From ac8e379a87b78ed96cc9dac5fe5b88e5bd4979f7 Mon Sep 17 00:00:00 2001 From: Antony Riakiotakis Date: Wed, 31 Jul 2013 22:39:17 +0000 Subject: [PATCH 01/25] Fix linking issue, we use bundled static glew so we should define static glew in ghost as well. --- intern/ghost/CMakeLists.txt | 2 ++ intern/ghost/SConscript | 3 +-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/intern/ghost/CMakeLists.txt b/intern/ghost/CMakeLists.txt index 12dd4c0d3eb..2538f0612db 100644 --- a/intern/ghost/CMakeLists.txt +++ b/intern/ghost/CMakeLists.txt @@ -315,5 +315,7 @@ elseif(WIN32) endif() +add_definitions(-DGLEW_STATIC) + blender_add_lib(bf_intern_ghost "${SRC}" "${INC}" "${INC_SYS}") diff --git a/intern/ghost/SConscript b/intern/ghost/SConscript index 0d7df2847e0..e48e4ee6b96 100644 --- a/intern/ghost/SConscript +++ b/intern/ghost/SConscript @@ -38,7 +38,7 @@ if window_system == 'darwin': pf = ['GHOST_DisplayManager', 'GHOST_System', 'GHOST_SystemPaths', 'GHOST_Window', 'GHOST_DropTarget', 'GHOST_NDOFManager'] -defs=['_USE_MATH_DEFINES'] +defs=['_USE_MATH_DEFINES', 'GLEW_STATIC'] incs = [ '.', @@ -142,7 +142,6 @@ else: except ValueError: pass - if window_system in ('win32-vc', 'win32-mingw', 'cygwin', 'linuxcross', 'win64-vc', 'win64-mingw'): incs = env['BF_WINTAB_INC'] + ' ' + incs incs += ' ../utfconv' From 702bf77b3490a6c74cf43236c5795b19d042f11b Mon Sep 17 00:00:00 2001 From: Thomas Dinges Date: Wed, 31 Jul 2013 22:51:48 +0000 Subject: [PATCH 02/25] Cycles / Squared Samples: * After some feedback decided to remove this option from the Progressive integrator, it only makes sense for Non-Progressive where we have different values for the sample types. --- intern/cycles/blender/addon/ui.py | 4 +++- intern/cycles/blender/blender_sync.cpp | 5 ++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/intern/cycles/blender/addon/ui.py b/intern/cycles/blender/addon/ui.py index 1a17675cb71..411bd5b8b27 100644 --- a/intern/cycles/blender/addon/ui.py +++ b/intern/cycles/blender/addon/ui.py @@ -70,7 +70,9 @@ class CyclesRender_PT_sampling(CyclesButtonsPanel, Panel): sub = row.row() sub.active = (device_type == 'NONE' or cscene.device == 'CPU') sub.prop(cscene, "progressive") - row.prop(cscene, "squared_samples") + + if not cscene.progressive: + row.prop(cscene, "squared_samples") split = layout.split() diff --git a/intern/cycles/blender/blender_sync.cpp b/intern/cycles/blender/blender_sync.cpp index 11e2be5e0fb..d1d235ec41a 100644 --- a/intern/cycles/blender/blender_sync.cpp +++ b/intern/cycles/blender/blender_sync.cpp @@ -321,7 +321,7 @@ void BlenderSync::sync_render_layers(BL::SpaceView3D b_v3d, const char *layer) render_layer.bound_samples = (use_layer_samples == 1); if(use_layer_samples != 2) { int samples = b_rlay->samples(); - if(get_boolean(cscene, "squared_samples")) + if(get_boolean(cscene, "squared_samples") && !(get_boolean(cscene, "progressive"))) render_layer.samples = samples * samples; else render_layer.samples = samples; @@ -414,10 +414,9 @@ SessionParams BlenderSync::get_session_params(BL::RenderEngine b_engine, BL::Use int preview_samples = get_int(cscene, "preview_samples"); int preview_aa_samples = get_int(cscene, "preview_aa_samples"); + /* Squared samples for Non-Progressive only */ if(get_boolean(cscene, "squared_samples")) { - samples = samples * samples; aa_samples = aa_samples * aa_samples; - preview_samples = preview_samples * preview_samples; preview_aa_samples = preview_aa_samples * preview_aa_samples; } From ceaec3c86ad57366639db8bc6ba5353e3680b22a Mon Sep 17 00:00:00 2001 From: Miika Hamalainen Date: Thu, 1 Aug 2013 12:09:12 +0000 Subject: [PATCH 03/25] Fix [#36265]: Smoke doesn't work if domain object has negative scale. --- source/blender/blenkernel/intern/smoke.c | 11 +++++++---- .../blender/editors/space_view3d/drawobject.c | 19 ++++++++----------- .../blender/editors/space_view3d/drawvolume.c | 4 ++-- 3 files changed, 17 insertions(+), 17 deletions(-) diff --git a/source/blender/blenkernel/intern/smoke.c b/source/blender/blenkernel/intern/smoke.c index b2c0a45cbc4..789b0ec5823 100644 --- a/source/blender/blenkernel/intern/smoke.c +++ b/source/blender/blenkernel/intern/smoke.c @@ -259,7 +259,10 @@ static void smoke_set_domain_from_derivedmesh(SmokeDomainSettings *sds, Object * zero_v3_int(sds->base_res); copy_v3_v3(sds->cell_size, size); } - mul_v3_v3(size, ob->size); + /* apply object scale */ + for (i = 0; i < 3; i++) { + size[i] = fabs(size[i] * ob->size[i]); + } copy_v3_v3(sds->global_size, size); copy_v3_v3(sds->dp0, min); @@ -272,21 +275,21 @@ static void smoke_set_domain_from_derivedmesh(SmokeDomainSettings *sds, Object * /* define grid resolutions from longest domain side */ if (size[0] >= MAX2(size[1], size[2])) { scale = res / size[0]; - sds->scale = size[0] / ob->size[0]; + sds->scale = size[0] / fabs(ob->size[0]); sds->base_res[0] = res; sds->base_res[1] = (int)(size[1] * scale + 0.5f); sds->base_res[2] = (int)(size[2] * scale + 0.5f); } else if (size[1] >= MAX2(size[0], size[2])) { scale = res / size[1]; - sds->scale = size[1] / ob->size[1]; + sds->scale = size[1] / fabs(ob->size[1]); sds->base_res[0] = (int)(size[0] * scale + 0.5f); sds->base_res[1] = res; sds->base_res[2] = (int)(size[2] * scale + 0.5f); } else { scale = res / size[2]; - sds->scale = size[2] / ob->size[2]; + sds->scale = size[2] / fabs(ob->size[2]); sds->base_res[0] = (int)(size[0] * scale + 0.5f); sds->base_res[1] = (int)(size[1] * scale + 0.5f); sds->base_res[2] = res; diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c index 6383440893d..797ba5a2236 100644 --- a/source/blender/editors/space_view3d/drawobject.c +++ b/source/blender/editors/space_view3d/drawobject.c @@ -7053,18 +7053,15 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, const short mul_mat3_m4_v3(ob->imat, viewnormal); normalize_v3(viewnormal); - /* set dynamic boundaries to draw the volume */ - p0[0] = sds->p0[0] + sds->cell_size[0] * sds->res_min[0] + sds->obj_shift_f[0]; - p0[1] = sds->p0[1] + sds->cell_size[1] * sds->res_min[1] + sds->obj_shift_f[1]; - p0[2] = sds->p0[2] + sds->cell_size[2] * sds->res_min[2] + sds->obj_shift_f[2]; - p1[0] = sds->p0[0] + sds->cell_size[0] * sds->res_max[0] + sds->obj_shift_f[0]; - p1[1] = sds->p0[1] + sds->cell_size[1] * sds->res_max[1] + sds->obj_shift_f[1]; - p1[2] = sds->p0[2] + sds->cell_size[2] * sds->res_max[2] + sds->obj_shift_f[2]; - - /* scale cube to global space to equalize volume slicing on all axises + /* set dynamic boundaries to draw the volume + * also scale cube to global space to equalize volume slicing on all axises * (its scaled back before drawing) */ - mul_v3_v3(p0, ob->size); - mul_v3_v3(p1, ob->size); + p0[0] = (sds->p0[0] + sds->cell_size[0] * sds->res_min[0] + sds->obj_shift_f[0]) * fabs(ob->size[0]); + p0[1] = (sds->p0[1] + sds->cell_size[1] * sds->res_min[1] + sds->obj_shift_f[1]) * fabs(ob->size[1]); + p0[2] = (sds->p0[2] + sds->cell_size[2] * sds->res_min[2] + sds->obj_shift_f[2]) * fabs(ob->size[2]); + p1[0] = (sds->p0[0] + sds->cell_size[0] * sds->res_max[0] + sds->obj_shift_f[0]) * fabs(ob->size[0]); + p1[1] = (sds->p0[1] + sds->cell_size[1] * sds->res_max[1] + sds->obj_shift_f[1]) * fabs(ob->size[1]); + p1[2] = (sds->p0[2] + sds->cell_size[2] * sds->res_max[2] + sds->obj_shift_f[2]) * fabs(ob->size[2]); if (!sds->wt || !(sds->viewsettings & MOD_SMOKE_VIEW_SHOWBIG)) { smd->domain->tex = NULL; diff --git a/source/blender/editors/space_view3d/drawvolume.c b/source/blender/editors/space_view3d/drawvolume.c index 8323e7de9a4..5ac6382bdbe 100644 --- a/source/blender/editors/space_view3d/drawvolume.c +++ b/source/blender/editors/space_view3d/drawvolume.c @@ -461,7 +461,7 @@ void draw_smoke_volume(SmokeDomainSettings *sds, Object *ob, glTexCoord3d((points[i * 3 + 0] - min[0]) * cor[0] / size[0], (points[i * 3 + 1] - min[1]) * cor[1] / size[1], (points[i * 3 + 2] - min[2]) * cor[2] / size[2]); - glVertex3f(points[i * 3 + 0] / ob->size[0], points[i * 3 + 1] / ob->size[1], points[i * 3 + 2] / ob->size[2]); + glVertex3f(points[i * 3 + 0] / fabs(ob->size[0]), points[i * 3 + 1] / fabs(ob->size[1]), points[i * 3 + 2] / fabs(ob->size[2])); } glEnd(); @@ -474,7 +474,7 @@ void draw_smoke_volume(SmokeDomainSettings *sds, Object *ob, glTexCoord3d((points[i * 3 + 0] - min[0]) * cor[0] / size[0], (points[i * 3 + 1] - min[1]) * cor[1] / size[1], (points[i * 3 + 2] - min[2]) * cor[2] / size[2]); - glVertex3f(points[i * 3 + 0] / ob->size[0], points[i * 3 + 1] / ob->size[1], points[i * 3 + 2] / ob->size[2]); + glVertex3f(points[i * 3 + 0] / fabs(ob->size[0]), points[i * 3 + 1] / fabs(ob->size[1]), points[i * 3 + 2] / fabs(ob->size[2])); } glEnd(); } From 9caaa78c32a4f990e9dae5cc6113c177089424a0 Mon Sep 17 00:00:00 2001 From: Thomas Dinges Date: Thu, 1 Aug 2013 14:00:24 +0000 Subject: [PATCH 04/25] Fix for r58798, forgot to update the presets. --- release/scripts/presets/cycles/sampling/final.py | 9 ++++++--- release/scripts/presets/cycles/sampling/preview.py | 9 ++++++--- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/release/scripts/presets/cycles/sampling/final.py b/release/scripts/presets/cycles/sampling/final.py index 4bb90d106f4..a76fa352178 100644 --- a/release/scripts/presets/cycles/sampling/final.py +++ b/release/scripts/presets/cycles/sampling/final.py @@ -3,10 +3,13 @@ cycles = bpy.context.scene.cycles cycles.squared_samples = True -cycles.samples = 24 -cycles.preview_samples = 24 +# Progressive +cycles.samples = 500 +cycles.preview_samples = 100 + +# Non-Progressive (squared) cycles.aa_samples = 8 -cycles.preview_aa_samples = 8 +cycles.preview_aa_samples = 4 cycles.diffuse_samples = 3 cycles.glossy_samples = 2 diff --git a/release/scripts/presets/cycles/sampling/preview.py b/release/scripts/presets/cycles/sampling/preview.py index fbe8a011c97..3f565ccff8c 100644 --- a/release/scripts/presets/cycles/sampling/preview.py +++ b/release/scripts/presets/cycles/sampling/preview.py @@ -3,10 +3,13 @@ cycles = bpy.context.scene.cycles cycles.squared_samples = True -cycles.samples = 12 -cycles.preview_samples = 12 +# Progressive +cycles.samples = 100 +cycles.preview_samples = 10 + +# Non-Progressive (squared) cycles.aa_samples = 4 -cycles.preview_aa_samples = 4 +cycles.preview_aa_samples = 2 cycles.diffuse_samples = 3 cycles.glossy_samples = 2 From 7eeaefb97ccf49d5a2cb801766fe765722e533b7 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Thu, 1 Aug 2013 16:34:55 +0000 Subject: [PATCH 05/25] Potential fix for wrogn k3 value after solve --- extern/libmv/libmv-capi.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/extern/libmv/libmv-capi.cc b/extern/libmv/libmv-capi.cc index 990b40df90a..063c63f9266 100644 --- a/extern/libmv/libmv-capi.cc +++ b/extern/libmv/libmv-capi.cc @@ -1014,6 +1014,7 @@ void libmv_cameraIntrinsicsExtract(const struct libmv_CameraIntrinsics *libmv_in *principal_y = camera_intrinsics->principal_point_y(); *k1 = camera_intrinsics->k1(); *k2 = camera_intrinsics->k2(); + *k3 = camera_intrinsics->k3(); } void libmv_cameraIntrinsicsUndistortByte(const struct libmv_CameraIntrinsics *libmv_intrinsics, From 6fe4ec1bdc4f8ef147e8d7db15162872004130da Mon Sep 17 00:00:00 2001 From: Antony Riakiotakis Date: Thu, 1 Aug 2013 17:14:20 +0000 Subject: [PATCH 06/25] Fix a very irritating problem of our stroke system. On small brushes, the space stroke would be repeated on unneeded subpixel precision. Since this is not really useful, enforce spacing to be at least one pixel. This makes small brushes quite more responsive. --- source/blender/editors/sculpt_paint/paint_stroke.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/blender/editors/sculpt_paint/paint_stroke.c b/source/blender/editors/sculpt_paint/paint_stroke.c index 576bbecb561..36e1b1feb38 100644 --- a/source/blender/editors/sculpt_paint/paint_stroke.c +++ b/source/blender/editors/sculpt_paint/paint_stroke.c @@ -375,13 +375,13 @@ static float paint_space_stroke_spacing(const Scene *scene, PaintStroke *stroke, /* apply spacing pressure */ if (stroke->brush->flag & BRUSH_SPACING_PRESSURE) - spacing = max_ff(1.0f, spacing * (1.5f - spacing_pressure)); + spacing = spacing * (1.5f - spacing_pressure); /* stroke system is used for 2d paint too, so we need to account for * the fact that brush can be scaled there. */ spacing *= stroke->zoom_2d; - return (size_clamp * spacing / 50.0f); + return max_ff(1.0, size_clamp * spacing / 50.0f); } static float paint_space_stroke_spacing_variable(const Scene *scene, PaintStroke *stroke, float pressure, float dpressure, float length) From e03b1668e0106019eed6097678cdaf7df3885638 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 1 Aug 2013 17:15:11 +0000 Subject: [PATCH 07/25] code cleanup: remove unused functions - IsectLLPt2Df - isect_point_quad_uv_v2 - isect_point_face_uv_v2 These are obsoleted by resolve_tri_uv, resolve_quad_uv also add attributes for unused function results for some math functions. --- source/blender/blenlib/BLI_math_geom.h | 12 +- source/blender/blenlib/BLI_math_vector.h | 91 +++---- source/blender/blenlib/intern/math_geom.c | 271 ++------------------- source/blender/modifiers/intern/MOD_skin.c | 2 +- 4 files changed, 69 insertions(+), 307 deletions(-) diff --git a/source/blender/blenlib/BLI_math_geom.h b/source/blender/blenlib/BLI_math_geom.h index f9671f57acd..6cb7103be9b 100644 --- a/source/blender/blenlib/BLI_math_geom.h +++ b/source/blender/blenlib/BLI_math_geom.h @@ -147,10 +147,6 @@ int isect_point_tri_v2(const float pt[2], const float v1[2], const float v2[2], int isect_point_tri_v2_cw(const float pt[2], const float v1[2], const float v2[2], const float v3[2]); int isect_point_tri_v2_int(const int x1, const int y1, const int x2, const int y2, const int a, const int b); bool isect_point_tri_prism_v3(const float p[3], const float v1[3], const float v2[3], const float v3[3]); -void isect_point_quad_uv_v2(const float v0[2], const float v1[2], const float v2[2], const float v3[2], - const float pt[2], float r_uv[2]); -void isect_point_face_uv_v2(const int isquad, const float v0[2], const float v1[2], const float v2[2], - const float v3[2], const float pt[2], float r_uv[2]); /* axis-aligned bounding box */ bool isect_aabb_aabb_v3(const float min1[3], const float max1[3], const float min2[3], const float max2[3]); @@ -198,7 +194,7 @@ void barycentric_weights_v2(const float v1[2], const float v2[2], const float v3 void barycentric_weights_v2_quad(const float v1[2], const float v2[2], const float v3[2], const float v4[2], const float co[2], float w[4]); -int barycentric_coords_v2(const float v1[2], const float v2[2], const float v3[2], const float co[2], float w[3]); +bool barycentric_coords_v2(const float v1[2], const float v2[2], const float v3[2], const float co[2], float w[3]); int barycentric_inside_triangle_v2(const float w[3]); void resolve_tri_uv(float r_uv[2], const float st[2], const float st0[2], const float st1[2], const float st2[2]); @@ -273,9 +269,9 @@ MINLINE void madd_sh_shfl(float r[9], const float sh[3], const float f); float form_factor_quad(const float p[3], const float n[3], const float q0[3], const float q1[3], const float q2[3], const float q3[3]); -int form_factor_visible_quad(const float p[3], const float n[3], - const float v0[3], const float v1[3], const float v2[3], - float q0[3], float q1[3], float q2[3], float q3[3]); +bool form_factor_visible_quad(const float p[3], const float n[3], + const float v0[3], const float v1[3], const float v2[3], + float q0[3], float q1[3], float q2[3], float q3[3]); float form_factor_hemi_poly(float p[3], float n[3], float v1[3], float v2[3], float v3[3], float v4[3]); diff --git a/source/blender/blenlib/BLI_math_vector.h b/source/blender/blenlib/BLI_math_vector.h index 38b377c640e..e05783004c7 100644 --- a/source/blender/blenlib/BLI_math_vector.h +++ b/source/blender/blenlib/BLI_math_vector.h @@ -47,6 +47,12 @@ extern "C" { # pragma GCC diagnostic ignored "-Wredundant-decls" #endif +#ifdef __GNUC__ +# define UNUSED_RESULT_ATTR __attribute__((warn_unused_result)) +#else +# define UNUSED_RESULT_ATTR +#endif + MINLINE void zero_v2(float r[2]); MINLINE void zero_v3(float r[3]); MINLINE void zero_v4(float r[4]); @@ -115,10 +121,10 @@ MINLINE void mul_v3_v3(float r[3], const float a[3]); MINLINE void mul_v3_v3v3(float r[3], const float a[3], const float b[3]); MINLINE void mul_v4_fl(float r[4], float f); MINLINE void mul_v4_v4fl(float r[3], const float a[3], float f); -MINLINE float mul_project_m4_v3_zfac(float mat[4][4], const float co[3]); -MINLINE float dot_m3_v3_row_x(float M[3][3], const float a[3]); -MINLINE float dot_m3_v3_row_y(float M[3][3], const float a[3]); -MINLINE float dot_m3_v3_row_z(float M[3][3], const float a[3]); +MINLINE float mul_project_m4_v3_zfac(float mat[4][4], const float co[3]) UNUSED_RESULT_ATTR; +MINLINE float dot_m3_v3_row_x(float M[3][3], const float a[3]) UNUSED_RESULT_ATTR; +MINLINE float dot_m3_v3_row_y(float M[3][3], const float a[3]) UNUSED_RESULT_ATTR; +MINLINE float dot_m3_v3_row_z(float M[3][3], const float a[3]) UNUSED_RESULT_ATTR; MINLINE void madd_v3_v3fl(float r[3], const float a[3], float f); MINLINE void madd_v3_v3v3(float r[3], const float a[3], const float b[3]); @@ -137,10 +143,10 @@ MINLINE void negate_v4_v4(float r[4], const float a[3]); MINLINE void negate_v3_short(short r[3]); -MINLINE float dot_v2v2(const float a[2], const float b[2]); -MINLINE float dot_v3v3(const float a[3], const float b[3]); +MINLINE float dot_v2v2(const float a[2], const float b[2]) UNUSED_RESULT_ATTR; +MINLINE float dot_v3v3(const float a[3], const float b[3]) UNUSED_RESULT_ATTR; -MINLINE float cross_v2v2(const float a[2], const float b[2]); +MINLINE float cross_v2v2(const float a[2], const float b[2]) UNUSED_RESULT_ATTR; MINLINE void cross_v3_v3v3(float r[3], const float a[3], const float b[3]); MINLINE void add_newell_cross_v3_v3v3(float n[3], const float v_prev[3], const float v_curr[3]); @@ -149,20 +155,20 @@ MINLINE void star_m3_v3(float rmat[3][3], float a[3]); /*********************************** Length **********************************/ -MINLINE float len_squared_v2(const float v[2]); -MINLINE float len_squared_v3(const float v[3]); -MINLINE float len_manhattan_v2(const float v[2]); -MINLINE int len_manhattan_v2_int(const int v[2]); -MINLINE float len_manhattan_v3(const float v[3]); -MINLINE float len_v2(const float a[2]); -MINLINE float len_v2v2(const float a[2], const float b[2]); -MINLINE float len_squared_v2v2(const float a[2], const float b[2]); -MINLINE float len_squared_v3v3(const float a[3], const float b[3]); -MINLINE float len_manhattan_v2v2(const float a[2], const float b[2]); -MINLINE int len_manhattan_v2v2_int(const int a[2], const int b[2]); -MINLINE float len_manhattan_v3v3(const float a[3], const float b[3]); -MINLINE float len_v3(const float a[3]); -MINLINE float len_v3v3(const float a[3], const float b[3]); +MINLINE float len_squared_v2(const float v[2]) UNUSED_RESULT_ATTR; +MINLINE float len_squared_v3(const float v[3]) UNUSED_RESULT_ATTR; +MINLINE float len_manhattan_v2(const float v[2]) UNUSED_RESULT_ATTR; +MINLINE int len_manhattan_v2_int(const int v[2]) UNUSED_RESULT_ATTR; +MINLINE float len_manhattan_v3(const float v[3]) UNUSED_RESULT_ATTR; +MINLINE float len_v2(const float a[2]) UNUSED_RESULT_ATTR; +MINLINE float len_v2v2(const float a[2], const float b[2]) UNUSED_RESULT_ATTR; +MINLINE float len_squared_v2v2(const float a[2], const float b[2]) UNUSED_RESULT_ATTR; +MINLINE float len_squared_v3v3(const float a[3], const float b[3]) UNUSED_RESULT_ATTR; +MINLINE float len_manhattan_v2v2(const float a[2], const float b[2]) UNUSED_RESULT_ATTR; +MINLINE int len_manhattan_v2v2_int(const int a[2], const int b[2]) UNUSED_RESULT_ATTR; +MINLINE float len_manhattan_v3v3(const float a[3], const float b[3]) UNUSED_RESULT_ATTR; +MINLINE float len_v3(const float a[3]) UNUSED_RESULT_ATTR; +MINLINE float len_v3v3(const float a[3], const float b[3]) UNUSED_RESULT_ATTR; MINLINE float normalize_v2(float r[2]); MINLINE float normalize_v2_v2(float r[2], const float a[2]); @@ -194,35 +200,35 @@ void flip_v2_v2v2(float v[2], const float v1[2], const float v2[2]); /********************************* Comparison ********************************/ -MINLINE int is_zero_v3(const float a[3]); -MINLINE int is_zero_v4(const float a[4]); -MINLINE int is_one_v3(const float a[3]); +MINLINE int is_zero_v3(const float a[3]) UNUSED_RESULT_ATTR; +MINLINE int is_zero_v4(const float a[4]) UNUSED_RESULT_ATTR; +MINLINE int is_one_v3(const float a[3]) UNUSED_RESULT_ATTR; -MINLINE int equals_v2v2(const float v1[2], const float v2[2]); -MINLINE int equals_v3v3(const float a[3], const float b[3]); -MINLINE int compare_v2v2(const float a[2], const float b[2], const float limit); -MINLINE int compare_v3v3(const float a[3], const float b[3], const float limit); -MINLINE int compare_len_v3v3(const float a[3], const float b[3], const float limit); +MINLINE int equals_v2v2(const float v1[2], const float v2[2]) UNUSED_RESULT_ATTR; +MINLINE int equals_v3v3(const float a[3], const float b[3]) UNUSED_RESULT_ATTR; +MINLINE int compare_v2v2(const float a[2], const float b[2], const float limit) UNUSED_RESULT_ATTR; +MINLINE int compare_v3v3(const float a[3], const float b[3], const float limit) UNUSED_RESULT_ATTR; +MINLINE int compare_len_v3v3(const float a[3], const float b[3], const float limit) UNUSED_RESULT_ATTR; -MINLINE int compare_v4v4(const float a[4], const float b[4], const float limit); -MINLINE int equals_v4v4(const float a[4], const float b[4]); +MINLINE int compare_v4v4(const float a[4], const float b[4], const float limit) UNUSED_RESULT_ATTR; +MINLINE int equals_v4v4(const float a[4], const float b[4]) UNUSED_RESULT_ATTR; -MINLINE float line_point_side_v2(const float l1[2], const float l2[2], const float pt[2]); +MINLINE float line_point_side_v2(const float l1[2], const float l2[2], const float pt[2]) UNUSED_RESULT_ATTR; /********************************** Angles ***********************************/ /* - angle with 2 arguments is angle between vector */ /* - angle with 3 arguments is angle between 3 points at the middle point */ /* - angle_normalized_* is faster equivalent if vectors are normalized */ -float angle_v2v2(const float a[2], const float b[2]); -float angle_signed_v2v2(const float v1[2], const float v2[2]); -float angle_v2v2v2(const float a[2], const float b[2], const float c[2]); -float angle_normalized_v2v2(const float a[2], const float b[2]); -float angle_v3v3(const float a[3], const float b[3]); -float angle_v3v3v3(const float a[3], const float b[3], const float c[3]); -float cos_v3v3v3(const float p1[3], const float p2[3], const float p3[3]); -float angle_normalized_v3v3(const float v1[3], const float v2[3]); -float angle_on_axis_v3v3v3_v3(const float v1[3], const float v2[3], const float v3[3], const float axis[3]); +float angle_v2v2(const float a[2], const float b[2]) UNUSED_RESULT_ATTR; +float angle_signed_v2v2(const float v1[2], const float v2[2]) UNUSED_RESULT_ATTR; +float angle_v2v2v2(const float a[2], const float b[2], const float c[2]) UNUSED_RESULT_ATTR; +float angle_normalized_v2v2(const float a[2], const float b[2]) UNUSED_RESULT_ATTR; +float angle_v3v3(const float a[3], const float b[3]) UNUSED_RESULT_ATTR; +float angle_v3v3v3(const float a[3], const float b[3], const float c[3]) UNUSED_RESULT_ATTR; +float cos_v3v3v3(const float p1[3], const float p2[3], const float p3[3]) UNUSED_RESULT_ATTR; +float angle_normalized_v3v3(const float v1[3], const float v2[3]) UNUSED_RESULT_ATTR; +float angle_on_axis_v3v3v3_v3(const float v1[3], const float v2[3], const float v3[3], const float axis[3]) UNUSED_RESULT_ATTR; void angle_tri_v3(float angles[3], const float v1[3], const float v2[3], const float v3[3]); void angle_quad_v3(float angles[4], const float v1[3], const float v2[3], const float v3[3], const float v4[3]); void angle_poly_v3(float *angles, const float *verts[3], int len); @@ -258,7 +264,7 @@ void axis_sort_v3(const float axis_values[3], int r_axis_order[3]); /***************************** Array Functions *******************************/ /* attempted to follow fixed length vertex functions. names could be improved*/ -double dot_vn_vn(const float *array_src_a, const float *array_src_b, const int size); +double dot_vn_vn(const float *array_src_a, const float *array_src_b, const int size) UNUSED_RESULT_ATTR; float normalize_vn_vn(float *array_tar, const float *array_src, const int size); float normalize_vn(float *array_tar, const int size); void range_vn_i(int *array_tar, const int size, const int start); @@ -283,6 +289,7 @@ void fill_vn_fl(float *array_tar, const int size, const float val); #ifdef BLI_MATH_GCC_WARN_PRAGMA # pragma GCC diagnostic pop #endif +#undef UNUSED_RESULT_ATTR #ifdef __cplusplus } diff --git a/source/blender/blenlib/intern/math_geom.c b/source/blender/blenlib/intern/math_geom.c index 0e7ff521ce8..9b8fd0ad85b 100644 --- a/source/blender/blenlib/intern/math_geom.c +++ b/source/blender/blenlib/intern/math_geom.c @@ -695,60 +695,6 @@ int isect_line_sphere_v2(const float l1[2], const float l2[2], } } -/** - * \return - * -1: collinear - * 1: intersection - */ -static short IsectLLPt2Df(const float x0, const float y0, const float x1, const float y1, - const float x2, const float y2, const float x3, const float y3, float *xi, float *yi) - -{ - /* - * this function computes the intersection of the sent lines - * and returns the intersection point, note that the function assumes - * the lines intersect. the function can handle vertical as well - * as horizontal lines. note the function isn't very clever, it simply - * applies the math, but we don't need speed since this is a - * pre-processing step - */ - float c1, c2; /* constants of linear equations */ - float det_inv; /* the inverse of the determinant of the coefficient */ - float m1, m2; /* the slopes of each line */ - /* - * compute slopes, note the cludge for infinity, however, this will - * be close enough - */ - if (fabsf(x1 - x0) > 0.000001f) - m1 = (y1 - y0) / (x1 - x0); - else - return -1; /*m1 = (float)1e+10;*/ /* close enough to infinity */ - - if (fabsf(x3 - x2) > 0.000001f) - m2 = (y3 - y2) / (x3 - x2); - else - return -1; /*m2 = (float)1e+10;*/ /* close enough to infinity */ - - if (fabsf(m1 - m2) < 0.000001f) - return -1; /* parallel lines */ - - /* compute constants */ - - c1 = (y0 - m1 * x0); - c2 = (y2 - m2 * x2); - - /* compute the inverse of the determinate */ - - det_inv = 1.0f / (-m1 + m2); - - /* use Kramers rule to compute xi and yi */ - - *xi = ((-c2 + c1) * det_inv); - *yi = ((m2 * c1 - m1 * c2) * det_inv); - - return 1; -} - /* point in polygon (keep float and int versions in sync) */ bool isect_point_poly_v2(const float pt[2], const float verts[][2], const int nr) { @@ -1718,193 +1664,6 @@ void limit_dist_v3(float v1[3], float v2[3], const float dist) } } -/* Similar to LineIntersectsTriangleUV, except it operates on a quad and in 2d, assumes point is in quad */ -void isect_point_quad_uv_v2(const float v0[2], const float v1[2], const float v2[2], const float v3[2], - const float pt[2], float r_uv[2]) -{ - float x0, y0, x1, y1, wtot, v2d[2], w1, w2; - - /* used for parallel lines */ - float pt3d[3], l1[3], l2[3], pt_on_line[3]; - - /* compute 2 edges of the quad intersection point */ - if (IsectLLPt2Df(v0[0], v0[1], v1[0], v1[1], v2[0], v2[1], v3[0], v3[1], &x0, &y0) == 1) { - /* the intersection point between the quad-edge intersection and the point in the quad we want the uv's for */ - /* should never be paralle !! */ - /*printf("\tnot parallel 1\n");*/ - IsectLLPt2Df(pt[0], pt[1], x0, y0, v0[0], v0[1], v3[0], v3[1], &x1, &y1); - - /* Get the weights from the new intersection point, to each edge */ - v2d[0] = x1 - v0[0]; - v2d[1] = y1 - v0[1]; - w1 = len_v2(v2d); - - v2d[0] = x1 - v3[0]; /* some but for the other vert */ - v2d[1] = y1 - v3[1]; - w2 = len_v2(v2d); - wtot = w1 + w2; - /*w1 = w1/wtot;*/ - /*w2 = w2/wtot;*/ - r_uv[0] = w1 / wtot; - } - else { - /* lines are parallel, lambda_cp_line_ex is 3d grrr */ - /*printf("\tparallel1\n");*/ - pt3d[0] = pt[0]; - pt3d[1] = pt[1]; - pt3d[2] = l1[2] = l2[2] = 0.0f; - - l1[0] = v0[0]; - l1[1] = v0[1]; - l2[0] = v1[0]; - l2[1] = v1[1]; - closest_to_line_v3(pt_on_line, pt3d, l1, l2); - v2d[0] = pt[0] - pt_on_line[0]; /* same, for the other vert */ - v2d[1] = pt[1] - pt_on_line[1]; - w1 = len_v2(v2d); - - l1[0] = v2[0]; - l1[1] = v2[1]; - l2[0] = v3[0]; - l2[1] = v3[1]; - closest_to_line_v3(pt_on_line, pt3d, l1, l2); - v2d[0] = pt[0] - pt_on_line[0]; /* same, for the other vert */ - v2d[1] = pt[1] - pt_on_line[1]; - w2 = len_v2(v2d); - wtot = w1 + w2; - r_uv[0] = w1 / wtot; - } - - /* Same as above to calc the uv[1] value, alternate calculation */ - - if (IsectLLPt2Df(v0[0], v0[1], v3[0], v3[1], v1[0], v1[1], v2[0], v2[1], &x0, &y0) == 1) { /* was v0,v1 v2,v3 now v0,v3 v1,v2*/ - /* never paralle if above was not */ - /*printf("\tnot parallel2\n");*/ - IsectLLPt2Df(pt[0], pt[1], x0, y0, v0[0], v0[1], v1[0], v1[1], &x1, &y1); /* was v0,v3 now v0,v1*/ - - v2d[0] = x1 - v0[0]; - v2d[1] = y1 - v0[1]; - w1 = len_v2(v2d); - - v2d[0] = x1 - v1[0]; - v2d[1] = y1 - v1[1]; - w2 = len_v2(v2d); - wtot = w1 + w2; - r_uv[1] = w1 / wtot; - } - else { - /* lines are parallel, lambda_cp_line_ex is 3d grrr */ - /*printf("\tparallel2\n");*/ - pt3d[0] = pt[0]; - pt3d[1] = pt[1]; - pt3d[2] = l1[2] = l2[2] = 0.0f; - - - l1[0] = v0[0]; - l1[1] = v0[1]; - l2[0] = v3[0]; - l2[1] = v3[1]; - closest_to_line_v3(pt_on_line, pt3d, l1, l2); - v2d[0] = pt[0] - pt_on_line[0]; /* some but for the other vert */ - v2d[1] = pt[1] - pt_on_line[1]; - w1 = len_v2(v2d); - - l1[0] = v1[0]; - l1[1] = v1[1]; - l2[0] = v2[0]; - l2[1] = v2[1]; - closest_to_line_v3(pt_on_line, pt3d, l1, l2); - v2d[0] = pt[0] - pt_on_line[0]; /* some but for the other vert */ - v2d[1] = pt[1] - pt_on_line[1]; - w2 = len_v2(v2d); - wtot = w1 + w2; - r_uv[1] = w1 / wtot; - } - /* may need to flip UV's here */ -} - -/* same as above but does tri's and quads, tri's are a bit of a hack */ -void isect_point_face_uv_v2(const int isquad, - const float v0[2], const float v1[2], const float v2[2], const float v3[2], - const float pt[2], float r_uv[2]) -{ - if (isquad) { - isect_point_quad_uv_v2(v0, v1, v2, v3, pt, r_uv); - } - else { - /* not for quads, use for our abuse of LineIntersectsTriangleUV */ - float p1_3d[3], p2_3d[3], v0_3d[3], v1_3d[3], v2_3d[3], lambda; - - p1_3d[0] = p2_3d[0] = r_uv[0]; - p1_3d[1] = p2_3d[1] = r_uv[1]; - p1_3d[2] = 1.0f; - p2_3d[2] = -1.0f; - v0_3d[2] = v1_3d[2] = v2_3d[2] = 0.0; - - /* generate a new fuv, (this is possibly a non optimal solution, - * since we only need 2d calculation but use 3d func's) - * - * this method makes an imaginary triangle in 2d space using the UV's from the derived mesh face - * Then find new uv coords using the fuv and this face with LineIntersectsTriangleUV. - * This means the new values will be correct in relation to the derived meshes face. - */ - copy_v2_v2(v0_3d, v0); - copy_v2_v2(v1_3d, v1); - copy_v2_v2(v2_3d, v2); - - /* Doing this in 3D is not nice */ - isect_line_tri_v3(p1_3d, p2_3d, v0_3d, v1_3d, v2_3d, &lambda, r_uv); - } -} - -#if 0 /* XXX this version used to be used in isect_point_tri_v2_int() and was called IsPointInTri2D */ - -int isect_point_tri_v2(float pt[2], float v1[2], float v2[2], float v3[2]) -{ - float inp1, inp2, inp3; - - inp1 = (v2[0] - v1[0]) * (v1[1] - pt[1]) + (v1[1] - v2[1]) * (v1[0] - pt[0]); - inp2 = (v3[0] - v2[0]) * (v2[1] - pt[1]) + (v2[1] - v3[1]) * (v2[0] - pt[0]); - inp3 = (v1[0] - v3[0]) * (v3[1] - pt[1]) + (v3[1] - v1[1]) * (v3[0] - pt[0]); - - if (inp1 <= 0.0f && inp2 <= 0.0f && inp3 <= 0.0f) return 1; - if (inp1 >= 0.0f && inp2 >= 0.0f && inp3 >= 0.0f) return 1; - - return 0; -} -#endif - -#if 0 - -int isect_point_tri_v2(float v0[2], float v1[2], float v2[2], float pt[2]) -{ - /* not for quads, use for our abuse of LineIntersectsTriangleUV */ - float p1_3d[3], p2_3d[3], v0_3d[3], v1_3d[3], v2_3d[3]; - /* not used */ - float lambda, uv[3]; - - p1_3d[0] = p2_3d[0] = uv[0] = pt[0]; - p1_3d[1] = p2_3d[1] = uv[1] = uv[2] = pt[1]; - p1_3d[2] = 1.0f; - p2_3d[2] = -1.0f; - v0_3d[2] = v1_3d[2] = v2_3d[2] = 0.0; - - /* generate a new fuv, (this is possibly a non optimal solution, - * since we only need 2d calculation but use 3d func's) - * - * this method makes an imaginary triangle in 2d space using the UV's from the derived mesh face - * Then find new uv coords using the fuv and this face with LineIntersectsTriangleUV. - * This means the new values will be correct in relation to the derived meshes face. - */ - copy_v2_v2(v0_3d, v0); - copy_v2_v2(v1_3d, v1); - copy_v2_v2(v2_3d, v2); - - /* Doing this in 3D is not nice */ - return isect_line_tri_v3(p1_3d, p2_3d, v0_3d, v1_3d, v2_3d, &lambda, uv); -} -#endif - /* * x1,y2 * | \ @@ -2326,7 +2085,7 @@ int barycentric_inside_triangle_v2(const float w[3]) } /* returns 0 for degenerated triangles */ -int barycentric_coords_v2(const float v1[2], const float v2[2], const float v3[2], const float co[2], float w[3]) +bool barycentric_coords_v2(const float v1[2], const float v2[2], const float v3[2], const float co[2], float w[3]) { float x = co[0], y = co[1]; float x1 = v1[0], y1 = v1[1]; @@ -2339,10 +2098,10 @@ int barycentric_coords_v2(const float v1[2], const float v2[2], const float v3[2 w[1] = ((y3 - y1) * (x - x3) + (x1 - x3) * (y - y3)) / det; w[2] = 1.0f - w[0] - w[1]; - return 1; + return true; } - return 0; + return false; } /* used by projection painting @@ -3384,9 +3143,9 @@ static void vec_add_dir(float r[3], const float v1[3], const float v2[3], const r[2] = v1[2] + fac * (v2[2] - v1[2]); } -int form_factor_visible_quad(const float p[3], const float n[3], - const float v0[3], const float v1[3], const float v2[3], - float q0[3], float q1[3], float q2[3], float q3[3]) +bool form_factor_visible_quad(const float p[3], const float n[3], + const float v0[3], const float v1[3], const float v2[3], + float q0[3], float q1[3], float q2[3], float q3[3]) { static const float epsilon = 1e-6f; float c, sd[3]; @@ -3507,11 +3266,11 @@ int form_factor_visible_quad(const float p[3], const float n[3], } else if (sd[2] < 0) { /* --- */ - return 0; + return false; } else { /* --0 */ - return 0; + return false; } } else { @@ -3524,11 +3283,11 @@ int form_factor_visible_quad(const float p[3], const float n[3], } else if (sd[2] < 0) { /* -0- */ - return 0; + return false; } else { /* -00 */ - return 0; + return false; } } } @@ -3566,11 +3325,11 @@ int form_factor_visible_quad(const float p[3], const float n[3], } else if (sd[2] < 0) { /* 0-- */ - return 0; + return false; } else { /* 0-0 */ - return 0; + return false; } } else { @@ -3583,16 +3342,16 @@ int form_factor_visible_quad(const float p[3], const float n[3], } else if (sd[2] < 0) { /* 00- */ - return 0; + return false; } else { /* 000 */ - return 0; + return false; } } } - return 1; + return true; } /* altivec optimization, this works, but is unused */ diff --git a/source/blender/modifiers/intern/MOD_skin.c b/source/blender/modifiers/intern/MOD_skin.c index 91dcf721e4b..df0a0266154 100644 --- a/source/blender/modifiers/intern/MOD_skin.c +++ b/source/blender/modifiers/intern/MOD_skin.c @@ -1039,7 +1039,7 @@ static int isect_ray_poly(const float ray_start[3], v_first = v; else if (v_prev != v_first) { float dist; - int curhit; + bool curhit; curhit = isect_ray_tri_v3(ray_start, ray_dir, v_first->co, v_prev->co, v->co, From 78820edafcad730493e95d0dfdeccba02445c1f3 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 1 Aug 2013 18:33:35 +0000 Subject: [PATCH 08/25] use bmesh for loop macros for looping over mesh verts/edges/faces --- .../blender/blenkernel/intern/cdderivedmesh.c | 19 +++++++-------- source/blender/bmesh/intern/bmesh_marking.c | 6 ++--- source/blender/bmesh/operators/bmo_dupe.c | 23 ++++++++----------- source/blender/bmesh/operators/bmo_edgenet.c | 3 +-- .../editors/space_view3d/view3d_select.c | 11 +++++---- 5 files changed, 28 insertions(+), 34 deletions(-) diff --git a/source/blender/blenkernel/intern/cdderivedmesh.c b/source/blender/blenkernel/intern/cdderivedmesh.c index 60f6bb0a736..6205c8016b6 100644 --- a/source/blender/blenkernel/intern/cdderivedmesh.c +++ b/source/blender/blenkernel/intern/cdderivedmesh.c @@ -1969,8 +1969,7 @@ static DerivedMesh *cddm_from_bmesh_ex(struct BMesh *bm, int use_mdisps, index = dm->getVertDataArray(dm, CD_ORIGINDEX); - eve = BM_iter_new(&iter, bm, BM_VERTS_OF_MESH, NULL); - for (i = 0; eve; eve = BM_iter_step(&iter), i++, index++) { + BM_ITER_MESH_INDEX (eve, &iter, bm, BM_VERTS_OF_MESH, i) { MVert *mv = &mvert[i]; copy_v3_v3(mv->co, eve->co); @@ -1983,15 +1982,14 @@ static DerivedMesh *cddm_from_bmesh_ex(struct BMesh *bm, int use_mdisps, if (cd_vert_bweight_offset != -1) mv->bweight = BM_ELEM_CD_GET_FLOAT_AS_UCHAR(eve, cd_vert_bweight_offset); - if (add_orig) *index = i; + if (add_orig) *index++ = i; CustomData_from_bmesh_block(&bm->vdata, &dm->vertData, eve->head.data, i); } bm->elem_index_dirty &= ~BM_VERT; index = dm->getEdgeDataArray(dm, CD_ORIGINDEX); - eed = BM_iter_new(&iter, bm, BM_EDGES_OF_MESH, NULL); - for (i = 0; eed; eed = BM_iter_step(&iter), i++, index++) { + BM_ITER_MESH_INDEX (eed, &iter, bm, BM_EDGES_OF_MESH, i) { MEdge *med = &medge[i]; BM_elem_index_set(eed, i); /* set_inline */ @@ -2013,7 +2011,7 @@ static DerivedMesh *cddm_from_bmesh_ex(struct BMesh *bm, int use_mdisps, if (cd_edge_bweight_offset != -1) med->bweight = BM_ELEM_CD_GET_FLOAT_AS_UCHAR(eed, cd_edge_bweight_offset); CustomData_from_bmesh_block(&bm->edata, &dm->edgeData, eed->head.data, i); - if (add_orig) *index = i; + if (add_orig) *index++ = i; } bm->elem_index_dirty &= ~BM_EDGE; @@ -2023,7 +2021,7 @@ static DerivedMesh *cddm_from_bmesh_ex(struct BMesh *bm, int use_mdisps, BM_mesh_elem_index_ensure(bm, BM_FACE); index = dm->getTessFaceDataArray(dm, CD_ORIGINDEX); - for (i = 0; i < dm->numTessFaceData; i++, index++) { + for (i = 0; i < dm->numTessFaceData; i++) { MFace *mf = &mface[i]; const BMLoop **l = em_looptris[i]; efa = l[0]->f; @@ -2036,7 +2034,7 @@ static DerivedMesh *cddm_from_bmesh_ex(struct BMesh *bm, int use_mdisps, mf->flag = BM_face_flag_to_mflag(efa); /* map mfaces to polygons in the same cddm intentionally */ - *index = BM_elem_index_get(efa); + *index++ = BM_elem_index_get(efa); loops_to_customdata_corners(bm, &dm->faceData, i, l, numCol, numTex); test_index_face(mf, &dm->faceData, i, 3); @@ -2045,8 +2043,7 @@ static DerivedMesh *cddm_from_bmesh_ex(struct BMesh *bm, int use_mdisps, index = CustomData_get_layer(&dm->polyData, CD_ORIGINDEX); j = 0; - efa = BM_iter_new(&iter, bm, BM_FACES_OF_MESH, NULL); - for (i = 0; efa; i++, efa = BM_iter_step(&iter), index++) { + BM_ITER_MESH_INDEX (efa, &iter, bm, BM_FACES_OF_MESH, i) { BMLoop *l_iter; BMLoop *l_first; MPoly *mp = &mpoly[i]; @@ -2070,7 +2067,7 @@ static DerivedMesh *cddm_from_bmesh_ex(struct BMesh *bm, int use_mdisps, CustomData_from_bmesh_block(&bm->pdata, &dm->polyData, efa->head.data, i); - if (add_orig) *index = i; + if (add_orig) *index++ = i; } bm->elem_index_dirty &= ~BM_FACE; diff --git a/source/blender/bmesh/intern/bmesh_marking.c b/source/blender/bmesh/intern/bmesh_marking.c index 61a326bbf97..d66e478cf22 100644 --- a/source/blender/bmesh/intern/bmesh_marking.c +++ b/source/blender/bmesh/intern/bmesh_marking.c @@ -501,19 +501,19 @@ static int bm_mesh_flag_count(BMesh *bm, const char htype, const char hflag, BLI_assert((htype & ~BM_ALL_NOLOOP) == 0); if (htype & BM_VERT) { - for (ele = BM_iter_new(&iter, bm, BM_VERTS_OF_MESH, NULL); ele; ele = BM_iter_step(&iter)) { + BM_ITER_MESH (ele, &iter, bm, BM_VERTS_OF_MESH) { if (respecthide && BM_elem_flag_test(ele, BM_ELEM_HIDDEN)) continue; if (BM_elem_flag_test_bool(ele, hflag) == test_for_enabled) tot++; } } if (htype & BM_EDGE) { - for (ele = BM_iter_new(&iter, bm, BM_EDGES_OF_MESH, NULL); ele; ele = BM_iter_step(&iter)) { + BM_ITER_MESH (ele, &iter, bm, BM_EDGES_OF_MESH) { if (respecthide && BM_elem_flag_test(ele, BM_ELEM_HIDDEN)) continue; if (BM_elem_flag_test_bool(ele, hflag) == test_for_enabled) tot++; } } if (htype & BM_FACE) { - for (ele = BM_iter_new(&iter, bm, BM_FACES_OF_MESH, NULL); ele; ele = BM_iter_step(&iter)) { + BM_ITER_MESH (ele, &iter, bm, BM_FACES_OF_MESH) { if (respecthide && BM_elem_flag_test(ele, BM_ELEM_HIDDEN)) continue; if (BM_elem_flag_test_bool(ele, hflag) == test_for_enabled) tot++; } diff --git a/source/blender/bmesh/operators/bmo_dupe.c b/source/blender/bmesh/operators/bmo_dupe.c index f9ff308b706..1dc7b0a414d 100644 --- a/source/blender/bmesh/operators/bmo_dupe.c +++ b/source/blender/bmesh/operators/bmo_dupe.c @@ -385,33 +385,30 @@ void bmo_split_exec(BMesh *bm, BMOperator *op) BMEdge *e; BMFace *f; BMIter iter, iter2; - int found; /* make sure to remove edges and verts we don't need */ - for (e = BM_iter_new(&iter, bm, BM_EDGES_OF_MESH, NULL); e; e = BM_iter_step(&iter)) { - found = 0; - f = BM_iter_new(&iter2, bm, BM_FACES_OF_EDGE, e); - for ( ; f; f = BM_iter_step(&iter2)) { + BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) { + bool found = false; + BM_ITER_ELEM (f, &iter2, e, BM_FACES_OF_EDGE) { if (!BMO_elem_flag_test(bm, f, SPLIT_INPUT)) { - found = 1; + found = true; break; } } - if (!found) { + if (found == false) { BMO_elem_flag_enable(bm, e, SPLIT_INPUT); } } - for (v = BM_iter_new(&iter, bm, BM_VERTS_OF_MESH, NULL); v; v = BM_iter_step(&iter)) { - found = 0; - e = BM_iter_new(&iter2, bm, BM_EDGES_OF_VERT, v); - for ( ; e; e = BM_iter_step(&iter2)) { + BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) { + bool found = false; + BM_ITER_ELEM (e, &iter2, v, BM_EDGES_OF_VERT) { if (!BMO_elem_flag_test(bm, e, SPLIT_INPUT)) { - found = 1; + found = true; break; } } - if (!found) { + if (found == false) { BMO_elem_flag_enable(bm, v, SPLIT_INPUT); } } diff --git a/source/blender/bmesh/operators/bmo_edgenet.c b/source/blender/bmesh/operators/bmo_edgenet.c index 903cef05604..325b40cb935 100644 --- a/source/blender/bmesh/operators/bmo_edgenet.c +++ b/source/blender/bmesh/operators/bmo_edgenet.c @@ -302,8 +302,7 @@ static void rotsys_make_consistent(BMesh *bm, EdgeData *edata, VertData *vdata) BMVert *startv = NULL; float dis; - v = BM_iter_new(&iter, bm, BM_VERTS_OF_MESH, NULL); - for (i = 0; i < bm->totvert; i++, BM_iter_step(&iter)) { + BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) { vd = vdata + BM_elem_index_get(v); if (vd->tag) diff --git a/source/blender/editors/space_view3d/view3d_select.c b/source/blender/editors/space_view3d/view3d_select.c index 16282b0d49c..4724d061909 100644 --- a/source/blender/editors/space_view3d/view3d_select.c +++ b/source/blender/editors/space_view3d/view3d_select.c @@ -146,12 +146,13 @@ static void edbm_backbuf_check_and_select_verts(BMEditMesh *em, const bool selec BMIter iter; unsigned int index = bm_wireoffs; - for (eve = BM_iter_new(&iter, em->bm, BM_VERTS_OF_MESH, NULL); eve; eve = BM_iter_step(&iter), index++) { + BM_ITER_MESH (eve, &iter, em->bm, BM_VERTS_OF_MESH) { if (!BM_elem_flag_test(eve, BM_ELEM_HIDDEN)) { if (EDBM_backbuf_check(index)) { BM_vert_select_set(em->bm, eve, select); } } + index++; } } @@ -161,13 +162,13 @@ static void edbm_backbuf_check_and_select_edges(BMEditMesh *em, const bool selec BMIter iter; int index = bm_solidoffs; - eed = BM_iter_new(&iter, em->bm, BM_EDGES_OF_MESH, NULL); - for (; eed; eed = BM_iter_step(&iter), index++) { + BM_ITER_MESH (eed, &iter, em->bm, BM_EDGES_OF_MESH) { if (!BM_elem_flag_test(eed, BM_ELEM_HIDDEN)) { if (EDBM_backbuf_check(index)) { BM_edge_select_set(em->bm, eed, select); } } + index++; } } @@ -177,13 +178,13 @@ static void edbm_backbuf_check_and_select_faces(BMEditMesh *em, const bool selec BMIter iter; unsigned int index = 1; - efa = BM_iter_new(&iter, em->bm, BM_FACES_OF_MESH, NULL); - for (; efa; efa = BM_iter_step(&iter), index++) { + BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) { if (!BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) { if (EDBM_backbuf_check(index)) { BM_face_select_set(em->bm, efa, select); } } + index++; } } From 36df391b2fe0eccf8182d817cf3fc73cbc7bc6fd Mon Sep 17 00:00:00 2001 From: Antony Riakiotakis Date: Thu, 1 Aug 2013 23:07:53 +0000 Subject: [PATCH 09/25] User request: when switching to smooth tool with shift-click in sculpting, use the original brush size. --- source/blender/editors/sculpt_paint/sculpt.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c index 4b7c2995ea7..2edd00c015d 100644 --- a/source/blender/editors/sculpt_paint/sculpt.c +++ b/source/blender/editors/sculpt_paint/sculpt.c @@ -306,6 +306,7 @@ typedef struct StrokeCache { char saved_active_brush_name[MAX_ID_NAME]; char saved_mask_brush_tool; + int saved_smooth_size; /* smooth tool copies the size of the current tool */ int alt_smooth; float plane_trim_squared; @@ -3710,6 +3711,7 @@ static void sculpt_omp_done(SculptSession *ss) static void sculpt_update_cache_invariants(bContext *C, Sculpt *sd, SculptSession *ss, wmOperator *op, const float mouse[2]) { StrokeCache *cache = MEM_callocN(sizeof(StrokeCache), "stroke cache"); + Scene *scene = CTX_data_scene(C); UnifiedPaintSettings *ups = &CTX_data_tool_settings(C)->unified_paint_settings; Brush *brush = BKE_paint_brush(&sd->paint); ViewContext *vc = paint_stroke_view_context(op->customdata); @@ -3755,6 +3757,7 @@ static void sculpt_update_cache_invariants(bContext *C, Sculpt *sd, SculptSessio else { Paint *p = &sd->paint; Brush *br; + int size = BKE_brush_size_get(scene, brush); BLI_strncpy(cache->saved_active_brush_name, brush->id.name + 2, sizeof(cache->saved_active_brush_name)); @@ -3763,6 +3766,8 @@ static void sculpt_update_cache_invariants(bContext *C, Sculpt *sd, SculptSessio if (br) { BKE_paint_brush_set(p, br); brush = br; + cache->saved_smooth_size = BKE_brush_size_get(scene, brush); + BKE_brush_size_set(scene, brush, size); } } } @@ -4352,6 +4357,7 @@ static void sculpt_stroke_done(const bContext *C, struct PaintStroke *UNUSED(str { UnifiedPaintSettings *ups = &CTX_data_tool_settings(C)->unified_paint_settings; Object *ob = CTX_data_active_object(C); + Scene *scene = CTX_data_scene(C); SculptSession *ss = ob->sculpt; Sculpt *sd = CTX_data_tool_settings(C)->sculpt; @@ -4375,6 +4381,7 @@ static void sculpt_stroke_done(const bContext *C, struct PaintStroke *UNUSED(str } else { Paint *p = &sd->paint; + BKE_brush_size_set(scene, ss->cache->brush, ss->cache->saved_smooth_size); brush = (Brush *)BKE_libblock_find_name(ID_BR, ss->cache->saved_active_brush_name); if (brush) { BKE_paint_brush_set(p, brush); From 53024698341690f53ce68f5b11b4c3635df833b5 Mon Sep 17 00:00:00 2001 From: Antony Riakiotakis Date: Fri, 2 Aug 2013 00:24:34 +0000 Subject: [PATCH 10/25] Some versioning changes/patching of the brush system: * Change overlay alphas to 33 if not initialized. This should have been done for 2.67 but better do it now to avoid frustration with overly transparent overlays. For users that have set this low manually this will reset the setting to 33 but I think it's less irritating than users who unwillingly had the setting to 1 and saw nothing when activating the overlay. * Allow overlay alpha to be zero as well * Reset old, now obsolete BRUSH_FIXED flag for brushes that still use this. I am doing this here to avoid patching hell when the paint brush is merged, since it's not possible to know the merged version beforehand, and this flag will be used. --- source/blender/blenkernel/BKE_blender.h | 3 +-- source/blender/blenloader/intern/readfile.c | 16 ++++++++++++++++ source/blender/makesrna/intern/rna_brush.c | 6 +++--- 3 files changed, 20 insertions(+), 5 deletions(-) diff --git a/source/blender/blenkernel/BKE_blender.h b/source/blender/blenkernel/BKE_blender.h index a0c2908a646..84e24df43e5 100644 --- a/source/blender/blenkernel/BKE_blender.h +++ b/source/blender/blenkernel/BKE_blender.h @@ -42,8 +42,7 @@ extern "C" { * and keep comment above the defines. * Use STRINGIFY() rather than defining with quotes */ #define BLENDER_VERSION 268 -#define BLENDER_SUBVERSION 1 - +#define BLENDER_SUBVERSION 2 /* 262 was the last editmesh release but it has compatibility code for bmesh data */ #define BLENDER_MINVERSION 262 #define BLENDER_MINSUBVERSION 0 diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 1ed22a53251..0ff3392ad00 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -9495,6 +9495,22 @@ static void do_versions(FileData *fd, Library *lib, Main *main) brush->spacing = MAX2(1, brush->spacing); } } + + if (!MAIN_VERSION_ATLEAST(main, 268, 2)) { + Brush *brush; + #define BRUSH_FIXED (1 << 6) + for (brush = main->brush.first; brush; brush = brush->id.next) { + brush->flag &= ~BRUSH_FIXED; + + if(brush->cursor_overlay_alpha < 2) + brush->cursor_overlay_alpha = 33; + if(brush->texture_overlay_alpha < 2) + brush->texture_overlay_alpha = 33; + if(brush->mask_overlay_alpha <2) + brush->mask_overlay_alpha = 33; + } + #undef BRUSH_FIXED + } { bScreen *sc; diff --git a/source/blender/makesrna/intern/rna_brush.c b/source/blender/makesrna/intern/rna_brush.c index c1707048612..5d68a6905a3 100644 --- a/source/blender/makesrna/intern/rna_brush.c +++ b/source/blender/makesrna/intern/rna_brush.c @@ -1086,19 +1086,19 @@ static void rna_def_brush(BlenderRNA *brna) prop = RNA_def_property(srna, "texture_overlay_alpha", PROP_INT, PROP_PERCENTAGE); RNA_def_property_int_sdna(prop, NULL, "texture_overlay_alpha"); - RNA_def_property_range(prop, 1, 100); + RNA_def_property_range(prop, 0, 100); RNA_def_property_ui_text(prop, "Texture Overlay Alpha", ""); RNA_def_property_update(prop, 0, "rna_Brush_update"); prop = RNA_def_property(srna, "mask_overlay_alpha", PROP_INT, PROP_PERCENTAGE); RNA_def_property_int_sdna(prop, NULL, "mask_overlay_alpha"); - RNA_def_property_range(prop, 1, 100); + RNA_def_property_range(prop, 0, 100); RNA_def_property_ui_text(prop, "Mask Texture Overlay Alpha", ""); RNA_def_property_update(prop, 0, "rna_Brush_update"); prop = RNA_def_property(srna, "cursor_overlay_alpha", PROP_INT, PROP_PERCENTAGE); RNA_def_property_int_sdna(prop, NULL, "cursor_overlay_alpha"); - RNA_def_property_range(prop, 1, 100); + RNA_def_property_range(prop, 0, 100); RNA_def_property_ui_text(prop, "Mask Texture Overlay Alpha", ""); RNA_def_property_update(prop, 0, "rna_Brush_update"); From efe690a3a5a53e7857838236159f6b1a41e48bd8 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 2 Aug 2013 13:21:32 +0000 Subject: [PATCH 11/25] code cleanup: - incorrect NULL check in logic UI drawing - incorrect NULL check in octree quad test --- source/blender/editors/space_logic/logic_window.c | 7 +++---- source/blender/editors/space_outliner/outliner_tools.c | 4 ++++ source/blender/render/intern/raytrace/rayobject_octree.cpp | 2 +- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/source/blender/editors/space_logic/logic_window.c b/source/blender/editors/space_logic/logic_window.c index ce8ee25eef0..2957edd941b 100644 --- a/source/blender/editors/space_logic/logic_window.c +++ b/source/blender/editors/space_logic/logic_window.c @@ -1009,8 +1009,6 @@ static void draw_sensor_armature(uiLayout *layout, PointerRNA *ptr) bSensor *sens = (bSensor *)ptr->data; bArmatureSensor *as = (bArmatureSensor *) sens->data; Object *ob = (Object *)ptr->id.data; - PointerRNA pose_ptr, pchan_ptr; - PropertyRNA *bones_prop= NULL; uiLayout *row; if (ob->type != OB_ARMATURE) { @@ -1019,11 +1017,12 @@ static void draw_sensor_armature(uiLayout *layout, PointerRNA *ptr) } if (ob->pose) { + PointerRNA pose_ptr, pchan_ptr; + PropertyRNA *bones_prop; + RNA_pointer_create((ID *)ob, &RNA_Pose, ob->pose, &pose_ptr); bones_prop = RNA_struct_find_property(&pose_ptr, "bones"); - } - if (&pose_ptr.data) { uiItemPointerR(layout, ptr, "bone", &pose_ptr, "bones", NULL, ICON_BONE_DATA); if (RNA_property_collection_lookup_string(&pose_ptr, bones_prop, as->posechannel, &pchan_ptr)) diff --git a/source/blender/editors/space_outliner/outliner_tools.c b/source/blender/editors/space_outliner/outliner_tools.c index fb56c5c6dfe..1e4af4304f0 100644 --- a/source/blender/editors/space_outliner/outliner_tools.c +++ b/source/blender/editors/space_outliner/outliner_tools.c @@ -683,6 +683,10 @@ static int outliner_object_operation_exec(bContext *C, wmOperator *op) outliner_do_object_operation(C, scene, soops, &soops->tree, item_rename_cb); str = "Rename Object"; } + else { + BLI_assert(0); + return OPERATOR_CANCELLED; + } ED_undo_push(C, str); diff --git a/source/blender/render/intern/raytrace/rayobject_octree.cpp b/source/blender/render/intern/raytrace/rayobject_octree.cpp index e4fd5a6d41e..2f668ba62d0 100644 --- a/source/blender/render/intern/raytrace/rayobject_octree.cpp +++ b/source/blender/render/intern/raytrace/rayobject_octree.cpp @@ -521,7 +521,7 @@ static void octree_fill_rayface(Octree *oc, RayFace *face) copy_v3_v3(co1, face->v1); copy_v3_v3(co2, face->v2); copy_v3_v3(co3, face->v3); - if (face->v4) + if (RE_rayface_isQuad(face)) copy_v3_v3(co4, face->v4); for (c = 0; c < 3; c++) { From c17f5960df41106a9d21b95dfdf54dbb505cbc71 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 2 Aug 2013 13:35:04 +0000 Subject: [PATCH 12/25] correct error in own recent edits to triangle joining --- source/blender/bmesh/operators/bmo_join_triangles.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/source/blender/bmesh/operators/bmo_join_triangles.c b/source/blender/bmesh/operators/bmo_join_triangles.c index 5ee03b8a541..12065743136 100644 --- a/source/blender/bmesh/operators/bmo_join_triangles.c +++ b/source/blender/bmesh/operators/bmo_join_triangles.c @@ -220,14 +220,15 @@ void bmo_join_triangles_exec(BMesh *bm, BMOperator *op) /* flag all edges of all input face */ BMO_ITER (f, &siter, op->slots_in, "faces", BM_FACE) { - BMO_elem_flag_enable(bm, f, FACE_INPUT); + if (f->len == 3) { + BMO_elem_flag_enable(bm, f, FACE_INPUT); + } } /* flag edges surrounded by 2 flagged triangles */ BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) { BMFace *f_a, *f_b; if (BM_edge_face_pair(e, &f_a, &f_b) && - (f_a->len == 3 && f_b->len == 3) && (BMO_elem_flag_test(bm, f_a, FACE_INPUT) && BMO_elem_flag_test(bm, f_b, FACE_INPUT))) { BMO_elem_flag_enable(bm, e, EDGE_MARK); @@ -307,9 +308,11 @@ void bmo_join_triangles_exec(BMesh *bm, BMOperator *op) continue; BM_edge_face_pair(e, &f_a, &f_b); /* checked above */ - f_new = BM_faces_join_pair(bm, f_a, f_b, e, true); - if (f_new) { - BMO_elem_flag_enable(bm, f_new, FACE_OUT); + if ((f_a->len == 3 && f_b->len == 3)) { + f_new = BM_faces_join_pair(bm, f_a, f_b, e, true); + if (f_new) { + BMO_elem_flag_enable(bm, f_new, FACE_OUT); + } } } From ab777e957cb8e8bde925af9dc6f960e4f045fa7a Mon Sep 17 00:00:00 2001 From: Gaia Clary Date: Fri, 2 Aug 2013 15:58:11 +0000 Subject: [PATCH 13/25] fix(Collada): wrong usage of the set attribute with multiple UV sets --- source/blender/collada/MeshImporter.cpp | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/source/blender/collada/MeshImporter.cpp b/source/blender/collada/MeshImporter.cpp index 1e0f0244072..8aa68ed9d04 100644 --- a/source/blender/collada/MeshImporter.cpp +++ b/source/blender/collada/MeshImporter.cpp @@ -618,13 +618,10 @@ void MeshImporter::read_polys(COLLADAFW::Mesh *collada_mesh, Mesh *me) set_poly_indices(mpoly, mloop, loop_index, position_indices, vcount); - for (unsigned int l = 0; l < index_list_array.getCount(); l++) { - int uvset_index = index_list_array[l]->getSetIndex(); - + for (unsigned int uvset_index = 0; uvset_index < index_list_array.getCount(); uvset_index++) { // get mtface by face index and uv set index MLoopUV *mloopuv = (MLoopUV *)CustomData_get_layer_n(&me->ldata, CD_MLOOPUV, uvset_index); - - set_face_uv(mloopuv+loop_index, uvs, start_index, *index_list_array[l], vcount); + set_face_uv(mloopuv+loop_index, uvs, start_index, *index_list_array[uvset_index], vcount); } if (mp_has_normals) { From 9f1670cde6379b81627ce172c738aa95e62d699b Mon Sep 17 00:00:00 2001 From: Miika Hamalainen Date: Fri, 2 Aug 2013 16:39:50 +0000 Subject: [PATCH 14/25] Fix [#35541]: Point cache doesn't load existing frames from disk if cache file name is changed. --- source/blender/blenkernel/intern/pointcache.c | 5 +++++ source/blender/makesrna/intern/rna_object_force.c | 1 + 2 files changed, 6 insertions(+) diff --git a/source/blender/blenkernel/intern/pointcache.c b/source/blender/blenkernel/intern/pointcache.c index 41b9734315d..93f6965e97b 100644 --- a/source/blender/blenkernel/intern/pointcache.c +++ b/source/blender/blenkernel/intern/pointcache.c @@ -3578,6 +3578,11 @@ void BKE_ptcache_load_external(PTCacheID *pid) cache->flag &= ~(PTCACHE_OUTDATED|PTCACHE_FRAMES_SKIPPED); } + /* make sure all new frames are loaded */ + if (cache->cached_frames) { + MEM_freeN(cache->cached_frames); + cache->cached_frames=NULL; + } BKE_ptcache_update_info(pid); } diff --git a/source/blender/makesrna/intern/rna_object_force.c b/source/blender/makesrna/intern/rna_object_force.c index 06d8f4faf04..1d2aa08e7cd 100644 --- a/source/blender/makesrna/intern/rna_object_force.c +++ b/source/blender/makesrna/intern/rna_object_force.c @@ -184,6 +184,7 @@ static void rna_Cache_idname_change(Main *UNUSED(bmain), Scene *UNUSED(scene), P BKE_ptcache_load_external(pid); DAG_id_tag_update(&ob->id, OB_RECALC_DATA); + WM_main_add_notifier(NC_OBJECT | ND_POINTCACHE, ob); } else { for (pid = pidlist.first; pid; pid = pid->next) { From b5016e34ed570a3d99c47f37783a163daecf5178 Mon Sep 17 00:00:00 2001 From: Mitchell Stokes Date: Fri, 2 Aug 2013 22:23:42 +0000 Subject: [PATCH 15/25] BGE: Fixing a memory leak with PyType_Ready_ADD. --- .../gameengine/Ketsji/KX_PythonInitTypes.cpp | 201 +++++++++++------- 1 file changed, 119 insertions(+), 82 deletions(-) diff --git a/source/gameengine/Ketsji/KX_PythonInitTypes.cpp b/source/gameengine/Ketsji/KX_PythonInitTypes.cpp index 05bdb3463a6..aeded04e4a7 100644 --- a/source/gameengine/Ketsji/KX_PythonInitTypes.cpp +++ b/source/gameengine/Ketsji/KX_PythonInitTypes.cpp @@ -99,6 +99,12 @@ #include "SCA_IController.h" #include "KX_NavMeshObject.h" +typedef vector GetSetList; + +struct PyTypes_state { + GetSetList *getsets; +}; + static void PyType_Attr_Set(PyGetSetDef *attr_getset, PyAttributeDef *attr) { attr_getset->name= (char *)attr->m_name; @@ -114,9 +120,11 @@ static void PyType_Attr_Set(PyGetSetDef *attr_getset, PyAttributeDef *attr) attr_getset->closure= reinterpret_cast(attr); } -static void PyType_Ready_ADD(PyObject *dict, PyTypeObject *tp, PyAttributeDef *attributes, PyAttributeDef *attributesPtr, int init_getset) +static void PyType_Ready_ADD(PyObject *mod, PyTypeObject *tp, PyAttributeDef *attributes, PyAttributeDef *attributesPtr, int init_getset) { PyAttributeDef *attr; + PyObject *dict = PyModule_GetDict(mod); + GetSetList *getsets = reinterpret_cast(PyModule_GetState(mod))->getsets; if (init_getset) { /* we need to do this for all types before calling PyType_Ready @@ -138,7 +146,9 @@ static void PyType_Ready_ADD(PyObject *dict, PyTypeObject *tp, PyAttributeDef *a attr->m_usePtr = true; } - tp->tp_getset = attr_getset = reinterpret_cast(PyMem_Malloc((attr_tot+1) * sizeof(PyGetSetDef))); // XXX - Todo, free + tp->tp_getset = attr_getset = reinterpret_cast(PyMem_Malloc((attr_tot+1) * sizeof(PyGetSetDef))); + + getsets->push_back(attr_getset); // Save the pointer so we can free it later if (attributes) { for (attr= attributes; attr->m_name; attr++, attr_getset++) { @@ -163,6 +173,32 @@ static void PyType_Ready_ADD(PyObject *dict, PyTypeObject *tp, PyAttributeDef *a #define PyType_Ready_Attr(d, n, i) PyType_Ready_ADD(d, &n::Type, n::Attributes, NULL, i) #define PyType_Ready_AttrPtr(d, n, i) PyType_Ready_ADD(d, &n::Type, n::Attributes, n::AttributesPtr, i) +static void freePyTypes(void *ptr) +{ + PyObject *mod = reinterpret_cast(ptr); + GetSetList *getsets = reinterpret_cast(PyModule_GetState(mod))->getsets; + GetSetList::iterator gsit; + + for (gsit = getsets->begin(); gsit != getsets->end(); ++gsit) { + PyMem_Free(*gsit); + } + + getsets->clear(); + delete getsets; +} + +static struct PyModuleDef typemodule = { + PyModuleDef_HEAD_INIT, + "GameTypes", + "BGE Python Types", + sizeof(PyTypes_state), + NULL, + NULL, + NULL, + NULL, + freePyTypes +}; + void initPyTypes(void) { @@ -172,90 +208,91 @@ void initPyTypes(void) */ /* For now just do PyType_Ready */ - PyObject *mod = PyModule_New("GameTypes"); - PyObject *dict = PyModule_GetDict(mod); + PyObject *mod = PyModule_Create(&typemodule); + PyTypes_state *state = reinterpret_cast(PyModule_GetState(mod)); + state->getsets = new GetSetList(); + PyDict_SetItemString(PySys_GetObject("modules"), "GameTypes", mod); Py_DECREF(mod); - for (int init_getset= 1; init_getset > -1; init_getset--) { /* run twice, once to init the getsets another to run PyType_Ready */ - PyType_Ready_Attr(dict, BL_ActionActuator, init_getset); - PyType_Ready_Attr(dict, BL_Shader, init_getset); - PyType_Ready_Attr(dict, BL_ShapeActionActuator, init_getset); - PyType_Ready_Attr(dict, BL_ArmatureObject, init_getset); - PyType_Ready_Attr(dict, BL_ArmatureActuator, init_getset); - PyType_Ready_Attr(dict, BL_ArmatureConstraint, init_getset); - PyType_Ready_AttrPtr(dict, BL_ArmatureBone, init_getset); - PyType_Ready_AttrPtr(dict, BL_ArmatureChannel, init_getset); - // PyType_Ready_Attr(dict, CPropValue, init_getset); // doesn't use Py_Header - PyType_Ready_Attr(dict, CListValue, init_getset); - PyType_Ready_Attr(dict, CValue, init_getset); - PyType_Ready_Attr(dict, KX_ArmatureSensor, init_getset); - PyType_Ready_Attr(dict, KX_BlenderMaterial, init_getset); - PyType_Ready_Attr(dict, KX_Camera, init_getset); - PyType_Ready_Attr(dict, KX_CameraActuator, init_getset); - PyType_Ready_Attr(dict, KX_CharacterWrapper, init_getset); - PyType_Ready_Attr(dict, KX_ConstraintActuator, init_getset); - PyType_Ready_Attr(dict, KX_ConstraintWrapper, init_getset); - PyType_Ready_Attr(dict, KX_GameActuator, init_getset); - PyType_Ready_Attr(dict, KX_GameObject, init_getset); - PyType_Ready_Attr(dict, KX_IpoActuator, init_getset); - PyType_Ready_Attr(dict, KX_LibLoadStatus, init_getset); - PyType_Ready_Attr(dict, KX_LightObject, init_getset); - PyType_Ready_Attr(dict, KX_FontObject, init_getset); - PyType_Ready_Attr(dict, KX_MeshProxy, init_getset); - PyType_Ready_Attr(dict, KX_MouseFocusSensor, init_getset); - PyType_Ready_Attr(dict, KX_NearSensor, init_getset); - PyType_Ready_Attr(dict, KX_NetworkMessageActuator, init_getset); - PyType_Ready_Attr(dict, KX_NetworkMessageSensor, init_getset); - PyType_Ready_Attr(dict, KX_ObjectActuator, init_getset); - PyType_Ready_Attr(dict, KX_ParentActuator, init_getset); - PyType_Ready_Attr(dict, KX_PolyProxy, init_getset); - PyType_Ready_Attr(dict, KX_PolygonMaterial, init_getset); - PyType_Ready_Attr(dict, KX_RadarSensor, init_getset); - PyType_Ready_Attr(dict, KX_RaySensor, init_getset); - PyType_Ready_Attr(dict, KX_SCA_AddObjectActuator, init_getset); - PyType_Ready_Attr(dict, KX_SCA_DynamicActuator, init_getset); - PyType_Ready_Attr(dict, KX_SCA_EndObjectActuator, init_getset); - PyType_Ready_Attr(dict, KX_SCA_ReplaceMeshActuator, init_getset); - PyType_Ready_Attr(dict, KX_Scene, init_getset); - PyType_Ready_Attr(dict, KX_NavMeshObject, init_getset); - PyType_Ready_Attr(dict, KX_SceneActuator, init_getset); - PyType_Ready_Attr(dict, KX_SoundActuator, init_getset); - PyType_Ready_Attr(dict, KX_StateActuator, init_getset); - PyType_Ready_Attr(dict, KX_SteeringActuator, init_getset); - PyType_Ready_Attr(dict, KX_TouchSensor, init_getset); - PyType_Ready_Attr(dict, KX_TrackToActuator, init_getset); - PyType_Ready_Attr(dict, KX_VehicleWrapper, init_getset); - PyType_Ready_Attr(dict, KX_VertexProxy, init_getset); - PyType_Ready_Attr(dict, KX_VisibilityActuator, init_getset); - PyType_Ready_Attr(dict, PyObjectPlus, init_getset); - PyType_Ready_Attr(dict, SCA_2DFilterActuator, init_getset); - PyType_Ready_Attr(dict, SCA_ANDController, init_getset); - // PyType_Ready_Attr(dict, SCA_Actuator, init_getset); // doesn't use Py_Header - PyType_Ready_Attr(dict, SCA_ActuatorSensor, init_getset); - PyType_Ready_Attr(dict, SCA_AlwaysSensor, init_getset); - PyType_Ready_Attr(dict, SCA_DelaySensor, init_getset); - PyType_Ready_Attr(dict, SCA_ILogicBrick, init_getset); - PyType_Ready_Attr(dict, SCA_IObject, init_getset); - PyType_Ready_Attr(dict, SCA_ISensor, init_getset); - PyType_Ready_Attr(dict, SCA_JoystickSensor, init_getset); - PyType_Ready_Attr(dict, SCA_KeyboardSensor, init_getset); - PyType_Ready_Attr(dict, SCA_MouseSensor, init_getset); - PyType_Ready_Attr(dict, SCA_NANDController, init_getset); - PyType_Ready_Attr(dict, SCA_NORController, init_getset); - PyType_Ready_Attr(dict, SCA_ORController, init_getset); - PyType_Ready_Attr(dict, SCA_PropertyActuator, init_getset); - PyType_Ready_Attr(dict, SCA_PropertySensor, init_getset); - PyType_Ready_Attr(dict, SCA_PythonController, init_getset); - PyType_Ready_Attr(dict, SCA_RandomActuator, init_getset); - PyType_Ready_Attr(dict, SCA_RandomSensor, init_getset); - PyType_Ready_Attr(dict, SCA_XNORController, init_getset); - PyType_Ready_Attr(dict, SCA_XORController, init_getset); - PyType_Ready_Attr(dict, SCA_IController, init_getset); - PyType_Ready_Attr(dict, SCA_PythonJoystick, init_getset); - PyType_Ready_Attr(dict, SCA_PythonKeyboard, init_getset); - PyType_Ready_Attr(dict, SCA_PythonMouse, init_getset); + PyType_Ready_Attr(mod, BL_ActionActuator, init_getset); + PyType_Ready_Attr(mod, BL_Shader, init_getset); + PyType_Ready_Attr(mod, BL_ShapeActionActuator, init_getset); + PyType_Ready_Attr(mod, BL_ArmatureObject, init_getset); + PyType_Ready_Attr(mod, BL_ArmatureActuator, init_getset); + PyType_Ready_Attr(mod, BL_ArmatureConstraint, init_getset); + PyType_Ready_AttrPtr(mod, BL_ArmatureBone, init_getset); + PyType_Ready_AttrPtr(mod, BL_ArmatureChannel, init_getset); + // PyType_Ready_Attr(mod, CPropValue, init_getset); // doesn't use Py_Header + PyType_Ready_Attr(mod, CListValue, init_getset); + PyType_Ready_Attr(mod, CValue, init_getset); + PyType_Ready_Attr(mod, KX_ArmatureSensor, init_getset); + PyType_Ready_Attr(mod, KX_BlenderMaterial, init_getset); + PyType_Ready_Attr(mod, KX_Camera, init_getset); + PyType_Ready_Attr(mod, KX_CameraActuator, init_getset); + PyType_Ready_Attr(mod, KX_CharacterWrapper, init_getset); + PyType_Ready_Attr(mod, KX_ConstraintActuator, init_getset); + PyType_Ready_Attr(mod, KX_ConstraintWrapper, init_getset); + PyType_Ready_Attr(mod, KX_GameActuator, init_getset); + PyType_Ready_Attr(mod, KX_GameObject, init_getset); + PyType_Ready_Attr(mod, KX_IpoActuator, init_getset); + PyType_Ready_Attr(mod, KX_LibLoadStatus, init_getset); + PyType_Ready_Attr(mod, KX_LightObject, init_getset); + PyType_Ready_Attr(mod, KX_FontObject, init_getset); + PyType_Ready_Attr(mod, KX_MeshProxy, init_getset); + PyType_Ready_Attr(mod, KX_MouseFocusSensor, init_getset); + PyType_Ready_Attr(mod, KX_NearSensor, init_getset); + PyType_Ready_Attr(mod, KX_NetworkMessageActuator, init_getset); + PyType_Ready_Attr(mod, KX_NetworkMessageSensor, init_getset); + PyType_Ready_Attr(mod, KX_ObjectActuator, init_getset); + PyType_Ready_Attr(mod, KX_ParentActuator, init_getset); + PyType_Ready_Attr(mod, KX_PolyProxy, init_getset); + PyType_Ready_Attr(mod, KX_PolygonMaterial, init_getset); + PyType_Ready_Attr(mod, KX_RadarSensor, init_getset); + PyType_Ready_Attr(mod, KX_RaySensor, init_getset); + PyType_Ready_Attr(mod, KX_SCA_AddObjectActuator, init_getset); + PyType_Ready_Attr(mod, KX_SCA_DynamicActuator, init_getset); + PyType_Ready_Attr(mod, KX_SCA_EndObjectActuator, init_getset); + PyType_Ready_Attr(mod, KX_SCA_ReplaceMeshActuator, init_getset); + PyType_Ready_Attr(mod, KX_Scene, init_getset); + PyType_Ready_Attr(mod, KX_NavMeshObject, init_getset); + PyType_Ready_Attr(mod, KX_SceneActuator, init_getset); + PyType_Ready_Attr(mod, KX_SoundActuator, init_getset); + PyType_Ready_Attr(mod, KX_StateActuator, init_getset); + PyType_Ready_Attr(mod, KX_SteeringActuator, init_getset); + PyType_Ready_Attr(mod, KX_TouchSensor, init_getset); + PyType_Ready_Attr(mod, KX_TrackToActuator, init_getset); + PyType_Ready_Attr(mod, KX_VehicleWrapper, init_getset); + PyType_Ready_Attr(mod, KX_VertexProxy, init_getset); + PyType_Ready_Attr(mod, KX_VisibilityActuator, init_getset); + PyType_Ready_Attr(mod, PyObjectPlus, init_getset); + PyType_Ready_Attr(mod, SCA_2DFilterActuator, init_getset); + PyType_Ready_Attr(mod, SCA_ANDController, init_getset); + // PyType_Ready_Attr(mod, SCA_Actuator, init_getset); // doesn't use Py_Header + PyType_Ready_Attr(mod, SCA_ActuatorSensor, init_getset); + PyType_Ready_Attr(mod, SCA_AlwaysSensor, init_getset); + PyType_Ready_Attr(mod, SCA_DelaySensor, init_getset); + PyType_Ready_Attr(mod, SCA_ILogicBrick, init_getset); + PyType_Ready_Attr(mod, SCA_IObject, init_getset); + PyType_Ready_Attr(mod, SCA_ISensor, init_getset); + PyType_Ready_Attr(mod, SCA_JoystickSensor, init_getset); + PyType_Ready_Attr(mod, SCA_KeyboardSensor, init_getset); + PyType_Ready_Attr(mod, SCA_MouseSensor, init_getset); + PyType_Ready_Attr(mod, SCA_NANDController, init_getset); + PyType_Ready_Attr(mod, SCA_NORController, init_getset); + PyType_Ready_Attr(mod, SCA_ORController, init_getset); + PyType_Ready_Attr(mod, SCA_PropertyActuator, init_getset); + PyType_Ready_Attr(mod, SCA_PropertySensor, init_getset); + PyType_Ready_Attr(mod, SCA_PythonController, init_getset); + PyType_Ready_Attr(mod, SCA_RandomActuator, init_getset); + PyType_Ready_Attr(mod, SCA_RandomSensor, init_getset); + PyType_Ready_Attr(mod, SCA_XNORController, init_getset); + PyType_Ready_Attr(mod, SCA_XORController, init_getset); + PyType_Ready_Attr(mod, SCA_IController, init_getset); + PyType_Ready_Attr(mod, SCA_PythonJoystick, init_getset); + PyType_Ready_Attr(mod, SCA_PythonKeyboard, init_getset); + PyType_Ready_Attr(mod, SCA_PythonMouse, init_getset); } From 5a042eb73438a60ccf2f62c6d57f5a97aff5760b Mon Sep 17 00:00:00 2001 From: Mitchell Stokes Date: Sat, 3 Aug 2013 05:01:23 +0000 Subject: [PATCH 16/25] BGE: Removing some unreachable and unused code in BL_ActionManager.cpp. --- source/gameengine/Ketsji/BL_ActionManager.cpp | 6 ------ 1 file changed, 6 deletions(-) diff --git a/source/gameengine/Ketsji/BL_ActionManager.cpp b/source/gameengine/Ketsji/BL_ActionManager.cpp index f3620a7b4ba..e3402972ca6 100644 --- a/source/gameengine/Ketsji/BL_ActionManager.cpp +++ b/source/gameengine/Ketsji/BL_ActionManager.cpp @@ -41,8 +41,6 @@ BL_ActionManager::~BL_ActionManager() float BL_ActionManager::GetActionFrame(short layer) { return m_layers[layer]->GetFrame(); - - return 0.f; } void BL_ActionManager::SetActionFrame(short layer, float frame) @@ -53,8 +51,6 @@ void BL_ActionManager::SetActionFrame(short layer, float frame) struct bAction *BL_ActionManager::GetCurrentAction(short layer) { return m_layers[layer]->GetAction(); - - return 0; } void BL_ActionManager::SetPlayMode(short layer, short mode) @@ -92,8 +88,6 @@ void BL_ActionManager::StopAction(short layer) bool BL_ActionManager::IsActionDone(short layer) { return m_layers[layer]->IsDone(); - - return true; } void BL_ActionManager::Update(float curtime) From 375309f7a92128fb64556a8b15d5cf115a25cc0a Mon Sep 17 00:00:00 2001 From: Mitchell Stokes Date: Sat, 3 Aug 2013 05:01:32 +0000 Subject: [PATCH 17/25] BGE: Making sure m_mirrorHalfWidth and m_mirrorHalfHeight are initialized in the ImageRender constructor. --- source/gameengine/VideoTexture/ImageRender.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/source/gameengine/VideoTexture/ImageRender.cpp b/source/gameengine/VideoTexture/ImageRender.cpp index f184ab9bd1d..d83cd2dc6fd 100644 --- a/source/gameengine/VideoTexture/ImageRender.cpp +++ b/source/gameengine/VideoTexture/ImageRender.cpp @@ -70,7 +70,9 @@ ImageRender::ImageRender (KX_Scene *scene, KX_Camera * camera) : m_owncamera(false), m_observer(NULL), m_mirror(NULL), - m_clip(100.f) + m_clip(100.f), + m_mirrorHalfWidth(0.f), + m_mirrorHalfHeight(0.f) { // initialize background color setBackground(0, 0, 255, 255); From c90a170d57c78f9206cb2788cd1b207f929f06cf Mon Sep 17 00:00:00 2001 From: Mitchell Stokes Date: Sat, 3 Aug 2013 05:01:36 +0000 Subject: [PATCH 18/25] BGE: Making sure m_offset is initialized in the ImageSourceMix constructor. --- source/gameengine/VideoTexture/ImageMix.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/gameengine/VideoTexture/ImageMix.h b/source/gameengine/VideoTexture/ImageMix.h index e55b95834fa..161a8b375ea 100644 --- a/source/gameengine/VideoTexture/ImageMix.h +++ b/source/gameengine/VideoTexture/ImageMix.h @@ -43,7 +43,7 @@ class ImageSourceMix : public ImageSource { public: /// constructor - ImageSourceMix (const char *id) : ImageSource(id), m_weight(0x100) {} + ImageSourceMix (const char *id) : ImageSource(id), m_offset(0), m_weight(0x100) {} /// destructor virtual ~ImageSourceMix (void) {} From ad65bc331572ddcd4426693f0554c37b1a2b274c Mon Sep 17 00:00:00 2001 From: Mitchell Stokes Date: Sat, 3 Aug 2013 05:01:40 +0000 Subject: [PATCH 19/25] BGE: Making sure m_buffV, m_buffU, and m_pitchUV are initialized in the FilterYV12 constructor. --- source/gameengine/VideoTexture/FilterSource.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/gameengine/VideoTexture/FilterSource.h b/source/gameengine/VideoTexture/FilterSource.h index 0289c88f056..bc80b2b36cc 100644 --- a/source/gameengine/VideoTexture/FilterSource.h +++ b/source/gameengine/VideoTexture/FilterSource.h @@ -164,7 +164,7 @@ class FilterYV12 : public FilterBase { public: /// constructor - FilterYV12 (void) {} + FilterYV12 (void): m_buffV(NULL), m_buffU(NULL), m_pitchUV(0) {} /// destructor virtual ~FilterYV12 (void) {} From e4d396f30004bfd7f165427a344accf962fa9501 Mon Sep 17 00:00:00 2001 From: Mitchell Stokes Date: Sat, 3 Aug 2013 05:01:45 +0000 Subject: [PATCH 20/25] BGE: Making sure m_line is initialized in the Exception (VideoTexture) constructor. --- source/gameengine/VideoTexture/Exception.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/source/gameengine/VideoTexture/Exception.cpp b/source/gameengine/VideoTexture/Exception.cpp index 0f571550205..804834af4cd 100644 --- a/source/gameengine/VideoTexture/Exception.cpp +++ b/source/gameengine/VideoTexture/Exception.cpp @@ -111,6 +111,8 @@ Exception::Exception (ExceptionID & expID, RESULT rslt, const char *fil, int lin // set file and line if (fil[0] != '\0' || lin > 0) setFileLine (fil, lin); + else + m_line = -1; } From e8ca7abb9a45a5f9ab88865de0c2b87b9705eeb9 Mon Sep 17 00:00:00 2001 From: Mitchell Stokes Date: Sat, 3 Aug 2013 05:01:50 +0000 Subject: [PATCH 21/25] BGE: Making sure m_objType is initialized in the BlendType (VideoTexture) constructor. --- source/gameengine/VideoTexture/BlendType.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/gameengine/VideoTexture/BlendType.h b/source/gameengine/VideoTexture/BlendType.h index 28eebe07789..561c6e8768f 100644 --- a/source/gameengine/VideoTexture/BlendType.h +++ b/source/gameengine/VideoTexture/BlendType.h @@ -38,7 +38,7 @@ template class BlendType { public: /// constructor - BlendType (const char * name) : m_name(name) {} + BlendType (const char * name) : m_name(name), m_objType(NULL) {} /// check blender type and return pointer to contained object or NULL (if type is not valid) PyObj *checkType(PyObject *obj) From 411a49445f7184f5aebb3d845fc223285cf0552b Mon Sep 17 00:00:00 2001 From: Mitchell Stokes Date: Sat, 3 Aug 2013 05:01:57 +0000 Subject: [PATCH 22/25] BGE: Making sure m_left, m_right, m_parent, m_radius, and m_client_object are initialized in the SG_Tree constructors. --- source/gameengine/SceneGraph/SG_Tree.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/source/gameengine/SceneGraph/SG_Tree.cpp b/source/gameengine/SceneGraph/SG_Tree.cpp index 99f68ef625a..bef246533a6 100644 --- a/source/gameengine/SceneGraph/SG_Tree.cpp +++ b/source/gameengine/SceneGraph/SG_Tree.cpp @@ -37,13 +37,19 @@ #include "SG_Tree.h" #include "SG_Node.h" -SG_Tree::SG_Tree() +SG_Tree::SG_Tree() : + m_left(NULL), + m_right(NULL), + m_parent(NULL), + m_radius(0.0), + m_client_object(NULL) { } SG_Tree::SG_Tree(SG_Tree* left, SG_Tree* right) : m_left(left), m_right(right), + m_parent(NULL), m_client_object(NULL) { if (m_left) @@ -63,6 +69,7 @@ SG_Tree::SG_Tree(SG_Tree* left, SG_Tree* right) : SG_Tree::SG_Tree(SG_Node* client) : m_left(NULL), m_right(NULL), + m_parent(NULL), m_client_object(client) { m_bbox = SG_BBox(client->BBox(), client->GetWorldTransform()); From e131447582a35fe4102f63b7d387d7cd57aa42b7 Mon Sep 17 00:00:00 2001 From: Mitchell Stokes Date: Sat, 3 Aug 2013 05:02:03 +0000 Subject: [PATCH 23/25] BGE: Making sure m_drawingmode is initialized in the various RAS_Storage constructors. --- .../gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageIM.cpp | 1 + .../gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageVA.cpp | 1 + .../Rasterizer/RAS_OpenGLRasterizer/RAS_StorageVBO.cpp | 1 + 3 files changed, 3 insertions(+) diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageIM.cpp b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageIM.cpp index 900d6f387ff..77bd540a039 100644 --- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageIM.cpp +++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageIM.cpp @@ -40,6 +40,7 @@ extern "C"{ } RAS_StorageIM::RAS_StorageIM(int *texco_num, RAS_IRasterizer::TexCoGen *texco, int *attrib_num, RAS_IRasterizer::TexCoGen *attrib, int *attrib_layer) : + m_drawingmode(RAS_IRasterizer::KX_TEXTURED), m_texco_num(texco_num), m_attrib_num(attrib_num), m_texco(texco), diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageVA.cpp b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageVA.cpp index 72af3852cf6..006c07b0491 100644 --- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageVA.cpp +++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageVA.cpp @@ -30,6 +30,7 @@ #include "GL/glew.h" RAS_StorageVA::RAS_StorageVA(int *texco_num, RAS_IRasterizer::TexCoGen *texco, int *attrib_num, RAS_IRasterizer::TexCoGen *attrib, int *attrib_layer) : + m_drawingmode(RAS_IRasterizer::KX_TEXTURED), m_texco_num(texco_num), m_attrib_num(attrib_num), m_last_texco_num(0), diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageVBO.cpp b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageVBO.cpp index c7779c209ba..06f85b143d2 100644 --- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageVBO.cpp +++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageVBO.cpp @@ -182,6 +182,7 @@ void VBO::Draw(int texco_num, RAS_IRasterizer::TexCoGen* texco, int attrib_num, } RAS_StorageVBO::RAS_StorageVBO(int *texco_num, RAS_IRasterizer::TexCoGen *texco, int *attrib_num, RAS_IRasterizer::TexCoGen *attrib, int *attrib_layer): + m_drawingmode(RAS_IRasterizer::KX_TEXTURED), m_texco_num(texco_num), m_attrib_num(attrib_num), m_texco(texco), From 91d148b8914bb198a78c3789fa39c2850d37d219 Mon Sep 17 00:00:00 2001 From: Miika Hamalainen Date: Sat, 3 Aug 2013 09:46:38 +0000 Subject: [PATCH 24/25] Dynamic Paint: Added a new "smoothness" parameter for waves. It greatly helps getting rid of that "noise" that occurs if you use really steep objects (like cubes) as a brush. New default value is 1.0 which is just high enough to only get rid of the sharpest spikes, so if you want really smooth waves it's better use higher values. This also seems to "fix" bug [#35413]. --- .../bl_ui/properties_physics_dynamicpaint.py | 1 + .../blender/blenkernel/intern/dynamicpaint.c | 20 +++++++++++++++---- .../blender/makesdna/DNA_dynamicpaint_types.h | 3 ++- .../makesrna/intern/rna_dynamicpaint.c | 5 +++++ 4 files changed, 24 insertions(+), 5 deletions(-) diff --git a/release/scripts/startup/bl_ui/properties_physics_dynamicpaint.py b/release/scripts/startup/bl_ui/properties_physics_dynamicpaint.py index 7ee63ee7a2f..75c4caa57bd 100644 --- a/release/scripts/startup/bl_ui/properties_physics_dynamicpaint.py +++ b/release/scripts/startup/bl_ui/properties_physics_dynamicpaint.py @@ -201,6 +201,7 @@ class PHYSICS_PT_dp_advanced_canvas(PhysicButtonsPanel, Panel): col = split.column(align=True) col.prop(surface, "wave_damping") col.prop(surface, "wave_spring") + col.prop(surface, "wave_smoothness") layout.separator() layout.prop(surface, "brush_group") diff --git a/source/blender/blenkernel/intern/dynamicpaint.c b/source/blender/blenkernel/intern/dynamicpaint.c index 1d5eaf3a1fc..dcbbd776228 100644 --- a/source/blender/blenkernel/intern/dynamicpaint.c +++ b/source/blender/blenkernel/intern/dynamicpaint.c @@ -1078,6 +1078,7 @@ DynamicPaintSurface *dynamicPaint_createNewSurface(DynamicPaintCanvasSettings *c surface->wave_speed = 1.0f; surface->wave_timescale = 1.0f; surface->wave_spring = 0.20f; + surface->wave_smoothness = 1.0f; modifier_path_init(surface->image_output_path, sizeof(surface->image_output_path), "cache_dynamicpaint"); @@ -1253,6 +1254,7 @@ void dynamicPaint_Modifier_copy(struct DynamicPaintModifierData *pmd, struct Dyn t_surface->wave_speed = surface->wave_speed; t_surface->wave_timescale = surface->wave_timescale; t_surface->wave_spring = surface->wave_spring; + t_surface->wave_smoothness = surface->wave_smoothness; BLI_strncpy(t_surface->uvlayer_name, surface->uvlayer_name, sizeof(t_surface->uvlayer_name)); BLI_strncpy(t_surface->image_output_path, surface->image_output_path, sizeof(t_surface->image_output_path)); @@ -4465,6 +4467,7 @@ static void dynamicPaint_doWaveStep(DynamicPaintSurface *surface, float timescal int steps, ss; float dt, min_dist, damp_factor; float wave_speed = surface->wave_speed; + float wave_max_slope = (surface->wave_smoothness >= 0.01f) ? (0.5f / surface->wave_smoothness) : 0.0f; double average_dist = 0.0f; const float canvas_size = getSurfaceDimension(sData); float wave_scale = CANVAS_REL_SIZE / canvas_size; @@ -4503,7 +4506,7 @@ static void dynamicPaint_doWaveStep(DynamicPaintSurface *surface, float timescal for (index = 0; index < sData->total_points; index++) { PaintWavePoint *wPoint = &((PaintWavePoint *)sData->type_data)[index]; int numOfNeighs = sData->adj_data->n_num[index]; - float force = 0.0f, avg_dist = 0.0f, avg_height = 0.0f; + float force = 0.0f, avg_dist = 0.0f, avg_height = 0.0f, avg_n_height = 0.0f; int numOfN = 0, numOfRN = 0; int i; @@ -4522,11 +4525,12 @@ static void dynamicPaint_doWaveStep(DynamicPaintSurface *surface, float timescal /* count average height for edge points for open borders */ if (!(sData->adj_data->flags[sData->adj_data->n_target[n_index]] & ADJ_ON_MESH_EDGE)) { - avg_height += tPoint->height; + avg_n_height += tPoint->height; numOfRN++; } force += (tPoint->height - wPoint->height) / (dist * dist); + avg_height += tPoint->height; } avg_dist = (numOfN) ? avg_dist / numOfN : 0.0f; @@ -4534,8 +4538,8 @@ static void dynamicPaint_doWaveStep(DynamicPaintSurface *surface, float timescal sData->adj_data->flags[index] & ADJ_ON_MESH_EDGE) { /* if open borders, apply a fake height to keep waves going on */ - avg_height = (numOfRN) ? avg_height / numOfRN : 0.0f; - wPoint->height = (dt * wave_speed * avg_height + wPoint->height * avg_dist) / (avg_dist + dt * wave_speed); + avg_n_height = (numOfRN) ? avg_n_height / numOfRN : 0.0f; + wPoint->height = (dt * wave_speed * avg_n_height + wPoint->height * avg_dist) / (avg_dist + dt * wave_speed); } /* else do wave eq */ else { @@ -4549,6 +4553,14 @@ static void dynamicPaint_doWaveStep(DynamicPaintSurface *surface, float timescal wPoint->velocity *= damp_factor; /* and new height */ wPoint->height += wPoint->velocity * dt; + + /* limit wave slope steepness */ + if (wave_max_slope && avg_dist) { + float max_offset = wave_max_slope * avg_dist; + float offset = (numOfN) ? (avg_height / numOfN - wPoint->height) : 0.0f; + if (offset > max_offset) wPoint->height += offset - max_offset; + if (offset < -max_offset) wPoint->height += offset + max_offset; + } } } } diff --git a/source/blender/makesdna/DNA_dynamicpaint_types.h b/source/blender/makesdna/DNA_dynamicpaint_types.h index 1f2a589dc27..d2b95c959b3 100644 --- a/source/blender/makesdna/DNA_dynamicpaint_types.h +++ b/source/blender/makesdna/DNA_dynamicpaint_types.h @@ -125,7 +125,8 @@ typedef struct DynamicPaintSurface { float influence_scale, radius_scale; /* wave settings */ - float wave_damping, wave_speed, wave_timescale, wave_spring; + float wave_damping, wave_speed, wave_timescale, wave_spring, wave_smoothness; + int pad2; char uvlayer_name[64]; /* MAX_CUSTOMDATA_LAYER_NAME */ char image_output_path[1024]; /* 1024 = FILE_MAX */ diff --git a/source/blender/makesrna/intern/rna_dynamicpaint.c b/source/blender/makesrna/intern/rna_dynamicpaint.c index fb16dd0c5a1..ff6b5a400b8 100644 --- a/source/blender/makesrna/intern/rna_dynamicpaint.c +++ b/source/blender/makesrna/intern/rna_dynamicpaint.c @@ -710,6 +710,11 @@ static void rna_def_canvas_surface(BlenderRNA *brna) RNA_def_property_ui_range(prop, 0.01, 1.0, 1, 2); RNA_def_property_ui_text(prop, "Spring", "Spring force that pulls water level back to zero"); + prop = RNA_def_property(srna, "wave_smoothness", PROP_FLOAT, PROP_NONE); + RNA_def_property_range(prop, 0.0, 10.0); + RNA_def_property_ui_range(prop, 0.1, 5.0, 1, 2); + RNA_def_property_ui_text(prop, "Smoothness", "Limit maximum steepness of wave slope between simulation points. Use higher values for smoother waves at expense of reduced detail"); + prop = RNA_def_property(srna, "use_wave_open_border", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flags", MOD_DPAINT_WAVE_OPEN_BORDERS); RNA_def_property_ui_text(prop, "Open Borders", "Pass waves through mesh edges"); From 66a40779271b55498216cc14b4df3ca8d575137c Mon Sep 17 00:00:00 2001 From: "Sv. Lockal" Date: Sat, 3 Aug 2013 11:35:09 +0000 Subject: [PATCH 25/25] fix for [#36260] 2,300 Objects Makes Blender Unresponsive MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - performance of outliner was low because of unoptimal data structures. - now it uses BLI_mempool instead of custom mempool and GHash to make searches for duplicates faster. - also fix undesired behaviour of BLI_mempool_as_arrayN thanks to Campbell Barton and Lukas Tönne for helping me get a better fix put together. --- source/blender/blenkernel/intern/object.c | 7 +- source/blender/blenlib/intern/BLI_mempool.c | 14 +- source/blender/blenloader/intern/readfile.c | 58 +++-- source/blender/blenloader/intern/writefile.c | 38 +++- .../editors/space_outliner/outliner_draw.c | 3 +- .../editors/space_outliner/outliner_edit.c | 6 +- .../editors/space_outliner/outliner_intern.h | 19 +- .../editors/space_outliner/outliner_select.c | 4 +- .../editors/space_outliner/outliner_tools.c | 5 + .../editors/space_outliner/outliner_tree.c | 200 ++++++++++-------- .../editors/space_outliner/space_outliner.c | 9 +- source/blender/makesdna/DNA_outliner_types.h | 9 +- source/blender/makesdna/DNA_space_types.h | 5 +- 13 files changed, 237 insertions(+), 140 deletions(-) diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c index 8ac067c0316..7aa23dc6c2b 100644 --- a/source/blender/blenkernel/intern/object.c +++ b/source/blender/blenkernel/intern/object.c @@ -678,9 +678,10 @@ void BKE_object_unlink(Object *ob) SpaceOops *so = (SpaceOops *)sl; if (so->treestore) { - TreeStoreElem *tselem = so->treestore->data; - int i; - for (i = 0; i < so->treestore->usedelem; i++, tselem++) { + TreeStoreElem *tselem; + BLI_mempool_iter iter; + BLI_mempool_iternew(so->treestore, &iter); + while ((tselem = BLI_mempool_iterstep(&iter))) { if (tselem->id == (ID *)ob) tselem->id = NULL; } } diff --git a/source/blender/blenlib/intern/BLI_mempool.c b/source/blender/blenlib/intern/BLI_mempool.c index 217a4b9d266..f370f32c31d 100644 --- a/source/blender/blenlib/intern/BLI_mempool.c +++ b/source/blender/blenlib/intern/BLI_mempool.c @@ -354,8 +354,18 @@ void BLI_mempool_as_array(BLI_mempool *pool, void **data) */ void *BLI_mempool_as_arrayN(BLI_mempool *pool, const char *allocstr) { - void *data = MEM_mallocN((size_t)(BLI_mempool_count(pool) * pool->esize), allocstr); - BLI_mempool_as_array(pool, data); + char *data = MEM_mallocN((size_t)(pool->totused * pool->esize), allocstr); + BLI_assert(pool->flag & BLI_MEMPOOL_ALLOW_ITER); + if (data) { + BLI_mempool_iter iter; + char *elem, *p = data; + BLI_mempool_iternew(pool, &iter); + for (elem = BLI_mempool_iterstep(&iter); elem; elem = BLI_mempool_iterstep(&iter)) { + memcpy(p, elem, (size_t)pool->esize); + p += pool->esize; + } + BLI_assert((p - data) == pool->totused * pool->esize); + } return data; } diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 0ff3392ad00..72b426a155a 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -108,6 +108,7 @@ #include "BLI_math.h" #include "BLI_edgehash.h" #include "BLI_threads.h" +#include "BLI_mempool.h" #include "BLF_translation.h" @@ -5684,16 +5685,24 @@ static void lib_link_screen(FileData *fd, Main *main) } else if (sl->spacetype == SPACE_OUTLINER) { SpaceOops *so= (SpaceOops *)sl; - TreeStoreElem *tselem; - int a; - so->search_tse.id = newlibadr(fd, NULL, so->search_tse.id); if (so->treestore) { - tselem = so->treestore->data; - for (a=0; a < so->treestore->usedelem; a++, tselem++) { + TreeStoreElem *tselem; + BLI_mempool_iter iter; + + BLI_mempool_iternew(so->treestore, &iter); + while ((tselem = BLI_mempool_iterstep(&iter))) { tselem->id = newlibadr(fd, NULL, tselem->id); } + if (so->treehash) { + /* update hash table, because it depends on ids too */ + BLI_ghash_clear(so->treehash, NULL, NULL); + BLI_mempool_iternew(so->treestore, &iter); + while ((tselem = BLI_mempool_iterstep(&iter))) { + BLI_ghash_insert(so->treehash, tselem, tselem); + } + } } } else if (sl->spacetype == SPACE_NODE) { @@ -6016,16 +6025,25 @@ void blo_lib_link_screen_restore(Main *newmain, bScreen *curscreen, Scene *cursc } else if (sl->spacetype == SPACE_OUTLINER) { SpaceOops *so= (SpaceOops *)sl; - int a; so->search_tse.id = restore_pointer_by_name(newmain, so->search_tse.id, 0); if (so->treestore) { - TreeStore *ts = so->treestore; - TreeStoreElem *tselem = ts->data; - for (a = 0; a < ts->usedelem; a++, tselem++) { + TreeStoreElem *tselem; + BLI_mempool_iter iter; + + BLI_mempool_iternew(so->treestore, &iter); + while ((tselem = BLI_mempool_iterstep(&iter))) { tselem->id = restore_pointer_by_name(newmain, tselem->id, 0); } + if (so->treehash) { + /* update hash table, because it depends on ids too */ + BLI_ghash_clear(so->treehash, NULL, NULL); + BLI_mempool_iternew(so->treestore, &iter); + while ((tselem = BLI_mempool_iterstep(&iter))) { + BLI_ghash_insert(so->treehash, tselem, tselem); + } + } } } else if (sl->spacetype == SPACE_NODE) { @@ -6283,13 +6301,27 @@ static bool direct_link_screen(FileData *fd, bScreen *sc) else if (sl->spacetype == SPACE_OUTLINER) { SpaceOops *soops = (SpaceOops *) sl; - soops->treestore = newdataadr(fd, soops->treestore); - if (soops->treestore) { - soops->treestore->data = newdataadr(fd, soops->treestore->data); + TreeStore *ts = newdataadr(fd, soops->treestore); + soops->treestore = NULL; + if (ts) { + TreeStoreElem *elems = newdataadr(fd, ts->data); + + soops->treestore = BLI_mempool_create(sizeof(TreeStoreElem), ts->usedelem, + 512, BLI_MEMPOOL_ALLOW_ITER); + if (ts->usedelem && elems) { + int i; + for (i = 0; i < ts->usedelem; i++) { + TreeStoreElem *new_elem = BLI_mempool_alloc(soops->treestore); + *new_elem = elems[i]; + } + MEM_freeN(elems); + } /* we only saved what was used */ - soops->treestore->totelem = soops->treestore->usedelem; soops->storeflag |= SO_TREESTORE_CLEANUP; // at first draw + + MEM_freeN(ts); } + soops->treehash = NULL; soops->tree.first = soops->tree.last= NULL; } else if (sl->spacetype == SPACE_IMAGE) { diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c index e170107713c..12804e8042d 100644 --- a/source/blender/blenloader/intern/writefile.c +++ b/source/blender/blenloader/intern/writefile.c @@ -144,12 +144,13 @@ #include "BLI_bitmap.h" #include "BLI_blenlib.h" #include "BLI_linklist.h" -#include "BKE_bpath.h" #include "BLI_math.h" #include "BLI_utildefines.h" +#include "BLI_mempool.h" #include "BKE_action.h" #include "BKE_blender.h" +#include "BKE_bpath.h" #include "BKE_curve.h" #include "BKE_constraint.h" #include "BKE_global.h" // for G @@ -2393,6 +2394,31 @@ static void write_region(WriteData *wd, ARegion *ar, int spacetype) } } +static void write_soops(WriteData *wd, SpaceOops *so) +{ + BLI_mempool *ts = so->treestore; + + if (ts) { + int elems = BLI_mempool_count(ts); + /* linearize mempool to array */ + TreeStoreElem *data = elems ? BLI_mempool_as_arrayN(ts, "TreeStoreElem") : NULL; + TreeStore ts_flat = {elems, elems, data}; + + /* temporarily replace mempool-treestore by flat-treestore */ + so->treestore = (BLI_mempool *)&ts_flat; + writestruct(wd, DATA, "SpaceOops", 1, so); + /* restore old treestore */ + so->treestore = ts; + writestruct(wd, DATA, "TreeStore", 1, &ts_flat); + if (data) { + writestruct(wd, DATA, "TreeStoreElem", elems, data); + MEM_freeN(data); + } + } else { + writestruct(wd, DATA, "SpaceOops", 1, so); + } +} + static void write_screens(WriteData *wd, ListBase *scrbase) { bScreen *sc; @@ -2475,15 +2501,7 @@ static void write_screens(WriteData *wd, ListBase *scrbase) } else if (sl->spacetype==SPACE_OUTLINER) { SpaceOops *so= (SpaceOops *)sl; - - writestruct(wd, DATA, "SpaceOops", 1, so); - - /* outliner */ - if (so->treestore) { - writestruct(wd, DATA, "TreeStore", 1, so->treestore); - if (so->treestore->data) - writestruct(wd, DATA, "TreeStoreElem", so->treestore->usedelem, so->treestore->data); - } + write_soops(wd, so); } else if (sl->spacetype==SPACE_IMAGE) { SpaceImage *sima= (SpaceImage *)sl; diff --git a/source/blender/editors/space_outliner/outliner_draw.c b/source/blender/editors/space_outliner/outliner_draw.c index b308bd09026..44d5672e7da 100644 --- a/source/blender/editors/space_outliner/outliner_draw.c +++ b/source/blender/editors/space_outliner/outliner_draw.c @@ -40,6 +40,7 @@ #include "BLI_blenlib.h" #include "BLI_utildefines.h" #include "BLI_ghash.h" +#include "BLI_mempool.h" #include "BLF_translation.h" @@ -407,7 +408,7 @@ static void namebutton_cb(bContext *C, void *tsep, char *oldname) SpaceOops *soops = CTX_wm_space_outliner(C); Scene *scene = CTX_data_scene(C); Object *obedit = CTX_data_edit_object(C); - TreeStore *ts = soops->treestore; + BLI_mempool *ts = soops->treestore; TreeStoreElem *tselem = tsep; if (ts && tselem) { diff --git a/source/blender/editors/space_outliner/outliner_edit.c b/source/blender/editors/space_outliner/outliner_edit.c index cef5fe53407..a014724af4a 100644 --- a/source/blender/editors/space_outliner/outliner_edit.c +++ b/source/blender/editors/space_outliner/outliner_edit.c @@ -984,7 +984,7 @@ static int ed_operator_outliner_datablocks_active(bContext *C) * NOTE: the caller must zero-out all values of the pointers that it passes here first, as * this function does not do that yet */ -static void tree_element_to_path(SpaceOops *soops, TreeElement *te, TreeStoreElem *tselem, +static void tree_element_to_path(TreeElement *te, TreeStoreElem *tselem, ID **id, char **path, int *array_index, short *flag, short *UNUSED(groupmode)) { ListBase hierarchy = {NULL, NULL}; @@ -1152,7 +1152,7 @@ static void do_outliner_drivers_editop(SpaceOops *soops, ListBase *tree, ReportL RNA_property_animateable(&te->rnaptr, te->directdata)) { /* get id + path + index info from the selected element */ - tree_element_to_path(soops, te, tselem, + tree_element_to_path(te, tselem, &id, &path, &array_index, &flag, &groupmode); } @@ -1333,7 +1333,7 @@ static void do_outliner_keyingset_editop(SpaceOops *soops, KeyingSet *ks, ListBa RNA_property_animateable(&te->rnaptr, te->directdata)) { /* get id + path + index info from the selected element */ - tree_element_to_path(soops, te, tselem, + tree_element_to_path(te, tselem, &id, &path, &array_index, &flag, &groupmode); } diff --git a/source/blender/editors/space_outliner/outliner_intern.h b/source/blender/editors/space_outliner/outliner_intern.h index 2310ca9b4b5..5aaf8b5430b 100644 --- a/source/blender/editors/space_outliner/outliner_intern.h +++ b/source/blender/editors/space_outliner/outliner_intern.h @@ -48,15 +48,15 @@ struct Object; typedef struct TreeElement { struct TreeElement *next, *prev, *parent; ListBase subtree; - int xs, ys; // do selection - int store_index; // offset in tree store - short flag; // flag for non-saved stuff - short index; // index for data arrays - short idcode; // from TreeStore id - short xend; // width of item display, for select + int xs, ys; // do selection + TreeStoreElem *store_elem; // element in tree store + short flag; // flag for non-saved stuff + short index; // index for data arrays + short idcode; // from TreeStore id + short xend; // width of item display, for select const char *name; - void *directdata; // Armature Bones, Base, Sequence, Strip... - PointerRNA rnaptr; // RNA Pointer + void *directdata; // Armature Bones, Base, Sequence, Strip... + PointerRNA rnaptr; // RNA Pointer } TreeElement; /* TreeElement->flag */ @@ -111,7 +111,7 @@ typedef struct TreeElement { /* get TreeStoreElem associated with a TreeElement * < a: (TreeElement) tree element to find stored element for */ -#define TREESTORE(a) (soops->treestore->data + (a)->store_index) +#define TREESTORE(a) ((a)->store_elem) /* size constants */ #define OL_Y_OFFSET 2 @@ -150,6 +150,7 @@ typedef struct TreeElement { /* outliner_tree.c ----------------------------------------------- */ +void outliner_rebuild_treehash(struct SpaceOops *soops); void outliner_free_tree(ListBase *lb); void outliner_cleanup_tree(struct SpaceOops *soops); diff --git a/source/blender/editors/space_outliner/outliner_select.c b/source/blender/editors/space_outliner/outliner_select.c index 9720d981e85..41ad75bb14f 100644 --- a/source/blender/editors/space_outliner/outliner_select.c +++ b/source/blender/editors/space_outliner/outliner_select.c @@ -282,7 +282,7 @@ static int tree_element_active_material(bContext *C, Scene *scene, SpaceOops *so return 0; } -static int tree_element_active_texture(bContext *C, Scene *scene, SpaceOops *soops, TreeElement *te, int set) +static int tree_element_active_texture(bContext *C, Scene *scene, SpaceOops *UNUSED(soops), TreeElement *te, int set) { TreeElement *tep; TreeStoreElem /* *tselem,*/ *tselemp; @@ -384,7 +384,7 @@ static int tree_element_active_camera(bContext *UNUSED(C), Scene *scene, SpaceOo return scene->camera == ob; } -static int tree_element_active_world(bContext *C, Scene *scene, SpaceOops *soops, TreeElement *te, int set) +static int tree_element_active_world(bContext *C, Scene *scene, SpaceOops *UNUSED(soops), TreeElement *te, int set) { TreeElement *tep; TreeStoreElem *tselem = NULL; diff --git a/source/blender/editors/space_outliner/outliner_tools.c b/source/blender/editors/space_outliner/outliner_tools.c index 1e4af4304f0..c1950e62817 100644 --- a/source/blender/editors/space_outliner/outliner_tools.c +++ b/source/blender/editors/space_outliner/outliner_tools.c @@ -45,6 +45,7 @@ #include "BLI_blenlib.h" #include "BLI_utildefines.h" +#include "BLI_ghash.h" #include "BKE_animsys.h" #include "BKE_context.h" @@ -298,13 +299,17 @@ static void object_delete_cb(bContext *C, Scene *scene, TreeElement *te, if (base == NULL) base = BKE_scene_base_find(scene, (Object *)tselem->id); if (base) { + SpaceOops *soops = CTX_wm_space_outliner(C); + // check also library later if (scene->obedit == base->object) ED_object_editmode_exit(C, EM_FREEDATA | EM_FREEUNDO | EM_WAITCURSOR | EM_DO_UNDO); ED_base_object_free_and_unlink(CTX_data_main(C), scene, base); te->directdata = NULL; + BLI_ghash_remove(soops->treehash, tselem, NULL, NULL); tselem->id = NULL; + BLI_ghash_insert(soops->treehash, tselem, tselem); } } diff --git a/source/blender/editors/space_outliner/outliner_tree.c b/source/blender/editors/space_outliner/outliner_tree.c index 17734f00997..2295af93166 100644 --- a/source/blender/editors/space_outliner/outliner_tree.c +++ b/source/blender/editors/space_outliner/outliner_tree.c @@ -63,6 +63,8 @@ #include "BLI_blenlib.h" #include "BLI_utildefines.h" #include "BLI_math.h" +#include "BLI_ghash.h" +#include "BLI_mempool.h" #include "BLF_translation.h" @@ -93,105 +95,127 @@ static void outliner_storage_cleanup(SpaceOops *soops) { - TreeStore *ts = soops->treestore; + BLI_mempool *ts = soops->treestore; if (ts) { TreeStoreElem *tselem; - int a, unused = 0; + int unused = 0; /* each element used once, for ID blocks with more users to have each a treestore */ - for (a = 0, tselem = ts->data; a < ts->usedelem; a++, tselem++) tselem->used = 0; + BLI_mempool_iter iter; + + BLI_mempool_iternew(ts, &iter); + while ((tselem = BLI_mempool_iterstep(&iter))) { + tselem->used = 0; + } /* cleanup only after reading file or undo step, and always for * RNA datablocks view in order to save memory */ if (soops->storeflag & SO_TREESTORE_CLEANUP) { - - for (a = 0, tselem = ts->data; a < ts->usedelem; a++, tselem++) { + BLI_mempool_iternew(ts, &iter); + while ((tselem = BLI_mempool_iterstep(&iter))) { if (tselem->id == NULL) unused++; } if (unused) { - if (ts->usedelem == unused) { - MEM_freeN(ts->data); - ts->data = NULL; - ts->usedelem = ts->totelem = 0; + if (BLI_mempool_count(ts) == unused) { + BLI_mempool_destroy(ts); + soops->treestore = NULL; + + if (soops->treehash) { + BLI_ghash_free(soops->treehash, NULL, NULL); + soops->treehash = NULL; + } } else { - TreeStoreElem *tsnewar, *tsnew; - - tsnew = tsnewar = MEM_mallocN((ts->usedelem - unused) * sizeof(TreeStoreElem), "new tselem"); - for (a = 0, tselem = ts->data; a < ts->usedelem; a++, tselem++) { + TreeStoreElem *tsenew; + BLI_mempool *new_ts = BLI_mempool_create(sizeof(TreeStoreElem), BLI_mempool_count(ts) - unused, + 512, BLI_MEMPOOL_ALLOW_ITER); + BLI_mempool_iternew(ts, &iter); + while ((tselem = BLI_mempool_iterstep(&iter))) { if (tselem->id) { - *tsnew = *tselem; - tsnew++; + tsenew = BLI_mempool_alloc(new_ts); + *tsenew = *tselem; + } + } + BLI_mempool_destroy(ts); + soops->treestore = new_ts; + + if (soops->treehash) { + /* update hash table to fix broken pointers */ + BLI_ghash_clear(soops->treehash, NULL, NULL); + BLI_mempool_iternew(soops->treestore, &iter); + while ((tselem = BLI_mempool_iterstep(&iter))) { + BLI_ghash_insert(soops->treehash, tselem, tselem); } } - MEM_freeN(ts->data); - ts->data = tsnewar; - ts->usedelem -= unused; - ts->totelem = ts->usedelem; } } } } } -/* XXX - THIS FUNCTION IS INCREDIBLY SLOW - * ... it can bring blenders tools and viewport to a grinding halt because of searching - * for duplicate items every times they are added. - * - * TODO (possible speedups) - * - use a hash for duplicate (could even store a hash per type) - * - use mempool for TreeElements - * */ +static unsigned int tse_hash(const void *ptr) +{ + const TreeStoreElem *tse = (const TreeStoreElem *)ptr; + unsigned int hash; + BLI_assert(tse->type || !tse->nr); + hash = BLI_ghashutil_inthash(SET_INT_IN_POINTER((tse->nr << 16) + tse->type)); + hash ^= BLI_ghashutil_inthash(tse->id); + return hash; +} + +static int tse_cmp(const void *a, const void *b) +{ + const TreeStoreElem *tse_a = (const TreeStoreElem *)a; + const TreeStoreElem *tse_b = (const TreeStoreElem *)b; + return tse_a->type != tse_b->type || tse_a->nr != tse_b->nr || tse_a->id != tse_b->id; +} + static void check_persistent(SpaceOops *soops, TreeElement *te, ID *id, short type, short nr) { - TreeStore *ts; - TreeStoreElem *tselem; - int a; + /* When treestore comes directly from readfile.c, treehash is empty; + * In this case we don't want to get TSE_CLOSED while adding elements one by one, + * that is why this function restores treehash */ + bool restore_treehash = (soops->treestore && !soops->treehash); + TreeStoreElem *tselem, elem_template; - /* case 1; no TreeStore */ if (soops->treestore == NULL) { - soops->treestore = MEM_callocN(sizeof(TreeStore), "treestore"); + /* if treestore was not created in readfile.c, create it here */ + soops->treestore = BLI_mempool_create(sizeof(TreeStoreElem), 1, 512, BLI_MEMPOOL_ALLOW_ITER); + } + if (soops->treehash == NULL) { + soops->treehash = BLI_ghash_new(tse_hash, tse_cmp, "treehash"); } - ts = soops->treestore; + if (restore_treehash) { + BLI_mempool_iter iter; + BLI_mempool_iternew(soops->treestore, &iter); + while ((tselem = BLI_mempool_iterstep(&iter))) { + BLI_ghash_insert(soops->treehash, tselem, tselem); + } + } + /* check if 'te' is in treestore */ - tselem = ts->data; - for (a = 0; a < ts->usedelem; a++, tselem++) { - if ((tselem->used == 0) && (tselem->type == type) && (tselem->id == id)) { - if ((type == 0) || (tselem->nr == nr)) { - te->store_index = a; - tselem->used = 1; - return; - } - } + elem_template.type = type; + elem_template.nr = type ? nr : 0; // we're picky! :) + elem_template.id = id; + tselem = BLI_ghash_lookup(soops->treehash, &elem_template); + if (tselem && !tselem->used) { + te->store_elem = tselem; + tselem->used = 1; + return; } - + /* add 1 element to treestore */ - if (ts->usedelem == ts->totelem) { - TreeStoreElem *tsnew; - - tsnew = MEM_mallocN((ts->totelem + TS_CHUNK) * sizeof(TreeStoreElem), "treestore data"); - if (ts->data) { - memcpy(tsnew, ts->data, ts->totelem * sizeof(TreeStoreElem)); - MEM_freeN(ts->data); - } - ts->data = tsnew; - ts->totelem += TS_CHUNK; - } - - tselem = ts->data + ts->usedelem; - + tselem = BLI_mempool_alloc(soops->treestore); tselem->type = type; - if (type) tselem->nr = nr; // we're picky! :) - else tselem->nr = 0; + tselem->nr = type ? nr : 0; tselem->id = id; tselem->used = 0; tselem->flag = TSE_CLOSED; - te->store_index = ts->usedelem; - - ts->usedelem++; + te->store_elem = tselem; + BLI_ghash_insert(soops->treehash, tselem, tselem); } /* ********************************************************* */ @@ -216,15 +240,14 @@ void outliner_cleanup_tree(SpaceOops *soops) outliner_storage_cleanup(soops); } -/* Find ith item from the treestore */ -static TreeElement *outliner_find_tree_element(ListBase *lb, int store_index) +/* Find specific item from the treestore */ +static TreeElement *outliner_find_tree_element(ListBase *lb, TreeStoreElem *store_elem) { - TreeElement *te = lb->first, *tes; - while (te) { - if (te->store_index == store_index) return te; - tes = outliner_find_tree_element(&te->subtree, store_index); + TreeElement *te, *tes; + for (te = lb->first; te; te = te->next) { + if (te->store_elem == store_elem) return te; + tes = outliner_find_tree_element(&te->subtree, store_elem); if (tes) return tes; - te = te->next; } return NULL; } @@ -232,23 +255,18 @@ static TreeElement *outliner_find_tree_element(ListBase *lb, int store_index) /* tse is not in the treestore, we use its contents to find a match */ TreeElement *outliner_find_tse(SpaceOops *soops, TreeStoreElem *tse) { - TreeStore *ts = soops->treestore; - TreeStoreElem *tselem; - int a; - + GHash *th = soops->treehash; + TreeStoreElem *tselem, tselem_template; + if (tse->id == NULL) return NULL; /* check if 'tse' is in treestore */ - tselem = ts->data; - for (a = 0; a < ts->usedelem; a++, tselem++) { - if ((tse->type == 0 && tselem->type == 0) || (tselem->type == tse->type && tselem->nr == tse->nr)) { - if (tselem->id == tse->id) { - break; - } - } - } + tselem_template.id = tse->id; + tselem_template.type = tse->type; + tselem_template.nr = tse->type ? tse->nr : 0; + tselem = BLI_ghash_lookup(th, &tselem_template); if (tselem) - return outliner_find_tree_element(&soops->tree, a); + return outliner_find_tree_element(&soops->tree, tselem); return NULL; } @@ -274,7 +292,7 @@ TreeElement *outliner_find_id(SpaceOops *soops, ListBase *lb, ID *id) } -ID *outliner_search_back(SpaceOops *soops, TreeElement *te, short idcode) +ID *outliner_search_back(SpaceOops *UNUSED(soops), TreeElement *te, short idcode) { TreeStoreElem *tselem; te = te->parent; @@ -1187,7 +1205,7 @@ static void outliner_add_seq_dup(SpaceOops *soops, Sequence *seq, TreeElement *t /* Hierarchy --------------------------------------------- */ /* make sure elements are correctly nested */ -static void outliner_make_hierarchy(SpaceOops *soops, ListBase *lb) +static void outliner_make_hierarchy(ListBase *lb) { TreeElement *te, *ten, *tep; TreeStoreElem *tselem; @@ -1489,7 +1507,7 @@ void outliner_build_tree(Main *mainvar, Scene *scene, SpaceOops *soops) Object *ob; TreeElement *te = NULL, *ten; TreeStoreElem *tselem; - int show_opened = (soops->treestore == NULL); /* on first view, we open scenes */ + int show_opened = !soops->treestore || !BLI_mempool_count(soops->treestore); /* on first view, we open scenes */ /* Are we looking for something - we want to tag parents to filter child matches * - NOT in datablocks view - searching all datablocks takes way too long to be useful @@ -1561,7 +1579,7 @@ void outliner_build_tree(Main *mainvar, Scene *scene, SpaceOops *soops) ten = outliner_add_element(soops, &te->subtree, base->object, te, 0, 0); ten->directdata = base; } - outliner_make_hierarchy(soops, &te->subtree); + outliner_make_hierarchy(&te->subtree); /* clear id.newid, to prevent objects be inserted in wrong scenes (parent in other scene) */ for (base = sce->base.first; base; base = base->next) base->object->id.newid = NULL; } @@ -1574,14 +1592,14 @@ void outliner_build_tree(Main *mainvar, Scene *scene, SpaceOops *soops) ten = outliner_add_element(soops, &soops->tree, base->object, NULL, 0, 0); ten->directdata = base; } - outliner_make_hierarchy(soops, &soops->tree); + outliner_make_hierarchy(&soops->tree); } else if (soops->outlinevis == SO_VISIBLE) { for (base = scene->base.first; base; base = base->next) { if (base->lay & scene->lay) outliner_add_element(soops, &soops->tree, base->object, NULL, 0, 0); } - outliner_make_hierarchy(soops, &soops->tree); + outliner_make_hierarchy(&soops->tree); } else if (soops->outlinevis == SO_GROUPS) { Group *group; @@ -1595,7 +1613,7 @@ void outliner_build_tree(Main *mainvar, Scene *scene, SpaceOops *soops) ten = outliner_add_element(soops, &te->subtree, go->ob, te, 0, 0); ten->directdata = NULL; /* eh, why? */ } - outliner_make_hierarchy(soops, &te->subtree); + outliner_make_hierarchy(&te->subtree); /* clear id.newid, to prevent objects be inserted in wrong scenes (parent in other scene) */ for (go = group->gobject.first; go; go = go->next) go->ob->id.newid = NULL; } @@ -1610,7 +1628,7 @@ void outliner_build_tree(Main *mainvar, Scene *scene, SpaceOops *soops) ten->directdata = base; } } - outliner_make_hierarchy(soops, &soops->tree); + outliner_make_hierarchy(&soops->tree); } } else if (soops->outlinevis == SO_SELECTED) { @@ -1622,7 +1640,7 @@ void outliner_build_tree(Main *mainvar, Scene *scene, SpaceOops *soops) } } } - outliner_make_hierarchy(soops, &soops->tree); + outliner_make_hierarchy(&soops->tree); } else if (soops->outlinevis == SO_SEQUENCE) { Sequence *seq; diff --git a/source/blender/editors/space_outliner/space_outliner.c b/source/blender/editors/space_outliner/space_outliner.c index 8da244b1db1..9c51265f917 100644 --- a/source/blender/editors/space_outliner/space_outliner.c +++ b/source/blender/editors/space_outliner/space_outliner.c @@ -37,6 +37,8 @@ #include "BLI_blenlib.h" #include "BLI_math.h" #include "BLI_utildefines.h" +#include "BLI_mempool.h" +#include "BLI_ghash.h" #include "BKE_context.h" #include "BKE_screen.h" @@ -426,10 +428,11 @@ static void outliner_free(SpaceLink *sl) outliner_free_tree(&soutliner->tree); if (soutliner->treestore) { - if (soutliner->treestore->data) MEM_freeN(soutliner->treestore->data); - MEM_freeN(soutliner->treestore); + BLI_mempool_destroy(soutliner->treestore); + } + if (soutliner->treehash) { + BLI_ghash_free(soutliner->treehash, NULL, NULL); } - } /* spacetype; init callback */ diff --git a/source/blender/makesdna/DNA_outliner_types.h b/source/blender/makesdna/DNA_outliner_types.h index 5f9c90f09f7..53061b55e2d 100644 --- a/source/blender/makesdna/DNA_outliner_types.h +++ b/source/blender/makesdna/DNA_outliner_types.h @@ -32,6 +32,8 @@ #ifndef __DNA_OUTLINER_TYPES_H__ #define __DNA_OUTLINER_TYPES_H__ +#include "DNA_defs.h" + struct ID; typedef struct TreeStoreElem { @@ -39,9 +41,12 @@ typedef struct TreeStoreElem { struct ID *id; } TreeStoreElem; +/* used only to store data in in blend files */ typedef struct TreeStore { - int totelem, usedelem; - TreeStoreElem *data; + int totelem DNA_DEPRECATED; /* was previously used for memory preallocation */ + int usedelem; /* number of elements in data array */ + TreeStoreElem *data; /* elements to be packed from mempool in writefile.c + * or extracted to mempool in readfile.c */ } TreeStore; /* TreeStoreElem->flag */ diff --git a/source/blender/makesdna/DNA_space_types.h b/source/blender/makesdna/DNA_space_types.h index 2d87cb1d890..c562a1fefae 100644 --- a/source/blender/makesdna/DNA_space_types.h +++ b/source/blender/makesdna/DNA_space_types.h @@ -72,6 +72,8 @@ struct wmTimer; struct MovieClip; struct MovieClipScopes; struct Mask; +struct GHash; +struct BLI_mempool; /* SpaceLink (Base) ==================================== */ @@ -244,13 +246,14 @@ typedef struct SpaceOops { View2D v2d DNA_DEPRECATED; /* deprecated, copied to region */ ListBase tree; - struct TreeStore *treestore; + struct BLI_mempool *treestore; /* search stuff */ char search_string[32]; struct TreeStoreElem search_tse; short flag, outlinevis, storeflag, search_flags; + struct GHash *treehash; } SpaceOops;