diff options
author | Sergey Sharybin <sergey.vfx@gmail.com> | 2011-12-09 14:02:01 +0400 |
---|---|---|
committer | Sergey Sharybin <sergey.vfx@gmail.com> | 2011-12-09 14:02:01 +0400 |
commit | 3717a4a9e1ef159ce9b75738cd40122bbd01671b (patch) | |
tree | aaa8c6affd659e4809156c58d82a16ff1ece359b | |
parent | dbc9227a3247e2138f964b1687e3467f3f4b9741 (diff) | |
parent | f025b7b51159cf3cdf49e9ec0eeaf4427010e1f7 (diff) |
Merging r42482 through r42532 from trunk into soc-2011-tomato
54 files changed, 610 insertions, 418 deletions
diff --git a/SConstruct b/SConstruct index fd99933e976..0bd7dc70446 100644 --- a/SConstruct +++ b/SConstruct @@ -119,6 +119,12 @@ tempbitness = int(B.arguments.get('BF_BITNESS', bitness)) # default to bitness f if tempbitness in (32, 64): # only set if 32 or 64 has been given bitness = int(tempbitness) +if bitness: + B.bitness = bitness +else: + B.bitness = tempbitness + + # first check cmdline for toolset and we create env to work on quickie = B.arguments.get('BF_QUICK', None) quickdebug = B.arguments.get('BF_QUICKDEBUG', None) diff --git a/build_files/scons/tools/Blender.py b/build_files/scons/tools/Blender.py index 8e431d8f43c..e9195fe207d 100644 --- a/build_files/scons/tools/Blender.py +++ b/build_files/scons/tools/Blender.py @@ -50,6 +50,7 @@ program_list = [] # A list holding Nodes to final binaries, used to create insta arguments = None targets = None resources = [] +bitness = 0 #some internals blenderdeps = [] # don't manipulate this one outside this module! diff --git a/intern/cycles/blender/blender_mesh.cpp b/intern/cycles/blender/blender_mesh.cpp index e247b3744fa..4b7651dba4c 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<uint> 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<void*, SocketPair> PtrSockMap; /* Find */ -void BlenderSync::find_shader(BL::ID id, vector<uint>& used_shaders) +void BlenderSync::find_shader(BL::ID id, vector<uint>& 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.cpp b/intern/cycles/blender/blender_sync.cpp index b89b7ebb9be..b66004bee58 100644 --- a/intern/cycles/blender/blender_sync.cpp +++ b/intern/cycles/blender/blender_sync.cpp @@ -269,7 +269,7 @@ SessionParams BlenderSync::get_session_params(BL::Scene b_scene, bool background if(!experimental || RNA_enum_get(&cscene, "gpu_type") == 0) dtype = DEVICE_CUDA; else - dtype = DEVICE_CUDA; + dtype = DEVICE_OPENCL; if(device_type_available(types, dtype)) params.device_type = dtype; 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<uint>& used_shaders); + void find_shader(BL::ID id, vector<uint>& 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/intern/cycles/kernel/SConscript b/intern/cycles/kernel/SConscript index eb99680efe4..be3c37b476c 100644 --- a/intern/cycles/kernel/SConscript +++ b/intern/cycles/kernel/SConscript @@ -1,6 +1,7 @@ #!/usr/bin/python import sys import os +import Blender as B def normpath(path): return os.path.abspath(os.path.normpath(path)) @@ -9,6 +10,12 @@ Import ('env') kernel_binaries = [] +#Bitness +if B.bitness == 32: + bits = 32 +else: + bits = 64 + if env['WITH_BF_CYCLES_CUDA_BINARIES']: kernel = env.Clone() @@ -27,7 +34,8 @@ if env['WITH_BF_CYCLES_CUDA_BINARIES']: svm_dir = os.path.join(source_dir, "../svm") # nvcc flags - nvcc_flags = "--cubin -use_fast_math --ptxas-options=\"-v\" --maxrregcount=24" + nvcc_flags = "-m%s" % (bits) + nvcc_flags += " --cubin -use_fast_math --ptxas-options=\"-v\" --maxrregcount=24" nvcc_flags += " --opencc-options -OPT:Olimit=0" nvcc_flags += " -DCCL_NAMESPACE_BEGIN= -DCCL_NAMESPACE_END= -DNVCC" nvcc_flags += " -I \"%s\" -I \"%s\"" % (util_dir, svm_dir) diff --git a/intern/cycles/render/mesh.cpp b/intern/cycles/render/mesh.cpp index fc2dd49205a..5d65ce69a00 100644 --- a/intern/cycles/render/mesh.cpp +++ b/intern/cycles/render/mesh.cpp @@ -270,15 +270,19 @@ void Mesh::compute_bvh(SceneParams *params, Progress& progress) void Mesh::tag_update(Scene *scene, bool rebuild) { need_update = true; - if(rebuild) + + if(rebuild) { need_update_rebuild = true; + scene->light_manager->need_update = true; + } + else { + foreach(uint sindex, used_shaders) + if(scene->shaders[sindex]->has_surface_emission) + scene->light_manager->need_update = true; + } scene->mesh_manager->need_update = true; scene->object_manager->need_update = true; - - foreach(uint sindex, used_shaders) - if(scene->shaders[sindex]->has_surface_emission) - scene->light_manager->need_update = true; } /* Mesh Manager */ @@ -685,9 +689,9 @@ void MeshManager::device_update(Device *device, DeviceScene *dscene, Scene *scen if(!mesh->transform_applied) { string msg = "Updating Mesh BVH "; if(mesh->name == "") - msg += string_printf("%lu/%lu", (unsigned long)(i+1), (unsigned long)num_instance_bvh); + msg += string_printf("%u/%u", (uint)(i+1), (uint)num_instance_bvh); else - msg += string_printf("%s %lu/%lu", mesh->name.c_str(), (unsigned long)(i+1), (unsigned long)num_instance_bvh); + msg += string_printf("%s %u/%u", mesh->name.c_str(), (uint)(i+1), (uint)num_instance_bvh); progress.set_status(msg, "Building BVH"); mesh->compute_bvh(&scene->params, progress); diff --git a/intern/cycles/render/sobol.cpp b/intern/cycles/render/sobol.cpp index be8939174b4..e3c2e802067 100644 --- a/intern/cycles/render/sobol.cpp +++ b/intern/cycles/render/sobol.cpp @@ -47,6 +47,7 @@ */ #include "util_debug.h" +#include "util_types.h" #include "sobol.h" @@ -55,8 +56,8 @@ CCL_NAMESPACE_BEGIN #define SOBOL_MAX_NUMBER 32 typedef struct SobolDirectionNumbers { - unsigned int d, s, a; - unsigned int m[SOBOL_MAX_NUMBER]; + uint d, s, a; + uint m[SOBOL_MAX_NUMBER]; } SobolDirectionNumbers; static SobolDirectionNumbers SOBOL_NUMBERS[SOBOL_MAX_DIMENSIONS-1] = { @@ -21262,38 +21263,38 @@ static SobolDirectionNumbers SOBOL_NUMBERS[SOBOL_MAX_DIMENSIONS-1] = { {21201, 18, 131059, {1, 1, 7, 11, 15, 7, 37, 239, 337, 245, 1557, 3681, 7357, 9639, 27367, 26869, 114603, 86317}} }; -void sobol_generate_direction_vectors(unsigned int vectors[][SOBOL_BITS], int dimensions) +void sobol_generate_direction_vectors(uint vectors[][SOBOL_BITS], int dimensions) { assert(dimensions <= SOBOL_MAX_DIMENSIONS); - const unsigned int L = SOBOL_BITS; + const uint L = SOBOL_BITS; /* first dimension is exception */ - unsigned int *v = vectors[0]; + uint *v = vectors[0]; - for(unsigned int i = 0; i < L; i++) + for(uint i = 0; i < L; i++) v[i] = 1 << (31-i); // all m's = 1 for(int dim = 1; dim < dimensions; dim++) { SobolDirectionNumbers *numbers = &SOBOL_NUMBERS[dim-1]; - unsigned int s = numbers->s; - unsigned int a = numbers->a; - unsigned int *m = numbers->m; + uint s = numbers->s; + uint a = numbers->a; + uint *m = numbers->m; v = vectors[dim]; if(L <= s) { - for(unsigned int i = 0; i < L; i++) + for(uint i = 0; i < L; i++) v[i] = m[i] << (31-i); } else { - for(unsigned int i = 0; i < s; i++) + for(uint i = 0; i < s; i++) v[i] = m[i] << (31-i); - for(unsigned int i = s; i < L; i++) { + for(uint i = s; i < L; i++) { v[i] = v[i-s] ^ (v[i-s] >> s); - for(unsigned int k = 1; k < s; k++) + for(uint k = 1; k < s; k++) v[i] ^= (((a >> (s-1-k)) & 1) * v[i-k]); } } diff --git a/intern/cycles/render/sobol.h b/intern/cycles/render/sobol.h index bfc2f5512aa..0f52a5fee68 100644 --- a/intern/cycles/render/sobol.h +++ b/intern/cycles/render/sobol.h @@ -19,12 +19,14 @@ #ifndef __SOBOL_H__ #define __SOBOL_H__ +#include "util_types.h" + CCL_NAMESPACE_BEGIN #define SOBOL_BITS 32 #define SOBOL_MAX_DIMENSIONS 21201 -void sobol_generate_direction_vectors(unsigned int vectors[][SOBOL_BITS], int dimensions); +void sobol_generate_direction_vectors(uint vectors[][SOBOL_BITS], int dimensions); CCL_NAMESPACE_END diff --git a/release/scripts/presets/tracking_settings/blurry_footage.py b/release/scripts/presets/tracking_settings/blurry_footage.py new file mode 100644 index 00000000000..c805301df78 --- /dev/null +++ b/release/scripts/presets/tracking_settings/blurry_footage.py @@ -0,0 +1,11 @@ +import bpy +settings = bpy.context.edit_movieclip.tracking.settings + +settings.default_tracker = 'Hybrid' +settings.default_pyramid_levels = 2 +settings.default_correlation_min = 0.75 +settings.default_pattern_size = 21 +settings.default_search_size = 100 +settings.default_frames_limit = 0 +settings.default_pattern_match = 'PREV_FRAME' +settings.default_margin = 0 diff --git a/release/scripts/presets/tracking_settings/default.py b/release/scripts/presets/tracking_settings/default.py index 4b2d41bf292..3846f92d828 100644 --- a/release/scripts/presets/tracking_settings/default.py +++ b/release/scripts/presets/tracking_settings/default.py @@ -1,11 +1,11 @@ import bpy settings = bpy.context.edit_movieclip.tracking.settings -settings.default_tracker = 'KLT' +settings.default_tracker = 'Hybrid' settings.default_pyramid_levels = 2 settings.default_correlation_min = 0.75 settings.default_pattern_size = 11 -settings.default_search_size = 51 +settings.default_search_size = 61 settings.default_frames_limit = 0 settings.default_pattern_match = 'KEYFRAME' settings.default_margin = 0 diff --git a/release/scripts/presets/tracking_settings/fast_motion.py b/release/scripts/presets/tracking_settings/fast_motion.py index a3d382e6700..f99fd7f0c42 100644 --- a/release/scripts/presets/tracking_settings/fast_motion.py +++ b/release/scripts/presets/tracking_settings/fast_motion.py @@ -1,11 +1,11 @@ import bpy settings = bpy.context.edit_movieclip.tracking.settings -settings.default_tracker = 'KLT' +settings.default_tracker = 'Hybrid' settings.default_pyramid_levels = 2 -settings.default_correlation_min = 0.75 -settings.default_pattern_size = 11 -settings.default_search_size = 121 +settings.default_correlation_min = 0.7 +settings.default_pattern_size = 31 +settings.default_search_size = 300 settings.default_frames_limit = 0 -settings.default_pattern_match = 'KEYFRAME' -settings.default_margin = 0 +settings.default_pattern_match = 'PREV_FRAME' +settings.default_margin = 5 diff --git a/release/scripts/startup/bl_operators/object_randomize_transform.py b/release/scripts/startup/bl_operators/object_randomize_transform.py index f0d2448b508..319fd1526fb 100644 --- a/release/scripts/startup/bl_operators/object_randomize_transform.py +++ b/release/scripts/startup/bl_operators/object_randomize_transform.py @@ -20,13 +20,12 @@ 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 from random import uniform - from mathutils import Vector random.seed(seed) @@ -43,8 +42,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] @@ -53,6 +57,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) @@ -86,6 +91,7 @@ def randomize_selected(seed, delta, loc, rot, scale, scale_even, scale_min): from bpy.props import (IntProperty, BoolProperty, FloatVectorProperty) +from math import pi class RandomizeLocRotSize(Operator): @@ -129,10 +135,10 @@ class RandomizeLocRotSize(Operator): rot = FloatVectorProperty( name="Rotation", description="Maximun rotation over each axis", - min=-180.0, - max=180.0, + min=-pi, + max=pi, default=(0.0, 0.0, 0.0), - subtype='TRANSLATION', + subtype='EULER', ) use_scale = BoolProperty( name="Randomize Scale", @@ -162,14 +168,12 @@ class RandomizeLocRotSize(Operator): ) def execute(self, context): - from math import radians - seed = self.random_seed delta = self.use_delta loc = None if not self.use_loc else self.loc - rot = None if not self.use_rot else self.rot * radians(1.0) + rot = None if not self.use_rot else Vector(self.rot) scale = None if not self.use_scale else self.scale scale_even = self.scale_even diff --git a/release/scripts/startup/bl_ui/space_userpref.py b/release/scripts/startup/bl_ui/space_userpref.py index d71d57509c1..df8c085d77e 100644 --- a/release/scripts/startup/bl_ui/space_userpref.py +++ b/release/scripts/startup/bl_ui/space_userpref.py @@ -889,6 +889,8 @@ class USERPREF_PT_input(Panel, InputKeyMapPanel): sub.label(text="NDOF Device:") sub.prop(inputs, "ndof_sensitivity", text="NDOF Sensitivity") + col.prop(inputs, "tweak_threshold") + row.separator() def draw(self, context): diff --git a/release/scripts/startup/bl_ui/space_view3d.py b/release/scripts/startup/bl_ui/space_view3d.py index ce0d56b9fca..5444ad327a9 100644 --- a/release/scripts/startup/bl_ui/space_view3d.py +++ b/release/scripts/startup/bl_ui/space_view3d.py @@ -255,7 +255,7 @@ class VIEW3D_MT_uv_map(Menu): layout.separator() - layout.operator_context = 'EXEC_DEFAULT' + layout.operator_context = 'EXEC_REGION_WIN' layout.operator("uv.cube_project") layout.operator("uv.cylinder_project") layout.operator("uv.sphere_project") diff --git a/source/blender/blenkernel/BKE_deform.h b/source/blender/blenkernel/BKE_deform.h index ed8ea691134..9902b26e15b 100644 --- a/source/blender/blenkernel/BKE_deform.h +++ b/source/blender/blenkernel/BKE_deform.h @@ -52,7 +52,8 @@ void defgroup_unique_name(struct bDeformGroup *dg, struct Object *ob); struct MDeformWeight *defvert_find_index(const struct MDeformVert *dv, const int defgroup); struct MDeformWeight *defvert_verify_index(struct MDeformVert *dv, const int defgroup); -void defvert_remove_index(struct MDeformVert *dvert, int defgroup, struct MDeformWeight *dw); +void defvert_add_index_notest(struct MDeformVert *dv, int defgroup, const float weight); +void defvert_remove_group(struct MDeformVert *dvert, struct MDeformWeight *dw); float defvert_find_weight(const struct MDeformVert *dvert, const int defgroup); float defvert_array_find_weight_safe(const struct MDeformVert *dvert, const int index, const int defgroup); @@ -62,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/BKE_mesh.h b/source/blender/blenkernel/BKE_mesh.h index 232aa46575e..3e2b2e47be5 100644 --- a/source/blender/blenkernel/BKE_mesh.h +++ b/source/blender/blenkernel/BKE_mesh.h @@ -145,7 +145,13 @@ int mesh_center_bounds(struct Mesh *me, float cent[3]); void mesh_translate(struct Mesh *me, float offset[3], int do_keys); /* mesh_validate.c */ -int BKE_mesh_validate_arrays(struct Mesh *me, struct MVert *mverts, unsigned int totvert, struct MEdge *medges, unsigned int totedge, struct MFace *mfaces, unsigned int totface, const short do_verbose, const short do_fixes); +int BKE_mesh_validate_arrays( + struct Mesh *me, + struct MVert *mverts, unsigned int totvert, + struct MEdge *medges, unsigned int totedge, + struct MFace *mfaces, unsigned int totface, + struct MDeformVert *dverts, /* assume totvert length */ + const short do_verbose, const short do_fixes); int BKE_mesh_validate(struct Mesh *me, int do_verbose); int BKE_mesh_validate_dm(struct DerivedMesh *dm); diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c index 5c80038a50d..4b91911a6ab 100644 --- a/source/blender/blenkernel/intern/DerivedMesh.c +++ b/source/blender/blenkernel/intern/DerivedMesh.c @@ -641,7 +641,9 @@ enum { 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) +static void calc_weightpaint_vert_color( + 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; float input = 0.0f; @@ -659,10 +661,12 @@ static void calc_weightpaint_vert_color(Object *ob, ColorBand *coba, int vert, u 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; + } } } } @@ -691,12 +695,8 @@ static void calc_weightpaint_vert_color(Object *ob, ColorBand *coba, int vert, u float colf[4]; CLAMP(input, 0.0f, 1.0f); - colf[0]= colf[1]= colf[2]= -1; - - if(coba) - do_colorband(coba, input, colf); - else - weight_to_rgb(colf, input); + if(coba) do_colorband(coba, input, colf); + else weight_to_rgb(colf, input); col[3] = (unsigned char)(colf[0] * 255.0f); col[2] = (unsigned char)(colf[1] * 255.0f); @@ -720,20 +720,20 @@ static void add_weight_mcol_dm(Object *ob, DerivedMesh *dm, int const draw_flag) 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; + 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) * 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], 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); } MEM_freeN(defbase_sel); 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/cdderivedmesh.c b/source/blender/blenkernel/intern/cdderivedmesh.c index aade98ec9da..d4d83fec0eb 100644 --- a/source/blender/blenkernel/intern/cdderivedmesh.c +++ b/source/blender/blenkernel/intern/cdderivedmesh.c @@ -1243,11 +1243,8 @@ static void cdDM_drawMappedFacesGLSL(DerivedMesh *dm, } } } - if(!dodraw) { - continue; - } - if( numdata != 0 ) { + if(dodraw && numdata != 0 ) { offset = 0; if(attribs.totorco) { copy_v3_v3((float *)&varray[elementsize*curface*3],(float *)attribs.orco.array[mface->v1]); @@ -1289,7 +1286,7 @@ static void cdDM_drawMappedFacesGLSL(DerivedMesh *dm, } curface++; if(mface->v4) { - if( numdata != 0 ) { + if(dodraw && numdata != 0 ) { offset = 0; if(attribs.totorco) { copy_v3_v3((float *)&varray[elementsize*curface*3],(float *)attribs.orco.array[mface->v3]); diff --git a/source/blender/blenkernel/intern/deform.c b/source/blender/blenkernel/intern/deform.c index 1f09d98d697..94be15e27c0 100644 --- a/source/blender/blenkernel/intern/deform.c +++ b/source/blender/blenkernel/intern/deform.c @@ -161,12 +161,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; i<dvert->totweight; i++, dw++) { - dw->def_nr= map[dw->def_nr]; + if (dw->def_nr < map_len) { + dw->def_nr= map[dw->def_nr]; + } } } @@ -198,8 +200,10 @@ void defvert_flip(MDeformVert *dvert, const int *flip_map, const int flip_map_le int i; for (dw= dvert->dw, i=0; i<dvert->totweight; 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]; + } } } } @@ -283,17 +287,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; } @@ -321,17 +325,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; } @@ -410,11 +414,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 @@ -574,46 +582,61 @@ MDeformWeight *defvert_verify_index(MDeformVert *dvert, const int defgroup) return dw_new; } -/* Removes the given vertex from the vertex group, specified either by its defgrp_idx, - * or directly by its MDeformWeight pointer, if dw is not NULL. - * WARNING: This function frees the given MDeformWeight, do not use it afterward! */ -void defvert_remove_index(MDeformVert *dvert, int defgroup, MDeformWeight *dw) +/* TODO. merge with code above! */ + +/* Adds the given vertex to the specified vertex group, with given weight. + * warning, this does NOT check for existign, assume caller already knows its not there */ +void defvert_add_index_notest(MDeformVert *dvert, int defgroup, const float weight) { MDeformWeight *dw_new; - int i; - /* Get index of removed MDeformWeight. */ - if (dw == NULL) { - dw = dvert->dw; - for (i = dvert->totweight; i > 0; i--, dw++) { - if (dw->def_nr == defgroup) - break; - } - i--; + /* do this check always, this function is used to check for it */ + if (!dvert || defgroup < 0) + return; + + dw_new = MEM_callocN(sizeof(MDeformWeight)*(dvert->totweight+1), "defvert_add_to group, new deformWeight"); + if(dvert->dw) { + memcpy(dw_new, dvert->dw, sizeof(MDeformWeight)*dvert->totweight); + MEM_freeN(dvert->dw); } - else { - i = dw - dvert->dw; + dvert->dw = dw_new; + dw_new += dvert->totweight; + dw_new->weight = weight; + dw_new->def_nr = defgroup; + dvert->totweight++; +} + + +/* Removes the given vertex from the vertex group. + * WARNING: This function frees the given MDeformWeight, do not use it afterward! */ +void defvert_remove_group(MDeformVert *dvert, MDeformWeight *dw) +{ + if (dvert && dw) { + MDeformWeight *dw_new; + int i = dw - dvert->dw; + /* Security check! */ - if(i < 0 || i >= dvert->totweight) + if(i < 0 || i >= dvert->totweight) { return; - } + } - dvert->totweight--; - /* If there are still other deform weights attached to this vert then remove - * this deform weight, and reshuffle the others. - */ - if (dvert->totweight) { - dw_new = MEM_mallocN(sizeof(MDeformWeight)*(dvert->totweight), __func__); - if (dvert->dw){ - memcpy(dw_new, dvert->dw, sizeof(MDeformWeight)*i); - memcpy(dw_new+i, dvert->dw+i+1, sizeof(MDeformWeight)*(dvert->totweight-i)); + dvert->totweight--; + /* If there are still other deform weights attached to this vert then remove + * this deform weight, and reshuffle the others. + */ + if (dvert->totweight) { + dw_new = MEM_mallocN(sizeof(MDeformWeight)*(dvert->totweight), __func__); + if (dvert->dw){ + memcpy(dw_new, dvert->dw, sizeof(MDeformWeight)*i); + memcpy(dw_new+i, dvert->dw+i+1, sizeof(MDeformWeight)*(dvert->totweight-i)); + MEM_freeN(dvert->dw); + } + dvert->dw = dw_new; + } + else { + /* If there are no other deform weights left then just remove this one. */ MEM_freeN(dvert->dw); + dvert->dw = NULL; } - dvert->dw = dw_new; - } - else { - /* If there are no other deform weights left then just remove this one. */ - MEM_freeN(dvert->dw); - dvert->dw = NULL; } } diff --git a/source/blender/blenkernel/intern/mesh_validate.c b/source/blender/blenkernel/intern/mesh_validate.c index 4295133b469..774565bb4bd 100644 --- a/source/blender/blenkernel/intern/mesh_validate.c +++ b/source/blender/blenkernel/intern/mesh_validate.c @@ -45,6 +45,7 @@ #include "MEM_guardedalloc.h" #include "BKE_mesh.h" +#include "BKE_deform.h" #define SELECT 1 @@ -118,7 +119,12 @@ static int search_face_cmp(const void *v1, const void *v2) #define PRINT if(do_verbose) printf -int BKE_mesh_validate_arrays(Mesh *me, MVert *mverts, unsigned int totvert, MEdge *medges, unsigned int totedge, MFace *mfaces, unsigned int totface, const short do_verbose, const short do_fixes) +int BKE_mesh_validate_arrays( Mesh *me, + MVert *mverts, unsigned int totvert, + MEdge *medges, unsigned int totedge, + MFace *mfaces, unsigned int totface, + MDeformVert *dverts, /* assume totvert length */ + const short do_verbose, const short do_fixes) { # define REMOVE_EDGE_TAG(_med) { _med->v2= _med->v1; do_edge_free= 1; } # define REMOVE_FACE_TAG(_mf) { _mf->v3=0; do_face_free= 1; } @@ -130,9 +136,11 @@ int BKE_mesh_validate_arrays(Mesh *me, MVert *mverts, unsigned int totvert, MEdg 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; @@ -157,11 +165,14 @@ int BKE_mesh_validate_arrays(Mesh *me, MVert *mverts, unsigned int totvert, MEdg int fix_normal= TRUE; for(j=0; j<3; j++) { - if(isnan(mvert->co[j]) || !finite(mvert->co[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) @@ -170,8 +181,10 @@ int BKE_mesh_validate_arrays(Mesh *me, MVert *mverts, unsigned int totvert, MEdg 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; + } } } @@ -307,6 +320,46 @@ int BKE_mesh_validate_arrays(Mesh *me, MVert *mverts, unsigned int totvert, MEdg BLI_edgehash_free(edge_hash, NULL); MEM_freeN(sort_faces); + + /* fix deform verts */ + if (dverts) { + MDeformVert *dv; + for(i=0, dv= dverts; i<totvert; i++, dv++) { + MDeformWeight *dw= dv->dw; + unsigned int j= 0; + + 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 */ + if (!finite(dw->weight)) { + 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; + } + } + + if (dw->def_nr < 0) { + PRINT(" vertex deform %u, has invalid group %d\n", i, dw->def_nr); + if (do_fixes) { + defvert_remove_group(dv, dw); + if (dv->dw) { + /* re-allocated, the new values compensate for stepping + * within the for loop and may not be valid */ + j--; + dw= dv->dw + j; + + vert_weights_fixed= TRUE; + } + else { /* all freed */ + break; + } + } + } + } + } + } + + PRINT("BKE_mesh_validate: finished\n\n"); # undef REMOVE_EDGE_TAG @@ -326,7 +379,7 @@ int BKE_mesh_validate_arrays(Mesh *me, MVert *mverts, unsigned int totvert, MEdg } } - 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) @@ -357,7 +410,8 @@ static int mesh_validate_customdata(CustomData *data, short do_verbose, const sh #undef PRINT -static int BKE_mesh_validate_all_customdata(CustomData *vdata, CustomData *edata, CustomData *fdata, short do_verbose, const short do_fixes) +static int BKE_mesh_validate_all_customdata(CustomData *vdata, CustomData *edata, CustomData *fdata, + short do_verbose, const short do_fixes) { int vfixed= 0, efixed= 0, ffixed= 0; @@ -377,14 +431,24 @@ int BKE_mesh_validate(Mesh *me, int do_verbose) } layers_fixed= BKE_mesh_validate_all_customdata(&me->vdata, &me->edata, &me->fdata, do_verbose, TRUE); - arrays_fixed= BKE_mesh_validate_arrays(me, me->mvert, me->totvert, me->medge, me->totedge, me->mface, me->totface, do_verbose, TRUE); + arrays_fixed= BKE_mesh_validate_arrays(me, + me->mvert, me->totvert, + me->medge, me->totedge, + me->mface, me->totface, + me->dvert, + do_verbose, TRUE); return layers_fixed || arrays_fixed; } int BKE_mesh_validate_dm(DerivedMesh *dm) { - return BKE_mesh_validate_arrays(NULL, dm->getVertArray(dm), dm->getNumVerts(dm), dm->getEdgeArray(dm), dm->getNumEdges(dm), dm->getFaceArray(dm), dm->getNumFaces(dm), TRUE, FALSE); + return BKE_mesh_validate_arrays(NULL, + dm->getVertArray(dm), dm->getNumVerts(dm), + dm->getEdgeArray(dm), dm->getNumEdges(dm), + dm->getFaceArray(dm), dm->getNumFaces(dm), + dm->getVertDataArray(dm, CD_MDEFORMVERT), + TRUE, FALSE); } void BKE_mesh_calc_edges(Mesh *mesh, int update) diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c index 0f2d14e3858..000df5e721d 100644 --- a/source/blender/blenkernel/intern/particle.c +++ b/source/blender/blenkernel/intern/particle.c @@ -79,6 +79,7 @@ #include "BKE_cdderivedmesh.h" #include "BKE_pointcache.h" #include "BKE_scene.h" +#include "BKE_deform.h" #include "RE_render_ext.h" @@ -1847,20 +1848,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) { @@ -2308,11 +2295,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)){ for(i=0; i<totvert; i++) - vg[i]=1.0f-vert_weight(dvert+i,psys->vgroup[vgroup]-1); + vg[i]= 1.0f - defvert_find_weight(&dvert[i], psys->vgroup[vgroup] - 1); } else{ for(i=0; i<totvert; i++) - vg[i]=vert_weight(dvert+i,psys->vgroup[vgroup]-1); + vg[i]= defvert_find_weight(&dvert[i], psys->vgroup[vgroup] - 1); } } } diff --git a/source/blender/blenkernel/intern/tracking.c b/source/blender/blenkernel/intern/tracking.c index 164320562f4..1936a2fbfb2 100644 --- a/source/blender/blenkernel/intern/tracking.c +++ b/source/blender/blenkernel/intern/tracking.c @@ -77,7 +77,7 @@ void BKE_tracking_init_settings(MovieTracking *tracking) tracking->camera.pixel_aspect= 1.0f; tracking->camera.units= CAMERA_UNITS_MM; - tracking->settings.default_tracker= TRACKER_KLT; + tracking->settings.default_tracker= TRACKER_HYBRID; tracking->settings.default_minimum_correlation= 0.75; tracking->settings.default_pattern_size= 11; tracking->settings.default_search_size= 51; diff --git a/source/blender/blenkernel/intern/unit.c b/source/blender/blenkernel/intern/unit.c index 616c27f6b0b..aa914998a72 100644 --- a/source/blender/blenkernel/intern/unit.c +++ b/source/blender/blenkernel/intern/unit.c @@ -494,7 +494,7 @@ static int unit_scale_str(char *str, int len_max, char *str_tmp, double scale_pr len_name = strlen(replace_str); len_move= (len - (found_ofs+len_name)) + 1; /* 1+ to copy the string terminator */ - len_num= BLI_snprintf(str_tmp, TEMP_STR_SIZE, "*%lg"SEP_STR, unit->scalar/scale_pref); /* # removed later */ + len_num= BLI_snprintf(str_tmp, TEMP_STR_SIZE, "*%g"SEP_STR, unit->scalar/scale_pref); /* # removed later */ if(len_num > len_max) len_num= len_max; 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 caffdc29118..6dbb08e115f 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/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c index c6159487145..aee23626787 100644 --- a/source/blender/editors/interface/interface_handlers.c +++ b/source/blender/editors/interface/interface_handlers.c @@ -5241,11 +5241,14 @@ static void button_activate_state(bContext *C, uiBut *but, uiHandleButtonState s data->state= state; - if(!ELEM(state, BUTTON_STATE_EXIT, BUTTON_STATE_HIGHLIGHT)) { - /* When objects for eg. are removed, running ui_check_but() - * can access the removed data - so disable update on exit - * or highlight */ - ui_check_but(but); + if(state != BUTTON_STATE_EXIT) { + /* When objects for eg. are removed, running ui_check_but() can access + the removed data - so disable update on exit. Also in case of + highlight when not in a popup menu, we remove because data used in + button below popup might have been removed by action of popup. Needs + a more reliable solution... */ + if(state != BUTTON_STATE_HIGHLIGHT || but->block->handle) + ui_check_but(but); } /* redraw */ diff --git a/source/blender/editors/interface/resources.c b/source/blender/editors/interface/resources.c index dee945ecd7d..c3fe50edcd3 100644 --- a/source/blender/editors/interface/resources.c +++ b/source/blender/editors/interface/resources.c @@ -1715,6 +1715,8 @@ void init_userdef_do_versions(void) U.ndof_flag = NDOF_LOCK_HORIZON | NDOF_SHOULD_PAN | NDOF_SHOULD_ZOOM | NDOF_SHOULD_ROTATE; } + if (U.tweak_threshold == 0 ) + U.tweak_threshold= 10; /* funny name, but it is GE stuff, moves userdef stuff to engine */ // XXX space_set_commmandline_options(); 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 b809fd5dbb1..408558a30eb 100644 --- a/source/blender/editors/object/object_vgroup.c +++ b/source/blender/editors/object/object_vgroup.c @@ -286,8 +286,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); @@ -314,11 +314,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); @@ -1809,12 +1809,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; i<id; i++) map[i]=i; - for(i=id+1; i<tot; i++) map[i]=i-1; + for(i=id+1; i<defbase_tot; i++) map[i]=i-1; vgroup_remap_update_users(ob, map); MEM_freeN(map); @@ -2194,7 +2194,10 @@ void OBJECT_OT_vertex_group_remove(wmOperatorType *ot) ot->exec= vertex_group_remove_exec; /* flags */ - ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; + /* redo operator will fail in this case because vertex groups aren't stored + in local edit mode stack and toggling "all" property will lead to + all groups deleted without way to restore them (see [#29527], sergey) */ + ot->flag= /*OPTYPE_REGISTER|*/OPTYPE_UNDO; /* properties */ RNA_def_boolean(ot->srna, "all", 0, "All", "Remove from all vertex groups"); @@ -2226,7 +2229,10 @@ void OBJECT_OT_vertex_group_assign(wmOperatorType *ot) ot->exec= vertex_group_assign_exec; /* flags */ - ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; + /* redo operator will fail in this case because vertex group assignment + isn't stored in local edit mode stack and toggling "new" property will + lead to creating plenty of new veretx groups (see [#29527], sergey) */ + ot->flag= /*OPTYPE_REGISTER|*/OPTYPE_UNDO; /* properties */ RNA_def_boolean(ot->srna, "new", 0, "New", "Assign vertex to new vertex group"); @@ -2265,7 +2271,10 @@ void OBJECT_OT_vertex_group_remove_from(wmOperatorType *ot) ot->exec= vertex_group_remove_from_exec; /* flags */ - ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; + /* redo operator will fail in this case because vertex groups ssignment + isn't stored in local edit mode stack and toggling "all" property will lead to + removing vertices from all groups (see [#29527], sergey) */ + ot->flag= /*OPTYPE_REGISTER|*/OPTYPE_UNDO; /* properties */ RNA_def_boolean(ot->srna, "all", 0, "All", "Remove from all vertex groups"); @@ -2808,8 +2817,8 @@ void OBJECT_OT_vertex_group_set_active(wmOperatorType *ot) static char *vgroup_init_remap(Object *ob) { bDeformGroup *def; - int def_tot = BLI_countlist(&ob->defbase); - 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; @@ -2825,8 +2834,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; @@ -2847,7 +2856,7 @@ static int vgroup_do_remap(Object *ob, char *name_array, wmOperator *op) for(eve=em->verts.first; eve; eve=eve->next){ dvert= CustomData_em_get(&em->vdata, eve->data, CD_MDEFORMVERT); if(dvert && dvert->totweight){ - defvert_remap(dvert, sort_map); + defvert_remap(dvert, sort_map, defbase_tot); } } } @@ -2865,13 +2874,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; i<def_tot; i++) + for(i=0; i<defbase_tot; i++) sort_map[i]++; sort_map_update[0]= 0; diff --git a/source/blender/editors/render/render_internal.c b/source/blender/editors/render/render_internal.c index dbd1e27024e..8a580627da3 100644 --- a/source/blender/editors/render/render_internal.c +++ b/source/blender/editors/render/render_internal.c @@ -378,8 +378,12 @@ static void render_progress_update(void *rjv, float progress) { RenderJob *rj= rjv; - if(rj->progress) + if(rj->progress && *rj->progress != progress) { *rj->progress = progress; + + /* make jobs timer to send notifier */ + *(rj->do_update)= 1; + } } static void image_rect_update(void *rjv, RenderResult *rr, volatile rcti *renrect) diff --git a/source/blender/editors/sculpt_paint/paint_vertex.c b/source/blender/editors/sculpt_paint/paint_vertex.c index 9cc81df6ce5..fa791665eb8 100644 --- a/source/blender/editors/sculpt_paint/paint_vertex.c +++ b/source/blender/editors/sculpt_paint/paint_vertex.c @@ -967,11 +967,11 @@ static EnumPropertyItem *weight_paint_sample_enum_itemf(bContext *C, PointerRNA index= view3d_sample_backbuf(&vc, win->eventstate->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) { MFace *mf= ((MFace *)me->mface) + index-1; unsigned int fidx= mf->v4 ? 3:2; - int *groups= MEM_callocN(totgroup*sizeof(int), "groups"); + int *groups= MEM_callocN(defbase_tot*sizeof(int), "groups"); int found= FALSE; do { @@ -979,8 +979,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--); @@ -992,7 +994,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 && i<totgroup; i++, dg= dg->next) { + for(dg= vc.obact->defbase.first; dg && i<defbase_tot; i++, dg= dg->next) { if(groups[i]) { item_tmp.identifier= item_tmp.name= dg->name; item_tmp.value= i; @@ -1091,7 +1093,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; @@ -1102,9 +1105,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; + } } } @@ -1115,8 +1120,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; + } } } } @@ -1125,12 +1132,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; @@ -1159,7 +1171,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++) { @@ -1188,7 +1200,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; @@ -1227,7 +1239,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; @@ -1241,30 +1256,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; + } } } } @@ -1274,12 +1294,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; @@ -1295,7 +1317,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 */ @@ -1359,17 +1381,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); } } } @@ -1389,15 +1411,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) { @@ -1443,13 +1467,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; @@ -1458,7 +1482,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, @@ -1473,13 +1500,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 */ @@ -1490,7 +1517,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) { @@ -1514,13 +1541,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; @@ -1560,8 +1589,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); @@ -1579,7 +1608,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 */ @@ -1604,13 +1633,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; @@ -1767,8 +1796,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; }; @@ -1823,6 +1852,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; @@ -1925,6 +1956,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; @@ -1956,9 +1988,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; @@ -2084,7 +2118,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 */ @@ -2106,9 +2140,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); } @@ -2139,8 +2173,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/drawobject.c b/source/blender/editors/space_view3d/drawobject.c index 3333149ec37..b6d3a07f0e3 100644 --- a/source/blender/editors/space_view3d/drawobject.c +++ b/source/blender/editors/space_view3d/drawobject.c @@ -265,7 +265,7 @@ 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, int glsl) +static int check_alpha_pass(Base *base) { if(base->flag & OB_FROMDUPLI) return 0; @@ -273,7 +273,7 @@ static int check_material_alpha(Base *base, int glsl) if(G.f & G_PICKSEL) return 0; - return (glsl || (base->object->dtx & OB_DRAWTRANSP)); + return (base->object->dtx & OB_DRAWTRANSP); } /***/ @@ -3326,7 +3326,7 @@ static int draw_mesh_object(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D Object *obedit= scene->obedit; Mesh *me= ob->data; EditMesh *em= me->edit_mesh; - int do_alpha_pass= 0, drawlinked= 0, retval= 0, glsl, check_alpha, i; + int do_alpha_after= 0, drawlinked= 0, retval= 0, glsl, check_alpha, i; /* If we are drawing shadows and any of the materials don't cast a shadow, * then don't draw the object */ @@ -3371,11 +3371,11 @@ 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, glsl); + check_alpha = check_alpha_pass(base); if(dt==OB_SOLID || glsl) { GPU_begin_object_materials(v3d, rv3d, scene, ob, glsl, - (check_alpha)? &do_alpha_pass: NULL); + (check_alpha)? &do_alpha_after: NULL); } draw_mesh_fancy(scene, ar, v3d, rv3d, base, dt, flag); @@ -3387,7 +3387,7 @@ static int draw_mesh_object(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D } /* GPU_begin_object_materials checked if this is needed */ - if(do_alpha_pass) { + if(do_alpha_after) { if(ob->dtx & OB_DRAWXRAY) { add_view3d_after(&v3d->afterdraw_xraytransp, base, flag); } diff --git a/source/blender/editors/space_view3d/view3d_snap.c b/source/blender/editors/space_view3d/view3d_snap.c index b2707db806f..ecb54c77e0c 100644 --- a/source/blender/editors/space_view3d/view3d_snap.c +++ b/source/blender/editors/space_view3d/view3d_snap.c @@ -91,9 +91,7 @@ static int tottrans= 0; /* copied from editobject.c, now uses (almost) proper depgraph */ static void special_transvert_update(Object *obedit) { - if(obedit) { - DAG_id_tag_update(obedit->data, 0); if(obedit->type==OB_MESH) { @@ -177,7 +175,7 @@ static void special_transvert_update(Object *obedit) } } } - if(arm->flag & ARM_MIRROR_EDIT) + if(arm->flag & ARM_MIRROR_EDIT) transform_armature_mirror_update(obedit); } else if(obedit->type==OB_LATTICE) { @@ -193,7 +191,7 @@ static void special_transvert_update(Object *obedit) /* mode flags: */ #define TM_ALL_JOINTS 1 /* all joints (for bones only) */ #define TM_SKIP_HANDLES 2 /* skip handles when control point is selected (for curves only) */ -static void make_trans_verts(Object *obedit, float *min, float *max, int mode) +static void make_trans_verts(Object *obedit, float *min, float *max, int mode) { Nurb *nu; BezTriple *bezt; @@ -278,7 +276,7 @@ static void make_trans_verts(Object *obedit, float *min, float *max, int mode) if ((tipsel && rootsel) || (rootsel)) { /* Don't add the tip (unless mode & TM_ALL_JOINTS, for getting all joints), * otherwise we get zero-length bones as tips will snap to the same - * location as heads. + * location as heads. */ if (rootok) { copy_v3_v3(tv->oldloc, ebo->head); @@ -296,7 +294,7 @@ static void make_trans_verts(Object *obedit, float *min, float *max, int mode) tv->flag= 1; tv++; tottrans++; - } + } } else if (tipsel) { copy_v3_v3(tv->oldloc, ebo->tail); @@ -306,7 +304,7 @@ static void make_trans_verts(Object *obedit, float *min, float *max, int mode) tv++; tottrans++; } - } + } } } else if (ELEM(obedit->type, OB_CURVE, OB_SURF)) { @@ -465,7 +463,7 @@ static int snap_sel_to_grid(bContext *C, wmOperator *UNUSED(op)) if(obedit) { tottrans= 0; - if ELEM6(obedit->type, OB_ARMATURE, OB_LATTICE, OB_MESH, OB_SURF, OB_CURVE, OB_MBALL) + if ELEM6(obedit->type, OB_ARMATURE, OB_LATTICE, OB_MESH, OB_SURF, OB_CURVE, OB_MBALL) make_trans_verts(obedit, bmat[0], bmat[1], 0); if(tottrans==0) return OPERATOR_CANCELLED; @@ -474,7 +472,6 @@ static int snap_sel_to_grid(bContext *C, wmOperator *UNUSED(op)) tv= transvmain; for(a=0; a<tottrans; a++, tv++) { - copy_v3_v3(vec, tv->loc); mul_m3_v3(bmat, vec); add_v3_v3(vec, obedit->obmat[3]); @@ -491,7 +488,6 @@ static int snap_sel_to_grid(bContext *C, wmOperator *UNUSED(op)) MEM_freeN(transvmain); transvmain= NULL; - } else { struct KeyingSet *ks = ANIM_get_keyingset_for_autokeying(scene, ANIM_KS_LOCATION_ID); @@ -501,34 +497,42 @@ static int snap_sel_to_grid(bContext *C, wmOperator *UNUSED(op)) bPoseChannel *pchan; bArmature *arm= ob->data; + invert_m4_m4(ob->imat, ob->obmat); + for (pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) { if(pchan->bone->flag & BONE_SELECTED) { if(pchan->bone->layer & arm->layer) { - if((pchan->bone->flag & BONE_CONNECTED)==0) { - float vecN[3], nLoc[3]; + if((pchan->bone->flag & BONE_CONNECTED)==0) { + float nLoc[3]; + float inv_restmat[4][4]; /* get nearest grid point to snap to */ copy_v3_v3(nLoc, pchan->pose_mat[3]); + /* We must operate in world space! */ + mul_m4_v3(ob->obmat, nLoc); vec[0]= gridf * (float)(floor(0.5f+ nLoc[0]/gridf)); vec[1]= gridf * (float)(floor(0.5f+ nLoc[1]/gridf)); vec[2]= gridf * (float)(floor(0.5f+ nLoc[2]/gridf)); + /* Back in object space... */ + mul_m4_v3(ob->imat, vec); - /* get bone-space location of grid point */ - armature_loc_pose_to_bone(pchan, vec, vecN); + /* get location of grid point in *rest* bone-space */ + invert_m4_m4(inv_restmat, pchan->bone->arm_mat); + mul_m4_v3(inv_restmat, vec); /* adjust location */ - if ((pchan->protectflag & OB_LOCK_LOCX)==0) - pchan->loc[0]= vecN[0]; - if ((pchan->protectflag & OB_LOCK_LOCY)==0) - pchan->loc[0]= vecN[1]; - if ((pchan->protectflag & OB_LOCK_LOCZ)==0) - pchan->loc[0]= vecN[2]; + if ((pchan->protectflag & OB_LOCK_LOCX)==0) + pchan->loc[0]= vec[0]; + if ((pchan->protectflag & OB_LOCK_LOCY)==0) + pchan->loc[1]= vec[1]; + if ((pchan->protectflag & OB_LOCK_LOCZ)==0) + pchan->loc[2]= vec[2]; /* auto-keyframing */ ED_autokeyframe_pchan(C, scene, ob, pchan, ks); } - /* if the bone has a parent and is connected to the parent, - * don't do anything - will break chain unless we do auto-ik. + /* if the bone has a parent and is connected to the parent, + * don't do anything - will break chain unless we do auto-ik. */ } } @@ -572,7 +576,6 @@ static int snap_sel_to_grid(bContext *C, wmOperator *UNUSED(op)) void VIEW3D_OT_snap_selected_to_grid(wmOperatorType *ot) { - /* identifiers */ ot->name= "Snap Selection to Grid"; ot->description= "Snap selected item(s) to nearest grid node"; @@ -603,7 +606,7 @@ static int snap_sel_to_curs(bContext *C, wmOperator *UNUSED(op)) if(obedit) { tottrans= 0; - if ELEM6(obedit->type, OB_ARMATURE, OB_LATTICE, OB_MESH, OB_SURF, OB_CURVE, OB_MBALL) + if ELEM6(obedit->type, OB_ARMATURE, OB_LATTICE, OB_MESH, OB_SURF, OB_CURVE, OB_MBALL) make_trans_verts(obedit, bmat[0], bmat[1], 0); if(tottrans==0) return OPERATOR_CANCELLED; @@ -621,7 +624,6 @@ static int snap_sel_to_curs(bContext *C, wmOperator *UNUSED(op)) MEM_freeN(transvmain); transvmain= NULL; - } else { struct KeyingSet *ks = ANIM_get_keyingset_for_autokeying(scene, ANIM_KS_LOCATION_ID); @@ -630,34 +632,34 @@ static int snap_sel_to_curs(bContext *C, wmOperator *UNUSED(op)) if(ob->mode & OB_MODE_POSE) { bPoseChannel *pchan; bArmature *arm= ob->data; - float cursp[3]; invert_m4_m4(ob->imat, ob->obmat); - copy_v3_v3(cursp, curs); - mul_m4_v3(ob->imat, cursp); + copy_v3_v3(vec, curs); + mul_m4_v3(ob->imat, vec); for (pchan = ob->pose->chanbase.first; pchan; pchan=pchan->next) { if(pchan->bone->flag & BONE_SELECTED) { if(pchan->bone->layer & arm->layer) { - if((pchan->bone->flag & BONE_CONNECTED)==0) { - float curspn[3]; + if((pchan->bone->flag & BONE_CONNECTED)==0) { + float inv_restmat[4][4]; - /* get location of cursor in bone-space */ - armature_loc_pose_to_bone(pchan, cursp, curspn); + /* get location of cursor in *rest* bone-space */ + invert_m4_m4(inv_restmat, pchan->bone->arm_mat); + mul_m4_v3(inv_restmat, vec); /* copy new position */ - if ((pchan->protectflag & OB_LOCK_LOCX)==0) - pchan->loc[0]= curspn[0]; - if ((pchan->protectflag & OB_LOCK_LOCY)==0) - pchan->loc[1]= curspn[1]; - if ((pchan->protectflag & OB_LOCK_LOCZ)==0) - pchan->loc[2]= curspn[2]; + if ((pchan->protectflag & OB_LOCK_LOCX)==0) + pchan->loc[0]= vec[0]; + if ((pchan->protectflag & OB_LOCK_LOCY)==0) + pchan->loc[1]= vec[1]; + if ((pchan->protectflag & OB_LOCK_LOCZ)==0) + pchan->loc[2]= vec[2]; /* auto-keyframing */ ED_autokeyframe_pchan(C, scene, ob, pchan, ks); } - /* if the bone has a parent and is connected to the parent, - * don't do anything - will break chain unless we do auto-ik. + /* if the bone has a parent and is connected to the parent, + * don't do anything - will break chain unless we do auto-ik. */ } } @@ -701,7 +703,6 @@ static int snap_sel_to_curs(bContext *C, wmOperator *UNUSED(op)) void VIEW3D_OT_snap_selected_to_cursor(wmOperatorType *ot) { - /* identifiers */ ot->name= "Snap Selection to Cursor"; ot->description= "Snap selected item(s) to cursor"; @@ -738,7 +739,6 @@ static int snap_curs_to_grid(bContext *C, wmOperator *UNUSED(op)) void VIEW3D_OT_snap_cursor_to_grid(wmOperatorType *ot) { - /* identifiers */ ot->name= "Snap Cursor to Grid"; ot->description= "Snap cursor to nearest grid node"; @@ -803,7 +803,7 @@ static int snap_curs_to_sel(bContext *C, wmOperator *UNUSED(op)) if(obedit) { tottrans=0; - if ELEM6(obedit->type, OB_ARMATURE, OB_LATTICE, OB_MESH, OB_SURF, OB_CURVE, OB_MBALL) + if ELEM6(obedit->type, OB_ARMATURE, OB_LATTICE, OB_MESH, OB_SURF, OB_CURVE, OB_MBALL) make_trans_verts(obedit, bmat[0], bmat[1], TM_ALL_JOINTS|TM_SKIP_HANDLES); if(tottrans==0) return OPERATOR_CANCELLED; @@ -881,10 +881,9 @@ static int snap_curs_to_sel(bContext *C, wmOperator *UNUSED(op)) void VIEW3D_OT_snap_cursor_to_selected(wmOperatorType *ot) { - /* identifiers */ ot->name= "Snap Cursor to Selected"; - ot->description= "Snap cursor to center of selected item(s)"; + ot->description= "Snap cursor to center of selected item(s)"; ot->idname= "VIEW3D_OT_snap_cursor_to_selected"; /* api callbacks */ @@ -932,7 +931,6 @@ static int snap_curs_to_active(bContext *C, wmOperator *UNUSED(op)) void VIEW3D_OT_snap_cursor_to_active(wmOperatorType *ot) { - /* identifiers */ ot->name= "Snap Cursor to Active"; ot->description= "Snap cursor to active item"; @@ -966,13 +964,12 @@ static int snap_curs_to_center(bContext *C, wmOperator *UNUSED(op)) void VIEW3D_OT_snap_cursor_to_center(wmOperatorType *ot) { - /* identifiers */ ot->name= "Snap Cursor to Center"; ot->description= "Snap cursor to the Center"; ot->idname= "VIEW3D_OT_snap_cursor_to_center"; - /* api callbacks */ + /* api callbacks */ ot->exec= snap_curs_to_center; ot->poll= ED_operator_view3d_active; @@ -990,7 +987,7 @@ int minmax_verts(Object *obedit, float *min, float *max) int a; tottrans=0; - if ELEM5(obedit->type, OB_ARMATURE, OB_LATTICE, OB_MESH, OB_SURF, OB_CURVE) + if ELEM5(obedit->type, OB_ARMATURE, OB_LATTICE, OB_MESH, OB_SURF, OB_CURVE) make_trans_verts(obedit, bmat[0], bmat[1], TM_ALL_JOINTS); if(tottrans==0) return 0; @@ -998,12 +995,12 @@ int minmax_verts(Object *obedit, float *min, float *max) copy_m3_m4(bmat, obedit->obmat); tv= transvmain; - for(a=0; a<tottrans; a++, tv++) { + for(a=0; a<tottrans; a++, tv++) { copy_v3_v3(vec, tv->loc); mul_m3_v3(bmat, vec); add_v3_v3(vec, obedit->obmat[3]); add_v3_v3(centroid, vec); - DO_MINMAX(vec, min, max); + DO_MINMAX(vec, min, max); } MEM_freeN(transvmain); diff --git a/source/blender/editors/space_view3d/view3d_view.c b/source/blender/editors/space_view3d/view3d_view.c index 90f617513a5..89f859d0976 100644 --- a/source/blender/editors/space_view3d/view3d_view.c +++ b/source/blender/editors/space_view3d/view3d_view.c @@ -1715,6 +1715,10 @@ static int game_engine_exec(bContext *C, wmOperator *op) if(!ED_view3d_context_activate(C)) return OPERATOR_CANCELLED; + /* redraw to hide any menus/popups, we don't go back to + the window manager until after this operator exits */ + WM_redraw_windows(C); + rv3d= CTX_wm_region_view3d(C); /* sa= CTX_wm_area(C); */ /* UNUSED */ ar= CTX_wm_region(C); @@ -1750,6 +1754,8 @@ static int game_engine_exec(bContext *C, wmOperator *op) CTX_wm_window_set(C, NULL); } + ED_area_tag_redraw(CTX_wm_area(C)); + if(prevwin) { /* restore context, in case it changed in the meantime, for example by working in another window or closing it */ @@ -1763,8 +1769,6 @@ static int game_engine_exec(bContext *C, wmOperator *op) //XXX restore_all_scene_cfra(scene_cfra_store); set_scene_bg(CTX_data_main(C), startscene); //XXX scene_update_for_newframe(bmain, scene, scene->lay); - - ED_area_tag_redraw(CTX_wm_area(C)); return OPERATOR_FINISHED; #else diff --git a/source/blender/gpu/GPU_draw.h b/source/blender/gpu/GPU_draw.h index dc1f80ca903..f73bd402167 100644 --- a/source/blender/gpu/GPU_draw.h +++ b/source/blender/gpu/GPU_draw.h @@ -69,7 +69,7 @@ void GPU_state_print(void); * - after drawing, the material must be disabled again */ void GPU_begin_object_materials(struct View3D *v3d, struct RegionView3D *rv3d, - struct Scene *scene, struct Object *ob, int glsl, int *do_alpha_pass); + struct Scene *scene, struct Object *ob, int glsl, int *do_alpha_after); void GPU_end_object_materials(void); int GPU_enable_material(int nr, void *attribs); diff --git a/source/blender/gpu/intern/gpu_draw.c b/source/blender/gpu/intern/gpu_draw.c index afd22fb70a0..3cd3cde8aad 100644 --- a/source/blender/gpu/intern/gpu_draw.c +++ b/source/blender/gpu/intern/gpu_draw.c @@ -942,7 +942,7 @@ static struct GPUMaterialState { GPUBlendMode *alphablend; GPUBlendMode alphablend_fixed[FIXEDMAT]; - int alphapass; + int use_alpha_pass, is_alpha_pass; int lastmatnr, lastretval; GPUBlendMode lastalphablend; @@ -993,7 +993,7 @@ static Material *gpu_active_node_material(Material *ma) return ma; } -void GPU_begin_object_materials(View3D *v3d, RegionView3D *rv3d, Scene *scene, Object *ob, int glsl, int *do_alpha_pass) +void GPU_begin_object_materials(View3D *v3d, RegionView3D *rv3d, Scene *scene, Object *ob, int glsl, int *do_alpha_after) { Material *ma; GPUMaterial *gpumat; @@ -1015,9 +1015,15 @@ void GPU_begin_object_materials(View3D *v3d, RegionView3D *rv3d, Scene *scene, O GMS.gviewmat= rv3d->viewmat; GMS.gviewinv= rv3d->viewinv; - GMS.alphapass = (v3d && v3d->transp); - if(do_alpha_pass) - *do_alpha_pass = 0; + /* alpha pass setup. there's various cases to handle here: + * object transparency on: only solid materials draw in the first pass, + and only transparent in the second 'alpha' pass. + * object transparency off: for glsl we draw both in a single pass, and + for solid we don't use transparency at all. */ + GMS.use_alpha_pass = (do_alpha_after != NULL); + GMS.is_alpha_pass = (v3d && v3d->transp); + if(GMS.use_alpha_pass) + *do_alpha_after = 0; if(GMS.totmat > FIXEDMAT) { GMS.matbuf= MEM_callocN(sizeof(GPUMaterialFixed)*GMS.totmat, "GMS.matbuf"); @@ -1064,20 +1070,23 @@ void GPU_begin_object_materials(View3D *v3d, RegionView3D *rv3d, Scene *scene, O /* fixed function opengl materials */ gpu_material_to_fixed(&GMS.matbuf[a], ma, gamma, ob, new_shading_nodes); - alphablend = (ma->alpha == 1.0f)? GPU_BLEND_SOLID: GPU_BLEND_ALPHA; - if(do_alpha_pass && GMS.alphapass) + if(GMS.use_alpha_pass) { GMS.matbuf[a].diff[3]= ma->alpha; - else + alphablend = (ma->alpha == 1.0f)? GPU_BLEND_SOLID: GPU_BLEND_ALPHA; + } + else { GMS.matbuf[a].diff[3]= 1.0f; + alphablend = GPU_BLEND_SOLID; + } } - /* setting do_alpha_pass = 1 indicates this object needs to be + /* setting do_alpha_after = 1 indicates this object needs to be * drawn in a second alpha pass for improved blending */ - if(do_alpha_pass) { - GMS.alphablend[a]= alphablend; - if(ELEM3(alphablend, GPU_BLEND_ALPHA, GPU_BLEND_ADD, GPU_BLEND_ALPHA_SORT) && !GMS.alphapass) - *do_alpha_pass= 1; - } + if(GMS.use_alpha_pass && !GMS.is_alpha_pass) + if(ELEM3(alphablend, GPU_BLEND_ALPHA, GPU_BLEND_ADD, GPU_BLEND_ALPHA_SORT)) + *do_alpha_after= 1; + + GMS.alphablend[a]= alphablend; } /* let's start with a clean state */ @@ -1122,20 +1131,26 @@ int GPU_enable_material(int nr, void *attribs) /* unbind glsl material */ if(GMS.gboundmat) { - if(GMS.alphapass) glDepthMask(0); + if(GMS.is_alpha_pass) glDepthMask(0); GPU_material_unbind(GPU_material_from_blender(GMS.gscene, GMS.gboundmat)); GMS.gboundmat= NULL; } /* draw materials with alpha in alpha pass */ GMS.lastmatnr = nr; - GMS.lastretval = ELEM(GMS.alphablend[nr], GPU_BLEND_SOLID, GPU_BLEND_CLIP); - if(GMS.alphapass) - GMS.lastretval = !GMS.lastretval; + GMS.lastretval = 1; + + if(GMS.use_alpha_pass) { + GMS.lastretval = ELEM(GMS.alphablend[nr], GPU_BLEND_SOLID, GPU_BLEND_CLIP); + if(GMS.is_alpha_pass) + GMS.lastretval = !GMS.lastretval; + } + else + GMS.lastretval = !GMS.is_alpha_pass; if(GMS.lastretval) { /* for alpha pass, use alpha blend */ - alphablend = (GMS.alphapass)? GPU_BLEND_ALPHA: GPU_BLEND_SOLID; + alphablend = GMS.alphablend[nr]; if(gattribs && GMS.gmatbuf[nr]) { /* bind glsl material and get attributes */ @@ -1152,7 +1167,7 @@ int GPU_enable_material(int nr, void *attribs) if(mat->game.alpha_blend != GPU_BLEND_SOLID) alphablend= mat->game.alpha_blend; - if(GMS.alphapass) glDepthMask(1); + if(GMS.is_alpha_pass) glDepthMask(1); } else { /* or do fixed function opengl material */ @@ -1188,7 +1203,7 @@ void GPU_disable_material(void) GMS.lastretval= 1; if(GMS.gboundmat) { - if(GMS.alphapass) glDepthMask(0); + if(GMS.is_alpha_pass) glDepthMask(0); GPU_material_unbind(GPU_material_from_blender(GMS.gscene, GMS.gboundmat)); GMS.gboundmat= NULL; } diff --git a/source/blender/makesdna/DNA_userdef_types.h b/source/blender/makesdna/DNA_userdef_types.h index 4f6c7e22f5e..851d4b562e6 100644 --- a/source/blender/makesdna/DNA_userdef_types.h +++ b/source/blender/makesdna/DNA_userdef_types.h @@ -408,7 +408,9 @@ typedef struct UserDef { struct ColorBand coba_weight; /* from texture.h */ float sculpt_paint_overlay_col[3]; - int pad3; + + short tweak_threshold; + short pad3; char author[80]; /* author name for file formats supporting it */ } UserDef; 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/makesrna/intern/rna_curve.c b/source/blender/makesrna/intern/rna_curve.c index 4afe0da85fa..5fd67efba1d 100644 --- a/source/blender/makesrna/intern/rna_curve.c +++ b/source/blender/makesrna/intern/rna_curve.c @@ -1286,21 +1286,21 @@ static void rna_def_curve(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Bevel Resolution", "Bevel resolution when depth is non-zero and no specific bevel object has been defined"); RNA_def_property_update(prop, 0, "rna_Curve_update_data"); - prop= RNA_def_property(srna, "offset", PROP_FLOAT, PROP_NONE); + prop= RNA_def_property(srna, "offset", PROP_FLOAT, PROP_NONE|PROP_UNIT_LENGTH); RNA_def_property_float_sdna(prop, NULL, "width"); RNA_def_property_ui_range(prop, -1.0, 1.0, 0.1, 3); RNA_def_property_float_funcs(prop, "rna_Curve_offset_get", "rna_Curve_offset_set", NULL); RNA_def_property_ui_text(prop, "Offset", "Offset the curve to adjust the width of a text"); RNA_def_property_update(prop, 0, "rna_Curve_update_data"); - prop= RNA_def_property(srna, "extrude", PROP_FLOAT, PROP_NONE); + prop= RNA_def_property(srna, "extrude", PROP_FLOAT, PROP_NONE|PROP_UNIT_LENGTH); RNA_def_property_float_sdna(prop, NULL, "ext1"); RNA_def_property_ui_range(prop, 0, 100.0, 0.1, 3); RNA_def_property_range(prop, 0.0, FLT_MAX); RNA_def_property_ui_text(prop, "Extrude", "Amount of curve extrusion when not using a bevel object"); RNA_def_property_update(prop, 0, "rna_Curve_update_data"); - prop= RNA_def_property(srna, "bevel_depth", PROP_FLOAT, PROP_NONE); + prop= RNA_def_property(srna, "bevel_depth", PROP_FLOAT, PROP_NONE|PROP_UNIT_LENGTH); RNA_def_property_float_sdna(prop, NULL, "ext2"); RNA_def_property_ui_range(prop, 0, 100.0, 0.1, 3); RNA_def_property_ui_text(prop, "Bevel Depth", "Bevel depth when not using a bevel object"); diff --git a/source/blender/makesrna/intern/rna_tracking.c b/source/blender/makesrna/intern/rna_tracking.c index 6332cd40bca..bf3806e5de4 100644 --- a/source/blender/makesrna/intern/rna_tracking.c +++ b/source/blender/makesrna/intern/rna_tracking.c @@ -432,17 +432,17 @@ static void rna_def_trackingSettings(BlenderRNA *brna) static EnumPropertyItem refine_items[] = { {0, "NONE", 0, "Nothing", "Do not refine camera intrinsics"}, {REFINE_FOCAL_LENGTH, "FOCAL_LENGTH", 0, "Focal Length", "Refine focal length"}, + {REFINE_FOCAL_LENGTH|REFINE_RADIAL_DISTORTION_K1, "FOCAL_LENGTH_RADIAL_K1", 0, "Focal length, K1", "Refine focal length and radial distortion K1"}, {REFINE_FOCAL_LENGTH| - REFINE_PRINCIPAL_POINT, "FOCAL_LENGTH_PRINCIPAL_POINT", 0, "Focal Length, Optical Center", "Refine focal length and optical center"}, + REFINE_RADIAL_DISTORTION_K1| + REFINE_RADIAL_DISTORTION_K2, "FOCAL_LENGTH_RADIAL_K1_K2", 0, "Focal length, K1, K2", "Refine focal length and radial distortion K1 and K2"}, {REFINE_FOCAL_LENGTH| REFINE_PRINCIPAL_POINT| REFINE_RADIAL_DISTORTION_K1| REFINE_RADIAL_DISTORTION_K2, "FOCAL_LENGTH_PRINCIPAL_POINT_RADIAL_K1_K2", 0, "Focal Length, Optical Center, K1, K2", "Refine focal length, optical center and radial distortion K1 and K2"}, {REFINE_FOCAL_LENGTH| - REFINE_RADIAL_DISTORTION_K1| - REFINE_RADIAL_DISTORTION_K2, "FOCAL_LENGTH_RADIAL_K1_K2", 0, "Focal length, K1. K2", "Refine focal length and radial distortion K1 and K2"}, - {REFINE_FOCAL_LENGTH|REFINE_RADIAL_DISTORTION_K1, "FOCAL_LENGTH_RADIAL_K1", 0, "Focal length, K1", "Refine focal length and radial distortion K1"}, + REFINE_PRINCIPAL_POINT, "FOCAL_LENGTH_PRINCIPAL_POINT", 0, "Focal Length, Optical Center", "Refine focal length and optical center"}, {0, NULL, 0, NULL, NULL} }; diff --git a/source/blender/makesrna/intern/rna_userdef.c b/source/blender/makesrna/intern/rna_userdef.c index 0ea6b902150..f9b20d3ac78 100644 --- a/source/blender/makesrna/intern/rna_userdef.c +++ b/source/blender/makesrna/intern/rna_userdef.c @@ -2929,6 +2929,11 @@ static void rna_def_userdef_input(BlenderRNA *brna) RNA_def_property_range(prop, 3, 40); RNA_def_property_ui_text(prop, "Drag Threshold", "Amount of pixels you have to drag before dragging UI items happens"); + prop= RNA_def_property(srna, "tweak_threshold", PROP_INT, PROP_NONE); + RNA_def_property_int_sdna(prop, NULL, "tweak_threshold"); + RNA_def_property_range(prop, 3, 1024); + RNA_def_property_ui_text(prop, "Tweak Threshold", "Number of pixels you have to drag before tweak event is triggered"); + /* 3D mouse settings */ /* global options */ prop= RNA_def_property(srna, "ndof_sensitivity", PROP_FLOAT, PROP_NONE); diff --git a/source/blender/modifiers/intern/MOD_hook.c b/source/blender/modifiers/intern/MOD_hook.c index 30e801c9b42..9e48c5d29e2 100644 --- a/source/blender/modifiers/intern/MOD_hook.c +++ b/source/blender/modifiers/intern/MOD_hook.c @@ -143,14 +143,9 @@ static float hook_falloff(float *co_1, float *co_2, const float falloff_squared, return fac; } -static void deformVerts(ModifierData *md, Object *ob, - DerivedMesh *dm, - float (*vertexCos)[3], - int numVerts, - int UNUSED(useRenderParams), - int UNUSED(isFinalCalc)) +static void deformVerts_do(HookModifierData *hmd, Object *ob, DerivedMesh *dm, + float (*vertexCos)[3], int numVerts) { - HookModifierData *hmd = (HookModifierData*) md; bPoseChannel *pchan= get_pose_channel(hmd->object->pose, hmd->subtarget); float vec[3], mat[4][4], dmat[4][4]; int i, *index_pt; @@ -251,17 +246,29 @@ static void deformVerts(ModifierData *md, Object *ob, } } -static void deformVertsEM( - ModifierData *md, Object *ob, struct EditMesh *editData, - DerivedMesh *derivedData, float (*vertexCos)[3], int numVerts) +static void deformVerts(ModifierData *md, Object *ob, DerivedMesh *derivedData, + float (*vertexCos)[3], int numVerts, + int UNUSED(useRenderParams), int UNUSED(isFinalCalc)) { - DerivedMesh *dm = derivedData; + HookModifierData *hmd = (HookModifierData*) md; + DerivedMesh *dm = get_dm(ob, NULL, derivedData, NULL, 0); - if(!derivedData) dm = CDDM_from_editmesh(editData, ob->data); + deformVerts_do(hmd, ob, dm, vertexCos, numVerts); + + if(derivedData != dm) + dm->release(dm); +} + +static void deformVertsEM(ModifierData *md, Object *ob, struct EditMesh *editData, + DerivedMesh *derivedData, float (*vertexCos)[3], int numVerts) +{ + HookModifierData *hmd = (HookModifierData*) md; + DerivedMesh *dm = get_dm(ob, editData, derivedData, NULL, 0); - deformVerts(md, ob, dm, vertexCos, numVerts, 0, 0); + deformVerts_do(hmd, ob, dm, vertexCos, numVerts); - if(!derivedData) dm->release(dm); + if(derivedData != dm) + dm->release(dm); } diff --git a/source/blender/modifiers/intern/MOD_mask.c b/source/blender/modifiers/intern/MOD_mask.c index 4145dafce7b..1fbe0eef6f3 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/modifiers/intern/MOD_weightvg_util.c b/source/blender/modifiers/intern/MOD_weightvg_util.c index e206000f41d..5631b7e716a 100644 --- a/source/blender/modifiers/intern/MOD_weightvg_util.c +++ b/source/blender/modifiers/intern/MOD_weightvg_util.c @@ -222,23 +222,7 @@ void weightvg_do_mask(int num, const int *indices, float *org_w, const float *ne } } -/* Adds the given vertex to the specified vertex group, with given weight. */ -static void defvert_add_to_group(MDeformVert *dv, int defgrp_idx, const float weight) -{ - /* TODO, move into deform.c as a generic function. This assumes the vertex - * groups have already been checked, so this has to remain low level. */ - MDeformWeight *newdw; - newdw = MEM_callocN(sizeof(MDeformWeight)*(dv->totweight+1), "defvert_add_to group, new deformWeight"); - if(dv->dw) { - memcpy(newdw, dv->dw, sizeof(MDeformWeight)*dv->totweight); - MEM_freeN(dv->dw); - } - dv->dw = newdw; - dv->dw[dv->totweight].weight = weight; - dv->dw[dv->totweight].def_nr = defgrp_idx; - dv->totweight++; -} /* Applies weights to given vgroup (defgroup), and optionnaly add/remove vertices from the group. @@ -264,7 +248,7 @@ void weightvg_update_vg(MDeformVert *dvert, int defgrp_idx, MDeformWeight **dws, /* If the vertex is in this vgroup, remove it if needed, or just update it. */ if(dw != NULL) { if(do_rem && w < rem_thresh) { - defvert_remove_index(dv, defgrp_idx, dw); + defvert_remove_group(dv, dw); } else { dw->weight = w; @@ -272,7 +256,7 @@ void weightvg_update_vg(MDeformVert *dvert, int defgrp_idx, MDeformWeight **dws, } /* Else, add it if needed! */ else if(do_add && w > add_thresh) { - defvert_add_to_group(dv, defgrp_idx, w); + defvert_add_index_notest(dv, defgrp_idx, w); } } } diff --git a/source/blender/render/intern/source/pipeline.c b/source/blender/render/intern/source/pipeline.c index 0bad1a13a5a..d82cff16496 100644 --- a/source/blender/render/intern/source/pipeline.c +++ b/source/blender/render/intern/source/pipeline.c @@ -3084,7 +3084,7 @@ void RE_BlenderAnim(Render *re, Main *bmain, Scene *scene, Object *camera_overri { bMovieHandle *mh= BKE_get_movie_handle(scene->r.im_format.imtype); int cfrao= scene->r.cfra; - int nfra; + int nfra, totrendered= 0, totskipped= 0; /* do not fully call for each frame, it initializes & pops output window */ if(!render_initialize_from_main(re, bmain, scene, NULL, camera_override, lay, 0, 1)) @@ -3109,6 +3109,7 @@ void RE_BlenderAnim(Render *re, Main *bmain, Scene *scene, Object *camera_overri BLI_exec_cb(re->main, (ID *)scene, BLI_CB_EVT_RENDER_PRE); do_render_all_options(re); + totrendered++; if(re->test_break(re->tbh) == 0) { if(!do_write_image_or_movie(re, bmain, scene, mh, NULL)) @@ -3157,6 +3158,7 @@ void RE_BlenderAnim(Render *re, Main *bmain, Scene *scene, Object *camera_overri if(scene->r.mode & R_NO_OVERWRITE && BLI_exists(name)) { printf("skipping existing frame \"%s\"\n", name); + totskipped++; continue; } if(scene->r.mode & R_TOUCH && !BLI_exists(name)) { @@ -3172,6 +3174,7 @@ void RE_BlenderAnim(Render *re, Main *bmain, Scene *scene, Object *camera_overri do_render_all_options(re); + totrendered++; if(re->test_break(re->tbh) == 0) { if(!G.afbreek) @@ -3201,6 +3204,9 @@ void RE_BlenderAnim(Render *re, Main *bmain, Scene *scene, Object *camera_overri /* end movie */ if(BKE_imtype_is_movie(scene->r.im_format.imtype)) mh->end_movie(); + + if(totskipped && totrendered == 0) + BKE_report(re->reports, RPT_INFO, "No frames rendered, skipped to not overwrite"); scene->r.cfra= cfrao; diff --git a/source/blender/windowmanager/intern/wm_gesture.c b/source/blender/windowmanager/intern/wm_gesture.c index ef463989c64..4fb8751de69 100644 --- a/source/blender/windowmanager/intern/wm_gesture.c +++ b/source/blender/windowmanager/intern/wm_gesture.c @@ -124,14 +124,13 @@ void WM_gestures_remove(bContext *C) /* tweak and line gestures */ -#define TWEAK_THRESHOLD 10 int wm_gesture_evaluate(wmGesture *gesture) { if(gesture->type==WM_GESTURE_TWEAK) { rcti *rect= gesture->customdata; int dx= rect->xmax - rect->xmin; int dy= rect->ymax - rect->ymin; - if(ABS(dx)+ABS(dy) > TWEAK_THRESHOLD) { + if(ABS(dx)+ABS(dy) > U.tweak_threshold) { int theta= (int)floor(4.0f*atan2f((float)dy, (float)dx)/(float)M_PI + 0.5f); int val= EVT_GESTURE_W; 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; |