diff --git a/doc/manpage/blender.1 b/doc/manpage/blender.1 index 620a90e61d2..169006fc609 100644 --- a/doc/manpage/blender.1 +++ b/doc/manpage/blender.1 @@ -1,4 +1,4 @@ -.TH "BLENDER" "1" "October 17, 2011" "Blender Blender 2\&.60 (sub 0)" +.TH "BLENDER" "1" "December 10, 2011" "Blender Blender 2\&.60 (sub 7)" .SH NAME blender \- a 3D modelling and rendering package @@ -15,7 +15,7 @@ Use Blender to create TV commercials, to make technical visualizations, business http://www.blender.org .SH OPTIONS -Blender 2.59 (sub 4) +Blender 2.60 (sub 7) Usage: blender [args ...] [file] [args ...] .br .SS "Render Options:" @@ -378,11 +378,10 @@ Arguments are executed in the order they are given. eg \fIBLENDER_USER_CONFIG\fR Directory for user configuration files. \fIBLENDER_USER_SCRIPTS\fR Directory for user scripts. \fIBLENDER_SYSTEM_SCRIPTS\fR Directory for system wide scripts. - \fIBLENDER_USER_DATAFILES\fR Directory for user data files (icons, translations, ..). + \fIBLENDER_USER_DAT`AFILES\fR Directory for user data files (icons, translations, ..). \fIBLENDER_SYSTEM_DATAFILES\fR Directory for system wide data files. \fIBLENDER_SYSTEM_PYTHON\fR Directory for system python libraries. \fITMP\fR or \fITMPDIR\fR Store temporary files here. - \fISDL_AUDIODRIVER\fR LibSDL audio driver \- alsa, esd, dma. \fIPYTHONHOME\fR Path to the python directory, eg. /usr/lib/python. .br .br diff --git a/intern/cycles/blender/blender_mesh.cpp b/intern/cycles/blender/blender_mesh.cpp index 7b701be49d7..bb4fef4a602 100644 --- a/intern/cycles/blender/blender_mesh.cpp +++ b/intern/cycles/blender/blender_mesh.cpp @@ -233,9 +233,9 @@ Mesh *BlenderSync::sync_mesh(BL::Object b_ob, bool object_updated) BL::Object::material_slots_iterator slot; for(b_ob.material_slots.begin(slot); slot != b_ob.material_slots.end(); ++slot) { if(render_layer.material_override) - find_shader(render_layer.material_override, used_shaders); + find_shader(render_layer.material_override, used_shaders, scene->default_surface); else - find_shader(slot->material(), used_shaders); + find_shader(slot->material(), used_shaders, scene->default_surface); } if(used_shaders.size() == 0) diff --git a/intern/cycles/blender/blender_object.cpp b/intern/cycles/blender/blender_object.cpp index abadee9328e..ec22d3db6f7 100644 --- a/intern/cycles/blender/blender_object.cpp +++ b/intern/cycles/blender/blender_object.cpp @@ -137,7 +137,7 @@ void BlenderSync::sync_light(BL::Object b_parent, int b_index, BL::Object b_ob, /* shader */ vector used_shaders; - find_shader(b_lamp, used_shaders); + find_shader(b_lamp, used_shaders, scene->default_light); if(used_shaders.size() == 0) used_shaders.push_back(scene->default_light); diff --git a/intern/cycles/blender/blender_shader.cpp b/intern/cycles/blender/blender_shader.cpp index 930ac1d495a..b0dd6988457 100644 --- a/intern/cycles/blender/blender_shader.cpp +++ b/intern/cycles/blender/blender_shader.cpp @@ -36,9 +36,9 @@ typedef map PtrSockMap; /* Find */ -void BlenderSync::find_shader(BL::ID id, vector& used_shaders) +void BlenderSync::find_shader(BL::ID id, vector& used_shaders, int default_shader) { - Shader *shader = shader_map.find(id); + Shader *shader = (id)? shader_map.find(id): scene->shaders[default_shader]; for(size_t i = 0; i < scene->shaders.size(); i++) { if(scene->shaders[i] == shader) { diff --git a/intern/cycles/blender/blender_sync.h b/intern/cycles/blender/blender_sync.h index bde3207e1be..83c7f70fd59 100644 --- a/intern/cycles/blender/blender_sync.h +++ b/intern/cycles/blender/blender_sync.h @@ -81,7 +81,7 @@ private: void sync_light(BL::Object b_parent, int b_index, BL::Object b_ob, Transform& tfm); /* util */ - void find_shader(BL::ID id, vector& used_shaders); + void find_shader(BL::ID id, vector& used_shaders, int default_shader); bool object_is_modified(BL::Object b_ob); bool object_is_mesh(BL::Object b_ob); bool object_is_light(BL::Object b_ob); diff --git a/release/scripts/modules/bpy_extras/image_utils.py b/release/scripts/modules/bpy_extras/image_utils.py index 52050b08bc7..7d409510c85 100644 --- a/release/scripts/modules/bpy_extras/image_utils.py +++ b/release/scripts/modules/bpy_extras/image_utils.py @@ -65,19 +65,45 @@ def load_image(imagepath, # TODO: recursive + # ------------------------------------------------------------------------- + # Utility Functions + + def _image_load_placeholder(path): + name = bpy.path.basename(path) + if type(name) == bytes: + name = name.decode('utf-8', "replace") + image = bpy.data.images.new(name, 128, 128) + # allow the path to be resolved later + image.filepath = path + image.source = 'FILE' + return image + def _image_load(path): import bpy if convert_callback: path = convert_callback(path) - image = bpy.data.images.load(path) + try: + image = bpy.data.images.load(path) + except RuntimeError: + image = None if verbose: - print(" image loaded '%s'" % path) + if image: + print(" image loaded '%s'" % path) + else: + print(" image load failed '%s'" % path) + + # image path has been checked so the path could not be read for some + # reason, so be sure to return a placeholder + if place_holder: + image = _image_load_placeholder(path) return image + # ------------------------------------------------------------------------- + if verbose: print("load_image('%s', '%s', ...)" % (imagepath, dirname)) @@ -103,11 +129,9 @@ def load_image(imagepath, if os.path.exists(nfilepath): return _image_load(nfilepath) + # None of the paths exist so return placeholder if place_holder: - image = bpy.data.images.new(bpy.path.basename(imagepath), 128, 128) - # allow the path to be resolved later - image.filepath = imagepath - return image + return _image_load_placeholder(imagepath) # TODO comprehensiveImageLoad also searched in bpy.config.textureDir return None diff --git a/release/scripts/startup/bl_operators/object_randomize_transform.py b/release/scripts/startup/bl_operators/object_randomize_transform.py index ed881fab5fd..fa36e48d47b 100644 --- a/release/scripts/startup/bl_operators/object_randomize_transform.py +++ b/release/scripts/startup/bl_operators/object_randomize_transform.py @@ -22,6 +22,7 @@ import bpy from bpy.types import Operator from mathutils import Vector + def randomize_selected(seed, delta, loc, rot, scale, scale_even, scale_min): import random @@ -42,8 +43,13 @@ def randomize_selected(seed, delta, loc, rot, scale, scale_even, scale_min): else: # otherwise the values change under us uniform(0.0, 0.0), uniform(0.0, 0.0), uniform(0.0, 0.0) - if rot: # TODO, non euler's + if rot: vec = rand_vec(rot) + + rotation_mode = obj.rotation_mode + if rotation_mode in {'QUATERNION', 'AXIS_ANGLE'}: + obj.rotation_mode = 'XYZ' + if delta: obj.delta_rotation_euler[0] += vec[0] obj.delta_rotation_euler[1] += vec[1] @@ -52,6 +58,7 @@ def randomize_selected(seed, delta, loc, rot, scale, scale_even, scale_min): obj.rotation_euler[0] += vec[0] obj.rotation_euler[1] += vec[1] obj.rotation_euler[2] += vec[2] + obj.rotation_mode = rotation_mode else: uniform(0.0, 0.0), uniform(0.0, 0.0), uniform(0.0, 0.0) diff --git a/release/scripts/startup/bl_operators/wm.py b/release/scripts/startup/bl_operators/wm.py index 14c9a090529..89029e3af01 100644 --- a/release/scripts/startup/bl_operators/wm.py +++ b/release/scripts/startup/bl_operators/wm.py @@ -457,8 +457,8 @@ class WM_OT_context_cycle_enum(Operator): class WM_OT_context_cycle_array(Operator): - '''Set a context array value. - Useful for cycling the active mesh edit mode''' + '''Set a context array value. ''' + '''Useful for cycling the active mesh edit mode''' bl_idname = "wm.context_cycle_array" bl_label = "Context Array Cycle" bl_options = {'UNDO', 'INTERNAL'} diff --git a/source/blender/blenkernel/BKE_DerivedMesh.h b/source/blender/blenkernel/BKE_DerivedMesh.h index 98a5154c256..139119ee873 100644 --- a/source/blender/blenkernel/BKE_DerivedMesh.h +++ b/source/blender/blenkernel/BKE_DerivedMesh.h @@ -128,6 +128,7 @@ struct DerivedMesh { BVHCache bvhCache; struct GPUDrawObject *drawObject; DerivedMeshType type; + float auto_bump_scale; /* calculate vert and face normals */ void (*calcNormals)(DerivedMesh *dm); @@ -655,6 +656,7 @@ void DM_vertex_attributes_from_gpu(DerivedMesh *dm, struct GPUVertexAttribs *gattribs, DMVertexAttribs *attribs); void DM_add_tangent_layer(DerivedMesh *dm); +void DM_calc_auto_bump_scale(DerivedMesh *dm); /* Set object's bounding box based on DerivedMesh min/max data */ void DM_set_object_boundbox(struct Object *ob, DerivedMesh *dm); diff --git a/source/blender/blenkernel/BKE_deform.h b/source/blender/blenkernel/BKE_deform.h index b08afd9c475..9902b26e15b 100644 --- a/source/blender/blenkernel/BKE_deform.h +++ b/source/blender/blenkernel/BKE_deform.h @@ -63,7 +63,7 @@ void defvert_copy_index(struct MDeformVert *dvert_dst, const struct MDeformVert void defvert_sync(struct MDeformVert *dvert_dst, const struct MDeformVert *dvert_src, int use_verify); void defvert_sync_mapped(struct MDeformVert *dvert_dst, const struct MDeformVert *dvert_src, const int *flip_map, const int flip_map_len, const int use_verify); -void defvert_remap (struct MDeformVert *dvert, int *map); +void defvert_remap (struct MDeformVert *dvert, int *map, const int map_len); void defvert_flip(struct MDeformVert *dvert, const int *flip_map, const int flip_map_len); void defvert_normalize(struct MDeformVert *dvert); diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c index 64a802f225f..8405a3922e6 100644 --- a/source/blender/blenkernel/intern/DerivedMesh.c +++ b/source/blender/blenkernel/intern/DerivedMesh.c @@ -276,6 +276,7 @@ void DM_init(DerivedMesh *dm, DerivedMeshType type, int numVerts, int numEdges, DM_init_funcs(dm); dm->needsFree = 1; + dm->auto_bump_scale = -1.0f; } void DM_from_template(DerivedMesh *dm, DerivedMesh *source, DerivedMeshType type, @@ -883,7 +884,7 @@ enum { }; static void calc_weightpaint_vert_color( - Object *ob, ColorBand *coba, int vert, unsigned char *col, + Object *ob, const int defbase_tot, ColorBand *coba, int vert, unsigned char *col, const char *dg_flags, int selected, int UNUSED(unselected), const int draw_flag) { Mesh *me = ob->data; @@ -902,10 +903,12 @@ static void calc_weightpaint_vert_color( for (i = dvert->totweight; i > 0; i--, dw++) { /* in multipaint, get the average if auto normalize is inactive * get the sum if it is active */ - if (dg_flags[dw->def_nr]) { - if (dw->weight) { - input += dw->weight; - was_a_nonzero= TRUE; + if (dw->def_nr < defbase_tot) { + if (dg_flags[dw->def_nr]) { + if (dw->weight) { + input += dw->weight; + was_a_nonzero= TRUE; + } } } } @@ -964,10 +967,10 @@ static void add_weight_mcol_dm(Object *ob, DerivedMesh *dm, int const draw_flag) int i, j, totface=dm->getNumTessFaces(dm), totloop; int *origIndex = dm->getVertDataArray(dm, CD_ORIGINDEX); - 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; + int defbase_tot = BLI_countlist(&ob->defbase); + char *defbase_sel = MEM_mallocN(defbase_tot * sizeof(char), __func__); + int selected = get_selected_defgroups(ob, defbase_sel, defbase_tot); + int unselected = defbase_tot - selected; wtcol = MEM_callocN (sizeof (unsigned char) * totface*4*4, "weightmap"); @@ -975,11 +978,11 @@ static void add_weight_mcol_dm(Object *ob, DerivedMesh *dm, int const draw_flag) memset(wtcol, 0x55, sizeof (unsigned char) * totface*4*4); for (i=0; iv1, &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); + calc_weightpaint_vert_color(ob, defbase_tot, coba, mf->v1, &wtcol[(i*4 + 0)*4], defbase_sel, selected, unselected, draw_flag); + calc_weightpaint_vert_color(ob, defbase_tot, coba, mf->v2, &wtcol[(i*4 + 1)*4], defbase_sel, selected, unselected, draw_flag); + calc_weightpaint_vert_color(ob, defbase_tot, 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], defbase_sel, selected, unselected, draw_flag); + calc_weightpaint_vert_color(ob, defbase_tot, coba, mf->v4, &wtcol[(i*4 + 3)*4], defbase_sel, selected, unselected, draw_flag); } CustomData_add_layer(&dm->faceData, CD_WEIGHT_MCOL, CD_ASSIGN, wtcol, totface); @@ -992,7 +995,7 @@ static void add_weight_mcol_dm(Object *ob, DerivedMesh *dm, int const draw_flag) for (j=0; jtotloop; j++, ml++, totloop++) { BLI_array_growone(wlcol); - calc_weightpaint_vert_color(ob, coba, origIndex ? origIndex[ml->v] : ml->v, + calc_weightpaint_vert_color(ob, defbase_tot, coba, origIndex ? origIndex[ml->v] : ml->v, (unsigned char *)&wlcol[totloop], defbase_sel, selected, unselected, draw_flag); } } @@ -2222,6 +2225,159 @@ void DM_add_tangent_layer(DerivedMesh *dm) MEM_freeN(vtangents); } +void DM_calc_auto_bump_scale(DerivedMesh *dm) +{ + /* int totvert= dm->getNumVerts(dm); */ /* UNUSED */ + int totface= dm->getNumTessFaces(dm); + + MVert * mvert = dm->getVertArray(dm); + MFace * mface = dm->getTessFaceArray(dm); + MTFace * mtface = dm->getTessFaceDataArray(dm, CD_MTFACE); + + if(mtface) + { + double dsum = 0.0; + int nr_accumulated = 0; + int f; + + for ( f=0; fFLT_EPSILON ) + { + float norm[3], v0[3], v1[3], f2x_surf_area, fsurf_ratio; + sub_v3_v3v3(v0, p1, p0); + sub_v3_v3v3(v1, p2, p0); + cross_v3_v3v3(norm, v0, v1); + + f2x_surf_area = len_v3(norm); + fsurf_ratio = f2x_surf_area/f2x_area_uv; // tri area divided by texture area + + ++nr_accumulated; + dsum += (double)(fsurf_ratio); + } + } + } + } + } + } + + // finalize + { + const float avg_area_ratio = (nr_accumulated>0) ? ((float)(dsum / nr_accumulated)) : 1.0f; + const float use_as_render_bump_scale = sqrtf(avg_area_ratio); // use width of average surface ratio as your bump scale + dm->auto_bump_scale = use_as_render_bump_scale; + } + } + else + { + dm->auto_bump_scale = 1.0f; + } +} + void DM_vertex_attributes_from_gpu(DerivedMesh *dm, GPUVertexAttribs *gattribs, DMVertexAttribs *attribs) { CustomData *vdata, *fdata, *tfdata = NULL; @@ -2235,6 +2391,15 @@ void DM_vertex_attributes_from_gpu(DerivedMesh *dm, GPUVertexAttribs *gattribs, vdata = &dm->vertData; fdata = tfdata = dm->getTessFaceDataLayout(dm); + /* calc auto bump scale if necessary */ +#if 0 + if(dm->auto_bump_scale<=0.0f) + DM_calc_auto_bump_scale(dm); +#else + dm->auto_bump_scale = 1.0f; // will revert this after release +#endif + + /* add a tangent layer if necessary */ for(b = 0; b < gattribs->totlayer; b++) if(gattribs->layer[b].type == CD_TANGENT) diff --git a/source/blender/blenkernel/intern/armature.c b/source/blender/blenkernel/intern/armature.c index 68d2cf940af..e10c4b24458 100644 --- a/source/blender/blenkernel/intern/armature.c +++ b/source/blender/blenkernel/intern/armature.c @@ -827,7 +827,7 @@ void armature_deform_verts(Object *armOb, Object *target, DerivedMesh *dm, const short use_envelope = deformflag & ARM_DEF_ENVELOPE; const short use_quaternion = deformflag & ARM_DEF_QUATERNION; const short invert_vgroup= deformflag & ARM_DEF_INVERT_VGROUP; - int numGroups = 0; /* safety for vertexgroup index overflow */ + int defbase_tot = 0; /* safety for vertexgroup index overflow */ int i, target_totvert = 0; /* safety for vertexgroup overflow */ int use_dverts = 0; int armature_def_nr; @@ -869,7 +869,7 @@ void armature_deform_verts(Object *armOb, Object *target, DerivedMesh *dm, armature_def_nr= defgroup_name_index(target, defgrp_name); if(ELEM(target->type, OB_MESH, OB_LATTICE)) { - numGroups = BLI_countlist(&target->defbase); + defbase_tot = BLI_countlist(&target->defbase); if(target->type==OB_MESH) { Mesh *me= target->data; @@ -896,8 +896,8 @@ void armature_deform_verts(Object *armOb, Object *target, DerivedMesh *dm, else if(dverts) use_dverts = 1; if(use_dverts) { - defnrToPC = MEM_callocN(sizeof(*defnrToPC) * numGroups, "defnrToBone"); - defnrToPCIndex = MEM_callocN(sizeof(*defnrToPCIndex) * numGroups, "defnrToIndex"); + defnrToPC = MEM_callocN(sizeof(*defnrToPC) * defbase_tot, "defnrToBone"); + defnrToPCIndex = MEM_callocN(sizeof(*defnrToPCIndex) * defbase_tot, "defnrToIndex"); for(i = 0, dg = target->defbase.first; dg; i++, dg = dg->next) { defnrToPC[i] = get_pose_channel(armOb->pose, dg->name); @@ -975,7 +975,7 @@ void armature_deform_verts(Object *armOb, Object *target, DerivedMesh *dm, for(j = 0; j < dvert->totweight; j++){ int index = dvert->dw[j].def_nr; - if(index < numGroups && (pchan= defnrToPC[index])) { + if(index < defbase_tot && (pchan= defnrToPC[index])) { float weight = dvert->dw[j].weight; Bone *bone= pchan->bone; pdef_info= pdef_info_array + defnrToPCIndex[index]; @@ -2473,7 +2473,7 @@ 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) +int get_selected_defgroups(Object *ob, char *dg_selection, int defbase_tot) { bDeformGroup *defgroup; unsigned int i; @@ -2482,7 +2482,7 @@ int get_selected_defgroups(Object *ob, char *dg_selection, int defbase_len) if(armob) { bPose *pose= armob->pose; - for (i= 0, defgroup= ob->defbase.first; i < defbase_len && defgroup; defgroup = defgroup->next, i++) { + for (i= 0, defgroup= ob->defbase.first; i < defbase_tot && defgroup; defgroup = defgroup->next, i++) { bPoseChannel *pchan= get_pose_channel(pose, defgroup->name); if(pchan && (pchan->bone->flag & BONE_SELECTED)) { dg_selection[i]= TRUE; @@ -2494,7 +2494,7 @@ int get_selected_defgroups(Object *ob, char *dg_selection, int defbase_len) } } else { - memset(dg_selection, FALSE, sizeof(char) * defbase_len); + memset(dg_selection, FALSE, sizeof(char) * defbase_tot); } return dg_flags_sel_tot; diff --git a/source/blender/blenkernel/intern/deform.c b/source/blender/blenkernel/intern/deform.c index 088241791a7..8967dcdbd0e 100644 --- a/source/blender/blenkernel/intern/deform.c +++ b/source/blender/blenkernel/intern/deform.c @@ -164,12 +164,14 @@ void defvert_sync_mapped(MDeformVert *dvert_dst, const MDeformVert *dvert_src, } /* be sure all flip_map values are valid */ -void defvert_remap(MDeformVert *dvert, int *map) +void defvert_remap(MDeformVert *dvert, int *map, const int map_len) { MDeformWeight *dw; int i; for (i=0, dw=dvert->dw; itotweight; i++, dw++) { - dw->def_nr= map[dw->def_nr]; + if (dw->def_nr < map_len) { + dw->def_nr= map[dw->def_nr]; + } } } @@ -201,8 +203,10 @@ void defvert_flip(MDeformVert *dvert, const int *flip_map, const int flip_map_le int i; for (dw= dvert->dw, i=0; itotweight; dw++, i++) { - if ((dw->def_nr < flip_map_len) && (flip_map[dw->def_nr] >= 0)) { - dw->def_nr= flip_map[dw->def_nr]; + if (dw->def_nr < flip_map_len) { + if (flip_map[dw->def_nr] >= 0) { + dw->def_nr= flip_map[dw->def_nr]; + } } } } @@ -286,17 +290,17 @@ int defgroup_find_index(Object *ob, bDeformGroup *dg) /* note, must be freed */ int *defgroup_flip_map(Object *ob, int *flip_map_len, int use_default) { - int totdg= *flip_map_len= BLI_countlist(&ob->defbase); + int defbase_tot= *flip_map_len= BLI_countlist(&ob->defbase); - if (totdg==0) { + if (defbase_tot==0) { return NULL; } else { bDeformGroup *dg; char name[sizeof(dg->name)]; - int i, flip_num, *map= MEM_mallocN(totdg * sizeof(int), __func__); + int i, flip_num, *map= MEM_mallocN(defbase_tot * sizeof(int), __func__); - for (i=0; i < totdg; i++) { + for (i=0; i < defbase_tot; i++) { map[i]= -1; } @@ -324,17 +328,17 @@ int *defgroup_flip_map(Object *ob, int *flip_map_len, int use_default) /* note, must be freed */ int *defgroup_flip_map_single(Object *ob, int *flip_map_len, int use_default, int defgroup) { - int totdg= *flip_map_len= BLI_countlist(&ob->defbase); + int defbase_tot= *flip_map_len= BLI_countlist(&ob->defbase); - if (totdg==0) { + if (defbase_tot==0) { return NULL; } else { bDeformGroup *dg; char name[sizeof(dg->name)]; - int i, flip_num, *map= MEM_mallocN(totdg * sizeof(int), __func__); + int i, flip_num, *map= MEM_mallocN(defbase_tot * sizeof(int), __func__); - for (i=0; i < totdg; i++) { + for (i=0; i < defbase_tot; i++) { if (use_default) map[i]= i; else map[i]= -1; } @@ -413,11 +417,15 @@ void flip_side_name(char name[MAX_VGROUP_NAME], const char from_name[MAX_VGROUP_ char number[MAX_VGROUP_NAME]= ""; /* The number extension string */ char *index=NULL; - len= BLI_strnlen(from_name, MAX_VGROUP_NAME); - if (len < 3) return; // we don't do names like .R or .L - + /* always copy the name, since this can be called with an uninitialized string */ BLI_strncpy(name, from_name, MAX_VGROUP_NAME); + len= BLI_strnlen(from_name, MAX_VGROUP_NAME); + if (len < 3) { + /* we don't do names like .R or .L */ + return; + } + /* We first check the case with a .### extension, let's find the last period */ if (isdigit(name[len-1])) { index= strrchr(name, '.'); // last occurrence diff --git a/source/blender/blenkernel/intern/editderivedmesh.c b/source/blender/blenkernel/intern/editderivedmesh.c index 3297417eb8c..89bf06be07e 100644 --- a/source/blender/blenkernel/intern/editderivedmesh.c +++ b/source/blender/blenkernel/intern/editderivedmesh.c @@ -619,7 +619,10 @@ static void emDM_drawMappedFaces( { EditDerivedBMesh *bmdm= (EditDerivedBMesh*) dm; BMFace *efa; - int i, draw; + struct BMLoop *(*looptris)[3]= bmdm->tc->looptris; + const int tottri= bmdm->tc->tottri; + const int lasttri= tottri - 1; /* compare agasint this a lot */ + int i, draw, flush; const int skip_normals= !glIsEnabled(GL_LIGHTING); /* could be passed as an arg */ /* GL_ZERO is used to detect if drawing has started or not */ @@ -639,8 +642,8 @@ static void emDM_drawMappedFaces( BM_ElemIndex_Ensure(bmdm->tc->bm, BM_VERT | BM_FACE); - for (i=0; itc->tottri; i++) { - BMLoop **l = bmdm->tc->looptris[i]; + for (i=0; i < tottri; i++) { + BMLoop **l = looptris[i]; int drawSmooth; efa = l[0]->f; @@ -695,7 +698,11 @@ static void emDM_drawMappedFaces( } } - if (draw==2) { + flush= (draw==2); + if (!skip_normals && !flush && (i != lasttri)) + flush|= efa->mat_nr != looptris[i + 1][0]->f->mat_nr; /* TODO, make this neater */ + + if (flush) { glEnd(); poly_prev= GL_ZERO; /* force glBegin */ @@ -707,8 +714,8 @@ static void emDM_drawMappedFaces( else { BM_ElemIndex_Ensure(bmdm->tc->bm, BM_FACE); - for (i=0; itc->tottri; i++) { - BMLoop **l = bmdm->tc->looptris[i]; + for (i=0; i < tottri; i++) { + BMLoop **l = looptris[i]; int drawSmooth; efa = l[0]->f; @@ -763,8 +770,12 @@ static void emDM_drawMappedFaces( } } + flush= (draw==2); + if (!skip_normals && !flush && (i != lasttri)) { + flush|= efa->mat_nr != looptris[i + 1][0]->f->mat_nr; /* TODO, make this neater */ + } - if (draw==2) { + if (flush) { glEnd(); poly_prev= GL_ZERO; /* force glBegin */ diff --git a/source/blender/blenkernel/intern/mesh_validate.c b/source/blender/blenkernel/intern/mesh_validate.c index fd19d8461d5..d3cfa42b179 100644 --- a/source/blender/blenkernel/intern/mesh_validate.c +++ b/source/blender/blenkernel/intern/mesh_validate.c @@ -136,9 +136,11 @@ int BKE_mesh_validate_arrays( Mesh *me, MVert *mvert= mverts; unsigned int i; - int do_face_free= FALSE; - int do_edge_free= FALSE; - int verts_fixed= FALSE; + short do_face_free= FALSE; + short do_edge_free= FALSE; + + short verts_fixed= FALSE; + short vert_weights_fixed= FALSE; int do_edge_recalc= FALSE; @@ -165,9 +167,12 @@ int BKE_mesh_validate_arrays( Mesh *me, for(j=0; j<3; j++) { if(!finite(mvert->co[j])) { PRINT(" vertex %u: has invalid coordinate\n", i); - zero_v3(mvert->co); - verts_fixed= TRUE; + if (do_fixes) { + zero_v3(mvert->co); + + verts_fixed= TRUE; + } } if(mvert->no[j]!=0) @@ -176,8 +181,10 @@ int BKE_mesh_validate_arrays( Mesh *me, if(fix_normal) { PRINT(" vertex %u: has zero normal, assuming Z-up normal\n", i); - mvert->no[2]= SHRT_MAX; - verts_fixed= TRUE; + if (do_fixes) { + mvert->no[2]= SHRT_MAX; + verts_fixed= TRUE; + } } } @@ -318,8 +325,8 @@ int BKE_mesh_validate_arrays( Mesh *me, if (dverts) { MDeformVert *dv; for(i=0, dv= dverts; idw; - unsigned int j= 0; + MDeformWeight *dw; + unsigned int j; for(j=0, dw= dv->dw; j < dv->totweight; j++, dw++) { /* note, greater then max defgroups is accounted for in our code, but not < 0 */ @@ -327,6 +334,14 @@ int BKE_mesh_validate_arrays( Mesh *me, PRINT(" vertex deform %u, group %d has weight: %f\n", i, dw->def_nr, dw->weight); if (do_fixes) { dw->weight= 0.0f; + vert_weights_fixed= TRUE; + } + } + else if (dw->weight < 0.0f || dw->weight > 1.0f) { + PRINT(" vertex deform %u, group %d has weight: %f\n", i, dw->def_nr, dw->weight); + if (do_fixes) { + CLAMP(dw->weight, 0.0f, 1.0f); + vert_weights_fixed= TRUE; } } @@ -339,6 +354,8 @@ int BKE_mesh_validate_arrays( Mesh *me, * within the for loop and may not be valid */ j--; dw= dv->dw + j; + + vert_weights_fixed= TRUE; } else { /* all freed */ break; @@ -369,7 +386,7 @@ int BKE_mesh_validate_arrays( Mesh *me, } } - return (verts_fixed || do_face_free || do_edge_free || do_edge_recalc); + return (verts_fixed || vert_weights_fixed || do_face_free || do_edge_free || do_edge_recalc); } static int mesh_validate_customdata(CustomData *data, short do_verbose, const short do_fixes) diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c index 56d29467ac7..b84d06d78e9 100644 --- a/source/blender/blenkernel/intern/particle.c +++ b/source/blender/blenkernel/intern/particle.c @@ -81,6 +81,7 @@ #include "BKE_cdderivedmesh.h" #include "BKE_pointcache.h" #include "BKE_scene.h" +#include "BKE_deform.h" #include "RE_render_ext.h" @@ -1849,20 +1850,6 @@ void psys_particle_on_emitter(ParticleSystemModifierData *psmd, int from, int in /************************************************/ /* Path Cache */ /************************************************/ -static float vert_weight(MDeformVert *dvert, int group) -{ - MDeformWeight *dw; - int i; - - if(dvert) { - dw= dvert->dw; - for(i= dvert->totweight; i>0; i--, dw++) { - if(dw->def_nr == group) return dw->weight; - if(i==1) break; /*otherwise dw will point to somewhere it shouldn't*/ - } - } - return 0.0; -} static void do_kink(ParticleKey *state, ParticleKey *par, float *par_rot, float time, float freq, float shape, float amplitude, float flat, short type, short axis, float obmat[][4], int smooth_start) { @@ -2310,11 +2297,11 @@ float *psys_cache_vgroup(DerivedMesh *dm, ParticleSystem *psys, int vgroup) vg=MEM_callocN(sizeof(float)*totvert, "vg_cache"); if(psys->vg_neg&(1<vgroup[vgroup]-1); + vg[i]= 1.0f - defvert_find_weight(&dvert[i], psys->vgroup[vgroup] - 1); } else{ for(i=0; ivgroup[vgroup]-1); + vg[i]= defvert_find_weight(&dvert[i], psys->vgroup[vgroup] - 1); } } } diff --git a/source/blender/editors/animation/anim_ipo_utils.c b/source/blender/editors/animation/anim_ipo_utils.c index d18a3c320f7..8e36e02bbb4 100644 --- a/source/blender/editors/animation/anim_ipo_utils.c +++ b/source/blender/editors/animation/anim_ipo_utils.c @@ -78,7 +78,8 @@ int getname_anim_fcurve(char *name, ID *id, FCurve *fcu) /* try to resolve the path */ if (RNA_path_resolve(&id_ptr, fcu->rna_path, &ptr, &prop)) { - char *structname=NULL, *propname=NULL, arrayindbuf[16]; + const char *structname=NULL, *propname=NULL; + char arrayindbuf[16]; const char *arrayname=NULL; short free_structname = 0; @@ -122,11 +123,11 @@ int getname_anim_fcurve(char *name, ID *id, FCurve *fcu) free_structname= 1; } else - structname= (char *)RNA_struct_ui_name(ptr.type); + structname= RNA_struct_ui_name(ptr.type); } /* Property Name is straightforward */ - propname= (char *)RNA_property_ui_name(prop); + propname= RNA_property_ui_name(prop); /* Array Index - only if applicable */ if (RNA_property_array_length(&ptr, prop)) { @@ -153,7 +154,7 @@ int getname_anim_fcurve(char *name, ID *id, FCurve *fcu) /* free temp name if nameprop is set */ if (free_structname) - MEM_freeN(structname); + MEM_freeN((void *)structname); /* Icon for this property's owner: diff --git a/source/blender/editors/animation/keyframing.c b/source/blender/editors/animation/keyframing.c index 4595bf3f64f..54314980e03 100644 --- a/source/blender/editors/animation/keyframing.c +++ b/source/blender/editors/animation/keyframing.c @@ -524,7 +524,8 @@ static float setting_get_rna_value (PointerRNA *ptr, PropertyRNA *prop, int inde enum { VISUALKEY_NONE = 0, VISUALKEY_LOC, - VISUALKEY_ROT, + VISUALKEY_ROT + /* VISUALKEY_SCA */ /* TODO - looks like support can be added now */ }; /* This helper function determines if visual-keyframing should be used when @@ -655,7 +656,7 @@ static short visualkey_can_use (PointerRNA *ptr, PropertyRNA *prop) */ static float visualkey_get_value (PointerRNA *ptr, PropertyRNA *prop, int array_index) { - char *identifier= (char *)RNA_property_identifier(prop); + const char *identifier= RNA_property_identifier(prop); /* handle for Objects or PoseChannels only * - constraints can be on either Objects or PoseChannels, so we only check if the diff --git a/source/blender/editors/armature/editarmature.c b/source/blender/editors/armature/editarmature.c index 79ae01746d1..f1990372fc8 100644 --- a/source/blender/editors/armature/editarmature.c +++ b/source/blender/editors/armature/editarmature.c @@ -161,7 +161,7 @@ void ED_armature_edit_bone_remove(bArmature *arm, EditBone *exBone) EditBone *ED_armature_bone_get_mirrored(ListBase *edbo, EditBone *ebo) { EditBone *eboflip= NULL; - char name[32]; + char name[MAXBONENAME]; if (ebo == NULL) return NULL; @@ -4663,7 +4663,7 @@ static void add_verts_to_dgroups(ReportList *reports, Scene *scene, Object *ob, /* find flipped group */ if (dgroup && mirror) { - char name[32]; + char name[MAXBONENAME]; // 0 = don't strip off number extensions flip_side_name(name, dgroup->name, FALSE); @@ -5456,7 +5456,7 @@ static int armature_flip_names_exec (bContext *C, wmOperator *UNUSED(op)) { Object *ob= CTX_data_edit_object(C); bArmature *arm; - char newname[32]; + char newname[MAXBONENAME]; /* paranoia checks */ if (ELEM(NULL, ob, ob->pose)) diff --git a/source/blender/editors/armature/poseobject.c b/source/blender/editors/armature/poseobject.c index 993c8420576..8d35122650f 100644 --- a/source/blender/editors/armature/poseobject.c +++ b/source/blender/editors/armature/poseobject.c @@ -989,7 +989,7 @@ static void set_pose_keys (Object *ob) static bPoseChannel *pose_bone_do_paste (Object *ob, bPoseChannel *chan, short selOnly, short flip) { bPoseChannel *pchan; - char name[32]; + char name[MAXBONENAME]; short paste_ok; /* get the name - if flipping, we must flip this first */ @@ -1740,7 +1740,7 @@ static int pose_flip_names_exec (bContext *C, wmOperator *UNUSED(op)) /* loop through selected bones, auto-naming them */ CTX_DATA_BEGIN(C, bPoseChannel*, pchan, selected_pose_bones) { - char newname[32]; + char newname[MAXBONENAME]; flip_side_name(newname, pchan->name, TRUE); ED_armature_bone_rename(arm, pchan->name, newname); } diff --git a/source/blender/editors/object/object_add.c b/source/blender/editors/object/object_add.c index 8d5c9dcc8f4..4db6e4ece54 100644 --- a/source/blender/editors/object/object_add.c +++ b/source/blender/editors/object/object_add.c @@ -895,7 +895,7 @@ static int object_delete_exec(bContext *C, wmOperator *op) { Main *bmain= CTX_data_main(C); Scene *scene= CTX_data_scene(C); - const short use_global= RNA_boolean_get(op->ptr, "global"); + const short use_global= RNA_boolean_get(op->ptr, "use_global"); /* int islamp= 0; */ /* UNUSED */ if(CTX_data_edit_object(C)) @@ -953,7 +953,7 @@ void OBJECT_OT_delete(wmOperatorType *ot) /* flags */ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; - RNA_def_boolean(ot->srna, "global", 0, "Delete Globally", "Remove object from all scenes"); + RNA_def_boolean(ot->srna, "use_global", 0, "Delete Globally", "Remove object from all scenes"); } /**************************** Copy Utilities ******************************/ diff --git a/source/blender/editors/object/object_ops.c b/source/blender/editors/object/object_ops.c index 0c9b7b2cbda..8fd852278d3 100644 --- a/source/blender/editors/object/object_ops.c +++ b/source/blender/editors/object/object_ops.c @@ -339,9 +339,9 @@ void ED_keymap_object(wmKeyConfig *keyconf) WM_keymap_add_item(keymap, "OBJECT_OT_move_to_layer", MKEY, KM_PRESS, 0, 0); WM_keymap_add_item(keymap, "OBJECT_OT_delete", XKEY, KM_PRESS, 0, 0); - RNA_boolean_set(WM_keymap_add_item(keymap, "OBJECT_OT_delete", XKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "global", TRUE); + RNA_boolean_set(WM_keymap_add_item(keymap, "OBJECT_OT_delete", XKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "use_global", TRUE); WM_keymap_add_item(keymap, "OBJECT_OT_delete", DELKEY, KM_PRESS, 0, 0); - RNA_boolean_set(WM_keymap_add_item(keymap, "OBJECT_OT_delete", DELKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "global", TRUE); + RNA_boolean_set(WM_keymap_add_item(keymap, "OBJECT_OT_delete", DELKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "use_global", TRUE); WM_keymap_add_menu(keymap, "INFO_MT_add", AKEY, KM_PRESS, KM_SHIFT, 0); diff --git a/source/blender/editors/object/object_select.c b/source/blender/editors/object/object_select.c index fce37b7a022..c4d33b74574 100644 --- a/source/blender/editors/object/object_select.c +++ b/source/blender/editors/object/object_select.c @@ -41,6 +41,7 @@ #include "DNA_modifier_types.h" #include "DNA_property_types.h" #include "DNA_scene_types.h" +#include "DNA_armature_types.h" #include "BLI_math.h" #include "BLI_listbase.h" @@ -893,7 +894,7 @@ static int object_select_mirror_exec(bContext *C, wmOperator *op) extend= RNA_boolean_get(op->ptr, "extend"); CTX_DATA_BEGIN(C, Base*, primbase, selected_bases) { - char tmpname[32]; + char tmpname[MAXBONENAME]; flip_side_name(tmpname, primbase->object->id.name+2, TRUE); diff --git a/source/blender/editors/object/object_vgroup.c b/source/blender/editors/object/object_vgroup.c index c6a6cf46257..dda33689180 100644 --- a/source/blender/editors/object/object_vgroup.c +++ b/source/blender/editors/object/object_vgroup.c @@ -290,8 +290,8 @@ int ED_vgroup_copy_array(Object *ob, Object *ob_from) int dvert_tot_from; int dvert_tot; int i; - int totdef_from= BLI_countlist(&ob_from->defbase); - int totdef= BLI_countlist(&ob->defbase); + int defbase_tot_from= BLI_countlist(&ob_from->defbase); + int defbase_tot= BLI_countlist(&ob->defbase); short new_vgroup= FALSE; ED_vgroup_give_parray(ob_from->data, &dvert_array_from, &dvert_tot_from); @@ -318,11 +318,11 @@ int ED_vgroup_copy_array(Object *ob, Object *ob_from) BLI_duplicatelist(&ob->defbase, &ob_from->defbase); ob->actdef= ob_from->actdef; - if(totdef_from < totdef) { + if(defbase_tot_from < defbase_tot) { /* correct vgroup indices because the number of vgroups is being reduced. */ - int *remap= MEM_mallocN(sizeof(int) * (totdef + 1), "ED_vgroup_copy_array"); - for(i=0; i<=totdef_from; i++) remap[i]= i; - for(; i<=totdef; i++) remap[i]= 0; /* can't use these, so disable */ + int *remap= MEM_mallocN(sizeof(int) * (defbase_tot + 1), "ED_vgroup_copy_array"); + for(i=0; i<=defbase_tot_from; i++) remap[i]= i; + for(; i<=defbase_tot; i++) remap[i]= 0; /* can't use these, so disable */ vgroup_remap_update_users(ob, remap); MEM_freeN(remap); @@ -1814,12 +1814,12 @@ static void vgroup_remap_update_users(Object *ob, int *map) static void vgroup_delete_update_users(Object *ob, int id) { - int i, tot= BLI_countlist(&ob->defbase) + 1; - int *map= MEM_mallocN(sizeof(int) * tot, "vgroup del"); + int i, defbase_tot= BLI_countlist(&ob->defbase) + 1; + int *map= MEM_mallocN(sizeof(int) * defbase_tot, "vgroup del"); map[id]= map[0]= 0; for(i=1; idefbase); - char *name_array= MEM_mallocN(MAX_VGROUP_NAME * sizeof(char) * def_tot, "sort vgroups"); + int defbase_tot = BLI_countlist(&ob->defbase); + char *name_array= MEM_mallocN(MAX_VGROUP_NAME * sizeof(char) * defbase_tot, "sort vgroups"); char *name; name= name_array; @@ -2839,8 +2839,8 @@ static int vgroup_do_remap(Object *ob, char *name_array, wmOperator *op) { MDeformVert *dvert= NULL; bDeformGroup *def; - int def_tot = BLI_countlist(&ob->defbase); - int *sort_map_update= MEM_mallocN(sizeof(int) * (def_tot + 1), "sort vgroups"); /* needs a dummy index at the start*/ + int defbase_tot = BLI_countlist(&ob->defbase); + int *sort_map_update= MEM_mallocN(sizeof(int) * (defbase_tot + 1), "sort vgroups"); /* needs a dummy index at the start*/ int *sort_map= sort_map_update + 1; char *name; int i; @@ -2862,7 +2862,7 @@ static int vgroup_do_remap(Object *ob, char *name_array, wmOperator *op) BM_ITER(eve, &iter, em->bm, BM_VERTS_OF_MESH, NULL) { dvert= CustomData_bmesh_get(&em->bm->vdata, eve->head.data, CD_MDEFORMVERT); if(dvert && dvert->totweight){ - defvert_remap(dvert, sort_map); + defvert_remap(dvert, sort_map, defbase_tot); } } } @@ -2880,13 +2880,13 @@ static int vgroup_do_remap(Object *ob, char *name_array, wmOperator *op) /*create as necassary*/ while(dvert && dvert_tot--) { if(dvert->totweight) - defvert_remap(dvert, sort_map); + defvert_remap(dvert, sort_map, defbase_tot); dvert++; } } /* update users */ - for(i=0; ieventstate->x - vc.ar->winrct.xmin, win->eventstate->y - vc.ar->winrct.ymin); if(index && index<=me->totface) { - const int totgroup= BLI_countlist(&vc.obact->defbase); - if(totgroup) { + const int defbase_tot= BLI_countlist(&vc.obact->defbase); + if(defbase_tot) { MPoly *mf= ((MPoly *)me->mpoly) + index-1; unsigned int fidx= mf->totloop - 1; - int *groups= MEM_callocN(totgroup*sizeof(int), "groups"); + int *groups= MEM_callocN(defbase_tot*sizeof(int), "groups"); int found= FALSE; do { @@ -1059,8 +1059,10 @@ static EnumPropertyItem *weight_paint_sample_enum_itemf(bContext *C, PointerRNA int i= dvert->totweight; MDeformWeight *dw; for(dw= dvert->dw; i > 0; dw++, i--) { - groups[dw->def_nr]= TRUE; - found= TRUE; + if (dw->def_nr < defbase_tot) { + groups[dw->def_nr]= TRUE; + found= TRUE; + } } } while (fidx--); @@ -1072,7 +1074,7 @@ static EnumPropertyItem *weight_paint_sample_enum_itemf(bContext *C, PointerRNA int totitem= 0; int i= 0; bDeformGroup *dg; - for(dg= vc.obact->defbase.first; dg && inext) { + for(dg= vc.obact->defbase.first; dg && inext) { if(groups[i]) { item_tmp.identifier= item_tmp.name= dg->name; item_tmp.value= i; @@ -1171,7 +1173,8 @@ 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, const char *vgroup_validmap, char do_auto_normalize) +static void do_weight_paint_auto_normalize_all_groups(MDeformVert *dvert, const int defbase_tot, + const char *vgroup_validmap, char do_auto_normalize) { if (do_auto_normalize == FALSE) { return; @@ -1182,9 +1185,11 @@ static void do_weight_paint_auto_normalize_all_groups(MDeformVert *dvert, const MDeformWeight *dw; for (i= dvert->totweight, dw= dvert->dw; i != 0; i--, dw++) { - if (vgroup_validmap[dw->def_nr]) { - tot++; - sum += dw->weight; + if (dw->def_nr < defbase_tot) { + if (vgroup_validmap[dw->def_nr]) { + tot++; + sum += dw->weight; + } } } @@ -1195,8 +1200,10 @@ static void do_weight_paint_auto_normalize_all_groups(MDeformVert *dvert, const fac= 1.0f / sum; for (i= dvert->totweight, dw= dvert->dw; i != 0; i--, dw++) { - if (vgroup_validmap[dw->def_nr]) { - dw->weight *= fac; + if (dw->def_nr < defbase_tot) { + if (vgroup_validmap[dw->def_nr]) { + dw->weight *= fac; + } } } } @@ -1205,12 +1212,17 @@ static void do_weight_paint_auto_normalize_all_groups(MDeformVert *dvert, const /* See if the current deform vertex has a locked group */ -static char has_locked_group(MDeformVert *dvert, const char *lock_flags) +static char has_locked_group(MDeformVert *dvert, const int defbase_tot, + 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; + MDeformWeight *dw; + + for (i= dvert->totweight, dw= dvert->dw; i != 0; i--, dw++) { + if (dw->def_nr < defbase_tot) { + if (lock_flags[dw->def_nr] && dw->weight > 0.0f) { + return TRUE; + } } } return FALSE; @@ -1239,7 +1251,7 @@ static char *gen_lock_flags(Object* ob, int defbase_tot) return NULL; } -static int has_locked_group_selected(int defbase_tot, char *defbase_sel, char *lock_flags) +static int has_locked_group_selected(int defbase_tot, const char *defbase_sel, const char *lock_flags) { int i; for(i = 0; i < defbase_tot; i++) { @@ -1268,7 +1280,7 @@ static int has_unselected_unlocked_bone_group(int defbase_tot, char *defbase_sel #endif -static void multipaint_selection(MDeformVert *dvert, float change, char *defbase_sel, int defbase_tot) +static void multipaint_selection(MDeformVert *dvert, const int defbase_tot, float change, const char *defbase_sel) { int i; MDeformWeight *dw; @@ -1307,7 +1319,10 @@ static void multipaint_selection(MDeformVert *dvert, float change, char *defbase /* 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) +static float redistribute_change(MDeformVert *ndv, const int defbase_tot, + char *change_status, const char change_me, int changeto, + float totchange, float total_valid, + char do_auto_normalize) { float was_change; float change; @@ -1321,30 +1336,35 @@ static float redistribute_change(MDeformVert *ndv, char *change_status, int chan 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; + + /* ignore anything outside the value range */ + if (ndw->def_nr < defbase_tot) { + + /* change only the groups with a valid status */ + if(change_status[ndw->def_nr] == change_me) { + 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; + } } } } @@ -1354,12 +1374,14 @@ static float redistribute_change(MDeformVert *ndv, char *change_status, int chan /* left overs */ return totchange; } -static float get_mp_change(MDeformVert *odv, char *defbase_sel, float brush_change); +static float get_mp_change(MDeformVert *odv, const int defbase_tot, const char *defbase_sel, float brush_change); /* 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, char *defbase_sel, - const char *lock_flags, const char *vgroup_validmap, char do_auto_normalize, char do_multipaint) +static void enforce_locks(MDeformVert *odv, MDeformVert *ndv, + const int defbase_tot, const char *defbase_sel, + const char *lock_flags, const char *vgroup_validmap, + char do_auto_normalize, char do_multipaint) { float totchange = 0.0f; float totchange_allowed = 0.0f; @@ -1375,7 +1397,7 @@ static void enforce_locks(MDeformVert *odv, MDeformVert *ndv, int defbase_tot, c char *change_status; - if(!lock_flags || !has_locked_group(ndv, lock_flags)) { + if(!lock_flags || !has_locked_group(ndv, defbase_tot, lock_flags)) { return; } /* record if a group was changed, unlocked and not changed, or locked */ @@ -1439,17 +1461,17 @@ static void enforce_locks(MDeformVert *odv, MDeformVert *ndv, int defbase_tot, c 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); + totchange_allowed = redistribute_change(ndv, defbase_tot, 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 with multipaint, so keep them changed that way! */ if(total_changed > 1 && do_multipaint) { - float undo_change = get_mp_change(ndv, defbase_sel, left_over); - multipaint_selection(ndv, undo_change, defbase_sel, defbase_tot); + float undo_change = get_mp_change(ndv, defbase_tot, defbase_sel, left_over); + multipaint_selection(ndv, defbase_tot, undo_change, defbase_sel); } /* 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); + redistribute_change(ndv, defbase_tot, change_status, 2, -2, left_over, total_changed, do_auto_normalize); } } } @@ -1469,15 +1491,17 @@ static void enforce_locks(MDeformVert *odv, MDeformVert *ndv, int defbase_tot, c } /* 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) +static float get_mp_change(MDeformVert *odv, const int defbase_tot, const 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 (dw->def_nr < defbase_tot) { + if(defbase_sel[dw->def_nr]) { + selwsum += dw->weight; + } } } if(selwsum && selwsum+brush_change > 0) { @@ -1523,13 +1547,13 @@ typedef struct WeightPaintInfo { 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 */ + const char *lock_flags; /* boolean array for locked bones, + * length of defbase_tot */ + const char *defbase_sel; /* boolean array for selected bones, + * length of defbase_tot, cant be const because of how its passed */ - char *vgroup_validmap; /* same as WeightPaintData.vgroup_validmap, - * only added here for convenience */ + const char *vgroup_validmap; /* same as WeightPaintData.vgroup_validmap, + * only added here for convenience */ char do_flip; char do_multipaint; @@ -1538,7 +1562,10 @@ typedef struct 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 */ + * normalizing while multi-painting + * + * note: this assumes dw->def_nr range has been checked by the caller + */ static int apply_mp_locks_normalize(Mesh *me, const WeightPaintInfo *wpi, const unsigned int index, MDeformWeight *dw, MDeformWeight *tdw, @@ -1553,13 +1580,13 @@ static int apply_mp_locks_normalize(Mesh *me, const WeightPaintInfo *wpi, 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->lock_flags == NULL) || + ((wpi->lock_flags[dw->def_nr] == FALSE) && /* def_nr range has to be checked for by caller */ + 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); + multipaint_selection(dv, wpi->defbase_tot, change, wpi->defbase_sel); } } else { /* this lets users paint normally, but don't let them paint locked groups */ @@ -1570,7 +1597,7 @@ static int apply_mp_locks_normalize(Mesh *me, const WeightPaintInfo *wpi, enforce_locks(&dv_test, dv, wpi->defbase_tot, wpi->defbase_sel, wpi->lock_flags, wpi->vgroup_validmap, wpi->do_auto_normalize, wpi->do_multipaint); - do_weight_paint_auto_normalize_all_groups(dv, wpi->vgroup_validmap, wpi->do_auto_normalize); + do_weight_paint_auto_normalize_all_groups(dv, wpi->defbase_tot, wpi->vgroup_validmap, wpi->do_auto_normalize); if(oldChange && wpi->do_multipaint && wpi->defbase_tot_sel > 1) { if(tdw->weight != oldw) { @@ -1594,13 +1621,15 @@ static int apply_mp_locks_normalize(Mesh *me, const WeightPaintInfo *wpi, /* 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) +static int get_first_selected_nonzero_weight(MDeformVert *dvert, const int defbase_tot, const 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; + if (dw->def_nr < defbase_tot) { + if (defbase_sel[dw->def_nr] && dw->weight > 0.0f) { + return i; + } } } return -1; @@ -1640,8 +1669,8 @@ static void do_weight_paint_vertex( /* vars which remain the same for every vert /* 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(dv, wpi->lock_flags) == FALSE)) + if ( (wpi->do_multipaint == FALSE || wpi->defbase_tot_sel <= 1) && + (wpi->lock_flags == NULL || has_locked_group(dv, wpi->defbase_tot, wpi->lock_flags) == FALSE)) { wpaint_blend(wp, dw, uw, alpha, paintweight, wpi->do_flip, FALSE); @@ -1659,7 +1688,7 @@ static void do_weight_paint_vertex( /* vars which remain the same for every vert * which has already been scaled down in relation to other weights, * then scales a second time [#26193]. Tricky multi-paint code doesn't * suffer from this problem - campbell */ - do_weight_paint_auto_normalize_all_groups(dv, wpi->vgroup_validmap, wpi->do_auto_normalize); + do_weight_paint_auto_normalize_all_groups(dv, wpi->defbase_tot, wpi->vgroup_validmap, wpi->do_auto_normalize); } else { /* use locks and/or multipaint */ @@ -1684,13 +1713,13 @@ static void do_weight_paint_vertex( /* vars which remain the same for every vert dv_copy.totweight = dv->totweight; tdw = dw; tuw = uw; - change = get_mp_change(wp->wpaint_prev+index, wpi->defbase_sel, neww - oldw); + change = get_mp_change(&wp->wpaint_prev[index], wpi->defbase_tot, wpi->defbase_sel, neww - oldw); if(change) { if(!tdw->weight) { - i = get_first_selected_nonzero_weight(dv, wpi->defbase_sel); + i = get_first_selected_nonzero_weight(dv, wpi->defbase_tot, wpi->defbase_sel); if(i>=0) { tdw = &(dv->dw[i]); - tuw = defvert_verify_index(wp->wpaint_prev+index, tdw->def_nr); + tuw = defvert_verify_index(&wp->wpaint_prev[index], tdw->def_nr); } else { change = 0; @@ -1847,8 +1876,8 @@ struct WPaintData { float wpimat[3][3]; /*variables for auto normalize*/ - char *vgroup_validmap; /*stores if vgroups tie to deforming bones or not*/ - char *lock_flags; + const char *vgroup_validmap; /*stores if vgroups tie to deforming bones or not*/ + const char *lock_flags; int defbase_tot; }; @@ -1903,6 +1932,8 @@ static char *wpaint_make_validmap(Object *ob) vgroup_validmap[i]= (BLI_ghash_lookup(gh, dg->name) != NULL); } + BLI_assert(i == BLI_ghash_size(gh)); + BLI_ghash_free(gh, NULL, NULL); return vgroup_validmap; @@ -2005,6 +2036,7 @@ static void wpaint_stroke_update_step(bContext *C, struct PaintStroke *stroke, P float alpha; float mval[2], pressure; int use_vert_sel; + char *defbase_sel; /* intentionally dont initialize as NULL, make sure we initialize all members below */ WeightPaintInfo wpi; @@ -2036,9 +2068,11 @@ static void wpaint_stroke_update_step(bContext *C, struct PaintStroke *stroke, P /* *** 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); + defbase_sel= MEM_mallocN(wpi.defbase_tot*sizeof(char), "wpi.defbase_sel"); + wpi.defbase_tot_sel= get_selected_defgroups(ob, defbase_sel, wpi.defbase_tot); + wpi.defbase_sel= defbase_sel; /* so we can stay const */ if(wpi.defbase_tot_sel == 0 && ob->actdef > 0) 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; @@ -2160,7 +2194,7 @@ static void wpaint_stroke_update_step(bContext *C, struct PaintStroke *stroke, P /* *** free wpi members */ - MEM_freeN(wpi.defbase_sel); + MEM_freeN((void *)wpi.defbase_sel); /* *** dont freeing wpi members */ @@ -2182,9 +2216,9 @@ static void wpaint_stroke_done(bContext *C, struct PaintStroke *stroke) MEM_freeN(wpd->indexar); if (wpd->vgroup_validmap) - MEM_freeN(wpd->vgroup_validmap); + MEM_freeN((void *)wpd->vgroup_validmap); if(wpd->lock_flags) - MEM_freeN(wpd->lock_flags); + MEM_freeN((void *)wpd->lock_flags); MEM_freeN(wpd); } @@ -2215,8 +2249,8 @@ static int wpaint_invoke(bContext *C, wmOperator *op, wmEvent *event) { op->customdata = paint_stroke_new(C, NULL, wpaint_stroke_test_start, - wpaint_stroke_update_step, - wpaint_stroke_done, event->type); + wpaint_stroke_update_step, + wpaint_stroke_done, event->type); /* add modal handler */ WM_event_add_modal_handler(C, op); diff --git a/source/blender/editors/space_outliner/outliner_tree.c b/source/blender/editors/space_outliner/outliner_tree.c index 794f898a1fc..084e48c0d6e 100644 --- a/source/blender/editors/space_outliner/outliner_tree.c +++ b/source/blender/editors/space_outliner/outliner_tree.c @@ -977,7 +977,7 @@ static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *i if(te->name) te->flag |= TE_FREE_NAME; else - te->name= (char*)RNA_struct_ui_name(ptr->type); + te->name= RNA_struct_ui_name(ptr->type); /* If searching don't expand RNA entries */ if(SEARCHING_OUTLINER(soops) && BLI_strcasecmp("RNA",te->name)==0) tselem->flag &= ~TSE_CHILDSEARCH; @@ -1007,7 +1007,7 @@ static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *i prop= propptr.data; proptype= RNA_property_type(prop); - te->name= (char*)RNA_property_ui_name(prop); + te->name= RNA_property_ui_name(prop); te->directdata= prop; te->rnaptr= *ptr; diff --git a/source/blender/editors/space_view3d/drawmesh.c b/source/blender/editors/space_view3d/drawmesh.c index 76ff7c08860..2c0af90a4d6 100644 --- a/source/blender/editors/space_view3d/drawmesh.c +++ b/source/blender/editors/space_view3d/drawmesh.c @@ -531,7 +531,7 @@ static int draw_tface_mapped__set_draw(void *userData, int index) static int draw_em_tf_mapped__set_draw(void *userData, int index) { - struct {DerivedMesh *dm; BMEditMesh *em; short has_mcol; short has_mtface;} *data = userData; + struct {BMEditMesh *em; short has_mcol; short has_mtface; MFace *mf; MTFace *tf;} *data = userData; BMEditMesh *em = data->em; BMFace *efa= EDBM_get_face_for_index(em, index); @@ -660,14 +660,12 @@ static void draw_mesh_text(Scene *scene, Object *ob, int glsl) static int compareDrawOptions(void *userData, int cur_index, int next_index) { - DerivedMesh *dm= (DerivedMesh*) userData; - MFace *mf = DM_get_tessface_data_layer(dm, CD_MFACE); - MTFace *tf = DM_get_tessface_data_layer(dm, CD_MTFACE); + struct { MFace *mf; MTFace *tf; } *data = userData; - if(mf && mf[cur_index].mat_nr != mf[next_index].mat_nr) + if(data->mf && data->mf[cur_index].mat_nr != data->mf[next_index].mat_nr) return 0; - if(tf && tf[cur_index].tpage != tf[next_index].tpage) + if(data->tf && data->tf[cur_index].tpage != data->tf[next_index].tpage) return 0; return 1; @@ -675,14 +673,12 @@ static int compareDrawOptions(void *userData, int cur_index, int next_index) static int compareDrawOptionsEm(void *userData, int cur_index, int next_index) { - struct {DerivedMesh *dm; EditMesh *em; short has_mcol; short has_mtface;} *data= userData; - MFace *mf = DM_get_tessface_data_layer(data->dm, CD_MFACE); - MTFace *tf = DM_get_tessface_data_layer(data->dm, CD_MTFACE); + struct {BMEditMesh *em; short has_mcol; short has_mtface; MFace *mf; MTFace *tf;} *data= userData; - if(mf && mf[cur_index].mat_nr != mf[next_index].mat_nr) + if(data->mf && data->mf[cur_index].mat_nr != data->mf[next_index].mat_nr) return 0; - if(tf && tf[cur_index].tpage != tf[next_index].tpage) + if(data->tf && data->tf[cur_index].tpage != data->tf[next_index].tpage) return 0; return 1; @@ -702,12 +698,13 @@ void draw_mesh_textured_old(Scene *scene, View3D *v3d, RegionView3D *rv3d, Objec glColor4f(1.0f,1.0f,1.0f,1.0f); if(ob->mode & OB_MODE_EDIT) { - struct {DerivedMesh *dm; BMEditMesh *em; short has_mcol; short has_mtface;} data; + struct {BMEditMesh *em; short has_mcol; short has_mtface; MFace *mf; MTFace *tf;} data; - data.dm = dm; data.em= me->edit_btmesh; data.has_mcol= CustomData_has_layer(&me->edit_btmesh->bm->ldata, CD_MLOOPCOL); data.has_mtface= CustomData_has_layer(&me->edit_btmesh->bm->pdata, CD_MTEXPOLY); + data.mf= DM_get_tessface_data_layer(dm, CD_MFACE); + data.tf= DM_get_tessface_data_layer(dm, CD_MTFACE); dm->drawMappedFacesTex(dm, draw_em_tf_mapped__set_draw, compareDrawOptionsEm, &data); } @@ -725,10 +722,15 @@ void draw_mesh_textured_old(Scene *scene, View3D *v3d, RegionView3D *rv3d, Objec dm->drawFacesTex(dm, draw_tface__set_draw_legacy, NULL, NULL); } else { + struct { MFace *mf; MTFace *tf; } userData; + if(!CustomData_has_layer(&dm->faceData,CD_TEXTURE_MCOL)) add_tface_color_layer(dm); - dm->drawFacesTex(dm, draw_tface__set_draw, compareDrawOptions, dm); + userData.mf = DM_get_tessface_data_layer(dm, CD_MFACE); + userData.tf = DM_get_tessface_data_layer(dm, CD_MTFACE); + + dm->drawFacesTex(dm, draw_tface__set_draw, compareDrawOptions, &userData); } } diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c index dd6e31ef8c4..edcfc42a798 100644 --- a/source/blender/editors/space_view3d/drawobject.c +++ b/source/blender/editors/space_view3d/drawobject.c @@ -2375,7 +2375,7 @@ static void draw_dm_edges_sharp(BMEditMesh *em, DerivedMesh *dm) * return 2 for the active face so it renders with stipple enabled */ static int draw_dm_faces_sel__setDrawOptions(void *userData, int index, int *UNUSED(drawSmooth_r)) { - struct { DerivedMesh *dm; unsigned char *cols[3]; BMEditMesh *em; BMFace *efa_act; Mesh *me;} *data = userData; + struct { DerivedMesh *dm; unsigned char *cols[3]; BMEditMesh *em; BMFace *efa_act; int *orig_index;} *data = userData; BMFace *efa = EDBM_get_face_for_index(data->em, index); unsigned char *col; @@ -2398,18 +2398,18 @@ static int draw_dm_faces_sel__setDrawOptions(void *userData, int index, int *UNU static int draw_dm_faces_sel__compareDrawOptions(void *userData, int index, int next_index) { - struct { DerivedMesh *dm; unsigned char *cols[3]; BMEditMesh *em; BMFace *efa_act; Mesh *me;} * data = userData; - int *orig_index= DM_get_tessface_data_layer(data->dm, CD_ORIGINDEX); + + struct { DerivedMesh *dm; unsigned char *cols[3]; BMEditMesh *em; BMFace *efa_act; int *orig_index; } * data = userData; BMFace *efa; BMFace *next_efa; unsigned char *col, *next_col; - if(!orig_index) + if(!data->orig_index) return 0; - efa= EDBM_get_face_for_index(data->em, orig_index[index]); - next_efa= EDBM_get_face_for_index(data->em, orig_index[next_index]); + efa= EDBM_get_face_for_index(data->em, data->orig_index[index]); + next_efa= EDBM_get_face_for_index(data->em, data->orig_index[next_index]); if(efa == next_efa) return 1; @@ -2428,16 +2428,16 @@ static int draw_dm_faces_sel__compareDrawOptions(void *userData, int index, int /* also draws the active face */ static void draw_dm_faces_sel(BMEditMesh *em, DerivedMesh *dm, unsigned char *baseCol, - unsigned char *selCol, unsigned char *actCol, BMFace *efa_act, Mesh *me) + unsigned char *selCol, unsigned char *actCol, BMFace *efa_act) { - struct { DerivedMesh *dm; unsigned char *cols[3]; BMEditMesh *em; BMFace *efa_act; Mesh *me;} data; + struct { DerivedMesh *dm; unsigned char *cols[3]; BMEditMesh *em; BMFace *efa_act; int *orig_index; } data; data.dm= dm; data.cols[0] = baseCol; data.em = em; data.cols[1] = selCol; data.cols[2] = actCol; data.efa_act = efa_act; - data.me = me; + data.orig_index = DM_get_tessface_data_layer(dm, CD_ORIGINDEX); dm->drawMappedFaces(dm, draw_dm_faces_sel__setDrawOptions, GPU_enable_material, draw_dm_faces_sel__compareDrawOptions, &data, 0); } @@ -2928,7 +2928,7 @@ static void draw_em_fancy(Scene *scene, View3D *v3d, RegionView3D *rv3d, if CHECK_OB_DRAWTEXTURE(v3d, dt) col1[3] = 0; - draw_dm_faces_sel(em, cageDM, col1, col2, col3, efa_act, me); + draw_dm_faces_sel(em, cageDM, col1, col2, col3, efa_act); glDisable(GL_BLEND); glDepthMask(1); // restore write in zbuffer @@ -2943,7 +2943,7 @@ static void draw_em_fancy(Scene *scene, View3D *v3d, RegionView3D *rv3d, glEnable(GL_BLEND); glDepthMask(0); // disable write in zbuffer, needed for nice transp - draw_dm_faces_sel(em, cageDM, col1, col2, col3, efa_act, me); + draw_dm_faces_sel(em, cageDM, col1, col2, col3, efa_act); glDisable(GL_BLEND); glDepthMask(1); // restore write in zbuffer diff --git a/source/blender/gpu/GPU_material.h b/source/blender/gpu/GPU_material.h index 418bea5fe9c..5689f02d2d7 100644 --- a/source/blender/gpu/GPU_material.h +++ b/source/blender/gpu/GPU_material.h @@ -83,7 +83,8 @@ typedef enum GPUBuiltin { GPU_INVERSE_OBJECT_MATRIX = 8, GPU_VIEW_POSITION = 16, GPU_VIEW_NORMAL = 32, - GPU_OBCOLOR = 64 + GPU_OBCOLOR = 64, + GPU_AUTO_BUMPSCALE = 128 } GPUBuiltin; typedef enum GPUBlendMode { @@ -129,7 +130,7 @@ void GPU_material_free(struct Material *ma); void GPU_materials_free(void); void GPU_material_bind(GPUMaterial *material, int oblay, int viewlay, double time, int mipmap); -void GPU_material_bind_uniforms(GPUMaterial *material, float obmat[][4], float viewmat[][4], float viewinv[][4], float obcol[4]); +void GPU_material_bind_uniforms(GPUMaterial *material, float obmat[][4], float viewmat[][4], float viewinv[][4], float obcol[4], float autobumpscale); void GPU_material_unbind(GPUMaterial *material); int GPU_material_bound(GPUMaterial *material); @@ -162,6 +163,7 @@ typedef enum GPUDynamicType { GPU_DYNAMIC_OBJECT_VIEWIMAT = 3, GPU_DYNAMIC_OBJECT_IMAT = 4, GPU_DYNAMIC_OBJECT_COLOR = 5, + GPU_DYNAMIC_OBJECT_AUTOBUMPSCALE = 15, GPU_DYNAMIC_LAMP_FIRST = 6, GPU_DYNAMIC_LAMP_DYNVEC = 6, GPU_DYNAMIC_LAMP_DYNCO = 7, diff --git a/source/blender/gpu/intern/gpu_codegen.c b/source/blender/gpu/intern/gpu_codegen.c index 185f9eb185e..05c459b703d 100644 --- a/source/blender/gpu/intern/gpu_codegen.c +++ b/source/blender/gpu/intern/gpu_codegen.c @@ -344,6 +344,8 @@ const char *GPU_builtin_name(GPUBuiltin builtin) return "varnormal"; else if(builtin == GPU_OBCOLOR) return "unfobcolor"; + else if(builtin == GPU_AUTO_BUMPSCALE) + return "unfobautobumpscale"; else return ""; } diff --git a/source/blender/gpu/intern/gpu_draw.c b/source/blender/gpu/intern/gpu_draw.c index 3cd3cde8aad..4af0cceb4e0 100644 --- a/source/blender/gpu/intern/gpu_draw.c +++ b/source/blender/gpu/intern/gpu_draw.c @@ -60,6 +60,7 @@ #include "BKE_node.h" #include "BKE_object.h" #include "BKE_scene.h" +#include "BKE_DerivedMesh.h" #include "BLI_threads.h" #include "BLI_blenlib.h" @@ -1155,11 +1156,14 @@ int GPU_enable_material(int nr, void *attribs) if(gattribs && GMS.gmatbuf[nr]) { /* bind glsl material and get attributes */ Material *mat = GMS.gmatbuf[nr]; + float auto_bump_scale; gpumat = GPU_material_from_blender(GMS.gscene, mat); GPU_material_vertex_attributes(gpumat, gattribs); 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); + + auto_bump_scale = GMS.gob->derivedFinal != NULL ? GMS.gob->derivedFinal->auto_bump_scale : 1.0f; + GPU_material_bind_uniforms(gpumat, GMS.gob->obmat, GMS.gviewmat, GMS.gviewinv, GMS.gob->col, auto_bump_scale); GMS.gboundmat= mat; /* for glsl use alpha blend mode, unless it's set to solid and diff --git a/source/blender/gpu/intern/gpu_material.c b/source/blender/gpu/intern/gpu_material.c index 397c0e32c69..2d8487deb71 100644 --- a/source/blender/gpu/intern/gpu_material.c +++ b/source/blender/gpu/intern/gpu_material.c @@ -94,7 +94,7 @@ struct GPUMaterial { /* for passing uniforms */ int viewmatloc, invviewmatloc; int obmatloc, invobmatloc; - int obcolloc; + int obcolloc, obautobumpscaleloc; ListBase lamps; }; @@ -212,7 +212,8 @@ static int GPU_material_construct_end(GPUMaterial *material) material->invobmatloc = GPU_shader_get_uniform(shader, GPU_builtin_name(GPU_INVERSE_OBJECT_MATRIX)); if(material->builtins & GPU_OBCOLOR) material->obcolloc = GPU_shader_get_uniform(shader, GPU_builtin_name(GPU_OBCOLOR)); - + if(material->builtins & GPU_AUTO_BUMPSCALE) + material->obautobumpscaleloc = GPU_shader_get_uniform(shader, GPU_builtin_name(GPU_AUTO_BUMPSCALE)); return 1; } @@ -273,7 +274,7 @@ void GPU_material_bind(GPUMaterial *material, int oblay, int viewlay, double tim } } -void GPU_material_bind_uniforms(GPUMaterial *material, float obmat[][4], float viewmat[][4], float viewinv[][4], float obcol[4]) +void GPU_material_bind_uniforms(GPUMaterial *material, float obmat[][4], float viewmat[][4], float viewinv[][4], float obcol[4], float autobumpscale) { if(material->pass) { GPUShader *shader = GPU_pass_shader(material->pass); @@ -300,7 +301,9 @@ void GPU_material_bind_uniforms(GPUMaterial *material, float obmat[][4], float v CLAMP(col[3], 0.0f, 1.0f); GPU_shader_uniform_vector(shader, material->obcolloc, 4, 1, col); } - + if(material->builtins & GPU_AUTO_BUMPSCALE) { + GPU_shader_uniform_vector(shader, material->obautobumpscaleloc, 1, 1, &autobumpscale); + } /* update lamps */ for(nlink=material->lamps.first; nlink; nlink=nlink->next) { lamp= nlink->data; @@ -1087,8 +1090,7 @@ static void do_material_tex(GPUShadeInput *shi) /* ntap bumpmap image */ int iBumpSpace; float ima_x, ima_y; - float hScale = 0.1f; // compatibility adjustment factor for all bumpspace types - float hScaleTex = 13.0f; // factor for scaling texspace bumps + float hScale; float imag_tspace_dimension_x = 1024.0f; // only used for texture space variant float aspect = 1.0f; @@ -1096,16 +1098,35 @@ static void do_material_tex(GPUShadeInput *shi) GPUNodeLink *surf_pos = GPU_builtin(GPU_VIEW_POSITION); GPUNodeLink *vR1, *vR2; GPUNodeLink *dBs, *dBt, *fDet; - + + hScale = 0.1; // compatibility adjustment factor for all bumpspace types if( mtex->texflag & MTEX_BUMP_TEXTURESPACE ) - hScale = hScaleTex; + hScale = 13.0f; // factor for scaling texspace bumps + else if(found_deriv_map!=0) + hScale = 1.0f; + + // resolve texture resolution + if( (mtex->texflag & MTEX_BUMP_TEXTURESPACE) || found_deriv_map ) { + ImBuf *ibuf= BKE_image_get_ibuf(tex->ima, &tex->iuser); + ima_x= 512.0f; ima_y= 512.f; // prevent calling textureSize, glsl 1.3 only + if(ibuf) { + ima_x= ibuf->x; + ima_y= ibuf->y; + aspect = ((float) ima_y) / ima_x; + } + } // The negate on norfac is done because the // normal in the renderer points inward which corresponds // to inverting the bump map. Should this ever change // this negate must be removed. norfac = -hScale * mtex->norfac; + if(found_deriv_map) norfac /= sqrtf(ima_x*ima_y); + tnorfac = GPU_uniform(&norfac); + + if(found_deriv_map) + GPU_link(mat, "math_multiply", tnorfac, GPU_builtin(GPU_AUTO_BUMPSCALE), &tnorfac); if(GPU_link_changed(stencil)) GPU_link(mat, "math_multiply", tnorfac, stencil, &tnorfac); @@ -1152,17 +1173,6 @@ static void do_material_tex(GPUShadeInput *shi) iBumpSpacePrev = iBumpSpace; } - - // resolve texture resolution - if( (mtex->texflag & MTEX_BUMP_TEXTURESPACE) || found_deriv_map ) { - ImBuf *ibuf= BKE_image_get_ibuf(tex->ima, &tex->iuser); - ima_x= 512.0f; ima_y= 512.f; // prevent calling textureSize, glsl 1.3 only - if(ibuf) { - ima_x= ibuf->x; - ima_y= ibuf->y; - aspect = ((float) ima_y) / ima_x; - } - } if(found_deriv_map) { @@ -1703,6 +1713,7 @@ GPUShaderExport *GPU_shader_export(struct Scene *scene, struct Material *ma) { GPU_OBJECT_MATRIX, GPU_DYNAMIC_OBJECT_MAT, GPU_DATA_16F }, { GPU_INVERSE_OBJECT_MATRIX, GPU_DYNAMIC_OBJECT_IMAT, GPU_DATA_16F }, { GPU_OBCOLOR, GPU_DYNAMIC_OBJECT_COLOR, GPU_DATA_4F }, + { GPU_AUTO_BUMPSCALE, GPU_DYNAMIC_OBJECT_AUTOBUMPSCALE, GPU_DATA_1F }, { 0 } }; diff --git a/source/blender/makesrna/intern/rna_access.c b/source/blender/makesrna/intern/rna_access.c index fa2fb061e3e..a31984dfc29 100644 --- a/source/blender/makesrna/intern/rna_access.c +++ b/source/blender/makesrna/intern/rna_access.c @@ -3751,7 +3751,7 @@ char *RNA_path_append(const char *path, PointerRNA *UNUSED(ptr), PropertyRNA *pr BLI_dynstr_append(dynstr, "."); } - BLI_dynstr_append(dynstr, (char*)RNA_property_identifier(prop)); + BLI_dynstr_append(dynstr, RNA_property_identifier(prop)); if(RNA_property_type(prop) == PROP_COLLECTION) { /* add ["strkey"] or [intkey] */ diff --git a/source/blender/modifiers/intern/MOD_hook.c b/source/blender/modifiers/intern/MOD_hook.c index e04d5113364..a6eb9ab1e48 100644 --- a/source/blender/modifiers/intern/MOD_hook.c +++ b/source/blender/modifiers/intern/MOD_hook.c @@ -185,22 +185,20 @@ static void deformVerts_do(HookModifierData *hmd, Object *ob, DerivedMesh *dm, const float fac_orig= hmd->force; float fac; const int *origindex_ar; - - /* if DerivedMesh is present and has original index data, - * use it - */ + + /* if DerivedMesh is present and has original index data, use it */ if(dm && (origindex_ar= dm->getVertDataArray(dm, CD_ORIGINDEX))) { for(i= 0, index_pt= hmd->indexar; i < hmd->totindex; i++, index_pt++) { if(*index_pt < numVerts) { int j; - + for(j = 0; j < numVerts; j++) { if(origindex_ar[j] == *index_pt) { float *co = vertexCos[j]; if((fac= hook_falloff(hmd->cent, co, falloff_squared, fac_orig))) { if(dvert) fac *= defvert_find_weight(dvert+j, defgrp_index); - + if(fac) { mul_v3_m4v3(vec, mat, co); interp_v3_v3v3(co, co, vec, fac); @@ -218,7 +216,7 @@ static void deformVerts_do(HookModifierData *hmd, Object *ob, DerivedMesh *dm, if((fac= hook_falloff(hmd->cent, co, falloff_squared, fac_orig))) { if(dvert) fac *= defvert_find_weight(dvert+(*index_pt), defgrp_index); - + if(fac) { mul_v3_m4v3(vec, mat, co); interp_v3_v3v3(co, co, vec, fac); @@ -230,11 +228,11 @@ static void deformVerts_do(HookModifierData *hmd, Object *ob, DerivedMesh *dm, } else if(dvert) { /* vertex group hook */ const float fac_orig= hmd->force; - + for(i = 0; i < max_dvert; i++, dvert++) { float fac; float *co = vertexCos[i]; - + if((fac= hook_falloff(hmd->cent, co, falloff_squared, fac_orig))) { fac *= defvert_find_weight(dvert, defgrp_index); if(fac) { @@ -251,12 +249,8 @@ static void deformVerts(ModifierData *md, Object *ob, DerivedMesh *derivedData, int UNUSED(useRenderParams), int UNUSED(isFinalCalc)) { HookModifierData *hmd = (HookModifierData*) md; - DerivedMesh *dm = get_dm(ob, NULL, derivedData, NULL, 0); - - deformVerts_do(hmd, ob, dm, vertexCos, numVerts); - - if(derivedData != dm) - dm->release(dm); + + deformVerts_do(hmd, ob, derivedData, vertexCos, numVerts); } static void deformVertsEM(ModifierData *md, Object *ob, struct BMEditMesh *editData, diff --git a/source/blender/modifiers/intern/MOD_mask.c b/source/blender/modifiers/intern/MOD_mask.c index 046eb0e5d03..cdb92ab432c 100644 --- a/source/blender/modifiers/intern/MOD_mask.c +++ b/source/blender/modifiers/intern/MOD_mask.c @@ -137,12 +137,13 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, bDeformGroup *def; char *bone_select_array; int bone_select_tot= 0; + const int defbase_tot= BLI_countlist(&ob->defbase); /* check that there is armature object with bones to use, otherwise return original mesh */ if (ELEM3(NULL, mmd->ob_arm, mmd->ob_arm->pose, ob->defbase.first)) return derivedData; - bone_select_array= MEM_mallocN(BLI_countlist(&ob->defbase) * sizeof(char), "mask array"); + bone_select_array= MEM_mallocN(defbase_tot * sizeof(char), "mask array"); for (i = 0, def = ob->defbase.first; def; def = def->next, i++) { @@ -194,12 +195,12 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, MDeformWeight *dw= dv->dw; int j; - for (j= dv->totweight; j > 0; j--, dw++) - { - if (bone_select_array[dw->def_nr]) - { - if(dw->weight != 0.0f) { - break; + for (j= dv->totweight; j > 0; j--, dw++) { + if (dw->def_nr < defbase_tot) { + if (bone_select_array[dw->def_nr]) { + if(dw->weight != 0.0f) { + break; + } } } } diff --git a/source/blender/python/intern/gpu.c b/source/blender/python/intern/gpu.c index 57ce7b59067..0da63297077 100644 --- a/source/blender/python/intern/gpu.c +++ b/source/blender/python/intern/gpu.c @@ -87,6 +87,7 @@ PyInit_gpu(void) PY_MODULE_ADD_CONSTANT(m, GPU_DYNAMIC_OBJECT_VIEWIMAT); PY_MODULE_ADD_CONSTANT(m, GPU_DYNAMIC_OBJECT_IMAT); PY_MODULE_ADD_CONSTANT(m, GPU_DYNAMIC_OBJECT_COLOR); + PY_MODULE_ADD_CONSTANT(m, GPU_DYNAMIC_OBJECT_AUTOBUMPSCALE); PY_MODULE_ADD_CONSTANT(m, GPU_DYNAMIC_LAMP_DYNVEC); PY_MODULE_ADD_CONSTANT(m, GPU_DYNAMIC_LAMP_DYNCO); PY_MODULE_ADD_CONSTANT(m, GPU_DYNAMIC_LAMP_DYNIMAT); diff --git a/source/blender/render/intern/source/render_texture.c b/source/blender/render/intern/source/render_texture.c index 412f45d184e..fffedb18687 100644 --- a/source/blender/render/intern/source/render_texture.c +++ b/source/blender/render/intern/source/render_texture.c @@ -1932,11 +1932,13 @@ static int ntap_bump_compute(NTapBump *ntap_bump, ShadeInput *shi, MTex *mtex, T float *nvec = texres->nor; texres->nor = NULL; - if( mtex->texflag & MTEX_BUMP_TEXTURESPACE ) { - if(tex->ima) - Hscale *= 13.0f; // appears to be a sensible default value - } else - Hscale *= 0.1f; // factor 0.1 proved to look like the previous bump code + if(found_deriv_map==0) { + if( mtex->texflag & MTEX_BUMP_TEXTURESPACE ) { + if(tex->ima) + Hscale *= 13.0f; // appears to be a sensible default value + } else + Hscale *= 0.1f; // factor 0.1 proved to look like the previous bump code + } if( !ntap_bump->init_done ) { copy_v3_v3(ntap_bump->vNacc, shi->vn); @@ -1958,15 +1960,21 @@ static int ntap_bump_compute(NTapBump *ntap_bump, ShadeInput *shi, MTex *mtex, T } if(found_deriv_map) { - float dBdu, dBdv; + float dBdu, dBdv, auto_bump = 1.0f; float s = 1; // negate this if flipped texture coordinate texco_mapping(shi, tex, mtex, co, dx, dy, texvec, dxt, dyt); rgbnor = multitex_mtex(shi, mtex, texvec, dxt, dyt, texres); + + if(shi->obr->ob->derivedFinal) + { + auto_bump = shi->obr->ob->derivedFinal->auto_bump_scale; + auto_bump /= sqrtf((float) (dimx*dimy)); + } // this variant using a derivative map is described here // http://mmikkelsen3d.blogspot.com/2011/07/derivative-maps.html - dBdu = Hscale*dimx*(2*texres->tr-1); - dBdv = Hscale*dimy*(2*texres->tg-1); + dBdu = auto_bump*Hscale*dimx*(2*texres->tr-1); + dBdv = auto_bump*Hscale*dimy*(2*texres->tg-1); dHdx = dBdu*dxt[0] + s * dBdv*dxt[1]; dHdy = dBdu*dyt[0] + s * dBdv*dyt[1]; diff --git a/source/gameengine/Converter/BL_SkinDeformer.cpp b/source/gameengine/Converter/BL_SkinDeformer.cpp index 81533205909..0c4806f4bd8 100644 --- a/source/gameengine/Converter/BL_SkinDeformer.cpp +++ b/source/gameengine/Converter/BL_SkinDeformer.cpp @@ -217,14 +217,14 @@ void BL_SkinDeformer::BGEDeformVerts() Object *par_arma = m_armobj->GetArmatureObject(); MDeformVert *dverts = m_bmesh->dvert; bDeformGroup *dg; - int numGroups = BLI_countlist(&m_objMesh->defbase); + int defbase_tot = BLI_countlist(&m_objMesh->defbase); if (!dverts) return; if (m_dfnrToPC == NULL) { - m_dfnrToPC = new bPoseChannel*[numGroups]; + m_dfnrToPC = new bPoseChannel*[defbase_tot]; int i; for (i=0, dg=(bDeformGroup*)m_objMesh->defbase.first; dg; @@ -260,7 +260,7 @@ void BL_SkinDeformer::BGEDeformVerts() { int index = dvert->dw[j].def_nr; - if (index < numGroups && (pchan=m_dfnrToPC[index])) + if (index < defbase_tot && (pchan=m_dfnrToPC[index])) { weight = dvert->dw[j].weight; diff --git a/source/gameengine/Ketsji/BL_BlenderShader.cpp b/source/gameengine/Ketsji/BL_BlenderShader.cpp index 6680e9556b9..0f97898c73f 100644 --- a/source/gameengine/Ketsji/BL_BlenderShader.cpp +++ b/source/gameengine/Ketsji/BL_BlenderShader.cpp @@ -8,6 +8,7 @@ #include "BKE_global.h" #include "BKE_main.h" +#include "BKE_DerivedMesh.h" #include "BL_BlenderShader.h" #include "BL_Material.h" @@ -146,7 +147,8 @@ void BL_BlenderShader::Update(const RAS_MeshSlot & ms, RAS_IRasterizer* rasty ) else obcol[0]= obcol[1]= obcol[2]= obcol[3]= 1.0f; - GPU_material_bind_uniforms(gpumat, obmat, viewmat, viewinvmat, obcol); + float auto_bump_scale = ms.m_pDerivedMesh!=0 ? ms.m_pDerivedMesh->auto_bump_scale : 1.0f; + GPU_material_bind_uniforms(gpumat, obmat, viewmat, viewinvmat, obcol, auto_bump_scale); mAlphaBlend = GPU_material_alpha_blend(gpumat, obcol); }