From a6e9c9fda0af4627e541b6cef4bfa41f4f5adb0e Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 11 Dec 2012 02:13:42 +0000 Subject: [PATCH 001/252] update api changelog --- doc/python_api/rst/change_log.rst | 430 ++++++++++++++++++++++++++++++ 1 file changed, 430 insertions(+) diff --git a/doc/python_api/rst/change_log.rst b/doc/python_api/rst/change_log.rst index c1f3c2e4267..7579070c258 100644 --- a/doc/python_api/rst/change_log.rst +++ b/doc/python_api/rst/change_log.rst @@ -3896,3 +3896,433 @@ Added ^^^^^ * :class:`bpy.types.LatticePoint.select` + + +2.64 to 2.65 +============ + +bpy.types.SmokeDomainSettings +----------------------------- + +Added +^^^^^ + +* :class:`bpy.types.SmokeDomainSettings.adapt_margin` +* :class:`bpy.types.SmokeDomainSettings.adapt_threshold` +* :class:`bpy.types.SmokeDomainSettings.additional_res` +* :class:`bpy.types.SmokeDomainSettings.burning_rate` +* :class:`bpy.types.SmokeDomainSettings.flame_ignition` +* :class:`bpy.types.SmokeDomainSettings.flame_max_temp` +* :class:`bpy.types.SmokeDomainSettings.flame_smoke` +* :class:`bpy.types.SmokeDomainSettings.flame_smoke_color` +* :class:`bpy.types.SmokeDomainSettings.flame_vorticity` +* :class:`bpy.types.SmokeDomainSettings.use_adaptive_domain` + +Removed +^^^^^^^ + +* **scale** + +bpy.types.BezierSplinePoint +--------------------------- + +Renamed +^^^^^^^ + +* **weight** -> :class:`bpy.types.BezierSplinePoint.weight_softbody` + +bpy.types.Material +------------------ + +Added +^^^^^ + +* :class:`bpy.types.Material.use_light_group_local` + +bpy.types.Curve +--------------- + +Added +^^^^^ + +* :class:`bpy.types.Curve.use_map_taper` + +bpy.types.EffectorWeights +------------------------- + +Added +^^^^^ + +* :class:`bpy.types.EffectorWeights.smokeflow` + +bpy.types.FieldSettings +----------------------- + +Added +^^^^^ + +* :class:`bpy.types.FieldSettings.source_object` +* :class:`bpy.types.FieldSettings.use_smoke_density` + +bpy.types.GPencilFrame +---------------------- + +Added +^^^^^ + +* :class:`bpy.types.GPencilFrame.clear` + +bpy.types.UserPreferencesView +----------------------------- + +Renamed +^^^^^^^ + +* **quit_dialog** -> :class:`bpy.types.UserPreferencesView.use_quit_dialog` + +bpy.types.GreasePencilLayers +---------------------------- + +Added +^^^^^ + +* :class:`bpy.types.GreasePencilLayers.new` +* :class:`bpy.types.GreasePencilLayers.remove` + +bpy.types.PointCache +-------------------- + +Removed +^^^^^^^ + +* **use_quick_cache** + +bpy.types.KinematicConstraint +----------------------------- + +Removed +^^^^^^^ + +* **use_target** + +bpy.types.DopeSheet +------------------- + +Added +^^^^^ + +* :class:`bpy.types.DopeSheet.show_only_errors` + +bpy.types.UILayout +------------------ + +Renamed +^^^^^^^ + +* **template_color_wheel** -> :class:`bpy.types.UILayout.template_color_picker` + +bpy.types.GPencilStroke +----------------------- + +Added +^^^^^ + +* :class:`bpy.types.GPencilStroke.draw_mode` + +bpy.types.UserPreferencesEdit +----------------------------- + +Added +^^^^^ + +* :class:`bpy.types.UserPreferencesEdit.use_auto_keying_warning` + +bpy.types.MovieTrackingObject +----------------------------- + +Added +^^^^^ + +* :class:`bpy.types.MovieTrackingObject.keyframe_a` +* :class:`bpy.types.MovieTrackingObject.keyframe_b` + +bpy.types.ShrinkwrapModifier +---------------------------- + +Added +^^^^^ + +* :class:`bpy.types.ShrinkwrapModifier.project_limit` + +bpy.types.FileSelectParams +-------------------------- + +Added +^^^^^ + +* :class:`bpy.types.FileSelectParams.use_filter_backup` + +bpy.types.RenderSettings +------------------------ + +Added +^^^^^ + +* :class:`bpy.types.RenderSettings.tile_x` +* :class:`bpy.types.RenderSettings.tile_y` +* :class:`bpy.types.RenderSettings.use_persistent_data` + +Removed +^^^^^^^ + +* **parts_x** +* **parts_y** +* **use_sequencer_gl_render** + +bpy.types.Sculpt +---------------- + +Added +^^^^^ + +* :class:`bpy.types.Sculpt.show_diffuse_color` + +bpy.types.SmokeFlowSettings +--------------------------- + +Added +^^^^^ + +* :class:`bpy.types.SmokeFlowSettings.density_vertex_group` +* :class:`bpy.types.SmokeFlowSettings.fuel_amount` +* :class:`bpy.types.SmokeFlowSettings.noise_texture` +* :class:`bpy.types.SmokeFlowSettings.smoke_color` +* :class:`bpy.types.SmokeFlowSettings.smoke_flow_source` +* :class:`bpy.types.SmokeFlowSettings.smoke_flow_type` +* :class:`bpy.types.SmokeFlowSettings.surface_distance` +* :class:`bpy.types.SmokeFlowSettings.texture_map_type` +* :class:`bpy.types.SmokeFlowSettings.texture_offset` +* :class:`bpy.types.SmokeFlowSettings.texture_size` +* :class:`bpy.types.SmokeFlowSettings.use_texture` +* :class:`bpy.types.SmokeFlowSettings.uv_layer` +* :class:`bpy.types.SmokeFlowSettings.velocity_normal` +* :class:`bpy.types.SmokeFlowSettings.velocity_random` +* :class:`bpy.types.SmokeFlowSettings.volume_density` + +Removed +^^^^^^^ + +* **use_outflow** + +bpy.types.GameObjectSettings +---------------------------- + +Added +^^^^^ + +* :class:`bpy.types.GameObjectSettings.collision_group` +* :class:`bpy.types.GameObjectSettings.collision_mask` + +bpy.types.SpaceView3D +--------------------- + +Added +^^^^^ + +* :class:`bpy.types.SpaceView3D.grid_scale_unit` +* :class:`bpy.types.SpaceView3D.render_border_max_x` +* :class:`bpy.types.SpaceView3D.render_border_max_y` +* :class:`bpy.types.SpaceView3D.render_border_min_x` +* :class:`bpy.types.SpaceView3D.render_border_min_y` +* :class:`bpy.types.SpaceView3D.use_render_border` + +bpy.types.DupliObject +--------------------- + +Added +^^^^^ + +* :class:`bpy.types.DupliObject.orco` +* :class:`bpy.types.DupliObject.particle_system` +* :class:`bpy.types.DupliObject.persistent_id` +* :class:`bpy.types.DupliObject.type` +* :class:`bpy.types.DupliObject.uv` + +Removed +^^^^^^^ + +* **particle_index** + +bpy.types.CyclesRenderSettings +------------------------------ + +Added +^^^^^ + +* :class:`bpy.types.CyclesRenderSettings.use_progressive_refine` + +bpy.types.MaterialTextureSlot +----------------------------- + +Added +^^^^^ + +* :class:`bpy.types.MaterialTextureSlot.use_map_to_bounds` + +bpy.types.MovieSequence +----------------------- + +Added +^^^^^ + +* :class:`bpy.types.MovieSequence.colorspace_settings` + +bpy.types.GPencilLayer +---------------------- + +Added +^^^^^ + +* :class:`bpy.types.GPencilLayer.clear` + +bpy.types.CYCLES +---------------- + +Added +^^^^^ + +* :class:`bpy.types.CYCLES.update_script_node` + +bpy.types.ImageSequence +----------------------- + +Added +^^^^^ + +* :class:`bpy.types.ImageSequence.colorspace_settings` + +bpy.types.LatticePoint +---------------------- + +Added +^^^^^ + +* :class:`bpy.types.LatticePoint.weight_softbody` + +bpy.types.DecimateModifier +-------------------------- + +Added +^^^^^ + +* :class:`bpy.types.DecimateModifier.angle_limit` +* :class:`bpy.types.DecimateModifier.decimate_type` +* :class:`bpy.types.DecimateModifier.invert_vertex_group` +* :class:`bpy.types.DecimateModifier.iterations` +* :class:`bpy.types.DecimateModifier.use_collapse_triangulate` +* :class:`bpy.types.DecimateModifier.use_dissolve_boundaries` +* :class:`bpy.types.DecimateModifier.vertex_group` + +bpy.types.UserPreferencesSystem +------------------------------- + +Added +^^^^^ + +* :class:`bpy.types.UserPreferencesSystem.multi_sample` + +Removed +^^^^^^^ + +* **use_antialiasing** + +bpy.types.Text +-------------- + +Removed +^^^^^^^ + +* **markers** + +bpy.types.GreasePencil +---------------------- + +Added +^^^^^ + +* :class:`bpy.types.GreasePencil.clear` + +bpy.types.UserPreferencesFilePaths +---------------------------------- + +Added +^^^^^ + +* :class:`bpy.types.UserPreferencesFilePaths.hide_system_bookmarks` + +bpy.types.ToolSettings +---------------------- + +Added +^^^^^ + +* :class:`bpy.types.ToolSettings.snap_uv_element` + +bpy.types.ShaderNodeTexCoord +---------------------------- + +Added +^^^^^ + +* :class:`bpy.types.ShaderNodeTexCoord.from_dupli` + +bpy.types.RenderEngine +---------------------- + +Added +^^^^^ + +* :class:`bpy.types.RenderEngine.update_memory_stats` +* :class:`bpy.types.RenderEngine.update_script_node` + +bpy.types.MovieTrackingSettings +------------------------------- + +Added +^^^^^ + +* :class:`bpy.types.MovieTrackingSettings.reconstruction_success_threshold` +* :class:`bpy.types.MovieTrackingSettings.use_fallback_reconstruction` + +Removed +^^^^^^^ + +* **keyframe_a** +* **keyframe_b** + +bpy.types.ThemeUserInterface +---------------------------- + +Added +^^^^^ + +* :class:`bpy.types.ThemeUserInterface.axis_x` +* :class:`bpy.types.ThemeUserInterface.axis_y` +* :class:`bpy.types.ThemeUserInterface.axis_z` + +bpy.types.BlendDataGreasePencils +-------------------------------- + +Added +^^^^^ + +* :class:`bpy.types.BlendDataGreasePencils.new` +* :class:`bpy.types.BlendDataGreasePencils.remove` + +bpy.types.Object +---------------- + +Function Arguments +^^^^^^^^^^^^^^^^^^ + +* :class:`bpy.types.Object.dupli_list_create` (scene, settings), *was (scene)* From 08f39daf4e6cee9fa66d7a5d0a78d4b8670f716b Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 11 Dec 2012 05:57:42 +0000 Subject: [PATCH 002/252] cmake wouldn't build since it was missing files added in r52858. --- intern/audaspace/CMakeLists.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/intern/audaspace/CMakeLists.txt b/intern/audaspace/CMakeLists.txt index 91b0549f742..ec66cffea3b 100644 --- a/intern/audaspace/CMakeLists.txt +++ b/intern/audaspace/CMakeLists.txt @@ -33,6 +33,7 @@ set(INC_SYS set(SRC FX/AUD_AccumulatorFactory.cpp + FX/AUD_BandpassCalculator.cpp FX/AUD_BaseIIRFilterReader.cpp FX/AUD_ButterworthCalculator.cpp FX/AUD_ButterworthFactory.cpp @@ -147,6 +148,7 @@ set(SRC intern/AUD_StreamBufferFactory.h FX/AUD_AccumulatorFactory.h + FX/AUD_BandpassCalculator.h FX/AUD_BaseIIRFilterReader.h FX/AUD_ButterworthCalculator.h FX/AUD_ButterworthFactory.h From cb2ad513bbef99e0c0d9b2cbb613412ac879f59b Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Tue, 11 Dec 2012 08:01:05 +0000 Subject: [PATCH 003/252] Splash template XCF file for Gimp. --- release/datafiles/splash_template.xcf | Bin 0 -> 21898 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 release/datafiles/splash_template.xcf diff --git a/release/datafiles/splash_template.xcf b/release/datafiles/splash_template.xcf new file mode 100644 index 0000000000000000000000000000000000000000..6d7e7d42c9f54173365ee04d3d28ca9f7abb1127 GIT binary patch literal 21898 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 Date: Tue, 11 Dec 2012 08:01:16 +0000 Subject: [PATCH 004/252] Fix game player still not using fast GPU mipmap generation, user preferencs are not actually used here. --- source/gameengine/GamePlayer/ghost/GPG_ghost.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/source/gameengine/GamePlayer/ghost/GPG_ghost.cpp b/source/gameengine/GamePlayer/ghost/GPG_ghost.cpp index a82f9ce1779..ba7d3135a10 100644 --- a/source/gameengine/GamePlayer/ghost/GPG_ghost.cpp +++ b/source/gameengine/GamePlayer/ghost/GPG_ghost.cpp @@ -492,6 +492,8 @@ int main(int argc, char** argv) // XXX this one too U.anisotropic_filter = 2; + // enable fast mipmap generation + U.use_gpu_mipmap = 1; sound_init_once(); From ea464b96592a3800a02ab568616328d010fab9a2 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Tue, 11 Dec 2012 08:13:56 +0000 Subject: [PATCH 005/252] OSL install deps script: set STOP_ON_WARNING to OFF to disable -Werror. --- build_files/build_environment/install_deps.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/build_files/build_environment/install_deps.sh b/build_files/build_environment/install_deps.sh index 072e999d827..24f0048e0eb 100755 --- a/build_files/build_environment/install_deps.sh +++ b/build_files/build_environment/install_deps.sh @@ -876,6 +876,7 @@ compile_OSL() { cmake_d="$cmake_d -D CMAKE_INSTALL_PREFIX=$_inst" cmake_d="$cmake_d -D BUILDSTATIC=ON" cmake_d="$cmake_d -D BUILD_TESTING=OFF" + cmake_d="$cmake_d -D STOP_ON_WARNING=OFF" if [ -d $INST/boost ]; then cmake_d="$cmake_d -D BOOST_ROOT=$INST/boost -D Boost_NO_SYSTEM_PATHS=ON" From d321ee3fdae12b8e0394369b702ba79c187e692e Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Tue, 11 Dec 2012 11:22:51 +0000 Subject: [PATCH 006/252] Fix #33476: cycles environment texture not showing image sequence options properly. --- source/blender/editors/space_node/drawnode.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c index 92edac356e6..381393eb725 100644 --- a/source/blender/editors/space_node/drawnode.c +++ b/source/blender/editors/space_node/drawnode.c @@ -1351,7 +1351,7 @@ static void node_shader_buts_tex_environment(uiLayout *layout, bContext *C, Poin uiItemR(layout, ptr, "color_space", 0, "", ICON_NONE); uiItemR(layout, ptr, "projection", 0, "", ICON_NONE); - node_buts_image_user(layout, C, ptr, &imaptr, &iuserptr); + node_buts_image_user(layout, C, &iuserptr, &imaptr, &iuserptr); } static void node_shader_buts_tex_sky(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr) From e089c5a976eda6fadff6a8d4b5edb6e7460c8f90 Mon Sep 17 00:00:00 2001 From: Daniel Genrich Date: Tue, 11 Dec 2012 13:02:42 +0000 Subject: [PATCH 007/252] Bugfix [#33467] Fluid Simulations Speed factor animated wrong result Thanks to Brecht for providing a patch and example blend. I changed and extended it a bit since there was another bug in that loop. --- intern/elbeem/intern/ntl_world.cpp | 8 +++++++- intern/elbeem/intern/ntl_world.h | 1 + 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/intern/elbeem/intern/ntl_world.cpp b/intern/elbeem/intern/ntl_world.cpp index dcc81dbe5cb..9ae5135b040 100644 --- a/intern/elbeem/intern/ntl_world.cpp +++ b/intern/elbeem/intern/ntl_world.cpp @@ -420,7 +420,12 @@ int ntlWorld::advanceSims(int framenum) // Was: double targetTime = mSimulationTime + (*mpSims)[mFirstSim]->getFrameTime(framenum); - DG double totalTime = 0.0, targetTime = 0.0; for(size_t i = 0; i < mSimFrameCnt; i++) - totalTime += (*mpSims)[mFirstSim]->getFrameTime(framenum); + { + /* We need an intermediate array "mSimFrameValue" because + otherwise if we don't start with starttime = 0, + the sim gets out of sync - DG */ + totalTime += (*mpSims)[mFirstSim]->getFrameTime(mSimFrameValue[i]); + } targetTime = totalTime + (*mpSims)[mFirstSim]->getFrameTime(framenum); int gstate = 0; @@ -468,6 +473,7 @@ int ntlWorld::advanceSims(int framenum) sim->prepareVisualization(); } + mSimFrameValue.push_back(framenum); mSimFrameCnt++; return 0; diff --git a/intern/elbeem/intern/ntl_world.h b/intern/elbeem/intern/ntl_world.h index c207904cf75..6cec098132b 100644 --- a/intern/elbeem/intern/ntl_world.h +++ b/intern/elbeem/intern/ntl_world.h @@ -118,6 +118,7 @@ class ntlWorld /*! count no. of frame for correct sim time */ int mSimFrameCnt; + vector mSimFrameValue; }; From 3261338aef86cada814698442da9a9ec3658644c Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 11 Dec 2012 13:56:01 +0000 Subject: [PATCH 008/252] unfreeze blender, back to bcon1 --- source/blender/blenkernel/BKE_blender.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/blenkernel/BKE_blender.h b/source/blender/blenkernel/BKE_blender.h index b624d0f9c3a..cd75749fa3c 100644 --- a/source/blender/blenkernel/BKE_blender.h +++ b/source/blender/blenkernel/BKE_blender.h @@ -52,7 +52,7 @@ extern "C" { /* can be left blank, otherwise a,b,c... etc with no quotes */ #define BLENDER_VERSION_CHAR /* alpha/beta/rc/release, docs use this */ -#define BLENDER_VERSION_CYCLE release +#define BLENDER_VERSION_CYCLE alpha extern char versionstr[]; /* from blender.c */ From 361eb23a42328c700a9d020be5896fed6bcd7f4a Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 11 Dec 2012 13:57:58 +0000 Subject: [PATCH 009/252] switch BLI_ghashutil_strhash() to "djb" hash (as used by glib), Gives approx 10% speedup in my own micro-benchmark looking up operators. --- source/blender/blenlib/intern/BLI_ghash.c | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/source/blender/blenlib/intern/BLI_ghash.c b/source/blender/blenlib/intern/BLI_ghash.c index c4094920c2a..8767a9ac14c 100644 --- a/source/blender/blenlib/intern/BLI_ghash.c +++ b/source/blender/blenlib/intern/BLI_ghash.c @@ -312,17 +312,25 @@ int BLI_ghashutil_intcmp(const void *a, const void *b) return (a < b) ? -1 : 1; } +/** + * This function implements the widely used "djb" hash apparently posted + * by Daniel Bernstein to comp.lang.c some time ago. The 32 bit + * unsigned hash value starts at 5381 and for each byte 'c' in the + * string, is updated: hash = hash * 33 + c. This + * function uses the signed value of each byte. + * + * note: this is the same hash method that glib 2.34.0 uses. + */ unsigned int BLI_ghashutil_strhash(const void *ptr) { - const char *s = ptr; - unsigned int i = 0; - unsigned char c; + const signed char *p; + unsigned int h = 5381; - while ((c = *s++)) { - i = i * 37 + c; + for (p = ptr; *p != '\0'; p++) { + h = (h << 5) + h + *p; } - return i; + return h; } int BLI_ghashutil_strcmp(const void *a, const void *b) { @@ -376,4 +384,3 @@ void BLI_ghashutil_pairfree(void *ptr) { MEM_freeN((void *)ptr); } - From 01ab26770f24d29eb45efe7b627708df876ae906 Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Tue, 11 Dec 2012 14:11:46 +0000 Subject: [PATCH 010/252] Fix some RNA subtypes for collections' active/active_index props (some PROP_POINTER had PROP_UNSIGNED!). Harmless, but stupid ;) --- source/blender/makesrna/intern/rna_action.c | 2 +- source/blender/makesrna/intern/rna_mesh.c | 18 +++++++++--------- source/blender/makesrna/intern/rna_object.c | 2 +- source/blender/makesrna/intern/rna_pose.c | 2 +- source/blender/makesrna/intern/rna_scene.c | 4 ++-- 5 files changed, 14 insertions(+), 14 deletions(-) diff --git a/source/blender/makesrna/intern/rna_action.c b/source/blender/makesrna/intern/rna_action.c index 1f9503f1cc9..07c394ae4d8 100644 --- a/source/blender/makesrna/intern/rna_action.c +++ b/source/blender/makesrna/intern/rna_action.c @@ -596,7 +596,7 @@ static void rna_def_action_pose_markers(BlenderRNA *brna, PropertyRNA *cprop) "rna_Action_active_pose_marker_set", NULL, NULL); RNA_def_property_ui_text(prop, "Active Pose Marker", "Active pose marker for this action"); - prop = RNA_def_property(srna, "active_index", PROP_INT, PROP_NONE); + prop = RNA_def_property(srna, "active_index", PROP_INT, PROP_UNSIGNED); RNA_def_property_int_sdna(prop, NULL, "active_marker"); RNA_def_property_int_funcs(prop, "rna_Action_active_pose_marker_index_get", "rna_Action_active_pose_marker_index_set", "rna_Action_active_pose_marker_index_range"); diff --git a/source/blender/makesrna/intern/rna_mesh.c b/source/blender/makesrna/intern/rna_mesh.c index 287995e0aa6..cdf8d6614f3 100644 --- a/source/blender/makesrna/intern/rna_mesh.c +++ b/source/blender/makesrna/intern/rna_mesh.c @@ -2353,7 +2353,7 @@ static void rna_def_tessface_vertex_colors(BlenderRNA *brna, PropertyRNA *cprop) RNA_def_property_flag(parm, PROP_RNAPTR); RNA_def_function_return(func, parm); - prop = RNA_def_property(srna, "active", PROP_POINTER, PROP_UNSIGNED); + prop = RNA_def_property(srna, "active", PROP_POINTER, PROP_NONE); RNA_def_property_struct_type(prop, "MeshColorLayer"); RNA_def_property_pointer_funcs(prop, "rna_Mesh_tessface_vertex_color_active_get", "rna_Mesh_tessface_vertex_color_active_set", NULL, NULL); @@ -2397,7 +2397,7 @@ static void rna_def_loop_colors(BlenderRNA *brna, PropertyRNA *cprop) RNA_def_property_clear_flag(parm, PROP_THICK_WRAP); #endif - prop = RNA_def_property(srna, "active", PROP_POINTER, PROP_UNSIGNED); + prop = RNA_def_property(srna, "active", PROP_POINTER, PROP_NONE); RNA_def_property_struct_type(prop, "MeshLoopColorLayer"); RNA_def_property_pointer_funcs(prop, "rna_Mesh_vertex_color_active_get", "rna_Mesh_vertex_color_active_set", NULL, NULL); @@ -2425,7 +2425,7 @@ static void rna_def_uv_layers(BlenderRNA *brna, PropertyRNA *cprop) RNA_def_struct_sdna(srna, "Mesh"); RNA_def_struct_ui_text(srna, "UV Loop Layers", "Collection of uv loop layers"); - prop = RNA_def_property(srna, "active", PROP_POINTER, PROP_UNSIGNED); + prop = RNA_def_property(srna, "active", PROP_POINTER, PROP_NONE); RNA_def_property_struct_type(prop, "MeshUVLoopLayer"); RNA_def_property_pointer_funcs(prop, "rna_Mesh_uv_layer_active_get", "rna_Mesh_uv_layer_active_set", NULL, NULL); @@ -2530,7 +2530,7 @@ static void rna_def_tessface_uv_textures(BlenderRNA *brna, PropertyRNA *cprop) RNA_def_function_return(func, parm); - prop = RNA_def_property(srna, "active", PROP_POINTER, PROP_UNSIGNED); + prop = RNA_def_property(srna, "active", PROP_POINTER, PROP_NONE); RNA_def_property_struct_type(prop, "MeshTextureFaceLayer"); RNA_def_property_pointer_funcs(prop, "rna_Mesh_tessface_uv_texture_active_get", "rna_Mesh_tessface_uv_texture_active_set", NULL, NULL); @@ -2575,7 +2575,7 @@ static void rna_def_uv_textures(BlenderRNA *brna, PropertyRNA *cprop) RNA_def_property_clear_flag(parm, PROP_THICK_WRAP); #endif - prop = RNA_def_property(srna, "active", PROP_POINTER, PROP_UNSIGNED); + prop = RNA_def_property(srna, "active", PROP_POINTER, PROP_NONE); RNA_def_property_struct_type(prop, "MeshTexturePolyLayer"); RNA_def_property_pointer_funcs(prop, "rna_Mesh_uv_texture_active_get", "rna_Mesh_uv_texture_active_set", NULL, NULL); @@ -2693,7 +2693,7 @@ static void rna_def_mesh(BlenderRNA *brna) RNA_def_property_ui_text(prop, "UV Loop Layers", "All UV loop layers"); rna_def_uv_layers(brna, prop); - prop = RNA_def_property(srna, "uv_layer_clone", PROP_POINTER, PROP_UNSIGNED); + prop = RNA_def_property(srna, "uv_layer_clone", PROP_POINTER, PROP_NONE); RNA_def_property_struct_type(prop, "MeshUVLoopLayer"); RNA_def_property_pointer_funcs(prop, "rna_Mesh_uv_layer_clone_get", "rna_Mesh_uv_layer_clone_set", NULL, NULL); @@ -2705,7 +2705,7 @@ static void rna_def_mesh(BlenderRNA *brna) "rna_Mesh_uv_layer_clone_index_set", "rna_Mesh_uv_layer_index_range"); RNA_def_property_ui_text(prop, "Clone UV loop layer Index", "Clone UV loop layer index"); - prop = RNA_def_property(srna, "uv_layer_stencil", PROP_POINTER, PROP_UNSIGNED); + prop = RNA_def_property(srna, "uv_layer_stencil", PROP_POINTER, PROP_NONE); RNA_def_property_struct_type(prop, "MeshUVLoopLayer"); RNA_def_property_pointer_funcs(prop, "rna_Mesh_uv_layer_stencil_get", "rna_Mesh_uv_layer_stencil_set", NULL, NULL); @@ -2736,7 +2736,7 @@ static void rna_def_mesh(BlenderRNA *brna) RNA_def_property_ui_text(prop, "UV Maps", "All UV maps"); rna_def_uv_textures(brna, prop); - prop = RNA_def_property(srna, "uv_texture_clone", PROP_POINTER, PROP_UNSIGNED); + prop = RNA_def_property(srna, "uv_texture_clone", PROP_POINTER, PROP_NONE); RNA_def_property_struct_type(prop, "MeshTexturePolyLayer"); RNA_def_property_pointer_funcs(prop, "rna_Mesh_uv_texture_clone_get", "rna_Mesh_uv_texture_clone_set", NULL, NULL); @@ -2748,7 +2748,7 @@ static void rna_def_mesh(BlenderRNA *brna) "rna_Mesh_uv_texture_clone_index_set", "rna_Mesh_uv_texture_index_range"); RNA_def_property_ui_text(prop, "Clone UV Map Index", "Clone UV map index"); - prop = RNA_def_property(srna, "uv_texture_stencil", PROP_POINTER, PROP_UNSIGNED); + prop = RNA_def_property(srna, "uv_texture_stencil", PROP_POINTER, PROP_NONE); RNA_def_property_struct_type(prop, "MeshTexturePolyLayer"); RNA_def_property_pointer_funcs(prop, "rna_Mesh_uv_texture_stencil_get", "rna_Mesh_uv_texture_stencil_set", NULL, NULL); diff --git a/source/blender/makesrna/intern/rna_object.c b/source/blender/makesrna/intern/rna_object.c index 1d08ea97b79..df7c4d78531 100644 --- a/source/blender/makesrna/intern/rna_object.c +++ b/source/blender/makesrna/intern/rna_object.c @@ -1961,7 +1961,7 @@ static void rna_def_object_vertex_groups(BlenderRNA *brna, PropertyRNA *cprop) RNA_def_property_ui_text(prop, "Active Vertex Group", "Vertex groups of the object"); RNA_def_property_update(prop, NC_GEOM | ND_DATA, "rna_Object_internal_update_data"); - prop = RNA_def_property(srna, "active_index", PROP_INT, PROP_NONE); + prop = RNA_def_property(srna, "active_index", PROP_INT, PROP_UNSIGNED); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); RNA_def_property_int_sdna(prop, NULL, "actdef"); RNA_def_property_int_funcs(prop, "rna_Object_active_vertex_group_index_get", diff --git a/source/blender/makesrna/intern/rna_pose.c b/source/blender/makesrna/intern/rna_pose.c index 5c90fb8787c..28d1de2c601 100644 --- a/source/blender/makesrna/intern/rna_pose.c +++ b/source/blender/makesrna/intern/rna_pose.c @@ -1246,7 +1246,7 @@ static void rna_def_bone_groups(BlenderRNA *brna, PropertyRNA *cprop) RNA_def_property_ui_text(prop, "Active Bone Group", "Active bone group for this pose"); RNA_def_property_update(prop, NC_OBJECT | ND_POSE, "rna_Pose_update"); - prop = RNA_def_property(srna, "active_index", PROP_INT, PROP_NONE); + prop = RNA_def_property(srna, "active_index", PROP_INT, PROP_UNSIGNED); RNA_def_property_int_sdna(prop, NULL, "active_group"); RNA_def_property_int_funcs(prop, "rna_Pose_active_bone_group_index_get", "rna_Pose_active_bone_group_index_set", "rna_Pose_active_bone_group_index_range"); diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c index 6f3a483cf7e..2d405f4fc0d 100644 --- a/source/blender/makesrna/intern/rna_scene.c +++ b/source/blender/makesrna/intern/rna_scene.c @@ -2812,7 +2812,7 @@ static void rna_def_render_layers(BlenderRNA *brna, PropertyRNA *cprop) RNA_def_struct_sdna(srna, "RenderData"); RNA_def_struct_ui_text(srna, "Render Layers", "Collection of render layers"); - prop = RNA_def_property(srna, "active_index", PROP_INT, PROP_NONE); + prop = RNA_def_property(srna, "active_index", PROP_INT, PROP_UNSIGNED); RNA_def_property_int_sdna(prop, NULL, "actlay"); RNA_def_property_int_funcs(prop, "rna_RenderSettings_active_layer_index_get", "rna_RenderSettings_active_layer_index_set", @@ -2820,7 +2820,7 @@ static void rna_def_render_layers(BlenderRNA *brna, PropertyRNA *cprop) RNA_def_property_ui_text(prop, "Active Layer Index", "Active index in render layer array"); RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, "rna_Scene_glsl_update"); - prop = RNA_def_property(srna, "active", PROP_POINTER, PROP_UNSIGNED); + prop = RNA_def_property(srna, "active", PROP_POINTER, PROP_NONE); RNA_def_property_struct_type(prop, "SceneRenderLayer"); RNA_def_property_pointer_funcs(prop, "rna_RenderSettings_active_layer_get", "rna_RenderSettings_active_layer_set", NULL, NULL); From 634b22fc46c10502c07175108bc68ff90903bb1f Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 11 Dec 2012 14:18:37 +0000 Subject: [PATCH 011/252] code cleanup: spelling labda -> lambda --- source/blender/blenkernel/intern/curve.c | 22 +-- source/blender/blenlib/intern/math_geom.c | 28 ++-- source/blender/blenlib/intern/rct.c | 8 +- .../blender/editors/armature/meshlaplacian.c | 8 +- source/blender/editors/mesh/editmesh_knife.c | 4 +- source/blender/editors/mesh/editmesh_select.c | 8 +- .../intern/raytrace/rayobject_octree.cpp | 134 +++++++++--------- source/blender/render/intern/source/envmap.c | 44 +++--- source/blender/render/intern/source/shadbuf.c | 46 +++--- source/blender/render/intern/source/zbuf.c | 42 +++--- 10 files changed, 172 insertions(+), 172 deletions(-) diff --git a/source/blender/blenkernel/intern/curve.c b/source/blender/blenkernel/intern/curve.c index 754a4fbc0c8..4b4ca1cb32b 100644 --- a/source/blender/blenkernel/intern/curve.c +++ b/source/blender/blenkernel/intern/curve.c @@ -68,7 +68,7 @@ /* local */ static int cu_isectLL(const float v1[3], const float v2[3], const float v3[3], const float v4[3], short cox, short coy, - float *labda, float *mu, float vec[3]); + float *lambda, float *mu, float vec[3]); void BKE_curve_unlink(Curve *cu) { @@ -1615,7 +1615,7 @@ void BKE_curve_bevel_make(Scene *scene, Object *ob, ListBase *disp, int forRende static int cu_isectLL(const float v1[3], const float v2[3], const float v3[3], const float v4[3], short cox, short coy, - float *labda, float *mu, float vec[3]) + float *lambda, float *mu, float vec[3]) { /* return: * -1: collinear @@ -1629,22 +1629,22 @@ static int cu_isectLL(const float v1[3], const float v2[3], const float v3[3], c if (deler == 0.0f) return -1; - *labda = (v1[coy] - v3[coy]) * (v3[cox] - v4[cox]) - (v1[cox] - v3[cox]) * (v3[coy] - v4[coy]); - *labda = -(*labda / deler); + *lambda = (v1[coy] - v3[coy]) * (v3[cox] - v4[cox]) - (v1[cox] - v3[cox]) * (v3[coy] - v4[coy]); + *lambda = -(*lambda / deler); deler = v3[coy] - v4[coy]; if (deler == 0) { deler = v3[cox] - v4[cox]; - *mu = -(*labda * (v2[cox] - v1[cox]) + v1[cox] - v3[cox]) / deler; + *mu = -(*lambda * (v2[cox] - v1[cox]) + v1[cox] - v3[cox]) / deler; } else { - *mu = -(*labda * (v2[coy] - v1[coy]) + v1[coy] - v3[coy]) / deler; + *mu = -(*lambda * (v2[coy] - v1[coy]) + v1[coy] - v3[coy]) / deler; } - vec[cox] = *labda * (v2[cox] - v1[cox]) + v1[cox]; - vec[coy] = *labda * (v2[coy] - v1[coy]) + v1[coy]; + vec[cox] = *lambda * (v2[cox] - v1[cox]) + v1[cox]; + vec[coy] = *lambda * (v2[coy] - v1[coy]) + v1[coy]; - if (*labda >= 0.0f && *labda <= 1.0f && *mu >= 0.0f && *mu <= 1.0f) { - if (*labda == 0.0f || *labda == 1.0f || *mu == 0.0f || *mu == 1.0f) + if (*lambda >= 0.0f && *lambda <= 1.0f && *mu >= 0.0f && *mu <= 1.0f) { + if (*lambda == 0.0f || *lambda == 1.0f || *mu == 0.0f || *mu == 1.0f) return 1; return 2; } @@ -1654,7 +1654,7 @@ static int cu_isectLL(const float v1[3], const float v2[3], const float v3[3], c static short bevelinside(BevList *bl1, BevList *bl2) { - /* is bl2 INSIDE bl1 ? with left-right method and "labda's" */ + /* is bl2 INSIDE bl1 ? with left-right method and "lambda's" */ /* returns '1' if correct hole */ BevPoint *bevp, *prevbevp; float min, max, vec[3], hvec1[3], hvec2[3], lab, mu; diff --git a/source/blender/blenlib/intern/math_geom.c b/source/blender/blenlib/intern/math_geom.c index 74abd7e8c7e..6938cde8ec5 100644 --- a/source/blender/blenlib/intern/math_geom.c +++ b/source/blender/blenlib/intern/math_geom.c @@ -180,7 +180,7 @@ float dist_to_line_v2(const float p[2], const float l1[2], const float l2[2]) /* distance p to line-piece v1-v2 */ float dist_squared_to_line_segment_v2(const float p[2], const float l1[2], const float l2[2]) { - float labda, rc[2], pt[2], len; + float lambda, rc[2], pt[2], len; rc[0] = l2[0] - l1[0]; rc[1] = l2[1] - l1[1]; @@ -191,18 +191,18 @@ float dist_squared_to_line_segment_v2(const float p[2], const float l1[2], const return (rc[0] * rc[0] + rc[1] * rc[1]); } - labda = (rc[0] * (p[0] - l1[0]) + rc[1] * (p[1] - l1[1])) / len; - if (labda <= 0.0f) { + lambda = (rc[0] * (p[0] - l1[0]) + rc[1] * (p[1] - l1[1])) / len; + if (lambda <= 0.0f) { pt[0] = l1[0]; pt[1] = l1[1]; } - else if (labda >= 1.0f) { + else if (lambda >= 1.0f) { pt[0] = l2[0]; pt[1] = l2[1]; } else { - pt[0] = labda * rc[0] + l1[0]; - pt[1] = labda * rc[1] + l1[1]; + pt[0] = lambda * rc[0] + l1[0]; + pt[1] = lambda * rc[1] + l1[1]; } rc[0] = pt[0] - p[0]; @@ -301,17 +301,17 @@ float dist_to_line_segment_v3(const float v1[3], const float v2[3], const float /* intersect Line-Line, shorts */ int isect_line_line_v2_int(const int v1[2], const int v2[2], const int v3[2], const int v4[2]) { - float div, labda, mu; + float div, lambda, mu; div = (float)((v2[0] - v1[0]) * (v4[1] - v3[1]) - (v2[1] - v1[1]) * (v4[0] - v3[0])); if (div == 0.0f) return ISECT_LINE_LINE_COLINEAR; - labda = ((float)(v1[1] - v3[1]) * (v4[0] - v3[0]) - (v1[0] - v3[0]) * (v4[1] - v3[1])) / div; + lambda = ((float)(v1[1] - v3[1]) * (v4[0] - v3[0]) - (v1[0] - v3[0]) * (v4[1] - v3[1])) / div; mu = ((float)(v1[1] - v3[1]) * (v2[0] - v1[0]) - (v1[0] - v3[0]) * (v2[1] - v1[1])) / div; - if (labda >= 0.0f && labda <= 1.0f && mu >= 0.0f && mu <= 1.0f) { - if (labda == 0.0f || labda == 1.0f || mu == 0.0f || mu == 1.0f) return ISECT_LINE_LINE_EXACT; + if (lambda >= 0.0f && lambda <= 1.0f && mu >= 0.0f && mu <= 1.0f) { + if (lambda == 0.0f || lambda == 1.0f || mu == 0.0f || mu == 1.0f) return ISECT_LINE_LINE_EXACT; return ISECT_LINE_LINE_CROSS; } return ISECT_LINE_LINE_NONE; @@ -335,17 +335,17 @@ int isect_line_line_v2_point(const float v1[2], const float v2[2], const float v /* intersect Line-Line, floats */ int isect_line_line_v2(const float v1[2], const float v2[2], const float v3[2], const float v4[2]) { - float div, labda, mu; + float div, lambda, mu; div = (v2[0] - v1[0]) * (v4[1] - v3[1]) - (v2[1] - v1[1]) * (v4[0] - v3[0]); if (div == 0.0f) return ISECT_LINE_LINE_COLINEAR; - labda = ((float)(v1[1] - v3[1]) * (v4[0] - v3[0]) - (v1[0] - v3[0]) * (v4[1] - v3[1])) / div; + lambda = ((float)(v1[1] - v3[1]) * (v4[0] - v3[0]) - (v1[0] - v3[0]) * (v4[1] - v3[1])) / div; mu = ((float)(v1[1] - v3[1]) * (v2[0] - v1[0]) - (v1[0] - v3[0]) * (v2[1] - v1[1])) / div; - if (labda >= 0.0f && labda <= 1.0f && mu >= 0.0f && mu <= 1.0f) { - if (labda == 0.0f || labda == 1.0f || mu == 0.0f || mu == 1.0f) return ISECT_LINE_LINE_EXACT; + if (lambda >= 0.0f && lambda <= 1.0f && mu >= 0.0f && mu <= 1.0f) { + if (lambda == 0.0f || lambda == 1.0f || mu == 0.0f || mu == 1.0f) return ISECT_LINE_LINE_EXACT; return ISECT_LINE_LINE_CROSS; } return ISECT_LINE_LINE_NONE; diff --git a/source/blender/blenlib/intern/rct.c b/source/blender/blenlib/intern/rct.c index ee073d5d309..fb767f54e55 100644 --- a/source/blender/blenlib/intern/rct.c +++ b/source/blender/blenlib/intern/rct.c @@ -109,9 +109,9 @@ static int isect_segments_i(const int v1[2], const int v2[2], const int v3[2], c return 1; /* co-linear */ } else { - const double labda = (double)((v1[1] - v3[1]) * (v4[0] - v3[0]) - (v1[0] - v3[0]) * (v4[1] - v3[1])) / div; + const double lambda = (double)((v1[1] - v3[1]) * (v4[0] - v3[0]) - (v1[0] - v3[0]) * (v4[1] - v3[1])) / div; const double mu = (double)((v1[1] - v3[1]) * (v2[0] - v1[0]) - (v1[0] - v3[0]) * (v2[1] - v1[1])) / div; - return (labda >= 0.0 && labda <= 1.0 && mu >= 0.0 && mu <= 1.0); + return (lambda >= 0.0 && lambda <= 1.0 && mu >= 0.0 && mu <= 1.0); } } static int isect_segments_fl(const float v1[2], const float v2[2], const float v3[2], const float v4[2]) @@ -121,9 +121,9 @@ static int isect_segments_fl(const float v1[2], const float v2[2], const float v return 1; /* co-linear */ } else { - const double labda = (double)((v1[1] - v3[1]) * (v4[0] - v3[0]) - (v1[0] - v3[0]) * (v4[1] - v3[1])) / div; + const double lambda = (double)((v1[1] - v3[1]) * (v4[0] - v3[0]) - (v1[0] - v3[0]) * (v4[1] - v3[1])) / div; const double mu = (double)((v1[1] - v3[1]) * (v2[0] - v1[0]) - (v1[0] - v3[0]) * (v2[1] - v1[1])) / div; - return (labda >= 0.0 && labda <= 1.0 && mu >= 0.0 && mu <= 1.0); + return (lambda >= 0.0 && lambda <= 1.0 && mu >= 0.0 && mu <= 1.0); } } diff --git a/source/blender/editors/armature/meshlaplacian.c b/source/blender/editors/armature/meshlaplacian.c index 9152ea8e198..1d97542172a 100644 --- a/source/blender/editors/armature/meshlaplacian.c +++ b/source/blender/editors/armature/meshlaplacian.c @@ -1120,7 +1120,7 @@ typedef struct MeshDeformBind { typedef struct MeshDeformIsect { float start[3]; float vec[3]; - float labda; + float lambda; void *face; int isect; @@ -1227,7 +1227,7 @@ static void harmonic_ray_callback(void *userdata, int index, const BVHTreeRay *r copy_v3_v3(hit->co, co); isec->isect = (dot_v3v3(no, ray->direction) <= 0.0f); - isec->labda = dist; + isec->lambda = dist; isec->face = mf; } } @@ -1245,7 +1245,7 @@ static MDefBoundIsect *meshdeform_ray_tree_intersect(MeshDeformBind *mdb, float /* setup isec */ memset(&isect_mdef, 0, sizeof(isect_mdef)); - isect_mdef.labda = 1e10f; + isect_mdef.lambda = 1e10f; add_v3_v3v3(isect_mdef.start, co1, epsilon); add_v3_v3v3(end, co2, epsilon); @@ -1256,7 +1256,7 @@ static MDefBoundIsect *meshdeform_ray_tree_intersect(MeshDeformBind *mdb, float if (BLI_bvhtree_ray_cast(mdb->bvhtree, isect_mdef.start, isect_mdef.vec, 0.0, &hit, harmonic_ray_callback, data) != -1) { - len = isect_mdef.labda; + len = isect_mdef.lambda; isect_mdef.face = mface = mface1 + hit.index; /* create MDefBoundIsect */ diff --git a/source/blender/editors/mesh/editmesh_knife.c b/source/blender/editors/mesh/editmesh_knife.c index a59c491fe13..f18168a25bf 100644 --- a/source/blender/editors/mesh/editmesh_knife.c +++ b/source/blender/editors/mesh/editmesh_knife.c @@ -1594,10 +1594,10 @@ static KnifeEdge *knife_find_closest_edge(KnifeTool_OpData *kcd, float p[3], flo dis = dist_to_line_segment_v2(sco, kfe->v1->sco, kfe->v2->sco); if (dis < curdis && dis < maxdist) { if (kcd->vc.rv3d->rflag & RV3D_CLIPPING) { - float labda = line_point_factor_v2(sco, kfe->v1->sco, kfe->v2->sco); + float lambda = line_point_factor_v2(sco, kfe->v1->sco, kfe->v2->sco); float vec[3]; - interp_v3_v3v3(vec, kfe->v1->cageco, kfe->v2->cageco, labda); + interp_v3_v3v3(vec, kfe->v1->cageco, kfe->v2->cageco, lambda); if (ED_view3d_clipping_test(kcd->vc.rv3d, vec, TRUE) == 0) { cure = kfe; diff --git a/source/blender/editors/mesh/editmesh_select.c b/source/blender/editors/mesh/editmesh_select.c index 3335f03ac17..1c9fc756426 100644 --- a/source/blender/editors/mesh/editmesh_select.c +++ b/source/blender/editors/mesh/editmesh_select.c @@ -464,12 +464,12 @@ static void findnearestedge__doClosest(void *userData, BMEdge *eed, const float if (distance < data->dist) { if (data->vc.rv3d->rflag & RV3D_CLIPPING) { - float labda = line_point_factor_v2(data->mval_fl, screen_co_a, screen_co_b); + float lambda = line_point_factor_v2(data->mval_fl, screen_co_a, screen_co_b); float vec[3]; - vec[0] = eed->v1->co[0] + labda * (eed->v2->co[0] - eed->v1->co[0]); - vec[1] = eed->v1->co[1] + labda * (eed->v2->co[1] - eed->v1->co[1]); - vec[2] = eed->v1->co[2] + labda * (eed->v2->co[2] - eed->v1->co[2]); + vec[0] = eed->v1->co[0] + lambda * (eed->v2->co[0] - eed->v1->co[0]); + vec[1] = eed->v1->co[1] + lambda * (eed->v2->co[1] - eed->v1->co[1]); + vec[2] = eed->v1->co[2] + lambda * (eed->v2->co[2] - eed->v1->co[2]); if (ED_view3d_clipping_test(data->vc.rv3d, vec, TRUE) == 0) { data->dist = distance; diff --git a/source/blender/render/intern/raytrace/rayobject_octree.cpp b/source/blender/render/intern/raytrace/rayobject_octree.cpp index afb8fe6c3b5..7800a7da370 100644 --- a/source/blender/render/intern/raytrace/rayobject_octree.cpp +++ b/source/blender/render/intern/raytrace/rayobject_octree.cpp @@ -326,7 +326,7 @@ static void d2dda(Octree *oc, short b1, short b2, short c1, short c2, char *ocfa int ocx1, ocx2, ocy1, ocy2; int x, y, dx = 0, dy = 0; float ox1, ox2, oy1, oy2; - float labda, labdao, labdax, labday, ldx, ldy; + float lambda, lambda_o, lambda_x, lambda_y, ldx, ldy; ocx1 = rts[b1][c1]; ocy1 = rts[b1][c2]; @@ -345,40 +345,40 @@ static void d2dda(Octree *oc, short b1, short b2, short c1, short c2, char *ocfa if (ox1 != ox2) { if (ox2 - ox1 > 0.0f) { - labdax = (ox1 - ocx1 - 1.0f) / (ox1 - ox2); + lambda_x = (ox1 - ocx1 - 1.0f) / (ox1 - ox2); ldx = -1.0f / (ox1 - ox2); dx = 1; } else { - labdax = (ox1 - ocx1) / (ox1 - ox2); + lambda_x = (ox1 - ocx1) / (ox1 - ox2); ldx = 1.0f / (ox1 - ox2); dx = -1; } } else { - labdax = 1.0f; + lambda_x = 1.0f; ldx = 0; } if (oy1 != oy2) { if (oy2 - oy1 > 0.0f) { - labday = (oy1 - ocy1 - 1.0f) / (oy1 - oy2); + lambda_y = (oy1 - ocy1 - 1.0f) / (oy1 - oy2); ldy = -1.0f / (oy1 - oy2); dy = 1; } else { - labday = (oy1 - ocy1) / (oy1 - oy2); + lambda_y = (oy1 - ocy1) / (oy1 - oy2); ldy = 1.0f / (oy1 - oy2); dy = -1; } } else { - labday = 1.0f; + lambda_y = 1.0f; ldy = 0; } x = ocx1; y = ocy1; - labda = MIN2(labdax, labday); + lambda = MIN2(lambda_x, lambda_y); while (TRUE) { @@ -389,26 +389,26 @@ static void d2dda(Octree *oc, short b1, short b2, short c1, short c2, char *ocfa ocface[oc->ocres * x + y] = 1; } - labdao = labda; - if (labdax == labday) { - labdax += ldx; + lambda_o = lambda; + if (lambda_x == lambda_y) { + lambda_x += ldx; x += dx; - labday += ldy; + lambda_y += ldy; y += dy; } else { - if (labdax < labday) { - labdax += ldx; + if (lambda_x < lambda_y) { + lambda_x += ldx; x += dx; } else { - labday += ldy; + lambda_y += ldy; y += dy; } } - labda = MIN2(labdax, labday); - if (labda == labdao) break; - if (labda >= 1.0f) break; + lambda = MIN2(lambda_x, lambda_y); + if (lambda == lambda_o) break; + if (lambda >= 1.0f) break; } ocface[oc->ocres * ocx2 + ocy2] = 1; } @@ -851,8 +851,8 @@ static int RE_rayobject_octree_intersect(RayObject *tree, Isect *is) OcVal ocval; float vec1[3], vec2[3], start[3], end[3]; float u1, u2, ox1, ox2, oy1, oy2, oz1, oz2; - float labdao, labdax, ldx, labday, ldy, labdaz, ldz, ddalabda; - float olabda = 0; + float lambda_o, lambda_x, ldx, lambda_y, ldy, lambda_z, ldz, dda_lambda; + float o_lambda = 0; int dx, dy, dz; int xo, yo, zo, c1 = 0; int ocx1, ocx2, ocy1, ocy2, ocz1, ocz2; @@ -871,7 +871,7 @@ static int RE_rayobject_octree_intersect(RayObject *tree, Isect *is) copy_v3_v3(start, is->start); madd_v3_v3v3fl(end, is->start, is->dir, is->dist); ldx = is->dir[0] * is->dist; - olabda = is->dist; + o_lambda = is->dist; u1 = 0.0f; u2 = 1.0f; @@ -939,68 +939,68 @@ static int RE_rayobject_octree_intersect(RayObject *tree, Isect *is) float dox, doy, doz; int eqval; - /* calc labda en ld */ + /* calc lambda en ld */ dox = ox1 - ox2; doy = oy1 - oy2; doz = oz1 - oz2; if (dox < -FLT_EPSILON) { ldx = -1.0f / dox; - labdax = (ocx1 - ox1 + 1.0f) * ldx; + lambda_x = (ocx1 - ox1 + 1.0f) * ldx; dx = 1; } else if (dox > FLT_EPSILON) { ldx = 1.0f / dox; - labdax = (ox1 - ocx1) * ldx; + lambda_x = (ox1 - ocx1) * ldx; dx = -1; } else { - labdax = 1.0f; + lambda_x = 1.0f; ldx = 0; dx = 0; } if (doy < -FLT_EPSILON) { ldy = -1.0f / doy; - labday = (ocy1 - oy1 + 1.0f) * ldy; + lambda_y = (ocy1 - oy1 + 1.0f) * ldy; dy = 1; } else if (doy > FLT_EPSILON) { ldy = 1.0f / doy; - labday = (oy1 - ocy1) * ldy; + lambda_y = (oy1 - ocy1) * ldy; dy = -1; } else { - labday = 1.0f; + lambda_y = 1.0f; ldy = 0; dy = 0; } if (doz < -FLT_EPSILON) { ldz = -1.0f / doz; - labdaz = (ocz1 - oz1 + 1.0f) * ldz; + lambda_z = (ocz1 - oz1 + 1.0f) * ldz; dz = 1; } else if (doz > FLT_EPSILON) { ldz = 1.0f / doz; - labdaz = (oz1 - ocz1) * ldz; + lambda_z = (oz1 - ocz1) * ldz; dz = -1; } else { - labdaz = 1.0f; + lambda_z = 1.0f; ldz = 0; dz = 0; } xo = ocx1; yo = ocy1; zo = ocz1; - ddalabda = MIN3(labdax, labday, labdaz); + dda_lambda = MIN3(lambda_x, lambda_y, lambda_z); vec2[0] = ox1; vec2[1] = oy1; vec2[2] = oz1; /* this loop has been constructed to make sure the first and last node of ray - * are always included, even when ddalabda==1.0f or larger */ + * are always included, even when dda_lambda==1.0f or larger */ while (TRUE) { @@ -1010,83 +1010,83 @@ static int RE_rayobject_octree_intersect(RayObject *tree, Isect *is) /* calculate ray intersection with octree node */ copy_v3_v3(vec1, vec2); // dox, y, z is negative - vec2[0] = ox1 - ddalabda * dox; - vec2[1] = oy1 - ddalabda * doy; - vec2[2] = oz1 - ddalabda * doz; + vec2[0] = ox1 - dda_lambda * dox; + vec2[1] = oy1 - dda_lambda * doy; + vec2[2] = oz1 - dda_lambda * doz; calc_ocval_ray(&ocval, (float)xo, (float)yo, (float)zo, vec1, vec2); - //is->dist = (u1+ddalabda*(u2-u1))*olabda; + //is->dist = (u1+dda_lambda*(u2-u1))*o_lambda; if (testnode(oc, is, no, ocval) ) found = 1; - if (is->dist < (u1 + ddalabda * (u2 - u1)) * olabda) + if (is->dist < (u1 + dda_lambda * (u2 - u1)) * o_lambda) return found; } - labdao = ddalabda; + lambda_o = dda_lambda; /* traversing octree nodes need careful detection of smallest values, with proper - * exceptions for equal labdas */ - eqval = (labdax == labday); - if (labday == labdaz) eqval += 2; - if (labdax == labdaz) eqval += 4; + * exceptions for equal lambdas */ + eqval = (lambda_x == lambda_y); + if (lambda_y == lambda_z) eqval += 2; + if (lambda_x == lambda_z) eqval += 4; if (eqval) { // only 4 cases exist! if (eqval == 7) { // x=y=z - xo += dx; labdax += ldx; - yo += dy; labday += ldy; - zo += dz; labdaz += ldz; + xo += dx; lambda_x += ldx; + yo += dy; lambda_y += ldy; + zo += dz; lambda_z += ldz; } else if (eqval == 1) { // x=y - if (labday < labdaz) { - xo += dx; labdax += ldx; - yo += dy; labday += ldy; + if (lambda_y < lambda_z) { + xo += dx; lambda_x += ldx; + yo += dy; lambda_y += ldy; } else { - zo += dz; labdaz += ldz; + zo += dz; lambda_z += ldz; } } else if (eqval == 2) { // y=z - if (labdax < labday) { - xo += dx; labdax += ldx; + if (lambda_x < lambda_y) { + xo += dx; lambda_x += ldx; } else { - yo += dy; labday += ldy; - zo += dz; labdaz += ldz; + yo += dy; lambda_y += ldy; + zo += dz; lambda_z += ldz; } } else { // x=z - if (labday < labdax) { - yo += dy; labday += ldy; + if (lambda_y < lambda_x) { + yo += dy; lambda_y += ldy; } else { - xo += dx; labdax += ldx; - zo += dz; labdaz += ldz; + xo += dx; lambda_x += ldx; + zo += dz; lambda_z += ldz; } } } else { // all three different, just three cases exist - eqval = (labdax < labday); - if (labday < labdaz) eqval += 2; - if (labdax < labdaz) eqval += 4; + eqval = (lambda_x < lambda_y); + if (lambda_y < lambda_z) eqval += 2; + if (lambda_x < lambda_z) eqval += 4; if (eqval == 7 || eqval == 5) { // x smallest - xo += dx; labdax += ldx; + xo += dx; lambda_x += ldx; } else if (eqval == 2 || eqval == 6) { // y smallest - yo += dy; labday += ldy; + yo += dy; lambda_y += ldy; } else { // z smallest - zo += dz; labdaz += ldz; + zo += dz; lambda_z += ldz; } } - ddalabda = MIN3(labdax, labday, labdaz); - if (ddalabda == labdao) break; + dda_lambda = MIN3(lambda_x, lambda_y, lambda_z); + if (dda_lambda == lambda_o) break; /* to make sure the last node is always checked */ - if (labdao >= 1.0f) break; + if (lambda_o >= 1.0f) break; } } diff --git a/source/blender/render/intern/source/envmap.c b/source/blender/render/intern/source/envmap.c index c3126e57b53..e04035e0c2b 100644 --- a/source/blender/render/intern/source/envmap.c +++ b/source/blender/render/intern/source/envmap.c @@ -587,53 +587,53 @@ void make_envmaps(Render *re) static int envcube_isect(EnvMap *env, const float vec[3], float answ[2]) { - float labda; + float lambda; int face; if (env->type == ENV_PLANE) { face = 1; - labda = 1.0f / vec[2]; - answ[0] = env->viewscale * labda * vec[0]; - answ[1] = -env->viewscale * labda * vec[1]; + lambda = 1.0f / vec[2]; + answ[0] = env->viewscale * lambda * vec[0]; + answ[1] = -env->viewscale * lambda * vec[1]; } else { /* which face */ if (vec[2] <= -fabsf(vec[0]) && vec[2] <= -fabsf(vec[1]) ) { face = 0; - labda = -1.0f / vec[2]; - answ[0] = labda * vec[0]; - answ[1] = labda * vec[1]; + lambda = -1.0f / vec[2]; + answ[0] = lambda * vec[0]; + answ[1] = lambda * vec[1]; } else if (vec[2] >= fabsf(vec[0]) && vec[2] >= fabsf(vec[1])) { face = 1; - labda = 1.0f / vec[2]; - answ[0] = labda * vec[0]; - answ[1] = -labda * vec[1]; + lambda = 1.0f / vec[2]; + answ[0] = lambda * vec[0]; + answ[1] = -lambda * vec[1]; } else if (vec[1] >= fabsf(vec[0])) { face = 2; - labda = 1.0f / vec[1]; - answ[0] = labda * vec[0]; - answ[1] = labda * vec[2]; + lambda = 1.0f / vec[1]; + answ[0] = lambda * vec[0]; + answ[1] = lambda * vec[2]; } else if (vec[0] <= -fabsf(vec[1])) { face = 3; - labda = -1.0f / vec[0]; - answ[0] = labda * vec[1]; - answ[1] = labda * vec[2]; + lambda = -1.0f / vec[0]; + answ[0] = lambda * vec[1]; + answ[1] = lambda * vec[2]; } else if (vec[1] <= -fabsf(vec[0])) { face = 4; - labda = -1.0f / vec[1]; - answ[0] = -labda * vec[0]; - answ[1] = labda * vec[2]; + lambda = -1.0f / vec[1]; + answ[0] = -lambda * vec[0]; + answ[1] = lambda * vec[2]; } else { face = 5; - labda = 1.0f / vec[0]; - answ[0] = -labda * vec[1]; - answ[1] = labda * vec[2]; + lambda = 1.0f / vec[0]; + answ[0] = -lambda * vec[1]; + answ[1] = lambda * vec[2]; } } diff --git a/source/blender/render/intern/source/shadbuf.c b/source/blender/render/intern/source/shadbuf.c index a7f6b40981d..078c11a2061 100644 --- a/source/blender/render/intern/source/shadbuf.c +++ b/source/blender/render/intern/source/shadbuf.c @@ -1302,7 +1302,7 @@ float shadow_halo(LampRen *lar, const float p1[3], const float p2[3]) ShadBuf *shb= lar->shb; ShadSampleBuf *shsample; float co[4], siz; - float labda, labdao, labdax, labday, ldx, ldy; + float lambda, lambda_o, lambda_x, lambda_y, ldx, ldy; float zf, xf1, yf1, zf1, xf2, yf2, zf2; float count, lightcount; int x, y, z, xs1, ys1; @@ -1336,68 +1336,68 @@ float shadow_halo(LampRen *lar, const float p1[3], const float p2[3]) if (xf1 != xf2) { if (xf2-xf1 > 0.0f) { - labdax= (xf1-xs1-1.0f)/(xf1-xf2); + lambda_x= (xf1-xs1-1.0f)/(xf1-xf2); ldx= -shb->shadhalostep/(xf1-xf2); dx= shb->shadhalostep; } else { - labdax= (xf1-xs1)/(xf1-xf2); + lambda_x= (xf1-xs1)/(xf1-xf2); ldx= shb->shadhalostep/(xf1-xf2); dx= -shb->shadhalostep; } } else { - labdax= 1.0; + lambda_x= 1.0; ldx= 0.0; } if (yf1 != yf2) { if (yf2-yf1 > 0.0f) { - labday= (yf1-ys1-1.0f)/(yf1-yf2); + lambda_y= (yf1-ys1-1.0f)/(yf1-yf2); ldy= -shb->shadhalostep/(yf1-yf2); dy= shb->shadhalostep; } else { - labday= (yf1-ys1)/(yf1-yf2); + lambda_y= (yf1-ys1)/(yf1-yf2); ldy= shb->shadhalostep/(yf1-yf2); dy= -shb->shadhalostep; } } else { - labday= 1.0; + lambda_y= 1.0; ldy= 0.0; } x= xs1; y= ys1; - labda= count= lightcount= 0.0; + lambda= count= lightcount= 0.0; /* printf("start %x %x \n", (int)(0x7FFFFFFF*zf1), (int)(0x7FFFFFFF*zf2)); */ while (1) { - labdao= labda; + lambda_o= lambda; - if (labdax==labday) { - labdax+= ldx; + if (lambda_x==lambda_y) { + lambda_x+= ldx; x+= dx; - labday+= ldy; + lambda_y+= ldy; y+= dy; } else { - if (labdax=1.0f) break; + lambda = min_ff(lambda_x, lambda_y); + if (lambda==lambda_o || lambda>=1.0f) break; - zf= zf1 + labda*(zf2-zf1); + zf= zf1 + lambda*(zf2-zf1); count+= (float)shb->totbuf; if (zf<= -1.0f) lightcount += 1.0f; /* close to the spot */ @@ -1686,21 +1686,21 @@ static int point_behind_strand(const float p[3], BSPFace *face) return 1; } else { - float labda= ( face->rc[0]*(p[0]-face->vec1[0]) + face->rc[1]*(p[1]-face->vec1[1]) )*face->len; + float lambda= ( face->rc[0]*(p[0]-face->vec1[0]) + face->rc[1]*(p[1]-face->vec1[1]) )*face->len; - if (labda > -face->radline_end && labda < 1.0f+face->radline_end) { + if (lambda > -face->radline_end && lambda < 1.0f+face->radline_end) { /* hesse for dist: */ //dist= (float)(fabs( (p[0]-vec2[0])*rc[1] + (p[1]-vec2[1])*rc[0])/len); - pt[0]= labda*face->rc[0]+face->vec1[0]; - pt[1]= labda*face->rc[1]+face->vec1[1]; + pt[0]= lambda*face->rc[0]+face->vec1[0]; + pt[1]= lambda*face->rc[1]+face->vec1[1]; rc[0]= pt[0]-p[0]; rc[1]= pt[1]-p[1]; dist= (float)sqrt(rc[0]*rc[0]+ rc[1]*rc[1]); if (dist < face->radline) { - float zval= face->vec1[2] + labda*face->rc[2]; + float zval= face->vec1[2] + lambda*face->rc[2]; if (p[2] > zval) return 1; } diff --git a/source/blender/render/intern/source/zbuf.c b/source/blender/render/intern/source/zbuf.c index c52fb84a7f8..2335725ee65 100644 --- a/source/blender/render/intern/source/zbuf.c +++ b/source/blender/render/intern/source/zbuf.c @@ -1600,8 +1600,8 @@ void zspan_scanconvert(ZSpan *zspan, void *handle, float *v1, float *v2, float * /** * (clip pyramid) - * Sets labda: flag, and parametrize the clipping of vertices in - * viewspace coordinates. labda = -1 means no clipping, labda in [0, 1] means a clipping. + * Sets lambda: flag, and parametrize the clipping of vertices in + * viewspace coordinates. lambda = -1 means no clipping, lambda in [0, 1] means a clipping. * Note: uses globals. * \param v1 start coordinate s * \param v2 target coordinate t @@ -1611,13 +1611,13 @@ void zspan_scanconvert(ZSpan *zspan, void *handle, float *v1, float *v2, float * * \param a index for coordinate (x, y, or z) */ -static void clippyra(float *labda, float *v1, float *v2, int *b2, int *b3, int a, float clipcrop) +static void clippyra(float *lambda, float *v1, float *v2, int *b2, int *b3, int a, float clipcrop) { float da, dw, u1=0.0, u2=1.0; float v13; - labda[0]= -1.0; - labda[1]= -1.0; + lambda[0]= -1.0; + lambda[1]= -1.0; da= v2[a]-v1[a]; /* prob; we clip slightly larger, osa renders add 2 pixels on edges, should become variable? */ @@ -1641,16 +1641,16 @@ static void clippyra(float *labda, float *v1, float *v2, int *b2, int *b3, int a if (cliptestf(da, -dw, v13, -v1[a], &u1, &u2)) { *b3=1; if (u2<1.0f) { - labda[1]= u2; + lambda[1]= u2; *b2=1; } - else labda[1]=1.0; /* u2 */ + else lambda[1]=1.0; /* u2 */ if (u1>0.0f) { - labda[0] = u1; + lambda[0] = u1; *b2 = 1; } else { - labda[0] = 0.0; + lambda[0] = 0.0; } } } @@ -1658,8 +1658,8 @@ static void clippyra(float *labda, float *v1, float *v2, int *b2, int *b3, int a /** * (make vertex pyramide clip) - * Checks labda and uses this to make decision about clipping the line - * segment from v1 to v2. labda is the factor by which the vector is + * Checks lambda and uses this to make decision about clipping the line + * segment from v1 to v2. lambda is the factor by which the vector is * cut. ( calculate s + l * ( t - s )). The result is appended to the * vertex list of this face. * @@ -1671,12 +1671,12 @@ static void clippyra(float *labda, float *v1, float *v2, int *b2, int *b3, int a * \param clve vertex vector. */ -static void makevertpyra(float *vez, float *labda, float **trias, float *v1, float *v2, int *b1, int *clve) +static void makevertpyra(float *vez, float *lambda, float **trias, float *v1, float *v2, int *b1, int *clve) { float l1, l2, *adr; - l1= labda[0]; - l2= labda[1]; + l1= lambda[0]; + l2= lambda[1]; if (l1!= -1.0f) { if (l1!= 0.0f) { @@ -1847,7 +1847,7 @@ void zbuf_make_winmat(Render *re, float winmat[][4]) void zbufclip(ZSpan *zspan, int obi, int zvlnr, float *f1, float *f2, float *f3, int c1, int c2, int c3) { - float *vlzp[32][3], labda[3][2]; + float *vlzp[32][3], lambda[3][2]; float vez[400], *trias[40]; if (c1 | c2 | c3) { /* not in middle */ @@ -1887,9 +1887,9 @@ void zbufclip(ZSpan *zspan, int obi, int zvlnr, float *f1, float *f2, float *f3, else if (b==1) arg= 0; else arg= 1; - clippyra(labda[0], vlzp[v][0], vlzp[v][1], &b2, &b3, arg, zspan->clipcrop); - clippyra(labda[1], vlzp[v][1], vlzp[v][2], &b2, &b3, arg, zspan->clipcrop); - clippyra(labda[2], vlzp[v][2], vlzp[v][0], &b2, &b3, arg, zspan->clipcrop); + clippyra(lambda[0], vlzp[v][0], vlzp[v][1], &b2, &b3, arg, zspan->clipcrop); + clippyra(lambda[1], vlzp[v][1], vlzp[v][2], &b2, &b3, arg, zspan->clipcrop); + clippyra(lambda[2], vlzp[v][2], vlzp[v][0], &b2, &b3, arg, zspan->clipcrop); if (b2==0 && b3==1) { /* completely 'in', but we copy because of last for () loop in this section */; @@ -1905,9 +1905,9 @@ void zbufclip(ZSpan *zspan, int obi, int zvlnr, float *f1, float *f2, float *f3, } else { b1=0; - makevertpyra(vez, labda[0], trias, vlzp[v][0], vlzp[v][1], &b1, &clve); - makevertpyra(vez, labda[1], trias, vlzp[v][1], vlzp[v][2], &b1, &clve); - makevertpyra(vez, labda[2], trias, vlzp[v][2], vlzp[v][0], &b1, &clve); + makevertpyra(vez, lambda[0], trias, vlzp[v][0], vlzp[v][1], &b1, &clve); + makevertpyra(vez, lambda[1], trias, vlzp[v][1], vlzp[v][2], &b1, &clve); + makevertpyra(vez, lambda[2], trias, vlzp[v][2], vlzp[v][0], &b1, &clve); /* after front clip done: now set clip flags */ if (b==0) { From 5943c81a937dcf3f18c09923938bdb0b6d352f77 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 11 Dec 2012 14:19:41 +0000 Subject: [PATCH 012/252] code cleanup: neareast -> nearest --- source/blender/blenkernel/intern/seqeffects.c | 2 +- source/blender/blenkernel/intern/tracking.c | 6 +++--- source/blender/compositor/operations/COM_ImageOperation.cpp | 4 ++-- .../compositor/operations/COM_MovieClipOperation.cpp | 2 +- .../compositor/operations/COM_MultilayerImageOperation.cpp | 2 +- source/blender/imbuf/IMB_imbuf.h | 4 ++-- source/blender/imbuf/intern/imageprocess.c | 6 +++--- source/blender/makesdna/DNA_tracking_types.h | 2 +- source/blender/makesrna/intern/rna_tracking.c | 2 +- .../blender/nodes/composite/nodes/node_composite_rotate.c | 2 +- .../nodes/composite/nodes/node_composite_transform.c | 2 +- 11 files changed, 17 insertions(+), 17 deletions(-) diff --git a/source/blender/blenkernel/intern/seqeffects.c b/source/blender/blenkernel/intern/seqeffects.c index 0b7fdaa7c1d..3bff209f53c 100644 --- a/source/blender/blenkernel/intern/seqeffects.c +++ b/source/blender/blenkernel/intern/seqeffects.c @@ -1745,7 +1745,7 @@ static void transform_image(int x, int y, ImBuf *ibuf1, ImBuf *out, float scale /* interpolate */ switch (interpolation) { case 0: - neareast_interpolation(ibuf1, out, xt, yt, xi, yi); + nearest_interpolation(ibuf1, out, xt, yt, xi, yi); break; case 1: bilinear_interpolation(ibuf1, out, xt, yt, xi, yi); diff --git a/source/blender/blenkernel/intern/tracking.c b/source/blender/blenkernel/intern/tracking.c index 30b48401046..801fecc9f7c 100644 --- a/source/blender/blenkernel/intern/tracking.c +++ b/source/blender/blenkernel/intern/tracking.c @@ -3462,15 +3462,15 @@ ImBuf *BKE_tracking_stabilize_frame(MovieTracking *tracking, int framenr, ImBuf BKE_tracking_stabilization_data_to_mat4(ibuf->x, ibuf->y, aspect, tloc, tscale, tangle, mat); invert_m4(mat); - if (filter == TRACKING_FILTER_NEAREAST) - interpolation = neareast_interpolation; + if (filter == TRACKING_FILTER_NEAREST) + interpolation = nearest_interpolation; else if (filter == TRACKING_FILTER_BILINEAR) interpolation = bilinear_interpolation; else if (filter == TRACKING_FILTER_BICUBIC) interpolation = bicubic_interpolation; else /* fallback to default interpolation method */ - interpolation = neareast_interpolation; + interpolation = nearest_interpolation; for (j = 0; j < tmpibuf->y; j++) { for (i = 0; i < tmpibuf->x; i++) { diff --git a/source/blender/compositor/operations/COM_ImageOperation.cpp b/source/blender/compositor/operations/COM_ImageOperation.cpp index 84557118a1c..c8e3dbf993d 100644 --- a/source/blender/compositor/operations/COM_ImageOperation.cpp +++ b/source/blender/compositor/operations/COM_ImageOperation.cpp @@ -120,7 +120,7 @@ void ImageOperation::executePixel(float output[4], float x, float y, PixelSample else { switch (sampler) { case COM_PS_NEAREST: - neareast_interpolation_color(this->m_buffer, NULL, output, x, y); + nearest_interpolation_color(this->m_buffer, NULL, output, x, y); break; case COM_PS_BILINEAR: bilinear_interpolation_color(this->m_buffer, NULL, output, x, y); @@ -143,7 +143,7 @@ void ImageAlphaOperation::executePixel(float output[4], float x, float y, PixelS tempcolor[3] = 1.0f; switch (sampler) { case COM_PS_NEAREST: - neareast_interpolation_color(this->m_buffer, NULL, tempcolor, x, y); + nearest_interpolation_color(this->m_buffer, NULL, tempcolor, x, y); break; case COM_PS_BILINEAR: bilinear_interpolation_color(this->m_buffer, NULL, tempcolor, x, y); diff --git a/source/blender/compositor/operations/COM_MovieClipOperation.cpp b/source/blender/compositor/operations/COM_MovieClipOperation.cpp index 709e4b7d4b0..74761f00e1f 100644 --- a/source/blender/compositor/operations/COM_MovieClipOperation.cpp +++ b/source/blender/compositor/operations/COM_MovieClipOperation.cpp @@ -95,7 +95,7 @@ void MovieClipOperation::executePixel(float output[4], float x, float y, PixelSa else { switch (sampler) { case COM_PS_NEAREST: - neareast_interpolation_color(this->m_movieClipBuffer, NULL, output, x, y); + nearest_interpolation_color(this->m_movieClipBuffer, NULL, output, x, y); break; case COM_PS_BILINEAR: bilinear_interpolation_color(this->m_movieClipBuffer, NULL, output, x, y); diff --git a/source/blender/compositor/operations/COM_MultilayerImageOperation.cpp b/source/blender/compositor/operations/COM_MultilayerImageOperation.cpp index af0d5161835..1c9dd0f170e 100644 --- a/source/blender/compositor/operations/COM_MultilayerImageOperation.cpp +++ b/source/blender/compositor/operations/COM_MultilayerImageOperation.cpp @@ -54,7 +54,7 @@ void MultilayerColorOperation::executePixel(float output[4], float x, float y, P if (this->m_numberOfChannels == 4) { switch (sampler) { case COM_PS_NEAREST: - neareast_interpolation_color(this->m_buffer, NULL, output, x, y); + nearest_interpolation_color(this->m_buffer, NULL, output, x, y); break; case COM_PS_BILINEAR: bilinear_interpolation_color(this->m_buffer, NULL, output, x, y); diff --git a/source/blender/imbuf/IMB_imbuf.h b/source/blender/imbuf/IMB_imbuf.h index d0ac71a7131..db1404813b1 100644 --- a/source/blender/imbuf/IMB_imbuf.h +++ b/source/blender/imbuf/IMB_imbuf.h @@ -407,11 +407,11 @@ void IMB_convert_rgba_to_abgr(struct ImBuf *ibuf); * \attention defined in imageprocess.c */ void bicubic_interpolation(struct ImBuf *in, struct ImBuf *out, float u, float v, int xout, int yout); -void neareast_interpolation(struct ImBuf *in, struct ImBuf *out, float u, float v, int xout, int yout); +void nearest_interpolation(struct ImBuf *in, struct ImBuf *out, float u, float v, int xout, int yout); void bilinear_interpolation(struct ImBuf *in, struct ImBuf *out, float u, float v, int xout, int yout); void bicubic_interpolation_color(struct ImBuf *in, unsigned char col[4], float col_float[4], float u, float v); -void neareast_interpolation_color(struct ImBuf *in, unsigned char col[4], float col_float[4], float u, float v); +void nearest_interpolation_color(struct ImBuf *in, unsigned char col[4], float col_float[4], float u, float v); void bilinear_interpolation_color(struct ImBuf *in, unsigned char col[4], float col_float[4], float u, float v); void bilinear_interpolation_color_wrap(struct ImBuf *in, unsigned char col[4], float col_float[4], float u, float v); diff --git a/source/blender/imbuf/intern/imageprocess.c b/source/blender/imbuf/intern/imageprocess.c index a185c4ee3e0..92b8dd8c724 100644 --- a/source/blender/imbuf/intern/imageprocess.c +++ b/source/blender/imbuf/intern/imageprocess.c @@ -219,7 +219,7 @@ void bilinear_interpolation(ImBuf *in, ImBuf *out, float u, float v, int xout, i /* function assumes out to be zero'ed, only does RGBA */ /* NEAREST INTERPOLATION */ -void neareast_interpolation_color(struct ImBuf *in, unsigned char outI[4], float outF[4], float u, float v) +void nearest_interpolation_color(struct ImBuf *in, unsigned char outI[4], float outF[4], float u, float v) { float *dataF; unsigned char *dataI; @@ -268,7 +268,7 @@ void neareast_interpolation_color(struct ImBuf *in, unsigned char outI[4], float } } -void neareast_interpolation(ImBuf *in, ImBuf *out, float x, float y, int xout, int yout) +void nearest_interpolation(ImBuf *in, ImBuf *out, float x, float y, int xout, int yout) { unsigned char *outI = NULL; float *outF = NULL; @@ -279,7 +279,7 @@ void neareast_interpolation(ImBuf *in, ImBuf *out, float x, float y, int xout, i pixel_from_buffer(out, &outI, &outF, xout, yout); /* gcc warns these could be uninitialized, but its ok */ - neareast_interpolation_color(in, outI, outF, x, y); + nearest_interpolation_color(in, outI, outF, x, y); } /*********************** Threaded image processing *************************/ diff --git a/source/blender/makesdna/DNA_tracking_types.h b/source/blender/makesdna/DNA_tracking_types.h index 12819303b26..b258fbaa668 100644 --- a/source/blender/makesdna/DNA_tracking_types.h +++ b/source/blender/makesdna/DNA_tracking_types.h @@ -373,7 +373,7 @@ enum { /* MovieTrackingStrabilization->filter */ enum { - TRACKING_FILTER_NEAREAST = 0, + TRACKING_FILTER_NEAREST = 0, TRACKING_FILTER_BILINEAR = 1, TRACKING_FILTER_BICUBIC = 2 }; diff --git a/source/blender/makesrna/intern/rna_tracking.c b/source/blender/makesrna/intern/rna_tracking.c index 4aefaf991d2..f5bcab3e530 100644 --- a/source/blender/makesrna/intern/rna_tracking.c +++ b/source/blender/makesrna/intern/rna_tracking.c @@ -1161,7 +1161,7 @@ static void rna_def_trackingStabilization(BlenderRNA *brna) PropertyRNA *prop; static EnumPropertyItem filter_items[] = { - {TRACKING_FILTER_NEAREAST, "NEAREST", 0, "Nearest", ""}, + {TRACKING_FILTER_NEAREST, "NEAREST", 0, "Nearest", ""}, {TRACKING_FILTER_BILINEAR, "BILINEAR", 0, "Bilinear", ""}, {TRACKING_FILTER_BICUBIC, "BICUBIC", 0, "Bicubic", ""}, {0, NULL, 0, NULL, NULL} diff --git a/source/blender/nodes/composite/nodes/node_composite_rotate.c b/source/blender/nodes/composite/nodes/node_composite_rotate.c index 9a76764b97e..50c8b2a78c1 100644 --- a/source/blender/nodes/composite/nodes/node_composite_rotate.c +++ b/source/blender/nodes/composite/nodes/node_composite_rotate.c @@ -91,7 +91,7 @@ static void node_composit_exec_rotate(void *UNUSED(data), bNode *node, bNodeStac switch (node->custom1) { case 0: - neareast_interpolation(ibuf, obuf, u, v, xo, yo); + nearest_interpolation(ibuf, obuf, u, v, xo, yo); break; case 1: bilinear_interpolation(ibuf, obuf, u, v, xo, yo); diff --git a/source/blender/nodes/composite/nodes/node_composite_transform.c b/source/blender/nodes/composite/nodes/node_composite_transform.c index a8ef0286f2f..d6bb545cd5c 100644 --- a/source/blender/nodes/composite/nodes/node_composite_transform.c +++ b/source/blender/nodes/composite/nodes/node_composite_transform.c @@ -93,7 +93,7 @@ CompBuf* node_composit_transform(CompBuf *cbuf, float x, float y, float angle, f switch (filter_type) { case 0: - neareast_interpolation(ibuf, obuf, vec[0], vec[1], i, j); + nearest_interpolation(ibuf, obuf, vec[0], vec[1], i, j); break; case 1: bilinear_interpolation(ibuf, obuf, vec[0], vec[1], i, j); From dfa662f53ae4562ccd44d8d8ba59c93bab2ff321 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 11 Dec 2012 14:20:29 +0000 Subject: [PATCH 013/252] use const char for display device --- source/blender/editors/interface/interface_intern.h | 2 +- source/blender/editors/interface/interface_regions.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/source/blender/editors/interface/interface_intern.h b/source/blender/editors/interface/interface_intern.h index 23d3810e058..1dc98639fe7 100644 --- a/source/blender/editors/interface/interface_intern.h +++ b/source/blender/editors/interface/interface_intern.h @@ -358,7 +358,7 @@ struct uiBlock { char color_profile; /* color profile for correcting linear colors for display */ - char *display_device; /* display device name used to display this block, + const char *display_device; /* display device name used to display this block, * used by color widgets to transform colors from/to scene linear */ }; diff --git a/source/blender/editors/interface/interface_regions.c b/source/blender/editors/interface/interface_regions.c index c13aadee069..b62e634b1eb 100644 --- a/source/blender/editors/interface/interface_regions.c +++ b/source/blender/editors/interface/interface_regions.c @@ -2240,7 +2240,7 @@ uiBlock *ui_block_func_COLOR(bContext *C, uiPopupBlockHandle *handle, void *arg_ /************************ Popup Menu Memory ****************************/ -static int ui_popup_string_hash(char *str) +static int ui_popup_string_hash(const char *str) { /* sometimes button contains hotkey, sometimes not, strip for proper compare */ int hash; From 06d5747ff3406a41633a17bac64d1150453c516c Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 11 Dec 2012 14:21:52 +0000 Subject: [PATCH 014/252] was using max short on a float in EDBM_face_find_nearest() --- source/blender/editors/mesh/editmesh_select.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/editors/mesh/editmesh_select.c b/source/blender/editors/mesh/editmesh_select.c index 1c9fc756426..a98345cacec 100644 --- a/source/blender/editors/mesh/editmesh_select.c +++ b/source/blender/editors/mesh/editmesh_select.c @@ -573,7 +573,7 @@ BMFace *EDBM_face_find_nearest(ViewContext *vc, float *r_dist) data.mval_fl[0] = vc->mval[0]; data.mval_fl[1] = vc->mval[1]; - data.dist = 0x7FFF; /* largest short */ + data.dist = FLT_MAX; data.toFace = efa; mesh_foreachScreenFace(vc, findnearestface__getDistance, &data, V3D_PROJ_TEST_CLIP_DEFAULT); From e2f0a1e4db1ac13f20bc540ef3c7268676e14a30 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 11 Dec 2012 14:24:27 +0000 Subject: [PATCH 015/252] own cleanup commit in bmesh branch - removed last letters from ends of some comments. --- source/blender/bmesh/intern/bmesh_core.c | 24 +++++++++---------- source/blender/bmesh/intern/bmesh_mods.c | 16 ++++++------- source/blender/bmesh/intern/bmesh_opdefines.c | 16 ++++++------- source/blender/bmesh/intern/bmesh_operators.c | 18 +++++++------- source/blender/bmesh/intern/bmesh_polygon.c | 2 +- source/blender/bmesh/operators/bmo_create.c | 2 +- .../bmesh/operators/bmo_join_triangles.c | 4 ++-- source/blender/bmesh/tools/BME_bevel.c | 2 +- 8 files changed, 42 insertions(+), 42 deletions(-) diff --git a/source/blender/bmesh/intern/bmesh_core.c b/source/blender/bmesh/intern/bmesh_core.c index 14fab7abdc9..b9feead0d45 100644 --- a/source/blender/bmesh/intern/bmesh_core.c +++ b/source/blender/bmesh/intern/bmesh_core.c @@ -78,7 +78,7 @@ BMVert *BM_vert_create(BMesh *bm, const float co[3], const BMVert *example, cons copy_v3_v3(v->co, co); } - /* allocate flag */ + /* allocate flags */ if (bm->toolflagpool) { v->oflags = BLI_mempool_calloc(bm->toolflagpool); } @@ -132,7 +132,7 @@ BMEdge *BM_edge_create(BMesh *bm, BMVert *v1, BMVert *v2, const BMEdge *example, e->head.htype = BM_EDGE; - /* allocate flag */ + /* allocate flags */ if (bm->toolflagpool) { e->oflags = BLI_mempool_calloc(bm->toolflagpool); } @@ -295,7 +295,7 @@ BLI_INLINE BMFace *bm_face_create__internal(BMesh *bm, const eBMCreateFlag creat f->head.htype = BM_FACE; - /* allocate flag */ + /* allocate flags */ if (bm->toolflagpool) { f->oflags = BLI_mempool_calloc(bm->toolflagpool); } @@ -321,7 +321,7 @@ BMFace *BM_face_create(BMesh *bm, BMVert **verts, BMEdge **edges, const int len, int i, overlap; if (len == 0) { - /* just return NULL for no */ + /* just return NULL for now */ return NULL; } @@ -814,11 +814,11 @@ static int bm_loop_reverse_loop(BMesh *bm, BMFace *f } } } - /* rebuild radia */ + /* rebuild radial */ for (i = 0, l_iter = l_first; i < len; i++, l_iter = l_iter->next) bmesh_radial_append(l_iter->e, l_iter); - /* validate radia */ + /* validate radial */ for (i = 0, l_iter = l_first; i < len; i++, l_iter = l_iter->next) { BM_CHECK_ELEMENT(l_iter); BM_CHECK_ELEMENT(l_iter->e); @@ -1068,7 +1068,7 @@ BMFace *BM_faces_join(BMesh *bm, BMFace **faces, int totface, const short do_del } while (l2 != l_iter); if (l2 != l_iter) { - /* I think this is correct */ + /* I think this is correct? */ if (l2->v != l_iter->v) { l2 = l2->next; } @@ -1080,7 +1080,7 @@ BMFace *BM_faces_join(BMesh *bm, BMFace **faces, int totface, const short do_del BM_elem_attrs_copy(bm, bm, faces[0], newf); #ifdef USE_BMESH_HOLES - /* add hole */ + /* add holes */ BLI_movelisttolist(&newf->loops, &holes); #endif @@ -1396,7 +1396,7 @@ BMVert *bmesh_semv(BMesh *bm, BMVert *tv, BMEdge *e, BMEdge **r_e) /* add ne to tv's disk cycle */ bmesh_disk_edge_append(ne, tv); - /* verify disk cycle */ + /* verify disk cycles */ edok = bmesh_disk_validate(valence1, ov->e, ov); BMESH_ASSERT(edok != FALSE); edok = bmesh_disk_validate(valence2, tv->e, tv); @@ -1483,7 +1483,7 @@ BMVert *bmesh_semv(BMesh *bm, BMVert *tv, BMEdge *e, BMEdge **r_e) BMESH_ASSERT(l->v != l->next->v); BMESH_ASSERT(l->e != l->next->e); - /* verify loop cycle for kloop-> */ + /* verify loop cycle for kloop->f */ BM_CHECK_ELEMENT(l); BM_CHECK_ELEMENT(l->v); BM_CHECK_ELEMENT(l->e); @@ -1564,7 +1564,7 @@ BMEdge *bmesh_jekv(BMesh *bm, BMEdge *ke, BMVert *kv, const short check_edge_dou oe = bmesh_disk_edge_next(ke, kv); tv = bmesh_edge_other_vert_get(ke, kv); ov = bmesh_edge_other_vert_get(oe, kv); - halt = bmesh_verts_in_edge(kv, tv, oe); /* check for double edge */ + halt = bmesh_verts_in_edge(kv, tv, oe); /* check for double edges */ if (halt) { return NULL; @@ -1572,7 +1572,7 @@ BMEdge *bmesh_jekv(BMesh *bm, BMEdge *ke, BMVert *kv, const short check_edge_dou else { BMEdge *e_splice; - /* For verification later, count valence of ov and t */ + /* For verification later, count valence of ov and tv */ valence1 = bmesh_disk_count(ov); valence2 = bmesh_disk_count(tv); diff --git a/source/blender/bmesh/intern/bmesh_mods.c b/source/blender/bmesh/intern/bmesh_mods.c index 89516061f91..4253bc750db 100644 --- a/source/blender/bmesh/intern/bmesh_mods.c +++ b/source/blender/bmesh/intern/bmesh_mods.c @@ -152,14 +152,14 @@ int BM_disk_dissolve(BMesh *bm, BMVert *v) return TRUE; } else if (keepedge == NULL && len == 2) { - /* collapse the verte */ + /* collapse the vertex */ e = BM_vert_collapse_faces(bm, v->e, v, 1.0, TRUE, TRUE); if (!e) { return FALSE; } - /* handle two-valenc */ + /* handle two-valence */ f = e->l->f; f2 = e->l->radial_next->f; @@ -205,12 +205,12 @@ int BM_disk_dissolve(BMesh *bm, BMVert *v) return FALSE; } - /* get remaining two face */ + /* get remaining two faces */ f = e->l->f; f2 = e->l->radial_next->f; if (f != f2) { - /* join two remaining face */ + /* join two remaining faces */ if (!BM_faces_join_pair(bm, f, f2, e, TRUE)) { return FALSE; } @@ -343,7 +343,7 @@ BMFace *BM_face_split(BMesh *bm, BMFace *f, BMVert *v1, BMVert *v2, BMLoop **r_l BLI_assert(v1 != v2); - /* do we have a multires layer */ + /* do we have a multires layer? */ if (has_mdisp) { of = BM_face_copy(bm, f, FALSE, FALSE); } @@ -649,7 +649,7 @@ BMVert *BM_edge_split(BMesh *bm, BMEdge *e, BMVert *v, BMEdge **r_e, float perce r_e = &e_dummy; } - /* do we have a multi-res layer */ + /* do we have a multi-res layer? */ if (do_mdisp) { BMLoop *l; int i; @@ -689,7 +689,7 @@ BMVert *BM_edge_split(BMesh *bm, BMEdge *e, BMVert *v, BMEdge **r_e, float perce if (do_mdisp) { int i, j; - /* interpolate new/changed loop data from copied old face */ + /* interpolate new/changed loop data from copied old faces */ for (j = 0; j < 2; j++) { for (i = 0; i < BLI_array_count(oldfaces); i++) { BMEdge *e1 = j ? *r_e : e; @@ -716,7 +716,7 @@ BMVert *BM_edge_split(BMesh *bm, BMEdge *e, BMVert *v, BMEdge **r_e, float perce } } - /* destroy the old face */ + /* destroy the old faces */ for (i = 0; i < BLI_array_count(oldfaces); i++) { BM_face_verts_kill(bm, oldfaces[i]); } diff --git a/source/blender/bmesh/intern/bmesh_opdefines.c b/source/blender/bmesh/intern/bmesh_opdefines.c index 58c6e051e48..3a7a1c4eaaa 100644 --- a/source/blender/bmesh/intern/bmesh_opdefines.c +++ b/source/blender/bmesh/intern/bmesh_opdefines.c @@ -339,7 +339,7 @@ static BMOpDefine bmo_automerge_def = { static BMOpDefine bmo_collapse_def = { "collapse", /* slots_in */ - {{"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* input edge */ + {{"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* input edges */ {{'\0'}}, }, {{{'\0'}}}, /* no output */ @@ -374,7 +374,7 @@ static BMOpDefine bmo_pointmerge_facedata_def = { static BMOpDefine bmo_average_vert_facedata_def = { "average_vert_facedata", /* slots_in */ - {{"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* input vertice */ + {{"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* input vertices */ {{'\0'}}, }, {{{'\0'}}}, /* no output */ @@ -390,7 +390,7 @@ static BMOpDefine bmo_average_vert_facedata_def = { static BMOpDefine bmo_pointmerge_def = { "pointmerge", /* slots_in */ - {{"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* input vertice */ + {{"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* input vertices */ {"merge_co", BMO_OP_SLOT_VEC}, {{'\0'}}, }, @@ -407,7 +407,7 @@ static BMOpDefine bmo_pointmerge_def = { static BMOpDefine bmo_collapse_uvs_def = { "collapse_uvs", /* slots_in */ - {{"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* input edge */ + {{"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* input edges */ {{'\0'}}, }, {{{'\0'}}}, /* no output */ @@ -513,7 +513,7 @@ static BMOpDefine bmo_contextual_create_def = { static BMOpDefine bmo_bridge_loops_def = { "bridge_loops", /* slots_in */ - {{"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* input edge */ + {{"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* input edges */ {"use_merge", BMO_OP_SLOT_BOOL}, {"merge_factor", BMO_OP_SLOT_FLT}, {{'\0'}}, @@ -534,7 +534,7 @@ static BMOpDefine bmo_bridge_loops_def = { static BMOpDefine bmo_edgenet_fill_def = { "edgenet_fill", /* slots_in */ - {{"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* input edge */ + {{"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* input edges */ /* restricts edges to groups. maps edges to integer */ {"restrict", BMO_OP_SLOT_MAPPING, {BMO_OP_SLOT_SUBTYPE_MAP_BOOL}}, {"use_restrict", BMO_OP_SLOT_BOOL}, @@ -547,7 +547,7 @@ static BMOpDefine bmo_edgenet_fill_def = { /* slots_out */ /* maps new faces to the group numbers they came from */ {{"face_groupmap.out", BMO_OP_SLOT_MAPPING, {BMO_OP_SLOT_SUBTYPE_MAP_ELEM}}, - {"faces.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* new face */ + {"faces.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* new faces */ {{'\0'}}, }, bmo_edgenet_fill_exec, @@ -962,7 +962,7 @@ static BMOpDefine bmo_subdivide_edges_def = { {/* these next three can have multiple types of elements in them */ {"geom_inner.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}}, {"geom_split.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}}, - {"geom.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}}, /* contains all output geometr */ + {"geom.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}}, /* contains all output geometry */ {{'\0'}}, }, bmo_subdivide_edges_exec, diff --git a/source/blender/bmesh/intern/bmesh_operators.c b/source/blender/bmesh/intern/bmesh_operators.c index 5e51f5a5ada..19f2b2f8978 100644 --- a/source/blender/bmesh/intern/bmesh_operators.c +++ b/source/blender/bmesh/intern/bmesh_operators.c @@ -1176,7 +1176,7 @@ static void bmo_flag_layer_alloc(BMesh *bm) bm->totflags++; - /* allocate new flag poo */ + /* allocate new flag pool */ bm->toolflagpool = newpool = BLI_mempool_create(sizeof(BMFlagLayer) * bm->totflags, 512, 512, 0); /* now go through and memcpy all the flags. Loops don't get a flag layer at this time.. */ @@ -1224,10 +1224,10 @@ static void bmo_flag_layer_free(BMesh *bm) /* de-increment the totflags first.. */ bm->totflags--; - /* allocate new flag poo */ + /* allocate new flag pool */ bm->toolflagpool = newpool = BLI_mempool_create(new_totflags_size, 512, 512, 0); - /* now go through and memcpy all the flag */ + /* now go through and memcpy all the flags */ BM_ITER_MESH_INDEX (ele, &iter, bm, BM_VERTS_OF_MESH, i) { oldflags = ele->oflags; ele->oflags = BLI_mempool_calloc(newpool); @@ -1265,7 +1265,7 @@ static void bmo_flag_layer_clear(BMesh *bm) BMIter iter; const int totflags_offset = bm->totflags - 1; - /* now go through and memcpy all the flag */ + /* now go through and memcpy all the flags */ BM_ITER_MESH_INDEX (ele, &iter, bm, BM_VERTS_OF_MESH, i) { memset(ele->oflags + totflags_offset, 0, sizeof(BMFlagLayer)); BM_elem_index_set(ele, i); /* set_inline */ @@ -1364,7 +1364,7 @@ void *BMO_iter_step(BMOIter *iter) return NULL; } -/* used for iterating over mapping */ +/* used for iterating over mappings */ void *BMO_iter_map_value(BMOIter *iter) { return iter->val; @@ -1380,7 +1380,7 @@ float BMO_iter_map_value_f(BMOIter *iter) return *((float *)iter->val); } -/* error syste */ +/* error system */ typedef struct BMOpError { struct BMOpError *next, *prev; int errorcode; @@ -1562,7 +1562,7 @@ int BMO_op_vinitf(BMesh *bm, BMOperator *op, const int flag, const char *_fmt, v goto error; \ } (void)0 - /* we muck around in here, so dup i */ + /* we muck around in here, so dup it */ fmt = ofmt = BLI_strdup(_fmt); /* find operator name */ @@ -1589,11 +1589,11 @@ int BMO_op_vinitf(BMesh *bm, BMOperator *op, const int flag, const char *_fmt, v while (*fmt) { if (state) { - /* jump past leading whitespac */ + /* jump past leading whitespace */ i = strspn(fmt, " "); fmt += i; - /* ignore trailing whitespac */ + /* ignore trailing whitespace */ if (!fmt[i]) break; diff --git a/source/blender/bmesh/intern/bmesh_polygon.c b/source/blender/bmesh/intern/bmesh_polygon.c index 2e0471863d4..3018db1af16 100644 --- a/source/blender/bmesh/intern/bmesh_polygon.c +++ b/source/blender/bmesh/intern/bmesh_polygon.c @@ -1042,7 +1042,7 @@ void BM_face_legal_splits(BMesh *bm, BMFace *f, BMLoop *(*loops)[2], int len) } } - /* do line crossing test */ + /* do line crossing tests */ for (i = 0; i < f->len; i++) { p1 = projverts[i]; p2 = projverts[(i + 1) % f->len]; diff --git a/source/blender/bmesh/operators/bmo_create.c b/source/blender/bmesh/operators/bmo_create.c index aa69806fb37..2ea5914ca92 100644 --- a/source/blender/bmesh/operators/bmo_create.c +++ b/source/blender/bmesh/operators/bmo_create.c @@ -578,7 +578,7 @@ static void init_rotsys(BMesh *bm, EdgeData *edata, VertData *vdata) //rotsys_fill_faces(bm, edata, vdata); #if 0 - /* create visualizing geometr */ + /* create visualizing geometry */ BMVert *lastv; BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) { BMVert *v2; diff --git a/source/blender/bmesh/operators/bmo_join_triangles.c b/source/blender/bmesh/operators/bmo_join_triangles.c index 1e18a83a0a0..45ecdee014e 100644 --- a/source/blender/bmesh/operators/bmo_join_triangles.c +++ b/source/blender/bmesh/operators/bmo_join_triangles.c @@ -331,13 +331,13 @@ void bmo_join_triangles_exec(BMesh *bm, BMOperator *op) } } - /* if l isn't NULL, we broke out of the loo */ + /* if l isn't NULL, we broke out of the loop */ if (l) { break; } } - /* if i isn't 2, we broke out of that loo */ + /* if i isn't 2, we broke out of that loop */ if (i != 2) { continue; } diff --git a/source/blender/bmesh/tools/BME_bevel.c b/source/blender/bmesh/tools/BME_bevel.c index 3f2ca21bcee..5e1d58150fa 100644 --- a/source/blender/bmesh/tools/BME_bevel.c +++ b/source/blender/bmesh/tools/BME_bevel.c @@ -965,7 +965,7 @@ static BMesh *BME_bevel_initialize(BMesh *bm, int options, BMIter iter; int /* wire, */ len; - /* tag non-manifold geometr */ + /* tag non-manifold geometry */ BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) { BMO_elem_flag_enable(bm, v, BME_BEVEL_ORIG); if (v->e) { From 7c699a217ae8bb98ead02923334db7dd105bf1b5 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 11 Dec 2012 14:29:01 +0000 Subject: [PATCH 016/252] define the size of matrix args for both rows/cols. --- source/blender/blenkernel/BKE_armature.h | 22 +-- source/blender/blenkernel/BKE_constraint.h | 4 +- source/blender/blenkernel/BKE_fluidsim.h | 2 +- source/blender/blenkernel/BKE_lattice.h | 2 +- source/blender/blenkernel/BKE_object.h | 12 +- source/blender/blenkernel/BKE_particle.h | 10 +- source/blender/blenkernel/intern/anim.c | 13 +- source/blender/blenkernel/intern/armature.c | 32 ++--- source/blender/blenkernel/intern/constraint.c | 12 +- source/blender/blenkernel/intern/lattice.c | 2 +- source/blender/blenkernel/intern/object.c | 20 +-- source/blender/blenkernel/intern/particle.c | 16 +-- source/blender/blenlib/BLI_math_geom.h | 2 +- source/blender/blenlib/BLI_math_matrix.h | 4 +- source/blender/blenlib/intern/math_geom.c | 10 +- source/blender/blenlib/intern/math_matrix.c | 128 +++++++++--------- source/blender/blenlib/intern/math_rotation.c | 32 ++--- .../blenlib/intern/math_vector_inline.c | 2 +- source/blender/collada/ArmatureImporter.cpp | 10 +- source/blender/collada/ArmatureImporter.h | 10 +- source/blender/collada/SkinInfo.cpp | 2 +- source/blender/collada/SkinInfo.h | 2 +- source/blender/collada/TransformReader.cpp | 10 +- source/blender/collada/TransformReader.h | 10 +- source/blender/collada/TransformWriter.cpp | 2 +- source/blender/collada/TransformWriter.h | 2 +- source/blender/collada/collada_internal.cpp | 8 +- source/blender/collada/collada_internal.h | 8 +- .../blender/editors/armature/BIF_generate.h | 5 +- .../editors/armature/editarmature_generate.c | 5 +- .../editors/armature/editarmature_sketch.c | 4 +- .../blender/editors/armature/meshlaplacian.c | 4 +- source/blender/editors/curve/editcurve.c | 4 +- source/blender/editors/include/ED_armature.h | 2 +- source/blender/editors/include/ED_object.h | 2 +- source/blender/editors/include/ED_transform.h | 2 +- source/blender/editors/include/ED_view3d.h | 12 +- source/blender/editors/mesh/editmesh_add.c | 2 +- source/blender/editors/mesh/editmesh_rip.c | 4 +- source/blender/editors/object/object_add.c | 2 +- .../blender/editors/physics/particle_edit.c | 10 +- .../editors/sculpt_paint/paint_utils.c | 2 +- .../editors/sculpt_paint/paint_vertex.c | 2 +- .../editors/space_view3d/drawarmature.c | 8 +- .../blender/editors/space_view3d/drawobject.c | 14 +- .../editors/space_view3d/view3d_draw.c | 10 +- .../editors/space_view3d/view3d_edit.c | 8 +- .../editors/space_view3d/view3d_intern.h | 4 +- .../editors/space_view3d/view3d_view.c | 2 +- source/blender/editors/transform/transform.c | 2 +- source/blender/editors/transform/transform.h | 2 +- .../editors/transform/transform_conversions.c | 2 +- .../editors/transform/transform_manipulator.c | 6 +- .../transform/transform_orientations.c | 2 +- .../editors/transform/transform_snap.c | 12 +- .../editors/uvedit/uvedit_unwrap_ops.c | 2 +- source/blender/gpu/GPU_draw.h | 2 +- source/blender/gpu/GPU_material.h | 6 +- source/blender/gpu/intern/gpu_draw.c | 2 +- source/blender/gpu/intern/gpu_material.c | 6 +- .../blender/ikplugin/intern/iksolver_plugin.c | 2 +- source/blender/makesdna/DNA_modifier_types.h | 2 +- .../modifiers/intern/MOD_boolean_util.c | 6 +- .../modifiers/intern/MOD_fluidsim_util.c | 2 +- .../render/extern/include/RE_pipeline.h | 6 +- .../render/intern/include/pixelblending.h | 4 +- .../blender/render/intern/include/rayobject.h | 2 +- .../render/intern/include/renderdatabase.h | 6 +- source/blender/render/intern/include/strand.h | 4 +- source/blender/render/intern/include/zbuf.h | 14 +- .../intern/raytrace/rayobject_instance.cpp | 2 +- .../intern/raytrace/rayobject_octree.cpp | 4 +- .../render/intern/source/convertblender.c | 12 +- source/blender/render/intern/source/envmap.c | 4 +- .../blender/render/intern/source/initrender.c | 2 +- .../blender/render/intern/source/pipeline.c | 2 +- .../render/intern/source/pixelblending.c | 4 +- .../render/intern/source/renderdatabase.c | 8 +- source/blender/render/intern/source/strand.c | 16 +-- source/blender/render/intern/source/zbuf.c | 18 +-- .../windowmanager/intern/wm_subwindow.c | 2 +- source/blender/windowmanager/wm_subwindow.h | 2 +- .../bad_level_call_stubs/stubs.c | 8 +- .../gameengine/Ketsji/KX_CameraActuator.cpp | 2 +- 84 files changed, 340 insertions(+), 335 deletions(-) diff --git a/source/blender/blenkernel/BKE_armature.h b/source/blender/blenkernel/BKE_armature.h index b0f372e0bac..765a00b8d4b 100644 --- a/source/blender/blenkernel/BKE_armature.h +++ b/source/blender/blenkernel/BKE_armature.h @@ -97,28 +97,28 @@ void BKE_pose_where_is_bone(struct Scene *scene, struct Object *ob, struct bPose void BKE_pose_where_is_bone_tail(struct bPoseChannel *pchan); /* get_objectspace_bone_matrix has to be removed still */ -void get_objectspace_bone_matrix(struct Bone *bone, float M_accumulatedMatrix[][4], int root, int posed); -void vec_roll_to_mat3(const float vec[3], const float roll, float mat[][3]); -void mat3_to_vec_roll(float mat[][3], float r_vec[3], float *r_roll); +void get_objectspace_bone_matrix(struct Bone *bone, float M_accumulatedMatrix[4][4], int root, int posed); +void vec_roll_to_mat3(const float vec[3], const float roll, float mat[3][3]); +void mat3_to_vec_roll(float mat[3][3], float r_vec[3], float *r_roll); /* Common Conversions Between Co-ordinate Spaces */ -void BKE_armature_mat_world_to_pose(struct Object *ob, float inmat[][4], float outmat[][4]); +void BKE_armature_mat_world_to_pose(struct Object *ob, float inmat[4][4], float outmat[4][4]); void BKE_armature_loc_world_to_pose(struct Object *ob, const float inloc[3], float outloc[3]); -void BKE_armature_mat_pose_to_bone(struct bPoseChannel *pchan, float inmat[][4], float outmat[][4]); +void BKE_armature_mat_pose_to_bone(struct bPoseChannel *pchan, float inmat[4][4], float outmat[4][4]); void BKE_armature_loc_pose_to_bone(struct bPoseChannel *pchan, const float inloc[3], float outloc[3]); -void BKE_armature_mat_bone_to_pose(struct bPoseChannel *pchan, float inmat[][4], float outmat[][4]); -void BKE_armature_mat_pose_to_delta(float delta_mat[][4], float pose_mat[][4], float arm_mat[][4]); +void BKE_armature_mat_bone_to_pose(struct bPoseChannel *pchan, float inmat[4][4], float outmat[4][4]); +void BKE_armature_mat_pose_to_delta(float delta_mat[4][4], float pose_mat[4][4], float arm_mat[4][4]); -void BKE_armature_mat_pose_to_bone_ex(struct Object *ob, struct bPoseChannel *pchan, float inmat[][4], float outmat[][4]); +void BKE_armature_mat_pose_to_bone_ex(struct Object *ob, struct bPoseChannel *pchan, float inmat[4][4], float outmat[4][4]); -void BKE_pchan_mat3_to_rot(struct bPoseChannel *pchan, float mat[][3], short use_compat); -void BKE_pchan_apply_mat4(struct bPoseChannel *pchan, float mat[][4], short use_comat); +void BKE_pchan_mat3_to_rot(struct bPoseChannel *pchan, float mat[3][3], short use_compat); +void BKE_pchan_apply_mat4(struct bPoseChannel *pchan, float mat[4][4], short use_comat); void BKE_pchan_to_mat4(struct bPoseChannel *pchan, float chan_mat[4][4]); void BKE_pchan_calc_mat(struct bPoseChannel *pchan); /* Get the "pchan to pose" transform matrix. These matrices apply the effects of * HINGE/NO_SCALE/NO_LOCAL_LOCATION options over the pchan loc/rot/scale transformations. */ -void BKE_pchan_to_pose_mat(struct bPoseChannel *pchan, float rotscale_mat[][4], float loc_mat[][4]); +void BKE_pchan_to_pose_mat(struct bPoseChannel *pchan, float rotscale_mat[4][4], float loc_mat[4][4]); /* Rotation Mode Conversions - Used for PoseChannels + Objects... */ void BKE_rotMode_change_values(float quat[4], float eul[3], float axis[3], float *angle, short oldMode, short newMode); diff --git a/source/blender/blenkernel/BKE_constraint.h b/source/blender/blenkernel/BKE_constraint.h index 686a60ab2c9..79e75127763 100644 --- a/source/blender/blenkernel/BKE_constraint.h +++ b/source/blender/blenkernel/BKE_constraint.h @@ -147,9 +147,9 @@ short proxylocked_constraints_owner(struct Object *ob, struct bPoseChannel *pcha struct bConstraintOb *constraints_make_evalob(struct Scene *scene, struct Object *ob, void *subdata, short datatype); void constraints_clear_evalob(struct bConstraintOb *cob); -void constraint_mat_convertspace(struct Object *ob, struct bPoseChannel *pchan, float mat[][4], short from, short to); +void constraint_mat_convertspace(struct Object *ob, struct bPoseChannel *pchan, float mat[4][4], short from, short to); -void get_constraint_target_matrix(struct Scene *scene, struct bConstraint *con, int n, short ownertype, void *ownerdata, float mat[][4], float ctime); +void get_constraint_target_matrix(struct Scene *scene, struct bConstraint *con, int n, short ownertype, void *ownerdata, float mat[4][4], float ctime); void get_constraint_targets_for_solving(struct bConstraint *con, struct bConstraintOb *ob, struct ListBase *targets, float ctime); void solve_constraints(struct ListBase *conlist, struct bConstraintOb *cob, float ctime); diff --git a/source/blender/blenkernel/BKE_fluidsim.h b/source/blender/blenkernel/BKE_fluidsim.h index c3fa6621c98..433c10b82f1 100644 --- a/source/blender/blenkernel/BKE_fluidsim.h +++ b/source/blender/blenkernel/BKE_fluidsim.h @@ -47,7 +47,7 @@ void initElbeemMesh(struct Scene *scene, struct Object *ob, int useGlobalCoords, int modifierIndex); /* bounding box & memory estimate */ -void fluid_get_bb(struct MVert *mvert, int totvert, float obmat[][4], +void fluid_get_bb(struct MVert *mvert, int totvert, float obmat[4][4], float start[3], float size[3]); void fluid_estimate_memory(struct Object *ob, struct FluidsimSettings *fss, char *value); diff --git a/source/blender/blenkernel/BKE_lattice.h b/source/blender/blenkernel/BKE_lattice.h index 34baa48dbe2..a0bebd752b5 100644 --- a/source/blender/blenkernel/BKE_lattice.h +++ b/source/blender/blenkernel/BKE_lattice.h @@ -59,7 +59,7 @@ void curve_deform_verts(struct Scene *scene, struct Object *cuOb, struct Object struct DerivedMesh *dm, float (*vertexCos)[3], int numVerts, const char *vgroup, short defaxis); void curve_deform_vector(struct Scene *scene, struct Object *cuOb, struct Object *target, - float orco[3], float vec[3], float mat[][3], int no_rot_axis); + float orco[3], float vec[3], float mat[3][3], int no_rot_axis); void lattice_deform_verts(struct Object *laOb, struct Object *target, struct DerivedMesh *dm, float (*vertexCos)[3], diff --git a/source/blender/blenkernel/BKE_object.h b/source/blender/blenkernel/BKE_object.h index ec0703248fd..65b3b194553 100644 --- a/source/blender/blenkernel/BKE_object.h +++ b/source/blender/blenkernel/BKE_object.h @@ -87,12 +87,12 @@ void BKE_object_make_local(struct Object *ob); int BKE_object_is_libdata(struct Object *ob); int BKE_object_obdata_is_libdata(struct Object *ob); -void BKE_object_scale_to_mat3(struct Object *ob, float mat[][3]); -void BKE_object_rot_to_mat3(struct Object *ob, float mat[][3]); -void BKE_object_mat3_to_rot(struct Object *ob, float mat[][3], short use_compat); -void BKE_object_to_mat3(struct Object *ob, float mat[][3]); -void BKE_object_to_mat4(struct Object *ob, float mat[][4]); -void BKE_object_apply_mat4(struct Object *ob, float mat[][4], const short use_compat, const short use_parent); +void BKE_object_scale_to_mat3(struct Object *ob, float mat[3][3]); +void BKE_object_rot_to_mat3(struct Object *ob, float mat[3][3]); +void BKE_object_mat3_to_rot(struct Object *ob, float mat[3][3], short use_compat); +void BKE_object_to_mat3(struct Object *ob, float mat[3][3]); +void BKE_object_to_mat4(struct Object *ob, float mat[4][4]); +void BKE_object_apply_mat4(struct Object *ob, float mat[4][4], const short use_compat, const short use_parent); int BKE_object_pose_context_check(struct Object *ob); struct Object *BKE_object_pose_armature_get(struct Object *ob); diff --git a/source/blender/blenkernel/BKE_particle.h b/source/blender/blenkernel/BKE_particle.h index ec03f53dbdb..bdaffef6818 100644 --- a/source/blender/blenkernel/BKE_particle.h +++ b/source/blender/blenkernel/BKE_particle.h @@ -247,7 +247,7 @@ void BKE_particlesettings_free(struct ParticleSettings *part); void psys_free_path_cache(struct ParticleSystem *psys, struct PTCacheEdit *edit); void psys_free(struct Object *ob, struct ParticleSystem *psys); -void psys_render_set(struct Object *ob, struct ParticleSystem *psys, float viewmat[][4], float winmat[][4], int winx, int winy, int timeoffset); +void psys_render_set(struct Object *ob, struct ParticleSystem *psys, float viewmat[4][4], float winmat[4][4], int winx, int winy, int timeoffset); void psys_render_restore(struct Object *ob, struct ParticleSystem *psys); int psys_render_simplify_distribution(struct ParticleThreadContext *ctx, int tot); int psys_render_simplify_params(struct ParticleSystem *psys, struct ChildParticle *cpa, float *params); @@ -288,7 +288,7 @@ void psys_get_dupli_texture(struct ParticleSystem *psys, struct ParticleSettings struct ParticleSystemModifierData *psmd, struct ParticleData *pa, struct ChildParticle *cpa, float uv[2], float orco[3]); void psys_get_dupli_path_transform(struct ParticleSimulationData *sim, struct ParticleData *pa, struct ChildParticle *cpa, - struct ParticleCacheKey *cache, float mat[][4], float *scale); + struct ParticleCacheKey *cache, float mat[4][4], float *scale); ParticleThread *psys_threads_create(struct ParticleSimulationData *sim); void psys_threads_free(ParticleThread *threads); @@ -322,9 +322,9 @@ void psys_free_children(struct ParticleSystem *psys); void psys_interpolate_particle(short type, struct ParticleKey keys[4], float dt, struct ParticleKey *result, int velocity); void psys_vec_rot_to_face(struct DerivedMesh *dm, struct ParticleData *pa, float vec[3]); -void psys_mat_hair_to_object(struct Object *ob, struct DerivedMesh *dm, short from, struct ParticleData *pa, float hairmat[][4]); -void psys_mat_hair_to_global(struct Object *ob, struct DerivedMesh *dm, short from, struct ParticleData *pa, float hairmat[][4]); -void psys_mat_hair_to_orco(struct Object *ob, struct DerivedMesh *dm, short from, struct ParticleData *pa, float hairmat[][4]); +void psys_mat_hair_to_object(struct Object *ob, struct DerivedMesh *dm, short from, struct ParticleData *pa, float hairmat[4][4]); +void psys_mat_hair_to_global(struct Object *ob, struct DerivedMesh *dm, short from, struct ParticleData *pa, float hairmat[4][4]); +void psys_mat_hair_to_orco(struct Object *ob, struct DerivedMesh *dm, short from, struct ParticleData *pa, float hairmat[4][4]); float psys_get_dietime_from_cache(struct PointCache *cache, int index); diff --git a/source/blender/blenkernel/intern/anim.c b/source/blender/blenkernel/intern/anim.c index 9a2462e9724..89f2291059f 100644 --- a/source/blender/blenkernel/intern/anim.c +++ b/source/blender/blenkernel/intern/anim.c @@ -76,7 +76,7 @@ /* --------------------- */ /* forward declarations */ -static void object_duplilist_recursive(ID *id, Scene *scene, Object *ob, ListBase *duplilist, float par_space_mat[][4], +static void object_duplilist_recursive(ID *id, Scene *scene, Object *ob, ListBase *duplilist, float par_space_mat[4][4], int persistent_id[MAX_DUPLI_RECUR], int level, int index, short flag); /* ******************************************************************** */ @@ -706,7 +706,7 @@ int where_on_path(Object *ob, float ctime, float vec[4], float dir[3], float qua #define DUPLILIST_FOR_RENDER 2 #define DUPLILIST_ANIMATED 4 -static DupliObject *new_dupli_object(ListBase *lb, Object *ob, float mat[][4], int lay, +static DupliObject *new_dupli_object(ListBase *lb, Object *ob, float mat[4][4], int lay, int persistent_id[MAX_DUPLI_RECUR], int level, int index, int type, short flag) { DupliObject *dob = MEM_callocN(sizeof(DupliObject), "dupliobject"); @@ -930,7 +930,7 @@ static void vertex_dupli__mapFunc(void *userData, int index, const float co[3], } } -static void vertex_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, float par_space_mat[][4], int persistent_id[MAX_DUPLI_RECUR], +static void vertex_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, float par_space_mat[4][4], int persistent_id[MAX_DUPLI_RECUR], int level, short flag) { Object *ob, *ob_iter; @@ -1054,7 +1054,7 @@ static void vertex_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, fl dm->release(dm); } -static void face_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, float par_space_mat[][4], int persistent_id[MAX_DUPLI_RECUR], +static void face_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, float par_space_mat[4][4], int persistent_id[MAX_DUPLI_RECUR], int level, short flag) { Object *ob, *ob_iter; @@ -1240,7 +1240,8 @@ static void face_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, floa dm->release(dm); } -static void new_particle_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, float par_space_mat[][4], int persistent_id[MAX_DUPLI_RECUR], ParticleSystem *psys, +static void new_particle_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, float par_space_mat[4][4], + int persistent_id[MAX_DUPLI_RECUR], ParticleSystem *psys, int level, short flag) { GroupObject *go; @@ -1635,7 +1636,7 @@ static void font_duplilist(ListBase *lb, Scene *scene, Object *par, int persiste /* ------------- */ -static void object_duplilist_recursive(ID *id, Scene *scene, Object *ob, ListBase *duplilist, float par_space_mat[][4], +static void object_duplilist_recursive(ID *id, Scene *scene, Object *ob, ListBase *duplilist, float par_space_mat[4][4], int persistent_id[MAX_DUPLI_RECUR], int level, int index, short flag) { if ((ob->transflag & OB_DUPLI) == 0) diff --git a/source/blender/blenkernel/intern/armature.c b/source/blender/blenkernel/intern/armature.c index 1970df54339..a93d728ad04 100644 --- a/source/blender/blenkernel/intern/armature.c +++ b/source/blender/blenkernel/intern/armature.c @@ -640,7 +640,7 @@ static void pchan_b_bone_defmats(bPoseChannel *pchan, bPoseChanDeform *pdef_info } } -static void b_bone_deform(bPoseChanDeform *pdef_info, Bone *bone, float co[3], DualQuat *dq, float defmat[][3]) +static void b_bone_deform(bPoseChanDeform *pdef_info, Bone *bone, float co[3], DualQuat *dq, float defmat[3][3]) { Mat4 *b_bone = pdef_info->b_bone_mats; float (*mat)[4] = b_bone[0].mat; @@ -722,7 +722,7 @@ float distfactor_to_bone(const float vec[3], const float b1[3], const float b2[3 } } -static void pchan_deform_mat_add(bPoseChannel *pchan, float weight, float bbonemat[][3], float mat[][3]) +static void pchan_deform_mat_add(bPoseChannel *pchan, float weight, float bbonemat[3][3], float mat[3][3]) { float wmat[3][3]; @@ -736,7 +736,7 @@ static void pchan_deform_mat_add(bPoseChannel *pchan, float weight, float bbonem } static float dist_bone_deform(bPoseChannel *pchan, bPoseChanDeform *pdef_info, float vec[3], DualQuat *dq, - float mat[][3], const float co[3]) + float mat[3][3], const float co[3]) { Bone *bone = pchan->bone; float fac, contrib = 0.0; @@ -783,7 +783,7 @@ static float dist_bone_deform(bPoseChannel *pchan, bPoseChanDeform *pdef_info, f } static void pchan_bone_deform(bPoseChannel *pchan, bPoseChanDeform *pdef_info, float weight, float vec[3], DualQuat *dq, - float mat[][3], const float co[3], float *contrib) + float mat[3][3], const float co[3], float *contrib) { float cop[3], bbonemat[3][3]; DualQuat bbonedq; @@ -1089,7 +1089,7 @@ void armature_deform_verts(Object *armOb, Object *target, DerivedMesh *dm, float /* ************ END Armature Deform ******************* */ -void get_objectspace_bone_matrix(struct Bone *bone, float M_accumulatedMatrix[][4], int UNUSED(root), +void get_objectspace_bone_matrix(struct Bone *bone, float M_accumulatedMatrix[4][4], int UNUSED(root), int UNUSED(posed)) { copy_m4_m4(M_accumulatedMatrix, bone->arm_mat); @@ -1098,7 +1098,7 @@ void get_objectspace_bone_matrix(struct Bone *bone, float M_accumulatedMatrix[][ /* **************** Space to Space API ****************** */ /* Convert World-Space Matrix to Pose-Space Matrix */ -void BKE_armature_mat_world_to_pose(Object *ob, float inmat[][4], float outmat[][4]) +void BKE_armature_mat_world_to_pose(Object *ob, float inmat[4][4], float outmat[4][4]) { float obmat[4][4]; @@ -1132,7 +1132,7 @@ void BKE_armature_loc_world_to_pose(Object *ob, const float inloc[3], float outl /* Simple helper, computes the offset bone matrix. * offs_bone = yoffs(b-1) + root(b) + bonemat(b). * Not exported, as it is only used in this file currently... */ -static void get_offset_bone_mat(Bone *bone, float offs_bone[][4]) +static void get_offset_bone_mat(Bone *bone, float offs_bone[4][4]) { if (!bone->parent) return; @@ -1164,7 +1164,7 @@ static void get_offset_bone_mat(Bone *bone, float offs_bone[][4]) * pose-channel into its local space (i.e. 'visual'-keyframing). * (note: I don't understand that, so I keep it :p --mont29). */ -void BKE_pchan_to_pose_mat(bPoseChannel *pchan, float rotscale_mat[][4], float loc_mat[][4]) +void BKE_pchan_to_pose_mat(bPoseChannel *pchan, float rotscale_mat[4][4], float loc_mat[4][4]) { Bone *bone, *parbone; bPoseChannel *parchan; @@ -1253,7 +1253,7 @@ void BKE_pchan_to_pose_mat(bPoseChannel *pchan, float rotscale_mat[][4], float l /* Convert Pose-Space Matrix to Bone-Space Matrix. * NOTE: this cannot be used to convert to pose-space transforms of the supplied * pose-channel into its local space (i.e. 'visual'-keyframing) */ -void BKE_armature_mat_pose_to_bone(bPoseChannel *pchan, float inmat[][4], float outmat[][4]) +void BKE_armature_mat_pose_to_bone(bPoseChannel *pchan, float inmat[4][4], float outmat[4][4]) { float rotscale_mat[4][4], loc_mat[4][4], inmat_[4][4]; @@ -1269,7 +1269,7 @@ void BKE_armature_mat_pose_to_bone(bPoseChannel *pchan, float inmat[][4], float } /* Convert Bone-Space Matrix to Pose-Space Matrix. */ -void BKE_armature_mat_bone_to_pose(bPoseChannel *pchan, float inmat[][4], float outmat[][4]) +void BKE_armature_mat_bone_to_pose(bPoseChannel *pchan, float inmat[4][4], float outmat[4][4]) { float rotscale_mat[4][4], loc_mat[4][4], inmat_[4][4]; @@ -1298,7 +1298,7 @@ void BKE_armature_loc_pose_to_bone(bPoseChannel *pchan, const float inloc[3], fl copy_v3_v3(outloc, nLocMat[3]); } -void BKE_armature_mat_pose_to_bone_ex(Object *ob, bPoseChannel *pchan, float inmat[][4], float outmat[][4]) +void BKE_armature_mat_pose_to_bone_ex(Object *ob, bPoseChannel *pchan, float inmat[4][4], float outmat[4][4]) { bPoseChannel work_pchan = *pchan; @@ -1316,7 +1316,7 @@ void BKE_armature_mat_pose_to_bone_ex(Object *ob, bPoseChannel *pchan, float inm } /* same as BKE_object_mat3_to_rot() */ -void BKE_pchan_mat3_to_rot(bPoseChannel *pchan, float mat[][3], short use_compat) +void BKE_pchan_mat3_to_rot(bPoseChannel *pchan, float mat[3][3], short use_compat) { switch (pchan->rotmode) { case ROT_MODE_QUAT: @@ -1335,7 +1335,7 @@ void BKE_pchan_mat3_to_rot(bPoseChannel *pchan, float mat[][3], short use_compat /* Apply a 4x4 matrix to the pose bone, * similar to BKE_object_apply_mat4() */ -void BKE_pchan_apply_mat4(bPoseChannel *pchan, float mat[][4], short use_compat) +void BKE_pchan_apply_mat4(bPoseChannel *pchan, float mat[4][4], short use_compat) { float rot[3][3]; mat4_to_loc_rot_size(pchan->loc, rot, pchan->size, mat); @@ -1345,7 +1345,7 @@ void BKE_pchan_apply_mat4(bPoseChannel *pchan, float mat[][4], short use_compat) /* Remove rest-position effects from pose-transform for obtaining * 'visual' transformation of pose-channel. * (used by the Visual-Keyframing stuff) */ -void BKE_armature_mat_pose_to_delta(float delta_mat[][4], float pose_mat[][4], float arm_mat[][4]) +void BKE_armature_mat_pose_to_delta(float delta_mat[4][4], float pose_mat[4][4], float arm_mat[4][4]) { float imat[4][4]; @@ -1425,7 +1425,7 @@ void BKE_rotMode_change_values(float quat[4], float eul[3], float axis[3], float * *************************************************************************** */ /* Computes vector and roll based on a rotation. * "mat" must contain only a rotation, and no scaling. */ -void mat3_to_vec_roll(float mat[][3], float r_vec[3], float *r_roll) +void mat3_to_vec_roll(float mat[3][3], float r_vec[3], float *r_roll) { if (r_vec) { copy_v3_v3(r_vec, mat[1]); @@ -1444,7 +1444,7 @@ void mat3_to_vec_roll(float mat[][3], float r_vec[3], float *r_roll) /* Calculates the rest matrix of a bone based * On its vector and a roll around that vector */ -void vec_roll_to_mat3(const float vec[3], const float roll, float mat[][3]) +void vec_roll_to_mat3(const float vec[3], const float roll, float mat[3][3]) { float nor[3], axis[3], target[3] = {0, 1, 0}; float theta; diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c index 97d750854f4..c3aab22fe5a 100644 --- a/source/blender/blenkernel/intern/constraint.c +++ b/source/blender/blenkernel/intern/constraint.c @@ -219,7 +219,7 @@ void constraints_clear_evalob(bConstraintOb *cob) * of a matrix from one space to another for constraint evaluation. * For now, this is only implemented for Objects and PoseChannels. */ -void constraint_mat_convertspace(Object *ob, bPoseChannel *pchan, float mat[][4], short from, short to) +void constraint_mat_convertspace(Object *ob, bPoseChannel *pchan, float mat[4][4], short from, short to) { float diff_mat[4][4]; float imat[4][4]; @@ -345,7 +345,7 @@ void constraint_mat_convertspace(Object *ob, bPoseChannel *pchan, float mat[][4] /* ------------ General Target Matrix Tools ---------- */ /* function that sets the given matrix based on given vertex group in mesh */ -static void contarget_get_mesh_mat(Object *ob, const char *substring, float mat[][4]) +static void contarget_get_mesh_mat(Object *ob, const char *substring, float mat[4][4]) { DerivedMesh *dm = NULL; BMEditMesh *em = BMEdit_FromObject(ob); @@ -441,7 +441,7 @@ static void contarget_get_mesh_mat(Object *ob, const char *substring, float mat[ } /* function that sets the given matrix based on given vertex group in lattice */ -static void contarget_get_lattice_mat(Object *ob, const char *substring, float mat[][4]) +static void contarget_get_lattice_mat(Object *ob, const char *substring, float mat[4][4]) { Lattice *lt = (Lattice *)ob->data; @@ -494,7 +494,7 @@ static void contarget_get_lattice_mat(Object *ob, const char *substring, float m /* generic function to get the appropriate matrix for most target cases */ /* The cases where the target can be object data have not been implemented */ -static void constraint_target_to_mat4(Object *ob, const char *substring, float mat[][4], short from, short to, float headtail) +static void constraint_target_to_mat4(Object *ob, const char *substring, float mat[4][4], short from, short to, float headtail) { /* Case OBJECT */ if (!strlen(substring)) { @@ -890,7 +890,7 @@ static int basis_cross(int n, int m) } } -static void vectomat(const float vec[3], const float target_up[3], short axis, short upflag, short flags, float m[][3]) +static void vectomat(const float vec[3], const float target_up[3], short axis, short upflag, short flags, float m[3][3]) { float n[3]; float u[3]; /* vector specifying the up axis */ @@ -4610,7 +4610,7 @@ short proxylocked_constraints_owner(Object *ob, bPoseChannel *pchan) * None of the actual calculations of the matrices should be done here! Also, this function is * not to be used by any new constraints, particularly any that have multiple targets. */ -void get_constraint_target_matrix(struct Scene *scene, bConstraint *con, int n, short ownertype, void *ownerdata, float mat[][4], float ctime) +void get_constraint_target_matrix(struct Scene *scene, bConstraint *con, int n, short ownertype, void *ownerdata, float mat[4][4], float ctime) { bConstraintTypeInfo *cti = constraint_get_typeinfo(con); ListBase targets = {NULL, NULL}; diff --git a/source/blender/blenkernel/intern/lattice.c b/source/blender/blenkernel/intern/lattice.c index a15ca7cb5ce..86b82c3cf43 100644 --- a/source/blender/blenkernel/intern/lattice.c +++ b/source/blender/blenkernel/intern/lattice.c @@ -753,7 +753,7 @@ void curve_deform_verts(Scene *scene, Object *cuOb, Object *target, /* orco is original not-animated or deformed reference point */ /* result written in vec and mat */ void curve_deform_vector(Scene *scene, Object *cuOb, Object *target, - float orco[3], float vec[3], float mat[][3], int no_rot_axis) + float orco[3], float vec[3], float mat[3][3], int no_rot_axis) { CurveDeform cd; float quat[4]; diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c index 47ca502d247..425990d7583 100644 --- a/source/blender/blenkernel/intern/object.c +++ b/source/blender/blenkernel/intern/object.c @@ -1488,14 +1488,14 @@ void BKE_object_make_proxy(Object *ob, Object *target, Object *gob) /* *************** CALC ****************** */ -void BKE_object_scale_to_mat3(Object *ob, float mat[][3]) +void BKE_object_scale_to_mat3(Object *ob, float mat[3][3]) { float vec[3]; mul_v3_v3v3(vec, ob->size, ob->dscale); size_to_mat3(mat, vec); } -void BKE_object_rot_to_mat3(Object *ob, float mat[][3]) +void BKE_object_rot_to_mat3(Object *ob, float mat[3][3]) { float rmat[3][3], dmat[3][3]; @@ -1529,7 +1529,7 @@ void BKE_object_rot_to_mat3(Object *ob, float mat[][3]) mul_m3_m3m3(mat, dmat, rmat); } -void BKE_object_mat3_to_rot(Object *ob, float mat[][3], short use_compat) +void BKE_object_mat3_to_rot(Object *ob, float mat[3][3], short use_compat) { switch (ob->rotmode) { case ROT_MODE_QUAT: @@ -1632,7 +1632,7 @@ void BKE_object_tfm_protected_restore(Object *ob, } /* see BKE_pchan_apply_mat4() for the equivalent 'pchan' function */ -void BKE_object_apply_mat4(Object *ob, float mat[][4], const short use_compat, const short use_parent) +void BKE_object_apply_mat4(Object *ob, float mat[4][4], const short use_compat, const short use_parent) { float rot[3][3]; @@ -1661,7 +1661,7 @@ void BKE_object_apply_mat4(Object *ob, float mat[][4], const short use_compat, c /* BKE_object_mat3_to_rot handles delta rotations */ } -void BKE_object_to_mat3(Object *ob, float mat[][3]) /* no parent */ +void BKE_object_to_mat3(Object *ob, float mat[3][3]) /* no parent */ { float smat[3][3]; float rmat[3][3]; @@ -1675,7 +1675,7 @@ void BKE_object_to_mat3(Object *ob, float mat[][3]) /* no parent */ mul_m3_m3m3(mat, rmat, smat); } -void BKE_object_to_mat4(Object *ob, float mat[][4]) +void BKE_object_to_mat4(Object *ob, float mat[4][4]) { float tmat[3][3]; @@ -1689,7 +1689,7 @@ void BKE_object_to_mat4(Object *ob, float mat[][4]) /* extern */ int enable_cu_speed = 1; -static void ob_parcurve(Scene *scene, Object *ob, Object *par, float mat[][4]) +static void ob_parcurve(Scene *scene, Object *ob, Object *par, float mat[4][4]) { Curve *cu; float vec[4], dir[3], quat[4], radius, ctime; @@ -1773,7 +1773,7 @@ static void ob_parcurve(Scene *scene, Object *ob, Object *par, float mat[][4]) } } -static void ob_parbone(Object *ob, Object *par, float mat[][4]) +static void ob_parbone(Object *ob, Object *par, float mat[4][4]) { bPoseChannel *pchan; float vec[3]; @@ -1903,7 +1903,7 @@ static void give_parvert(Object *par, int nr, float vec[3]) } } -static void ob_parvert3(Object *ob, Object *par, float mat[][4]) +static void ob_parvert3(Object *ob, Object *par, float mat[4][4]) { float cmat[3][3], v1[3], v2[3], v3[3], q[4]; @@ -1931,7 +1931,7 @@ static void ob_parvert3(Object *ob, Object *par, float mat[][4]) } } -static void solve_parenting(Scene *scene, Object *ob, Object *par, float obmat[][4], float slowmat[][4], int simul) +static void solve_parenting(Scene *scene, Object *ob, Object *par, float obmat[4][4], float slowmat[4][4], int simul) { float totmat[4][4]; float tmat[4][4]; diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c index 5f5a713064d..97d8b06d3a7 100644 --- a/source/blender/blenkernel/intern/particle.c +++ b/source/blender/blenkernel/intern/particle.c @@ -680,7 +680,7 @@ static float psys_render_projected_area(ParticleSystem *psys, const float center return area; } -void psys_render_set(Object *ob, ParticleSystem *psys, float viewmat[][4], float winmat[][4], int winx, int winy, int timeoffset) +void psys_render_set(Object *ob, ParticleSystem *psys, float viewmat[4][4], float winmat[4][4], int winx, int winy, int timeoffset) { ParticleRenderData *data; ParticleSystemModifierData *psmd = psys_get_modifier(ob, psys); @@ -1919,7 +1919,7 @@ void psys_particle_on_emitter(ParticleSystemModifierData *psmd, int from, int in /* Path Cache */ /************************************************/ -static void do_kink(ParticleKey *state, ParticleKey *par, float *par_rot, float time, float freq, float shape, float amplitude, float flat, short type, short axis, float obmat[][4], int smooth_start) +static void do_kink(ParticleKey *state, ParticleKey *par, float *par_rot, float time, float freq, float shape, float amplitude, float flat, short type, short axis, float obmat[4][4], int smooth_start) { float kink[3] = {1.f, 0.f, 0.f}, par_vec[3], q1[4] = {1.f, 0.f, 0.f, 0.f}; float t, dt = 1.f, result[3]; @@ -3351,7 +3351,7 @@ static void key_from_object(Object *ob, ParticleKey *key) } #endif -static void triatomat(float *v1, float *v2, float *v3, float (*uv)[2], float mat[][4]) +static void triatomat(float *v1, float *v2, float *v3, float (*uv)[2], float mat[4][4]) { float det, w1, w2, d1[2], d2[2]; @@ -3392,7 +3392,7 @@ static void triatomat(float *v1, float *v2, float *v3, float (*uv)[2], float mat cross_v3_v3v3(mat[0], mat[1], mat[2]); } -static void psys_face_mat(Object *ob, DerivedMesh *dm, ParticleData *pa, float mat[][4], int orco) +static void psys_face_mat(Object *ob, DerivedMesh *dm, ParticleData *pa, float mat[4][4], int orco) { float v[3][3]; MFace *mface; @@ -3425,7 +3425,7 @@ static void psys_face_mat(Object *ob, DerivedMesh *dm, ParticleData *pa, float m triatomat(v[0], v[1], v[2], (osface) ? osface->uv : NULL, mat); } -void psys_mat_hair_to_object(Object *UNUSED(ob), DerivedMesh *dm, short from, ParticleData *pa, float hairmat[][4]) +void psys_mat_hair_to_object(Object *UNUSED(ob), DerivedMesh *dm, short from, ParticleData *pa, float hairmat[4][4]) { float vec[3]; @@ -3440,7 +3440,7 @@ void psys_mat_hair_to_object(Object *UNUSED(ob), DerivedMesh *dm, short from, Pa copy_v3_v3(hairmat[3], vec); } -void psys_mat_hair_to_orco(Object *ob, DerivedMesh *dm, short from, ParticleData *pa, float hairmat[][4]) +void psys_mat_hair_to_orco(Object *ob, DerivedMesh *dm, short from, ParticleData *pa, float hairmat[4][4]) { float vec[3], orco[3]; @@ -3462,7 +3462,7 @@ void psys_vec_rot_to_face(DerivedMesh *dm, ParticleData *pa, float vec[3]) mul_mat3_m4_v3(mat, vec); } -void psys_mat_hair_to_global(Object *ob, DerivedMesh *dm, short from, ParticleData *pa, float hairmat[][4]) +void psys_mat_hair_to_global(Object *ob, DerivedMesh *dm, short from, ParticleData *pa, float hairmat[4][4]) { float facemat[4][4]; @@ -4502,7 +4502,7 @@ void psys_get_dupli_texture(ParticleSystem *psys, ParticleSettings *part, psys_particle_on_emitter(psmd, part->from, pa->num, pa->num_dmcache, pa->fuv, pa->foffset, loc, 0, 0, 0, orco, 0); } -void psys_get_dupli_path_transform(ParticleSimulationData *sim, ParticleData *pa, ChildParticle *cpa, ParticleCacheKey *cache, float mat[][4], float *scale) +void psys_get_dupli_path_transform(ParticleSimulationData *sim, ParticleData *pa, ChildParticle *cpa, ParticleCacheKey *cache, float mat[4][4], float *scale) { Object *ob = sim->ob; ParticleSystem *psys = sim->psys; diff --git a/source/blender/blenlib/BLI_math_geom.h b/source/blender/blenlib/BLI_math_geom.h index cfd163d4e57..423765bad3d 100644 --- a/source/blender/blenlib/BLI_math_geom.h +++ b/source/blender/blenlib/BLI_math_geom.h @@ -202,7 +202,7 @@ void perspective_m4(float mat[4][4], const float left, const float right, const float bottom, const float top, const float nearClip, const float farClip); void orthographic_m4(float mat[4][4], const float left, const float right, const float bottom, const float top, const float nearClip, const float farClip); -void window_translate_m4(float winmat[][4], float perspmat[][4], +void window_translate_m4(float winmat[4][4], float perspmat[4][4], const float x, const float y); int box_clip_bounds_m4(float boundbox[2][3], diff --git a/source/blender/blenlib/BLI_math_matrix.h b/source/blender/blenlib/BLI_math_matrix.h index f51bd1cf840..c97eb4c588c 100644 --- a/source/blender/blenlib/BLI_math_matrix.h +++ b/source/blender/blenlib/BLI_math_matrix.h @@ -167,8 +167,8 @@ void translate_m4(float mat[4][4], float tx, float ty, float tz); void rotate_m4(float mat[4][4], const char axis, const float angle); -void mat3_to_rot_size(float rot[3][3], float size[3], float mat3[][3]); -void mat4_to_loc_rot_size(float loc[3], float rot[3][3], float size[3], float wmat[][4]); +void mat3_to_rot_size(float rot[3][3], float size[3], float mat3[3][3]); +void mat4_to_loc_rot_size(float loc[3], float rot[3][3], float size[3], float wmat[4][4]); void loc_eul_size_to_mat4(float R[4][4], const float loc[3], const float eul[3], const float size[3]); diff --git a/source/blender/blenlib/intern/math_geom.c b/source/blender/blenlib/intern/math_geom.c index 6938cde8ec5..931025606db 100644 --- a/source/blender/blenlib/intern/math_geom.c +++ b/source/blender/blenlib/intern/math_geom.c @@ -2435,7 +2435,7 @@ void interp_barycentric_tri_v3(float data[3][3], float u, float v, float res[3]) /***************************** View & Projection *****************************/ -void orthographic_m4(float matrix[][4], const float left, const float right, const float bottom, const float top, +void orthographic_m4(float matrix[4][4], const float left, const float right, const float bottom, const float top, const float nearClip, const float farClip) { float Xdelta, Ydelta, Zdelta; @@ -2481,7 +2481,7 @@ void perspective_m4(float mat[4][4], const float left, const float right, const } /* translate a matrix created by orthographic_m4 or perspective_m4 in XY coords (used to jitter the view) */ -void window_translate_m4(float winmat[][4], float perspmat[][4], const float x, const float y) +void window_translate_m4(float winmat[4][4], float perspmat[4][4], const float x, const float y) { if (winmat[2][3] == -1.0f) { /* in the case of a win-matrix, this means perspective always */ @@ -2509,7 +2509,7 @@ void window_translate_m4(float winmat[][4], float perspmat[][4], const float x, } } -static void i_multmatrix(float icand[][4], float Vm[][4]) +static void i_multmatrix(float icand[4][4], float Vm[4][4]) { int row, col; float temp[4][4]; @@ -2523,7 +2523,7 @@ static void i_multmatrix(float icand[][4], float Vm[][4]) copy_m4_m4(Vm, temp); } -void polarview_m4(float Vm[][4], float dist, float azimuth, float incidence, float twist) +void polarview_m4(float Vm[4][4], float dist, float azimuth, float incidence, float twist) { unit_m4(Vm); @@ -2534,7 +2534,7 @@ void polarview_m4(float Vm[][4], float dist, float azimuth, float incidence, flo rotate_m4(Vm, 'Z', -azimuth); } -void lookat_m4(float mat[][4], float vx, float vy, float vz, float px, float py, float pz, float twist) +void lookat_m4(float mat[4][4], float vx, float vy, float vz, float px, float py, float pz, float twist) { float sine, cosine, hyp, hyp1, dx, dy, dz; float mat1[4][4] = MAT4_UNITY; diff --git a/source/blender/blenlib/intern/math_matrix.c b/source/blender/blenlib/intern/math_matrix.c index 38214f9c6b0..3ca771769a6 100644 --- a/source/blender/blenlib/intern/math_matrix.c +++ b/source/blender/blenlib/intern/math_matrix.c @@ -43,7 +43,7 @@ void zero_m4(float m[4][4]) memset(m, 0, 4 * 4 * sizeof(float)); } -void unit_m3(float m[][3]) +void unit_m3(float m[3][3]) { m[0][0] = m[1][1] = m[2][2] = 1.0; m[0][1] = m[0][2] = 0.0; @@ -51,7 +51,7 @@ void unit_m3(float m[][3]) m[2][0] = m[2][1] = 0.0; } -void unit_m4(float m[][4]) +void unit_m4(float m[4][4]) { m[0][0] = m[1][1] = m[2][2] = m[3][3] = 1.0; m[0][1] = m[0][2] = m[0][3] = 0.0; @@ -60,18 +60,18 @@ void unit_m4(float m[][4]) m[3][0] = m[3][1] = m[3][2] = 0.0; } -void copy_m3_m3(float m1[][3], float m2[][3]) +void copy_m3_m3(float m1[3][3], float m2[3][3]) { /* destination comes first: */ memcpy(&m1[0], &m2[0], 9 * sizeof(float)); } -void copy_m4_m4(float m1[][4], float m2[][4]) +void copy_m4_m4(float m1[4][4], float m2[4][4]) { memcpy(m1, m2, 4 * 4 * sizeof(float)); } -void copy_m3_m4(float m1[][3], float m2[][4]) +void copy_m3_m4(float m1[3][3], float m2[4][4]) { m1[0][0] = m2[0][0]; m1[0][1] = m2[0][1]; @@ -86,7 +86,7 @@ void copy_m3_m4(float m1[][3], float m2[][4]) m1[2][2] = m2[2][2]; } -void copy_m4_m3(float m1[][4], float m2[][3]) /* no clear */ +void copy_m4_m3(float m1[4][4], float m2[3][3]) /* no clear */ { m1[0][0] = m2[0][0]; m1[0][1] = m2[0][1]; @@ -112,7 +112,7 @@ void copy_m4_m3(float m1[][4], float m2[][3]) /* no clear */ } -void swap_m3m3(float m1[][3], float m2[][3]) +void swap_m3m3(float m1[3][3], float m2[3][3]) { float t; int i, j; @@ -126,7 +126,7 @@ void swap_m3m3(float m1[][3], float m2[][3]) } } -void swap_m4m4(float m1[][4], float m2[][4]) +void swap_m4m4(float m1[4][4], float m2[4][4]) { float t; int i, j; @@ -142,7 +142,7 @@ void swap_m4m4(float m1[][4], float m2[][4]) /******************************** Arithmetic *********************************/ -void mult_m4_m4m4(float m1[][4], float m3_[][4], float m2_[][4]) +void mult_m4_m4m4(float m1[4][4], float m3_[4][4], float m2_[4][4]) { float m2[4][4], m3[4][4]; @@ -173,7 +173,7 @@ void mult_m4_m4m4(float m1[][4], float m3_[][4], float m2_[][4]) } -void mul_m3_m3m3(float m1[][3], float m3_[][3], float m2_[][3]) +void mul_m3_m3m3(float m1[3][3], float m3_[3][3], float m2_[3][3]) { float m2[3][3], m3[3][3]; @@ -195,7 +195,7 @@ void mul_m3_m3m3(float m1[][3], float m3_[][3], float m2_[][3]) m1[2][2] = m2[2][0] * m3[0][2] + m2[2][1] * m3[1][2] + m2[2][2] * m3[2][2]; } -void mul_m4_m4m3(float m1[][4], float m3_[][4], float m2_[][3]) +void mul_m4_m4m3(float m1[4][4], float m3_[4][4], float m2_[3][3]) { float m2[3][3], m3[4][4]; @@ -215,7 +215,7 @@ void mul_m4_m4m3(float m1[][4], float m3_[][4], float m2_[][3]) } /* m1 = m2 * m3, ignore the elements on the 4th row/column of m3 */ -void mult_m3_m3m4(float m1[][3], float m3_[][4], float m2_[][3]) +void mult_m3_m3m4(float m1[3][3], float m3_[4][4], float m2_[3][3]) { float m2[3][3], m3[4][4]; @@ -237,7 +237,7 @@ void mult_m3_m3m4(float m1[][3], float m3_[][4], float m2_[][3]) m1[2][2] = m2[2][0] * m3[0][2] + m2[2][1] * m3[1][2] + m2[2][2] * m3[2][2]; } -void mul_m4_m3m4(float m1[][4], float m3_[][3], float m2_[][4]) +void mul_m4_m3m4(float m1[4][4], float m3_[3][3], float m2_[4][4]) { float m2[4][4], m3[3][3]; @@ -256,10 +256,10 @@ void mul_m4_m3m4(float m1[][4], float m3_[][3], float m2_[][4]) m1[2][2] = m2[2][0] * m3[0][2] + m2[2][1] * m3[1][2] + m2[2][2] * m3[2][2]; } -void mul_serie_m3(float answ[][3], - float m1[][3], float m2[][3], float m3[][3], - float m4[][3], float m5[][3], float m6[][3], - float m7[][3], float m8[][3]) +void mul_serie_m3(float answ[3][3], + float m1[3][3], float m2[3][3], float m3[3][3], + float m4[3][3], float m5[3][3], float m6[3][3], + float m7[3][3], float m8[3][3]) { float temp[3][3]; @@ -289,10 +289,10 @@ void mul_serie_m3(float answ[][3], } } -void mul_serie_m4(float answ[][4], float m1[][4], - float m2[][4], float m3[][4], float m4[][4], - float m5[][4], float m6[][4], float m7[][4], - float m8[][4]) +void mul_serie_m4(float answ[4][4], float m1[4][4], + float m2[4][4], float m3[4][4], float m4[4][4], + float m5[4][4], float m6[4][4], float m7[4][4], + float m8[4][4]) { float temp[4][4]; @@ -322,7 +322,7 @@ void mul_serie_m4(float answ[][4], float m1[][4], } } -void mul_m4_v3(float mat[][4], float vec[3]) +void mul_m4_v3(float mat[4][4], float vec[3]) { float x, y; @@ -333,7 +333,7 @@ void mul_m4_v3(float mat[][4], float vec[3]) vec[2] = x * mat[0][2] + y * mat[1][2] + mat[2][2] * vec[2] + mat[3][2]; } -void mul_v3_m4v3(float in[3], float mat[][4], const float vec[3]) +void mul_v3_m4v3(float in[3], float mat[4][4], const float vec[3]) { float x, y; @@ -345,7 +345,7 @@ void mul_v3_m4v3(float in[3], float mat[][4], const float vec[3]) } /* same as mul_m4_v3() but doesnt apply translation component */ -void mul_mat3_m4_v3(float mat[][4], float vec[3]) +void mul_mat3_m4_v3(float mat[4][4], float vec[3]) { float x, y; @@ -356,7 +356,7 @@ void mul_mat3_m4_v3(float mat[][4], float vec[3]) vec[2] = x * mat[0][2] + y * mat[1][2] + mat[2][2] * vec[2]; } -void mul_project_m4_v3(float mat[][4], float vec[3]) +void mul_project_m4_v3(float mat[4][4], float vec[3]) { const float w = vec[0] * mat[0][3] + vec[1] * mat[1][3] + vec[2] * mat[2][3] + mat[3][3]; mul_m4_v3(mat, vec); @@ -419,7 +419,7 @@ void mul_m3_v3(float M[3][3], float r[3]) copy_v3_v3(r, tmp); } -void mul_transposed_m3_v3(float mat[][3], float vec[3]) +void mul_transposed_m3_v3(float mat[3][3], float vec[3]) { float x, y; @@ -457,7 +457,7 @@ void mul_mat3_m4_fl(float m[4][4], float f) m[i][j] *= f; } -void mul_m3_v3_double(float mat[][3], double vec[3]) +void mul_m3_v3_double(float mat[3][3], double vec[3]) { double x, y; @@ -468,7 +468,7 @@ void mul_m3_v3_double(float mat[][3], double vec[3]) vec[2] = x * (double)mat[0][2] + y * (double)mat[1][2] + (double)mat[2][2] * vec[2]; } -void add_m3_m3m3(float m1[][3], float m2[][3], float m3[][3]) +void add_m3_m3m3(float m1[3][3], float m2[3][3], float m3[3][3]) { int i, j; @@ -477,7 +477,7 @@ void add_m3_m3m3(float m1[][3], float m2[][3], float m3[][3]) m1[i][j] = m2[i][j] + m3[i][j]; } -void add_m4_m4m4(float m1[][4], float m2[][4], float m3[][4]) +void add_m4_m4m4(float m1[4][4], float m2[4][4], float m3[4][4]) { int i, j; @@ -486,7 +486,7 @@ void add_m4_m4m4(float m1[][4], float m2[][4], float m3[][4]) m1[i][j] = m2[i][j] + m3[i][j]; } -void sub_m3_m3m3(float m1[][3], float m2[][3], float m3[][3]) +void sub_m3_m3m3(float m1[3][3], float m2[3][3], float m3[3][3]) { int i, j; @@ -495,7 +495,7 @@ void sub_m3_m3m3(float m1[][3], float m2[][3], float m3[][3]) m1[i][j] = m2[i][j] - m3[i][j]; } -void sub_m4_m4m4(float m1[][4], float m2[][4], float m3[][4]) +void sub_m4_m4m4(float m1[4][4], float m2[4][4], float m3[4][4]) { int i, j; @@ -665,7 +665,7 @@ int invert_m4_m4(float inverse[4][4], float mat[4][4]) /****************************** Linear Algebra *******************************/ -void transpose_m3(float mat[][3]) +void transpose_m3(float mat[3][3]) { float t; @@ -680,7 +680,7 @@ void transpose_m3(float mat[][3]) mat[2][1] = t; } -void transpose_m4(float mat[][4]) +void transpose_m4(float mat[4][4]) { float t; @@ -706,7 +706,7 @@ void transpose_m4(float mat[][4]) mat[3][2] = t; } -void orthogonalize_m3(float mat[][3], int axis) +void orthogonalize_m3(float mat[3][3], int axis) { float size[3]; mat3_to_size(size, mat); @@ -784,7 +784,7 @@ void orthogonalize_m3(float mat[][3], int axis) mul_v3_fl(mat[2], size[2]); } -void orthogonalize_m4(float mat[][4], int axis) +void orthogonalize_m4(float mat[4][4], int axis) { float size[3]; mat4_to_size(size, mat); @@ -863,7 +863,7 @@ void orthogonalize_m4(float mat[][4], int axis) mul_v3_fl(mat[2], size[2]); } -int is_orthogonal_m3(float m[][3]) +int is_orthogonal_m3(float m[3][3]) { int i, j; @@ -877,7 +877,7 @@ int is_orthogonal_m3(float m[][3]) return 1; } -int is_orthogonal_m4(float m[][4]) +int is_orthogonal_m4(float m[4][4]) { int i, j; @@ -892,7 +892,7 @@ int is_orthogonal_m4(float m[][4]) return 1; } -int is_orthonormal_m3(float m[][3]) +int is_orthonormal_m3(float m[3][3]) { if (is_orthogonal_m3(m)) { int i; @@ -907,7 +907,7 @@ int is_orthonormal_m3(float m[][3]) return 0; } -int is_orthonormal_m4(float m[][4]) +int is_orthonormal_m4(float m[4][4]) { if (is_orthogonal_m4(m)) { int i; @@ -922,7 +922,7 @@ int is_orthonormal_m4(float m[][4]) return 0; } -int is_uniform_scaled_m3(float m[][3]) +int is_uniform_scaled_m3(float m[3][3]) { const float eps = 1e-7; float t[3][3]; @@ -951,21 +951,21 @@ int is_uniform_scaled_m3(float m[][3]) return 0; } -void normalize_m3(float mat[][3]) +void normalize_m3(float mat[3][3]) { normalize_v3(mat[0]); normalize_v3(mat[1]); normalize_v3(mat[2]); } -void normalize_m3_m3(float rmat[][3], float mat[][3]) +void normalize_m3_m3(float rmat[3][3], float mat[3][3]) { normalize_v3_v3(rmat[0], mat[0]); normalize_v3_v3(rmat[1], mat[1]); normalize_v3_v3(rmat[2], mat[2]); } -void normalize_m4(float mat[][4]) +void normalize_m4(float mat[4][4]) { float len; @@ -977,7 +977,7 @@ void normalize_m4(float mat[][4]) if (len != 0.0f) mat[2][3] /= len; } -void normalize_m4_m4(float rmat[][4], float mat[][4]) +void normalize_m4_m4(float rmat[4][4], float mat[4][4]) { float len; @@ -998,7 +998,7 @@ void adjoint_m2_m2(float m1[][2], float m[][2]) m1[1][1] = m[0][0]; } -void adjoint_m3_m3(float m1[][3], float m[][3]) +void adjoint_m3_m3(float m1[3][3], float m[3][3]) { BLI_assert(m1 != m); m1[0][0] = m[1][1] * m[2][2] - m[1][2] * m[2][1]; @@ -1014,7 +1014,7 @@ void adjoint_m3_m3(float m1[][3], float m[][3]) m1[2][2] = m[0][0] * m[1][1] - m[0][1] * m[1][0]; } -void adjoint_m4_m4(float out[][4], float in[][4]) /* out = ADJ(in) */ +void adjoint_m4_m4(float out[4][4], float in[4][4]) /* out = ADJ(in) */ { float a1, a2, a3, a4, b1, b2, b3, b4; float c1, c2, c3, c4, d1, d2, d3, d4; @@ -1080,7 +1080,7 @@ float determinant_m3(float a1, float a2, float a3, return ans; } -float determinant_m4(float m[][4]) +float determinant_m4(float m[4][4]) { float ans; float a1, a2, a3, a4, b1, b2, b3, b4, c1, c2, c3, c4, d1, d2, d3, d4; @@ -1115,7 +1115,7 @@ float determinant_m4(float m[][4]) /****************************** Transformations ******************************/ -void size_to_mat3(float mat[][3], const float size[3]) +void size_to_mat3(float mat[3][3], const float size[3]) { mat[0][0] = size[0]; mat[0][1] = 0.0f; @@ -1128,7 +1128,7 @@ void size_to_mat3(float mat[][3], const float size[3]) mat[2][0] = 0.0f; } -void size_to_mat4(float mat[][4], const float size[3]) +void size_to_mat4(float mat[4][4], const float size[3]) { float tmat[3][3]; @@ -1137,14 +1137,14 @@ void size_to_mat4(float mat[][4], const float size[3]) copy_m4_m3(mat, tmat); } -void mat3_to_size(float size[3], float mat[][3]) +void mat3_to_size(float size[3], float mat[3][3]) { size[0] = len_v3(mat[0]); size[1] = len_v3(mat[1]); size[2] = len_v3(mat[2]); } -void mat4_to_size(float size[3], float mat[][4]) +void mat4_to_size(float size[3], float mat[4][4]) { size[0] = len_v3(mat[0]); size[1] = len_v3(mat[1]); @@ -1154,7 +1154,7 @@ void mat4_to_size(float size[3], float mat[][4]) /* this gets the average scale of a matrix, only use when your scaling * data that has no idea of scale axis, examples are bone-envelope-radius * and curve radius */ -float mat3_to_scale(float mat[][3]) +float mat3_to_scale(float mat[3][3]) { /* unit length vector */ float unit_vec[3] = {0.577350269189626f, 0.577350269189626f, 0.577350269189626f}; @@ -1162,7 +1162,7 @@ float mat3_to_scale(float mat[][3]) return len_v3(unit_vec); } -float mat4_to_scale(float mat[][4]) +float mat4_to_scale(float mat[4][4]) { float tmat[3][3]; copy_m3_m4(tmat, mat); @@ -1200,7 +1200,7 @@ void mat3_to_rot_size(float rot[3][3], float size[3], float mat3[3][3]) size[2] = mat3[2][2]; } -void mat4_to_loc_rot_size(float loc[3], float rot[3][3], float size[3], float wmat[][4]) +void mat4_to_loc_rot_size(float loc[3], float rot[3][3], float size[3], float wmat[4][4]) { float mat3[3][3]; /* wmat -> 3x3 */ @@ -1211,7 +1211,7 @@ void mat4_to_loc_rot_size(float loc[3], float rot[3][3], float size[3], float wm copy_v3_v3(loc, wmat[3]); } -void scale_m3_fl(float m[][3], float scale) +void scale_m3_fl(float m[3][3], float scale) { m[0][0] = m[1][1] = m[2][2] = scale; m[0][1] = m[0][2] = 0.0; @@ -1219,7 +1219,7 @@ void scale_m3_fl(float m[][3], float scale) m[2][0] = m[2][1] = 0.0; } -void scale_m4_fl(float m[][4], float scale) +void scale_m4_fl(float m[4][4], float scale) { m[0][0] = m[1][1] = m[2][2] = scale; m[3][3] = 1.0; @@ -1229,14 +1229,14 @@ void scale_m4_fl(float m[][4], float scale) m[3][0] = m[3][1] = m[3][2] = 0.0; } -void translate_m4(float mat[][4], float Tx, float Ty, float Tz) +void translate_m4(float mat[4][4], float Tx, float Ty, float Tz) { mat[3][0] += (Tx * mat[0][0] + Ty * mat[1][0] + Tz * mat[2][0]); mat[3][1] += (Tx * mat[0][1] + Ty * mat[1][1] + Tz * mat[2][1]); mat[3][2] += (Tx * mat[0][2] + Ty * mat[1][2] + Tz * mat[2][2]); } -void rotate_m4(float mat[][4], const char axis, const float angle) +void rotate_m4(float mat[4][4], const char axis, const float angle) { int col; float temp[4] = {0.0f, 0.0f, 0.0f, 0.0f}; @@ -1276,7 +1276,7 @@ void rotate_m4(float mat[][4], const char axis, const float angle) } } -void blend_m3_m3m3(float out[][3], float dst[][3], float src[][3], const float srcweight) +void blend_m3_m3m3(float out[3][3], float dst[3][3], float src[3][3], const float srcweight) { float srot[3][3], drot[3][3]; float squat[4], dquat[4], fquat[4]; @@ -1299,7 +1299,7 @@ void blend_m3_m3m3(float out[][3], float dst[][3], float src[][3], const float s mul_m3_m3m3(out, rmat, smat); } -void blend_m4_m4m4(float out[][4], float dst[][4], float src[][4], const float srcweight) +void blend_m4_m4m4(float out[4][4], float dst[4][4], float src[4][4], const float srcweight) { float sloc[3], dloc[3], floc[3]; float srot[3][3], drot[3][3]; @@ -1321,14 +1321,14 @@ void blend_m4_m4m4(float out[][4], float dst[][4], float src[][4], const float s loc_quat_size_to_mat4(out, floc, fquat, fsize); } -int is_negative_m3(float mat[][3]) +int is_negative_m3(float mat[3][3]) { float vec[3]; cross_v3_v3v3(vec, mat[0], mat[1]); return (dot_v3v3(vec, mat[2]) < 0.0f); } -int is_negative_m4(float mat[][4]) +int is_negative_m4(float mat[4][4]) { float vec[3]; cross_v3_v3v3(vec, mat[0], mat[1]); @@ -1418,7 +1418,7 @@ void loc_axisangle_size_to_mat4(float mat[4][4], const float loc[3], const float /*********************************** Other ***********************************/ -void print_m3(const char *str, float m[][3]) +void print_m3(const char *str, float m[3][3]) { printf("%s\n", str); printf("%f %f %f\n", m[0][0], m[1][0], m[2][0]); @@ -1427,7 +1427,7 @@ void print_m3(const char *str, float m[][3]) printf("\n"); } -void print_m4(const char *str, float m[][4]) +void print_m4(const char *str, float m[4][4]) { printf("%s\n", str); printf("%f %f %f %f\n", m[0][0], m[1][0], m[2][0], m[3][0]); diff --git a/source/blender/blenlib/intern/math_rotation.c b/source/blender/blenlib/intern/math_rotation.c index 3069542107e..71f146e8131 100644 --- a/source/blender/blenlib/intern/math_rotation.c +++ b/source/blender/blenlib/intern/math_rotation.c @@ -185,7 +185,7 @@ void mul_fac_qt_fl(float q[4], const float fac) } /* skip error check, currently only needed by mat3_to_quat_is_ok */ -static void quat_to_mat3_no_error(float m[][3], const float q[4]) +static void quat_to_mat3_no_error(float m[3][3], const float q[4]) { double q0, q1, q2, q3, qda, qdb, qdc, qaa, qab, qac, qbb, qbc, qcc; @@ -217,7 +217,7 @@ static void quat_to_mat3_no_error(float m[][3], const float q[4]) m[2][2] = (float)(1.0 - qaa - qbb); } -void quat_to_mat3(float m[][3], const float q[4]) +void quat_to_mat3(float m[3][3], const float q[4]) { #ifdef DEBUG float f; @@ -229,7 +229,7 @@ void quat_to_mat3(float m[][3], const float q[4]) quat_to_mat3_no_error(m, q); } -void quat_to_mat4(float m[][4], const float q[4]) +void quat_to_mat4(float m[4][4], const float q[4]) { double q0, q1, q2, q3, qda, qdb, qdc, qaa, qab, qac, qbb, qbc, qcc; @@ -273,7 +273,7 @@ void quat_to_mat4(float m[][4], const float q[4]) m[3][3] = 1.0f; } -void mat3_to_quat(float q[4], float wmat[][3]) +void mat3_to_quat(float q[4], float wmat[3][3]) { double tr, s; float mat[3][3]; @@ -325,7 +325,7 @@ void mat3_to_quat(float q[4], float wmat[][3]) normalize_qt(q); } -void mat4_to_quat(float q[4], float m[][4]) +void mat4_to_quat(float q[4], float m[4][4]) { float mat[3][3]; @@ -861,7 +861,7 @@ void single_axis_angle_to_mat3(float mat[3][3], const char axis, const float ang /* TODO: the following calls should probably be deprecated sometime */ /* TODO, replace use of this function with axis_angle_to_mat3() */ -void vec_rot_to_mat3(float mat[][3], const float vec[3], const float phi) +void vec_rot_to_mat3(float mat[3][3], const float vec[3], const float phi) { /* rotation of phi radials around vec */ float vx, vx2, vy, vy2, vz, vz2, co, si; @@ -889,7 +889,7 @@ void vec_rot_to_mat3(float mat[][3], const float vec[3], const float phi) /******************************** XYZ Eulers *********************************/ /* XYZ order */ -void eul_to_mat3(float mat[][3], const float eul[3]) +void eul_to_mat3(float mat[3][3], const float eul[3]) { double ci, cj, ch, si, sj, sh, cc, cs, sc, ss; @@ -917,7 +917,7 @@ void eul_to_mat3(float mat[][3], const float eul[3]) } /* XYZ order */ -void eul_to_mat4(float mat[][4], const float eul[3]) +void eul_to_mat4(float mat[4][4], const float eul[3]) { double ci, cj, ch, si, sj, sh, cc, cs, sc, ss; @@ -950,7 +950,7 @@ void eul_to_mat4(float mat[][4], const float eul[3]) /* returns two euler calculation methods, so we can pick the best */ /* XYZ order */ -static void mat3_to_eul2(float tmat[][3], float eul1[3], float eul2[3]) +static void mat3_to_eul2(float tmat[3][3], float eul1[3], float eul2[3]) { float cy, quat[4], mat[3][3]; @@ -982,7 +982,7 @@ static void mat3_to_eul2(float tmat[][3], float eul1[3], float eul2[3]) } /* XYZ order */ -void mat3_to_eul(float *eul, float tmat[][3]) +void mat3_to_eul(float *eul, float tmat[3][3]) { float eul1[3], eul2[3]; @@ -998,7 +998,7 @@ void mat3_to_eul(float *eul, float tmat[][3]) } /* XYZ order */ -void mat4_to_eul(float *eul, float tmat[][4]) +void mat4_to_eul(float *eul, float tmat[4][4]) { float tempMat[3][3]; @@ -1107,7 +1107,7 @@ void compatible_eul(float eul[3], const float oldrot[3]) /* uses 2 methods to retrieve eulers, and picks the closest */ /* XYZ order */ -void mat3_to_compatible_eul(float eul[3], const float oldrot[3], float mat[][3]) +void mat3_to_compatible_eul(float eul[3], const float oldrot[3], float mat[3][3]) { float eul1[3], eul2[3]; float d1, d2; @@ -1388,7 +1388,7 @@ void rotate_eulO(float beul[3], const short order, char axis, float ang) } /* the matrix is written to as 3 axis vectors */ -void eulO_to_gimbal_axis(float gmat[][3], const float eul[3], const short order) +void eulO_to_gimbal_axis(float gmat[3][3], const float eul[3], const short order) { const RotOrderInfo *R = GET_ROTATIONORDER_INFO(order); @@ -1447,7 +1447,7 @@ void eulO_to_gimbal_axis(float gmat[][3], const float eul[3], const short order) * - added support for scaling */ -void mat4_to_dquat(DualQuat *dq, float basemat[][4], float mat[][4]) +void mat4_to_dquat(DualQuat *dq, float basemat[4][4], float mat[4][4]) { float *t, *q, dscale[3], scale[3], basequat[4]; float baseRS[4][4], baseinv[4][4], baseR[4][4], baseRinv[4][4]; @@ -1502,7 +1502,7 @@ void mat4_to_dquat(DualQuat *dq, float basemat[][4], float mat[][4]) dq->trans[3] = 0.5f * ( t[0] * q[2] - t[1] * q[1] + t[2] * q[0]); } -void dquat_to_mat4(float mat[][4], DualQuat *dq) +void dquat_to_mat4(float mat[4][4], DualQuat *dq) { float len, *t, q0[4]; @@ -1583,7 +1583,7 @@ void normalize_dq(DualQuat *dq, float totweight) } } -void mul_v3m3_dq(float co[3], float mat[][3], DualQuat *dq) +void mul_v3m3_dq(float co[3], float mat[3][3], DualQuat *dq) { float M[3][3], t[3], scalemat[3][3], len2; float w = dq->quat[0], x = dq->quat[1], y = dq->quat[2], z = dq->quat[3]; diff --git a/source/blender/blenlib/intern/math_vector_inline.c b/source/blender/blenlib/intern/math_vector_inline.c index 3ede8636aa5..04b9d574347 100644 --- a/source/blender/blenlib/intern/math_vector_inline.c +++ b/source/blender/blenlib/intern/math_vector_inline.c @@ -544,7 +544,7 @@ MINLINE void add_newell_cross_v3_v3v3(float n[3], const float v_prev[3], const f n[2] += (v_prev[0] - v_curr[0]) * (v_prev[1] + v_curr[1]); } -MINLINE void star_m3_v3(float rmat[][3], float a[3]) +MINLINE void star_m3_v3(float rmat[3][3], float a[3]) { rmat[0][0] = rmat[1][1] = rmat[2][2] = 0.0; rmat[0][1] = -a[2]; diff --git a/source/blender/collada/ArmatureImporter.cpp b/source/blender/collada/ArmatureImporter.cpp index cd2574d055e..f1cf732e695 100644 --- a/source/blender/collada/ArmatureImporter.cpp +++ b/source/blender/collada/ArmatureImporter.cpp @@ -79,7 +79,7 @@ JointData *ArmatureImporter::get_joint_data(COLLADAFW::Node *node); } #endif void ArmatureImporter::create_unskinned_bone(COLLADAFW::Node *node, EditBone *parent, int totchild, - float parent_mat[][4], Object *ob_arm) + float parent_mat[4][4], Object *ob_arm) { std::vector::iterator it; it = std::find(finished_joints.begin(), finished_joints.end(), node); @@ -156,7 +156,7 @@ void ArmatureImporter::create_unskinned_bone(COLLADAFW::Node *node, EditBone *pa } void ArmatureImporter::create_bone(SkinInfo& skin, COLLADAFW::Node *node, EditBone *parent, int totchild, - float parent_mat[][4], bArmature *arm) + float parent_mat[4][4], bArmature *arm) { //Checking if bone is already made. std::vector::iterator it; @@ -268,7 +268,7 @@ void ArmatureImporter::create_bone(SkinInfo& skin, COLLADAFW::Node *node, EditBo finished_joints.push_back(node); } -void ArmatureImporter::add_leaf_bone(float mat[][4], EditBone *bone, COLLADAFW::Node *node) +void ArmatureImporter::add_leaf_bone(float mat[4][4], EditBone *bone, COLLADAFW::Node *node) { LeafBone leaf; @@ -572,7 +572,7 @@ void ArmatureImporter::create_armature_bones(SkinInfo& skin) // is a child of a node (not joint), root should be true since // this is where we build armature bones from -void ArmatureImporter::set_pose(Object *ob_arm, COLLADAFW::Node *root_node, const char *parentname, float parent_mat[][4]) +void ArmatureImporter::set_pose(Object *ob_arm, COLLADAFW::Node *root_node, const char *parentname, float parent_mat[4][4]) { char *bone_name = (char *) bc_get_joint_name(root_node); float mat[4][4]; @@ -792,7 +792,7 @@ void ArmatureImporter::get_rna_path_for_joint(COLLADAFW::Node *node, char *joint } // gives a world-space mat -bool ArmatureImporter::get_joint_bind_mat(float m[][4], COLLADAFW::Node *joint) +bool ArmatureImporter::get_joint_bind_mat(float m[4][4], COLLADAFW::Node *joint) { std::map::iterator it; bool found = false; diff --git a/source/blender/collada/ArmatureImporter.h b/source/blender/collada/ArmatureImporter.h index a6b37287479..bb710f09490 100644 --- a/source/blender/collada/ArmatureImporter.h +++ b/source/blender/collada/ArmatureImporter.h @@ -104,16 +104,16 @@ private: #endif void create_bone(SkinInfo& skin, COLLADAFW::Node *node, EditBone *parent, int totchild, - float parent_mat[][4], bArmature *arm); + float parent_mat[4][4], bArmature *arm); void create_unskinned_bone(COLLADAFW::Node *node, EditBone *parent, int totchild, - float parent_mat[][4], Object * ob_arm); + float parent_mat[4][4], Object * ob_arm); - void add_leaf_bone(float mat[][4], EditBone *bone, COLLADAFW::Node * node); + void add_leaf_bone(float mat[4][4], EditBone *bone, COLLADAFW::Node * node); void fix_leaf_bones(); - void set_pose ( Object * ob_arm, COLLADAFW::Node * root_node, const char *parentname, float parent_mat[][4]); + void set_pose ( Object * ob_arm, COLLADAFW::Node * root_node, const char *parentname, float parent_mat[4][4]); #if 0 @@ -168,7 +168,7 @@ public: void get_rna_path_for_joint(COLLADAFW::Node *node, char *joint_path, size_t count); // gives a world-space mat - bool get_joint_bind_mat(float m[][4], COLLADAFW::Node *joint); + bool get_joint_bind_mat(float m[4][4], COLLADAFW::Node *joint); void set_tags_map( TagsMap& tags_map); diff --git a/source/blender/collada/SkinInfo.cpp b/source/blender/collada/SkinInfo.cpp index 9b0d59d66ea..470f663f716 100644 --- a/source/blender/collada/SkinInfo.cpp +++ b/source/blender/collada/SkinInfo.cpp @@ -168,7 +168,7 @@ Object *SkinInfo::set_armature(Object *ob_arm) return ob_arm; } -bool SkinInfo::get_joint_inv_bind_matrix(float inv_bind_mat[][4], COLLADAFW::Node *node) +bool SkinInfo::get_joint_inv_bind_matrix(float inv_bind_mat[4][4], COLLADAFW::Node *node) { const COLLADAFW::UniqueId& uid = node->getUniqueId(); std::vector::iterator it; diff --git a/source/blender/collada/SkinInfo.h b/source/blender/collada/SkinInfo.h index 894f53f07c3..e074f59cffc 100644 --- a/source/blender/collada/SkinInfo.h +++ b/source/blender/collada/SkinInfo.h @@ -103,7 +103,7 @@ public: Object* set_armature(Object *ob_arm); - bool get_joint_inv_bind_matrix(float inv_bind_mat[][4], COLLADAFW::Node *node); + bool get_joint_inv_bind_matrix(float inv_bind_mat[4][4], COLLADAFW::Node *node); Object *BKE_armature_from_object(); diff --git a/source/blender/collada/TransformReader.cpp b/source/blender/collada/TransformReader.cpp index 61793589422..5bc135e9b67 100644 --- a/source/blender/collada/TransformReader.cpp +++ b/source/blender/collada/TransformReader.cpp @@ -34,7 +34,7 @@ TransformReader::TransformReader(UnitConverter *conv) : unit_converter(conv) /* pass */ } -void TransformReader::get_node_mat(float mat[][4], COLLADAFW::Node *node, std::map *animation_map, Object *ob) +void TransformReader::get_node_mat(float mat[4][4], COLLADAFW::Node *node, std::map *animation_map, Object *ob) { float cur[4][4]; float copy[4][4]; @@ -79,7 +79,7 @@ void TransformReader::get_node_mat(float mat[][4], COLLADAFW::Node *node, std::m } } -void TransformReader::dae_rotate_to_mat4(COLLADAFW::Transformation *tm, float m[][4]) +void TransformReader::dae_rotate_to_mat4(COLLADAFW::Transformation *tm, float m[4][4]) { COLLADAFW::Rotate *ro = (COLLADAFW::Rotate *)tm; COLLADABU::Math::Vector3& axis = ro->getRotationAxis(); @@ -91,7 +91,7 @@ void TransformReader::dae_rotate_to_mat4(COLLADAFW::Transformation *tm, float m[ axis_angle_to_mat4(m, ax, angle); } -void TransformReader::dae_translate_to_mat4(COLLADAFW::Transformation *tm, float m[][4]) +void TransformReader::dae_translate_to_mat4(COLLADAFW::Transformation *tm, float m[4][4]) { COLLADAFW::Translate *tra = (COLLADAFW::Translate *)tm; COLLADABU::Math::Vector3& t = tra->getTranslation(); @@ -103,14 +103,14 @@ void TransformReader::dae_translate_to_mat4(COLLADAFW::Transformation *tm, float m[3][2] = (float)t[2]; } -void TransformReader::dae_scale_to_mat4(COLLADAFW::Transformation *tm, float m[][4]) +void TransformReader::dae_scale_to_mat4(COLLADAFW::Transformation *tm, float m[4][4]) { COLLADABU::Math::Vector3& s = ((COLLADAFW::Scale *)tm)->getScale(); float size[3] = {(float)s[0], (float)s[1], (float)s[2]}; size_to_mat4(m, size); } -void TransformReader::dae_matrix_to_mat4(COLLADAFW::Transformation *tm, float m[][4]) +void TransformReader::dae_matrix_to_mat4(COLLADAFW::Transformation *tm, float m[4][4]) { unit_converter->dae_matrix_to_mat4_(m, ((COLLADAFW::Matrix *)tm)->getMatrix()); } diff --git a/source/blender/collada/TransformReader.h b/source/blender/collada/TransformReader.h index 47e59a1bf52..ab974b9ba85 100644 --- a/source/blender/collada/TransformReader.h +++ b/source/blender/collada/TransformReader.h @@ -58,12 +58,12 @@ public: TransformReader(UnitConverter *conv); - void get_node_mat(float mat[][4], COLLADAFW::Node *node, std::map *animation_map, Object *ob); + void get_node_mat(float mat[4][4], COLLADAFW::Node *node, std::map *animation_map, Object *ob); - void dae_rotate_to_mat4(COLLADAFW::Transformation *tm, float m[][4]); - void dae_translate_to_mat4(COLLADAFW::Transformation *tm, float m[][4]); - void dae_scale_to_mat4(COLLADAFW::Transformation *tm, float m[][4]); - void dae_matrix_to_mat4(COLLADAFW::Transformation *tm, float m[][4]); + void dae_rotate_to_mat4(COLLADAFW::Transformation *tm, float m[4][4]); + void dae_translate_to_mat4(COLLADAFW::Transformation *tm, float m[4][4]); + void dae_scale_to_mat4(COLLADAFW::Transformation *tm, float m[4][4]); + void dae_matrix_to_mat4(COLLADAFW::Transformation *tm, float m[4][4]); void dae_translate_to_v3(COLLADAFW::Transformation *tm, float v[3]); void dae_scale_to_v3(COLLADAFW::Transformation *tm, float v[3]); void dae_vector3_to_v3(const COLLADABU::Math::Vector3 &v3, float v[3]); diff --git a/source/blender/collada/TransformWriter.cpp b/source/blender/collada/TransformWriter.cpp index 0d6e3831637..3fe3f620a68 100644 --- a/source/blender/collada/TransformWriter.cpp +++ b/source/blender/collada/TransformWriter.cpp @@ -32,7 +32,7 @@ #include "BLI_math.h" -void TransformWriter::add_node_transform(COLLADASW::Node& node, float mat[][4], float parent_mat[][4]) +void TransformWriter::add_node_transform(COLLADASW::Node& node, float mat[4][4], float parent_mat[4][4]) { float loc[3], rot[3], scale[3]; float local[4][4]; diff --git a/source/blender/collada/TransformWriter.h b/source/blender/collada/TransformWriter.h index 917e26dac1a..d2a4b54a570 100644 --- a/source/blender/collada/TransformWriter.h +++ b/source/blender/collada/TransformWriter.h @@ -37,7 +37,7 @@ class TransformWriter : protected TransformBase { protected: - void add_node_transform(COLLADASW::Node& node, float mat[][4], float parent_mat[][4]); + void add_node_transform(COLLADASW::Node& node, float mat[4][4], float parent_mat[4][4]); void add_node_transform_ob(COLLADASW::Node& node, Object *ob); diff --git a/source/blender/collada/collada_internal.cpp b/source/blender/collada/collada_internal.cpp index a4969735757..0c95cd6a31a 100644 --- a/source/blender/collada/collada_internal.cpp +++ b/source/blender/collada/collada_internal.cpp @@ -74,7 +74,7 @@ void UnitConverter::convertVector3(COLLADABU::Math::Vector3 &vec, float *v) // TODO need also for angle conversion, time conversion... -void UnitConverter::dae_matrix_to_mat4_(float out[][4], const COLLADABU::Math::Matrix4& in) +void UnitConverter::dae_matrix_to_mat4_(float out[4][4], const COLLADABU::Math::Matrix4& in) { // in DAE, matrices use columns vectors, (see comments in COLLADABUMathMatrix4.h) // so here, to make a blender matrix, we swap columns and rows @@ -85,13 +85,13 @@ void UnitConverter::dae_matrix_to_mat4_(float out[][4], const COLLADABU::Math::M } } -void UnitConverter::mat4_to_dae(float out[][4], float in[][4]) +void UnitConverter::mat4_to_dae(float out[4][4], float const in[4][4]) { copy_m4_m4(out, in); transpose_m4(out); } -void UnitConverter::mat4_to_dae_double(double out[][4], float in[][4]) +void UnitConverter::mat4_to_dae_double(double out[4][4], float in[4][4]) { float mat[4][4]; @@ -102,7 +102,7 @@ void UnitConverter::mat4_to_dae_double(double out[][4], float in[][4]) out[i][j] = mat[i][j]; } -void TransformBase::decompose(float mat[][4], float *loc, float eul[3], float quat[4], float *size) +void TransformBase::decompose(float mat[4][4], float *loc, float eul[3], float quat[4], float *size) { mat4_to_size(size, mat); if (eul) { diff --git a/source/blender/collada/collada_internal.h b/source/blender/collada/collada_internal.h index 6eec6a1675e..d92f53f714c 100644 --- a/source/blender/collada/collada_internal.h +++ b/source/blender/collada/collada_internal.h @@ -69,17 +69,17 @@ public: // TODO need also for angle conversion, time conversion... - void dae_matrix_to_mat4_(float out[][4], const COLLADABU::Math::Matrix4& in); + void dae_matrix_to_mat4_(float out[4][4], const COLLADABU::Math::Matrix4& in); - void mat4_to_dae(float out[][4], float in[][4]); + void mat4_to_dae(float out[4][4], float in[4][4]); - void mat4_to_dae_double(double out[][4], float in[][4]); + void mat4_to_dae_double(double out[4][4], float in[4][4]); }; class TransformBase { public: - void decompose(float mat[][4], float *loc, float eul[3], float quat[4], float *size); + void decompose(float mat[4][4], float *loc, float eul[3], float quat[4], float *size); }; extern void clear_global_id_map(); diff --git a/source/blender/editors/armature/BIF_generate.h b/source/blender/editors/armature/BIF_generate.h index 06ee3fbb64c..71109574fe0 100644 --- a/source/blender/editors/armature/BIF_generate.h +++ b/source/blender/editors/armature/BIF_generate.h @@ -40,9 +40,10 @@ int nextFixedSubdivision(struct ToolSettings *toolsettings, struct BArcIterator int nextLengthSubdivision(struct ToolSettings *toolsettings, struct BArcIterator *iter, int start, int end, float head[3], float p[3]); int nextAdaptativeSubdivision(struct ToolSettings *toolsettings, struct BArcIterator *iter, int start, int end, float head[3], float p[3]); -struct EditBone *subdivideArcBy(struct ToolSettings *toolsettings, struct bArmature *arm, ListBase *editbones, struct BArcIterator *iter, float invmat[][4], float tmat[][3], NextSubdivisionFunc next_subdividion); +struct EditBone *subdivideArcBy(struct ToolSettings *toolsettings, struct bArmature *arm, ListBase *editbones, struct BArcIterator *iter, + float invmat[4][4], float tmat[3][3], NextSubdivisionFunc next_subdividion); -void setBoneRollFromNormal(struct EditBone *bone, const float no[3], float invmat[][4], float tmat[][3]); +void setBoneRollFromNormal(struct EditBone *bone, const float no[3], float invmat[4][4], float tmat[3][3]); #endif /* __BIF_GENERATE_H__ */ diff --git a/source/blender/editors/armature/editarmature_generate.c b/source/blender/editors/armature/editarmature_generate.c index d9c7e78c01e..979c352c4b2 100644 --- a/source/blender/editors/armature/editarmature_generate.c +++ b/source/blender/editors/armature/editarmature_generate.c @@ -50,7 +50,7 @@ #include "armature_intern.h" #include "BIF_generate.h" -void setBoneRollFromNormal(EditBone *bone, const float no[3], float UNUSED(invmat[][4]), float tmat[][3]) +void setBoneRollFromNormal(EditBone *bone, const float no[3], float UNUSED(invmat[4][4]), float tmat[3][3]) { if (no != NULL && !is_zero_v3(no)) { float normal[3]; @@ -257,7 +257,8 @@ int nextLengthSubdivision(ToolSettings *toolsettings, BArcIterator *iter, int st return -1; } -EditBone *subdivideArcBy(ToolSettings *toolsettings, bArmature *arm, ListBase *UNUSED(editbones), BArcIterator *iter, float invmat[][4], float tmat[][3], NextSubdivisionFunc next_subdividion) +EditBone *subdivideArcBy(ToolSettings *toolsettings, bArmature *arm, ListBase *UNUSED(editbones), BArcIterator *iter, + float invmat[4][4], float tmat[3][3], NextSubdivisionFunc next_subdividion) { EditBone *lastBone = NULL; EditBone *child = NULL; diff --git a/source/blender/editors/armature/editarmature_sketch.c b/source/blender/editors/armature/editarmature_sketch.c index f9cf4a29269..b61aa86a52f 100644 --- a/source/blender/editors/armature/editarmature_sketch.c +++ b/source/blender/editors/armature/editarmature_sketch.c @@ -361,7 +361,7 @@ static void sk_autoname(bContext *C, ReebArc *arc) } } -static ReebNode *sk_pointToNode(SK_Point *pt, float imat[][4], float tmat[][3]) +static ReebNode *sk_pointToNode(SK_Point *pt, float imat[4][4], float tmat[3][3]) { ReebNode *node; @@ -375,7 +375,7 @@ static ReebNode *sk_pointToNode(SK_Point *pt, float imat[][4], float tmat[][3]) return node; } -static ReebArc *sk_strokeToArc(SK_Stroke *stk, float imat[][4], float tmat[][3]) +static ReebArc *sk_strokeToArc(SK_Stroke *stk, float imat[4][4], float tmat[3][3]) { ReebArc *arc; int i; diff --git a/source/blender/editors/armature/meshlaplacian.c b/source/blender/editors/armature/meshlaplacian.c index 1d97542172a..5376c897c29 100644 --- a/source/blender/editors/armature/meshlaplacian.c +++ b/source/blender/editors/armature/meshlaplacian.c @@ -862,7 +862,7 @@ static void rigid_add_edge_to_R(LaplacianSystem *sys, EditVert *v1, EditVert *v2 rigid_add_half_edge_to_R(sys, v2, v1, w); } -static void rigid_orthogonalize_R(float R[][3]) +static void rigid_orthogonalize_R(float R[3][3]) { HMatrix M, Q, S; @@ -1956,7 +1956,7 @@ static void heat_weighting_bind(Scene *scene, DerivedMesh *dm, MeshDeformModifie } #endif -void mesh_deform_bind(Scene *scene, MeshDeformModifierData *mmd, float *vertexcos, int totvert, float cagemat[][4]) +void mesh_deform_bind(Scene *scene, MeshDeformModifierData *mmd, float *vertexcos, int totvert, float cagemat[4][4]) { MeshDeformBind mdb; MVert *mvert; diff --git a/source/blender/editors/curve/editcurve.c b/source/blender/editors/curve/editcurve.c index 23fed4ce8fc..f4dccd01007 100644 --- a/source/blender/editors/curve/editcurve.c +++ b/source/blender/editors/curve/editcurve.c @@ -1493,7 +1493,7 @@ static void setflagsNurb(ListBase *editnurb, short flag) } } -static void rotateflagNurb(ListBase *editnurb, short flag, float *cent, float rotmat[][3]) +static void rotateflagNurb(ListBase *editnurb, short flag, float *cent, float rotmat[3][3]) { /* all verts with (flag & 'flag') rotate */ Nurb *nu; @@ -4278,7 +4278,7 @@ int mouse_nurb(bContext *C, const int mval[2], int extend, int deselect, int tog /* 'cent' is in object space and 'dvec' in worldspace. */ -static int spin_nurb(float viewmat[][4], Object *obedit, float *axis, float *cent) +static int spin_nurb(float viewmat[4][4], Object *obedit, float *axis, float *cent) { Curve *cu = (Curve *)obedit->data; ListBase *editnurb = object_editcurve_get(obedit); diff --git a/source/blender/editors/include/ED_armature.h b/source/blender/editors/include/ED_armature.h index efd10f3cb6b..4db79df033e 100644 --- a/source/blender/editors/include/ED_armature.h +++ b/source/blender/editors/include/ED_armature.h @@ -184,7 +184,7 @@ int BDR_drawSketchNames(struct ViewContext *vc); /* meshlaplacian.c */ void mesh_deform_bind(struct Scene *scene, struct MeshDeformModifierData *mmd, - float *vertexcos, int totvert, float cagemat[][4]); + float *vertexcos, int totvert, float cagemat[4][4]); #ifdef __cplusplus } diff --git a/source/blender/editors/include/ED_object.h b/source/blender/editors/include/ED_object.h index 0d0b8d8e797..533bfe2fa20 100644 --- a/source/blender/editors/include/ED_object.h +++ b/source/blender/editors/include/ED_object.h @@ -134,7 +134,7 @@ void ED_object_location_from_view(struct bContext *C, float loc[3]); void ED_object_rotation_from_view(struct bContext *C, float rot[3]); void ED_object_base_init_transform(struct bContext *C, struct Base *base, const float loc[3], const float rot[3]); float ED_object_new_primitive_matrix(struct bContext *C, struct Object *editob, - const float loc[3], const float rot[3], float primmat[][4], + const float loc[3], const float rot[3], float primmat[4][4], int apply_diameter); void ED_object_add_generic_props(struct wmOperatorType *ot, int do_editmode); diff --git a/source/blender/editors/include/ED_transform.h b/source/blender/editors/include/ED_transform.h index d7e9fc323a6..03c1dd5a86d 100644 --- a/source/blender/editors/include/ED_transform.h +++ b/source/blender/editors/include/ED_transform.h @@ -124,7 +124,7 @@ void BIF_createTransformOrientation(struct bContext *C, struct ReportList *repor void BIF_selectTransformOrientation(struct bContext *C, struct TransformOrientation *ts); void BIF_selectTransformOrientationValue(struct bContext *C, int orientation); -void ED_getTransformOrientationMatrix(const struct bContext *C, float orientation_mat[][3], int activeOnly); +void ED_getTransformOrientationMatrix(const struct bContext *C, float orientation_mat[3][3], int activeOnly); struct EnumPropertyItem *BIF_enumTransformOrientation(struct bContext *C); const char *BIF_menustringTransformOrientation(const struct bContext *C, const char *title); /* the returned value was allocated and needs to be freed after use */ diff --git a/source/blender/editors/include/ED_view3d.h b/source/blender/editors/include/ED_view3d.h index f15f2418707..d83835f8dc5 100644 --- a/source/blender/editors/include/ED_view3d.h +++ b/source/blender/editors/include/ED_view3d.h @@ -86,8 +86,8 @@ typedef struct ViewDepths { float *give_cursor(struct Scene *scene, struct View3D *v3d); -void ED_view3d_to_m4(float mat[][4], const float ofs[3], const float quat[4], const float dist); -void ED_view3d_from_m4(float mat[][4], float ofs[3], float quat[4], float *dist); +void ED_view3d_to_m4(float mat[4][4], const float ofs[3], const float quat[4], const float dist); +void ED_view3d_from_m4(float mat[4][4], float ofs[3], float quat[4], float *dist); void ED_view3d_from_object(struct Object *ob, float ofs[3], float quat[4], float *dist, float *lens); void ED_view3d_to_object(struct Object *ob, const float ofs[3], const float quat[4], const float dist); @@ -208,7 +208,7 @@ void ED_view3d_calc_camera_border(struct Scene *scene, struct ARegion *ar, struc void ED_view3d_calc_camera_border_size(struct Scene *scene, struct ARegion *ar, struct View3D *v3d, struct RegionView3D *rv3d, float size_r[2]); void ED_view3d_clipping_calc(struct BoundBox *bb, float planes[4][4], struct bglMats *mats, const struct rcti *rect); -void ED_view3d_clipping_local(struct RegionView3D *rv3d, float mat[][4]); +void ED_view3d_clipping_local(struct RegionView3D *rv3d, float mat[4][4]); int ED_view3d_clipping_test(struct RegionView3D *rv3d, const float vec[3], const int is_local); void ED_view3d_clipping_set(struct RegionView3D *rv3d); void ED_view3d_clipping_enable(void); @@ -219,7 +219,7 @@ float ED_view3d_pixel_size(struct RegionView3D *rv3d, const float co[3]); float ED_view3d_radius_to_persp_dist(const float angle, const float radius); float ED_view3d_radius_to_ortho_dist(const float lens, const float radius); -void drawcircball(int mode, const float cent[3], float rad, float tmat[][4]); +void drawcircball(int mode, const float cent[3], float rad, float tmat[4][4]); /* backbuffer select and draw support */ void view3d_validate_backbuf(struct ViewContext *vc); @@ -264,7 +264,7 @@ int ED_view3d_scene_layer_set(int lay, const int *values, int *active); int ED_view3d_context_activate(struct bContext *C); void ED_view3d_draw_offscreen_init(struct Scene *scene, struct View3D *v3d); void ED_view3d_draw_offscreen(struct Scene *scene, struct View3D *v3d, struct ARegion *ar, - int winx, int winy, float viewmat[][4], float winmat[][4], int do_bgpic, int colormanage_background); + int winx, int winy, float viewmat[4][4], float winmat[4][4], int do_bgpic, int colormanage_background); struct ImBuf *ED_view3d_draw_offscreen_imbuf(struct Scene *scene, struct View3D *v3d, struct ARegion *ar, int sizex, int sizey, unsigned int flag, int draw_background, int colormanage_background, char err_out[256]); @@ -274,7 +274,7 @@ struct ImBuf *ED_view3d_draw_offscreen_imbuf_simple(struct Scene *scene, struct struct Base *ED_view3d_give_base_under_cursor(struct bContext *C, const int mval[2]); void ED_view3d_quadview_update(struct ScrArea *sa, struct ARegion *ar, short do_clip); -void ED_view3d_update_viewmat(struct Scene *scene, struct View3D *v3d, struct ARegion *ar, float viewmat[][4], float winmat[][4]); +void ED_view3d_update_viewmat(struct Scene *scene, struct View3D *v3d, struct ARegion *ar, float viewmat[4][4], float winmat[4][4]); int ED_view3d_lock(struct RegionView3D *rv3d); uint64_t ED_view3d_datamask(struct Scene *scene, struct View3D *v3d); diff --git a/source/blender/editors/mesh/editmesh_add.c b/source/blender/editors/mesh/editmesh_add.c index 4a425c83d86..763c6c98a99 100644 --- a/source/blender/editors/mesh/editmesh_add.c +++ b/source/blender/editors/mesh/editmesh_add.c @@ -58,7 +58,7 @@ /* BMESH_TODO: 'state' is not a good name, should be flipped and called 'was_editmode', * or at least something more descriptive */ static Object *make_prim_init(bContext *C, const char *idname, - float *dia, float mat[][4], + float *dia, float mat[4][4], int *state, const float loc[3], const float rot[3], const unsigned int layer) { Object *obedit = CTX_data_edit_object(C); diff --git a/source/blender/editors/mesh/editmesh_rip.c b/source/blender/editors/mesh/editmesh_rip.c index 2ecc20b2ddb..9b8f90bc7cf 100644 --- a/source/blender/editors/mesh/editmesh_rip.c +++ b/source/blender/editors/mesh/editmesh_rip.c @@ -63,7 +63,7 @@ * point and would result in the same distance. */ #define INSET_DEFAULT 0.00001f -static float edbm_rip_edgedist(ARegion *ar, float mat[][4], +static float edbm_rip_edgedist(ARegion *ar, float mat[4][4], const float co1[3], const float co2[3], const float mvalf[2], const float inset) { @@ -83,7 +83,7 @@ static float edbm_rip_edgedist(ARegion *ar, float mat[][4], } #if 0 -static float edbm_rip_linedist(ARegion *ar, float mat[][4], +static float edbm_rip_linedist(ARegion *ar, float mat[4][4], const float co1[3], const float co2[3], const float mvalf[2]) { float vec1[2], vec2[2]; diff --git a/source/blender/editors/object/object_add.c b/source/blender/editors/object/object_add.c index 7c4a547debc..b3c0368adfe 100644 --- a/source/blender/editors/object/object_add.c +++ b/source/blender/editors/object/object_add.c @@ -186,7 +186,7 @@ void ED_object_base_init_transform(bContext *C, Base *base, const float loc[3], /* Uses context to figure out transform for primitive. * Returns standard diameter. */ float ED_object_new_primitive_matrix(bContext *C, Object *obedit, - const float loc[3], const float rot[3], float primmat[][4], + const float loc[3], const float rot[3], float primmat[4][4], int apply_diameter) { Scene *scene = CTX_data_scene(C); diff --git a/source/blender/editors/physics/particle_edit.c b/source/blender/editors/physics/particle_edit.c index f5754297e9f..6a56a5fdb33 100644 --- a/source/blender/editors/physics/particle_edit.c +++ b/source/blender/editors/physics/particle_edit.c @@ -516,7 +516,7 @@ static int point_is_selected(PTCacheEditPoint *point) typedef void (*ForPointFunc)(PEData *data, int point_index); typedef void (*ForKeyFunc)(PEData *data, int point_index, int key_index); -typedef void (*ForKeyMatFunc)(PEData *data, float mat[][4], float imat[][4], int point_index, int key_index, PTCacheEditKey *key); +typedef void (*ForKeyMatFunc)(PEData *data, float mat[4][4], float imat[4][4], int point_index, int key_index, PTCacheEditKey *key); static void for_mouse_hit_keys(PEData *data, ForKeyFunc func, int nearest) { @@ -2766,7 +2766,7 @@ void PARTICLE_OT_mirror(wmOperatorType *ot) /************************* brush edit callbacks ********************/ -static void brush_comb(PEData *data, float UNUSED(mat[][4]), float imat[][4], int point_index, int key_index, PTCacheEditKey *key) +static void brush_comb(PEData *data, float UNUSED(mat[4][4]), float imat[4][4], int point_index, int key_index, PTCacheEditKey *key) { ParticleEditSettings *pset= PE_settings(data->scene); float cvec[3], fac; @@ -3038,7 +3038,7 @@ static void brush_puff(PEData *data, int point_index) } -static void BKE_brush_weight_get(PEData *data, float UNUSED(mat[][4]), float UNUSED(imat[][4]), int point_index, int key_index, PTCacheEditKey *UNUSED(key)) +static void BKE_brush_weight_get(PEData *data, float UNUSED(mat[4][4]), float UNUSED(imat[4][4]), int point_index, int key_index, PTCacheEditKey *UNUSED(key)) { /* roots have full weight allways */ if (key_index) { @@ -3052,7 +3052,7 @@ static void BKE_brush_weight_get(PEData *data, float UNUSED(mat[][4]), float UNU } } -static void brush_smooth_get(PEData *data, float mat[][4], float UNUSED(imat[][4]), int UNUSED(point_index), int key_index, PTCacheEditKey *key) +static void brush_smooth_get(PEData *data, float mat[4][4], float UNUSED(imat[4][4]), int UNUSED(point_index), int key_index, PTCacheEditKey *key) { if (key_index) { float dvec[3]; @@ -3064,7 +3064,7 @@ static void brush_smooth_get(PEData *data, float mat[][4], float UNUSED(imat[][4 } } -static void brush_smooth_do(PEData *data, float UNUSED(mat[][4]), float imat[][4], int point_index, int key_index, PTCacheEditKey *key) +static void brush_smooth_do(PEData *data, float UNUSED(mat[4][4]), float imat[4][4], int point_index, int key_index, PTCacheEditKey *key) { float vec[3], dvec[3]; diff --git a/source/blender/editors/sculpt_paint/paint_utils.c b/source/blender/editors/sculpt_paint/paint_utils.c index cb4b6346c2a..e7d13bd080d 100644 --- a/source/blender/editors/sculpt_paint/paint_utils.c +++ b/source/blender/editors/sculpt_paint/paint_utils.c @@ -189,7 +189,7 @@ float paint_get_tex_pixel(Brush *br, float u, float v) /* 3D Paint */ -static void imapaint_project(Object *ob, float model[][4], float proj[][4], const float co[3], float pco[4]) +static void imapaint_project(Object *ob, float model[4][4], float proj[4][4], const float co[3], float pco[4]) { copy_v3_v3(pco, co); pco[3] = 1.0f; diff --git a/source/blender/editors/sculpt_paint/paint_vertex.c b/source/blender/editors/sculpt_paint/paint_vertex.c index 94b00101dc2..90ca1a6b18a 100644 --- a/source/blender/editors/sculpt_paint/paint_vertex.c +++ b/source/blender/editors/sculpt_paint/paint_vertex.c @@ -873,7 +873,7 @@ static float calc_vp_strength_dl(VPaint *vp, ViewContext *vc, const float vert_n } static float calc_vp_alpha_dl(VPaint *vp, ViewContext *vc, - float vpimat[][3], const float *vert_nor, + float vpimat[3][3], const float *vert_nor, const float mval[2], const float brush_size_pressure, const float brush_alpha_pressure) { diff --git a/source/blender/editors/space_view3d/drawarmature.c b/source/blender/editors/space_view3d/drawarmature.c index beafee335d4..f37437b159d 100644 --- a/source/blender/editors/space_view3d/drawarmature.c +++ b/source/blender/editors/space_view3d/drawarmature.c @@ -637,7 +637,7 @@ static float co[16] = { /* smat, imat = mat & imat to draw screenaligned */ -static void draw_sphere_bone_dist(float smat[][4], float imat[][4], bPoseChannel *pchan, EditBone *ebone) +static void draw_sphere_bone_dist(float smat[4][4], float imat[4][4], bPoseChannel *pchan, EditBone *ebone) { float head, tail, dist /*, length*/; float *headvec, *tailvec, dirvec[3]; @@ -755,7 +755,7 @@ static void draw_sphere_bone_dist(float smat[][4], float imat[][4], bPoseChannel /* smat, imat = mat & imat to draw screenaligned */ -static void draw_sphere_bone_wire(float smat[][4], float imat[][4], +static void draw_sphere_bone_wire(float smat[4][4], float imat[4][4], int armflag, int boneflag, short constflag, unsigned int id, bPoseChannel *pchan, EditBone *ebone) { @@ -1648,7 +1648,7 @@ static void draw_pose_dofs(Object *ob) } } -static void bone_matrix_translate_y(float mat[][4], float y) +static void bone_matrix_translate_y(float mat[4][4], float y) { float trans[3]; @@ -2069,7 +2069,7 @@ static void draw_pose_bones(Scene *scene, View3D *v3d, ARegion *ar, Base *base, } /* in editmode, we don't store the bone matrix... */ -static void get_matrix_editbone(EditBone *eBone, float bmat[][4]) +static void get_matrix_editbone(EditBone *eBone, float bmat[4][4]) { float delta[3]; float mat[3][3]; diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c index 5ac7327b93b..055afda189f 100644 --- a/source/blender/editors/space_view3d/drawobject.c +++ b/source/blender/editors/space_view3d/drawobject.c @@ -622,7 +622,7 @@ static void draw_empty_image(Object *ob, const short dflag, const unsigned char BKE_image_release_ibuf(ima, ibuf, NULL); } -static void circball_array_fill(float verts[CIRCLE_RESOL][3], const float cent[3], float rad, float tmat[][4]) +static void circball_array_fill(float verts[CIRCLE_RESOL][3], const float cent[3], float rad, float tmat[4][4]) { float vx[3], vy[3]; float *viter = (float *)verts; @@ -638,7 +638,7 @@ static void circball_array_fill(float verts[CIRCLE_RESOL][3], const float cent[3 } } -void drawcircball(int mode, const float cent[3], float rad, float tmat[][4]) +void drawcircball(int mode, const float cent[3], float rad, float tmat[4][4]) { float verts[CIRCLE_RESOL][3]; @@ -739,7 +739,7 @@ void view3d_cached_text_draw_add(const float co[3], memcpy(++vos, str, alloc_len); } -void view3d_cached_text_draw_end(View3D *v3d, ARegion *ar, int depth_write, float mat[][4]) +void view3d_cached_text_draw_end(View3D *v3d, ARegion *ar, int depth_write, float mat[4][4]) { RegionView3D *rv3d = ar->regiondata; ListBase *strings = &CachedText[CachedTextLevel - 1]; @@ -929,7 +929,7 @@ static void drawcube_size(const float size[3]) } #endif -static void drawshadbuflimits(Lamp *la, float mat[][4]) +static void drawshadbuflimits(Lamp *la, float mat[4][4]) { float sta[3], end[3], lavec[3]; @@ -5446,7 +5446,7 @@ static void draw_textcurs(float textcurs[4][2]) set_inverted_drawing(0); } -static void drawspiral(const float cent[3], float rad, float tmat[][4], int start) +static void drawspiral(const float cent[3], float rad, float tmat[4][4], int start) { float vec[3], vx[3], vy[3]; const float tot_inv = (1.0f / (float)CIRCLE_RESOL); @@ -5535,7 +5535,7 @@ static void drawcircle_size(float size) } /* needs fixing if non-identity matrice used */ -static void drawtube(const float vec[3], float radius, float height, float tmat[][4]) +static void drawtube(const float vec[3], float radius, float height, float tmat[4][4]) { float cur[3]; drawcircball(GL_LINE_LOOP, vec, radius, tmat); @@ -5557,7 +5557,7 @@ static void drawtube(const float vec[3], float radius, float height, float tmat[ glEnd(); } /* needs fixing if non-identity matrice used */ -static void drawcone(const float vec[3], float radius, float height, float tmat[][4]) +static void drawcone(const float vec[3], float radius, float height, float tmat[4][4]) { float cur[3]; diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c index 51261f4c341..a2e16efadd4 100644 --- a/source/blender/editors/space_view3d/view3d_draw.c +++ b/source/blender/editors/space_view3d/view3d_draw.c @@ -217,7 +217,7 @@ void ED_view3d_clipping_enable(void) } } -static int view3d_clipping_test(const float vec[3], float clip[][4]) +static int view3d_clipping_test(const float vec[3], float clip[6][4]) { float view[3]; copy_v3_v3(view, vec); @@ -2307,7 +2307,7 @@ typedef struct View3DShadow { } View3DShadow; static void gpu_render_lamp_update(Scene *scene, View3D *v3d, Object *ob, Object *par, - float obmat[][4], ListBase *shadows) + float obmat[4][4], ListBase *shadows) { GPULamp *lamp; Lamp *la = (Lamp *)ob->data; @@ -2466,7 +2466,7 @@ CustomDataMask ED_view3d_screen_datamask(bScreen *screen) return mask; } -void ED_view3d_update_viewmat(Scene *scene, View3D *v3d, ARegion *ar, float viewmat[][4], float winmat[][4]) +void ED_view3d_update_viewmat(Scene *scene, View3D *v3d, ARegion *ar, float viewmat[4][4], float winmat[4][4]) { RegionView3D *rv3d = ar->regiondata; @@ -2509,7 +2509,7 @@ void ED_view3d_update_viewmat(Scene *scene, View3D *v3d, ARegion *ar, float view } } -static void view3d_main_area_setup_view(Scene *scene, View3D *v3d, ARegion *ar, float viewmat[][4], float winmat[][4]) +static void view3d_main_area_setup_view(Scene *scene, View3D *v3d, ARegion *ar, float viewmat[4][4], float winmat[4][4]) { RegionView3D *rv3d = ar->regiondata; @@ -2533,7 +2533,7 @@ void ED_view3d_draw_offscreen_init(Scene *scene, View3D *v3d) * stuff like shadow buffers */ void ED_view3d_draw_offscreen(Scene *scene, View3D *v3d, ARegion *ar, - int winx, int winy, float viewmat[][4], float winmat[][4], + int winx, int winy, float viewmat[4][4], float winmat[4][4], int do_bgpic, int colormanage_background) { RegionView3D *rv3d = ar->regiondata; diff --git a/source/blender/editors/space_view3d/view3d_edit.c b/source/blender/editors/space_view3d/view3d_edit.c index d45013c40d9..dc3baf04a74 100644 --- a/source/blender/editors/space_view3d/view3d_edit.c +++ b/source/blender/editors/space_view3d/view3d_edit.c @@ -3576,7 +3576,7 @@ static void calc_clipping_plane(float clip[6][4], BoundBox *clipbb) } } -static void calc_local_clipping(float clip_local[][4], BoundBox *clipbb, float mat[][4]) +static void calc_local_clipping(float clip_local[6][4], BoundBox *clipbb, float mat[4][4]) { BoundBox clipbb_local; float imat[4][4]; @@ -3591,7 +3591,7 @@ static void calc_local_clipping(float clip_local[][4], BoundBox *clipbb, float m calc_clipping_plane(clip_local, &clipbb_local); } -void ED_view3d_clipping_local(RegionView3D *rv3d, float mat[][4]) +void ED_view3d_clipping_local(RegionView3D *rv3d, float mat[4][4]) { if (rv3d->rflag & RV3D_CLIPPING) calc_local_clipping(rv3d->clip_local, rv3d->clipbb, mat); @@ -3997,7 +3997,7 @@ float ED_view3d_offset_distance(float mat[4][4], float ofs[3]) { * \param quat The view rotation, quaternion normally from RegionView3D.viewquat. * \param dist The view distance from ofs, normally from RegionView3D.dist. */ -void ED_view3d_from_m4(float mat[][4], float ofs[3], float quat[4], float *dist) +void ED_view3d_from_m4(float mat[4][4], float ofs[3], float quat[4], float *dist) { /* Offset */ if (ofs) @@ -4034,7 +4034,7 @@ void ED_view3d_from_m4(float mat[][4], float ofs[3], float quat[4], float *dist) * \param quat The view rotation, quaternion normally from RegionView3D.viewquat. * \param dist The view distance from ofs, normally from RegionView3D.dist. */ -void ED_view3d_to_m4(float mat[][4], const float ofs[3], const float quat[4], const float dist) +void ED_view3d_to_m4(float mat[4][4], const float ofs[3], const float quat[4], const float dist) { float iviewquat[4] = {-quat[0], quat[1], quat[2], quat[3]}; float dvec[3] = {0.0f, 0.0f, dist}; diff --git a/source/blender/editors/space_view3d/view3d_intern.h b/source/blender/editors/space_view3d/view3d_intern.h index 5beeda9f220..f8a7cdde8a5 100644 --- a/source/blender/editors/space_view3d/view3d_intern.h +++ b/source/blender/editors/space_view3d/view3d_intern.h @@ -125,7 +125,7 @@ void drawaxes(float size, char drawtype); void view3d_cached_text_draw_begin(void); void view3d_cached_text_draw_add(const float co[3], const char *str, short xoffs, short flag, const unsigned char col[4]); -void view3d_cached_text_draw_end(View3D * v3d, ARegion * ar, int depth_write, float mat[][4]); +void view3d_cached_text_draw_end(View3D * v3d, ARegion * ar, int depth_write, float mat[4][4]); enum { V3D_CACHE_TEXT_ZBUF = (1 << 0), @@ -172,7 +172,7 @@ void VIEW3D_OT_localview(struct wmOperatorType *ot); void VIEW3D_OT_game_start(struct wmOperatorType *ot); -int ED_view3d_boundbox_clip(RegionView3D * rv3d, float obmat[][4], struct BoundBox *bb); +int ED_view3d_boundbox_clip(RegionView3D * rv3d, float obmat[4][4], struct BoundBox *bb); void view3d_smooth_view(struct bContext *C, struct View3D *v3d, struct ARegion *ar, struct Object *, struct Object *, float *ofs, float *quat, float *dist, float *lens); diff --git a/source/blender/editors/space_view3d/view3d_view.c b/source/blender/editors/space_view3d/view3d_view.c index ef15c1e734e..505b99dad01 100644 --- a/source/blender/editors/space_view3d/view3d_view.c +++ b/source/blender/editors/space_view3d/view3d_view.c @@ -579,7 +579,7 @@ void ED_view3d_clipping_calc(BoundBox *bb, float planes[4][4], bglMats *mats, co } -int ED_view3d_boundbox_clip(RegionView3D *rv3d, float obmat[][4], BoundBox *bb) +int ED_view3d_boundbox_clip(RegionView3D *rv3d, float obmat[4][4], BoundBox *bb) { /* return 1: draw */ diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c index 6145fec7e51..d877d506e3e 100644 --- a/source/blender/editors/transform/transform.c +++ b/source/blender/editors/transform/transform.c @@ -2884,7 +2884,7 @@ BLI_INLINE int tx_vec_sign_flip(const float a[3], const float b[3]) } /* smat is reference matrix, only scaled */ -static void TransMat3ToSize(float mat[][3], float smat[][3], float size[3]) +static void TransMat3ToSize(float mat[3][3], float smat[3][3], float size[3]) { float vec[3]; diff --git a/source/blender/editors/transform/transform.h b/source/blender/editors/transform/transform.h index bc959a772d6..08fe1e7676b 100644 --- a/source/blender/editors/transform/transform.h +++ b/source/blender/editors/transform/transform.h @@ -572,7 +572,7 @@ void flushTransTracking(TransInfo *t); void flushTransMasking(TransInfo *t); /*********************** exported from transform_manipulator.c ********** */ -int gimbal_axis(struct Object *ob, float gmat[][3]); /* return 0 when no gimbal for selection */ +int gimbal_axis(struct Object *ob, float gmat[3][3]); /* return 0 when no gimbal for selection */ int calc_manipulator_stats(const struct bContext *C); /*********************** TransData Creation and General Handling *********** */ diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c index 51efa2b0e40..884ec03cc62 100644 --- a/source/blender/editors/transform/transform_conversions.c +++ b/source/blender/editors/transform/transform_conversions.c @@ -1769,7 +1769,7 @@ void flushTransParticles(TransInfo *t) * but instead it's a depth-first search, fudged * to report shortest distances. I have no idea how fast * or slow this is. */ -static void editmesh_set_connectivity_distance(BMEditMesh *em, float mtx[][3], float *dists) +static void editmesh_set_connectivity_distance(BMEditMesh *em, float mtx[3][3], float *dists) { BMVert **queue = NULL; float *dqueue = NULL; diff --git a/source/blender/editors/transform/transform_manipulator.c b/source/blender/editors/transform/transform_manipulator.c index a3f45acc02e..757fdfa2445 100644 --- a/source/blender/editors/transform/transform_manipulator.c +++ b/source/blender/editors/transform/transform_manipulator.c @@ -199,7 +199,7 @@ static int test_rotmode_euler(short rotmode) return (ELEM(rotmode, ROT_MODE_AXISANGLE, ROT_MODE_QUAT)) ? 0 : 1; } -int gimbal_axis(Object *ob, float gmat[][3]) +int gimbal_axis(Object *ob, float gmat[3][3]) { if (ob) { if (ob->mode & OB_MODE_POSE) { @@ -638,7 +638,7 @@ static void test_manipulator_axis(const bContext *C) /* ******************** DRAWING STUFFIES *********** */ -static float screen_aligned(RegionView3D *rv3d, float mat[][4]) +static float screen_aligned(RegionView3D *rv3d, float mat[4][4]) { glTranslatef(mat[3][0], mat[3][1], mat[3][2]); @@ -826,7 +826,7 @@ static void draw_manipulator_axes(View3D *v3d, RegionView3D *rv3d, int colcode, } } -static void preOrthoFront(int ortho, float twmat[][4], int axis) +static void preOrthoFront(int ortho, float twmat[4][4], int axis) { if (ortho == 0) { float omat[4][4]; diff --git a/source/blender/editors/transform/transform_orientations.c b/source/blender/editors/transform/transform_orientations.c index 70e4d4cd027..d758a15f50c 100644 --- a/source/blender/editors/transform/transform_orientations.c +++ b/source/blender/editors/transform/transform_orientations.c @@ -851,7 +851,7 @@ int getTransformOrientation(const bContext *C, float normal[3], float plane[3], return result; } -void ED_getTransformOrientationMatrix(const bContext *C, float orientation_mat[][3], int activeOnly) +void ED_getTransformOrientationMatrix(const bContext *C, float orientation_mat[3][3], int activeOnly) { float normal[3] = {0.0, 0.0, 0.0}; float plane[3] = {0.0, 0.0, 0.0}; diff --git a/source/blender/editors/transform/transform_snap.c b/source/blender/editors/transform/transform_snap.c index 2d95e2ecdc6..9de9c96f2ec 100644 --- a/source/blender/editors/transform/transform_snap.c +++ b/source/blender/editors/transform/transform_snap.c @@ -1141,7 +1141,7 @@ static void TargetSnapClosest(TransInfo *t) } } -static int snapEdge(ARegion *ar, float v1co[3], short v1no[3], float v2co[3], short v2no[3], float obmat[][4], float timat[][3], +static int snapEdge(ARegion *ar, float v1co[3], short v1no[3], float v2co[3], short v2no[3], float obmat[4][4], float timat[3][3], const float ray_start[3], const float ray_start_local[3], const float ray_normal_local[3], const float mval[2], float r_loc[3], float r_no[3], int *r_dist, float *r_depth) { @@ -1228,7 +1228,7 @@ static int snapEdge(ARegion *ar, float v1co[3], short v1no[3], float v2co[3], sh return retval; } -static int snapVertex(ARegion *ar, float vco[3], short vno[3], float obmat[][4], float timat[][3], +static int snapVertex(ARegion *ar, float vco[3], short vno[3], float obmat[4][4], float timat[3][3], const float ray_start[3], const float ray_start_local[3], const float ray_normal_local[3], const float mval[2], float r_loc[3], float r_no[3], int *r_dist, float *r_depth) { @@ -1276,7 +1276,7 @@ static int snapVertex(ARegion *ar, float vco[3], short vno[3], float obmat[][4], return retval; } -static int snapArmature(short snap_mode, ARegion *ar, Object *ob, bArmature *arm, float obmat[][4], +static int snapArmature(short snap_mode, ARegion *ar, Object *ob, bArmature *arm, float obmat[4][4], const float ray_start[3], const float ray_normal[3], const float mval[2], float r_loc[3], float *UNUSED(r_no), int *r_dist, float *r_depth) { @@ -1339,7 +1339,7 @@ static int snapArmature(short snap_mode, ARegion *ar, Object *ob, bArmature *arm return retval; } -static int snapDerivedMesh(short snap_mode, ARegion *ar, Object *ob, DerivedMesh *dm, BMEditMesh *em, float obmat[][4], +static int snapDerivedMesh(short snap_mode, ARegion *ar, Object *ob, DerivedMesh *dm, BMEditMesh *em, float obmat[4][4], const float ray_start[3], const float ray_normal[3], const float mval[2], float r_loc[3], float r_no[3], int *r_dist, float *r_depth) { @@ -1517,7 +1517,7 @@ static int snapDerivedMesh(short snap_mode, ARegion *ar, Object *ob, DerivedMesh return retval; } -static int snapObject(Scene *scene, ARegion *ar, Object *ob, int editobject, float obmat[][4], +static int snapObject(Scene *scene, ARegion *ar, Object *ob, int editobject, float obmat[4][4], const float ray_start[3], const float ray_normal[3], const float mval[2], float r_loc[3], float r_no[3], int *r_dist, float *r_depth) { @@ -1670,7 +1670,7 @@ static void addDepthPeel(ListBase *depth_peels, float depth, float p[3], float n peel->flag = 0; } -static int peelDerivedMesh(Object *ob, DerivedMesh *dm, float obmat[][4], +static int peelDerivedMesh(Object *ob, DerivedMesh *dm, float obmat[4][4], const float ray_start[3], const float ray_normal[3], const float UNUSED(mval[2]), ListBase *depth_peels) { diff --git a/source/blender/editors/uvedit/uvedit_unwrap_ops.c b/source/blender/editors/uvedit/uvedit_unwrap_ops.c index 1f3f21967f4..6e6de03a834 100644 --- a/source/blender/editors/uvedit/uvedit_unwrap_ops.c +++ b/source/blender/editors/uvedit/uvedit_unwrap_ops.c @@ -907,7 +907,7 @@ static void uv_map_transform_center(Scene *scene, View3D *v3d, float *result, } } -static void uv_map_rotation_matrix(float result[][4], RegionView3D *rv3d, Object *ob, +static void uv_map_rotation_matrix(float result[4][4], RegionView3D *rv3d, Object *ob, float upangledeg, float sideangledeg, float radius) { float rotup[4][4], rotside[4][4], viewmatrix[4][4], rotobj[4][4]; diff --git a/source/blender/gpu/GPU_draw.h b/source/blender/gpu/GPU_draw.h index b26c25558c3..974865db1c0 100644 --- a/source/blender/gpu/GPU_draw.h +++ b/source/blender/gpu/GPU_draw.h @@ -93,7 +93,7 @@ int GPU_set_tpage(struct MTFace *tface, int mipmap, int transp); int GPU_default_lights(void); int GPU_scene_object_lights(struct Scene *scene, struct Object *ob, - int lay, float viewmat[][4], int ortho); + int lay, float viewmat[4][4], int ortho); /* Text render * - based on moving uv coordinates */ diff --git a/source/blender/gpu/GPU_material.h b/source/blender/gpu/GPU_material.h index c46230de8bf..20791652735 100644 --- a/source/blender/gpu/GPU_material.h +++ b/source/blender/gpu/GPU_material.h @@ -127,7 +127,7 @@ void GPU_material_free(struct Material *ma); void GPU_materials_free(void); void GPU_material_bind(GPUMaterial *material, int oblay, int viewlay, double time, int mipmap); -void GPU_material_bind_uniforms(GPUMaterial *material, float obmat[][4], float viewmat[][4], float viewinv[][4], float obcol[4], float autobumpscale); +void GPU_material_bind_uniforms(GPUMaterial *material, float obmat[4][4], float viewmat[4][4], float viewinv[4][4], float obcol[4], float autobumpscale); void GPU_material_unbind(GPUMaterial *material); int GPU_material_bound(GPUMaterial *material); @@ -232,10 +232,10 @@ void GPU_lamp_free(struct Object *ob); int GPU_lamp_has_shadow_buffer(GPULamp *lamp); void GPU_lamp_update_buffer_mats(GPULamp *lamp); -void GPU_lamp_shadow_buffer_bind(GPULamp *lamp, float viewmat[][4], int *winsize, float winmat[][4]); +void GPU_lamp_shadow_buffer_bind(GPULamp *lamp, float viewmat[4][4], int *winsize, float winmat[4][4]); void GPU_lamp_shadow_buffer_unbind(GPULamp *lamp); -void GPU_lamp_update(GPULamp *lamp, int lay, int hide, float obmat[][4]); +void GPU_lamp_update(GPULamp *lamp, int lay, int hide, float obmat[4][4]); void GPU_lamp_update_colors(GPULamp *lamp, float r, float g, float b, float energy); void GPU_lamp_update_distance(GPULamp *lamp, float distance, float att1, float att2); void GPU_lamp_update_spot(GPULamp *lamp, float spotsize, float spotblend); diff --git a/source/blender/gpu/intern/gpu_draw.c b/source/blender/gpu/intern/gpu_draw.c index d466e59452b..f4810c540c3 100644 --- a/source/blender/gpu/intern/gpu_draw.c +++ b/source/blender/gpu/intern/gpu_draw.c @@ -1593,7 +1593,7 @@ int GPU_default_lights(void) return count; } -int GPU_scene_object_lights(Scene *scene, Object *ob, int lay, float viewmat[][4], int ortho) +int GPU_scene_object_lights(Scene *scene, Object *ob, int lay, float viewmat[4][4], int ortho) { Base *base; Lamp *la; diff --git a/source/blender/gpu/intern/gpu_material.c b/source/blender/gpu/intern/gpu_material.c index 9c48f74bf5f..09776fd1714 100644 --- a/source/blender/gpu/intern/gpu_material.c +++ b/source/blender/gpu/intern/gpu_material.c @@ -282,7 +282,7 @@ void GPU_material_bind(GPUMaterial *material, int oblay, int viewlay, double tim } } -void GPU_material_bind_uniforms(GPUMaterial *material, float obmat[][4], float viewmat[][4], float viewinv[][4], float obcol[4], float autobumpscale) +void GPU_material_bind_uniforms(GPUMaterial *material, float obmat[4][4], float viewmat[4][4], float viewinv[4][4], float obcol[4], float autobumpscale) { if (material->pass) { GPUShader *shader = GPU_pass_shader(material->pass); @@ -1572,7 +1572,7 @@ void GPU_materials_free(void) /* Lamps and shadow buffers */ -void GPU_lamp_update(GPULamp *lamp, int lay, int hide, float obmat[][4]) +void GPU_lamp_update(GPULamp *lamp, int lay, int hide, float obmat[4][4]) { float mat[4][4]; @@ -1854,7 +1854,7 @@ void GPU_lamp_update_buffer_mats(GPULamp *lamp) mult_m4_m4m4(lamp->persmat, rangemat, persmat); } -void GPU_lamp_shadow_buffer_bind(GPULamp *lamp, float viewmat[][4], int *winsize, float winmat[][4]) +void GPU_lamp_shadow_buffer_bind(GPULamp *lamp, float viewmat[4][4], int *winsize, float winmat[4][4]) { GPU_lamp_update_buffer_mats(lamp); diff --git a/source/blender/ikplugin/intern/iksolver_plugin.c b/source/blender/ikplugin/intern/iksolver_plugin.c index ca81f4c915a..75aaa23369b 100644 --- a/source/blender/ikplugin/intern/iksolver_plugin.c +++ b/source/blender/ikplugin/intern/iksolver_plugin.c @@ -206,7 +206,7 @@ static void make_dmats(bPoseChannel *pchan) /* applies IK matrix to pchan, IK is done separated */ /* formula: pose_mat(b) = pose_mat(b-1) * diffmat(b-1, b) * ik_mat(b) */ /* to make this work, the diffmats have to be precalculated! Stored in chan_mat */ -static void where_is_ik_bone(bPoseChannel *pchan, float ik_mat[][3]) // nr = to detect if this is first bone +static void where_is_ik_bone(bPoseChannel *pchan, float ik_mat[3][3]) // nr = to detect if this is first bone { float vec[3], ikmat[4][4]; diff --git a/source/blender/makesdna/DNA_modifier_types.h b/source/blender/makesdna/DNA_modifier_types.h index 3875a0d5799..68aa7600cd1 100644 --- a/source/blender/makesdna/DNA_modifier_types.h +++ b/source/blender/makesdna/DNA_modifier_types.h @@ -586,7 +586,7 @@ typedef struct MeshDeformModifierData { /* runtime */ void (*bindfunc)(struct Scene *scene, struct MeshDeformModifierData *mmd, - float *vertexcos, int totvert, float cagemat[][4]); + float *vertexcos, int totvert, float cagemat[4][4]); } MeshDeformModifierData; typedef enum { diff --git a/source/blender/modifiers/intern/MOD_boolean_util.c b/source/blender/modifiers/intern/MOD_boolean_util.c index 2ff93532d14..0cf4f6a008f 100644 --- a/source/blender/modifiers/intern/MOD_boolean_util.c +++ b/source/blender/modifiers/intern/MOD_boolean_util.c @@ -305,7 +305,7 @@ static Object *AddNewBlenderMesh(Scene *scene, Base *base) static void InterpCSGFace( DerivedMesh *dm, DerivedMesh *orig_dm, int index, int orig_index, int nr, - float mapmat[][4]) + float mapmat[4][4]) { float obco[3], *co[4], *orig_co[4], w[4][4]; MFace *mface, *orig_mface; @@ -344,8 +344,8 @@ static void InterpCSGFace( static DerivedMesh *ConvertCSGDescriptorsToDerivedMesh( CSG_FaceIteratorDescriptor *face_it, CSG_VertexIteratorDescriptor *vertex_it, - float parinv[][4], - float mapmat[][4], + float parinv[4][4], + float mapmat[4][4], Material **mat, int *totmat, DerivedMesh *dm1, diff --git a/source/blender/modifiers/intern/MOD_fluidsim_util.c b/source/blender/modifiers/intern/MOD_fluidsim_util.c index 13d409dc941..b39ddf62c55 100644 --- a/source/blender/modifiers/intern/MOD_fluidsim_util.c +++ b/source/blender/modifiers/intern/MOD_fluidsim_util.c @@ -301,7 +301,7 @@ static DerivedMesh *fluidsim_read_obj(const char *filename, const MPoly *mp_exam } -void fluid_get_bb(MVert *mvert, int totvert, float obmat[][4], +void fluid_get_bb(MVert *mvert, int totvert, float obmat[4][4], /*RET*/ float start[3], /*RET*/ float size[3]) { float bbsx = 0.0, bbsy = 0.0, bbsz = 0.0; diff --git a/source/blender/render/extern/include/RE_pipeline.h b/source/blender/render/extern/include/RE_pipeline.h index ecdd1774221..f97e5ac3c59 100644 --- a/source/blender/render/extern/include/RE_pipeline.h +++ b/source/blender/render/extern/include/RE_pipeline.h @@ -198,7 +198,7 @@ void RE_SetOrtho (struct Render *re, rctf *viewplane, float clipsta, float clipe void RE_SetPixelSize(struct Render *re, float pixsize); /* option to set viewmatrix before making dbase */ -void RE_SetView (struct Render *re, float mat[][4]); +void RE_SetView (struct Render *re, float mat[4][4]); /* make or free the dbase */ void RE_Database_FromScene(struct Render *re, struct Main *bmain, struct Scene *scene, unsigned int lay, int use_camera_view); @@ -273,8 +273,8 @@ int RE_seq_render_active(struct Scene *scene, struct RenderData *rd); void RE_Database_Baking(struct Render *re, struct Main *bmain, struct Scene *scene, unsigned int lay, const int type, struct Object *actob); -void RE_DataBase_GetView(struct Render *re, float mat[][4]); -void RE_GetCameraWindow(struct Render *re, struct Object *camera, int frame, float mat[][4]); +void RE_DataBase_GetView(struct Render *re, float mat[4][4]); +void RE_GetCameraWindow(struct Render *re, struct Object *camera, int frame, float mat[4][4]); struct Scene *RE_GetScene(struct Render *re); int RE_is_rendering_allowed(struct Scene *scene, struct Object *camera_override, struct ReportList *reports); diff --git a/source/blender/render/intern/include/pixelblending.h b/source/blender/render/intern/include/pixelblending.h index bb2e7e7f9f9..19759bf3e97 100644 --- a/source/blender/render/intern/include/pixelblending.h +++ b/source/blender/render/intern/include/pixelblending.h @@ -38,8 +38,8 @@ */ void add_filt_fmask(unsigned int mask, const float col[4], float *rowbuf, int row_w); void add_filt_fmask_pixsize(unsigned int mask, float *in, float *rowbuf, int row_w, int pixsize); -void add_filt_fmask_coord(float filt[][3], const float col[4], float *rowbuf, int row_w, int col_h, int x, int y); -void mask_array(unsigned int mask, float filt[][3]); +void add_filt_fmask_coord(float filt[3][3], const float col[4], float *rowbuf, int row_w, int col_h, int x, int y); +void mask_array(unsigned int mask, float filt[3][3]); /** * Alpha-over blending for floats. diff --git a/source/blender/render/intern/include/rayobject.h b/source/blender/render/intern/include/rayobject.h index 07fc7d7a6ed..7a9d242a2a1 100644 --- a/source/blender/render/intern/include/rayobject.h +++ b/source/blender/render/intern/include/rayobject.h @@ -56,7 +56,7 @@ int RE_rayobject_raycast(RayObject *r, struct Isect *i); /* Acceleration Structures */ RayObject *RE_rayobject_octree_create(int ocres, int size); -RayObject *RE_rayobject_instance_create(RayObject *target, float transform[][4], void *ob, void *target_ob); +RayObject *RE_rayobject_instance_create(RayObject *target, float transform[4][4], void *ob, void *target_ob); RayObject *RE_rayobject_empty_create(void); RayObject *RE_rayobject_blibvh_create(int size); /* BLI_kdopbvh.c */ diff --git a/source/blender/render/intern/include/renderdatabase.h b/source/blender/render/intern/include/renderdatabase.h index 5213f14d773..24989b13c48 100644 --- a/source/blender/render/intern/include/renderdatabase.h +++ b/source/blender/render/intern/include/renderdatabase.h @@ -87,8 +87,8 @@ void free_renderdata_tables(struct Render *re); void free_renderdata_vertnodes(struct VertTableNode *vertnodes); void free_renderdata_vlaknodes(struct VlakTableNode *vlaknodes); -void project_renderdata(struct Render *re, void (*projectfunc)(const float *, float mat[][4], float *), int do_pano, float xoffs, int do_buckets); -int clip_render_object(float boundbox[][3], float bounds[4], float mat[][4]); +void project_renderdata(struct Render *re, void (*projectfunc)(const float *, float mat[4][4], float *), int do_pano, float xoffs, int do_buckets); +int clip_render_object(float boundbox[2][3], float bounds[4], float mat[4][4]); /* functions are not exported... so wrong names */ @@ -106,7 +106,7 @@ struct HaloRen *RE_inithalo_particle(struct Render *re, struct ObjectRen *obr, s struct StrandBuffer *RE_addStrandBuffer(struct ObjectRen *obr, int totvert); struct ObjectRen *RE_addRenderObject(struct Render *re, struct Object *ob, struct Object *par, int index, int psysindex, int lay); -struct ObjectInstanceRen *RE_addRenderInstance(struct Render *re, struct ObjectRen *obr, struct Object *ob, struct Object *par, int index, int psysindex, float mat[][4], int lay); +struct ObjectInstanceRen *RE_addRenderInstance(struct Render *re, struct ObjectRen *obr, struct Object *ob, struct Object *par, int index, int psysindex, float mat[4][4], int lay); void RE_makeRenderInstances(struct Render *re); float *RE_vertren_get_stress(struct ObjectRen *obr, struct VertRen *ver, int verify); diff --git a/source/blender/render/intern/include/strand.h b/source/blender/render/intern/include/strand.h index 720354219e9..d9594864bff 100644 --- a/source/blender/render/intern/include/strand.h +++ b/source/blender/render/intern/include/strand.h @@ -92,10 +92,10 @@ struct StrandShadeCache; typedef struct StrandShadeCache StrandShadeCache; void strand_eval_point(StrandSegment *sseg, StrandPoint *spoint); -void render_strand_segment(struct Render *re, float winmat[][4], struct StrandPart *spart, struct ZSpan *zspan, int totzspan, StrandSegment *sseg); +void render_strand_segment(struct Render *re, float winmat[4][4], struct StrandPart *spart, struct ZSpan *zspan, int totzspan, StrandSegment *sseg); void strand_minmax(struct StrandRen *strand, float min[3], float max[3], const float width); -struct StrandSurface *cache_strand_surface(struct Render *re, struct ObjectRen *obr, struct DerivedMesh *dm, float mat[][4], int timeoffset); +struct StrandSurface *cache_strand_surface(struct Render *re, struct ObjectRen *obr, struct DerivedMesh *dm, float mat[4][4], int timeoffset); void free_strand_surface(struct Render *re); struct StrandShadeCache *strand_shade_cache_create(void); diff --git a/source/blender/render/intern/include/zbuf.h b/source/blender/render/intern/include/zbuf.h index e873111e6bf..162fa3b7e88 100644 --- a/source/blender/render/intern/include/zbuf.h +++ b/source/blender/render/intern/include/zbuf.h @@ -49,17 +49,17 @@ void fillrect(int *rect, int x, int y, int val); * Converts a world coordinate into a homogeneous coordinate in view * coordinates. */ -void projectvert(const float v1[3], float winmat[][4], float adr[4]); -void projectverto(const float v1[3], float winmat[][4], float adr[4]); +void projectvert(const float v1[3], float winmat[4][4], float adr[4]); +void projectverto(const float v1[3], float winmat[4][4], float adr[4]); int testclip(const float v[3]); -void zbuffer_shadow(struct Render *re, float winmat[][4], struct LampRen *lar, int *rectz, int size, float jitx, float jity); -void zbuffer_abuf_shadow(struct Render *re, struct LampRen *lar, float winmat[][4], struct APixstr *APixbuf, struct APixstrand *apixbuf, struct ListBase *apsmbase, int size, int samples, float (*jit)[2]); +void zbuffer_shadow(struct Render *re, float winmat[4][4], struct LampRen *lar, int *rectz, int size, float jitx, float jity); +void zbuffer_abuf_shadow(struct Render *re, struct LampRen *lar, float winmat[4][4], struct APixstr *APixbuf, struct APixstrand *apixbuf, struct ListBase *apsmbase, int size, int samples, float (*jit)[2]); void zbuffer_solid(struct RenderPart *pa, struct RenderLayer *rl, void (*fillfunc)(struct RenderPart *, struct ZSpan *, int, void*), void *data); unsigned short *zbuffer_transp_shade(struct RenderPart *pa, struct RenderLayer *rl, float *pass, struct ListBase *psmlist); void zbuffer_sss(RenderPart *pa, unsigned int lay, void *handle, void (*func)(void*, int, int, int, int, int)); -int zbuffer_strands_abuf(struct Render *re, struct RenderPart *pa, struct APixstrand *apixbuf, struct ListBase *apsmbase, unsigned int lay, int negzmask, float winmat[][4], int winx, int winy, int sample, float (*jit)[2], float clipcrop, int shadow, struct StrandShadeCache *cache); +int zbuffer_strands_abuf(struct Render *re, struct RenderPart *pa, struct APixstrand *apixbuf, struct ListBase *apsmbase, unsigned int lay, int negzmask, float winmat[4][4], int winx, int winy, int sample, float (*jit)[2], float clipcrop, int shadow, struct StrandShadeCache *cache); typedef struct APixstr { unsigned short mask[4]; /* jitter mask */ @@ -136,8 +136,8 @@ void zbufclipwire(struct ZSpan *zspan, int obi, int zvlnr, int ec, float *ho1, float *ho2, float *ho3, float *ho4, int c1, int c2, int c3, int c4); /* exported to shadeinput.c */ -void zbuf_make_winmat(Render *re, float winmat[][4]); -void zbuf_render_project(float winmat[][4], const float co[3], float ho[4]); +void zbuf_make_winmat(Render *re, float winmat[4][4]); +void zbuf_render_project(float winmat[4][4], const float co[3], float ho[4]); /* sould not really be exposed, bad! */ void hoco_to_zco(ZSpan *zspan, float zco[3], const float hoco[4]); diff --git a/source/blender/render/intern/raytrace/rayobject_instance.cpp b/source/blender/render/intern/raytrace/rayobject_instance.cpp index f797f7a4311..f9ed012b117 100644 --- a/source/blender/render/intern/raytrace/rayobject_instance.cpp +++ b/source/blender/render/intern/raytrace/rayobject_instance.cpp @@ -75,7 +75,7 @@ typedef struct InstanceRayObject { } InstanceRayObject; -RayObject *RE_rayobject_instance_create(RayObject *target, float transform[][4], void *ob, void *target_ob) +RayObject *RE_rayobject_instance_create(RayObject *target, float transform[4][4], void *ob, void *target_ob) { InstanceRayObject *obj = (InstanceRayObject *)MEM_callocN(sizeof(InstanceRayObject), "InstanceRayObject"); assert(RE_rayobject_isAligned(obj) ); /* RayObject API assumes real data to be 4-byte aligned */ diff --git a/source/blender/render/intern/raytrace/rayobject_octree.cpp b/source/blender/render/intern/raytrace/rayobject_octree.cpp index 7800a7da370..dad7fe5fd60 100644 --- a/source/blender/render/intern/raytrace/rayobject_octree.cpp +++ b/source/blender/render/intern/raytrace/rayobject_octree.cpp @@ -223,7 +223,7 @@ static Node *addnode(Octree *oc) return oc->adrnode[index] + (oc->nodecount & 4095); } -static int face_in_node(RayFace *face, short x, short y, short z, float rtf[][3]) +static int face_in_node(RayFace *face, short x, short y, short z, float rtf[4][3]) { static float nor[3], d; float fx, fy, fz; @@ -321,7 +321,7 @@ static void ocwrite(Octree *oc, RayFace *face, int quad, short x, short y, short calc_ocval_face(rtf[0], rtf[1], rtf[2], NULL, x >> 2, y >> 1, z, &no->ov[a]); } -static void d2dda(Octree *oc, short b1, short b2, short c1, short c2, char *ocface, short rts[][3], float rtf[][3]) +static void d2dda(Octree *oc, short b1, short b2, short c1, short c2, char *ocface, short rts[4][3], float rtf[4][3]) { int ocx1, ocx2, ocy1, ocy2; int x, y, dx = 0, dy = 0; diff --git a/source/blender/render/intern/source/convertblender.c b/source/blender/render/intern/source/convertblender.c index 386086333e0..37fd213edd5 100644 --- a/source/blender/render/intern/source/convertblender.c +++ b/source/blender/render/intern/source/convertblender.c @@ -759,7 +759,7 @@ static VertRen *as_findvertex(VlakRen *vlr, VertRen *UNUSED(ver), ASvert *asv, f /* note; autosmooth happens in object space still, after applying autosmooth we rotate */ /* note2; actually, when original mesh and displist are equal sized, face normals are from original mesh */ -static void autosmooth(Render *UNUSED(re), ObjectRen *obr, float mat[][4], int degr) +static void autosmooth(Render *UNUSED(re), ObjectRen *obr, float mat[4][4], int degr) { ASvert *asv, *asverts; ASface *asf; @@ -2186,7 +2186,7 @@ static short test_for_displace(Render *re, Object *ob) return 0; } -static void displace_render_vert(Render *re, ObjectRen *obr, ShadeInput *shi, VertRen *vr, int vindex, float *scale, float mat[][4], float imat[][3]) +static void displace_render_vert(Render *re, ObjectRen *obr, ShadeInput *shi, VertRen *vr, int vindex, float *scale, float mat[4][4], float imat[3][3]) { MTFace *tface; short texco= shi->mat->texco; @@ -2285,7 +2285,7 @@ static void displace_render_vert(Render *re, ObjectRen *obr, ShadeInput *shi, Ve return; } -static void displace_render_face(Render *re, ObjectRen *obr, VlakRen *vlr, float *scale, float mat[][4], float imat[][3]) +static void displace_render_face(Render *re, ObjectRen *obr, VlakRen *vlr, float *scale, float mat[4][4], float imat[3][3]) { ShadeInput shi; @@ -2340,7 +2340,7 @@ static void displace_render_face(Render *re, ObjectRen *obr, VlakRen *vlr, float } } -static void do_displacement(Render *re, ObjectRen *obr, float mat[][4], float imat[][3]) +static void do_displacement(Render *re, ObjectRen *obr, float mat[4][4], float imat[3][3]) { VertRen *vr; VlakRen *vlr; @@ -3520,7 +3520,7 @@ static void init_render_mesh(Render *re, ObjectRen *obr, int timeoffset) /* Lamps and Shadowbuffers */ /* ------------------------------------------------------------------------- */ -static void initshadowbuf(Render *re, LampRen *lar, float mat[][4]) +static void initshadowbuf(Render *re, LampRen *lar, float mat[4][4]) { struct ShadBuf *shb; float viewinv[4][4]; @@ -5136,7 +5136,7 @@ void RE_DataBase_ApplyWindow(Render *re) project_renderdata(re, projectverto, 0, 0, 0); } -void RE_DataBase_GetView(Render *re, float mat[][4]) +void RE_DataBase_GetView(Render *re, float mat[4][4]) { copy_m4_m4(mat, re->viewmat); } diff --git a/source/blender/render/intern/source/envmap.c b/source/blender/render/intern/source/envmap.c index e04035e0c2b..be8b7f6c357 100644 --- a/source/blender/render/intern/source/envmap.c +++ b/source/blender/render/intern/source/envmap.c @@ -210,7 +210,7 @@ static void envmap_free_render_copy(Render *envre) /* ------------------------------------------------------------------------- */ -static void envmap_transmatrix(float mat[][4], int part) +static void envmap_transmatrix(float mat[4][4], int part) { float tmat[4][4], eul[3], rotmat[4][4]; @@ -247,7 +247,7 @@ static void envmap_transmatrix(float mat[][4], int part) /* ------------------------------------------------------------------------- */ -static void env_rotate_scene(Render *re, float mat[][4], int mode) +static void env_rotate_scene(Render *re, float mat[4][4], int mode) { GroupObject *go; ObjectRen *obr; diff --git a/source/blender/render/intern/source/initrender.c b/source/blender/render/intern/source/initrender.c index 3ea74abbcc2..0d957f8019f 100644 --- a/source/blender/render/intern/source/initrender.c +++ b/source/blender/render/intern/source/initrender.c @@ -515,7 +515,7 @@ void RE_SetPixelSize(Render *re, float pixsize) re->viewdy = re->ycor * pixsize; } -void RE_GetCameraWindow(struct Render *re, struct Object *camera, int frame, float mat[][4]) +void RE_GetCameraWindow(struct Render *re, struct Object *camera, int frame, float mat[4][4]) { re->r.cfra = frame; RE_SetCamera(re, camera); diff --git a/source/blender/render/intern/source/pipeline.c b/source/blender/render/intern/source/pipeline.c index 6b5b9716f3b..e22a90cacb5 100644 --- a/source/blender/render/intern/source/pipeline.c +++ b/source/blender/render/intern/source/pipeline.c @@ -582,7 +582,7 @@ void RE_SetOrtho(Render *re, rctf *viewplane, float clipsta, float clipend) re->viewplane.ymin, re->viewplane.ymax, re->clipsta, re->clipend); } -void RE_SetView(Render *re, float mat[][4]) +void RE_SetView(Render *re, float mat[4][4]) { /* re->ok flag? */ copy_m4_m4(re->viewmat, mat); diff --git a/source/blender/render/intern/source/pixelblending.c b/source/blender/render/intern/source/pixelblending.c index 74de8a1291f..21ff1151cfb 100644 --- a/source/blender/render/intern/source/pixelblending.c +++ b/source/blender/render/intern/source/pixelblending.c @@ -206,7 +206,7 @@ void add_filt_fmask(unsigned int mask, const float col[4], float *rowbuf, int ro } -void mask_array(unsigned int mask, float filt[][3]) +void mask_array(unsigned int mask, float filt[3][3]) { float **fmask1 = R.samples->fmask1, **fmask2 = R.samples->fmask2; unsigned int maskand = (mask & 255); @@ -244,7 +244,7 @@ void mask_array(unsigned int mask, float filt[][3]) * */ -void add_filt_fmask_coord(float filt[][3], const float col[4], float *rowbuf, int row_w, int col_h, int x, int y) +void add_filt_fmask_coord(float filt[3][3], const float col[4], float *rowbuf, int row_w, int col_h, int x, int y) { float *fpoin[3][3]; float val, r, g, b, al, lfilt[3][3]; diff --git a/source/blender/render/intern/source/renderdatabase.c b/source/blender/render/intern/source/renderdatabase.c index 44daaf516e1..e189d8bdaea 100644 --- a/source/blender/render/intern/source/renderdatabase.c +++ b/source/blender/render/intern/source/renderdatabase.c @@ -1221,7 +1221,9 @@ static int panotestclip(Render *re, int do_pano, float v[4]) * - shadow buffering (shadbuf.c) */ -void project_renderdata(Render *re, void (*projectfunc)(const float *, float mat[][4], float *), int do_pano, float xoffs, int UNUSED(do_buckets)) +void project_renderdata(Render *re, + void (*projectfunc)(const float *, float mat[4][4], float *), + int do_pano, float xoffs, int UNUSED(do_buckets)) { ObjectRen *obr; HaloRen *har = NULL; @@ -1308,7 +1310,7 @@ void project_renderdata(Render *re, void (*projectfunc)(const float *, float mat /* ------------------------------------------------------------------------- */ -ObjectInstanceRen *RE_addRenderInstance(Render *re, ObjectRen *obr, Object *ob, Object *par, int index, int psysindex, float mat[][4], int lay) +ObjectInstanceRen *RE_addRenderInstance(Render *re, ObjectRen *obr, Object *ob, Object *par, int index, int psysindex, float mat[4][4], int lay) { ObjectInstanceRen *obi; float mat3[3][3]; @@ -1363,7 +1365,7 @@ void RE_makeRenderInstances(Render *re) re->instancetable= newlist; } -int clip_render_object(float boundbox[][3], float bounds[4], float winmat[][4]) +int clip_render_object(float boundbox[2][3], float bounds[4], float winmat[4][4]) { float mat[4][4], vec[4]; int a, fl, flag = -1; diff --git a/source/blender/render/intern/source/strand.c b/source/blender/render/intern/source/strand.c index 2fe8adaa1ee..569bac29205 100644 --- a/source/blender/render/intern/source/strand.c +++ b/source/blender/render/intern/source/strand.c @@ -476,13 +476,13 @@ static int compare_strand_segment(const void *poin1, const void *poin2) return 1; } -static void do_strand_point_project(float winmat[][4], ZSpan *zspan, float *co, float *hoco, float *zco) +static void do_strand_point_project(float winmat[4][4], ZSpan *zspan, float *co, float *hoco, float *zco) { projectvert(co, winmat, hoco); hoco_to_zco(zspan, zco, hoco); } -static void strand_project_point(float winmat[][4], float winx, float winy, StrandPoint *spoint) +static void strand_project_point(float winmat[4][4], float winx, float winy, StrandPoint *spoint) { float div; @@ -603,7 +603,7 @@ static void do_strand_fillac(void *handle, int x, int y, float u, float v, float } /* width is calculated in hoco space, to ensure strands are visible */ -static int strand_test_clip(float winmat[][4], ZSpan *UNUSED(zspan), float *bounds, float *co, float *zcomp, float widthx, float widthy) +static int strand_test_clip(float winmat[4][4], ZSpan *UNUSED(zspan), float *bounds, float *co, float *zcomp, float widthx, float widthy) { float hoco[4]; int clipflag= 0; @@ -663,7 +663,7 @@ static void do_scanconvert_strand(Render *UNUSED(re), StrandPart *spart, ZSpan * zspan_scanconvert_strand(zspan, spart, jco1, jco3, jco4, do_strand_fillac); } -static void strand_render(Render *re, StrandSegment *sseg, float winmat[][4], StrandPart *spart, ZSpan *zspan, int totzspan, StrandPoint *p1, StrandPoint *p2) +static void strand_render(Render *re, StrandSegment *sseg, float winmat[4][4], StrandPart *spart, ZSpan *zspan, int totzspan, StrandPoint *p1, StrandPoint *p2) { if (spart) { float t= p2->t; @@ -696,7 +696,7 @@ static void strand_render(Render *re, StrandSegment *sseg, float winmat[][4], St } } -static int strand_segment_recursive(Render *re, float winmat[][4], StrandPart *spart, ZSpan *zspan, int totzspan, StrandSegment *sseg, StrandPoint *p1, StrandPoint *p2, int depth) +static int strand_segment_recursive(Render *re, float winmat[4][4], StrandPart *spart, ZSpan *zspan, int totzspan, StrandSegment *sseg, StrandPoint *p1, StrandPoint *p2, int depth) { StrandPoint p; StrandBuffer *buffer= sseg->buffer; @@ -745,7 +745,7 @@ static int strand_segment_recursive(Render *re, float winmat[][4], StrandPart *s return 1; } -void render_strand_segment(Render *re, float winmat[][4], StrandPart *spart, ZSpan *zspan, int totzspan, StrandSegment *sseg) +void render_strand_segment(Render *re, float winmat[4][4], StrandPart *spart, ZSpan *zspan, int totzspan, StrandSegment *sseg) { StrandBuffer *buffer= sseg->buffer; StrandPoint *p1= &sseg->point1; @@ -783,7 +783,7 @@ void render_strand_segment(Render *re, float winmat[][4], StrandPart *spart, ZSp } /* render call to fill in strands */ -int zbuffer_strands_abuf(Render *re, RenderPart *pa, APixstrand *apixbuf, ListBase *apsmbase, unsigned int lay, int UNUSED(negzmask), float winmat[][4], int winx, int winy, int samples, float (*jit)[2], float clipcrop, int shadow, StrandShadeCache *cache) +int zbuffer_strands_abuf(Render *re, RenderPart *pa, APixstrand *apixbuf, ListBase *apsmbase, unsigned int lay, int UNUSED(negzmask), float winmat[4][4], int winx, int winy, int samples, float (*jit)[2], float clipcrop, int shadow, StrandShadeCache *cache) { ObjectRen *obr; ObjectInstanceRen *obi; @@ -976,7 +976,7 @@ int zbuffer_strands_abuf(Render *re, RenderPart *pa, APixstrand *apixbuf, ListBa /* *************** */ -StrandSurface *cache_strand_surface(Render *re, ObjectRen *obr, DerivedMesh *dm, float mat[][4], int timeoffset) +StrandSurface *cache_strand_surface(Render *re, ObjectRen *obr, DerivedMesh *dm, float mat[4][4], int timeoffset) { StrandSurface *mesh; MFace *mface; diff --git a/source/blender/render/intern/source/zbuf.c b/source/blender/render/intern/source/zbuf.c index 2335725ee65..2e1b23435e5 100644 --- a/source/blender/render/intern/source/zbuf.c +++ b/source/blender/render/intern/source/zbuf.c @@ -1708,7 +1708,7 @@ static void makevertpyra(float *vez, float *lambda, float **trias, float *v1, fl /* ------------------------------------------------------------------------- */ -void projectverto(const float v1[3], float winmat[][4], float adr[4]) +void projectverto(const float v1[3], float winmat[4][4], float adr[4]) { /* calcs homogenic coord of vertex v1 */ float x, y, z; @@ -1726,7 +1726,7 @@ void projectverto(const float v1[3], float winmat[][4], float adr[4]) /* ------------------------------------------------------------------------- */ -void projectvert(const float v1[3], float winmat[][4], float adr[4]) +void projectvert(const float v1[3], float winmat[4][4], float adr[4]) { /* calcs homogenic coord of vertex v1 */ float x, y, z; @@ -1761,7 +1761,7 @@ static void zbuf_project_cache_clear(ZbufProjectCache *cache, int size) cache[i].index= -1; } -static int zbuf_shadow_project(ZbufProjectCache *cache, int index, float winmat[][4], float *co, float *ho) +static int zbuf_shadow_project(ZbufProjectCache *cache, int index, float winmat[4][4], float *co, float *ho) { int cindex= index & 255; @@ -1790,7 +1790,7 @@ static void zbuffer_part_bounds(int winx, int winy, RenderPart *pa, float *bound bounds[3]= (2*pa->disprect.ymax - winy+1)/(float)winy; } -static int zbuf_part_project(ZbufProjectCache *cache, int index, float winmat[][4], float *bounds, float *co, float *ho) +static int zbuf_part_project(ZbufProjectCache *cache, int index, float winmat[4][4], float *bounds, float *co, float *ho) { float vec[3]; int cindex= index & 255; @@ -1819,7 +1819,7 @@ static int zbuf_part_project(ZbufProjectCache *cache, int index, float winmat[][ } } -void zbuf_render_project(float winmat[][4], const float co[3], float ho[4]) +void zbuf_render_project(float winmat[4][4], const float co[3], float ho[4]) { float vec[3]; @@ -1827,7 +1827,7 @@ void zbuf_render_project(float winmat[][4], const float co[3], float ho[4]) projectvert(vec, winmat, ho); } -void zbuf_make_winmat(Render *re, float winmat[][4]) +void zbuf_make_winmat(Render *re, float winmat[4][4]) { if (re->r.mode & R_PANORAMA) { float panomat[4][4]= MAT4_UNITY; @@ -2296,7 +2296,7 @@ void zbuffer_solid(RenderPart *pa, RenderLayer *rl, void(*fillfunc)(RenderPart*, } } -void zbuffer_shadow(Render *re, float winmat[][4], LampRen *lar, int *rectz, int size, float jitx, float jity) +void zbuffer_shadow(Render *re, float winmat[4][4], LampRen *lar, int *rectz, int size, float jitx, float jity) { ZbufProjectCache cache[ZBUF_PROJECT_CACHE_SIZE]; ZSpan zspan; @@ -3261,7 +3261,7 @@ static void copyto_abufz(RenderPart *pa, int *arectz, int *rectmask, int sample) * Do accumulation z buffering. */ -static int zbuffer_abuf(Render *re, RenderPart *pa, APixstr *APixbuf, ListBase *apsmbase, unsigned int lay, int negzmask, float winmat[][4], int winx, int winy, int samples, float (*jit)[2], float UNUSED(clipcrop), int shadow) +static int zbuffer_abuf(Render *re, RenderPart *pa, APixstr *APixbuf, ListBase *apsmbase, unsigned int lay, int negzmask, float winmat[4][4], int winx, int winy, int samples, float (*jit)[2], float UNUSED(clipcrop), int shadow) { ZbufProjectCache cache[ZBUF_PROJECT_CACHE_SIZE]; ZSpan zspans[16], *zspan; /* MAX_OSA */ @@ -3459,7 +3459,7 @@ static int zbuffer_abuf_render(RenderPart *pa, APixstr *APixbuf, APixstrand *APi return doztra; } -void zbuffer_abuf_shadow(Render *re, LampRen *lar, float winmat[][4], APixstr *APixbuf, APixstrand *APixbufstrand, ListBase *apsmbase, int size, int samples, float (*jit)[2]) +void zbuffer_abuf_shadow(Render *re, LampRen *lar, float winmat[4][4], APixstr *APixbuf, APixstrand *APixbufstrand, ListBase *apsmbase, int size, int samples, float (*jit)[2]) { RenderPart pa; int lay= -1; diff --git a/source/blender/windowmanager/intern/wm_subwindow.c b/source/blender/windowmanager/intern/wm_subwindow.c index 8533494ae96..9b46dced6bc 100644 --- a/source/blender/windowmanager/intern/wm_subwindow.c +++ b/source/blender/windowmanager/intern/wm_subwindow.c @@ -131,7 +131,7 @@ void wm_subwindow_getorigin(wmWindow *win, int swinid, int *x, int *y) } } -void wm_subwindow_getmatrix(wmWindow *win, int swinid, float mat[][4]) +void wm_subwindow_getmatrix(wmWindow *win, int swinid, float mat[4][4]) { wmSubWindow *swin = swin_from_swinid(win, swinid); diff --git a/source/blender/windowmanager/wm_subwindow.h b/source/blender/windowmanager/wm_subwindow.h index 5017977952b..b584d0127a5 100644 --- a/source/blender/windowmanager/wm_subwindow.h +++ b/source/blender/windowmanager/wm_subwindow.h @@ -46,7 +46,7 @@ void wm_subwindow_position(wmWindow *win, int swinid, rcti *winrct); void wm_subwindow_getsize(wmWindow *win, int swinid, int *x, int *y); void wm_subwindow_getorigin(wmWindow *win, int swinid, int *x, int *y); -void wm_subwindow_getmatrix(wmWindow *win, int swinid, float mat[][4]); +void wm_subwindow_getmatrix(wmWindow *win, int swinid, float mat[4][4]); unsigned int index_to_framebuffer(int index); diff --git a/source/blenderplayer/bad_level_call_stubs/stubs.c b/source/blenderplayer/bad_level_call_stubs/stubs.c index 5e38dad74ed..2b29129c0f7 100644 --- a/source/blenderplayer/bad_level_call_stubs/stubs.c +++ b/source/blenderplayer/bad_level_call_stubs/stubs.c @@ -176,7 +176,7 @@ int RE_RenderInProgress(struct Render *re) {return 0;} struct Scene *RE_GetScene(struct Render *re) {return (struct Scene *) NULL;} void RE_Database_Free(struct Render *re) {} void RE_FreeRender(struct Render *re) {} -void RE_DataBase_GetView(struct Render *re, float mat[][4]) {} +void RE_DataBase_GetView(struct Render *re, float mat[4][4]) {} int externtex(struct MTex *mtex, float *vec, float *tin, float *tr, float *tg, float *tb, float *ta) {return 0;} float texture_value_blend(float tex, float out, float fact, float facg, int blendtype, int flip) {return 0.0f;} void texture_rgb_blend(float *in, float *tex, float *out, float fact, float facg, int blendtype) {} @@ -299,13 +299,13 @@ void ED_node_tree_update(struct SpaceNode *snode, struct Scene *scene) {} void ED_view3d_scene_layers_update(struct Main *bmain, struct Scene *scene) {} int ED_view3d_scene_layer_set(int lay, const int *values) {return 0;} void ED_view3d_quadview_update(struct ScrArea *sa, struct ARegion *ar) {} -void ED_view3d_from_m4(float mat[][4], float ofs[3], float quat[4], float *dist) {} +void ED_view3d_from_m4(float mat[4][4], float ofs[3], float quat[4], float *dist) {} struct BGpic *ED_view3D_background_image_new(struct View3D *v3d) {return (struct BGpic *) NULL;} void ED_view3D_background_image_remove(struct View3D *v3d, struct BGpic *bgpic) {} void ED_view3D_background_image_clear(struct View3D *v3d) {} -void ED_view3d_update_viewmat(struct Scene *scene, struct View3D *v3d, struct ARegion *ar, float viewmat[][4], float winmat[][4]) {} +void ED_view3d_update_viewmat(struct Scene *scene, struct View3D *v3d, struct ARegion *ar, float viewmat[4][4], float winmat[4][4]) {} float ED_view3d_grid_scale(struct Scene *scene, struct View3D *v3d, const char **grid_unit) {return 0.0f;} -void view3d_apply_mat4(float mat[][4], float *ofs, float *quat, float *dist) {} +void view3d_apply_mat4(float mat[4][4], float *ofs, float *quat, float *dist) {} int text_file_modified(struct Text *text) {return 0;} void ED_node_shader_default(struct Material *ma) {} void ED_screen_animation_timer_update(struct bContext *C, int redraws) {} diff --git a/source/gameengine/Ketsji/KX_CameraActuator.cpp b/source/gameengine/Ketsji/KX_CameraActuator.cpp index 59ca0d8d326..792a0759b59 100644 --- a/source/gameengine/Ketsji/KX_CameraActuator.cpp +++ b/source/gameengine/Ketsji/KX_CameraActuator.cpp @@ -115,7 +115,7 @@ void KX_CameraActuator::Relink(CTR_Map *obj_map) /* copied from blender BLI_math ... don't know if there's an equivalent */ -static void Kx_VecUpMat3(float vec[3], float mat[][3], short axis) +static void Kx_VecUpMat3(float vec[3], float mat[3][3], short axis) { // Construct a camera matrix s.t. the specified axis From f6c14d430f62cc816fe6fdeb2d6b071df845e3e1 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 11 Dec 2012 14:30:12 +0000 Subject: [PATCH 017/252] minor speedup - replace use of smallhash with api_flags for BM_edge_split() --- source/blender/bmesh/intern/bmesh_mods.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/source/blender/bmesh/intern/bmesh_mods.c b/source/blender/bmesh/intern/bmesh_mods.c index 4253bc750db..9a99d5b96d1 100644 --- a/source/blender/bmesh/intern/bmesh_mods.c +++ b/source/blender/bmesh/intern/bmesh_mods.c @@ -641,7 +641,6 @@ BMVert *BM_edge_split(BMesh *bm, BMEdge *e, BMVert *v, BMEdge **r_e, float perce BMFace **oldfaces = NULL; BMEdge *e_dummy; BLI_array_staticdeclare(oldfaces, 32); - SmallHash hash; const int do_mdisp = (e->l && CustomData_has_layer(&bm->ldata, CD_MDISPS)); /* we need this for handling multi-res */ @@ -660,12 +659,11 @@ BMVert *BM_edge_split(BMesh *bm, BMEdge *e, BMVert *v, BMEdge **r_e, float perce l = l->radial_next; } while (l != e->l); - /* create a hash so we can differentiate oldfaces from new face */ - BLI_smallhash_init(&hash); - + /* flag existing faces so we can differentiate oldfaces from new faces */ for (i = 0; i < BLI_array_count(oldfaces); i++) { + BM_ELEM_API_FLAG_ENABLE(oldfaces[i], _FLAG_OVERLAP); oldfaces[i] = BM_face_copy(bm, oldfaces[i], TRUE, TRUE); - BLI_smallhash_insert(&hash, (intptr_t)oldfaces[i], NULL); + BM_ELEM_API_FLAG_DISABLE(oldfaces[i], _FLAG_OVERLAP); } } @@ -703,7 +701,8 @@ BMVert *BM_edge_split(BMesh *bm, BMEdge *e, BMVert *v, BMEdge **r_e, float perce } do { - if (!BLI_smallhash_haskey(&hash, (intptr_t)l->f)) { + /* check this is an old face */ + if (BM_ELEM_API_FLAG_TEST(l->f, _FLAG_OVERLAP)) { BMLoop *l2_first; l2 = l2_first = BM_FACE_FIRST_LOOP(l->f); @@ -741,7 +740,6 @@ BMVert *BM_edge_split(BMesh *bm, BMEdge *e, BMVert *v, BMEdge **r_e, float perce #endif BLI_array_free(oldfaces); - BLI_smallhash_release(&hash); } return nv; From fd3068281c28a3e801da3fb2f2bcbf06b2e3be24 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Tue, 11 Dec 2012 14:39:26 +0000 Subject: [PATCH 018/252] Fix OS X warning on startup about using deprecated function, when building against 10.8 SDK. --- intern/ghost/intern/GHOST_WindowCocoa.mm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/intern/ghost/intern/GHOST_WindowCocoa.mm b/intern/ghost/intern/GHOST_WindowCocoa.mm index 7a5bb8ab604..a483c030b31 100644 --- a/intern/ghost/intern/GHOST_WindowCocoa.mm +++ b/intern/ghost/intern/GHOST_WindowCocoa.mm @@ -1221,7 +1221,7 @@ GHOST_TSuccess GHOST_WindowCocoa::setProgressBar(float progress) [dockIcon lockFocus]; NSRect progressBox = {{4, 4}, {120, 16}}; - [[NSImage imageNamed:@"NSApplicationIcon"] dissolveToPoint:NSZeroPoint fraction:1.0]; + [[NSImage imageNamed:@"NSApplicationIcon"] drawAtPoint:NSZeroPoint fromRect:NSZeroRect operation:NSCompositeSourceOver fraction:1.0]; // Track & Outline [[NSColor blackColor] setFill]; @@ -1260,7 +1260,7 @@ GHOST_TSuccess GHOST_WindowCocoa::endProgressBar() NSImage* dockIcon = [[NSImage alloc] initWithSize:NSMakeSize(128,128)]; [dockIcon lockFocus]; - [[NSImage imageNamed:@"NSApplicationIcon"] dissolveToPoint:NSZeroPoint fraction:1.0]; + [[NSImage imageNamed:@"NSApplicationIcon"] drawAtPoint:NSZeroPoint fromRect:NSZeroRect operation:NSCompositeSourceOver fraction:1.0]; [dockIcon unlockFocus]; [NSApp setApplicationIconImage:dockIcon]; [dockIcon release]; From 68efcca5ea0db71856dbad2cff21b64ab51f3fd7 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Tue, 11 Dec 2012 14:39:28 +0000 Subject: [PATCH 019/252] Fix issue reported in #32174: IK solver stretch was less stable after a code refactor commit, epsilon was supposed to be 0.01 instead of 0.001. --- intern/iksolver/extern/IK_solver.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/intern/iksolver/extern/IK_solver.h b/intern/iksolver/extern/IK_solver.h index a3f599e06c8..4de9f143e77 100644 --- a/intern/iksolver/extern/IK_solver.h +++ b/intern/iksolver/extern/IK_solver.h @@ -163,7 +163,7 @@ float IK_SolverGetPoleAngle(IK_Solver *solver); int IK_Solve(IK_Solver *solver, float tolerance, int max_iterations); -#define IK_STRETCH_STIFF_EPS 0.001f +#define IK_STRETCH_STIFF_EPS 0.01f #define IK_STRETCH_STIFF_MIN 0.001f #define IK_STRETCH_STIFF_MAX 1e10 From 1e5cc7c51b3c7d3c2f99fc748d3978a90d2133d3 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Tue, 11 Dec 2012 14:39:30 +0000 Subject: [PATCH 020/252] RNA: add Window x/y position and size access. --- source/blender/makesrna/intern/rna_wm.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/source/blender/makesrna/intern/rna_wm.c b/source/blender/makesrna/intern/rna_wm.c index f83410e7cc1..f3e28f1d7a3 100644 --- a/source/blender/makesrna/intern/rna_wm.c +++ b/source/blender/makesrna/intern/rna_wm.c @@ -1617,6 +1617,26 @@ static void rna_def_window(BlenderRNA *brna) RNA_def_property_pointer_funcs(prop, NULL, "rna_Window_screen_set", NULL, NULL); RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE); RNA_def_property_update(prop, 0, "rna_Window_screen_update"); + + prop = RNA_def_property(srna, "x", PROP_INT, PROP_NONE); + RNA_def_property_int_sdna(prop, NULL, "posx"); + RNA_def_property_clear_flag(prop, PROP_EDITABLE); + RNA_def_property_ui_text(prop, "X Position", "Vertical location of the window"); + + prop = RNA_def_property(srna, "y", PROP_INT, PROP_NONE); + RNA_def_property_int_sdna(prop, NULL, "posy"); + RNA_def_property_clear_flag(prop, PROP_EDITABLE); + RNA_def_property_ui_text(prop, "Y Position", "Horizontal location of the window"); + + prop = RNA_def_property(srna, "width", PROP_INT, PROP_UNSIGNED); + RNA_def_property_int_sdna(prop, NULL, "sizex"); + RNA_def_property_clear_flag(prop, PROP_EDITABLE); + RNA_def_property_ui_text(prop, "Width", "Window width"); + + prop = RNA_def_property(srna, "height", PROP_INT, PROP_UNSIGNED); + RNA_def_property_int_sdna(prop, NULL, "sizey"); + RNA_def_property_clear_flag(prop, PROP_EDITABLE); + RNA_def_property_ui_text(prop, "Height", "Window height"); } /* curve.splines */ From 7c81952179f0ff08cfdd8f571eb1c0f06e224070 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Tue, 11 Dec 2012 14:39:32 +0000 Subject: [PATCH 021/252] Cycles: trick to make building with OSL trunk work as well, it has a different name for LoadMemoryShader so we make it call the right name depending on which is available. --- intern/cycles/render/osl.cpp | 36 +++++++++++++++++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) diff --git a/intern/cycles/render/osl.cpp b/intern/cycles/render/osl.cpp index e4ee40d881e..b3b838be25b 100644 --- a/intern/cycles/render/osl.cpp +++ b/intern/cycles/render/osl.cpp @@ -268,9 +268,43 @@ const char *OSLShaderManager::shader_load_filepath(string filepath) return shader_load_bytecode(bytecode_hash, bytecode); } +/* don't try this at home .. this is a template trick to use either + * LoadMemoryShader or LoadMemoryCompiledShader which are the function + * names in our custom branch and the official repository. */ + +template struct enable_if { typedef T type; }; +template struct enable_if { }; + +template +struct has_LoadMemoryCompiledShader { + typedef int yes; + typedef char no; + + template struct type_check; + template static yes &chk(type_check*); + template static no &chk(...); + static bool const value = sizeof(chk(0)) == sizeof(yes); +}; + +template +typename enable_if::value, bool>::type +load_memory_shader(T *ss, const char *name, const char *buffer) +{ + return ss->LoadMemoryCompiledShader(name, buffer); +} + +template +typename enable_if::value, bool>::type +load_memory_shader(T *ss, const char *name, const char *buffer) +{ + return ss->LoadMemoryShader(name, buffer); +} + const char *OSLShaderManager::shader_load_bytecode(const string& hash, const string& bytecode) { - ss->LoadMemoryShader(hash.c_str(), bytecode.c_str()); + load_memory_shader(ss, hash.c_str(), bytecode.c_str()); return loaded_shaders.insert(hash).first->c_str(); } From 43c04eefe32773b708d85ea0db95564e71f4870e Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Tue, 11 Dec 2012 14:39:37 +0000 Subject: [PATCH 022/252] Cycles: RGB and Vector Curves nodes now supported, with the limitation that the range must be left to the default (0..1 and -1..1). --- intern/cycles/blender/blender_shader.cpp | 14 +++-- intern/cycles/blender/blender_util.h | 30 +++++++++++ intern/cycles/kernel/shaders/CMakeLists.txt | 2 + .../cycles/kernel/shaders/node_rgb_curves.osl | 53 +++++++++++++++++++ .../kernel/shaders/node_vector_curves.osl | 53 +++++++++++++++++++ intern/cycles/kernel/svm/svm.h | 3 ++ intern/cycles/kernel/svm/svm_ramp.h | 25 +++++++-- intern/cycles/kernel/svm/svm_types.h | 1 + intern/cycles/render/nodes.cpp | 47 ++++++++++++++++ intern/cycles/render/nodes.h | 6 +++ .../nodes/shader/nodes/node_shader_curves.c | 4 +- 11 files changed, 230 insertions(+), 8 deletions(-) create mode 100644 intern/cycles/kernel/shaders/node_rgb_curves.osl create mode 100644 intern/cycles/kernel/shaders/node_vector_curves.osl diff --git a/intern/cycles/blender/blender_shader.cpp b/intern/cycles/blender/blender_shader.cpp index c9380d8d58b..848a9a199f9 100644 --- a/intern/cycles/blender/blender_shader.cpp +++ b/intern/cycles/blender/blender_shader.cpp @@ -173,7 +173,6 @@ static ShaderNode *add_node(Scene *scene, BL::BlendData b_data, BL::Scene b_scen switch(b_node.type()) { /* not supported */ - case BL::ShaderNode::type_CURVE_VEC: break; case BL::ShaderNode::type_GEOMETRY: break; case BL::ShaderNode::type_MATERIAL: break; case BL::ShaderNode::type_MATERIAL_EXT: break; @@ -193,9 +192,18 @@ static ShaderNode *add_node(Scene *scene, BL::BlendData b_data, BL::Scene b_scen node = proxy; break; } + case BL::ShaderNode::type_CURVE_VEC: { + BL::ShaderNodeVectorCurve b_curve_node(b_node); + VectorCurvesNode *curves = new VectorCurvesNode(); + curvemapping_color_to_array(b_curve_node.mapping(), curves->curves, RAMP_TABLE_SIZE, false); + node = curves; + break; + } case BL::ShaderNode::type_CURVE_RGB: { - RGBCurvesNode *ramp = new RGBCurvesNode(); - node = ramp; + BL::ShaderNodeRGBCurve b_curve_node(b_node); + RGBCurvesNode *curves = new RGBCurvesNode(); + curvemapping_color_to_array(b_curve_node.mapping(), curves->curves, RAMP_TABLE_SIZE, true); + node = curves; break; } case BL::ShaderNode::type_VALTORGB: { diff --git a/intern/cycles/blender/blender_util.h b/intern/cycles/blender/blender_util.h index 0a9f2dd06aa..fbcbe15ec5a 100644 --- a/intern/cycles/blender/blender_util.h +++ b/intern/cycles/blender/blender_util.h @@ -52,6 +52,36 @@ static inline void colorramp_to_array(BL::ColorRamp ramp, float4 *data, int size } } +static inline void curvemapping_color_to_array(BL::CurveMapping cumap, float4 *data, int size, bool rgb_curve) +{ + cumap.update(); + + BL::CurveMap mapR = cumap.curves[0]; + BL::CurveMap mapG = cumap.curves[1]; + BL::CurveMap mapB = cumap.curves[2]; + + if(rgb_curve) { + BL::CurveMap mapI = cumap.curves[3]; + + for(int i = 0; i < size; i++) { + float t = i/(float)(size-1); + + data[i][0] = mapR.evaluate(mapI.evaluate(t)); + data[i][1] = mapG.evaluate(mapI.evaluate(t)); + data[i][2] = mapB.evaluate(mapI.evaluate(t)); + } + } + else { + for(int i = 0; i < size; i++) { + float t = i/(float)(size-1); + + data[i][0] = mapR.evaluate(t); + data[i][1] = mapG.evaluate(t); + data[i][2] = mapB.evaluate(t); + } + } +} + static inline bool BKE_object_is_modified(BL::Object self, BL::Scene scene, bool preview) { return self.is_modified(scene, (preview)? (1<<0): (1<<1))? true: false; diff --git a/intern/cycles/kernel/shaders/CMakeLists.txt b/intern/cycles/kernel/shaders/CMakeLists.txt index f7fec62fd6d..70fc8610c98 100644 --- a/intern/cycles/kernel/shaders/CMakeLists.txt +++ b/intern/cycles/kernel/shaders/CMakeLists.txt @@ -49,6 +49,7 @@ set(SRC_OSL node_output_volume.osl node_particle_info.osl node_refraction_bsdf.osl + node_rgb_curves.osl node_rgb_ramp.osl node_separate_rgb.osl node_set_normal.osl @@ -58,6 +59,7 @@ set(SRC_OSL node_translucent_bsdf.osl node_transparent_bsdf.osl node_value.osl + node_vector_curves.osl node_vector_math.osl node_velvet_bsdf.osl node_voronoi_texture.osl diff --git a/intern/cycles/kernel/shaders/node_rgb_curves.osl b/intern/cycles/kernel/shaders/node_rgb_curves.osl new file mode 100644 index 00000000000..baa1d5c3de4 --- /dev/null +++ b/intern/cycles/kernel/shaders/node_rgb_curves.osl @@ -0,0 +1,53 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "stdosl.h" +#include "oslutil.h" + +float ramp_lookup(color ramp[RAMP_TABLE_SIZE], float at, int component) +{ + float f = clamp(at, 0.0, 1.0) * (RAMP_TABLE_SIZE - 1); + + /* clamp int as well in case of NaN */ + int i = (int)f; + if (i < 0) i = 0; + if (i >= RAMP_TABLE_SIZE) i = RAMP_TABLE_SIZE - 1; + float t = f - (float)i; + + float result = ramp[i][component]; + + if (t > 0.0) + result = (1.0 - t) * result + t * ramp[i + 1][component]; + + return result; +} + +shader node_rgb_curves( + color ramp[RAMP_TABLE_SIZE] = {0.0}, + + color ColorIn = color(0.0, 0.0, 0.0), + float Fac = 0.0, + output color ColorOut = color(0.0, 0.0, 0.0)) +{ + ColorOut[0] = ramp_lookup(ramp, ColorIn[0], 0); + ColorOut[1] = ramp_lookup(ramp, ColorIn[1], 1); + ColorOut[2] = ramp_lookup(ramp, ColorIn[2], 2); + + ColorOut = mix(ColorIn, ColorOut, Fac); +} + diff --git a/intern/cycles/kernel/shaders/node_vector_curves.osl b/intern/cycles/kernel/shaders/node_vector_curves.osl new file mode 100644 index 00000000000..94082287f4d --- /dev/null +++ b/intern/cycles/kernel/shaders/node_vector_curves.osl @@ -0,0 +1,53 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "stdosl.h" +#include "oslutil.h" + +float ramp_lookup(color ramp[RAMP_TABLE_SIZE], float at, int component) +{ + float f = clamp((at + 1.0)*0.5, 0.0, 1.0) * (RAMP_TABLE_SIZE - 1); + + /* clamp int as well in case of NaN */ + int i = (int)f; + if (i < 0) i = 0; + if (i >= RAMP_TABLE_SIZE) i = RAMP_TABLE_SIZE - 1; + float t = f - (float)i; + + float result = ramp[i][component]; + + if (t > 0.0) + result = (1.0 - t) * result + t * ramp[i + 1][component]; + + return result*2.0 - 1.0; +} + +shader node_vector_curves( + color ramp[RAMP_TABLE_SIZE] = {0.0}, + + vector VectorIn = vector(0.0, 0.0, 0.0), + float Fac = 0.0, + output vector VectorOut = vector(0.0, 0.0, 0.0)) +{ + VectorOut[0] = ramp_lookup(ramp, VectorIn[0], 0); + VectorOut[1] = ramp_lookup(ramp, VectorIn[1], 1); + VectorOut[2] = ramp_lookup(ramp, VectorIn[2], 2); + + VectorOut = mix(VectorIn, VectorOut, Fac); +} + diff --git a/intern/cycles/kernel/svm/svm.h b/intern/cycles/kernel/svm/svm.h index 9c79886fdca..ec7978066c2 100644 --- a/intern/cycles/kernel/svm/svm.h +++ b/intern/cycles/kernel/svm/svm.h @@ -398,6 +398,9 @@ __device_noinline void svm_eval_nodes(KernelGlobals *kg, ShaderData *sd, ShaderT case NODE_RGB_CURVES: svm_node_rgb_curves(kg, sd, stack, node, &offset); break; + case NODE_VECTOR_CURVES: + svm_node_vector_curves(kg, sd, stack, node, &offset); + break; case NODE_LIGHT_FALLOFF: svm_node_light_falloff(sd, stack, node); break; diff --git a/intern/cycles/kernel/svm/svm_ramp.h b/intern/cycles/kernel/svm/svm_ramp.h index c64413cbe84..054137fe7a3 100644 --- a/intern/cycles/kernel/svm/svm_ramp.h +++ b/intern/cycles/kernel/svm/svm_ramp.h @@ -63,9 +63,9 @@ __device void svm_node_rgb_curves(KernelGlobals *kg, ShaderData *sd, float *stac float fac = stack_load_float(stack, fac_offset); float3 color = stack_load_float3(stack, color_offset); - float r = rgb_ramp_lookup(kg, *offset, rgb_ramp_lookup(kg, *offset, color.x).w).x; - float g = rgb_ramp_lookup(kg, *offset, rgb_ramp_lookup(kg, *offset, color.y).w).y; - float b = rgb_ramp_lookup(kg, *offset, rgb_ramp_lookup(kg, *offset, color.z).w).z; + float r = rgb_ramp_lookup(kg, *offset, color.x).x; + float g = rgb_ramp_lookup(kg, *offset, color.y).y; + float b = rgb_ramp_lookup(kg, *offset, color.z).z; color = (1.0f - fac)*color + fac*make_float3(r, g, b); stack_store_float3(stack, out_offset, color); @@ -73,6 +73,25 @@ __device void svm_node_rgb_curves(KernelGlobals *kg, ShaderData *sd, float *stac *offset += RAMP_TABLE_SIZE; } +__device void svm_node_vector_curves(KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node, int *offset) +{ + uint fac_offset = node.y; + uint color_offset = node.z; + uint out_offset = node.w; + + float fac = stack_load_float(stack, fac_offset); + float3 color = stack_load_float3(stack, color_offset); + + float r = rgb_ramp_lookup(kg, *offset, (color.x + 1.0f)*0.5f).x; + float g = rgb_ramp_lookup(kg, *offset, (color.y + 1.0f)*0.5f).y; + float b = rgb_ramp_lookup(kg, *offset, (color.z + 1.0f)*0.5f).z; + + color = (1.0f - fac)*color + fac*make_float3(r*2.0f - 1.0f, g*2.0f - 1.0f, b*2.0f - 1.0f); + stack_store_float3(stack, out_offset, color); + + *offset += RAMP_TABLE_SIZE; +} + CCL_NAMESPACE_END #endif /* __SVM_RAMP_H__ */ diff --git a/intern/cycles/kernel/svm/svm_types.h b/intern/cycles/kernel/svm/svm_types.h index b41e34ab407..e7fe6dc0857 100644 --- a/intern/cycles/kernel/svm/svm_types.h +++ b/intern/cycles/kernel/svm/svm_types.h @@ -88,6 +88,7 @@ typedef enum NodeType { NODE_BRIGHTCONTRAST, NODE_RGB_RAMP, NODE_RGB_CURVES, + NODE_VECTOR_CURVES, NODE_MIN_MAX, NODE_LIGHT_FALLOFF, NODE_OBJECT_INFO, diff --git a/intern/cycles/render/nodes.cpp b/intern/cycles/render/nodes.cpp index 3f8055b3540..aef28449e44 100644 --- a/intern/cycles/render/nodes.cpp +++ b/intern/cycles/render/nodes.cpp @@ -3018,9 +3018,56 @@ void RGBCurvesNode::compile(SVMCompiler& compiler) void RGBCurvesNode::compile(OSLCompiler& compiler) { + float ramp[RAMP_TABLE_SIZE][3]; + + for (int i = 0; i < RAMP_TABLE_SIZE; ++i) { + ramp[i][0] = curves[i].x; + ramp[i][1] = curves[i].y; + ramp[i][2] = curves[i].z; + } + + compiler.parameter_color_array("ramp", ramp, RAMP_TABLE_SIZE); compiler.add(this, "node_rgb_curves"); } +/* VectorCurvesNode */ + +VectorCurvesNode::VectorCurvesNode() +: ShaderNode("rgb_curves") +{ + add_input("Fac", SHADER_SOCKET_FLOAT); + add_input("Vector", SHADER_SOCKET_VECTOR); + add_output("Vector", SHADER_SOCKET_VECTOR); +} + +void VectorCurvesNode::compile(SVMCompiler& compiler) +{ + ShaderInput *fac_in = input("Fac"); + ShaderInput *vector_in = input("Vector"); + ShaderOutput *vector_out = output("Vector"); + + compiler.stack_assign(fac_in); + compiler.stack_assign(vector_in); + compiler.stack_assign(vector_out); + + compiler.add_node(NODE_VECTOR_CURVES, fac_in->stack_offset, vector_in->stack_offset, vector_out->stack_offset); + compiler.add_array(curves, RAMP_TABLE_SIZE); +} + +void VectorCurvesNode::compile(OSLCompiler& compiler) +{ + float ramp[RAMP_TABLE_SIZE][3]; + + for (int i = 0; i < RAMP_TABLE_SIZE; ++i) { + ramp[i][0] = curves[i].x; + ramp[i][1] = curves[i].y; + ramp[i][2] = curves[i].z; + } + + compiler.parameter_color_array("ramp", ramp, RAMP_TABLE_SIZE); + compiler.add(this, "node_vector_curves"); +} + /* RGBRampNode */ RGBRampNode::RGBRampNode() diff --git a/intern/cycles/render/nodes.h b/intern/cycles/render/nodes.h index 67733142dd1..5e357cff56c 100644 --- a/intern/cycles/render/nodes.h +++ b/intern/cycles/render/nodes.h @@ -455,6 +455,12 @@ public: float4 curves[RAMP_TABLE_SIZE]; }; +class VectorCurvesNode : public ShaderNode { +public: + SHADER_NODE_CLASS(VectorCurvesNode) + float4 curves[RAMP_TABLE_SIZE]; +}; + class RGBRampNode : public ShaderNode { public: SHADER_NODE_CLASS(RGBRampNode) diff --git a/source/blender/nodes/shader/nodes/node_shader_curves.c b/source/blender/nodes/shader/nodes/node_shader_curves.c index 9fa654c9740..216e10a7e9a 100644 --- a/source/blender/nodes/shader/nodes/node_shader_curves.c +++ b/source/blender/nodes/shader/nodes/node_shader_curves.c @@ -74,7 +74,7 @@ void register_node_type_sh_curve_vec(bNodeTreeType *ttype) static bNodeType ntype; node_type_base(ttype, &ntype, SH_NODE_CURVE_VEC, "Vector Curves", NODE_CLASS_OP_VECTOR, NODE_OPTIONS); - node_type_compatibility(&ntype, NODE_OLD_SHADING); + node_type_compatibility(&ntype, NODE_OLD_SHADING|NODE_NEW_SHADING); node_type_socket_templates(&ntype, sh_node_curve_vec_in, sh_node_curve_vec_out); node_type_size(&ntype, 200, 140, 320); node_type_init(&ntype, node_shader_init_curve_vec); @@ -132,7 +132,7 @@ void register_node_type_sh_curve_rgb(bNodeTreeType *ttype) static bNodeType ntype; node_type_base(ttype, &ntype, SH_NODE_CURVE_RGB, "RGB Curves", NODE_CLASS_OP_COLOR, NODE_OPTIONS); - node_type_compatibility(&ntype, NODE_OLD_SHADING); + node_type_compatibility(&ntype, NODE_OLD_SHADING|NODE_NEW_SHADING); node_type_socket_templates(&ntype, sh_node_curve_rgb_in, sh_node_curve_rgb_out); node_type_size(&ntype, 200, 140, 320); node_type_init(&ntype, node_shader_init_curve_rgb); From 8d4bd2cf3b08456dfdec39b9c88f744ce8f12c72 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Tue, 11 Dec 2012 14:39:41 +0000 Subject: [PATCH 023/252] Cycles OSL: add diffuse_ramp closure in addition to phong_ramp. --- intern/cycles/kernel/CMakeLists.txt | 1 + .../cycles/kernel/closure/bsdf_diffuse_ramp.h | 96 +++++++++++++++ intern/cycles/kernel/osl/CMakeLists.txt | 1 + .../cycles/kernel/osl/bsdf_diffuse_ramp.cpp | 115 ++++++++++++++++++ intern/cycles/kernel/osl/osl_closures.cpp | 2 + intern/cycles/kernel/osl/osl_closures.h | 2 + intern/cycles/kernel/shaders/stdosl.h | 1 + intern/cycles/kernel/svm/svm_bsdf.h | 11 ++ intern/cycles/kernel/svm/svm_types.h | 1 + 9 files changed, 230 insertions(+) create mode 100644 intern/cycles/kernel/closure/bsdf_diffuse_ramp.h create mode 100644 intern/cycles/kernel/osl/bsdf_diffuse_ramp.cpp diff --git a/intern/cycles/kernel/CMakeLists.txt b/intern/cycles/kernel/CMakeLists.txt index 5a570328948..b7878e9b00f 100644 --- a/intern/cycles/kernel/CMakeLists.txt +++ b/intern/cycles/kernel/CMakeLists.txt @@ -49,6 +49,7 @@ set(SRC_CLOSURE_HEADERS closure/bsdf.h closure/bsdf_ashikhmin_velvet.h closure/bsdf_diffuse.h + closure/bsdf_diffuse_ramp.h closure/bsdf_microfacet.h closure/bsdf_oren_nayar.h closure/bsdf_phong_ramp.h diff --git a/intern/cycles/kernel/closure/bsdf_diffuse_ramp.h b/intern/cycles/kernel/closure/bsdf_diffuse_ramp.h new file mode 100644 index 00000000000..8a09979806a --- /dev/null +++ b/intern/cycles/kernel/closure/bsdf_diffuse_ramp.h @@ -0,0 +1,96 @@ +/* + * Adapted from Open Shading Language with this license: + * + * Copyright (c) 2009-2010 Sony Pictures Imageworks Inc., et al. + * All Rights Reserved. + * + * Modifications Copyright 2012, Blender Foundation. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Sony Pictures Imageworks nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __BSDF_DIFFUSE_RAMP_H__ +#define __BSDF_DIFFUSE_RAMP_H__ + +CCL_NAMESPACE_BEGIN + +__device float3 bsdf_diffuse_ramp_get_color(const ShaderClosure *sc, const float3 colors[8], float pos) +{ + int MAXCOLORS = 8; + + float npos = pos * (float)(MAXCOLORS - 1); + int ipos = (int)npos; + if (ipos >= (MAXCOLORS - 1)) + return colors[MAXCOLORS - 1]; + float offset = npos - (float)ipos; + return colors[ipos] * (1.0f - offset) + colors[ipos+1] * offset; +} + +__device int bsdf_diffuse_ramp_setup(ShaderClosure *sc) +{ + sc->type = CLOSURE_BSDF_DIFFUSE_RAMP_ID; + return SD_BSDF | SD_BSDF_HAS_EVAL; +} + +__device void bsdf_diffuse_ramp_blur(ShaderClosure *sc, float roughness) +{ +} + +__device float3 bsdf_diffuse_ramp_eval_reflect(const ShaderClosure *sc, const float3 colors[8], const float3 I, const float3 omega_in, float *pdf) +{ + float3 N = sc->N; + + float cos_pi = fmaxf(dot(N, omega_in), 0.0f); + *pdf = cos_pi * M_1_PI_F; + return bsdf_diffuse_ramp_get_color(sc, colors, cos_pi) * M_1_PI_F; +} + +__device float3 bsdf_diffuse_ramp_eval_transmit(const ShaderClosure *sc, const float3 colors[8], const float3 I, const float3 omega_in, float *pdf) +{ + return make_float3(0.0f, 0.0f, 0.0f); +} + +__device int bsdf_diffuse_ramp_sample(const ShaderClosure *sc, const float3 colors[8], float3 Ng, float3 I, float3 dIdx, float3 dIdy, float randu, float randv, float3 *eval, float3 *omega_in, float3 *domega_in_dx, float3 *domega_in_dy, float *pdf) +{ + float3 N = sc->N; + + // distribution over the hemisphere + sample_cos_hemisphere(N, randu, randv, omega_in, pdf); + + if(dot(Ng, *omega_in) > 0.0f) { + *eval = bsdf_diffuse_ramp_get_color(sc, colors, *pdf * M_PI_F) * M_1_PI_F; +#ifdef __RAY_DIFFERENTIALS__ + *domega_in_dx = (2 * dot(N, dIdx)) * N - dIdx; + *domega_in_dy = (2 * dot(N, dIdy)) * N - dIdy; +#endif + } + else + *pdf = 0.0f; + + return LABEL_REFLECT|LABEL_DIFFUSE; +} + +CCL_NAMESPACE_END + +#endif /* __BSDF_DIFFUSE_RAMP_H__ */ diff --git a/intern/cycles/kernel/osl/CMakeLists.txt b/intern/cycles/kernel/osl/CMakeLists.txt index 1b1bb558bc9..80653f24338 100644 --- a/intern/cycles/kernel/osl/CMakeLists.txt +++ b/intern/cycles/kernel/osl/CMakeLists.txt @@ -14,6 +14,7 @@ set(INC_SYS set(SRC background.cpp + bsdf_diffuse_ramp.cpp bsdf_phong_ramp.cpp emissive.cpp osl_closures.cpp diff --git a/intern/cycles/kernel/osl/bsdf_diffuse_ramp.cpp b/intern/cycles/kernel/osl/bsdf_diffuse_ramp.cpp new file mode 100644 index 00000000000..7189f99a822 --- /dev/null +++ b/intern/cycles/kernel/osl/bsdf_diffuse_ramp.cpp @@ -0,0 +1,115 @@ +/* + * Adapted from Open Shading Language with this license: + * + * Copyright (c) 2009-2010 Sony Pictures Imageworks Inc., et al. + * All Rights Reserved. + * + * Modifications Copyright 2011, Blender Foundation. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Sony Pictures Imageworks nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include + +#include + +#include "osl_closures.h" + +#include "kernel_types.h" +#include "kernel_montecarlo.h" +#include "closure/bsdf_diffuse_ramp.h" + +CCL_NAMESPACE_BEGIN + +using namespace OSL; + +class DiffuseRampClosure : public CBSDFClosure { +public: + DiffuseRampClosure() : CBSDFClosure(LABEL_DIFFUSE) {} + Color3 colors[8]; + float3 fcolors[8]; + + size_t memsize() const { return sizeof(*this); } + const char *name() const { return "diffuse_ramp"; } + + void setup() + { + sc.N = TO_FLOAT3(N); + m_shaderdata_flag = bsdf_diffuse_ramp_setup(&sc); + + for(int i = 0; i < 8; i++) + fcolors[i] = TO_FLOAT3(colors[i]); + } + + bool mergeable(const ClosurePrimitive *other) const + { + return false; + } + + void blur(float roughness) + { + bsdf_diffuse_ramp_blur(&sc, roughness); + } + + void print_on(std::ostream &out) const + { + out << name() << " ((" << sc.N[0] << ", " << sc.N[1] << ", " << sc.N[2] << "))"; + } + + float3 eval_reflect(const float3 &omega_out, const float3 &omega_in, float& pdf) const + { + return bsdf_diffuse_ramp_eval_reflect(&sc, fcolors, omega_out, omega_in, &pdf); + } + + float3 eval_transmit(const float3 &omega_out, const float3 &omega_in, float& pdf) const + { + return bsdf_diffuse_ramp_eval_transmit(&sc, fcolors, omega_out, omega_in, &pdf); + } + + int sample(const float3 &Ng, + const float3 &omega_out, const float3 &domega_out_dx, const float3 &domega_out_dy, + float randu, float randv, + float3 &omega_in, float3 &domega_in_dx, float3 &domega_in_dy, + float &pdf, float3 &eval) const + { + return bsdf_diffuse_ramp_sample(&sc, fcolors, Ng, omega_out, domega_out_dx, domega_out_dy, + randu, randv, &eval, &omega_in, &domega_in_dx, &domega_in_dy, &pdf); + } +}; + +ClosureParam *closure_bsdf_diffuse_ramp_params() +{ + static ClosureParam params[] = { + CLOSURE_VECTOR_PARAM(DiffuseRampClosure, N), + CLOSURE_COLOR_ARRAY_PARAM(DiffuseRampClosure, colors, 8), + CLOSURE_STRING_KEYPARAM("label"), + CLOSURE_FINISH_PARAM(DiffuseRampClosure) + }; + return params; +} + +CLOSURE_PREPARE(closure_bsdf_diffuse_ramp_prepare, DiffuseRampClosure) + +CCL_NAMESPACE_END + diff --git a/intern/cycles/kernel/osl/osl_closures.cpp b/intern/cycles/kernel/osl/osl_closures.cpp index f95859d237d..1f71fde549e 100644 --- a/intern/cycles/kernel/osl/osl_closures.cpp +++ b/intern/cycles/kernel/osl/osl_closures.cpp @@ -196,6 +196,8 @@ void OSLShader::register_closures(OSLShadingSystem *ss_) closure_ambient_occlusion_params(), closure_ambient_occlusion_prepare); register_closure(ss, "phong_ramp", id++, closure_bsdf_phong_ramp_params(), closure_bsdf_phong_ramp_prepare); + register_closure(ss, "diffuse_ramp", id++, + closure_bsdf_diffuse_ramp_params(), closure_bsdf_diffuse_ramp_prepare); } CCL_NAMESPACE_END diff --git a/intern/cycles/kernel/osl/osl_closures.h b/intern/cycles/kernel/osl/osl_closures.h index 2d91b37be7e..5cd333c806e 100644 --- a/intern/cycles/kernel/osl/osl_closures.h +++ b/intern/cycles/kernel/osl/osl_closures.h @@ -48,12 +48,14 @@ OSL::ClosureParam *closure_background_params(); OSL::ClosureParam *closure_holdout_params(); OSL::ClosureParam *closure_ambient_occlusion_params(); OSL::ClosureParam *closure_bsdf_phong_ramp_params(); +OSL::ClosureParam *closure_bsdf_diffuse_ramp_params(); void closure_emission_prepare(OSL::RendererServices *, int id, void *data); void closure_background_prepare(OSL::RendererServices *, int id, void *data); void closure_holdout_prepare(OSL::RendererServices *, int id, void *data); void closure_ambient_occlusion_prepare(OSL::RendererServices *, int id, void *data); void closure_bsdf_phong_ramp_prepare(OSL::RendererServices *, int id, void *data); +void closure_bsdf_diffuse_ramp_prepare(OSL::RendererServices *, int id, void *data); enum { AmbientOcclusion = 100 diff --git a/intern/cycles/kernel/shaders/stdosl.h b/intern/cycles/kernel/shaders/stdosl.h index 24c3a50e6f6..f4c0d0734bc 100644 --- a/intern/cycles/kernel/shaders/stdosl.h +++ b/intern/cycles/kernel/shaders/stdosl.h @@ -434,6 +434,7 @@ string concat (string a, string b, string c, string d, string e, string f) { closure color diffuse(normal N) BUILTIN; closure color oren_nayar(normal N, float sigma) BUILTIN; closure color phong_ramp(normal N, float exponent, color colors[8]) BUILTIN; +closure color diffuse_ramp(normal N, color colors[8]) BUILTIN; closure color translucent(normal N) BUILTIN; closure color reflection(normal N) BUILTIN; closure color refraction(normal N, float eta) BUILTIN; diff --git a/intern/cycles/kernel/svm/svm_bsdf.h b/intern/cycles/kernel/svm/svm_bsdf.h index 07927fe5691..a9524f3ed37 100644 --- a/intern/cycles/kernel/svm/svm_bsdf.h +++ b/intern/cycles/kernel/svm/svm_bsdf.h @@ -20,6 +20,7 @@ #include "../closure/bsdf_diffuse.h" #include "../closure/bsdf_oren_nayar.h" #include "../closure/bsdf_phong_ramp.h" +#include "../closure/bsdf_diffuse_ramp.h" #include "../closure/bsdf_microfacet.h" #include "../closure/bsdf_reflection.h" #include "../closure/bsdf_refraction.h" @@ -48,6 +49,10 @@ __device int svm_bsdf_sample(const ShaderData *sd, const ShaderClosure *sc, floa /*case CLOSURE_BSDF_PHONG_RAMP_ID: label = bsdf_phong_ramp_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv, eval, omega_in, &domega_in->dx, &domega_in->dy, pdf); + break; + case CLOSURE_BSDF_DIFFUSE_RAMP_ID: + label = bsdf_diffuse_ramp_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv, + eval, omega_in, &domega_in->dx, &domega_in->dy, pdf); break;*/ case CLOSURE_BSDF_TRANSLUCENT_ID: label = bsdf_translucent_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv, @@ -117,6 +122,9 @@ __device float3 svm_bsdf_eval(const ShaderData *sd, const ShaderClosure *sc, con break; /*case CLOSURE_BSDF_PHONG_RAMP_ID: eval = bsdf_phong_ramp_eval_reflect(sc, sd->I, omega_in, pdf); + break; + case CLOSURE_BSDF_DIFFUSE_RAMP_ID: + eval = bsdf_diffuse_ramp_eval_reflect(sc, sd->I, omega_in, pdf); break;*/ case CLOSURE_BSDF_TRANSLUCENT_ID: eval = bsdf_translucent_eval_reflect(sc, sd->I, omega_in, pdf); @@ -223,6 +231,9 @@ __device void svm_bsdf_blur(ShaderClosure *sc, float roughness) break; /*case CLOSURE_BSDF_PHONG_RAMP_ID: bsdf_phong_ramp_blur(sc, roughness); + break; + case CLOSURE_BSDF_DIFFUSE_RAMP_ID: + bsdf_diffuse_ramp_blur(sc, roughness); break;*/ case CLOSURE_BSDF_TRANSLUCENT_ID: bsdf_translucent_blur(sc, roughness); diff --git a/intern/cycles/kernel/svm/svm_types.h b/intern/cycles/kernel/svm/svm_types.h index e7fe6dc0857..0830a700281 100644 --- a/intern/cycles/kernel/svm/svm_types.h +++ b/intern/cycles/kernel/svm/svm_types.h @@ -313,6 +313,7 @@ typedef enum ClosureType { CLOSURE_BSDF_DIFFUSE_ID, CLOSURE_BSDF_OREN_NAYAR_ID, + CLOSURE_BSDF_DIFFUSE_RAMP_ID, CLOSURE_BSDF_GLOSSY_ID, CLOSURE_BSDF_REFLECTION_ID, From cb116b42f46fc11c60d1976c190eb1d9570da48a Mon Sep 17 00:00:00 2001 From: Ton Roosendaal Date: Tue, 11 Dec 2012 14:45:38 +0000 Subject: [PATCH 024/252] Bug fix, irc report: When camera is the pivot of 3d window, and you go to camera view, moving out of view with MMB drag causes zooming to stop working. Zooms depend on view3d "dist" value, which then became zero. This fix just makes dist "1.0" then, arbitrary but keeps things at least work. (Tried restoring to previous 'dist', but this fails in cases too) --- source/blender/editors/space_view3d/view3d_edit.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/source/blender/editors/space_view3d/view3d_edit.c b/source/blender/editors/space_view3d/view3d_edit.c index dc3baf04a74..231a8d3dcf2 100644 --- a/source/blender/editors/space_view3d/view3d_edit.c +++ b/source/blender/editors/space_view3d/view3d_edit.c @@ -3977,16 +3977,25 @@ int ED_view3d_autodist_depth_seg(ARegion *ar, const int mval_sta[2], const int m return (*depth == FLT_MAX) ? 0 : 1; } -float ED_view3d_offset_distance(float mat[4][4], float ofs[3]) { +float ED_view3d_offset_distance(float mat[4][4], float ofs[3]) +{ float pos[4] = {0.0f, 0.0f, 0.0f, 1.0f}; float dir[4] = {0.0f, 0.0f, 1.0f, 0.0f}; - + float dist; + mul_m4_v4(mat, pos); add_v3_v3(pos, ofs); mul_m4_v4(mat, dir); normalize_v3(dir); - return dot_v3v3(pos, dir); + dist = dot_v3v3(pos, dir); + + /* problem - ofs[3] can be on same location as camera itself. + Blender needs proper dist value for zoom */ + if ( fabs(dist) <= FLT_EPSILON) { + return 1.0f; + } + return dist; } /** From 3520dd56e3894d2b5c825dc98cdd5d846b6756c0 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 11 Dec 2012 15:06:51 +0000 Subject: [PATCH 025/252] fix for warnings/errors in recent commits --- source/blender/collada/collada_internal.cpp | 2 +- source/blender/collada/collada_internal.h | 4 ++-- source/blender/editors/space_view3d/view3d_edit.c | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/source/blender/collada/collada_internal.cpp b/source/blender/collada/collada_internal.cpp index 0c95cd6a31a..13ff69d3abf 100644 --- a/source/blender/collada/collada_internal.cpp +++ b/source/blender/collada/collada_internal.cpp @@ -91,7 +91,7 @@ void UnitConverter::mat4_to_dae(float out[4][4], float const in[4][4]) transpose_m4(out); } -void UnitConverter::mat4_to_dae_double(double out[4][4], float in[4][4]) +void UnitConverter::mat4_to_dae_double(double out[4][4], float const in[4][4]) { float mat[4][4]; diff --git a/source/blender/collada/collada_internal.h b/source/blender/collada/collada_internal.h index d92f53f714c..5a5126025de 100644 --- a/source/blender/collada/collada_internal.h +++ b/source/blender/collada/collada_internal.h @@ -71,9 +71,9 @@ public: void dae_matrix_to_mat4_(float out[4][4], const COLLADABU::Math::Matrix4& in); - void mat4_to_dae(float out[4][4], float in[4][4]); + void mat4_to_dae(float out[4][4], float const in[4][4]); - void mat4_to_dae_double(double out[4][4], float in[4][4]); + void mat4_to_dae_double(double out[4][4], float const in[4][4]); }; class TransformBase diff --git a/source/blender/editors/space_view3d/view3d_edit.c b/source/blender/editors/space_view3d/view3d_edit.c index 231a8d3dcf2..d0783419fe8 100644 --- a/source/blender/editors/space_view3d/view3d_edit.c +++ b/source/blender/editors/space_view3d/view3d_edit.c @@ -3992,7 +3992,7 @@ float ED_view3d_offset_distance(float mat[4][4], float ofs[3]) /* problem - ofs[3] can be on same location as camera itself. Blender needs proper dist value for zoom */ - if ( fabs(dist) <= FLT_EPSILON) { + if (fabsf(dist) <= FLT_EPSILON) { return 1.0f; } return dist; From 71730f26d7c816854a471c9733ad4c10b88fd357 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 11 Dec 2012 15:10:19 +0000 Subject: [PATCH 026/252] replace BLI_array_fixedstack_declare with() new macro BLI_array_alloca() which uses stack memory always and doesn't need to be freed explicitly. --- source/blender/blenkernel/intern/mesh.c | 6 +-- source/blender/blenlib/BLI_array.h | 19 +++++++ source/blender/bmesh/intern/bmesh_construct.c | 22 ++++---- source/blender/bmesh/intern/bmesh_core.c | 36 ++++--------- source/blender/bmesh/intern/bmesh_interp.c | 41 ++++---------- source/blender/bmesh/intern/bmesh_polygon.c | 25 +++------ source/blender/bmesh/intern/bmesh_queries.c | 6 +-- source/blender/bmesh/operators/bmo_extrude.c | 53 ++++++++----------- source/blender/bmesh/tools/bmesh_bevel.c | 4 +- source/blender/editors/mesh/editmesh_knife.c | 9 +--- .../editors/uvedit/uvedit_unwrap_ops.c | 5 +- 11 files changed, 84 insertions(+), 142 deletions(-) diff --git a/source/blender/blenkernel/intern/mesh.c b/source/blender/blenkernel/intern/mesh.c index 036f8f5e673..75504416067 100644 --- a/source/blender/blenkernel/intern/mesh.c +++ b/source/blender/blenkernel/intern/mesh.c @@ -3009,9 +3009,9 @@ float BKE_mesh_calc_poly_area(MPoly *mpoly, MLoop *loopstart, else { int i; MLoop *l_iter = loopstart; - float area, polynorm_local[3], (*vertexcos)[3]; + float area, polynorm_local[3]; + float (*vertexcos)[3] = BLI_array_alloca(vertexcos, mpoly->totloop); const float *no = polynormal ? polynormal : polynorm_local; - BLI_array_fixedstack_declare(vertexcos, BM_DEFAULT_NGON_STACK_SIZE, mpoly->totloop, __func__); /* pack vertex cos into an array for area_poly_v3 */ for (i = 0; i < mpoly->totloop; i++, l_iter++) { @@ -3026,8 +3026,6 @@ float BKE_mesh_calc_poly_area(MPoly *mpoly, MLoop *loopstart, /* finally calculate the area */ area = area_poly_v3(mpoly->totloop, vertexcos, no); - BLI_array_fixedstack_free(vertexcos); - return area; } } diff --git a/source/blender/blenlib/BLI_array.h b/source/blender/blenlib/BLI_array.h index a21778307c1..975476a669b 100644 --- a/source/blender/blenlib/BLI_array.h +++ b/source/blender/blenlib/BLI_array.h @@ -196,3 +196,22 @@ if (_##arr##_is_static) { \ MEM_freeN(arr); \ } (void)0 + + +/* alloca */ +#if defined(__GNUC__) || defined(__clang__) +#define BLI_array_alloca(arr, realsize) \ + (typeof(arr))alloca(sizeof(*arr) * (realsize)) + +#define BLI_array_alloca_and_count(arr, realsize) \ + (typeof(arr))alloca(sizeof(*arr) * (realsize)); \ + const int _##arr##_count = (realsize) + +#else +#define BLI_array_alloca(arr, realsize) \ + alloca(sizeof(*arr) * (realsize)) + +#define BLI_array_alloca_and_count(arr, realsize) \ + alloca(sizeof(*arr) * (realsize)); \ + const int _##arr##_count = (realsize) +#endif diff --git a/source/blender/bmesh/intern/bmesh_construct.c b/source/blender/bmesh/intern/bmesh_construct.c index 8b7fac1eacd..e12110b31ca 100644 --- a/source/blender/bmesh/intern/bmesh_construct.c +++ b/source/blender/bmesh/intern/bmesh_construct.c @@ -173,15 +173,17 @@ void BM_face_copy_shared(BMesh *bm, BMFace *f) */ BMFace *BM_face_create_ngon(BMesh *bm, BMVert *v1, BMVert *v2, BMEdge **edges, int len, const int create_flag) { - BMEdge **edges2 = NULL; - BLI_array_staticdeclare(edges2, BM_DEFAULT_NGON_STACK_SIZE); - BMVert **verts = NULL; - BLI_array_staticdeclare(verts, BM_DEFAULT_NGON_STACK_SIZE); + BMEdge **edges2 = BLI_array_alloca_and_count(edges2, len); + BMVert **verts = BLI_array_alloca_and_count(verts, len + 1); + int e2_index = 0; + int v_index = 0; + BMFace *f = NULL; BMEdge *e; BMVert *v, *ev1, *ev2; int i, /* j, */ v1found, reverse; + /* this code is hideous, yeek. I'll have to think about ways of * cleaning it up. basically, it now combines the old BM_face_create_ngon * _and_ the old bmesh_mf functions, so its kindof smashed together @@ -207,14 +209,14 @@ BMFace *BM_face_create_ngon(BMesh *bm, BMVert *v1, BMVert *v2, BMEdge **edges, i SWAP(BMVert *, ev1, ev2); } - BLI_array_append(verts, ev1); + verts[v_index++] = ev1; v = ev2; e = edges[0]; do { BMEdge *e2 = e; - BLI_array_append(verts, v); - BLI_array_append(edges2, e); + verts[v_index++] = v; + edges2[e2_index++] = e; /* we only flag the verts to check if they are in the face more then once */ BM_ELEM_API_FLAG_ENABLE(v, _FLAG_MV); @@ -289,9 +291,6 @@ BMFace *BM_face_create_ngon(BMesh *bm, BMVert *v1, BMVert *v2, BMEdge **edges, i BM_ELEM_API_FLAG_DISABLE(edges2[i], _FLAG_MF); } - BLI_array_free(verts); - BLI_array_free(edges2); - return f; err: @@ -303,9 +302,6 @@ err: } } - BLI_array_free(verts); - BLI_array_free(edges2); - return NULL; } diff --git a/source/blender/bmesh/intern/bmesh_core.c b/source/blender/bmesh/intern/bmesh_core.c index b9feead0d45..4442b4eac9c 100644 --- a/source/blender/bmesh/intern/bmesh_core.c +++ b/source/blender/bmesh/intern/bmesh_core.c @@ -211,10 +211,8 @@ static BMLoop *bm_face_boundary_add(BMesh *bm, BMFace *f, BMVert *startv, BMEdge BMFace *BM_face_copy(BMesh *bm, BMFace *f, const short copyverts, const short copyedges) { - BMVert **verts = NULL; - BMEdge **edges = NULL; - BLI_array_fixedstack_declare(verts, BM_DEFAULT_NGON_STACK_SIZE, f->len, __func__); - BLI_array_fixedstack_declare(edges, BM_DEFAULT_NGON_STACK_SIZE, f->len, __func__); + BMVert **verts = BLI_array_alloca(verts, f->len); + BMEdge **edges = BLI_array_alloca(edges, f->len); BMLoop *l_iter; BMLoop *l_first; BMLoop *l_copy; @@ -267,9 +265,6 @@ BMFace *BM_face_copy(BMesh *bm, BMFace *f, const short copyverts, const short co l_copy = l_copy->next; } while ((l_iter = l_iter->next) != l_first); - BLI_array_fixedstack_free(verts); - BLI_array_fixedstack_free(edges); - return f_copy; } @@ -585,22 +580,19 @@ static void bm_kill_only_loop(BMesh *bm, BMLoop *l) */ void BM_face_edges_kill(BMesh *bm, BMFace *f) { - BMEdge **edges = NULL; - BLI_array_staticdeclare(edges, BM_DEFAULT_NGON_STACK_SIZE); + BMEdge **edges = BLI_array_alloca_and_count(edges, f->len); BMLoop *l_iter; BMLoop *l_first; - int i; + int i = 0; l_iter = l_first = BM_FACE_FIRST_LOOP(f); do { - BLI_array_append(edges, l_iter->e); + edges[i++] = l_iter->e; } while ((l_iter = l_iter->next) != l_first); for (i = 0; i < BLI_array_count(edges); i++) { BM_edge_kill(bm, edges[i]); } - - BLI_array_free(edges); } /** @@ -609,22 +601,19 @@ void BM_face_edges_kill(BMesh *bm, BMFace *f) */ void BM_face_verts_kill(BMesh *bm, BMFace *f) { - BMVert **verts = NULL; - BLI_array_staticdeclare(verts, BM_DEFAULT_NGON_STACK_SIZE); + BMVert **verts = BLI_array_alloca_and_count(verts, f->len); BMLoop *l_iter; BMLoop *l_first; - int i; + int i = 0; l_iter = l_first = BM_FACE_FIRST_LOOP(f); do { - BLI_array_append(verts, l_iter->v); + verts[i++] = l_iter->v; } while ((l_iter = l_iter->next) != l_first); for (i = 0; i < BLI_array_count(verts); i++) { BM_vert_kill(bm, verts[i]); } - - BLI_array_free(verts); } /** @@ -761,8 +750,7 @@ static int bm_loop_reverse_loop(BMesh *bm, BMFace *f const int len = f->len; const int do_disps = CustomData_has_layer(&bm->ldata, CD_MDISPS); BMLoop *l_iter, *oldprev, *oldnext; - BMEdge **edar = NULL; - BLI_array_fixedstack_declare(edar, BM_DEFAULT_NGON_STACK_SIZE, len, __func__); + BMEdge **edar = BLI_array_alloca(edar, len); int i, j, edok; for (i = 0, l_iter = l_first; i < len; i++, l_iter = l_iter->next) { @@ -826,8 +814,6 @@ static int bm_loop_reverse_loop(BMesh *bm, BMFace *f BM_CHECK_ELEMENT(l_iter->f); } - BLI_array_fixedstack_free(edar); - BM_CHECK_ELEMENT(f); return 1; @@ -1614,8 +1600,7 @@ BMEdge *bmesh_jekv(BMesh *bm, BMEdge *ke, BMVert *kv, const short check_edge_dou radlen = bmesh_radial_length(ke->l); if (LIKELY(radlen)) { - BMLoop **loops = NULL; - BLI_array_fixedstack_declare(loops, BM_DEFAULT_NGON_STACK_SIZE, radlen, __func__); + BMLoop **loops = BLI_array_alloca(loops, radlen); killoop = ke->l; @@ -1628,7 +1613,6 @@ BMEdge *bmesh_jekv(BMesh *bm, BMEdge *ke, BMVert *kv, const short check_edge_dou bm->totloop--; BLI_mempool_free(bm->lpool, loops[i]); } - BLI_array_fixedstack_free(loops); } /* Validate radial cycle of oe */ diff --git a/source/blender/bmesh/intern/bmesh_interp.c b/source/blender/bmesh/intern/bmesh_interp.c index caf9f3c70d5..df58b90bc03 100644 --- a/source/blender/bmesh/intern/bmesh_interp.c +++ b/source/blender/bmesh/intern/bmesh_interp.c @@ -172,11 +172,9 @@ void BM_face_interp_from_face(BMesh *bm, BMFace *target, BMFace *source) BMLoop *l_iter; BMLoop *l_first; - void **blocks = NULL; - float (*cos)[3] = NULL, *w = NULL; - BLI_array_fixedstack_declare(cos, BM_DEFAULT_NGON_STACK_SIZE, source->len, __func__); - BLI_array_fixedstack_declare(w, BM_DEFAULT_NGON_STACK_SIZE, source->len, __func__); - BLI_array_fixedstack_declare(blocks, BM_DEFAULT_NGON_STACK_SIZE, source->len, __func__); + void **blocks = BLI_array_alloca(blocks, source->len); + float (*cos)[3] = BLI_array_alloca(cos, source->len); + float *w = BLI_array_alloca(w, source->len); int i; BM_elem_attrs_copy(bm, bm, source, target); @@ -196,10 +194,6 @@ void BM_face_interp_from_face(BMesh *bm, BMFace *target, BMFace *source) CustomData_bmesh_interp(&bm->ldata, blocks, w, NULL, source->len, l_iter->head.data); i++; } while ((l_iter = l_iter->next) != l_first); - - BLI_array_fixedstack_free(cos); - BLI_array_fixedstack_free(w); - BLI_array_fixedstack_free(blocks); } /** @@ -609,14 +603,12 @@ void BM_loop_interp_from_face(BMesh *bm, BMLoop *target, BMFace *source, { BMLoop *l_iter; BMLoop *l_first; - void **blocks = NULL; - void **vblocks = NULL; - float (*cos)[3] = NULL, co[3], *w = NULL; + void **vblocks = BLI_array_alloca(vblocks, do_vertex ? source->len : 0); + void **blocks = BLI_array_alloca(blocks, source->len); + float (*cos)[3] = BLI_array_alloca(cos, source->len); + float *w = BLI_array_alloca(w, source->len); + float co[3]; float cent[3] = {0.0f, 0.0f, 0.0f}; - BLI_array_fixedstack_declare(cos, BM_DEFAULT_NGON_STACK_SIZE, source->len, __func__); - BLI_array_fixedstack_declare(w, BM_DEFAULT_NGON_STACK_SIZE, source->len, __func__); - BLI_array_fixedstack_declare(blocks, BM_DEFAULT_NGON_STACK_SIZE, source->len, __func__); - BLI_array_fixedstack_declare(vblocks, BM_DEFAULT_NGON_STACK_SIZE, do_vertex ? source->len : 0, __func__); int i, ax, ay; BM_elem_attrs_copy(bm, bm, source, target->f); @@ -667,13 +659,8 @@ void BM_loop_interp_from_face(BMesh *bm, BMLoop *target, BMFace *source, CustomData_bmesh_interp(&bm->ldata, blocks, w, NULL, source->len, target->head.data); if (do_vertex) { CustomData_bmesh_interp(&bm->vdata, vblocks, w, NULL, source->len, target->v->head.data); - BLI_array_fixedstack_free(vblocks); } - BLI_array_fixedstack_free(cos); - BLI_array_fixedstack_free(w); - BLI_array_fixedstack_free(blocks); - if (do_multires) { if (CustomData_has_layer(&bm->ldata, CD_MDISPS)) { bm_loop_interp_mdisps(bm, target, source); @@ -686,12 +673,10 @@ void BM_vert_interp_from_face(BMesh *bm, BMVert *v, BMFace *source) { BMLoop *l_iter; BMLoop *l_first; - void **blocks = NULL; - float (*cos)[3] = NULL, *w = NULL; + void **blocks = BLI_array_alloca(blocks, source->len); + float (*cos)[3] = BLI_array_alloca(cos, source->len); + float *w = BLI_array_alloca(w, source->len); float cent[3] = {0.0f, 0.0f, 0.0f}; - BLI_array_fixedstack_declare(cos, BM_DEFAULT_NGON_STACK_SIZE, source->len, __func__); - BLI_array_fixedstack_declare(w, BM_DEFAULT_NGON_STACK_SIZE, source->len, __func__); - BLI_array_fixedstack_declare(blocks, BM_DEFAULT_NGON_STACK_SIZE, source->len, __func__); int i; i = 0; @@ -718,10 +703,6 @@ void BM_vert_interp_from_face(BMesh *bm, BMVert *v, BMFace *source) /* interpolate */ interp_weights_poly_v3(w, cos, source->len, v->co); CustomData_bmesh_interp(&bm->vdata, blocks, w, NULL, source->len, v->head.data); - - BLI_array_fixedstack_free(cos); - BLI_array_fixedstack_free(w); - BLI_array_fixedstack_free(blocks); } static void update_data_blocks(BMesh *bm, CustomData *olddata, CustomData *data) diff --git a/source/blender/bmesh/intern/bmesh_polygon.c b/source/blender/bmesh/intern/bmesh_polygon.c index 3018db1af16..953e7f4d20c 100644 --- a/source/blender/bmesh/intern/bmesh_polygon.c +++ b/source/blender/bmesh/intern/bmesh_polygon.c @@ -157,13 +157,11 @@ float BM_face_calc_area(BMFace *f) { BMLoop *l; BMIter iter; - float (*verts)[3]; + float (*verts)[3] = BLI_array_alloca(verts, f->len); float normal[3]; float area; int i; - BLI_array_fixedstack_declare(verts, BM_DEFAULT_NGON_STACK_SIZE, f->len, __func__); - BM_ITER_ELEM_INDEX (l, &iter, f, BM_LOOPS_OF_FACE, i) { copy_v3_v3(verts[i], l->v->co); } @@ -179,8 +177,6 @@ float BM_face_calc_area(BMFace *f) area = area_poly_v3(f->len, verts, normal); } - BLI_array_fixedstack_free(verts); - return area; } @@ -855,8 +851,8 @@ void BM_face_triangulate(BMesh *bm, BMFace *f, float (*projectverts)[3], const s BMLoop *newl; BMLoop *l_iter; BMLoop *l_first; - float *abscoss = NULL; - BLI_array_fixedstack_declare(abscoss, 16, f->len, "BM_face_triangulate: temp absolute cosines of face corners"); + /* BM_face_triangulate: temp absolute cosines of face corners */ + float *abscoss = BLI_array_alloca(abscoss, f->len); /* copy vertex coordinates to vertspace area */ i = 0; @@ -940,11 +936,10 @@ void BM_face_triangulate(BMesh *bm, BMFace *f, float (*projectverts)[3], const s } #endif - BLI_array_fixedstack_free(abscoss); - /* NULL-terminate */ - if (newfaces) + if (newfaces) { newfaces[nf_i] = NULL; + } } /** @@ -961,13 +956,10 @@ void BM_face_legal_splits(BMesh *bm, BMFace *f, BMLoop *(*loops)[2], int len) BMLoop *l; float v1[3], v2[3], v3[3] /*, v4[3 */, no[3], mid[3], *p1, *p2, *p3, *p4; float out[3] = {-FLT_MAX, -FLT_MAX, 0.0f}; - float (*projverts)[3]; - float (*edgeverts)[3]; + float (*projverts)[3] = BLI_array_alloca(projverts, f->len); + float (*edgeverts)[3] = BLI_array_alloca(edgeverts, len * 2); float fac1 = 1.0000001f, fac2 = 0.9f; //9999f; //0.999f; int i, j, a = 0, clen; - - BLI_array_fixedstack_declare(projverts, BM_DEFAULT_NGON_STACK_SIZE, f->len, "projvertsb"); - BLI_array_fixedstack_declare(edgeverts, BM_DEFAULT_NGON_STACK_SIZE * 2, len * 2, "edgevertsb"); i = 0; l = BM_iter_new(&iter, bm, BM_LOOPS_OF_FACE, f); @@ -1085,7 +1077,4 @@ void BM_face_legal_splits(BMesh *bm, BMFace *f, BMLoop *(*loops)[2], int len) } } } - - BLI_array_fixedstack_free(projverts); - BLI_array_fixedstack_free(edgeverts); } diff --git a/source/blender/bmesh/intern/bmesh_queries.c b/source/blender/bmesh/intern/bmesh_queries.c index 195c60c5a9c..633c715f257 100644 --- a/source/blender/bmesh/intern/bmesh_queries.c +++ b/source/blender/bmesh/intern/bmesh_queries.c @@ -1415,8 +1415,7 @@ int BM_face_exists_multi(BMVert **varr, BMEdge **earr, int len) /* same as 'BM_face_exists_multi' but built vert array from edges */ int BM_face_exists_multi_edge(BMEdge **earr, int len) { - BMVert **varr; - BLI_array_fixedstack_declare(varr, BM_DEFAULT_NGON_STACK_SIZE, len, __func__); + BMVert **varr = BLI_array_alloca(varr, len); int ok; int i, i_next; @@ -1432,14 +1431,11 @@ int BM_face_exists_multi_edge(BMEdge **earr, int len) if (ok == FALSE) { BMESH_ASSERT(0); - BLI_array_fixedstack_free(varr); return FALSE; } ok = BM_face_exists_multi(varr, earr, len); - BLI_array_fixedstack_free(varr); - return ok; } diff --git a/source/blender/bmesh/operators/bmo_extrude.c b/source/blender/bmesh/operators/bmo_extrude.c index 065a1b57737..bf3bafc57fb 100644 --- a/source/blender/bmesh/operators/bmo_extrude.c +++ b/source/blender/bmesh/operators/bmo_extrude.c @@ -600,39 +600,31 @@ static void solidify_add_thickness(BMesh *bm, const float dist) float *vert_accum = vert_angles + bm->totvert; int i, index; - /* array for passing verts to angle_poly_v3 */ - float **verts = NULL; - BLI_array_staticdeclare(verts, BM_DEFAULT_NGON_STACK_SIZE); - /* array for receiving angles from angle_poly_v3 */ - float *face_angles = NULL; - BLI_array_staticdeclare(face_angles, BM_DEFAULT_NGON_STACK_SIZE); - BM_mesh_elem_index_ensure(bm, BM_VERT); BM_ITER_MESH (f, &iter, bm, BM_FACES_OF_MESH) { - if (!BMO_elem_flag_test(bm, f, FACE_MARK)) { - continue; + if (BMO_elem_flag_test(bm, f, FACE_MARK)) { + + /* array for passing verts to angle_poly_v3 */ + float *face_angles = BLI_array_alloca(face_angles, f->len); + /* array for receiving angles from angle_poly_v3 */ + float **verts = BLI_array_alloca(verts, f->len); + + BM_ITER_ELEM_INDEX (l, &loopIter, f, BM_LOOPS_OF_FACE, i) { + verts[i] = l->v->co; + } + + angle_poly_v3(face_angles, (const float **)verts, f->len); + + i = 0; + BM_ITER_ELEM (l, &loopIter, f, BM_LOOPS_OF_FACE) { + v = l->v; + index = BM_elem_index_get(v); + vert_accum[index] += face_angles[i]; + vert_angles[index] += shell_angle_to_dist(angle_normalized_v3v3(v->no, f->no)) * face_angles[i]; + i++; + } } - - BLI_array_grow_items(verts, f->len); - BM_ITER_ELEM_INDEX (l, &loopIter, f, BM_LOOPS_OF_FACE, i) { - verts[i] = l->v->co; - } - - BLI_array_grow_items(face_angles, f->len); - angle_poly_v3(face_angles, (const float **)verts, f->len); - - i = 0; - BM_ITER_ELEM (l, &loopIter, f, BM_LOOPS_OF_FACE) { - v = l->v; - index = BM_elem_index_get(v); - vert_accum[index] += face_angles[i]; - vert_angles[index] += shell_angle_to_dist(angle_normalized_v3v3(v->no, f->no)) * face_angles[i]; - i++; - } - - BLI_array_empty(verts); - BLI_array_empty(face_angles); } BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) { @@ -643,9 +635,6 @@ static void solidify_add_thickness(BMesh *bm, const float dist) } MEM_freeN(vert_angles); - - BLI_array_free(verts); - BLI_array_free(face_angles); } void bmo_solidify_face_region_exec(BMesh *bm, BMOperator *op) diff --git a/source/blender/bmesh/tools/bmesh_bevel.c b/source/blender/bmesh/tools/bmesh_bevel.c index 9125800d3e8..fe9b0f21812 100644 --- a/source/blender/bmesh/tools/bmesh_bevel.c +++ b/source/blender/bmesh/tools/bmesh_bevel.c @@ -263,14 +263,12 @@ static BMFace *bev_create_ngon(BMesh *bm, BMVert **vert_arr, const int totv, BMF } else { int i; - BMEdge **ee = NULL; - BLI_array_fixedstack_declare(ee, BM_DEFAULT_NGON_STACK_SIZE, totv, __func__); + BMEdge **ee = BLI_array_alloca(ee, totv); for (i = 0; i < totv; i++) { ee[i] = BM_edge_create(bm, vert_arr[i], vert_arr[(i + 1) % totv], NULL, BM_CREATE_NO_DOUBLE); } f = BM_face_create_ngon(bm, vert_arr[0], vert_arr[1], ee, totv, 0); - BLI_array_fixedstack_free(ee); } if (facerep && f) { int has_mdisps = CustomData_has_layer(&bm->ldata, CD_MDISPS); diff --git a/source/blender/editors/mesh/editmesh_knife.c b/source/blender/editors/mesh/editmesh_knife.c index f18168a25bf..b7b71be0df9 100644 --- a/source/blender/editors/mesh/editmesh_knife.c +++ b/source/blender/editors/mesh/editmesh_knife.c @@ -2591,10 +2591,8 @@ static void knife_make_chain_cut(KnifeTool_OpData *kcd, BMFace *f, ListBase *cha BMLoop *lnew, *l_iter; int i; int nco = BLI_countlist(chain) - 1; - float (*cos)[3] = NULL; - KnifeVert **kverts; - BLI_array_fixedstack_declare(cos, BM_DEFAULT_NGON_STACK_SIZE, nco, __func__); - BLI_array_fixedstack_declare(kverts, BM_DEFAULT_NGON_STACK_SIZE, nco, __func__); + float (*cos)[3] = BLI_array_alloca(cos, nco); + KnifeVert **kverts = BLI_array_alloca(kverts, nco); kfe = ((Ref *)chain->first)->ref; v1 = kfe->v1->v ? kfe->v1->v : kfe->v2->v; @@ -2643,9 +2641,6 @@ static void knife_make_chain_cut(KnifeTool_OpData *kcd, BMFace *f, ListBase *cha BM_edge_select_set(bm, lnew->e, TRUE); } } - - BLI_array_fixedstack_free(cos); - BLI_array_fixedstack_free(kverts); } static void knife_make_face_cuts(KnifeTool_OpData *kcd, BMFace *f, ListBase *kfedges) diff --git a/source/blender/editors/uvedit/uvedit_unwrap_ops.c b/source/blender/editors/uvedit/uvedit_unwrap_ops.c index 6e6de03a834..b50b8d466f1 100644 --- a/source/blender/editors/uvedit/uvedit_unwrap_ops.c +++ b/source/blender/editors/uvedit/uvedit_unwrap_ops.c @@ -1413,8 +1413,7 @@ static void uv_map_mirror(BMEditMesh *em, BMFace *efa, MTexPoly *UNUSED(tf)) BMLoop *l; BMIter liter; MLoopUV *luv; - float **uvs = NULL; - BLI_array_fixedstack_declare(uvs, BM_DEFAULT_NGON_STACK_SIZE, efa->len, __func__); + float **uvs = BLI_array_alloca(uvs, efa->len); float dx; int i, mi; @@ -1436,8 +1435,6 @@ static void uv_map_mirror(BMEditMesh *em, BMFace *efa, MTexPoly *UNUSED(tf)) if (dx > 0.5f) uvs[i][0] += 1.0f; } } - - BLI_array_fixedstack_free(uvs); } static int sphere_project_exec(bContext *C, wmOperator *op) From 570cdb3b6e84b0f95d73d2154fcaf4ec27ea4dca Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 11 Dec 2012 15:14:35 +0000 Subject: [PATCH 027/252] image stamp data's strings could be short enough not to fit the entire ID name length. --- source/blender/blenkernel/intern/image.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/source/blender/blenkernel/intern/image.c b/source/blender/blenkernel/intern/image.c index f09f128e874..c4ce17c394a 100644 --- a/source/blender/blenkernel/intern/image.c +++ b/source/blender/blenkernel/intern/image.c @@ -1400,7 +1400,9 @@ static void timecode_simple_string(char *text, size_t text_size, const int cfra, } } -/* could allow access externally - 512 is for long names, 64 is for id names */ +#define STAMP_NAME_SIZE ((MAX_ID_NAME - 2) + 16) +/* could allow access externally - 512 is for long names, + * STAMP_NAME_SIZE is for id names, allowing them some room for description */ typedef struct StampData { char file[512]; char note[512]; @@ -1408,12 +1410,13 @@ typedef struct StampData { char marker[512]; char time[512]; char frame[512]; - char camera[64]; - char cameralens[64]; - char scene[64]; - char strip[64]; - char rendertime[64]; + char camera[STAMP_NAME_SIZE]; + char cameralens[STAMP_NAME_SIZE]; + char scene[STAMP_NAME_SIZE]; + char strip[STAMP_NAME_SIZE]; + char rendertime[STAMP_NAME_SIZE]; } StampData; +#undef STAMP_NAME_SIZE static void stampdata(Scene *scene, Object *camera, StampData *stamp_data, int do_prefix) { From 1eadcf743df76508864b3ab9d3e763b4e1e39119 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 11 Dec 2012 15:29:08 +0000 Subject: [PATCH 028/252] fix for building with msvc --- source/blender/blenlib/BLI_array.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/source/blender/blenlib/BLI_array.h b/source/blender/blenlib/BLI_array.h index 975476a669b..c1b77077a4d 100644 --- a/source/blender/blenlib/BLI_array.h +++ b/source/blender/blenlib/BLI_array.h @@ -199,6 +199,10 @@ /* alloca */ +#ifdef _MSC_VER +# define alloca _alloca +#endif + #if defined(__GNUC__) || defined(__clang__) #define BLI_array_alloca(arr, realsize) \ (typeof(arr))alloca(sizeof(*arr) * (realsize)) From 92ae023a90adcac43a8079978eded9e0ca26a1ae Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 11 Dec 2012 15:56:11 +0000 Subject: [PATCH 029/252] change to r52888, since we dont always want ED_view3d_offset_distance() to give a corrected value, instead pass a fallback so callers don't allow zero by accident. --- source/blender/editors/include/ED_view3d.h | 3 ++- .../editors/space_view3d/view3d_edit.c | 20 +++++++++++-------- .../editors/space_view3d/view3d_view.c | 4 ++-- 3 files changed, 16 insertions(+), 11 deletions(-) diff --git a/source/blender/editors/include/ED_view3d.h b/source/blender/editors/include/ED_view3d.h index d83835f8dc5..e3d14fb4aac 100644 --- a/source/blender/editors/include/ED_view3d.h +++ b/source/blender/editors/include/ED_view3d.h @@ -295,7 +295,8 @@ void ED_view3D_background_image_remove(struct View3D *v3d, struct BGpic *bgpic); void ED_view3D_background_image_clear(struct View3D *v3d); #define VIEW3D_MARGIN 1.4f -float ED_view3d_offset_distance(float mat[4][4], float ofs[3]); +#define VIEW3D_DIST_FALLBACK 1.0f +float ED_view3d_offset_distance(float mat[4][4], const float ofs[3], const float dist_fallback); float ED_scene_grid_scale(struct Scene *scene, const char **grid_unit); float ED_view3d_grid_scale(struct Scene *scene, struct View3D *v3d, const char **grid_unit); diff --git a/source/blender/editors/space_view3d/view3d_edit.c b/source/blender/editors/space_view3d/view3d_edit.c index d0783419fe8..3050b7efad2 100644 --- a/source/blender/editors/space_view3d/view3d_edit.c +++ b/source/blender/editors/space_view3d/view3d_edit.c @@ -96,7 +96,8 @@ int ED_view3d_camera_lock_check(View3D *v3d, RegionView3D *rv3d) void ED_view3d_camera_lock_init(View3D *v3d, RegionView3D *rv3d) { if (ED_view3d_camera_lock_check(v3d, rv3d)) { - rv3d->dist = ED_view3d_offset_distance(v3d->camera->obmat, rv3d->ofs); + /* using a fallback dist is OK here since ED_view3d_from_object() compensates for it */ + rv3d->dist = ED_view3d_offset_distance(v3d->camera->obmat, rv3d->ofs, VIEW3D_DIST_FALLBACK); ED_view3d_from_object(v3d->camera, rv3d->ofs, rv3d->viewquat, &rv3d->dist, NULL); } } @@ -895,7 +896,7 @@ static int viewrotate_invoke(bContext *C, wmOperator *op, wmEvent *event) /* changed since 2.4x, use the camera view */ if (vod->v3d->camera) { - rv3d->dist = ED_view3d_offset_distance(vod->v3d->camera->obmat, rv3d->ofs); + rv3d->dist = ED_view3d_offset_distance(vod->v3d->camera->obmat, rv3d->ofs, VIEW3D_DIST_FALLBACK); ED_view3d_from_object(vod->v3d->camera, rv3d->ofs, rv3d->viewquat, &rv3d->dist, NULL); } @@ -3977,7 +3978,11 @@ int ED_view3d_autodist_depth_seg(ARegion *ar, const int mval_sta[2], const int m return (*depth == FLT_MAX) ? 0 : 1; } -float ED_view3d_offset_distance(float mat[4][4], float ofs[3]) +/* problem - ofs[3] can be on same location as camera itself. + * Blender needs proper dist value for zoom. + * use fallback_dist to override small values + */ +float ED_view3d_offset_distance(float mat[4][4], const float ofs[3], const float fallback_dist) { float pos[4] = {0.0f, 0.0f, 0.0f, 1.0f}; float dir[4] = {0.0f, 0.0f, 1.0f, 0.0f}; @@ -3989,12 +3994,11 @@ float ED_view3d_offset_distance(float mat[4][4], float ofs[3]) normalize_v3(dir); dist = dot_v3v3(pos, dir); - - /* problem - ofs[3] can be on same location as camera itself. - Blender needs proper dist value for zoom */ - if (fabsf(dist) <= FLT_EPSILON) { - return 1.0f; + + if ((dist < FLT_EPSILON) && (fallback_dist != 0.0f)) { + dist = fallback_dist; } + return dist; } diff --git a/source/blender/editors/space_view3d/view3d_view.c b/source/blender/editors/space_view3d/view3d_view.c index 505b99dad01..5a7edfe4140 100644 --- a/source/blender/editors/space_view3d/view3d_view.c +++ b/source/blender/editors/space_view3d/view3d_view.c @@ -161,7 +161,7 @@ void view3d_smooth_view(bContext *C, View3D *v3d, ARegion *ar, Object *oldcamera if (lens) sms.new_lens = *lens; if (camera) { - sms.new_dist = ED_view3d_offset_distance(camera->obmat, ofs); + sms.new_dist = ED_view3d_offset_distance(camera->obmat, ofs, VIEW3D_DIST_FALLBACK); ED_view3d_from_object(camera, sms.new_ofs, sms.new_quat, &sms.new_dist, &sms.new_lens); sms.to_camera = TRUE; /* restore view3d values in end */ } @@ -186,7 +186,7 @@ void view3d_smooth_view(bContext *C, View3D *v3d, ARegion *ar, Object *oldcamera /* original values */ if (oldcamera) { - sms.orig_dist = ED_view3d_offset_distance(oldcamera->obmat, rv3d->ofs); + sms.orig_dist = ED_view3d_offset_distance(oldcamera->obmat, rv3d->ofs, 0.0f); ED_view3d_from_object(oldcamera, sms.orig_ofs, sms.orig_quat, &sms.orig_dist, &sms.orig_lens); } else { From 188718a3d57f3d869f228142ae30cce904e0e2e8 Mon Sep 17 00:00:00 2001 From: Thomas Dinges Date: Tue, 11 Dec 2012 16:06:03 +0000 Subject: [PATCH 030/252] OSL Shader Files: * Simplify default color values, where each component was the same. * Initialize closures as Null Closure, rather than assigning an existing closure, gets overwritten anyways. --- intern/cycles/kernel/shaders/node_add_closure.osl | 6 +++--- intern/cycles/kernel/shaders/node_ambient_occlusion.osl | 4 ++-- intern/cycles/kernel/shaders/node_attribute.osl | 2 +- intern/cycles/kernel/shaders/node_background.osl | 4 ++-- intern/cycles/kernel/shaders/node_brick_texture.osl | 8 ++++---- intern/cycles/kernel/shaders/node_brightness.osl | 4 ++-- intern/cycles/kernel/shaders/node_checker_texture.osl | 6 +++--- intern/cycles/kernel/shaders/node_combine_rgb.osl | 2 +- intern/cycles/kernel/shaders/node_convert_from_color.osl | 2 +- intern/cycles/kernel/shaders/node_convert_from_float.osl | 2 +- intern/cycles/kernel/shaders/node_convert_from_int.osl | 2 +- intern/cycles/kernel/shaders/node_convert_from_normal.osl | 2 +- intern/cycles/kernel/shaders/node_convert_from_point.osl | 2 +- intern/cycles/kernel/shaders/node_diffuse_bsdf.osl | 4 ++-- intern/cycles/kernel/shaders/node_emission.osl | 4 ++-- intern/cycles/kernel/shaders/node_environment_texture.osl | 2 +- intern/cycles/kernel/shaders/node_gamma.osl | 4 ++-- intern/cycles/kernel/shaders/node_glass_bsdf.osl | 4 ++-- intern/cycles/kernel/shaders/node_glossy_bsdf.osl | 4 ++-- intern/cycles/kernel/shaders/node_gradient_texture.osl | 2 +- intern/cycles/kernel/shaders/node_hsv.osl | 4 ++-- intern/cycles/kernel/shaders/node_image_texture.osl | 2 +- intern/cycles/kernel/shaders/node_invert.osl | 4 ++-- intern/cycles/kernel/shaders/node_magic_texture.osl | 2 +- intern/cycles/kernel/shaders/node_mix.osl | 6 +++--- intern/cycles/kernel/shaders/node_mix_closure.osl | 6 +++--- intern/cycles/kernel/shaders/node_musgrave_texture.osl | 2 +- intern/cycles/kernel/shaders/node_noise_texture.osl | 2 +- intern/cycles/kernel/shaders/node_output_surface.osl | 2 +- intern/cycles/kernel/shaders/node_output_volume.osl | 2 +- intern/cycles/kernel/shaders/node_refraction_bsdf.osl | 4 ++-- intern/cycles/kernel/shaders/node_rgb_curves.osl | 4 ++-- intern/cycles/kernel/shaders/node_rgb_ramp.osl | 2 +- intern/cycles/kernel/shaders/node_separate_rgb.osl | 2 +- intern/cycles/kernel/shaders/node_sky_texture.osl | 2 +- intern/cycles/kernel/shaders/node_translucent_bsdf.osl | 4 ++-- intern/cycles/kernel/shaders/node_transparent_bsdf.osl | 4 ++-- intern/cycles/kernel/shaders/node_value.osl | 4 ++-- intern/cycles/kernel/shaders/node_velvet_bsdf.osl | 4 ++-- intern/cycles/kernel/shaders/node_voronoi_texture.osl | 2 +- intern/cycles/kernel/shaders/node_ward_bsdf.osl | 4 ++-- intern/cycles/kernel/shaders/node_wave_texture.osl | 2 +- 42 files changed, 70 insertions(+), 70 deletions(-) diff --git a/intern/cycles/kernel/shaders/node_add_closure.osl b/intern/cycles/kernel/shaders/node_add_closure.osl index ecf6bf5912e..5c9ffecd1f1 100644 --- a/intern/cycles/kernel/shaders/node_add_closure.osl +++ b/intern/cycles/kernel/shaders/node_add_closure.osl @@ -19,9 +19,9 @@ #include "stdosl.h" shader node_add_closure( - closure color Closure1 = background(), - closure color Closure2 = background(), - output closure color Closure = background()) + closure color Closure1 = 0, + closure color Closure2 = 0, + output closure color Closure = 0) { Closure = Closure1 + Closure2; } diff --git a/intern/cycles/kernel/shaders/node_ambient_occlusion.osl b/intern/cycles/kernel/shaders/node_ambient_occlusion.osl index b9423344e73..58c44224e8d 100644 --- a/intern/cycles/kernel/shaders/node_ambient_occlusion.osl +++ b/intern/cycles/kernel/shaders/node_ambient_occlusion.osl @@ -20,8 +20,8 @@ shader node_ambient_occlusion( normal NormalIn = N, - color Color = color(0.8, 0.8, 0.8), - output closure color AO = ambient_occlusion()) + color Color = 0.8, + output closure color AO = 0) { AO = Color * ambient_occlusion(); } diff --git a/intern/cycles/kernel/shaders/node_attribute.osl b/intern/cycles/kernel/shaders/node_attribute.osl index 8e7c846d1a3..47404927779 100644 --- a/intern/cycles/kernel/shaders/node_attribute.osl +++ b/intern/cycles/kernel/shaders/node_attribute.osl @@ -22,7 +22,7 @@ shader node_attribute( string bump_offset = "center", string name = "", output point Vector = point(0.0, 0.0, 0.0), - output color Color = color(0.0, 0.0, 0.0), + output color Color = 0.0, output float Fac = 0.0) { getattribute(name, Color); diff --git a/intern/cycles/kernel/shaders/node_background.osl b/intern/cycles/kernel/shaders/node_background.osl index b51a1685294..b0c62c0381c 100644 --- a/intern/cycles/kernel/shaders/node_background.osl +++ b/intern/cycles/kernel/shaders/node_background.osl @@ -19,9 +19,9 @@ #include "stdosl.h" shader node_background( - color Color = color(0.8, 0.8, 0.8), + color Color = 0.8, float Strength = 1.0, - output closure color Background = background()) + output closure color Background = 0) { Background = Color * Strength * background(); } diff --git a/intern/cycles/kernel/shaders/node_brick_texture.osl b/intern/cycles/kernel/shaders/node_brick_texture.osl index b1f2a35789f..509b4f2883b 100644 --- a/intern/cycles/kernel/shaders/node_brick_texture.osl +++ b/intern/cycles/kernel/shaders/node_brick_texture.osl @@ -65,16 +65,16 @@ shader node_brick_texture( float Squash = 1.0, int SquashFrequency = 1, point Vector = P, - color Color1 = color(0.2, 0.2, 0.2), - color Color2 = color(0.8, 0.8, 0.8), - color Mortar = color(0.0, 0.0, 0.0), + color Color1 = 0.2, + color Color2 = 0.8, + color Mortar = 0.0, float Scale = 5.0, float MortarSize = 0.02, float Bias = 0.0, float BrickWidth = 0.5, float RowHeight = 0.25, output float Fac = 0.0, - output color Color = color(0.2, 0.2, 0.2)) + output color Color = 0.2) { point p = Vector; diff --git a/intern/cycles/kernel/shaders/node_brightness.osl b/intern/cycles/kernel/shaders/node_brightness.osl index b263d815566..2de3c94ecc1 100644 --- a/intern/cycles/kernel/shaders/node_brightness.osl +++ b/intern/cycles/kernel/shaders/node_brightness.osl @@ -19,10 +19,10 @@ #include "stdosl.h" shader node_brightness( - color ColorIn = color(0.8, 0.8, 0.8), + color ColorIn = 0.8, float Bright = 0.0, float Contrast = 0.0, - output color ColorOut = color(0.8, 0.8, 0.8)) + output color ColorOut = 0.8) { float a = 1.0 + Contrast; float b = Bright - Contrast*0.5; diff --git a/intern/cycles/kernel/shaders/node_checker_texture.osl b/intern/cycles/kernel/shaders/node_checker_texture.osl index eed56f4453a..84cfa8937a6 100644 --- a/intern/cycles/kernel/shaders/node_checker_texture.osl +++ b/intern/cycles/kernel/shaders/node_checker_texture.osl @@ -44,10 +44,10 @@ shader node_checker_texture( matrix mapping = matrix(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), float Scale = 5.0, point Vector = P, - color Color1 = color(0.8, 0.8, 0.8), - color Color2 = color(0.2, 0.2, 0.2), + color Color1 = 0.8, + color Color2 = 0.2, output float Fac = 0.0, - output color Color = color(0.0, 0.0, 0.0)) + output color Color = 0.0) { point p = Vector; diff --git a/intern/cycles/kernel/shaders/node_combine_rgb.osl b/intern/cycles/kernel/shaders/node_combine_rgb.osl index 546369f660e..1bdb4de9a5e 100644 --- a/intern/cycles/kernel/shaders/node_combine_rgb.osl +++ b/intern/cycles/kernel/shaders/node_combine_rgb.osl @@ -22,7 +22,7 @@ shader node_combine_rgb( float R = 0.0, float G = 0.0, float B = 0.0, - output color Image = color(0.8, 0.8, 0.8)) + output color Image = 0.8) { Image = color(R, G, B); } diff --git a/intern/cycles/kernel/shaders/node_convert_from_color.osl b/intern/cycles/kernel/shaders/node_convert_from_color.osl index ea488c9ce4c..6a6512e9f5b 100644 --- a/intern/cycles/kernel/shaders/node_convert_from_color.osl +++ b/intern/cycles/kernel/shaders/node_convert_from_color.osl @@ -19,7 +19,7 @@ #include "stdosl.h" shader node_convert_from_color( - color Color = color(0.0, 0.0, 0.0), + color Color = 0.0, output string String = "", output float Val = 0.0, output int ValInt = 0, diff --git a/intern/cycles/kernel/shaders/node_convert_from_float.osl b/intern/cycles/kernel/shaders/node_convert_from_float.osl index a20b491c91d..b6d5084a6dd 100644 --- a/intern/cycles/kernel/shaders/node_convert_from_float.osl +++ b/intern/cycles/kernel/shaders/node_convert_from_float.osl @@ -22,7 +22,7 @@ shader node_convert_from_float( float Val = 0.0, output string String = "", output int ValInt = 0, - output color Color = color(0.0, 0.0, 0.0), + output color Color = 0.0, output vector Vector = vector(0.0, 0.0, 0.0), output point Point = point(0.0, 0.0, 0.0), output normal Normal = normal(0.0, 0.0, 0.0)) diff --git a/intern/cycles/kernel/shaders/node_convert_from_int.osl b/intern/cycles/kernel/shaders/node_convert_from_int.osl index 911b4928db8..3d389cfa587 100644 --- a/intern/cycles/kernel/shaders/node_convert_from_int.osl +++ b/intern/cycles/kernel/shaders/node_convert_from_int.osl @@ -22,7 +22,7 @@ shader node_convert_from_int( int ValInt = 0, output string String = "", output float Val = 0.0, - output color Color = color(0.0, 0.0, 0.0), + output color Color = 0.0, output vector Vector = vector(0.0, 0.0, 0.0), output point Point = point(0.0, 0.0, 0.0), output normal Normal = normal(0.0, 0.0, 0.0)) diff --git a/intern/cycles/kernel/shaders/node_convert_from_normal.osl b/intern/cycles/kernel/shaders/node_convert_from_normal.osl index 1add7400a22..a4cb004f597 100644 --- a/intern/cycles/kernel/shaders/node_convert_from_normal.osl +++ b/intern/cycles/kernel/shaders/node_convert_from_normal.osl @@ -24,7 +24,7 @@ shader node_convert_from_normal( output float Val = 0.0, output int ValInt = 0, output vector Vector = vector(0.0, 0.0, 0.0), - output color Color = color(0.0, 0.0, 0.0), + output color Color = 0.0, output point Point = point(0.0, 0.0, 0.0)) { Val = (Normal[0] + Normal[1] + Normal[2]) * (1.0 / 3.0); diff --git a/intern/cycles/kernel/shaders/node_convert_from_point.osl b/intern/cycles/kernel/shaders/node_convert_from_point.osl index 8a315828c55..8ea7d380247 100644 --- a/intern/cycles/kernel/shaders/node_convert_from_point.osl +++ b/intern/cycles/kernel/shaders/node_convert_from_point.osl @@ -24,7 +24,7 @@ shader node_convert_from_point( output float Val = 0.0, output int ValInt = 0, output vector Vector = vector(0.0, 0.0, 0.0), - output color Color = color(0.0, 0.0, 0.0), + output color Color = 0.0, output normal Normal = normal(0.0, 0.0, 0.0)) { Val = (Point[0] + Point[1] + Point[2]) * (1.0 / 3.0); diff --git a/intern/cycles/kernel/shaders/node_diffuse_bsdf.osl b/intern/cycles/kernel/shaders/node_diffuse_bsdf.osl index d6dc17316e8..eae4772f173 100644 --- a/intern/cycles/kernel/shaders/node_diffuse_bsdf.osl +++ b/intern/cycles/kernel/shaders/node_diffuse_bsdf.osl @@ -19,10 +19,10 @@ #include "stdosl.h" shader node_diffuse_bsdf( - color Color = color(0.8, 0.8, 0.8), + color Color = 0.8, float Roughness = 0.0, normal Normal = N, - output closure color BSDF = diffuse(Normal)) + output closure color BSDF = 0) { if (Roughness == 0.0) BSDF = Color * diffuse(Normal); diff --git a/intern/cycles/kernel/shaders/node_emission.osl b/intern/cycles/kernel/shaders/node_emission.osl index 7ad0f9f7760..854d94c0f9d 100644 --- a/intern/cycles/kernel/shaders/node_emission.osl +++ b/intern/cycles/kernel/shaders/node_emission.osl @@ -20,9 +20,9 @@ shader node_emission( int TotalPower = 0, - color Color = color(0.8, 0.8, 0.8), + color Color = 0.8, float Strength = 1.0, - output closure color Emission = emission()) + output closure color Emission = 0) { if (TotalPower) Emission = ((Strength / surfacearea()) * Color) * emission(); diff --git a/intern/cycles/kernel/shaders/node_environment_texture.osl b/intern/cycles/kernel/shaders/node_environment_texture.osl index 7da336a53f0..33b30a27ee1 100644 --- a/intern/cycles/kernel/shaders/node_environment_texture.osl +++ b/intern/cycles/kernel/shaders/node_environment_texture.osl @@ -48,7 +48,7 @@ shader node_environment_texture( string filename = "", string projection = "Equirectangular", string color_space = "sRGB", - output color Color = color(0.0, 0.0, 0.0), + output color Color = 0.0, output float Alpha = 1.0) { vector p = Vector; diff --git a/intern/cycles/kernel/shaders/node_gamma.osl b/intern/cycles/kernel/shaders/node_gamma.osl index d55e908b0b7..5c913c29d5f 100644 --- a/intern/cycles/kernel/shaders/node_gamma.osl +++ b/intern/cycles/kernel/shaders/node_gamma.osl @@ -19,9 +19,9 @@ #include "stdosl.h" shader node_gamma( - color ColorIn = color(0.8, 0.8, 0.8), + color ColorIn = 0.8, float Gamma = 1.0, - output color ColorOut = color(0.0, 0.0, 0.0)) + output color ColorOut = 0.0) { ColorOut = pow(ColorIn, Gamma); } diff --git a/intern/cycles/kernel/shaders/node_glass_bsdf.osl b/intern/cycles/kernel/shaders/node_glass_bsdf.osl index 30b9d301f32..da1a42876fe 100644 --- a/intern/cycles/kernel/shaders/node_glass_bsdf.osl +++ b/intern/cycles/kernel/shaders/node_glass_bsdf.osl @@ -20,12 +20,12 @@ #include "node_fresnel.h" shader node_glass_bsdf( - color Color = color(0.8, 0.8, 0.8), + color Color = 0.8, string distribution = "Sharp", float Roughness = 0.2, float IOR = 1.45, normal Normal = N, - output closure color BSDF = diffuse(Normal)) + output closure color BSDF = 0) { float f = max(IOR, 1.0 + 1e-5); float eta = backfacing() ? 1.0 / f: f; diff --git a/intern/cycles/kernel/shaders/node_glossy_bsdf.osl b/intern/cycles/kernel/shaders/node_glossy_bsdf.osl index 03340c74af5..79bbe724acd 100644 --- a/intern/cycles/kernel/shaders/node_glossy_bsdf.osl +++ b/intern/cycles/kernel/shaders/node_glossy_bsdf.osl @@ -20,11 +20,11 @@ #include "node_fresnel.h" shader node_glossy_bsdf( - color Color = color(0.8, 0.8, 0.8), + color Color = 0.8, string distribution = "Beckmann", float Roughness = 0.2, normal Normal = N, - output closure color BSDF = diffuse(Normal)) + output closure color BSDF = 0) { if (distribution == "Sharp") BSDF = Color * reflection(Normal); diff --git a/intern/cycles/kernel/shaders/node_gradient_texture.osl b/intern/cycles/kernel/shaders/node_gradient_texture.osl index 8d862dbad67..9ae281ff623 100644 --- a/intern/cycles/kernel/shaders/node_gradient_texture.osl +++ b/intern/cycles/kernel/shaders/node_gradient_texture.osl @@ -68,7 +68,7 @@ shader node_gradient_texture( string Type = "Linear", point Vector = P, output float Fac = 0.0, - output color Color = color(0.0, 0.0, 0.0)) + output color Color = 0.0) { point p = Vector; diff --git a/intern/cycles/kernel/shaders/node_hsv.osl b/intern/cycles/kernel/shaders/node_hsv.osl index 0f4bedfb0f8..d5fdb1c616f 100644 --- a/intern/cycles/kernel/shaders/node_hsv.osl +++ b/intern/cycles/kernel/shaders/node_hsv.osl @@ -24,8 +24,8 @@ shader node_hsv( float Saturation = 1.0, float Value = 1.0, float Fac = 0.5, - color ColorIn = color(0.0, 0.0, 0.0), - output color ColorOut = color(0.0, 0.0, 0.0)) + color ColorIn = 0.0, + output color ColorOut = 0.0) { color Color = rgb_to_hsv(ColorIn); diff --git a/intern/cycles/kernel/shaders/node_image_texture.osl b/intern/cycles/kernel/shaders/node_image_texture.osl index 99074672a6a..c94a3f7e76a 100644 --- a/intern/cycles/kernel/shaders/node_image_texture.osl +++ b/intern/cycles/kernel/shaders/node_image_texture.osl @@ -37,7 +37,7 @@ shader node_image_texture( string color_space = "sRGB", string projection = "Flat", float projection_blend = 0.0, - output color Color = color(0.0, 0.0, 0.0), + output color Color = 0.0, output float Alpha = 1.0) { point p = Vector; diff --git a/intern/cycles/kernel/shaders/node_invert.osl b/intern/cycles/kernel/shaders/node_invert.osl index 27021942558..8711e2f120f 100644 --- a/intern/cycles/kernel/shaders/node_invert.osl +++ b/intern/cycles/kernel/shaders/node_invert.osl @@ -20,8 +20,8 @@ shader node_invert( float Fac = 1.0, - color ColorIn = color(0.8, 0.8, 0.8), - output color ColorOut = color(0.8, 0.8, 0.8)) + color ColorIn = 0.8, + output color ColorOut = 0.8) { color ColorInv = color(1.0) - ColorIn; ColorOut = mix(ColorIn, ColorInv, Fac); diff --git a/intern/cycles/kernel/shaders/node_magic_texture.osl b/intern/cycles/kernel/shaders/node_magic_texture.osl index b81a30499b2..943d9c6af68 100644 --- a/intern/cycles/kernel/shaders/node_magic_texture.osl +++ b/intern/cycles/kernel/shaders/node_magic_texture.osl @@ -99,7 +99,7 @@ shader node_magic_texture( float Distortion = 5.0, float Scale = 5.0, point Vector = P, - output color Color = color(0.0, 0.0, 0.0)) + output color Color = 0.0) { point p = Vector; diff --git a/intern/cycles/kernel/shaders/node_mix.osl b/intern/cycles/kernel/shaders/node_mix.osl index b2af36230f8..bcd00bb84e8 100644 --- a/intern/cycles/kernel/shaders/node_mix.osl +++ b/intern/cycles/kernel/shaders/node_mix.osl @@ -282,9 +282,9 @@ shader node_mix( string type = "Mix", int Clamp = 0, float Fac = 0.5, - color Color1 = color(0.0, 0.0, 0.0), - color Color2 = color(0.0, 0.0, 0.0), - output color Color = color(0.0, 0.0, 0.0)) + color Color1 = 0.0, + color Color2 = 0.0, + output color Color = 0.0) { float t = clamp(Fac, 0.0, 1.0); diff --git a/intern/cycles/kernel/shaders/node_mix_closure.osl b/intern/cycles/kernel/shaders/node_mix_closure.osl index e28dd1fc436..a0bef49b879 100644 --- a/intern/cycles/kernel/shaders/node_mix_closure.osl +++ b/intern/cycles/kernel/shaders/node_mix_closure.osl @@ -20,9 +20,9 @@ shader node_mix_closure( float Fac = 0.5, - closure color Closure1 = background(), - closure color Closure2 = background(), - output closure color Closure = background()) + closure color Closure1 = 0, + closure color Closure2 = 0, + output closure color Closure = 0) { float t = clamp(Fac, 0.0, 1.0); Closure = (1.0 - t) * Closure1 + t * Closure2; diff --git a/intern/cycles/kernel/shaders/node_musgrave_texture.osl b/intern/cycles/kernel/shaders/node_musgrave_texture.osl index afdbca27a3f..541f26b4e56 100644 --- a/intern/cycles/kernel/shaders/node_musgrave_texture.osl +++ b/intern/cycles/kernel/shaders/node_musgrave_texture.osl @@ -198,7 +198,7 @@ shader node_musgrave_texture( float Scale = 5.0, point Vector = P, output float Fac = 0.0, - output color Color = color(0.0, 0.0, 0.0)) + output color Color = 0.0) { float dimension = max(Dimension, 1e-5); float octaves = clamp(Detail, 0.0, 16.0); diff --git a/intern/cycles/kernel/shaders/node_noise_texture.osl b/intern/cycles/kernel/shaders/node_noise_texture.osl index 0a379491781..ec86a10b013 100644 --- a/intern/cycles/kernel/shaders/node_noise_texture.osl +++ b/intern/cycles/kernel/shaders/node_noise_texture.osl @@ -50,7 +50,7 @@ shader node_noise_texture( float Detail = 2.0, point Vector = P, output float Fac = 0.0, - output color Color = color(0.2, 0.2, 0.2)) + output color Color = 0.0) { point p = Vector; diff --git a/intern/cycles/kernel/shaders/node_output_surface.osl b/intern/cycles/kernel/shaders/node_output_surface.osl index 6efaf91121b..da6eedb9f98 100644 --- a/intern/cycles/kernel/shaders/node_output_surface.osl +++ b/intern/cycles/kernel/shaders/node_output_surface.osl @@ -18,7 +18,7 @@ #include "stdosl.h" -surface node_output_surface(closure color Surface = background()) +surface node_output_surface(closure color Surface = 0) { Ci = Surface; } diff --git a/intern/cycles/kernel/shaders/node_output_volume.osl b/intern/cycles/kernel/shaders/node_output_volume.osl index 18094242dc7..ec32ed3fcd2 100644 --- a/intern/cycles/kernel/shaders/node_output_volume.osl +++ b/intern/cycles/kernel/shaders/node_output_volume.osl @@ -18,7 +18,7 @@ #include "stdosl.h" -volume node_output_volume(closure color Volume = background()) +volume node_output_volume(closure color Volume = 0) { Ci = Volume; } diff --git a/intern/cycles/kernel/shaders/node_refraction_bsdf.osl b/intern/cycles/kernel/shaders/node_refraction_bsdf.osl index 0cf9d460c6e..d95a26cdff9 100644 --- a/intern/cycles/kernel/shaders/node_refraction_bsdf.osl +++ b/intern/cycles/kernel/shaders/node_refraction_bsdf.osl @@ -19,12 +19,12 @@ #include "stdosl.h" shader node_refraction_bsdf( - color Color = color(0.8, 0.8, 0.8), + color Color = 0.8, string distribution = "Sharp", float Roughness = 0.2, float IOR = 1.45, normal Normal = N, - output closure color BSDF = diffuse(Normal)) + output closure color BSDF = 0) { float f = max(IOR, 1.0 + 1e-5); float eta = backfacing() ? 1.0 / f: f; diff --git a/intern/cycles/kernel/shaders/node_rgb_curves.osl b/intern/cycles/kernel/shaders/node_rgb_curves.osl index baa1d5c3de4..362bae8a750 100644 --- a/intern/cycles/kernel/shaders/node_rgb_curves.osl +++ b/intern/cycles/kernel/shaders/node_rgb_curves.osl @@ -40,9 +40,9 @@ float ramp_lookup(color ramp[RAMP_TABLE_SIZE], float at, int component) shader node_rgb_curves( color ramp[RAMP_TABLE_SIZE] = {0.0}, - color ColorIn = color(0.0, 0.0, 0.0), + color ColorIn = 0.0, float Fac = 0.0, - output color ColorOut = color(0.0, 0.0, 0.0)) + output color ColorOut = 0.0) { ColorOut[0] = ramp_lookup(ramp, ColorIn[0], 0); ColorOut[1] = ramp_lookup(ramp, ColorIn[1], 1); diff --git a/intern/cycles/kernel/shaders/node_rgb_ramp.osl b/intern/cycles/kernel/shaders/node_rgb_ramp.osl index 0df11bb38de..bac4b9552e0 100644 --- a/intern/cycles/kernel/shaders/node_rgb_ramp.osl +++ b/intern/cycles/kernel/shaders/node_rgb_ramp.osl @@ -24,7 +24,7 @@ shader node_rgb_ramp( float ramp_alpha[RAMP_TABLE_SIZE] = {0.0}, float Fac = 0.0, - output color Color = color(0.0, 0.0, 0.0), + output color Color = 0.0, output float Alpha = 1.0) { float f = clamp(Fac, 0.0, 1.0) * (RAMP_TABLE_SIZE - 1); diff --git a/intern/cycles/kernel/shaders/node_separate_rgb.osl b/intern/cycles/kernel/shaders/node_separate_rgb.osl index b48bd7e59d6..0066a1daa91 100644 --- a/intern/cycles/kernel/shaders/node_separate_rgb.osl +++ b/intern/cycles/kernel/shaders/node_separate_rgb.osl @@ -19,7 +19,7 @@ #include "stdosl.h" shader node_separate_rgb( - color Image = color(0.8, 0.8, 0.8), + color Image = 0.8, output float R = 0.0, output float G = 0.0, output float B = 0.0) diff --git a/intern/cycles/kernel/shaders/node_sky_texture.osl b/intern/cycles/kernel/shaders/node_sky_texture.osl index 24a63c78458..13f958d65bd 100644 --- a/intern/cycles/kernel/shaders/node_sky_texture.osl +++ b/intern/cycles/kernel/shaders/node_sky_texture.osl @@ -154,7 +154,7 @@ shader node_sky_texture( vector Vector = P, vector sun_direction = vector(0, 0, 1), float turbidity = 2.2, - output color Color = color(0.0, 0.0, 0.0)) + output color Color = 0.0) { vector p = Vector; diff --git a/intern/cycles/kernel/shaders/node_translucent_bsdf.osl b/intern/cycles/kernel/shaders/node_translucent_bsdf.osl index e7efe73700c..c0a093b35d2 100644 --- a/intern/cycles/kernel/shaders/node_translucent_bsdf.osl +++ b/intern/cycles/kernel/shaders/node_translucent_bsdf.osl @@ -19,9 +19,9 @@ #include "stdosl.h" shader node_translucent_bsdf( - color Color = color(0.8, 0.8, 0.8), + color Color = 0.8, normal Normal = N, - output closure color BSDF = diffuse(Normal)) + output closure color BSDF = 0) { BSDF = Color * translucent(Normal); } diff --git a/intern/cycles/kernel/shaders/node_transparent_bsdf.osl b/intern/cycles/kernel/shaders/node_transparent_bsdf.osl index 875bce3f16c..976b7d5f756 100644 --- a/intern/cycles/kernel/shaders/node_transparent_bsdf.osl +++ b/intern/cycles/kernel/shaders/node_transparent_bsdf.osl @@ -19,9 +19,9 @@ #include "stdosl.h" shader node_transparent_bsdf( - color Color = color(0.8, 0.8, 0.8), + color Color = 0.8, normal Normal = N, - output closure color BSDF = diffuse(Normal)) + output closure color BSDF = 0) { BSDF = Color * transparent(); } diff --git a/intern/cycles/kernel/shaders/node_value.osl b/intern/cycles/kernel/shaders/node_value.osl index bee6f39f2bc..d3672b8c0cf 100644 --- a/intern/cycles/kernel/shaders/node_value.osl +++ b/intern/cycles/kernel/shaders/node_value.osl @@ -21,10 +21,10 @@ shader node_value( float value_value = 0.0, vector vector_value = vector(0.0, 0.0, 0.0), - color color_value = color(0.0, 0.0, 0.0), + color color_value = 0.0, output float Value = 0.0, output vector Vector = vector(0.0, 0.0, 0.0), - output color Color = color(0.0, 0.0, 0.0)) + output color Color = 0.0) { Value = value_value; Vector = vector_value; diff --git a/intern/cycles/kernel/shaders/node_velvet_bsdf.osl b/intern/cycles/kernel/shaders/node_velvet_bsdf.osl index 3aa662bdd08..5506ab20703 100644 --- a/intern/cycles/kernel/shaders/node_velvet_bsdf.osl +++ b/intern/cycles/kernel/shaders/node_velvet_bsdf.osl @@ -20,10 +20,10 @@ #include "node_fresnel.h" shader node_velvet_bsdf( - color Color = color(0.8, 0.8, 0.8), + color Color = 0.8, float Sigma = 0.0, normal Normal = N, - output closure color BSDF = diffuse(Normal)) + output closure color BSDF = 0) { float sigma = clamp(Sigma, 0.0, 1.0); diff --git a/intern/cycles/kernel/shaders/node_voronoi_texture.osl b/intern/cycles/kernel/shaders/node_voronoi_texture.osl index 43f8ecc666a..db8787892d2 100644 --- a/intern/cycles/kernel/shaders/node_voronoi_texture.osl +++ b/intern/cycles/kernel/shaders/node_voronoi_texture.osl @@ -28,7 +28,7 @@ shader node_voronoi_texture( float Scale = 5.0, point Vector = P, output float Fac = 0.0, - output color Color = color(0.0, 0.0, 0.0)) + output color Color = 0.0) { point p = Vector; diff --git a/intern/cycles/kernel/shaders/node_ward_bsdf.osl b/intern/cycles/kernel/shaders/node_ward_bsdf.osl index 82ce15ab9b6..bae55bcceaf 100644 --- a/intern/cycles/kernel/shaders/node_ward_bsdf.osl +++ b/intern/cycles/kernel/shaders/node_ward_bsdf.osl @@ -19,13 +19,13 @@ #include "stdosl.h" shader node_ward_bsdf( - color Color = color(0.8, 0.8, 0.8), + color Color = 0.0, float Roughness = 0.0, float Anisotropy = 0.0, float Rotation = 0.0, normal Normal = N, normal Tangent = normalize(dPdu), - output closure color BSDF = diffuse(Normal)) + output closure color BSDF = 0) { /* rotate tangent around normal */ vector T = Tangent; diff --git a/intern/cycles/kernel/shaders/node_wave_texture.osl b/intern/cycles/kernel/shaders/node_wave_texture.osl index 6648cd06278..11c4689196d 100644 --- a/intern/cycles/kernel/shaders/node_wave_texture.osl +++ b/intern/cycles/kernel/shaders/node_wave_texture.osl @@ -55,7 +55,7 @@ shader node_wave_texture( float DetailScale = 1.0, point Vector = P, output float Fac = 0.0, - output color Color = color (0.0, 0.0, 0.0)) + output color Color = 0.0) { point p = Vector; From 892d21631b46f9c34fe1648dec9c78bb18a58876 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Tue, 11 Dec 2012 19:45:16 +0000 Subject: [PATCH 031/252] Install dependencies used to always mark schro as used for suse. Now it should respect all features option. Also removed some duplicated entries. --- build_files/build_environment/install_deps.sh | 5 ----- 1 file changed, 5 deletions(-) diff --git a/build_files/build_environment/install_deps.sh b/build_files/build_environment/install_deps.sh index 24f0048e0eb..75b07ff73b3 100755 --- a/build_files/build_environment/install_deps.sh +++ b/build_files/build_environment/install_deps.sh @@ -1588,11 +1588,6 @@ install_SUSE() { INFO "" install_packages_SUSE $_packages - OPENJPEG_USE=true - SCHRO_USE=true - VORBIS_USE=true - THEORA_USE=true - INFO "" X264_DEV="x264-devel" check_package_version_ge_SUSE $X264_DEV $X264_VERSION_MIN From b5ce1b1a23a3befbcc4cd3c67a5ec6a76d77aa5a Mon Sep 17 00:00:00 2001 From: Daniel Genrich Date: Tue, 11 Dec 2012 20:39:54 +0000 Subject: [PATCH 032/252] Fix for cloth/smoke: Collision and flow objects always had to be on the same layer. Reported and patch by MiikaH --- source/blender/blenkernel/intern/collision.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/source/blender/blenkernel/intern/collision.c b/source/blender/blenkernel/intern/collision.c index 4641a02265a..f0043d9fa77 100644 --- a/source/blender/blenkernel/intern/collision.c +++ b/source/blender/blenkernel/intern/collision.c @@ -567,7 +567,9 @@ Object **get_collisionobjects(Scene *scene, Object *self, Group *group, unsigned Scene *sce_iter; /* add objects in same layer in scene */ for (SETLOOPER(scene, sce_iter, base)) { - if (base->lay & self->lay) + /* Need to check for active layers, too. + Otherwise this check fails if the objects are not on the same layer - DG */ + if ((base->lay & self->lay) || (base->lay & scene->lay)) add_collision_object(&objs, &numobj, &maxobj, base->object, self, 0, modifier_type); } From c40030a36ce61cd6d4158e129fe8e5a17ac33bc5 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 12 Dec 2012 02:48:03 +0000 Subject: [PATCH 033/252] replace BLI_array_declare with BLI_array_staticdeclare() and BLI_array_alloca() for smaller arrays. --- intern/cycles/kernel/shaders/node_mapping.osl | 3 +- source/blender/bmesh/intern/bmesh_core.c | 2 +- source/blender/bmesh/tools/bmesh_bevel.c | 6 +- source/blender/editors/uvedit/uvedit_draw.c | 86 ++++++------------- 4 files changed, 31 insertions(+), 66 deletions(-) diff --git a/intern/cycles/kernel/shaders/node_mapping.osl b/intern/cycles/kernel/shaders/node_mapping.osl index 92df043b39d..787f65217aa 100644 --- a/intern/cycles/kernel/shaders/node_mapping.osl +++ b/intern/cycles/kernel/shaders/node_mapping.osl @@ -28,9 +28,8 @@ shader node_mapping( { point p = transform(Matrix, VectorIn); - if(use_minmax) + if (use_minmax) p = min(max(mapping_min, p), mapping_max); VectorOut = p; } - diff --git a/source/blender/bmesh/intern/bmesh_core.c b/source/blender/bmesh/intern/bmesh_core.c index 4442b4eac9c..870d0f3d7dd 100644 --- a/source/blender/bmesh/intern/bmesh_core.c +++ b/source/blender/bmesh/intern/bmesh_core.c @@ -1879,7 +1879,7 @@ int BM_vert_splice(BMesh *bm, BMVert *v, BMVert *v_target) int bmesh_vert_separate(BMesh *bm, BMVert *v, BMVert ***r_vout, int *r_vout_len) { BMEdge **stack = NULL; - BLI_array_declare(stack); + BLI_array_staticdeclare(stack, BM_DEFAULT_ITER_STACK_SIZE); BMVert **verts = NULL; GHash *visithash; BMIter eiter, liter; diff --git a/source/blender/bmesh/tools/bmesh_bevel.c b/source/blender/bmesh/tools/bmesh_bevel.c index fe9b0f21812..e5a398ec66e 100644 --- a/source/blender/bmesh/tools/bmesh_bevel.c +++ b/source/blender/bmesh/tools/bmesh_bevel.c @@ -1135,7 +1135,7 @@ static void bevel_build_rings(BMesh *bm, BevVert *bv) /* Make center ngon if odd number of segments and fully beveled */ if (ns % 2 == 1 && vm->count == bv->selcount) { BMVert **vv = NULL; - BLI_array_declare(vv); + BLI_array_staticdeclare(vv, BM_DEFAULT_NGON_STACK_SIZE); v = vm->boundstart; do { @@ -1153,7 +1153,7 @@ static void bevel_build_rings(BMesh *bm, BevVert *bv) if (vm->count > bv->selcount) { int j; BMVert **vv = NULL; - BLI_array_declare(vv); + BLI_array_staticdeclare(vv, BM_DEFAULT_NGON_STACK_SIZE); v = vm->boundstart; f = boundvert_rep_face(v); @@ -1215,7 +1215,7 @@ static BMFace *bevel_build_poly_ex(BMesh *bm, BevVert *bv) VMesh *vm = bv->vmesh; BoundVert *v; BMVert **vv = NULL; - BLI_array_declare(vv); + BLI_array_staticdeclare(vv, BM_DEFAULT_NGON_STACK_SIZE); v = vm->boundstart; n = 0; diff --git a/source/blender/editors/uvedit/uvedit_draw.c b/source/blender/editors/uvedit/uvedit_draw.c index 9c2c300c530..c4267358d61 100644 --- a/source/blender/editors/uvedit/uvedit_draw.c +++ b/source/blender/editors/uvedit/uvedit_draw.c @@ -169,10 +169,8 @@ static void draw_uvs_stretch(SpaceImage *sima, Scene *scene, BMEditMesh *em, MTe MTexPoly *tf; MLoopUV *luv; Image *ima = sima->image; - BLI_array_declare(tf_uv); - BLI_array_declare(tf_uvorig); - float aspx, aspy, col[4], (*tf_uv)[2] = NULL, (*tf_uvorig)[2] = NULL; - int i, j, nverts; + float aspx, aspy, col[4]; + int i; ED_space_image_get_uv_aspect(sima, &aspx, &aspy); @@ -182,20 +180,14 @@ static void draw_uvs_stretch(SpaceImage *sima, Scene *scene, BMEditMesh *em, MTe float totarea = 0.0f, totuvarea = 0.0f, areadiff, uvarea, area; BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) { + const int efa_len = efa->len; + float (*tf_uv)[2] = BLI_array_alloca(tf_uv, efa_len); + float (*tf_uvorig)[2] = BLI_array_alloca(tf_uvorig, efa_len); tf = CustomData_bmesh_get(&bm->pdata, efa->head.data, CD_MTEXPOLY); - - BLI_array_empty(tf_uv); - BLI_array_empty(tf_uvorig); - BLI_array_grow_items(tf_uv, efa->len); - BLI_array_grow_items(tf_uvorig, efa->len); - i = 0; - BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { + BM_ITER_ELEM_INDEX (l, &liter, efa, BM_LOOPS_OF_FACE, i) { luv = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_MLOOPUV); - copy_v2_v2(tf_uvorig[i], luv->uv); - - i++; } uv_poly_copy_aspect(tf_uvorig, tf_uv, aspx, aspy, efa->len); @@ -232,20 +224,15 @@ static void draw_uvs_stretch(SpaceImage *sima, Scene *scene, BMEditMesh *em, MTe else { BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) { if (BM_elem_flag_test(efa, BM_ELEM_TAG)) { + const int efa_len = efa->len; + float (*tf_uv)[2] = BLI_array_alloca(tf_uv, efa_len); + float (*tf_uvorig)[2] = BLI_array_alloca(tf_uvorig, efa_len); + area = BM_face_calc_area(efa) / totarea; - BLI_array_empty(tf_uv); - BLI_array_empty(tf_uvorig); - BLI_array_grow_items(tf_uv, efa->len); - BLI_array_grow_items(tf_uvorig, efa->len); - - i = 0; - BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { + BM_ITER_ELEM_INDEX (l, &liter, efa, BM_LOOPS_OF_FACE, i) { luv = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_MLOOPUV); - copy_v2_v2(tf_uvorig[i], luv->uv); - - i++; } uv_poly_copy_aspect(tf_uvorig, tf_uv, aspx, aspy, efa->len); @@ -276,18 +263,9 @@ static void draw_uvs_stretch(SpaceImage *sima, Scene *scene, BMEditMesh *em, MTe } case SI_UVDT_STRETCH_ANGLE: { - float *uvang = NULL; - float *ang = NULL; - float (*av)[3] = NULL; /* use for 2d and 3d angle vectors */ - float (*auv)[2] = NULL; float a; - BLI_array_declare(uvang); - BLI_array_declare(ang); - BLI_array_declare(av); - BLI_array_declare(auv); - - col[3] = 0.5; /* hard coded alpha, not that nice */ + col[3] = 0.5f; /* hard coded alpha, not that nice */ glShadeModel(GL_SMOOTH); @@ -295,44 +273,40 @@ static void draw_uvs_stretch(SpaceImage *sima, Scene *scene, BMEditMesh *em, MTe tf = CustomData_bmesh_get(&bm->pdata, efa->head.data, CD_MTEXPOLY); if (uvedit_face_visible_test(scene, ima, efa, tf)) { - nverts = efa->len; + const int efa_len = efa->len; + float (*tf_uv)[2] = BLI_array_alloca(tf_uv, efa_len); + float (*tf_uvorig)[2] = BLI_array_alloca(tf_uvorig, efa_len); + float *uvang = BLI_array_alloca(uvang, efa_len); + float *ang = BLI_array_alloca(ang, efa_len); + float (*av)[3] = BLI_array_alloca(av, efa_len); /* use for 2d and 3d angle vectors */ + float (*auv)[2] = BLI_array_alloca(auv, efa_len); + int j; + BM_elem_flag_enable(efa, BM_ELEM_TAG); - BLI_array_empty(tf_uv); - BLI_array_empty(tf_uvorig); - BLI_array_empty(uvang); - BLI_array_empty(ang); - BLI_array_empty(av); - BLI_array_empty(auv); - BLI_array_grow_items(tf_uv, nverts); - BLI_array_grow_items(tf_uvorig, nverts); - BLI_array_grow_items(uvang, nverts); - BLI_array_grow_items(ang, nverts); - BLI_array_grow_items(av, nverts); - BLI_array_grow_items(auv, nverts); BM_ITER_ELEM_INDEX (l, &liter, efa, BM_LOOPS_OF_FACE, i) { luv = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_MLOOPUV); copy_v2_v2(tf_uvorig[i], luv->uv); } - uv_poly_copy_aspect(tf_uvorig, tf_uv, aspx, aspy, nverts); + uv_poly_copy_aspect(tf_uvorig, tf_uv, aspx, aspy, efa_len); - j = nverts - 1; + j = efa_len - 1; BM_ITER_ELEM_INDEX (l, &liter, efa, BM_LOOPS_OF_FACE, i) { sub_v2_v2v2(auv[i], tf_uv[j], tf_uv[i]); normalize_v2(auv[i]); sub_v3_v3v3(av[i], l->prev->v->co, l->v->co); normalize_v3(av[i]); j = i; } - for (i = 0; i < nverts; i++) { + for (i = 0; i < efa_len; i++) { #if 0 /* Simple but slow, better reuse normalized vectors * (Not ported to bmesh, copied for reference) */ uvang1 = RAD2DEG(angle_v2v2v2(tf_uv[3], tf_uv[0], tf_uv[1])); ang1 = RAD2DEG(angle_v3v3v3(efa->v4->co, efa->v1->co, efa->v2->co)); #endif - uvang[i] = angle_normalized_v2v2(auv[i], auv[(i + 1) % nverts]); - ang[i] = angle_normalized_v3v3(av[i], av[(i + 1) % nverts]); + uvang[i] = angle_normalized_v2v2(auv[i], auv[(i + 1) % efa_len]); + ang[i] = angle_normalized_v3v3(av[i], av[(i + 1) % efa_len]); } glBegin(GL_POLYGON); @@ -354,17 +328,9 @@ static void draw_uvs_stretch(SpaceImage *sima, Scene *scene, BMEditMesh *em, MTe glShadeModel(GL_FLAT); - BLI_array_free(uvang); - BLI_array_free(ang); - BLI_array_free(av); - BLI_array_free(auv); - break; } } - - BLI_array_free(tf_uv); - BLI_array_free(tf_uvorig); } static void draw_uvs_other(Scene *scene, Object *obedit, Image *curimage) From 21a2660290fd74da5adea6df944922180ffe6c91 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 12 Dec 2012 04:41:23 +0000 Subject: [PATCH 034/252] assert in debug builds if MEM_ alloc's are called in openmp threads. note: the caller can do locking to prevent errors - but this isn't being done in blender yet, so this prevents accidental allocs in openmp for now. --- intern/guardedalloc/intern/mallocn.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/intern/guardedalloc/intern/mallocn.c b/intern/guardedalloc/intern/mallocn.c index 4a79f5d0de1..59e780f21e5 100644 --- a/intern/guardedalloc/intern/mallocn.c +++ b/intern/guardedalloc/intern/mallocn.c @@ -110,6 +110,15 @@ typedef struct MemHead { #endif } MemHead; +/* for openmp threading asserts, saves time troubleshooting + * we may need to extend this if blender code starts using MEM_ + * functions inside OpenMP correctly with omp_set_lock() */ +#if defined(_OPENMP) && defined(DEBUG) +# include +# include +# define DEBUG_OMP_MALLOC +#endif + typedef struct MemTail { int tag3, pad; } MemTail; @@ -194,6 +203,10 @@ static void print_error(const char *str, ...) static void mem_lock_thread(void) { +#ifdef DEBUG_OMP_MALLOC + assert(omp_in_parallel() == 0); +#endif + if (thread_lock_callback) thread_lock_callback(); } @@ -214,8 +227,7 @@ int MEM_check_memory_integrity(void) err_val = check_memlist(listend); - if (err_val == NULL) return 0; - return 1; + return (err_val != NULL); } From 3d69dbd44a8c14c54785833fc469ee14173c6132 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 12 Dec 2012 05:04:01 +0000 Subject: [PATCH 035/252] use openmp to thread some common bmesh operations - BM_mesh_elem_toolflags_ensure / bmo_flag_layer_alloc / bmo_flag_layer_free / bmo_flag_layer_clear - BM_mesh_select_flush - EDBM_index_arrays_init notes: - mostly use openmp `sections` to split operations on vert/edge/face since this is a fairly minor change. - split tool flag pool in 3, this means we can allocate exact sizes needed and iterate on them in threads without alloc'ing. --- source/blender/bmesh/bmesh_class.h | 5 +- source/blender/bmesh/intern/bmesh_core.c | 32 +-- source/blender/bmesh/intern/bmesh_marking.c | 133 ++++++---- source/blender/bmesh/intern/bmesh_mesh.c | 156 +++++++----- source/blender/bmesh/intern/bmesh_operators.c | 231 ++++++++++++------ source/blender/editors/mesh/editmesh_utils.c | 52 ++-- .../blender/modifiers/intern/MOD_decimate.c | 4 +- 7 files changed, 373 insertions(+), 240 deletions(-) diff --git a/source/blender/bmesh/bmesh_class.h b/source/blender/bmesh/bmesh_class.h index 9d797c1e602..4a370a24c7d 100644 --- a/source/blender/bmesh/bmesh_class.h +++ b/source/blender/bmesh/bmesh_class.h @@ -187,8 +187,9 @@ typedef struct BMesh { /*element pools*/ struct BLI_mempool *vpool, *epool, *lpool, *fpool; - /*operator api stuff*/ - struct BLI_mempool *toolflagpool; + /*operator api stuff (must be all NULL or all alloc'd)*/ + struct BLI_mempool *vtoolflagpool, *etoolflagpool, *ftoolflagpool; + int stackdepth; struct BMOperator *currentop; diff --git a/source/blender/bmesh/intern/bmesh_core.c b/source/blender/bmesh/intern/bmesh_core.c index 870d0f3d7dd..ea9ab364b84 100644 --- a/source/blender/bmesh/intern/bmesh_core.c +++ b/source/blender/bmesh/intern/bmesh_core.c @@ -79,8 +79,8 @@ BMVert *BM_vert_create(BMesh *bm, const float co[3], const BMVert *example, cons } /* allocate flags */ - if (bm->toolflagpool) { - v->oflags = BLI_mempool_calloc(bm->toolflagpool); + if (bm->vtoolflagpool) { + v->oflags = BLI_mempool_calloc(bm->vtoolflagpool); } if (!(create_flag & BM_CREATE_SKIP_CD)) { @@ -133,8 +133,8 @@ BMEdge *BM_edge_create(BMesh *bm, BMVert *v1, BMVert *v2, const BMEdge *example, e->head.htype = BM_EDGE; /* allocate flags */ - if (bm->toolflagpool) { - e->oflags = BLI_mempool_calloc(bm->toolflagpool); + if (bm->etoolflagpool) { + e->oflags = BLI_mempool_calloc(bm->etoolflagpool); } e->v1 = v1; @@ -291,8 +291,8 @@ BLI_INLINE BMFace *bm_face_create__internal(BMesh *bm, const eBMCreateFlag creat f->head.htype = BM_FACE; /* allocate flags */ - if (bm->toolflagpool) { - f->oflags = BLI_mempool_calloc(bm->toolflagpool); + if (bm->ftoolflagpool) { + f->oflags = BLI_mempool_calloc(bm->ftoolflagpool); } if (!(create_flag & BM_CREATE_SKIP_CD)) { @@ -512,8 +512,8 @@ static void bm_kill_only_vert(BMesh *bm, BMVert *v) if (v->head.data) CustomData_bmesh_free_block(&bm->vdata, &v->head.data); - if (bm->toolflagpool) { - BLI_mempool_free(bm->toolflagpool, v->oflags); + if (bm->vtoolflagpool) { + BLI_mempool_free(bm->vtoolflagpool, v->oflags); } BLI_mempool_free(bm->vpool, v); } @@ -532,8 +532,8 @@ static void bm_kill_only_edge(BMesh *bm, BMEdge *e) if (e->head.data) CustomData_bmesh_free_block(&bm->edata, &e->head.data); - if (bm->toolflagpool) { - BLI_mempool_free(bm->toolflagpool, e->oflags); + if (bm->etoolflagpool) { + BLI_mempool_free(bm->etoolflagpool, e->oflags); } BLI_mempool_free(bm->epool, e); } @@ -555,8 +555,8 @@ static void bm_kill_only_face(BMesh *bm, BMFace *f) if (f->head.data) CustomData_bmesh_free_block(&bm->pdata, &f->head.data); - if (bm->toolflagpool) { - BLI_mempool_free(bm->toolflagpool, f->oflags); + if (bm->ftoolflagpool) { + BLI_mempool_free(bm->ftoolflagpool, f->oflags); } BLI_mempool_free(bm->fpool, f); } @@ -1785,8 +1785,8 @@ BMFace *bmesh_jfke(BMesh *bm, BMFace *f1, BMFace *f2, BMEdge *e) bmesh_disk_edge_remove(f1loop->e, f1loop->e->v2); /* deallocate edge and its two loops as well as f2 */ - if (bm->toolflagpool) { - BLI_mempool_free(bm->toolflagpool, f1loop->e->oflags); + if (bm->etoolflagpool) { + BLI_mempool_free(bm->etoolflagpool, f1loop->e->oflags); } BLI_mempool_free(bm->epool, f1loop->e); bm->totedge--; @@ -1794,8 +1794,8 @@ BMFace *bmesh_jfke(BMesh *bm, BMFace *f1, BMFace *f2, BMEdge *e) bm->totloop--; BLI_mempool_free(bm->lpool, f2loop); bm->totloop--; - if (bm->toolflagpool) { - BLI_mempool_free(bm->toolflagpool, f2->oflags); + if (bm->ftoolflagpool) { + BLI_mempool_free(bm->ftoolflagpool, f2->oflags); } BLI_mempool_free(bm->fpool, f2); bm->totface--; diff --git a/source/blender/bmesh/intern/bmesh_marking.c b/source/blender/bmesh/intern/bmesh_marking.c index 9af65d7dd7e..6093547150c 100644 --- a/source/blender/bmesh/intern/bmesh_marking.c +++ b/source/blender/bmesh/intern/bmesh_marking.c @@ -44,8 +44,6 @@ static void recount_totsels(BMesh *bm) { - BMIter iter; - BMElem *ele; const char iter_types[3] = {BM_VERTS_OF_MESH, BM_EDGES_OF_MESH, BM_FACES_OF_MESH}; @@ -58,11 +56,16 @@ static void recount_totsels(BMesh *bm) tots[1] = &bm->totedgesel; tots[2] = &bm->totfacesel; +#pragma omp parallel for schedule(dynamic) for (i = 0; i < 3; i++) { - ele = BM_iter_new(&iter, bm, iter_types[i], NULL); - for ( ; ele; ele = BM_iter_step(&iter)) { - if (BM_elem_flag_test(ele, BM_ELEM_SELECT)) *tots[i] += 1; + BMIter iter; + BMElem *ele; + int count = 0; + + BM_ITER_MESH (ele, &iter, bm, iter_types[i]) { + if (BM_elem_flag_test(ele, BM_ELEM_SELECT)) count += 1; } + *tots[i] = count; } } @@ -161,34 +164,45 @@ void BM_mesh_deselect_flush(BMesh *bm) int ok; - BM_ITER_MESH (e, &eiter, bm, BM_EDGES_OF_MESH) { - if (!(BM_elem_flag_test(e->v1, BM_ELEM_SELECT) && - BM_elem_flag_test(e->v2, BM_ELEM_SELECT) && - !BM_elem_flag_test(e, BM_ELEM_HIDDEN))) + /* we can use 2 sections here because the second loop isnt checking edge selection */ +#pragma omp parallel sections + { +#pragma omp section { - BM_elem_flag_disable(e, BM_ELEM_SELECT); - } - } - - BM_ITER_MESH (f, &fiter, bm, BM_FACES_OF_MESH) { - ok = TRUE; - if (!BM_elem_flag_test(f, BM_ELEM_HIDDEN)) { - l_iter = l_first = BM_FACE_FIRST_LOOP(f); - do { - if (!BM_elem_flag_test(l_iter->v, BM_ELEM_SELECT)) { - ok = FALSE; - break; + BM_ITER_MESH (e, &eiter, bm, BM_EDGES_OF_MESH) { + if (!(BM_elem_flag_test(e->v1, BM_ELEM_SELECT) && + BM_elem_flag_test(e->v2, BM_ELEM_SELECT) && + !BM_elem_flag_test(e, BM_ELEM_HIDDEN))) + { + BM_elem_flag_disable(e, BM_ELEM_SELECT); } - } while ((l_iter = l_iter->next) != l_first); - } - else { - ok = FALSE; + } } - if (ok == FALSE) { - BM_elem_flag_disable(f, BM_ELEM_SELECT); +#pragma omp section + { + BM_ITER_MESH (f, &fiter, bm, BM_FACES_OF_MESH) { + ok = TRUE; + if (!BM_elem_flag_test(f, BM_ELEM_HIDDEN)) { + l_iter = l_first = BM_FACE_FIRST_LOOP(f); + do { + if (!BM_elem_flag_test(l_iter->v, BM_ELEM_SELECT)) { + ok = FALSE; + break; + } + } while ((l_iter = l_iter->next) != l_first); + } + else { + ok = FALSE; + } + + if (ok == FALSE) { + BM_elem_flag_disable(f, BM_ELEM_SELECT); + } + } } } + /* end sections */ /* Remove any deselected elements from the BMEditSelection */ BM_select_history_validate(bm); @@ -212,32 +226,42 @@ void BM_mesh_select_flush(BMesh *bm) int ok; - BM_ITER_MESH (e, &eiter, bm, BM_EDGES_OF_MESH) { - if (BM_elem_flag_test(e->v1, BM_ELEM_SELECT) && - BM_elem_flag_test(e->v2, BM_ELEM_SELECT) && - !BM_elem_flag_test(e, BM_ELEM_HIDDEN)) + /* we can use 2 sections here because the second loop isnt checking edge selection */ +#pragma omp parallel sections + { +#pragma omp section { - BM_elem_flag_enable(e, BM_ELEM_SELECT); - } - } - - BM_ITER_MESH (f, &fiter, bm, BM_FACES_OF_MESH) { - ok = TRUE; - if (!BM_elem_flag_test(f, BM_ELEM_HIDDEN)) { - l_iter = l_first = BM_FACE_FIRST_LOOP(f); - do { - if (!BM_elem_flag_test(l_iter->v, BM_ELEM_SELECT)) { - ok = FALSE; - break; + BM_ITER_MESH (e, &eiter, bm, BM_EDGES_OF_MESH) { + if (BM_elem_flag_test(e->v1, BM_ELEM_SELECT) && + BM_elem_flag_test(e->v2, BM_ELEM_SELECT) && + !BM_elem_flag_test(e, BM_ELEM_HIDDEN)) + { + BM_elem_flag_enable(e, BM_ELEM_SELECT); } - } while ((l_iter = l_iter->next) != l_first); - } - else { - ok = FALSE; + } } - if (ok) { - BM_elem_flag_enable(f, BM_ELEM_SELECT); +#pragma omp section + { + BM_ITER_MESH (f, &fiter, bm, BM_FACES_OF_MESH) { + ok = TRUE; + if (!BM_elem_flag_test(f, BM_ELEM_HIDDEN)) { + l_iter = l_first = BM_FACE_FIRST_LOOP(f); + do { + if (!BM_elem_flag_test(l_iter->v, BM_ELEM_SELECT)) { + ok = FALSE; + break; + } + } while ((l_iter = l_iter->next) != l_first); + } + else { + ok = FALSE; + } + + if (ok) { + BM_elem_flag_enable(f, BM_ELEM_SELECT); + } + } } } @@ -810,8 +834,6 @@ void BM_mesh_elem_hflag_disable_test(BMesh *bm, const char htype, const char hfl const char flag_types[3] = {BM_VERT, BM_EDGE, BM_FACE}; - BMIter iter; - BMElem *ele; int i; if (hflag & BM_ELEM_SELECT) { @@ -825,16 +847,25 @@ void BM_mesh_elem_hflag_disable_test(BMesh *bm, const char htype, const char hfl { /* fast path for deselect all, avoid topology loops * since we know all will be de-selected anyway. */ + +#pragma omp parallel for schedule(dynamic) for (i = 0; i < 3; i++) { + BMIter iter; + BMElem *ele; + ele = BM_iter_new(&iter, bm, iter_types[i], NULL); for ( ; ele; ele = BM_iter_step(&iter)) { BM_elem_flag_disable(ele, BM_ELEM_SELECT); } } + bm->totvertsel = bm->totedgesel = bm->totfacesel = 0; } else { for (i = 0; i < 3; i++) { + BMIter iter; + BMElem *ele; + if (htype & flag_types[i]) { ele = BM_iter_new(&iter, bm, iter_types[i], NULL); for ( ; ele; ele = BM_iter_step(&iter)) { diff --git a/source/blender/bmesh/intern/bmesh_mesh.c b/source/blender/bmesh/intern/bmesh_mesh.c index 590edc45d07..8d5bf46a6e5 100644 --- a/source/blender/bmesh/intern/bmesh_mesh.c +++ b/source/blender/bmesh/intern/bmesh_mesh.c @@ -63,40 +63,62 @@ static void bm_mempool_init(BMesh *bm, const BMAllocTemplate *allocsize) void BM_mesh_elem_toolflags_ensure(BMesh *bm) { - if (bm->toolflagpool == NULL) { - const int totflagpool_size = max_ii(512, bm->totvert + bm->totedge + bm->totface); - BLI_mempool *toolflagpool; + if (bm->vtoolflagpool && bm->etoolflagpool && bm->ftoolflagpool) { + return; + } - BMIter iter; - BMElemF *ele; - const char iter_types[3] = {BM_VERTS_OF_MESH, - BM_EDGES_OF_MESH, - BM_FACES_OF_MESH}; + bm->vtoolflagpool = BLI_mempool_create(sizeof(BMFlagLayer), max_ii(512, bm->totvert), 512, 0); + bm->etoolflagpool = BLI_mempool_create(sizeof(BMFlagLayer), max_ii(512, bm->totedge), 512, 0); + bm->ftoolflagpool = BLI_mempool_create(sizeof(BMFlagLayer), max_ii(512, bm->totface), 512, 0); - int i; - - BLI_assert(bm->totflags == 0); - - /* allocate one flag pool that we don't get rid of. */ - toolflagpool = BLI_mempool_create(sizeof(BMFlagLayer), totflagpool_size, 512, 0); - - - for (i = 0; i < 3; i++) { - BM_ITER_MESH (ele, &iter, bm, iter_types[i]) { +#pragma omp parallel sections + { +#pragma omp section + { + BLI_mempool *toolflagpool = bm->vtoolflagpool; + BMIter iter; + BMElemF *ele; + BM_ITER_MESH (ele, &iter, bm, BM_VERTS_OF_MESH) { + ele->oflags = BLI_mempool_calloc(toolflagpool); + } + } +#pragma omp section + { + BLI_mempool *toolflagpool = bm->etoolflagpool; + BMIter iter; + BMElemF *ele; + BM_ITER_MESH (ele, &iter, bm, BM_EDGES_OF_MESH) { + ele->oflags = BLI_mempool_calloc(toolflagpool); + } + } +#pragma omp section + { + BLI_mempool *toolflagpool = bm->ftoolflagpool; + BMIter iter; + BMElemF *ele; + BM_ITER_MESH (ele, &iter, bm, BM_FACES_OF_MESH) { ele->oflags = BLI_mempool_calloc(toolflagpool); } } - - bm->toolflagpool = toolflagpool; - bm->totflags = 1; } + + + bm->totflags = 1; } void BM_mesh_elem_toolflags_clear(BMesh *bm) { - if (bm->toolflagpool) { - BLI_mempool_destroy(bm->toolflagpool); - bm->toolflagpool = NULL; + if (bm->vtoolflagpool) { + BLI_mempool_destroy(bm->vtoolflagpool); + bm->vtoolflagpool = NULL; + } + if (bm->etoolflagpool) { + BLI_mempool_destroy(bm->etoolflagpool); + bm->etoolflagpool = NULL; + } + if (bm->ftoolflagpool) { + BLI_mempool_destroy(bm->ftoolflagpool); + bm->ftoolflagpool = NULL; } } @@ -446,50 +468,58 @@ void BM_mesh_elem_index_ensure(BMesh *bm, const char hflag) BM_ELEM_INDEX_VALIDATE(bm, "Should Never Fail!", __func__); #endif - if (hflag & BM_VERT) { - if (bm->elem_index_dirty & BM_VERT) { - int index = 0; - BM_ITER_MESH (ele, &iter, bm, BM_VERTS_OF_MESH) { - BM_elem_index_set(ele, index); /* set_ok */ - index++; +#pragma omp parallel sections + { +#pragma omp section + { + if (hflag & BM_VERT) { + if (bm->elem_index_dirty & BM_VERT) { + int index; + BM_ITER_MESH_INDEX (ele, &iter, bm, BM_VERTS_OF_MESH, index) { + BM_elem_index_set(ele, index); /* set_ok */ + } + BLI_assert(index == bm->totvert); + } + else { + // printf("%s: skipping vert index calc!\n", __func__); + } } - bm->elem_index_dirty &= ~BM_VERT; - BLI_assert(index == bm->totvert); } - else { - // printf("%s: skipping vert index calc!\n", __func__); + +#pragma omp section + { + if (hflag & BM_EDGE) { + if (bm->elem_index_dirty & BM_EDGE) { + int index; + BM_ITER_MESH_INDEX (ele, &iter, bm, BM_EDGES_OF_MESH, index) { + BM_elem_index_set(ele, index); /* set_ok */ + } + BLI_assert(index == bm->totedge); + } + else { + // printf("%s: skipping edge index calc!\n", __func__); + } + } + } + +#pragma omp section + { + if (hflag & BM_FACE) { + if (bm->elem_index_dirty & BM_FACE) { + int index; + BM_ITER_MESH_INDEX (ele, &iter, bm, BM_FACES_OF_MESH, index) { + BM_elem_index_set(ele, index); /* set_ok */ + } + BLI_assert(index == bm->totface); + } + else { + // printf("%s: skipping face index calc!\n", __func__); + } + } } } - if (hflag & BM_EDGE) { - if (bm->elem_index_dirty & BM_EDGE) { - int index = 0; - BM_ITER_MESH (ele, &iter, bm, BM_EDGES_OF_MESH) { - BM_elem_index_set(ele, index); /* set_ok */ - index++; - } - bm->elem_index_dirty &= ~BM_EDGE; - BLI_assert(index == bm->totedge); - } - else { - // printf("%s: skipping edge index calc!\n", __func__); - } - } - - if (hflag & BM_FACE) { - if (bm->elem_index_dirty & BM_FACE) { - int index = 0; - BM_ITER_MESH (ele, &iter, bm, BM_FACES_OF_MESH) { - BM_elem_index_set(ele, index); /* set_ok */ - index++; - } - bm->elem_index_dirty &= ~BM_FACE; - BLI_assert(index == bm->totface); - } - else { - // printf("%s: skipping face index calc!\n", __func__); - } - } + bm->elem_index_dirty &= ~hflag; } diff --git a/source/blender/bmesh/intern/bmesh_operators.c b/source/blender/bmesh/intern/bmesh_operators.c index 19f2b2f8978..f7dcb8ba483 100644 --- a/source/blender/bmesh/intern/bmesh_operators.c +++ b/source/blender/bmesh/intern/bmesh_operators.c @@ -599,6 +599,7 @@ void BMO_mesh_flag_disable_all(BMesh *bm, BMOperator *UNUSED(op), const char hty BMElemF *ele; int i; +#pragma omp parallel for schedule(dynamic) for (i = 0; i < 3; i++) { if (htype & flag_types[i]) { BM_ITER_MESH (ele, &iter, bm, iter_types[i]) { @@ -1159,100 +1160,161 @@ void BMO_slot_buffer_flag_disable(BMesh *bm, */ static void bmo_flag_layer_alloc(BMesh *bm) { - BMElemF *ele; /* set the index values since we are looping over all data anyway, * may save time later on */ - int i; - BMIter iter; - BLI_mempool *oldpool = bm->toolflagpool; /* old flag pool */ - BLI_mempool *newpool; - void *oldflags; + BLI_mempool *voldpool = bm->vtoolflagpool; /* old flag pool */ + BLI_mempool *eoldpool = bm->etoolflagpool; /* old flag pool */ + BLI_mempool *foldpool = bm->ftoolflagpool; /* old flag pool */ /* store memcpy size for reuse */ const size_t old_totflags_size = (bm->totflags * sizeof(BMFlagLayer)); - BLI_assert(oldpool != NULL); - bm->totflags++; - /* allocate new flag pool */ - bm->toolflagpool = newpool = BLI_mempool_create(sizeof(BMFlagLayer) * bm->totflags, 512, 512, 0); - - /* now go through and memcpy all the flags. Loops don't get a flag layer at this time.. */ - BM_ITER_MESH_INDEX (ele, &iter, bm, BM_VERTS_OF_MESH, i) { - oldflags = ele->oflags; - ele->oflags = BLI_mempool_calloc(newpool); - memcpy(ele->oflags, oldflags, old_totflags_size); - BM_elem_index_set(ele, i); /* set_inline */ - BM_ELEM_API_FLAG_CLEAR((BMElemF *)ele); - } - BM_ITER_MESH_INDEX (ele, &iter, bm, BM_EDGES_OF_MESH, i) { - oldflags = ele->oflags; - ele->oflags = BLI_mempool_calloc(newpool); - memcpy(ele->oflags, oldflags, old_totflags_size); - BM_elem_index_set(ele, i); /* set_inline */ - BM_ELEM_API_FLAG_CLEAR((BMElemF *)ele); - } - BM_ITER_MESH_INDEX (ele, &iter, bm, BM_FACES_OF_MESH, i) { - oldflags = ele->oflags; - ele->oflags = BLI_mempool_calloc(newpool); - memcpy(ele->oflags, oldflags, old_totflags_size); - BM_elem_index_set(ele, i); /* set_inline */ - BM_ELEM_API_FLAG_CLEAR((BMElemF *)ele); + bm->vtoolflagpool = BLI_mempool_create(sizeof(BMFlagLayer) * bm->totflags, max_ii(512, bm->totvert), 512, 0); + bm->etoolflagpool = BLI_mempool_create(sizeof(BMFlagLayer) * bm->totflags, max_ii(512, bm->totedge), 512, 0); + bm->ftoolflagpool = BLI_mempool_create(sizeof(BMFlagLayer) * bm->totflags, max_ii(512, bm->totface), 512, 0); + +#pragma omp parallel sections + { +#pragma omp section + { + BMIter iter; + BMElemF *ele; + int i; + + BLI_mempool *newpool = bm->vtoolflagpool; + + /* now go through and memcpy all the flags. Loops don't get a flag layer at this time.. */ + BM_ITER_MESH_INDEX (ele, &iter, bm, BM_VERTS_OF_MESH, i) { + void *oldflags = ele->oflags; + ele->oflags = BLI_mempool_calloc(newpool); + memcpy(ele->oflags, oldflags, old_totflags_size); + BM_elem_index_set(ele, i); /* set_inline */ + BM_ELEM_API_FLAG_CLEAR((BMElemF *)ele); + } + } +#pragma omp section + { + BMIter iter; + BMElemF *ele; + int i; + + BLI_mempool *newpool = bm->etoolflagpool; + + BM_ITER_MESH_INDEX (ele, &iter, bm, BM_EDGES_OF_MESH, i) { + void *oldflags = ele->oflags; + ele->oflags = BLI_mempool_calloc(newpool); + memcpy(ele->oflags, oldflags, old_totflags_size); + BM_elem_index_set(ele, i); /* set_inline */ + BM_ELEM_API_FLAG_CLEAR((BMElemF *)ele); + } + } +#pragma omp section + { + BMIter iter; + BMElemF *ele; + int i; + + BLI_mempool *newpool = bm->ftoolflagpool; + + BM_ITER_MESH_INDEX (ele, &iter, bm, BM_FACES_OF_MESH, i) { + void *oldflags = ele->oflags; + ele->oflags = BLI_mempool_calloc(newpool); + memcpy(ele->oflags, oldflags, old_totflags_size); + BM_elem_index_set(ele, i); /* set_inline */ + BM_ELEM_API_FLAG_CLEAR((BMElemF *)ele); + } + } } + BLI_mempool_destroy(voldpool); + BLI_mempool_destroy(eoldpool); + BLI_mempool_destroy(foldpool); + bm->elem_index_dirty &= ~(BM_VERT | BM_EDGE | BM_FACE); - BLI_mempool_destroy(oldpool); + } static void bmo_flag_layer_free(BMesh *bm) { - BMElemF *ele; /* set the index values since we are looping over all data anyway, * may save time later on */ - int i; - BMIter iter; - BLI_mempool *oldpool = bm->toolflagpool; - BLI_mempool *newpool; - void *oldflags; - + BLI_mempool *voldpool = bm->vtoolflagpool; + BLI_mempool *eoldpool = bm->etoolflagpool; + BLI_mempool *foldpool = bm->ftoolflagpool; + /* store memcpy size for reuse */ const size_t new_totflags_size = ((bm->totflags - 1) * sizeof(BMFlagLayer)); /* de-increment the totflags first.. */ bm->totflags--; - /* allocate new flag pool */ - bm->toolflagpool = newpool = BLI_mempool_create(new_totflags_size, 512, 512, 0); - - /* now go through and memcpy all the flags */ - BM_ITER_MESH_INDEX (ele, &iter, bm, BM_VERTS_OF_MESH, i) { - oldflags = ele->oflags; - ele->oflags = BLI_mempool_calloc(newpool); - memcpy(ele->oflags, oldflags, new_totflags_size); - BM_elem_index_set(ele, i); /* set_inline */ - BM_ELEM_API_FLAG_CLEAR((BMElemF *)ele); - } - BM_ITER_MESH_INDEX (ele, &iter, bm, BM_EDGES_OF_MESH, i) { - oldflags = ele->oflags; - ele->oflags = BLI_mempool_calloc(newpool); - memcpy(ele->oflags, oldflags, new_totflags_size); - BM_elem_index_set(ele, i); /* set_inline */ - BM_ELEM_API_FLAG_CLEAR((BMElemF *)ele); - } - BM_ITER_MESH_INDEX (ele, &iter, bm, BM_FACES_OF_MESH, i) { - oldflags = ele->oflags; - ele->oflags = BLI_mempool_calloc(newpool); - memcpy(ele->oflags, oldflags, new_totflags_size); - BM_elem_index_set(ele, i); /* set_inline */ - BM_ELEM_API_FLAG_CLEAR((BMElemF *)ele); + + bm->vtoolflagpool = BLI_mempool_create(new_totflags_size, bm->totvert, 512, 0); + bm->etoolflagpool = BLI_mempool_create(new_totflags_size, bm->totedge, 512, 0); + bm->ftoolflagpool = BLI_mempool_create(new_totflags_size, bm->totface, 512, 0); + +#pragma omp parallel sections + { +#pragma omp section + { + BMIter iter; + BMElemF *ele; + int i; + + BLI_mempool *newpool = bm->vtoolflagpool; + + /* now go through and memcpy all the flag */ + BM_ITER_MESH_INDEX (ele, &iter, bm, BM_VERTS_OF_MESH, i) { + void *oldflags = ele->oflags; + ele->oflags = BLI_mempool_calloc(newpool); + memcpy(ele->oflags, oldflags, new_totflags_size); + BM_elem_index_set(ele, i); /* set_inline */ + BM_ELEM_API_FLAG_CLEAR((BMElemF *)ele); + } + } +#pragma omp section + { + BMIter iter; + BMElemF *ele; + int i; + + BLI_mempool *newpool = bm->etoolflagpool; + + BM_ITER_MESH_INDEX (ele, &iter, bm, BM_EDGES_OF_MESH, i) { + void *oldflags = ele->oflags; + ele->oflags = BLI_mempool_calloc(newpool); + memcpy(ele->oflags, oldflags, new_totflags_size); + BM_elem_index_set(ele, i); /* set_inline */ + BM_ELEM_API_FLAG_CLEAR((BMElemF *)ele); + } + } +#pragma omp section + { + BMIter iter; + BMElemF *ele; + int i; + + BLI_mempool *newpool = bm->ftoolflagpool; + + BM_ITER_MESH_INDEX (ele, &iter, bm, BM_FACES_OF_MESH, i) { + void *oldflags = ele->oflags; + ele->oflags = BLI_mempool_calloc(newpool); + memcpy(ele->oflags, oldflags, new_totflags_size); + BM_elem_index_set(ele, i); /* set_inline */ + BM_ELEM_API_FLAG_CLEAR((BMElemF *)ele); + } + } } + BLI_mempool_destroy(voldpool); + BLI_mempool_destroy(eoldpool); + BLI_mempool_destroy(foldpool); + bm->elem_index_dirty &= ~(BM_VERT | BM_EDGE | BM_FACE); - - BLI_mempool_destroy(oldpool); } static void bmo_flag_layer_clear(BMesh *bm) @@ -1261,22 +1323,35 @@ static void bmo_flag_layer_clear(BMesh *bm) /* set the index values since we are looping over all data anyway, * may save time later on */ int i; + const BMFlagLayer zero_flag = {0}; BMIter iter; const int totflags_offset = bm->totflags - 1; - /* now go through and memcpy all the flags */ - BM_ITER_MESH_INDEX (ele, &iter, bm, BM_VERTS_OF_MESH, i) { - memset(ele->oflags + totflags_offset, 0, sizeof(BMFlagLayer)); - BM_elem_index_set(ele, i); /* set_inline */ - } - BM_ITER_MESH_INDEX (ele, &iter, bm, BM_EDGES_OF_MESH, i) { - memset(ele->oflags + totflags_offset, 0, sizeof(BMFlagLayer)); - BM_elem_index_set(ele, i); /* set_inline */ - } - BM_ITER_MESH_INDEX (ele, &iter, bm, BM_FACES_OF_MESH, i) { - memset(ele->oflags + totflags_offset, 0, sizeof(BMFlagLayer)); - BM_elem_index_set(ele, i); /* set_inline */ +#pragma omp parallel sections + { + /* now go through and memcpy all the flag */ +#pragma omp section + { + BM_ITER_MESH_INDEX (ele, &iter, bm, BM_VERTS_OF_MESH, i) { + ele->oflags[totflags_offset] = zero_flag; + BM_elem_index_set(ele, i); /* set_inline */ + } + } +#pragma omp section + { + BM_ITER_MESH_INDEX (ele, &iter, bm, BM_EDGES_OF_MESH, i) { + ele->oflags[totflags_offset] = zero_flag; + BM_elem_index_set(ele, i); /* set_inline */ + } + } +#pragma omp section + { + BM_ITER_MESH_INDEX (ele, &iter, bm, BM_FACES_OF_MESH, i) { + ele->oflags[totflags_offset] = zero_flag; + BM_elem_index_set(ele, i); /* set_inline */ + } + } } bm->elem_index_dirty &= ~(BM_VERT | BM_EDGE | BM_FACE); diff --git a/source/blender/editors/mesh/editmesh_utils.c b/source/blender/editors/mesh/editmesh_utils.c index 2cf63586142..6f5a61075ae 100644 --- a/source/blender/editors/mesh/editmesh_utils.c +++ b/source/blender/editors/mesh/editmesh_utils.c @@ -396,41 +396,34 @@ void EDBM_index_arrays_init(BMEditMesh *tm, int forvert, int foredge, int forfac EDBM_index_arrays_free(tm); if (forvert) { - BMIter iter; - BMVert *ele; - int i = 0; - tm->vert_index = MEM_mallocN(sizeof(void **) * tm->bm->totvert, "tm->vert_index"); - - ele = BM_iter_new(&iter, tm->bm, BM_VERTS_OF_MESH, NULL); - for ( ; ele; ele = BM_iter_step(&iter)) { - tm->vert_index[i++] = ele; - } } - if (foredge) { - BMIter iter; - BMEdge *ele; - int i = 0; - tm->edge_index = MEM_mallocN(sizeof(void **) * tm->bm->totedge, "tm->edge_index"); - - ele = BM_iter_new(&iter, tm->bm, BM_EDGES_OF_MESH, NULL); - for ( ; ele; ele = BM_iter_step(&iter)) { - tm->edge_index[i++] = ele; - } + } + if (forface) { + tm->face_index = MEM_mallocN(sizeof(void **) * tm->bm->totface, "tm->face_index"); } - if (forface) { - BMIter iter; - BMFace *ele; - int i = 0; - - tm->face_index = MEM_mallocN(sizeof(void **) * tm->bm->totface, "tm->face_index"); - - ele = BM_iter_new(&iter, tm->bm, BM_FACES_OF_MESH, NULL); - for ( ; ele; ele = BM_iter_step(&iter)) { - tm->face_index[i++] = ele; +#pragma omp parallel sections + { +#pragma omp section + { + if (forvert) { + BM_iter_as_array(tm->bm, BM_VERTS_OF_MESH, NULL, (void **)tm->vert_index, tm->bm->totvert); + } + } +#pragma omp section + { + if (foredge) { + BM_iter_as_array(tm->bm, BM_EDGES_OF_MESH, NULL, (void **)tm->edge_index, tm->bm->totedge); + } + } +#pragma omp section + { + if (forface) { + BM_iter_as_array(tm->bm, BM_FACES_OF_MESH, NULL, (void **)tm->face_index, tm->bm->totface); + } } } } @@ -1283,6 +1276,7 @@ void EDBM_mesh_reveal(BMEditMesh *em) /* Use tag flag to remember what was hidden before all is revealed. * BM_ELEM_HIDDEN --> BM_ELEM_TAG */ +#pragma omp parallel for schedule(dynamic) for (i = 0; i < 3; i++) { BM_ITER_MESH (ele, &iter, em->bm, iter_types[i]) { BM_elem_flag_set(ele, BM_ELEM_TAG, BM_elem_flag_test(ele, BM_ELEM_HIDDEN)); diff --git a/source/blender/modifiers/intern/MOD_decimate.c b/source/blender/modifiers/intern/MOD_decimate.c index 28cdfa810fa..a23b677f8e6 100644 --- a/source/blender/modifiers/intern/MOD_decimate.c +++ b/source/blender/modifiers/intern/MOD_decimate.c @@ -188,7 +188,9 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, /* update for display only */ dmd->face_count = bm->totface; result = CDDM_from_bmesh(bm, FALSE); - BLI_assert(bm->toolflagpool == NULL); /* make sure we never alloc'd this */ + BLI_assert(bm->vtoolflagpool == NULL); /* make sure we never alloc'd this */ + BLI_assert(bm->etoolflagpool == NULL); + BLI_assert(bm->ftoolflagpool == NULL); BM_mesh_free(bm); #ifdef USE_TIMEIT From cf723e5e7c99cf653196b47afe131cb3cac24050 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 12 Dec 2012 05:27:52 +0000 Subject: [PATCH 036/252] use htype flags as arguments to EDBM_index_arrays_init(), no functional changes. --- source/blender/blenkernel/BKE_tessmesh.h | 4 +- .../blenkernel/intern/editderivedmesh.c | 52 +++++++-------- source/blender/editors/include/ED_mesh.h | 4 +- source/blender/editors/mesh/editface.c | 2 +- source/blender/editors/mesh/editmesh_utils.c | 66 ++++++++++--------- source/blender/editors/mesh/mesh_navmesh.c | 2 +- .../blender/editors/space_view3d/drawobject.c | 4 +- .../editors/space_view3d/view3d_iterators.c | 6 +- .../editors/space_view3d/view3d_snap.c | 2 +- .../editors/transform/transform_snap.c | 4 +- source/blender/editors/uvedit/uvedit_ops.c | 8 +-- .../editors/uvedit/uvedit_smart_stitch.c | 2 +- .../editors/uvedit/uvedit_unwrap_ops.c | 2 +- 13 files changed, 80 insertions(+), 78 deletions(-) diff --git a/source/blender/blenkernel/BKE_tessmesh.h b/source/blender/blenkernel/BKE_tessmesh.h index dea5e726671..6967f1b2951 100644 --- a/source/blender/blenkernel/BKE_tessmesh.h +++ b/source/blender/blenkernel/BKE_tessmesh.h @@ -83,9 +83,9 @@ typedef struct BMEditMesh { int mirr_free_arrays; } BMEditMesh; -void BMEdit_RecalcTessellation(BMEditMesh *tm); +void BMEdit_RecalcTessellation(BMEditMesh *em); BMEditMesh *BMEdit_Create(BMesh *bm, int do_tessellate); -BMEditMesh *BMEdit_Copy(BMEditMesh *tm); +BMEditMesh *BMEdit_Copy(BMEditMesh *em); BMEditMesh *BMEdit_FromObject(struct Object *ob); void BMEdit_Free(BMEditMesh *em); void BMEdit_UpdateLinkedCustomData(BMEditMesh *em); diff --git a/source/blender/blenkernel/intern/editderivedmesh.c b/source/blender/blenkernel/intern/editderivedmesh.c index 321a61ce238..73320c96315 100644 --- a/source/blender/blenkernel/intern/editderivedmesh.c +++ b/source/blender/blenkernel/intern/editderivedmesh.c @@ -71,24 +71,24 @@ extern GLubyte stipple_quarttone[128]; /* glutil.c, bad level data */ BMEditMesh *BMEdit_Create(BMesh *bm, int do_tessellate) { - BMEditMesh *tm = MEM_callocN(sizeof(BMEditMesh), __func__); + BMEditMesh *em = MEM_callocN(sizeof(BMEditMesh), __func__); - tm->bm = bm; + em->bm = bm; if (do_tessellate) { - BMEdit_RecalcTessellation(tm); + BMEdit_RecalcTessellation(em); } - return tm; + return em; } -BMEditMesh *BMEdit_Copy(BMEditMesh *tm) +BMEditMesh *BMEdit_Copy(BMEditMesh *em) { - BMEditMesh *tm2 = MEM_callocN(sizeof(BMEditMesh), __func__); - *tm2 = *tm; + BMEditMesh *em_copy = MEM_callocN(sizeof(BMEditMesh), __func__); + *em_copy = *em; - tm2->derivedCage = tm2->derivedFinal = NULL; + em_copy->derivedCage = em_copy->derivedFinal = NULL; - tm2->bm = BM_mesh_copy(tm->bm); + em_copy->bm = BM_mesh_copy(em->bm); /* The tessellation is NOT calculated on the copy here, * because currently all the callers of this function use @@ -97,22 +97,22 @@ BMEditMesh *BMEdit_Copy(BMEditMesh *tm) * reasons, in that case it makes more sense to do the * tessellation only when/if that copy ends up getting * used.*/ - tm2->looptris = NULL; + em_copy->looptris = NULL; - tm2->vert_index = NULL; - tm2->edge_index = NULL; - tm2->face_index = NULL; + em_copy->vert_index = NULL; + em_copy->edge_index = NULL; + em_copy->face_index = NULL; - return tm2; + return em_copy; } -static void BMEdit_RecalcTessellation_intern(BMEditMesh *tm) +static void BMEdit_RecalcTessellation_intern(BMEditMesh *em) { /* use this to avoid locking pthread for _every_ polygon * and calling the fill function */ #define USE_TESSFACE_SPEEDUP - BMesh *bm = tm->bm; + BMesh *bm = em->bm; BMLoop *(*looptris)[3] = NULL; BLI_array_declare(looptris); BMIter iter, liter; @@ -125,26 +125,26 @@ static void BMEdit_RecalcTessellation_intern(BMEditMesh *tm) #if 0 /* note, we could be clever and re-use this array but would need to ensure * its realloced at some point, for now just free it */ - if (tm->looptris) MEM_freeN(tm->looptris); + if (em->looptris) MEM_freeN(em->looptris); - /* Use tm->tottri when set, this means no reallocs while transforming, + /* Use em->tottri when set, this means no reallocs while transforming, * (unless scanfill fails), otherwise... */ /* allocate the length of totfaces, avoid many small reallocs, * if all faces are tri's it will be correct, quads == 2x allocs */ - BLI_array_reserve(looptris, (tm->tottri && tm->tottri < bm->totface * 3) ? tm->tottri : bm->totface); + BLI_array_reserve(looptris, (em->tottri && em->tottri < bm->totface * 3) ? em->tottri : bm->totface); #else /* this means no reallocs for quad dominant models, for */ - if ( (tm->looptris != NULL) && - (tm->tottri != 0) && + if ( (em->looptris != NULL) && + (em->tottri != 0) && /* (totrti <= bm->totface * 2) would be fine for all quads, * but in case there are some ngons, still re-use the array */ - (tm->tottri <= bm->totface * 3)) + (em->tottri <= bm->totface * 3)) { - looptris = tm->looptris; + looptris = em->looptris; } else { - if (tm->looptris) MEM_freeN(tm->looptris); + if (em->looptris) MEM_freeN(em->looptris); BLI_array_reserve(looptris, bm->totface); } @@ -237,8 +237,8 @@ static void BMEdit_RecalcTessellation_intern(BMEditMesh *tm) } } - tm->tottri = i; - tm->looptris = looptris; + em->tottri = i; + em->looptris = looptris; #undef USE_TESSFACE_SPEEDUP diff --git a/source/blender/editors/include/ED_mesh.h b/source/blender/editors/include/ED_mesh.h index 865da8f0e6e..06e94e0dbda 100644 --- a/source/blender/editors/include/ED_mesh.h +++ b/source/blender/editors/include/ED_mesh.h @@ -86,10 +86,10 @@ void EDBM_mesh_clear(struct BMEditMesh *em); void EDBM_selectmode_to_scene(struct bContext *C); void EDBM_mesh_make(struct ToolSettings *ts, struct Scene *scene, struct Object *ob); -void EDBM_mesh_free(struct BMEditMesh *tm); +void EDBM_mesh_free(struct BMEditMesh *em); void EDBM_mesh_load(struct Object *ob); -void EDBM_index_arrays_init(struct BMEditMesh *em, int forvert, int foredge, int forface); +void EDBM_index_arrays_init(struct BMEditMesh *em, const char htype); void EDBM_index_arrays_free(struct BMEditMesh *em); struct BMVert *EDBM_vert_at_index(struct BMEditMesh *em, int index); struct BMEdge *EDBM_edge_at_index(struct BMEditMesh *em, int index); diff --git a/source/blender/editors/mesh/editface.c b/source/blender/editors/mesh/editface.c index 4350c005f95..8c0777b2426 100644 --- a/source/blender/editors/mesh/editface.c +++ b/source/blender/editors/mesh/editface.c @@ -852,7 +852,7 @@ void ED_mesh_mirrtopo_init(Mesh *me, const int ob_mode, MirrTopoStore_t *mesh_to if (em) { if (skip_em_vert_array_init == FALSE) { - EDBM_index_arrays_init(em, 1, 0, 0); + EDBM_index_arrays_init(em, BM_VERT); } } diff --git a/source/blender/editors/mesh/editmesh_utils.c b/source/blender/editors/mesh/editmesh_utils.c index 6f5a61075ae..7259559603a 100644 --- a/source/blender/editors/mesh/editmesh_utils.c +++ b/source/blender/editors/mesh/editmesh_utils.c @@ -391,74 +391,76 @@ void EDBM_mesh_free(BMEditMesh *em) BMEdit_Free(em); } -void EDBM_index_arrays_init(BMEditMesh *tm, int forvert, int foredge, int forface) +void EDBM_index_arrays_init(BMEditMesh *em, const char htype) { - EDBM_index_arrays_free(tm); + BLI_assert((htype & ~BM_ALL_NOLOOP) == 0); - if (forvert) { - tm->vert_index = MEM_mallocN(sizeof(void **) * tm->bm->totvert, "tm->vert_index"); + EDBM_index_arrays_free(em); + + if (htype & BM_VERT) { + em->vert_index = MEM_mallocN(sizeof(void **) * em->bm->totvert, "em->vert_index"); } - if (foredge) { - tm->edge_index = MEM_mallocN(sizeof(void **) * tm->bm->totedge, "tm->edge_index"); + if (htype & BM_EDGE) { + em->edge_index = MEM_mallocN(sizeof(void **) * em->bm->totedge, "em->edge_index"); } - if (forface) { - tm->face_index = MEM_mallocN(sizeof(void **) * tm->bm->totface, "tm->face_index"); + if (htype & BM_FACE) { + em->face_index = MEM_mallocN(sizeof(void **) * em->bm->totface, "em->face_index"); } #pragma omp parallel sections { #pragma omp section { - if (forvert) { - BM_iter_as_array(tm->bm, BM_VERTS_OF_MESH, NULL, (void **)tm->vert_index, tm->bm->totvert); + if (htype & BM_VERT) { + BM_iter_as_array(em->bm, BM_VERTS_OF_MESH, NULL, (void **)em->vert_index, em->bm->totvert); } } #pragma omp section { - if (foredge) { - BM_iter_as_array(tm->bm, BM_EDGES_OF_MESH, NULL, (void **)tm->edge_index, tm->bm->totedge); + if (htype & BM_EDGE) { + BM_iter_as_array(em->bm, BM_EDGES_OF_MESH, NULL, (void **)em->edge_index, em->bm->totedge); } } #pragma omp section { - if (forface) { - BM_iter_as_array(tm->bm, BM_FACES_OF_MESH, NULL, (void **)tm->face_index, tm->bm->totface); + if (htype & BM_FACE) { + BM_iter_as_array(em->bm, BM_FACES_OF_MESH, NULL, (void **)em->face_index, em->bm->totface); } } } } -void EDBM_index_arrays_free(BMEditMesh *tm) +void EDBM_index_arrays_free(BMEditMesh *em) { - if (tm->vert_index) { - MEM_freeN(tm->vert_index); - tm->vert_index = NULL; + if (em->vert_index) { + MEM_freeN(em->vert_index); + em->vert_index = NULL; } - if (tm->edge_index) { - MEM_freeN(tm->edge_index); - tm->edge_index = NULL; + if (em->edge_index) { + MEM_freeN(em->edge_index); + em->edge_index = NULL; } - if (tm->face_index) { - MEM_freeN(tm->face_index); - tm->face_index = NULL; + if (em->face_index) { + MEM_freeN(em->face_index); + em->face_index = NULL; } } -BMVert *EDBM_vert_at_index(BMEditMesh *tm, int index) +BMVert *EDBM_vert_at_index(BMEditMesh *em, int index) { - return tm->vert_index && index < tm->bm->totvert ? tm->vert_index[index] : NULL; + return em->vert_index && index < em->bm->totvert ? em->vert_index[index] : NULL; } -BMEdge *EDBM_edge_at_index(BMEditMesh *tm, int index) +BMEdge *EDBM_edge_at_index(BMEditMesh *em, int index) { - return tm->edge_index && index < tm->bm->totedge ? tm->edge_index[index] : NULL; + return em->edge_index && index < em->bm->totedge ? em->edge_index[index] : NULL; } -BMFace *EDBM_face_at_index(BMEditMesh *tm, int index) +BMFace *EDBM_face_at_index(BMEditMesh *em, int index) { - return (tm->face_index && index < tm->bm->totface && index >= 0) ? tm->face_index[index] : NULL; + return (em->face_index && index < em->bm->totface && index >= 0) ? em->face_index[index] : NULL; } void EDBM_selectmode_flush_ex(BMEditMesh *em, const short selectmode) @@ -647,7 +649,7 @@ UvVertMap *EDBM_uv_vert_map_create(BMEditMesh *em, int selected, int do_face_idx int totverts, i, totuv; if (do_face_idx_array) - EDBM_index_arrays_init(em, 0, 0, 1); + EDBM_index_arrays_init(em, BM_FACE); BM_mesh_elem_index_ensure(em->bm, BM_VERT); @@ -1104,7 +1106,7 @@ void EDBM_verts_mirror_cache_begin(BMEditMesh *em, const short use_select) } if (!em->vert_index) { - EDBM_index_arrays_init(em, 1, 0, 0); + EDBM_index_arrays_init(em, BM_VERT); em->mirr_free_arrays = 1; } diff --git a/source/blender/editors/mesh/mesh_navmesh.c b/source/blender/editors/mesh/mesh_navmesh.c index 83a1261e981..bae2c6cde9d 100644 --- a/source/blender/editors/mesh/mesh_navmesh.c +++ b/source/blender/editors/mesh/mesh_navmesh.c @@ -375,7 +375,7 @@ static Object *createRepresentation(bContext *C, struct recast_polyMesh *pmesh, BM_vert_create(em->bm, co, NULL, 0); } - EDBM_index_arrays_init(em, 1, 0, 0); + EDBM_index_arrays_init(em, BM_VERT); /* create faces */ for (j = 0; j < trinum; j++) { diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c index 055afda189f..75fe1e27bf5 100644 --- a/source/blender/editors/space_view3d/drawobject.c +++ b/source/blender/editors/space_view3d/drawobject.c @@ -2838,7 +2838,7 @@ static void draw_em_fancy(Scene *scene, View3D *v3d, RegionView3D *rv3d, } } - EDBM_index_arrays_init(em, 1, 1, 1); + EDBM_index_arrays_init(em, BM_VERT | BM_EDGE | BM_FACE); if (dt > OB_WIRE) { if (check_object_draw_texture(scene, v3d, dt)) { @@ -7123,7 +7123,7 @@ void draw_object_backbufsel(Scene *scene, View3D *v3d, RegionView3D *rv3d, Objec DerivedMesh *dm = editbmesh_get_derived_cage(scene, ob, em, CD_MASK_BAREMESH); - EDBM_index_arrays_init(em, 1, 1, 1); + EDBM_index_arrays_init(em, BM_VERT | BM_EDGE | BM_FACE); bbs_mesh_solid_EM(em, scene, v3d, ob, dm, ts->selectmode & SCE_SELECT_FACE); if (ts->selectmode & SCE_SELECT_FACE) diff --git a/source/blender/editors/space_view3d/view3d_iterators.c b/source/blender/editors/space_view3d/view3d_iterators.c index 37607729d0d..04d47e6cf5d 100644 --- a/source/blender/editors/space_view3d/view3d_iterators.c +++ b/source/blender/editors/space_view3d/view3d_iterators.c @@ -113,7 +113,7 @@ void mesh_foreachScreenVert( ED_view3d_clipping_local(vc->rv3d, vc->obedit->obmat); /* for local clipping lookups */ } - EDBM_index_arrays_init(vc->em, 1, 0, 0); + EDBM_index_arrays_init(vc->em, BM_VERT); dm->foreachMappedVert(dm, mesh_foreachScreenVert__mapFunc, &data); EDBM_index_arrays_free(vc->em); @@ -172,7 +172,7 @@ void mesh_foreachScreenEdge( ED_view3d_clipping_local(vc->rv3d, vc->obedit->obmat); /* for local clipping lookups */ } - EDBM_index_arrays_init(vc->em, 0, 1, 0); + EDBM_index_arrays_init(vc->em, BM_EDGE); dm->foreachMappedEdge(dm, mesh_foreachScreenEdge__mapFunc, &data); EDBM_index_arrays_free(vc->em); @@ -209,7 +209,7 @@ void mesh_foreachScreenFace( ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); - EDBM_index_arrays_init(vc->em, 0, 0, 1); + EDBM_index_arrays_init(vc->em, BM_FACE); dm->foreachMappedFaceCenter(dm, mesh_foreachScreenFace__mapFunc, &data); EDBM_index_arrays_free(vc->em); diff --git a/source/blender/editors/space_view3d/view3d_snap.c b/source/blender/editors/space_view3d/view3d_snap.c index 7f1bbb22f24..e60eed42770 100644 --- a/source/blender/editors/space_view3d/view3d_snap.c +++ b/source/blender/editors/space_view3d/view3d_snap.c @@ -340,7 +340,7 @@ static void make_trans_verts(Object *obedit, float min[3], float max[3], int mod } if (transvmain && em->derivedCage) { - EDBM_index_arrays_init(em, 1, 0, 0); + EDBM_index_arrays_init(em, BM_VERT); em->derivedCage->foreachMappedVert(em->derivedCage, set_mapped_co, userdata); EDBM_index_arrays_free(em); } diff --git a/source/blender/editors/transform/transform_snap.c b/source/blender/editors/transform/transform_snap.c index 9de9c96f2ec..b1e48448fac 100644 --- a/source/blender/editors/transform/transform_snap.c +++ b/source/blender/editors/transform/transform_snap.c @@ -1417,7 +1417,7 @@ static int snapDerivedMesh(short snap_mode, ARegion *ar, Object *ob, DerivedMesh if (em != NULL) { index_array = dm->getVertDataArray(dm, CD_ORIGINDEX); - EDBM_index_arrays_init(em, 1, 0, 0); + EDBM_index_arrays_init(em, BM_VERT); } for (i = 0; i < totvert; i++) { @@ -1468,7 +1468,7 @@ static int snapDerivedMesh(short snap_mode, ARegion *ar, Object *ob, DerivedMesh if (em != NULL) { index_array = dm->getEdgeDataArray(dm, CD_ORIGINDEX); - EDBM_index_arrays_init(em, 0, 1, 0); + EDBM_index_arrays_init(em, BM_EDGE); } for (i = 0; i < totedge; i++) { diff --git a/source/blender/editors/uvedit/uvedit_ops.c b/source/blender/editors/uvedit/uvedit_ops.c index a384c777aab..46b7db32334 100644 --- a/source/blender/editors/uvedit/uvedit_ops.c +++ b/source/blender/editors/uvedit/uvedit_ops.c @@ -999,7 +999,7 @@ static int select_edgeloop(Scene *scene, Image *ima, BMEditMesh *em, NearestHit int a, looking, nverts, starttotf, select; /* setup */ - EDBM_index_arrays_init(em, 0, 0, 1); + EDBM_index_arrays_init(em, BM_FACE); vmap = EDBM_uv_vert_map_create(em, 0, 0, limit); BM_mesh_elem_index_ensure(em->bm, BM_VERT | BM_FACE); @@ -1111,7 +1111,7 @@ static void select_linked(Scene *scene, Image *ima, BMEditMesh *em, const float unsigned int a; char *flag; - EDBM_index_arrays_init(em, 0, 0, 1); /* we can use this too */ + EDBM_index_arrays_init(em, BM_FACE); /* we can use this too */ vmap = EDBM_uv_vert_map_create(em, 1, 1, limit); if (vmap == NULL) @@ -2608,7 +2608,7 @@ static void uv_faces_do_sticky(SpaceImage *sima, Scene *scene, Object *obedit, s uvedit_pixel_to_float(sima, limit, 0.05); - EDBM_index_arrays_init(em, 0, 0, 1); + EDBM_index_arrays_init(em, BM_FACE); vmap = EDBM_uv_vert_map_create(em, 0, 0, limit); /* verts are numbered above in make_uv_vert_map_EM, make sure this stays true! */ @@ -3795,7 +3795,7 @@ static int seams_from_islands_exec(bContext *C, wmOperator *op) } /* This code sets editvert->tmp.l to the index. This will be useful later on. */ - EDBM_index_arrays_init(em, 0, 0, 1); + EDBM_index_arrays_init(em, BM_FACE); vmap = EDBM_uv_vert_map_create(em, 0, 0, limit); BM_ITER_MESH (editedge, &iter, bm, BM_EDGES_OF_MESH) { diff --git a/source/blender/editors/uvedit/uvedit_smart_stitch.c b/source/blender/editors/uvedit/uvedit_smart_stitch.c index 4ca642690c4..b67747ead5a 100644 --- a/source/blender/editors/uvedit/uvedit_smart_stitch.c +++ b/source/blender/editors/uvedit/uvedit_smart_stitch.c @@ -1256,7 +1256,7 @@ static int stitch_init(bContext *C, wmOperator *op) int faceIndex, elementIndex; UvElement *element; - EDBM_index_arrays_init(em, 0, 0, 1); + EDBM_index_arrays_init(em, BM_FACE); RNA_BEGIN (op->ptr, itemptr, "selection") { diff --git a/source/blender/editors/uvedit/uvedit_unwrap_ops.c b/source/blender/editors/uvedit/uvedit_unwrap_ops.c index b50b8d466f1..6ef680f368d 100644 --- a/source/blender/editors/uvedit/uvedit_unwrap_ops.c +++ b/source/blender/editors/uvedit/uvedit_unwrap_ops.c @@ -434,7 +434,7 @@ static ParamHandle *construct_param_handle_subsurfed(Scene *scene, Object *ob, B faceMap = MEM_mallocN(numOfFaces * sizeof(BMFace *), "unwrap_edit_face_map"); BM_mesh_elem_index_ensure(em->bm, BM_VERT); - EDBM_index_arrays_init(em, 0, 1, 1); + EDBM_index_arrays_init(em, BM_EDGE | BM_FACE); /* map subsurfed faces to original editFaces */ for (i = 0; i < numOfFaces; i++) From 3759c10e5c832672920daf80b0f1018604cfb4b4 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Wed, 12 Dec 2012 06:51:06 +0000 Subject: [PATCH 037/252] Fix #33485: cycles OSL now autodetects the presence of emission and transparent closures to enable multiple importance sampling and transparent shadows. --- intern/cycles/render/graph.h | 3 +++ intern/cycles/render/nodes.h | 6 +++++- intern/cycles/render/osl.cpp | 41 ++++++++++++++++++++++++++++-------- intern/cycles/render/osl.h | 15 ++++++++++++- intern/cycles/render/svm.cpp | 8 +++---- 5 files changed, 58 insertions(+), 15 deletions(-) diff --git a/intern/cycles/render/graph.h b/intern/cycles/render/graph.h index b79167839ab..61b5bd83534 100644 --- a/intern/cycles/render/graph.h +++ b/intern/cycles/render/graph.h @@ -183,6 +183,9 @@ public: virtual void compile(SVMCompiler& compiler) = 0; virtual void compile(OSLCompiler& compiler) = 0; + virtual bool has_surface_emission() { return false; } + virtual bool has_surface_transparent() { return false; } + vector inputs; vector outputs; diff --git a/intern/cycles/render/nodes.h b/intern/cycles/render/nodes.h index 5e357cff56c..8012a99ff05 100644 --- a/intern/cycles/render/nodes.h +++ b/intern/cycles/render/nodes.h @@ -26,7 +26,7 @@ CCL_NAMESPACE_BEGIN class ImageManager; -class Shadr; +class Shader; /* Texture Mapping */ @@ -220,6 +220,8 @@ public: class TransparentBsdfNode : public BsdfNode { public: SHADER_NODE_CLASS(TransparentBsdfNode) + + bool has_surface_transparent() { return true; } }; class VelvetBsdfNode : public BsdfNode { @@ -255,6 +257,8 @@ class EmissionNode : public ShaderNode { public: SHADER_NODE_CLASS(EmissionNode) + bool has_surface_emission() { return true; } + bool total_power; }; diff --git a/intern/cycles/render/osl.cpp b/intern/cycles/render/osl.cpp index b3b838be25b..28de56f3a72 100644 --- a/intern/cycles/render/osl.cpp +++ b/intern/cycles/render/osl.cpp @@ -76,12 +76,12 @@ void OSLShaderManager::device_update(Device *device, DeviceScene *dscene, Scene if(progress.get_cancel()) return; - if(shader->sample_as_light && shader->has_surface_emission) - scene->light_manager->need_update = true; - OSLCompiler compiler((void*)this, (void*)ss, scene->image_manager); compiler.background = (shader == scene->shaders[scene->default_background]); compiler.compile(og, shader); + + if(shader->sample_as_light && shader->has_surface_emission) + scene->light_manager->need_update = true; } /* setup shader engine */ @@ -202,8 +202,14 @@ static string shader_filepath_hash(const string& filepath, uint64_t modified_tim const char *OSLShaderManager::shader_test_loaded(const string& hash) { - set::iterator it = loaded_shaders.find(hash); - return (it == loaded_shaders.end())? NULL: it->c_str(); + map::iterator it = loaded_shaders.find(hash); + return (it == loaded_shaders.end())? NULL: it->first.c_str(); +} + +OSLShaderInfo *OSLShaderManager::shader_loaded_info(const string& hash) +{ + map::iterator it = loaded_shaders.find(hash); + return (it == loaded_shaders.end())? NULL: &it->second; } const char *OSLShaderManager::shader_load_filepath(string filepath) @@ -261,7 +267,8 @@ const char *OSLShaderManager::shader_load_filepath(string filepath) if(!path_read_text(filepath, bytecode)) { fprintf(stderr, "Cycles shader graph: failed to read file %s\n", filepath.c_str()); - loaded_shaders.insert(bytecode_hash); /* to avoid repeat tries */ + OSLShaderInfo info; + loaded_shaders[bytecode_hash] = info; /* to avoid repeat tries */ return NULL; } @@ -306,7 +313,13 @@ const char *OSLShaderManager::shader_load_bytecode(const string& hash, const str { load_memory_shader(ss, hash.c_str(), bytecode.c_str()); - return loaded_shaders.insert(hash).first->c_str(); + /* this is a bit weak, but works */ + OSLShaderInfo info; + info.has_surface_emission = (bytecode.find("\"emission\"") != string::npos); + info.has_surface_transparent = (bytecode.find("\"transparent\"") != string::npos); + loaded_shaders[hash] = info; + + return loaded_shaders.find(hash)->first.c_str(); } /* Graph Compiler */ @@ -477,6 +490,16 @@ void OSLCompiler::add(ShaderNode *node, const char *name, bool isfilepath) ss->ConnectShaders(id_from.c_str(), param_from.c_str(), id_to.c_str(), param_to.c_str()); } } + + /* test if we shader contains specific closures */ + OSLShaderInfo *info = ((OSLShaderManager*)manager)->shader_loaded_info(name); + + if(info) { + if(info->has_surface_emission) + current_shader->has_surface_emission = true; + if(info->has_surface_transparent) + current_shader->has_surface_transparent = true; + } } void OSLCompiler::parameter(const char *name, float f) @@ -632,9 +655,9 @@ void OSLCompiler::generate_nodes(const set& nodes) node->compile(*this); done.insert(node); - if(node->name == ustring("emission")) + if(node->has_surface_emission()) current_shader->has_surface_emission = true; - if(node->name == ustring("transparent")) + if(node->has_surface_transparent()) current_shader->has_surface_transparent = true; } else diff --git a/intern/cycles/render/osl.h b/intern/cycles/render/osl.h index 9b58745bd46..3c599caa893 100644 --- a/intern/cycles/render/osl.h +++ b/intern/cycles/render/osl.h @@ -45,6 +45,18 @@ class ShaderOutput; #ifdef WITH_OSL +/* OSL Shader Info + * to auto detect closures in the shader for MIS and transparent shadows */ + +struct OSLShaderInfo { + OSLShaderInfo() + : has_surface_emission(false), has_surface_transparent(false) + {} + + bool has_surface_emission; + bool has_surface_transparent; +}; + /* Shader Manage */ class OSLShaderManager : public ShaderManager { @@ -65,6 +77,7 @@ public: const char *shader_test_loaded(const string& hash); const char *shader_load_bytecode(const string& hash, const string& bytecode); const char *shader_load_filepath(string filepath); + OSLShaderInfo *shader_loaded_info(const string& hash); protected: void texture_system_init(); @@ -74,7 +87,7 @@ protected: OSL::TextureSystem *ts; OSLRenderServices *services; OSL::ErrorHandler errhandler; - set loaded_shaders; + map loaded_shaders; }; #endif diff --git a/intern/cycles/render/svm.cpp b/intern/cycles/render/svm.cpp index 4acd174e60f..f7cb8f62247 100644 --- a/intern/cycles/render/svm.cpp +++ b/intern/cycles/render/svm.cpp @@ -478,9 +478,9 @@ void SVMCompiler::generate_closure(ShaderNode *node, set& done) stack_clear_users(node, done); stack_clear_temporary(node); - if(node->name == ustring("emission")) + if(node->has_surface_emission()) current_shader->has_surface_emission = true; - if(node->name == ustring("transparent")) + if(node->has_surface_transparent()) current_shader->has_surface_transparent = true; /* end node is added outside of this */ @@ -538,9 +538,9 @@ void SVMCompiler::generate_multi_closure(ShaderNode *node, set& don mix_weight_offset = SVM_STACK_INVALID; - if(node->name == ustring("emission")) + if(node->has_surface_emission()) current_shader->has_surface_emission = true; - if(node->name == ustring("transparent")) + if(node->has_surface_transparent()) current_shader->has_surface_transparent = true; } From 44b634bcb1363fa600e0f9300dcaa76402b47738 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 12 Dec 2012 06:53:39 +0000 Subject: [PATCH 038/252] make EDBM_index_arrays's stay in memory, blender was allocating an array and filling it for verts/edges/faces on every redraw. this may introduce bugs which I didn't catch, but they are very easy to identify in a debug build which has asserts to ensure the arrays are valid before use. in my own test drawing ~98,304 quads - this gave an overall ~16% drawing speedup. --- source/blender/blenkernel/BKE_tessmesh.h | 1 - source/blender/editors/include/ED_mesh.h | 9 +- source/blender/editors/mesh/editface.c | 7 +- source/blender/editors/mesh/editmesh_add.c | 2 +- source/blender/editors/mesh/editmesh_knife.c | 2 +- source/blender/editors/mesh/editmesh_rip.c | 2 +- source/blender/editors/mesh/editmesh_select.c | 12 +- source/blender/editors/mesh/editmesh_slide.c | 4 +- source/blender/editors/mesh/editmesh_tools.c | 108 +++++++++--------- source/blender/editors/mesh/editmesh_utils.c | 91 ++++++++++----- source/blender/editors/mesh/mesh_navmesh.c | 4 +- .../blender/editors/space_view3d/drawobject.c | 8 +- .../editors/space_view3d/view3d_iterators.c | 9 +- .../editors/space_view3d/view3d_snap.c | 3 +- .../editors/transform/transform_snap.c | 10 +- source/blender/editors/uvedit/uvedit_ops.c | 20 ++-- .../editors/uvedit/uvedit_smart_stitch.c | 3 +- .../editors/uvedit/uvedit_unwrap_ops.c | 4 +- 18 files changed, 156 insertions(+), 143 deletions(-) diff --git a/source/blender/blenkernel/BKE_tessmesh.h b/source/blender/blenkernel/BKE_tessmesh.h index 6967f1b2951..9462822e25f 100644 --- a/source/blender/blenkernel/BKE_tessmesh.h +++ b/source/blender/blenkernel/BKE_tessmesh.h @@ -80,7 +80,6 @@ typedef struct BMEditMesh { /*temp variables for x-mirror editing*/ int mirror_cdlayer; /* -1 is invalid */ - int mirr_free_arrays; } BMEditMesh; void BMEdit_RecalcTessellation(BMEditMesh *em); diff --git a/source/blender/editors/include/ED_mesh.h b/source/blender/editors/include/ED_mesh.h index 06e94e0dbda..23c67f837b8 100644 --- a/source/blender/editors/include/ED_mesh.h +++ b/source/blender/editors/include/ED_mesh.h @@ -89,8 +89,12 @@ void EDBM_mesh_make(struct ToolSettings *ts, struct Scene *scene, struct Object void EDBM_mesh_free(struct BMEditMesh *em); void EDBM_mesh_load(struct Object *ob); +void EDBM_index_arrays_ensure(struct BMEditMesh *em, const char htype); void EDBM_index_arrays_init(struct BMEditMesh *em, const char htype); void EDBM_index_arrays_free(struct BMEditMesh *em); +#ifdef DEBUG +int EDBM_index_arrays_check(struct BMEditMesh *em); +#endif struct BMVert *EDBM_vert_at_index(struct BMEditMesh *em, int index); struct BMEdge *EDBM_edge_at_index(struct BMEditMesh *em, int index); struct BMFace *EDBM_face_at_index(struct BMEditMesh *em, int index); @@ -115,7 +119,8 @@ int EDBM_vert_color_check(struct BMEditMesh *em); void EDBM_mesh_hide(struct BMEditMesh *em, int swap); void EDBM_mesh_reveal(struct BMEditMesh *em); -void EDBM_update_generic(struct bContext *C, struct BMEditMesh *em, const short do_tessface); +void EDBM_update_generic(struct bContext *C, struct BMEditMesh *em, + const short do_tessface, const short is_destructive); struct UvElementMap *EDBM_uv_element_map_create(struct BMEditMesh *em, int selected, int doIslands); void EDBM_uv_element_map_free(struct UvElementMap *vmap); @@ -126,7 +131,7 @@ struct MTexPoly *EDBM_mtexpoly_active_get(struct BMEditMesh *em, struct BMFace * void EDBM_uv_vert_map_free(struct UvVertMap *vmap); struct UvMapVert *EDBM_uv_vert_map_at_index(struct UvVertMap *vmap, unsigned int v); -struct UvVertMap *EDBM_uv_vert_map_create(struct BMEditMesh *em, int selected, int do_face_idx_array, const float limit[2]); +struct UvVertMap *EDBM_uv_vert_map_create(struct BMEditMesh *em, int selected, const float limit[2]); void EDBM_flag_enable_all(struct BMEditMesh *em, const char hflag); void EDBM_flag_disable_all(struct BMEditMesh *em, const char hflag); diff --git a/source/blender/editors/mesh/editface.c b/source/blender/editors/mesh/editface.c index 8c0777b2426..05f2269c359 100644 --- a/source/blender/editors/mesh/editface.c +++ b/source/blender/editors/mesh/editface.c @@ -852,7 +852,7 @@ void ED_mesh_mirrtopo_init(Mesh *me, const int ob_mode, MirrTopoStore_t *mesh_to if (em) { if (skip_em_vert_array_init == FALSE) { - EDBM_index_arrays_init(em, BM_VERT); + EDBM_index_arrays_ensure(em, BM_VERT); } } @@ -888,11 +888,6 @@ void ED_mesh_mirrtopo_init(Mesh *me, const int ob_mode, MirrTopoStore_t *mesh_to last = a; } } - if (em) { - if (skip_em_vert_array_init == FALSE) { - EDBM_index_arrays_free(em); - } - } MEM_freeN(topo_pairs); topo_pairs = NULL; diff --git a/source/blender/editors/mesh/editmesh_add.c b/source/blender/editors/mesh/editmesh_add.c index 763c6c98a99..94ff32c5aed 100644 --- a/source/blender/editors/mesh/editmesh_add.c +++ b/source/blender/editors/mesh/editmesh_add.c @@ -90,7 +90,7 @@ static void make_prim_finish(bContext *C, Object *obedit, int *state, int enter_ EDBM_selectmode_flush_ex(em, SCE_SELECT_VERTEX); /* only recalc editmode tessface if we are staying in editmode */ - EDBM_update_generic(C, em, !exit_editmode); + EDBM_update_generic(C, em, !exit_editmode, TRUE); /* userdef */ if (exit_editmode) { diff --git a/source/blender/editors/mesh/editmesh_knife.c b/source/blender/editors/mesh/editmesh_knife.c index b7b71be0df9..31415cf98d2 100644 --- a/source/blender/editors/mesh/editmesh_knife.c +++ b/source/blender/editors/mesh/editmesh_knife.c @@ -2841,7 +2841,7 @@ static void knifetool_finish(bContext *C, wmOperator *op) #endif EDBM_mesh_normals_update(kcd->em); - EDBM_update_generic(C, kcd->em, TRUE); + EDBM_update_generic(C, kcd->em, TRUE, TRUE); } /* copied from paint_image.c */ diff --git a/source/blender/editors/mesh/editmesh_rip.c b/source/blender/editors/mesh/editmesh_rip.c index 9b8f90bc7cf..01a2579520a 100644 --- a/source/blender/editors/mesh/editmesh_rip.c +++ b/source/blender/editors/mesh/editmesh_rip.c @@ -1044,7 +1044,7 @@ static int edbm_rip_invoke(bContext *C, wmOperator *op, wmEvent *event) return OPERATOR_CANCELLED; } - EDBM_update_generic(C, em, TRUE); + EDBM_update_generic(C, em, TRUE, TRUE); return OPERATOR_FINISHED; } diff --git a/source/blender/editors/mesh/editmesh_select.c b/source/blender/editors/mesh/editmesh_select.c index a98345cacec..e3f918b66c9 100644 --- a/source/blender/editors/mesh/editmesh_select.c +++ b/source/blender/editors/mesh/editmesh_select.c @@ -725,7 +725,7 @@ static int similar_face_select_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } - EDBM_update_generic(C, em, FALSE); + EDBM_update_generic(C, em, FALSE, FALSE); /* we succeeded */ return OPERATOR_FINISHED; @@ -767,7 +767,7 @@ static int similar_edge_select_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } - EDBM_update_generic(C, em, FALSE); + EDBM_update_generic(C, em, FALSE, FALSE); /* we succeeded */ return OPERATOR_FINISHED; @@ -812,7 +812,7 @@ static int similar_vert_select_exec(bContext *C, wmOperator *op) EDBM_selectmode_flush(em); - EDBM_update_generic(C, em, FALSE); + EDBM_update_generic(C, em, FALSE, FALSE); /* we succeeded */ return OPERATOR_FINISHED; @@ -1487,7 +1487,7 @@ static int mouse_mesh_shortest_path_edge(bContext *C, ViewContext *vc) break; } - EDBM_update_generic(C, em, FALSE); + EDBM_update_generic(C, em, FALSE, FALSE); return TRUE; } @@ -1678,7 +1678,7 @@ static int mouse_mesh_shortest_path_face(bContext *C, ViewContext *vc) BM_active_face_set(em->bm, f_dst); - EDBM_update_generic(C, em, FALSE); + EDBM_update_generic(C, em, FALSE, FALSE); return TRUE; } @@ -2635,7 +2635,7 @@ static int edbm_select_nth_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } - EDBM_update_generic(C, em, FALSE); + EDBM_update_generic(C, em, FALSE, FALSE); return OPERATOR_FINISHED; } diff --git a/source/blender/editors/mesh/editmesh_slide.c b/source/blender/editors/mesh/editmesh_slide.c index 4fbe9c2534f..d5ca2e928da 100644 --- a/source/blender/editors/mesh/editmesh_slide.c +++ b/source/blender/editors/mesh/editmesh_slide.c @@ -264,7 +264,7 @@ static void vtx_slide_confirm(bContext *C, wmOperator *op) EDBM_selectmode_flush(em); /* NC_GEOM | ND_DATA & Retess */ - EDBM_update_generic(C, em, TRUE); + EDBM_update_generic(C, em, TRUE, FALSE); ED_region_tag_redraw(vso->active_region); } @@ -752,7 +752,7 @@ static int edbm_vertex_slide_exec_ex(bContext *C, wmOperator *op, const int do_u if (do_update) { /* Update Geometry */ - EDBM_update_generic(C, em, TRUE); + EDBM_update_generic(C, em, TRUE, FALSE); } return OPERATOR_FINISHED; diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c index ad1077156ba..41d5cedbc2c 100644 --- a/source/blender/editors/mesh/editmesh_tools.c +++ b/source/blender/editors/mesh/editmesh_tools.c @@ -112,7 +112,7 @@ static int edbm_subdivide_exec(bContext *C, wmOperator *op) RNA_boolean_get(op->ptr, "quadtri"), TRUE, FALSE, RNA_int_get(op->ptr, "seed")); - EDBM_update_generic(C, em, TRUE); + EDBM_update_generic(C, em, TRUE, TRUE); return OPERATOR_FINISHED; } @@ -181,7 +181,7 @@ static int edbm_unsubdivide_exec(bContext *C, wmOperator *op) } EDBM_selectmode_flush(em); - EDBM_update_generic(C, em, TRUE); + EDBM_update_generic(C, em, TRUE, TRUE); return OPERATOR_FINISHED; } @@ -463,7 +463,7 @@ static int edbm_extrude_repeat_exec(bContext *C, wmOperator *op) EDBM_mesh_normals_update(em); - EDBM_update_generic(C, em, TRUE); + EDBM_update_generic(C, em, TRUE, TRUE); return OPERATOR_FINISHED; } @@ -585,7 +585,7 @@ static int edbm_extrude_region_exec(bContext *C, wmOperator *op) * done.*/ EDBM_mesh_normals_update(em); - EDBM_update_generic(C, em, TRUE); + EDBM_update_generic(C, em, TRUE, TRUE); return OPERATOR_FINISHED; } @@ -678,7 +678,7 @@ static int edbm_extrude_faces_exec(bContext *C, wmOperator *op) edbm_extrude_discrete_faces(em, op, BM_ELEM_SELECT, nor); - EDBM_update_generic(C, em, TRUE); + EDBM_update_generic(C, em, TRUE, TRUE); return OPERATOR_FINISHED; } @@ -936,7 +936,7 @@ static int edbm_dupli_extrude_cursor_invoke(bContext *C, wmOperator *op, wmEvent * done. */ EDBM_mesh_normals_update(vc.em); - EDBM_update_generic(C, vc.em, TRUE); + EDBM_update_generic(C, vc.em, TRUE, TRUE); return OPERATOR_FINISHED; } @@ -1001,7 +1001,7 @@ static int edbm_delete_exec(bContext *C, wmOperator *op) EDBM_flag_disable_all(em, BM_ELEM_SELECT); - EDBM_update_generic(C, em, TRUE); + EDBM_update_generic(C, em, TRUE, TRUE); return OPERATOR_FINISHED; } @@ -1034,7 +1034,7 @@ static int edbm_collapse_edge_exec(bContext *C, wmOperator *op) if (!EDBM_op_callf(em, op, "collapse edges=%he", BM_ELEM_SELECT)) return OPERATOR_CANCELLED; - EDBM_update_generic(C, em, TRUE); + EDBM_update_generic(C, em, TRUE, TRUE); return OPERATOR_FINISHED; } @@ -1062,7 +1062,7 @@ static int edbm_collapse_edge_loop_exec(bContext *C, wmOperator *op) if (!EDBM_op_callf(em, op, "dissolve_edge_loop edges=%he", BM_ELEM_SELECT)) return OPERATOR_CANCELLED; - EDBM_update_generic(C, em, TRUE); + EDBM_update_generic(C, em, TRUE, TRUE); return OPERATOR_FINISHED; } @@ -1121,7 +1121,7 @@ static int edbm_add_edge_face_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } - EDBM_update_generic(C, em, TRUE); + EDBM_update_generic(C, em, TRUE, TRUE); return OPERATOR_FINISHED; } @@ -1176,7 +1176,7 @@ static int edbm_mark_seam(bContext *C, wmOperator *op) } ED_uvedit_live_unwrap(scene, obedit); - EDBM_update_generic(C, em, TRUE); + EDBM_update_generic(C, em, TRUE, FALSE); return OPERATOR_FINISHED; } @@ -1230,7 +1230,7 @@ static int edbm_mark_sharp(bContext *C, wmOperator *op) } } - EDBM_update_generic(C, em, TRUE); + EDBM_update_generic(C, em, TRUE, FALSE); return OPERATOR_FINISHED; } @@ -1272,7 +1272,7 @@ static int edbm_vert_connect(bContext *C, wmOperator *op) else { EDBM_selectmode_flush(em); /* so newly created edges get the selection state from the vertex */ - EDBM_update_generic(C, em, TRUE); + EDBM_update_generic(C, em, TRUE, TRUE); return len ? OPERATOR_FINISHED : OPERATOR_CANCELLED; } @@ -1310,7 +1310,7 @@ static int edbm_edge_split_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } - EDBM_update_generic(C, em, TRUE); + EDBM_update_generic(C, em, TRUE, TRUE); return len ? OPERATOR_FINISHED : OPERATOR_CANCELLED; } @@ -1349,7 +1349,7 @@ static int edbm_duplicate_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } - EDBM_update_generic(C, em, TRUE); + EDBM_update_generic(C, em, TRUE, TRUE); return OPERATOR_FINISHED; } @@ -1388,7 +1388,7 @@ static int edbm_flip_normals_exec(bContext *C, wmOperator *op) if (!EDBM_op_callf(em, op, "reverse_faces faces=%hf", BM_ELEM_SELECT)) return OPERATOR_CANCELLED; - EDBM_update_generic(C, em, TRUE); + EDBM_update_generic(C, em, TRUE, FALSE); return OPERATOR_FINISHED; } @@ -1469,7 +1469,7 @@ static int edbm_edge_rotate_selected_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } - EDBM_update_generic(C, em, TRUE); + EDBM_update_generic(C, em, TRUE, TRUE); return OPERATOR_FINISHED; } @@ -1500,7 +1500,7 @@ static int edbm_hide_exec(bContext *C, wmOperator *op) EDBM_mesh_hide(em, RNA_boolean_get(op->ptr, "unselected")); - EDBM_update_generic(C, em, TRUE); + EDBM_update_generic(C, em, TRUE, FALSE); return OPERATOR_FINISHED; } @@ -1530,7 +1530,7 @@ static int edbm_reveal_exec(bContext *C, wmOperator *UNUSED(op)) EDBM_mesh_reveal(em); - EDBM_update_generic(C, em, TRUE); + EDBM_update_generic(C, em, TRUE, FALSE); return OPERATOR_FINISHED; } @@ -1563,7 +1563,7 @@ static int edbm_normals_make_consistent_exec(bContext *C, wmOperator *op) if (RNA_boolean_get(op->ptr, "inside")) EDBM_op_callf(em, op, "reverse_faces faces=%hf", BM_ELEM_SELECT); - EDBM_update_generic(C, em, TRUE); + EDBM_update_generic(C, em, TRUE, FALSE); return OPERATOR_FINISHED; } @@ -1645,7 +1645,7 @@ static int edbm_do_smooth_vertex_exec(bContext *C, wmOperator *op) EDBM_verts_mirror_cache_end(em); } - EDBM_update_generic(C, em, TRUE); + EDBM_update_generic(C, em, TRUE, FALSE); return OPERATOR_FINISHED; } @@ -1721,7 +1721,7 @@ static int edbm_do_smooth_laplacian_vertex_exec(bContext *C, wmOperator *op) EDBM_verts_mirror_cache_end(em); } - EDBM_update_generic(C, em, TRUE); + EDBM_update_generic(C, em, TRUE, FALSE); return OPERATOR_FINISHED; } @@ -1775,7 +1775,7 @@ static int edbm_faces_shade_smooth_exec(bContext *C, wmOperator *UNUSED(op)) mesh_set_smooth_faces(em, 1); - EDBM_update_generic(C, em, FALSE); + EDBM_update_generic(C, em, FALSE, FALSE); return OPERATOR_FINISHED; } @@ -1802,7 +1802,7 @@ static int edbm_faces_shade_flat_exec(bContext *C, wmOperator *UNUSED(op)) mesh_set_smooth_faces(em, 0); - EDBM_update_generic(C, em, FALSE); + EDBM_update_generic(C, em, FALSE, FALSE); return OPERATOR_FINISHED; } @@ -1845,7 +1845,7 @@ static int edbm_rotate_uvs_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } - EDBM_update_generic(C, em, FALSE); + EDBM_update_generic(C, em, FALSE, FALSE); /* we succeeded */ return OPERATOR_FINISHED; @@ -1868,7 +1868,7 @@ static int edbm_reverse_uvs_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } - EDBM_update_generic(C, em, FALSE); + EDBM_update_generic(C, em, FALSE, FALSE); /* we succeeded */ return OPERATOR_FINISHED; @@ -1895,7 +1895,7 @@ static int edbm_rotate_colors_exec(bContext *C, wmOperator *op) } /* dependencies graph and notification stuff */ - EDBM_update_generic(C, em, FALSE); + EDBM_update_generic(C, em, FALSE, FALSE); /* we succeeded */ return OPERATOR_FINISHED; @@ -1919,7 +1919,7 @@ static int edbm_reverse_colors_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } - EDBM_update_generic(C, em, FALSE); + EDBM_update_generic(C, em, FALSE, FALSE); /* we succeeded */ return OPERATOR_FINISHED; @@ -2104,7 +2104,7 @@ static int edbm_merge_exec(bContext *C, wmOperator *op) if (!status) return OPERATOR_CANCELLED; - EDBM_update_generic(C, em, TRUE); + EDBM_update_generic(C, em, TRUE, TRUE); return OPERATOR_FINISHED; } @@ -2221,7 +2221,7 @@ static int edbm_remove_doubles_exec(bContext *C, wmOperator *op) count = totvert_orig - em->bm->totvert; BKE_reportf(op->reports, RPT_INFO, "Removed %d vertices", count); - EDBM_update_generic(C, em, TRUE); + EDBM_update_generic(C, em, TRUE, TRUE); return OPERATOR_FINISHED; } @@ -2328,7 +2328,7 @@ static int edbm_select_vertex_path_exec(bContext *C, wmOperator *op) EDBM_selectmode_flush(em); - EDBM_update_generic(C, em, FALSE); + EDBM_update_generic(C, em, FALSE, FALSE); /* we succeeded */ return OPERATOR_FINISHED; @@ -2403,7 +2403,7 @@ static int edbm_shape_propagate_to_all_exec(bContext *C, wmOperator *op) shape_propagate(em, op); - EDBM_update_generic(C, em, FALSE); + EDBM_update_generic(C, em, FALSE, FALSE); return OPERATOR_FINISHED; } @@ -2474,7 +2474,7 @@ static int edbm_blend_from_shape_exec(bContext *C, wmOperator *op) } } - EDBM_update_generic(C, em, TRUE); + EDBM_update_generic(C, em, TRUE, FALSE); return OPERATOR_FINISHED; } @@ -2665,7 +2665,7 @@ static int edbm_solidify_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } - EDBM_update_generic(C, em, TRUE); + EDBM_update_generic(C, em, TRUE, TRUE); return OPERATOR_FINISHED; } @@ -2990,7 +2990,7 @@ static int edbm_knife_cut_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } - EDBM_update_generic(C, em, TRUE); + EDBM_update_generic(C, em, TRUE, TRUE); return OPERATOR_FINISHED; } @@ -3232,7 +3232,7 @@ static int edbm_separate_exec(bContext *C, wmOperator *op) else BLI_assert(0); if (retval) { - EDBM_update_generic(C, em, TRUE); + EDBM_update_generic(C, em, TRUE, TRUE); } } else { @@ -3332,7 +3332,7 @@ static int edbm_fill_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } - EDBM_update_generic(C, em, TRUE); + EDBM_update_generic(C, em, TRUE, TRUE); return OPERATOR_FINISHED; @@ -3361,7 +3361,7 @@ static int edbm_beautify_fill_exec(bContext *C, wmOperator *op) if (!EDBM_op_callf(em, op, "beautify_fill faces=%hf", BM_ELEM_SELECT)) return OPERATOR_CANCELLED; - EDBM_update_generic(C, em, TRUE); + EDBM_update_generic(C, em, TRUE, TRUE); return OPERATOR_FINISHED; } @@ -3392,7 +3392,7 @@ static int edbm_quads_convert_to_tris_exec(bContext *C, wmOperator *op) if (!EDBM_op_callf(em, op, "triangulate faces=%hf use_beauty=%b", BM_ELEM_SELECT, use_beauty)) return OPERATOR_CANCELLED; - EDBM_update_generic(C, em, TRUE); + EDBM_update_generic(C, em, TRUE, TRUE); return OPERATOR_FINISHED; } @@ -3433,7 +3433,7 @@ static int edbm_tris_convert_to_quads_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } - EDBM_update_generic(C, em, TRUE); + EDBM_update_generic(C, em, TRUE, TRUE); return OPERATOR_FINISHED; } @@ -3489,7 +3489,7 @@ static int edbm_dissolve_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } - EDBM_update_generic(C, em, TRUE); + EDBM_update_generic(C, em, TRUE, TRUE); return OPERATOR_FINISHED; } @@ -3561,7 +3561,7 @@ static int edbm_dissolve_limited_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } - EDBM_update_generic(C, em, TRUE); + EDBM_update_generic(C, em, TRUE, TRUE); return OPERATOR_FINISHED; } @@ -3606,7 +3606,7 @@ static int edbm_split_exec(bContext *C, wmOperator *op) /* Geometry has changed, need to recalc normals and looptris */ EDBM_mesh_normals_update(em); - EDBM_update_generic(C, em, TRUE); + EDBM_update_generic(C, em, TRUE, TRUE); return OPERATOR_FINISHED; } @@ -3665,7 +3665,7 @@ static int edbm_spin_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } - EDBM_update_generic(C, em, TRUE); + EDBM_update_generic(C, em, TRUE, TRUE); return OPERATOR_FINISHED; } @@ -3788,7 +3788,7 @@ static int edbm_screw_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } - EDBM_update_generic(C, em, TRUE); + EDBM_update_generic(C, em, TRUE, TRUE); return OPERATOR_FINISHED; } @@ -4603,7 +4603,7 @@ static int edbm_noise_exec(bContext *C, wmOperator *op) EDBM_mesh_normals_update(em); - EDBM_update_generic(C, em, TRUE); + EDBM_update_generic(C, em, TRUE, FALSE); return OPERATOR_FINISHED; } @@ -4827,7 +4827,7 @@ static int edbm_bevel_calc(bContext *C, wmOperator *op) EDBM_mesh_normals_update(opdata->em); - EDBM_update_generic(C, opdata->em, TRUE); + EDBM_update_generic(C, opdata->em, TRUE, TRUE); return 1; } @@ -4859,7 +4859,7 @@ static int edbm_bevel_cancel(bContext *C, wmOperator *op) BevelData *opdata = op->customdata; if (opdata->is_modal) { EDBM_redo_state_free(&opdata->mesh_backup, opdata->em, TRUE); - EDBM_update_generic(C, opdata->em, FALSE); + EDBM_update_generic(C, opdata->em, FALSE, TRUE); } edbm_bevel_exit(C, op); @@ -5140,7 +5140,7 @@ static int edbm_bridge_edge_loops_exec(bContext *C, wmOperator *op) } else { - EDBM_update_generic(C, em, TRUE); + EDBM_update_generic(C, em, TRUE, TRUE); return OPERATOR_FINISHED; } } @@ -5263,7 +5263,7 @@ static int edbm_inset_cancel(bContext *C, wmOperator *op) opdata = op->customdata; if (opdata->is_modal) { EDBM_redo_state_free(&opdata->backup, opdata->em, TRUE); - EDBM_update_generic(C, opdata->em, FALSE); + EDBM_update_generic(C, opdata->em, FALSE, TRUE); } edbm_inset_exit(C, op); @@ -5318,7 +5318,7 @@ static int edbm_inset_calc(bContext *C, wmOperator *op) return 0; } else { - EDBM_update_generic(C, em, TRUE); + EDBM_update_generic(C, em, TRUE, TRUE); return 1; } } @@ -5581,7 +5581,7 @@ static int edbm_wireframe_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } else { - EDBM_update_generic(C, em, TRUE); + EDBM_update_generic(C, em, TRUE, TRUE); return OPERATOR_FINISHED; } } @@ -5671,7 +5671,7 @@ static int edbm_convex_hull_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } else { - EDBM_update_generic(C, em, TRUE); + EDBM_update_generic(C, em, TRUE, TRUE); EDBM_selectmode_flush(em); return OPERATOR_FINISHED; } @@ -5726,7 +5726,7 @@ static int mesh_symmetrize_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } else { - EDBM_update_generic(C, em, TRUE); + EDBM_update_generic(C, em, TRUE, TRUE); EDBM_selectmode_flush(em); return OPERATOR_FINISHED; } diff --git a/source/blender/editors/mesh/editmesh_utils.c b/source/blender/editors/mesh/editmesh_utils.c index 7259559603a..61bce9f8d1e 100644 --- a/source/blender/editors/mesh/editmesh_utils.c +++ b/source/blender/editors/mesh/editmesh_utils.c @@ -391,11 +391,13 @@ void EDBM_mesh_free(BMEditMesh *em) BMEdit_Free(em); } -void EDBM_index_arrays_init(BMEditMesh *em, const char htype) + +void EDBM_index_arrays_ensure(BMEditMesh *em, const char htype) { BLI_assert((htype & ~BM_ALL_NOLOOP) == 0); - EDBM_index_arrays_free(em); + /* in debug mode double check we didn't need to recalculate */ + BLI_assert(EDBM_index_arrays_check(em) == TRUE); if (htype & BM_VERT) { em->vert_index = MEM_mallocN(sizeof(void **) * em->bm->totvert, "em->vert_index"); @@ -430,6 +432,16 @@ void EDBM_index_arrays_init(BMEditMesh *em, const char htype) } } +/* use EDBM_index_arrays_ensure where possible to avoid full rebuild */ +void EDBM_index_arrays_init(BMEditMesh *em, const char htype) +{ + BLI_assert((htype & ~BM_ALL_NOLOOP) == 0); + + /* force recalc */ + EDBM_index_arrays_free(em); + EDBM_index_arrays_ensure(em, htype); +} + void EDBM_index_arrays_free(BMEditMesh *em) { if (em->vert_index) { @@ -448,6 +460,42 @@ void EDBM_index_arrays_free(BMEditMesh *em) } } +/* debug check only - no need to optimize */ +#ifdef DEBUG +int EDBM_index_arrays_check(BMEditMesh *em) +{ + BMIter iter; + BMElem *ele; + int i; + + if (em->vert_index) { + BM_ITER_MESH_INDEX (ele, &iter, em->bm, BM_VERTS_OF_MESH, i) { + if (ele != (BMElem *)em->vert_index[i]) { + return FALSE; + } + } + } + + if (em->edge_index) { + BM_ITER_MESH_INDEX (ele, &iter, em->bm, BM_EDGES_OF_MESH, i) { + if (ele != (BMElem *)em->edge_index[i]) { + return FALSE; + } + } + } + + if (em->face_index) { + BM_ITER_MESH_INDEX (ele, &iter, em->bm, BM_FACES_OF_MESH, i) { + if (ele != (BMElem *)em->face_index[i]) { + return FALSE; + } + } + } + + return TRUE; +} +#endif + BMVert *EDBM_vert_at_index(BMEditMesh *em, int index) { return em->vert_index && index < em->bm->totvert ? em->vert_index[index] : NULL; @@ -634,7 +682,7 @@ void undo_push_mesh(bContext *C, const char *name) } /* write comment here */ -UvVertMap *EDBM_uv_vert_map_create(BMEditMesh *em, int selected, int do_face_idx_array, const float limit[2]) +UvVertMap *EDBM_uv_vert_map_create(BMEditMesh *em, int selected, const float limit[2]) { BMVert *ev; BMFace *efa; @@ -647,11 +695,8 @@ UvVertMap *EDBM_uv_vert_map_create(BMEditMesh *em, int selected, int do_face_idx MLoopUV *luv; unsigned int a; int totverts, i, totuv; - - if (do_face_idx_array) - EDBM_index_arrays_init(em, BM_FACE); - BM_mesh_elem_index_ensure(em->bm, BM_VERT); + BM_mesh_elem_index_ensure(em->bm, BM_VERT | BM_FACE); totverts = em->bm->totvert; totuv = 0; @@ -663,14 +708,10 @@ UvVertMap *EDBM_uv_vert_map_create(BMEditMesh *em, int selected, int do_face_idx } if (totuv == 0) { - if (do_face_idx_array) - EDBM_index_arrays_free(em); return NULL; } vmap = (UvVertMap *)MEM_callocN(sizeof(*vmap), "UvVertMap"); if (!vmap) { - if (do_face_idx_array) - EDBM_index_arrays_free(em); return NULL; } @@ -679,8 +720,6 @@ UvVertMap *EDBM_uv_vert_map_create(BMEditMesh *em, int selected, int do_face_idx if (!vmap->vert || !vmap->buf) { BKE_mesh_uv_vert_map_free(vmap); - if (do_face_idx_array) - EDBM_index_arrays_free(em); return NULL; } @@ -757,10 +796,7 @@ UvVertMap *EDBM_uv_vert_map_create(BMEditMesh *em, int selected, int do_face_idx vmap->vert[a] = newvlist; a++; } - - if (do_face_idx_array) - EDBM_index_arrays_free(em); - + return vmap; } @@ -1105,10 +1141,7 @@ void EDBM_verts_mirror_cache_begin(BMEditMesh *em, const short use_select) topo = 1; } - if (!em->vert_index) { - EDBM_index_arrays_init(em, BM_VERT); - em->mirr_free_arrays = 1; - } + EDBM_index_arrays_ensure(em, BM_VERT); if (!CustomData_get_layer_named(&bm->vdata, CD_PROP_INT, BM_CD_LAYER_ID)) { BM_data_layer_add_named(bm, &bm->vdata, CD_PROP_INT, BM_CD_LAYER_ID); @@ -1200,11 +1233,6 @@ void EDBM_verts_mirror_cache_clear(BMEditMesh *em, BMVert *v) void EDBM_verts_mirror_cache_end(BMEditMesh *em) { - if (em->mirr_free_arrays) { - MEM_freeN(em->vert_index); - em->vert_index = NULL; - } - em->mirror_cdlayer = -1; } @@ -1309,7 +1337,8 @@ void EDBM_mesh_reveal(BMEditMesh *em) /* so many tools call these that we better make it a generic function. */ -void EDBM_update_generic(bContext *C, BMEditMesh *em, const short do_tessface) +void EDBM_update_generic(bContext *C, BMEditMesh *em, + const short do_tessface, const short is_destructive) { Object *ob = em->ob; /* order of calling isn't important */ @@ -1319,4 +1348,12 @@ void EDBM_update_generic(bContext *C, BMEditMesh *em, const short do_tessface) if (do_tessface) { BMEdit_RecalcTessellation(em); } + + if (is_destructive) { + EDBM_index_arrays_free(em); + } + else { + /* in debug mode double check we didn't need to recalculate */ + BLI_assert(EDBM_index_arrays_check(em) == TRUE); + } } diff --git a/source/blender/editors/mesh/mesh_navmesh.c b/source/blender/editors/mesh/mesh_navmesh.c index bae2c6cde9d..21564d2d348 100644 --- a/source/blender/editors/mesh/mesh_navmesh.c +++ b/source/blender/editors/mesh/mesh_navmesh.c @@ -375,7 +375,7 @@ static Object *createRepresentation(bContext *C, struct recast_polyMesh *pmesh, BM_vert_create(em->bm, co, NULL, 0); } - EDBM_index_arrays_init(em, BM_VERT); + EDBM_index_arrays_ensure(em, BM_VERT); /* create faces */ for (j = 0; j < trinum; j++) { @@ -399,8 +399,6 @@ static Object *createRepresentation(bContext *C, struct recast_polyMesh *pmesh, polygonIdx = (int *)CustomData_bmesh_get(&em->bm->pdata, newFace->head.data, CD_RECAST); *polygonIdx = i + 1; /* add 1 to avoid zero idx */ } - - EDBM_index_arrays_free(em); } recast_destroyPolyMesh(pmesh); diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c index 75fe1e27bf5..780b7426d51 100644 --- a/source/blender/editors/space_view3d/drawobject.c +++ b/source/blender/editors/space_view3d/drawobject.c @@ -2838,7 +2838,7 @@ static void draw_em_fancy(Scene *scene, View3D *v3d, RegionView3D *rv3d, } } - EDBM_index_arrays_init(em, BM_VERT | BM_EDGE | BM_FACE); + EDBM_index_arrays_ensure(em, BM_VERT | BM_EDGE | BM_FACE); if (dt > OB_WIRE) { if (check_object_draw_texture(scene, v3d, dt)) { @@ -2989,8 +2989,6 @@ static void draw_em_fancy(Scene *scene, View3D *v3d, RegionView3D *rv3d, bglPolygonOffset(rv3d->dist, 0.0); GPU_disable_material(); } - - EDBM_index_arrays_free(em); } /* Mesh drawing routines */ @@ -7123,7 +7121,7 @@ void draw_object_backbufsel(Scene *scene, View3D *v3d, RegionView3D *rv3d, Objec DerivedMesh *dm = editbmesh_get_derived_cage(scene, ob, em, CD_MASK_BAREMESH); - EDBM_index_arrays_init(em, BM_VERT | BM_EDGE | BM_FACE); + EDBM_index_arrays_ensure(em, BM_VERT | BM_EDGE | BM_FACE); bbs_mesh_solid_EM(em, scene, v3d, ob, dm, ts->selectmode & SCE_SELECT_FACE); if (ts->selectmode & SCE_SELECT_FACE) @@ -7149,8 +7147,6 @@ void draw_object_backbufsel(Scene *scene, View3D *v3d, RegionView3D *rv3d, Objec bglPolygonOffset(rv3d->dist, 0.0); dm->release(dm); - - EDBM_index_arrays_free(em); } else { Mesh *me = ob->data; diff --git a/source/blender/editors/space_view3d/view3d_iterators.c b/source/blender/editors/space_view3d/view3d_iterators.c index 04d47e6cf5d..a0b36e57d69 100644 --- a/source/blender/editors/space_view3d/view3d_iterators.c +++ b/source/blender/editors/space_view3d/view3d_iterators.c @@ -113,9 +113,8 @@ void mesh_foreachScreenVert( ED_view3d_clipping_local(vc->rv3d, vc->obedit->obmat); /* for local clipping lookups */ } - EDBM_index_arrays_init(vc->em, BM_VERT); + EDBM_index_arrays_ensure(vc->em, BM_VERT); dm->foreachMappedVert(dm, mesh_foreachScreenVert__mapFunc, &data); - EDBM_index_arrays_free(vc->em); dm->release(dm); } @@ -172,9 +171,8 @@ void mesh_foreachScreenEdge( ED_view3d_clipping_local(vc->rv3d, vc->obedit->obmat); /* for local clipping lookups */ } - EDBM_index_arrays_init(vc->em, BM_EDGE); + EDBM_index_arrays_ensure(vc->em, BM_EDGE); dm->foreachMappedEdge(dm, mesh_foreachScreenEdge__mapFunc, &data); - EDBM_index_arrays_free(vc->em); dm->release(dm); } @@ -209,9 +207,8 @@ void mesh_foreachScreenFace( ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); - EDBM_index_arrays_init(vc->em, BM_FACE); + EDBM_index_arrays_ensure(vc->em, BM_FACE); dm->foreachMappedFaceCenter(dm, mesh_foreachScreenFace__mapFunc, &data); - EDBM_index_arrays_free(vc->em); dm->release(dm); } diff --git a/source/blender/editors/space_view3d/view3d_snap.c b/source/blender/editors/space_view3d/view3d_snap.c index e60eed42770..f570ec38ae3 100644 --- a/source/blender/editors/space_view3d/view3d_snap.c +++ b/source/blender/editors/space_view3d/view3d_snap.c @@ -340,9 +340,8 @@ static void make_trans_verts(Object *obedit, float min[3], float max[3], int mod } if (transvmain && em->derivedCage) { - EDBM_index_arrays_init(em, BM_VERT); + EDBM_index_arrays_ensure(em, BM_VERT); em->derivedCage->foreachMappedVert(em->derivedCage, set_mapped_co, userdata); - EDBM_index_arrays_free(em); } } else if (obedit->type == OB_ARMATURE) { diff --git a/source/blender/editors/transform/transform_snap.c b/source/blender/editors/transform/transform_snap.c index b1e48448fac..5577619901a 100644 --- a/source/blender/editors/transform/transform_snap.c +++ b/source/blender/editors/transform/transform_snap.c @@ -1417,7 +1417,7 @@ static int snapDerivedMesh(short snap_mode, ARegion *ar, Object *ob, DerivedMesh if (em != NULL) { index_array = dm->getVertDataArray(dm, CD_ORIGINDEX); - EDBM_index_arrays_init(em, BM_VERT); + EDBM_index_arrays_ensure(em, BM_VERT); } for (i = 0; i < totvert; i++) { @@ -1452,9 +1452,6 @@ static int snapDerivedMesh(short snap_mode, ARegion *ar, Object *ob, DerivedMesh } } - if (em != NULL) { - EDBM_index_arrays_free(em); - } break; } case SCE_SNAP_MODE_EDGE: @@ -1468,7 +1465,7 @@ static int snapDerivedMesh(short snap_mode, ARegion *ar, Object *ob, DerivedMesh if (em != NULL) { index_array = dm->getEdgeDataArray(dm, CD_ORIGINDEX); - EDBM_index_arrays_init(em, BM_EDGE); + EDBM_index_arrays_ensure(em, BM_EDGE); } for (i = 0; i < totedge; i++) { @@ -1505,9 +1502,6 @@ static int snapDerivedMesh(short snap_mode, ARegion *ar, Object *ob, DerivedMesh } } - if (em != NULL) { - EDBM_index_arrays_free(em); - } break; } } diff --git a/source/blender/editors/uvedit/uvedit_ops.c b/source/blender/editors/uvedit/uvedit_ops.c index 46b7db32334..4336eb02752 100644 --- a/source/blender/editors/uvedit/uvedit_ops.c +++ b/source/blender/editors/uvedit/uvedit_ops.c @@ -999,8 +999,8 @@ static int select_edgeloop(Scene *scene, Image *ima, BMEditMesh *em, NearestHit int a, looking, nverts, starttotf, select; /* setup */ - EDBM_index_arrays_init(em, BM_FACE); - vmap = EDBM_uv_vert_map_create(em, 0, 0, limit); + EDBM_index_arrays_ensure(em, BM_FACE); + vmap = EDBM_uv_vert_map_create(em, 0, limit); BM_mesh_elem_index_ensure(em->bm, BM_VERT | BM_FACE); @@ -1091,7 +1091,6 @@ static int select_edgeloop(Scene *scene, Image *ima, BMEditMesh *em, NearestHit /* cleanup */ EDBM_uv_vert_map_free(vmap); - EDBM_index_arrays_free(em); return (select) ? 1 : -1; } @@ -1111,8 +1110,8 @@ static void select_linked(Scene *scene, Image *ima, BMEditMesh *em, const float unsigned int a; char *flag; - EDBM_index_arrays_init(em, BM_FACE); /* we can use this too */ - vmap = EDBM_uv_vert_map_create(em, 1, 1, limit); + EDBM_index_arrays_ensure(em, BM_FACE); /* we can use this too */ + vmap = EDBM_uv_vert_map_create(em, 1, limit); if (vmap == NULL) return; @@ -1270,7 +1269,6 @@ static void select_linked(Scene *scene, Image *ima, BMEditMesh *em, const float MEM_freeN(stack); MEM_freeN(flag); EDBM_uv_vert_map_free(vmap); - EDBM_index_arrays_free(em); } /* WATCH IT: this returns first selected UV, @@ -2608,8 +2606,8 @@ static void uv_faces_do_sticky(SpaceImage *sima, Scene *scene, Object *obedit, s uvedit_pixel_to_float(sima, limit, 0.05); - EDBM_index_arrays_init(em, BM_FACE); - vmap = EDBM_uv_vert_map_create(em, 0, 0, limit); + EDBM_index_arrays_ensure(em, BM_FACE); + vmap = EDBM_uv_vert_map_create(em, 0, limit); /* verts are numbered above in make_uv_vert_map_EM, make sure this stays true! */ if (vmap == NULL) { @@ -2662,7 +2660,6 @@ static void uv_faces_do_sticky(SpaceImage *sima, Scene *scene, Object *obedit, s } } } - EDBM_index_arrays_free(em); EDBM_uv_vert_map_free(vmap); } @@ -3795,8 +3792,8 @@ static int seams_from_islands_exec(bContext *C, wmOperator *op) } /* This code sets editvert->tmp.l to the index. This will be useful later on. */ - EDBM_index_arrays_init(em, BM_FACE); - vmap = EDBM_uv_vert_map_create(em, 0, 0, limit); + EDBM_index_arrays_ensure(em, BM_FACE); + vmap = EDBM_uv_vert_map_create(em, 0, limit); BM_ITER_MESH (editedge, &iter, bm, BM_EDGES_OF_MESH) { /* flags to determine if we uv is separated from first editface match */ @@ -3875,7 +3872,6 @@ static int seams_from_islands_exec(bContext *C, wmOperator *op) me->drawflag |= ME_DRAWSEAMS; EDBM_uv_vert_map_free(vmap); - EDBM_index_arrays_free(em); DAG_id_tag_update(&me->id, 0); WM_event_add_notifier(C, NC_GEOM | ND_DATA, me); diff --git a/source/blender/editors/uvedit/uvedit_smart_stitch.c b/source/blender/editors/uvedit/uvedit_smart_stitch.c index b67747ead5a..9c99eb196c2 100644 --- a/source/blender/editors/uvedit/uvedit_smart_stitch.c +++ b/source/blender/editors/uvedit/uvedit_smart_stitch.c @@ -1256,7 +1256,7 @@ static int stitch_init(bContext *C, wmOperator *op) int faceIndex, elementIndex; UvElement *element; - EDBM_index_arrays_init(em, BM_FACE); + EDBM_index_arrays_ensure(em, BM_FACE); RNA_BEGIN (op->ptr, itemptr, "selection") { @@ -1268,7 +1268,6 @@ static int stitch_init(bContext *C, wmOperator *op) } RNA_END; - EDBM_index_arrays_free(em); /* Clear the selection */ RNA_collection_clear(op->ptr, "selection"); diff --git a/source/blender/editors/uvedit/uvedit_unwrap_ops.c b/source/blender/editors/uvedit/uvedit_unwrap_ops.c index 6ef680f368d..6c385527977 100644 --- a/source/blender/editors/uvedit/uvedit_unwrap_ops.c +++ b/source/blender/editors/uvedit/uvedit_unwrap_ops.c @@ -434,7 +434,7 @@ static ParamHandle *construct_param_handle_subsurfed(Scene *scene, Object *ob, B faceMap = MEM_mallocN(numOfFaces * sizeof(BMFace *), "unwrap_edit_face_map"); BM_mesh_elem_index_ensure(em->bm, BM_VERT); - EDBM_index_arrays_init(em, BM_EDGE | BM_FACE); + EDBM_index_arrays_ensure(em, BM_EDGE | BM_FACE); /* map subsurfed faces to original editFaces */ for (i = 0; i < numOfFaces; i++) @@ -449,8 +449,6 @@ static ParamHandle *construct_param_handle_subsurfed(Scene *scene, Object *ob, B EDBM_edge_at_index(em, origEdgeIndices[i]) : NULL; } - EDBM_index_arrays_free(em); - /* Prepare and feed faces to the solver */ for (i = 0; i < numOfFaces; i++) { ParamKey key, vkeys[4]; From 3e8b56b321225b5fce0e02130a3de2f770b19441 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 12 Dec 2012 06:57:41 +0000 Subject: [PATCH 039/252] add destructive argument to bmesh.update_edit_mesh() --- source/blender/python/bmesh/bmesh_py_api.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/source/blender/python/bmesh/bmesh_py_api.c b/source/blender/python/bmesh/bmesh_py_api.c index 18f5d895132..5e6fd1c8019 100644 --- a/source/blender/python/bmesh/bmesh_py_api.c +++ b/source/blender/python/bmesh/bmesh_py_api.c @@ -98,7 +98,7 @@ static PyObject *bpy_bm_from_edit_mesh(PyObject *UNUSED(self), PyObject *value) } PyDoc_STRVAR(bpy_bm_update_edit_mesh_doc, -".. method:: update_edit_mesh(mesh, tessface=True)\n" +".. method:: update_edit_mesh(mesh, tessface=True, destructive=True)\n" "\n" " Update the mesh after changes to the BMesh in editmode, \n" " optionally recalculating n-gon tessellation.\n" @@ -107,14 +107,17 @@ PyDoc_STRVAR(bpy_bm_update_edit_mesh_doc, " :type mesh: :class:`bpy.types.Mesh`\n" " :arg tessface: Option to recalculate n-gon tessellation.\n" " :type tessface: boolean\n" +" :arg destructive: Use when grometry has been added or removed.\n" +" :type destructive: boolean\n" ); static PyObject *bpy_bm_update_edit_mesh(PyObject *UNUSED(self), PyObject *args) { PyObject *py_me; Mesh *me; int do_tessface = TRUE; + int is_destructive = TRUE; - if (!PyArg_ParseTuple(args, "O|i:update_edit_mesh", &py_me, &do_tessface)) { + if (!PyArg_ParseTuple(args, "O|ii:update_edit_mesh", &py_me, &do_tessface, &is_destructive)) { return NULL; } @@ -134,10 +137,11 @@ static PyObject *bpy_bm_update_edit_mesh(PyObject *UNUSED(self), PyObject *args) /* XXX, not great - infact this function could just not use the context at all * postpone that change until after release: BMESH_TODO - campbell */ extern struct bContext *BPy_GetContext(void); - extern void EDBM_update_generic(struct bContext *C, BMEditMesh *em, const short do_tessface); + extern void EDBM_update_generic(struct bContext *C, BMEditMesh *em, + const short do_tessface, const short is_destructive); struct bContext *C = BPy_GetContext(); - EDBM_update_generic(C, me->edit_btmesh, do_tessface); + EDBM_update_generic(C, me->edit_btmesh, do_tessface, is_destructive); } Py_RETURN_NONE; From 2ee180eab678c0b21e92aa0175ad93528d9009ae Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 12 Dec 2012 07:20:34 +0000 Subject: [PATCH 040/252] add threshold for bmesh & openmp so its not used with low poly meshes, BM_OMP_LIMIT may need tweaking. --- source/blender/bmesh/bmesh_class.h | 1 + source/blender/bmesh/intern/bmesh_marking.c | 6 +++--- source/blender/bmesh/intern/bmesh_mesh.c | 4 ++-- source/blender/bmesh/intern/bmesh_operators.c | 8 ++++---- source/blender/editors/mesh/editmesh_utils.c | 4 ++-- 5 files changed, 12 insertions(+), 11 deletions(-) diff --git a/source/blender/bmesh/bmesh_class.h b/source/blender/bmesh/bmesh_class.h index 4a370a24c7d..7520164bf61 100644 --- a/source/blender/bmesh/bmesh_class.h +++ b/source/blender/bmesh/bmesh_class.h @@ -277,5 +277,6 @@ enum { * but should not error on valid cases */ #define BM_LOOP_RADIAL_MAX 10000 #define BM_NGON_MAX 100000 +#define BM_OMP_LIMIT 10000 #endif /* __BMESH_CLASS_H__ */ diff --git a/source/blender/bmesh/intern/bmesh_marking.c b/source/blender/bmesh/intern/bmesh_marking.c index 6093547150c..b1ec4cde44b 100644 --- a/source/blender/bmesh/intern/bmesh_marking.c +++ b/source/blender/bmesh/intern/bmesh_marking.c @@ -165,7 +165,7 @@ void BM_mesh_deselect_flush(BMesh *bm) int ok; /* we can use 2 sections here because the second loop isnt checking edge selection */ -#pragma omp parallel sections +#pragma omp parallel sections if (bm->totedge + bm->totface >= BM_OMP_LIMIT) { #pragma omp section { @@ -227,7 +227,7 @@ void BM_mesh_select_flush(BMesh *bm) int ok; /* we can use 2 sections here because the second loop isnt checking edge selection */ -#pragma omp parallel sections +#pragma omp parallel sections if (bm->totedge + bm->totface >= BM_OMP_LIMIT) { #pragma omp section { @@ -848,7 +848,7 @@ void BM_mesh_elem_hflag_disable_test(BMesh *bm, const char htype, const char hfl /* fast path for deselect all, avoid topology loops * since we know all will be de-selected anyway. */ -#pragma omp parallel for schedule(dynamic) +#pragma omp parallel for schedule(dynamic) if (bm->totvert + bm->totedge + bm->totface >= BM_OMP_LIMIT) for (i = 0; i < 3; i++) { BMIter iter; BMElem *ele; diff --git a/source/blender/bmesh/intern/bmesh_mesh.c b/source/blender/bmesh/intern/bmesh_mesh.c index 8d5bf46a6e5..015c040dc95 100644 --- a/source/blender/bmesh/intern/bmesh_mesh.c +++ b/source/blender/bmesh/intern/bmesh_mesh.c @@ -71,7 +71,7 @@ void BM_mesh_elem_toolflags_ensure(BMesh *bm) bm->etoolflagpool = BLI_mempool_create(sizeof(BMFlagLayer), max_ii(512, bm->totedge), 512, 0); bm->ftoolflagpool = BLI_mempool_create(sizeof(BMFlagLayer), max_ii(512, bm->totface), 512, 0); -#pragma omp parallel sections +#pragma omp parallel sections if (bm->totvert + bm->totedge + bm->totface >= BM_OMP_LIMIT) { #pragma omp section { @@ -468,7 +468,7 @@ void BM_mesh_elem_index_ensure(BMesh *bm, const char hflag) BM_ELEM_INDEX_VALIDATE(bm, "Should Never Fail!", __func__); #endif -#pragma omp parallel sections +#pragma omp parallel sections if (bm->totvert + bm->totedge + bm->totface >= BM_OMP_LIMIT) { #pragma omp section { diff --git a/source/blender/bmesh/intern/bmesh_operators.c b/source/blender/bmesh/intern/bmesh_operators.c index f7dcb8ba483..fbf51b7dfdf 100644 --- a/source/blender/bmesh/intern/bmesh_operators.c +++ b/source/blender/bmesh/intern/bmesh_operators.c @@ -599,7 +599,7 @@ void BMO_mesh_flag_disable_all(BMesh *bm, BMOperator *UNUSED(op), const char hty BMElemF *ele; int i; -#pragma omp parallel for schedule(dynamic) +#pragma omp parallel for schedule(dynamic) if (bm->totvert + bm->totedge + bm->totface >= BM_OMP_LIMIT) for (i = 0; i < 3; i++) { if (htype & flag_types[i]) { BM_ITER_MESH (ele, &iter, bm, iter_types[i]) { @@ -1176,7 +1176,7 @@ static void bmo_flag_layer_alloc(BMesh *bm) bm->etoolflagpool = BLI_mempool_create(sizeof(BMFlagLayer) * bm->totflags, max_ii(512, bm->totedge), 512, 0); bm->ftoolflagpool = BLI_mempool_create(sizeof(BMFlagLayer) * bm->totflags, max_ii(512, bm->totface), 512, 0); -#pragma omp parallel sections +#pragma omp parallel sections if (bm->totvert + bm->totedge + bm->totface >= BM_OMP_LIMIT) { #pragma omp section { @@ -1257,7 +1257,7 @@ static void bmo_flag_layer_free(BMesh *bm) bm->etoolflagpool = BLI_mempool_create(new_totflags_size, bm->totedge, 512, 0); bm->ftoolflagpool = BLI_mempool_create(new_totflags_size, bm->totface, 512, 0); -#pragma omp parallel sections +#pragma omp parallel sections if (bm->totvert + bm->totedge + bm->totface >= BM_OMP_LIMIT) { #pragma omp section { @@ -1328,7 +1328,7 @@ static void bmo_flag_layer_clear(BMesh *bm) BMIter iter; const int totflags_offset = bm->totflags - 1; -#pragma omp parallel sections +#pragma omp parallel sections if (bm->totvert + bm->totedge + bm->totface >= BM_OMP_LIMIT) { /* now go through and memcpy all the flag */ #pragma omp section diff --git a/source/blender/editors/mesh/editmesh_utils.c b/source/blender/editors/mesh/editmesh_utils.c index 61bce9f8d1e..17a9c7df41b 100644 --- a/source/blender/editors/mesh/editmesh_utils.c +++ b/source/blender/editors/mesh/editmesh_utils.c @@ -409,7 +409,7 @@ void EDBM_index_arrays_ensure(BMEditMesh *em, const char htype) em->face_index = MEM_mallocN(sizeof(void **) * em->bm->totface, "em->face_index"); } -#pragma omp parallel sections +#pragma omp parallel sections if (em->bm->totvert + em->bm->totedge + em->bm->totface >= BM_OMP_LIMIT) { #pragma omp section { @@ -1306,7 +1306,7 @@ void EDBM_mesh_reveal(BMEditMesh *em) /* Use tag flag to remember what was hidden before all is revealed. * BM_ELEM_HIDDEN --> BM_ELEM_TAG */ -#pragma omp parallel for schedule(dynamic) +#pragma omp parallel for schedule(dynamic) if (em->bm->totvert + em->bm->totedge + em->bm->totface >= BM_OMP_LIMIT) for (i = 0; i < 3; i++) { BM_ITER_MESH (ele, &iter, em->bm, iter_types[i]) { BM_elem_flag_set(ele, BM_ELEM_TAG, BM_elem_flag_test(ele, BM_ELEM_HIDDEN)); From f06370dd446039227f6045041a3aeb04f0d378cf Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 12 Dec 2012 07:31:22 +0000 Subject: [PATCH 041/252] fix for EDBM_index_arrays_ensure not working as intended. --- source/blender/editors/mesh/editmesh_utils.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/source/blender/editors/mesh/editmesh_utils.c b/source/blender/editors/mesh/editmesh_utils.c index 17a9c7df41b..9852283430a 100644 --- a/source/blender/editors/mesh/editmesh_utils.c +++ b/source/blender/editors/mesh/editmesh_utils.c @@ -394,18 +394,23 @@ void EDBM_mesh_free(BMEditMesh *em) void EDBM_index_arrays_ensure(BMEditMesh *em, const char htype) { + /* assume if the array is non-null then its valid and no need to recalc */ + const char htype_needed = ((em->vert_index ? 0 : BM_VERT) | + (em->edge_index ? 0 : BM_EDGE) | + (em->face_index ? 0 : BM_FACE)) & htype; + BLI_assert((htype & ~BM_ALL_NOLOOP) == 0); /* in debug mode double check we didn't need to recalculate */ BLI_assert(EDBM_index_arrays_check(em) == TRUE); - if (htype & BM_VERT) { + if (htype_needed & BM_VERT) { em->vert_index = MEM_mallocN(sizeof(void **) * em->bm->totvert, "em->vert_index"); } - if (htype & BM_EDGE) { + if (htype_needed & BM_EDGE) { em->edge_index = MEM_mallocN(sizeof(void **) * em->bm->totedge, "em->edge_index"); } - if (htype & BM_FACE) { + if (htype_needed & BM_FACE) { em->face_index = MEM_mallocN(sizeof(void **) * em->bm->totface, "em->face_index"); } @@ -413,19 +418,19 @@ void EDBM_index_arrays_ensure(BMEditMesh *em, const char htype) { #pragma omp section { - if (htype & BM_VERT) { + if (htype_needed & BM_VERT) { BM_iter_as_array(em->bm, BM_VERTS_OF_MESH, NULL, (void **)em->vert_index, em->bm->totvert); } } #pragma omp section { - if (htype & BM_EDGE) { + if (htype_needed & BM_EDGE) { BM_iter_as_array(em->bm, BM_EDGES_OF_MESH, NULL, (void **)em->edge_index, em->bm->totedge); } } #pragma omp section { - if (htype & BM_FACE) { + if (htype_needed & BM_FACE) { BM_iter_as_array(em->bm, BM_FACES_OF_MESH, NULL, (void **)em->face_index, em->bm->totface); } } From 3945979f2b69b2f73f41c0f59b6a40ab13e4a56c Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Wed, 12 Dec 2012 09:17:21 +0000 Subject: [PATCH 042/252] Fix #33486: cycles CPU image textures were offset wrong by half a pixel compared to OpenGL/CUDA/OSL rendering. --- intern/cycles/kernel/kernel_compat_cpu.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/intern/cycles/kernel/kernel_compat_cpu.h b/intern/cycles/kernel/kernel_compat_cpu.h index 45f653a686c..01bb78e8e1c 100644 --- a/intern/cycles/kernel/kernel_compat_cpu.h +++ b/intern/cycles/kernel/kernel_compat_cpu.h @@ -112,8 +112,8 @@ template struct texture_image { return make_float4(0.0f, 0.0f, 0.0f, 0.0f); int ix, iy, nix, niy; - float tx = frac(x*width, &ix); - float ty = frac(y*height, &iy); + float tx = frac(x*width - 0.5f, &ix); + float ty = frac(y*height - 0.5f, &iy); if(periodic) { ix = wrap_periodic(ix, width); From 2713d4d5bd2298c4b978f6e7199d591e71eee951 Mon Sep 17 00:00:00 2001 From: Gaia Clary Date: Wed, 12 Dec 2012 09:49:05 +0000 Subject: [PATCH 043/252] revert recent code cleanup which introduced const parameters --- source/blender/collada/collada_internal.cpp | 4 ++-- source/blender/collada/collada_internal.h | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/source/blender/collada/collada_internal.cpp b/source/blender/collada/collada_internal.cpp index 13ff69d3abf..51d81dc164b 100644 --- a/source/blender/collada/collada_internal.cpp +++ b/source/blender/collada/collada_internal.cpp @@ -85,13 +85,13 @@ void UnitConverter::dae_matrix_to_mat4_(float out[4][4], const COLLADABU::Math:: } } -void UnitConverter::mat4_to_dae(float out[4][4], float const in[4][4]) +void UnitConverter::mat4_to_dae(float out[4][4], float in[4][4]) { copy_m4_m4(out, in); transpose_m4(out); } -void UnitConverter::mat4_to_dae_double(double out[4][4], float const in[4][4]) +void UnitConverter::mat4_to_dae_double(double out[4][4], float in[4][4]) { float mat[4][4]; diff --git a/source/blender/collada/collada_internal.h b/source/blender/collada/collada_internal.h index 5a5126025de..d92f53f714c 100644 --- a/source/blender/collada/collada_internal.h +++ b/source/blender/collada/collada_internal.h @@ -71,9 +71,9 @@ public: void dae_matrix_to_mat4_(float out[4][4], const COLLADABU::Math::Matrix4& in); - void mat4_to_dae(float out[4][4], float const in[4][4]); + void mat4_to_dae(float out[4][4], float in[4][4]); - void mat4_to_dae_double(double out[4][4], float const in[4][4]); + void mat4_to_dae_double(double out[4][4], float in[4][4]); }; class TransformBase From dd2d54bae9ab2b95553c7c3ed04185fcf36a0420 Mon Sep 17 00:00:00 2001 From: "Sv. Lockal" Date: Wed, 12 Dec 2012 10:21:24 +0000 Subject: [PATCH 044/252] Use own list of actions for Vertex Group Lock operator instead of reusing Select All actions. Previous actions and descriptions were confusing, e. g. UnLock All used the description of Deselect All. --- .../startup/bl_ui/properties_data_mesh.py | 4 +-- source/blender/editors/object/object_vgroup.c | 28 ++++++++++++++----- 2 files changed, 23 insertions(+), 9 deletions(-) diff --git a/release/scripts/startup/bl_ui/properties_data_mesh.py b/release/scripts/startup/bl_ui/properties_data_mesh.py index 6125540d491..e33bed7ec6d 100644 --- a/release/scripts/startup/bl_ui/properties_data_mesh.py +++ b/release/scripts/startup/bl_ui/properties_data_mesh.py @@ -36,8 +36,8 @@ class MESH_MT_vertex_group_specials(Menu): layout.operator("object.vertex_group_mirror", icon='ARROW_LEFTRIGHT') layout.operator("object.vertex_group_remove", icon='X', text="Delete All").all = True layout.separator() - layout.operator("object.vertex_group_lock", icon='LOCKED', text="Lock All").action = 'SELECT' - layout.operator("object.vertex_group_lock", icon='UNLOCKED', text="UnLock All").action = 'DESELECT' + layout.operator("object.vertex_group_lock", icon='LOCKED', text="Lock All").action = 'LOCK' + layout.operator("object.vertex_group_lock", icon='UNLOCKED', text="UnLock All").action = 'UNLOCK' layout.operator("object.vertex_group_lock", icon='LOCKED', text="Lock Invert All").action = 'INVERT' diff --git a/source/blender/editors/object/object_vgroup.c b/source/blender/editors/object/object_vgroup.c index 1b135c0686e..dae95a1bffc 100644 --- a/source/blender/editors/object/object_vgroup.c +++ b/source/blender/editors/object/object_vgroup.c @@ -1516,16 +1516,30 @@ static void vgroup_normalize_all(Object *ob, int lock_active) } } +enum { + VGROUP_TOGGLE, + VGROUP_LOCK, + VGROUP_UNLOCK, + VGROUP_INVERT +}; + +static EnumPropertyItem vgroup_lock_actions[] = { + {VGROUP_TOGGLE, "TOGGLE", 0, "Toggle", "Unlock all vertex groups if there is at least one locked group, lock all in other case"}, + {VGROUP_LOCK, "LOCK", 0, "Lock", "Lock all vertex groups"}, + {VGROUP_UNLOCK, "UNLOCK", 0, "Unlock", "Unlock all vertex groups"}, + {VGROUP_INVERT, "INVERT", 0, "Invert", "Invert the lock state of all vertex groups"}, + {0, NULL, 0, NULL, NULL} +}; static void vgroup_lock_all(Object *ob, int action) { bDeformGroup *dg; - if (action == SEL_TOGGLE) { - action = SEL_SELECT; + if (action == VGROUP_TOGGLE) { + action = VGROUP_LOCK; for (dg = ob->defbase.first; dg; dg = dg->next) { if (dg->flag & DG_LOCK_WEIGHT) { - action = SEL_DESELECT; + action = VGROUP_UNLOCK; break; } } @@ -1533,13 +1547,13 @@ static void vgroup_lock_all(Object *ob, int action) for (dg = ob->defbase.first; dg; dg = dg->next) { switch (action) { - case SEL_SELECT: + case VGROUP_LOCK: dg->flag |= DG_LOCK_WEIGHT; break; - case SEL_DESELECT: + case VGROUP_UNLOCK: dg->flag &= ~DG_LOCK_WEIGHT; break; - case SEL_INVERT: + case VGROUP_INVERT: dg->flag ^= DG_LOCK_WEIGHT; break; } @@ -2963,7 +2977,7 @@ void OBJECT_OT_vertex_group_lock(wmOperatorType *ot) /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; - WM_operator_properties_select_all(ot); + RNA_def_enum(ot->srna, "action", vgroup_lock_actions, VGROUP_TOGGLE, "Action", "Lock action to execute on vertex groups"); } static int vertex_group_invert_exec(bContext *C, wmOperator *op) From 0ec099f2828921c6aa69987c9bfe51a4971a8c5d Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Wed, 12 Dec 2012 11:12:37 +0000 Subject: [PATCH 045/252] Sequencer old todo: inserting keyframes with preview opened didn't work Solved in more like a workaround way by not calling BKE_scene_update_for_newframe if scene's frame didn't change. --- source/blender/blenkernel/intern/sequencer.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/source/blender/blenkernel/intern/sequencer.c b/source/blender/blenkernel/intern/sequencer.c index acce3740c98..ea8c60c1eab 100644 --- a/source/blender/blenkernel/intern/sequencer.c +++ b/source/blender/blenkernel/intern/sequencer.c @@ -2408,7 +2408,8 @@ static ImBuf *seq_render_scene_strip(SeqRenderData context, Sequence *seq, float context.scene->r.seq_prev_type = 3 /* == OB_SOLID */; /* opengl offscreen render */ - BKE_scene_update_for_newframe(context.bmain, scene, scene->lay); + if (oldcfra != scene->r.cfra) + BKE_scene_update_for_newframe(context.bmain, scene, scene->lay); ibuf = sequencer_view3d_cb(scene, camera, context.rectx, context.recty, IB_rect, context.scene->r.seq_prev_type, TRUE, FALSE, err_out); if (ibuf == NULL) { @@ -2431,7 +2432,8 @@ static ImBuf *seq_render_scene_strip(SeqRenderData context, Sequence *seq, float if (re == NULL) re = RE_NewRender(scene->id.name); - BKE_scene_update_for_newframe(context.bmain, scene, scene->lay); + if (oldcfra != scene->r.cfra) + BKE_scene_update_for_newframe(context.bmain, scene, scene->lay); RE_BlenderFrame(re, context.bmain, scene, NULL, camera, scene->lay, frame, FALSE); /* restore previous state after it was toggled on & off by RE_BlenderFrame */ From 868cb64d6c4ffad573bb9d7003afdaf06787dd43 Mon Sep 17 00:00:00 2001 From: Ton Roosendaal Date: Wed, 12 Dec 2012 12:18:29 +0000 Subject: [PATCH 046/252] Bug fix [#33492] Right click on 'confirm reload' crashes Context check could result in NULL - added provision for it and made sure the check is local only (for 1 new option) --- source/blender/editors/interface/interface_handlers.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c index b80025e0d77..1ac56fd30bb 100644 --- a/source/blender/editors/interface/interface_handlers.c +++ b/source/blender/editors/interface/interface_handlers.c @@ -4629,7 +4629,6 @@ static void popup_add_shortcut_func(bContext *C, void *arg1, void *UNUSED(arg2)) static int ui_but_menu(bContext *C, uiBut *but) { - ARegion *ar = CTX_wm_region(C); uiPopupMenu *pup; uiLayout *layout; int length; @@ -4845,9 +4844,13 @@ static int ui_but_menu(bContext *C, uiBut *but) } /* Show header tools for header buttons. */ - if (ar->regiontype == RGN_TYPE_HEADER) { - uiItemMenuF(layout, IFACE_("Header"), ICON_NONE, ED_screens_header_tools_menu_create, NULL); - uiItemS(layout); + if (CTX_wm_region(C)) { + ARegion *ar = CTX_wm_region(C); + if (ar->regiontype == RGN_TYPE_HEADER) { + + uiItemMenuF(layout, IFACE_("Header"), ICON_NONE, ED_screens_header_tools_menu_create, NULL); + uiItemS(layout); + } } { /* Docs */ From 743ecc7bd0bb499956ac3a64af9b82214d8164cb Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Wed, 12 Dec 2012 12:23:30 +0000 Subject: [PATCH 047/252] Revert recent workaround for sequencer, it'll only work in cases scene strip is added at frame 1, which is very limited usecase. Proper solution is not possible yet.. --- source/blender/blenkernel/intern/sequencer.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/source/blender/blenkernel/intern/sequencer.c b/source/blender/blenkernel/intern/sequencer.c index ea8c60c1eab..acce3740c98 100644 --- a/source/blender/blenkernel/intern/sequencer.c +++ b/source/blender/blenkernel/intern/sequencer.c @@ -2408,8 +2408,7 @@ static ImBuf *seq_render_scene_strip(SeqRenderData context, Sequence *seq, float context.scene->r.seq_prev_type = 3 /* == OB_SOLID */; /* opengl offscreen render */ - if (oldcfra != scene->r.cfra) - BKE_scene_update_for_newframe(context.bmain, scene, scene->lay); + BKE_scene_update_for_newframe(context.bmain, scene, scene->lay); ibuf = sequencer_view3d_cb(scene, camera, context.rectx, context.recty, IB_rect, context.scene->r.seq_prev_type, TRUE, FALSE, err_out); if (ibuf == NULL) { @@ -2432,8 +2431,7 @@ static ImBuf *seq_render_scene_strip(SeqRenderData context, Sequence *seq, float if (re == NULL) re = RE_NewRender(scene->id.name); - if (oldcfra != scene->r.cfra) - BKE_scene_update_for_newframe(context.bmain, scene, scene->lay); + BKE_scene_update_for_newframe(context.bmain, scene, scene->lay); RE_BlenderFrame(re, context.bmain, scene, NULL, camera, scene->lay, frame, FALSE); /* restore previous state after it was toggled on & off by RE_BlenderFrame */ From b93f02042e503a092d4ce2a3971236c9484dd332 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 12 Dec 2012 12:29:37 +0000 Subject: [PATCH 048/252] use header only tags for edge split (to prepare to move this into tools/) --- .../blender/bmesh/operators/bmo_edgesplit.c | 36 ++++++++----------- 1 file changed, 14 insertions(+), 22 deletions(-) diff --git a/source/blender/bmesh/operators/bmo_edgesplit.c b/source/blender/bmesh/operators/bmo_edgesplit.c index 9e9e4b8c962..81728cea906 100644 --- a/source/blender/bmesh/operators/bmo_edgesplit.c +++ b/source/blender/bmesh/operators/bmo_edgesplit.c @@ -32,16 +32,8 @@ #include "intern/bmesh_operators_private.h" /* own include */ -enum { - EDGE_SEAM = 1 -}; - -enum { - VERT_SEAM = 2 -}; - /** - * Remove the EDGE_SEAM flag for edges we cant split + * Remove the BM_ELEM_TAG flag for edges we cant split * * un-tag edges not connected to other tagged edges, * unless they are on a boundary @@ -67,7 +59,7 @@ static void bm_edgesplit_validate_seams(BMesh *bm, BMOperator *op) BM_elem_flag_disable(e, BM_ELEM_INTERNAL_TAG); if (e->l == NULL) { - BMO_elem_flag_disable(bm, e, EDGE_SEAM); + BM_elem_flag_disable(e, BM_ELEM_TAG); } else if (BM_edge_is_boundary(e)) { vt = &vtouch[BM_elem_index_get(e->v1)]; if (*vt < 2) (*vt)++; @@ -75,7 +67,7 @@ static void bm_edgesplit_validate_seams(BMesh *bm, BMOperator *op) /* while the boundary verts need to be tagged, * the edge its self can't be split */ - BMO_elem_flag_disable(bm, e, EDGE_SEAM); + BM_elem_flag_disable(e, BM_ELEM_TAG); } } @@ -92,7 +84,7 @@ static void bm_edgesplit_validate_seams(BMesh *bm, BMOperator *op) if (vtouch[BM_elem_index_get(e->v1)] == 1 && vtouch[BM_elem_index_get(e->v2)] == 1) { - BMO_elem_flag_disable(bm, e, EDGE_SEAM); + BM_elem_flag_disable(e, BM_ELEM_TAG); } } @@ -106,11 +98,11 @@ void bmo_split_edges_exec(BMesh *bm, BMOperator *op) BMEdge *e; const int use_verts = BMO_slot_bool_get(op->slots_in, "use_verts"); - BMO_slot_buffer_flag_enable(bm, op->slots_in, "edges", BM_EDGE, EDGE_SEAM); + BMO_slot_buffer_hflag_enable(bm, op->slots_in, "edges", BM_EDGE, BM_ELEM_TAG, FALSE); if (use_verts) { /* this slows down the operation but its ok because the modifier doesn't use */ - BMO_slot_buffer_flag_enable(bm, op->slots_in, "verts", BM_VERT, VERT_SEAM); + BMO_slot_buffer_hflag_enable(bm, op->slots_in, "verts", BM_VERT, BM_ELEM_TAG, FALSE); /* prevent one edge having both verts unflagged * we could alternately disable these edges, either way its a corner case. @@ -119,11 +111,11 @@ void bmo_split_edges_exec(BMesh *bm, BMOperator *op) * would leave a duplicate edge. */ BMO_ITER (e, &siter, op->slots_in, "edges", BM_EDGE) { - if (UNLIKELY((BMO_elem_flag_test(bm, e->v1, VERT_SEAM) == FALSE && - (BMO_elem_flag_test(bm, e->v2, VERT_SEAM) == FALSE)))) + if (UNLIKELY((BM_elem_flag_test(e->v1, BM_ELEM_TAG) == FALSE && + (BM_elem_flag_test(e->v2, BM_ELEM_TAG) == FALSE)))) { - BMO_elem_flag_enable(bm, e->v1, VERT_SEAM); - BMO_elem_flag_enable(bm, e->v2, VERT_SEAM); + BM_elem_flag_enable(e->v1, BM_ELEM_TAG); + BM_elem_flag_enable(e->v2, BM_ELEM_TAG); } } } @@ -131,7 +123,7 @@ void bmo_split_edges_exec(BMesh *bm, BMOperator *op) bm_edgesplit_validate_seams(bm, op); BMO_ITER (e, &siter, op->slots_in, "edges", BM_EDGE) { - if (BMO_elem_flag_test(bm, e, EDGE_SEAM)) { + if (BM_elem_flag_test(e, BM_ELEM_TAG)) { /* this flag gets copied so we can be sure duplicate edges get it too (important) */ BM_elem_flag_enable(e, BM_ELEM_INTERNAL_TAG); @@ -147,17 +139,17 @@ void bmo_split_edges_exec(BMesh *bm, BMOperator *op) if (use_verts) { BMO_ITER (e, &siter, op->slots_in, "edges", BM_EDGE) { - if (BMO_elem_flag_test(bm, e->v1, VERT_SEAM) == FALSE) { + if (BM_elem_flag_test(e->v1, BM_ELEM_TAG) == FALSE) { BM_elem_flag_disable(e->v1, BM_ELEM_TAG); } - if (BMO_elem_flag_test(bm, e->v2, VERT_SEAM) == FALSE) { + if (BM_elem_flag_test(e->v2, BM_ELEM_TAG) == FALSE) { BM_elem_flag_disable(e->v2, BM_ELEM_TAG); } } } BMO_ITER (e, &siter, op->slots_in, "edges", BM_EDGE) { - if (BMO_elem_flag_test(bm, e, EDGE_SEAM)) { + if (BM_elem_flag_test(e, BM_ELEM_TAG)) { if (BM_elem_flag_test(e->v1, BM_ELEM_TAG)) { BM_elem_flag_disable(e->v1, BM_ELEM_TAG); bmesh_vert_separate(bm, e->v1, NULL, NULL); From dd0e554d9e76d0c6394d89b10bea4ad9b566d5fb Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Wed, 12 Dec 2012 12:42:12 +0000 Subject: [PATCH 049/252] Sequencer: add textured solid option for opengl preview --- release/scripts/startup/bl_ui/space_sequencer.py | 4 ++++ source/blender/blenkernel/BKE_sequencer.h | 2 +- source/blender/blenkernel/intern/sequencer.c | 5 +++-- source/blender/editors/include/ED_view3d.h | 2 +- source/blender/editors/render/render_opengl.c | 2 +- source/blender/editors/space_view3d/view3d_draw.c | 5 ++++- source/blender/makesdna/DNA_scene_types.h | 1 + source/blender/makesrna/intern/rna_scene.c | 5 +++++ source/blender/windowmanager/intern/wm_files.c | 2 +- 9 files changed, 21 insertions(+), 7 deletions(-) diff --git a/release/scripts/startup/bl_ui/space_sequencer.py b/release/scripts/startup/bl_ui/space_sequencer.py index fdfd43157c7..5b7a3a82aae 100644 --- a/release/scripts/startup/bl_ui/space_sequencer.py +++ b/release/scripts/startup/bl_ui/space_sequencer.py @@ -867,6 +867,10 @@ class SEQUENCER_PT_preview(SequencerButtonsPanel_Output, Panel): #col.active = render.use_sequencer_gl_preview col.prop(render, "sequencer_gl_preview", text="") + row = col.row() + row.active = render.sequencer_gl_preview == 'SOLID' + row.prop(render, "use_sequencer_gl_textured_solid") + class SEQUENCER_PT_view(SequencerButtonsPanel_Output, Panel): bl_label = "View Settings" diff --git a/source/blender/blenkernel/BKE_sequencer.h b/source/blender/blenkernel/BKE_sequencer.h index 88294cb30b6..e3d9c513c5c 100644 --- a/source/blender/blenkernel/BKE_sequencer.h +++ b/source/blender/blenkernel/BKE_sequencer.h @@ -363,7 +363,7 @@ struct Sequence *BKE_sequencer_add_sound_strip(struct bContext *C, ListBase *seq struct Sequence *BKE_sequencer_add_movie_strip(struct bContext *C, ListBase *seqbasep, struct SeqLoadInfo *seq_load); /* view3d draw callback, run when not in background view */ -typedef struct ImBuf *(*SequencerDrawView)(struct Scene *, struct Object *, int, int, unsigned int, int, int, int, char[256]); +typedef struct ImBuf *(*SequencerDrawView)(struct Scene *, struct Object *, int, int, unsigned int, int, int, int, int, char[256]); extern SequencerDrawView sequencer_view3d_cb; /* copy/paste */ diff --git a/source/blender/blenkernel/intern/sequencer.c b/source/blender/blenkernel/intern/sequencer.c index acce3740c98..861a8266511 100644 --- a/source/blender/blenkernel/intern/sequencer.c +++ b/source/blender/blenkernel/intern/sequencer.c @@ -2409,8 +2409,9 @@ static ImBuf *seq_render_scene_strip(SeqRenderData context, Sequence *seq, float /* opengl offscreen render */ BKE_scene_update_for_newframe(context.bmain, scene, scene->lay); - ibuf = sequencer_view3d_cb(scene, camera, context.rectx, context.recty, - IB_rect, context.scene->r.seq_prev_type, TRUE, FALSE, err_out); + ibuf = sequencer_view3d_cb(scene, camera, context.rectx, context.recty, IB_rect, + context.scene->r.seq_prev_type, context.scene->r.seq_flag & R_SEQ_SOLID_TEX, + TRUE, FALSE, err_out); if (ibuf == NULL) { fprintf(stderr, "seq_render_scene_strip failed to get opengl buffer: %s\n", err_out); } diff --git a/source/blender/editors/include/ED_view3d.h b/source/blender/editors/include/ED_view3d.h index e3d14fb4aac..8ca7d5a023e 100644 --- a/source/blender/editors/include/ED_view3d.h +++ b/source/blender/editors/include/ED_view3d.h @@ -269,7 +269,7 @@ void ED_view3d_draw_offscreen(struct Scene *scene, struct View3D *v3d, struct AR struct ImBuf *ED_view3d_draw_offscreen_imbuf(struct Scene *scene, struct View3D *v3d, struct ARegion *ar, int sizex, int sizey, unsigned int flag, int draw_background, int colormanage_background, char err_out[256]); struct ImBuf *ED_view3d_draw_offscreen_imbuf_simple(struct Scene *scene, struct Object *camera, int width, int height, unsigned int flag, int drawtype, - int draw_background, int colormanage_background, char err_out[256]); + int use_solid_tex, int draw_background, int colormanage_background, char err_out[256]); struct Base *ED_view3d_give_base_under_cursor(struct bContext *C, const int mval[2]); diff --git a/source/blender/editors/render/render_opengl.c b/source/blender/editors/render/render_opengl.c index 73f8abdf15f..16fe94ff2e5 100644 --- a/source/blender/editors/render/render_opengl.c +++ b/source/blender/editors/render/render_opengl.c @@ -232,7 +232,7 @@ static void screen_opengl_render_apply(OGLRender *oglrender) else { /* shouldnt suddenly give errors mid-render but possible */ char err_out[256] = "unknown"; - ImBuf *ibuf_view = ED_view3d_draw_offscreen_imbuf_simple(scene, scene->camera, oglrender->sizex, oglrender->sizey, IB_rectfloat, OB_SOLID, TRUE, FALSE, err_out); + ImBuf *ibuf_view = ED_view3d_draw_offscreen_imbuf_simple(scene, scene->camera, oglrender->sizex, oglrender->sizey, IB_rectfloat, OB_SOLID, FALSE, TRUE, FALSE, err_out); camera = scene->camera; if (ibuf_view) { diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c index a2e16efadd4..154eeae8dc8 100644 --- a/source/blender/editors/space_view3d/view3d_draw.c +++ b/source/blender/editors/space_view3d/view3d_draw.c @@ -2748,7 +2748,7 @@ ImBuf *ED_view3d_draw_offscreen_imbuf(Scene *scene, View3D *v3d, ARegion *ar, /* creates own 3d views, used by the sequencer */ ImBuf *ED_view3d_draw_offscreen_imbuf_simple(Scene *scene, Object *camera, int width, int height, - unsigned int flag, int drawtype, int draw_background, + unsigned int flag, int drawtype, int use_solid_tex, int draw_background, int colormanage_background, char err_out[256]) { View3D v3d = {NULL}; @@ -2765,6 +2765,9 @@ ImBuf *ED_view3d_draw_offscreen_imbuf_simple(Scene *scene, Object *camera, int w v3d.drawtype = drawtype; v3d.flag2 = V3D_RENDER_OVERRIDE; + if (use_solid_tex) + v3d.flag2 |= V3D_SOLID_TEX; + rv3d.persp = RV3D_CAMOB; copy_m4_m4(rv3d.viewinv, v3d.camera->obmat); diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h index 1599b71d832..1afa6987ac6 100644 --- a/source/blender/makesdna/DNA_scene_types.h +++ b/source/blender/makesdna/DNA_scene_types.h @@ -1198,6 +1198,7 @@ typedef struct Scene { /* seq_flag */ #define R_SEQ_GL_PREV 1 // #define R_SEQ_GL_REND 2 // UNUSED, opengl render has its own operator now. +#define R_SEQ_SOLID_TEX 4 /* displaymode */ diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c index 2d405f4fc0d..80c2e8dc8a3 100644 --- a/source/blender/makesrna/intern/rna_scene.c +++ b/source/blender/makesrna/intern/rna_scene.c @@ -3992,6 +3992,11 @@ static void rna_def_scene_render_data(BlenderRNA *brna) RNA_def_property_enum_items(prop, viewport_shade_items); RNA_def_property_ui_text(prop, "Sequencer Preview Shading", "Method to draw in the sequencer view"); + prop = RNA_def_property(srna, "use_sequencer_gl_textured_solid", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "seq_flag", R_SEQ_SOLID_TEX); + RNA_def_property_ui_text(prop, "Textured Solid", "Draw face-assigned textures in solid draw method"); + RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_SceneSequencer_update"); + /* layers */ prop = RNA_def_property(srna, "layers", PROP_COLLECTION, PROP_NONE); RNA_def_property_collection_sdna(prop, NULL, "layers", NULL); diff --git a/source/blender/windowmanager/intern/wm_files.c b/source/blender/windowmanager/intern/wm_files.c index 0e4af46d0fc..de59ec8d339 100644 --- a/source/blender/windowmanager/intern/wm_files.c +++ b/source/blender/windowmanager/intern/wm_files.c @@ -708,7 +708,7 @@ static ImBuf *blend_file_thumb(Scene *scene, bScreen *screen, int **thumb_pt) if (scene->camera) { ibuf = ED_view3d_draw_offscreen_imbuf_simple(scene, scene->camera, BLEN_THUMB_SIZE * 2, BLEN_THUMB_SIZE * 2, - IB_rect, OB_SOLID, FALSE, FALSE, err_out); + IB_rect, OB_SOLID, FALSE, FALSE, FALSE, err_out); } else { ibuf = ED_view3d_draw_offscreen_imbuf(scene, v3d, ar, BLEN_THUMB_SIZE * 2, BLEN_THUMB_SIZE * 2, From 7ab67541d3112d9b6d722aa413ce2af344ec08dc Mon Sep 17 00:00:00 2001 From: Lukas Toenne Date: Wed, 12 Dec 2012 12:50:39 +0000 Subject: [PATCH 050/252] Toolbar region for the node editor. This region is, for now, empty and hidden by default. Later on we might add standard panels here, but at least it will give addons a place to register tool shelf panels. --- .../blender/editors/space_node/CMakeLists.txt | 1 + .../blender/editors/space_node/node_intern.h | 5 + source/blender/editors/space_node/node_ops.c | 2 + .../blender/editors/space_node/node_toolbar.c | 92 +++++++++++++++++++ .../blender/editors/space_node/space_node.c | 53 +++++++++++ 5 files changed, 153 insertions(+) create mode 100644 source/blender/editors/space_node/node_toolbar.c diff --git a/source/blender/editors/space_node/CMakeLists.txt b/source/blender/editors/space_node/CMakeLists.txt index 996c6fb530f..3803f899ccc 100644 --- a/source/blender/editors/space_node/CMakeLists.txt +++ b/source/blender/editors/space_node/CMakeLists.txt @@ -52,6 +52,7 @@ set(SRC node_relationships.c node_select.c node_templates.c + node_toolbar.c node_view.c space_node.c diff --git a/source/blender/editors/space_node/node_intern.h b/source/blender/editors/space_node/node_intern.h index 45509e02226..671c4fde709 100644 --- a/source/blender/editors/space_node/node_intern.h +++ b/source/blender/editors/space_node/node_intern.h @@ -63,6 +63,7 @@ typedef struct bNodeLinkDrag { /* space_node.c */ ARegion *node_has_buttons_region(ScrArea *sa); +ARegion *node_has_tools_region(ScrArea *sa); /* node_header.c */ void node_menus_register(void); @@ -86,6 +87,10 @@ void node_set_cursor(struct wmWindow *win, struct SpaceNode *snode); void node_buttons_register(struct ARegionType *art); void NODE_OT_properties(struct wmOperatorType *ot); +/* node_toolbar.c */ +void node_toolbar_register(struct ARegionType *art); +void NODE_OT_toolbar(struct wmOperatorType *ot); + /* node_ops.c */ void node_operatortypes(void); void node_keymap(wmKeyConfig *keyconf); diff --git a/source/blender/editors/space_node/node_ops.c b/source/blender/editors/space_node/node_ops.c index 64e5f67a348..8adccd9e6c4 100644 --- a/source/blender/editors/space_node/node_ops.c +++ b/source/blender/editors/space_node/node_ops.c @@ -49,6 +49,7 @@ void node_operatortypes(void) { WM_operatortype_append(NODE_OT_properties); + WM_operatortype_append(NODE_OT_toolbar); WM_operatortype_append(NODE_OT_select); WM_operatortype_append(NODE_OT_select_all); @@ -204,6 +205,7 @@ void node_keymap(struct wmKeyConfig *keyconf) keymap = WM_keymap_find(keyconf, "Node Generic", SPACE_NODE, 0); WM_keymap_add_item(keymap, "NODE_OT_properties", NKEY, KM_PRESS, 0, 0); + WM_keymap_add_item(keymap, "NODE_OT_toolbar", TKEY, KM_PRESS, 0, 0); /* Main Area only ----------------- */ keymap = WM_keymap_find(keyconf, "Node Editor", SPACE_NODE, 0); diff --git a/source/blender/editors/space_node/node_toolbar.c b/source/blender/editors/space_node/node_toolbar.c new file mode 100644 index 00000000000..86da4009b17 --- /dev/null +++ b/source/blender/editors/space_node/node_toolbar.c @@ -0,0 +1,92 @@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2012 Blender Foundation. + * All rights reserved. + * + * + * Contributor(s): Lukas Toenne + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/editors/space_node/node_toolbar.c + * \ingroup nodes + */ + + +#include "MEM_guardedalloc.h" + +#include "BLI_utildefines.h" + +#include "DNA_node_types.h" + +#include "BKE_context.h" +#include "BKE_node.h" +#include "BKE_screen.h" + +#include "WM_api.h" +#include "WM_types.h" + +#include "RNA_access.h" + +#include "ED_screen.h" + +#include "UI_interface.h" +#include "UI_resources.h" + +#include "node_intern.h" /* own include */ + + +/* ******************* node toolbar registration ************** */ + +void node_toolbar_register(ARegionType *UNUSED(art)) +{ +} + +/* ********** operator to open/close toolshelf region */ + +static int node_toolbar(bContext *C, wmOperator *UNUSED(op)) +{ + ScrArea *sa = CTX_wm_area(C); + ARegion *ar = node_has_tools_region(sa); + + if (ar) + ED_region_toggle_hidden(C, ar); + + return OPERATOR_FINISHED; +} + +/* non-standard poll operator which doesn't care if there are any nodes */ +static int node_toolbar_poll(bContext *C) +{ + ScrArea *sa = CTX_wm_area(C); + return (sa && (sa->spacetype == SPACE_NODE)); +} + +void NODE_OT_toolbar(wmOperatorType *ot) +{ + ot->name = "Tool Shelf"; + ot->description = "Toggles tool shelf display"; + ot->idname = "NODE_OT_toolbar"; + + ot->exec = node_toolbar; + ot->poll = node_toolbar_poll; + + /* flags */ + ot->flag = 0; +} diff --git a/source/blender/editors/space_node/space_node.c b/source/blender/editors/space_node/space_node.c index f7e0d51ea03..0e015a4477c 100644 --- a/source/blender/editors/space_node/space_node.c +++ b/source/blender/editors/space_node/space_node.c @@ -85,6 +85,30 @@ ARegion *node_has_buttons_region(ScrArea *sa) return arnew; } +ARegion *node_has_tools_region(ScrArea *sa) +{ + ARegion *ar, *arnew; + + ar = BKE_area_find_region_type(sa, RGN_TYPE_TOOLS); + if (ar) return ar; + + /* add subdiv level; after header */ + ar = BKE_area_find_region_type(sa, RGN_TYPE_HEADER); + + /* is error! */ + if (ar == NULL) return NULL; + + arnew = MEM_callocN(sizeof(ARegion), "node tools"); + + BLI_insertlinkafter(&sa->regionbase, ar, arnew); + arnew->regiontype = RGN_TYPE_TOOLS; + arnew->alignment = RGN_ALIGN_LEFT; + + arnew->flag = RGN_FLAG_HIDDEN; + + return arnew; +} + /* ******************** default callbacks for node space ***************** */ static SpaceLink *node_new(const bContext *UNUSED(C)) @@ -342,6 +366,22 @@ static void node_buttons_area_draw(const bContext *C, ARegion *ar) ED_region_panels(C, ar, 1, NULL, -1); } +/* add handlers, stuff you only do once or on area/region changes */ +static void node_toolbar_area_init(wmWindowManager *wm, ARegion *ar) +{ + wmKeyMap *keymap; + + ED_region_panels_init(wm, ar); + + keymap = WM_keymap_find(wm->defaultconf, "Node Generic", SPACE_NODE, 0); + WM_event_add_keymap_handler(&ar->handlers, keymap); +} + +static void node_toolbar_area_draw(const bContext *C, ARegion *ar) +{ + ED_region_panels(C, ar, 1, NULL, -1); +} + static void node_cursor(wmWindow *win, ScrArea *sa, ARegion *ar) { SpaceNode *snode = sa->spacedata.first; @@ -570,6 +610,19 @@ void ED_spacetype_node(void) node_buttons_register(art); + /* regions: toolbar */ + art = MEM_callocN(sizeof(ARegionType), "spacetype view3d tools region"); + art->regionid = RGN_TYPE_TOOLS; + art->prefsizex = 160; /* XXX */ + art->prefsizey = 50; /* XXX */ + art->keymapflag = ED_KEYMAP_UI | ED_KEYMAP_FRAMES; + art->listener = node_region_listener; + art->init = node_toolbar_area_init; + art->draw = node_toolbar_area_draw; + BLI_addhead(&st->regiontypes, art); + + node_toolbar_register(art); + BKE_spacetype_register(st); } From 6a6bede3f68836ce486004300b27c84c9a4a060c Mon Sep 17 00:00:00 2001 From: Lukas Toenne Date: Wed, 12 Dec 2012 12:50:43 +0000 Subject: [PATCH 051/252] A few basic Python operators for adding nodes in the node editor tree. These operators basically have the same functionality as the 'Add' menu (which currently does not even use operators itself). They can be used in customized tools. The node_add_move operator is an extended variant which starts the (modal) transform operator right after adding a node, as a quicker way of inserting nodes in a tree. --- release/scripts/startup/bl_operators/node.py | 76 +++++++++++++++++++- 1 file changed, 75 insertions(+), 1 deletion(-) diff --git a/release/scripts/startup/bl_operators/node.py b/release/scripts/startup/bl_operators/node.py index fb264cb3429..38adcdf7368 100644 --- a/release/scripts/startup/bl_operators/node.py +++ b/release/scripts/startup/bl_operators/node.py @@ -20,7 +20,81 @@ import bpy from bpy.types import Operator -from bpy.props import EnumProperty +from bpy.props import EnumProperty, StringProperty + +# Base class for node 'Add' operators +class NodeAddOperator(): + @staticmethod + def store_mouse_cursor(context, event): + space = context.space_data + v2d = context.region.view2d + + # convert mouse position to the View2D for later node placement + space.cursor_location = v2d.region_to_view(event.mouse_region_x, + event.mouse_region_y) + + def create_node(self, context, node_type): + space = context.space_data + tree = space.edit_tree + + node = tree.nodes.new(type=node_type) + + # select only the new node + for n in tree.nodes: + n.select = (n == node) + tree.nodes.active = node + node.location = space.cursor_location + return node + + @classmethod + def poll(cls, context): + space = context.space_data + # needs active node editor and a tree to add nodes to + return (space.type == 'NODE_EDITOR' and space.edit_tree) + + # Default invoke stores the mouse position to place the node correctly + def invoke(self, context, event): + self.store_mouse_cursor(context, event) + return self.execute(context) + + +# Simple basic operator for adding a node +class NODE_OT_add_node(NodeAddOperator, Operator): + '''Add a node to the active tree''' + bl_idname = "node.add_node" + bl_label = "Add Node" + + type = StringProperty(name="Node Type", description="Node type") + + # optional group tree parameter for group nodes + group_tree = StringProperty(name="Group tree", description="Group node tree name") + + def execute(self, context): + node = self.create_node(context, self.type) + + # set the node group tree of a group node + if self.properties.is_property_set('group_tree'): + node.node_tree = bpy.data.node_groups[self.group_tree] + + return {'FINISHED'} + + +# Adds a node and immediately starts the transform operator for inserting in a tree +class NODE_OT_add_node_move(NODE_OT_add_node): + '''Add a node to the active tree and start transform''' + bl_idname = "node.add_node_move" + bl_label = "Add Node and Move" + + type = StringProperty(name="Node Type", description="Node type") + + # optional group tree parameter for group nodes + group_tree = StringProperty(name="Group tree", description="Group node tree name") + + def invoke(self, context, event): + self.store_mouse_cursor(context, event) + self.execute(context) + return bpy.ops.transform.translate('INVOKE_DEFAULT') + # XXX These node item lists should actually be generated by a callback at # operator execution time (see node_type_items below), From ee62b20158f2322006b1b186024d888ec2175faf Mon Sep 17 00:00:00 2001 From: Lukas Toenne Date: Wed, 12 Dec 2012 12:50:45 +0000 Subject: [PATCH 052/252] Fix for misleading doc string of panel header options. --- source/blender/makesrna/intern/rna_ui.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/blender/makesrna/intern/rna_ui.c b/source/blender/makesrna/intern/rna_ui.c index a0a9f6183af..de359fd6413 100644 --- a/source/blender/makesrna/intern/rna_ui.c +++ b/source/blender/makesrna/intern/rna_ui.c @@ -651,8 +651,8 @@ static void rna_def_panel(BlenderRNA *brna) static EnumPropertyItem panel_flag_items[] = { {PNL_DEFAULT_CLOSED, "DEFAULT_CLOSED", 0, "Default Closed", "Defines if the panel has to be open or collapsed at the time of its creation"}, - {PNL_NO_HEADER, "HIDE_HEADER", 0, "Show Header", - "If set to True, the panel shows a header, which contains a clickable " + {PNL_NO_HEADER, "HIDE_HEADER", 0, "Hide Header", + "If set to False, the panel shows a header, which contains a clickable " "arrow to collapse the panel and the label (see bl_label)"}, {0, NULL, 0, NULL, NULL} }; From 0ca46e3524ad74b4912b4cdfa8f27ae162e10257 Mon Sep 17 00:00:00 2001 From: Lukas Toenne Date: Wed, 12 Dec 2012 12:50:49 +0000 Subject: [PATCH 053/252] Fix for menu context. The menu draw function context did not inherit the custom context storage from the original uiLayout yet. Fix by Campbell Barton (ideasman_42). --- source/blender/editors/interface/interface_layout.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/source/blender/editors/interface/interface_layout.c b/source/blender/editors/interface/interface_layout.c index 9759c22f30e..c67c64a0540 100644 --- a/source/blender/editors/interface/interface_layout.c +++ b/source/blender/editors/interface/interface_layout.c @@ -1466,7 +1466,13 @@ static void ui_item_menutype_func(bContext *C, uiLayout *layout, void *arg_mt) printf("%s: opening menu \"%s\"\n", __func__, mt->idname); } + if (layout->context) + CTX_store_set(C, layout->context); + mt->draw(C, &menu); + + if (layout->context) + CTX_store_set(C, NULL); } static void ui_item_menu(uiLayout *layout, const char *name, int icon, uiMenuCreateFunc func, void *arg, void *argN, const char *tip) From bee7c20a97e2e4fc72926a22db7409ab1b161f24 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 12 Dec 2012 12:57:27 +0000 Subject: [PATCH 054/252] move edge split into its own function which can be called by the modifier without having to call a bmesh operator (gives some speedup). --- source/blender/bmesh/CMakeLists.txt | 2 + .../blender/bmesh/operators/bmo_edgesplit.c | 122 +------------ source/blender/bmesh/tools/bmesh_edgesplit.c | 170 ++++++++++++++++++ source/blender/bmesh/tools/bmesh_edgesplit.h | 32 ++++ .../blender/modifiers/intern/MOD_edgesplit.c | 28 +-- 5 files changed, 218 insertions(+), 136 deletions(-) create mode 100644 source/blender/bmesh/tools/bmesh_edgesplit.c create mode 100644 source/blender/bmesh/tools/bmesh_edgesplit.h diff --git a/source/blender/bmesh/CMakeLists.txt b/source/blender/bmesh/CMakeLists.txt index 2a23658f5d0..c41b0703240 100644 --- a/source/blender/bmesh/CMakeLists.txt +++ b/source/blender/bmesh/CMakeLists.txt @@ -111,6 +111,8 @@ set(SRC tools/bmesh_decimate_dissolve.c tools/bmesh_decimate_unsubdivide.c tools/bmesh_decimate.h + tools/bmesh_edgesplit.c + tools/bmesh_edgesplit.h bmesh.h bmesh_class.h diff --git a/source/blender/bmesh/operators/bmo_edgesplit.c b/source/blender/bmesh/operators/bmo_edgesplit.c index 81728cea906..b4b50a60877 100644 --- a/source/blender/bmesh/operators/bmo_edgesplit.c +++ b/source/blender/bmesh/operators/bmo_edgesplit.c @@ -22,80 +22,21 @@ /** \file blender/bmesh/operators/bmo_edgesplit.c * \ingroup bmesh + * + * Just a wrapper around #BM_mesh_edgesplit */ -#include "MEM_guardedalloc.h" - #include "BLI_utildefines.h" #include "bmesh.h" +#include "tools/bmesh_edgesplit.h" #include "intern/bmesh_operators_private.h" /* own include */ -/** - * Remove the BM_ELEM_TAG flag for edges we cant split - * - * un-tag edges not connected to other tagged edges, - * unless they are on a boundary - */ -static void bm_edgesplit_validate_seams(BMesh *bm, BMOperator *op) -{ - BMOIter siter; - BMIter iter; - BMEdge *e; - - unsigned char *vtouch; - unsigned char *vt; - - BM_mesh_elem_index_ensure(bm, BM_VERT); - - vtouch = MEM_callocN(sizeof(char) * bm->totvert, __func__); - - /* tag all boundary verts so as not to untag an edge which is inbetween only 2 faces [] */ - BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) { - - /* unrelated to flag assignment in this function - since this is the - * only place we loop over all edges, disable tag */ - BM_elem_flag_disable(e, BM_ELEM_INTERNAL_TAG); - - if (e->l == NULL) { - BM_elem_flag_disable(e, BM_ELEM_TAG); - } - else if (BM_edge_is_boundary(e)) { - vt = &vtouch[BM_elem_index_get(e->v1)]; if (*vt < 2) (*vt)++; - vt = &vtouch[BM_elem_index_get(e->v2)]; if (*vt < 2) (*vt)++; - - /* while the boundary verts need to be tagged, - * the edge its self can't be split */ - BM_elem_flag_disable(e, BM_ELEM_TAG); - } - } - - /* single marked edges unconnected to any other marked edges - * are illegal, go through and unmark them */ - BMO_ITER (e, &siter, op->slots_in, "edges", BM_EDGE) { - /* lame, but we don't want the count to exceed 255, - * so just count to 2, its all we need */ - unsigned char *vt; - vt = &vtouch[BM_elem_index_get(e->v1)]; if (*vt < 2) (*vt)++; - vt = &vtouch[BM_elem_index_get(e->v2)]; if (*vt < 2) (*vt)++; - } - BMO_ITER (e, &siter, op->slots_in, "edges", BM_EDGE) { - if (vtouch[BM_elem_index_get(e->v1)] == 1 && - vtouch[BM_elem_index_get(e->v2)] == 1) - { - BM_elem_flag_disable(e, BM_ELEM_TAG); - } - } - - MEM_freeN(vtouch); -} /* keep this operator fast, its used in a modifier */ void bmo_split_edges_exec(BMesh *bm, BMOperator *op) { - BMOIter siter; - BMEdge *e; const int use_verts = BMO_slot_bool_get(op->slots_in, "use_verts"); BMO_slot_buffer_hflag_enable(bm, op->slots_in, "edges", BM_EDGE, BM_ELEM_TAG, FALSE); @@ -103,63 +44,10 @@ void bmo_split_edges_exec(BMesh *bm, BMOperator *op) if (use_verts) { /* this slows down the operation but its ok because the modifier doesn't use */ BMO_slot_buffer_hflag_enable(bm, op->slots_in, "verts", BM_VERT, BM_ELEM_TAG, FALSE); - - /* prevent one edge having both verts unflagged - * we could alternately disable these edges, either way its a corner case. - * - * This is needed so we don't split off the edge but then none of its verts which - * would leave a duplicate edge. - */ - BMO_ITER (e, &siter, op->slots_in, "edges", BM_EDGE) { - if (UNLIKELY((BM_elem_flag_test(e->v1, BM_ELEM_TAG) == FALSE && - (BM_elem_flag_test(e->v2, BM_ELEM_TAG) == FALSE)))) - { - BM_elem_flag_enable(e->v1, BM_ELEM_TAG); - BM_elem_flag_enable(e->v2, BM_ELEM_TAG); - } - } } - bm_edgesplit_validate_seams(bm, op); - - BMO_ITER (e, &siter, op->slots_in, "edges", BM_EDGE) { - if (BM_elem_flag_test(e, BM_ELEM_TAG)) { - /* this flag gets copied so we can be sure duplicate edges get it too (important) */ - BM_elem_flag_enable(e, BM_ELEM_INTERNAL_TAG); - - /* keep splitting until each loop has its own edge */ - do { - bmesh_edge_separate(bm, e, e->l); - } while (!BM_edge_is_boundary(e)); - - BM_elem_flag_enable(e->v1, BM_ELEM_TAG); - BM_elem_flag_enable(e->v2, BM_ELEM_TAG); - } - } - - if (use_verts) { - BMO_ITER (e, &siter, op->slots_in, "edges", BM_EDGE) { - if (BM_elem_flag_test(e->v1, BM_ELEM_TAG) == FALSE) { - BM_elem_flag_disable(e->v1, BM_ELEM_TAG); - } - if (BM_elem_flag_test(e->v2, BM_ELEM_TAG) == FALSE) { - BM_elem_flag_disable(e->v2, BM_ELEM_TAG); - } - } - } - - BMO_ITER (e, &siter, op->slots_in, "edges", BM_EDGE) { - if (BM_elem_flag_test(e, BM_ELEM_TAG)) { - if (BM_elem_flag_test(e->v1, BM_ELEM_TAG)) { - BM_elem_flag_disable(e->v1, BM_ELEM_TAG); - bmesh_vert_separate(bm, e->v1, NULL, NULL); - } - if (BM_elem_flag_test(e->v2, BM_ELEM_TAG)) { - BM_elem_flag_disable(e->v2, BM_ELEM_TAG); - bmesh_vert_separate(bm, e->v2, NULL, NULL); - } - } - } + /* this is where everything happens */ + BM_mesh_edgesplit(bm, use_verts, TRUE); BMO_slot_buffer_from_enabled_hflag(bm, op, op->slots_out, "edges.out", BM_EDGE, BM_ELEM_INTERNAL_TAG); } diff --git a/source/blender/bmesh/tools/bmesh_edgesplit.c b/source/blender/bmesh/tools/bmesh_edgesplit.c new file mode 100644 index 00000000000..b6a8c7985d6 --- /dev/null +++ b/source/blender/bmesh/tools/bmesh_edgesplit.c @@ -0,0 +1,170 @@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor(s): Campbell Barton + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/bmesh/tools/bmesh_edgesplit.c + * \ingroup bmesh + * + * Edge-Split. + * + */ + +#include "MEM_guardedalloc.h" + +#include "BLI_utildefines.h" + +#include "bmesh.h" + +#include "bmesh_edgesplit.h" /* own include */ + + +/** + * Remove the BM_ELEM_TAG flag for edges we cant split + * + * un-tag edges not connected to other tagged edges, + * unless they are on a boundary + */ +static void bm_edgesplit_validate_seams(BMesh *bm) +{ + BMIter iter; + BMEdge *e; + + unsigned char *vtouch; + unsigned char *vt; + + BM_mesh_elem_index_ensure(bm, BM_VERT); + + vtouch = MEM_callocN(sizeof(char) * bm->totvert, __func__); + + /* tag all boundary verts so as not to untag an edge which is inbetween only 2 faces [] */ + BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) { + + /* unrelated to flag assignment in this function - since this is the + * only place we loop over all edges, disable tag */ + BM_elem_flag_disable(e, BM_ELEM_INTERNAL_TAG); + + if (e->l == NULL) { + BM_elem_flag_disable(e, BM_ELEM_TAG); + } + else if (BM_edge_is_boundary(e)) { + vt = &vtouch[BM_elem_index_get(e->v1)]; if (*vt < 2) (*vt)++; + vt = &vtouch[BM_elem_index_get(e->v2)]; if (*vt < 2) (*vt)++; + + /* while the boundary verts need to be tagged, + * the edge its self can't be split */ + BM_elem_flag_disable(e, BM_ELEM_TAG); + } + } + + /* single marked edges unconnected to any other marked edges + * are illegal, go through and unmark them */ + BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) { + if (BM_elem_flag_test(e, BM_ELEM_TAG)) { + /* lame, but we don't want the count to exceed 255, + * so just count to 2, its all we need */ + unsigned char *vt; + vt = &vtouch[BM_elem_index_get(e->v1)]; if (*vt < 2) (*vt)++; + vt = &vtouch[BM_elem_index_get(e->v2)]; if (*vt < 2) (*vt)++; + } + } + BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) { + if (BM_elem_flag_test(e, BM_ELEM_TAG)) { + if (vtouch[BM_elem_index_get(e->v1)] == 1 && + vtouch[BM_elem_index_get(e->v2)] == 1) + { + BM_elem_flag_disable(e, BM_ELEM_TAG); + } + } + } + + MEM_freeN(vtouch); +} + +void BM_mesh_edgesplit(BMesh *bm, const int use_verts, const int tag_only) +{ + BMIter iter; + BMEdge *e; + + + if (tag_only == FALSE) { + BM_mesh_elem_hflag_enable_all(bm, BM_EDGE | (use_verts ? BM_VERT : 0), BM_ELEM_TAG, FALSE); + } + + if (use_verts) { + /* prevent one edge having both verts unflagged + * we could alternately disable these edges, either way its a corner case. + * + * This is needed so we don't split off the edge but then none of its verts which + * would leave a duplicate edge. + */ + BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) { + if (BM_elem_flag_test(e, BM_ELEM_TAG)) { + if (UNLIKELY(((BM_elem_flag_test(e->v1, BM_ELEM_TAG) == FALSE) && + (BM_elem_flag_test(e->v2, BM_ELEM_TAG) == FALSE)))) + { + BM_elem_flag_enable(e->v1, BM_ELEM_TAG); + BM_elem_flag_enable(e->v2, BM_ELEM_TAG); + } + } + } + } + + bm_edgesplit_validate_seams(bm); + + BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) { + if (BM_elem_flag_test(e, BM_ELEM_TAG)) { + /* this flag gets copied so we can be sure duplicate edges get it too (important) */ + BM_elem_flag_enable(e, BM_ELEM_INTERNAL_TAG); + + /* keep splitting until each loop has its own edge */ + do { + bmesh_edge_separate(bm, e, e->l); + } while (!BM_edge_is_boundary(e)); + + BM_elem_flag_enable(e->v1, BM_ELEM_TAG); + BM_elem_flag_enable(e->v2, BM_ELEM_TAG); + } + } + + if (use_verts) { + BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) { + if (BM_elem_flag_test(e->v1, BM_ELEM_TAG) == FALSE) { + BM_elem_flag_disable(e->v1, BM_ELEM_TAG); + } + if (BM_elem_flag_test(e->v2, BM_ELEM_TAG) == FALSE) { + BM_elem_flag_disable(e->v2, BM_ELEM_TAG); + } + } + } + + BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) { + if (BM_elem_flag_test(e, BM_ELEM_TAG)) { + if (BM_elem_flag_test(e->v1, BM_ELEM_TAG)) { + BM_elem_flag_disable(e->v1, BM_ELEM_TAG); + bmesh_vert_separate(bm, e->v1, NULL, NULL); + } + if (BM_elem_flag_test(e->v2, BM_ELEM_TAG)) { + BM_elem_flag_disable(e->v2, BM_ELEM_TAG); + bmesh_vert_separate(bm, e->v2, NULL, NULL); + } + } + } +} diff --git a/source/blender/bmesh/tools/bmesh_edgesplit.h b/source/blender/bmesh/tools/bmesh_edgesplit.h new file mode 100644 index 00000000000..687fdac0e00 --- /dev/null +++ b/source/blender/bmesh/tools/bmesh_edgesplit.h @@ -0,0 +1,32 @@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor(s): + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#ifndef __BMESH_EDGESPLIT_H__ +#define __BMESH_EDGESPLIT_H__ + +/** \file blender/bmesh/tools/bmesh_edgesplit.h + * \ingroup bmesh + */ + +void BM_mesh_edgesplit(BMesh *bm, const int use_verts, const int tag_only); + +#endif /* __BMESH_EDGESPLIT_H__ */ diff --git a/source/blender/modifiers/intern/MOD_edgesplit.c b/source/blender/modifiers/intern/MOD_edgesplit.c index ec81c5ce699..5c786626c94 100644 --- a/source/blender/modifiers/intern/MOD_edgesplit.c +++ b/source/blender/modifiers/intern/MOD_edgesplit.c @@ -30,32 +30,24 @@ /** \file blender/modifiers/intern/MOD_edgesplit.c * \ingroup modifiers + * + * EdgeSplit modifier + * + * Splits edges in the mesh according to sharpness flag + * or edge angle (can be used to achieve autosmoothing) */ - -/* EdgeSplit modifier: Splits edges in the mesh according to sharpness flag - * or edge angle (can be used to achieve autosmoothing) */ - #include "BLI_utildefines.h" #include "BLI_math.h" -#include "MEM_guardedalloc.h" - #include "BKE_cdderivedmesh.h" #include "BKE_modifier.h" -#include "BKE_mesh.h" #include "bmesh.h" +#include "tools/bmesh_edgesplit.h" #include "DNA_object_types.h" -/* EdgeSplit */ -/* EdgeSplit modifier: Splits edges in the mesh according to sharpness flag - * or edge angle (can be used to achieve autosmoothing) - * - * note: this code is very close to MOD_bevel.c - */ - #define EDGE_MARK 1 static DerivedMesh *doEdgeSplit(DerivedMesh *dm, EdgeSplitModifierData *emd, Object *UNUSED(ob)) @@ -67,7 +59,6 @@ static DerivedMesh *doEdgeSplit(DerivedMesh *dm, EdgeSplitModifierData *emd, Obj float threshold = cosf((emd->split_angle + 0.00001f) * (float)M_PI / 180.0f); bm = DM_to_bmesh(dm); - BM_mesh_elem_toolflags_ensure(bm); if (emd->flags & MOD_EDGESPLIT_FROMANGLE) { BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) { @@ -81,7 +72,7 @@ static DerivedMesh *doEdgeSplit(DerivedMesh *dm, EdgeSplitModifierData *emd, Obj /* 2 face edge - check angle*/ (dot_v3v3(l1->f->no, l2->f->no) < threshold)) { - BMO_elem_flag_enable(bm, e, EDGE_MARK); + BM_elem_flag_enable(e, BM_ELEM_TAG); } } } @@ -94,14 +85,13 @@ static DerivedMesh *doEdgeSplit(DerivedMesh *dm, EdgeSplitModifierData *emd, Obj (e->l->next != e->l)) { if (!BM_elem_flag_test(e, BM_ELEM_SMOOTH)) { - BMO_elem_flag_enable(bm, e, EDGE_MARK); + BM_elem_flag_enable(e, BM_ELEM_TAG); } } } } - BMO_op_callf(bm, BMO_FLAG_DEFAULTS, - "split_edges edges=%fe", EDGE_MARK); + BM_mesh_edgesplit(bm, FALSE, TRUE); /* BM_mesh_validate(bm); */ /* for troubleshooting */ From 96cad133f75b22a3ac8045fefe18239bef5a4bf9 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 12 Dec 2012 14:34:21 +0000 Subject: [PATCH 055/252] fix [#33489] Scaling normals with Alt (maintains shell thickness) producing wrong result. not exactly a bug - zero area faces from a cancelled extrude gave issues - but this is a common use case, so make it work by only using selected faces when calculating the vertex shell thickness. --- .../editors/transform/transform_conversions.c | 36 ++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c index 884ec03cc62..5497b421981 100644 --- a/source/blender/editors/transform/transform_conversions.c +++ b/source/blender/editors/transform/transform_conversions.c @@ -1879,6 +1879,40 @@ static void get_edge_center(float cent_r[3], BMVert *eve) } } +/* local version of #BM_vert_calc_shell_factor which only + * uses selected faces */ +static float bm_vert_calc_shell_factor_selected(BMVert *v) +{ + BMIter iter; + BMLoop *l; + float accum_shell = 0.0f; + float accum_angle = 0.0f; + int tot_sel = 0, tot = 0; + + BM_ITER_ELEM (l, &iter, v, BM_LOOPS_OF_VERT) { + if (BM_elem_flag_test(l->f, BM_ELEM_SELECT)) { /* <-- only difference to BM_vert_calc_shell_factor! */ + const float face_angle = BM_loop_calc_face_angle(l); + accum_shell += shell_angle_to_dist(angle_normalized_v3v3(v->no, l->f->no)) * face_angle; + accum_angle += face_angle; + tot_sel++; + } + tot++; + } + + if (accum_angle != 0.0f) { + return accum_shell / accum_angle; + } + else { + if (tot != 0 && tot_sel == 0) { + /* none selected, so use all */ + return BM_vert_calc_shell_factor(v); + } + else { + return 1.0f; + } + } +} + /* way to overwrite what data is edited with transform */ static void VertsToTransData(TransInfo *t, TransData *td, TransDataExtension *tx, BMEditMesh *em, BMVert *eve, float *bweight) @@ -1927,7 +1961,7 @@ static void VertsToTransData(TransInfo *t, TransData *td, TransDataExtension *tx } else if (t->mode == TFM_SHRINKFATTEN) { td->ext = tx; - tx->isize[0] = BM_vert_calc_shell_factor(eve); + tx->isize[0] = bm_vert_calc_shell_factor_selected(eve); } } From 5616c7a0585521ca16f352ce2277cf4ac73eced2 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Wed, 12 Dec 2012 14:43:07 +0000 Subject: [PATCH 056/252] Cycles: disable scaling up of ray differentials after diffuse/glossy bounce, this isn't working well for OSL texture filtering and wasn't very helpful to begin with, a better solution should be possible. --- .../kernel/closure/bsdf_ashikhmin_velvet.h | 2 -- intern/cycles/kernel/closure/bsdf_diffuse.h | 8 ++---- .../cycles/kernel/closure/bsdf_microfacet.h | 28 ------------------- .../cycles/kernel/closure/bsdf_oren_nayar.h | 2 -- .../cycles/kernel/closure/bsdf_phong_ramp.h | 9 ------ intern/cycles/kernel/closure/bsdf_ward.h | 6 ---- intern/cycles/kernel/closure/bsdf_westin.h | 10 ------- 7 files changed, 2 insertions(+), 63 deletions(-) diff --git a/intern/cycles/kernel/closure/bsdf_ashikhmin_velvet.h b/intern/cycles/kernel/closure/bsdf_ashikhmin_velvet.h index 016fd73204e..60f809159ac 100644 --- a/intern/cycles/kernel/closure/bsdf_ashikhmin_velvet.h +++ b/intern/cycles/kernel/closure/bsdf_ashikhmin_velvet.h @@ -134,8 +134,6 @@ __device int bsdf_ashikhmin_velvet_sample(const ShaderClosure *sc, float3 Ng, fl // TODO: find a better approximation for the retroreflective bounce *domega_in_dx = (2 * dot(N, dIdx)) * N - dIdx; *domega_in_dy = (2 * dot(N, dIdy)) * N - dIdy; - *domega_in_dx *= 125.0f; - *domega_in_dy *= 125.0f; #endif } else diff --git a/intern/cycles/kernel/closure/bsdf_diffuse.h b/intern/cycles/kernel/closure/bsdf_diffuse.h index 88b40e3d479..46318ecd138 100644 --- a/intern/cycles/kernel/closure/bsdf_diffuse.h +++ b/intern/cycles/kernel/closure/bsdf_diffuse.h @@ -74,8 +74,6 @@ __device int bsdf_diffuse_sample(const ShaderClosure *sc, float3 Ng, float3 I, f // TODO: find a better approximation for the diffuse bounce *domega_in_dx = (2 * dot(N, dIdx)) * N - dIdx; *domega_in_dy = (2 * dot(N, dIdy)) * N - dIdy; - *domega_in_dx *= 125.0f; - *domega_in_dy *= 125.0f; #endif } else @@ -126,10 +124,8 @@ __device int bsdf_translucent_sample(const ShaderClosure *sc, float3 Ng, float3 *eval = make_float3(*pdf, *pdf, *pdf); #ifdef __RAY_DIFFERENTIALS__ // TODO: find a better approximation for the diffuse bounce - *domega_in_dx = (2 * dot(N, dIdx)) * N - dIdx; - *domega_in_dy = (2 * dot(N, dIdy)) * N - dIdy; - *domega_in_dx *= -125.0f; - *domega_in_dy *= -125.0f; + *domega_in_dx = -((2 * dot(N, dIdx)) * N - dIdx); + *domega_in_dy = -((2 * dot(N, dIdy)) * N - dIdy); #endif } else { diff --git a/intern/cycles/kernel/closure/bsdf_microfacet.h b/intern/cycles/kernel/closure/bsdf_microfacet.h index a564b99e759..019ec105111 100644 --- a/intern/cycles/kernel/closure/bsdf_microfacet.h +++ b/intern/cycles/kernel/closure/bsdf_microfacet.h @@ -199,12 +199,6 @@ __device int bsdf_microfacet_ggx_sample(const ShaderClosure *sc, float3 Ng, floa #ifdef __RAY_DIFFERENTIALS__ *domega_in_dx = (2 * dot(m, dIdx)) * m - dIdx; *domega_in_dy = (2 * dot(m, dIdy)) * m - dIdy; - // Since there is some blur to this reflection, make the - // derivatives a bit bigger. In theory this varies with the - // roughness but the exact relationship is complex and - // requires more ops than are practical. - *domega_in_dx *= 10.0f; - *domega_in_dy *= 10.0f; #endif } } @@ -251,14 +245,6 @@ __device int bsdf_microfacet_ggx_sample(const ShaderClosure *sc, float3 Ng, floa // eq. 38 and eq. 17 *pdf = pm * (m_eta * m_eta) * fabsf(cosHI) / Ht2; *eval = make_float3(out, out, out); -#ifdef __RAY_DIFFERENTIALS__ - // Since there is some blur to this refraction, make the - // derivatives a bit bigger. In theory this varies with the - // roughness but the exact relationship is complex and - // requires more ops than are practical. - *domega_in_dx *= 10.0f; - *domega_in_dy *= 10.0f; -#endif } } } @@ -430,12 +416,6 @@ __device int bsdf_microfacet_beckmann_sample(const ShaderClosure *sc, float3 Ng, #ifdef __RAY_DIFFERENTIALS__ *domega_in_dx = (2 * dot(m, dIdx)) * m - dIdx; *domega_in_dy = (2 * dot(m, dIdy)) * m - dIdy; - // Since there is some blur to this reflection, make the - // derivatives a bit bigger. In theory this varies with the - // roughness but the exact relationship is complex and - // requires more ops than are practical. - *domega_in_dx *= 10.0f; - *domega_in_dy *= 10.0f; #endif } } @@ -486,14 +466,6 @@ __device int bsdf_microfacet_beckmann_sample(const ShaderClosure *sc, float3 Ng, // eq. 38 and eq. 17 *pdf = pm * (m_eta * m_eta) * fabsf(cosHI) / Ht2; *eval = make_float3(out, out, out); -#ifdef __RAY_DIFFERENTIALS__ - // Since there is some blur to this refraction, make the - // derivatives a bit bigger. In theory this varies with the - // roughness but the exact relationship is complex and - // requires more ops than are practical. - *domega_in_dx *= 10.0f; - *domega_in_dy *= 10.0f; -#endif } } } diff --git a/intern/cycles/kernel/closure/bsdf_oren_nayar.h b/intern/cycles/kernel/closure/bsdf_oren_nayar.h index 066937da6eb..770f06dddc5 100644 --- a/intern/cycles/kernel/closure/bsdf_oren_nayar.h +++ b/intern/cycles/kernel/closure/bsdf_oren_nayar.h @@ -81,8 +81,6 @@ __device int bsdf_oren_nayar_sample(const ShaderClosure *sc, float3 Ng, float3 I // TODO: find a better approximation for the bounce *domega_in_dx = (2.0f * dot(sc->N, dIdx)) * sc->N - dIdx; *domega_in_dy = (2.0f * dot(sc->N, dIdy)) * sc->N - dIdy; - *domega_in_dx *= 125.0f; - *domega_in_dy *= 125.0f; #endif } else { diff --git a/intern/cycles/kernel/closure/bsdf_phong_ramp.h b/intern/cycles/kernel/closure/bsdf_phong_ramp.h index 575a798aed4..2f57fc1693f 100644 --- a/intern/cycles/kernel/closure/bsdf_phong_ramp.h +++ b/intern/cycles/kernel/closure/bsdf_phong_ramp.h @@ -119,15 +119,6 @@ __device int bsdf_phong_ramp_sample(const ShaderClosure *sc, const float3 colors *pdf = (m_exponent + 1) * common; float out = cosNI * (m_exponent + 2) * common; *eval = bsdf_phong_ramp_get_color(sc, colors, cosp) * out; - -#ifdef __RAY_DIFFERENTIALS__ - // Since there is some blur to this reflection, make the - // derivatives a bit bigger. In theory this varies with the - // exponent but the exact relationship is complex and - // requires more ops than are practical. - *domega_in_dx *= 10; - *domega_in_dy *= 10; -#endif } } } diff --git a/intern/cycles/kernel/closure/bsdf_ward.h b/intern/cycles/kernel/closure/bsdf_ward.h index dbddcf20dba..c95b0e3f7a0 100644 --- a/intern/cycles/kernel/closure/bsdf_ward.h +++ b/intern/cycles/kernel/closure/bsdf_ward.h @@ -182,12 +182,6 @@ __device int bsdf_ward_sample(const ShaderClosure *sc, float3 Ng, float3 I, floa #ifdef __RAY_DIFFERENTIALS__ *domega_in_dx = (2 * dot(N, dIdx)) * N - dIdx; *domega_in_dy = (2 * dot(N, dIdy)) * N - dIdy; - // Since there is some blur to this reflection, make the - // derivatives a bit bigger. In theory this varies with the - // roughness but the exact relationship is complex and - // requires more ops than are practical. - *domega_in_dx *= 10.0f; - *domega_in_dy *= 10.0f; #endif } } diff --git a/intern/cycles/kernel/closure/bsdf_westin.h b/intern/cycles/kernel/closure/bsdf_westin.h index 968173208b4..29bfa85bcc1 100644 --- a/intern/cycles/kernel/closure/bsdf_westin.h +++ b/intern/cycles/kernel/closure/bsdf_westin.h @@ -108,14 +108,6 @@ __device int bsdf_westin_backscatter_sample(const ShaderClosure *sc, float3 Ng, *pdf = 0.5f * M_1_PI_F * powf(cosTheta, m_invroughness); *pdf = (m_invroughness + 1) * (*pdf); *eval = make_float3(*pdf, *pdf, *pdf); -#ifdef __RAY_DIFFERENTIALS__ - // Since there is some blur to this reflection, make the - // derivatives a bit bigger. In theory this varies with the - // exponent but the exact relationship is complex and - // requires more ops than are practical. - *domega_in_dx *= 10.0f; - *domega_in_dy *= 10.0f; -#endif } } } @@ -176,8 +168,6 @@ __device int bsdf_westin_sheen_sample(const ShaderClosure *sc, float3 Ng, float3 // TODO: find a better approximation for the diffuse bounce *domega_in_dx = (2 * dot(N, dIdx)) * N - dIdx; *domega_in_dy = (2 * dot(N, dIdy)) * N - dIdy; - *domega_in_dx *= 125.0f; - *domega_in_dy *= 125.0f; #endif } else { From b76d465e3c775b8f7d09fe1f1d0e4fa50a08725b Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Wed, 12 Dec 2012 14:43:11 +0000 Subject: [PATCH 057/252] Fix related to #33480: for blender internal volume rendering, the camera inside volume wasn't accurate, it still isn't quite but hopefully a bit better by taking clip start into account. With clip start it's actually impossible to do a single 'inside' test, since there will not be a single point where all camera rays start from, though for small clip start they will be close together. --- source/blender/render/intern/source/convertblender.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/source/blender/render/intern/source/convertblender.c b/source/blender/render/intern/source/convertblender.c index 37fd213edd5..620f9d41818 100644 --- a/source/blender/render/intern/source/convertblender.c +++ b/source/blender/render/intern/source/convertblender.c @@ -3158,7 +3158,12 @@ static void init_camera_inside_volumes(Render *re) { ObjectInstanceRen *obi; VolumeOb *vo; - float co[3] = {0.f, 0.f, 0.f}; + /* coordinates are all in camera space, so camera coordinate is zero. we also + * add an offset for the clip start, however note that with clip start it's + * actually impossible to do a single 'inside' test, since there will not be + * a single point where all camera rays start from, though for small clip start + * they will be close together. */ + float co[3] = {0.f, 0.f, -re->clipsta}; for (vo= re->volumes.first; vo; vo= vo->next) { for (obi= re->instancetable.first; obi; obi= obi->next) { From 8e9a6871b421cc8b4682b4ce2c046610069791b1 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 12 Dec 2012 15:01:27 +0000 Subject: [PATCH 058/252] fix for crash in own commit r52911 --- source/blender/editors/mesh/editmesh_loopcut.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/source/blender/editors/mesh/editmesh_loopcut.c b/source/blender/editors/mesh/editmesh_loopcut.c index dec45b7f326..3efd823179e 100644 --- a/source/blender/editors/mesh/editmesh_loopcut.c +++ b/source/blender/editors/mesh/editmesh_loopcut.c @@ -334,6 +334,9 @@ static void ringsel_finish(bContext *C, wmOperator *op) SUBDIV_SELECT_LOOPCUT, SUBD_PATH, 0, TRUE, use_only_quads, 0); + /* tessface is already re-recalculated */ + EDBM_update_generic(C, em, FALSE, TRUE); + /* force edge slide to edge select mode in in face select mode */ if (em->selectmode & SCE_SELECT_FACE) { if (em->selectmode == SCE_SELECT_FACE) @@ -345,11 +348,9 @@ static void ringsel_finish(bContext *C, wmOperator *op) WM_event_add_notifier(C, NC_SCENE | ND_TOOLSETTINGS, CTX_data_scene(C)); } - else + else { EDBM_selectmode_flush(lcd->em); - - WM_event_add_notifier(C, NC_GEOM | ND_SELECT | ND_DATA, lcd->ob->data); - DAG_id_tag_update(lcd->ob->data, 0); + } } else { /* XXX Is this piece of code ever used now? Simple loop select is now From d5c2a1f8f4c9d00d7bdb66e5c2a5f8602597f989 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 12 Dec 2012 15:22:54 +0000 Subject: [PATCH 059/252] remove context argument from EDBM_update_generic() --- source/blender/editors/include/ED_mesh.h | 3 +- source/blender/editors/mesh/editmesh_add.c | 2 +- source/blender/editors/mesh/editmesh_knife.c | 6 +- .../blender/editors/mesh/editmesh_loopcut.c | 2 +- source/blender/editors/mesh/editmesh_rip.c | 2 +- source/blender/editors/mesh/editmesh_select.c | 22 +-- source/blender/editors/mesh/editmesh_slide.c | 4 +- source/blender/editors/mesh/editmesh_tools.c | 140 +++++++++--------- source/blender/editors/mesh/editmesh_utils.c | 5 +- source/blender/python/bmesh/bmesh_py_api.c | 10 +- 10 files changed, 94 insertions(+), 102 deletions(-) diff --git a/source/blender/editors/include/ED_mesh.h b/source/blender/editors/include/ED_mesh.h index 23c67f837b8..b4e430e3560 100644 --- a/source/blender/editors/include/ED_mesh.h +++ b/source/blender/editors/include/ED_mesh.h @@ -119,8 +119,7 @@ int EDBM_vert_color_check(struct BMEditMesh *em); void EDBM_mesh_hide(struct BMEditMesh *em, int swap); void EDBM_mesh_reveal(struct BMEditMesh *em); -void EDBM_update_generic(struct bContext *C, struct BMEditMesh *em, - const short do_tessface, const short is_destructive); +void EDBM_update_generic(struct BMEditMesh *em, const short do_tessface, const short is_destructive); struct UvElementMap *EDBM_uv_element_map_create(struct BMEditMesh *em, int selected, int doIslands); void EDBM_uv_element_map_free(struct UvElementMap *vmap); diff --git a/source/blender/editors/mesh/editmesh_add.c b/source/blender/editors/mesh/editmesh_add.c index 94ff32c5aed..adcec5699a9 100644 --- a/source/blender/editors/mesh/editmesh_add.c +++ b/source/blender/editors/mesh/editmesh_add.c @@ -90,7 +90,7 @@ static void make_prim_finish(bContext *C, Object *obedit, int *state, int enter_ EDBM_selectmode_flush_ex(em, SCE_SELECT_VERTEX); /* only recalc editmode tessface if we are staying in editmode */ - EDBM_update_generic(C, em, !exit_editmode, TRUE); + EDBM_update_generic(em, !exit_editmode, TRUE); /* userdef */ if (exit_editmode) { diff --git a/source/blender/editors/mesh/editmesh_knife.c b/source/blender/editors/mesh/editmesh_knife.c index 31415cf98d2..189f5241a68 100644 --- a/source/blender/editors/mesh/editmesh_knife.c +++ b/source/blender/editors/mesh/editmesh_knife.c @@ -2830,7 +2830,7 @@ static void knife_make_cuts(KnifeTool_OpData *kcd) #endif /* called on tool confirmation */ -static void knifetool_finish(bContext *C, wmOperator *op) +static void knifetool_finish(wmOperator *op) { KnifeTool_OpData *kcd = op->customdata; @@ -2841,7 +2841,7 @@ static void knifetool_finish(bContext *C, wmOperator *op) #endif EDBM_mesh_normals_update(kcd->em); - EDBM_update_generic(C, kcd->em, TRUE, TRUE); + EDBM_update_generic(kcd->em, TRUE, TRUE); } /* copied from paint_image.c */ @@ -3129,7 +3129,7 @@ static int knifetool_modal(bContext *C, wmOperator *op, wmEvent *event) /* finish */ ED_region_tag_redraw(kcd->ar); - knifetool_finish(C, op); + knifetool_finish(op); knifetool_exit(C, op); ED_area_headerprint(CTX_wm_area(C), NULL); diff --git a/source/blender/editors/mesh/editmesh_loopcut.c b/source/blender/editors/mesh/editmesh_loopcut.c index 3efd823179e..7721f878ce6 100644 --- a/source/blender/editors/mesh/editmesh_loopcut.c +++ b/source/blender/editors/mesh/editmesh_loopcut.c @@ -335,7 +335,7 @@ static void ringsel_finish(bContext *C, wmOperator *op) use_only_quads, 0); /* tessface is already re-recalculated */ - EDBM_update_generic(C, em, FALSE, TRUE); + EDBM_update_generic(em, FALSE, TRUE); /* force edge slide to edge select mode in in face select mode */ if (em->selectmode & SCE_SELECT_FACE) { diff --git a/source/blender/editors/mesh/editmesh_rip.c b/source/blender/editors/mesh/editmesh_rip.c index 01a2579520a..4909561f677 100644 --- a/source/blender/editors/mesh/editmesh_rip.c +++ b/source/blender/editors/mesh/editmesh_rip.c @@ -1044,7 +1044,7 @@ static int edbm_rip_invoke(bContext *C, wmOperator *op, wmEvent *event) return OPERATOR_CANCELLED; } - EDBM_update_generic(C, em, TRUE, TRUE); + EDBM_update_generic(em, TRUE, TRUE); return OPERATOR_FINISHED; } diff --git a/source/blender/editors/mesh/editmesh_select.c b/source/blender/editors/mesh/editmesh_select.c index e3f918b66c9..6adcede9699 100644 --- a/source/blender/editors/mesh/editmesh_select.c +++ b/source/blender/editors/mesh/editmesh_select.c @@ -725,7 +725,7 @@ static int similar_face_select_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } - EDBM_update_generic(C, em, FALSE, FALSE); + EDBM_update_generic(em, FALSE, FALSE); /* we succeeded */ return OPERATOR_FINISHED; @@ -767,7 +767,7 @@ static int similar_edge_select_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } - EDBM_update_generic(C, em, FALSE, FALSE); + EDBM_update_generic(em, FALSE, FALSE); /* we succeeded */ return OPERATOR_FINISHED; @@ -812,7 +812,7 @@ static int similar_vert_select_exec(bContext *C, wmOperator *op) EDBM_selectmode_flush(em); - EDBM_update_generic(C, em, FALSE, FALSE); + EDBM_update_generic(em, FALSE, FALSE); /* we succeeded */ return OPERATOR_FINISHED; @@ -1431,7 +1431,7 @@ static int edgetag_shortest_path(Scene *scene, BMesh *bm, BMEdge *e_src, BMEdge /* ******************* mesh shortest path select, uses prev-selected edge ****************** */ /* since you want to create paths with multiple selects, it doesn't have extend option */ -static int mouse_mesh_shortest_path_edge(bContext *C, ViewContext *vc) +static int mouse_mesh_shortest_path_edge(ViewContext *vc) { BMEditMesh *em = vc->em; BMEdge *e_dst; @@ -1470,7 +1470,7 @@ static int mouse_mesh_shortest_path_edge(bContext *C, ViewContext *vc) BM_select_history_store(em->bm, e_dst); /* force drawmode for mesh */ - switch (CTX_data_tool_settings(C)->edge_mode) { + switch (vc->scene->toolsettings->edge_mode) { case EDGE_MODE_TAG_SEAM: me->drawflag |= ME_DRAWSEAMS; @@ -1487,7 +1487,7 @@ static int mouse_mesh_shortest_path_edge(bContext *C, ViewContext *vc) break; } - EDBM_update_generic(C, em, FALSE, FALSE); + EDBM_update_generic(em, FALSE, FALSE); return TRUE; } @@ -1644,7 +1644,7 @@ static int facetag_shortest_path(Scene *scene, BMesh *bm, BMFace *f_src, BMFace return 1; } -static int mouse_mesh_shortest_path_face(bContext *C, ViewContext *vc) +static int mouse_mesh_shortest_path_face(ViewContext *vc) { BMEditMesh *em = vc->em; BMFace *f_dst; @@ -1678,7 +1678,7 @@ static int mouse_mesh_shortest_path_face(bContext *C, ViewContext *vc) BM_active_face_set(em->bm, f_dst); - EDBM_update_generic(C, em, FALSE, FALSE); + EDBM_update_generic(em, FALSE, FALSE); return TRUE; } @@ -1703,7 +1703,7 @@ static int edbm_shortest_path_select_invoke(bContext *C, wmOperator *UNUSED(op), em = vc.em; if (em->selectmode & SCE_SELECT_EDGE) { - if (mouse_mesh_shortest_path_edge(C, &vc)) { + if (mouse_mesh_shortest_path_edge(&vc)) { return OPERATOR_FINISHED; } else { @@ -1711,7 +1711,7 @@ static int edbm_shortest_path_select_invoke(bContext *C, wmOperator *UNUSED(op), } } else if (em->selectmode & SCE_SELECT_FACE) { - if (mouse_mesh_shortest_path_face(C, &vc)) { + if (mouse_mesh_shortest_path_face(&vc)) { return OPERATOR_FINISHED; } else { @@ -2635,7 +2635,7 @@ static int edbm_select_nth_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } - EDBM_update_generic(C, em, FALSE, FALSE); + EDBM_update_generic(em, FALSE, FALSE); return OPERATOR_FINISHED; } diff --git a/source/blender/editors/mesh/editmesh_slide.c b/source/blender/editors/mesh/editmesh_slide.c index d5ca2e928da..eb0a21261ce 100644 --- a/source/blender/editors/mesh/editmesh_slide.c +++ b/source/blender/editors/mesh/editmesh_slide.c @@ -264,7 +264,7 @@ static void vtx_slide_confirm(bContext *C, wmOperator *op) EDBM_selectmode_flush(em); /* NC_GEOM | ND_DATA & Retess */ - EDBM_update_generic(C, em, TRUE, FALSE); + EDBM_update_generic(em, TRUE, FALSE); ED_region_tag_redraw(vso->active_region); } @@ -752,7 +752,7 @@ static int edbm_vertex_slide_exec_ex(bContext *C, wmOperator *op, const int do_u if (do_update) { /* Update Geometry */ - EDBM_update_generic(C, em, TRUE, FALSE); + EDBM_update_generic(em, TRUE, FALSE); } return OPERATOR_FINISHED; diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c index 41d5cedbc2c..c04e74a717c 100644 --- a/source/blender/editors/mesh/editmesh_tools.c +++ b/source/blender/editors/mesh/editmesh_tools.c @@ -112,7 +112,7 @@ static int edbm_subdivide_exec(bContext *C, wmOperator *op) RNA_boolean_get(op->ptr, "quadtri"), TRUE, FALSE, RNA_int_get(op->ptr, "seed")); - EDBM_update_generic(C, em, TRUE, TRUE); + EDBM_update_generic(em, TRUE, TRUE); return OPERATOR_FINISHED; } @@ -181,7 +181,7 @@ static int edbm_unsubdivide_exec(bContext *C, wmOperator *op) } EDBM_selectmode_flush(em); - EDBM_update_generic(C, em, TRUE, TRUE); + EDBM_update_generic(em, TRUE, TRUE); return OPERATOR_FINISHED; } @@ -463,7 +463,7 @@ static int edbm_extrude_repeat_exec(bContext *C, wmOperator *op) EDBM_mesh_normals_update(em); - EDBM_update_generic(C, em, TRUE, TRUE); + EDBM_update_generic(em, TRUE, TRUE); return OPERATOR_FINISHED; } @@ -585,7 +585,7 @@ static int edbm_extrude_region_exec(bContext *C, wmOperator *op) * done.*/ EDBM_mesh_normals_update(em); - EDBM_update_generic(C, em, TRUE, TRUE); + EDBM_update_generic(em, TRUE, TRUE); return OPERATOR_FINISHED; } @@ -678,7 +678,7 @@ static int edbm_extrude_faces_exec(bContext *C, wmOperator *op) edbm_extrude_discrete_faces(em, op, BM_ELEM_SELECT, nor); - EDBM_update_generic(C, em, TRUE, TRUE); + EDBM_update_generic(em, TRUE, TRUE); return OPERATOR_FINISHED; } @@ -936,7 +936,7 @@ static int edbm_dupli_extrude_cursor_invoke(bContext *C, wmOperator *op, wmEvent * done. */ EDBM_mesh_normals_update(vc.em); - EDBM_update_generic(C, vc.em, TRUE, TRUE); + EDBM_update_generic(vc.em, TRUE, TRUE); return OPERATOR_FINISHED; } @@ -1001,7 +1001,7 @@ static int edbm_delete_exec(bContext *C, wmOperator *op) EDBM_flag_disable_all(em, BM_ELEM_SELECT); - EDBM_update_generic(C, em, TRUE, TRUE); + EDBM_update_generic(em, TRUE, TRUE); return OPERATOR_FINISHED; } @@ -1034,7 +1034,7 @@ static int edbm_collapse_edge_exec(bContext *C, wmOperator *op) if (!EDBM_op_callf(em, op, "collapse edges=%he", BM_ELEM_SELECT)) return OPERATOR_CANCELLED; - EDBM_update_generic(C, em, TRUE, TRUE); + EDBM_update_generic(em, TRUE, TRUE); return OPERATOR_FINISHED; } @@ -1062,7 +1062,7 @@ static int edbm_collapse_edge_loop_exec(bContext *C, wmOperator *op) if (!EDBM_op_callf(em, op, "dissolve_edge_loop edges=%he", BM_ELEM_SELECT)) return OPERATOR_CANCELLED; - EDBM_update_generic(C, em, TRUE, TRUE); + EDBM_update_generic(em, TRUE, TRUE); return OPERATOR_FINISHED; } @@ -1121,7 +1121,7 @@ static int edbm_add_edge_face_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } - EDBM_update_generic(C, em, TRUE, TRUE); + EDBM_update_generic(em, TRUE, TRUE); return OPERATOR_FINISHED; } @@ -1176,7 +1176,7 @@ static int edbm_mark_seam(bContext *C, wmOperator *op) } ED_uvedit_live_unwrap(scene, obedit); - EDBM_update_generic(C, em, TRUE, FALSE); + EDBM_update_generic(em, TRUE, FALSE); return OPERATOR_FINISHED; } @@ -1230,7 +1230,7 @@ static int edbm_mark_sharp(bContext *C, wmOperator *op) } } - EDBM_update_generic(C, em, TRUE, FALSE); + EDBM_update_generic(em, TRUE, FALSE); return OPERATOR_FINISHED; } @@ -1272,7 +1272,7 @@ static int edbm_vert_connect(bContext *C, wmOperator *op) else { EDBM_selectmode_flush(em); /* so newly created edges get the selection state from the vertex */ - EDBM_update_generic(C, em, TRUE, TRUE); + EDBM_update_generic(em, TRUE, TRUE); return len ? OPERATOR_FINISHED : OPERATOR_CANCELLED; } @@ -1310,7 +1310,7 @@ static int edbm_edge_split_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } - EDBM_update_generic(C, em, TRUE, TRUE); + EDBM_update_generic(em, TRUE, TRUE); return len ? OPERATOR_FINISHED : OPERATOR_CANCELLED; } @@ -1349,7 +1349,7 @@ static int edbm_duplicate_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } - EDBM_update_generic(C, em, TRUE, TRUE); + EDBM_update_generic(em, TRUE, TRUE); return OPERATOR_FINISHED; } @@ -1388,7 +1388,7 @@ static int edbm_flip_normals_exec(bContext *C, wmOperator *op) if (!EDBM_op_callf(em, op, "reverse_faces faces=%hf", BM_ELEM_SELECT)) return OPERATOR_CANCELLED; - EDBM_update_generic(C, em, TRUE, FALSE); + EDBM_update_generic(em, TRUE, FALSE); return OPERATOR_FINISHED; } @@ -1469,7 +1469,7 @@ static int edbm_edge_rotate_selected_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } - EDBM_update_generic(C, em, TRUE, TRUE); + EDBM_update_generic(em, TRUE, TRUE); return OPERATOR_FINISHED; } @@ -1500,7 +1500,7 @@ static int edbm_hide_exec(bContext *C, wmOperator *op) EDBM_mesh_hide(em, RNA_boolean_get(op->ptr, "unselected")); - EDBM_update_generic(C, em, TRUE, FALSE); + EDBM_update_generic(em, TRUE, FALSE); return OPERATOR_FINISHED; } @@ -1530,7 +1530,7 @@ static int edbm_reveal_exec(bContext *C, wmOperator *UNUSED(op)) EDBM_mesh_reveal(em); - EDBM_update_generic(C, em, TRUE, FALSE); + EDBM_update_generic(em, TRUE, FALSE); return OPERATOR_FINISHED; } @@ -1563,7 +1563,7 @@ static int edbm_normals_make_consistent_exec(bContext *C, wmOperator *op) if (RNA_boolean_get(op->ptr, "inside")) EDBM_op_callf(em, op, "reverse_faces faces=%hf", BM_ELEM_SELECT); - EDBM_update_generic(C, em, TRUE, FALSE); + EDBM_update_generic(em, TRUE, FALSE); return OPERATOR_FINISHED; } @@ -1645,7 +1645,7 @@ static int edbm_do_smooth_vertex_exec(bContext *C, wmOperator *op) EDBM_verts_mirror_cache_end(em); } - EDBM_update_generic(C, em, TRUE, FALSE); + EDBM_update_generic(em, TRUE, FALSE); return OPERATOR_FINISHED; } @@ -1721,7 +1721,7 @@ static int edbm_do_smooth_laplacian_vertex_exec(bContext *C, wmOperator *op) EDBM_verts_mirror_cache_end(em); } - EDBM_update_generic(C, em, TRUE, FALSE); + EDBM_update_generic(em, TRUE, FALSE); return OPERATOR_FINISHED; } @@ -1775,7 +1775,7 @@ static int edbm_faces_shade_smooth_exec(bContext *C, wmOperator *UNUSED(op)) mesh_set_smooth_faces(em, 1); - EDBM_update_generic(C, em, FALSE, FALSE); + EDBM_update_generic(em, FALSE, FALSE); return OPERATOR_FINISHED; } @@ -1802,7 +1802,7 @@ static int edbm_faces_shade_flat_exec(bContext *C, wmOperator *UNUSED(op)) mesh_set_smooth_faces(em, 0); - EDBM_update_generic(C, em, FALSE, FALSE); + EDBM_update_generic(em, FALSE, FALSE); return OPERATOR_FINISHED; } @@ -1845,7 +1845,7 @@ static int edbm_rotate_uvs_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } - EDBM_update_generic(C, em, FALSE, FALSE); + EDBM_update_generic(em, FALSE, FALSE); /* we succeeded */ return OPERATOR_FINISHED; @@ -1868,7 +1868,7 @@ static int edbm_reverse_uvs_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } - EDBM_update_generic(C, em, FALSE, FALSE); + EDBM_update_generic(em, FALSE, FALSE); /* we succeeded */ return OPERATOR_FINISHED; @@ -1895,7 +1895,7 @@ static int edbm_rotate_colors_exec(bContext *C, wmOperator *op) } /* dependencies graph and notification stuff */ - EDBM_update_generic(C, em, FALSE, FALSE); + EDBM_update_generic(em, FALSE, FALSE); /* we succeeded */ return OPERATOR_FINISHED; @@ -1919,7 +1919,7 @@ static int edbm_reverse_colors_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } - EDBM_update_generic(C, em, FALSE, FALSE); + EDBM_update_generic(em, FALSE, FALSE); /* we succeeded */ return OPERATOR_FINISHED; @@ -2104,7 +2104,7 @@ static int edbm_merge_exec(bContext *C, wmOperator *op) if (!status) return OPERATOR_CANCELLED; - EDBM_update_generic(C, em, TRUE, TRUE); + EDBM_update_generic(em, TRUE, TRUE); return OPERATOR_FINISHED; } @@ -2221,7 +2221,7 @@ static int edbm_remove_doubles_exec(bContext *C, wmOperator *op) count = totvert_orig - em->bm->totvert; BKE_reportf(op->reports, RPT_INFO, "Removed %d vertices", count); - EDBM_update_generic(C, em, TRUE, TRUE); + EDBM_update_generic(em, TRUE, TRUE); return OPERATOR_FINISHED; } @@ -2328,7 +2328,7 @@ static int edbm_select_vertex_path_exec(bContext *C, wmOperator *op) EDBM_selectmode_flush(em); - EDBM_update_generic(C, em, FALSE, FALSE); + EDBM_update_generic(em, FALSE, FALSE); /* we succeeded */ return OPERATOR_FINISHED; @@ -2403,7 +2403,7 @@ static int edbm_shape_propagate_to_all_exec(bContext *C, wmOperator *op) shape_propagate(em, op); - EDBM_update_generic(C, em, FALSE, FALSE); + EDBM_update_generic(em, FALSE, FALSE); return OPERATOR_FINISHED; } @@ -2474,7 +2474,7 @@ static int edbm_blend_from_shape_exec(bContext *C, wmOperator *op) } } - EDBM_update_generic(C, em, TRUE, FALSE); + EDBM_update_generic(em, TRUE, FALSE); return OPERATOR_FINISHED; } @@ -2665,7 +2665,7 @@ static int edbm_solidify_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } - EDBM_update_generic(C, em, TRUE, TRUE); + EDBM_update_generic(em, TRUE, TRUE); return OPERATOR_FINISHED; } @@ -2990,7 +2990,7 @@ static int edbm_knife_cut_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } - EDBM_update_generic(C, em, TRUE, TRUE); + EDBM_update_generic(em, TRUE, TRUE); return OPERATOR_FINISHED; } @@ -3232,7 +3232,7 @@ static int edbm_separate_exec(bContext *C, wmOperator *op) else BLI_assert(0); if (retval) { - EDBM_update_generic(C, em, TRUE, TRUE); + EDBM_update_generic(em, TRUE, TRUE); } } else { @@ -3332,7 +3332,7 @@ static int edbm_fill_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } - EDBM_update_generic(C, em, TRUE, TRUE); + EDBM_update_generic(em, TRUE, TRUE); return OPERATOR_FINISHED; @@ -3361,7 +3361,7 @@ static int edbm_beautify_fill_exec(bContext *C, wmOperator *op) if (!EDBM_op_callf(em, op, "beautify_fill faces=%hf", BM_ELEM_SELECT)) return OPERATOR_CANCELLED; - EDBM_update_generic(C, em, TRUE, TRUE); + EDBM_update_generic(em, TRUE, TRUE); return OPERATOR_FINISHED; } @@ -3392,7 +3392,7 @@ static int edbm_quads_convert_to_tris_exec(bContext *C, wmOperator *op) if (!EDBM_op_callf(em, op, "triangulate faces=%hf use_beauty=%b", BM_ELEM_SELECT, use_beauty)) return OPERATOR_CANCELLED; - EDBM_update_generic(C, em, TRUE, TRUE); + EDBM_update_generic(em, TRUE, TRUE); return OPERATOR_FINISHED; } @@ -3433,7 +3433,7 @@ static int edbm_tris_convert_to_quads_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } - EDBM_update_generic(C, em, TRUE, TRUE); + EDBM_update_generic(em, TRUE, TRUE); return OPERATOR_FINISHED; } @@ -3489,7 +3489,7 @@ static int edbm_dissolve_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } - EDBM_update_generic(C, em, TRUE, TRUE); + EDBM_update_generic(em, TRUE, TRUE); return OPERATOR_FINISHED; } @@ -3561,7 +3561,7 @@ static int edbm_dissolve_limited_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } - EDBM_update_generic(C, em, TRUE, TRUE); + EDBM_update_generic(em, TRUE, TRUE); return OPERATOR_FINISHED; } @@ -3606,7 +3606,7 @@ static int edbm_split_exec(bContext *C, wmOperator *op) /* Geometry has changed, need to recalc normals and looptris */ EDBM_mesh_normals_update(em); - EDBM_update_generic(C, em, TRUE, TRUE); + EDBM_update_generic(em, TRUE, TRUE); return OPERATOR_FINISHED; } @@ -3665,7 +3665,7 @@ static int edbm_spin_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } - EDBM_update_generic(C, em, TRUE, TRUE); + EDBM_update_generic(em, TRUE, TRUE); return OPERATOR_FINISHED; } @@ -3788,7 +3788,7 @@ static int edbm_screw_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } - EDBM_update_generic(C, em, TRUE, TRUE); + EDBM_update_generic(em, TRUE, TRUE); return OPERATOR_FINISHED; } @@ -4603,7 +4603,7 @@ static int edbm_noise_exec(bContext *C, wmOperator *op) EDBM_mesh_normals_update(em); - EDBM_update_generic(C, em, TRUE, FALSE); + EDBM_update_generic(em, TRUE, FALSE); return OPERATOR_FINISHED; } @@ -4762,7 +4762,7 @@ static int edbm_bevel_init(bContext *C, wmOperator *op, int is_modal) return 1; } -static int edbm_bevel_calc(bContext *C, wmOperator *op) +static int edbm_bevel_calc(wmOperator *op) { BevelData *opdata = op->customdata; BMEditMesh *em = opdata->em; @@ -4827,7 +4827,7 @@ static int edbm_bevel_calc(bContext *C, wmOperator *op) EDBM_mesh_normals_update(opdata->em); - EDBM_update_generic(C, opdata->em, TRUE, TRUE); + EDBM_update_generic(opdata->em, TRUE, TRUE); return 1; } @@ -4859,7 +4859,7 @@ static int edbm_bevel_cancel(bContext *C, wmOperator *op) BevelData *opdata = op->customdata; if (opdata->is_modal) { EDBM_redo_state_free(&opdata->mesh_backup, opdata->em, TRUE); - EDBM_update_generic(C, opdata->em, FALSE, TRUE); + EDBM_update_generic(opdata->em, FALSE, TRUE); } edbm_bevel_exit(C, op); @@ -4877,7 +4877,7 @@ static int edbm_bevel_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } - if (!edbm_bevel_calc(C, op)) { + if (!edbm_bevel_calc(op)) { edbm_bevel_cancel(C, op); return OPERATOR_CANCELLED; } @@ -4914,7 +4914,7 @@ static int edbm_bevel_invoke(bContext *C, wmOperator *op, wmEvent *event) edbm_bevel_update_header(op, C); - if (!edbm_bevel_calc(C, op)) { + if (!edbm_bevel_calc(op)) { edbm_bevel_cancel(C, op); return OPERATOR_CANCELLED; } @@ -4984,7 +4984,7 @@ static int edbm_bevel_modal(bContext *C, wmOperator *op, wmEvent *event) float value = RNA_float_get(op->ptr, "offset"); applyNumInput(&opdata->num_input, &value); RNA_float_set(op->ptr, "offset", value); - edbm_bevel_calc(C, op); + edbm_bevel_calc(op); edbm_bevel_update_header(op, C); return OPERATOR_RUNNING_MODAL; } @@ -5017,7 +5017,7 @@ static int edbm_bevel_modal(bContext *C, wmOperator *op, wmEvent *event) RNA_float_set(op->ptr, "percent", factor); #endif - edbm_bevel_calc(C, op); + edbm_bevel_calc(op); edbm_bevel_update_header(op, C); } break; @@ -5025,7 +5025,7 @@ static int edbm_bevel_modal(bContext *C, wmOperator *op, wmEvent *event) case LEFTMOUSE: case PADENTER: case RETKEY: - edbm_bevel_calc(C, op); + edbm_bevel_calc(op); edbm_bevel_exit(C, op); return OPERATOR_FINISHED; @@ -5037,7 +5037,7 @@ static int edbm_bevel_modal(bContext *C, wmOperator *op, wmEvent *event) segments++; RNA_int_set(op->ptr, "segments", segments); - edbm_bevel_calc(C, op); + edbm_bevel_calc(op); edbm_bevel_update_header(op, C); break; @@ -5048,7 +5048,7 @@ static int edbm_bevel_modal(bContext *C, wmOperator *op, wmEvent *event) segments = max_ii(segments - 1, 1); RNA_int_set(op->ptr, "segments", segments); - edbm_bevel_calc(C, op); + edbm_bevel_calc(op); edbm_bevel_update_header(op, C); break; @@ -5140,7 +5140,7 @@ static int edbm_bridge_edge_loops_exec(bContext *C, wmOperator *op) } else { - EDBM_update_generic(C, em, TRUE, TRUE); + EDBM_update_generic(em, TRUE, TRUE); return OPERATOR_FINISHED; } } @@ -5263,7 +5263,7 @@ static int edbm_inset_cancel(bContext *C, wmOperator *op) opdata = op->customdata; if (opdata->is_modal) { EDBM_redo_state_free(&opdata->backup, opdata->em, TRUE); - EDBM_update_generic(C, opdata->em, FALSE, TRUE); + EDBM_update_generic(opdata->em, FALSE, TRUE); } edbm_inset_exit(C, op); @@ -5273,7 +5273,7 @@ static int edbm_inset_cancel(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } -static int edbm_inset_calc(bContext *C, wmOperator *op) +static int edbm_inset_calc(wmOperator *op) { InsetData *opdata; BMEditMesh *em; @@ -5318,7 +5318,7 @@ static int edbm_inset_calc(bContext *C, wmOperator *op) return 0; } else { - EDBM_update_generic(C, em, TRUE, TRUE); + EDBM_update_generic(em, TRUE, TRUE); return 1; } } @@ -5327,7 +5327,7 @@ static int edbm_inset_exec(bContext *C, wmOperator *op) { edbm_inset_init(C, op, FALSE); - if (!edbm_inset_calc(C, op)) { + if (!edbm_inset_calc(op)) { edbm_inset_exit(C, op); return OPERATOR_CANCELLED; } @@ -5358,7 +5358,7 @@ static int edbm_inset_invoke(bContext *C, wmOperator *op, wmEvent *event) opdata->initial_length = len_v2(mlen); opdata->pixel_size = rv3d ? ED_view3d_pixel_size(rv3d, center_3d) : 1.0f; - edbm_inset_calc(C, op); + edbm_inset_calc(op); edbm_inset_update_header(op, C); @@ -5381,7 +5381,7 @@ static int edbm_inset_modal(bContext *C, wmOperator *op, wmEvent *event) RNA_float_set(op->ptr, "thickness", amounts[0]); RNA_float_set(op->ptr, "depth", amounts[1]); - if (edbm_inset_calc(C, op)) { + if (edbm_inset_calc(op)) { edbm_inset_update_header(op, C); return OPERATOR_RUNNING_MODAL; } @@ -5422,7 +5422,7 @@ static int edbm_inset_modal(bContext *C, wmOperator *op, wmEvent *event) RNA_float_set(op->ptr, "thickness", amount); } - if (edbm_inset_calc(C, op)) + if (edbm_inset_calc(op)) edbm_inset_update_header(op, C); else { edbm_inset_cancel(C, op); @@ -5434,7 +5434,7 @@ static int edbm_inset_modal(bContext *C, wmOperator *op, wmEvent *event) case LEFTMOUSE: case PADENTER: case RETKEY: - edbm_inset_calc(C, op); + edbm_inset_calc(op); edbm_inset_exit(C, op); return OPERATOR_FINISHED; @@ -5483,7 +5483,7 @@ static int edbm_inset_modal(bContext *C, wmOperator *op, wmEvent *event) if (event->val == KM_PRESS) { int use_outset = RNA_boolean_get(op->ptr, "use_outset"); RNA_boolean_set(op->ptr, "use_outset", !use_outset); - if (edbm_inset_calc(C, op)) { + if (edbm_inset_calc(op)) { edbm_inset_update_header(op, C); } else { @@ -5496,7 +5496,7 @@ static int edbm_inset_modal(bContext *C, wmOperator *op, wmEvent *event) if (event->val == KM_PRESS) { int use_boundary = RNA_boolean_get(op->ptr, "use_boundary"); RNA_boolean_set(op->ptr, "use_boundary", !use_boundary); - if (edbm_inset_calc(C, op)) { + if (edbm_inset_calc(op)) { edbm_inset_update_header(op, C); } else { @@ -5581,7 +5581,7 @@ static int edbm_wireframe_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } else { - EDBM_update_generic(C, em, TRUE, TRUE); + EDBM_update_generic(em, TRUE, TRUE); return OPERATOR_FINISHED; } } @@ -5671,7 +5671,7 @@ static int edbm_convex_hull_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } else { - EDBM_update_generic(C, em, TRUE, TRUE); + EDBM_update_generic(em, TRUE, TRUE); EDBM_selectmode_flush(em); return OPERATOR_FINISHED; } @@ -5726,7 +5726,7 @@ static int mesh_symmetrize_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } else { - EDBM_update_generic(C, em, TRUE, TRUE); + EDBM_update_generic(em, TRUE, TRUE); EDBM_selectmode_flush(em); return OPERATOR_FINISHED; } diff --git a/source/blender/editors/mesh/editmesh_utils.c b/source/blender/editors/mesh/editmesh_utils.c index 9852283430a..a07fb4ea66e 100644 --- a/source/blender/editors/mesh/editmesh_utils.c +++ b/source/blender/editors/mesh/editmesh_utils.c @@ -1342,13 +1342,12 @@ void EDBM_mesh_reveal(BMEditMesh *em) /* so many tools call these that we better make it a generic function. */ -void EDBM_update_generic(bContext *C, BMEditMesh *em, - const short do_tessface, const short is_destructive) +void EDBM_update_generic(BMEditMesh *em, const short do_tessface, const short is_destructive) { Object *ob = em->ob; /* order of calling isn't important */ DAG_id_tag_update(ob->data, OB_RECALC_DATA); - WM_event_add_notifier(C, NC_GEOM | ND_DATA, ob->data); + WM_main_add_notifier(NC_GEOM | ND_DATA, ob->data); if (do_tessface) { BMEdit_RecalcTessellation(em); diff --git a/source/blender/python/bmesh/bmesh_py_api.c b/source/blender/python/bmesh/bmesh_py_api.c index 5e6fd1c8019..9abb13731af 100644 --- a/source/blender/python/bmesh/bmesh_py_api.c +++ b/source/blender/python/bmesh/bmesh_py_api.c @@ -134,14 +134,8 @@ static PyObject *bpy_bm_update_edit_mesh(PyObject *UNUSED(self), PyObject *args) } { - /* XXX, not great - infact this function could just not use the context at all - * postpone that change until after release: BMESH_TODO - campbell */ - extern struct bContext *BPy_GetContext(void); - extern void EDBM_update_generic(struct bContext *C, BMEditMesh *em, - const short do_tessface, const short is_destructive); - - struct bContext *C = BPy_GetContext(); - EDBM_update_generic(C, me->edit_btmesh, do_tessface, is_destructive); + extern void EDBM_update_generic(BMEditMesh *em, const short do_tessface, const short is_destructive); + EDBM_update_generic(me->edit_btmesh, do_tessface, is_destructive); } Py_RETURN_NONE; From 3c4df7dd204144f563183b594e10d0c8ceec06dc Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 12 Dec 2012 15:41:15 +0000 Subject: [PATCH 060/252] style cleanup: also change node selection method not to compare nodes a lot. --- release/scripts/startup/bl_operators/node.py | 31 +++++++++++++------- 1 file changed, 21 insertions(+), 10 deletions(-) diff --git a/release/scripts/startup/bl_operators/node.py b/release/scripts/startup/bl_operators/node.py index 38adcdf7368..071eb2e75f9 100644 --- a/release/scripts/startup/bl_operators/node.py +++ b/release/scripts/startup/bl_operators/node.py @@ -37,11 +37,13 @@ class NodeAddOperator(): space = context.space_data tree = space.edit_tree - node = tree.nodes.new(type=node_type) - # select only the new node for n in tree.nodes: - n.select = (n == node) + n.select = False + + node = tree.nodes.new(type=node_type) + + node.select = True tree.nodes.active = node node.location = space.cursor_location return node @@ -64,11 +66,15 @@ class NODE_OT_add_node(NodeAddOperator, Operator): bl_idname = "node.add_node" bl_label = "Add Node" - type = StringProperty(name="Node Type", description="Node type") - + type = StringProperty( + name="Node Type", + description="Node type", + ) # optional group tree parameter for group nodes - group_tree = StringProperty(name="Group tree", description="Group node tree name") - + group_tree = StringProperty( + name="Group tree", + description="Group node tree name", + ) def execute(self, context): node = self.create_node(context, self.type) @@ -85,10 +91,15 @@ class NODE_OT_add_node_move(NODE_OT_add_node): bl_idname = "node.add_node_move" bl_label = "Add Node and Move" - type = StringProperty(name="Node Type", description="Node type") - + type = StringProperty( + name="Node Type", + description="Node type", + ) # optional group tree parameter for group nodes - group_tree = StringProperty(name="Group tree", description="Group node tree name") + group_tree = StringProperty( + name="Group tree", + description="Group node tree name", + ) def invoke(self, context, event): self.store_mouse_cursor(context, event) From 450139fd9498fac8a9927eb364d3ce1059a432a4 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 12 Dec 2012 16:32:05 +0000 Subject: [PATCH 061/252] edge slide: skip creating BMBVHTree when its not used. --- source/blender/editors/transform/transform.c | 31 ++++++++++++++------ 1 file changed, 22 insertions(+), 9 deletions(-) diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c index d877d506e3e..b50cb4428a5 100644 --- a/source/blender/editors/transform/transform.c +++ b/source/blender/editors/transform/transform.c @@ -4903,7 +4903,7 @@ static int createSlideVerts(TransInfo *t) BMEdge *e, *e1; BMVert *v, *v2, *first; TransDataSlideVert *sv_array; - BMBVHTree *btree = BMBVH_NewBVH(em, BMBVH_RESPECT_HIDDEN, NULL, NULL); + BMBVHTree *btree; SmallHash table; SlideData *sld = MEM_callocN(sizeof(*sld), "sld"); View3D *v3d = NULL; @@ -4915,6 +4915,7 @@ static int createSlideVerts(TransInfo *t) float vec[3], vec2[3] /*, lastvec[3], size, dis=0.0, z */ /* UNUSED */; float dir[3], maxdist, (*loop_dir)[3], *loop_maxdist; int numsel, i, j, loop_nr, l_nr; + int use_btree_disp; if (t->spacetype == SPACE_VIEW3D) { /* background mode support */ @@ -4922,6 +4923,15 @@ static int createSlideVerts(TransInfo *t) rv3d = t->ar ? t->ar->regiondata : NULL; } + use_btree_disp = (v3d && t->obedit->dt > OB_WIRE && v3d->drawtype > OB_WIRE); + + if (use_btree_disp) { + btree = BMBVH_NewBVH(em, BMBVH_RESPECT_HIDDEN, NULL, NULL); + } + else { + btree = NULL; + } + sld->is_proportional = TRUE; sld->curr_sv_index = 0; sld->flipped_vtx = FALSE; @@ -4955,7 +4965,8 @@ static int createSlideVerts(TransInfo *t) if (numsel == 0 || numsel > 2) { MEM_freeN(sld); - BMBVH_FreeBVH(btree); + if (btree) + BMBVH_FreeBVH(btree); return 0; /* invalid edge selection */ } } @@ -4965,7 +4976,8 @@ static int createSlideVerts(TransInfo *t) if (BM_elem_flag_test(e, BM_ELEM_SELECT)) { if (!BM_edge_is_manifold(e)) { MEM_freeN(sld); - BMBVH_FreeBVH(btree); + if (btree) + BMBVH_FreeBVH(btree); return 0; /* can only handle exactly 2 faces around each edge */ } } @@ -4985,7 +4997,8 @@ static int createSlideVerts(TransInfo *t) if (!j) { MEM_freeN(sld); - BMBVH_FreeBVH(btree); + if (btree) + BMBVH_FreeBVH(btree); return 0; } @@ -5140,9 +5153,7 @@ static int createSlideVerts(TransInfo *t) continue; /* This test is only relevant if object is not wire-drawn! See [#32068]. */ - if (v3d && t->obedit->dt > OB_WIRE && v3d->drawtype > OB_WIRE && - !BMBVH_EdgeVisible(btree, e2, ar, v3d, t->obedit)) - { + if (use_btree_disp && !BMBVH_EdgeVisible(btree, e2, ar, v3d, t->obedit)) { continue; } @@ -5244,10 +5255,12 @@ static int createSlideVerts(TransInfo *t) t->customData = sld; BLI_smallhash_release(&table); - BMBVH_FreeBVH(btree); + if (btree) { + BMBVH_FreeBVH(btree); + } MEM_freeN(loop_dir); MEM_freeN(loop_maxdist); - + return 1; } From 82cc300ec6c72f5977ceea249b0af8a0756f3b36 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 12 Dec 2012 16:39:16 +0000 Subject: [PATCH 062/252] fix for another crash in r52911 --- source/blender/editors/transform/transform.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c index b50cb4428a5..6a5904767b7 100644 --- a/source/blender/editors/transform/transform.c +++ b/source/blender/editors/transform/transform.c @@ -5261,6 +5261,9 @@ static int createSlideVerts(TransInfo *t) MEM_freeN(loop_dir); MEM_freeN(loop_maxdist); + /* arrays are dirty from copying faces: EDBM_index_arrays_free */ + EDBM_update_generic(em, FALSE, TRUE); + return 1; } @@ -5432,6 +5435,9 @@ void freeSlideTempFaces(SlideData *sld) BLI_smallhash_release(&sld->origfaces); sld->origfaces_init = FALSE; + + /* arrays are dirty from removing faces: EDBM_index_arrays_free */ + EDBM_update_generic(sld->em, FALSE, TRUE); } } From f1d3a2e130d9ce18466d3587decf70567c80c1eb Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Wed, 12 Dec 2012 16:51:05 +0000 Subject: [PATCH 063/252] Fix error compiling in debug build, should test #ifndef NDEBUG instead of --- source/blender/editors/include/ED_mesh.h | 2 +- source/blender/editors/mesh/editmesh_utils.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/source/blender/editors/include/ED_mesh.h b/source/blender/editors/include/ED_mesh.h index b4e430e3560..1b4a67d38c0 100644 --- a/source/blender/editors/include/ED_mesh.h +++ b/source/blender/editors/include/ED_mesh.h @@ -92,7 +92,7 @@ void EDBM_mesh_load(struct Object *ob); void EDBM_index_arrays_ensure(struct BMEditMesh *em, const char htype); void EDBM_index_arrays_init(struct BMEditMesh *em, const char htype); void EDBM_index_arrays_free(struct BMEditMesh *em); -#ifdef DEBUG +#ifndef NDEBUG int EDBM_index_arrays_check(struct BMEditMesh *em); #endif struct BMVert *EDBM_vert_at_index(struct BMEditMesh *em, int index); diff --git a/source/blender/editors/mesh/editmesh_utils.c b/source/blender/editors/mesh/editmesh_utils.c index a07fb4ea66e..cbb7262beb2 100644 --- a/source/blender/editors/mesh/editmesh_utils.c +++ b/source/blender/editors/mesh/editmesh_utils.c @@ -466,7 +466,7 @@ void EDBM_index_arrays_free(BMEditMesh *em) } /* debug check only - no need to optimize */ -#ifdef DEBUG +#ifndef NDEBUG int EDBM_index_arrays_check(BMEditMesh *em) { BMIter iter; From 5ebe822f4b022e9d10eafe41359c7a47eac16148 Mon Sep 17 00:00:00 2001 From: Lukas Toenne Date: Wed, 12 Dec 2012 17:50:35 +0000 Subject: [PATCH 064/252] Fix for range checks in generated RNA functions. The code was skipping the value clamping for float and int properties if using the min/max values of the respective number format, but not taking into account range callbacks of the property. --- source/blender/makesrna/intern/makesrna.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/blender/makesrna/intern/makesrna.c b/source/blender/makesrna/intern/makesrna.c index 6fa53f4e029..1d9b737ba29 100644 --- a/source/blender/makesrna/intern/makesrna.c +++ b/source/blender/makesrna/intern/makesrna.c @@ -760,7 +760,7 @@ static void rna_clamp_value(FILE *f, PropertyRNA *prop, int array) if (prop->type == PROP_INT) { IntPropertyRNA *iprop = (IntPropertyRNA *)prop; - if (iprop->hardmin != INT_MIN || iprop->hardmax != INT_MAX) { + if (iprop->hardmin != INT_MIN || iprop->hardmax != INT_MAX || iprop->range) { if (array) fprintf(f, "CLAMPIS(values[i], "); else fprintf(f, "CLAMPIS(value, "); if (iprop->range) { @@ -776,7 +776,7 @@ static void rna_clamp_value(FILE *f, PropertyRNA *prop, int array) else if (prop->type == PROP_FLOAT) { FloatPropertyRNA *fprop = (FloatPropertyRNA *)prop; - if (fprop->hardmin != -FLT_MAX || fprop->hardmax != FLT_MAX) { + if (fprop->hardmin != -FLT_MAX || fprop->hardmax != FLT_MAX || fprop->range) { if (array) fprintf(f, "CLAMPIS(values[i], "); else fprintf(f, "CLAMPIS(value, "); if (fprop->range) { From 5783283d7220f9dccd871a31d55ba28c96a07834 Mon Sep 17 00:00:00 2001 From: Lukas Toenne Date: Wed, 12 Dec 2012 17:50:44 +0000 Subject: [PATCH 065/252] RNA properties for width and height of nodes. Note: For most node types the height is determined automatically. Note2: There are two independent width values, one for regular nodes and one for the collapsed ("hidden") state. --- source/blender/makesrna/intern/rna_nodetree.c | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c index 1da9a450c2c..eb614ba8fc1 100644 --- a/source/blender/makesrna/intern/rna_nodetree.c +++ b/source/blender/makesrna/intern/rna_nodetree.c @@ -499,6 +499,20 @@ static void rna_Node_name_set(PointerRNA *ptr, const char *value) BKE_all_animdata_fix_paths_rename(NULL, "nodes", oldname, node->name); } +static void rna_Node_width_range(PointerRNA *ptr, float *min, float *max, float *softmin, float *softmax) +{ + bNode *node = ptr->data; + *min = *softmin = node->typeinfo->minwidth; + *max = *softmax = node->typeinfo->maxwidth; +} + +static void rna_Node_height_range(PointerRNA *ptr, float *min, float *max, float *softmin, float *softmax) +{ + bNode *node = ptr->data; + *min = *softmin = node->typeinfo->minheight; + *max = *softmax = node->typeinfo->maxheight; +} + static void rna_NodeSocket_update(Main *bmain, Scene *scene, PointerRNA *ptr) { bNodeTree *ntree = (bNodeTree *)ptr->id.data; @@ -4609,6 +4623,24 @@ static void rna_def_node(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Location", ""); RNA_def_property_update(prop, NC_NODE, "rna_Node_update"); + prop = RNA_def_property(srna, "width", PROP_FLOAT, PROP_XYZ); + RNA_def_property_float_sdna(prop, NULL, "width"); + RNA_def_property_float_funcs(prop, NULL, NULL, "rna_Node_width_range"); + RNA_def_property_ui_text(prop, "Width", "Width of the node"); + RNA_def_property_update(prop, NC_NODE | ND_DISPLAY, NULL); + + prop = RNA_def_property(srna, "width_hidden", PROP_FLOAT, PROP_XYZ); + RNA_def_property_float_sdna(prop, NULL, "miniwidth"); + RNA_def_property_float_funcs(prop, NULL, NULL, "rna_Node_width_range"); + RNA_def_property_ui_text(prop, "Width Hidden", "Width of the node in hidden state"); + RNA_def_property_update(prop, NC_NODE | ND_DISPLAY, NULL); + + prop = RNA_def_property(srna, "height", PROP_FLOAT, PROP_XYZ); + RNA_def_property_float_sdna(prop, NULL, "height"); + RNA_def_property_float_funcs(prop, NULL, NULL, "rna_Node_height_range"); + RNA_def_property_ui_text(prop, "Height", "Height of the node"); + RNA_def_property_update(prop, NC_NODE | ND_DISPLAY, NULL); + prop = RNA_def_property(srna, "name", PROP_STRING, PROP_NONE); RNA_def_property_ui_text(prop, "Name", "Unique node identifier"); RNA_def_struct_name_property(srna, prop); From 26ae649b01c1147ec2fbb147bb652a8bc49a0019 Mon Sep 17 00:00:00 2001 From: Jens Verwiebe Date: Wed, 12 Dec 2012 18:31:19 +0000 Subject: [PATCH 066/252] OSX/cmake: fix ndof compile --- CMakeLists.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 3e1c8fec02a..7433d7259ac 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1521,7 +1521,8 @@ elseif(APPLE) endif() if(WITH_INPUT_NDOF) - set(PLATFORM_LINKFLAGS "${PLATFORM_LINKFLAGS} -weak_framework 3DconnexionClient") + set(PLATFORM_LINKFLAGS "${PLATFORM_LINKFLAGS} -F/Library/Frameworks -weak_framework 3DconnexionClient") + set(NDOF_INCLUDE_DIRS /Library/Frameworks/3DconnexionClient.framework ) endif() endif() From 12b642062c6fcef70151bd2424c2ebbc6a1a6843 Mon Sep 17 00:00:00 2001 From: Ton Roosendaal Date: Wed, 12 Dec 2012 18:58:11 +0000 Subject: [PATCH 067/252] Holiday coding log :) Nice formatted version (pictures soon): http://wiki.blender.org/index.php/Dev:Ref/Release_Notes/2.66/Usability Short list of main changes: - Transparent region option (over main region), added code to blend in/out such panels. - Min size window now 640 x 480 - Fixed DPI for ui - lots of cleanup and changes everywhere. Icon image need correct size still, layer-in-use icon needs remake. - Macbook retina support, use command line --no-native-pixels to disable it - Timeline Marker label was drawing wrong - Trackpad and magic mouse: supports zoom (hold ctrl) - Fix for splash position: removed ghost function and made window size update after creation immediate - Fast undo buffer save now adds UI as well. Could be checked for regular file save even... Quit.blend and temp file saving use this now. - Dixed filename in window on reading quit.blend or temp saves, and they now add a warning in window title: "(Recovered)" - New Userpref option "Keep Session" - this always saves quit.blend, and loads on start. This allows keeping UI and data without actual saves, until you actually save. When you load startup.blend and quit, it recognises the quit.blend as a startup (no file name in header) - Added 3D view copy/paste buffers (selected objects). Shortcuts ctrl-c, ctrl-v (OSX, cmd-c, cmd-v). Coded partial file saving for it. Could be used for other purposes. Todo: use OS clipboards. - User preferences (themes, keymaps, user settings) now can be saved as a separate file. Old option is called "Save Startup File" the new one "Save User Settings". To visualise this difference, the 'save startup file' button has been removed from user preferences window. That option is available as CTRL+U and in File menu still. - OSX: fixed bug that stopped giving mouse events outside window. This also fixes "Continuous Grab" for OSX. (error since 2009) --- intern/ghost/GHOST_C-api.h | 10 + intern/ghost/GHOST_ISystem.h | 7 + intern/ghost/intern/GHOST_C-api.cpp | 13 + intern/ghost/intern/GHOST_System.cpp | 13 + intern/ghost/intern/GHOST_System.h | 11 + intern/ghost/intern/GHOST_SystemCocoa.mm | 27 +- intern/ghost/intern/GHOST_SystemWin32.cpp | 4 +- intern/ghost/intern/GHOST_WindowCocoa.mm | 13 +- intern/ghost/intern/GHOST_WindowX11.cpp | 4 +- .../scripts/startup/bl_ui/space_userpref.py | 4 +- source/blender/blenfont/BLF_api.h | 1 + source/blender/blenfont/intern/blf.c | 5 + source/blender/blenkernel/BKE_blender.h | 16 +- source/blender/blenkernel/BKE_global.h | 2 +- source/blender/blenkernel/BKE_main.h | 3 +- source/blender/blenkernel/BKE_scene.h | 3 +- source/blender/blenkernel/intern/blender.c | 250 +++++++++++++++--- source/blender/blenkernel/intern/scene.c | 13 +- source/blender/blenlib/BLI_path_util.h | 1 + source/blender/blenloader/BLO_readfile.h | 21 +- source/blender/blenloader/intern/readfile.c | 138 ++++++---- source/blender/blenloader/intern/writefile.c | 18 +- .../editors/animation/anim_channels_defines.c | 36 ++- source/blender/editors/animation/anim_draw.c | 9 +- .../blender/editors/animation/anim_markers.c | 14 +- .../editors/animation/keyframes_draw.c | 6 +- source/blender/editors/gpencil/drawgpencil.c | 2 + source/blender/editors/include/BIF_gl.h | 8 + source/blender/editors/include/ED_anim_api.h | 24 +- source/blender/editors/include/ED_screen.h | 2 +- source/blender/editors/include/UI_interface.h | 13 +- source/blender/editors/include/UI_view2d.h | 6 +- source/blender/editors/interface/interface.c | 21 +- .../editors/interface/interface_draw.c | 14 +- .../editors/interface/interface_handlers.c | 4 +- .../editors/interface/interface_icons.c | 9 +- .../editors/interface/interface_intern.h | 2 +- .../editors/interface/interface_layout.c | 14 +- .../editors/interface/interface_panel.c | 12 +- .../editors/interface/interface_regions.c | 78 +++--- .../editors/interface/interface_style.c | 40 ++- .../editors/interface/interface_templates.c | 45 ++-- .../editors/interface/interface_widgets.c | 177 +++++++------ source/blender/editors/interface/resources.c | 19 +- source/blender/editors/interface/view2d.c | 52 ++-- source/blender/editors/screen/area.c | 167 ++++++------ source/blender/editors/screen/glutil.c | 7 +- source/blender/editors/screen/screen_edit.c | 75 ++++-- source/blender/editors/screen/screen_intern.h | 12 +- source/blender/editors/screen/screen_ops.c | 159 ++++++++++- .../editors/space_console/console_draw.c | 5 +- .../blender/editors/space_graph/graph_draw.c | 2 +- source/blender/editors/space_info/info_draw.c | 5 +- source/blender/editors/space_info/textview.c | 3 +- .../editors/space_logic/logic_window.c | 20 +- source/blender/editors/space_nla/nla_draw.c | 36 +-- source/blender/editors/space_node/drawnode.c | 37 ++- source/blender/editors/space_node/node_add.c | 8 +- source/blender/editors/space_node/node_draw.c | 68 +++-- source/blender/editors/space_node/node_edit.c | 12 +- .../blender/editors/space_node/node_intern.h | 47 ++-- .../editors/space_node/node_templates.c | 3 + .../blender/editors/space_node/space_node.c | 13 +- .../editors/space_outliner/outliner_draw.c | 49 ++-- source/blender/editors/space_text/text_draw.c | 47 ++-- .../blender/editors/space_text/text_intern.h | 11 +- source/blender/editors/space_text/text_ops.c | 8 +- .../blender/editors/space_text/text_python.c | 10 +- .../editors/space_view3d/space_view3d.c | 2 +- .../editors/space_view3d/view3d_draw.c | 89 ++++--- .../editors/space_view3d/view3d_edit.c | 2 +- .../blender/editors/space_view3d/view3d_ops.c | 79 ++++++ .../editors/space_view3d/view3d_view.c | 2 +- .../editors/transform/transform_conversions.c | 16 +- source/blender/makesdna/DNA_screen_types.h | 9 +- source/blender/makesdna/DNA_space_types.h | 9 +- source/blender/makesdna/DNA_userdef_types.h | 17 +- source/blender/makesrna/intern/rna_userdef.c | 20 +- source/blender/windowmanager/WM_api.h | 11 +- source/blender/windowmanager/intern/wm_draw.c | 83 ++++-- .../windowmanager/intern/wm_event_system.c | 15 +- .../blender/windowmanager/intern/wm_files.c | 99 +++++-- .../windowmanager/intern/wm_init_exit.c | 29 +- .../windowmanager/intern/wm_operators.c | 74 ++++-- .../windowmanager/intern/wm_subwindow.c | 12 +- .../blender/windowmanager/intern/wm_window.c | 229 ++++++++++------ .../blender/windowmanager/wm_event_system.h | 3 + source/blender/windowmanager/wm_event_types.h | 1 + source/blender/windowmanager/wm_files.h | 8 +- source/blender/windowmanager/wm_window.h | 2 - source/creator/creator.c | 7 + 91 files changed, 1893 insertions(+), 913 deletions(-) diff --git a/intern/ghost/GHOST_C-api.h b/intern/ghost/GHOST_C-api.h index f886dfd9d7d..ab5feb287d8 100644 --- a/intern/ghost/GHOST_C-api.h +++ b/intern/ghost/GHOST_C-api.h @@ -852,6 +852,16 @@ extern int GHOST_toggleConsole(int action); */ extern int GHOST_confirmQuit(GHOST_WindowHandle windowhandle); +/** + * Use native pixel size (MacBook pro 'retina'), if supported. + */ +extern int GHOST_UseNativePixels(void); + +/** + * If window was opened using native pixel size, it returns scaling factor. + */ +extern float GHOST_GetNativePixelSize(void); + #ifdef __cplusplus } diff --git a/intern/ghost/GHOST_ISystem.h b/intern/ghost/GHOST_ISystem.h index ad5d2379787..dfe01521a29 100644 --- a/intern/ghost/GHOST_ISystem.h +++ b/intern/ghost/GHOST_ISystem.h @@ -294,6 +294,13 @@ public: * \return The current status. */ virtual bool getFullScreen(void) = 0; + + /** + * Native pixel size support (MacBook 'retina'). + * \return The pixel size in float. + */ + virtual bool useNativePixel(void) = 0; + virtual float getNativePixelSize(void) = 0; /*************************************************************************************** * Event management functionality diff --git a/intern/ghost/intern/GHOST_C-api.cpp b/intern/ghost/intern/GHOST_C-api.cpp index 88d02c46f61..ba0a6eba36f 100644 --- a/intern/ghost/intern/GHOST_C-api.cpp +++ b/intern/ghost/intern/GHOST_C-api.cpp @@ -878,3 +878,16 @@ int GHOST_confirmQuit(GHOST_WindowHandle windowhandle) GHOST_ISystem *system = GHOST_ISystem::getSystem(); return system->confirmQuit((GHOST_IWindow *) windowhandle); } + +int GHOST_UseNativePixels(void) +{ + GHOST_ISystem *system = GHOST_ISystem::getSystem(); + return system->useNativePixel(); +} + +float GHOST_GetNativePixelSize(void) +{ + GHOST_ISystem *system = GHOST_ISystem::getSystem(); + return system->getNativePixelSize(); +} + diff --git a/intern/ghost/intern/GHOST_System.cpp b/intern/ghost/intern/GHOST_System.cpp index 8c6491bcbfd..a008d224a20 100644 --- a/intern/ghost/intern/GHOST_System.cpp +++ b/intern/ghost/intern/GHOST_System.cpp @@ -373,3 +373,16 @@ int GHOST_System::confirmQuit(GHOST_IWindow *window) const { return 1; } + +bool GHOST_System::useNativePixel(void) +{ + m_nativePixel = 1; + return 1; +} + +float GHOST_System::getNativePixelSize(void) +{ + if (m_nativePixel) + return m_nativePixelSize; + return 1.0f; +} diff --git a/intern/ghost/intern/GHOST_System.h b/intern/ghost/intern/GHOST_System.h index d2e3377f6ce..5060f22c509 100644 --- a/intern/ghost/intern/GHOST_System.h +++ b/intern/ghost/intern/GHOST_System.h @@ -167,6 +167,16 @@ public: */ virtual bool getFullScreen(void); + + /** + * Native pixel size support (MacBook 'retina'). + * \return The pixel size in float. + */ + virtual bool useNativePixel(void); + bool m_nativePixel; + + virtual float getNativePixelSize(void); + float m_nativePixelSize; /*************************************************************************************** * Event management functionality @@ -350,6 +360,7 @@ protected: /** Settings of the display before the display went fullscreen. */ GHOST_DisplaySetting m_preFullScreenSetting; + }; inline GHOST_TimerManager *GHOST_System::getTimerManager() const diff --git a/intern/ghost/intern/GHOST_SystemCocoa.mm b/intern/ghost/intern/GHOST_SystemCocoa.mm index 16edb4af575..7f6b69d9d50 100644 --- a/intern/ghost/intern/GHOST_SystemCocoa.mm +++ b/intern/ghost/intern/GHOST_SystemCocoa.mm @@ -1058,7 +1058,7 @@ GHOST_TSuccess GHOST_SystemCocoa::handleWindowEvent(GHOST_TEventType eventType, pushEvent( new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowSize, window) ); //Mouse up event is trapped by the resizing event loop, so send it anyway to the window manager pushEvent(new GHOST_EventButton(getMilliSeconds(), GHOST_kEventButtonUp, window, convertButton(0))); - m_ignoreWindowSizedMessages = true; + //m_ignoreWindowSizedMessages = true; } break; default: @@ -1450,13 +1450,22 @@ GHOST_TSuccess GHOST_SystemCocoa::handleMouseEvent(void *eventPtr) { NSEvent *event = (NSEvent *)eventPtr; GHOST_WindowCocoa* window; + CocoaWindow *cocoawindow; + /* [event window] returns other windows if mouse-over, that's OSX input standard + however, if mouse exits window(s), the windows become inactive, until you click. + We then fall back to the active window from ghost */ window = (GHOST_WindowCocoa*)m_windowManager->getWindowAssociatedWithOSWindow((void*)[event window]); if (!window) { - //printf("\nW failure for event 0x%x",[event type]); - return GHOST_kFailure; + window = (GHOST_WindowCocoa*)m_windowManager->getActiveWindow(); + if (!window) { + //printf("\nW failure for event 0x%x",[event type]); + return GHOST_kFailure; + } } + cocoawindow = (CocoaWindow *)window->getOSWindow(); + switch ([event type]) { case NSLeftMouseDown: case NSRightMouseDown: @@ -1509,7 +1518,7 @@ GHOST_TSuccess GHOST_SystemCocoa::handleMouseEvent(void *eventPtr) break; case GHOST_kGrabWrap: //Wrap cursor at area/window boundaries { - NSPoint mousePos = [event locationInWindow]; + NSPoint mousePos = [cocoawindow mouseLocationOutsideOfEventStream]; GHOST_TInt32 x_mouse= mousePos.x; GHOST_TInt32 y_mouse= mousePos.y; GHOST_TInt32 x_accum, y_accum, x_cur, y_cur, x, y; @@ -1555,9 +1564,9 @@ GHOST_TSuccess GHOST_SystemCocoa::handleMouseEvent(void *eventPtr) default: { //Normal cursor operation: send mouse position in window - NSPoint mousePos = [event locationInWindow]; + NSPoint mousePos = [cocoawindow mouseLocationOutsideOfEventStream]; GHOST_TInt32 x, y; - + window->clientToScreenIntern(mousePos.x, mousePos.y, x, y); pushEvent(new GHOST_EventCursor([event timestamp] * 1000, GHOST_kEventCursorMove, window, x, y)); @@ -1584,7 +1593,7 @@ GHOST_TSuccess GHOST_SystemCocoa::handleMouseEvent(void *eventPtr) pushEvent(new GHOST_EventWheel([event timestamp] * 1000, window, delta)); } else { - NSPoint mousePos = [event locationInWindow]; + NSPoint mousePos = [cocoawindow mouseLocationOutsideOfEventStream]; GHOST_TInt32 x, y; double dx = [event deltaX]; double dy = -[event deltaY]; @@ -1616,7 +1625,7 @@ GHOST_TSuccess GHOST_SystemCocoa::handleMouseEvent(void *eventPtr) case NSEventTypeMagnify: { - NSPoint mousePos = [event locationInWindow]; + NSPoint mousePos = [cocoawindow mouseLocationOutsideOfEventStream]; GHOST_TInt32 x, y; window->clientToScreenIntern(mousePos.x, mousePos.y, x, y); pushEvent(new GHOST_EventTrackpad([event timestamp] * 1000, window, GHOST_kTrackpadEventMagnify, x, y, @@ -1626,7 +1635,7 @@ GHOST_TSuccess GHOST_SystemCocoa::handleMouseEvent(void *eventPtr) case NSEventTypeRotate: { - NSPoint mousePos = [event locationInWindow]; + NSPoint mousePos = [cocoawindow mouseLocationOutsideOfEventStream]; GHOST_TInt32 x, y; window->clientToScreenIntern(mousePos.x, mousePos.y, x, y); pushEvent(new GHOST_EventTrackpad([event timestamp] * 1000, window, GHOST_kTrackpadEventRotate, x, y, diff --git a/intern/ghost/intern/GHOST_SystemWin32.cpp b/intern/ghost/intern/GHOST_SystemWin32.cpp index 46c71f57c6f..9f62ed76735 100644 --- a/intern/ghost/intern/GHOST_SystemWin32.cpp +++ b/intern/ghost/intern/GHOST_SystemWin32.cpp @@ -782,8 +782,8 @@ GHOST_TSuccess GHOST_SystemWin32::pushDragDropEvent(GHOST_TEventType eventType, void GHOST_SystemWin32::processMinMaxInfo(MINMAXINFO *minmax) { - minmax->ptMinTrackSize.x = 320; - minmax->ptMinTrackSize.y = 240; + minmax->ptMinTrackSize.x = 640; + minmax->ptMinTrackSize.y = 480; } #ifdef WITH_INPUT_NDOF diff --git a/intern/ghost/intern/GHOST_WindowCocoa.mm b/intern/ghost/intern/GHOST_WindowCocoa.mm index a483c030b31..2c833fcaf9d 100644 --- a/intern/ghost/intern/GHOST_WindowCocoa.mm +++ b/intern/ghost/intern/GHOST_WindowCocoa.mm @@ -470,8 +470,8 @@ GHOST_WindowCocoa::GHOST_WindowCocoa( [m_window setSystemAndWindowCocoa:systemCocoa windowCocoa:this]; //Forbid to resize the window below the blender defined minimum one - minSize.width = 320; - minSize.height = 240; + minSize.width = 640; + minSize.height = 480; [m_window setContentMinSize:minSize]; setTitle(title); @@ -579,6 +579,13 @@ GHOST_WindowCocoa::GHOST_WindowCocoa( updateDrawingContext(); activateDrawingContext(); + if (m_systemCocoa->m_nativePixel) { + [m_openGLView setWantsBestResolutionOpenGLSurface:YES]; + NSRect backingBounds = [m_openGLView convertRectToBacking:[m_openGLView bounds]]; + m_systemCocoa->m_nativePixelSize = (float)backingBounds.size.width / (float)rect.size.width; + } + + m_tablet.Active = GHOST_kTabletModeNone; CocoaWindowDelegate *windowDelegate = [[CocoaWindowDelegate alloc] init]; @@ -1008,7 +1015,7 @@ GHOST_TSuccess GHOST_WindowCocoa::setState(GHOST_TWindowState state) [tmpWindow registerForDraggedTypes:[NSArray arrayWithObjects:NSFilenamesPboardType, NSStringPboardType, NSTIFFPboardType, nil]]; //Forbid to resize the window below the blender defined minimum one - [tmpWindow setContentMinSize:NSMakeSize(320, 240)]; + [tmpWindow setContentMinSize:NSMakeSize(640, 480)]; //Assign the openGL view to the new window [tmpWindow setContentView:m_openGLView]; diff --git a/intern/ghost/intern/GHOST_WindowX11.cpp b/intern/ghost/intern/GHOST_WindowX11.cpp index 156bc86869a..3440e3ce15a 100644 --- a/intern/ghost/intern/GHOST_WindowX11.cpp +++ b/intern/ghost/intern/GHOST_WindowX11.cpp @@ -363,8 +363,8 @@ GHOST_WindowX11( xsizehints->y = top; xsizehints->width = width; xsizehints->height = height; - xsizehints->min_width = 320; /* size hints, could be made apart of the ghost api */ - xsizehints->min_height = 240; /* limits are also arbitrary, but should not allow 1x1 window */ + xsizehints->min_width = 640; /* size hints, could be made apart of the ghost api */ + xsizehints->min_height = 480; /* limits are also arbitrary, but should not allow 1x1 window */ xsizehints->max_width = 65535; xsizehints->max_height = 65535; XSetWMNormalHints(m_display, m_window, xsizehints); diff --git a/release/scripts/startup/bl_ui/space_userpref.py b/release/scripts/startup/bl_ui/space_userpref.py index 0bb25e98456..42d64078acb 100644 --- a/release/scripts/startup/bl_ui/space_userpref.py +++ b/release/scripts/startup/bl_ui/space_userpref.py @@ -84,7 +84,7 @@ class USERPREF_HT_header(Header): userpref = context.user_preferences layout.operator_context = 'EXEC_AREA' - layout.operator("wm.save_homefile", text="Save As Default") + layout.operator("wm.save_userpref") layout.operator_context = 'INVOKE_DEFAULT' @@ -445,6 +445,7 @@ class USERPREF_PT_system(Panel): col.label(text="Window Draw Method:") col.prop(system, "window_draw_method", text="") col.prop(system, "multi_sample", text="") + col.prop(system, "use_region_overlap") col.label(text="Text Draw Options:") col.prop(system, "use_text_antialiasing") col.label(text="Textures:") @@ -855,6 +856,7 @@ class USERPREF_PT_file(Panel): col.prop(paths, "recent_files") col.prop(paths, "use_save_preview_images") col.label(text="Auto Save:") + col.prop(paths, "use_keep_session") col.prop(paths, "use_auto_save_temporary_files") sub = col.column() sub.active = paths.use_auto_save_temporary_files diff --git a/source/blender/blenfont/BLF_api.h b/source/blender/blenfont/BLF_api.h index 6f348ccc267..25b55eacd77 100644 --- a/source/blender/blenfont/BLF_api.h +++ b/source/blender/blenfont/BLF_api.h @@ -37,6 +37,7 @@ struct ColorManagedDisplay; int BLF_init(int points, int dpi); void BLF_exit(void); +void BLF_default_dpi(int dpi); void BLF_cache_clear(void); diff --git a/source/blender/blenfont/intern/blf.c b/source/blender/blenfont/intern/blf.c index 778b6c11e5a..16756769675 100644 --- a/source/blender/blenfont/intern/blf.c +++ b/source/blender/blenfont/intern/blf.c @@ -87,6 +87,11 @@ int BLF_init(int points, int dpi) return blf_font_init(); } +void BLF_default_dpi(int dpi) +{ + global_font_dpi = dpi; +} + void BLF_exit(void) { FontBLF *font; diff --git a/source/blender/blenkernel/BKE_blender.h b/source/blender/blenkernel/BKE_blender.h index cd75749fa3c..ffdbc9cb9d8 100644 --- a/source/blender/blenkernel/BKE_blender.h +++ b/source/blender/blenkernel/BKE_blender.h @@ -62,6 +62,7 @@ struct bContext; struct ReportList; struct Scene; struct Main; +struct ID; int BKE_read_file(struct bContext *C, const char *filepath, struct ReportList *reports); @@ -72,12 +73,17 @@ int BKE_read_file(struct bContext *C, const char *filepath, struct ReportList *r int BKE_read_file_from_memory(struct bContext *C, char *filebuf, int filelength, struct ReportList *reports); int BKE_read_file_from_memfile(struct bContext *C, struct MemFile *memfile, struct ReportList *reports); +int BKE_read_file_userdef(const char *filepath, struct ReportList *reports); +int BKE_write_file_userdef(const char *filepath, struct ReportList *reports); + void free_blender(void); void initglobals(void); /* load new userdef from file, exit blender */ void BKE_userdef_free(void); - +/* handle changes in userdef */ +void BKE_userdef_state(void); + /* set this callback when a UI is running */ void set_blender_test_break_cb(void (*func)(void) ); int blender_test_break(void); @@ -93,9 +99,15 @@ extern void BKE_reset_undo(void); extern char *BKE_undo_menu_string(void); extern void BKE_undo_number(struct bContext *C, int nr); extern const char *BKE_undo_get_name(int nr, int *active); -extern void BKE_undo_save_quit(void); +extern int BKE_undo_save_file(const struct bContext *C, char *filename); extern struct Main *BKE_undo_get_main(struct Scene **scene); + /* copybuffer */ +void BKE_copybuffer_begin(void); +void BKE_copybuffer_tag_ID(struct ID *id); +int BKE_copybuffer_save(char *filename, struct ReportList *reports); + int BKE_copybuffer_paste(struct bContext *C, char *libname, struct ReportList *reports); + #ifdef __cplusplus } #endif diff --git a/source/blender/blenkernel/BKE_global.h b/source/blender/blenkernel/BKE_global.h index f6276a69d57..38a88607119 100644 --- a/source/blender/blenkernel/BKE_global.h +++ b/source/blender/blenkernel/BKE_global.h @@ -149,7 +149,7 @@ enum { /* #define G_FILE_SHOW_PROFILE (1 << 6) */ /* deprecated */ #define G_FILE_LOCK (1 << 7) #define G_FILE_SIGN (1 << 8) -/* #define G_FILE_PUBLISH (1 << 9) */ /* deprecated */ +#define G_FILE_USERPREFS (1 << 9) #define G_FILE_NO_UI (1 << 10) /* #define G_FILE_GAME_TO_IPO (1 << 11) */ /* deprecated */ #define G_FILE_GAME_MAT (1 << 12) /* deprecated */ diff --git a/source/blender/blenkernel/BKE_main.h b/source/blender/blenkernel/BKE_main.h index cfdcf1436bf..b49c5fda475 100644 --- a/source/blender/blenkernel/BKE_main.h +++ b/source/blender/blenkernel/BKE_main.h @@ -53,7 +53,8 @@ typedef struct Main { char name[1024]; /* 1024 = FILE_MAX */ short versionfile, subversionfile; short minversionfile, minsubversionfile; - int revision; /* svn revision of binary that saved file */ + int revision; /* svn revision of binary that saved file */ + short recovered; /* indicate the main->name (file) is the recovered one */ struct Library *curlib; ListBase scene; diff --git a/source/blender/blenkernel/BKE_scene.h b/source/blender/blenkernel/BKE_scene.h index 9927c7a42ed..3be07e72fc2 100644 --- a/source/blender/blenkernel/BKE_scene.h +++ b/source/blender/blenkernel/BKE_scene.h @@ -47,7 +47,7 @@ struct RenderData; struct SceneRenderLayer; struct Scene; struct Text; -struct Text; +struct Main; #define SCE_COPY_NEW 0 #define SCE_COPY_EMPTY 1 @@ -68,6 +68,7 @@ void free_qtcodecdata(struct QuicktimeCodecData *acd); void BKE_scene_free(struct Scene *sce); struct Scene *BKE_scene_add(const char *name); +struct Scene *BKE_main_scene_add(struct Main *bmain, const char *name); /* base functions */ struct Base *BKE_scene_base_find(struct Scene *scene, struct Object *ob); diff --git a/source/blender/blenkernel/intern/blender.c b/source/blender/blenkernel/intern/blender.c index f0d201ea3f7..3aa425bdbb9 100644 --- a/source/blender/blenkernel/intern/blender.c +++ b/source/blender/blenkernel/intern/blender.c @@ -80,8 +80,11 @@ #include "BKE_screen.h" #include "BKE_sequencer.h" #include "BKE_sound.h" + #include "RE_pipeline.h" +#include "BLF_api.h" + #include "BLO_undofile.h" #include "BLO_readfile.h" #include "BLO_writefile.h" @@ -230,6 +233,9 @@ static void setup_app_data(bContext *C, BlendFileData *bfd, const char *filepath /* but use new Scene pointer */ curscene = bfd->curscene; if (curscene == NULL) curscene = bfd->main->scene.first; + /* empty file, we add a scene to make Blender work */ + if (curscene == NULL) curscene = BKE_main_scene_add(bfd->main, "Empty"); + /* and we enforce curscene to be in current screen */ if (curscreen) curscreen->scene = curscene; /* can run in bgmode */ @@ -270,7 +276,7 @@ static void setup_app_data(bContext *C, BlendFileData *bfd, const char *filepath G.fileflags = bfd->fileflags; CTX_wm_manager_set(C, G.main->wm.first); CTX_wm_screen_set(C, bfd->curscreen); - CTX_data_scene_set(C, bfd->curscreen->scene); + CTX_data_scene_set(C, bfd->curscene); CTX_wm_area_set(C, NULL); CTX_wm_region_set(C, NULL); CTX_wm_menu_set(C, NULL); @@ -310,22 +316,23 @@ static void setup_app_data(bContext *C, BlendFileData *bfd, const char *filepath if (G.main->versionfile < 250) do_versions_ipos_to_animato(G.main); - if (recover && bfd->filename[0] && G.relbase_valid) { + G.main->recovered = 0; + + /* startup.blend or recovered startup */ + if (bfd->filename[0] == 0) { + G.main->name[0] = 0; + } + else if (recover && G.relbase_valid) { /* in case of autosave or quit.blend, use original filename instead * use relbase_valid to make sure the file is saved, else we get in the filename */ filepath = bfd->filename; - } -#if 0 - else if (!G.relbase_valid) { - /* otherwise, use an empty string as filename, rather than */ - filepath = ""; - } -#endif + G.main->recovered = 1; + + /* these are the same at times, should never copy to the same location */ + if (G.main->name != filepath) + BLI_strncpy(G.main->name, filepath, FILE_MAX); + } - /* these are the same at times, should never copy to the same location */ - if (G.main->name != filepath) - BLI_strncpy(G.main->name, filepath, FILE_MAX); - /* baseflags, groups, make depsgraph, etc */ BKE_scene_set_background(G.main, CTX_data_scene(C)); @@ -334,7 +341,7 @@ static void setup_app_data(bContext *C, BlendFileData *bfd, const char *filepath } MEM_freeN(bfd); - + (void)curscene; /* quiet warning */ } @@ -393,6 +400,14 @@ void BKE_userdef_free(void) BLI_freelistN(&U.addons); } +/* handle changes in settings that need recalc */ +void BKE_userdef_state(void) +{ + BLF_default_dpi(U.pixelsize * U.dpi); + U.widget_unit = (U.pixelsize * U.dpi * 20 + 36) / 72; + +} + int BKE_read_file(bContext *C, const char *filepath, ReportList *reports) { BlendFileData *bfd; @@ -439,14 +454,57 @@ int BKE_read_file_from_memfile(bContext *C, MemFile *memfile, ReportList *report BlendFileData *bfd; bfd = BLO_read_from_memfile(CTX_data_main(C), G.main->name, memfile, reports); - if (bfd) + if (bfd) { + /* remove the unused screens and wm */ + while (bfd->main->wm.first) + BKE_libblock_free(&bfd->main->wm, bfd->main->wm.first); + while (bfd->main->screen.first) + BKE_libblock_free(&bfd->main->screen, bfd->main->screen.first); + setup_app_data(C, bfd, ""); + } else BKE_reports_prepend(reports, "Loading failed: "); return (bfd ? 1 : 0); } +/* only read the userdef from a .blend */ +int BKE_read_file_userdef(const char *filepath, ReportList *reports) +{ + BlendFileData *bfd; + int retval = 0; + + bfd = BLO_read_from_file(filepath, reports); + if (bfd->user) { + retval = BKE_READ_FILE_OK_USERPREFS; + + /* only here free userdef themes... */ + BKE_userdef_free(); + + U = *bfd->user; + MEM_freeN(bfd->user); + } + free_main(bfd->main); + MEM_freeN(bfd); + + return retval; +} + +/* only write the userdef in a .blend */ +int BKE_write_file_userdef(const char *filepath, ReportList *reports) +{ + Main *mainb = MEM_callocN(sizeof(Main), "empty main"); + int retval = 0; + + if (BLO_write_file(mainb, filepath, G_FILE_USERPREFS, reports, NULL)) { + retval = 1; + } + + MEM_freeN(mainb); + + return retval; +} /* ***************** testing for break ************* */ @@ -728,48 +786,39 @@ char *BKE_undo_menu_string(void) return menu; } -/* saves quit.blend */ -void BKE_undo_save_quit(void) +/* saves .blend using undo buffer, returns 1 == success */ +int BKE_undo_save_file(const bContext *C, char *filename) { UndoElem *uel; MemFileChunk *chunk; - char str[FILE_MAX]; const int flag = O_BINARY + O_WRONLY + O_CREAT + O_TRUNC + O_EXCL; int file; if ((U.uiflag & USER_GLOBALUNDO) == 0) { - return; + return 0; } uel = curundo; if (uel == NULL) { fprintf(stderr, "No undo buffer to save recovery file\n"); - return; + return 0; } - /* no undo state to save */ - if (undobase.first == undobase.last) { - return; - } - - /* save the undo state as quit.blend */ - BLI_make_file_string("/", str, BLI_temporary_dir(), "quit.blend"); - /* first try create the file, if it exists call without 'O_CREAT', * to avoid writing to a symlink - use 'O_EXCL' (CVE-2008-1103) */ errno = 0; - file = BLI_open(str, flag, 0666); + file = BLI_open(filename, flag, 0666); if (file == -1) { if (errno == EEXIST) { errno = 0; - file = BLI_open(str, flag & ~O_CREAT, 0666); + file = BLI_open(filename, flag & ~O_CREAT, 0666); } } if (file == -1) { fprintf(stderr, "Unable to save '%s': %s\n", - str, errno ? strerror(errno) : "Unknown error opening file"); - return; + filename, errno ? strerror(errno) : "Unknown error opening file"); + return 0; } for (chunk = uel->memfile.chunks.first; chunk; chunk = chunk->next) { @@ -777,16 +826,15 @@ void BKE_undo_save_quit(void) break; } } - + close(file); if (chunk) { fprintf(stderr, "Unable to save '%s': %s\n", - str, errno ? strerror(errno) : "Unknown error writing file"); - } - else { - printf("Saved session recovery to '%s'\n", str); + filename, errno ? strerror(errno) : "Unknown error writing file"); + return 0; } + return 1; } /* sets curscene */ @@ -806,3 +854,131 @@ Main *BKE_undo_get_main(Scene **scene) return mainp; } +/* ************** copy paste .blend, partial saves ********** */ + +/* assumes data is in G.main */ + +void BKE_copybuffer_begin(void) +{ + /* set all id flags to zero; */ + flag_all_listbases_ids(LIB_NEED_EXPAND | LIB_DOIT, 0); +} + +void BKE_copybuffer_tag_ID(ID *id) +{ + id->flag |= LIB_NEED_EXPAND | LIB_DOIT; +} + +static void copybuffer_doit(void *UNUSED(handle), Main *UNUSED(bmain), void *vid) +{ + if (vid) { + ID *id = vid; + id->flag |= LIB_NEED_EXPAND | LIB_DOIT; + } +} + +/* frees main in end */ +int BKE_copybuffer_save(char *filename, ReportList *reports) +{ + Main *mainb = MEM_callocN(sizeof(Main), "copybuffer"); + ListBase *lbarray[MAX_LIBARRAY], *fromarray[MAX_LIBARRAY]; + int a, retval; + + BLO_main_expander(copybuffer_doit); + BLO_expand_main(NULL, G.main); + + /* move over all tagged blocks */ + set_listbasepointers(G.main, fromarray); + a = set_listbasepointers(mainb, lbarray); + while (a--) { + ID *id, *nextid; + ListBase *lb1 = lbarray[a], *lb2 = fromarray[a]; + + for (id = lb2->first; id; id= nextid) { + nextid = id->next; + if (id->flag & LIB_DOIT) { + BLI_remlink(lb2, id); + BLI_addtail(lb1, id); + } + } + } + + + /* save the buffer */ + retval = BLO_write_file(mainb, filename, 0, reports, NULL); + + /* move back the main, now sorted again */ + set_listbasepointers(G.main, lbarray); + a = set_listbasepointers(mainb, fromarray); + while (a--) { + ID *id; + ListBase *lb1 = lbarray[a], *lb2 = fromarray[a]; + + while (lb2->first) { + id = lb2->first; + BLI_remlink(lb2, id); + BLI_addtail(lb1, id); + id_sort_by_name(lb1, id); + } + } + + MEM_freeN(mainb); + + /* set id flag to zero; */ + flag_all_listbases_ids(LIB_NEED_EXPAND | LIB_DOIT, 0); + + return retval; +} + +/* return success (1) */ +int BKE_copybuffer_paste(bContext *C, char *libname, ReportList *reports) +{ + Main *bmain = CTX_data_main(C); + Scene *scene = CTX_data_scene(C); + Main *mainl = NULL; + Library *lib; + BlendHandle *bh; + + bh = BLO_blendhandle_from_file(libname, reports); + + if (bh == NULL) { + /* error reports will have been made by BLO_blendhandle_from_file() */ + return 0; + } + + BKE_scene_base_deselect_all(scene); + + /* tag everything, all untagged data can be made local + * its also generally useful to know what is new + * + * take extra care flag_all_listbases_ids(LIB_LINK_TAG, 0) is called after! */ + flag_all_listbases_ids(LIB_PRE_EXISTING, 1); + + /* here appending/linking starts */ + mainl = BLO_library_append_begin(bmain, &bh, libname); + + BLO_library_append_all(mainl, bh); + + BLO_library_append_end(C, mainl, &bh, 0, 0); + + /* mark all library linked objects to be updated */ + recalc_all_library_objects(bmain); + IMB_colormanagement_check_file_config(bmain); + + /* append, rather than linking */ + lib = BLI_findstring(&bmain->library, libname, offsetof(Library, filepath)); + BKE_library_make_local(bmain, lib, 1); + + /* important we unset, otherwise these object wont + * link into other scenes from this blend file */ + flag_all_listbases_ids(LIB_PRE_EXISTING, 0); + + /* recreate dependency graph to include new objects */ + DAG_scene_sort(bmain, scene); + DAG_ids_flush_update(bmain, 0); + + BLO_blendhandle_close(bh); + /* remove library... */ + + return 1; +} diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c index 9bb2fb2de52..47f0da18163 100644 --- a/source/blender/blenkernel/intern/scene.c +++ b/source/blender/blenkernel/intern/scene.c @@ -372,9 +372,8 @@ void BKE_scene_free(Scene *sce) BKE_color_managed_view_settings_free(&sce->view_settings); } -Scene *BKE_scene_add(const char *name) +static Scene *scene_add(Main *bmain, const char *name) { - Main *bmain = G.main; Scene *sce; ParticleEditSettings *pset; int a; @@ -605,6 +604,16 @@ Scene *BKE_scene_add(const char *name) return sce; } +Scene *BKE_scene_add(const char *name) +{ + return scene_add(G.main, name); +} + +Scene *BKE_main_scene_add(Main *bmain, const char *name) +{ + return scene_add(bmain, name); +} + Base *BKE_scene_base_find(Scene *scene, Object *ob) { return BLI_findptr(&scene->base, ob, offsetof(Base, object)); diff --git a/source/blender/blenlib/BLI_path_util.h b/source/blender/blenlib/BLI_path_util.h index 5e47adf25ef..43724d8dd44 100644 --- a/source/blender/blenlib/BLI_path_util.h +++ b/source/blender/blenlib/BLI_path_util.h @@ -67,6 +67,7 @@ char *BLI_get_folder_version(const int id, const int ver, const int do_check); #define BLENDER_RESOURCE_PATH_SYSTEM 2 #define BLENDER_STARTUP_FILE "startup.blend" +#define BLENDER_USERPREF_FILE "userpref.blend" #define BLENDER_BOOKMARK_FILE "bookmarks.txt" #define BLENDER_HISTORY_FILE "recent-files.txt" diff --git a/source/blender/blenloader/BLO_readfile.h b/source/blender/blenloader/BLO_readfile.h index 16a4d8d46ec..2ee5decdfac 100644 --- a/source/blender/blenloader/BLO_readfile.h +++ b/source/blender/blenloader/BLO_readfile.h @@ -240,13 +240,32 @@ struct ID *BLO_library_append_named_part_ex(const struct bContext *C, struct Mai void BLO_library_append_end(const struct bContext *C, struct Main *mainl, BlendHandle **bh, int idcode, short flag); +void BLO_library_append_all(struct Main *mainl, BlendHandle *bh); + void *BLO_library_read_struct(struct FileData *fd, struct BHead *bh, const char *blockname); BlendFileData *blo_read_blendafterruntime(int file, const char *name, int actualsize, struct ReportList *reports); - + /* internal function but we need to expose it */ void blo_lib_link_screen_restore(struct Main *newmain, struct bScreen *curscreen, struct Scene *curscene); +/** + * BLO_expand_main() loops over all ID data in Main to mark relations. + * Set (id->flag & LIB_NEED_EXPAND) to mark expanding. Flags get cleared after expanding. + * + * \param expand_doit_func() gets called for each ID block it finds + */ +void BLO_main_expander(void (*expand_doit_func)(void *, struct Main *, void *)); + +/** + * BLO_expand_main() loops over all ID data in Main to mark relations. + * Set (id->flag & LIB_NEED_EXPAND) to mark expanding. Flags get cleared after expanding. + * + * \param fdhandle usually filedata, or own handle + * \param mainvar the Main database to expand + */ +void BLO_expand_main(void *fdhandle, struct Main *mainvar); + #ifdef __cplusplus } #endif diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 203af1d8316..cf4deb7213d 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -2981,7 +2981,7 @@ static void direct_link_text(FileData *fd, Text *text) if (text->flags & TXT_ISEXT) { BKE_text_reload(text); } - else { + /* else { */ #endif link_list(fd, &text->lines); @@ -5160,6 +5160,7 @@ static void direct_link_windowmanager(FileData *fd, wmWindowManager *wm) win->drawdata = NULL; win->drawmethod = -1; win->drawfail = 0; + win->active = 0; } wm->timers.first = wm->timers.last = NULL; @@ -5231,27 +5232,6 @@ static void direct_link_gpencil(FileData *fd, bGPdata *gpd) /* ****************** READ SCREEN ***************** */ -static void butspace_version_132(SpaceButs *buts) -{ - buts->v2d.tot.xmin = 0.0f; - buts->v2d.tot.ymin = 0.0f; - buts->v2d.tot.xmax = 1279.0f; - buts->v2d.tot.ymax = 228.0f; - - buts->v2d.min[0] = 256.0f; - buts->v2d.min[1] = 42.0f; - - buts->v2d.max[0] = 2048.0f; - buts->v2d.max[1] = 450.0f; - - buts->v2d.minzoom = 0.5f; - buts->v2d.maxzoom = 1.21f; - - buts->v2d.scroll = 0; - buts->v2d.keepzoom = 1; - buts->v2d.keeptot = 1; -} - /* note: file read without screens option G_FILE_NO_UI; * check lib pointers in call below */ static void lib_link_screen(FileData *fd, Main *main) @@ -5305,18 +5285,9 @@ static void lib_link_screen(FileData *fd, Main *main) else if (sl->spacetype == SPACE_BUTS) { SpaceButs *sbuts = (SpaceButs *)sl; sbuts->pinid = newlibadr(fd, sc->id.lib, sbuts->pinid); - sbuts->mainbo = sbuts->mainb; - sbuts->mainbuser = sbuts->mainb; - if (main->versionfile < 132) - butspace_version_132(sbuts); } else if (sl->spacetype == SPACE_FILE) { - SpaceFile *sfile = (SpaceFile *)sl; - sfile->files = NULL; - sfile->op = NULL; - sfile->layout = NULL; - sfile->folders_prev = NULL; - sfile->folders_next = NULL; + ; } else if (sl->spacetype == SPACE_ACTION) { SpaceAction *saction = (SpaceAction *)sl; @@ -5348,12 +5319,6 @@ static void lib_link_screen(FileData *fd, Main *main) */ sseq->gpd = newlibadr_us(fd, sc->id.lib, sseq->gpd); - sseq->scopes.reference_ibuf = NULL; - sseq->scopes.zebra_ibuf = NULL; - sseq->scopes.waveform_ibuf = NULL; - sseq->scopes.sep_waveform_ibuf = NULL; - sseq->scopes.vector_ibuf = NULL; - sseq->scopes.histogram_ibuf = NULL; } else if (sl->spacetype == SPACE_NLA) { SpaceNla *snla= (SpaceNla *)sl; @@ -5368,7 +5333,6 @@ static void lib_link_screen(FileData *fd, Main *main) SpaceText *st= (SpaceText *)sl; st->text= newlibadr(fd, sc->id.lib, st->text); - st->drawcache= NULL; } else if (sl->spacetype == SPACE_SCRIPT) { SpaceScript *scpt = (SpaceScript *)sl; @@ -5385,7 +5349,6 @@ static void lib_link_screen(FileData *fd, Main *main) TreeStoreElem *tselem; int a; - so->tree.first = so->tree.last= NULL; so->search_tse.id = newlibadr(fd, NULL, so->search_tse.id); if (so->treestore) { @@ -5399,7 +5362,6 @@ static void lib_link_screen(FileData *fd, Main *main) SpaceNode *snode = (SpaceNode *)sl; snode->id = newlibadr(fd, sc->id.lib, snode->id); - snode->edittree = NULL; if (ELEM3(snode->treetype, NTREE_COMPOSIT, NTREE_SHADER, NTREE_TEXTURE)) { /* internal data, a bit patchy */ @@ -5420,19 +5382,12 @@ static void lib_link_screen(FileData *fd, Main *main) else { snode->nodetree = newlibadr_us(fd, sc->id.lib, snode->nodetree); } - - snode->linkdrag.first = snode->linkdrag.last = NULL; } else if (sl->spacetype == SPACE_CLIP) { SpaceClip *sclip = (SpaceClip *)sl; sclip->clip = newlibadr_us(fd, sc->id.lib, sclip->clip); sclip->mask_info.mask = newlibadr_us(fd, sc->id.lib, sclip->mask_info.mask); - - sclip->scopes.track_search = NULL; - sclip->scopes.track_preview = NULL; - sclip->draw_context = NULL; - sclip->scopes.ok = 0; } else if (sl->spacetype == SPACE_LOGIC) { SpaceLogic *slogic = (SpaceLogic *)sl; @@ -5774,6 +5729,7 @@ static void direct_link_region(FileData *fd, ARegion *ar, int spacetype) ar->type = NULL; ar->swap = 0; ar->do_draw = FALSE; + ar->regiontimer = NULL; memset(&ar->drawrct, 0, sizeof(ar->drawrct)); } @@ -5918,6 +5874,7 @@ static void direct_link_screen(FileData *fd, bScreen *sc) soops->treestore->totelem = soops->treestore->usedelem; soops->storeflag |= SO_TREESTORE_CLEANUP; // at first draw } + soops->tree.first = soops->tree.last= NULL; } else if (sl->spacetype == SPACE_IMAGE) { SpaceImage *sima = (SpaceImage *)sl; @@ -5950,6 +5907,13 @@ static void direct_link_screen(FileData *fd, bScreen *sc) snode->gpd = newdataadr(fd, snode->gpd); direct_link_gpencil(fd, snode->gpd); } + snode->edittree = NULL; + snode->linkdrag.first = snode->linkdrag.last = NULL; + } + else if (sl->spacetype == SPACE_TEXT) { + SpaceText *st= (SpaceText *)sl; + + st->drawcache= NULL; } else if (sl->spacetype == SPACE_TIME) { SpaceTime *stime = (SpaceTime *)sl; @@ -5965,6 +5929,8 @@ static void direct_link_screen(FileData *fd, bScreen *sc) } } else if (sl->spacetype == SPACE_SEQ) { + SpaceSeq *sseq = (SpaceSeq *)sl; + /* grease pencil data is not a direct data and can't be linked from direct_link* * functions, it should be linked from lib_link* functions instead * @@ -5973,17 +5939,26 @@ static void direct_link_screen(FileData *fd, bScreen *sc) * simple return NULL here (sergey) */ #if 0 - SpaceSeq *sseq = (SpaceSeq *)sl; if (sseq->gpd) { sseq->gpd = newdataadr(fd, sseq->gpd); direct_link_gpencil(fd, sseq->gpd); } #endif + sseq->scopes.reference_ibuf = NULL; + sseq->scopes.zebra_ibuf = NULL; + sseq->scopes.waveform_ibuf = NULL; + sseq->scopes.sep_waveform_ibuf = NULL; + sseq->scopes.vector_ibuf = NULL; + sseq->scopes.histogram_ibuf = NULL; + } else if (sl->spacetype == SPACE_BUTS) { SpaceButs *sbuts = (SpaceButs *)sl; + sbuts->path= NULL; sbuts->texuser= NULL; + sbuts->mainbo = sbuts->mainb; + sbuts->mainbuser = sbuts->mainb; } else if (sl->spacetype == SPACE_CONSOLE) { SpaceConsole *sconsole = (SpaceConsole *)sl; @@ -6023,6 +5998,14 @@ static void direct_link_screen(FileData *fd, bScreen *sc) sfile->op = NULL; sfile->params = newdataadr(fd, sfile->params); } + else if (sl->spacetype == SPACE_CLIP) { + SpaceClip *sclip = (SpaceClip *)sl; + + sclip->scopes.track_search = NULL; + sclip->scopes.track_preview = NULL; + sclip->draw_context = NULL; + sclip->scopes.ok = 0; + } } sa->actionzones.first = sa->actionzones.last = NULL; @@ -8401,8 +8384,11 @@ static void lib_link_all(FileData *fd, Main *main) { oldnewmap_sort(fd); - lib_link_windowmanager(fd, main); - lib_link_screen(fd, main); + /* No load UI for undo memfiles */ + if (fd->memfile == NULL) { + lib_link_windowmanager(fd, main); + lib_link_screen(fd, main); + } lib_link_scene(fd, main); lib_link_object(fd, main); lib_link_curve(fd, main); @@ -8675,9 +8661,10 @@ static ID *is_yet_read(FileData *fd, Main *mainvar, BHead *bhead) return BLI_findstring(which_libbase(mainvar, GS(idname)), idname, offsetof(ID, name)); } -static void expand_doit(FileData *fd, Main *mainvar, void *old) +static void expand_doit_library(void *fdhandle, Main *mainvar, void *old) { BHead *bhead; + FileData *fd = fdhandle; ID *id; bhead = find_bhead(fd, old); @@ -8744,7 +8731,7 @@ static void expand_doit(FileData *fd, Main *mainvar, void *old) } } - +static void (*expand_doit)(void *, Main *, void *); // XXX deprecated - old animation system static void expand_ipo(FileData *fd, Main *mainvar, Ipo *ipo) @@ -9455,14 +9442,18 @@ static void expand_mask(FileData *fd, Main *mainvar, Mask *mask) } } -static void expand_main(FileData *fd, Main *mainvar) +void BLO_main_expander(void (*expand_doit_func)(void *, Main *, void *)) +{ + expand_doit = expand_doit_func; +} + +void BLO_expand_main(void *fdhandle, Main *mainvar) { ListBase *lbarray[MAX_LIBARRAY]; + FileData *fd = fdhandle; ID *id; int a, do_it = TRUE; - if (fd == NULL) return; - while (do_it) { do_it = FALSE; @@ -9553,6 +9544,9 @@ static void expand_main(FileData *fd, Main *mainvar) } } + +/* ***************************** */ + static int object_in_any_scene(Main *mainvar, Object *ob) { Scene *sce; @@ -9701,6 +9695,28 @@ static ID *append_named_part(Main *mainl, FileData *fd, const char *idname, cons return (found) ? id : NULL; } +/* simple reader for copy/paste buffers */ +void BLO_library_append_all(Main *mainl, BlendHandle *bh) +{ + FileData *fd = (FileData *)(bh); + BHead *bhead; + ID *id = NULL; + + for (bhead = blo_firstbhead(fd); bhead; bhead = blo_nextbhead(fd, bhead)) { + if (bhead->code == ENDB) + break; + if (bhead->code == ID_OB) + read_libblock(fd, mainl, bhead, LIB_TESTIND, &id); + + if (id) { + /* sort by name in list */ + ListBase *lb = which_libbase(mainl, GS(id->name)); + id_sort_by_name(lb, id); + } + } +} + + static ID *append_named_part_ex(const bContext *C, Main *mainl, FileData *fd, const char *idname, const int idcode, const int flag) { ID *id= append_named_part(mainl, fd, idname, idcode); @@ -9805,8 +9821,11 @@ static void library_append_end(const bContext *C, Main *mainl, FileData **fd, in Main *mainvar; Library *curlib; + /* expander now is callback function */ + BLO_main_expander(expand_doit_library); + /* make main consistent */ - expand_main(*fd, mainl); + BLO_expand_main(*fd, mainl); /* do this when expand found other libs */ read_libraries(*fd, (*fd)->mainlist); @@ -9901,6 +9920,9 @@ static void read_libraries(FileData *basefd, ListBase *mainlist) ListBase *lbarray[MAX_LIBARRAY]; int a, do_it = TRUE; + /* expander now is callback function */ + BLO_main_expander(expand_doit_library); + while (do_it) { do_it = FALSE; @@ -10000,7 +10022,7 @@ static void read_libraries(FileData *basefd, ListBase *mainlist) } } - expand_main(fd, mainptr); + BLO_expand_main(fd, mainptr); } } diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c index b010cae6893..cee61858467 100644 --- a/source/blender/blenloader/intern/writefile.c +++ b/source/blender/blenloader/intern/writefile.c @@ -2515,6 +2515,9 @@ static void write_screens(WriteData *wd, ListBase *scrbase) sc= sc->id.next; } + + /* flush helps the compression for undo-save */ + mywrite(wd, MYWRITE_FLUSH, 0); } static void write_libraries(WriteData *wd, Main *main) @@ -2877,7 +2880,7 @@ static void write_global(WriteData *wd, int fileflags, Main *mainvar) /* XXX still remap G */ fg.curscreen= screen; - fg.curscene= screen->scene; + fg.curscene= screen? screen->scene : NULL; fg.displaymode= G.displaymode; fg.winpos= G.winpos; @@ -2886,7 +2889,6 @@ static void write_global(WriteData *wd, int fileflags, Main *mainvar) fg.globalf= G.f; BLI_strncpy(fg.filename, mainvar->name, sizeof(fg.filename)); - sprintf(subvstr, "%4d", BLENDER_SUBVERSION); memcpy(fg.subvstr, subvstr, 4); @@ -2938,11 +2940,8 @@ static int write_file_handle(Main *mainvar, int handle, MemFile *compare, MemFil write_thumb(wd, thumb); write_global(wd, write_flags, mainvar); - /* no UI save in undo */ - if (current==NULL) { - write_windowmanagers(wd, &mainvar->wm); - write_screens (wd, &mainvar->screen); - } + write_windowmanagers(wd, &mainvar->wm); + write_screens (wd, &mainvar->screen); write_movieclips (wd, &mainvar->movieclip); write_masks (wd, &mainvar->mask); write_scenes (wd, &mainvar->scene); @@ -3027,7 +3026,6 @@ static int do_history(const char *name, ReportList *reports) /* return: success (1) */ int BLO_write_file(Main *mainvar, const char *filepath, int write_flags, ReportList *reports, const int *thumb) { - char userfilename[FILE_MAX]; char tempname[FILE_MAX+1]; int file, err, write_user_block; @@ -3074,8 +3072,7 @@ int BLO_write_file(Main *mainvar, const char *filepath, int write_flags, ReportL } } - BLI_make_file_string(G.main->name, userfilename, BLI_get_folder_create(BLENDER_USER_CONFIG, NULL), BLENDER_STARTUP_FILE); - write_user_block= (BLI_path_cmp(filepath, userfilename) == 0); + write_user_block= write_flags & G_FILE_USERPREFS; if (write_flags & G_FILE_RELATIVE_REMAP) BLI_bpath_relative_convert(mainvar, filepath, NULL); /* note, making relative to something OTHER then G.main->name */ @@ -3151,3 +3148,4 @@ int BLO_write_file_mem(Main *mainvar, MemFile *compare, MemFile *current, int wr if (err==0) return 1; return 0; } + diff --git a/source/blender/editors/animation/anim_channels_defines.c b/source/blender/editors/animation/anim_channels_defines.c index 9ceecd60bef..f5c9bfb4cf5 100644 --- a/source/blender/editors/animation/anim_channels_defines.c +++ b/source/blender/editors/animation/anim_channels_defines.c @@ -82,7 +82,7 @@ #define EXTRA_SCROLL_PAD 100.0f /* size of indent steps */ -#define INDENT_STEP_SIZE 7 +#define INDENT_STEP_SIZE (0.35f * U.widget_unit) /* size of string buffers used for animation channel displayed names */ #define ANIM_CHAN_NAME_SIZE 256 @@ -305,15 +305,15 @@ static short acf_generic_group_offset(bAnimContext *ac, bAnimListElem *ale) if (ale->id) { /* texture animdata */ if (GS(ale->id->name) == ID_TE) { - offset += 21; + offset += U.widget_unit; } /* materials and particles animdata */ else if (ELEM(GS(ale->id->name), ID_MA, ID_PA)) - offset += 14; + offset += (short)(0.7f * U.widget_unit); /* if not in Action Editor mode, action-groups (and their children) must carry some offset too... */ else if (ac->datatype != ANIMCONT_ACTION) - offset += 14; + offset += (short)(0.7f * U.widget_unit); /* nodetree animdata */ if (GS(ale->id->name) == ID_NT) { @@ -2911,12 +2911,12 @@ void ANIM_channel_setting_set(bAnimContext *ac, bAnimListElem *ale, int setting, /* --------------------------- */ -// XXX hardcoded size of icons -#define ICON_WIDTH 17 -// XXX hardcoded width of sliders -#define SLIDER_WIDTH 80 -// XXX hardcoded width of rename textboxes -#define RENAME_TEXT_WIDTH 100 +// size of icons +#define ICON_WIDTH (0.85f * U.widget_unit) +// width of sliders +#define SLIDER_WIDTH (4 * U.widget_unit) +// width of rename textboxes +#define RENAME_TEXT_WIDTH (5 * U.widget_unit) /* Draw the given channel */ void ANIM_channel_draw(bAnimContext *ac, bAnimListElem *ale, float yminc, float ymaxc) @@ -2937,12 +2937,11 @@ void ANIM_channel_draw(bAnimContext *ac, bAnimListElem *ale, float yminc, float offset = 0; /* calculate appropriate y-coordinates for icon buttons - * 7 is hardcoded factor for half-height of icons */ y = (ymaxc - yminc) / 2 + yminc; - ymid = y - 7; + ymid = y - 0.5f * ICON_WIDTH; /* y-coordinates for text is only 4 down from middle */ - ytext = y - 4; + ytext = y - 0.2f * U.widget_unit; /* check if channel is selected */ if (acf->has_setting(ac, ale, ACHANNEL_SETTING_SELECT)) @@ -2989,10 +2988,8 @@ void ANIM_channel_draw(bAnimContext *ac, bAnimListElem *ale, float yminc, float glColor3fv(fcu->color); /* just a solid color rect - * hardcoded 17 pixels width is slightly wider than icon width, so that - * there's a slight border around it */ - glRectf(offset, yminc, offset + 17, ymaxc); + glRectf(offset, yminc, offset + ICON_WIDTH, ymaxc); } /* icon is drawn as widget now... */ @@ -3086,7 +3083,7 @@ void ANIM_channel_draw(bAnimContext *ac, bAnimListElem *ale, float yminc, float } - /* finally draw a backdrop rect behind these + /* finally draw a backdrop rect behind these * - starts from the point where the first toggle/slider starts, * - ends past the space that might be reserved for a scroller */ @@ -3365,12 +3362,9 @@ void ANIM_channel_draw_widgets(bContext *C, bAnimContext *ac, bAnimListElem *ale offset = 0; /* calculate appropriate y-coordinates for icon buttons - * 7 is hardcoded factor for half-height of icons */ y = (ymaxc - yminc) / 2 + yminc; - ymid = y - 7; - /* y-coordinates for text is only 4 down from middle */ - /* ytext = y - 4; */ + ymid = y - 0.5f * ICON_WIDTH; /* no button backdrop behind icons */ uiBlockSetEmboss(block, UI_EMBOSSN); diff --git a/source/blender/editors/animation/anim_draw.c b/source/blender/editors/animation/anim_draw.c index 0f0584ad8fe..d83d1805f0e 100644 --- a/source/blender/editors/animation/anim_draw.c +++ b/source/blender/editors/animation/anim_draw.c @@ -33,9 +33,12 @@ #include "DNA_anim_types.h" #include "DNA_object_types.h" #include "DNA_scene_types.h" +#include "DNA_userdef_types.h" + #include "BLI_math.h" #include "BKE_context.h" +#include "BKE_blender.h" #include "BKE_global.h" #include "BKE_nla.h" #include "BKE_object.h" @@ -197,15 +200,15 @@ static void draw_cfra_number(Scene *scene, View2D *v2d, float cfra, short time) /* get starting coordinates for drawing */ x = cfra * xscale; - y = 18; + y = 0.9f * U.widget_unit; /* draw green box around/behind text */ UI_ThemeColorShade(TH_CFRAME, 0); - glRectf(x, y, x + slen, y + 15); + glRectf(x, y, x + slen, y + 0.75f * U.widget_unit); /* draw current frame number - black text */ UI_ThemeColor(TH_TEXT); - UI_DrawString(x - 5, y + 3, numstr); + UI_DrawString(x - 0.25f * U.widget_unit, y + 0.15f * U.widget_unit, numstr); /* restore view transform */ glScalef(xscale, 1.0, 1.0); diff --git a/source/blender/editors/animation/anim_markers.c b/source/blender/editors/animation/anim_markers.c index 1b980790fdc..f684e57c2bc 100644 --- a/source/blender/editors/animation/anim_markers.c +++ b/source/blender/editors/animation/anim_markers.c @@ -395,7 +395,7 @@ static void draw_marker(View2D *v2d, TimeMarker *marker, int cfra, int flag) ICON_MARKER; } - UI_icon_draw(xpos * xscale - 5.0f, 16.0f, icon_id); + UI_icon_draw(xpos * xscale - 0.3f * UI_DPI_ICON_SIZE, UI_DPI_ICON_SIZE, icon_id); glDisable(GL_BLEND); @@ -405,18 +405,18 @@ static void draw_marker(View2D *v2d, TimeMarker *marker, int cfra, int flag) if (marker->flag & SELECT) { UI_ThemeColor(TH_TEXT_HI); - x = xpos * xscale + 4.0f; - y = (ypixels <= 39.0f) ? (ypixels - 10.0f) : 29.0f; + x = xpos * xscale + 4.0f * UI_DPI_FAC; + y = (ypixels <= 39.0f * UI_DPI_FAC) ? (ypixels - 10.0f * UI_DPI_FAC) : 29.0f * UI_DPI_FAC; } else { UI_ThemeColor(TH_TEXT); if ((marker->frame <= cfra) && (marker->frame + 5 > cfra)) { - x = xpos * xscale + 4.0f; - y = (ypixels <= 39.0f) ? (ypixels - 10.0f) : 29.0f; + x = xpos * xscale + 8.0f * UI_DPI_FAC; + y = (ypixels <= 39.0f * UI_DPI_FAC) ? (ypixels - 10.0f * UI_DPI_FAC) : 29.0f * UI_DPI_FAC; } else { - x = xpos * xscale + 4.0f; - y = 17.0f; + x = xpos * xscale + 8.0f * UI_DPI_FAC; + y = 17.0f * UI_DPI_FAC; } } diff --git a/source/blender/editors/animation/keyframes_draw.c b/source/blender/editors/animation/keyframes_draw.c index e520a95aa95..d9d2180e184 100644 --- a/source/blender/editors/animation/keyframes_draw.c +++ b/source/blender/editors/animation/keyframes_draw.c @@ -649,7 +649,7 @@ static void draw_keylist(View2D *v2d, DLRBT_Tree *keys, DLRBT_Tree *blocks, floa ActKeyColumn *ak; ActKeyBlock *ab; float xscale; - + float iconsize = U.widget_unit / 4.0f; glEnable(GL_BLEND); /* get View2D scaling factor */ @@ -665,7 +665,7 @@ static void draw_keylist(View2D *v2d, DLRBT_Tree *keys, DLRBT_Tree *blocks, floa else UI_ThemeColor4(TH_STRIP); - glRectf(ab->start, ypos - 5, ab->end, ypos + 5); + glRectf(ab->start, ypos - iconsize, ab->end, ypos + iconsize); } } } @@ -686,7 +686,7 @@ static void draw_keylist(View2D *v2d, DLRBT_Tree *keys, DLRBT_Tree *blocks, floa /* draw using OpenGL - uglier but faster */ /* NOTE1: a previous version of this didn't work nice for some intel cards * NOTE2: if we wanted to go back to icons, these are icon = (ak->sel & SELECT) ? ICON_SPACE2 : ICON_SPACE3; */ - draw_keyframe_shape(ak->cfra, ypos, xscale, 5.0f, (ak->sel & SELECT), ak->key_type, KEYFRAME_SHAPE_BOTH, kalpha); + draw_keyframe_shape(ak->cfra, ypos, xscale, iconsize, (ak->sel & SELECT), ak->key_type, KEYFRAME_SHAPE_BOTH, kalpha); } } diff --git a/source/blender/editors/gpencil/drawgpencil.c b/source/blender/editors/gpencil/drawgpencil.c index 11e07584405..3e092ed8c5b 100644 --- a/source/blender/editors/gpencil/drawgpencil.c +++ b/source/blender/editors/gpencil/drawgpencil.c @@ -45,8 +45,10 @@ #include "DNA_scene_types.h" #include "DNA_screen_types.h" #include "DNA_space_types.h" +#include "DNA_userdef_types.h" #include "DNA_view3d_types.h" +#include "BKE_blender.h" #include "BKE_context.h" #include "BKE_global.h" #include "BKE_gpencil.h" diff --git a/source/blender/editors/include/BIF_gl.h b/source/blender/editors/include/BIF_gl.h index 479e0b65177..cdf9b71972d 100644 --- a/source/blender/editors/include/BIF_gl.h +++ b/source/blender/editors/include/BIF_gl.h @@ -35,6 +35,14 @@ #include "GL/glew.h" +#ifdef __APPLE__ + +/* hacking pointsize and linewidth */ +#define glPointSize(f) glPointSize(U.pixelsize*(f)) +#define glLineWidth(f) glLineWidth(U.pixelsize*(f)) + +#endif + /* * these should be phased out. cpack should be replaced in * code with calls to glColor3ub. - zr diff --git a/source/blender/editors/include/ED_anim_api.h b/source/blender/editors/include/ED_anim_api.h index 8d7ae3aad6a..551d3041398 100644 --- a/source/blender/editors/include/ED_anim_api.h +++ b/source/blender/editors/include/ED_anim_api.h @@ -300,34 +300,34 @@ typedef enum eAnimFilter_Flags { /* -------------- Channel Defines -------------- */ /* channel heights */ -#define ACHANNEL_FIRST -16 -#define ACHANNEL_HEIGHT 16 -#define ACHANNEL_HEIGHT_HALF 8 -#define ACHANNEL_SKIP 2 +#define ACHANNEL_FIRST (-0.8f * U.widget_unit) +#define ACHANNEL_HEIGHT (0.8f * U.widget_unit) +#define ACHANNEL_HEIGHT_HALF (0.4f * U.widget_unit) +#define ACHANNEL_SKIP (0.1f * U.widget_unit) #define ACHANNEL_STEP (ACHANNEL_HEIGHT + ACHANNEL_SKIP) /* channel widths */ -#define ACHANNEL_NAMEWIDTH 200 +#define ACHANNEL_NAMEWIDTH (10 * U.widget_unit) /* channel toggle-buttons */ -#define ACHANNEL_BUTTON_WIDTH 16 +#define ACHANNEL_BUTTON_WIDTH (0.8f * U.widget_unit) /* -------------- NLA Channel Defines -------------- */ /* NLA channel heights */ // XXX: NLACHANNEL_FIRST isn't used? -#define NLACHANNEL_FIRST -16 -#define NLACHANNEL_HEIGHT(snla) ((snla && (snla->flag & SNLA_NOSTRIPCURVES)) ? 16 : 24) -#define NLACHANNEL_HEIGHT_HALF(snla) ((snla && (snla->flag & SNLA_NOSTRIPCURVES)) ? 8 : 12) -#define NLACHANNEL_SKIP 2 +#define NLACHANNEL_FIRST (-0.8f * U.widget_unit) +#define NLACHANNEL_HEIGHT(snla) ((snla && (snla->flag & SNLA_NOSTRIPCURVES)) ? (0.8f * U.widget_unit) : (1.2f * U.widget_unit)) +#define NLACHANNEL_HEIGHT_HALF(snla) ((snla && (snla->flag & SNLA_NOSTRIPCURVES)) ? (0.4f * U.widget_unit) : (0.6f * U.widget_unit)) +#define NLACHANNEL_SKIP (0.1f * U.widget_unit) #define NLACHANNEL_STEP(snla) (NLACHANNEL_HEIGHT(snla) + NLACHANNEL_SKIP) /* channel widths */ -#define NLACHANNEL_NAMEWIDTH 200 +#define NLACHANNEL_NAMEWIDTH (10 * U.widget_unit) /* channel toggle-buttons */ -#define NLACHANNEL_BUTTON_WIDTH 16 +#define NLACHANNEL_BUTTON_WIDTH (0.8f * U.widget_unit) /* ---------------- API -------------------- */ diff --git a/source/blender/editors/include/ED_screen.h b/source/blender/editors/include/ED_screen.h index 860d176ffb3..f7a42d5b1ac 100644 --- a/source/blender/editors/include/ED_screen.h +++ b/source/blender/editors/include/ED_screen.h @@ -64,9 +64,9 @@ void ED_region_panels(const struct bContext *C, struct ARegion *ar, int verti void ED_region_header_init(struct ARegion *ar); void ED_region_header(const struct bContext *C, struct ARegion *ar); void ED_region_toggle_hidden(struct bContext *C, struct ARegion *ar); -void region_scissor_winrct(struct ARegion *ar, struct rcti *winrct); void ED_region_info_draw(struct ARegion *ar, const char *text, int block, float alpha); void ED_region_grid_draw(struct ARegion *ar, float zoomx, float zoomy); +float ED_region_blend_factor(struct ARegion *ar); /* spaces */ void ED_spacetypes_init(void); diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h index 2dc552d0fce..abd1782d0f2 100644 --- a/source/blender/editors/include/UI_interface.h +++ b/source/blender/editors/include/UI_interface.h @@ -175,10 +175,10 @@ typedef struct uiLayout uiLayout; /* uiBut->drawflag */ #define UI_BUT_DRAW_ENUM_ARROWS (1 << 0) /* draw enum-like up/down arrows for button */ -/* scale fixed button widths by this to account for DPI - * 8.4852 == sqrtf(72.0f)) */ -#define UI_DPI_FAC (sqrtf((float)U.dpi) / 8.48528137423857f) -#define UI_DPI_ICON_FAC (((float)U.dpi) / 72.0f) +/* scale fixed button widths by this to account for DPI (no difference for buttons or icons anymore */ + +#define UI_DPI_FAC ((U.pixelsize * (float)U.dpi) / 72.0f) +#define UI_DPI_ICON_FAC ((U.pixelsize * (float)U.dpi) / 72.0f) /* 16 to copy ICON_DEFAULT_HEIGHT */ #define UI_DPI_ICON_SIZE ((float)16 * UI_DPI_ICON_FAC) @@ -893,7 +893,10 @@ void uiStyleFontDrawRotated(struct uiFontStyle *fs, struct rcti *rect, const cha int UI_GetStringWidth(const char *str); // XXX temp void UI_DrawString(float x, float y, const char *str); // XXX temp void UI_DrawTriIcon(float x, float y, char dir); -uiStyle *UI_GetStyle(void); + +uiStyle *UI_GetStyle(void); /* use for fonts etc */ +uiStyle *UI_GetStyleDraw(void); /* DPI scaled settings for drawing */ + /* linker workaround ack! */ void UI_template_fix_linking(void); diff --git a/source/blender/editors/include/UI_view2d.h b/source/blender/editors/include/UI_view2d.h index 24759fa778a..3b94291b43a 100644 --- a/source/blender/editors/include/UI_view2d.h +++ b/source/blender/editors/include/UI_view2d.h @@ -102,11 +102,11 @@ enum { /* ------ Defines for Scrollers ----- */ /* scroller area */ -#define V2D_SCROLL_HEIGHT 17 -#define V2D_SCROLL_WIDTH 17 +#define V2D_SCROLL_HEIGHT (0.85f * U.widget_unit) +#define V2D_SCROLL_WIDTH (0.85f * U.widget_unit) /* scroller 'handles' hotspot radius for mouse */ -#define V2D_SCROLLER_HANDLE_SIZE 12 +#define V2D_SCROLLER_HANDLE_SIZE (0.6f * U.widget_unit) /* ------ Define for UI_view2d_sync ----- */ diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c index ce82e064531..3a377ade44c 100644 --- a/source/blender/editors/interface/interface.c +++ b/source/blender/editors/interface/interface.c @@ -69,7 +69,6 @@ #include "WM_api.h" #include "WM_types.h" #include "wm_subwindow.h" -#include "wm_window.h" #include "RNA_access.h" @@ -298,9 +297,9 @@ static void ui_centered_bounds_block(const bContext *C, uiBlock *block) /* note: this is used for the splash where window bounds event has not been * updated by ghost, get the window bounds from ghost directly */ - // wm_window_get_size(window, &xmax, &ymax); - wm_window_get_size_ghost(window, &xmax, &ymax); - + xmax = WM_window_pixels_x(window); + ymax = WM_window_pixels_y(window); + ui_bounds_block(block); width = BLI_rctf_size_x(&block->rect); @@ -326,7 +325,8 @@ static void ui_popup_bounds_block(const bContext *C, uiBlock *block, eBlockBound /* compute mouse position with user defined offset */ ui_bounds_block(block); - wm_window_get_size(window, &xmax, &ymax); + xmax = WM_window_pixels_x(window); + ymax = WM_window_pixels_y(window); oldwidth = BLI_rctf_size_x(&block->rect); oldheight = BLI_rctf_size_y(&block->rect); @@ -334,7 +334,7 @@ static void ui_popup_bounds_block(const bContext *C, uiBlock *block, eBlockBound /* first we ensure wide enough text bounds */ if (bounds_calc == UI_BLOCK_BOUNDS_POPUP_MENU) { if (block->flag & UI_BLOCK_LOOP) { - block->bounds = 50; + block->bounds = 2.5f * UI_UNIT_X; ui_text_bounds_block(block, block->rect.xmin); } } @@ -983,7 +983,8 @@ void ui_fontscale(short *points, float aspect) float pointsf = *points; /* for some reason scaling fonts goes too fast compared to widget size */ - aspect = sqrt(aspect); + /* XXX not true anymore? (ton) */ + //aspect = sqrt(aspect); pointsf /= aspect; if (aspect > 1.0f) @@ -1000,7 +1001,7 @@ static void ui_but_to_pixelrect(rcti *rect, const ARegion *ar, uiBlock *block, u ui_block_to_window_fl(ar, block, &rectf.xmin, &rectf.ymin); ui_block_to_window_fl(ar, block, &rectf.xmax, &rectf.ymax); - + rectf.xmin -= ar->winrct.xmin; rectf.ymin -= ar->winrct.ymin; rectf.xmax -= ar->winrct.xmin; @@ -1015,7 +1016,7 @@ static void ui_but_to_pixelrect(rcti *rect, const ARegion *ar, uiBlock *block, u /* uses local copy of style, to scale things down, and allow widgets to change stuff */ void uiDrawBlock(const bContext *C, uiBlock *block) { - uiStyle style = *UI_GetStyle(); /* XXX pass on as arg */ + uiStyle style = *UI_GetStyleDraw(); /* XXX pass on as arg */ ARegion *ar; uiBut *but; rcti rect; @@ -2650,7 +2651,7 @@ static uiBut *ui_def_but(uiBlock *block, int type, int retval, const char *str, BLI_assert(width >= 0); BLI_assert(height >= 0); - + /* we could do some more error checks here */ if ((type & BUTTYPE) == LABEL) { BLI_assert((poin != NULL || min != 0.0f || max != 0.0f || (a1 == 0.0f && a2 != 0.0f) || (a1 != 0.0f && a1 != 1.0f)) == FALSE); diff --git a/source/blender/editors/interface/interface_draw.c b/source/blender/editors/interface/interface_draw.c index 4d96ad810d4..792553f842c 100644 --- a/source/blender/editors/interface/interface_draw.c +++ b/source/blender/editors/interface/interface_draw.c @@ -429,17 +429,18 @@ void ui_draw_but_IMAGE(ARegion *UNUSED(ar), uiBut *but, uiWidgetColors *UNUSED(w #else ImBuf *ibuf = (ImBuf *)but->poin; //GLint scissor[4]; - //int w, h; + int w, h; if (!ibuf) return; + w = BLI_rcti_size_x(rect); + h = BLI_rcti_size_y(rect); + /* scissor doesn't seem to be doing the right thing...? */ #if 0 //glColor4f(1.0, 0.f, 0.f, 1.f); //fdrawbox(rect->xmin, rect->ymin, rect->xmax, rect->ymax) - w = BLI_rcti_size_x(rect); - h = BLI_rcti_size_y(rect); /* prevent drawing outside widget area */ glGetIntegerv(GL_SCISSOR_BOX, scissor); glScissor(ar->winrct.xmin + rect->xmin, ar->winrct.ymin + rect->ymin, w, h); @@ -448,9 +449,16 @@ void ui_draw_but_IMAGE(ARegion *UNUSED(ar), uiBut *but, uiWidgetColors *UNUSED(w glEnable(GL_BLEND); glColor4f(0.0, 0.0, 0.0, 0.0); + if (w != ibuf->x || h != ibuf->y) { + float facx = (float)w / (float)ibuf->x; + float facy = (float)h / (float)ibuf->y; + glPixelZoom(facx, facy); + } glaDrawPixelsSafe((float)rect->xmin, (float)rect->ymin, ibuf->x, ibuf->y, ibuf->x, GL_RGBA, GL_UNSIGNED_BYTE, ibuf->rect); //glaDrawPixelsTex((float)rect->xmin, (float)rect->ymin, ibuf->x, ibuf->y, GL_UNSIGNED_BYTE, ibuf->rect); + glPixelZoom(1.0f, 1.0f); + glDisable(GL_BLEND); #if 0 diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c index 1ac56fd30bb..258775867cc 100644 --- a/source/blender/editors/interface/interface_handlers.c +++ b/source/blender/editors/interface/interface_handlers.c @@ -4530,7 +4530,7 @@ static uiBlock *menu_change_shortcut(bContext *C, ARegion *ar, void *arg) wmKeyMapItem *kmi; PointerRNA ptr; uiLayout *layout; - uiStyle *style = UI_GetStyle(); + uiStyle *style = UI_GetStyleDraw(); IDProperty *prop = (but->opptr) ? but->opptr->data : NULL; int kmi_id = WM_key_event_operator_id(C, but->optype->idname, but->opcontext, prop, 1, &km); @@ -4562,7 +4562,7 @@ static uiBlock *menu_add_shortcut(bContext *C, ARegion *ar, void *arg) wmKeyMapItem *kmi; PointerRNA ptr; uiLayout *layout; - uiStyle *style = UI_GetStyle(); + uiStyle *style = UI_GetStyleDraw(); IDProperty *prop = (but->opptr) ? but->opptr->data : NULL; int kmi_id; diff --git a/source/blender/editors/interface/interface_icons.c b/source/blender/editors/interface/interface_icons.c index bb0cc1176d8..d78985fa5e2 100644 --- a/source/blender/editors/interface/interface_icons.c +++ b/source/blender/editors/interface/interface_icons.c @@ -750,7 +750,7 @@ static DrawInfo *icon_create_drawinfo(void) return di; } -/* note!, returns unscaled by DPI, may need to multiply result by UI_DPI_ICON_FAC */ +/* note!, returns unscaled by DPI */ int UI_icon_get_width(int icon_id) { Icon *icon = NULL; @@ -887,7 +887,7 @@ static void icon_draw_rect(float x, float y, int w, int h, float UNUSED(aspect), /* first allocate imbuf for scaling and copy preview into it */ ima = IMB_allocImBuf(rw, rh, 32, IB_rect); memcpy(ima->rect, rect, rw * rh * sizeof(unsigned int)); - IMB_scaleImBuf(ima, w, h); /* scale it */ + IMB_scalefastImBuf(ima, w, h); /* scale it */ rect = ima->rect; } @@ -965,7 +965,7 @@ static void icon_draw_size(float x, float y, int icon_id, float aspect, float al Icon *icon = NULL; DrawInfo *di = NULL; IconImage *iimg; - float fdraw_size = is_preview ? draw_size : (draw_size * UI_DPI_ICON_FAC); + float fdraw_size = draw_size; int w, h; icon = BKE_icon_get(icon_id); @@ -1158,9 +1158,10 @@ void UI_icon_draw_aspect_color(float x, float y, int icon_id, float aspect, cons icon_draw_size(x, y, icon_id, aspect, 1.0f, rgb, ICON_SIZE_ICON, draw_size, FALSE, FALSE); } +/* draws icon with dpi scale factor */ void UI_icon_draw(float x, float y, int icon_id) { - UI_icon_draw_aspect(x, y, icon_id, 1.0f, 1.0f); + UI_icon_draw_aspect(x, y, icon_id, 1.0f / UI_DPI_ICON_FAC, 1.0f); } void UI_icon_draw_size(float x, float y, int size, int icon_id, float alpha) diff --git a/source/blender/editors/interface/interface_intern.h b/source/blender/editors/interface/interface_intern.h index 1dc98639fe7..fce43173832 100644 --- a/source/blender/editors/interface/interface_intern.h +++ b/source/blender/editors/interface/interface_intern.h @@ -267,7 +267,7 @@ struct uiBut { void *dragpoin; struct ImBuf *imb; float imb_scale; - + /* active button data */ struct uiHandleButtonData *active; diff --git a/source/blender/editors/interface/interface_layout.c b/source/blender/editors/interface/interface_layout.c index c67c64a0540..e93ecc72725 100644 --- a/source/blender/editors/interface/interface_layout.c +++ b/source/blender/editors/interface/interface_layout.c @@ -65,8 +65,6 @@ #define RNA_NO_INDEX -1 #define RNA_ENUM_VALUE -2 -#define EM_SEPR_X 6 -#define EM_SEPR_Y 6 // #define USE_OP_RESET_BUT // we may want to make this optional, disable for now. @@ -227,14 +225,16 @@ static int ui_layout_vary_direction(uiLayout *layout) /* estimated size of text + icon */ static int ui_text_icon_width(uiLayout *layout, const char *name, int icon, int compact) { + float f5 = 0.25f * UI_UNIT_X; + float f10 = 0.5f * UI_UNIT_X; int variable = ui_layout_vary_direction(layout) == UI_ITEM_VARY_X; if (icon && !name[0]) return UI_UNIT_X; /* icon only */ else if (icon) - return (variable) ? UI_GetStringWidth(name) + (compact ? 5 : 10) + UI_UNIT_X : 10 * UI_UNIT_X; /* icon + text */ + return (variable) ? UI_GetStringWidth(name) + (compact ? f5 : f10) + UI_UNIT_X : 10 * UI_UNIT_X; /* icon + text */ else - return (variable) ? UI_GetStringWidth(name) + (compact ? 5 : 10) + UI_UNIT_X : 10 * UI_UNIT_X; /* text only */ + return (variable) ? UI_GetStringWidth(name) + (compact ? f5 : f10) + UI_UNIT_X : 10 * UI_UNIT_X; /* text only */ } static void ui_item_size(uiItem *item, int *r_w, int *r_h) @@ -1495,7 +1495,7 @@ static void ui_item_menu(uiLayout *layout, const char *name, int icon, uiMenuCre h = UI_UNIT_Y; if (layout->root->type == UI_LAYOUT_HEADER) /* ugly .. */ - w -= 10; + w -= UI_UNIT_Y/2; if (name[0] && icon) but = uiDefIconTextMenuBut(block, func, arg, icon, name, 0, 0, w, h, tip); @@ -1610,7 +1610,7 @@ void uiItemS(uiLayout *layout) uiBlock *block = layout->root->block; uiBlockSetCurLayout(block, layout); - uiDefBut(block, SEPR, 0, "", 0, 0, EM_SEPR_X, EM_SEPR_Y, NULL, 0.0, 0.0, 0, 0, ""); + uiDefBut(block, SEPR, 0, "", 0, 0, 0.3f * UI_UNIT_X, 0.3f * UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, ""); } /* level items */ @@ -2941,7 +2941,7 @@ void uiLayoutOperatorButs(const bContext *C, uiLayout *layout, wmOperator *op, col = uiLayoutColumn(layout, FALSE); block = uiLayoutGetBlock(col); - but = uiDefIconTextBut(block, BUT, 0, ICON_FILE_REFRESH, IFACE_("Reset"), 0, 0, 18, 20, + but = uiDefIconTextBut(block, BUT, 0, ICON_FILE_REFRESH, IFACE_("Reset"), 0, 0, UI_UNIT_X, UI_UNIT_Y, NULL, 0.0, 0.0, 0.0, 0.0, TIP_("Reset operator defaults")); uiButSetFunc(but, ui_layout_operator_buts__reset_cb, op, NULL); } diff --git a/source/blender/editors/interface/interface_panel.c b/source/blender/editors/interface/interface_panel.c index 2b170ea546b..0bdb39cb58e 100644 --- a/source/blender/editors/interface/interface_panel.c +++ b/source/blender/editors/interface/interface_panel.c @@ -305,7 +305,7 @@ void uiEndPanel(uiBlock *block, int width, int height) static void ui_offset_panel_block(uiBlock *block) { - uiStyle *style = UI_GetStyle(); + uiStyle *style = UI_GetStyleDraw(); uiBut *but; int ofsy; @@ -345,14 +345,18 @@ static void uiPanelPop(uiBlock *UNUSED(block)) /* triangle 'icon' for panel header */ void UI_DrawTriIcon(float x, float y, char dir) { + float f3 = 0.15 * U.widget_unit; + float f5 = 0.25 * U.widget_unit; + float f7 = 0.35 * U.widget_unit; + if (dir == 'h') { - ui_draw_anti_tria(x - 3, y - 5, x - 3, y + 5, x + 7, y); + ui_draw_anti_tria(x - f3, y - f5, x - f3, y + f5, x + f7, y); } else if (dir == 't') { - ui_draw_anti_tria(x - 5, y - 7, x + 5, y - 7, x, y + 3); + ui_draw_anti_tria(x - f5, y - f7, x + f5, y - f7, x, y + f3); } else { /* 'v' = vertical, down */ - ui_draw_anti_tria(x - 5, y + 3, x + 5, y + 3, x, y - 7); + ui_draw_anti_tria(x - f5, y + f3, x + f5, y + f3, x, y - f7); } } diff --git a/source/blender/editors/interface/interface_regions.c b/source/blender/editors/interface/interface_regions.c index b62e634b1eb..ed619605963 100644 --- a/source/blender/editors/interface/interface_regions.c +++ b/source/blender/editors/interface/interface_regions.c @@ -672,7 +672,9 @@ ARegion *ui_tooltip_create(bContext *C, ARegion *butregion, uiBut *but) BLI_rcti_translate(&rect_i, butregion->winrct.xmin, butregion->winrct.ymin); } - wm_window_get_size(CTX_wm_window(C), &winx, &winy); + winx = WM_window_pixels_x(CTX_wm_window(C)); + winy = WM_window_pixels_y(CTX_wm_window(C)); + //wm_window_get_size(CTX_wm_window(C), &winx, &winy); if (rect_i.xmax > winx) { /* super size */ @@ -1185,7 +1187,9 @@ ARegion *ui_searchbox_create(bContext *C, ARegion *butregion, uiBut *but) BLI_rcti_translate(&rect_i, butregion->winrct.xmin, butregion->winrct.ymin); - wm_window_get_size(CTX_wm_window(C), &winx, &winy); + winx = WM_window_pixels_x(CTX_wm_window(C)); + winy = WM_window_pixels_y(CTX_wm_window(C)); + //wm_window_get_size(CTX_wm_window(C), &winx, &winy); if (rect_i.xmax > winx) { /* super size */ @@ -1314,11 +1318,11 @@ static void ui_block_position(wmWindow *window, ARegion *butregion, uiBut *but, /* widget_roundbox_set has this correction too, keep in sync */ if (but->type != PULLDOWN) { if (but->flag & UI_BUT_ALIGN_TOP) - butrct.ymax += 1.0f; + butrct.ymax += U.pixelsize; if (but->flag & UI_BUT_ALIGN_LEFT) - butrct.xmin -= 1.0f; + butrct.xmin -= U.pixelsize; } - + /* calc block rect */ if (block->rect.xmin == 0.0f && block->rect.xmax == 0.0f) { if (block->buttons.first) { @@ -1334,7 +1338,7 @@ static void ui_block_position(wmWindow *window, ARegion *butregion, uiBut *but, block->rect.xmax = block->rect.ymax = 20; } } - + /* aspect = (float)(BLI_rcti_size_x(&block->rect) + 4);*/ /*UNUSED*/ ui_block_to_window_fl(butregion, but->block, &block->rect.xmin, &block->rect.ymin); ui_block_to_window_fl(butregion, but->block, &block->rect.xmax, &block->rect.ymax); @@ -1342,8 +1346,8 @@ static void ui_block_position(wmWindow *window, ARegion *butregion, uiBut *but, //block->rect.xmin -= 2.0; block->rect.ymin -= 2.0; //block->rect.xmax += 2.0; block->rect.ymax += 2.0; - xsize = BLI_rctf_size_x(&block->rect) + 4; /* 4 for shadow */ - ysize = BLI_rctf_size_y(&block->rect) + 4; + xsize = BLI_rctf_size_x(&block->rect) + 0.2f * UI_UNIT_X; /* 4 for shadow */ + ysize = BLI_rctf_size_y(&block->rect) + 0.2f * UI_UNIT_Y; /* aspect /= (float)xsize;*/ /*UNUSED*/ { @@ -1351,7 +1355,9 @@ static void ui_block_position(wmWindow *window, ARegion *butregion, uiBut *but, int winx, winy; // int offscreen; - wm_window_get_size(window, &winx, &winy); + winx = WM_window_pixels_x(window); + winy = WM_window_pixels_y(window); + // wm_window_get_size(window, &winx, &winy); if (block->direction & UI_CENTER) center = ysize / 2; else center = 0; @@ -1523,7 +1529,9 @@ static void ui_popup_block_clip(wmWindow *window, uiBlock *block) return; } - wm_window_get_size(window, &winx, &winy); + winx = WM_window_pixels_x(window); + winy = WM_window_pixels_y(window); + // wm_window_get_size(window, &winx, &winy); if (block->rect.xmin < MENU_SHADOW_SIDE) block->rect.xmin = MENU_SHADOW_SIDE; @@ -1635,7 +1643,6 @@ uiPopupBlockHandle *ui_popup_block_create(bContext *C, ARegion *butregion, uiBut /* if this is being created from a button */ if (but) { block->aspect = but->block->aspect; - ui_block_position(window, butregion, but, block); handle->direction = block->direction; } @@ -2019,10 +2026,10 @@ static void do_picker_new_mode_cb(bContext *UNUSED(C), void *bt1, void *UNUSED(a picker_new_hide_reveal(bt->block, colormode); } -#define PICKER_H 150 -#define PICKER_W 150 -#define PICKER_SPACE 6 -#define PICKER_BAR 14 +#define PICKER_H (7.5f * U.widget_unit) +#define PICKER_W (7.5f * U.widget_unit) +#define PICKER_SPACE (0.3f * U.widget_unit) +#define PICKER_BAR (0.7f * U.widget_unit) #define PICKER_TOTAL_W (PICKER_W + PICKER_SPACE + PICKER_BAR) @@ -2066,11 +2073,12 @@ static void uiBlockPicker(uiBlock *block, float rgba[4], PointerRNA *ptr, Proper float rgb_gamma[3]; float min, max, step, precision; float *hsv = ui_block_hsv_get(block); + int yco; ui_block_hsv_get(block); width = PICKER_TOTAL_W; - butwidth = width - UI_UNIT_X - 10; + butwidth = width - 1.5f * UI_UNIT_X; /* existence of profile means storage is in linear color space, with display correction */ /* XXX That tip message is not use anywhere! */ @@ -2108,44 +2116,47 @@ static void uiBlockPicker(uiBlock *block, float rgba[4], PointerRNA *ptr, Proper } /* mode */ + yco = -1.5f * UI_UNIT_Y; uiBlockBeginAlign(block); - bt = uiDefButS(block, ROW, 0, IFACE_("RGB"), 0, -30, width / 3, UI_UNIT_Y, &colormode, 0.0, 0.0, 0, 0, ""); + bt = uiDefButS(block, ROW, 0, IFACE_("RGB"), 0, yco, width / 3, UI_UNIT_Y, &colormode, 0.0, 0.0, 0, 0, ""); uiButSetFunc(bt, do_picker_new_mode_cb, bt, NULL); - bt = uiDefButS(block, ROW, 0, IFACE_("HSV"), width / 3, -30, width / 3, UI_UNIT_Y, &colormode, 0.0, 1.0, 0, 0, ""); + bt = uiDefButS(block, ROW, 0, IFACE_("HSV"), width / 3, yco, width / 3, UI_UNIT_Y, &colormode, 0.0, 1.0, 0, 0, ""); uiButSetFunc(bt, do_picker_new_mode_cb, bt, NULL); - bt = uiDefButS(block, ROW, 0, IFACE_("Hex"), 2 * width / 3, -30, width / 3, UI_UNIT_Y, &colormode, 0.0, 2.0, 0, 0, ""); + bt = uiDefButS(block, ROW, 0, IFACE_("Hex"), 2 * width / 3, yco, width / 3, UI_UNIT_Y, &colormode, 0.0, 2.0, 0, 0, ""); uiButSetFunc(bt, do_picker_new_mode_cb, bt, NULL); uiBlockEndAlign(block); + yco = -3.0f * UI_UNIT_Y; if (show_picker) { - bt = uiDefIconButO(block, BUT, "UI_OT_eyedropper", WM_OP_INVOKE_DEFAULT, ICON_EYEDROPPER, butwidth + 10, -60, UI_UNIT_X, UI_UNIT_Y, NULL); + bt = uiDefIconButO(block, BUT, "UI_OT_eyedropper", WM_OP_INVOKE_DEFAULT, ICON_EYEDROPPER, butwidth + 10, yco, UI_UNIT_X, UI_UNIT_Y, NULL); uiButSetFunc(bt, close_popup_cb, bt, NULL); } /* RGB values */ uiBlockBeginAlign(block); - bt = uiDefButR_prop(block, NUMSLI, 0, IFACE_("R "), 0, -60, butwidth, UI_UNIT_Y, ptr, prop, 0, 0.0, 0.0, 0, 3, TIP_("Red")); + bt = uiDefButR_prop(block, NUMSLI, 0, IFACE_("R "), 0, yco, butwidth, UI_UNIT_Y, ptr, prop, 0, 0.0, 0.0, 0, 3, TIP_("Red")); uiButSetFunc(bt, do_picker_rna_cb, bt, NULL); - bt = uiDefButR_prop(block, NUMSLI, 0, IFACE_("G "), 0, -80, butwidth, UI_UNIT_Y, ptr, prop, 1, 0.0, 0.0, 0, 3, TIP_("Green")); + bt = uiDefButR_prop(block, NUMSLI, 0, IFACE_("G "), 0, yco -= UI_UNIT_Y, butwidth, UI_UNIT_Y, ptr, prop, 1, 0.0, 0.0, 0, 3, TIP_("Green")); uiButSetFunc(bt, do_picker_rna_cb, bt, NULL); - bt = uiDefButR_prop(block, NUMSLI, 0, IFACE_("B "), 0, -100, butwidth, UI_UNIT_Y, ptr, prop, 2, 0.0, 0.0, 0, 3, TIP_("Blue")); + bt = uiDefButR_prop(block, NUMSLI, 0, IFACE_("B "), 0, yco -= UI_UNIT_Y, butwidth, UI_UNIT_Y, ptr, prop, 2, 0.0, 0.0, 0, 3, TIP_("Blue")); uiButSetFunc(bt, do_picker_rna_cb, bt, NULL); /* could use uiItemFullR(col, ptr, prop, -1, 0, UI_ITEM_R_EXPAND|UI_ITEM_R_SLIDER, "", ICON_NONE); * but need to use uiButSetFunc for updating other fake buttons */ /* HSV values */ + yco = -3.0f * UI_UNIT_Y; uiBlockBeginAlign(block); - bt = uiDefButF(block, NUMSLI, 0, IFACE_("H "), 0, -60, butwidth, UI_UNIT_Y, hsv, 0.0, 1.0, 10, 3, TIP_("Hue")); + bt = uiDefButF(block, NUMSLI, 0, IFACE_("H "), 0, yco, butwidth, UI_UNIT_Y, hsv, 0.0, 1.0, 10, 3, TIP_("Hue")); uiButSetFunc(bt, do_hsv_rna_cb, bt, hsv); - bt = uiDefButF(block, NUMSLI, 0, IFACE_("S "), 0, -80, butwidth, UI_UNIT_Y, hsv + 1, 0.0, 1.0, 10, 3, TIP_("Saturation")); + bt = uiDefButF(block, NUMSLI, 0, IFACE_("S "), 0, yco -= UI_UNIT_Y, butwidth, UI_UNIT_Y, hsv + 1, 0.0, 1.0, 10, 3, TIP_("Saturation")); uiButSetFunc(bt, do_hsv_rna_cb, bt, hsv); - bt = uiDefButF(block, NUMSLI, 0, IFACE_("V "), 0, -100, butwidth, UI_UNIT_Y, hsv + 2, 0.0, max, 10, 3, TIP_("Value")); + bt = uiDefButF(block, NUMSLI, 0, IFACE_("V "), 0, yco -= UI_UNIT_Y, butwidth, UI_UNIT_Y, hsv + 2, 0.0, max, 10, 3, TIP_("Value")); uiButSetFunc(bt, do_hsv_rna_cb, bt, hsv); uiBlockEndAlign(block); if (rgba[3] != FLT_MAX) { - bt = uiDefButR_prop(block, NUMSLI, 0, IFACE_("A "), 0, -120, butwidth, UI_UNIT_Y, ptr, prop, 3, 0.0, 0.0, 0, 0, TIP_("Alpha")); + bt = uiDefButR_prop(block, NUMSLI, 0, IFACE_("A "), 0, yco -= UI_UNIT_Y, butwidth, UI_UNIT_Y, ptr, prop, 3, 0.0, 0.0, 0, 0, TIP_("Alpha")); uiButSetFunc(bt, do_picker_rna_cb, bt, NULL); } else { @@ -2154,9 +2165,10 @@ static void uiBlockPicker(uiBlock *block, float rgba[4], PointerRNA *ptr, Proper BLI_snprintf(hexcol, sizeof(hexcol), "%02X%02X%02X", FTOCHAR(rgb_gamma[0]), FTOCHAR(rgb_gamma[1]), FTOCHAR(rgb_gamma[2])); - bt = uiDefBut(block, TEX, 0, IFACE_("Hex: "), 0, -60, butwidth, UI_UNIT_Y, hexcol, 0, 8, 0, 0, TIP_("Hex triplet for color (#RRGGBB)")); + yco = -3.0f * UI_UNIT_Y; + bt = uiDefBut(block, TEX, 0, IFACE_("Hex: "), 0, yco, butwidth, UI_UNIT_Y, hexcol, 0, 8, 0, 0, TIP_("Hex triplet for color (#RRGGBB)")); uiButSetFunc(bt, do_hex_rna_cb, bt, hexcol); - uiDefBut(block, LABEL, 0, IFACE_("(Gamma Corrected)"), 0, -80, butwidth, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, ""); + uiDefBut(block, LABEL, 0, IFACE_("(Gamma Corrected)"), 0, yco - UI_UNIT_Y, butwidth, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, ""); rgb_to_hsv_v(rgba, hsv); @@ -2228,7 +2240,7 @@ uiBlock *ui_block_func_COLOR(bContext *C, uiPopupBlockHandle *handle, void *arg_ uiBlockPicker(block, handle->retvec, &but->rnapoin, but->rnaprop, show_picker); block->flag = UI_BLOCK_LOOP | UI_BLOCK_REDRAW | UI_BLOCK_KEEP_OPEN | UI_BLOCK_OUT_1 | UI_BLOCK_MOVEMOUSE_QUIT; - uiBoundsBlock(block, 10); + uiBoundsBlock(block, 0.5 * UI_UNIT_X); block->block_event_func = ui_picker_small_wheel_cb; @@ -2386,7 +2398,7 @@ static uiBlock *ui_block_func_POPUP(bContext *C, uiPopupBlockHandle *handle, voi } block->minbounds = minwidth; - uiTextBoundsBlock(block, 50); + uiTextBoundsBlock(block, 2.5 * UI_UNIT_X); } /* if menu slides out of other menu, override direction */ @@ -2402,7 +2414,7 @@ uiPopupBlockHandle *ui_popup_menu_create(bContext *C, ARegion *butregion, uiBut uiMenuCreateFunc menu_func, void *arg, char *str) { wmWindow *window = CTX_wm_window(C); - uiStyle *style = UI_GetStyle(); + uiStyle *style = UI_GetStyleDraw(); uiPopupBlockHandle *handle; uiPopupMenu *pup; pup = MEM_callocN(sizeof(uiPopupMenu), __func__); @@ -2466,7 +2478,7 @@ uiPopupBlockHandle *ui_popup_menu_create(bContext *C, ARegion *butregion, uiBut /* only return handler, and set optional title */ uiPopupMenu *uiPupMenuBegin(bContext *C, const char *title, int icon) { - uiStyle *style = UI_GetStyle(); + uiStyle *style = UI_GetStyleDraw(); uiPopupMenu *pup = MEM_callocN(sizeof(uiPopupMenu), "popup menu"); uiBut *but; diff --git a/source/blender/editors/interface/interface_style.c b/source/blender/editors/interface/interface_style.c index 7e7db6aeaaa..7118cbcd855 100644 --- a/source/blender/editors/interface/interface_style.c +++ b/source/blender/editors/interface/interface_style.c @@ -166,7 +166,7 @@ void uiStyleFontDrawExt(uiFontStyle *fs, rcti *rect, const char *str, } /* clip is very strict, so we give it some space */ - BLF_clipping(fs->uifont_id, rect->xmin - 1, rect->ymin - 4, rect->xmax + 1, rect->ymax + 4); + BLF_clipping(fs->uifont_id, rect->xmin - 2, rect->ymin - 4, rect->xmax + 1, rect->ymax + 4); BLF_enable(fs->uifont_id, BLF_CLIPPING); BLF_position(fs->uifont_id, rect->xmin + xofs, rect->ymin + yofs, 0.0f); @@ -261,6 +261,32 @@ uiStyle *UI_GetStyle(void) return (style != NULL) ? style : U.uistyles.first; } +/* for drawing, scaled with DPI setting */ +uiStyle *UI_GetStyleDraw(void) +{ + uiStyle *style = UI_GetStyle(); + static uiStyle _style; + + _style = *style; + + _style.paneltitle.shadx = (short)(UI_DPI_FAC * _style.paneltitle.shadx); + _style.paneltitle.shady = (short)(UI_DPI_FAC * _style.grouplabel.shady); + _style.grouplabel.shadx = (short)(UI_DPI_FAC * _style.grouplabel.shadx); + _style.grouplabel.shady = (short)(UI_DPI_FAC * _style.paneltitle.shady); + _style.widgetlabel.shadx = (short)(UI_DPI_FAC * _style.widgetlabel.shadx); + _style.widgetlabel.shady = (short)(UI_DPI_FAC * _style.widgetlabel.shady); + + _style.columnspace = (short)(UI_DPI_FAC * _style.columnspace); + _style.templatespace = (short)(UI_DPI_FAC * _style.templatespace); + _style.boxspace = (short)(UI_DPI_FAC * _style.boxspace); + _style.buttonspacex = (short)(UI_DPI_FAC * _style.buttonspacex); + _style.buttonspacey = (short)(UI_DPI_FAC * _style.buttonspacey); + _style.panelspace = (short)(UI_DPI_FAC * _style.panelspace); + _style.panelouter = (short)(UI_DPI_FAC * _style.panelouter); + + return &_style; +} + /* temporarily, does widget font */ int UI_GetStringWidth(const char *str) { @@ -364,9 +390,9 @@ void uiStyleInit(void) * Yes, this build the glyph cache and create * the texture. */ - BLF_size(font->blf_id, 11, U.dpi); - BLF_size(font->blf_id, 12, U.dpi); - BLF_size(font->blf_id, 14, U.dpi); + BLF_size(font->blf_id, 11 * U.pixelsize, U.dpi); + BLF_size(font->blf_id, 12 * U.pixelsize, U.dpi); + BLF_size(font->blf_id, 14 * U.pixelsize, U.dpi); } } @@ -378,19 +404,19 @@ void uiStyleInit(void) if (blf_mono_font == -1) blf_mono_font = BLF_load_mem_unique("monospace", (unsigned char *)datatoc_bmonofont_ttf, datatoc_bmonofont_ttf_size); - BLF_size(blf_mono_font, 12, 72); + BLF_size(blf_mono_font, 12 * U.pixelsize, 72); /* second for rendering else we get threading problems */ if (blf_mono_font_render == -1) blf_mono_font_render = BLF_load_mem_unique("monospace", (unsigned char *)datatoc_bmonofont_ttf, datatoc_bmonofont_ttf_size); - BLF_size(blf_mono_font_render, 12, 72); + BLF_size(blf_mono_font_render, 12 * U.pixelsize, 72 ); } void uiStyleFontSet(uiFontStyle *fs) { uiFont *font = uifont_to_blfont(fs->uifont_id); - BLF_size(font->blf_id, fs->points, U.dpi); + BLF_size(font->blf_id, fs->points * U.pixelsize, U.dpi); } diff --git a/source/blender/editors/interface/interface_templates.c b/source/blender/editors/interface/interface_templates.c index f7a53c6bab2..0e3c32334b8 100644 --- a/source/blender/editors/interface/interface_templates.c +++ b/source/blender/editors/interface/interface_templates.c @@ -179,29 +179,29 @@ static uiBlock *id_search_menu(bContext *C, ARegion *ar, void *arg_litem) /* preview thumbnails */ if (template.prv_rows > 0 && template.prv_cols > 0) { - int w = 96 * template.prv_cols; - int h = 96 * template.prv_rows + 20; + int w = 4 * U.widget_unit * template.prv_cols; + int h = 4 * U.widget_unit * template.prv_rows + U.widget_unit; /* fake button, it holds space for search items */ uiDefBut(block, LABEL, 0, "", 10, 15, w, h, NULL, 0, 0, 0, 0, NULL); - but = uiDefSearchBut(block, search, 0, ICON_VIEWZOOM, sizeof(search), 10, 0, w, 19, - template.prv_rows, template.prv_cols, ""); + but = uiDefSearchBut(block, search, 0, ICON_VIEWZOOM, sizeof(search), 10, 0, w, UI_UNIT_Y, + template.prv_rows, template.prv_cols, ""); uiButSetSearchFunc(but, id_search_cb, &template, id_search_call_cb, idptr.data); } /* list view */ else { const int searchbox_width = uiSearchBoxWidth(); const int searchbox_height = uiSearchBoxHeight(); + /* fake button, it holds space for search items */ uiDefBut(block, LABEL, 0, "", 10, 15, searchbox_width, searchbox_height, NULL, 0, 0, 0, 0, NULL); - but = uiDefSearchBut(block, search, 0, ICON_VIEWZOOM, sizeof(search), 10, 0, searchbox_width, UI_UNIT_Y - 1, 0, 0, ""); uiButSetSearchFunc(but, id_search_cb, &template, id_search_call_cb, idptr.data); } - uiBoundsBlock(block, 6); + uiBoundsBlock(block, 0.3f * U.widget_unit); uiBlockSetDirection(block, UI_DOWN); uiEndBlock(C, block); @@ -1437,7 +1437,7 @@ static void colorband_buttons_large(uiLayout *layout, uiBlock *block, ColorBand const int line2_y = yoffs + 65; if (coba == NULL) return; - + bt = uiDefBut(block, BUT, 0, IFACE_("Add"), 0 + xoffs, line1_y, 40, UI_UNIT_Y, NULL, 0, 0, 0, 0, TIP_("Add a new color stop to the colorband")); uiButSetNFunc(bt, colorband_add_cb, MEM_dupallocN(cb), coba); @@ -1547,8 +1547,8 @@ void uiTemplateColorRamp(uiLayout *layout, PointerRNA *ptr, const char *propname cb->ptr = *ptr; cb->prop = prop; - rect.xmin = 0; rect.xmax = 200; - rect.ymin = 0; rect.ymax = 190; + rect.xmin = 0; rect.xmax = 10.0f * UI_UNIT_X; + rect.ymin = 0; rect.ymax = 19.5f * UI_UNIT_X; block = uiLayoutAbsoluteBlock(layout); colorband_buttons_layout(layout, block, cptr.data, &rect, !expand, cb); @@ -1579,8 +1579,8 @@ void uiTemplateHistogram(uiLayout *layout, PointerRNA *ptr, const char *propname cb->ptr = *ptr; cb->prop = prop; - rect.xmin = 0; rect.xmax = 200; - rect.ymin = 0; rect.ymax = 190; + rect.xmin = 0; rect.xmax = 10.0f * UI_UNIT_X; + rect.ymin = 0; rect.ymax = 9.5f * UI_UNIT_Y; block = uiLayoutAbsoluteBlock(layout); //colorband_buttons_layout(layout, block, cptr.data, &rect, !expand, cb); @@ -1589,8 +1589,9 @@ void uiTemplateHistogram(uiLayout *layout, PointerRNA *ptr, const char *propname hist->height = (hist->height <= UI_UNIT_Y) ? UI_UNIT_Y : hist->height; - bt = uiDefBut(block, HISTOGRAM, 0, "", rect.xmin, rect.ymin, BLI_rctf_size_x(&rect), hist->height, hist, - 0, 0, 0, 0, ""); + bt = uiDefBut(block, HISTOGRAM, 0, "", rect.xmin, rect.ymin, BLI_rctf_size_x(&rect), UI_DPI_FAC * hist->height, + hist, 0, 0, 0, 0, ""); + uiButSetNFunc(bt, rna_update_cb, MEM_dupallocN(cb), NULL); MEM_freeN(cb); @@ -1620,15 +1621,15 @@ void uiTemplateWaveform(uiLayout *layout, PointerRNA *ptr, const char *propname) cb->ptr = *ptr; cb->prop = prop; - rect.xmin = 0; rect.xmax = 200; - rect.ymin = 0; rect.ymax = 190; + rect.xmin = 0; rect.xmax = 10.0f * UI_UNIT_X; + rect.ymin = 0; rect.ymax = 9.5f * UI_UNIT_Y; block = uiLayoutAbsoluteBlock(layout); scopes->wavefrm_height = (scopes->wavefrm_height <= UI_UNIT_Y) ? UI_UNIT_Y : scopes->wavefrm_height; - bt = uiDefBut(block, WAVEFORM, 0, "", rect.xmin, rect.ymin, BLI_rctf_size_x(&rect), scopes->wavefrm_height, scopes, - 0, 0, 0, 0, ""); + bt = uiDefBut(block, WAVEFORM, 0, "", rect.xmin, rect.ymin, BLI_rctf_size_x(&rect), UI_DPI_FAC * scopes->wavefrm_height, + scopes, 0, 0, 0, 0, ""); (void)bt; /* UNUSED */ MEM_freeN(cb); @@ -1658,15 +1659,15 @@ void uiTemplateVectorscope(uiLayout *layout, PointerRNA *ptr, const char *propna cb->ptr = *ptr; cb->prop = prop; - rect.xmin = 0; rect.xmax = 200; - rect.ymin = 0; rect.ymax = 190; + rect.xmin = 0; rect.xmax = 10.0f * UI_UNIT_X; + rect.ymin = 0; rect.ymax = 9.5f * UI_UNIT_Y; block = uiLayoutAbsoluteBlock(layout); scopes->vecscope_height = (scopes->vecscope_height <= UI_UNIT_Y) ? UI_UNIT_Y : scopes->vecscope_height; bt = uiDefBut(block, VECTORSCOPE, 0, "", rect.xmin, rect.ymin, BLI_rctf_size_x(&rect), - scopes->vecscope_height, scopes, 0, 0, 0, 0, ""); + UI_DPI_FAC * scopes->vecscope_height, scopes, 0, 0, 0, 0, ""); uiButSetNFunc(bt, rna_update_cb, MEM_dupallocN(cb), NULL); MEM_freeN(cb); @@ -2010,7 +2011,7 @@ static void curvemap_buttons_layout(uiLayout *layout, PointerRNA *ptr, char labe /* curve itself */ size = uiLayoutGetWidth(layout); row = uiLayoutRow(layout, FALSE); - uiDefBut(block, BUT_CURVE, 0, "", 0, 0, size, MIN2(size, 200), cumap, 0.0f, 1.0f, bg, 0, ""); + uiDefBut(block, BUT_CURVE, 0, "", 0, 0, size, MIN2(size, 10.0f * UI_UNIT_X), cumap, 0.0f, 1.0f, bg, 0, ""); /* sliders for selected point */ for (i = 0; i < cm->totpoint; i++) { @@ -2081,7 +2082,7 @@ void uiTemplateCurveMapping(uiLayout *layout, PointerRNA *ptr, const char *propn /********************* ColorPicker Template ************************/ -#define WHEEL_SIZE 100 +#define WHEEL_SIZE (5*U.widget_unit) /* This template now follows User Preference for type - name is not correct anymore... */ void uiTemplateColorPicker(uiLayout *layout, PointerRNA *ptr, const char *propname, int value_slider, diff --git a/source/blender/editors/interface/interface_widgets.c b/source/blender/editors/interface/interface_widgets.c index c4b80f0a42f..77fbe940c4a 100644 --- a/source/blender/editors/interface/interface_widgets.c +++ b/source/blender/editors/interface/interface_widgets.c @@ -333,10 +333,10 @@ static void round_box__edges(uiWidgetBase *wt, int roundboxalign, rcti *rect, fl { float vec[WIDGET_CURVE_RESOLU][2], veci[WIDGET_CURVE_RESOLU][2]; float minx = rect->xmin, miny = rect->ymin, maxx = rect->xmax, maxy = rect->ymax; - float minxi = minx + 1.0f; /* boundbox inner */ - float maxxi = maxx - 1.0f; - float minyi = miny + 1.0f; - float maxyi = maxy - 1.0f; + float minxi = minx + U.pixelsize; /* boundbox inner */ + float maxxi = maxx - U.pixelsize; + float minyi = miny + U.pixelsize; + float maxyi = maxy - U.pixelsize; float facxi = (maxxi != minxi) ? 1.0f / (maxxi - minxi) : 0.0f; /* for uv, can divide by zero */ float facyi = (maxyi != minyi) ? 1.0f / (maxyi - minyi) : 0.0f; int a, tot = 0, minsize; @@ -352,7 +352,7 @@ static void round_box__edges(uiWidgetBase *wt, int roundboxalign, rcti *rect, fl rad = 0.5f * minsize; if (2.0f * (radi + 1.0f) > minsize) - radi = 0.5f * minsize - 1.0f; + radi = 0.5f * minsize - U.pixelsize; /* mult */ for (a = 0; a < WIDGET_CURVE_RESOLU; a++) { @@ -481,7 +481,7 @@ static void round_box__edges(uiWidgetBase *wt, int roundboxalign, rcti *rect, fl static void round_box_edges(uiWidgetBase *wt, int roundboxalign, rcti *rect, float rad) { - round_box__edges(wt, roundboxalign, rect, rad, rad - 1.0f); + round_box__edges(wt, roundboxalign, rect, rad, rad - U.pixelsize); } @@ -863,7 +863,7 @@ static int ui_but_draw_menu_icon(uiBut *but) static void widget_draw_icon(uiBut *but, BIFIconID icon, float alpha, rcti *rect) { - int xs = 0, ys = 0; + float xs = 0.0f, ys = 0.0f; float aspect, height; if (but->flag & UI_ICON_PREVIEW) { @@ -874,21 +874,13 @@ static void widget_draw_icon(uiBut *but, BIFIconID icon, float alpha, rcti *rect /* this icon doesn't need draw... */ if (icon == ICON_BLANK1 && (but->flag & UI_ICON_SUBMENU) == 0) return; - /* we need aspect from block, for menus... these buttons are scaled in uiPositionBlock() */ - aspect = but->block->aspect; - if (aspect != but->aspect) { - /* prevent scaling up icon in pupmenu */ - if (aspect < 1.0f) { - height = UI_DPI_ICON_SIZE; - aspect = 1.0f; - - } - else - height = UI_DPI_ICON_SIZE / aspect; - } - else - height = UI_DPI_ICON_SIZE; - + /* XXX remove hack when new icons are made */ + if ( icon == ICON_LAYER_ACTIVE || icon == ICON_LAYER_USED) + height = 1.2f * BLI_rcti_size_y(rect); else + /* icons are 80% of height of button (16 pixels inside 20 height) */ + height = 0.8f * BLI_rcti_size_y(rect); + aspect = height / ICON_DEFAULT_HEIGHT; + /* calculate blend color */ if (ELEM4(but->type, TOG, ROW, TOGN, LISTROW)) { if (but->flag & UI_SELECT) {} @@ -905,45 +897,45 @@ static void widget_draw_icon(uiBut *but, BIFIconID icon, float alpha, rcti *rect if (but->flag & UI_ICON_LEFT) { if (but->type == BUT_TOGDUAL) { if (but->drawstr[0]) { - xs = rect->xmin - 1; + xs = rect->xmin - 1.0f * aspect; } else { - xs = (rect->xmin + rect->xmax - height) / 2; + xs = (rect->xmin + rect->xmax - height) / 2.0f; } } else if (but->block->flag & UI_BLOCK_LOOP) { if (but->type == SEARCH_MENU) - xs = rect->xmin + 4; + xs = rect->xmin + 4.0f * aspect; else - xs = rect->xmin + 1; + xs = rect->xmin + 1.0f * aspect; } else if ((but->type == ICONROW) || (but->type == ICONTEXTROW)) { - xs = rect->xmin + 3; + xs = rect->xmin + 3.0f * aspect; } else { - xs = rect->xmin + 4; + xs = rect->xmin + 4.0f * aspect; } - ys = (rect->ymin + rect->ymax - height) / 2; + ys = (rect->ymin + rect->ymax - height) / 2.0f; } else { - xs = (rect->xmin + rect->xmax - height) / 2; - ys = (rect->ymin + rect->ymax - height) / 2; + xs = (rect->xmin + rect->xmax - height) / 2.0f; + ys = (rect->ymin + rect->ymax - height) / 2.0f; } - + /* to indicate draggable */ if (but->dragpoin && (but->flag & UI_ACTIVE)) { float rgb[3] = {1.25f, 1.25f, 1.25f}; - UI_icon_draw_aspect_color(xs, ys, icon, aspect, rgb); + UI_icon_draw_aspect_color(xs, ys, icon, 1.0f / aspect, rgb); } else - UI_icon_draw_aspect(xs, ys, icon, aspect, alpha); + UI_icon_draw_aspect(xs, ys, icon, 1.0f / aspect, alpha); } if (ui_but_draw_menu_icon(but)) { - xs = rect->xmax - UI_DPI_ICON_SIZE - 1; - ys = (rect->ymin + rect->ymax - height) / 2; + xs = rect->xmax - UI_DPI_ICON_SIZE - aspect; + ys = (rect->ymin + rect->ymax - height) / 2.0f; - UI_icon_draw_aspect(xs, ys, ICON_RIGHTARROW_THIN, aspect, alpha); + UI_icon_draw_aspect(xs, ys, ICON_RIGHTARROW_THIN, 1.0f / aspect, alpha); } glDisable(GL_BLEND); @@ -1329,14 +1321,15 @@ static void widget_draw_text_icon(uiFontStyle *fstyle, uiWidgetColors *wcol, uiB if (but->flag & UI_HAS_ICON) { widget_draw_icon(but, but->icon + but->iconadd, 1.0f, rect); - - rect->xmin += (int)((float)UI_icon_get_width(but->icon + but->iconadd) * UI_DPI_ICON_FAC); + + /* icons default draw 0.8f x height */ + rect->xmin += (int)(0.8f * BLI_rcti_size_y(rect)); if (but->editstr || (but->flag & UI_TEXT_LEFT)) - rect->xmin += 5; + rect->xmin += 0.4f * U.widget_unit; } else if ((but->flag & UI_TEXT_LEFT)) - rect->xmin += 5; + rect->xmin += 0.4f * U.widget_unit; /* always draw text for textbutton cursor */ widget_draw_text(fstyle, wcol, but, rect); @@ -1816,17 +1809,20 @@ static void widget_softshadow(rcti *rect, int roundboxalign, float radin, float float quad_strip[WIDGET_SIZE_MAX * 2][2]; /* prevent tooltips to not show round shadow */ - if (2.0f * radout > 0.2f * BLI_rcti_size_y(&rect1)) + if (radout > 0.2f * BLI_rcti_size_y(&rect1)) rect1.ymax -= 0.2f * BLI_rcti_size_y(&rect1); else - rect1.ymax -= 2.0f * radout; + rect1.ymax -= radout; /* inner part */ totvert = round_box_shadow_edges(wtb.inner_v, &rect1, radin, roundboxalign & (UI_CNR_BOTTOM_RIGHT | UI_CNR_BOTTOM_LEFT), 0.0f); /* inverse linear shadow alpha */ - alpha = 0.15; - alphastep = 0.67; + alpha = 0.15f; + if (U.pixelsize > 1.0f) + alphastep = 0.78f; + else + alphastep = 0.67f; glEnableClientState(GL_VERTEX_ARRAY); @@ -1858,17 +1854,17 @@ static void widget_menu_back(uiWidgetColors *wcol, rcti *rect, int flag, int dir } else if (direction == UI_DOWN) { roundboxalign = (UI_CNR_BOTTOM_RIGHT | UI_CNR_BOTTOM_LEFT); - rect->ymin -= 4.0; + rect->ymin -= 0.1f * U.widget_unit; } else if (direction == UI_TOP) { roundboxalign = UI_CNR_TOP_LEFT | UI_CNR_TOP_RIGHT; - rect->ymax += 4.0; + rect->ymax += 0.1f * U.widget_unit; } glEnable(GL_BLEND); - widget_softshadow(rect, roundboxalign, 5.0f, 8.0f); + widget_softshadow(rect, roundboxalign, 0.25f * U.widget_unit, 0.4f * U.widget_unit); - round_box_edges(&wtb, roundboxalign, rect, 5.0f); + round_box_edges(&wtb, roundboxalign, rect, 0.25f * U.widget_unit); wtb.emboss = 0; widgetbase_draw(&wtb, wcol); @@ -2540,14 +2536,15 @@ static void widget_numslider(uiBut *but, uiWidgetColors *wcol, rcti *rect, int s fac = ((float)value - but->softmin) * (BLI_rcti_size_x(&rect1) - offs) / (but->softmax - but->softmin); /* left part of slider, always rounded */ - rect1.xmax = rect1.xmin + ceil(offs + 1.0f); + rect1.xmax = rect1.xmin + ceil(offs + U.pixelsize); round_box_edges(&wtb1, roundboxalign & ~(UI_CNR_TOP_RIGHT | UI_CNR_BOTTOM_RIGHT), &rect1, offs); wtb1.outline = 0; widgetbase_draw(&wtb1, wcol); /* right part of slider, interpolate roundness */ rect1.xmax = rect1.xmin + fac + offs; - rect1.xmin += floor(offs - 1.0f); + rect1.xmin += floor(offs - U.pixelsize); + if (rect1.xmax + offs > rect->xmax) offs *= (rect1.xmax + offs - rect->xmax) / offs; else @@ -2577,7 +2574,7 @@ static void widget_numslider(uiBut *but, uiWidgetColors *wcol, rcti *rect, int s static void widget_swatch(uiBut *but, uiWidgetColors *wcol, rcti *rect, int state, int roundboxalign) { uiWidgetBase wtb; - float col[4]; + float rad, col[4]; int color_profile = but->block->color_profile; col[3] = 1.0f; @@ -2594,7 +2591,8 @@ static void widget_swatch(uiBut *but, uiWidgetColors *wcol, rcti *rect, int stat widget_init(&wtb); /* half rounded */ - round_box_edges(&wtb, roundboxalign, rect, 5.0f); + rad = 0.25f * U.widget_unit; + round_box_edges(&wtb, roundboxalign, rect, rad); ui_get_but_vectorf(but, col); @@ -2608,7 +2606,7 @@ static void widget_swatch(uiBut *but, uiWidgetColors *wcol, rcti *rect, int stat rect->ymin += SWATCH_KEYED_BORDER; rect->ymax -= SWATCH_KEYED_BORDER; - round_box_edges(&wtb, roundboxalign, rect, 5.0f); + round_box_edges(&wtb, roundboxalign, rect, rad); } if (color_profile) @@ -2632,12 +2630,14 @@ static void widget_icon_has_anim(uiBut *UNUSED(but), uiWidgetColors *wcol, rcti { if (state & (UI_BUT_ANIMATED | UI_BUT_ANIMATED_KEY | UI_BUT_DRIVEN | UI_BUT_REDALERT)) { uiWidgetBase wtb; - + float rad; + widget_init(&wtb); wtb.outline = 0; /* rounded */ - round_box_edges(&wtb, UI_CNR_ALL, rect, 10.0f); + rad = 0.5f * BLI_rcti_size_y(rect); + round_box_edges(&wtb, UI_CNR_ALL, rect, rad); widgetbase_draw(&wtb, wcol); } } @@ -2646,6 +2646,7 @@ static void widget_icon_has_anim(uiBut *UNUSED(but), uiWidgetColors *wcol, rcti static void widget_textbut(uiWidgetColors *wcol, rcti *rect, int state, int roundboxalign) { uiWidgetBase wtb; + float rad; if (state & UI_SELECT) SWAP(short, wcol->shadetop, wcol->shadedown); @@ -2653,7 +2654,8 @@ static void widget_textbut(uiWidgetColors *wcol, rcti *rect, int state, int roun widget_init(&wtb); /* half rounded */ - round_box_edges(&wtb, roundboxalign, rect, 4.0f); + rad = 0.2f * U.widget_unit; + round_box_edges(&wtb, roundboxalign, rect, rad); widgetbase_draw(&wtb, wcol); @@ -2663,11 +2665,13 @@ static void widget_textbut(uiWidgetColors *wcol, rcti *rect, int state, int roun static void widget_menubut(uiWidgetColors *wcol, rcti *rect, int UNUSED(state), int roundboxalign) { uiWidgetBase wtb; + float rad; widget_init(&wtb); /* half rounded */ - round_box_edges(&wtb, roundboxalign, rect, 4.0f); + rad = 0.2f * U.widget_unit; + round_box_edges(&wtb, roundboxalign, rect, rad); /* decoration */ widget_menu_trias(&wtb.tria1, rect); @@ -2681,11 +2685,13 @@ static void widget_menubut(uiWidgetColors *wcol, rcti *rect, int UNUSED(state), static void widget_menuiconbut(uiWidgetColors *wcol, rcti *rect, int UNUSED(state), int roundboxalign) { uiWidgetBase wtb; + float rad; widget_init(&wtb); /* half rounded */ - round_box_edges(&wtb, roundboxalign, rect, 4.0f); + rad = 0.2f * U.widget_unit; + round_box_edges(&wtb, roundboxalign, rect, rad); /* decoration */ widgetbase_draw(&wtb, wcol); @@ -2696,11 +2702,13 @@ static void widget_menunodebut(uiWidgetColors *wcol, rcti *rect, int UNUSED(stat /* silly node link button hacks */ uiWidgetBase wtb; uiWidgetColors wcol_backup = *wcol; + float rad; widget_init(&wtb); /* half rounded */ - round_box_edges(&wtb, roundboxalign, rect, 4.0f); + rad = 0.2f * U.widget_unit; + round_box_edges(&wtb, roundboxalign, rect, rad); wcol->inner[0] += 15; wcol->inner[1] += 15; @@ -2718,7 +2726,7 @@ static void widget_pulldownbut(uiWidgetColors *wcol, rcti *rect, int state, int { if (state & UI_ACTIVE) { uiWidgetBase wtb; - float rad = 0.25f * BLI_rcti_size_y(rect); /* 4.0f */ + float rad = 0.2f * U.widget_unit; widget_init(&wtb); @@ -2745,12 +2753,14 @@ static void widget_menu_itembut(uiWidgetColors *wcol, rcti *rect, int UNUSED(sta static void widget_list_itembut(uiWidgetColors *wcol, rcti *rect, int UNUSED(state), int UNUSED(roundboxalign)) { uiWidgetBase wtb; + float rad; widget_init(&wtb); /* rounded, but no outline */ wtb.outline = 0; - round_box_edges(&wtb, UI_CNR_ALL, rect, 4.0f); + rad = 0.2f * U.widget_unit; + round_box_edges(&wtb, UI_CNR_ALL, rect, rad); widgetbase_draw(&wtb, wcol); } @@ -2759,6 +2769,7 @@ static void widget_optionbut(uiWidgetColors *wcol, rcti *rect, int state, int UN { uiWidgetBase wtb; rcti recttemp = *rect; + float rad; int delta; widget_init(&wtb); @@ -2774,7 +2785,8 @@ static void widget_optionbut(uiWidgetColors *wcol, rcti *rect, int state, int UN recttemp.ymax -= delta; /* half rounded */ - round_box_edges(&wtb, UI_CNR_ALL, &recttemp, 4.0f); + rad = 0.2f * U.widget_unit; + round_box_edges(&wtb, UI_CNR_ALL, &recttemp, rad); /* decoration */ if (state & UI_SELECT) { @@ -2791,11 +2803,13 @@ static void widget_optionbut(uiWidgetColors *wcol, rcti *rect, int state, int UN static void widget_radiobut(uiWidgetColors *wcol, rcti *rect, int UNUSED(state), int roundboxalign) { uiWidgetBase wtb; + float rad; widget_init(&wtb); /* half rounded */ - round_box_edges(&wtb, roundboxalign, rect, 4.0f); + rad = 0.2f * U.widget_unit; + round_box_edges(&wtb, roundboxalign, rect, rad); widgetbase_draw(&wtb, wcol); @@ -2804,6 +2818,7 @@ static void widget_radiobut(uiWidgetColors *wcol, rcti *rect, int UNUSED(state), static void widget_box(uiBut *but, uiWidgetColors *wcol, rcti *rect, int UNUSED(state), int roundboxalign) { uiWidgetBase wtb; + float rad; char old_col[3]; widget_init(&wtb); @@ -2818,7 +2833,8 @@ static void widget_box(uiBut *but, uiWidgetColors *wcol, rcti *rect, int UNUSED( } /* half rounded */ - round_box_edges(&wtb, roundboxalign, rect, 4.0f); + rad = 0.2f * U.widget_unit; + round_box_edges(&wtb, roundboxalign, rect, rad); widgetbase_draw(&wtb, wcol); @@ -2833,12 +2849,14 @@ static void widget_box(uiBut *but, uiWidgetColors *wcol, rcti *rect, int UNUSED( static void widget_but(uiWidgetColors *wcol, rcti *rect, int UNUSED(state), int roundboxalign) { uiWidgetBase wtb; + float rad; widget_init(&wtb); /* half rounded */ - round_box_edges(&wtb, roundboxalign, rect, 4.0f); - + rad = 0.2f * U.widget_unit; + round_box_edges(&wtb, roundboxalign, rect, rad); + widgetbase_draw(&wtb, wcol); } @@ -2846,7 +2864,7 @@ static void widget_but(uiWidgetColors *wcol, rcti *rect, int UNUSED(state), int static void widget_roundbut(uiWidgetColors *wcol, rcti *rect, int UNUSED(state), int roundboxalign) { uiWidgetBase wtb; - float rad = 5.0f; /* 0.5f * BLI_rcti_size_y(rect); */ + float rad = 0.25f * U.widget_unit; widget_init(&wtb); @@ -2859,6 +2877,7 @@ static void widget_roundbut(uiWidgetColors *wcol, rcti *rect, int UNUSED(state), static void widget_draw_extra_mask(const bContext *C, uiBut *but, uiWidgetType *wt, rcti *rect) { uiWidgetBase wtb; + float rad = 0.25f * U.widget_unit; unsigned char col[4]; /* state copy! */ @@ -2874,12 +2893,12 @@ static void widget_draw_extra_mask(const bContext *C, uiBut *but, uiWidgetType * UI_GetThemeColor3ubv(TH_BACK, col); glColor3ubv(col); - round_box__edges(&wtb, UI_CNR_ALL, rect, 0.0f, 4.0); + round_box__edges(&wtb, UI_CNR_ALL, rect, 0.0f, rad); widgetbase_outline(&wtb); } /* outline */ - round_box_edges(&wtb, UI_CNR_ALL, rect, 5.0f); + round_box_edges(&wtb, UI_CNR_ALL, rect, rad); wtb.outline = 1; wtb.inner = 0; widgetbase_draw(&wtb, &wt->wcol); @@ -3068,9 +3087,9 @@ static int widget_roundbox_set(uiBut *but, rcti *rect) /* ui_block_position has this correction too, keep in sync */ if (but->flag & UI_BUT_ALIGN_TOP) - rect->ymax += 1; + rect->ymax += U.pixelsize; if (but->flag & UI_BUT_ALIGN_LEFT) - rect->xmin -= 1; + rect->xmin -= U.pixelsize; switch (but->flag & UI_BUT_ALIGN) { case UI_BUT_ALIGN_TOP: @@ -3381,7 +3400,7 @@ void ui_draw_search_back(uiStyle *UNUSED(style), uiBlock *block, rcti *rect) uiWidgetType *wt = widget_type(UI_WTYPE_BOX); glEnable(GL_BLEND); - widget_softshadow(rect, UI_CNR_ALL, 5.0f, 8.0f); + widget_softshadow(rect, UI_CNR_ALL, 0.25f * U.widget_unit, 0.4f * U.widget_unit); glDisable(GL_BLEND); wt->state(wt, 0); @@ -3408,7 +3427,7 @@ void ui_draw_menu_item(uiFontStyle *fstyle, rcti *rect, const char *name, int ic fstyle->align = UI_STYLE_TEXT_LEFT; /* text location offset */ - rect->xmin += 5; + rect->xmin += 0.25f * UI_UNIT_X; if (iconid) rect->xmin += UI_DPI_ICON_SIZE; /* cut string in 2 parts? */ @@ -3433,10 +3452,16 @@ void ui_draw_menu_item(uiFontStyle *fstyle, rcti *rect, const char *name, int ic *rect = _rect; if (iconid) { - int xs = rect->xmin + 4; + float height, aspect; + int xs = rect->xmin + 0.2f * UI_UNIT_X; int ys = 1 + (rect->ymin + rect->ymax - UI_DPI_ICON_SIZE) / 2; + + /* icons are 80% of height of button (16 pixels inside 20 height) */ + height = 0.8f * BLI_rcti_size_y(rect); + aspect = ICON_DEFAULT_HEIGHT / height; + glEnable(GL_BLEND); - UI_icon_draw_aspect(xs, ys, iconid, 1.2f, 0.5f); /* XXX scale weak get from fstyle? */ + UI_icon_draw_aspect(xs, ys, iconid, aspect, 0.5f); /* XXX scale weak get from fstyle? */ glDisable(GL_BLEND); } } diff --git a/source/blender/editors/interface/resources.c b/source/blender/editors/interface/resources.c index fa5d5806bb8..3a482b97d37 100644 --- a/source/blender/editors/interface/resources.c +++ b/source/blender/editors/interface/resources.c @@ -1990,7 +1990,7 @@ void init_userdef_do_versions(void) if (U.dragthreshold == 0) U.dragthreshold = 5; if (U.widget_unit == 0) - U.widget_unit = (U.dpi * 20 + 36) / 72; + U.widget_unit = 20; if (U.anisotropic_filter <= 0) U.anisotropic_filter = 1; @@ -2009,6 +2009,23 @@ void init_userdef_do_versions(void) if (U.tweak_threshold == 0) U.tweak_threshold = 10; + if (bmain->versionfile < 265) { /* XXX fix for when you apply */ + bTheme *btheme; + + for (btheme = U.themes.first; btheme; btheme = btheme->next) { + /* note: the toggle operator for transparent backdrops limits to these spacetypes */ + if (btheme->tnode.button[3] == 255) { + btheme->tv3d.button[3] = 128; + btheme->tnode.button[3] = 128; + btheme->tima.button[3] = 128; + btheme->tseq.button[3] = 128; + btheme->tclip.button[3] = 128; + } + } + } + if (U.pixelsize == 0.0f) + U.pixelsize = 1.0f; + /* funny name, but it is GE stuff, moves userdef stuff to engine */ // XXX space_set_commmandline_options(); /* this timer uses U */ diff --git a/source/blender/editors/interface/view2d.c b/source/blender/editors/interface/view2d.c index f1a3f59bc22..356b5a687ff 100644 --- a/source/blender/editors/interface/view2d.c +++ b/source/blender/editors/interface/view2d.c @@ -1150,7 +1150,7 @@ View2DGrid *UI_view2d_grid_calc(Scene *scene, View2D *v2d, pixels = (float)BLI_rcti_size_x(&v2d->mask); if (pixels != 0.0f) { - grid->dx = (U.v2d_min_gridsize * space) / (seconddiv * pixels); + grid->dx = (U.v2d_min_gridsize * U.pixelsize * space) / (seconddiv * pixels); step_to_grid(&grid->dx, &grid->powerx, xunits); grid->dx *= seconddiv; } @@ -1167,7 +1167,7 @@ View2DGrid *UI_view2d_grid_calc(Scene *scene, View2D *v2d, space = BLI_rctf_size_y(&v2d->cur); pixels = (float)winy; - grid->dy = U.v2d_min_gridsize * space / pixels; + grid->dy = U.v2d_min_gridsize * U.pixelsize * space / pixels; step_to_grid(&grid->dy, &grid->powery, yunits); if (yclamp == V2D_GRID_CLAMP) { @@ -1212,7 +1212,7 @@ void UI_view2d_grid_draw(View2D *v2d, View2DGrid *grid, int flag) vec2[1] = v2d->cur.ymax; /* minor gridlines */ - step = (BLI_rcti_size_x(&v2d->mask) + 1) / U.v2d_min_gridsize; + step = (BLI_rcti_size_x(&v2d->mask) + 1) / (U.v2d_min_gridsize * U.pixelsize); UI_ThemeColor(TH_GRID); for (a = 0; a < step; a++) { @@ -1246,7 +1246,7 @@ void UI_view2d_grid_draw(View2D *v2d, View2DGrid *grid, int flag) vec1[0] = grid->startx; vec2[0] = v2d->cur.xmax; - step = (BLI_rcti_size_y(&v2d->mask) + 1) / U.v2d_min_gridsize; + step = (BLI_rcti_size_y(&v2d->mask) + 1) / (U.v2d_min_gridsize * U.pixelsize); UI_ThemeColor(TH_GRID); for (a = 0; a <= step; a++) { @@ -1427,6 +1427,7 @@ View2DScrollers *UI_view2d_scrollers_calc(const bContext *C, View2D *v2d, rcti vert, hor; float fac1, fac2, totsize, scrollsize; int scroll = view2d_scroll_mapped(v2d->scroll); + int smaller; /* scrollers is allocated here... */ scrollers = MEM_callocN(sizeof(View2DScrollers), "View2DScrollers"); @@ -1435,19 +1436,20 @@ View2DScrollers *UI_view2d_scrollers_calc(const bContext *C, View2D *v2d, hor = v2d->hor; /* slider rects need to be smaller than region */ - hor.xmin += 4; - hor.xmax -= 4; + smaller = (int)(0.2f * U.widget_unit); + hor.xmin += smaller; + hor.xmax -= smaller; if (scroll & V2D_SCROLL_BOTTOM) - hor.ymin += 4; + hor.ymin += smaller; else - hor.ymax -= 4; + hor.ymax -= smaller; if (scroll & V2D_SCROLL_LEFT) - vert.xmin += 4; + vert.xmin += smaller; else - vert.xmax -= 4; - vert.ymin += 4; - vert.ymax -= 4; + vert.xmax -= smaller; + vert.ymin += smaller; + vert.ymax -= smaller; CLAMP(vert.ymin, vert.ymin, vert.ymax - V2D_SCROLLER_HANDLE_SIZE); CLAMP(hor.xmin, hor.xmin, hor.xmax - V2D_SCROLLER_HANDLE_SIZE); @@ -1621,6 +1623,7 @@ void UI_view2d_scrollers_draw(const bContext *C, View2D *v2d, View2DScrollers *v uiWidgetColors wcol = btheme->tui.wcol_scroll; rcti slider; int state; + unsigned char col[4]; slider.xmin = vs->hor_min; slider.xmax = vs->hor_max; @@ -1643,8 +1646,12 @@ void UI_view2d_scrollers_draw(const bContext *C, View2D *v2d, View2DScrollers *v state |= UI_SCROLL_ARROWS; } - UI_ThemeColor(TH_BACK); - glRecti(v2d->hor.xmin, v2d->hor.ymin, v2d->hor.xmax, v2d->hor.ymax); + /* clean rect behind slider, but not with transparent background */ + UI_GetThemeColor4ubv(TH_BACK, col); + if (col[3] == 255) { + glColor3ub(col[0], col[1],col[2]); + glRecti(v2d->hor.xmin, v2d->hor.ymin, v2d->hor.xmax, v2d->hor.ymax); + } uiWidgetScrollDraw(&wcol, &hor, &slider, state); } @@ -1680,12 +1687,12 @@ void UI_view2d_scrollers_draw(const bContext *C, View2D *v2d, View2DScrollers *v /* draw numbers in the appropriate range */ if (dfac > 0.0f) { - float h = 2.0f + (float)(hor.ymin); + float h = 0.1f*UI_UNIT_Y + (float)(hor.ymin); - for (; fac < hor.xmax - 10; fac += dfac, val += grid->dx) { + for (; fac < hor.xmax - 0.5f * U.widget_unit; fac += dfac, val += grid->dx) { /* make prints look nicer for scrollers */ - if (fac < hor.xmin + 10) + if (fac < hor.xmin + 0.5f * U.widget_unit) continue; switch (vs->xunits) { @@ -1732,6 +1739,7 @@ void UI_view2d_scrollers_draw(const bContext *C, View2D *v2d, View2DScrollers *v uiWidgetColors wcol = btheme->tui.wcol_scroll; rcti slider; int state; + unsigned char col[4]; slider.xmin = vert.xmin; slider.xmax = vert.xmax; @@ -1753,9 +1761,13 @@ void UI_view2d_scrollers_draw(const bContext *C, View2D *v2d, View2DScrollers *v { state |= UI_SCROLL_ARROWS; } - - UI_ThemeColor(TH_BACK); - glRecti(v2d->vert.xmin, v2d->vert.ymin, v2d->vert.xmax, v2d->vert.ymax); + + /* clean rect behind slider, but not with transparent background */ + UI_GetThemeColor4ubv(TH_BACK, col); + if (col[3] == 255) { + glColor3ub(col[0], col[1],col[2]); + glRecti(v2d->vert.xmin, v2d->vert.ymin, v2d->vert.xmax, v2d->vert.ymax); + } uiWidgetScrollDraw(&wcol, &vert, &slider, state); } diff --git a/source/blender/editors/screen/area.c b/source/blender/editors/screen/area.c index f30e0abb4f3..852ce02fa40 100644 --- a/source/blender/editors/screen/area.c +++ b/source/blender/editors/screen/area.c @@ -235,8 +235,8 @@ static void region_draw_azone_icon(AZone *az) static void draw_azone_plus(float x1, float y1, float x2, float y2) { - float width = 2.0f; - float pad = 4.0f; + float width = 0.05f * U.widget_unit; + float pad = 0.2f * U.widget_unit; glRectf((x1 + x2 - width) * 0.5f, y1 + pad, (x1 + x2 + width) * 0.5f, y2 - pad); glRectf(x1 + pad, (y1 + y2 - width) * 0.5f, (x1 + x2 - width) * 0.5f, (y1 + y2 + width) * 0.5f); @@ -395,47 +395,14 @@ void ED_area_overdraw(bContext *C) } -/* get scissor rect, checking overlapping regions */ -void region_scissor_winrct(ARegion *ar, rcti *winrct) -{ - *winrct = ar->winrct; - - if (ELEM(ar->alignment, RGN_OVERLAP_LEFT, RGN_OVERLAP_RIGHT)) - return; - - while (ar->prev) { - ar = ar->prev; - - if (BLI_rcti_isect(winrct, &ar->winrct, NULL)) { - if (ar->flag & RGN_FLAG_HIDDEN) { - /* pass */ - } - else if (ar->alignment & RGN_SPLIT_PREV) { - /* pass */ - } - else if (ar->alignment == RGN_OVERLAP_LEFT) { - winrct->xmin = ar->winrct.xmax + 1; - } - else if (ar->alignment == RGN_OVERLAP_RIGHT) { - winrct->xmax = ar->winrct.xmin - 1; - } - else break; - } - } -} - /* only exported for WM */ /* makes region ready for drawing, sets pixelspace */ void ED_region_set(const bContext *C, ARegion *ar) { wmWindow *win = CTX_wm_window(C); ScrArea *sa = CTX_wm_area(C); - rcti winrct; - /* checks other overlapping regions */ - region_scissor_winrct(ar, &winrct); - - ar->drawrct = winrct; + ar->drawrct = ar->winrct; /* note; this sets state, so we can use wmOrtho and friends */ wmSubWindowScissorSet(win, ar->swinid, &ar->drawrct); @@ -452,24 +419,20 @@ void ED_region_do_draw(bContext *C, ARegion *ar) wmWindow *win = CTX_wm_window(C); ScrArea *sa = CTX_wm_area(C); ARegionType *at = ar->type; - rcti winrct; /* see BKE_spacedata_draw_locks() */ if (at->do_lock) return; - /* checks other overlapping regions */ - region_scissor_winrct(ar, &winrct); - /* if no partial draw rect set, full rect */ if (ar->drawrct.xmin == ar->drawrct.xmax) - ar->drawrct = winrct; + ar->drawrct = ar->winrct; else { /* extra clip for safety (intersect the rects, could use API func) */ - ar->drawrct.xmin = max_ii(winrct.xmin, ar->drawrct.xmin); - ar->drawrct.ymin = max_ii(winrct.ymin, ar->drawrct.ymin); - ar->drawrct.xmax = min_ii(winrct.xmax, ar->drawrct.xmax); - ar->drawrct.ymax = min_ii(winrct.ymax, ar->drawrct.ymax); + ar->drawrct.xmin = max_ii(ar->winrct.xmin, ar->drawrct.xmin); + ar->drawrct.ymin = max_ii(ar->winrct.ymin, ar->drawrct.ymin); + ar->drawrct.xmax = min_ii(ar->winrct.xmax, ar->drawrct.xmax); + ar->drawrct.ymax = min_ii(ar->winrct.ymax, ar->drawrct.ymax); } /* note; this sets state, so we can use wmOrtho and friends */ @@ -500,7 +463,7 @@ void ED_region_do_draw(bContext *C, ARegion *ar) uiFreeInactiveBlocks(C, &ar->uiblocks); if (sa) - region_draw_emboss(ar, &winrct); + region_draw_emboss(ar, &ar->winrct); } /* ********************************** @@ -627,8 +590,8 @@ static void area_azone_initialize(bScreen *screen, ScrArea *sa) BLI_rcti_init(&az->rect, az->x1, az->x2, az->y1, az->y2); } -#define AZONEPAD_EDGE 4 -#define AZONEPAD_ICON 9 +#define AZONEPAD_EDGE (0.2f * U.widget_unit) +#define AZONEPAD_ICON (0.45f * U.widget_unit) static void region_azone_edge(AZone *az, ARegion *ar) { switch (az->edge) { @@ -720,8 +683,8 @@ static void region_azone_icon(ScrArea *sa, AZone *az, ARegion *ar) } } -#define AZONEPAD_TAB_PLUSW 14 -#define AZONEPAD_TAB_PLUSH 14 +#define AZONEPAD_TAB_PLUSW (0.7f * U.widget_unit) +#define AZONEPAD_TAB_PLUSH (0.7f * U.widget_unit) /* region already made zero sized, in shape of edge */ static void region_azone_tab_plus(ScrArea *sa, AZone *az, ARegion *ar) @@ -765,8 +728,8 @@ static void region_azone_tab_plus(ScrArea *sa, AZone *az, ARegion *ar) } -#define AZONEPAD_TABW 18 -#define AZONEPAD_TABH 7 +#define AZONEPAD_TABW (0.9f * U.widget_unit) +#define AZONEPAD_TABH (0.35f * U.widget_unit) /* region already made zero sized, in shape of edge */ static void region_azone_tab(ScrArea *sa, AZone *az, ARegion *ar) @@ -809,8 +772,8 @@ static void region_azone_tab(ScrArea *sa, AZone *az, ARegion *ar) BLI_rcti_init(&az->rect, az->x1, az->x2, az->y1, az->y2); } -#define AZONEPAD_TRIAW 16 -#define AZONEPAD_TRIAH 9 +#define AZONEPAD_TRIAW (0.8f * U.widget_unit) +#define AZONEPAD_TRIAH (0.45f * U.widget_unit) /* region already made zero sized, in shape of edge */ @@ -892,9 +855,9 @@ static void region_azone_add(ScrArea *sa, ARegion *ar, int alignment) region_azone_initialize(sa, ar, AE_BOTTOM_TO_TOPLEFT); else if (alignment == RGN_ALIGN_BOTTOM) region_azone_initialize(sa, ar, AE_TOP_TO_BOTTOMRIGHT); - else if (ELEM(alignment, RGN_ALIGN_RIGHT, RGN_OVERLAP_RIGHT)) + else if (alignment == RGN_ALIGN_RIGHT) region_azone_initialize(sa, ar, AE_LEFT_TO_TOPRIGHT); - else if (ELEM(alignment, RGN_ALIGN_LEFT, RGN_OVERLAP_LEFT)) + else if (alignment == RGN_ALIGN_LEFT) region_azone_initialize(sa, ar, AE_RIGHT_TO_TOPLEFT); } @@ -909,7 +872,20 @@ static int rct_fits(rcti *rect, char dir, int size) } } -static void region_rect_recursive(ScrArea *sa, ARegion *ar, rcti *remainder, int quad) +/* *************************************************************** */ + +/* overlapping regions only in the following restricted cases */ +static int region_is_overlap(wmWindow *win, ScrArea *sa, ARegion *ar) +{ + if (U.uiflag2 & USER_REGION_OVERLAP) + if (WM_is_draw_triple(win)) + if (ELEM5(sa->spacetype, SPACE_VIEW3D, SPACE_IMAGE, SPACE_SEQ, SPACE_CLIP, SPACE_NODE)) + if (ELEM3(ar->regiontype, RGN_TYPE_TOOLS, RGN_TYPE_UI, RGN_TYPE_TOOL_PROPS)) + return 1; + return 0; +} + +static void region_rect_recursive(wmWindow *win, ScrArea *sa, ARegion *ar, rcti *remainder, int quad) { rcti *remainder_prev = remainder; int prefsizex, prefsizey; @@ -928,6 +904,9 @@ static void region_rect_recursive(ScrArea *sa, ARegion *ar, rcti *remainder, int alignment = ar->alignment & ~RGN_SPLIT_PREV; + /* set here, assuming userpref switching forces to call this again */ + ar->overlap = region_is_overlap(win, sa, ar); + /* clear state flags first */ ar->flag &= ~RGN_FLAG_TOO_SMALL; /* user errors */ @@ -935,15 +914,15 @@ static void region_rect_recursive(ScrArea *sa, ARegion *ar, rcti *remainder, int alignment = RGN_ALIGN_NONE; /* prefsize, for header we stick to exception */ - prefsizex = ar->sizex ? ar->sizex : ar->type->prefsizex; + prefsizex = ar->sizex ? ar->sizex : UI_DPI_FAC * ar->type->prefsizex; if (ar->regiontype == RGN_TYPE_HEADER) { - prefsizey = ar->type->prefsizey; + prefsizey = ED_area_headersize(); } else if (ar->regiontype == RGN_TYPE_UI && sa->spacetype == SPACE_FILE) { prefsizey = UI_UNIT_Y * 2 + (UI_UNIT_Y / 2); } else { - prefsizey = ar->sizey ? ar->sizey : ar->type->prefsizey; + prefsizey = ar->sizey ? ar->sizey : UI_DPI_FAC * ar->type->prefsizey; } @@ -985,7 +964,7 @@ static void region_rect_recursive(ScrArea *sa, ARegion *ar, rcti *remainder, int } } } - else if (ELEM4(alignment, RGN_ALIGN_LEFT, RGN_ALIGN_RIGHT, RGN_OVERLAP_LEFT, RGN_OVERLAP_RIGHT)) { + else if (ELEM(alignment, RGN_ALIGN_LEFT, RGN_ALIGN_RIGHT)) { if (rct_fits(remainder, 'h', prefsizex) < 0) { ar->flag |= RGN_FLAG_TOO_SMALL; @@ -998,14 +977,14 @@ static void region_rect_recursive(ScrArea *sa, ARegion *ar, rcti *remainder, int ar->winrct = *remainder; - if (ELEM(alignment, RGN_ALIGN_RIGHT, RGN_OVERLAP_RIGHT)) { + if (alignment == RGN_ALIGN_RIGHT) { ar->winrct.xmin = ar->winrct.xmax - prefsizex + 1; - if (alignment == RGN_ALIGN_RIGHT) + if (ar->overlap == 0) remainder->xmax = ar->winrct.xmin - 1; } else { ar->winrct.xmax = ar->winrct.xmin + prefsizex - 1; - if (alignment == RGN_ALIGN_LEFT) + if (ar->overlap == 0) remainder->xmin = ar->winrct.xmax + 1; } } @@ -1090,9 +1069,9 @@ static void region_rect_recursive(ScrArea *sa, ARegion *ar, rcti *remainder, int ar->winrct.ymin = ar->winrct.ymax; else if (alignment == RGN_ALIGN_BOTTOM) ar->winrct.ymax = ar->winrct.ymin; - else if (ELEM(alignment, RGN_ALIGN_RIGHT, RGN_OVERLAP_RIGHT)) + else if (alignment == RGN_ALIGN_RIGHT) ar->winrct.xmin = ar->winrct.xmax; - else if (ELEM(alignment, RGN_ALIGN_LEFT, RGN_OVERLAP_LEFT)) + else if (alignment == RGN_ALIGN_LEFT) ar->winrct.xmax = ar->winrct.xmin; else /* prevent winrct to be valid */ ar->winrct.xmax = ar->winrct.xmin; @@ -1121,12 +1100,12 @@ static void region_rect_recursive(ScrArea *sa, ARegion *ar, rcti *remainder, int region_azone_add(sa, ar, alignment); } - region_rect_recursive(sa, ar->next, remainder, quad); + region_rect_recursive(win, sa, ar->next, remainder, quad); } static void area_calc_totrct(ScrArea *sa, int sizex, int sizey) { - short rt = 0; // CLAMPIS(G.debug_value, 0, 16); + short rt = U.pixelsize > 1 ? 1 : 0; if (sa->v1->vec.x > 0) sa->totrct.xmin = sa->v1->vec.x + 1 + rt; else sa->totrct.xmin = sa->v1->vec.x; @@ -1229,14 +1208,14 @@ void ED_area_initialize(wmWindowManager *wm, wmWindow *win, ScrArea *sa) ar->type = BKE_regiontype_from_id(sa->type, ar->regiontype); /* area sizes */ - area_calc_totrct(sa, win->sizex, win->sizey); + area_calc_totrct(sa, WM_window_pixels_x(win), WM_window_pixels_y(win)); /* clear all azones, add the area triange widgets */ area_azone_initialize(win->screen, sa); /* region rect sizes */ rect = sa->totrct; - region_rect_recursive(sa, sa->regionbase.first, &rect, 0); + region_rect_recursive(win, sa, sa->regionbase.first, &rect, 0); /* default area handlers */ ed_default_handlers(wm, sa, &sa->handlers, sa->type->keymapflag); @@ -1284,11 +1263,17 @@ void ED_region_toggle_hidden(bContext *C, ARegion *ar) ar->flag ^= RGN_FLAG_HIDDEN; - if (ar->flag & RGN_FLAG_HIDDEN) - WM_event_remove_handlers(C, &ar->handlers); + if (ar->overlap) { + /* starts a timer, and in end calls the stuff below itself (region_sblend_invoke()) */ + region_blend_start(C, sa, ar); + } + else { + if (ar->flag & RGN_FLAG_HIDDEN) + WM_event_remove_handlers(C, &ar->handlers); - ED_area_initialize(CTX_wm_manager(C), CTX_wm_window(C), sa); - ED_area_tag_redraw(sa); + ED_area_initialize(CTX_wm_manager(C), CTX_wm_window(C), sa); + ED_area_tag_redraw(sa); + } } /* sa2 to sa1, we swap spaces for fullscreen to keep all allocated data */ @@ -1441,7 +1426,7 @@ void ED_area_prevspace(bContext *C, ScrArea *sa) { SpaceLink *sl = (sa) ? sa->spacedata.first : CTX_wm_space_data(C); - if (sl->next) { + if (sl && sl->next) { /* workaround for case of double prevspace, render window * with a file browser on top of it */ if (sl->next->spacetype == SPACE_FILE && sl->next->next) @@ -1565,14 +1550,14 @@ int ED_area_header_standardbuttons(const bContext *C, uiBlock *block, int yco) void ED_region_panels(const bContext *C, ARegion *ar, int vertical, const char *context, int contextnr) { ScrArea *sa = CTX_wm_area(C); - uiStyle *style = UI_GetStyle(); + uiStyle *style = UI_GetStyleDraw(); uiBlock *block; PanelType *pt; Panel *panel; View2D *v2d = &ar->v2d; View2DScrollers *scrollers; int x, y, xco, yco, w, em, triangle, open, newcontext = 0; - + if (contextnr >= 0) newcontext = UI_view2d_tab_set(v2d, contextnr); @@ -1653,8 +1638,18 @@ void ED_region_panels(const bContext *C, ARegion *ar, int vertical, const char * uiEndPanels(C, ar, &x, &y); /* clear */ - UI_ThemeClearColor((ar->type->regionid == RGN_TYPE_PREVIEW) ? TH_PREVIEW_BACK : TH_BACK); - glClear(GL_COLOR_BUFFER_BIT); + if (ar->overlap) { + /* view should be in pixelspace */ + UI_view2d_view_restore(C); + glEnable(GL_BLEND); + UI_ThemeColor4((ar->type->regionid == RGN_TYPE_PREVIEW) ? TH_PREVIEW_BACK : TH_BACK); + glRecti(0, 0, BLI_rcti_size_x(&ar->winrct), BLI_rcti_size_y(&ar->winrct)); + glDisable(GL_BLEND); + } + else { + UI_ThemeClearColor((ar->type->regionid == RGN_TYPE_PREVIEW) ? TH_PREVIEW_BACK : TH_BACK); + glClear(GL_COLOR_BUFFER_BIT); + } /* before setting the view */ if (vertical) { @@ -1725,7 +1720,7 @@ void ED_region_panels_init(wmWindowManager *wm, ARegion *ar) void ED_region_header(const bContext *C, ARegion *ar) { - uiStyle *style = UI_GetStyle(); + uiStyle *style = UI_GetStyleDraw(); uiBlock *block; uiLayout *layout; HeaderType *ht; @@ -1740,8 +1735,8 @@ void ED_region_header(const bContext *C, ARegion *ar) /* set view2d view matrix for scrolling (without scrollers) */ UI_view2d_view_ortho(&ar->v2d); - xco = maxco = 8; - yco = headery - 4; + xco = maxco = 0.4f * UI_UNIT_X; + yco = headery - floor(0.2f * UI_UNIT_Y); /* draw all headers types */ for (ht = ar->type->headertypes.first; ht; ht = ht->next) { @@ -1784,18 +1779,16 @@ void ED_region_header_init(ARegion *ar) /* UI_UNIT_Y is defined as U variable now, depending dpi */ int ED_area_headersize(void) { - return UI_UNIT_Y + 6; + return (int)(1.3f * UI_UNIT_Y); } void ED_region_info_draw(ARegion *ar, const char *text, int block, float alpha) { - const int header_height = 18; - uiStyle *style = UI_GetStyle(); + const int header_height = UI_UNIT_Y; + uiStyle *style = UI_GetStyleDraw(); int fontid = style->widget.uifont_id; rcti rect; - BLF_size(fontid, 11.0f, 72); - /* background box */ rect = ar->winrct; rect.xmin = 0; diff --git a/source/blender/editors/screen/glutil.c b/source/blender/editors/screen/glutil.c index ce2d045dc80..d3947432004 100644 --- a/source/blender/editors/screen/glutil.c +++ b/source/blender/editors/screen/glutil.c @@ -33,11 +33,13 @@ #include "MEM_guardedalloc.h" +#include "DNA_userdef_types.h" #include "DNA_vec_types.h" #include "BLI_rect.h" #include "BLI_utildefines.h" +#include "BKE_blender.h" #include "BKE_colortools.h" #include "BLI_math.h" @@ -292,7 +294,10 @@ void setlinestyle(int nr) else { glEnable(GL_LINE_STIPPLE); - glLineStipple(nr, 0xAAAA); + if (U.pixelsize > 1.0f) + glLineStipple(nr, 0xCCCC); + else + glLineStipple(nr, 0xAAAA); } } diff --git a/source/blender/editors/screen/screen_edit.c b/source/blender/editors/screen/screen_edit.c index 60aad14efcf..9a91e9d96cd 100644 --- a/source/blender/editors/screen/screen_edit.c +++ b/source/blender/editors/screen/screen_edit.c @@ -263,6 +263,9 @@ int scredge_is_horizontal(ScrEdge *se) ScrEdge *screen_find_active_scredge(bScreen *sc, int mx, int my) { ScrEdge *se; + int safety = U.widget_unit/10; + + if (safety < 2) safety = 2; for (se = sc->edgebase.first; se; se = se->next) { if (scredge_is_horizontal(se)) { @@ -270,7 +273,7 @@ ScrEdge *screen_find_active_scredge(bScreen *sc, int mx, int my) min = MIN2(se->v1->vec.x, se->v2->vec.x); max = MAX2(se->v1->vec.x, se->v2->vec.x); - if (abs(my - se->v1->vec.y) <= 2 && mx >= min && mx <= max) + if (abs(my - se->v1->vec.y) <= safety && mx >= min && mx <= max) return se; } else { @@ -278,7 +281,7 @@ ScrEdge *screen_find_active_scredge(bScreen *sc, int mx, int my) min = MIN2(se->v1->vec.y, se->v2->vec.y); max = MAX2(se->v1->vec.y, se->v2->vec.y); - if (abs(mx - se->v1->vec.x) <= 2 && my >= min && my <= max) + if (abs(mx - se->v1->vec.x) <= safety && my >= min && my <= max) return se; } } @@ -428,9 +431,9 @@ bScreen *ED_screen_add(wmWindow *win, Scene *scene, const char *name) sc->winid = win->winid; sv1 = screen_addvert(sc, 0, 0); - sv2 = screen_addvert(sc, 0, win->sizey - 1); - sv3 = screen_addvert(sc, win->sizex - 1, win->sizey - 1); - sv4 = screen_addvert(sc, win->sizex - 1, 0); + sv2 = screen_addvert(sc, 0, WM_window_pixels_y(win) - 1); + sv3 = screen_addvert(sc, WM_window_pixels_x(win) - 1, WM_window_pixels_y(win) - 1); + sv4 = screen_addvert(sc, WM_window_pixels_x(win) - 1, 0); screen_addedge(sc, sv1, sv2); screen_addedge(sc, sv2, sv3); @@ -628,7 +631,7 @@ static void screen_test_scale(bScreen *sc, int winsizex, int winsizey) float facx, facy, tempf, min[2], max[2]; /* calculate size */ - min[0] = min[1] = 10000.0f; + min[0] = min[1] = 20000.0f; max[0] = max[1] = 0.0f; for (sv = sc->vertbase.first; sv; sv = sv->next) { @@ -669,6 +672,29 @@ static void screen_test_scale(bScreen *sc, int winsizex, int winsizey) CLAMP(sv->vec.y, 0, winsizey); } + + /* scale prefsizes of regions */ + for (sa = sc->areabase.first; sa; sa = sa->next) { + ARegion *ar; + + for (ar = sa->regionbase.first; ar; ar = ar->next) { + ar->sizex = (int)((float)ar->sizex * facx); + ar->sizey = (int)((float)ar->sizey * facy); + ar->winx = (int)((float)ar->winx * facx); + ar->winy = (int)((float)ar->winy * facy); + } + if (sa->spacedata.first) { + SpaceLink *sl = sa->spacedata.first; + for (sl = sl->next; sl; sl = sl->next) { + for (ar = sl->regionbase.first; ar; ar = ar->next) { + ar->sizex = (int)((float)ar->sizex * facx); + ar->sizey = (int)((float)ar->sizey * facy); + ar->winx = (int)((float)ar->winx * facx); + ar->winy = (int)((float)ar->winy * facy); + } + } + } + } } /* test for collapsed areas. This could happen in some blender version... */ @@ -676,7 +702,7 @@ static void screen_test_scale(bScreen *sc, int winsizex, int winsizey) /* make each window at least ED_area_headersize() high */ for (sa = sc->areabase.first; sa; sa = sa->next) { - int headery = ED_area_headersize() + 1; + int headery = ED_area_headersize() + U.pixelsize; if (sa->v1->vec.y + headery > sa->v2->vec.y) { /* lower edge */ @@ -907,18 +933,18 @@ static void drawscredge_area(ScrArea *sa, int sizex, int sizey, int center) short y1 = sa->v1->vec.y; short x2 = sa->v3->vec.x; short y2 = sa->v3->vec.y; - short a, rt; - - rt = 0; // CLAMPIS(G.debug_value, 0, 16); if (center == 0) { - cpack(0x505050); - for (a = -rt; a <= rt; a++) - if (a != 0) - drawscredge_area_draw(sizex, sizey, x1, y1, x2, y2, a); + if (U.pixelsize > 1.0f) { + + glColor3ub(0x50, 0x50, 0x50); + glLineWidth(1.5f * U.pixelsize); + drawscredge_area_draw(sizex, sizey, x1, y1, x2, y2, 0); + glLineWidth(1.0f); + } } else { - cpack(0x0); + glColor3ub(0, 0, 0); drawscredge_area_draw(sizex, sizey, x1, y1, x2, y2, 0); } } @@ -1002,10 +1028,10 @@ void ED_screen_draw(wmWindow *win) if (sa->flag & AREA_FLAG_DRAWJOINFROM) sa1 = sa; if (sa->flag & AREA_FLAG_DRAWJOINTO) sa2 = sa; if (sa->flag & (AREA_FLAG_DRAWSPLIT_H | AREA_FLAG_DRAWSPLIT_V)) sa3 = sa; - drawscredge_area(sa, win->sizex, win->sizey, 0); + drawscredge_area(sa, WM_window_pixels_x(win), WM_window_pixels_y(win), 0); } for (sa = win->screen->areabase.first; sa; sa = sa->next) - drawscredge_area(sa, win->sizex, win->sizey, 1); + drawscredge_area(sa, WM_window_pixels_x(win), WM_window_pixels_y(win), 1); /* blended join arrow */ if (sa1 && sa2) { @@ -1078,20 +1104,20 @@ void ED_screen_refresh(wmWindowManager *wm, wmWindow *win) rcti winrct; winrct.xmin = 0; - winrct.xmax = win->sizex - 1; + winrct.xmax = WM_window_pixels_x(win) - 1; winrct.ymin = 0; - winrct.ymax = win->sizey - 1; + winrct.ymax = WM_window_pixels_y(win) - 1; - screen_test_scale(win->screen, win->sizex, win->sizey); + /* header size depends on DPI, let's verify */ + screen_refresh_headersizes(); + + screen_test_scale(win->screen, WM_window_pixels_x(win), WM_window_pixels_y(win)); if (win->screen->mainwin == 0) win->screen->mainwin = wm_subwindow_open(win, &winrct); else wm_subwindow_position(win, win->screen->mainwin, &winrct); - /* header size depends on DPI, let's verify */ - screen_refresh_headersizes(); - for (sa = win->screen->areabase.first; sa; sa = sa->next) { /* set spacetype and region callbacks, calls init() */ /* sets subwindows for regions, adds handlers */ @@ -1142,6 +1168,9 @@ void ED_region_exit(bContext *C, ARegion *ar) MEM_freeN(ar->headerstr); ar->headerstr = NULL; + if (ar->regiontimer) + WM_event_remove_timer(CTX_wm_manager(C), CTX_wm_window(C), ar->regiontimer); + CTX_wm_region_set(C, prevar); } diff --git a/source/blender/editors/screen/screen_intern.h b/source/blender/editors/screen/screen_intern.h index 86d99777e98..2e2b53f57d6 100644 --- a/source/blender/editors/screen/screen_intern.h +++ b/source/blender/editors/screen/screen_intern.h @@ -35,7 +35,7 @@ struct wmWindow; struct Scene; -#define AZONESPOT 12 +#define AZONESPOT (0.6f * U.widget_unit) /* area.c */ void area_copy_data(ScrArea *sa1, ScrArea *sa2, int swap_space); @@ -57,12 +57,16 @@ ScrEdge *screen_find_active_scredge(bScreen *sc, int mx, int my); struct AZone *is_in_area_actionzone(ScrArea *sa, const int xy[2]); /* screen_context.c */ -int ed_screen_context(const bContext *C, const char *member, bContextDataResult *result); +int ed_screen_context(const bContext *C, const char *member, bContextDataResult *result); extern const char *screen_context_dir[]; /* doc access */ /* screendump.c */ -void SCREEN_OT_screenshot(struct wmOperatorType *ot); -void SCREEN_OT_screencast(struct wmOperatorType *ot); +void SCREEN_OT_screenshot(struct wmOperatorType *ot); +void SCREEN_OT_screencast(struct wmOperatorType *ot); + +/* screen_ops.c */ +void region_blend_start(struct bContext *C, struct ScrArea *sa, struct ARegion *ar); + #endif /* __SCREEN_INTERN_H__ */ diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c index 67d4af916aa..269cc672e34 100644 --- a/source/blender/editors/screen/screen_ops.c +++ b/source/blender/editors/screen/screen_ops.c @@ -965,7 +965,7 @@ typedef struct sAreaMoveData { static void area_move_set_limits(bScreen *sc, int dir, int *bigger, int *smaller) { ScrArea *sa; - int areaminy = ED_area_headersize() + 1; + int areaminy = ED_area_headersize() + U.pixelsize; // pixelsize is used as area divider /* we check all areas and test for free space with MINSIZE */ *bigger = *smaller = 100000; @@ -1038,19 +1038,19 @@ static void area_move_apply_do(bContext *C, int origval, int delta, int dir, int for (v1 = sc->vertbase.first; v1; v1 = v1->next) { if (v1->flag) { /* that way a nice AREAGRID */ - if ((dir == 'v') && v1->vec.x > 0 && v1->vec.x < win->sizex - 1) { + if ((dir == 'v') && v1->vec.x > 0 && v1->vec.x < WM_window_pixels_x(win) - 1) { v1->vec.x = origval + delta; if (delta != bigger && delta != -smaller) v1->vec.x -= (v1->vec.x % AREAGRID); } - if ((dir == 'h') && v1->vec.y > 0 && v1->vec.y < win->sizey - 1) { + if ((dir == 'h') && v1->vec.y > 0 && v1->vec.y < WM_window_pixels_y(win) - 1) { v1->vec.y = origval + delta; v1->vec.y += AREAGRID - 1; v1->vec.y -= (v1->vec.y % AREAGRID); /* prevent too small top header */ - if (v1->vec.y > win->sizey - areaminy) - v1->vec.y = win->sizey - areaminy; + if (v1->vec.y > WM_window_pixels_y(win) - areaminy) + v1->vec.y = WM_window_pixels_y(win) - areaminy; } } } @@ -1720,9 +1720,9 @@ static int region_scale_invoke(bContext *C, wmOperator *op, wmEvent *event) /* if not set we do now, otherwise it uses type */ if (rmd->ar->sizex == 0) - rmd->ar->sizex = rmd->ar->type->prefsizex; + rmd->ar->sizex = rmd->ar->winx; if (rmd->ar->sizey == 0) - rmd->ar->sizey = rmd->ar->type->prefsizey; + rmd->ar->sizey = rmd->ar->winy; /* now copy to regionmovedata */ if (rmd->edge == AE_LEFT_TO_TOPRIGHT || rmd->edge == AE_RIGHT_TO_TOPLEFT) { @@ -1734,7 +1734,7 @@ static int region_scale_invoke(bContext *C, wmOperator *op, wmEvent *event) /* limit headers to standard height for now */ if (rmd->ar->regiontype == RGN_TYPE_HEADER) - maxsize = rmd->ar->type->prefsizey; + maxsize = ED_area_headersize(); else maxsize = 1000; @@ -2797,7 +2797,6 @@ static void SCREEN_OT_region_quadview(wmOperatorType *ot) } - /* ************** region flip operator ***************************** */ /* flip a region alignment */ @@ -3583,6 +3582,146 @@ static void SCENE_OT_delete(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; } +/* ***************** region alpha blending ***************** */ + +/* implementation note: a disapplearing region needs at least 1 last draw with 100% backbuffer + texture over it- then triple buffer will clear it entirely. + This because flag RGN_HIDDEN is set in end - region doesnt draw at all then */ + +typedef struct RegionAlphaInfo { + ScrArea *sa; + ARegion *ar, *child_ar; /* other region */ + int hidden; +} RegionAlphaInfo; + +#define TIMEOUT 0.3f +#define TIMESTEP 0.04 + +float ED_region_blend_factor(ARegion *ar) +{ + /* check parent too */ + if(ar->regiontimer == NULL && (ar->alignment & RGN_SPLIT_PREV) && ar->prev) + ar = ar->prev; + + if (ar->regiontimer) { + RegionAlphaInfo *rgi = ar->regiontimer->customdata; + float alpha; + + alpha = (float)ar->regiontimer->duration / TIMEOUT; + /* makes sure the blend out works 100% - without area redraws */ + if (rgi->hidden) alpha = 0.9 - TIMESTEP - alpha; + + CLAMP(alpha, 0.0f, 1.0f); + return alpha; + } + return 1.0f; +} + +/* assumes region has running region-blend timer */ +static void region_blend_end(bContext *C, ARegion *ar, int is_running) +{ + RegionAlphaInfo *rgi = ar->regiontimer->customdata; + + /* always send redraw */ + ED_region_tag_redraw(ar); + if (rgi->child_ar) + ED_region_tag_redraw(rgi->child_ar); + + /* if running timer was hiding, the flag toggle went wrong */ + if (is_running) { + if (rgi->hidden) + rgi->ar->flag &= ~RGN_FLAG_HIDDEN; + } + else { + if (rgi->hidden) { + rgi->ar->flag |= rgi->hidden; + ED_area_initialize(CTX_wm_manager(C), CTX_wm_window(C), rgi->sa); + } + /* area decoration needs redraw in end */ + ED_area_tag_redraw(rgi->sa); + } + WM_event_remove_timer(CTX_wm_manager(C), NULL, ar->regiontimer); /* frees rgi */ + ar->regiontimer = NULL; + +} +/* assumes that *ar itself is not a splitted version from previous region */ +void region_blend_start(bContext *C, ScrArea *sa, ARegion *ar) +{ + wmWindowManager *wm = CTX_wm_manager(C); + wmWindow *win = CTX_wm_window(C); + RegionAlphaInfo *rgi; + + /* end running timer */ + if (ar->regiontimer) { + + region_blend_end(C, ar, 1); + } + rgi = MEM_callocN(sizeof(RegionAlphaInfo), "RegionAlphaInfo"); + + rgi->hidden = ar->flag & RGN_FLAG_HIDDEN; + rgi->sa = sa; + rgi->ar = ar; + ar->flag &= ~RGN_FLAG_HIDDEN; + + /* blend in, reinitialize regions because it got unhidden */ + if (rgi->hidden == 0) + ED_area_initialize(wm, win, sa); + else + WM_event_remove_handlers(C, &ar->handlers); + + if(ar->next) + if (ar->next->alignment & RGN_SPLIT_PREV) + rgi->child_ar = ar->next; + + /* new timer */ + ar->regiontimer = WM_event_add_timer(wm, win, TIMERREGION, TIMESTEP); + ar->regiontimer->customdata = rgi; + +} + +/* timer runs in win->handlers, so it cannot use context to find area/region */ +static int region_blend_invoke(bContext *C, wmOperator *UNUSED(op), wmEvent *event) +{ + RegionAlphaInfo *rgi; + wmTimer *timer = event->customdata; + + /* event type is TIMERREGION, but we better check */ + if (event->type != TIMERREGION || timer == NULL) + return OPERATOR_PASS_THROUGH; + + rgi = timer->customdata; + + /* always send redraws */ + ED_region_tag_redraw(rgi->ar); + if (rgi->child_ar) + ED_region_tag_redraw(rgi->child_ar); + + /* end timer? */ + if (rgi->ar->regiontimer->duration > TIMEOUT) { + region_blend_end(C, rgi->ar, 0); + return (OPERATOR_FINISHED | OPERATOR_PASS_THROUGH); + } + + return (OPERATOR_FINISHED | OPERATOR_PASS_THROUGH); +} + +static void SCREEN_OT_region_blend(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Region Alpha"; + ot->idname = "SCREEN_OT_region_blend"; + ot->description = "Blend in and out overlapping region"; + + /* api callbacks */ + ot->invoke = region_blend_invoke; + + /* flags */ + ot->flag = 0; + + /* properties */ +} + + /* **************** Assigning operatortypes to global list, adding handlers **************** */ @@ -3615,6 +3754,7 @@ void ED_operatortypes_screen(void) WM_operatortype_append(SCREEN_OT_screenshot); WM_operatortype_append(SCREEN_OT_screencast); WM_operatortype_append(SCREEN_OT_userpref_show); + WM_operatortype_append(SCREEN_OT_region_blend); /*frame changes*/ WM_operatortype_append(SCREEN_OT_frame_offset); @@ -3717,6 +3857,7 @@ void ED_keymap_screen(wmKeyConfig *keyconf) /* standard timers */ WM_keymap_add_item(keymap, "SCREEN_OT_animation_step", TIMER0, KM_ANY, KM_ANY, 0); + WM_keymap_add_item(keymap, "SCREEN_OT_region_blend", TIMERREGION, KM_ANY, KM_ANY, 0); RNA_int_set(WM_keymap_add_item(keymap, "SCREEN_OT_screen_set", RIGHTARROWKEY, KM_PRESS, KM_CTRL, 0)->ptr, "delta", 1); diff --git a/source/blender/editors/space_console/console_draw.c b/source/blender/editors/space_console/console_draw.c index a215b476094..5da3081df52 100644 --- a/source/blender/editors/space_console/console_draw.c +++ b/source/blender/editors/space_console/console_draw.c @@ -50,6 +50,7 @@ #include "ED_datafiles.h" #include "ED_types.h" +#include "UI_interface.h" #include "UI_resources.h" #include "console_intern.h" @@ -119,7 +120,7 @@ void console_scrollback_prompt_end(struct SpaceConsole *sc, ConsoleLine *cl_dumm static int console_textview_begin(TextViewContext *tvc) { SpaceConsole *sc = (SpaceConsole *)tvc->arg1; - tvc->lheight = sc->lheight; + tvc->lheight = sc->lheight * UI_DPI_FAC; tvc->sel_start = sc->sel_start; tvc->sel_end = sc->sel_end; @@ -217,7 +218,7 @@ static int console_textview_main__internal(struct SpaceConsole *sc, ARegion *ar, /* view */ tvc.sel_start = sc->sel_start; tvc.sel_end = sc->sel_end; - tvc.lheight = sc->lheight; + tvc.lheight = sc->lheight * UI_DPI_FAC; tvc.ymin = v2d->cur.ymin; tvc.ymax = v2d->cur.ymax; tvc.winx = ar->winx; diff --git a/source/blender/editors/space_graph/graph_draw.c b/source/blender/editors/space_graph/graph_draw.c index f665b979559..256c90a1f1a 100644 --- a/source/blender/editors/space_graph/graph_draw.c +++ b/source/blender/editors/space_graph/graph_draw.c @@ -516,7 +516,7 @@ static void draw_fcurve_curve(bAnimContext *ac, ID *id, FCurve *fcu, View2D *v2d */ /* grid->dx represents the number of 'frames' between gridlines, but we divide by U.v2d_min_gridsize to get pixels-steps */ /* TODO: perhaps we should have 1.0 frames as upper limit so that curves don't get too distorted? */ - samplefreq = dx / U.v2d_min_gridsize; + samplefreq = dx / (U.v2d_min_gridsize * U.pixelsize); if (samplefreq < 0.00001f) samplefreq = 0.00001f; diff --git a/source/blender/editors/space_info/info_draw.c b/source/blender/editors/space_info/info_draw.c index 5830c4574df..cd12b93c7ea 100644 --- a/source/blender/editors/space_info/info_draw.c +++ b/source/blender/editors/space_info/info_draw.c @@ -56,6 +56,7 @@ #include "ED_types.h" #include "UI_resources.h" +#include "UI_interface.h" #include "info_intern.h" #include "../space_info/textview.h" @@ -139,7 +140,7 @@ static int report_textview_begin(TextViewContext *tvc) // SpaceConsole *sc = (SpaceConsole *)tvc->arg1; ReportList *reports = (ReportList *)tvc->arg2; - tvc->lheight = 14; //sc->lheight; + tvc->lheight = 14 * UI_DPI_FAC; //sc->lheight; tvc->sel_start = 0; tvc->sel_end = 0; @@ -269,7 +270,7 @@ static int info_textview_main__internal(struct SpaceInfo *sinfo, ARegion *ar, Re /* view */ tvc.sel_start = 0; tvc.sel_end = 0; - tvc.lheight = 14; //sc->lheight; + tvc.lheight = 14 * UI_DPI_FAC; //sc->lheight; tvc.ymin = v2d->cur.ymin; tvc.ymax = v2d->cur.ymax; tvc.winx = ar->winx; diff --git a/source/blender/editors/space_info/textview.c b/source/blender/editors/space_info/textview.c index f454b1dbe7d..f2c2bbfaa71 100644 --- a/source/blender/editors/space_info/textview.c +++ b/source/blender/editors/space_info/textview.c @@ -45,7 +45,8 @@ static void console_font_begin(TextViewContext *sc) { - BLF_size(blf_mono_font, sc->lheight - 2, 72); + /* 0.875 is based on: 16 pixels lines get 14 pixel text */ + BLF_size(blf_mono_font, 0.875 * sc->lheight, 72); } typedef struct ConsoleDrawContext { diff --git a/source/blender/editors/space_logic/logic_window.c b/source/blender/editors/space_logic/logic_window.c index 5a8a7cef119..00745062582 100644 --- a/source/blender/editors/space_logic/logic_window.c +++ b/source/blender/editors/space_logic/logic_window.c @@ -2270,11 +2270,11 @@ void logic_buttons(bContext *C, ARegion *ar) /* ****************** Controllers ****************** */ - xco= 420; yco= -10; width= 300; + xco= 21 * U.widget_unit; yco= - U.widget_unit / 2; width= 15 * U.widget_unit; layout= uiBlockLayout(block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL, xco, yco, width, 20, UI_GetStyle()); row = uiLayoutRow(layout, TRUE); - uiDefBlockBut(block, controller_menu, NULL, IFACE_("Controllers"), xco-10, yco, 300, UI_UNIT_Y, ""); /* replace this with uiLayout stuff later */ + uiDefBlockBut(block, controller_menu, NULL, IFACE_("Controllers"), xco - U.widget_unit / 2, yco, width, UI_UNIT_Y, ""); /* replace this with uiLayout stuff later */ uiItemR(row, &logic_ptr, "show_controllers_selected_objects", 0, IFACE_("Sel"), ICON_NONE); uiItemR(row, &logic_ptr, "show_controllers_active_object", 0, IFACE_("Act"), ICON_NONE); @@ -2301,7 +2301,7 @@ void logic_buttons(bContext *C, ARegion *ar) uiItemR(split, &settings_ptr, "show_state_panel", UI_ITEM_R_NO_BG, "", ICON_DISCLOSURE_TRI_RIGHT); row = uiLayoutRow(split, TRUE); - uiDefButBitS(block, TOG, OB_SHOWCONT, B_REDR, ob->id.name+2, (short)(xco-10), yco, (short)(width-30), UI_UNIT_Y, &ob->scaflag, 0, 31, 0, 0, TIP_("Object name, click to show/hide controllers")); + uiDefButBitS(block, TOG, OB_SHOWCONT, B_REDR, ob->id.name+2, (short)(xco - U.widget_unit / 2), yco, (short)(width - 1.5f * U.widget_unit), UI_UNIT_Y, &ob->scaflag, 0, 31, 0, 0, TIP_("Object name, click to show/hide controllers")); RNA_pointer_create((ID *)ob, &RNA_Object, ob, &object_ptr); uiLayoutSetContextPointer(row, "object", &object_ptr); @@ -2377,11 +2377,11 @@ void logic_buttons(bContext *C, ARegion *ar) /* ****************** Sensors ****************** */ - xco= 10; yco= -10; width= 340; + xco= U.widget_unit / 2; yco= -U.widget_unit / 2; width= 17 * U.widget_unit; layout= uiBlockLayout(block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL, xco, yco, width, 20, UI_GetStyle()); row = uiLayoutRow(layout, TRUE); - uiDefBlockBut(block, sensor_menu, NULL, IFACE_("Sensors"), xco-10, yco, 300, UI_UNIT_Y, ""); /* replace this with uiLayout stuff later */ + uiDefBlockBut(block, sensor_menu, NULL, IFACE_("Sensors"), xco - U.widget_unit / 2, yco, 15 * U.widget_unit, UI_UNIT_Y, ""); /* replace this with uiLayout stuff later */ uiItemR(row, &logic_ptr, "show_sensors_selected_objects", 0, IFACE_("Sel"), ICON_NONE); uiItemR(row, &logic_ptr, "show_sensors_active_object", 0, IFACE_("Act"), ICON_NONE); @@ -2398,7 +2398,7 @@ void logic_buttons(bContext *C, ARegion *ar) if ((ob->scavisflag & OB_VIS_SENS) == 0) continue; row = uiLayoutRow(layout, TRUE); - uiDefButBitS(block, TOG, OB_SHOWSENS, B_REDR, ob->id.name+2, (short)(xco-10), yco, (short)(width-30), UI_UNIT_Y, &ob->scaflag, 0, 31, 0, 0, TIP_("Object name, click to show/hide sensors")); + uiDefButBitS(block, TOG, OB_SHOWSENS, B_REDR, ob->id.name+2, (short)(xco - U.widget_unit / 2), yco, (short)(width - 1.5f * U.widget_unit), UI_UNIT_Y, &ob->scaflag, 0, 31, 0, 0, TIP_("Object name, click to show/hide sensors")); RNA_pointer_create((ID *)ob, &RNA_Object, ob, &object_ptr); uiLayoutSetContextPointer(row, "object", &object_ptr); @@ -2446,11 +2446,11 @@ void logic_buttons(bContext *C, ARegion *ar) /* ****************** Actuators ****************** */ - xco= 800; yco= -10; width= 340; + xco= 40 * U.widget_unit; yco= -U.widget_unit / 2; width= 17 * U.widget_unit; layout= uiBlockLayout(block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL, xco, yco, width, 20, UI_GetStyle()); row = uiLayoutRow(layout, TRUE); - uiDefBlockBut(block, actuator_menu, NULL, IFACE_("Actuators"), xco-10, yco, 300, UI_UNIT_Y, ""); /* replace this with uiLayout stuff later */ + uiDefBlockBut(block, actuator_menu, NULL, IFACE_("Actuators"), xco - U.widget_unit / 2, yco, 15 * U.widget_unit, UI_UNIT_Y, ""); /* replace this with uiLayout stuff later */ uiItemR(row, &logic_ptr, "show_actuators_selected_objects", 0, IFACE_("Sel"), ICON_NONE); uiItemR(row, &logic_ptr, "show_actuators_active_object", 0, IFACE_("Act"), ICON_NONE); @@ -2469,7 +2469,7 @@ void logic_buttons(bContext *C, ARegion *ar) } row = uiLayoutRow(layout, TRUE); - uiDefButBitS(block, TOG, OB_SHOWACT, B_REDR, ob->id.name+2, (short)(xco-10), yco, (short)(width-30), UI_UNIT_Y, &ob->scaflag, 0, 31, 0, 0, TIP_("Object name, click to show/hide actuators")); + uiDefButBitS(block, TOG, OB_SHOWACT, B_REDR, ob->id.name+2, (short)(xco - U.widget_unit / 2), yco, (short)(width - 1.5f * U.widget_unit), UI_UNIT_Y, &ob->scaflag, 0, 31, 0, 0, TIP_("Object name, click to show/hide actuators")); RNA_pointer_create((ID *)ob, &RNA_Object, ob, &object_ptr); uiLayoutSetContextPointer(row, "object", &object_ptr); @@ -2516,7 +2516,7 @@ void logic_buttons(bContext *C, ARegion *ar) uiBlockLayoutResolve(block, NULL, &yco); /* stores final height in yco */ height = MIN2(height, yco); - UI_view2d_totRect_set(&ar->v2d, 1150, height); + UI_view2d_totRect_set(&ar->v2d, 57.5f * U.widget_unit, height); /* set the view */ UI_view2d_view_ortho(&ar->v2d); diff --git a/source/blender/editors/space_nla/nla_draw.c b/source/blender/editors/space_nla/nla_draw.c index fd999bf2476..beabd44c297 100644 --- a/source/blender/editors/space_nla/nla_draw.c +++ b/source/blender/editors/space_nla/nla_draw.c @@ -632,7 +632,7 @@ static void draw_nla_channel_list_gl(bAnimContext *ac, ListBase *anim_data, View for (ale = anim_data->first; ale; ale = ale->next) { const float yminc = (float)(y - NLACHANNEL_HEIGHT_HALF(snla)); const float ymaxc = (float)(y + NLACHANNEL_HEIGHT_HALF(snla)); - const float ydatac = (float)(y - 7); + const float ydatac = (float)(y - 0.35f * U.widget_unit); /* check if visible */ if (IN_RANGE(yminc, v2d->cur.ymin, v2d->cur.ymax) || @@ -716,7 +716,7 @@ static void draw_nla_channel_list_gl(bAnimContext *ac, ListBase *anim_data, View if (ale->id) { /* special exception for textures */ if (GS(ale->id->name) == ID_TE) { - offset = 14; + offset = 0.7f * U.widget_unit; indent = 1; } /* special exception for nodetrees */ @@ -727,7 +727,7 @@ static void draw_nla_channel_list_gl(bAnimContext *ac, ListBase *anim_data, View case NTREE_SHADER: { /* same as for textures */ - offset = 14; + offset = 0.7f * U.widget_unit; indent = 1; } break; @@ -735,19 +735,19 @@ static void draw_nla_channel_list_gl(bAnimContext *ac, ListBase *anim_data, View case NTREE_TEXTURE: { /* even more */ - offset = 21; + offset = U.widget_unit; indent = 1; } break; default: /* normal will do */ - offset = 14; + offset = 0.7f * U.widget_unit; break; } } else { - offset = 14; + offset = 0.7f * U.widget_unit; } } else { @@ -779,7 +779,7 @@ static void draw_nla_channel_list_gl(bAnimContext *ac, ListBase *anim_data, View glColor4f(color[0], color[1], color[2], alpha); } - offset += 7 * indent; + offset += 0.35f * U.widget_unit * indent; /* only on top two corners, to show that this channel sits on top of the preceding ones */ uiSetRoundBox(UI_CNR_TOP_LEFT | UI_CNR_TOP_RIGHT); @@ -797,7 +797,7 @@ static void draw_nla_channel_list_gl(bAnimContext *ac, ListBase *anim_data, View UI_ThemeColorShade(TH_HEADER, ((nonSolo == 0) ? 20 : -20)); indent += group; - offset += 7 * indent; + offset += 0.35f * U.widget_unit * indent; glBegin(GL_QUADS); glVertex2f(x + offset, yminc); glVertex2f(x + offset, ymaxc); @@ -809,14 +809,14 @@ static void draw_nla_channel_list_gl(bAnimContext *ac, ListBase *anim_data, View /* draw expand/collapse triangle */ if (expand > 0) { UI_icon_draw(x + offset, ydatac, expand); - offset += 17; + offset += 0.85f * U.widget_unit; } /* draw special icon indicating certain data-types */ if (special > -1) { /* for normal channels */ UI_icon_draw(x + offset, ydatac, special); - offset += 17; + offset += 0.85f * U.widget_unit; } glDisable(GL_BLEND); @@ -837,19 +837,19 @@ static void draw_nla_channel_list_gl(bAnimContext *ac, ListBase *anim_data, View /* draw protect 'lock' */ if (protect > -1) { - offset = 16; + offset = 0.8f * U.widget_unit; UI_icon_draw((float)(v2d->cur.xmax - offset), ydatac, protect); } /* draw mute 'eye' */ if (mute > -1) { - offset += 16; + offset += 0.8f * U.widget_unit; UI_icon_draw((float)(v2d->cur.xmax - offset), ydatac, mute); } /* draw NLA-action line 'status-icons' - only when there's an action */ if ((ale->type == ANIMTYPE_NLAACTION) && (ale->data)) { - offset += 16; + offset += 0.8f * U.widget_unit; /* now draw some indicator icons */ if ((adt) && (adt->flag & ADT_NLA_EDIT_ON)) { @@ -862,7 +862,7 @@ static void draw_nla_channel_list_gl(bAnimContext *ac, ListBase *anim_data, View fdrawline((float)(v2d->cur.xmax - offset), yminc, (float)(v2d->cur.xmax - offset), ymaxc); - offset += 16; + offset += 0.8f * U.widget_unit; /* 'tweaking action' indicator - not a button */ UI_icon_draw((float)(v2d->cur.xmax - offset), ydatac, ICON_EDIT); @@ -870,10 +870,10 @@ static void draw_nla_channel_list_gl(bAnimContext *ac, ListBase *anim_data, View else { /* XXX firstly draw a little rect to help identify that it's different from the toggles */ glBegin(GL_LINE_LOOP); - glVertex2f((float)v2d->cur.xmax - offset - 1, y - 7); - glVertex2f((float)v2d->cur.xmax - offset - 1, y + 9); - glVertex2f((float)v2d->cur.xmax - 1, y + 9); - glVertex2f((float)v2d->cur.xmax - 1, y - 7); + glVertex2f((float)v2d->cur.xmax - offset - 1, y - 0.35f * U.widget_unit); + glVertex2f((float)v2d->cur.xmax - offset - 1, y + 0.45 * U.widget_unit); + glVertex2f((float)v2d->cur.xmax - 1, y + 0.45f * U.widget_unit); + glVertex2f((float)v2d->cur.xmax - 1, y - 0.35f * U.widget_unit); glEnd(); // GL_LINES /* 'push down' icon for normal active-actions */ diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c index 381393eb725..e3078d3f72b 100644 --- a/source/blender/editors/space_node/drawnode.c +++ b/source/blender/editors/space_node/drawnode.c @@ -123,10 +123,10 @@ static void node_socket_button_string(const bContext *C, uiBlock *block, float slen; UI_ThemeColor(TH_TEXT); - slen = (UI_GetStringWidth(ui_name) + NODE_MARGIN_X) * snode->aspect_sqrt; + slen = (UI_GetStringWidth(ui_name) + NODE_MARGIN_X) * snode->aspect; /* XXX, check for dpis */ while (slen > (width * 0.5f) && *ui_name) { ui_name = BLI_str_find_next_char_utf8(ui_name, NULL); - slen = (UI_GetStringWidth(ui_name) + NODE_MARGIN_X) * snode->aspect_sqrt; + slen = (UI_GetStringWidth(ui_name) + NODE_MARGIN_X) * snode->aspect; } RNA_pointer_create(&ntree->id, &RNA_NodeSocket, sock, &ptr); @@ -229,19 +229,18 @@ static void node_draw_input_default(const bContext *C, uiBlock *block, node_socket_button_label(C, block, ntree, node, sock, IFACE_(name), x, y, width); } -static void node_draw_output_default(const bContext *C, uiBlock *block, +static void node_draw_output_default(const bContext *UNUSED(C), uiBlock *block, bNodeTree *UNUSED(ntree), bNode *node, bNodeSocket *sock, const char *name, int UNUSED(x), int UNUSED(y), int UNUSED(width)) { - SpaceNode *snode = CTX_wm_space_node(C); const char *ui_name = IFACE_(name); float slen; UI_ThemeColor(TH_TEXT); - slen = (UI_GetStringWidth(ui_name) + NODE_MARGIN_X) * snode->aspect_sqrt; - while (slen > node->width && *ui_name) { + slen = (UI_GetStringWidth(ui_name) + NODE_MARGIN_X) ; + while (slen > NODE_WIDTH(node) && *ui_name) { ui_name = BLI_str_find_next_char_utf8(ui_name, NULL); - slen = (UI_GetStringWidth(ui_name) + NODE_MARGIN_X) * snode->aspect_sqrt; + slen = (UI_GetStringWidth(ui_name) + NODE_MARGIN_X); } if (*ui_name) { @@ -509,14 +508,14 @@ static void node_update_group(const bContext *C, bNodeTree *ntree, bNode *gnode) bNodeSocket *sock, *gsock; float locx, locy; rctf *rect = &gnode->totr; - const float dpi_fac = UI_DPI_ICON_FAC; + const float dpi_fac = UI_DPI_FAC; const float node_group_frame = NODE_GROUP_FRAME * dpi_fac; const float group_header = 26 * dpi_fac; int counter; int dy; /* get "global" coords */ - nodeToView(gnode, 0.0f, 0.0f, &locx, &locy); + node_to_view(gnode, 0.0f, 0.0f, &locx, &locy); /* center them, is a bit of abuse of locx and locy though */ node_update_nodetree(C, ngroup, locx, locy); @@ -688,7 +687,7 @@ static void draw_group_socket_name(SpaceNode *snode, bNode *gnode, bNodeSocket * static void draw_group_socket(const bContext *C, SpaceNode *snode, bNodeTree *ntree, bNode *gnode, bNodeSocket *sock, bNodeSocket *gsock, int index, int in_out) { - const float dpi_fac = UI_DPI_ICON_FAC; + const float dpi_fac = 1.0f; bNodeTree *ngroup = (bNodeTree *)gnode->id; bNodeSocketType *stype = ntreeGetSocketType(gsock ? gsock->type : sock->type); uiBut *bt; @@ -800,7 +799,7 @@ static void node_draw_group(const bContext *C, ARegion *ar, SpaceNode *snode, bN uiLayout *layout; PointerRNA ptr; rctf rect = gnode->totr; - const float dpi_fac = UI_DPI_ICON_FAC; + const float dpi_fac = 1.0f; const float node_group_frame = NODE_GROUP_FRAME * dpi_fac; const float group_header = 26 * dpi_fac; @@ -925,7 +924,7 @@ static void node_uifunc_group(uiLayout *layout, bContext *C, PointerRNA *ptr) */ static void node_update_frame(const bContext *UNUSED(C), bNodeTree *ntree, bNode *node) { - const float margin = 30.0f; + const float margin = 1.5f * U.widget_unit; NodeFrame *data = (NodeFrame *)node->storage; int bbinit; bNode *tnode; @@ -933,8 +932,8 @@ static void node_update_frame(const bContext *UNUSED(C), bNodeTree *ntree, bNode float xmax, ymax; /* init rect from current frame size */ - nodeToView(node, node->offsetx, node->offsety, &rect.xmin, &rect.ymax); - nodeToView(node, node->offsetx + node->width, node->offsety - node->height, &rect.xmax, &rect.ymin); + node_to_view(node, node->offsetx, node->offsety, &rect.xmin, &rect.ymax); + node_to_view(node, node->offsetx + node->width, node->offsety - node->height, &rect.xmax, &rect.ymin); /* frame can be resized manually only if shrinking is disabled or no children are attached */ data->flag |= NODE_FRAME_RESIZEABLE; @@ -963,8 +962,8 @@ static void node_update_frame(const bContext *UNUSED(C), bNodeTree *ntree, bNode } /* now adjust the frame size from view-space bounding box */ - nodeFromView(node, rect.xmin, rect.ymax, &node->offsetx, &node->offsety); - nodeFromView(node, rect.xmax, rect.ymin, &xmax, &ymax); + node_from_view(node, rect.xmin, rect.ymax, &node->offsetx, &node->offsety); + node_from_view(node, rect.xmax, rect.ymin, &xmax, &ymax); node->width = xmax - node->offsetx; node->height = -ymax + node->offsety; @@ -1101,7 +1100,7 @@ static void node_update_reroute(const bContext *UNUSED(C), bNodeTree *UNUSED(ntr float size = NODE_REROUTE_SIZE; /* get "global" coords */ - nodeToView(node, 0.0f, 0.0f, &locx, &locy); + node_to_view(node, 0.0f, 0.0f, &locx, &locy); /* reroute node has exactly one input and one output, both in the same place */ nsock = node->outputs.first; @@ -3532,7 +3531,7 @@ void node_draw_link_bezier(View2D *v2d, SpaceNode *snode, bNodeLink *link, glDisable(GL_LINE_SMOOTH); /* restore previuos linewidth */ - glLineWidth(linew); + glLineWidth(1.0f); } } @@ -3618,7 +3617,7 @@ void node_draw_link_straight(View2D *v2d, SpaceNode *snode, bNodeLink *link, glDisable(GL_LINE_SMOOTH); /* restore previuos linewidth */ - glLineWidth(linew); + glLineWidth(1.0f); } #endif diff --git a/source/blender/editors/space_node/node_add.c b/source/blender/editors/space_node/node_add.c index 96ac716f383..509e326137b 100644 --- a/source/blender/editors/space_node/node_add.c +++ b/source/blender/editors/space_node/node_add.c @@ -76,10 +76,14 @@ bNode *node_add_node(SpaceNode *snode, Main *bmain, Scene *scene, if (node) { node_select(node); + /* node location is mapped */ + locx /= UI_DPI_FAC; + locy /= UI_DPI_FAC; + gnode = node_tree_get_editgroup(snode->nodetree); // arbitrary y offset of 60 so its visible if (gnode) { - nodeFromView(gnode, locx, locy + 60.0f, &node->locx, &node->locy); + node_from_view(gnode, locx, locy + 60.0f, &node->locx, &node->locy); } else { node->locx = locx; @@ -215,7 +219,7 @@ static bNodeSocketLink *add_reroute_do_socket_section(bContext *C, bNodeSocketLi mul_v2_fl(insert_point, 1.0f / num_links); if (gnode) { - nodeFromView(gnode, insert_point[0], insert_point[1], &reroute_node->locx, &reroute_node->locy); + node_from_view(gnode, insert_point[0], insert_point[1], &reroute_node->locx, &reroute_node->locy); } else { reroute_node->locx = insert_point[0]; diff --git a/source/blender/editors/space_node/node_draw.c b/source/blender/editors/space_node/node_draw.c index 72461cfb2a8..704bc70fa01 100644 --- a/source/blender/editors/space_node/node_draw.c +++ b/source/blender/editors/space_node/node_draw.c @@ -278,6 +278,21 @@ static void node_uiblocks_init(const bContext *C, bNodeTree *ntree) } } +void node_to_view(struct bNode *node, float x, float y, float *rx, float *ry) +{ + nodeToView(node, x, y, rx, ry); + *rx *= UI_DPI_FAC; + *ry *= UI_DPI_FAC; +} + +void node_from_view(struct bNode *node, float x, float y, float *rx, float *ry) +{ + x /= UI_DPI_FAC; + y /= UI_DPI_FAC; + nodeFromView(node, x, y, rx, ry); +} + + /* based on settings in node, sets drawing rect info. each redraw! */ static void node_update_basis(const bContext *C, bNodeTree *ntree, bNode *node) { @@ -289,7 +304,7 @@ static void node_update_basis(const bContext *C, bNodeTree *ntree, bNode *node) int buty; /* get "global" coords */ - nodeToView(node, 0.0f, 0.0f, &locx, &locy); + node_to_view(node, 0.0f, 0.0f, &locx, &locy); dy = locy; /* header */ @@ -302,14 +317,14 @@ static void node_update_basis(const bContext *C, bNodeTree *ntree, bNode *node) /* output sockets */ for (nsock = node->outputs.first; nsock; nsock = nsock->next) { if (!nodeSocketIsHidden(nsock)) { - nsock->locx = locx + node->width; + nsock->locx = locx + NODE_WIDTH(node); nsock->locy = dy - NODE_DYS; dy -= NODE_DY; } } node->prvr.xmin = locx + NODE_DYS; - node->prvr.xmax = locx + node->width - NODE_DYS; + node->prvr.xmax = locx + NODE_WIDTH(node) - NODE_DYS; /* preview rect? */ if (node->flag & NODE_PREVIEW) { @@ -323,12 +338,13 @@ static void node_update_basis(const bContext *C, bNodeTree *ntree, bNode *node) node->prvr.ymax = dy; if (aspect <= 1.0f) - node->prvr.ymin = dy - aspect * (node->width - NODE_DY); + node->prvr.ymin = dy - aspect * (NODE_WIDTH(node) - NODE_DY); else { /* width correction of image */ - float dx = (node->width - NODE_DYS) - (node->width - NODE_DYS) / aspect; + /* XXX huh? (ton) */ + float dx = (NODE_WIDTH(node) - NODE_DYS) - (NODE_WIDTH(node) - NODE_DYS) / aspect; - node->prvr.ymin = dy - (node->width - NODE_DY); + node->prvr.ymin = dy - (NODE_WIDTH(node) - NODE_DY); node->prvr.xmin += 0.5f * dx; node->prvr.xmax -= 0.5f * dx; @@ -343,7 +359,7 @@ static void node_update_basis(const bContext *C, bNodeTree *ntree, bNode *node) else { float oldh = BLI_rctf_size_y(&node->prvr); if (oldh == 0.0f) - oldh = 0.6f * node->width - NODE_DY; + oldh = 0.6f * NODE_WIDTH(node) - NODE_DY; dy -= NODE_DYS / 2; node->prvr.ymax = dy; node->prvr.ymin = dy - oldh; @@ -357,21 +373,22 @@ static void node_update_basis(const bContext *C, bNodeTree *ntree, bNode *node) /* set this for uifunc() that don't use layout engine yet */ node->butr.xmin = 0; - node->butr.xmax = node->width - 2 * NODE_DYS; + node->butr.xmax = NODE_WIDTH(node) - 2 * NODE_DYS; node->butr.ymin = 0; node->butr.ymax = 0; RNA_pointer_create(&ntree->id, &RNA_Node, node, &ptr); + layout = uiBlockLayout(node->block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL, - locx + NODE_DYS, dy, node->butr.xmax, NODE_DY, UI_GetStyle()); + locx + NODE_DYS, dy, node->butr.xmax, 0, UI_GetStyle()); uiLayoutSetContextPointer(layout, "node", &ptr); node->typeinfo->uifunc(layout, (bContext *)C, &ptr); uiBlockEndAlign(node->block); uiBlockLayoutResolve(node->block, NULL, &buty); - + dy = buty - NODE_DYS / 2; } @@ -389,7 +406,7 @@ static void node_update_basis(const bContext *C, bNodeTree *ntree, bNode *node) dy -= NODE_DYS / 2; node->totr.xmin = locx; - node->totr.xmax = locx + node->width; + node->totr.xmax = locx + NODE_WIDTH(node); node->totr.ymax = locy; node->totr.ymin = min_ff(dy, locy - 2 * NODE_DY); @@ -412,7 +429,7 @@ static void node_update_hidden(bNode *node) int totin = 0, totout = 0, tot; /* get "global" coords */ - nodeToView(node, 0.0f, 0.0f, &locx, &locy); + node_to_view(node, 0.0f, 0.0f, &locx, &locy); /* calculate minimal radius */ for (nsock = node->inputs.first; nsock; nsock = nsock->next) @@ -700,7 +717,7 @@ static void node_draw_basis(const bContext *C, ARegion *ar, SpaceNode *snode, bN uiRoundBox(rct->xmin, rct->ymax - NODE_DY, rct->xmax, rct->ymax, BASIS_RAD); /* show/hide icons */ - iconofs = rct->xmax - 7.0f; + iconofs = rct->xmax - 0.35f * U.widget_unit; /* preview */ if (node->typeinfo->flag & NODE_PREVIEW) { @@ -742,13 +759,13 @@ static void node_draw_basis(const bContext *C, ARegion *ar, SpaceNode *snode, bN /* XXX button uses a custom triangle draw below, so make it invisible without icon */ uiBlockSetEmboss(node->block, UI_EMBOSSN); but = uiDefBut(node->block, TOGBUT, B_REDR, "", - rct->xmin + 10.0f - but_size / 2, rct->ymax - NODE_DY / 2.0f - but_size / 2, + rct->xmin + 0.5f * U.widget_unit - but_size / 2, rct->ymax - NODE_DY / 2.0f - but_size / 2, but_size, but_size, NULL, 0, 0, 0, 0, ""); uiButSetFunc(but, node_toggle_button_cb, node, (void *)"NODE_OT_hide_toggle"); uiBlockSetEmboss(node->block, UI_EMBOSS); /* custom draw function for this button */ - UI_DrawTriIcon(rct->xmin + 10.0f, rct->ymax - NODE_DY / 2.0f, 'v'); + UI_DrawTriIcon(rct->xmin + 0.5f * U.widget_unit, rct->ymax - NODE_DY / 2.0f, 'v'); } /* this isn't doing anything for the label, so commenting out */ @@ -765,7 +782,7 @@ static void node_draw_basis(const bContext *C, ARegion *ar, SpaceNode *snode, bN // BLI_snprintf(showname, sizeof(showname), "[%s]", showname); /* XXX - don't print into self! */ uiDefBut(node->block, LABEL, 0, showname, - (int)(rct->xmin + (NODE_MARGIN_X / snode->aspect_sqrt)), (int)(rct->ymax - NODE_DY), + (int)(rct->xmin + (NODE_MARGIN_X)), (int)(rct->ymax - NODE_DY), (short)(iconofs - rct->xmin - 18.0f), (short)NODE_DY, NULL, 0, 0, 0, 0, ""); @@ -808,8 +825,8 @@ static void node_draw_basis(const bContext *C, ARegion *ar, SpaceNode *snode, bN node_socket_circle_draw(ntree, sock, NODE_SOCKSIZE, sock->flag & SELECT); node->typeinfo->drawinputfunc(C, node->block, ntree, node, sock, IFACE_(sock->name), - sock->locx + (NODE_DYS / snode->aspect_sqrt), sock->locy - NODE_DYS, - node->width - NODE_DY); + sock->locx + (NODE_DYS), sock->locy - NODE_DYS, + NODE_WIDTH(node) - NODE_DY); } /* socket outputs */ @@ -820,8 +837,8 @@ static void node_draw_basis(const bContext *C, ARegion *ar, SpaceNode *snode, bN node_socket_circle_draw(ntree, sock, NODE_SOCKSIZE, sock->flag & SELECT); node->typeinfo->drawoutputfunc(C, node->block, ntree, node, sock, IFACE_(sock->name), - sock->locx - node->width + (NODE_DYS / snode->aspect_sqrt), sock->locy - NODE_DYS, - node->width - NODE_DY); + sock->locx - NODE_WIDTH(node) + (NODE_DYS), sock->locy - NODE_DYS, + NODE_WIDTH(node) - NODE_DY); } /* preview */ @@ -843,7 +860,7 @@ static void node_draw_hidden(const bContext *C, ARegion *ar, SpaceNode *snode, b rctf *rct = &node->totr; float dx, centy = BLI_rctf_cent_y(rct); float hiddenrad = BLI_rctf_size_y(rct) / 2.0f; - float socket_size = NODE_SOCKSIZE * UI_DPI_ICON_FAC; + float socket_size = NODE_SOCKSIZE; int color_id = node_get_colorid(node); char showname[128]; /* 128 is used below */ @@ -920,7 +937,7 @@ static void node_draw_hidden(const bContext *C, ARegion *ar, SpaceNode *snode, b // BLI_snprintf(showname, sizeof(showname), "[%s]", showname); /* XXX - don't print into self! */ uiDefBut(node->block, LABEL, 0, showname, - (int)(rct->xmin + (NODE_MARGIN_X / snode->aspect_sqrt)), (int)(centy - 10), + (int)(rct->xmin + (NODE_MARGIN_X)), (int)(centy - 10), (short)(BLI_rctf_size_x(rct) - 18.0f - 12.0f), (short)NODE_DY, NULL, 0, 0, 0, 0, ""); } @@ -1011,7 +1028,7 @@ void node_update_nodetree(const bContext *C, bNodeTree *ntree, float offsetx, fl /* update nodes front to back, so children sizes get updated before parents */ for (node = ntree->nodes.last; node; node = node->prev) { - /* XXX little hack */ + /* XXX little hack (not used anyore?) */ node->locx += offsetx; node->locy += offsety; @@ -1082,7 +1099,7 @@ void drawnodespace(const bContext *C, ARegion *ar, View2D *v2d) SpaceNode *snode = CTX_wm_space_node(C); bNodeLinkDrag *nldrag; LinkData *linkdata; - + UI_ThemeClearColor(TH_BACK); glClear(GL_COLOR_BUFFER_BIT); @@ -1098,11 +1115,10 @@ void drawnodespace(const bContext *C, ARegion *ar, View2D *v2d) /* aspect+font, set each time */ snode->aspect = BLI_rctf_size_x(&v2d->cur) / (float)ar->winx; - snode->aspect_sqrt = sqrtf(snode->aspect); // XXX snode->curfont = uiSetCurFont_ext(snode->aspect); /* grid */ - UI_view2d_multi_grid_draw(v2d, 25.0f, 5, 2); + UI_view2d_multi_grid_draw(v2d, U.widget_unit, 5, 2); /* backdrop */ draw_nodespace_back_pix(C, ar, snode); diff --git a/source/blender/editors/space_node/node_edit.c b/source/blender/editors/space_node/node_edit.c index f757345bdcb..ae95d9ae074 100644 --- a/source/blender/editors/space_node/node_edit.c +++ b/source/blender/editors/space_node/node_edit.c @@ -874,8 +874,8 @@ static int node_resize_modal(bContext *C, wmOperator *op, wmEvent *event) case MOUSEMOVE: UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &mx, &my); - dx = mx - nsw->mxstart; - dy = my - nsw->mystart; + dx = (mx - nsw->mxstart) / UI_DPI_FAC; + dy = (my - nsw->mystart) / UI_DPI_FAC; if (node) { if (node->flag & NODE_HIDDEN) { @@ -894,8 +894,8 @@ static int node_resize_modal(bContext *C, wmOperator *op, wmEvent *event) } } else { - float widthmin = UI_DPI_FAC * node->typeinfo->minwidth; - float widthmax = UI_DPI_FAC * node->typeinfo->maxwidth; + float widthmin = node->typeinfo->minwidth; + float widthmax = node->typeinfo->maxwidth; if (nsw->directions & NODE_RESIZE_RIGHT) { node->width = nsw->oldwidth + dx; CLAMP(node->width, widthmin, widthmax); @@ -1967,7 +1967,7 @@ static int node_clipboard_copy_exec(bContext *C, wmOperator *UNUSED(op)) /* get group node offset */ if (gnode) - nodeToView(gnode, 0.0f, 0.0f, &gnode_x, &gnode_y); + node_to_view(gnode, 0.0f, 0.0f, &gnode_x, &gnode_y); for (node = ntree->nodes.first; node; node = node->next) { if (node->flag & SELECT) { @@ -2080,7 +2080,7 @@ static int node_clipboard_paste_exec(bContext *C, wmOperator *op) /* get group node offset */ if (gnode) { - nodeToView(gnode, 0.0f, 0.0f, &gnode_center[0], &gnode_center[1]); + node_to_view(gnode, 0.0f, 0.0f, &gnode_center[0], &gnode_center[1]); } else { zero_v2(gnode_center); diff --git a/source/blender/editors/space_node/node_intern.h b/source/blender/editors/space_node/node_intern.h index 671c4fde709..e8dd1cf1528 100644 --- a/source/blender/editors/space_node/node_intern.h +++ b/source/blender/editors/space_node/node_intern.h @@ -48,6 +48,7 @@ struct bNode; struct bNodeSocket; struct bNodeLink; struct Main; +struct wmKeyConfig; /* temp data to pass on to modal */ typedef struct bNodeLinkDrag { @@ -82,6 +83,9 @@ void node_draw_nodetree(const struct bContext *C, struct ARegion *ar, struct Spa void drawnodespace(const bContext *C, ARegion *ar, View2D *v2d); void node_set_cursor(struct wmWindow *win, struct SpaceNode *snode); + /* DPI scaled coords */ +void node_to_view(struct bNode *node, float x, float y, float *rx, float *ry); +void node_from_view(struct bNode *node, float x, float y, float *rx, float *ry); /* node_buttons.c */ void node_buttons_register(struct ARegionType *art); @@ -93,7 +97,7 @@ void NODE_OT_toolbar(struct wmOperatorType *ot); /* node_ops.c */ void node_operatortypes(void); -void node_keymap(wmKeyConfig *keyconf); +void node_keymap(struct wmKeyConfig *keyconf); /* node_select.c */ void node_select(struct bNode *node); @@ -108,14 +112,14 @@ int node_select_same_type_np(struct SpaceNode *snode, int dir); void node_select_single(struct bContext *C, struct bNode *node); void NODE_OT_select(struct wmOperatorType *ot); -void NODE_OT_select_all(wmOperatorType *ot); -void NODE_OT_select_linked_to(wmOperatorType *ot); -void NODE_OT_select_linked_from(wmOperatorType *ot); +void NODE_OT_select_all(struct wmOperatorType *ot); +void NODE_OT_select_linked_to(struct wmOperatorType *ot); +void NODE_OT_select_linked_from(struct wmOperatorType *ot); void NODE_OT_select_border(struct wmOperatorType *ot); void NODE_OT_select_lasso(struct wmOperatorType *ot); void NODE_OT_select_same_type(struct wmOperatorType *ot); -void NODE_OT_select_same_type_next(wmOperatorType *ot); -void NODE_OT_select_same_type_prev(wmOperatorType *ot); +void NODE_OT_select_same_type_next(struct wmOperatorType *ot); +void NODE_OT_select_same_type_prev(struct wmOperatorType *ot); /* node_view.c */ void NODE_OT_view_all(struct wmOperatorType *ot); @@ -123,14 +127,14 @@ void NODE_OT_view_selected(struct wmOperatorType *ot); void NODE_OT_backimage_move(struct wmOperatorType *ot); void NODE_OT_backimage_zoom(struct wmOperatorType *ot); -void NODE_OT_backimage_sample(wmOperatorType *ot); +void NODE_OT_backimage_sample(struct wmOperatorType *ot); /* drawnode.c */ -void node_draw_link(View2D *v2d, SpaceNode *snode, bNodeLink *link); -void node_draw_link_bezier(View2D *v2d, SpaceNode *snode, bNodeLink *link, int th_col1, int do_shaded, int th_col2, int do_triple, int th_col3); -int node_link_bezier_points(View2D * v2d, SpaceNode * snode, bNodeLink * link, float coord_array[][2], int resol); +void node_draw_link(struct View2D *v2d, struct SpaceNode *snode, struct bNodeLink *link); +void node_draw_link_bezier(struct View2D *v2d, struct SpaceNode *snode, struct bNodeLink *link, int th_col1, int do_shaded, int th_col2, int do_triple, int th_col3); +int node_link_bezier_points(struct View2D * v2d, struct SpaceNode * snode, struct bNodeLink * link, float coord_array[][2], int resol); // void node_draw_link_straight(View2D *v2d, SpaceNode *snode, bNodeLink *link, int th_col1, int do_shaded, int th_col2, int do_triple, int th_col3 ); -void draw_nodespace_back_pix(const struct bContext *C, ARegion *ar, SpaceNode *snode); +void draw_nodespace_back_pix(const struct bContext *C, struct ARegion *ar, struct SpaceNode *snode); /* node_add.c */ @@ -172,10 +176,10 @@ void NODE_OT_link_viewer(struct wmOperatorType *ot); /* node_edit.c */ void node_tree_from_ID(ID *id, bNodeTree **ntree, bNodeTree **edittree, int *treetype); -void snode_notify(bContext *C, SpaceNode *snode); -void snode_dag_update(bContext *C, SpaceNode *snode); -void snode_set_context(SpaceNode *snode, Scene *scene); -void snode_make_group_editable(SpaceNode *snode, bNode *gnode); +void snode_notify(struct bContext *C, struct SpaceNode *snode); +void snode_dag_update(struct bContext *C, struct SpaceNode *snode); +void snode_set_context(struct SpaceNode *snode, Scene *scene); +void snode_make_group_editable(struct SpaceNode *snode, struct bNode *gnode); bNode *node_tree_get_editgroup(bNodeTree *ntree); void snode_update(struct SpaceNode *snode, struct bNode *node); @@ -184,7 +188,7 @@ int composite_node_active(struct bContext *C); int node_has_hidden_sockets(bNode *node); void node_set_hidden_sockets(SpaceNode *snode, bNode *node, int set); -int node_render_changed_exec(bContext *, wmOperator *); +int node_render_changed_exec(bContext *, struct wmOperator *); int node_find_indicated_socket(struct SpaceNode *snode, struct bNode **nodep, struct bNodeSocket **sockp, int in_out); void NODE_OT_duplicate(struct wmOperatorType *ot); @@ -217,13 +221,14 @@ extern const char *node_context_dir[]; // XXXXXX -// XXX from BSE_node.h -#define HIDDEN_RAD 15.0f -#define BASIS_RAD 8.0f +// nodes draw without dpi - the view zoom is flexible +#define HIDDEN_RAD (0.75f * U.widget_unit) +#define BASIS_RAD (0.4f * U.widget_unit) #define NODE_DYS (U.widget_unit / 2) #define NODE_DY U.widget_unit -#define NODE_MARGIN_X 15 -#define NODE_SOCKSIZE 5 +#define NODE_WIDTH(node) (node->width * UI_DPI_FAC) +#define NODE_MARGIN_X (0.75f * U.widget_unit) +#define NODE_SOCKSIZE (0.25f * U.widget_unit) #define NODE_LINK_RESOL 12 // XXX button events (butspace) diff --git a/source/blender/editors/space_node/node_templates.c b/source/blender/editors/space_node/node_templates.c index 23f4e948794..ca85415cb5a 100644 --- a/source/blender/editors/space_node/node_templates.c +++ b/source/blender/editors/space_node/node_templates.c @@ -30,6 +30,7 @@ #include "DNA_node_types.h" #include "DNA_screen_types.h" +#include "DNA_space_types.h" #include "BLI_listbase.h" #include "BLI_string.h" @@ -52,6 +53,8 @@ #include "ED_util.h" +#include "node_intern.h" + /************************* Node Socket Manipulation **************************/ static void node_tag_recursive(bNode *node) diff --git a/source/blender/editors/space_node/space_node.c b/source/blender/editors/space_node/space_node.c index 0e015a4477c..fe880a7592b 100644 --- a/source/blender/editors/space_node/space_node.c +++ b/source/blender/editors/space_node/space_node.c @@ -142,15 +142,12 @@ static SpaceLink *node_new(const bContext *UNUSED(C)) BLI_addtail(&snode->regionbase, ar); ar->regiontype = RGN_TYPE_WINDOW; - ar->v2d.tot.xmin = -256.0f; - ar->v2d.tot.ymin = -256.0f; - ar->v2d.tot.xmax = 768.0f; - ar->v2d.tot.ymax = 768.0f; + ar->v2d.tot.xmin = -12.8f * U.widget_unit; + ar->v2d.tot.ymin = -12.8f * U.widget_unit; + ar->v2d.tot.xmax = 38.4f * U.widget_unit; + ar->v2d.tot.ymax = 38.4f * U.widget_unit; - ar->v2d.cur.xmin = -256.0f; - ar->v2d.cur.ymin = -256.0f; - ar->v2d.cur.xmax = 768.0f; - ar->v2d.cur.ymax = 768.0f; + ar->v2d.cur = ar->v2d.tot; ar->v2d.min[0] = 1.0f; ar->v2d.min[1] = 1.0f; diff --git a/source/blender/editors/space_outliner/outliner_draw.c b/source/blender/editors/space_outliner/outliner_draw.c index d37cb4be8fa..911902d275d 100644 --- a/source/blender/editors/space_outliner/outliner_draw.c +++ b/source/blender/editors/space_outliner/outliner_draw.c @@ -893,7 +893,7 @@ static void outliner_buttons(const bContext *C, uiBlock *block, ARegion *ar, Spa struct DrawIconArg { uiBlock *block; ID *id; - int xmax, x, y; + float xmax, x, y, xb, yb; float alpha; }; @@ -902,13 +902,11 @@ static void tselem_draw_icon_uibut(struct DrawIconArg *arg, int icon) /* restrict column clip... it has been coded by simply overdrawing, doesnt work for buttons */ if (arg->x >= arg->xmax) { glEnable(GL_BLEND); - UI_icon_draw_aspect(arg->x, arg->y, icon, 1.0f, arg->alpha); + UI_icon_draw_aspect(arg->x, arg->y, icon, 1.0f / UI_DPI_ICON_FAC, arg->alpha); glDisable(GL_BLEND); } else { - /* XXX investigate: button placement of icons is way different than UI_icon_draw? */ - float ufac = UI_UNIT_X / 20.0f; - uiBut *but = uiDefIconBut(arg->block, LABEL, 0, icon, arg->x - 3.0f * ufac, arg->y, UI_UNIT_X - 4.0f * ufac, UI_UNIT_Y - 4.0f * ufac, NULL, 0.0, 0.0, 1.0, arg->alpha, (arg->id && arg->id->lib) ? arg->id->lib->name : ""); + uiBut *but = uiDefIconBut(arg->block, LABEL, 0, icon, arg->xb, arg->yb, UI_UNIT_X, UI_UNIT_Y, NULL, 0.0, 0.0, 1.0, arg->alpha, (arg->id && arg->id->lib) ? arg->id->lib->name : ""); if (arg->id) uiButSetDragID(but, arg->id); @@ -919,15 +917,24 @@ static void tselem_draw_icon_uibut(struct DrawIconArg *arg, int icon) static void tselem_draw_icon(uiBlock *block, int xmax, float x, float y, TreeStoreElem *tselem, TreeElement *te, float alpha) { struct DrawIconArg arg; + float aspect; + + /* icons tiny bit away from text */ + x -= 0.15f * UI_UNIT_Y; /* make function calls a bit compacter */ arg.block = block; arg.id = tselem->id; arg.xmax = xmax; - arg.x = x; - arg.y = y; + arg.xb = x; /* for ui buttons */ + arg.yb = y; arg.alpha = alpha; + /* placement of icons, copied from interface_widgets.c */ + aspect = (0.8f * UI_UNIT_Y) / ICON_DEFAULT_HEIGHT; + arg.x = x = x + 4.0f * aspect; + arg.y = y = y + 0.1f * UI_UNIT_Y; + if (tselem->type) { switch (tselem->type) { case TSE_ANIM_DATA: @@ -1220,10 +1227,10 @@ static void outliner_draw_iconrow(bContext *C, uiBlock *block, Scene *scene, Spa uiSetRoundBox(UI_CNR_ALL); glColor4ub(255, 255, 255, 100); - uiRoundBox((float) *offsx - 0.5f * ufac, - (float)ys - 1.0f * ufac, - (float)*offsx + UI_UNIT_Y - 3.0f * ufac, - (float)ys + UI_UNIT_Y - 3.0f * ufac, + uiRoundBox((float) *offsx - 1.5f * ufac, + (float)ys + 2.0f * ufac, + (float)*offsx + UI_UNIT_X - 3.0f * ufac, + (float)ys + UI_UNIT_Y - 1.0f * ufac, (float)UI_UNIT_Y / 2.0f - 2.0f * ufac); glEnable(GL_BLEND); /* roundbox disables */ } @@ -1355,9 +1362,9 @@ static void outliner_draw_tree_element(bContext *C, uiBlock *block, Scene *scene /* active circle */ if (active) { uiSetRoundBox(UI_CNR_ALL); - uiRoundBox((float)startx + UI_UNIT_Y - 1.5f * ufac, + uiRoundBox((float)startx + UI_UNIT_X - 1.5f * ufac, (float)*starty + 2.0f * ufac, - (float)startx + 2.0f * UI_UNIT_Y - 4.0f * ufac, + (float)startx + 2.0f * UI_UNIT_X - 3.0f * ufac, (float)*starty + UI_UNIT_Y - 1.0f * ufac, UI_UNIT_Y / 2.0f - 2.0f * ufac); glEnable(GL_BLEND); /* roundbox disables it */ @@ -1384,8 +1391,8 @@ static void outliner_draw_tree_element(bContext *C, uiBlock *block, Scene *scene /* datatype icon */ if (!(ELEM(tselem->type, TSE_RNA_PROPERTY, TSE_RNA_ARRAY_ELEM))) { - // icons a bit higher - tselem_draw_icon(block, xmax, (float)startx + offsx - 0.5f * ufac, (float)*starty + 2.0f * ufac, tselem, te, 1.0f); + + tselem_draw_icon(block, xmax, (float)startx + offsx, (float)*starty, tselem, te, 1.0f); offsx += UI_UNIT_X; } @@ -1425,12 +1432,12 @@ static void outliner_draw_tree_element(bContext *C, uiBlock *block, Scene *scene /* divider */ UI_ThemeColorShade(TH_BACK, -40); - glRecti(tempx - 10, *starty + 4, tempx - 8, *starty + UI_UNIT_Y - 4); + glRecti(tempx - 10.0 * ufac, *starty + 4.0f * ufac, tempx - 8.0f * ufac, *starty + UI_UNIT_Y - 4.0f * ufac); glEnable(GL_BLEND); glPixelTransferf(GL_ALPHA_SCALE, 0.5); - outliner_draw_iconrow(C, block, scene, soops, &te->subtree, 0, xmax, &tempx, *starty + 2); + outliner_draw_iconrow(C, block, scene, soops, &te->subtree, 0, xmax, &tempx, *starty); glPixelTransferf(GL_ALPHA_SCALE, 1.0); glDisable(GL_BLEND); @@ -1625,7 +1632,7 @@ static void outliner_draw_restrictcols(ARegion *ar) /* ****************************************************** */ /* Main Entrypoint - Draw contents of Outliner editor */ - + void draw_outliner(const bContext *C) { Main *mainvar = CTX_data_main(C); @@ -1635,8 +1642,8 @@ void draw_outliner(const bContext *C) SpaceOops *soops = CTX_wm_space_outliner(C); uiBlock *block; int sizey = 0, sizex = 0, sizex_rna = 0; - - outliner_build_tree(mainvar, scene, soops); // always + + outliner_build_tree(mainvar, scene, soops); // always /* get extents of data */ outliner_height(soops, &soops->tree, &sizey); @@ -1709,7 +1716,7 @@ void draw_outliner(const bContext *C) uiEndBlock(C, block); uiDrawBlock(C, block); - + /* clear flag that allows quick redraws */ soops->storeflag &= ~SO_TREESTORE_REDRAW; } diff --git a/source/blender/editors/space_text/text_draw.c b/source/blender/editors/space_text/text_draw.c index 46ab2d9e688..9a448cfda13 100644 --- a/source/blender/editors/space_text/text_draw.c +++ b/source/blender/editors/space_text/text_draw.c @@ -65,7 +65,7 @@ static void text_font_begin(SpaceText *st) { - BLF_size(mono, st->lheight, 72); + BLF_size(mono, st->lheight_dpi, 72); } static void text_font_end(SpaceText *UNUSED(st)) @@ -734,7 +734,7 @@ static int text_draw_wrapped(SpaceText *st, const char *str, int x, int y, int w if (st->showsyntax && format) format_draw_color(format[a]); x += text_font_draw_character_utf8(st, x, y, str + ma); } - y -= st->lheight + TXT_LINE_SPACING; + y -= st->lheight_dpi + TXT_LINE_SPACING; x = basex; lines++; start = end; mstart = mend; @@ -852,7 +852,7 @@ static void text_update_drawcache(SpaceText *st, ARegion *ar) full_update |= drawcache->wordwrap != st->wordwrap; /* word-wrapping option was toggled */ full_update |= drawcache->showlinenrs != st->showlinenrs; /* word-wrapping option was toggled */ full_update |= drawcache->tabnumber != st->tabnumber; /* word-wrapping option was toggled */ - full_update |= drawcache->lheight != st->lheight; /* word-wrapping option was toggled */ + full_update |= drawcache->lheight != st->lheight_dpi; /* word-wrapping option was toggled */ full_update |= drawcache->cwidth != st->cwidth; /* word-wrapping option was toggled */ full_update |= strncmp(drawcache->text_id, txt->id.name, MAX_ID_NAME); /* text datablock was changed */ @@ -928,7 +928,7 @@ static void text_update_drawcache(SpaceText *st, ARegion *ar) /* store settings */ drawcache->winx = ar->winx; drawcache->wordwrap = st->wordwrap; - drawcache->lheight = st->lheight; + drawcache->lheight = st->lheight_dpi; drawcache->cwidth = st->cwidth; drawcache->showlinenrs = st->showlinenrs; drawcache->tabnumber = st->tabnumber; @@ -1237,9 +1237,9 @@ static void draw_documentation(SpaceText *st, ARegion *ar) x += SUGG_LIST_WIDTH * st->cwidth + 50; } - /* top = */ /* UNUSED */ y = ar->winy - st->lheight * l - 2; + /* top = */ /* UNUSED */ y = ar->winy - st->lheight_dpi * l - 2; boxw = DOC_WIDTH * st->cwidth + 20; - boxh = (DOC_HEIGHT + 1) * st->lheight; + boxh = (DOC_HEIGHT + 1) * st->lheight_dpi; /* Draw panel */ UI_ThemeColor(TH_BACK); @@ -1271,7 +1271,7 @@ static void draw_documentation(SpaceText *st, ARegion *ar) else if (*p == '\n') { buf[i] = '\0'; if (lines >= 0) { - y -= st->lheight; + y -= st->lheight_dpi; text_draw(st, buf, 0, 0, 1, x + 4, y - 3, NULL); } i = 0; br = DOC_WIDTH; lines++; @@ -1280,7 +1280,7 @@ static void draw_documentation(SpaceText *st, ARegion *ar) if (i == DOC_WIDTH) { /* Reached the width, go to last break and wrap there */ buf[br] = '\0'; if (lines >= 0) { - y -= st->lheight; + y -= st->lheight_dpi; text_draw(st, buf, 0, 0, 1, x + 4, y - 3, NULL); } p -= i - br - 1; /* Rewind pointer to last break */ @@ -1326,10 +1326,10 @@ static void draw_suggestion_list(SpaceText *st, ARegion *ar) else { x = st->cwidth * (st->text->curc - st->left) + TXT_OFFSET - 4; } - y = ar->winy - st->lheight * l - 2; + y = ar->winy - st->lheight_dpi * l - 2; boxw = SUGG_LIST_WIDTH * st->cwidth + 20; - boxh = SUGG_LIST_SIZE * st->lheight + 8; + boxh = SUGG_LIST_SIZE * st->lheight_dpi + 8; UI_ThemeColor(TH_SHADE1); glRecti(x - 1, y + 1, x + boxw + 1, y - boxh - 1); @@ -1341,7 +1341,7 @@ static void draw_suggestion_list(SpaceText *st, ARegion *ar) for (i = 0; i < SUGG_LIST_SIZE && item; i++, item = item->next) { - y -= st->lheight; + y -= st->lheight_dpi; BLI_strncpy(str, item->name, SUGG_LIST_WIDTH); @@ -1349,7 +1349,7 @@ static void draw_suggestion_list(SpaceText *st, ARegion *ar) if (item == sel) { UI_ThemeColor(TH_SHADE2); - glRecti(x + 16, y - 3, x + 16 + w, y + st->lheight - 3); + glRecti(x + 16, y - 3, x + 16 + w, y + st->lheight_dpi - 3); } b = 1; /* b=1 color block, text is default. b=0 no block, color text */ switch (item->type) { @@ -1376,7 +1376,7 @@ static void draw_cursor(SpaceText *st, ARegion *ar) Text *text = st->text; int vcurl, vcurc, vsell, vselc, hidden = 0; int x, y, w, i; - int lheight = st->lheight + TXT_LINE_SPACING; + int lheight = st->lheight_dpi + TXT_LINE_SPACING; /* Draw the selection */ if (text->curl != text->sell || text->curc != text->selc) { @@ -1588,7 +1588,7 @@ static void draw_brackets(SpaceText *st, ARegion *ar) UI_ThemeColor(TH_HILITE); x = st->showlinenrs ? TXT_OFFSET + TEXTXLOC : TXT_OFFSET; - y = ar->winy - st->lheight; + y = ar->winy - st->lheight_dpi; /* draw opening bracket */ ch = startl->line[startc]; @@ -1598,8 +1598,8 @@ static void draw_brackets(SpaceText *st, ARegion *ar) if (viewc >= 0) { viewl = txt_get_span(text->lines.first, startl) - st->top + offl; - text_font_draw_character(st, x + viewc * st->cwidth, y - viewl * (st->lheight + TXT_LINE_SPACING), ch); - text_font_draw_character(st, x + viewc * st->cwidth + 1, y - viewl * (st->lheight + TXT_LINE_SPACING), ch); + text_font_draw_character(st, x + viewc * st->cwidth, y - viewl * (st->lheight_dpi + TXT_LINE_SPACING), ch); + text_font_draw_character(st, x + viewc * st->cwidth + 1, y - viewl * (st->lheight_dpi + TXT_LINE_SPACING), ch); } /* draw closing bracket */ @@ -1610,8 +1610,8 @@ static void draw_brackets(SpaceText *st, ARegion *ar) if (viewc >= 0) { viewl = txt_get_span(text->lines.first, endl) - st->top + offl; - text_font_draw_character(st, x + viewc * st->cwidth, y - viewl * (st->lheight + TXT_LINE_SPACING), ch); - text_font_draw_character(st, x + viewc * st->cwidth + 1, y - viewl * (st->lheight + TXT_LINE_SPACING), ch); + text_font_draw_character(st, x + viewc * st->cwidth, y - viewl * (st->lheight_dpi + TXT_LINE_SPACING), ch); + text_font_draw_character(st, x + viewc * st->cwidth + 1, y - viewl * (st->lheight_dpi + TXT_LINE_SPACING), ch); } } @@ -1627,7 +1627,10 @@ void draw_text_main(SpaceText *st, ARegion *ar) int wraplinecount = 0, wrap_skip = 0; int margin_column_x; - if (st->lheight) st->viewlines = (int)ar->winy / (st->lheight + TXT_LINE_SPACING); + /* dpi controlled line height and font size */ + st->lheight_dpi = (U.widget_unit * st->lheight) / 20; + + if (st->lheight_dpi) st->viewlines = (int)ar->winy / (st->lheight_dpi + TXT_LINE_SPACING); else st->viewlines = 0; /* if no text, nothing to do */ @@ -1686,7 +1689,7 @@ void draw_text_main(SpaceText *st, ARegion *ar) st->linenrs_tot = 0; /* not used */ x = TXT_OFFSET; } - y = ar->winy - st->lheight; + y = ar->winy - st->lheight_dpi; winx = ar->winx - TXT_SCROLL_WIDTH; /* draw cursor */ @@ -1716,12 +1719,12 @@ void draw_text_main(SpaceText *st, ARegion *ar) if (st->wordwrap) { /* draw word wrapped text */ int lines = text_draw_wrapped(st, tmp->line, x, y, winx - x, tmp->format, wrap_skip); - y -= lines * (st->lheight + TXT_LINE_SPACING); + y -= lines * (st->lheight_dpi + TXT_LINE_SPACING); } else { /* draw unwrapped text */ text_draw(st, tmp->line, st->left, ar->winx / st->cwidth, 1, x, y, tmp->format); - y -= st->lheight + TXT_LINE_SPACING; + y -= st->lheight_dpi + TXT_LINE_SPACING; } wrap_skip = 0; diff --git a/source/blender/editors/space_text/text_intern.h b/source/blender/editors/space_text/text_intern.h index ea61644cee9..6d3b184f6cf 100644 --- a/source/blender/editors/space_text/text_intern.h +++ b/source/blender/editors/space_text/text_intern.h @@ -54,12 +54,11 @@ void text_scroll_to_cursor(struct SpaceText *st, struct ScrArea *sa); void text_update_cursor_moved(struct bContext *C); /* TXT_OFFSET used to be 35 when the scrollbar was on the left... */ -#define TXT_OFFSET 15 -#define TXT_SCROLL_WIDTH 20 -#define TXT_SCROLL_SPACE 2 -#define TXT_LINE_SPACING 4 /* space between lines */ - -#define TEXTXLOC (st->cwidth * st->linenrs_tot) +#define TXT_OFFSET ((int)(0.75f * U.widget_unit)) +#define TXT_SCROLL_WIDTH U.widget_unit +#define TXT_SCROLL_SPACE ((int)(0.1f * U.widget_unit)) +#define TXT_LINE_SPACING ((int)(0.2f * U.widget_unit)) /* space between lines */ +#define TEXTXLOC (st->cwidth * st->linenrs_tot) #define SUGG_LIST_SIZE 7 #define SUGG_LIST_WIDTH 20 diff --git a/source/blender/editors/space_text/text_ops.c b/source/blender/editors/space_text/text_ops.c index 5b7f92739ed..83a1bfee0d8 100644 --- a/source/blender/editors/space_text/text_ops.c +++ b/source/blender/editors/space_text/text_ops.c @@ -2106,10 +2106,10 @@ static void text_scroll_apply(bContext *C, wmOperator *op, wmEvent *event) if (!tsc->scrollbar) { txtdelta[0] = -tsc->delta[0] / st->cwidth; - txtdelta[1] = tsc->delta[1] / (st->lheight + TXT_LINE_SPACING); + txtdelta[1] = tsc->delta[1] / (st->lheight_dpi + TXT_LINE_SPACING); tsc->delta[0] %= st->cwidth; - tsc->delta[1] %= (st->lheight + TXT_LINE_SPACING); + tsc->delta[1] %= (st->lheight_dpi + TXT_LINE_SPACING); } else { txtdelta[1] = -tsc->delta[1] * st->pix_per_line; @@ -2204,7 +2204,7 @@ static int text_scroll_invoke(bContext *C, wmOperator *op, wmEvent *event) tsc->old[1] = event->y; /* Sensitivity of scroll set to 4pix per line/char */ tsc->delta[0] = (event->x - event->prevx) * st->cwidth / 4; - tsc->delta[1] = (event->y - event->prevy) * st->lheight / 4; + tsc->delta[1] = (event->y - event->prevy) * st->lheight_dpi / 4; tsc->first = 0; tsc->scrollbar = 0; text_scroll_apply(C, op, event); @@ -2503,7 +2503,7 @@ static void text_cursor_set_to_pos(SpaceText *st, ARegion *ar, int x, int y, int { Text *text = st->text; text_update_character_width(st); - y = (ar->winy - 2 - y) / (st->lheight + TXT_LINE_SPACING); + y = (ar->winy - 2 - y) / (st->lheight_dpi + TXT_LINE_SPACING); if (st->showlinenrs) x -= TXT_OFFSET + TEXTXLOC; else x -= TXT_OFFSET; diff --git a/source/blender/editors/space_text/text_python.c b/source/blender/editors/space_text/text_python.c index 4c9b4b900cc..a06144b8260 100644 --- a/source/blender/editors/space_text/text_python.c +++ b/source/blender/editors/space_text/text_python.c @@ -36,7 +36,9 @@ #include "DNA_screen_types.h" #include "DNA_space_types.h" #include "DNA_text_types.h" +#include "DNA_userdef_types.h" +#include "BKE_blender.h" #include "BKE_suggestions.h" #include "BKE_text.h" @@ -78,10 +80,10 @@ int text_do_suggest_select(SpaceText *st, ARegion *ar) else { x = st->cwidth * (st->text->curc - st->left) + TXT_OFFSET - 4; } - y = ar->winy - st->lheight * l - 2; + y = ar->winy - st->lheight_dpi * l - 2; - w = SUGG_LIST_WIDTH * st->cwidth + 20; - h = SUGG_LIST_SIZE * st->lheight + 8; + w = SUGG_LIST_WIDTH * st->cwidth + U.widget_unit; + h = SUGG_LIST_SIZE * st->lheight_dpi + 0.4f * U.widget_unit; // XXX getmouseco_areawin(mval); @@ -92,7 +94,7 @@ int text_do_suggest_select(SpaceText *st, ARegion *ar) for (i = 0, item = first; i < *top && item->next; i++, item = item->next) ; /* Work out the target item index in the visible list */ - tgti = (y - mval[1] - 4) / st->lheight; + tgti = (y - mval[1] - 4) / st->lheight_dpi; if (tgti < 0 || tgti > SUGG_LIST_SIZE) return 1; diff --git a/source/blender/editors/space_view3d/space_view3d.c b/source/blender/editors/space_view3d/space_view3d.c index 1c31cd23e33..9faefbd4c2b 100644 --- a/source/blender/editors/space_view3d/space_view3d.c +++ b/source/blender/editors/space_view3d/space_view3d.c @@ -117,7 +117,7 @@ ARegion *view3d_has_tools_region(ScrArea *sa) BLI_insertlinkafter(&sa->regionbase, arhead, artool); artool->regiontype = RGN_TYPE_TOOLS; - artool->alignment = RGN_ALIGN_LEFT; //RGN_OVERLAP_LEFT; + artool->alignment = RGN_ALIGN_LEFT; artool->flag = RGN_FLAG_HIDDEN; } diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c index 154eeae8dc8..a5cbe88faf1 100644 --- a/source/blender/editors/space_view3d/view3d_draw.c +++ b/source/blender/editors/space_view3d/view3d_draw.c @@ -563,35 +563,60 @@ static void drawfloor(Scene *scene, View3D *v3d, const char **grid_unit) if (v3d->zbuf && scene->obedit) glDepthMask(1); } +/* checks overlapping region for labels, axes, icons */ +static int draw_name_offset(ARegion *ar) +{ + ARegion *arn = ar; + + /* too lazy to pass on area listbase */ + while (arn->prev) + arn = arn->prev; + + /* check if a region overlaps with the current one */ + for (; arn; arn= arn->next) { + if (ar != arn) + if (ar->winrct.xmin == arn->winrct.xmin) + if (ar->winrct.ymin == arn->winrct.ymin) + return arn->winrct.xmax - arn->winrct.xmin; + } + return 0; +} + + static void drawcursor(Scene *scene, ARegion *ar, View3D *v3d) { int co[2]; /* we don't want the clipping for cursor */ if (ED_view3d_project_int_global(ar, give_cursor(scene, v3d), co, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) { + float f5 = 0.25f * U.widget_unit; + float f10 = 0.5f * U.widget_unit; + float f20 = U.widget_unit; + setlinestyle(0); cpack(0xFF); - circ((float)co[0], (float)co[1], 10.0); - setlinestyle(4); + circ((float)co[0], (float)co[1], f10); + setlinestyle(4); cpack(0xFFFFFF); - circ((float)co[0], (float)co[1], 10.0); + circ((float)co[0], (float)co[1], f10); setlinestyle(0); cpack(0x0); - sdrawline(co[0] - 20, co[1], co[0] - 5, co[1]); - sdrawline(co[0] + 5, co[1], co[0] + 20, co[1]); - sdrawline(co[0], co[1] - 20, co[0], co[1] - 5); - sdrawline(co[0], co[1] + 5, co[0], co[1] + 20); + sdrawline(co[0] - f20, co[1], co[0] - f5, co[1]); + sdrawline(co[0] + f5, co[1], co[0] + f20, co[1]); + sdrawline(co[0], co[1] - f20, co[0], co[1] - f5); + sdrawline(co[0], co[1] + f5, co[0], co[1] + f20); } } /* Draw a live substitute of the view icon, which is always shown * colors copied from transform_manipulator.c, we should keep these matching. */ -static void draw_view_axis(RegionView3D *rv3d) +static void draw_view_axis(ARegion *ar, RegionView3D *rv3d) { const float k = U.rvisize; /* axis size */ const float toll = 0.5; /* used to see when view is quasi-orthogonal */ - const float start = k + 1.0f; /* axis center in screen coordinates, x=y */ + const float startx = k + 1.0f + draw_name_offset(ar); /* axis center in screen coordinates, x=y */ + const float starty = k + 1.0f; float ydisp = 0.0; /* vertical displacement to allow obj info text */ int bright = 25 * (float)U.rvibright + 5; /* axis alpha (rvibright has range 0-10) */ @@ -613,12 +638,12 @@ static void draw_view_axis(RegionView3D *rv3d) UI_ThemeColorShadeAlpha(TH_AXIS_X, 0, bright); glBegin(GL_LINES); - glVertex2f(start, start + ydisp); - glVertex2f(start + dx, start + dy + ydisp); + glVertex2f(startx, starty + ydisp); + glVertex2f(startx + dx, starty + dy + ydisp); glEnd(); if (fabsf(dx) > toll || fabsf(dy) > toll) { - BLF_draw_default_ascii(start + dx + 2, start + dy + ydisp + 2, 0.0f, "x", 1); + BLF_draw_default_ascii(startx + dx + 2, starty + dy + ydisp + 2, 0.0f, "x", 1); } /* BLF_draw_default disables blending */ @@ -633,12 +658,12 @@ static void draw_view_axis(RegionView3D *rv3d) UI_ThemeColorShadeAlpha(TH_AXIS_Y, 0, bright); glBegin(GL_LINES); - glVertex2f(start, start + ydisp); - glVertex2f(start + dx, start + dy + ydisp); + glVertex2f(startx, starty + ydisp); + glVertex2f(startx + dx, starty + dy + ydisp); glEnd(); if (fabsf(dx) > toll || fabsf(dy) > toll) { - BLF_draw_default_ascii(start + dx + 2, start + dy + ydisp + 2, 0.0f, "y", 1); + BLF_draw_default_ascii(startx + dx + 2, starty + dy + ydisp + 2, 0.0f, "y", 1); } glEnable(GL_BLEND); @@ -652,12 +677,12 @@ static void draw_view_axis(RegionView3D *rv3d) UI_ThemeColorShadeAlpha(TH_AXIS_Z, 0, bright); glBegin(GL_LINES); - glVertex2f(start, start + ydisp); - glVertex2f(start + dx, start + dy + ydisp); + glVertex2f(startx, starty + ydisp); + glVertex2f(startx + dx, starty + dy + ydisp); glEnd(); if (fabsf(dx) > toll || fabsf(dy) > toll) { - BLF_draw_default_ascii(start + dx + 2, start + dy + ydisp + 2, 0.0f, "z", 1); + BLF_draw_default_ascii(startx + dx + 2, starty + dy + ydisp + 2, 0.0f, "z", 1); } /* restore line-width */ @@ -770,7 +795,7 @@ static void draw_rotation_guide(RegionView3D *rv3d) glDepthMask(1); } -static void draw_view_icon(RegionView3D *rv3d) +static void draw_view_icon(ARegion *ar, RegionView3D *rv3d) { BIFIconID icon; @@ -785,7 +810,7 @@ static void draw_view_icon(RegionView3D *rv3d) glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - UI_icon_draw(5.0, 5.0, icon); + UI_icon_draw(5.0 + draw_name_offset(ar), 5.0, icon); glDisable(GL_BLEND); } @@ -853,17 +878,17 @@ static void draw_viewport_name(ARegion *ar, View3D *v3d) if (name) { UI_ThemeColor(TH_TEXT_HI); - BLF_draw_default_ascii(22, ar->winy - 17, 0.0f, name, sizeof(tmpstr)); + BLF_draw_default_ascii(U.widget_unit + draw_name_offset(ar), ar->winy - U.widget_unit, 0.0f, name, sizeof(tmpstr)); } } /* draw info beside axes in bottom left-corner: * framenum, object name, bone name (if available), marker name (if available) */ -static void draw_selected_name(Scene *scene, Object *ob) +static void draw_selected_name(ARegion *ar, Scene *scene, Object *ob) { char info[256], *markern; - short offset = 30; + short offset = 30 + draw_name_offset(ar); /* get name of marker on current frame (if available) */ markern = BKE_scene_find_marker_name(scene, CFRA); @@ -946,9 +971,9 @@ static void draw_selected_name(Scene *scene, Object *ob) } if (U.uiflag & USER_SHOW_ROTVIEWICON) - offset = 14 + (U.rvisize * 2); + offset = U.widget_unit + (U.rvisize * 2) + draw_name_offset(ar); - BLF_draw_default(offset, 10, 0.0f, info, sizeof(info)); + BLF_draw_default(offset, 0.5f * U.widget_unit, 0.0f, info, sizeof(info)); } static void view3d_camera_border(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D *rv3d, @@ -1289,7 +1314,6 @@ static void backdrawview3d(Scene *scene, ARegion *ar, View3D *v3d) RegionView3D *rv3d = ar->regiondata; struct Base *base = scene->basact; int multisample_enabled; - rcti winrct; BLI_assert(ar->regiontype == RGN_TYPE_WINDOW); @@ -1338,8 +1362,7 @@ static void backdrawview3d(Scene *scene, ARegion *ar, View3D *v3d) if (multisample_enabled) glDisable(GL_MULTISAMPLE_ARB); - region_scissor_winrct(ar, &winrct); - glScissor(winrct.xmin, winrct.ymin, BLI_rcti_size_x(&winrct), BLI_rcti_size_y(&winrct)); + glScissor(ar->winrct.xmin, ar->winrct.ymin, BLI_rcti_size_x(&ar->winrct), BLI_rcti_size_y(&ar->winrct)); glClearColor(0.0, 0.0, 0.0, 0.0); if (v3d->zbuf) { @@ -2846,7 +2869,7 @@ static void draw_viewport_fps(Scene *scene, ARegion *ar) BLI_snprintf(printable, sizeof(printable), "fps: %i", (int)(fps + 0.5f)); } - BLF_draw_default_ascii(22, ar->winy - 17, 0.0f, printable, sizeof(printable)); + BLF_draw_default_ascii(U.widget_unit, ar->winy - U.widget_unit, 0.0f, printable, sizeof(printable)); } static void view3d_main_area_draw_objects(const bContext *C, ARegion *ar, const char **grid_unit); @@ -3181,13 +3204,13 @@ static void view3d_main_area_draw_info(const bContext *C, ARegion *ar, const cha drawcursor(scene, ar, v3d); if (U.uiflag & USER_SHOW_ROTVIEWICON) - draw_view_axis(rv3d); + draw_view_axis(ar, rv3d); else - draw_view_icon(rv3d); + draw_view_icon(ar, rv3d); ob = OBACT; if (U.uiflag & USER_DRAWVIEWINFO) - draw_selected_name(scene, ob); + draw_selected_name(ar, scene, ob); } if (rv3d->render_engine) { @@ -3211,7 +3234,7 @@ static void view3d_main_area_draw_info(const bContext *C, ARegion *ar, const cha BLI_snprintf(numstr, sizeof(numstr), "%s x %.4g", grid_unit, v3d->grid); } - BLF_draw_default_ascii(22, ar->winy - (USER_SHOW_VIEWPORTNAME ? 40 : 20), 0.0f, + BLF_draw_default_ascii(U.widget_unit, ar->winy - (USER_SHOW_VIEWPORTNAME ? 2 * U.widget_unit : U.widget_unit), 0.0f, numstr[0] ? numstr : grid_unit, sizeof(numstr)); } } diff --git a/source/blender/editors/space_view3d/view3d_edit.c b/source/blender/editors/space_view3d/view3d_edit.c index 3050b7efad2..c46e1aff9ae 100644 --- a/source/blender/editors/space_view3d/view3d_edit.c +++ b/source/blender/editors/space_view3d/view3d_edit.c @@ -1911,7 +1911,7 @@ static int viewzoom_invoke(bContext *C, wmOperator *op, wmEvent *event) viewzoom_exec(C, op); } else { - if (event->type == MOUSEZOOM) { + if (event->type == MOUSEZOOM || event->type == MOUSEPAN) { /* Bypass Zoom invert flag for track pads (pass FALSE always) */ if (U.uiflag & USER_ZOOM_HORIZ) { diff --git a/source/blender/editors/space_view3d/view3d_ops.c b/source/blender/editors/space_view3d/view3d_ops.c index 6105b5e4eb5..244a886646d 100644 --- a/source/blender/editors/space_view3d/view3d_ops.c +++ b/source/blender/editors/space_view3d/view3d_ops.c @@ -39,6 +39,10 @@ #include "DNA_space_types.h" #include "DNA_view3d_types.h" +#include "BKE_blender.h" +#include "BKE_context.h" +#include "BKE_main.h" + #include "BLI_math.h" #include "BLI_blenlib.h" #include "BLI_utildefines.h" @@ -48,10 +52,75 @@ #include "WM_api.h" #include "WM_types.h" +#include "ED_screen.h" #include "ED_transform.h" #include "view3d_intern.h" +/* ************************** copy paste ***************************** */ + +static int view3d_copybuffer_exec(bContext *C, wmOperator *op) +{ + char str[FILE_MAX]; + + BKE_copybuffer_begin(); + + /* context, selection, could be generalized */ + CTX_DATA_BEGIN (C, Object *, ob, selected_objects) + { + BKE_copybuffer_tag_ID(&ob->id); + + } + CTX_DATA_END; + + BLI_make_file_string("/", str, BLI_temporary_dir(), "copybuffer.blend"); + BKE_copybuffer_save(str, op->reports); + + return OPERATOR_FINISHED; +} + +static void VIEW3D_OT_copybuffer(wmOperatorType *ot) +{ + + /* identifiers */ + ot->name = "Copy Selection to Buffer"; + ot->idname = "VIEW3D_OT_copybuffer"; + ot->description = "Selected objects are saved in a temp file"; + + /* api callbacks */ + ot->invoke = WM_operator_confirm; + ot->exec = view3d_copybuffer_exec; + ot->poll = ED_operator_view3d_active; +} + +static int view3d_pastebuffer_exec(bContext *C, wmOperator *op) +{ + char str[FILE_MAX]; + + BLI_make_file_string("/", str, BLI_temporary_dir(), "copybuffer.blend"); + BKE_copybuffer_paste(C, str, op->reports); + + WM_event_add_notifier(C, NC_WINDOW, NULL); + + return OPERATOR_FINISHED; +} + +static void VIEW3D_OT_pastebuffer(wmOperatorType *ot) +{ + + /* identifiers */ + ot->name = "Paste Selection from Buffer"; + ot->idname = "VIEW3D_OT_pastebuffer"; + ot->description = "Contents of copybuffer gets pasted"; + + /* api callbacks */ + ot->invoke = WM_operator_confirm; + ot->exec = view3d_pastebuffer_exec; + ot->poll = ED_operator_view3d_active; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; +} /* ************************** registration **********************************/ @@ -97,6 +166,8 @@ void view3d_operatortypes(void) WM_operatortype_append(VIEW3D_OT_game_start); WM_operatortype_append(VIEW3D_OT_fly); WM_operatortype_append(VIEW3D_OT_layers); + WM_operatortype_append(VIEW3D_OT_copybuffer); + WM_operatortype_append(VIEW3D_OT_pastebuffer); WM_operatortype_append(VIEW3D_OT_properties); WM_operatortype_append(VIEW3D_OT_toolshelf); @@ -153,6 +224,7 @@ void view3d_keymap(wmKeyConfig *keyconf) WM_keymap_add_item(keymap, "VIEW3D_OT_rotate", MOUSEROTATE, 0, 0, 0); WM_keymap_add_item(keymap, "VIEW3D_OT_move", MOUSEPAN, 0, 0, 0); WM_keymap_add_item(keymap, "VIEW3D_OT_zoom", MOUSEZOOM, 0, 0, 0); + WM_keymap_add_item(keymap, "VIEW3D_OT_zoom", MOUSEPAN, 0, KM_CTRL, 0); /*numpad +/-*/ RNA_int_set(WM_keymap_add_item(keymap, "VIEW3D_OT_zoom", PADPLUSKEY, KM_PRESS, 0, 0)->ptr, "delta", 1); @@ -359,6 +431,13 @@ void view3d_keymap(wmKeyConfig *keyconf) WM_keymap_add_menu(keymap, "VIEW3D_MT_snap", SKEY, KM_PRESS, KM_SHIFT, 0); +#ifdef __APPLE__ + WM_keymap_add_item(keymap, "VIEW3D_OT_copybuffer", CKEY, KM_PRESS, KM_OSKEY, 0); + WM_keymap_add_item(keymap, "VIEW3D_OT_pastebuffer", VKEY, KM_PRESS, KM_OSKEY, 0); +#endif + WM_keymap_add_item(keymap, "VIEW3D_OT_copybuffer", CKEY, KM_PRESS, KM_CTRL, 0); + WM_keymap_add_item(keymap, "VIEW3D_OT_pastebuffer", VKEY, KM_PRESS, KM_CTRL, 0); + /* context ops */ kmi = WM_keymap_add_item(keymap, "WM_OT_context_set_enum", COMMAKEY, KM_PRESS, 0, 0); RNA_string_set(kmi->ptr, "data_path", "space_data.pivot_point"); diff --git a/source/blender/editors/space_view3d/view3d_view.c b/source/blender/editors/space_view3d/view3d_view.c index 5a7edfe4140..56ce9bda607 100644 --- a/source/blender/editors/space_view3d/view3d_view.c +++ b/source/blender/editors/space_view3d/view3d_view.c @@ -1530,7 +1530,7 @@ float ED_view3d_pixel_size(RegionView3D *rv3d, const float co[3]) rv3d->persmat[0][3] * co[0] + rv3d->persmat[1][3] * co[1] + rv3d->persmat[2][3] * co[2]) - ) * rv3d->pixsize; + ) * rv3d->pixsize * U.pixelsize; } float ED_view3d_radius_to_persp_dist(const float angle, const float radius) diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c index 5497b421981..dc33b851db8 100644 --- a/source/blender/editors/transform/transform_conversions.c +++ b/source/blender/editors/transform/transform_conversions.c @@ -113,6 +113,7 @@ #include "WM_types.h" #include "UI_view2d.h" +#include "UI_interface.h" #include "RNA_access.h" @@ -2229,7 +2230,12 @@ void flushTransNodes(TransInfo *t) /* flush to 2d vector from internally used 3d vector */ for (a = 0, td = t->data, td2d = t->data2d; a < t->total; a++, td++, td2d++) { bNode *node = td->extra; - add_v2_v2v2(&node->locx, td2d->loc, td2d->ih1); + float vec[2]; + + /* weirdo - but the node system is a mix of free 2d elements and dpi sensitive UI */ + add_v2_v2v2(vec, td2d->loc, td2d->ih1); + node->locx = vec[0] / UI_DPI_FAC; + node->locy = vec[1] / UI_DPI_FAC; } /* handle intersection with noodles */ @@ -5626,7 +5632,8 @@ static void NodeToTransData(TransData *td, TransData2D *td2d, bNode *node) /* hold original location */ float locxy[2] = {BLI_rctf_cent_x(&node->totr), BLI_rctf_cent_y(&node->totr)}; - + float nodeloc[2]; + copy_v2_v2(td2d->loc, locxy); td2d->loc[2] = 0.0f; td2d->loc2d = td2d->loc; /* current location */ @@ -5651,7 +5658,10 @@ static void NodeToTransData(TransData *td, TransData2D *td2d, bNode *node) unit_m3(td->mtx); unit_m3(td->smtx); - sub_v2_v2v2(td2d->ih1, &node->locx, locxy); + /* weirdo - but the node system is a mix of free 2d elements and dpi sensitive UI */ + nodeloc[0] = UI_DPI_FAC * node->locx; + nodeloc[1] = UI_DPI_FAC * node->locy; + sub_v2_v2v2(td2d->ih1, nodeloc, locxy); td->extra = node; } diff --git a/source/blender/makesdna/DNA_screen_types.h b/source/blender/makesdna/DNA_screen_types.h index b1cd54950e6..ed2ffdf6702 100644 --- a/source/blender/makesdna/DNA_screen_types.h +++ b/source/blender/makesdna/DNA_screen_types.h @@ -159,7 +159,8 @@ typedef struct ARegion { short do_draw; /* private, cached notifier events */ short do_draw_overlay; /* private, cached notifier events */ short swap; /* private, indicator to survive swap-exchange */ - short pad[3]; + short overlap; /* private, set for indicate drawing overlapped */ + short pad[2]; struct ARegionType *type; /* callbacks for this region type */ @@ -167,6 +168,8 @@ typedef struct ARegion { ListBase panels; /* Panel */ ListBase handlers; /* wmEventHandler */ + struct wmTimer *regiontimer; /* blend in/out */ + char *headerstr; /* use this string to draw info */ void *regiondata; /* XXX 2.50, need spacedata equivalent? */ } ARegion; @@ -235,10 +238,6 @@ enum { #define RGN_ALIGN_VSPLIT 6 #define RGN_ALIGN_FLOAT 7 #define RGN_ALIGN_QSPLIT 8 -#define RGN_OVERLAP_TOP 9 -#define RGN_OVERLAP_BOTTOM 10 -#define RGN_OVERLAP_LEFT 11 -#define RGN_OVERLAP_RIGHT 12 #define RGN_SPLIT_PREV 32 diff --git a/source/blender/makesdna/DNA_space_types.h b/source/blender/makesdna/DNA_space_types.h index be6464778e5..9ef18f31f29 100644 --- a/source/blender/makesdna/DNA_space_types.h +++ b/source/blender/makesdna/DNA_space_types.h @@ -797,7 +797,7 @@ typedef struct SpaceText { int top, viewlines; short flags, menunr; - short lheight; /* user preference */ + short lheight; /* user preference, is font_size! */ char cwidth, linenrs_tot; /* runtime computed, character width and the number of chars to use when showing line numbers */ int left; int showlinenrs; @@ -816,8 +816,9 @@ typedef struct SpaceText { char findstr[256]; /* ST_MAX_FIND_STR */ char replacestr[256]; /* ST_MAX_FIND_STR */ - short margin_column; /* column number to show right margin at */ - char pad[6]; + short margin_column; /* column number to show right margin at */ + short lheight_dpi; /* actual lineheight, dpi controlled */ + char pad[4]; void *drawcache; /* cache for faster drawing */ } SpaceText; @@ -886,7 +887,7 @@ typedef struct SpaceNode { struct ID *id, *from; /* context, no need to save in file? well... pinning... */ short flag, pad1; /* menunr: browse id block in header */ - float aspect, aspect_sqrt; + float aspect, pad2; /* internal state variables */ float xof, yof; /* offset for drawing the backdrop */ float zoom; /* zoom for backdrop */ diff --git a/source/blender/makesdna/DNA_userdef_types.h b/source/blender/makesdna/DNA_userdef_types.h index 2e2f65dbec7..8f8cf3eda26 100644 --- a/source/blender/makesdna/DNA_userdef_types.h +++ b/source/blender/makesdna/DNA_userdef_types.h @@ -359,9 +359,10 @@ typedef struct UserDef { short versions; short dbl_click_time; - int gameflags; - int wheellinescroll; - int uiflag, language; + short gameflags; + short wheellinescroll; + int uiflag, uiflag2; + int language; short userpref, viewzoom; int mixbufsize; @@ -412,7 +413,7 @@ typedef struct UserDef { short scrcastfps; /* frame rate for screencast to be played back */ short scrcastwait; /* milliseconds between screencast snapshots */ - short widget_unit; /* defaults to 20 for 72 DPI setting */ + short widget_unit; /* private, defaults to 20 for 72 DPI setting */ short anisotropic_filter; short use_16bit_textures, use_gpu_mipmap; @@ -443,7 +444,7 @@ typedef struct UserDef { int compute_device_id; float fcu_inactive_alpha; /* opacity of inactive F-Curves in F-Curve Editor */ - float pad; + float pixelsize; /* private, set by GHOST, to multiply DPI with */ } UserDef; extern UserDef U; /* from blenkernel blender.c */ @@ -539,6 +540,12 @@ typedef enum eUserpref_UI_Flag { USER_HIDE_SYSTEM_BOOKMARKS = (1 << 31) } eUserpref_UI_Flag; +/* uiflag2 */ +typedef enum eUserpref_UI_Flag2 { + USER_KEEP_SESSION = (1 << 0), + USER_REGION_OVERLAP = (1 << 1) +} eUserpref_UI_Flag2; + /* Auto-Keying mode */ typedef enum eAutokey_Mode { /* AUTOKEY_ON is a bitflag */ diff --git a/source/blender/makesrna/intern/rna_userdef.c b/source/blender/makesrna/intern/rna_userdef.c index 7be34c398ae..d24ddcdaef2 100644 --- a/source/blender/makesrna/intern/rna_userdef.c +++ b/source/blender/makesrna/intern/rna_userdef.c @@ -62,6 +62,7 @@ static EnumPropertyItem compute_device_type_items[] = { #include "DNA_object_types.h" #include "DNA_screen_types.h" +#include "BKE_blender.h" #include "BKE_DerivedMesh.h" #include "BKE_depsgraph.h" #include "BKE_global.h" @@ -83,9 +84,10 @@ static void rna_userdef_update(Main *UNUSED(bmain), Scene *UNUSED(scene), Pointe WM_main_add_notifier(NC_WINDOW, NULL); } +/* also used by buffer swap switching */ static void rna_userdef_dpi_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *UNUSED(ptr)) { - U.widget_unit = (U.dpi * 20 + 36) / 72; + BKE_userdef_state(); WM_main_add_notifier(NC_WINDOW, NULL); /* full redraw */ WM_main_add_notifier(NC_SCREEN | NA_EDITED, NULL); /* refresh region sizes */ } @@ -840,7 +842,7 @@ static void rna_def_userdef_theme_space_generic(BlenderRNA *brna) /* buttons */ /* if (! ELEM(spacetype, SPACE_BUTS, SPACE_OUTLINER)) { */ prop = RNA_def_property(srna, "button", PROP_FLOAT, PROP_COLOR_GAMMA); - RNA_def_property_array(prop, 3); + RNA_def_property_array(prop, 4); RNA_def_property_ui_text(prop, "Region Background", ""); RNA_def_property_update(prop, 0, "rna_userdef_update"); @@ -3275,7 +3277,7 @@ static void rna_def_userdef_system(BlenderRNA *brna) RNA_def_property_enum_sdna(prop, NULL, "wmdrawmethod"); RNA_def_property_enum_items(prop, draw_method_items); RNA_def_property_ui_text(prop, "Window Draw Method", "Drawing method used by the window manager"); - RNA_def_property_update(prop, 0, "rna_userdef_update"); + RNA_def_property_update(prop, 0, "rna_userdef_dpi_update"); prop = RNA_def_property(srna, "audio_mixing_buffer", PROP_ENUM, PROP_NONE); RNA_def_property_enum_sdna(prop, NULL, "mixbufsize"); @@ -3329,6 +3331,13 @@ static void rna_def_userdef_system(BlenderRNA *brna) RNA_def_property_enum_items(prop, multi_sample_levels); RNA_def_property_ui_text(prop, "MultiSample", "Enable OpenGL multi-sampling, only for systems that support it, requires restart"); + prop = RNA_def_property(srna, "use_region_overlap", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "uiflag2", USER_REGION_OVERLAP); + RNA_def_property_ui_text(prop, "Region Overlap", + "Draw tool/property regions over the main region, when using Triple Buffer"); + RNA_def_property_update(prop, 0, "rna_userdef_dpi_update"); + + #ifdef WITH_CYCLES prop = RNA_def_property(srna, "compute_device_type", PROP_ENUM, PROP_NONE); RNA_def_property_flag(prop, PROP_ENUM_NO_CONTEXT); @@ -3664,6 +3673,11 @@ static void rna_def_userdef_filepaths(BlenderRNA *brna) "The time (in minutes) to wait between automatic temporary saves"); RNA_def_property_update(prop, 0, "rna_userdef_autosave_update"); + prop = RNA_def_property(srna, "use_keep_session", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "uiflag2", USER_KEEP_SESSION); + RNA_def_property_ui_text(prop, "Keep Session", + "Always load session recovery and save it after quitting Blender"); + prop = RNA_def_property(srna, "recent_files", PROP_INT, PROP_NONE); RNA_def_property_range(prop, 0, 30); RNA_def_property_ui_text(prop, "Recent Files", "Maximum number of recently opened files to remember"); diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h index 8d885bf6d6f..ce08d7ff9c0 100644 --- a/source/blender/windowmanager/WM_api.h +++ b/source/blender/windowmanager/WM_api.h @@ -68,6 +68,7 @@ typedef struct wmJob wmJob; void WM_init_state_size_set (int stax, int stay, int sizx, int sizy); void WM_init_state_fullscreen_set(void); void WM_init_state_normal_set(void); +void WM_init_native_pixels(int do_it); void WM_init (struct bContext *C, int argc, const char **argv); void WM_exit_ext (struct bContext *C, const short do_python); @@ -92,21 +93,23 @@ void WM_check (struct bContext *C); struct wmWindow *WM_window_open (struct bContext *C, struct rcti *rect); +int WM_window_pixels_x (struct wmWindow *win); +int WM_window_pixels_y (struct wmWindow *win); + /* defines for 'type' WM_window_open_temp */ #define WM_WINDOW_RENDER 0 #define WM_WINDOW_USERPREFS 1 #define WM_WINDOW_FILESEL 2 void WM_window_open_temp (struct bContext *C, struct rcti *position, int type); + + /* returns true if draw method is triple buffer */ +int WM_is_draw_triple(struct wmWindow *win); /* files */ -int WM_homefile_read_exec(struct bContext *C, struct wmOperator *op); -int WM_homefile_read(struct bContext *C, struct ReportList *reports, short from_memory); -int WM_homefile_write_exec(struct bContext *C, struct wmOperator *op); void WM_file_read(struct bContext *C, const char *filepath, struct ReportList *reports); -int WM_file_write(struct bContext *C, const char *target, int fileflags, struct ReportList *reports); void WM_autosave_init(struct wmWindowManager *wm); /* mouse cursors */ diff --git a/source/blender/windowmanager/intern/wm_draw.c b/source/blender/windowmanager/intern/wm_draw.c index a92ed65392c..11cf1088280 100644 --- a/source/blender/windowmanager/intern/wm_draw.c +++ b/source/blender/windowmanager/intern/wm_draw.c @@ -49,6 +49,7 @@ #include "BKE_context.h" #include "BKE_global.h" +#include "BKE_screen.h" #include "GHOST_C-api.h" @@ -431,22 +432,22 @@ static int wm_triple_gen_textures(wmWindow *win, wmDrawTriple *triple) triple->target = GL_TEXTURE_RECTANGLE_ARB; triple->nx = 1; triple->ny = 1; - triple->x[0] = win->sizex; - triple->y[0] = win->sizey; + triple->x[0] = WM_window_pixels_x(win); + triple->y[0] = WM_window_pixels_y(win); } else if (GPU_non_power_of_two_support()) { triple->target = GL_TEXTURE_2D; triple->nx = 1; triple->ny = 1; - triple->x[0] = win->sizex; - triple->y[0] = win->sizey; + triple->x[0] = WM_window_pixels_x(win); + triple->y[0] = WM_window_pixels_y(win); } else { triple->target = GL_TEXTURE_2D; triple->nx = 0; triple->ny = 0; - split_width(win->sizex, MAX_N_TEX, triple->x, &triple->nx); - split_width(win->sizey, MAX_N_TEX, triple->y, &triple->ny); + split_width(WM_window_pixels_x(win), MAX_N_TEX, triple->x, &triple->nx); + split_width(WM_window_pixels_y(win), MAX_N_TEX, triple->y, &triple->ny); } /* generate texture names */ @@ -491,7 +492,7 @@ static int wm_triple_gen_textures(wmWindow *win, wmDrawTriple *triple) return 1; } -static void wm_triple_draw_textures(wmWindow *win, wmDrawTriple *triple) +static void wm_triple_draw_textures(wmWindow *win, wmDrawTriple *triple, float alpha) { float halfx, halfy, ratiox, ratioy; int x, y, sizex, sizey, offx, offy; @@ -500,8 +501,8 @@ static void wm_triple_draw_textures(wmWindow *win, wmDrawTriple *triple) for (y = 0, offy = 0; y < triple->ny; offy += triple->y[y], y++) { for (x = 0, offx = 0; x < triple->nx; offx += triple->x[x], x++) { - sizex = (x == triple->nx - 1) ? win->sizex - offx : triple->x[x]; - sizey = (y == triple->ny - 1) ? win->sizey - offy : triple->y[y]; + sizex = (x == triple->nx - 1) ? WM_window_pixels_x(win) - offx : triple->x[x]; + sizey = (y == triple->ny - 1) ? WM_window_pixels_y(win) - offy : triple->y[y]; /* wmOrtho for the screen has this same offset */ ratiox = sizex; @@ -519,7 +520,7 @@ static void wm_triple_draw_textures(wmWindow *win, wmDrawTriple *triple) glBindTexture(triple->target, triple->bind[x + y * triple->nx]); - glColor3f(1.0f, 1.0f, 1.0f); + glColor4f(1.0f, 1.0f, 1.0f, alpha); glBegin(GL_QUADS); glTexCoord2f(halfx, halfy); glVertex2f(offx, offy); @@ -546,8 +547,8 @@ static void wm_triple_copy_textures(wmWindow *win, wmDrawTriple *triple) for (y = 0, offy = 0; y < triple->ny; offy += triple->y[y], y++) { for (x = 0, offx = 0; x < triple->nx; offx += triple->x[x], x++) { - sizex = (x == triple->nx - 1) ? win->sizex - offx : triple->x[x]; - sizey = (y == triple->ny - 1) ? win->sizey - offy : triple->y[y]; + sizex = (x == triple->nx - 1) ? WM_window_pixels_x(win) - offx : triple->x[x]; + sizey = (y == triple->ny - 1) ? WM_window_pixels_y(win) - offy : triple->y[y]; glBindTexture(triple->target, triple->bind[x + y * triple->nx]); glCopyTexSubImage2D(triple->target, 0, 0, 0, offx, offy, sizex, sizey); @@ -557,6 +558,20 @@ static void wm_triple_copy_textures(wmWindow *win, wmDrawTriple *triple) glBindTexture(triple->target, 0); } +static void wm_draw_region_blend(wmWindow *win, ARegion *ar) +{ + float fac = ED_region_blend_factor(ar); + + /* region blend always is 1, except when blend timer is running */ + if (fac < 1.0f) { + wmSubWindowScissorSet(win, win->screen->mainwin, &ar->winrct); + + glEnable(GL_BLEND); + wm_triple_draw_textures(win, win->drawdata, 1.0f - fac); + glDisable(GL_BLEND); + } +} + static void wm_method_draw_triple(bContext *C, wmWindow *win) { wmWindowManager *wm = CTX_wm_manager(C); @@ -572,7 +587,7 @@ static void wm_method_draw_triple(bContext *C, wmWindow *win) wmSubWindowSet(win, screen->mainwin); - wm_triple_draw_textures(win, win->drawdata); + wm_triple_draw_textures(win, win->drawdata, 1.0f); } else { win->drawdata = MEM_callocN(sizeof(wmDrawTriple), "wmDrawTriple"); @@ -591,11 +606,13 @@ static void wm_method_draw_triple(bContext *C, wmWindow *win) for (ar = sa->regionbase.first; ar; ar = ar->next) { if (ar->swinid && ar->do_draw) { - CTX_wm_region_set(C, ar); - ED_region_do_draw(C, ar); - ED_area_overdraw_flush(sa, ar); - CTX_wm_region_set(C, NULL); - copytex = 1; + if (ar->overlap == 0) { + CTX_wm_region_set(C, ar); + ED_region_do_draw(C, ar); + ED_area_overdraw_flush(sa, ar); + CTX_wm_region_set(C, NULL); + copytex = 1; + } } } @@ -610,10 +627,28 @@ static void wm_method_draw_triple(bContext *C, wmWindow *win) wm_triple_copy_textures(win, triple); } + /* draw overlapping area regions (always like popups) */ + for (sa = screen->areabase.first; sa; sa = sa->next) { + CTX_wm_area_set(C, sa); + + for (ar = sa->regionbase.first; ar; ar = ar->next) { + if (ar->swinid && ar->overlap) { + CTX_wm_region_set(C, ar); + ED_region_do_draw(C, ar); + ED_area_overdraw_flush(sa, ar); + CTX_wm_region_set(C, NULL); + + wm_draw_region_blend(win, ar); + } + } + + CTX_wm_area_set(C, NULL); + } + /* after area regions so we can do area 'overlay' drawing */ ED_screen_draw(win); - /* draw overlapping regions */ + /* draw floating regions (menus) */ for (ar = screen->regionbase.first; ar; ar = ar->next) { if (ar->swinid) { CTX_wm_menu_set(C, ar); @@ -652,9 +687,9 @@ static void wm_method_draw_triple(bContext *C, wmWindow *win) if (wm->drags.first) { wm_drags_draw(C, win, NULL); } - } + /****************** main update call **********************/ /* quick test to prevent changing window drawable */ @@ -734,6 +769,14 @@ static int wm_automatic_draw_method(wmWindow *win) return win->drawmethod; } +int WM_is_draw_triple(wmWindow *win) +{ + /* function can get called before this variable is set in drawing code below */ + if (win->drawmethod != U.wmdrawmethod) + win->drawmethod = U.wmdrawmethod; + return USER_DRAW_TRIPLE == wm_automatic_draw_method(win); +} + void wm_tag_redraw_overlay(wmWindow *win, ARegion *ar) { /* for draw triple gestures, paint cursors don't need region redraw */ diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c index c0e3b19c716..db80b0bd1a0 100644 --- a/source/blender/windowmanager/intern/wm_event_system.c +++ b/source/blender/windowmanager/intern/wm_event_system.c @@ -2738,11 +2738,9 @@ void wm_event_add_ghostevent(wmWindowManager *wm, wmWindow *win, int type, int U { GHOST_TEventCursorData *cd = customdata; wmEvent *lastevent = win->queue.last; - int cx, cy; - GHOST_ScreenToClient(win->ghostwin, cd->x, cd->y, &cx, &cy); - evt->x = cx; - evt->y = (win->sizey - 1) - cy; + evt->x = cd->x; + evt->y = cd->y; event.x = evt->x; event.y = evt->y; @@ -2790,13 +2788,8 @@ void wm_event_add_ghostevent(wmWindowManager *wm, wmWindow *win, int type, int U break; } - { - int cx, cy; - GHOST_ScreenToClient(win->ghostwin, pd->x, pd->y, &cx, &cy); - event.x = evt->x = cx; - event.y = evt->y = (win->sizey - 1) - cy; - } - + event.x = evt->x = pd->x; + event.y = evt->y = pd->y; event.val = 0; /* Use prevx/prevy so we can calculate the delta later */ diff --git a/source/blender/windowmanager/intern/wm_files.c b/source/blender/windowmanager/intern/wm_files.c index de59ec8d339..2e2595259ce 100644 --- a/source/blender/windowmanager/intern/wm_files.c +++ b/source/blender/windowmanager/intern/wm_files.c @@ -283,7 +283,9 @@ static void wm_window_match_do(bContext *C, ListBase *oldwmlist) /* in case UserDef was read, we re-initialize all, and do versioning */ static void wm_init_userdef(bContext *C) { + /* versioning is here */ UI_init_userdef(); + MEM_CacheLimiter_set_maximum(((size_t)U.memcachelimit) * 1024 * 1024); sound_init(CTX_data_main(C)); @@ -300,6 +302,10 @@ static void wm_init_userdef(bContext *C) /* update tempdir from user preferences */ BLI_init_temporary_dir(U.tempdir); + + /* displays with larger native pixels, like Macbook. Used to scale dpi with */ + U.pixelsize = GHOST_GetNativePixelSize(); + BKE_userdef_state(); } @@ -388,6 +394,8 @@ void WM_file_read(bContext *C, const char *filepath, ReportList *reports) /* also exit screens and editors */ wm_window_match_init(C, &wmbase); + /* confusing this global... */ + G.relbase_valid = 1; retval = BKE_read_file(C, filepath, reports); G.save_over = 1; @@ -408,7 +416,6 @@ void WM_file_read(bContext *C, const char *filepath, ReportList *reports) } if (retval != BKE_READ_FILE_FAIL) { - G.relbase_valid = 1; if (do_history) { write_history(); } @@ -485,11 +492,12 @@ void WM_file_read(bContext *C, const char *filepath, ReportList *reports) /* called on startup, (context entirely filled with NULLs) */ /* or called for 'New File' */ -/* op can be NULL */ -int WM_homefile_read(bContext *C, ReportList *UNUSED(reports), short from_memory) +/* both startup.blend and userpref.blend are checked */ +int wm_homefile_read(bContext *C, ReportList *UNUSED(reports), short from_memory) { ListBase wmbase; - char tstr[FILE_MAX]; + char startstr[FILE_MAX]; + char prefstr[FILE_MAX]; int success = 0; BLI_callback_exec(CTX_data_main(C), NULL, BLI_CB_EVT_LOAD_PRE); @@ -498,10 +506,12 @@ int WM_homefile_read(bContext *C, ReportList *UNUSED(reports), short from_memory if (!from_memory) { char *cfgdir = BLI_get_folder(BLENDER_USER_CONFIG, NULL); if (cfgdir) { - BLI_make_file_string(G.main->name, tstr, cfgdir, BLENDER_STARTUP_FILE); + BLI_make_file_string(G.main->name, startstr, cfgdir, BLENDER_STARTUP_FILE); + BLI_make_file_string(G.main->name, prefstr, cfgdir, BLENDER_USERPREF_FILE); } else { - tstr[0] = '\0'; + startstr[0] = '\0'; + prefstr[0] = '\0'; from_memory = 1; } } @@ -512,14 +522,20 @@ int WM_homefile_read(bContext *C, ReportList *UNUSED(reports), short from_memory /* put aside screens to match with persistent windows later */ wm_window_match_init(C, &wmbase); - if (!from_memory && BLI_exists(tstr)) { - success = (BKE_read_file(C, tstr, NULL) != BKE_READ_FILE_FAIL); + if (!from_memory && BLI_exists(startstr)) { + success = (BKE_read_file(C, startstr, NULL) != BKE_READ_FILE_FAIL); - if (U.themes.first == NULL) { - printf("\nError: No valid "STRINGIFY (BLENDER_STARTUP_FILE)", fall back to built-in default.\n\n"); - success = 0; - } } + if (!from_memory && BLI_exists(prefstr)) { + success = BKE_read_file_userdef(prefstr, NULL); + if (success) printf("read new prefs: %s\n", prefstr); + } + + if (U.themes.first == NULL) { + printf("\nError: No valid "STRINGIFY (BLENDER_STARTUP_FILE)", fall back to built-in default.\n\n"); + success = 0; + } + if (success == 0) { success = BKE_read_file_from_memory(C, datatoc_startup_blend, datatoc_startup_blend_size, NULL); if (wmbase.first == NULL) wm_clear_default_size(C); @@ -584,13 +600,13 @@ int WM_homefile_read(bContext *C, ReportList *UNUSED(reports), short from_memory return TRUE; } -int WM_homefile_read_exec(bContext *C, wmOperator *op) +int wm_homefile_read_exec(bContext *C, wmOperator *op) { int from_memory = strcmp(op->type->idname, "WM_OT_read_factory_settings") == 0; - return WM_homefile_read(C, op->reports, from_memory) ? OPERATOR_FINISHED : OPERATOR_CANCELLED; + return wm_homefile_read(C, op->reports, from_memory) ? OPERATOR_FINISHED : OPERATOR_CANCELLED; } -void WM_read_history(void) +void wm_read_history(void) { char name[FILE_MAX]; LinkNode *l, *lines; @@ -630,6 +646,10 @@ static void write_history(void) FILE *fp; int i; + /* no write history for recovered startup files */ + if (G.main->name[0] == 0) + return; + /* will be NULL in background mode */ user_config_dir = BLI_get_folder_create(BLENDER_USER_CONFIG, NULL); if (!user_config_dir) @@ -762,12 +782,11 @@ int write_crash_blend(void) } } -int WM_file_write(bContext *C, const char *target, int fileflags, ReportList *reports) +int wm_file_write(bContext *C, const char *target, int fileflags, ReportList *reports) { Library *li; int len; char filepath[FILE_MAX]; - int *thumb = NULL; ImBuf *ibuf_thumb = NULL; @@ -861,7 +880,7 @@ int WM_file_write(bContext *C, const char *target, int fileflags, ReportList *re } /* operator entry */ -int WM_homefile_write_exec(bContext *C, wmOperator *op) +int wm_homefile_write_exec(bContext *C, wmOperator *op) { wmWindowManager *wm = CTX_wm_manager(C); wmWindow *win = CTX_wm_window(C); @@ -881,7 +900,7 @@ int WM_homefile_write_exec(bContext *C, wmOperator *op) /* force save as regular blend file */ fileflags = G.fileflags & ~(G_FILE_COMPRESS | G_FILE_AUTOPLAY | G_FILE_LOCK | G_FILE_SIGN | G_FILE_HISTORY); - if (BLO_write_file(CTX_data_main(C), filepath, fileflags, op->reports, NULL) == 0) { + if (BLO_write_file(CTX_data_main(C), filepath, fileflags | G_FILE_USERPREFS, op->reports, NULL) == 0) { printf("fail\n"); return OPERATOR_CANCELLED; } @@ -893,6 +912,28 @@ int WM_homefile_write_exec(bContext *C, wmOperator *op) return OPERATOR_FINISHED; } +/* Only save the prefs block. operator entry */ +int wm_userpref_write_exec(bContext *C, wmOperator *op) +{ + wmWindowManager *wm = CTX_wm_manager(C); + char filepath[FILE_MAX]; + + /* update keymaps in user preferences */ + WM_keyconfig_update(wm); + + BLI_make_file_string("/", filepath, BLI_get_folder_create(BLENDER_USER_CONFIG, NULL), BLENDER_USERPREF_FILE); + printf("trying to save userpref at %s ", filepath); + + if (BKE_write_file_userdef(filepath, op->reports) == 0) { + printf("fail\n"); + return OPERATOR_CANCELLED; + } + + printf("ok\n"); + + return OPERATOR_FINISHED; +} + /************************ autosave ****************************/ void wm_autosave_location(char *filepath) @@ -936,7 +977,7 @@ void wm_autosave_timer(const bContext *C, wmWindowManager *wm, wmTimer *UNUSED(w wmWindow *win; wmEventHandler *handler; char filepath[FILE_MAX]; - int fileflags; + Scene *scene = CTX_data_scene(C); WM_event_remove_timer(wm, NULL, wm->autosavetimer); @@ -960,12 +1001,17 @@ void wm_autosave_timer(const bContext *C, wmWindowManager *wm, wmTimer *UNUSED(w wm_autosave_location(filepath); - /* force save as regular blend file */ - fileflags = G.fileflags & ~(G_FILE_COMPRESS | G_FILE_AUTOPLAY | G_FILE_LOCK | G_FILE_SIGN | G_FILE_HISTORY); - - /* no error reporting to console */ - BLO_write_file(CTX_data_main(C), filepath, fileflags, NULL, NULL); + if (U.uiflag & USER_GLOBALUNDO) { + /* fast save of last undobuffer, now with UI */ + BKE_undo_save_file(C, filepath); + } + else { + /* save as regular blend file */ + int fileflags = G.fileflags & ~(G_FILE_COMPRESS | G_FILE_AUTOPLAY | G_FILE_LOCK | G_FILE_SIGN | G_FILE_HISTORY); + /* no error reporting to console */ + BLO_write_file(CTX_data_main(C), filepath, fileflags, NULL, NULL); + } /* do timer after file write, just in case file write takes a long time */ wm->autosavetimer = WM_event_add_timer(wm, NULL, TIMERAUTOSAVE, U.savetime * 60.0); } @@ -1002,3 +1048,6 @@ void wm_autosave_read(bContext *C, ReportList *reports) WM_file_read(C, filename, reports); } + + + diff --git a/source/blender/windowmanager/intern/wm_init_exit.c b/source/blender/windowmanager/intern/wm_init_exit.c index c9f0bbffc63..563cb592d5a 100644 --- a/source/blender/windowmanager/intern/wm_init_exit.c +++ b/source/blender/windowmanager/intern/wm_init_exit.c @@ -48,6 +48,7 @@ #include "DNA_windowmanager_types.h" #include "BLI_listbase.h" +#include "BLI_path_util.h" #include "BLI_string.h" #include "BLI_utildefines.h" @@ -128,6 +129,7 @@ int wm_start_with_console = 0; /* used in creator.c */ /* only called once, for startup */ void WM_init(bContext *C, int argc, const char **argv) { + if (!G.background) { wm_ghost_init(C); /* note: it assigns C to ghost! */ wm_init_cursor_data(); @@ -149,8 +151,8 @@ void WM_init(bContext *C, int argc, const char **argv) BLF_lang_init(); /* get the default database, plus a wm */ - WM_homefile_read(C, NULL, G.factory_startup); - + wm_homefile_read(C, NULL, G.factory_startup); + BLF_lang_set(NULL); /* note: there is a bug where python needs initializing before loading the @@ -158,7 +160,7 @@ void WM_init(bContext *C, int argc, const char **argv) * initializing space types and other internal data. * * However cant redo this at the moment. Solution is to load python - * before WM_homefile_read() or make py-drivers check if python is running. + * before wm_homefile_read() or make py-drivers check if python is running. * Will try fix when the crash can be repeated. - campbell. */ #ifdef WITH_PYTHON @@ -195,7 +197,7 @@ void WM_init(bContext *C, int argc, const char **argv) ED_preview_init_dbase(); - WM_read_history(); + wm_read_history(); /* allow a path of "", this is what happens when making a new file */ #if 0 @@ -211,6 +213,10 @@ void WM_init(bContext *C, int argc, const char **argv) COM_linker_hack = COM_execute; } #endif + + /* load last session, uses regular file reading so it has to be in end (after init py etc) */ + if (U.uiflag2 & USER_KEEP_SESSION) + wm_recover_last_session(C, NULL); } void WM_init_splash(bContext *C) @@ -372,6 +378,18 @@ void WM_exit_ext(bContext *C, const short do_python) if (C && wm) { wmWindow *win; + if (!G.background) { + if ((U.uiflag2 & USER_KEEP_SESSION) || BKE_undo_valid(NULL)) { + /* save the undo state as quit.blend */ + char filename[FILE_MAX]; + + BLI_make_file_string("/", filename, BLI_temporary_dir(), "quit.blend"); + + if (BKE_undo_save_file(C, filename)) + printf("Saved session recovery to '%s'\n", filename); + } + } + WM_jobs_kill_all(wm); for (win = wm->windows.first; win; win = win->next) { @@ -454,9 +472,6 @@ void WM_exit_ext(bContext *C, const short do_python) GPU_free_unused_buffers(); GPU_extensions_exit(); - if (!G.background) { - BKE_undo_save_quit(); /* saves quit.blend if global undo is on */ - } BKE_reset_undo(); ED_file_exit(); /* for fsmenu */ diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c index 8a0701b1063..1b6fe910ac5 100644 --- a/source/blender/windowmanager/intern/wm_operators.c +++ b/source/blender/windowmanager/intern/wm_operators.c @@ -103,6 +103,7 @@ #include "wm_draw.h" #include "wm_event_system.h" #include "wm_event_types.h" +#include "wm_files.h" #include "wm_subwindow.h" #include "wm_window.h" @@ -1452,9 +1453,9 @@ static uiBlock *wm_block_create_splash(bContext *C, ARegion *ar, void *UNUSED(ar "%d.%02d.%d", BLENDER_VERSION / 100, BLENDER_VERSION % 100, BLENDER_SUBVERSION); BLI_snprintf(revision_buf, sizeof(revision_buf), "r%s", build_rev); - BLF_size(style->widgetlabel.uifont_id, style->widgetlabel.points, U.dpi); - ver_width = (int)BLF_width(style->widgetlabel.uifont_id, version_buf) + 5; - rev_width = (int)BLF_width(style->widgetlabel.uifont_id, revision_buf) + 5; + BLF_size(style->widgetlabel.uifont_id, style->widgetlabel.points, U.pixelsize * U.dpi); + ver_width = (int)BLF_width(style->widgetlabel.uifont_id, version_buf) + 0.5f * U.widget_unit; + rev_width = (int)BLF_width(style->widgetlabel.uifont_id, revision_buf) + 0.5f * U.widget_unit; #endif /* WITH_BUILDINFO */ block = uiBeginBlock(C, ar, "_popup", UI_EMBOSS); @@ -1464,16 +1465,17 @@ static uiBlock *wm_block_create_splash(bContext *C, ARegion *ar, void *UNUSED(ar * ugly results and clipping the splash isn't useful anyway, just disable it [#32938] */ uiBlockSetFlag(block, UI_BLOCK_KEEP_OPEN | UI_BLOCK_NO_WIN_CLIP); - but = uiDefBut(block, BUT_IMAGE, 0, "", 0, 10, 501, 282, ibuf, 0.0, 0.0, 0, 0, ""); /* button owns the imbuf now */ + /* XXX splash scales with pixelsize, should become widget-units */ + but = uiDefBut(block, BUT_IMAGE, 0, "", 0, 0.5f * U.widget_unit, U.pixelsize * 501, U.pixelsize *282, ibuf, 0.0, 0.0, 0, 0, ""); /* button owns the imbuf now */ uiButSetFunc(but, wm_block_splash_close, block, NULL); uiBlockSetFunc(block, wm_block_splash_refreshmenu, block, NULL); #ifdef WITH_BUILDINFO - uiDefBut(block, LABEL, 0, version_buf, 494 - ver_width, 282 - 24, ver_width, UI_UNIT_Y, NULL, 0, 0, 0, 0, NULL); - uiDefBut(block, LABEL, 0, revision_buf, 494 - rev_width, 282 - 36, rev_width, UI_UNIT_Y, NULL, 0, 0, 0, 0, NULL); + uiDefBut(block, LABEL, 0, version_buf, U.pixelsize * 494 - ver_width, U.pixelsize * 258, ver_width, UI_UNIT_Y, NULL, 0, 0, 0, 0, NULL); + uiDefBut(block, LABEL, 0, revision_buf, U.pixelsize * 494 - rev_width, U.pixelsize * 246, rev_width, UI_UNIT_Y, NULL, 0, 0, 0, 0, NULL); #endif /* WITH_BUILDINFO */ - layout = uiBlockLayout(block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL, 10, 2, 480, 110, style); + layout = uiBlockLayout(block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL, 10, 2, U.pixelsize * 480, U.pixelsize * 110, style); uiBlockSetEmboss(block, UI_EMBOSS); /* show the splash menu (containing interaction presets), using python */ @@ -1675,12 +1677,23 @@ static void WM_OT_window_duplicate(wmOperatorType *ot) static void WM_OT_save_homefile(wmOperatorType *ot) { - ot->name = "Save User Settings"; + ot->name = "Save Startup File"; ot->idname = "WM_OT_save_homefile"; - ot->description = "Make the current file the default .blend file"; + ot->description = "Make the current file the default .blend file, includes preferences"; ot->invoke = WM_operator_confirm; - ot->exec = WM_homefile_write_exec; + ot->exec = wm_homefile_write_exec; + ot->poll = WM_operator_winactive; +} + +static void WM_OT_save_userpref(wmOperatorType *ot) +{ + ot->name = "Save User Settings"; + ot->idname = "WM_OT_save_userpref"; + ot->description = "Save user preferences separately, overrides startup file preferences"; + + ot->invoke = WM_operator_confirm; + ot->exec = wm_userpref_write_exec; ot->poll = WM_operator_winactive; } @@ -1691,7 +1704,7 @@ static void WM_OT_read_homefile(wmOperatorType *ot) ot->description = "Open the default file (doesn't save the current file)"; ot->invoke = WM_operator_confirm; - ot->exec = WM_homefile_read_exec; + ot->exec = wm_homefile_read_exec; /* ommit poll to run in background mode */ } @@ -1702,7 +1715,7 @@ static void WM_OT_read_factory_settings(wmOperatorType *ot) ot->description = "Load default file and user preferences"; ot->invoke = WM_operator_confirm; - ot->exec = WM_homefile_read_exec; + ot->exec = wm_homefile_read_exec; /* ommit poll to run in background mode */ } @@ -2003,21 +2016,33 @@ static void WM_OT_link_append(wmOperatorType *ot) /* *************** recover last session **************** */ -static int wm_recover_last_session_exec(bContext *C, wmOperator *op) +void wm_recover_last_session(bContext *C, ReportList *reports) { char filename[FILE_MAX]; - - G.fileflags |= G_FILE_RECOVER; - - /* XXX wm in context is not set correctly after WM_file_read -> crash */ - /* do it before for now, but is this correct with multiple windows? */ - WM_event_add_notifier(C, NC_WINDOW, NULL); - - /* load file */ + BLI_make_file_string("/", filename, BLI_temporary_dir(), "quit.blend"); - WM_file_read(C, filename, op->reports); + /* if reports==NULL, it's called directly without operator, we add a quick check here */ + if (reports || BLI_exists(filename)) { + G.fileflags |= G_FILE_RECOVER; + + /* XXX wm in context is not set correctly after WM_file_read -> crash */ + /* do it before for now, but is this correct with multiple windows? */ + WM_event_add_notifier(C, NC_WINDOW, NULL); + + /* load file */ + WM_file_read(C, filename, reports); + + G.fileflags &= ~G_FILE_RECOVER; + + /* XXX bad global... fixme */ + if (G.main->name[0]) + G.file_loaded = 1; /* prevents splash to show */ + } +} - G.fileflags &= ~G_FILE_RECOVER; +static int wm_recover_last_session_exec(bContext *C, wmOperator *op) +{ + wm_recover_last_session(C, op->reports); return OPERATOR_FINISHED; } @@ -2158,7 +2183,7 @@ static int wm_save_as_mainfile_exec(bContext *C, wmOperator *op) G_FILE_MESH_COMPAT); #endif - if (WM_file_write(C, path, fileflags, op->reports) != 0) + if (wm_file_write(C, path, fileflags, op->reports) != 0) return OPERATOR_CANCELLED; WM_event_add_notifier(C, NC_WM | ND_FILESAVE, NULL); @@ -3787,6 +3812,7 @@ void wm_operatortype_init(void) WM_operatortype_append(WM_OT_read_homefile); WM_operatortype_append(WM_OT_read_factory_settings); WM_operatortype_append(WM_OT_save_homefile); + WM_operatortype_append(WM_OT_save_userpref); WM_operatortype_append(WM_OT_window_fullscreen_toggle); WM_operatortype_append(WM_OT_quit_blender); WM_operatortype_append(WM_OT_open_mainfile); diff --git a/source/blender/windowmanager/intern/wm_subwindow.c b/source/blender/windowmanager/intern/wm_subwindow.c index 9b46dced6bc..1ed9ffb3b6c 100644 --- a/source/blender/windowmanager/intern/wm_subwindow.c +++ b/source/blender/windowmanager/intern/wm_subwindow.c @@ -217,10 +217,10 @@ void wm_subwindow_position(wmWindow *win, int swinid, rcti *winrct) * fixed it). - zr (2001!) */ - if (swin->winrct.xmax > win->sizex) - swin->winrct.xmax = win->sizex; - if (swin->winrct.ymax > win->sizey) - swin->winrct.ymax = win->sizey; + if (swin->winrct.xmax > WM_window_pixels_x(win)) + swin->winrct.xmax = WM_window_pixels_x(win); + if (swin->winrct.ymax > WM_window_pixels_y(win)) + swin->winrct.ymax = WM_window_pixels_y(win); /* extra service */ wmSubWindowSet(win, swinid); @@ -257,8 +257,8 @@ void wmSubWindowScissorSet(wmWindow *win, int swinid, rcti *srct) glViewport(_curswin->winrct.xmin, _curswin->winrct.ymin, width, height); if (srct) { - width = BLI_rcti_size_x(srct) + 1; - height = BLI_rcti_size_y(srct) + 1; + int width = BLI_rcti_size_x(srct) + 1; /* only here */ + int height = BLI_rcti_size_y(srct) + 1; glScissor(srct->xmin, srct->ymin, width, height); } else diff --git a/source/blender/windowmanager/intern/wm_window.c b/source/blender/windowmanager/intern/wm_window.c index 09f7e1692d9..e7be7596598 100644 --- a/source/blender/windowmanager/intern/wm_window.c +++ b/source/blender/windowmanager/intern/wm_window.c @@ -91,7 +91,9 @@ static struct WMInitStruct { int windowstate; WinOverrideFlag override_flag; -} wm_init_state = {0, 0, 0, 0, GHOST_kWindowStateNormal, 0}; + + int native_pixels; +} wm_init_state = {0, 0, 0, 0, GHOST_kWindowStateNormal, 0, 1}; /* ******** win open & close ************ */ @@ -241,7 +243,7 @@ wmWindow *wm_window_copy(bContext *C, wmWindow *winorig) win->screen->do_refresh = TRUE; win->screen->do_draw = TRUE; - win->drawmethod = -1; + win->drawmethod = U.wmdrawmethod; win->drawdata = NULL; return win; @@ -251,51 +253,50 @@ wmWindow *wm_window_copy(bContext *C, wmWindow *winorig) void wm_window_close(bContext *C, wmWindowManager *wm, wmWindow *win) { wmWindow *tmpwin; - bScreen *screen = win->screen; + int do_exit = 0; + + /* first check if we have to quit (there are non-temp remaining windows) */ + for (tmpwin = wm->windows.first; tmpwin; tmpwin = tmpwin->next) { + if (tmpwin == win) + continue; + if (tmpwin->screen->temp == 0) + break; + } + + if (tmpwin == NULL) + do_exit = 1; - /* first check if we have any non-temp remaining windows */ if ((U.uiflag & USER_QUIT_PROMPT) && !wm->file_saved) { - if (wm->windows.first) { - for (tmpwin = wm->windows.first; tmpwin; tmpwin = tmpwin->next) { - if (tmpwin == win) - continue; - if (tmpwin->screen->temp == 0) - break; - } - if (tmpwin == NULL) { - if (!GHOST_confirmQuit(win->ghostwin)) - return; - } + if (do_exit) { + if (!GHOST_confirmQuit(win->ghostwin)) + return; } } - BLI_remlink(&wm->windows, win); - - wm_draw_window_clear(win); - CTX_wm_window_set(C, win); /* needed by handlers */ - WM_event_remove_handlers(C, &win->handlers); - WM_event_remove_handlers(C, &win->modalhandlers); - ED_screen_exit(C, win, win->screen); - - wm_window_free(C, wm, win); - - /* if temp screen, delete it after window free (it stops jobs that can access it) */ - if (screen->temp) { - Main *bmain = CTX_data_main(C); - BKE_libblock_free(&bmain->screen, screen); - } - - /* check remaining windows */ - if (wm->windows.first) { - for (win = wm->windows.first; win; win = win->next) - if (win->screen->temp == 0) - break; - /* in this case we close all */ - if (win == NULL) - WM_exit(C); - } - else + /* let WM_exit do all freeing, for correct quit.blend save */ + if (do_exit) { WM_exit(C); + } + else { + bScreen *screen = win->screen; + + BLI_remlink(&wm->windows, win); + + wm_draw_window_clear(win); + + CTX_wm_window_set(C, win); /* needed by handlers */ + WM_event_remove_handlers(C, &win->handlers); + WM_event_remove_handlers(C, &win->modalhandlers); + ED_screen_exit(C, win, win->screen); + + wm_window_free(C, wm, win); + + /* if temp screen, delete it after window free (it stops jobs that can access it) */ + if (screen->temp) { + Main *bmain = CTX_data_main(C); + BKE_libblock_free(&bmain->screen, screen); + } + } } void wm_window_title(wmWindowManager *wm, wmWindow *win) @@ -309,7 +310,8 @@ void wm_window_title(wmWindowManager *wm, wmWindow *win) /* this is set to 1 if you don't have startup.blend open */ if (G.save_over && G.main->name[0]) { char str[sizeof(G.main->name) + 12]; - BLI_snprintf(str, sizeof(str), "Blender%s [%s]", wm->file_saved ? "" : "*", G.main->name); + BLI_snprintf(str, sizeof(str), "Blender%s [%s%s]", wm->file_saved ? "" : "*", G.main->name, + G.main->recovered ? " (Recovered)" : ""); GHOST_SetTitle(win->ghostwin, str); } else @@ -344,8 +346,6 @@ static void wm_window_add_ghostwindow(const char *title, wmWindow *win) wm_get_screensize(&scr_w, &scr_h); posy = (scr_h - win->posy - win->sizey); - /* Disable AA for now, as GL_SELECT (used for border, lasso, ... select) - * doesn't work well when AA is initialized, even if not used. */ ghostwin = GHOST_CreateWindow(g_system, title, win->posx, posy, win->sizex, win->sizey, (GHOST_TWindowState)win->windowstate, @@ -354,6 +354,8 @@ static void wm_window_add_ghostwindow(const char *title, wmWindow *win) multisamples /* AA */); if (ghostwin) { + GHOST_RectangleHandle bounds; + /* needed so we can detect the graphics card below */ GPU_extensions_init(); @@ -372,7 +374,19 @@ static void wm_window_add_ghostwindow(const char *title, wmWindow *win) if (!GPU_type_matches(GPU_DEVICE_ATI, GPU_OS_UNIX, GPU_DRIVER_OPENSOURCE)) { glClear(GL_COLOR_BUFFER_BIT); } + + /* displays with larger native pixels, like Macbook. Used to scale dpi with */ + /* needed here, because it's used before it reads userdef */ + U.pixelsize = GHOST_GetNativePixelSize(); + BKE_userdef_state(); + + /* store actual window size in blender window */ + bounds = GHOST_GetClientBounds(win->ghostwin); + win->sizex = GHOST_GetWidthRectangle(bounds); + win->sizey = GHOST_GetHeightRectangle(bounds); + GHOST_DisposeRectangle(bounds); + wm_window_swap_buffers(win); //GHOST_SetWindowState(ghostwin, GHOST_kWindowStateModified); @@ -468,7 +482,7 @@ wmWindow *WM_window_open(bContext *C, rcti *rect) win->sizex = BLI_rcti_size_x(rect); win->sizey = BLI_rcti_size_y(rect); - win->drawmethod = -1; + win->drawmethod = U.wmdrawmethod; win->drawdata = NULL; WM_check(C); @@ -578,6 +592,23 @@ int wm_window_fullscreen_toggle_exec(bContext *C, wmOperator *UNUSED(op)) /* ************ events *************** */ +static void wm_convert_cursor_position(wmWindow *win, int *x, int *y) +{ + + GHOST_ScreenToClient(win->ghostwin, *x, *y, x, y); + *x *= GHOST_GetNativePixelSize(); + + *y = (win->sizey - 1) - *y; + *y *= GHOST_GetNativePixelSize(); +} + + +void wm_get_cursor_position(wmWindow *win, int *x, int *y) +{ + GHOST_GetCursorPosition(g_system, x, y); + wm_convert_cursor_position(win, x, y); +} + typedef enum { SHIFT = 's', CONTROL = 'c', @@ -633,6 +664,7 @@ void wm_window_make_drawable(bContext *C, wmWindow *win) } /* called by ghost, here we handle events for windows themselves or send to event system */ +/* mouse coordinate converversion happens here */ static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr C_void_ptr) { bContext *C = C_void_ptr; @@ -673,7 +705,7 @@ static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr C_void_ptr { GHOST_TEventKeyData kdata; wmEvent event; - int cx, cy, wx, wy; + int wx, wy; wm->winactive = win; /* no context change! c->wm->windrawable is drawable, or for area queues */ @@ -703,11 +735,10 @@ static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr C_void_ptr win->eventstate->keymodifier = 0; /* entering window, update mouse pos. but no event */ - GHOST_GetCursorPosition(g_system, &wx, &wy); - - GHOST_ScreenToClient(win->ghostwin, wx, wy, &cx, &cy); - win->eventstate->x = cx; - win->eventstate->y = (win->sizey - 1) - cy; + wm_get_cursor_position(win, &wx, &wy); + + win->eventstate->x = wx; + win->eventstate->y = wy; win->addmousemove = 1; /* enables highlighted buttons */ @@ -857,14 +888,12 @@ static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr C_void_ptr { wmEvent event; GHOST_TEventDragnDropData *ddd = GHOST_GetEventData(evt); - int cx, cy, wx, wy; + int wx, wy; /* entering window, update mouse pos */ - GHOST_GetCursorPosition(g_system, &wx, &wy); - - GHOST_ScreenToClient(win->ghostwin, wx, wy, &cx, &cy); - win->eventstate->x = cx; - win->eventstate->y = (win->sizey - 1) - cy; + wm_get_cursor_position(win, &wx, &wy); + win->eventstate->x = wx; + win->eventstate->y = wy; event = *(win->eventstate); /* copy last state, like mouse coords */ @@ -907,11 +936,24 @@ static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr C_void_ptr } } - - break; } - + case GHOST_kEventTrackpad: + { + GHOST_TEventTrackpadData *pd = data; + + wm_convert_cursor_position(win, &pd->x, &pd->y); + wm_event_add_ghostevent(wm, win, type, time, data); + break; + } + case GHOST_kEventCursorMove: + { + GHOST_TEventCursorData *cd = data; + + wm_convert_cursor_position(win, &cd->x, &cd->y); + wm_event_add_ghostevent(wm, win, type, time, data); + break; + } default: wm_event_add_ghostevent(wm, win, type, time, data); break; @@ -1017,6 +1059,10 @@ void wm_ghost_init(bContext *C) g_system = GHOST_CreateSystem(); GHOST_AddEventConsumer(g_system, consumer); + + if (wm_init_state.native_pixels) { + GHOST_UseNativePixels(); + } } } @@ -1068,6 +1114,8 @@ void WM_event_remove_timer(wmWindowManager *wm, wmWindow *UNUSED(win), wmTimer * if (wt == timer) break; if (wt) { + wmWindow *win; + if (wm->reports.reporttimer == wt) wm->reports.reporttimer = NULL; @@ -1075,6 +1123,16 @@ void WM_event_remove_timer(wmWindowManager *wm, wmWindow *UNUSED(win), wmTimer * if (wt->customdata) MEM_freeN(wt->customdata); MEM_freeN(wt); + + /* there might be events in queue with this timer as customdata */ + for (win = wm->windows.first; win; win = win->next) { + wmEvent *event; + for (event = win->queue.first; event; event = event->next) { + if (event->customdata == wt) { + event->customdata = NULL; + } + } + } } } @@ -1158,23 +1216,6 @@ void wm_window_get_position(wmWindow *win, int *posx_r, int *posy_r) *posy_r = win->posy; } -void wm_window_get_size(wmWindow *win, int *width_r, int *height_r) -{ - *width_r = win->sizex; - *height_r = win->sizey; -} - -/* exceptional case: - splash is called before events are processed - * this means we don't actually know the window size so get this from GHOST */ -void wm_window_get_size_ghost(wmWindow *win, int *width_r, int *height_r) -{ - GHOST_RectangleHandle bounds = GHOST_GetClientBounds(win->ghostwin); - *width_r = GHOST_GetWidthRectangle(bounds); - *height_r = GHOST_GetHeightRectangle(bounds); - - GHOST_DisposeRectangle(bounds); -} - void wm_window_set_size(wmWindow *win, int width, int height) { GHOST_SetClientSize(win->ghostwin, width, height); @@ -1202,12 +1243,6 @@ void wm_window_swap_buffers(wmWindow *win) #endif } -void wm_get_cursor_position(wmWindow *win, int *x, int *y) -{ - GHOST_GetCursorPosition(g_system, x, y); - GHOST_ScreenToClient(win->ghostwin, *x, *y, x, y); - *y = (win->sizey - 1) - *y; -} /* ******************* exported api ***************** */ @@ -1217,8 +1252,8 @@ void WM_init_state_size_set(int stax, int stay, int sizx, int sizy) { wm_init_state.start_x = stax; /* left hand pos */ wm_init_state.start_y = stay; /* bottom pos */ - wm_init_state.size_x = sizx; - wm_init_state.size_y = sizy; + wm_init_state.size_x = sizx < 640 ? 640 : sizx; + wm_init_state.size_y = sizy < 480 ? 480 : sizy; wm_init_state.override_flag |= WIN_OVERRIDE_GEOM; } @@ -1235,12 +1270,20 @@ void WM_init_state_normal_set(void) wm_init_state.override_flag |= WIN_OVERRIDE_WINSTATE; } +void WM_init_native_pixels(int do_it) +{ + wm_init_state.native_pixels = do_it; +} + /* This function requires access to the GHOST_SystemHandle (g_system) */ void WM_cursor_warp(wmWindow *win, int x, int y) { if (win && win->ghostwin) { + float f = GHOST_GetNativePixelSize(); int oldx = x, oldy = y; + x = x / f; + y = y / f; y = win->sizey - y - 1; GHOST_ClientToScreen(win->ghostwin, x, y, &x, &y); @@ -1251,3 +1294,19 @@ void WM_cursor_warp(wmWindow *win, int x, int y) } } +/* support for native pixel size */ +/* mac retina opens window in size X, but it has up to 2 x more pixels */ +int WM_window_pixels_x(wmWindow *win) +{ + float f = GHOST_GetNativePixelSize(); + + return (int)(f * (float)win->sizex); +} + +int WM_window_pixels_y(wmWindow *win) +{ + float f = GHOST_GetNativePixelSize(); + + return (int)(f * (float)win->sizey); + +} diff --git a/source/blender/windowmanager/wm_event_system.h b/source/blender/windowmanager/wm_event_system.h index 2d0dd2ef911..2fbfdc41bce 100644 --- a/source/blender/windowmanager/wm_event_system.h +++ b/source/blender/windowmanager/wm_event_system.h @@ -107,5 +107,8 @@ void wm_dropbox_free(void); void wm_drags_check_ops(bContext *C, wmEvent *event); void wm_drags_draw(bContext *C, wmWindow *win, rcti *rect); +/* wm_operators.c */ +void wm_recover_last_session(bContext *C, ReportList *reports); + #endif /* __WM_EVENT_SYSTEM_H__ */ diff --git a/source/blender/windowmanager/wm_event_types.h b/source/blender/windowmanager/wm_event_types.h index 4d3d6ef89d9..de28cf5409d 100644 --- a/source/blender/windowmanager/wm_event_types.h +++ b/source/blender/windowmanager/wm_event_types.h @@ -148,6 +148,7 @@ enum { #define TIMERJOBS 0x0114 /* timer event, jobs system */ #define TIMERAUTOSAVE 0x0115 /* timer event, autosave */ #define TIMERREPORT 0x0116 /* timer event, reports */ +#define TIMERREGION 0x0117 /* timer event, region slide in/out */ #define TIMERF 0x011F /* last timer */ /* test whether the event is timer event */ diff --git a/source/blender/windowmanager/wm_files.h b/source/blender/windowmanager/wm_files.h index f373530b5e6..fe007e7f52f 100644 --- a/source/blender/windowmanager/wm_files.h +++ b/source/blender/windowmanager/wm_files.h @@ -31,7 +31,13 @@ #ifndef __WM_FILES_H__ #define __WM_FILES_H__ -void WM_read_history(void); +void wm_read_history(void); +int wm_file_write(struct bContext *C, const char *target, int fileflags, struct ReportList *reports); +int wm_homefile_read_exec(struct bContext *C, struct wmOperator *op); +int wm_homefile_read(struct bContext *C, struct ReportList *reports, short from_memory); +int wm_homefile_write_exec(struct bContext *C, struct wmOperator *op); +int wm_userpref_write_exec(struct bContext *C, struct wmOperator *op); + #endif /* __WM_FILES_H__ */ diff --git a/source/blender/windowmanager/wm_window.h b/source/blender/windowmanager/wm_window.h index 6360cfd4802..ce360f5ef56 100644 --- a/source/blender/windowmanager/wm_window.h +++ b/source/blender/windowmanager/wm_window.h @@ -55,8 +55,6 @@ void wm_window_make_drawable(bContext *C, wmWindow *win); void wm_window_raise (wmWindow *win); void wm_window_lower (wmWindow *win); void wm_window_set_size (wmWindow *win, int width, int height); -void wm_window_get_size (wmWindow *win, int *width_r, int *height_r); -void wm_window_get_size_ghost(wmWindow *win, int *width_r, int *height_r); void wm_window_get_position (wmWindow *win, int *posx_r, int *posy_r); void wm_window_swap_buffers (wmWindow *win); diff --git a/source/creator/creator.c b/source/creator/creator.c index 0f1207a9a88..a05fcac4c89 100644 --- a/source/creator/creator.c +++ b/source/creator/creator.c @@ -481,6 +481,12 @@ static int prefsize(int argc, const char **argv, void *UNUSED(data)) return 4; } +static int native_pixels(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data)) +{ + WM_init_native_pixels(0); + return 0; +} + static int with_borders(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data)) { WM_init_state_normal_set(); @@ -1159,6 +1165,7 @@ static void setupArguments(bContext *C, bArgs *ba, SYS_SystemHandle *syshandle) BLI_argsAdd(ba, 2, "-con", "--start-console", "\n\tStart with the console window open (ignored if -b is set)", start_with_console, NULL); BLI_argsAdd(ba, 2, "-R", NULL, "\n\tRegister .blend extension, then exit (Windows only)", register_extension, NULL); BLI_argsAdd(ba, 2, "-r", NULL, "\n\tSilently register .blend extension, then exit (Windows only)", register_extension, ba); + BLI_argsAdd(ba, 2, NULL, "--no-native-pixels", "\n\tDo not use native pixel size, for high resolution displays (MacBook 'Retina')", native_pixels, ba); /* third pass: disabling things and forcing settings */ BLI_argsAddCase(ba, 3, "-nojoystick", 1, NULL, 0, "\n\tDisable joystick support", no_joystick, syshandle); From dcf6e5f5f68b48f5536502849e53fa966d7bc40c Mon Sep 17 00:00:00 2001 From: Ton Roosendaal Date: Wed, 12 Dec 2012 19:09:25 +0000 Subject: [PATCH 068/252] Quick fix for ghost error - solves pixelsize to return 0. --- source/blender/windowmanager/intern/wm_files.c | 1 + 1 file changed, 1 insertion(+) diff --git a/source/blender/windowmanager/intern/wm_files.c b/source/blender/windowmanager/intern/wm_files.c index 2e2595259ce..0f983cbd568 100644 --- a/source/blender/windowmanager/intern/wm_files.c +++ b/source/blender/windowmanager/intern/wm_files.c @@ -305,6 +305,7 @@ static void wm_init_userdef(bContext *C) /* displays with larger native pixels, like Macbook. Used to scale dpi with */ U.pixelsize = GHOST_GetNativePixelSize(); + if (U.pixelsize == 0) U.pixelsize = 1; BKE_userdef_state(); } From 7605e9dbf2dea7b1ad502e9710de44273c7dc394 Mon Sep 17 00:00:00 2001 From: Ton Roosendaal Date: Wed, 12 Dec 2012 19:16:19 +0000 Subject: [PATCH 069/252] Better patch for pixelsize to be zero - ghost code is going to be fixed next. --- source/blender/blenkernel/intern/blender.c | 1 + 1 file changed, 1 insertion(+) diff --git a/source/blender/blenkernel/intern/blender.c b/source/blender/blenkernel/intern/blender.c index 3aa425bdbb9..8a29e5ea1a7 100644 --- a/source/blender/blenkernel/intern/blender.c +++ b/source/blender/blenkernel/intern/blender.c @@ -403,6 +403,7 @@ void BKE_userdef_free(void) /* handle changes in settings that need recalc */ void BKE_userdef_state(void) { + if (U.pixelsize == 0) U.pixelsize = 1; BLF_default_dpi(U.pixelsize * U.dpi); U.widget_unit = (U.pixelsize * U.dpi * 20 + 36) / 72; From fc65922124a17a01c90615eb1723c64058f372a8 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Wed, 12 Dec 2012 19:20:36 +0000 Subject: [PATCH 070/252] GHOST should now be finally fixed --- intern/ghost/intern/GHOST_System.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/intern/ghost/intern/GHOST_System.cpp b/intern/ghost/intern/GHOST_System.cpp index a008d224a20..41beeac6b51 100644 --- a/intern/ghost/intern/GHOST_System.cpp +++ b/intern/ghost/intern/GHOST_System.cpp @@ -45,7 +45,9 @@ GHOST_System::GHOST_System() - : m_displayManager(0), + : m_nativePixel(false), + m_nativePixelSize(1), + m_displayManager(0), m_timerManager(0), m_windowManager(0), m_eventManager(0) @@ -376,7 +378,7 @@ int GHOST_System::confirmQuit(GHOST_IWindow *window) const bool GHOST_System::useNativePixel(void) { - m_nativePixel = 1; + m_nativePixel = true; return 1; } From 8af6721eb5c94f29c3d4d21c0b1431dda3b1cf84 Mon Sep 17 00:00:00 2001 From: Jens Verwiebe Date: Wed, 12 Dec 2012 19:54:14 +0000 Subject: [PATCH 071/252] OSX: make cmake and scons both compile jack and ndof with newer sdk's --- CMakeLists.txt | 2 +- SConstruct | 5 +++-- build_files/scons/config/darwin-config.py | 2 +- intern/ghost/SConscript | 2 +- intern/ghost/intern/GHOST_NDOFManagerCocoa.mm | 2 +- 5 files changed, 7 insertions(+), 6 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 7433d7259ac..9b9fafdf514 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1522,7 +1522,7 @@ elseif(APPLE) if(WITH_INPUT_NDOF) set(PLATFORM_LINKFLAGS "${PLATFORM_LINKFLAGS} -F/Library/Frameworks -weak_framework 3DconnexionClient") - set(NDOF_INCLUDE_DIRS /Library/Frameworks/3DconnexionClient.framework ) + set(NDOF_INCLUDE_DIRS /Library/Frameworks/3DconnexionClient.framework/Headers ) endif() endif() diff --git a/SConstruct b/SConstruct index c2bae0459ca..34d1742ee56 100644 --- a/SConstruct +++ b/SConstruct @@ -294,7 +294,8 @@ if env['OURPLATFORM']=='darwin': print "3D_CONNEXION_CLIENT_LIBRARY not found, disabling WITH_BF_3DMOUSE" # avoid build errors ! env['WITH_BF_3DMOUSE'] = 0 else: - env.Append(LINKFLAGS=['-Xlinker','-weak_framework','-Xlinker','3DconnexionClient']) + env.Append(LINKFLAGS=['-F/Library/Frameworks','-Xlinker','-weak_framework','-Xlinker','3DconnexionClient']) + env['BF_3DMOUSE_INC'] = '/Library/Frameworks/3DconnexionClient.framework/Headers' # for now, Mac builders must download and install the JackOSX framework # necessary header file lives here when installed: @@ -304,7 +305,7 @@ if env['OURPLATFORM']=='darwin': print "JackOSX install not found, disabling WITH_BF_JACK" # avoid build errors ! env['WITH_BF_JACK'] = 0 else: - env.Append(LINKFLAGS=['-Xlinker','-weak_framework','-Xlinker','Jackmp']) + env.Append(LINKFLAGS=['-L/Library/Frameworks','-Xlinker','-weak_framework','-Xlinker','Jackmp']) if env['WITH_BF_CYCLES_OSL'] == 1: OSX_OSL_LIBPATH = Dir(env.subst(env['BF_OSL_LIBPATH'])).abspath diff --git a/build_files/scons/config/darwin-config.py b/build_files/scons/config/darwin-config.py index 252a1b1b37e..207ddd3579b 100644 --- a/build_files/scons/config/darwin-config.py +++ b/build_files/scons/config/darwin-config.py @@ -165,7 +165,7 @@ BF_CXX_LIB_STATIC = '${BF_CXX}/lib/libstdc++.a' WITH_BF_JACK = True BF_JACK = '/Library/Frameworks/Jackmp.framework' BF_JACK_INC = '${BF_JACK}/headers' -BF_JACK_LIB = 'jack' +#BF_JACK_LIB = 'jack' # not used due framework BF_JACK_LIBPATH = '${BF_JACK}' WITH_BF_SNDFILE = True diff --git a/intern/ghost/SConscript b/intern/ghost/SConscript index 44882a64286..96d9cfb98f8 100644 --- a/intern/ghost/SConscript +++ b/intern/ghost/SConscript @@ -93,7 +93,7 @@ else: if env['WITH_BF_3DMOUSE']: defs.append('WITH_INPUT_NDOF') - if env['OURPLATFORM']=='linux': + if env['OURPLATFORM'] in ('linux','darwin'): incs += ' ' + env['BF_3DMOUSE_INC'] else: sources.remove('intern' + os.sep + 'GHOST_NDOFManager.cpp') diff --git a/intern/ghost/intern/GHOST_NDOFManagerCocoa.mm b/intern/ghost/intern/GHOST_NDOFManagerCocoa.mm index d29dd4dd3e8..0d009e17561 100644 --- a/intern/ghost/intern/GHOST_NDOFManagerCocoa.mm +++ b/intern/ghost/intern/GHOST_NDOFManagerCocoa.mm @@ -27,7 +27,7 @@ #include "GHOST_SystemCocoa.h" extern "C" { - #include <3DconnexionClient/ConnexionClientAPI.h> + #include #include } From 69ba2d3edb06d529be724431ef226eb57b248aa4 Mon Sep 17 00:00:00 2001 From: Ton Roosendaal Date: Wed, 12 Dec 2012 19:56:24 +0000 Subject: [PATCH 072/252] Crash, IRC report. Moving panels in a buttons-region around was calling menu code, reading NULL pointer. Seems to be an existing issue, not caused by my previous commit :) --- source/blender/editors/interface/interface_handlers.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c index 258775867cc..4f6e184dceb 100644 --- a/source/blender/editors/interface/interface_handlers.c +++ b/source/blender/editors/interface/interface_handlers.c @@ -6927,11 +6927,12 @@ static int ui_handler_region_menu(bContext *C, wmEvent *event, void *UNUSED(user if (data->state == BUTTON_STATE_MENU_OPEN) { /* handle events for menus and their buttons recursively, * this will handle events from the top to the bottom menu */ - retval = ui_handle_menus_recursive(C, event, data->menu, 0); + if (data->menu) + retval = ui_handle_menus_recursive(C, event, data->menu, 0); /* handle events for the activated button */ if (retval == WM_UI_HANDLER_CONTINUE || event->type == TIMER) { - if (data->menu->menuretval) + if (data->menu && data->menu->menuretval) ui_handle_button_return_submenu(C, event, but); else ui_handle_button_event(C, event, but); From 160ebfa4c4b6b85b8266f8473160fa9bf4feb222 Mon Sep 17 00:00:00 2001 From: Ton Roosendaal Date: Wed, 12 Dec 2012 20:31:12 +0000 Subject: [PATCH 073/252] Disable a bugfix I did - to prevent event timers to be used still. Code looks sane, but somehow it frustrates the panel animation timer, causing freezes now. Work for tomorrow. --- source/blender/windowmanager/intern/wm_window.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/windowmanager/intern/wm_window.c b/source/blender/windowmanager/intern/wm_window.c index e7be7596598..3c56e8d341e 100644 --- a/source/blender/windowmanager/intern/wm_window.c +++ b/source/blender/windowmanager/intern/wm_window.c @@ -1129,7 +1129,7 @@ void WM_event_remove_timer(wmWindowManager *wm, wmWindow *UNUSED(win), wmTimer * wmEvent *event; for (event = win->queue.first; event; event = event->next) { if (event->customdata == wt) { - event->customdata = NULL; + //event->customdata = NULL; } } } From 9211fae41e294aefc980dd8fcb37ac9fed2efe1a Mon Sep 17 00:00:00 2001 From: Ton Roosendaal Date: Wed, 12 Dec 2012 22:02:08 +0000 Subject: [PATCH 074/252] Bugfix, irc report: Crash on running in background mode. Calling GHOST function, but there is no GHOST initialized. Easy to skip. --- source/blender/windowmanager/intern/wm_files.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/source/blender/windowmanager/intern/wm_files.c b/source/blender/windowmanager/intern/wm_files.c index 0f983cbd568..6c16c968a81 100644 --- a/source/blender/windowmanager/intern/wm_files.c +++ b/source/blender/windowmanager/intern/wm_files.c @@ -304,8 +304,10 @@ static void wm_init_userdef(bContext *C) BLI_init_temporary_dir(U.tempdir); /* displays with larger native pixels, like Macbook. Used to scale dpi with */ - U.pixelsize = GHOST_GetNativePixelSize(); + if (G.background == FALSE) + U.pixelsize = GHOST_GetNativePixelSize(); if (U.pixelsize == 0) U.pixelsize = 1; + BKE_userdef_state(); } From 9a848c1a9d286bc3fd3bef837963f59000524a59 Mon Sep 17 00:00:00 2001 From: Alex Fraser Date: Wed, 12 Dec 2012 22:42:55 +0000 Subject: [PATCH 075/252] Can now set a lower bound on the number of subframes (i.e. an upper bound on the time step size) for fluid simulations. Previously, the "subframes" parameter was not available when the adaptive time step was enabled; now they can both be set. The two settings can be used together to greatly increase simulation stability. --- .../startup/bl_ui/properties_particle.py | 12 ++++--- .../blenkernel/intern/particle_system.c | 34 +++++++++++++++---- source/blender/makesrna/intern/rna_particle.c | 6 ++-- 3 files changed, 37 insertions(+), 15 deletions(-) diff --git a/release/scripts/startup/bl_ui/properties_particle.py b/release/scripts/startup/bl_ui/properties_particle.py index 3f672d2a977..75154550bcb 100644 --- a/release/scripts/startup/bl_ui/properties_particle.py +++ b/release/scripts/startup/bl_ui/properties_particle.py @@ -490,11 +490,13 @@ class PARTICLE_PT_physics(ParticleButtonsPanel, Panel): col.prop(part, "integrator", text="") col.prop(part, "timestep") sub = col.row() - if part.adaptive_subframes: - sub.prop(part, "courant_target", text="Threshold") - else: - sub.prop(part, "subframes") - sub.prop(part, "adaptive_subframes", text="") + sub.prop(part, "subframes") + supports_courant = part.physics_type == 'FLUID' + subsub = sub.row() + subsub.enabled = supports_courant + subsub.prop(part, "adaptive_subframes", text="") + if supports_courant and part.adaptive_subframes: + col.prop(part, "courant_target", text="Threshold") row = layout.row() row.prop(part, "use_size_deflect") diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c index 90889d7c09e..d5fabf60079 100644 --- a/source/blender/blenkernel/intern/particle_system.c +++ b/source/blender/blenkernel/intern/particle_system.c @@ -3781,11 +3781,12 @@ static void save_hair(ParticleSimulationData *sim, float UNUSED(cfra)) /* Code for an adaptive time step based on the Courant-Friedrichs-Lewy * condition. */ -#define MIN_TIMESTEP 1.0f / 101.0f +static const float MIN_TIMESTEP = 1.0f / 101.0f; /* Tolerance of 1.5 means the last subframe neither favors growing nor * shrinking (e.g if it were 1.3, the last subframe would tend to be too * small). */ -#define TIMESTEP_EXPANSION_TOLERANCE 1.5f +static const float TIMESTEP_EXPANSION_FACTOR = 0.1f; +static const float TIMESTEP_EXPANSION_TOLERANCE = 1.5f; /* Calculate the speed of the particle relative to the local scale of the * simulation. This should be called once per particle during a simulation @@ -3802,14 +3803,31 @@ static void update_courant_num(ParticleSimulationData *sim, ParticleData *pa, if (sim->courant_num < speed * dtime / sphdata->element_size) sim->courant_num = speed * dtime / sphdata->element_size; } +static float get_base_time_step(ParticleSettings *part) { + return 1.0f / (float) (part->subframes + 1); +} /* Update time step size to suit current conditions. */ static float update_timestep(ParticleSystem *psys, ParticleSimulationData *sim, float t_frac) { + float dt_target; if (sim->courant_num == 0.0f) - psys->dt_frac = 1.0f; + dt_target = 1.0f; else - psys->dt_frac *= (psys->part->courant_target / sim->courant_num); - CLAMP(psys->dt_frac, MIN_TIMESTEP, 1.0f); + dt_target = psys->dt_frac * (psys->part->courant_target / sim->courant_num); + + /* Make sure the time step is reasonable. + * For some reason, the CLAMP macro doesn't work here. The time step becomes + * too large. - z0r */ + if (dt_target < MIN_TIMESTEP) + dt_target = MIN_TIMESTEP; + else if (dt_target > get_base_time_step(psys->part)) + dt_target = get_base_time_step(psys->part); + + /* Decrease time step instantly, but expand slowly. */ + if (dt_target > psys->dt_frac) + psys->dt_frac = interpf(dt_target, psys->dt_frac, TIMESTEP_EXPANSION_FACTOR); + else + psys->dt_frac = dt_target; /* Sync with frame end if it's close. */ if (t_frac == 1.0f) @@ -4307,14 +4325,16 @@ static void system_step(ParticleSimulationData *sim, float cfra) if ((int)cfra == startframe && part->sta < startframe) totframesback = (startframe - (int)part->sta); + /* Initialise time step. This may change if automatic subframes are + * enabled. */ if (!(part->time_flag & PART_TIME_AUTOSF)) { /* Constant time step */ - psys->dt_frac = 1.0f / (float) (part->subframes + 1); + psys->dt_frac = get_base_time_step(part); } else if ((int)cfra == startframe) { /* Variable time step; use a very conservative value at the start. * If it doesn't need to be so small, it will quickly grow. */ - psys->dt_frac = 1.0; + psys->dt_frac = get_base_time_step(part); } else if (psys->dt_frac < MIN_TIMESTEP) { psys->dt_frac = MIN_TIMESTEP; diff --git a/source/blender/makesrna/intern/rna_particle.c b/source/blender/makesrna/intern/rna_particle.c index 6825d3d781d..96b6197cf69 100644 --- a/source/blender/makesrna/intern/rna_particle.c +++ b/source/blender/makesrna/intern/rna_particle.c @@ -2129,11 +2129,11 @@ static void rna_def_particle_settings(BlenderRNA *brna) RNA_def_property_update(prop, 0, "rna_Particle_reset"); prop = RNA_def_property(srna, "courant_target", PROP_FLOAT, PROP_NONE); - RNA_def_property_range(prop, 0.01, 10); - RNA_def_property_float_default(prop, 0.2); + RNA_def_property_range(prop, 0.0001, 10); + RNA_def_property_float_default(prop, 0.1); RNA_def_property_ui_text(prop, "Adaptive Subframe Threshold", "The relative distance a particle can move before requiring more subframes " - "(target Courant number); 0.1-0.3 is the recommended range"); + "(target Courant number); 0.01-0.3 is the recommended range"); RNA_def_property_update(prop, 0, "rna_Particle_reset"); prop = RNA_def_property(srna, "jitter_factor", PROP_FLOAT, PROP_NONE); From d6a291ca37fbe183873a62034692eab53e8d9278 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 13 Dec 2012 00:41:23 +0000 Subject: [PATCH 076/252] fix another crash from missing update in Auto-Merge from r52911 --- source/blender/editors/mesh/editmesh_select.c | 22 ++++++++++--------- .../editors/transform/transform_conversions.c | 2 +- source/blender/makesrna/intern/rna_object.c | 2 ++ 3 files changed, 15 insertions(+), 11 deletions(-) diff --git a/source/blender/editors/mesh/editmesh_select.c b/source/blender/editors/mesh/editmesh_select.c index 6adcede9699..a8f6ccc6c2c 100644 --- a/source/blender/editors/mesh/editmesh_select.c +++ b/source/blender/editors/mesh/editmesh_select.c @@ -107,21 +107,23 @@ void EDBM_select_mirrored(Object *UNUSED(obedit), BMEditMesh *em, int extend) void EDBM_automerge(Scene *scene, Object *obedit, int update) { - BMEditMesh *em; if ((scene->toolsettings->automerge) && (obedit && obedit->type == OB_MESH)) { - em = BMEdit_FromObject(obedit); - if (!em) - return; + int ok; + BMEditMesh *em = BMEdit_FromObject(obedit); - BMO_op_callf(em->bm, BMO_FLAG_DEFAULTS, - "automerge verts=%hv dist=%f", - BM_ELEM_SELECT, scene->toolsettings->doublimit); - if (update) { - DAG_id_tag_update(obedit->data, OB_RECALC_DATA); - BMEdit_RecalcTessellation(em); + if (!em) { + return; + } + + ok = BMO_op_callf(em->bm, BMO_FLAG_DEFAULTS, + "automerge verts=%hv dist=%f", + BM_ELEM_SELECT, scene->toolsettings->doublimit); + + if (LIKELY(ok) && update) { + EDBM_update_generic(em, TRUE, TRUE); } } } diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c index dc33b851db8..ea852fdb098 100644 --- a/source/blender/editors/transform/transform_conversions.c +++ b/source/blender/editors/transform/transform_conversions.c @@ -5131,7 +5131,7 @@ void special_aftertrans_update(bContext *C, TransInfo *t) * during cleanup - psy-fi */ freeSlideTempFaces(sld); } - EDBM_automerge(t->scene, t->obedit, 1); + EDBM_automerge(t->scene, t->obedit, TRUE); } else { if (t->mode == TFM_EDGE_SLIDE) { diff --git a/source/blender/makesrna/intern/rna_object.c b/source/blender/makesrna/intern/rna_object.c index df7c4d78531..c49bdf032fc 100644 --- a/source/blender/makesrna/intern/rna_object.c +++ b/source/blender/makesrna/intern/rna_object.c @@ -94,6 +94,7 @@ static EnumPropertyItem parent_type_items[] = { {0, NULL, 0, NULL, NULL} }; +#ifndef RNA_RUNTIME static EnumPropertyItem dupli_items[] = { {0, "NONE", 0, "None", ""}, {OB_DUPLIFRAMES, "FRAMES", 0, "Frames", "Make copy of object for every frame"}, @@ -102,6 +103,7 @@ static EnumPropertyItem dupli_items[] = { {OB_DUPLIGROUP, "GROUP", 0, "Group", "Enable group instancing"}, {0, NULL, 0, NULL, NULL} }; +#endif static EnumPropertyItem collision_bounds_items[] = { {OB_BOUND_BOX, "BOX", 0, "Box", ""}, From 0260e4b8a38cc567eda0679aaf7723ff442bdc34 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 13 Dec 2012 00:47:47 +0000 Subject: [PATCH 077/252] code cleanup: quiet warnings --- source/blender/blenkernel/BKE_blender.h | 2 +- source/blender/blenkernel/intern/blender.c | 2 +- source/blender/editors/screen/area.c | 16 ++++++++-------- source/blender/editors/screen/screen_ops.c | 6 +++--- source/blender/editors/space_nla/nla_draw.c | 4 ++-- .../editors/space_outliner/outliner_draw.c | 5 ++++- source/blender/windowmanager/intern/wm_files.c | 2 +- .../blender/windowmanager/intern/wm_init_exit.c | 2 +- 8 files changed, 21 insertions(+), 18 deletions(-) diff --git a/source/blender/blenkernel/BKE_blender.h b/source/blender/blenkernel/BKE_blender.h index ffdbc9cb9d8..622b5090f05 100644 --- a/source/blender/blenkernel/BKE_blender.h +++ b/source/blender/blenkernel/BKE_blender.h @@ -99,7 +99,7 @@ extern void BKE_reset_undo(void); extern char *BKE_undo_menu_string(void); extern void BKE_undo_number(struct bContext *C, int nr); extern const char *BKE_undo_get_name(int nr, int *active); -extern int BKE_undo_save_file(const struct bContext *C, char *filename); +extern int BKE_undo_save_file(const char *filename); extern struct Main *BKE_undo_get_main(struct Scene **scene); /* copybuffer */ diff --git a/source/blender/blenkernel/intern/blender.c b/source/blender/blenkernel/intern/blender.c index 8a29e5ea1a7..7ee3bddc82b 100644 --- a/source/blender/blenkernel/intern/blender.c +++ b/source/blender/blenkernel/intern/blender.c @@ -788,7 +788,7 @@ char *BKE_undo_menu_string(void) } /* saves .blend using undo buffer, returns 1 == success */ -int BKE_undo_save_file(const bContext *C, char *filename) +int BKE_undo_save_file(const char *filename) { UndoElem *uel; MemFileChunk *chunk; diff --git a/source/blender/editors/screen/area.c b/source/blender/editors/screen/area.c index 852ce02fa40..80270116a13 100644 --- a/source/blender/editors/screen/area.c +++ b/source/blender/editors/screen/area.c @@ -699,28 +699,28 @@ static void region_azone_tab_plus(ScrArea *sa, AZone *az, ARegion *ar) switch (az->edge) { case AE_TOP_TO_BOTTOMRIGHT: if (ar->winrct.ymax == sa->totrct.ymin) add = 1; else add = 0; - az->x1 = ar->winrct.xmax - 2.5 * AZONEPAD_TAB_PLUSW; + az->x1 = ar->winrct.xmax - 2.5f * AZONEPAD_TAB_PLUSW; az->y1 = ar->winrct.ymax - add; - az->x2 = ar->winrct.xmax - 1.5 * AZONEPAD_TAB_PLUSW; + az->x2 = ar->winrct.xmax - 1.5f * AZONEPAD_TAB_PLUSW; az->y2 = ar->winrct.ymax - add + AZONEPAD_TAB_PLUSH; break; case AE_BOTTOM_TO_TOPLEFT: - az->x1 = ar->winrct.xmax - 2.5 * AZONEPAD_TAB_PLUSW; + az->x1 = ar->winrct.xmax - 2.5f * AZONEPAD_TAB_PLUSW; az->y1 = ar->winrct.ymin - AZONEPAD_TAB_PLUSH; - az->x2 = ar->winrct.xmax - 1.5 * AZONEPAD_TAB_PLUSW; + az->x2 = ar->winrct.xmax - 1.5f * AZONEPAD_TAB_PLUSW; az->y2 = ar->winrct.ymin; break; case AE_LEFT_TO_TOPRIGHT: az->x1 = ar->winrct.xmin - AZONEPAD_TAB_PLUSH; - az->y1 = ar->winrct.ymax - 2.5 * AZONEPAD_TAB_PLUSW; + az->y1 = ar->winrct.ymax - 2.5f * AZONEPAD_TAB_PLUSW; az->x2 = ar->winrct.xmin; - az->y2 = ar->winrct.ymax - 1.5 * AZONEPAD_TAB_PLUSW; + az->y2 = ar->winrct.ymax - 1.5f * AZONEPAD_TAB_PLUSW; break; case AE_RIGHT_TO_TOPLEFT: az->x1 = ar->winrct.xmax - 1; - az->y1 = ar->winrct.ymax - 2.5 * AZONEPAD_TAB_PLUSW; + az->y1 = ar->winrct.ymax - 2.5f * AZONEPAD_TAB_PLUSW; az->x2 = ar->winrct.xmax - 1 + AZONEPAD_TAB_PLUSH; - az->y2 = ar->winrct.ymax - 1.5 * AZONEPAD_TAB_PLUSW; + az->y2 = ar->winrct.ymax - 1.5f * AZONEPAD_TAB_PLUSW; break; } /* rect needed for mouse pointer test */ diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c index 269cc672e34..5a99fc7ae4c 100644 --- a/source/blender/editors/screen/screen_ops.c +++ b/source/blender/editors/screen/screen_ops.c @@ -3595,7 +3595,7 @@ typedef struct RegionAlphaInfo { } RegionAlphaInfo; #define TIMEOUT 0.3f -#define TIMESTEP 0.04 +#define TIMESTEP 0.04f float ED_region_blend_factor(ARegion *ar) { @@ -3609,7 +3609,7 @@ float ED_region_blend_factor(ARegion *ar) alpha = (float)ar->regiontimer->duration / TIMEOUT; /* makes sure the blend out works 100% - without area redraws */ - if (rgi->hidden) alpha = 0.9 - TIMESTEP - alpha; + if (rgi->hidden) alpha = 0.9f - TIMESTEP - alpha; CLAMP(alpha, 0.0f, 1.0f); return alpha; @@ -3697,7 +3697,7 @@ static int region_blend_invoke(bContext *C, wmOperator *UNUSED(op), wmEvent *eve ED_region_tag_redraw(rgi->child_ar); /* end timer? */ - if (rgi->ar->regiontimer->duration > TIMEOUT) { + if (rgi->ar->regiontimer->duration > (double)TIMEOUT) { region_blend_end(C, rgi->ar, 0); return (OPERATOR_FINISHED | OPERATOR_PASS_THROUGH); } diff --git a/source/blender/editors/space_nla/nla_draw.c b/source/blender/editors/space_nla/nla_draw.c index beabd44c297..0c89e3ecbcf 100644 --- a/source/blender/editors/space_nla/nla_draw.c +++ b/source/blender/editors/space_nla/nla_draw.c @@ -871,8 +871,8 @@ static void draw_nla_channel_list_gl(bAnimContext *ac, ListBase *anim_data, View /* XXX firstly draw a little rect to help identify that it's different from the toggles */ glBegin(GL_LINE_LOOP); glVertex2f((float)v2d->cur.xmax - offset - 1, y - 0.35f * U.widget_unit); - glVertex2f((float)v2d->cur.xmax - offset - 1, y + 0.45 * U.widget_unit); - glVertex2f((float)v2d->cur.xmax - 1, y + 0.45f * U.widget_unit); + glVertex2f((float)v2d->cur.xmax - offset - 1, y + 0.45f * U.widget_unit); + glVertex2f((float)v2d->cur.xmax - 1, y + 0.45f * U.widget_unit); glVertex2f((float)v2d->cur.xmax - 1, y - 0.35f * U.widget_unit); glEnd(); // GL_LINES diff --git a/source/blender/editors/space_outliner/outliner_draw.c b/source/blender/editors/space_outliner/outliner_draw.c index 911902d275d..3823798194e 100644 --- a/source/blender/editors/space_outliner/outliner_draw.c +++ b/source/blender/editors/space_outliner/outliner_draw.c @@ -1432,7 +1432,10 @@ static void outliner_draw_tree_element(bContext *C, uiBlock *block, Scene *scene /* divider */ UI_ThemeColorShade(TH_BACK, -40); - glRecti(tempx - 10.0 * ufac, *starty + 4.0f * ufac, tempx - 8.0f * ufac, *starty + UI_UNIT_Y - 4.0f * ufac); + glRecti(tempx - 10.0f * ufac, + *starty + 4.0f * ufac, + tempx - 8.0f * ufac, + *starty + UI_UNIT_Y - 4.0f * ufac); glEnable(GL_BLEND); glPixelTransferf(GL_ALPHA_SCALE, 0.5); diff --git a/source/blender/windowmanager/intern/wm_files.c b/source/blender/windowmanager/intern/wm_files.c index 6c16c968a81..df463076919 100644 --- a/source/blender/windowmanager/intern/wm_files.c +++ b/source/blender/windowmanager/intern/wm_files.c @@ -1006,7 +1006,7 @@ void wm_autosave_timer(const bContext *C, wmWindowManager *wm, wmTimer *UNUSED(w if (U.uiflag & USER_GLOBALUNDO) { /* fast save of last undobuffer, now with UI */ - BKE_undo_save_file(C, filepath); + BKE_undo_save_file(filepath); } else { /* save as regular blend file */ diff --git a/source/blender/windowmanager/intern/wm_init_exit.c b/source/blender/windowmanager/intern/wm_init_exit.c index 563cb592d5a..734941b8907 100644 --- a/source/blender/windowmanager/intern/wm_init_exit.c +++ b/source/blender/windowmanager/intern/wm_init_exit.c @@ -385,7 +385,7 @@ void WM_exit_ext(bContext *C, const short do_python) BLI_make_file_string("/", filename, BLI_temporary_dir(), "quit.blend"); - if (BKE_undo_save_file(C, filename)) + if (BKE_undo_save_file(filename)) printf("Saved session recovery to '%s'\n", filename); } } From 96b2dc8e13ad6364c23119dcb909da785b5dca2b Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 13 Dec 2012 01:00:21 +0000 Subject: [PATCH 078/252] style cleanup: changes from recent commits --- source/blender/blenkernel/intern/anim.c | 2 +- source/blender/blenkernel/intern/blender.c | 2 +- .../blender/editors/interface/interface_layout.c | 2 +- .../editors/interface/interface_templates.c | 8 ++++---- source/blender/editors/interface/view2d.c | 4 ++-- source/blender/editors/screen/screen_edit.c | 2 +- source/blender/editors/screen/screen_ops.c | 15 +++++++++------ source/blender/editors/space_view3d/view3d_draw.c | 2 +- .../nodes/shader/nodes/node_shader_material.c | 2 +- source/blender/windowmanager/WM_api.h | 4 ++-- .../windowmanager/intern/wm_event_system.c | 4 ++-- source/blender/windowmanager/intern/wm_window.c | 2 +- 12 files changed, 26 insertions(+), 23 deletions(-) diff --git a/source/blender/blenkernel/intern/anim.c b/source/blender/blenkernel/intern/anim.c index 89f2291059f..4058809c275 100644 --- a/source/blender/blenkernel/intern/anim.c +++ b/source/blender/blenkernel/intern/anim.c @@ -1480,7 +1480,7 @@ static void new_particle_duplilist(ListBase *lb, ID *id, Scene *scene, Object *p /* blender internal needs this to be set to dupligroup to render * groups correctly, but we don't want this hack for cycles */ - if(dupli_type_hack && GS(id->name) == ID_GR) + if (dupli_type_hack && GS(id->name) == ID_GR) dupli_type = OB_DUPLIGROUP; /* to give ipos in object correct offset */ diff --git a/source/blender/blenkernel/intern/blender.c b/source/blender/blenkernel/intern/blender.c index 7ee3bddc82b..6e2cfc4090e 100644 --- a/source/blender/blenkernel/intern/blender.c +++ b/source/blender/blenkernel/intern/blender.c @@ -895,7 +895,7 @@ int BKE_copybuffer_save(char *filename, ReportList *reports) ID *id, *nextid; ListBase *lb1 = lbarray[a], *lb2 = fromarray[a]; - for (id = lb2->first; id; id= nextid) { + for (id = lb2->first; id; id = nextid) { nextid = id->next; if (id->flag & LIB_DOIT) { BLI_remlink(lb2, id); diff --git a/source/blender/editors/interface/interface_layout.c b/source/blender/editors/interface/interface_layout.c index e93ecc72725..b976bcad6ac 100644 --- a/source/blender/editors/interface/interface_layout.c +++ b/source/blender/editors/interface/interface_layout.c @@ -1495,7 +1495,7 @@ static void ui_item_menu(uiLayout *layout, const char *name, int icon, uiMenuCre h = UI_UNIT_Y; if (layout->root->type == UI_LAYOUT_HEADER) /* ugly .. */ - w -= UI_UNIT_Y/2; + w -= UI_UNIT_Y / 2; if (name[0] && icon) but = uiDefIconTextMenuBut(block, func, arg, icon, name, 0, 0, w, h, tip); diff --git a/source/blender/editors/interface/interface_templates.c b/source/blender/editors/interface/interface_templates.c index 0e3c32334b8..ae1447112e9 100644 --- a/source/blender/editors/interface/interface_templates.c +++ b/source/blender/editors/interface/interface_templates.c @@ -186,7 +186,7 @@ static uiBlock *id_search_menu(bContext *C, ARegion *ar, void *arg_litem) uiDefBut(block, LABEL, 0, "", 10, 15, w, h, NULL, 0, 0, 0, 0, NULL); but = uiDefSearchBut(block, search, 0, ICON_VIEWZOOM, sizeof(search), 10, 0, w, UI_UNIT_Y, - template.prv_rows, template.prv_cols, ""); + template.prv_rows, template.prv_cols, ""); uiButSetSearchFunc(but, id_search_cb, &template, id_search_call_cb, idptr.data); } /* list view */ @@ -1590,7 +1590,7 @@ void uiTemplateHistogram(uiLayout *layout, PointerRNA *ptr, const char *propname hist->height = (hist->height <= UI_UNIT_Y) ? UI_UNIT_Y : hist->height; bt = uiDefBut(block, HISTOGRAM, 0, "", rect.xmin, rect.ymin, BLI_rctf_size_x(&rect), UI_DPI_FAC * hist->height, - hist, 0, 0, 0, 0, ""); + hist, 0, 0, 0, 0, ""); uiButSetNFunc(bt, rna_update_cb, MEM_dupallocN(cb), NULL); @@ -1629,7 +1629,7 @@ void uiTemplateWaveform(uiLayout *layout, PointerRNA *ptr, const char *propname) scopes->wavefrm_height = (scopes->wavefrm_height <= UI_UNIT_Y) ? UI_UNIT_Y : scopes->wavefrm_height; bt = uiDefBut(block, WAVEFORM, 0, "", rect.xmin, rect.ymin, BLI_rctf_size_x(&rect), UI_DPI_FAC * scopes->wavefrm_height, - scopes, 0, 0, 0, 0, ""); + scopes, 0, 0, 0, 0, ""); (void)bt; /* UNUSED */ MEM_freeN(cb); @@ -1667,7 +1667,7 @@ void uiTemplateVectorscope(uiLayout *layout, PointerRNA *ptr, const char *propna scopes->vecscope_height = (scopes->vecscope_height <= UI_UNIT_Y) ? UI_UNIT_Y : scopes->vecscope_height; bt = uiDefBut(block, VECTORSCOPE, 0, "", rect.xmin, rect.ymin, BLI_rctf_size_x(&rect), - UI_DPI_FAC * scopes->vecscope_height, scopes, 0, 0, 0, 0, ""); + UI_DPI_FAC * scopes->vecscope_height, scopes, 0, 0, 0, 0, ""); uiButSetNFunc(bt, rna_update_cb, MEM_dupallocN(cb), NULL); MEM_freeN(cb); diff --git a/source/blender/editors/interface/view2d.c b/source/blender/editors/interface/view2d.c index 356b5a687ff..e2a20e5296a 100644 --- a/source/blender/editors/interface/view2d.c +++ b/source/blender/editors/interface/view2d.c @@ -1649,7 +1649,7 @@ void UI_view2d_scrollers_draw(const bContext *C, View2D *v2d, View2DScrollers *v /* clean rect behind slider, but not with transparent background */ UI_GetThemeColor4ubv(TH_BACK, col); if (col[3] == 255) { - glColor3ub(col[0], col[1],col[2]); + glColor3ub(col[0], col[1], col[2]); glRecti(v2d->hor.xmin, v2d->hor.ymin, v2d->hor.xmax, v2d->hor.ymax); } @@ -1765,7 +1765,7 @@ void UI_view2d_scrollers_draw(const bContext *C, View2D *v2d, View2DScrollers *v /* clean rect behind slider, but not with transparent background */ UI_GetThemeColor4ubv(TH_BACK, col); if (col[3] == 255) { - glColor3ub(col[0], col[1],col[2]); + glColor3ub(col[0], col[1], col[2]); glRecti(v2d->vert.xmin, v2d->vert.ymin, v2d->vert.xmax, v2d->vert.ymax); } diff --git a/source/blender/editors/screen/screen_edit.c b/source/blender/editors/screen/screen_edit.c index 9a91e9d96cd..bf44e6be7b6 100644 --- a/source/blender/editors/screen/screen_edit.c +++ b/source/blender/editors/screen/screen_edit.c @@ -263,7 +263,7 @@ int scredge_is_horizontal(ScrEdge *se) ScrEdge *screen_find_active_scredge(bScreen *sc, int mx, int my) { ScrEdge *se; - int safety = U.widget_unit/10; + int safety = U.widget_unit / 10; if (safety < 2) safety = 2; diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c index 5a99fc7ae4c..6ca3c939124 100644 --- a/source/blender/editors/screen/screen_ops.c +++ b/source/blender/editors/screen/screen_ops.c @@ -3600,13 +3600,14 @@ typedef struct RegionAlphaInfo { float ED_region_blend_factor(ARegion *ar) { /* check parent too */ - if(ar->regiontimer == NULL && (ar->alignment & RGN_SPLIT_PREV) && ar->prev) + if (ar->regiontimer == NULL && (ar->alignment & RGN_SPLIT_PREV) && ar->prev) { ar = ar->prev; - + } + if (ar->regiontimer) { RegionAlphaInfo *rgi = ar->regiontimer->customdata; float alpha; - + alpha = (float)ar->regiontimer->duration / TIMEOUT; /* makes sure the blend out works 100% - without area redraws */ if (rgi->hidden) alpha = 0.9f - TIMESTEP - alpha; @@ -3669,10 +3670,12 @@ void region_blend_start(bContext *C, ScrArea *sa, ARegion *ar) else WM_event_remove_handlers(C, &ar->handlers); - if(ar->next) - if (ar->next->alignment & RGN_SPLIT_PREV) + if (ar->next) { + if (ar->next->alignment & RGN_SPLIT_PREV) { rgi->child_ar = ar->next; - + } + } + /* new timer */ ar->regiontimer = WM_event_add_timer(wm, win, TIMERREGION, TIMESTEP); ar->regiontimer->customdata = rgi; diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c index a5cbe88faf1..1b0b0f027d9 100644 --- a/source/blender/editors/space_view3d/view3d_draw.c +++ b/source/blender/editors/space_view3d/view3d_draw.c @@ -573,7 +573,7 @@ static int draw_name_offset(ARegion *ar) arn = arn->prev; /* check if a region overlaps with the current one */ - for (; arn; arn= arn->next) { + for (; arn; arn = arn->next) { if (ar != arn) if (ar->winrct.xmin == arn->winrct.xmin) if (ar->winrct.ymin == arn->winrct.ymin) diff --git a/source/blender/nodes/shader/nodes/node_shader_material.c b/source/blender/nodes/shader/nodes/node_shader_material.c index 2902bf143c8..a36f35c646d 100644 --- a/source/blender/nodes/shader/nodes/node_shader_material.c +++ b/source/blender/nodes/shader/nodes/node_shader_material.c @@ -145,7 +145,7 @@ static void node_shader_exec_material(void *data, bNode *node, bNodeStack **in, /* make alpha output give results even if transparency is only enabled on * the material linked in this not and not on the parent material */ mode = shi->mode; - if(shi->mat->mode & MA_TRANSP) + if (shi->mat->mode & MA_TRANSP) shi->mode |= MA_TRANSP; shi->nodes= 1; /* temp hack to prevent trashadow recursion */ diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h index ce08d7ff9c0..c1a99513eec 100644 --- a/source/blender/windowmanager/WM_api.h +++ b/source/blender/windowmanager/WM_api.h @@ -147,7 +147,7 @@ struct wmEventHandler *WM_event_add_ui_handler(const struct bContext *C, ListBas int (*func)(struct bContext *C, struct wmEvent *event, void *userdata), void (*remove)(struct bContext *C, void *userdata), void *userdata); void WM_event_remove_ui_handler(ListBase *handlers, - int (*func)(struct bContext *C, struct wmEvent *event, void *userdata), + int (*func)(struct bContext *C, struct wmEvent *event, void *userdata), void (*remove)(struct bContext *C, void *userdata), void *userdata, int postpone); void WM_event_remove_area_handler(struct ListBase *handlers, void *area); @@ -301,7 +301,7 @@ struct wmDrag *WM_event_start_drag(struct bContext *C, int icon, int type, void void WM_event_drag_image(struct wmDrag *, struct ImBuf *, float scale, int sx, int sy); struct wmDropBox *WM_dropbox_add(ListBase *lb, const char *idname, int (*poll)(struct bContext *, struct wmDrag *, struct wmEvent *event), - void (*copy)(struct wmDrag *, struct wmDropBox *)); + void (*copy)(struct wmDrag *, struct wmDropBox *)); ListBase *WM_dropboxmap_find(const char *idname, int spaceid, int regionid); /* Set a subwindow active in pixelspace view, with optional scissor subset */ diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c index db80b0bd1a0..d8dd0ac04c4 100644 --- a/source/blender/windowmanager/intern/wm_event_system.c +++ b/source/blender/windowmanager/intern/wm_event_system.c @@ -1640,9 +1640,9 @@ static int wm_action_not_handled(int action) static int wm_handlers_do_intern(bContext *C, wmEvent *event, ListBase *handlers) { #ifndef NDEBUG - const int do_debug_handler = (G.debug & G_DEBUG_HANDLERS) + const int do_debug_handler = (G.debug & G_DEBUG_HANDLERS) && /* comment this out to flood the console! (if you really want to test) */ - && !ELEM(event->type, MOUSEMOVE, INBETWEEN_MOUSEMOVE) + !ELEM(event->type, MOUSEMOVE, INBETWEEN_MOUSEMOVE) ; #endif wmWindowManager *wm = CTX_wm_manager(C); diff --git a/source/blender/windowmanager/intern/wm_window.c b/source/blender/windowmanager/intern/wm_window.c index 3c56e8d341e..4dd7559c2cf 100644 --- a/source/blender/windowmanager/intern/wm_window.c +++ b/source/blender/windowmanager/intern/wm_window.c @@ -311,7 +311,7 @@ void wm_window_title(wmWindowManager *wm, wmWindow *win) if (G.save_over && G.main->name[0]) { char str[sizeof(G.main->name) + 12]; BLI_snprintf(str, sizeof(str), "Blender%s [%s%s]", wm->file_saved ? "" : "*", G.main->name, - G.main->recovered ? " (Recovered)" : ""); + G.main->recovered ? " (Recovered)" : ""); GHOST_SetTitle(win->ghostwin, str); } else From 0082b25eec4717794a2adeca0c684599d0cc6b3c Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 13 Dec 2012 01:17:22 +0000 Subject: [PATCH 079/252] remove BKE_main_scene_add(), just add main arg to BKE_scene_add() --- source/blender/blenkernel/BKE_scene.h | 3 +-- source/blender/blenkernel/intern/blender.c | 4 ++-- source/blender/blenkernel/intern/scene.c | 10 +++------- source/blender/editors/screen/screen_ops.c | 2 +- source/blender/makesrna/intern/rna_main_api.c | 4 ++-- 5 files changed, 9 insertions(+), 14 deletions(-) diff --git a/source/blender/blenkernel/BKE_scene.h b/source/blender/blenkernel/BKE_scene.h index 3be07e72fc2..6447b2a8dee 100644 --- a/source/blender/blenkernel/BKE_scene.h +++ b/source/blender/blenkernel/BKE_scene.h @@ -67,8 +67,7 @@ void free_avicodecdata(struct AviCodecData *acd); void free_qtcodecdata(struct QuicktimeCodecData *acd); void BKE_scene_free(struct Scene *sce); -struct Scene *BKE_scene_add(const char *name); -struct Scene *BKE_main_scene_add(struct Main *bmain, const char *name); +struct Scene *BKE_scene_add(struct Main *bmain, const char *name); /* base functions */ struct Base *BKE_scene_base_find(struct Scene *scene, struct Object *ob); diff --git a/source/blender/blenkernel/intern/blender.c b/source/blender/blenkernel/intern/blender.c index 6e2cfc4090e..8d923964b75 100644 --- a/source/blender/blenkernel/intern/blender.c +++ b/source/blender/blenkernel/intern/blender.c @@ -234,7 +234,7 @@ static void setup_app_data(bContext *C, BlendFileData *bfd, const char *filepath curscene = bfd->curscene; if (curscene == NULL) curscene = bfd->main->scene.first; /* empty file, we add a scene to make Blender work */ - if (curscene == NULL) curscene = BKE_main_scene_add(bfd->main, "Empty"); + if (curscene == NULL) curscene = BKE_scene_add(bfd->main, "Empty"); /* and we enforce curscene to be in current screen */ if (curscreen) curscreen->scene = curscene; /* can run in bgmode */ @@ -286,7 +286,7 @@ static void setup_app_data(bContext *C, BlendFileData *bfd, const char *filepath if (CTX_data_scene(C) == NULL) { /* in case we don't even have a local scene, add one */ if (!G.main->scene.first) - BKE_scene_add("Scene"); + BKE_scene_add(G.main, "Scene"); CTX_data_scene_set(C, G.main->scene.first); CTX_wm_screen(C)->scene = CTX_data_scene(C); diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c index 47f0da18163..6a5886faa67 100644 --- a/source/blender/blenkernel/intern/scene.c +++ b/source/blender/blenkernel/intern/scene.c @@ -143,7 +143,8 @@ Scene *BKE_scene_copy(Scene *sce, int type) if (type == SCE_COPY_EMPTY) { ListBase lb; - scen = BKE_scene_add(sce->id.name + 2); + /* XXX. main should become an arg */ + scen = BKE_scene_add(G.main, sce->id.name + 2); lb = scen->r.layers; scen->r = sce->r; @@ -604,12 +605,7 @@ static Scene *scene_add(Main *bmain, const char *name) return sce; } -Scene *BKE_scene_add(const char *name) -{ - return scene_add(G.main, name); -} - -Scene *BKE_main_scene_add(Main *bmain, const char *name) +Scene *BKE_scene_add(Main *bmain, const char *name) { return scene_add(bmain, name); } diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c index 6ca3c939124..fef039bc196 100644 --- a/source/blender/editors/screen/screen_ops.c +++ b/source/blender/editors/screen/screen_ops.c @@ -3505,7 +3505,7 @@ static int scene_new_exec(bContext *C, wmOperator *op) int type = RNA_enum_get(op->ptr, "type"); if (type == SCE_COPY_NEW) { - newscene = BKE_scene_add("Scene"); + newscene = BKE_scene_add(bmain, "Scene"); } else { /* different kinds of copying */ newscene = BKE_scene_copy(scene, type); diff --git a/source/blender/makesrna/intern/rna_main_api.c b/source/blender/makesrna/intern/rna_main_api.c index cf9415a75e7..cc74fce1733 100644 --- a/source/blender/makesrna/intern/rna_main_api.c +++ b/source/blender/makesrna/intern/rna_main_api.c @@ -118,9 +118,9 @@ static void rna_Main_cameras_remove(Main *bmain, ReportList *reports, PointerRNA } } -static Scene *rna_Main_scenes_new(Main *UNUSED(bmain), const char *name) +static Scene *rna_Main_scenes_new(Main *bmain, const char *name) { - return BKE_scene_add(name); + return BKE_scene_add(bmain, name); } static void rna_Main_scenes_remove(Main *bmain, bContext *C, ReportList *reports, PointerRNA *scene_ptr) { From 3716dfb3b045306d51e6cccca6d699afa072490a Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 13 Dec 2012 01:21:12 +0000 Subject: [PATCH 080/252] remove UI_DPI_FAC, its not needed anymore. --- source/blender/editors/include/UI_interface.h | 5 ++--- source/blender/editors/interface/interface_icons.c | 2 +- source/blender/editors/space_outliner/outliner_draw.c | 2 +- source/blender/editors/space_view3d/view3d_buttons.c | 2 +- 4 files changed, 5 insertions(+), 6 deletions(-) diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h index abd1782d0f2..07af0de9541 100644 --- a/source/blender/editors/include/UI_interface.h +++ b/source/blender/editors/include/UI_interface.h @@ -175,12 +175,11 @@ typedef struct uiLayout uiLayout; /* uiBut->drawflag */ #define UI_BUT_DRAW_ENUM_ARROWS (1 << 0) /* draw enum-like up/down arrows for button */ -/* scale fixed button widths by this to account for DPI (no difference for buttons or icons anymore */ +/* scale fixed button widths by this to account for DPI */ #define UI_DPI_FAC ((U.pixelsize * (float)U.dpi) / 72.0f) -#define UI_DPI_ICON_FAC ((U.pixelsize * (float)U.dpi) / 72.0f) /* 16 to copy ICON_DEFAULT_HEIGHT */ -#define UI_DPI_ICON_SIZE ((float)16 * UI_DPI_ICON_FAC) +#define UI_DPI_ICON_SIZE ((float)16 * UI_DPI_FAC) /* Button types, bits stored in 1 value... and a short even! * - bits 0-4: bitnr (0-31) diff --git a/source/blender/editors/interface/interface_icons.c b/source/blender/editors/interface/interface_icons.c index d78985fa5e2..79dd01fd400 100644 --- a/source/blender/editors/interface/interface_icons.c +++ b/source/blender/editors/interface/interface_icons.c @@ -1161,7 +1161,7 @@ void UI_icon_draw_aspect_color(float x, float y, int icon_id, float aspect, cons /* draws icon with dpi scale factor */ void UI_icon_draw(float x, float y, int icon_id) { - UI_icon_draw_aspect(x, y, icon_id, 1.0f / UI_DPI_ICON_FAC, 1.0f); + UI_icon_draw_aspect(x, y, icon_id, 1.0f / UI_DPI_FAC, 1.0f); } void UI_icon_draw_size(float x, float y, int size, int icon_id, float alpha) diff --git a/source/blender/editors/space_outliner/outliner_draw.c b/source/blender/editors/space_outliner/outliner_draw.c index 3823798194e..abe0ef253f9 100644 --- a/source/blender/editors/space_outliner/outliner_draw.c +++ b/source/blender/editors/space_outliner/outliner_draw.c @@ -902,7 +902,7 @@ static void tselem_draw_icon_uibut(struct DrawIconArg *arg, int icon) /* restrict column clip... it has been coded by simply overdrawing, doesnt work for buttons */ if (arg->x >= arg->xmax) { glEnable(GL_BLEND); - UI_icon_draw_aspect(arg->x, arg->y, icon, 1.0f / UI_DPI_ICON_FAC, arg->alpha); + UI_icon_draw_aspect(arg->x, arg->y, icon, 1.0f / UI_DPI_FAC, arg->alpha); glDisable(GL_BLEND); } else { diff --git a/source/blender/editors/space_view3d/view3d_buttons.c b/source/blender/editors/space_view3d/view3d_buttons.c index bf14d915412..31f72def302 100644 --- a/source/blender/editors/space_view3d/view3d_buttons.c +++ b/source/blender/editors/space_view3d/view3d_buttons.c @@ -365,7 +365,7 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float if (block) { /* buttons */ uiBut *but; int yi = 200; - const int buth = 20 * UI_DPI_ICON_FAC; + const int buth = 20 * UI_DPI_FAC; const int but_margin = 2; const char *c; From 1ab6306177d303165c3e80d4056a47ce6e74ac41 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 13 Dec 2012 02:40:49 +0000 Subject: [PATCH 081/252] minor edits - add BLENDER_QUIT_FILE define. - use const for passing rcti's in widget drawing. --- source/blender/blenlib/BLI_path_util.h | 1 + source/blender/editors/include/UI_interface.h | 4 +- .../editors/interface/interface_intern.h | 6 +- .../editors/interface/interface_regions.c | 19 +++--- .../editors/interface/interface_style.c | 2 +- .../editors/interface/interface_templates.c | 2 +- .../editors/interface/interface_widgets.c | 58 +++++++++---------- .../blender/windowmanager/intern/wm_files.c | 2 +- .../windowmanager/intern/wm_init_exit.c | 2 +- .../windowmanager/intern/wm_operators.c | 4 +- 10 files changed, 52 insertions(+), 48 deletions(-) diff --git a/source/blender/blenlib/BLI_path_util.h b/source/blender/blenlib/BLI_path_util.h index 43724d8dd44..557ecb3dd0c 100644 --- a/source/blender/blenlib/BLI_path_util.h +++ b/source/blender/blenlib/BLI_path_util.h @@ -68,6 +68,7 @@ char *BLI_get_folder_version(const int id, const int ver, const int do_check); #define BLENDER_STARTUP_FILE "startup.blend" #define BLENDER_USERPREF_FILE "userpref.blend" +#define BLENDER_QUIT_FILE "quit.blend" #define BLENDER_BOOKMARK_FILE "bookmarks.txt" #define BLENDER_HISTORY_FILE "recent-files.txt" diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h index 07af0de9541..90f8779b2c7 100644 --- a/source/blender/editors/include/UI_interface.h +++ b/source/blender/editors/include/UI_interface.h @@ -286,7 +286,7 @@ void uiDrawBoxVerticalShade(int mode, float minx, float miny, float maxx, float #define UI_SCROLL_PRESSED 1 #define UI_SCROLL_ARROWS 2 #define UI_SCROLL_NO_OUTLINE 4 -void uiWidgetScrollDraw(struct uiWidgetColors *wcol, struct rcti *rect, struct rcti *slider, int state); +void uiWidgetScrollDraw(struct uiWidgetColors *wcol, const struct rcti *rect, const struct rcti *slider, int state); /* Callbacks * @@ -884,7 +884,7 @@ void uiIDContextProperty(struct bContext *C, struct PointerRNA *ptr, struct Prop /* Styled text draw */ void uiStyleFontSet(struct uiFontStyle *fs); -void uiStyleFontDrawExt(struct uiFontStyle *fs, struct rcti *rect, const char *str, +void uiStyleFontDrawExt(struct uiFontStyle *fs, const struct rcti *rect, const char *str, float *r_xofs, float *r_yofs); void uiStyleFontDraw(struct uiFontStyle *fs, struct rcti *rect, const char *str); void uiStyleFontDrawRotated(struct uiFontStyle *fs, struct rcti *rect, const char *str); diff --git a/source/blender/editors/interface/interface_intern.h b/source/blender/editors/interface/interface_intern.h index fce43173832..f088b3a54f4 100644 --- a/source/blender/editors/interface/interface_intern.h +++ b/source/blender/editors/interface/interface_intern.h @@ -492,7 +492,7 @@ extern void ui_draw_aligned_panel(struct uiStyle *style, uiBlock *block, rcti *r /* interface_draw.c */ extern void ui_dropshadow(const rctf *rct, float radius, float aspect, float alpha, int select); -void ui_draw_gradient(rcti *rect, const float hsv[3], const int type, const float alpha); +void ui_draw_gradient(const rcti *rect, const float hsv[3], const int type, const float alpha); void ui_draw_but_HISTOGRAM(ARegion *ar, uiBut *but, struct uiWidgetColors *wcol, rcti *rect); void ui_draw_but_WAVEFORM(ARegion *ar, uiBut *but, struct uiWidgetColors *wcol, rcti *rect); @@ -517,8 +517,8 @@ void ui_draw_menu_back(struct uiStyle *style, uiBlock *block, rcti *rect); uiWidgetColors *ui_tooltip_get_theme(void); void ui_draw_tooltip_background(uiStyle *UNUSED(style), uiBlock * block, rcti * rect); void ui_draw_search_back(struct uiStyle *style, uiBlock *block, rcti *rect); -int ui_link_bezier_points(rcti * rect, float coord_array[][2], int resol); -void ui_draw_link_bezier(rcti *rect); +int ui_link_bezier_points(const rcti * rect, float coord_array[][2], int resol); +void ui_draw_link_bezier(const rcti *rect); extern void ui_draw_but(const struct bContext *C, ARegion *ar, struct uiStyle *style, uiBut *but, rcti *rect); /* theme color init */ diff --git a/source/blender/editors/interface/interface_regions.c b/source/blender/editors/interface/interface_regions.c index ed619605963..8acae65bf5f 100644 --- a/source/blender/editors/interface/interface_regions.c +++ b/source/blender/editors/interface/interface_regions.c @@ -306,8 +306,9 @@ static ARegion *ui_add_temporary_region(bScreen *sc) static void ui_remove_temporary_region(bContext *C, bScreen *sc, ARegion *ar) { - if (CTX_wm_window(C)) - wm_draw_region_clear(CTX_wm_window(C), ar); + wmWindow *win = CTX_wm_window(C); + if (win) + wm_draw_region_clear(win, ar); ED_region_exit(C, ar); BKE_area_region_free(NULL, ar); /* NULL: no spacetype */ @@ -416,6 +417,7 @@ static void ui_tooltip_region_free_cb(ARegion *ar) ARegion *ui_tooltip_create(bContext *C, ARegion *butregion, uiBut *but) { + wmWindow *win = CTX_wm_window(C); uiStyle *style = UI_GetStyle(); static ARegionType type; ARegion *ar; @@ -672,9 +674,9 @@ ARegion *ui_tooltip_create(bContext *C, ARegion *butregion, uiBut *but) BLI_rcti_translate(&rect_i, butregion->winrct.xmin, butregion->winrct.ymin); } - winx = WM_window_pixels_x(CTX_wm_window(C)); - winy = WM_window_pixels_y(CTX_wm_window(C)); - //wm_window_get_size(CTX_wm_window(C), &winx, &winy); + winx = WM_window_pixels_x(win); + winy = WM_window_pixels_y(win); + //wm_window_get_size(win, &winx, &winy); if (rect_i.xmax > winx) { /* super size */ @@ -1099,6 +1101,7 @@ static void ui_searchbox_region_free_cb(ARegion *ar) ARegion *ui_searchbox_create(bContext *C, ARegion *butregion, uiBut *but) { + wmWindow *win = CTX_wm_window(C); uiStyle *style = UI_GetStyle(); static ARegionType type; ARegion *ar; @@ -1187,9 +1190,9 @@ ARegion *ui_searchbox_create(bContext *C, ARegion *butregion, uiBut *but) BLI_rcti_translate(&rect_i, butregion->winrct.xmin, butregion->winrct.ymin); - winx = WM_window_pixels_x(CTX_wm_window(C)); - winy = WM_window_pixels_y(CTX_wm_window(C)); - //wm_window_get_size(CTX_wm_window(C), &winx, &winy); + winx = WM_window_pixels_x(win); + winy = WM_window_pixels_y(win); + //wm_window_get_size(win, &winx, &winy); if (rect_i.xmax > winx) { /* super size */ diff --git a/source/blender/editors/interface/interface_style.c b/source/blender/editors/interface/interface_style.c index 7118cbcd855..ef24ea951e3 100644 --- a/source/blender/editors/interface/interface_style.c +++ b/source/blender/editors/interface/interface_style.c @@ -143,7 +143,7 @@ static uiFont *uifont_to_blfont(int id) /* *************** draw ************************ */ -void uiStyleFontDrawExt(uiFontStyle *fs, rcti *rect, const char *str, +void uiStyleFontDrawExt(uiFontStyle *fs, const rcti *rect, const char *str, float *r_xofs, float *r_yofs) { float height; diff --git a/source/blender/editors/interface/interface_templates.c b/source/blender/editors/interface/interface_templates.c index ae1447112e9..9ba25392b92 100644 --- a/source/blender/editors/interface/interface_templates.c +++ b/source/blender/editors/interface/interface_templates.c @@ -2082,7 +2082,7 @@ void uiTemplateCurveMapping(uiLayout *layout, PointerRNA *ptr, const char *propn /********************* ColorPicker Template ************************/ -#define WHEEL_SIZE (5*U.widget_unit) +#define WHEEL_SIZE (5 * U.widget_unit) /* This template now follows User Preference for type - name is not correct anymore... */ void uiTemplateColorPicker(uiLayout *layout, PointerRNA *ptr, const char *propname, int value_slider, diff --git a/source/blender/editors/interface/interface_widgets.c b/source/blender/editors/interface/interface_widgets.c index 77fbe940c4a..1d43d59da68 100644 --- a/source/blender/editors/interface/interface_widgets.c +++ b/source/blender/editors/interface/interface_widgets.c @@ -119,7 +119,7 @@ typedef struct uiWidgetType { void (*state)(struct uiWidgetType *, int state); void (*draw)(uiWidgetColors *, rcti *, int state, int roundboxalign); void (*custom)(uiBut *, uiWidgetColors *, rcti *, int state, int roundboxalign); - void (*text)(uiFontStyle *, uiWidgetColors *, uiBut *, rcti *); + void (*text)(uiFontStyle *, uiWidgetColors *, uiBut *, rcti *); } uiWidgetType; @@ -251,7 +251,7 @@ static void widget_init(uiWidgetBase *wtb) /* helper call, makes shadow rect, with 'sun' above menu, so only shadow to left/right/bottom */ /* return tot */ -static int round_box_shadow_edges(float (*vert)[2], rcti *rect, float rad, int roundboxalign, float step) +static int round_box_shadow_edges(float (*vert)[2], const rcti *rect, float rad, int roundboxalign, float step) { float vec[WIDGET_CURVE_RESOLU][2]; float minx, miny, maxx, maxy; @@ -329,7 +329,7 @@ static int round_box_shadow_edges(float (*vert)[2], rcti *rect, float rad, int r } /* this call has 1 extra arg to allow mask outline */ -static void round_box__edges(uiWidgetBase *wt, int roundboxalign, rcti *rect, float rad, float radi) +static void round_box__edges(uiWidgetBase *wt, int roundboxalign, const rcti *rect, float rad, float radi) { float vec[WIDGET_CURVE_RESOLU][2], veci[WIDGET_CURVE_RESOLU][2]; float minx = rect->xmin, miny = rect->ymin, maxx = rect->xmax, maxy = rect->ymax; @@ -479,14 +479,14 @@ static void round_box__edges(uiWidgetBase *wt, int roundboxalign, rcti *rect, fl wt->totvert = tot; } -static void round_box_edges(uiWidgetBase *wt, int roundboxalign, rcti *rect, float rad) +static void round_box_edges(uiWidgetBase *wt, int roundboxalign, const rcti *rect, float rad) { round_box__edges(wt, roundboxalign, rect, rad, rad - U.pixelsize); } /* based on button rect, return scaled array of triangles */ -static void widget_num_tria(uiWidgetTrias *tria, rcti *rect, float triasize, char where) +static void widget_num_tria(uiWidgetTrias *tria, const rcti *rect, float triasize, char where) { float centx, centy, sizex, sizey, minsize; int a, i1 = 0, i2 = 1; @@ -521,7 +521,7 @@ static void widget_num_tria(uiWidgetTrias *tria, rcti *rect, float triasize, cha tria->index = num_tria_face; } -static void widget_scroll_circle(uiWidgetTrias *tria, rcti *rect, float triasize, char where) +static void widget_scroll_circle(uiWidgetTrias *tria, const rcti *rect, float triasize, char where) { float centx, centy, sizex, sizey, minsize; int a, i1 = 0, i2 = 1; @@ -564,7 +564,7 @@ static void widget_trias_draw(uiWidgetTrias *tria) glDisableClientState(GL_VERTEX_ARRAY); } -static void widget_menu_trias(uiWidgetTrias *tria, rcti *rect) +static void widget_menu_trias(uiWidgetTrias *tria, const rcti *rect) { float centx, centy, size, asp; int a; @@ -588,7 +588,7 @@ static void widget_menu_trias(uiWidgetTrias *tria, rcti *rect) tria->index = menu_tria_face; } -static void widget_check_trias(uiWidgetTrias *tria, rcti *rect) +static void widget_check_trias(uiWidgetTrias *tria, const rcti *rect) { float centx, centy, size; int a; @@ -833,7 +833,7 @@ static void widgetbase_draw(uiWidgetBase *wtb, uiWidgetColors *wcol) #define PREVIEW_PAD 4 -static void widget_draw_preview(BIFIconID icon, float UNUSED(alpha), rcti *rect) +static void widget_draw_preview(BIFIconID icon, float UNUSED(alpha), const rcti *rect) { int w, h, size; @@ -861,7 +861,7 @@ static int ui_but_draw_menu_icon(uiBut *but) /* icons have been standardized... and this call draws in untransformed coordinates */ -static void widget_draw_icon(uiBut *but, BIFIconID icon, float alpha, rcti *rect) +static void widget_draw_icon(uiBut *but, BIFIconID icon, float alpha, const rcti *rect) { float xs = 0.0f, ys = 0.0f; float aspect, height; @@ -963,7 +963,7 @@ static void ui_text_clip_give_next_off(uiBut *but) * \note Sets but->ofs to make sure text is correctly visible. * \note Clips right in some cases, this function could be cleaned up. */ -static void ui_text_clip_left(uiFontStyle *fstyle, uiBut *but, rcti *rect) +static void ui_text_clip_left(uiFontStyle *fstyle, uiBut *but, const rcti *rect) { int border = (but->flag & UI_BUT_ALIGN_RIGHT) ? 8 : 10; int okwidth = BLI_rcti_size_x(rect) - border; @@ -992,7 +992,7 @@ static void ui_text_clip_left(uiFontStyle *fstyle, uiBut *but, rcti *rect) /** * Cut off the text, taking into account the cursor location (text display while editing). */ -static void ui_text_clip_cursor(uiFontStyle *fstyle, uiBut *but, rcti *rect) +static void ui_text_clip_cursor(uiFontStyle *fstyle, uiBut *but, const rcti *rect) { int border = (but->flag & UI_BUT_ALIGN_RIGHT) ? 8 : 10; int okwidth = BLI_rcti_size_x(rect) - border; @@ -1056,7 +1056,7 @@ static void ui_text_clip_cursor(uiFontStyle *fstyle, uiBut *but, rcti *rect) * * \note deals with ': ' especially for number buttons */ -static void ui_text_clip_right_label(uiFontStyle *fstyle, uiBut *but, rcti *rect) +static void ui_text_clip_right_label(uiFontStyle *fstyle, uiBut *but, const rcti *rect) { int border = (but->flag & UI_BUT_ALIGN_RIGHT) ? 8 : 10; int okwidth = BLI_rcti_size_x(rect) - border; @@ -1800,7 +1800,7 @@ static void widget_state_menu_item(uiWidgetType *wt, int state) /* ************ menu backdrop ************************* */ /* outside of rect, rad to left/bottom/right */ -static void widget_softshadow(rcti *rect, int roundboxalign, float radin, float radout) +static void widget_softshadow(const rcti *rect, int roundboxalign, const float radin, const float radout) { uiWidgetBase wtb; rcti rect1 = *rect; @@ -1996,7 +1996,7 @@ static void ui_draw_but_HSVCIRCLE(uiBut *but, uiWidgetColors *wcol, const rcti * /* ************ custom buttons, old stuff ************** */ /* draws in resolution of 20x4 colors */ -void ui_draw_gradient(rcti *rect, const float hsv[3], const int type, const float alpha) +void ui_draw_gradient(const rcti *rect, const float hsv[3], const int type, const float alpha) { const float color_step = (type == UI_GRAD_H) ? 0.02f : 0.05f; int a; @@ -2135,7 +2135,7 @@ void ui_draw_gradient(rcti *rect, const float hsv[3], const int type, const floa -static void ui_draw_but_HSVCUBE(uiBut *but, rcti *rect) +static void ui_draw_but_HSVCUBE(uiBut *but, const rcti *rect) { float rgb[3]; float x = 0.0f, y = 0.0f; @@ -2178,10 +2178,10 @@ static void ui_draw_but_HSVCUBE(uiBut *but, rcti *rect) } /* vertical 'value' slider, using new widget code */ -static void ui_draw_but_HSV_v(uiBut *but, rcti *rect) +static void ui_draw_but_HSV_v(uiBut *but, const rcti *rect) { uiWidgetBase wtb; - float rad = 0.5f * BLI_rcti_size_x(rect); + const float rad = 0.5f * BLI_rcti_size_x(rect); float x, y; float rgb[3], hsv[3], v, range; int color_profile = but->block->color_profile; @@ -2226,7 +2226,7 @@ static void ui_draw_but_HSV_v(uiBut *but, rcti *rect) /* ************ separator, for menus etc ***************** */ -static void ui_draw_separator(rcti *rect, uiWidgetColors *wcol) +static void ui_draw_separator(const rcti *rect, uiWidgetColors *wcol) { int y = rect->ymin + BLI_rcti_size_y(rect) / 2 - 1; unsigned char col[4]; @@ -2247,7 +2247,7 @@ static void ui_draw_separator(rcti *rect, uiWidgetColors *wcol) static void widget_numbut(uiWidgetColors *wcol, rcti *rect, int state, int roundboxalign) { uiWidgetBase wtb; - float rad = 0.5f * BLI_rcti_size_y(rect); + const float rad = 0.5f * BLI_rcti_size_y(rect); float textofs = rad * 0.75f; if (state & UI_SELECT) @@ -2271,7 +2271,7 @@ static void widget_numbut(uiWidgetColors *wcol, rcti *rect, int state, int round rect->xmax -= textofs; } -int ui_link_bezier_points(rcti *rect, float coord_array[][2], int resol) +int ui_link_bezier_points(const rcti *rect, float coord_array[][2], int resol) { float dist, vec[4][2]; @@ -2295,7 +2295,7 @@ int ui_link_bezier_points(rcti *rect, float coord_array[][2], int resol) } #define LINK_RESOL 24 -void ui_draw_link_bezier(rcti *rect) +void ui_draw_link_bezier(const rcti *rect) { float coord_array[LINK_RESOL + 1][2]; @@ -2318,18 +2318,18 @@ void ui_draw_link_bezier(rcti *rect) } /* function in use for buttons and for view2d sliders */ -void uiWidgetScrollDraw(uiWidgetColors *wcol, rcti *rect, rcti *slider, int state) +void uiWidgetScrollDraw(uiWidgetColors *wcol, const rcti *rect, const rcti *slider, int state) { uiWidgetBase wtb; - float rad; int horizontal; + float rad; short outline = 0; widget_init(&wtb); /* determine horizontal/vertical */ horizontal = (BLI_rcti_size_x(rect) > BLI_rcti_size_y(rect)); - + if (horizontal) rad = 0.5f * BLI_rcti_size_y(rect); else @@ -2726,7 +2726,7 @@ static void widget_pulldownbut(uiWidgetColors *wcol, rcti *rect, int state, int { if (state & UI_ACTIVE) { uiWidgetBase wtb; - float rad = 0.2f * U.widget_unit; + const float rad = 0.2f * U.widget_unit; widget_init(&wtb); @@ -2864,7 +2864,7 @@ static void widget_but(uiWidgetColors *wcol, rcti *rect, int UNUSED(state), int static void widget_roundbut(uiWidgetColors *wcol, rcti *rect, int UNUSED(state), int roundboxalign) { uiWidgetBase wtb; - float rad = 0.25f * U.widget_unit; + const float rad = 0.25f * U.widget_unit; widget_init(&wtb); @@ -2877,7 +2877,7 @@ static void widget_roundbut(uiWidgetColors *wcol, rcti *rect, int UNUSED(state), static void widget_draw_extra_mask(const bContext *C, uiBut *but, uiWidgetType *wt, rcti *rect) { uiWidgetBase wtb; - float rad = 0.25f * U.widget_unit; + const float rad = 0.25f * U.widget_unit; unsigned char col[4]; /* state copy! */ @@ -2906,7 +2906,7 @@ static void widget_draw_extra_mask(const bContext *C, uiBut *but, uiWidgetType * } -static void widget_disabled(rcti *rect) +static void widget_disabled(const rcti *rect) { float col[4]; diff --git a/source/blender/windowmanager/intern/wm_files.c b/source/blender/windowmanager/intern/wm_files.c index df463076919..73f26185764 100644 --- a/source/blender/windowmanager/intern/wm_files.c +++ b/source/blender/windowmanager/intern/wm_files.c @@ -1035,7 +1035,7 @@ void wm_autosave_delete(void) if (BLI_exists(filename)) { char str[FILE_MAX]; - BLI_make_file_string("/", str, BLI_temporary_dir(), "quit.blend"); + BLI_make_file_string("/", str, BLI_temporary_dir(), BLENDER_QUIT_FILE); /* if global undo; remove tempsave, otherwise rename */ if (U.uiflag & USER_GLOBALUNDO) BLI_delete(filename, 0, 0); diff --git a/source/blender/windowmanager/intern/wm_init_exit.c b/source/blender/windowmanager/intern/wm_init_exit.c index 734941b8907..3cffa143ebc 100644 --- a/source/blender/windowmanager/intern/wm_init_exit.c +++ b/source/blender/windowmanager/intern/wm_init_exit.c @@ -383,7 +383,7 @@ void WM_exit_ext(bContext *C, const short do_python) /* save the undo state as quit.blend */ char filename[FILE_MAX]; - BLI_make_file_string("/", filename, BLI_temporary_dir(), "quit.blend"); + BLI_make_file_string("/", filename, BLI_temporary_dir(), BLENDER_QUIT_FILE); if (BKE_undo_save_file(filename)) printf("Saved session recovery to '%s'\n", filename); diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c index 1b6fe910ac5..a5ed337c3d8 100644 --- a/source/blender/windowmanager/intern/wm_operators.c +++ b/source/blender/windowmanager/intern/wm_operators.c @@ -2020,7 +2020,7 @@ void wm_recover_last_session(bContext *C, ReportList *reports) { char filename[FILE_MAX]; - BLI_make_file_string("/", filename, BLI_temporary_dir(), "quit.blend"); + BLI_make_file_string("/", filename, BLI_temporary_dir(), BLENDER_QUIT_FILE); /* if reports==NULL, it's called directly without operator, we add a quick check here */ if (reports || BLI_exists(filename)) { G.fileflags |= G_FILE_RECOVER; @@ -2050,7 +2050,7 @@ static void WM_OT_recover_last_session(wmOperatorType *ot) { ot->name = "Recover Last Session"; ot->idname = "WM_OT_recover_last_session"; - ot->description = "Open the last closed file (\"quit.blend\")"; + ot->description = "Open the last closed file (\"" BLENDER_QUIT_FILE "\")"; ot->exec = wm_recover_last_session_exec; ot->poll = WM_operator_winactive; From e036c90253cc0afafef6bf8a2e85158d934ba5c8 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 13 Dec 2012 05:43:01 +0000 Subject: [PATCH 082/252] region overlap feature missed view3d grid-scale text, increase string size for title text too. --- source/blender/editors/space_view3d/view3d_draw.c | 3 ++- source/blender/windowmanager/intern/wm_window.c | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c index 1b0b0f027d9..c9387bd776d 100644 --- a/source/blender/editors/space_view3d/view3d_draw.c +++ b/source/blender/editors/space_view3d/view3d_draw.c @@ -3234,7 +3234,8 @@ static void view3d_main_area_draw_info(const bContext *C, ARegion *ar, const cha BLI_snprintf(numstr, sizeof(numstr), "%s x %.4g", grid_unit, v3d->grid); } - BLF_draw_default_ascii(U.widget_unit, ar->winy - (USER_SHOW_VIEWPORTNAME ? 2 * U.widget_unit : U.widget_unit), 0.0f, + BLF_draw_default_ascii(draw_name_offset(ar) + U.widget_unit, + ar->winy - (USER_SHOW_VIEWPORTNAME ? 2 * U.widget_unit : U.widget_unit), 0.0f, numstr[0] ? numstr : grid_unit, sizeof(numstr)); } } diff --git a/source/blender/windowmanager/intern/wm_window.c b/source/blender/windowmanager/intern/wm_window.c index 4dd7559c2cf..226f4f2aa60 100644 --- a/source/blender/windowmanager/intern/wm_window.c +++ b/source/blender/windowmanager/intern/wm_window.c @@ -309,7 +309,7 @@ void wm_window_title(wmWindowManager *wm, wmWindow *win) /* this is set to 1 if you don't have startup.blend open */ if (G.save_over && G.main->name[0]) { - char str[sizeof(G.main->name) + 12]; + char str[sizeof(G.main->name) + 24]; BLI_snprintf(str, sizeof(str), "Blender%s [%s%s]", wm->file_saved ? "" : "*", G.main->name, G.main->recovered ? " (Recovered)" : ""); GHOST_SetTitle(win->ghostwin, str); From 3a408317192a7662dd5568e6b295174b025cefb4 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 13 Dec 2012 06:36:02 +0000 Subject: [PATCH 083/252] image view cursor wasn't scaling up with the DPI --- source/blender/editors/uvedit/uvedit_draw.c | 39 +++++++++++---------- 1 file changed, 20 insertions(+), 19 deletions(-) diff --git a/source/blender/editors/uvedit/uvedit_draw.c b/source/blender/editors/uvedit/uvedit_draw.c index c4267358d61..c6b251b04ae 100644 --- a/source/blender/editors/uvedit/uvedit_draw.c +++ b/source/blender/editors/uvedit/uvedit_draw.c @@ -60,48 +60,49 @@ #include "ED_uvedit.h" #include "UI_resources.h" +#include "UI_interface.h" #include "uvedit_intern.h" void draw_image_cursor(SpaceImage *sima, ARegion *ar) { - float zoomx, zoomy, w, h; + float zoomx, zoomy, x_fac, y_fac; int width, height; ED_space_image_get_size(sima, &width, &height); ED_space_image_get_zoom(sima, ar, &zoomx, &zoomy); - w = zoomx * width / 256.0f; - h = zoomy * height / 256.0f; + x_fac = (1.0f / (zoomx * width / 256.0f)) * UI_DPI_FAC; + y_fac = (1.0f / (zoomy * height / 256.0f)) * UI_DPI_FAC; cpack(0xFFFFFF); glTranslatef(sima->cursor[0], sima->cursor[1], 0.0); - fdrawline(-0.05f / w, 0, 0, 0.05f / h); - fdrawline(0, 0.05f / h, 0.05f / w, 0.0f); - fdrawline(0.05f / w, 0.0f, 0.0f, -0.05f / h); - fdrawline(0.0f, -0.05f / h, -0.05f / w, 0.0f); + fdrawline(-0.05f * x_fac, 0, 0, 0.05f * y_fac); + fdrawline(0, 0.05f * y_fac, 0.05f * x_fac, 0.0f); + fdrawline(0.05f * x_fac, 0.0f, 0.0f, -0.05f * y_fac); + fdrawline(0.0f, -0.05f * y_fac, -0.05f * x_fac, 0.0f); setlinestyle(4); cpack(0xFF); - fdrawline(-0.05f / w, 0.0f, 0.0f, 0.05f / h); - fdrawline(0.0f, 0.05f / h, 0.05f / w, 0.0f); - fdrawline(0.05f / w, 0.0f, 0.0f, -0.05f / h); - fdrawline(0.0f, -0.05f / h, -0.05f / w, 0.0f); + fdrawline(-0.05f * x_fac, 0.0f, 0.0f, 0.05f * y_fac); + fdrawline(0.0f, 0.05f * y_fac, 0.05f * x_fac, 0.0f); + fdrawline(0.05f * x_fac, 0.0f, 0.0f, -0.05f * y_fac); + fdrawline(0.0f, -0.05f * y_fac, -0.05f * x_fac, 0.0f); setlinestyle(0.0f); cpack(0x0); - fdrawline(-0.020f / w, 0.0f, -0.1f / w, 0.0f); - fdrawline(0.1f / w, 0.0f, 0.020f / w, 0.0f); - fdrawline(0.0f, -0.020f / h, 0.0f, -0.1f / h); - fdrawline(0.0f, 0.1f / h, 0.0f, 0.020f / h); + fdrawline(-0.020f * x_fac, 0.0f, -0.1f * x_fac, 0.0f); + fdrawline(0.1f * x_fac, 0.0f, 0.020f * x_fac, 0.0f); + fdrawline(0.0f, -0.020f * y_fac, 0.0f, -0.1f * y_fac); + fdrawline(0.0f, 0.1f * y_fac, 0.0f, 0.020f * y_fac); setlinestyle(1); cpack(0xFFFFFF); - fdrawline(-0.020f / w, 0.0f, -0.1f / w, 0.0f); - fdrawline(0.1f / w, 0.0f, 0.020f / w, 0.0f); - fdrawline(0.0f, -0.020f / h, 0.0f, -0.1f / h); - fdrawline(0.0f, 0.1f / h, 0.0f, 0.020f / h); + fdrawline(-0.020f * x_fac, 0.0f, -0.1f * x_fac, 0.0f); + fdrawline(0.1f * x_fac, 0.0f, 0.020f * x_fac, 0.0f); + fdrawline(0.0f, -0.020f * y_fac, 0.0f, -0.1f * y_fac); + fdrawline(0.0f, 0.1f * y_fac, 0.0f, 0.020f * y_fac); glTranslatef(-sima->cursor[0], -sima->cursor[1], 0.0); setlinestyle(0); From 0c3103ac85ad57309a1f166edd81fc0ae3005049 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Thu, 13 Dec 2012 07:32:31 +0000 Subject: [PATCH 084/252] Fix #33500: when transforming, tapping shift twice and holding did not enable precision mode. Not really the intended way to use this but it revealed a bug in the event handling here. --- source/blender/editors/transform/transform_input.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/source/blender/editors/transform/transform_input.c b/source/blender/editors/transform/transform_input.c index 7e05fdae364..88ed002af89 100644 --- a/source/blender/editors/transform/transform_input.c +++ b/source/blender/editors/transform/transform_input.c @@ -397,12 +397,13 @@ int handleMouseInput(TransInfo *t, MouseInput *mi, wmEvent *event) * store the mouse position where the normal movement ended */ copy_v2_v2_int(mi->precision_mval, event->mval); mi->precision = 1; + redraw = TREDRAW_HARD; } - else { + else if(event->val == KM_RELEASE) { t->modifiers &= ~MOD_PRECISION; mi->precision = 0; + redraw = TREDRAW_HARD; } - redraw = TREDRAW_HARD; break; } From 5d520c2b5a16cf7d86d4ed001857ced2ded8f8e7 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Thu, 13 Dec 2012 08:45:55 +0000 Subject: [PATCH 085/252] Cycles: shuffle addon import statements a bit to try to fix a strange import error in some builds. --- intern/cycles/blender/CMakeLists.txt | 1 - intern/cycles/blender/addon/__init__.py | 12 ++++- intern/cycles/blender/addon/engine.py | 5 +- intern/cycles/blender/addon/enums.py | 63 ----------------------- intern/cycles/blender/addon/properties.py | 61 ++++++++++++++++++---- intern/cycles/blender/addon/ui.py | 3 +- 6 files changed, 64 insertions(+), 81 deletions(-) delete mode 100644 intern/cycles/blender/addon/enums.py diff --git a/intern/cycles/blender/CMakeLists.txt b/intern/cycles/blender/CMakeLists.txt index 292c37d6b61..88363758364 100644 --- a/intern/cycles/blender/CMakeLists.txt +++ b/intern/cycles/blender/CMakeLists.txt @@ -38,7 +38,6 @@ set(SRC set(ADDON_FILES addon/__init__.py addon/engine.py - addon/enums.py addon/osl.py addon/presets.py addon/properties.py diff --git a/intern/cycles/blender/addon/__init__.py b/intern/cycles/blender/addon/__init__.py index 0fad2ac5618..6d1b6d4f56e 100644 --- a/intern/cycles/blender/addon/__init__.py +++ b/intern/cycles/blender/addon/__init__.py @@ -21,7 +21,7 @@ bl_info = { "name": "Cycles Render Engine", "author": "", - "blender": (2, 6, 3), + "blender": (2, 6, 5), "location": "Info header, render engine menu", "description": "Cycles Render Engine integration", "warning": "", @@ -31,8 +31,8 @@ bl_info = { "category": "Render"} import bpy -from . import ui, properties, engine, presets +from . import engine class CyclesRender(bpy.types.RenderEngine): bl_idname = 'CYCLES' @@ -84,6 +84,10 @@ class CyclesRender(bpy.types.RenderEngine): def register(): + from . import ui + from . import properties + from . import presets + properties.register() ui.register() presets.register() @@ -91,6 +95,10 @@ def register(): def unregister(): + from . import ui + from . import properties + from . import presets + ui.unregister() properties.unregister() presets.unregister() diff --git a/intern/cycles/blender/addon/engine.py b/intern/cycles/blender/addon/engine.py index ca5cbee9325..9641128d994 100644 --- a/intern/cycles/blender/addon/engine.py +++ b/intern/cycles/blender/addon/engine.py @@ -18,10 +18,8 @@ # -import bpy - - def init(): + import bpy import _cycles import os.path @@ -32,6 +30,7 @@ def init(): def create(engine, data, scene, region=0, v3d=0, rv3d=0): + import bpy import _cycles data = data.as_pointer() diff --git a/intern/cycles/blender/addon/enums.py b/intern/cycles/blender/addon/enums.py deleted file mode 100644 index 82b48973ca1..00000000000 --- a/intern/cycles/blender/addon/enums.py +++ /dev/null @@ -1,63 +0,0 @@ -# -# Copyright 2011, Blender Foundation. -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software Foundation, -# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -# - -# - -from . import engine - -devices = ( - ('CPU', "CPU", "Use CPU for rendering"), - ('GPU', "GPU Compute", "Use GPU compute device for rendering, configured in user preferences")) - -feature_set = ( - ('SUPPORTED', "Supported", "Only use finished and supported features"), - ('EXPERIMENTAL', "Experimental", "Use experimental and incomplete features that might be broken or change in the future"), - ) - -shading_systems = ( - ('GPU_COMPATIBLE', "GPU Compatible", "Restricted shading system compatible with GPU rendering"), - ('OSL', "Open Shading Language", "Open Shading Language shading system that only runs on the CPU"), - ) - -displacement_methods = ( - ('BUMP', "Bump", "Bump mapping to simulate the appearance of displacement"), - ('TRUE', "True", "Use true displacement only, requires fine subdivision"), - ('BOTH', "Both", "Combination of displacement and bump mapping"), - ) - -bvh_types = ( - ('DYNAMIC_BVH', "Dynamic BVH", "Objects can be individually updated, at the cost of slower render time"), - ('STATIC_BVH', "Static BVH", "Any object modification requires a complete BVH rebuild, but renders faster"), - ) - -filter_types = ( - ('BOX', "Box", "Box filter"), - ('GAUSSIAN', "Gaussian", "Gaussian filter"), - ) - -aperture_types = ( - ('RADIUS', "Radius", "Directly change the size of the aperture"), - ('FSTOP', "F/stop", "Change the size of the aperture by f/stops"), - ) - -panorama_types = ( - ('EQUIRECTANGULAR', "Equirectangular", "Render the scene with a spherical camera, also known as Lat Long panorama"), - ('FISHEYE_EQUIDISTANT', "Fisheye Equidistant", "Ideal for fulldomes, ignore the sensor dimensions"), - ('FISHEYE_EQUISOLID', "Fisheye Equisolid", - "Similar to most fisheye modern lens, takes sensor dimensions into consideration"), - ) diff --git a/intern/cycles/blender/addon/properties.py b/intern/cycles/blender/addon/properties.py index 0b8ca6e0fbe..ae4b7e3cc92 100644 --- a/intern/cycles/blender/addon/properties.py +++ b/intern/cycles/blender/addon/properties.py @@ -25,10 +25,49 @@ from bpy.props import (BoolProperty, IntProperty, PointerProperty) -import math +# enums -from . import enums +enum_devices = ( + ('CPU', "CPU", "Use CPU for rendering"), + ('GPU', "GPU Compute", "Use GPU compute device for rendering, configured in user preferences")) +enum_feature_set = ( + ('SUPPORTED', "Supported", "Only use finished and supported features"), + ('EXPERIMENTAL', "Experimental", "Use experimental and incomplete features that might be broken or change in the future"), + ) + +enum_shading_systems = ( + ('GPU_COMPATIBLE', "GPU Compatible", "Restricted shading system compatible with GPU rendering"), + ('OSL', "Open Shading Language", "Open Shading Language shading system that only runs on the CPU"), + ) + +enum_displacement_methods = ( + ('BUMP', "Bump", "Bump mapping to simulate the appearance of displacement"), + ('TRUE', "True", "Use true displacement only, requires fine subdivision"), + ('BOTH', "Both", "Combination of displacement and bump mapping"), + ) + +enum_bvh_types = ( + ('DYNAMIC_BVH', "Dynamic BVH", "Objects can be individually updated, at the cost of slower render time"), + ('STATIC_BVH', "Static BVH", "Any object modification requires a complete BVH rebuild, but renders faster"), + ) + +enum_filter_types = ( + ('BOX', "Box", "Box filter"), + ('GAUSSIAN', "Gaussian", "Gaussian filter"), + ) + +enum_aperture_types = ( + ('RADIUS', "Radius", "Directly change the size of the aperture"), + ('FSTOP', "F/stop", "Change the size of the aperture by f/stops"), + ) + +enum_panorama_types = ( + ('EQUIRECTANGULAR', "Equirectangular", "Render the scene with a spherical camera, also known as Lat Long panorama"), + ('FISHEYE_EQUIDISTANT', "Fisheye Equidistant", "Ideal for fulldomes, ignore the sensor dimensions"), + ('FISHEYE_EQUISOLID', "Fisheye Equisolid", + "Similar to most fisheye modern lens, takes sensor dimensions into consideration"), + ) class CyclesRenderSettings(bpy.types.PropertyGroup): @classmethod @@ -41,19 +80,19 @@ class CyclesRenderSettings(bpy.types.PropertyGroup): cls.device = EnumProperty( name="Device", description="Device to use for rendering", - items=enums.devices, + items=enum_devices, default='CPU', ) cls.feature_set = EnumProperty( name="Feature Set", description="Feature set to use for rendering", - items=enums.feature_set, + items=enum_feature_set, default='SUPPORTED', ) cls.shading_system = EnumProperty( name="Shading System", description="Shading system to use for rendering", - items=enums.shading_systems, + items=enum_shading_systems, default='GPU_COMPATIBLE', ) @@ -212,7 +251,7 @@ class CyclesRenderSettings(bpy.types.PropertyGroup): cls.filter_type = EnumProperty( name="Filter Type", description="Pixel filter type", - items=enums.filter_types, + items=enum_filter_types, default='GAUSSIAN', ) cls.filter_width = FloatProperty( @@ -275,7 +314,7 @@ class CyclesRenderSettings(bpy.types.PropertyGroup): cls.debug_bvh_type = EnumProperty( name="Viewport BVH Type", description="Choose between faster updates, or faster render", - items=enums.bvh_types, + items=enum_bvh_types, default='DYNAMIC_BVH', ) cls.debug_use_spatial_splits = BoolProperty( @@ -305,6 +344,8 @@ class CyclesRenderSettings(bpy.types.PropertyGroup): class CyclesCameraSettings(bpy.types.PropertyGroup): @classmethod def register(cls): + import math + bpy.types.Camera.cycles = PointerProperty( name="Cycles Camera Settings", description="Cycles camera settings", @@ -314,7 +355,7 @@ class CyclesCameraSettings(bpy.types.PropertyGroup): cls.aperture_type = EnumProperty( name="Aperture Type", description="Use F/stop number or aperture radius", - items=enums.aperture_types, + items=enum_aperture_types, default='RADIUS', ) cls.aperture_fstop = FloatProperty( @@ -349,7 +390,7 @@ class CyclesCameraSettings(bpy.types.PropertyGroup): cls.panorama_type = EnumProperty( name="Panorama Type", description="Distortion to use for the calculation", - items=enums.panorama_types, + items=enum_panorama_types, default='FISHEYE_EQUISOLID', ) cls.fisheye_fov = FloatProperty( @@ -518,7 +559,7 @@ class CyclesMeshSettings(bpy.types.PropertyGroup): cls.displacement_method = EnumProperty( name="Displacement Method", description="Method to use for the displacement", - items=enums.displacement_methods, + items=enum_displacement_methods, default='BUMP', ) cls.use_subdivision = BoolProperty( diff --git a/intern/cycles/blender/addon/ui.py b/intern/cycles/blender/addon/ui.py index ba931469e8a..66f99beeb97 100644 --- a/intern/cycles/blender/addon/ui.py +++ b/intern/cycles/blender/addon/ui.py @@ -22,8 +22,6 @@ import bpy from bpy.types import Panel, Menu -from . import enums, engine - class CYCLES_MT_integrator_presets(Menu): bl_label = "Integrator Presets" @@ -947,6 +945,7 @@ def draw_device(self, context): layout = self.layout if scene.render.engine == 'CYCLES': + from . import engine cscene = scene.cycles layout.prop(cscene, "feature_set") From 6e038ff3988e12f52a8f8478d2eb67497f6bf87f Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Thu, 13 Dec 2012 08:46:07 +0000 Subject: [PATCH 086/252] CMake: on linux, make boost now always require multithreaded libs, disabling this was a hack for the precompiled libs in svn. Also bumped minimum version to 1.48 because that's the first version that contains boost::locale. --- CMakeLists.txt | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 9b9fafdf514..674e532ff2c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -644,20 +644,15 @@ if(UNIX AND NOT APPLE) if(WITH_BOOST) # uses in build instructions to override include and library variables if(NOT BOOST_CUSTOM) - # XXX No more lib dir, is this multithread stuff still needed? if(${WITH_STATIC_LIBS}) set(Boost_USE_STATIC_LIBS ON) endif() - if(NOT BOOST_ROOT) - set(Boost_USE_MULTITHREADED OFF) - else() - set(Boost_USE_MULTITHREADED ON) - endif() + set(Boost_USE_MULTITHREADED ON) set(__boost_packages filesystem regex system thread date_time) if (WITH_INTERNATIONAL) list(APPEND __boost_packages locale) endif() - find_package(Boost 1.34 COMPONENTS ${__boost_packages}) + find_package(Boost 1.48 COMPONENTS ${__boost_packages}) if(Boost_USE_STATIC_LIBS AND Boost_USE_ICU) find_package(IcuLinux) endif() From 223cb8c94a332141ab3a97bf02c25470fa932070 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Thu, 13 Dec 2012 09:14:41 +0000 Subject: [PATCH 087/252] FFmpeg: remove limits of bitrate, they were far too low for losless formats like DNxHD --- source/blender/makesrna/intern/rna_scene.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c index 80c2e8dc8a3..32b6b97ccc2 100644 --- a/source/blender/makesrna/intern/rna_scene.c +++ b/source/blender/makesrna/intern/rna_scene.c @@ -3071,21 +3071,18 @@ static void rna_def_scene_ffmpeg_settings(BlenderRNA *brna) prop = RNA_def_property(srna, "video_bitrate", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, NULL, "video_bitrate"); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); - RNA_def_property_range(prop, 1, 64000); RNA_def_property_ui_text(prop, "Bitrate", "Video bitrate (kb/s)"); RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL); prop = RNA_def_property(srna, "minrate", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, NULL, "rc_min_rate"); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); - RNA_def_property_range(prop, 0, 48000); RNA_def_property_ui_text(prop, "Min Rate", "Rate control: min rate (kb/s)"); RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL); prop = RNA_def_property(srna, "maxrate", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, NULL, "rc_max_rate"); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); - RNA_def_property_range(prop, 1, 96000); RNA_def_property_ui_text(prop, "Max Rate", "Rate control: max rate (kb/s)"); RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL); From 15634fd22e28e95f9d2905a29d4cc34fdb613e7c Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 13 Dec 2012 09:46:24 +0000 Subject: [PATCH 088/252] fix for sequence size mismatch when loading themes, addition of alpha channel caused themes not to load. --- release/scripts/modules/rna_xml.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/release/scripts/modules/rna_xml.py b/release/scripts/modules/rna_xml.py index e21ccd08a35..08b60ebc6f8 100644 --- a/release/scripts/modules/rna_xml.py +++ b/release/scripts/modules/rna_xml.py @@ -265,7 +265,15 @@ def xml2rna(root_xml, tp_name = 'ARRAY' # print(" %s.%s (%s) --- %s" % (type(value).__name__, attr, tp_name, subvalue_type)) - setattr(value, attr, value_xml_coerce) + try: + setattr(value, attr, value_xml_coerce) + except ValueError: + # size mismatch + val = getattr(value, attr) + if len(val) < len(value_xml_coerce): + setattr(value, attr, value_xml_coerce[:len(val)]) + else: + setattr(value, attr, list(value_xml_coerce) + list(val)[len(value_xml_coerce):]) # --------------------------------------------------------------------- # Complex attributes From 1fca21cc243ac888e694e34eadc1c1037606c1ed Mon Sep 17 00:00:00 2001 From: Ton Roosendaal Date: Thu, 13 Dec 2012 10:24:46 +0000 Subject: [PATCH 089/252] Bug fix: - Code for detecting "click inside button panel" was convoluted and detected wrong panels even when they were closed. - Any click inside panels now return "Event Handled", that will prevent events being passed on in case of overlapping or transparent button panels. This is ancient code, will be in on my attention list for further cleaning. --- .../editors/interface/interface_panel.c | 51 +++++++++++-------- 1 file changed, 30 insertions(+), 21 deletions(-) diff --git a/source/blender/editors/interface/interface_panel.c b/source/blender/editors/interface/interface_panel.c index 0bdb39cb58e..f60e4dff23a 100644 --- a/source/blender/editors/interface/interface_panel.c +++ b/source/blender/editors/interface/interface_panel.c @@ -1096,27 +1096,45 @@ int ui_handler_panel_region(bContext *C, wmEvent *event) ARegion *ar = CTX_wm_region(C); uiBlock *block; Panel *pa; - int retval, mx, my, inside_header = 0, inside_scale = 0, inside; + int retval, mx, my; retval = WM_UI_HANDLER_CONTINUE; for (block = ar->uiblocks.last; block; block = block->prev) { + int inside = 0, inside_header = 0, inside_scale = 0; + mx = event->x; my = event->y; ui_window_to_block(ar, block, &mx, &my); - /* check if inside boundbox */ - inside = 0; + /* checks for mouse position inside */ pa = block->panel; if (!pa || pa->paneltab != NULL) continue; if (pa->type && pa->type->flag & PNL_NO_HEADER) /* XXX - accessed freed panels when scripts reload, need to fix. */ continue; - - if (block->rect.xmin <= mx && block->rect.xmax >= mx) - if (block->rect.ymin <= my && block->rect.ymax + PNL_HEADER >= my) - inside = 1; + /* clicked at panel header? */ + if (pa->flag & PNL_CLOSEDX) { + if (block->rect.xmin <= mx && block->rect.xmin + PNL_HEADER >= mx) + inside_header = 1; + } + else if ((block->rect.ymax <= my) && (block->rect.ymax + PNL_HEADER >= my)) { + inside_header = 1; + } + else if (!(pa->flag & PNL_CLOSEDY)) { + /* open panel */ + if (pa->control & UI_PNL_SCALE) { + if (block->rect.xmax - PNL_HEADER <= mx) + if (block->rect.ymin + PNL_HEADER >= my) + inside_scale = 1; + } + if (block->rect.xmin <= mx && block->rect.xmax >= mx) + if (block->rect.ymin <= my && block->rect.ymax + PNL_HEADER >= my) + inside = 1; + } + + /* XXX hardcoded key warning */ if (inside && event->val == KM_PRESS) { if (event->type == AKEY && !ELEM4(KM_MOD_FIRST, event->ctrl, event->oskey, event->shift, event->alt)) { @@ -1135,22 +1153,13 @@ int ui_handler_panel_region(bContext *C, wmEvent *event) if (ui_button_is_active(ar)) continue; - if (inside) { - /* clicked at panel header? */ - if (pa->flag & PNL_CLOSEDX) { - if (block->rect.xmin <= mx && block->rect.xmin + PNL_HEADER >= mx) - inside_header = 1; - } - else if ((block->rect.ymax <= my) && (block->rect.ymax + PNL_HEADER >= my)) { - inside_header = 1; - } - else if (pa->control & UI_PNL_SCALE) { - if (block->rect.xmax - PNL_HEADER <= mx) - if (block->rect.ymin + PNL_HEADER >= my) - inside_scale = 1; - } + if (inside || inside_header) { if (event->val == KM_PRESS) { + + /* all inside clicks should return in break - overlapping/float panels */ + retval = WM_UI_HANDLER_BREAK; + /* open close on header */ if (ELEM(event->type, RETKEY, PADENTER)) { if (inside_header) { From b83f105588f2c1d72e185dd9431ffb855a213123 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 13 Dec 2012 10:29:31 +0000 Subject: [PATCH 090/252] update themes for added alpha channel --- .../presets/interface_theme/back_to_black.xml | 34 +++++++++---------- .../presets/interface_theme/blender_24x.xml | 34 +++++++++---------- .../presets/interface_theme/elsyiun.xml | 34 +++++++++---------- .../presets/interface_theme/hexagon.xml | 34 +++++++++---------- .../interface_theme/ubuntu_ambiance.xml | 34 +++++++++---------- 5 files changed, 85 insertions(+), 85 deletions(-) diff --git a/release/scripts/presets/interface_theme/back_to_black.xml b/release/scripts/presets/interface_theme/back_to_black.xml index 0a77aa132a8..ff0a36da3a5 100644 --- a/release/scripts/presets/interface_theme/back_to_black.xml +++ b/release/scripts/presets/interface_theme/back_to_black.xml @@ -288,7 +288,7 @@ header="#000000" header_text="#979797" header_text_hi="#ffffff" - button="#000000" + button="#00000057" button_title="#c5c5c5" button_text="#c3c3c3" button_text_hi="#ffffff"> @@ -331,7 +331,7 @@ header="#000000" header_text="#979797" header_text_hi="#ffffff" - button="#000000" + button="#000000ff" button_title="#c5c5c5" button_text="#c3c3c3" button_text_hi="#ffffff"> @@ -361,7 +361,7 @@ header="#000000" header_text="#979797" header_text_hi="#ffffff" - button="#000000" + button="#000000ff" button_title="#c5c5c5" button_text="#c3c3c3" button_text_hi="#ffffff"> @@ -400,7 +400,7 @@ header="#000000" header_text="#979797" header_text_hi="#ffffff" - button="#000000" + button="#000000ff" button_title="#c3c3c3" button_text="#c3c3c3" button_text_hi="#ffffff"> @@ -437,7 +437,7 @@ header="#000000" header_text="#979797" header_text_hi="#ffffff" - button="#000000" + button="#000000ff" button_title="#c5c5c5" button_text="#c3c3c3" button_text_hi="#ffffff"> @@ -476,7 +476,7 @@ header="#000000" header_text="#979797" header_text_hi="#ffffff" - button="#000000" + button="#000000ff" button_title="#c5c5c5" button_text="#c3c3c3" button_text_hi="#ffffff"> @@ -507,7 +507,7 @@ header="#000000" header_text="#f3f3f3" header_text_hi="#ffffff" - button="#020202" + button="#02020242" button_title="#bdbdbd" button_text="#dddddd" button_text_hi="#ffffff"> @@ -525,7 +525,7 @@ header="#000000" header_text="#979797" header_text_hi="#ffffff" - button="#000000" + button="#000000ff" button_title="#c5c5c5" button_text="#c3c3c3" button_text_hi="#ffffff"> @@ -550,7 +550,7 @@ header="#000000" header_text="#b9b9b9" header_text_hi="#ffffff" - button="#000000" + button="#000000ff" button_title="#d8d8d8" button_text="#cccccc" button_text_hi="#ffffff"> @@ -569,7 +569,7 @@ header="#000000" header_text="#979797" header_text_hi="#ffffff" - button="#000000" + button="#000000ff" button_title="#c5c5c5" button_text="#c3c3c3" button_text_hi="#ffffff"> @@ -598,7 +598,7 @@ header="#000000" header_text="#c7c7c7" header_text_hi="#ffffff" - button="#000000" + button="#0000002f" button_title="#c5c5c5" button_text="#c3c3c3" button_text_hi="#ffffff"> @@ -623,7 +623,7 @@ header="#000000" header_text="#979797" header_text_hi="#ffffff" - button="#000000" + button="#000000ff" button_title="#c5c5c5" button_text="#c3c3c3" button_text_hi="#ffffff"> @@ -642,7 +642,7 @@ header="#000000" header_text="#979797" header_text_hi="#ffffff" - button="#000000" + button="#000000ff" button_title="#c5c5c5" button_text="#c3c3c3" button_text_hi="#ffffff"> @@ -660,7 +660,7 @@ header="#000000" header_text="#adadad" header_text_hi="#ffffff" - button="#000000" + button="#000000ff" button_title="#c5c5c5" button_text="#c3c3c3" button_text_hi="#ffffff"> @@ -678,7 +678,7 @@ header="#000000" header_text="#979797" header_text_hi="#ffffff" - button="#000000" + button="#000000ff" button_title="#c5c5c5" button_text="#c3c3c3" button_text_hi="#ffffff"> @@ -700,7 +700,7 @@ header="#000000" header_text="#979797" header_text_hi="#ffffff" - button="#000000" + button="#000000ff" button_title="#c5c5c5" button_text="#c3c3c3" button_text_hi="#ffffff"> @@ -732,7 +732,7 @@ header="#000000" header_text="#979797" header_text_hi="#ffffff" - button="#070707" + button="#070707ff" button_title="#c5c5c5" button_text="#c3c3c3" button_text_hi="#ffffff"> diff --git a/release/scripts/presets/interface_theme/blender_24x.xml b/release/scripts/presets/interface_theme/blender_24x.xml index 18ae3072208..f26f66af816 100644 --- a/release/scripts/presets/interface_theme/blender_24x.xml +++ b/release/scripts/presets/interface_theme/blender_24x.xml @@ -288,7 +288,7 @@ header="#b4b4b4" header_text="#000000" header_text_hi="#ffffff" - button="#b4b4b4" + button="#b4b4b457" button_title="#5a5a5a" button_text="#5a5a5a" button_text_hi="#ffffff"> @@ -331,7 +331,7 @@ header="#b4b4b4" header_text="#000000" header_text_hi="#ffffff" - button="#727272" + button="#727272ff" button_title="#000000" button_text="#000000" button_text_hi="#ffffff"> @@ -361,7 +361,7 @@ header="#b4b4b4" header_text="#000000" header_text_hi="#ffffff" - button="#b4b4b4" + button="#b4b4b4ff" button_title="#000000" button_text="#000000" button_text_hi="#ffffff"> @@ -400,7 +400,7 @@ header="#b4b4b4" header_text="#000000" header_text_hi="#ffffff" - button="#b4b4b4" + button="#b4b4b4ff" button_title="#000000" button_text="#000000" button_text_hi="#ffffff"> @@ -437,7 +437,7 @@ header="#b4b4b4" header_text="#000000" header_text_hi="#ffffff" - button="#b4b4b4" + button="#b4b4b4ff" button_title="#000000" button_text="#000000" button_text_hi="#ffffff"> @@ -476,7 +476,7 @@ header="#b4b4b4" header_text="#000000" header_text_hi="#ffffff" - button="#b4b4b4" + button="#b4b4b4ff" button_title="#000000" button_text="#000000" button_text_hi="#ffffff"> @@ -507,7 +507,7 @@ header="#b4b4b4" header_text="#000000" header_text_hi="#ffffff" - button="#b4b4b4" + button="#b4b4b442" button_title="#000000" button_text="#000000" button_text_hi="#ffffff"> @@ -525,7 +525,7 @@ header="#b4b4b4" header_text="#000000" header_text_hi="#ffffff" - button="#b4b4b4" + button="#b4b4b4ff" button_title="#000000" button_text="#000000" button_text_hi="#ffffff"> @@ -550,7 +550,7 @@ header="#b4b4b4" header_text="#000000" header_text_hi="#ffffff" - button="#b4b4b4" + button="#b4b4b4ff" button_title="#000000" button_text="#000000" button_text_hi="#ffffff"> @@ -569,7 +569,7 @@ header="#b4b4b4" header_text="#000000" header_text_hi="#ffffff" - button="#b4b4b4" + button="#b4b4b4ff" button_title="#000000" button_text="#000000" button_text_hi="#ffffff"> @@ -598,7 +598,7 @@ header="#b4b4b4" header_text="#000000" header_text_hi="#ffffff" - button="#b4b4b4" + button="#b4b4b42f" button_title="#000000" button_text="#000000" button_text_hi="#ffffff"> @@ -623,7 +623,7 @@ header="#b4b4b4" header_text="#000000" header_text_hi="#ffffff" - button="#b4b4b4" + button="#b4b4b4ff" button_title="#000000" button_text="#000000" button_text_hi="#ffffff"> @@ -642,7 +642,7 @@ header="#b4b4b4" header_text="#000000" header_text_hi="#ffffff" - button="#b4b4b4" + button="#b4b4b4ff" button_title="#000000" button_text="#000000" button_text_hi="#ffffff"> @@ -660,7 +660,7 @@ header="#b4b4b4" header_text="#000000" header_text_hi="#ffffff" - button="#b4b4b4" + button="#b4b4b4ff" button_title="#000000" button_text="#000000" button_text_hi="#ffffff"> @@ -678,7 +678,7 @@ header="#b4b4b4" header_text="#000000" header_text_hi="#ffffff" - button="#b4b4b4" + button="#b4b4b4ff" button_title="#000000" button_text="#000000" button_text_hi="#ffffff"> @@ -700,7 +700,7 @@ header="#b4b4b4" header_text="#000000" header_text_hi="#ffffff" - button="#b4b4b4" + button="#b4b4b4ff" button_title="#000000" button_text="#000000" button_text_hi="#ffffff"> @@ -732,7 +732,7 @@ header="#b4b4b4" header_text="#000000" header_text_hi="#ffffff" - button="#b4b4b4" + button="#b4b4b4ff" button_title="#000000" button_text="#000000" button_text_hi="#ffffff"> diff --git a/release/scripts/presets/interface_theme/elsyiun.xml b/release/scripts/presets/interface_theme/elsyiun.xml index c10eb108000..25023310b85 100644 --- a/release/scripts/presets/interface_theme/elsyiun.xml +++ b/release/scripts/presets/interface_theme/elsyiun.xml @@ -288,7 +288,7 @@ header="#3b3b3b" header_text="#b9b9b9" header_text_hi="#ffffff" - button="#3b3b3b" + button="#3b3b3b57" button_title="#979797" button_text="#979797" button_text_hi="#ffffff"> @@ -331,7 +331,7 @@ header="#3b3b3b" header_text="#000000" header_text_hi="#ffffff" - button="#3b3b3b" + button="#3b3b3bff" button_title="#8b8b8b" button_text="#8b8b8b" button_text_hi="#ffffff"> @@ -361,7 +361,7 @@ header="#3b3b3b" header_text="#8b8b8b" header_text_hi="#ffffff" - button="#303030" + button="#303030ff" button_title="#000000" button_text="#000000" button_text_hi="#ffffff"> @@ -400,7 +400,7 @@ header="#3b3b3b" header_text="#000000" header_text_hi="#ffffff" - button="#3b3b3b" + button="#3b3b3bff" button_title="#000000" button_text="#000000" button_text_hi="#ffffff"> @@ -437,7 +437,7 @@ header="#3b3b3b" header_text="#000000" header_text_hi="#ffffff" - button="#aaaaaa" + button="#aaaaaaff" button_title="#000000" button_text="#000000" button_text_hi="#ffffff"> @@ -476,7 +476,7 @@ header="#303030" header_text="#000000" header_text_hi="#ffffff" - button="#303030" + button="#303030ff" button_title="#8b8b8b" button_text="#8b8b8b" button_text_hi="#ffffff"> @@ -507,7 +507,7 @@ header="#3b3b3b" header_text="#000000" header_text_hi="#ffffff" - button="#3b3b3b" + button="#3b3b3b42" button_title="#000000" button_text="#000000" button_text_hi="#ffffff"> @@ -525,7 +525,7 @@ header="#3b3b3b" header_text="#000000" header_text_hi="#ffffff" - button="#727272" + button="#727272ff" button_title="#b8b8b8" button_text="#b8b8b8" button_text_hi="#ffffff"> @@ -550,7 +550,7 @@ header="#3b3b3b" header_text="#000000" header_text_hi="#ffffff" - button="#3b3b3b" + button="#3b3b3bff" button_title="#8b8b8b" button_text="#8b8b8b" button_text_hi="#ffffff"> @@ -569,7 +569,7 @@ header="#3b3b3b" header_text="#000000" header_text_hi="#ffffff" - button="#727272" + button="#727272ff" button_title="#000000" button_text="#000000" button_text_hi="#ffffff"> @@ -598,7 +598,7 @@ header="#3b3b3b" header_text="#000000" header_text_hi="#ffffff" - button="#3b3b3b" + button="#3b3b3b2f" button_title="#8b8b8b" button_text="#8b8b8b" button_text_hi="#ffffff"> @@ -623,7 +623,7 @@ header="#3b3b3b" header_text="#000000" header_text_hi="#ffffff" - button="#3b3b3b" + button="#3b3b3bff" button_title="#8b8b8b" button_text="#8b8b8b" button_text_hi="#ffffff"> @@ -642,7 +642,7 @@ header="#3b3b3b" header_text="#000000" header_text_hi="#ffffff" - button="#727272" + button="#727272ff" button_title="#000000" button_text="#000000" button_text_hi="#ffffff"> @@ -660,7 +660,7 @@ header="#3b3b3b" header_text="#000000" header_text_hi="#000000" - button="#3b3b3b" + button="#3b3b3bff" button_title="#000000" button_text="#000000" button_text_hi="#000000"> @@ -678,7 +678,7 @@ header="#3b3b3b" header_text="#000000" header_text_hi="#ffffff" - button="#727272" + button="#727272ff" button_title="#000000" button_text="#000000" button_text_hi="#ffffff"> @@ -700,7 +700,7 @@ header="#303030" header_text="#000000" header_text_hi="#ffffff" - button="#3b3b3b" + button="#3b3b3bff" button_title="#000000" button_text="#000000" button_text_hi="#ffffff"> @@ -732,7 +732,7 @@ header="#313131" header_text="#000000" header_text_hi="#ffffff" - button="#3b3b3b" + button="#3b3b3bff" button_title="#000000" button_text="#000000" button_text_hi="#ffffff"> diff --git a/release/scripts/presets/interface_theme/hexagon.xml b/release/scripts/presets/interface_theme/hexagon.xml index ad514bbbafa..1acc54912c3 100644 --- a/release/scripts/presets/interface_theme/hexagon.xml +++ b/release/scripts/presets/interface_theme/hexagon.xml @@ -288,7 +288,7 @@ header="#646875" header_text="#000000" header_text_hi="#ffffff" - button="#6c717f" + button="#6c717f57" button_title="#eaeaea" button_text="#d7d7d7" button_text_hi="#ffffff"> @@ -331,7 +331,7 @@ header="#5c606c" header_text="#000000" header_text_hi="#ffffff" - button="#646875" + button="#646875ff" button_title="#000000" button_text="#000000" button_text_hi="#ffffff"> @@ -361,7 +361,7 @@ header="#5c606c" header_text="#dddddd" header_text_hi="#ffffff" - button="#6c717f" + button="#6c717fff" button_title="#d7d7d7" button_text="#d7d7d7" button_text_hi="#ffffff"> @@ -400,7 +400,7 @@ header="#5c606c" header_text="#000000" header_text_hi="#ffffff" - button="#646875" + button="#646875ff" button_title="#000000" button_text="#000000" button_text_hi="#ffffff"> @@ -437,7 +437,7 @@ header="#5c606c" header_text="#000000" header_text_hi="#ffffff" - button="#6c717f" + button="#6c717fff" button_title="#000000" button_text="#000000" button_text_hi="#ffffff"> @@ -476,7 +476,7 @@ header="#5c606c" header_text="#000000" header_text_hi="#ffffff" - button="#646875" + button="#646875ff" button_title="#eeeeee" button_text="#eeeeee" button_text_hi="#ffffff"> @@ -507,7 +507,7 @@ header="#5c606c" header_text="#000000" header_text_hi="#ffffff" - button="#646875" + button="#64687542" button_title="#000000" button_text="#000000" button_text_hi="#ffffff"> @@ -525,7 +525,7 @@ header="#646875" header_text="#000000" header_text_hi="#ffffff" - button="#727272" + button="#727272ff" button_title="#000000" button_text="#000000" button_text_hi="#ffffff"> @@ -550,7 +550,7 @@ header="#5c606c" header_text="#000000" header_text_hi="#ffffff" - button="#646875" + button="#646875ff" button_title="#000000" button_text="#000000" button_text_hi="#ffffff"> @@ -569,7 +569,7 @@ header="#565863" header_text="#000000" header_text_hi="#ffffff" - button="#5a5e6a" + button="#5a5e6aff" button_title="#000000" button_text="#000000" button_text_hi="#ffffff"> @@ -598,7 +598,7 @@ header="#5c606c" header_text="#000000" header_text_hi="#ffffff" - button="#646875" + button="#6468752f" button_title="#000000" button_text="#000000" button_text_hi="#ffffff"> @@ -623,7 +623,7 @@ header="#5c606c" header_text="#000000" header_text_hi="#ffffff" - button="#6c717f" + button="#6c717fff" button_title="#d7d7d7" button_text="#d7d7d7" button_text_hi="#ffffff"> @@ -642,7 +642,7 @@ header="#6c717f" header_text="#000000" header_text_hi="#ffffff" - button="#727272" + button="#727272ff" button_title="#000000" button_text="#000000" button_text_hi="#ffffff"> @@ -660,7 +660,7 @@ header="#646875" header_text="#dddddd" header_text_hi="#ffffff" - button="#b4b4b4" + button="#b4b4b4ff" button_title="#000000" button_text="#000000" button_text_hi="#ffffff"> @@ -678,7 +678,7 @@ header="#5c606c" header_text="#000000" header_text_hi="#ffffff" - button="#6c717f" + button="#6c717fff" button_title="#000000" button_text="#000000" button_text_hi="#ffffff"> @@ -700,7 +700,7 @@ header="#5c606c" header_text="#000000" header_text_hi="#ffffff" - button="#6c717f" + button="#6c717fff" button_title="#000000" button_text="#000000" button_text_hi="#ffffff"> @@ -732,7 +732,7 @@ header="#5c606c" header_text="#000000" header_text_hi="#ffffff" - button="#646875" + button="#646875ff" button_title="#000000" button_text="#000000" button_text_hi="#ffffff"> diff --git a/release/scripts/presets/interface_theme/ubuntu_ambiance.xml b/release/scripts/presets/interface_theme/ubuntu_ambiance.xml index 8f4a42b6ab7..b1fd93b52dd 100644 --- a/release/scripts/presets/interface_theme/ubuntu_ambiance.xml +++ b/release/scripts/presets/interface_theme/ubuntu_ambiance.xml @@ -288,7 +288,7 @@ header="#464541" header_text="#acacac" header_text_hi="#ffffff" - button="#3c3b37" + button="#3c3b3757" button_title="#9c9c9c" button_text="#9c9c9c" button_text_hi="#ffffff"> @@ -331,7 +331,7 @@ header="#464541" header_text="#acacac" header_text_hi="#ffffff" - button="#3c3b37" + button="#3c3b37ff" button_title="#9c9c9c" button_text="#9c9c9c" button_text_hi="#ffffff"> @@ -361,7 +361,7 @@ header="#464541" header_text="#acacac" header_text_hi="#ffffff" - button="#727272" + button="#727272ff" button_title="#000000" button_text="#000000" button_text_hi="#ffffff"> @@ -400,7 +400,7 @@ header="#464541" header_text="#acacac" header_text_hi="#ffffff" - button="#3c3b37" + button="#3c3b37ff" button_title="#000000" button_text="#000000" button_text_hi="#ffffff"> @@ -437,7 +437,7 @@ header="#464541" header_text="#cacaca" header_text_hi="#ffffff" - button="#3c3b37" + button="#3c3b37ff" button_title="#9c9c9c" button_text="#9c9c9c" button_text_hi="#ffffff"> @@ -476,7 +476,7 @@ header="#464541" header_text="#acacac" header_text_hi="#ffffff" - button="#3c3b37" + button="#3c3b37ff" button_title="#b1b1b1" button_text="#b9b9b9" button_text_hi="#ffffff"> @@ -507,7 +507,7 @@ header="#464541" header_text="#acacac" header_text_hi="#ffffff" - button="#3c3b37" + button="#3c3b3742" button_title="#acacac" button_text="#acacac" button_text_hi="#ffffff"> @@ -525,7 +525,7 @@ header="#464541" header_text="#acacac" header_text_hi="#ffffff" - button="#3c3b37" + button="#3c3b37ff" button_title="#000000" button_text="#000000" button_text_hi="#ffffff"> @@ -550,7 +550,7 @@ header="#464541" header_text="#acacac" header_text_hi="#ffffff" - button="#191919" + button="#191919ff" button_title="#64645e" button_text="#95948f" button_text_hi="#ffffff"> @@ -569,7 +569,7 @@ header="#464541" header_text="#acacac" header_text_hi="#ffffff" - button="#3c3b37" + button="#3c3b37ff" button_title="#9c9c9c" button_text="#9c9c9c" button_text_hi="#ffffff"> @@ -598,7 +598,7 @@ header="#464541" header_text="#acacac" header_text_hi="#ffffff" - button="#353430" + button="#3534302f" button_title="#acacac" button_text="#acacac" button_text_hi="#ffffff"> @@ -623,7 +623,7 @@ header="#464541" header_text="#acacac" header_text_hi="#ffffff" - button="#353430" + button="#353430ff" button_title="#7d7d7d" button_text="#acacac" button_text_hi="#ffffff"> @@ -642,7 +642,7 @@ header="#464541" header_text="#acacac" header_text_hi="#ffffff" - button="#3c3b37" + button="#3c3b37ff" button_title="#000000" button_text="#000000" button_text_hi="#f47421"> @@ -660,7 +660,7 @@ header="#464541" header_text="#ffffff" header_text_hi="#ffffff" - button="#3c3b37" + button="#3c3b37ff" button_title="#eeedeb" button_text="#eeedeb" button_text_hi="#ffffff"> @@ -678,7 +678,7 @@ header="#3c3b37" header_text="#d3d2cd" header_text_hi="#ffffff" - button="#696965" + button="#696965ff" button_title="#000000" button_text="#000000" button_text_hi="#ffffff"> @@ -700,7 +700,7 @@ header="#464541" header_text="#acacac" header_text_hi="#ffffff" - button="#3c3b37" + button="#3c3b37ff" button_title="#000000" button_text="#000000" button_text_hi="#ffffff"> @@ -732,7 +732,7 @@ header="#464541" header_text="#9c9c9c" header_text_hi="#ffffff" - button="#3c3b37" + button="#3c3b37ff" button_title="#9c9c9c" button_text="#ffffff" button_text_hi="#ffffff"> From 60808c5ed6a3b38ffefcdc4714ebdd5a2ae6d327 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 13 Dec 2012 10:37:04 +0000 Subject: [PATCH 091/252] disable openmp thread assert, would fail in cases where the caller was locking for its self (sculpt mode) --- intern/guardedalloc/intern/mallocn.c | 3 +++ source/blender/editors/space_view3d/view3d_draw.c | 6 +++--- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/intern/guardedalloc/intern/mallocn.c b/intern/guardedalloc/intern/mallocn.c index 59e780f21e5..d747f042cbc 100644 --- a/intern/guardedalloc/intern/mallocn.c +++ b/intern/guardedalloc/intern/mallocn.c @@ -113,11 +113,14 @@ typedef struct MemHead { /* for openmp threading asserts, saves time troubleshooting * we may need to extend this if blender code starts using MEM_ * functions inside OpenMP correctly with omp_set_lock() */ + +#if 0 /* disable for now, only use to debug openmp code which doesn lock threads for malloc */ #if defined(_OPENMP) && defined(DEBUG) # include # include # define DEBUG_OMP_MALLOC #endif +#endif typedef struct MemTail { int tag3, pad; diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c index c9387bd776d..2f09354439b 100644 --- a/source/blender/editors/space_view3d/view3d_draw.c +++ b/source/blender/editors/space_view3d/view3d_draw.c @@ -589,9 +589,9 @@ static void drawcursor(Scene *scene, ARegion *ar, View3D *v3d) /* we don't want the clipping for cursor */ if (ED_view3d_project_int_global(ar, give_cursor(scene, v3d), co, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) { - float f5 = 0.25f * U.widget_unit; - float f10 = 0.5f * U.widget_unit; - float f20 = U.widget_unit; + const float f5 = 0.25f * U.widget_unit; + const float f10 = 0.5f * U.widget_unit; + const float f20 = U.widget_unit; setlinestyle(0); cpack(0xFF); From b30c74a5175cfec05b096b6a36801dddea4009d3 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Thu, 13 Dec 2012 10:51:38 +0000 Subject: [PATCH 092/252] Fix #33510: Rotate around selection doesn't work when .blend saved in sculpt mode Issue was caused by calculateTransformCenter not giving any center point in cases object is in painting mode, which lead to previous offset used for view rotation. Since this previous offset is a static variable, it'll mean rotation will happen around scene origin after re-starting blender. Now made it so viewport rotation will use active object's center as an offset when active object is in painting mode. Should behave in more predictable way. --- .../blender/editors/space_view3d/view3d_edit.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/source/blender/editors/space_view3d/view3d_edit.c b/source/blender/editors/space_view3d/view3d_edit.c index c46e1aff9ae..19d10645e51 100644 --- a/source/blender/editors/space_view3d/view3d_edit.c +++ b/source/blender/editors/space_view3d/view3d_edit.c @@ -432,8 +432,21 @@ static void viewops_data_create(bContext *C, wmOperator *op, wmEvent *event) copy_v3_v3(vod->ofs, rv3d->ofs); if (vod->use_dyn_ofs) { - /* If there's no selection, lastofs is unmodified and last value since static */ - calculateTransformCenter(C, V3D_CENTROID, lastofs, NULL); + Scene *scene = CTX_data_scene(C); + Object *ob = OBACT; + + if (ob->mode & OB_MODE_ALL_PAINT) { + /* transformation is disabled for painting modes, which will make it + * so previous offset is used. This is annoying when you open file + * saved with active object in painting mode + */ + copy_v3_v3(lastofs, ob->obmat[3]); + } + else { + /* If there's no selection, lastofs is unmodified and last value since static */ + calculateTransformCenter(C, V3D_CENTROID, lastofs, NULL); + } + negate_v3_v3(vod->dyn_ofs, lastofs); } else if (U.uiflag & USER_ZBUF_ORBIT) { From dfc3685b1f93092a03b156571d640c64eb0ad955 Mon Sep 17 00:00:00 2001 From: Ton Roosendaal Date: Thu, 13 Dec 2012 10:58:00 +0000 Subject: [PATCH 093/252] Only LMB clicks in Panel should return "handled" - it accidentally returned it for mousewheel too. Previous commit made scrolling in button regions not work. --- source/blender/editors/interface/interface_panel.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/source/blender/editors/interface/interface_panel.c b/source/blender/editors/interface/interface_panel.c index f60e4dff23a..3eb4026f0e0 100644 --- a/source/blender/editors/interface/interface_panel.c +++ b/source/blender/editors/interface/interface_panel.c @@ -1157,27 +1157,31 @@ int ui_handler_panel_region(bContext *C, wmEvent *event) if (event->val == KM_PRESS) { - /* all inside clicks should return in break - overlapping/float panels */ - retval = WM_UI_HANDLER_BREAK; - /* open close on header */ if (ELEM(event->type, RETKEY, PADENTER)) { if (inside_header) { ui_handle_panel_header(C, block, mx, my, RETKEY); + retval = WM_UI_HANDLER_BREAK; break; } } else if (event->type == LEFTMOUSE) { + /* all inside clicks should return in break - overlapping/float panels */ + retval = WM_UI_HANDLER_BREAK; + if (inside_header) { if (event->ctrl) panels_collapse_all(sa, ar); ui_handle_panel_header(C, block, mx, my, 0); + retval = WM_UI_HANDLER_BREAK; break; } else if (inside_scale && !(pa->flag & PNL_CLOSED)) { panel_activate_state(C, pa, PANEL_STATE_DRAG_SCALE); + retval = WM_UI_HANDLER_BREAK; break; } + } else if (event->type == ESCKEY) { /*XXX 2.50*/ From c44d10547975f55c98e6b82e615d0ee34f5d6470 Mon Sep 17 00:00:00 2001 From: Ton Roosendaal Date: Thu, 13 Dec 2012 11:27:21 +0000 Subject: [PATCH 094/252] Bugfix, IRC report: If a new userpref.blend was loaded, but no startup.blend existed yet, Blender crashed. --- source/blender/windowmanager/intern/wm_files.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/source/blender/windowmanager/intern/wm_files.c b/source/blender/windowmanager/intern/wm_files.c index 73f26185764..cd5da43646c 100644 --- a/source/blender/windowmanager/intern/wm_files.c +++ b/source/blender/windowmanager/intern/wm_files.c @@ -529,10 +529,6 @@ int wm_homefile_read(bContext *C, ReportList *UNUSED(reports), short from_memory success = (BKE_read_file(C, startstr, NULL) != BKE_READ_FILE_FAIL); } - if (!from_memory && BLI_exists(prefstr)) { - success = BKE_read_file_userdef(prefstr, NULL); - if (success) printf("read new prefs: %s\n", prefstr); - } if (U.themes.first == NULL) { printf("\nError: No valid "STRINGIFY (BLENDER_STARTUP_FILE)", fall back to built-in default.\n\n"); @@ -550,6 +546,12 @@ int wm_homefile_read(bContext *C, ReportList *UNUSED(reports), short from_memory #endif } + /* check new prefs only after startup.blend was finished */ + if (!from_memory && BLI_exists(prefstr)) { + int done = BKE_read_file_userdef(prefstr, NULL); + if (done) printf("read new prefs: %s\n", prefstr); + } + /* prevent buggy files that had G_FILE_RELATIVE_REMAP written out by mistake. Screws up autosaves otherwise * can remove this eventually, only in a 2.53 and older, now its not written */ G.fileflags &= ~G_FILE_RELATIVE_REMAP; From 97bea740f8ea17420a9827204d0e68e5202f34a9 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 13 Dec 2012 11:54:39 +0000 Subject: [PATCH 095/252] svg source files from jendrzych, v. 2.5.06 split SVG in two to match the PNG's. Original URL: http://pixel-sized.blogspot.nl/2012/05/two-years-of-absence-here.html#more --- release/datafiles/blender_icons.svg | 67197 ++++++++++++++++++++++++++ release/datafiles/prvicons.svg | 19922 ++++++++ 2 files changed, 87119 insertions(+) create mode 100644 release/datafiles/blender_icons.svg create mode 100644 release/datafiles/prvicons.svg diff --git a/release/datafiles/blender_icons.svg b/release/datafiles/blender_icons.svg new file mode 100644 index 00000000000..6177ee77740 --- /dev/null +++ b/release/datafiles/blender_icons.svg @@ -0,0 +1,67197 @@ + + + + + Blender icons v. 2.5.06 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + Blender icons v. 2.5.06 + 21.05.2012 + + + Andrzej Ambroż + + + + + Andrzej Ambroż + + + + + Andrzej Ambroż + + + + + This content is under CC Attribution-NonCommercial ShareAlike licence 3.0 as long as it's used for Blender 3D GUI. Any other uses are not allowed. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/release/datafiles/prvicons.svg b/release/datafiles/prvicons.svg new file mode 100644 index 00000000000..2e77cd6e62a --- /dev/null +++ b/release/datafiles/prvicons.svg @@ -0,0 +1,19922 @@ + + + + + Blender icons v. 2.5.06 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + Blender icons v. 2.5.06 + 21.05.2012 + + + Andrzej Ambroż + + + + + Andrzej Ambroż + + + + + Andrzej Ambroż + + + + + This content is under CC Attribution-NonCommercial ShareAlike licence 3.0 as long as it's used for Blender 3D GUI. Any other uses are not allowed. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From 0f97d53c74b7b1c4a0b3e17a1ee66c04577fdd8a Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 13 Dec 2012 11:59:07 +0000 Subject: [PATCH 096/252] add include so alloca() is found on mingw. --- source/blender/blenlib/BLI_array.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/source/blender/blenlib/BLI_array.h b/source/blender/blenlib/BLI_array.h index c1b77077a4d..6d34b0d48d5 100644 --- a/source/blender/blenlib/BLI_array.h +++ b/source/blender/blenlib/BLI_array.h @@ -203,6 +203,10 @@ # define alloca _alloca #endif +#if defined(__MINGW32__) +# include /* mingw needs for alloca() */ +#endif + #if defined(__GNUC__) || defined(__clang__) #define BLI_array_alloca(arr, realsize) \ (typeof(arr))alloca(sizeof(*arr) * (realsize)) @@ -219,3 +223,4 @@ alloca(sizeof(*arr) * (realsize)); \ const int _##arr##_count = (realsize) #endif + From a63f0d320b4fb9351ebfd525b6c13d98dda25a15 Mon Sep 17 00:00:00 2001 From: Ton Roosendaal Date: Thu, 13 Dec 2012 12:17:57 +0000 Subject: [PATCH 097/252] Bugfix [#33511] Overlapping regions: when dragging the region to close them, it started the blending timer - which of course is not meant to happen. --- source/blender/editors/screen/area.c | 17 ++++++++++++----- source/blender/editors/screen/screen_intern.h | 1 + source/blender/editors/screen/screen_ops.c | 4 ++-- 3 files changed, 15 insertions(+), 7 deletions(-) diff --git a/source/blender/editors/screen/area.c b/source/blender/editors/screen/area.c index 80270116a13..a0bcab118f5 100644 --- a/source/blender/editors/screen/area.c +++ b/source/blender/editors/screen/area.c @@ -1257,25 +1257,32 @@ void ED_region_init(bContext *C, ARegion *ar) glLoadIdentity(); } -void ED_region_toggle_hidden(bContext *C, ARegion *ar) +/* for quick toggle, can skip fades */ +void region_toggle_hidden(bContext *C, ARegion *ar, int do_fade) { ScrArea *sa = CTX_wm_area(C); - + ar->flag ^= RGN_FLAG_HIDDEN; - - if (ar->overlap) { + + if (do_fade && ar->overlap) { /* starts a timer, and in end calls the stuff below itself (region_sblend_invoke()) */ region_blend_start(C, sa, ar); } else { if (ar->flag & RGN_FLAG_HIDDEN) WM_event_remove_handlers(C, &ar->handlers); - + ED_area_initialize(CTX_wm_manager(C), CTX_wm_window(C), sa); ED_area_tag_redraw(sa); } } +/* exported to all editors, uses fading default */ +void ED_region_toggle_hidden(bContext *C, ARegion *ar) +{ + region_toggle_hidden(C, ar, 1); +} + /* sa2 to sa1, we swap spaces for fullscreen to keep all allocated data */ /* area vertices were set */ void area_copy_data(ScrArea *sa1, ScrArea *sa2, int swap_space) diff --git a/source/blender/editors/screen/screen_intern.h b/source/blender/editors/screen/screen_intern.h index 2e2b53f57d6..b811fc46188 100644 --- a/source/blender/editors/screen/screen_intern.h +++ b/source/blender/editors/screen/screen_intern.h @@ -39,6 +39,7 @@ struct Scene; /* area.c */ void area_copy_data(ScrArea *sa1, ScrArea *sa2, int swap_space); +void region_toggle_hidden(bContext *C, ARegion *ar, int do_fade); /* screen_edit.c */ ScrEdge *screen_findedge(bScreen *sc, ScrVert *v1, ScrVert *v2); diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c index fef039bc196..807c5a4c457 100644 --- a/source/blender/editors/screen/screen_ops.c +++ b/source/blender/editors/screen/screen_ops.c @@ -1786,7 +1786,7 @@ static void region_scale_validate_size(RegionMoveData *rmd) static void region_scale_toggle_hidden(bContext *C, RegionMoveData *rmd) { - ED_region_toggle_hidden(C, rmd->ar); + region_toggle_hidden(C, rmd->ar, 0); region_scale_validate_size(rmd); } @@ -3594,7 +3594,7 @@ typedef struct RegionAlphaInfo { int hidden; } RegionAlphaInfo; -#define TIMEOUT 0.3f +#define TIMEOUT 0.2f #define TIMESTEP 0.04f float ED_region_blend_factor(ARegion *ar) From 8bd94b0af34b2014e4bdc37adcccce97542b02dc Mon Sep 17 00:00:00 2001 From: Jens Verwiebe Date: Thu, 13 Dec 2012 12:46:11 +0000 Subject: [PATCH 098/252] OSX: add plist key High Resolution Capable --- release/darwin/blender.app/Contents/Info.plist | 2 ++ release/darwin/blenderplayer.app/Contents/Info.plist | 2 ++ 2 files changed, 4 insertions(+) diff --git a/release/darwin/blender.app/Contents/Info.plist b/release/darwin/blender.app/Contents/Info.plist index 064ffe5bc3f..ecea0e3ec76 100644 --- a/release/darwin/blender.app/Contents/Info.plist +++ b/release/darwin/blender.app/Contents/Info.plist @@ -50,5 +50,7 @@ NSPrincipalClass NSApplication + NSHighResolutionCapable + diff --git a/release/darwin/blenderplayer.app/Contents/Info.plist b/release/darwin/blenderplayer.app/Contents/Info.plist index c7b9ceb568e..91eb2d7e84d 100644 --- a/release/darwin/blenderplayer.app/Contents/Info.plist +++ b/release/darwin/blenderplayer.app/Contents/Info.plist @@ -45,5 +45,7 @@ NSPrincipalClass NSApplication + NSHighResolutionCapable + From b120e649f20e28d736e730d51f456e6aa2392053 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 13 Dec 2012 12:52:12 +0000 Subject: [PATCH 099/252] remove unrelated text --- release/datafiles/blender_icons.svg | 2829 ++++++++++++++------------- 1 file changed, 1451 insertions(+), 1378 deletions(-) diff --git a/release/datafiles/blender_icons.svg b/release/datafiles/blender_icons.svg index 6177ee77740..7fd7bb5f980 100644 --- a/release/datafiles/blender_icons.svg +++ b/release/datafiles/blender_icons.svg @@ -890,19 +890,6 @@ style="stop-color:#9a9a9a;stop-opacity:1.0000000;" id="stop15568" /> - - - @@ -14900,32 +14887,6 @@ offset="1" id="stop44943-2" /> - - - - - - - - - + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path23719" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path23723" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path23727" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path23731" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path23735" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path23739" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path23743" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path23747" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path23751" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path23755" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path23759" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path23763" + inkscape:connector-curvature="0" /> + id="path10987" + inkscape:connector-curvature="0" /> + id="path23771" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path23775" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path23779" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path23783" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path23787" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path23791" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path23795" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path23799" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path23803" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path23807" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path23811" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path23815" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path23827" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path23831" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path23835" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path23839" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path23843" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path23847" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path23851" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path23855" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path23859" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path23863" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path23867" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path23871" + inkscape:connector-curvature="0" /> + id="path10992" + inkscape:connector-curvature="0" /> + id="path23879" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path23883" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path23887" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path23891" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path23895" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path23899" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path23903" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path23907" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path23911" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path23915" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path23919" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path23923" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path23935" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path23939" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path23943" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path23947" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path23951" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path23955" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path23959" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path23963" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path23967" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path23971" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path23975" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path23979" + inkscape:connector-curvature="0" /> + id="path10996" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path23989" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path23993" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path23997" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24001" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24005" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24009" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24013" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24017" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24021" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24025" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24029" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24033" + inkscape:connector-curvature="0" /> + id="path10998" + inkscape:connector-curvature="0" /> + id="path24041" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24045" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24049" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24053" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24057" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24061" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24065" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24069" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24073" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24077" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24081" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24085" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24097" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24101" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24105" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24109" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24113" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24117" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24121" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24125" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24129" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24133" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24137" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24141" + inkscape:connector-curvature="0" /> + id="path11002" + inkscape:connector-curvature="0" /> + id="path24149" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24153" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24157" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24161" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24165" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24169" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24173" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24177" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24181" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24185" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24189" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24193" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24205" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24209" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24213" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24217" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24221" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24225" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24229" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24233" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24237" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24241" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24245" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24249" + inkscape:connector-curvature="0" /> + id="path11006" + inkscape:connector-curvature="0" /> + id="path24257" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24261" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24265" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24269" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24273" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24277" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24281" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24285" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24289" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24293" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24297" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24301" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24313" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24317" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24321" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24325" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24329" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24333" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24337" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24341" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24345" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24349" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24353" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24357" + inkscape:connector-curvature="0" /> + id="path11010" + inkscape:connector-curvature="0" /> + id="path24365" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24369" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24373" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24377" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24381" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24385" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24389" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24393" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24397" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24401" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24405" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24409" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24421" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24425" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24429" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24433" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24437" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24441" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24445" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24449" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24453" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24457" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24461" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24465" + inkscape:connector-curvature="0" /> + id="path11014" + inkscape:connector-curvature="0" /> + id="path24473" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24477" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24481" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24485" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24489" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24493" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24497" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24501" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24505" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24509" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24513" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24517" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24529" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24533" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24537" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24541" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24545" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24549" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24553" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24557" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24561" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24565" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24569" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24573" + inkscape:connector-curvature="0" /> + id="path11018" + inkscape:connector-curvature="0" /> + id="path24581" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24585" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24589" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24593" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24597" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24601" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24605" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24609" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24613" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24617" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24621" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24625" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24638" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24642" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24646" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24650" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24654" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24658" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24662" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24666" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24670" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24674" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24678" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24682" + inkscape:connector-curvature="0" /> + id="path11022" + inkscape:connector-curvature="0" /> + id="path24690" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24694" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24698" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24702" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24706" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24710" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24714" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24718" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24722" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24726" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24730" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24734" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24746" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24750" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24754" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24758" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24762" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24766" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24770" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24774" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24778" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24782" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24786" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24790" + inkscape:connector-curvature="0" /> + id="path11026" + inkscape:connector-curvature="0" /> + id="path24798" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24802" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24806" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24810" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24814" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24818" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24822" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24826" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24830" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24834" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24838" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24842" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24854" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24858" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24862" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24866" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24870" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24874" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24878" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24882" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24886" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24890" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24894" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24898" + inkscape:connector-curvature="0" /> + id="path11030" + inkscape:connector-curvature="0" /> + id="path24906" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24910" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24914" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24918" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24922" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24926" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24930" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24934" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24938" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24942" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24946" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path24950" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path39840" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path39844" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path39848" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path39852" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path39856" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path39860" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path39864" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path39868" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path39872" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path39876" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path39880" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path39884" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path39900" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path39904" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path39909" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path39913" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path39917" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path39921" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path39925" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path39929" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path39933" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path39937" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path39941" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path39945" + inkscape:connector-curvature="0" /> + id="path39947" + inkscape:connector-curvature="0" /> + id="path39955" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path39959" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path39963" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path39967" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path39971" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path39975" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path39979" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path39983" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path39987" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path39991" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path39995" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path39999" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path40013" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path40017" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path40021" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path40025" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path40029" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path40033" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path40038" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path40042" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path40046" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path40050" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path40054" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path40058" + inkscape:connector-curvature="0" /> + id="path40060" + inkscape:connector-curvature="0" /> + id="path40068" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path40072" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path40076" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path40080" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path40084" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path40088" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path40092" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path40096" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path40100" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path40104" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path40108" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path40112" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path40126" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path40130" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path40134" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path40138" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path40142" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path40146" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path40150" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path40154" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path40158" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path40162" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path40166" + inkscape:connector-curvature="0" /> + style="opacity:0.9;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.70000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path40170" + inkscape:connector-curvature="0" /> + id="path40172" + inkscape:connector-curvature="0" /> @@ -23233,606 +23906,6 @@ id="path35918" inkscape:connector-curvature="0" /> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Date: Thu, 13 Dec 2012 13:20:01 +0000 Subject: [PATCH 100/252] Feature fix: Upgraded version to 2.65.1, and check on this to map default region backgrounds to have an alpha 0.5. This only worked until now for 2.64 savedi startups. --- source/blender/blenkernel/BKE_blender.h | 2 +- source/blender/editors/interface/resources.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/source/blender/blenkernel/BKE_blender.h b/source/blender/blenkernel/BKE_blender.h index 622b5090f05..8ba850c952c 100644 --- a/source/blender/blenkernel/BKE_blender.h +++ b/source/blender/blenkernel/BKE_blender.h @@ -42,7 +42,7 @@ extern "C" { * and keep comment above the defines. * Use STRINGIFY() rather than defining with quotes */ #define BLENDER_VERSION 265 -#define BLENDER_SUBVERSION 0 +#define BLENDER_SUBVERSION 1 /* 262 was the last editmesh release but it has compatibility code for bmesh data */ #define BLENDER_MINVERSION 262 diff --git a/source/blender/editors/interface/resources.c b/source/blender/editors/interface/resources.c index 3a482b97d37..180c5ddada2 100644 --- a/source/blender/editors/interface/resources.c +++ b/source/blender/editors/interface/resources.c @@ -2009,7 +2009,7 @@ void init_userdef_do_versions(void) if (U.tweak_threshold == 0) U.tweak_threshold = 10; - if (bmain->versionfile < 265) { /* XXX fix for when you apply */ + if (bmain->versionfile < 265 || (bmain->versionfile == 265 && bmain->subversionfile < 1)) { bTheme *btheme; for (btheme = U.themes.first; btheme; btheme = btheme->next) { From d06876f45ab479dd8c2defb52299222b57f81ec4 Mon Sep 17 00:00:00 2001 From: Ton Roosendaal Date: Thu, 13 Dec 2012 14:25:15 +0000 Subject: [PATCH 101/252] Bugfix, IRC report (Error in 2.65 release too) Mac OS X: on closing Blender, it 'flashed', which appeared to be a white window opening and closing quickly. Caused by code trying to send focus to another opened window, and accidentally focusing the closed one - causing it to reopen. --- intern/ghost/intern/GHOST_WindowCocoa.mm | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/intern/ghost/intern/GHOST_WindowCocoa.mm b/intern/ghost/intern/GHOST_WindowCocoa.mm index 2c833fcaf9d..e044967fdef 100644 --- a/intern/ghost/intern/GHOST_WindowCocoa.mm +++ b/intern/ghost/intern/GHOST_WindowCocoa.mm @@ -622,14 +622,19 @@ GHOST_WindowCocoa::~GHOST_WindowCocoa() // back to YES right before closing [m_window setReleasedWhenClosed:YES]; [m_window close]; - m_window = nil; } - //Check for other blender opened windows and make the frontmost key + // Check for other blender opened windows and make the frontmost key + // Note: for some reason the closed window is still in the list NSArray *windowsList = [NSApp orderedWindows]; - if ([windowsList count]) { - [[windowsList objectAtIndex:0] makeKeyAndOrderFront:nil]; + for (int a = 0; a < [windowsList count]; a++) { + if (m_window != (CocoaWindow *)[windowsList objectAtIndex:a]) { + [[windowsList objectAtIndex:a] makeKeyAndOrderFront:nil]; + break; + } } + m_window = nil; + [pool drain]; } From 02689df6c03ec99a1a957a6c29847952eb233b67 Mon Sep 17 00:00:00 2001 From: Antony Riakiotakis Date: Thu, 13 Dec 2012 14:33:14 +0000 Subject: [PATCH 102/252] Part of bratwurst GSOC cleanup of subsurf unwrap code: Ommit subsurf level in the operator and use the modifier level and subdivision type instead. Using subsurf only makes sense if the modifier is first so print an warning and turn off if this is not the case. --- .../editors/uvedit/uvedit_unwrap_ops.c | 58 ++++++++++++++----- source/blender/makesdna/DNA_scene_types.h | 4 +- 2 files changed, 46 insertions(+), 16 deletions(-) diff --git a/source/blender/editors/uvedit/uvedit_unwrap_ops.c b/source/blender/editors/uvedit/uvedit_unwrap_ops.c index 6c385527977..346ea6edf7a 100644 --- a/source/blender/editors/uvedit/uvedit_unwrap_ops.c +++ b/source/blender/editors/uvedit/uvedit_unwrap_ops.c @@ -87,6 +87,24 @@ #include "uvedit_intern.h" #include "uvedit_parametrizer.h" +static void modifier_unwrap_state(Object *obedit, Scene *scene, short *use_subsurf) +{ + ModifierData *md; + short subsurf = scene->toolsettings->uvcalc_flag & UVCALC_USESUBSURF; + + md = obedit->modifiers.first; + + /* subsurf will take the modifier settings only if modifier is first or right after mirror */ + if (subsurf) { + if (md && md->type == eModifierType_Subsurf) + subsurf = TRUE; + else + subsurf = FALSE; + } + + *use_subsurf = subsurf; +} + static int ED_uvedit_ensure_uvs(bContext *C, Scene *scene, Object *obedit) { Main *bmain = CTX_data_main(C); @@ -379,6 +397,9 @@ static ParamHandle *construct_param_handle_subsurfed(Scene *scene, Object *ob, B MEdge *edge; int i; + /* pointers to modifier data for unwrap control */ + ModifierData *md; + SubsurfModifierData *smd_real; /* modifier initialization data, will control what type of subdivision will happen*/ SubsurfModifierData smd = {{0}}; /* Used to hold subsurfed Mesh */ @@ -409,8 +430,11 @@ static ParamHandle *construct_param_handle_subsurfed(Scene *scene, Object *ob, B } /* number of subdivisions to perform */ - smd.levels = scene->toolsettings->uv_subsurf_level; - smd.subdivType = ME_CC_SUBSURF; + md = ob->modifiers.first; + smd_real = (SubsurfModifierData *)md; + + smd.levels = smd_real->levels; + smd.subdivType = smd_real->subdivType; initialDerived = CDDM_from_editbmesh(em, FALSE, FALSE); derivedMesh = subsurf_make_derived_from_derived(initialDerived, &smd, @@ -445,7 +469,7 @@ static ParamHandle *construct_param_handle_subsurfed(Scene *scene, Object *ob, B /* map subsurfed edges to original editEdges */ for (i = 0; i < numOfEdges; i++) { /* not all edges correspond to an old edge */ - edgeMap[i] = (origEdgeIndices[i] != -1) ? + edgeMap[i] = (origEdgeIndices[i] != ORIGINDEX_NONE) ? EDBM_edge_at_index(em, origEdgeIndices[i]) : NULL; } @@ -813,16 +837,18 @@ void ED_uvedit_live_unwrap_begin(Scene *scene, Object *obedit) BMEditMesh *em = BMEdit_FromObject(obedit); short abf = scene->toolsettings->unwrapper == 0; short fillholes = scene->toolsettings->uvcalc_flag & UVCALC_FILLHOLES; - short use_subsurf = scene->toolsettings->uvcalc_flag & UVCALC_USESUBSURF; + short use_subsurf; + + modifier_unwrap_state(obedit, scene, &use_subsurf); if (!ED_uvedit_test(obedit)) { return; } if (use_subsurf) - liveHandle = construct_param_handle_subsurfed(scene, obedit, em, fillholes, 0, 1); + liveHandle = construct_param_handle_subsurfed(scene, obedit, em, fillholes, FALSE, TRUE); else - liveHandle = construct_param_handle(scene, obedit, em, 0, fillholes, 0, 1); + liveHandle = construct_param_handle(scene, obedit, em, FALSE, fillholes, FALSE, TRUE); param_lscm_begin(liveHandle, PARAM_TRUE, abf); } @@ -1137,12 +1163,14 @@ void ED_unwrap_lscm(Scene *scene, Object *obedit, const short sel) const short fill_holes = scene->toolsettings->uvcalc_flag & UVCALC_FILLHOLES; const short correct_aspect = !(scene->toolsettings->uvcalc_flag & UVCALC_NO_ASPECT_CORRECT); - const short use_subsurf = scene->toolsettings->uvcalc_flag & UVCALC_USESUBSURF; + short use_subsurf; + + modifier_unwrap_state(obedit, scene, &use_subsurf); if (use_subsurf) handle = construct_param_handle_subsurfed(scene, obedit, em, fill_holes, sel, correct_aspect); else - handle = construct_param_handle(scene, obedit, em, 0, fill_holes, sel, correct_aspect); + handle = construct_param_handle(scene, obedit, em, FALSE, fill_holes, sel, correct_aspect); param_lscm_begin(handle, PARAM_FALSE, scene->toolsettings->unwrapper == 0); param_lscm_solve(handle); @@ -1165,7 +1193,7 @@ static int unwrap_exec(bContext *C, wmOperator *op) int fill_holes = RNA_boolean_get(op->ptr, "fill_holes"); int correct_aspect = RNA_boolean_get(op->ptr, "correct_aspect"); int use_subsurf = RNA_boolean_get(op->ptr, "use_subsurf_data"); - int subsurf_level = RNA_int_get(op->ptr, "uv_subsurf_level"); + short use_subsurf_final; float obsize[3]; short implicit = 0; @@ -1195,8 +1223,6 @@ static int unwrap_exec(bContext *C, wmOperator *op) else RNA_float_set(op->ptr, "margin", scene->toolsettings->uvcalc_margin); - scene->toolsettings->uv_subsurf_level = subsurf_level; - if (fill_holes) scene->toolsettings->uvcalc_flag |= UVCALC_FILLHOLES; else scene->toolsettings->uvcalc_flag &= ~UVCALC_FILLHOLES; @@ -1206,6 +1232,12 @@ static int unwrap_exec(bContext *C, wmOperator *op) if (use_subsurf) scene->toolsettings->uvcalc_flag |= UVCALC_USESUBSURF; else scene->toolsettings->uvcalc_flag &= ~UVCALC_USESUBSURF; + /* double up the check here but better keep ED_unwrap_lscm interface simple and not + * pass operator for warning append */ + modifier_unwrap_state(obedit, scene, &use_subsurf_final); + if(use_subsurf != use_subsurf_final) + BKE_report(op->reports, RPT_INFO, "Subsurf modifier needs to be first to work with unwrap"); + /* execute unwrap */ ED_unwrap_lscm(scene, obedit, TRUE); @@ -1240,10 +1272,8 @@ void UV_OT_unwrap(wmOperatorType *ot) "Virtual fill holes in mesh before unwrapping, to better avoid overlaps and preserve symmetry"); RNA_def_boolean(ot->srna, "correct_aspect", 1, "Correct Aspect", "Map UVs taking image aspect ratio into account"); - RNA_def_boolean(ot->srna, "use_subsurf_data", 0, "Use Subsurf Data", + RNA_def_boolean(ot->srna, "use_subsurf_data", 0, "Use Subsurf Modifier", "Map UVs taking vertex position after subsurf into account"); - RNA_def_int(ot->srna, "uv_subsurf_level", 1, 1, 6, "Subsurf Target", - "Number of times to subdivide before calculating UVs", 1, 6); RNA_def_float_factor(ot->srna, "margin", 0.001f, 0.0f, 1.0f, "Margin", "Space between islands", 0.0f, 1.0f); } diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h index 1afa6987ac6..988517f8ebc 100644 --- a/source/blender/makesdna/DNA_scene_types.h +++ b/source/blender/makesdna/DNA_scene_types.h @@ -945,7 +945,7 @@ typedef struct ToolSettings { short uvcalc_mapalign; short uvcalc_flag; short uv_flag, uv_selectmode; - short uv_subsurf_level; + short pad2; /* Grease Pencil */ short gpencil_flags; @@ -973,7 +973,7 @@ typedef struct ToolSettings { /* Multires */ char multires_subdiv_type; - char pad2[5]; + char pad3[5]; /* Skeleton generation */ short skgen_resolution; From 28cd6031405be776bbc6f40397732d8e8efe914d Mon Sep 17 00:00:00 2001 From: Ton Roosendaal Date: Thu, 13 Dec 2012 16:21:08 +0000 Subject: [PATCH 103/252] Bugfix - own collection. Very occasionally Timer Events could still get handled, after stopping a timer - especially with the timer event still in the queue. This patch disables such events. Introduced a EVENT_NONE to make sure it gets ignored everywhere. --- source/blender/windowmanager/intern/wm_window.c | 3 ++- source/blender/windowmanager/wm_event_types.h | 2 ++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/source/blender/windowmanager/intern/wm_window.c b/source/blender/windowmanager/intern/wm_window.c index 226f4f2aa60..be202a23d33 100644 --- a/source/blender/windowmanager/intern/wm_window.c +++ b/source/blender/windowmanager/intern/wm_window.c @@ -1129,7 +1129,8 @@ void WM_event_remove_timer(wmWindowManager *wm, wmWindow *UNUSED(win), wmTimer * wmEvent *event; for (event = win->queue.first; event; event = event->next) { if (event->customdata == wt) { - //event->customdata = NULL; + event->customdata = NULL; + event->type = EVENT_NONE; /* timer users customdata, dont want NULL == NULL */ } } } diff --git a/source/blender/windowmanager/wm_event_types.h b/source/blender/windowmanager/wm_event_types.h index de28cf5409d..c90bbaf8d6c 100644 --- a/source/blender/windowmanager/wm_event_types.h +++ b/source/blender/windowmanager/wm_event_types.h @@ -53,6 +53,8 @@ #define MOUSEX 4 #define MOUSEY 5 +/* non-event, for example disabled timer */ +#define EVENT_NONE 0 /* MOUSE : 0x00x */ #define LEFTMOUSE 1 #define MIDDLEMOUSE 2 From d4cd8239129fa66526137a2764de629bc4d2293c Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Thu, 13 Dec 2012 16:55:54 +0000 Subject: [PATCH 104/252] SCons: added static libs path for OIIO, OCIO and Boost This should make it easier to write user-config.py Still not sure how to deal with OSL and LLVM in a nice way, they're currently using some hacks which didn't support specifying this libraries as static. --- build_files/scons/config/linux-config.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/build_files/scons/config/linux-config.py b/build_files/scons/config/linux-config.py index 038a9bc421d..7ad52054bbe 100644 --- a/build_files/scons/config/linux-config.py +++ b/build_files/scons/config/linux-config.py @@ -206,6 +206,7 @@ if not os.path.exists(LCGDIR + '/oiio'): BF_OIIO = '/usr' BF_OIIO_INC = '${BF_OIIO}/include' BF_OIIO_LIB = 'OpenImageIO' +BF_OIIO_LIB_STATIC = '${BF_OIIO_LIBPATH}/libOpenImageIO.a ${BF_OPENEXR}/lib/libIlmImf.a ${BF_JPEG}/lib/libjpeg.a' BF_OIIO_LIBPATH = '${BF_OIIO}/lib' WITH_BF_OCIO = True @@ -216,6 +217,7 @@ if not os.path.exists(LCGDIR + '/ocio'): BF_OCIO = '/usr' BF_OCIO_INC = '${BF_OCIO}/include' BF_OCIO_LIB = 'OpenColorIO yaml-cpp tinyxml' +BF_OCIO_LIB_STATIC = '${BF_OCIO_LIBPATH}/libOpenColorIO.a ${BF_OCIO_LIBPATH}/libtinyxml.a ${BF_OCIO_LIBPATH}/libyaml-cpp.a' BF_OCIO_LIBPATH = '${BF_OCIO}/lib' WITH_BF_BOOST = True @@ -226,6 +228,9 @@ if not os.path.exists(LCGDIR + '/boost'): BF_BOOST = '/usr' BF_BOOST_INC = '${BF_BOOST}/include' BF_BOOST_LIB = 'boost_date_time boost_filesystem boost_regex boost_system boost_thread' +BF_BOOST_LIB_STATIC = '${BF_BOOST_LIBPATH}/libboost_filesystem.a ${BF_BOOST_LIBPATH}/libboost_date_time.a ' + \ + '${BF_BOOST_LIBPATH}/libboost_regex.a ${BF_BOOST_LIBPATH}/libboost_locale.a ${BF_BOOST_LIBPATH}/libboost_system.a' + \ + '${BF_BOOST_LIBPATH}/libboost_thread.a' BF_BOOST_LIB_INTERNATIONAL = 'boost_locale' BF_BOOST_LIBPATH = '${BF_BOOST}/lib' From 1d18a77019089d8201c1cffa75be8e24c2c03735 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Thu, 13 Dec 2012 17:12:00 +0000 Subject: [PATCH 105/252] Fix for using active scene instead of actually changed one in some RNA callbacks --- source/blender/makesrna/intern/rna_scene.c | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c index 32b6b97ccc2..8f31b176a3a 100644 --- a/source/blender/makesrna/intern/rna_scene.c +++ b/source/blender/makesrna/intern/rna_scene.c @@ -1247,27 +1247,32 @@ static void object_simplify_update(Object *ob) } } -static void rna_Scene_use_simplify_update(Main *bmain, Scene *scene, PointerRNA *UNUSED(ptr)) +static void rna_Scene_use_simplify_update(Main *bmain, Scene *UNUSED(scene), PointerRNA *ptr) { + Scene *sce = ptr->id.data; Scene *sce_iter; Base *base; - for (SETLOOPER(scene, sce_iter, base)) + for (SETLOOPER(sce, sce_iter, base)) object_simplify_update(base->object); DAG_ids_flush_update(bmain, 0); WM_main_add_notifier(NC_GEOM | ND_DATA, NULL); } -static void rna_Scene_simplify_update(Main *bmain, Scene *scene, PointerRNA *ptr) +static void rna_Scene_simplify_update(Main *bmain, Scene *UNUSED(scene), PointerRNA *ptr) { - if (scene->r.mode & R_SIMPLIFY) - rna_Scene_use_simplify_update(bmain, scene, ptr); + Scene *sce = ptr->id.data; + + if (sce->r.mode & R_SIMPLIFY) + rna_Scene_use_simplify_update(bmain, sce, ptr); } -static void rna_Scene_use_persistent_data_update(Main *bmain, Scene *scene, PointerRNA *UNUSED(ptr)) +static void rna_Scene_use_persistent_data_update(Main *bmain, Scene *UNUSED(scene), PointerRNA *ptr) { - if (!(scene->r.mode & R_PERSISTENT_DATA)) + Scene *sce = ptr->id.data; + + if (!(sce->r.mode & R_PERSISTENT_DATA)) RE_FreePersistentData(); } From ae2a9a6e7a5e8cf81bb2ffadde05f348ffcac8e1 Mon Sep 17 00:00:00 2001 From: Ton Roosendaal Date: Thu, 13 Dec 2012 17:43:12 +0000 Subject: [PATCH 106/252] Bug fix, irc report: Overlapping regions, when you both want them on the same side they should not overlap each other! (Try F5 on a region to flip position). Code for subdivision is in need for some cleanup - a branching recursion is needed. --- source/blender/editors/screen/area.c | 34 ++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/source/blender/editors/screen/area.c b/source/blender/editors/screen/area.c index a0bcab118f5..db57aeb0167 100644 --- a/source/blender/editors/screen/area.c +++ b/source/blender/editors/screen/area.c @@ -874,6 +874,36 @@ static int rct_fits(rcti *rect, char dir, int size) /* *************************************************************** */ +/* ar should be overlapping */ +/* function checks if some overlapping region was defined before - on same place */ +static void region_overlap_fix(ARegion *ar) +{ + ARegion *ar1 = ar->prev; + + /* find overlapping previous region on same place */ + while (ar1) { + if (ar1->overlap) { + if ((ar1->alignment & RGN_SPLIT_PREV)==0) + if (BLI_rcti_isect(&ar1->winrct, &ar->winrct, NULL)) + break; + } + ar1 = ar1->prev; + } + + /* translate */ + if (ar1) { + int align1 = ar1->alignment & ~RGN_SPLIT_PREV; + + if (align1 == RGN_ALIGN_LEFT) { + BLI_rcti_translate(&ar->winrct, ar1->winx, 0); + } + else if (align1 == RGN_ALIGN_RIGHT) { + BLI_rcti_translate(&ar->winrct, -ar1->winx, 0); + } + } + +} + /* overlapping regions only in the following restricted cases */ static int region_is_overlap(wmWindow *win, ScrArea *sa, ARegion *ar) { @@ -1061,6 +1091,10 @@ static void region_rect_recursive(wmWindow *win, ScrArea *sa, ARegion *ar, rcti ar->winx = BLI_rcti_size_x(&ar->winrct) + 1; ar->winy = BLI_rcti_size_y(&ar->winrct) + 1; + /* exception for multiple aligned overlapping regions on same spot */ + if (ar->overlap) + region_overlap_fix(ar); + /* set winrect for azones */ if (ar->flag & (RGN_FLAG_HIDDEN | RGN_FLAG_TOO_SMALL)) { ar->winrct = *remainder; From fd755d2550bef8191d29adf15e6293779b033c0c Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Thu, 13 Dec 2012 20:07:16 +0000 Subject: [PATCH 107/252] Fix #33522: Crash when "rotate arond selection" is on, and when no object in scene Own regression in recent fix --- source/blender/editors/space_view3d/view3d_edit.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/editors/space_view3d/view3d_edit.c b/source/blender/editors/space_view3d/view3d_edit.c index 19d10645e51..cd5770ba940 100644 --- a/source/blender/editors/space_view3d/view3d_edit.c +++ b/source/blender/editors/space_view3d/view3d_edit.c @@ -435,7 +435,7 @@ static void viewops_data_create(bContext *C, wmOperator *op, wmEvent *event) Scene *scene = CTX_data_scene(C); Object *ob = OBACT; - if (ob->mode & OB_MODE_ALL_PAINT) { + if (ob && ob->mode & OB_MODE_ALL_PAINT) { /* transformation is disabled for painting modes, which will make it * so previous offset is used. This is annoying when you open file * saved with active object in painting mode From 60800669d5137c3c6a858f2cc6a4a593fae2c24a Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 13 Dec 2012 23:18:38 +0000 Subject: [PATCH 108/252] patch [#33448] Adding Vector Sources for Icons add additional icons to the svg. --- release/datafiles/blender_icons.svg | 36135 +++++++++++++++++++++++++- 1 file changed, 35826 insertions(+), 309 deletions(-) diff --git a/release/datafiles/blender_icons.svg b/release/datafiles/blender_icons.svg index 7fd7bb5f980..6abb7d250f0 100644 --- a/release/datafiles/blender_icons.svg +++ b/release/datafiles/blender_icons.svg @@ -16788,88 +16788,6 @@ offset="1" style="stop-color:#306998;stop-opacity:1;" /> - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + xlink:href="#linearGradient1610-09" + id="linearGradient36657-4" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(0.888889,0,0,1,513.5,184.50451)" + x1="253.78497" + y1="3.6831069" + x2="278.25537" + y2="30.023426" /> + + id="stop84211" /> + + + + + + id="stop84220" /> + gradientTransform="translate(670,-33)" + x1="87" + y1="241.125" + x2="93.0625" + y2="249" /> + + + + + xlink:href="#linearGradient16500-1" + id="linearGradient36663-5" + gradientUnits="userSpaceOnUse" + gradientTransform="translate(0,-95.999998)" + x1="754.28558" + y1="300.83292" + x2="758" + y2="305" /> + + + + + + + + id="stop84246" /> + id="stop84248" /> + gradientTransform="matrix(-1,0,0,1,551,105)" + x1="497.3125" + y1="35" + x2="483" + y2="35" /> + + + + + xlink:href="#linearGradient1610-09" + id="linearGradient37138-5" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(-1,0,0,1,551,105)" + x1="497.3125" + y1="35" + x2="483" + y2="35" /> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + id="stop84345" /> + id="stop84347" /> + gradientTransform="translate(-15.983875,338)" + x1="70.55275" + y1="97.5" + x2="79.355118" + y2="107.18619" /> + + + + + xlink:href="#linearGradient319-43" + id="linearGradient71838-5" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(0.9998599,0,0,0.9960071,-15.972985,338.41149)" + x1="61.465469" + y1="88.058716" + x2="86.00116" + y2="112.03586" /> + + id="stop84359" /> + id="stop84361" /> + x1="-26" + y1="38" + x2="-27" + y2="30.200407" + gradientTransform="translate(522.00015,466)" /> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + style="display:inline;enable-background:new" + id="g42207-2" + transform="translate(230.99917,191.00001)"> + transform="translate(83.990364,83.999999)" + id="g42209-9" + style="opacity:0.5"> + inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png" + d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z" + sodipodi:ry="8" + sodipodi:rx="8" + sodipodi:cy="118" + sodipodi:cx="132" + id="path42213-0" + style="fill:none;stroke:url(#linearGradient42487-4-8);stroke-width:1.22662127;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" + sodipodi:type="arc" + transform="matrix(0.814129,0,0,0.816369,-10.451999,24.674751)" /> - - + transform="matrix(0.814129,0,0,0.816369,-10.451999,24.674751)" + sodipodi:type="arc" + style="fill:none;stroke:url(#linearGradient42491-0-0);stroke-width:1.22662127;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" + id="path42217-3" + sodipodi:cx="132" + sodipodi:cy="118" + sodipodi:rx="8" + sodipodi:ry="8" + d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z" + inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png" + inkscape:export-xdpi="90" + inkscape:export-ydpi="90" /> + + transform="matrix(1.3088013,0,0,1.3078064,114.94487,78.842325)" + style="display:inline" + inkscape:export-ydpi="90" + inkscape:export-xdpi="90" + inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png" + id="g42219-5" /> + + + + + + id="g36345-6" + transform="matrix(1.1658027,0,0,1.1657997,198.71028,-2.0560643)"> + inkscape:transform-center-y="-3.2499984" + inkscape:transform-center-x="-2.8145849" + sodipodi:end="5.7595865" + sodipodi:start="4.712389" + inkscape:export-ydpi="90" + inkscape:export-xdpi="90" + inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png" + d="m 132,110 a 8,8 0 0 1 6.9282,4 L 132,118 z" + sodipodi:ry="8" + sodipodi:rx="8" + sodipodi:cy="118" + sodipodi:cx="132" + id="path36349-3" + style="fill:#df0505;fill-opacity:1;fill-rule:nonzero;stroke:none" + sodipodi:type="arc" + transform="matrix(0.6969448,0,0,0.6969467,36.918512,140.83126)" /> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + style="opacity:0.2;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.9999994px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + id="rect38927-6" + width="11.970581" + height="8.0306396" + x="329.02942" + y="605.96936" /> + + inkscape:export-ydpi="90" + inkscape:export-xdpi="90" + inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png" + id="path42957-3" + d="m 340.48389,606.50001 c -3.66204,-3e-5 -7.70403,2e-5 -10.98389,-10e-6 l 0.002,10.00007 10.99778,-7e-5 -0.0161,-9.99999 2.1e-4,0 z" + style="fill:none;stroke:url(#linearGradient42965-7-9-1);stroke-width:0.99999923px;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + sodipodi:nodetypes="ccccc" + inkscape:connector-curvature="0" /> + + sodipodi:nodetypes="ccccc" + style="opacity:0.35;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.9999994px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + d="m 340.5,614 -11,0 0,-1 11,0 0,1 z" + id="path38929-0" + inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png" + inkscape:export-xdpi="90" + inkscape:export-ydpi="90" + inkscape:connector-curvature="0" /> + + + + + + + + + - - - - + d="M -15.594023,497.94339 -20.25,493.5" + style="fill:none;stroke:#28170b;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.34386529;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + id="path26264-6" + inkscape:connector-curvature="0" /> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + transform="translate(160.99163,124)" + id="g45287-4"> + + + + + - + id="rect32363-6" + style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" /> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + y="52" + x="320" + height="16" + width="16" + id="rect44095-0" + style="opacity:0;fill:#1a1a1a;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.20000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" /> + + + + + + + + + + + + + + + + + - + style="opacity:0;fill:#1a1a1a;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.20000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + id="rect44093-6" + width="16" + height="16" + x="341" + y="52" /> + + + + + + + + + + + + + + + + + + style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + id="rect29107-0" + width="16" + height="16" + x="742" + y="414" /> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From 566af58e1cb95f83082c782da61e835f9d32bd0a Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 14 Dec 2012 00:49:55 +0000 Subject: [PATCH 109/252] add assert if both args to invert_m4_m4 are the same. --- source/blender/blenlib/intern/math_matrix.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/source/blender/blenlib/intern/math_matrix.c b/source/blender/blenlib/intern/math_matrix.c index 3ca771769a6..70eb5c1bb60 100644 --- a/source/blender/blenlib/intern/math_matrix.c +++ b/source/blender/blenlib/intern/math_matrix.c @@ -613,6 +613,8 @@ int invert_m4_m4(float inverse[4][4], float mat[4][4]) float max; int maxj; + BLI_assert(inverse != mat); + /* Set inverse to identity */ for (i = 0; i < 4; i++) for (j = 0; j < 4; j++) From 370c0ce09f2f3324e381565e04189667e4666089 Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Fri, 14 Dec 2012 01:34:11 +0000 Subject: [PATCH 110/252] SVG Icons - Ported over some of the animation related icons * Made SVG versions of the NLA solo (star) icons. These are much nicer than the hack 'n slash bitmap versions, but could still do with some polish. The svg is too heavy to do fine tweaks here. * Ported over the mute/graph-visible icons * Recreated Drivers icon * Moved Blender icon from AD1/DA1 to AD16/DA16, as per the trunk icon sheet --- release/datafiles/blender_icons.svg | 2070 ++++++++++++++++----------- 1 file changed, 1240 insertions(+), 830 deletions(-) diff --git a/release/datafiles/blender_icons.svg b/release/datafiles/blender_icons.svg index 6abb7d250f0..9403edeb110 100644 --- a/release/datafiles/blender_icons.svg +++ b/release/datafiles/blender_icons.svg @@ -14,7 +14,7 @@ height="640" id="svg2" sodipodi:version="0.32" - inkscape:version="0.48.3.1 r9886" + inkscape:version="0.48.2 r9819" version="1.0" sodipodi:docname="blender_icons.svg" inkscape:output_extension="org.inkscape.output.svg.inkscape" @@ -17138,19 +17138,6 @@ offset="1" style="stop-color:#ffffff;stop-opacity:1;" /> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -57402,7 +57436,7 @@ sodipodi:cy="118" sodipodi:rx="8" sodipodi:ry="8" - d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z" + d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z" inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png" inkscape:export-xdpi="90" inkscape:export-ydpi="90" /> @@ -57410,7 +57444,7 @@ inkscape:export-ydpi="90" inkscape:export-xdpi="90" inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png" - d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z" + d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z" sodipodi:ry="8" sodipodi:rx="8" sodipodi:cy="118" @@ -57446,7 +57480,7 @@ inkscape:export-ydpi="90" inkscape:export-xdpi="90" inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png" - d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z" + d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z" sodipodi:ry="8" sodipodi:rx="8" sodipodi:cy="118" @@ -57463,7 +57497,7 @@ sodipodi:cy="118" sodipodi:rx="8" sodipodi:ry="8" - d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z" + d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z" inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png" inkscape:export-xdpi="90" inkscape:export-ydpi="90" /> @@ -57477,7 +57511,7 @@ sodipodi:cy="118" sodipodi:rx="8" sodipodi:ry="8" - d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z" + d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z" inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png" inkscape:export-xdpi="90" inkscape:export-ydpi="90" /> @@ -57485,7 +57519,7 @@ inkscape:export-ydpi="90" inkscape:export-xdpi="90" inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png" - d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z" + d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z" sodipodi:ry="8" sodipodi:rx="8" sodipodi:cy="118" @@ -57498,7 +57532,7 @@ inkscape:export-ydpi="90" inkscape:export-xdpi="90" inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png" - d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z" + d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z" sodipodi:ry="8" sodipodi:rx="8" sodipodi:cy="118" @@ -57547,7 +57581,7 @@ inkscape:export-xdpi="90" inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png" transform="matrix(1.0911926,0,0,1.176776,253.08415,-79.548088)" - d="m 72,14.5 a 1.5,1.5 0 1 1 -3,0 1.5,1.5 0 1 1 3,0 z" + d="M 72,14.5 C 72,15.328427 71.328427,16 70.5,16 69.671573,16 69,15.328427 69,14.5 69,13.671573 69.671573,13 70.5,13 c 0.828427,0 1.5,0.671573 1.5,1.5 z" sodipodi:ry="1.5" sodipodi:rx="1.5" sodipodi:cy="14.5" @@ -58021,7 +58055,7 @@ inkscape:export-ydpi="90" inkscape:export-xdpi="90" inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png" - d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z" + d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z" sodipodi:ry="8" sodipodi:rx="8" sodipodi:cy="118" @@ -58046,7 +58080,7 @@ sodipodi:cy="118" sodipodi:rx="8" sodipodi:ry="8" - d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z" + d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z" inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png" inkscape:export-xdpi="90" inkscape:export-ydpi="90" /> @@ -58055,7 +58089,7 @@ inkscape:export-ydpi="90" inkscape:export-xdpi="90" inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png" - d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z" + d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z" sodipodi:ry="8" sodipodi:rx="8" sodipodi:cy="118" @@ -58107,7 +58141,7 @@ inkscape:export-ydpi="90" inkscape:export-xdpi="90" inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png" - d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z" + d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z" sodipodi:ry="8" sodipodi:rx="8" sodipodi:cy="118" @@ -58124,7 +58158,7 @@ sodipodi:cy="118" sodipodi:rx="8" sodipodi:ry="8" - d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z" + d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z" inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png" inkscape:export-xdpi="90" inkscape:export-ydpi="90" @@ -58197,7 +58231,7 @@ sodipodi:cy="118" sodipodi:rx="8" sodipodi:ry="8" - d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z" + d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z" inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png" inkscape:export-xdpi="90" inkscape:export-ydpi="90" /> @@ -58206,7 +58240,7 @@ inkscape:export-ydpi="90" inkscape:export-xdpi="90" inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png" - d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z" + d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z" sodipodi:ry="8" sodipodi:rx="8" sodipodi:cy="118" @@ -58226,7 +58260,7 @@ inkscape:export-ydpi="90" inkscape:export-xdpi="90" inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png" - d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z" + d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z" sodipodi:ry="8" sodipodi:rx="8" sodipodi:cy="118" @@ -58243,7 +58277,7 @@ sodipodi:cy="118" sodipodi:rx="8" sodipodi:ry="8" - d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z" + d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z" inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png" inkscape:export-xdpi="90" inkscape:export-ydpi="90" @@ -58314,7 +58348,7 @@ sodipodi:cy="118" sodipodi:rx="8" sodipodi:ry="8" - d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z" + d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z" inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png" inkscape:export-xdpi="90" inkscape:export-ydpi="90" /> @@ -58329,7 +58363,7 @@ inkscape:export-ydpi="90" inkscape:export-xdpi="90" inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png" - d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z" + d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z" sodipodi:ry="8" sodipodi:rx="8" sodipodi:cy="118" @@ -58346,7 +58380,7 @@ sodipodi:cy="118" sodipodi:rx="8" sodipodi:ry="8" - d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z" + d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z" inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png" inkscape:export-xdpi="90" inkscape:export-ydpi="90" @@ -58368,7 +58402,7 @@ sodipodi:cy="118" sodipodi:rx="8" sodipodi:ry="8" - d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z" + d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z" inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png" inkscape:export-xdpi="90" inkscape:export-ydpi="90" /> @@ -58377,7 +58411,7 @@ inkscape:export-ydpi="90" inkscape:export-xdpi="90" inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png" - d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z" + d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z" sodipodi:ry="8" sodipodi:rx="8" sodipodi:cy="118" @@ -58448,7 +58482,7 @@ inkscape:export-ydpi="90" inkscape:export-xdpi="90" inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png" - d="m 141.08637,118 a 9.0863705,9.0860729 0 1 1 -18.17274,0 9.0863705,9.0860729 0 1 1 18.17274,0 z" + d="m 141.08637,118 c 0,5.0181 -4.06811,9.08607 -9.08637,9.08607 -5.01826,0 -9.08637,-4.06797 -9.08637,-9.08607 0,-5.0181 4.06811,-9.08607 9.08637,-9.08607 5.01826,0 9.08637,4.06797 9.08637,9.08607 z" sodipodi:ry="9.0860729" sodipodi:rx="9.0863705" sodipodi:cy="118" @@ -58474,7 +58508,7 @@ sodipodi:cy="118" sodipodi:rx="9.0863705" sodipodi:ry="9.0860729" - d="m 141.08637,118 a 9.0863705,9.0860729 0 1 1 -18.17274,0 9.0863705,9.0860729 0 1 1 18.17274,0 z" + d="m 141.08637,118 c 0,5.0181 -4.06811,9.08607 -9.08637,9.08607 -5.01826,0 -9.08637,-4.06797 -9.08637,-9.08607 0,-5.0181 4.06811,-9.08607 9.08637,-9.08607 5.01826,0 9.08637,4.06797 9.08637,9.08607 z" inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png" inkscape:export-xdpi="90" inkscape:export-ydpi="90" /> @@ -58721,7 +58755,7 @@ sodipodi:cy="-222" sodipodi:rx="3.3084693" sodipodi:ry="1.2798798" - d="m 111.30847,-222 a 3.3084693,1.2798798 0 1 1 -6.61694,0 3.3084693,1.2798798 0 1 1 6.61694,0 z" + d="m 111.30847,-222 c 0,0.70686 -1.48125,1.27988 -3.30847,1.27988 -1.82722,0 -3.30847,-0.57302 -3.30847,-1.27988 0,-0.70686 1.48125,-1.27988 3.30847,-1.27988 1.82722,0 3.30847,0.57302 3.30847,1.27988 z" transform="matrix(1.0307577,0,0,0.9140456,39.651558,-39.251735)" /> @@ -59265,7 +59299,7 @@ inkscape:export-xdpi="90" inkscape:export-ydpi="90"> + d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z" /> @@ -59712,7 +59746,7 @@ inkscape:export-ydpi="90" inkscape:export-xdpi="90" inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png" - d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z" + d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z" sodipodi:ry="8" sodipodi:rx="8" sodipodi:cy="118" @@ -59823,7 +59857,7 @@ inkscape:export-ydpi="90" inkscape:export-xdpi="90" inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png" - d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z" + d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z" sodipodi:ry="8" sodipodi:rx="8" sodipodi:cy="118" @@ -59863,7 +59897,7 @@ sodipodi:cy="118" sodipodi:rx="8" sodipodi:ry="8" - d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z" + d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z" inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png" inkscape:export-xdpi="90" inkscape:export-ydpi="90" /> @@ -59902,7 +59936,7 @@ sodipodi:cy="119.5" sodipodi:rx="5.5" sodipodi:ry="5.5" - d="m 196,119.5 a 5.5,5.5 0 1 1 -11,0 5.5,5.5 0 1 1 11,0 z" + d="m 196,119.5 c 0,3.03757 -2.46243,5.5 -5.5,5.5 -3.03757,0 -5.5,-2.46243 -5.5,-5.5 0,-3.03757 2.46243,-5.5 5.5,-5.5 3.03757,0 5.5,2.46243 5.5,5.5 z" transform="matrix(0.61819,0,0,0.618186,73.23488,45.12681)" /> @@ -59921,7 +59955,7 @@ id="g24576"> @@ -60225,7 +60259,7 @@ sodipodi:cy="165" sodipodi:rx="1" sodipodi:ry="1" - d="m 148,165 a 1,1 0 1 1 -2,0 1,1 0 1 1 2,0 z" + d="m 148,165 c 0,0.55228 -0.44772,1 -1,1 -0.55228,0 -1,-0.44772 -1,-1 0,-0.55228 0.44772,-1 1,-1 0.55228,0 1,0.44772 1,1 z" transform="matrix(1.5,0,0,1.5,-73.5,-83.5)" inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png" inkscape:export-xdpi="90" @@ -60244,7 +60278,7 @@ inkscape:export-xdpi="90" inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png" transform="matrix(1.5,0,0,1.5,-66.5,-83.5)" - d="m 148,165 a 1,1 0 1 1 -2,0 1,1 0 1 1 2,0 z" + d="m 148,165 c 0,0.55228 -0.44772,1 -1,1 -0.55228,0 -1,-0.44772 -1,-1 0,-0.55228 0.44772,-1 1,-1 0.55228,0 1,0.44772 1,1 z" sodipodi:ry="1" sodipodi:rx="1" sodipodi:cy="165" @@ -60285,7 +60319,7 @@ sodipodi:cy="78.5" sodipodi:rx="3.5" sodipodi:ry="3.5" - d="m 262,78.5 a 3.5,3.5 0 1 1 -7,0 3.5,3.5 0 1 1 7,0 z" + d="m 262,78.5 c 0,1.932997 -1.567,3.5 -3.5,3.5 -1.933,0 -3.5,-1.567003 -3.5,-3.5 0,-1.932997 1.567,-3.5 3.5,-3.5 1.933,0 3.5,1.567003 3.5,3.5 z" transform="matrix(-1.4308622,0,0,1.4308687,469.36987,363.18486)" inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png" inkscape:export-xdpi="90" @@ -60313,7 +60347,7 @@ inkscape:export-xdpi="90" inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png" transform="matrix(-1.4308622,0,0,1.4308687,469.36987,363.18486)" - d="m 262,78.5 a 3.5,3.5 0 1 1 -7,0 3.5,3.5 0 1 1 7,0 z" + d="m 262,78.5 c 0,1.932997 -1.567,3.5 -3.5,3.5 -1.933,0 -3.5,-1.567003 -3.5,-3.5 0,-1.932997 1.567,-3.5 3.5,-3.5 1.933,0 3.5,1.567003 3.5,3.5 z" sodipodi:ry="3.5" sodipodi:rx="3.5" sodipodi:cy="78.5" @@ -60339,13 +60373,13 @@ sodipodi:cy="78.5" sodipodi:rx="3.5" sodipodi:ry="3.5" - d="m 262,78.5 a 3.5,3.5 0 1 1 -7,0 3.5,3.5 0 1 1 7,0 z" + d="m 262,78.5 c 0,1.932997 -1.567,3.5 -3.5,3.5 -1.933,0 -3.5,-1.567003 -3.5,-3.5 0,-1.932997 1.567,-3.5 3.5,-3.5 1.933,0 3.5,1.567003 3.5,3.5 z" transform="matrix(-1.14287,0,0,1.142863,463.9317,115.7853)" /> @@ -61114,7 +61148,7 @@ sodipodi:cy="35.5" sodipodi:rx="3.5" sodipodi:ry="3.5" - d="m 334,35.5 a 3.5,3.5 0 1 1 -7,0 3.5,3.5 0 1 1 7,0 z" + d="m 334,35.5 c 0,1.932997 -1.567,3.5 -3.5,3.5 -1.933,0 -3.5,-1.567003 -3.5,-3.5 0,-1.932997 1.567,-3.5 3.5,-3.5 1.933,0 3.5,1.567003 3.5,3.5 z" transform="matrix(1.000048,0,0,0.999998,-0.01591645,12.000064)" /> @@ -61158,7 +61192,7 @@ style="fill:none;stroke:#000000;stroke-width:0.80000001;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.5;display:inline" /> @@ -61563,7 +61597,7 @@ inkscape:export-ydpi="90" inkscape:export-xdpi="90" inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png" - d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z" + d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z" sodipodi:ry="8" sodipodi:rx="8" sodipodi:cy="118" @@ -61581,7 +61615,7 @@ sodipodi:cy="118" sodipodi:rx="8" sodipodi:ry="8" - d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z" + d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z" inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png" inkscape:export-xdpi="90" inkscape:export-ydpi="90" /> @@ -62234,7 +62268,7 @@ inkscape:export-ydpi="90" inkscape:export-xdpi="90" inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png" - d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z" + d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z" sodipodi:ry="8" sodipodi:rx="8" sodipodi:cy="118" @@ -62260,7 +62294,7 @@ sodipodi:cy="118" sodipodi:rx="8" sodipodi:ry="8" - d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z" + d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z" inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png" inkscape:export-xdpi="90" inkscape:export-ydpi="90" /> @@ -62395,7 +62429,7 @@ sodipodi:cy="118" sodipodi:rx="8" sodipodi:ry="8" - d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z" + d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z" inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png" inkscape:export-xdpi="90" inkscape:export-ydpi="90" /> @@ -62403,7 +62437,7 @@ inkscape:export-ydpi="90" inkscape:export-xdpi="90" inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png" - d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z" + d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z" sodipodi:ry="8" sodipodi:rx="8" sodipodi:cy="118" @@ -62422,7 +62456,7 @@ sodipodi:cy="118" sodipodi:rx="8" sodipodi:ry="8" - d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z" + d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z" inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png" inkscape:export-xdpi="90" inkscape:export-ydpi="90" @@ -62431,7 +62465,7 @@ inkscape:export-ydpi="90" inkscape:export-xdpi="90" inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png" - d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z" + d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z" sodipodi:ry="8" sodipodi:rx="8" sodipodi:cy="118" @@ -63802,7 +63836,7 @@ sodipodi:cy="35.5" sodipodi:rx="2.7944512" sodipodi:ry="2.7944512" - d="m 333.29445,35.5 a 2.7944512,2.7944512 0 1 1 -5.5889,0 2.7944512,2.7944512 0 1 1 5.5889,0 z" + d="m 333.29445,35.5 c 0,1.543333 -1.25112,2.794451 -2.79445,2.794451 -1.54333,0 -2.79445,-1.251118 -2.79445,-2.794451 0,-1.543333 1.25112,-2.794451 2.79445,-2.794451 1.54333,0 2.79445,1.251118 2.79445,2.794451 z" transform="matrix(1.4256767,0,0,1.4314068,-320.1963,68.175135)" /> @@ -64509,7 +64543,7 @@ sodipodi:cy="502" sodipodi:rx="2.5312502" sodipodi:ry="2.5" - d="m 80.53125,502 a 2.5312502,2.5 0 1 1 -5.0625,0 2.5312502,2.5 0 1 1 5.0625,0 z" + d="m 80.53125,502 c 0,1.38071 -1.133279,2.5 -2.53125,2.5 -1.397971,0 -2.53125,-1.11929 -2.53125,-2.5 0,-1.38071 1.133279,-2.5 2.53125,-2.5 1.397971,0 2.53125,1.11929 2.53125,2.5 z" transform="matrix(0.7834486,0,0,0.2000006,10.413535,395.5997)" /> + d="m 446.5,108.5 c 0,1.65685 -1.34315,3 -3,3 -1.65685,0 -3,-1.34315 -3,-3 0,-1.65685 1.34315,-3 3,-3 1.65685,0 3,1.34315 3,3 z" /> + d="m 440.514,108.7895 c -0.15988,-1.64913 1.04738,-3.11561 2.6965,-3.2755 1.64913,-0.15988 3.11561,1.04738 3.2755,2.6965 0.15988,1.64913 -1.04738,3.11561 -2.6965,3.2755 -0.37605,0.0365 -0.75561,0.002 -1.1187,-0.10287" /> + d="m 446.5,108.5 c 0,1.65685 -1.34315,3 -3,3 -1.65685,0 -3,-1.34315 -3,-3 0,-1.65685 1.34315,-3 3,-3 1.65685,0 3,1.34315 3,3 z" /> + d="m 446.5,108.5 c 0,1.65685 -1.34315,3 -3,3 -1.65685,0 -3,-1.34315 -3,-3 0,-1.65685 1.34315,-3 3,-3 1.65685,0 3,1.34315 3,3 z" /> + d="m 446.5,108.5 c 0,1.65685 -1.34315,3 -3,3 -1.65685,0 -3,-1.34315 -3,-3 0,-1.65685 1.34315,-3 3,-3 1.65685,0 3,1.34315 3,3 z" /> + d="m 446.5,108.5 c 0,1.65685 -1.34315,3 -3,3 -1.65685,0 -3,-1.34315 -3,-3 0,-1.65685 1.34315,-3 3,-3 1.65685,0 3,1.34315 3,3 z" /> @@ -65125,7 +65159,7 @@ x="409" y="-41" /> + d="m 446.5,108.5 c 0,1.65685 -1.34315,3 -3,3 -1.65685,0 -3,-1.34315 -3,-3 0,-1.65685 1.34315,-3 3,-3 1.65685,0 3,1.34315 3,3 z" /> + d="m 446.5,108.5 c 0,1.65685 -1.34315,3 -3,3 -1.65685,0 -3,-1.34315 -3,-3 0,-1.65685 1.34315,-3 3,-3 1.65685,0 3,1.34315 3,3 z" /> + d="m 446.5,108.5 c 0,1.65685 -1.34315,3 -3,3 -1.65685,0 -3,-1.34315 -3,-3 0,-1.65685 1.34315,-3 3,-3 1.65685,0 3,1.34315 3,3 z" /> @@ -65304,7 +65338,7 @@ x="409" y="-41" /> + d="m 446.5,108.5 c 0,1.65685 -1.34315,3 -3,3 -1.65685,0 -3,-1.34315 -3,-3 0,-1.65685 1.34315,-3 3,-3 1.65685,0 3,1.34315 3,3 z" /> @@ -67890,7 +67924,7 @@ inkscape:export-ydpi="90" inkscape:export-xdpi="90" inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png" - d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z" + d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z" sodipodi:ry="8" sodipodi:rx="8" sodipodi:cy="118" @@ -67907,7 +67941,7 @@ sodipodi:cy="118" sodipodi:rx="8" sodipodi:ry="8" - d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z" + d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z" inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png" inkscape:export-xdpi="90" inkscape:export-ydpi="90" @@ -67916,7 +67950,7 @@ inkscape:export-ydpi="90" inkscape:export-xdpi="90" inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png" - d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z" + d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z" sodipodi:ry="8" sodipodi:rx="8" sodipodi:cy="118" @@ -68847,7 +68881,7 @@ inkscape:export-ydpi="90" transform="matrix(1.0004639,0,0,0.9963165,-69.122722,304.28985)"> @@ -70184,7 +70218,7 @@ inkscape:export-ydpi="90" inkscape:export-xdpi="90" inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png" - d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z" + d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z" sodipodi:ry="8" sodipodi:rx="8" sodipodi:cy="118" @@ -70212,7 +70246,7 @@ sodipodi:cy="118" sodipodi:rx="8" sodipodi:ry="8" - d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z" + d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z" inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png" inkscape:export-xdpi="90" inkscape:export-ydpi="90" @@ -70221,7 +70255,7 @@ inkscape:export-ydpi="90" inkscape:export-xdpi="90" inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png" - d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z" + d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z" sodipodi:ry="8" sodipodi:rx="8" sodipodi:cy="118" @@ -70700,11 +70734,11 @@ sodipodi:cy="-23" sodipodi:rx="1" sodipodi:ry="1" - d="m 134,-23 a 1,1 0 1 1 -2,0 1,1 0 1 1 2,0 z" + d="m 134,-23 c 0,0.552285 -0.44772,1 -1,1 -0.55228,0 -1,-0.447715 -1,-1 0,-0.552285 0.44772,-1 1,-1 0.55228,0 1,0.447715 1,1 z" transform="translate(0.5,-0.46875)" /> @@ -70980,7 +71014,7 @@ sodipodi:cy="118" sodipodi:rx="8" sodipodi:ry="8" - d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z" + d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z" inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png" inkscape:export-xdpi="90" inkscape:export-ydpi="90" /> @@ -70993,7 +71027,7 @@ sodipodi:cy="118" sodipodi:rx="8" sodipodi:ry="8" - d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z" + d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z" inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png" inkscape:export-xdpi="90" inkscape:export-ydpi="90" /> @@ -71722,7 +71756,7 @@ @@ -73712,7 +73746,7 @@ sodipodi:cy="502" sodipodi:rx="2.5312502" sodipodi:ry="2.5" - d="m 80.53125,502 a 2.5312502,2.5 0 1 1 -5.0625,0 2.5312502,2.5 0 1 1 5.0625,0 z" + d="m 80.53125,502 c 0,1.38071 -1.133279,2.5 -2.53125,2.5 -1.397971,0 -2.53125,-1.11929 -2.53125,-2.5 0,-1.38071 1.133279,-2.5 2.53125,-2.5 1.397971,0 2.53125,1.11929 2.53125,2.5 z" transform="matrix(0.9552133,0,0,0.9315985,-40.901258,-140.2522)" /> @@ -74368,9 +74402,9 @@ sodipodi:cy="79.5" sodipodi:rx="3.5" sodipodi:ry="3.5" - d="m 211,79.5 a 3.5,3.5 0 1 1 -7,0 3.5,3.5 0 1 1 7,0 z" /> + d="m 211,79.5 c 0,1.932997 -1.567,3.5 -3.5,3.5 -1.933,0 -3.5,-1.567003 -3.5,-3.5 0,-1.932997 1.567,-3.5 3.5,-3.5 1.933,0 3.5,1.567003 3.5,3.5 z" /> @@ -74928,7 +74962,7 @@ inkscape:export-ydpi="90" inkscape:export-xdpi="90" inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png" - d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z" + d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z" sodipodi:ry="8" sodipodi:rx="8" sodipodi:cy="118" @@ -76095,13 +76129,13 @@ sodipodi:cy="554" sodipodi:rx="4.5" sodipodi:ry="2.25" - d="m 57.5,554 a 4.5,2.25 0 1 1 -9,0 4.5,2.25 0 1 1 9,0 z" + d="m 57.5,554 c 0,1.24264 -2.014719,2.25 -4.5,2.25 -2.485281,0 -4.5,-1.00736 -4.5,-2.25 0,-1.24264 2.014719,-2.25 4.5,-2.25 2.485281,0 4.5,1.00736 4.5,2.25 z" transform="matrix(0.7630859,-0.2494396,0.2996015,0.9926766,-151.92281,17.77746)" /> + transform="translate(104.91639,-82)"> + d="m 434.99991,14.5 c 0,1.609518 -1.79082,2.91429 -3.99991,2.91429 -2.20909,0 -3.99991,-1.304772 -3.99991,-2.91429 0,-1.609518 1.79082,-2.91429 3.99991,-2.91429 2.20909,0 3.99991,1.304772 3.99991,2.91429 z" /> + d="m 65,135 c 0,0.55228 -0.447715,1 -1,1 -0.552285,0 -1,-0.44772 -1,-1 0,-0.55228 0.447715,-1 1,-1 0.552285,0 1,0.44772 1,1 z" /> + d="m 65,135 c 0,0.55228 -0.447715,1 -1,1 -0.552285,0 -1,-0.44772 -1,-1 0,-0.55228 0.447715,-1 1,-1 0.552285,0 1,0.44772 1,1 z" /> @@ -77496,7 +77530,7 @@ id="g28085"> @@ -78040,7 +78074,7 @@ inkscape:connector-curvature="0" /> + d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z" /> @@ -79745,7 +79779,7 @@ inkscape:export-ydpi="90" inkscape:export-xdpi="90" inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png" - d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z" + d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z" sodipodi:ry="8" sodipodi:rx="8" sodipodi:cy="118" @@ -79762,7 +79796,7 @@ sodipodi:cy="118" sodipodi:rx="8" sodipodi:ry="8" - d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z" + d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z" inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png" inkscape:export-xdpi="90" inkscape:export-ydpi="90" @@ -79776,7 +79810,7 @@ sodipodi:cy="118" sodipodi:rx="8" sodipodi:ry="8" - d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z" + d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z" inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png" inkscape:export-xdpi="90" inkscape:export-ydpi="90" /> @@ -79987,13 +80021,13 @@ sodipodi:cy="78.5" sodipodi:rx="3.5" sodipodi:ry="3.5" - d="m 262,78.5 a 3.5,3.5 0 1 1 -7,0 3.5,3.5 0 1 1 7,0 z" + d="m 262,78.5 c 0,1.932997 -1.567,3.5 -3.5,3.5 -1.933,0 -3.5,-1.567003 -3.5,-3.5 0,-1.932997 1.567,-3.5 3.5,-3.5 1.933,0 3.5,1.567003 3.5,3.5 z" transform="matrix(-1.14287,0,0,1.142863,463.9317,115.80133)" /> + d="m 65,135 c 0,0.55228 -0.447715,1 -1,1 -0.552285,0 -1,-0.44772 -1,-1 0,-0.55228 0.447715,-1 1,-1 0.552285,0 1,0.44772 1,1 z" /> @@ -80298,7 +80332,7 @@ sodipodi:cy="78.5" sodipodi:rx="3.5" sodipodi:ry="3.5" - d="m 262,78.5 a 3.5,3.5 0 1 1 -7,0 3.5,3.5 0 1 1 7,0 z" + d="m 262,78.5 c 0,1.932997 -1.567,3.5 -3.5,3.5 -1.933,0 -3.5,-1.567003 -3.5,-3.5 0,-1.932997 1.567,-3.5 3.5,-3.5 1.933,0 3.5,1.567003 3.5,3.5 z" transform="matrix(-1.5000024,0,0,1.4990511,528.75064,424.32781)" inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png" inkscape:export-xdpi="90" @@ -80332,7 +80366,7 @@ sodipodi:cy="78.5" sodipodi:rx="3.5" sodipodi:ry="3.5" - d="m 262,78.5 a 3.5,3.5 0 1 1 -7,0 3.5,3.5 0 1 1 7,0 z" + d="m 262,78.5 c 0,1.932997 -1.567,3.5 -3.5,3.5 -1.933,0 -3.5,-1.567003 -3.5,-3.5 0,-1.932997 1.567,-3.5 3.5,-3.5 1.933,0 3.5,1.567003 3.5,3.5 z" transform="matrix(-1.5714299,0,0,1.5714268,505.21462,331.643)" inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png" inkscape:export-xdpi="90" @@ -80371,13 +80405,13 @@ sodipodi:cy="78.5" sodipodi:rx="3.5" sodipodi:ry="3.5" - d="m 262,78.5 a 3.5,3.5 0 1 1 -7,0 3.5,3.5 0 1 1 7,0 z" + d="m 262,78.5 c 0,1.932997 -1.567,3.5 -3.5,3.5 -1.933,0 -3.5,-1.567003 -3.5,-3.5 0,-1.932997 1.567,-3.5 3.5,-3.5 1.933,0 3.5,1.567003 3.5,3.5 z" transform="matrix(-1.14287,0,0,1.142863,463.9317,115.7853)" /> @@ -80572,7 +80606,7 @@ inkscape:export-ydpi="90" inkscape:export-xdpi="90" inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png" - d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z" + d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z" sodipodi:ry="8" sodipodi:rx="8" sodipodi:cy="118" @@ -80584,7 +80618,7 @@ inkscape:export-ydpi="90" inkscape:export-xdpi="90" inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png" - d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z" + d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z" sodipodi:ry="8" sodipodi:rx="8" sodipodi:cy="118" @@ -80628,7 +80662,7 @@ sodipodi:cy="78.5" sodipodi:rx="3.5" sodipodi:ry="3.5" - d="m 262,78.5 a 3.5,3.5 0 1 1 -7,0 3.5,3.5 0 1 1 7,0 z" + d="m 262,78.5 c 0,1.932997 -1.567,3.5 -3.5,3.5 -1.933,0 -3.5,-1.567003 -3.5,-3.5 0,-1.932997 1.567,-3.5 3.5,-3.5 1.933,0 3.5,1.567003 3.5,3.5 z" transform="matrix(-1.5714299,0,0,1.5714268,505.21462,331.643)" inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png" inkscape:export-xdpi="90" @@ -80667,13 +80701,13 @@ sodipodi:cy="78.5" sodipodi:rx="3.5" sodipodi:ry="3.5" - d="m 262,78.5 a 3.5,3.5 0 1 1 -7,0 3.5,3.5 0 1 1 7,0 z" + d="m 262,78.5 c 0,1.932997 -1.567,3.5 -3.5,3.5 -1.933,0 -3.5,-1.567003 -3.5,-3.5 0,-1.932997 1.567,-3.5 3.5,-3.5 1.933,0 3.5,1.567003 3.5,3.5 z" transform="matrix(-1.14287,0,0,1.142863,463.9317,115.7853)" /> @@ -80967,7 +81001,7 @@ style="display:inline"> @@ -81215,7 +81249,7 @@ inkscape:export-ydpi="90" inkscape:export-xdpi="90" inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png" - d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z" + d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z" sodipodi:ry="8" sodipodi:rx="8" sodipodi:cy="118" @@ -81234,7 +81268,7 @@ inkscape:export-ydpi="90" inkscape:export-xdpi="90" inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png" - d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z" + d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z" sodipodi:ry="8" sodipodi:rx="8" sodipodi:cy="118" @@ -81252,7 +81286,7 @@ sodipodi:cy="118" sodipodi:rx="8" sodipodi:ry="8" - d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z" + d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z" inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png" inkscape:export-xdpi="90" inkscape:export-ydpi="90" /> @@ -81977,7 +82011,7 @@ id="g36930"> + d="m 266.5,330.5 c 0,1.10457 -0.89543,2 -2,2 -1.10457,0 -2,-0.89543 -2,-2 0,-1.10457 0.89543,-2 2,-2 1.10457,0 2,0.89543 2,2 z" /> + d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z" /> @@ -83127,7 +83161,7 @@ sodipodi:cy="118" sodipodi:rx="8" sodipodi:ry="8" - d="m 132,110 a 8,8 0 0 1 6.9282,4 L 132,118 z" + d="m 132,110 c 2.85812,0 5.49914,1.52479 6.9282,4 L 132,118 z" inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png" inkscape:export-xdpi="90" inkscape:export-ydpi="90" @@ -83143,7 +83177,7 @@ inkscape:export-ydpi="90" inkscape:export-xdpi="90" inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png" - d="m 132,110 a 8,8 0 0 1 6.9282,4 L 132,118 z" + d="m 132,110 c 2.85812,0 5.49914,1.52479 6.9282,4 L 132,118 z" sodipodi:ry="8" sodipodi:rx="8" sodipodi:cy="118" @@ -83161,7 +83195,7 @@ sodipodi:cy="118" sodipodi:rx="8" sodipodi:ry="8" - d="m 132,110 a 8,8 0 0 1 6.9282,4 L 132,118 z" + d="m 132,110 c 2.85812,0 5.49914,1.52479 6.9282,4 L 132,118 z" inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png" inkscape:export-xdpi="90" inkscape:export-ydpi="90" @@ -83177,7 +83211,7 @@ inkscape:export-ydpi="90" inkscape:export-xdpi="90" inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png" - d="m 132,110 a 8,8 0 0 1 6.9282,4 L 132,118 z" + d="m 132,110 c 2.85812,0 5.49914,1.52479 6.9282,4 L 132,118 z" sodipodi:ry="8" sodipodi:rx="8" sodipodi:cy="118" @@ -83195,7 +83229,7 @@ sodipodi:cy="118" sodipodi:rx="8" sodipodi:ry="8" - d="m 132,110 a 8,8 0 0 1 6.9282,4 L 132,118 z" + d="m 132,110 c 2.85812,0 5.49914,1.52479 6.9282,4 L 132,118 z" inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png" inkscape:export-xdpi="90" inkscape:export-ydpi="90" @@ -83209,7 +83243,7 @@ inkscape:export-ydpi="90" inkscape:export-xdpi="90" inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png" - d="m 132,110 a 8,8 0 0 1 6.9282,4 L 132,118 z" + d="m 132,110 c 2.85812,0 5.49914,1.52479 6.9282,4 L 132,118 z" sodipodi:ry="8" sodipodi:rx="8" sodipodi:cy="118" @@ -83224,7 +83258,7 @@ inkscape:export-ydpi="90" inkscape:export-xdpi="90" inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png" - d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z" + d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z" sodipodi:ry="8" sodipodi:rx="8" sodipodi:cy="118" @@ -83242,7 +83276,7 @@ sodipodi:cy="118" sodipodi:rx="8" sodipodi:ry="8" - d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z" + d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z" inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png" inkscape:export-xdpi="90" inkscape:export-ydpi="90" /> @@ -83365,7 +83399,7 @@ sodipodi:cy="118" sodipodi:rx="8" sodipodi:ry="8" - d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z" + d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z" inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png" inkscape:export-xdpi="90" inkscape:export-ydpi="90" /> @@ -83374,7 +83408,7 @@ inkscape:export-ydpi="90" inkscape:export-xdpi="90" inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png" - d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z" + d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z" sodipodi:ry="8" sodipodi:rx="8" sodipodi:cy="118" @@ -83391,7 +83425,7 @@ inkscape:export-ydpi="90" inkscape:export-xdpi="90" inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png" - d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z" + d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z" sodipodi:ry="8" sodipodi:rx="8" sodipodi:cy="118" @@ -83513,7 +83547,7 @@ style="fill:#f9f9f9;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.69999999;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" /> @@ -83855,7 +83889,7 @@ inkscape:export-ydpi="90" inkscape:export-xdpi="90" inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png" - d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z" + d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z" sodipodi:ry="8" sodipodi:rx="8" sodipodi:cy="118" @@ -83950,7 +83984,7 @@ sodipodi:cy="40.5" sodipodi:rx="6.5" sodipodi:ry="2.5" - d="m -213.5,40.5 a 6.5,2.5 0 1 1 -13,0 6.5,2.5 0 1 1 13,0 z" + d="m -213.5,40.5 c 0,1.380712 -2.91015,2.5 -6.5,2.5 -3.58985,0 -6.5,-1.119288 -6.5,-2.5 0,-1.380712 2.91015,-2.5 6.5,-2.5 3.58985,0 6.5,1.119288 6.5,2.5 z" transform="matrix(0.9999986,0,0,1.799999,-2.971883e-4,111.10004)" /> @@ -84368,7 +84402,7 @@ inkscape:export-ydpi="90" inkscape:export-xdpi="90" inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png" - d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z" + d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z" sodipodi:ry="8" sodipodi:rx="8" sodipodi:cy="118" @@ -84449,7 +84483,7 @@ inkscape:export-ydpi="90" inkscape:export-xdpi="90" inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png" - d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z" + d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z" sodipodi:ry="8" sodipodi:rx="8" sodipodi:cy="118" @@ -84466,7 +84500,7 @@ sodipodi:cy="118" sodipodi:rx="8" sodipodi:ry="8" - d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z" + d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z" inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png" inkscape:export-xdpi="90" inkscape:export-ydpi="90" @@ -84480,7 +84514,7 @@ sodipodi:cy="118" sodipodi:rx="8" sodipodi:ry="8" - d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z" + d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z" inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png" inkscape:export-xdpi="90" inkscape:export-ydpi="90" /> @@ -84488,7 +84522,7 @@ inkscape:export-ydpi="90" inkscape:export-xdpi="90" inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png" - d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z" + d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z" sodipodi:ry="8" sodipodi:rx="8" sodipodi:cy="118" @@ -84574,7 +84608,7 @@ sodipodi:cy="118" sodipodi:rx="8" sodipodi:ry="8" - d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z" + d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z" inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png" inkscape:export-xdpi="90" inkscape:export-ydpi="90" /> @@ -84582,7 +84616,7 @@ inkscape:export-ydpi="90" inkscape:export-xdpi="90" inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png" - d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z" + d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z" sodipodi:ry="8" sodipodi:rx="8" sodipodi:cy="118" @@ -85161,7 +85195,7 @@ inkscape:connector-curvature="0" /> @@ -85408,7 +85442,7 @@ sodipodi:cy="118" sodipodi:rx="8" sodipodi:ry="8" - d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z" + d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z" inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png" inkscape:export-xdpi="90" inkscape:export-ydpi="90" /> @@ -85416,7 +85450,7 @@ inkscape:export-ydpi="90" inkscape:export-xdpi="90" inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png" - d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z" + d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z" sodipodi:ry="8" sodipodi:rx="8" sodipodi:cy="118" @@ -85434,7 +85468,7 @@ sodipodi:cy="118" sodipodi:rx="8" sodipodi:ry="8" - d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z" + d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z" inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png" inkscape:export-xdpi="90" inkscape:export-ydpi="90" /> @@ -85447,7 +85481,7 @@ sodipodi:cy="118" sodipodi:rx="8" sodipodi:ry="8" - d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z" + d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z" inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png" inkscape:export-xdpi="90" inkscape:export-ydpi="90" /> @@ -85507,7 +85541,7 @@ inkscape:export-ydpi="90" inkscape:export-xdpi="90" inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png" - d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z" + d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z" sodipodi:ry="8" sodipodi:rx="8" sodipodi:cy="118" @@ -85525,7 +85559,7 @@ sodipodi:cy="118" sodipodi:rx="8" sodipodi:ry="8" - d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z" + d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z" inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png" inkscape:export-xdpi="90" inkscape:export-ydpi="90" /> @@ -85533,7 +85567,7 @@ inkscape:export-ydpi="90" inkscape:export-xdpi="90" inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png" - d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z" + d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z" sodipodi:ry="8" sodipodi:rx="8" sodipodi:cy="118" @@ -85546,7 +85580,7 @@ inkscape:export-ydpi="90" inkscape:export-xdpi="90" inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png" - d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z" + d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z" sodipodi:ry="8" sodipodi:rx="8" sodipodi:cy="118" @@ -85613,7 +85647,7 @@ sodipodi:cy="118" sodipodi:rx="8" sodipodi:ry="8" - d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z" + d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z" inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png" inkscape:export-xdpi="90" inkscape:export-ydpi="90" /> @@ -85621,7 +85655,7 @@ inkscape:export-ydpi="90" inkscape:export-xdpi="90" inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png" - d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z" + d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z" sodipodi:ry="8" sodipodi:rx="8" sodipodi:cy="118" @@ -85639,7 +85673,7 @@ sodipodi:cy="118" sodipodi:rx="8" sodipodi:ry="8" - d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z" + d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z" inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png" inkscape:export-xdpi="90" inkscape:export-ydpi="90" /> @@ -85652,7 +85686,7 @@ sodipodi:cy="118" sodipodi:rx="8" sodipodi:ry="8" - d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z" + d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z" inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png" inkscape:export-xdpi="90" inkscape:export-ydpi="90" /> @@ -85704,7 +85738,7 @@ sodipodi:cy="118" sodipodi:rx="8" sodipodi:ry="8" - d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z" + d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z" inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png" inkscape:export-xdpi="90" inkscape:export-ydpi="90" /> @@ -85712,7 +85746,7 @@ inkscape:export-ydpi="90" inkscape:export-xdpi="90" inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png" - d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z" + d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z" sodipodi:ry="8" sodipodi:rx="8" sodipodi:cy="118" @@ -85730,7 +85764,7 @@ sodipodi:cy="118" sodipodi:rx="8" sodipodi:ry="8" - d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z" + d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z" inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png" inkscape:export-xdpi="90" inkscape:export-ydpi="90" /> @@ -85743,7 +85777,7 @@ sodipodi:cy="118" sodipodi:rx="8" sodipodi:ry="8" - d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z" + d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z" inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png" inkscape:export-xdpi="90" inkscape:export-ydpi="90" /> @@ -85760,7 +85794,7 @@ inkscape:export-ydpi="90" inkscape:export-xdpi="90" inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png" - d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z" + d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z" sodipodi:ry="8" sodipodi:rx="8" sodipodi:cy="118" @@ -85777,7 +85811,7 @@ sodipodi:cy="118" sodipodi:rx="8" sodipodi:ry="8" - d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z" + d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z" inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png" inkscape:export-xdpi="90" inkscape:export-ydpi="90" @@ -85791,7 +85825,7 @@ sodipodi:cy="118" sodipodi:rx="8" sodipodi:ry="8" - d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z" + d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z" inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png" inkscape:export-xdpi="90" inkscape:export-ydpi="90" /> @@ -85814,7 +85848,7 @@ sodipodi:cy="118" sodipodi:rx="8" sodipodi:ry="8" - d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z" + d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z" inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png" inkscape:export-xdpi="90" inkscape:export-ydpi="90" /> @@ -85822,7 +85856,7 @@ inkscape:export-ydpi="90" inkscape:export-xdpi="90" inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png" - d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z" + d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z" sodipodi:ry="8" sodipodi:rx="8" sodipodi:cy="118" @@ -85840,7 +85874,7 @@ sodipodi:cy="118" sodipodi:rx="8" sodipodi:ry="8" - d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z" + d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z" inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png" inkscape:export-xdpi="90" inkscape:export-ydpi="90" /> @@ -85853,7 +85887,7 @@ sodipodi:cy="118" sodipodi:rx="8" sodipodi:ry="8" - d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z" + d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z" inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png" inkscape:export-xdpi="90" inkscape:export-ydpi="90" /> @@ -86221,7 +86255,7 @@ sodipodi:cy="118" sodipodi:rx="8" sodipodi:ry="8" - d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z" + d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z" inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png" inkscape:export-xdpi="90" inkscape:export-ydpi="90" /> @@ -86229,7 +86263,7 @@ inkscape:export-ydpi="90" inkscape:export-xdpi="90" inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png" - d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z" + d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z" sodipodi:ry="8" sodipodi:rx="8" sodipodi:cy="118" @@ -86247,7 +86281,7 @@ sodipodi:cy="118" sodipodi:rx="8" sodipodi:ry="8" - d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z" + d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z" inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png" inkscape:export-xdpi="90" inkscape:export-ydpi="90" /> @@ -86295,7 +86329,7 @@ inkscape:export-ydpi="90" inkscape:export-xdpi="90" inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png" - d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z" + d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z" sodipodi:ry="8" sodipodi:rx="8" sodipodi:cy="118" @@ -86313,7 +86347,7 @@ sodipodi:cy="118" sodipodi:rx="8" sodipodi:ry="8" - d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z" + d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z" inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png" inkscape:export-xdpi="90" inkscape:export-ydpi="90" /> @@ -86321,7 +86355,7 @@ inkscape:export-ydpi="90" inkscape:export-xdpi="90" inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png" - d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z" + d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z" sodipodi:ry="8" sodipodi:rx="8" sodipodi:cy="118" @@ -86343,7 +86377,7 @@ sodipodi:cy="292.5" sodipodi:rx="4" sodipodi:ry="4" - d="m 223.5,292.5 a 4,4 0 1 1 -8,0 4,4 0 1 1 8,0 z" + d="m 223.5,292.5 c 0,2.20914 -1.79086,4 -4,4 -2.20914,0 -4,-1.79086 -4,-4 0,-2.20914 1.79086,-4 4,-4 2.20914,0 4,1.79086 4,4 z" transform="translate(20,0)" /> @@ -86422,7 +86456,7 @@ inkscape:export-ydpi="90" inkscape:export-xdpi="90" inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png" - d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z" + d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z" sodipodi:ry="8" sodipodi:rx="8" sodipodi:cy="118" @@ -86480,7 +86514,7 @@ sodipodi:cy="118" sodipodi:rx="8" sodipodi:ry="8" - d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z" + d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z" inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png" inkscape:export-xdpi="90" inkscape:export-ydpi="90" /> @@ -86488,7 +86522,7 @@ inkscape:export-ydpi="90" inkscape:export-xdpi="90" inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png" - d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z" + d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z" sodipodi:ry="8" sodipodi:rx="8" sodipodi:cy="118" @@ -86506,7 +86540,7 @@ sodipodi:cy="118" sodipodi:rx="8" sodipodi:ry="8" - d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z" + d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z" inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png" inkscape:export-xdpi="90" inkscape:export-ydpi="90" /> @@ -86517,7 +86551,7 @@ style="opacity:0.9;display:inline;enable-background:new"> @@ -86577,11 +86611,11 @@ sodipodi:cy="192.5" sodipodi:rx="1.75" sodipodi:ry="1.75" - d="m 466.25,192.5 a 1.75,1.75 0 1 1 -3.5,0 1.75,1.75 0 1 1 3.5,0 z" + d="m 466.25,192.5 c 0,0.9665 -0.7835,1.75 -1.75,1.75 -0.9665,0 -1.75,-0.7835 -1.75,-1.75 0,-0.9665 0.7835,-1.75 1.75,-1.75 0.9665,0 1.75,0.7835 1.75,1.75 z" transform="matrix(1.7142856,0,0,1.7142871,-330.83199,-136.46043)" /> @@ -86652,7 +86686,7 @@ sodipodi:cy="118" sodipodi:rx="8" sodipodi:ry="8" - d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z" + d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z" inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png" inkscape:export-xdpi="90" inkscape:export-ydpi="90" /> @@ -86660,7 +86694,7 @@ inkscape:export-ydpi="90" inkscape:export-xdpi="90" inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png" - d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z" + d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z" sodipodi:ry="8" sodipodi:rx="8" sodipodi:cy="118" @@ -86700,7 +86734,7 @@ sodipodi:cy="118" sodipodi:rx="8" sodipodi:ry="8" - d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z" + d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z" inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png" inkscape:export-xdpi="90" inkscape:export-ydpi="90" /> @@ -86709,7 +86743,7 @@ inkscape:export-ydpi="90" inkscape:export-xdpi="90" inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png" - d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z" + d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z" sodipodi:ry="8" sodipodi:rx="8" sodipodi:cy="118" @@ -86721,7 +86755,7 @@ inkscape:export-ydpi="90" inkscape:export-xdpi="90" inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png" - d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z" + d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z" sodipodi:ry="8" sodipodi:rx="8" sodipodi:cy="118" @@ -86914,7 +86948,7 @@ sodipodi:cy="14.5" sodipodi:rx="1.5" sodipodi:ry="1.5" - d="m 72,14.5 a 1.5,1.5 0 1 1 -3,0 1.5,1.5 0 1 1 3,0 z" + d="M 72,14.5 C 72,15.328427 71.328427,16 70.5,16 69.671573,16 69,15.328427 69,14.5 69,13.671573 69.671573,13 70.5,13 c 0.828427,0 1.5,0.671573 1.5,1.5 z" transform="matrix(1.3333333,0,0,1.3333343,3,147.66665)" inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png" inkscape:export-xdpi="90" @@ -86928,7 +86962,7 @@ sodipodi:cy="14.5" sodipodi:rx="1.5" sodipodi:ry="1.5" - d="m 72,14.5 a 1.5,1.5 0 1 1 -3,0 1.5,1.5 0 1 1 3,0 z" + d="M 72,14.5 C 72,15.328427 71.328427,16 70.5,16 69.671573,16 69,15.328427 69,14.5 69,13.671573 69.671573,13 70.5,13 c 0.828427,0 1.5,0.671573 1.5,1.5 z" inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png" inkscape:export-xdpi="90" inkscape:export-ydpi="90" /> @@ -87021,7 +87055,7 @@ sodipodi:end="6.2810509" sodipodi:start="0" transform="matrix(1.2491741,-1.2491602,0.7680871,0.768079,-75.108556,239.34027)" - d="m 182.21113,35 a 1.2111344,4.9951267 0 1 1 0,-0.01066" + d="m 182.21113,35 c 0,2.758732 -0.54224,4.995127 -1.21113,4.995127 -0.66889,0 -1.21113,-2.236395 -1.21113,-4.995127 0,-2.758732 0.54224,-4.995127 1.21113,-4.995127 0.66788,0 1.20971,2.229902 1.21113,4.984465" sodipodi:ry="4.9951267" sodipodi:rx="1.2111344" sodipodi:cy="35" @@ -87037,7 +87071,7 @@ sodipodi:cy="35" sodipodi:rx="1.1763829" sodipodi:ry="5.5293522" - d="m 182.17638,35 a 1.1763829,5.5293522 0 1 1 -2.35276,0 1.1763829,5.5293522 0 1 1 2.35276,0 z" + d="m 182.17638,35 c 0,3.053777 -0.52668,5.529352 -1.17638,5.529352 -0.6497,0 -1.17638,-2.475575 -1.17638,-5.529352 0,-3.053777 0.52668,-5.529352 1.17638,-5.529352 0.6497,0 1.17638,2.475575 1.17638,5.529352 z" transform="matrix(0.9589476,-0.9192618,0.5776079,0.5780619,-15.42366,185.77921)" /> @@ -87448,7 +87482,7 @@ id="g35449"> @@ -88463,7 +88497,7 @@ inkscape:export-ydpi="90" inkscape:export-xdpi="90" inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png" - d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z" + d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z" sodipodi:ry="8" sodipodi:rx="8" sodipodi:cy="118" @@ -88622,7 +88656,7 @@ sodipodi:cy="118" sodipodi:rx="8" sodipodi:ry="8" - d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z" + d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z" inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png" inkscape:export-xdpi="90" inkscape:export-ydpi="90" @@ -88635,7 +88669,7 @@ sodipodi:cy="118" sodipodi:rx="8" sodipodi:ry="8" - d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z" + d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z" inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png" inkscape:export-xdpi="90" inkscape:export-ydpi="90" @@ -88683,7 +88717,7 @@ inkscape:export-ydpi="90" inkscape:export-xdpi="90" inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png" - d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z" + d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z" sodipodi:ry="8" sodipodi:rx="8" sodipodi:cy="118" @@ -88703,9 +88737,9 @@ sodipodi:cy="118" sodipodi:rx="8" sodipodi:ry="8" - d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z" /> + d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z" /> @@ -88755,7 +88789,7 @@ sodipodi:cy="118" sodipodi:rx="8" sodipodi:ry="8" - d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z" /> + d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z" /> @@ -89477,7 +89511,7 @@ inkscape:export-ydpi="90" inkscape:export-xdpi="90" inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png" - d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z" + d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z" sodipodi:ry="8" sodipodi:rx="8" sodipodi:cy="118" @@ -89527,7 +89561,7 @@ inkscape:export-ydpi="90" inkscape:export-xdpi="90" inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png" - d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z" + d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z" sodipodi:ry="8" sodipodi:rx="8" sodipodi:cy="118" @@ -89559,7 +89593,7 @@ sodipodi:cy="118" sodipodi:rx="8" sodipodi:ry="8" - d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z" + d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z" inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png" inkscape:export-xdpi="90" inkscape:export-ydpi="90" /> @@ -89909,7 +89943,7 @@ sodipodi:cy="118" sodipodi:rx="8" sodipodi:ry="8" - d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z" + d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z" inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png" inkscape:export-xdpi="90" inkscape:export-ydpi="90" /> @@ -89929,7 +89963,7 @@ inkscape:export-ydpi="90" inkscape:export-xdpi="90" inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png" - d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z" + d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z" sodipodi:ry="8" sodipodi:rx="8" sodipodi:cy="118" @@ -89942,7 +89976,7 @@ inkscape:export-ydpi="90" inkscape:export-xdpi="90" inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png" - d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z" + d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z" sodipodi:ry="8" sodipodi:rx="8" sodipodi:cy="118" @@ -89956,7 +89990,7 @@ id="g36537"> @@ -90350,7 +90384,7 @@ sodipodi:cy="118" sodipodi:rx="8" sodipodi:ry="8" - d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z" + d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z" inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png" inkscape:export-xdpi="90" inkscape:export-ydpi="90" /> @@ -90358,7 +90392,7 @@ inkscape:export-ydpi="90" inkscape:export-xdpi="90" inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png" - d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z" + d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z" sodipodi:ry="8" sodipodi:rx="8" sodipodi:cy="118" @@ -92333,7 +92367,7 @@ @@ -92371,7 +92405,7 @@ inkscape:export-ydpi="90" inkscape:export-xdpi="90" inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png" - d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z" + d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z" sodipodi:ry="8" sodipodi:rx="8" sodipodi:cy="118" @@ -92501,7 +92535,7 @@ inkscape:export-ydpi="90" inkscape:export-xdpi="90" inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png" - d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z" + d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z" sodipodi:ry="8" sodipodi:rx="8" sodipodi:cy="118" @@ -92518,14 +92552,14 @@ sodipodi:cy="118" sodipodi:rx="8" sodipodi:ry="8" - d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z" + d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z" inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png" inkscape:export-xdpi="90" inkscape:export-ydpi="90" transform="matrix(-0.683022,-0.07745026,0.0778507,-0.683064,209.4726,314.325)" /> + d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z" /> @@ -93936,7 +93970,7 @@ inkscape:export-ydpi="90" inkscape:export-xdpi="90" inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png" - d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z" + d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z" sodipodi:ry="8" sodipodi:rx="8" sodipodi:cy="118" @@ -94004,7 +94038,7 @@ sodipodi:cy="118" sodipodi:rx="8" sodipodi:ry="8" - d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z" + d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z" inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png" inkscape:export-xdpi="90" inkscape:export-ydpi="90" /> @@ -94020,7 +94054,7 @@ inkscape:export-ydpi="90" inkscape:export-xdpi="90" inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png" - d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z" + d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z" sodipodi:ry="8" sodipodi:rx="8" sodipodi:cy="118" @@ -94715,13 +94749,13 @@ sodipodi:cy="118" sodipodi:rx="8" sodipodi:ry="8" - d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z" + d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z" inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png" inkscape:export-xdpi="90" inkscape:export-ydpi="90" transform="matrix(0.787566,0,0,0.779223,26.709197,21.3179)" /> + d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z" /> @@ -96482,7 +96516,7 @@ inkscape:export-ydpi="90" inkscape:export-xdpi="90" inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png" - d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z" + d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z" sodipodi:ry="8" sodipodi:rx="8" sodipodi:cy="118" @@ -96494,7 +96528,7 @@ inkscape:export-ydpi="90" inkscape:export-xdpi="90" inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png" - d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z" + d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z" sodipodi:ry="8" sodipodi:rx="8" sodipodi:cy="118" @@ -97822,7 +97856,7 @@ sodipodi:cy="118" sodipodi:rx="8" sodipodi:ry="8" - d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z" + d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z" inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png" inkscape:export-xdpi="90" inkscape:export-ydpi="90" /> @@ -97831,7 +97865,7 @@ inkscape:export-ydpi="90" inkscape:export-xdpi="90" inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png" - d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z" + d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z" sodipodi:ry="8" sodipodi:rx="8" sodipodi:cy="118" @@ -97850,7 +97884,7 @@ sodipodi:cy="118" sodipodi:rx="8" sodipodi:ry="8" - d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z" + d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z" transform="matrix(0.5705005,0,0,0.5705012,51.746079,156.18087)" /> @@ -97958,7 +97992,7 @@ sodipodi:cy="118" sodipodi:rx="8" sodipodi:ry="8" - d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z" + d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z" inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png" inkscape:export-xdpi="90" inkscape:export-ydpi="90" /> @@ -97966,7 +98000,7 @@ inkscape:export-ydpi="90" inkscape:export-xdpi="90" inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png" - d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z" + d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z" sodipodi:ry="8" sodipodi:rx="8" sodipodi:cy="118" @@ -97979,7 +98013,7 @@ inkscape:export-ydpi="90" inkscape:export-xdpi="90" inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png" - d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z" + d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z" sodipodi:ry="8" sodipodi:rx="8" sodipodi:cy="118" @@ -98200,7 +98234,7 @@ sodipodi:end="1.5729572" sodipodi:start="0" transform="matrix(-2.421633,0,0,-2.417581,92.2682,-69.13182)" - d="m 54,-32.5 a 4.5,4.5 0 0 1 -4.509724,4.499989" + d="m 54,-32.5 c 0,2.485281 -2.014719,4.5 -4.5,4.5 -0.0032,0 -0.0065,-4e-6 -0.0097,-1.1e-5" sodipodi:ry="4.5" sodipodi:rx="4.5" sodipodi:cy="-32.5" @@ -98219,7 +98253,7 @@ sodipodi:cy="-32.5" sodipodi:rx="4.5" sodipodi:ry="4.5" - d="m 54,-32.5 a 4.5,4.5 0 0 1 -4.509724,4.499989" + d="m 54,-32.5 c 0,2.485281 -2.014719,4.5 -4.5,4.5 -0.0032,0 -0.0065,-4e-6 -0.0097,-1.1e-5" transform="matrix(-2.421633,0,0,-2.417581,92.2682,-69.13182)" sodipodi:start="0" sodipodi:end="1.5729572" @@ -98236,7 +98270,7 @@ sodipodi:end="1.5729572" sodipodi:start="0" transform="matrix(-2.421633,0,0,-2.417581,92.2682,-69.13182)" - d="m 54,-32.5 a 4.5,4.5 0 0 1 -4.509724,4.499989" + d="m 54,-32.5 c 0,2.485281 -2.014719,4.5 -4.5,4.5 -0.0032,0 -0.0065,-4e-6 -0.0097,-1.1e-5" sodipodi:ry="4.5" sodipodi:rx="4.5" sodipodi:cy="-32.5" @@ -98255,7 +98289,7 @@ sodipodi:cy="-32.5" sodipodi:rx="4.5" sodipodi:ry="4.5" - d="m 54,-32.5 a 4.5,4.5 0 0 1 -4.509724,4.499989" + d="m 54,-32.5 c 0,2.485281 -2.014719,4.5 -4.5,4.5 -0.0032,0 -0.0065,-4e-6 -0.0097,-1.1e-5" transform="matrix(-2.587958,0,0,-2.597682,100.48861,-75.018268)" sodipodi:start="0" sodipodi:end="1.5729572" @@ -98828,7 +98862,7 @@ inkscape:export-ydpi="90" inkscape:export-xdpi="90" inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png" - d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z" + d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z" sodipodi:ry="8" sodipodi:rx="8" sodipodi:cy="118" @@ -98842,7 +98876,7 @@ inkscape:export-ydpi="90" inkscape:export-xdpi="90" inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png" - d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z" + d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z" sodipodi:ry="8" sodipodi:rx="8" sodipodi:cy="118" @@ -98932,7 +98966,7 @@ sodipodi:cy="118" sodipodi:rx="8" sodipodi:ry="8" - d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z" + d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z" inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png" inkscape:export-xdpi="90" inkscape:export-ydpi="90" /> @@ -98968,7 +99002,7 @@ inkscape:export-ydpi="90" inkscape:export-xdpi="90" inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png" - d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z" + d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z" sodipodi:ry="8" sodipodi:rx="8" sodipodi:cy="118" @@ -98994,7 +99028,7 @@ sodipodi:cy="118" sodipodi:rx="8" sodipodi:ry="8" - d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z" + d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z" inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png" inkscape:export-xdpi="90" inkscape:export-ydpi="90" /> @@ -99174,7 +99208,7 @@ @@ -99735,7 +99769,7 @@ inkscape:export-ydpi="90" inkscape:export-xdpi="90" inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png" - d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z" + d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z" sodipodi:ry="8" sodipodi:rx="8" sodipodi:cy="118" @@ -99753,7 +99787,7 @@ sodipodi:cy="118" sodipodi:rx="8" sodipodi:ry="8" - d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z" + d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z" inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png" inkscape:export-xdpi="90" inkscape:export-ydpi="90" /> @@ -99766,7 +99800,7 @@ sodipodi:cy="118" sodipodi:rx="8" sodipodi:ry="8" - d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z" + d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z" inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png" inkscape:export-xdpi="90" inkscape:export-ydpi="90" /> @@ -99774,7 +99808,7 @@ inkscape:export-ydpi="90" inkscape:export-xdpi="90" inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png" - d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z" + d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z" sodipodi:ry="8" sodipodi:rx="8" sodipodi:cy="118" @@ -99811,7 +99845,7 @@ inkscape:export-ydpi="90" inkscape:export-xdpi="90" inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png" - d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z" + d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z" sodipodi:ry="8" sodipodi:rx="8" sodipodi:cy="118" @@ -99830,7 +99864,7 @@ inkscape:export-ydpi="90" inkscape:export-xdpi="90" inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png" - d="m 132,110 a 8,8 0 0 1 6.9282,4 L 132,118 z" + d="m 132,110 c 2.85812,0 5.49914,1.52479 6.9282,4 L 132,118 z" sodipodi:ry="8" sodipodi:rx="8" sodipodi:cy="118" @@ -99848,7 +99882,7 @@ sodipodi:cy="118" sodipodi:rx="8" sodipodi:ry="8" - d="m 132,110 a 8,8 0 0 1 6.9282,4 L 132,118 z" + d="m 132,110 c 2.85812,0 5.49914,1.52479 6.9282,4 L 132,118 z" inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png" inkscape:export-xdpi="90" inkscape:export-ydpi="90" @@ -99864,7 +99898,7 @@ inkscape:export-ydpi="90" inkscape:export-xdpi="90" inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png" - d="m 132,110 a 8,8 0 0 1 6.9282,4 L 132,118 z" + d="m 132,110 c 2.85812,0 5.49914,1.52479 6.9282,4 L 132,118 z" sodipodi:ry="8" sodipodi:rx="8" sodipodi:cy="118" @@ -99882,7 +99916,7 @@ sodipodi:cy="118" sodipodi:rx="8" sodipodi:ry="8" - d="m 132,110 a 8,8 0 0 1 6.9282,4 L 132,118 z" + d="m 132,110 c 2.85812,0 5.49914,1.52479 6.9282,4 L 132,118 z" inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png" inkscape:export-xdpi="90" inkscape:export-ydpi="90" @@ -99897,7 +99931,7 @@ inkscape:export-ydpi="90" inkscape:export-xdpi="90" inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png" - d="m 132,110 a 8,8 0 0 1 6.9282,4 L 132,118 z" + d="m 132,110 c 2.85812,0 5.49914,1.52479 6.9282,4 L 132,118 z" sodipodi:ry="8" sodipodi:rx="8" sodipodi:cy="118" @@ -99916,7 +99950,7 @@ sodipodi:cy="118" sodipodi:rx="8" sodipodi:ry="8" - d="m 132,110 a 8,8 0 0 1 6.9282,4 L 132,118 z" + d="m 132,110 c 2.85812,0 5.49914,1.52479 6.9282,4 L 132,118 z" inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png" inkscape:export-xdpi="90" inkscape:export-ydpi="90" @@ -99933,7 +99967,7 @@ sodipodi:cy="118" sodipodi:rx="8" sodipodi:ry="8" - d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z" + d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z" inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png" inkscape:export-xdpi="90" inkscape:export-ydpi="90" /> @@ -99941,7 +99975,7 @@ inkscape:export-ydpi="90" inkscape:export-xdpi="90" inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png" - d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z" + d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z" sodipodi:ry="8" sodipodi:rx="8" sodipodi:cy="118" @@ -99971,7 +100005,7 @@ inkscape:export-ydpi="90" inkscape:export-xdpi="90" inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png" - d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z" + d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z" sodipodi:ry="8" sodipodi:rx="8" sodipodi:cy="118" @@ -99990,7 +100024,7 @@ inkscape:export-ydpi="90" inkscape:export-xdpi="90" inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png" - d="m 132,110 a 8,8 0 0 1 6.9282,4 L 132,118 z" + d="m 132,110 c 2.85812,0 5.49914,1.52479 6.9282,4 L 132,118 z" sodipodi:ry="8" sodipodi:rx="8" sodipodi:cy="118" @@ -100008,7 +100042,7 @@ sodipodi:cy="118" sodipodi:rx="8" sodipodi:ry="8" - d="m 132,110 a 8,8 0 0 1 6.9282,4 L 132,118 z" + d="m 132,110 c 2.85812,0 5.49914,1.52479 6.9282,4 L 132,118 z" inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png" inkscape:export-xdpi="90" inkscape:export-ydpi="90" @@ -100024,7 +100058,7 @@ inkscape:export-ydpi="90" inkscape:export-xdpi="90" inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png" - d="m 132,110 a 8,8 0 0 1 6.9282,4 L 132,118 z" + d="m 132,110 c 2.85812,0 5.49914,1.52479 6.9282,4 L 132,118 z" sodipodi:ry="8" sodipodi:rx="8" sodipodi:cy="118" @@ -100042,7 +100076,7 @@ sodipodi:cy="118" sodipodi:rx="8" sodipodi:ry="8" - d="m 132,110 a 8,8 0 0 1 6.9282,4 L 132,118 z" + d="m 132,110 c 2.85812,0 5.49914,1.52479 6.9282,4 L 132,118 z" inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png" inkscape:export-xdpi="90" inkscape:export-ydpi="90" @@ -100057,7 +100091,7 @@ inkscape:export-ydpi="90" inkscape:export-xdpi="90" inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png" - d="m 132,110 a 8,8 0 0 1 6.9282,4 L 132,118 z" + d="m 132,110 c 2.85812,0 5.49914,1.52479 6.9282,4 L 132,118 z" sodipodi:ry="8" sodipodi:rx="8" sodipodi:cy="118" @@ -100076,7 +100110,7 @@ sodipodi:cy="118" sodipodi:rx="8" sodipodi:ry="8" - d="m 132,110 a 8,8 0 0 1 6.9282,4 L 132,118 z" + d="m 132,110 c 2.85812,0 5.49914,1.52479 6.9282,4 L 132,118 z" inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png" inkscape:export-xdpi="90" inkscape:export-ydpi="90" @@ -100093,7 +100127,7 @@ sodipodi:cy="118" sodipodi:rx="8" sodipodi:ry="8" - d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z" + d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z" inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png" inkscape:export-xdpi="90" inkscape:export-ydpi="90" /> @@ -100101,7 +100135,7 @@ inkscape:export-ydpi="90" inkscape:export-xdpi="90" inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png" - d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z" + d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z" sodipodi:ry="8" sodipodi:rx="8" sodipodi:cy="118" @@ -100131,7 +100165,7 @@ inkscape:export-ydpi="90" inkscape:export-xdpi="90" inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png" - d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z" + d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z" sodipodi:ry="8" sodipodi:rx="8" sodipodi:cy="118" @@ -100150,7 +100184,7 @@ inkscape:export-ydpi="90" inkscape:export-xdpi="90" inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png" - d="m 132,110 a 8,8 0 0 1 6.9282,4 L 132,118 z" + d="m 132,110 c 2.85812,0 5.49914,1.52479 6.9282,4 L 132,118 z" sodipodi:ry="8" sodipodi:rx="8" sodipodi:cy="118" @@ -100168,7 +100202,7 @@ sodipodi:cy="118" sodipodi:rx="8" sodipodi:ry="8" - d="m 132,110 a 8,8 0 0 1 6.9282,4 L 132,118 z" + d="m 132,110 c 2.85812,0 5.49914,1.52479 6.9282,4 L 132,118 z" inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png" inkscape:export-xdpi="90" inkscape:export-ydpi="90" @@ -100184,7 +100218,7 @@ inkscape:export-ydpi="90" inkscape:export-xdpi="90" inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png" - d="m 132,110 a 8,8 0 0 1 6.9282,4 L 132,118 z" + d="m 132,110 c 2.85812,0 5.49914,1.52479 6.9282,4 L 132,118 z" sodipodi:ry="8" sodipodi:rx="8" sodipodi:cy="118" @@ -100202,7 +100236,7 @@ sodipodi:cy="118" sodipodi:rx="8" sodipodi:ry="8" - d="m 132,110 a 8,8 0 0 1 6.9282,4 L 132,118 z" + d="m 132,110 c 2.85812,0 5.49914,1.52479 6.9282,4 L 132,118 z" inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png" inkscape:export-xdpi="90" inkscape:export-ydpi="90" @@ -100217,7 +100251,7 @@ inkscape:export-ydpi="90" inkscape:export-xdpi="90" inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png" - d="m 132,110 a 8,8 0 0 1 6.9282,4 L 132,118 z" + d="m 132,110 c 2.85812,0 5.49914,1.52479 6.9282,4 L 132,118 z" sodipodi:ry="8" sodipodi:rx="8" sodipodi:cy="118" @@ -100236,7 +100270,7 @@ sodipodi:cy="118" sodipodi:rx="8" sodipodi:ry="8" - d="m 132,110 a 8,8 0 0 1 6.9282,4 L 132,118 z" + d="m 132,110 c 2.85812,0 5.49914,1.52479 6.9282,4 L 132,118 z" inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png" inkscape:export-xdpi="90" inkscape:export-ydpi="90" @@ -100253,7 +100287,7 @@ sodipodi:cy="118" sodipodi:rx="8" sodipodi:ry="8" - d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z" + d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z" inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png" inkscape:export-xdpi="90" inkscape:export-ydpi="90" /> @@ -100261,7 +100295,7 @@ inkscape:export-ydpi="90" inkscape:export-xdpi="90" inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png" - d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z" + d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z" sodipodi:ry="8" sodipodi:rx="8" sodipodi:cy="118" @@ -100388,7 +100422,7 @@ inkscape:connector-curvature="0" /> @@ -101027,7 +101061,7 @@ inkscape:export-ydpi="90" inkscape:export-xdpi="90" inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png" - d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z" + d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z" sodipodi:ry="8" sodipodi:rx="8" sodipodi:cy="118" @@ -101041,7 +101075,7 @@ inkscape:export-ydpi="90" inkscape:export-xdpi="90" inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png" - d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z" + d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z" sodipodi:ry="8" sodipodi:rx="8" sodipodi:cy="118" @@ -101142,7 +101176,7 @@ sodipodi:cy="118" sodipodi:rx="8" sodipodi:ry="8" - d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z" + d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z" inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png" inkscape:export-xdpi="90" inkscape:export-ydpi="90" /> @@ -101150,7 +101184,7 @@ inkscape:export-ydpi="90" inkscape:export-xdpi="90" inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png" - d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z" + d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z" sodipodi:ry="8" sodipodi:rx="8" sodipodi:cy="118" @@ -101164,7 +101198,7 @@ inkscape:export-ydpi="90" inkscape:export-xdpi="90" inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png" - d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z" + d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z" sodipodi:ry="8" sodipodi:rx="8" sodipodi:cy="118" @@ -101374,7 +101408,7 @@ inkscape:connector-curvature="0" /> @@ -102263,7 +102297,7 @@ inkscape:export-ydpi="90" inkscape:export-xdpi="90" inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png" - d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z" + d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z" sodipodi:ry="8" sodipodi:rx="8" sodipodi:cy="118" @@ -102783,5 +102817,381 @@ id="path39249-3-7" sodipodi:nodetypes="cccccc" inkscape:connector-curvature="0" /> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From 31ee55ef235ec030912820fb2422a68f27e270db Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Fri, 14 Dec 2012 01:40:09 +0000 Subject: [PATCH 111/252] SVG Icons: Back to screen icon --- release/datafiles/blender_icons.svg | 199 ++++++++++++++++++++++++++-- 1 file changed, 186 insertions(+), 13 deletions(-) diff --git a/release/datafiles/blender_icons.svg b/release/datafiles/blender_icons.svg index 9403edeb110..a080c723873 100644 --- a/release/datafiles/blender_icons.svg +++ b/release/datafiles/blender_icons.svg @@ -49655,15 +49655,6 @@ offset="1" style="stop-color:#ffffff;stop-opacity:1;" /> - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From 455693a6eaf1fa55aa4c92b514e9f1e1af0686f8 Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Fri, 14 Dec 2012 01:52:08 +0000 Subject: [PATCH 112/252] SVG Icons: Frame Next/Prev (used for Motion Tracker controls) --- release/datafiles/blender_icons.svg | 272 +++++++++++++++++++++++++++- 1 file changed, 269 insertions(+), 3 deletions(-) diff --git a/release/datafiles/blender_icons.svg b/release/datafiles/blender_icons.svg index a080c723873..4553003682f 100644 --- a/release/datafiles/blender_icons.svg +++ b/release/datafiles/blender_icons.svg @@ -49757,6 +49757,154 @@ offset="1" id="stop44943-2-1" /> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From b8d89be64c419a075cf55a1e6e9aa9d021731ad3 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 14 Dec 2012 04:07:30 +0000 Subject: [PATCH 113/252] UV Warp Modifier: Based on patch [#30837] UV Offset Modifier by Pawel Kowal (pkowal) - Allows you to setup a transformation between objects to apply to UV coords. - Option to select which axis apply to U/V. - Option to select the UV center (needed for transformations that scale or rotate). - Uses from/to objects in a similar way to the Warp modifier. - Vertex group can be used to adjust influence. --- .../startup/bl_ui/properties_data_modifier.py | 42 +++ .../editors/space_outliner/outliner_draw.c | 1 + source/blender/makesdna/DNA_modifier_types.h | 21 +- source/blender/makesrna/RNA_access.h | 1 + source/blender/makesrna/intern/rna_modifier.c | 94 +++++- source/blender/modifiers/CMakeLists.txt | 5 +- source/blender/modifiers/MOD_modifiertypes.h | 1 + source/blender/modifiers/intern/MOD_util.c | 1 + source/blender/modifiers/intern/MOD_uvwarp.c | 268 ++++++++++++++++++ 9 files changed, 428 insertions(+), 6 deletions(-) create mode 100644 source/blender/modifiers/intern/MOD_uvwarp.c diff --git a/release/scripts/startup/bl_ui/properties_data_modifier.py b/release/scripts/startup/bl_ui/properties_data_modifier.py index 62461d800f6..e90d1616929 100644 --- a/release/scripts/startup/bl_ui/properties_data_modifier.py +++ b/release/scripts/startup/bl_ui/properties_data_modifier.py @@ -1032,5 +1032,47 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel): def TRIANGULATE(self, layout, ob, md): layout.prop(md, "use_beauty") + def UV_WARP(self, layout, ob, md): + split = layout.split() + col = split.column() + col.prop(md, "center"); + + col = split.column() + col.label(text="UV Axis:") + col.prop(md, "axis_u", text=""); + col.prop(md, "axis_v", text=""); + + split = layout.split() + col = split.column() + col.label(text="From:") + col.prop(md, "object_from", text="") + + col = split.column() + col.label(text="To:") + col.prop(md, "object_to", text="") + + split = layout.split() + col = split.column() + obj = md.object_from + if obj and obj.type == 'ARMATURE': + col.label(text="Bone:") + col.prop_search(md, "bone_from", obj.data, "bones", text="") + + col = split.column() + obj = md.object_to + if obj and obj.type == 'ARMATURE': + col.label(text="Bone:") + col.prop_search(md, "bone_to", obj.data, "bones", text="") + + split = layout.split() + + col = split.column() + col.label(text="Vertex Group:") + col.prop_search(md, "vertex_group", ob, "vertex_groups", text="") + + col = split.column() + col.label(text="UV Map:") + col.prop_search(md, "uv_layer", ob.data, "uv_textures", text="") + if __name__ == "__main__": # only for live edit. bpy.utils.register_module(__name__) diff --git a/source/blender/editors/space_outliner/outliner_draw.c b/source/blender/editors/space_outliner/outliner_draw.c index abe0ef253f9..186a3432ab1 100644 --- a/source/blender/editors/space_outliner/outliner_draw.c +++ b/source/blender/editors/space_outliner/outliner_draw.c @@ -996,6 +996,7 @@ static void tselem_draw_icon(uiBlock *block, int xmax, float x, float y, TreeSto case eModifierType_Array: UI_icon_draw(x, y, ICON_MOD_ARRAY); break; case eModifierType_UVProject: + case eModifierType_UVWarp: /* TODO, get own icon */ UI_icon_draw(x, y, ICON_MOD_UVPROJECT); break; case eModifierType_Displace: UI_icon_draw(x, y, ICON_MOD_DISPLACE); break; diff --git a/source/blender/makesdna/DNA_modifier_types.h b/source/blender/makesdna/DNA_modifier_types.h index 68aa7600cd1..089103c66e5 100644 --- a/source/blender/makesdna/DNA_modifier_types.h +++ b/source/blender/makesdna/DNA_modifier_types.h @@ -76,7 +76,8 @@ typedef enum ModifierType { eModifierType_Remesh = 41, eModifierType_Skin = 42, eModifierType_LaplacianSmooth = 43, - eModifierType_Triangulate = 44, + eModifierType_Triangulate = 44, + eModifierType_UVWarp = 45, NUM_MODIFIER_TYPES } ModifierType; @@ -1140,4 +1141,20 @@ typedef struct LaplacianSmoothModifierData { short flag, repeat; } LaplacianSmoothModifierData; -#endif +typedef struct UVWarpModifierData { + ModifierData modifier; + + char axis_u, axis_v; + char pad[6]; + float center[2]; /* used for rotate/scale */ + + struct Object *object_src; /* source */ + char bone_src[64]; /* optional name of bone target, MAX_ID_NAME-2 */ + struct Object *object_dst; /* target */ + char bone_dst[64]; /* optional name of bone target, MAX_ID_NAME-2 */ + + char vgroup_name[64]; /* optional vertexgroup name, MAX_VGROUP_NAME */ + char uvlayer_name[64]; /* MAX_CUSTOMDATA_LAYER_NAME */ +} UVWarpModifierData; + +#endif /* __DNA_MODIFIER_TYPES_H__ */ diff --git a/source/blender/makesrna/RNA_access.h b/source/blender/makesrna/RNA_access.h index 0e5f9c5fa5f..4795338c85c 100644 --- a/source/blender/makesrna/RNA_access.h +++ b/source/blender/makesrna/RNA_access.h @@ -587,6 +587,7 @@ extern StructRNA RNA_TransformConstraint; extern StructRNA RNA_TransformSequence; extern StructRNA RNA_UILayout; extern StructRNA RNA_UIListItem; +extern StructRNA RNA_UVWarpModifier; extern StructRNA RNA_UVProjectModifier; extern StructRNA RNA_UVProjector; extern StructRNA RNA_UnitSettings; diff --git a/source/blender/makesrna/intern/rna_modifier.c b/source/blender/makesrna/intern/rna_modifier.c index a2b0945fb46..e1489d821a0 100644 --- a/source/blender/makesrna/intern/rna_modifier.c +++ b/source/blender/makesrna/intern/rna_modifier.c @@ -59,6 +59,7 @@ EnumPropertyItem modifier_type_items[] = { {0, "", 0, N_("Modify"), ""}, {eModifierType_UVProject, "UV_PROJECT", ICON_MOD_UVPROJECT, "UV Project", ""}, + {eModifierType_UVWarp, "UV_WARP", ICON_MOD_UVPROJECT, "UV Warp", ""}, {eModifierType_WeightVGEdit, "VERTEX_WEIGHT_EDIT", ICON_MOD_VERTEX_WEIGHT, "Vertex Weight Edit", ""}, {eModifierType_WeightVGMix, "VERTEX_WEIGHT_MIX", ICON_MOD_VERTEX_WEIGHT, "Vertex Weight Mix", ""}, {eModifierType_WeightVGProximity, "VERTEX_WEIGHT_PROXIMITY", ICON_MOD_VERTEX_WEIGHT, @@ -129,7 +130,7 @@ static StructRNA *rna_Modifier_refine(struct PointerRNA *ptr) { ModifierData *md = (ModifierData *)ptr->data; - switch (md->type) { + switch ((ModifierType)md->type) { case eModifierType_Subsurf: return &RNA_SubsurfModifier; case eModifierType_Lattice: @@ -216,9 +217,16 @@ static StructRNA *rna_Modifier_refine(struct PointerRNA *ptr) return &RNA_LaplacianSmoothModifier; case eModifierType_Triangulate: return &RNA_TriangulateModifier; - default: + case eModifierType_UVWarp: + return &RNA_UVWarpModifier; + /* Default */ + case eModifierType_None: + case eModifierType_ShapeKey: + case NUM_MODIFIER_TYPES: return &RNA_Modifier; } + + return &RNA_Modifier; } static void rna_Modifier_name_set(PointerRNA *ptr, const char *value) @@ -738,6 +746,18 @@ static void rna_BevelModifier_angle_limit_set(PointerRNA *ptr, float value) md->bevel_angle = (int)value; } +static void rna_UVWarpModifier_vgroup_set(PointerRNA *ptr, const char *value) +{ + UVWarpModifierData *umd = (UVWarpModifierData*)ptr->data; + rna_object_vgroup_name_set(ptr, value, umd->vgroup_name, sizeof(umd->vgroup_name)); +} + +static void rna_UVWarpModifier_uvlayer_set(PointerRNA *ptr, const char *value) +{ + UVWarpModifierData *umd = (UVWarpModifierData*)ptr->data; + rna_object_uvlayer_name_set(ptr, value, umd->uvlayer_name, sizeof(umd->uvlayer_name)); +} + #else static PropertyRNA *rna_def_property_subdivision_common(StructRNA *srna, const char type[]) @@ -2773,6 +2793,75 @@ static void rna_def_modifier_screw(BlenderRNA *brna) #endif } +static void rna_def_modifier_uvwarp(BlenderRNA *brna) +{ + StructRNA *srna; + PropertyRNA *prop; + + static EnumPropertyItem uvwarp_axis[] = { + {0, "X", 0, "X", ""}, + {1, "Y", 0, "Y", ""}, + {2, "Z", 0, "Z", ""}, + {0, NULL, 0, NULL, NULL} + }; + + srna = RNA_def_struct(brna, "UVWarpModifier", "Modifier"); + RNA_def_struct_ui_text(srna, "UVWarp Modifier", "Add target position to uv coordinates"); + RNA_def_struct_sdna(srna, "UVWarpModifierData"); + RNA_def_struct_ui_icon(srna, ICON_MOD_UVPROJECT); + + prop = RNA_def_property(srna, "axis_u", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_sdna(prop, NULL, "axis_u"); + RNA_def_property_enum_items(prop, uvwarp_axis); + RNA_def_property_ui_text(prop, "U-Axis", "Pole axis for rotation"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); + + prop = RNA_def_property(srna, "axis_v", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_sdna(prop, NULL, "axis_v"); + RNA_def_property_enum_items(prop, uvwarp_axis); + RNA_def_property_ui_text(prop, "V-Axis", "Pole axis for rotation"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); + + prop = RNA_def_property(srna, "center", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "center"); + RNA_def_property_ui_text(prop, "UV Center", "Center point for rotate/scale"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); + + prop = RNA_def_property(srna, "object_from", PROP_POINTER, PROP_NONE); + RNA_def_property_pointer_sdna(prop, NULL, "object_src"); + RNA_def_property_ui_text(prop, "Target", "Object defining offset"); + RNA_def_property_flag(prop, PROP_EDITABLE); + RNA_def_property_update(prop, 0, "rna_Modifier_dependency_update"); + + prop = RNA_def_property(srna, "bone_from", PROP_STRING, PROP_NONE); + RNA_def_property_string_sdna(prop, NULL, "bone_src"); + RNA_def_property_ui_text(prop, "Sub-Target", "Bone defining offset"); + RNA_def_property_update(prop, 0, "rna_Modifier_dependency_update"); + + prop = RNA_def_property(srna, "object_to", PROP_POINTER, PROP_NONE); + RNA_def_property_pointer_sdna(prop, NULL, "object_dst"); + RNA_def_property_ui_text(prop, "Target", "Object defining offset"); + RNA_def_property_flag(prop, PROP_EDITABLE); + RNA_def_property_update(prop, 0, "rna_Modifier_dependency_update"); + + prop = RNA_def_property(srna, "bone_to", PROP_STRING, PROP_NONE); + RNA_def_property_string_sdna(prop, NULL, "bone_dst"); + RNA_def_property_ui_text(prop, "Sub-Target", "Bone defining offset"); + RNA_def_property_update(prop, 0, "rna_Modifier_dependency_update"); + + prop = RNA_def_property(srna, "vertex_group", PROP_STRING, PROP_NONE); + RNA_def_property_string_sdna(prop, NULL, "vgroup_name"); + RNA_def_property_ui_text(prop, "Vertex Group", "Vertex group name"); + RNA_def_property_string_funcs(prop, NULL, NULL, "rna_UVWarpModifier_vgroup_set"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); + + prop = RNA_def_property(srna, "uv_layer", PROP_STRING, PROP_NONE); + RNA_def_property_string_sdna(prop, NULL, "uvlayer_name"); + RNA_def_property_ui_text(prop, "UV Layer", "UV Layer name"); + RNA_def_property_string_funcs(prop, NULL, NULL, "rna_UVWarpModifier_uvlayer_set"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); +} + static void rna_def_modifier_weightvg_mask(BlenderRNA *UNUSED(brna), StructRNA *srna) { static EnumPropertyItem weightvg_mask_tex_map_items[] = { @@ -3480,6 +3569,7 @@ void RNA_def_modifier(BlenderRNA *brna) rna_def_modifier_smoke(brna); rna_def_modifier_solidify(brna); rna_def_modifier_screw(brna); + rna_def_modifier_uvwarp(brna); rna_def_modifier_weightvgedit(brna); rna_def_modifier_weightvgmix(brna); rna_def_modifier_weightvgproximity(brna); diff --git a/source/blender/modifiers/CMakeLists.txt b/source/blender/modifiers/CMakeLists.txt index cf3bb05849a..33209095164 100644 --- a/source/blender/modifiers/CMakeLists.txt +++ b/source/blender/modifiers/CMakeLists.txt @@ -64,8 +64,8 @@ set(SRC intern/MOD_fluidsim.c intern/MOD_fluidsim_util.c intern/MOD_hook.c - intern/MOD_lattice.c intern/MOD_laplaciansmooth.c + intern/MOD_lattice.c intern/MOD_mask.c intern/MOD_meshdeform.c intern/MOD_mirror.c @@ -86,7 +86,9 @@ set(SRC intern/MOD_solidify.c intern/MOD_subsurf.c intern/MOD_surface.c + intern/MOD_triangulate.c intern/MOD_util.c + intern/MOD_uvwarp.c intern/MOD_uvproject.c intern/MOD_warp.c intern/MOD_wave.c @@ -94,7 +96,6 @@ set(SRC intern/MOD_weightvgedit.c intern/MOD_weightvgmix.c intern/MOD_weightvgproximity.c - intern/MOD_triangulate.c MOD_modifiertypes.h intern/MOD_boolean_util.h diff --git a/source/blender/modifiers/MOD_modifiertypes.h b/source/blender/modifiers/MOD_modifiertypes.h index 290ba193567..17e903e9ebb 100644 --- a/source/blender/modifiers/MOD_modifiertypes.h +++ b/source/blender/modifiers/MOD_modifiertypes.h @@ -77,6 +77,7 @@ extern ModifierTypeInfo modifierType_Remesh; extern ModifierTypeInfo modifierType_Skin; extern ModifierTypeInfo modifierType_LaplacianSmooth; extern ModifierTypeInfo modifierType_Triangulate; +extern ModifierTypeInfo modifierType_UVWarp; /* MOD_util.c */ void modifier_type_init(ModifierTypeInfo *types[]); diff --git a/source/blender/modifiers/intern/MOD_util.c b/source/blender/modifiers/intern/MOD_util.c index a27d5e5e03b..6c2f68891af 100644 --- a/source/blender/modifiers/intern/MOD_util.c +++ b/source/blender/modifiers/intern/MOD_util.c @@ -279,5 +279,6 @@ void modifier_type_init(ModifierTypeInfo *types[]) INIT_TYPE(Skin); INIT_TYPE(LaplacianSmooth); INIT_TYPE(Triangulate); + INIT_TYPE(UVWarp); #undef INIT_TYPE } diff --git a/source/blender/modifiers/intern/MOD_uvwarp.c b/source/blender/modifiers/intern/MOD_uvwarp.c new file mode 100644 index 00000000000..05e8d0df54c --- /dev/null +++ b/source/blender/modifiers/intern/MOD_uvwarp.c @@ -0,0 +1,268 @@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor(s): Pawel Kowal, Campbell Barton + * + * ***** END GPL LICENSE BLOCK ***** + * + */ + +/** \file blender/modifiers/intern/MOD_uvwarp.c + * \ingroup modifiers + */ + +#include + +#include "DNA_meshdata_types.h" +#include "DNA_object_types.h" + +#include "BLI_math.h" +#include "BLI_string.h" +#include "BLI_utildefines.h" + +#include "BKE_action.h" /* BKE_pose_channel_find_name */ +#include "BKE_cdderivedmesh.h" +#include "BKE_deform.h" +#include "BKE_modifier.h" + +#include "depsgraph_private.h" + +#include "MOD_util.h" + + +static void uv_warp_from_mat4_pair(float uv_dst[2], const float uv_src[2], float warp_mat[4][4], + int axis_u, int axis_v) +{ + float tuv[3] = {0.0f}; + + tuv[axis_u] = uv_src[0]; + tuv[axis_v] = uv_src[1]; + + mul_m4_v3(warp_mat, tuv); + + uv_dst[0] = tuv[axis_u]; + uv_dst[1] = tuv[axis_v]; +} + +static void initData(ModifierData *md) +{ + UVWarpModifierData *umd = (UVWarpModifierData *) md; + umd->axis_u = 0; + umd->axis_v = 1; + copy_v2_fl(umd->center, 0.5f); +} + +static void copyData(ModifierData *md, ModifierData *target) +{ + UVWarpModifierData *umd = (UVWarpModifierData *)md; + UVWarpModifierData *tumd = (UVWarpModifierData *)target; + + tumd->axis_u = umd->axis_u; + tumd->axis_v = umd->axis_v; + copy_v2_v2(tumd->center, umd->center); + tumd->object_src = umd->object_src; + BLI_strncpy(tumd->bone_src, umd->bone_src, sizeof(tumd->bone_src)); + tumd->object_dst = umd->object_dst; + BLI_strncpy(tumd->bone_dst, umd->bone_dst, sizeof(tumd->bone_dst)); + BLI_strncpy(tumd->vgroup_name, umd->vgroup_name, sizeof(tumd->vgroup_name)); + BLI_strncpy(tumd->uvlayer_name, umd->uvlayer_name, sizeof(umd->uvlayer_name)); +} + +static CustomDataMask requiredDataMask(Object *UNUSED(ob), ModifierData *md) +{ + UVWarpModifierData *umd = (UVWarpModifierData *)md; + CustomDataMask dataMask = 0; + + /* ask for vertexgroups if we need them */ + if (umd->vgroup_name[0]) + dataMask |= CD_MASK_MDEFORMVERT; + + return dataMask; +} + +static void matrix_from_obj_pchan(float mat[4][4], Object *ob, const char *bonename) +{ + bPoseChannel *pchan = BKE_pose_channel_find_name(ob->pose, bonename); + if (pchan) { + mult_m4_m4m4(mat, ob->obmat, pchan->pose_mat); + } + else { + copy_m4_m4(mat, ob->obmat); + } +} + +#define OMP_LIMIT 1000 +static DerivedMesh *applyModifier(ModifierData *md, Object *ob, + DerivedMesh *dm, + ModifierApplyFlag UNUSED(flag)) +{ + UVWarpModifierData *umd = (UVWarpModifierData *) md; + int i, numPolys, numLoops; + MPoly *mpoly; + MLoop *mloop; + MLoopUV *mloopuv; + MDeformVert *dvert; + int defgrp_index; + char uvname[MAX_CUSTOMDATA_LAYER_NAME]; + float mat_src[4][4]; + float mat_dst[4][4]; + float imat_dst[4][4]; + float warp_mat[4][4]; + const int axis_u = umd->axis_u; + const int axis_v = umd->axis_v; + + /* make sure there are UV Maps available */ + if (!CustomData_has_layer(&dm->loopData, CD_MLOOPUV)) { + return dm; + } + else if (ELEM(NULL, umd->object_src, umd->object_dst)) { + modifier_setError(md, "from/to objects must be set"); + return dm; + } + + /* make sure anything moving UVs is available */ + matrix_from_obj_pchan(mat_src, umd->object_src, umd->bone_src); + matrix_from_obj_pchan(mat_dst, umd->object_dst, umd->bone_dst); + + invert_m4_m4(imat_dst, mat_dst); + mult_m4_m4m4(warp_mat, imat_dst, mat_src); + + /* apply warp */ + if (!is_zero_v2(umd->center)) { + float mat_cent[4][4]; + float imat_cent[4][4]; + + unit_m4(mat_cent); + mat_cent[3][axis_u] = umd->center[0]; + mat_cent[3][axis_v] = umd->center[1]; + + invert_m4_m4(imat_cent, mat_cent); + + mult_m4_m4m4(warp_mat, warp_mat, imat_cent); + mult_m4_m4m4(warp_mat, mat_cent, warp_mat); + } + + /* make sure we're using an existing layer */ + CustomData_validate_layer_name(&dm->loopData, CD_MLOOPUV, umd->uvlayer_name, uvname); + + numPolys = dm->getNumPolys(dm); + numLoops = dm->getNumLoops(dm); + + mpoly = dm->getPolyArray(dm); + mloop = dm->getLoopArray(dm); + /* make sure we are not modifying the original UV map */ + mloopuv = CustomData_duplicate_referenced_layer_named(&dm->loopData, CD_MLOOPUV, uvname, numLoops); + modifier_get_vgroup(ob, dm, umd->vgroup_name, &dvert, &defgrp_index); + + if (dvert) { +#pragma omp parallel for if (numPolys > OMP_LIMIT) + for (i = 0; i < numPolys; i++) { + float uv[2]; + MPoly *mp = &mpoly[i]; + MLoop *ml = &mloop[mp->loopstart]; + MLoopUV *mluv = &mloopuv[mp->loopstart]; + int l; + for (l = 0; l < mp->totloop; l++, ml++, mluv++) { + const float weight = defvert_find_weight(&dvert[ml->v], defgrp_index); + uv_warp_from_mat4_pair(uv, mluv->uv, warp_mat, axis_u, axis_v); + interp_v2_v2v2(mluv->uv, mluv->uv, uv, weight); + } + } + } + else { +#pragma omp parallel for if (numPolys > OMP_LIMIT) + for (i = 0; i < numPolys; i++) { + MPoly *mp = &mpoly[i]; + // MLoop *ml = &mloop[mp->loopstart]; + MLoopUV *mluv = &mloopuv[mp->loopstart]; + int l; + for (l = 0; l < mp->totloop; l++, /* ml++, */ mluv++) { + uv_warp_from_mat4_pair(mluv->uv, mluv->uv, warp_mat, axis_u, axis_v); + } + } + } + + dm->dirty |= DM_DIRTY_TESS_CDLAYERS; + + return dm; +} + +static DerivedMesh *applyModifierEM(ModifierData *md, Object *ob, + struct BMEditMesh *UNUSED(editData), + DerivedMesh *derivedData) +{ + return applyModifier(md, ob, derivedData, MOD_APPLY_USECACHE); +} + +static void foreachObjectLink(ModifierData *md, Object *ob, ObjectWalkFunc walk, void *userData) +{ + UVWarpModifierData *umd = (UVWarpModifierData *) md; + + walk(userData, ob, &umd->object_dst); + walk(userData, ob, &umd->object_src); +} + +static void uv_warp_deps_object_bone(DagForest *forest, DagNode *obNode, + Object *obj, const char *bonename) +{ + if (obj) { + DagNode *curNode = dag_get_node(forest, obj); + + if (bonename[0]) + dag_add_relation(forest, curNode, obNode, DAG_RL_OB_DATA | DAG_RL_DATA_DATA, "UVWarp Modifier"); + else + dag_add_relation(forest, curNode, obNode, DAG_RL_OB_DATA, "UVWarp Modifier"); + } +} + +static void updateDepgraph(ModifierData *md, DagForest *forest, + struct Scene *UNUSED(scene), + Object *UNUSED(ob), + DagNode *obNode) +{ + UVWarpModifierData *umd = (UVWarpModifierData *) md; + + uv_warp_deps_object_bone(forest, obNode, umd->object_src, umd->bone_src); + uv_warp_deps_object_bone(forest, obNode, umd->object_dst, umd->bone_dst); +} + +ModifierTypeInfo modifierType_UVWarp = { + /* name */ "UVWarp", + /* structName */ "UVWarpModifierData", + /* structSize */ sizeof(UVWarpModifierData), + /* type */ eModifierTypeType_NonGeometrical, + /* flags */ eModifierTypeFlag_AcceptsMesh | + eModifierTypeFlag_SupportsEditmode | + eModifierTypeFlag_EnableInEditmode, + /* copyData */ copyData, + /* deformVerts */ NULL, + /* deformMatrices */ NULL, + /* deformVertsEM */ NULL, + /* deformMatricesEM */ NULL, + /* applyModifier */ applyModifier, + /* applyModifierEM */ applyModifierEM, + /* initData */ initData, + /* requiredDataMask */ requiredDataMask, + /* freeData */ NULL, + /* isDisabled */ NULL, + /* updateDepgraph */ updateDepgraph, + /* dependsOnTime */ NULL, + /* dependsOnNormals */ NULL, + /* foreachObjectLink */ foreachObjectLink, + /* foreachIDLink */ NULL, + /* foreachTexLink */ NULL, +}; From 5e9ee25328aa3aab4549a1ebfae931161ed02f2b Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 14 Dec 2012 04:38:52 +0000 Subject: [PATCH 114/252] style cleanup --- source/blender/editors/screen/area.c | 2 +- source/blender/editors/space_node/node_add.c | 2 +- source/blender/editors/transform/transform_input.c | 2 +- source/blender/editors/uvedit/uvedit_unwrap_ops.c | 2 +- source/blender/modifiers/intern/MOD_uvwarp.c | 2 +- source/blender/windowmanager/WM_api.h | 3 ++- 6 files changed, 7 insertions(+), 6 deletions(-) diff --git a/source/blender/editors/screen/area.c b/source/blender/editors/screen/area.c index db57aeb0167..62ddd10ee7c 100644 --- a/source/blender/editors/screen/area.c +++ b/source/blender/editors/screen/area.c @@ -883,7 +883,7 @@ static void region_overlap_fix(ARegion *ar) /* find overlapping previous region on same place */ while (ar1) { if (ar1->overlap) { - if ((ar1->alignment & RGN_SPLIT_PREV)==0) + if ((ar1->alignment & RGN_SPLIT_PREV) == 0) if (BLI_rcti_isect(&ar1->winrct, &ar->winrct, NULL)) break; } diff --git a/source/blender/editors/space_node/node_add.c b/source/blender/editors/space_node/node_add.c index 509e326137b..18ce2c81716 100644 --- a/source/blender/editors/space_node/node_add.c +++ b/source/blender/editors/space_node/node_add.c @@ -207,7 +207,7 @@ static bNodeSocketLink *add_reroute_do_socket_section(bContext *C, bNodeSocketLi } add_v2_v2(insert_point, socklink->point); - ++num_links; + num_links++; } socklink = socklink->next; } diff --git a/source/blender/editors/transform/transform_input.c b/source/blender/editors/transform/transform_input.c index 88ed002af89..69569251d01 100644 --- a/source/blender/editors/transform/transform_input.c +++ b/source/blender/editors/transform/transform_input.c @@ -399,7 +399,7 @@ int handleMouseInput(TransInfo *t, MouseInput *mi, wmEvent *event) mi->precision = 1; redraw = TREDRAW_HARD; } - else if(event->val == KM_RELEASE) { + else if (event->val == KM_RELEASE) { t->modifiers &= ~MOD_PRECISION; mi->precision = 0; redraw = TREDRAW_HARD; diff --git a/source/blender/editors/uvedit/uvedit_unwrap_ops.c b/source/blender/editors/uvedit/uvedit_unwrap_ops.c index 346ea6edf7a..cb54689a3c0 100644 --- a/source/blender/editors/uvedit/uvedit_unwrap_ops.c +++ b/source/blender/editors/uvedit/uvedit_unwrap_ops.c @@ -1235,7 +1235,7 @@ static int unwrap_exec(bContext *C, wmOperator *op) /* double up the check here but better keep ED_unwrap_lscm interface simple and not * pass operator for warning append */ modifier_unwrap_state(obedit, scene, &use_subsurf_final); - if(use_subsurf != use_subsurf_final) + if (use_subsurf != use_subsurf_final) BKE_report(op->reports, RPT_INFO, "Subsurf modifier needs to be first to work with unwrap"); /* execute unwrap */ diff --git a/source/blender/modifiers/intern/MOD_uvwarp.c b/source/blender/modifiers/intern/MOD_uvwarp.c index 05e8d0df54c..5585a715131 100644 --- a/source/blender/modifiers/intern/MOD_uvwarp.c +++ b/source/blender/modifiers/intern/MOD_uvwarp.c @@ -45,7 +45,7 @@ static void uv_warp_from_mat4_pair(float uv_dst[2], const float uv_src[2], float warp_mat[4][4], - int axis_u, int axis_v) + int axis_u, int axis_v) { float tuv[3] = {0.0f}; diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h index c1a99513eec..a4579ea31bc 100644 --- a/source/blender/windowmanager/WM_api.h +++ b/source/blender/windowmanager/WM_api.h @@ -148,7 +148,8 @@ struct wmEventHandler *WM_event_add_ui_handler(const struct bContext *C, ListBas void (*remove)(struct bContext *C, void *userdata), void *userdata); void WM_event_remove_ui_handler(ListBase *handlers, int (*func)(struct bContext *C, struct wmEvent *event, void *userdata), - void (*remove)(struct bContext *C, void *userdata), void *userdata, int postpone); + void (*remove)(struct bContext *C, void *userdata), + void *userdata, int postpone); void WM_event_remove_area_handler(struct ListBase *handlers, void *area); struct wmEventHandler *WM_event_add_modal_handler(struct bContext *C, struct wmOperator *op); From f276b3a3cdfa46be051db981395e4d7cb5691b89 Mon Sep 17 00:00:00 2001 From: Alex Fraser Date: Fri, 14 Dec 2012 04:57:26 +0000 Subject: [PATCH 115/252] Adding a new SPH solver that is more physically accurate. See patch #29681 http://projects.blender.org/tracker/index.php?func=detail&aid=29681&group_id=9&atid=127 The solver was mostly implemented by John Mansour at VPAC, with help from me and with funding from the AutoCRC. The SPH formulation is due to Gingold and Monaghan, and the smoothing kernel is due to Wendland. This solver does not replace the old one; it is available as an option. Note that the new solver uses different units than the old one. The patch page has a couple of attachments that can be used to test the new solver, particularly sphclassical_dam_s0.01_grav.blend (ignore the earlier tests). The simulation in that file compares well with a physical experimental dam break; details in a paper by Changhong Hu and Makoto Sueyoshi, also referred to on that page. --- .../startup/bl_ui/properties_particle.py | 65 +-- source/blender/blenkernel/BKE_particle.h | 27 +- .../blenkernel/intern/particle_system.c | 382 +++++++++++++++--- source/blender/makesdna/DNA_particle_types.h | 9 + source/blender/makesrna/intern/rna_particle.c | 23 +- 5 files changed, 411 insertions(+), 95 deletions(-) diff --git a/release/scripts/startup/bl_ui/properties_particle.py b/release/scripts/startup/bl_ui/properties_particle.py index 75154550bcb..2c2ced5db0c 100644 --- a/release/scripts/startup/bl_ui/properties_particle.py +++ b/release/scripts/startup/bl_ui/properties_particle.py @@ -505,6 +505,10 @@ class PARTICLE_PT_physics(ParticleButtonsPanel, Panel): if part.physics_type == 'FLUID': fluid = part.fluid + split = layout.split() + sub = split.row() + sub.prop(fluid, "solver", expand=True) + split = layout.split() col = split.column() @@ -516,13 +520,14 @@ class PARTICLE_PT_physics(ParticleButtonsPanel, Panel): col = split.column() col.label(text="Advanced:") - sub = col.row() - sub.prop(fluid, "repulsion", slider=fluid.factor_repulsion) - sub.prop(fluid, "factor_repulsion", text="") + if fluid.solver == 'DDR': + sub = col.row() + sub.prop(fluid, "repulsion", slider=fluid.factor_repulsion) + sub.prop(fluid, "factor_repulsion", text="") - sub = col.row() - sub.prop(fluid, "stiff_viscosity", slider=fluid.factor_stiff_viscosity) - sub.prop(fluid, "factor_stiff_viscosity", text="") + sub = col.row() + sub.prop(fluid, "stiff_viscosity", slider=fluid.factor_stiff_viscosity) + sub.prop(fluid, "factor_stiff_viscosity", text="") sub = col.row() sub.prop(fluid, "fluid_radius", slider=fluid.factor_radius) @@ -532,27 +537,37 @@ class PARTICLE_PT_physics(ParticleButtonsPanel, Panel): sub.prop(fluid, "rest_density", slider=fluid.factor_density) sub.prop(fluid, "factor_density", text="") - split = layout.split() + if fluid.solver == 'CLASSICAL': + # With the classical solver, it is possible to calculate the + # spacing between particles when the fluid is at rest. This + # makes it easier to set stable initial conditions. + particle_volume = part.mass / fluid.rest_density + spacing = pow(particle_volume, 1/3) + sub = col.row() + sub.label(text="Spacing: %g" % spacing) - col = split.column() - col.label(text="Springs:") - col.prop(fluid, "spring_force", text="Force") - col.prop(fluid, "use_viscoelastic_springs") - sub = col.column(align=True) - sub.active = fluid.use_viscoelastic_springs - sub.prop(fluid, "yield_ratio", slider=True) - sub.prop(fluid, "plasticity", slider=True) + elif fluid.solver == 'DDR': + split = layout.split() - col = split.column() - col.label(text="Advanced:") - sub = col.row() - sub.prop(fluid, "rest_length", slider=fluid.factor_rest_length) - sub.prop(fluid, "factor_rest_length", text="") - col.label(text="") - sub = col.column() - sub.active = fluid.use_viscoelastic_springs - sub.prop(fluid, "use_initial_rest_length") - sub.prop(fluid, "spring_frames", text="Frames") + col = split.column() + col.label(text="Springs:") + col.prop(fluid, "spring_force", text="Force") + col.prop(fluid, "use_viscoelastic_springs") + sub = col.column(align=True) + sub.active = fluid.use_viscoelastic_springs + sub.prop(fluid, "yield_ratio", slider=True) + sub.prop(fluid, "plasticity", slider=True) + + col = split.column() + col.label(text="Advanced:") + sub = col.row() + sub.prop(fluid, "rest_length", slider=fluid.factor_rest_length) + sub.prop(fluid, "factor_rest_length", text="") + col.label(text="") + sub = col.column() + sub.active = fluid.use_viscoelastic_springs + sub.prop(fluid, "use_initial_rest_length") + sub.prop(fluid, "spring_frames", text="Frames") elif part.physics_type == 'KEYED': split = layout.split() diff --git a/source/blender/blenkernel/BKE_particle.h b/source/blender/blenkernel/BKE_particle.h index bdaffef6818..f15ad296e4a 100644 --- a/source/blender/blenkernel/BKE_particle.h +++ b/source/blender/blenkernel/BKE_particle.h @@ -20,7 +20,9 @@ * * The Original Code is: all of this file. * - * Contributor(s): none yet. + * Adaptive time step + * Classical SPH + * Copyright 2011-2012 AutoCRC * * ***** END GPL LICENSE BLOCK ***** */ @@ -58,6 +60,7 @@ struct RNG; struct SurfaceModifierData; struct BVHTreeRay; struct BVHTreeRayHit; +struct EdgeHash; #define PARTICLE_P ParticleData * pa; int p #define LOOP_PARTICLES for (p = 0, pa = psys->particles; p < psys->totpart; p++, pa++) @@ -85,6 +88,24 @@ typedef struct ParticleSimulationData { float courant_num; } ParticleSimulationData; +typedef struct SPHData { + ParticleSystem *psys[10]; + ParticleData *pa; + float mass; + struct EdgeHash *eh; + float *gravity; + float hfac; + /* Average distance to neighbours (other particles in the support domain), + for calculating the Courant number (adaptive time step). */ + int pass; + float element_size; + float flow[3]; + + /* Integrator callbacks. This allows different SPH implementations. */ + void (*force_cb) (void *sphdata_v, ParticleKey *state, float *force, float *impulse); + void (*density_cb) (void *rangedata_v, int index, float squared_dist); +} SPHData; + typedef struct ParticleTexture { float ivel; /* used in reset */ float time, life, exist, size; /* used in init */ @@ -283,6 +304,10 @@ float psys_get_child_size(struct ParticleSystem *psys, struct ChildParticle *cpa void psys_get_particle_on_path(struct ParticleSimulationData *sim, int pa_num, struct ParticleKey *state, int vel); int psys_get_particle_state(struct ParticleSimulationData *sim, int p, struct ParticleKey *state, int always); +void psys_sph_init(struct ParticleSimulationData *sim, struct SPHData *sphdata); +void psys_sph_finalise(struct SPHData *sphdata); +void psys_sph_density(struct BVHTree *tree, struct SPHData* data, float co[3], float vars[2]); + /* for anim.c */ void psys_get_dupli_texture(struct ParticleSystem *psys, struct ParticleSettings *part, struct ParticleSystemModifierData *psmd, struct ParticleData *pa, struct ChildParticle *cpa, diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c index d5fabf60079..7c95265b27b 100644 --- a/source/blender/blenkernel/intern/particle_system.c +++ b/source/blender/blenkernel/intern/particle_system.c @@ -23,7 +23,8 @@ * Contributor(s): Raul Fernandez Hernandez (Farsthary), Stephen Swhitehorn. * * Adaptive time step - * Copyright 2011 AutoCRC + * Classical SPH + * Copyright 2011-2012 AutoCRC * * ***** END GPL LICENSE BLOCK ***** */ @@ -1889,7 +1890,6 @@ void reset_particle(ParticleSimulationData *sim, ParticleData *pa, float dtime, bpa->data.acc[0]=bpa->data.acc[1]=bpa->data.acc[2]=0.0f; } - if (part->type == PART_HAIR) { pa->lifetime = 100.0f; } @@ -2390,33 +2390,34 @@ typedef struct SPHRangeData { SPHNeighbor neighbors[SPH_NEIGHBORS]; int tot_neighbors; - float density, near_density; - float h; + float* data; ParticleSystem *npsys; ParticleData *pa; + float h; float massfac; int use_size; } SPHRangeData; -typedef struct SPHData { - ParticleSystem *psys[10]; - ParticleData *pa; - float mass; - EdgeHash *eh; - float *gravity; - /* Average distance to neighbors (other particles in the support domain), - * for calculating the Courant number (adaptive time step). */ - int pass; - float element_size; - float flow[3]; +static void sph_evaluate_func(BVHTree *tree, ParticleSystem **psys, float co[3], SPHRangeData *pfr, float interaction_radius, BVHTree_RangeQuery callback) { + int i; - /* Integrator callbacks. This allows different SPH implementations. */ - void (*force_cb) (void *sphdata_v, ParticleKey *state, float *force, float *impulse); - void (*density_cb) (void *rangedata_v, int index, float squared_dist); -} SPHData; + pfr->tot_neighbors = 0; + for (i=0; i < 10 && psys[i]; i++) { + pfr->npsys = psys[i]; + pfr->massfac = psys[i]->part->mass; + pfr->use_size = psys[i]->part->flag & PART_SIZEMASS; + + if (tree) { + BLI_bvhtree_range_query(tree, co, interaction_radius, callback, pfr); + break; + } else { + BLI_bvhtree_range_query(psys[i]->bvhtree, co, interaction_radius, callback, pfr); + } + } +} static void sph_density_accum_cb(void *userdata, int index, float squared_dist) { SPHRangeData *pfr = (SPHRangeData *)userdata; @@ -2446,8 +2447,8 @@ static void sph_density_accum_cb(void *userdata, int index, float squared_dist) if (pfr->use_size) q *= npa->size; - pfr->density += q*q; - pfr->near_density += q*q*q; + pfr->data[0] += q*q; + pfr->data[1] += q*q*q; } /* @@ -2500,8 +2501,10 @@ static void sph_force_cb(void *sphdata_v, ParticleKey *state, float *force, floa float inv_mass = 1.0f/mass; float spring_constant = fluid->spring_k; - - float h = fluid->radius * (fluid->flag & SPH_FAC_RADIUS ? 4.f*pa->size : 1.f); /* 4.0 seems to be a pretty good value */ + + /* 4.0 seems to be a pretty good value */ + float interaction_radius = fluid->radius * (fluid->flag & SPH_FAC_RADIUS ? 4.0f * pa->size : 1.0f); + float h = interaction_radius * sphdata->hfac; float rest_density = fluid->rest_density * (fluid->flag & SPH_FAC_DENSITY ? 4.77f : 1.f); /* 4.77 is an experimentally determined density factor */ float rest_length = fluid->rest_length * (fluid->flag & SPH_FAC_REST_LENGTH ? 2.588f * pa->size : 1.f); @@ -2512,24 +2515,23 @@ static void sph_force_cb(void *sphdata_v, ParticleKey *state, float *force, floa float vec[3]; float vel[3]; float co[3]; + float data[2]; + float density, near_density; int i, spring_index, index = pa - psys[0]->particles; - pfr.tot_neighbors = 0; - pfr.density = pfr.near_density = 0.f; + data[0] = data[1] = 0; + pfr.data = data; pfr.h = h; pfr.pa = pa; - for (i=0; i<10 && psys[i]; i++) { - pfr.npsys = psys[i]; - pfr.massfac = psys[i]->part->mass*inv_mass; - pfr.use_size = psys[i]->part->flag & PART_SIZEMASS; + sph_evaluate_func( NULL, psys, state->co, &pfr, interaction_radius, sph_density_accum_cb); - BLI_bvhtree_range_query(psys[i]->bvhtree, state->co, h, sphdata->density_cb, &pfr); - } + density = data[0]; + near_density = data[1]; - pressure = stiffness * (pfr.density - rest_density); - near_pressure = stiffness_near_fac * pfr.near_density; + pressure = stiffness * (density - rest_density); + near_pressure = stiffness_near_fac * near_density; pfn = pfr.neighbors; for (i=0; ibuoyancy > 0.f && gravity) - madd_v3_v3fl(force, gravity, fluid->buoyancy * (pfr.density-rest_density)); + madd_v3_v3fl(force, gravity, fluid->buoyancy * (density-rest_density)); if (sphdata->pass == 0 && psys[0]->part->time_flag & PART_TIME_AUTOSF) sph_particle_courant(sphdata, &pfr); sphdata->pass++; } -static void sph_solver_init(ParticleSimulationData *sim, SPHData *sphdata) +/* powf is really slow for raising to integer powers. */ +MINLINE float pow2(float x) { + return x * x; +} +MINLINE float pow3(float x) { + return pow2(x) * x; +} +MINLINE float pow4(float x) { + return pow2(pow2(x)); +} +MINLINE float pow7(float x) { + return pow2(pow3(x)) * x; +} + +static void sphclassical_density_accum_cb(void *userdata, int index, float squared_dist) +{ + SPHRangeData *pfr = (SPHRangeData *)userdata; + ParticleData *npa = pfr->npsys->particles + index; + float q; + float qfac = 21.0f / (256.f * M_PI); + float rij, rij_h; + float vec[3]; + + /* Exclude particles that are more than 2h away. Can't use squared_dist here + * because it is not accurate enough. Use current state, i.e. the output of + * basic_integrate() - z0r */ + sub_v3_v3v3(vec, npa->state.co, pfr->pa->state.co); + rij = len_v3(vec); + rij_h = rij / pfr->h; + if (rij_h > 2.0f) + return; + + /* Smoothing factor. Utilise the Wendland kernel. gnuplot: + * q1(x) = (2.0 - x)**4 * ( 1.0 + 2.0 * x) + * plot [0:2] q1(x) */ + q = qfac / pow3(pfr->h) * pow4(2.0f - rij_h) * ( 1.0f + 2.0f * rij_h); + q *= pfr->massfac; + + if (pfr->use_size) + q *= pfr->pa->size; + + pfr->data[0] += q; + pfr->data[1] += q / npa->sphdensity; +} + +static void sphclassical_neighbour_accum_cb(void *userdata, int index, float squared_dist) +{ + SPHRangeData *pfr = (SPHRangeData *)userdata; + ParticleData *npa = pfr->npsys->particles + index; + float rij, rij_h; + float vec[3]; + + if (pfr->tot_neighbors >= SPH_NEIGHBORS) + return; + + /* Exclude particles that are more than 2h away. Can't use squared_dist here + * because it is not accurate enough. Use current state, i.e. the output of + * basic_integrate() - z0r */ + sub_v3_v3v3(vec, npa->state.co, pfr->pa->state.co); + rij = len_v3(vec); + rij_h = rij / pfr->h; + if (rij_h > 2.0f) + return; + + pfr->neighbors[pfr->tot_neighbors].index = index; + pfr->neighbors[pfr->tot_neighbors].psys = pfr->npsys; + pfr->tot_neighbors++; +} +static void sphclassical_force_cb(void *sphdata_v, ParticleKey *state, float *force, float *UNUSED(impulse)) +{ + SPHData *sphdata = (SPHData *)sphdata_v; + ParticleSystem **psys = sphdata->psys; + ParticleData *pa = sphdata->pa; + SPHFluidSettings *fluid = psys[0]->part->fluid; + SPHRangeData pfr; + SPHNeighbor *pfn; + float *gravity = sphdata->gravity; + + float dq, u, rij, dv[3]; + float pressure, npressure; + + float visc = fluid->viscosity_omega; + + float interaction_radius; + float h, hinv; + /* 4.77 is an experimentally determined density factor */ + float rest_density = fluid->rest_density * (fluid->flag & SPH_FAC_DENSITY ? 4.77f : 1.0f); + + float stiffness = fluid->stiffness_k; + + ParticleData *npa; + float vec[3]; + float co[3]; + float pressureTerm; + + int i; + + float qfac2 = 42.0f / (256.0f * M_PI); + float rij_h; + + /* 4.0 here is to be consistent with previous formulation/interface */ + interaction_radius = fluid->radius * (fluid->flag & SPH_FAC_RADIUS ? 4.0f * pa->size : 1.0f); + h = interaction_radius * sphdata->hfac; + hinv = 1.0f / h; + + pfr.h = h; + pfr.pa = pa; + + sph_evaluate_func(NULL, psys, state->co, &pfr, interaction_radius, sphclassical_neighbour_accum_cb); + pressure = stiffness * (pow7(pa->sphdensity / rest_density) - 1.0f); + + /* multiply by mass so that we return a force, not accel */ + qfac2 *= sphdata->mass / pow3(pfr.h); + + pfn = pfr.neighbors; + for (i = 0; i < pfr.tot_neighbors; i++, pfn++) { + npa = pfn->psys->particles + pfn->index; + if (npa == pa) { + /* we do not contribute to ourselves */ + continue; + } + + /* Find vector to neighbour. Exclude particles that are more than 2h + * away. Can't use current state here because it may have changed on + * another thread - so do own mini integration. Unlike basic_integrate, + * SPH integration depends on neighbouring particles. - z0r */ + madd_v3_v3v3fl(co, npa->prev_state.co, npa->prev_state.vel, state->time); + sub_v3_v3v3(vec, co, state->co); + rij = normalize_v3(vec); + rij_h = rij / pfr.h; + if (rij_h > 2.0f) + continue; + + npressure = stiffness * (pow7(npa->sphdensity / rest_density) - 1.0f); + + /* First derivative of smoothing factor. Utilise the Wendland kernel. + * gnuplot: + * q2(x) = 2.0 * (2.0 - x)**4 - 4.0 * (2.0 - x)**3 * (1.0 + 2.0 * x) + * plot [0:2] q2(x) + * Particles > 2h away are excluded above. */ + dq = qfac2 * (2.0f * pow4(2.0f - rij_h) - 4.0f * pow3(2.0f - rij_h) * (1.0f + 2.0f * rij_h) ); + + if (pfn->psys->part->flag & PART_SIZEMASS) + dq *= npa->size; + + pressureTerm = pressure / pow2(pa->sphdensity) + npressure / pow2(npa->sphdensity); + + /* Note that 'minus' is removed, because vec = vecBA, not vecAB. + * This applies to the viscosity calculation below, too. */ + madd_v3_v3fl(force, vec, pressureTerm * dq); + + /* Viscosity */ + if (visc > 0.0f) { + sub_v3_v3v3(dv, npa->prev_state.vel, pa->prev_state.vel); + u = dot_v3v3(vec, dv); + /* Apply parameters */ + u *= -dq * hinv * visc / (0.5f * npa->sphdensity + 0.5f * pa->sphdensity); + madd_v3_v3fl(force, vec, u); + } + } + + /* Artificial buoyancy force in negative gravity direction */ + if (fluid->buoyancy > 0.f && gravity) + madd_v3_v3fl(force, gravity, fluid->buoyancy * (pa->sphdensity - rest_density)); + + if (sphdata->pass == 0 && psys[0]->part->time_flag & PART_TIME_AUTOSF) + sph_particle_courant(sphdata, &pfr); + sphdata->pass++; +} + +static void sphclassical_calc_dens(ParticleData *pa, float UNUSED(dfra), SPHData *sphdata){ + ParticleSystem **psys = sphdata->psys; + SPHFluidSettings *fluid = psys[0]->part->fluid; + /* 4.0 seems to be a pretty good value */ + float interaction_radius = fluid->radius * (fluid->flag & SPH_FAC_RADIUS ? 4.0f * psys[0]->part->size : 1.0f); + SPHRangeData pfr; + float data[2]; + + data[0] = 0; + data[1] = 0; + pfr.data = data; + pfr.h = interaction_radius * sphdata->hfac; + pfr.pa = pa; + + sph_evaluate_func( NULL, psys, pa->state.co, &pfr, interaction_radius, sphclassical_density_accum_cb); + pa->sphdensity = MIN2(MAX2(data[0], fluid->rest_density * 0.9f), fluid->rest_density * 1.1f); +} + +void psys_sph_init(ParticleSimulationData *sim, SPHData *sphdata) { ParticleTarget *pt; int i; @@ -2621,17 +2811,44 @@ static void sph_solver_init(ParticleSimulationData *sim, SPHData *sphdata) sphdata->pa = NULL; sphdata->mass = 1.0f; - sphdata->force_cb = sph_force_cb; - sphdata->density_cb = sph_density_accum_cb; + if (sim->psys->part->fluid->solver == SPH_SOLVER_DDR) { + sphdata->force_cb = sph_force_cb; + sphdata->density_cb = sph_density_accum_cb; + sphdata->hfac = 1.0f; + } else { + /* SPH_SOLVER_CLASSICAL */ + sphdata->force_cb = sphclassical_force_cb; + sphdata->density_cb = sphclassical_density_accum_cb; + sphdata->hfac = 0.5f; + } + } -static void sph_solver_finalise(SPHData *sphdata) +void psys_sph_finalise(SPHData *sphdata) { if (sphdata->eh) { BLI_edgehash_free(sphdata->eh, NULL); sphdata->eh = NULL; } } +/* Sample the density field at a point in space. */ +void psys_sph_density(BVHTree *tree, SPHData *sphdata, float co[3], float vars[2]) { + ParticleSystem **psys = sphdata->psys; + SPHFluidSettings *fluid = psys[0]->part->fluid; + /* 4.0 seems to be a pretty good value */ + float interaction_radius = fluid->radius * (fluid->flag & SPH_FAC_RADIUS ? 4.0f * psys[0]->part->size : 1.0f); + SPHRangeData pfr; + float density[2]; + + density[0] = density[1] = 0.0f; + pfr.data = density; + pfr.h = interaction_radius*sphdata->hfac; + + sph_evaluate_func(tree, psys, co, &pfr, interaction_radius, sphdata->density_cb); + + vars[0] = pfr.data[0]; + vars[1] = pfr.data[1]; +} static void sph_integrate(ParticleSimulationData *sim, ParticleData *pa, float dfra, SPHData *sphdata) { @@ -3815,15 +4032,14 @@ static float update_timestep(ParticleSystem *psys, ParticleSimulationData *sim, else dt_target = psys->dt_frac * (psys->part->courant_target / sim->courant_num); - /* Make sure the time step is reasonable. - * For some reason, the CLAMP macro doesn't work here. The time step becomes - * too large. - z0r */ + /* Make sure the time step is reasonable. For some reason, the CLAMP macro + * doesn't work here. The time step becomes too large. - z0r */ if (dt_target < MIN_TIMESTEP) dt_target = MIN_TIMESTEP; else if (dt_target > get_base_time_step(psys->part)) dt_target = get_base_time_step(psys->part); - /* Decrease time step instantly, but expand slowly. */ + /* Decrease time step instantly, but increase slowly. */ if (dt_target > psys->dt_frac) psys->dt_frac = interpf(dt_target, psys->dt_frac, TIMESTEP_EXPANSION_FACTOR); else @@ -3991,31 +4207,71 @@ static void dynamics_step(ParticleSimulationData *sim, float cfra) case PART_PHYS_FLUID: { SPHData sphdata; - sph_solver_init(sim, &sphdata); + ParticleSettings *part = sim->psys->part; + psys_sph_init(sim, &sphdata); + + if (part->fluid->flag & SPH_SOLVER_DDR) { + /* Apply SPH forces using double-density relaxation algorithm + * (Clavat et. al.) */ + #pragma omp parallel for firstprivate (sphdata) private (pa) schedule(dynamic,5) + LOOP_DYNAMIC_PARTICLES { + /* do global forces & effectors */ + basic_integrate(sim, p, pa->state.time, cfra); + + /* actual fluids calculations */ + sph_integrate(sim, pa, pa->state.time, &sphdata); + + if(sim->colliders) + collision_check(sim, p, pa->state.time, cfra); + + /* SPH particles are not physical particles, just interpolation + * particles, thus rotation has not a direct sense for them */ + basic_rotate(part, pa, pa->state.time, timestep); + + #pragma omp critical + if (part->time_flag & PART_TIME_AUTOSF) + update_courant_num(sim, pa, dtime, &sphdata); + } + + sph_springs_modify(psys, timestep); + + } else { + /* SPH_SOLVER_CLASSICAL */ + /* Apply SPH forces using classical algorithm (due to Gingold + * and Monaghan). Note that, unlike double-density relaxation, + * this algorthim is separated into distinct loops. */ + + #pragma omp parallel for firstprivate (sphdata) private (pa) schedule(dynamic,5) + LOOP_DYNAMIC_PARTICLES { + basic_integrate(sim, p, pa->state.time, cfra); + } + + /* calculate summation density */ + #pragma omp parallel for firstprivate (sphdata) private (pa) schedule(dynamic,5) + LOOP_DYNAMIC_PARTICLES { + sphclassical_calc_dens(pa, pa->state.time, &sphdata); + } - #pragma omp parallel for firstprivate (sphdata) private (pa) schedule(dynamic,5) - LOOP_DYNAMIC_PARTICLES { /* do global forces & effectors */ - basic_integrate(sim, p, pa->state.time, cfra); + #pragma omp parallel for firstprivate (sphdata) private (pa) schedule(dynamic,5) + LOOP_DYNAMIC_PARTICLES { + /* actual fluids calculations */ + sph_integrate(sim, pa, pa->state.time, &sphdata); - /* actual fluids calculations */ - sph_integrate(sim, pa, pa->state.time, &sphdata); - - if (sim->colliders) - collision_check(sim, p, pa->state.time, cfra); + if(sim->colliders) + collision_check(sim, p, pa->state.time, cfra); - /* SPH particles are not physical particles, just interpolation - * particles, thus rotation has not a direct sense for them */ - basic_rotate(part, pa, pa->state.time, timestep); + /* SPH particles are not physical particles, just interpolation + * particles, thus rotation has not a direct sense for them */ + basic_rotate(part, pa, pa->state.time, timestep); - #pragma omp critical - if (part->time_flag & PART_TIME_AUTOSF) - update_courant_num(sim, pa, dtime, &sphdata); + #pragma omp critical + if (part->time_flag & PART_TIME_AUTOSF) + update_courant_num(sim, pa, dtime, &sphdata); + } } - sph_springs_modify(psys, timestep); - - sph_solver_finalise(&sphdata); + psys_sph_finalise(&sphdata); break; } } @@ -4325,18 +4581,16 @@ static void system_step(ParticleSimulationData *sim, float cfra) if ((int)cfra == startframe && part->sta < startframe) totframesback = (startframe - (int)part->sta); - /* Initialise time step. This may change if automatic subframes are - * enabled. */ if (!(part->time_flag & PART_TIME_AUTOSF)) { /* Constant time step */ psys->dt_frac = get_base_time_step(part); } else if ((int)cfra == startframe) { - /* Variable time step; use a very conservative value at the start. - * If it doesn't need to be so small, it will quickly grow. */ + /* Variable time step; initialise to subframes */ psys->dt_frac = get_base_time_step(part); } else if (psys->dt_frac < MIN_TIMESTEP) { + /* Variable time step; subsequent frames */ psys->dt_frac = MIN_TIMESTEP; } diff --git a/source/blender/makesdna/DNA_particle_types.h b/source/blender/makesdna/DNA_particle_types.h index 5952aa8afb0..1cf16fb52b3 100644 --- a/source/blender/makesdna/DNA_particle_types.h +++ b/source/blender/makesdna/DNA_particle_types.h @@ -116,6 +116,9 @@ typedef struct ParticleData { float size; /* size and multiplier so that we can update size when ever */ + float sphdensity; /* density of sph particle */ + int pad; + int hair_index; short flag; short alive; /* the life state of a particle */ @@ -130,6 +133,8 @@ typedef struct SPHFluidSettings { float stiffness_k, stiffness_knear, rest_density; float buoyancy; int flag, spring_frames; + short solver; + short pad[3]; } SPHFluidSettings; /* fluid->flag */ @@ -141,6 +146,10 @@ typedef struct SPHFluidSettings { #define SPH_FAC_VISCOSITY 32 #define SPH_FAC_REST_LENGTH 64 +/* fluid->solver (numerical ID field, not bitfield) */ +#define SPH_SOLVER_DDR 0 +#define SPH_SOLVER_CLASSICAL 1 + typedef struct ParticleSettings { ID id; struct AnimData *adt; diff --git a/source/blender/makesrna/intern/rna_particle.c b/source/blender/makesrna/intern/rna_particle.c index 96b6197cf69..93f940b1aa3 100644 --- a/source/blender/makesrna/intern/rna_particle.c +++ b/source/blender/makesrna/intern/rna_particle.c @@ -1112,12 +1112,25 @@ static void rna_def_fluid_settings(BlenderRNA *brna) { StructRNA *srna; PropertyRNA *prop; - + + static EnumPropertyItem sph_solver_items[] = { + {SPH_SOLVER_DDR, "DDR", 0, "Double-Density", "An artistic solver with strong surface tension effects (original)"}, + {SPH_SOLVER_CLASSICAL, "CLASSICAL", 0, "Classical", "A more physically-accurate solver"}, + {0, NULL, 0, NULL, NULL} + }; + srna = RNA_def_struct(brna, "SPHFluidSettings", NULL); RNA_def_struct_path_func(srna, "rna_SPHFluidSettings_path"); RNA_def_struct_ui_text(srna, "SPH Fluid Settings", "Settings for particle fluids physics"); - + /* Fluid settings */ + prop = RNA_def_property(srna, "solver", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_sdna(prop, NULL, "solver"); + RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); + RNA_def_property_enum_items(prop, sph_solver_items); + RNA_def_property_ui_text(prop, "SPH Solver", "The code used to calculate internal forces on particles"); + RNA_def_property_update(prop, 0, "rna_Particle_reset"); + prop = RNA_def_property(srna, "spring_force", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "spring_k"); RNA_def_property_range(prop, 0.0f, 100.0f); @@ -1186,7 +1199,7 @@ static void rna_def_fluid_settings(BlenderRNA *brna) /* Double density relaxation */ prop = RNA_def_property(srna, "stiffness", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "stiffness_k"); - RNA_def_property_range(prop, 0.0f, 100.0f); + RNA_def_property_range(prop, 0.0f, 100000.0f); RNA_def_property_ui_range(prop, 0.0f, 10.0f, 1, 3); RNA_def_property_ui_text(prop, "Stiffness", "How incompressible the fluid is"); RNA_def_property_update(prop, 0, "rna_Particle_reset"); @@ -1201,7 +1214,7 @@ static void rna_def_fluid_settings(BlenderRNA *brna) prop = RNA_def_property(srna, "rest_density", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "rest_density"); - RNA_def_property_range(prop, 0.0f, 100.0f); + RNA_def_property_range(prop, 0.0f, 10000.0f); RNA_def_property_ui_range(prop, 0.0f, 2.0f, 1, 3); RNA_def_property_ui_text(prop, "Rest Density", "Fluid rest density"); RNA_def_property_update(prop, 0, "rna_Particle_reset"); @@ -2281,7 +2294,7 @@ static void rna_def_particle_settings(BlenderRNA *brna) /* physical properties */ prop = RNA_def_property(srna, "mass", PROP_FLOAT, PROP_NONE); - RNA_def_property_range(prop, 0.001f, 100000.0f); + RNA_def_property_range(prop, 0.00000001f, 100000.0f); RNA_def_property_ui_range(prop, 0.01, 100, 1, 3); RNA_def_property_ui_text(prop, "Mass", "Mass of the particles"); RNA_def_property_update(prop, 0, "rna_Particle_reset"); From 30c365908aab12d8a51142c464db271613064e24 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 14 Dec 2012 05:27:53 +0000 Subject: [PATCH 116/252] code cleanup: minor edits to the console. --- .../editors/space_console/console_draw.c | 5 ++-- .../editors/space_console/console_intern.h | 2 +- source/blender/editors/space_info/textview.c | 27 +++++++++++-------- source/blender/editors/space_info/textview.h | 2 +- 4 files changed, 21 insertions(+), 15 deletions(-) diff --git a/source/blender/editors/space_console/console_draw.c b/source/blender/editors/space_console/console_draw.c index 5da3081df52..ba371ac3239 100644 --- a/source/blender/editors/space_console/console_draw.c +++ b/source/blender/editors/space_console/console_draw.c @@ -196,7 +196,8 @@ static int console_textview_line_color(struct TextViewContext *tvc, unsigned cha } -static int console_textview_main__internal(struct SpaceConsole *sc, ARegion *ar, int draw, int mval[2], void **mouse_pick, int *pos_pick) +static int console_textview_main__internal(struct SpaceConsole *sc, ARegion *ar, int draw, + int mval[2], void **mouse_pick, int *pos_pick) { ConsoleLine cl_dummy = {NULL}; int ret = 0; @@ -243,7 +244,7 @@ int console_textview_height(struct SpaceConsole *sc, ARegion *ar) return console_textview_main__internal(sc, ar, 0, mval, NULL, NULL); } -int console_char_pick(struct SpaceConsole *sc, ARegion *ar, int mval[2]) +int console_char_pick(struct SpaceConsole *sc, ARegion *ar, const int mval[2]) { int pos_pick = 0; void *mouse_pick = NULL; diff --git a/source/blender/editors/space_console/console_intern.h b/source/blender/editors/space_console/console_intern.h index 3d30dcad710..1e79e4b9714 100644 --- a/source/blender/editors/space_console/console_intern.h +++ b/source/blender/editors/space_console/console_intern.h @@ -37,7 +37,7 @@ struct bContext; /* console_draw.c */ void console_textview_main(struct SpaceConsole *sc, struct ARegion *ar); int console_textview_height(struct SpaceConsole *sc, struct ARegion *ar); /* needed to calculate the scrollbar */ -int console_char_pick(struct SpaceConsole *sc, struct ARegion *ar, int mval[2]); +int console_char_pick(struct SpaceConsole *sc, struct ARegion *ar, const int mval[2]); void console_scrollback_prompt_begin(struct SpaceConsole *sc, ConsoleLine *cl_dummy); void console_scrollback_prompt_end(struct SpaceConsole *sc, ConsoleLine *cl_dummy); diff --git a/source/blender/editors/space_info/textview.c b/source/blender/editors/space_info/textview.c index f2c2bbfaa71..cd7a1d785b2 100644 --- a/source/blender/editors/space_info/textview.c +++ b/source/blender/editors/space_info/textview.c @@ -62,7 +62,13 @@ typedef struct ConsoleDrawContext { int draw; } ConsoleDrawContext; -static void console_draw_sel(int sel[2], int xy[2], int str_len_draw, int cwidth, int lheight) +BLI_INLINE void console_step_sel(ConsoleDrawContext *cdc, const int step) +{ + cdc->sel[0] += step; + cdc->sel[1] += step; +} + +static void console_draw_sel(const int sel[2], const int xy[2], const int str_len_draw, int cwidth, int lheight) { if (sel[0] <= str_len_draw && sel[1] >= 0) { int sta = max_ii(sel[0], 0); @@ -85,9 +91,9 @@ static void console_draw_sel(int sel[2], int xy[2], int str_len_draw, int cwidth /* return 0 if the last line is off the screen * should be able to use this for any string type */ -static int console_draw_string(ConsoleDrawContext *cdc, const char *str, int str_len, unsigned char *fg, unsigned char *bg) +static int console_draw_string(ConsoleDrawContext *cdc, const char *str, const int str_len, + const unsigned char *fg, const unsigned char *bg) { -#define STEP_SEL(value) cdc->sel[0] += (value); cdc->sel[1] += (value) int rct_ofs = cdc->lheight / 4; int tot_lines = (str_len / cdc->console_width) + 1; /* total number of lines for wrapping */ int y_next = (str_len > cdc->console_width) ? cdc->xy[1] + cdc->lheight * tot_lines : cdc->xy[1] + cdc->lheight; @@ -121,7 +127,7 @@ static int console_draw_string(ConsoleDrawContext *cdc, const char *str, int str /* adjust selection even if not drawing */ if (cdc->sel[0] != cdc->sel[1]) { - STEP_SEL(-(str_len + 1)); + console_step_sel(cdc, -(str_len + 1)); } return 1; @@ -150,10 +156,10 @@ static int console_draw_string(ConsoleDrawContext *cdc, const char *str, int str BLF_draw(mono, line_stride, str_len - initial_offset); if (cdc->sel[0] != cdc->sel[1]) { - STEP_SEL(-initial_offset); + console_step_sel(cdc, -initial_offset); // glColor4ub(255, 0, 0, 96); // debug console_draw_sel(cdc->sel, cdc->xy, str_len % cdc->console_width, cdc->cwidth, cdc->lheight); - STEP_SEL(cdc->console_width); + console_step_sel(cdc, cdc->console_width); glColor3ubv(fg); } @@ -168,7 +174,7 @@ static int console_draw_string(ConsoleDrawContext *cdc, const char *str, int str if (cdc->sel[0] != cdc->sel[1]) { // glColor4ub(0, 255, 0, 96); // debug console_draw_sel(cdc->sel, cdc->xy, cdc->console_width, cdc->cwidth, cdc->lheight); - STEP_SEL(cdc->console_width); + console_step_sel(cdc, cdc->console_width); glColor3ubv(fg); } @@ -180,7 +186,7 @@ static int console_draw_string(ConsoleDrawContext *cdc, const char *str, int str } copy_v2_v2_int(cdc->sel, sel_orig); - STEP_SEL(-(str_len + 1)); + console_step_sel(cdc, -(str_len + 1)); } else { /* simple, no wrap */ @@ -202,7 +208,7 @@ static int console_draw_string(ConsoleDrawContext *cdc, const char *str, int str // glColor4ub(255, 255, 0, 96); // debug console_draw_sel(isel, cdc->xy, str_len, cdc->cwidth, cdc->lheight); - STEP_SEL(-(str_len + 1)); + console_step_sel(cdc, -(str_len + 1)); } cdc->xy[1] += cdc->lheight; @@ -212,13 +218,12 @@ static int console_draw_string(ConsoleDrawContext *cdc, const char *str, int str } return 1; -#undef STEP_SEL } #define CONSOLE_DRAW_MARGIN 4 #define CONSOLE_DRAW_SCROLL 16 -int textview_draw(TextViewContext *tvc, int draw, int mval[2], void **mouse_pick, int *pos_pick) +int textview_draw(TextViewContext *tvc, const int draw, int mval[2], void **mouse_pick, int *pos_pick) { ConsoleDrawContext cdc = {0}; diff --git a/source/blender/editors/space_info/textview.h b/source/blender/editors/space_info/textview.h index 33fbe556245..d0fab880dc3 100644 --- a/source/blender/editors/space_info/textview.h +++ b/source/blender/editors/space_info/textview.h @@ -54,7 +54,7 @@ typedef struct TextViewContext { } TextViewContext; -int textview_draw(struct TextViewContext *tvc, int draw, int mval[2], void **mouse_pick, int *pos_pick); +int textview_draw(struct TextViewContext *tvc, const int draw, int mval[2], void **mouse_pick, int *pos_pick); #define TVC_LINE_FG (1<<0) #define TVC_LINE_BG (1<<1) From 48661fd663ed06aa5ddbca2b4d3f1113aaa95aa0 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 14 Dec 2012 06:12:04 +0000 Subject: [PATCH 117/252] tweaks to text selection and highlight drawing. --- source/blender/editors/space_text/text_draw.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/source/blender/editors/space_text/text_draw.c b/source/blender/editors/space_text/text_draw.c index 9a448cfda13..24f40dbbe2a 100644 --- a/source/blender/editors/space_text/text_draw.c +++ b/source/blender/editors/space_text/text_draw.c @@ -1399,9 +1399,9 @@ static void draw_cursor(SpaceText *st, ARegion *ar) if (vcurl == vsell) { y -= vcurl * lheight; if (vcurc < vselc) - glRecti(x + vcurc * st->cwidth - 1, y, x + vselc * st->cwidth, y - lheight + TXT_LINE_SPACING); + glRecti(x + vcurc * st->cwidth - 1, y, x + vselc * st->cwidth, y - lheight); else - glRecti(x + vselc * st->cwidth - 1, y, x + vcurc * st->cwidth, y - lheight + TXT_LINE_SPACING); + glRecti(x + vselc * st->cwidth - 1, y, x + vcurc * st->cwidth, y - lheight); } else { int froml, fromc, tol, toc; @@ -1420,7 +1420,7 @@ static void draw_cursor(SpaceText *st, ARegion *ar) for (i = froml + 1; i < tol; i++) glRecti(x - 4, y, ar->winx, y - lheight), y -= lheight; - glRecti(x - 4, y, x + toc * st->cwidth, y - lheight + TXT_LINE_SPACING); y -= lheight; + glRecti(x - 4, y, x + toc * st->cwidth, y - lheight); y -= lheight; } } else { @@ -1445,11 +1445,11 @@ static void draw_cursor(SpaceText *st, ARegion *ar) wrap_offset_in_line(st, ar, text->sell, text->selc, &offl, &offc); y1 = ar->winy - 2 - (vsell - offl) * lheight; - y2 = y1 - lheight * visible_lines + 1; + y2 = y1 - (lheight * visible_lines + TXT_LINE_SPACING); } else { y1 = ar->winy - 2 - vsell * lheight; - y2 = y1 - lheight + 1; + y2 = y1 - (lheight + TXT_LINE_SPACING); } if (!(y1 < 0 || y2 > ar->winy)) { /* check we need to draw */ @@ -1483,7 +1483,7 @@ static void draw_cursor(SpaceText *st, ARegion *ar) } else { UI_ThemeColor(TH_HILITE); - glRecti(x - 1, y, x + 1, y - lheight + TXT_LINE_SPACING); + glRecti(x - 1, y, x + 1, y - lheight); } } } From 20846bee03ebae035120744f463c45fc741ca894 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 14 Dec 2012 08:05:56 +0000 Subject: [PATCH 118/252] correct scrollbars not working properly with DPI in the console/info view. --- source/blender/editors/include/UI_view2d.h | 1 + source/blender/editors/space_console/console_draw.c | 10 ++++------ source/blender/editors/space_info/info_draw.c | 3 ++- source/blender/editors/space_info/textview.c | 6 +++--- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/source/blender/editors/include/UI_view2d.h b/source/blender/editors/include/UI_view2d.h index 3b94291b43a..d050df5839a 100644 --- a/source/blender/editors/include/UI_view2d.h +++ b/source/blender/editors/include/UI_view2d.h @@ -132,6 +132,7 @@ struct View2DScrollers; struct wmKeyConfig; struct bScreen; +struct Scene; struct ScrArea; struct ARegion; struct bContext; diff --git a/source/blender/editors/space_console/console_draw.c b/source/blender/editors/space_console/console_draw.c index ba371ac3239..22c260de1a1 100644 --- a/source/blender/editors/space_console/console_draw.c +++ b/source/blender/editors/space_console/console_draw.c @@ -52,6 +52,7 @@ #include "UI_interface.h" #include "UI_resources.h" +#include "UI_view2d.h" #include "console_intern.h" @@ -80,9 +81,9 @@ typedef struct ConsoleDrawContext { int cwidth; int lheight; int console_width; - int winx; int ymin, ymax; #if 0 /* used by textview, may use later */ + int winx; int *xy; // [2] int *sel; // [2] int *pos_pick; /* bottom of view == 0, top of file == combine chars, end of line is lower then start. */ @@ -112,9 +113,6 @@ void console_scrollback_prompt_end(struct SpaceConsole *sc, ConsoleLine *cl_dumm } #define CONSOLE_DRAW_MARGIN 4 -#define CONSOLE_DRAW_SCROLL 16 - - /* console textview callbacks */ static int console_textview_begin(TextViewContext *tvc) @@ -222,7 +220,7 @@ static int console_textview_main__internal(struct SpaceConsole *sc, ARegion *ar, tvc.lheight = sc->lheight * UI_DPI_FAC; tvc.ymin = v2d->cur.ymin; tvc.ymax = v2d->cur.ymax; - tvc.winx = ar->winx; + tvc.winx = ar->winx - V2D_SCROLL_WIDTH; console_scrollback_prompt_begin(sc, &cl_dummy); ret = textview_draw(&tvc, draw, mval, mouse_pick, pos_pick); @@ -250,7 +248,7 @@ int console_char_pick(struct SpaceConsole *sc, ARegion *ar, const int mval[2]) void *mouse_pick = NULL; int mval_clamp[2]; - mval_clamp[0] = CLAMPIS(mval[0], CONSOLE_DRAW_MARGIN, ar->winx - (CONSOLE_DRAW_SCROLL + CONSOLE_DRAW_MARGIN)); + mval_clamp[0] = CLAMPIS(mval[0], CONSOLE_DRAW_MARGIN, ar->winx - CONSOLE_DRAW_MARGIN); mval_clamp[1] = CLAMPIS(mval[1], CONSOLE_DRAW_MARGIN, ar->winy - CONSOLE_DRAW_MARGIN); console_textview_main__internal(sc, ar, 0, mval_clamp, &mouse_pick, &pos_pick); diff --git a/source/blender/editors/space_info/info_draw.c b/source/blender/editors/space_info/info_draw.c index cd12b93c7ea..54afc9a0849 100644 --- a/source/blender/editors/space_info/info_draw.c +++ b/source/blender/editors/space_info/info_draw.c @@ -57,6 +57,7 @@ #include "UI_resources.h" #include "UI_interface.h" +#include "UI_view2d.h" #include "info_intern.h" #include "../space_info/textview.h" @@ -273,7 +274,7 @@ static int info_textview_main__internal(struct SpaceInfo *sinfo, ARegion *ar, Re tvc.lheight = 14 * UI_DPI_FAC; //sc->lheight; tvc.ymin = v2d->cur.ymin; tvc.ymax = v2d->cur.ymax; - tvc.winx = ar->winx; + tvc.winx = ar->winx - V2D_SCROLL_WIDTH; ret = textview_draw(&tvc, draw, mval, mouse_pick, pos_pick); diff --git a/source/blender/editors/space_info/textview.c b/source/blender/editors/space_info/textview.c index cd7a1d785b2..e5f8d6553ed 100644 --- a/source/blender/editors/space_info/textview.c +++ b/source/blender/editors/space_info/textview.c @@ -221,7 +221,6 @@ static int console_draw_string(ConsoleDrawContext *cdc, const char *str, const i } #define CONSOLE_DRAW_MARGIN 4 -#define CONSOLE_DRAW_SCROLL 16 int textview_draw(TextViewContext *tvc, const int draw, int mval[2], void **mouse_pick, int *pos_pick) { @@ -247,9 +246,10 @@ int textview_draw(TextViewContext *tvc, const int draw, int mval[2], void **mous cdc.cwidth = (int)BLF_fixed_width(mono); assert(cdc.cwidth > 0); cdc.lheight = tvc->lheight; - cdc.console_width = (tvc->winx - (CONSOLE_DRAW_SCROLL + CONSOLE_DRAW_MARGIN * 2) ) / cdc.cwidth; + /* note, scroll bar must be already subtracted () */ + cdc.console_width = (tvc->winx - (CONSOLE_DRAW_MARGIN * 2) ) / cdc.cwidth; CLAMP(cdc.console_width, 1, INT_MAX); /* avoid divide by zero on small windows */ - cdc.winx = tvc->winx - (CONSOLE_DRAW_MARGIN + CONSOLE_DRAW_SCROLL); + cdc.winx = tvc->winx - CONSOLE_DRAW_MARGIN; cdc.ymin = tvc->ymin; cdc.ymax = tvc->ymax; cdc.xy = xy; From 3d99ba125f74f77b4deea9a6385bcc5ffd6849b2 Mon Sep 17 00:00:00 2001 From: Jens Verwiebe Date: Fri, 14 Dec 2012 08:48:48 +0000 Subject: [PATCH 119/252] OSX/nativePixel: fix compile for OSX < 10.7 --- intern/ghost/intern/GHOST_WindowCocoa.mm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/intern/ghost/intern/GHOST_WindowCocoa.mm b/intern/ghost/intern/GHOST_WindowCocoa.mm index e044967fdef..3e967e034c4 100644 --- a/intern/ghost/intern/GHOST_WindowCocoa.mm +++ b/intern/ghost/intern/GHOST_WindowCocoa.mm @@ -578,13 +578,13 @@ GHOST_WindowCocoa::GHOST_WindowCocoa( setDrawingContextType(type); updateDrawingContext(); activateDrawingContext(); - +#if MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_7 // retina support started with 10.7.4 afaik if (m_systemCocoa->m_nativePixel) { [m_openGLView setWantsBestResolutionOpenGLSurface:YES]; NSRect backingBounds = [m_openGLView convertRectToBacking:[m_openGLView bounds]]; m_systemCocoa->m_nativePixelSize = (float)backingBounds.size.width / (float)rect.size.width; } - +#endif m_tablet.Active = GHOST_kTabletModeNone; From dbe158f0bb9f71511184629f7b8e2f3b6eb19fa9 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Fri, 14 Dec 2012 09:19:13 +0000 Subject: [PATCH 120/252] Fix #33525: Mask points are add offset for the mouse when adding on viewer node with aspect != 1 It was strange logic in code from 2010 which forced image aspect to be 1 for viewer nodes and render results. Not sure why it's needed, was only used for unwrapping aspect correction, but render result/viewer images are already handled differently there. --- source/blender/editors/space_image/image_edit.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/source/blender/editors/space_image/image_edit.c b/source/blender/editors/space_image/image_edit.c index c4e2230e7a7..261caf57c5d 100644 --- a/source/blender/editors/space_image/image_edit.c +++ b/source/blender/editors/space_image/image_edit.c @@ -194,9 +194,7 @@ void ED_space_image_get_size_fl(SpaceImage *sima, float size[2]) void ED_space_image_get_aspect(SpaceImage *sima, float *aspx, float *aspy) { Image *ima = sima->image; - if ((ima == NULL) || (ima->type == IMA_TYPE_R_RESULT) || (ima->type == IMA_TYPE_COMPOSITE) || - (ima->aspx == 0.0f || ima->aspy == 0.0f)) - { + if ((ima == NULL) || (ima->aspx == 0.0f || ima->aspy == 0.0f)) { *aspx = *aspy = 1.0; } else { From f9f53ca728a69936ef52efe794ea8367cbcc5137 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Fri, 14 Dec 2012 09:29:05 +0000 Subject: [PATCH 121/252] Fix #33526: Bezier Curve Tilt in transform panel does not work beyond 360 degrees No need to clamp tilt value in transform panel, til beyond 360 degrees works fine and clamping it in panel lead to some unexpected behavior. --- source/blender/editors/space_view3d/view3d_buttons.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/blender/editors/space_view3d/view3d_buttons.c b/source/blender/editors/space_view3d/view3d_buttons.c index 31f72def302..2d981f92af2 100644 --- a/source/blender/editors/space_view3d/view3d_buttons.c +++ b/source/blender/editors/space_view3d/view3d_buttons.c @@ -439,7 +439,7 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float uiDefButR(block, NUM, 0, "Radius", 0, yi -= buth + but_margin, 200, buth, &data_ptr, "radius", 0, 0.0, 100.0, 1, 3, NULL); uiDefButR(block, NUM, 0, "Tilt", 0, yi -= buth + but_margin, 200, buth, - &data_ptr, "tilt", 0, -M_PI * 2.0, M_PI * 2.0, 1, 3, NULL); + &data_ptr, "tilt", 0, -FLT_MAX, FLT_MAX, 1, 3, NULL); } else if (totcurvedata > 1) { uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, IFACE_("Mean Weight:"), @@ -450,7 +450,7 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float &(tfp->ve_median[C_RADIUS]), 0.0, 100.0, 1, 3, TIP_("Radius of curve control points")); but = uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, IFACE_("Mean Tilt:"), 0, yi -= buth + but_margin, 200, buth, - &(tfp->ve_median[C_TILT]), -M_PI * 2.0, M_PI * 2.0, 1, 3, + &(tfp->ve_median[C_TILT]), -FLT_MAX, FLT_MAX, 1, 3, TIP_("Tilt of curve control points")); uiButSetUnitType(but, PROP_UNIT_ROTATION); } From d38881706cdd3e52e130ccf400a609caafc3a84a Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 14 Dec 2012 09:40:32 +0000 Subject: [PATCH 122/252] add back a key to access view-cursor (alt+home) --- source/blender/editors/space_view3d/view3d_ops.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/source/blender/editors/space_view3d/view3d_ops.c b/source/blender/editors/space_view3d/view3d_ops.c index 244a886646d..19f94c1b47e 100644 --- a/source/blender/editors/space_view3d/view3d_ops.c +++ b/source/blender/editors/space_view3d/view3d_ops.c @@ -242,6 +242,8 @@ void view3d_keymap(wmKeyConfig *keyconf) WM_keymap_add_item(keymap, "VIEW3D_OT_view_center_camera", HOMEKEY, KM_PRESS, 0, 0); /* only with camera view */ + WM_keymap_add_item(keymap, "VIEW3D_OT_view_center_cursor", HOMEKEY, KM_PRESS, KM_ALT, 0); + kmi = WM_keymap_add_item(keymap, "VIEW3D_OT_view_all", HOMEKEY, KM_PRESS, 0, 0); RNA_boolean_set(kmi->ptr, "center", FALSE); /* only without camera view */ kmi = WM_keymap_add_item(keymap, "VIEW3D_OT_view_all", HOMEKEY, KM_PRESS, KM_CTRL, 0); From edabf35affb2daf07ff806bf1c0988d4ad6406cd Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Fri, 14 Dec 2012 09:47:05 +0000 Subject: [PATCH 123/252] Fix #33530: Blender Crash when selecting "Point select mode" in Particle Mode with and 0 hairs object --- source/blender/editors/space_view3d/drawobject.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c index 780b7426d51..6c58ca5a691 100644 --- a/source/blender/editors/space_view3d/drawobject.c +++ b/source/blender/editors/space_view3d/drawobject.c @@ -4657,9 +4657,11 @@ static void draw_ptcache_edit(Scene *scene, View3D *v3d, PTCacheEdit *edit) if (!(point->flag & PEP_HIDE)) totkeys += point->totkey; - if (edit->points && !(edit->points->keys->flag & PEK_USE_WCO)) - pd = pdata = MEM_callocN(totkeys * 3 * sizeof(float), "particle edit point data"); - cd = cdata = MEM_callocN(totkeys * (timed ? 4 : 3) * sizeof(float), "particle edit color data"); + if (totkeys) { + if (edit->points && !(edit->points->keys->flag & PEK_USE_WCO)) + pd = pdata = MEM_callocN(totkeys * 3 * sizeof(float), "particle edit point data"); + cd = cdata = MEM_callocN(totkeys * (timed ? 4 : 3) * sizeof(float), "particle edit color data"); + } for (i = 0, point = edit->points; i < totpoint; i++, point++) { if (point->flag & PEP_HIDE) From 4961b2a789220d783d404ac8ee5ea4d39482e858 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Fri, 14 Dec 2012 12:00:59 +0000 Subject: [PATCH 124/252] Fix #33532: vertex paint subtract mode was broken, always resulting in black. --- source/blender/editors/sculpt_paint/paint_vertex.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/source/blender/editors/sculpt_paint/paint_vertex.c b/source/blender/editors/sculpt_paint/paint_vertex.c index 90ca1a6b18a..76d666c7e27 100644 --- a/source/blender/editors/sculpt_paint/paint_vertex.c +++ b/source/blender/editors/sculpt_paint/paint_vertex.c @@ -657,11 +657,11 @@ BLI_INLINE unsigned int mcol_sub(unsigned int col1, unsigned int col2, int fac) cp = (unsigned char *)&col; temp = cp1[0] - ((fac * cp2[0]) / 255); - cp1[0] = (temp < 0) ? 0 : temp; + cp[0] = (temp < 0) ? 0 : temp; temp = cp1[1] - ((fac * cp2[1]) / 255); - cp1[1] = (temp < 0) ? 0 : temp; + cp[1] = (temp < 0) ? 0 : temp; temp = cp1[2] - ((fac * cp2[2]) / 255); - cp1[2] = (temp < 0) ? 0 : temp; + cp[2] = (temp < 0) ? 0 : temp; cp[3] = 255; return col; From 7fe2ac8e9abded2d981e0811a26821119bec42de Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Fri, 14 Dec 2012 12:06:09 +0000 Subject: [PATCH 125/252] SCons; cleanup linux-config.py from using deprecated libraries from svn This was already done for CMake and mentioning this paths in scons only messes things up. --- build_files/scons/config/linux-config.py | 47 ++++-------------------- 1 file changed, 8 insertions(+), 39 deletions(-) diff --git a/build_files/scons/config/linux-config.py b/build_files/scons/config/linux-config.py index 7ad52054bbe..f884941e07d 100644 --- a/build_files/scons/config/linux-config.py +++ b/build_files/scons/config/linux-config.py @@ -1,15 +1,5 @@ -# find library directory -import platform -import os from Modules.FindPython import FindPython -bitness = platform.architecture()[0] -if bitness == '64bit': - LCGDIR = '../lib/linux64' -else: - LCGDIR = '../lib/linux' -LIBDIR = "#${LCGDIR}" - py = FindPython() BF_PYTHON_ABI_FLAGS = py['ABI_FLAGS'] @@ -113,7 +103,7 @@ BF_QUICKTIME = '/usr/local' BF_QUICKTIME_INC = '${BF_QUICKTIME}/include' WITH_BF_ICONV = False -BF_ICONV = LIBDIR + "/iconv" +BF_ICONV = "/usr" BF_ICONV_INC = '${BF_ICONV}/include' BF_ICONV_LIB = 'iconv' BF_ICONV_LIBPATH = '${BF_ICONV}/lib' @@ -122,18 +112,7 @@ WITH_BF_BINRELOC = True # enable ffmpeg support WITH_BF_FFMPEG = True -BF_FFMPEG = LIBDIR + '/ffmpeg' -if os.path.exists(LCGDIR + '/ffmpeg'): - WITH_BF_STATICFFMPEG = True - BF_FFMPEG_LIB_STATIC = '${BF_FFMPEG_LIBPATH}/libavformat.a ${BF_FFMPEG_LIBPATH}/libswscale.a ' + \ - '${BF_FFMPEG_LIBPATH}/libavcodec.a ${BF_FFMPEG_LIBPATH}/libavdevice.a ${BF_FFMPEG_LIBPATH}/libavutil.a ' + \ - '${BF_FFMPEG_LIBPATH}/libxvidcore.a ${BF_FFMPEG_LIBPATH}/libx264.a ${BF_FFMPEG_LIBPATH}/libmp3lame.a ' + \ - '${BF_FFMPEG_LIBPATH}/libvpx.a ${BF_FFMPEG_LIBPATH}/libvorbis.a ${BF_FFMPEG_LIBPATH}/libogg.a ' + \ - '${BF_FFMPEG_LIBPATH}/libvorbisenc.a ${BF_FFMPEG_LIBPATH}/libtheora.a ' + \ - '${BF_FFMPEG_LIBPATH}/libschroedinger-1.0.a ${BF_FFMPEG_LIBPATH}/liborc-0.4.a ${BF_FFMPEG_LIBPATH}/libdirac_encoder.a ' + \ - '${BF_FFMPEG_LIBPATH}/libfaad.a' -else: - BF_FFMPEG = '/usr' +BF_FFMPEG = '/usr' BF_FFMPEG_LIB = 'avformat avcodec swscale avutil avdevice' BF_FFMPEG_INC = '${BF_FFMPEG}/include' BF_FFMPEG_LIBPATH='${BF_FFMPEG}/lib' @@ -198,34 +177,25 @@ BF_JEMALLOC_LIBPATH = '${BF_JEMALLOC}/lib' BF_JEMALLOC_LIB = 'jemalloc' BF_JEMALLOC_LIB_STATIC = '${BF_JEMALLOC_LIBPATH}/libjemalloc.a' -WITH_BF_OIIO = True +WITH_BF_OIIO = False WITH_BF_STATICOIIO = False -BF_OIIO = LIBDIR + '/oiio' -if not os.path.exists(LCGDIR + '/oiio'): - WITH_BF_OIIO = False - BF_OIIO = '/usr' +BF_OIIO = '/usr' BF_OIIO_INC = '${BF_OIIO}/include' BF_OIIO_LIB = 'OpenImageIO' BF_OIIO_LIB_STATIC = '${BF_OIIO_LIBPATH}/libOpenImageIO.a ${BF_OPENEXR}/lib/libIlmImf.a ${BF_JPEG}/lib/libjpeg.a' BF_OIIO_LIBPATH = '${BF_OIIO}/lib' -WITH_BF_OCIO = True +WITH_BF_OCIO = False WITH_BF_STATICOCIO = False -BF_OCIO = LIBDIR + '/ocio' -if not os.path.exists(LCGDIR + '/ocio'): - WITH_BF_OCIO = False - BF_OCIO = '/usr' +BF_OCIO = '/usr' BF_OCIO_INC = '${BF_OCIO}/include' BF_OCIO_LIB = 'OpenColorIO yaml-cpp tinyxml' BF_OCIO_LIB_STATIC = '${BF_OCIO_LIBPATH}/libOpenColorIO.a ${BF_OCIO_LIBPATH}/libtinyxml.a ${BF_OCIO_LIBPATH}/libyaml-cpp.a' BF_OCIO_LIBPATH = '${BF_OCIO}/lib' -WITH_BF_BOOST = True +WITH_BF_BOOST = False WITH_BF_STATICBOOST = False -BF_BOOST = LIBDIR + '/boost' -if not os.path.exists(LCGDIR + '/boost'): - WITH_BF_BOOST = False - BF_BOOST = '/usr' +BF_BOOST = '/usr' BF_BOOST_INC = '${BF_BOOST}/include' BF_BOOST_LIB = 'boost_date_time boost_filesystem boost_regex boost_system boost_thread' BF_BOOST_LIB_STATIC = '${BF_BOOST_LIBPATH}/libboost_filesystem.a ${BF_BOOST_LIBPATH}/libboost_date_time.a ' + \ @@ -306,4 +276,3 @@ PLATFORM_LINKFLAGS = ['-pthread'] #Fix for LLVM conflict with Mesa llvmpipe if WITH_BF_LLVM: PLATFORM_LINKFLAGS += ['-Wl,--version-script=source/creator/blender.map'] - From e00e649063d3eedc4230b807eb12e049e882513f Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Fri, 14 Dec 2012 12:06:24 +0000 Subject: [PATCH 126/252] SCons: clean up code which was commented out since 2007 --- build_files/scons/config/linux-config.py | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/build_files/scons/config/linux-config.py b/build_files/scons/config/linux-config.py index f884941e07d..0185c2dd783 100644 --- a/build_files/scons/config/linux-config.py +++ b/build_files/scons/config/linux-config.py @@ -228,8 +228,6 @@ BF_3DMOUSE_LIB_STATIC = '${BF_3DMOUSE_LIBPATH}/libspnav.a' ## CC = 'gcc' CXX = 'g++' -##ifeq ($CPU),alpha) -## CFLAGS += -pipe -fPIC -funsigned-char -fno-strict-aliasing -mieee CCFLAGS = ['-pipe','-fPIC','-funsigned-char','-fno-strict-aliasing','-D_LARGEFILE_SOURCE', '-D_FILE_OFFSET_BITS=64','-D_LARGEFILE64_SOURCE'] CXXFLAGS = [] @@ -243,22 +241,12 @@ if WITH_BF_FFMPEG: REL_CFLAGS = [] REL_CXXFLAGS = [] REL_CCFLAGS = ['-DNDEBUG', '-O2'] -##BF_DEPEND = True -## -##AR = ar -##ARFLAGS = ruv -##ARFLAGSQUIET = ru -## + C_WARN = ['-Wno-char-subscripts', '-Wdeclaration-after-statement', '-Wunused-parameter', '-Wstrict-prototypes', '-Werror=declaration-after-statement', '-Werror=implicit-function-declaration', '-Werror=return-type'] CC_WARN = ['-Wall'] CXX_WARN = ['-Wno-invalid-offsetof', '-Wno-sign-compare'] - -##FIX_STUBS_WARNINGS = -Wno-unused - LLIBS = ['util', 'c', 'm', 'dl', 'pthread', 'stdc++'] -##LOPTS = --dynamic -##DYNLDFLAGS = -shared $(LDFLAGS) BF_PROFILE = False BF_PROFILE_CCFLAGS = ['-pg','-g'] From fec6b9d89d45b08bcdea639760f77edf17b99dc3 Mon Sep 17 00:00:00 2001 From: Thomas Dinges Date: Fri, 14 Dec 2012 14:59:16 +0000 Subject: [PATCH 127/252] Blender Internal / Texture UI: * Ocean Texture was not in alphabetical order. --- source/blender/makesrna/intern/rna_texture.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/makesrna/intern/rna_texture.c b/source/blender/makesrna/intern/rna_texture.c index bdf9fa4e436..e116e5df0de 100644 --- a/source/blender/makesrna/intern/rna_texture.c +++ b/source/blender/makesrna/intern/rna_texture.c @@ -71,12 +71,12 @@ EnumPropertyItem texture_type_items[] = { {TEX_MUSGRAVE, "MUSGRAVE", ICON_TEXTURE, "Musgrave", "Procedural - highly flexible fractal noise texture"}, {TEX_NOISE, "NOISE", ICON_TEXTURE, "Noise", "Procedural - random noise, gives a different result every time, for every frame, for every pixel"}, + {TEX_OCEAN, "OCEAN", ICON_TEXTURE, "Ocean", "Use a texture generated by an Ocean modifier"}, {TEX_POINTDENSITY, "POINT_DENSITY", ICON_TEXTURE, "Point Density", ""}, {TEX_STUCCI, "STUCCI", ICON_TEXTURE, "Stucci", "Procedural - create a fractal noise texture"}, {TEX_VORONOI, "VORONOI", ICON_TEXTURE, "Voronoi", "Procedural - create cell-like patterns based on Worley noise"}, {TEX_VOXELDATA, "VOXEL_DATA", ICON_TEXTURE, "Voxel Data", "Create a 3D texture based on volumetric data"}, {TEX_WOOD, "WOOD", ICON_TEXTURE, "Wood", "Procedural - wave generated bands or rings, with optional noise"}, - {TEX_OCEAN, "OCEAN", ICON_TEXTURE, "Ocean", "Use a texture generated by an Ocean modifier"}, {0, NULL, 0, NULL, NULL} }; From 0990c84f3f31d34eedd3cd72b0e706e9d80ffdf9 Mon Sep 17 00:00:00 2001 From: Ton Roosendaal Date: Fri, 14 Dec 2012 15:09:59 +0000 Subject: [PATCH 128/252] Fixes for correct UI scaling display: - Move to layer (and more popups) didn't scale yet - User Prefs and render window now open on right location on Mac Retinas - Brush sizes for painting now scale for Mac Retina --- source/blender/blenkernel/intern/brush.c | 7 ++-- .../blender/editors/physics/particle_edit.c | 34 ++++++++++++------- source/blender/editors/render/render_view.c | 8 +++-- source/blender/editors/screen/screen_ops.c | 5 +-- .../windowmanager/intern/wm_operators.c | 4 +-- 5 files changed, 37 insertions(+), 21 deletions(-) diff --git a/source/blender/blenkernel/intern/brush.c b/source/blender/blenkernel/intern/brush.c index f310895f590..3e5dee5b0de 100644 --- a/source/blender/blenkernel/intern/brush.c +++ b/source/blender/blenkernel/intern/brush.c @@ -39,6 +39,7 @@ #include "DNA_color_types.h" #include "DNA_scene_types.h" #include "DNA_object_types.h" +#include "DNA_userdef_types.h" #include "DNA_windowmanager_types.h" #include "WM_types.h" @@ -51,6 +52,7 @@ #include "BLI_rand.h" #include "BLI_utildefines.h" +#include "BKE_blender.h" #include "BKE_brush.h" #include "BKE_colortools.h" #include "BKE_global.h" @@ -644,8 +646,9 @@ void BKE_brush_size_set(Scene *scene, Brush *brush, int size) int BKE_brush_size_get(const Scene *scene, Brush *brush) { UnifiedPaintSettings *ups = &scene->toolsettings->unified_paint_settings; - - return (ups->flag & UNIFIED_PAINT_SIZE) ? ups->size : brush->size; + int size = (ups->flag & UNIFIED_PAINT_SIZE) ? ups->size : brush->size; + + return (int)((float)size * U.pixelsize); } int BKE_brush_use_locked_size(const Scene *scene, Brush *brush) diff --git a/source/blender/editors/physics/particle_edit.c b/source/blender/editors/physics/particle_edit.c index 6a56a5fdb33..30508a793ae 100644 --- a/source/blender/editors/physics/particle_edit.c +++ b/source/blender/editors/physics/particle_edit.c @@ -53,10 +53,9 @@ #include "BLI_rand.h" #include "BLI_utildefines.h" -#include "BKE_DerivedMesh.h" -#include "BKE_depsgraph.h" - #include "BKE_context.h" +#include "BKE_depsgraph.h" +#include "BKE_DerivedMesh.h" #include "BKE_global.h" #include "BKE_object.h" #include "BKE_mesh.h" @@ -193,6 +192,16 @@ ParticleEditSettings *PE_settings(Scene *scene) return scene->toolsettings ? &scene->toolsettings->particle : NULL; } +static float pe_brush_size_get(const Scene *UNUSED(scene), ParticleBrushData *brush) +{ + // here we can enable unified brush size, needs more work... + // UnifiedPaintSettings *ups = &scene->toolsettings->unified_paint_settings; + // float size = (ups->flag & UNIFIED_PAINT_SIZE) ? ups->size : brush->size; + + return brush->size * U.pixelsize; +} + + /* always gets at least the first particlesystem even if PSYS_CURRENT flag is not set * * note: this function runs on poll, therefor it can runs many times a second @@ -2500,7 +2509,8 @@ void PARTICLE_OT_weight_set(wmOperatorType *ot) static void brush_drawcursor(bContext *C, int x, int y, void *UNUSED(customdata)) { - ParticleEditSettings *pset= PE_settings(CTX_data_scene(C)); + Scene *scene = CTX_data_scene(C); + ParticleEditSettings *pset= PE_settings(scene); ParticleBrushData *brush; if (pset->brushtype < 0) @@ -2516,7 +2526,7 @@ static void brush_drawcursor(bContext *C, int x, int y, void *UNUSED(customdata) glColor4ub(255, 255, 255, 128); glEnable(GL_LINE_SMOOTH); glEnable(GL_BLEND); - glutil_draw_lined_arc(0.0, M_PI*2.0, brush->size, 40); + glutil_draw_lined_arc(0.0, M_PI*2.0, pe_brush_size_get(scene, brush), 40); glDisable(GL_BLEND); glDisable(GL_LINE_SMOOTH); @@ -3535,7 +3545,7 @@ static void brush_edit_apply(bContext *C, wmOperator *op, PointerRNA *itemptr) selected= (short)count_selected_keys(scene, edit); dmax = max_ff(fabsf(dx), fabsf(dy)); - tot_steps = dmax/(0.2f * brush->size) + 1; + tot_steps = dmax/(0.2f * pe_brush_size_get(scene, brush)) + 1; dx /= (float)tot_steps; dy /= (float)tot_steps; @@ -3549,7 +3559,7 @@ static void brush_edit_apply(bContext *C, wmOperator *op, PointerRNA *itemptr) { const float mval_f[2] = {dx, dy}; data.mval= mval; - data.rad= (float)brush->size; + data.rad= pe_brush_size_get(scene, brush); data.combfac= (brush->strength - 0.5f) * 2.0f; if (data.combfac < 0.0f) @@ -3569,7 +3579,7 @@ static void brush_edit_apply(bContext *C, wmOperator *op, PointerRNA *itemptr) { if (edit->psys && edit->pathcache) { data.mval= mval; - data.rad= (float)brush->size; + data.rad= pe_brush_size_get(scene, brush); data.cutfac= brush->strength; if (selected) @@ -3590,7 +3600,7 @@ static void brush_edit_apply(bContext *C, wmOperator *op, PointerRNA *itemptr) { data.mval= mval; - data.rad= (float)brush->size; + data.rad= pe_brush_size_get(scene, brush); data.growfac= brush->strength / 50.0f; if (brush->invert ^ flip) @@ -3609,7 +3619,7 @@ static void brush_edit_apply(bContext *C, wmOperator *op, PointerRNA *itemptr) if (edit->psys) { data.dm= psmd->dm; data.mval= mval; - data.rad= (float)brush->size; + data.rad= pe_brush_size_get(scene, brush); data.select= selected; data.pufffac= (brush->strength - 0.5f) * 2.0f; @@ -3642,7 +3652,7 @@ static void brush_edit_apply(bContext *C, wmOperator *op, PointerRNA *itemptr) case PE_BRUSH_SMOOTH: { data.mval= mval; - data.rad= (float)brush->size; + data.rad= pe_brush_size_get(scene, brush); data.vec[0] = data.vec[1] = data.vec[2] = 0.0f; data.tot= 0; @@ -3665,7 +3675,7 @@ static void brush_edit_apply(bContext *C, wmOperator *op, PointerRNA *itemptr) if (edit->psys) { data.dm= psmd->dm; data.mval= mval; - data.rad= (float)brush->size; + data.rad= pe_brush_size_get(scene, brush); data.weightfac = brush->strength; /* note that this will never be zero */ diff --git a/source/blender/editors/render/render_view.c b/source/blender/editors/render/render_view.c index 5ec7f4d05b6..f15f7b539f3 100644 --- a/source/blender/editors/render/render_view.c +++ b/source/blender/editors/render/render_view.c @@ -35,6 +35,7 @@ #include "BLI_utildefines.h" #include "DNA_scene_types.h" +#include "DNA_userdef_types.h" #include "BKE_blender.h" #include "BKE_context.h" @@ -151,9 +152,10 @@ void render_view_open(bContext *C, int mx, int my) if (sizex < 320) sizex = 320; if (sizey < 256) sizey = 256; - /* XXX some magic to calculate postition */ - rect.xmin = mx + win->posx - sizex / 2; - rect.ymin = my + win->posy - sizey / 2; + /* some magic to calculate postition */ + /* pixelsize: mouse coords are in U.pixelsize units :/ */ + rect.xmin = (mx / U.pixelsize) + win->posx - sizex / 2; + rect.ymin = (my / U.pixelsize) + win->posy - sizey / 2; rect.xmax = rect.xmin + sizex; rect.ymax = rect.ymin + sizey; diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c index 807c5a4c457..d819176e542 100644 --- a/source/blender/editors/screen/screen_ops.c +++ b/source/blender/editors/screen/screen_ops.c @@ -3419,8 +3419,9 @@ static int userpref_show_invoke(bContext *C, wmOperator *UNUSED(op), wmEvent *ev sizey = 480; /* some magic to calculate postition */ - rect.xmin = event->x + CTX_wm_window(C)->posx - sizex / 2; - rect.ymin = event->y + CTX_wm_window(C)->posy - sizey / 2; + /* pixelsize: mouse coords are in U.pixelsize units :/ */ + rect.xmin = (event->x / U.pixelsize) + CTX_wm_window(C)->posx - sizex / 2; + rect.ymin = (event->y / U.pixelsize) + CTX_wm_window(C)->posy - sizey / 2; rect.xmax = rect.xmin + sizex; rect.ymax = rect.ymin + sizey; diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c index a5ed337c3d8..ebb9e6662e6 100644 --- a/source/blender/windowmanager/intern/wm_operators.c +++ b/source/blender/windowmanager/intern/wm_operators.c @@ -1079,7 +1079,7 @@ static uiBlock *wm_block_create_redo(bContext *C, ARegion *ar, void *arg_op) uiBlock *block; uiLayout *layout; uiStyle *style = UI_GetStyle(); - int width = 300; + int width = 15 * UI_UNIT_X; block = uiBeginBlock(C, ar, __func__, UI_EMBOSS); uiBlockClearFlag(block, UI_BLOCK_LOOP); @@ -1263,7 +1263,7 @@ static int wm_operator_props_popup_ex(bContext *C, wmOperator *op, const int do_ /* if we don't have global undo, we can't do undo push for automatic redo, * so we require manual OK clicking in this popup */ if (!(U.uiflag & USER_GLOBALUNDO)) - return WM_operator_props_dialog_popup(C, op, 300, UI_UNIT_Y); + return WM_operator_props_dialog_popup(C, op, 15 * UI_UNIT_X, UI_UNIT_Y); uiPupBlock(C, wm_block_create_redo, op); From 16003d27385f2a4ce3c5b34681ceda8c0cc33553 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 14 Dec 2012 15:17:53 +0000 Subject: [PATCH 129/252] commands to convert svg-to-png as shell scripts (just for convenience), and center prvicons.svg so the resulting image is sized properly. --- release/datafiles/blender_icons.sh | 4 + release/datafiles/prvicons.sh | 4 + release/datafiles/prvicons.svg | 327 +++++++---------------------- 3 files changed, 81 insertions(+), 254 deletions(-) create mode 100755 release/datafiles/blender_icons.sh create mode 100755 release/datafiles/prvicons.sh diff --git a/release/datafiles/blender_icons.sh b/release/datafiles/blender_icons.sh new file mode 100755 index 00000000000..0bce9be6b8b --- /dev/null +++ b/release/datafiles/blender_icons.sh @@ -0,0 +1,4 @@ +#!/bin/sh +# This script updates icons from the SVG file + +inkscape blender_icons.svg --without-gui --export-png=blender_icons.png diff --git a/release/datafiles/prvicons.sh b/release/datafiles/prvicons.sh new file mode 100755 index 00000000000..144dd9da362 --- /dev/null +++ b/release/datafiles/prvicons.sh @@ -0,0 +1,4 @@ +#!/bin/sh +# This script updates icons from the SVG file + +inkscape prvicons.svg --without-gui --export-png=prvicons.png diff --git a/release/datafiles/prvicons.svg b/release/datafiles/prvicons.svg index 2e77cd6e62a..d373410db73 100644 --- a/release/datafiles/prvicons.svg +++ b/release/datafiles/prvicons.svg @@ -10,8 +10,8 @@ xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" - width="602" - height="640" + width="192" + height="192" id="svg2" sodipodi:version="0.32" inkscape:version="0.48.3.1 r9886" @@ -949,7 +949,8 @@ sodipodi:nodetypes="cccccc" inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png" inkscape:export-xdpi="90" - inkscape:export-ydpi="90" /> + inkscape:export-ydpi="90" + inkscape:connector-curvature="0" /> @@ -1281,19 +1282,6 @@ y1="323" x2="337.80573" y2="337.517" /> - - - @@ -1597,7 +1585,8 @@ + id="path17190" + inkscape:connector-curvature="0" /> @@ -2577,19 +2566,6 @@ offset="1" id="stop14236" /> - - - - - - + id="path17572" + inkscape:connector-curvature="0" /> + id="path18636" + inkscape:connector-curvature="0" /> - - - - - - - - - - - - + sodipodi:nodetypes="cccccccc" + inkscape:connector-curvature="0" /> + inkscape:transform-center-x="4" + inkscape:connector-curvature="0" /> + style="fill:url(#linearGradient25383);fill-rule:evenodd;stroke:none" + inkscape:connector-curvature="0" /> + style="fill:url(#linearGradient25385);fill-rule:evenodd;stroke:none" + inkscape:connector-curvature="0" /> + style="fill:url(#linearGradient25387);fill-rule:evenodd;stroke:none" + inkscape:connector-curvature="0" /> + style="fill:url(#linearGradient25573);fill-rule:evenodd;stroke:none" + inkscape:connector-curvature="0" /> + inkscape:transform-center-y="-4" + inkscape:connector-curvature="0" /> + inkscape:transform-center-x="-4" + inkscape:connector-curvature="0" /> + inkscape:transform-center-y="4" + inkscape:connector-curvature="0" /> + sodipodi:nodetypes="cccccc" + inkscape:connector-curvature="0" /> - - - - - - - - - - - - - - - - - - - - - + sodipodi:nodetypes="cccccc" + inkscape:connector-curvature="0" /> - - - + style="opacity:0.2;fill:#3771c8;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:3.0999999;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + inkscape:connector-curvature="0" /> + id="path28966" + inkscape:connector-curvature="0" /> + inkscape:export-ydpi="90" + inkscape:connector-curvature="0" /> + style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;color:#000000;fill:#ff0000;fill-opacity:1;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Bitstream Vera Sans;-inkscape-font-specification:Bitstream Vera Sans" + inkscape:connector-curvature="0" /> - - - + units="px" + inkscape:snap-center="false" + fit-margin-top="0" + fit-margin-left="0" + fit-margin-right="0" + fit-margin-bottom="0"> + originy="0px" /> @@ -17739,8 +17554,9 @@ inkscape:groupmode="layer" id="layer3" inkscape:label="bckgrnd" - style="display:inline" - sodipodi:insensitive="true"> + style="display:none" + sodipodi:insensitive="true" + transform="translate(-872,-180)"> + d="" + inkscape:connector-curvature="0" /> + d="" + inkscape:connector-curvature="0" /> + style="display:inline" + transform="translate(-872,-180)"> @@ -18851,7 +18670,7 @@ transform="matrix(1.1428564,0,0,1.2000001,822.71436,-355.40005)"> @@ -18889,13 +18708,13 @@ sodipodi:cy="554" sodipodi:rx="4.5" sodipodi:ry="2.25" - d="m 57.5,554 a 4.5,2.25 0 1 1 -9,0 4.5,2.25 0 1 1 9,0 z" + d="m 57.5,554 c 0,1.24264 -2.014719,2.25 -4.5,2.25 -2.485281,0 -4.5,-1.00736 -4.5,-2.25 0,-1.24264 2.014719,-2.25 4.5,-2.25 2.485281,0 4.5,1.00736 4.5,2.25 z" transform="matrix(0.7630859,-0.2494396,0.2996015,0.9926766,-151.92281,17.77746)" /> @@ -19074,7 +18893,7 @@ inkscape:export-ydpi="90" inkscape:export-xdpi="90" inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png" - d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z" + d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z" sodipodi:ry="8" sodipodi:rx="8" sodipodi:cy="118" @@ -19108,7 +18927,7 @@ inkscape:export-ydpi="90" inkscape:export-xdpi="90" inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png" - d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z" + d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z" sodipodi:ry="8" sodipodi:rx="8" sodipodi:cy="118" @@ -19228,7 +19047,7 @@ transform="matrix(0.5406242,0,0,0.5829534,814.13667,247.65542)"> + d="m 923,342 c 0,0.55228 -0.44772,1 -1,1 -0.55228,0 -1,-0.44772 -1,-1 0,-0.55228 0.44772,-1 1,-1 0.55228,0 1,0.44772 1,1 z" /> Date: Fri, 14 Dec 2012 15:26:49 +0000 Subject: [PATCH 130/252] Cycles: make "Open Shading Language" a boolean toggle, the other option "GPU Compatible" was confusing. --- intern/cycles/blender/addon/properties.py | 13 +++---------- intern/cycles/blender/blender_sync.cpp | 4 ++-- 2 files changed, 5 insertions(+), 12 deletions(-) diff --git a/intern/cycles/blender/addon/properties.py b/intern/cycles/blender/addon/properties.py index ae4b7e3cc92..26fc7a81936 100644 --- a/intern/cycles/blender/addon/properties.py +++ b/intern/cycles/blender/addon/properties.py @@ -36,11 +36,6 @@ enum_feature_set = ( ('EXPERIMENTAL', "Experimental", "Use experimental and incomplete features that might be broken or change in the future"), ) -enum_shading_systems = ( - ('GPU_COMPATIBLE', "GPU Compatible", "Restricted shading system compatible with GPU rendering"), - ('OSL', "Open Shading Language", "Open Shading Language shading system that only runs on the CPU"), - ) - enum_displacement_methods = ( ('BUMP', "Bump", "Bump mapping to simulate the appearance of displacement"), ('TRUE', "True", "Use true displacement only, requires fine subdivision"), @@ -89,11 +84,9 @@ class CyclesRenderSettings(bpy.types.PropertyGroup): items=enum_feature_set, default='SUPPORTED', ) - cls.shading_system = EnumProperty( - name="Shading System", - description="Shading system to use for rendering", - items=enum_shading_systems, - default='GPU_COMPATIBLE', + cls.shading_system = BoolProperty( + name="Open Shading Language", + description="Use Open Shading Language (CPU rendering only)", ) cls.progressive = BoolProperty( diff --git a/intern/cycles/blender/blender_sync.cpp b/intern/cycles/blender/blender_sync.cpp index d0e8b508df6..e78026e7ae1 100644 --- a/intern/cycles/blender/blender_sync.cpp +++ b/intern/cycles/blender/blender_sync.cpp @@ -289,7 +289,7 @@ SceneParams BlenderSync::get_scene_params(BL::Scene b_scene, bool background) BL::RenderSettings r = b_scene.render(); SceneParams params; PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles"); - int shadingsystem = RNA_enum_get(&cscene, "shading_system"); + int shadingsystem = RNA_boolean_get(&cscene, "shading_system"); if(shadingsystem == 0) params.shadingsystem = SceneParams::SVM; @@ -414,7 +414,7 @@ SessionParams BlenderSync::get_session_params(BL::RenderEngine b_engine, BL::Use params.progressive = true; /* shading system - scene level needs full refresh */ - int shadingsystem = RNA_enum_get(&cscene, "shading_system"); + int shadingsystem = RNA_boolean_get(&cscene, "shading_system"); if(shadingsystem == 0) params.shadingsystem = SessionParams::SVM; From e5407ef8d9fc0973089b2ac69e418179b99bfa18 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 14 Dec 2012 16:09:31 +0000 Subject: [PATCH 131/252] workaround for ndof events showing in view3d menu items. (add before other keys, eventually we may want to have some kind of priority here) --- .../blender/editors/space_view3d/view3d_ops.c | 37 +++++++------------ 1 file changed, 13 insertions(+), 24 deletions(-) diff --git a/source/blender/editors/space_view3d/view3d_ops.c b/source/blender/editors/space_view3d/view3d_ops.c index 19f94c1b47e..fb9bfc4a7d9 100644 --- a/source/blender/editors/space_view3d/view3d_ops.c +++ b/source/blender/editors/space_view3d/view3d_ops.c @@ -189,12 +189,24 @@ void view3d_keymap(wmKeyConfig *keyconf) keymap = WM_keymap_find(keyconf, "3D View Generic", SPACE_VIEW3D, 0); + /* 3D mouse align */ + /* note: positioned here so keymaps show keyboard keys if assigned */ + kmi = WM_keymap_add_item(keymap, "VIEW3D_OT_viewnumpad", NDOF_BUTTON_FRONT, KM_PRESS, KM_SHIFT, 0); + RNA_enum_set(kmi->ptr, "type", RV3D_VIEW_FRONT); + RNA_boolean_set(kmi->ptr, "align_active", TRUE); + kmi = WM_keymap_add_item(keymap, "VIEW3D_OT_viewnumpad", NDOF_BUTTON_RIGHT, KM_PRESS, KM_SHIFT, 0); + RNA_enum_set(kmi->ptr, "type", RV3D_VIEW_RIGHT); + RNA_boolean_set(kmi->ptr, "align_active", TRUE); + kmi = WM_keymap_add_item(keymap, "VIEW3D_OT_viewnumpad", NDOF_BUTTON_TOP, KM_PRESS, KM_SHIFT, 0); + RNA_enum_set(kmi->ptr, "type", RV3D_VIEW_TOP); + RNA_boolean_set(kmi->ptr, "align_active", TRUE); + WM_keymap_add_item(keymap, "VIEW3D_OT_properties", NKEY, KM_PRESS, 0, 0); WM_keymap_add_item(keymap, "VIEW3D_OT_toolshelf", TKEY, KM_PRESS, 0, 0); /* only for region 3D window */ keymap = WM_keymap_find(keyconf, "3D View", SPACE_VIEW3D, 0); - + kmi = WM_keymap_verify_item(keymap, "VIEW3D_OT_manipulator", LEFTMOUSE, KM_PRESS, KM_ANY, 0); RNA_boolean_set(kmi->ptr, "release_confirm", TRUE); /* @@ -300,29 +312,6 @@ void view3d_keymap(wmKeyConfig *keyconf) kmi = WM_keymap_add_item(keymap, "VIEW3D_OT_viewnumpad", PAD7, KM_PRESS, KM_SHIFT | KM_CTRL, 0); RNA_enum_set(kmi->ptr, "type", RV3D_VIEW_BOTTOM); RNA_boolean_set(kmi->ptr, "align_active", TRUE); - - /* 3D mouse */ - WM_keymap_add_item(keymap, "VIEW3D_OT_ndof_orbit", NDOF_MOTION, 0, KM_CTRL, 0); - WM_keymap_add_item(keymap, "VIEW3D_OT_ndof_pan", NDOF_MOTION, 0, KM_SHIFT, 0); - WM_keymap_add_item(keymap, "VIEW3D_OT_ndof_all", NDOF_MOTION, 0, 0, 0); - WM_keymap_add_item(keymap, "VIEW3D_OT_view_selected", NDOF_BUTTON_FIT, KM_PRESS, 0, 0); - RNA_enum_set(WM_keymap_add_item(keymap, "VIEW3D_OT_viewnumpad", NDOF_BUTTON_FRONT, KM_PRESS, 0, 0)->ptr, "type", RV3D_VIEW_FRONT); - RNA_enum_set(WM_keymap_add_item(keymap, "VIEW3D_OT_viewnumpad", NDOF_BUTTON_BACK, KM_PRESS, 0, 0)->ptr, "type", RV3D_VIEW_BACK); - RNA_enum_set(WM_keymap_add_item(keymap, "VIEW3D_OT_viewnumpad", NDOF_BUTTON_LEFT, KM_PRESS, 0, 0)->ptr, "type", RV3D_VIEW_LEFT); - RNA_enum_set(WM_keymap_add_item(keymap, "VIEW3D_OT_viewnumpad", NDOF_BUTTON_RIGHT, KM_PRESS, 0, 0)->ptr, "type", RV3D_VIEW_RIGHT); - RNA_enum_set(WM_keymap_add_item(keymap, "VIEW3D_OT_viewnumpad", NDOF_BUTTON_TOP, KM_PRESS, 0, 0)->ptr, "type", RV3D_VIEW_TOP); - RNA_enum_set(WM_keymap_add_item(keymap, "VIEW3D_OT_viewnumpad", NDOF_BUTTON_BOTTOM, KM_PRESS, 0, 0)->ptr, "type", RV3D_VIEW_BOTTOM); - - /* 3D mouse align */ - kmi = WM_keymap_add_item(keymap, "VIEW3D_OT_viewnumpad", NDOF_BUTTON_FRONT, KM_PRESS, KM_SHIFT, 0); - RNA_enum_set(kmi->ptr, "type", RV3D_VIEW_FRONT); - RNA_boolean_set(kmi->ptr, "align_active", TRUE); - kmi = WM_keymap_add_item(keymap, "VIEW3D_OT_viewnumpad", NDOF_BUTTON_RIGHT, KM_PRESS, KM_SHIFT, 0); - RNA_enum_set(kmi->ptr, "type", RV3D_VIEW_RIGHT); - RNA_boolean_set(kmi->ptr, "align_active", TRUE); - kmi = WM_keymap_add_item(keymap, "VIEW3D_OT_viewnumpad", NDOF_BUTTON_TOP, KM_PRESS, KM_SHIFT, 0); - RNA_enum_set(kmi->ptr, "type", RV3D_VIEW_TOP); - RNA_boolean_set(kmi->ptr, "align_active", TRUE); WM_keymap_add_item(keymap, "VIEW3D_OT_localview", PADSLASHKEY, KM_PRESS, 0, 0); From bb26d80ad88236800607bed0b0a72a5d14f67bb9 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 14 Dec 2012 16:10:46 +0000 Subject: [PATCH 132/252] code cleanup and move alternate shell calculation method into its own function: BM_vert_calc_shell_factor_ex --- .../blenkernel/intern/particle_system.c | 8 ++--- source/blender/bmesh/intern/bmesh_queries.c | 34 ++++++++++++++++++ source/blender/bmesh/intern/bmesh_queries.h | 1 + source/blender/editors/screen/screen_ops.c | 11 +++--- .../editors/transform/transform_conversions.c | 36 +------------------ 5 files changed, 47 insertions(+), 43 deletions(-) diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c index 7c95265b27b..037864c7e38 100644 --- a/source/blender/blenkernel/intern/particle_system.c +++ b/source/blender/blenkernel/intern/particle_system.c @@ -2616,12 +2616,12 @@ MINLINE float pow7(float x) { return pow2(pow3(x)) * x; } -static void sphclassical_density_accum_cb(void *userdata, int index, float squared_dist) +static void sphclassical_density_accum_cb(void *userdata, int index, float UNUSED(squared_dist)) { SPHRangeData *pfr = (SPHRangeData *)userdata; ParticleData *npa = pfr->npsys->particles + index; float q; - float qfac = 21.0f / (256.f * M_PI); + float qfac = 21.0f / (256.f * (float)M_PI); float rij, rij_h; float vec[3]; @@ -2647,7 +2647,7 @@ static void sphclassical_density_accum_cb(void *userdata, int index, float squar pfr->data[1] += q / npa->sphdensity; } -static void sphclassical_neighbour_accum_cb(void *userdata, int index, float squared_dist) +static void sphclassical_neighbour_accum_cb(void *userdata, int index, float UNUSED(squared_dist)) { SPHRangeData *pfr = (SPHRangeData *)userdata; ParticleData *npa = pfr->npsys->particles + index; @@ -2699,7 +2699,7 @@ static void sphclassical_force_cb(void *sphdata_v, ParticleKey *state, float *fo int i; - float qfac2 = 42.0f / (256.0f * M_PI); + float qfac2 = 42.0f / (256.0f * (float)M_PI); float rij_h; /* 4.0 here is to be consistent with previous formulation/interface */ diff --git a/source/blender/bmesh/intern/bmesh_queries.c b/source/blender/bmesh/intern/bmesh_queries.c index 633c715f257..5f5c60dde3f 100644 --- a/source/blender/bmesh/intern/bmesh_queries.c +++ b/source/blender/bmesh/intern/bmesh_queries.c @@ -1113,6 +1113,40 @@ float BM_vert_calc_shell_factor(BMVert *v) return 1.0f; } } +/* alternate version of #BM_vert_calc_shell_factor which only + * uses 'hflag' faces, but falls back to all if none found. */ +float BM_vert_calc_shell_factor_ex(BMVert *v, const char hflag) +{ + BMIter iter; + BMLoop *l; + float accum_shell = 0.0f; + float accum_angle = 0.0f; + int tot_sel = 0, tot = 0; + + BM_ITER_ELEM (l, &iter, v, BM_LOOPS_OF_VERT) { + if (BM_elem_flag_test(l->f, hflag)) { /* <-- main difference to BM_vert_calc_shell_factor! */ + const float face_angle = BM_loop_calc_face_angle(l); + accum_shell += shell_angle_to_dist(angle_normalized_v3v3(v->no, l->f->no)) * face_angle; + accum_angle += face_angle; + tot_sel++; + } + tot++; + } + + if (accum_angle != 0.0f) { + return accum_shell / accum_angle; + } + else { + /* other main difference from BM_vert_calc_shell_factor! */ + if (tot != 0 && tot_sel == 0) { + /* none selected, so use all */ + return BM_vert_calc_shell_factor(v); + } + else { + return 1.0f; + } + } +} /** * \note quite an obscure function. diff --git a/source/blender/bmesh/intern/bmesh_queries.h b/source/blender/bmesh/intern/bmesh_queries.h index 7a18f69371e..9af792417bf 100644 --- a/source/blender/bmesh/intern/bmesh_queries.h +++ b/source/blender/bmesh/intern/bmesh_queries.h @@ -69,6 +69,7 @@ void BM_edge_calc_face_tangent(BMEdge *e, BMLoop *e_loop, float r_tangent[3]) float BM_vert_calc_edge_angle(BMVert *v); float BM_vert_calc_shell_factor(BMVert *v); +float BM_vert_calc_shell_factor_ex(BMVert *v, const char hflag); float BM_vert_calc_mean_tagged_edge_length(BMVert *v); BMLoop *BM_face_find_shortest_loop(BMFace *f); diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c index d819176e542..6e65d7fa59a 100644 --- a/source/blender/editors/screen/screen_ops.c +++ b/source/blender/editors/screen/screen_ops.c @@ -140,9 +140,11 @@ static int screen_active_editable(bContext *C) /* when mouse is over area-edge */ int ED_operator_screen_mainwinactive(bContext *C) { + bScreen *screen; if (CTX_wm_window(C) == NULL) return 0; - if (CTX_wm_screen(C) == NULL) return 0; - if (CTX_wm_screen(C)->subwinactive != CTX_wm_screen(C)->mainwin) return 0; + screen = CTX_wm_screen(C); + if (screen == NULL) return 0; + if (screen->subwinactive != screen->mainwin) return 0; return 1; } @@ -3412,6 +3414,7 @@ static void SCREEN_OT_back_to_previous(struct wmOperatorType *ot) static int userpref_show_invoke(bContext *C, wmOperator *UNUSED(op), wmEvent *event) { + wmWindow *win = CTX_wm_window(C); rcti rect; int sizex, sizey; @@ -3420,8 +3423,8 @@ static int userpref_show_invoke(bContext *C, wmOperator *UNUSED(op), wmEvent *ev /* some magic to calculate postition */ /* pixelsize: mouse coords are in U.pixelsize units :/ */ - rect.xmin = (event->x / U.pixelsize) + CTX_wm_window(C)->posx - sizex / 2; - rect.ymin = (event->y / U.pixelsize) + CTX_wm_window(C)->posy - sizey / 2; + rect.xmin = (event->x / U.pixelsize) + win->posx - sizex / 2; + rect.ymin = (event->y / U.pixelsize) + win->posy - sizey / 2; rect.xmax = rect.xmin + sizex; rect.ymax = rect.ymin + sizey; diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c index ea852fdb098..c7499d3717f 100644 --- a/source/blender/editors/transform/transform_conversions.c +++ b/source/blender/editors/transform/transform_conversions.c @@ -1880,40 +1880,6 @@ static void get_edge_center(float cent_r[3], BMVert *eve) } } -/* local version of #BM_vert_calc_shell_factor which only - * uses selected faces */ -static float bm_vert_calc_shell_factor_selected(BMVert *v) -{ - BMIter iter; - BMLoop *l; - float accum_shell = 0.0f; - float accum_angle = 0.0f; - int tot_sel = 0, tot = 0; - - BM_ITER_ELEM (l, &iter, v, BM_LOOPS_OF_VERT) { - if (BM_elem_flag_test(l->f, BM_ELEM_SELECT)) { /* <-- only difference to BM_vert_calc_shell_factor! */ - const float face_angle = BM_loop_calc_face_angle(l); - accum_shell += shell_angle_to_dist(angle_normalized_v3v3(v->no, l->f->no)) * face_angle; - accum_angle += face_angle; - tot_sel++; - } - tot++; - } - - if (accum_angle != 0.0f) { - return accum_shell / accum_angle; - } - else { - if (tot != 0 && tot_sel == 0) { - /* none selected, so use all */ - return BM_vert_calc_shell_factor(v); - } - else { - return 1.0f; - } - } -} - /* way to overwrite what data is edited with transform */ static void VertsToTransData(TransInfo *t, TransData *td, TransDataExtension *tx, BMEditMesh *em, BMVert *eve, float *bweight) @@ -1962,7 +1928,7 @@ static void VertsToTransData(TransInfo *t, TransData *td, TransDataExtension *tx } else if (t->mode == TFM_SHRINKFATTEN) { td->ext = tx; - tx->isize[0] = bm_vert_calc_shell_factor_selected(eve); + tx->isize[0] = BM_vert_calc_shell_factor_ex(eve, BM_ELEM_SELECT); } } From da7ce6a3ccdee61dacd64de3df0e041edef7a321 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 14 Dec 2012 16:51:02 +0000 Subject: [PATCH 133/252] use UI_view2d_getscale() to get the scale for image cursor drawing and ED_mask_pixelspace_factor(). - was getting the image width/height when its not needed before. --- source/blender/editors/include/UI_view2d.h | 1 + source/blender/editors/interface/view2d.c | 6 ++++++ source/blender/editors/mask/mask_edit.c | 20 ++++++++------------ source/blender/editors/uvedit/uvedit_draw.c | 12 ++++++------ 4 files changed, 21 insertions(+), 18 deletions(-) diff --git a/source/blender/editors/include/UI_view2d.h b/source/blender/editors/include/UI_view2d.h index d050df5839a..3ae1e93dc3d 100644 --- a/source/blender/editors/include/UI_view2d.h +++ b/source/blender/editors/include/UI_view2d.h @@ -199,6 +199,7 @@ struct View2D *UI_view2d_fromcontext(const struct bContext *C); struct View2D *UI_view2d_fromcontext_rwin(const struct bContext *C); void UI_view2d_getscale(struct View2D *v2d, float *x, float *y); +void UI_view2d_getscale_inverse(struct View2D *v2d, float *x, float *y); short UI_view2d_mouse_in_scrollers(const struct bContext *C, struct View2D *v2d, int x, int y); diff --git a/source/blender/editors/interface/view2d.c b/source/blender/editors/interface/view2d.c index e2a20e5296a..a5f9995df88 100644 --- a/source/blender/editors/interface/view2d.c +++ b/source/blender/editors/interface/view2d.c @@ -2059,6 +2059,12 @@ void UI_view2d_getscale(View2D *v2d, float *x, float *y) if (x) *x = BLI_rcti_size_x(&v2d->mask) / BLI_rctf_size_x(&v2d->cur); if (y) *y = BLI_rcti_size_y(&v2d->mask) / BLI_rctf_size_y(&v2d->cur); } +/* Same as UI_view2d_getscale() - 1.0f / x, y */ +void UI_view2d_getscale_inverse(View2D *v2d, float *x, float *y) +{ + if (x) *x = BLI_rctf_size_x(&v2d->cur) / BLI_rcti_size_x(&v2d->mask); + if (y) *y = BLI_rctf_size_y(&v2d->cur) / BLI_rcti_size_y(&v2d->mask); +} /* Check if mouse is within scrollers * - Returns appropriate code for match diff --git a/source/blender/editors/mask/mask_edit.c b/source/blender/editors/mask/mask_edit.c index 18384ad9de4..cd2995be439 100644 --- a/source/blender/editors/mask/mask_edit.c +++ b/source/blender/editors/mask/mask_edit.c @@ -324,15 +324,13 @@ void ED_mask_pixelspace_factor(ScrArea *sa, ARegion *ar, float *scalex, float *s case SPACE_CLIP: { SpaceClip *sc = sa->spacedata.first; - int width, height; - float zoomx, zoomy, aspx, aspy; + float aspx, aspy; - ED_space_clip_get_size(sc, &width, &height); - ED_space_clip_get_zoom(sc, ar, &zoomx, &zoomy); + UI_view2d_getscale(&ar->v2d, scalex, scaley); ED_space_clip_get_aspect(sc, &aspx, &aspy); - *scalex = ((float)width * aspx) * zoomx; - *scaley = ((float)height * aspy) * zoomy; + *scalex *= aspx; + *scaley *= aspy; break; } case SPACE_SEQ: @@ -343,15 +341,13 @@ void ED_mask_pixelspace_factor(ScrArea *sa, ARegion *ar, float *scalex, float *s case SPACE_IMAGE: { SpaceImage *sima = sa->spacedata.first; - int width, height; - float zoomx, zoomy, aspx, aspy; + float aspx, aspy; - ED_space_image_get_size(sima, &width, &height); - ED_space_image_get_zoom(sima, ar, &zoomx, &zoomy); + UI_view2d_getscale(&ar->v2d, scalex, scaley); ED_space_image_get_aspect(sima, &aspx, &aspy); - *scalex = ((float)width * aspx) * zoomx; - *scaley = ((float)height * aspy) * zoomy; + *scalex *= aspx; + *scaley *= aspy; break; } default: diff --git a/source/blender/editors/uvedit/uvedit_draw.c b/source/blender/editors/uvedit/uvedit_draw.c index c6b251b04ae..607640090aa 100644 --- a/source/blender/editors/uvedit/uvedit_draw.c +++ b/source/blender/editors/uvedit/uvedit_draw.c @@ -61,19 +61,19 @@ #include "UI_resources.h" #include "UI_interface.h" +#include "UI_view2d.h" #include "uvedit_intern.h" void draw_image_cursor(SpaceImage *sima, ARegion *ar) { - float zoomx, zoomy, x_fac, y_fac; - int width, height; + float zoom[2], x_fac, y_fac; - ED_space_image_get_size(sima, &width, &height); - ED_space_image_get_zoom(sima, ar, &zoomx, &zoomy); + UI_view2d_getscale_inverse(&ar->v2d, &zoom[0], &zoom[1]); - x_fac = (1.0f / (zoomx * width / 256.0f)) * UI_DPI_FAC; - y_fac = (1.0f / (zoomy * height / 256.0f)) * UI_DPI_FAC; + mul_v2_fl(zoom, 256.0f * UI_DPI_FAC); + x_fac = zoom[0]; + y_fac = zoom[1]; cpack(0xFFFFFF); glTranslatef(sima->cursor[0], sima->cursor[1], 0.0); From 073669dd8588a3b80dfffee98b4f239b4baee8c8 Mon Sep 17 00:00:00 2001 From: Ton Roosendaal Date: Fri, 14 Dec 2012 18:54:22 +0000 Subject: [PATCH 134/252] Bug fix, irc submitted: On saving a first .blend after startup, the file would load back as if it was not saved (showing no name in header). The whole FILEFLAGS and G.relabase_valid and G.file_saved etc is messy. This commit fixes issues, but only adds more mess :) Will discuss a nicer implementation of all of this. --- source/blender/windowmanager/intern/wm_files.c | 8 ++++++++ source/blender/windowmanager/intern/wm_operators.c | 2 ++ 2 files changed, 10 insertions(+) diff --git a/source/blender/windowmanager/intern/wm_files.c b/source/blender/windowmanager/intern/wm_files.c index cd5da43646c..6a84e3e4e7d 100644 --- a/source/blender/windowmanager/intern/wm_files.c +++ b/source/blender/windowmanager/intern/wm_files.c @@ -841,6 +841,14 @@ int wm_file_write(bContext *C, const char *target, int fileflags, ReportList *re fileflags |= G_FILE_HISTORY; /* write file history */ + /* first time saving */ + /* XXX temp solution to solve bug, real fix coming (ton) */ + if (G.main->name[0] == 0) + BLI_strncpy(G.main->name, filepath, sizeof(G.main->name)); + + /* XXX temp solution to solve bug, real fix coming (ton) */ + G.main->recovered = 0; + if (BLO_write_file(CTX_data_main(C), filepath, fileflags, reports, thumb)) { if (!(fileflags & G_FILE_SAVE_COPY)) { G.relbase_valid = 1; diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c index ebb9e6662e6..bb957cfcb3c 100644 --- a/source/blender/windowmanager/intern/wm_operators.c +++ b/source/blender/windowmanager/intern/wm_operators.c @@ -2037,6 +2037,8 @@ void wm_recover_last_session(bContext *C, ReportList *reports) /* XXX bad global... fixme */ if (G.main->name[0]) G.file_loaded = 1; /* prevents splash to show */ + else + G.relbase_valid = 0; } } From f1d487d1c452559afe395f578c84ff29121b24d0 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Fri, 14 Dec 2012 20:56:14 +0000 Subject: [PATCH 135/252] Fix mac build error with SDK < 10.7, this version is not then defined then as pointed out by Patrick Boelens on the mailing list. --- intern/ghost/intern/GHOST_WindowCocoa.mm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/intern/ghost/intern/GHOST_WindowCocoa.mm b/intern/ghost/intern/GHOST_WindowCocoa.mm index 3e967e034c4..6c5dbe83f4c 100644 --- a/intern/ghost/intern/GHOST_WindowCocoa.mm +++ b/intern/ghost/intern/GHOST_WindowCocoa.mm @@ -578,7 +578,7 @@ GHOST_WindowCocoa::GHOST_WindowCocoa( setDrawingContextType(type); updateDrawingContext(); activateDrawingContext(); -#if MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_7 // retina support started with 10.7.4 afaik +#if defined(MAC_OS_X_VERSION_10_7) && (MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_7) // retina support started with 10.7.4 afaik if (m_systemCocoa->m_nativePixel) { [m_openGLView setWantsBestResolutionOpenGLSurface:YES]; NSRect backingBounds = [m_openGLView convertRectToBacking:[m_openGLView bounds]]; From 071a43f7540cbb263d3b974203c4c2cb0757464c Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Fri, 14 Dec 2012 21:41:22 +0000 Subject: [PATCH 136/252] Fix #33497: seting object scale to 0 on one axis made moving verts in edit mode impossible. In this case matrix inversion failed and didn't give a useful result. Now it falls back to a pseudoinverse in that case, so that moving along the other axes still works. There may be other places that can benefit from this, but this is a place where it has no significant performance impact, doing this in general for e.g. bone matrices could be quite slow. --- source/blender/blenlib/BLI_math_matrix.h | 4 ++++ source/blender/blenlib/intern/math_matrix.c | 20 +++++++++++++++---- .../editors/transform/transform_conversions.c | 20 ++++++++++--------- 3 files changed, 31 insertions(+), 13 deletions(-) diff --git a/source/blender/blenlib/BLI_math_matrix.h b/source/blender/blenlib/BLI_math_matrix.h index c97eb4c588c..c12ec62ca1b 100644 --- a/source/blender/blenlib/BLI_math_matrix.h +++ b/source/blender/blenlib/BLI_math_matrix.h @@ -144,10 +144,14 @@ float determinant_m2(float a, float b, float determinant_m3(float a, float b, float c, float d, float e, float f, float g, float h, float i); +float determinant_m3_array(float m[3][3]); float determinant_m4(float A[4][4]); +#define PSEUDOINVERSE_EPSILON 1e-8f + void svd_m4(float U[4][4], float s[4], float V[4][4], float A[4][4]); void pseudoinverse_m4_m4(float Ainv[4][4], float A[4][4], float epsilon); +void pseudoinverse_m3_m3(float Ainv[3][3], float A[3][3], float epsilon); /****************************** Transformations ******************************/ diff --git a/source/blender/blenlib/intern/math_matrix.c b/source/blender/blenlib/intern/math_matrix.c index 70eb5c1bb60..a0c372c13dc 100644 --- a/source/blender/blenlib/intern/math_matrix.c +++ b/source/blender/blenlib/intern/math_matrix.c @@ -504,8 +504,7 @@ void sub_m4_m4m4(float m1[4][4], float m2[4][4], float m3[4][4]) m1[i][j] = m2[i][j] - m3[i][j]; } -/* why not make this a standard part of the API? */ -static float determinant_m3_local(float m[3][3]) +float determinant_m3_array(float m[3][3]) { return (m[0][0] * (m[1][1] * m[2][2] - m[1][2] * m[2][1]) - m[1][0] * (m[0][1] * m[2][2] - m[0][2] * m[2][1]) + @@ -534,7 +533,7 @@ int invert_m3_m3_ex(float m1[3][3], float m2[3][3], const float epsilon) adjoint_m3_m3(m1, m2); /* then determinant old matrix! */ - det = determinant_m3_local(m2); + det = determinant_m3_array(m2); success = (fabsf(det) > epsilon); @@ -569,7 +568,7 @@ int invert_m3_m3(float m1[3][3], float m2[3][3]) adjoint_m3_m3(m1, m2); /* then determinant old matrix! */ - det = determinant_m3_local(m2); + det = determinant_m3_array(m2); success = (det != 0.0f); @@ -1903,3 +1902,16 @@ void pseudoinverse_m4_m4(float Ainv[4][4], float A[4][4], float epsilon) mul_serie_m4(Ainv, U, Wm, V, NULL, NULL, NULL, NULL, NULL); } + +void pseudoinverse_m3_m3(float Ainv[3][3], float A[3][3], float epsilon) +{ + /* try regular inverse when possible, otherwise fall back to slow svd */ + if(!invert_m3_m3(Ainv, A)) { + float tmp[4][4], tmpinv[4][4]; + + copy_m4_m3(tmp, A); + pseudoinverse_m4_m4(tmpinv, tmp, epsilon); + copy_m3_m4(Ainv, tmpinv); + } +} + diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c index c7499d3717f..7da47425370 100644 --- a/source/blender/editors/transform/transform_conversions.c +++ b/source/blender/editors/transform/transform_conversions.c @@ -272,7 +272,7 @@ static void createTransTexspace(TransInfo *t) copy_m3_m4(td->mtx, ob->obmat); copy_m3_m4(td->axismtx, ob->obmat); normalize_m3(td->axismtx); - invert_m3_m3(td->smtx, td->mtx); + pseudoinverse_m3_m3(td->smtx, td->mtx, PSEUDOINVERSE_EPSILON); if (BKE_object_obdata_texspace_get(ob, &texflag, &td->loc, &td->ext->size, &td->ext->rot)) { ob->dtx |= OB_TEXSPACE; @@ -316,7 +316,7 @@ static void createTransEdge(TransInfo *t) td = t->data = MEM_callocN(t->total * sizeof(TransData), "TransCrease"); copy_m3_m4(mtx, t->obedit->obmat); - invert_m3_m3(smtx, mtx); + pseudoinverse_m3_m3(smtx, mtx, PSEUDOINVERSE_EPSILON); BM_ITER_MESH (eed, &iter, em->bm, BM_EDGES_OF_MESH) { if (!BM_elem_flag_test(eed, BM_ELEM_HIDDEN) && (BM_elem_flag_test(eed, BM_ELEM_SELECT) || propmode)) { @@ -553,7 +553,7 @@ static void add_pose_transdata(TransInfo *t, bPoseChannel *pchan, Object *ob, Tr invert_m3_m3(td->ext->r_smtx, td->ext->r_mtx); } - invert_m3_m3(td->smtx, td->mtx); + pseudoinverse_m3_m3(td->smtx, td->mtx, PSEUDOINVERSE_EPSILON); /* exceptional case: rotate the pose bone which also applies transformation * when a parentless bone has BONE_NO_LOCAL_LOCATION [] */ @@ -605,7 +605,7 @@ static void add_pose_transdata(TransInfo *t, bPoseChannel *pchan, Object *ob, Tr /* only object matrix correction */ copy_m3_m3(td->mtx, omat); - invert_m3_m3(td->smtx, td->mtx); + pseudoinverse_m3_m3(td->smtx, td->mtx, PSEUDOINVERSE_EPSILON); } } @@ -1054,7 +1054,7 @@ static void createTransArmatureVerts(TransInfo *t) if (!t->total) return; copy_m3_m4(mtx, t->obedit->obmat); - invert_m3_m3(smtx, mtx); + pseudoinverse_m3_m3(smtx, mtx, PSEUDOINVERSE_EPSILON); td = t->data = MEM_callocN(t->total * sizeof(TransData), "TransEditBone"); @@ -1222,7 +1222,7 @@ static void createTransMBallVerts(TransInfo *t) tx = t->ext = MEM_callocN(t->total * sizeof(TransDataExtension), "MetaElement_TransExtension"); copy_m3_m4(mtx, t->obedit->obmat); - invert_m3_m3(smtx, mtx); + pseudoinverse_m3_m3(smtx, mtx, PSEUDOINVERSE_EPSILON); for (ml = mb->editelems->first; ml; ml = ml->next) { if (propmode || (ml->flag & SELECT)) { @@ -1379,7 +1379,7 @@ static void createTransCurveVerts(TransInfo *t) t->data = MEM_callocN(t->total * sizeof(TransData), "TransObData(Curve EditMode)"); copy_m3_m4(mtx, t->obedit->obmat); - invert_m3_m3(smtx, mtx); + pseudoinverse_m3_m3(smtx, mtx, PSEUDOINVERSE_EPSILON); td = t->data; for (nu = nurbs->first; nu; nu = nu->next) { @@ -1570,7 +1570,7 @@ static void createTransLatticeVerts(TransInfo *t) t->data = MEM_callocN(t->total * sizeof(TransData), "TransObData(Lattice EditMode)"); copy_m3_m4(mtx, t->obedit->obmat); - invert_m3_m3(smtx, mtx); + pseudoinverse_m3_m3(smtx, mtx, PSEUDOINVERSE_EPSILON); td = t->data; bp = latt->def; @@ -2052,7 +2052,9 @@ static void createTransEditVerts(TransInfo *t) } copy_m3_m4(mtx, t->obedit->obmat); - invert_m3_m3(smtx, mtx); + /* we use a pseudoinverse so that when one of the axes is scaled to 0, + * matrix inversion still works and we can still moving along the other */ + pseudoinverse_m3_m3(smtx, mtx, PSEUDOINVERSE_EPSILON); if (propmode & T_PROP_CONNECTED) { editmesh_set_connectivity_distance(em, mtx, dists); From 1e6f6e87805dd2290e304aecc68aba1a25a287e7 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Fri, 14 Dec 2012 22:08:19 +0000 Subject: [PATCH 137/252] Fix #33539: shift+numpad 2/4/8 shortcuts for zoom in image and clip editor don't work in Windows. These shortcuts are taken by the operating system, so ctrl+numpad 2/4/8 now work as well and are the shortcuts shown in menus. --- source/blender/editors/space_clip/space_clip.c | 5 +++++ source/blender/editors/space_image/space_image.c | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/source/blender/editors/space_clip/space_clip.c b/source/blender/editors/space_clip/space_clip.c index 77e2a1bb3d3..7befa490d41 100644 --- a/source/blender/editors/space_clip/space_clip.c +++ b/source/blender/editors/space_clip/space_clip.c @@ -592,9 +592,14 @@ static void clip_keymap(struct wmKeyConfig *keyconf) WM_keymap_add_item(keymap, "CLIP_OT_view_zoom_in", PADPLUSKEY, KM_PRESS, 0, 0); WM_keymap_add_item(keymap, "CLIP_OT_view_zoom_out", PADMINUS, KM_PRESS, 0, 0); + /* ctrl now works as well, shift + numpad works as arrow keys on Windows */ + RNA_float_set(WM_keymap_add_item(keymap, "CLIP_OT_view_zoom_ratio", PAD8, KM_PRESS, KM_CTRL, 0)->ptr, "ratio", 8.0f); + RNA_float_set(WM_keymap_add_item(keymap, "CLIP_OT_view_zoom_ratio", PAD4, KM_PRESS, KM_CTRL, 0)->ptr, "ratio", 4.0f); + RNA_float_set(WM_keymap_add_item(keymap, "CLIP_OT_view_zoom_ratio", PAD2, KM_PRESS, KM_CTRL, 0)->ptr, "ratio", 2.0f); RNA_float_set(WM_keymap_add_item(keymap, "CLIP_OT_view_zoom_ratio", PAD8, KM_PRESS, KM_SHIFT, 0)->ptr, "ratio", 8.0f); RNA_float_set(WM_keymap_add_item(keymap, "CLIP_OT_view_zoom_ratio", PAD4, KM_PRESS, KM_SHIFT, 0)->ptr, "ratio", 4.0f); RNA_float_set(WM_keymap_add_item(keymap, "CLIP_OT_view_zoom_ratio", PAD2, KM_PRESS, KM_SHIFT, 0)->ptr, "ratio", 2.0f); + RNA_float_set(WM_keymap_add_item(keymap, "CLIP_OT_view_zoom_ratio", PAD1, KM_PRESS, 0, 0)->ptr, "ratio", 1.0f); RNA_float_set(WM_keymap_add_item(keymap, "CLIP_OT_view_zoom_ratio", PAD2, KM_PRESS, 0, 0)->ptr, "ratio", 0.5f); RNA_float_set(WM_keymap_add_item(keymap, "CLIP_OT_view_zoom_ratio", PAD4, KM_PRESS, 0, 0)->ptr, "ratio", 0.25f); diff --git a/source/blender/editors/space_image/space_image.c b/source/blender/editors/space_image/space_image.c index ea696772957..5616c025407 100644 --- a/source/blender/editors/space_image/space_image.c +++ b/source/blender/editors/space_image/space_image.c @@ -292,9 +292,14 @@ static void image_keymap(struct wmKeyConfig *keyconf) WM_keymap_add_item(keymap, "IMAGE_OT_view_zoom", MIDDLEMOUSE, KM_PRESS, KM_CTRL, 0); WM_keymap_add_item(keymap, "IMAGE_OT_view_zoom", MOUSEZOOM, 0, 0, 0); + /* ctrl now works as well, shift + numpad works as arrow keys on Windows */ + RNA_float_set(WM_keymap_add_item(keymap, "IMAGE_OT_view_zoom_ratio", PAD8, KM_PRESS, KM_CTRL, 0)->ptr, "ratio", 8.0f); + RNA_float_set(WM_keymap_add_item(keymap, "IMAGE_OT_view_zoom_ratio", PAD4, KM_PRESS, KM_CTRL, 0)->ptr, "ratio", 4.0f); + RNA_float_set(WM_keymap_add_item(keymap, "IMAGE_OT_view_zoom_ratio", PAD2, KM_PRESS, KM_CTRL, 0)->ptr, "ratio", 2.0f); RNA_float_set(WM_keymap_add_item(keymap, "IMAGE_OT_view_zoom_ratio", PAD8, KM_PRESS, KM_SHIFT, 0)->ptr, "ratio", 8.0f); RNA_float_set(WM_keymap_add_item(keymap, "IMAGE_OT_view_zoom_ratio", PAD4, KM_PRESS, KM_SHIFT, 0)->ptr, "ratio", 4.0f); RNA_float_set(WM_keymap_add_item(keymap, "IMAGE_OT_view_zoom_ratio", PAD2, KM_PRESS, KM_SHIFT, 0)->ptr, "ratio", 2.0f); + RNA_float_set(WM_keymap_add_item(keymap, "IMAGE_OT_view_zoom_ratio", PAD1, KM_PRESS, 0, 0)->ptr, "ratio", 1.0f); RNA_float_set(WM_keymap_add_item(keymap, "IMAGE_OT_view_zoom_ratio", PAD2, KM_PRESS, 0, 0)->ptr, "ratio", 0.5f); RNA_float_set(WM_keymap_add_item(keymap, "IMAGE_OT_view_zoom_ratio", PAD4, KM_PRESS, 0, 0)->ptr, "ratio", 0.25f); From defaf1d0283ea675bb965418c32185c444b1189c Mon Sep 17 00:00:00 2001 From: Antony Riakiotakis Date: Fri, 14 Dec 2012 22:39:03 +0000 Subject: [PATCH 138/252] initialize static island colour display on reverting to default theme --- source/blender/editors/interface/resources.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/source/blender/editors/interface/resources.c b/source/blender/editors/interface/resources.c index 180c5ddada2..ca8ab48e734 100644 --- a/source/blender/editors/interface/resources.c +++ b/source/blender/editors/interface/resources.c @@ -860,7 +860,8 @@ void ui_theme_init_default(void) rgba_char_args_set_fl(btheme->tima.preview_stitch_vert, 0.0, 0.0, 1.0, 0.2); rgba_char_args_set_fl(btheme->tima.preview_stitch_stitchable, 0.0, 1.0, 0.0, 1.0); rgba_char_args_set_fl(btheme->tima.preview_stitch_unstitchable, 1.0, 0.0, 0.0, 1.0); - + rgba_char_args_set_fl(btheme->tima.preview_stitch_active, 0.886, 0.824, 0.765, 0.140); + /* space text */ btheme->text = btheme->tv3d; rgba_char_args_set(btheme->text.back, 153, 153, 153, 255); From 96f6a5cf207c31afefa9faf63bdc76a072cb078c Mon Sep 17 00:00:00 2001 From: Antony Riakiotakis Date: Fri, 14 Dec 2012 23:20:11 +0000 Subject: [PATCH 139/252] Restoring default theme made the panel regions opaque again. --- source/blender/editors/interface/resources.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/editors/interface/resources.c b/source/blender/editors/interface/resources.c index ca8ab48e734..5f0f7ab7ba7 100644 --- a/source/blender/editors/interface/resources.c +++ b/source/blender/editors/interface/resources.c @@ -683,7 +683,7 @@ void ui_theme_init_default(void) rgba_char_args_set(btheme->tv3d.text_hi, 255, 255, 255, 255); rgba_char_args_set_fl(btheme->tv3d.header, 0.45, 0.45, 0.45, 1.0); - rgba_char_args_set_fl(btheme->tv3d.button, 0.45, 0.45, 0.45, 1.0); + rgba_char_args_set_fl(btheme->tv3d.button, 0.45, 0.45, 0.45, 0.5); rgba_char_args_set(btheme->tv3d.panel, 165, 165, 165, 127); rgba_char_args_set(btheme->tv3d.shade1, 160, 160, 160, 100); From 1b37f8dca85578ad2bf5f8202568d00b91d194b8 Mon Sep 17 00:00:00 2001 From: Erwin Coumans Date: Sat, 15 Dec 2012 01:01:35 +0000 Subject: [PATCH 140/252] Hi there, it has been a while, just curious if my SVN account still works :) This commit is an attempt to improve collisions between moving Bullet rigid bodies using (concave) triangle mesh bounds. Instead of using Gimpact, this we create a btCompoundShape with child shape tetrahedra derived from the surface triangles. For each triangle, we add a fourth vertex using the centroid, shifting inwards using the triangle normal. If the centroid hits an internal triangle, we stop. The default depth could be exposed as 'advanced' setting in the user interface. This solution will be a slower than the original/gimpact solution, but a bit more reliable. In the future, it is better to add HACD, convex decomposition to Blender, for moving concave meshes. See http://kmamou.blogspot.com and the Bullet SDK's Demos/ConvexDecompositionDemo. --- .../Gimpact/btCompoundFromGimpact.h | 98 +++++++++++++++++++ .../Gimpact/btGImpactQuantizedBvh.cpp | 8 +- .../Gimpact/btGImpactQuantizedBvh.h | 4 +- .../Gimpact/btGImpactShape.cpp | 35 +++++++ .../BulletCollision/Gimpact/btGImpactShape.h | 27 +++-- .../Physics/Bullet/CcdPhysicsController.cpp | 11 ++- 6 files changed, 168 insertions(+), 15 deletions(-) create mode 100644 extern/bullet2/src/BulletCollision/Gimpact/btCompoundFromGimpact.h diff --git a/extern/bullet2/src/BulletCollision/Gimpact/btCompoundFromGimpact.h b/extern/bullet2/src/BulletCollision/Gimpact/btCompoundFromGimpact.h new file mode 100644 index 00000000000..8d4c35515b1 --- /dev/null +++ b/extern/bullet2/src/BulletCollision/Gimpact/btCompoundFromGimpact.h @@ -0,0 +1,98 @@ +#ifndef BT_COMPOUND_FROM_GIMPACT +#define BT_COMPOUND_FROM_GIMPACT + +#include "BulletCollision/CollisionShapes/btCompoundShape.h" +#include "btGImpactShape.h" +#include "BulletCollision/NarrowPhaseCollision/btRaycastCallback.h" + +struct MyCallback : public btTriangleRaycastCallback + { + int m_ignorePart; + int m_ignoreTriangleIndex; + + + MyCallback(const btVector3& from, const btVector3& to, int ignorePart, int ignoreTriangleIndex) + :btTriangleRaycastCallback(from,to), + m_ignorePart(ignorePart), + m_ignoreTriangleIndex(ignoreTriangleIndex) + { + + } + virtual btScalar reportHit(const btVector3& hitNormalLocal, btScalar hitFraction, int partId, int triangleIndex) + { + if (partId!=m_ignorePart || triangleIndex!=m_ignoreTriangleIndex) + { + if (hitFraction < m_hitFraction) + return hitFraction; + } + + return m_hitFraction; + } + }; + struct MyInternalTriangleIndexCallback :public btInternalTriangleIndexCallback + { + const btGImpactMeshShape* m_gimpactShape; + btCompoundShape* m_colShape; + btScalar m_depth; + + MyInternalTriangleIndexCallback (btCompoundShape* colShape, const btGImpactMeshShape* meshShape, btScalar depth) + :m_colShape(colShape), + m_gimpactShape(meshShape), + m_depth(depth) + { + } + + virtual void internalProcessTriangleIndex(btVector3* triangle,int partId,int triangleIndex) + { + btVector3 scale = m_gimpactShape->getLocalScaling(); + btVector3 v0=triangle[0]*scale; + btVector3 v1=triangle[1]*scale; + btVector3 v2=triangle[2]*scale; + + btVector3 centroid = (v0+v1+v2)/3; + btVector3 normal = (v1-v0).cross(v2-v0); + normal.normalize(); + btVector3 rayFrom = centroid; + btVector3 rayTo = centroid-normal*m_depth; + + MyCallback cb(rayFrom,rayTo,partId,triangleIndex); + + m_gimpactShape->processAllTrianglesRay(&cb,rayFrom, rayTo); + if (cb.m_hitFraction<1) + { + rayTo.setInterpolate3(cb.m_from,cb.m_to,cb.m_hitFraction); + //rayTo = cb.m_from; + //rayTo = rayTo.lerp(cb.m_to,cb.m_hitFraction); + //gDebugDraw.drawLine(tr(centroid),tr(centroid+normal),btVector3(1,0,0)); + } + + + + + btConvexHullShape* tet = new btConvexHullShape(); + tet->addPoint(v0); + tet->addPoint(v1); + tet->addPoint(v2); + tet->addPoint(rayTo); + btTransform ident; + ident.setIdentity(); + m_colShape->addChildShape(ident,tet); + } + }; + +btCompoundShape* btCreateCompoundFromGimpactShape(const btGImpactMeshShape* gimpactMesh, btScalar depth) +{ + btCompoundShape* colShape = new btCompoundShape(); + + btTransform tr; + tr.setIdentity(); + + MyInternalTriangleIndexCallback cb(colShape,gimpactMesh, depth); + btVector3 aabbMin,aabbMax; + gimpactMesh->getAabb(tr,aabbMin,aabbMax); + gimpactMesh->getMeshInterface()->InternalProcessAllTriangles(&cb,aabbMin,aabbMax); + + return colShape; +} + +#endif //BT_COMPOUND_FROM_GIMPACT \ No newline at end of file diff --git a/extern/bullet2/src/BulletCollision/Gimpact/btGImpactQuantizedBvh.cpp b/extern/bullet2/src/BulletCollision/Gimpact/btGImpactQuantizedBvh.cpp index cd4dfdb60e9..4528758c370 100644 --- a/extern/bullet2/src/BulletCollision/Gimpact/btGImpactQuantizedBvh.cpp +++ b/extern/bullet2/src/BulletCollision/Gimpact/btGImpactQuantizedBvh.cpp @@ -384,7 +384,7 @@ bool btGImpactQuantizedBvh::rayQuery( SIMD_FORCE_INLINE bool _quantized_node_collision( - btGImpactQuantizedBvh * boxset0, btGImpactQuantizedBvh * boxset1, + const btGImpactQuantizedBvh * boxset0, const btGImpactQuantizedBvh * boxset1, const BT_BOX_BOX_TRANSFORM_CACHE & trans_cache_1to0, int node0 ,int node1, bool complete_primitive_tests) { @@ -402,7 +402,7 @@ SIMD_FORCE_INLINE bool _quantized_node_collision( //stackless recursive collision routine static void _find_quantized_collision_pairs_recursive( - btGImpactQuantizedBvh * boxset0, btGImpactQuantizedBvh * boxset1, + const btGImpactQuantizedBvh * boxset0, const btGImpactQuantizedBvh * boxset1, btPairSet * collision_pairs, const BT_BOX_BOX_TRANSFORM_CACHE & trans_cache_1to0, int node0, int node1, bool complete_primitive_tests) @@ -501,8 +501,8 @@ static void _find_quantized_collision_pairs_recursive( } -void btGImpactQuantizedBvh::find_collision(btGImpactQuantizedBvh * boxset0, const btTransform & trans0, - btGImpactQuantizedBvh * boxset1, const btTransform & trans1, +void btGImpactQuantizedBvh::find_collision(const btGImpactQuantizedBvh * boxset0, const btTransform & trans0, + const btGImpactQuantizedBvh * boxset1, const btTransform & trans1, btPairSet & collision_pairs) { diff --git a/extern/bullet2/src/BulletCollision/Gimpact/btGImpactQuantizedBvh.h b/extern/bullet2/src/BulletCollision/Gimpact/btGImpactQuantizedBvh.h index 9c990774739..e6e52fff4c0 100644 --- a/extern/bullet2/src/BulletCollision/Gimpact/btGImpactQuantizedBvh.h +++ b/extern/bullet2/src/BulletCollision/Gimpact/btGImpactQuantizedBvh.h @@ -363,8 +363,8 @@ public: static float getAverageTreeCollisionTime(); #endif //TRI_COLLISION_PROFILING - static void find_collision(btGImpactQuantizedBvh * boxset1, const btTransform & trans1, - btGImpactQuantizedBvh * boxset2, const btTransform & trans2, + static void find_collision(const btGImpactQuantizedBvh * boxset1, const btTransform & trans1, + const btGImpactQuantizedBvh * boxset2, const btTransform & trans2, btPairSet & collision_pairs); }; diff --git a/extern/bullet2/src/BulletCollision/Gimpact/btGImpactShape.cpp b/extern/bullet2/src/BulletCollision/Gimpact/btGImpactShape.cpp index cceace55e4b..ac8efdf3833 100644 --- a/extern/bullet2/src/BulletCollision/Gimpact/btGImpactShape.cpp +++ b/extern/bullet2/src/BulletCollision/Gimpact/btGImpactShape.cpp @@ -25,6 +25,7 @@ subject to the following restrictions: #define CALC_EXACT_INERTIA 1 + void btGImpactCompoundShape::calculateLocalInertia(btScalar mass,btVector3& inertia) const { lockChildShapes(); @@ -144,6 +145,31 @@ void btGImpactMeshShape::rayTest(const btVector3& rayFrom, const btVector3& rayT { } +void btGImpactMeshShapePart::processAllTrianglesRay(btTriangleCallback* callback,const btVector3& rayFrom, const btVector3& rayTo) const +{ + lockChildShapes(); + + btAlignedObjectArray collided; + btVector3 rayDir(rayTo - rayFrom); + rayDir.normalize(); + m_box_set.rayQuery(rayDir, rayFrom, collided); + + if(collided.size()==0) + { + unlockChildShapes(); + return; + } + + int part = (int)getPart(); + btPrimitiveTriangle triangle; + int i = collided.size(); + while(i--) + { + getPrimitiveTriangle(collided[i],triangle); + callback->processTriangle(triangle.m_vertices,part,collided[i]); + } + unlockChildShapes(); +} void btGImpactMeshShapePart::processAllTriangles(btTriangleCallback* callback,const btVector3& aabbMin,const btVector3& aabbMax) const { @@ -182,6 +208,15 @@ void btGImpactMeshShape::processAllTriangles(btTriangleCallback* callback,const } } +void btGImpactMeshShape::processAllTrianglesRay(btTriangleCallback* callback,const btVector3& rayFrom, const btVector3& rayTo) const +{ + int i = m_mesh_parts.size(); + while(i--) + { + m_mesh_parts[i]->processAllTrianglesRay(callback, rayFrom, rayTo); + } +} + ///fills the dataBuffer and returns the struct name (and 0 on failure) const char* btGImpactMeshShape::serialize(void* dataBuffer, btSerializer* serializer) const diff --git a/extern/bullet2/src/BulletCollision/Gimpact/btGImpactShape.h b/extern/bullet2/src/BulletCollision/Gimpact/btGImpactShape.h index 90015bb9ac0..3d1f48d4776 100644 --- a/extern/bullet2/src/BulletCollision/Gimpact/btGImpactShape.h +++ b/extern/bullet2/src/BulletCollision/Gimpact/btGImpactShape.h @@ -51,6 +51,7 @@ enum eGIMPACT_SHAPE_TYPE }; + //! Helper class for tetrahedrons class btTetrahedronShapeEx:public btBU_Simplex1to4 { @@ -192,7 +193,7 @@ public: virtual eGIMPACT_SHAPE_TYPE getGImpactShapeType() const = 0 ; //! gets boxset - SIMD_FORCE_INLINE btGImpactBoxSet * getBoxSet() + SIMD_FORCE_INLINE const btGImpactBoxSet * getBoxSet() const { return &m_box_set; } @@ -288,6 +289,15 @@ public: (void) callback; (void) aabbMin; (void) aabbMax; } + //! Function for retrieve triangles. + /*! + It gives the triangles in local space + */ + virtual void processAllTrianglesRay(btTriangleCallback* /*callback*/,const btVector3& /*rayFrom*/, const btVector3& /*rayTo*/) const + { + + } + //!@} }; @@ -635,25 +645,25 @@ public: return (int )numverts; } - SIMD_FORCE_INLINE void get_indices(int face_index,int &i0,int &i1,int &i2) const + SIMD_FORCE_INLINE void get_indices(int face_index,unsigned int &i0,unsigned int &i1,unsigned int &i2) const { if(indicestype == PHY_SHORT) { - short * s_indices = (short *)(indexbase + face_index*indexstride); + unsigned short* s_indices = (unsigned short *)(indexbase + face_index * indexstride); i0 = s_indices[0]; i1 = s_indices[1]; i2 = s_indices[2]; } else { - int * i_indices = (int *)(indexbase + face_index*indexstride); + unsigned int * i_indices = (unsigned int *)(indexbase + face_index*indexstride); i0 = i_indices[0]; i1 = i_indices[1]; i2 = i_indices[2]; } } - SIMD_FORCE_INLINE void get_vertex(int vertex_index, btVector3 & vertex) const + SIMD_FORCE_INLINE void get_vertex(unsigned int vertex_index, btVector3 & vertex) const { if(type == PHY_DOUBLE) { @@ -682,7 +692,7 @@ public: virtual void get_primitive_triangle(int prim_index,btPrimitiveTriangle & triangle) const { - int indices[3]; + unsigned int indices[3]; get_indices(prim_index,indices[0],indices[1],indices[2]); get_vertex(indices[0],triangle.m_vertices[0]); get_vertex(indices[1],triangle.m_vertices[1]); @@ -692,7 +702,7 @@ public: SIMD_FORCE_INLINE void get_bullet_triangle(int prim_index,btTriangleShapeEx & triangle) const { - int indices[3]; + unsigned int indices[3]; get_indices(prim_index,indices[0],indices[1],indices[2]); get_vertex(indices[0],triangle.m_vertices1[0]); get_vertex(indices[1],triangle.m_vertices1[1]); @@ -885,6 +895,7 @@ public: } virtual void processAllTriangles(btTriangleCallback* callback,const btVector3& aabbMin,const btVector3& aabbMax) const; + virtual void processAllTrianglesRay(btTriangleCallback* callback,const btVector3& rayFrom,const btVector3& rayTo) const; }; @@ -1141,6 +1152,8 @@ public: */ virtual void processAllTriangles(btTriangleCallback* callback,const btVector3& aabbMin,const btVector3& aabbMax) const; + virtual void processAllTrianglesRay (btTriangleCallback* callback,const btVector3& rayFrom,const btVector3& rayTo) const; + virtual int calculateSerializeBufferSize() const; ///fills the dataBuffer and returns the struct name (and 0 on failure) diff --git a/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp b/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp index 6c6ce94d8d5..a1b30ccb001 100644 --- a/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp +++ b/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp @@ -24,7 +24,7 @@ subject to the following restrictions: #include "btBulletDynamicsCommon.h" #include "BulletCollision/CollisionDispatch/btGhostObject.h" #include "BulletCollision/CollisionShapes/btScaledBvhTriangleMeshShape.h" - +#include "BulletCollision/Gimpact/btCompoundFromGimpact.h" #include "BulletCollision/CollisionShapes/btTriangleIndexVertexArray.h" #include "PHY_IMotionState.h" @@ -2169,9 +2169,16 @@ btCollisionShape* CcdShapeConstructionInfo::CreateBulletShape(btScalar margin, b ); btGImpactMeshShape* gimpactShape = new btGImpactMeshShape(indexVertexArrays); gimpactShape->setMargin(margin); - collisionShape = gimpactShape; gimpactShape->updateBound(); + //the depth value is how far along the triangle normal, the centroid is moved inwards + //to create surface tetrahedra for the btCompoundShape + //would be nice to expose this in the Blender user interfaceb + btScalar depth=btScalar(0.2); + collisionShape = btCreateCompoundFromGimpactShape(gimpactShape,depth); + delete gimpactShape; + + } else { if (!m_unscaledShape || m_forceReInstance) From cc32540c48ebf53a66b2f0df6ff8d0ca23dc4785 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sat, 15 Dec 2012 02:48:25 +0000 Subject: [PATCH 141/252] style cleanup: stop the style checker script from complaining about '!*ptr' --- source/blender/blenlib/intern/BLI_kdopbvh.c | 2 +- source/blender/blenlib/intern/math_matrix.c | 2 +- source/blender/editors/interface/interface_regions.c | 8 ++++---- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/source/blender/blenlib/intern/BLI_kdopbvh.c b/source/blender/blenlib/intern/BLI_kdopbvh.c index 6cf167b8823..55f67cedfc6 100644 --- a/source/blender/blenlib/intern/BLI_kdopbvh.c +++ b/source/blender/blenlib/intern/BLI_kdopbvh.c @@ -1237,7 +1237,7 @@ static void dfs_find_nearest_begin(BVHNearestData *data, BVHNode *node) #define DEFAULT_FIND_NEAREST_HEAP_SIZE 1024 -#define NodeDistance_priority(a, b) ( (a).dist < (b).dist) +#define NodeDistance_priority(a, b) ((a).dist < (b).dist) static void NodeDistance_push_heap(NodeDistance *heap, int heap_size) PUSH_HEAP_BODY(NodeDistance, NodeDistance_priority, heap, heap_size) diff --git a/source/blender/blenlib/intern/math_matrix.c b/source/blender/blenlib/intern/math_matrix.c index a0c372c13dc..3a294769eb3 100644 --- a/source/blender/blenlib/intern/math_matrix.c +++ b/source/blender/blenlib/intern/math_matrix.c @@ -1906,7 +1906,7 @@ void pseudoinverse_m4_m4(float Ainv[4][4], float A[4][4], float epsilon) void pseudoinverse_m3_m3(float Ainv[3][3], float A[3][3], float epsilon) { /* try regular inverse when possible, otherwise fall back to slow svd */ - if(!invert_m3_m3(Ainv, A)) { + if (!invert_m3_m3(Ainv, A)) { float tmp[4][4], tmpinv[4][4]; copy_m4_m3(tmp, A); diff --git a/source/blender/editors/interface/interface_regions.c b/source/blender/editors/interface/interface_regions.c index 8acae65bf5f..9df642f58b7 100644 --- a/source/blender/editors/interface/interface_regions.c +++ b/source/blender/editors/interface/interface_regions.c @@ -425,7 +425,7 @@ ARegion *ui_tooltip_create(bContext *C, ARegion *butregion, uiBut *but) /* IDProperty *prop;*/ char buf[512]; float fonth, fontw, aspect = but->block->aspect; - int winx, winy, ofsx, ofsy, w, h, a; + int winx /*, winy */, ofsx, ofsy, w, h, a; rctf rect_fl; rcti rect_i; @@ -675,7 +675,7 @@ ARegion *ui_tooltip_create(bContext *C, ARegion *butregion, uiBut *but) } winx = WM_window_pixels_x(win); - winy = WM_window_pixels_y(win); + // winy = WM_window_pixels_y(win); /* UNUSED */ //wm_window_get_size(win, &winx, &winy); if (rect_i.xmax > winx) { @@ -1109,7 +1109,7 @@ ARegion *ui_searchbox_create(bContext *C, ARegion *butregion, uiBut *but) float aspect = but->block->aspect; rctf rect_fl; rcti rect_i; - int winx, winy, ofsx, ofsy; + int winx /*, winy */, ofsx, ofsy; int i; /* create area region */ @@ -1191,7 +1191,7 @@ ARegion *ui_searchbox_create(bContext *C, ARegion *butregion, uiBut *but) BLI_rcti_translate(&rect_i, butregion->winrct.xmin, butregion->winrct.ymin); winx = WM_window_pixels_x(win); - winy = WM_window_pixels_y(win); + // winy = WM_window_pixels_y(win); /* UNUSED */ //wm_window_get_size(win, &winx, &winy); if (rect_i.xmax > winx) { From 865b547b4426fa353aa9e1473b66c3af0d53ea4d Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sat, 15 Dec 2012 04:44:10 +0000 Subject: [PATCH 142/252] add checks to style checker script for 'a . b' and 'a []' also use BLI_findindex for modifiers_indexInObject --- source/blender/blenkernel/intern/modifier.c | 7 +------ source/blender/blenlib/BLI_listbase.h | 4 ++-- source/blender/blenlib/intern/listbase.c | 2 +- source/blender/editors/space_info/space_info.c | 2 +- source/blender/editors/uvedit/uvedit_intern.h | 2 +- source/blender/windowmanager/intern/wm_operators.c | 2 +- 6 files changed, 7 insertions(+), 12 deletions(-) diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c index 25b70ce1793..5918879906a 100644 --- a/source/blender/blenkernel/intern/modifier.c +++ b/source/blender/blenkernel/intern/modifier.c @@ -623,12 +623,7 @@ int modifiers_isPreview(Object *ob) int modifiers_indexInObject(Object *ob, ModifierData *md_seek) { - int i = 0; - ModifierData *md; - - for (md = ob->modifiers.first; (md && md_seek != md); md = md->next, i++) ; - if (!md) return -1; /* modifier isn't in the object */ - return i; + return BLI_findindex(&ob->modifiers, md_seek); } void modifier_freeTemporaryData(ModifierData *md) diff --git a/source/blender/blenlib/BLI_listbase.h b/source/blender/blenlib/BLI_listbase.h index 1330a74bea3..d06956e39de 100644 --- a/source/blender/blenlib/BLI_listbase.h +++ b/source/blender/blenlib/BLI_listbase.h @@ -41,7 +41,7 @@ extern "C" { #endif void BLI_insertlink(struct ListBase *listbase, void *vprevlink, void *vnewlink); -int BLI_findindex(const struct ListBase *listbase, void *vlink); +int BLI_findindex(const struct ListBase *listbase, const void *vlink); int BLI_findstringindex(const struct ListBase *listbase, const char *id, const int offset); /* find forwards */ @@ -79,4 +79,4 @@ struct LinkData *BLI_genericNodeN(void *data); } #endif -#endif +#endif /* __BLI_LISTBASE_H__ */ diff --git a/source/blender/blenlib/intern/listbase.c b/source/blender/blenlib/intern/listbase.c index 9f6f409c473..c60a9ae6bfc 100644 --- a/source/blender/blenlib/intern/listbase.c +++ b/source/blender/blenlib/intern/listbase.c @@ -345,7 +345,7 @@ void *BLI_rfindlink(const ListBase *listbase, int number) return link; } -int BLI_findindex(const ListBase *listbase, void *vlink) +int BLI_findindex(const ListBase *listbase, const void *vlink) { Link *link = NULL; int number = 0; diff --git a/source/blender/editors/space_info/space_info.c b/source/blender/editors/space_info/space_info.c index cba0a808d63..db9be22eedb 100644 --- a/source/blender/editors/space_info/space_info.c +++ b/source/blender/editors/space_info/space_info.c @@ -272,7 +272,7 @@ static void info_header_listener(ARegion *ar, wmNotifier *wmn) static void recent_files_menu_draw(const bContext *UNUSED(C), Menu *menu) { struct RecentFile *recent; - char file [FILE_MAX]; + char file[FILE_MAX]; uiLayout *layout = menu->layout; uiLayoutSetOperatorContext(layout, WM_OP_EXEC_REGION_WIN); if (G.recent_files.first) { diff --git a/source/blender/editors/uvedit/uvedit_intern.h b/source/blender/editors/uvedit/uvedit_intern.h index b42875f20c2..27bbba11e75 100644 --- a/source/blender/editors/uvedit/uvedit_intern.h +++ b/source/blender/editors/uvedit/uvedit_intern.h @@ -51,7 +51,7 @@ int uvedit_face_visible_nolocal(struct Scene *scene, struct BMFace *efa); /* geometric utilities */ float uv_poly_area(float uv[][2], int len); -void uv_poly_copy_aspect(float uv_orig [][2], float uv[][2], float aspx, float aspy, int len); +void uv_poly_copy_aspect(float uv_orig[][2], float uv[][2], float aspx, float aspy, int len); void uv_poly_center(struct BMEditMesh *em, struct BMFace *f, float r_cent[2]); /* find nearest */ diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c index bb957cfcb3c..469845ec2bc 100644 --- a/source/blender/windowmanager/intern/wm_operators.c +++ b/source/blender/windowmanager/intern/wm_operators.c @@ -1430,7 +1430,7 @@ static uiBlock *wm_block_create_splash(bContext *C, ARegion *ar, void *UNUSED(ar int i; MenuType *mt = WM_menutype_find("USERPREF_MT_splash", TRUE); char url[96]; - char file [FILE_MAX]; + char file[FILE_MAX]; #ifndef WITH_HEADLESS extern char datatoc_splash_png[]; From 11ffc7f5c236f21ff1ad65a67476af36d2445e81 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sat, 15 Dec 2012 05:46:41 +0000 Subject: [PATCH 143/252] remove modifiers_indexInObject(), just call BLI_findindex directly. --- source/blender/blenkernel/BKE_modifier.h | 2 -- source/blender/blenkernel/intern/DerivedMesh.c | 4 ++-- source/blender/blenkernel/intern/modifier.c | 5 ----- source/blender/editors/physics/physics_fluid.c | 6 +++--- 4 files changed, 5 insertions(+), 12 deletions(-) diff --git a/source/blender/blenkernel/BKE_modifier.h b/source/blender/blenkernel/BKE_modifier.h index 2fa78b30835..cc260b8f60c 100644 --- a/source/blender/blenkernel/BKE_modifier.h +++ b/source/blender/blenkernel/BKE_modifier.h @@ -358,8 +358,6 @@ int modifiers_isCorrectableDeformed(struct Object *ob); void modifier_freeTemporaryData(struct ModifierData *md); int modifiers_isPreview(struct Object *ob); -int modifiers_indexInObject(struct Object *ob, struct ModifierData *md); - typedef struct CDMaskLink { struct CDMaskLink *next; CustomDataMask mask; diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c index d09bea0f662..1f4cc9bc5c2 100644 --- a/source/blender/blenkernel/intern/DerivedMesh.c +++ b/source/blender/blenkernel/intern/DerivedMesh.c @@ -1421,7 +1421,7 @@ static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos } /* grab modifiers until index i */ - if ((index >= 0) && (modifiers_indexInObject(ob, md) >= index)) + if ((index >= 0) && (BLI_findindex(&ob->modifiers, md) >= index)) break; } @@ -1666,7 +1666,7 @@ static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos isPrevDeform = (mti->type == eModifierTypeType_OnlyDeform); /* grab modifiers until index i */ - if ((index >= 0) && (modifiers_indexInObject(ob, md) >= index)) + if ((index >= 0) && (BLI_findindex(&ob->modifiers, md) >= index)) break; if (sculpt_mode && md->type == eModifierType_Multires) diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c index 5918879906a..2aeda614f07 100644 --- a/source/blender/blenkernel/intern/modifier.c +++ b/source/blender/blenkernel/intern/modifier.c @@ -621,11 +621,6 @@ int modifiers_isPreview(Object *ob) return FALSE; } -int modifiers_indexInObject(Object *ob, ModifierData *md_seek) -{ - return BLI_findindex(&ob->modifiers, md_seek); -} - void modifier_freeTemporaryData(ModifierData *md) { if (md->type == eModifierType_Armature) { diff --git a/source/blender/editors/physics/physics_fluid.c b/source/blender/editors/physics/physics_fluid.c index 5304c64c2a9..25408961dc5 100644 --- a/source/blender/editors/physics/physics_fluid.c +++ b/source/blender/editors/physics/physics_fluid.c @@ -267,7 +267,7 @@ static void set_vertex_channel(float *channel, float time, struct Scene *scene, FluidsimModifierData *fluidmd = (FluidsimModifierData *)modifiers_findByType(ob, eModifierType_Fluidsim); float *verts; int *tris=NULL, numVerts=0, numTris=0; - int modifierIndex = modifiers_indexInObject(ob, (ModifierData *)fluidmd); + int modifierIndex = BLI_findindex(&ob->modifiers, fluidmd); int framesize = (3*fobj->numVerts) + 1; int j; @@ -388,7 +388,7 @@ static void fluid_init_all_channels(bContext *C, Object *UNUSED(fsDomain), Fluid if (fluid_is_animated_mesh(fluidmd->fss)) { float *verts=NULL; - int *tris=NULL, modifierIndex = modifiers_indexInObject(ob, (ModifierData *)fluidmd); + int *tris=NULL, modifierIndex = BLI_findindex(&ob->modifiers, (ModifierData *)fluidmd); initElbeemMesh(scene, ob, &fobj->numVerts, &verts, &fobj->numTris, &tris, 0, modifierIndex); fobj->VertexCache = MEM_callocN(length *((fobj->numVerts*CHANNEL_VEC)+1) * sizeof(float), "fluidobject VertexCache"); @@ -491,7 +491,7 @@ static void export_fluid_objects(ListBase *fobjects, Scene *scene, int length) for (fobj=fobjects->first; fobj; fobj=fobj->next) { Object *ob = fobj->object; FluidsimModifierData *fluidmd = (FluidsimModifierData *)modifiers_findByType(ob, eModifierType_Fluidsim); - int modifierIndex = modifiers_indexInObject(ob, (ModifierData *)fluidmd); + int modifierIndex = BLI_findindex(&ob->modifiers, fluidmd); float *verts=NULL; int *tris=NULL; From 34b7495523190f75cc4c13f03f86adc8d2de582b Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sat, 15 Dec 2012 06:12:40 +0000 Subject: [PATCH 144/252] prevent the text 3d cursor from z-fighting with the text. --- source/blender/editors/space_view3d/drawobject.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c index 6c58ca5a691..d444612cfc5 100644 --- a/source/blender/editors/space_view3d/drawobject.c +++ b/source/blender/editors/space_view3d/drawobject.c @@ -5432,10 +5432,10 @@ static void curve_draw_speed(Scene *scene, Object *ob) #endif /* XXX old animation system stuff */ -static void draw_textcurs(float textcurs[4][2]) +static void draw_textcurs(RegionView3D *rv3d, float textcurs[4][2]) { cpack(0); - + bglPolygonOffset(rv3d->dist, -1.0); set_inverted_drawing(1); glBegin(GL_QUADS); glVertex2fv(textcurs[0]); @@ -5444,6 +5444,7 @@ static void draw_textcurs(float textcurs[4][2]) glVertex2fv(textcurs[3]); glEnd(); set_inverted_drawing(0); + bglPolygonOffset(rv3d->dist, 0.0); } static void drawspiral(const float cent[3], float rad, float tmat[4][4], int start) @@ -6364,7 +6365,7 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, const short case OB_FONT: cu = ob->data; if (cu->editfont) { - draw_textcurs(cu->editfont->textcurs); + draw_textcurs(rv3d, cu->editfont->textcurs); if (cu->flag & CU_FAST) { cpack(0xFFFFFF); From 81d240c8c86d0741e26eaa3f8b4b4c9bfac38f1a Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sat, 15 Dec 2012 07:57:16 +0000 Subject: [PATCH 145/252] avoid using strlen() for comparisons in for loops. for expanding whitespace in the text editor and ui paste. --- source/blender/datatoc/datatoc.c | 4 ++- .../editors/interface/interface_handlers.c | 23 +++++++------- source/blender/editors/space_text/text_ops.c | 31 +++++++++---------- source/blender/makesdna/intern/makesdna.c | 4 +-- 4 files changed, 31 insertions(+), 31 deletions(-) diff --git a/source/blender/datatoc/datatoc.c b/source/blender/datatoc/datatoc.c index 379658bb4c4..236d9af8ef1 100644 --- a/source/blender/datatoc/datatoc.c +++ b/source/blender/datatoc/datatoc.c @@ -51,6 +51,7 @@ int main(int argc, char **argv) FILE *fpin, *fpout; long size; int i; + int argv_len; if (argc < 2) { printf("Usage: datatoc \n"); @@ -75,7 +76,8 @@ int main(int argc, char **argv) printf("Making C file <%s>\n", argv[2]); #endif - for (i = 0; i < (int)strlen(argv[1]); i++) + argv_len = (int)strlen(argv[1]); + for (i = 0; i < argv_len; i++) if (argv[1][i] == '.') argv[1][i] = '_'; fpout = fopen(argv[2], "w"); diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c index 4f6e184dceb..531fbec4cc3 100644 --- a/source/blender/editors/interface/interface_handlers.c +++ b/source/blender/editors/interface/interface_handlers.c @@ -1674,10 +1674,11 @@ static int ui_textedit_copypaste(uiBut *but, uiHandleButtonData *data, int paste { char buf[UI_MAX_DRAW_STR] = {0}; char *str, *p, *pbuf; - int len, x, i, changed = 0; + int x, changed = 0; + int str_len, buf_len; str = data->str; - len = strlen(str); + str_len = strlen(str); /* paste */ if (paste) { @@ -1687,28 +1688,28 @@ static int ui_textedit_copypaste(uiBut *but, uiHandleButtonData *data, int paste if (p && p[0]) { unsigned int y; - i = 0; - while (*p && *p != '\r' && *p != '\n' && i < UI_MAX_DRAW_STR - 1) { - buf[i++] = *p; + buf_len = 0; + while (*p && *p != '\r' && *p != '\n' && buf_len < UI_MAX_DRAW_STR - 1) { + buf[buf_len++] = *p; p++; } - buf[i] = 0; + buf[buf_len] = 0; /* paste over the current selection */ if ((but->selend - but->selsta) > 0) { ui_textedit_delete_selection(but, data); - len = strlen(str); + str_len = strlen(str); } - for (y = 0; y < strlen(buf); y++) { + for (y = 0; y < buf_len; y++) { /* add contents of buffer */ - if (len + 1 < data->maxlen) { + if (str_len + 1 < data->maxlen) { for (x = data->maxlen; x > but->pos; x--) str[x] = str[x - 1]; str[but->pos] = buf[y]; but->pos++; - len++; - str[len] = '\0'; + str_len++; + str[str_len] = '\0'; } } diff --git a/source/blender/editors/space_text/text_ops.c b/source/blender/editors/space_text/text_ops.c index 83a1bfee0d8..71044579df4 100644 --- a/source/blender/editors/space_text/text_ops.c +++ b/source/blender/editors/space_text/text_ops.c @@ -1131,21 +1131,20 @@ static int text_convert_whitespace_exec(bContext *C, wmOperator *op) TextLine *tmp; FlattenString fs; size_t a, j; - char *text_check_line, *new_line; + char *new_line; int extra, number; //unknown for now int type = RNA_enum_get(op->ptr, "type"); - - tmp = text->lines.first; - + /* first convert to all space, this make it a lot easier to convert to tabs * because there is no mixtures of ' ' && '\t' */ - while (tmp) { - text_check_line = tmp->line; + for (tmp = text->lines.first; tmp; tmp = tmp->next) { + const char *text_check_line = tmp->line; + const int text_check_line_len = tmp->len; number = flatten_string(st, &fs, text_check_line) + 1; flatten_string_free(&fs); new_line = MEM_callocN(number, "Converted_Line"); j = 0; - for (a = 0; a < strlen(text_check_line); a++) { //foreach char in line + for (a = 0; a < text_check_line_len; a++) { //foreach char in line if (text_check_line[a] == '\t') { //checking for tabs //get the number of spaces this tabs is showing //i don't like doing it this way but will look into it later @@ -1175,20 +1174,19 @@ static int text_convert_whitespace_exec(bContext *C, wmOperator *op) tmp->line = new_line; tmp->len = strlen(new_line); tmp->format = NULL; - tmp = tmp->next; } if (type == TO_TABS) { // Converting to tabs //start over from the beginning - tmp = text->lines.first; - while (tmp) { - text_check_line = tmp->line; + for (tmp = text->lines.first; tmp; tmp = tmp->next) { + const char *text_check_line = tmp->line; + const int text_check_line_len = tmp->len; extra = 0; - for (a = 0; a < strlen(text_check_line); a++) { + for (a = 0; a < text_check_line_len; a++) { number = 0; for (j = 0; j < (size_t)st->tabnumber; j++) { - if ((a + j) <= strlen(text_check_line)) { //check to make sure we are not pass the end of the line + if ((a + j) <= text_check_line_len) { //check to make sure we are not pass the end of the line if (text_check_line[a + j] != ' ') { number = 1; } @@ -1201,12 +1199,12 @@ static int text_convert_whitespace_exec(bContext *C, wmOperator *op) } if (extra > 0) { //got tabs make malloc and do what you have to do - new_line = MEM_callocN(strlen(text_check_line) - (((st->tabnumber * extra) - extra) - 1), "Converted_Line"); + new_line = MEM_callocN(text_check_line_len - (((st->tabnumber * extra) - extra) - 1), "Converted_Line"); extra = 0; //reuse vars - for (a = 0; a < strlen(text_check_line); a++) { + for (a = 0; a < text_check_line_len; a++) { number = 0; for (j = 0; j < (size_t)st->tabnumber; j++) { - if ((a + j) <= strlen(text_check_line)) { //check to make sure we are not pass the end of the line + if ((a + j) <= text_check_line_len) { //check to make sure we are not pass the end of the line if (text_check_line[a + j] != ' ') { number = 1; } @@ -1233,7 +1231,6 @@ static int text_convert_whitespace_exec(bContext *C, wmOperator *op) tmp->len = strlen(new_line); tmp->format = NULL; } - tmp = tmp->next; } } diff --git a/source/blender/makesdna/intern/makesdna.c b/source/blender/makesdna/intern/makesdna.c index fa0b313a120..e02a9bfe56a 100644 --- a/source/blender/makesdna/intern/makesdna.c +++ b/source/blender/makesdna/intern/makesdna.c @@ -984,7 +984,7 @@ static int make_structDNA(char *baseDirectory, FILE *file) /* little test first... */ /* Mind the breaking condition here! */ if (debugSDNA) printf("\tStart of header scan:\n"); - for (i = 0; strlen(includefiles[i]); i++) { + for (i = 0; *(includefiles[i]) != '\0'; i++) { sprintf(str, "%s%s", baseDirectory, includefiles[i]); if (debugSDNA) printf("\t|-- Converting %s\n", str); if (convert_include(str)) { @@ -1100,7 +1100,7 @@ static int make_structDNA(char *baseDirectory, FILE *file) else { /* add all include files defined in the global array */ - for (i = 0; strlen(includefiles[i]); i++) { + for (i = 0; *(includefiles[i]) != '\0'; i++) { fprintf(fp, "#include \"%s%s\"\n", baseDirectory, includefiles[i]); } From 35dd893c368548b5d9d7bb56a1b9db07c71165d2 Mon Sep 17 00:00:00 2001 From: Ton Roosendaal Date: Sat, 15 Dec 2012 09:45:34 +0000 Subject: [PATCH 146/252] Bugfix, irc collection: With larger header sizes (via DPI setting), splitting an area horizontally (using left-bottom corner widget, move up) stopped immediate after split, not allowing to drag it to a position. Culprit was code to check minimum header size, and area operator using the same flags. Now ScrVert has two flags - one for internal use, one for the tools to set. --- source/blender/editors/screen/area.c | 2 +- source/blender/editors/screen/screen_ops.c | 18 +++++++++--------- source/blender/makesdna/DNA_screen_types.h | 3 ++- 3 files changed, 12 insertions(+), 11 deletions(-) diff --git a/source/blender/editors/screen/area.c b/source/blender/editors/screen/area.c index 62ddd10ee7c..a73c2d818d0 100644 --- a/source/blender/editors/screen/area.c +++ b/source/blender/editors/screen/area.c @@ -1139,7 +1139,7 @@ static void region_rect_recursive(wmWindow *win, ScrArea *sa, ARegion *ar, rcti static void area_calc_totrct(ScrArea *sa, int sizex, int sizey) { - short rt = U.pixelsize > 1 ? 1 : 0; + short rt = U.pixelsize > 1.0f ? 1 : 0; if (sa->v1->vec.x > 0) sa->totrct.xmin = sa->v1->vec.x + 1 + rt; else sa->totrct.xmin = sa->v1->vec.x; diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c index 6e65d7fa59a..2e6cb420974 100644 --- a/source/blender/editors/screen/screen_ops.c +++ b/source/blender/editors/screen/screen_ops.c @@ -977,18 +977,18 @@ static void area_move_set_limits(bScreen *sc, int dir, int *bigger, int *smaller int y1 = sa->v2->vec.y - sa->v1->vec.y - areaminy; /* if top or down edge selected, test height */ - if (sa->v1->flag && sa->v4->flag) + if (sa->v1->editflag && sa->v4->editflag) *bigger = min_ii(*bigger, y1); - else if (sa->v2->flag && sa->v3->flag) + else if (sa->v2->editflag && sa->v3->editflag) *smaller = min_ii(*smaller, y1); } else { int x1 = sa->v4->vec.x - sa->v1->vec.x - AREAMINX; /* if left or right edge selected, test width */ - if (sa->v1->flag && sa->v2->flag) + if (sa->v1->editflag && sa->v2->editflag) *bigger = min_ii(*bigger, x1); - else if (sa->v3->flag && sa->v4->flag) + else if (sa->v3->editflag && sa->v4->editflag) *smaller = min_ii(*smaller, x1); } } @@ -1038,7 +1038,7 @@ static void area_move_apply_do(bContext *C, int origval, int delta, int dir, int delta = CLAMPIS(delta, -smaller, bigger); for (v1 = sc->vertbase.first; v1; v1 = v1->next) { - if (v1->flag) { + if (v1->editflag) { /* that way a nice AREAGRID */ if ((dir == 'v') && v1->vec.x > 0 && v1->vec.x < WM_window_pixels_x(win) - 1) { v1->vec.x = origval + delta; @@ -1058,7 +1058,7 @@ static void area_move_apply_do(bContext *C, int origval, int delta, int dir, int } for (sa = sc->areabase.first; sa; sa = sa->next) { - if (sa->v1->flag || sa->v2->flag || sa->v3->flag || sa->v4->flag) + if (sa->v1->editflag || sa->v2->editflag || sa->v3->editflag || sa->v4->editflag) ED_area_tag_redraw(sa); } @@ -1336,10 +1336,10 @@ static int area_split_apply(bContext *C, wmOperator *op) /* select newly created edge, prepare for moving edge */ for (sv = sc->vertbase.first; sv; sv = sv->next) - sv->flag = 0; + sv->editflag = 0; - sd->nedge->v1->flag = 1; - sd->nedge->v2->flag = 1; + sd->nedge->v1->editflag = 1; + sd->nedge->v2->editflag = 1; if (dir == 'h') sd->origval = sd->nedge->v1->vec.y; else sd->origval = sd->nedge->v1->vec.x; diff --git a/source/blender/makesdna/DNA_screen_types.h b/source/blender/makesdna/DNA_screen_types.h index ed2ffdf6702..de6ddb4b896 100644 --- a/source/blender/makesdna/DNA_screen_types.h +++ b/source/blender/makesdna/DNA_screen_types.h @@ -82,7 +82,8 @@ typedef struct bScreen { typedef struct ScrVert { struct ScrVert *next, *prev, *newv; vec2s vec; - int flag; + /* first one used internally, second one for tools */ + short flag, editflag; } ScrVert; typedef struct ScrEdge { From 06888b7bebf66c5b05dd1a8106e35c57458252c0 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Sat, 15 Dec 2012 10:18:42 +0000 Subject: [PATCH 147/252] Cycles OSL minor optimizations: recycle shading context, don't do memory allocations for trace data, avoid some virtual function calls. Only helps a few percentages. --- intern/cycles/kernel/CMakeLists.txt | 2 +- intern/cycles/kernel/closure/bsdf.h | 385 +++++++++++++----- intern/cycles/kernel/closure/bsdf_util.h | 137 +++++++ intern/cycles/kernel/closure/emissive.h | 7 +- intern/cycles/kernel/closure/volume.h | 7 +- intern/cycles/kernel/kernel_displace.h | 4 +- intern/cycles/kernel/kernel_emission.h | 6 +- intern/cycles/kernel/kernel_path.h | 8 +- intern/cycles/kernel/kernel_shader.h | 158 ++----- intern/cycles/kernel/kernel_types.h | 17 +- .../cycles/kernel/osl/bsdf_diffuse_ramp.cpp | 4 +- intern/cycles/kernel/osl/bsdf_phong_ramp.cpp | 4 +- intern/cycles/kernel/osl/emissive.cpp | 2 +- intern/cycles/kernel/osl/osl_closures.cpp | 30 +- intern/cycles/kernel/osl/osl_closures.h | 12 +- intern/cycles/kernel/osl/osl_globals.h | 11 + intern/cycles/kernel/osl/osl_services.cpp | 53 ++- intern/cycles/kernel/osl/osl_services.h | 7 - intern/cycles/kernel/osl/osl_shader.cpp | 144 +++---- intern/cycles/kernel/osl/osl_shader.h | 12 +- intern/cycles/kernel/svm/svm_bsdf.h | 279 ------------- 21 files changed, 599 insertions(+), 690 deletions(-) create mode 100644 intern/cycles/kernel/closure/bsdf_util.h delete mode 100644 intern/cycles/kernel/svm/svm_bsdf.h diff --git a/intern/cycles/kernel/CMakeLists.txt b/intern/cycles/kernel/CMakeLists.txt index b7878e9b00f..b6e024dde17 100644 --- a/intern/cycles/kernel/CMakeLists.txt +++ b/intern/cycles/kernel/CMakeLists.txt @@ -56,6 +56,7 @@ set(SRC_CLOSURE_HEADERS closure/bsdf_reflection.h closure/bsdf_refraction.h closure/bsdf_transparent.h + closure/bsdf_util.h closure/bsdf_ward.h closure/bsdf_westin.h closure/emissive.h @@ -64,7 +65,6 @@ set(SRC_CLOSURE_HEADERS set(SRC_SVM_HEADERS svm/svm.h svm/svm_attribute.h - svm/svm_bsdf.h svm/svm_camera.h svm/svm_closure.h svm/svm_convert.h diff --git a/intern/cycles/kernel/closure/bsdf.h b/intern/cycles/kernel/closure/bsdf.h index cfb6321a918..f26aefe7fd3 100644 --- a/intern/cycles/kernel/closure/bsdf.h +++ b/intern/cycles/kernel/closure/bsdf.h @@ -1,137 +1,296 @@ /* - * Adapted from Open Shading Language with this license: + * Copyright 2011, Blender Foundation. * - * Copyright (c) 2009-2010 Sony Pictures Imageworks Inc., et al. - * All Rights Reserved. + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. * - * Modifications Copyright 2011, Blender Foundation. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Sony Pictures Imageworks nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -#ifndef __OSL_BSDF_H__ -#define __OSL_BSDF_H__ +#include "../closure/bsdf_ashikhmin_velvet.h" +#include "../closure/bsdf_diffuse.h" +#include "../closure/bsdf_oren_nayar.h" +#include "../closure/bsdf_phong_ramp.h" +#include "../closure/bsdf_diffuse_ramp.h" +#include "../closure/bsdf_microfacet.h" +#include "../closure/bsdf_reflection.h" +#include "../closure/bsdf_refraction.h" +#include "../closure/bsdf_transparent.h" +#ifdef __ANISOTROPIC__ +#include "../closure/bsdf_ward.h" +#endif +#include "../closure/bsdf_westin.h" CCL_NAMESPACE_BEGIN -__device float fresnel_dielectric(float eta, const float3 N, - const float3 I, float3 *R, float3 *T, -#ifdef __RAY_DIFFERENTIALS__ - const float3 dIdx, const float3 dIdy, - float3 *dRdx, float3 *dRdy, - float3 *dTdx, float3 *dTdy, -#endif - bool *is_inside) +__device int bsdf_sample(KernelGlobals *kg, const ShaderData *sd, const ShaderClosure *sc, float randu, float randv, float3 *eval, float3 *omega_in, differential3 *domega_in, float *pdf) { - float cos = dot(N, I), neta; - float3 Nn; - // compute reflection - *R = (2 * cos)* N - I; -#ifdef __RAY_DIFFERENTIALS__ - *dRdx = (2 * dot(N, dIdx)) * N - dIdx; - *dRdy = (2 * dot(N, dIdy)) * N - dIdy; + int label; + +#ifdef __OSL__ + if(kg->osl && sc->prim) + return OSLShader::bsdf_sample(sd, sc, randu, randv, *eval, *omega_in, *domega_in, *pdf); #endif - // check which side of the surface we are on - if(cos > 0) { - // we are on the outside of the surface, going in - neta = 1 / eta; - Nn = N; - *is_inside = false; - } - else { - // we are inside the surface, - cos = -cos; - neta = eta; - Nn = -N; - *is_inside = true; - } - *R = (2 * cos)* Nn - I; - float arg = 1 -(neta * neta *(1 -(cos * cos))); - if(arg < 0) { - *T = make_float3(0.0f, 0.0f, 0.0f); -#ifdef __RAY_DIFFERENTIALS__ - *dTdx = make_float3(0.0f, 0.0f, 0.0f); - *dTdy = make_float3(0.0f, 0.0f, 0.0f); + + switch(sc->type) { + case CLOSURE_BSDF_DIFFUSE_ID: + label = bsdf_diffuse_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv, + eval, omega_in, &domega_in->dx, &domega_in->dy, pdf); + break; +#ifdef __SVM__ + case CLOSURE_BSDF_OREN_NAYAR_ID: + label = bsdf_oren_nayar_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv, + eval, omega_in, &domega_in->dx, &domega_in->dy, pdf); + break; + /*case CLOSURE_BSDF_PHONG_RAMP_ID: + label = bsdf_phong_ramp_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv, + eval, omega_in, &domega_in->dx, &domega_in->dy, pdf); + break; + case CLOSURE_BSDF_DIFFUSE_RAMP_ID: + label = bsdf_diffuse_ramp_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv, + eval, omega_in, &domega_in->dx, &domega_in->dy, pdf); + break;*/ + case CLOSURE_BSDF_TRANSLUCENT_ID: + label = bsdf_translucent_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv, + eval, omega_in, &domega_in->dx, &domega_in->dy, pdf); + break; + case CLOSURE_BSDF_REFLECTION_ID: + label = bsdf_reflection_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv, + eval, omega_in, &domega_in->dx, &domega_in->dy, pdf); + break; + case CLOSURE_BSDF_REFRACTION_ID: + label = bsdf_refraction_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv, + eval, omega_in, &domega_in->dx, &domega_in->dy, pdf); + break; + case CLOSURE_BSDF_TRANSPARENT_ID: + label = bsdf_transparent_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv, + eval, omega_in, &domega_in->dx, &domega_in->dy, pdf); + break; + case CLOSURE_BSDF_MICROFACET_GGX_ID: + case CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID: + label = bsdf_microfacet_ggx_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv, + eval, omega_in, &domega_in->dx, &domega_in->dy, pdf); + break; + case CLOSURE_BSDF_MICROFACET_BECKMANN_ID: + case CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID: + label = bsdf_microfacet_beckmann_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv, + eval, omega_in, &domega_in->dx, &domega_in->dy, pdf); + break; +#ifdef __ANISOTROPIC__ + case CLOSURE_BSDF_WARD_ID: + label = bsdf_ward_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv, + eval, omega_in, &domega_in->dx, &domega_in->dy, pdf); + break; #endif - return 1; // total internal reflection - } - else { - float dnp = sqrtf(arg); - float nK = (neta * cos)- dnp; - *T = -(neta * I)+(nK * Nn); -#ifdef __RAY_DIFFERENTIALS__ - *dTdx = -(neta * dIdx) + ((neta - neta * neta * cos / dnp) * dot(dIdx, Nn)) * Nn; - *dTdy = -(neta * dIdy) + ((neta - neta * neta * cos / dnp) * dot(dIdy, Nn)) * Nn; + case CLOSURE_BSDF_ASHIKHMIN_VELVET_ID: + label = bsdf_ashikhmin_velvet_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv, + eval, omega_in, &domega_in->dx, &domega_in->dy, pdf); + break; + case CLOSURE_BSDF_WESTIN_BACKSCATTER_ID: + label = bsdf_westin_backscatter_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv, + eval, omega_in, &domega_in->dx, &domega_in->dy, pdf); + break; + case CLOSURE_BSDF_WESTIN_SHEEN_ID: + label = bsdf_westin_sheen_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv, + eval, omega_in, &domega_in->dx, &domega_in->dy, pdf); + break; #endif - // compute Fresnel terms - float cosTheta1 = cos; // N.R - float cosTheta2 = -dot(Nn, *T); - float pPara = (cosTheta1 - eta * cosTheta2)/(cosTheta1 + eta * cosTheta2); - float pPerp = (eta * cosTheta1 - cosTheta2)/(eta * cosTheta1 + cosTheta2); - return 0.5f * (pPara * pPara + pPerp * pPerp); + default: + label = LABEL_NONE; + break; } + + return label; } -__device float fresnel_dielectric_cos(float cosi, float eta) +__device float3 bsdf_eval(KernelGlobals *kg, const ShaderData *sd, const ShaderClosure *sc, const float3 omega_in, float *pdf) { - // compute fresnel reflectance without explicitly computing - // the refracted direction - float c = fabsf(cosi); - float g = eta * eta - 1 + c * c; - if(g > 0) { - g = sqrtf(g); - float A = (g - c)/(g + c); - float B = (c *(g + c)- 1)/(c *(g - c)+ 1); - return 0.5f * A * A *(1 + B * B); + float3 eval; + +#ifdef __OSL__ + if(kg->osl && sc->prim) + return OSLShader::bsdf_eval(sd, sc, omega_in, *pdf); +#endif + + if(dot(sd->Ng, omega_in) >= 0.0f) { + switch(sc->type) { + case CLOSURE_BSDF_DIFFUSE_ID: + eval = bsdf_diffuse_eval_reflect(sc, sd->I, omega_in, pdf); + break; +#ifdef __SVM__ + case CLOSURE_BSDF_OREN_NAYAR_ID: + eval = bsdf_oren_nayar_eval_reflect(sc, sd->I, omega_in, pdf); + break; + /*case CLOSURE_BSDF_PHONG_RAMP_ID: + eval = bsdf_phong_ramp_eval_reflect(sc, sd->I, omega_in, pdf); + break; + case CLOSURE_BSDF_DIFFUSE_RAMP_ID: + eval = bsdf_diffuse_ramp_eval_reflect(sc, sd->I, omega_in, pdf); + break;*/ + case CLOSURE_BSDF_TRANSLUCENT_ID: + eval = bsdf_translucent_eval_reflect(sc, sd->I, omega_in, pdf); + break; + case CLOSURE_BSDF_REFLECTION_ID: + eval = bsdf_reflection_eval_reflect(sc, sd->I, omega_in, pdf); + break; + case CLOSURE_BSDF_REFRACTION_ID: + eval = bsdf_refraction_eval_reflect(sc, sd->I, omega_in, pdf); + break; + case CLOSURE_BSDF_TRANSPARENT_ID: + eval = bsdf_transparent_eval_reflect(sc, sd->I, omega_in, pdf); + break; + case CLOSURE_BSDF_MICROFACET_GGX_ID: + case CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID: + eval = bsdf_microfacet_ggx_eval_reflect(sc, sd->I, omega_in, pdf); + break; + case CLOSURE_BSDF_MICROFACET_BECKMANN_ID: + case CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID: + eval = bsdf_microfacet_beckmann_eval_reflect(sc, sd->I, omega_in, pdf); + break; +#ifdef __ANISOTROPIC__ + case CLOSURE_BSDF_WARD_ID: + eval = bsdf_ward_eval_reflect(sc, sd->I, omega_in, pdf); + break; +#endif + case CLOSURE_BSDF_ASHIKHMIN_VELVET_ID: + eval = bsdf_ashikhmin_velvet_eval_reflect(sc, sd->I, omega_in, pdf); + break; + case CLOSURE_BSDF_WESTIN_BACKSCATTER_ID: + eval = bsdf_westin_backscatter_eval_reflect(sc, sd->I, omega_in, pdf); + break; + case CLOSURE_BSDF_WESTIN_SHEEN_ID: + eval = bsdf_westin_sheen_eval_reflect(sc, sd->I, omega_in, pdf); + break; +#endif + default: + eval = make_float3(0.0f, 0.0f, 0.0f); + break; + } } - return 1.0f; // TIR(no refracted component) -} - -__device float fresnel_conductor(float cosi, float eta, float k) -{ - float tmp_f = eta * eta + k * k; - float tmp = tmp_f * cosi * cosi; - float Rparl2 = (tmp - (2.0f * eta * cosi) + 1)/ - (tmp + (2.0f * eta * cosi) + 1); - float Rperp2 = (tmp_f - (2.0f * eta * cosi) + cosi * cosi)/ - (tmp_f + (2.0f * eta * cosi) + cosi * cosi); - return(Rparl2 + Rperp2) * 0.5f; -} - -__device float smooth_step(float edge0, float edge1, float x) -{ - float result; - if(x < edge0) result = 0.0f; - else if(x >= edge1) result = 1.0f; else { - float t = (x - edge0)/(edge1 - edge0); - result = (3.0f-2.0f*t)*(t*t); + switch(sc->type) { + case CLOSURE_BSDF_DIFFUSE_ID: + eval = bsdf_diffuse_eval_transmit(sc, sd->I, omega_in, pdf); + break; +#ifdef __SVM__ + case CLOSURE_BSDF_OREN_NAYAR_ID: + eval = bsdf_oren_nayar_eval_transmit(sc, sd->I, omega_in, pdf); + break; + case CLOSURE_BSDF_TRANSLUCENT_ID: + eval = bsdf_translucent_eval_transmit(sc, sd->I, omega_in, pdf); + break; + case CLOSURE_BSDF_REFLECTION_ID: + eval = bsdf_reflection_eval_transmit(sc, sd->I, omega_in, pdf); + break; + case CLOSURE_BSDF_REFRACTION_ID: + eval = bsdf_refraction_eval_transmit(sc, sd->I, omega_in, pdf); + break; + case CLOSURE_BSDF_TRANSPARENT_ID: + eval = bsdf_transparent_eval_transmit(sc, sd->I, omega_in, pdf); + break; + case CLOSURE_BSDF_MICROFACET_GGX_ID: + case CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID: + eval = bsdf_microfacet_ggx_eval_transmit(sc, sd->I, omega_in, pdf); + break; + case CLOSURE_BSDF_MICROFACET_BECKMANN_ID: + case CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID: + eval = bsdf_microfacet_beckmann_eval_transmit(sc, sd->I, omega_in, pdf); + break; +#ifdef __ANISOTROPIC__ + case CLOSURE_BSDF_WARD_ID: + eval = bsdf_ward_eval_transmit(sc, sd->I, omega_in, pdf); + break; +#endif + case CLOSURE_BSDF_ASHIKHMIN_VELVET_ID: + eval = bsdf_ashikhmin_velvet_eval_transmit(sc, sd->I, omega_in, pdf); + break; + case CLOSURE_BSDF_WESTIN_BACKSCATTER_ID: + eval = bsdf_westin_backscatter_eval_transmit(sc, sd->I, omega_in, pdf); + break; + case CLOSURE_BSDF_WESTIN_SHEEN_ID: + eval = bsdf_westin_sheen_eval_transmit(sc, sd->I, omega_in, pdf); + break; +#endif + default: + eval = make_float3(0.0f, 0.0f, 0.0f); + break; + } + } + + return eval; +} + +__device void bsdf_blur(KernelGlobals *kg, ShaderClosure *sc, float roughness) +{ +#ifdef __OSL__ + if(kg->osl && sc->prim) { + OSLShader::bsdf_blur(sc, roughness); + return; + } +#endif + + switch(sc->type) { + case CLOSURE_BSDF_DIFFUSE_ID: + bsdf_diffuse_blur(sc, roughness); + break; +#ifdef __SVM__ + case CLOSURE_BSDF_OREN_NAYAR_ID: + bsdf_oren_nayar_blur(sc, roughness); + break; + /*case CLOSURE_BSDF_PHONG_RAMP_ID: + bsdf_phong_ramp_blur(sc, roughness); + break; + case CLOSURE_BSDF_DIFFUSE_RAMP_ID: + bsdf_diffuse_ramp_blur(sc, roughness); + break;*/ + case CLOSURE_BSDF_TRANSLUCENT_ID: + bsdf_translucent_blur(sc, roughness); + break; + case CLOSURE_BSDF_REFLECTION_ID: + bsdf_reflection_blur(sc, roughness); + break; + case CLOSURE_BSDF_REFRACTION_ID: + bsdf_refraction_blur(sc, roughness); + break; + case CLOSURE_BSDF_TRANSPARENT_ID: + bsdf_transparent_blur(sc, roughness); + break; + case CLOSURE_BSDF_MICROFACET_GGX_ID: + case CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID: + bsdf_microfacet_ggx_blur(sc, roughness); + break; + case CLOSURE_BSDF_MICROFACET_BECKMANN_ID: + case CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID: + bsdf_microfacet_beckmann_blur(sc, roughness); + break; +#ifdef __ANISOTROPIC__ + case CLOSURE_BSDF_WARD_ID: + bsdf_ward_blur(sc, roughness); + break; +#endif + case CLOSURE_BSDF_ASHIKHMIN_VELVET_ID: + bsdf_ashikhmin_velvet_blur(sc, roughness); + break; + case CLOSURE_BSDF_WESTIN_BACKSCATTER_ID: + bsdf_westin_backscatter_blur(sc, roughness); + break; + case CLOSURE_BSDF_WESTIN_SHEEN_ID: + bsdf_westin_sheen_blur(sc, roughness); + break; +#endif + default: + break; } - return result; } CCL_NAMESPACE_END -#endif /* __OSL_BSDF_H__ */ - diff --git a/intern/cycles/kernel/closure/bsdf_util.h b/intern/cycles/kernel/closure/bsdf_util.h new file mode 100644 index 00000000000..cfb6321a918 --- /dev/null +++ b/intern/cycles/kernel/closure/bsdf_util.h @@ -0,0 +1,137 @@ +/* + * Adapted from Open Shading Language with this license: + * + * Copyright (c) 2009-2010 Sony Pictures Imageworks Inc., et al. + * All Rights Reserved. + * + * Modifications Copyright 2011, Blender Foundation. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Sony Pictures Imageworks nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __OSL_BSDF_H__ +#define __OSL_BSDF_H__ + +CCL_NAMESPACE_BEGIN + +__device float fresnel_dielectric(float eta, const float3 N, + const float3 I, float3 *R, float3 *T, +#ifdef __RAY_DIFFERENTIALS__ + const float3 dIdx, const float3 dIdy, + float3 *dRdx, float3 *dRdy, + float3 *dTdx, float3 *dTdy, +#endif + bool *is_inside) +{ + float cos = dot(N, I), neta; + float3 Nn; + // compute reflection + *R = (2 * cos)* N - I; +#ifdef __RAY_DIFFERENTIALS__ + *dRdx = (2 * dot(N, dIdx)) * N - dIdx; + *dRdy = (2 * dot(N, dIdy)) * N - dIdy; +#endif + // check which side of the surface we are on + if(cos > 0) { + // we are on the outside of the surface, going in + neta = 1 / eta; + Nn = N; + *is_inside = false; + } + else { + // we are inside the surface, + cos = -cos; + neta = eta; + Nn = -N; + *is_inside = true; + } + *R = (2 * cos)* Nn - I; + float arg = 1 -(neta * neta *(1 -(cos * cos))); + if(arg < 0) { + *T = make_float3(0.0f, 0.0f, 0.0f); +#ifdef __RAY_DIFFERENTIALS__ + *dTdx = make_float3(0.0f, 0.0f, 0.0f); + *dTdy = make_float3(0.0f, 0.0f, 0.0f); +#endif + return 1; // total internal reflection + } + else { + float dnp = sqrtf(arg); + float nK = (neta * cos)- dnp; + *T = -(neta * I)+(nK * Nn); +#ifdef __RAY_DIFFERENTIALS__ + *dTdx = -(neta * dIdx) + ((neta - neta * neta * cos / dnp) * dot(dIdx, Nn)) * Nn; + *dTdy = -(neta * dIdy) + ((neta - neta * neta * cos / dnp) * dot(dIdy, Nn)) * Nn; +#endif + // compute Fresnel terms + float cosTheta1 = cos; // N.R + float cosTheta2 = -dot(Nn, *T); + float pPara = (cosTheta1 - eta * cosTheta2)/(cosTheta1 + eta * cosTheta2); + float pPerp = (eta * cosTheta1 - cosTheta2)/(eta * cosTheta1 + cosTheta2); + return 0.5f * (pPara * pPara + pPerp * pPerp); + } +} + +__device float fresnel_dielectric_cos(float cosi, float eta) +{ + // compute fresnel reflectance without explicitly computing + // the refracted direction + float c = fabsf(cosi); + float g = eta * eta - 1 + c * c; + if(g > 0) { + g = sqrtf(g); + float A = (g - c)/(g + c); + float B = (c *(g + c)- 1)/(c *(g - c)+ 1); + return 0.5f * A * A *(1 + B * B); + } + return 1.0f; // TIR(no refracted component) +} + +__device float fresnel_conductor(float cosi, float eta, float k) +{ + float tmp_f = eta * eta + k * k; + float tmp = tmp_f * cosi * cosi; + float Rparl2 = (tmp - (2.0f * eta * cosi) + 1)/ + (tmp + (2.0f * eta * cosi) + 1); + float Rperp2 = (tmp_f - (2.0f * eta * cosi) + cosi * cosi)/ + (tmp_f + (2.0f * eta * cosi) + cosi * cosi); + return(Rparl2 + Rperp2) * 0.5f; +} + +__device float smooth_step(float edge0, float edge1, float x) +{ + float result; + if(x < edge0) result = 0.0f; + else if(x >= edge1) result = 1.0f; + else { + float t = (x - edge0)/(edge1 - edge0); + result = (3.0f-2.0f*t)*(t*t); + } + return result; +} + +CCL_NAMESPACE_END + +#endif /* __OSL_BSDF_H__ */ + diff --git a/intern/cycles/kernel/closure/emissive.h b/intern/cycles/kernel/closure/emissive.h index cbf9d9a4efb..33b1b695a9a 100644 --- a/intern/cycles/kernel/closure/emissive.h +++ b/intern/cycles/kernel/closure/emissive.h @@ -49,17 +49,12 @@ __device void emissive_sample(const float3 Ng, float randu, float randv, /* todo: not implemented and used yet */ } -__device float3 emissive_eval(const float3 Ng, const float3 I) +__device float3 emissive_simple_eval(const float3 Ng, const float3 I) { float res = emissive_pdf(Ng, I); return make_float3(res, res, res); } -__device float3 svm_emissive_eval(ShaderData *sd, ShaderClosure *sc) -{ - return emissive_eval(sd->Ng, sd->I); -} - CCL_NAMESPACE_END diff --git a/intern/cycles/kernel/closure/volume.h b/intern/cycles/kernel/closure/volume.h index 734f9111ab6..0b553f38a25 100644 --- a/intern/cycles/kernel/closure/volume.h +++ b/intern/cycles/kernel/closure/volume.h @@ -53,8 +53,13 @@ __device float3 volume_transparent_eval_phase(const ShaderClosure *sc, const flo /* VOLUME CLOSURE */ -__device float3 volume_eval_phase(const ShaderClosure *sc, const float3 omega_in, const float3 omega_out) +__device float3 volume_eval_phase(KernelGlobals *kg, const ShaderClosure *sc, const float3 omega_in, const float3 omega_out) { +#ifdef __OSL__ + if(kg->osl && sc->prim) + return OSLShader::volume_eval_phase(sc, omega_in, omega_out); +#endif + float3 eval; switch(sc->type) { diff --git a/intern/cycles/kernel/kernel_displace.h b/intern/cycles/kernel/kernel_displace.h index a55f7a7fd75..fc2be342e02 100644 --- a/intern/cycles/kernel/kernel_displace.h +++ b/intern/cycles/kernel/kernel_displace.h @@ -35,7 +35,7 @@ __device void kernel_shader_evaluate(KernelGlobals *kg, uint4 *input, float4 *ou /* evaluate */ float3 P = sd.P; - shader_eval_displacement(kg, &sd); + shader_eval_displacement(kg, &sd, SHADER_CONTEXT_MAIN); out = sd.P - P; } else { // SHADER_EVAL_BACKGROUND @@ -63,7 +63,7 @@ __device void kernel_shader_evaluate(KernelGlobals *kg, uint4 *input, float4 *ou /* evaluate */ int flag = 0; /* we can't know which type of BSDF this is for */ - out = shader_eval_background(kg, &sd, flag); + out = shader_eval_background(kg, &sd, flag, SHADER_CONTEXT_MAIN); } shader_release(kg, &sd); diff --git a/intern/cycles/kernel/kernel_emission.h b/intern/cycles/kernel/kernel_emission.h index 6d650a0158d..e56633c9358 100644 --- a/intern/cycles/kernel/kernel_emission.h +++ b/intern/cycles/kernel/kernel_emission.h @@ -42,7 +42,7 @@ __device float3 direct_emissive_eval(KernelGlobals *kg, float rando, ray.time = time; #endif shader_setup_from_background(kg, &sd, &ray); - eval = shader_eval_background(kg, &sd, 0); + eval = shader_eval_background(kg, &sd, 0, SHADER_CONTEXT_EMISSION); } else #endif @@ -52,7 +52,7 @@ __device float3 direct_emissive_eval(KernelGlobals *kg, float rando, /* no path flag, we're evaluating this for all closures. that's weak but * we'd have to do multiple evaluations otherwise */ - shader_eval_surface(kg, &sd, rando, 0); + shader_eval_surface(kg, &sd, rando, 0, SHADER_CONTEXT_EMISSION); /* evaluate emissive closure */ if(sd.flag & SD_EMISSION) @@ -170,7 +170,7 @@ __device float3 indirect_background(KernelGlobals *kg, Ray *ray, int path_flag, /* evaluate background closure */ ShaderData sd; shader_setup_from_background(kg, &sd, ray); - float3 L = shader_eval_background(kg, &sd, path_flag); + float3 L = shader_eval_background(kg, &sd, path_flag, SHADER_CONTEXT_EMISSION); shader_release(kg, &sd); #ifdef __BACKGROUND_MIS__ diff --git a/intern/cycles/kernel/kernel_path.h b/intern/cycles/kernel/kernel_path.h index 3588b09c790..8da21751cbe 100644 --- a/intern/cycles/kernel/kernel_path.h +++ b/intern/cycles/kernel/kernel_path.h @@ -207,7 +207,7 @@ __device_inline bool shadow_blocked(KernelGlobals *kg, PathState *state, Ray *ra ShaderData sd; shader_setup_from_ray(kg, &sd, &isect, ray); - shader_eval_surface(kg, &sd, 0.0f, PATH_RAY_SHADOW); + shader_eval_surface(kg, &sd, 0.0f, PATH_RAY_SHADOW, SHADER_CONTEXT_SHADOW); throughput *= shader_bsdf_transparency(kg, &sd); @@ -272,7 +272,7 @@ __device float4 kernel_path_progressive(KernelGlobals *kg, RNG *rng, int sample, ShaderData sd; shader_setup_from_ray(kg, &sd, &isect, &ray); float rbsdf = path_rng(kg, rng, sample, rng_offset + PRNG_BSDF); - shader_eval_surface(kg, &sd, rbsdf, state.flag); + shader_eval_surface(kg, &sd, rbsdf, state.flag, SHADER_CONTEXT_MAIN); kernel_write_data_passes(kg, buffer, &L, &sd, sample, state.flag, throughput); @@ -478,7 +478,7 @@ __device void kernel_path_indirect(KernelGlobals *kg, RNG *rng, int sample, Ray ShaderData sd; shader_setup_from_ray(kg, &sd, &isect, &ray); float rbsdf = path_rng(kg, rng, sample, rng_offset + PRNG_BSDF); - shader_eval_surface(kg, &sd, rbsdf, state.flag); + shader_eval_surface(kg, &sd, rbsdf, state.flag, SHADER_CONTEXT_INDIRECT); shader_merge_closures(kg, &sd); /* blurring of bsdf after bounces, for rays that have a small likelihood @@ -666,7 +666,7 @@ __device float4 kernel_path_non_progressive(KernelGlobals *kg, RNG *rng, int sam ShaderData sd; shader_setup_from_ray(kg, &sd, &isect, &ray); float rbsdf = path_rng(kg, rng, sample, rng_offset + PRNG_BSDF); - shader_eval_surface(kg, &sd, rbsdf, state.flag); + shader_eval_surface(kg, &sd, rbsdf, state.flag, SHADER_CONTEXT_MAIN); shader_merge_closures(kg, &sd); kernel_write_data_passes(kg, buffer, &L, &sd, sample, state.flag, throughput); diff --git a/intern/cycles/kernel/kernel_shader.h b/intern/cycles/kernel/kernel_shader.h index 98a7ec59d7b..9bbfe6b0cc5 100644 --- a/intern/cycles/kernel/kernel_shader.h +++ b/intern/cycles/kernel/kernel_shader.h @@ -26,11 +26,11 @@ * */ +#include "closure/bsdf_util.h" #include "closure/bsdf.h" #include "closure/emissive.h" #include "closure/volume.h" -#include "svm/svm_bsdf.h" #include "svm/svm.h" CCL_NAMESPACE_BEGIN @@ -56,11 +56,6 @@ __device_noinline void shader_setup_object_transforms(KernelGlobals *kg, ShaderD __device_inline void shader_setup_from_ray(KernelGlobals *kg, ShaderData *sd, const Intersection *isect, const Ray *ray) { -#ifdef __OSL__ - if (kg->osl) - OSLShader::init(kg, sd); -#endif - /* fetch triangle data */ int prim = kernel_tex_fetch(__prim_index, isect->prim); float4 Ns = kernel_tex_fetch(__tri_normal, prim); @@ -142,11 +137,6 @@ __device void shader_setup_from_sample(KernelGlobals *kg, ShaderData *sd, const float3 P, const float3 Ng, const float3 I, int shader, int object, int prim, float u, float v, float t, float time) { -#ifdef __OSL__ - if (kg->osl) - OSLShader::init(kg, sd); -#endif - /* vectors */ sd->P = P; sd->N = Ng; @@ -273,11 +263,6 @@ __device void shader_setup_from_displace(KernelGlobals *kg, ShaderData *sd, __device_inline void shader_setup_from_background(KernelGlobals *kg, ShaderData *sd, const Ray *ray) { -#ifdef __OSL__ - if (kg->osl) - OSLShader::init(kg, sd); -#endif - /* vectors */ sd->P = ray->D; sd->N = -sd->P; @@ -320,9 +305,8 @@ __device_inline void shader_setup_from_background(KernelGlobals *kg, ShaderData #ifdef __MULTI_CLOSURE__ -#ifdef __OSL__ -__device_inline void _shader_bsdf_multi_eval_osl(const ShaderData *sd, const float3 omega_in, float *pdf, - int skip_bsdf, BsdfEval *bsdf_eval, float sum_pdf, float sum_sample_weight) +__device_inline void _shader_bsdf_multi_eval(KernelGlobals *kg, const ShaderData *sd, const float3 omega_in, float *pdf, + int skip_bsdf, BsdfEval *result_eval, float sum_pdf, float sum_sample_weight) { for(int i = 0; i< sd->num_closure; i++) { if(i == skip_bsdf) @@ -332,38 +316,10 @@ __device_inline void _shader_bsdf_multi_eval_osl(const ShaderData *sd, const flo if(CLOSURE_IS_BSDF(sc->type)) { float bsdf_pdf = 0.0f; - - float3 eval = OSLShader::bsdf_eval(sd, sc, omega_in, bsdf_pdf); + float3 eval = bsdf_eval(kg, sd, sc, omega_in, &bsdf_pdf); if(bsdf_pdf != 0.0f) { - bsdf_eval_accum(bsdf_eval, sc->type, eval*sc->weight); - sum_pdf += bsdf_pdf*sc->sample_weight; - } - - sum_sample_weight += sc->sample_weight; - } - } - - *pdf = (sum_sample_weight > 0.0f)? sum_pdf/sum_sample_weight: 0.0f; -} -#endif - -__device_inline void _shader_bsdf_multi_eval_svm(const ShaderData *sd, const float3 omega_in, float *pdf, - int skip_bsdf, BsdfEval *bsdf_eval, float sum_pdf, float sum_sample_weight) -{ - for(int i = 0; i< sd->num_closure; i++) { - if(i == skip_bsdf) - continue; - - const ShaderClosure *sc = &sd->closure[i]; - - if(CLOSURE_IS_BSDF(sc->type)) { - float bsdf_pdf = 0.0f; - - float3 eval = svm_bsdf_eval(sd, sc, omega_in, &bsdf_pdf); - - if(bsdf_pdf != 0.0f) { - bsdf_eval_accum(bsdf_eval, sc->type, eval*sc->weight); + bsdf_eval_accum(result_eval, sc->type, eval*sc->weight); sum_pdf += bsdf_pdf*sc->sample_weight; } @@ -382,17 +338,12 @@ __device void shader_bsdf_eval(KernelGlobals *kg, const ShaderData *sd, #ifdef __MULTI_CLOSURE__ bsdf_eval_init(eval, NBUILTIN_CLOSURES, make_float3(0.0f, 0.0f, 0.0f), kernel_data.film.use_light_pass); -#ifdef __OSL__ - if (kg->osl) - return _shader_bsdf_multi_eval_osl(sd, omega_in, pdf, -1, eval, 0.0f, 0.0f); - else -#endif - return _shader_bsdf_multi_eval_svm(sd, omega_in, pdf, -1, eval, 0.0f, 0.0f); + return _shader_bsdf_multi_eval(kg, sd, omega_in, pdf, -1, eval, 0.0f, 0.0f); #else const ShaderClosure *sc = &sd->closure; *pdf = 0.0f; - *eval = svm_bsdf_eval(sd, sc, omega_in, pdf)*sc->weight; + *eval = bsdf_eval(kg, sd, sc, omega_in, pdf)*sc->weight; #endif } @@ -439,24 +390,14 @@ __device int shader_bsdf_sample(KernelGlobals *kg, const ShaderData *sd, float3 eval; *pdf = 0.0f; -#ifdef __OSL__ - if (kg->osl) - label = OSLShader::bsdf_sample(sd, sc, randu, randv, eval, *omega_in, *domega_in, *pdf); - else -#endif - label = svm_bsdf_sample(sd, sc, randu, randv, &eval, omega_in, domega_in, pdf); + label = bsdf_sample(kg, sd, sc, randu, randv, &eval, omega_in, domega_in, pdf); if(*pdf != 0.0f) { bsdf_eval_init(bsdf_eval, sc->type, eval*sc->weight, kernel_data.film.use_light_pass); if(sd->num_closure > 1) { float sweight = sc->sample_weight; -#ifdef __OSL__ - if (kg->osl) - _shader_bsdf_multi_eval_osl(sd, *omega_in, pdf, sampled, bsdf_eval, *pdf*sweight, sweight); - else -#endif - _shader_bsdf_multi_eval_svm(sd, *omega_in, pdf, sampled, bsdf_eval, *pdf*sweight, sweight); + _shader_bsdf_multi_eval(kg, sd, *omega_in, pdf, sampled, bsdf_eval, *pdf*sweight, sweight); } } @@ -464,7 +405,7 @@ __device int shader_bsdf_sample(KernelGlobals *kg, const ShaderData *sd, #else /* sample the single closure that we picked */ *pdf = 0.0f; - int label = svm_bsdf_sample(sd, &sd->closure, randu, randv, bsdf_eval, omega_in, domega_in, pdf); + int label = bsdf_sample(kg, sd, &sd->closure, randu, randv, bsdf_eval, omega_in, domega_in, pdf); *bsdf_eval *= sd->closure.weight; return label; #endif @@ -478,12 +419,7 @@ __device int shader_bsdf_sample_closure(KernelGlobals *kg, const ShaderData *sd, float3 eval; *pdf = 0.0f; -#ifdef __OSL__ - if (kg->osl) - label = OSLShader::bsdf_sample(sd, sc, randu, randv, eval, *omega_in, *domega_in, *pdf); - else -#endif - label = svm_bsdf_sample(sd, sc, randu, randv, &eval, omega_in, domega_in, pdf); + label = bsdf_sample(kg, sd, sc, randu, randv, &eval, omega_in, domega_in, pdf); if(*pdf != 0.0f) bsdf_eval_init(bsdf_eval, sc->type, eval*sc->weight, kernel_data.film.use_light_pass); @@ -497,17 +433,11 @@ __device void shader_bsdf_blur(KernelGlobals *kg, ShaderData *sd, float roughnes for(int i = 0; i< sd->num_closure; i++) { ShaderClosure *sc = &sd->closure[i]; - if(CLOSURE_IS_BSDF(sc->type)) { -#ifdef __OSL__ - if (kg->osl) - OSLShader::bsdf_blur(sc, roughness); - else -#endif - svm_bsdf_blur(sc, roughness); - } + if(CLOSURE_IS_BSDF(sc->type)) + bsdf_blur(kg, sc, roughness); } #else - svm_bsdf_blur(&sd->closure, roughness); + bsdf_blur(kg, &sd->closure, roughness); #endif } @@ -635,6 +565,16 @@ __device float3 shader_bsdf_ao(KernelGlobals *kg, ShaderData *sd, float ao_facto /* Emission */ +__device float3 emissive_eval(KernelGlobals *kg, ShaderData *sd, ShaderClosure *sc) +{ +#ifdef __OSL__ + if(kg->osl && sc->prim) + return OSLShader::emissive_eval(sd, sc); +#endif + + return emissive_simple_eval(sd->Ng, sd->I); +} + __device float3 shader_emissive_eval(KernelGlobals *kg, ShaderData *sd) { float3 eval; @@ -644,18 +584,11 @@ __device float3 shader_emissive_eval(KernelGlobals *kg, ShaderData *sd) for(int i = 0; i < sd->num_closure; i++) { ShaderClosure *sc = &sd->closure[i]; - if(CLOSURE_IS_EMISSION(sc->type)) { -#ifdef __OSL__ - if (kg->osl) - eval += OSLShader::emissive_eval(sd, sc)*sc->weight; - else -#endif - eval += svm_emissive_eval(sd, sc)*sc->weight; - - } + if(CLOSURE_IS_EMISSION(sc->type)) + eval += emissive_eval(kg, sd, sc)*sc->weight; } #else - eval = svm_emissive_eval(sd, &sd->closure)*sd->closure.weight; + eval = emissive_eval(kg, sd, &sd->closure)*sd->closure.weight; #endif return eval; @@ -687,11 +620,11 @@ __device float3 shader_holdout_eval(KernelGlobals *kg, ShaderData *sd) /* Surface Evaluation */ __device void shader_eval_surface(KernelGlobals *kg, ShaderData *sd, - float randb, int path_flag) + float randb, int path_flag, ShaderContext ctx) { #ifdef __OSL__ if (kg->osl) - OSLShader::eval_surface(kg, sd, randb, path_flag); + OSLShader::eval_surface(kg, sd, randb, path_flag, ctx); else #endif { @@ -706,11 +639,11 @@ __device void shader_eval_surface(KernelGlobals *kg, ShaderData *sd, /* Background Evaluation */ -__device float3 shader_eval_background(KernelGlobals *kg, ShaderData *sd, int path_flag) +__device float3 shader_eval_background(KernelGlobals *kg, ShaderData *sd, int path_flag, ShaderContext ctx) { #ifdef __OSL__ if (kg->osl) - return OSLShader::eval_background(kg, sd, path_flag); + return OSLShader::eval_background(kg, sd, path_flag, ctx); else #endif @@ -753,31 +686,25 @@ __device float3 shader_volume_eval_phase(KernelGlobals *kg, ShaderData *sd, for(int i = 0; i< sd->num_closure; i++) { const ShaderClosure *sc = &sd->closure[i]; - if(CLOSURE_IS_VOLUME(sc->type)) { -#ifdef __OSL__ - if (kg->osl) - eval += OSLShader::volume_eval_phase(sc, omega_in, omega_out); - else -#endif - eval += volume_eval_phase(sc, omega_in, omega_out); - } + if(CLOSURE_IS_VOLUME(sc->type)) + eval += volume_eval_phase(kg, sc, omega_in, omega_out); } return eval; #else - return volume_eval_phase(&sd->closure, omega_in, omega_out); + return volume_eval_phase(kg, &sd->closure, omega_in, omega_out); #endif } /* Volume Evaluation */ __device void shader_eval_volume(KernelGlobals *kg, ShaderData *sd, - float randb, int path_flag) + float randb, int path_flag, ShaderContext ctx) { #ifdef __SVM__ #ifdef __OSL__ if (kg->osl) - OSLShader::eval_volume(kg, sd, randb, path_flag); + OSLShader::eval_volume(kg, sd, randb, path_flag, ctx); else #endif svm_eval_nodes(kg, sd, SHADER_TYPE_VOLUME, randb, path_flag); @@ -786,13 +713,13 @@ __device void shader_eval_volume(KernelGlobals *kg, ShaderData *sd, /* Displacement Evaluation */ -__device void shader_eval_displacement(KernelGlobals *kg, ShaderData *sd) +__device void shader_eval_displacement(KernelGlobals *kg, ShaderData *sd, ShaderContext ctx) { /* this will modify sd->P */ #ifdef __SVM__ #ifdef __OSL__ if (kg->osl) - OSLShader::eval_displacement(kg, sd); + OSLShader::eval_displacement(kg, sd, ctx); else #endif svm_eval_nodes(kg, sd, SHADER_TYPE_DISPLACEMENT, 0.0f, 0); @@ -818,7 +745,6 @@ __device bool shader_transparent_shadow(KernelGlobals *kg, Intersection *isect) #ifdef __NON_PROGRESSIVE__ __device void shader_merge_closures(KernelGlobals *kg, ShaderData *sd) { -#ifndef __OSL__ /* merge identical closures, better when we sample a single closure at a time */ for(int i = 0; i < sd->num_closure; i++) { ShaderClosure *sci = &sd->closure[i]; @@ -826,7 +752,7 @@ __device void shader_merge_closures(KernelGlobals *kg, ShaderData *sd) for(int j = i + 1; j < sd->num_closure; j++) { ShaderClosure *scj = &sd->closure[j]; - if(sci->type == scj->type && sci->data0 == scj->data0 && sci->data1 == scj->data1) { + if(!sci->prim && sci->type == scj->type && sci->data0 == scj->data0 && sci->data1 == scj->data1) { sci->weight += scj->weight; sci->sample_weight += scj->sample_weight; @@ -838,7 +764,6 @@ __device void shader_merge_closures(KernelGlobals *kg, ShaderData *sd) } } } -#endif } #endif @@ -846,10 +771,7 @@ __device void shader_merge_closures(KernelGlobals *kg, ShaderData *sd) __device void shader_release(KernelGlobals *kg, ShaderData *sd) { -#ifdef __OSL__ - if (kg->osl) - OSLShader::release(kg, sd); -#endif + /* nothing to do currently */ } CCL_NAMESPACE_END diff --git a/intern/cycles/kernel/kernel_types.h b/intern/cycles/kernel/kernel_types.h index e3a766e56b1..a0673f55681 100644 --- a/intern/cycles/kernel/kernel_types.h +++ b/intern/cycles/kernel/kernel_types.h @@ -379,6 +379,18 @@ typedef struct ShaderClosure { #endif } ShaderClosure; +/* Shader Context + * + * For OSL we recycle a fixed number of contexts for speed */ + +typedef enum ShaderContext { + SHADER_CONTEXT_MAIN = 0, + SHADER_CONTEXT_INDIRECT = 1, + SHADER_CONTEXT_EMISSION = 2, + SHADER_CONTEXT_SHADOW = 3, + SHADER_CONTEXT_NUM = 4 +} ShaderContext; + /* Shader Data * * Main shader state at a point on the surface or in a volume. All coordinates @@ -466,11 +478,6 @@ typedef struct ShaderData { /* Closure data, with a single sampled closure for low memory usage */ ShaderClosure closure; #endif - -#ifdef __OSL__ - /* OSL context */ - void *osl_ctx; -#endif } ShaderData; /* Constrant Kernel Data diff --git a/intern/cycles/kernel/osl/bsdf_diffuse_ramp.cpp b/intern/cycles/kernel/osl/bsdf_diffuse_ramp.cpp index 7189f99a822..a320bea118a 100644 --- a/intern/cycles/kernel/osl/bsdf_diffuse_ramp.cpp +++ b/intern/cycles/kernel/osl/bsdf_diffuse_ramp.cpp @@ -55,7 +55,7 @@ public: void setup() { - sc.N = TO_FLOAT3(N); + sc.prim = this; m_shaderdata_flag = bsdf_diffuse_ramp_setup(&sc); for(int i = 0; i < 8; i++) @@ -101,7 +101,7 @@ public: ClosureParam *closure_bsdf_diffuse_ramp_params() { static ClosureParam params[] = { - CLOSURE_VECTOR_PARAM(DiffuseRampClosure, N), + CLOSURE_FLOAT3_PARAM(DiffuseRampClosure, sc.N), CLOSURE_COLOR_ARRAY_PARAM(DiffuseRampClosure, colors, 8), CLOSURE_STRING_KEYPARAM("label"), CLOSURE_FINISH_PARAM(DiffuseRampClosure) diff --git a/intern/cycles/kernel/osl/bsdf_phong_ramp.cpp b/intern/cycles/kernel/osl/bsdf_phong_ramp.cpp index fb144be7e50..ef656ee7d5f 100644 --- a/intern/cycles/kernel/osl/bsdf_phong_ramp.cpp +++ b/intern/cycles/kernel/osl/bsdf_phong_ramp.cpp @@ -54,7 +54,7 @@ public: void setup() { - sc.N = TO_FLOAT3(N); + sc.prim = this; m_shaderdata_flag = bsdf_phong_ramp_setup(&sc); for(int i = 0; i < 8; i++) @@ -100,7 +100,7 @@ public: ClosureParam *closure_bsdf_phong_ramp_params() { static ClosureParam params[] = { - CLOSURE_VECTOR_PARAM(PhongRampClosure, N), + CLOSURE_FLOAT3_PARAM(PhongRampClosure, sc.N), CLOSURE_FLOAT_PARAM(PhongRampClosure, sc.data0), CLOSURE_COLOR_ARRAY_PARAM(PhongRampClosure, colors, 8), CLOSURE_STRING_KEYPARAM("label"), diff --git a/intern/cycles/kernel/osl/emissive.cpp b/intern/cycles/kernel/osl/emissive.cpp index 37e3e37c00a..7d9fa81dbdd 100644 --- a/intern/cycles/kernel/osl/emissive.cpp +++ b/intern/cycles/kernel/osl/emissive.cpp @@ -65,7 +65,7 @@ public: Color3 eval(const Vec3 &Ng, const Vec3 &omega_out) const { - float3 result = emissive_eval(TO_FLOAT3(Ng), TO_FLOAT3(omega_out)); + float3 result = emissive_simple_eval(TO_FLOAT3(Ng), TO_FLOAT3(omega_out)); return TO_COLOR3(result); } diff --git a/intern/cycles/kernel/osl/osl_closures.cpp b/intern/cycles/kernel/osl/osl_closures.cpp index 1f71fde549e..fa9f770d6ed 100644 --- a/intern/cycles/kernel/osl/osl_closures.cpp +++ b/intern/cycles/kernel/osl/osl_closures.cpp @@ -43,7 +43,7 @@ #include "kernel_types.h" #include "kernel_montecarlo.h" -#include "closure/bsdf.h" +#include "closure/bsdf_util.h" #include "closure/bsdf_ashikhmin_velvet.h" #include "closure/bsdf_diffuse.h" #include "closure/bsdf_microfacet.h" @@ -62,34 +62,34 @@ using namespace OSL; /* BSDF class definitions */ BSDF_CLOSURE_CLASS_BEGIN(Diffuse, diffuse, diffuse, LABEL_DIFFUSE) - CLOSURE_VECTOR_PARAM(DiffuseClosure, N), + CLOSURE_FLOAT3_PARAM(DiffuseClosure, sc.N), BSDF_CLOSURE_CLASS_END(Diffuse, diffuse) BSDF_CLOSURE_CLASS_BEGIN(Translucent, translucent, translucent, LABEL_DIFFUSE) - CLOSURE_VECTOR_PARAM(TranslucentClosure, N), + CLOSURE_FLOAT3_PARAM(TranslucentClosure, sc.N), BSDF_CLOSURE_CLASS_END(Translucent, translucent) BSDF_CLOSURE_CLASS_BEGIN(OrenNayar, oren_nayar, oren_nayar, LABEL_DIFFUSE) - CLOSURE_VECTOR_PARAM(OrenNayarClosure, N), + CLOSURE_FLOAT3_PARAM(OrenNayarClosure, sc.N), CLOSURE_FLOAT_PARAM(OrenNayarClosure, sc.data0), BSDF_CLOSURE_CLASS_END(OrenNayar, oren_nayar) BSDF_CLOSURE_CLASS_BEGIN(Reflection, reflection, reflection, LABEL_SINGULAR) - CLOSURE_VECTOR_PARAM(ReflectionClosure, N), + CLOSURE_FLOAT3_PARAM(ReflectionClosure, sc.N), BSDF_CLOSURE_CLASS_END(Reflection, reflection) BSDF_CLOSURE_CLASS_BEGIN(Refraction, refraction, refraction, LABEL_SINGULAR) - CLOSURE_VECTOR_PARAM(RefractionClosure, N), + CLOSURE_FLOAT3_PARAM(RefractionClosure, sc.N), CLOSURE_FLOAT_PARAM(RefractionClosure, sc.data0), BSDF_CLOSURE_CLASS_END(Refraction, refraction) BSDF_CLOSURE_CLASS_BEGIN(WestinBackscatter, westin_backscatter, westin_backscatter, LABEL_GLOSSY) - CLOSURE_VECTOR_PARAM(WestinBackscatterClosure, N), + CLOSURE_FLOAT3_PARAM(WestinBackscatterClosure, sc.N), CLOSURE_FLOAT_PARAM(WestinBackscatterClosure, sc.data0), BSDF_CLOSURE_CLASS_END(WestinBackscatter, westin_backscatter) BSDF_CLOSURE_CLASS_BEGIN(WestinSheen, westin_sheen, westin_sheen, LABEL_DIFFUSE) - CLOSURE_VECTOR_PARAM(WestinSheenClosure, N), + CLOSURE_FLOAT3_PARAM(WestinSheenClosure, sc.N), CLOSURE_FLOAT_PARAM(WestinSheenClosure, sc.data0), BSDF_CLOSURE_CLASS_END(WestinSheen, westin_sheen) @@ -97,35 +97,35 @@ BSDF_CLOSURE_CLASS_BEGIN(Transparent, transparent, transparent, LABEL_SINGULAR) BSDF_CLOSURE_CLASS_END(Transparent, transparent) BSDF_CLOSURE_CLASS_BEGIN(AshikhminVelvet, ashikhmin_velvet, ashikhmin_velvet, LABEL_DIFFUSE) - CLOSURE_VECTOR_PARAM(AshikhminVelvetClosure, N), + CLOSURE_FLOAT3_PARAM(AshikhminVelvetClosure, sc.N), CLOSURE_FLOAT_PARAM(AshikhminVelvetClosure, sc.data0), BSDF_CLOSURE_CLASS_END(AshikhminVelvet, ashikhmin_velvet) BSDF_CLOSURE_CLASS_BEGIN(Ward, ward, ward, LABEL_GLOSSY) - CLOSURE_VECTOR_PARAM(WardClosure, N), - CLOSURE_VECTOR_PARAM(WardClosure, T), + CLOSURE_FLOAT3_PARAM(WardClosure, sc.N), + CLOSURE_FLOAT3_PARAM(WardClosure, sc.T), CLOSURE_FLOAT_PARAM(WardClosure, sc.data0), CLOSURE_FLOAT_PARAM(WardClosure, sc.data1), BSDF_CLOSURE_CLASS_END(Ward, ward) BSDF_CLOSURE_CLASS_BEGIN(MicrofacetGGX, microfacet_ggx, microfacet_ggx, LABEL_GLOSSY) - CLOSURE_VECTOR_PARAM(MicrofacetGGXClosure, N), + CLOSURE_FLOAT3_PARAM(MicrofacetGGXClosure, sc.N), CLOSURE_FLOAT_PARAM(MicrofacetGGXClosure, sc.data0), BSDF_CLOSURE_CLASS_END(MicrofacetGGX, microfacet_ggx) BSDF_CLOSURE_CLASS_BEGIN(MicrofacetBeckmann, microfacet_beckmann, microfacet_beckmann, LABEL_GLOSSY) - CLOSURE_VECTOR_PARAM(MicrofacetBeckmannClosure, N), + CLOSURE_FLOAT3_PARAM(MicrofacetBeckmannClosure, sc.N), CLOSURE_FLOAT_PARAM(MicrofacetBeckmannClosure, sc.data0), BSDF_CLOSURE_CLASS_END(MicrofacetBeckmann, microfacet_beckmann) BSDF_CLOSURE_CLASS_BEGIN(MicrofacetGGXRefraction, microfacet_ggx_refraction, microfacet_ggx, LABEL_GLOSSY) - CLOSURE_VECTOR_PARAM(MicrofacetGGXRefractionClosure, N), + CLOSURE_FLOAT3_PARAM(MicrofacetGGXRefractionClosure, sc.N), CLOSURE_FLOAT_PARAM(MicrofacetGGXRefractionClosure, sc.data0), CLOSURE_FLOAT_PARAM(MicrofacetGGXRefractionClosure, sc.data1), BSDF_CLOSURE_CLASS_END(MicrofacetGGXRefraction, microfacet_ggx_refraction) BSDF_CLOSURE_CLASS_BEGIN(MicrofacetBeckmannRefraction, microfacet_beckmann_refraction, microfacet_beckmann, LABEL_GLOSSY) - CLOSURE_VECTOR_PARAM(MicrofacetBeckmannRefractionClosure, N), + CLOSURE_FLOAT3_PARAM(MicrofacetBeckmannRefractionClosure, sc.N), CLOSURE_FLOAT_PARAM(MicrofacetBeckmannRefractionClosure, sc.data0), CLOSURE_FLOAT_PARAM(MicrofacetBeckmannRefractionClosure, sc.data1), BSDF_CLOSURE_CLASS_END(MicrofacetBeckmannRefraction, microfacet_beckmann_refraction) diff --git a/intern/cycles/kernel/osl/osl_closures.h b/intern/cycles/kernel/osl/osl_closures.h index 5cd333c806e..fe37c974e95 100644 --- a/intern/cycles/kernel/osl/osl_closures.h +++ b/intern/cycles/kernel/osl/osl_closures.h @@ -70,8 +70,11 @@ void name(RendererServices *, int id, void *data) \ #define CLOSURE_PREPARE_STATIC(name, classname) static CLOSURE_PREPARE(name, classname) -#define TO_VEC3(v) (*(OSL::Vec3 *)&(v)) -#define TO_COLOR3(v) (*(OSL::Color3 *)&(v)) +#define CLOSURE_FLOAT3_PARAM(st, fld) \ + { TypeDesc::TypeVector, reckless_offsetof(st, fld), NULL, sizeof(OSL::Vec3) } + +#define TO_VEC3(v) OSL::Vec3(v.x, v.y, v.z) +#define TO_COLOR3(v) OSL::Color3(v.x, v.y, v.z) #define TO_FLOAT3(v) make_float3(v[0], v[1], v[2]) /* BSDF */ @@ -79,7 +82,6 @@ void name(RendererServices *, int id, void *data) \ class CBSDFClosure : public OSL::ClosurePrimitive { public: ShaderClosure sc; - OSL::Vec3 N, T; CBSDFClosure(int scattering) : OSL::ClosurePrimitive(BSDF), m_scattering_label(scattering), m_shaderdata_flag(0) { } @@ -87,7 +89,6 @@ public: int scattering() const { return m_scattering_label; } int shaderdata_flag() const { return m_shaderdata_flag; } - ClosureType shaderclosure_type() const { return sc.type; } virtual void blur(float roughness) = 0; virtual float3 eval_reflect(const float3 &omega_out, const float3 &omega_in, float &pdf) const = 0; @@ -114,8 +115,7 @@ public: \ \ void setup() \ { \ - sc.N = TO_FLOAT3(N); \ - sc.T = TO_FLOAT3(T); \ + sc.prim = NULL; \ m_shaderdata_flag = bsdf_##lower##_setup(&sc); \ } \ \ diff --git a/intern/cycles/kernel/osl/osl_globals.h b/intern/cycles/kernel/osl/osl_globals.h index 1a2a210de88..fb569117698 100644 --- a/intern/cycles/kernel/osl/osl_globals.h +++ b/intern/cycles/kernel/osl/osl_globals.h @@ -75,10 +75,21 @@ struct OSLGlobals { vector object_names; }; +/* trace() call result */ +struct OSLTraceData { + Ray ray; + Intersection isect; + ShaderData sd; + bool setup; + bool init; +}; + /* thread key for thread specific data lookup */ struct OSLThreadData { OSL::ShaderGlobals globals; OSL::PerThreadInfo *thread_info; + OSLTraceData tracedata; + OSL::ShadingContext *context[SHADER_CONTEXT_NUM]; }; CCL_NAMESPACE_END diff --git a/intern/cycles/kernel/osl/osl_services.cpp b/intern/cycles/kernel/osl/osl_services.cpp index b584a54b1b7..d6e52e28c62 100644 --- a/intern/cycles/kernel/osl/osl_services.cpp +++ b/intern/cycles/kernel/osl/osl_services.cpp @@ -47,7 +47,7 @@ CCL_NAMESPACE_BEGIN /* RenderServices implementation */ -#define TO_MATRIX44(m) (*(OSL::Matrix44 *)&(m)) +#define COPY_MATRIX44(m1, m2) memcpy(m1, m2, sizeof(*m2)) /* static ustrings */ ustring OSLRenderServices::u_distance("distance"); @@ -121,7 +121,7 @@ bool OSLRenderServices::get_matrix(OSL::Matrix44 &result, OSL::TransformationPtr Transform tfm = object_fetch_transform(kg, object, OBJECT_TRANSFORM); #endif tfm = transform_transpose(tfm); - result = TO_MATRIX44(tfm); + COPY_MATRIX44(&result, &tfm); return true; } @@ -151,7 +151,7 @@ bool OSLRenderServices::get_inverse_matrix(OSL::Matrix44 &result, OSL::Transform Transform itfm = object_fetch_transform(kg, object, OBJECT_INVERSE_TRANSFORM); #endif itfm = transform_transpose(itfm); - result = TO_MATRIX44(itfm); + COPY_MATRIX44(&result, &itfm); return true; } @@ -166,22 +166,22 @@ bool OSLRenderServices::get_matrix(OSL::Matrix44 &result, ustring from, float ti if (from == u_ndc) { Transform tfm = transform_transpose(transform_quick_inverse(kernel_data.cam.worldtondc)); - result = TO_MATRIX44(tfm); + COPY_MATRIX44(&result, &tfm); return true; } else if (from == u_raster) { Transform tfm = transform_transpose(kernel_data.cam.rastertoworld); - result = TO_MATRIX44(tfm); + COPY_MATRIX44(&result, &tfm); return true; } else if (from == u_screen) { Transform tfm = transform_transpose(kernel_data.cam.screentoworld); - result = TO_MATRIX44(tfm); + COPY_MATRIX44(&result, &tfm); return true; } else if (from == u_camera) { Transform tfm = transform_transpose(kernel_data.cam.cameratoworld); - result = TO_MATRIX44(tfm); + COPY_MATRIX44(&result, &tfm); return true; } @@ -194,22 +194,22 @@ bool OSLRenderServices::get_inverse_matrix(OSL::Matrix44 &result, ustring to, fl if (to == u_ndc) { Transform tfm = transform_transpose(kernel_data.cam.worldtondc); - result = TO_MATRIX44(tfm); + COPY_MATRIX44(&result, &tfm); return true; } else if (to == u_raster) { Transform tfm = transform_transpose(kernel_data.cam.worldtoraster); - result = TO_MATRIX44(tfm); + COPY_MATRIX44(&result, &tfm); return true; } else if (to == u_screen) { Transform tfm = transform_transpose(kernel_data.cam.worldtoscreen); - result = TO_MATRIX44(tfm); + COPY_MATRIX44(&result, &tfm); return true; } else if (to == u_camera) { Transform tfm = transform_transpose(kernel_data.cam.worldtocamera); - result = TO_MATRIX44(tfm); + COPY_MATRIX44(&result, &tfm); return true; } @@ -232,7 +232,7 @@ bool OSLRenderServices::get_matrix(OSL::Matrix44 &result, OSL::TransformationPtr Transform tfm = object_fetch_transform(kg, object, OBJECT_TRANSFORM); #endif tfm = transform_transpose(tfm); - result = TO_MATRIX44(tfm); + COPY_MATRIX44(&result, &tfm); return true; } @@ -257,7 +257,7 @@ bool OSLRenderServices::get_inverse_matrix(OSL::Matrix44 &result, OSL::Transform Transform tfm = object_fetch_transform(kg, object, OBJECT_INVERSE_TRANSFORM); #endif tfm = transform_transpose(tfm); - result = TO_MATRIX44(tfm); + COPY_MATRIX44(&result, &tfm); return true; } @@ -272,22 +272,22 @@ bool OSLRenderServices::get_matrix(OSL::Matrix44 &result, ustring from) if (from == u_ndc) { Transform tfm = transform_transpose(transform_quick_inverse(kernel_data.cam.worldtondc)); - result = TO_MATRIX44(tfm); + COPY_MATRIX44(&result, &tfm); return true; } else if (from == u_raster) { Transform tfm = transform_transpose(kernel_data.cam.rastertoworld); - result = TO_MATRIX44(tfm); + COPY_MATRIX44(&result, &tfm); return true; } else if (from == u_screen) { Transform tfm = transform_transpose(kernel_data.cam.screentoworld); - result = TO_MATRIX44(tfm); + COPY_MATRIX44(&result, &tfm); return true; } else if (from == u_camera) { Transform tfm = transform_transpose(kernel_data.cam.cameratoworld); - result = TO_MATRIX44(tfm); + COPY_MATRIX44(&result, &tfm); return true; } @@ -300,22 +300,22 @@ bool OSLRenderServices::get_inverse_matrix(OSL::Matrix44 &result, ustring to) if (to == u_ndc) { Transform tfm = transform_transpose(kernel_data.cam.worldtondc); - result = TO_MATRIX44(tfm); + COPY_MATRIX44(&result, &tfm); return true; } else if (to == u_raster) { Transform tfm = transform_transpose(kernel_data.cam.worldtoraster); - result = TO_MATRIX44(tfm); + COPY_MATRIX44(&result, &tfm); return true; } else if (to == u_screen) { Transform tfm = transform_transpose(kernel_data.cam.worldtoscreen); - result = TO_MATRIX44(tfm); + COPY_MATRIX44(&result, &tfm); return true; } else if (to == u_camera) { Transform tfm = transform_transpose(kernel_data.cam.worldtocamera); - result = TO_MATRIX44(tfm); + COPY_MATRIX44(&result, &tfm); return true; } @@ -815,13 +815,10 @@ bool OSLRenderServices::trace(TraceOpt &options, OSL::ShaderGlobals *sg, ray.dD.dy = TO_FLOAT3(dRdy); /* allocate trace data */ - TraceData *tracedata = new TraceData(); + OSLTraceData *tracedata = (OSLTraceData*)sg->tracedata; tracedata->ray = ray; tracedata->setup = false; - - if(sg->tracedata) - delete (TraceData*)sg->tracedata; - sg->tracedata = tracedata; + tracedata->init = true; /* raytrace */ return scene_intersect(kernel_globals, &ray, ~0, &tracedata->isect); @@ -831,9 +828,9 @@ bool OSLRenderServices::trace(TraceOpt &options, OSL::ShaderGlobals *sg, bool OSLRenderServices::getmessage(OSL::ShaderGlobals *sg, ustring source, ustring name, TypeDesc type, void *val, bool derivatives) { - TraceData *tracedata = (TraceData*)sg->tracedata; + OSLTraceData *tracedata = (OSLTraceData*)sg->tracedata; - if(source == u_trace && tracedata) { + if(source == u_trace && tracedata->init) { if(name == u_hit) { return set_attribute_int((tracedata->isect.prim != ~0), type, derivatives, val); } diff --git a/intern/cycles/kernel/osl/osl_services.h b/intern/cycles/kernel/osl/osl_services.h index e687700b383..cd4a4163209 100644 --- a/intern/cycles/kernel/osl/osl_services.h +++ b/intern/cycles/kernel/osl/osl_services.h @@ -106,13 +106,6 @@ public: static bool get_object_standard_attribute(KernelGlobals *kg, ShaderData *sd, ustring name, TypeDesc type, bool derivatives, void *val); - struct TraceData { - Ray ray; - Intersection isect; - ShaderData sd; - bool setup; - }; - static ustring u_distance; static ustring u_index; static ustring u_camera; diff --git a/intern/cycles/kernel/osl/osl_shader.cpp b/intern/cycles/kernel/osl/osl_shader.cpp index 32712b25e92..f5c04b6755e 100644 --- a/intern/cycles/kernel/osl/osl_shader.cpp +++ b/intern/cycles/kernel/osl/osl_shader.cpp @@ -51,8 +51,13 @@ void OSLShader::thread_init(KernelGlobals *kg, KernelGlobals *kernel_globals, OS OSLThreadData *tdata = new OSLThreadData(); memset(&tdata->globals, 0, sizeof(OSL::ShaderGlobals)); + tdata->globals.tracedata = &tdata->tracedata; + tdata->globals.flipHandedness = false; tdata->thread_info = ss->create_thread_info(); + for(int i = 0; i < SHADER_CONTEXT_NUM; i++) + tdata->context[i] = ss->get_context(tdata->thread_info); + kg->osl_ss = (OSLShadingSystem*)ss; kg->osl_tdata = tdata; } @@ -65,6 +70,9 @@ void OSLShader::thread_free(KernelGlobals *kg) OSL::ShadingSystem *ss = (OSL::ShadingSystem*)kg->osl_ss; OSLThreadData *tdata = kg->osl_tdata; + for(int i = 0; i < SHADER_CONTEXT_NUM; i++) + ss->release_context(tdata->context[i]); + ss->destroy_thread_info(tdata->thread_info); delete tdata; @@ -77,8 +85,10 @@ void OSLShader::thread_free(KernelGlobals *kg) /* Globals */ static void shaderdata_to_shaderglobals(KernelGlobals *kg, ShaderData *sd, - int path_flag, OSL::ShaderGlobals *globals) + int path_flag, OSLThreadData *tdata) { + OSL::ShaderGlobals *globals = &tdata->globals; + /* copy from shader data to shader globals */ globals->P = TO_VEC3(sd->P); globals->dPdx = TO_VEC3(sd->dP.dx); @@ -100,15 +110,11 @@ static void shaderdata_to_shaderglobals(KernelGlobals *kg, ShaderData *sd, globals->time = sd->time; /* booleans */ - globals->raytype = path_flag; /* todo: add our own ray types */ + globals->raytype = path_flag; globals->backfacing = (sd->flag & SD_BACKFACING); - /* don't know yet if we need this */ - globals->flipHandedness = false; - /* shader data to be used in services callbacks */ globals->renderstate = sd; - globals->tracedata = NULL; /* hacky, we leave it to services to fetch actual object matrix */ globals->shader2common = sd; @@ -116,6 +122,9 @@ static void shaderdata_to_shaderglobals(KernelGlobals *kg, ShaderData *sd, /* must be set to NULL before execute */ globals->Ci = NULL; + + /* clear trace data */ + tdata->tracedata.init = false; } /* Surface */ @@ -132,14 +141,10 @@ static void flatten_surface_closure_tree(ShaderData *sd, bool no_glossy, if (prim) { ShaderClosure sc; - sc.prim = prim; sc.weight = weight; switch (prim->category()) { case OSL::ClosurePrimitive::BSDF: { - if (sd->num_closure == MAX_CLOSURE) - return; - CBSDFClosure *bsdf = (CBSDFClosure *)prim; int scattering = bsdf->scattering(); @@ -151,8 +156,13 @@ static void flatten_surface_closure_tree(ShaderData *sd, bool no_glossy, float sample_weight = fabsf(average(weight)); sc.sample_weight = sample_weight; - sc.type = bsdf->shaderclosure_type(); - sc.N = bsdf->sc.N; /* needed for AO */ + + sc.type = bsdf->sc.type; + sc.N = bsdf->sc.N; + sc.T = bsdf->sc.T; + sc.data0 = bsdf->sc.data0; + sc.data1 = bsdf->sc.data1; + sc.prim = bsdf->sc.prim; /* add */ if(sc.sample_weight > 1e-5f && sd->num_closure < MAX_CLOSURE) { @@ -170,6 +180,7 @@ static void flatten_surface_closure_tree(ShaderData *sd, bool no_glossy, sc.sample_weight = sample_weight; sc.type = CLOSURE_EMISSION_ID; + sc.prim = NULL; /* flag */ if(sd->num_closure < MAX_CLOSURE) { @@ -179,14 +190,12 @@ static void flatten_surface_closure_tree(ShaderData *sd, bool no_glossy, break; } case AmbientOcclusion: { - if (sd->num_closure == MAX_CLOSURE) - return; - /* sample weight */ float sample_weight = fabsf(average(weight)); sc.sample_weight = sample_weight; sc.type = CLOSURE_AMBIENT_OCCLUSION_ID; + sc.prim = NULL; if(sd->num_closure < MAX_CLOSURE) { sd->closure[sd->num_closure++] = sc; @@ -195,11 +204,9 @@ static void flatten_surface_closure_tree(ShaderData *sd, bool no_glossy, break; } case OSL::ClosurePrimitive::Holdout: - if (sd->num_closure == MAX_CLOSURE) - return; - sc.sample_weight = 0.0f; sc.type = CLOSURE_HOLDOUT_ID; + sc.prim = NULL; if(sd->num_closure < MAX_CLOSURE) { sd->closure[sd->num_closure++] = sc; @@ -226,26 +233,20 @@ static void flatten_surface_closure_tree(ShaderData *sd, bool no_glossy, } } -void OSLShader::eval_surface(KernelGlobals *kg, ShaderData *sd, float randb, int path_flag) +void OSLShader::eval_surface(KernelGlobals *kg, ShaderData *sd, float randb, int path_flag, ShaderContext ctx) { - /* gather pointers */ - OSL::ShadingSystem *ss = (OSL::ShadingSystem*)kg->osl_ss; - OSLThreadData *tdata = kg->osl_tdata; - OSL::ShaderGlobals *globals = &tdata->globals; - OSL::ShadingContext *ctx = (OSL::ShadingContext *)sd->osl_ctx; - /* setup shader globals from shader data */ - shaderdata_to_shaderglobals(kg, sd, path_flag, globals); + OSLThreadData *tdata = kg->osl_tdata; + shaderdata_to_shaderglobals(kg, sd, path_flag, tdata); /* execute shader for this point */ + OSL::ShadingSystem *ss = (OSL::ShadingSystem*)kg->osl_ss; + OSL::ShaderGlobals *globals = &tdata->globals; + OSL::ShadingContext *octx = tdata->context[(int)ctx]; int shader = sd->shader & SHADER_MASK; if (kg->osl->surface_state[shader]) - ss->execute(*ctx, *(kg->osl->surface_state[shader]), *globals); - - /* free trace data */ - if(globals->tracedata) - delete (OSLRenderServices::TraceData*)globals->tracedata; + ss->execute(*octx, *(kg->osl->surface_state[shader]), *globals); /* flatten closure tree */ sd->num_closure = 0; @@ -287,24 +288,19 @@ static float3 flatten_background_closure_tree(const OSL::ClosureColor *closure) return make_float3(0.0f, 0.0f, 0.0f); } -float3 OSLShader::eval_background(KernelGlobals *kg, ShaderData *sd, int path_flag) +float3 OSLShader::eval_background(KernelGlobals *kg, ShaderData *sd, int path_flag, ShaderContext ctx) { - /* gather pointers */ - OSL::ShadingSystem *ss = (OSL::ShadingSystem*)kg->osl_ss; - OSLThreadData *tdata = kg->osl_tdata; - OSL::ShaderGlobals *globals = &tdata->globals; - OSL::ShadingContext *ctx = (OSL::ShadingContext *)sd->osl_ctx; - /* setup shader globals from shader data */ - shaderdata_to_shaderglobals(kg, sd, path_flag, globals); + OSLThreadData *tdata = kg->osl_tdata; + shaderdata_to_shaderglobals(kg, sd, path_flag, tdata); /* execute shader for this point */ - if (kg->osl->background_state) - ss->execute(*ctx, *(kg->osl->background_state), *globals); + OSL::ShadingSystem *ss = (OSL::ShadingSystem*)kg->osl_ss; + OSL::ShaderGlobals *globals = &tdata->globals; + OSL::ShadingContext *octx = tdata->context[(int)ctx]; - /* free trace data */ - if(globals->tracedata) - delete (OSLRenderServices::TraceData*)globals->tracedata; + if (kg->osl->background_state) + ss->execute(*octx, *(kg->osl->background_state), *globals); /* return background color immediately */ if (globals->Ci) @@ -327,19 +323,16 @@ static void flatten_volume_closure_tree(ShaderData *sd, if (prim) { ShaderClosure sc; - sc.prim = prim; sc.weight = weight; switch (prim->category()) { case OSL::ClosurePrimitive::Volume: { - if (sd->num_closure == MAX_CLOSURE) - return; - /* sample weight */ float sample_weight = fabsf(average(weight)); sc.sample_weight = sample_weight; sc.type = CLOSURE_VOLUME_ID; + sc.prim = NULL; /* add */ if(sc.sample_weight > 1e-5f && sd->num_closure < MAX_CLOSURE) @@ -368,26 +361,20 @@ static void flatten_volume_closure_tree(ShaderData *sd, } } -void OSLShader::eval_volume(KernelGlobals *kg, ShaderData *sd, float randb, int path_flag) +void OSLShader::eval_volume(KernelGlobals *kg, ShaderData *sd, float randb, int path_flag, ShaderContext ctx) { - /* gather pointers */ - OSL::ShadingSystem *ss = (OSL::ShadingSystem*)kg->osl_ss; - OSLThreadData *tdata = kg->osl_tdata; - OSL::ShaderGlobals *globals = &tdata->globals; - OSL::ShadingContext *ctx = (OSL::ShadingContext *)sd->osl_ctx; - /* setup shader globals from shader data */ - shaderdata_to_shaderglobals(kg, sd, path_flag, globals); + OSLThreadData *tdata = kg->osl_tdata; + shaderdata_to_shaderglobals(kg, sd, path_flag, tdata); /* execute shader */ + OSL::ShadingSystem *ss = (OSL::ShadingSystem*)kg->osl_ss; + OSL::ShaderGlobals *globals = &tdata->globals; + OSL::ShadingContext *octx = tdata->context[(int)ctx]; int shader = sd->shader & SHADER_MASK; if (kg->osl->volume_state[shader]) - ss->execute(*ctx, *(kg->osl->volume_state[shader]), *globals); - - /* free trace data */ - if(globals->tracedata) - delete (OSLRenderServices::TraceData*)globals->tracedata; + ss->execute(*octx, *(kg->osl->volume_state[shader]), *globals); if (globals->Ci) flatten_volume_closure_tree(sd, globals->Ci); @@ -395,46 +382,25 @@ void OSLShader::eval_volume(KernelGlobals *kg, ShaderData *sd, float randb, int /* Displacement */ -void OSLShader::eval_displacement(KernelGlobals *kg, ShaderData *sd) +void OSLShader::eval_displacement(KernelGlobals *kg, ShaderData *sd, ShaderContext ctx) { - /* gather pointers */ - OSL::ShadingSystem *ss = (OSL::ShadingSystem*)kg->osl_ss; - OSLThreadData *tdata = kg->osl_tdata; - OSL::ShaderGlobals *globals = &tdata->globals; - OSL::ShadingContext *ctx = (OSL::ShadingContext *)sd->osl_ctx; - /* setup shader globals from shader data */ - shaderdata_to_shaderglobals(kg, sd, 0, globals); + OSLThreadData *tdata = kg->osl_tdata; + shaderdata_to_shaderglobals(kg, sd, 0, tdata); /* execute shader */ + OSL::ShadingSystem *ss = (OSL::ShadingSystem*)kg->osl_ss; + OSL::ShaderGlobals *globals = &tdata->globals; + OSL::ShadingContext *octx = tdata->context[(int)ctx]; int shader = sd->shader & SHADER_MASK; if (kg->osl->displacement_state[shader]) - ss->execute(*ctx, *(kg->osl->displacement_state[shader]), *globals); - - /* free trace data */ - if(globals->tracedata) - delete (OSLRenderServices::TraceData*)globals->tracedata; + ss->execute(*octx, *(kg->osl->displacement_state[shader]), *globals); /* get back position */ sd->P = TO_FLOAT3(globals->P); } -void OSLShader::init(KernelGlobals *kg, ShaderData *sd) -{ - OSL::ShadingSystem *ss = (OSL::ShadingSystem*)kg->osl_ss; - OSLThreadData *tdata = kg->osl_tdata; - - sd->osl_ctx = ss->get_context(tdata->thread_info); -} - -void OSLShader::release(KernelGlobals *kg, ShaderData *sd) -{ - OSL::ShadingSystem *ss = (OSL::ShadingSystem*)kg->osl_ss; - - ss->release_context((OSL::ShadingContext *)sd->osl_ctx); -} - /* BSDF Closure */ int OSLShader::bsdf_sample(const ShaderData *sd, const ShaderClosure *sc, float randu, float randv, float3& eval, float3& omega_in, differential3& domega_in, float& pdf) diff --git a/intern/cycles/kernel/osl/osl_shader.h b/intern/cycles/kernel/osl/osl_shader.h index e614f240dc1..2e46a2de42c 100644 --- a/intern/cycles/kernel/osl/osl_shader.h +++ b/intern/cycles/kernel/osl/osl_shader.h @@ -55,10 +55,10 @@ public: static void thread_free(KernelGlobals *kg); /* eval */ - static void eval_surface(KernelGlobals *kg, ShaderData *sd, float randb, int path_flag); - static float3 eval_background(KernelGlobals *kg, ShaderData *sd, int path_flag); - static void eval_volume(KernelGlobals *kg, ShaderData *sd, float randb, int path_flag); - static void eval_displacement(KernelGlobals *kg, ShaderData *sd); + static void eval_surface(KernelGlobals *kg, ShaderData *sd, float randb, int path_flag, ShaderContext ctx); + static float3 eval_background(KernelGlobals *kg, ShaderData *sd, int path_flag, ShaderContext ctx); + static void eval_volume(KernelGlobals *kg, ShaderData *sd, float randb, int path_flag, ShaderContext ctx); + static void eval_displacement(KernelGlobals *kg, ShaderData *sd, ShaderContext ctx); /* sample & eval */ static int bsdf_sample(const ShaderData *sd, const ShaderClosure *sc, @@ -73,10 +73,6 @@ public: static float3 volume_eval_phase(const ShaderClosure *sc, const float3 omega_in, const float3 omega_out); - /* release */ - static void init(KernelGlobals *kg, ShaderData *sd); - static void release(KernelGlobals *kg, ShaderData *sd); - /* attributes */ static int find_attribute(KernelGlobals *kg, const ShaderData *sd, uint id); }; diff --git a/intern/cycles/kernel/svm/svm_bsdf.h b/intern/cycles/kernel/svm/svm_bsdf.h deleted file mode 100644 index a9524f3ed37..00000000000 --- a/intern/cycles/kernel/svm/svm_bsdf.h +++ /dev/null @@ -1,279 +0,0 @@ -/* - * Copyright 2011, Blender Foundation. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include "../closure/bsdf_ashikhmin_velvet.h" -#include "../closure/bsdf_diffuse.h" -#include "../closure/bsdf_oren_nayar.h" -#include "../closure/bsdf_phong_ramp.h" -#include "../closure/bsdf_diffuse_ramp.h" -#include "../closure/bsdf_microfacet.h" -#include "../closure/bsdf_reflection.h" -#include "../closure/bsdf_refraction.h" -#include "../closure/bsdf_transparent.h" -#ifdef __ANISOTROPIC__ -#include "../closure/bsdf_ward.h" -#endif -#include "../closure/bsdf_westin.h" - -CCL_NAMESPACE_BEGIN - -__device int svm_bsdf_sample(const ShaderData *sd, const ShaderClosure *sc, float randu, float randv, float3 *eval, float3 *omega_in, differential3 *domega_in, float *pdf) -{ - int label; - - switch(sc->type) { - case CLOSURE_BSDF_DIFFUSE_ID: - label = bsdf_diffuse_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv, - eval, omega_in, &domega_in->dx, &domega_in->dy, pdf); - break; -#ifdef __SVM__ - case CLOSURE_BSDF_OREN_NAYAR_ID: - label = bsdf_oren_nayar_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv, - eval, omega_in, &domega_in->dx, &domega_in->dy, pdf); - break; - /*case CLOSURE_BSDF_PHONG_RAMP_ID: - label = bsdf_phong_ramp_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv, - eval, omega_in, &domega_in->dx, &domega_in->dy, pdf); - break; - case CLOSURE_BSDF_DIFFUSE_RAMP_ID: - label = bsdf_diffuse_ramp_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv, - eval, omega_in, &domega_in->dx, &domega_in->dy, pdf); - break;*/ - case CLOSURE_BSDF_TRANSLUCENT_ID: - label = bsdf_translucent_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv, - eval, omega_in, &domega_in->dx, &domega_in->dy, pdf); - break; - case CLOSURE_BSDF_REFLECTION_ID: - label = bsdf_reflection_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv, - eval, omega_in, &domega_in->dx, &domega_in->dy, pdf); - break; - case CLOSURE_BSDF_REFRACTION_ID: - label = bsdf_refraction_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv, - eval, omega_in, &domega_in->dx, &domega_in->dy, pdf); - break; - case CLOSURE_BSDF_TRANSPARENT_ID: - label = bsdf_transparent_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv, - eval, omega_in, &domega_in->dx, &domega_in->dy, pdf); - break; - case CLOSURE_BSDF_MICROFACET_GGX_ID: - case CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID: - label = bsdf_microfacet_ggx_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv, - eval, omega_in, &domega_in->dx, &domega_in->dy, pdf); - break; - case CLOSURE_BSDF_MICROFACET_BECKMANN_ID: - case CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID: - label = bsdf_microfacet_beckmann_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv, - eval, omega_in, &domega_in->dx, &domega_in->dy, pdf); - break; -#ifdef __ANISOTROPIC__ - case CLOSURE_BSDF_WARD_ID: - label = bsdf_ward_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv, - eval, omega_in, &domega_in->dx, &domega_in->dy, pdf); - break; -#endif - case CLOSURE_BSDF_ASHIKHMIN_VELVET_ID: - label = bsdf_ashikhmin_velvet_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv, - eval, omega_in, &domega_in->dx, &domega_in->dy, pdf); - break; - case CLOSURE_BSDF_WESTIN_BACKSCATTER_ID: - label = bsdf_westin_backscatter_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv, - eval, omega_in, &domega_in->dx, &domega_in->dy, pdf); - break; - case CLOSURE_BSDF_WESTIN_SHEEN_ID: - label = bsdf_westin_sheen_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv, - eval, omega_in, &domega_in->dx, &domega_in->dy, pdf); - break; -#endif - default: - label = LABEL_NONE; - break; - } - - return label; -} - -__device float3 svm_bsdf_eval(const ShaderData *sd, const ShaderClosure *sc, const float3 omega_in, float *pdf) -{ - float3 eval; - - if(dot(sd->Ng, omega_in) >= 0.0f) { - switch(sc->type) { - case CLOSURE_BSDF_DIFFUSE_ID: - eval = bsdf_diffuse_eval_reflect(sc, sd->I, omega_in, pdf); - break; -#ifdef __SVM__ - case CLOSURE_BSDF_OREN_NAYAR_ID: - eval = bsdf_oren_nayar_eval_reflect(sc, sd->I, omega_in, pdf); - break; - /*case CLOSURE_BSDF_PHONG_RAMP_ID: - eval = bsdf_phong_ramp_eval_reflect(sc, sd->I, omega_in, pdf); - break; - case CLOSURE_BSDF_DIFFUSE_RAMP_ID: - eval = bsdf_diffuse_ramp_eval_reflect(sc, sd->I, omega_in, pdf); - break;*/ - case CLOSURE_BSDF_TRANSLUCENT_ID: - eval = bsdf_translucent_eval_reflect(sc, sd->I, omega_in, pdf); - break; - case CLOSURE_BSDF_REFLECTION_ID: - eval = bsdf_reflection_eval_reflect(sc, sd->I, omega_in, pdf); - break; - case CLOSURE_BSDF_REFRACTION_ID: - eval = bsdf_refraction_eval_reflect(sc, sd->I, omega_in, pdf); - break; - case CLOSURE_BSDF_TRANSPARENT_ID: - eval = bsdf_transparent_eval_reflect(sc, sd->I, omega_in, pdf); - break; - case CLOSURE_BSDF_MICROFACET_GGX_ID: - case CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID: - eval = bsdf_microfacet_ggx_eval_reflect(sc, sd->I, omega_in, pdf); - break; - case CLOSURE_BSDF_MICROFACET_BECKMANN_ID: - case CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID: - eval = bsdf_microfacet_beckmann_eval_reflect(sc, sd->I, omega_in, pdf); - break; -#ifdef __ANISOTROPIC__ - case CLOSURE_BSDF_WARD_ID: - eval = bsdf_ward_eval_reflect(sc, sd->I, omega_in, pdf); - break; -#endif - case CLOSURE_BSDF_ASHIKHMIN_VELVET_ID: - eval = bsdf_ashikhmin_velvet_eval_reflect(sc, sd->I, omega_in, pdf); - break; - case CLOSURE_BSDF_WESTIN_BACKSCATTER_ID: - eval = bsdf_westin_backscatter_eval_reflect(sc, sd->I, omega_in, pdf); - break; - case CLOSURE_BSDF_WESTIN_SHEEN_ID: - eval = bsdf_westin_sheen_eval_reflect(sc, sd->I, omega_in, pdf); - break; -#endif - default: - eval = make_float3(0.0f, 0.0f, 0.0f); - break; - } - } - else { - switch(sc->type) { - case CLOSURE_BSDF_DIFFUSE_ID: - eval = bsdf_diffuse_eval_transmit(sc, sd->I, omega_in, pdf); - break; -#ifdef __SVM__ - case CLOSURE_BSDF_OREN_NAYAR_ID: - eval = bsdf_oren_nayar_eval_transmit(sc, sd->I, omega_in, pdf); - break; - case CLOSURE_BSDF_TRANSLUCENT_ID: - eval = bsdf_translucent_eval_transmit(sc, sd->I, omega_in, pdf); - break; - case CLOSURE_BSDF_REFLECTION_ID: - eval = bsdf_reflection_eval_transmit(sc, sd->I, omega_in, pdf); - break; - case CLOSURE_BSDF_REFRACTION_ID: - eval = bsdf_refraction_eval_transmit(sc, sd->I, omega_in, pdf); - break; - case CLOSURE_BSDF_TRANSPARENT_ID: - eval = bsdf_transparent_eval_transmit(sc, sd->I, omega_in, pdf); - break; - case CLOSURE_BSDF_MICROFACET_GGX_ID: - case CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID: - eval = bsdf_microfacet_ggx_eval_transmit(sc, sd->I, omega_in, pdf); - break; - case CLOSURE_BSDF_MICROFACET_BECKMANN_ID: - case CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID: - eval = bsdf_microfacet_beckmann_eval_transmit(sc, sd->I, omega_in, pdf); - break; -#ifdef __ANISOTROPIC__ - case CLOSURE_BSDF_WARD_ID: - eval = bsdf_ward_eval_transmit(sc, sd->I, omega_in, pdf); - break; -#endif - case CLOSURE_BSDF_ASHIKHMIN_VELVET_ID: - eval = bsdf_ashikhmin_velvet_eval_transmit(sc, sd->I, omega_in, pdf); - break; - case CLOSURE_BSDF_WESTIN_BACKSCATTER_ID: - eval = bsdf_westin_backscatter_eval_transmit(sc, sd->I, omega_in, pdf); - break; - case CLOSURE_BSDF_WESTIN_SHEEN_ID: - eval = bsdf_westin_sheen_eval_transmit(sc, sd->I, omega_in, pdf); - break; -#endif - default: - eval = make_float3(0.0f, 0.0f, 0.0f); - break; - } - } - - return eval; -} - -__device void svm_bsdf_blur(ShaderClosure *sc, float roughness) -{ - switch(sc->type) { - case CLOSURE_BSDF_DIFFUSE_ID: - bsdf_diffuse_blur(sc, roughness); - break; -#ifdef __SVM__ - case CLOSURE_BSDF_OREN_NAYAR_ID: - bsdf_oren_nayar_blur(sc, roughness); - break; - /*case CLOSURE_BSDF_PHONG_RAMP_ID: - bsdf_phong_ramp_blur(sc, roughness); - break; - case CLOSURE_BSDF_DIFFUSE_RAMP_ID: - bsdf_diffuse_ramp_blur(sc, roughness); - break;*/ - case CLOSURE_BSDF_TRANSLUCENT_ID: - bsdf_translucent_blur(sc, roughness); - break; - case CLOSURE_BSDF_REFLECTION_ID: - bsdf_reflection_blur(sc, roughness); - break; - case CLOSURE_BSDF_REFRACTION_ID: - bsdf_refraction_blur(sc, roughness); - break; - case CLOSURE_BSDF_TRANSPARENT_ID: - bsdf_transparent_blur(sc, roughness); - break; - case CLOSURE_BSDF_MICROFACET_GGX_ID: - case CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID: - bsdf_microfacet_ggx_blur(sc, roughness); - break; - case CLOSURE_BSDF_MICROFACET_BECKMANN_ID: - case CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID: - bsdf_microfacet_beckmann_blur(sc, roughness); - break; -#ifdef __ANISOTROPIC__ - case CLOSURE_BSDF_WARD_ID: - bsdf_ward_blur(sc, roughness); - break; -#endif - case CLOSURE_BSDF_ASHIKHMIN_VELVET_ID: - bsdf_ashikhmin_velvet_blur(sc, roughness); - break; - case CLOSURE_BSDF_WESTIN_BACKSCATTER_ID: - bsdf_westin_backscatter_blur(sc, roughness); - break; - case CLOSURE_BSDF_WESTIN_SHEEN_ID: - bsdf_westin_sheen_blur(sc, roughness); - break; -#endif - default: - break; - } -} - -CCL_NAMESPACE_END - From 1ab3edb108ee51eb150f942e18bb124e4bba85f4 Mon Sep 17 00:00:00 2001 From: Ton Roosendaal Date: Sat, 15 Dec 2012 10:53:35 +0000 Subject: [PATCH 148/252] Classical mistake - fix a bug in 1 feature, but don't test the related ones :/ Previous commit broke dragging area edges. --- source/blender/editors/screen/screen_ops.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c index 2e6cb420974..df7b2f73c25 100644 --- a/source/blender/editors/screen/screen_ops.c +++ b/source/blender/editors/screen/screen_ops.c @@ -1001,6 +1001,7 @@ static int area_move_init(bContext *C, wmOperator *op) bScreen *sc = CTX_wm_screen(C); ScrEdge *actedge; sAreaMoveData *md; + ScrVert *v1; int x, y; /* required properties */ @@ -1019,7 +1020,11 @@ static int area_move_init(bContext *C, wmOperator *op) else md->origval = actedge->v1->vec.x; select_connected_scredge(sc, actedge); - /* now all vertices with 'flag==1' are the ones that can be moved. */ + /* now all vertices with 'flag==1' are the ones that can be moved. Move this to editflag */ + for (v1 = sc->vertbase.first; v1; v1 = v1->next) + if (v1->flag) + v1->editflag = 1; + area_move_set_limits(sc, md->dir, &md->bigger, &md->smaller); From 11f2348383d3b8cde70506f8b013433b610c5d62 Mon Sep 17 00:00:00 2001 From: Ton Roosendaal Date: Sat, 15 Dec 2012 11:00:57 +0000 Subject: [PATCH 149/252] Graah! Not using brains for quick fixes... --- source/blender/editors/screen/screen_ops.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c index df7b2f73c25..0f1c44de4ce 100644 --- a/source/blender/editors/screen/screen_ops.c +++ b/source/blender/editors/screen/screen_ops.c @@ -1021,10 +1021,11 @@ static int area_move_init(bContext *C, wmOperator *op) select_connected_scredge(sc, actedge); /* now all vertices with 'flag==1' are the ones that can be moved. Move this to editflag */ - for (v1 = sc->vertbase.first; v1; v1 = v1->next) + for (v1 = sc->vertbase.first; v1; v1 = v1->next) { + v1->editflag = 0; if (v1->flag) v1->editflag = 1; - + } area_move_set_limits(sc, md->dir, &md->bigger, &md->smaller); From f98c2c936ca3637c634f0adef605602fe07d0b55 Mon Sep 17 00:00:00 2001 From: Jens Verwiebe Date: Sat, 15 Dec 2012 11:15:05 +0000 Subject: [PATCH 150/252] OSX/availability: use of the numerical value instead of the symbol in the #if MAC_OS_X_VERSION_MIN_REQUIRED comparison clause: If the code is loaded on an older system that does not include the symbol definition, the comparison still works --- intern/ghost/intern/GHOST_SystemCocoa.mm | 6 +++--- intern/ghost/intern/GHOST_WindowCocoa.mm | 16 ++++++++-------- intern/itasc/kdl/chain.hpp | 2 +- intern/itasc/kdl/tree.hpp | 4 ++-- source/blender/editors/space_file/fsmenu.c | 2 +- source/blender/quicktime/apple/qtkit_export.m | 2 +- source/blender/quicktime/quicktime_export.h | 2 +- 7 files changed, 17 insertions(+), 17 deletions(-) diff --git a/intern/ghost/intern/GHOST_SystemCocoa.mm b/intern/ghost/intern/GHOST_SystemCocoa.mm index 7f6b69d9d50..aca1a4071d8 100644 --- a/intern/ghost/intern/GHOST_SystemCocoa.mm +++ b/intern/ghost/intern/GHOST_SystemCocoa.mm @@ -56,7 +56,7 @@ #include "AssertMacros.h" #pragma mark KeyMap, mouse converters -#if MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_4 +#if MAC_OS_X_VERSION_MIN_REQUIRED <= 1040 /* Keycodes not defined in Tiger */ /* * Summary: @@ -360,7 +360,7 @@ static GHOST_TKey convertKey(int rawCode, unichar recvChar, UInt16 keyAction) return (GHOST_TKey) (recvChar - 'a' + GHOST_kKeyA); } else { -#if MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_4 +#if MAC_OS_X_VERSION_MIN_REQUIRED <= 1040 KeyboardLayoutRef keyLayout; UCKeyboardLayout *uchrData; @@ -423,7 +423,7 @@ static GHOST_TKey convertKey(int rawCode, unichar recvChar, UInt16 keyAction) #pragma mark defines for 10.6 api not documented in 10.5 -#if MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_4 +#if MAC_OS_X_VERSION_MIN_REQUIRED <= 1040 enum { /* The following event types are available on some hardware on 10.5.2 and later */ NSEventTypeGesture = 29, diff --git a/intern/ghost/intern/GHOST_WindowCocoa.mm b/intern/ghost/intern/GHOST_WindowCocoa.mm index 6c5dbe83f4c..792836b0a21 100644 --- a/intern/ghost/intern/GHOST_WindowCocoa.mm +++ b/intern/ghost/intern/GHOST_WindowCocoa.mm @@ -28,7 +28,7 @@ #include -#if MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_5 +#if MAC_OS_X_VERSION_MIN_REQUIRED <= 1050 //Use of the SetSystemUIMode function (64bit compatible) #include #endif @@ -58,7 +58,7 @@ extern "C" { extern void wm_draw_update(bContext *C); };*/ @interface CocoaWindowDelegate : NSObject -#if MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_6 +#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1060 #endif { @@ -115,12 +115,12 @@ extern "C" { - (void)windowDidResize:(NSNotification *)notification { -#if MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_6 +#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1060 //if (![[notification object] inLiveResize]) { //Send event only once, at end of resize operation (when user has released mouse button) #endif systemCocoa->handleWindowEvent(GHOST_kEventWindowSize, associatedWindow); -#if MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_6 +#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1060 //} #endif /* Live resize ugly patch. Needed because live resize runs in a modal loop, not letting main loop run @@ -287,7 +287,7 @@ extern "C" { } } -#if MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_4 +#if MAC_OS_X_VERSION_MIN_REQUIRED <= 1040 //Cmd+key are handled differently before 10.5 - (BOOL)performKeyEquivalent:(NSEvent *)theEvent { @@ -578,7 +578,7 @@ GHOST_WindowCocoa::GHOST_WindowCocoa( setDrawingContextType(type); updateDrawingContext(); activateDrawingContext(); -#if defined(MAC_OS_X_VERSION_10_7) && (MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_7) // retina support started with 10.7.4 afaik +#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1070 // retina support started with 10.7.4 afaik if (m_systemCocoa->m_nativePixel) { [m_openGLView setWantsBestResolutionOpenGLSurface:YES]; NSRect backingBounds = [m_openGLView convertRectToBacking:[m_openGLView bounds]]; @@ -928,7 +928,7 @@ GHOST_TSuccess GHOST_WindowCocoa::setState(GHOST_TWindowState state) * doesn't know view/window difference. */ m_fullScreen = true; -#if MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_6 +#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1060 //10.6 provides Cocoa functions to autoshow menu bar, and to change a window style //Hide menu & dock if needed if ([[m_window screen] isEqual:[[NSScreen screens] objectAtIndex:0]]) { @@ -987,7 +987,7 @@ GHOST_TSuccess GHOST_WindowCocoa::setState(GHOST_TWindowState state) m_fullScreen = false; //Exit fullscreen -#if MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_6 +#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1060 //Show again menu & dock if needed if ([[m_window screen] isEqual:[NSScreen mainScreen]]) { [NSApp setPresentationOptions:NSApplicationPresentationDefault]; diff --git a/intern/itasc/kdl/chain.hpp b/intern/itasc/kdl/chain.hpp index fde9d4ed23e..1776737fc7d 100644 --- a/intern/itasc/kdl/chain.hpp +++ b/intern/itasc/kdl/chain.hpp @@ -36,7 +36,7 @@ namespace KDL { class Chain { private: #if defined(__APPLE__) -# if MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_5 +# if MAC_OS_X_VERSION_MIN_REQUIRED <= 1050 std::vector segments; # else // Eigen allocator is needed for alignment of Eigen data types diff --git a/intern/itasc/kdl/tree.hpp b/intern/itasc/kdl/tree.hpp index a020c6cf2cf..82794f96b94 100644 --- a/intern/itasc/kdl/tree.hpp +++ b/intern/itasc/kdl/tree.hpp @@ -28,7 +28,7 @@ #include #include #if defined(__APPLE__) -# if MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_5 +# if MAC_OS_X_VERSION_MIN_REQUIRED <= 1050 //no include # else # include @@ -42,7 +42,7 @@ namespace KDL //Forward declaration class TreeElement; #if defined(__APPLE__) -# if MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_5 +# if MAC_OS_X_VERSION_MIN_REQUIRED <= 1050 typedef std::map SegmentMap; # else // Eigen allocator is needed for alignment of Eigen data types diff --git a/source/blender/editors/space_file/fsmenu.c b/source/blender/editors/space_file/fsmenu.c index a5647c06b92..5f1f9a3ab22 100644 --- a/source/blender/editors/space_file/fsmenu.c +++ b/source/blender/editors/space_file/fsmenu.c @@ -350,7 +350,7 @@ void fsmenu_read_system(struct FSMenu *fsmenu, int read_bookmarks) #else #ifdef __APPLE__ { -#if (MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_4) +#if (MAC_OS_X_VERSION_MIN_REQUIRED <= 1040) OSErr err = noErr; int i; const char *home; diff --git a/source/blender/quicktime/apple/qtkit_export.m b/source/blender/quicktime/apple/qtkit_export.m index e0858cd5ec2..6935c908ee4 100644 --- a/source/blender/quicktime/apple/qtkit_export.m +++ b/source/blender/quicktime/apple/qtkit_export.m @@ -61,7 +61,7 @@ #import #include -#if (MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_4) || !__LP64__ +#if (MAC_OS_X_VERSION_MIN_REQUIRED <= 1040) || !__LP64__ #error 64 bit build & OSX 10.5 minimum are needed for QTKit #endif diff --git a/source/blender/quicktime/quicktime_export.h b/source/blender/quicktime/quicktime_export.h index a3469ddafde..d773cdc8f3a 100644 --- a/source/blender/quicktime/quicktime_export.h +++ b/source/blender/quicktime/quicktime_export.h @@ -87,7 +87,7 @@ void makeqtstring(struct RenderData *rd, char *string); //for playanim.c -#if (defined(USE_QTKIT) && MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5 && __LP64__) +#if (defined(USE_QTKIT) && MAC_OS_X_VERSION_MIN_REQUIRED >= 1050 && __LP64__) //Include the quicktime codec types constants that are missing in QTKitDefines.h enum { kRawCodecType = 'raw ', From 21a9fa908954e82e11fe11b67b708edcad6e9dcc Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sat, 15 Dec 2012 15:31:50 +0000 Subject: [PATCH 151/252] move bpath module from BLI to BKE, it was making many bad level calls into BKE. --- .../BLI_bpath.h => blenkernel/BKE_bpath.h} | 38 ++++++------- source/blender/blenkernel/CMakeLists.txt | 6 ++- source/blender/blenkernel/intern/action.c | 2 +- source/blender/blenkernel/intern/armature.c | 2 +- source/blender/blenkernel/intern/blender.c | 4 +- .../{blenlib => blenkernel}/intern/bpath.c | 54 +++++++++---------- source/blender/blenkernel/intern/brush.c | 2 +- source/blender/blenkernel/intern/curve.c | 2 +- source/blender/blenkernel/intern/image.c | 2 +- source/blender/blenkernel/intern/lattice.c | 2 +- source/blender/blenkernel/intern/library.c | 8 +-- source/blender/blenkernel/intern/material.c | 2 +- source/blender/blenkernel/intern/mball.c | 2 +- source/blender/blenkernel/intern/mesh.c | 2 +- source/blender/blenkernel/intern/object.c | 2 +- source/blender/blenkernel/intern/particle.c | 2 +- source/blender/blenkernel/intern/speaker.c | 2 +- source/blender/blenkernel/intern/texture.c | 2 +- source/blender/blenkernel/intern/world.c | 2 +- source/blender/blenlib/CMakeLists.txt | 2 - source/blender/blenloader/intern/writefile.c | 14 ++--- source/blender/editors/space_info/info_ops.c | 10 ++-- source/blender/python/intern/bpy.c | 10 ++-- 23 files changed, 88 insertions(+), 86 deletions(-) rename source/blender/{blenlib/BLI_bpath.h => blenkernel/BKE_bpath.h} (70%) rename source/blender/{blenlib => blenkernel}/intern/bpath.c (91%) diff --git a/source/blender/blenlib/BLI_bpath.h b/source/blender/blenkernel/BKE_bpath.h similarity index 70% rename from source/blender/blenlib/BLI_bpath.h rename to source/blender/blenkernel/BKE_bpath.h index 438bffb2fc5..7c350fdb03b 100644 --- a/source/blender/blenlib/BLI_bpath.h +++ b/source/blender/blenkernel/BKE_bpath.h @@ -25,14 +25,14 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file BLI_bpath.h +/** \file BKE_bpath.h * \ingroup bli * \attention Based on ghash, difference is ghash is not a fixed size, * so for BPath we don't need to malloc */ -#ifndef __BLI_BPATH_H__ -#define __BLI_BPATH_H__ +#ifndef __BKE_BPATH_H__ +#define __BKE_BPATH_H__ struct ID; struct ListBase; @@ -43,20 +43,20 @@ struct ReportList; * path has changed, and in that case, should write the result to pathOut. */ typedef int (*BPathVisitor)(void *userdata, char *path_dst, const char *path_src); /* Executes 'visit' for each path associated with 'id'. */ -void BLI_bpath_traverse_id(struct Main *bmain, struct ID *id, BPathVisitor visit_cb, const int flag, void *userdata); -void BLI_bpath_traverse_id_list(struct Main *bmain, struct ListBase *lb, BPathVisitor visit_cb, const int flag, void *userdata); -void BLI_bpath_traverse_main(struct Main *bmain, BPathVisitor visit_cb, const int flag, void *userdata); -int BLI_bpath_relocate_visitor(void *oldbasepath, char *path_dst, const char *path_src); +void BKE_bpath_traverse_id(struct Main *bmain, struct ID *id, BPathVisitor visit_cb, const int flag, void *userdata); +void BKE_bpath_traverse_id_list(struct Main *bmain, struct ListBase *lb, BPathVisitor visit_cb, const int flag, void *userdata); +void BKE_bpath_traverse_main(struct Main *bmain, BPathVisitor visit_cb, const int flag, void *userdata); +int BKE_bpath_relocate_visitor(void *oldbasepath, char *path_dst, const char *path_src); /* Functions for temp backup/restore of paths, path count must NOT change */ -void *BLI_bpath_list_backup(struct Main *bmain, const int flag); -void BLI_bpath_list_restore(struct Main *bmain, const int flag, void *ls_handle); -void BLI_bpath_list_free(void *ls_handle); +void *BKE_bpath_list_backup(struct Main *bmain, const int flag); +void BKE_bpath_list_restore(struct Main *bmain, const int flag, void *ls_handle); +void BKE_bpath_list_free(void *ls_handle); -#define BLI_BPATH_TRAVERSE_ABS (1 << 0) /* convert paths to absolute */ -#define BLI_BPATH_TRAVERSE_SKIP_LIBRARY (1 << 2) /* skip library paths */ -#define BLI_BPATH_TRAVERSE_SKIP_PACKED (1 << 3) /* skip packed data */ -#define BLI_BPATH_TRAVERSE_SKIP_MULTIFILE (1 << 4) /* skip paths where a single dir is used with an array of files, eg. +#define BKE_BPATH_TRAVERSE_ABS (1 << 0) /* convert paths to absolute */ +#define BKE_BPATH_TRAVERSE_SKIP_LIBRARY (1 << 2) /* skip library paths */ +#define BKE_BPATH_TRAVERSE_SKIP_PACKED (1 << 3) /* skip packed data */ +#define BKE_BPATH_TRAVERSE_SKIP_MULTIFILE (1 << 4) /* skip paths where a single dir is used with an array of files, eg. * sequence strip images and pointcache. in this case only use the first * file, this is needed for directory manipulation functions which might * otherwise modify the same directory multiple times */ @@ -64,9 +64,9 @@ void BLI_bpath_list_free(void *ls_handle); /* high level funcs */ /* creates a text file with missing files if there are any */ -void BLI_bpath_missing_files_check(struct Main *bmain, struct ReportList *reports); -void BLI_bpath_missing_files_find(struct Main *bmain, const char *searchpath, struct ReportList *reports); -void BLI_bpath_relative_convert(struct Main *bmain, const char *basedir, struct ReportList *reports); -void BLI_bpath_absolute_convert(struct Main *bmain, const char *basedir, struct ReportList *reports); +void BKE_bpath_missing_files_check(struct Main *bmain, struct ReportList *reports); +void BKE_bpath_missing_files_find(struct Main *bmain, const char *searchpath, struct ReportList *reports); +void BKE_bpath_relative_convert(struct Main *bmain, const char *basedir, struct ReportList *reports); +void BKE_bpath_absolute_convert(struct Main *bmain, const char *basedir, struct ReportList *reports); -#endif /* __BLI_BPATH_H__ */ +#endif /* __BKE_BPATH_H__ */ diff --git a/source/blender/blenkernel/CMakeLists.txt b/source/blender/blenkernel/CMakeLists.txt index 2da9b402d59..57996630c28 100644 --- a/source/blender/blenkernel/CMakeLists.txt +++ b/source/blender/blenkernel/CMakeLists.txt @@ -65,6 +65,7 @@ set(SRC intern/bmfont.c intern/boids.c intern/booleanops_mesh.c + intern/bpath.c intern/brush.c intern/bullet.c intern/bvhutils.c @@ -101,9 +102,9 @@ set(SRC intern/lamp.c intern/lattice.c intern/library.c + intern/mask.c intern/mask_evaluate.c intern/mask_rasterize.c - intern/mask.c intern/material.c intern/mball.c intern/mesh.c @@ -147,6 +148,7 @@ set(SRC intern/world.c intern/writeavi.c intern/writeframeserver.c + BKE_DerivedMesh.h BKE_action.h @@ -234,6 +236,8 @@ set(SRC BKE_world.h BKE_writeavi.h BKE_writeframeserver.h + BKE_bpath.h + depsgraph_private.h nla_private.h intern/CCGSubSurf.h diff --git a/source/blender/blenkernel/intern/action.c b/source/blender/blenkernel/intern/action.c index dd27cc70ba3..5da4f05321a 100644 --- a/source/blender/blenkernel/intern/action.c +++ b/source/blender/blenkernel/intern/action.c @@ -43,7 +43,7 @@ #include "DNA_object_types.h" #include "BLI_blenlib.h" -#include "BLI_bpath.h" +#include "BKE_bpath.h" #include "BLI_math.h" #include "BLI_utildefines.h" #include "BLI_ghash.h" diff --git a/source/blender/blenkernel/intern/armature.c b/source/blender/blenkernel/intern/armature.c index a93d728ad04..e8dfe027bd7 100644 --- a/source/blender/blenkernel/intern/armature.c +++ b/source/blender/blenkernel/intern/armature.c @@ -37,7 +37,7 @@ #include "MEM_guardedalloc.h" -#include "BLI_bpath.h" +#include "BKE_bpath.h" #include "BLI_math.h" #include "BLI_blenlib.h" #include "BLI_utildefines.h" diff --git a/source/blender/blenkernel/intern/blender.c b/source/blender/blenkernel/intern/blender.c index 8d923964b75..a46a3879dc8 100644 --- a/source/blender/blenkernel/intern/blender.c +++ b/source/blender/blenkernel/intern/blender.c @@ -56,7 +56,7 @@ #include "DNA_sound_types.h" #include "BLI_blenlib.h" -#include "BLI_bpath.h" +#include "BKE_bpath.h" #include "BLI_dynstr.h" #include "BLI_utildefines.h" #include "BLI_callbacks.h" @@ -182,7 +182,7 @@ static void clean_paths(Main *main) { Scene *scene; - BLI_bpath_traverse_main(main, clean_paths_visit_cb, BLI_BPATH_TRAVERSE_SKIP_MULTIFILE, NULL); + BKE_bpath_traverse_main(main, clean_paths_visit_cb, BKE_BPATH_TRAVERSE_SKIP_MULTIFILE, NULL); for (scene = main->scene.first; scene; scene = scene->id.next) { BLI_clean(scene->r.pic); diff --git a/source/blender/blenlib/intern/bpath.c b/source/blender/blenkernel/intern/bpath.c similarity index 91% rename from source/blender/blenlib/intern/bpath.c rename to source/blender/blenkernel/intern/bpath.c index c650438a31e..9f51dddb4fc 100644 --- a/source/blender/blenlib/intern/bpath.c +++ b/source/blender/blenkernel/intern/bpath.c @@ -72,7 +72,7 @@ #include "DNA_smoke_types.h" #include "BLI_blenlib.h" -#include "BLI_bpath.h" +#include "BKE_bpath.h" #include "BLI_utildefines.h" #include "BKE_font.h" @@ -95,9 +95,9 @@ static int checkMissingFiles_visit_cb(void *userdata, char *UNUSED(path_dst), co } /* high level function */ -void BLI_bpath_missing_files_check(Main *bmain, ReportList *reports) +void BKE_bpath_missing_files_check(Main *bmain, ReportList *reports) { - BLI_bpath_traverse_main(bmain, checkMissingFiles_visit_cb, BLI_BPATH_TRAVERSE_ABS, reports); + BKE_bpath_traverse_main(bmain, checkMissingFiles_visit_cb, BKE_BPATH_TRAVERSE_ABS, reports); } typedef struct BPathRemap_Data { @@ -132,7 +132,7 @@ static int makeFilesRelative_visit_cb(void *userdata, char *path_dst, const char } } -void BLI_bpath_relative_convert(Main *bmain, const char *basedir, ReportList *reports) +void BKE_bpath_relative_convert(Main *bmain, const char *basedir, ReportList *reports) { BPathRemap_Data data = {NULL}; @@ -144,7 +144,7 @@ void BLI_bpath_relative_convert(Main *bmain, const char *basedir, ReportList *re data.basedir = basedir; data.reports = reports; - BLI_bpath_traverse_main(bmain, makeFilesRelative_visit_cb, 0, (void *)&data); + BKE_bpath_traverse_main(bmain, makeFilesRelative_visit_cb, 0, (void *)&data); BKE_reportf(reports, data.count_failed ? RPT_WARNING : RPT_INFO, "Total files %d | Changed %d | Failed %d", @@ -174,8 +174,8 @@ static int makeFilesAbsolute_visit_cb(void *userdata, char *path_dst, const char } } -/* similar to BLI_bpath_relative_convert - keep in sync! */ -void BLI_bpath_absolute_convert(Main *bmain, const char *basedir, ReportList *reports) +/* similar to BKE_bpath_relative_convert - keep in sync! */ +void BKE_bpath_absolute_convert(Main *bmain, const char *basedir, ReportList *reports) { BPathRemap_Data data = {NULL}; @@ -187,7 +187,7 @@ void BLI_bpath_absolute_convert(Main *bmain, const char *basedir, ReportList *re data.basedir = basedir; data.reports = reports; - BLI_bpath_traverse_main(bmain, makeFilesAbsolute_visit_cb, 0, (void *)&data); + BKE_bpath_traverse_main(bmain, makeFilesAbsolute_visit_cb, 0, (void *)&data); BKE_reportf(reports, data.count_failed ? RPT_WARNING : RPT_INFO, "Total files %d | Changed %d | Failed %d", @@ -298,14 +298,14 @@ static int findMissingFiles_visit_cb(void *userdata, char *path_dst, const char } } -void BLI_bpath_missing_files_find(Main *bmain, const char *searchpath, ReportList *reports) +void BKE_bpath_missing_files_find(Main *bmain, const char *searchpath, ReportList *reports) { struct BPathFind_Data data = {NULL}; data.reports = reports; BLI_split_dir_part(searchpath, data.searchdir, sizeof(data.searchdir)); - BLI_bpath_traverse_main(bmain, findMissingFiles_visit_cb, 0, (void *)&data); + BKE_bpath_traverse_main(bmain, findMissingFiles_visit_cb, 0, (void *)&data); } /* Run a visitor on a string, replacing the contents of the string as needed. */ @@ -383,11 +383,11 @@ static int rewrite_path_alloc(char **path, BPathVisitor visit_cb, const char *ab } /* Run visitor function 'visit' on all paths contained in 'id'. */ -void BLI_bpath_traverse_id(Main *bmain, ID *id, BPathVisitor visit_cb, const int flag, void *bpath_user_data) +void BKE_bpath_traverse_id(Main *bmain, ID *id, BPathVisitor visit_cb, const int flag, void *bpath_user_data) { - const char *absbase = (flag & BLI_BPATH_TRAVERSE_ABS) ? ID_BLEND_PATH(bmain, id) : NULL; + const char *absbase = (flag & BKE_BPATH_TRAVERSE_ABS) ? ID_BLEND_PATH(bmain, id) : NULL; - if ((flag & BLI_BPATH_TRAVERSE_SKIP_LIBRARY) && id->lib) { + if ((flag & BKE_BPATH_TRAVERSE_SKIP_LIBRARY) && id->lib) { return; } @@ -396,7 +396,7 @@ void BLI_bpath_traverse_id(Main *bmain, ID *id, BPathVisitor visit_cb, const int { Image *ima; ima = (Image *)id; - if (ima->packedfile == NULL || (flag & BLI_BPATH_TRAVERSE_SKIP_PACKED) == 0) { + if (ima->packedfile == NULL || (flag & BKE_BPATH_TRAVERSE_SKIP_PACKED) == 0) { if (ELEM3(ima->source, IMA_SRC_FILE, IMA_SRC_MOVIE, IMA_SRC_SEQUENCE)) { rewrite_path_fixed(ima->name, visit_cb, absbase, bpath_user_data); } @@ -475,7 +475,7 @@ void BLI_bpath_traverse_id(Main *bmain, ID *id, BPathVisitor visit_cb, const int case ID_SO: { bSound *sound = (bSound *)id; - if (sound->packedfile == NULL || (flag & BLI_BPATH_TRAVERSE_SKIP_PACKED) == 0) { + if (sound->packedfile == NULL || (flag & BKE_BPATH_TRAVERSE_SKIP_PACKED) == 0) { rewrite_path_fixed(sound->name, visit_cb, absbase, bpath_user_data); } break; @@ -488,7 +488,7 @@ void BLI_bpath_traverse_id(Main *bmain, ID *id, BPathVisitor visit_cb, const int case ID_VF: { VFont *vfont = (VFont *)id; - if (vfont->packedfile == NULL || (flag & BLI_BPATH_TRAVERSE_SKIP_PACKED) == 0) { + if (vfont->packedfile == NULL || (flag & BKE_BPATH_TRAVERSE_SKIP_PACKED) == 0) { if (BKE_vfont_is_builtin(vfont) == FALSE) { rewrite_path_fixed(((VFont *)id)->name, visit_cb, absbase, bpath_user_data); } @@ -555,7 +555,7 @@ void BLI_bpath_traverse_id(Main *bmain, ID *id, BPathVisitor visit_cb, const int int len = MEM_allocN_len(se) / sizeof(*se); int i; - if (flag & BLI_BPATH_TRAVERSE_SKIP_MULTIFILE) { + if (flag & BKE_BPATH_TRAVERSE_SKIP_MULTIFILE) { /* only operate on one path */ len = MIN2(1, len); } @@ -604,26 +604,26 @@ void BLI_bpath_traverse_id(Main *bmain, ID *id, BPathVisitor visit_cb, const int } } -void BLI_bpath_traverse_id_list(Main *bmain, ListBase *lb, BPathVisitor visit_cb, const int flag, void *bpath_user_data) +void BKE_bpath_traverse_id_list(Main *bmain, ListBase *lb, BPathVisitor visit_cb, const int flag, void *bpath_user_data) { ID *id; for (id = lb->first; id; id = id->next) { - BLI_bpath_traverse_id(bmain, id, visit_cb, flag, bpath_user_data); + BKE_bpath_traverse_id(bmain, id, visit_cb, flag, bpath_user_data); } } -void BLI_bpath_traverse_main(Main *bmain, BPathVisitor visit_cb, const int flag, void *bpath_user_data) +void BKE_bpath_traverse_main(Main *bmain, BPathVisitor visit_cb, const int flag, void *bpath_user_data) { ListBase *lbarray[MAX_LIBARRAY]; int a = set_listbasepointers(bmain, lbarray); while (a--) { - BLI_bpath_traverse_id_list(bmain, lbarray[a], visit_cb, flag, bpath_user_data); + BKE_bpath_traverse_id_list(bmain, lbarray[a], visit_cb, flag, bpath_user_data); } } /* Rewrites a relative path to be relative to the main file - unless the path is * absolute, in which case it is not altered. */ -int BLI_bpath_relocate_visitor(void *pathbase_v, char *path_dst, const char *path_src) +int BKE_bpath_relocate_visitor(void *pathbase_v, char *path_dst, const char *path_src) { /* be sure there is low chance of the path being too short */ char filepath[(FILE_MAXDIR * 2) + FILE_MAXFILE]; @@ -700,23 +700,23 @@ static int bpath_list_restore(void *userdata, char *path_dst, const char *path_s } /* return ls_handle */ -void *BLI_bpath_list_backup(Main *bmain, const int flag) +void *BKE_bpath_list_backup(Main *bmain, const int flag) { ListBase *ls = MEM_callocN(sizeof(ListBase), __func__); - BLI_bpath_traverse_main(bmain, bpath_list_append, flag, ls); + BKE_bpath_traverse_main(bmain, bpath_list_append, flag, ls); return ls; } -void BLI_bpath_list_restore(Main *bmain, const int flag, void *ls_handle) +void BKE_bpath_list_restore(Main *bmain, const int flag, void *ls_handle) { ListBase *ls = ls_handle; - BLI_bpath_traverse_main(bmain, bpath_list_restore, flag, ls); + BKE_bpath_traverse_main(bmain, bpath_list_restore, flag, ls); } -void BLI_bpath_list_free(void *ls_handle) +void BKE_bpath_list_free(void *ls_handle) { ListBase *ls = ls_handle; BLI_assert(ls->first == NULL); /* assumes we were used */ diff --git a/source/blender/blenkernel/intern/brush.c b/source/blender/blenkernel/intern/brush.c index 3e5dee5b0de..7bcb9b45b23 100644 --- a/source/blender/blenkernel/intern/brush.c +++ b/source/blender/blenkernel/intern/brush.c @@ -46,7 +46,7 @@ #include "RNA_access.h" -#include "BLI_bpath.h" +#include "BKE_bpath.h" #include "BLI_math.h" #include "BLI_blenlib.h" #include "BLI_rand.h" diff --git a/source/blender/blenkernel/intern/curve.c b/source/blender/blenkernel/intern/curve.c index 4b4ca1cb32b..c9f084a9297 100644 --- a/source/blender/blenkernel/intern/curve.c +++ b/source/blender/blenkernel/intern/curve.c @@ -36,7 +36,7 @@ #include "MEM_guardedalloc.h" -#include "BLI_bpath.h" +#include "BKE_bpath.h" #include "BLI_blenlib.h" #include "BLI_math.h" #include "BLI_utildefines.h" diff --git a/source/blender/blenkernel/intern/image.c b/source/blender/blenkernel/intern/image.c index c4ce17c394a..f1f9667c3d0 100644 --- a/source/blender/blenkernel/intern/image.c +++ b/source/blender/blenkernel/intern/image.c @@ -68,7 +68,7 @@ #include "BLI_blenlib.h" #include "BLI_threads.h" #include "BLI_utildefines.h" -#include "BLI_bpath.h" +#include "BKE_bpath.h" #include "BKE_bmfont.h" #include "BKE_colortools.h" diff --git a/source/blender/blenkernel/intern/lattice.c b/source/blender/blenkernel/intern/lattice.c index 86b82c3cf43..7f3e43c40ff 100644 --- a/source/blender/blenkernel/intern/lattice.c +++ b/source/blender/blenkernel/intern/lattice.c @@ -37,7 +37,7 @@ #include "MEM_guardedalloc.h" #include "BLI_blenlib.h" -#include "BLI_bpath.h" +#include "BKE_bpath.h" #include "BLI_math.h" #include "BLI_utildefines.h" diff --git a/source/blender/blenkernel/intern/library.c b/source/blender/blenkernel/intern/library.c index eb0612a75bd..855e2d44661 100644 --- a/source/blender/blenkernel/intern/library.c +++ b/source/blender/blenkernel/intern/library.c @@ -71,7 +71,7 @@ #include "BLI_blenlib.h" #include "BLI_dynstr.h" #include "BLI_utildefines.h" -#include "BLI_bpath.h" +#include "BKE_bpath.h" #include "BKE_animsys.h" #include "BKE_camera.h" @@ -136,9 +136,9 @@ void BKE_id_lib_local_paths(Main *bmain, Library *lib, ID *id) { char *bpath_user_data[2] = {bmain->name, lib->filepath}; - BLI_bpath_traverse_id(bmain, id, - BLI_bpath_relocate_visitor, - BLI_BPATH_TRAVERSE_SKIP_MULTIFILE, + BKE_bpath_traverse_id(bmain, id, + BKE_bpath_relocate_visitor, + BKE_BPATH_TRAVERSE_SKIP_MULTIFILE, bpath_user_data); } diff --git a/source/blender/blenkernel/intern/material.c b/source/blender/blenkernel/intern/material.c index ea317956255..e4a938e7152 100644 --- a/source/blender/blenkernel/intern/material.c +++ b/source/blender/blenkernel/intern/material.c @@ -52,7 +52,7 @@ #include "BLI_math.h" #include "BLI_listbase.h" #include "BLI_utildefines.h" -#include "BLI_bpath.h" +#include "BKE_bpath.h" #include "BLI_string.h" #include "BKE_animsys.h" diff --git a/source/blender/blenkernel/intern/mball.c b/source/blender/blenkernel/intern/mball.c index 805e77cf84f..fdd0c504dac 100644 --- a/source/blender/blenkernel/intern/mball.c +++ b/source/blender/blenkernel/intern/mball.c @@ -50,7 +50,7 @@ #include "BLI_blenlib.h" #include "BLI_math.h" #include "BLI_utildefines.h" -#include "BLI_bpath.h" +#include "BKE_bpath.h" #include "BKE_global.h" diff --git a/source/blender/blenkernel/intern/mesh.c b/source/blender/blenkernel/intern/mesh.c index 75504416067..e12c3bc2260 100644 --- a/source/blender/blenkernel/intern/mesh.c +++ b/source/blender/blenkernel/intern/mesh.c @@ -46,7 +46,7 @@ #include "BLI_utildefines.h" #include "BLI_blenlib.h" -#include "BLI_bpath.h" +#include "BKE_bpath.h" #include "BLI_math.h" #include "BLI_edgehash.h" #include "BLI_scanfill.h" diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c index 425990d7583..85ad7186132 100644 --- a/source/blender/blenkernel/intern/object.c +++ b/source/blender/blenkernel/intern/object.c @@ -59,7 +59,7 @@ #include "DNA_object_types.h" #include "BLI_blenlib.h" -#include "BLI_bpath.h" +#include "BKE_bpath.h" #include "BLI_math.h" #include "BLI_pbvh.h" #include "BLI_utildefines.h" diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c index 97d8b06d3a7..000545d936f 100644 --- a/source/blender/blenkernel/intern/particle.c +++ b/source/blender/blenkernel/intern/particle.c @@ -55,7 +55,7 @@ #include "BLI_rand.h" #include "BLI_threads.h" #include "BLI_linklist.h" -#include "BLI_bpath.h" +#include "BKE_bpath.h" #include "BKE_anim.h" #include "BKE_animsys.h" diff --git a/source/blender/blenkernel/intern/speaker.c b/source/blender/blenkernel/intern/speaker.c index 09440591826..4594445dec0 100644 --- a/source/blender/blenkernel/intern/speaker.c +++ b/source/blender/blenkernel/intern/speaker.c @@ -35,7 +35,7 @@ #include "BLI_math.h" #include "BLI_utildefines.h" -#include "BLI_bpath.h" +#include "BKE_bpath.h" #include "BKE_animsys.h" #include "BKE_global.h" diff --git a/source/blender/blenkernel/intern/texture.c b/source/blender/blenkernel/intern/texture.c index 6d0313f6334..b78d23c5437 100644 --- a/source/blender/blenkernel/intern/texture.c +++ b/source/blender/blenkernel/intern/texture.c @@ -42,7 +42,7 @@ #include "BLI_math.h" #include "BLI_kdopbvh.h" #include "BLI_utildefines.h" -#include "BLI_bpath.h" +#include "BKE_bpath.h" #include "DNA_key_types.h" #include "DNA_object_types.h" diff --git a/source/blender/blenkernel/intern/world.c b/source/blender/blenkernel/intern/world.c index 4bde895cf7d..ef5ad435037 100644 --- a/source/blender/blenkernel/intern/world.c +++ b/source/blender/blenkernel/intern/world.c @@ -40,7 +40,7 @@ #include "BLI_listbase.h" #include "BLI_utildefines.h" -#include "BLI_bpath.h" +#include "BKE_bpath.h" #include "BKE_animsys.h" #include "BKE_global.h" diff --git a/source/blender/blenlib/CMakeLists.txt b/source/blender/blenlib/CMakeLists.txt index 8a3b1c9675b..f1f70a79202 100644 --- a/source/blender/blenlib/CMakeLists.txt +++ b/source/blender/blenlib/CMakeLists.txt @@ -50,7 +50,6 @@ set(SRC intern/BLI_mempool.c intern/DLRB_tree.c intern/boxpack2d.c - intern/bpath.c intern/callbacks.c intern/cpu.c intern/dynlib.c @@ -101,7 +100,6 @@ set(SRC BLI_bitmap.h BLI_blenlib.h BLI_boxpack2d.h - BLI_bpath.h BLI_callbacks.h BLI_cpu.h BLI_dlrbTree.h diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c index cee61858467..f82883addb1 100644 --- a/source/blender/blenloader/intern/writefile.c +++ b/source/blender/blenloader/intern/writefile.c @@ -139,7 +139,7 @@ #include "BLI_bitmap.h" #include "BLI_blenlib.h" #include "BLI_linklist.h" -#include "BLI_bpath.h" +#include "BKE_bpath.h" #include "BLI_math.h" #include "BLI_utildefines.h" @@ -3031,7 +3031,7 @@ int BLO_write_file(Main *mainvar, const char *filepath, int write_flags, ReportL /* path backup/restore */ void *path_list_backup = NULL; - const int path_list_flag = (BLI_BPATH_TRAVERSE_SKIP_LIBRARY | BLI_BPATH_TRAVERSE_SKIP_MULTIFILE); + const int path_list_flag = (BKE_BPATH_TRAVERSE_SKIP_LIBRARY | BKE_BPATH_TRAVERSE_SKIP_MULTIFILE); /* open temporary file, so we preserve the original in case we crash */ BLI_snprintf(tempname, sizeof(tempname), "%s@", filepath); @@ -3044,7 +3044,7 @@ int BLO_write_file(Main *mainvar, const char *filepath, int write_flags, ReportL /* check if we need to backup and restore paths */ if (UNLIKELY((write_flags & G_FILE_RELATIVE_REMAP) && (G_FILE_SAVE_COPY & write_flags))) { - path_list_backup = BLI_bpath_list_backup(mainvar, path_list_flag); + path_list_backup = BKE_bpath_list_backup(mainvar, path_list_flag); } /* remapping of relative paths to new file location */ @@ -3067,7 +3067,7 @@ int BLO_write_file(Main *mainvar, const char *filepath, int write_flags, ReportL * we should not have any relative paths, but if there * is somehow, an invalid or empty G.main->name it will * print an error, don't try make the absolute in this case. */ - BLI_bpath_absolute_convert(mainvar, G.main->name, NULL); + BKE_bpath_absolute_convert(mainvar, G.main->name, NULL); } } } @@ -3075,15 +3075,15 @@ int BLO_write_file(Main *mainvar, const char *filepath, int write_flags, ReportL write_user_block= write_flags & G_FILE_USERPREFS; if (write_flags & G_FILE_RELATIVE_REMAP) - BLI_bpath_relative_convert(mainvar, filepath, NULL); /* note, making relative to something OTHER then G.main->name */ + BKE_bpath_relative_convert(mainvar, filepath, NULL); /* note, making relative to something OTHER then G.main->name */ /* actual file writing */ err= write_file_handle(mainvar, file, NULL, NULL, write_user_block, write_flags, thumb); close(file); if (UNLIKELY(path_list_backup)) { - BLI_bpath_list_restore(mainvar, path_list_flag, path_list_backup); - BLI_bpath_list_free(path_list_backup); + BKE_bpath_list_restore(mainvar, path_list_flag, path_list_backup); + BKE_bpath_list_free(path_list_backup); } if (err) { diff --git a/source/blender/editors/space_info/info_ops.c b/source/blender/editors/space_info/info_ops.c index 48b5eaf7b44..e902a4ea6f4 100644 --- a/source/blender/editors/space_info/info_ops.c +++ b/source/blender/editors/space_info/info_ops.c @@ -40,7 +40,7 @@ #include "BLI_blenlib.h" #include "BLI_math.h" -#include "BLI_bpath.h" +#include "BKE_bpath.h" #include "BLI_utildefines.h" #include "BKE_context.h" @@ -204,7 +204,7 @@ static int make_paths_relative_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } - BLI_bpath_relative_convert(bmain, bmain->name, op->reports); + BKE_bpath_relative_convert(bmain, bmain->name, op->reports); /* redraw everything so any changed paths register */ WM_main_add_notifier(NC_WINDOW, NULL); @@ -237,7 +237,7 @@ static int make_paths_absolute_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } - BLI_bpath_absolute_convert(bmain, bmain->name, op->reports); + BKE_bpath_absolute_convert(bmain, bmain->name, op->reports); /* redraw everything so any changed paths register */ WM_main_add_notifier(NC_WINDOW, NULL); @@ -266,7 +266,7 @@ static int report_missing_files_exec(bContext *C, wmOperator *op) Main *bmain = CTX_data_main(C); /* run the missing file check */ - BLI_bpath_missing_files_check(bmain, op->reports); + BKE_bpath_missing_files_check(bmain, op->reports); return OPERATOR_FINISHED; } @@ -291,7 +291,7 @@ static int find_missing_files_exec(bContext *C, wmOperator *op) { Main *bmain = CTX_data_main(C); const char *searchpath = RNA_string_get_alloc(op->ptr, "filepath", NULL, 0); - BLI_bpath_missing_files_find(bmain, searchpath, op->reports); + BKE_bpath_missing_files_find(bmain, searchpath, op->reports); MEM_freeN((void *)searchpath); return OPERATOR_FINISHED; diff --git a/source/blender/python/intern/bpy.c b/source/blender/python/intern/bpy.c index 3ed662f41d7..876e2b2568f 100644 --- a/source/blender/python/intern/bpy.c +++ b/source/blender/python/intern/bpy.c @@ -45,7 +45,7 @@ #include "BLI_path_util.h" #include "BLI_string.h" -#include "BLI_bpath.h" +#include "BKE_bpath.h" #include "BLI_utildefines.h" #include "BKE_main.h" @@ -127,13 +127,13 @@ static PyObject *bpy_blend_paths(PyObject *UNUSED(self), PyObject *args, PyObjec return NULL; } - if (absolute) flag |= BLI_BPATH_TRAVERSE_ABS; - if (!packed) flag |= BLI_BPATH_TRAVERSE_SKIP_PACKED; - if (local) flag |= BLI_BPATH_TRAVERSE_SKIP_LIBRARY; + if (absolute) flag |= BKE_BPATH_TRAVERSE_ABS; + if (!packed) flag |= BKE_BPATH_TRAVERSE_SKIP_PACKED; + if (local) flag |= BKE_BPATH_TRAVERSE_SKIP_LIBRARY; list = PyList_New(0); - BLI_bpath_traverse_main(G.main, bpy_blend_paths_visit_cb, flag, (void *)list); + BKE_bpath_traverse_main(G.main, bpy_blend_paths_visit_cb, flag, (void *)list); return list; } From a6bee579e9c6e144f731072b93d004af7b2011c5 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sat, 15 Dec 2012 15:59:25 +0000 Subject: [PATCH 152/252] move pbvh into BKE, it used many BKE bad level includes. now blenlib/BLI doesn't depend on any blenkern/BKE functions, there are still some bad level includes but these are only to access G.background and the blender version define. --- .../blender/{blenlib/BLI_pbvh.h => blenkernel/BKE_pbvh.h} | 0 source/blender/blenkernel/CMakeLists.txt | 5 +++-- source/blender/blenkernel/intern/DerivedMesh.c | 2 +- source/blender/blenkernel/intern/action.c | 1 - source/blender/blenkernel/intern/armature.c | 1 - source/blender/blenkernel/intern/blender.c | 2 +- source/blender/blenkernel/intern/bpath.c | 3 ++- source/blender/blenkernel/intern/brush.c | 1 - source/blender/blenkernel/intern/cdderivedmesh.c | 2 +- source/blender/blenkernel/intern/curve.c | 1 - source/blender/blenkernel/intern/editderivedmesh.c | 2 +- source/blender/blenkernel/intern/image.c | 1 - source/blender/blenkernel/intern/lattice.c | 1 - source/blender/blenkernel/intern/material.c | 1 - source/blender/blenkernel/intern/mball.c | 2 -- source/blender/blenkernel/intern/mesh.c | 1 - source/blender/blenkernel/intern/multires.c | 2 +- source/blender/blenkernel/intern/object.c | 3 +-- source/blender/blenkernel/intern/particle.c | 1 - source/blender/{blenlib => blenkernel}/intern/pbvh.c | 4 +--- source/blender/blenkernel/intern/speaker.c | 1 - source/blender/blenkernel/intern/subsurf_ccg.c | 2 +- source/blender/blenkernel/intern/texture.c | 1 - source/blender/blenkernel/intern/world.c | 1 - source/blender/blenlib/CMakeLists.txt | 6 +----- source/blender/blenlib/SConscript | 4 ++-- source/blender/blenlib/intern/BLI_ghash.c | 2 +- source/blender/blenlib/intern/endian_switch.c | 2 +- source/blender/blenlib/intern/fileops.c | 2 +- source/blender/blenlib/intern/freetypefont.c | 2 -- source/blender/blenlib/intern/path_util.c | 2 +- source/blender/blenlib/intern/winstuff.c | 2 +- source/blender/editors/sculpt_paint/paint_hide.c | 2 +- source/blender/editors/sculpt_paint/paint_mask.c | 3 +-- source/blender/editors/sculpt_paint/sculpt.c | 2 +- source/blender/editors/sculpt_paint/sculpt_intern.h | 2 +- source/blender/makesrna/intern/rna_sculpt_paint.c | 3 +-- 37 files changed, 26 insertions(+), 49 deletions(-) rename source/blender/{blenlib/BLI_pbvh.h => blenkernel/BKE_pbvh.h} (100%) rename source/blender/{blenlib => blenkernel}/intern/pbvh.c (99%) diff --git a/source/blender/blenlib/BLI_pbvh.h b/source/blender/blenkernel/BKE_pbvh.h similarity index 100% rename from source/blender/blenlib/BLI_pbvh.h rename to source/blender/blenkernel/BKE_pbvh.h diff --git a/source/blender/blenkernel/CMakeLists.txt b/source/blender/blenkernel/CMakeLists.txt index 57996630c28..b350cb718c8 100644 --- a/source/blender/blenkernel/CMakeLists.txt +++ b/source/blender/blenkernel/CMakeLists.txt @@ -122,6 +122,7 @@ set(SRC intern/paint.c intern/particle.c intern/particle_system.c + intern/pbvh.c intern/pointcache.c intern/property.c intern/report.c @@ -149,7 +150,6 @@ set(SRC intern/writeavi.c intern/writeframeserver.c - BKE_DerivedMesh.h BKE_action.h BKE_anim.h @@ -161,6 +161,7 @@ set(SRC BKE_bmfont_types.h BKE_boids.h BKE_booleanops_mesh.h + BKE_bpath.h BKE_brush.h BKE_bullet.h BKE_bvhutils.h @@ -211,6 +212,7 @@ set(SRC BKE_packedFile.h BKE_paint.h BKE_particle.h + BKE_pbvh.h BKE_pointcache.h BKE_property.h BKE_report.h @@ -236,7 +238,6 @@ set(SRC BKE_world.h BKE_writeavi.h BKE_writeframeserver.h - BKE_bpath.h depsgraph_private.h nla_private.h diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c index 1f4cc9bc5c2..6b8baf42318 100644 --- a/source/blender/blenkernel/intern/DerivedMesh.c +++ b/source/blender/blenkernel/intern/DerivedMesh.c @@ -47,10 +47,10 @@ #include "BLI_math.h" #include "BLI_memarena.h" #include "BLI_array.h" -#include "BLI_pbvh.h" #include "BLI_utildefines.h" #include "BLI_linklist.h" +#include "BKE_pbvh.h" #include "BKE_cdderivedmesh.h" #include "BKE_displist.h" #include "BKE_key.h" diff --git a/source/blender/blenkernel/intern/action.c b/source/blender/blenkernel/intern/action.c index 5da4f05321a..83d1538ecbe 100644 --- a/source/blender/blenkernel/intern/action.c +++ b/source/blender/blenkernel/intern/action.c @@ -43,7 +43,6 @@ #include "DNA_object_types.h" #include "BLI_blenlib.h" -#include "BKE_bpath.h" #include "BLI_math.h" #include "BLI_utildefines.h" #include "BLI_ghash.h" diff --git a/source/blender/blenkernel/intern/armature.c b/source/blender/blenkernel/intern/armature.c index e8dfe027bd7..9155d67dc36 100644 --- a/source/blender/blenkernel/intern/armature.c +++ b/source/blender/blenkernel/intern/armature.c @@ -37,7 +37,6 @@ #include "MEM_guardedalloc.h" -#include "BKE_bpath.h" #include "BLI_math.h" #include "BLI_blenlib.h" #include "BLI_utildefines.h" diff --git a/source/blender/blenkernel/intern/blender.c b/source/blender/blenkernel/intern/blender.c index a46a3879dc8..42634e6e700 100644 --- a/source/blender/blenkernel/intern/blender.c +++ b/source/blender/blenkernel/intern/blender.c @@ -56,7 +56,6 @@ #include "DNA_sound_types.h" #include "BLI_blenlib.h" -#include "BKE_bpath.h" #include "BLI_dynstr.h" #include "BLI_utildefines.h" #include "BLI_callbacks.h" @@ -65,6 +64,7 @@ #include "IMB_moviecache.h" #include "BKE_blender.h" +#include "BKE_bpath.h" #include "BKE_context.h" #include "BKE_depsgraph.h" #include "BKE_displist.h" diff --git a/source/blender/blenkernel/intern/bpath.c b/source/blender/blenkernel/intern/bpath.c index 9f51dddb4fc..24b13b062f3 100644 --- a/source/blender/blenkernel/intern/bpath.c +++ b/source/blender/blenkernel/intern/bpath.c @@ -72,7 +72,6 @@ #include "DNA_smoke_types.h" #include "BLI_blenlib.h" -#include "BKE_bpath.h" #include "BLI_utildefines.h" #include "BKE_font.h" @@ -83,6 +82,8 @@ #include "BKE_sequencer.h" #include "BKE_image.h" /* so we can check the image's type */ +#include "BKE_bpath.h" /* own include */ + static int checkMissingFiles_visit_cb(void *userdata, char *UNUSED(path_dst), const char *path_src) { ReportList *reports = (ReportList *)userdata; diff --git a/source/blender/blenkernel/intern/brush.c b/source/blender/blenkernel/intern/brush.c index 7bcb9b45b23..405b1efb25d 100644 --- a/source/blender/blenkernel/intern/brush.c +++ b/source/blender/blenkernel/intern/brush.c @@ -46,7 +46,6 @@ #include "RNA_access.h" -#include "BKE_bpath.h" #include "BLI_math.h" #include "BLI_blenlib.h" #include "BLI_rand.h" diff --git a/source/blender/blenkernel/intern/cdderivedmesh.c b/source/blender/blenkernel/intern/cdderivedmesh.c index 54bbe4bf495..34adeb4fefb 100644 --- a/source/blender/blenkernel/intern/cdderivedmesh.c +++ b/source/blender/blenkernel/intern/cdderivedmesh.c @@ -40,12 +40,12 @@ #include "BLI_blenlib.h" #include "BLI_edgehash.h" #include "BLI_math.h" -#include "BLI_pbvh.h" #include "BLI_array.h" #include "BLI_smallhash.h" #include "BLI_utildefines.h" #include "BLI_scanfill.h" +#include "BKE_pbvh.h" #include "BKE_cdderivedmesh.h" #include "BKE_global.h" #include "BKE_mesh.h" diff --git a/source/blender/blenkernel/intern/curve.c b/source/blender/blenkernel/intern/curve.c index c9f084a9297..1d199cdf1e2 100644 --- a/source/blender/blenkernel/intern/curve.c +++ b/source/blender/blenkernel/intern/curve.c @@ -36,7 +36,6 @@ #include "MEM_guardedalloc.h" -#include "BKE_bpath.h" #include "BLI_blenlib.h" #include "BLI_math.h" #include "BLI_utildefines.h" diff --git a/source/blender/blenkernel/intern/editderivedmesh.c b/source/blender/blenkernel/intern/editderivedmesh.c index 73320c96315..bb8df834d0f 100644 --- a/source/blender/blenkernel/intern/editderivedmesh.c +++ b/source/blender/blenkernel/intern/editderivedmesh.c @@ -39,8 +39,8 @@ #include "BLI_blenlib.h" #include "BLI_edgehash.h" #include "BLI_math.h" -#include "BLI_pbvh.h" +#include "BKE_pbvh.h" #include "BKE_cdderivedmesh.h" #include "BKE_global.h" #include "BKE_mesh.h" diff --git a/source/blender/blenkernel/intern/image.c b/source/blender/blenkernel/intern/image.c index f1f9667c3d0..7f0475cf155 100644 --- a/source/blender/blenkernel/intern/image.c +++ b/source/blender/blenkernel/intern/image.c @@ -68,7 +68,6 @@ #include "BLI_blenlib.h" #include "BLI_threads.h" #include "BLI_utildefines.h" -#include "BKE_bpath.h" #include "BKE_bmfont.h" #include "BKE_colortools.h" diff --git a/source/blender/blenkernel/intern/lattice.c b/source/blender/blenkernel/intern/lattice.c index 7f3e43c40ff..d98188d8a6f 100644 --- a/source/blender/blenkernel/intern/lattice.c +++ b/source/blender/blenkernel/intern/lattice.c @@ -37,7 +37,6 @@ #include "MEM_guardedalloc.h" #include "BLI_blenlib.h" -#include "BKE_bpath.h" #include "BLI_math.h" #include "BLI_utildefines.h" diff --git a/source/blender/blenkernel/intern/material.c b/source/blender/blenkernel/intern/material.c index e4a938e7152..a3dcda7069a 100644 --- a/source/blender/blenkernel/intern/material.c +++ b/source/blender/blenkernel/intern/material.c @@ -52,7 +52,6 @@ #include "BLI_math.h" #include "BLI_listbase.h" #include "BLI_utildefines.h" -#include "BKE_bpath.h" #include "BLI_string.h" #include "BKE_animsys.h" diff --git a/source/blender/blenkernel/intern/mball.c b/source/blender/blenkernel/intern/mball.c index fdd0c504dac..5c882fd97d6 100644 --- a/source/blender/blenkernel/intern/mball.c +++ b/source/blender/blenkernel/intern/mball.c @@ -50,8 +50,6 @@ #include "BLI_blenlib.h" #include "BLI_math.h" #include "BLI_utildefines.h" -#include "BKE_bpath.h" - #include "BKE_global.h" #include "BKE_main.h" diff --git a/source/blender/blenkernel/intern/mesh.c b/source/blender/blenkernel/intern/mesh.c index e12c3bc2260..55cf2743bfa 100644 --- a/source/blender/blenkernel/intern/mesh.c +++ b/source/blender/blenkernel/intern/mesh.c @@ -46,7 +46,6 @@ #include "BLI_utildefines.h" #include "BLI_blenlib.h" -#include "BKE_bpath.h" #include "BLI_math.h" #include "BLI_edgehash.h" #include "BLI_scanfill.h" diff --git a/source/blender/blenkernel/intern/multires.c b/source/blender/blenkernel/intern/multires.c index c737dccc5d2..06d7cf55d49 100644 --- a/source/blender/blenkernel/intern/multires.c +++ b/source/blender/blenkernel/intern/multires.c @@ -43,9 +43,9 @@ #include "BLI_bitmap.h" #include "BLI_blenlib.h" #include "BLI_math.h" -#include "BLI_pbvh.h" #include "BLI_utildefines.h" +#include "BKE_pbvh.h" #include "BKE_ccg.h" #include "BKE_cdderivedmesh.h" #include "BKE_mesh.h" diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c index 85ad7186132..c705e226f45 100644 --- a/source/blender/blenkernel/intern/object.c +++ b/source/blender/blenkernel/intern/object.c @@ -59,12 +59,11 @@ #include "DNA_object_types.h" #include "BLI_blenlib.h" -#include "BKE_bpath.h" #include "BLI_math.h" -#include "BLI_pbvh.h" #include "BLI_utildefines.h" #include "BLI_linklist.h" +#include "BKE_pbvh.h" #include "BKE_main.h" #include "BKE_global.h" #include "BKE_idprop.h" diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c index 000545d936f..b2851962b49 100644 --- a/source/blender/blenkernel/intern/particle.c +++ b/source/blender/blenkernel/intern/particle.c @@ -55,7 +55,6 @@ #include "BLI_rand.h" #include "BLI_threads.h" #include "BLI_linklist.h" -#include "BKE_bpath.h" #include "BKE_anim.h" #include "BKE_animsys.h" diff --git a/source/blender/blenlib/intern/pbvh.c b/source/blender/blenkernel/intern/pbvh.c similarity index 99% rename from source/blender/blenlib/intern/pbvh.c rename to source/blender/blenkernel/intern/pbvh.c index 6fa6d86589f..3a4e8afca76 100644 --- a/source/blender/blenlib/intern/pbvh.c +++ b/source/blender/blenkernel/intern/pbvh.c @@ -22,8 +22,6 @@ * \ingroup bli */ - - #include "DNA_meshdata_types.h" #include "MEM_guardedalloc.h" @@ -32,8 +30,8 @@ #include "BLI_math.h" #include "BLI_utildefines.h" #include "BLI_ghash.h" -#include "BLI_pbvh.h" +#include "BKE_pbvh.h" #include "BKE_ccg.h" #include "BKE_DerivedMesh.h" #include "BKE_mesh.h" /* for BKE_mesh_calc_normals */ diff --git a/source/blender/blenkernel/intern/speaker.c b/source/blender/blenkernel/intern/speaker.c index 4594445dec0..f6599cc9648 100644 --- a/source/blender/blenkernel/intern/speaker.c +++ b/source/blender/blenkernel/intern/speaker.c @@ -35,7 +35,6 @@ #include "BLI_math.h" #include "BLI_utildefines.h" -#include "BKE_bpath.h" #include "BKE_animsys.h" #include "BKE_global.h" diff --git a/source/blender/blenkernel/intern/subsurf_ccg.c b/source/blender/blenkernel/intern/subsurf_ccg.c index be8b572417e..fdd115617de 100644 --- a/source/blender/blenkernel/intern/subsurf_ccg.c +++ b/source/blender/blenkernel/intern/subsurf_ccg.c @@ -50,8 +50,8 @@ #include "BLI_edgehash.h" #include "BLI_math.h" #include "BLI_memarena.h" -#include "BLI_pbvh.h" +#include "BKE_pbvh.h" #include "BKE_ccg.h" #include "BKE_cdderivedmesh.h" #include "BKE_global.h" diff --git a/source/blender/blenkernel/intern/texture.c b/source/blender/blenkernel/intern/texture.c index b78d23c5437..149842bc038 100644 --- a/source/blender/blenkernel/intern/texture.c +++ b/source/blender/blenkernel/intern/texture.c @@ -42,7 +42,6 @@ #include "BLI_math.h" #include "BLI_kdopbvh.h" #include "BLI_utildefines.h" -#include "BKE_bpath.h" #include "DNA_key_types.h" #include "DNA_object_types.h" diff --git a/source/blender/blenkernel/intern/world.c b/source/blender/blenkernel/intern/world.c index ef5ad435037..ad101c41dc5 100644 --- a/source/blender/blenkernel/intern/world.c +++ b/source/blender/blenkernel/intern/world.c @@ -40,7 +40,6 @@ #include "BLI_listbase.h" #include "BLI_utildefines.h" -#include "BKE_bpath.h" #include "BKE_animsys.h" #include "BKE_global.h" diff --git a/source/blender/blenlib/CMakeLists.txt b/source/blender/blenlib/CMakeLists.txt index f1f70a79202..6644c58611f 100644 --- a/source/blender/blenlib/CMakeLists.txt +++ b/source/blender/blenlib/CMakeLists.txt @@ -25,9 +25,7 @@ set(INC . - ../blenkernel - ../blenloader - ../gpu + # ../blenkernel # dont add this back! ../makesdna ../../../intern/ghost ../../../intern/guardedalloc @@ -77,7 +75,6 @@ set(SRC intern/md5.c intern/noise.c intern/path_util.c - intern/pbvh.c intern/quadric.c intern/rand.c intern/rct.c @@ -135,7 +132,6 @@ set(SRC BLI_mempool.h BLI_noise.h BLI_path_util.h - BLI_pbvh.h BLI_quadric.h BLI_rand.h BLI_rect.h diff --git a/source/blender/blenlib/SConscript b/source/blender/blenlib/SConscript index e53f622a5c4..e42c43566fc 100644 --- a/source/blender/blenlib/SConscript +++ b/source/blender/blenlib/SConscript @@ -4,8 +4,8 @@ Import ('env') sources = env.Glob('intern/*.c') cflags='' -incs = '. ../makesdna ../blenkernel #/intern/guardedalloc #/intern/ghost ../editors/include ../gpu ../blenloader' -incs += ' ../windowmanager ../bmesh #/extern/glew/include' +# don't add ../blenkernel back! +incs = '. ../makesdna #/intern/guardedalloc #/intern/ghost' incs += ' ' + env['BF_FREETYPE_INC'] incs += ' ' + env['BF_ZLIB_INC'] diff --git a/source/blender/blenlib/intern/BLI_ghash.c b/source/blender/blenlib/intern/BLI_ghash.c index 8767a9ac14c..7d2fc38272d 100644 --- a/source/blender/blenlib/intern/BLI_ghash.c +++ b/source/blender/blenlib/intern/BLI_ghash.c @@ -39,7 +39,7 @@ #include "BLI_mempool.h" #include "BLI_ghash.h" -#include "BLO_sys_types.h" // for intptr_t support +#include "MEM_sys_types.h" /* for intptr_t support */ /***/ unsigned int hashsizes[] = { diff --git a/source/blender/blenlib/intern/endian_switch.c b/source/blender/blenlib/intern/endian_switch.c index b9b18136863..e3ed88b6f8d 100644 --- a/source/blender/blenlib/intern/endian_switch.c +++ b/source/blender/blenlib/intern/endian_switch.c @@ -24,7 +24,7 @@ * \ingroup bli */ -#include "BLO_sys_types.h" +#include "MEM_sys_types.h" #include "BLI_utildefines.h" #include "BLI_endian_switch.h" diff --git a/source/blender/blenlib/intern/fileops.c b/source/blender/blenlib/intern/fileops.c index 883cdfde426..0f42fca9f12 100644 --- a/source/blender/blenlib/intern/fileops.c +++ b/source/blender/blenlib/intern/fileops.c @@ -63,7 +63,7 @@ #include "BLI_blenlib.h" #include "BLI_utildefines.h" -#include "BLO_sys_types.h" // for intptr_t support +#include "MEM_sys_types.h" // for intptr_t support /* gzip the file in from and write it to "to". diff --git a/source/blender/blenlib/intern/freetypefont.c b/source/blender/blenlib/intern/freetypefont.c index 0a87316aa81..353b73a6403 100644 --- a/source/blender/blenlib/intern/freetypefont.c +++ b/source/blender/blenlib/intern/freetypefont.c @@ -52,8 +52,6 @@ #include "BLI_math.h" #include "BLI_utildefines.h" -#include "BKE_font.h" - #include "DNA_vfont_types.h" #include "DNA_packedFile_types.h" #include "DNA_curve_types.h" diff --git a/source/blender/blenlib/intern/path_util.c b/source/blender/blenlib/intern/path_util.c index 444daf8817c..7c1842b10f2 100644 --- a/source/blender/blenlib/intern/path_util.c +++ b/source/blender/blenlib/intern/path_util.c @@ -47,7 +47,7 @@ #include "BLI_string_utf8.h" #include "BLI_utildefines.h" -#include "BKE_blender.h" /* BLENDER_VERSION */ +#include "../blenkernel/BKE_blender.h" /* BLENDER_VERSION, bad level include (no function call) */ #include "GHOST_Path-api.h" diff --git a/source/blender/blenlib/intern/winstuff.c b/source/blender/blenlib/intern/winstuff.c index 68d9d74cca4..65fb490b218 100644 --- a/source/blender/blenlib/intern/winstuff.c +++ b/source/blender/blenlib/intern/winstuff.c @@ -41,7 +41,7 @@ #include "BLI_path_util.h" #include "BLI_string.h" -#include "BKE_global.h" +#include "../blenkernel/BKE_global.h" /* G.background, bad level include (no function calls) */ #define WIN32_SKIP_HKEY_PROTECTION // need to use HKEY #include "BLI_winstuff.h" diff --git a/source/blender/editors/sculpt_paint/paint_hide.c b/source/blender/editors/sculpt_paint/paint_hide.c index bdd73cd6db3..36fe4715fc0 100644 --- a/source/blender/editors/sculpt_paint/paint_hide.c +++ b/source/blender/editors/sculpt_paint/paint_hide.c @@ -37,7 +37,6 @@ #include "BLI_bitmap.h" #include "BLI_listbase.h" #include "BLI_math_vector.h" -#include "BLI_pbvh.h" #include "BLI_utildefines.h" #include "DNA_mesh_types.h" @@ -45,6 +44,7 @@ #include "DNA_object_types.h" #include "DNA_scene_types.h" +#include "BKE_pbvh.h" #include "BKE_ccg.h" #include "BKE_context.h" #include "BKE_DerivedMesh.h" diff --git a/source/blender/editors/sculpt_paint/paint_mask.c b/source/blender/editors/sculpt_paint/paint_mask.c index 697d7c63d1f..9fe7fc1d3ac 100644 --- a/source/blender/editors/sculpt_paint/paint_mask.c +++ b/source/blender/editors/sculpt_paint/paint_mask.c @@ -38,8 +38,7 @@ #include "DNA_meshdata_types.h" #include "DNA_object_types.h" -#include "BLI_pbvh.h" - +#include "BKE_pbvh.h" #include "BKE_ccg.h" #include "BKE_context.h" #include "BKE_DerivedMesh.h" diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c index e2ed7776b7e..8325b47beab 100644 --- a/source/blender/editors/sculpt_paint/sculpt.c +++ b/source/blender/editors/sculpt_paint/sculpt.c @@ -40,7 +40,6 @@ #include "BLI_utildefines.h" #include "BLI_dynstr.h" #include "BLI_ghash.h" -#include "BLI_pbvh.h" #include "BLI_threads.h" #include "BLI_rand.h" @@ -51,6 +50,7 @@ #include "DNA_scene_types.h" #include "DNA_brush_types.h" +#include "BKE_pbvh.h" #include "BKE_brush.h" #include "BKE_ccg.h" #include "BKE_cdderivedmesh.h" diff --git a/source/blender/editors/sculpt_paint/sculpt_intern.h b/source/blender/editors/sculpt_paint/sculpt_intern.h index acb906e4a91..44068122b89 100644 --- a/source/blender/editors/sculpt_paint/sculpt_intern.h +++ b/source/blender/editors/sculpt_paint/sculpt_intern.h @@ -38,7 +38,7 @@ #include "DNA_key_types.h" #include "BLI_bitmap.h" -#include "BLI_pbvh.h" +#include "BKE_pbvh.h" struct bContext; struct Brush; diff --git a/source/blender/makesrna/intern/rna_sculpt_paint.c b/source/blender/makesrna/intern/rna_sculpt_paint.c index 84e76fae896..f717c83075a 100644 --- a/source/blender/makesrna/intern/rna_sculpt_paint.c +++ b/source/blender/makesrna/intern/rna_sculpt_paint.c @@ -59,8 +59,7 @@ static EnumPropertyItem particle_edit_hair_brush_items[] = { #include "BKE_pointcache.h" #include "BKE_particle.h" #include "BKE_depsgraph.h" - -#include "BLI_pbvh.h" +#include "BKE_pbvh.h" #include "ED_particle.h" From c26746ccec8f7513cc28612842dc4033dddaa91d Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sat, 15 Dec 2012 16:13:27 +0000 Subject: [PATCH 153/252] use struct type for VPaintData.vertexcosnos rather then float*. --- source/blender/blenkernel/BKE_DerivedMesh.h | 7 +++++- .../blender/blenkernel/intern/DerivedMesh.c | 14 +++++------ .../editors/sculpt_paint/paint_vertex.c | 25 +++++++++---------- 3 files changed, 25 insertions(+), 21 deletions(-) diff --git a/source/blender/blenkernel/BKE_DerivedMesh.h b/source/blender/blenkernel/BKE_DerivedMesh.h index 617c4cd2bc8..ed90c63d949 100644 --- a/source/blender/blenkernel/BKE_DerivedMesh.h +++ b/source/blender/blenkernel/BKE_DerivedMesh.h @@ -105,6 +105,11 @@ struct PBVH; * Also, the mface origindex layer indexes mpolys, not mfaces. */ +typedef struct DMCoNo { + float co[3]; + float no[3]; +} DMCoNo; + typedef struct DMGridAdjacency { int index[4]; int rotation[4]; @@ -603,7 +608,7 @@ void vDM_ColorBand_store(struct ColorBand *coba); /** Simple function to get me->totvert amount of vertices/normals, * correctly deformed and subsurfered. Needed especially when vertexgroups are involved. * In use now by vertex/weight paint and particles */ -float *mesh_get_mapped_verts_nors(struct Scene *scene, struct Object *ob); +DMCoNo *mesh_get_mapped_verts_nors(struct Scene *scene, struct Object *ob); /* */ DerivedMesh *mesh_get_derived_final(struct Scene *scene, struct Object *ob, diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c index 6b8baf42318..010839764b2 100644 --- a/source/blender/blenkernel/intern/DerivedMesh.c +++ b/source/blender/blenkernel/intern/DerivedMesh.c @@ -2334,29 +2334,29 @@ static void make_vertexcosnos__mapFunc(void *userData, int index, const float co /* it stores the normals as floats, but they can still be scaled as shorts (32767 = unit) */ /* in use now by vertex/weight paint and particle generating */ -float *mesh_get_mapped_verts_nors(Scene *scene, Object *ob) +DMCoNo *mesh_get_mapped_verts_nors(Scene *scene, Object *ob) { Mesh *me = ob->data; DerivedMesh *dm; - float *vertexcosnos; + DMCoNo *vertexcosnos; /* lets prevent crashing... */ if (ob->type != OB_MESH || me->totvert == 0) return NULL; dm = mesh_get_derived_final(scene, ob, CD_MASK_BAREMESH | CD_MASK_ORIGINDEX); - vertexcosnos = MEM_callocN(6 * sizeof(float) * me->totvert, "vertexcosnos map"); + vertexcosnos = MEM_callocN(sizeof(DMCoNo) * me->totvert, "vertexcosnos map"); if (dm->foreachMappedVert) { dm->foreachMappedVert(dm, make_vertexcosnos__mapFunc, vertexcosnos); } else { - float *fp = vertexcosnos; + DMCoNo *v_co_no = vertexcosnos; int a; - for (a = 0; a < me->totvert; a++, fp += 6) { - dm->getVertCo(dm, a, fp); - dm->getVertNo(dm, a, fp + 3); + for (a = 0; a < me->totvert; a++, v_co_no++) { + dm->getVertCo(dm, a, v_co_no->co); + dm->getVertNo(dm, a, v_co_no->no); } } diff --git a/source/blender/editors/sculpt_paint/paint_vertex.c b/source/blender/editors/sculpt_paint/paint_vertex.c index 76d666c7e27..073aee1d974 100644 --- a/source/blender/editors/sculpt_paint/paint_vertex.c +++ b/source/blender/editors/sculpt_paint/paint_vertex.c @@ -851,12 +851,12 @@ static int sample_backbuf_area(ViewContext *vc, int *indexar, int totface, int x } /* whats _dl mean? */ -static float calc_vp_strength_dl(VPaint *vp, ViewContext *vc, const float vert_nor[3], +static float calc_vp_strength_dl(VPaint *vp, ViewContext *vc, const float co[3], const float mval[2], const float brush_size_pressure) { float vertco[2]; - if (ED_view3d_project_float_global(vc->ar, vert_nor, vertco, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) { + if (ED_view3d_project_float_global(vc->ar, co, vertco, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) { float delta[2]; float dist_squared; @@ -873,24 +873,23 @@ static float calc_vp_strength_dl(VPaint *vp, ViewContext *vc, const float vert_n } static float calc_vp_alpha_dl(VPaint *vp, ViewContext *vc, - float vpimat[3][3], const float *vert_nor, + float vpimat[3][3], const DMCoNo *v_co_no, const float mval[2], const float brush_size_pressure, const float brush_alpha_pressure) { - float strength = calc_vp_strength_dl(vp, vc, vert_nor, mval, brush_size_pressure); + float strength = calc_vp_strength_dl(vp, vc, v_co_no->co, mval, brush_size_pressure); if (strength > 0.0f) { float alpha = brush_alpha_pressure * strength; if (vp->flag & VP_NORMALS) { float dvec[3]; - const float *no = vert_nor + 3; /* transpose ! */ - dvec[2] = dot_v3v3(vpimat[2], no); + dvec[2] = dot_v3v3(vpimat[2], v_co_no->no); if (dvec[2] > 0.0f) { - dvec[0] = dot_v3v3(vpimat[0], no); - dvec[1] = dot_v3v3(vpimat[1], no); + dvec[0] = dot_v3v3(vpimat[0], v_co_no->no); + dvec[1] = dot_v3v3(vpimat[1], v_co_no->no); alpha *= dvec[2] / len_v3(dvec); } @@ -2038,7 +2037,7 @@ struct WPaintData { int *indexar; int vgroup_active; int vgroup_mirror; - float *vertexcosnos; + DMCoNo *vertexcosnos; float wpimat[3][3]; /* variables for auto normalize */ @@ -2286,7 +2285,7 @@ static void wpaint_stroke_update_step(bContext *C, struct PaintStroke *stroke, P ml = me->mloop + mpoly->loopstart; for (i = 0; i < mpoly->totloop; i++, ml++) { unsigned int vidx = ml->v; - const float fac = calc_vp_strength_dl(wp, vc, wpd->vertexcosnos + 6 * vidx, mval, brush_size_pressure); + const float fac = calc_vp_strength_dl(wp, vc, wpd->vertexcosnos[vidx].co, mval, brush_size_pressure); if (fac > 0.0f) { dw = dw_func(&me->dvert[vidx], wpi.vgroup_active); paintweight += dw ? (dw->weight * fac) : 0.0f; @@ -2312,7 +2311,7 @@ static void wpaint_stroke_update_step(bContext *C, struct PaintStroke *stroke, P unsigned int vidx = ml->v; if (me->dvert[vidx].flag) { - alpha = calc_vp_alpha_dl(wp, vc, wpd->wpimat, wpd->vertexcosnos + 6 * vidx, + alpha = calc_vp_alpha_dl(wp, vc, wpd->wpimat, &wpd->vertexcosnos[vidx], mval, brush_size_pressure, brush_alpha_pressure); if (alpha) { do_weight_paint_vertex(wp, ob, &wpi, vidx, alpha, paintweight); @@ -2548,7 +2547,7 @@ typedef struct VPaintData { ViewContext vc; unsigned int paintcol; int *indexar; - float *vertexcosnos; + DMCoNo *vertexcosnos; float vpimat[3][3]; /* modify 'me->mcol' directly, since the derived mesh is drawing from this array, @@ -2696,7 +2695,7 @@ static void vpaint_paint_poly(VPaint *vp, VPaintData *vpd, Object *ob, ml = me->mloop + mpoly->loopstart; for (i = 0; i < mpoly->totloop; i++, ml++) { alpha = calc_vp_alpha_dl(vp, vc, vpd->vpimat, - vpd->vertexcosnos + 6 * ml->v, mval, + &vpd->vertexcosnos[ml->v], mval, brush_size_pressure, brush_alpha_pressure); if (alpha > 0.0f) { const int alpha_i = (int)(alpha * 255.0f); From 695468a3b9a54dc2f26b2aac7c48d6d066f80b3d Mon Sep 17 00:00:00 2001 From: Ton Roosendaal Date: Sat, 15 Dec 2012 16:22:18 +0000 Subject: [PATCH 154/252] Finished themes for transparent Button regions in Blender. Notes and image: http://wiki.blender.org/index.php/Dev:Ref/Release_Notes/2.66/Usability - now each editor has own settings for "show panel header" and "show panel background", and colors+alpha for this. - this setting used to be global for all editors, but it can conflict with looks of specific editors. - Now you can set for editors to show panels with a 100% transparent tool/properties region. Note: read XML theme files now might get an error, Campbell will fix. --- .../scripts/startup/bl_ui/space_userpref.py | 24 ------ source/blender/blenkernel/BKE_blender.h | 2 +- source/blender/blenkernel/intern/blender.c | 1 - source/blender/editors/include/UI_resources.h | 7 ++ .../editors/interface/interface_panel.c | 14 +++- source/blender/editors/interface/resources.c | 70 ++++++++++++---- source/blender/editors/screen/screen_ops.c | 7 +- .../blender/editors/space_file/space_file.c | 2 +- source/blender/makesdna/DNA_userdef_types.h | 31 +++++--- source/blender/makesrna/intern/rna_userdef.c | 79 +++++++++++-------- 10 files changed, 138 insertions(+), 99 deletions(-) diff --git a/release/scripts/startup/bl_ui/space_userpref.py b/release/scripts/startup/bl_ui/space_userpref.py index 42d64078acb..4a8459aedcf 100644 --- a/release/scripts/startup/bl_ui/space_userpref.py +++ b/release/scripts/startup/bl_ui/space_userpref.py @@ -707,30 +707,6 @@ class USERPREF_PT_theme(Panel): col.separator() col.separator() - ui = theme.user_interface.panel - col.label("Panels:") - - row = col.row() - - subsplit = row.split(percentage=0.95) - - padding = subsplit.split(percentage=0.15) - colsub = padding.column() - colsub = padding.column() - rowsub = colsub.row() - rowsub.prop(ui, "show_header") - rowsub.label() - - subsplit = row.split(percentage=0.85) - - padding = subsplit.split(percentage=0.15) - colsub = padding.column() - colsub = padding.column() - colsub.row().prop(ui, "header") - - col.separator() - col.separator() - ui = theme.user_interface col.label("Axis Colors:") diff --git a/source/blender/blenkernel/BKE_blender.h b/source/blender/blenkernel/BKE_blender.h index 8ba850c952c..980514608f3 100644 --- a/source/blender/blenkernel/BKE_blender.h +++ b/source/blender/blenkernel/BKE_blender.h @@ -42,7 +42,7 @@ extern "C" { * and keep comment above the defines. * Use STRINGIFY() rather than defining with quotes */ #define BLENDER_VERSION 265 -#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 diff --git a/source/blender/blenkernel/intern/blender.c b/source/blender/blenkernel/intern/blender.c index 42634e6e700..7aec7dddba6 100644 --- a/source/blender/blenkernel/intern/blender.c +++ b/source/blender/blenkernel/intern/blender.c @@ -403,7 +403,6 @@ void BKE_userdef_free(void) /* handle changes in settings that need recalc */ void BKE_userdef_state(void) { - if (U.pixelsize == 0) U.pixelsize = 1; BLF_default_dpi(U.pixelsize * U.dpi); U.widget_unit = (U.pixelsize * U.dpi * 20 + 36) / 72; diff --git a/source/blender/editors/include/UI_resources.h b/source/blender/editors/include/UI_resources.h index f4e921e2fa4..dbbcc6953ed 100644 --- a/source/blender/editors/include/UI_resources.h +++ b/source/blender/editors/include/UI_resources.h @@ -69,6 +69,13 @@ enum { TH_PANEL_TEXT, TH_PANEL_TEXT_HI, + /* panels */ + TH_PANEL_HEADER, + TH_PANEL_BACK, + TH_PANEL_SHOW_HEADER, + TH_PANEL_SHOW_BACK, + + TH_BUTBACK, TH_BUTBACK_TEXT, TH_BUTBACK_TEXT_HI, diff --git a/source/blender/editors/interface/interface_panel.c b/source/blender/editors/interface/interface_panel.c index 3eb4026f0e0..8b5f69e9dc3 100644 --- a/source/blender/editors/interface/interface_panel.c +++ b/source/blender/editors/interface/interface_panel.c @@ -499,7 +499,6 @@ static void rectf_scale(rctf *rect, const float scale) /* panel integrated in buttonswindow, tool/property lists etc */ void ui_draw_aligned_panel(uiStyle *style, uiBlock *block, rcti *rect) { - bTheme *btheme = UI_GetTheme(); Panel *panel = block->panel; rcti headrect; rctf itemrect; @@ -521,10 +520,11 @@ void ui_draw_aligned_panel(uiStyle *style, uiBlock *block, rcti *rect) glEnable(GL_BLEND); - if (btheme->tui.panel.show_header) { + + if (UI_GetThemeValue(TH_PANEL_SHOW_HEADER)) { /* draw with background color */ glEnable(GL_BLEND); - glColor4ubv((unsigned char *)btheme->tui.panel.header); + UI_ThemeColor4(TH_PANEL_HEADER); glRectf(minx, headrect.ymin + 1, maxx, y); fdrawline(minx, y, maxx, y); @@ -581,6 +581,14 @@ void ui_draw_aligned_panel(uiStyle *style, uiBlock *block, rcti *rect) uiRoundRect(0.5f + rect->xmin, 0.5f + rect->ymin, 0.5f + rect->xmax, 0.5f + headrect.ymax + 1, 8); } + /* panel backdrop */ + if (UI_GetThemeValue(TH_PANEL_SHOW_BACK)) { + /* draw with background color */ + glEnable(GL_BLEND); + UI_ThemeColor4(TH_PANEL_BACK); + glRecti(rect->xmin, rect->ymin, rect->xmax, rect->ymax); + } + if (panel->control & UI_PNL_SCALE) ui_draw_panel_scalewidget(rect); } diff --git a/source/blender/editors/interface/resources.c b/source/blender/editors/interface/resources.c index 5f0f7ab7ba7..3036961d279 100644 --- a/source/blender/editors/interface/resources.c +++ b/source/blender/editors/interface/resources.c @@ -86,7 +86,7 @@ const unsigned char *UI_ThemeGetColorPtr(bTheme *btheme, int spacetype, int colo static char error[4] = {240, 0, 240, 255}; static char alert[4] = {240, 60, 60, 255}; static char headerdesel[4] = {0, 0, 0, 255}; - + static char setting = 0; const char *cp = error; if (btheme) { @@ -216,13 +216,19 @@ const unsigned char *UI_ThemeGetColorPtr(bTheme *btheme, int spacetype, int colo case TH_HEADER_TEXT_HI: cp = ts->header_text_hi; break; - case TH_PANEL: - cp = ts->panel; break; - case TH_PANEL_TEXT: - cp = ts->panel_text; break; - case TH_PANEL_TEXT_HI: - cp = ts->panel_text_hi; break; - + case TH_PANEL_HEADER: + cp = ts->panelcolors.header; break; + case TH_PANEL_BACK: + cp = ts->panelcolors.back; break; + case TH_PANEL_SHOW_HEADER: + cp = &setting; + setting = ts->panelcolors.show_header; + break; + case TH_PANEL_SHOW_BACK: + cp = &setting; + setting = ts->panelcolors.show_back; + break; + case TH_BUTBACK: cp = ts->button; break; case TH_BUTBACK_TEXT: @@ -603,9 +609,9 @@ static void ui_theme_init_new_do(ThemeSpace *ts) rgba_char_args_test_set(ts->header_title, 0, 0, 0, 255); rgba_char_args_test_set(ts->header_text_hi, 255, 255, 255, 255); - rgba_char_args_test_set(ts->panel_text, 0, 0, 0, 255); - rgba_char_args_test_set(ts->panel_title, 0, 0, 0, 255); - rgba_char_args_test_set(ts->panel_text_hi, 255, 255, 255, 255); +// rgba_char_args_test_set(ts->panel_text, 0, 0, 0, 255); +// rgba_char_args_test_set(ts->panel_title, 0, 0, 0, 255); +// rgba_char_args_test_set(ts->panel_text_hi, 255, 255, 255, 255); rgba_char_args_test_set(ts->button, 145, 145, 145, 245); rgba_char_args_test_set(ts->button_title, 0, 0, 0, 255); @@ -684,7 +690,7 @@ void ui_theme_init_default(void) rgba_char_args_set_fl(btheme->tv3d.header, 0.45, 0.45, 0.45, 1.0); rgba_char_args_set_fl(btheme->tv3d.button, 0.45, 0.45, 0.45, 0.5); - rgba_char_args_set(btheme->tv3d.panel, 165, 165, 165, 127); +// rgba_char_args_set(btheme->tv3d.panel, 165, 165, 165, 127); rgba_char_args_set(btheme->tv3d.shade1, 160, 160, 160, 100); rgba_char_args_set(btheme->tv3d.shade2, 0x7f, 0x70, 0x70, 100); @@ -763,14 +769,14 @@ void ui_theme_init_default(void) btheme->tbuts = btheme->tv3d; rgba_char_args_set_fl(btheme->tbuts.back, 0.45, 0.45, 0.45, 1.0); - rgba_char_args_set(btheme->tbuts.panel, 0x82, 0x82, 0x82, 255); +// rgba_char_args_set(btheme->tbuts.panel, 0x82, 0x82, 0x82, 255); /* graph editor */ btheme->tipo = btheme->tv3d; rgba_char_args_set_fl(btheme->tipo.back, 0.42, 0.42, 0.42, 1.0); rgba_char_args_set_fl(btheme->tipo.list, 0.4, 0.4, 0.4, 1.0); rgba_char_args_set(btheme->tipo.grid, 94, 94, 94, 255); - rgba_char_args_set(btheme->tipo.panel, 255, 255, 255, 150); +// rgba_char_args_set(btheme->tipo.panel, 255, 255, 255, 150); rgba_char_args_set(btheme->tipo.shade1, 150, 150, 150, 100); /* scrollbars */ rgba_char_args_set(btheme->tipo.shade2, 0x70, 0x70, 0x70, 100); rgba_char_args_set(btheme->tipo.vertex, 0, 0, 0, 255); @@ -816,11 +822,11 @@ void ui_theme_init_default(void) /* to have something initialized */ btheme->tfile = btheme->tv3d; rgba_char_args_set_fl(btheme->tfile.back, 0.3, 0.3, 0.3, 1); - rgba_char_args_set_fl(btheme->tfile.panel, 0.3, 0.3, 0.3, 1); +// rgba_char_args_set_fl(btheme->tfile.panel, 0.3, 0.3, 0.3, 1); rgba_char_args_set_fl(btheme->tfile.list, 0.4, 0.4, 0.4, 1); rgba_char_args_set(btheme->tfile.text, 250, 250, 250, 255); rgba_char_args_set(btheme->tfile.text_hi, 15, 15, 15, 255); - rgba_char_args_set(btheme->tfile.panel, 145, 145, 145, 255); /* bookmark/ui regions */ +// rgba_char_args_set(btheme->tfile.panel, 145, 145, 145, 255); /* bookmark/ui regions */ rgba_char_args_set(btheme->tfile.active, 130, 130, 130, 255); /* selected files */ rgba_char_args_set(btheme->tfile.hilite, 255, 140, 25, 255); /* selected files */ @@ -2024,6 +2030,38 @@ void init_userdef_do_versions(void) } } } + + /* panel header/backdrop supported locally per editor now */ + if (bmain->versionfile < 265 || (bmain->versionfile == 265 && bmain->subversionfile < 2)) { + bTheme *btheme; + + for (btheme = U.themes.first; btheme; btheme = btheme->next) { + + /* new color, panel backdrop. Not used anywhere yet, until you enable it */ + copy_v3_v3_char(btheme->tui.panel.back, btheme->tbuts.button); + btheme->tui.panel.back[3] = 128; + + btheme->tbuts.panelcolors = btheme->tui.panel; + btheme->tv3d.panelcolors = btheme->tui.panel; + btheme->tfile.panelcolors = btheme->tui.panel; + btheme->tipo.panelcolors = btheme->tui.panel; + btheme->tinfo.panelcolors = btheme->tui.panel; + btheme->tact.panelcolors = btheme->tui.panel; + btheme->tnla.panelcolors = btheme->tui.panel; + btheme->tseq.panelcolors = btheme->tui.panel; + btheme->tima.panelcolors = btheme->tui.panel; + btheme->text.panelcolors = btheme->tui.panel; + btheme->toops.panelcolors = btheme->tui.panel; + btheme->ttime.panelcolors = btheme->tui.panel; + btheme->tnode.panelcolors = btheme->tui.panel; + btheme->tlogic.panelcolors = btheme->tui.panel; + btheme->tuserpref.panelcolors = btheme->tui.panel; + btheme->tconsole.panelcolors = btheme->tui.panel; + btheme->tclip.panelcolors = btheme->tui.panel; + } + } + + if (U.pixelsize == 0.0f) U.pixelsize = 1.0f; diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c index 0f1c44de4ce..a26f5e87090 100644 --- a/source/blender/editors/screen/screen_ops.c +++ b/source/blender/editors/screen/screen_ops.c @@ -1021,11 +1021,8 @@ static int area_move_init(bContext *C, wmOperator *op) select_connected_scredge(sc, actedge); /* now all vertices with 'flag==1' are the ones that can be moved. Move this to editflag */ - for (v1 = sc->vertbase.first; v1; v1 = v1->next) { - v1->editflag = 0; - if (v1->flag) - v1->editflag = 1; - } + for (v1 = sc->vertbase.first; v1; v1 = v1->next) + v1->editflag = v1->flag; area_move_set_limits(sc, md->dir, &md->bigger, &md->smaller); diff --git a/source/blender/editors/space_file/space_file.c b/source/blender/editors/space_file/space_file.c index be037a0d5ba..7cc322c06bb 100644 --- a/source/blender/editors/space_file/space_file.c +++ b/source/blender/editors/space_file/space_file.c @@ -533,7 +533,7 @@ static void file_ui_area_draw(const bContext *C, ARegion *ar) { float col[3]; /* clear */ - UI_GetThemeColor3fv(TH_PANEL, col); + UI_GetThemeColor3fv(TH_BACK, col); glClearColor(col[0], col[1], col[2], 0.0); glClear(GL_COLOR_BUFFER_BIT); diff --git a/source/blender/makesdna/DNA_userdef_types.h b/source/blender/makesdna/DNA_userdef_types.h index 8f8cf3eda26..a67502d9283 100644 --- a/source/blender/makesdna/DNA_userdef_types.h +++ b/source/blender/makesdna/DNA_userdef_types.h @@ -143,8 +143,10 @@ typedef struct uiWidgetStateColors { typedef struct uiPanelColors { char header[4]; + char back[4]; short show_header; - short pad; + short show_back; + int pad; } uiPanelColors; typedef struct ThemeUI { @@ -157,7 +159,7 @@ typedef struct ThemeUI { uiWidgetStateColors wcol_state; - uiPanelColors panel; + uiPanelColors panel; /* depricated, but we keep it for do_versions (2.66.1) */ char iconfile[256]; // FILE_MAXFILE length float icon_alpha; @@ -172,33 +174,36 @@ typedef struct ThemeUI { typedef struct ThemeSpace { /* main window colors */ char back[4]; - char title[4]; + char title[4]; /* panel title */ char text[4]; char text_hi[4]; /* header colors */ - char header[4]; - char header_title[4]; + char header[4]; /* region background */ + char header_title[4]; /* unused */ char header_text[4]; char header_text_hi[4]; /* button/tool regions */ - char button[4]; - char button_title[4]; + char button[4]; /* region background */ + char button_title[4]; /* panel title */ char button_text[4]; char button_text_hi[4]; /* listview regions */ - char list[4]; - char list_title[4]; + char list[4]; /* region background */ + char list_title[4]; /* panel title */ char list_text[4]; char list_text_hi[4]; /* float panel */ - char panel[4]; - char panel_title[4]; - char panel_text[4]; - char panel_text_hi[4]; +/* char panel[4]; unused */ +/* char panel_title[4]; unused */ +/* char panel_text[4]; unused */ +/* char panel_text_hi[4]; unused */ + + /* note, cannot use name 'panel' because of DNA mapping old files */ + uiPanelColors panelcolors; char shade1[4]; char shade2[4]; diff --git a/source/blender/makesrna/intern/rna_userdef.c b/source/blender/makesrna/intern/rna_userdef.c index d24ddcdaef2..c0467a43222 100644 --- a/source/blender/makesrna/intern/rna_userdef.c +++ b/source/blender/makesrna/intern/rna_userdef.c @@ -504,12 +504,12 @@ static void rna_def_userdef_theme_ui_style(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Panel Zoom", "Default zoom level for panel areas"); #endif - prop = RNA_def_property(srna, "panel_title", PROP_POINTER, PROP_NONE); - RNA_def_property_flag(prop, PROP_NEVER_NULL); - RNA_def_property_pointer_sdna(prop, NULL, "paneltitle"); - RNA_def_property_struct_type(prop, "ThemeFontStyle"); - RNA_def_property_ui_text(prop, "Panel Style", ""); - RNA_def_property_update(prop, 0, "rna_userdef_update"); +// prop = RNA_def_property(srna, "panel_title", PROP_POINTER, PROP_NONE); +// RNA_def_property_flag(prop, PROP_NEVER_NULL); +// RNA_def_property_pointer_sdna(prop, NULL, "paneltitle"); +// RNA_def_property_struct_type(prop, "ThemeFontStyle"); +// RNA_def_property_ui_text(prop, "Panel Style", ""); +// RNA_def_property_update(prop, 0, "rna_userdef_update"); /* (not used yet) */ #if 0 @@ -650,10 +650,18 @@ static void rna_def_userdef_theme_ui_panel(BlenderRNA *brna) prop = RNA_def_property(srna, "header", PROP_FLOAT, PROP_COLOR_GAMMA); RNA_def_property_ui_text(prop, "Header", ""); RNA_def_property_update(prop, 0, "rna_userdef_update"); - + + prop = RNA_def_property(srna, "back", PROP_FLOAT, PROP_COLOR_GAMMA); + RNA_def_property_ui_text(prop, "Background", ""); + RNA_def_property_update(prop, 0, "rna_userdef_update"); + prop = RNA_def_property(srna, "show_header", PROP_BOOLEAN, PROP_NONE); RNA_def_property_ui_text(prop, "Show Header", ""); RNA_def_property_update(prop, 0, "rna_userdef_update"); + + prop = RNA_def_property(srna, "show_back", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_ui_text(prop, "Show Background", ""); + RNA_def_property_update(prop, 0, "rna_userdef_update"); } static void rna_def_userdef_theme_ui(BlenderRNA *brna) @@ -759,11 +767,6 @@ static void rna_def_userdef_theme_ui(BlenderRNA *brna) RNA_def_property_ui_text(prop, "State Colors", ""); RNA_def_property_update(prop, 0, "rna_userdef_update"); - prop = RNA_def_property(srna, "panel", PROP_POINTER, PROP_NONE); - RNA_def_property_flag(prop, PROP_NEVER_NULL); - RNA_def_property_ui_text(prop, "Panel Colors", ""); - RNA_def_property_update(prop, 0, "rna_userdef_update"); - prop = RNA_def_property(srna, "icon_file", PROP_STRING, PROP_FILEPATH); RNA_def_property_string_sdna(prop, NULL, "iconfile"); RNA_def_property_ui_text(prop, "Icon File", ""); @@ -839,6 +842,12 @@ static void rna_def_userdef_theme_space_generic(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Header Text Highlight", ""); RNA_def_property_update(prop, 0, "rna_userdef_update"); + /* panel settings */ + prop = RNA_def_property(srna, "panelcolors", PROP_POINTER, PROP_NONE); + RNA_def_property_flag(prop, PROP_NEVER_NULL); + RNA_def_property_ui_text(prop, "Panel Colors", ""); + RNA_def_property_update(prop, 0, "rna_userdef_update"); + /* buttons */ /* if (! ELEM(spacetype, SPACE_BUTS, SPACE_OUTLINER)) { */ prop = RNA_def_property(srna, "button", PROP_FLOAT, PROP_COLOR_GAMMA); @@ -1116,10 +1125,10 @@ static void rna_def_userdef_theme_space_view3d(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Grid", ""); RNA_def_property_update(prop, 0, "rna_userdef_update"); - prop = RNA_def_property(srna, "panel", PROP_FLOAT, PROP_COLOR_GAMMA); - RNA_def_property_array(prop, 4); - RNA_def_property_ui_text(prop, "Panel", ""); - RNA_def_property_update(prop, 0, "rna_userdef_update"); +// prop = RNA_def_property(srna, "panel", PROP_FLOAT, PROP_COLOR_GAMMA); +// RNA_def_property_array(prop, 4); +// RNA_def_property_ui_text(prop, "Panel", ""); +// RNA_def_property_update(prop, 0, "rna_userdef_update"); prop = RNA_def_property(srna, "wire", PROP_FLOAT, PROP_COLOR_GAMMA); RNA_def_property_array(prop, 3); @@ -1275,10 +1284,10 @@ static void rna_def_userdef_theme_space_graph(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Grid", ""); RNA_def_property_update(prop, 0, "rna_userdef_update"); - prop = RNA_def_property(srna, "panel", PROP_FLOAT, PROP_COLOR_GAMMA); - RNA_def_property_array(prop, 3); - RNA_def_property_ui_text(prop, "Panel", ""); - RNA_def_property_update(prop, 0, "rna_userdef_update"); +// prop = RNA_def_property(srna, "panel", PROP_FLOAT, PROP_COLOR_GAMMA); +// RNA_def_property_array(prop, 3); +// RNA_def_property_ui_text(prop, "Panel", ""); +// RNA_def_property_update(prop, 0, "rna_userdef_update"); prop = RNA_def_property(srna, "window_sliders", PROP_FLOAT, PROP_COLOR_GAMMA); RNA_def_property_float_sdna(prop, NULL, "shade1"); @@ -1362,11 +1371,11 @@ static void rna_def_userdef_theme_space_file(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Selected File", ""); RNA_def_property_update(prop, 0, "rna_userdef_update"); - prop = RNA_def_property(srna, "tiles", PROP_FLOAT, PROP_COLOR_GAMMA); - RNA_def_property_float_sdna(prop, NULL, "panel"); - RNA_def_property_array(prop, 3); - RNA_def_property_ui_text(prop, "Tiles", ""); - RNA_def_property_update(prop, 0, "rna_userdef_update"); +// prop = RNA_def_property(srna, "tiles", PROP_FLOAT, PROP_COLOR_GAMMA); +// RNA_def_property_float_sdna(prop, NULL, "panel"); +// RNA_def_property_array(prop, 3); +// RNA_def_property_ui_text(prop, "Tiles", ""); +// RNA_def_property_update(prop, 0, "rna_userdef_update"); prop = RNA_def_property(srna, "scrollbar", PROP_FLOAT, PROP_COLOR_GAMMA); RNA_def_property_float_sdna(prop, NULL, "shade1"); @@ -1656,7 +1665,7 @@ static void rna_def_userdef_theme_space_node(BlenderRNA *brna) static void rna_def_userdef_theme_space_logic(BlenderRNA *brna) { StructRNA *srna; - PropertyRNA *prop; +// PropertyRNA *prop; /* space_logic */ @@ -1667,17 +1676,17 @@ static void rna_def_userdef_theme_space_logic(BlenderRNA *brna) rna_def_userdef_theme_spaces_main(srna); - prop = RNA_def_property(srna, "panel", PROP_FLOAT, PROP_COLOR_GAMMA); - RNA_def_property_array(prop, 3); - RNA_def_property_ui_text(prop, "Panel", ""); - RNA_def_property_update(prop, 0, "rna_userdef_update"); +// prop = RNA_def_property(srna, "panel", PROP_FLOAT, PROP_COLOR_GAMMA); +// RNA_def_property_array(prop, 3); +// RNA_def_property_ui_text(prop, "Panel", ""); +// RNA_def_property_update(prop, 0, "rna_userdef_update"); } static void rna_def_userdef_theme_space_buts(BlenderRNA *brna) { StructRNA *srna; - PropertyRNA *prop; +// PropertyRNA *prop; /* space_buts */ @@ -1688,10 +1697,10 @@ static void rna_def_userdef_theme_space_buts(BlenderRNA *brna) rna_def_userdef_theme_spaces_main(srna); - prop = RNA_def_property(srna, "panel", PROP_FLOAT, PROP_COLOR_GAMMA); - RNA_def_property_array(prop, 3); - RNA_def_property_ui_text(prop, "Panel", ""); - RNA_def_property_update(prop, 0, "rna_userdef_update"); +// prop = RNA_def_property(srna, "panel", PROP_FLOAT, PROP_COLOR_GAMMA); +// RNA_def_property_array(prop, 3); +// RNA_def_property_ui_text(prop, "Panel", ""); +// RNA_def_property_update(prop, 0, "rna_userdef_update"); } static void rna_def_userdef_theme_space_time(BlenderRNA *brna) From 722999e6d06250e0511ba1060c00227d3db668b0 Mon Sep 17 00:00:00 2001 From: Ton Roosendaal Date: Sat, 15 Dec 2012 16:27:12 +0000 Subject: [PATCH 155/252] Better tooltip for "Install Theme..." --- release/scripts/startup/bl_operators/wm.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/release/scripts/startup/bl_operators/wm.py b/release/scripts/startup/bl_operators/wm.py index 105b532ac38..c24e0920213 100644 --- a/release/scripts/startup/bl_operators/wm.py +++ b/release/scripts/startup/bl_operators/wm.py @@ -1620,7 +1620,7 @@ class WM_OT_addon_disable(Operator): class WM_OT_theme_install(Operator): - "Install a theme" + "Load and apply a Blender XML theme file" bl_idname = "wm.theme_install" bl_label = "Install Theme..." From 2681cc66a50f16c77c8ad46915a53640f65bb51f Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sat, 15 Dec 2012 16:31:25 +0000 Subject: [PATCH 156/252] minor edits with recent commits, also avoid calling BKE_mesh_from_object() in vertex paint, just pass the mesh. --- source/blender/blenkernel/BKE_bpath.h | 2 +- source/blender/blenkernel/BKE_pbvh.h | 4 ++-- source/blender/editors/sculpt_paint/paint_vertex.c | 5 ++--- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/source/blender/blenkernel/BKE_bpath.h b/source/blender/blenkernel/BKE_bpath.h index 7c350fdb03b..16a8b1be85b 100644 --- a/source/blender/blenkernel/BKE_bpath.h +++ b/source/blender/blenkernel/BKE_bpath.h @@ -26,7 +26,7 @@ */ /** \file BKE_bpath.h - * \ingroup bli + * \ingroup bke * \attention Based on ghash, difference is ghash is not a fixed size, * so for BPath we don't need to malloc */ diff --git a/source/blender/blenkernel/BKE_pbvh.h b/source/blender/blenkernel/BKE_pbvh.h index 59ecdb359c9..302de593963 100644 --- a/source/blender/blenkernel/BKE_pbvh.h +++ b/source/blender/blenkernel/BKE_pbvh.h @@ -21,8 +21,8 @@ #ifndef __BLI_PBVH_H__ #define __BLI_PBVH_H__ -/** \file BLI_pbvh.h - * \ingroup bli +/** \file BKE_pbvh.h + * \ingroup bke * \brief A BVH for high poly meshes. */ diff --git a/source/blender/editors/sculpt_paint/paint_vertex.c b/source/blender/editors/sculpt_paint/paint_vertex.c index 073aee1d974..a7d75c617be 100644 --- a/source/blender/editors/sculpt_paint/paint_vertex.c +++ b/source/blender/editors/sculpt_paint/paint_vertex.c @@ -2646,13 +2646,12 @@ static int vpaint_stroke_test_start(bContext *C, struct wmOperator *op, const fl return 1; } -static void vpaint_paint_poly(VPaint *vp, VPaintData *vpd, Object *ob, +static void vpaint_paint_poly(VPaint *vp, VPaintData *vpd, Mesh *me, const unsigned int index, const float mval[2], const float brush_size_pressure, const float brush_alpha_pressure) { ViewContext *vc = &vpd->vc; Brush *brush = paint_brush(&vp->paint); - Mesh *me = BKE_mesh_from_object(ob); MPoly *mpoly = &me->mpoly[index]; MFace *mf; MCol *mc; @@ -2786,7 +2785,7 @@ static void vpaint_stroke_update_step(bContext *C, struct PaintStroke *stroke, P for (index = 0; index < totindex; index++) { if (indexar[index] && indexar[index] <= me->totpoly) { - vpaint_paint_poly(vp, vpd, ob, indexar[index] - 1, mval, brush_size_pressure, brush_alpha_pressure); + vpaint_paint_poly(vp, vpd, me, indexar[index] - 1, mval, brush_size_pressure, brush_alpha_pressure); } } From 91c5f4a7b4f05db9a90e659bfb2a5d1c8fc7fd09 Mon Sep 17 00:00:00 2001 From: Ton Roosendaal Date: Sat, 15 Dec 2012 16:35:00 +0000 Subject: [PATCH 157/252] Cleanup: Removed unused panel colors (and panel text) from Themes. --- source/blender/editors/include/UI_resources.h | 6 ---- source/blender/makesrna/intern/rna_userdef.c | 31 ------------------- 2 files changed, 37 deletions(-) diff --git a/source/blender/editors/include/UI_resources.h b/source/blender/editors/include/UI_resources.h index dbbcc6953ed..eaab17c4137 100644 --- a/source/blender/editors/include/UI_resources.h +++ b/source/blender/editors/include/UI_resources.h @@ -64,18 +64,12 @@ enum { TH_HEADER_TEXT, TH_HEADER_TEXT_HI, - /* float panels */ - TH_PANEL, - TH_PANEL_TEXT, - TH_PANEL_TEXT_HI, - /* panels */ TH_PANEL_HEADER, TH_PANEL_BACK, TH_PANEL_SHOW_HEADER, TH_PANEL_SHOW_BACK, - TH_BUTBACK, TH_BUTBACK_TEXT, TH_BUTBACK_TEXT_HI, diff --git a/source/blender/makesrna/intern/rna_userdef.c b/source/blender/makesrna/intern/rna_userdef.c index c0467a43222..dd25958ffa8 100644 --- a/source/blender/makesrna/intern/rna_userdef.c +++ b/source/blender/makesrna/intern/rna_userdef.c @@ -504,13 +504,6 @@ static void rna_def_userdef_theme_ui_style(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Panel Zoom", "Default zoom level for panel areas"); #endif -// prop = RNA_def_property(srna, "panel_title", PROP_POINTER, PROP_NONE); -// RNA_def_property_flag(prop, PROP_NEVER_NULL); -// RNA_def_property_pointer_sdna(prop, NULL, "paneltitle"); -// RNA_def_property_struct_type(prop, "ThemeFontStyle"); -// RNA_def_property_ui_text(prop, "Panel Style", ""); -// RNA_def_property_update(prop, 0, "rna_userdef_update"); - /* (not used yet) */ #if 0 prop = RNA_def_property(srna, "group_label", PROP_POINTER, PROP_NONE); @@ -1125,11 +1118,6 @@ static void rna_def_userdef_theme_space_view3d(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Grid", ""); RNA_def_property_update(prop, 0, "rna_userdef_update"); -// prop = RNA_def_property(srna, "panel", PROP_FLOAT, PROP_COLOR_GAMMA); -// RNA_def_property_array(prop, 4); -// RNA_def_property_ui_text(prop, "Panel", ""); -// RNA_def_property_update(prop, 0, "rna_userdef_update"); - prop = RNA_def_property(srna, "wire", PROP_FLOAT, PROP_COLOR_GAMMA); RNA_def_property_array(prop, 3); RNA_def_property_ui_text(prop, "Wire", ""); @@ -1284,11 +1272,6 @@ static void rna_def_userdef_theme_space_graph(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Grid", ""); RNA_def_property_update(prop, 0, "rna_userdef_update"); -// prop = RNA_def_property(srna, "panel", PROP_FLOAT, PROP_COLOR_GAMMA); -// RNA_def_property_array(prop, 3); -// RNA_def_property_ui_text(prop, "Panel", ""); -// RNA_def_property_update(prop, 0, "rna_userdef_update"); - prop = RNA_def_property(srna, "window_sliders", PROP_FLOAT, PROP_COLOR_GAMMA); RNA_def_property_float_sdna(prop, NULL, "shade1"); RNA_def_property_array(prop, 3); @@ -1371,12 +1354,6 @@ static void rna_def_userdef_theme_space_file(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Selected File", ""); RNA_def_property_update(prop, 0, "rna_userdef_update"); -// prop = RNA_def_property(srna, "tiles", PROP_FLOAT, PROP_COLOR_GAMMA); -// RNA_def_property_float_sdna(prop, NULL, "panel"); -// RNA_def_property_array(prop, 3); -// RNA_def_property_ui_text(prop, "Tiles", ""); -// RNA_def_property_update(prop, 0, "rna_userdef_update"); - prop = RNA_def_property(srna, "scrollbar", PROP_FLOAT, PROP_COLOR_GAMMA); RNA_def_property_float_sdna(prop, NULL, "shade1"); RNA_def_property_array(prop, 3); @@ -1676,10 +1653,6 @@ static void rna_def_userdef_theme_space_logic(BlenderRNA *brna) rna_def_userdef_theme_spaces_main(srna); -// prop = RNA_def_property(srna, "panel", PROP_FLOAT, PROP_COLOR_GAMMA); -// RNA_def_property_array(prop, 3); -// RNA_def_property_ui_text(prop, "Panel", ""); -// RNA_def_property_update(prop, 0, "rna_userdef_update"); } @@ -1697,10 +1670,6 @@ static void rna_def_userdef_theme_space_buts(BlenderRNA *brna) rna_def_userdef_theme_spaces_main(srna); -// prop = RNA_def_property(srna, "panel", PROP_FLOAT, PROP_COLOR_GAMMA); -// RNA_def_property_array(prop, 3); -// RNA_def_property_ui_text(prop, "Panel", ""); -// RNA_def_property_update(prop, 0, "rna_userdef_update"); } static void rna_def_userdef_theme_space_time(BlenderRNA *brna) From 468a6aba62b800efee2ece74717dd25c25a44702 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Sat, 15 Dec 2012 17:15:42 +0000 Subject: [PATCH 158/252] Attempted fix #33546: GPU mipmap generation is not working on some ATI cards, causing textures to be missing in textured draw mode. There is apparently a bug in the ATI drivers, committed a workaround for that now. http://www.opengl.org/wiki/Common_Mistakes#Automatic_mipmap_generation --- source/blender/gpu/intern/gpu_draw.c | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/source/blender/gpu/intern/gpu_draw.c b/source/blender/gpu/intern/gpu_draw.c index f4810c540c3..88a9122e88c 100644 --- a/source/blender/gpu/intern/gpu_draw.c +++ b/source/blender/gpu/intern/gpu_draw.c @@ -252,6 +252,25 @@ void GPU_set_gpu_mipmapping(int gpu_mipmap) } } +static void gpu_generate_mipmap(GLenum target) +{ + int is_ati = GPU_type_matches(GPU_DEVICE_ATI, GPU_OS_ANY, GPU_DRIVER_ANY); + int target_enabled = 0; + + /* work around bug in ATI driver, need to have GL_TEXTURE_2D enabled + * http://www.opengl.org/wiki/Common_Mistakes#Automatic_mipmap_generation */ + if (is_ati) { + target_enabled = glIsEnabled(target); + if (!target_enabled) + glEnable(target); + } + + glGenerateMipmapEXT(target); + + if (is_ati && !target_enabled) + glDisable(target); +} + void GPU_set_mipmap(int mipmap) { if (GTS.domipmap != (mipmap != 0)) { @@ -691,7 +710,7 @@ void GPU_create_gl_tex(unsigned int *bind, unsigned int *pix, float * frect, int else glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, rectw, recth, 0, GL_RGBA, GL_UNSIGNED_BYTE, pix); - glGenerateMipmapEXT(GL_TEXTURE_2D); + gpu_generate_mipmap(GL_TEXTURE_2D); } else { if (use_high_bit_depth) @@ -934,7 +953,7 @@ void GPU_paint_update_image(Image *ima, int x, int y, int w, int h) /* we have already accounted for the case where GTS.gpu_mipmap is false * so we will be using GPU mipmap generation here */ if (GPU_get_mipmap()) { - glGenerateMipmapEXT(GL_TEXTURE_2D); + gpu_generate_mipmap(GL_TEXTURE_2D); } else { ima->tpageflag &= ~IMA_MIPMAP_COMPLETE; @@ -959,7 +978,7 @@ void GPU_paint_update_image(Image *ima, int x, int y, int w, int h) /* see comment above as to why we are using gpu mipmap generation here */ if (GPU_get_mipmap()) { - glGenerateMipmapEXT(GL_TEXTURE_2D); + gpu_generate_mipmap(GL_TEXTURE_2D); } else { ima->tpageflag &= ~IMA_MIPMAP_COMPLETE; From ce08127caf5dc833fa9e106eeb4c33c91488b20d Mon Sep 17 00:00:00 2001 From: Ton Roosendaal Date: Sat, 15 Dec 2012 18:12:38 +0000 Subject: [PATCH 159/252] Bugfix, IRC submitted: Color Pickers, square versions, didn't draw the 'cursor' correctly. Was missing colorprofile check. --- source/blender/editors/interface/interface_widgets.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/source/blender/editors/interface/interface_widgets.c b/source/blender/editors/interface/interface_widgets.c index 1d43d59da68..6d9df40f931 100644 --- a/source/blender/editors/interface/interface_widgets.c +++ b/source/blender/editors/interface/interface_widgets.c @@ -2141,10 +2141,18 @@ static void ui_draw_but_HSVCUBE(uiBut *but, const rcti *rect) float x = 0.0f, y = 0.0f; float *hsv = ui_block_hsv_get(but->block); float hsv_n[3]; + int color_profile = but->block->color_profile; + + if (but->rnaprop && RNA_property_subtype(but->rnaprop) == PROP_COLOR_GAMMA) + color_profile = FALSE; copy_v3_v3(hsv_n, hsv); ui_get_but_vectorf(but, rgb); + + if (color_profile && (int)but->a1 != UI_GRAD_SV) + ui_block_to_display_space_v3(but->block, rgb); + rgb_to_hsv_compat_v(rgb, hsv_n); ui_draw_gradient(rect, hsv_n, but->a1, 1.0f); From b0edc388562fd68bb1d6a556e6f48174ad237bc9 Mon Sep 17 00:00:00 2001 From: Jens Verwiebe Date: Sat, 15 Dec 2012 18:32:53 +0000 Subject: [PATCH 160/252] OSX: makeKeyAndOrderFront would show window from orderedWindows list on every loop, so use makeKeyWindow only to avoid flicker when closing app --- intern/ghost/intern/GHOST_WindowCocoa.mm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/intern/ghost/intern/GHOST_WindowCocoa.mm b/intern/ghost/intern/GHOST_WindowCocoa.mm index 792836b0a21..9f738c345f4 100644 --- a/intern/ghost/intern/GHOST_WindowCocoa.mm +++ b/intern/ghost/intern/GHOST_WindowCocoa.mm @@ -629,7 +629,7 @@ GHOST_WindowCocoa::~GHOST_WindowCocoa() NSArray *windowsList = [NSApp orderedWindows]; for (int a = 0; a < [windowsList count]; a++) { if (m_window != (CocoaWindow *)[windowsList objectAtIndex:a]) { - [[windowsList objectAtIndex:a] makeKeyAndOrderFront:nil]; + [[windowsList objectAtIndex:a] makeKeyWindow]; break; } } From 114459e7f68f97cf16748445d432a1b2e314f177 Mon Sep 17 00:00:00 2001 From: Ove Murberg Henriksen Date: Sat, 15 Dec 2012 19:56:25 +0000 Subject: [PATCH 161/252] Pure style cleanup. --- source/blender/editors/object/object_vgroup.c | 150 ++++++++++-------- 1 file changed, 81 insertions(+), 69 deletions(-) diff --git a/source/blender/editors/object/object_vgroup.c b/source/blender/editors/object/object_vgroup.c index dae95a1bffc..846e2acd9f2 100644 --- a/source/blender/editors/object/object_vgroup.c +++ b/source/blender/editors/object/object_vgroup.c @@ -400,26 +400,34 @@ typedef enum WT_ReplaceMode { } WT_ReplaceMode; static EnumPropertyItem WT_vertex_group_mode_item[] = { - {WT_REPLACE_ACTIVE_VERTEX_GROUP, "WT_REPLACE_ACTIVE_VERTEX_GROUP", 0, "Active", "Transfer active vertex group from selected to active mesh"}, - {WT_REPLACE_ALL_VERTEX_GROUPS, "WT_REPLACE_ALL_VERTEX_GROUPS", 0, "All", "Transfer all vertex groups from selected to active mesh"}, + {WT_REPLACE_ACTIVE_VERTEX_GROUP, + "WT_REPLACE_ACTIVE_VERTEX_GROUP", 0, "Active", "Transfer active vertex group from selected to active mesh"}, + {WT_REPLACE_ALL_VERTEX_GROUPS, + "WT_REPLACE_ALL_VERTEX_GROUPS", 0, "All", "Transfer all vertex groups from selected to active mesh"}, {0, NULL, 0, NULL, NULL} }; static EnumPropertyItem WT_method_item[] = { - {WT_BY_INDEX, "WT_BY_INDEX", 0, "Vertex index", "Copy for identical meshes"}, - {WT_BY_NEAREST_VERTEX, "WT_BY_NEAREST_VERTEX", 0, "Nearest vertex", "Copy weight from closest vertex"}, - {WT_BY_NEAREST_FACE, "WT_BY_NEAREST_FACE", 0, "Nearest face", "Barycentric interpolation from nearest face"}, - {WT_BY_NEAREST_VERTEX_IN_FACE, "WT_BY_NEAREST_VERTEX_IN_FACE", 0, "Nearest vertex in face", "Copy weight from closest vertex in nearest face"}, + {WT_BY_INDEX, + "WT_BY_INDEX", 0, "Vertex index", "Copy for identical meshes"}, + {WT_BY_NEAREST_VERTEX, + "WT_BY_NEAREST_VERTEX", 0, "Nearest vertex", "Copy weight from closest vertex"}, + {WT_BY_NEAREST_FACE, + "WT_BY_NEAREST_FACE", 0, "Nearest face", "Barycentric interpolation from nearest face"}, + {WT_BY_NEAREST_VERTEX_IN_FACE, + "WT_BY_NEAREST_VERTEX_IN_FACE", 0, "Nearest vertex in face", "Copy weight from closest vertex in nearest face"}, {0, NULL, 0, NULL, NULL} }; static EnumPropertyItem WT_replace_mode_item[] = { - {WT_REPLACE_ALL_WEIGHTS, "WT_REPLACE_ALL_WEIGHTS", 0, "All", "Overwrite all weights"}, - {WT_REPLACE_EMPTY_WEIGHTS, "WT_REPLACE_EMPTY_WEIGHTS", 0, "Empty", "Add weights to vertices with no weight"}, + {WT_REPLACE_ALL_WEIGHTS, + "WT_REPLACE_ALL_WEIGHTS", 0, "All", "Overwrite all weights"}, + {WT_REPLACE_EMPTY_WEIGHTS, + "WT_REPLACE_EMPTY_WEIGHTS", 0, "Empty", "Add weights to vertices with no weight"}, {0, NULL, 0, NULL, NULL} }; -/*copy weight*/ +/* Copy weight.*/ static void vgroup_transfer_weight(float *r_weight_dst, const float weight_src, const WT_ReplaceMode replace_mode) { switch (replace_mode) { @@ -439,7 +447,7 @@ static void vgroup_transfer_weight(float *r_weight_dst, const float weight_src, } } -/* could be exposed externally */ +/* Could be exposed externally */ static int ed_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGroup *dg_src, Scene *scene, WT_Method method, WT_ReplaceMode replace_mode, wmOperator *op) { @@ -457,53 +465,53 @@ static int ed_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGrou float weight, tmp_weight[4], tmp_co[3], normal[3], tmp_mat[4][4], dist_v1, dist_v2, dist_v3, dist_v4; const int use_vert_sel = vertex_group_use_vert_sel(ob_dst); - /* create new and overwrite vertex group on destination without data */ + /* Create new and overwrite vertex group on destination without data.*/ if (!defgroup_find_name(ob_dst, dg_src->name)) { ED_vgroup_delete(ob_dst, defgroup_find_name(ob_dst, dg_src->name)); ED_vgroup_add_name(ob_dst, dg_src->name); } - /* get destination deformgroup */ + /* Get destination deformgroup.*/ dg_dst = defgroup_find_name(ob_dst, dg_src->name); - /* get meshes */ + /* Get meshes.*/ dmesh_src = mesh_get_derived_deform(scene, ob_src, CD_MASK_BAREMESH); me_dst = ob_dst->data; me_src = ob_src->data; - /* sanity check */ + /* Sanity check.*/ if (!me_src->dvert) { BKE_report(op->reports, RPT_ERROR, "Transfer failed (source mesh does not have any vertex groups)"); return 0; } - /* create data in memory when nothing there */ + /* Create data in memory when nothing there.*/ if (!me_dst->dvert) ED_vgroup_data_create(ob_dst->data); - /* get vertex group arrays */ + /* Get vertex group arrays.*/ ED_vgroup_give_parray(ob_src->data, &dv_array_src, &dv_tot_src, FALSE); ED_vgroup_give_parray(ob_dst->data, &dv_array_dst, &dv_tot_dst, use_vert_sel); - /* get indexes of vertex groups */ + /* Get indexes of vertex groups.*/ index_src = BLI_findindex(&ob_src->defbase, dg_src); index_dst = BLI_findindex(&ob_dst->defbase, dg_dst); - /* get vertices */ + /* Get vertices.*/ mv_dst = me_dst->mvert; mv_src = dmesh_src->getVertArray(dmesh_src); - /* prepare transformation matrix */ + /* Prepare transformation matrix.*/ invert_m4_m4(ob_src->imat, ob_src->obmat); mult_m4_m4m4(tmp_mat, ob_src->imat, ob_dst->obmat); - /* clear weights */ + /* Clear weights.*/ if (replace_mode == WT_REPLACE_ALL_WEIGHTS) { for (i = 0, dv_dst = dv_array_dst; i < me_dst->totvert; i++, dv_dst++) { if (*dv_dst == NULL) continue; dw_dst = defvert_find_index(*dv_dst, index_dst); - /* remove vertex from group */ + /* Remove vertex from group.*/ if (dw_dst) defvert_remove_group(*dv_dst, dw_dst); } } @@ -511,7 +519,7 @@ static int ed_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGrou switch (method) { case WT_BY_INDEX: - /* check if indices are matching, delete and return if not */ + /* Check if indices are matching, delete and return if not.*/ if (ob_dst == ob_src || dv_tot_dst == 0 || dv_tot_dst != dv_tot_src || dv_array_src == NULL || dv_array_dst == NULL) { @@ -523,14 +531,15 @@ static int ed_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGrou return 0; } - /* loop through the vertices*/ - for (i = 0, dv_src = dv_array_src, dv_dst = dv_array_dst; i < me_dst->totvert; i++, dv_dst++, dv_src++, mv_src++, mv_dst++) { + /* Loop through the vertices.*/ + for (i = 0, dv_src = dv_array_src, dv_dst = dv_array_dst; i < me_dst->totvert; + i++, dv_dst++, dv_src++, mv_src++, mv_dst++) { if (*dv_dst == NULL) { continue; } - /* copy weight */ + /* Copy weight.*/ dw_src = defvert_find_index(*dv_src, index_src); if (dw_src && dw_src->weight) { dw_dst = defvert_verify_index(*dv_dst, index_dst); @@ -540,29 +549,30 @@ static int ed_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGrou break; case WT_BY_NEAREST_VERTEX: - /* make node tree */ + /* Make node tree.*/ bvhtree_from_mesh_verts(&tree_mesh_vertices_src, dmesh_src, FLT_EPSILON, 2, 6); - /* loop trough vertices */ + /* Loop trough vertices.*/ for (i = 0, dv_dst = dv_array_dst; i < me_dst->totvert; i++, dv_dst++, mv_dst++) { if (*dv_dst == NULL) { continue; } - /* reset nearest */ + /* Reset nearest.*/ nearest.dist = FLT_MAX; - /* with current binary tree its marginally faster to start searching at the top, as opposed to previous search. */ + /* It is faster to start searching at the top of the tree instead of previous search result.*/ nearest.index = -1; - /* transform into target space */ + /* Transform into target space.*/ mul_v3_m4v3(tmp_co, tmp_mat, mv_dst->co); - /* node tree accelerated search for closest vetex */ + /* Node tree accelerated search for closest vetex.*/ BLI_bvhtree_find_nearest(tree_mesh_vertices_src.tree, tmp_co, &nearest, tree_mesh_vertices_src.nearest_callback, &tree_mesh_vertices_src); - /* copy weight that are not NULL including weight value 0. Existing target weights are overwritten prior to this in relevant cases. */ + /* Copy weight that are not NULL including weight value 0. + * Existing target weights are overwritten prior to this in relevant cases.*/ dw_src = defvert_find_index(dv_array_src[nearest.index], index_src); if (dw_src && dw_src->weight) { dw_dst = defvert_verify_index(*dv_dst, index_dst); @@ -570,105 +580,108 @@ static int ed_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGrou } } - /* free memory */ + /* Free memory.*/ free_bvhtree_from_mesh(&tree_mesh_vertices_src); break; case WT_BY_NEAREST_FACE: - /* get faces */ + /* Get faces.*/ DM_ensure_tessface(dmesh_src); mface_src = dmesh_src->getTessFaceArray(dmesh_src); - /* make node tree */ + /* Make node tree.*/ bvhtree_from_mesh_faces(&tree_mesh_faces_src, dmesh_src, FLT_EPSILON, 2, 6); - /* loop through the vertices */ + /* Loop through the vertices.*/ for (i = 0, dv_dst = dv_array_dst; i < me_dst->totvert; i++, dv_dst++, mv_dst++) { if (*dv_dst == NULL) { continue; } - /* reset nearest */ + /* Reset nearest.*/ nearest.dist = FLT_MAX; - /* with current binary tree its marginally faster to start searching at the top, as opposed to previous search. */ + /* It is faster to start searching at the top of the tree instead of previous search result.*/ nearest.index = -1; - /* transform into target space */ + /* Transform into target space.*/ mul_v3_m4v3(tmp_co, tmp_mat, mv_dst->co); - /* node tree accelerated search for closest face */ + /* Node tree accelerated search for closest face.*/ BLI_bvhtree_find_nearest(tree_mesh_faces_src.tree, tmp_co, &nearest, tree_mesh_faces_src.nearest_callback, &tree_mesh_faces_src); index_nearest = nearest.index; - /* project onto face */ + /* Project onto face.*/ mf = &mface_src[index_nearest]; normal_tri_v3(normal, mv_src[mf->v1].co, mv_src[mf->v2].co, mv_src[mf->v3].co); project_v3_plane(tmp_co, normal, mv_src[mf->v1].co); - /* interpolate weights over face*/ + /* Interpolate weights over face.*/ f_index = mf->v4 ? 3 : 2; if (f_index == 3) { - interp_weights_face_v3(tmp_weight, mv_src[mf->v1].co, mv_src[mf->v2].co, mv_src[mf->v3].co, mv_src[mf->v4].co, tmp_co); + interp_weights_face_v3(tmp_weight, mv_src[mf->v1].co, mv_src[mf->v2].co, + mv_src[mf->v3].co, mv_src[mf->v4].co, tmp_co); } else { - interp_weights_face_v3(tmp_weight, mv_src[mf->v1].co, mv_src[mf->v2].co, mv_src[mf->v3].co, NULL, tmp_co); + interp_weights_face_v3(tmp_weight, mv_src[mf->v1].co, mv_src[mf->v2].co, + mv_src[mf->v3].co, NULL, tmp_co); } - /* get weights from face*/ + /* Get weights from face.*/ weight = 0; do { v_index = (&mf->v1)[f_index]; weight += tmp_weight[f_index] * defvert_find_weight(dv_array_src[v_index], index_src); } while (f_index--); - /* copy weight that are not NULL including weight value 0. Existing target weights are overwritten prior to this in relevant cases. */ + /* Copy weight that are not NULL including weight value 0. + * Existing target weights are overwritten prior to this in relevant cases.*/ if (weight > 0) { dw_dst = defvert_verify_index(*dv_dst, index_dst); vgroup_transfer_weight(&dw_dst->weight, weight, replace_mode); } } - /* free memory */ + /* Free memory.*/ free_bvhtree_from_mesh(&tree_mesh_faces_src); break; case WT_BY_NEAREST_VERTEX_IN_FACE: - /* get faces */ + /* Get faces.*/ DM_ensure_tessface(dmesh_src); mface_src = dmesh_src->getTessFaceArray(dmesh_src); - /* make node tree */ + /* Make node tree.*/ bvhtree_from_mesh_faces(&tree_mesh_faces_src, dmesh_src, FLT_EPSILON, 2, 6); - /* loop through the vertices */ + /* Loop through the vertices.*/ for (i = 0, dv_dst = dv_array_dst; i < me_dst->totvert; i++, dv_dst++, mv_dst++) { if (*dv_dst == NULL) { continue; } - /* reset nearest */ + /* Reset nearest.*/ nearest.dist = FLT_MAX; - /* With current binary tree its marginally faster to start searching at the top, as opposed to previous search. */ + /* It is faster to start searching at the top of the tree instead of previous search result.*/ nearest.index = -1; - /* transform into target space */ + /* Transform into target space.*/ mul_v3_m4v3(tmp_co, tmp_mat, mv_dst->co); - /* node tree accelerated search for closest face */ + /* Node tree accelerated search for closest face.*/ BLI_bvhtree_find_nearest(tree_mesh_faces_src.tree, tmp_co, &nearest, tree_mesh_faces_src.nearest_callback, &tree_mesh_faces_src); index_nearest = nearest.index; - /* get distances */ + /* Get distances.*/ mf = &mface_src[index_nearest]; dist_v1 = len_squared_v3v3(tmp_co, mv_src[mf->v1].co); dist_v2 = len_squared_v3v3(tmp_co, mv_src[mf->v2].co); dist_v3 = len_squared_v3v3(tmp_co, mv_src[mf->v3].co); - /* get closest vertex */ + /* Get closest vertex.*/ f_index = mf->v4 ? 3 : 2; if (dist_v1 < dist_v2 && dist_v1 < dist_v3) index_nearest_vertex = mf->v1; else if (dist_v2 < dist_v3) index_nearest_vertex = mf->v2; @@ -680,7 +693,8 @@ static int ed_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGrou } } - /* copy weight that are not NULL including weight value 0. Existing target weights are overwritten prior to this in relevant cases. */ + /* Copy weight that are not NULL including weight value 0. + * Existing target weights are overwritten prior to this in relevant cases.*/ dw_src = defvert_find_index(dv_array_src[index_nearest_vertex], index_src); if (dw_src && dw_src->weight) { dw_dst = defvert_verify_index(*dv_dst, index_dst); @@ -688,7 +702,7 @@ static int ed_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGrou } } - /* free memory */ + /* Free memory.*/ free_bvhtree_from_mesh(&tree_mesh_faces_src); break; @@ -697,7 +711,7 @@ static int ed_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGrou break; } - /*free memory*/ + /* Free memory.*/ if (dv_array_src) MEM_freeN(dv_array_src); if (dv_array_dst) MEM_freeN(dv_array_dst); dmesh_src->release(dmesh_src); @@ -3288,7 +3302,7 @@ static int vertex_group_transfer_weight_exec(bContext *C, wmOperator *op) WT_Method method = RNA_enum_get(op->ptr, "WT_method"); WT_ReplaceMode replace_mode = RNA_enum_get(op->ptr, "WT_replace_mode"); - /* Macro to loop through selected objects and perform operation depending on function, option and method */ + /* Macro to loop through selected objects and perform operation depending on function, option and method.*/ CTX_DATA_BEGIN (C, Object *, ob_slc, selected_editable_objects) { @@ -3296,8 +3310,7 @@ static int vertex_group_transfer_weight_exec(bContext *C, wmOperator *op) switch (vertex_group_mode) { case WT_REPLACE_ACTIVE_VERTEX_GROUP: - if (!ed_vgroup_transfer_weight(ob_act, ob_slc, - BLI_findlink(&ob_slc->defbase, ob_slc->actdef - 1), + if (!ed_vgroup_transfer_weight(ob_act, ob_slc, BLI_findlink(&ob_slc->defbase, ob_slc->actdef - 1), scene, method, replace_mode, op)) { fail++; @@ -3306,8 +3319,7 @@ static int vertex_group_transfer_weight_exec(bContext *C, wmOperator *op) case WT_REPLACE_ALL_VERTEX_GROUPS: for (dg_src = ob_slc->defbase.first; dg_src; dg_src = dg_src->next) { - if (!ed_vgroup_transfer_weight(ob_act, ob_slc, - dg_src, scene, method, replace_mode, op)) + if (!ed_vgroup_transfer_weight(ob_act, ob_slc, dg_src, scene, method, replace_mode, op)) { fail++; } @@ -3321,7 +3333,7 @@ static int vertex_group_transfer_weight_exec(bContext *C, wmOperator *op) } } - /* Event notifiers for correct display of data */ + /* Event notifiers for correct display of data.*/ DAG_id_tag_update(&ob_slc->id, OB_RECALC_DATA); WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob_slc); WM_event_add_notifier(C, NC_GEOM | ND_DATA, ob_slc->data); @@ -3339,19 +3351,19 @@ static int vertex_group_transfer_weight_exec(bContext *C, wmOperator *op) /* transfers weight from active to selected */ void OBJECT_OT_vertex_group_transfer_weight(wmOperatorType *ot) { - /* identifiers */ + /* Identifiers.*/ ot->name = "Transfer Weights"; ot->idname = "OBJECT_OT_vertex_group_transfer_weight"; ot->description = "Transfer weight paint to active from selected mesh"; - /* api callbacks */ + /* API callbacks.*/ ot->poll = vertex_group_poll; ot->exec = vertex_group_transfer_weight_exec; - /* flags */ + /* Flags.*/ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; - /* properties */ + /* Properties.*/ ot->prop = RNA_def_enum(ot->srna, "WT_vertex_group_mode", WT_vertex_group_mode_item, 1, "Group", ""); ot->prop = RNA_def_enum(ot->srna, "WT_method", WT_method_item, 3, "Method", ""); ot->prop = RNA_def_enum(ot->srna, "WT_replace_mode", WT_replace_mode_item, 1, "Replace", ""); From 0ac1424264248a260ffc77a1b0febe1ee46331fe Mon Sep 17 00:00:00 2001 From: Ove Murberg Henriksen Date: Sat, 15 Dec 2012 20:32:32 +0000 Subject: [PATCH 162/252] Bugfix: [#33513] Transfer weights mixing up. Removal of this line fixed the bug. But! I suspect it opens up for an excaption. I will try to identify the exception and handle it in a different way. --- source/blender/editors/object/object_vgroup.c | 1 - 1 file changed, 1 deletion(-) diff --git a/source/blender/editors/object/object_vgroup.c b/source/blender/editors/object/object_vgroup.c index 846e2acd9f2..a0a27a565ee 100644 --- a/source/blender/editors/object/object_vgroup.c +++ b/source/blender/editors/object/object_vgroup.c @@ -467,7 +467,6 @@ static int ed_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGrou /* Create new and overwrite vertex group on destination without data.*/ if (!defgroup_find_name(ob_dst, dg_src->name)) { - ED_vgroup_delete(ob_dst, defgroup_find_name(ob_dst, dg_src->name)); ED_vgroup_add_name(ob_dst, dg_src->name); } From caf2324d56da9ce69de7a37dfb3aa91e55de2ebb Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Sat, 15 Dec 2012 20:43:25 +0000 Subject: [PATCH 163/252] Fix cycles build error with OSL disabled. --- intern/cycles/kernel/kernel_shader.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/intern/cycles/kernel/kernel_shader.h b/intern/cycles/kernel/kernel_shader.h index 9bbfe6b0cc5..47b4d02e5bf 100644 --- a/intern/cycles/kernel/kernel_shader.h +++ b/intern/cycles/kernel/kernel_shader.h @@ -752,7 +752,11 @@ __device void shader_merge_closures(KernelGlobals *kg, ShaderData *sd) for(int j = i + 1; j < sd->num_closure; j++) { ShaderClosure *scj = &sd->closure[j]; +#ifdef __OSL__ if(!sci->prim && sci->type == scj->type && sci->data0 == scj->data0 && sci->data1 == scj->data1) { +#else + if(sci->type == scj->type && sci->data0 == scj->data0 && sci->data1 == scj->data1) { +#endif sci->weight += scj->weight; sci->sample_weight += scj->sample_weight; From 8ec289739e1d4066ed24b98c3daa0c665550c1f3 Mon Sep 17 00:00:00 2001 From: Ove Murberg Henriksen Date: Sat, 15 Dec 2012 22:47:57 +0000 Subject: [PATCH 164/252] Changed some comments to make more sense. --- source/blender/editors/object/object_vgroup.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/source/blender/editors/object/object_vgroup.c b/source/blender/editors/object/object_vgroup.c index a0a27a565ee..c233611faab 100644 --- a/source/blender/editors/object/object_vgroup.c +++ b/source/blender/editors/object/object_vgroup.c @@ -465,7 +465,7 @@ static int ed_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGrou float weight, tmp_weight[4], tmp_co[3], normal[3], tmp_mat[4][4], dist_v1, dist_v2, dist_v3, dist_v4; const int use_vert_sel = vertex_group_use_vert_sel(ob_dst); - /* Create new and overwrite vertex group on destination without data.*/ + /* Ensure vertex group on target.*/ if (!defgroup_find_name(ob_dst, dg_src->name)) { ED_vgroup_add_name(ob_dst, dg_src->name); } @@ -570,8 +570,8 @@ static int ed_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGrou BLI_bvhtree_find_nearest(tree_mesh_vertices_src.tree, tmp_co, &nearest, tree_mesh_vertices_src.nearest_callback, &tree_mesh_vertices_src); - /* Copy weight that are not NULL including weight value 0. - * Existing target weights are overwritten prior to this in relevant cases.*/ + /* Copy weight that are not NULL including weight value 0. In relevant cases, existing weights are + * overwritten prior to this. See the "Clear weights." step above.*/ dw_src = defvert_find_index(dv_array_src[nearest.index], index_src); if (dw_src && dw_src->weight) { dw_dst = defvert_verify_index(*dv_dst, index_dst); @@ -634,8 +634,8 @@ static int ed_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGrou weight += tmp_weight[f_index] * defvert_find_weight(dv_array_src[v_index], index_src); } while (f_index--); - /* Copy weight that are not NULL including weight value 0. - * Existing target weights are overwritten prior to this in relevant cases.*/ + /* Copy weight that are not NULL including weight value 0. In relevant cases, existing weights are + * overwritten prior to this. See the "Clear weights." step above.*/ if (weight > 0) { dw_dst = defvert_verify_index(*dv_dst, index_dst); vgroup_transfer_weight(&dw_dst->weight, weight, replace_mode); @@ -692,8 +692,8 @@ static int ed_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGrou } } - /* Copy weight that are not NULL including weight value 0. - * Existing target weights are overwritten prior to this in relevant cases.*/ + /* Copy weight that are not NULL including weight value 0. In relevant cases, existing weights are + * overwritten prior to this. See the "Clear weights." step above.*/ dw_src = defvert_find_index(dv_array_src[index_nearest_vertex], index_src); if (dw_src && dw_src->weight) { dw_dst = defvert_verify_index(*dv_dst, index_dst); From a837d9a8960ed5ec8ff1eb179d52f329a549c56f Mon Sep 17 00:00:00 2001 From: Ove Murberg Henriksen Date: Sat, 15 Dec 2012 23:52:39 +0000 Subject: [PATCH 165/252] Fixing name of a function to be consistent with the rest of the code. --- source/blender/editors/object/object_vgroup.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/source/blender/editors/object/object_vgroup.c b/source/blender/editors/object/object_vgroup.c index c233611faab..44d1ccf99ed 100644 --- a/source/blender/editors/object/object_vgroup.c +++ b/source/blender/editors/object/object_vgroup.c @@ -448,7 +448,7 @@ static void vgroup_transfer_weight(float *r_weight_dst, const float weight_src, } /* Could be exposed externally */ -static int ed_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGroup *dg_src, Scene *scene, +static int ED_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGroup *dg_src, Scene *scene, WT_Method method, WT_ReplaceMode replace_mode, wmOperator *op) { bDeformGroup *dg_dst; @@ -3309,7 +3309,7 @@ static int vertex_group_transfer_weight_exec(bContext *C, wmOperator *op) switch (vertex_group_mode) { case WT_REPLACE_ACTIVE_VERTEX_GROUP: - if (!ed_vgroup_transfer_weight(ob_act, ob_slc, BLI_findlink(&ob_slc->defbase, ob_slc->actdef - 1), + if (!ED_vgroup_transfer_weight(ob_act, ob_slc, BLI_findlink(&ob_slc->defbase, ob_slc->actdef - 1), scene, method, replace_mode, op)) { fail++; @@ -3318,7 +3318,7 @@ static int vertex_group_transfer_weight_exec(bContext *C, wmOperator *op) case WT_REPLACE_ALL_VERTEX_GROUPS: for (dg_src = ob_slc->defbase.first; dg_src; dg_src = dg_src->next) { - if (!ed_vgroup_transfer_weight(ob_act, ob_slc, dg_src, scene, method, replace_mode, op)) + if (!ED_vgroup_transfer_weight(ob_act, ob_slc, dg_src, scene, method, replace_mode, op)) { fail++; } From 635099fdbca54f861d9cf121fe12d5c6bfa66295 Mon Sep 17 00:00:00 2001 From: Ove Murberg Henriksen Date: Sun, 16 Dec 2012 02:29:46 +0000 Subject: [PATCH 166/252] Reverting rev 53044 because it broke something and was wrong. I also added comment to avoid this happening in the future. --- source/blender/editors/object/object_vgroup.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/source/blender/editors/object/object_vgroup.c b/source/blender/editors/object/object_vgroup.c index 44d1ccf99ed..69e843ec706 100644 --- a/source/blender/editors/object/object_vgroup.c +++ b/source/blender/editors/object/object_vgroup.c @@ -447,8 +447,10 @@ static void vgroup_transfer_weight(float *r_weight_dst, const float weight_src, } } -/* Could be exposed externally */ -static int ED_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGroup *dg_src, Scene *scene, +/* Could be exposed externally by implementing it in header with the rest. + * Simple refactoring will break something. + * For now, naming is ed_ instead of ED_*/ +static int ed_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGroup *dg_src, Scene *scene, WT_Method method, WT_ReplaceMode replace_mode, wmOperator *op) { bDeformGroup *dg_dst; @@ -3309,7 +3311,7 @@ static int vertex_group_transfer_weight_exec(bContext *C, wmOperator *op) switch (vertex_group_mode) { case WT_REPLACE_ACTIVE_VERTEX_GROUP: - if (!ED_vgroup_transfer_weight(ob_act, ob_slc, BLI_findlink(&ob_slc->defbase, ob_slc->actdef - 1), + if (!ed_vgroup_transfer_weight(ob_act, ob_slc, BLI_findlink(&ob_slc->defbase, ob_slc->actdef - 1), scene, method, replace_mode, op)) { fail++; @@ -3318,7 +3320,7 @@ static int vertex_group_transfer_weight_exec(bContext *C, wmOperator *op) case WT_REPLACE_ALL_VERTEX_GROUPS: for (dg_src = ob_slc->defbase.first; dg_src; dg_src = dg_src->next) { - if (!ED_vgroup_transfer_weight(ob_act, ob_slc, dg_src, scene, method, replace_mode, op)) + if (!ed_vgroup_transfer_weight(ob_act, ob_slc, dg_src, scene, method, replace_mode, op)) { fail++; } From 48935ac3b5ad1c11b6492018cff50eb97cb28cfb Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sun, 16 Dec 2012 02:53:28 +0000 Subject: [PATCH 167/252] error in 53006, moved into another keymap rather then just re-ordering. --- source/blender/editors/space_view3d/view3d_ops.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/source/blender/editors/space_view3d/view3d_ops.c b/source/blender/editors/space_view3d/view3d_ops.c index fb9bfc4a7d9..ce05bbf7b0f 100644 --- a/source/blender/editors/space_view3d/view3d_ops.c +++ b/source/blender/editors/space_view3d/view3d_ops.c @@ -188,7 +188,13 @@ void view3d_keymap(wmKeyConfig *keyconf) wmKeyMapItem *kmi; keymap = WM_keymap_find(keyconf, "3D View Generic", SPACE_VIEW3D, 0); + + WM_keymap_add_item(keymap, "VIEW3D_OT_properties", NKEY, KM_PRESS, 0, 0); + WM_keymap_add_item(keymap, "VIEW3D_OT_toolshelf", TKEY, KM_PRESS, 0, 0); + /* only for region 3D window */ + keymap = WM_keymap_find(keyconf, "3D View", SPACE_VIEW3D, 0); + /* 3D mouse align */ /* note: positioned here so keymaps show keyboard keys if assigned */ kmi = WM_keymap_add_item(keymap, "VIEW3D_OT_viewnumpad", NDOF_BUTTON_FRONT, KM_PRESS, KM_SHIFT, 0); @@ -201,12 +207,6 @@ void view3d_keymap(wmKeyConfig *keyconf) RNA_enum_set(kmi->ptr, "type", RV3D_VIEW_TOP); RNA_boolean_set(kmi->ptr, "align_active", TRUE); - WM_keymap_add_item(keymap, "VIEW3D_OT_properties", NKEY, KM_PRESS, 0, 0); - WM_keymap_add_item(keymap, "VIEW3D_OT_toolshelf", TKEY, KM_PRESS, 0, 0); - - /* only for region 3D window */ - keymap = WM_keymap_find(keyconf, "3D View", SPACE_VIEW3D, 0); - kmi = WM_keymap_verify_item(keymap, "VIEW3D_OT_manipulator", LEFTMOUSE, KM_PRESS, KM_ANY, 0); RNA_boolean_set(kmi->ptr, "release_confirm", TRUE); /* From 1886ae38b4240a7a25c8256c70b794932d45a667 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sun, 16 Dec 2012 04:05:16 +0000 Subject: [PATCH 168/252] add Matrix.normalized(), handy for transforming normals. --- .../python/mathutils/mathutils_Matrix.c | 49 +++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/source/blender/python/mathutils/mathutils_Matrix.c b/source/blender/python/mathutils/mathutils_Matrix.c index 05306f230d1..44f06fe4eda 100644 --- a/source/blender/python/mathutils/mathutils_Matrix.c +++ b/source/blender/python/mathutils/mathutils_Matrix.c @@ -1533,6 +1533,53 @@ static PyObject *Matrix_transposed(MatrixObject *self) return matrix__apply_to_copy((PyNoArgsFunction)Matrix_transpose, self); } +/*---------------------------matrix.normalize() ------------------*/ +PyDoc_STRVAR(Matrix_normalize_doc, +".. method:: normalize()\n" +"\n" +" Normalize each of the columns of the matrix (useful for transforming unit length normals).\n" +); +static PyObject *Matrix_normalize(MatrixObject *self) +{ + if (BaseMath_ReadCallback(self) == -1) + return NULL; + + if (self->num_col != self->num_row) { + PyErr_SetString(PyExc_ValueError, + "Matrix.normalize(): " + "only square matrices are supported"); + return NULL; + } + + if (self->num_col == 3) { + normalize_m3((float (*)[3])self->matrix); + } + else if (self->num_col == 4) { + normalize_m4((float (*)[4])self->matrix); + } + else { + PyErr_SetString(PyExc_ValueError, + "Matrix.normalize(): " + "can only use a 3x3 or 4x4 matrix"); + } + + (void)BaseMath_WriteCallback(self); + Py_RETURN_NONE; +} + +PyDoc_STRVAR(Matrix_normalized_doc, +".. method:: normalized()\n" +"\n" +" Return a row normalized matrix\n" +"\n" +" :return: a row normalized matrix\n" +" :rtype: :class:`Matrix`\n" +); +static PyObject *Matrix_normalized(MatrixObject *self) +{ + return matrix__apply_to_copy((PyNoArgsFunction)Matrix_normalize, self); +} + /*---------------------------matrix.zero() -----------------------*/ PyDoc_STRVAR(Matrix_zero_doc, ".. method:: zero()\n" @@ -2371,6 +2418,8 @@ static struct PyMethodDef Matrix_methods[] = { /* operate on original or copy */ {"transpose", (PyCFunction) Matrix_transpose, METH_NOARGS, Matrix_transpose_doc}, {"transposed", (PyCFunction) Matrix_transposed, METH_NOARGS, Matrix_transposed_doc}, + {"normalize", (PyCFunction) Matrix_normalize, METH_NOARGS, Matrix_normalize_doc}, + {"normalized", (PyCFunction) Matrix_normalized, METH_NOARGS, Matrix_normalized_doc}, {"invert", (PyCFunction) Matrix_invert, METH_NOARGS, Matrix_invert_doc}, {"inverted", (PyCFunction) Matrix_inverted, METH_NOARGS, Matrix_inverted_doc}, {"adjugate", (PyCFunction) Matrix_adjugate, METH_NOARGS, Matrix_adjugate_doc}, From 950fb66c38e65cdc4177dd5aa0800a105f46c304 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sun, 16 Dec 2012 04:10:57 +0000 Subject: [PATCH 169/252] replace TypeError with Value error for matrix operations where the type is right but it can't succeed because of a property of the instance (normally the wrong col/row size). --- .../python/mathutils/mathutils_Matrix.c | 38 +++++++++---------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/source/blender/python/mathutils/mathutils_Matrix.c b/source/blender/python/mathutils/mathutils_Matrix.c index 44f06fe4eda..e64853fd8f5 100644 --- a/source/blender/python/mathutils/mathutils_Matrix.c +++ b/source/blender/python/mathutils/mathutils_Matrix.c @@ -1025,13 +1025,13 @@ static PyObject *Matrix_resize_4x4(MatrixObject *self) int col; if (self->wrapped == Py_WRAP) { - PyErr_SetString(PyExc_TypeError, + PyErr_SetString(PyExc_ValueError, "Matrix.resize_4x4(): " "cannot resize wrapped data - make a copy and resize that"); return NULL; } if (self->cb_user) { - PyErr_SetString(PyExc_TypeError, + PyErr_SetString(PyExc_ValueError, "Matrix.resize_4x4(): " "cannot resize owned data - make a copy and resize that"); return NULL; @@ -1080,7 +1080,7 @@ static PyObject *Matrix_to_4x4(MatrixObject *self) } /* TODO, 2x2 matrix */ - PyErr_SetString(PyExc_TypeError, + PyErr_SetString(PyExc_ValueError, "Matrix.to_4x4(): " "inappropriate matrix size"); return NULL; @@ -1102,7 +1102,7 @@ static PyObject *Matrix_to_3x3(MatrixObject *self) return NULL; if ((self->num_row < 3) || (self->num_col < 3)) { - PyErr_SetString(PyExc_TypeError, + PyErr_SetString(PyExc_ValueError, "Matrix.to_3x3(): inappropriate matrix size"); return NULL; } @@ -1126,7 +1126,7 @@ static PyObject *Matrix_to_translation(MatrixObject *self) return NULL; if ((self->num_row < 3) || self->num_col < 4) { - PyErr_SetString(PyExc_TypeError, + PyErr_SetString(PyExc_ValueError, "Matrix.to_translation(): " "inappropriate matrix size"); return NULL; @@ -1156,7 +1156,7 @@ static PyObject *Matrix_to_scale(MatrixObject *self) /*must be 3-4 cols, 3-4 rows, square matrix */ if ((self->num_row < 3) || (self->num_col < 3)) { - PyErr_SetString(PyExc_TypeError, + PyErr_SetString(PyExc_ValueError, "Matrix.to_scale(): " "inappropriate matrix size, 3x3 minimum size"); return NULL; @@ -1194,7 +1194,7 @@ static PyObject *Matrix_invert(MatrixObject *self) return NULL; if (self->num_col != self->num_row) { - PyErr_SetString(PyExc_TypeError, + PyErr_SetString(PyExc_ValueError, "Matrix.invert(ed): " "only square matrices are supported"); return NULL; @@ -1222,7 +1222,7 @@ static PyObject *Matrix_invert(MatrixObject *self) break; } default: - PyErr_Format(PyExc_TypeError, + PyErr_Format(PyExc_ValueError, "Matrix invert(ed): size (%d) unsupported", (int)self->num_col); return NULL; @@ -1281,7 +1281,7 @@ static PyObject *Matrix_adjugate(MatrixObject *self) return NULL; if (self->num_col != self->num_row) { - PyErr_SetString(PyExc_TypeError, + PyErr_SetString(PyExc_ValueError, "Matrix.adjugate(d): " "only square matrices are supported"); return NULL; @@ -1311,7 +1311,7 @@ static PyObject *Matrix_adjugate(MatrixObject *self) break; } default: - PyErr_Format(PyExc_TypeError, + PyErr_Format(PyExc_ValueError, "Matrix adjugate(d): size (%d) unsupported", (int)self->num_col); return NULL; @@ -1357,7 +1357,7 @@ static PyObject *Matrix_rotate(MatrixObject *self, PyObject *value) return NULL; if (self->num_row != 3 || self->num_col != 3) { - PyErr_SetString(PyExc_TypeError, + PyErr_SetString(PyExc_ValueError, "Matrix.rotate(): " "must have 3x3 dimensions"); return NULL; @@ -1390,7 +1390,7 @@ static PyObject *Matrix_decompose(MatrixObject *self) float size[3]; if (self->num_row != 4 || self->num_col != 4) { - PyErr_SetString(PyExc_TypeError, + PyErr_SetString(PyExc_ValueError, "Matrix.decompose(): " "inappropriate matrix size - expects 4x4 matrix"); return NULL; @@ -1476,7 +1476,7 @@ static PyObject *Matrix_determinant(MatrixObject *self) return NULL; if (self->num_col != self->num_row) { - PyErr_SetString(PyExc_TypeError, + PyErr_SetString(PyExc_ValueError, "Matrix.determinant(): " "only square matrices are supported"); return NULL; @@ -1498,7 +1498,7 @@ static PyObject *Matrix_transpose(MatrixObject *self) return NULL; if (self->num_col != self->num_row) { - PyErr_SetString(PyExc_TypeError, + PyErr_SetString(PyExc_ValueError, "Matrix.transpose(d): " "only square matrices are supported"); return NULL; @@ -1570,9 +1570,9 @@ static PyObject *Matrix_normalize(MatrixObject *self) PyDoc_STRVAR(Matrix_normalized_doc, ".. method:: normalized()\n" "\n" -" Return a row normalized matrix\n" +" Return a column normalized matrix\n" "\n" -" :return: a row normalized matrix\n" +" :return: a column normalized matrix\n" " :rtype: :class:`Matrix`\n" ); static PyObject *Matrix_normalized(MatrixObject *self) @@ -1615,7 +1615,7 @@ static PyObject *Matrix_identity(MatrixObject *self) return NULL; if (self->num_col != self->num_row) { - PyErr_SetString(PyExc_TypeError, + PyErr_SetString(PyExc_ValueError, "Matrix.identity(): " "only square matrices are supported"); return NULL; @@ -1971,7 +1971,7 @@ static PyObject *Matrix_add(PyObject *m1, PyObject *m2) return NULL; if (mat1->num_col != mat2->num_col || mat1->num_row != mat2->num_row) { - PyErr_SetString(PyExc_TypeError, + PyErr_SetString(PyExc_ValueError, "Matrix addition: " "matrices must have the same dimensions for this operation"); return NULL; @@ -2003,7 +2003,7 @@ static PyObject *Matrix_sub(PyObject *m1, PyObject *m2) return NULL; if (mat1->num_col != mat2->num_col || mat1->num_row != mat2->num_row) { - PyErr_SetString(PyExc_TypeError, + PyErr_SetString(PyExc_ValueError, "Matrix addition: " "matrices must have the same dimensions for this operation"); return NULL; From 5310961523faa34a6ef2fe08ff2984a3cab97f67 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sun, 16 Dec 2012 05:48:27 +0000 Subject: [PATCH 170/252] update themes --- .../presets/interface_theme/back_to_black.xml | 131 ++++++++++++++++-- .../presets/interface_theme/blender_24x.xml | 131 ++++++++++++++++-- .../presets/interface_theme/elsyiun.xml | 131 ++++++++++++++++-- .../presets/interface_theme/hexagon.xml | 131 ++++++++++++++++-- .../interface_theme/ubuntu_ambiance.xml | 131 ++++++++++++++++-- 5 files changed, 605 insertions(+), 50 deletions(-) diff --git a/release/scripts/presets/interface_theme/back_to_black.xml b/release/scripts/presets/interface_theme/back_to_black.xml index ff0a36da3a5..18a3e539738 100644 --- a/release/scripts/presets/interface_theme/back_to_black.xml +++ b/release/scripts/presets/interface_theme/back_to_black.xml @@ -220,16 +220,10 @@ blend="0.1"> - - - - + + + + + + + + @@ -348,7 +355,6 @@ + + + + @@ -404,6 +417,13 @@ button_title="#c3c3c3" button_text="#c3c3c3" button_text_hi="#ffffff"> + + + + @@ -441,6 +461,13 @@ button_title="#c5c5c5" button_text="#c3c3c3" button_text_hi="#ffffff"> + + + + @@ -480,6 +507,13 @@ button_title="#c5c5c5" button_text="#c3c3c3" button_text_hi="#ffffff"> + + + + @@ -511,12 +545,19 @@ button_title="#bdbdbd" button_text="#dddddd" button_text_hi="#ffffff"> + + + + - + + + + + @@ -554,6 +602,13 @@ button_title="#d8d8d8" button_text="#cccccc" button_text_hi="#ffffff"> + + + + @@ -573,6 +628,13 @@ button_title="#c5c5c5" button_text="#c3c3c3" button_text_hi="#ffffff"> + + + + @@ -602,6 +664,13 @@ button_title="#c5c5c5" button_text="#c3c3c3" button_text_hi="#ffffff"> + + + + @@ -614,7 +683,7 @@ - + + + + + @@ -646,6 +722,13 @@ button_title="#c5c5c5" button_text="#c3c3c3" button_text_hi="#ffffff"> + + + + @@ -664,6 +747,13 @@ button_title="#c5c5c5" button_text="#c3c3c3" button_text_hi="#ffffff"> + + + + @@ -682,6 +772,13 @@ button_title="#c5c5c5" button_text="#c3c3c3" button_text_hi="#ffffff"> + + + + @@ -704,6 +801,13 @@ button_title="#c5c5c5" button_text="#c3c3c3" button_text_hi="#ffffff"> + + + + @@ -736,6 +840,13 @@ button_title="#c5c5c5" button_text="#c3c3c3" button_text_hi="#ffffff"> + + + + diff --git a/release/scripts/presets/interface_theme/blender_24x.xml b/release/scripts/presets/interface_theme/blender_24x.xml index f26f66af816..5ad7c502cc7 100644 --- a/release/scripts/presets/interface_theme/blender_24x.xml +++ b/release/scripts/presets/interface_theme/blender_24x.xml @@ -220,16 +220,10 @@ blend="0.5"> - - - - + + + + + + + + @@ -348,7 +355,6 @@ + + + + @@ -404,6 +417,13 @@ button_title="#000000" button_text="#000000" button_text_hi="#ffffff"> + + + + @@ -441,6 +461,13 @@ button_title="#000000" button_text="#000000" button_text_hi="#ffffff"> + + + + @@ -480,6 +507,13 @@ button_title="#000000" button_text="#000000" button_text_hi="#ffffff"> + + + + @@ -511,12 +545,19 @@ button_title="#000000" button_text="#000000" button_text_hi="#ffffff"> + + + + - + + + + + @@ -554,6 +602,13 @@ button_title="#000000" button_text="#000000" button_text_hi="#ffffff"> + + + + @@ -573,6 +628,13 @@ button_title="#000000" button_text="#000000" button_text_hi="#ffffff"> + + + + @@ -602,6 +664,13 @@ button_title="#000000" button_text="#000000" button_text_hi="#ffffff"> + + + + @@ -614,7 +683,7 @@ - + + + + + @@ -646,6 +722,13 @@ button_title="#000000" button_text="#000000" button_text_hi="#ffffff"> + + + + @@ -664,6 +747,13 @@ button_title="#000000" button_text="#000000" button_text_hi="#ffffff"> + + + + @@ -682,6 +772,13 @@ button_title="#000000" button_text="#000000" button_text_hi="#ffffff"> + + + + @@ -704,6 +801,13 @@ button_title="#000000" button_text="#000000" button_text_hi="#ffffff"> + + + + @@ -736,6 +840,13 @@ button_title="#000000" button_text="#000000" button_text_hi="#ffffff"> + + + + diff --git a/release/scripts/presets/interface_theme/elsyiun.xml b/release/scripts/presets/interface_theme/elsyiun.xml index 25023310b85..0daadcd41d3 100644 --- a/release/scripts/presets/interface_theme/elsyiun.xml +++ b/release/scripts/presets/interface_theme/elsyiun.xml @@ -220,16 +220,10 @@ blend="0.5"> - - - - + + + + + + + + @@ -348,7 +355,6 @@ + + + + @@ -404,6 +417,13 @@ button_title="#000000" button_text="#000000" button_text_hi="#ffffff"> + + + + @@ -441,6 +461,13 @@ button_title="#000000" button_text="#000000" button_text_hi="#ffffff"> + + + + @@ -480,6 +507,13 @@ button_title="#8b8b8b" button_text="#8b8b8b" button_text_hi="#ffffff"> + + + + @@ -511,12 +545,19 @@ button_title="#000000" button_text="#000000" button_text_hi="#ffffff"> + + + + - + + + + + @@ -554,6 +602,13 @@ button_title="#8b8b8b" button_text="#8b8b8b" button_text_hi="#ffffff"> + + + + @@ -573,6 +628,13 @@ button_title="#000000" button_text="#000000" button_text_hi="#ffffff"> + + + + @@ -602,6 +664,13 @@ button_title="#8b8b8b" button_text="#8b8b8b" button_text_hi="#ffffff"> + + + + @@ -614,7 +683,7 @@ - + + + + + @@ -646,6 +722,13 @@ button_title="#000000" button_text="#000000" button_text_hi="#ffffff"> + + + + @@ -664,6 +747,13 @@ button_title="#000000" button_text="#000000" button_text_hi="#000000"> + + + + @@ -682,6 +772,13 @@ button_title="#000000" button_text="#000000" button_text_hi="#ffffff"> + + + + @@ -704,6 +801,13 @@ button_title="#000000" button_text="#000000" button_text_hi="#ffffff"> + + + + @@ -736,6 +840,13 @@ button_title="#000000" button_text="#000000" button_text_hi="#ffffff"> + + + + diff --git a/release/scripts/presets/interface_theme/hexagon.xml b/release/scripts/presets/interface_theme/hexagon.xml index 1acc54912c3..932bd52a4e9 100644 --- a/release/scripts/presets/interface_theme/hexagon.xml +++ b/release/scripts/presets/interface_theme/hexagon.xml @@ -220,16 +220,10 @@ blend="0.5"> - - - - + + + + + + + + @@ -348,7 +355,6 @@ + + + + @@ -404,6 +417,13 @@ button_title="#000000" button_text="#000000" button_text_hi="#ffffff"> + + + + @@ -441,6 +461,13 @@ button_title="#000000" button_text="#000000" button_text_hi="#ffffff"> + + + + @@ -480,6 +507,13 @@ button_title="#eeeeee" button_text="#eeeeee" button_text_hi="#ffffff"> + + + + @@ -511,12 +545,19 @@ button_title="#000000" button_text="#000000" button_text_hi="#ffffff"> + + + + - + + + + + @@ -554,6 +602,13 @@ button_title="#000000" button_text="#000000" button_text_hi="#ffffff"> + + + + @@ -573,6 +628,13 @@ button_title="#000000" button_text="#000000" button_text_hi="#ffffff"> + + + + @@ -602,6 +664,13 @@ button_title="#000000" button_text="#000000" button_text_hi="#ffffff"> + + + + @@ -614,7 +683,7 @@ - + + + + + @@ -646,6 +722,13 @@ button_title="#000000" button_text="#000000" button_text_hi="#ffffff"> + + + + @@ -664,6 +747,13 @@ button_title="#000000" button_text="#000000" button_text_hi="#ffffff"> + + + + @@ -682,6 +772,13 @@ button_title="#000000" button_text="#000000" button_text_hi="#ffffff"> + + + + @@ -704,6 +801,13 @@ button_title="#000000" button_text="#000000" button_text_hi="#ffffff"> + + + + @@ -736,6 +840,13 @@ button_title="#000000" button_text="#000000" button_text_hi="#ffffff"> + + + + diff --git a/release/scripts/presets/interface_theme/ubuntu_ambiance.xml b/release/scripts/presets/interface_theme/ubuntu_ambiance.xml index b1fd93b52dd..8be83cbde23 100644 --- a/release/scripts/presets/interface_theme/ubuntu_ambiance.xml +++ b/release/scripts/presets/interface_theme/ubuntu_ambiance.xml @@ -220,16 +220,10 @@ blend="0.1"> - - - - + + + + + + + + @@ -348,7 +355,6 @@ + + + + @@ -404,6 +417,13 @@ button_title="#000000" button_text="#000000" button_text_hi="#ffffff"> + + + + @@ -441,6 +461,13 @@ button_title="#9c9c9c" button_text="#9c9c9c" button_text_hi="#ffffff"> + + + + @@ -480,6 +507,13 @@ button_title="#b1b1b1" button_text="#b9b9b9" button_text_hi="#ffffff"> + + + + @@ -511,12 +545,19 @@ button_title="#acacac" button_text="#acacac" button_text_hi="#ffffff"> + + + + - + + + + + @@ -554,6 +602,13 @@ button_title="#64645e" button_text="#95948f" button_text_hi="#ffffff"> + + + + @@ -573,6 +628,13 @@ button_title="#9c9c9c" button_text="#9c9c9c" button_text_hi="#ffffff"> + + + + @@ -602,6 +664,13 @@ button_title="#acacac" button_text="#acacac" button_text_hi="#ffffff"> + + + + @@ -614,7 +683,7 @@ - + + + + + @@ -646,6 +722,13 @@ button_title="#000000" button_text="#000000" button_text_hi="#f47421"> + + + + @@ -664,6 +747,13 @@ button_title="#eeedeb" button_text="#eeedeb" button_text_hi="#ffffff"> + + + + @@ -682,6 +772,13 @@ button_title="#000000" button_text="#000000" button_text_hi="#ffffff"> + + + + @@ -704,6 +801,13 @@ button_title="#000000" button_text="#000000" button_text_hi="#ffffff"> + + + + @@ -736,6 +840,13 @@ button_title="#9c9c9c" button_text="#ffffff" button_text_hi="#ffffff"> + + + + From db4d342223e699407ad71f917a58d5d86a167073 Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Sun, 16 Dec 2012 06:30:17 +0000 Subject: [PATCH 171/252] Bugfix #33541 - Deleting all keyframes leaves dangling action groups When deleting all keyframes in F-Curves, the corresponding F-Curves are deleted. If all the F-Curves in an action group were deleted in such a way, the group wouldn't be removed. This meant that these groups would never be shown (until F-Curves for these groups were created again), but would still exist, causing problems when trying to rearrange groups in the animation editors (i.e. groups would appear to not move). Now these groups get deleted when they get empty. --- .../editors/animation/anim_channels_edit.c | 30 ++++++++++++------- 1 file changed, 20 insertions(+), 10 deletions(-) diff --git a/source/blender/editors/animation/anim_channels_edit.c b/source/blender/editors/animation/anim_channels_edit.c index fe836204c27..1e4431bd0d6 100644 --- a/source/blender/editors/animation/anim_channels_edit.c +++ b/source/blender/editors/animation/anim_channels_edit.c @@ -538,12 +538,26 @@ void ANIM_fcurve_delete_from_animdata(bAnimContext *ac, AnimData *adt, FCurve *f BLI_remlink(&adt->drivers, fcu); } else if (adt->action) { + bAction *act = adt->action; + /* remove from group or action, whichever one "owns" the F-Curve */ - if (fcu->grp) - action_groups_remove_channel(adt->action, fcu); - else - BLI_remlink(&adt->action->curves, fcu); + if (fcu->grp) { + bActionGroup *agrp = fcu->grp; + /* remove F-Curve from group+action */ + action_groups_remove_channel(act, fcu); + + /* if group has no more channels, remove it too, + * otherwise can have many dangling groups [#33541] + */ + if (agrp->channels.first == NULL) { + BLI_freelinkN(&act->groups, agrp); + } + } + else { + BLI_remlink(&act->curves, fcu); + } + /* if action has no more F-Curves as a result of this, unlink it from * AnimData if it did not come from a NLA Strip being tweaked. * @@ -551,12 +565,8 @@ void ANIM_fcurve_delete_from_animdata(bAnimContext *ac, AnimData *adt, FCurve *f * channel list that are empty, and linger around long after the data they * are for has disappeared (and probably won't come back). */ - // XXX: does everybody always want this? - /* XXX: there's a problem where many actions could build up in the file if multiple - * full add/delete cycles are performed on the same objects, but assume that this is rare - */ - if ((adt->action->curves.first == NULL) && (adt->flag & ADT_NLA_EDIT_ON) == 0) { - id_us_min(&adt->action->id); + if ((act->curves.first == NULL) && (adt->flag & ADT_NLA_EDIT_ON) == 0) { + id_us_min(&act->id); adt->action = NULL; } } From 9a469b62cabf3d434de68c9e698970cc7f060136 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sun, 16 Dec 2012 08:43:05 +0000 Subject: [PATCH 172/252] replace strcpy with BLI_strncpy or memcpy when the size is known. --- source/blender/blenkernel/BKE_property.h | 3 ++- source/blender/blenkernel/intern/customdata.c | 9 +++++---- source/blender/blenkernel/intern/dynamicpaint.c | 2 +- source/blender/blenkernel/intern/gpencil.c | 2 +- source/blender/blenkernel/intern/material.c | 2 +- source/blender/blenkernel/intern/object.c | 1 + source/blender/blenkernel/intern/property.c | 2 +- source/blender/editors/mask/mask_relationships.c | 5 +++-- source/blender/editors/space_view3d/drawvolume.c | 1 + .../blender/editors/transform/transform_orientations.c | 7 ++++--- source/blender/makesdna/DNA_customdata_types.h | 2 +- source/blender/makesrna/intern/rna_space.c | 2 +- 12 files changed, 22 insertions(+), 16 deletions(-) diff --git a/source/blender/blenkernel/BKE_property.h b/source/blender/blenkernel/BKE_property.h index e0eb8c04b60..99e60757f15 100644 --- a/source/blender/blenkernel/BKE_property.h +++ b/source/blender/blenkernel/BKE_property.h @@ -47,6 +47,7 @@ void BKE_bproperty_object_set(struct Object *ob, struct bProperty * // int BKE_bproperty_cmp(struct bProperty *prop, const char *str); void BKE_bproperty_set(struct bProperty *prop, const char *str); void BKE_bproperty_add(struct bProperty *prop, const char *str); -void BKE_bproperty_set_valstr(struct bProperty *prop, char *str); +/* should really be called '_get_valstr()' or '_as_string()' */ +void BKE_bproperty_set_valstr(struct bProperty *prop, char str[MAX_PROPSTRING]); #endif diff --git a/source/blender/blenkernel/intern/customdata.c b/source/blender/blenkernel/intern/customdata.c index b2f8db0dcce..0f352dede23 100644 --- a/source/blender/blenkernel/intern/customdata.c +++ b/source/blender/blenkernel/intern/customdata.c @@ -2104,7 +2104,7 @@ int CustomData_set_layer_name(const CustomData *data, int type, int n, const cha if (layer_index < 0) return 0; if (!name) return 0; - strcpy(data->layers[layer_index].name, name); + BLI_strncpy(data->layers[layer_index].name, name, sizeof(data->layers[layer_index].name)); return 1; } @@ -2854,10 +2854,11 @@ void CustomData_validate_layer_name(const CustomData *data, int type, const char * deleted, so assign the active layer to name */ index = CustomData_get_active_layer_index(data, type); - strcpy(outname, data->layers[index].name); + BLI_strncpy(outname, data->layers[index].name, MAX_CUSTOMDATA_LAYER_NAME); + } + else { + BLI_strncpy(outname, name, MAX_CUSTOMDATA_LAYER_NAME); } - else - strcpy(outname, name); } int CustomData_verify_versions(struct CustomData *data, int index) diff --git a/source/blender/blenkernel/intern/dynamicpaint.c b/source/blender/blenkernel/intern/dynamicpaint.c index ed85e5b627b..38838fa8fca 100644 --- a/source/blender/blenkernel/intern/dynamicpaint.c +++ b/source/blender/blenkernel/intern/dynamicpaint.c @@ -397,7 +397,7 @@ void dynamicPaintSurface_updateType(struct DynamicPaintSurface *surface) } else { strcpy(surface->output_name, "dp_"); - strcpy(surface->output_name2, surface->output_name); + BLI_strncpy(surface->output_name2, surface->output_name, sizeof(surface->output_name2)); surface->flags &= ~MOD_DPAINT_ANTIALIAS; surface->depth_clamp = 0.0f; } diff --git a/source/blender/blenkernel/intern/gpencil.c b/source/blender/blenkernel/intern/gpencil.c index a7d0152a799..0c83bb8d39a 100644 --- a/source/blender/blenkernel/intern/gpencil.c +++ b/source/blender/blenkernel/intern/gpencil.c @@ -183,7 +183,7 @@ bGPDlayer *gpencil_layer_addnew(bGPdata *gpd, const char *name, int setactive) gpl->thickness = 3; /* auto-name */ - strcpy(gpl->info, name); + BLI_strncpy(gpl->info, name, sizeof(gpl->info)); BLI_uniquename(&gpd->layers, gpl, "GP_Layer", '.', offsetof(bGPDlayer, info), sizeof(gpl->info)); /* make this one the active one */ diff --git a/source/blender/blenkernel/intern/material.c b/source/blender/blenkernel/intern/material.c index a3dcda7069a..f0327719372 100644 --- a/source/blender/blenkernel/intern/material.c +++ b/source/blender/blenkernel/intern/material.c @@ -1855,7 +1855,7 @@ static void convert_tfacematerial(Main *main, Material *ma) mat_new = BKE_material_copy(ma); if (mat_new) { /* rename the material*/ - strcpy(mat_new->id.name, idname); + BLI_strncpy(mat_new->id.name, idname, sizeof(mat_new->id.name)); id_us_min((ID *)mat_new); mat_nr = mesh_addmaterial(me, mat_new); diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c index c705e226f45..03f3fc13ce4 100644 --- a/source/blender/blenkernel/intern/object.c +++ b/source/blender/blenkernel/intern/object.c @@ -57,6 +57,7 @@ #include "DNA_view3d_types.h" #include "DNA_world_types.h" #include "DNA_object_types.h" +#include "DNA_property_types.h" #include "BLI_blenlib.h" #include "BLI_math.h" diff --git a/source/blender/blenkernel/intern/property.c b/source/blender/blenkernel/intern/property.c index 8da4f11fed3..c4658712ecb 100644 --- a/source/blender/blenkernel/intern/property.c +++ b/source/blender/blenkernel/intern/property.c @@ -287,7 +287,7 @@ void BKE_bproperty_add(bProperty *prop, const char *str) } /* reads value of property, sets it in chars in str */ -void BKE_bproperty_set_valstr(bProperty *prop, char *str) +void BKE_bproperty_set_valstr(bProperty *prop, char str[MAX_PROPSTRING]) { // extern int Gdfra; /* sector.c */ diff --git a/source/blender/editors/mask/mask_relationships.c b/source/blender/editors/mask/mask_relationships.c index a1f2539ce7c..2a1bdee32f7 100644 --- a/source/blender/editors/mask/mask_relationships.c +++ b/source/blender/editors/mask/mask_relationships.c @@ -31,6 +31,7 @@ #include "BLI_math.h" +#include "BLI_string.h" #include "BKE_context.h" #include "BKE_depsgraph.h" @@ -143,8 +144,8 @@ static int mask_parent_set_exec(bContext *C, wmOperator *UNUSED(op)) if (MASKPOINT_ISSEL_ANY(point)) { point->parent.id_type = ID_MC; point->parent.id = &clip->id; - strcpy(point->parent.parent, tracking_object->name); - strcpy(point->parent.sub_parent, track->name); + BLI_strncpy(point->parent.parent, tracking_object->name, sizeof(point->parent.parent)); + BLI_strncpy(point->parent.sub_parent, track->name, sizeof(point->parent.sub_parent)); copy_v2_v2(point->parent.parent_orig, parmask_pos); } diff --git a/source/blender/editors/space_view3d/drawvolume.c b/source/blender/editors/space_view3d/drawvolume.c index ebb48960b80..70690e2dce7 100644 --- a/source/blender/editors/space_view3d/drawvolume.c +++ b/source/blender/editors/space_view3d/drawvolume.c @@ -38,6 +38,7 @@ #include "DNA_screen_types.h" #include "DNA_smoke_types.h" #include "DNA_view3d_types.h" +#include "DNA_property_types.h" #include "BLI_utildefines.h" #include "BLI_blenlib.h" diff --git a/source/blender/editors/transform/transform_orientations.c b/source/blender/editors/transform/transform_orientations.c index d758a15f50c..e865680ebd3 100644 --- a/source/blender/editors/transform/transform_orientations.c +++ b/source/blender/editors/transform/transform_orientations.c @@ -437,7 +437,7 @@ int BIF_countTransformOrientation(const bContext *C) return count; } -void applyTransformOrientation(const bContext *C, float mat[3][3], char *name) +void applyTransformOrientation(const bContext *C, float mat[3][3], char name[MAX_NAME]) { TransformOrientation *ts; View3D *v3d = CTX_wm_view3d(C); @@ -448,8 +448,9 @@ void applyTransformOrientation(const bContext *C, float mat[3][3], char *name) for (i = 0, ts = CTX_data_scene(C)->transform_spaces.first; ts; ts = ts->next, i++) { if (selected_index == i) { - if (name) - strcpy(name, ts->name); + if (name) { + BLI_strncpy(name, ts->name, MAX_NAME); + } copy_m3_m3(mat, ts->mat); break; diff --git a/source/blender/makesdna/DNA_customdata_types.h b/source/blender/makesdna/DNA_customdata_types.h index 6f7bb5a723e..e28b8780250 100644 --- a/source/blender/makesdna/DNA_customdata_types.h +++ b/source/blender/makesdna/DNA_customdata_types.h @@ -46,7 +46,7 @@ typedef struct CustomDataLayer { int active_clone; /* number of the layer to render*/ int active_mask; /* number of the layer to render*/ int uid; /* shape keyblock unique id reference*/ - char name[64]; /* layer name, MAX_CUSTOMDATA_LAYER_AAME */ + char name[64]; /* layer name, MAX_CUSTOMDATA_LAYER_NAME */ void *data; /* layer data */ } CustomDataLayer; diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c index 2b2e8d97499..32208c8c819 100644 --- a/source/blender/makesrna/intern/rna_space.c +++ b/source/blender/makesrna/intern/rna_space.c @@ -775,7 +775,7 @@ static void rna_SpaceProperties_align_set(PointerRNA *ptr, int value) static void rna_ConsoleLine_body_get(PointerRNA *ptr, char *value) { ConsoleLine *ci = (ConsoleLine *)ptr->data; - strcpy(value, ci->line); + memcpy(value, ci->line, ci->len + 1); } static int rna_ConsoleLine_body_length(PointerRNA *ptr) From e114459ba36276aed5f3e04d99e7c8556a3e206b Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Sun, 16 Dec 2012 09:37:15 +0000 Subject: [PATCH 173/252] Fix region overlap drawing over render info text in image editor and 3d view. --- source/blender/editors/include/ED_screen.h | 2 ++ source/blender/editors/screen/area.c | 22 ++++++++++++- .../editors/space_view3d/view3d_draw.c | 31 ++++--------------- 3 files changed, 29 insertions(+), 26 deletions(-) diff --git a/source/blender/editors/include/ED_screen.h b/source/blender/editors/include/ED_screen.h index f7a42d5b1ac..edee1213502 100644 --- a/source/blender/editors/include/ED_screen.h +++ b/source/blender/editors/include/ED_screen.h @@ -67,6 +67,8 @@ void ED_region_toggle_hidden(struct bContext *C, struct ARegion *ar); void ED_region_info_draw(struct ARegion *ar, const char *text, int block, float alpha); void ED_region_grid_draw(struct ARegion *ar, float zoomx, float zoomy); float ED_region_blend_factor(struct ARegion *ar); +int ED_region_overlapping_offset(struct ARegion *ar); + /* spaces */ void ED_spacetypes_init(void); diff --git a/source/blender/editors/screen/area.c b/source/blender/editors/screen/area.c index a73c2d818d0..932414ffaba 100644 --- a/source/blender/editors/screen/area.c +++ b/source/blender/editors/screen/area.c @@ -1852,7 +1852,7 @@ void ED_region_info_draw(ARegion *ar, const char *text, int block, float alpha) /* text */ UI_ThemeColor(TH_TEXT_HI); - BLF_position(fontid, 12, rect.ymin + 5, 0.0f); + BLF_position(fontid, 12 + ED_region_overlapping_offset(ar), rect.ymin + 5, 0.0f); BLF_draw(fontid, text, BLF_DRAW_STR_DUMMY_MAX); } @@ -1915,3 +1915,23 @@ void ED_region_grid_draw(ARegion *ar, float zoomx, float zoomy) } glEnd(); } + +/* checks overlapping region for labels, axes, icons */ +int ED_region_overlapping_offset(ARegion *ar) +{ + ARegion *arn = ar; + + /* too lazy to pass on area listbase */ + while (arn->prev) + arn = arn->prev; + + /* check if a region overlaps with the current one */ + for (; arn; arn = arn->next) { + if (ar != arn) + if (ar->winrct.xmin == arn->winrct.xmin) + if (ar->winrct.ymin == arn->winrct.ymin) + return arn->winrct.xmax - arn->winrct.xmin; + } + return 0; +} + diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c index 2f09354439b..31bfd9f45e0 100644 --- a/source/blender/editors/space_view3d/view3d_draw.c +++ b/source/blender/editors/space_view3d/view3d_draw.c @@ -563,25 +563,6 @@ static void drawfloor(Scene *scene, View3D *v3d, const char **grid_unit) if (v3d->zbuf && scene->obedit) glDepthMask(1); } -/* checks overlapping region for labels, axes, icons */ -static int draw_name_offset(ARegion *ar) -{ - ARegion *arn = ar; - - /* too lazy to pass on area listbase */ - while (arn->prev) - arn = arn->prev; - - /* check if a region overlaps with the current one */ - for (; arn; arn = arn->next) { - if (ar != arn) - if (ar->winrct.xmin == arn->winrct.xmin) - if (ar->winrct.ymin == arn->winrct.ymin) - return arn->winrct.xmax - arn->winrct.xmin; - } - return 0; -} - static void drawcursor(Scene *scene, ARegion *ar, View3D *v3d) { @@ -615,7 +596,7 @@ static void draw_view_axis(ARegion *ar, RegionView3D *rv3d) { const float k = U.rvisize; /* axis size */ const float toll = 0.5; /* used to see when view is quasi-orthogonal */ - const float startx = k + 1.0f + draw_name_offset(ar); /* axis center in screen coordinates, x=y */ + const float startx = k + 1.0f + ED_region_overlapping_offset(ar); /* axis center in screen coordinates, x=y */ const float starty = k + 1.0f; float ydisp = 0.0; /* vertical displacement to allow obj info text */ int bright = 25 * (float)U.rvibright + 5; /* axis alpha (rvibright has range 0-10) */ @@ -810,7 +791,7 @@ static void draw_view_icon(ARegion *ar, RegionView3D *rv3d) glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - UI_icon_draw(5.0 + draw_name_offset(ar), 5.0, icon); + UI_icon_draw(5.0 + ED_region_overlapping_offset(ar), 5.0, icon); glDisable(GL_BLEND); } @@ -878,7 +859,7 @@ static void draw_viewport_name(ARegion *ar, View3D *v3d) if (name) { UI_ThemeColor(TH_TEXT_HI); - BLF_draw_default_ascii(U.widget_unit + draw_name_offset(ar), ar->winy - U.widget_unit, 0.0f, name, sizeof(tmpstr)); + BLF_draw_default_ascii(U.widget_unit + ED_region_overlapping_offset(ar), ar->winy - U.widget_unit, 0.0f, name, sizeof(tmpstr)); } } @@ -888,7 +869,7 @@ static void draw_viewport_name(ARegion *ar, View3D *v3d) static void draw_selected_name(ARegion *ar, Scene *scene, Object *ob) { char info[256], *markern; - short offset = 30 + draw_name_offset(ar); + short offset = 30 + ED_region_overlapping_offset(ar); /* get name of marker on current frame (if available) */ markern = BKE_scene_find_marker_name(scene, CFRA); @@ -971,7 +952,7 @@ static void draw_selected_name(ARegion *ar, Scene *scene, Object *ob) } if (U.uiflag & USER_SHOW_ROTVIEWICON) - offset = U.widget_unit + (U.rvisize * 2) + draw_name_offset(ar); + offset = U.widget_unit + (U.rvisize * 2) + ED_region_overlapping_offset(ar); BLF_draw_default(offset, 0.5f * U.widget_unit, 0.0f, info, sizeof(info)); } @@ -3234,7 +3215,7 @@ static void view3d_main_area_draw_info(const bContext *C, ARegion *ar, const cha BLI_snprintf(numstr, sizeof(numstr), "%s x %.4g", grid_unit, v3d->grid); } - BLF_draw_default_ascii(draw_name_offset(ar) + U.widget_unit, + BLF_draw_default_ascii(ED_region_overlapping_offset(ar) + U.widget_unit, ar->winy - (USER_SHOW_VIEWPORTNAME ? 2 * U.widget_unit : U.widget_unit), 0.0f, numstr[0] ? numstr : grid_unit, sizeof(numstr)); } From 176292067eaa5b56c8bdee3d58890f01007bd479 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Sun, 16 Dec 2012 09:37:32 +0000 Subject: [PATCH 174/252] Cycles OSL: small optimization to geometry node, tangent output still was not properly optimized out in some cases. For reference, setting this will give detailed information about OSL shaders: export OSL_OPTIONS="statistics:level=1,debug=1,llvm_debug=1" --- intern/cycles/kernel/osl/osl_shader.cpp | 3 --- intern/cycles/kernel/shaders/node_geometry.osl | 3 +-- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/intern/cycles/kernel/osl/osl_shader.cpp b/intern/cycles/kernel/osl/osl_shader.cpp index f5c04b6755e..3ff032374fc 100644 --- a/intern/cycles/kernel/osl/osl_shader.cpp +++ b/intern/cycles/kernel/osl/osl_shader.cpp @@ -172,9 +172,6 @@ static void flatten_surface_closure_tree(ShaderData *sd, bool no_glossy, break; } case OSL::ClosurePrimitive::Emissive: { - if (sd->num_closure == MAX_CLOSURE) - return; - /* sample weight */ float sample_weight = fabsf(average(weight)); diff --git a/intern/cycles/kernel/shaders/node_geometry.osl b/intern/cycles/kernel/shaders/node_geometry.osl index d1c11b70081..3d5d67360ce 100644 --- a/intern/cycles/kernel/shaders/node_geometry.osl +++ b/intern/cycles/kernel/shaders/node_geometry.osl @@ -56,8 +56,7 @@ shader node_geometry( 0.0, 0.0, 0.0, 0.0, 0.5, -0.5, 0.0, 1.0); - vector T = transform(project, generated); - T = transform("object", "world", T); + vector T = transform("object", "world", transform(project, generated)); Tangent = cross(Normal, normalize(cross(T, Normal))); } else { From dd582e03080cbe7e3ab2357ffd23461e2ab673c4 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sun, 16 Dec 2012 09:41:39 +0000 Subject: [PATCH 175/252] set compositor background scale to 1.0 --- release/datafiles/startup.blend | Bin 415348 -> 416736 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/release/datafiles/startup.blend b/release/datafiles/startup.blend index cdd43c74f3bbf39983861609586efa14db42012b..aa7a679c0b22d08cebf00cde27562bee9da12919 100644 GIT binary patch literal 416736 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 z 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

1w^bOhY^FwsWkwN|2 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�EGTV#oTz5I&Y>n7XdoRRzyy@EZ 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

YCv|O=v)*eeo^T8j?D%$zcGC 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ϋ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 diff --git a/release/datafiles/blender_icons.svg b/release/datafiles/blender_icons.svg index 4553003682f..ab3a07b8fad 100644 --- a/release/datafiles/blender_icons.svg +++ b/release/datafiles/blender_icons.svg @@ -14,7 +14,7 @@ height="640" id="svg2" sodipodi:version="0.32" - inkscape:version="0.48.2 r9819" + inkscape:version="0.48.3.1 r9886" version="1.0" sodipodi:docname="blender_icons.svg" inkscape:output_extension="org.inkscape.output.svg.inkscape" @@ -49905,6 +49905,27 @@ y1="118.5" x2="235" y2="118.5" /> + + + + + + + + + + + + + + + + From 9064f0cb517df80cf3db44eb249c1be41f175728 Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Tue, 18 Dec 2012 09:03:21 +0000 Subject: [PATCH 218/252] Adding Amharic (i.e. ethiopic) glyphs. --- release/datafiles/fonts/droidsans.ttf.gz | Bin 2347305 -> 2617436 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/release/datafiles/fonts/droidsans.ttf.gz b/release/datafiles/fonts/droidsans.ttf.gz index 439515e5bb4a639c2779a106cd31738123586cca..a0e7502cc1fc30704a48f395516a81b072eb209a 100644 GIT binary patch literal 2617436 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

WI7qk%c*WP0TmW=jl3Ke}9bYh7xxs<oQ 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Äi8+duxhRFth!iEO2) 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%0AnNRwtV}FaEZX{McwX=*E8J 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 From dc7a138830bed2f27cc5b20d919b73406ff17480 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sun, 16 Dec 2012 10:28:52 +0000 Subject: [PATCH 176/252] correct bad comment --- source/blender/makesrna/intern/makesrna.c | 2 +- source/blender/python/mathutils/mathutils_Matrix.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/source/blender/makesrna/intern/makesrna.c b/source/blender/makesrna/intern/makesrna.c index 1d9b737ba29..9b7872f0b4b 100644 --- a/source/blender/makesrna/intern/makesrna.c +++ b/source/blender/makesrna/intern/makesrna.c @@ -91,7 +91,7 @@ static void rna_generate_static_parameter_prototypes(FILE *f, StructRNA *srna, F { \ WRITE_COMMA; \ fprintf(f, param); \ - } + } (void)0 static int replace_if_different(char *tmpfile, const char *dep_files[]) { diff --git a/source/blender/python/mathutils/mathutils_Matrix.c b/source/blender/python/mathutils/mathutils_Matrix.c index e64853fd8f5..da2888045d0 100644 --- a/source/blender/python/mathutils/mathutils_Matrix.c +++ b/source/blender/python/mathutils/mathutils_Matrix.c @@ -1537,7 +1537,7 @@ static PyObject *Matrix_transposed(MatrixObject *self) PyDoc_STRVAR(Matrix_normalize_doc, ".. method:: normalize()\n" "\n" -" Normalize each of the columns of the matrix (useful for transforming unit length normals).\n" +" Normalize each of the matrix columns.\n" ); static PyObject *Matrix_normalize(MatrixObject *self) { From 677f519ca5a7a68b8e361487f2c9883e2cdc8861 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Sun, 16 Dec 2012 11:47:13 +0000 Subject: [PATCH 177/252] Bugfix IRC report Curves heavily scaled down will have render artifacts Caused by precision issues when computing average normal map for INDEX3 surface type. Now calculation happens in local object space instead of world space. --- .../render/intern/source/convertblender.c | 26 ++++++++++++++----- 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/source/blender/render/intern/source/convertblender.c b/source/blender/render/intern/source/convertblender.c index 620f9d41818..67e899e425e 100644 --- a/source/blender/render/intern/source/convertblender.c +++ b/source/blender/render/intern/source/convertblender.c @@ -2820,7 +2820,7 @@ static void init_render_curve(Render *re, ObjectRen *obr, int timeoffset) ListBase disp={NULL, NULL}; Material **matar; float *data, *fp, *orco=NULL; - float n[3], mat[4][4]; + float n[3], mat[4][4], nmat[4][4]; int nr, startvert, a, b; int need_orco=0, totmat; @@ -2835,6 +2835,11 @@ static void init_render_curve(Render *re, ObjectRen *obr, int timeoffset) mult_m4_m4m4(mat, re->viewmat, ob->obmat); invert_m4_m4(ob->imat, mat); + /* local object -> world space transform for normals */ + copy_m4_m4(nmat, mat); + transpose_m4(nmat); + invert_m4(nmat); + /* material array */ totmat= ob->totcol+1; matar= MEM_callocN(sizeof(Material*)*totmat, "init_render_surf matar"); @@ -2891,13 +2896,20 @@ static void init_render_curve(Render *re, ObjectRen *obr, int timeoffset) zero_v3(n); index= dl->index; for (a=0; aparts; a++, index+=3) { + int v1 = index[0], v2 = index[1], v3 = index[2]; + float *co1 = &dl->verts[v1 * 3], + *co2 = &dl->verts[v2 * 3], + *co3 = &dl->verts[v3 * 3]; + vlr= RE_findOrAddVlak(obr, obr->totvlak++); - vlr->v1= RE_findOrAddVert(obr, startvert+index[0]); - vlr->v2= RE_findOrAddVert(obr, startvert+index[1]); - vlr->v3= RE_findOrAddVert(obr, startvert+index[2]); + vlr->v1= RE_findOrAddVert(obr, startvert + v1); + vlr->v2= RE_findOrAddVert(obr, startvert + v2); + vlr->v3= RE_findOrAddVert(obr, startvert + v3); vlr->v4= NULL; - if (area_tri_v3(vlr->v3->co, vlr->v2->co, vlr->v1->co)>FLT_EPSILON10) { - normal_tri_v3(tmp, vlr->v3->co, vlr->v2->co, vlr->v1->co); + + /* to prevent float accuracy issues, we calculate normal in local object space (not world) */ + if (area_tri_v3(co3, co2, co1)>FLT_EPSILON10) { + normal_tri_v3(tmp, co3, co2, co1); add_v3_v3(n, tmp); } @@ -2906,6 +2918,8 @@ static void init_render_curve(Render *re, ObjectRen *obr, int timeoffset) vlr->ec= 0; } + /* transform normal to world space */ + mul_m4_v3(nmat, n); normalize_v3(n); /* vertex normals */ From a0855a95db222e64d84682edff1df21308f51b5c Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Sun, 16 Dec 2012 12:55:52 +0000 Subject: [PATCH 178/252] Cycles: add "Textures" panel in particle properties, to make it possble to add textures when Cycles is selected as render engine. --- intern/cycles/blender/addon/ui.py | 32 +++++++++++++++++++ .../editors/space_buttons/buttons_texture.c | 12 ++++++- 2 files changed, 43 insertions(+), 1 deletion(-) diff --git a/intern/cycles/blender/addon/ui.py b/intern/cycles/blender/addon/ui.py index 66f99beeb97..86a1ab3c3e0 100644 --- a/intern/cycles/blender/addon/ui.py +++ b/intern/cycles/blender/addon/ui.py @@ -915,6 +915,37 @@ class CyclesTexture_PT_colors(CyclesButtonsPanel, Panel): layout.template_color_ramp(mapping, "color_ramp", expand=True) +class CyclesParticle_PT_textures(CyclesButtonsPanel, Panel): + bl_label = "Textures" + bl_context = "particle" + bl_options = {'DEFAULT_CLOSED'} + + @classmethod + def poll(cls, context): + psys = context.particle_system + return psys and CyclesButtonsPanel.poll(context) + + def draw(self, context): + layout = self.layout + + psys = context.particle_system + part = psys.settings + + row = layout.row() + row.template_list(part, "texture_slots", part, "active_texture_index", rows=2) + + col = row.column(align=True) + col.operator("texture.slot_move", text="", icon='TRIA_UP').type = 'UP' + col.operator("texture.slot_move", text="", icon='TRIA_DOWN').type = 'DOWN' + col.menu("TEXTURE_MT_specials", icon='DOWNARROW_HLT', text="") + + if not part.active_texture: + layout.template_ID(part, "active_texture", new="texture.new") + else: + slot = part.texture_slots[part.active_texture_index] + layout.template_ID(slot, "texture", new="texture.new") + + class CyclesScene_PT_simplify(CyclesButtonsPanel, Panel): bl_label = "Simplify" bl_context = "scene" @@ -1027,6 +1058,7 @@ def get_panels(): bpy.types.TEXTURE_PT_pointdensity_turbulence, bpy.types.TEXTURE_PT_mapping, bpy.types.TEXTURE_PT_influence, + bpy.types.TEXTURE_PT_colors, bpy.types.PARTICLE_PT_context_particles, bpy.types.PARTICLE_PT_emission, bpy.types.PARTICLE_PT_hair_dynamics, diff --git a/source/blender/editors/space_buttons/buttons_texture.c b/source/blender/editors/space_buttons/buttons_texture.c index abfefba02b9..3175c15ccac 100644 --- a/source/blender/editors/space_buttons/buttons_texture.c +++ b/source/blender/editors/space_buttons/buttons_texture.c @@ -358,7 +358,17 @@ static void template_texture_user_menu(bContext *C, uiLayout *layout, void *UNUS } /* create button */ - BLI_snprintf(name, UI_MAX_NAME_STR, " %s", user->name); + if (user->prop) { + PointerRNA texptr = RNA_property_pointer_get(&user->ptr, user->prop); + Tex *tex = texptr.data; + + if (tex) + BLI_snprintf(name, UI_MAX_NAME_STR, " %s - %s", user->name, tex->id.name+2); + else + BLI_snprintf(name, UI_MAX_NAME_STR, " %s", user->name); + } + else + BLI_snprintf(name, UI_MAX_NAME_STR, " %s", user->name); but = uiDefIconTextBut(block, BUT, 0, user->icon, name, 0, 0, UI_UNIT_X * 4, UI_UNIT_Y, NULL, 0.0, 0.0, 0.0, 0.0, ""); From 05142993317ca33debeb965cd3ed2ce6adba48a3 Mon Sep 17 00:00:00 2001 From: Ton Roosendaal Date: Sun, 16 Dec 2012 13:31:56 +0000 Subject: [PATCH 179/252] Bugfix #33458 Tooltips in Blender were not scaling when zooming in/out on UI elements. (They did follow DPI though, but tooltips were in a 'global' fixed size). Error was that for tooltips on large scaled popups (like in Node editor) the drawing was entirely wrong even. Now tooltips scale correctly, also for fonts. --- .../editors/interface/interface_regions.c | 46 +++++++++---------- 1 file changed, 21 insertions(+), 25 deletions(-) diff --git a/source/blender/editors/interface/interface_regions.c b/source/blender/editors/interface/interface_regions.c index 9df642f58b7..84a25feac80 100644 --- a/source/blender/editors/interface/interface_regions.c +++ b/source/blender/editors/interface/interface_regions.c @@ -624,12 +624,14 @@ ARegion *ui_tooltip_create(bContext *C, ARegion *butregion, uiBut *but) /* set font, get bb */ data->fstyle = style->widget; /* copy struct */ data->fstyle.align = UI_STYLE_TEXT_CENTER; + ui_fontscale(&data->fstyle.points, aspect); + uiStyleFontSet(&data->fstyle); - /* these defines may need to be tweaked depending on font */ -#define TIP_MARGIN_Y 2 -#define TIP_BORDER_X 16.0f -#define TIP_BORDER_Y 6.0f + /* these defines tweaked depending on font */ +#define TIP_MARGIN_Y (2.0f / aspect) +#define TIP_BORDER_X (16.0f / aspect) +#define TIP_BORDER_Y (6.0f / aspect) h = BLF_height_max(data->fstyle.uifont_id); @@ -639,7 +641,7 @@ ARegion *ui_tooltip_create(bContext *C, ARegion *butregion, uiBut *but) fonth += (a == 0) ? h : h + TIP_MARGIN_Y; } - fontw *= aspect; + //fontw *= aspect; ar->regiondata = data; @@ -647,36 +649,30 @@ ARegion *ui_tooltip_create(bContext *C, ARegion *butregion, uiBut *but) data->lineh = h; data->spaceh = TIP_MARGIN_Y; - /* compute position */ - ofsx = (but->block->panel) ? but->block->panel->ofsx : 0; - ofsy = (but->block->panel) ? but->block->panel->ofsy : 0; + ofsx = 0; //(but->block->panel) ? but->block->panel->ofsx : 0; + ofsy = 0; //(but->block->panel) ? but->block->panel->ofsy : 0; + + rect_fl.xmin = (but->rect.xmin + but->rect.xmax) * 0.5f + ofsx - (TIP_BORDER_X ); + rect_fl.xmax = rect_fl.xmin + fontw + (TIP_BORDER_X ); + rect_fl.ymax = but->rect.ymin + ofsy - (TIP_BORDER_Y ); + rect_fl.ymin = rect_fl.ymax - fonth - (TIP_BORDER_Y ); - rect_fl.xmin = (but->rect.xmin + but->rect.xmax) * 0.5f + ofsx - (TIP_BORDER_X * aspect); - rect_fl.xmax = rect_fl.xmin + fontw + (TIP_BORDER_X * aspect); - rect_fl.ymax = but->rect.ymin + ofsy - (TIP_BORDER_Y * aspect); - rect_fl.ymin = rect_fl.ymax - fonth * aspect - (TIP_BORDER_Y * aspect); - #undef TIP_MARGIN_Y #undef TIP_BORDER_X #undef TIP_BORDER_Y - - /* copy to int, gets projected if possible too */ - BLI_rcti_rctf_copy(&rect_i, &rect_fl); + /* since the text has beens caled already, the size of tooltips is defined now */ + /* here we try to figure out the right location */ if (butregion) { - /* XXX temp, region v2ds can be empty still */ - if (butregion->v2d.cur.xmin != butregion->v2d.cur.xmax) { - UI_view2d_to_region_no_clip(&butregion->v2d, rect_fl.xmin, rect_fl.ymin, &rect_i.xmin, &rect_i.ymin); - UI_view2d_to_region_no_clip(&butregion->v2d, rect_fl.xmax, rect_fl.ymax, &rect_i.xmax, &rect_i.ymax); - } - - BLI_rcti_translate(&rect_i, butregion->winrct.xmin, butregion->winrct.ymin); + float ofsx = rect_fl.xmin, ofsy = rect_fl.ymax; + ui_block_to_window_fl(butregion, but->block, &ofsx, &ofsy); + BLI_rctf_translate(&rect_fl, ofsx - rect_fl.xmin, ofsy - rect_fl.ymax); } + BLI_rcti_rctf_copy(&rect_i, &rect_fl); + /* clip with window boundaries */ winx = WM_window_pixels_x(win); - // winy = WM_window_pixels_y(win); /* UNUSED */ - //wm_window_get_size(win, &winx, &winy); if (rect_i.xmax > winx) { /* super size */ From 54787a885551b15e143db59c9268e5b4e6418039 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sun, 16 Dec 2012 14:17:15 +0000 Subject: [PATCH 180/252] fix own error [#33529] Bevel on a certain edgeloop results in segmentation fault relied on edges having a loop, now use overlap apiflag instead. --- source/blender/bmesh/tools/bmesh_bevel.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/source/blender/bmesh/tools/bmesh_bevel.c b/source/blender/bmesh/tools/bmesh_bevel.c index e5a398ec66e..cc472e4a501 100644 --- a/source/blender/bmesh/tools/bmesh_bevel.c +++ b/source/blender/bmesh/tools/bmesh_bevel.c @@ -37,6 +37,7 @@ #include "BKE_customdata.h" #include "bmesh.h" +#include "./intern/bmesh_private.h" @@ -1475,9 +1476,9 @@ static void build_vmesh(MemArena *mem_arena, BMesh *bm, BevVert *bv) } /* take care, this flag isn't cleared before use, it just so happens that its not set */ -#define BM_BEVEL_EDGE_TAG_ENABLE(bme) BM_elem_flag_enable( (bme)->l, BM_ELEM_TAG) -#define BM_BEVEL_EDGE_TAG_DISABLE(bme) BM_elem_flag_disable( (bme)->l, BM_ELEM_TAG) -#define BM_BEVEL_EDGE_TAG_TEST(bme) BM_elem_flag_test( (bme)->l, BM_ELEM_TAG) +#define BM_BEVEL_EDGE_TAG_ENABLE(bme) BM_ELEM_API_FLAG_ENABLE( (bme), _FLAG_OVERLAP) +#define BM_BEVEL_EDGE_TAG_DISABLE(bme) BM_ELEM_API_FLAG_DISABLE( (bme), _FLAG_OVERLAP) +#define BM_BEVEL_EDGE_TAG_TEST(bme) BM_ELEM_API_FLAG_TEST( (bme), _FLAG_OVERLAP) /* * Construction around the vertex @@ -1504,6 +1505,8 @@ static void bevel_vert_construct(BMesh *bm, BevelParams *bp, BMVert *v) nsel++; } ntot++; + + BM_BEVEL_EDGE_TAG_DISABLE(bme); } if (nsel == 0) { From 7965b6995edfb8cf8bfd04dbf2114ca6b23ddd5a Mon Sep 17 00:00:00 2001 From: Ton Roosendaal Date: Sun, 16 Dec 2012 14:19:29 +0000 Subject: [PATCH 181/252] Bug fix 33563 Region sizex/sizey should store the actual used sizes, for hide/reveal. Didn't happen correctly, resulting in opening button regions of size 1. --- source/blender/editors/screen/area.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/source/blender/editors/screen/area.c b/source/blender/editors/screen/area.c index 932414ffaba..766d114093e 100644 --- a/source/blender/editors/screen/area.c +++ b/source/blender/editors/screen/area.c @@ -944,7 +944,7 @@ static void region_rect_recursive(wmWindow *win, ScrArea *sa, ARegion *ar, rcti alignment = RGN_ALIGN_NONE; /* prefsize, for header we stick to exception */ - prefsizex = ar->sizex ? ar->sizex : UI_DPI_FAC * ar->type->prefsizex; + prefsizex = ar->sizex > 1 ? ar->sizex : UI_DPI_FAC * ar->type->prefsizex; if (ar->regiontype == RGN_TYPE_HEADER) { prefsizey = ED_area_headersize(); } @@ -952,7 +952,7 @@ static void region_rect_recursive(wmWindow *win, ScrArea *sa, ARegion *ar, rcti prefsizey = UI_UNIT_Y * 2 + (UI_UNIT_Y / 2); } else { - prefsizey = ar->sizey ? ar->sizey : UI_DPI_FAC * ar->type->prefsizey; + prefsizey = ar->sizey > 1 ? ar->sizey : UI_DPI_FAC * ar->type->prefsizey; } @@ -1091,6 +1091,10 @@ static void region_rect_recursive(wmWindow *win, ScrArea *sa, ARegion *ar, rcti ar->winx = BLI_rcti_size_x(&ar->winrct) + 1; ar->winy = BLI_rcti_size_y(&ar->winrct) + 1; + /* if region opened normally, we store this for hide/reveal usage */ + if (ar->winx > 1) ar->sizex = ar->winx; + if (ar->winy > 1) ar->sizey = ar->winy; + /* exception for multiple aligned overlapping regions on same spot */ if (ar->overlap) region_overlap_fix(ar); @@ -1298,6 +1302,8 @@ void region_toggle_hidden(bContext *C, ARegion *ar, int do_fade) ar->flag ^= RGN_FLAG_HIDDEN; + printf("%d\n", ar->winx); + if (do_fade && ar->overlap) { /* starts a timer, and in end calls the stuff below itself (region_sblend_invoke()) */ region_blend_start(C, sa, ar); From 9a2290cf5fcbd86f6a738d6aead3649796dc06f4 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sun, 16 Dec 2012 14:22:48 +0000 Subject: [PATCH 182/252] fix for bevel using the wrong property name when shift was held. --- source/blender/editors/mesh/editmesh_tools.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c index c04e74a717c..ec9da47c9ac 100644 --- a/source/blender/editors/mesh/editmesh_tools.c +++ b/source/blender/editors/mesh/editmesh_tools.c @@ -4950,9 +4950,9 @@ static float edbm_bevel_mval_factor(wmOperator *op, wmEvent *event) if (event->shift) { if (opdata->shift_factor < 0.0f) { #ifdef NEW_BEVEL - opdata->shift_factor = RNA_float_get(op->ptr, "factor"); -#else opdata->shift_factor = RNA_float_get(op->ptr, "percent"); +#else + opdata->shift_factor = RNA_float_get(op->ptr, "factor"); #endif } factor = (factor - opdata->shift_factor) * 0.1f + opdata->shift_factor; From 7b5784e37c8c6e1ea22d3307805e47d1a5ac947b Mon Sep 17 00:00:00 2001 From: Ton Roosendaal Date: Sun, 16 Dec 2012 14:50:50 +0000 Subject: [PATCH 183/252] Test print in bugfix... --- source/blender/editors/screen/area.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/source/blender/editors/screen/area.c b/source/blender/editors/screen/area.c index 766d114093e..d9fbfe4bd91 100644 --- a/source/blender/editors/screen/area.c +++ b/source/blender/editors/screen/area.c @@ -1302,8 +1302,6 @@ void region_toggle_hidden(bContext *C, ARegion *ar, int do_fade) ar->flag ^= RGN_FLAG_HIDDEN; - printf("%d\n", ar->winx); - if (do_fade && ar->overlap) { /* starts a timer, and in end calls the stuff below itself (region_sblend_invoke()) */ region_blend_start(C, sa, ar); From c5e46863a27c9a73d844d4dbdf72a37473bfb2f1 Mon Sep 17 00:00:00 2001 From: Miika Hamalainen Date: Sun, 16 Dec 2012 19:19:45 +0000 Subject: [PATCH 184/252] Fix [#33565]: Dynamic Paint modifier surfaces not copied Dynamic Paint canvas surfaces were not copied with modifier. --- .../blender/blenkernel/intern/dynamicpaint.c | 61 +++++++++++++++++++ 1 file changed, 61 insertions(+) diff --git a/source/blender/blenkernel/intern/dynamicpaint.c b/source/blender/blenkernel/intern/dynamicpaint.c index 38838fa8fca..56b9db94108 100644 --- a/source/blender/blenkernel/intern/dynamicpaint.c +++ b/source/blender/blenkernel/intern/dynamicpaint.c @@ -1193,7 +1193,68 @@ void dynamicPaint_Modifier_copy(struct DynamicPaintModifierData *pmd, struct Dyn /* Copy data */ if (tpmd->canvas) { + DynamicPaintSurface *surface; tpmd->canvas->pmd = tpmd; + /* free default surface */ + if (tpmd->canvas->surfaces.first) + dynamicPaint_freeSurface(tpmd->canvas->surfaces.first); + + /* copy existing surfaces */ + for (surface = pmd->canvas->surfaces.first; surface; surface = surface->next) { + DynamicPaintSurface *t_surface = dynamicPaint_createNewSurface(tpmd->canvas, NULL); + + /* surface settings */ + t_surface->brush_group = surface->brush_group; + MEM_freeN(t_surface->effector_weights); + t_surface->effector_weights = MEM_dupallocN(surface->effector_weights); + + BLI_strncpy(t_surface->name, surface->name, sizeof(t_surface->name)); + t_surface->format = surface->format; + t_surface->type = surface->type; + t_surface->disp_type = surface->disp_type; + t_surface->image_fileformat = surface->image_fileformat; + t_surface->effect_ui = surface->effect_ui; + t_surface->preview_id = surface->preview_id; + t_surface->init_color_type = surface->init_color_type; + t_surface->flags = surface->flags; + t_surface->effect = surface->effect; + + t_surface->image_resolution = surface->image_resolution; + t_surface->substeps = surface->substeps; + t_surface->start_frame = surface->start_frame; + t_surface->end_frame = surface->end_frame; + + copy_v4_v4(t_surface->init_color, surface->init_color); + t_surface->init_texture = surface->init_texture; + BLI_strncpy(t_surface->init_layername, surface->init_layername, sizeof(t_surface->init_layername)); + + t_surface->dry_speed = surface->dry_speed; + t_surface->diss_speed = surface->diss_speed; + t_surface->color_dry_threshold = surface->color_dry_threshold; + t_surface->depth_clamp = surface->depth_clamp; + t_surface->disp_factor = surface->disp_factor; + + + t_surface->spread_speed = surface->spread_speed; + t_surface->color_spread_speed = surface->color_spread_speed; + t_surface->shrink_speed = surface->shrink_speed; + t_surface->drip_vel = surface->drip_vel; + t_surface->drip_acc = surface->drip_acc; + + t_surface->influence_scale = surface->influence_scale; + t_surface->radius_scale = surface->radius_scale; + + t_surface->wave_damping = surface->wave_damping; + t_surface->wave_speed = surface->wave_speed; + t_surface->wave_timescale = surface->wave_timescale; + t_surface->wave_spring = surface->wave_spring; + + 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)); + BLI_strncpy(t_surface->output_name, surface->output_name, sizeof(t_surface->output_name)); + BLI_strncpy(t_surface->output_name2, surface->output_name2, sizeof(t_surface->output_name2)); + } + dynamicPaint_resetPreview(tpmd->canvas); } else if (tpmd->brush) { DynamicPaintBrushSettings *brush = pmd->brush, *t_brush = tpmd->brush; From f596cb272164dea576973d031f47d8d1c958dadf Mon Sep 17 00:00:00 2001 From: Howard Trickey Date: Mon, 17 Dec 2012 00:31:59 +0000 Subject: [PATCH 185/252] Fix knife cut-through bug #33571. The code to connect across a face didn't stop after it found one. --- source/blender/editors/mesh/editmesh_knife.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/blender/editors/mesh/editmesh_knife.c b/source/blender/editors/mesh/editmesh_knife.c index 189f5241a68..31d5eed83dc 100644 --- a/source/blender/editors/mesh/editmesh_knife.c +++ b/source/blender/editors/mesh/editmesh_knife.c @@ -720,7 +720,7 @@ static void knife_cut_through(KnifeTool_OpData *kcd) for (r = firstfaces.first; r; r = r->next) { f = r->ref; found = 0; - for (j = 0, lh2 = kcd->linehits; j < kcd->totlinehit; j++, lh2++) { + for (j = 0, lh2 = kcd->linehits; j < kcd->totlinehit && !found; j++, lh2++) { kfe2 = lh2->kfe; for (r2 = kfe2->faces.first; r2; r2 = r2->next) { if (r2->ref == f) { @@ -750,7 +750,7 @@ static void knife_cut_through(KnifeTool_OpData *kcd) for (r = kfe->faces.first; r; r = r->next) { f = r->ref; found = 0; - for (j = i + 1, lh2 = lh + 1; j < kcd->totlinehit; j++, lh2++) { + for (j = i + 1, lh2 = lh + 1; j < kcd->totlinehit && !found; j++, lh2++) { kfe2 = lh2->kfe; for (r2 = kfe2->faces.first; r2; r2 = r2->next) { if (r2->ref == f) { From bc0e1211de9765f0c1fc5196f3d72eff06cfb6d4 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 17 Dec 2012 00:39:03 +0000 Subject: [PATCH 186/252] fix [#33551] End Caps on a curve array with subsurf crashes blender when entering Edit Mode DM_to_bmesh_ex could merge a 'dm' into an existing BMesh, in that case CD_ORIGINDEX values needed to be set to ORIGINDEX_NONE. --- .../blenkernel/intern/modifiers_bmesh.c | 31 +++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) diff --git a/source/blender/blenkernel/intern/modifiers_bmesh.c b/source/blender/blenkernel/intern/modifiers_bmesh.c index 381e4350391..7df7561a1a1 100644 --- a/source/blender/blenkernel/intern/modifiers_bmesh.c +++ b/source/blender/blenkernel/intern/modifiers_bmesh.c @@ -40,7 +40,11 @@ #include "BKE_bmesh.h" #include "BKE_tessmesh.h" -/* main function for copying DerivedMesh data into BMesh */ +/** + * The main function for copying DerivedMesh data into BMesh. + * + * \note The mesh may already have geometry. see 'is_init' + */ void DM_to_bmesh_ex(DerivedMesh *dm, BMesh *bm) { MVert *mv, *mvert; @@ -56,6 +60,14 @@ void DM_to_bmesh_ex(DerivedMesh *dm, BMesh *bm) BLI_array_declare(edges); int i, j, k, totvert, totedge /* , totface */ /* UNUSED */ ; int is_init = (bm->totvert == 0) && (bm->totedge == 0) && (bm->totface == 0); + char has_orig_hflag = 0; + + if (is_init == FALSE) { + /* check if we have an origflag */ + has_orig_hflag |= CustomData_has_layer(&bm->vdata, CD_ORIGINDEX) ? BM_VERT : 0; + has_orig_hflag |= CustomData_has_layer(&bm->edata, CD_ORIGINDEX) ? BM_EDGE : 0; + has_orig_hflag |= CustomData_has_layer(&bm->pdata, CD_ORIGINDEX) ? BM_FACE : 0; + } /*merge custom data layout*/ CustomData_bmesh_merge(&dm->vertData, &bm->vdata, CD_MASK_DERIVEDMESH, CD_CALLOC, bm, BM_VERT); @@ -85,10 +97,15 @@ void DM_to_bmesh_ex(DerivedMesh *dm, BMesh *bm) BM_elem_index_set(v, i); /* set_inline */ CustomData_to_bmesh_block(&dm->vertData, &bm->vdata, i, &v->head.data); + vtable[i] = v; /* add bevel weight */ BM_elem_float_data_set(&bm->vdata, v, CD_BWEIGHT, (float)mv->bweight / 255.0f); - vtable[i] = v; + + if (UNLIKELY(has_orig_hflag & BM_VERT)) { + int *orig_index = CustomData_bmesh_get(&bm->vdata, v->head.data, CD_ORIGINDEX); + *orig_index = ORIGINDEX_NONE; + } } MEM_freeN(mvert); if (is_init) bm->elem_index_dirty &= ~BM_VERT; @@ -109,6 +126,11 @@ void DM_to_bmesh_ex(DerivedMesh *dm, BMesh *bm) BM_elem_float_data_set(&bm->edata, e, CD_CREASE, (float)me->crease / 255.0f); /* add bevel weight */ BM_elem_float_data_set(&bm->edata, e, CD_BWEIGHT, (float)me->bweight / 255.0f); + + if (UNLIKELY(has_orig_hflag & BM_EDGE)) { + int *orig_index = CustomData_bmesh_get(&bm->edata, e->head.data, CD_ORIGINDEX); + *orig_index = ORIGINDEX_NONE; + } } MEM_freeN(medge); if (is_init) bm->elem_index_dirty &= ~BM_EDGE; @@ -158,6 +180,11 @@ void DM_to_bmesh_ex(DerivedMesh *dm, BMesh *bm) else { BM_face_normal_update(f); } + + if (UNLIKELY(has_orig_hflag & BM_FACE)) { + int *orig_index = CustomData_bmesh_get(&bm->pdata, f->head.data, CD_ORIGINDEX); + *orig_index = ORIGINDEX_NONE; + } } if (is_init) bm->elem_index_dirty &= ~BM_FACE; From f9ec10688a634f446e5666eead66e865a1595b67 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 17 Dec 2012 02:34:53 +0000 Subject: [PATCH 187/252] fix [#33501] Grease pencil in OpenGL render With the view3d 'Render Only' option, grease pencil wouldn't draw, but for OpenGL render it did. Since grease pencil can be very useful in opengl renders, enable grease pencil drawing with 'Render Only' option in the viewport, and add a checkbox in the grease pencil header not to draw (unchecking each layer is annoying and applies to all spaces). --- source/blender/blenkernel/BKE_blender.h | 2 +- source/blender/blenloader/intern/readfile.c | 44 +++++++++++++++++++ .../blender/editors/gpencil/gpencil_buttons.c | 7 +++ source/blender/editors/include/ED_gpencil.h | 1 + .../blender/editors/space_clip/clip_buttons.c | 1 + .../blender/editors/space_clip/space_clip.c | 14 +++--- .../editors/space_image/image_buttons.c | 1 + .../blender/editors/space_image/space_image.c | 13 ++++-- .../blender/editors/space_node/node_buttons.c | 1 + source/blender/editors/space_node/node_draw.c | 18 +++++--- .../blender/editors/space_node/space_node.c | 2 + .../space_sequencer/sequencer_buttons.c | 1 + .../editors/space_sequencer/sequencer_draw.c | 13 +++--- .../editors/space_sequencer/space_sequencer.c | 5 ++- .../editors/space_view3d/space_view3d.c | 11 ++--- .../editors/space_view3d/view3d_buttons.c | 1 + .../editors/space_view3d/view3d_draw.c | 30 ++++++++----- source/blender/makesdna/DNA_space_types.h | 7 +-- source/blender/makesdna/DNA_view3d_types.h | 3 +- source/blender/makesrna/intern/rna_space.c | 25 +++++++++++ 20 files changed, 155 insertions(+), 45 deletions(-) diff --git a/source/blender/blenkernel/BKE_blender.h b/source/blender/blenkernel/BKE_blender.h index 980514608f3..570086e9b69 100644 --- a/source/blender/blenkernel/BKE_blender.h +++ b/source/blender/blenkernel/BKE_blender.h @@ -42,7 +42,7 @@ extern "C" { * and keep comment above the defines. * Use STRINGIFY() rather than defining with quotes */ #define BLENDER_VERSION 265 -#define BLENDER_SUBVERSION 2 +#define BLENDER_SUBVERSION 3 /* 262 was the last editmesh release but it has compatibility code for bmesh data */ #define BLENDER_MINVERSION 262 diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index cf4deb7213d..0d40ad9d4cd 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -8365,6 +8365,50 @@ static void do_versions(FileData *fd, Library *lib, Main *main) } } + if (main->versionfile < 265 || (main->versionfile == 265 && main->subversionfile < 3)) { + bScreen *sc; + for (sc = main->screen.first; sc; sc = sc->id.next) { + ScrArea *sa; + for (sa = sc->areabase.first; sa; sa = sa->next) { + SpaceLink *sl; + for (sl = sa->spacedata.first; sl; sl = sl->next) { + switch (sl->spacetype) { + case SPACE_VIEW3D: + { + View3D *v3d = (View3D *)sl; + v3d->flag2 |= V3D_SHOW_GPENCIL; + break; + } + case SPACE_SEQ: + { + SpaceSeq *sseq = (SpaceSeq *)sl; + sseq->flag |= SEQ_SHOW_GPENCIL; + break; + } + case SPACE_IMAGE: + { + SpaceImage *sima = (SpaceImage *)sl; + sima->flag |= SI_SHOW_GPENCIL; + break; + } + case SPACE_NODE: + { + SpaceNode *snode = (SpaceNode *)sl; + snode->flag |= SNODE_SHOW_GPENCIL; + break; + } + case SPACE_CLIP: + { + SpaceClip *sclip = (SpaceClip *)sl; + sclip->flag |= SC_SHOW_GPENCIL; + break; + } + } + } + } + } + } + /* WATCH IT!!!: pointers from libdata have not been converted yet here! */ /* WATCH IT 2!: Userdef struct init has to be in editors/interface/resources.c! */ diff --git a/source/blender/editors/gpencil/gpencil_buttons.c b/source/blender/editors/gpencil/gpencil_buttons.c index 8a3c996a481..0aa109a0aef 100644 --- a/source/blender/editors/gpencil/gpencil_buttons.c +++ b/source/blender/editors/gpencil/gpencil_buttons.c @@ -312,6 +312,13 @@ static void draw_gpencil_panel(bContext *C, uiLayout *layout, bGPdata *gpd, Poin } } +void gpencil_panel_standard_header(const bContext *C, Panel *pa) +{ + PointerRNA ptr; + RNA_pointer_create((ID *)CTX_wm_screen(C), &RNA_Space, CTX_wm_space_data(C), &ptr); + + uiItemR(pa->layout, &ptr, "show_grease_pencil", 0, "", ICON_NONE); +} /* Standard panel to be included wherever Grease Pencil is used... */ void gpencil_panel_standard(const bContext *C, Panel *pa) diff --git a/source/blender/editors/include/ED_gpencil.h b/source/blender/editors/include/ED_gpencil.h index 5cc1ecade3e..29d4097521d 100644 --- a/source/blender/editors/include/ED_gpencil.h +++ b/source/blender/editors/include/ED_gpencil.h @@ -81,6 +81,7 @@ void draw_gpencil_2dimage(const struct bContext *C); void draw_gpencil_view2d(const struct bContext *C, short onlyv2d); void draw_gpencil_view3d(struct Scene *scene, struct View3D *v3d, struct ARegion *ar, short only3d); +void gpencil_panel_standard_header(const struct bContext *C, struct Panel *pa); void gpencil_panel_standard(const struct bContext *C, struct Panel *pa); /* ----------- Grease-Pencil AnimEdit API ------------------ */ diff --git a/source/blender/editors/space_clip/clip_buttons.c b/source/blender/editors/space_clip/clip_buttons.c index 969b0e25928..2cb6d8c9234 100644 --- a/source/blender/editors/space_clip/clip_buttons.c +++ b/source/blender/editors/space_clip/clip_buttons.c @@ -78,6 +78,7 @@ void ED_clip_buttons_register(ARegionType *art) pt = MEM_callocN(sizeof(PanelType), "spacetype clip panel gpencil"); strcpy(pt->idname, "CLIP_PT_gpencil"); strcpy(pt->label, "Grease Pencil"); + pt->draw_header = gpencil_panel_standard_header; pt->draw = gpencil_panel_standard; pt->flag |= PNL_DEFAULT_CLOSED; pt->poll = clip_grease_pencil_panel_poll; diff --git a/source/blender/editors/space_clip/space_clip.c b/source/blender/editors/space_clip/space_clip.c index 7befa490d41..dc7b6d77c9e 100644 --- a/source/blender/editors/space_clip/space_clip.c +++ b/source/blender/editors/space_clip/space_clip.c @@ -246,7 +246,7 @@ static SpaceLink *clip_new(const bContext *C) sc = MEM_callocN(sizeof(SpaceClip), "initclip"); sc->spacetype = SPACE_CLIP; sc->flag = SC_SHOW_MARKER_PATTERN | SC_SHOW_TRACK_PATH | SC_MANUAL_CALIBRATION | - SC_SHOW_GRAPH_TRACKS | SC_SHOW_GRAPH_FRAMES; + SC_SHOW_GRAPH_TRACKS | SC_SHOW_GRAPH_FRAMES | SC_SHOW_GPENCIL; sc->zoom = 1.0f; sc->path_length = 20; sc->scopes.track_preview_height = 120; @@ -1151,14 +1151,18 @@ static void clip_main_area_draw(const bContext *C, ARegion *ar) } - /* Grease Pencil */ - clip_draw_grease_pencil((bContext *)C, 1); + if (sc->flag & SC_SHOW_GPENCIL) { + /* Grease Pencil */ + clip_draw_grease_pencil((bContext *)C, TRUE); + } /* reset view matrix */ UI_view2d_view_restore(C); - /* draw Grease Pencil - screen space only */ - clip_draw_grease_pencil((bContext *)C, 0); + if (sc->flag & SC_SHOW_GPENCIL) { + /* draw Grease Pencil - screen space only */ + clip_draw_grease_pencil((bContext *)C, FALSE); + } } static void clip_main_area_listener(ARegion *ar, wmNotifier *wmn) diff --git a/source/blender/editors/space_image/image_buttons.c b/source/blender/editors/space_image/image_buttons.c index 0a3db59096a..d02186e59dd 100644 --- a/source/blender/editors/space_image/image_buttons.c +++ b/source/blender/editors/space_image/image_buttons.c @@ -858,6 +858,7 @@ void image_buttons_register(ARegionType *art) pt = MEM_callocN(sizeof(PanelType), "spacetype image panel gpencil"); strcpy(pt->idname, "IMAGE_PT_gpencil"); strcpy(pt->label, "Grease Pencil"); + pt->draw_header = gpencil_panel_standard_header; pt->draw = gpencil_panel_standard; BLI_addtail(&art->paneltypes, pt); } diff --git a/source/blender/editors/space_image/space_image.c b/source/blender/editors/space_image/space_image.c index 5616c025407..b0e9f8bcf99 100644 --- a/source/blender/editors/space_image/space_image.c +++ b/source/blender/editors/space_image/space_image.c @@ -151,6 +151,7 @@ static SpaceLink *image_new(const bContext *UNUSED(C)) simage->spacetype = SPACE_IMAGE; simage->zoom = 1.0f; simage->lock = TRUE; + simage->flag = SI_SHOW_GPENCIL; simage->iuser.ok = TRUE; simage->iuser.fie_ima = 2; @@ -674,16 +675,20 @@ static void image_main_area_draw(const bContext *C, ARegion *ar) ED_region_draw_cb_draw(C, ar, REGION_DRAW_POST_VIEW); - /* Grease Pencil too (in addition to UV's) */ - draw_image_grease_pencil((bContext *)C, 1); + if (sima->flag & SI_SHOW_GPENCIL) { + /* Grease Pencil too (in addition to UV's) */ + draw_image_grease_pencil((bContext *)C, TRUE); + } /* sample line */ draw_image_sample_line(sima); UI_view2d_view_restore(C); - /* draw Grease Pencil - screen space only */ - draw_image_grease_pencil((bContext *)C, 0); + if (sima->flag & SI_SHOW_GPENCIL) { + /* draw Grease Pencil - screen space only */ + draw_image_grease_pencil((bContext *)C, FALSE); + } if (mask) { int width, height; diff --git a/source/blender/editors/space_node/node_buttons.c b/source/blender/editors/space_node/node_buttons.c index da077d93641..300328f5fd4 100644 --- a/source/blender/editors/space_node/node_buttons.c +++ b/source/blender/editors/space_node/node_buttons.c @@ -184,6 +184,7 @@ void node_buttons_register(ARegionType *art) pt = MEM_callocN(sizeof(PanelType), "spacetype node panel gpencil"); strcpy(pt->idname, "NODE_PT_gpencil"); strcpy(pt->label, "Grease Pencil"); + pt->draw_header = gpencil_panel_standard_header; pt->draw = gpencil_panel_standard; pt->poll = active_nodetree_poll; BLI_addtail(&art->paneltypes, pt); diff --git a/source/blender/editors/space_node/node_draw.c b/source/blender/editors/space_node/node_draw.c index 704bc70fa01..e1d5e4200b8 100644 --- a/source/blender/editors/space_node/node_draw.c +++ b/source/blender/editors/space_node/node_draw.c @@ -1172,16 +1172,22 @@ void drawnodespace(const bContext *C, ARegion *ar, View2D *v2d) ED_region_draw_cb_draw(C, ar, REGION_DRAW_POST_VIEW); - /* draw grease-pencil ('canvas' strokes) */ - if (snode->nodetree) - draw_gpencil_view2d(C, 1); + if (snode->flag & SNODE_SHOW_GPENCIL) { + /* draw grease-pencil ('canvas' strokes) */ + if (snode->nodetree) { + draw_gpencil_view2d(C, TRUE); + } + } /* reset view matrix */ UI_view2d_view_restore(C); - /* draw grease-pencil (screen strokes, and also paintbuffer) */ - if (snode->nodetree) - draw_gpencil_view2d(C, 0); + if (snode->flag & SNODE_SHOW_GPENCIL) { + /* draw grease-pencil (screen strokes, and also paintbuffer) */ + if (snode->nodetree) { + draw_gpencil_view2d(C, FALSE); + } + } /* scrollers */ scrollers = UI_view2d_scrollers_calc(C, v2d, 10, V2D_GRID_CLAMP, V2D_ARG_DUMMY, V2D_ARG_DUMMY); diff --git a/source/blender/editors/space_node/space_node.c b/source/blender/editors/space_node/space_node.c index fe880a7592b..513f6b43e9a 100644 --- a/source/blender/editors/space_node/space_node.c +++ b/source/blender/editors/space_node/space_node.c @@ -119,6 +119,8 @@ static SpaceLink *node_new(const bContext *UNUSED(C)) snode = MEM_callocN(sizeof(SpaceNode), "initnode"); snode->spacetype = SPACE_NODE; + snode->flag = SNODE_SHOW_GPENCIL; + /* backdrop */ snode->zoom = 1.0f; diff --git a/source/blender/editors/space_sequencer/sequencer_buttons.c b/source/blender/editors/space_sequencer/sequencer_buttons.c index 7dbcabedccc..bd4bb0896ed 100644 --- a/source/blender/editors/space_sequencer/sequencer_buttons.c +++ b/source/blender/editors/space_sequencer/sequencer_buttons.c @@ -58,6 +58,7 @@ void sequencer_buttons_register(ARegionType *art) pt = MEM_callocN(sizeof(PanelType), "spacetype sequencer panel gpencil"); strcpy(pt->idname, "SEQUENCER_PT_gpencil"); strcpy(pt->label, N_("Grease Pencil")); + pt->draw_header = gpencil_panel_standard_header; pt->draw = gpencil_panel_standard; BLI_addtail(&art->paneltypes, pt); } diff --git a/source/blender/editors/space_sequencer/sequencer_draw.c b/source/blender/editors/space_sequencer/sequencer_draw.c index 1a84efa0b50..9cc6b3d07a2 100644 --- a/source/blender/editors/space_sequencer/sequencer_draw.c +++ b/source/blender/editors/space_sequencer/sequencer_draw.c @@ -1125,8 +1125,10 @@ void draw_image_seq(const bContext *C, Scene *scene, ARegion *ar, SpaceSeq *sseq setlinestyle(0); } - /* draw grease-pencil (image aligned) */ - draw_gpencil_2dimage(C); + if (sseq->flag & SEQ_SHOW_GPENCIL) { + /* draw grease-pencil (image aligned) */ + draw_gpencil_2dimage(C); + } if (!scope) IMB_freeImBuf(ibuf); @@ -1134,9 +1136,10 @@ void draw_image_seq(const bContext *C, Scene *scene, ARegion *ar, SpaceSeq *sseq /* ortho at pixel level */ UI_view2d_view_restore(C); - /* draw grease-pencil (screen aligned) */ - draw_gpencil_view2d(C, 0); - + if (sseq->flag & SEQ_SHOW_GPENCIL) { + /* draw grease-pencil (screen aligned) */ + draw_gpencil_view2d(C, 0); + } /* NOTE: sequencer mask editing isnt finished, the draw code is working but editing not, diff --git a/source/blender/editors/space_sequencer/space_sequencer.c b/source/blender/editors/space_sequencer/space_sequencer.c index e8d47016608..436b649f3b1 100644 --- a/source/blender/editors/space_sequencer/space_sequencer.c +++ b/source/blender/editors/space_sequencer/space_sequencer.c @@ -120,6 +120,8 @@ static SpaceLink *sequencer_new(const bContext *C) sseq->chanshown = 0; sseq->view = SEQ_VIEW_SEQUENCE; sseq->mainb = SEQ_DRAW_IMG_IMBUF; + sseq->flag = SEQ_SHOW_GPENCIL; + /* header */ ar = MEM_callocN(sizeof(ARegion), "header for sequencer"); @@ -306,8 +308,7 @@ static void sequencer_refresh(const bContext *C, ScrArea *sa) } } -static SpaceLink *sequencer_duplicate(SpaceLink *sl) -{ +static SpaceLink *sequencer_duplicate(SpaceLink *sl){ SpaceSeq *sseqn = MEM_dupallocN(sl); /* clear or remove stuff from old */ diff --git a/source/blender/editors/space_view3d/space_view3d.c b/source/blender/editors/space_view3d/space_view3d.c index 9faefbd4c2b..325e502f620 100644 --- a/source/blender/editors/space_view3d/space_view3d.c +++ b/source/blender/editors/space_view3d/space_view3d.c @@ -261,14 +261,11 @@ static SpaceLink *view3d_new(const bContext *C) v3d->gridlines = 16; v3d->gridsubdiv = 10; v3d->drawtype = OB_SOLID; + + v3d->gridflag = V3D_SHOW_X | V3D_SHOW_Y | V3D_SHOW_FLOOR; - v3d->gridflag |= V3D_SHOW_X; - v3d->gridflag |= V3D_SHOW_Y; - v3d->gridflag |= V3D_SHOW_FLOOR; - v3d->gridflag &= ~V3D_SHOW_Z; - - v3d->flag |= V3D_SELECT_OUTLINE; - v3d->flag2 |= V3D_SHOW_RECONSTRUCTION; + v3d->flag = V3D_SELECT_OUTLINE; + v3d->flag2 = V3D_SHOW_RECONSTRUCTION | V3D_SHOW_GPENCIL; v3d->lens = 35.0f; v3d->near = 0.01f; diff --git a/source/blender/editors/space_view3d/view3d_buttons.c b/source/blender/editors/space_view3d/view3d_buttons.c index 2d981f92af2..6a095a8d2b1 100644 --- a/source/blender/editors/space_view3d/view3d_buttons.c +++ b/source/blender/editors/space_view3d/view3d_buttons.c @@ -1260,6 +1260,7 @@ void view3d_buttons_register(ARegionType *art) pt = MEM_callocN(sizeof(PanelType), "spacetype view3d panel gpencil"); strcpy(pt->idname, "VIEW3D_PT_gpencil"); strcpy(pt->label, "Grease Pencil"); + pt->draw_header = gpencil_panel_standard_header; pt->draw = gpencil_panel_standard; BLI_addtail(&art->paneltypes, pt); diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c index 31bfd9f45e0..7fccff861ab 100644 --- a/source/blender/editors/space_view3d/view3d_draw.c +++ b/source/blender/editors/space_view3d/view3d_draw.c @@ -2169,7 +2169,9 @@ void draw_depth_gpencil(Scene *scene, ARegion *ar, View3D *v3d) v3d->zbuf = TRUE; glEnable(GL_DEPTH_TEST); - draw_gpencil_view3d(scene, v3d, ar, 1); + if (v3d->flag2 & V3D_SHOW_GPENCIL) { + draw_gpencil_view3d(scene, v3d, ar, TRUE); + } v3d->zbuf = zbuf; @@ -2649,9 +2651,11 @@ void ED_view3d_draw_offscreen(Scene *scene, View3D *v3d, ARegion *ar, } /* must be before xray draw which clears the depth buffer */ - if (v3d->zbuf) glDisable(GL_DEPTH_TEST); - draw_gpencil_view3d(scene, v3d, ar, 1); - if (v3d->zbuf) glEnable(GL_DEPTH_TEST); + if (v3d->flag2 & V3D_SHOW_GPENCIL) { + if (v3d->zbuf) glDisable(GL_DEPTH_TEST); + draw_gpencil_view3d(scene, v3d, ar, TRUE); + if (v3d->zbuf) glEnable(GL_DEPTH_TEST); + } /* transp and X-ray afterdraw stuff */ if (v3d->afterdraw_transp.first) view3d_draw_transp(scene, ar, v3d); @@ -2675,8 +2679,11 @@ void ED_view3d_draw_offscreen(Scene *scene, View3D *v3d, ARegion *ar, /* draw grease-pencil stuff */ ED_region_pixelspace(ar); - /* draw grease-pencil stuff - needed to get paint-buffer shown too (since it's 2D) */ - draw_gpencil_view3d(scene, v3d, ar, 0); + + if (v3d->flag2 & V3D_SHOW_GPENCIL) { + /* draw grease-pencil stuff - needed to get paint-buffer shown too (since it's 2D) */ + draw_gpencil_view3d(scene, v3d, ar, FALSE); + } /* freeing the images again here could be done after the operator runs, leaving for now */ GPU_free_images_anim(); @@ -3109,10 +3116,10 @@ static void view3d_main_area_draw_objects(const bContext *C, ARegion *ar, const // REEB_draw(); - if ((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) { + if (v3d->flag2 & V3D_SHOW_GPENCIL) { /* must be before xray draw which clears the depth buffer */ if (v3d->zbuf) glDisable(GL_DEPTH_TEST); - draw_gpencil_view3d(scene, v3d, ar, 1); + draw_gpencil_view3d(scene, v3d, ar, TRUE); if (v3d->zbuf) glEnable(GL_DEPTH_TEST); } @@ -3178,9 +3185,10 @@ static void view3d_main_area_draw_info(const bContext *C, ARegion *ar, const cha if ((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) { Object *ob; - /* draw grease-pencil stuff - needed to get paint-buffer shown too (since it's 2D) */ - // if (v3d->flag2 & V3D_DISPGP) - draw_gpencil_view3d(scene, v3d, ar, 0); + if (v3d->flag2 & V3D_SHOW_GPENCIL) { + /* draw grease-pencil stuff - needed to get paint-buffer shown too (since it's 2D) */ + draw_gpencil_view3d(scene, v3d, ar, FALSE); + } drawcursor(scene, ar, v3d); diff --git a/source/blender/makesdna/DNA_space_types.h b/source/blender/makesdna/DNA_space_types.h index 9ef18f31f29..2e4ecba98c3 100644 --- a/source/blender/makesdna/DNA_space_types.h +++ b/source/blender/makesdna/DNA_space_types.h @@ -496,6 +496,7 @@ typedef enum eSpaceSeq_Flag { SEQ_DRAW_SAFE_MARGINS = (1 << 3), /* SEQ_DRAW_GPENCIL = (1 << 4), */ /* DEPRECATED */ SEQ_NO_DRAW_CFRANUM = (1 << 5), + SEQ_SHOW_GPENCIL = (1 << 6), } eSpaceSeq_Flag; /* sseq->view */ @@ -776,7 +777,7 @@ typedef enum eSpaceImage_Flag { SI_DRAW_TILE = (1 << 19), SI_SMOOTH_UV = (1 << 20), SI_DRAW_STRETCH = (1 << 21), -/* SI_DISPGP = (1 << 22), */ /* deprecated */ + SI_SHOW_GPENCIL = (1 << 22), SI_DRAW_OTHER = (1 << 23), SI_COLOR_CORRECTION = (1 << 24), @@ -907,7 +908,7 @@ typedef struct SpaceNode { /* snode->flag */ typedef enum eSpaceNode_Flag { SNODE_BACKDRAW = (1 << 1), -/* SNODE_DISPGP = (1 << 2), */ /* XXX: Grease Pencil - deprecated? */ + SNODE_SHOW_GPENCIL = (1 << 2), SNODE_USE_ALPHA = (1 << 3), SNODE_SHOW_ALPHA = (1 << 4), SNODE_SHOW_R = (1 << 7), @@ -1061,7 +1062,7 @@ typedef enum eSpaceClip_Flag { SC_SHOW_GRID = (1 << 9), SC_SHOW_STABLE = (1 << 10), SC_MANUAL_CALIBRATION = (1 << 11), -/* SC_SHOW_GPENCIL = (1 << 12),*/ /* UNUSED */ + SC_SHOW_GPENCIL = (1 << 12), SC_SHOW_FILTERS = (1 << 13), SC_SHOW_GRAPH_FRAMES = (1 << 14), SC_SHOW_GRAPH_TRACKS = (1 << 15), diff --git a/source/blender/makesdna/DNA_view3d_types.h b/source/blender/makesdna/DNA_view3d_types.h index c83b0bc366f..dbe54a4fcdf 100644 --- a/source/blender/makesdna/DNA_view3d_types.h +++ b/source/blender/makesdna/DNA_view3d_types.h @@ -225,6 +225,7 @@ typedef struct View3D { #define V3D_DISPBGPICS 2 #define V3D_HIDE_HELPLINES 4 #define V3D_INVALID_BACKBUF 8 +#define V3D_INVALID_BACKBUF 8 #define V3D_ALIGN 1024 #define V3D_SELECT_OUTLINE 2048 @@ -261,7 +262,7 @@ typedef struct View3D { /* View3d->flag2 (short) */ #define V3D_RENDER_OVERRIDE 4 #define V3D_SOLID_TEX 8 -#define V3D_DISPGP 16 +#define V3D_SHOW_GPENCIL 16 #define V3D_LOCK_CAMERA 32 #define V3D_RENDER_SHADOW 64 /* This is a runtime only flag that's used to tell draw_mesh_object() that we're doing a shadow pass instead of a regular draw */ #define V3D_SHOW_RECONSTRUCTION 128 diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c index 32208c8c819..a59cfc46c37 100644 --- a/source/blender/makesrna/intern/rna_space.c +++ b/source/blender/makesrna/intern/rna_space.c @@ -1659,6 +1659,12 @@ static void rna_def_space_view3d(BlenderRNA *brna) "Show dashed lines indicating parent or constraint relationships"); RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL); + prop = RNA_def_property(srna, "show_grease_pencil", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag2", V3D_SHOW_GPENCIL); + RNA_def_property_ui_text(prop, "Show Grease Pencil", + "Show grease pencil for this view"); + RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL); + prop = RNA_def_property(srna, "show_textured_solid", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag2", V3D_SOLID_TEX); RNA_def_property_ui_text(prop, "Textured Solid", "Display face-assigned textures in solid view"); @@ -2044,6 +2050,12 @@ static void rna_def_space_image(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Draw Repeated", "Draw the image repeated outside of the main view"); RNA_def_property_update(prop, NC_SPACE | ND_SPACE_IMAGE, NULL); + prop = RNA_def_property(srna, "show_grease_pencil", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", SI_SHOW_GPENCIL); + RNA_def_property_ui_text(prop, "Show Grease Pencil", + "Show grease pencil for this view"); + RNA_def_property_update(prop, NC_SPACE | ND_SPACE_IMAGE, NULL); + prop = RNA_def_property(srna, "draw_channels", PROP_ENUM, PROP_NONE); RNA_def_property_enum_bitflag_sdna(prop, NULL, "flag"); RNA_def_property_enum_items(prop, draw_channels_items); @@ -2209,6 +2221,12 @@ static void rna_def_space_sequencer(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Show Seconds", "Show timing in seconds not frames"); RNA_def_property_update(prop, NC_SPACE | ND_SPACE_SEQUENCER, NULL); + prop = RNA_def_property(srna, "show_grease_pencil", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", SEQ_SHOW_GPENCIL); + RNA_def_property_ui_text(prop, "Show Grease Pencil", + "Show grease pencil for this view"); + RNA_def_property_update(prop, NC_SPACE | ND_SPACE_SEQUENCER, NULL); + prop = RNA_def_property(srna, "display_channel", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, NULL, "chanshown"); RNA_def_property_ui_text(prop, "Display Channel", @@ -3302,6 +3320,13 @@ static void rna_def_space_clip(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Manual Calibration", "Use manual calibration helpers"); RNA_def_property_update(prop, NC_SPACE | ND_SPACE_CLIP, NULL); + /* show grease pencil */ + prop = RNA_def_property(srna, "show_grease_pencil", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", SC_SHOW_GPENCIL); + RNA_def_property_ui_text(prop, "Show Grease Pencil", + "Show grease pencil for this view"); + RNA_def_property_update(prop, NC_SPACE | ND_SPACE_CLIP, NULL); + /* show filters */ prop = RNA_def_property(srna, "show_filters", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", SC_SHOW_FILTERS); From 519378fca6fb3982568ab975c904658954e44c7f Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 17 Dec 2012 02:46:30 +0000 Subject: [PATCH 188/252] patch [#33441] Remove unneeded strcpy()'s from makesdna.c --- source/blender/makesdna/DNA_space_types.h | 3 +-- source/blender/makesdna/intern/makesdna.c | 27 +++++++++-------------- 2 files changed, 12 insertions(+), 18 deletions(-) diff --git a/source/blender/makesdna/DNA_space_types.h b/source/blender/makesdna/DNA_space_types.h index 2e4ecba98c3..d632a886130 100644 --- a/source/blender/makesdna/DNA_space_types.h +++ b/source/blender/makesdna/DNA_space_types.h @@ -494,9 +494,8 @@ typedef enum eSpaceSeq_Flag { SEQ_MARKER_TRANS = (1 << 1), SEQ_DRAW_COLOR_SEPARATED = (1 << 2), SEQ_DRAW_SAFE_MARGINS = (1 << 3), -/* SEQ_DRAW_GPENCIL = (1 << 4), */ /* DEPRECATED */ + SEQ_SHOW_GPENCIL = (1 << 4), SEQ_NO_DRAW_CFRANUM = (1 << 5), - SEQ_SHOW_GPENCIL = (1 << 6), } eSpaceSeq_Flag; /* sseq->view */ diff --git a/source/blender/makesdna/intern/makesdna.c b/source/blender/makesdna/intern/makesdna.c index e02a9bfe56a..e131cde8b27 100644 --- a/source/blender/makesdna/intern/makesdna.c +++ b/source/blender/makesdna/intern/makesdna.c @@ -208,7 +208,7 @@ static int calculate_structlens(int); /** * Construct the DNA.c file */ -void dna_write(FILE *file, void *pntr, int size); +static void dna_write(FILE *file, const void *pntr, const int size); /** * Report all structures found so far, and print their lengths. @@ -892,7 +892,7 @@ static int calculate_structlens(int firststruct) #define MAX_DNA_LINE_LENGTH 20 -void dna_write(FILE *file, void *pntr, int size) +static void dna_write(FILE *file, const void *pntr, const int size) { static int linelength = 0; int i; @@ -934,7 +934,7 @@ void printStructLengths(void) } -static int make_structDNA(char *baseDirectory, FILE *file) +static int make_structDNA(const char *baseDirectory, FILE *file) { int len, i; short *sp; @@ -1036,12 +1036,10 @@ static int make_structDNA(char *baseDirectory, FILE *file) /* pass */ } else { - strcpy(str, "SDNA"); - dna_write(file, str, 4); + dna_write(file, "SDNA", 4); /* write names */ - strcpy(str, "NAME"); - dna_write(file, str, 4); + dna_write(file, "NAME", 4); len = nr_names; dna_write(file, &len, 4); @@ -1053,8 +1051,7 @@ static int make_structDNA(char *baseDirectory, FILE *file) dna_write(file, names[0], len); /* write TYPES */ - strcpy(str, "TYPE"); - dna_write(file, str, 4); + dna_write(file, "TYPE", 4); len = nr_types; dna_write(file, &len, 4); @@ -1067,16 +1064,14 @@ static int make_structDNA(char *baseDirectory, FILE *file) dna_write(file, types[0], len); /* WRITE TYPELENGTHS */ - strcpy(str, "TLEN"); - dna_write(file, str, 4); + dna_write(file, "TLEN", 4); len = 2 * nr_types; if (nr_types & 1) len += 2; dna_write(file, typelens_native, len); /* WRITE STRUCTS */ - strcpy(str, "STRC"); - dna_write(file, str, 4); + dna_write(file, "STRC", 4); len = nr_structs; dna_write(file, &len, 4); @@ -1165,13 +1160,13 @@ int main(int argc, char **argv) return_status = 1; } else { - char baseDirectory[256]; + const char *baseDirectory; if (argc == 3) { - strcpy(baseDirectory, argv[2]); + baseDirectory = argv[2]; } else { - strcpy(baseDirectory, BASE_HEADER); + baseDirectory = BASE_HEADER; } fprintf(file, "const unsigned char DNAstr[] = {\n"); From fe006c042661586a03d27ad5418ca373bfa48e45 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 17 Dec 2012 04:44:39 +0000 Subject: [PATCH 189/252] don't draw the sequencer grease pencil panel when in the channel view or scopes. also don't draw grease pencil over scopes. --- source/blender/editors/include/ED_sequencer.h | 2 ++ .../editors/space_sequencer/sequencer_buttons.c | 10 ++++++++++ .../editors/space_sequencer/sequencer_draw.c | 14 ++++++++++---- .../editors/space_sequencer/sequencer_edit.c | 7 +++++++ 4 files changed, 29 insertions(+), 4 deletions(-) diff --git a/source/blender/editors/include/ED_sequencer.h b/source/blender/editors/include/ED_sequencer.h index 84fd5332316..23d173aebdc 100644 --- a/source/blender/editors/include/ED_sequencer.h +++ b/source/blender/editors/include/ED_sequencer.h @@ -38,6 +38,8 @@ int ED_space_sequencer_maskedit_mask_poll(struct bContext *C); int ED_space_sequencer_check_show_maskedit(struct SpaceSeq *sseq, struct Scene *scene); int ED_space_sequencer_maskedit_poll(struct bContext *C); +int ED_space_sequencer_check_show_imbuf(struct SpaceSeq *sseq); + void ED_operatormacros_sequencer(void); #endif /* __ED_SEQUENCER_H__ */ diff --git a/source/blender/editors/space_sequencer/sequencer_buttons.c b/source/blender/editors/space_sequencer/sequencer_buttons.c index bd4bb0896ed..21128408a97 100644 --- a/source/blender/editors/space_sequencer/sequencer_buttons.c +++ b/source/blender/editors/space_sequencer/sequencer_buttons.c @@ -41,6 +41,7 @@ #include "ED_screen.h" #include "ED_gpencil.h" +#include "ED_sequencer.h" #include "WM_api.h" #include "WM_types.h" @@ -51,6 +52,14 @@ /* **************************** buttons ********************************* */ +static int sequencer_grease_pencil_panel_poll(const bContext *C, PanelType *UNUSED(pt)) +{ + SpaceSeq *sseq = CTX_wm_space_seq(C); + + /* don't show the gpencil if we are not showing the image */ + return ED_space_sequencer_check_show_imbuf(sseq); +} + void sequencer_buttons_register(ARegionType *art) { PanelType *pt; @@ -60,6 +69,7 @@ void sequencer_buttons_register(ARegionType *art) strcpy(pt->label, N_("Grease Pencil")); pt->draw_header = gpencil_panel_standard_header; pt->draw = gpencil_panel_standard; + pt->poll = sequencer_grease_pencil_panel_poll; BLI_addtail(&art->paneltypes, pt); } diff --git a/source/blender/editors/space_sequencer/sequencer_draw.c b/source/blender/editors/space_sequencer/sequencer_draw.c index 9cc6b3d07a2..e3db9c23c41 100644 --- a/source/blender/editors/space_sequencer/sequencer_draw.c +++ b/source/blender/editors/space_sequencer/sequencer_draw.c @@ -62,6 +62,7 @@ #include "ED_gpencil.h" #include "ED_markers.h" #include "ED_mask.h" +#include "ED_sequencer.h" #include "ED_types.h" #include "ED_space_api.h" @@ -921,6 +922,7 @@ void draw_image_seq(const bContext *C, Scene *scene, ARegion *ar, SpaceSeq *sseq GLuint last_texid; unsigned char *display_buffer; void *cache_handle = NULL; + const int is_imbuf = ED_space_sequencer_check_show_imbuf(sseq); if (G.is_rendering == FALSE) { /* stop all running jobs, except screen one. currently previews frustrate Render @@ -1126,8 +1128,10 @@ void draw_image_seq(const bContext *C, Scene *scene, ARegion *ar, SpaceSeq *sseq } if (sseq->flag & SEQ_SHOW_GPENCIL) { - /* draw grease-pencil (image aligned) */ - draw_gpencil_2dimage(C); + if (is_imbuf) { + /* draw grease-pencil (image aligned) */ + draw_gpencil_2dimage(C); + } } if (!scope) @@ -1137,8 +1141,10 @@ void draw_image_seq(const bContext *C, Scene *scene, ARegion *ar, SpaceSeq *sseq UI_view2d_view_restore(C); if (sseq->flag & SEQ_SHOW_GPENCIL) { - /* draw grease-pencil (screen aligned) */ - draw_gpencil_view2d(C, 0); + if (is_imbuf) { + /* draw grease-pencil (screen aligned) */ + draw_gpencil_view2d(C, 0); + } } diff --git a/source/blender/editors/space_sequencer/sequencer_edit.c b/source/blender/editors/space_sequencer/sequencer_edit.c index e7f77db3b9e..409f655bb79 100644 --- a/source/blender/editors/space_sequencer/sequencer_edit.c +++ b/source/blender/editors/space_sequencer/sequencer_edit.c @@ -496,6 +496,13 @@ int ED_space_sequencer_maskedit_poll(bContext *C) return FALSE; } +/* are we displaying the seq output (not channels or histogram)*/ +int ED_space_sequencer_check_show_imbuf(SpaceSeq *sseq) +{ + return (ELEM(sseq->view, SEQ_VIEW_PREVIEW, SEQ_VIEW_SEQUENCE_PREVIEW) && + ELEM(sseq->mainb, SEQ_DRAW_SEQUENCE, SEQ_DRAW_IMG_IMBUF)); +} + int seq_effect_find_selected(Scene *scene, Sequence *activeseq, int type, Sequence **selseq1, Sequence **selseq2, Sequence **selseq3, const char **error_str) { Editing *ed = BKE_sequencer_editing_get(scene, FALSE); From 9ac713bdb577116f4af0ef5250efddf82f93cf69 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 17 Dec 2012 05:36:00 +0000 Subject: [PATCH 190/252] missed this recent commit, while drawing grease pencil, draw if 'Render Only' is on. --- source/blender/editors/space_view3d/view3d_draw.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c index 7fccff861ab..d3dc8f9a75e 100644 --- a/source/blender/editors/space_view3d/view3d_draw.c +++ b/source/blender/editors/space_view3d/view3d_draw.c @@ -3182,14 +3182,14 @@ static void view3d_main_area_draw_info(const bContext *C, ARegion *ar, const cha glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); } + if (v3d->flag2 & V3D_SHOW_GPENCIL) { + /* draw grease-pencil stuff - needed to get paint-buffer shown too (since it's 2D) */ + draw_gpencil_view3d(scene, v3d, ar, FALSE); + } + if ((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) { Object *ob; - if (v3d->flag2 & V3D_SHOW_GPENCIL) { - /* draw grease-pencil stuff - needed to get paint-buffer shown too (since it's 2D) */ - draw_gpencil_view3d(scene, v3d, ar, FALSE); - } - drawcursor(scene, ar, v3d); if (U.uiflag & USER_SHOW_ROTVIEWICON) From 18cb2d208c80c9abf884e51c9e7c6f822c811190 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 17 Dec 2012 05:38:50 +0000 Subject: [PATCH 191/252] code cleanup: use 'const float *' when getting the 3d cursor and not editing it. --- source/blender/blenkernel/BKE_main.h | 4 +++- .../blender/editors/armature/editarmature.c | 7 ++++--- source/blender/editors/gpencil/gpencil_edit.c | 2 +- .../blender/editors/gpencil/gpencil_paint.c | 2 +- source/blender/editors/mesh/editmesh_tools.c | 5 +++-- source/blender/editors/object/object_add.c | 2 +- .../editors/space_view3d/view3d_edit.c | 3 +-- source/blender/editors/transform/transform.c | 3 ++- .../editors/transform/transform_generics.c | 2 +- .../editors/uvedit/uvedit_unwrap_ops.c | 21 +++++++++++-------- source/blender/makesrna/intern/rna_space.c | 2 +- 11 files changed, 30 insertions(+), 23 deletions(-) diff --git a/source/blender/blenkernel/BKE_main.h b/source/blender/blenkernel/BKE_main.h index b49c5fda475..da0cba422c3 100644 --- a/source/blender/blenkernel/BKE_main.h +++ b/source/blender/blenkernel/BKE_main.h @@ -51,7 +51,7 @@ struct Library; typedef struct Main { struct Main *next, *prev; char name[1024]; /* 1024 = FILE_MAX */ - short versionfile, subversionfile; + short versionfile, subversionfile; /* see BLENDER_VERSION, BLENDER_SUBVERSION */ short minversionfile, minsubversionfile; int revision; /* svn revision of binary that saved file */ short recovered; /* indicate the main->name (file) is the recovered one */ @@ -92,6 +92,8 @@ typedef struct Main { char id_tag_update[256]; } Main; +#define MAIN_VERSION_ATLEAST(main, ver, subver) \ + ((main)->versionfile >= (ver) || (main->versionfile == (ver) && (main)->subversionfile >= (subver))) #ifdef __cplusplus } diff --git a/source/blender/editors/armature/editarmature.c b/source/blender/editors/armature/editarmature.c index e801d3689e5..ffe58be0139 100644 --- a/source/blender/editors/armature/editarmature.c +++ b/source/blender/editors/armature/editarmature.c @@ -2062,7 +2062,7 @@ static int armature_calc_roll_exec(bContext *C, wmOperator *op) Scene *scene = CTX_data_scene(C); View3D *v3d = CTX_wm_view3d(C); /* can be NULL */ float cursor_local[3]; - float *cursor = give_cursor(scene, v3d); + const float *cursor = give_cursor(scene, v3d); copy_v3_v3(cursor_local, cursor); @@ -2323,7 +2323,8 @@ static int armature_click_extrude_exec(bContext *C, wmOperator *UNUSED(op)) View3D *v3d; bArmature *arm; EditBone *ebone, *newbone, *flipbone; - float *curs, mat[3][3], imat[3][3]; + float mat[3][3], imat[3][3]; + const float *curs; int a, to_root = 0; Object *obedit; Scene *scene; @@ -2418,7 +2419,7 @@ static int armature_click_extrude_invoke(bContext *C, wmOperator *op, wmEvent *e Scene *scene; ARegion *ar; View3D *v3d; - float *fp = NULL, tvec[3], oldcurs[3], mval_f[2]; + float *fp, tvec[3], oldcurs[3], mval_f[2]; int retv; scene = CTX_data_scene(C); diff --git a/source/blender/editors/gpencil/gpencil_edit.c b/source/blender/editors/gpencil/gpencil_edit.c index e9ca7392752..e4e640eeefc 100644 --- a/source/blender/editors/gpencil/gpencil_edit.c +++ b/source/blender/editors/gpencil/gpencil_edit.c @@ -451,7 +451,7 @@ static void gp_strokepoint_convertcoords(bContext *C, bGPDstroke *gps, bGPDspoin copy_v3_v3(p3d, &pt->x); } else { - float *fp = give_cursor(scene, v3d); + const float *fp = give_cursor(scene, v3d); float mvalf[2]; /* get screen coordinate */ diff --git a/source/blender/editors/gpencil/gpencil_paint.c b/source/blender/editors/gpencil/gpencil_paint.c index 8fdca730674..c40312758fc 100644 --- a/source/blender/editors/gpencil/gpencil_paint.c +++ b/source/blender/editors/gpencil/gpencil_paint.c @@ -208,7 +208,7 @@ static int gpencil_project_check(tGPsdata *p) static void gp_get_3d_reference(tGPsdata *p, float vec[3]) { View3D *v3d = p->sa->spacedata.first; - float *fp = give_cursor(p->scene, v3d); + const float *fp = give_cursor(p->scene, v3d); /* the reference point used depends on the owner... */ #if 0 /* XXX: disabled for now, since we can't draw relative to the owner yet */ diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c index ec9da47c9ac..be51928fef2 100644 --- a/source/blender/editors/mesh/editmesh_tools.c +++ b/source/blender/editors/mesh/editmesh_tools.c @@ -906,7 +906,7 @@ static int edbm_dupli_extrude_cursor_invoke(bContext *C, wmOperator *op, wmEvent BM_ELEM_SELECT, min); } else { - float *curs = give_cursor(vc.scene, vc.v3d); + const float *curs = give_cursor(vc.scene, vc.v3d); BMOperator bmop; BMOIter oiter; @@ -2033,7 +2033,8 @@ static int merge_target(BMEditMesh *em, Scene *scene, View3D *v3d, Object *ob, { BMIter iter; BMVert *v; - float *vco = NULL, co[3], cent[3] = {0.0f, 0.0f, 0.0f}; + float co[3], cent[3] = {0.0f, 0.0f, 0.0f}; + const float *vco = NULL; if (target) { vco = give_cursor(scene, v3d); diff --git a/source/blender/editors/object/object_add.c b/source/blender/editors/object/object_add.c index b3c0368adfe..ac1dd2464f8 100644 --- a/source/blender/editors/object/object_add.c +++ b/source/blender/editors/object/object_add.c @@ -146,7 +146,7 @@ void ED_object_location_from_view(bContext *C, float loc[3]) { View3D *v3d = CTX_wm_view3d(C); Scene *scene = CTX_data_scene(C); - float *cursor; + const float *cursor; cursor = give_cursor(scene, v3d); diff --git a/source/blender/editors/space_view3d/view3d_edit.c b/source/blender/editors/space_view3d/view3d_edit.c index cd5770ba940..a1f0bf69497 100644 --- a/source/blender/editors/space_view3d/view3d_edit.c +++ b/source/blender/editors/space_view3d/view3d_edit.c @@ -3683,10 +3683,9 @@ static int view3d_cursor3d_invoke(bContext *C, wmOperator *UNUSED(op), wmEvent * ARegion *ar = CTX_wm_region(C); View3D *v3d = CTX_wm_view3d(C); RegionView3D *rv3d = CTX_wm_region_view3d(C); - float *fp = NULL; + float *fp = give_cursor(scene, v3d); float mval_fl[2]; int flip; - fp = give_cursor(scene, v3d); flip = initgrabz(rv3d, fp[0], fp[1], fp[2]); diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c index 6a5904767b7..e85fe005670 100644 --- a/source/blender/editors/transform/transform.c +++ b/source/blender/editors/transform/transform.c @@ -2579,7 +2579,8 @@ int handleEventWarp(TransInfo *t, wmEvent *event) int Warp(TransInfo *t, const int UNUSED(mval[2])) { TransData *td = t->data; - float vec[3], circumfac, dist, phi0, co, si, *curs, cursor[3], gcursor[3]; + float vec[3], circumfac, dist, phi0, co, si, cursor[3], gcursor[3]; + const float *curs; int i; char str[50]; diff --git a/source/blender/editors/transform/transform_generics.c b/source/blender/editors/transform/transform_generics.c index 615bb786071..6d7ddd4e0ed 100644 --- a/source/blender/editors/transform/transform_generics.c +++ b/source/blender/editors/transform/transform_generics.c @@ -1445,7 +1445,7 @@ void calculateCenter2D(TransInfo *t) void calculateCenterCursor(TransInfo *t) { - float *cursor; + const float *cursor; cursor = give_cursor(t->scene, t->view); copy_v3_v3(t->center, cursor); diff --git a/source/blender/editors/uvedit/uvedit_unwrap_ops.c b/source/blender/editors/uvedit/uvedit_unwrap_ops.c index cb54689a3c0..2ca711a4a6a 100644 --- a/source/blender/editors/uvedit/uvedit_unwrap_ops.c +++ b/source/blender/editors/uvedit/uvedit_unwrap_ops.c @@ -895,16 +895,18 @@ void ED_uvedit_live_unwrap(Scene *scene, Object *obedit) static void uv_map_transform_center(Scene *scene, View3D *v3d, float *result, Object *ob, BMEditMesh *em) { - BMFace *efa; - BMLoop *l; - BMIter iter, liter; - float min[3], max[3], *cursx; int around = (v3d) ? v3d->around : V3D_CENTER; /* only operates on the edit object - this is all that's needed now */ switch (around) { case V3D_CENTER: /* bounding box center */ + { + BMFace *efa; + BMLoop *l; + BMIter iter, liter; + float min[3], max[3]; + INIT_MINMAX(min, max); BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) { @@ -916,17 +918,18 @@ static void uv_map_transform_center(Scene *scene, View3D *v3d, float *result, } mid_v3_v3v3(result, min, max); break; - + } case V3D_CURSOR: /* cursor center */ - cursx = give_cursor(scene, v3d); + { + const float *curs = give_cursor(scene, v3d); /* shift to objects world */ - sub_v3_v3v3(result, cursx, ob->obmat[3]); + sub_v3_v3v3(result, curs, ob->obmat[3]); break; - + } case V3D_LOCAL: /* object center */ case V3D_CENTROID: /* multiple objects centers, only one object here*/ default: - result[0] = result[1] = result[2] = 0.0; + zero_v3(result); break; } } diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c index a59cfc46c37..f7475151e9d 100644 --- a/source/blender/makesrna/intern/rna_space.c +++ b/source/blender/makesrna/intern/rna_space.c @@ -321,7 +321,7 @@ static void rna_View3D_CursorLocation_get(PointerRNA *ptr, float *values) View3D *v3d = (View3D *)(ptr->data); bScreen *sc = (bScreen *)ptr->id.data; Scene *scene = (Scene *)sc->scene; - float *loc = give_cursor(scene, v3d); + const float *loc = give_cursor(scene, v3d); copy_v3_v3(values, loc); } From c92dd5fa40c03dd677c4cd24fa905e25b7cf0d52 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 17 Dec 2012 06:58:19 +0000 Subject: [PATCH 192/252] bpy/rna api: add support for classmethods. So RNA can expose functions from the type, eg: bpy.types.Objects.some_function() --- source/blender/python/intern/bpy_rna.c | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/source/blender/python/intern/bpy_rna.c b/source/blender/python/intern/bpy_rna.c index a0df8988068..fbdcc86c425 100644 --- a/source/blender/python/intern/bpy_rna.c +++ b/source/blender/python/intern/bpy_rna.c @@ -1478,7 +1478,7 @@ int pyrna_pydict_to_props(PointerRNA *ptr, PyObject *kw, int all_args, const cha } -static PyObject *pyrna_func_to_py(PointerRNA *ptr, FunctionRNA *func) +static PyObject *pyrna_func_to_py(const PointerRNA *ptr, FunctionRNA *func) { BPy_FunctionRNA *pyfunc = (BPy_FunctionRNA *) PyObject_NEW(BPy_FunctionRNA, &pyrna_func_Type); pyfunc->ptr = *ptr; @@ -6029,6 +6029,28 @@ static void pyrna_subtype_set_rna(PyObject *newclass, StructRNA *srna) PyObject_SetAttr(newclass, bpy_intern_str_bl_rna, item); Py_DECREF(item); + /* add classmethods */ + { + const ListBase *lb; + Link *link; + + const PointerRNA func_ptr = {{NULL}, srna, NULL}; + + lb = RNA_struct_type_functions(srna); + for (link = lb->first; link; link = link->next) { + FunctionRNA *func = (FunctionRNA *)link; + const int flag = RNA_function_flag(func); + if ((flag & FUNC_NO_SELF) && /* is classmethod */ + (flag & FUNC_REGISTER) == FALSE) /* is not for registration */ + { /* is not for registration */ + /* we may went to set the type of this later */ + PyObject *func_py = pyrna_func_to_py(&func_ptr, func); + PyObject_SetAttrString(newclass, RNA_function_identifier(func), func_py); + Py_DECREF(func_py); + } + } + } + /* done with rna instance */ } From ab2c273b12df9be548abb3cf491be88ddbbf465e Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Mon, 17 Dec 2012 08:01:43 +0000 Subject: [PATCH 193/252] Added GPL header to sconscripts! Also changed shebang to '#!/usr/bin/env python', this is more portable across unixes... --- SConstruct | 2 +- intern/SConscript | 28 ++++++++++++++++++- intern/audaspace/SConscript | 23 ++++++++++++++- intern/bsp/SConscript | 28 ++++++++++++++++++- intern/container/SConscript | 28 ++++++++++++++++++- intern/cycles/SConscript | 28 ++++++++++++++++++- intern/cycles/kernel/SConscript | 28 ++++++++++++++++++- intern/cycles/kernel/osl/SConscript | 27 +++++++++++++++++- intern/cycles/kernel/shaders/SConscript | 28 ++++++++++++++++++- intern/dualcon/SConscript | 28 ++++++++++++++++++- intern/elbeem/SConscript | 28 ++++++++++++++++++- intern/ghost/SConscript | 28 ++++++++++++++++++- intern/guardedalloc/SConscript | 27 +++++++++++++++++- intern/iksolver/SConscript | 28 ++++++++++++++++++- intern/itasc/SConscript | 28 ++++++++++++++++++- intern/locale/SConscript | 27 +++++++++++++++++- intern/memutil/SConscript | 28 ++++++++++++++++++- intern/mikktspace/SConscript | 28 ++++++++++++++++++- intern/moto/SConscript | 28 ++++++++++++++++++- intern/opencolorio/SConscript | 27 +++++++++++++++++- intern/opennl/SConscript | 28 ++++++++++++++++++- intern/raskter/SConscript | 27 +++++++++++++++++- intern/smoke/SConscript | 28 ++++++++++++++++++- intern/string/SConscript | 28 ++++++++++++++++++- intern/utfconv/SConscript | 28 ++++++++++++++++++- source/SConscript | 28 ++++++++++++++++++- source/blender/SConscript | 28 ++++++++++++++++++- source/blender/avi/SConscript | 28 ++++++++++++++++++- source/blender/blenfont/SConscript | 28 ++++++++++++++++++- source/blender/blenkernel/SConscript | 28 ++++++++++++++++++- source/blender/blenlib/SConscript | 28 ++++++++++++++++++- source/blender/blenloader/SConscript | 28 ++++++++++++++++++- source/blender/bmesh/SConscript | 28 ++++++++++++++++++- source/blender/collada/SConscript | 3 +- source/blender/compositor/SConscript | 28 ++++++++++++++++++- source/blender/editors/SConscript | 28 ++++++++++++++++++- source/blender/editors/animation/SConscript | 28 ++++++++++++++++++- source/blender/editors/armature/SConscript | 28 ++++++++++++++++++- source/blender/editors/curve/SConscript | 28 ++++++++++++++++++- source/blender/editors/datafiles/SConscript | 28 ++++++++++++++++++- source/blender/editors/gpencil/SConscript | 28 ++++++++++++++++++- source/blender/editors/interface/SConscript | 28 ++++++++++++++++++- source/blender/editors/io/SConscript | 27 +++++++++++++++++- source/blender/editors/mask/SConscript | 28 ++++++++++++++++++- source/blender/editors/mesh/SConscript | 28 ++++++++++++++++++- source/blender/editors/metaball/SConscript | 28 ++++++++++++++++++- source/blender/editors/object/SConscript | 28 ++++++++++++++++++- source/blender/editors/physics/SConscript | 28 ++++++++++++++++++- source/blender/editors/render/SConscript | 28 ++++++++++++++++++- source/blender/editors/screen/SConscript | 28 ++++++++++++++++++- .../blender/editors/sculpt_paint/SConscript | 28 ++++++++++++++++++- source/blender/editors/sound/SConscript | 28 ++++++++++++++++++- .../blender/editors/space_action/SConscript | 28 ++++++++++++++++++- source/blender/editors/space_api/SConscript | 28 ++++++++++++++++++- .../blender/editors/space_buttons/SConscript | 28 ++++++++++++++++++- source/blender/editors/space_clip/SConscript | 28 ++++++++++++++++++- .../blender/editors/space_console/SConscript | 28 ++++++++++++++++++- source/blender/editors/space_file/SConscript | 28 ++++++++++++++++++- source/blender/editors/space_graph/SConscript | 28 ++++++++++++++++++- source/blender/editors/space_image/SConscript | 28 ++++++++++++++++++- source/blender/editors/space_info/SConscript | 28 ++++++++++++++++++- source/blender/editors/space_logic/SConscript | 28 ++++++++++++++++++- source/blender/editors/space_nla/SConscript | 28 ++++++++++++++++++- source/blender/editors/space_node/SConscript | 28 ++++++++++++++++++- .../blender/editors/space_outliner/SConscript | 28 ++++++++++++++++++- .../blender/editors/space_script/SConscript | 28 ++++++++++++++++++- .../editors/space_sequencer/SConscript | 28 ++++++++++++++++++- source/blender/editors/space_text/SConscript | 28 ++++++++++++++++++- source/blender/editors/space_time/SConscript | 28 ++++++++++++++++++- .../blender/editors/space_userpref/SConscript | 28 ++++++++++++++++++- .../blender/editors/space_view3d/SConscript | 28 ++++++++++++++++++- source/blender/editors/transform/SConscript | 28 ++++++++++++++++++- source/blender/editors/util/SConscript | 28 ++++++++++++++++++- source/blender/editors/uvedit/SConscript | 28 ++++++++++++++++++- source/blender/gpu/SConscript | 28 ++++++++++++++++++- source/blender/ikplugin/SConscript | 28 ++++++++++++++++++- source/blender/imbuf/SConscript | 28 ++++++++++++++++++- source/blender/imbuf/intern/cineon/SConscript | 28 ++++++++++++++++++- source/blender/imbuf/intern/dds/SConscript | 28 ++++++++++++++++++- .../blender/imbuf/intern/openexr/SConscript | 28 ++++++++++++++++++- source/blender/makesdna/SConscript | 28 ++++++++++++++++++- source/blender/makesdna/intern/SConscript | 28 ++++++++++++++++++- source/blender/makesrna/SConscript | 28 ++++++++++++++++++- source/blender/makesrna/intern/SConscript | 28 ++++++++++++++++++- source/blender/modifiers/SConscript | 28 ++++++++++++++++++- source/blender/nodes/SConscript | 28 ++++++++++++++++++- source/blender/opencl/SConscript | 28 ++++++++++++++++++- source/blender/python/SConscript | 27 +++++++++++++++++- source/blender/quicktime/SConscript | 28 ++++++++++++++++++- source/blender/render/SConscript | 28 ++++++++++++++++++- source/blender/windowmanager/SConscript | 28 ++++++++++++++++++- .../bad_level_call_stubs/SConscript | 28 ++++++++++++++++++- source/gameengine/BlenderRoutines/SConscript | 28 ++++++++++++++++++- source/gameengine/Converter/SConscript | 28 ++++++++++++++++++- source/gameengine/Expressions/SConscript | 28 ++++++++++++++++++- source/gameengine/GameLogic/SConscript | 28 ++++++++++++++++++- source/gameengine/GamePlayer/SConscript | 28 ++++++++++++++++++- .../gameengine/GamePlayer/common/SConscript | 28 ++++++++++++++++++- source/gameengine/GamePlayer/ghost/SConscript | 28 ++++++++++++++++++- source/gameengine/Ketsji/KXNetwork/SConscript | 28 ++++++++++++++++++- source/gameengine/Ketsji/SConscript | 28 ++++++++++++++++++- .../Network/LoopBackNetwork/SConscript | 28 ++++++++++++++++++- source/gameengine/Network/SConscript | 28 ++++++++++++++++++- source/gameengine/Physics/Bullet/SConscript | 28 ++++++++++++++++++- source/gameengine/Physics/Dummy/SConscript | 28 ++++++++++++++++++- source/gameengine/Physics/common/SConscript | 28 ++++++++++++++++++- source/gameengine/Rasterizer/SConscript | 28 ++++++++++++++++++- source/gameengine/SConscript | 28 ++++++++++++++++++- source/gameengine/SceneGraph/SConscript | 27 +++++++++++++++++- source/gameengine/VideoTexture/SConscript | 28 ++++++++++++++++++- source/icons/SConscript | 28 ++++++++++++++++++- 111 files changed, 2933 insertions(+), 111 deletions(-) diff --git a/SConstruct b/SConstruct index 34d1742ee56..97d4a334d5c 100644 --- a/SConstruct +++ b/SConstruct @@ -14,7 +14,7 @@ # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software Foundation, -# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. # # The Original Code is Copyright (C) 2006, Blender Foundation # All rights reserved. diff --git a/intern/SConscript b/intern/SConscript index 5360ce4ea88..a35c99bbbaa 100644 --- a/intern/SConscript +++ b/intern/SConscript @@ -1,4 +1,30 @@ -#!/usr/bin/python +#!/usr/bin/env python +# +# ***** BEGIN GPL LICENSE BLOCK ***** +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# The Original Code is Copyright (C) 2006, Blender Foundation +# All rights reserved. +# +# The Original Code is: all of this file. +# +# Contributor(s): Nathan Letwory. +# +# ***** END GPL LICENSE BLOCK ***** + Import ('env') SConscript(['audaspace/SConscript', diff --git a/intern/audaspace/SConscript b/intern/audaspace/SConscript index e2b6efacc96..ba549530e64 100644 --- a/intern/audaspace/SConscript +++ b/intern/audaspace/SConscript @@ -1,4 +1,25 @@ -#!/usr/bin/python +#!/usr/bin/env python +# +# ***** BEGIN LGPL LICENSE BLOCK ***** +# +# Copyright 2009 Jrg Hermann Mller +# +# This file is part of AudaSpace. +# +# AudaSpace is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# AudaSpace is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with AudaSpace. If not, see . +# +# ***** END LGPL LICENSE BLOCK ***** Import ('env') diff --git a/intern/bsp/SConscript b/intern/bsp/SConscript index d3f7cf1c6ec..92c8ee48b33 100644 --- a/intern/bsp/SConscript +++ b/intern/bsp/SConscript @@ -1,4 +1,30 @@ -#!/usr/bin/python +#!/usr/bin/env python +# +# ***** BEGIN GPL LICENSE BLOCK ***** +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# The Original Code is Copyright (C) 2006, Blender Foundation +# All rights reserved. +# +# The Original Code is: all of this file. +# +# Contributor(s): Nathan Letwory. +# +# ***** END GPL LICENSE BLOCK ***** + Import ('env') sources = env.Glob('intern/*.cpp') diff --git a/intern/container/SConscript b/intern/container/SConscript index 8edf86d7d4a..1f943157d6a 100644 --- a/intern/container/SConscript +++ b/intern/container/SConscript @@ -1,4 +1,30 @@ -#!/usr/bin/python +#!/usr/bin/env python +# +# ***** BEGIN GPL LICENSE BLOCK ***** +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# The Original Code is Copyright (C) 2006, Blender Foundation +# All rights reserved. +# +# The Original Code is: all of this file. +# +# Contributor(s): Nathan Letwory. +# +# ***** END GPL LICENSE BLOCK ***** + Import ('env') sources = env.Glob('intern/*.cpp') diff --git a/intern/cycles/SConscript b/intern/cycles/SConscript index a0e2650ddc6..dcb684c4be7 100644 --- a/intern/cycles/SConscript +++ b/intern/cycles/SConscript @@ -1,4 +1,30 @@ -#!/usr/bin/python +#!/usr/bin/env python +# +# ***** BEGIN GPL LICENSE BLOCK ***** +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# The Original Code is Copyright (C) 2011, Blender Foundation +# All rights reserved. +# +# The Original Code is: all of this file. +# +# Contributor(s): Nathan Letwory. +# +# ***** END GPL LICENSE BLOCK ***** + from os import path Import('env') diff --git a/intern/cycles/kernel/SConscript b/intern/cycles/kernel/SConscript index 730f758194e..3a46d10dee1 100644 --- a/intern/cycles/kernel/SConscript +++ b/intern/cycles/kernel/SConscript @@ -1,4 +1,30 @@ -#!/usr/bin/python +#!/usr/bin/env python +# +# ***** BEGIN GPL LICENSE BLOCK ***** +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# The Original Code is Copyright (C) 2011, Blender Foundation +# All rights reserved. +# +# The Original Code is: all of this file. +# +# Contributor(s): Nathan Letwory. +# +# ***** END GPL LICENSE BLOCK ***** + import sys import os import Blender as B diff --git a/intern/cycles/kernel/osl/SConscript b/intern/cycles/kernel/osl/SConscript index d4b42d2becb..fe7fec463a7 100644 --- a/intern/cycles/kernel/osl/SConscript +++ b/intern/cycles/kernel/osl/SConscript @@ -1,4 +1,29 @@ -#!/usr/bin/python +#!/usr/bin/env python +# +# ***** BEGIN GPL LICENSE BLOCK ***** +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# The Original Code is Copyright (C) 2011, Blender Foundation +# All rights reserved. +# +# The Original Code is: all of this file. +# +# Contributor(s): Nathan Letwory. +# +# ***** END GPL LICENSE BLOCK ***** Import('env') diff --git a/intern/cycles/kernel/shaders/SConscript b/intern/cycles/kernel/shaders/SConscript index 36b86d7b4f6..daf2b67ad2b 100644 --- a/intern/cycles/kernel/shaders/SConscript +++ b/intern/cycles/kernel/shaders/SConscript @@ -1,4 +1,30 @@ -#!/usr/bin/python +#!/usr/bin/env python +# +# ***** BEGIN GPL LICENSE BLOCK ***** +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# The Original Code is Copyright (C) 2011, Blender Foundation +# All rights reserved. +# +# The Original Code is: all of this file. +# +# Contributor(s): Nathan Letwory. +# +# ***** END GPL LICENSE BLOCK ***** + import sys import os import Blender as B diff --git a/intern/dualcon/SConscript b/intern/dualcon/SConscript index 481e9ae7f5c..34df21a74c3 100644 --- a/intern/dualcon/SConscript +++ b/intern/dualcon/SConscript @@ -1,4 +1,30 @@ -#!/usr/bin/python +#!/usr/bin/env python +# +# ***** BEGIN GPL LICENSE BLOCK ***** +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# The Original Code is Copyright (C) 2006, Blender Foundation +# All rights reserved. +# +# The Original Code is: all of this file. +# +# Contributor(s): Nathan Letwory. +# +# ***** END GPL LICENSE BLOCK ***** + Import ('env') sources = env.Glob('intern/*.cpp') diff --git a/intern/elbeem/SConscript b/intern/elbeem/SConscript index 9c035c0c285..133f02e41bc 100644 --- a/intern/elbeem/SConscript +++ b/intern/elbeem/SConscript @@ -1,4 +1,30 @@ -#!/usr/bin/python +#!/usr/bin/env python +# +# ***** BEGIN GPL LICENSE BLOCK ***** +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# The Original Code is Copyright (C) 2006, Blender Foundation +# All rights reserved. +# +# The Original Code is: all of this file. +# +# Contributor(s): Nathan Letwory. +# +# ***** END GPL LICENSE BLOCK ***** + import sys import os Import('env') diff --git a/intern/ghost/SConscript b/intern/ghost/SConscript index 96d9cfb98f8..7e142c4aeab 100644 --- a/intern/ghost/SConscript +++ b/intern/ghost/SConscript @@ -1,4 +1,30 @@ -#!/usr/bin/python +#!/usr/bin/env python +# +# ***** BEGIN GPL LICENSE BLOCK ***** +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# The Original Code is Copyright (C) 2006, Blender Foundation +# All rights reserved. +# +# The Original Code is: all of this file. +# +# Contributor(s): Nathan Letwory. +# +# ***** END GPL LICENSE BLOCK ***** + import sys import os diff --git a/intern/guardedalloc/SConscript b/intern/guardedalloc/SConscript index 74d6e07269f..0712e1c4489 100644 --- a/intern/guardedalloc/SConscript +++ b/intern/guardedalloc/SConscript @@ -1,4 +1,29 @@ -#!/usr/bin/python +#!/usr/bin/env python +# +# ***** BEGIN GPL LICENSE BLOCK ***** +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# The Original Code is Copyright (C) 2006, Blender Foundation +# All rights reserved. +# +# The Original Code is: all of this file. +# +# Contributor(s): Nathan Letwory. +# +# ***** END GPL LICENSE BLOCK ***** Import('env') diff --git a/intern/iksolver/SConscript b/intern/iksolver/SConscript index b88d3b1b713..ba973ad5fd5 100644 --- a/intern/iksolver/SConscript +++ b/intern/iksolver/SConscript @@ -1,4 +1,30 @@ -#!/usr/bin/python +#!/usr/bin/env python +# +# ***** BEGIN GPL LICENSE BLOCK ***** +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# The Original Code is Copyright (C) 2006, Blender Foundation +# All rights reserved. +# +# The Original Code is: all of this file. +# +# Contributor(s): Nathan Letwory. +# +# ***** END GPL LICENSE BLOCK ***** + Import ('env') sources = env.Glob('intern/*.cpp') diff --git a/intern/itasc/SConscript b/intern/itasc/SConscript index c1ad931c665..208fee5f2d3 100644 --- a/intern/itasc/SConscript +++ b/intern/itasc/SConscript @@ -1,4 +1,30 @@ -#!/usr/bin/python +#!/usr/bin/env python +# +# ***** BEGIN GPL LICENSE BLOCK ***** +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# The Original Code is Copyright (C) 2006, Blender Foundation +# All rights reserved. +# +# The Original Code is: all of this file. +# +# Contributor(s): Nathan Letwory. +# +# ***** END GPL LICENSE BLOCK ***** + Import ('env') sources = env.Glob('*.cpp') diff --git a/intern/locale/SConscript b/intern/locale/SConscript index df745f093ea..f60bd90fb38 100644 --- a/intern/locale/SConscript +++ b/intern/locale/SConscript @@ -1,4 +1,29 @@ -#!/usr/bin/python +#!/usr/bin/env python +# +# ***** BEGIN GPL LICENSE BLOCK ***** +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# The Original Code is Copyright (C) 2012, Blender Foundation +# All rights reserved. +# +# The Original Code is: all of this file. +# +# Contributor(s): Bastien Montagne. +# +# ***** END GPL LICENSE BLOCK ***** Import('env') diff --git a/intern/memutil/SConscript b/intern/memutil/SConscript index c9a03982615..95fa39eb9c5 100644 --- a/intern/memutil/SConscript +++ b/intern/memutil/SConscript @@ -1,4 +1,30 @@ -#!/usr/bin/python +#!/usr/bin/env python +# +# ***** BEGIN GPL LICENSE BLOCK ***** +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# The Original Code is Copyright (C) 2006, Blender Foundation +# All rights reserved. +# +# The Original Code is: all of this file. +# +# Contributor(s): Nathan Letwory. +# +# ***** END GPL LICENSE BLOCK ***** + Import ('env') sources = env.Glob('intern/*.cpp') diff --git a/intern/mikktspace/SConscript b/intern/mikktspace/SConscript index 8f31f21a26f..fcb257a4ea0 100644 --- a/intern/mikktspace/SConscript +++ b/intern/mikktspace/SConscript @@ -1,4 +1,30 @@ -#!/usr/bin/python +#!/usr/bin/env python +# +# ***** BEGIN GPL LICENSE BLOCK ***** +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# The Original Code is Copyright (C) 2006, Blender Foundation +# All rights reserved. +# +# The Original Code is: all of this file. +# +# Contributor(s): Daniel Genrich +# +# ***** END GPL LICENSE BLOCK ***** + Import ('env') sources = ['mikktspace.c'] diff --git a/intern/moto/SConscript b/intern/moto/SConscript index ba257a33b14..34a0afe27f8 100644 --- a/intern/moto/SConscript +++ b/intern/moto/SConscript @@ -1,4 +1,30 @@ -#!/usr/bin/python +#!/usr/bin/env python +# +# ***** BEGIN GPL LICENSE BLOCK ***** +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# The Original Code is Copyright (C) 2006, Blender Foundation +# All rights reserved. +# +# The Original Code is: all of this file. +# +# Contributor(s): Nathan Letwory. +# +# ***** END GPL LICENSE BLOCK ***** + Import ('env') sources = env.Glob('intern/*.cpp') diff --git a/intern/opencolorio/SConscript b/intern/opencolorio/SConscript index a4d21f3e440..6e7c467f64f 100644 --- a/intern/opencolorio/SConscript +++ b/intern/opencolorio/SConscript @@ -1,4 +1,29 @@ -#!/usr/bin/python +#!/usr/bin/env python +# +# ***** BEGIN GPL LICENSE BLOCK ***** +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# The Original Code is Copyright (C) 2012, Blender Foundation +# All rights reserved. +# +# The Original Code is: all of this file. +# +# Contributor(s): Sergey Sharybin. +# +# ***** END GPL LICENSE BLOCK ***** Import('env') diff --git a/intern/opennl/SConscript b/intern/opennl/SConscript index a0f02735748..f47dd560779 100644 --- a/intern/opennl/SConscript +++ b/intern/opennl/SConscript @@ -1,4 +1,30 @@ -#!/usr/bin/python +#!/usr/bin/env python +# +# ***** BEGIN GPL LICENSE BLOCK ***** +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# The Original Code is Copyright (C) 2006, Blender Foundation +# All rights reserved. +# +# The Original Code is: all of this file. +# +# Contributor(s): Nathan Letwory. +# +# ***** END GPL LICENSE BLOCK ***** + Import ('env') sources = env.Glob('intern/*.c') + env.Glob('superlu/*.c') diff --git a/intern/raskter/SConscript b/intern/raskter/SConscript index 7ad505d70e4..c7bf647b0e2 100644 --- a/intern/raskter/SConscript +++ b/intern/raskter/SConscript @@ -1,4 +1,29 @@ -#!/usr/bin/python +#!/usr/bin/env python +# +# ***** BEGIN GPL LICENSE BLOCK ***** +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# The Original Code is Copyright (C) 2012, Blender Foundation +# All rights reserved. +# +# The Original Code is: all of this file. +# +# Contributor(s): Peter Larabell +# +# ***** END GPL LICENSE BLOCK ***** Import ('env') diff --git a/intern/smoke/SConscript b/intern/smoke/SConscript index 0511257d319..c4a579b22b3 100644 --- a/intern/smoke/SConscript +++ b/intern/smoke/SConscript @@ -1,4 +1,30 @@ -#!/usr/bin/python +#!/usr/bin/env python +# +# ***** BEGIN GPL LICENSE BLOCK ***** +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# The Original Code is Copyright (C) 2006, Blender Foundation +# All rights reserved. +# +# The Original Code is: all of this file. +# +# Contributor(s): Daniel Genrich +# +# ***** END GPL LICENSE BLOCK ***** + Import ('env') sources = env.Glob('intern/*.cpp') diff --git a/intern/string/SConscript b/intern/string/SConscript index dac0ead8e61..8e14605b15d 100644 --- a/intern/string/SConscript +++ b/intern/string/SConscript @@ -1,4 +1,30 @@ -#!/usr/bin/python +#!/usr/bin/env python +# +# ***** BEGIN GPL LICENSE BLOCK ***** +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# The Original Code is Copyright (C) 2006, Blender Foundation +# All rights reserved. +# +# The Original Code is: all of this file. +# +# Contributor(s): Nathan Letwory. +# +# ***** END GPL LICENSE BLOCK ***** + Import ('env') sources = env.Glob('intern/*.cpp') diff --git a/intern/utfconv/SConscript b/intern/utfconv/SConscript index 19a698b6a0b..875f6154d55 100644 --- a/intern/utfconv/SConscript +++ b/intern/utfconv/SConscript @@ -1,4 +1,30 @@ -#!/usr/bin/python +#!/usr/bin/env python +# +# ***** BEGIN GPL LICENSE BLOCK ***** +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# The Original Code is Copyright (C) 2006, Blender Foundation +# All rights reserved. +# +# The Original Code is: all of this file. +# +# Contributor(s): Nathan Letwory. +# +# ***** END GPL LICENSE BLOCK ***** + Import ('env') sources = ['utfconv.c'] diff --git a/source/SConscript b/source/SConscript index fdd126b28c6..432cfb31c7d 100644 --- a/source/SConscript +++ b/source/SConscript @@ -1,4 +1,30 @@ -#!/usr/bin/python +#!/usr/bin/env python +# +# ***** BEGIN GPL LICENSE BLOCK ***** +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# The Original Code is Copyright (C) 2006, Blender Foundation +# All rights reserved. +# +# The Original Code is: all of this file. +# +# Contributor(s): Nathan Letwory. +# +# ***** END GPL LICENSE BLOCK ***** + Import ('env') SConscript(['blender/SConscript']) diff --git a/source/blender/SConscript b/source/blender/SConscript index e1f81f9aaba..bf52f2e8635 100644 --- a/source/blender/SConscript +++ b/source/blender/SConscript @@ -1,4 +1,30 @@ -#!/usr/bin/python +#!/usr/bin/env python +# +# ***** BEGIN GPL LICENSE BLOCK ***** +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# The Original Code is Copyright (C) 2006, Blender Foundation +# All rights reserved. +# +# The Original Code is: all of this file. +# +# Contributor(s): Nathan Letwory. +# +# ***** END GPL LICENSE BLOCK ***** + Import ('env') import sys diff --git a/source/blender/avi/SConscript b/source/blender/avi/SConscript index 4d2ce8fd845..0e46781b768 100644 --- a/source/blender/avi/SConscript +++ b/source/blender/avi/SConscript @@ -1,4 +1,30 @@ -#!/usr/bin/python +#!/usr/bin/env python +# +# ***** BEGIN GPL LICENSE BLOCK ***** +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# The Original Code is Copyright (C) 2006, Blender Foundation +# All rights reserved. +# +# The Original Code is: all of this file. +# +# Contributor(s): Nathan Letwory. +# +# ***** END GPL LICENSE BLOCK ***** + Import ('env') sources = env.Glob('intern/*.c') diff --git a/source/blender/blenfont/SConscript b/source/blender/blenfont/SConscript index c0591c877ef..a6ea724a51f 100644 --- a/source/blender/blenfont/SConscript +++ b/source/blender/blenfont/SConscript @@ -1,4 +1,30 @@ -#!/usr/bin/python +#!/usr/bin/env python +# +# ***** BEGIN GPL LICENSE BLOCK ***** +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# The Original Code is Copyright (C) 2006, Blender Foundation +# All rights reserved. +# +# The Original Code is: all of this file. +# +# Contributor(s): Nathan Letwory. +# +# ***** END GPL LICENSE BLOCK ***** + import sys Import ('env') diff --git a/source/blender/blenkernel/SConscript b/source/blender/blenkernel/SConscript index 22be2f78ea7..0286172e639 100644 --- a/source/blender/blenkernel/SConscript +++ b/source/blender/blenkernel/SConscript @@ -1,4 +1,30 @@ -#!/usr/bin/python +#!/usr/bin/env python +# +# ***** BEGIN GPL LICENSE BLOCK ***** +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# The Original Code is Copyright (C) 2006, Blender Foundation +# All rights reserved. +# +# The Original Code is: all of this file. +# +# Contributor(s): Nathan Letwory. +# +# ***** END GPL LICENSE BLOCK ***** + Import ('env') import os diff --git a/source/blender/blenlib/SConscript b/source/blender/blenlib/SConscript index e42c43566fc..2be06f7311d 100644 --- a/source/blender/blenlib/SConscript +++ b/source/blender/blenlib/SConscript @@ -1,4 +1,30 @@ -#!/usr/bin/python +#!/usr/bin/env python +# +# ***** BEGIN GPL LICENSE BLOCK ***** +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# The Original Code is Copyright (C) 2006, Blender Foundation +# All rights reserved. +# +# The Original Code is: all of this file. +# +# Contributor(s): Nathan Letwory. +# +# ***** END GPL LICENSE BLOCK ***** + Import ('env') sources = env.Glob('intern/*.c') diff --git a/source/blender/blenloader/SConscript b/source/blender/blenloader/SConscript index 49e8869637e..8950c4f7702 100644 --- a/source/blender/blenloader/SConscript +++ b/source/blender/blenloader/SConscript @@ -1,4 +1,30 @@ -#!/usr/bin/python +#!/usr/bin/env python +# +# ***** BEGIN GPL LICENSE BLOCK ***** +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# The Original Code is Copyright (C) 2006, Blender Foundation +# All rights reserved. +# +# The Original Code is: all of this file. +# +# Contributor(s): Nathan Letwory. +# +# ***** END GPL LICENSE BLOCK ***** + Import ('env') sources = env.Glob('intern/*.c') diff --git a/source/blender/bmesh/SConscript b/source/blender/bmesh/SConscript index 6765d57cb3e..722b7518630 100644 --- a/source/blender/bmesh/SConscript +++ b/source/blender/bmesh/SConscript @@ -1,4 +1,30 @@ -#!/usr/bin/python +#!/usr/bin/env python +# +# ***** BEGIN GPL LICENSE BLOCK ***** +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# The Original Code is Copyright (C) 2006, Blender Foundation +# All rights reserved. +# +# The Original Code is: all of this file. +# +# Contributor(s): Nathan Letwory. +# +# ***** END GPL LICENSE BLOCK ***** + Import ('env') cflags='' diff --git a/source/blender/collada/SConscript b/source/blender/collada/SConscript index 5d921681aea..1351441e41b 100644 --- a/source/blender/collada/SConscript +++ b/source/blender/collada/SConscript @@ -1,4 +1,5 @@ -#!/usr/bin/python +#!/usr/bin/env python +# # ***** BEGIN GPL LICENSE BLOCK ***** # # This program is free software; you can redistribute it and/or diff --git a/source/blender/compositor/SConscript b/source/blender/compositor/SConscript index 9f947ca7327..1872bf2afac 100644 --- a/source/blender/compositor/SConscript +++ b/source/blender/compositor/SConscript @@ -1,4 +1,30 @@ -#!/usr/bin/python +#!/usr/bin/env python +# +# ***** BEGIN GPL LICENSE BLOCK ***** +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# The Original Code is Copyright (C) 2011, Blender Foundation +# All rights reserved. +# +# The Original Code is: all of this file. +# +# Contributor(s): Jeroen Bakker, Monique Dewanchand, Blender Developers Fund. +# +# ***** END GPL LICENSE BLOCK ***** + Import ('env') defs = ['GLEW_STATIC'] diff --git a/source/blender/editors/SConscript b/source/blender/editors/SConscript index 6233ea0dc39..1ea2bc0e4ef 100644 --- a/source/blender/editors/SConscript +++ b/source/blender/editors/SConscript @@ -1,4 +1,30 @@ -#!/usr/bin/python +#!/usr/bin/env python +# +# ***** BEGIN GPL LICENSE BLOCK ***** +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# The Original Code is Copyright (C) 2006, Blender Foundation +# All rights reserved. +# +# The Original Code is: all of this file. +# +# Contributor(s): Nathan Letwory. +# +# ***** END GPL LICENSE BLOCK ***** + Import ('env') diff --git a/source/blender/editors/animation/SConscript b/source/blender/editors/animation/SConscript index 658ad2794a1..2a6b381ba66 100644 --- a/source/blender/editors/animation/SConscript +++ b/source/blender/editors/animation/SConscript @@ -1,4 +1,30 @@ -#!/usr/bin/python +#!/usr/bin/env python +# +# ***** BEGIN GPL LICENSE BLOCK ***** +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# The Original Code is Copyright (C) 2006, Blender Foundation +# All rights reserved. +# +# The Original Code is: all of this file. +# +# Contributor(s): Nathan Letwory. +# +# ***** END GPL LICENSE BLOCK ***** + Import ('env') sources = env.Glob('*.c') diff --git a/source/blender/editors/armature/SConscript b/source/blender/editors/armature/SConscript index ba375f30093..1911d76a894 100644 --- a/source/blender/editors/armature/SConscript +++ b/source/blender/editors/armature/SConscript @@ -1,4 +1,30 @@ -#!/usr/bin/python +#!/usr/bin/env python +# +# ***** BEGIN GPL LICENSE BLOCK ***** +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# The Original Code is Copyright (C) 2006, Blender Foundation +# All rights reserved. +# +# The Original Code is: all of this file. +# +# Contributor(s): Nathan Letwory. +# +# ***** END GPL LICENSE BLOCK ***** + Import ('env') sources = env.Glob('*.c') diff --git a/source/blender/editors/curve/SConscript b/source/blender/editors/curve/SConscript index 95dd7fc6233..abefd3c6dd6 100644 --- a/source/blender/editors/curve/SConscript +++ b/source/blender/editors/curve/SConscript @@ -1,4 +1,30 @@ -#!/usr/bin/python +#!/usr/bin/env python +# +# ***** BEGIN GPL LICENSE BLOCK ***** +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# The Original Code is Copyright (C) 2006, Blender Foundation +# All rights reserved. +# +# The Original Code is: all of this file. +# +# Contributor(s): Nathan Letwory. +# +# ***** END GPL LICENSE BLOCK ***** + Import ('env') sources = env.Glob('*.c') diff --git a/source/blender/editors/datafiles/SConscript b/source/blender/editors/datafiles/SConscript index e0816f783d3..fcc610eeee1 100644 --- a/source/blender/editors/datafiles/SConscript +++ b/source/blender/editors/datafiles/SConscript @@ -1,4 +1,30 @@ -#!/usr/bin/python +#!/usr/bin/env python +# +# ***** BEGIN GPL LICENSE BLOCK ***** +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# The Original Code is Copyright (C) 2006, Blender Foundation +# All rights reserved. +# +# The Original Code is: all of this file. +# +# Contributor(s): Nathan Letwory. +# +# ***** END GPL LICENSE BLOCK ***** + Import ('env') # all source generated now diff --git a/source/blender/editors/gpencil/SConscript b/source/blender/editors/gpencil/SConscript index 9d92a238eb7..f72e124e862 100644 --- a/source/blender/editors/gpencil/SConscript +++ b/source/blender/editors/gpencil/SConscript @@ -1,4 +1,30 @@ -#!/usr/bin/python +#!/usr/bin/env python +# +# ***** BEGIN GPL LICENSE BLOCK ***** +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# The Original Code is Copyright (C) 2006, Blender Foundation +# All rights reserved. +# +# The Original Code is: all of this file. +# +# Contributor(s): Nathan Letwory. +# +# ***** END GPL LICENSE BLOCK ***** + Import ('env') sources = env.Glob('*.c') diff --git a/source/blender/editors/interface/SConscript b/source/blender/editors/interface/SConscript index 2d6d5cd235e..8d277d6cd35 100644 --- a/source/blender/editors/interface/SConscript +++ b/source/blender/editors/interface/SConscript @@ -1,4 +1,30 @@ -#!/usr/bin/python +#!/usr/bin/env python +# +# ***** BEGIN GPL LICENSE BLOCK ***** +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# The Original Code is Copyright (C) 2006, Blender Foundation +# All rights reserved. +# +# The Original Code is: all of this file. +# +# Contributor(s): Nathan Letwory. +# +# ***** END GPL LICENSE BLOCK ***** + Import ('env') sources = env.Glob('*.c') diff --git a/source/blender/editors/io/SConscript b/source/blender/editors/io/SConscript index d012576637c..cef73f33ddd 100644 --- a/source/blender/editors/io/SConscript +++ b/source/blender/editors/io/SConscript @@ -1,4 +1,29 @@ -#!/usr/bin/python +#!/usr/bin/env python +# +# ***** BEGIN GPL LICENSE BLOCK ***** +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# The Original Code is Copyright (C) 2006, Blender Foundation +# All rights reserved. +# +# The Original Code is: all of this file. +# +# Contributor(s): Nathan Letwory. +# +# ***** END GPL LICENSE BLOCK ***** Import ('env') diff --git a/source/blender/editors/mask/SConscript b/source/blender/editors/mask/SConscript index 4af000d038d..3200362b580 100644 --- a/source/blender/editors/mask/SConscript +++ b/source/blender/editors/mask/SConscript @@ -1,4 +1,30 @@ -#!/usr/bin/python +#!/usr/bin/env python +# +# ***** BEGIN GPL LICENSE BLOCK ***** +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# The Original Code is Copyright (C) 2006, Blender Foundation +# All rights reserved. +# +# The Original Code is: all of this file. +# +# Contributor(s): Nathan Letwory. +# +# ***** END GPL LICENSE BLOCK ***** + Import ('env') sources = env.Glob('*.c') diff --git a/source/blender/editors/mesh/SConscript b/source/blender/editors/mesh/SConscript index 91ffdc91685..11c90a4a922 100644 --- a/source/blender/editors/mesh/SConscript +++ b/source/blender/editors/mesh/SConscript @@ -1,4 +1,30 @@ -#!/usr/bin/python +#!/usr/bin/env python +# +# ***** BEGIN GPL LICENSE BLOCK ***** +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# The Original Code is Copyright (C) 2006, Blender Foundation +# All rights reserved. +# +# The Original Code is: all of this file. +# +# Contributor(s): Nathan Letwory. +# +# ***** END GPL LICENSE BLOCK ***** + Import ('env') sources = env.Glob('*.c') diff --git a/source/blender/editors/metaball/SConscript b/source/blender/editors/metaball/SConscript index b1a1ce935db..7083eff863e 100644 --- a/source/blender/editors/metaball/SConscript +++ b/source/blender/editors/metaball/SConscript @@ -1,4 +1,30 @@ -#!/usr/bin/python +#!/usr/bin/env python +# +# ***** BEGIN GPL LICENSE BLOCK ***** +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# The Original Code is Copyright (C) 2006, Blender Foundation +# All rights reserved. +# +# The Original Code is: all of this file. +# +# Contributor(s): Nathan Letwory. +# +# ***** END GPL LICENSE BLOCK ***** + Import ('env') sources = env.Glob('*.c') diff --git a/source/blender/editors/object/SConscript b/source/blender/editors/object/SConscript index b53ea549853..df51198df92 100644 --- a/source/blender/editors/object/SConscript +++ b/source/blender/editors/object/SConscript @@ -1,4 +1,30 @@ -#!/usr/bin/python +#!/usr/bin/env python +# +# ***** BEGIN GPL LICENSE BLOCK ***** +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# The Original Code is Copyright (C) 2006, Blender Foundation +# All rights reserved. +# +# The Original Code is: all of this file. +# +# Contributor(s): Nathan Letwory. +# +# ***** END GPL LICENSE BLOCK ***** + Import ('env') sources = env.Glob('*.c') diff --git a/source/blender/editors/physics/SConscript b/source/blender/editors/physics/SConscript index fffe05d6a0d..293f7769a6a 100644 --- a/source/blender/editors/physics/SConscript +++ b/source/blender/editors/physics/SConscript @@ -1,4 +1,30 @@ -#!/usr/bin/python +#!/usr/bin/env python +# +# ***** BEGIN GPL LICENSE BLOCK ***** +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# The Original Code is Copyright (C) 2006, Blender Foundation +# All rights reserved. +# +# The Original Code is: all of this file. +# +# Contributor(s): Nathan Letwory. +# +# ***** END GPL LICENSE BLOCK ***** + Import ('env') sources = env.Glob('*.c') diff --git a/source/blender/editors/render/SConscript b/source/blender/editors/render/SConscript index 0b19ecdab8e..c05b542aea8 100644 --- a/source/blender/editors/render/SConscript +++ b/source/blender/editors/render/SConscript @@ -1,4 +1,30 @@ -#!/usr/bin/python +#!/usr/bin/env python +# +# ***** BEGIN GPL LICENSE BLOCK ***** +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# The Original Code is Copyright (C) 2006, Blender Foundation +# All rights reserved. +# +# The Original Code is: all of this file. +# +# Contributor(s): Nathan Letwory. +# +# ***** END GPL LICENSE BLOCK ***** + Import ('env') sources = env.Glob('*.c') diff --git a/source/blender/editors/screen/SConscript b/source/blender/editors/screen/SConscript index 0e894a13d28..c0a14ce5377 100644 --- a/source/blender/editors/screen/SConscript +++ b/source/blender/editors/screen/SConscript @@ -1,4 +1,30 @@ -#!/usr/bin/python +#!/usr/bin/env python +# +# ***** BEGIN GPL LICENSE BLOCK ***** +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# The Original Code is Copyright (C) 2006, Blender Foundation +# All rights reserved. +# +# The Original Code is: all of this file. +# +# Contributor(s): Nathan Letwory. +# +# ***** END GPL LICENSE BLOCK ***** + Import ('env') sources = env.Glob('*.c') diff --git a/source/blender/editors/sculpt_paint/SConscript b/source/blender/editors/sculpt_paint/SConscript index 21439e6c6b2..6767e06f65b 100644 --- a/source/blender/editors/sculpt_paint/SConscript +++ b/source/blender/editors/sculpt_paint/SConscript @@ -1,4 +1,30 @@ -#!/usr/bin/python +#!/usr/bin/env python +# +# ***** BEGIN GPL LICENSE BLOCK ***** +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# The Original Code is Copyright (C) 2006, Blender Foundation +# All rights reserved. +# +# The Original Code is: all of this file. +# +# Contributor(s): Nathan Letwory. +# +# ***** END GPL LICENSE BLOCK ***** + Import ('env') sources = env.Glob('*.c') diff --git a/source/blender/editors/sound/SConscript b/source/blender/editors/sound/SConscript index e17bccdadd9..1eaf9c2e945 100644 --- a/source/blender/editors/sound/SConscript +++ b/source/blender/editors/sound/SConscript @@ -1,4 +1,30 @@ -#!/usr/bin/python +#!/usr/bin/env python +# +# ***** BEGIN GPL LICENSE BLOCK ***** +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# The Original Code is Copyright (C) 2006, Blender Foundation +# All rights reserved. +# +# The Original Code is: all of this file. +# +# Contributor(s): Nathan Letwory. +# +# ***** END GPL LICENSE BLOCK ***** + Import ('env') sources = env.Glob('*.c') diff --git a/source/blender/editors/space_action/SConscript b/source/blender/editors/space_action/SConscript index 0fee8ff68ab..abaf6154a42 100644 --- a/source/blender/editors/space_action/SConscript +++ b/source/blender/editors/space_action/SConscript @@ -1,4 +1,30 @@ -#!/usr/bin/python +#!/usr/bin/env python +# +# ***** BEGIN GPL LICENSE BLOCK ***** +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# The Original Code is Copyright (C) 2006, Blender Foundation +# All rights reserved. +# +# The Original Code is: all of this file. +# +# Contributor(s): Nathan Letwory. +# +# ***** END GPL LICENSE BLOCK ***** + Import ('env') sources = env.Glob('*.c') diff --git a/source/blender/editors/space_api/SConscript b/source/blender/editors/space_api/SConscript index 9b818b074ba..a07be054011 100644 --- a/source/blender/editors/space_api/SConscript +++ b/source/blender/editors/space_api/SConscript @@ -1,4 +1,30 @@ -#!/usr/bin/python +#!/usr/bin/env python +# +# ***** BEGIN GPL LICENSE BLOCK ***** +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# The Original Code is Copyright (C) 2006, Blender Foundation +# All rights reserved. +# +# The Original Code is: all of this file. +# +# Contributor(s): Nathan Letwory. +# +# ***** END GPL LICENSE BLOCK ***** + Import ('env') sources = env.Glob('*.c') diff --git a/source/blender/editors/space_buttons/SConscript b/source/blender/editors/space_buttons/SConscript index 92579b6dedf..5250a1264a4 100644 --- a/source/blender/editors/space_buttons/SConscript +++ b/source/blender/editors/space_buttons/SConscript @@ -1,4 +1,30 @@ -#!/usr/bin/python +#!/usr/bin/env python +# +# ***** BEGIN GPL LICENSE BLOCK ***** +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# The Original Code is Copyright (C) 2006, Blender Foundation +# All rights reserved. +# +# The Original Code is: all of this file. +# +# Contributor(s): Nathan Letwory. +# +# ***** END GPL LICENSE BLOCK ***** + Import ('env') sources = env.Glob('*.c') diff --git a/source/blender/editors/space_clip/SConscript b/source/blender/editors/space_clip/SConscript index c9c82aea68e..2cbefee0170 100644 --- a/source/blender/editors/space_clip/SConscript +++ b/source/blender/editors/space_clip/SConscript @@ -1,4 +1,30 @@ -#!/usr/bin/python +#!/usr/bin/env python +# +# ***** BEGIN GPL LICENSE BLOCK ***** +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# The Original Code is Copyright (C) 2006, Blender Foundation +# All rights reserved. +# +# The Original Code is: all of this file. +# +# Contributor(s): Nathan Letwory. +# +# ***** END GPL LICENSE BLOCK ***** + Import ('env') sources = env.Glob('*.c') diff --git a/source/blender/editors/space_console/SConscript b/source/blender/editors/space_console/SConscript index f246f08d7ac..3e2c9d6dfdf 100644 --- a/source/blender/editors/space_console/SConscript +++ b/source/blender/editors/space_console/SConscript @@ -1,4 +1,30 @@ -#!/usr/bin/python +#!/usr/bin/env python +# +# ***** BEGIN GPL LICENSE BLOCK ***** +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# The Original Code is Copyright (C) 2006, Blender Foundation +# All rights reserved. +# +# The Original Code is: all of this file. +# +# Contributor(s): Nathan Letwory. +# +# ***** END GPL LICENSE BLOCK ***** + Import ('env') sources = env.Glob('*.c') diff --git a/source/blender/editors/space_file/SConscript b/source/blender/editors/space_file/SConscript index b387d489805..c3f8c6667f7 100644 --- a/source/blender/editors/space_file/SConscript +++ b/source/blender/editors/space_file/SConscript @@ -1,4 +1,30 @@ -#!/usr/bin/python +#!/usr/bin/env python +# +# ***** BEGIN GPL LICENSE BLOCK ***** +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# The Original Code is Copyright (C) 2006, Blender Foundation +# All rights reserved. +# +# The Original Code is: all of this file. +# +# Contributor(s): Nathan Letwory. +# +# ***** END GPL LICENSE BLOCK ***** + Import ('env') sources = env.Glob('*.c') diff --git a/source/blender/editors/space_graph/SConscript b/source/blender/editors/space_graph/SConscript index 83239a5480a..84ac27a8962 100644 --- a/source/blender/editors/space_graph/SConscript +++ b/source/blender/editors/space_graph/SConscript @@ -1,4 +1,30 @@ -#!/usr/bin/python +#!/usr/bin/env python +# +# ***** BEGIN GPL LICENSE BLOCK ***** +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# The Original Code is Copyright (C) 2006, Blender Foundation +# All rights reserved. +# +# The Original Code is: all of this file. +# +# Contributor(s): Nathan Letwory. +# +# ***** END GPL LICENSE BLOCK ***** + Import ('env') sources = env.Glob('*.c') diff --git a/source/blender/editors/space_image/SConscript b/source/blender/editors/space_image/SConscript index 737da4aac74..6e7c5982d6e 100644 --- a/source/blender/editors/space_image/SConscript +++ b/source/blender/editors/space_image/SConscript @@ -1,4 +1,30 @@ -#!/usr/bin/python +#!/usr/bin/env python +# +# ***** BEGIN GPL LICENSE BLOCK ***** +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# The Original Code is Copyright (C) 2006, Blender Foundation +# All rights reserved. +# +# The Original Code is: all of this file. +# +# Contributor(s): Nathan Letwory. +# +# ***** END GPL LICENSE BLOCK ***** + Import ('env') sources = env.Glob('*.c') diff --git a/source/blender/editors/space_info/SConscript b/source/blender/editors/space_info/SConscript index e4746aefa0c..bacc28161d3 100644 --- a/source/blender/editors/space_info/SConscript +++ b/source/blender/editors/space_info/SConscript @@ -1,4 +1,30 @@ -#!/usr/bin/python +#!/usr/bin/env python +# +# ***** BEGIN GPL LICENSE BLOCK ***** +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# The Original Code is Copyright (C) 2006, Blender Foundation +# All rights reserved. +# +# The Original Code is: all of this file. +# +# Contributor(s): Nathan Letwory. +# +# ***** END GPL LICENSE BLOCK ***** + Import ('env') sources = env.Glob('*.c') diff --git a/source/blender/editors/space_logic/SConscript b/source/blender/editors/space_logic/SConscript index e63d88ea5de..e5a19b7f30b 100644 --- a/source/blender/editors/space_logic/SConscript +++ b/source/blender/editors/space_logic/SConscript @@ -1,4 +1,30 @@ -#!/usr/bin/python +#!/usr/bin/env python +# +# ***** BEGIN GPL LICENSE BLOCK ***** +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# The Original Code is Copyright (C) 2006, Blender Foundation +# All rights reserved. +# +# The Original Code is: all of this file. +# +# Contributor(s): Nathan Letwory. +# +# ***** END GPL LICENSE BLOCK ***** + Import ('env') sources = env.Glob('*.c') diff --git a/source/blender/editors/space_nla/SConscript b/source/blender/editors/space_nla/SConscript index ee010e6856f..18c6392eee9 100644 --- a/source/blender/editors/space_nla/SConscript +++ b/source/blender/editors/space_nla/SConscript @@ -1,4 +1,30 @@ -#!/usr/bin/python +#!/usr/bin/env python +# +# ***** BEGIN GPL LICENSE BLOCK ***** +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# The Original Code is Copyright (C) 2006, Blender Foundation +# All rights reserved. +# +# The Original Code is: all of this file. +# +# Contributor(s): Nathan Letwory. +# +# ***** END GPL LICENSE BLOCK ***** + Import ('env') sources = env.Glob('*.c') diff --git a/source/blender/editors/space_node/SConscript b/source/blender/editors/space_node/SConscript index 7e311b1329d..70837fa766a 100644 --- a/source/blender/editors/space_node/SConscript +++ b/source/blender/editors/space_node/SConscript @@ -1,4 +1,30 @@ -#!/usr/bin/python +#!/usr/bin/env python +# +# ***** BEGIN GPL LICENSE BLOCK ***** +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# The Original Code is Copyright (C) 2006, Blender Foundation +# All rights reserved. +# +# The Original Code is: all of this file. +# +# Contributor(s): Nathan Letwory. +# +# ***** END GPL LICENSE BLOCK ***** + Import ('env') sources = env.Glob('*.c') diff --git a/source/blender/editors/space_outliner/SConscript b/source/blender/editors/space_outliner/SConscript index a6f2e3c2a5d..1bb71941a43 100644 --- a/source/blender/editors/space_outliner/SConscript +++ b/source/blender/editors/space_outliner/SConscript @@ -1,4 +1,30 @@ -#!/usr/bin/python +#!/usr/bin/env python +# +# ***** BEGIN GPL LICENSE BLOCK ***** +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# The Original Code is Copyright (C) 2006, Blender Foundation +# All rights reserved. +# +# The Original Code is: all of this file. +# +# Contributor(s): Nathan Letwory. +# +# ***** END GPL LICENSE BLOCK ***** + Import ('env') sources = env.Glob('*.c') diff --git a/source/blender/editors/space_script/SConscript b/source/blender/editors/space_script/SConscript index c30e204f6f4..eff603a3e2d 100644 --- a/source/blender/editors/space_script/SConscript +++ b/source/blender/editors/space_script/SConscript @@ -1,4 +1,30 @@ -#!/usr/bin/python +#!/usr/bin/env python +# +# ***** BEGIN GPL LICENSE BLOCK ***** +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# The Original Code is Copyright (C) 2006, Blender Foundation +# All rights reserved. +# +# The Original Code is: all of this file. +# +# Contributor(s): Nathan Letwory. +# +# ***** END GPL LICENSE BLOCK ***** + Import ('env') sources = env.Glob('*.c') diff --git a/source/blender/editors/space_sequencer/SConscript b/source/blender/editors/space_sequencer/SConscript index bc72786fc5f..060c7892bd1 100644 --- a/source/blender/editors/space_sequencer/SConscript +++ b/source/blender/editors/space_sequencer/SConscript @@ -1,4 +1,30 @@ -#!/usr/bin/python +#!/usr/bin/env python +# +# ***** BEGIN GPL LICENSE BLOCK ***** +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# The Original Code is Copyright (C) 2006, Blender Foundation +# All rights reserved. +# +# The Original Code is: all of this file. +# +# Contributor(s): Nathan Letwory. +# +# ***** END GPL LICENSE BLOCK ***** + Import ('env') sources = env.Glob('*.c') diff --git a/source/blender/editors/space_text/SConscript b/source/blender/editors/space_text/SConscript index 373564520c8..4b6d9fbd693 100644 --- a/source/blender/editors/space_text/SConscript +++ b/source/blender/editors/space_text/SConscript @@ -1,4 +1,30 @@ -#!/usr/bin/python +#!/usr/bin/env python +# +# ***** BEGIN GPL LICENSE BLOCK ***** +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# The Original Code is Copyright (C) 2006, Blender Foundation +# All rights reserved. +# +# The Original Code is: all of this file. +# +# Contributor(s): Nathan Letwory. +# +# ***** END GPL LICENSE BLOCK ***** + Import ('env') sources = env.Glob('*.c') diff --git a/source/blender/editors/space_time/SConscript b/source/blender/editors/space_time/SConscript index c08339ba692..32f02bff008 100644 --- a/source/blender/editors/space_time/SConscript +++ b/source/blender/editors/space_time/SConscript @@ -1,4 +1,30 @@ -#!/usr/bin/python +#!/usr/bin/env python +# +# ***** BEGIN GPL LICENSE BLOCK ***** +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# The Original Code is Copyright (C) 2006, Blender Foundation +# All rights reserved. +# +# The Original Code is: all of this file. +# +# Contributor(s): Nathan Letwory. +# +# ***** END GPL LICENSE BLOCK ***** + Import ('env') sources = env.Glob('*.c') diff --git a/source/blender/editors/space_userpref/SConscript b/source/blender/editors/space_userpref/SConscript index 5c52e6f4c41..d5aa9304364 100644 --- a/source/blender/editors/space_userpref/SConscript +++ b/source/blender/editors/space_userpref/SConscript @@ -1,4 +1,30 @@ -#!/usr/bin/python +#!/usr/bin/env python +# +# ***** BEGIN GPL LICENSE BLOCK ***** +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# The Original Code is Copyright (C) 2006, Blender Foundation +# All rights reserved. +# +# The Original Code is: all of this file. +# +# Contributor(s): Nathan Letwory. +# +# ***** END GPL LICENSE BLOCK ***** + Import ('env') sources = env.Glob('*.c') diff --git a/source/blender/editors/space_view3d/SConscript b/source/blender/editors/space_view3d/SConscript index ffe35019960..578f06ada16 100644 --- a/source/blender/editors/space_view3d/SConscript +++ b/source/blender/editors/space_view3d/SConscript @@ -1,4 +1,30 @@ -#!/usr/bin/python +#!/usr/bin/env python +# +# ***** BEGIN GPL LICENSE BLOCK ***** +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# The Original Code is Copyright (C) 2006, Blender Foundation +# All rights reserved. +# +# The Original Code is: all of this file. +# +# Contributor(s): Nathan Letwory. +# +# ***** END GPL LICENSE BLOCK ***** + Import ('env') sources = env.Glob('*.c') diff --git a/source/blender/editors/transform/SConscript b/source/blender/editors/transform/SConscript index 9cf36a2d970..d579fd73db3 100644 --- a/source/blender/editors/transform/SConscript +++ b/source/blender/editors/transform/SConscript @@ -1,4 +1,30 @@ -#!/usr/bin/python +#!/usr/bin/env python +# +# ***** BEGIN GPL LICENSE BLOCK ***** +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# The Original Code is Copyright (C) 2006, Blender Foundation +# All rights reserved. +# +# The Original Code is: all of this file. +# +# Contributor(s): Nathan Letwory. +# +# ***** END GPL LICENSE BLOCK ***** + Import ('env') sources = env.Glob('*.c') diff --git a/source/blender/editors/util/SConscript b/source/blender/editors/util/SConscript index 74879e54850..1c1a8e46dd7 100644 --- a/source/blender/editors/util/SConscript +++ b/source/blender/editors/util/SConscript @@ -1,4 +1,30 @@ -#!/usr/bin/python +#!/usr/bin/env python +# +# ***** BEGIN GPL LICENSE BLOCK ***** +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# The Original Code is Copyright (C) 2006, Blender Foundation +# All rights reserved. +# +# The Original Code is: all of this file. +# +# Contributor(s): Nathan Letwory. +# +# ***** END GPL LICENSE BLOCK ***** + Import ('env') sources = env.Glob('*.c') diff --git a/source/blender/editors/uvedit/SConscript b/source/blender/editors/uvedit/SConscript index d236b18a8fd..01316680d5d 100644 --- a/source/blender/editors/uvedit/SConscript +++ b/source/blender/editors/uvedit/SConscript @@ -1,4 +1,30 @@ -#!/usr/bin/python +#!/usr/bin/env python +# +# ***** BEGIN GPL LICENSE BLOCK ***** +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# The Original Code is Copyright (C) 2006, Blender Foundation +# All rights reserved. +# +# The Original Code is: all of this file. +# +# Contributor(s): Nathan Letwory. +# +# ***** END GPL LICENSE BLOCK ***** + Import ('env') sources = env.Glob('*.c') diff --git a/source/blender/gpu/SConscript b/source/blender/gpu/SConscript index 9b8a86eac15..aeb7edc2c56 100644 --- a/source/blender/gpu/SConscript +++ b/source/blender/gpu/SConscript @@ -1,4 +1,30 @@ -#!/usr/bin/python +#!/usr/bin/env python +# +# ***** BEGIN GPL LICENSE BLOCK ***** +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# The Original Code is Copyright (C) 2006, Blender Foundation +# All rights reserved. +# +# The Original Code is: all of this file. +# +# Contributor(s): Nathan Letwory. +# +# ***** END GPL LICENSE BLOCK ***** + Import ('env') sources = env.Glob('intern/*.c') diff --git a/source/blender/ikplugin/SConscript b/source/blender/ikplugin/SConscript index 97b1cf18e0d..0d201cb423c 100644 --- a/source/blender/ikplugin/SConscript +++ b/source/blender/ikplugin/SConscript @@ -1,4 +1,30 @@ -#!/usr/bin/python +#!/usr/bin/env python +# +# ***** BEGIN GPL LICENSE BLOCK ***** +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# The Original Code is Copyright (C) 2006, Blender Foundation +# All rights reserved. +# +# The Original Code is: all of this file. +# +# Contributor(s): Nathan Letwory. +# +# ***** END GPL LICENSE BLOCK ***** + Import ('env') defs = [] sources = env.Glob('intern/*.c') + env.Glob('intern/*.cpp') diff --git a/source/blender/imbuf/SConscript b/source/blender/imbuf/SConscript index 976108cd84e..f76da8cd9d0 100644 --- a/source/blender/imbuf/SConscript +++ b/source/blender/imbuf/SConscript @@ -1,4 +1,30 @@ -#!/usr/bin/python +#!/usr/bin/env python +# +# ***** BEGIN GPL LICENSE BLOCK ***** +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# The Original Code is Copyright (C) 2006, Blender Foundation +# All rights reserved. +# +# The Original Code is: all of this file. +# +# Contributor(s): Nathan Letwory. +# +# ***** END GPL LICENSE BLOCK ***** + import os Import ('env') diff --git a/source/blender/imbuf/intern/cineon/SConscript b/source/blender/imbuf/intern/cineon/SConscript index a07334632d7..d8fc2502081 100644 --- a/source/blender/imbuf/intern/cineon/SConscript +++ b/source/blender/imbuf/intern/cineon/SConscript @@ -1,4 +1,30 @@ -#!/usr/bin/python +#!/usr/bin/env python +# +# ***** BEGIN GPL LICENSE BLOCK ***** +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# The Original Code is Copyright (C) 2006, Blender Foundation +# All rights reserved. +# +# The Original Code is: all of this file. +# +# Contributor(s): Nathan Letwory. +# +# ***** END GPL LICENSE BLOCK ***** + Import ('env') source_files = env.Glob('*.c') diff --git a/source/blender/imbuf/intern/dds/SConscript b/source/blender/imbuf/intern/dds/SConscript index 475d21135aa..960e15f8e55 100644 --- a/source/blender/imbuf/intern/dds/SConscript +++ b/source/blender/imbuf/intern/dds/SConscript @@ -1,4 +1,30 @@ -#!/usr/bin/python +#!/usr/bin/env python +# +# ***** BEGIN GPL LICENSE BLOCK ***** +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# The Original Code is Copyright (C) 2006, Blender Foundation +# All rights reserved. +# +# The Original Code is: all of this file. +# +# Contributor(s): Nathan Letwory. +# +# ***** END GPL LICENSE BLOCK ***** + Import ('env') source_files = ['dds_api.cpp', 'DirectDrawSurface.cpp', 'Stream.cpp', 'BlockDXT.cpp', 'ColorBlock.cpp', 'Image.cpp', 'FlipDXT.cpp'] diff --git a/source/blender/imbuf/intern/openexr/SConscript b/source/blender/imbuf/intern/openexr/SConscript index a6c5ad984e2..ac38c0458d9 100644 --- a/source/blender/imbuf/intern/openexr/SConscript +++ b/source/blender/imbuf/intern/openexr/SConscript @@ -1,4 +1,30 @@ -#!/usr/bin/python +#!/usr/bin/env python +# +# ***** BEGIN GPL LICENSE BLOCK ***** +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# The Original Code is Copyright (C) 2006, Blender Foundation +# All rights reserved. +# +# The Original Code is: all of this file. +# +# Contributor(s): Nathan Letwory. +# +# ***** END GPL LICENSE BLOCK ***** + Import ('env') source_files = ['openexr_api.cpp'] diff --git a/source/blender/makesdna/SConscript b/source/blender/makesdna/SConscript index c3d39783b00..a6520a6c03e 100644 --- a/source/blender/makesdna/SConscript +++ b/source/blender/makesdna/SConscript @@ -1,4 +1,30 @@ -#!/usr/bin/python +#!/usr/bin/env python +# +# ***** BEGIN GPL LICENSE BLOCK ***** +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# The Original Code is Copyright (C) 2006, Blender Foundation +# All rights reserved. +# +# The Original Code is: all of this file. +# +# Contributor(s): Nathan Letwory. +# +# ***** END GPL LICENSE BLOCK ***** + Import ('env') objs = [] diff --git a/source/blender/makesdna/intern/SConscript b/source/blender/makesdna/intern/SConscript index c1e6eb5281d..add9611866d 100644 --- a/source/blender/makesdna/intern/SConscript +++ b/source/blender/makesdna/intern/SConscript @@ -1,4 +1,30 @@ -#!/usr/bin/python +#!/usr/bin/env python +# +# ***** BEGIN GPL LICENSE BLOCK ***** +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# The Original Code is Copyright (C) 2006, Blender Foundation +# All rights reserved. +# +# The Original Code is: all of this file. +# +# Contributor(s): Nathan Letwory. +# +# ***** END GPL LICENSE BLOCK ***** + import sys import os diff --git a/source/blender/makesrna/SConscript b/source/blender/makesrna/SConscript index 29910121e2a..aab08a3366e 100644 --- a/source/blender/makesrna/SConscript +++ b/source/blender/makesrna/SConscript @@ -1,4 +1,30 @@ -#!/usr/bin/python +#!/usr/bin/env python +# +# ***** BEGIN GPL LICENSE BLOCK ***** +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# The Original Code is Copyright (C) 2006, Blender Foundation +# All rights reserved. +# +# The Original Code is: all of this file. +# +# Contributor(s): Nathan Letwory. +# +# ***** END GPL LICENSE BLOCK ***** + Import ('env') objs = [] diff --git a/source/blender/makesrna/intern/SConscript b/source/blender/makesrna/intern/SConscript index d26de50fae0..5d60d416cc4 100644 --- a/source/blender/makesrna/intern/SConscript +++ b/source/blender/makesrna/intern/SConscript @@ -1,4 +1,30 @@ -#!/usr/bin/python +#!/usr/bin/env python +# +# ***** BEGIN GPL LICENSE BLOCK ***** +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# The Original Code is Copyright (C) 2006, Blender Foundation +# All rights reserved. +# +# The Original Code is: all of this file. +# +# Contributor(s): Nathan Letwory. +# +# ***** END GPL LICENSE BLOCK ***** + import sys import os diff --git a/source/blender/modifiers/SConscript b/source/blender/modifiers/SConscript index 62fd9ba2de1..d3430c6a4d5 100644 --- a/source/blender/modifiers/SConscript +++ b/source/blender/modifiers/SConscript @@ -1,4 +1,30 @@ -#!/usr/bin/python +#!/usr/bin/env python +# +# ***** BEGIN GPL LICENSE BLOCK ***** +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# The Original Code is Copyright (C) 2006, Blender Foundation +# All rights reserved. +# +# The Original Code is: all of this file. +# +# Contributor(s): Nathan Letwory. +# +# ***** END GPL LICENSE BLOCK ***** + Import ('env') sources = env.Glob('intern/*.c') diff --git a/source/blender/nodes/SConscript b/source/blender/nodes/SConscript index ec4f00a199a..cc735902934 100644 --- a/source/blender/nodes/SConscript +++ b/source/blender/nodes/SConscript @@ -1,4 +1,30 @@ -#!/usr/bin/python +#!/usr/bin/env python +# +# ***** BEGIN GPL LICENSE BLOCK ***** +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# The Original Code is Copyright (C) 2006, Blender Foundation +# All rights reserved. +# +# The Original Code is: all of this file. +# +# Contributor(s): Nathan Letwory. +# +# ***** END GPL LICENSE BLOCK ***** + Import ('env') sources = env.Glob('intern/*.c') diff --git a/source/blender/opencl/SConscript b/source/blender/opencl/SConscript index e91a99d5075..388789a5b50 100644 --- a/source/blender/opencl/SConscript +++ b/source/blender/opencl/SConscript @@ -1,4 +1,30 @@ -#!/usr/bin/python +#!/usr/bin/env python +# +# ***** BEGIN GPL LICENSE BLOCK ***** +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# The Original Code is Copyright (C) 2006, Blender Foundation +# All rights reserved. +# +# The Original Code is: all of this file. +# +# Contributor(s): Nathan Letwory. +# +# ***** END GPL LICENSE BLOCK ***** + Import ('env') sources = env.Glob('intern/*.c') diff --git a/source/blender/python/SConscript b/source/blender/python/SConscript index 012bc279cfb..6ecc77efb1f 100644 --- a/source/blender/python/SConscript +++ b/source/blender/python/SConscript @@ -1,4 +1,29 @@ -#!/usr/bin/python +#!/usr/bin/env python +# +# ***** BEGIN GPL LICENSE BLOCK ***** +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# The Original Code is Copyright (C) 2006, Blender Foundation +# All rights reserved. +# +# The Original Code is: all of this file. +# +# Contributor(s): Nathan Letwory. +# +# ***** END GPL LICENSE BLOCK ***** # TODO, split into 3 files. diff --git a/source/blender/quicktime/SConscript b/source/blender/quicktime/SConscript index db1d4a4f1ab..a32f325de24 100644 --- a/source/blender/quicktime/SConscript +++ b/source/blender/quicktime/SConscript @@ -1,4 +1,30 @@ -#!/usr/bin/python +#!/usr/bin/env python +# +# ***** BEGIN GPL LICENSE BLOCK ***** +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# The Original Code is Copyright (C) 2006, Blender Foundation +# All rights reserved. +# +# The Original Code is: all of this file. +# +# Contributor(s): Nathan Letwory. +# +# ***** END GPL LICENSE BLOCK ***** + Import ('env') diff --git a/source/blender/render/SConscript b/source/blender/render/SConscript index 8a044b19a79..992dd8c8262 100644 --- a/source/blender/render/SConscript +++ b/source/blender/render/SConscript @@ -1,4 +1,30 @@ -#!/usr/bin/python +#!/usr/bin/env python +# +# ***** BEGIN GPL LICENSE BLOCK ***** +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# The Original Code is Copyright (C) 2006, Blender Foundation +# All rights reserved. +# +# The Original Code is: all of this file. +# +# Contributor(s): Nathan Letwory. +# +# ***** END GPL LICENSE BLOCK ***** + Import ('env') sources = env.Glob('intern/source/*.c') diff --git a/source/blender/windowmanager/SConscript b/source/blender/windowmanager/SConscript index 68fdbec2cfa..6db0e142ac4 100644 --- a/source/blender/windowmanager/SConscript +++ b/source/blender/windowmanager/SConscript @@ -1,4 +1,30 @@ -#!/usr/bin/python +#!/usr/bin/env python +# +# ***** BEGIN GPL LICENSE BLOCK ***** +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# The Original Code is Copyright (C) 2006, Blender Foundation +# All rights reserved. +# +# The Original Code is: all of this file. +# +# Contributor(s): Nathan Letwory. +# +# ***** END GPL LICENSE BLOCK ***** + Import ('env') import os diff --git a/source/blenderplayer/bad_level_call_stubs/SConscript b/source/blenderplayer/bad_level_call_stubs/SConscript index 5efe9aa5761..f26f4dfea6b 100644 --- a/source/blenderplayer/bad_level_call_stubs/SConscript +++ b/source/blenderplayer/bad_level_call_stubs/SConscript @@ -1,4 +1,30 @@ -#!/usr/bin/python +#!/usr/bin/env python +# +# ***** BEGIN GPL LICENSE BLOCK ***** +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# The Original Code is Copyright (C) 2006, Blender Foundation +# All rights reserved. +# +# The Original Code is: all of this file. +# +# Contributor(s): Nathan Letwory. +# +# ***** END GPL LICENSE BLOCK ***** + Import ('env') sources = 'stubs.c' diff --git a/source/gameengine/BlenderRoutines/SConscript b/source/gameengine/BlenderRoutines/SConscript index 04dbe27337f..e2417d70b58 100644 --- a/source/gameengine/BlenderRoutines/SConscript +++ b/source/gameengine/BlenderRoutines/SConscript @@ -1,4 +1,30 @@ -#!/usr/bin/python +#!/usr/bin/env python +# +# ***** BEGIN GPL LICENSE BLOCK ***** +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# The Original Code is Copyright (C) 2006, Blender Foundation +# All rights reserved. +# +# The Original Code is: all of this file. +# +# Contributor(s): Nathan Letwory. +# +# ***** END GPL LICENSE BLOCK ***** + Import ('env') sources = env.Glob('*.cpp') diff --git a/source/gameengine/Converter/SConscript b/source/gameengine/Converter/SConscript index b9c70910283..28ad742545e 100644 --- a/source/gameengine/Converter/SConscript +++ b/source/gameengine/Converter/SConscript @@ -1,4 +1,30 @@ -#!/usr/bin/python +#!/usr/bin/env python +# +# ***** BEGIN GPL LICENSE BLOCK ***** +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# The Original Code is Copyright (C) 2006, Blender Foundation +# All rights reserved. +# +# The Original Code is: all of this file. +# +# Contributor(s): Nathan Letwory. +# +# ***** END GPL LICENSE BLOCK ***** + Import ('env') sources = env.Glob('*.cpp') diff --git a/source/gameengine/Expressions/SConscript b/source/gameengine/Expressions/SConscript index 4dc165a7696..a6d82a4f2da 100644 --- a/source/gameengine/Expressions/SConscript +++ b/source/gameengine/Expressions/SConscript @@ -1,4 +1,30 @@ -#!/usr/bin/python +#!/usr/bin/env python +# +# ***** BEGIN GPL LICENSE BLOCK ***** +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# The Original Code is Copyright (C) 2006, Blender Foundation +# All rights reserved. +# +# The Original Code is: all of this file. +# +# Contributor(s): Nathan Letwory. +# +# ***** END GPL LICENSE BLOCK ***** + Import ('env') sources = env.Glob('*.cpp') diff --git a/source/gameengine/GameLogic/SConscript b/source/gameengine/GameLogic/SConscript index da3c0fadb51..b274e518015 100644 --- a/source/gameengine/GameLogic/SConscript +++ b/source/gameengine/GameLogic/SConscript @@ -1,4 +1,30 @@ -#!/usr/bin/python +#!/usr/bin/env python +# +# ***** BEGIN GPL LICENSE BLOCK ***** +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# The Original Code is Copyright (C) 2006, Blender Foundation +# All rights reserved. +# +# The Original Code is: all of this file. +# +# Contributor(s): Nathan Letwory. +# +# ***** END GPL LICENSE BLOCK ***** + Import ('env') sources = env.Glob('*.cpp') + env.Glob('Joystick/*.cpp') diff --git a/source/gameengine/GamePlayer/SConscript b/source/gameengine/GamePlayer/SConscript index 0b140bba8e7..d1930aca26d 100644 --- a/source/gameengine/GamePlayer/SConscript +++ b/source/gameengine/GamePlayer/SConscript @@ -1,3 +1,29 @@ -#!/usr/bin/python +#!/usr/bin/env python +# +# ***** BEGIN GPL LICENSE BLOCK ***** +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# The Original Code is Copyright (C) 2006, Blender Foundation +# All rights reserved. +# +# The Original Code is: all of this file. +# +# Contributor(s): Nathan Letwory. +# +# ***** END GPL LICENSE BLOCK ***** + SConscript(['common/SConscript', 'ghost/SConscript']) diff --git a/source/gameengine/GamePlayer/common/SConscript b/source/gameengine/GamePlayer/common/SConscript index 6a1f47c51af..1648d8af78c 100644 --- a/source/gameengine/GamePlayer/common/SConscript +++ b/source/gameengine/GamePlayer/common/SConscript @@ -1,4 +1,30 @@ -#!/usr/bin/python +#!/usr/bin/env python +# +# ***** BEGIN GPL LICENSE BLOCK ***** +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# The Original Code is Copyright (C) 2006, Blender Foundation +# All rights reserved. +# +# The Original Code is: all of this file. +# +# Contributor(s): Nathan Letwory. +# +# ***** END GPL LICENSE BLOCK ***** + import sys Import ('env') diff --git a/source/gameengine/GamePlayer/ghost/SConscript b/source/gameengine/GamePlayer/ghost/SConscript index fb046d0fdf8..64bd58aa784 100644 --- a/source/gameengine/GamePlayer/ghost/SConscript +++ b/source/gameengine/GamePlayer/ghost/SConscript @@ -1,4 +1,30 @@ -#!/usr/bin/python +#!/usr/bin/env python +# +# ***** BEGIN GPL LICENSE BLOCK ***** +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# The Original Code is Copyright (C) 2006, Blender Foundation +# All rights reserved. +# +# The Original Code is: all of this file. +# +# Contributor(s): Nathan Letwory. +# +# ***** END GPL LICENSE BLOCK ***** + import sys Import ('env') diff --git a/source/gameengine/Ketsji/KXNetwork/SConscript b/source/gameengine/Ketsji/KXNetwork/SConscript index 3d696501203..40a1ec10df3 100644 --- a/source/gameengine/Ketsji/KXNetwork/SConscript +++ b/source/gameengine/Ketsji/KXNetwork/SConscript @@ -1,4 +1,30 @@ -#!/usr/bin/python +#!/usr/bin/env python +# +# ***** BEGIN GPL LICENSE BLOCK ***** +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# The Original Code is Copyright (C) 2006, Blender Foundation +# All rights reserved. +# +# The Original Code is: all of this file. +# +# Contributor(s): Nathan Letwory. +# +# ***** END GPL LICENSE BLOCK ***** + Import ('env') sources = env.Glob('*.cpp') diff --git a/source/gameengine/Ketsji/SConscript b/source/gameengine/Ketsji/SConscript index 88689a5a736..da1a72b4758 100644 --- a/source/gameengine/Ketsji/SConscript +++ b/source/gameengine/Ketsji/SConscript @@ -1,4 +1,30 @@ -#!/usr/bin/python +#!/usr/bin/env python +# +# ***** BEGIN GPL LICENSE BLOCK ***** +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# The Original Code is Copyright (C) 2006, Blender Foundation +# All rights reserved. +# +# The Original Code is: all of this file. +# +# Contributor(s): Nathan Letwory. +# +# ***** END GPL LICENSE BLOCK ***** + import sys Import ('env') diff --git a/source/gameengine/Network/LoopBackNetwork/SConscript b/source/gameengine/Network/LoopBackNetwork/SConscript index 7ca0a64f774..b183634d224 100644 --- a/source/gameengine/Network/LoopBackNetwork/SConscript +++ b/source/gameengine/Network/LoopBackNetwork/SConscript @@ -1,4 +1,30 @@ -#!/usr/bin/python +#!/usr/bin/env python +# +# ***** BEGIN GPL LICENSE BLOCK ***** +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# The Original Code is Copyright (C) 2006, Blender Foundation +# All rights reserved. +# +# The Original Code is: all of this file. +# +# Contributor(s): Nathan Letwory. +# +# ***** END GPL LICENSE BLOCK ***** + Import ('env') sources = 'NG_LoopBackNetworkDeviceInterface.cpp' diff --git a/source/gameengine/Network/SConscript b/source/gameengine/Network/SConscript index bbf714383b7..7365db5ba99 100644 --- a/source/gameengine/Network/SConscript +++ b/source/gameengine/Network/SConscript @@ -1,4 +1,30 @@ -#!/usr/bin/python +#!/usr/bin/env python +# +# ***** BEGIN GPL LICENSE BLOCK ***** +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# The Original Code is Copyright (C) 2006, Blender Foundation +# All rights reserved. +# +# The Original Code is: all of this file. +# +# Contributor(s): Nathan Letwory. +# +# ***** END GPL LICENSE BLOCK ***** + Import ('env') sources = env.Glob('*.cpp') #'NG_NetworkMessage.cpp NG_NetworkObject.cpp NG_NetworkScene.cpp' diff --git a/source/gameengine/Physics/Bullet/SConscript b/source/gameengine/Physics/Bullet/SConscript index ba4db001533..83239cf979a 100644 --- a/source/gameengine/Physics/Bullet/SConscript +++ b/source/gameengine/Physics/Bullet/SConscript @@ -1,4 +1,30 @@ -#!/usr/bin/python +#!/usr/bin/env python +# +# ***** BEGIN GPL LICENSE BLOCK ***** +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# The Original Code is Copyright (C) 2006, Blender Foundation +# All rights reserved. +# +# The Original Code is: all of this file. +# +# Contributor(s): Nathan Letwory. +# +# ***** END GPL LICENSE BLOCK ***** + Import ('env') sources = 'CcdPhysicsEnvironment.cpp CcdPhysicsController.cpp CcdGraphicController.cpp' diff --git a/source/gameengine/Physics/Dummy/SConscript b/source/gameengine/Physics/Dummy/SConscript index 13d1a893823..95b777b61be 100644 --- a/source/gameengine/Physics/Dummy/SConscript +++ b/source/gameengine/Physics/Dummy/SConscript @@ -1,4 +1,30 @@ -#!/usr/bin/python +#!/usr/bin/env python +# +# ***** BEGIN GPL LICENSE BLOCK ***** +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# The Original Code is Copyright (C) 2006, Blender Foundation +# All rights reserved. +# +# The Original Code is: all of this file. +# +# Contributor(s): Nathan Letwory. +# +# ***** END GPL LICENSE BLOCK ***** + Import ('env') sources = 'DummyPhysicsEnvironment.cpp' diff --git a/source/gameengine/Physics/common/SConscript b/source/gameengine/Physics/common/SConscript index abff3e33121..aee5e444079 100644 --- a/source/gameengine/Physics/common/SConscript +++ b/source/gameengine/Physics/common/SConscript @@ -1,4 +1,30 @@ -#!/usr/bin/python +#!/usr/bin/env python +# +# ***** BEGIN GPL LICENSE BLOCK ***** +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# The Original Code is Copyright (C) 2006, Blender Foundation +# All rights reserved. +# +# The Original Code is: all of this file. +# +# Contributor(s): Nathan Letwory. +# +# ***** END GPL LICENSE BLOCK ***** + Import ('env') sources = 'PHY_IMotionState.cpp PHY_IController.cpp PHY_IPhysicsController.cpp PHY_IGraphicController.cpp PHY_IPhysicsEnvironment.cpp PHY_IVehicle.cpp' diff --git a/source/gameengine/Rasterizer/SConscript b/source/gameengine/Rasterizer/SConscript index 4164271ba9b..438e95391bb 100644 --- a/source/gameengine/Rasterizer/SConscript +++ b/source/gameengine/Rasterizer/SConscript @@ -1,4 +1,30 @@ -#!/usr/bin/python +#!/usr/bin/env python +# +# ***** BEGIN GPL LICENSE BLOCK ***** +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# The Original Code is Copyright (C) 2006, Blender Foundation +# All rights reserved. +# +# The Original Code is: all of this file. +# +# Contributor(s): Nathan Letwory. +# +# ***** END GPL LICENSE BLOCK ***** + Import ('env') sources = env.Glob('*.cpp') diff --git a/source/gameengine/SConscript b/source/gameengine/SConscript index aebbf4d9fcf..3db973d9406 100644 --- a/source/gameengine/SConscript +++ b/source/gameengine/SConscript @@ -1,4 +1,30 @@ -#!/usr/bin/python +#!/usr/bin/env python +# +# ***** BEGIN GPL LICENSE BLOCK ***** +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# The Original Code is Copyright (C) 2006, Blender Foundation +# All rights reserved. +# +# The Original Code is: all of this file. +# +# Contributor(s): Nathan Letwory. +# +# ***** END GPL LICENSE BLOCK ***** + Import ('env') SConscript(['BlenderRoutines/SConscript', diff --git a/source/gameengine/SceneGraph/SConscript b/source/gameengine/SceneGraph/SConscript index 9270169199e..c88a2d6280b 100644 --- a/source/gameengine/SceneGraph/SConscript +++ b/source/gameengine/SceneGraph/SConscript @@ -1,4 +1,29 @@ -#!/usr/bin/python +#!/usr/bin/env python +# +# ***** BEGIN GPL LICENSE BLOCK ***** +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# The Original Code is Copyright (C) 2006, Blender Foundation +# All rights reserved. +# +# The Original Code is: all of this file. +# +# Contributor(s): Nathan Letwory. +# +# ***** END GPL LICENSE BLOCK ***** Import ('env') diff --git a/source/gameengine/VideoTexture/SConscript b/source/gameengine/VideoTexture/SConscript index e66284948ed..ac8082e0d09 100644 --- a/source/gameengine/VideoTexture/SConscript +++ b/source/gameengine/VideoTexture/SConscript @@ -1,4 +1,30 @@ -#!/usr/bin/python +#!/usr/bin/env python +# +# ***** BEGIN GPL LICENSE BLOCK ***** +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# The Original Code is Copyright (C) 2006, Blender Foundation +# All rights reserved. +# +# The Original Code is: all of this file. +# +# Contributor(s): Nathan Letwory. +# +# ***** END GPL LICENSE BLOCK ***** + import sys Import ('env') diff --git a/source/icons/SConscript b/source/icons/SConscript index 4bb27a7d4fb..443f6454417 100644 --- a/source/icons/SConscript +++ b/source/icons/SConscript @@ -1,4 +1,30 @@ -#!/usr/bin/python +#!/usr/bin/env python +# +# ***** BEGIN GPL LICENSE BLOCK ***** +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# The Original Code is Copyright (C) 2006, Blender Foundation +# All rights reserved. +# +# The Original Code is: all of this file. +# +# Contributor(s): Nathan Letwory. +# +# ***** END GPL LICENSE BLOCK ***** + Import ('env') import btools From 8a4ba61786fe4e9e8e5729cb20d0ed4aad3e0d46 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Mon, 17 Dec 2012 08:45:44 +0000 Subject: [PATCH 194/252] Fix part #33534: Building proxies will remove strip animation --- source/blender/blenkernel/intern/sequencer.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/source/blender/blenkernel/intern/sequencer.c b/source/blender/blenkernel/intern/sequencer.c index 861a8266511..1467d24f323 100644 --- a/source/blender/blenkernel/intern/sequencer.c +++ b/source/blender/blenkernel/intern/sequencer.c @@ -191,7 +191,9 @@ static void BKE_sequence_free_ex(Scene *scene, Sequence *seq, const int do_cache ((ID *)seq->sound)->us--; } - /* clipboard has no scene and will never have a sound handle or be active */ + /* clipboard has no scene and will never have a sound handle or be active + * same goes to sequences copy for proxy rebuild job + */ if (scene) { Editing *ed = scene->ed; @@ -1451,7 +1453,7 @@ void BKE_sequencer_proxy_rebuild_finish(SeqIndexBuildContext *context, short sto IMB_anim_index_rebuild_finish(context->index_context, stop); } - seq_free_sequence_recurse(context->scene, context->seq); + seq_free_sequence_recurse(NULL, context->seq); MEM_freeN(context); } From 359b683e1efef80648bf4dbd8225c540a05d0cf1 Mon Sep 17 00:00:00 2001 From: Ton Roosendaal Date: Mon, 17 Dec 2012 09:02:43 +0000 Subject: [PATCH 195/252] Small tweak for using transparent+overlapping regions: On mouse-over these regions now become active always (as if they were opaque). This active state is used by many tools, or for drawing cursors. Currently, all events (if not handled by button region) are passed on anyway to the underlying region. Visible errors were for example drawing the paint brush circle. --- source/blender/editors/screen/screen_edit.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/source/blender/editors/screen/screen_edit.c b/source/blender/editors/screen/screen_edit.c index bf44e6be7b6..f71d63e5fef 100644 --- a/source/blender/editors/screen/screen_edit.c +++ b/source/blender/editors/screen/screen_edit.c @@ -1291,9 +1291,12 @@ void ED_screen_set_subwinactive(bContext *C, wmEvent *event) break; } if (sa) { + /* make overlap active when mouse over */ for (ar = sa->regionbase.first; ar; ar = ar->next) { - if (BLI_rcti_isect_pt_v(&ar->winrct, &event->x)) + if (BLI_rcti_isect_pt_v(&ar->winrct, &event->x)) { scr->subwinactive = ar->swinid; + break; + } } } else From 734b4f60c1865d88d375b7c5b2003edc8c2291fa Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 17 Dec 2012 09:17:21 +0000 Subject: [PATCH 196/252] missed adding show_grease_pencil to node space in recent commit --- source/blender/makesrna/intern/rna_space.c | 6 ++++++ source/blender/python/intern/bpy_rna.c | 5 ++--- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c index f7475151e9d..6c084cdd898 100644 --- a/source/blender/makesrna/intern/rna_space.c +++ b/source/blender/makesrna/intern/rna_space.c @@ -3048,6 +3048,12 @@ static void rna_def_space_node(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Backdrop", "Use active Viewer Node output as backdrop for compositing nodes"); RNA_def_property_update(prop, NC_SPACE | ND_SPACE_NODE_VIEW, NULL); + prop = RNA_def_property(srna, "show_grease_pencil", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", SNODE_SHOW_GPENCIL); + RNA_def_property_ui_text(prop, "Show Grease Pencil", + "Show grease pencil for this view"); + RNA_def_property_update(prop, NC_SPACE | ND_SPACE_NODE_VIEW, NULL); + prop = RNA_def_property(srna, "use_auto_render", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", SNODE_AUTO_RENDER); RNA_def_property_ui_text(prop, "Auto Render", "Re-render and composite changed layers on 3D edits"); diff --git a/source/blender/python/intern/bpy_rna.c b/source/blender/python/intern/bpy_rna.c index fbdcc86c425..55983c73895 100644 --- a/source/blender/python/intern/bpy_rna.c +++ b/source/blender/python/intern/bpy_rna.c @@ -6031,18 +6031,17 @@ static void pyrna_subtype_set_rna(PyObject *newclass, StructRNA *srna) /* add classmethods */ { + const PointerRNA func_ptr = {{NULL}, srna, NULL}; const ListBase *lb; Link *link; - const PointerRNA func_ptr = {{NULL}, srna, NULL}; - lb = RNA_struct_type_functions(srna); for (link = lb->first; link; link = link->next) { FunctionRNA *func = (FunctionRNA *)link; const int flag = RNA_function_flag(func); if ((flag & FUNC_NO_SELF) && /* is classmethod */ (flag & FUNC_REGISTER) == FALSE) /* is not for registration */ - { /* is not for registration */ + { /* we may went to set the type of this later */ PyObject *func_py = pyrna_func_to_py(&func_ptr, func); PyObject_SetAttrString(newclass, RNA_function_identifier(func), func_py); From b61958c80db5ea206a9d425ed78a2238779b3d96 Mon Sep 17 00:00:00 2001 From: Ton Roosendaal Date: Mon, 17 Dec 2012 12:03:31 +0000 Subject: [PATCH 197/252] Bugfix 33560 Setup: 2 windows, 2 scenes, shared objects and groups. Errors: - editing in 1 window, didn't correctly update shared stuff in the other (like child - parent relations) - deleting group members in 1 scene, could crash the other. Fixes: - On load, only a depsgraph was created for the "active" scene. Now it makes depsgraphs for all visible scenes. - "DAG ID flushes" were only working on active scenes too, they now take the other visible into account as well. - Delete object - notifier was only sent to the active scene. All in all it's a real depsgraph fix (for once!) :) Using multi-window and multi-scene setups now is more useful. --- source/blender/blenkernel/intern/blender.c | 18 ++- source/blender/blenkernel/intern/depsgraph.c | 114 ++++++++++++------ source/blender/editors/object/object_add.c | 20 ++- .../editors/space_view3d/space_view3d.c | 12 +- 4 files changed, 115 insertions(+), 49 deletions(-) diff --git a/source/blender/blenkernel/intern/blender.c b/source/blender/blenkernel/intern/blender.c index 7aec7dddba6..5c0856bc95b 100644 --- a/source/blender/blenkernel/intern/blender.c +++ b/source/blender/blenkernel/intern/blender.c @@ -54,6 +54,7 @@ #include "DNA_screen_types.h" #include "DNA_sequence_types.h" #include "DNA_sound_types.h" +#include "DNA_windowmanager_types.h" #include "BLI_blenlib.h" #include "BLI_dynstr.h" @@ -334,6 +335,20 @@ static void setup_app_data(bContext *C, BlendFileData *bfd, const char *filepath } /* baseflags, groups, make depsgraph, etc */ + /* first handle case if other windows have different scenes visible */ + if (mode == 0) { + wmWindowManager *wm = G.main->wm.first; + + if (wm) { + wmWindow *win; + + for (win = wm->windows.first; win; win = win->next) { + if (win->screen && win->screen->scene) /* zealous check... */ + if (win->screen->scene != CTX_data_scene(C)) + BKE_scene_set_background(G.main, win->screen->scene); + } + } + } BKE_scene_set_background(G.main, CTX_data_scene(C)); if (mode != 'u') { @@ -341,8 +356,7 @@ static void setup_app_data(bContext *C, BlendFileData *bfd, const char *filepath } MEM_freeN(bfd); - - (void)curscene; /* quiet warning */ + } static int handle_subversion_warning(Main *main, ReportList *reports) diff --git a/source/blender/blenkernel/intern/depsgraph.c b/source/blender/blenkernel/intern/depsgraph.c index 3ed759392b6..6ba140fcec1 100644 --- a/source/blender/blenkernel/intern/depsgraph.c +++ b/source/blender/blenkernel/intern/depsgraph.c @@ -2482,30 +2482,51 @@ void DAG_scene_update_flags(Main *bmain, Scene *scene, unsigned int lay, const s } -static void dag_current_scene_layers(Main *bmain, Scene **sce, unsigned int *lay) +/* struct returned by DagSceneLayer */ +typedef struct DagSceneLayer { + struct DagSceneLayer *next, *prev; + Scene *scene; + unsigned int layer; +} DagSceneLayer; + +/* returns visible scenes with valid DAG */ +static void dag_current_scene_layers(Main *bmain, ListBase *lb) { wmWindowManager *wm; wmWindow *win; + + lb->first = lb->last = NULL; - /* only one scene supported currently, making more scenes work - * correctly requires changes beyond just the dependency graph */ - - *sce = NULL; - *lay = 0; - + /* if we have a windowmanager, look into windows */ if ((wm = bmain->wm.first)) { - /* if we have a windowmanager, look into windows */ + + flag_listbase_ids(&bmain->scene, LIB_DOIT, 1); + for (win = wm->windows.first; win; win = win->next) { - if (win->screen) { - if (*sce == NULL) *sce = win->screen->scene; - *lay |= BKE_screen_visible_layers(win->screen, win->screen->scene); + if (win->screen && win->screen->scene->theDag) { + Scene *scene = win->screen->scene; + + if (scene->id.flag & LIB_DOIT) { + DagSceneLayer *dsl = MEM_mallocN(sizeof(DagSceneLayer), "dag scene layer"); + + BLI_addtail(lb, dsl); + + dsl->scene = scene; + dsl->layer = BKE_screen_visible_layers(win->screen, scene); + + scene->id.flag &= ~LIB_DOIT; + } } } } else { /* if not, use the first sce */ - *sce = bmain->scene.first; - if (*sce) *lay = (*sce)->lay; + DagSceneLayer *dsl = MEM_mallocN(sizeof(DagSceneLayer), "dag scene layer"); + + BLI_addtail(lb, dsl); + + dsl->scene = bmain->scene.first; + dsl->layer = dsl->scene->lay; /* XXX for background mode, we should get the scene * from somewhere, for the -S option, but it's in @@ -2515,29 +2536,36 @@ static void dag_current_scene_layers(Main *bmain, Scene **sce, unsigned int *lay void DAG_ids_flush_update(Main *bmain, int time) { - Scene *sce; - unsigned int lay; + ListBase listbase; + DagSceneLayer *dsl; + + /* get list of visible scenes and layers */ + dag_current_scene_layers(bmain, &listbase); - dag_current_scene_layers(bmain, &sce, &lay); - - if (sce) - DAG_scene_flush_update(bmain, sce, lay, time); + for (dsl = listbase.first; dsl; dsl = dsl->next) + DAG_scene_flush_update(bmain, dsl->scene, dsl->layer, time); + + BLI_freelistN(&listbase); } void DAG_on_visible_update(Main *bmain, const short do_time) { - Scene *scene; - Base *base; - Object *ob; - Group *group; - GroupObject *go; - DagNode *node; - unsigned int lay, oblay; - - dag_current_scene_layers(bmain, &scene, &lay); - - if (scene && scene->theDag) { + ListBase listbase; + DagSceneLayer *dsl; + + /* get list of visible scenes and layers */ + dag_current_scene_layers(bmain, &listbase); + + for (dsl = listbase.first; dsl; dsl = dsl->next) { + Scene *scene = dsl->scene; Scene *sce_iter; + Base *base; + Object *ob; + Group *group; + GroupObject *go; + DagNode *node; + unsigned int lay = dsl->layer, oblay; + /* derivedmeshes and displists are not saved to file so need to be * remade, tag them so they get remade in the scene update loop, * note armature poses or object matrices are preserved and do not @@ -2574,6 +2602,8 @@ void DAG_on_visible_update(Main *bmain, const short do_time) DAG_scene_update_flags(bmain, scene, lay, do_time); scene->lay_updated |= lay; } + + BLI_freelistN(&listbase); /* hack to get objects updating on layer changes */ DAG_id_type_tag(bmain, ID_OB); @@ -2758,14 +2788,15 @@ static void dag_id_flush_update(Scene *sce, ID *id) void DAG_ids_flush_tagged(Main *bmain) { + ListBase listbase; + DagSceneLayer *dsl; ListBase *lbarray[MAX_LIBARRAY]; - Scene *sce; - unsigned int lay; int a, do_flush = FALSE; + + /* get list of visible scenes and layers */ + dag_current_scene_layers(bmain, &listbase); - dag_current_scene_layers(bmain, &sce, &lay); - - if (!sce || !sce->theDag) + if (listbase.first == NULL) return; /* loop over all ID types */ @@ -2780,7 +2811,10 @@ void DAG_ids_flush_tagged(Main *bmain) if (id && bmain->id_tag_update[id->name[0]]) { for (; id; id = id->next) { if (id->flag & (LIB_ID_RECALC | LIB_ID_RECALC_DATA)) { - dag_id_flush_update(sce, id); + + for (dsl = listbase.first; dsl; dsl = dsl->next) + dag_id_flush_update(dsl->scene, id); + do_flush = TRUE; } } @@ -2788,8 +2822,12 @@ void DAG_ids_flush_tagged(Main *bmain) } /* flush changes to other objects */ - if (do_flush) - DAG_scene_flush_update(bmain, sce, lay, 0); + if (do_flush) { + for (dsl = listbase.first; dsl; dsl = dsl->next) + DAG_scene_flush_update(bmain, dsl->scene, dsl->layer, 0); + } + + BLI_freelistN(&listbase); } void DAG_ids_check_recalc(Main *bmain, Scene *scene, int time) diff --git a/source/blender/editors/object/object_add.c b/source/blender/editors/object/object_add.c index ac1dd2464f8..b21b77e4e34 100644 --- a/source/blender/editors/object/object_add.c +++ b/source/blender/editors/object/object_add.c @@ -936,6 +936,8 @@ static int object_delete_exec(bContext *C, wmOperator *op) { Main *bmain = CTX_data_main(C); Scene *scene = CTX_data_scene(C); + wmWindowManager *wm = CTX_wm_manager(C); + wmWindow *win; const short use_global = RNA_boolean_get(op->ptr, "use_global"); if (CTX_data_edit_object(C)) @@ -967,11 +969,21 @@ static int object_delete_exec(bContext *C, wmOperator *op) } CTX_DATA_END; - DAG_scene_sort(bmain, scene); - DAG_ids_flush_update(bmain, 0); + /* delete has to handle all open scenes */ + flag_listbase_ids(&bmain->scene, LIB_DOIT, 1); + for (win = wm->windows.first; win; win = win->next) { + scene = win->screen->scene; + + if (scene->id.flag & LIB_DOIT) { + scene->id.flag &= ~LIB_DOIT; + + DAG_scene_sort(bmain, scene); - WM_event_add_notifier(C, NC_SCENE | ND_OB_ACTIVE, scene); - WM_event_add_notifier(C, NC_SCENE | ND_LAYER_CONTENT, scene); + WM_event_add_notifier(C, NC_SCENE | ND_OB_ACTIVE, scene); + WM_event_add_notifier(C, NC_SCENE | ND_LAYER_CONTENT, scene); + } + } + DAG_ids_flush_update(bmain, 0); return OPERATOR_FINISHED; } diff --git a/source/blender/editors/space_view3d/space_view3d.c b/source/blender/editors/space_view3d/space_view3d.c index 325e502f620..61649e105ee 100644 --- a/source/blender/editors/space_view3d/space_view3d.c +++ b/source/blender/editors/space_view3d/space_view3d.c @@ -632,8 +632,7 @@ static void view3d_recalc_used_layers(ARegion *ar, wmNotifier *wmn, Scene *scene static void view3d_main_area_listener(ARegion *ar, wmNotifier *wmn) { - bScreen *sc; - + /* context changes */ switch (wmn->category) { case NC_ANIMATION: @@ -656,7 +655,8 @@ static void view3d_main_area_listener(ARegion *ar, wmNotifier *wmn) case NC_SCENE: switch (wmn->data) { case ND_LAYER_CONTENT: - view3d_recalc_used_layers(ar, wmn, wmn->reference); + if (wmn->reference) + view3d_recalc_used_layers(ar, wmn, wmn->reference); ED_region_tag_redraw(ar); break; case ND_FRAME: @@ -784,8 +784,10 @@ static void view3d_main_area_listener(ARegion *ar, wmNotifier *wmn) case ND_SCREENSET: /* screen was changed, need to update used layers due to NC_SCENE|ND_LAYER_CONTENT */ /* updates used layers only for View3D in active screen */ - sc = wmn->reference; - view3d_recalc_used_layers(ar, wmn, sc->scene); + if (wmn->reference) { + bScreen *sc = wmn->reference; + view3d_recalc_used_layers(ar, wmn, sc->scene); + } ED_region_tag_redraw(ar); break; } From bf51b85871dd424d8481eb09a9fc217955ed35b1 Mon Sep 17 00:00:00 2001 From: Ton Roosendaal Date: Mon, 17 Dec 2012 12:35:39 +0000 Subject: [PATCH 198/252] Version patch for reading old files (2.50 and before). In 2.50 a new convention was added to save the filename in the .blend itself. This to allow recovery of temp saves. In current svn, it made old files open as if it was a saved home file (not storing the name in header, or in file history). Note: file handling for all recovery, remapping etc is in need for cleanup. --- source/blender/blenloader/intern/readfile.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 0d40ad9d4cd..a1a34816d51 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -6608,6 +6608,10 @@ static BHead *read_global(BlendFileData *bfd, FileData *fd, BHead *bhead) bfd->globalf = fg->globalf; BLI_strncpy(bfd->filename, fg->filename, sizeof(bfd->filename)); + /* early 2.50 version patch - filename not in FileGlobal struct */ + if (fd->fileversion <= 250) + BLI_strncpy(bfd->filename, bfd->main->name, sizeof(bfd->main->name)); + if (G.fileflags & G_FILE_RECOVER) BLI_strncpy(fd->relabase, fg->filename, sizeof(fd->relabase)); From 95225cf11057a985867f413f17871c53742eb5d0 Mon Sep 17 00:00:00 2001 From: Ton Roosendaal Date: Mon, 17 Dec 2012 14:51:06 +0000 Subject: [PATCH 199/252] Bug fix, IRC report. With 2 windows, 2 scenes, linked objects: - enter editmode in 1 window. - the other window allowed to enter editmode too. - and crash happened on exit editmode. Since editmode is in Context (scene->obedit) a bad conflict arises. New function BKE_object_is_in_editmode() returns this info outside of context. Note I didn't use BMEdit_FromObject() because of the assert(). NOTE: contextual storage of editmode could need rework... five places: - ob->mode / ob->restore_mode - scene->object - CTX_data_edit_object() - BKE_object_is_in_editmode() - view3d mode handling menu --- source/blender/blenkernel/BKE_object.h | 3 +- source/blender/blenkernel/intern/object.c | 44 +++++++++++++++++++++ source/blender/editors/object/object_edit.c | 4 ++ 3 files changed, 50 insertions(+), 1 deletion(-) diff --git a/source/blender/blenkernel/BKE_object.h b/source/blender/blenkernel/BKE_object.h index 65b3b194553..885bb6f2a26 100644 --- a/source/blender/blenkernel/BKE_object.h +++ b/source/blender/blenkernel/BKE_object.h @@ -76,7 +76,8 @@ void BKE_object_copy_proxy_drivers(struct Object *ob, struct Object *target); void BKE_object_unlink(struct Object *ob); int BKE_object_exists_check(struct Object *obtest); - +int BKE_object_is_in_editmode(struct Object *ob); + struct Object *BKE_object_add_only_object(int type, const char *name); struct Object *BKE_object_add(struct Scene *scene, int type); void *BKE_object_obdata_add_from_type(int type); diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c index 03f3fc13ce4..20a718e83cd 100644 --- a/source/blender/blenkernel/intern/object.c +++ b/source/blender/blenkernel/intern/object.c @@ -729,6 +729,50 @@ void BKE_object_unlink(Object *ob) } } +/* actual check for internal data, not context or flags */ +int BKE_object_is_in_editmode(Object *ob) +{ + if (ob->data == NULL) + return 0; + + if (ob->type == OB_MESH) { + Mesh *me = ob->data; + if (me->edit_btmesh) + return 1; + } + else if (ob->type == OB_ARMATURE) { + bArmature *arm = ob->data; + + if (arm->edbo) + return 1; + } + else if (ob->type == OB_FONT) { + Curve *cu = ob->data; + + if (cu->editfont) + return 1; + } + else if (ob->type == OB_MBALL) { + MetaBall *mb = ob->data; + + if (mb->editelems) + return 1; + } + else if (ob->type == OB_LATTICE) { + Lattice *lt = ob->data; + + if (lt->editlatt) + return 1; + } + else if (ob->type == OB_SURF || ob->type == OB_CURVE) { + Curve *cu = ob->data; + + if (cu->editnurb) + return 1; + } + return 0; +} + int BKE_object_exists_check(Object *obtest) { Object *ob; diff --git a/source/blender/editors/object/object_edit.c b/source/blender/editors/object/object_edit.c index d39e34824b9..12edb3e8edb 100644 --- a/source/blender/editors/object/object_edit.c +++ b/source/blender/editors/object/object_edit.c @@ -429,6 +429,10 @@ void ED_object_enter_editmode(bContext *C, int flag) ob = base->object; + /* this checks actual object->data, for cases when other scenes have it in editmode context */ + if ( BKE_object_is_in_editmode(ob) ) + return; + if (BKE_object_obdata_is_libdata(ob)) { error_libdata(); return; From 1fe6d543a5f45ddd7d49a0237bfe32e35e86ce5e Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 17 Dec 2012 15:02:26 +0000 Subject: [PATCH 200/252] fix/workaround [#33493] checker de-select and edge loops Checker de-select by default would give uneven selection on a circle, this isnt really a bug but the offset used would give unevenly spaced selection even if the 3rd vertex for eg could be evenly selected on a circle. Change how the offset works so the active element always remains selected when the offset is set to zero, this tends to give more even de-selection. --- source/blender/editors/mesh/editmesh_select.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/source/blender/editors/mesh/editmesh_select.c b/source/blender/editors/mesh/editmesh_select.c index a8f6ccc6c2c..6ca7777f8e2 100644 --- a/source/blender/editors/mesh/editmesh_select.c +++ b/source/blender/editors/mesh/editmesh_select.c @@ -2630,7 +2630,8 @@ static int edbm_select_nth_exec(bContext *C, wmOperator *op) int nth = RNA_int_get(op->ptr, "nth"); int offset = RNA_int_get(op->ptr, "offset"); - offset = MIN2(nth, offset); + /* so input of offset zero ends up being (nth - 1) */ + offset = (offset + (nth - 1)) % nth; if (edbm_deselect_nth(em, nth, offset) == 0) { BKE_report(op->reports, RPT_ERROR, "Mesh has no active vert/edge/face"); From c9f0e29f3cc6ef5c757d08c57e561a1ad551066d Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 17 Dec 2012 15:17:51 +0000 Subject: [PATCH 201/252] fix [#33581] Vertex Color Layer vertex colors were added to meshes with no faces whenver exiting/entering editmode, while in vertex paint mode outside of editmode. *(making a really big list of vertex colors!) --- source/blender/editors/sculpt_paint/paint_vertex.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/editors/sculpt_paint/paint_vertex.c b/source/blender/editors/sculpt_paint/paint_vertex.c index a7d75c617be..9bbf99ff3cf 100644 --- a/source/blender/editors/sculpt_paint/paint_vertex.c +++ b/source/blender/editors/sculpt_paint/paint_vertex.c @@ -346,7 +346,7 @@ static void make_vertexcol(Object *ob) /* single ob */ if (me->edit_btmesh) return; /* copies from shadedisplist to mcol */ - if (!me->mloopcol) { + if (!me->mloopcol && me->totloop) { if (!me->mcol) { CustomData_add_layer(&me->fdata, CD_MCOL, CD_DEFAULT, NULL, me->totface); } From 60e35be2d4ca9713b8a135d38d624ba3068a5dc6 Mon Sep 17 00:00:00 2001 From: Ton Roosendaal Date: Mon, 17 Dec 2012 17:37:48 +0000 Subject: [PATCH 202/252] UI fixes: - on setting lower DPI, the regions that were scrolled down would start moving down 1 pixel on every draw. Caused by rounding error. (int + 0.1 vs int -0.1) (Ancient bug) - circles used in outliner - to denote selection/active - now draw bigger, and better centered. (2.66 fix only) --- source/blender/editors/interface/view2d.c | 5 +-- source/blender/editors/screen/area.c | 6 ++-- .../editors/space_outliner/outliner_draw.c | 32 ++++++++++--------- 3 files changed, 23 insertions(+), 20 deletions(-) diff --git a/source/blender/editors/interface/view2d.c b/source/blender/editors/interface/view2d.c index a5f9995df88..306b328b431 100644 --- a/source/blender/editors/interface/view2d.c +++ b/source/blender/editors/interface/view2d.c @@ -852,10 +852,11 @@ void UI_view2d_totRect_set_resize(View2D *v2d, int width, int height, int resize /* hrumf! */ /* XXX: there are work arounds for this in the panel and file browse code. */ + /* round to int, because this is called with width + V2D_SCROLL_WIDTH */ if (scroll & V2D_SCROLL_HORIZONTAL) - width -= V2D_SCROLL_WIDTH; + width -= (int)V2D_SCROLL_WIDTH; if (scroll & V2D_SCROLL_VERTICAL) - height -= V2D_SCROLL_HEIGHT; + height -= (int)V2D_SCROLL_HEIGHT; if (ELEM(0, width, height)) { if (G.debug & G_DEBUG) diff --git a/source/blender/editors/screen/area.c b/source/blender/editors/screen/area.c index d9fbfe4bd91..e5ffbab91ea 100644 --- a/source/blender/editors/screen/area.c +++ b/source/blender/editors/screen/area.c @@ -1703,7 +1703,7 @@ void ED_region_panels(const bContext *C, ARegion *ar, int vertical, const char * v2d->keepofs &= ~(V2D_LOCKOFS_Y | V2D_KEEPOFS_X); v2d->scroll |= V2D_SCROLL_HORIZONTAL_HIDE; v2d->scroll &= ~V2D_SCROLL_VERTICAL_HIDE; - + /* ensure tot is set correctly, to keep views on bottons, with sliders */ y = min_ii(y, v2d->cur.ymin); y = -y; @@ -1724,8 +1724,8 @@ void ED_region_panels(const bContext *C, ARegion *ar, int vertical, const char * y = -y; } - /* +V2D_SCROLL_HEIGHT is workaround to set the actual height */ - UI_view2d_totRect_set(v2d, x + V2D_SCROLL_WIDTH, y + V2D_SCROLL_HEIGHT); + /* +V2D_SCROLL_HEIGHT is workaround to set the actual height (needs to be int) */ + UI_view2d_totRect_set(v2d, x + (int)V2D_SCROLL_WIDTH, y + (int)V2D_SCROLL_HEIGHT); /* set the view */ UI_view2d_view_ortho(v2d); diff --git a/source/blender/editors/space_outliner/outliner_draw.c b/source/blender/editors/space_outliner/outliner_draw.c index 186a3432ab1..33217e042e5 100644 --- a/source/blender/editors/space_outliner/outliner_draw.c +++ b/source/blender/editors/space_outliner/outliner_draw.c @@ -1227,10 +1227,10 @@ static void outliner_draw_iconrow(bContext *C, uiBlock *block, Scene *scene, Spa float ufac = UI_UNIT_X / 20.0f; uiSetRoundBox(UI_CNR_ALL); - glColor4ub(255, 255, 255, 100); - uiRoundBox((float) *offsx - 1.5f * ufac, - (float)ys + 2.0f * ufac, - (float)*offsx + UI_UNIT_X - 3.0f * ufac, + glColor4ub(255, 255, 255, 128); + uiRoundBox((float) *offsx - 1.0f * ufac, + (float)ys + 1.0f * ufac, + (float)*offsx + UI_UNIT_X - 1.0f * ufac, (float)ys + UI_UNIT_Y - 1.0f * ufac, (float)UI_UNIT_Y / 2.0f - 2.0f * ufac); glEnable(GL_BLEND); /* roundbox disables */ @@ -1278,6 +1278,7 @@ static void outliner_draw_tree_element(bContext *C, uiBlock *block, Scene *scene if (*starty + 2 * UI_UNIT_Y >= ar->v2d.cur.ymin && *starty <= ar->v2d.cur.ymax) { int xmax = ar->v2d.cur.xmax; + unsigned char alpha = 128; /* icons can be ui buts, we don't want it to overlap with restrict */ if ((soops->flag & SO_HIDE_RESTRICTCOLS) == 0) @@ -1294,16 +1295,17 @@ static void outliner_draw_tree_element(bContext *C, uiBlock *block, Scene *scene { char col[4]; UI_GetThemeColorType4ubv(TH_MATCH, SPACE_OUTLINER, col); - col[3] = 100; + col[3] = alpha; glColor4ubv((GLubyte *)col); glRecti(startx, *starty + 1, ar->v2d.cur.xmax, *starty + UI_UNIT_Y - 1); } /* colors for active/selected data */ if (tselem->type == 0) { + if (te->idcode == ID_SCE) { if (tselem->id == (ID *)scene) { - glColor4ub(255, 255, 255, 100); + glColor4ub(255, 255, 255, alpha); active = 2; } } @@ -1312,7 +1314,7 @@ static void outliner_draw_tree_element(bContext *C, uiBlock *block, Scene *scene if (group_select_flag(gr)) { char col[4]; UI_GetThemeColorType4ubv(TH_SELECT, SPACE_VIEW3D, col); - col[3] = 100; + col[3] = alpha; glColor4ubv((GLubyte *)col); active = 2; @@ -1330,14 +1332,14 @@ static void outliner_draw_tree_element(bContext *C, uiBlock *block, Scene *scene if (ob == OBACT) { if (ob->flag & SELECT) { UI_GetThemeColorType4ubv(TH_ACTIVE, SPACE_VIEW3D, col); - col[3] = 100; + col[3] = alpha; } active = 1; /* means it draws white text */ } else if (ob->flag & SELECT) { UI_GetThemeColorType4ubv(TH_SELECT, SPACE_VIEW3D, col); - col[3] = 100; + col[3] = alpha; } glColor4ubv((GLubyte *)col); @@ -1345,27 +1347,27 @@ static void outliner_draw_tree_element(bContext *C, uiBlock *block, Scene *scene } else if (scene->obedit && scene->obedit->data == tselem->id) { - glColor4ub(255, 255, 255, 100); + glColor4ub(255, 255, 255, alpha); active = 2; } else { if (tree_element_active(C, scene, soops, te, 0)) { - glColor4ub(220, 220, 255, 100); + glColor4ub(220, 220, 255, alpha); active = 2; } } } else { if (tree_element_type_active(NULL, scene, soops, te, tselem, 0) ) active = 2; - glColor4ub(220, 220, 255, 100); + glColor4ub(220, 220, 255, alpha); } /* active circle */ if (active) { uiSetRoundBox(UI_CNR_ALL); - uiRoundBox((float)startx + UI_UNIT_X - 1.5f * ufac, - (float)*starty + 2.0f * ufac, - (float)startx + 2.0f * UI_UNIT_X - 3.0f * ufac, + uiRoundBox((float)startx + UI_UNIT_X - 1.0f * ufac, + (float)*starty + 1.0f * ufac, + (float)startx + 2.0f * UI_UNIT_X - 1.0f * ufac, (float)*starty + UI_UNIT_Y - 1.0f * ufac, UI_UNIT_Y / 2.0f - 2.0f * ufac); glEnable(GL_BLEND); /* roundbox disables it */ From b60671c9626d77417fe839c43a1aca72ccc5fc0d Mon Sep 17 00:00:00 2001 From: Ton Roosendaal Date: Mon, 17 Dec 2012 18:45:13 +0000 Subject: [PATCH 203/252] Object Layer property now has tag "not animatable". Even with new depsgraph that'll be a big problem to support. For as long layers define relationships or define evaluation this should remain a static state. Instead, animate outliner "visibility". --- source/blender/makesrna/intern/rna_object.c | 1 + 1 file changed, 1 insertion(+) diff --git a/source/blender/makesrna/intern/rna_object.c b/source/blender/makesrna/intern/rna_object.c index c49bdf032fc..b218cc6a944 100644 --- a/source/blender/makesrna/intern/rna_object.c +++ b/source/blender/makesrna/intern/rna_object.c @@ -2082,6 +2082,7 @@ static void rna_def_object(BlenderRNA *brna) RNA_def_property_boolean_funcs(prop, NULL, "rna_Object_layer_set"); RNA_def_property_flag(prop, PROP_LIB_EXCEPTION); RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, "rna_Object_layer_update"); + RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); prop = RNA_def_property(srna, "layers_local_view", PROP_BOOLEAN, PROP_LAYER_MEMBER); RNA_def_property_boolean_sdna(prop, NULL, "lay", 0x01000000); From 83b03b8dfd9a454a55d17406a4b26320166fb1b9 Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Mon, 17 Dec 2012 19:26:09 +0000 Subject: [PATCH 204/252] Fix [#33590] The Screw Tool in Edit Mode isn't calculating the correct angle step divisions per turn. Degrees were used as radians... :p Also tweaked min values of steps and turns! --- source/blender/editors/mesh/editmesh_tools.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c index be51928fef2..e2083539392 100644 --- a/source/blender/editors/mesh/editmesh_tools.c +++ b/source/blender/editors/mesh/editmesh_tools.c @@ -3778,7 +3778,7 @@ static int edbm_screw_exec(bContext *C, wmOperator *op) if (!EDBM_op_init(em, &spinop, op, "spin geom=%hvef cent=%v axis=%v dvec=%v steps=%i angle=%f use_duplicate=%b", - BM_ELEM_SELECT, cent, axis, dvec, turns * steps, 360.0f * turns, FALSE)) + BM_ELEM_SELECT, cent, axis, dvec, turns * steps, DEG2RADF(360.0f * turns), FALSE)) { return OPERATOR_CANCELLED; } @@ -3823,8 +3823,8 @@ void MESH_OT_screw(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; /* props */ - RNA_def_int(ot->srna, "steps", 9, 0, INT_MAX, "Steps", "Steps", 0, 256); - RNA_def_int(ot->srna, "turns", 1, 0, INT_MAX, "Turns", "Turns", 0, 256); + RNA_def_int(ot->srna, "steps", 9, 1, INT_MAX, "Steps", "Steps", 3, 256); + RNA_def_int(ot->srna, "turns", 1, 1, INT_MAX, "Turns", "Turns", 1, 256); RNA_def_float_vector(ot->srna, "center", 3, NULL, -FLT_MAX, FLT_MAX, "Center", "Center in global view space", -FLT_MAX, FLT_MAX); From 738c482101f907e93f265689fd5440f724ce6c4e Mon Sep 17 00:00:00 2001 From: Antony Riakiotakis Date: Mon, 17 Dec 2012 20:14:07 +0000 Subject: [PATCH 205/252] uv edge based stitch. Useful to disambiguate betwen islands when uvs are shared by more than two islands. Uv edges usually belong to only two islands, making for much cleaner stitches. To change between stitch modes, press TAB. Initial mode depends on the selection mode of the image editor. Documentation can also be found on the release wiki --- source/blender/blenkernel/BKE_mesh.h | 2 - source/blender/editors/mesh/editmesh_utils.c | 14 +- .../editors/uvedit/uvedit_smart_stitch.c | 1411 ++++++++++++----- 3 files changed, 992 insertions(+), 435 deletions(-) diff --git a/source/blender/blenkernel/BKE_mesh.h b/source/blender/blenkernel/BKE_mesh.h index e53d0efffbd..3fc1b7d6136 100644 --- a/source/blender/blenkernel/BKE_mesh.h +++ b/source/blender/blenkernel/BKE_mesh.h @@ -229,8 +229,6 @@ typedef struct UvElement { /* Next UvElement corresponding to same vertex */ struct UvElement *next; /* Face the element belongs to */ - struct BMFace *face; - /* Index in the editFace of the uv */ struct BMLoop *l; /* index in loop. */ unsigned short tfindex; diff --git a/source/blender/editors/mesh/editmesh_utils.c b/source/blender/editors/mesh/editmesh_utils.c index cbb7262beb2..b1094c75f27 100644 --- a/source/blender/editors/mesh/editmesh_utils.c +++ b/source/blender/editors/mesh/editmesh_utils.c @@ -876,7 +876,6 @@ UvElementMap *EDBM_uv_element_map_create(BMEditMesh *em, int selected, int do_is if (!selected || ((!BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) && BM_elem_flag_test(efa, BM_ELEM_SELECT))) { BM_ITER_ELEM_INDEX (l, &liter, efa, BM_LOOPS_OF_FACE, i) { buf->l = l; - buf->face = efa; buf->separate = 0; buf->island = INVALID_ISLAND; buf->tfindex = i; @@ -948,7 +947,7 @@ UvElementMap *EDBM_uv_element_map_create(BMEditMesh *em, int selected, int do_is for (i = 0; i < totuv; i++) { if (element_map->buf[i].island == INVALID_ISLAND) { element_map->buf[i].island = nislands; - stack[0] = element_map->buf[i].face; + stack[0] = element_map->buf[i].l->f; island_number[BM_elem_index_get(stack[0])] = nislands; stacksize = 1; @@ -962,12 +961,11 @@ UvElementMap *EDBM_uv_element_map_create(BMEditMesh *em, int selected, int do_is if (element->separate) initelement = element; - if (element->face == efa) { + if (element->l->f == efa) { /* found the uv corresponding to our face and vertex. Now fill it to the buffer */ element->island = nislands; map[element - element_map->buf] = islandbufsize; islandbuf[islandbufsize].l = element->l; - islandbuf[islandbufsize].face = element->face; islandbuf[islandbufsize].separate = element->separate; islandbuf[islandbufsize].tfindex = element->tfindex; islandbuf[islandbufsize].island = nislands; @@ -977,9 +975,9 @@ UvElementMap *EDBM_uv_element_map_create(BMEditMesh *em, int selected, int do_is if (element->separate && element != initelement) break; - if (island_number[BM_elem_index_get(element->face)] == INVALID_ISLAND) { - stack[stacksize++] = element->face; - island_number[BM_elem_index_get(element->face)] = nislands; + if (island_number[BM_elem_index_get(element->l->f)] == INVALID_ISLAND) { + stack[stacksize++] = element->l->f; + island_number[BM_elem_index_get(element->l->f)] = nislands; } } break; @@ -1060,7 +1058,7 @@ UvElement *ED_uv_element_get(UvElementMap *map, BMFace *efa, BMLoop *l) element = map->vert[BM_elem_index_get(l->v)]; for (; element; element = element->next) - if (element->face == efa) + if (element->l->f == efa) return element; return NULL; diff --git a/source/blender/editors/uvedit/uvedit_smart_stitch.c b/source/blender/editors/uvedit/uvedit_smart_stitch.c index 9c99eb196c2..280b6f0703d 100644 --- a/source/blender/editors/uvedit/uvedit_smart_stitch.c +++ b/source/blender/editors/uvedit/uvedit_smart_stitch.c @@ -72,24 +72,24 @@ /* ********************** smart stitch operator *********************** */ -/* object that stores display data for previewing before accepting stitching */ +/* object that stores display data for previewing before confirming stitching */ typedef struct StitchPreviewer { - /* here we'll store the preview triangle indices of the mesh */ - float *preview_polys; - /* uvs per polygon. */ - unsigned int *uvs_per_polygon; - /*number of preview polygons */ - unsigned int num_polys; - /* preview data. These will be either the previewed vertices or edges depending on stitch mode settings */ - float *preview_stitchable; - float *preview_unstitchable; - /* here we'll store the number of elements to be drawn */ - unsigned int num_stitchable; - unsigned int num_unstitchable; - unsigned int preview_uvs; - /* ...and here we'll store the triangles*/ - float *static_tris; - unsigned int num_static_tris; + /* here we'll store the preview triangle indices of the mesh */ + float *preview_polys; + /* uvs per polygon. */ + unsigned int *uvs_per_polygon; + /*number of preview polygons */ + unsigned int num_polys; + /* preview data. These will be either the previewed vertices or edges depending on stitch mode settings */ + float *preview_stitchable; + float *preview_unstitchable; + /* here we'll store the number of elements to be drawn */ + unsigned int num_stitchable; + unsigned int num_unstitchable; + unsigned int preview_uvs; + /* ...and here we'll store the static island triangles*/ + float *static_tris; + unsigned int num_static_tris; } StitchPreviewer; @@ -98,85 +98,96 @@ struct IslandStitchData; /* This is a straightforward implementation, count the uv's in the island that will move and take the mean displacement/rotation and apply it to all * elements of the island except from the stitchable */ typedef struct IslandStitchData { - /* rotation can be used only for edges, for vertices there is no such notion */ - float rotation; - float translation[2]; - /* Used for rotation, the island will rotate around this point */ - float medianPoint[2]; - int numOfElements; - int num_rot_elements; - /* flag to remember if island has been added for preview */ - char addedForPreview; - /* flag an island to be considered for determining static island */ - char stitchableCandidate; - /* if edge rotation is used, flag so that vertex rotation is not used */ - char use_edge_rotation; + /* rotation can be used only for edges, for vertices there is no such notion */ + float rotation; + float translation[2]; + /* Used for rotation, the island will rotate around this point */ + float medianPoint[2]; + int numOfElements; + int num_rot_elements; + /* flag to remember if island has been added for preview */ + char addedForPreview; + /* flag an island to be considered for determining static island */ + char stitchableCandidate; + /* if edge rotation is used, flag so that vertex rotation is not used */ + char use_edge_rotation; } IslandStitchData; /* just for averaging UVs */ typedef struct UVVertAverage { - float uv[2]; - unsigned short count; + float uv[2]; + unsigned short count; } UVVertAverage; typedef struct UvEdge { - /* index to uv buffer */ - unsigned int uv1; - unsigned int uv2; - /* general use flag (Used to check if edge is boundary here, and propagates to adjacency elements) */ - char flag; - /* element that guarantees element->face has the face on element->tfindex and element->tfindex+1 is the second uv */ - UvElement *element; + /* index to uv buffer */ + unsigned int uv1; + unsigned int uv2; + /* general use flag (Used to check if edge is boundary here, and propagates to adjacency elements) */ + unsigned char flag; + /* element that guarantees element->face has the edge on element->tfindex and element->tfindex+1 is the second uv */ + UvElement *element; + /* next uv edge with the same exact vertices as this one.. Calculated at startup to save time */ + struct UvEdge *next; + /* point to first of common edges. Needed for iteration */ + struct UvEdge *first; } UvEdge; /* stitch state object */ typedef struct StitchState { - /* use limit flag */ - char use_limit; - /* limit to operator, same as original operator */ - float limit_dist; - /* snap uv islands together during stitching */ - char snap_islands; - /* stich at midpoints or at islands */ - char midpoints; - /* editmesh, cached for use in modal handler */ - BMEditMesh *em; - /* clear seams of stitched edges after stitch */ - char clear_seams; - /* element map for getting info about uv connectivity */ - UvElementMap *element_map; - /* edge container */ - UvEdge *uvedges; - /* container of first of a group of coincident uvs, these will be operated upon */ - UvElement **uvs; - /* maps uvelements to their first coincident uv */ - int *map; - /* 2D normals per uv to calculate rotation for snapping */ - float *normals; - /* edge storage */ - UvEdge *edges; + /* use limit flag */ + char use_limit; + /* limit to operator, same as original operator */ + float limit_dist; + /* snap uv islands together during stitching */ + char snap_islands; + /* stich at midpoints or at islands */ + char midpoints; + /* editmesh, cached for use in modal handler */ + BMEditMesh *em; + /* clear seams of stitched edges after stitch */ + char clear_seams; + /* element map for getting info about uv connectivity */ + UvElementMap *element_map; + /* edge container */ + UvEdge *uvedges; + /* container of first of a group of coincident uvs, these will be operated upon */ + UvElement **uvs; + /* maps uvelements to their first coincident uv */ + int *map; + /* 2D normals per uv to calculate rotation for snapping */ + float *normals; + /* edge storage */ + UvEdge *edges; + /* hash for quick lookup of edges */ + GHash *edge_hash; - /* count of separate uvs and edges */ - int total_boundary_edges; - int total_separate_uvs; - /* hold selection related information */ - UvElement **selection_stack; - int selection_size; - /* island that stays in place */ - int static_island; - /* store number of primitives per face so that we can allocate the active island buffer later */ - unsigned int *tris_per_island; + /* count of separate uvs and edges */ + int total_separate_edges; + int total_separate_uvs; + /* hold selection related information */ + void **selection_stack; + int selection_size; + /* island that stays in place */ + int static_island; + /* store number of primitives per face so that we can allocate the active island buffer later */ + unsigned int *tris_per_island; - void *draw_handle; + /* vert or edge mode used for stitching */ + char mode; + /* handle for drawing */ + void *draw_handle; + /* preview data */ + StitchPreviewer *stitch_preview; } StitchState; typedef struct PreviewPosition { - int data_position; - int polycount_position; + int data_position; + int polycount_position; } PreviewPosition; /* - * defines for UvElement flags + * defines for UvElement/UcEdge flags */ #define STITCH_SELECTED 1 #define STITCH_STITCHABLE 2 @@ -186,83 +197,79 @@ typedef struct PreviewPosition { #define STITCH_NO_PREVIEW -1 -/* previewer stuff (see uvedit_intern.h for more info) */ -static StitchPreviewer *_stitch_preview; +enum StitchModes { + STITCH_VERT, + STITCH_EDGE +}; /* constructor */ static StitchPreviewer *stitch_preview_init(void) { - _stitch_preview = MEM_mallocN(sizeof(StitchPreviewer), "stitch_previewer"); - _stitch_preview->preview_polys = NULL; - _stitch_preview->preview_stitchable = NULL; - _stitch_preview->preview_unstitchable = NULL; - _stitch_preview->uvs_per_polygon = NULL; + StitchPreviewer *stitch_preview; - _stitch_preview->preview_uvs = 0; - _stitch_preview->num_polys = 0; - _stitch_preview->num_stitchable = 0; - _stitch_preview->num_unstitchable = 0; + stitch_preview = MEM_mallocN(sizeof(StitchPreviewer), "stitch_previewer"); + stitch_preview->preview_polys = NULL; + stitch_preview->preview_stitchable = NULL; + stitch_preview->preview_unstitchable = NULL; + stitch_preview->uvs_per_polygon = NULL; - _stitch_preview->static_tris = NULL; + stitch_preview->preview_uvs = 0; + stitch_preview->num_polys = 0; + stitch_preview->num_stitchable = 0; + stitch_preview->num_unstitchable = 0; - _stitch_preview->num_static_tris = 0; + stitch_preview->static_tris = NULL; - return _stitch_preview; + stitch_preview->num_static_tris = 0; + + return stitch_preview; } /* destructor...yeah this should be C++ :) */ -static void stitch_preview_delete(void) +static void stitch_preview_delete(StitchPreviewer *stitch_preview) { - if (_stitch_preview) { - if (_stitch_preview->preview_polys) { - MEM_freeN(_stitch_preview->preview_polys); - _stitch_preview->preview_polys = NULL; + if (stitch_preview) { + if (stitch_preview->preview_polys) { + MEM_freeN(stitch_preview->preview_polys); + stitch_preview->preview_polys = NULL; } - if (_stitch_preview->uvs_per_polygon) { - MEM_freeN(_stitch_preview->uvs_per_polygon); - _stitch_preview->uvs_per_polygon = NULL; + if (stitch_preview->uvs_per_polygon) { + MEM_freeN(stitch_preview->uvs_per_polygon); + stitch_preview->uvs_per_polygon = NULL; } - if (_stitch_preview->preview_stitchable) { - MEM_freeN(_stitch_preview->preview_stitchable); - _stitch_preview->preview_stitchable = NULL; + if (stitch_preview->preview_stitchable) { + MEM_freeN(stitch_preview->preview_stitchable); + stitch_preview->preview_stitchable = NULL; } - if (_stitch_preview->preview_unstitchable) { - MEM_freeN(_stitch_preview->preview_unstitchable); - _stitch_preview->preview_unstitchable = NULL; + if (stitch_preview->preview_unstitchable) { + MEM_freeN(stitch_preview->preview_unstitchable); + stitch_preview->preview_unstitchable = NULL; } - if (_stitch_preview->static_tris) { - MEM_freeN(_stitch_preview->static_tris); - _stitch_preview->static_tris = NULL; + if (stitch_preview->static_tris) { + MEM_freeN(stitch_preview->static_tris); + stitch_preview->static_tris = NULL; } - - MEM_freeN(_stitch_preview); - _stitch_preview = NULL; + MEM_freeN(stitch_preview); } } - -/* "getter method" */ -static StitchPreviewer *uv_get_stitch_previewer(void) -{ - return _stitch_preview; -} - #define HEADER_LENGTH 256 /* This function updates the header of the UV editor when the stitch tool updates its settings */ -static void stitch_update_header(StitchState *stitch_state, bContext *C) +static void stitch_update_header(StitchState *state, bContext *C) { - static char str[] = "(S)nap %s, (M)idpoints %s, (L)imit %.2f (Alt Wheel adjust) %s, Switch (I)sland, shift select vertices"; + static char str[] = "Mode(TAB) %s, (S)nap %s, (M)idpoints %s, (L)imit %.2f (Alt Wheel adjust) %s, Switch (I)sland, shift select vertices"; char msg[HEADER_LENGTH]; ScrArea *sa = CTX_wm_area(C); if (sa) { BLI_snprintf(msg, HEADER_LENGTH, str, - stitch_state->snap_islands ? "On" : "Off", - stitch_state->midpoints ? "On" : "Off", - stitch_state->limit_dist, - stitch_state->use_limit ? "On" : "Off"); + state->mode == STITCH_VERT ? "Vertex" : "Edge", + state->snap_islands ? "On" : "Off", + state->midpoints ? "On" : "Off", + state->limit_dist, + state->use_limit ? "On" : "Off"); ED_area_headerprint(sa, msg); } @@ -292,30 +299,29 @@ static void stitch_uv_rotate(float rotation, float medianPoint[2], float uv[2]) uv[1] = uv_rotation_result[1] + medianPoint[1]; } +/* check if two uvelements are stitchable. This should only operate on -different- separate UvElements */ static int stitch_check_uvs_stitchable(UvElement *element, UvElement *element_iter, StitchState *state) { float limit; - int do_limit; if (element_iter == element) { return 0; } limit = state->limit_dist; - do_limit = state->use_limit; - if (do_limit) { - MLoopUV *luv_orig, *luv_iter; - BMLoop *l_orig, *l_iter; + if (state->use_limit) { + MLoopUV *luv, *luv_iter; + BMLoop *l; - l_orig = element->l; - luv_orig = CustomData_bmesh_get(&state->em->bm->ldata, l_orig->head.data, CD_MLOOPUV); - l_iter = element_iter->l; - luv_iter = CustomData_bmesh_get(&state->em->bm->ldata, l_iter->head.data, CD_MLOOPUV); + l = element->l; + luv = CustomData_bmesh_get(&state->em->bm->ldata, l->head.data, CD_MLOOPUV); + l = element_iter->l; + luv_iter = CustomData_bmesh_get(&state->em->bm->ldata, l->head.data, CD_MLOOPUV); - if (fabsf(luv_orig->uv[0] - luv_iter->uv[0]) < limit && - fabsf(luv_orig->uv[1] - luv_iter->uv[1]) < limit) + if (fabsf(luv->uv[0] - luv_iter->uv[0]) < limit && + fabsf(luv->uv[1] - luv_iter->uv[1]) < limit) { return 1; } @@ -328,6 +334,46 @@ static int stitch_check_uvs_stitchable(UvElement *element, UvElement *element_it } } +static int stitch_check_edges_stitchable(UvEdge *edge, UvEdge *edge_iter, StitchState *state) +{ + float limit; + + if (edge_iter == edge) { + return 0; + } + + limit = state->limit_dist; + + if(state->use_limit) { + BMLoop *l; + MLoopUV *luv_orig1, *luv_iter1; + MLoopUV *luv_orig2, *luv_iter2; + + l = state->uvs[edge->uv1]->l; + luv_orig1 = CustomData_bmesh_get(&state->em->bm->ldata, l->head.data, CD_MLOOPUV); + l = state->uvs[edge_iter->uv1]->l; + luv_iter1 = CustomData_bmesh_get(&state->em->bm->ldata, l->head.data, CD_MLOOPUV); + + l = state->uvs[edge->uv2]->l; + luv_orig2 = CustomData_bmesh_get(&state->em->bm->ldata, l->head.data, CD_MLOOPUV); + l = state->uvs[edge_iter->uv2]->l; + luv_iter2 = CustomData_bmesh_get(&state->em->bm->ldata, l->head.data, CD_MLOOPUV); + + if (fabsf(luv_orig1->uv[0] - luv_iter1->uv[0]) < limit && + fabsf(luv_orig1->uv[1] - luv_iter1->uv[1]) < limit && + fabsf(luv_orig2->uv[0] - luv_iter2->uv[0]) < limit && + fabsf(luv_orig2->uv[1] - luv_iter2->uv[1]) < limit) + { + return 1; + } + else { + return 0; + } + } + else { + return 1; + } +} static int stitch_check_uvs_state_stitchable(UvElement *element, UvElement *element_iter, StitchState *state) { @@ -341,6 +387,17 @@ static int stitch_check_uvs_state_stitchable(UvElement *element, UvElement *elem } +static int stitch_check_edges_state_stitchable(UvEdge *edge, UvEdge *edge_iter, StitchState *state) +{ + if ((state->snap_islands && edge->element->island == edge_iter->element->island) || + (!state->midpoints && edge->element->island == edge_iter->element->island)) + { + return 0; + } + + return stitch_check_edges_stitchable(edge, edge_iter, state); +} + /* calculate snapping for islands */ static void stitch_calculate_island_snapping(StitchState *state, PreviewPosition *preview_position, StitchPreviewer *preview, IslandStitchData *island_stitch_data, int final) { @@ -378,7 +435,7 @@ static void stitch_calculate_island_snapping(StitchState *state, PreviewPosition } else { - int face_preview_pos = preview_position[BM_elem_index_get(element->face)].data_position; + int face_preview_pos = preview_position[BM_elem_index_get(element->l->f)].data_position; stitch_uv_rotate(island_stitch_data[i].rotation, island_stitch_data[i].medianPoint, preview->preview_polys + face_preview_pos + 2 * element->tfindex); @@ -414,9 +471,13 @@ static void stitch_island_calculate_edge_rotation(UvEdge *edge, StitchState *sta l2 = element2->l; luv2 = CustomData_bmesh_get(&state->em->bm->ldata, l2->head.data, CD_MLOOPUV); - index1 = uvfinal_map[element1 - state->element_map->buf]; - index2 = uvfinal_map[element2 - state->element_map->buf]; - + if (state->mode == STITCH_VERT) { + index1 = uvfinal_map[element1 - state->element_map->buf]; + index2 = uvfinal_map[element2 - state->element_map->buf]; + } else { + index1 = edge->uv1; + index2 = edge->uv2; + } /* the idea here is to take the directions of the edges and find the rotation between final and initial * direction. This, using inner and outer vector products, gives the angle. Directions are differences so... */ uv1[0] = luv2->uv[0] - luv1->uv[0]; @@ -461,7 +522,10 @@ static void stitch_island_calculate_vert_rotation(UvElement *element, StitchStat if (element_iter->separate && stitch_check_uvs_state_stitchable(element, element_iter, state)) { int index_tmp1, index_tmp2; float normal[2]; - /* easily possible*/ + + /* only calculate rotation against static island uv verts */ + if(!state->midpoints && element_iter->island != state->static_island) + continue; index_tmp1 = element_iter - state->element_map->buf; index_tmp1 = state->map[index_tmp1]; @@ -482,34 +546,112 @@ static void stitch_island_calculate_vert_rotation(UvElement *element, StitchStat } -static void stitch_state_delete(StitchState *stitch_state) +static void state_delete(StitchState *state) { - if (stitch_state) { - if (stitch_state->element_map) { - EDBM_uv_element_map_free(stitch_state->element_map); + if (state) { + if (state->element_map) { + EDBM_uv_element_map_free(state->element_map); } - if (stitch_state->uvs) { - MEM_freeN(stitch_state->uvs); + if (state->uvs) { + MEM_freeN(state->uvs); } - if (stitch_state->selection_stack) { - MEM_freeN(stitch_state->selection_stack); + if (state->selection_stack) { + MEM_freeN(state->selection_stack); } - if (stitch_state->tris_per_island) { - MEM_freeN(stitch_state->tris_per_island); + if (state->tris_per_island) { + MEM_freeN(state->tris_per_island); } - if (stitch_state->map) { - MEM_freeN(stitch_state->map); + if (state->map) { + MEM_freeN(state->map); } - if (stitch_state->normals) { - MEM_freeN(stitch_state->normals); + if (state->normals) { + MEM_freeN(state->normals); } - if (stitch_state->edges) { - MEM_freeN(stitch_state->edges); + if (state->edges) { + MEM_freeN(state->edges); } - MEM_freeN(stitch_state); + if (state->stitch_preview) { + stitch_preview_delete(state->stitch_preview); + } + if (state->edge_hash) { + BLI_ghash_free(state->edge_hash, NULL, NULL); + } + MEM_freeN(state); } } +static void stitch_uv_edge_generate_linked_edges(GHash *edge_hash, StitchState *state) +{ + UvEdge *edges = state->edges; + int *map = state->map; + UvElementMap *element_map = state->element_map; + UvElement *first_element = element_map->buf; + int i; + + for (i = 0; i < state->total_separate_edges; i++) { + UvEdge *edge = edges + i; + + if(edge->first) + continue; + + /* only boundary edges can be stitched. Yes. Sorry about that :p */ + if(edge->flag & STITCH_BOUNDARY) { + UvElement *element1 = state->uvs[edge->uv1]; + UvElement *element2 = state->uvs[edge->uv2]; + + /* Now iterate through all faces and try to find edges sharing the same vertices */ + UvElement *iter1 = element_map->vert[BM_elem_index_get(element1->l->v)]; + UvEdge *last_set = edge; + int elemindex2 = BM_elem_index_get(element2->l->v); + + edge->first = edge; + + for (; iter1; iter1 = iter1->next) { + UvElement *iter2 = NULL; + + /* check to see if other vertex of edge belongs to same vertex as */ + if(BM_elem_index_get(iter1->l->next->v) == elemindex2) + iter2 = ED_uv_element_get(element_map, iter1->l->f, iter1->l->next); + else if(BM_elem_index_get(iter1->l->prev->v) == elemindex2) + iter2 = ED_uv_element_get(element_map, iter1->l->f, iter1->l->prev); + + if(iter2) { + int index1 = map[iter1 - first_element]; + int index2 = map[iter2 - first_element]; + + /* make certain we do not have the same edge! */ + if(state->uvs[index2] != element2 && state->uvs[index1] != element1) { + UvEdge edgetmp; + UvEdge *edge2; + + + /* make sure the indices are well behaved */ + if(index1 < index2) { + edgetmp.uv1 = index1; + edgetmp.uv2 = index2; + } else { + edgetmp.uv1 = index2; + edgetmp.uv2 = index1; + } + + /* get the edge from the hash */ + edge2 = BLI_ghash_lookup(edge_hash, &edgetmp); + + /* here I am taking care of non manifold case, assuming more than two matching edges. + * I am not too sure we want this though */ + last_set->next = edge2; + last_set = edge2; + /* set first, similarly to uv elements. Now we can iterate among common edges easily */ + edge2->first = edge; + } + } + } + } else { + /* so stitchability code works */ + edge->first = edge; + } + } +} /* checks for remote uvs that may be stitched with a certain uv, flags them if stitchable. */ @@ -526,9 +668,6 @@ static void determine_uv_stitchability(UvElement *element, StitchState *state, I for (; element_iter; element_iter = element_iter->next) { if (element_iter->separate) { - if (element_iter == element) { - continue; - } if (stitch_check_uvs_stitchable(element, element_iter, state)) { island_stitch_data[element_iter->island].stitchableCandidate = 1; island_stitch_data[element->island].stitchableCandidate = 1; @@ -538,6 +677,19 @@ static void determine_uv_stitchability(UvElement *element, StitchState *state, I } } +static void determine_uv_edge_stitchability(UvEdge *edge, StitchState *state, IslandStitchData *island_stitch_data) +{ + UvEdge *edge_iter = edge->first; + + for (; edge_iter; edge_iter = edge_iter->next) { + if(stitch_check_edges_stitchable(edge, edge_iter, state)) { + island_stitch_data[edge_iter->element->island].stitchableCandidate = 1; + island_stitch_data[edge->element->island].stitchableCandidate = 1; + edge->flag |= STITCH_STITCHABLE_CANDIDATE; + } + } +} + /* set preview buffer position of UV face in editface->tmp.l */ static void stitch_set_face_preview_buffer_position(BMFace *efa, StitchPreviewer *preview, PreviewPosition *preview_position) @@ -555,7 +707,7 @@ static void stitch_set_face_preview_buffer_position(BMFace *efa, StitchPreviewer /* setup face preview for all coincident uvs and their faces */ static void stitch_setup_face_preview_for_uv_group(UvElement *element, StitchState *state, IslandStitchData *island_stitch_data, PreviewPosition *preview_position) { - StitchPreviewer *preview = uv_get_stitch_previewer(); + StitchPreviewer *preview = state->stitch_preview; /* static island does not change so returning immediately */ if (state->snap_islands && !state->midpoints && state->static_island == element->island) @@ -566,17 +718,17 @@ static void stitch_setup_face_preview_for_uv_group(UvElement *element, StitchSta } do { - stitch_set_face_preview_buffer_position(element->face, preview, preview_position); + stitch_set_face_preview_buffer_position(element->l->f, preview, preview_position); element = element->next; } while (element && !element->separate); } /* checks if uvs are indeed stitchable and registers so that they can be shown in preview */ -static void stitch_validate_stichability(UvElement *element, StitchState *state, IslandStitchData *island_stitch_data, +static void stitch_validate_uv_stichability(UvElement *element, StitchState *state, IslandStitchData *island_stitch_data, PreviewPosition *preview_position) { UvElement *element_iter; - StitchPreviewer *preview; + StitchPreviewer *preview = state->stitch_preview; int vert_index; BMLoop *l; @@ -584,7 +736,6 @@ static void stitch_validate_stichability(UvElement *element, StitchState *state, vert_index = BM_elem_index_get(l->v); - preview = uv_get_stitch_previewer(); element_iter = state->element_map->vert[vert_index]; for (; element_iter; element_iter = element_iter->next) { @@ -608,6 +759,72 @@ static void stitch_validate_stichability(UvElement *element, StitchState *state, } } + +static void stitch_validate_edge_stichability(UvEdge *edge, StitchState *state, IslandStitchData *island_stitch_data, + PreviewPosition *preview_position) { + UvEdge *edge_iter = edge->first; + StitchPreviewer *preview = state->stitch_preview; + + for (; edge_iter; edge_iter = edge_iter->next) { + if (edge_iter == edge) + continue; + if (stitch_check_edges_state_stitchable(edge, edge_iter, state)) { + if ((edge_iter->element->island == state->static_island) || (edge->element->island == state->static_island)) { + edge->flag |= STITCH_STITCHABLE; + preview->num_stitchable++; + stitch_setup_face_preview_for_uv_group(state->uvs[edge->uv1], state, island_stitch_data, preview_position); + stitch_setup_face_preview_for_uv_group(state->uvs[edge->uv2], state, island_stitch_data, preview_position); + return; + } + } + } + + /* this can happen if the uvs to be stitched are not on a stitchable island */ + if (!(edge->flag & STITCH_STITCHABLE)) { + preview->num_unstitchable++; + } +} + + +static void stitch_propagate_uv_final_position (UvElement *element, int index, PreviewPosition *preview_position, UVVertAverage *final_position, StitchState *state, char final, Scene* scene) +{ + StitchPreviewer *preview = state->stitch_preview; + + if (element->flag & STITCH_STITCHABLE) { + UvElement *element_iter = element; + /* propagate to coincident uvs */ + do { + BMLoop *l; + MLoopUV *luv; + + l = element_iter->l; + luv = CustomData_bmesh_get(&state->em->bm->ldata, l->head.data, CD_MLOOPUV); + + element_iter->flag |= STITCH_PROCESSED; + /* either flush to preview or to the MTFace, if final */ + if (final) { + copy_v2_v2(luv->uv, final_position[index].uv); + + uvedit_uv_select_enable(state->em, scene, l, FALSE); + } + else { + int face_preview_pos = preview_position[BM_elem_index_get(element_iter->l->f)].data_position; + if (face_preview_pos != STITCH_NO_PREVIEW) { + copy_v2_v2(preview->preview_polys + face_preview_pos + 2 * element_iter->tfindex, + final_position[index].uv); + } + } + + /* end of calculations, keep only the selection flag */ + if ( (!state->snap_islands) || ((!state->midpoints) && (element_iter->island == state->static_island))) { + element_iter->flag &= STITCH_SELECTED; + } + + element_iter = element_iter->next; + } while (element_iter && !element_iter->separate); + } +} + /* main processing function. It calculates preview and final positions. */ static int stitch_process_data(StitchState *state, Scene *scene, int final) { @@ -618,6 +835,7 @@ static int stitch_process_data(StitchState *state, Scene *scene, int final) BMFace *efa; BMIter iter; UVVertAverage *final_position; + char stitch_midpoints = state->midpoints; /* used to map uv indices to uvaverage indices for selection */ unsigned int *uvfinal_map; @@ -625,8 +843,8 @@ static int stitch_process_data(StitchState *state, Scene *scene, int final) PreviewPosition *preview_position; /* cleanup previous preview */ - stitch_preview_delete(); - preview = stitch_preview_init(); + stitch_preview_delete(state->stitch_preview); + preview = state->stitch_preview = stitch_preview_init(); if (preview == NULL) return 0; @@ -649,8 +867,13 @@ static int stitch_process_data(StitchState *state, Scene *scene, int final) *****************************************/ for (i = 0; i < state->selection_size; i++) { - UvElement *element = state->selection_stack[i]; - determine_uv_stitchability(element, state, island_stitch_data); + if(state->mode == STITCH_VERT) { + UvElement *element = (UvElement *)state->selection_stack[i]; + determine_uv_stitchability(element, state, island_stitch_data); + } else { + UvEdge *edge = (UvEdge *)state->selection_stack[i]; + determine_uv_edge_stitchability(edge, state, island_stitch_data); + } } /* set static island to one that is added for preview */ @@ -664,14 +887,25 @@ static int stitch_process_data(StitchState *state, Scene *scene, int final) } for (i = 0; i < state->selection_size; i++) { - UvElement *element = state->selection_stack[i]; - if (element->flag & STITCH_STITCHABLE_CANDIDATE) { - element->flag &= ~STITCH_STITCHABLE_CANDIDATE; - stitch_validate_stichability(element, state, island_stitch_data, preview_position); - } - else { - /* add to preview for unstitchable */ - preview->num_unstitchable++; + if(state->mode == STITCH_VERT) { + UvElement *element = (UvElement *)state->selection_stack[i]; + if (element->flag & STITCH_STITCHABLE_CANDIDATE) { + element->flag &= ~STITCH_STITCHABLE_CANDIDATE; + stitch_validate_uv_stichability(element, state, island_stitch_data, preview_position); + } + else { + /* add to preview for unstitchable */ + preview->num_unstitchable++; + } + } else { + UvEdge *edge = (UvEdge *)state->selection_stack[i]; + if(edge->flag & STITCH_STITCHABLE_CANDIDATE) { + edge->flag &= ~STITCH_STITCHABLE_CANDIDATE; + stitch_validate_edge_stichability(edge, state, island_stitch_data, preview_position); + } + else { + preview->num_unstitchable++; + } } } @@ -686,7 +920,7 @@ static int stitch_process_data(StitchState *state, Scene *scene, int final) numOfIslandUVs = getNumOfIslandUvs(state->element_map, i); element = &state->element_map->buf[state->element_map->islandIndices[i]]; for (j = 0; j < numOfIslandUVs; j++, element++) { - stitch_set_face_preview_buffer_position(element->face, preview, preview_position); + stitch_set_face_preview_buffer_position(element->l->f, preview, preview_position); } } } @@ -701,11 +935,12 @@ static int stitch_process_data(StitchState *state, Scene *scene, int final) MLoopUV *luv; unsigned int buffer_index = 0; int stitchBufferIndex = 0, unstitchBufferIndex = 0; + int preview_size = (state->mode == STITCH_VERT) ? 2 : 4; /* initialize the preview buffers */ preview->preview_polys = (float *)MEM_mallocN(preview->preview_uvs * sizeof(float) * 2, "tri_uv_stitch_prev"); preview->uvs_per_polygon = MEM_mallocN(preview->num_polys * sizeof(*preview->uvs_per_polygon), "tri_uv_stitch_prev"); - preview->preview_stitchable = (float *)MEM_mallocN(preview->num_stitchable * sizeof(float) * 2, "stitch_preview_stichable_data"); - preview->preview_unstitchable = (float *)MEM_mallocN(preview->num_unstitchable * sizeof(float) * 2, "stitch_preview_unstichable_data"); + preview->preview_stitchable = (float *)MEM_mallocN(preview->num_stitchable * sizeof(float) * preview_size, "stitch_preview_stichable_data"); + preview->preview_unstitchable = (float *)MEM_mallocN(preview->num_unstitchable * sizeof(float) * preview_size, "stitch_preview_unstichable_data"); preview->static_tris = (float *)MEM_mallocN(state->tris_per_island[state->static_island] * sizeof(float) * 6, "static_island_preview_tris"); @@ -715,7 +950,7 @@ static int stitch_process_data(StitchState *state, Scene *scene, int final) return 0; } - /* copy data from MTFaces to the preview display buffers */ + /* copy data from MLoopUVs to the preview display buffers */ BM_ITER_MESH (efa, &iter, state->em->bm, BM_FACES_OF_MESH) { /* just to test if face was added for processing. uvs of inselected vertices will return NULL */ UvElement *element = ED_uv_element_get(state->element_map, efa, BM_FACE_FIRST_LOOP(efa)); @@ -757,22 +992,54 @@ static int stitch_process_data(StitchState *state, Scene *scene, int final) } /* fill the appropriate preview buffers */ - for (i = 0; i < state->total_separate_uvs; i++) { - UvElement *element = (UvElement *)state->uvs[i]; - if (element->flag & STITCH_STITCHABLE) { - l = element->l; - luv = CustomData_bmesh_get(&state->em->bm->ldata, l->head.data, CD_MLOOPUV); + if(state->mode == STITCH_VERT) { + for (i = 0; i < state->total_separate_uvs; i++) { + UvElement *element = (UvElement *)state->uvs[i]; + if (element->flag & STITCH_STITCHABLE) { + l = element->l; + luv = CustomData_bmesh_get(&state->em->bm->ldata, l->head.data, CD_MLOOPUV); - copy_v2_v2(&preview->preview_stitchable[stitchBufferIndex * 2], luv->uv); + copy_v2_v2(&preview->preview_stitchable[stitchBufferIndex * 2], luv->uv); - stitchBufferIndex++; + stitchBufferIndex++; + } + else if (element->flag & STITCH_SELECTED) { + l = element->l; + luv = CustomData_bmesh_get(&state->em->bm->ldata, l->head.data, CD_MLOOPUV); + + copy_v2_v2(&preview->preview_unstitchable[unstitchBufferIndex * 2], luv->uv); + unstitchBufferIndex++; + } } - else if (element->flag & STITCH_SELECTED) { - l = element->l; - luv = CustomData_bmesh_get(&state->em->bm->ldata, l->head.data, CD_MLOOPUV); + } else { + for (i = 0; i < state->total_separate_edges; i++) { + UvEdge *edge = state->edges + i; + UvElement *element1 = state->uvs[edge->uv1]; + UvElement *element2 = state->uvs[edge->uv2]; - copy_v2_v2(&preview->preview_unstitchable[unstitchBufferIndex * 2], luv->uv); - unstitchBufferIndex++; + if(edge->flag & STITCH_STITCHABLE) { + l = element1->l; + luv = CustomData_bmesh_get(&state->em->bm->ldata, l->head.data, CD_MLOOPUV); + copy_v2_v2(&preview->preview_stitchable[stitchBufferIndex * 4], luv->uv); + + l = element2->l; + luv = CustomData_bmesh_get(&state->em->bm->ldata, l->head.data, CD_MLOOPUV); + copy_v2_v2(&preview->preview_stitchable[stitchBufferIndex * 4 + 2], luv->uv); + + stitchBufferIndex++; + BLI_assert(stitchBufferIndex <= preview->num_stitchable); + } else if (edge->flag & STITCH_SELECTED) { + l = element1->l; + luv = CustomData_bmesh_get(&state->em->bm->ldata, l->head.data, CD_MLOOPUV); + copy_v2_v2(&preview->preview_unstitchable[unstitchBufferIndex * 4], luv->uv); + + l = element2->l; + luv = CustomData_bmesh_get(&state->em->bm->ldata, l->head.data, CD_MLOOPUV); + copy_v2_v2(&preview->preview_unstitchable[unstitchBufferIndex * 4 + 2], luv->uv); + + unstitchBufferIndex++; + BLI_assert(unstitchBufferIndex <= preview->num_unstitchable); + } } } } @@ -781,141 +1048,215 @@ static int stitch_process_data(StitchState *state, Scene *scene, int final) * Here we calculate the final coordinates of the uvs * ******************************************************/ - final_position = MEM_callocN(state->selection_size * sizeof(*final_position), "stitch_uv_average"); - uvfinal_map = MEM_mallocN(state->element_map->totalUVs * sizeof(*uvfinal_map), "stitch_uv_final_map"); + if (state->mode == STITCH_VERT) { + final_position = MEM_callocN(state->selection_size * sizeof(*final_position), "stitch_uv_average"); + uvfinal_map = MEM_mallocN(state->element_map->totalUVs * sizeof(*uvfinal_map), "stitch_uv_final_map"); + } else { + final_position = MEM_callocN(state->total_separate_uvs * sizeof(*final_position), "stitch_uv_average"); + } /* first pass, calculate final position for stitchable uvs of the static island */ for (i = 0; i < state->selection_size; i++) { - UvElement *element = state->selection_stack[i]; - if (element->flag & STITCH_STITCHABLE) { - BMLoop *l; - MLoopUV *luv; - UvElement *element_iter; + if (state->mode == STITCH_VERT) { + UvElement *element = state->selection_stack[i]; - l = element->l; - luv = CustomData_bmesh_get(&state->em->bm->ldata, l->head.data, CD_MLOOPUV); + if (element->flag & STITCH_STITCHABLE) { + BMLoop *l; + MLoopUV *luv; + UvElement *element_iter; + l = element->l; + luv = CustomData_bmesh_get(&state->em->bm->ldata, l->head.data, CD_MLOOPUV); - uvfinal_map[element - state->element_map->buf] = i; + uvfinal_map[element - state->element_map->buf] = i; - copy_v2_v2(final_position[i].uv, luv->uv); - final_position[i].count = 1; + copy_v2_v2(final_position[i].uv, luv->uv); + final_position[i].count = 1; - if (state->snap_islands && element->island == state->static_island && !stitch_midpoints) - continue; + if (state->snap_islands && element->island == state->static_island && !stitch_midpoints) + continue; - element_iter = state->element_map->vert[BM_elem_index_get(l->v)]; + element_iter = state->element_map->vert[BM_elem_index_get(l->v)]; - for ( ; element_iter; element_iter = element_iter->next) { - if (element_iter->separate) { - if (stitch_check_uvs_state_stitchable(element, element_iter, state)) { - l = element_iter->l; - luv = CustomData_bmesh_get(&state->em->bm->ldata, l->head.data, CD_MLOOPUV); - if (stitch_midpoints) { - add_v2_v2(final_position[i].uv, luv->uv); - final_position[i].count++; - } - else if (element_iter->island == state->static_island) { - /* if multiple uvs on the static island exist, - * last checked remains. to disambiguate we need to limit or use - * edge stitch */ - copy_v2_v2(final_position[i].uv, luv->uv); + for ( ; element_iter; element_iter = element_iter->next) { + if (element_iter->separate) { + if (stitch_check_uvs_state_stitchable(element, element_iter, state)) { + l = element_iter->l; + luv = CustomData_bmesh_get(&state->em->bm->ldata, l->head.data, CD_MLOOPUV); + if (stitch_midpoints) { + add_v2_v2(final_position[i].uv, luv->uv); + final_position[i].count++; + } + else if (element_iter->island == state->static_island) { + /* if multiple uvs on the static island exist, + * last checked remains. to disambiguate we need to limit or use + * edge stitch */ + copy_v2_v2(final_position[i].uv, luv->uv); + } + } + } + } + } + if (stitch_midpoints) { + final_position[i].uv[0] /= final_position[i].count; + final_position[i].uv[1] /= final_position[i].count; + } + } else { + UvEdge *edge = state->selection_stack[i]; + + if (edge->flag & STITCH_STITCHABLE) { + MLoopUV *luv2, *luv1; + BMLoop *l; + UvEdge *edge_iter; + + l = state->uvs[edge->uv1]->l; + luv1 = CustomData_bmesh_get(&state->em->bm->ldata, l->head.data, CD_MLOOPUV); + l = state->uvs[edge->uv2]->l; + luv2 = CustomData_bmesh_get(&state->em->bm->ldata, l->head.data, CD_MLOOPUV); + + copy_v2_v2(final_position[edge->uv1].uv, luv1->uv); + copy_v2_v2(final_position[edge->uv2].uv, luv2->uv); + final_position[edge->uv1].count = 1; + final_position[edge->uv2].count = 1; + + state->uvs[edge->uv1]->flag |= STITCH_STITCHABLE; + state->uvs[edge->uv2]->flag |= STITCH_STITCHABLE; + + if (state->snap_islands && edge->element->island == state->static_island && !stitch_midpoints) + continue; + + for (edge_iter = edge->first; edge_iter; edge_iter = edge_iter->next) { + if (stitch_check_edges_state_stitchable (edge, edge_iter, state)) { + l = state->uvs[edge_iter->uv1]->l; + luv1 = CustomData_bmesh_get(&state->em->bm->ldata, l->head.data, CD_MLOOPUV); + l = state->uvs[edge_iter->uv2]->l; + luv2 = CustomData_bmesh_get(&state->em->bm->ldata, l->head.data, CD_MLOOPUV); + + if(stitch_midpoints) { + add_v2_v2(final_position[edge->uv1].uv, luv1->uv); + final_position[edge->uv1].count++; + add_v2_v2(final_position[edge->uv2].uv, luv2->uv); + final_position[edge->uv2].count++; + } + else if (edge_iter->element->island == state->static_island) { + copy_v2_v2(final_position[edge->uv1].uv, luv1->uv); + copy_v2_v2(final_position[edge->uv2].uv, luv2->uv); } } } } - } - if (stitch_midpoints) { - final_position[i].uv[0] /= final_position[i].count; - final_position[i].uv[1] /= final_position[i].count; } } /* second pass, calculate island rotation and translation before modifying any uvs */ if (state->snap_islands) { - for (i = 0; i < state->selection_size; i++) { - UvElement *element = state->selection_stack[i]; - if (element->flag & STITCH_STITCHABLE) { - BMLoop *l; - MLoopUV *luv; + if (state->mode == STITCH_VERT) { + for (i = 0; i < state->selection_size; i++) { + UvElement *element = state->selection_stack[i]; - l = element->l; - luv = CustomData_bmesh_get(&state->em->bm->ldata, l->head.data, CD_MLOOPUV); - - /* accumulate each islands' translation from stitchable elements. it is important to do here - * because in final pass MTFaces get modified and result is zero. */ - island_stitch_data[element->island].translation[0] += final_position[i].uv[0] - luv->uv[0]; - island_stitch_data[element->island].translation[1] += final_position[i].uv[1] - luv->uv[1]; - island_stitch_data[element->island].medianPoint[0] += luv->uv[0]; - island_stitch_data[element->island].medianPoint[1] += luv->uv[1]; - island_stitch_data[element->island].numOfElements++; - } - } - - /* only calculate rotation when an edge has been fully selected */ - for (i = 0; i < state->total_boundary_edges; i++) { - UvEdge *edge = state->edges + i; - if ((state->uvs[edge->uv1]->flag & STITCH_STITCHABLE) && (state->uvs[edge->uv2]->flag & STITCH_STITCHABLE)) { - stitch_island_calculate_edge_rotation(edge, state, final_position, uvfinal_map, island_stitch_data); - island_stitch_data[state->uvs[edge->uv1]->island].use_edge_rotation = TRUE; - } - } - - /* clear seams of stitched edges */ - if (final && state->clear_seams) { - for (i = 0; i < state->total_boundary_edges; i++) { - UvEdge *edge = state->edges + i; - if ((state->uvs[edge->uv1]->flag & STITCH_STITCHABLE) && (state->uvs[edge->uv2]->flag & STITCH_STITCHABLE)) - BM_elem_flag_disable(edge->element->l->e, BM_ELEM_SEAM); - } - } - - for (i = 0; i < state->selection_size; i++) { - UvElement *element = state->selection_stack[i]; - if (!island_stitch_data[element->island].use_edge_rotation) { if (element->flag & STITCH_STITCHABLE) { - stitch_island_calculate_vert_rotation(element, state, island_stitch_data); + BMLoop *l; + MLoopUV *luv; + + l = element->l; + luv = CustomData_bmesh_get(&state->em->bm->ldata, l->head.data, CD_MLOOPUV); + + /* accumulate each islands' translation from stitchable elements. it is important to do here + * because in final pass MTFaces get modified and result is zero. */ + island_stitch_data[element->island].translation[0] += final_position[i].uv[0] - luv->uv[0]; + island_stitch_data[element->island].translation[1] += final_position[i].uv[1] - luv->uv[1]; + island_stitch_data[element->island].medianPoint[0] += luv->uv[0]; + island_stitch_data[element->island].medianPoint[1] += luv->uv[1]; + island_stitch_data[element->island].numOfElements++; + } + } + + /* only calculate rotation when an edge has been fully selected */ + for (i = 0; i < state->total_separate_edges; i++) { + UvEdge *edge = state->edges + i; + if ((edge->flag & STITCH_BOUNDARY) && (state->uvs[edge->uv1]->flag & STITCH_STITCHABLE) && (state->uvs[edge->uv2]->flag & STITCH_STITCHABLE)) { + stitch_island_calculate_edge_rotation(edge, state, final_position, uvfinal_map, island_stitch_data); + island_stitch_data[state->uvs[edge->uv1]->island].use_edge_rotation = TRUE; + } + } + + /* clear seams of stitched edges */ + if (final && state->clear_seams) { + for (i = 0; i < state->total_separate_edges; i++) { + UvEdge *edge = state->edges + i; + if ((state->uvs[edge->uv1]->flag & STITCH_STITCHABLE) && (state->uvs[edge->uv2]->flag & STITCH_STITCHABLE)) + BM_elem_flag_disable(edge->element->l->e, BM_ELEM_SEAM); + } + } + + for (i = 0; i < state->selection_size; i++) { + UvElement *element = state->selection_stack[i]; + if (!island_stitch_data[element->island].use_edge_rotation) { + if (element->flag & STITCH_STITCHABLE) { + stitch_island_calculate_vert_rotation(element, state, island_stitch_data); + } + } + } + } else { + for (i = 0; i < state->total_separate_uvs; i++) { + UvElement *element = state->uvs[i]; + + if (stitch_midpoints) { + final_position[i].uv[0] /= final_position[i].count; + final_position[i].uv[1] /= final_position[i].count; + } + + if (element->flag & STITCH_STITCHABLE) { + BMLoop *l; + MLoopUV *luv; + + l = element->l; + luv = CustomData_bmesh_get(&state->em->bm->ldata, l->head.data, CD_MLOOPUV); + + /* accumulate each islands' translation from stitchable elements. it is important to do here + * because in final pass MTFaces get modified and result is zero. */ + island_stitch_data[element->island].translation[0] += final_position[i].uv[0] - luv->uv[0]; + island_stitch_data[element->island].translation[1] += final_position[i].uv[1] - luv->uv[1]; + island_stitch_data[element->island].medianPoint[0] += luv->uv[0]; + island_stitch_data[element->island].medianPoint[1] += luv->uv[1]; + island_stitch_data[element->island].numOfElements++; + } + } + + for (i = 0; i < state->selection_size; i++) { + UvEdge *edge = state->selection_stack[i]; + + if(edge->flag & STITCH_STITCHABLE) { + stitch_island_calculate_edge_rotation(edge, state, final_position, NULL, island_stitch_data); + island_stitch_data[state->uvs[edge->uv1]->island].use_edge_rotation = TRUE; + } + } + + /* clear seams of stitched edges */ + if (final && state->clear_seams) { + for (i = 0; i < state->selection_size; i++) { + UvEdge *edge = state->selection_stack[i]; + if(edge->flag & STITCH_STITCHABLE) { + BM_elem_flag_disable(edge->element->l->e, BM_ELEM_SEAM); + } } } } - } /* third pass, propagate changes to coincident uvs */ for (i = 0; i < state->selection_size; i++) { - UvElement *element = state->selection_stack[i]; - if (element->flag & STITCH_STITCHABLE) { - UvElement *element_iter = element; - /* propagate to coincident uvs */ - do { - BMLoop *l; - MLoopUV *luv; + if (state->mode == STITCH_VERT) { + UvElement *element = state->selection_stack[i]; - l = element_iter->l; - luv = CustomData_bmesh_get(&state->em->bm->ldata, l->head.data, CD_MLOOPUV); + stitch_propagate_uv_final_position (element, i, preview_position, final_position, state, final, scene); + } else { + UvEdge *edge = state->selection_stack[i]; - element_iter->flag |= STITCH_PROCESSED; - /* either flush to preview or to the MTFace, if final */ - if (final) { - copy_v2_v2(luv->uv, final_position[i].uv); + stitch_propagate_uv_final_position (state->uvs[edge->uv1], edge->uv1, preview_position, final_position, state, final, scene); + stitch_propagate_uv_final_position (state->uvs[edge->uv2], edge->uv2, preview_position, final_position, state, final, scene); - uvedit_uv_select_enable(state->em, scene, l, FALSE); - } - else { - int face_preview_pos = preview_position[BM_elem_index_get(element_iter->face)].data_position; - if (face_preview_pos != STITCH_NO_PREVIEW) { - copy_v2_v2(preview->preview_polys + face_preview_pos + 2 * element_iter->tfindex, - final_position[i].uv); - } - } - - /* end of calculations, keep only the selection flag */ - if ( (!state->snap_islands) || ((!stitch_midpoints) && (element_iter->island == state->static_island))) { - element_iter->flag &= STITCH_SELECTED; - } - - element_iter = element_iter->next; - } while (element_iter && !element_iter->separate); + edge->flag &= (STITCH_SELECTED | STITCH_BOUNDARY); } } @@ -925,7 +1266,9 @@ static int stitch_process_data(StitchState *state, Scene *scene, int final) } MEM_freeN(final_position); - MEM_freeN(uvfinal_map); + if (state->mode == STITCH_VERT) { + MEM_freeN(uvfinal_map); + } MEM_freeN(island_stitch_data); MEM_freeN(preview_position); @@ -937,8 +1280,8 @@ static unsigned int uv_edge_hash(const void *key) { UvEdge *edge = (UvEdge *)key; return - BLI_ghashutil_inthash(SET_INT_IN_POINTER(edge->uv2)) + - BLI_ghashutil_inthash(SET_INT_IN_POINTER(edge->uv1)); + BLI_ghashutil_inthash(SET_INT_IN_POINTER(edge->uv2)) + + BLI_ghashutil_inthash(SET_INT_IN_POINTER(edge->uv1)); } static int uv_edge_compare(const void *a, const void *b) @@ -952,13 +1295,41 @@ static int uv_edge_compare(const void *a, const void *b) return 1; } +/* select all common edges */ +static void stitch_select_edge(UvEdge *edge, StitchState *state, int always_select) +{ + UvEdge *eiter; + UvEdge **selection_stack = (UvEdge **)state->selection_stack; + + for (eiter = edge->first; eiter; eiter = eiter->next) { + if (eiter->flag & STITCH_SELECTED) { + int i; + if (always_select) + continue; + + eiter->flag &= ~STITCH_SELECTED; + for (i = 0; i < state->selection_size; i++) { + if (selection_stack[i] == eiter) { + (state->selection_size)--; + selection_stack[i] = selection_stack[state->selection_size]; + break; + } + } + } + else { + eiter->flag |= STITCH_SELECTED; + selection_stack[state->selection_size++] = eiter; + } + } +} + /* Select all common uvs */ static void stitch_select_uv(UvElement *element, StitchState *state, int always_select) { BMLoop *l; UvElement *element_iter; - UvElement **selection_stack = state->selection_stack; + UvElement **selection_stack = (UvElement **)state->selection_stack; l = element->l; @@ -989,6 +1360,54 @@ static void stitch_select_uv(UvElement *element, StitchState *state, int always_ } } +static void stitch_switch_selection_mode(StitchState *state) +{ + void **old_selection_stack = state->selection_stack; + int old_selection_size = state->selection_size; + state->selection_size = 0; + + if (state->mode == STITCH_VERT) { + int i; + state->selection_stack = MEM_mallocN(state->total_separate_edges*sizeof(*state->selection_stack), + "stitch_new_edge_selection_stack"); + + /* check if both elements of an edge are selected */ + for (i = 0; i < state->total_separate_edges; i++) { + UvEdge *edge = state->edges + i; + UvElement *element1 = state->uvs[edge->uv1]; + UvElement *element2 = state->uvs[edge->uv2]; + + if ((element1->flag & STITCH_SELECTED) && (element2->flag & STITCH_SELECTED)) + stitch_select_edge(edge, state, TRUE); + } + + /* unselect selected uvelements */ + for (i = 0; i < old_selection_size; i++) { + UvElement *element = old_selection_stack[i]; + + element->flag &= ~STITCH_SELECTED; + } + state->mode = STITCH_EDGE; + } else { + int i; + state->selection_stack = MEM_mallocN(state->total_separate_uvs*sizeof(*state->selection_stack), + "stitch_new_vert_selection_stack"); + + for (i = 0; i < old_selection_size; i++) { + UvEdge *edge = old_selection_stack[i]; + UvElement *element1 = state->uvs[edge->uv1]; + UvElement *element2 = state->uvs[edge->uv2]; + + stitch_select_uv(element1, state, TRUE); + stitch_select_uv(element2, state, TRUE); + + edge->flag &= ~STITCH_SELECTED; + } + state->mode = STITCH_VERT; + } + MEM_freeN(old_selection_stack); +} + static void stitch_calculate_edge_normal(BMEditMesh *em, UvEdge *edge, float *normal) { BMLoop *l1 = edge->element->l; @@ -1007,11 +1426,12 @@ static void stitch_calculate_edge_normal(BMEditMesh *em, UvEdge *edge, float *no normalize_v2(normal); } -static void stitch_draw(const bContext *UNUSED(C), ARegion *UNUSED(ar), void *UNUSED(arg)) +static void stitch_draw(const bContext *UNUSED(C), ARegion *UNUSED(ar), void *arg) { int i, index = 0; float pointsize = UI_GetThemeValuef(TH_VERTEX_SIZE); - StitchPreviewer *stitch_preview = uv_get_stitch_previewer(); + StitchState *state = (StitchState *)arg; + StitchPreviewer *stitch_preview = state->stitch_preview; glPushClientAttrib(GL_CLIENT_VERTEX_ARRAY_BIT); glEnableClientState(GL_VERTEX_ARRAY); @@ -1042,24 +1462,56 @@ static void stitch_draw(const bContext *UNUSED(C), ARegion *UNUSED(ar), void *UN glDisable(GL_BLEND); /* draw vert preview */ - glPointSize(pointsize * 2.0f); - UI_ThemeColor4(TH_STITCH_PREVIEW_STITCHABLE); - glVertexPointer(2, GL_FLOAT, 0, stitch_preview->preview_stitchable); - glDrawArrays(GL_POINTS, 0, stitch_preview->num_stitchable); + if(state->mode == STITCH_VERT) { + glPointSize(pointsize * 2.0f); + UI_ThemeColor4(TH_STITCH_PREVIEW_STITCHABLE); + glVertexPointer(2, GL_FLOAT, 0, stitch_preview->preview_stitchable); + glDrawArrays(GL_POINTS, 0, stitch_preview->num_stitchable); - UI_ThemeColor4(TH_STITCH_PREVIEW_UNSTITCHABLE); - glVertexPointer(2, GL_FLOAT, 0, stitch_preview->preview_unstitchable); - glDrawArrays(GL_POINTS, 0, stitch_preview->num_unstitchable); + UI_ThemeColor4(TH_STITCH_PREVIEW_UNSTITCHABLE); + glVertexPointer(2, GL_FLOAT, 0, stitch_preview->preview_unstitchable); + glDrawArrays(GL_POINTS, 0, stitch_preview->num_unstitchable); + } else { + UI_ThemeColor4(TH_STITCH_PREVIEW_STITCHABLE); + glVertexPointer(2, GL_FLOAT, 0, stitch_preview->preview_stitchable); + glDrawArrays(GL_LINES, 0, 2*stitch_preview->num_stitchable); + + UI_ThemeColor4(TH_STITCH_PREVIEW_UNSTITCHABLE); + glVertexPointer(2, GL_FLOAT, 0, stitch_preview->preview_unstitchable); + glDrawArrays(GL_LINES, 0, 2*stitch_preview->num_unstitchable); + } glPopClientAttrib(); glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + glPointSize(1.0); +} + +static UvEdge *uv_edge_get (BMLoop *l, StitchState *state) +{ + UvEdge tmp_edge; + + UvElement *element1 = ED_uv_element_get(state->element_map, l->f, l); + UvElement *element2 = ED_uv_element_get(state->element_map, l->f, l->next); + + int uv1 = state->map[element1 - state->element_map->buf]; + int uv2 = state->map[element2 - state->element_map->buf]; + + if(uv1 < uv2) { + tmp_edge.uv1 = uv1; + tmp_edge.uv2 = uv2; + } else { + tmp_edge.uv1 = uv2; + tmp_edge.uv2 = uv1; + } + + return BLI_ghash_lookup(state->edge_hash, &tmp_edge); } static int stitch_init(bContext *C, wmOperator *op) { /* for fast edge lookup... */ - GHash *edgeHash; + GHash *edge_hash; /* ...and actual edge storage */ UvEdge *edges; int total_edges; @@ -1097,21 +1549,38 @@ static int stitch_init(bContext *C, wmOperator *op) state->static_island = RNA_int_get(op->ptr, "static_island"); state->midpoints = RNA_boolean_get(op->ptr, "midpoint_snap"); state->clear_seams = RNA_boolean_get(op->ptr, "clear_seams"); - state->draw_handle = ED_region_draw_cb_activate(ar->type, stitch_draw, NULL, REGION_DRAW_POST_VIEW); + if (RNA_struct_property_is_set(op->ptr, "mode")) { + state->mode = RNA_enum_get(op->ptr, "mode"); + } else { + if (ts->uv_flag & UV_SYNC_SELECTION) { + if (ts->selectmode & SCE_SELECT_VERTEX) + state->mode = STITCH_VERT; + else + state->mode = STITCH_EDGE; + } else { + if (ts->uv_selectmode & UV_SELECT_VERTEX) { + state->mode = STITCH_VERT; + } else { + state->mode = STITCH_EDGE; + } + } + } + + state->draw_handle = ED_region_draw_cb_activate(ar->type, stitch_draw, state, REGION_DRAW_POST_VIEW); /* in uv synch selection, all uv's are visible */ if (ts->uv_flag & UV_SYNC_SELECTION) { - state->element_map = EDBM_uv_element_map_create(state->em, 0, 1); + state->element_map = EDBM_uv_element_map_create(state->em, FALSE, TRUE); } else { - state->element_map = EDBM_uv_element_map_create(state->em, 1, 1); + state->element_map = EDBM_uv_element_map_create(state->em, TRUE, TRUE); } if (!state->element_map) { - stitch_state_delete(state); + state_delete(state); return 0; } /* Entirely possible if redoing last operator that static island is bigger than total number of islands. - * This ensures we get no hang in the island checking code in stitch_process_data. */ + * This ensures we get no hang in the island checking code in stitch_stitch_process_data. */ state->static_island %= state->element_map->totalIslands; /* Count 'unique' uvs */ @@ -1121,22 +1590,21 @@ static int stitch_init(bContext *C, wmOperator *op) } } + /* explicitly set preview to NULL, to avoid deleting an invalid pointer on stitch_process_data */ + state->stitch_preview = NULL; /* Allocate the unique uv buffers */ state->uvs = MEM_mallocN(sizeof(*state->uvs) * counter, "uv_stitch_unique_uvs"); /* internal uvs need no normals but it is hard and slow to keep a map of * normals only for boundary uvs, so allocating for all uvs */ state->normals = MEM_callocN(sizeof(*state->normals) * counter * 2, "uv_stitch_normals"); state->total_separate_uvs = counter; - /* we can at most have totalUVs edges or uvs selected. Actually they are less, considering we store only - * unique uvs for processing but I am accounting for all bizarre cases, especially for edges, this way */ - state->selection_stack = MEM_mallocN(sizeof(*state->selection_stack) * counter, "uv_stitch_selection_stack"); state->map = map = MEM_mallocN(sizeof(*map) * state->element_map->totalUVs, "uv_stitch_unique_map"); /* Allocate the edge stack */ - edgeHash = BLI_ghash_new(uv_edge_hash, uv_edge_compare, "stitch_edge_hash"); + edge_hash = BLI_ghash_new(uv_edge_hash, uv_edge_compare, "stitch_edge_hash"); all_edges = MEM_mallocN(sizeof(*all_edges) * state->element_map->totalUVs, "stitch_all_edges"); - if (!state->selection_stack || !state->uvs || !map || !edgeHash || !all_edges) { - stitch_state_delete(state); + if (!state->uvs || !map || !edge_hash || !all_edges) { + state_delete(state); return 0; } @@ -1169,6 +1637,8 @@ static int stitch_init(bContext *C, wmOperator *op) offset1 = map[itmp1]; offset2 = map[itmp2]; + all_edges[counter].next = NULL; + all_edges[counter].first = NULL; all_edges[counter].flag = 0; all_edges[counter].element = element; /* using an order policy, sort uvs according to address space. This avoids @@ -1182,12 +1652,12 @@ static int stitch_init(bContext *C, wmOperator *op) all_edges[counter].uv2 = offset1; } - if (BLI_ghash_haskey(edgeHash, &all_edges[counter])) { - char *flag = BLI_ghash_lookup(edgeHash, &all_edges[counter]); - *flag = 0; + if (BLI_ghash_haskey(edge_hash, &all_edges[counter])) { + UvEdge *edge = BLI_ghash_lookup(edge_hash, &all_edges[counter]); + edge->flag = 0; } else { - BLI_ghash_insert(edgeHash, &all_edges[counter], &(all_edges[counter].flag)); + BLI_ghash_insert(edge_hash, &all_edges[counter], &all_edges[counter]); all_edges[counter].flag = STITCH_BOUNDARY; } counter++; @@ -1195,55 +1665,55 @@ static int stitch_init(bContext *C, wmOperator *op) } - ghi = BLI_ghashIterator_new(edgeHash); - total_edges = 0; - /* fill the edges with data */ - for (; !BLI_ghashIterator_isDone(ghi); BLI_ghashIterator_step(ghi)) { - UvEdge *edge = ((UvEdge *)BLI_ghashIterator_getKey(ghi)); - if (edge->flag & STITCH_BOUNDARY) { - total_edges++; - } - } + ghi = BLI_ghashIterator_new(edge_hash); + total_edges = BLI_ghash_size(edge_hash); state->edges = edges = MEM_mallocN(sizeof(*edges) * total_edges, "stitch_edges"); - if (!ghi || !edges) { - MEM_freeN(all_edges); - stitch_state_delete(state); + + /* I assume any system will be able to at least allocate an iterator :p */ + if (!edges) { + BLI_ghashIterator_free(ghi); + state_delete(state); return 0; } - state->total_boundary_edges = total_edges; + state->total_separate_edges = total_edges; /* fill the edges with data */ - for (i = 0, BLI_ghashIterator_init(ghi, edgeHash); !BLI_ghashIterator_isDone(ghi); BLI_ghashIterator_step(ghi)) { - UvEdge *edge = ((UvEdge *)BLI_ghashIterator_getKey(ghi)); - if (edge->flag & STITCH_BOUNDARY) { - edges[i++] = *((UvEdge *)BLI_ghashIterator_getKey(ghi)); - } + for (i = 0, BLI_ghashIterator_init(ghi, edge_hash); !BLI_ghashIterator_isDone(ghi); BLI_ghashIterator_step(ghi)) { + edges[i++] = *((UvEdge *)BLI_ghashIterator_getKey(ghi)); } /* cleanup temporary stuff */ BLI_ghashIterator_free(ghi); MEM_freeN(all_edges); - /* refill hash with new pointers to cleanup duplicates */ - BLI_ghash_free(edgeHash, NULL, NULL); + BLI_ghash_free(edge_hash, NULL, NULL); + + /* refill an edge hash to create edge connnectivity data */ + state->edge_hash = edge_hash = BLI_ghash_new(uv_edge_hash, uv_edge_compare, "stitch_edge_hash"); + for (i = 0; i < total_edges; i++) { + BLI_ghash_insert(edge_hash, edges + i, edges + i); + } + stitch_uv_edge_generate_linked_edges(edge_hash, state); /***** calculate 2D normals for boundary uvs *****/ /* we use boundary edges to calculate 2D normals. * to disambiguate the direction of the normal, we also need * a point "inside" the island, that can be provided by - * the opposite uv for a quad, or the next uv for a triangle. */ + * the winding of the polygon (assuming counter-clockwise flow). */ for (i = 0; i < total_edges; i++) { float normal[2]; - stitch_calculate_edge_normal(em, edges + i, normal); + if (edges[i].flag & STITCH_BOUNDARY) { + stitch_calculate_edge_normal(em, edges + i, normal); - add_v2_v2(state->normals + edges[i].uv1 * 2, normal); - add_v2_v2(state->normals + edges[i].uv2 * 2, normal); + add_v2_v2(state->normals + edges[i].uv1 * 2, normal); + add_v2_v2(state->normals + edges[i].uv2 * 2, normal); - normalize_v2(state->normals + edges[i].uv1 * 2); - normalize_v2(state->normals + edges[i].uv2 * 2); + normalize_v2(state->normals + edges[i].uv1 * 2); + normalize_v2(state->normals + edges[i].uv2 * 2); + } } @@ -1255,30 +1725,86 @@ static int stitch_init(bContext *C, wmOperator *op) if (RNA_struct_property_is_set(op->ptr, "selection")) { int faceIndex, elementIndex; UvElement *element; + enum StitchModes stored_mode = RNA_enum_get(op->ptr, "stored_mode"); EDBM_index_arrays_ensure(em, BM_FACE); - RNA_BEGIN (op->ptr, itemptr, "selection") - { - faceIndex = RNA_int_get(&itemptr, "face_index"); - elementIndex = RNA_int_get(&itemptr, "element_index"); - efa = EDBM_face_at_index(em, faceIndex); - element = ED_uv_element_get(state->element_map, efa, BM_iter_at_index(NULL, BM_LOOPS_OF_FACE, efa, elementIndex)); - stitch_select_uv(element, state, 1); - } - RNA_END; + if(stored_mode == STITCH_VERT) { + state->selection_stack = MEM_mallocN(sizeof(*state->selection_stack) * state->total_separate_uvs, "uv_stitch_selection_stack"); + RNA_BEGIN (op->ptr, itemptr, "selection") + { + faceIndex = RNA_int_get(&itemptr, "face_index"); + elementIndex = RNA_int_get(&itemptr, "element_index"); + efa = EDBM_face_at_index(em, faceIndex); + element = ED_uv_element_get(state->element_map, efa, BM_iter_at_index(NULL, BM_LOOPS_OF_FACE, efa, elementIndex)); + stitch_select_uv(element, state, 1); + } + RNA_END; + } else { + state->selection_stack = MEM_mallocN(sizeof(*state->selection_stack) * state->total_separate_edges, "uv_stitch_selection_stack"); + + RNA_BEGIN (op->ptr, itemptr, "selection") + { + UvEdge tmp_edge, *edge; + int uv1, uv2; + faceIndex = RNA_int_get(&itemptr, "face_index"); + elementIndex = RNA_int_get(&itemptr, "element_index"); + efa = EDBM_face_at_index(em, faceIndex); + element = ED_uv_element_get(state->element_map, efa, BM_iter_at_index(NULL, BM_LOOPS_OF_FACE, efa, elementIndex)); + uv1 = map[element - state->element_map->buf]; + + element = ED_uv_element_get(state->element_map, efa, BM_iter_at_index(NULL, BM_LOOPS_OF_FACE, efa, (elementIndex+1)%efa->len)); + uv2 = map[element - state->element_map->buf]; + + if(uv1 < uv2) { + tmp_edge.uv1 = uv1; + tmp_edge.uv2 = uv2; + } else { + tmp_edge.uv1 = uv2; + tmp_edge.uv2 = uv1; + } + + edge = BLI_ghash_lookup(edge_hash, &tmp_edge); + + stitch_select_edge(edge, state, TRUE); + } + RNA_END; + } + /* if user has switched the operator mode after operation, we need to convert + * the stored format */ + if (state->mode != stored_mode) { + state->mode = stored_mode; + stitch_switch_selection_mode(state); + } /* Clear the selection */ RNA_collection_clear(op->ptr, "selection"); } else { - BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) { - BM_ITER_ELEM_INDEX (l, &liter, efa, BM_LOOPS_OF_FACE, i) { - if (uvedit_uv_select_test(em, scene, l)) { - UvElement *element = ED_uv_element_get(state->element_map, efa, l); - if (element) { - stitch_select_uv(element, state, 1); + if(state->mode == STITCH_VERT) { + state->selection_stack = MEM_mallocN(sizeof(*state->selection_stack) * state->total_separate_uvs, "uv_stitch_selection_stack"); + + BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) { + BM_ITER_ELEM_INDEX (l, &liter, efa, BM_LOOPS_OF_FACE, i) { + if (uvedit_uv_select_test(em, scene, l)) { + UvElement *element = ED_uv_element_get(state->element_map, efa, l); + if (element) { + stitch_select_uv(element, state, 1); + } + } + } + } + } else { + state->selection_stack = MEM_mallocN(sizeof(*state->selection_stack) * state->total_separate_edges, "uv_stitch_selection_stack"); + + BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) { + BM_ITER_ELEM_INDEX (l, &liter, efa, BM_LOOPS_OF_FACE, i) { + if(uvedit_edge_select_test(em, scene, l)) { + UvEdge *edge = uv_edge_get(l, state); + if(edge) { + stitch_select_edge(edge, state, TRUE); + } } } } @@ -1301,8 +1827,9 @@ static int stitch_init(bContext *C, wmOperator *op) } } - if (!stitch_process_data(state, scene, 0)) { - stitch_state_delete(state); + if (!stitch_process_data(state, scene, FALSE)) { + + state_delete(state); return 0; } @@ -1323,7 +1850,7 @@ static int stitch_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event)) static void stitch_exit(bContext *C, wmOperator *op, int finished) { - StitchState *stitch_state; + StitchState *state; Scene *scene; SpaceImage *sima; ScrArea *sa = CTX_wm_area(C); @@ -1333,45 +1860,47 @@ static void stitch_exit(bContext *C, wmOperator *op, int finished) obedit = CTX_data_edit_object(C); sima = CTX_wm_space_image(C); - stitch_state = (StitchState *)op->customdata; + state = (StitchState *)op->customdata; if (finished) { int i; - RNA_float_set(op->ptr, "limit", stitch_state->limit_dist); - RNA_boolean_set(op->ptr, "use_limit", stitch_state->use_limit); - RNA_boolean_set(op->ptr, "snap_islands", stitch_state->snap_islands); - RNA_int_set(op->ptr, "static_island", stitch_state->static_island); - RNA_boolean_set(op->ptr, "midpoint_snap", stitch_state->midpoints); + RNA_float_set(op->ptr, "limit", state->limit_dist); + RNA_boolean_set(op->ptr, "use_limit", state->use_limit); + RNA_boolean_set(op->ptr, "snap_islands", state->snap_islands); + RNA_int_set(op->ptr, "static_island", state->static_island); + RNA_boolean_set(op->ptr, "midpoint_snap", state->midpoints); + RNA_enum_set(op->ptr, "mode", state->mode); + RNA_enum_set(op->ptr, "stored_mode", state->mode); /* Store selection for re-execution of stitch */ - for (i = 0; i < stitch_state->selection_size; i++) { + for (i = 0; i < state->selection_size; i++) { + UvElement *element; PointerRNA itemptr; - UvElement *element = stitch_state->selection_stack[i]; - + if (state->mode == STITCH_VERT) { + element = state->selection_stack[i]; + } else { + element = ((UvEdge *)state->selection_stack[i])->element; + } RNA_collection_add(op->ptr, "selection", &itemptr); - RNA_int_set(&itemptr, "face_index", BM_elem_index_get(element->face)); - + RNA_int_set(&itemptr, "face_index", BM_elem_index_get(element->l->f)); RNA_int_set(&itemptr, "element_index", element->tfindex); } - uvedit_live_unwrap_update(sima, scene, obedit); } if (sa) ED_area_headerprint(sa, NULL); - ED_region_draw_cb_exit(CTX_wm_region(C)->type, stitch_state->draw_handle); + ED_region_draw_cb_exit(CTX_wm_region(C)->type, state->draw_handle); DAG_id_tag_update(obedit->data, 0); WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data); - stitch_state_delete(stitch_state); + state_delete(state); op->customdata = NULL; - - stitch_preview_delete(); } @@ -1397,7 +1926,7 @@ static int stitch_exec(bContext *C, wmOperator *op) } } -static void stitch_select(bContext *C, Scene *scene, wmEvent *event, StitchState *stitch_state) +static void stitch_select(bContext *C, Scene *scene, wmEvent *event, StitchState *state) { /* add uv under mouse to processed uv's */ float co[2]; @@ -1406,42 +1935,52 @@ static void stitch_select(bContext *C, Scene *scene, wmEvent *event, StitchState Image *ima = CTX_data_edit_image(C); UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &co[0], &co[1]); - uv_find_nearest_vert(scene, ima, stitch_state->em, co, NULL, &hit); - if (hit.efa) { - /* Add vertex to selection, deselect all common uv's of vert other - * than selected and update the preview. This behavior was decided so that - * you can do stuff like deselect the opposite stitchable vertex and the initial still gets deselected */ + if(state->mode == STITCH_VERT) { + uv_find_nearest_vert(scene, ima, state->em, co, NULL, &hit); - /* This works due to setting of tmp in find nearest uv vert */ - UvElement *element = ED_uv_element_get(stitch_state->element_map, hit.efa, hit.l); - stitch_select_uv(element, stitch_state, 0); + if (hit.efa) { + /* Add vertex to selection, deselect all common uv's of vert other + * than selected and update the preview. This behavior was decided so that + * you can do stuff like deselect the opposite stitchable vertex and the initial still gets deselected */ + /* This works due to setting of tmp in find nearest uv vert */ + UvElement *element = ED_uv_element_get(state->element_map, hit.efa, hit.l); + stitch_select_uv(element, state, FALSE); + + } + } else { + uv_find_nearest_edge(scene, ima, state->em, co, &hit); + + if(hit.efa) { + UvEdge *edge = uv_edge_get(hit.l, state); + stitch_select_edge(edge, state, FALSE); + } } } static int stitch_modal(bContext *C, wmOperator *op, wmEvent *event) { - StitchState *stitch_state; + StitchState *state; Scene *scene = CTX_data_scene(C); - stitch_state = (StitchState *)op->customdata; + state = (StitchState *)op->customdata; switch (event->type) { case MIDDLEMOUSE: return OPERATOR_PASS_THROUGH; - /* Cancel */ + /* Cancel */ case ESCKEY: return stitch_cancel(C, op); case LEFTMOUSE: if (event->shift && (U.flag & USER_LMOUSESELECT)) { - if (event->val == KM_RELEASE) { - stitch_select(C, scene, event, stitch_state); + if (event->val == KM_PRESS) { + stitch_select(C, scene, event, state); - if (!stitch_process_data(stitch_state, scene, 0)) { + if (!stitch_process_data(state, scene, FALSE)) { return stitch_cancel(C, op); } } @@ -1450,7 +1989,7 @@ static int stitch_modal(bContext *C, wmOperator *op, wmEvent *event) case PADENTER: case RETKEY: if (event->val == KM_PRESS) { - if (stitch_process_data(stitch_state, scene, 1)) { + if (stitch_process_data(state, scene, TRUE)) { stitch_exit(C, op, 1); return OPERATOR_FINISHED; } @@ -1461,12 +2000,12 @@ static int stitch_modal(bContext *C, wmOperator *op, wmEvent *event) else { return OPERATOR_PASS_THROUGH; } - /* Increase limit */ + /* Increase limit */ case PADPLUSKEY: case WHEELUPMOUSE: if (event->val == KM_PRESS && event->alt) { - stitch_state->limit_dist += 0.01f; - if (!stitch_process_data(stitch_state, scene, 0)) { + state->limit_dist += 0.01f; + if (!stitch_process_data(state, scene, FALSE)) { return stitch_cancel(C, op); } break; @@ -1474,13 +2013,13 @@ static int stitch_modal(bContext *C, wmOperator *op, wmEvent *event) else { return OPERATOR_PASS_THROUGH; } - /* Decrease limit */ + /* Decrease limit */ case PADMINUS: case WHEELDOWNMOUSE: if (event->val == KM_PRESS && event->alt) { - stitch_state->limit_dist -= 0.01f; - stitch_state->limit_dist = MAX2(0.01f, stitch_state->limit_dist); - if (!stitch_process_data(stitch_state, scene, 0)) { + state->limit_dist -= 0.01f; + state->limit_dist = MAX2(0.01f, state->limit_dist); + if (!stitch_process_data(state, scene, FALSE)) { return stitch_cancel(C, op); } break; @@ -1489,11 +2028,11 @@ static int stitch_modal(bContext *C, wmOperator *op, wmEvent *event) return OPERATOR_PASS_THROUGH; } - /* Use Limit (Default off)*/ + /* Use Limit (Default off)*/ case LKEY: if (event->val == KM_PRESS) { - stitch_state->use_limit = !stitch_state->use_limit; - if (!stitch_process_data(stitch_state, scene, 0)) { + state->use_limit = !state->use_limit; + if (!stitch_process_data(state, scene, FALSE)) { return stitch_cancel(C, op); } break; @@ -1502,10 +2041,10 @@ static int stitch_modal(bContext *C, wmOperator *op, wmEvent *event) case IKEY: if (event->val == KM_PRESS) { - stitch_state->static_island++; - stitch_state->static_island %= stitch_state->element_map->totalIslands; + state->static_island++; + state->static_island %= state->element_map->totalIslands; - if (!stitch_process_data(stitch_state, scene, 0)) { + if (!stitch_process_data(state, scene, FALSE)) { return stitch_cancel(C, op); } break; @@ -1514,33 +2053,33 @@ static int stitch_modal(bContext *C, wmOperator *op, wmEvent *event) case MKEY: if (event->val == KM_PRESS) { - stitch_state->midpoints = !stitch_state->midpoints; - if (!stitch_process_data(stitch_state, scene, 0)) { + state->midpoints = !state->midpoints; + if (!stitch_process_data(state, scene, FALSE)) { return stitch_cancel(C, op); } } break; - /* Select geometry*/ + /* Select geometry*/ case RIGHTMOUSE: if (!event->shift) { return stitch_cancel(C, op); } - if (event->val == KM_RELEASE && !(U.flag & USER_LMOUSESELECT)) { - stitch_select(C, scene, event, stitch_state); + if (event->val == KM_PRESS && !(U.flag & USER_LMOUSESELECT)) { + stitch_select(C, scene, event, state); - if (!stitch_process_data(stitch_state, scene, 0)) { + if (!stitch_process_data(state, scene, FALSE)) { return stitch_cancel(C, op); } break; } return OPERATOR_RUNNING_MODAL; - /* snap islands on/off */ + /* snap islands on/off */ case SKEY: if (event->val == KM_PRESS) { - stitch_state->snap_islands = !stitch_state->snap_islands; - if (!stitch_process_data(stitch_state, scene, 0)) { + state->snap_islands = !state->snap_islands; + if (!stitch_process_data(state, scene, FALSE)) { return stitch_cancel(C, op); } break; @@ -1549,12 +2088,23 @@ static int stitch_modal(bContext *C, wmOperator *op, wmEvent *event) return OPERATOR_RUNNING_MODAL; } + /* switch between edge/vertex mode */ + case TABKEY: + if (event->val == KM_PRESS) { + stitch_switch_selection_mode(state); + + if (!stitch_process_data(state, scene, FALSE)) { + return stitch_cancel(C, op); + } + } + break; + default: return OPERATOR_RUNNING_MODAL; } /* if updated settings, renew feedback message */ - stitch_update_header(stitch_state, C); + stitch_update_header(state, C); ED_region_tag_redraw(CTX_wm_region(C)); return OPERATOR_RUNNING_MODAL; } @@ -1563,6 +2113,12 @@ void UV_OT_stitch(wmOperatorType *ot) { PropertyRNA *prop; + static EnumPropertyItem stitch_modes[] = { + {STITCH_VERT, "VERTEX", 0, "Vertex", ""}, + {STITCH_EDGE, "EDGE", 0, "Edge", ""}, + {0, NULL, 0, NULL, NULL} + }; + /* identifiers */ ot->name = "Stitch"; ot->description = "Stitch selected UV vertices by proximity"; @@ -1589,6 +2145,11 @@ void UV_OT_stitch(wmOperatorType *ot) "UVs are stitched at midpoint instead of at static island"); RNA_def_boolean(ot->srna, "clear_seams", 1, "Clear Seams", "Clear seams of stitched edges"); + RNA_def_enum(ot->srna, "mode", stitch_modes, STITCH_VERT, "Operation Mode", + "Use vertex or edge stitching"); + prop = RNA_def_enum(ot->srna, "stored_mode", stitch_modes, STITCH_VERT, "Stored Operation Mode", + "Use vertex or edge stitching"); + RNA_def_property_flag(prop, PROP_HIDDEN); prop = RNA_def_collection_runtime(ot->srna, "selection", &RNA_SelectedUvElement, "Selection", ""); /* Selection should not be editable or viewed in toolbar */ RNA_def_property_flag(prop, PROP_HIDDEN); From b481ec92e49eeebf060802befb0d860760e45cd6 Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Mon, 17 Dec 2012 20:16:37 +0000 Subject: [PATCH 206/252] Minor tweaks to some UI messages... --- build_files/scons/config/linux-config.py | 2 +- source/blender/editors/space_view3d/view3d_ops.c | 2 +- source/blender/modifiers/intern/MOD_uvwarp.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/build_files/scons/config/linux-config.py b/build_files/scons/config/linux-config.py index 0185c2dd783..db3b369c5c4 100644 --- a/build_files/scons/config/linux-config.py +++ b/build_files/scons/config/linux-config.py @@ -197,7 +197,7 @@ WITH_BF_BOOST = False WITH_BF_STATICBOOST = False BF_BOOST = '/usr' BF_BOOST_INC = '${BF_BOOST}/include' -BF_BOOST_LIB = 'boost_date_time boost_filesystem boost_regex boost_system boost_thread' +BF_BOOST_LIB = 'boost_filesystem boost_regex boost_system boost_thread boost_date_time' BF_BOOST_LIB_STATIC = '${BF_BOOST_LIBPATH}/libboost_filesystem.a ${BF_BOOST_LIBPATH}/libboost_date_time.a ' + \ '${BF_BOOST_LIBPATH}/libboost_regex.a ${BF_BOOST_LIBPATH}/libboost_locale.a ${BF_BOOST_LIBPATH}/libboost_system.a' + \ '${BF_BOOST_LIBPATH}/libboost_thread.a' diff --git a/source/blender/editors/space_view3d/view3d_ops.c b/source/blender/editors/space_view3d/view3d_ops.c index ce05bbf7b0f..1334afee30e 100644 --- a/source/blender/editors/space_view3d/view3d_ops.c +++ b/source/blender/editors/space_view3d/view3d_ops.c @@ -111,7 +111,7 @@ static void VIEW3D_OT_pastebuffer(wmOperatorType *ot) /* identifiers */ ot->name = "Paste Selection from Buffer"; ot->idname = "VIEW3D_OT_pastebuffer"; - ot->description = "Contents of copybuffer gets pasted"; + ot->description = "Contents of copy buffer gets pasted"; /* api callbacks */ ot->invoke = WM_operator_confirm; diff --git a/source/blender/modifiers/intern/MOD_uvwarp.c b/source/blender/modifiers/intern/MOD_uvwarp.c index 5585a715131..249c3c89d5f 100644 --- a/source/blender/modifiers/intern/MOD_uvwarp.c +++ b/source/blender/modifiers/intern/MOD_uvwarp.c @@ -130,7 +130,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, return dm; } else if (ELEM(NULL, umd->object_src, umd->object_dst)) { - modifier_setError(md, "from/to objects must be set"); + modifier_setError(md, "From/To objects must be set"); return dm; } From cfd6282a80f0aa10a3d663c9c7fad5a74ae14d45 Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Mon, 17 Dec 2012 20:32:25 +0000 Subject: [PATCH 207/252] Minor update to i18n spell check stuff... --- release/scripts/modules/bl_i18n_utils/spell_check_utils.py | 1 + 1 file changed, 1 insertion(+) diff --git a/release/scripts/modules/bl_i18n_utils/spell_check_utils.py b/release/scripts/modules/bl_i18n_utils/spell_check_utils.py index fbe405a61c6..049ec9ca969 100644 --- a/release/scripts/modules/bl_i18n_utils/spell_check_utils.py +++ b/release/scripts/modules/bl_i18n_utils/spell_check_utils.py @@ -385,6 +385,7 @@ dict_uimsgs = { "vinterlace", "wetmap", "wetmaps", "wpaint", + "uvwarp", # Algorithm names "beckmann", From 593ae2c8f4abce2aab3a7a7b54322b9ab69710ff Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Mon, 17 Dec 2012 20:37:10 +0000 Subject: [PATCH 208/252] Fix #33505: various issues * Motion blur with shutter time > 1 did result in the correct evaluation of some modifiers because it set the subframe to values > 1, and some places assume the current frame to be set to the integer coordinate and the subframe to be a value between 0 and 1. * Shape keys did not take subframe time offsets into account. * Point density texture was using an current frame value that was never set. --- source/blender/blenkernel/intern/key.c | 8 ++++---- .../blender/render/intern/include/render_types.h | 1 - source/blender/render/intern/source/pipeline.c | 14 +++++++++++--- source/blender/render/intern/source/pointdensity.c | 2 +- 4 files changed, 16 insertions(+), 9 deletions(-) diff --git a/source/blender/blenkernel/intern/key.c b/source/blender/blenkernel/intern/key.c index 782d796b8a7..ad95f09826a 100644 --- a/source/blender/blenkernel/intern/key.c +++ b/source/blender/blenkernel/intern/key.c @@ -1078,7 +1078,7 @@ static void do_mesh_key(Scene *scene, Object *ob, Key *key, char *out, const int if (key->slurph && key->type != KEY_RELATIVE) { const float ctime_scaled = key->ctime / 100.0f; float delta = (float)key->slurph / tot; - float cfra = (float)scene->r.cfra; + float cfra = (float)scene->r.cfra + scene->r.subframe; int step, a; if (tot > 100 && slurph_opt) { @@ -1176,7 +1176,7 @@ static void do_curve_key(Scene *scene, Object *ob, Key *key, char *out, const in if (key->slurph && key->type != KEY_RELATIVE) { const float ctime_scaled = key->ctime / 100.0f; float delta = (float)key->slurph / tot; - float cfra = (float)scene->r.cfra; + float cfra = (float)scene->r.cfra + scene->r.subframe; Nurb *nu; int i = 0, remain = 0; int step, a; @@ -1258,7 +1258,7 @@ static void do_latt_key(Scene *scene, Object *ob, Key *key, char *out, const int if (key->slurph && key->type != KEY_RELATIVE) { const float ctime_scaled = key->ctime / 100.0f; float delta = (float)key->slurph / tot; - float cfra = (float)scene->r.cfra; + float cfra = (float)scene->r.cfra + scene->r.subframe; int a; for (a = 0; a < tot; a++, cfra += delta) { @@ -1373,7 +1373,7 @@ float *do_ob_key(Scene *scene, Object *ob) } else { /* do shapekey local drivers */ - float ctime = (float)scene->r.cfra; // XXX this needs to be checked + float ctime = (float)scene->r.cfra + scene->r.subframe; BKE_animsys_evaluate_animdata(scene, &key->id, key->adt, ctime, ADT_RECALC_DRIVERS); diff --git a/source/blender/render/intern/include/render_types.h b/source/blender/render/intern/include/render_types.h index 6ed8d6a7b6c..742241676dc 100644 --- a/source/blender/render/intern/include/render_types.h +++ b/source/blender/render/intern/include/render_types.h @@ -198,7 +198,6 @@ struct Render ListBase strandsurface; /* use this instead of R.r.cfra */ - float cfra; float mblur_offs, field_offs; /* render database */ diff --git a/source/blender/render/intern/source/pipeline.c b/source/blender/render/intern/source/pipeline.c index e22a90cacb5..413d7cb959e 100644 --- a/source/blender/render/intern/source/pipeline.c +++ b/source/blender/render/intern/source/pipeline.c @@ -942,6 +942,9 @@ void RE_TileProcessor(Render *re) static void do_render_3d(Render *re) { + float cfra; + int cfra_backup; + /* try external */ if (RE_engine_render(re, 0)) return; @@ -949,9 +952,13 @@ static void do_render_3d(Render *re) /* internal */ RE_parts_clamp(re); -// re->cfra= cfra; /* <- unused! */ - re->scene->r.subframe = re->mblur_offs + re->field_offs; - + /* add motion blur and fields offset to frames */ + cfra_backup = re->scene->r.cfra; + + cfra = re->scene->r.cfra + re->mblur_offs + re->field_offs; + re->scene->r.cfra = floorf(cfra); + re->scene->r.subframe = cfra - floorf(cfra); + /* lock drawing in UI during data phase */ if (re->draw_lock) re->draw_lock(re->dlh, 1); @@ -976,6 +983,7 @@ static void do_render_3d(Render *re) /* free all render verts etc */ RE_Database_Free(re); + re->scene->r.cfra = cfra_backup; re->scene->r.subframe = 0.f; } diff --git a/source/blender/render/intern/source/pointdensity.c b/source/blender/render/intern/source/pointdensity.c index a540cdb85d5..3ca4015ff7b 100644 --- a/source/blender/render/intern/source/pointdensity.c +++ b/source/blender/render/intern/source/pointdensity.c @@ -447,7 +447,7 @@ int pointdensitytex(Tex *tex, const float texvec[3], TexResult *texres) turb = BLI_gTurbulence(pd->noise_size, texvec[0]+age, texvec[1]+age, texvec[2]+age, pd->noise_depth, 0, pd->noise_basis); } else if (pd->noise_influence == TEX_PD_NOISE_TIME) { - time = R.cfra / (float)R.r.efra; + time = R.r.cfra / (float)R.r.efra; turb = BLI_gTurbulence(pd->noise_size, texvec[0]+time, texvec[1]+time, texvec[2]+time, pd->noise_depth, 0, pd->noise_basis); //turb = BLI_turbulence(pd->noise_size, texvec[0]+time, texvec[1]+time, texvec[2]+time, pd->noise_depth); } From 779375251c51fa843337d6340e7d14959e620abe Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Mon, 17 Dec 2012 21:40:28 +0000 Subject: [PATCH 209/252] Fix #33487: game engine did not convert objects with rotation modes other than Euler XYZ correctly, was never implemented; --- source/blender/blenkernel/BKE_object.h | 2 +- source/blender/blenkernel/intern/object.c | 9 ++++--- .../blender/editors/object/object_transform.c | 2 +- .../blender/editors/space_clip/tracking_ops.c | 2 +- .../Converter/BL_BlenderDataConversion.cpp | 25 +++++++++++++------ 5 files changed, 27 insertions(+), 13 deletions(-) diff --git a/source/blender/blenkernel/BKE_object.h b/source/blender/blenkernel/BKE_object.h index 885bb6f2a26..bfae1bd2390 100644 --- a/source/blender/blenkernel/BKE_object.h +++ b/source/blender/blenkernel/BKE_object.h @@ -89,7 +89,7 @@ int BKE_object_is_libdata(struct Object *ob); int BKE_object_obdata_is_libdata(struct Object *ob); void BKE_object_scale_to_mat3(struct Object *ob, float mat[3][3]); -void BKE_object_rot_to_mat3(struct Object *ob, float mat[3][3]); +void BKE_object_rot_to_mat3(struct Object *ob, float mat[3][3], short use_drot); void BKE_object_mat3_to_rot(struct Object *ob, float mat[3][3], short use_compat); void BKE_object_to_mat3(struct Object *ob, float mat[3][3]); void BKE_object_to_mat4(struct Object *ob, float mat[4][4]); diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c index 20a718e83cd..56af4267ec7 100644 --- a/source/blender/blenkernel/intern/object.c +++ b/source/blender/blenkernel/intern/object.c @@ -1539,7 +1539,7 @@ void BKE_object_scale_to_mat3(Object *ob, float mat[3][3]) size_to_mat3(mat, vec); } -void BKE_object_rot_to_mat3(Object *ob, float mat[3][3]) +void BKE_object_rot_to_mat3(Object *ob, float mat[3][3], short use_drot) { float rmat[3][3], dmat[3][3]; @@ -1570,7 +1570,10 @@ void BKE_object_rot_to_mat3(Object *ob, float mat[3][3]) } /* combine these rotations */ - mul_m3_m3m3(mat, dmat, rmat); + if(use_drot) + mul_m3_m3m3(mat, dmat, rmat); + else + copy_m3_m3(mat, rmat); } void BKE_object_mat3_to_rot(Object *ob, float mat[3][3], short use_compat) @@ -1715,7 +1718,7 @@ void BKE_object_to_mat3(Object *ob, float mat[3][3]) /* no parent */ BKE_object_scale_to_mat3(ob, smat); /* rot */ - BKE_object_rot_to_mat3(ob, rmat); + BKE_object_rot_to_mat3(ob, rmat, TRUE); mul_m3_m3m3(mat, rmat, smat); } diff --git a/source/blender/editors/object/object_transform.c b/source/blender/editors/object/object_transform.c index 900bf57b509..7a2eb5667a2 100644 --- a/source/blender/editors/object/object_transform.c +++ b/source/blender/editors/object/object_transform.c @@ -447,7 +447,7 @@ static int apply_objects_internal(bContext *C, ReportList *reports, int apply_lo float tmat[3][3], timat[3][3]; /* simple rotation matrix */ - BKE_object_rot_to_mat3(ob, rsmat); + BKE_object_rot_to_mat3(ob, rsmat, TRUE); /* correct for scale, note mul_m3_m3m3 has swapped args! */ BKE_object_scale_to_mat3(ob, tmat); diff --git a/source/blender/editors/space_clip/tracking_ops.c b/source/blender/editors/space_clip/tracking_ops.c index a29524de36d..77662d8ac13 100644 --- a/source/blender/editors/space_clip/tracking_ops.c +++ b/source/blender/editors/space_clip/tracking_ops.c @@ -2025,7 +2025,7 @@ static void set_axis(Scene *scene, Object *ob, MovieClip *clip, MovieTrackingOb if (!flip) { float lmat[4][4], ilmat[4][4], rmat[3][3]; - BKE_object_rot_to_mat3(ob, rmat); + BKE_object_rot_to_mat3(ob, rmat, TRUE); invert_m3(rmat); mul_m4_m4m3(mat, mat, rmat); diff --git a/source/gameengine/Converter/BL_BlenderDataConversion.cpp b/source/gameengine/Converter/BL_BlenderDataConversion.cpp index eb695e624e4..ab0630bf398 100644 --- a/source/gameengine/Converter/BL_BlenderDataConversion.cpp +++ b/source/gameengine/Converter/BL_BlenderDataConversion.cpp @@ -2187,26 +2187,37 @@ static void bl_ConvertBlenderObject_Single( blenderobject->loc[1]+blenderobject->dloc[1], blenderobject->loc[2]+blenderobject->dloc[2] ); - MT_Vector3 eulxyz(blenderobject->rot); + + MT_Matrix3x3 rotation; + float rotmat[3][3]; + BKE_object_rot_to_mat3(blenderobject, rotmat, FALSE); + rotation.setValue3x3((float*)rotmat); + MT_Vector3 scale(blenderobject->size); + if (converter->addInitFromFrame) {//rcruiz - float eulxyzPrev[3]; blenderscene->r.cfra=blenderscene->r.sfra-1; //XXX update_for_newframe(); MT_Vector3 tmp=pos-MT_Point3(blenderobject->loc[0]+blenderobject->dloc[0], blenderobject->loc[1]+blenderobject->dloc[1], blenderobject->loc[2]+blenderobject->dloc[2] ); - eulxyzPrev[0]=blenderobject->rot[0]; - eulxyzPrev[1]=blenderobject->rot[1]; - eulxyzPrev[2]=blenderobject->rot[2]; + + float rotmatPrev[3][3]; + BKE_object_rot_to_mat3(blenderobject, rotmatPrev, FALSE); + + float eulxyz[3], eulxyzPrev[3]; + mat3_to_eul(eulxyz, rotmat); + mat3_to_eul(eulxyzPrev, rotmatPrev); double fps = (double) blenderscene->r.frs_sec/ (double) blenderscene->r.frs_sec_base; tmp.scale(fps, fps, fps); inivel.push_back(tmp); - tmp=eulxyz-eulxyzPrev; + tmp[0]=eulxyz[0]-eulxyzPrev[0]; + tmp[1]=eulxyz[1]-eulxyzPrev[1]; + tmp[2]=eulxyz[2]-eulxyzPrev[2]; tmp.scale(fps, fps, fps); iniang.push_back(tmp); blenderscene->r.cfra=blenderscene->r.sfra; @@ -2214,7 +2225,7 @@ static void bl_ConvertBlenderObject_Single( } gameobj->NodeSetLocalPosition(pos); - gameobj->NodeSetLocalOrientation(MT_Matrix3x3(eulxyz)); + gameobj->NodeSetLocalOrientation(rotation); gameobj->NodeSetLocalScale(scale); gameobj->NodeUpdateGS(0); From 899ba3fdb619034653ad59dfae6c8eec9f443933 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 18 Dec 2012 01:46:15 +0000 Subject: [PATCH 210/252] style cleanup --- source/blender/blenkernel/intern/object.c | 2 +- .../blenkernel/intern/particle_system.c | 13 +- source/blender/bmesh/CMakeLists.txt | 2 + .../operations/COM_OpenCLKernels.cl | 3 +- source/blender/editors/object/object_vgroup.c | 3 +- .../editors/space_buttons/buttons_texture.c | 2 +- .../editors/uvedit/uvedit_smart_stitch.c | 303 ++++++++++-------- source/blender/gpu/intern/gpu_material.c | 2 +- 8 files changed, 178 insertions(+), 152 deletions(-) diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c index 56af4267ec7..28aa3a523cd 100644 --- a/source/blender/blenkernel/intern/object.c +++ b/source/blender/blenkernel/intern/object.c @@ -1570,7 +1570,7 @@ void BKE_object_rot_to_mat3(Object *ob, float mat[3][3], short use_drot) } /* combine these rotations */ - if(use_drot) + if (use_drot) mul_m3_m3m3(mat, dmat, rmat); else copy_m3_m3(mat, rmat); diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c index 037864c7e38..26bdc751582 100644 --- a/source/blender/blenkernel/intern/particle_system.c +++ b/source/blender/blenkernel/intern/particle_system.c @@ -2413,7 +2413,8 @@ static void sph_evaluate_func(BVHTree *tree, ParticleSystem **psys, float co[3], if (tree) { BLI_bvhtree_range_query(tree, co, interaction_radius, callback, pfr); break; - } else { + } + else { BLI_bvhtree_range_query(psys[i]->bvhtree, co, interaction_radius, callback, pfr); } } @@ -2815,7 +2816,8 @@ void psys_sph_init(ParticleSimulationData *sim, SPHData *sphdata) sphdata->force_cb = sph_force_cb; sphdata->density_cb = sph_density_accum_cb; sphdata->hfac = 1.0f; - } else { + } + else { /* SPH_SOLVER_CLASSICAL */ sphdata->force_cb = sphclassical_force_cb; sphdata->density_cb = sphclassical_density_accum_cb; @@ -4221,7 +4223,7 @@ static void dynamics_step(ParticleSimulationData *sim, float cfra) /* actual fluids calculations */ sph_integrate(sim, pa, pa->state.time, &sphdata); - if(sim->colliders) + if (sim->colliders) collision_check(sim, p, pa->state.time, cfra); /* SPH particles are not physical particles, just interpolation @@ -4235,7 +4237,8 @@ static void dynamics_step(ParticleSimulationData *sim, float cfra) sph_springs_modify(psys, timestep); - } else { + } + else { /* SPH_SOLVER_CLASSICAL */ /* Apply SPH forces using classical algorithm (due to Gingold * and Monaghan). Note that, unlike double-density relaxation, @@ -4258,7 +4261,7 @@ static void dynamics_step(ParticleSimulationData *sim, float cfra) /* actual fluids calculations */ sph_integrate(sim, pa, pa->state.time, &sphdata); - if(sim->colliders) + if (sim->colliders) collision_check(sim, p, pa->state.time, cfra); /* SPH particles are not physical particles, just interpolation diff --git a/source/blender/bmesh/CMakeLists.txt b/source/blender/bmesh/CMakeLists.txt index c41b0703240..ae2400b6cdc 100644 --- a/source/blender/bmesh/CMakeLists.txt +++ b/source/blender/bmesh/CMakeLists.txt @@ -113,6 +113,8 @@ set(SRC tools/bmesh_decimate.h tools/bmesh_edgesplit.c tools/bmesh_edgesplit.h + tools/bmesh_triangulate.c + tools/bmesh_triangulate.h bmesh.h bmesh_class.h diff --git a/source/blender/compositor/operations/COM_OpenCLKernels.cl b/source/blender/compositor/operations/COM_OpenCLKernels.cl index 36205bb94cc..8cc25fc3360 100644 --- a/source/blender/compositor/operations/COM_OpenCLKernels.cl +++ b/source/blender/compositor/operations/COM_OpenCLKernels.cl @@ -66,7 +66,8 @@ __kernel void bokehBlurKernel(__read_only image2d_t boundingBox, __read_only ima } color /= multiplyer; - } else { + } + else { int2 imageCoordinates = realCoordinate - offsetInput; color = read_imagef(inputImage, SAMPLER_NEAREST, imageCoordinates); } diff --git a/source/blender/editors/object/object_vgroup.c b/source/blender/editors/object/object_vgroup.c index 69e843ec706..f3e792def17 100644 --- a/source/blender/editors/object/object_vgroup.c +++ b/source/blender/editors/object/object_vgroup.c @@ -3320,8 +3320,7 @@ static int vertex_group_transfer_weight_exec(bContext *C, wmOperator *op) case WT_REPLACE_ALL_VERTEX_GROUPS: for (dg_src = ob_slc->defbase.first; dg_src; dg_src = dg_src->next) { - if (!ed_vgroup_transfer_weight(ob_act, ob_slc, dg_src, scene, method, replace_mode, op)) - { + if (!ed_vgroup_transfer_weight(ob_act, ob_slc, dg_src, scene, method, replace_mode, op)) { fail++; } } diff --git a/source/blender/editors/space_buttons/buttons_texture.c b/source/blender/editors/space_buttons/buttons_texture.c index 3175c15ccac..935b15f3cd8 100644 --- a/source/blender/editors/space_buttons/buttons_texture.c +++ b/source/blender/editors/space_buttons/buttons_texture.c @@ -363,7 +363,7 @@ static void template_texture_user_menu(bContext *C, uiLayout *layout, void *UNUS Tex *tex = texptr.data; if (tex) - BLI_snprintf(name, UI_MAX_NAME_STR, " %s - %s", user->name, tex->id.name+2); + BLI_snprintf(name, UI_MAX_NAME_STR, " %s - %s", user->name, tex->id.name + 2); else BLI_snprintf(name, UI_MAX_NAME_STR, " %s", user->name); } diff --git a/source/blender/editors/uvedit/uvedit_smart_stitch.c b/source/blender/editors/uvedit/uvedit_smart_stitch.c index 280b6f0703d..bd50857c8b8 100644 --- a/source/blender/editors/uvedit/uvedit_smart_stitch.c +++ b/source/blender/editors/uvedit/uvedit_smart_stitch.c @@ -74,22 +74,22 @@ /* object that stores display data for previewing before confirming stitching */ typedef struct StitchPreviewer { - /* here we'll store the preview triangle indices of the mesh */ - float *preview_polys; - /* uvs per polygon. */ - unsigned int *uvs_per_polygon; - /*number of preview polygons */ - unsigned int num_polys; - /* preview data. These will be either the previewed vertices or edges depending on stitch mode settings */ - float *preview_stitchable; - float *preview_unstitchable; - /* here we'll store the number of elements to be drawn */ - unsigned int num_stitchable; - unsigned int num_unstitchable; - unsigned int preview_uvs; - /* ...and here we'll store the static island triangles*/ - float *static_tris; - unsigned int num_static_tris; + /* here we'll store the preview triangle indices of the mesh */ + float *preview_polys; + /* uvs per polygon. */ + unsigned int *uvs_per_polygon; + /*number of preview polygons */ + unsigned int num_polys; + /* preview data. These will be either the previewed vertices or edges depending on stitch mode settings */ + float *preview_stitchable; + float *preview_unstitchable; + /* here we'll store the number of elements to be drawn */ + unsigned int num_stitchable; + unsigned int num_unstitchable; + unsigned int preview_uvs; + /* ...and here we'll store the static island triangles*/ + float *static_tris; + unsigned int num_static_tris; } StitchPreviewer; @@ -98,93 +98,93 @@ struct IslandStitchData; /* This is a straightforward implementation, count the uv's in the island that will move and take the mean displacement/rotation and apply it to all * elements of the island except from the stitchable */ typedef struct IslandStitchData { - /* rotation can be used only for edges, for vertices there is no such notion */ - float rotation; - float translation[2]; - /* Used for rotation, the island will rotate around this point */ - float medianPoint[2]; - int numOfElements; - int num_rot_elements; - /* flag to remember if island has been added for preview */ - char addedForPreview; - /* flag an island to be considered for determining static island */ - char stitchableCandidate; - /* if edge rotation is used, flag so that vertex rotation is not used */ - char use_edge_rotation; + /* rotation can be used only for edges, for vertices there is no such notion */ + float rotation; + float translation[2]; + /* Used for rotation, the island will rotate around this point */ + float medianPoint[2]; + int numOfElements; + int num_rot_elements; + /* flag to remember if island has been added for preview */ + char addedForPreview; + /* flag an island to be considered for determining static island */ + char stitchableCandidate; + /* if edge rotation is used, flag so that vertex rotation is not used */ + char use_edge_rotation; } IslandStitchData; /* just for averaging UVs */ typedef struct UVVertAverage { - float uv[2]; - unsigned short count; + float uv[2]; + unsigned short count; } UVVertAverage; typedef struct UvEdge { - /* index to uv buffer */ - unsigned int uv1; - unsigned int uv2; - /* general use flag (Used to check if edge is boundary here, and propagates to adjacency elements) */ - unsigned char flag; - /* element that guarantees element->face has the edge on element->tfindex and element->tfindex+1 is the second uv */ - UvElement *element; - /* next uv edge with the same exact vertices as this one.. Calculated at startup to save time */ - struct UvEdge *next; - /* point to first of common edges. Needed for iteration */ - struct UvEdge *first; + /* index to uv buffer */ + unsigned int uv1; + unsigned int uv2; + /* general use flag (Used to check if edge is boundary here, and propagates to adjacency elements) */ + unsigned char flag; + /* element that guarantees element->face has the edge on element->tfindex and element->tfindex+1 is the second uv */ + UvElement *element; + /* next uv edge with the same exact vertices as this one.. Calculated at startup to save time */ + struct UvEdge *next; + /* point to first of common edges. Needed for iteration */ + struct UvEdge *first; } UvEdge; /* stitch state object */ typedef struct StitchState { - /* use limit flag */ - char use_limit; - /* limit to operator, same as original operator */ - float limit_dist; - /* snap uv islands together during stitching */ - char snap_islands; - /* stich at midpoints or at islands */ - char midpoints; - /* editmesh, cached for use in modal handler */ - BMEditMesh *em; - /* clear seams of stitched edges after stitch */ - char clear_seams; - /* element map for getting info about uv connectivity */ - UvElementMap *element_map; - /* edge container */ - UvEdge *uvedges; - /* container of first of a group of coincident uvs, these will be operated upon */ - UvElement **uvs; - /* maps uvelements to their first coincident uv */ - int *map; - /* 2D normals per uv to calculate rotation for snapping */ - float *normals; - /* edge storage */ - UvEdge *edges; - /* hash for quick lookup of edges */ - GHash *edge_hash; + /* use limit flag */ + char use_limit; + /* limit to operator, same as original operator */ + float limit_dist; + /* snap uv islands together during stitching */ + char snap_islands; + /* stich at midpoints or at islands */ + char midpoints; + /* editmesh, cached for use in modal handler */ + BMEditMesh *em; + /* clear seams of stitched edges after stitch */ + char clear_seams; + /* element map for getting info about uv connectivity */ + UvElementMap *element_map; + /* edge container */ + UvEdge *uvedges; + /* container of first of a group of coincident uvs, these will be operated upon */ + UvElement **uvs; + /* maps uvelements to their first coincident uv */ + int *map; + /* 2D normals per uv to calculate rotation for snapping */ + float *normals; + /* edge storage */ + UvEdge *edges; + /* hash for quick lookup of edges */ + GHash *edge_hash; - /* count of separate uvs and edges */ - int total_separate_edges; - int total_separate_uvs; - /* hold selection related information */ - void **selection_stack; - int selection_size; - /* island that stays in place */ - int static_island; - /* store number of primitives per face so that we can allocate the active island buffer later */ - unsigned int *tris_per_island; + /* count of separate uvs and edges */ + int total_separate_edges; + int total_separate_uvs; + /* hold selection related information */ + void **selection_stack; + int selection_size; + /* island that stays in place */ + int static_island; + /* store number of primitives per face so that we can allocate the active island buffer later */ + unsigned int *tris_per_island; - /* vert or edge mode used for stitching */ - char mode; - /* handle for drawing */ - void *draw_handle; - /* preview data */ - StitchPreviewer *stitch_preview; + /* vert or edge mode used for stitching */ + char mode; + /* handle for drawing */ + void *draw_handle; + /* preview data */ + StitchPreviewer *stitch_preview; } StitchState; typedef struct PreviewPosition { - int data_position; - int polycount_position; + int data_position; + int polycount_position; } PreviewPosition; /* * defines for UvElement/UcEdge flags @@ -344,7 +344,7 @@ static int stitch_check_edges_stitchable(UvEdge *edge, UvEdge *edge_iter, Stitch limit = state->limit_dist; - if(state->use_limit) { + if (state->use_limit) { BMLoop *l; MLoopUV *luv_orig1, *luv_iter1; MLoopUV *luv_orig2, *luv_iter2; @@ -474,7 +474,8 @@ static void stitch_island_calculate_edge_rotation(UvEdge *edge, StitchState *sta if (state->mode == STITCH_VERT) { index1 = uvfinal_map[element1 - state->element_map->buf]; index2 = uvfinal_map[element2 - state->element_map->buf]; - } else { + } + else { index1 = edge->uv1; index2 = edge->uv2; } @@ -524,7 +525,7 @@ static void stitch_island_calculate_vert_rotation(UvElement *element, StitchStat float normal[2]; /* only calculate rotation against static island uv verts */ - if(!state->midpoints && element_iter->island != state->static_island) + if (!state->midpoints && element_iter->island != state->static_island) continue; index_tmp1 = element_iter - state->element_map->buf; @@ -591,11 +592,11 @@ static void stitch_uv_edge_generate_linked_edges(GHash *edge_hash, StitchState * for (i = 0; i < state->total_separate_edges; i++) { UvEdge *edge = edges + i; - if(edge->first) + if (edge->first) continue; /* only boundary edges can be stitched. Yes. Sorry about that :p */ - if(edge->flag & STITCH_BOUNDARY) { + if (edge->flag & STITCH_BOUNDARY) { UvElement *element1 = state->uvs[edge->uv1]; UvElement *element2 = state->uvs[edge->uv2]; @@ -610,26 +611,27 @@ static void stitch_uv_edge_generate_linked_edges(GHash *edge_hash, StitchState * UvElement *iter2 = NULL; /* check to see if other vertex of edge belongs to same vertex as */ - if(BM_elem_index_get(iter1->l->next->v) == elemindex2) + if (BM_elem_index_get(iter1->l->next->v) == elemindex2) iter2 = ED_uv_element_get(element_map, iter1->l->f, iter1->l->next); - else if(BM_elem_index_get(iter1->l->prev->v) == elemindex2) + else if (BM_elem_index_get(iter1->l->prev->v) == elemindex2) iter2 = ED_uv_element_get(element_map, iter1->l->f, iter1->l->prev); - if(iter2) { + if (iter2) { int index1 = map[iter1 - first_element]; int index2 = map[iter2 - first_element]; /* make certain we do not have the same edge! */ - if(state->uvs[index2] != element2 && state->uvs[index1] != element1) { + if (state->uvs[index2] != element2 && state->uvs[index1] != element1) { UvEdge edgetmp; UvEdge *edge2; /* make sure the indices are well behaved */ - if(index1 < index2) { + if (index1 < index2) { edgetmp.uv1 = index1; edgetmp.uv2 = index2; - } else { + } + else { edgetmp.uv1 = index2; edgetmp.uv2 = index1; } @@ -646,7 +648,8 @@ static void stitch_uv_edge_generate_linked_edges(GHash *edge_hash, StitchState * } } } - } else { + } + else { /* so stitchability code works */ edge->first = edge; } @@ -682,7 +685,7 @@ static void determine_uv_edge_stitchability(UvEdge *edge, StitchState *state, Is UvEdge *edge_iter = edge->first; for (; edge_iter; edge_iter = edge_iter->next) { - if(stitch_check_edges_stitchable(edge, edge_iter, state)) { + if (stitch_check_edges_stitchable(edge, edge_iter, state)) { island_stitch_data[edge_iter->element->island].stitchableCandidate = 1; island_stitch_data[edge->element->island].stitchableCandidate = 1; edge->flag |= STITCH_STITCHABLE_CANDIDATE; @@ -761,7 +764,7 @@ static void stitch_validate_uv_stichability(UvElement *element, StitchState *sta static void stitch_validate_edge_stichability(UvEdge *edge, StitchState *state, IslandStitchData *island_stitch_data, - PreviewPosition *preview_position) { + PreviewPosition *preview_position) { UvEdge *edge_iter = edge->first; StitchPreviewer *preview = state->stitch_preview; @@ -770,11 +773,11 @@ static void stitch_validate_edge_stichability(UvEdge *edge, StitchState *state, continue; if (stitch_check_edges_state_stitchable(edge, edge_iter, state)) { if ((edge_iter->element->island == state->static_island) || (edge->element->island == state->static_island)) { - edge->flag |= STITCH_STITCHABLE; - preview->num_stitchable++; - stitch_setup_face_preview_for_uv_group(state->uvs[edge->uv1], state, island_stitch_data, preview_position); - stitch_setup_face_preview_for_uv_group(state->uvs[edge->uv2], state, island_stitch_data, preview_position); - return; + edge->flag |= STITCH_STITCHABLE; + preview->num_stitchable++; + stitch_setup_face_preview_for_uv_group(state->uvs[edge->uv1], state, island_stitch_data, preview_position); + stitch_setup_face_preview_for_uv_group(state->uvs[edge->uv2], state, island_stitch_data, preview_position); + return; } } } @@ -867,10 +870,11 @@ static int stitch_process_data(StitchState *state, Scene *scene, int final) *****************************************/ for (i = 0; i < state->selection_size; i++) { - if(state->mode == STITCH_VERT) { + if (state->mode == STITCH_VERT) { UvElement *element = (UvElement *)state->selection_stack[i]; determine_uv_stitchability(element, state, island_stitch_data); - } else { + } + else { UvEdge *edge = (UvEdge *)state->selection_stack[i]; determine_uv_edge_stitchability(edge, state, island_stitch_data); } @@ -887,7 +891,7 @@ static int stitch_process_data(StitchState *state, Scene *scene, int final) } for (i = 0; i < state->selection_size; i++) { - if(state->mode == STITCH_VERT) { + if (state->mode == STITCH_VERT) { UvElement *element = (UvElement *)state->selection_stack[i]; if (element->flag & STITCH_STITCHABLE_CANDIDATE) { element->flag &= ~STITCH_STITCHABLE_CANDIDATE; @@ -897,9 +901,10 @@ static int stitch_process_data(StitchState *state, Scene *scene, int final) /* add to preview for unstitchable */ preview->num_unstitchable++; } - } else { + } + else { UvEdge *edge = (UvEdge *)state->selection_stack[i]; - if(edge->flag & STITCH_STITCHABLE_CANDIDATE) { + if (edge->flag & STITCH_STITCHABLE_CANDIDATE) { edge->flag &= ~STITCH_STITCHABLE_CANDIDATE; stitch_validate_edge_stichability(edge, state, island_stitch_data, preview_position); } @@ -992,7 +997,7 @@ static int stitch_process_data(StitchState *state, Scene *scene, int final) } /* fill the appropriate preview buffers */ - if(state->mode == STITCH_VERT) { + if (state->mode == STITCH_VERT) { for (i = 0; i < state->total_separate_uvs; i++) { UvElement *element = (UvElement *)state->uvs[i]; if (element->flag & STITCH_STITCHABLE) { @@ -1011,13 +1016,14 @@ static int stitch_process_data(StitchState *state, Scene *scene, int final) unstitchBufferIndex++; } } - } else { + } + else { for (i = 0; i < state->total_separate_edges; i++) { UvEdge *edge = state->edges + i; UvElement *element1 = state->uvs[edge->uv1]; UvElement *element2 = state->uvs[edge->uv2]; - if(edge->flag & STITCH_STITCHABLE) { + if (edge->flag & STITCH_STITCHABLE) { l = element1->l; luv = CustomData_bmesh_get(&state->em->bm->ldata, l->head.data, CD_MLOOPUV); copy_v2_v2(&preview->preview_stitchable[stitchBufferIndex * 4], luv->uv); @@ -1028,7 +1034,8 @@ static int stitch_process_data(StitchState *state, Scene *scene, int final) stitchBufferIndex++; BLI_assert(stitchBufferIndex <= preview->num_stitchable); - } else if (edge->flag & STITCH_SELECTED) { + } + else if (edge->flag & STITCH_SELECTED) { l = element1->l; luv = CustomData_bmesh_get(&state->em->bm->ldata, l->head.data, CD_MLOOPUV); copy_v2_v2(&preview->preview_unstitchable[unstitchBufferIndex * 4], luv->uv); @@ -1051,7 +1058,8 @@ static int stitch_process_data(StitchState *state, Scene *scene, int final) if (state->mode == STITCH_VERT) { final_position = MEM_callocN(state->selection_size * sizeof(*final_position), "stitch_uv_average"); uvfinal_map = MEM_mallocN(state->element_map->totalUVs * sizeof(*uvfinal_map), "stitch_uv_final_map"); - } else { + } + else { final_position = MEM_callocN(state->total_separate_uvs * sizeof(*final_position), "stitch_uv_average"); } @@ -1101,7 +1109,8 @@ static int stitch_process_data(StitchState *state, Scene *scene, int final) final_position[i].uv[0] /= final_position[i].count; final_position[i].uv[1] /= final_position[i].count; } - } else { + } + else { UvEdge *edge = state->selection_stack[i]; if (edge->flag & STITCH_STITCHABLE) { @@ -1132,7 +1141,7 @@ static int stitch_process_data(StitchState *state, Scene *scene, int final) l = state->uvs[edge_iter->uv2]->l; luv2 = CustomData_bmesh_get(&state->em->bm->ldata, l->head.data, CD_MLOOPUV); - if(stitch_midpoints) { + if (stitch_midpoints) { add_v2_v2(final_position[edge->uv1].uv, luv1->uv); final_position[edge->uv1].count++; add_v2_v2(final_position[edge->uv2].uv, luv2->uv); @@ -1197,7 +1206,8 @@ static int stitch_process_data(StitchState *state, Scene *scene, int final) } } } - } else { + } + else { for (i = 0; i < state->total_separate_uvs; i++) { UvElement *element = state->uvs[i]; @@ -1226,7 +1236,7 @@ static int stitch_process_data(StitchState *state, Scene *scene, int final) for (i = 0; i < state->selection_size; i++) { UvEdge *edge = state->selection_stack[i]; - if(edge->flag & STITCH_STITCHABLE) { + if (edge->flag & STITCH_STITCHABLE) { stitch_island_calculate_edge_rotation(edge, state, final_position, NULL, island_stitch_data); island_stitch_data[state->uvs[edge->uv1]->island].use_edge_rotation = TRUE; } @@ -1236,7 +1246,7 @@ static int stitch_process_data(StitchState *state, Scene *scene, int final) if (final && state->clear_seams) { for (i = 0; i < state->selection_size; i++) { UvEdge *edge = state->selection_stack[i]; - if(edge->flag & STITCH_STITCHABLE) { + if (edge->flag & STITCH_STITCHABLE) { BM_elem_flag_disable(edge->element->l->e, BM_ELEM_SEAM); } } @@ -1388,7 +1398,8 @@ static void stitch_switch_selection_mode(StitchState *state) element->flag &= ~STITCH_SELECTED; } state->mode = STITCH_EDGE; - } else { + } + else { int i; state->selection_stack = MEM_mallocN(state->total_separate_uvs*sizeof(*state->selection_stack), "stitch_new_vert_selection_stack"); @@ -1462,7 +1473,7 @@ static void stitch_draw(const bContext *UNUSED(C), ARegion *UNUSED(ar), void *ar glDisable(GL_BLEND); /* draw vert preview */ - if(state->mode == STITCH_VERT) { + if (state->mode == STITCH_VERT) { glPointSize(pointsize * 2.0f); UI_ThemeColor4(TH_STITCH_PREVIEW_STITCHABLE); glVertexPointer(2, GL_FLOAT, 0, stitch_preview->preview_stitchable); @@ -1471,7 +1482,8 @@ static void stitch_draw(const bContext *UNUSED(C), ARegion *UNUSED(ar), void *ar UI_ThemeColor4(TH_STITCH_PREVIEW_UNSTITCHABLE); glVertexPointer(2, GL_FLOAT, 0, stitch_preview->preview_unstitchable); glDrawArrays(GL_POINTS, 0, stitch_preview->num_unstitchable); - } else { + } + else { UI_ThemeColor4(TH_STITCH_PREVIEW_STITCHABLE); glVertexPointer(2, GL_FLOAT, 0, stitch_preview->preview_stitchable); glDrawArrays(GL_LINES, 0, 2*stitch_preview->num_stitchable); @@ -1497,10 +1509,11 @@ static UvEdge *uv_edge_get (BMLoop *l, StitchState *state) int uv1 = state->map[element1 - state->element_map->buf]; int uv2 = state->map[element2 - state->element_map->buf]; - if(uv1 < uv2) { + if (uv1 < uv2) { tmp_edge.uv1 = uv1; tmp_edge.uv2 = uv2; - } else { + } + else { tmp_edge.uv1 = uv2; tmp_edge.uv2 = uv1; } @@ -1551,16 +1564,19 @@ static int stitch_init(bContext *C, wmOperator *op) state->clear_seams = RNA_boolean_get(op->ptr, "clear_seams"); if (RNA_struct_property_is_set(op->ptr, "mode")) { state->mode = RNA_enum_get(op->ptr, "mode"); - } else { + } + else { if (ts->uv_flag & UV_SYNC_SELECTION) { if (ts->selectmode & SCE_SELECT_VERTEX) state->mode = STITCH_VERT; else state->mode = STITCH_EDGE; - } else { + } + else { if (ts->uv_selectmode & UV_SELECT_VERTEX) { state->mode = STITCH_VERT; - } else { + } + else { state->mode = STITCH_EDGE; } } @@ -1729,7 +1745,7 @@ static int stitch_init(bContext *C, wmOperator *op) EDBM_index_arrays_ensure(em, BM_FACE); - if(stored_mode == STITCH_VERT) { + if (stored_mode == STITCH_VERT) { state->selection_stack = MEM_mallocN(sizeof(*state->selection_stack) * state->total_separate_uvs, "uv_stitch_selection_stack"); RNA_BEGIN (op->ptr, itemptr, "selection") @@ -1741,7 +1757,8 @@ static int stitch_init(bContext *C, wmOperator *op) stitch_select_uv(element, state, 1); } RNA_END; - } else { + } + else { state->selection_stack = MEM_mallocN(sizeof(*state->selection_stack) * state->total_separate_edges, "uv_stitch_selection_stack"); RNA_BEGIN (op->ptr, itemptr, "selection") @@ -1754,13 +1771,14 @@ static int stitch_init(bContext *C, wmOperator *op) element = ED_uv_element_get(state->element_map, efa, BM_iter_at_index(NULL, BM_LOOPS_OF_FACE, efa, elementIndex)); uv1 = map[element - state->element_map->buf]; - element = ED_uv_element_get(state->element_map, efa, BM_iter_at_index(NULL, BM_LOOPS_OF_FACE, efa, (elementIndex+1)%efa->len)); + element = ED_uv_element_get(state->element_map, efa, BM_iter_at_index(NULL, BM_LOOPS_OF_FACE, efa, (elementIndex + 1) % efa->len)); uv2 = map[element - state->element_map->buf]; - if(uv1 < uv2) { + if (uv1 < uv2) { tmp_edge.uv1 = uv1; tmp_edge.uv2 = uv2; - } else { + } + else { tmp_edge.uv1 = uv2; tmp_edge.uv2 = uv1; } @@ -1782,7 +1800,7 @@ static int stitch_init(bContext *C, wmOperator *op) } else { - if(state->mode == STITCH_VERT) { + if (state->mode == STITCH_VERT) { state->selection_stack = MEM_mallocN(sizeof(*state->selection_stack) * state->total_separate_uvs, "uv_stitch_selection_stack"); BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) { @@ -1795,14 +1813,15 @@ static int stitch_init(bContext *C, wmOperator *op) } } } - } else { + } + else { state->selection_stack = MEM_mallocN(sizeof(*state->selection_stack) * state->total_separate_edges, "uv_stitch_selection_stack"); BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) { BM_ITER_ELEM_INDEX (l, &liter, efa, BM_LOOPS_OF_FACE, i) { - if(uvedit_edge_select_test(em, scene, l)) { + if (uvedit_edge_select_test(em, scene, l)) { UvEdge *edge = uv_edge_get(l, state); - if(edge) { + if (edge) { stitch_select_edge(edge, state, TRUE); } } @@ -1879,7 +1898,8 @@ static void stitch_exit(bContext *C, wmOperator *op, int finished) PointerRNA itemptr; if (state->mode == STITCH_VERT) { element = state->selection_stack[i]; - } else { + } + else { element = ((UvEdge *)state->selection_stack[i])->element; } RNA_collection_add(op->ptr, "selection", &itemptr); @@ -1936,7 +1956,7 @@ static void stitch_select(bContext *C, Scene *scene, wmEvent *event, StitchState UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &co[0], &co[1]); - if(state->mode == STITCH_VERT) { + if (state->mode == STITCH_VERT) { uv_find_nearest_vert(scene, ima, state->em, co, NULL, &hit); if (hit.efa) { @@ -1949,10 +1969,11 @@ static void stitch_select(bContext *C, Scene *scene, wmEvent *event, StitchState stitch_select_uv(element, state, FALSE); } - } else { + } + else { uv_find_nearest_edge(scene, ima, state->em, co, &hit); - if(hit.efa) { + if (hit.efa) { UvEdge *edge = uv_edge_get(hit.l, state); stitch_select_edge(edge, state, FALSE); } diff --git a/source/blender/gpu/intern/gpu_material.c b/source/blender/gpu/intern/gpu_material.c index 09776fd1714..2039f01a740 100644 --- a/source/blender/gpu/intern/gpu_material.c +++ b/source/blender/gpu/intern/gpu_material.c @@ -1526,7 +1526,7 @@ GPUMaterial *GPU_material_from_blender(Scene *scene, Material *ma) ntreeGPUMaterialNodes(ma->nodetree, mat); } else { - if(BKE_scene_use_new_shading_nodes(scene)) { + if (BKE_scene_use_new_shading_nodes(scene)) { /* create simple diffuse material instead of nodes */ outlink = gpu_material_diffuse_bsdf(mat, ma); } From e72239c6a45173c0d23868c8e66b0926dcf2fd9c Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 18 Dec 2012 01:52:18 +0000 Subject: [PATCH 211/252] style cleanup --- .../blenkernel/intern/particle_system.c | 26 ++++++++++++------- source/blender/blenkernel/intern/smoke.c | 9 ++++--- source/blender/bmesh/CMakeLists.txt | 2 -- .../blender/editors/physics/physics_fluid.c | 2 +- .../editors/space_sequencer/space_sequencer.c | 3 ++- .../blender/imbuf/intern/cineon/cineonlib.c | 3 ++- source/blender/imbuf/intern/cineon/dpxlib.c | 3 ++- 7 files changed, 30 insertions(+), 18 deletions(-) diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c index 26bdc751582..090082b333d 100644 --- a/source/blender/blenkernel/intern/particle_system.c +++ b/source/blender/blenkernel/intern/particle_system.c @@ -2400,7 +2400,8 @@ typedef struct SPHRangeData { int use_size; } SPHRangeData; -static void sph_evaluate_func(BVHTree *tree, ParticleSystem **psys, float co[3], SPHRangeData *pfr, float interaction_radius, BVHTree_RangeQuery callback) { +static void sph_evaluate_func(BVHTree *tree, ParticleSystem **psys, float co[3], SPHRangeData *pfr, float interaction_radius, BVHTree_RangeQuery callback) +{ int i; pfr->tot_neighbors = 0; @@ -2604,16 +2605,20 @@ static void sph_force_cb(void *sphdata_v, ParticleKey *state, float *force, floa } /* powf is really slow for raising to integer powers. */ -MINLINE float pow2(float x) { +MINLINE float pow2(float x) +{ return x * x; } -MINLINE float pow3(float x) { +MINLINE float pow3(float x) +{ return pow2(x) * x; } -MINLINE float pow4(float x) { +MINLINE float pow4(float x) +{ return pow2(pow2(x)); } -MINLINE float pow7(float x) { +MINLINE float pow7(float x) +{ return pow2(pow3(x)) * x; } @@ -2773,7 +2778,8 @@ static void sphclassical_force_cb(void *sphdata_v, ParticleKey *state, float *fo sphdata->pass++; } -static void sphclassical_calc_dens(ParticleData *pa, float UNUSED(dfra), SPHData *sphdata){ +static void sphclassical_calc_dens(ParticleData *pa, float UNUSED(dfra), SPHData *sphdata) +{ ParticleSystem **psys = sphdata->psys; SPHFluidSettings *fluid = psys[0]->part->fluid; /* 4.0 seems to be a pretty good value */ @@ -2834,7 +2840,8 @@ void psys_sph_finalise(SPHData *sphdata) } } /* Sample the density field at a point in space. */ -void psys_sph_density(BVHTree *tree, SPHData *sphdata, float co[3], float vars[2]) { +void psys_sph_density(BVHTree *tree, SPHData *sphdata, float co[3], float vars[2]) +{ ParticleSystem **psys = sphdata->psys; SPHFluidSettings *fluid = psys[0]->part->fluid; /* 4.0 seems to be a pretty good value */ @@ -4012,7 +4019,7 @@ static const float TIMESTEP_EXPANSION_TOLERANCE = 1.5f; * step, after the velocity has been updated. element_size defines the scale of * the simulation, and is typically the distance to neighboring particles. */ static void update_courant_num(ParticleSimulationData *sim, ParticleData *pa, - float dtime, SPHData *sphdata) + float dtime, SPHData *sphdata) { float relative_vel[3]; float speed; @@ -4022,7 +4029,8 @@ static void update_courant_num(ParticleSimulationData *sim, ParticleData *pa, if (sim->courant_num < speed * dtime / sphdata->element_size) sim->courant_num = speed * dtime / sphdata->element_size; } -static float get_base_time_step(ParticleSettings *part) { +static float get_base_time_step(ParticleSettings *part) +{ return 1.0f / (float) (part->subframes + 1); } /* Update time step size to suit current conditions. */ diff --git a/source/blender/blenkernel/intern/smoke.c b/source/blender/blenkernel/intern/smoke.c index 53dfbdcfb85..c9cf5d561e5 100644 --- a/source/blender/blenkernel/intern/smoke.c +++ b/source/blender/blenkernel/intern/smoke.c @@ -924,7 +924,8 @@ static void clampBoundsInDomain(SmokeDomainSettings *sds, int min[3], int max[3] } } -static void em_allocateData(EmissionMap *em, int use_velocity) { +static void em_allocateData(EmissionMap *em, int use_velocity) +{ int i, res[3]; for (i = 0; i < 3; i++) { @@ -941,7 +942,8 @@ static void em_allocateData(EmissionMap *em, int use_velocity) { em->velocity = MEM_callocN(sizeof(float) * em->total_cells * 3, "smoke_flow_velocity"); } -static void em_freeData(EmissionMap *em) { +static void em_freeData(EmissionMap *em) +{ if (em->influence) MEM_freeN(em->influence); if (em->velocity) @@ -2509,7 +2511,8 @@ float smoke_get_velocity_at(struct Object *ob, float position[3], float velocity return -1.0f; } -int smoke_get_data_flags(SmokeDomainSettings *sds) { +int smoke_get_data_flags(SmokeDomainSettings *sds) +{ int flags = 0; if (smoke_has_heat(sds->fluid)) flags |= SM_ACTIVE_HEAT; if (smoke_has_fuel(sds->fluid)) flags |= SM_ACTIVE_FIRE; diff --git a/source/blender/bmesh/CMakeLists.txt b/source/blender/bmesh/CMakeLists.txt index ae2400b6cdc..c41b0703240 100644 --- a/source/blender/bmesh/CMakeLists.txt +++ b/source/blender/bmesh/CMakeLists.txt @@ -113,8 +113,6 @@ set(SRC tools/bmesh_decimate.h tools/bmesh_edgesplit.c tools/bmesh_edgesplit.h - tools/bmesh_triangulate.c - tools/bmesh_triangulate.h bmesh.h bmesh_class.h diff --git a/source/blender/editors/physics/physics_fluid.c b/source/blender/editors/physics/physics_fluid.c index 25408961dc5..db2023b7364 100644 --- a/source/blender/editors/physics/physics_fluid.c +++ b/source/blender/editors/physics/physics_fluid.c @@ -142,7 +142,7 @@ static int fluid_is_animated_mesh(FluidsimSettings *fss) #if 0 /* helper function */ -void fluidsimGetGeometryObjFilename(Object *ob, char *dst) { //, char *srcname) +void fluidsimGetGeometryObjFilename(Object *ob, char *dst) //, char *srcname) { //BLI_snprintf(dst, FILE_MAXFILE, "%s_cfgdata_%s.bobj.gz", srcname, ob->id.name); BLI_snprintf(dst, FILE_MAXFILE, "fluidcfgdata_%s.bobj.gz", ob->id.name); diff --git a/source/blender/editors/space_sequencer/space_sequencer.c b/source/blender/editors/space_sequencer/space_sequencer.c index 436b649f3b1..d541e1d6c07 100644 --- a/source/blender/editors/space_sequencer/space_sequencer.c +++ b/source/blender/editors/space_sequencer/space_sequencer.c @@ -308,7 +308,8 @@ static void sequencer_refresh(const bContext *C, ScrArea *sa) } } -static SpaceLink *sequencer_duplicate(SpaceLink *sl){ +static SpaceLink *sequencer_duplicate(SpaceLink *sl) +{ SpaceSeq *sseqn = MEM_dupallocN(sl); /* clear or remove stuff from old */ diff --git a/source/blender/imbuf/intern/cineon/cineonlib.c b/source/blender/imbuf/intern/cineon/cineonlib.c index 3049a5be514..b858251a6b9 100644 --- a/source/blender/imbuf/intern/cineon/cineonlib.c +++ b/source/blender/imbuf/intern/cineon/cineonlib.c @@ -50,7 +50,8 @@ static int verbose = 0; -void cineonSetVerbose(int verbosity) { +void cineonSetVerbose(int verbosity) +{ verbose = verbosity; } diff --git a/source/blender/imbuf/intern/cineon/dpxlib.c b/source/blender/imbuf/intern/cineon/dpxlib.c index 4c9b5e620dd..aeebf46a632 100644 --- a/source/blender/imbuf/intern/cineon/dpxlib.c +++ b/source/blender/imbuf/intern/cineon/dpxlib.c @@ -48,7 +48,8 @@ static int verbose = 0; -void dpxSetVerbose(int verbosity) { +void dpxSetVerbose(int verbosity) +{ verbose = verbosity; } From dd68223c720c951b8e8f54a8664dab34270b985d Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 18 Dec 2012 05:29:56 +0000 Subject: [PATCH 212/252] fix [#33575] Manipulator showing incorrect local axes in armature pose mode. --- .../blender/editors/transform/transform_manipulator.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/source/blender/editors/transform/transform_manipulator.c b/source/blender/editors/transform/transform_manipulator.c index 757fdfa2445..80c67cb3f4c 100644 --- a/source/blender/editors/transform/transform_manipulator.c +++ b/source/blender/editors/transform/transform_manipulator.c @@ -572,6 +572,16 @@ int calc_manipulator_stats(const bContext *C) } /* no break we define 'normal' as 'local' in Object mode */ case V3D_MANIP_LOCAL: + if (ob->mode & OB_MODE_POSE) { + /* each bone moves on its own local axis, but to avoid confusion, + * use the active pones axis for display [#33575], this works as expected on a single bone + * and users who select many bones will understand whats going on and what local means + * when they start transforming */ + float mat[3][3]; + ED_getTransformOrientationMatrix(C, mat, (v3d->around == V3D_ACTIVE)); + copy_m4_m3(rv3d->twmat, mat); + break; + } copy_m4_m4(rv3d->twmat, ob->obmat); normalize_m4(rv3d->twmat); break; From 40a667e2ffcf772c65220debf19fa3926a4e4a01 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 18 Dec 2012 05:38:21 +0000 Subject: [PATCH 213/252] code cleanup --- .../editors/transform/transform_manipulator.c | 14 ++++++++++---- .../editors/transform/transform_orientations.c | 4 ++-- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/source/blender/editors/transform/transform_manipulator.c b/source/blender/editors/transform/transform_manipulator.c index 80c67cb3f4c..50f753390bd 100644 --- a/source/blender/editors/transform/transform_manipulator.c +++ b/source/blender/editors/transform/transform_manipulator.c @@ -552,8 +552,9 @@ int calc_manipulator_stats(const bContext *C) switch (v3d->twmode) { case V3D_MANIP_GLOBAL: + { break; /* nothing to do */ - + } case V3D_MANIP_GIMBAL: { float mat[3][3]; @@ -562,16 +563,21 @@ int calc_manipulator_stats(const bContext *C) break; } /* if not gimbal, fall through to normal */ + /* pass through */ } case V3D_MANIP_NORMAL: + { if (obedit || ob->mode & OB_MODE_POSE) { float mat[3][3]; ED_getTransformOrientationMatrix(C, mat, (v3d->around == V3D_ACTIVE)); copy_m4_m3(rv3d->twmat, mat); break; } - /* no break we define 'normal' as 'local' in Object mode */ + /* no break we define 'normal' as 'local' in Object mode */ + /* pass through */ + } case V3D_MANIP_LOCAL: + { if (ob->mode & OB_MODE_POSE) { /* each bone moves on its own local axis, but to avoid confusion, * use the active pones axis for display [#33575], this works as expected on a single bone @@ -585,15 +591,15 @@ int calc_manipulator_stats(const bContext *C) copy_m4_m4(rv3d->twmat, ob->obmat); normalize_m4(rv3d->twmat); break; - + } case V3D_MANIP_VIEW: { float mat[3][3]; copy_m3_m4(mat, rv3d->viewinv); normalize_m3(mat); copy_m4_m3(rv3d->twmat, mat); + break; } - break; default: /* V3D_MANIP_CUSTOM */ { float mat[3][3]; diff --git a/source/blender/editors/transform/transform_orientations.c b/source/blender/editors/transform/transform_orientations.c index e865680ebd3..1f0fcbcde5a 100644 --- a/source/blender/editors/transform/transform_orientations.c +++ b/source/blender/editors/transform/transform_orientations.c @@ -738,7 +738,7 @@ int getTransformOrientation(const bContext *C, float normal[3], float plane[3], } } - if (normal[0] != 0 || normal[1] != 0 || normal[2] != 0) { + if (!is_zero_v3(normal)) { result = ORIENTATION_NORMAL; } } @@ -780,7 +780,7 @@ int getTransformOrientation(const bContext *C, float normal[3], float plane[3], normalize_v3(normal); normalize_v3(plane); - if (plane[0] != 0 || plane[1] != 0 || plane[2] != 0) { + if (!is_zero_v3(plane)) { result = ORIENTATION_EDGE; } From a82397561e884a6ff4a640dc0cc419ff90a596e2 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 18 Dec 2012 06:36:35 +0000 Subject: [PATCH 214/252] add support for active-element in pose mode and armature editmode. This works most usefully when combined with Normal orientation. --- .../editors/transform/transform_manipulator.c | 63 ++++++++++---- .../transform/transform_orientations.c | 82 +++++++++++++------ 2 files changed, 102 insertions(+), 43 deletions(-) diff --git a/source/blender/editors/transform/transform_manipulator.c b/source/blender/editors/transform/transform_manipulator.c index 50f753390bd..f848ab9f4dc 100644 --- a/source/blender/editors/transform/transform_manipulator.c +++ b/source/blender/editors/transform/transform_manipulator.c @@ -361,18 +361,35 @@ int calc_manipulator_stats(const bContext *C) else if (obedit->type == OB_ARMATURE) { bArmature *arm = obedit->data; EditBone *ebo; - for (ebo = arm->edbo->first; ebo; ebo = ebo->next) { - if (EBONE_VISIBLE(arm, ebo)) { - if (ebo->flag & BONE_TIPSEL) { - calc_tw_center(scene, ebo->tail); - totsel++; - } - if (ebo->flag & BONE_ROOTSEL) { - calc_tw_center(scene, ebo->head); - totsel++; - } - if (ebo->flag & BONE_SELECTED) { - stats_editbone(rv3d, ebo); + + if ((v3d->around == V3D_ACTIVE) && (ebo = arm->act_edbone)) { + /* doesn't check selection or visibility intentionally */ + if (ebo->flag & BONE_TIPSEL) { + calc_tw_center(scene, ebo->tail); + totsel++; + } + if ((ebo->flag & BONE_ROOTSEL) || + ((ebo->flag & BONE_TIPSEL) == FALSE)) /* ensure we get at least one point */ + { + calc_tw_center(scene, ebo->head); + totsel++; + } + stats_editbone(rv3d, ebo); + } + else { + for (ebo = arm->edbo->first; ebo; ebo = ebo->next) { + if (EBONE_VISIBLE(arm, ebo)) { + if (ebo->flag & BONE_TIPSEL) { + calc_tw_center(scene, ebo->tail); + totsel++; + } + if (ebo->flag & BONE_ROOTSEL) { + calc_tw_center(scene, ebo->head); + totsel++; + } + if (ebo->flag & BONE_SELECTED) { + stats_editbone(rv3d, ebo); + } } } } @@ -480,17 +497,29 @@ int calc_manipulator_stats(const bContext *C) else if (ob && (ob->mode & OB_MODE_POSE)) { bPoseChannel *pchan; int mode = TFM_ROTATION; // mislead counting bones... bah. We don't know the manipulator mode, could be mixed + int ok = FALSE; if ((ob->lay & v3d->lay) == 0) return 0; - totsel = count_set_pose_transflags(&mode, 0, ob); + if ((v3d->around == V3D_ACTIVE) && (pchan = BKE_pose_channel_active(ob))) { + /* doesn't check selection or visibility intentionally */ + stats_pose(scene, rv3d, pchan); + totsel = 1; + ok = TRUE; + } + else { + totsel = count_set_pose_transflags(&mode, 0, ob); - if (totsel) { - /* use channels to get stats */ - for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) { - stats_pose(scene, rv3d, pchan); + if (totsel) { + /* use channels to get stats */ + for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) { + stats_pose(scene, rv3d, pchan); + } + ok = TRUE; } + } + if (ok) { mul_v3_fl(scene->twcent, 1.0f / (float)totsel); // centroid! mul_m4_v3(ob->obmat, scene->twcent); mul_m4_v3(ob->obmat, scene->twmin); diff --git a/source/blender/editors/transform/transform_orientations.c b/source/blender/editors/transform/transform_orientations.c index 1f0fcbcde5a..c9c4f7e2c7b 100644 --- a/source/blender/editors/transform/transform_orientations.c +++ b/source/blender/editors/transform/transform_orientations.c @@ -43,6 +43,7 @@ #include "BLI_blenlib.h" #include "BLI_utildefines.h" +#include "BKE_action.h" #include "BKE_armature.h" #include "BKE_curve.h" #include "BKE_context.h" @@ -761,29 +762,45 @@ int getTransformOrientation(const bContext *C, float normal[3], float plane[3], else if (obedit->type == OB_ARMATURE) { bArmature *arm = obedit->data; EditBone *ebone; + int ok = FALSE; - for (ebone = arm->edbo->first; ebone; ebone = ebone->next) { - if (arm->layer & ebone->layer) { - if (ebone->flag & BONE_SELECTED) { - float tmat[3][3]; - float vec[3]; - sub_v3_v3v3(vec, ebone->tail, ebone->head); - normalize_v3(vec); - add_v3_v3(normal, vec); - - vec_roll_to_mat3(vec, ebone->roll, tmat); - add_v3_v3(plane, tmat[2]); + /* grr,.but better then duplicate code */ +#define EBONE_CALC_NORMAL_PLANE { \ + float tmat[3][3]; \ + float vec[3]; \ + sub_v3_v3v3(vec, ebone->tail, ebone->head); \ + normalize_v3(vec); \ + add_v3_v3(normal, vec); \ + \ + vec_roll_to_mat3(vec, ebone->roll, tmat); \ + add_v3_v3(plane, tmat[2]); \ + } (void)0 + + + if (activeOnly && (ebone = arm->act_edbone)) { + EBONE_CALC_NORMAL_PLANE; + ok = TRUE; + } + else { + for (ebone = arm->edbo->first; ebone; ebone = ebone->next) { + if (arm->layer & ebone->layer) { + if (ebone->flag & BONE_SELECTED) { + EBONE_CALC_NORMAL_PLANE; + ok = TRUE; + } } } } - normalize_v3(normal); - normalize_v3(plane); + if (ok) { + normalize_v3(normal); + normalize_v3(plane); - if (!is_zero_v3(plane)) { - result = ORIENTATION_EDGE; + if (!is_zero_v3(plane)) { + result = ORIENTATION_EDGE; + } } - +#undef EBONE_CALC_NORMAL_PLANE } /* Vectors from edges don't need the special transpose inverse multiplication */ @@ -799,19 +816,32 @@ int getTransformOrientation(const bContext *C, float normal[3], float plane[3], else if (ob && (ob->mode & OB_MODE_POSE)) { bArmature *arm = ob->data; bPoseChannel *pchan; - int totsel; - - totsel = count_bone_select(arm, &arm->bonebase, 1); - if (totsel) { - float imat[3][3], mat[3][3]; + float imat[3][3], mat[3][3]; + int ok = FALSE; - /* use channels to get stats */ - for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) { - if (pchan->bone && pchan->bone->flag & BONE_TRANSFORM) { - add_v3_v3(normal, pchan->pose_mat[2]); - add_v3_v3(plane, pchan->pose_mat[1]); + if (activeOnly && (pchan = BKE_pose_channel_active(ob))) { + add_v3_v3(normal, pchan->pose_mat[2]); + add_v3_v3(plane, pchan->pose_mat[1]); + ok = TRUE; + } + else { + int totsel; + + totsel = count_bone_select(arm, &arm->bonebase, 1); + if (totsel) { + /* use channels to get stats */ + for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) { + if (pchan->bone && pchan->bone->flag & BONE_TRANSFORM) { + add_v3_v3(normal, pchan->pose_mat[2]); + add_v3_v3(plane, pchan->pose_mat[1]); + } } + ok = TRUE; } + } + + /* use for both active & all */ + if (ok) { negate_v3(plane); /* we need the transpose of the inverse for a normal... */ From 2c0bceb1f51344ece4be7a41ca93cc72f0151667 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 18 Dec 2012 07:38:02 +0000 Subject: [PATCH 215/252] fix for own error in recent commit with active pose mode, depended on an uninitialized flag. --- .../editors/transform/transform_manipulator.c | 20 +++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/source/blender/editors/transform/transform_manipulator.c b/source/blender/editors/transform/transform_manipulator.c index f848ab9f4dc..6b016bf4303 100644 --- a/source/blender/editors/transform/transform_manipulator.c +++ b/source/blender/editors/transform/transform_manipulator.c @@ -148,10 +148,8 @@ static void stats_pose(Scene *scene, RegionView3D *rv3d, bPoseChannel *pchan) Bone *bone = pchan->bone; if (bone) { - if (bone->flag & BONE_TRANSFORM) { - calc_tw_center(scene, pchan->pose_head); - protectflag_to_drawflags(pchan->protectflag, &rv3d->twdrawflag); - } + calc_tw_center(scene, pchan->pose_head); + protectflag_to_drawflags(pchan->protectflag, &rv3d->twdrawflag); } } @@ -503,9 +501,12 @@ int calc_manipulator_stats(const bContext *C) if ((v3d->around == V3D_ACTIVE) && (pchan = BKE_pose_channel_active(ob))) { /* doesn't check selection or visibility intentionally */ - stats_pose(scene, rv3d, pchan); - totsel = 1; - ok = TRUE; + Bone *bone = pchan->bone; + if (bone) { + stats_pose(scene, rv3d, pchan); + totsel = 1; + ok = TRUE; + } } else { totsel = count_set_pose_transflags(&mode, 0, ob); @@ -513,7 +514,10 @@ int calc_manipulator_stats(const bContext *C) if (totsel) { /* use channels to get stats */ for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) { - stats_pose(scene, rv3d, pchan); + Bone *bone = pchan->bone; + if (bone && (bone->flag & BONE_TRANSFORM)) { + stats_pose(scene, rv3d, pchan); + } } ok = TRUE; } From e364c94c7b803c78b8dd44a8023dac8952e6efab Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 18 Dec 2012 08:41:38 +0000 Subject: [PATCH 216/252] fix [#33580] Masking keyframes disappear from dope sheet when using undo. --- source/blender/blenkernel/BKE_library.h | 1 + source/blender/blenkernel/intern/library.c | 8 ++++++++ source/blender/blenloader/intern/readfile.c | 17 ++++++++++++----- .../editors/animation/anim_channels_edit.c | 2 +- source/blender/editors/space_clip/clip_editor.c | 8 +++----- source/blender/editors/space_image/image_edit.c | 7 +++---- 6 files changed, 28 insertions(+), 15 deletions(-) diff --git a/source/blender/blenkernel/BKE_library.h b/source/blender/blenkernel/BKE_library.h index bc081b7f308..b9bb67fa509 100644 --- a/source/blender/blenkernel/BKE_library.h +++ b/source/blender/blenkernel/BKE_library.h @@ -62,6 +62,7 @@ void BKE_libblock_copy_data(struct ID *id, const struct ID *id_from, const shor void BKE_id_lib_local_paths(struct Main *bmain, struct Library *lib, struct ID *id); void id_lib_extern(struct ID *id); void BKE_library_filepath_set(struct Library *lib, const char *filepath); +void id_us_ensure_real(struct ID *id); void id_us_plus(struct ID *id); void id_us_min(struct ID *id); diff --git a/source/blender/blenkernel/intern/library.c b/source/blender/blenkernel/intern/library.c index 855e2d44661..9ace0ceade3 100644 --- a/source/blender/blenkernel/intern/library.c +++ b/source/blender/blenkernel/intern/library.c @@ -152,6 +152,14 @@ void id_lib_extern(ID *id) } } +/* ensure we have a real user */ +void id_us_ensure_real(ID *id) +{ + if (ID_REAL_USERS(id) <= 0) { + id->us = MAX2(id->us, 0) + 1; + } +} + void id_us_plus(ID *id) { if (id) { diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index a1a34816d51..98f3baa4c08 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -5414,7 +5414,14 @@ static void *restore_pointer_by_name(Main *mainp, ID *id, int user) for (; idn; idn = idn->next) { if (idn->name[2] == name[0] && strcmp(idn->name+2, name) == 0) { if (idn->lib == id->lib) { - if (user && idn->us == 0) idn->us++; + if (user == 1) { + if (idn->us == 0) { + idn->us++; + } + } + else if (user == 2) { + id_us_ensure_real(idn); + } break; } } @@ -5580,7 +5587,7 @@ void blo_lib_link_screen_restore(Main *newmain, bScreen *curscreen, Scene *cursc else if (sl->spacetype == SPACE_IMAGE) { SpaceImage *sima = (SpaceImage *)sl; - sima->image = restore_pointer_by_name(newmain, (ID *)sima->image, 1); + sima->image = restore_pointer_by_name(newmain, (ID *)sima->image, 2); /* this will be freed, not worth attempting to find same scene, * since it gets initialized later */ @@ -5596,7 +5603,7 @@ void blo_lib_link_screen_restore(Main *newmain, bScreen *curscreen, Scene *cursc * so assume that here we're doing for undo only... */ sima->gpd = restore_pointer_by_name(newmain, (ID *)sima->gpd, 1); - sima->mask_info.mask = restore_pointer_by_name(newmain, (ID *)sima->mask_info.mask, 1); + sima->mask_info.mask = restore_pointer_by_name(newmain, (ID *)sima->mask_info.mask, 2); } else if (sl->spacetype == SPACE_SEQ) { SpaceSeq *sseq = (SpaceSeq *)sl; @@ -5671,8 +5678,8 @@ void blo_lib_link_screen_restore(Main *newmain, bScreen *curscreen, Scene *cursc else if (sl->spacetype == SPACE_CLIP) { SpaceClip *sclip = (SpaceClip *)sl; - sclip->clip = restore_pointer_by_name(newmain, (ID *)sclip->clip, 1); - sclip->mask_info.mask = restore_pointer_by_name(newmain, (ID *)sclip->mask_info.mask, 1); + sclip->clip = restore_pointer_by_name(newmain, (ID *)sclip->clip, 2); + sclip->mask_info.mask = restore_pointer_by_name(newmain, (ID *)sclip->mask_info.mask, 2); sclip->scopes.ok = 0; } diff --git a/source/blender/editors/animation/anim_channels_edit.c b/source/blender/editors/animation/anim_channels_edit.c index 1e4431bd0d6..458054c9d7f 100644 --- a/source/blender/editors/animation/anim_channels_edit.c +++ b/source/blender/editors/animation/anim_channels_edit.c @@ -1236,7 +1236,7 @@ static int animchannels_delete_exec(bContext *C, wmOperator *UNUSED(op)) case ANIMTYPE_MASKLAYER: { - /* Grease Pencil layer */ + /* Mask layer */ Mask *mask = (Mask *)ale->id; MaskLayer *masklay = (MaskLayer *)ale->data; diff --git a/source/blender/editors/space_clip/clip_editor.c b/source/blender/editors/space_clip/clip_editor.c index 1a62af39600..3088243d266 100644 --- a/source/blender/editors/space_clip/clip_editor.c +++ b/source/blender/editors/space_clip/clip_editor.c @@ -38,6 +38,7 @@ #include "BKE_movieclip.h" #include "BKE_context.h" #include "BKE_tracking.h" +#include "BKE_library.h" #include "DNA_mask_types.h" #include "DNA_object_types.h" /* SELECT */ @@ -524,8 +525,7 @@ void ED_space_clip_set_clip(bContext *C, bScreen *screen, SpaceClip *sc, MovieCl old_clip = sc->clip; sc->clip = clip; - if (sc->clip && sc->clip->id.us == 0) - sc->clip->id.us = 1; + id_us_ensure_real((ID *)sc->clip); if (screen && sc->view == SC_VIEW_CLIP) { ScrArea *area; @@ -561,9 +561,7 @@ void ED_space_clip_set_mask(bContext *C, SpaceClip *sc, Mask *mask) { sc->mask_info.mask = mask; - if (sc->mask_info.mask && sc->mask_info.mask->id.us == 0) { - sc->mask_info.mask->id.us = 1; - } + id_us_ensure_real((ID *)sc->mask_info.mask); if (C) { WM_event_add_notifier(C, NC_MASK | NA_SELECTED, mask); diff --git a/source/blender/editors/space_image/image_edit.c b/source/blender/editors/space_image/image_edit.c index 261caf57c5d..34207e16f1c 100644 --- a/source/blender/editors/space_image/image_edit.c +++ b/source/blender/editors/space_image/image_edit.c @@ -40,6 +40,7 @@ #include "BKE_image.h" #include "BKE_main.h" #include "BKE_tessmesh.h" +#include "BKE_library.h" #include "IMB_imbuf_types.h" @@ -78,8 +79,7 @@ void ED_space_image_set(SpaceImage *sima, Scene *scene, Object *obedit, Image *i if (sima->image) BKE_image_signal(sima->image, &sima->iuser, IMA_SIGNAL_USER_NEW_IMAGE); - if (sima->image && ID_REAL_USERS(sima->image) <= 0) - sima->image->id.us = max_ii(sima->image->id.us, 0) + 1; + id_us_ensure_real((ID *)sima->image); if (obedit) WM_main_add_notifier(NC_GEOM | ND_DATA, obedit->data); @@ -97,8 +97,7 @@ void ED_space_image_set_mask(bContext *C, SpaceImage *sima, Mask *mask) sima->mask_info.mask = mask; /* weak, but same as image/space */ - if (sima->mask_info.mask && ID_REAL_USERS(sima->mask_info.mask) <= 0) - sima->mask_info.mask->id.us = max_ii(sima->mask_info.mask->id.us, 0) + 1; + id_us_ensure_real((ID *)sima->mask_info.mask); if (C) { WM_event_add_notifier(C, NC_MASK | NA_SELECTED, mask); From c1976dfd28ab5a76518ba3a2e24f5215995f1f4c Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Tue, 18 Dec 2012 08:50:22 +0000 Subject: [PATCH 217/252] Added WeightVG modifier icon to svg file (and tried enhance it slightly). --- release/datafiles/blender_icons.png | Bin 189744 -> 230694 bytes release/datafiles/blender_icons.svg | 144 ++++++++++++++++++++++++++-- 2 files changed, 136 insertions(+), 8 deletions(-) diff --git a/release/datafiles/blender_icons.png b/release/datafiles/blender_icons.png index b0d5e825738ce6548801ada3b73cba2fd1144313..d96dd5d48866d94c307cf778359dd4094817119a 100644 GIT binary patch literal 230694 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�IEVgQg4z@Y05(BY7{9%tQf8Kaj;+!Xjhzt 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