Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/source
diff options
context:
space:
mode:
authorTamito Kajiyama <rd6t-kjym@asahi-net.or.jp>2013-03-18 04:48:59 +0400
committerTamito Kajiyama <rd6t-kjym@asahi-net.or.jp>2013-03-18 04:48:59 +0400
commitc1ceab1281ccf061f03f8000bf190a082a5385d8 (patch)
tree01b9a9cfca80432d316bdad6c18c74eb025e9eb0 /source
parent0d9c98c4bbfbc8c70c4772086dd09a51d01921ef (diff)
parent66a35e089a64d27bfc09c2225a530069eca05875 (diff)
Merged changes in the trunk up to revision 55357.
Resolved conflicts: release/datafiles/startup.blend source/blender/editors/space_nla/nla_buttons.c Also updated source/blender/blenkernel/intern/linestyle.c as a follow-up of recent changes for the use of bool.
Diffstat (limited to 'source')
-rw-r--r--source/blender/avi/intern/avi.c27
-rw-r--r--source/blender/blenfont/BLF_api.h1
-rw-r--r--source/blender/blenfont/BLF_translation.h4
-rw-r--r--source/blender/blenfont/intern/blf.c15
-rw-r--r--source/blender/blenfont/intern/blf_dir.c1
-rw-r--r--source/blender/blenfont/intern/blf_font.c34
-rw-r--r--source/blender/blenfont/intern/blf_internal.h1
-rw-r--r--source/blender/blenfont/intern/blf_lang.c9
-rw-r--r--source/blender/blenfont/intern/blf_translation.c51
-rw-r--r--source/blender/blenkernel/BKE_DerivedMesh.h2
-rw-r--r--source/blender/blenkernel/BKE_animsys.h4
-rw-r--r--source/blender/blenkernel/BKE_blender.h4
-rw-r--r--source/blender/blenkernel/BKE_brush.h19
-rw-r--r--source/blender/blenkernel/BKE_ccg.h2
-rw-r--r--source/blender/blenkernel/BKE_curve.h17
-rw-r--r--source/blender/blenkernel/BKE_font.h2
-rw-r--r--source/blender/blenkernel/BKE_idcode.h4
-rw-r--r--source/blender/blenkernel/BKE_image.h2
-rw-r--r--source/blender/blenkernel/BKE_library.h19
-rw-r--r--source/blender/blenkernel/BKE_main.h4
-rw-r--r--source/blender/blenkernel/BKE_mball.h4
-rw-r--r--source/blender/blenkernel/BKE_mesh.h5
-rw-r--r--source/blender/blenkernel/BKE_movieclip.h5
-rw-r--r--source/blender/blenkernel/BKE_node.h1
-rw-r--r--source/blender/blenkernel/BKE_object.h17
-rw-r--r--source/blender/blenkernel/BKE_packedFile.h2
-rw-r--r--source/blender/blenkernel/BKE_paint.h14
-rw-r--r--source/blender/blenkernel/BKE_pbvh.h2
-rw-r--r--source/blender/blenkernel/BKE_screen.h14
-rw-r--r--source/blender/blenkernel/BKE_sequencer.h20
-rw-r--r--source/blender/blenkernel/BKE_text.h14
-rw-r--r--source/blender/blenkernel/BKE_tracking.h3
-rw-r--r--source/blender/blenkernel/BKE_unit.h3
-rw-r--r--source/blender/blenkernel/depsgraph_private.h2
-rw-r--r--source/blender/blenkernel/intern/DerivedMesh.c64
-rw-r--r--source/blender/blenkernel/intern/anim.c10
-rw-r--r--source/blender/blenkernel/intern/anim_sys.c4
-rw-r--r--source/blender/blenkernel/intern/armature.c2
-rw-r--r--source/blender/blenkernel/intern/blender.c6
-rw-r--r--source/blender/blenkernel/intern/bmfont.c8
-rw-r--r--source/blender/blenkernel/intern/brush.c205
-rw-r--r--source/blender/blenkernel/intern/cloth.c4
-rw-r--r--source/blender/blenkernel/intern/collision.c6
-rw-r--r--source/blender/blenkernel/intern/colortools.c8
-rw-r--r--source/blender/blenkernel/intern/constraint.c4
-rw-r--r--source/blender/blenkernel/intern/context.c7
-rw-r--r--source/blender/blenkernel/intern/curve.c62
-rw-r--r--source/blender/blenkernel/intern/customdata.c16
-rw-r--r--source/blender/blenkernel/intern/customdata_file.c4
-rw-r--r--source/blender/blenkernel/intern/deform.c8
-rw-r--r--source/blender/blenkernel/intern/depsgraph.c4
-rw-r--r--source/blender/blenkernel/intern/dynamicpaint.c30
-rw-r--r--source/blender/blenkernel/intern/font.c21
-rw-r--r--source/blender/blenkernel/intern/idcode.c17
-rw-r--r--source/blender/blenkernel/intern/idprop.c2
-rw-r--r--source/blender/blenkernel/intern/image.c12
-rw-r--r--source/blender/blenkernel/intern/image_gen.c5
-rw-r--r--source/blender/blenkernel/intern/implicit.c2
-rw-r--r--source/blender/blenkernel/intern/key.c56
-rw-r--r--source/blender/blenkernel/intern/lattice.c22
-rw-r--r--source/blender/blenkernel/intern/library.c305
-rw-r--r--source/blender/blenkernel/intern/linestyle.c7
-rw-r--r--source/blender/blenkernel/intern/material.c4
-rw-r--r--source/blender/blenkernel/intern/mball.c25
-rw-r--r--source/blender/blenkernel/intern/mesh.c84
-rw-r--r--source/blender/blenkernel/intern/mesh_validate.c10
-rw-r--r--source/blender/blenkernel/intern/movieclip.c54
-rw-r--r--source/blender/blenkernel/intern/navmesh_conversion.c2
-rw-r--r--source/blender/blenkernel/intern/nla.c4
-rw-r--r--source/blender/blenkernel/intern/node.c8
-rw-r--r--source/blender/blenkernel/intern/object.c95
-rw-r--r--source/blender/blenkernel/intern/packedFile.c21
-rw-r--r--source/blender/blenkernel/intern/paint.c69
-rw-r--r--source/blender/blenkernel/intern/pbvh.c4
-rw-r--r--source/blender/blenkernel/intern/pbvh_bmesh.c132
-rw-r--r--source/blender/blenkernel/intern/pointcache.c21
-rw-r--r--source/blender/blenkernel/intern/property.c6
-rw-r--r--source/blender/blenkernel/intern/rigidbody.c7
-rw-r--r--source/blender/blenkernel/intern/scene.c10
-rw-r--r--source/blender/blenkernel/intern/seqcache.c4
-rw-r--r--source/blender/blenkernel/intern/seqeffects.c22
-rw-r--r--source/blender/blenkernel/intern/sequencer.c78
-rw-r--r--source/blender/blenkernel/intern/smoke.c6
-rw-r--r--source/blender/blenkernel/intern/softbody.c28
-rw-r--r--source/blender/blenkernel/intern/subsurf_ccg.c7
-rw-r--r--source/blender/blenkernel/intern/text.c52
-rw-r--r--source/blender/blenkernel/intern/texture.c17
-rw-r--r--source/blender/blenkernel/intern/tracking.c64
-rw-r--r--source/blender/blenkernel/intern/unit.c58
-rw-r--r--source/blender/blenkernel/intern/writeffmpeg.c63
-rw-r--r--source/blender/blenlib/BLI_buffer.h22
-rw-r--r--source/blender/blenlib/BLI_fileops.h21
-rw-r--r--source/blender/blenlib/BLI_fileops_types.h1
-rw-r--r--source/blender/blenlib/BLI_ghash.h8
-rw-r--r--source/blender/blenlib/BLI_gsqueue.h2
-rw-r--r--source/blender/blenlib/BLI_heap.h2
-rw-r--r--source/blender/blenlib/BLI_lasso.h4
-rw-r--r--source/blender/blenlib/BLI_linklist.h1
-rw-r--r--source/blender/blenlib/BLI_math_base.h9
-rw-r--r--source/blender/blenlib/BLI_math_geom.h13
-rw-r--r--source/blender/blenlib/BLI_math_inline.h5
-rw-r--r--source/blender/blenlib/BLI_math_vector.h10
-rw-r--r--source/blender/blenlib/BLI_path_util.h67
-rw-r--r--source/blender/blenlib/BLI_rect.h28
-rw-r--r--source/blender/blenlib/BLI_string.h85
-rw-r--r--source/blender/blenlib/BLI_string_utf8.h9
-rw-r--r--source/blender/blenlib/BLI_utildefines.h24
-rw-r--r--source/blender/blenlib/BLI_winstuff.h9
-rw-r--r--source/blender/blenlib/CMakeLists.txt1
-rw-r--r--source/blender/blenlib/SConscript2
-rw-r--r--source/blender/blenlib/intern/BLI_ghash.c16
-rw-r--r--source/blender/blenlib/intern/BLI_heap.c5
-rw-r--r--source/blender/blenlib/intern/BLI_linklist.c12
-rw-r--r--source/blender/blenlib/intern/BLI_memarena.c2
-rw-r--r--source/blender/blenlib/intern/buffer.c3
-rw-r--r--source/blender/blenlib/intern/fileops.c293
-rw-r--r--source/blender/blenlib/intern/freetypefont.c4
-rw-r--r--source/blender/blenlib/intern/gsqueue.c4
-rw-r--r--source/blender/blenlib/intern/lasso.c65
-rw-r--r--source/blender/blenlib/intern/math_base.c7
-rw-r--r--source/blender/blenlib/intern/math_geom.c113
-rw-r--r--source/blender/blenlib/intern/math_matrix.c10
-rw-r--r--source/blender/blenlib/intern/math_vector_inline.c9
-rw-r--r--source/blender/blenlib/intern/noise.c4
-rw-r--r--source/blender/blenlib/intern/path_util.c736
-rw-r--r--source/blender/blenlib/intern/rct.c136
-rw-r--r--source/blender/blenlib/intern/storage.c272
-rw-r--r--source/blender/blenlib/intern/string.c155
-rw-r--r--source/blender/blenlib/intern/string_utf8.c37
-rw-r--r--source/blender/blenlib/intern/winstuff.c5
-rw-r--r--source/blender/blenloader/intern/readfile.c163
-rw-r--r--source/blender/blenloader/intern/versioning_250.c2
-rw-r--r--source/blender/blenloader/intern/versioning_legacy.c6
-rw-r--r--source/blender/blenloader/intern/writefile.c47
-rw-r--r--source/blender/bmesh/CMakeLists.txt1
-rw-r--r--source/blender/bmesh/SConscript20
-rw-r--r--source/blender/bmesh/bmesh_class.h3
-rw-r--r--source/blender/bmesh/intern/bmesh_core.c414
-rw-r--r--source/blender/bmesh/intern/bmesh_core.h6
-rw-r--r--source/blender/bmesh/intern/bmesh_interp.c22
-rw-r--r--source/blender/bmesh/intern/bmesh_log.c2
-rw-r--r--source/blender/bmesh/intern/bmesh_mesh.c2
-rw-r--r--source/blender/bmesh/intern/bmesh_mesh_conv.c4
-rw-r--r--source/blender/bmesh/intern/bmesh_mods.c164
-rw-r--r--source/blender/bmesh/intern/bmesh_mods.h4
-rw-r--r--source/blender/bmesh/intern/bmesh_operator_api.h2
-rw-r--r--source/blender/bmesh/intern/bmesh_operator_api_inline.h4
-rw-r--r--source/blender/bmesh/intern/bmesh_operators.c6
-rw-r--r--source/blender/bmesh/intern/bmesh_operators_private.h3
-rw-r--r--source/blender/bmesh/intern/bmesh_polygon.c106
-rw-r--r--source/blender/bmesh/intern/bmesh_polygon.h6
-rw-r--r--source/blender/bmesh/intern/bmesh_queries.c61
-rw-r--r--source/blender/bmesh/intern/bmesh_queries.h2
-rw-r--r--source/blender/bmesh/intern/bmesh_structure.c10
-rw-r--r--source/blender/bmesh/intern/bmesh_walkers_impl.c6
-rw-r--r--source/blender/bmesh/operators/bmo_bevel.c2
-rw-r--r--source/blender/bmesh/operators/bmo_connect.c54
-rw-r--r--source/blender/bmesh/operators/bmo_create.c14
-rw-r--r--source/blender/bmesh/operators/bmo_dissolve.c87
-rw-r--r--source/blender/bmesh/operators/bmo_extrude.c15
-rw-r--r--source/blender/bmesh/operators/bmo_hull.c2
-rw-r--r--source/blender/bmesh/operators/bmo_removedoubles.c10
-rw-r--r--source/blender/bmesh/operators/bmo_smooth_laplacian.c47
-rw-r--r--source/blender/bmesh/operators/bmo_subdivide.c223
-rw-r--r--source/blender/bmesh/operators/bmo_subdivide.h72
-rw-r--r--source/blender/bmesh/operators/bmo_wireframe.c2
-rw-r--r--source/blender/bmesh/tools/bmesh_bevel.c65
-rw-r--r--source/blender/bmesh/tools/bmesh_bevel.h2
-rw-r--r--source/blender/bmesh/tools/bmesh_decimate_dissolve.c18
-rw-r--r--source/blender/bmesh/tools/bmesh_decimate_unsubdivide.c4
-rw-r--r--source/blender/bmesh/tools/bmesh_edgesplit.c2
-rw-r--r--source/blender/collada/AnimationExporter.cpp33
-rw-r--r--source/blender/collada/AnimationExporter.h5
-rw-r--r--source/blender/collada/ArmatureImporter.cpp4
-rw-r--r--source/blender/collada/ControllerExporter.cpp2
-rw-r--r--source/blender/collada/DocumentExporter.cpp24
-rw-r--r--source/blender/collada/EffectExporter.cpp6
-rw-r--r--source/blender/collada/ExportSettings.h2
-rw-r--r--source/blender/collada/ExtraHandler.cpp2
-rw-r--r--source/blender/collada/GeometryExporter.cpp46
-rw-r--r--source/blender/collada/GeometryExporter.h2
-rw-r--r--source/blender/collada/MaterialExporter.h2
-rw-r--r--source/blender/collada/MeshImporter.cpp5
-rw-r--r--source/blender/collada/MeshImporter.h18
-rw-r--r--source/blender/collada/SceneExporter.cpp13
-rw-r--r--source/blender/collada/SceneExporter.h2
-rw-r--r--source/blender/collada/TransformWriter.cpp33
-rw-r--r--source/blender/collada/TransformWriter.h3
-rw-r--r--source/blender/collada/collada.cpp12
-rw-r--r--source/blender/collada/collada.h19
-rw-r--r--source/blender/collada/collada_internal.cpp6
-rw-r--r--source/blender/collada/collada_internal.h1
-rw-r--r--source/blender/collada/collada_utils.cpp32
-rw-r--r--source/blender/compositor/COM_compositor.h4
-rw-r--r--source/blender/compositor/intern/COM_ExecutionGroup.cpp93
-rw-r--r--source/blender/compositor/intern/COM_ExecutionGroup.h24
-rw-r--r--source/blender/compositor/intern/COM_ExecutionSystem.cpp11
-rw-r--r--source/blender/compositor/nodes/COM_CompositorNode.cpp3
-rw-r--r--source/blender/compositor/nodes/COM_MixNode.cpp10
-rw-r--r--source/blender/compositor/nodes/COM_ViewerNode.cpp2
-rw-r--r--source/blender/compositor/operations/COM_MixBaseOperation.cpp26
-rw-r--r--source/blender/compositor/operations/COM_MixBaseOperation.h2
-rw-r--r--source/blender/compositor/operations/COM_PreviewOperation.h3
-rw-r--r--source/blender/compositor/operations/COM_TextureOperation.cpp31
-rw-r--r--source/blender/compositor/operations/COM_TextureOperation.h5
-rw-r--r--source/blender/compositor/operations/COM_TranslateOperation.cpp2
-rw-r--r--source/blender/compositor/operations/COM_ViewerBaseOperation.h3
-rw-r--r--source/blender/editors/animation/anim_channels_defines.c42
-rw-r--r--source/blender/editors/animation/anim_channels_edit.c8
-rw-r--r--source/blender/editors/animation/anim_filter.c41
-rw-r--r--source/blender/editors/animation/anim_ipo_utils.c6
-rw-r--r--source/blender/editors/animation/anim_markers.c95
-rw-r--r--source/blender/editors/animation/anim_ops.c6
-rw-r--r--source/blender/editors/animation/keyframing.c27
-rw-r--r--source/blender/editors/animation/keyingsets.c4
-rw-r--r--source/blender/editors/armature/armature_add.c6
-rw-r--r--source/blender/editors/armature/armature_naming.c12
-rw-r--r--source/blender/editors/armature/armature_relations.c2
-rw-r--r--source/blender/editors/armature/armature_select.c16
-rw-r--r--source/blender/editors/armature/armature_utils.c9
-rw-r--r--source/blender/editors/armature/editarmature_generate.c6
-rw-r--r--source/blender/editors/armature/editarmature_retarget.c6
-rw-r--r--source/blender/editors/armature/editarmature_sketch.c43
-rw-r--r--source/blender/editors/armature/pose_edit.c14
-rw-r--r--source/blender/editors/armature/pose_group.c2
-rw-r--r--source/blender/editors/armature/pose_lib.c12
-rw-r--r--source/blender/editors/armature/pose_select.c2
-rw-r--r--source/blender/editors/armature/pose_slide.c12
-rw-r--r--source/blender/editors/armature/reeb.c4
-rw-r--r--source/blender/editors/curve/editcurve.c209
-rw-r--r--source/blender/editors/curve/editfont.c26
-rw-r--r--source/blender/editors/datafiles/SConscript134
-rw-r--r--source/blender/editors/gpencil/gpencil_buttons.c35
-rw-r--r--source/blender/editors/gpencil/gpencil_paint.c17
-rw-r--r--source/blender/editors/include/BIF_glutil.h14
-rw-r--r--source/blender/editors/include/ED_anim_api.h5
-rw-r--r--source/blender/editors/include/ED_armature.h3
-rw-r--r--source/blender/editors/include/ED_curve.h2
-rw-r--r--source/blender/editors/include/ED_fileselect.h7
-rw-r--r--source/blender/editors/include/ED_mesh.h10
-rw-r--r--source/blender/editors/include/ED_numinput.h2
-rw-r--r--source/blender/editors/include/ED_screen.h1
-rw-r--r--source/blender/editors/include/ED_sequencer.h2
-rw-r--r--source/blender/editors/include/ED_space_api.h2
-rw-r--r--source/blender/editors/include/ED_transform.h14
-rw-r--r--source/blender/editors/include/ED_view3d.h69
-rw-r--r--source/blender/editors/include/UI_resources.h1
-rw-r--r--source/blender/editors/interface/interface.c86
-rw-r--r--source/blender/editors/interface/interface_draw.c38
-rw-r--r--source/blender/editors/interface/interface_handlers.c30
-rw-r--r--source/blender/editors/interface/interface_icons.c22
-rw-r--r--source/blender/editors/interface/interface_intern.h7
-rw-r--r--source/blender/editors/interface/interface_layout.c5
-rw-r--r--source/blender/editors/interface/interface_ops.c6
-rw-r--r--source/blender/editors/interface/interface_panel.c4
-rw-r--r--source/blender/editors/interface/interface_regions.c6
-rw-r--r--source/blender/editors/interface/interface_style.c26
-rw-r--r--source/blender/editors/interface/interface_templates.c44
-rw-r--r--source/blender/editors/interface/interface_widgets.c9
-rw-r--r--source/blender/editors/interface/resources.c8
-rw-r--r--source/blender/editors/interface/view2d.c8
-rw-r--r--source/blender/editors/interface/view2d_ops.c20
-rw-r--r--source/blender/editors/io/io_collada.c34
-rw-r--r--source/blender/editors/mask/mask_add.c4
-rw-r--r--source/blender/editors/mask/mask_ops.c6
-rw-r--r--source/blender/editors/mask/mask_select.c4
-rw-r--r--source/blender/editors/mesh/CMakeLists.txt2
-rw-r--r--source/blender/editors/mesh/editface.c39
-rw-r--r--source/blender/editors/mesh/editmesh_add.c5
-rw-r--r--source/blender/editors/mesh/editmesh_knife.c519
-rw-r--r--source/blender/editors/mesh/editmesh_knife_project.c168
-rw-r--r--source/blender/editors/mesh/editmesh_loopcut.c7
-rw-r--r--source/blender/editors/mesh/editmesh_rip.c25
-rw-r--r--source/blender/editors/mesh/editmesh_select.c79
-rw-r--r--source/blender/editors/mesh/editmesh_tools.c235
-rw-r--r--source/blender/editors/mesh/mesh_data.c5
-rw-r--r--source/blender/editors/mesh/mesh_intern.h7
-rw-r--r--source/blender/editors/mesh/mesh_ops.c2
-rw-r--r--source/blender/editors/mesh/meshtools.c4
-rw-r--r--source/blender/editors/metaball/mball_edit.c2
-rw-r--r--source/blender/editors/metaball/mball_ops.c10
-rw-r--r--source/blender/editors/object/object_add.c13
-rw-r--r--source/blender/editors/object/object_bake.c8
-rw-r--r--source/blender/editors/object/object_constraint.c24
-rw-r--r--source/blender/editors/object/object_edit.c6
-rw-r--r--source/blender/editors/object/object_intern.h1
-rw-r--r--source/blender/editors/object/object_lattice.c53
-rw-r--r--source/blender/editors/object/object_modifier.c30
-rw-r--r--source/blender/editors/object/object_ops.c3
-rw-r--r--source/blender/editors/object/object_relations.c33
-rw-r--r--source/blender/editors/object/object_transform.c16
-rw-r--r--source/blender/editors/object/object_vgroup.c2
-rw-r--r--source/blender/editors/physics/particle_edit.c24
-rw-r--r--source/blender/editors/physics/physics_fluid.c15
-rw-r--r--source/blender/editors/physics/physics_ops.c4
-rw-r--r--source/blender/editors/physics/rigidbody_object.c106
-rw-r--r--source/blender/editors/physics/rigidbody_world.c2
-rw-r--r--source/blender/editors/render/SConscript2
-rw-r--r--source/blender/editors/render/render_internal.c35
-rw-r--r--source/blender/editors/render/render_opengl.c4
-rw-r--r--source/blender/editors/render/render_preview.c45
-rw-r--r--source/blender/editors/render/render_shading.c2
-rw-r--r--source/blender/editors/render/render_update.c2
-rw-r--r--source/blender/editors/render/render_view.c2
-rw-r--r--source/blender/editors/screen/area.c24
-rw-r--r--source/blender/editors/screen/glutil.c43
-rw-r--r--source/blender/editors/screen/screen_edit.c24
-rw-r--r--source/blender/editors/screen/screen_ops.c44
-rw-r--r--source/blender/editors/screen/screendump.c2
-rw-r--r--source/blender/editors/sculpt_paint/CMakeLists.txt6
-rw-r--r--source/blender/editors/sculpt_paint/SConscript5
-rw-r--r--source/blender/editors/sculpt_paint/paint_cursor.c60
-rw-r--r--source/blender/editors/sculpt_paint/paint_hide.c2
-rw-r--r--source/blender/editors/sculpt_paint/paint_image.c5392
-rw-r--r--source/blender/editors/sculpt_paint/paint_image_2d.c732
-rw-r--r--source/blender/editors/sculpt_paint/paint_image_proj.c4465
-rw-r--r--source/blender/editors/sculpt_paint/paint_intern.h47
-rw-r--r--source/blender/editors/sculpt_paint/paint_mask.c1
-rw-r--r--source/blender/editors/sculpt_paint/paint_ops.c28
-rw-r--r--source/blender/editors/sculpt_paint/paint_stroke.c288
-rw-r--r--source/blender/editors/sculpt_paint/paint_utils.c42
-rw-r--r--source/blender/editors/sculpt_paint/paint_vertex.c81
-rw-r--r--source/blender/editors/sculpt_paint/sculpt.c359
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_intern.h3
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_undo.c57
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_uv.c73
-rw-r--r--source/blender/editors/sound/sound_ops.c6
-rw-r--r--source/blender/editors/space_action/action_edit.c2
-rw-r--r--source/blender/editors/space_action/action_select.c9
-rw-r--r--source/blender/editors/space_buttons/buttons_ops.c15
-rw-r--r--source/blender/editors/space_buttons/buttons_texture.c2
-rw-r--r--source/blender/editors/space_clip/SConscript3
-rw-r--r--source/blender/editors/space_clip/clip_dopesheet_ops.c61
-rw-r--r--source/blender/editors/space_clip/clip_draw.c2
-rw-r--r--source/blender/editors/space_clip/clip_graph_ops.c2
-rw-r--r--source/blender/editors/space_clip/clip_intern.h3
-rw-r--r--source/blender/editors/space_clip/clip_ops.c272
-rw-r--r--source/blender/editors/space_clip/clip_toolbar.c8
-rw-r--r--source/blender/editors/space_clip/space_clip.c8
-rw-r--r--source/blender/editors/space_clip/tracking_ops.c28
-rw-r--r--source/blender/editors/space_clip/tracking_select.c16
-rw-r--r--source/blender/editors/space_console/console_draw.c42
-rw-r--r--source/blender/editors/space_console/console_ops.c8
-rw-r--r--source/blender/editors/space_console/space_console.c4
-rw-r--r--source/blender/editors/space_file/file_draw.c7
-rw-r--r--source/blender/editors/space_file/file_ops.c32
-rw-r--r--source/blender/editors/space_file/filelist.c38
-rw-r--r--source/blender/editors/space_file/filelist.h15
-rw-r--r--source/blender/editors/space_file/filesel.c18
-rw-r--r--source/blender/editors/space_file/fsmenu.c28
-rw-r--r--source/blender/editors/space_file/space_file.c33
-rw-r--r--source/blender/editors/space_graph/graph_edit.c15
-rw-r--r--source/blender/editors/space_graph/graph_ops.c6
-rw-r--r--source/blender/editors/space_graph/graph_select.c9
-rw-r--r--source/blender/editors/space_image/SConscript2
-rw-r--r--source/blender/editors/space_image/image_buttons.c63
-rw-r--r--source/blender/editors/space_image/image_draw.c8
-rw-r--r--source/blender/editors/space_image/image_ops.c52
-rw-r--r--source/blender/editors/space_image/space_image.c2
-rw-r--r--source/blender/editors/space_info/info_ops.c12
-rw-r--r--source/blender/editors/space_info/info_report.c2
-rw-r--r--source/blender/editors/space_info/info_stats.c56
-rw-r--r--source/blender/editors/space_info/textview.c119
-rw-r--r--source/blender/editors/space_logic/logic_ops.c37
-rw-r--r--source/blender/editors/space_nla/nla_buttons.c53
-rw-r--r--source/blender/editors/space_nla/nla_channels.c185
-rw-r--r--source/blender/editors/space_nla/nla_draw.c8
-rw-r--r--source/blender/editors/space_nla/nla_edit.c19
-rw-r--r--source/blender/editors/space_nla/nla_intern.h4
-rw-r--r--source/blender/editors/space_nla/nla_ops.c8
-rw-r--r--source/blender/editors/space_nla/nla_select.c6
-rw-r--r--source/blender/editors/space_node/drawnode.c85
-rw-r--r--source/blender/editors/space_node/node_add.c2
-rw-r--r--source/blender/editors/space_node/node_draw.c2
-rw-r--r--source/blender/editors/space_node/node_edit.c114
-rw-r--r--source/blender/editors/space_node/node_group.c6
-rw-r--r--source/blender/editors/space_node/node_intern.h2
-rw-r--r--source/blender/editors/space_node/node_ops.c4
-rw-r--r--source/blender/editors/space_node/node_relationships.c10
-rw-r--r--source/blender/editors/space_node/node_select.c4
-rw-r--r--source/blender/editors/space_node/node_view.c10
-rw-r--r--source/blender/editors/space_node/space_node.c2
-rw-r--r--source/blender/editors/space_outliner/outliner_draw.c302
-rw-r--r--source/blender/editors/space_outliner/outliner_edit.c44
-rw-r--r--source/blender/editors/space_outliner/outliner_intern.h9
-rw-r--r--source/blender/editors/space_outliner/outliner_ops.c18
-rw-r--r--source/blender/editors/space_outliner/outliner_select.c187
-rw-r--r--source/blender/editors/space_outliner/outliner_tools.c91
-rw-r--r--source/blender/editors/space_outliner/outliner_tree.c78
-rw-r--r--source/blender/editors/space_outliner/space_outliner.c12
-rw-r--r--source/blender/editors/space_sequencer/sequencer_add.c14
-rw-r--r--source/blender/editors/space_sequencer/sequencer_draw.c4
-rw-r--r--source/blender/editors/space_sequencer/sequencer_edit.c16
-rw-r--r--source/blender/editors/space_sequencer/sequencer_select.c8
-rw-r--r--source/blender/editors/space_sequencer/sequencer_view.c6
-rw-r--r--source/blender/editors/space_sequencer/space_sequencer.c6
-rw-r--r--source/blender/editors/space_text/space_text.c2
-rw-r--r--source/blender/editors/space_text/text_autocomplete.c6
-rw-r--r--source/blender/editors/space_text/text_draw.c223
-rw-r--r--source/blender/editors/space_text/text_format.c2
-rw-r--r--source/blender/editors/space_text/text_format_lua.c2
-rw-r--r--source/blender/editors/space_text/text_format_osl.c10
-rw-r--r--source/blender/editors/space_text/text_format_py.c2
-rw-r--r--source/blender/editors/space_text/text_ops.c141
-rw-r--r--source/blender/editors/space_view3d/CMakeLists.txt1
-rw-r--r--source/blender/editors/space_view3d/drawmesh.c8
-rw-r--r--source/blender/editors/space_view3d/drawobject.c29
-rw-r--r--source/blender/editors/space_view3d/space_view3d.c39
-rw-r--r--source/blender/editors/space_view3d/view3d_draw.c164
-rw-r--r--source/blender/editors/space_view3d/view3d_edit.c94
-rw-r--r--source/blender/editors/space_view3d/view3d_fly.c8
-rw-r--r--source/blender/editors/space_view3d/view3d_header.c18
-rw-r--r--source/blender/editors/space_view3d/view3d_intern.h3
-rw-r--r--source/blender/editors/space_view3d/view3d_ops.c1
-rw-r--r--source/blender/editors/space_view3d/view3d_project.c96
-rw-r--r--source/blender/editors/space_view3d/view3d_ruler.c939
-rw-r--r--source/blender/editors/space_view3d/view3d_select.c50
-rw-r--r--source/blender/editors/space_view3d/view3d_toolbar.c2
-rw-r--r--source/blender/editors/space_view3d/view3d_view.c41
-rw-r--r--source/blender/editors/transform/transform.c399
-rw-r--r--source/blender/editors/transform/transform.h23
-rw-r--r--source/blender/editors/transform/transform_constraints.c20
-rw-r--r--source/blender/editors/transform/transform_conversions.c22
-rw-r--r--source/blender/editors/transform/transform_generics.c16
-rw-r--r--source/blender/editors/transform/transform_input.c2
-rw-r--r--source/blender/editors/transform/transform_manipulator.c27
-rw-r--r--source/blender/editors/transform/transform_ops.c32
-rw-r--r--source/blender/editors/transform/transform_orientations.c12
-rw-r--r--source/blender/editors/transform/transform_snap.c121
-rw-r--r--source/blender/editors/util/ed_util.c3
-rw-r--r--source/blender/editors/util/editmode_undo.c8
-rw-r--r--source/blender/editors/util/numinput.c2
-rw-r--r--source/blender/editors/util/undo.c2
-rw-r--r--source/blender/editors/uvedit/uvedit_draw.c37
-rw-r--r--source/blender/editors/uvedit/uvedit_ops.c12
-rw-r--r--source/blender/editors/uvedit/uvedit_smart_stitch.c9
-rw-r--r--source/blender/editors/uvedit/uvedit_unwrap_ops.c4
-rw-r--r--source/blender/gpu/CMakeLists.txt7
-rw-r--r--source/blender/gpu/GPU_extensions.h26
-rw-r--r--source/blender/gpu/GPU_simple_shader.h89
-rw-r--r--source/blender/gpu/SConscript20
-rw-r--r--source/blender/gpu/intern/gpu_codegen.c2
-rw-r--r--source/blender/gpu/intern/gpu_draw.c38
-rw-r--r--source/blender/gpu/intern/gpu_extensions.c40
-rw-r--r--source/blender/gpu/intern/gpu_fixed_material.c191
-rw-r--r--source/blender/gpu/intern/gpu_material.c2
-rw-r--r--source/blender/gpu/intern/gpu_simple_shader.c283
-rw-r--r--source/blender/gpu/shaders/gpu_shader_material.glsl2
-rw-r--r--source/blender/gpu/shaders/gpu_shader_simple_frag.glsl (renamed from source/blender/gpu/shaders/gpu_shader_fixed_fragment.glsl)0
-rw-r--r--source/blender/gpu/shaders/gpu_shader_simple_vert.glsl (renamed from source/blender/gpu/shaders/gpu_shader_fixed_vertex.glsl)8
-rw-r--r--source/blender/gpu/shaders/gpu_shader_vertex.glsl8
-rw-r--r--source/blender/ikplugin/intern/iksolver_plugin.c4
-rw-r--r--source/blender/imbuf/IMB_imbuf.h6
-rw-r--r--source/blender/imbuf/IMB_imbuf_types.h1
-rw-r--r--source/blender/imbuf/SConscript6
-rw-r--r--source/blender/imbuf/intern/IMB_colormanagement_intern.h11
-rw-r--r--source/blender/imbuf/intern/IMB_indexer.h3
-rw-r--r--source/blender/imbuf/intern/anim_movie.c10
-rw-r--r--source/blender/imbuf/intern/bmp.c12
-rw-r--r--source/blender/imbuf/intern/cineon/cineon_dpx.c23
-rw-r--r--source/blender/imbuf/intern/cineon/cineonlib.c10
-rw-r--r--source/blender/imbuf/intern/cineon/dpxlib.c29
-rw-r--r--source/blender/imbuf/intern/cineon/logImageCore.c2
-rw-r--r--source/blender/imbuf/intern/colormanagement.c11
-rw-r--r--source/blender/imbuf/intern/dds/BlockDXT.cpp4
-rw-r--r--source/blender/imbuf/intern/dds/DirectDrawSurface.cpp8
-rw-r--r--source/blender/imbuf/intern/dds/FlipDXT.cpp2
-rw-r--r--source/blender/imbuf/intern/indexer.c17
-rw-r--r--source/blender/imbuf/intern/iris.c1
-rw-r--r--source/blender/imbuf/intern/jpeg.c3
-rw-r--r--source/blender/imbuf/intern/moviecache.c6
-rw-r--r--source/blender/imbuf/intern/openexr/openexr_api.cpp12
-rw-r--r--source/blender/imbuf/intern/png.c1
-rw-r--r--source/blender/imbuf/intern/radiance_hdr.c5
-rw-r--r--source/blender/imbuf/intern/readimage.c3
-rw-r--r--source/blender/imbuf/intern/rectop.c97
-rw-r--r--source/blender/imbuf/intern/scaling.c111
-rw-r--r--source/blender/imbuf/intern/targa.c95
-rw-r--r--source/blender/imbuf/intern/thumbs.c5
-rw-r--r--source/blender/imbuf/intern/util.c2
-rw-r--r--source/blender/makesdna/DNA_brush_types.h5
-rw-r--r--source/blender/makesdna/DNA_genfile.h2
-rw-r--r--source/blender/makesdna/DNA_modifier_types.h2
-rw-r--r--source/blender/makesdna/DNA_node_types.h6
-rw-r--r--source/blender/makesdna/DNA_scene_types.h14
-rw-r--r--source/blender/makesdna/DNA_texture_types.h2
-rw-r--r--source/blender/makesdna/DNA_userdef_types.h5
-rw-r--r--source/blender/makesdna/DNA_view3d_types.h5
-rw-r--r--source/blender/makesdna/intern/dna_genfile.c16
-rw-r--r--source/blender/makesdna/intern/makesdna.c8
-rw-r--r--source/blender/makesrna/RNA_access.h123
-rw-r--r--source/blender/makesrna/RNA_types.h4
-rw-r--r--source/blender/makesrna/intern/makesrna.c9
-rw-r--r--source/blender/makesrna/intern/rna_ID.c17
-rw-r--r--source/blender/makesrna/intern/rna_access.c335
-rw-r--r--source/blender/makesrna/intern/rna_action.c13
-rw-r--r--source/blender/makesrna/intern/rna_actuator.c15
-rw-r--r--source/blender/makesrna/intern/rna_animation.c15
-rw-r--r--source/blender/makesrna/intern/rna_animviz.c7
-rw-r--r--source/blender/makesrna/intern/rna_armature.c4
-rw-r--r--source/blender/makesrna/intern/rna_boid.c11
-rw-r--r--source/blender/makesrna/intern/rna_brush.c152
-rw-r--r--source/blender/makesrna/intern/rna_camera.c15
-rw-r--r--source/blender/makesrna/intern/rna_cloth.c9
-rw-r--r--source/blender/makesrna/intern/rna_color.c20
-rw-r--r--source/blender/makesrna/intern/rna_constraint.c88
-rw-r--r--source/blender/makesrna/intern/rna_context.c6
-rw-r--r--source/blender/makesrna/intern/rna_controller.c11
-rw-r--r--source/blender/makesrna/intern/rna_curve.c10
-rw-r--r--source/blender/makesrna/intern/rna_dynamicpaint.c9
-rw-r--r--source/blender/makesrna/intern/rna_fcurve.c13
-rw-r--r--source/blender/makesrna/intern/rna_fluidsim.c1
-rw-r--r--source/blender/makesrna/intern/rna_gpencil.c17
-rw-r--r--source/blender/makesrna/intern/rna_group.c7
-rw-r--r--source/blender/makesrna/intern/rna_image.c14
-rw-r--r--source/blender/makesrna/intern/rna_image_api.c8
-rw-r--r--source/blender/makesrna/intern/rna_internal.h11
-rw-r--r--source/blender/makesrna/intern/rna_internal_types.h2
-rw-r--r--source/blender/makesrna/intern/rna_key.c13
-rw-r--r--source/blender/makesrna/intern/rna_lamp.c9
-rw-r--r--source/blender/makesrna/intern/rna_lattice.c12
-rw-r--r--source/blender/makesrna/intern/rna_main.c1
-rw-r--r--source/blender/makesrna/intern/rna_main_api.c2
-rw-r--r--source/blender/makesrna/intern/rna_mask.c8
-rw-r--r--source/blender/makesrna/intern/rna_material.c7
-rw-r--r--source/blender/makesrna/intern/rna_mesh.c19
-rw-r--r--source/blender/makesrna/intern/rna_meta.c9
-rw-r--r--source/blender/makesrna/intern/rna_modifier.c24
-rw-r--r--source/blender/makesrna/intern/rna_movieclip.c7
-rw-r--r--source/blender/makesrna/intern/rna_nla.c13
-rw-r--r--source/blender/makesrna/intern/rna_nodetree.c70
-rw-r--r--source/blender/makesrna/intern/rna_object.c13
-rw-r--r--source/blender/makesrna/intern/rna_object_force.c11
-rw-r--r--source/blender/makesrna/intern/rna_packedfile.c7
-rw-r--r--source/blender/makesrna/intern/rna_particle.c11
-rw-r--r--source/blender/makesrna/intern/rna_pose.c6
-rw-r--r--source/blender/makesrna/intern/rna_render.c21
-rw-r--r--source/blender/makesrna/intern/rna_rna.c5
-rw-r--r--source/blender/makesrna/intern/rna_scene.c13
-rw-r--r--source/blender/makesrna/intern/rna_scene_api.c8
-rw-r--r--source/blender/makesrna/intern/rna_sculpt_paint.c7
-rw-r--r--source/blender/makesrna/intern/rna_sensor.c11
-rw-r--r--source/blender/makesrna/intern/rna_sensor_api.c6
-rw-r--r--source/blender/makesrna/intern/rna_sequencer.c13
-rw-r--r--source/blender/makesrna/intern/rna_sequencer_api.c10
-rw-r--r--source/blender/makesrna/intern/rna_space.c13
-rw-r--r--source/blender/makesrna/intern/rna_text_api.c3
-rw-r--r--source/blender/makesrna/intern/rna_texture.c16
-rw-r--r--source/blender/makesrna/intern/rna_texture_api.c1
-rw-r--r--source/blender/makesrna/intern/rna_timeline.c5
-rw-r--r--source/blender/makesrna/intern/rna_tracking.c1
-rw-r--r--source/blender/makesrna/intern/rna_ui.c21
-rw-r--r--source/blender/makesrna/intern/rna_ui_api.c2
-rw-r--r--source/blender/makesrna/intern/rna_userdef.c38
-rw-r--r--source/blender/makesrna/intern/rna_wm.c73
-rw-r--r--source/blender/makesrna/intern/rna_wm_api.c14
-rw-r--r--source/blender/modifiers/intern/MOD_array.c2
-rw-r--r--source/blender/modifiers/intern/MOD_bevel.c3
-rw-r--r--source/blender/modifiers/intern/MOD_build.c2
-rw-r--r--source/blender/modifiers/intern/MOD_cloth.c1
-rw-r--r--source/blender/modifiers/intern/MOD_laplaciansmooth.c5
-rw-r--r--source/blender/modifiers/intern/MOD_mask.c6
-rw-r--r--source/blender/modifiers/intern/MOD_meshcache_pc2.c2
-rw-r--r--source/blender/modifiers/intern/MOD_particleinstance.c4
-rw-r--r--source/blender/modifiers/intern/MOD_skin.c2
-rw-r--r--source/blender/modifiers/intern/MOD_solidify.c60
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_outputFile.c13
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_trackpos.c4
-rw-r--r--source/blender/python/bmesh/bmesh_py_ops.c2
-rw-r--r--source/blender/python/bmesh/bmesh_py_ops_call.c2
-rw-r--r--source/blender/python/bmesh/bmesh_py_types.h2
-rw-r--r--source/blender/python/bmesh/bmesh_py_types_meshdata.h3
-rw-r--r--source/blender/python/generic/idprop_py_api.c4
-rw-r--r--source/blender/python/generic/py_capi_utils.c4
-rw-r--r--source/blender/python/intern/bpy.c38
-rw-r--r--source/blender/python/intern/bpy_app.c3
-rw-r--r--source/blender/python/intern/bpy_app_translations.c2
-rw-r--r--source/blender/python/intern/bpy_interface.c8
-rw-r--r--source/blender/python/intern/bpy_library.c2
-rw-r--r--source/blender/python/intern/bpy_operator.c2
-rw-r--r--source/blender/python/intern/bpy_operator_wrap.c10
-rw-r--r--source/blender/python/intern/bpy_props.c8
-rw-r--r--source/blender/python/intern/bpy_rna.c18
-rw-r--r--source/blender/python/intern/bpy_traceback.c1
-rw-r--r--source/blender/python/mathutils/mathutils_Matrix.c10
-rw-r--r--source/blender/quicktime/apple/qtkit_import.m1
-rw-r--r--source/blender/quicktime/apple/quicktime_export.c4
-rw-r--r--source/blender/quicktime/apple/quicktime_import.c10
-rw-r--r--source/blender/render/CMakeLists.txt4
-rw-r--r--source/blender/render/SConscript3
-rw-r--r--source/blender/render/extern/include/RE_engine.h3
-rw-r--r--source/blender/render/intern/raytrace/rayobject.cpp2
-rw-r--r--source/blender/render/intern/raytrace/rayobject_rtbuild.cpp10
-rw-r--r--source/blender/render/intern/source/bake.c2
-rw-r--r--source/blender/render/intern/source/convertblender.c20
-rw-r--r--source/blender/render/intern/source/envmap.c4
-rw-r--r--source/blender/render/intern/source/external_engine.c5
-rw-r--r--source/blender/render/intern/source/imagetexture.c36
-rw-r--r--source/blender/render/intern/source/occlusion.c4
-rw-r--r--source/blender/render/intern/source/pipeline.c72
-rw-r--r--source/blender/render/intern/source/pointdensity.c6
-rw-r--r--source/blender/render/intern/source/rayshade.c10
-rw-r--r--source/blender/render/intern/source/render_result.c8
-rw-r--r--source/blender/render/intern/source/sss.c6
-rw-r--r--source/blender/render/intern/source/volume_precache.c22
-rw-r--r--source/blender/render/intern/source/voxeldata.c8
-rw-r--r--source/blender/windowmanager/WM_api.h42
-rw-r--r--source/blender/windowmanager/WM_types.h7
-rw-r--r--source/blender/windowmanager/intern/wm.c4
-rw-r--r--source/blender/windowmanager/intern/wm_dragdrop.c4
-rw-r--r--source/blender/windowmanager/intern/wm_event_system.c21
-rw-r--r--source/blender/windowmanager/intern/wm_files.c11
-rw-r--r--source/blender/windowmanager/intern/wm_gesture.c2
-rw-r--r--source/blender/windowmanager/intern/wm_init_exit.c1
-rw-r--r--source/blender/windowmanager/intern/wm_jobs.c4
-rw-r--r--source/blender/windowmanager/intern/wm_keymap.c2
-rw-r--r--source/blender/windowmanager/intern/wm_operators.c100
-rw-r--r--source/blender/windowmanager/intern/wm_playanim.c186
-rw-r--r--source/blender/windowmanager/intern/wm_subwindow.c6
-rw-r--r--source/blender/windowmanager/intern/wm_window.c29
-rw-r--r--source/blender/windowmanager/wm_event_types.h2
-rw-r--r--source/blender/windowmanager/wm_window.h1
-rw-r--r--source/blenderplayer/CMakeLists.txt1
-rw-r--r--source/blenderplayer/bad_level_call_stubs/stubs.c7
-rw-r--r--source/creator/CMakeLists.txt1
-rw-r--r--source/gameengine/BlenderRoutines/KX_BlenderGL.cpp2
-rw-r--r--source/gameengine/BlenderRoutines/KX_BlenderInputDevice.h2
-rw-r--r--source/gameengine/Expressions/Value.h8
-rw-r--r--source/gameengine/GameLogic/SCA_IActuator.h2
-rw-r--r--source/gameengine/GamePlayer/common/GPC_Canvas.h4
-rw-r--r--source/gameengine/GamePlayer/ghost/GPG_ghost.cpp1
-rw-r--r--source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp4
-rw-r--r--source/gameengine/Ketsji/KX_GameObject.cpp4
-rw-r--r--source/gameengine/Ketsji/KX_PythonInit.cpp2
-rw-r--r--source/gameengine/Network/NG_NetworkScene.h2
-rw-r--r--source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp14
-rw-r--r--source/gameengine/Rasterizer/RAS_2DFilterManager.cpp6
-rw-r--r--source/tests/bl_pyapi_mathutils.py2
-rw-r--r--source/tests/bl_run_operators.py4
639 files changed, 17751 insertions, 12131 deletions
diff --git a/source/blender/avi/intern/avi.c b/source/blender/avi/intern/avi.c
index fcc9526b58a..1b1ec1c08af 100644
--- a/source/blender/avi/intern/avi.c
+++ b/source/blender/avi/intern/avi.c
@@ -38,12 +38,15 @@
#include <stdio.h>
#include <ctype.h>
+#ifdef WIN32
+#include "BLI_winstuff.h"
+#endif
+
#include "MEM_guardedalloc.h"
#include "MEM_sys_types.h"
-#ifdef WIN32
-# include "BLI_winstuff.h"
-#endif
+#include "BLI_utildefines.h"
+#include "BLI_fileops.h"
#include "AVI_avi.h"
#include "avi_intern.h"
@@ -208,7 +211,7 @@ int AVI_is_avi(char *name)
FILE *fp;
int ret;
- fp = fopen(name, "rb");
+ fp = BLI_fopen(name, "rb");
if (fp == NULL)
return 0;
@@ -238,7 +241,7 @@ int AVI_is_avi(const char *name)
DEBUG_PRINT("opening movie\n");
movie.type = AVI_MOVIE_READ;
- movie.fp = fopen(name, "rb");
+ movie.fp = BLI_fopen(name, "rb");
movie.offset_table = NULL;
if (movie.fp == NULL)
@@ -404,7 +407,9 @@ int AVI_is_avi(const char *name)
}
if (j > 0) fseek(movie.fp, j, SEEK_CUR);
}
- else fseek(movie.fp, movie.streams[temp].sf_size, SEEK_CUR);
+ else {
+ fseek(movie.fp, movie.streams[temp].sf_size, SEEK_CUR);
+ }
/* Walk to the next LIST */
while (GET_FCC(movie.fp) != FCC("LIST")) {
@@ -439,7 +444,7 @@ AviError AVI_open_movie(const char *name, AviMovie *movie)
memset(movie, 0, sizeof(AviMovie));
movie->type = AVI_MOVIE_READ;
- movie->fp = fopen(name, "rb");
+ movie->fp = BLI_fopen(name, "rb");
movie->offset_table = NULL;
if (movie->fp == NULL)
@@ -595,8 +600,10 @@ AviError AVI_open_movie(const char *name, AviMovie *movie)
}
if (j > 0) fseek(movie->fp, j, SEEK_CUR);
}
- else fseek(movie->fp, movie->streams[temp].sf_size, SEEK_CUR);
-
+ else {
+ fseek(movie->fp, movie->streams[temp].sf_size, SEEK_CUR);
+ }
+
/* Walk to the next LIST */
while (GET_FCC(movie->fp) != FCC("LIST")) {
temp = GET_FCC(movie->fp);
@@ -761,7 +768,7 @@ AviError AVI_open_compress(char *name, AviMovie *movie, int streams, ...)
int64_t junk_pos;
movie->type = AVI_MOVIE_WRITE;
- movie->fp = fopen(name, "wb");
+ movie->fp = BLI_fopen(name, "wb");
movie->index_entries = 0;
diff --git a/source/blender/blenfont/BLF_api.h b/source/blender/blenfont/BLF_api.h
index 0ca97975d87..fd8bd196717 100644
--- a/source/blender/blenfont/BLF_api.h
+++ b/source/blender/blenfont/BLF_api.h
@@ -77,6 +77,7 @@ void BLF_draw_default_ascii(float x, float y, float z, const char *str, size_t l
/* Draw the string using the current font. */
void BLF_draw(int fontid, const char *str, size_t len);
void BLF_draw_ascii(int fontid, const char *str, size_t len);
+int BLF_draw_mono(int fontid, const char *str, size_t len, int cwidth);
/* This function return the bounding box of the string
* and are not multiplied by the aspect.
diff --git a/source/blender/blenfont/BLF_translation.h b/source/blender/blenfont/BLF_translation.h
index 197809426ae..c8d46503e26 100644
--- a/source/blender/blenfont/BLF_translation.h
+++ b/source/blender/blenfont/BLF_translation.h
@@ -68,6 +68,8 @@ struct EnumPropertyItem *BLF_RNA_lang_enum_properties(void);
unsigned char *BLF_get_unifont(int *unifont_size);
void BLF_free_unifont(void);
+unsigned char *BLF_get_unifont_mono(int *unifont_size);
+void BLF_free_unifont_mono(void);
const char *BLF_pgettext(const char *msgctxt, const char *msgid);
@@ -108,12 +110,14 @@ const char *BLF_translate_do_tooltip(const char *msgctxt, const char *msgid);
* All i18n contexts must be defined here.
* This is a nice way to be sure not to use a context twice for different
* things, and limit the number of existing contexts!
+ * WARNING! Contexts should not be longer than BKE_ST_MAXNAME - 1!
*/
/* Default, void context.
* WARNING! The "" context is not the same as no (NULL) context at mo/boost::locale level!
* NOTE: We translate BLF_I18NCONTEXT_DEFAULT as BLF_I18NCONTEXT_DEFAULT_BPY in Python, as we can't use "natural"
* None value in rna string properties... :/
+ * The void string "" is also interpreted as BLF_I18NCONTEXT_DEFAULT.
* For perf reason, we only use the first char to detect this context, so other contexts should never start
* with the same char!
*/
diff --git a/source/blender/blenfont/intern/blf.c b/source/blender/blenfont/intern/blf.c
index 061e8e28607..e7e277b7b34 100644
--- a/source/blender/blenfont/intern/blf.c
+++ b/source/blender/blenfont/intern/blf.c
@@ -576,6 +576,21 @@ void BLF_draw_ascii(int fontid, const char *str, size_t len)
}
}
+int BLF_draw_mono(int fontid, const char *str, size_t len, int cwidth)
+{
+ FontBLF *font = blf_get(fontid);
+ GLint mode, param;
+ int columns = 0;
+
+ if (font && font->glyph_cache) {
+ blf_draw__start(font, &mode, &param);
+ columns = blf_font_draw_mono(font, str, len, cwidth);
+ blf_draw__end(mode, param);
+ }
+
+ return columns;
+}
+
void BLF_boundbox(int fontid, const char *str, rctf *box)
{
FontBLF *font = blf_get(fontid);
diff --git a/source/blender/blenfont/intern/blf_dir.c b/source/blender/blenfont/intern/blf_dir.c
index b6a98faa48c..116a55c0579 100644
--- a/source/blender/blenfont/intern/blf_dir.c
+++ b/source/blender/blenfont/intern/blf_dir.c
@@ -41,6 +41,7 @@
#include "DNA_vec_types.h"
+#include "BLI_utildefines.h"
#include "BLI_fileops.h"
#include "BLI_listbase.h"
#include "BLI_path_util.h"
diff --git a/source/blender/blenfont/intern/blf_font.c b/source/blender/blenfont/intern/blf_font.c
index 1900efa2dbc..f2c36475870 100644
--- a/source/blender/blenfont/intern/blf_font.c
+++ b/source/blender/blenfont/intern/blf_font.c
@@ -219,6 +219,40 @@ void blf_font_draw_ascii(FontBLF *font, const char *str, size_t len)
}
}
+/* use fixed column width, but an utf8 character may occupy multiple columns */
+int blf_font_draw_mono(FontBLF *font, const char *str, size_t len, int cwidth)
+{
+ unsigned int c;
+ GlyphBLF *g;
+ int col, columns = 0;
+ int pen_x = 0, pen_y = 0;
+ size_t i = 0;
+ GlyphBLF **glyph_ascii_table = font->glyph_cache->glyph_ascii_table;
+
+ blf_font_ensure_ascii_table(font);
+
+ while ((i < len) && str[i]) {
+ BLF_UTF8_NEXT_FAST(font, g, str, i, c, glyph_ascii_table);
+
+ if (c == BLI_UTF8_ERR)
+ break;
+ if (g == NULL)
+ continue;
+
+ /* do not return this loop if clipped, we want every character tested */
+ blf_glyph_render(font, g, (float)pen_x, (float)pen_y);
+
+ col = BLI_wcwidth((wchar_t)c);
+ if (col < 0)
+ col = 1;
+
+ columns += col;
+ pen_x += cwidth * col;
+ }
+
+ return columns;
+}
+
/* Sanity checks are done by BLF_draw_buffer() */
void blf_font_buffer(FontBLF *font, const char *str)
{
diff --git a/source/blender/blenfont/intern/blf_internal.h b/source/blender/blenfont/intern/blf_internal.h
index 65a54783978..b1301be46fd 100644
--- a/source/blender/blenfont/intern/blf_internal.h
+++ b/source/blender/blenfont/intern/blf_internal.h
@@ -53,6 +53,7 @@ void blf_font_attach_from_mem(struct FontBLF *font, const unsigned char *mem, in
void blf_font_size(struct FontBLF *font, int size, int dpi);
void blf_font_draw(struct FontBLF *font, const char *str, size_t len);
void blf_font_draw_ascii(struct FontBLF *font, const char *str, size_t len);
+int blf_font_draw_mono(struct FontBLF *font, const char *str, size_t len, int cwidth);
void blf_font_buffer(struct FontBLF *font, const char *str);
void blf_font_boundbox(struct FontBLF *font, const char *str, struct rctf *box);
void blf_font_width_and_height(struct FontBLF *font, const char *str, float *width, float *height);
diff --git a/source/blender/blenfont/intern/blf_lang.c b/source/blender/blenfont/intern/blf_lang.c
index 73294f1aed6..d1c037b0358 100644
--- a/source/blender/blenfont/intern/blf_lang.c
+++ b/source/blender/blenfont/intern/blf_lang.c
@@ -78,15 +78,16 @@ static void free_locales(void)
static void fill_locales(void)
{
- char *languages_path = BLI_get_folder(BLENDER_DATAFILES, "locale");
+ const char * const languages_path = BLI_get_folder(BLENDER_DATAFILES, "locale");
+ char languages[FILE_MAX];
LinkNode *lines = NULL, *line;
char *str;
int idx = 0;
free_locales();
- BLI_join_dirfile(languages_path, FILE_MAX, languages_path, "languages");
- line = lines = BLI_file_read_as_lines(languages_path);
+ BLI_join_dirfile(languages, FILE_MAX, languages_path, "languages");
+ line = lines = BLI_file_read_as_lines(languages);
/* This whole "parsing" code is a bit weak, in that it expects strictly formated input file...
* Should not be a problem, though, as this file is script-generated! */
@@ -185,7 +186,7 @@ EnumPropertyItem *BLF_RNA_lang_enum_properties(void)
void BLF_lang_init(void)
{
#ifdef WITH_INTERNATIONAL
- char *messagepath = BLI_get_folder(BLENDER_DATAFILES, "locale");
+ const char * const messagepath = BLI_get_folder(BLENDER_DATAFILES, "locale");
if (messagepath) {
bl_locale_init(messagepath, TEXT_DOMAIN_NAME);
diff --git a/source/blender/blenfont/intern/blf_translation.c b/source/blender/blenfont/intern/blf_translation.c
index b5b72b68677..4e9408c512a 100644
--- a/source/blender/blenfont/intern/blf_translation.c
+++ b/source/blender/blenfont/intern/blf_translation.c
@@ -50,13 +50,16 @@
static const char unifont_filename[] = "droidsans.ttf.gz";
static unsigned char *unifont_ttf = NULL;
static int unifont_size = 0;
+static const char unifont_mono_filename[] = "bmonofont-i18n.ttf.gz";
+static unsigned char *unifont_mono_ttf = NULL;
+static int unifont_mono_size = 0;
#endif /* WITH_INTERNATIONAL */
unsigned char *BLF_get_unifont(int *unifont_size_r)
{
#ifdef WITH_INTERNATIONAL
if (unifont_ttf == NULL) {
- char *fontpath = BLI_get_folder(BLENDER_DATAFILES, "fonts");
+ const char * const fontpath = BLI_get_folder(BLENDER_DATAFILES, "fonts");
if (fontpath) {
char unifont_path[1024];
@@ -87,14 +90,49 @@ void BLF_free_unifont(void)
#endif
}
+unsigned char *BLF_get_unifont_mono(int *unifont_size_r)
+{
+#ifdef WITH_INTERNATIONAL
+ if (unifont_mono_ttf == NULL) {
+ const char *fontpath = BLI_get_folder(BLENDER_DATAFILES, "fonts");
+ if (fontpath) {
+ char unifont_path[1024];
+
+ BLI_snprintf(unifont_path, sizeof(unifont_path), "%s/%s", fontpath, unifont_mono_filename);
+
+ unifont_mono_ttf = (unsigned char *)BLI_file_ungzip_to_mem(unifont_path, &unifont_mono_size);
+ }
+ else {
+ printf("%s: 'fonts' data path not found for international monospace font, continuing\n", __func__);
+ }
+ }
+
+ *unifont_size_r = unifont_mono_size;
+
+ return unifont_mono_ttf;
+#else
+ (void)unifont_size_r;
+ return NULL;
+#endif
+}
+
+void BLF_free_unifont_mono(void)
+{
+#ifdef WITH_INTERNATIONAL
+ if (unifont_mono_ttf)
+ MEM_freeN(unifont_mono_ttf);
+#else
+#endif
+}
+
const char *BLF_pgettext(const char *msgctxt, const char *msgid)
{
#ifdef WITH_INTERNATIONAL
- if (msgid && msgid[0]) {
- const char *ret;
+ const char *ret = msgid;
+ if (msgid && msgid[0]) {
/*if (msgctxt && !strcmp(msgctxt, BLF_I18NCONTEXT_DEFAULT_BPY_INTERN)) { */
- if (msgctxt && msgctxt[0] == BLF_I18NCONTEXT_DEFAULT_BPY[0]) {
+ if (msgctxt && (!msgctxt[0] || msgctxt[0] == BLF_I18NCONTEXT_DEFAULT_BPY[0])) {
/* BLF_I18NCONTEXT_DEFAULT_BPY context is reserved and considered the same as default NULL one. */
msgctxt = BLF_I18NCONTEXT_DEFAULT;
}
@@ -105,10 +143,9 @@ const char *BLF_pgettext(const char *msgctxt, const char *msgid)
if (ret == msgid) {
ret = BPY_app_translations_py_pgettext(msgctxt, msgid);
}
-
- return ret;
}
- return "";
+
+ return ret;
#else
(void)msgctxt;
return msgid;
diff --git a/source/blender/blenkernel/BKE_DerivedMesh.h b/source/blender/blenkernel/BKE_DerivedMesh.h
index 486834f9540..51c46bcc235 100644
--- a/source/blender/blenkernel/BKE_DerivedMesh.h
+++ b/source/blender/blenkernel/BKE_DerivedMesh.h
@@ -608,7 +608,7 @@ void DM_interp_poly_data(struct DerivedMesh *source, struct DerivedMesh *dest,
float *weights, int count, int dest_index);
/* Temporary? A function to give a colorband to derivedmesh for vertexcolor ranges */
-void vDM_ColorBand_store(struct ColorBand *coba);
+void vDM_ColorBand_store(const struct ColorBand *coba, const char alert_color[4]);
/** Simple function to get me->totvert amount of vertices/normals,
* correctly deformed and subsurfered. Needed especially when vertexgroups are involved.
diff --git a/source/blender/blenkernel/BKE_animsys.h b/source/blender/blenkernel/BKE_animsys.h
index e648523aec3..dd150ba6a63 100644
--- a/source/blender/blenkernel/BKE_animsys.h
+++ b/source/blender/blenkernel/BKE_animsys.h
@@ -63,10 +63,10 @@ short BKE_animdata_set_action(struct ReportList *reports, struct ID *id, struct
void BKE_free_animdata(struct ID *id);
/* Copy AnimData */
-struct AnimData *BKE_copy_animdata(struct AnimData *adt, const short do_action);
+struct AnimData *BKE_copy_animdata(struct AnimData *adt, const bool do_action);
/* Copy AnimData */
-int BKE_copy_animdata_id(struct ID *id_to, struct ID *id_from, const short do_action);
+int BKE_copy_animdata_id(struct ID *id_to, struct ID *id_from, const bool do_action);
/* Copy AnimData Actions */
void BKE_copy_animdata_id_action(struct ID *id);
diff --git a/source/blender/blenkernel/BKE_blender.h b/source/blender/blenkernel/BKE_blender.h
index d66909449e4..d3671516248 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 266
-#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
@@ -50,7 +50,7 @@ extern "C" {
/* used by packaging tools */
/* can be left blank, otherwise a,b,c... etc with no quotes */
-#define BLENDER_VERSION_CHAR
+#define BLENDER_VERSION_CHAR a
/* alpha/beta/rc/release, docs use this */
#define BLENDER_VERSION_CYCLE alpha
diff --git a/source/blender/blenkernel/BKE_brush.h b/source/blender/blenkernel/BKE_brush.h
index cfae15961d7..3a4684257f6 100644
--- a/source/blender/blenkernel/BKE_brush.h
+++ b/source/blender/blenkernel/BKE_brush.h
@@ -69,24 +69,13 @@ float BKE_brush_curve_strength_clamp(struct Brush *br, float p, const float len)
float BKE_brush_curve_strength(struct Brush *br, float p, const float len); /* used for sculpt */
/* sampling */
-void BKE_brush_sample_tex(const struct Scene *scene, struct Brush *brush, const float sampleco[3], float rgba[4], const int thread, struct ImagePool *pool);
-void BKE_brush_sample_tex_2D(const struct Scene *scene, struct Brush *brush, const float xy[2], float rgba[4], const int thread);
+float BKE_brush_sample_tex_3D(const Scene *scene, struct Brush *br, const float point[3],
+ float rgba[4], const int thread, struct ImagePool *pool);
+float BKE_brush_sample_tex_2D(const struct Scene *scene, struct Brush *brush, const float xy[2],
+ float rgba[4], struct ImagePool *pool);
void BKE_brush_imbuf_new(const struct Scene *scene, struct Brush *brush, short flt, short texfalloff, int size,
struct ImBuf **imbuf, int use_color_correction);
-/* painting */
-struct BrushPainter;
-typedef struct BrushPainter BrushPainter;
-typedef int (*BrushFunc)(void *user, struct ImBuf *ibuf, const float lastpos[2], const float pos[2]);
-
-BrushPainter *BKE_brush_painter_new(struct Scene *scene, struct Brush *brush);
-void BKE_brush_painter_require_imbuf(BrushPainter *painter, short flt,
- short texonly, int size);
-int BKE_brush_painter_paint(BrushPainter *painter, BrushFunc func, const float pos[2],
- double time, float pressure, void *user, int use_color_correction);
-void BKE_brush_painter_break_stroke(BrushPainter *painter);
-void BKE_brush_painter_free(BrushPainter *painter);
-
/* texture */
unsigned int *BKE_brush_gen_texture_cache(struct Brush *br, int half_side);
diff --git a/source/blender/blenkernel/BKE_ccg.h b/source/blender/blenkernel/BKE_ccg.h
index 6d39d42bde5..fb6211504ae 100644
--- a/source/blender/blenkernel/BKE_ccg.h
+++ b/source/blender/blenkernel/BKE_ccg.h
@@ -126,7 +126,7 @@ BLI_INLINE CCGElem *CCG_elem_offset(const CCGKey *key, CCGElem *elem, int offset
BLI_INLINE CCGElem *CCG_grid_elem(const CCGKey *key, CCGElem *elem, int x, int y)
{
- BLI_assert(x < key->grid_size && y < key->grid_size);
+// BLI_assert(x < key->grid_size && y < key->grid_size);
return CCG_elem_offset(key, elem, (y * key->grid_size + x));
}
diff --git a/source/blender/blenkernel/BKE_curve.h b/source/blender/blenkernel/BKE_curve.h
index 358f884f74e..88d9cbb9b35 100644
--- a/source/blender/blenkernel/BKE_curve.h
+++ b/source/blender/blenkernel/BKE_curve.h
@@ -38,7 +38,6 @@ struct BezTriple;
struct Curve;
struct EditNurb;
struct ListBase;
-struct ListBase;
struct Main;
struct Nurb;
struct Object;
@@ -66,9 +65,9 @@ void BKE_curve_type_test(struct Object *ob);
void BKE_curve_curve_dimension_update(struct Curve *cu);
void BKE_curve_texspace_calc(struct Curve *cu);
-int BKE_curve_minmax(struct Curve *cu, float min[3], float max[3]);
-int BKE_curve_center_median(struct Curve *cu, float cent[3]);
-int BKE_curve_center_bounds(struct Curve *cu, float cent[3]);
+bool BKE_curve_minmax(struct Curve *cu, float min[3], float max[3]);
+bool BKE_curve_center_median(struct Curve *cu, float cent[3]);
+bool BKE_curve_center_bounds(struct Curve *cu, float cent[3]);
void BKE_curve_translate(struct Curve *cu, float offset[3], int do_keys);
void BKE_curve_delete_material_index(struct Curve *cu, int index);
@@ -118,11 +117,11 @@ void BKE_nurb_knot_calc_u(struct Nurb *nu);
void BKE_nurb_knot_calc_v(struct Nurb *nu);
/* nurb checks if they can be drawn, also clamp order func */
-int BKE_nurb_check_valid_u(struct Nurb *nu);
-int BKE_nurb_check_valid_v(struct Nurb *nu);
+bool BKE_nurb_check_valid_u(struct Nurb *nu);
+bool BKE_nurb_check_valid_v(struct Nurb *nu);
-int BKE_nurb_order_clamp_u(struct Nurb *nu);
-int BKE_nurb_order_clamp_v(struct Nurb *nu);
+bool BKE_nurb_order_clamp_u(struct Nurb *nu);
+bool BKE_nurb_order_clamp_v(struct Nurb *nu);
void BKE_nurb_direction_switch(struct Nurb *nu);
@@ -135,4 +134,4 @@ void BKE_nurb_handles_calc(struct Nurb *nu);
void BKE_nurb_handles_autocalc(struct Nurb *nu, int flag);
void BKE_nurb_handles_test(struct Nurb *nu);
-#endif
+#endif /* __BKE_CURVE_H__ */
diff --git a/source/blender/blenkernel/BKE_font.h b/source/blender/blenkernel/BKE_font.h
index cd52dd75f26..028ff0f93d6 100644
--- a/source/blender/blenkernel/BKE_font.h
+++ b/source/blender/blenkernel/BKE_font.h
@@ -71,7 +71,7 @@ typedef struct EditFont {
} EditFont;
-int BKE_vfont_is_builtin(struct VFont *vfont);
+bool BKE_vfont_is_builtin(struct VFont *vfont);
void BKE_vfont_builtin_register(void *mem, int size);
void BKE_vfont_free_data(struct VFont *vfont);
diff --git a/source/blender/blenkernel/BKE_idcode.h b/source/blender/blenkernel/BKE_idcode.h
index 2a01ef3afdb..74dc8de753e 100644
--- a/source/blender/blenkernel/BKE_idcode.h
+++ b/source/blender/blenkernel/BKE_idcode.h
@@ -64,7 +64,7 @@ int BKE_idcode_from_name(const char *name);
* \param code The code to check.
* \return Boolean, 0 when non linkable.
*/
-int BKE_idcode_is_linkable(int code);
+bool BKE_idcode_is_linkable(int code);
/**
* Return if the ID code is a valid ID code.
@@ -72,7 +72,7 @@ int BKE_idcode_is_linkable(int code);
* \param code The code to check.
* \return Boolean, 0 when invalid.
*/
-int BKE_idcode_is_valid(int code);
+bool BKE_idcode_is_valid(int code);
/**
* Return an ID code and steps the index forward 1.
diff --git a/source/blender/blenkernel/BKE_image.h b/source/blender/blenkernel/BKE_image.h
index dd7e06259bd..26ac2cc8bb4 100644
--- a/source/blender/blenkernel/BKE_image.h
+++ b/source/blender/blenkernel/BKE_image.h
@@ -68,7 +68,7 @@ int BKE_add_image_extension_from_type(char *string, const char imtype);
char BKE_ftype_to_imtype(const int ftype);
int BKE_imtype_to_ftype(const char imtype);
-int BKE_imtype_is_movie(const char imtype);
+bool BKE_imtype_is_movie(const char imtype);
int BKE_imtype_supports_zbuf(const char imtype);
int BKE_imtype_supports_compress(const char imtype);
int BKE_imtype_supports_quality(const char imtype);
diff --git a/source/blender/blenkernel/BKE_library.h b/source/blender/blenkernel/BKE_library.h
index 5aa82be0541..816fb2d1b35 100644
--- a/source/blender/blenkernel/BKE_library.h
+++ b/source/blender/blenkernel/BKE_library.h
@@ -63,7 +63,7 @@ __attribute__((warn_unused_result))
__attribute__((nonnull))
#endif
;
-void BKE_libblock_copy_data(struct ID *id, const struct ID *id_from, const short do_action);
+void BKE_libblock_copy_data(struct ID *id, const struct ID *id_from, const bool do_action);
void BKE_id_lib_local_paths(struct Main *bmain, struct Library *lib, struct ID *id);
void id_lib_extern(struct ID *id);
@@ -72,13 +72,13 @@ void id_us_ensure_real(struct ID *id);
void id_us_plus(struct ID *id);
void id_us_min(struct ID *id);
-int id_make_local(struct ID *id, int test);
-int id_single_user(struct bContext *C, struct ID *id, struct PointerRNA *ptr, struct PropertyRNA *prop);
-int id_copy(struct ID *id, struct ID **newid, int test);
-int id_unlink(struct ID *id, int test);
+bool id_make_local(struct ID *id, bool test);
+bool id_single_user(struct bContext *C, struct ID *id, struct PointerRNA *ptr, struct PropertyRNA *prop);
+bool id_copy(struct ID *id, struct ID **newid, bool test);
+bool id_unlink(struct ID *id, int test);
void id_sort_by_name(struct ListBase *lb, struct ID *id);
-int new_id(struct ListBase *lb, struct ID *id, const char *name);
+bool new_id(struct ListBase *lb, struct ID *id, const char *name);
void id_clear_lib_data(struct Main *bmain, struct ID *id);
struct ListBase *which_libbase(struct Main *mainlib, short type);
@@ -96,10 +96,9 @@ void tag_main_lb(struct ListBase *lb, const short tag);
void tag_main(struct Main *mainvar, const short tag);
void rename_id(struct ID *id, const char *name);
-void name_uiprefix_id(char *name, struct ID *id);
+void name_uiprefix_id(char *name, const struct ID *id);
void test_idbutton(char *name);
-void text_idbutton(struct ID *id, char *text);
-void BKE_library_make_local(struct Main *bmain, struct Library *lib, int untagged_only);
+void BKE_library_make_local(struct Main *bmain, struct Library *lib, bool untagged_only);
struct ID *BKE_libblock_find_name(const short type, const char *name)
#ifdef __GNUC__
__attribute__((warn_unused_result))
@@ -128,4 +127,4 @@ void set_free_windowmanager_cb(void (*func)(struct bContext *, struct wmWindowMa
}
#endif
-#endif
+#endif /* __BKE_LIBRARY_H__ */
diff --git a/source/blender/blenkernel/BKE_main.h b/source/blender/blenkernel/BKE_main.h
index 7c36ff07da5..fec163e2d17 100644
--- a/source/blender/blenkernel/BKE_main.h
+++ b/source/blender/blenkernel/BKE_main.h
@@ -98,6 +98,10 @@ typedef struct Main {
#define MAIN_VERSION_ATLEAST(main, ver, subver) \
((main)->versionfile > (ver) || (main->versionfile == (ver) && (main)->subversionfile >= (subver)))
+#define MAIN_VERSION_OLDER(main, ver, subver) \
+ ((main)->versionfile < (ver) || (main->versionfile == (ver) && (main)->subversionfile < (subver)))
+
+
#ifdef __cplusplus
}
#endif
diff --git a/source/blender/blenkernel/BKE_mball.h b/source/blender/blenkernel/BKE_mball.h
index 662bfab10a1..9bbff515983 100644
--- a/source/blender/blenkernel/BKE_mball.h
+++ b/source/blender/blenkernel/BKE_mball.h
@@ -48,8 +48,8 @@ void BKE_mball_make_local(struct MetaBall *mb);
void BKE_mball_cubeTable_free(void);
void BKE_mball_polygonize(struct Scene *scene, struct Object *ob, struct ListBase *dispbase);
-int BKE_mball_is_basis_for(struct Object *ob1, struct Object *ob2);
-int BKE_mball_is_basis(struct Object *ob);
+bool BKE_mball_is_basis_for(struct Object *ob1, struct Object *ob2);
+bool BKE_mball_is_basis(struct Object *ob);
struct Object *BKE_mball_basis_find(struct Scene *scene, struct Object *ob);
void BKE_mball_texspace_calc(struct Object *ob);
diff --git a/source/blender/blenkernel/BKE_mesh.h b/source/blender/blenkernel/BKE_mesh.h
index 24535eb1fd6..398d1fe8545 100644
--- a/source/blender/blenkernel/BKE_mesh.h
+++ b/source/blender/blenkernel/BKE_mesh.h
@@ -169,7 +169,8 @@ int BKE_mesh_nurbs_displist_to_mdata(struct Object *ob, struct ListBase *dispbas
struct MLoopUV **alluv, int *_totloop, int *_totpoly);
void BKE_mesh_from_nurbs_displist(struct Object *ob, struct ListBase *dispbase, int use_orco_uv);
void BKE_mesh_from_nurbs(struct Object *ob);
-void BKE_mesh_from_curve(struct Scene *scene, struct Object *ob);
+void BKE_mesh_to_curve_nurblist(struct DerivedMesh *dm, struct ListBase *nurblist, const int edge_users_test);
+void BKE_mesh_to_curve(struct Scene *scene, struct Object *ob);
void BKE_mesh_delete_material_index(struct Mesh *me, short index);
void BKE_mesh_smooth_flag_set(struct Object *meshOb, int enableSmooth);
void BKE_mesh_convert_mfaces_to_mpolys(struct Mesh *mesh);
@@ -325,7 +326,7 @@ int BKE_mesh_validate_arrays(
int BKE_mesh_validate(struct Mesh *me, int do_verbose);
int BKE_mesh_validate_dm(struct DerivedMesh *dm);
-void BKE_mesh_calc_edges(struct Mesh *mesh, int update);
+void BKE_mesh_calc_edges(struct Mesh *mesh, bool update, const bool select);
void BKE_mesh_ensure_navmesh(struct Mesh *me);
diff --git a/source/blender/blenkernel/BKE_movieclip.h b/source/blender/blenkernel/BKE_movieclip.h
index 5777a4094bc..c8c94b2898b 100644
--- a/source/blender/blenkernel/BKE_movieclip.h
+++ b/source/blender/blenkernel/BKE_movieclip.h
@@ -64,9 +64,14 @@ void BKE_movieclip_get_cache_segments(struct MovieClip *clip, struct MovieClipUs
void BKE_movieclip_build_proxy_frame(struct MovieClip *clip, int clip_flag, struct MovieDistortion *distortion,
int cfra, int *build_sizes, int build_count, int undistorted);
+void BKE_movieclip_build_proxy_frame_for_ibuf(struct MovieClip *clip, struct ImBuf *ibuf, struct MovieDistortion *distortion,
+ int cfra, int *build_sizes, int build_count, int undistorted);
+
float BKE_movieclip_remap_scene_to_clip_frame(struct MovieClip *clip, float framenr);
float BKE_movieclip_remap_clip_to_scene_frame(struct MovieClip *clip, float framenr);
+void BKE_movieclip_filename_for_frame(struct MovieClip *clip, int framenr, char *name);
+
/* cacheing flags */
#define MOVIECLIP_CACHE_SKIP (1 << 0)
diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h
index 19fe621ade9..80955729326 100644
--- a/source/blender/blenkernel/BKE_node.h
+++ b/source/blender/blenkernel/BKE_node.h
@@ -48,6 +48,7 @@ struct GPUMaterial;
struct GPUNode;
struct GPUNodeStack;
struct ID;
+struct ImBuf;
struct ImageFormatData;
struct ListBase;
struct Main;
diff --git a/source/blender/blenkernel/BKE_object.h b/source/blender/blenkernel/BKE_object.h
index 89860cd0da9..5caa484caa0 100644
--- a/source/blender/blenkernel/BKE_object.h
+++ b/source/blender/blenkernel/BKE_object.h
@@ -68,7 +68,7 @@ void BKE_object_update_base_layer(struct Scene *scene, struct Object *ob);
void BKE_object_free(struct Object *ob);
void BKE_object_free_display(struct Object *ob);
-int BKE_object_support_modifier_type_check(struct Object *ob, int modifier_type);
+bool BKE_object_support_modifier_type_check(struct Object *ob, int modifier_type);
void BKE_object_link_modifiers(struct Object *ob, struct Object *from);
void BKE_object_free_modifiers(struct Object *ob);
@@ -77,8 +77,8 @@ void BKE_object_make_proxy(struct Object *ob, struct Object *target, struct Obje
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);
+bool BKE_object_exists_check(struct Object *obtest);
+bool BKE_object_is_in_editmode(struct Object *ob);
struct Object *BKE_object_add_only_object(struct Main *bmain, int type, const char *name);
struct Object *BKE_object_add(struct Scene *scene, int type);
@@ -87,8 +87,8 @@ void *BKE_object_obdata_add_from_type(int type);
struct Object *BKE_object_copy_ex(struct Main *bmain, struct Object *ob, int copy_caches);
struct Object *BKE_object_copy(struct Object *ob);
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);
+bool BKE_object_is_libdata(struct Object *ob);
+bool 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], short use_drot);
@@ -128,7 +128,7 @@ void BKE_scene_foreach_display_point(struct Scene *scene,
const short flag,
void (*func_cb)(const float[3], void *), void *user_data);
-int BKE_object_parent_loop_check(const struct Object *parent, const struct Object *ob);
+bool BKE_object_parent_loop_check(const struct Object *parent, const struct Object *ob);
void *BKE_object_tfm_backup(struct Object *ob);
void BKE_object_tfm_restore(struct Object *ob, void *obtfm_pt);
@@ -160,9 +160,12 @@ int BKE_object_insert_ptcache(struct Object *ob);
// void object_delete_ptcache(struct Object *ob, int index);
struct KeyBlock *BKE_object_insert_shape_key(struct Scene *scene, struct Object *ob, const char *name, int from_mix);
+bool BKE_object_is_child_recursive(struct Object *ob_parent, struct Object *ob_child);
+bool BKE_object_is_animated(struct Scene *scene, struct Object *ob);
+
+/* return ModifierMode flag */
int BKE_object_is_modified(struct Scene *scene, struct Object *ob);
int BKE_object_is_deform_modified(struct Scene *scene, struct Object *ob);
-int BKE_object_is_animated(struct Scene *scene, struct Object *ob);
void BKE_object_relink(struct Object *ob);
diff --git a/source/blender/blenkernel/BKE_packedFile.h b/source/blender/blenkernel/BKE_packedFile.h
index b19a2092206..8fab44121de 100644
--- a/source/blender/blenkernel/BKE_packedFile.h
+++ b/source/blender/blenkernel/BKE_packedFile.h
@@ -74,7 +74,7 @@ void rewindPackedFile(struct PackedFile *pf);
int readPackedFile(struct PackedFile *pf, void *data, int size);
/* ID should be not NULL, return 1 if there's a packed file */
-int BKE_pack_check(struct ID *id);
+bool BKE_pack_check(struct ID *id);
/* ID should be not NULL, throws error when ID is Library */
void BKE_unpack_id(struct Main *bmain, struct ID *id, struct ReportList *reports, int how);
diff --git a/source/blender/blenkernel/BKE_paint.h b/source/blender/blenkernel/BKE_paint.h
index 211b6189fa8..35941d0a05a 100644
--- a/source/blender/blenkernel/BKE_paint.h
+++ b/source/blender/blenkernel/BKE_paint.h
@@ -48,12 +48,23 @@ struct PBVH;
struct Scene;
struct StrokeCache;
struct ImagePool;
+struct UnifiedPaintSettings;
extern const char PAINT_CURSOR_SCULPT[3];
extern const char PAINT_CURSOR_VERTEX_PAINT[3];
extern const char PAINT_CURSOR_WEIGHT_PAINT[3];
extern const char PAINT_CURSOR_TEXTURE_PAINT[3];
+typedef enum PaintMode {
+ PAINT_SCULPT = 0,
+ PAINT_VERTEX = 1,
+ PAINT_WEIGHT = 2,
+ PAINT_TEXTURE_PROJECTIVE = 3,
+ PAINT_TEXTURE_2D = 4,
+ PAINT_SCULPT_UV = 5,
+ PAINT_INVALID = 6
+} PaintMode;
+
void BKE_paint_init(struct Paint *p, const char col[3]);
void BKE_paint_free(struct Paint *p);
void BKE_paint_copy(struct Paint *src, struct Paint *tar);
@@ -61,6 +72,7 @@ void BKE_paint_copy(struct Paint *src, struct Paint *tar);
/* TODO, give these BKE_ prefix too */
struct Paint *paint_get_active(struct Scene *sce);
struct Paint *paint_get_active_from_context(const struct bContext *C);
+PaintMode paintmode_get_active_from_context(const struct bContext *C);
struct Brush *paint_brush(struct Paint *paint);
void paint_brush_set(struct Paint *paint, struct Brush *br);
@@ -79,7 +91,7 @@ int paint_is_bmesh_face_hidden(struct BMFace *f);
/* paint masks */
float paint_grid_paint_mask(const struct GridPaintMask *gpm, unsigned level,
unsigned x, unsigned y);
-
+void paint_calculate_rake_rotation(struct UnifiedPaintSettings *ups, const float mouse_pos[2]);
/* Session data (mode-specific) */
typedef struct SculptSession {
diff --git a/source/blender/blenkernel/BKE_pbvh.h b/source/blender/blenkernel/BKE_pbvh.h
index 99ed978561e..cdc8ef0bdf4 100644
--- a/source/blender/blenkernel/BKE_pbvh.h
+++ b/source/blender/blenkernel/BKE_pbvh.h
@@ -295,7 +295,7 @@ void pbvh_vertex_iter_init(PBVH *bvh, PBVHNode *node,
vi.mask = &vi.vmask[vi.vert_indices[vi.gx]]; \
} \
else { \
- if (!BLI_ghashIterator_isDone(&vi.bm_unique_verts)) {\
+ if (BLI_ghashIterator_notDone(&vi.bm_unique_verts)) {\
vi.bm_vert = BLI_ghashIterator_getKey(&vi.bm_unique_verts); \
BLI_ghashIterator_step(&vi.bm_unique_verts); \
} \
diff --git a/source/blender/blenkernel/BKE_screen.h b/source/blender/blenkernel/BKE_screen.h
index 629acab9e34..5407e22e49e 100644
--- a/source/blender/blenkernel/BKE_screen.h
+++ b/source/blender/blenkernel/BKE_screen.h
@@ -75,6 +75,8 @@ typedef struct SpaceType {
/* init is to cope with file load, screen (size) changes, check handlers */
void (*init)(struct wmWindowManager *, struct ScrArea *);
+ /* exit is called when the area is hidden or removed */
+ void (*exit)(struct wmWindowManager *, struct ScrArea *);
/* Listeners can react to bContext changes */
void (*listener)(struct ScrArea *, struct wmNotifier *);
@@ -116,6 +118,8 @@ typedef struct ARegionType {
/* add handlers, stuff you only do once or on area/region type/size changes */
void (*init)(struct wmWindowManager *, struct ARegion *);
+ /* exit is called when the region is hidden or removed */
+ void (*exit)(struct wmWindowManager *, struct ARegion *);
/* draw entirely, view changes should be handled here */
void (*draw)(const struct bContext *, struct ARegion *);
/* contextual changes should be handled here */
@@ -163,9 +167,10 @@ typedef struct ARegionType {
typedef struct PanelType {
struct PanelType *next, *prev;
- char idname[BKE_ST_MAXNAME]; /* unique name */
- char label[BKE_ST_MAXNAME]; /* for panel header */
- char context[BKE_ST_MAXNAME]; /* for buttons window */
+ char idname[BKE_ST_MAXNAME]; /* unique name */
+ char label[BKE_ST_MAXNAME]; /* for panel header */
+ char translation_context[BKE_ST_MAXNAME];
+ char context[BKE_ST_MAXNAME]; /* for buttons window */
int space_type;
int region_type;
@@ -227,7 +232,8 @@ typedef struct MenuType {
char idname[BKE_ST_MAXNAME]; /* unique name */
char label[BKE_ST_MAXNAME]; /* for button text */
- char *description;
+ char translation_context[BKE_ST_MAXNAME];
+ char *description;
/* verify if the menu should draw or not */
int (*poll)(const struct bContext *, struct MenuType *);
diff --git a/source/blender/blenkernel/BKE_sequencer.h b/source/blender/blenkernel/BKE_sequencer.h
index c0ff634671d..a46d947b9d9 100644
--- a/source/blender/blenkernel/BKE_sequencer.h
+++ b/source/blender/blenkernel/BKE_sequencer.h
@@ -192,7 +192,7 @@ void BKE_sequencer_pixel_from_sequencer_space_v4(struct Scene *scene, float pixe
/* **********************************************************************
* sequencer scene functions
* ********************************************************************** */
-struct Editing *BKE_sequencer_editing_get(struct Scene *scene, int alloc);
+struct Editing *BKE_sequencer_editing_get(struct Scene *scene, bool alloc);
struct Editing *BKE_sequencer_editing_ensure(struct Scene *scene);
void BKE_sequencer_editing_free(struct Scene *scene);
@@ -289,10 +289,10 @@ int BKE_sequence_tx_get_final_right(struct Sequence *seq, int metaclip);
void BKE_sequence_tx_set_final_left(struct Sequence *seq, int val);
void BKE_sequence_tx_set_final_right(struct Sequence *seq, int val);
void BKE_sequence_tx_handle_xlimits(struct Sequence *seq, int leftflag, int rightflag);
-int BKE_sequence_tx_test(struct Sequence *seq);
-int BKE_sequence_single_check(struct Sequence *seq);
+bool BKE_sequence_tx_test(struct Sequence *seq);
+bool BKE_sequence_single_check(struct Sequence *seq);
void BKE_sequence_single_fix(struct Sequence *seq);
-int BKE_sequence_test_overlap(struct ListBase *seqbasep, struct Sequence *test);
+bool BKE_sequence_test_overlap(struct ListBase *seqbasep, struct Sequence *test);
void BKE_sequence_translate(struct Scene *scene, struct Sequence *seq, int delta);
void BKE_sequence_sound_init(struct Scene *scene, struct Sequence *seq);
struct Sequence *BKE_sequencer_foreground_frame_get(struct Scene *scene, int frame);
@@ -301,14 +301,14 @@ struct Sequence *BKE_sequence_metastrip(ListBase *seqbase /* = ed->seqbase */, s
void BKE_sequencer_offset_animdata(struct Scene *scene, struct Sequence *seq, int ofs);
void BKE_sequencer_dupe_animdata(struct Scene *scene, const char *name_src, const char *name_dst);
-int BKE_sequence_base_shuffle(struct ListBase *seqbasep, struct Sequence *test, struct Scene *evil_scene);
-int BKE_sequence_base_shuffle_time(ListBase *seqbasep, struct Scene *evil_scene);
-int BKE_sequence_base_isolated_sel_check(struct ListBase *seqbase);
+bool BKE_sequence_base_shuffle(struct ListBase *seqbasep, struct Sequence *test, struct Scene *evil_scene);
+bool BKE_sequence_base_shuffle_time(ListBase *seqbasep, struct Scene *evil_scene);
+bool BKE_sequence_base_isolated_sel_check(struct ListBase *seqbase);
void BKE_sequencer_free_imbuf(struct Scene *scene, struct ListBase *seqbasep, int for_render);
struct Sequence *BKE_sequence_dupli_recursive(struct Scene *scene, struct Scene *scene_to, struct Sequence *seq, int dupe_flag);
int BKE_sequence_swap(struct Sequence *seq_a, struct Sequence *seq_b, const char **error_str);
-int BKE_sequence_check_depend(struct Sequence *seq, struct Sequence *cur);
+bool BKE_sequence_check_depend(struct Sequence *seq, struct Sequence *cur);
void BKE_sequence_invalidate_cache(struct Scene *scene, struct Sequence *seq);
void BKE_sequence_invalidate_dependent(struct Scene *scene, struct Sequence *seq);
void BKE_sequence_invalidate_cache_for_modifier(struct Scene *scene, struct Sequence *seq);
@@ -320,7 +320,7 @@ void BKE_sequencer_update_sound(struct Scene *scene, struct bSound *sound);
void BKE_sequence_base_unique_name_recursive(ListBase *seqbasep, struct Sequence *seq);
void BKE_sequence_base_dupli_recursive(struct Scene *scene, struct Scene *scene_to, ListBase *nseqbase, ListBase *seqbase, int dupe_flag);
-int BKE_sequence_is_valid_check(struct Sequence *seq);
+bool BKE_sequence_is_valid_check(struct Sequence *seq);
void BKE_sequencer_clear_scene_in_allseqs(struct Main *bmain, struct Scene *sce);
void BKE_sequencer_clear_movieclip_in_clipboard(struct MovieClip *clip);
@@ -419,4 +419,4 @@ int BKE_sequence_supports_modifiers(struct Sequence *seq);
struct ImBuf *BKE_sequencer_render_mask_input(SeqRenderData context, int mask_input_type, struct Sequence *mask_sequence, struct Mask *mask_id, int cfra, int make_float);
void BKE_sequencer_color_balance_apply(struct StripColorBalance *cb, struct ImBuf *ibuf, float mul, short make_float, struct ImBuf *mask_input);
-#endif /* __BKE_SEQUENCER_H__ */
+#endif /* __BKE_SEQUENCER_H__ */
diff --git a/source/blender/blenkernel/BKE_text.h b/source/blender/blenkernel/BKE_text.h
index 3d7b5d1c8e4..5e81fb85d76 100644
--- a/source/blender/blenkernel/BKE_text.h
+++ b/source/blender/blenkernel/BKE_text.h
@@ -45,16 +45,16 @@ struct SpaceText;
void BKE_text_free (struct Text *text);
void txt_set_undostate (int u);
int txt_get_undostate (void);
-struct Text* BKE_text_add (struct Main *bmain, const char *name);
+struct Text *BKE_text_add (struct Main *bmain, const char *name);
int txt_extended_ascii_as_utf8(char **str);
int BKE_text_reload (struct Text *text);
-struct Text* BKE_text_load (struct Main *bmain, const char *file, const char *relpath);
-struct Text* BKE_text_copy (struct Text *ta);
+struct Text *BKE_text_load (struct Main *bmain, const char *file, const char *relpath);
+struct Text *BKE_text_copy (struct Text *ta);
void BKE_text_unlink (struct Main *bmain, struct Text *text);
void BKE_text_clear (struct Text *text);
void BKE_text_write (struct Text *text, const char *str);
-char* txt_to_buf (struct Text *text);
+char *txt_to_buf (struct Text *text);
void txt_clean_text (struct Text *text);
void txt_order_cursors (struct Text *text);
int txt_find_string (struct Text *text, const char *findstr, int wrap, int match_case);
@@ -62,6 +62,8 @@ int txt_has_sel (struct Text *text);
int txt_get_span (struct TextLine *from, struct TextLine *to);
int txt_utf8_offset_to_index(const char *str, int offset);
int txt_utf8_index_to_offset(const char *str, int index);
+int txt_utf8_offset_to_column(const char *str, int offset);
+int txt_utf8_column_to_offset(const char *str, int column);
void txt_move_up (struct Text *text, short sel);
void txt_move_down (struct Text *text, short sel);
void txt_move_left (struct Text *text, short sel);
@@ -80,7 +82,7 @@ void txt_delete_word (struct Text *text);
void txt_delete_selected (struct Text *text);
void txt_sel_all (struct Text *text);
void txt_sel_line (struct Text *text);
-char* txt_sel_to_buf (struct Text *text);
+char *txt_sel_to_buf (struct Text *text);
void txt_insert_buf (struct Text *text, const char *in_buffer);
void txt_print_undo (struct Text *text);
void txt_undo_add_op (struct Text *text, int op);
@@ -98,7 +100,7 @@ void txt_indent (struct Text *text);
void txt_uncomment (struct Text *text);
void txt_move_lines (struct Text *text, const int direction);
void txt_duplicate_line (struct Text *text);
-int setcurr_tab_spaces (struct Text *text, int space);
+int txt_setcurr_tab_spaces(struct Text *text, int space);
/* utility functions, could be moved somewhere more generic but are python/text related */
int text_check_bracket(const char ch);
diff --git a/source/blender/blenkernel/BKE_tracking.h b/source/blender/blenkernel/BKE_tracking.h
index 9bdc96e187d..c8ad708f832 100644
--- a/source/blender/blenkernel/BKE_tracking.h
+++ b/source/blender/blenkernel/BKE_tracking.h
@@ -144,6 +144,7 @@ void BKE_tracking_camera_get_reconstructed_interpolate(struct MovieTracking *tra
struct MovieDistortion *BKE_tracking_distortion_new(void);
void BKE_tracking_distortion_update(struct MovieDistortion *distortion, struct MovieTracking *tracking,
int calibration_width, int calibration_height);
+void BKE_tracking_distortion_set_threads(struct MovieDistortion *distortion, int threads);
struct MovieDistortion *BKE_tracking_distortion_copy(struct MovieDistortion *distortion);
struct ImBuf *BKE_tracking_distortion_exec(struct MovieDistortion *distortion, struct MovieTracking *tracking,
struct ImBuf *ibuf, int width, int height, float overscan, int undistort);
@@ -162,7 +163,7 @@ void BKE_tracking_max_undistortion_delta_across_bound(struct MovieTracking *trac
/* **** Image sampling **** */
struct ImBuf *BKE_tracking_sample_pattern(int frame_width, int frame_height,
struct ImBuf *struct_ibuf, struct MovieTrackingTrack *track,
- struct MovieTrackingMarker *marker, int use_mask,
+ struct MovieTrackingMarker *marker, int from_anchor, int use_mask,
int num_samples_x, int num_samples_y, float pos[2]);
struct ImBuf *BKE_tracking_get_pattern_imbuf(struct ImBuf *ibuf, struct MovieTrackingTrack *track,
struct MovieTrackingMarker *marker, int anchored, int disable_channels);
diff --git a/source/blender/blenkernel/BKE_unit.h b/source/blender/blenkernel/BKE_unit.h
index 86f46820c97..6b5ce5e1d21 100644
--- a/source/blender/blenkernel/BKE_unit.h
+++ b/source/blender/blenkernel/BKE_unit.h
@@ -70,7 +70,8 @@ double bUnit_GetScaler(void *usys_pt, int index);
#define B_UNIT_TIME 6
#define B_UNIT_VELOCITY 7
#define B_UNIT_ACCELERATION 8
-#define B_UNIT_TYPE_TOT 9
+#define B_UNIT_CAMERA 9
+#define B_UNIT_TYPE_TOT 10
#ifdef __cplusplus
}
diff --git a/source/blender/blenkernel/depsgraph_private.h b/source/blender/blenkernel/depsgraph_private.h
index ad5369c0820..14e7d220449 100644
--- a/source/blender/blenkernel/depsgraph_private.h
+++ b/source/blender/blenkernel/depsgraph_private.h
@@ -137,8 +137,6 @@ DagNode *dag_get_node(DagForest *forest, void *fob);
DagNode *dag_get_sub_node(DagForest *forest, void *fob);
void dag_add_relation(DagForest *forest, DagNode *fob1, DagNode *fob2, short rel, const char *name);
-void graph_bfs(void);
-
DagNodeQueue *graph_dfs(void);
void set_node_xy(DagNode *node, float x, float y);
diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c
index ffd86ea9ce0..f09de138428 100644
--- a/source/blender/blenkernel/intern/DerivedMesh.c
+++ b/source/blender/blenkernel/intern/DerivedMesh.c
@@ -1025,12 +1025,18 @@ enum {
CALC_WP_AUTO_NORMALIZE = (1 << 4)
};
-static void weightpaint_color(unsigned char r_col[4], ColorBand *coba, const float input)
+typedef struct DMWeightColorInfo {
+ const ColorBand *coba;
+ const char *alert_color;
+} DMWeightColorInfo;
+
+
+static void weightpaint_color(unsigned char r_col[4], DMWeightColorInfo *dm_wcinfo, const float input)
{
float colf[4];
- if (coba) {
- do_colorband(coba, input, colf);
+ if (dm_wcinfo && dm_wcinfo->coba) {
+ do_colorband(dm_wcinfo->coba, input, colf);
}
else {
weight_to_rgb(colf, input);
@@ -1047,17 +1053,19 @@ static void weightpaint_color(unsigned char r_col[4], ColorBand *coba, const flo
static void calc_weightpaint_vert_color(
unsigned char r_col[4],
- MDeformVert *dv, ColorBand *coba,
+ MDeformVert *dv,
+ DMWeightColorInfo *dm_wcinfo,
const int defbase_tot, const int defbase_act,
const char *defbase_sel, const int defbase_sel_tot,
const int draw_flag)
{
float input = 0.0f;
- bool make_black = false;
+ bool show_alert_color = false;
if ((defbase_sel_tot > 1) && (draw_flag & CALC_WP_MULTIPAINT)) {
- int was_a_nonzero = FALSE;
+ /* Multi-Paint feature */
+ bool was_a_nonzero = false;
unsigned int i;
MDeformWeight *dw = dv->dw;
@@ -1068,15 +1076,15 @@ static void calc_weightpaint_vert_color(
if (defbase_sel[dw->def_nr]) {
if (dw->weight) {
input += dw->weight;
- was_a_nonzero = TRUE;
+ was_a_nonzero = true;
}
}
}
}
/* make it black if the selected groups have no weight on a vertex */
- if (was_a_nonzero == FALSE) {
- make_black = true;
+ if (was_a_nonzero == false) {
+ show_alert_color = true;
}
else if ((draw_flag & CALC_WP_AUTO_NORMALIZE) == FALSE) {
input /= defbase_sel_tot; /* get the average */
@@ -1088,33 +1096,32 @@ static void calc_weightpaint_vert_color(
if (draw_flag & CALC_WP_GROUP_USER_ACTIVE) {
if (input == 0.0f) {
- make_black = true;
+ show_alert_color = true;
}
}
else if (draw_flag & CALC_WP_GROUP_USER_ALL) {
if (input == 0.0f) {
- make_black = defvert_is_weight_zero(dv, defbase_tot);
+ show_alert_color = defvert_is_weight_zero(dv, defbase_tot);
}
}
}
- if (make_black) { /* TODO, theme color */
- r_col[3] = 255;
- r_col[2] = 0;
- r_col[1] = 0;
- r_col[0] = 0;
+ if (show_alert_color == false) {
+ CLAMP(input, 0.0f, 1.0f);
+ weightpaint_color(r_col, dm_wcinfo, input);
}
else {
- CLAMP(input, 0.0f, 1.0f);
- weightpaint_color(r_col, coba, input);
+ copy_v3_v3_char((char *)r_col, dm_wcinfo->alert_color);
+ r_col[3] = 255;
}
}
-static ColorBand *stored_cb = NULL;
+static DMWeightColorInfo G_dm_wcinfo;
-void vDM_ColorBand_store(ColorBand *coba)
+void vDM_ColorBand_store(const ColorBand *coba, const char alert_color[4])
{
- stored_cb = coba;
+ G_dm_wcinfo.coba = coba;
+ G_dm_wcinfo.alert_color = alert_color;
}
/* return an array of vertex weight colors, caller must free.
@@ -1122,7 +1129,7 @@ void vDM_ColorBand_store(ColorBand *coba)
* note that we could save some memory and allocate RGB only but then we'd need to
* re-arrange the colors when copying to the face since MCol has odd ordering,
* so leave this as is - campbell */
-static unsigned char *calc_weightpaint_vert_array(Object *ob, DerivedMesh *dm, int const draw_flag, ColorBand *coba)
+static unsigned char *calc_weightpaint_vert_array(Object *ob, DerivedMesh *dm, int const draw_flag, DMWeightColorInfo *dm_wcinfo)
{
MDeformVert *dv = DM_get_vert_data_layer(dm, CD_MDEFORMVERT);
int numVerts = dm->getNumVerts(dm);
@@ -1144,7 +1151,7 @@ static unsigned char *calc_weightpaint_vert_array(Object *ob, DerivedMesh *dm, i
}
for (i = numVerts; i != 0; i--, wc += 4, dv++) {
- calc_weightpaint_vert_color(wc, dv, coba, defbase_tot, defbase_act, defbase_sel, defbase_sel_tot, draw_flag);
+ calc_weightpaint_vert_color(wc, dv, dm_wcinfo, defbase_tot, defbase_act, defbase_sel, defbase_sel_tot, draw_flag);
}
if (defbase_sel) {
@@ -1157,7 +1164,7 @@ static unsigned char *calc_weightpaint_vert_array(Object *ob, DerivedMesh *dm, i
col_i = 0;
}
else {
- weightpaint_color((unsigned char *)&col_i, coba, 0.0f);
+ weightpaint_color((unsigned char *)&col_i, dm_wcinfo, 0.0f);
}
fill_vn_i((int *)wtcol_v, numVerts, col_i);
}
@@ -1185,7 +1192,6 @@ static unsigned char *calc_colors_from_weights_array(const int num, float *weigh
void DM_update_weight_mcol(Object *ob, DerivedMesh *dm, int const draw_flag,
float *weights, int num, const int *indices)
{
- ColorBand *coba = stored_cb; /* warning, not a local var */
unsigned char *wtcol_v;
unsigned char(*wtcol_l)[4] = CustomData_get_layer(dm->getLoopDataLayout(dm), CD_PREVIEW_MLOOPCOL);
@@ -1213,10 +1219,10 @@ void DM_update_weight_mcol(Object *ob, DerivedMesh *dm, int const draw_flag,
if (indices)
MEM_freeN(w);
}
-
- /* No weights given, take them from active vgroup(s). */
- else
- wtcol_v = calc_weightpaint_vert_array(ob, dm, draw_flag, coba);
+ else {
+ /* No weights given, take them from active vgroup(s). */
+ wtcol_v = calc_weightpaint_vert_array(ob, dm, draw_flag, &G_dm_wcinfo);
+ }
/* now add to loops, so the data can be passed through the modifier stack */
/* If no CD_PREVIEW_MLOOPCOL existed yet, we have to add a new one! */
diff --git a/source/blender/blenkernel/intern/anim.c b/source/blender/blenkernel/intern/anim.c
index 4eb26e81ae2..ddb4cc4391a 100644
--- a/source/blender/blenkernel/intern/anim.c
+++ b/source/blender/blenkernel/intern/anim.c
@@ -1154,10 +1154,6 @@ static void face_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, floa
if (ob->type != OB_MBALL) ob->flag |= OB_DONE; /* doesnt render */
for (a = 0, mp = mpoly; a < totface; a++, mp++) {
- int mv1;
- int mv2;
- int mv3;
- /* int mv4; */ /* UNUSED */
float *v1;
float *v2;
float *v3;
@@ -1171,9 +1167,9 @@ static void face_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, floa
}
else {
BKE_mesh_calc_poly_normal(mp, mloop + mp->loopstart, mvert, f_no);
- v1 = mvert[(mv1 = loopstart[0].v)].co;
- v2 = mvert[(mv2 = loopstart[1].v)].co;
- v3 = mvert[(mv3 = loopstart[2].v)].co;
+ v1 = mvert[loopstart[0].v].co;
+ v2 = mvert[loopstart[1].v].co;
+ v3 = mvert[loopstart[2].v].co;
}
/* translation */
diff --git a/source/blender/blenkernel/intern/anim_sys.c b/source/blender/blenkernel/intern/anim_sys.c
index bd13c406fa5..738d4c5b089 100644
--- a/source/blender/blenkernel/intern/anim_sys.c
+++ b/source/blender/blenkernel/intern/anim_sys.c
@@ -245,7 +245,7 @@ void BKE_free_animdata(ID *id)
/* Freeing -------------------------------------------- */
/* Make a copy of the given AnimData - to be used when copying datablocks */
-AnimData *BKE_copy_animdata(AnimData *adt, const short do_action)
+AnimData *BKE_copy_animdata(AnimData *adt, const bool do_action)
{
AnimData *dadt;
@@ -277,7 +277,7 @@ AnimData *BKE_copy_animdata(AnimData *adt, const short do_action)
return dadt;
}
-int BKE_copy_animdata_id(ID *id_to, ID *id_from, const short do_action)
+int BKE_copy_animdata_id(ID *id_to, ID *id_from, const bool do_action)
{
AnimData *adt;
diff --git a/source/blender/blenkernel/intern/armature.c b/source/blender/blenkernel/intern/armature.c
index 480814a28c3..ffe6a312ef8 100644
--- a/source/blender/blenkernel/intern/armature.c
+++ b/source/blender/blenkernel/intern/armature.c
@@ -1596,7 +1596,7 @@ static void pose_proxy_synchronize(Object *ob, Object *from, int layer_protected
}
else if (pchan->bone->layer & layer_protected) {
ListBase proxylocal_constraints = {NULL, NULL};
- bPoseChannel pchanw = {NULL};
+ bPoseChannel pchanw;
/* copy posechannel to temp, but restore important pointers */
pchanw = *pchanp;
diff --git a/source/blender/blenkernel/intern/blender.c b/source/blender/blenkernel/intern/blender.c
index be316197078..82b3b4f5618 100644
--- a/source/blender/blenkernel/intern/blender.c
+++ b/source/blender/blenkernel/intern/blender.c
@@ -899,7 +899,9 @@ static void copybuffer_doit(void *UNUSED(handle), Main *UNUSED(bmain), void *vid
{
if (vid) {
ID *id = vid;
- id->flag |= LIB_NEED_EXPAND | LIB_DOIT;
+ /* only tag for need-expand if not done, prevents eternal loops */
+ if ((id->flag & LIB_DOIT) == 0)
+ id->flag |= LIB_NEED_EXPAND | LIB_DOIT;
}
}
@@ -993,7 +995,7 @@ int BKE_copybuffer_paste(bContext *C, char *libname, ReportList *reports)
/* append, rather than linking */
lib = BLI_findstring(&bmain->library, libname, offsetof(Library, filepath));
- BKE_library_make_local(bmain, lib, 1);
+ BKE_library_make_local(bmain, lib, true);
/* important we unset, otherwise these object wont
* link into other scenes from this blend file */
diff --git a/source/blender/blenkernel/intern/bmfont.c b/source/blender/blenkernel/intern/bmfont.c
index fc83b24da5b..78da4f5b1c2 100644
--- a/source/blender/blenkernel/intern/bmfont.c
+++ b/source/blender/blenkernel/intern/bmfont.c
@@ -56,7 +56,7 @@
#include "BKE_bmfont.h"
#include "BKE_bmfont_types.h"
-void printfGlyph(bmGlyph * glyph)
+void printfGlyph(bmGlyph *glyph)
{
printf("unicode: %d '%c'\n", glyph->unicode, glyph->unicode);
printf(" locx: %4d locy: %4d\n", glyph->locx, glyph->locy);
@@ -68,7 +68,7 @@ void printfGlyph(bmGlyph * glyph)
#define MAX2(x, y) ((x) > (y) ? (x) : (y))
#define MAX3(x, y, z) (MAX2(MAX2((x), (y)), (z)))
-void calcAlpha(ImBuf * ibuf)
+void calcAlpha(ImBuf *ibuf)
{
int i;
char * rect;
@@ -82,7 +82,7 @@ void calcAlpha(ImBuf * ibuf)
}
}
-void readBitmapFontVersion0(ImBuf * ibuf, unsigned char * rect, int step)
+void readBitmapFontVersion0(ImBuf *ibuf, unsigned char *rect, int step)
{
int glyphcount, bytes, i, index, linelength, ysize;
unsigned char * buffer;
@@ -198,7 +198,7 @@ void detectBitmapFont(ImBuf *ibuf)
readBitmapFontVersion0(ibuf, rect, 4);
}
else {
- printf("detectBitmapFont :Unsupported version %d\n", version);
+ printf("detectBitmapFont :Unsupported version %d\n", (int)version);
}
/* on succes ibuf->userdata points to the bitmapfont */
diff --git a/source/blender/blenkernel/intern/brush.c b/source/blender/blenkernel/intern/brush.c
index ba69fa4336e..6adcdbd2c3e 100644
--- a/source/blender/blenkernel/intern/brush.c
+++ b/source/blender/blenkernel/intern/brush.c
@@ -53,6 +53,7 @@
#include "IMB_imbuf_types.h"
#include "RE_render_ext.h" /* externtex */
+#include "RE_shader_ext.h"
static void brush_defaults(Brush *brush)
{
@@ -471,62 +472,133 @@ int BKE_brush_clone_image_delete(Brush *brush)
return 0;
}
-/* Brush Sampling for 3d brushes. Currently used for texture painting only, but should be generalized */
-void BKE_brush_sample_tex(const Scene *scene, Brush *brush, const float sampleco[3], float rgba[4], const int thread, struct ImagePool *pool)
+/* Generic texture sampler for 3D painting systems. point has to be either in
+ * region space mouse coordinates, or 3d world coordinates for 3D mapping */
+float BKE_brush_sample_tex_3D(const Scene *scene, Brush *br,
+ const float point[3],
+ float rgba[4], const int thread,
+ struct ImagePool *pool)
{
- MTex *mtex = &brush->mtex;
+ UnifiedPaintSettings *ups = &scene->toolsettings->unified_paint_settings;
+ MTex *mtex = &br->mtex;
+ float intensity = 1.0;
+ bool hasrgb = false;
- if (mtex && mtex->tex) {
- float tin, tr, tg, tb, ta;
- int hasrgb;
- const int radius = BKE_brush_size_get(scene, brush);
+ if (!mtex->tex) {
+ intensity = 1;
+ }
+ else if (mtex->brush_map_mode == MTEX_MAP_MODE_3D) {
+ /* Get strength by feeding the vertex
+ * location directly into a texture */
+ hasrgb = externtex(mtex, point, &intensity,
+ rgba, rgba + 1, rgba + 2, rgba + 3, thread, pool);
+ }
+ else {
+ float rotation = -mtex->rot;
+ float point_2d[2] = {point[0], point[1]};
+ float x = 0.0f, y = 0.0f; /* Quite warnings */
+ float radius = 1.0f; /* Quite warnings */
+ float co[3];
- if (brush->mtex.brush_map_mode == MTEX_MAP_MODE_3D) {
- hasrgb = externtex(mtex, sampleco, &tin, &tr, &tg, &tb, &ta, thread, pool);
- }
- else {
- float co[3];
+ if (mtex->brush_map_mode == MTEX_MAP_MODE_VIEW) {
+ /* keep coordinates relative to mouse */
+
+ rotation += ups->brush_rotation;
- co[0] = sampleco[0] / radius;
- co[1] = sampleco[1] / radius;
- co[2] = 0.0f;
+ point_2d[0] -= ups->tex_mouse[0];
+ point_2d[1] -= ups->tex_mouse[1];
- hasrgb = externtex(mtex, co, &tin, &tr, &tg, &tb, &ta, thread, pool);
+ /* use pressure adjusted size for fixed mode */
+ radius = ups->pixel_radius;
+
+ x = point_2d[0];
+ y = point_2d[1];
}
+ else if (mtex->brush_map_mode == MTEX_MAP_MODE_TILED) {
+ /* leave the coordinates relative to the screen */
- if (hasrgb) {
- rgba[0] = tr;
- rgba[1] = tg;
- rgba[2] = tb;
- rgba[3] = ta;
+ /* use unadjusted size for tiled mode */
+ radius = BKE_brush_size_get(scene, br);
+
+ x = point_2d[0];
+ y = point_2d[1];
}
- else {
- rgba[0] = tin;
- rgba[1] = tin;
- rgba[2] = tin;
- rgba[3] = 1.0f;
+
+ x /= radius;
+ y /= radius;
+
+ /* it is probably worth optimizing for those cases where
+ * the texture is not rotated by skipping the calls to
+ * atan2, sqrtf, sin, and cos. */
+ if (rotation > 0.001f || rotation < -0.001f) {
+ const float angle = atan2f(y, x) + rotation;
+ const float flen = sqrtf(x * x + y * y);
+
+ x = flen * cosf(angle);
+ y = flen * sinf(angle);
}
+
+ x *= br->mtex.size[0];
+ y *= br->mtex.size[1];
+
+ co[0] = x + br->mtex.ofs[0];
+ co[1] = y + br->mtex.ofs[1];
+ co[2] = 0.0f;
+
+ hasrgb = externtex(mtex, co, &intensity,
+ rgba, rgba + 1, rgba + 2, rgba + 3, thread, pool);
}
- else {
- rgba[0] = rgba[1] = rgba[2] = rgba[3] = 1.0f;
+
+ intensity += br->texture_sample_bias;
+
+ if (!hasrgb) {
+ rgba[0] = intensity;
+ rgba[1] = intensity;
+ rgba[2] = intensity;
+ rgba[3] = 1.0f;
}
+
+ return intensity;
}
+
/* Brush Sampling for 2D brushes. when we unify the brush systems this will be necessarily a separate function */
-void BKE_brush_sample_tex_2D(const Scene *scene, Brush *brush, const float xy[2], float rgba[4], const int thread)
+float BKE_brush_sample_tex_2D(const Scene *scene, Brush *brush, const float xy[2], float rgba[4], struct ImagePool *pool)
{
+ UnifiedPaintSettings *ups = &scene->toolsettings->unified_paint_settings;
MTex *mtex = &brush->mtex;
if (mtex && mtex->tex) {
float co[3], tin, tr, tg, tb, ta;
+ float x = xy[0], y = xy[1];
int hasrgb;
- const int radius = BKE_brush_size_get(scene, brush);
+ int radius = BKE_brush_size_get(scene, brush);
+ float rotation = -mtex->rot;
+
+ if (mtex->brush_map_mode == MTEX_MAP_MODE_VIEW) {
+ rotation += ups->brush_rotation;
+ radius = ups->pixel_radius;
+ }
+
+ x /= radius;
+ y /= radius;
+
+ if (rotation > 0.001f || rotation < -0.001f) {
+ const float angle = atan2f(y, x) + rotation;
+ const float flen = sqrtf(x * x + y * y);
- co[0] = xy[0] / radius;
- co[1] = xy[1] / radius;
+ x = flen * cosf(angle);
+ y = flen * sinf(angle);
+ }
+
+ x *= brush->mtex.size[0];
+ y *= brush->mtex.size[1];
+
+ co[0] = x + brush->mtex.ofs[0];
+ co[1] = y + brush->mtex.ofs[1];
co[2] = 0.0f;
- hasrgb = externtex(mtex, co, &tin, &tr, &tg, &tb, &ta, thread, NULL);
+ hasrgb = externtex(mtex, co, &tin, &tr, &tg, &tb, &ta, 0, pool);
if (hasrgb) {
rgba[0] = tr;
@@ -540,9 +612,11 @@ void BKE_brush_sample_tex_2D(const Scene *scene, Brush *brush, const float xy[2]
rgba[2] = tin;
rgba[3] = 1.0f;
}
+ return tin;
}
else {
rgba[0] = rgba[1] = rgba[2] = rgba[3] = 1.0f;
+ return 1.0;
}
}
@@ -790,7 +864,8 @@ void BKE_brush_scale_size(int *r_brush_size,
void BKE_brush_jitter_pos(const Scene *scene, Brush *brush, const float pos[2], float jitterpos[2])
{
- int use_jitter = brush->jitter != 0;
+ int use_jitter = (brush->flag & BRUSH_ABSOLUTE_JITTER) ?
+ (brush->jitter_absolute != 0) : (brush->jitter != 0);
/* jitter-ed brush gives weird and unpredictable result for this
* kinds of stroke, so manually disable jitter usage (sergey) */
@@ -798,17 +873,26 @@ void BKE_brush_jitter_pos(const Scene *scene, Brush *brush, const float pos[2],
if (use_jitter) {
float rand_pos[2];
- const int radius = BKE_brush_size_get(scene, brush);
- const int diameter = 2 * radius;
+ float spread;
+ int diameter;
- /* find random position within a circle of diameter 1 */
do {
rand_pos[0] = BLI_frand() - 0.5f;
rand_pos[1] = BLI_frand() - 0.5f;
} while (len_v2(rand_pos) > 0.5f);
- jitterpos[0] = pos[0] + 2 * rand_pos[0] * diameter * brush->jitter;
- jitterpos[1] = pos[1] + 2 * rand_pos[1] * diameter * brush->jitter;
+
+ if (brush->flag & BRUSH_ABSOLUTE_JITTER) {
+ diameter = 2 * brush->jitter_absolute;
+ spread = 1.0;
+ }
+ else {
+ diameter = 2 * BKE_brush_size_get(scene, brush);
+ spread = brush->jitter;
+ }
+ /* find random position within a circle of diameter 1 */
+ jitterpos[0] = pos[0] + 2 * rand_pos[0] * diameter * spread;
+ jitterpos[1] = pos[1] + 2 * rand_pos[1] * diameter * spread;
}
else {
copy_v2_v2(jitterpos, pos);
@@ -841,6 +925,49 @@ float BKE_brush_curve_strength(Brush *br, float p, const float len)
return curvemapping_evaluateF(br->curve, 0, p);
}
+/* TODO: should probably be unified with BrushPainter stuff? */
+unsigned int *BKE_brush_gen_texture_cache(Brush *br, int half_side)
+{
+ unsigned int *texcache = NULL;
+ MTex *mtex = &br->mtex;
+ TexResult texres = {0};
+ int hasrgb, ix, iy;
+ int side = half_side * 2;
+
+ if (mtex->tex) {
+ float x, y, step = 2.0 / side, co[3];
+
+ texcache = MEM_callocN(sizeof(int) * side * side, "Brush texture cache");
+
+ /*do normalized cannonical view coords for texture*/
+ for (y = -1.0, iy = 0; iy < side; iy++, y += step) {
+ for (x = -1.0, ix = 0; ix < side; ix++, x += step) {
+ co[0] = x;
+ co[1] = y;
+ co[2] = 0.0f;
+
+ /* This is copied from displace modifier code */
+ hasrgb = multitex_ext(mtex->tex, co, NULL, NULL, 0, &texres, NULL);
+
+ /* if the texture gave an RGB value, we assume it didn't give a valid
+ * intensity, so calculate one (formula from do_material_tex).
+ * if the texture didn't give an RGB value, copy the intensity across
+ */
+ if (hasrgb & TEX_RGB)
+ texres.tin = rgb_to_grayscale(&texres.tr);
+
+ ((char *)texcache)[(iy * side + ix) * 4] =
+ ((char *)texcache)[(iy * side + ix) * 4 + 1] =
+ ((char *)texcache)[(iy * side + ix) * 4 + 2] =
+ ((char *)texcache)[(iy * side + ix) * 4 + 3] = (char)(texres.tin * 255.0f);
+ }
+ }
+ }
+
+ return texcache;
+}
+
+
/**** Radial Control ****/
struct ImBuf *BKE_brush_gen_radial_control_imbuf(Brush *br)
{
diff --git a/source/blender/blenkernel/intern/cloth.c b/source/blender/blenkernel/intern/cloth.c
index c1293542963..a7311d5efc7 100644
--- a/source/blender/blenkernel/intern/cloth.c
+++ b/source/blender/blenkernel/intern/cloth.c
@@ -783,14 +783,12 @@ static void cloth_apply_vgroup ( ClothModifierData *clmd, DerivedMesh *dm )
/* goalfac= 1.0f; */ /* UNUSED */
- /*
// Kicking goal factor to simplify things...who uses that anyway?
// ABS ( clmd->sim_parms->maxgoal - clmd->sim_parms->mingoal );
- */
verts->goal = powf(verts->goal, 4.0f);
if ( verts->goal >= SOFTGOALSNAP )
- verts->flags |= CLOTH_VERT_FLAG_PINNED;
+ verts->flags |= CLOTH_VERT_FLAG_PINNED;
}
if (clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_SCALING ) {
diff --git a/source/blender/blenkernel/intern/collision.c b/source/blender/blenkernel/intern/collision.c
index 061657c8f2d..ed72a0fb37b 100644
--- a/source/blender/blenkernel/intern/collision.c
+++ b/source/blender/blenkernel/intern/collision.c
@@ -116,7 +116,7 @@ BVHTree *bvhtree_build_from_mvert ( MFace *mfaces, unsigned int numfaces, MVert
return tree;
}
-void bvhtree_update_from_mvert(BVHTree * bvhtree, MFace *faces, int numfaces, MVert *x, MVert *xnew, int UNUSED(numverts), int moving )
+void bvhtree_update_from_mvert(BVHTree *bvhtree, MFace *faces, int numfaces, MVert *x, MVert *xnew, int UNUSED(numverts), int moving )
{
int i;
MFace *mfaces = faces;
@@ -654,7 +654,7 @@ static void cloth_bvh_objcollisions_nearcheck ( ClothModifierData * clmd, Collis
{
int i;
- *collisions = (CollPair *) MEM_mallocN(sizeof(CollPair) * numresult * 64, "collision array" ); //*4 since cloth_collision_static can return more than 1 collision
+ *collisions = (CollPair *) MEM_mallocN(sizeof(CollPair) * numresult * 64, "collision array" ); // * 4 since cloth_collision_static can return more than 1 collision
*collisions_index = *collisions;
for ( i = 0; i < numresult; i++ ) {
@@ -706,7 +706,7 @@ static int cloth_bvh_objcollisions_resolve ( ClothModifierData * clmd, Collision
}
// cloth - object collisions
-int cloth_bvh_objcollision(Object *ob, ClothModifierData * clmd, float step, float dt )
+int cloth_bvh_objcollision(Object *ob, ClothModifierData *clmd, float step, float dt )
{
Cloth *cloth= clmd->clothObject;
BVHTree *cloth_bvh= cloth->bvhtree;
diff --git a/source/blender/blenkernel/intern/colortools.c b/source/blender/blenkernel/intern/colortools.c
index d08c16eac9e..5176f93f4f3 100644
--- a/source/blender/blenkernel/intern/colortools.c
+++ b/source/blender/blenkernel/intern/colortools.c
@@ -199,7 +199,9 @@ int curvemap_remove_point(CurveMap *cuma, CurveMapPoint *point)
cmp[b] = cuma->curve[a];
b++;
}
- else removed++;
+ else {
+ removed++;
+ }
}
MEM_freeN(cuma->curve);
@@ -221,7 +223,9 @@ void curvemap_remove(CurveMap *cuma, const short flag)
cmp[b] = cuma->curve[a];
b++;
}
- else removed++;
+ else {
+ removed++;
+ }
}
cmp[b] = cuma->curve[a];
diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c
index 48ad3f51389..3430c2ea7a1 100644
--- a/source/blender/blenkernel/intern/constraint.c
+++ b/source/blender/blenkernel/intern/constraint.c
@@ -817,7 +817,7 @@ static void childof_evaluate(bConstraint *con, bConstraintOb *cob, ListBase *tar
static bConstraintTypeInfo CTI_CHILDOF = {
CONSTRAINT_TYPE_CHILDOF, /* type */
sizeof(bChildOfConstraint), /* size */
- "ChildOf", /* name */
+ "Child Of", /* name */
"bChildOfConstraint", /* struct name */
NULL, /* free data */
childof_id_looper, /* id looper */
@@ -992,7 +992,7 @@ static void trackto_evaluate(bConstraint *con, bConstraintOb *cob, ListBase *tar
static bConstraintTypeInfo CTI_TRACKTO = {
CONSTRAINT_TYPE_TRACKTO, /* type */
sizeof(bTrackToConstraint), /* size */
- "TrackTo", /* name */
+ "Track To", /* name */
"bTrackToConstraint", /* struct name */
NULL, /* free data */
trackto_id_looper, /* id looper */
diff --git a/source/blender/blenkernel/intern/context.c b/source/blender/blenkernel/intern/context.c
index a9e3d52f223..d899990a66a 100644
--- a/source/blender/blenkernel/intern/context.c
+++ b/source/blender/blenkernel/intern/context.c
@@ -27,7 +27,6 @@
* \ingroup bke
*/
-
#include <string.h>
#include <stdlib.h>
#include <stddef.h>
@@ -41,8 +40,6 @@
#include "DNA_windowmanager_types.h"
#include "DNA_object_types.h"
-#include "RNA_access.h"
-
#include "BLI_listbase.h"
#include "BLI_string.h"
#include "BLI_threads.h"
@@ -54,8 +51,10 @@
#include "BKE_main.h"
#include "BKE_screen.h"
+#include "RNA_access.h"
+
#ifdef WITH_PYTHON
-#include "BPY_extern.h"
+# include "BPY_extern.h"
#endif
/* struct */
diff --git a/source/blender/blenkernel/intern/curve.c b/source/blender/blenkernel/intern/curve.c
index 2da75ec64be..5d2c85e5825 100644
--- a/source/blender/blenkernel/intern/curve.c
+++ b/source/blender/blenkernel/intern/curve.c
@@ -793,7 +793,9 @@ static void makeknots(Nurb *nu, short uv)
calcknots(nu->knotsv, nu->pntsv, nu->orderv, nu->flagv);
}
}
- else nu->knotsv = NULL;
+ else {
+ nu->knotsv = NULL;
+ }
}
}
}
@@ -3317,76 +3319,76 @@ void BKE_curve_keyVertexTilts_apply(Curve *UNUSED(cu), ListBase *lb, float *key)
}
}
-int BKE_nurb_check_valid_u(struct Nurb *nu)
+bool BKE_nurb_check_valid_u(struct Nurb *nu)
{
if (nu == NULL)
- return 0;
+ return false;
if (nu->pntsu <= 1)
- return 0;
+ return false;
if (nu->type != CU_NURBS)
- return 1; /* not a nurb, lets assume its valid */
+ return true; /* not a nurb, lets assume its valid */
- if (nu->pntsu < nu->orderu) return 0;
+ if (nu->pntsu < nu->orderu) return false;
if (((nu->flag & CU_NURB_CYCLIC) == 0) && (nu->flagu & CU_NURB_BEZIER)) { /* Bezier U Endpoints */
if (nu->orderu == 4) {
if (nu->pntsu < 5)
- return 0; /* bezier with 4 orderu needs 5 points */
+ return false; /* bezier with 4 orderu needs 5 points */
}
else {
if (nu->orderu != 3)
- return 0; /* order must be 3 or 4 */
+ return false; /* order must be 3 or 4 */
}
}
- return 1;
+ return true;
}
-int BKE_nurb_check_valid_v(struct Nurb *nu)
+bool BKE_nurb_check_valid_v(struct Nurb *nu)
{
if (nu == NULL)
- return 0;
+ return false;
if (nu->pntsv <= 1)
- return 0;
+ return false;
if (nu->type != CU_NURBS)
- return 1; /* not a nurb, lets assume its valid */
+ return true; /* not a nurb, lets assume its valid */
if (nu->pntsv < nu->orderv)
- return 0;
+ return false;
if (((nu->flag & CU_NURB_CYCLIC) == 0) && (nu->flagv & CU_NURB_BEZIER)) { /* Bezier V Endpoints */
if (nu->orderv == 4) {
if (nu->pntsv < 5)
- return 0; /* bezier with 4 orderu needs 5 points */
+ return false; /* bezier with 4 orderu needs 5 points */
}
else {
if (nu->orderv != 3)
- return 0; /* order must be 3 or 4 */
+ return false; /* order must be 3 or 4 */
}
}
- return 1;
+ return true;
}
-int BKE_nurb_order_clamp_u(struct Nurb *nu)
+bool BKE_nurb_order_clamp_u(struct Nurb *nu)
{
- int change = 0;
+ bool change = false;
if (nu->pntsu < nu->orderu) {
nu->orderu = nu->pntsu;
- change = 1;
+ change = true;
}
if (((nu->flagu & CU_NURB_CYCLIC) == 0) && (nu->flagu & CU_NURB_BEZIER)) {
CLAMP(nu->orderu, 3, 4);
- change = 1;
+ change = true;
}
return change;
}
-int BKE_nurb_order_clamp_v(struct Nurb *nu)
+bool BKE_nurb_order_clamp_v(struct Nurb *nu)
{
- int change = 0;
+ bool change = false;
if (nu->pntsv < nu->orderv) {
nu->orderv = nu->pntsv;
- change = 1;
+ change = true;
}
if (((nu->flagv & CU_NURB_CYCLIC) == 0) && (nu->flagv & CU_NURB_BEZIER)) {
CLAMP(nu->orderv, 3, 4);
- change = 1;
+ change = true;
}
return change;
}
@@ -3403,7 +3405,7 @@ ListBase *BKE_curve_nurbs_get(Curve *cu)
/* basic vertex data functions */
-int BKE_curve_minmax(Curve *cu, float min[3], float max[3])
+bool BKE_curve_minmax(Curve *cu, float min[3], float max[3])
{
ListBase *nurb_lb = BKE_curve_nurbs_get(cu);
Nurb *nu;
@@ -3414,7 +3416,7 @@ int BKE_curve_minmax(Curve *cu, float min[3], float max[3])
return (nurb_lb->first != NULL);
}
-int BKE_curve_center_median(Curve *cu, float cent[3])
+bool BKE_curve_center_median(Curve *cu, float cent[3])
{
ListBase *nurb_lb = BKE_curve_nurbs_get(cu);
Nurb *nu;
@@ -3452,16 +3454,16 @@ int BKE_curve_center_median(Curve *cu, float cent[3])
return (total != 0);
}
-int BKE_curve_center_bounds(Curve *cu, float cent[3])
+bool BKE_curve_center_bounds(Curve *cu, float cent[3])
{
float min[3], max[3];
INIT_MINMAX(min, max);
if (BKE_curve_minmax(cu, min, max)) {
mid_v3_v3v3(cent, min, max);
- return 1;
+ return true;
}
- return 0;
+ return false;
}
void BKE_curve_translate(Curve *cu, float offset[3], int do_keys)
diff --git a/source/blender/blenkernel/intern/customdata.c b/source/blender/blenkernel/intern/customdata.c
index 48d7ae1de86..e91fd0cc929 100644
--- a/source/blender/blenkernel/intern/customdata.c
+++ b/source/blender/blenkernel/intern/customdata.c
@@ -195,7 +195,7 @@ static void layerCopy_bmesh_elem_py_ptr(const void *UNUSED(source), void *dest,
}
#ifndef WITH_PYTHON
-void bpy_bm_generic_invalidate(void *UNUSED(self))
+void bpy_bm_generic_invalidate(struct BPy_BMGeneric *UNUSED(self))
{
/* dummy */
}
@@ -203,8 +203,6 @@ void bpy_bm_generic_invalidate(void *UNUSED(self))
static void layerFree_bmesh_elem_py_ptr(void *data, int count, int size)
{
- extern void bpy_bm_generic_invalidate(void *self);
-
int i;
for (i = 0; i < count; ++i) {
@@ -1174,7 +1172,7 @@ const CustomDataMask CD_MASK_MESH =
CD_MASK_MSTICKY | CD_MASK_MDEFORMVERT | CD_MASK_MTFACE | CD_MASK_MCOL |
CD_MASK_PROP_FLT | CD_MASK_PROP_INT | CD_MASK_PROP_STR | CD_MASK_MDISPS |
CD_MASK_MLOOPUV | CD_MASK_MLOOPCOL | CD_MASK_MPOLY | CD_MASK_MLOOP |
- CD_MASK_MTEXPOLY | CD_MASK_NORMAL | CD_MASK_RECAST | CD_MASK_PAINT_MASK |
+ CD_MASK_MTEXPOLY | CD_MASK_RECAST | CD_MASK_PAINT_MASK |
CD_MASK_GRID_PAINT_MASK | CD_MASK_MVERT_SKIN | CD_MASK_FREESTYLE_EDGE | CD_MASK_FREESTYLE_FACE;
const CustomDataMask CD_MASK_EDITMESH =
CD_MASK_MSTICKY | CD_MASK_MDEFORMVERT | CD_MASK_MTFACE | CD_MASK_MLOOPUV |
@@ -2866,7 +2864,7 @@ static int CustomData_is_property_layer(int type)
return 0;
}
-static int cd_layer_find_dupe(CustomData *data, const char *name, int type, int index)
+static bool cd_layer_find_dupe(CustomData *data, const char *name, int type, int index)
{
int i;
/* see if there is a duplicate */
@@ -2876,21 +2874,21 @@ static int cd_layer_find_dupe(CustomData *data, const char *name, int type, int
if (CustomData_is_property_layer(type)) {
if (CustomData_is_property_layer(layer->type) && strcmp(layer->name, name) == 0) {
- return 1;
+ return true;
}
}
else {
if (i != index && layer->type == type && strcmp(layer->name, name) == 0) {
- return 1;
+ return true;
}
}
}
}
- return 0;
+ return false;
}
-static int customdata_unique_check(void *arg, const char *name)
+static bool customdata_unique_check(void *arg, const char *name)
{
struct {CustomData *data; int type; int index; } *data_arg = arg;
return cd_layer_find_dupe(data_arg->data, name, data_arg->type, data_arg->index);
diff --git a/source/blender/blenkernel/intern/customdata_file.c b/source/blender/blenkernel/intern/customdata_file.c
index 78449879f72..c72eea50e40 100644
--- a/source/blender/blenkernel/intern/customdata_file.c
+++ b/source/blender/blenkernel/intern/customdata_file.c
@@ -29,9 +29,9 @@
#include "MEM_guardedalloc.h"
+#include "BLI_utildefines.h"
#include "BLI_fileops.h"
#include "BLI_string.h"
-#include "BLI_utildefines.h"
#include "BLI_endian_switch.h"
#include "BKE_customdata_file.h"
@@ -404,7 +404,7 @@ void cdf_write_close(CDataFile *cdf)
void cdf_remove(const char *filename)
{
- BLI_delete(filename, 0, 0);
+ BLI_delete(filename, false, false);
}
/********************************** Layers ***********************************/
diff --git a/source/blender/blenkernel/intern/deform.c b/source/blender/blenkernel/intern/deform.c
index 439180e8d76..2ba71ecd9b5 100644
--- a/source/blender/blenkernel/intern/deform.c
+++ b/source/blender/blenkernel/intern/deform.c
@@ -432,22 +432,22 @@ int defgroup_flip_index(Object *ob, int index, int use_default)
return (flip_index == -1 && use_default) ? index : flip_index;
}
-static int defgroup_find_name_dupe(const char *name, bDeformGroup *dg, Object *ob)
+static bool defgroup_find_name_dupe(const char *name, bDeformGroup *dg, Object *ob)
{
bDeformGroup *curdef;
for (curdef = ob->defbase.first; curdef; curdef = curdef->next) {
if (dg != curdef) {
if (!strcmp(curdef->name, name)) {
- return 1;
+ return true;
}
}
}
- return 0;
+ return false;
}
-static int defgroup_unique_check(void *arg, const char *name)
+static bool defgroup_unique_check(void *arg, const char *name)
{
struct {Object *ob; void *dg; } *data = arg;
return defgroup_find_name_dupe(name, data->dg, data->ob);
diff --git a/source/blender/blenkernel/intern/depsgraph.c b/source/blender/blenkernel/intern/depsgraph.c
index b919b9ffd8f..3a531cf32ae 100644
--- a/source/blender/blenkernel/intern/depsgraph.c
+++ b/source/blender/blenkernel/intern/depsgraph.c
@@ -1555,7 +1555,9 @@ static unsigned int flush_layer_node(Scene *sce, DagNode *node, int curtime)
if (itA->node->lasttime != curtime) {
itA->lay = flush_layer_node(sce, itA->node, curtime); /* lay is only set once for each relation */
}
- else itA->lay = itA->node->lay;
+ else {
+ itA->lay = itA->node->lay;
+ }
node->lay |= itA->lay;
}
diff --git a/source/blender/blenkernel/intern/dynamicpaint.c b/source/blender/blenkernel/intern/dynamicpaint.c
index 685d66195c7..4b05f1c1050 100644
--- a/source/blender/blenkernel/intern/dynamicpaint.c
+++ b/source/blender/blenkernel/intern/dynamicpaint.c
@@ -340,7 +340,7 @@ int dynamicPaint_outputLayerExists(struct DynamicPaintSurface *surface, Object *
return 0;
}
-static int surface_duplicateOutputExists(void *arg, const char *name)
+static bool surface_duplicateOutputExists(void *arg, const char *name)
{
DynamicPaintSurface *t_surface = (DynamicPaintSurface *)arg;
DynamicPaintSurface *surface = t_surface->canvas->surfaces.first;
@@ -349,11 +349,11 @@ static int surface_duplicateOutputExists(void *arg, const char *name)
if (surface != t_surface && surface->type == t_surface->type &&
surface->format == t_surface->format)
{
- if (surface->output_name[0] != '\0' && !BLI_path_cmp(name, surface->output_name)) return 1;
- if (surface->output_name2[0] != '\0' && !BLI_path_cmp(name, surface->output_name2)) return 1;
+ if (surface->output_name[0] != '\0' && !BLI_path_cmp(name, surface->output_name)) return true;
+ if (surface->output_name2[0] != '\0' && !BLI_path_cmp(name, surface->output_name2)) return true;
}
}
- return 0;
+ return false;
}
static void surface_setUniqueOutputName(DynamicPaintSurface *surface, char *basename, int output)
@@ -367,15 +367,15 @@ static void surface_setUniqueOutputName(DynamicPaintSurface *surface, char *base
}
-static int surface_duplicateNameExists(void *arg, const char *name)
+static bool surface_duplicateNameExists(void *arg, const char *name)
{
DynamicPaintSurface *t_surface = (DynamicPaintSurface *)arg;
DynamicPaintSurface *surface = t_surface->canvas->surfaces.first;
for (; surface; surface = surface->next) {
- if (surface != t_surface && !strcmp(name, surface->name)) return 1;
+ if (surface != t_surface && !strcmp(name, surface->name)) return true;
}
- return 0;
+ return false;
}
void dynamicPaintSurface_setUniqueName(DynamicPaintSurface *surface, const char *basename)
@@ -473,7 +473,9 @@ static float mixColors(float a_color[3], float a_weight, float b_color[3], float
}
weight_ratio = b_weight / (a_weight + b_weight);
}
- else return a_weight * (1.0f - ratio);
+ else {
+ return a_weight * (1.0f - ratio);
+ }
/* calculate final interpolation factor */
if (ratio <= 0.5f) {
@@ -2606,7 +2608,9 @@ int dynamicPaint_createUVSurface(DynamicPaintSurface *surface)
if (!f_data->uv_p || !f_data->barycentricWeights) error = 1;
}
- else error = 1;
+ else {
+ error = 1;
+ }
sData->total_points = active_points;
@@ -2859,7 +2863,9 @@ static void dynamicPaint_doMaterialTex(BrushMaterials *bMats, float color[3], fl
mat = bMats->ob_mats[mat_nr];
if (mat == NULL) return; /* No material assigned */
}
- else return;
+ else {
+ return;
+ }
}
RE_sample_material_color(mat, color, alpha, volume_co, surface_co, faceIndex, isQuad, orcoDm, brushOb);
@@ -3924,7 +3930,9 @@ static int dynamicPaint_paintSinglePoint(DynamicPaintSurface *surface, float *po
strength = 1.0f - distance / brush_radius;
CLAMP(strength, 0.0f, 1.0f);
}
- else strength = 1.0f;
+ else {
+ strength = 1.0f;
+ }
if (strength >= 0.001f) {
float paintColor[3] = {0.0f};
diff --git a/source/blender/blenkernel/intern/font.c b/source/blender/blenkernel/intern/font.c
index 3e1e55132d8..b3edeb67928 100644
--- a/source/blender/blenkernel/intern/font.c
+++ b/source/blender/blenkernel/intern/font.c
@@ -101,9 +101,9 @@ void BKE_vfont_free(struct VFont *vf)
static void *builtin_font_data = NULL;
static int builtin_font_size = 0;
-int BKE_vfont_is_builtin(struct VFont *vfont)
+bool BKE_vfont_is_builtin(struct VFont *vfont)
{
- return (strcmp(vfont->name, FO_BUILTIN_NAME) == 0);
+ return STREQ(vfont->name, FO_BUILTIN_NAME);
}
void BKE_vfont_builtin_register(void *mem, int size)
@@ -188,18 +188,14 @@ VFont *BKE_vfont_load(Main *bmain, const char *name)
PackedFile *temp_pf = NULL;
int is_builtin;
- if (strcmp(name, FO_BUILTIN_NAME) == 0) {
+ if (STREQ(name, FO_BUILTIN_NAME)) {
BLI_strncpy(filename, name, sizeof(filename));
pf = get_builtin_packedfile();
is_builtin = TRUE;
}
else {
- char dir[FILE_MAXDIR];
-
- BLI_strncpy(dir, name, sizeof(dir));
- BLI_splitdirstring(dir, filename);
-
+ BLI_split_file_part(name, filename, sizeof(filename));
pf = newPackedFile(NULL, name, bmain->name);
temp_pf = newPackedFile(NULL, name, bmain->name);
@@ -947,10 +943,13 @@ makebreak:
ct = chartransdata;
for (i = 0; i < slen; i++) {
if (ct->linenr == lnr) {
- if (ct->charnr == cnr) break;
- if ( (ct + 1)->charnr == 0) break;
+ if ((ct->charnr == cnr) || ((ct + 1)->charnr == 0)) {
+ break;
+ }
+ }
+ else if (ct->linenr > lnr) {
+ break;
}
- else if (ct->linenr > lnr) break;
cu->pos++;
ct++;
}
diff --git a/source/blender/blenkernel/intern/idcode.c b/source/blender/blenkernel/intern/idcode.c
index 8fab0f2d4df..11d3e69120d 100644
--- a/source/blender/blenkernel/intern/idcode.c
+++ b/source/blender/blenkernel/intern/idcode.c
@@ -30,12 +30,13 @@
* \ingroup bke
*/
-
#include <stdlib.h>
#include <string.h>
#include "DNA_ID.h"
+#include "BLI_utildefines.h"
+
#include "BKE_idcode.h"
typedef struct {
@@ -91,9 +92,11 @@ static IDType *idtype_from_name(const char *str)
{
int i = nidtypes;
- while (i--)
- if (strcmp(str, idtypes[i].name) == 0)
+ while (i--) {
+ if (STREQ(str, idtypes[i].name)) {
return &idtypes[i];
+ }
+ }
return NULL;
}
@@ -108,15 +111,15 @@ static IDType *idtype_from_code(int code)
return NULL;
}
-int BKE_idcode_is_valid(int code)
+bool BKE_idcode_is_valid(int code)
{
- return idtype_from_code(code) ? 1 : 0;
+ return idtype_from_code(code) ? true : false;
}
-int BKE_idcode_is_linkable(int code)
+bool BKE_idcode_is_linkable(int code)
{
IDType *idt = idtype_from_code(code);
- return idt ? (idt->flags & IDTYPE_FLAGS_ISLINKABLE) : 0;
+ return idt ? ((idt->flags & IDTYPE_FLAGS_ISLINKABLE) != 0) : false;
}
const char *BKE_idcode_to_name(int code)
diff --git a/source/blender/blenkernel/intern/idprop.c b/source/blender/blenkernel/intern/idprop.c
index 19ef1e3971d..8dc284e0a3e 100644
--- a/source/blender/blenkernel/intern/idprop.c
+++ b/source/blender/blenkernel/intern/idprop.c
@@ -451,7 +451,7 @@ void IDP_ReplaceGroupInGroup(IDProperty *dest, IDProperty *src)
IDProperty *loop, *prop;
for (prop = src->data.group.first; prop; prop = prop->next) {
for (loop = dest->data.group.first; loop; loop = loop->next) {
- if (strcmp(loop->name, prop->name) == 0) {
+ if (STREQ(loop->name, prop->name)) {
IDProperty *copy = IDP_CopyProperty(prop);
BLI_insertlinkafter(&dest->data.group, loop, copy);
diff --git a/source/blender/blenkernel/intern/image.c b/source/blender/blenkernel/intern/image.c
index 3655afdf088..c27f5e62520 100644
--- a/source/blender/blenkernel/intern/image.c
+++ b/source/blender/blenkernel/intern/image.c
@@ -1042,7 +1042,7 @@ char BKE_ftype_to_imtype(const int ftype)
}
-int BKE_imtype_is_movie(const char imtype)
+bool BKE_imtype_is_movie(const char imtype)
{
switch (imtype) {
case R_IMF_IMTYPE_AVIRAW:
@@ -1053,9 +1053,9 @@ int BKE_imtype_is_movie(const char imtype)
case R_IMF_IMTYPE_THEORA:
case R_IMF_IMTYPE_XVID:
case R_IMF_IMTYPE_FRAMESERVER:
- return 1;
+ return true;
}
- return 0;
+ return false;
}
int BKE_imtype_supports_zbuf(const char imtype)
@@ -1567,7 +1567,9 @@ static void stampdata(Scene *scene, Object *camera, StampData *stamp_data, int d
if (camera && camera->type == OB_CAMERA) {
BLI_snprintf(text, sizeof(text), "%.2f", ((Camera *)camera->data)->lens);
}
- else BLI_strncpy(text, "<none>", sizeof(text));
+ else {
+ BLI_strncpy(text, "<none>", sizeof(text));
+ }
BLI_snprintf(stamp_data->cameralens, sizeof(stamp_data->cameralens), do_prefix ? "Lens %s" : "%s", text);
}
@@ -1944,7 +1946,7 @@ int BKE_imbuf_write(ImBuf *ibuf, const char *name, ImageFormatData *imf)
else if (imtype == R_IMF_IMTYPE_DPX) {
ibuf->ftype = DPX;
if (imf->cineon_flag & R_IMF_CINEON_FLAG_LOG) {
- ibuf->ftype |= CINEON_LOG;
+ ibuf->ftype |= CINEON_LOG;
}
if (imf->depth == R_IMF_CHAN_DEPTH_16) {
ibuf->ftype |= CINEON_16BIT;
diff --git a/source/blender/blenkernel/intern/image_gen.c b/source/blender/blenkernel/intern/image_gen.c
index 468a88775c6..415f0a87431 100644
--- a/source/blender/blenkernel/intern/image_gen.c
+++ b/source/blender/blenkernel/intern/image_gen.c
@@ -24,13 +24,14 @@
* \ingroup bke
*/
-
#include <math.h>
#include <stdlib.h>
-#include "BKE_image.h"
#include "BLI_math_color.h"
#include "BLI_math_base.h"
+
+#include "BKE_image.h"
+
#include "BLF_api.h"
void BKE_image_buf_fill_color(unsigned char *rect, float *rect_float, int width, int height, const float color[4])
diff --git a/source/blender/blenkernel/intern/implicit.c b/source/blender/blenkernel/intern/implicit.c
index 90cd7bc2df5..b9064fe8ba3 100644
--- a/source/blender/blenkernel/intern/implicit.c
+++ b/source/blender/blenkernel/intern/implicit.c
@@ -1716,7 +1716,7 @@ static void simulate_implicit_euler(lfVector *Vnew, lfVector *UNUSED(lX), lfVect
* (edge distance constraints) in a lagrangian solver. then add forces to help
* guide the implicit solver to that state. this function is called after
* collisions*/
-static int UNUSED_FUNCTION(cloth_calc_helper_forces)(Object *UNUSED(ob), ClothModifierData * clmd, float (*initial_cos)[3], float UNUSED(step), float dt)
+static int UNUSED_FUNCTION(cloth_calc_helper_forces)(Object *UNUSED(ob), ClothModifierData *clmd, float (*initial_cos)[3], float UNUSED(step), float dt)
{
Cloth *cloth= clmd->clothObject;
float (*cos)[3] = MEM_callocN(sizeof(float)*3*cloth->numverts, "cos cloth_calc_helper_forces");
diff --git a/source/blender/blenkernel/intern/key.c b/source/blender/blenkernel/intern/key.c
index f3dc391738e..d123de224e9 100644
--- a/source/blender/blenkernel/intern/key.c
+++ b/source/blender/blenkernel/intern/key.c
@@ -405,9 +405,13 @@ static int setkeys(float fac, ListBase *lb, KeyBlock *k[], float t[4], int cycl)
k1 = firstkey;
ofs += dpos;
}
- else if (t[2] == t[3]) break;
+ else if (t[2] == t[3]) {
+ break;
+ }
+ }
+ else {
+ k1 = k1->next;
}
- else k1 = k1->next;
t[0] = t[1];
k[0] = k[1];
@@ -595,7 +599,9 @@ static void cp_key(const int start, int end, const int tot, char *poin, Key *key
k1 += a * key->elemsize;
}
}
- else k1 += start * key->elemsize;
+ else {
+ k1 += start * key->elemsize;
+ }
}
if (mode == KEY_MODE_BEZTRIPLE) {
@@ -828,7 +834,9 @@ static void do_key(const int start, int end, const int tot, char *poin, Key *key
if (k[0]->totelem) {
k1d = k[0]->totelem / (float)tot;
}
- else flagdo -= 1;
+ else {
+ flagdo -= 1;
+ }
}
if (tot != k[1]->totelem) {
k2tot = 0.0;
@@ -836,7 +844,9 @@ static void do_key(const int start, int end, const int tot, char *poin, Key *key
if (k[0]->totelem) {
k2d = k[1]->totelem / (float)tot;
}
- else flagdo -= 2;
+ else {
+ flagdo -= 2;
+ }
}
if (tot != k[2]->totelem) {
k3tot = 0.0;
@@ -844,7 +854,9 @@ static void do_key(const int start, int end, const int tot, char *poin, Key *key
if (k[0]->totelem) {
k3d = k[2]->totelem / (float)tot;
}
- else flagdo -= 4;
+ else {
+ flagdo -= 4;
+ }
}
if (tot != k[3]->totelem) {
k4tot = 0.0;
@@ -852,7 +864,9 @@ static void do_key(const int start, int end, const int tot, char *poin, Key *key
if (k[0]->totelem) {
k4d = k[3]->totelem / (float)tot;
}
- else flagdo -= 8;
+ else {
+ flagdo -= 8;
+ }
}
/* this exception needed for slurphing */
@@ -869,7 +883,9 @@ static void do_key(const int start, int end, const int tot, char *poin, Key *key
k1 += a * key->elemsize;
}
}
- else k1 += start * key->elemsize;
+ else {
+ k1 += start * key->elemsize;
+ }
}
if (flagdo & 2) {
if (flagflo & 2) {
@@ -880,7 +896,9 @@ static void do_key(const int start, int end, const int tot, char *poin, Key *key
k2 += a * key->elemsize;
}
}
- else k2 += start * key->elemsize;
+ else {
+ k2 += start * key->elemsize;
+ }
}
if (flagdo & 4) {
if (flagflo & 4) {
@@ -891,7 +909,9 @@ static void do_key(const int start, int end, const int tot, char *poin, Key *key
k3 += a * key->elemsize;
}
}
- else k3 += start * key->elemsize;
+ else {
+ k3 += start * key->elemsize;
+ }
}
if (flagdo & 8) {
if (flagflo & 8) {
@@ -902,7 +922,9 @@ static void do_key(const int start, int end, const int tot, char *poin, Key *key
k4 += a * key->elemsize;
}
}
- else k4 += start * key->elemsize;
+ else {
+ k4 += start * key->elemsize;
+ }
}
}
@@ -968,7 +990,9 @@ static void do_key(const int start, int end, const int tot, char *poin, Key *key
k2 += elemsize;
}
}
- else k2 += elemsize;
+ else {
+ k2 += elemsize;
+ }
}
if (flagdo & 4) {
if (flagflo & 4) {
@@ -978,7 +1002,9 @@ static void do_key(const int start, int end, const int tot, char *poin, Key *key
k3 += elemsize;
}
}
- else k3 += elemsize;
+ else {
+ k3 += elemsize;
+ }
}
if (flagdo & 8) {
if (flagflo & 8) {
@@ -988,7 +1014,9 @@ static void do_key(const int start, int end, const int tot, char *poin, Key *key
k4 += elemsize;
}
}
- else k4 += elemsize;
+ else {
+ k4 += elemsize;
+ }
}
if (mode == KEY_MODE_BEZTRIPLE) a += 2;
diff --git a/source/blender/blenkernel/intern/lattice.c b/source/blender/blenkernel/intern/lattice.c
index c3e7a963c04..c881209b109 100644
--- a/source/blender/blenkernel/intern/lattice.c
+++ b/source/blender/blenkernel/intern/lattice.c
@@ -404,9 +404,11 @@ void calc_latt_deform(Object *ob, float co[3], float weight)
if (w != 0.0f) {
if (ww > 0) {
if (ww < lt->pntsw) idx_w = ww * lt->pntsu * lt->pntsv;
- else idx_w = (lt->pntsw - 1) * lt->pntsu * lt->pntsv;
+ else idx_w = (lt->pntsw - 1) * lt->pntsu * lt->pntsv;
+ }
+ else {
+ idx_w = 0;
}
- else idx_w = 0;
for (vv = vi - 1; vv <= vi + 2; vv++) {
v = w * tv[vv - vi + 1];
@@ -414,9 +416,11 @@ void calc_latt_deform(Object *ob, float co[3], float weight)
if (v != 0.0f) {
if (vv > 0) {
if (vv < lt->pntsv) idx_v = idx_w + vv * lt->pntsu;
- else idx_v = idx_w + (lt->pntsv - 1) * lt->pntsu;
+ else idx_v = idx_w + (lt->pntsv - 1) * lt->pntsu;
+ }
+ else {
+ idx_v = idx_w;
}
- else idx_v = idx_w;
for (uu = ui - 1; uu <= ui + 2; uu++) {
u = weight * v * tu[uu - ui + 1];
@@ -424,9 +428,11 @@ void calc_latt_deform(Object *ob, float co[3], float weight)
if (u != 0.0f) {
if (uu > 0) {
if (uu < lt->pntsu) idx_u = idx_v + uu;
- else idx_u = idx_v + (lt->pntsu - 1);
+ else idx_u = idx_v + (lt->pntsu - 1);
+ }
+ else {
+ idx_u = idx_v;
}
- else idx_u = idx_v;
madd_v3_v3fl(co, &lt->latticedata[idx_u * 3], u);
@@ -492,7 +498,9 @@ static int where_on_path_deform(Object *ob, float ctime, float vec[4], float dir
if (cycl == 0) {
ctime1 = CLAMPIS(ctime, 0.0f, 1.0f);
}
- else ctime1 = ctime;
+ else {
+ ctime1 = ctime;
+ }
/* vec needs 4 items */
if (where_on_path(ob, ctime1, vec, dir, quat, radius, NULL)) {
diff --git a/source/blender/blenkernel/intern/library.c b/source/blender/blenkernel/intern/library.c
index b4c1d681ddc..67fc5bd5dca 100644
--- a/source/blender/blenkernel/intern/library.c
+++ b/source/blender/blenkernel/intern/library.c
@@ -174,6 +174,7 @@ void id_us_plus(ID *id)
}
}
+/* decrements the user count for *id. */
void id_us_min(ID *id)
{
if (id) {
@@ -189,106 +190,112 @@ void id_us_min(ID *id)
}
}
-int id_make_local(ID *id, int test)
+/* calls the appropriate make_local method for the block, unless test. Returns true
+ * if the block can be made local. */
+bool id_make_local(ID *id, bool test)
{
if (id->flag & LIB_INDIRECT)
- return 0;
+ return false;
switch (GS(id->name)) {
case ID_SCE:
- return 0; /* not implemented */
+ return false; /* not implemented */
case ID_LI:
- return 0; /* can't be linked */
+ return false; /* can't be linked */
case ID_OB:
if (!test) BKE_object_make_local((Object *)id);
- return 1;
+ return true;
case ID_ME:
if (!test) {
BKE_mesh_make_local((Mesh *)id);
BKE_key_make_local(((Mesh *)id)->key);
}
- return 1;
+ return true;
case ID_CU:
if (!test) {
BKE_curve_make_local((Curve *)id);
BKE_key_make_local(((Curve *)id)->key);
}
- return 1;
+ return true;
case ID_MB:
if (!test) BKE_mball_make_local((MetaBall *)id);
- return 1;
+ return true;
case ID_MA:
if (!test) BKE_material_make_local((Material *)id);
- return 1;
+ return true;
case ID_TE:
if (!test) BKE_texture_make_local((Tex *)id);
- return 1;
+ return true;
case ID_IM:
if (!test) BKE_image_make_local((Image *)id);
- return 1;
+ return true;
case ID_LT:
if (!test) {
BKE_lattice_make_local((Lattice *)id);
BKE_key_make_local(((Lattice *)id)->key);
}
- return 1;
+ return true;
case ID_LA:
if (!test) BKE_lamp_make_local((Lamp *)id);
- return 1;
+ return true;
case ID_CA:
if (!test) BKE_camera_make_local((Camera *)id);
- return 1;
+ return true;
case ID_SPK:
if (!test) BKE_speaker_make_local((Speaker *)id);
- return 1;
+ return true;
case ID_IP:
- return 0; /* deprecated */
+ return false; /* deprecated */
case ID_KE:
if (!test) BKE_key_make_local((Key *)id);
- return 1;
+ return true;
case ID_WO:
if (!test) BKE_world_make_local((World *)id);
- return 1;
+ return true;
case ID_SCR:
- return 0; /* can't be linked */
+ return false; /* can't be linked */
case ID_VF:
- return 0; /* not implemented */
+ return false; /* not implemented */
case ID_TXT:
- return 0; /* not implemented */
+ return false; /* not implemented */
case ID_SCRIPT:
- return 0; /* deprecated */
+ return false; /* deprecated */
case ID_SO:
- return 0; /* not implemented */
+ return false; /* not implemented */
case ID_GR:
- return 0; /* not implemented */
+ return false; /* not implemented */
case ID_AR:
if (!test) BKE_armature_make_local((bArmature *)id);
- return 1;
+ return true;
case ID_AC:
if (!test) BKE_action_make_local((bAction *)id);
- return 1;
+ return true;
case ID_NT:
- return 0; /* not implemented */
+ return false; /* not implemented */
case ID_BR:
if (!test) BKE_brush_make_local((Brush *)id);
- return 1;
+ return true;
case ID_PA:
if (!test) BKE_particlesettings_make_local((ParticleSettings *)id);
- return 1;
+ return true;
case ID_WM:
- return 0; /* can't be linked */
+ return false; /* can't be linked */
case ID_GD:
- return 0; /* not implemented */
+ return false; /* not implemented */
#ifdef WITH_FREESTYLE
case ID_LS:
return 0; /* not implemented */
#endif
}
- return 0;
+ return false;
}
-int id_copy(ID *id, ID **newid, int test)
+/**
+ * Invokes the appropriate copy method for the block and returns the result in
+ * newid, unless test. Returns true iff the block can be copied.
+ */
+bool id_copy(ID *id, ID **newid, bool test)
{
if (!test) *newid = NULL;
@@ -297,86 +304,86 @@ int id_copy(ID *id, ID **newid, int test)
* - id.us of the new ID is set to 1 */
switch (GS(id->name)) {
case ID_SCE:
- return 0; /* can't be copied from here */
+ return false; /* can't be copied from here */
case ID_LI:
- return 0; /* can't be copied from here */
+ return false; /* can't be copied from here */
case ID_OB:
if (!test) *newid = (ID *)BKE_object_copy((Object *)id);
- return 1;
+ return true;
case ID_ME:
if (!test) *newid = (ID *)BKE_mesh_copy((Mesh *)id);
- return 1;
+ return true;
case ID_CU:
if (!test) *newid = (ID *)BKE_curve_copy((Curve *)id);
- return 1;
+ return true;
case ID_MB:
if (!test) *newid = (ID *)BKE_mball_copy((MetaBall *)id);
- return 1;
+ return true;
case ID_MA:
if (!test) *newid = (ID *)BKE_material_copy((Material *)id);
- return 1;
+ return true;
case ID_TE:
if (!test) *newid = (ID *)BKE_texture_copy((Tex *)id);
- return 1;
+ return true;
case ID_IM:
if (!test) *newid = (ID *)BKE_image_copy(G.main, (Image *)id);
- return 1;
+ return true;
case ID_LT:
if (!test) *newid = (ID *)BKE_lattice_copy((Lattice *)id);
- return 1;
+ return true;
case ID_LA:
if (!test) *newid = (ID *)BKE_lamp_copy((Lamp *)id);
- return 1;
+ return true;
case ID_SPK:
if (!test) *newid = (ID *)BKE_speaker_copy((Speaker *)id);
- return 1;
+ return true;
case ID_CA:
if (!test) *newid = (ID *)BKE_camera_copy((Camera *)id);
- return 1;
+ return true;
case ID_IP:
- return 0; /* deprecated */
+ return false; /* deprecated */
case ID_KE:
if (!test) *newid = (ID *)BKE_key_copy((Key *)id);
- return 1;
+ return true;
case ID_WO:
if (!test) *newid = (ID *)BKE_world_copy((World *)id);
- return 1;
+ return true;
case ID_SCR:
- return 0; /* can't be copied from here */
+ return false; /* can't be copied from here */
case ID_VF:
- return 0; /* not implemented */
+ return false; /* not implemented */
case ID_TXT:
if (!test) *newid = (ID *)BKE_text_copy((Text *)id);
- return 1;
+ return true;
case ID_SCRIPT:
- return 0; /* deprecated */
+ return false; /* deprecated */
case ID_SO:
- return 0; /* not implemented */
+ return false; /* not implemented */
case ID_GR:
if (!test) *newid = (ID *)BKE_group_copy((Group *)id);
- return 1;
+ return true;
case ID_AR:
if (!test) *newid = (ID *)BKE_armature_copy((bArmature *)id);
- return 1;
+ return true;
case ID_AC:
if (!test) *newid = (ID *)BKE_action_copy((bAction *)id);
- return 1;
+ return true;
case ID_NT:
if (!test) *newid = (ID *)ntreeCopyTree((bNodeTree *)id);
- return 1;
+ return true;
case ID_BR:
if (!test) *newid = (ID *)BKE_brush_copy((Brush *)id);
- return 1;
+ return true;
case ID_PA:
if (!test) *newid = (ID *)BKE_particlesettings_copy((ParticleSettings *)id);
- return 1;
+ return true;
case ID_WM:
- return 0; /* can't be copied from here */
+ return false; /* can't be copied from here */
case ID_GD:
- return 0; /* not implemented */
+ return false; /* not implemented */
case ID_MSK:
if (!test) *newid = (ID *)BKE_mask_copy((Mask *)id);
- return 1;
+ return true;
#ifdef WITH_FREESTYLE
case ID_LS:
if(!test) *newid= (ID*)FRS_copy_linestyle((FreestyleLineStyle*)id);
@@ -384,42 +391,42 @@ int id_copy(ID *id, ID **newid, int test)
#endif
}
- return 0;
+ return false;
}
-int id_unlink(ID *id, int test)
+bool id_unlink(ID *id, int test)
{
Main *mainlib = G.main;
ListBase *lb;
switch (GS(id->name)) {
case ID_TXT:
- if (test) return 1;
+ if (test) return true;
BKE_text_unlink(mainlib, (Text *)id);
break;
case ID_GR:
- if (test) return 1;
+ if (test) return true;
BKE_group_unlink((Group *)id);
break;
case ID_OB:
- if (test) return 1;
+ if (test) return true;
BKE_object_unlink((Object *)id);
break;
}
if (id->us == 0) {
- if (test) return 1;
+ if (test) return true;
lb = which_libbase(mainlib, GS(id->name));
BKE_libblock_free(lb, id);
- return 1;
+ return true;
}
- return 0;
+ return false;
}
-int id_single_user(bContext *C, ID *id, PointerRNA *ptr, PropertyRNA *prop)
+bool id_single_user(bContext *C, ID *id, PointerRNA *ptr, PropertyRNA *prop)
{
ID *newid = NULL;
PointerRNA idptr;
@@ -427,7 +434,7 @@ int id_single_user(bContext *C, ID *id, PointerRNA *ptr, PropertyRNA *prop)
if (id) {
/* if property isn't editable, we're going to have an extra block hanging around until we save */
if (RNA_property_editable(ptr, prop)) {
- if (id_copy(id, &newid, 0) && newid) {
+ if (id_copy(id, &newid, false) && newid) {
/* copy animation actions too */
BKE_copy_animdata_id_action(id);
/* us is 1 by convention, but RNA_property_pointer_set
@@ -439,12 +446,12 @@ int id_single_user(bContext *C, ID *id, PointerRNA *ptr, PropertyRNA *prop)
RNA_property_pointer_set(ptr, prop, idptr);
RNA_property_update(C, ptr, prop);
- return 1;
+ return true;
}
}
}
- return 0;
+ return false;
}
ListBase *which_libbase(Main *mainlib, short type)
@@ -552,7 +559,13 @@ void recalc_all_library_objects(Main *main)
ob->recalc |= OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME;
}
-/* note: MAX_LIBARRAY define should match this code */
+/**
+ * puts into array *lb pointers to all the ListBase structs in main,
+ * and returns the number of them as the function result. This is useful for
+ * generic traversal of all the blocks in a Main (by traversing all the
+ * lists in turn), without worrying about block types.
+ *
+ * \note MAX_LIBARRAY define should match this code */
int set_listbasepointers(Main *main, ListBase **lb)
{
int a = 0;
@@ -619,6 +632,10 @@ int set_listbasepointers(Main *main, ListBase **lb)
*
* **************************** */
+/**
+ * Allocates and returns memory of the right size for the specified block type,
+ * initialized to zero.
+ */
static ID *alloc_libblock_notest(short type)
{
ID *id = NULL;
@@ -726,7 +743,12 @@ static ID *alloc_libblock_notest(short type)
return id;
}
-/* used everywhere in blenkernel and text.c */
+/**
+ * Allocates and returns a block of the specified type, with the specified name
+ * (adjusted as necessary to ensure uniqueness), and appended to the specified list.
+ * The user count is set to 1, all other content (apart from name and links) being
+ * initialized to zero.
+ */
void *BKE_libblock_alloc(ListBase *lb, short type, const char *name)
{
ID *id = NULL;
@@ -738,25 +760,25 @@ void *BKE_libblock_alloc(ListBase *lb, short type, const char *name)
id->icon_id = 0;
*( (short *)id->name) = type;
new_id(lb, id, name);
- /* alphabetic insterion: is in new_id */
+ /* alphabetic insertion: is in new_id */
}
return id;
}
/* by spec, animdata is first item after ID */
/* and, trust that BKE_animdata_from_id() will only find AnimData for valid ID-types */
-static void id_copy_animdata(ID *id, const short do_action)
+static void id_copy_animdata(ID *id, const bool do_action)
{
AnimData *adt = BKE_animdata_from_id(id);
if (adt) {
IdAdtTemplate *iat = (IdAdtTemplate *)id;
- iat->adt = BKE_copy_animdata(iat->adt, do_action); /* could be set to FALSE, need to investigate */
+ iat->adt = BKE_copy_animdata(iat->adt, do_action); /* could be set to false, need to investigate */
}
}
/* material nodes use this since they are not treated as libdata */
-void BKE_libblock_copy_data(ID *id, const ID *id_from, const short do_action)
+void BKE_libblock_copy_data(ID *id, const ID *id_from, const bool do_action)
{
if (id_from->properties)
id->properties = IDP_CopyProperty(id_from->properties);
@@ -788,7 +810,7 @@ void *BKE_libblock_copy_ex(Main *bmain, ID *id)
id->newid = idn;
idn->flag |= LIB_NEW;
- BKE_libblock_copy_data(idn, id, FALSE);
+ BKE_libblock_copy_data(idn, id, false);
return idn;
}
@@ -1207,7 +1229,7 @@ void id_sort_by_name(ListBase *lb, ID *id)
}
-/*
+/**
* Check to see if there is an ID with the same name as 'name'.
* Returns the ID if so, if not, returns NULL
*/
@@ -1229,9 +1251,9 @@ static ID *is_dupid(ListBase *lb, ID *id, const char *name)
return idtest;
}
-/*
+/**
* Check to see if an ID name is already used, and find a new one if so.
- * Return 1 if created a new name (returned in name).
+ * Return true if created a new name (returned in name).
*
* Normally the ID that's being check is already in the ListBase, so ID *id
* points at the new entry. The Python Library module needs to know what
@@ -1239,11 +1261,13 @@ static ID *is_dupid(ListBase *lb, ID *id, const char *name)
* id is NULL
*/
-static int check_for_dupid(ListBase *lb, ID *id, char *name)
+static bool check_for_dupid(ListBase *lb, ID *id, char *name)
{
ID *idtest;
int nr = 0, nrtest, a, left_len;
- char in_use[64]; /* use as a boolean array, unrelated to name length */
+#define MAX_IN_USE 64
+ bool in_use[MAX_IN_USE];
+ /* to speed up finding unused numbers within [1 .. MAX_IN_USE - 1] */
char left[MAX_ID_NAME + 8], leftest[MAX_ID_NAME + 8];
@@ -1251,23 +1275,23 @@ static int check_for_dupid(ListBase *lb, ID *id, char *name)
/* if ( strlen(name) > MAX_ID_NAME-3 ) name[MAX_ID_NAME-3] = 0; */
/* removed since this is only ever called from one place - campbell */
- while (1) {
+ while (true) {
/* phase 1: id already exists? */
idtest = is_dupid(lb, id, name);
/* if there is no double, done */
- if (idtest == NULL) return 0;
+ if (idtest == NULL) return false;
/* we have a dup; need to make a new name */
- /* quick check so we can reuse one of first 64 ids if vacant */
- memset(in_use, 0, sizeof(in_use));
+ /* quick check so we can reuse one of first MAX_IN_USE - 1 ids if vacant */
+ memset(in_use, false, sizeof(in_use));
/* get name portion, number portion ("name.number") */
left_len = BLI_split_name_num(left, &nr, name, '.');
/* if new name will be too long, truncate it */
- if (nr > 999 && left_len > (MAX_ID_NAME - 8)) {
+ if (nr > 999 && left_len > (MAX_ID_NAME - 8)) { /* assumption: won't go beyond 9999 */
left[MAX_ID_NAME - 8] = 0;
left_len = MAX_ID_NAME - 8;
}
@@ -1284,35 +1308,50 @@ static int check_for_dupid(ListBase *lb, ID *id, char *name)
(BLI_split_name_num(leftest, &nrtest, idtest->name + 2, '.') == left_len)
)
{
- if (nrtest < sizeof(in_use))
- in_use[nrtest] = 1; /* mark as used */
+ /* will get here at least once, otherwise is_dupid call above would have returned NULL */
+ if (nrtest < MAX_IN_USE)
+ in_use[nrtest] = true; /* mark as used */
if (nr <= nrtest)
nr = nrtest + 1; /* track largest unused */
}
}
+ /* At this point, nr will be at least 1. */
+ BLI_assert(nr >= 1);
/* decide which value of nr to use */
- for (a = 0; a < sizeof(in_use); a++) {
- if (a >= nr) break; /* stop when we've check up to biggest */
- if (in_use[a] == 0) { /* found an unused value */
+ for (a = 0; a < MAX_IN_USE; a++) {
+ if (a >= nr) break; /* stop when we've checked up to biggest */ /* redundant check */
+ if (!in_use[a]) { /* found an unused value */
nr = a;
+ /* can only be zero if all potential duplicate names had
+ * nonzero numeric suffixes, which means name itself has
+ * nonzero numeric suffix (else no name conflict and wouldn't
+ * have got here), which means name[left_len] is not a null */
break;
}
}
+ /* At this point, nr is either the lowest unused number within [0 .. MAX_IN_USE - 1],
+ * or 1 greater than the largest used number if all those low ones are taken.
+ * We can't be bothered to look for the lowest unused number beyond (MAX_IN_USE - 1). */
/* If the original name has no numeric suffix,
* rather than just chopping and adding numbers,
* shave off the end chars until we have a unique name.
* Check the null terminators match as well so we don't get Cube.000 -> Cube.00 */
if (nr == 0 && name[left_len] == '\0') {
- int len = left_len - 1;
+ int len;
+ /* FIXME: this code will never be executed, because either nr will be
+ * at least 1, or name will not end at left_len! */
+ BLI_assert(0);
+
+ len = left_len - 1;
idtest = is_dupid(lb, id, name);
while (idtest && len > 1) {
name[len--] = '\0';
idtest = is_dupid(lb, id, name);
}
- if (idtest == NULL) return 1;
+ if (idtest == NULL) return true;
/* otherwise just continue and use a number suffix */
}
@@ -1326,24 +1365,26 @@ static int check_for_dupid(ListBase *lb, ID *id, char *name)
/* this format specifier is from hell... */
BLI_snprintf(name, sizeof(id->name) - 2, "%s.%.3d", left, nr);
- return 1;
+ return true;
}
+
+#undef MAX_IN_USE
}
/*
* Only for local blocks: external en indirect blocks already have a
* unique ID.
*
- * return 1: created a new name
+ * return true: created a new name
*/
-int new_id(ListBase *lb, ID *id, const char *tname)
+bool new_id(ListBase *lb, ID *id, const char *tname)
{
- int result;
+ bool result;
char name[MAX_ID_NAME - 2];
/* if library, don't rename */
- if (id->lib) return 0;
+ if (id->lib) return false;
/* if no libdata given, look up based on ID */
if (lb == NULL) lb = which_libbase(G.main, GS(id->name));
@@ -1415,10 +1456,9 @@ void clear_id_newpoins(void)
}
}
-#define LIBTAG(a) if (a && a->id.lib) { a->id.flag &= ~LIB_INDIRECT; a->id.flag |= LIB_EXTERN; } (void)0
-
static void lib_indirect_test_id(ID *id, Library *lib)
{
+#define LIBTAG(a) if (a && a->id.lib) { a->id.flag &= ~LIB_INDIRECT; a->id.flag |= LIB_EXTERN; } (void)0
if (id->lib) {
/* datablocks that were indirectly related are now direct links
@@ -1458,6 +1498,8 @@ static void lib_indirect_test_id(ID *id, Library *lib)
me = ob->data;
LIBTAG(me);
}
+
+#undef LIBTAG
}
void tag_main_lb(ListBase *lb, const short tag)
@@ -1495,9 +1537,9 @@ void tag_main(struct Main *mainvar, const short tag)
/* if lib!=NULL, only all from lib local
* bmain is almost certainly G.main */
-void BKE_library_make_local(Main *bmain, Library *lib, int untagged_only)
+void BKE_library_make_local(Main *bmain, Library *lib, bool untagged_only)
{
- ListBase *lbarray[MAX_LIBARRAY], tempbase = {NULL, NULL};
+ ListBase *lbarray[MAX_LIBARRAY];
ID *id, *idn;
int a;
@@ -1515,7 +1557,7 @@ void BKE_library_make_local(Main *bmain, Library *lib, int untagged_only)
* (very nasty to discover all your links are lost after appending)
* */
if (id->flag & (LIB_EXTERN | LIB_INDIRECT | LIB_NEW) &&
- (untagged_only == 0 || !(id->flag & LIB_PRE_EXISTING)))
+ ((untagged_only == false) || !(id->flag & LIB_PRE_EXISTING)))
{
if (lib == NULL || id->lib == lib) {
if (id->lib) {
@@ -1532,16 +1574,8 @@ void BKE_library_make_local(Main *bmain, Library *lib, int untagged_only)
}
id = idn;
}
-
- /* patch2: make it aphabetically */
- while ( (id = tempbase.first) ) {
- BLI_remlink(&tempbase, id);
- BLI_addtail(lbarray[a], id);
- new_id(lbarray[a], id, NULL);
- }
}
- /* patch 3: make sure library data isn't indirect falsely... */
a = set_listbasepointers(bmain, lbarray);
while (a--) {
for (id = lbarray[a]->first; id; id = id->next)
@@ -1557,39 +1591,20 @@ void test_idbutton(char *name)
ID *idtest;
- lb = which_libbase(G.main, GS(name - 2) );
+ lb = which_libbase(G.main, GS(name) );
if (lb == NULL) return;
/* search for id */
- idtest = BLI_findstring(lb, name, offsetof(ID, name) + 2);
+ idtest = BLI_findstring(lb, name + 2, offsetof(ID, name) + 2);
- if (idtest && (new_id(lb, idtest, name) == 0)) {
+ if (idtest && !new_id(lb, idtest, name + 2)) {
id_sort_by_name(lb, idtest);
}
}
-void text_idbutton(struct ID *id, char *text)
-{
- if (id) {
- if (GS(id->name) == ID_SCE)
- strcpy(text, "SCE: ");
- else if (GS(id->name) == ID_SCR)
- strcpy(text, "SCR: ");
- else if (GS(id->name) == ID_MA && ((Material *)id)->use_nodes)
- strcpy(text, "NT: ");
- else {
- text[0] = id->name[0];
- text[1] = id->name[1];
- text[2] = ':';
- text[3] = ' ';
- text[4] = 0;
- }
- }
- else {
- text[0] = '\0';
- }
-}
-
+/**
+ * Sets the name of a block to name, suitably adjusted for uniqueness.
+ */
void rename_id(ID *id, const char *name)
{
ListBase *lb;
@@ -1600,7 +1615,11 @@ void rename_id(ID *id, const char *name)
new_id(lb, id, name);
}
-void name_uiprefix_id(char *name, ID *id)
+/**
+ * Returns in name the name of the block, with a 3-character prefix prepended
+ * indicating whether it comes from a library, has a fake user, or no users.
+ */
+void name_uiprefix_id(char *name, const ID *id)
{
name[0] = id->lib ? 'L' : ' ';
name[1] = id->flag & LIB_FAKEUSER ? 'F' : (id->us == 0) ? '0' : ' ';
diff --git a/source/blender/blenkernel/intern/linestyle.c b/source/blender/blenkernel/intern/linestyle.c
index aa9200adef4..ca3a910f403 100644
--- a/source/blender/blenkernel/intern/linestyle.c
+++ b/source/blender/blenkernel/intern/linestyle.c
@@ -39,6 +39,10 @@
#include "DNA_material_types.h" /* for ramp blend */
#include "DNA_texture_types.h"
+#include "BLI_blenlib.h"
+#include "BLI_math.h"
+#include "BLI_utildefines.h"
+
#include "BKE_global.h"
#include "BKE_library.h"
#include "BKE_linestyle.h"
@@ -47,9 +51,6 @@
#include "BKE_colortools.h"
#include "BKE_animsys.h"
-#include "BLI_blenlib.h"
-#include "BLI_math.h"
-
static const char *modifier_name[LS_MODIFIER_NUM] = {
NULL,
"Along Stroke",
diff --git a/source/blender/blenkernel/intern/material.c b/source/blender/blenkernel/intern/material.c
index 50e00161db3..6f6686150ae 100644
--- a/source/blender/blenkernel/intern/material.c
+++ b/source/blender/blenkernel/intern/material.c
@@ -1797,7 +1797,9 @@ static short convert_tfacenomaterial(Main *main, Mesh *me, MTFace *tf, int flag)
ma->game.flag = -flag;
id_us_min((ID *)ma);
}
- else printf("Error: Unable to create Material \"%s\" for Mesh \"%s\".", idname + 2, me->id.name + 2);
+ else {
+ printf("Error: Unable to create Material \"%s\" for Mesh \"%s\".", idname + 2, me->id.name + 2);
+ }
}
/* set as converted, no need to go bad to this face */
diff --git a/source/blender/blenkernel/intern/mball.c b/source/blender/blenkernel/intern/mball.c
index 5cc3145213c..72284130869 100644
--- a/source/blender/blenkernel/intern/mball.c
+++ b/source/blender/blenkernel/intern/mball.c
@@ -439,18 +439,15 @@ float *BKE_mball_make_orco(Object *ob, ListBase *dispbase)
* It test last character of Object ID name. If last character
* is digit it return 0, else it return 1.
*/
-int BKE_mball_is_basis(Object *ob)
+bool BKE_mball_is_basis(Object *ob)
{
- int len;
-
/* just a quick test */
- len = strlen(ob->id.name);
- if (isdigit(ob->id.name[len - 1]) ) return 0;
- return 1;
+ const int len = strlen(ob->id.name);
+ return (!isdigit(ob->id.name[len - 1]));
}
/* return nonzero if ob1 is a basis mball for ob */
-int BKE_mball_is_basis_for(Object *ob1, Object *ob2)
+bool BKE_mball_is_basis_for(Object *ob1, Object *ob2)
{
int basis1nr, basis2nr;
char basis1name[MAX_ID_NAME], basis2name[MAX_ID_NAME];
@@ -458,8 +455,12 @@ int BKE_mball_is_basis_for(Object *ob1, Object *ob2)
BLI_split_name_num(basis1name, &basis1nr, ob1->id.name + 2, '.');
BLI_split_name_num(basis2name, &basis2nr, ob2->id.name + 2, '.');
- if (!strcmp(basis1name, basis2name)) return BKE_mball_is_basis(ob1);
- else return 0;
+ if (!strcmp(basis1name, basis2name)) {
+ return BKE_mball_is_basis(ob1);
+ }
+ else {
+ return false;
+ }
}
/* \brief copy some properties from object to other metaball object with same base name
@@ -1500,7 +1501,7 @@ static void add_cube(PROCESS *mbproc, int i, int j, int k, int count)
static void find_first_points(PROCESS *mbproc, MetaBall *mb, int a)
{
MetaElem *ml;
- float f = 0.0f;
+ float f;
ml = G_mb.mainb[a];
f = 1.0f - (mb->thresh / ml->s);
@@ -2293,7 +2294,9 @@ void BKE_mball_polygonize(Scene *scene, Object *ob, ListBase *dispbase)
}
/* width is size per polygonize cube */
- if (G.is_rendering) width = mb->rendersize;
+ if (G.is_rendering) {
+ width = mb->rendersize;
+ }
else {
width = mb->wiresize;
if (G.moving && mb->flag == MB_UPDATE_HALFRES) width *= 2;
diff --git a/source/blender/blenkernel/intern/mesh.c b/source/blender/blenkernel/intern/mesh.c
index f6f60d03cf7..b4833cdb53b 100644
--- a/source/blender/blenkernel/intern/mesh.c
+++ b/source/blender/blenkernel/intern/mesh.c
@@ -1198,7 +1198,7 @@ void BKE_mesh_from_metaball(ListBase *lb, Mesh *me)
BKE_mesh_calc_normals(me->mvert, me->totvert, me->mloop, me->mpoly, me->totloop, me->totpoly, NULL);
- BKE_mesh_calc_edges(me, TRUE);
+ BKE_mesh_calc_edges(me, true, false);
}
}
@@ -1523,7 +1523,7 @@ void BKE_mesh_from_nurbs_displist(Object *ob, ListBase *dispbase, int use_orco_u
BKE_mesh_calc_normals(me->mvert, me->totvert, me->mloop, me->mpoly, me->totloop, me->totpoly, NULL);
- BKE_mesh_calc_edges(me, TRUE);
+ BKE_mesh_calc_edges(me, true, false);
}
else {
me = BKE_mesh_add(G.main, "Mesh");
@@ -1586,65 +1586,46 @@ static void appendPolyLineVert(ListBase *lb, unsigned int index)
BLI_addtail(lb, vl);
}
-void BKE_mesh_from_curve(Scene *scene, Object *ob)
+void BKE_mesh_to_curve_nurblist(DerivedMesh *dm, ListBase *nurblist, const int edge_users_test)
{
- /* make new mesh data from the original copy */
- DerivedMesh *dm = mesh_get_derived_final(scene, ob, CD_MASK_MESH);
-
- MVert *mverts = dm->getVertArray(dm);
+ MVert *mvert = dm->getVertArray(dm);
MEdge *med, *medge = dm->getEdgeArray(dm);
- MFace *mf, *mface = dm->getTessFaceArray(dm);
+ MPoly *mp, *mpoly = dm->getPolyArray(dm);
+ MLoop *mloop = dm->getLoopArray(dm);
- int totedge = dm->getNumEdges(dm);
- int totface = dm->getNumTessFaces(dm);
+ int dm_totedge = dm->getNumEdges(dm);
+ int dm_totpoly = dm->getNumPolys(dm);
int totedges = 0;
- int i, needsFree = 0;
+ int i;
/* only to detect edge polylines */
- EdgeHash *eh = BLI_edgehash_new();
- EdgeHash *eh_edge = BLI_edgehash_new();
-
+ int *edge_users;
ListBase edges = {NULL, NULL};
- /* create edges from all faces (so as to find edges not in any faces) */
- mf = mface;
- for (i = 0; i < totface; i++, mf++) {
- if (!BLI_edgehash_haskey(eh, mf->v1, mf->v2))
- BLI_edgehash_insert(eh, mf->v1, mf->v2, NULL);
- if (!BLI_edgehash_haskey(eh, mf->v2, mf->v3))
- BLI_edgehash_insert(eh, mf->v2, mf->v3, NULL);
-
- if (mf->v4) {
- if (!BLI_edgehash_haskey(eh, mf->v3, mf->v4))
- BLI_edgehash_insert(eh, mf->v3, mf->v4, NULL);
- if (!BLI_edgehash_haskey(eh, mf->v4, mf->v1))
- BLI_edgehash_insert(eh, mf->v4, mf->v1, NULL);
- }
- else {
- if (!BLI_edgehash_haskey(eh, mf->v3, mf->v1))
- BLI_edgehash_insert(eh, mf->v3, mf->v1, NULL);
+ /* get boundary edges */
+ edge_users = MEM_callocN(sizeof(int) * dm_totedge, __func__);
+ for (i = 0, mp = mpoly; i < dm_totpoly; i++, mp++) {
+ MLoop *ml = &mloop[mp->loopstart];
+ int j;
+ for (j = 0; j < mp->totloop; j++, ml++) {
+ edge_users[ml->e]++;
}
}
+ /* create edges from all faces (so as to find edges not in any faces) */
med = medge;
- for (i = 0; i < totedge; i++, med++) {
- if (!BLI_edgehash_haskey(eh, med->v1, med->v2)) {
+ for (i = 0; i < dm_totedge; i++, med++) {
+ if (edge_users[i] == edge_users_test) {
EdgeLink *edl = MEM_callocN(sizeof(EdgeLink), "EdgeLink");
-
- BLI_edgehash_insert(eh_edge, med->v1, med->v2, NULL);
edl->edge = med;
BLI_addtail(&edges, edl); totedges++;
}
}
- BLI_edgehash_free(eh_edge, NULL);
- BLI_edgehash_free(eh, NULL);
+ MEM_freeN(edge_users);
if (edges.first) {
- Curve *cu = BKE_curve_add(G.main, ob->id.name + 2, OB_CURVE);
- cu->flag |= CU_3D;
-
while (edges.first) {
/* each iteration find a polyline and add this as a nurbs poly spline */
@@ -1724,24 +1705,41 @@ void BKE_mesh_from_curve(Scene *scene, Object *ob)
/* add points */
vl = polyline.first;
for (i = 0, bp = nu->bp; i < totpoly; i++, bp++, vl = (VertLink *)vl->next) {
- copy_v3_v3(bp->vec, mverts[vl->index].co);
+ copy_v3_v3(bp->vec, mvert[vl->index].co);
bp->f1 = SELECT;
bp->radius = bp->weight = 1.0;
}
BLI_freelistN(&polyline);
/* add nurb to curve */
- BLI_addtail(&cu->nurb, nu);
+ BLI_addtail(nurblist, nu);
}
/* --- done with nurbs --- */
}
+ }
+}
+
+void BKE_mesh_to_curve(Scene *scene, Object *ob)
+{
+ /* make new mesh data from the original copy */
+ DerivedMesh *dm = mesh_get_derived_final(scene, ob, CD_MASK_MESH);
+ ListBase nurblist = {NULL, NULL};
+ bool needsFree = false;
+
+ BKE_mesh_to_curve_nurblist(dm, &nurblist, 0);
+
+ if (nurblist.first) {
+ Curve *cu = BKE_curve_add(G.main, ob->id.name + 2, OB_CURVE);
+ cu->flag |= CU_3D;
+
+ cu->nurb = nurblist;
((Mesh *)ob->data)->id.us--;
ob->data = cu;
ob->type = OB_CURVE;
/* curve objects can't contain DM in usual cases, we could free memory */
- needsFree = 1;
+ needsFree = true;
}
dm->needsFree = needsFree;
diff --git a/source/blender/blenkernel/intern/mesh_validate.c b/source/blender/blenkernel/intern/mesh_validate.c
index 74d3645ea66..9d16d38220a 100644
--- a/source/blender/blenkernel/intern/mesh_validate.c
+++ b/source/blender/blenkernel/intern/mesh_validate.c
@@ -774,7 +774,7 @@ int BKE_mesh_validate_arrays(Mesh *mesh,
}
if (do_edge_recalc) {
- BKE_mesh_calc_edges(mesh, TRUE);
+ BKE_mesh_calc_edges(mesh, true, false);
}
}
@@ -914,7 +914,7 @@ int BKE_mesh_validate_dm(DerivedMesh *dm)
* \param mesh The mesh to add edges into
* \param update When true create new edges co-exist
*/
-void BKE_mesh_calc_edges(Mesh *mesh, int update)
+void BKE_mesh_calc_edges(Mesh *mesh, bool update, const bool select)
{
CustomData edata;
EdgeHashIterator *ehi;
@@ -923,9 +923,11 @@ void BKE_mesh_calc_edges(Mesh *mesh, int update)
EdgeHash *eh = BLI_edgehash_new();
int i, totedge, totpoly = mesh->totpoly;
int med_index;
+ /* select for newly created meshes which are selected [#25595] */
+ const short ed_flag = (ME_EDGEDRAW | ME_EDGERENDER) | (select ? SELECT : 0);
if (mesh->totedge == 0)
- update = FALSE;
+ update = false;
if (update) {
/* assume existing edges are valid
@@ -963,7 +965,7 @@ void BKE_mesh_calc_edges(Mesh *mesh, int update)
}
else {
BLI_edgehashIterator_getKey(ehi, &med->v1, &med->v2);
- med->flag = ME_EDGEDRAW | ME_EDGERENDER | SELECT; /* select for newly created meshes which are selected [#25595] */
+ med->flag = ed_flag;
}
/* store the new edge index in the hash value */
diff --git a/source/blender/blenkernel/intern/movieclip.c b/source/blender/blenkernel/intern/movieclip.c
index 5519edca7ff..e79754ca203 100644
--- a/source/blender/blenkernel/intern/movieclip.c
+++ b/source/blender/blenkernel/intern/movieclip.c
@@ -1230,7 +1230,7 @@ void BKE_movieclip_update_scopes(MovieClip *clip, MovieClipUser *user, MovieClip
scopes->ok = TRUE;
}
-static void movieclip_build_proxy_ibuf(MovieClip *clip, ImBuf *ibuf, int cfra, int proxy_render_size, int undistorted)
+static void movieclip_build_proxy_ibuf(MovieClip *clip, ImBuf *ibuf, int cfra, int proxy_render_size, int undistorted, bool threaded)
{
char name[FILE_MAX];
int quality, rectx, recty;
@@ -1244,7 +1244,10 @@ static void movieclip_build_proxy_ibuf(MovieClip *clip, ImBuf *ibuf, int cfra, i
scaleibuf = IMB_dupImBuf(ibuf);
- IMB_scaleImBuf(scaleibuf, (short)rectx, (short)recty);
+ if (threaded)
+ IMB_scaleImBuf_threaded(scaleibuf, (short)rectx, (short)recty);
+ else
+ IMB_scaleImBuf(scaleibuf, (short)rectx, (short)recty);
quality = clip->proxy.quality;
scaleibuf->ftype = JPG | quality;
@@ -1253,6 +1256,10 @@ static void movieclip_build_proxy_ibuf(MovieClip *clip, ImBuf *ibuf, int cfra, i
if (scaleibuf->planes == 32)
scaleibuf->planes = 24;
+ /* TODO: currently the most weak part of multithreaded proxies,
+ * could be solved in a way that thread only prepares memory
+ * buffer and write to disk happens separately
+ */
BLI_lock_thread(LOCK_MOVIECLIP);
BLI_make_existing_file(name);
@@ -1264,12 +1271,18 @@ static void movieclip_build_proxy_ibuf(MovieClip *clip, ImBuf *ibuf, int cfra, i
IMB_freeImBuf(scaleibuf);
}
+/* note: currently used by proxy job for movies, threading happens within single frame
+ * (meaning scaling shall be threaded)
+ */
void BKE_movieclip_build_proxy_frame(MovieClip *clip, int clip_flag, struct MovieDistortion *distortion,
int cfra, int *build_sizes, int build_count, int undistorted)
{
ImBuf *ibuf;
MovieClipUser user;
+ if (!build_count)
+ return;
+
user.framenr = cfra;
user.render_flag = 0;
user.render_size = MCLIP_PROXY_RENDER_SIZE_FULL;
@@ -1284,7 +1297,7 @@ void BKE_movieclip_build_proxy_frame(MovieClip *clip, int clip_flag, struct Movi
tmpibuf = get_undistorted_ibuf(clip, distortion, ibuf);
for (i = 0; i < build_count; i++)
- movieclip_build_proxy_ibuf(clip, tmpibuf, cfra, build_sizes[i], undistorted);
+ movieclip_build_proxy_ibuf(clip, tmpibuf, cfra, build_sizes[i], undistorted, true);
IMB_freeImBuf(ibuf);
@@ -1293,6 +1306,30 @@ void BKE_movieclip_build_proxy_frame(MovieClip *clip, int clip_flag, struct Movi
}
}
+/* note: currently used by proxy job for sequences, threading happens within sequence
+ * (different threads handles different frames, no threading within frame is needed)
+ */
+void BKE_movieclip_build_proxy_frame_for_ibuf(MovieClip *clip, ImBuf *ibuf, struct MovieDistortion *distortion,
+ int cfra, int *build_sizes, int build_count, int undistorted)
+{
+ if (!build_count)
+ return;
+
+ if (ibuf) {
+ ImBuf *tmpibuf = ibuf;
+ int i;
+
+ if (undistorted)
+ tmpibuf = get_undistorted_ibuf(clip, distortion, ibuf);
+
+ for (i = 0; i < build_count; i++)
+ movieclip_build_proxy_ibuf(clip, tmpibuf, cfra, build_sizes[i], undistorted, false);
+
+ if (tmpibuf != ibuf)
+ IMB_freeImBuf(tmpibuf);
+ }
+}
+
void BKE_movieclip_free(MovieClip *clip)
{
BKE_sequencer_clear_movieclip_in_clipboard(clip);
@@ -1381,3 +1418,14 @@ float BKE_movieclip_remap_clip_to_scene_frame(MovieClip *clip, float framenr)
{
return framenr + (float) clip->start_frame - 1.0f;
}
+
+void BKE_movieclip_filename_for_frame(MovieClip *clip, int framenr, char *name)
+{
+ if (clip->source != MCLIP_SRC_MOVIE) {
+ get_sequence_fname(clip, framenr, name);
+ }
+ else {
+ BLI_strncpy(name, clip->name, FILE_MAX);
+ BLI_path_abs(name, ID_BLEND_PATH(G.main, &clip->id));
+ }
+}
diff --git a/source/blender/blenkernel/intern/navmesh_conversion.c b/source/blender/blenkernel/intern/navmesh_conversion.c
index 3bf5f863557..1d662ae3116 100644
--- a/source/blender/blenkernel/intern/navmesh_conversion.c
+++ b/source/blender/blenkernel/intern/navmesh_conversion.c
@@ -436,7 +436,7 @@ int buildNavMeshDataByDerivedMesh(DerivedMesh *dm, int *vertsPerPoly,
unsigned short **polys, int **dtrisToPolysMap,
int **dtrisToTrisMap, int **trisToFacesMap)
{
- int res = 1;
+ int res;
int ntris = 0, *recastData = NULL;
unsigned short *tris = NULL;
diff --git a/source/blender/blenkernel/intern/nla.c b/source/blender/blenkernel/intern/nla.c
index 143f2186020..ccae1f606fc 100644
--- a/source/blender/blenkernel/intern/nla.c
+++ b/source/blender/blenkernel/intern/nla.c
@@ -1262,7 +1262,7 @@ void BKE_nlastrip_validate_fcurves(NlaStrip *strip)
/* Sanity Validation ------------------------------------ */
-static int nla_editbone_name_check(void *arg, const char *name)
+static bool nla_editbone_name_check(void *arg, const char *name)
{
return BLI_ghash_haskey((GHash *)arg, (void *)name);
}
@@ -1660,7 +1660,7 @@ void BKE_nla_tweakmode_exit(AnimData *adt)
/* Baking Tools ------------------------------------------- */
-static void UNUSED_FUNCTION(BKE_nla_bake) (Scene * scene, ID *UNUSED(id), AnimData * adt, int UNUSED(flag))
+static void UNUSED_FUNCTION(BKE_nla_bake) (Scene *scene, ID *UNUSED(id), AnimData *adt, int UNUSED(flag))
{
/* verify that data is valid
diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c
index 3dbaab008f8..974a564b9da 100644
--- a/source/blender/blenkernel/intern/node.c
+++ b/source/blender/blenkernel/intern/node.c
@@ -571,6 +571,12 @@ void nodeInternalRelink(bNodeTree *ntree, bNode *node)
link->fromnode = fromlink->fromnode;
link->fromsock = fromlink->fromsock;
+ /* if the up- or downstream link is invalid,
+ * the replacement link will be invalid too.
+ */
+ if (!(fromlink->flag & NODE_LINK_VALID))
+ link->flag &= ~NODE_LINK_VALID;
+
ntree->update |= NTREE_UPDATE_LINKS;
}
else
@@ -710,7 +716,7 @@ static bNodeTree *ntreeCopyTree_internal(bNodeTree *ntree, const short do_id_use
}
else {
newtree = MEM_dupallocN(ntree);
- BKE_libblock_copy_data(&newtree->id, &ntree->id, TRUE); /* copy animdata and ID props */
+ BKE_libblock_copy_data(&newtree->id, &ntree->id, true); /* copy animdata and ID props */
}
id_us_plus((ID *)newtree->gpd);
diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c
index 5cea2c9fe0e..0c6e0f72523 100644
--- a/source/blender/blenkernel/intern/object.c
+++ b/source/blender/blenkernel/intern/object.c
@@ -189,7 +189,7 @@ void BKE_object_free_modifiers(Object *ob)
BKE_object_free_softbody(ob);
}
-int BKE_object_support_modifier_type_check(Object *ob, int modifier_type)
+bool BKE_object_support_modifier_type_check(Object *ob, int modifier_type)
{
ModifierTypeInfo *mti;
@@ -198,10 +198,10 @@ int BKE_object_support_modifier_type_check(Object *ob, int modifier_type)
if (!((mti->flags & eModifierTypeFlag_AcceptsCVs) ||
(ob->type == OB_MESH && (mti->flags & eModifierTypeFlag_AcceptsMesh))))
{
- return FALSE;
+ return false;
}
- return TRUE;
+ return true;
}
void BKE_object_link_modifiers(struct Object *ob_dst, struct Object *ob_src)
@@ -291,6 +291,9 @@ void sculptsession_bm_to_me(struct Object *ob, int reorder)
BM_mesh_bm_to_me(ss->bm, ob->data, FALSE);
}
}
+
+ /* ensure the objects DerivedMesh mesh doesn't hold onto arrays now realloc'd in the mesh [#34473] */
+ DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
}
}
@@ -784,61 +787,61 @@ void BKE_object_unlink(Object *ob)
}
/* actual check for internal data, not context or flags */
-int BKE_object_is_in_editmode(Object *ob)
+bool BKE_object_is_in_editmode(Object *ob)
{
if (ob->data == NULL)
- return 0;
+ return false;
if (ob->type == OB_MESH) {
Mesh *me = ob->data;
if (me->edit_btmesh)
- return 1;
+ return true;
}
else if (ob->type == OB_ARMATURE) {
bArmature *arm = ob->data;
if (arm->edbo)
- return 1;
+ return true;
}
else if (ob->type == OB_FONT) {
Curve *cu = ob->data;
if (cu->editfont)
- return 1;
+ return true;
}
else if (ob->type == OB_MBALL) {
MetaBall *mb = ob->data;
if (mb->editelems)
- return 1;
+ return true;
}
else if (ob->type == OB_LATTICE) {
Lattice *lt = ob->data;
if (lt->editlatt)
- return 1;
+ return true;
}
else if (ob->type == OB_SURF || ob->type == OB_CURVE) {
Curve *cu = ob->data;
if (cu->editnurb)
- return 1;
+ return true;
}
- return 0;
+ return false;
}
-int BKE_object_exists_check(Object *obtest)
+bool BKE_object_exists_check(Object *obtest)
{
Object *ob;
- if (obtest == NULL) return 0;
+ if (obtest == NULL) return false;
ob = G.main->object.first;
while (ob) {
- if (ob == obtest) return 1;
+ if (ob == obtest) return true;
ob = ob->id.next;
}
- return 0;
+ return false;
}
/* *************************************************** */
@@ -1405,24 +1408,24 @@ void BKE_object_make_local(Object *ob)
/*
* Returns true if the Object is a from an external blend file (libdata)
*/
-int BKE_object_is_libdata(Object *ob)
+bool BKE_object_is_libdata(Object *ob)
{
- if (!ob) return 0;
- if (ob->proxy) return 0;
- if (ob->id.lib) return 1;
- return 0;
+ if (!ob) return false;
+ if (ob->proxy) return false;
+ if (ob->id.lib) return true;
+ return false;
}
/* Returns true if the Object data is a from an external blend file (libdata) */
-int BKE_object_obdata_is_libdata(Object *ob)
+bool BKE_object_obdata_is_libdata(Object *ob)
{
- if (!ob) return 0;
- if (ob->proxy && (ob->data == NULL || ((ID *)ob->data)->lib == NULL)) return 0;
- if (ob->id.lib) return 1;
- if (ob->data == NULL) return 0;
- if (((ID *)ob->data)->lib) return 1;
+ if (!ob) return false;
+ if (ob->proxy && (ob->data == NULL || ((ID *)ob->data)->lib == NULL)) return false;
+ if (ob->id.lib) return true;
+ if (ob->data == NULL) return false;
+ if (((ID *)ob->data)->lib) return true;
- return 0;
+ return false;
}
/* *************** PROXY **************** */
@@ -2634,11 +2637,11 @@ void BKE_object_tfm_restore(Object *ob, void *obtfm_pt)
copy_m4_m4(ob->imat, obtfm->imat);
}
-int BKE_object_parent_loop_check(const Object *par, const Object *ob)
+bool BKE_object_parent_loop_check(const Object *par, const Object *ob)
{
/* test if 'ob' is a parent somewhere in par's parents */
- if (par == NULL) return 0;
- if (ob == par) return 1;
+ if (par == NULL) return false;
+ if (ob == par) return true;
return BKE_object_parent_loop_check(par->parent, ob);
}
@@ -3137,6 +3140,16 @@ KeyBlock *BKE_object_insert_shape_key(Scene *scene, Object *ob, const char *name
}
+bool BKE_object_is_child_recursive(Object *ob_parent, Object *ob_child)
+{
+ for (ob_child = ob_child->parent; ob_child; ob_child = ob_child->parent) {
+ if (ob_child == ob_parent) {
+ return true;
+ }
+ }
+ return false;
+}
+
/* most important if this is modified it should _always_ return True, in certain
* cases false positives are hard to avoid (shape keys for example) */
int BKE_object_is_modified(Scene *scene, Object *ob)
@@ -3192,7 +3205,7 @@ int BKE_object_is_deform_modified(Scene *scene, Object *ob)
}
/* See if an object is using an animated modifier */
-int BKE_object_is_animated(Scene *scene, Object *ob)
+bool BKE_object_is_animated(Scene *scene, Object *ob)
{
ModifierData *md;
@@ -3201,9 +3214,9 @@ int BKE_object_is_animated(Scene *scene, Object *ob)
(modifier_isEnabled(scene, md, eModifierMode_Realtime) ||
modifier_isEnabled(scene, md, eModifierMode_Render)))
{
- return 1;
+ return true;
}
- return 0;
+ return false;
}
static void copy_object__forwardModifierLinks(void *UNUSED(userData), Object *UNUSED(ob), ID **idpoin)
@@ -3286,18 +3299,6 @@ static Object *obrel_armature_find(Object *ob)
return ob_arm;
}
-static int obrel_is_recursive_child(Object *ob, Object *child)
-{
- Object *par;
- for (par = child->parent; par; par = par->parent) {
- if (par == ob) {
- return TRUE;
- }
- }
- return FALSE;
-}
-
-
static int obrel_list_test(Object *ob)
{
return ob && !(ob->id.flag & LIB_DOIT);
@@ -3370,7 +3371,7 @@ LinkNode *BKE_object_relational_superset(struct Scene *scene, eObjectSet objectS
Object *child = local_base->object;
if (obrel_list_test(child)) {
- if ((includeFilter & OB_REL_CHILDREN_RECURSIVE && obrel_is_recursive_child(ob, child)) ||
+ if ((includeFilter & OB_REL_CHILDREN_RECURSIVE && BKE_object_is_child_recursive(ob, child)) ||
(includeFilter & OB_REL_CHILDREN && child->parent && child->parent == ob))
{
obrel_list_add(&links, child);
diff --git a/source/blender/blenkernel/intern/packedFile.c b/source/blender/blenkernel/intern/packedFile.c
index 288e4ccde5d..5a02d929b76 100644
--- a/source/blender/blenkernel/intern/packedFile.c
+++ b/source/blender/blenkernel/intern/packedFile.c
@@ -348,7 +348,7 @@ int writePackedFile(ReportList *reports, const char *filename, PackedFile *pf, i
}
}
else {
- if (BLI_delete(tempname, 0, 0) != 0) {
+ if (BLI_delete(tempname, false, false) != 0) {
BKE_reportf(reports, RPT_ERROR, "Error deleting '%s' (ignored)", tempname);
}
}
@@ -488,11 +488,8 @@ int unpackVFont(ReportList *reports, VFont *vfont, int how)
int ret_value = RET_ERROR;
if (vfont != NULL) {
- BLI_strncpy(localname, vfont->name, sizeof(localname));
- BLI_splitdirstring(localname, fi);
-
+ BLI_split_file_part(vfont->name, fi, sizeof(fi));
BLI_snprintf(localname, sizeof(localname), "//fonts/%s", fi);
-
newname = unpackFile(reports, vfont->name, localname, vfont->packedfile, how);
if (newname != NULL) {
ret_value = RET_OK;
@@ -513,10 +510,8 @@ int unpackSound(Main *bmain, ReportList *reports, bSound *sound, int how)
int ret_value = RET_ERROR;
if (sound != NULL) {
- BLI_strncpy(localname, sound->name, sizeof(localname));
- BLI_splitdirstring(localname, fi);
+ BLI_split_file_part(sound->name, fi, sizeof(fi));
BLI_snprintf(localname, sizeof(localname), "//sounds/%s", fi);
-
newname = unpackFile(reports, sound->name, localname, sound->packedfile, how);
if (newname != NULL) {
BLI_strncpy(sound->name, newname, sizeof(sound->name));
@@ -541,10 +536,8 @@ int unpackImage(ReportList *reports, Image *ima, int how)
int ret_value = RET_ERROR;
if (ima != NULL && ima->name[0]) {
- BLI_strncpy(localname, ima->name, sizeof(localname));
- BLI_splitdirstring(localname, fi);
+ BLI_split_file_part(ima->name, fi, sizeof(fi));
BLI_snprintf(localname, sizeof(localname), "//textures/%s", fi);
-
newname = unpackFile(reports, ima->name, localname, ima->packedfile, how);
if (newname != NULL) {
ret_value = RET_OK;
@@ -591,7 +584,7 @@ void packLibraries(Main *bmain, ReportList *reports)
/* test for relativenss */
for (lib = bmain->library.first; lib; lib = lib->id.next)
- if (0 == BLI_path_is_rel(lib->name))
+ if (!BLI_path_is_rel(lib->name))
break;
if (lib) {
@@ -624,7 +617,7 @@ void unpackAll(Main *bmain, ReportList *reports, int how)
}
/* ID should be not NULL, return 1 if there's a packed file */
-int BKE_pack_check(ID *id)
+bool BKE_pack_check(ID *id)
{
if (GS(id->name) == ID_IM) {
Image *ima = (Image *)id;
@@ -642,7 +635,7 @@ int BKE_pack_check(ID *id)
Library *li = (Library *)id;
return li->packedfile != NULL;
}
- return 0;
+ return false;
}
/* ID should be not NULL */
diff --git a/source/blender/blenkernel/intern/paint.c b/source/blender/blenkernel/intern/paint.c
index d34d5eaa250..cc647a90c8f 100644
--- a/source/blender/blenkernel/intern/paint.c
+++ b/source/blender/blenkernel/intern/paint.c
@@ -40,6 +40,7 @@
#include "BLI_bitmap.h"
#include "BLI_utildefines.h"
+#include "BLI_math_vector.h"
#include "BKE_brush.h"
#include "BKE_context.h"
@@ -137,6 +138,55 @@ Paint *paint_get_active_from_context(const bContext *C)
return NULL;
}
+PaintMode paintmode_get_active_from_context(const bContext *C)
+{
+ Scene *sce = CTX_data_scene(C);
+ SpaceImage *sima;
+
+ if (sce) {
+ ToolSettings *ts = sce->toolsettings;
+ Object *obact = NULL;
+
+ if (sce->basact && sce->basact->object)
+ obact = sce->basact->object;
+
+ if ((sima = CTX_wm_space_image(C)) != NULL) {
+ if (obact && obact->mode == OB_MODE_EDIT) {
+ if (sima->mode == SI_MODE_PAINT)
+ return PAINT_TEXTURE_2D;
+ else if (ts->use_uv_sculpt)
+ return PAINT_SCULPT_UV;
+ }
+ else {
+ return PAINT_TEXTURE_2D;
+ }
+ }
+ else if (obact) {
+ switch (obact->mode) {
+ case OB_MODE_SCULPT:
+ return PAINT_SCULPT;
+ case OB_MODE_VERTEX_PAINT:
+ return PAINT_VERTEX;
+ case OB_MODE_WEIGHT_PAINT:
+ return PAINT_WEIGHT;
+ case OB_MODE_TEXTURE_PAINT:
+ return PAINT_TEXTURE_PROJECTIVE;
+ case OB_MODE_EDIT:
+ if (ts->use_uv_sculpt)
+ return PAINT_SCULPT_UV;
+ else
+ return PAINT_TEXTURE_2D;
+ }
+ }
+ else {
+ /* default to image paint */
+ return PAINT_TEXTURE_2D;
+ }
+ }
+
+ return PAINT_INVALID;
+}
+
Brush *paint_brush(Paint *p)
{
return p ? p->brush : NULL;
@@ -251,3 +301,22 @@ float paint_grid_paint_mask(const GridPaintMask *gpm, unsigned level,
return gpm->data[(y * factor) * gridsize + (x * factor)];
}
+
+/* threshhold to move before updating the brush rotation */
+#define RAKE_THRESHHOLD 20
+
+void paint_calculate_rake_rotation(UnifiedPaintSettings *ups, const float mouse_pos[2])
+{
+ const float u = 0.5f;
+ const float r = RAKE_THRESHHOLD;
+
+ float dpos[2];
+ sub_v2_v2v2(dpos, ups->last_rake, mouse_pos);
+
+ if (len_squared_v2(dpos) >= r * r) {
+ ups->brush_rotation = atan2(dpos[0], dpos[1]);
+
+ interp_v2_v2v2(ups->last_rake, ups->last_rake,
+ mouse_pos, u);
+ }
+}
diff --git a/source/blender/blenkernel/intern/pbvh.c b/source/blender/blenkernel/intern/pbvh.c
index 477ae27394f..5efeeaeedaa 100644
--- a/source/blender/blenkernel/intern/pbvh.c
+++ b/source/blender/blenkernel/intern/pbvh.c
@@ -294,7 +294,7 @@ static void build_mesh_leaf_node(PBVH *bvh, PBVHNode *node)
/* Build the vertex list, unique verts first */
for (iter = BLI_ghashIterator_new(map), i = 0;
- BLI_ghashIterator_isDone(iter) == FALSE;
+ BLI_ghashIterator_notDone(iter);
BLI_ghashIterator_step(iter), ++i)
{
void *value = BLI_ghashIterator_getValue(iter);
@@ -1217,7 +1217,7 @@ void BKE_pbvh_get_grid_updates(PBVH *bvh, int clear, void ***gridfaces, int *tot
faces = MEM_callocN(sizeof(void *) * tot, "PBVH Grid Faces");
for (hiter = BLI_ghashIterator_new(map), i = 0;
- !BLI_ghashIterator_isDone(hiter);
+ BLI_ghashIterator_notDone(hiter);
BLI_ghashIterator_step(hiter), ++i)
{
faces[i] = BLI_ghashIterator_getKey(hiter);
diff --git a/source/blender/blenkernel/intern/pbvh_bmesh.c b/source/blender/blenkernel/intern/pbvh_bmesh.c
index 386a8b27870..0ca73b92071 100644
--- a/source/blender/blenkernel/intern/pbvh_bmesh.c
+++ b/source/blender/blenkernel/intern/pbvh_bmesh.c
@@ -20,6 +20,7 @@
#include "MEM_guardedalloc.h"
+#include "BLI_utildefines.h"
#include "BLI_buffer.h"
#include "BLI_ghash.h"
#include "BLI_heap.h"
@@ -82,8 +83,8 @@ static void pbvh_bmesh_node_finalize(PBVH *bvh, int node_index)
}
BLI_assert(n->vb.bmin[0] <= n->vb.bmax[0] &&
- n->vb.bmin[1] <= n->vb.bmax[1] &&
- n->vb.bmin[2] <= n->vb.bmax[2]);
+ n->vb.bmin[1] <= n->vb.bmax[1] &&
+ n->vb.bmin[2] <= n->vb.bmax[2]);
n->orig_vb = n->vb;
@@ -274,8 +275,8 @@ static PBVHNode *pbvh_bmesh_node_lookup(PBVH *bvh, GHash *map, void *key)
}
static BMVert *pbvh_bmesh_vert_create(PBVH *bvh, int node_index,
- const float co[3],
- const BMVert *example)
+ const float co[3],
+ const BMVert *example)
{
BMVert *v = BM_vert_create(bvh->bm, co, example, 0);
void *val = SET_INT_IN_POINTER(node_index);
@@ -354,7 +355,7 @@ static PBVHNode *pbvh_bmesh_vert_other_node_find(PBVH *bvh, BMVert *v)
}
static void pbvh_bmesh_vert_ownership_transfer(PBVH *bvh, PBVHNode *new_owner,
- BMVert *v)
+ BMVert *v)
{
PBVHNode *current_owner;
@@ -367,7 +368,7 @@ static void pbvh_bmesh_vert_ownership_transfer(PBVH *bvh, PBVHNode *new_owner,
/* Set new ownership */
BLI_ghash_insert(bvh->bm_vert_to_node, v,
- SET_INT_IN_POINTER(new_owner - bvh->nodes));
+ SET_INT_IN_POINTER(new_owner - bvh->nodes));
BLI_ghash_insert(new_owner->bm_unique_verts, v, NULL);
BLI_ghash_remove(new_owner->bm_other_verts, v, NULL, NULL);
BLI_assert(!BLI_ghash_haskey(new_owner->bm_other_verts, v));
@@ -489,35 +490,50 @@ static int edge_queue_tri_in_sphere(const EdgeQueue *q, BMFace *f)
return ((len_squared_v3v3(q->center, c) <= q->radius_squared));
}
+/* Return true if the vertex mask is less than 0.5, false otherwise */
+static int check_mask_half(BMesh *bm, BMVert *v)
+{
+ const float *mask;
+
+ mask = CustomData_bmesh_get(&bm->vdata, v->head.data, CD_PAINT_MASK);
+ return ((*mask) < 0.5f);
+}
+
static void edge_queue_insert(EdgeQueue *q, BLI_mempool *pool, BMEdge *e,
- float priority)
+ float priority, BMesh *bm)
{
BMVert **pair;
- pair = BLI_mempool_alloc(pool);
- pair[0] = e->v1;
- pair[1] = e->v2;
- BLI_heap_insert(q->heap, priority, pair);
+ /* Don't let topology update affect masked vertices. Unlike with
+ * displacements, can't do 50% topology update, so instead set
+ * (arbitrary) cutoff: if both vertices' masks are less than 50%,
+ * topology update can happen. */
+ if (check_mask_half(bm, e->v1) && check_mask_half(bm, e->v2)) {
+ pair = BLI_mempool_alloc(pool);
+ pair[0] = e->v1;
+ pair[1] = e->v2;
+ BLI_heap_insert(q->heap, priority, pair);
+ }
}
static void long_edge_queue_edge_add(EdgeQueue *q, BLI_mempool *pool,
- BMEdge *e)
+ BMEdge *e, BMesh *bm)
{
const float len_sq = BM_edge_calc_length_squared(e);
if (len_sq > q->limit_len_squared)
- edge_queue_insert(q, pool, e, 1.0f / len_sq);
+ edge_queue_insert(q, pool, e, 1.0f / len_sq, bm);
}
static void short_edge_queue_edge_add(EdgeQueue *q, BLI_mempool *pool,
- BMEdge *e)
+ BMEdge *e, BMesh *bm)
{
const float len_sq = BM_edge_calc_length_squared(e);
if (len_sq < q->limit_len_squared)
- edge_queue_insert(q, pool, e, len_sq);
+ edge_queue_insert(q, pool, e, len_sq, bm);
}
static void long_edge_queue_face_add(EdgeQueue *q, BLI_mempool *pool,
- BMFace *f)
+ BMFace *f, BMesh *bm)
{
if (edge_queue_tri_in_sphere(q, f)) {
BMLoop *l_iter;
@@ -526,13 +542,13 @@ static void long_edge_queue_face_add(EdgeQueue *q, BLI_mempool *pool,
/* Check each edge of the face */
l_iter = l_first = BM_FACE_FIRST_LOOP(f);
do {
- long_edge_queue_edge_add(q, pool, l_iter->e);
+ long_edge_queue_edge_add(q, pool, l_iter->e, bm);
} while ((l_iter = l_iter->next) != l_first);
}
}
static void short_edge_queue_face_add(EdgeQueue *q, BLI_mempool *pool,
- BMFace *f)
+ BMFace *f, BMesh *bm)
{
if (edge_queue_tri_in_sphere(q, f)) {
BMLoop *l_iter;
@@ -541,7 +557,7 @@ static void short_edge_queue_face_add(EdgeQueue *q, BLI_mempool *pool,
/* Check each edge of the face */
l_iter = l_first = BM_FACE_FIRST_LOOP(f);
do {
- short_edge_queue_edge_add(q, pool, l_iter->e);
+ short_edge_queue_edge_add(q, pool, l_iter->e, bm);
} while ((l_iter = l_iter->next) != l_first);
}
}
@@ -556,8 +572,8 @@ static void short_edge_queue_face_add(EdgeQueue *q, BLI_mempool *pool,
* The highest priority (lowest number) is given to the longest edge.
*/
static void long_edge_queue_create(EdgeQueue *q, BLI_mempool *pool,
- PBVH *bvh, const float center[3],
- float radius)
+ PBVH *bvh, const float center[3],
+ float radius)
{
int n;
@@ -579,7 +595,7 @@ static void long_edge_queue_create(EdgeQueue *q, BLI_mempool *pool,
GHASH_ITER (gh_iter, node->bm_faces) {
BMFace *f = BLI_ghashIterator_getKey(&gh_iter);
- long_edge_queue_face_add(q, pool, f);
+ long_edge_queue_face_add(q, pool, f, bvh->bm);
}
}
}
@@ -595,8 +611,8 @@ static void long_edge_queue_create(EdgeQueue *q, BLI_mempool *pool,
* The highest priority (lowest number) is given to the shortest edge.
*/
static void short_edge_queue_create(EdgeQueue *q, BLI_mempool *pool,
- PBVH *bvh, const float center[3],
- float radius)
+ PBVH *bvh, const float center[3],
+ float radius)
{
int n;
@@ -618,7 +634,7 @@ static void short_edge_queue_create(EdgeQueue *q, BLI_mempool *pool,
GHASH_ITER (gh_iter, node->bm_faces) {
BMFace *f = BLI_ghashIterator_getKey(&gh_iter);
- short_edge_queue_face_add(q, pool, f);
+ short_edge_queue_face_add(q, pool, f, bvh->bm);
}
}
}
@@ -673,9 +689,9 @@ static void pbvh_bmesh_split_edge(PBVH *bvh, EdgeQueue *q, BLI_mempool *pool,
/* Create two new faces */
f_new = pbvh_bmesh_face_create(bvh, ni, v1, v_new, opp, f_adj);
- long_edge_queue_face_add(q, pool, f_new);
+ long_edge_queue_face_add(q, pool, f_new, bvh->bm);
f_new = pbvh_bmesh_face_create(bvh, ni, v_new, v2, opp, f_adj);
- long_edge_queue_face_add(q, pool, f_new);
+ long_edge_queue_face_add(q, pool, f_new, bvh->bm);
/* Delete original */
pbvh_bmesh_face_remove(bvh, f_adj);
@@ -693,7 +709,7 @@ static void pbvh_bmesh_split_edge(PBVH *bvh, EdgeQueue *q, BLI_mempool *pool,
BMEdge *e2;
BM_ITER_ELEM (e2, &bm_iter, opp, BM_EDGES_OF_VERT) {
- long_edge_queue_edge_add(q, pool, e2);
+ long_edge_queue_edge_add(q, pool, e2, bvh->bm);
}
}
}
@@ -929,8 +945,8 @@ static int pbvh_bmesh_collapse_short_edges(PBVH *bvh, EdgeQueue *q,
/************************* Called from pbvh.c *************************/
int pbvh_bmesh_node_raycast(PBVHNode *node, const float ray_start[3],
- const float ray_normal[3], float *dist,
- int use_original)
+ const float ray_normal[3], float *dist,
+ int use_original)
{
GHashIterator gh_iter;
int hit = 0;
@@ -940,10 +956,10 @@ int pbvh_bmesh_node_raycast(PBVHNode *node, const float ray_start[3],
for (i = 0; i < node->bm_tot_ortri; i++) {
const int *t = node->bm_ortri[i];
hit |= ray_face_intersection(ray_start, ray_normal,
- node->bm_orco[t[0]],
- node->bm_orco[t[1]],
- node->bm_orco[t[2]],
- NULL, dist);
+ node->bm_orco[t[0]],
+ node->bm_orco[t[1]],
+ node->bm_orco[t[2]],
+ NULL, dist);
}
}
else {
@@ -988,7 +1004,7 @@ void pbvh_bmesh_normals_update(PBVHNode **nodes, int totnode)
/* Build a PBVH from a BMesh */
void BKE_pbvh_build_bmesh(PBVH *bvh, BMesh *bm, int smooth_shading,
- BMLog *log)
+ BMLog *log)
{
BMIter iter;
BMFace *f;
@@ -1098,7 +1114,7 @@ void BKE_pbvh_bmesh_node_save_orig(PBVHNode *node)
return;
totvert = (BLI_ghash_size(node->bm_unique_verts) +
- BLI_ghash_size(node->bm_other_verts));
+ BLI_ghash_size(node->bm_other_verts));
tottri = BLI_ghash_size(node->bm_faces);
@@ -1214,31 +1230,31 @@ void bmesh_print(BMesh *bm)
BMLoop *l;
fprintf(stderr, "\nbm=%p, totvert=%d, totedge=%d, "
- "totloop=%d, totface=%d\n",
- bm, bm->totvert, bm->totedge,
- bm->totloop, bm->totface);
+ "totloop=%d, totface=%d\n",
+ bm, bm->totvert, bm->totedge,
+ bm->totloop, bm->totface);
fprintf(stderr, "vertices:\n");
BM_ITER_MESH(v, &iter, bm, BM_VERTS_OF_MESH) {
fprintf(stderr, " %d co=(%.3f %.3f %.3f) oflag=%x\n",
- BM_elem_index_get(v), v->co[0], v->co[1], v->co[2],
- v->oflags[bm->stackdepth - 1].f);
+ BM_elem_index_get(v), v->co[0], v->co[1], v->co[2],
+ v->oflags[bm->stackdepth - 1].f);
}
fprintf(stderr, "edges:\n");
BM_ITER_MESH(e, &iter, bm, BM_EDGES_OF_MESH) {
fprintf(stderr, " %d v1=%d, v2=%d, oflag=%x\n",
- BM_elem_index_get(e),
- BM_elem_index_get(e->v1),
- BM_elem_index_get(e->v2),
- e->oflags[bm->stackdepth - 1].f);
+ BM_elem_index_get(e),
+ BM_elem_index_get(e->v1),
+ BM_elem_index_get(e->v2),
+ e->oflags[bm->stackdepth - 1].f);
}
fprintf(stderr, "faces:\n");
BM_ITER_MESH(f, &iter, bm, BM_FACES_OF_MESH) {
fprintf(stderr, " %d len=%d, oflag=%x\n",
- BM_elem_index_get(f), f->len,
- f->oflags[bm->stackdepth - 1].f);
+ BM_elem_index_get(f), f->len,
+ f->oflags[bm->stackdepth - 1].f);
fprintf(stderr, " v: ");
BM_ITER_ELEM(v, &siter, f, BM_VERTS_OF_FACE) {
@@ -1255,9 +1271,9 @@ void bmesh_print(BMesh *bm)
fprintf(stderr, " l: ");
BM_ITER_ELEM(l, &siter, f, BM_LOOPS_OF_FACE) {
fprintf(stderr, "%d(v=%d, e=%d) ",
- BM_elem_index_get(l),
- BM_elem_index_get(l->v),
- BM_elem_index_get(l->e));
+ BM_elem_index_get(l),
+ BM_elem_index_get(l->v),
+ BM_elem_index_get(l->e));
}
fprintf(stderr, "\n");
}
@@ -1272,15 +1288,15 @@ void pbvh_bmesh_print(PBVH *bvh)
fprintf(stderr, "bm_face_to_node:\n");
GHASH_ITER (gh_iter, bvh->bm_face_to_node) {
fprintf(stderr, " %d -> %d\n",
- BM_elem_index_get((BMFace*)BLI_ghashIterator_getKey(&gh_iter)),
- GET_INT_FROM_POINTER(BLI_ghashIterator_getValue(&gh_iter)));
+ BM_elem_index_get((BMFace*)BLI_ghashIterator_getKey(&gh_iter)),
+ GET_INT_FROM_POINTER(BLI_ghashIterator_getValue(&gh_iter)));
}
fprintf(stderr, "bm_vert_to_node:\n");
GHASH_ITER (gh_iter, bvh->bm_vert_to_node) {
fprintf(stderr, " %d -> %d\n",
- BM_elem_index_get((BMVert*)BLI_ghashIterator_getKey(&gh_iter)),
- GET_INT_FROM_POINTER(BLI_ghashIterator_getValue(&gh_iter)));
+ BM_elem_index_get((BMVert*)BLI_ghashIterator_getKey(&gh_iter)),
+ GET_INT_FROM_POINTER(BLI_ghashIterator_getValue(&gh_iter)));
}
for (n = 0; n < bvh->totnode; n++) {
@@ -1291,15 +1307,15 @@ void pbvh_bmesh_print(PBVH *bvh)
fprintf(stderr, "node %d\n faces:\n", n);
GHASH_ITER (gh_iter, node->bm_faces)
fprintf(stderr, " %d\n",
- BM_elem_index_get((BMFace*)BLI_ghashIterator_getKey(&gh_iter)));
+ BM_elem_index_get((BMFace*)BLI_ghashIterator_getKey(&gh_iter)));
fprintf(stderr, " unique verts:\n");
GHASH_ITER (gh_iter, node->bm_unique_verts)
fprintf(stderr, " %d\n",
- BM_elem_index_get((BMVert*)BLI_ghashIterator_getKey(&gh_iter)));
+ BM_elem_index_get((BMVert*)BLI_ghashIterator_getKey(&gh_iter)));
fprintf(stderr, " other verts:\n");
GHASH_ITER (gh_iter, node->bm_other_verts)
fprintf(stderr, " %d\n",
- BM_elem_index_get((BMVert*)BLI_ghashIterator_getKey(&gh_iter)));
+ BM_elem_index_get((BMVert*)BLI_ghashIterator_getKey(&gh_iter)));
}
}
@@ -1341,7 +1357,7 @@ void pbvh_bmesh_verify(PBVH *bvh)
/* Check that the vertex is in the node */
BLI_assert(BLI_ghash_haskey(n->bm_unique_verts, v) ^
- BLI_ghash_haskey(n->bm_other_verts, v));
+ BLI_ghash_haskey(n->bm_other_verts, v));
/* Check that the vertex has a node owner */
nv = pbvh_bmesh_node_lookup(bvh, bvh->bm_vert_to_node, v);
diff --git a/source/blender/blenkernel/intern/pointcache.c b/source/blender/blenkernel/intern/pointcache.c
index c8947730ea8..c900d08e4e9 100644
--- a/source/blender/blenkernel/intern/pointcache.c
+++ b/source/blender/blenkernel/intern/pointcache.c
@@ -840,7 +840,10 @@ static int ptcache_dynamicpaint_read(PTCacheFile *pf, void *dp_v)
/* version header */
ptcache_file_read(pf, version, 1, sizeof(char) * 4);
- if (strncmp(version, DPAINT_CACHE_VERSION, 4)) {printf("Dynamic Paint: Invalid cache version: %s!\n", version); return 0;}
+ if (strncmp(version, DPAINT_CACHE_VERSION, 4)) {
+ printf("Dynamic Paint: Invalid cache version: %s!\n", version);
+ return 0;
+ }
if (surface->format != MOD_DPAINT_SURFACE_F_IMAGESEQ && surface->data) {
unsigned int data_len;
@@ -1516,7 +1519,7 @@ static int ptcache_file_compressed_write(PTCacheFile *pf, unsigned char *in, uns
if (mode == 2) {
r = LzmaCompress(out, &out_len, in, in_len, //assume sizeof(char)==1....
- props, &sizeOfIt, 5, 1 << 24, 3, 0, 2, 32, 2);
+ props, &sizeOfIt, 5, 1 << 24, 3, 0, 2, 32, 2);
if (!(r == SZ_OK) || (out_len >= in_len))
compressed = 0;
@@ -2432,7 +2435,7 @@ void BKE_ptcache_id_clear(PTCacheID *pid, int mode, unsigned int cfra)
if (mode == PTCACHE_CLEAR_ALL) {
pid->cache->last_exact = MIN2(pid->cache->startframe, 0);
BLI_join_dirfile(path_full, sizeof(path_full), path, de->d_name);
- BLI_delete(path_full, 0, 0);
+ BLI_delete(path_full, false, false);
}
else {
/* read the number of the file */
@@ -2448,7 +2451,7 @@ void BKE_ptcache_id_clear(PTCacheID *pid, int mode, unsigned int cfra)
{
BLI_join_dirfile(path_full, sizeof(path_full), path, de->d_name);
- BLI_delete(path_full, 0, 0);
+ BLI_delete(path_full, false, false);
if (pid->cache->cached_frames && frame >=sta && frame <= end)
pid->cache->cached_frames[frame-sta] = 0;
}
@@ -2502,7 +2505,7 @@ void BKE_ptcache_id_clear(PTCacheID *pid, int mode, unsigned int cfra)
if (pid->cache->flag & PTCACHE_DISK_CACHE) {
if (BKE_ptcache_id_exist(pid, cfra)) {
ptcache_filename(pid, filename, cfra, 1, 1); /* no path */
- BLI_delete(filename, 0, 0);
+ BLI_delete(filename, false, false);
}
}
else {
@@ -2820,7 +2823,7 @@ void BKE_ptcache_remove(void)
}
else if (strstr(de->d_name, PTCACHE_EXT)) { /* do we have the right extension?*/
BLI_join_dirfile(path_full, sizeof(path_full), path, de->d_name);
- BLI_delete(path_full, 0, 0);
+ BLI_delete(path_full, false, false);
}
else {
rmdir = 0; /* unknown file, don't remove the dir */
@@ -2834,7 +2837,7 @@ void BKE_ptcache_remove(void)
}
if (rmdir) {
- BLI_delete(path, 1, 0);
+ BLI_delete(path, true, false);
}
}
@@ -3039,7 +3042,7 @@ static void *ptcache_bake_thread(void *ptr)
}
/* if bake is not given run simulations to current frame */
-void BKE_ptcache_bake(PTCacheBaker* baker)
+void BKE_ptcache_bake(PTCacheBaker *baker)
{
Main *bmain = baker->main;
Scene *scene = baker->scene;
@@ -3511,7 +3514,7 @@ void BKE_ptcache_update_info(PTCacheID *pid)
else if (totframes && cache->totpoint)
BLI_snprintf(cache->info, sizeof(cache->info), IFACE_("%i points found!"), cache->totpoint);
else
- BLI_snprintf(cache->info, sizeof(cache->info), IFACE_("No valid data to read!"));
+ BLI_strncpy(cache->info, IFACE_("No valid data to read!"), sizeof(cache->info));
return;
}
diff --git a/source/blender/blenkernel/intern/property.c b/source/blender/blenkernel/intern/property.c
index c4658712ecb..ec23a7db8a1 100644
--- a/source/blender/blenkernel/intern/property.c
+++ b/source/blender/blenkernel/intern/property.c
@@ -74,8 +74,10 @@ bProperty *BKE_bproperty_copy(bProperty *prop)
if (prop->poin && prop->poin != &prop->data) {
propn->poin = MEM_dupallocN(prop->poin);
}
- else propn->poin = &propn->data;
-
+ else {
+ propn->poin = &propn->data;
+ }
+
return propn;
}
diff --git a/source/blender/blenkernel/intern/rigidbody.c b/source/blender/blenkernel/intern/rigidbody.c
index d144ac927a6..bccc6f9a93b 100644
--- a/source/blender/blenkernel/intern/rigidbody.c
+++ b/source/blender/blenkernel/intern/rigidbody.c
@@ -637,12 +637,12 @@ void BKE_rigidbody_validate_sim_constraint(RigidBodyWorld *rbw, Object *ob, shor
RB_constraint_set_limits_6dof(rbc->physics_constraint, RB_LIMIT_ANG_Z, 0.0f, -1.0f);
break;
case RBC_TYPE_MOTOR:
- rbc->physics_constraint = RB_constraint_new_motor(loc, rot, rb1, rb2);
+ rbc->physics_constraint = RB_constraint_new_motor(loc, rot, rb1, rb2);
- RB_constraint_set_enable_motor(rbc->physics_constraint, rbc->flag & RBC_FLAG_USE_MOTOR_LIN, rbc->flag & RBC_FLAG_USE_MOTOR_ANG);
+ RB_constraint_set_enable_motor(rbc->physics_constraint, rbc->flag & RBC_FLAG_USE_MOTOR_LIN, rbc->flag & RBC_FLAG_USE_MOTOR_ANG);
RB_constraint_set_max_impulse_motor(rbc->physics_constraint, rbc->motor_lin_max_impulse, rbc->motor_ang_max_impulse);
RB_constraint_set_target_velocity_motor(rbc->physics_constraint, rbc->motor_lin_target_velocity, rbc->motor_ang_target_velocity);
- break;
+ break;
}
}
else { /* can't create constraint without both rigid bodies */
@@ -1338,6 +1338,7 @@ void BKE_rigidbody_remove_constraint(Scene *scene, Object *ob) {}
void BKE_rigidbody_sync_transforms(RigidBodyWorld *rbw, Object *ob, float ctime) {}
void BKE_rigidbody_aftertrans_update(Object *ob, float loc[3], float rot[3], float quat[4], float rotAxis[3], float rotAngle) {}
void BKE_rigidbody_cache_reset(RigidBodyWorld *rbw) {}
+void BKE_rigidbody_rebuild_world(Scene *scene, float ctime) {}
void BKE_rigidbody_do_simulation(Scene *scene, float ctime) {}
#ifdef __GNUC__
diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c
index 19eea279f79..a942e694f2e 100644
--- a/source/blender/blenkernel/intern/scene.c
+++ b/source/blender/blenkernel/intern/scene.c
@@ -461,7 +461,7 @@ Scene *BKE_scene_add(Main *bmain, const char *name)
sce->r.postsat = 1.0;
sce->r.bake_mode = 1; /* prevent to include render stuff here */
- sce->r.bake_filter = 2;
+ sce->r.bake_filter = 16;
sce->r.bake_osa = 5;
sce->r.bake_flag = R_BAKE_CLEAR;
sce->r.bake_normal_space = R_BAKE_SPACE_TANGENT;
@@ -786,7 +786,9 @@ int BKE_scene_base_iter_next(Scene **scene, int val, Base **base, Object **ob)
else {
if (*base && fase != F_DUPLI) {
*base = (*base)->next;
- if (*base) *ob = (*base)->object;
+ if (*base) {
+ *ob = (*base)->object;
+ }
else {
if (fase == F_SCENE) {
/* (*scene) is finished, now do the set */
@@ -803,7 +805,9 @@ int BKE_scene_base_iter_next(Scene **scene, int val, Base **base, Object **ob)
}
}
- if (*base == NULL) fase = F_START;
+ if (*base == NULL) {
+ fase = F_START;
+ }
else {
if (fase != F_DUPLI) {
if ( (*base)->object->transflag & OB_DUPLI) {
diff --git a/source/blender/blenkernel/intern/seqcache.c b/source/blender/blenkernel/intern/seqcache.c
index e3f0226c863..978c1a7c9b0 100644
--- a/source/blender/blenkernel/intern/seqcache.c
+++ b/source/blender/blenkernel/intern/seqcache.c
@@ -26,7 +26,6 @@
* \ingroup bke
*/
-
#include <stddef.h>
#include "BLO_sys_types.h" /* for intptr_t */
@@ -34,7 +33,6 @@
#include "MEM_guardedalloc.h"
#include "DNA_sequence_types.h"
-#include "BKE_sequencer.h"
#include "IMB_moviecache.h"
#include "IMB_imbuf.h"
@@ -42,6 +40,8 @@
#include "BLI_listbase.h"
+#include "BKE_sequencer.h"
+
typedef struct SeqCacheKey {
struct Sequence *seq;
SeqRenderData context;
diff --git a/source/blender/blenkernel/intern/seqeffects.c b/source/blender/blenkernel/intern/seqeffects.c
index c0e85352217..a1dc19e1ff7 100644
--- a/source/blender/blenkernel/intern/seqeffects.c
+++ b/source/blender/blenkernel/intern/seqeffects.c
@@ -182,8 +182,8 @@ static void do_alphaover_effect_byte(float facf0, float facf1, int x, int y, un
fac = fac2;
mfac = 1.0f - fac2 * rt1[3];
- if (fac <= 0.0f) *( (unsigned int *) rt) = *( (unsigned int *) cp2);
- else if (mfac <= 0.0f) *( (unsigned int *) rt) = *( (unsigned int *) cp1);
+ if (fac <= 0.0f) *((unsigned int *) rt) = *((unsigned int *) cp2);
+ else if (mfac <= 0.0f) *((unsigned int *) rt) = *((unsigned int *) cp1);
else {
tempc[0] = fac * rt1[0] + mfac * rt2[0];
tempc[1] = fac * rt1[1] + mfac * rt2[1];
@@ -206,8 +206,8 @@ static void do_alphaover_effect_byte(float facf0, float facf1, int x, int y, un
fac = fac4;
mfac = 1.0f - (fac4 * rt1[3]);
- if (fac <= 0.0f) *( (unsigned int *) rt) = *( (unsigned int *) cp2);
- else if (mfac <= 0.0f) *( (unsigned int *) rt) = *( (unsigned int *) cp1);
+ if (fac <= 0.0f) *((unsigned int *) rt) = *((unsigned int *) cp2);
+ else if (mfac <= 0.0f) *((unsigned int *) rt) = *((unsigned int *) cp1);
else {
tempc[0] = fac * rt1[0] + mfac * rt2[0];
tempc[1] = fac * rt1[1] + mfac * rt2[1];
@@ -328,13 +328,13 @@ static void do_alphaunder_effect_byte(float facf0, float facf1, int x, int y, un
/* this complex optimization is because the
* 'skybuf' can be crossed in
*/
- if (rt2[3] == 0 && fac2 == 256) *( (unsigned int *) rt) = *( (unsigned int *) rt1);
- else if (rt2[3] == 255) *( (unsigned int *) rt) = *( (unsigned int *) rt2);
+ if (rt2[3] == 0 && fac2 == 256) *((unsigned int *) rt) = *((unsigned int *) rt1);
+ else if (rt2[3] == 255) *((unsigned int *) rt) = *((unsigned int *) rt2);
else {
mfac = rt2[3];
fac = (fac2 * (256 - mfac)) >> 8;
- if (fac == 0) *( (unsigned int *) rt) = *( (unsigned int *) rt2);
+ if (fac == 0) *((unsigned int *) rt) = *((unsigned int *) rt2);
else {
rt[0] = (fac * rt1[0] + mfac * rt2[0]) >> 8;
rt[1] = (fac * rt1[1] + mfac * rt2[1]) >> 8;
@@ -351,13 +351,13 @@ static void do_alphaunder_effect_byte(float facf0, float facf1, int x, int y, un
x = xo;
while (x--) {
- if (rt2[3] == 0 && fac4 == 256) *( (unsigned int *) rt) = *( (unsigned int *) rt1);
- else if (rt2[3] == 255) *( (unsigned int *) rt) = *( (unsigned int *) rt2);
+ if (rt2[3] == 0 && fac4 == 256) *((unsigned int *) rt) = *((unsigned int *) rt1);
+ else if (rt2[3] == 255) *((unsigned int *) rt) = *((unsigned int *) rt2);
else {
mfac = rt2[3];
fac = (fac4 * (256 - mfac)) >> 8;
- if (fac == 0) *( (unsigned int *)rt) = *( (unsigned int *)rt2);
+ if (fac == 0) *((unsigned int *)rt) = *((unsigned int *)rt2);
else {
rt[0] = (fac * rt1[0] + mfac * rt2[0]) >> 8;
rt[1] = (fac * rt1[1] + mfac * rt2[1]) >> 8;
@@ -682,7 +682,7 @@ static void gamtabs(float gamma)
}
/* inverse gamtab1 : in byte, out short */
for (a = 1; a <= 256; a++) {
- if (gamma == 2.0f) igamtab1[a - 1] = a * a - 1;
+ if (gamma == 2.0f) igamtab1[a - 1] = a * a - 1;
else if (gamma == 1.0f) igamtab1[a - 1] = 256 * a - 1;
else {
val = a / 256.0f;
diff --git a/source/blender/blenkernel/intern/sequencer.c b/source/blender/blenkernel/intern/sequencer.c
index 613c02c173b..9b276912087 100644
--- a/source/blender/blenkernel/intern/sequencer.c
+++ b/source/blender/blenkernel/intern/sequencer.c
@@ -245,7 +245,7 @@ static void seq_free_sequence_recurse(Scene *scene, Sequence *seq)
}
-Editing *BKE_sequencer_editing_get(Scene *scene, int alloc)
+Editing *BKE_sequencer_editing_get(Scene *scene, bool alloc)
{
if (alloc) {
BKE_sequencer_editing_ensure(scene);
@@ -856,7 +856,7 @@ static void seqbase_unique_name(ListBase *seqbasep, SeqUniqueInfo *sui)
{
Sequence *seq;
for (seq = seqbasep->first; seq; seq = seq->next) {
- if (sui->seq != seq && strcmp(sui->name_dest, seq->name + 2) == 0) {
+ if ((sui->seq != seq) && STREQ(sui->name_dest, seq->name + 2)) {
/* SEQ_NAME_MAXSTR - 2 for prefix, -1 for \0, -4 for the number */
BLI_snprintf(sui->name_dest, sizeof(sui->name_dest), "%.59s.%03d", sui->name_src, sui->count++);
sui->match = 1; /* be sure to re-scan */
@@ -3062,30 +3062,30 @@ static void free_anim_seq(Sequence *seq)
}
/* check whether sequence cur depends on seq */
-int BKE_sequence_check_depend(Sequence *seq, Sequence *cur)
+bool BKE_sequence_check_depend(Sequence *seq, Sequence *cur)
{
if (cur->seq1 == seq || cur->seq2 == seq || cur->seq3 == seq)
- return TRUE;
+ return true;
/* sequences are not intersecting in time, assume no dependency exists between them */
if (cur->enddisp < seq->startdisp || cur->startdisp > seq->enddisp)
- return FALSE;
+ return false;
/* checking sequence is below reference one, not dependent on it */
if (cur->machine < seq->machine)
- return FALSE;
+ return false;
/* sequence is not blending with lower machines, no dependency here occurs
* check for non-effects only since effect could use lower machines as input
*/
if ((cur->type & SEQ_TYPE_EFFECT) == 0 &&
- ((cur->blend_mode == SEQ_BLEND_REPLACE) ||
- (cur->blend_mode == SEQ_TYPE_CROSS && cur->blend_opacity == 100.0f)))
+ ((cur->blend_mode == SEQ_BLEND_REPLACE) ||
+ (cur->blend_mode == SEQ_TYPE_CROSS && cur->blend_opacity == 100.0f)))
{
- return FALSE;
+ return false;
}
- return TRUE;
+ return true;
}
static void sequence_do_invalidate_dependent(Sequence *seq, ListBase *seqbase)
@@ -3291,7 +3291,7 @@ void BKE_sequence_tx_set_final_right(Sequence *seq, int val)
/* used so we can do a quick check for single image seq
* since they work a bit differently to normal image seq's (during transform) */
-int BKE_sequence_single_check(Sequence *seq)
+bool BKE_sequence_single_check(Sequence *seq)
{
return ((seq->len == 1) &&
(seq->type == SEQ_TYPE_IMAGE ||
@@ -3300,21 +3300,21 @@ int BKE_sequence_single_check(Sequence *seq)
}
/* check if the selected seq's reference unselected seq's */
-int BKE_sequence_base_isolated_sel_check(ListBase *seqbase)
+bool BKE_sequence_base_isolated_sel_check(ListBase *seqbase)
{
Sequence *seq;
/* is there more than 1 select */
- int ok = FALSE;
+ bool ok = false;
for (seq = seqbase->first; seq; seq = seq->next) {
if (seq->flag & SELECT) {
- ok = TRUE;
+ ok = true;
break;
}
}
- if (ok == FALSE)
- return FALSE;
+ if (ok == false)
+ return false;
/* test relationships */
for (seq = seqbase->first; seq; seq = seq->next) {
@@ -3322,24 +3322,24 @@ int BKE_sequence_base_isolated_sel_check(ListBase *seqbase)
continue;
if (seq->flag & SELECT) {
- if ( (seq->seq1 && (seq->seq1->flag & SELECT) == 0) ||
- (seq->seq2 && (seq->seq2->flag & SELECT) == 0) ||
- (seq->seq3 && (seq->seq3->flag & SELECT) == 0) )
+ if ((seq->seq1 && (seq->seq1->flag & SELECT) == 0) ||
+ (seq->seq2 && (seq->seq2->flag & SELECT) == 0) ||
+ (seq->seq3 && (seq->seq3->flag & SELECT) == 0) )
{
- return FALSE;
+ return false;
}
}
else {
- if ( (seq->seq1 && (seq->seq1->flag & SELECT)) ||
- (seq->seq2 && (seq->seq2->flag & SELECT)) ||
- (seq->seq3 && (seq->seq3->flag & SELECT)) )
+ if ((seq->seq1 && (seq->seq1->flag & SELECT)) ||
+ (seq->seq2 && (seq->seq2->flag & SELECT)) ||
+ (seq->seq3 && (seq->seq3->flag & SELECT)) )
{
- return FALSE;
+ return false;
}
}
}
- return TRUE;
+ return true;
}
/* use to impose limits when dragging/extending - so impossible situations don't happen
@@ -3405,29 +3405,29 @@ void BKE_sequence_single_fix(Sequence *seq)
}
}
-int BKE_sequence_tx_test(Sequence *seq)
+bool BKE_sequence_tx_test(Sequence *seq)
{
return (seq->type < SEQ_TYPE_EFFECT) || (BKE_sequence_effect_get_num_inputs(seq->type) == 0);
}
-static int seq_overlap(Sequence *seq1, Sequence *seq2)
+static bool seq_overlap(Sequence *seq1, Sequence *seq2)
{
return (seq1 != seq2 && seq1->machine == seq2->machine &&
((seq1->enddisp <= seq2->startdisp) || (seq1->startdisp >= seq2->enddisp)) == 0);
}
-int BKE_sequence_test_overlap(ListBase *seqbasep, Sequence *test)
+bool BKE_sequence_test_overlap(ListBase *seqbasep, Sequence *test)
{
Sequence *seq;
seq = seqbasep->first;
while (seq) {
if (seq_overlap(test, seq))
- return 1;
+ return true;
seq = seq->next;
}
- return 0;
+ return false;
}
@@ -3487,7 +3487,7 @@ Sequence *BKE_sequencer_foreground_frame_get(Scene *scene, int frame)
}
/* return 0 if there werent enough space */
-int BKE_sequence_base_shuffle(ListBase *seqbasep, Sequence *test, Scene *evil_scene)
+bool BKE_sequence_base_shuffle(ListBase *seqbasep, Sequence *test, Scene *evil_scene)
{
int orig_machine = test->machine;
test->machine++;
@@ -3518,10 +3518,10 @@ int BKE_sequence_base_shuffle(ListBase *seqbasep, Sequence *test, Scene *evil_sc
BKE_sequence_translate(evil_scene, test, new_frame - test->start);
BKE_sequence_calc(evil_scene, test);
- return 0;
+ return false;
}
else {
- return 1;
+ return true;
}
}
@@ -3572,7 +3572,7 @@ static int shuffle_seq_time_offset(Scene *scene, ListBase *seqbasep, char dir)
return tot_ofs;
}
-int BKE_sequence_base_shuffle_time(ListBase *seqbasep, Scene *evil_scene)
+bool BKE_sequence_base_shuffle_time(ListBase *seqbasep, Scene *evil_scene)
{
/* note: seq->tmp is used to tag strips to move */
@@ -3591,7 +3591,7 @@ int BKE_sequence_base_shuffle_time(ListBase *seqbasep, Scene *evil_scene)
}
}
- return offset ? 0 : 1;
+ return offset ? false : true;
}
void BKE_sequencer_update_sound_bounds_all(Scene *scene)
@@ -3861,7 +3861,7 @@ Sequence *BKE_sequence_get_by_name(ListBase *seqbase, const char *name, int recu
Sequence *rseq = NULL;
for (iseq = seqbase->first; iseq; iseq = iseq->next) {
- if (strcmp(name, iseq->name + 2) == 0)
+ if (STREQ(name, iseq->name + 2))
return iseq;
else if (recursive && (iseq->seqbase.first) && (rseq = BKE_sequence_get_by_name(&iseq->seqbase, name, 1))) {
return rseq;
@@ -4072,7 +4072,7 @@ Sequence *BKE_sequencer_add_sound_strip(bContext *C, ListBase *seqbasep, SeqLoad
if (sound == NULL || sound->playback_handle == NULL) {
#if 0
- if (op)
+ if (op)
BKE_report(op->reports, RPT_ERROR, "Unsupported audio format");
#endif
@@ -4324,7 +4324,7 @@ void BKE_sequence_base_dupli_recursive(Scene *scene, Scene *scene_to, ListBase *
/* called on draw, needs to be fast,
* we could cache and use a flag if we want to make checks for file paths resolving for eg. */
-int BKE_sequence_is_valid_check(Sequence *seq)
+bool BKE_sequence_is_valid_check(Sequence *seq)
{
switch (seq->type) {
case SEQ_TYPE_MASK:
@@ -4337,6 +4337,6 @@ int BKE_sequence_is_valid_check(Sequence *seq)
return (seq->sound != NULL);
}
- return TRUE;
+ return true;
}
diff --git a/source/blender/blenkernel/intern/smoke.c b/source/blender/blenkernel/intern/smoke.c
index 248cd689258..435e81556ab 100644
--- a/source/blender/blenkernel/intern/smoke.c
+++ b/source/blender/blenkernel/intern/smoke.c
@@ -1776,6 +1776,8 @@ static void update_flowsfluids(Scene *scene, Object *ob, SmokeDomainSettings *sd
dy = gy - sds->res_min[1];
dz = gz - sds->res_min[2];
d_index = smoke_get_index(dx, sds->res[0], dy, sds->res[1], dz);
+ /* make sure emission cell is inside the new domain boundary */
+ if (dx < 0 || dy < 0 || dz < 0 || dx >= sds->res[0] || dy >= sds->res[1] || dz >= sds->res[2]) continue;
if (sfs->type == MOD_SMOKE_FLOW_TYPE_OUTFLOW) { // outflow
apply_outflow_fields(d_index, density, heat, fuel, react, color_r, color_g, color_b);
@@ -2284,7 +2286,9 @@ struct DerivedMesh *smokeModifier_do(SmokeModifierData *smd, Scene *scene, Objec
{
return createDomainGeometry(smd->domain, ob);
}
- else return CDDM_copy(dm);
+ else {
+ return CDDM_copy(dm);
+ }
}
static float calc_voxel_transp(float *result, float *input, int res[3], int *pixel, float *tRay, float correct)
diff --git a/source/blender/blenkernel/intern/softbody.c b/source/blender/blenkernel/intern/softbody.c
index e2c6df5e528..8e5e0da20f9 100644
--- a/source/blender/blenkernel/intern/softbody.c
+++ b/source/blender/blenkernel/intern/softbody.c
@@ -200,18 +200,18 @@ static float sb_time_scale(Object *ob)
SoftBody *sb= ob->soft; /* is supposed to be there */
if (sb) {
return(sb->physics_speed);
- /*hrms .. this could be IPO as well :)
- estimated range [0.001 sluggish slug - 100.0 very fast (i hope ODE solver can handle that)]
- 1 approx = a unit 1 pendulum at g = 9.8 [earth conditions] has period 65 frames
- theory would give a 50 frames period .. so there must be something inaccurate .. looking for that (BM)
+ /* hrms .. this could be IPO as well :)
+ * estimated range [0.001 sluggish slug - 100.0 very fast (i hope ODE solver can handle that)]
+ * 1 approx = a unit 1 pendulum at g = 9.8 [earth conditions] has period 65 frames
+ * theory would give a 50 frames period .. so there must be something inaccurate .. looking for that (BM)
*/
}
return (1.0f);
/*
- this would be frames/sec independent timing assuming 25 fps is default
- but does not work very well with NLA
- return (25.0f/scene->r.frs_sec)
- */
+ * this would be frames/sec independent timing assuming 25 fps is default
+ * but does not work very well with NLA
+ * return (25.0f/scene->r.frs_sec)
+ */
}
/*--- frame based timing ---*/
@@ -1034,7 +1034,7 @@ static int sb_detect_aabb_collisionCached(float UNUSED(force[3]), unsigned int U
hash = vertexowner->soft->scratch->colliderhash;
ihash = BLI_ghashIterator_new(hash);
- while (!BLI_ghashIterator_isDone(ihash) ) {
+ while (BLI_ghashIterator_notDone(ihash) ) {
ccd_Mesh *ccdm = BLI_ghashIterator_getValue (ihash);
ob = BLI_ghashIterator_getKey (ihash);
@@ -1113,7 +1113,7 @@ static int sb_detect_face_pointCached(float face_v1[3], float face_v2[3], float
hash = vertexowner->soft->scratch->colliderhash;
ihash = BLI_ghashIterator_new(hash);
- while (!BLI_ghashIterator_isDone(ihash) ) {
+ while (BLI_ghashIterator_notDone(ihash) ) {
ccd_Mesh *ccdm = BLI_ghashIterator_getValue (ihash);
ob = BLI_ghashIterator_getKey (ihash);
@@ -1205,7 +1205,7 @@ static int sb_detect_face_collisionCached(float face_v1[3], float face_v2[3], fl
hash = vertexowner->soft->scratch->colliderhash;
ihash = BLI_ghashIterator_new(hash);
- while (!BLI_ghashIterator_isDone(ihash) ) {
+ while (BLI_ghashIterator_notDone(ihash) ) {
ccd_Mesh *ccdm = BLI_ghashIterator_getValue (ihash);
ob = BLI_ghashIterator_getKey (ihash);
@@ -1305,7 +1305,7 @@ static int sb_detect_face_collisionCached(float face_v1[3], float face_v2[3], fl
normalize_v3(d_nvect);
if (
/* isect_line_tri_v3(nv1, nv3, face_v1, face_v2, face_v3, &t, NULL) ||
- we did that edge already */
+ * we did that edge already */
isect_line_tri_v3(nv3, nv4, face_v1, face_v2, face_v3, &t, NULL) ||
isect_line_tri_v3(nv4, nv1, face_v1, face_v2, face_v3, &t, NULL) ) {
Vec3PlusStVec(force, -0.5f, d_nvect);
@@ -1433,7 +1433,7 @@ static int sb_detect_edge_collisionCached(float edge_v1[3], float edge_v2[3], fl
hash = vertexowner->soft->scratch->colliderhash;
ihash = BLI_ghashIterator_new(hash);
- while (!BLI_ghashIterator_isDone(ihash) ) {
+ while (BLI_ghashIterator_notDone(ihash) ) {
ccd_Mesh *ccdm = BLI_ghashIterator_getValue (ihash);
ob = BLI_ghashIterator_getKey (ihash);
@@ -1763,7 +1763,7 @@ static int sb_detect_vertex_collisionCached(float opco[3], float facenormal[3],
outerforceaccu[0]=outerforceaccu[1]=outerforceaccu[2]=0.0f;
innerforceaccu[0]=innerforceaccu[1]=innerforceaccu[2]=0.0f;
/* go */
- while (!BLI_ghashIterator_isDone(ihash) ) {
+ while (BLI_ghashIterator_notDone(ihash) ) {
ccd_Mesh *ccdm = BLI_ghashIterator_getValue (ihash);
ob = BLI_ghashIterator_getKey (ihash);
diff --git a/source/blender/blenkernel/intern/subsurf_ccg.c b/source/blender/blenkernel/intern/subsurf_ccg.c
index 3c90da60103..3d633dc964a 100644
--- a/source/blender/blenkernel/intern/subsurf_ccg.c
+++ b/source/blender/blenkernel/intern/subsurf_ccg.c
@@ -3103,7 +3103,6 @@ static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss,
int numTex, numCol;
int hasPCol, hasOrigSpace;
int gridInternalEdges;
- float *w = NULL;
WeightTable wtable = {0};
/* MCol *mcol; */ /* UNUSED */
MEdge *medge = NULL;
@@ -3307,7 +3306,7 @@ static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss,
int numFinalEdges = numVerts * (gridSideEdges + gridInternalEdges);
int origIndex = GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(f));
int g2_wid = gridCuts + 2;
- float *w2;
+ float *w, *w2;
int s, x, y;
w = get_ss_weights(&wtable, gridCuts, numVerts);
@@ -3320,8 +3319,6 @@ static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss,
faceFlags->mat_nr = mpoly ? mpoly[origIndex].mat_nr : 0;
faceFlags++;
- origIndex = base_polyOrigIndex ? base_polyOrigIndex[origIndex] : origIndex;
-
/* set the face base vert */
*((int *)ccgSubSurf_getFaceUserData(ss, f)) = vertNum;
@@ -3429,7 +3426,7 @@ static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss,
faceOrigIndex++;
}
if (polyOrigIndex) {
- *polyOrigIndex = origIndex;
+ *polyOrigIndex = base_polyOrigIndex ? base_polyOrigIndex[origIndex] : origIndex;
polyOrigIndex++;
}
diff --git a/source/blender/blenkernel/intern/text.c b/source/blender/blenkernel/intern/text.c
index 184984352ba..3936c533a41 100644
--- a/source/blender/blenkernel/intern/text.c
+++ b/source/blender/blenkernel/intern/text.c
@@ -791,6 +791,29 @@ int txt_utf8_index_to_offset(const char *str, int index)
return offset;
}
+int txt_utf8_offset_to_column(const char *str, int offset)
+{
+ int column = 0, pos = 0;
+ while (pos < offset) {
+ column += BLI_str_utf8_char_width_safe(str + pos);
+ pos += BLI_str_utf8_size_safe(str + pos);
+ }
+ return column;
+}
+
+int txt_utf8_column_to_offset(const char *str, int column)
+{
+ int offset = 0, pos = 0, col;
+ while (pos < column) {
+ col = BLI_str_utf8_char_width_safe(str + offset);
+ if (pos + col > column)
+ break;
+ offset += BLI_str_utf8_size_safe(str + offset);
+ pos += col;
+ }
+ return offset;
+}
+
/* returns the real number of characters in string */
/* not the same as BLI_strlen_utf8, which returns length for wide characters */
static int txt_utf8_len(const char *src)
@@ -804,6 +827,17 @@ static int txt_utf8_len(const char *src)
return len;
}
+static int txt_utf8_width(const char *src)
+{
+ int col = 0;
+
+ for (; *src; src += BLI_str_utf8_size(src)) {
+ col += BLI_str_utf8_char_width(src);
+ }
+
+ return col;
+}
+
void txt_move_up(Text *text, short sel)
{
TextLine **linep;
@@ -815,10 +849,10 @@ void txt_move_up(Text *text, short sel)
if (!*linep) return;
if ((*linep)->prev) {
- int index = txt_utf8_offset_to_index((*linep)->line, *charp);
+ int column = txt_utf8_offset_to_column((*linep)->line, *charp);
*linep = (*linep)->prev;
- if (index > txt_utf8_len((*linep)->line)) *charp = (*linep)->len;
- else *charp = txt_utf8_index_to_offset((*linep)->line, index);
+ if (column > txt_utf8_width((*linep)->line)) *charp = (*linep)->len;
+ else *charp = txt_utf8_column_to_offset((*linep)->line, column);
}
else {
@@ -839,10 +873,10 @@ void txt_move_down(Text *text, short sel)
if (!*linep) return;
if ((*linep)->next) {
- int index = txt_utf8_offset_to_index((*linep)->line, *charp);
+ int column = txt_utf8_offset_to_column((*linep)->line, *charp);
*linep = (*linep)->next;
- if (index > txt_utf8_len((*linep)->line)) *charp = (*linep)->len;
- else *charp = txt_utf8_index_to_offset((*linep)->line, index);
+ if (column > txt_utf8_width((*linep)->line)) *charp = (*linep)->len;
+ else *charp = txt_utf8_column_to_offset((*linep)->line, column);
}
else {
txt_move_eol(text, sel);
@@ -930,7 +964,9 @@ void txt_move_right(Text *text, short sel)
tabsize++;
(*charp) = i;
}
- else (*charp) += BLI_str_utf8_size((*linep)->line + *charp);
+ else {
+ (*charp) += BLI_str_utf8_size((*linep)->line + *charp);
+ }
}
if (!sel) txt_pop_sel(text);
@@ -2825,7 +2861,7 @@ void txt_move_lines(struct Text *text, const int direction)
}
}
-int setcurr_tab_spaces(Text *text, int space)
+int txt_setcurr_tab_spaces(Text *text, int space)
{
int i = 0;
int test = 0;
diff --git a/source/blender/blenkernel/intern/texture.c b/source/blender/blenkernel/intern/texture.c
index 55a0f3752a1..bdf2ce622de 100644
--- a/source/blender/blenkernel/intern/texture.c
+++ b/source/blender/blenkernel/intern/texture.c
@@ -256,7 +256,9 @@ int do_colorband(const ColorBand *coba, float in, float out[4])
left.pos = 0.0f;
cbd2 = &left;
}
- else cbd2 = cbd1 - 1;
+ else {
+ cbd2 = cbd1 - 1;
+ }
if (in >= cbd1->pos && coba->ipotype < 2) {
out[0] = cbd1->r;
@@ -440,7 +442,7 @@ void default_tex(Tex *tex)
tex->type = TEX_CLOUDS;
tex->stype = 0;
tex->flag = TEX_CHECKER_ODD;
- tex->imaflag = TEX_INTERPOL | TEX_MIPMAP;
+ tex->imaflag = TEX_INTERPOL | TEX_MIPMAP | TEX_USEALPHA;
tex->extend = TEX_REPEAT;
tex->cropxmin = tex->cropymin = 0.0;
tex->cropxmax = tex->cropymax = 1.0;
@@ -911,15 +913,18 @@ void autotexname(Tex *tex)
else if (tex->type == TEX_IMAGE) {
ima = tex->ima;
if (ima) {
- BLI_strncpy(di, ima->name, sizeof(di));
- BLI_splitdirstring(di, fi);
+ BLI_split_file_part(ima->name, fi, sizeof(fi));
strcpy(di, "I.");
strcat(di, fi);
new_id(&bmain->tex, (ID *)tex, di);
}
- else new_id(&bmain->tex, (ID *)tex, texstr[tex->type]);
+ else {
+ new_id(&bmain->tex, (ID *)tex, texstr[tex->type]);
+ }
+ }
+ else {
+ new_id(&bmain->tex, (ID *)tex, texstr[tex->type]);
}
- else new_id(&bmain->tex, (ID *)tex, texstr[tex->type]);
}
}
#endif
diff --git a/source/blender/blenkernel/intern/tracking.c b/source/blender/blenkernel/intern/tracking.c
index f63a1f2cec0..df10d1374bb 100644
--- a/source/blender/blenkernel/intern/tracking.c
+++ b/source/blender/blenkernel/intern/tracking.c
@@ -261,7 +261,9 @@ void BKE_tracking_get_projection_matrix(MovieTracking *tracking, MovieTrackingOb
invert_m4_m4(imat, camera->mat);
mult_m4_m4m4(mat, winmat, imat);
}
- else copy_m4_m4(mat, winmat);
+ else {
+ copy_m4_m4(mat, winmat);
+ }
}
/* **** space transformation functions **** */
@@ -1189,6 +1191,7 @@ MovieTrackingObject *BKE_tracking_object_add(MovieTracking *tracking, const char
object->keyframe2 = 30;
BKE_tracking_object_unique_name(tracking, object);
+ BKE_tracking_dopesheet_tag_update(tracking);
return object;
}
@@ -1223,6 +1226,9 @@ int BKE_tracking_object_delete(MovieTracking *tracking, MovieTrackingObject *obj
tracking->objectnr = index - 1;
else
tracking->objectnr = 0;
+
+ BKE_tracking_dopesheet_tag_update(tracking);
+
return TRUE;
}
@@ -1446,7 +1452,7 @@ static void cameraIntrinscisOptionsFromTracking(libmv_cameraIntrinsicsOptions *c
camera_intrinsics_options->k3 = camera->k3;
camera_intrinsics_options->image_width = calibration_width;
- camera_intrinsics_options->image_height = (double) calibration_height * aspy;
+ camera_intrinsics_options->image_height = (double) (calibration_height * aspy);
}
#endif
@@ -1456,6 +1462,10 @@ MovieDistortion *BKE_tracking_distortion_new(void)
distortion = MEM_callocN(sizeof(MovieDistortion), "BKE_tracking_distortion_create");
+#ifdef WITH_LIBMV
+ distortion->intrinsics = libmv_CameraIntrinsicsNewEmpty();
+#endif
+
return distortion;
}
@@ -1468,12 +1478,7 @@ void BKE_tracking_distortion_update(MovieDistortion *distortion, MovieTracking *
cameraIntrinscisOptionsFromTracking(&camera_intrinsics_options, tracking,
calibration_width, calibration_height);
- if (!distortion->intrinsics) {
- distortion->intrinsics = libmv_CameraIntrinsicsNew(&camera_intrinsics_options);
- }
- else {
- libmv_CameraIntrinsicsUpdate(distortion->intrinsics, &camera_intrinsics_options);
- }
+ libmv_CameraIntrinsicsUpdate(distortion->intrinsics, &camera_intrinsics_options);
#else
(void) distortion;
(void) tracking;
@@ -1482,6 +1487,16 @@ void BKE_tracking_distortion_update(MovieDistortion *distortion, MovieTracking *
#endif
}
+void BKE_tracking_distortion_set_threads(MovieDistortion *distortion, int threads)
+{
+#ifdef WITH_LIBMV
+ libmv_CameraIntrinsicsSetThreads(distortion->intrinsics, threads);
+#else
+ (void) distortion;
+ (void) threads;
+#endif
+}
+
MovieDistortion *BKE_tracking_distortion_copy(MovieDistortion *distortion)
{
MovieDistortion *new_distortion;
@@ -1594,8 +1609,8 @@ void BKE_tracking_undistort_v2(MovieTracking *tracking, const float co[2], float
libmv_InvertIntrinsics(&camera_intrinsics_options, x, y, &x, &y);
- r_co[0] = x * camera->focal + camera->principal[0];
- r_co[1] = y * camera->focal + camera->principal[1] * aspy;
+ r_co[0] = (float)x * camera->focal + camera->principal[0];
+ r_co[1] = (float)y * camera->focal + camera->principal[1] * aspy;
#else
(void) camera;
(void) co;
@@ -1699,7 +1714,7 @@ static void disable_imbuf_channels(ImBuf *ibuf, MovieTrackingTrack *track, int g
ImBuf *BKE_tracking_sample_pattern(int frame_width, int frame_height, ImBuf *search_ibuf,
MovieTrackingTrack *track, MovieTrackingMarker *marker,
- int use_mask, int num_samples_x, int num_samples_y,
+ int from_anchor, int use_mask, int num_samples_x, int num_samples_y,
float pos[2])
{
#ifdef WITH_LIBMV
@@ -1719,6 +1734,28 @@ ImBuf *BKE_tracking_sample_pattern(int frame_width, int frame_height, ImBuf *sea
get_marker_coords_for_tracking(frame_width, frame_height, marker, src_pixel_x, src_pixel_y);
+ /* from_anchor means search buffer was obtained for an anchored position,
+ * which means applying track offset rounded to pixel space (we could not
+ * store search buffer with sub-pixel precision)
+ *
+ * in this case we need to alter coordinates a bit, to compensate rounded
+ * fractional part of offset
+ */
+ if (from_anchor) {
+ int a;
+
+ for (a = 0; a < 5; a++) {
+ src_pixel_x[a] += (double) ((track->offset[0] * frame_width) - ((int) (track->offset[0] * frame_width)));
+ src_pixel_y[a] += (double) ((track->offset[1] * frame_height) - ((int) (track->offset[1] * frame_height)));
+
+ /* when offset is negative, rounding happens in opposite direction */
+ if (track->offset[0] < 0.0f)
+ src_pixel_x[a] += 1.0;
+ if (track->offset[1] < 0.0f)
+ src_pixel_y[a] += 1.0;
+ }
+ }
+
if (use_mask) {
mask = BKE_tracking_track_get_mask(frame_width, frame_height, track, marker);
}
@@ -1751,6 +1788,7 @@ ImBuf *BKE_tracking_sample_pattern(int frame_width, int frame_height, ImBuf *sea
(void) frame_height;
(void) search_ibuf;
(void) marker;
+ (void) from_anchor;
(void) track;
(void) use_mask;
@@ -1779,7 +1817,7 @@ ImBuf *BKE_tracking_get_pattern_imbuf(ImBuf *ibuf, MovieTrackingTrack *track, Mo
if (search_ibuf) {
pattern_ibuf = BKE_tracking_sample_pattern(ibuf->x, ibuf->y, search_ibuf, track, marker,
- FALSE, num_samples_x, num_samples_y, NULL);
+ anchored, FALSE, num_samples_x, num_samples_y, NULL);
IMB_freeImBuf(search_ibuf);
}
@@ -2726,7 +2764,7 @@ static void reconstruct_retrieve_libmv_intrinscis(MovieReconstructContext *conte
tracking->camera.focal = focal_length;
tracking->camera.principal[0] = principal_x;
- tracking->camera.principal[1] = principal_y / aspy;
+ tracking->camera.principal[1] = principal_y / (double)aspy;
tracking->camera.k1 = k1;
tracking->camera.k2 = k2;
diff --git a/source/blender/blenkernel/intern/unit.c b/source/blender/blenkernel/intern/unit.c
index dd6ed42bd92..066b6eff5c5 100644
--- a/source/blender/blenkernel/intern/unit.c
+++ b/source/blender/blenkernel/intern/unit.c
@@ -104,7 +104,7 @@ typedef struct bUnitCollection {
/* Dummy */
static struct bUnitDef buDummyDef[] = { {"", NULL, "", NULL, NULL, 1.0, 0.0}, {NULL, NULL, NULL, NULL, NULL, 0.0, 0.0}};
-static struct bUnitCollection buDummyCollecton = {buDummyDef, 0, 0, sizeof(buDummyDef)};
+static struct bUnitCollection buDummyCollection = {buDummyDef, 0, 0, sizeof(buDummyDef)};
/* Lengths */
static struct bUnitDef buMetricLenDef[] = {
@@ -125,7 +125,7 @@ static struct bUnitDef buMetricLenDef[] = {
#endif
{NULL, NULL, NULL, NULL, NULL, 0.0, 0.0}
};
-static struct bUnitCollection buMetricLenCollecton = {buMetricLenDef, 3, 0, sizeof(buMetricLenDef) / sizeof(bUnitDef)};
+static struct bUnitCollection buMetricLenCollection = {buMetricLenDef, 3, 0, sizeof(buMetricLenDef) / sizeof(bUnitDef)};
static struct bUnitDef buImperialLenDef[] = {
{"mile", "miles", "mi", "m", "Miles", UN_SC_MI, 0.0, B_UNIT_DEF_NONE},
@@ -137,7 +137,7 @@ static struct bUnitDef buImperialLenDef[] = {
{"thou", "thou", "thou", "mil", "Thou", UN_SC_MIL, 0.0, B_UNIT_DEF_NONE}, /* plural for thou has no 's' */
{NULL, NULL, NULL, NULL, NULL, 0.0, 0.0}
};
-static struct bUnitCollection buImperialLenCollecton = {buImperialLenDef, 4, 0, sizeof(buImperialLenDef) / sizeof(bUnitDef)};
+static struct bUnitCollection buImperialLenCollection = {buImperialLenDef, 4, 0, sizeof(buImperialLenDef) / sizeof(bUnitDef)};
/* Areas */
static struct bUnitDef buMetricAreaDef[] = {
@@ -151,7 +151,7 @@ static struct bUnitDef buMetricAreaDef[] = {
{"square micrometer", "square micrometers", "µm²", "um2", "Square Micrometers", UN_SC_UM * UN_SC_UM, 0.0, B_UNIT_DEF_NONE},
{NULL, NULL, NULL, NULL, NULL, 0.0, 0.0}
};
-static struct bUnitCollection buMetricAreaCollecton = {buMetricAreaDef, 3, 0, sizeof(buMetricAreaDef) / sizeof(bUnitDef)};
+static struct bUnitCollection buMetricAreaCollection = {buMetricAreaDef, 3, 0, sizeof(buMetricAreaDef) / sizeof(bUnitDef)};
static struct bUnitDef buImperialAreaDef[] = {
{"square mile", "square miles", "sq mi", "sq m", "Square Miles", UN_SC_MI * UN_SC_MI, 0.0, B_UNIT_DEF_NONE},
@@ -163,7 +163,7 @@ static struct bUnitDef buImperialAreaDef[] = {
{"square thou", "square thous", "sq mil", NULL, "Square Thous", UN_SC_MIL * UN_SC_MIL, 0.0, B_UNIT_DEF_NONE},
{NULL, NULL, NULL, NULL, NULL, 0.0, 0.0}
};
-static struct bUnitCollection buImperialAreaCollecton = {buImperialAreaDef, 4, 0, sizeof(buImperialAreaDef) / sizeof(bUnitDef)};
+static struct bUnitCollection buImperialAreaCollection = {buImperialAreaDef, 4, 0, sizeof(buImperialAreaDef) / sizeof(bUnitDef)};
/* Volumes */
static struct bUnitDef buMetricVolDef[] = {
@@ -177,7 +177,7 @@ static struct bUnitDef buMetricVolDef[] = {
{"cubic micrometer", "cubic micrometers", "µm³", "um3", "Cubic Micrometers", UN_SC_UM * UN_SC_UM * UN_SC_UM, 0.0, B_UNIT_DEF_NONE},
{NULL, NULL, NULL, NULL, NULL, 0.0, 0.0}
};
-static struct bUnitCollection buMetricVolCollecton = {buMetricVolDef, 3, 0, sizeof(buMetricVolDef) / sizeof(bUnitDef)};
+static struct bUnitCollection buMetricVolCollection = {buMetricVolDef, 3, 0, sizeof(buMetricVolDef) / sizeof(bUnitDef)};
static struct bUnitDef buImperialVolDef[] = {
{"cubic mile", "cubic miles", "cu mi", "cu m", "Cubic Miles", UN_SC_MI * UN_SC_MI * UN_SC_MI, 0.0, B_UNIT_DEF_NONE},
@@ -189,7 +189,7 @@ static struct bUnitDef buImperialVolDef[] = {
{"cubic thou", "cubic thous", "cu mil", NULL, "Cubic Thous", UN_SC_MIL * UN_SC_MIL * UN_SC_MIL, 0.0, B_UNIT_DEF_NONE},
{NULL, NULL, NULL, NULL, NULL, 0.0, 0.0}
};
-static struct bUnitCollection buImperialVolCollecton = {buImperialVolDef, 4, 0, sizeof(buImperialVolDef) / sizeof(bUnitDef)};
+static struct bUnitCollection buImperialVolCollection = {buImperialVolDef, 4, 0, sizeof(buImperialVolDef) / sizeof(bUnitDef)};
/* Mass */
static struct bUnitDef buMetricMassDef[] = {
@@ -201,7 +201,7 @@ static struct bUnitDef buMetricMassDef[] = {
{"gram", "grams", "g", NULL, "Grams", UN_SC_G, 0.0, B_UNIT_DEF_NONE},
{NULL, NULL, NULL, NULL, NULL, 0.0, 0.0}
};
-static struct bUnitCollection buMetricMassCollecton = {buMetricMassDef, 2, 0, sizeof(buMetricMassDef) / sizeof(bUnitDef)};
+static struct bUnitCollection buMetricMassCollection = {buMetricMassDef, 2, 0, sizeof(buMetricMassDef) / sizeof(bUnitDef)};
static struct bUnitDef buImperialMassDef[] = {
{"ton", "tonnes", "ton", "t", "Tonnes", UN_SC_ITON, 0.0, B_UNIT_DEF_NONE},
@@ -211,7 +211,7 @@ static struct bUnitDef buImperialMassDef[] = {
{"ounce", "ounces", "oz", NULL, "Ounces", UN_SC_OZ, 0.0, B_UNIT_DEF_NONE},
{NULL, NULL, NULL, NULL, NULL, 0.0, 0.0}
};
-static struct bUnitCollection buImperialMassCollecton = {buImperialMassDef, 3, 0, sizeof(buImperialMassDef) / sizeof(bUnitDef)};
+static struct bUnitCollection buImperialMassCollection = {buImperialMassDef, 3, 0, sizeof(buImperialMassDef) / sizeof(bUnitDef)};
/* Even if user scales the system to a point where km^3 is used, velocity and
* acceleration aren't scaled: that's why we have so few units for them */
@@ -222,27 +222,27 @@ static struct bUnitDef buMetricVelDef[] = {
{"kilometer per hour", "kilometers per hour", "km/h", NULL, "Kilometers per hour", UN_SC_KM / 3600.0f, 0.0, B_UNIT_DEF_SUPPRESS},
{NULL, NULL, NULL, NULL, NULL, 0.0, 0.0}
};
-static struct bUnitCollection buMetricVelCollecton = {buMetricVelDef, 0, 0, sizeof(buMetricVelDef) / sizeof(bUnitDef)};
+static struct bUnitCollection buMetricVelCollection = {buMetricVelDef, 0, 0, sizeof(buMetricVelDef) / sizeof(bUnitDef)};
static struct bUnitDef buImperialVelDef[] = {
{"foot per second", "feet per second", "ft/s", "fps", "Feet per second", UN_SC_FT, 0.0, B_UNIT_DEF_NONE}, /* base unit */
{"mile per hour", "miles per hour", "mph", NULL, "Miles per hour", UN_SC_MI / 3600.0f, 0.0, B_UNIT_DEF_SUPPRESS},
{NULL, NULL, NULL, NULL, NULL, 0.0, 0.0}
};
-static struct bUnitCollection buImperialVelCollecton = {buImperialVelDef, 0, 0, sizeof(buImperialVelDef) / sizeof(bUnitDef)};
+static struct bUnitCollection buImperialVelCollection = {buImperialVelDef, 0, 0, sizeof(buImperialVelDef) / sizeof(bUnitDef)};
/* Acceleration */
static struct bUnitDef buMetricAclDef[] = {
{"meter per second squared", "meters per second squared", "m/s²", "m/s2", "Meters per second squared", UN_SC_M, 0.0, B_UNIT_DEF_NONE}, /* base unit */
{NULL, NULL, NULL, NULL, NULL, 0.0, 0.0}
};
-static struct bUnitCollection buMetricAclCollecton = {buMetricAclDef, 0, 0, sizeof(buMetricAclDef) / sizeof(bUnitDef)};
+static struct bUnitCollection buMetricAclCollection = {buMetricAclDef, 0, 0, sizeof(buMetricAclDef) / sizeof(bUnitDef)};
static struct bUnitDef buImperialAclDef[] = {
{"foot per second squared", "feet per second squared", "ft/s²", "ft/s2", "Feet per second squared", UN_SC_FT, 0.0, B_UNIT_DEF_NONE}, /* base unit */
{NULL, NULL, NULL, NULL, NULL, 0.0, 0.0}
};
-static struct bUnitCollection buImperialAclCollecton = {buImperialAclDef, 0, 0, sizeof(buImperialAclDef) / sizeof(bUnitDef)};
+static struct bUnitCollection buImperialAclCollection = {buImperialAclDef, 0, 0, sizeof(buImperialAclDef) / sizeof(bUnitDef)};
/* Time */
static struct bUnitDef buNaturalTimeDef[] = {
@@ -255,7 +255,7 @@ static struct bUnitDef buNaturalTimeDef[] = {
{"microsecond", "microseconds", "µs", "us", "Microseconds", 0.000001, 0.0, B_UNIT_DEF_NONE},
{NULL, NULL, NULL, NULL, NULL, 0.0, 0.0}
};
-static struct bUnitCollection buNaturalTimeCollecton = {buNaturalTimeDef, 3, 0, sizeof(buNaturalTimeDef) / sizeof(bUnitDef)};
+static struct bUnitCollection buNaturalTimeCollection = {buNaturalTimeDef, 3, 0, sizeof(buNaturalTimeDef) / sizeof(bUnitDef)};
static struct bUnitDef buNaturalRotDef[] = {
@@ -266,12 +266,24 @@ static struct bUnitDef buNaturalRotDef[] = {
};
static struct bUnitCollection buNaturalRotCollection = {buNaturalRotDef, 0, 0, sizeof(buNaturalRotDef) / sizeof(bUnitDef)};
-#define UNIT_SYSTEM_TOT (((sizeof(bUnitSystems) / 9) / sizeof(void *)) - 1)
-static struct bUnitCollection *bUnitSystems[][9] = {
- {NULL, NULL, NULL, NULL, NULL, &buNaturalRotCollection, &buNaturalTimeCollecton, NULL, NULL},
- {NULL, &buMetricLenCollecton, &buMetricAreaCollecton, &buMetricVolCollecton, &buMetricMassCollecton, &buNaturalRotCollection, &buNaturalTimeCollecton, &buMetricVelCollecton, &buMetricAclCollecton}, /* metric */
- {NULL, &buImperialLenCollecton, &buImperialAreaCollecton, &buImperialVolCollecton, &buImperialMassCollecton, &buNaturalRotCollection, &buNaturalTimeCollecton, &buImperialVelCollecton, &buImperialAclCollecton}, /* imperial */
- {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}
+/* Camera Lengths */
+static struct bUnitDef buCameraLenDef[] = {
+ {"meter", "meters", "m", NULL, "Meters", UN_SC_KM, 0.0, B_UNIT_DEF_NONE}, /* base unit */
+ {"decimeter", "decimeters", "dm", NULL, "10 Centimeters", UN_SC_HM, 0.0, B_UNIT_DEF_SUPPRESS},
+ {"centimeter", "centimeters", "cm", NULL, "Centimeters", UN_SC_DAM, 0.0, B_UNIT_DEF_SUPPRESS},
+ {"millimeter", "millimeters", "mm", NULL, "Millimeters", UN_SC_M, 0.0, B_UNIT_DEF_NONE},
+ {"micrometer", "micrometers", "µm", "um", "Micrometers", UN_SC_MM, 0.0, B_UNIT_DEF_SUPPRESS}, // micron too?
+ {NULL, NULL, NULL, NULL, NULL, 0.0, 0.0}
+};
+static struct bUnitCollection buCameraLenCollection = {buCameraLenDef, 3, 0, sizeof(buCameraLenDef) / sizeof(bUnitDef)};
+
+
+#define UNIT_SYSTEM_TOT (((sizeof(bUnitSystems) / B_UNIT_TYPE_TOT) / sizeof(void *)) - 1)
+static struct bUnitCollection *bUnitSystems[][B_UNIT_TYPE_TOT] = {
+ {NULL, NULL, NULL, NULL, NULL, &buNaturalRotCollection, &buNaturalTimeCollection, NULL, NULL, NULL},
+ {NULL, &buMetricLenCollection, &buMetricAreaCollection, &buMetricVolCollection, &buMetricMassCollection, &buNaturalRotCollection, &buNaturalTimeCollection, &buMetricVelCollection, &buMetricAclCollection, &buCameraLenCollection}, /* metric */
+ {NULL, &buImperialLenCollection, &buImperialAreaCollection, &buImperialVolCollection, &buImperialMassCollection, &buNaturalRotCollection, &buNaturalTimeCollection, &buImperialVelCollection, &buImperialAclCollection, &buCameraLenCollection}, /* imperial */
+ {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}
};
@@ -395,10 +407,10 @@ void bUnit_AsString(char *str, int len_max, double value, int prec, int system,
bUnitCollection *usys = unit_get_system(system, type);
if (usys == NULL || usys->units[0].name == NULL)
- usys = &buDummyCollecton;
+ usys = &buDummyCollection;
/* split output makes sense only for length, mass and time */
- if (split && (type == B_UNIT_LENGTH || type == B_UNIT_MASS || type == B_UNIT_TIME)) {
+ if (split && (type == B_UNIT_LENGTH || type == B_UNIT_MASS || type == B_UNIT_TIME || type == B_UNIT_CAMERA)) {
bUnitDef *unit_a, *unit_b;
double value_a, value_b;
@@ -706,7 +718,7 @@ void bUnit_ToUnitAltName(char *str, int len_max, const char *orig_str, int syste
/* print the alt_name */
if (unit->name_alt)
- len_name = BLI_snprintf(str, len_max, "%s", unit->name_alt);
+ len_name = BLI_strncpy_rlen(str, unit->name_alt, len_max);
else
len_name = 0;
diff --git a/source/blender/blenkernel/intern/writeffmpeg.c b/source/blender/blenkernel/intern/writeffmpeg.c
index 7e51025883d..a88a9e4954b 100644
--- a/source/blender/blenkernel/intern/writeffmpeg.c
+++ b/source/blender/blenkernel/intern/writeffmpeg.c
@@ -111,8 +111,9 @@ static void delete_picture(AVFrame *f)
}
}
-static int use_float_audio_buffer(int codec_id)
+static int request_float_audio_buffer(int codec_id)
{
+ /* If any of these codecs, we prefer the float sample format (if supported) */
return codec_id == CODEC_ID_AAC || codec_id == CODEC_ID_AC3 || codec_id == CODEC_ID_VORBIS;
}
@@ -551,6 +552,12 @@ static AVStream *alloc_video_stream(RenderData *rd, int codec_id, AVFormatContex
}
}
+ if (codec_id == CODEC_ID_PNG) {
+ if (rd->im_format.planes == R_IMF_PLANES_RGBA) {
+ c->pix_fmt = PIX_FMT_ARGB;
+ }
+ }
+
if ((of->oformat->flags & AVFMT_GLOBALHEADER)
// || !strcmp(of->oformat->name, "mp4")
// || !strcmp(of->oformat->name, "mov")
@@ -623,16 +630,55 @@ static AVStream *alloc_audio_stream(RenderData *rd, int codec_id, AVFormatContex
c->bit_rate = ffmpeg_audio_bitrate * 1000;
c->sample_fmt = AV_SAMPLE_FMT_S16;
c->channels = rd->ffcodecdata.audio_channels;
- if (use_float_audio_buffer(codec_id)) {
+
+ if (request_float_audio_buffer(codec_id)) {
+ /* mainly for AAC codec which is experimental */
c->strict_std_compliance = FF_COMPLIANCE_EXPERIMENTAL;
c->sample_fmt = AV_SAMPLE_FMT_FLT;
}
+
codec = avcodec_find_encoder(c->codec_id);
if (!codec) {
//XXX error("Couldn't find a valid audio codec");
return NULL;
}
+ if (codec->sample_fmts) {
+ /* check if the prefered sample format for this codec is supported.
+ * this is because, depending on the version of libav, and with the whole ffmpeg/libav fork situation,
+ * you have various implementations around. float samples in particular are not always supported.
+ */
+ const enum AVSampleFormat *p = codec->sample_fmts;
+ for (; *p!=-1; p++) {
+ if (*p == st->codec->sample_fmt)
+ break;
+ }
+ if (*p == -1) {
+ /* sample format incompatible with codec. Defaulting to a format known to work */
+ st->codec->sample_fmt = codec->sample_fmts[0];
+ }
+ }
+
+ if (c->sample_fmt == AV_SAMPLE_FMT_FLTP) {
+ BLI_strncpy(error, "Requested audio codec requires planar float sample format, which is not supported yet", error_size);
+ return NULL;
+ }
+
+ if (codec->supported_samplerates) {
+ const int *p = codec->supported_samplerates;
+ int best = 0;
+ int best_dist = INT_MAX;
+ for (; *p; p++) {
+ int dist = abs(st->codec->sample_rate - *p);
+ if (dist < best_dist) {
+ best_dist = dist;
+ best = *p;
+ }
+ }
+ /* best is the closest supported sample rate (same as selected if best_dist == 0) */
+ st->codec->sample_rate = best;
+ }
+
set_ffmpeg_properties(rd, c, "audio");
if (avcodec_open2(c, codec, NULL) < 0) {
@@ -658,7 +704,7 @@ static AVStream *alloc_audio_stream(RenderData *rd, int codec_id, AVFormatContex
audio_output_buffer = (uint8_t *) av_malloc(audio_outbuf_size);
- if (use_float_audio_buffer(codec_id)) {
+ if (c->sample_fmt == AV_SAMPLE_FMT_FLT) {
audio_input_buffer = (uint8_t *) av_malloc(audio_input_samples * c->channels * sizeof(float));
}
else {
@@ -740,7 +786,7 @@ static int start_ffmpeg_impl(struct RenderData *rd, int rectx, int recty, Report
fmt->audio_codec = ffmpeg_audio_codec;
- BLI_snprintf(of->filename, sizeof(of->filename), "%s", name);
+ BLI_strncpy(of->filename, name, sizeof(of->filename));
/* set the codec to the user's selection */
switch (ffmpeg_type) {
case FFMPEG_AVI:
@@ -837,7 +883,8 @@ static int start_ffmpeg_impl(struct RenderData *rd, int rectx, int recty, Report
}
if (avformat_write_header(of, NULL) < 0) {
BKE_report(reports, RPT_ERROR, "Could not initialize streams, probably unsupported codec combination");
- av_dict_free(&opts);
+ av_dict_free(&opts);
+ avio_close(of->pb);
return 0;
}
@@ -963,7 +1010,7 @@ int BKE_ffmpeg_start(struct Scene *scene, RenderData *rd, int rectx, int recty,
AVCodecContext *c = audio_stream->codec;
AUD_DeviceSpecs specs;
specs.channels = c->channels;
- if (use_float_audio_buffer(c->codec_id)) {
+ if (c->sample_fmt == AV_SAMPLE_FMT_FLT) {
specs.format = AUD_FORMAT_FLOAT32;
}
else {
@@ -980,7 +1027,6 @@ int BKE_ffmpeg_start(struct Scene *scene, RenderData *rd, int rectx, int recty,
return success;
}
-void BKE_ffmpeg_end(void);
static void end_ffmpeg_impl(int is_autosplit);
#ifdef WITH_AUDASPACE
@@ -1493,6 +1539,9 @@ int BKE_ffmpeg_alpha_channel_is_supported(RenderData *rd)
if (codec == CODEC_ID_QTRLE)
return TRUE;
+ if (codec == CODEC_ID_PNG)
+ return TRUE;
+
#ifdef FFMPEG_FFV1_ALPHA_SUPPORTED
if (codec == CODEC_ID_FFV1)
return TRUE;
diff --git a/source/blender/blenlib/BLI_buffer.h b/source/blender/blenlib/BLI_buffer.h
index 880a97acb80..fe835e7cadc 100644
--- a/source/blender/blenlib/BLI_buffer.h
+++ b/source/blender/blenlib/BLI_buffer.h
@@ -52,6 +52,7 @@ enum {
};
#define BLI_buffer_declare_static(type_, name_, flag_, static_count_) \
+ char name_ ## user; /* warn for free only */ \
type_ *name_ ## _static_[static_count_]; \
BLI_Buffer name_ = { \
/* clear the static memory if this is a calloc'd array */ \
@@ -66,15 +67,26 @@ enum {
/* never use static*/
#define BLI_buffer_declare(type_, name_, flag_) \
+ bool name_ ## user; /* warn for free only */ \
BLI_Buffer name_ = {NULL, \
sizeof(type_), \
0, \
0, \
flag_}
-
#define BLI_buffer_at(buffer_, type_, index_) ( \
- (((type_ *)(buffer_)->data)[(BLI_assert(sizeof(type_) == (buffer_)->elem_size)), index_]))
+ (((type_ *)(buffer_)->data)[ \
+ (BLI_assert(sizeof(type_) == (buffer_)->elem_size)), \
+ (BLI_assert(index_ >= 0 && index_ < (buffer_)->count)), \
+ index_]))
+
+#define BLI_buffer_array(buffer_, type_) ( \
+ &(BLI_buffer_at(buffer_, type_, 0)))
+
+#define BLI_buffer_resize_data(buffer_, type_, new_count_) ( \
+ (BLI_buffer_resize(buffer_, new_count_), new_count_ ? BLI_buffer_array(buffer_, type_) : NULL))
+
+
#define BLI_buffer_append(buffer_, type_, val_) ( \
BLI_buffer_resize(buffer_, (buffer_)->count + 1), \
@@ -85,6 +97,10 @@ enum {
void BLI_buffer_resize(BLI_Buffer *buffer, int new_count);
/* Does not free the buffer structure itself */
-void BLI_buffer_free(BLI_Buffer *buffer);
+void _bli_buffer_free(BLI_Buffer *buffer);
+#define BLI_buffer_free(name_) { \
+ _bli_buffer_free(name_); \
+ (void)name_ ## user; /* ensure we free */ \
+} (void)0
#endif /* __BLI_BUFFER_H__ */
diff --git a/source/blender/blenlib/BLI_fileops.h b/source/blender/blenlib/BLI_fileops.h
index c278370d211..b0e3f47b627 100644
--- a/source/blender/blenlib/BLI_fileops.h
+++ b/source/blender/blenlib/BLI_fileops.h
@@ -34,14 +34,12 @@
#define __BLI_FILEOPS_H__
#include <stdio.h>
-
+#include <sys/stat.h>
#ifdef __cplusplus
extern "C" {
#endif
-#include "BLI_fileops_types.h"
-
/* for size_t (needed on windows) */
#include <stddef.h>
@@ -52,7 +50,7 @@ struct gzFile;
int BLI_exists(const char *path);
int BLI_copy(const char *path, const char *to);
int BLI_rename(const char *from, const char *to);
-int BLI_delete(const char *path, int dir, int recursive);
+int BLI_delete(const char *path, bool dir, bool recursive);
int BLI_move(const char *path, const char *to);
int BLI_create_symlink(const char *path, const char *to);
int BLI_stat(const char *path, struct stat *buffer);
@@ -61,22 +59,24 @@ int BLI_stat(const char *path, struct stat *buffer);
struct direntry;
-int BLI_is_dir(const char *path);
-int BLI_is_file(const char *path);
+bool BLI_is_dir(const char *path);
+bool BLI_is_file(const char *path);
void BLI_dir_create_recursive(const char *dir);
double BLI_dir_free_space(const char *dir);
char *BLI_current_working_dir(char *dir, const size_t maxlen);
unsigned int BLI_dir_contents(const char *dir, struct direntry **filelist);
+void BLI_free_filelist(struct direntry * filelist, unsigned int nrentries);
/* Files */
FILE *BLI_fopen(const char *filename, const char *mode);
void *BLI_gzopen(const char *filename, const char *mode);
int BLI_open(const char *filename, int oflag, int pmode);
+int BLI_access(const char *filename, int mode);
-int BLI_file_is_writable(const char *file);
-int BLI_file_touch(const char *file);
+bool BLI_file_is_writable(const char *file);
+bool BLI_file_touch(const char *file);
int BLI_file_gzip(const char *from, const char *to);
char *BLI_file_ungzip_to_mem(const char *from_file, int *size_r);
@@ -85,7 +85,7 @@ size_t BLI_file_descriptor_size(int file);
size_t BLI_file_size(const char *file);
/* compare if one was last modified before the other */
-int BLI_file_older(const char *file1, const char *file2);
+bool BLI_file_older(const char *file1, const char *file2);
/* read ascii file as lines, empty list if reading fails */
struct LinkNode *BLI_file_read_as_lines(const char *file);
@@ -104,5 +104,4 @@ void BLI_get_short_name(char short_name[256], const char *filename);
}
#endif
-#endif
-
+#endif /* __BLI_FILEOPS_H__ */
diff --git a/source/blender/blenlib/BLI_fileops_types.h b/source/blender/blenlib/BLI_fileops_types.h
index 1c6463eb6ea..a7372c01e52 100644
--- a/source/blender/blenlib/BLI_fileops_types.h
+++ b/source/blender/blenlib/BLI_fileops_types.h
@@ -42,7 +42,6 @@ typedef unsigned int mode_t;
struct ImBuf;
struct direntry {
- char *string;
mode_t type;
char *relname;
char *path;
diff --git a/source/blender/blenlib/BLI_ghash.h b/source/blender/blenlib/BLI_ghash.h
index 7eac1425a5c..97564ca5363 100644
--- a/source/blender/blenlib/BLI_ghash.h
+++ b/source/blender/blenlib/BLI_ghash.h
@@ -69,9 +69,9 @@ GHash *BLI_ghash_new(GHashHashFP hashfp, GHashCmpFP cmpfp, const char *info);
void BLI_ghash_free(GHash *gh, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfreefp);
void BLI_ghash_insert(GHash *gh, void *key, void *val);
void *BLI_ghash_lookup(GHash *gh, const void *key);
-int BLI_ghash_remove(GHash *gh, void *key, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfreefp);
+bool BLI_ghash_remove(GHash *gh, void *key, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfreefp);
void *BLI_ghash_pop(GHash *gh, void *key, GHashKeyFreeFP keyfreefp);
-int BLI_ghash_haskey(GHash *gh, const void *key);
+bool BLI_ghash_haskey(GHash *gh, const void *key);
int BLI_ghash_size(GHash *gh);
/* *** */
@@ -130,11 +130,11 @@ void BLI_ghashIterator_step(GHashIterator *ghi);
* \param ghi The iterator.
* \return True if done, False otherwise.
*/
-int BLI_ghashIterator_isDone(GHashIterator *ghi);
+bool BLI_ghashIterator_notDone(GHashIterator *ghi);
#define GHASH_ITER(gh_iter_, ghash_) \
for (BLI_ghashIterator_init(&gh_iter_, ghash_); \
- !BLI_ghashIterator_isDone(&gh_iter_); \
+ BLI_ghashIterator_notDone(&gh_iter_); \
BLI_ghashIterator_step(&gh_iter_))
/* *** */
diff --git a/source/blender/blenlib/BLI_gsqueue.h b/source/blender/blenlib/BLI_gsqueue.h
index b4cb1edd45a..b9d8a8f9d14 100644
--- a/source/blender/blenlib/BLI_gsqueue.h
+++ b/source/blender/blenlib/BLI_gsqueue.h
@@ -47,7 +47,7 @@ GSQueue *BLI_gsqueue_new(int elem_size);
/**
* Query if the queue is empty
*/
-int BLI_gsqueue_is_empty(GSQueue *gq);
+bool BLI_gsqueue_is_empty(GSQueue *gq);
/**
* Query number elements in the queue
diff --git a/source/blender/blenlib/BLI_heap.h b/source/blender/blenlib/BLI_heap.h
index c0941e00c9b..bc7b6000322 100644
--- a/source/blender/blenlib/BLI_heap.h
+++ b/source/blender/blenlib/BLI_heap.h
@@ -54,7 +54,7 @@ HeapNode *BLI_heap_insert(Heap *heap, float value, void *ptr);
void BLI_heap_remove(Heap *heap, HeapNode *node);
/* Return 0 if the heap is empty, 1 otherwise. */
-int BLI_heap_is_empty(Heap *heap);
+bool BLI_heap_is_empty(Heap *heap);
/* Return the size of the heap. */
unsigned int BLI_heap_size(Heap *heap);
diff --git a/source/blender/blenlib/BLI_lasso.h b/source/blender/blenlib/BLI_lasso.h
index a7e90a51e86..0addd463a70 100644
--- a/source/blender/blenlib/BLI_lasso.h
+++ b/source/blender/blenlib/BLI_lasso.h
@@ -35,7 +35,7 @@
struct rcti;
void BLI_lasso_boundbox(struct rcti *rect, const int mcords[][2], const short moves);
-int BLI_lasso_is_point_inside(const int mcords[][2], const short moves, const int sx, const int sy, const int error_value);
-int BLI_lasso_is_edge_inside(const int mcords[][2], const short moves, int x0, int y0, int x1, int y1, const int error_value);
+bool BLI_lasso_is_point_inside(const int mcords[][2], const short moves, const int sx, const int sy, const int error_value);
+bool BLI_lasso_is_edge_inside(const int mcords[][2], const short moves, int x0, int y0, int x1, int y1, const int error_value);
#endif
diff --git a/source/blender/blenlib/BLI_linklist.h b/source/blender/blenlib/BLI_linklist.h
index da56a300b9b..3e7fdc8bf75 100644
--- a/source/blender/blenlib/BLI_linklist.h
+++ b/source/blender/blenlib/BLI_linklist.h
@@ -59,6 +59,7 @@ void BLI_linklist_prepend_arena(struct LinkNode **listp, void *ptr, struct Me
void BLI_linklist_insert_after(struct LinkNode **listp, void *ptr);
void BLI_linklist_free(struct LinkNode *list, LinkNodeFreeFP freefunc);
+void BLI_linklist_freeN(struct LinkNode *list);
void BLI_linklist_apply(struct LinkNode *list, LinkNodeApplyFP applyfunc, void *userdata);
#endif
diff --git a/source/blender/blenlib/BLI_math_base.h b/source/blender/blenlib/BLI_math_base.h
index aa4e697b48b..67c1ffcebc0 100644
--- a/source/blender/blenlib/BLI_math_base.h
+++ b/source/blender/blenlib/BLI_math_base.h
@@ -179,6 +179,11 @@
#include "intern/math_base_inline.c"
#endif
+#ifdef BLI_MATH_GCC_WARN_PRAGMA
+# pragma GCC diagnostic push
+# pragma GCC diagnostic ignored "-Wredundant-decls"
+#endif
+
/******************************* Float ******************************/
MINLINE float sqrt3f(float f);
@@ -217,6 +222,10 @@ extern double round(double x);
double double_round(double x, int ndigits);
+#ifdef BLI_MATH_GCC_WARN_PRAGMA
+# pragma GCC diagnostic pop
+#endif
+
/* asserts, some math functions expect normalized inputs
* check the vector is unit length, or zero length (which can't be helped in some cases).
*/
diff --git a/source/blender/blenlib/BLI_math_geom.h b/source/blender/blenlib/BLI_math_geom.h
index 13f47d94160..94fa88801f0 100644
--- a/source/blender/blenlib/BLI_math_geom.h
+++ b/source/blender/blenlib/BLI_math_geom.h
@@ -40,6 +40,11 @@ extern "C" {
#include "intern/math_geom_inline.c"
#endif
+#ifdef BLI_MATH_GCC_WARN_PRAGMA
+# pragma GCC diagnostic push
+# pragma GCC diagnostic ignored "-Wredundant-decls"
+#endif
+
/********************************** Polygons *********************************/
void cent_tri_v3(float r[3], const float a[3], const float b[3], const float c[3]);
@@ -130,13 +135,15 @@ int isect_ray_tri_epsilon_v3(const float p1[3], const float d[3],
const float v0[3], const float v1[3], const float v2[3], float *r_lambda, float r_uv[2], const float epsilon);
/* point in polygon */
+bool isect_point_poly_v2(const float pt[2], const float verts[][2], const int nr);
+bool isect_point_poly_v2_int(const int pt[2], const int verts[][2], const int nr);
+
int isect_point_quad_v2(const float p[2], const float a[2], const float b[2], const float c[2], const float d[2]);
int isect_point_tri_v2(const float pt[2], const float v1[2], const float v2[2], const float v3[2]);
int isect_point_tri_v2_cw(const float pt[2], const float v1[2], const float v2[2], const float v3[2]);
int isect_point_tri_v2_int(const int x1, const int y1, const int x2, const int y2, const int a, const int b);
int isect_point_tri_prism_v3(const float p[3], const float v1[3], const float v2[3], const float v3[3]);
-
void isect_point_quad_uv_v2(const float v0[2], const float v1[2], const float v2[2], const float v3[2],
const float pt[2], float r_uv[2]);
void isect_point_face_uv_v2(const int isquad, const float v0[2], const float v1[2], const float v2[2],
@@ -281,6 +288,10 @@ MINLINE int min_axis_v3(const float vec[3]);
MINLINE int poly_to_tri_count(const int poly_count, const int corner_count);
+#ifdef BLI_MATH_GCC_WARN_PRAGMA
+# pragma GCC diagnostic pop
+#endif
+
#ifdef __cplusplus
}
#endif
diff --git a/source/blender/blenlib/BLI_math_inline.h b/source/blender/blenlib/BLI_math_inline.h
index 6dad44644f2..2bf3b9532dd 100644
--- a/source/blender/blenlib/BLI_math_inline.h
+++ b/source/blender/blenlib/BLI_math_inline.h
@@ -56,6 +56,11 @@ extern "C" {
# define MALWAYS_INLINE
#endif
+/* gcc 4.6 (supports push/pop) */
+#if (defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 406))
+# define BLI_MATH_GCC_WARN_PRAGMA 1
+#endif
+
#ifdef __cplusplus
}
#endif
diff --git a/source/blender/blenlib/BLI_math_vector.h b/source/blender/blenlib/BLI_math_vector.h
index 42a6b90f738..c9ad19f74b4 100644
--- a/source/blender/blenlib/BLI_math_vector.h
+++ b/source/blender/blenlib/BLI_math_vector.h
@@ -42,6 +42,11 @@ extern "C" {
/************************************* Init ***********************************/
+#ifdef BLI_MATH_GCC_WARN_PRAGMA
+# pragma GCC diagnostic push
+# pragma GCC diagnostic ignored "-Wredundant-decls"
+#endif
+
MINLINE void zero_v2(float r[2]);
MINLINE void zero_v3(float r[3]);
MINLINE void zero_v4(float r[4]);
@@ -108,6 +113,7 @@ MINLINE void mul_v3_v3(float r[3], const float a[3]);
MINLINE void mul_v3_v3v3(float r[3], const float a[3], const float b[3]);
MINLINE void mul_v4_fl(float r[4], float f);
MINLINE void mul_v4_v4fl(float r[3], const float a[3], float f);
+MINLINE float mul_project_m4_v3_zfac(float mat[4][4], const float co[3]);
MINLINE void madd_v3_v3fl(float r[3], const float a[3], float f);
MINLINE void madd_v3_v3v3(float r[3], const float a[3], const float b[3]);
@@ -260,6 +266,10 @@ void fill_vn_i(int *array_tar, const int size, const int val);
void fill_vn_ushort(unsigned short *array_tar, const int size, const unsigned short val);
void fill_vn_fl(float *array_tar, const int size, const float val);
+#ifdef BLI_MATH_GCC_WARN_PRAGMA
+# pragma GCC diagnostic pop
+#endif
+
#ifdef __cplusplus
}
#endif
diff --git a/source/blender/blenlib/BLI_path_util.h b/source/blender/blenlib/BLI_path_util.h
index 8c51c925d97..20fc489cbc3 100644
--- a/source/blender/blenlib/BLI_path_util.h
+++ b/source/blender/blenlib/BLI_path_util.h
@@ -40,10 +40,10 @@ struct direntry;
const char *BLI_getDefaultDocumentFolder(void);
-char *BLI_get_folder(int folder_id, const char *subfolder);
-char *BLI_get_folder_create(int folder_id, const char *subfolder);
-char *BLI_get_user_folder_notest(int folder_id, const char *subfolder);
-char *BLI_get_folder_version(const int id, const int ver, const int do_check);
+const char *BLI_get_folder(int folder_id, const char *subfolder);
+const char *BLI_get_folder_create(int folder_id, const char *subfolder);
+const char *BLI_get_user_folder_notest(int folder_id, const char *subfolder);
+const char *BLI_get_folder_version(const int id, const int ver, const bool do_check);
/* folder_id */
@@ -86,11 +86,11 @@ void BLI_setenv_if_new(const char *env, const char *val);
void BLI_make_file_string(const char *relabase, char *string, const char *dir, const char *file);
void BLI_make_exist(char *dir);
void BLI_make_existing_file(const char *name);
-void BLI_split_dirfile(const char *string, char *dir, char *file, const size_t dirlen, const size_t filelen);
-void BLI_split_dir_part(const char *string, char *dir, const size_t dirlen);
-void BLI_split_file_part(const char *string, char *file, const size_t filelen);
-void BLI_join_dirfile(char *string, const size_t maxlen, const char *dir, const char *file);
-char *BLI_path_basename(char *path);
+void BLI_split_dirfile(const char *string, char *dir, char *file, size_t dirlen, size_t filelen);
+void BLI_split_dir_part(const char *string, char *dir, size_t dirlen);
+void BLI_split_file_part(const char *string, char *file, size_t filelen);
+void BLI_join_dirfile(char *string, size_t maxlen, const char *dir, const char *file);
+const char *BLI_path_basename(const char *path);
typedef enum bli_rebase_state {
BLI_REBASE_NO_SRCDIR = 0,
@@ -100,24 +100,24 @@ typedef enum bli_rebase_state {
int BLI_rebase_path(char *abs, size_t abs_len, char *rel, size_t rel_len, const char *base_dir, const char *src_dir, const char *dest_dir);
-char *BLI_last_slash(const char *string);
-int BLI_add_slash(char *string);
-void BLI_del_slash(char *string);
-char *BLI_first_slash(char *string);
-
-void BLI_getlastdir(const char *dir, char *last, const size_t maxlen);
-int BLI_testextensie(const char *str, const char *ext);
-int BLI_testextensie_array(const char *str, const char **ext_array);
-int BLI_testextensie_glob(const char *str, const char *ext_fnmatch);
-int BLI_replace_extension(char *path, size_t maxlen, const char *ext);
-int BLI_ensure_extension(char *path, size_t maxlen, const char *ext);
-void BLI_uniquename(struct ListBase *list, void *vlink, const char defname[], char delim, short name_offs, short len);
-int BLI_uniquename_cb(int (*unique_check)(void *, const char *), void *arg, const char defname[], char delim, char *name, short name_len);
+const char *BLI_last_slash(const char *string);
+int BLI_add_slash(char *string);
+void BLI_del_slash(char *string);
+const char *BLI_first_slash(const char *string);
+
+void BLI_getlastdir(const char *dir, char *last, size_t maxlen);
+bool BLI_testextensie(const char *str, const char *ext);
+bool BLI_testextensie_array(const char *str, const char **ext_array);
+bool BLI_testextensie_glob(const char *str, const char *ext_fnmatch);
+bool BLI_replace_extension(char *path, size_t maxlen, const char *ext);
+bool BLI_ensure_extension(char *path, size_t maxlen, const char *ext);
+void BLI_uniquename(struct ListBase *list, void *vlink, const char * defname, char delim, short name_offs, short len);
+bool BLI_uniquename_cb(bool (*unique_check)(void * arg, const char * name),
+ void *arg, const char * defname, char delim, char *name, short name_len);
void BLI_newname(char *name, int add);
int BLI_stringdec(const char *string, char *head, char *start, unsigned short *numlen);
void BLI_stringenc(char *string, const char *head, const char *tail, unsigned short numlen, int pic);
-int BLI_split_name_num(char *left, int *nr, const char *name, const char delim);
-void BLI_splitdirstring(char *di, char *fi);
+int BLI_split_name_num(char *left, int *nr, const char *name, char delim);
/* make sure path separators conform to system one */
void BLI_clean(char *path)
@@ -131,15 +131,15 @@ __attribute__((nonnull(1)))
* converts it to a regular full path.
* Also removes garbage from directory paths, like /../ or double slashes etc
*/
-void BLI_cleanup_file(const char *relabase, char *dir); /* removes trailing slash */
+void BLI_cleanup_file(const char *relabase, char *path); /* removes trailing slash */
void BLI_cleanup_dir(const char *relabase, char *dir); /* same as above but adds a trailing slash */
-void BLI_cleanup_path(const char *relabase, char *dir); /* doesn't touch trailing slash */
+void BLI_cleanup_path(const char *relabase, char *path); /* doesn't touch trailing slash */
/* go back one directory */
-int BLI_parent_dir(char *path);
+bool BLI_parent_dir(char *path);
/* return whether directory is root and thus has no parent dir */
-int BLI_has_parent(char *path);
+bool BLI_has_parent(char *path);
/**
* Blender's path code replacement function.
@@ -153,14 +153,15 @@ int BLI_has_parent(char *path);
* \a framenum The framenumber to replace the frame code with.
* \retval Returns true if the path was relative (started with "//").
*/
-int BLI_path_abs(char *path, const char *basepath);
-int BLI_path_frame(char *path, int frame, int digits);
-int BLI_path_frame_range(char *path, int sta, int end, int digits);
-int BLI_path_cwd(char *path);
+bool BLI_path_abs(char *path, const char *basepath);
+bool BLI_path_frame(char *path, int frame, int digits);
+bool BLI_path_frame_range(char *path, int sta, int end, int digits);
+bool BLI_path_cwd(char *path);
void BLI_path_rel(char *file, const char *relfile);
-int BLI_path_is_rel(const char *path);
+bool BLI_path_is_rel(const char *path);
+/* path string comparisons: case-insensitive for Windows, case-sensitive otherwise */
#ifdef WIN32
# define BLI_path_cmp BLI_strcasecmp
# define BLI_path_ncmp BLI_strncasecmp
diff --git a/source/blender/blenlib/BLI_rect.h b/source/blender/blenlib/BLI_rect.h
index 3c9363039b2..9ce75de5ea8 100644
--- a/source/blender/blenlib/BLI_rect.h
+++ b/source/blender/blenlib/BLI_rect.h
@@ -43,8 +43,8 @@ struct rcti;
extern "C" {
#endif
-int BLI_rcti_is_empty(const struct rcti *rect);
-int BLI_rctf_is_empty(const struct rctf *rect);
+bool BLI_rcti_is_empty(const struct rcti *rect);
+bool BLI_rctf_is_empty(const struct rctf *rect);
void BLI_rctf_init(struct rctf *rect, float xmin, float xmax, float ymin, float ymax);
void BLI_rcti_init(struct rcti *rect, int xmin, int xmax, int ymin, int ymax);
void BLI_rcti_init_minmax(struct rcti *rect);
@@ -60,18 +60,18 @@ void BLI_rcti_scale(rcti *rect, const float scale);
void BLI_rctf_scale(rctf *rect, const float scale);
void BLI_rctf_interp(struct rctf *rect, const struct rctf *rect_a, const struct rctf *rect_b, const float fac);
//void BLI_rcti_interp(struct rctf *rect, struct rctf *rect_a, struct rctf *rect_b, float fac);
-int BLI_rctf_clamp_pt_v(const struct rctf *rect, float xy[2]);
-int BLI_rcti_clamp_pt_v(const struct rcti *rect, int xy[2]);
-int BLI_rctf_compare(const struct rctf *rect_a, const struct rctf *rect_b, const float limit);
-int BLI_rcti_compare(const struct rcti *rect_a, const struct rcti *rect_b);
-int BLI_rctf_isect(const struct rctf *src1, const struct rctf *src2, struct rctf *dest);
-int BLI_rcti_isect(const struct rcti *src1, const struct rcti *src2, struct rcti *dest);
-int BLI_rcti_isect_pt(const struct rcti *rect, const int x, const int y);
-int BLI_rcti_isect_pt_v(const struct rcti *rect, const int xy[2]);
-int BLI_rctf_isect_pt(const struct rctf *rect, const float x, const float y);
-int BLI_rctf_isect_pt_v(const struct rctf *rect, const float xy[2]);
-int BLI_rcti_isect_segment(const struct rcti *rect, const int s1[2], const int s2[2]);
-int BLI_rctf_isect_segment(const struct rctf *rect, const float s1[2], const float s2[2]);
+bool BLI_rctf_clamp_pt_v(const struct rctf *rect, float xy[2]);
+bool BLI_rcti_clamp_pt_v(const struct rcti *rect, int xy[2]);
+bool BLI_rctf_compare(const struct rctf *rect_a, const struct rctf *rect_b, const float limit);
+bool BLI_rcti_compare(const struct rcti *rect_a, const struct rcti *rect_b);
+bool BLI_rctf_isect(const struct rctf *src1, const struct rctf *src2, struct rctf *dest);
+bool BLI_rcti_isect(const struct rcti *src1, const struct rcti *src2, struct rcti *dest);
+bool BLI_rcti_isect_pt(const struct rcti *rect, const int x, const int y);
+bool BLI_rcti_isect_pt_v(const struct rcti *rect, const int xy[2]);
+bool BLI_rctf_isect_pt(const struct rctf *rect, const float x, const float y);
+bool BLI_rctf_isect_pt_v(const struct rctf *rect, const float xy[2]);
+bool BLI_rcti_isect_segment(const struct rcti *rect, const int s1[2], const int s2[2]);
+bool BLI_rctf_isect_segment(const struct rctf *rect, const float s1[2], const float s2[2]);
void BLI_rctf_union(struct rctf *rctf1, const struct rctf *rctf2);
void BLI_rcti_union(struct rcti *rcti1, const struct rcti *rcti2);
void BLI_rcti_rctf_copy(struct rcti *dst, const struct rctf *src);
diff --git a/source/blender/blenlib/BLI_string.h b/source/blender/blenlib/BLI_string.h
index 70c89773f02..3bc9d733254 100644
--- a/source/blender/blenlib/BLI_string.h
+++ b/source/blender/blenlib/BLI_string.h
@@ -38,42 +38,20 @@
extern "C" {
#endif
-/**
- * Duplicates the cstring \a str into a newly mallocN'd
- * string and returns it.
- *
- * \param str The string to be duplicated
- * \retval Returns the duplicated string
- */
-char *BLI_strdup(const char *str)
+char *BLI_strdupn(const char *str, const size_t len)
#ifdef __GNUC__
__attribute__((warn_unused_result))
__attribute__((nonnull))
#endif
;
-/**
- * Duplicates the first \a len bytes of cstring \a str
- * into a newly mallocN'd string and returns it. \a str
- * is assumed to be at least len bytes long.
- *
- * \param str The string to be duplicated
- * \param len The number of bytes to duplicate
- * \retval Returns the duplicated string
- */
-char *BLI_strdupn(const char *str, const size_t len)
+char *BLI_strdup(const char *str)
#ifdef __GNUC__
__attribute__((warn_unused_result))
__attribute__((nonnull))
#endif
;
-/**
- * Appends the two strings, and returns new mallocN'ed string
- * \param str1 first string for copy
- * \param str2 second string for append
- * \retval Returns dst
- */
char *BLI_strdupcat(const char *__restrict str1, const char *__restrict str2)
#ifdef __GNUC__
__attribute__((warn_unused_result))
@@ -81,32 +59,19 @@ __attribute__((nonnull))
#endif
;
-/**
- * Like strncpy but ensures dst is always
- * '\0' terminated.
- *
- * \param dst Destination for copy
- * \param src Source string to copy
- * \param maxncpy Maximum number of characters to copy (generally
- * the size of dst)
- * \retval Returns dst
- */
char *BLI_strncpy(char *__restrict dst, const char *__restrict src, const size_t maxncpy)
#ifdef __GNUC__
__attribute__((nonnull))
#endif
;
-/**
- *Makes a copy of the text within the "" that appear after some text 'blahblah'
- * i.e. for string 'pose["apples"]' with prefix 'pose[', it should grab "apples"
- *
- * - str: is the entire string to chop
- * - prefix: is the part of the string to leave out
- *
- * Assume that the strings returned must be freed afterwards, and that the inputs will contain
- * data we want...
- */
+size_t BLI_strncpy_rlen(char *__restrict dst, const char *__restrict src, const size_t maxncpy)
+#ifdef __GNUC__
+__attribute__((warn_unused_result))
+__attribute__((nonnull))
+#endif
+;
+
char *BLI_str_quoted_substrN(const char *__restrict str, const char *__restrict prefix)
#ifdef __GNUC__
__attribute__((warn_unused_result))
@@ -114,16 +79,6 @@ __attribute__((nonnull))
#endif
;
-/**
- * Returns a copy of the cstring \a str into a newly mallocN'd
- * string with all instances of oldText replaced with newText,
- * and returns it.
- *
- * \param str The string to replace occurrences of oldText in
- * \param oldText The text in the string to find and replace
- * \param newText The text in the string to find and replace
- * \retval Returns the duplicated string
- */
char *BLI_replacestr(char *__restrict str, const char *__restrict oldText, const char *__restrict newText)
#ifdef __GNUC__
__attribute__((warn_unused_result))
@@ -131,9 +86,6 @@ __attribute__((nonnull))
#endif
;
-/*
- * Replacement for snprintf
- */
size_t BLI_snprintf(char *__restrict buffer, size_t len, const char *__restrict format, ...)
#ifdef __GNUC__
__attribute__ ((format(printf, 3, 4)))
@@ -141,19 +93,12 @@ __attribute__((nonnull))
#endif
;
-/*
- * Replacement for vsnprintf
- */
size_t BLI_vsnprintf(char *__restrict buffer, size_t count, const char *__restrict format, va_list arg)
#ifdef __GNUC__
__attribute__ ((format(printf, 3, 0)))
#endif
;
-/*
- * Print formatted string into a newly mallocN'd string
- * and return it.
- */
char *BLI_sprintfN(const char *__restrict format, ...)
#ifdef __GNUC__
__attribute__ ((format(printf, 1, 2)))
@@ -168,11 +113,6 @@ __attribute__((nonnull))
#endif
;
-/**
- * Compare two strings without regard to case.
- *
- * \retval True if the strings are equal, false otherwise.
- */
int BLI_strcaseeq(const char *a, const char *b)
#ifdef __GNUC__
__attribute__((warn_unused_result))
@@ -214,7 +154,7 @@ void BLI_timestr(double _time, char *str)
#ifdef __GNUC__
__attribute__((nonnull))
#endif
-; /* time var is global */
+;
void BLI_ascii_strtolower(char *str, const size_t len)
#ifdef __GNUC__
@@ -226,6 +166,11 @@ void BLI_ascii_strtoupper(char *str, const size_t len)
__attribute__((nonnull))
#endif
;
+int BLI_str_rstrip_float_zero(char *str, const char pad)
+#ifdef __GNUC__
+__attribute__((nonnull))
+#endif
+;
#ifdef __cplusplus
}
diff --git a/source/blender/blenlib/BLI_string_utf8.h b/source/blender/blenlib/BLI_string_utf8.h
index 30d5c28bf98..d20cbd2a91c 100644
--- a/source/blender/blenlib/BLI_string_utf8.h
+++ b/source/blender/blenlib/BLI_string_utf8.h
@@ -56,7 +56,14 @@ size_t BLI_strnlen_utf8(const char *start, const size_t maxlen);
size_t BLI_strncpy_wchar_as_utf8(char *__restrict dst, const wchar_t *__restrict src, const size_t maxcpy);
size_t BLI_strncpy_wchar_from_utf8(wchar_t *__restrict dst, const char *__restrict src, const size_t maxcpy);
-#define BLI_UTF8_MAX 6
+/* count columns that character/string occupies, based on wcwidth.c */
+int BLI_wcwidth(wchar_t ucs);
+int BLI_wcswidth(const wchar_t *pwcs, size_t n);
+int BLI_str_utf8_char_width(const char *p); /* warning, can return -1 on bad chars */
+int BLI_str_utf8_char_width_safe(const char *p);
+
+#define BLI_UTF8_MAX 6 /* mem */
+#define BLI_UTF8_WIDTH_MAX 2 /* columns */
#define BLI_UTF8_ERR ((unsigned int)-1)
#ifdef __cplusplus
diff --git a/source/blender/blenlib/BLI_utildefines.h b/source/blender/blenlib/BLI_utildefines.h
index bbafd28ddbc..bf5531d94af 100644
--- a/source/blender/blenlib/BLI_utildefines.h
+++ b/source/blender/blenlib/BLI_utildefines.h
@@ -167,7 +167,7 @@ typedef bool _BLI_Bool;
(b) = (tval); \
} (void)0
-
+/* ELEM#(a, ...): is the first arg equal any of the others */
#define ELEM(a, b, c) ((a) == (b) || (a) == (c))
#define ELEM3(a, b, c, d) (ELEM(a, b, c) || (a) == (d) )
#define ELEM4(a, b, c, d, e) (ELEM(a, b, c) || ELEM(a, d, e) )
@@ -295,9 +295,9 @@ typedef bool _BLI_Bool;
#define UNPACK3(a) ((a)[0]), ((a)[1]), ((a)[2])
#define UNPACK4(a) ((a)[0]), ((a)[1]), ((a)[2]), ((a)[3])
/* op may be '&' or '*' */
-#define UNPACK2OP(a, op) op((a)[0]), op((a)[1])
-#define UNPACK3OP(a, op) op((a)[0]), op((a)[1]), op((a)[2])
-#define UNPACK4OP(a, op) op((a)[0]), op((a)[1]), op((a)[2]), op((a)[3])
+#define UNPACK2OP(op, a) op((a)[0]), op((a)[1])
+#define UNPACK3OP(op, a) op((a)[0]), op((a)[1]), op((a)[2])
+#define UNPACK4OP(op, a) op((a)[0]), op((a)[1]), op((a)[2]), op((a)[3])
/* array helpers */
#define ARRAY_LAST_ITEM(arr_start, arr_dtype, elem_size, tot) \
@@ -326,6 +326,22 @@ typedef bool _BLI_Bool;
#define STRINGIFY_APPEND(a, b) "" a #b
#define STRINGIFY(x) STRINGIFY_APPEND("", x)
+/* generic strcmp macros */
+#define STREQ(a, b) (strcmp(a, b) == 0)
+#define STRNEQ(a, b) (!STREQ(a, b))
+
+#define STRCASEEQ(a, b) (strcasecmp(a, b) == 0)
+#define STRCASENEQ(a, b) (!STRCASEEQ(a, b))
+
+#define STREQLEN(a, b, n) (strncmp(a, b, n) == 0)
+#define STRNEQLEN(a, b, n) (!STREQLEN(a, b, n))
+
+#define STRCASEEQLEN(a, b, n) (strncasecmp(a, b, n) == 0)
+#define STRCASENEQLEN(a, b, n) (!STRCASEEQLEN(a, b, n))
+
+#define STRPREFIX(a, b) (strncmp((a), (b), strlen(b)) == 0)
+
+
/* useful for debugging */
#define AT __FILE__ ":" STRINGIFY(__LINE__)
diff --git a/source/blender/blenlib/BLI_winstuff.h b/source/blender/blenlib/BLI_winstuff.h
index 70c7f1d9cae..20a4c3c274e 100644
--- a/source/blender/blenlib/BLI_winstuff.h
+++ b/source/blender/blenlib/BLI_winstuff.h
@@ -94,6 +94,15 @@ extern "C" {
/* defines for using ISO C++ conformant names */
#define snprintf _snprintf
+#ifdef _MSC_VER
+# define R_OK 4
+# define W_OK 2
+// not accepted by access() on windows
+//# define X_OK 1
+# define F_OK 0
+# define PATH_MAX 4096
+#endif
+
#ifndef FREE_WINDOWS
typedef unsigned int mode_t;
#endif
diff --git a/source/blender/blenlib/CMakeLists.txt b/source/blender/blenlib/CMakeLists.txt
index 82ff09b5999..9b3fca280c4 100644
--- a/source/blender/blenlib/CMakeLists.txt
+++ b/source/blender/blenlib/CMakeLists.txt
@@ -29,6 +29,7 @@ set(INC
../makesdna
../../../intern/ghost
../../../intern/guardedalloc
+ ../../../extern/wcwidth
)
set(INC_SYS
diff --git a/source/blender/blenlib/SConscript b/source/blender/blenlib/SConscript
index 19216442aa0..79e2a47aeb8 100644
--- a/source/blender/blenlib/SConscript
+++ b/source/blender/blenlib/SConscript
@@ -31,7 +31,7 @@ sources = env.Glob('intern/*.c')
cflags=''
# don't add ../blenkernel back!
-incs = '. ../makesdna #/intern/guardedalloc #/intern/ghost'
+incs = '. ../makesdna #/intern/guardedalloc #/intern/ghost #/extern/wcwidth'
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 7ebe4430e20..ebc40ebc5e3 100644
--- a/source/blender/blenlib/intern/BLI_ghash.c
+++ b/source/blender/blenlib/intern/BLI_ghash.c
@@ -120,7 +120,7 @@ void *BLI_ghash_lookup(GHash *gh, const void *key)
return NULL;
}
-int BLI_ghash_remove(GHash *gh, void *key, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfreefp)
+bool BLI_ghash_remove(GHash *gh, void *key, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfreefp)
{
unsigned int hash = gh->hashfp(key) % gh->nbuckets;
Entry *e;
@@ -140,12 +140,12 @@ int BLI_ghash_remove(GHash *gh, void *key, GHashKeyFreeFP keyfreefp, GHashValFre
else gh->buckets[hash] = n;
gh->nentries--;
- return 1;
+ return true;
}
p = e;
}
- return 0;
+ return false;
}
/* same as above but return the value,
@@ -178,16 +178,16 @@ void *BLI_ghash_pop(GHash *gh, void *key, GHashKeyFreeFP keyfreefp)
return NULL;
}
-int BLI_ghash_haskey(GHash *gh, const void *key)
+bool BLI_ghash_haskey(GHash *gh, const void *key)
{
unsigned int hash = gh->hashfp(key) % gh->nbuckets;
Entry *e;
for (e = gh->buckets[hash]; e; e = e->next)
if (gh->cmpfp(key, e->key) == 0)
- return 1;
+ return true;
- return 0;
+ return false;
}
void BLI_ghash_free(GHash *gh, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfreefp)
@@ -271,9 +271,9 @@ void BLI_ghashIterator_step(GHashIterator *ghi)
}
}
}
-int BLI_ghashIterator_isDone(GHashIterator *ghi)
+bool BLI_ghashIterator_notDone(GHashIterator *ghi)
{
- return !ghi->curEntry;
+ return ghi->curEntry != NULL;
}
/***/
diff --git a/source/blender/blenlib/intern/BLI_heap.c b/source/blender/blenlib/intern/BLI_heap.c
index aa54969b6f8..53489c76962 100644
--- a/source/blender/blenlib/intern/BLI_heap.c
+++ b/source/blender/blenlib/intern/BLI_heap.c
@@ -33,9 +33,10 @@
#include <string.h>
#include "MEM_guardedalloc.h"
+
+#include "BLI_utildefines.h"
#include "BLI_memarena.h"
#include "BLI_heap.h"
-#include "BLI_utildefines.h"
/***/
@@ -183,7 +184,7 @@ HeapNode *BLI_heap_insert(Heap *heap, float value, void *ptr)
return node;
}
-int BLI_heap_is_empty(Heap *heap)
+bool BLI_heap_is_empty(Heap *heap)
{
return (heap->size == 0);
}
diff --git a/source/blender/blenlib/intern/BLI_linklist.c b/source/blender/blenlib/intern/BLI_linklist.c
index 0e630efc349..b08fbe17a43 100644
--- a/source/blender/blenlib/intern/BLI_linklist.c
+++ b/source/blender/blenlib/intern/BLI_linklist.c
@@ -155,6 +155,18 @@ void BLI_linklist_free(LinkNode *list, LinkNodeFreeFP freefunc)
}
}
+void BLI_linklist_freeN(LinkNode *list)
+{
+ while (list) {
+ LinkNode *next = list->next;
+
+ MEM_freeN(list->link);
+ MEM_freeN(list);
+
+ list = next;
+ }
+}
+
void BLI_linklist_apply(LinkNode *list, LinkNodeApplyFP applyfunc, void *userdata)
{
for (; list; list = list->next)
diff --git a/source/blender/blenlib/intern/BLI_memarena.c b/source/blender/blenlib/intern/BLI_memarena.c
index 0ac6209fc95..b6b5b600ab1 100644
--- a/source/blender/blenlib/intern/BLI_memarena.c
+++ b/source/blender/blenlib/intern/BLI_memarena.c
@@ -74,7 +74,7 @@ void BLI_memarena_use_align(struct MemArena *ma, const int align)
void BLI_memarena_free(MemArena *ma)
{
- BLI_linklist_free(ma->bufs, (void (*)(void *))MEM_freeN);
+ BLI_linklist_freeN(ma->bufs);
MEM_freeN(ma);
}
diff --git a/source/blender/blenlib/intern/buffer.c b/source/blender/blenlib/intern/buffer.c
index b2280b9a0d1..aac3a3bc3f3 100644
--- a/source/blender/blenlib/intern/buffer.c
+++ b/source/blender/blenlib/intern/buffer.c
@@ -70,7 +70,8 @@ void BLI_buffer_resize(BLI_Buffer *buffer, int new_count)
buffer->count = new_count;
}
-void BLI_buffer_free(BLI_Buffer *buffer)
+/* callers use BLI_buffer_free */
+void _bli_buffer_free(BLI_Buffer *buffer)
{
if ((buffer->flag & BLI_BUFFER_USE_STATIC) == 0) {
if (buffer->data) {
diff --git a/source/blender/blenlib/intern/fileops.c b/source/blender/blenlib/intern/fileops.c
index 24b3c36a329..29280c36222 100644
--- a/source/blender/blenlib/intern/fileops.c
+++ b/source/blender/blenlib/intern/fileops.c
@@ -138,7 +138,9 @@ char *BLI_file_ungzip_to_mem(const char *from_file, int *size_r)
if (readsize > 0) {
size += readsize;
}
- else break;
+ else {
+ break;
+ }
}
gzclose(gzfile);
@@ -155,37 +157,43 @@ char *BLI_file_ungzip_to_mem(const char *from_file, int *size_r)
return mem;
}
-
-/* return 1 when file can be written */
-int BLI_file_is_writable(const char *filename)
+/**
+ * Returns true if the file with the specified name can be written.
+ * This implementation uses access(2), which makes the check according
+ * to the real UID and GID of the process, not its effective UID and GID.
+ * This shouldn't matter for Blender, which is not going to run privileged
+ * anyway.
+ */
+bool BLI_file_is_writable(const char *filename)
{
- int file;
-
- /* first try to open without creating */
- file = BLI_open(filename, O_BINARY | O_RDWR, 0666);
-
- if (file < 0) {
- /* now try to open and create. a test without actually
- * creating a file would be nice, but how? */
- file = BLI_open(filename, O_BINARY | O_RDWR | O_CREAT, 0666);
-
- if (file < 0) {
- return 0;
- }
- else {
- /* success, delete the file we create */
- close(file);
- BLI_delete(filename, 0, 0);
- return 1;
- }
+ bool writable;
+ if (BLI_access(filename, W_OK) == 0) {
+ /* file exists and I can write to it */
+ writable = true;
+ }
+ else if (errno != ENOENT) {
+ /* most likely file or containing directory cannot be accessed */
+ writable = false;
}
else {
- close(file);
- return 1;
+ /* file doesn't exist -- check I can create it in parent directory */
+ char parent[FILE_MAX];
+ BLI_split_dirfile(filename, parent, NULL, sizeof(parent), 0);
+#ifdef WIN32
+ /* windows does not have X_OK */
+ writable = BLI_access(parent, W_OK) == 0;
+#else
+ writable = BLI_access(parent, X_OK | W_OK) == 0;
+#endif
}
+ return writable;
}
-int BLI_file_touch(const char *file)
+/**
+ * Creates the file with nothing in it, or updates its last-modified date if it already exists.
+ * Returns true if successful. (like the unix touch command)
+ */
+bool BLI_file_touch(const char *file)
{
FILE *f = BLI_fopen(file, "r+b");
if (f != NULL) {
@@ -198,9 +206,9 @@ int BLI_file_touch(const char *file)
}
if (f) {
fclose(f);
- return 1;
+ return true;
}
- return 0;
+ return false;
}
#ifdef WIN32
@@ -255,7 +263,12 @@ int BLI_open(const char *filename, int oflag, int pmode)
return uopen(filename, oflag, pmode);
}
-int BLI_delete(const char *file, int dir, int recursive)
+int BLI_access(const char *filename, int mode)
+{
+ return uaccess(filename, mode);
+}
+
+int BLI_delete(const char *file, bool dir, bool recursive)
{
int err;
@@ -279,6 +292,8 @@ int BLI_delete(const char *file, int dir, int recursive)
return err;
}
+/* Not used anywhere! */
+#if 0
int BLI_move(const char *file, const char *to)
{
int err;
@@ -308,7 +323,7 @@ int BLI_move(const char *file, const char *to)
return err;
}
-
+#endif
int BLI_copy(const char *file, const char *to)
{
@@ -391,15 +406,16 @@ int BLI_rename(const char *from, const char *to)
/* make sure the filenames are different (case insensitive) before removing */
if (BLI_exists(to) && BLI_strcasecmp(from, to))
- if (BLI_delete(to, 0, 0)) return 1;
+ if (BLI_delete(to, false, false)) return 1;
return urename(from, to);
}
#else /* The UNIX world */
+/* results from recursive_operation and its callbacks */
enum {
- /* operation succeeded succeeded */
+ /* operation succeeded */
RecursiveOp_Callback_OK = 0,
/* operation requested not to perform recursive digging for current path */
@@ -434,120 +450,122 @@ static char *strip_last_slash(const char *dir)
return result;
}
-static int recursive_operation(const char *startfrom, const char *startto, RecursiveOp_Callback callback_dir_pre,
+
+
+/**
+ * Scans \a startfrom, generating a corresponding destination name for each item found by
+ * prefixing it with startto, recursively scanning subdirectories, and invoking the specified
+ * callbacks for files and subdirectories found as appropriate.
+ *
+ * \param startfrom Top-level source path.
+ * \param startto Top-level destination path.
+ * \param callback_dir_pre Optional, to be invoked before entering a subdirectory, can return
+ * RecursiveOp_Callback_StopRecurs to skip the subdirectory.
+ * \param callback_file Optional, to be invoked on each file found.
+ * \param callback_dir_post optional, to be invoked after leaving a subdirectory.
+ * \return
+ */
+static int recursive_operation(const char *startfrom, const char *startto,
+ RecursiveOp_Callback callback_dir_pre,
RecursiveOp_Callback callback_file, RecursiveOp_Callback callback_dir_post)
{
- struct dirent **dirlist;
struct stat st;
char *from = NULL, *to = NULL;
char *from_path = NULL, *to_path = NULL;
+ struct dirent **dirlist = NULL;
size_t from_alloc_len = -1, to_alloc_len = -1;
int i, n, ret = 0;
- /* ensure there's no trailing slash in file path */
- from = strip_last_slash(startfrom);
- if (startto)
- to = strip_last_slash(startto);
+ do { /* once */
+ /* ensure there's no trailing slash in file path */
+ from = strip_last_slash(startfrom);
+ if (startto)
+ to = strip_last_slash(startto);
- ret = lstat(from, &st);
- if (ret < 0) {
- /* source wasn't found, nothing to operate with */
- return ret;
- }
-
- if (!S_ISDIR(st.st_mode)) {
- /* source isn't a directory, can't do recursive walking for it,
- * so just call file callback and leave */
- if (callback_file) {
- ret = callback_file(from, to);
+ ret = lstat(from, &st);
+ if (ret < 0)
+ /* source wasn't found, nothing to operate with */
+ break;
- if (ret != RecursiveOp_Callback_OK)
- ret = -1;
+ if (!S_ISDIR(st.st_mode)) {
+ /* source isn't a directory, can't do recursive walking for it,
+ * so just call file callback and leave */
+ if (callback_file != NULL) {
+ ret = callback_file(from, to);
+ if (ret != RecursiveOp_Callback_OK)
+ ret = -1;
+ }
+ break;
}
- MEM_freeN(from);
- if (to) MEM_freeN(to);
-
- return ret;
- }
-
-
- n = scandir(startfrom, &dirlist, 0, alphasort);
- if (n < 0) {
- /* error opening directory for listing */
- perror("scandir");
-
- MEM_freeN(from);
- if (to) MEM_freeN(to);
-
- return -1;
- }
-
- if (callback_dir_pre) {
- /* call pre-recursive walking directory callback */
- ret = callback_dir_pre(from, to);
-
- if (ret != RecursiveOp_Callback_OK) {
- MEM_freeN(from);
- if (to) free(to);
+ n = scandir(startfrom, &dirlist, 0, alphasort);
+ if (n < 0) {
+ /* error opening directory for listing */
+ perror("scandir");
+ ret = -1;
+ break;
+ }
- if (ret == RecursiveOp_Callback_StopRecurs) {
- /* callback requested not to perform recursive walking, not an error */
- return 0;
+ if (callback_dir_pre != NULL) {
+ ret = callback_dir_pre(from, to);
+ if (ret != RecursiveOp_Callback_OK) {
+ if (ret == RecursiveOp_Callback_StopRecurs)
+ /* callback requested not to perform recursive walking, not an error */
+ ret = 0;
+ else
+ ret = -1;
+ break;
}
-
- return -1;
}
- }
- for (i = 0; i < n; i++) {
- struct dirent *dirent = dirlist[i];
+ for (i = 0; i < n; i++) {
+ const struct dirent * const dirent = dirlist[i];
- if (!strcmp(dirent->d_name, ".") || !strcmp(dirent->d_name, "..")) {
- free(dirent);
- continue;
- }
+ if (!strcmp(dirent->d_name, ".") || !strcmp(dirent->d_name, ".."))
+ continue;
- join_dirfile_alloc(&from_path, &from_alloc_len, from, dirent->d_name);
+ join_dirfile_alloc(&from_path, &from_alloc_len, from, dirent->d_name);
+ if (to)
+ join_dirfile_alloc(&to_path, &to_alloc_len, to, dirent->d_name);
- if (to)
- join_dirfile_alloc(&to_path, &to_alloc_len, to, dirent->d_name);
+ if (dirent->d_type == DT_DIR) {
+ /* recursively dig into a subfolder */
+ ret = recursive_operation(from_path, to_path, callback_dir_pre, callback_file, callback_dir_post);
+ }
+ else if (callback_file != NULL) {
+ ret = callback_file(from_path, to_path);
+ if (ret != RecursiveOp_Callback_OK)
+ ret = -1;
+ }
- if (dirent->d_type == DT_DIR) {
- /* recursively dig into a folder */
- ret = recursive_operation(from_path, to_path, callback_dir_pre, callback_file, callback_dir_post);
+ if (ret != 0)
+ break;
}
- else if (callback_file) {
- /* call file callback for current path */
- ret = callback_file(from_path, to_path);
- if (ret != RecursiveOp_Callback_OK)
- ret = -1;
- }
-
- if (ret != 0) {
- while (i < n) {
- free(dirlist[i++]);
- }
+ if (ret != 0)
break;
- }
- }
-
- free(dirlist);
- if (ret == 0) {
- if (callback_dir_post) {
- /* call post-recursive directory callback */
+ if (callback_dir_post != NULL) {
ret = callback_dir_post(from, to);
if (ret != RecursiveOp_Callback_OK)
ret = -1;
}
}
+ while (false);
- if (from_path) MEM_freeN(from_path);
- if (to_path) MEM_freeN(to_path);
-
- MEM_freeN(from);
- if (to) MEM_freeN(to);
+ if (dirlist != NULL) {
+ for (i = 0; i < n; i++) {
+ free(dirlist[i]);
+ }
+ free(dirlist);
+ }
+ if (from_path != NULL)
+ MEM_freeN(from_path);
+ if (to_path != NULL)
+ MEM_freeN(to_path);
+ if (from != NULL)
+ MEM_freeN(from);
+ if (to != NULL)
+ MEM_freeN(to);
return ret;
}
@@ -589,7 +607,17 @@ int BLI_open(const char *filename, int oflag, int pmode)
return open(filename, oflag, pmode);
}
-int BLI_delete(const char *file, int dir, int recursive)
+int BLI_access(const char *filename, int mode)
+{
+ return access(filename, mode);
+}
+
+
+/**
+ * Deletes the specified file or directory (depending on dir), optionally
+ * doing recursive delete of directory contents.
+ */
+int BLI_delete(const char *file, bool dir, bool recursive)
{
if (strchr(file, '"')) {
printf("Error: not deleted file %s because of quote!\n", file);
@@ -608,20 +636,26 @@ int BLI_delete(const char *file, int dir, int recursive)
return -1;
}
-static int check_the_same(const char *path_a, const char *path_b)
+/**
+ * Do the two paths denote the same filesystem object?
+ */
+static bool check_the_same(const char *path_a, const char *path_b)
{
struct stat st_a, st_b;
if (lstat(path_a, &st_a))
- return 0;
+ return false;
if (lstat(path_b, &st_b))
- return 0;
+ return false;
return st_a.st_dev == st_b.st_dev && st_a.st_ino == st_b.st_ino;
}
-static int set_permissions(const char *file, struct stat *st)
+/**
+ * Sets the mode and ownership of file to the values from st.
+ */
+static int set_permissions(const char *file, const struct stat *st)
{
if (chown(file, st->st_uid, st->st_gid)) {
perror("chown");
@@ -769,6 +803,8 @@ static int copy_single_file(const char *from, const char *to)
return RecursiveOp_Callback_OK;
}
+/* Not used anywhere! */
+#if 0
static int move_callback_pre(const char *from, const char *to)
{
int ret = rename(from, to);
@@ -789,16 +825,19 @@ static int move_single_file(const char *from, const char *to)
return RecursiveOp_Callback_OK;
}
+/* if *file represents a directory, moves all its contents into *to, else renames
+ * file itself to *to. */
int BLI_move(const char *file, const char *to)
{
int ret = recursive_operation(file, to, move_callback_pre, move_single_file, NULL);
- if (ret) {
+ if (ret && ret != -1) {
return recursive_operation(file, NULL, NULL, delete_single_file, delete_callback_post);
}
return ret;
}
+#endif
static char *check_destination(const char *file, const char *to)
{
@@ -806,7 +845,8 @@ static char *check_destination(const char *file, const char *to)
if (!stat(to, &st)) {
if (S_ISDIR(st.st_mode)) {
- char *str, *filename, *path;
+ char *str, *path;
+ const char *filename;
size_t len = 0;
str = strip_last_slash(file);
@@ -875,7 +915,7 @@ void BLI_dir_create_recursive(const char *dirname)
BLI_strncpy(tmp, dirname, size);
- lslash = BLI_last_slash(tmp);
+ lslash = (char *)BLI_last_slash(tmp);
if (lslash) {
/* Split about the last slash and recurse */
*lslash = 0;
@@ -893,10 +933,9 @@ int BLI_rename(const char *from, const char *to)
if (!BLI_exists(from)) return 0;
if (BLI_exists(to))
- if (BLI_delete(to, 0, 0)) return 1;
+ if (BLI_delete(to, false, false)) return 1;
return rename(from, to);
}
#endif
-
diff --git a/source/blender/blenlib/intern/freetypefont.c b/source/blender/blenlib/intern/freetypefont.c
index 353b73a6403..2b3e2d233d9 100644
--- a/source/blender/blenlib/intern/freetypefont.c
+++ b/source/blender/blenlib/intern/freetypefont.c
@@ -449,7 +449,9 @@ static int check_freetypefont(PackedFile *pf)
glyph_index = FT_Get_Char_Index(face, 'A');
err = FT_Load_Glyph(face, glyph_index, FT_LOAD_NO_SCALE | FT_LOAD_NO_BITMAP);
- if (err) success = 0;
+ if (err) {
+ success = 0;
+ }
else {
glyph = face->glyph;
if (glyph->format == ft_glyph_format_outline) {
diff --git a/source/blender/blenlib/intern/gsqueue.c b/source/blender/blenlib/intern/gsqueue.c
index d569534f2f3..272f840296e 100644
--- a/source/blender/blenlib/intern/gsqueue.c
+++ b/source/blender/blenlib/intern/gsqueue.c
@@ -32,6 +32,8 @@
#include <string.h>
#include "MEM_guardedalloc.h"
+
+#include "BLI_utildefines.h"
#include "BLI_gsqueue.h"
typedef struct _GSQueueElem GSQueueElem;
@@ -54,7 +56,7 @@ GSQueue *BLI_gsqueue_new(int elem_size)
return gq;
}
-int BLI_gsqueue_is_empty(GSQueue *gq)
+bool BLI_gsqueue_is_empty(GSQueue *gq)
{
return (gq->head == NULL);
}
diff --git a/source/blender/blenlib/intern/lasso.c b/source/blender/blenlib/intern/lasso.c
index 5cd8bb813a1..aa08a780394 100644
--- a/source/blender/blenlib/intern/lasso.c
+++ b/source/blender/blenlib/intern/lasso.c
@@ -53,77 +53,44 @@ void BLI_lasso_boundbox(rcti *rect, const int mcords[][2], const short moves)
}
-int BLI_lasso_is_point_inside(const int mcords[][2], const short moves,
- const int sx, const int sy,
- const int error_value)
+bool BLI_lasso_is_point_inside(const int mcords[][2], const short moves,
+ const int sx, const int sy,
+ const int error_value)
{
- /* we do the angle rule, define that all added angles should be about zero or (2 * PI) */
- float angletot = 0.0, dot, ang, cross, fp1[2], fp2[2];
- int a;
- const int *p1, *p2;
-
if (sx == error_value) {
- return 0;
+ return false;
}
-
- p1 = mcords[moves - 1];
- p2 = mcords[0];
-
- /* first vector */
- fp1[0] = (float)(p1[0] - sx);
- fp1[1] = (float)(p1[1] - sy);
- normalize_v2(fp1);
-
- for (a = 0; a < moves; a++) {
- /* second vector */
- fp2[0] = (float)(p2[0] - sx);
- fp2[1] = (float)(p2[1] - sy);
- normalize_v2(fp2);
-
- /* dot and angle and cross */
- dot = fp1[0] * fp2[0] + fp1[1] * fp2[1];
- ang = fabs(saacos(dot));
-
- cross = (float)((p1[1] - p2[1]) * (p1[0] - sx) + (p2[0] - p1[0]) * (p1[1] - sy));
-
- if (cross < 0.0f) angletot -= ang;
- else angletot += ang;
-
- /* circulate */
- fp1[0] = fp2[0]; fp1[1] = fp2[1];
- p1 = p2;
- p2 = mcords[a + 1];
+ else {
+ int pt[2] = {sx, sy};
+ return isect_point_poly_v2_int(pt, mcords, moves);
}
-
- if (fabsf(angletot) > 4.0f) return 1;
- return 0;
}
/* edge version for lasso select. we assume boundbox check was done */
-int BLI_lasso_is_edge_inside(const int mcords[][2], const short moves,
- int x0, int y0, int x1, int y1,
- const int error_value)
+bool BLI_lasso_is_edge_inside(const int mcords[][2], const short moves,
+ int x0, int y0, int x1, int y1,
+ const int error_value)
{
int v1[2], v2[2];
int a;
if (x0 == error_value || x1 == error_value) {
- return 0;
+ return false;
}
v1[0] = x0, v1[1] = y0;
v2[0] = x1, v2[1] = y1;
/* check points in lasso */
- if (BLI_lasso_is_point_inside(mcords, moves, v1[0], v1[1], error_value)) return 1;
- if (BLI_lasso_is_point_inside(mcords, moves, v2[0], v2[1], error_value)) return 1;
+ if (BLI_lasso_is_point_inside(mcords, moves, v1[0], v1[1], error_value)) return true;
+ if (BLI_lasso_is_point_inside(mcords, moves, v2[0], v2[1], error_value)) return true;
/* no points in lasso, so we have to intersect with lasso edge */
- if (isect_line_line_v2_int(mcords[0], mcords[moves - 1], v1, v2) > 0) return 1;
+ if (isect_line_line_v2_int(mcords[0], mcords[moves - 1], v1, v2) > 0) return true;
for (a = 0; a < moves - 1; a++) {
- if (isect_line_line_v2_int(mcords[a], mcords[a + 1], v1, v2) > 0) return 1;
+ if (isect_line_line_v2_int(mcords[a], mcords[a + 1], v1, v2) > 0) return true;
}
- return 0;
+ return false;
}
diff --git a/source/blender/blenlib/intern/math_base.c b/source/blender/blenlib/intern/math_base.c
index 6bb238ac612..38d303e667a 100644
--- a/source/blender/blenlib/intern/math_base.c
+++ b/source/blender/blenlib/intern/math_base.c
@@ -57,7 +57,14 @@ double round(double x)
return copysign(y, x);
}
#else /* OpenSuse 11.1 seems to need this. */
+# ifdef __GNUC__
+# pragma GCC diagnostic push
+# pragma GCC diagnostic ignored "-Wredundant-decls"
+# endif
double round(double x);
+# ifdef __GNUC__
+# pragma GCC diagnostic pop
+# endif
#endif
/* from python 3.1 floatobject.c
diff --git a/source/blender/blenlib/intern/math_geom.c b/source/blender/blenlib/intern/math_geom.c
index 8f7ecdcfde8..173c6d06861 100644
--- a/source/blender/blenlib/intern/math_geom.c
+++ b/source/blender/blenlib/intern/math_geom.c
@@ -106,12 +106,12 @@ float area_quad_v3(const float v1[3], const float v2[3], const float v3[3], cons
sub_v3_v3v3(vec1, v2, v1);
sub_v3_v3v3(vec2, v4, v1);
cross_v3_v3v3(n, vec1, vec2);
- len = normalize_v3(n);
+ len = len_v3(n);
sub_v3_v3v3(vec1, v4, v3);
sub_v3_v3v3(vec2, v2, v3);
cross_v3_v3v3(n, vec1, vec2);
- len += normalize_v3(n);
+ len += len_v3(n);
return (len / 2.0f);
}
@@ -119,14 +119,13 @@ float area_quad_v3(const float v1[3], const float v2[3], const float v3[3], cons
/* Triangles */
float area_tri_v3(const float v1[3], const float v2[3], const float v3[3])
{
- float len, vec1[3], vec2[3], n[3];
+ float vec1[3], vec2[3], n[3];
sub_v3_v3v3(vec1, v3, v2);
sub_v3_v3v3(vec2, v1, v2);
cross_v3_v3v3(n, vec1, vec2);
- len = normalize_v3(n);
- return (len / 2.0f);
+ return len_v3(n) / 2.0f;
}
float area_tri_signed_v3(const float v1[3], const float v2[3], const float v3[3], const float normal[3])
@@ -729,6 +728,86 @@ static short IsectLLPt2Df(const float x0, const float y0, const float x1, const
return 1;
}
+/* point in polygon (keep float and int versions in sync) */
+bool isect_point_poly_v2(const float pt[2], const float verts[][2], const int nr)
+{
+ /* we do the angle rule, define that all added angles should be about zero or (2 * PI) */
+ float angletot = 0.0;
+ float fp1[2], fp2[2];
+ int i;
+ const float *p1, *p2;
+
+ p1 = verts[nr - 1];
+ p2 = verts[0];
+
+ /* first vector */
+ fp1[0] = (float)(p1[0] - pt[0]);
+ fp1[1] = (float)(p1[1] - pt[1]);
+ normalize_v2(fp1);
+
+ for (i = 0; i < nr; i++) {
+ float dot, ang, cross;
+ /* second vector */
+ fp2[0] = (float)(p2[0] - pt[0]);
+ fp2[1] = (float)(p2[1] - pt[1]);
+ normalize_v2(fp2);
+
+ /* dot and angle and cross */
+ dot = dot_v2v2(fp1, fp2);
+ ang = fabsf(saacos(dot));
+ cross = (float)((p1[1] - p2[1]) * (p1[0] - pt[0]) + (p2[0] - p1[0]) * (p1[1] - pt[1]));
+
+ if (cross < 0.0f) angletot -= ang;
+ else angletot += ang;
+
+ /* circulate */
+ copy_v2_v2(fp1, fp2);
+ p1 = p2;
+ p2 = verts[i + 1];
+ }
+
+ return (fabsf(angletot) > 4.0f);
+}
+bool isect_point_poly_v2_int(const int pt[2], const int verts[][2], const int nr)
+{
+ /* we do the angle rule, define that all added angles should be about zero or (2 * PI) */
+ float angletot = 0.0;
+ float fp1[2], fp2[2];
+ int i;
+ const int *p1, *p2;
+
+ p1 = verts[nr - 1];
+ p2 = verts[0];
+
+ /* first vector */
+ fp1[0] = (float)(p1[0] - pt[0]);
+ fp1[1] = (float)(p1[1] - pt[1]);
+ normalize_v2(fp1);
+
+ for (i = 0; i < nr; i++) {
+ float dot, ang, cross;
+ /* second vector */
+ fp2[0] = (float)(p2[0] - pt[0]);
+ fp2[1] = (float)(p2[1] - pt[1]);
+ normalize_v2(fp2);
+
+ /* dot and angle and cross */
+ dot = dot_v2v2(fp1, fp2);
+ ang = fabsf(saacos(dot));
+ cross = (float)((p1[1] - p2[1]) * (p1[0] - pt[0]) + (p2[0] - p1[0]) * (p1[1] - pt[1]));
+
+ if (cross < 0.0f) angletot -= ang;
+ else angletot += ang;
+
+ /* circulate */
+ copy_v2_v2(fp1, fp2);
+ p1 = p2;
+ p2 = verts[i + 1];
+ }
+
+ return (fabsf(angletot) > 4.0f);
+}
+
/* point in tri */
/* only single direction */
@@ -2219,6 +2298,13 @@ void barycentric_weights_v2_quad(const float v1[2], const float v2[2], const flo
len_v2(dirs[3]),
};
+ /* variable 'area' is just for storage,
+ * the order its initialized doesn't matter */
+#ifdef __clang__
+# pragma clang diagnostic push
+# pragma clang diagnostic ignored "-Wunsequenced"
+#endif
+
/* inline mean_value_half_tan four times here */
float t[4] = {
MEAN_VALUE_HALF_TAN_V2(area, 0, 1),
@@ -2227,6 +2313,10 @@ void barycentric_weights_v2_quad(const float v1[2], const float v2[2], const flo
MEAN_VALUE_HALF_TAN_V2(area, 3, 0),
};
+#ifdef __clang__
+# pragma clang diagnostic pop
+#endif
+
#undef MEAN_VALUE_HALF_TAN_V2
w[0] = (t[3] + t[0]) / lens[0];
@@ -2564,7 +2654,9 @@ void resolve_tri_uv(float r_uv[2], const float st[2], const float st0[2], const
r_uv[0] = (float)((d * x[0] - b * x[1]) / det);
r_uv[1] = (float)(((-c) * x[0] + a * x[1]) / det);
}
- else zero_v2(r_uv);
+ else {
+ zero_v2(r_uv);
+ }
}
/* bilinear reverse */
@@ -3063,7 +3155,9 @@ void vcloud_estimate_transform(int list_size, float (*pos)[3], float *weight, fl
add_v3_v3(accu_com, v);
accu_weight += weight[a];
}
- else add_v3_v3(accu_com, pos[a]);
+ else {
+ add_v3_v3(accu_com, pos[a]);
+ }
if (rweight) {
float v[3];
@@ -3072,8 +3166,9 @@ void vcloud_estimate_transform(int list_size, float (*pos)[3], float *weight, fl
add_v3_v3(accu_rcom, v);
accu_rweight += rweight[a];
}
- else add_v3_v3(accu_rcom, rpos[a]);
-
+ else {
+ add_v3_v3(accu_rcom, rpos[a]);
+ }
}
if (!weight || !rweight) {
accu_weight = accu_rweight = list_size;
diff --git a/source/blender/blenlib/intern/math_matrix.c b/source/blender/blenlib/intern/math_matrix.c
index 9d9e3e611e1..f116c9b8443 100644
--- a/source/blender/blenlib/intern/math_matrix.c
+++ b/source/blender/blenlib/intern/math_matrix.c
@@ -333,15 +333,15 @@ void mul_m4_v3(float mat[4][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][4], const float vec[3])
+void mul_v3_m4v3(float r[3], float mat[4][4], const float vec[3])
{
float x, y;
x = vec[0];
y = vec[1];
- in[0] = x * mat[0][0] + y * mat[1][0] + mat[2][0] * vec[2] + mat[3][0];
- in[1] = x * mat[0][1] + y * mat[1][1] + mat[2][1] * vec[2] + mat[3][1];
- in[2] = x * mat[0][2] + y * mat[1][2] + mat[2][2] * vec[2] + mat[3][2];
+ r[0] = x * mat[0][0] + y * mat[1][0] + mat[2][0] * vec[2] + mat[3][0];
+ r[1] = x * mat[0][1] + y * mat[1][1] + mat[2][1] * vec[2] + mat[3][1];
+ r[2] = x * mat[0][2] + y * mat[1][2] + mat[2][2] * vec[2] + mat[3][2];
}
void mul_v2_m2v2(float r[2], float mat[2][2], const float vec[2])
@@ -367,7 +367,7 @@ void mul_mat3_m4_v3(float mat[4][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];
+ const float w = mul_project_m4_v3_zfac(mat, vec);
mul_m4_v3(mat, vec);
vec[0] /= w;
diff --git a/source/blender/blenlib/intern/math_vector_inline.c b/source/blender/blenlib/intern/math_vector_inline.c
index 48e7de43a86..c8e8ff9602b 100644
--- a/source/blender/blenlib/intern/math_vector_inline.c
+++ b/source/blender/blenlib/intern/math_vector_inline.c
@@ -398,6 +398,15 @@ MINLINE void mul_v4_v4fl(float r[4], const float a[4], float f)
r[3] = a[3] * f;
}
+/* note: could add a matrix inline */
+MINLINE float mul_project_m4_v3_zfac(float mat[4][4], const float co[3])
+{
+ return (mat[0][3] * co[0]) +
+ (mat[1][3] * co[1]) +
+ (mat[2][3] * co[2]) + mat[3][3];
+}
+
+
MINLINE void madd_v2_v2fl(float r[2], const float a[2], float f)
{
r[0] += a[0] * f;
diff --git a/source/blender/blenlib/intern/noise.c b/source/blender/blenlib/intern/noise.c
index c159f707b98..6e52145c653 100644
--- a/source/blender/blenlib/intern/noise.c
+++ b/source/blender/blenlib/intern/noise.c
@@ -281,9 +281,9 @@ static float npfade(float t)
return (t * t * t * (t * (t * 6.0f - 15.0f) + 10.0f));
}
-static float grad(int hash, float x, float y, float z)
+static float grad(int hash_val, float x, float y, float z)
{
- int h = hash & 15; /* CONVERT LO 4 BITS OF HASH CODE */
+ int h = hash_val & 15; /* CONVERT LO 4 BITS OF HASH CODE */
float u = h < 8 ? x : y, /* INTO 12 GRADIENT DIRECTIONS. */
v = h < 4 ? y : h == 12 || h == 14 ? x : z;
return ((h & 1) == 0 ? u : -u) + ((h & 2) == 0 ? v : -v);
diff --git a/source/blender/blenlib/intern/path_util.c b/source/blender/blenlib/intern/path_util.c
index 5265d862ab8..c3bc35a906b 100644
--- a/source/blender/blenlib/intern/path_util.c
+++ b/source/blender/blenlib/intern/path_util.c
@@ -41,11 +41,11 @@
#include "DNA_listBase.h"
+#include "BLI_utildefines.h"
#include "BLI_fileops.h"
#include "BLI_path_util.h"
#include "BLI_string.h"
#include "BLI_string_utf8.h"
-#include "BLI_utildefines.h"
#include "../blenkernel/BKE_blender.h" /* BLENDER_VERSION, bad level include (no function call) */
@@ -79,43 +79,50 @@
/* local */
#define UNIQUE_NAME_MAX 128
-static char bprogname[FILE_MAX]; /* path to program executable */
-static char bprogdir[FILE_MAX]; /* path in which executable is located */
+static char bprogname[FILE_MAX]; /* full path to program executable */
+static char bprogdir[FILE_MAX]; /* full path to directory in which executable is located */
static char btempdir[FILE_MAX]; /* temporary directory */
-static int add_win32_extension(char *name);
-static char *blender_version_decimal(const int ver);
-
/* implementation */
+/**
+ * Looks for a sequence of decimal digits in string, preceding any filename extension,
+ * returning the integer value if found, or 0 if not.
+ *
+ * \param string String to scan.
+ * \param head Optional area to return copy of part of string prior to digits, or before dot if no digits.
+ * \param tail Optional area to return copy of part of string following digits, or from dot if no digits.
+ * \param numlen Optional to return number of digits found.
+ */
int BLI_stringdec(const char *string, char *head, char *tail, unsigned short *numlen)
{
- unsigned short len, len2, lenlslash = 0, nums = 0, nume = 0;
- short i, found = 0;
- char *lslash = BLI_last_slash(string);
- len2 = len = strlen(string);
- if (lslash)
- lenlslash = (int)(lslash - string);
+ unsigned short nums = 0, nume = 0;
+ short i;
+ bool found_digit = false;
+ const char * const lslash = BLI_last_slash(string);
+ const unsigned short string_len = strlen(string);
+ const unsigned short lslash_len = lslash != NULL ? (int)(lslash - string) : 0;
+ unsigned short name_end = string_len;
- while (len > lenlslash && string[--len] != '.') {}
- if (len == lenlslash && string[len] != '.') len = len2;
+ while (name_end > lslash_len && string[--name_end] != '.') {} /* name ends at dot if present */
+ if (name_end == lslash_len && string[name_end] != '.') name_end = string_len;
- for (i = len - 1; i >= lenlslash; i--) {
+ for (i = name_end - 1; i >= lslash_len; i--) {
if (isdigit(string[i])) {
- if (found) {
+ if (found_digit) {
nums = i;
}
else {
nume = i;
nums = i;
- found = 1;
+ found_digit = true;
}
}
else {
- if (found) break;
+ if (found_digit) break;
}
}
- if (found) {
+ if (found_digit) {
if (tail) strcpy(tail, &string[nume + 1]);
if (head) {
strcpy(head, string);
@@ -124,56 +131,71 @@ int BLI_stringdec(const char *string, char *head, char *tail, unsigned short *nu
if (numlen) *numlen = nume - nums + 1;
return ((int)atoi(&(string[nums])));
}
- if (tail) strcpy(tail, string + len);
+ if (tail) strcpy(tail, string + name_end);
if (head) {
- strncpy(head, string, len);
- head[len] = '\0';
+ strncpy(head, string, name_end);
+ head[name_end] = '\0';
}
if (numlen) *numlen = 0;
return 0;
}
+/**
+ * Returns in area pointed to by string a string of the form "<head><pic><tail>", where pic
+ * is formatted as numlen digits with leading zeroes.
+ */
void BLI_stringenc(char *string, const char *head, const char *tail, unsigned short numlen, int pic)
{
- char fmtstr[16] = "";
- if (pic < 0) pic = 0;
- sprintf(fmtstr, "%%s%%.%dd%%s", numlen);
- sprintf(string, fmtstr, head, pic, tail);
+ sprintf(string, "%s%.*d%s", head, numlen, MAX2(0, pic), tail);
}
-/* Foo.001 -> "Foo", 1
- * Returns the length of "Foo" */
+/**
+ * Looks for a numeric suffix preceded by delim character on the end of
+ * name, puts preceding part into *left and value of suffix into *nr.
+ * Returns the length of *left.
+ *
+ * Foo.001 -> "Foo", 1
+ * Returning the length of "Foo"
+ *
+ * \param left Where to return copy of part preceding delim
+ * \param nr Where to return value of numeric suffix
+ * \param name String to split
+ * \param delim Delimiter character
+ * \return Length of \a left
+ */
int BLI_split_name_num(char *left, int *nr, const char *name, const char delim)
{
- int a;
+ const int name_len = strlen(name);
*nr = 0;
- a = strlen(name);
- memcpy(left, name, (a + 1) * sizeof(char));
-
- if (a > 1 && name[a - 1] == delim) return a;
-
- while (a--) {
- if (name[a] == delim) {
- left[a] = 0;
- *nr = atol(name + a + 1);
- /* casting down to an int, can overflow for large numbers */
- if (*nr < 0)
- *nr = 0;
- return a;
- }
- if (isdigit(name[a]) == 0) break;
-
- left[a] = 0;
+ memcpy(left, name, (name_len + 1) * sizeof(char));
+
+ /* name doesn't end with a delimiter "foo." */
+ if ((name_len > 1 && name[name_len - 1] == delim) == 0) {
+ int a = name_len;
+ while (a--) {
+ if (name[a] == delim) {
+ left[a] = '\0'; /* truncate left part here */
+ *nr = atol(name + a + 1);
+ /* casting down to an int, can overflow for large numbers */
+ if (*nr < 0)
+ *nr = 0;
+ return a;
+ }
+ else if (isdigit(name[a]) == 0) {
+ /* non-numeric suffix - give up */
+ break;
+ }
+ }
}
- for (a = 0; name[a]; a++)
- left[a] = name[a];
-
- return a;
+ return name_len;
}
+/**
+ * Looks for a string of digits within name (using BLI_stringdec) and adjusts it by add.
+ */
void BLI_newname(char *name, int add)
{
char head[UNIQUE_NAME_MAX], tail[UNIQUE_NAME_MAX];
@@ -196,9 +218,20 @@ void BLI_newname(char *name, int add)
BLI_stringenc(name, head, tail, digits, pic);
}
-
-
-int BLI_uniquename_cb(int (*unique_check)(void *, const char *), void *arg, const char defname[], char delim, char *name, short name_len)
+/**
+ * Ensures name is unique (according to criteria specified by caller in unique_check callback),
+ * incrementing its numeric suffix as necessary. Returns true if name had to be adjusted.
+ *
+ * \param unique_check Return true if name is not unique
+ * \param arg Additional arg to unique_check--meaning is up to caller
+ * \param defname To initialize name if latter is empty
+ * \param delim Delimits numeric suffix in name
+ * \param name Name to be ensured unique
+ * \param name_len Maximum length of name area
+ * \return true if there if the name was changed
+ */
+bool BLI_uniquename_cb(bool (*unique_check)(void * arg, const char *name),
+ void *arg, const char *defname, char delim, char *name, short name_len)
{
if (name[0] == '\0') {
BLI_strncpy(name, defname, name_len);
@@ -211,7 +244,7 @@ int BLI_uniquename_cb(int (*unique_check)(void *, const char *), void *arg, cons
int number;
int len = BLI_split_name_num(left, &number, name, delim);
do {
- int numlen = BLI_snprintf(numstr, sizeof(numstr), "%c%03d", delim, ++number);
+ const int numlen = BLI_snprintf(numstr, sizeof(numstr), "%c%03d", delim, ++number);
/* highly unlikely the string only has enough room for the number
* but support anyway */
@@ -229,10 +262,10 @@ int BLI_uniquename_cb(int (*unique_check)(void *, const char *), void *arg, cons
BLI_strncpy(name, tempname, name_len);
- return 1;
+ return true;
}
- return 0;
+ return false;
}
/* little helper macro for BLI_uniquename */
@@ -250,28 +283,39 @@ int BLI_uniquename_cb(int (*unique_check)(void *, const char *), void *arg, cons
* defname: the name that should be used by default if none is specified already
* delim: the character which acts as a delimiter between parts of the name
*/
-static int uniquename_find_dupe(ListBase *list, void *vlink, const char *name, short name_offs)
+static bool uniquename_find_dupe(ListBase *list, void *vlink, const char *name, short name_offs)
{
Link *link;
for (link = list->first; link; link = link->next) {
if (link != vlink) {
if (!strcmp(GIVE_STRADDR(link, name_offs), name)) {
- return 1;
+ return true;
}
}
}
- return 0;
+ return false;
}
-static int uniquename_unique_check(void *arg, const char *name)
+static bool uniquename_unique_check(void *arg, const char *name)
{
struct {ListBase *lb; void *vlink; short name_offs; } *data = arg;
return uniquename_find_dupe(data->lb, data->vlink, name, data->name_offs);
}
-void BLI_uniquename(ListBase *list, void *vlink, const char defname[], char delim, short name_offs, short name_len)
+/**
+ * Ensures that the specified block has a unique name within the containing list,
+ * incrementing its numeric suffix as necessary.
+ *
+ * \param list List containing the block
+ * \param vlink The block to check the name for
+ * \param defname To initialize block name if latter is empty
+ * \param delim Delimits numeric suffix in name
+ * \param name_offs Offset of name within block structure
+ * \param name_len Maximum length of name area
+ */
+void BLI_uniquename(ListBase *list, void *vlink, const char *defname, char delim, short name_offs, short name_len)
{
struct {ListBase *lb; void *vlink; short name_offs; } data;
data.lb = list;
@@ -299,19 +343,19 @@ void BLI_uniquename(ListBase *list, void *vlink, const char defname[], char deli
* If relbase is NULL then its ignored
*/
-void BLI_cleanup_path(const char *relabase, char *dir)
+void BLI_cleanup_path(const char *relabase, char *path)
{
ptrdiff_t a;
char *start, *eind;
if (relabase) {
- BLI_path_abs(dir, relabase);
+ BLI_path_abs(path, relabase);
}
else {
- if (dir[0] == '/' && dir[1] == '/') {
- if (dir[2] == '\0') {
+ if (path[0] == '/' && path[1] == '/') {
+ if (path[2] == '\0') {
return; /* path is "//" - cant clean it */
}
- dir = dir + 2; /* skip the first // */
+ path = path + 2; /* leave the initial "//" untouched */
}
}
@@ -327,70 +371,72 @@ void BLI_cleanup_path(const char *relabase, char *dir)
/* Note, this should really be moved to the file selector,
* since this function is used in many areas */
- if (strcmp(dir, ".") == 0) { /* happens for example in FILE_MAIN */
- get_default_root(dir);
+ if (strcmp(path, ".") == 0) { /* happens for example in FILE_MAIN */
+ get_default_root(path);
return;
}
- while ( (start = strstr(dir, "\\..\\")) ) {
+ while ( (start = strstr(path, "\\..\\")) ) {
eind = start + strlen("\\..\\") - 1;
- a = start - dir - 1;
+ a = start - path - 1;
while (a > 0) {
- if (dir[a] == '\\') break;
+ if (path[a] == '\\') break;
a--;
}
if (a < 0) {
break;
}
else {
- memmove(dir + a, eind, strlen(eind) + 1);
+ memmove(path + a, eind, strlen(eind) + 1);
}
}
- while ( (start = strstr(dir, "\\.\\")) ) {
+ while ( (start = strstr(path, "\\.\\")) ) {
eind = start + strlen("\\.\\") - 1;
memmove(start, eind, strlen(eind) + 1);
}
- while ( (start = strstr(dir, "\\\\")) ) {
+ while ( (start = strstr(path, "\\\\")) ) {
eind = start + strlen("\\\\") - 1;
memmove(start, eind, strlen(eind) + 1);
}
#else
- if (dir[0] == '.') { /* happens, for example in FILE_MAIN */
- dir[0] = '/';
- dir[1] = 0;
+ if (path[0] == '.') { /* happens, for example in FILE_MAIN */
+ path[0] = '/';
+ path[1] = 0;
return;
}
- /* support for odd paths: eg /../home/me --> /home/me
- * this is a valid path in blender but we cant handle this the usual way below
- * simply strip this prefix then evaluate the path as usual. pythons os.path.normpath() does this */
- while ((strncmp(dir, "/../", 4) == 0)) {
- memmove(dir, dir + 4, strlen(dir + 4) + 1);
- }
-
- while ( (start = strstr(dir, "/../")) ) {
- eind = start + (4 - 1) /* strlen("/../") - 1 */;
- a = start - dir - 1;
- while (a > 0) {
- if (dir[a] == '/') break;
- a--;
- }
- if (a < 0) {
- break;
+ while ( (start = strstr(path, "/../")) ) {
+ a = start - path - 1;
+ if (a > 0) {
+ /* <prefix>/<parent>/../<postfix> => <prefix>/<postfix> */
+ eind = start + (4 - 1) /* strlen("/../") - 1 */; /* strip "/.." and keep last "/" */
+ while (a > 0 && path[a] != '/') { /* find start of <parent> */
+ a--;
+ }
+ memmove(path + a, eind, strlen(eind) + 1);
}
else {
- memmove(dir + a, eind, strlen(eind) + 1);
+ /* support for odd paths: eg /../home/me --> /home/me
+ * this is a valid path in blender but we cant handle this the usual way below
+ * simply strip this prefix then evaluate the path as usual.
+ * pythons os.path.normpath() does this */
+
+ /* Note: previous version of following call used an offset of 3 instead of 4,
+ * which meant that the "/../home/me" example actually became "home/me".
+ * Using offset of 3 gives behaviour consistent with the abovementioned
+ * Python routine. */
+ memmove(path, path + 3, strlen(path + 3) + 1);
}
}
- while ( (start = strstr(dir, "/./")) ) {
+ while ( (start = strstr(path, "/./")) ) {
eind = start + (3 - 1) /* strlen("/./") - 1 */;
memmove(start, eind, strlen(eind) + 1);
}
- while ( (start = strstr(dir, "//")) ) {
+ while ( (start = strstr(path, "//")) ) {
eind = start + (2 - 1) /* strlen("//") - 1 */;
memmove(start, eind, strlen(eind) + 1);
}
@@ -404,20 +450,28 @@ void BLI_cleanup_dir(const char *relabase, char *dir)
}
-void BLI_cleanup_file(const char *relabase, char *dir)
+void BLI_cleanup_file(const char *relabase, char *path)
{
- BLI_cleanup_path(relabase, dir);
- BLI_del_slash(dir);
+ BLI_cleanup_path(relabase, path);
+ BLI_del_slash(path);
}
-int BLI_path_is_rel(const char *path)
+/**
+ * Does path begin with the special "//" prefix that Blender uses to indicate
+ * a path relative to the .blend file.
+ */
+bool BLI_path_is_rel(const char *path)
{
return path[0] == '/' && path[1] == '/';
}
+/**
+ * Replaces *file with a relative version (prefixed by "//") such that BLI_path_abs, given
+ * the same *relfile, will convert it back to its original value.
+ */
void BLI_path_rel(char *file, const char *relfile)
{
- char *lslash;
+ const char *lslash;
char temp[FILE_MAX];
char res[FILE_MAX];
@@ -519,7 +573,11 @@ void BLI_path_rel(char *file, const char *relfile)
}
}
-int BLI_has_parent(char *path)
+/**
+ * Cleans path and makes sure it ends with a slash.
+ * \return true if \a path has more than one other path separator in it.
+ */
+bool BLI_has_parent(char *path)
{
int len;
int slashes = 0;
@@ -534,25 +592,34 @@ int BLI_has_parent(char *path)
return slashes > 1;
}
-int BLI_parent_dir(char *path)
+/**
+ * Replaces path with the path of its parent directory, returning true if
+ * it was able to find a parent directory within the pathname.
+ */
+bool BLI_parent_dir(char *path)
{
static char parent_dir[] = {'.', '.', SEP, '\0'}; /* "../" or "..\\" */
char tmp[FILE_MAX + 4];
BLI_strncpy(tmp, path, sizeof(tmp) - 4);
BLI_add_slash(tmp);
strcat(tmp, parent_dir);
- BLI_cleanup_dir(NULL, tmp);
+ BLI_cleanup_dir(NULL, tmp); /* does all the work of normalizing the path for us */
if (!BLI_testextensie(tmp, parent_dir)) {
BLI_strncpy(path, tmp, sizeof(tmp));
- return 1;
+ return true;
}
else {
- return 0;
+ return false;
}
}
-static int stringframe_chars(char *path, int *char_start, int *char_end)
+/**
+ * Looks for a sequence of "#" characters in the last slash-separated component of *path,
+ * returning the indexes of the first and one past the last character in the sequence in
+ * *char_start and *char_end respectively. Returns true if such a sequence was found.
+ */
+static bool stringframe_chars(const char *path, int *char_start, int *char_end)
{
int ch_sta, ch_end, i;
/* Insert current frame: file### -> file001 */
@@ -576,18 +643,22 @@ static int stringframe_chars(char *path, int *char_start, int *char_end)
if (ch_end) {
*char_start = ch_sta;
*char_end = ch_end;
- return 1;
+ return true;
}
else {
*char_start = -1;
*char_end = -1;
- return 0;
+ return false;
}
}
+/**
+ * Ensure *path contains at least one "#" character in its last slash-separated
+ * component, appending one digits long if not.
+ */
static void ensure_digits(char *path, int digits)
{
- char *file = BLI_last_slash(path);
+ char *file = (char *)BLI_last_slash(path);
if (file == NULL)
file = path;
@@ -602,7 +673,11 @@ static void ensure_digits(char *path, int digits)
}
}
-int BLI_path_frame(char *path, int frame, int digits)
+/**
+ * Replaces "#" character sequence in last slash-separated component of *path
+ * with frame as decimal integer, with leading zeroes as necessary, to make digits digits.
+ */
+bool BLI_path_frame(char *path, int frame, int digits)
{
int ch_sta, ch_end;
@@ -613,12 +688,17 @@ int BLI_path_frame(char *path, int frame, int digits)
char tmp[FILE_MAX];
sprintf(tmp, "%.*s%.*d%s", ch_sta, path, ch_end - ch_sta, frame, path + ch_end);
strcpy(path, tmp);
- return 1;
+ return true;
}
- return 0;
+ return false;
}
-int BLI_path_frame_range(char *path, int sta, int end, int digits)
+/**
+ * Replaces "#" character sequence in last slash-separated component of *path
+ * with sta and end as decimal integers, with leading zeroes as necessary, to make digits
+ * digits each, with a hyphen in-between.
+ */
+bool BLI_path_frame_range(char *path, int sta, int end, int digits)
{
int ch_sta, ch_end;
@@ -631,14 +711,19 @@ int BLI_path_frame_range(char *path, int sta, int end, int digits)
"%.*s%.*d-%.*d%s",
ch_sta, path, ch_end - ch_sta, sta, ch_end - ch_sta, end, path + ch_end);
BLI_strncpy(path, tmp, FILE_MAX);
- return 1;
+ return true;
}
- return 0;
+ return false;
}
-int BLI_path_abs(char *path, const char *basepath)
+/**
+ * If path begins with "//", strips that and replaces it with basepath directory. Also converts
+ * a drive-letter prefix to something more sensible if this is a non-drive-letter-based system.
+ * Returns true if "//" prefix expansion was done.
+ */
+bool BLI_path_abs(char *path, const char *basepath)
{
- int wasrelative = BLI_path_is_rel(path);
+ const bool wasrelative = BLI_path_is_rel(path);
char tmp[FILE_MAX];
char base[FILE_MAX];
#ifdef WIN32
@@ -696,21 +781,23 @@ int BLI_path_abs(char *path, const char *basepath)
/* Paths starting with // will get the blend file as their base,
* this isn't standard in any os but is used in blender all over the place */
if (wasrelative) {
- char *lslash = BLI_last_slash(base);
+ const char * const lslash = BLI_last_slash(base);
if (lslash) {
- int baselen = (int) (lslash - base) + 1;
+ const int baselen = (int) (lslash - base) + 1; /* length up to and including last "/" */
/* use path for temp storage here, we copy back over it right away */
- BLI_strncpy(path, tmp + 2, FILE_MAX);
+ BLI_strncpy(path, tmp + 2, FILE_MAX); /* strip "//" */
- memcpy(tmp, base, baselen);
- BLI_strncpy(tmp + baselen, path, sizeof(tmp) - baselen);
- BLI_strncpy(path, tmp, FILE_MAX);
+ memcpy(tmp, base, baselen); /* prefix with base up to last "/" */
+ BLI_strncpy(tmp + baselen, path, sizeof(tmp) - baselen); /* append path after "//" */
+ BLI_strncpy(path, tmp, FILE_MAX); /* return as result */
}
else {
+ /* base doesn't seem to be a directory--ignore it and just strip "//" prefix on path */
BLI_strncpy(path, tmp + 2, FILE_MAX);
}
}
else {
+ /* base ignored */
BLI_strncpy(path, tmp, FILE_MAX);
}
@@ -730,24 +817,27 @@ int BLI_path_abs(char *path, const char *basepath)
}
-/*
- * Should only be done with command line paths.
- * this is NOT something blenders internal paths support like the // prefix
+/**
+ * Expands path relative to the current working directory, if it was relative.
+ * Returns true if such expansion was done.
+ *
+ * \note Should only be done with command line paths.
+ * this is _not_ something blenders internal paths support like the "//" prefix
*/
-int BLI_path_cwd(char *path)
+bool BLI_path_cwd(char *path)
{
- int wasrelative = 1;
- int filelen = strlen(path);
+ bool wasrelative = true;
+ const int filelen = strlen(path);
#ifdef WIN32
if (filelen >= 3 && path[1] == ':' && (path[2] == '\\' || path[2] == '/'))
- wasrelative = 0;
+ wasrelative = false;
#else
if (filelen >= 2 && path[0] == '/')
- wasrelative = 0;
+ wasrelative = false;
#endif
- if (wasrelative == 1) {
+ if (wasrelative) {
char cwd[FILE_MAX] = "";
BLI_current_working_dir(cwd, sizeof(cwd)); /* in case the full path to the blend isn't used */
@@ -772,22 +862,9 @@ int BLI_path_cwd(char *path)
return wasrelative;
}
-
-/* 'di's filename component is moved into 'fi', di is made a dir path */
-void BLI_splitdirstring(char *di, char *fi)
-{
- char *lslash = BLI_last_slash(di);
-
- if (lslash) {
- BLI_strncpy(fi, lslash + 1, FILE_MAXFILE);
- *(lslash + 1) = 0;
- }
- else {
- BLI_strncpy(fi, di, FILE_MAXFILE);
- di[0] = 0;
- }
-}
-
+/**
+ * Copies into *last the part of *dir following the second-last slash.
+ */
void BLI_getlastdir(const char *dir, char *last, const size_t maxlen)
{
const char *s = dir;
@@ -814,7 +891,7 @@ void BLI_getlastdir(const char *dir, char *last, const size_t maxlen)
const char *BLI_getDefaultDocumentFolder(void)
{
#ifndef WIN32
- const char *xdg_documents_dir = getenv("XDG_DOCUMENTS_DIR");
+ const char * const xdg_documents_dir = getenv("XDG_DOCUMENTS_DIR");
if (xdg_documents_dir)
return xdg_documents_dir;
@@ -850,6 +927,7 @@ const char *BLI_getDefaultDocumentFolder(void)
// #define PATH_DEBUG
+/* returns a formatted representation of the specified version number. Non-reentrant! */
static char *blender_version_decimal(const int ver)
{
static char version_str[5];
@@ -857,7 +935,11 @@ static char *blender_version_decimal(const int ver)
return version_str;
}
-static int test_path(char *targetpath, const char *path_base, const char *path_sep, const char *folder_name)
+/**
+ * Concatenates path_base, (optional) path_sep and (optional) folder_name into targetpath,
+ * returning true if result points to a directory.
+ */
+static bool test_path(char *targetpath, const char *path_base, const char *path_sep, const char *folder_name)
{
char tmppath[FILE_MAX];
@@ -869,44 +951,60 @@ static int test_path(char *targetpath, const char *path_base, const char *path_s
BLI_make_file_string("/", targetpath, tmppath, folder_name);
else
BLI_strncpy(targetpath, tmppath, sizeof(tmppath));
+ /* FIXME: why is "//" on front of tmppath expanded to "/" (by BLI_join_dirfile)
+ * if folder_name is specified but not otherwise? */
if (BLI_is_dir(targetpath)) {
#ifdef PATH_DEBUG
printf("\t%s found: %s\n", __func__, targetpath);
#endif
- return 1;
+ return true;
}
else {
#ifdef PATH_DEBUG
printf("\t%s missing: %s\n", __func__, targetpath);
#endif
//targetpath[0] = '\0';
- return 0;
+ return false;
}
}
-static int test_env_path(char *path, const char *envvar)
+/**
+ * Puts the value of the specified environment variable into *path if it exists
+ * and points at a directory. Returns true if this was done.
+ */
+static bool test_env_path(char *path, const char *envvar)
{
const char *env = envvar ? getenv(envvar) : NULL;
- if (!env) return 0;
+ if (!env) return false;
if (BLI_is_dir(env)) {
BLI_strncpy(path, env, FILE_MAX);
#ifdef PATH_DEBUG
printf("\t%s env %s found: %s\n", __func__, envvar, env);
#endif
- return 1;
+ return true;
}
else {
path[0] = '\0';
#ifdef PATH_DEBUG
printf("\t%s env %s missing: %s\n", __func__, envvar, env);
#endif
- return 0;
+ return false;
}
}
-static int get_path_local(char *targetpath, const char *folder_name, const char *subfolder_name, const int ver)
+/**
+ * Constructs in \a targetpath the name of a directory relative to a version-specific
+ * subdirectory in the parent directory of the Blender executable.
+ *
+ * \param targetpath String to return path
+ * \param folder_name Optional folder name within version-specific directory
+ * \param subfolder_name Optional subfolder name within folder_name
+ * \param ver To construct name of version-specific directory within bprogdir
+ * \return true if such a directory exists.
+ */
+static bool get_path_local(char *targetpath, const char *folder_name, const char *subfolder_name, const int ver)
{
char relfolder[FILE_MAX];
@@ -927,22 +1025,34 @@ static int get_path_local(char *targetpath, const char *folder_name, const char
}
/* try EXECUTABLE_DIR/2.5x/folder_name - new default directory for local blender installed files */
- if (test_path(targetpath, bprogdir, blender_version_decimal(ver), relfolder))
- return 1;
-
- return 0;
+ return test_path(targetpath, bprogdir, blender_version_decimal(ver), relfolder);
}
-static int is_portable_install(void)
+/**
+ * Is this an install with user files kept together with the Blender executable and its
+ * installation files.
+ */
+static bool is_portable_install(void)
{
- /* detect portable install by the existance of config folder */
+ /* detect portable install by the existence of config folder */
const int ver = BLENDER_VERSION;
char path[FILE_MAX];
return get_path_local(path, "config", NULL, ver);
}
-static int get_path_user(char *targetpath, const char *folder_name, const char *subfolder_name, const char *envvar, const int ver)
+/**
+ * Returns the path of a folder within the user-files area.
+ *
+ *
+ * \param targetpath String to return path
+ * \param folder_name default name of folder within user area
+ * \param subfolder_name optional name of subfolder within folder
+ * \param envvar name of environment variable which, if defined, overrides folder_name
+ * \param ver Blender version, used to construct a subdirectory name
+ * \return true if it was able to construct such a path.
+ */
+static bool get_path_user(char *targetpath, const char *folder_name, const char *subfolder_name, const char *envvar, const int ver)
{
char user_path[FILE_MAX];
const char *user_base_path;
@@ -959,7 +1069,7 @@ static int get_path_user(char *targetpath, const char *folder_name, const char *
}
else {
BLI_strncpy(targetpath, user_path, FILE_MAX);
- return 1;
+ return true;
}
}
@@ -968,30 +1078,34 @@ static int get_path_user(char *targetpath, const char *folder_name, const char *
BLI_strncpy(user_path, user_base_path, FILE_MAX);
if (!user_path[0])
- return 0;
+ return false;
#ifdef PATH_DEBUG
printf("%s: %s\n", __func__, user_path);
#endif
if (subfolder_name) {
- /* try $HOME/folder_name/subfolder_name */
return test_path(targetpath, user_path, folder_name, subfolder_name);
}
else {
- /* try $HOME/folder_name */
return test_path(targetpath, user_path, NULL, folder_name);
}
}
-static int get_path_system(char *targetpath, const char *folder_name, const char *subfolder_name, const char *envvar, const int ver)
+/**
+ * Returns the path of a folder within the Blender installation directory.
+ *
+ * \param targetpath String to return path
+ * \param folder_name default name of folder within installation area
+ * \param subfolder_name optional name of subfolder within folder
+ * \param envvar name of environment variable which, if defined, overrides folder_name
+ * \param ver Blender version, used to construct a subdirectory name
+ * \return true if it was able to construct such a path.
+ */
+static bool get_path_system(char *targetpath, const char *folder_name, const char *subfolder_name, const char *envvar, const int ver)
{
char system_path[FILE_MAX];
const char *system_base_path;
-
-
- /* first allow developer only overrides to the system path
- * these are only used when running blender from source */
char cwd[FILE_MAX];
char relfolder[FILE_MAX];
@@ -1007,16 +1121,20 @@ static int get_path_system(char *targetpath, const char *folder_name, const char
relfolder[0] = '\0';
}
+ /* first allow developer only overrides to the system path
+ * these are only used when running blender from source */
+
/* try CWD/release/folder_name */
if (BLI_current_working_dir(cwd, sizeof(cwd))) {
if (test_path(targetpath, cwd, "release", relfolder)) {
- return 1;
+ return true;
}
}
/* try EXECUTABLE_DIR/release/folder_name */
if (test_path(targetpath, bprogdir, "release", relfolder))
- return 1;
+ return true;
+
/* end developer overrides */
@@ -1029,7 +1147,7 @@ static int get_path_system(char *targetpath, const char *folder_name, const char
}
else {
BLI_strncpy(targetpath, system_path, FILE_MAX);
- return 1;
+ return true;
}
}
@@ -1038,7 +1156,7 @@ static int get_path_system(char *targetpath, const char *folder_name, const char
BLI_strncpy(system_path, system_base_path, FILE_MAX);
if (!system_path[0])
- return 0;
+ return false;
#ifdef PATH_DEBUG
printf("%s: %s\n", __func__, system_path);
@@ -1056,7 +1174,7 @@ static int get_path_system(char *targetpath, const char *folder_name, const char
/* get a folder out of the 'folder_id' presets for paths */
/* returns the path if found, NULL string if not */
-char *BLI_get_folder(int folder_id, const char *subfolder)
+const char *BLI_get_folder(int folder_id, const char *subfolder)
{
const int ver = BLENDER_VERSION;
static char path[FILE_MAX] = "";
@@ -1103,7 +1221,10 @@ char *BLI_get_folder(int folder_id, const char *subfolder)
return path;
}
-char *BLI_get_user_folder_notest(int folder_id, const char *subfolder)
+/**
+ * Returns the path to a folder in the user area without checking that it actually exists first.
+ */
+const char *BLI_get_user_folder_notest(int folder_id, const char *subfolder)
{
const int ver = BLENDER_VERSION;
static char path[FILE_MAX] = "";
@@ -1128,9 +1249,12 @@ char *BLI_get_user_folder_notest(int folder_id, const char *subfolder)
return path;
}
-char *BLI_get_folder_create(int folder_id, const char *subfolder)
+/**
+ * Returns the path to a folder in the user area, creating it if it doesn't exist.
+ */
+const char *BLI_get_folder_create(int folder_id, const char *subfolder)
{
- char *path;
+ const char *path;
/* only for user folders */
if (!ELEM4(folder_id, BLENDER_USER_DATAFILES, BLENDER_USER_CONFIG, BLENDER_USER_SCRIPTS, BLENDER_USER_AUTOSAVE))
@@ -1146,10 +1270,14 @@ char *BLI_get_folder_create(int folder_id, const char *subfolder)
return path;
}
-char *BLI_get_folder_version(const int id, const int ver, const int do_check)
+/**
+ * Returns the path of the top-level version-specific local, user or system directory.
+ * If do_check, then the result will be NULL if the directory doesn't exist.
+ */
+const char *BLI_get_folder_version(const int id, const int ver, const bool do_check)
{
static char path[FILE_MAX] = "";
- int ok;
+ bool ok;
switch (id) {
case BLENDER_RESOURCE_PATH_USER:
ok = get_path_user(path, NULL, NULL, NULL, ver);
@@ -1162,11 +1290,11 @@ char *BLI_get_folder_version(const int id, const int ver, const int do_check)
break;
default:
path[0] = '\0'; /* in case do_check is false */
- ok = FALSE;
+ ok = false;
BLI_assert(!"incorrect ID");
}
- if ((ok == FALSE) && do_check) {
+ if (!ok && do_check) {
return NULL;
}
@@ -1183,6 +1311,9 @@ char *BLI_get_folder_version(const int id, const int ver, const int do_check)
# undef PATH_DEBUG
#endif
+/**
+ * Sets the specified environment variable to the specified value.
+ */
void BLI_setenv(const char *env, const char *val)
{
/* free windows */
@@ -1208,6 +1339,8 @@ void BLI_setenv(const char *env, const char *val)
/**
* Only set an env var if already not there.
* Like Unix setenv(env, val, 0);
+ *
+ * (not used anywhere).
*/
void BLI_setenv_if_new(const char *env, const char *val)
{
@@ -1216,6 +1349,9 @@ void BLI_setenv_if_new(const char *env, const char *val)
}
+/**
+ * Changes to the path separators to the native ones for this OS.
+ */
void BLI_clean(char *path)
{
#ifdef WIN32
@@ -1227,6 +1363,9 @@ void BLI_clean(char *path)
#endif
}
+/**
+ * Replaces occurrences of from with to in *string.
+ */
void BLI_char_switch(char *string, char from, char to)
{
while (*string != 0) {
@@ -1235,6 +1374,10 @@ void BLI_char_switch(char *string, char from, char to)
}
}
+/**
+ * Strips off nonexistent subdirectories from the end of *dir, leaving the path of
+ * the lowest-level directory that does exist.
+ */
void BLI_make_exist(char *dir)
{
int a;
@@ -1243,7 +1386,7 @@ void BLI_make_exist(char *dir)
a = strlen(dir);
- while (BLI_is_dir(dir) == 0) {
+ while (!BLI_is_dir(dir)) {
a--;
while (dir[a] != SEP) {
a--;
@@ -1263,21 +1406,28 @@ void BLI_make_exist(char *dir)
}
}
+/**
+ * Ensures that the parent directory of *name exists.
+ */
void BLI_make_existing_file(const char *name)
{
- char di[FILE_MAX], fi[FILE_MAXFILE];
+ char di[FILE_MAX];
+ BLI_split_dir_part(name, di, sizeof(di));
- BLI_strncpy(di, name, sizeof(di));
- BLI_splitdirstring(di, fi);
-
- /* test exist */
- if (BLI_exists(di) == 0) {
- BLI_dir_create_recursive(di);
- }
+ /* make if if the dir doesn't exist */
+ BLI_dir_create_recursive(di);
}
-
-void BLI_make_file_string(const char *relabase, char *string, const char *dir, const char *file)
+/**
+ * Returns in *string the concatenation of *dir and *file (also with *relabase on the
+ * front if specified and *dir begins with "//"). Normalizes all occurrences of path
+ * separators, including ensuring there is exactly one between the copies of *dir and *file,
+ * and between the copies of *relabase and *dir.
+ *
+ * \param relabase Optional prefix to substitute for "//" on front of *dir
+ * \param string Area to return result
+ */
+void BLI_make_file_string(const char *relabase, char *string, const char *dir, const char *file)
{
int sl;
@@ -1310,7 +1460,7 @@ void BLI_make_file_string(const char *relabase, char *string, const char *dir,
/* Get the file name, chop everything past the last slash (ie. the filename) */
strcpy(string, relabase);
- lslash = BLI_last_slash(string);
+ lslash = (char *)BLI_last_slash(string);
if (lslash) *(lslash + 1) = 0;
dir += 2; /* Skip over the relative reference */
@@ -1359,43 +1509,34 @@ void BLI_make_file_string(const char *relabase, char *string, const char *dir,
BLI_clean(string);
}
-int BLI_testextensie(const char *str, const char *ext)
+/* does str end with ext. */
+bool BLI_testextensie(const char *str, const char *ext)
{
- short a, b;
- int retval;
-
- a = strlen(str);
- b = strlen(ext);
-
- if (a == 0 || b == 0 || b >= a) {
- retval = 0;
- }
- else if (BLI_strcasecmp(ext, str + a - b)) {
- retval = 0;
- }
- else {
- retval = 1;
- }
-
- return (retval);
+ const size_t a = strlen(str);
+ const size_t b = strlen(ext);
+ return !(a == 0 || b == 0 || b >= a) && (BLI_strcasecmp(ext, str + a - b) == 0);
}
-int BLI_testextensie_array(const char *str, const char **ext_array)
+/* does str end with any of the suffixes in *ext_array. */
+bool BLI_testextensie_array(const char *str, const char **ext_array)
{
int i = 0;
while (ext_array[i]) {
if (BLI_testextensie(str, ext_array[i])) {
- return 1;
+ return true;
}
i++;
}
- return 0;
+ return false;
}
-/* semicolon separated wildcards, eg:
- * '*.zip;*.py;*.exe' */
-int BLI_testextensie_glob(const char *str, const char *ext_fnmatch)
+/**
+ * Semicolon separated wildcards, eg:
+ * '*.zip;*.py;*.exe'
+ * does str match any of the semicolon-separated glob patterns in fnmatch.
+ */
+bool BLI_testextensie_glob(const char *str, const char *ext_fnmatch)
{
const char *ext_step = ext_fnmatch;
char pattern[16];
@@ -1414,19 +1555,23 @@ int BLI_testextensie_glob(const char *str, const char *ext_fnmatch)
BLI_strncpy(pattern, ext_step, len_ext);
if (fnmatch(pattern, str, FNM_CASEFOLD) == 0) {
- return 1;
+ return true;
}
ext_step += len_ext;
}
- return 0;
+ return false;
}
-int BLI_replace_extension(char *path, size_t maxlen, const char *ext)
+/**
+ * Removes any existing extension on the end of \a path and appends \a ext.
+ * \return false if there was no room.
+ */
+bool BLI_replace_extension(char *path, size_t maxlen, const char *ext)
{
- size_t path_len = strlen(path);
- size_t ext_len = strlen(ext);
+ const size_t path_len = strlen(path);
+ const size_t ext_len = strlen(ext);
ssize_t a;
for (a = path_len - 1; a >= 0; a--) {
@@ -1440,24 +1585,26 @@ int BLI_replace_extension(char *path, size_t maxlen, const char *ext)
}
if (a + ext_len >= maxlen)
- return 0;
+ return false;
memcpy(path + a, ext, ext_len + 1);
- return 1;
+ return true;
}
-/* strip's trailing '.'s and adds the extension only when needed */
-int BLI_ensure_extension(char *path, size_t maxlen, const char *ext)
+/**
+ * Strip's trailing '.'s and adds the extension only when needed
+ */
+bool BLI_ensure_extension(char *path, size_t maxlen, const char *ext)
{
- size_t path_len = strlen(path);
- size_t ext_len = strlen(ext);
+ const size_t path_len = strlen(path);
+ const size_t ext_len = strlen(ext);
ssize_t a;
- /* first check the extension is alread there */
+ /* first check the extension is already there */
if ( (ext_len <= path_len) &&
(strcmp(path + (path_len - ext_len), ext) == 0))
{
- return 1;
+ return true;
}
for (a = path_len - 1; a >= 0; a--) {
@@ -1471,10 +1618,10 @@ int BLI_ensure_extension(char *path, size_t maxlen, const char *ext)
a++;
if (a + ext_len >= maxlen)
- return 0;
+ return false;
memcpy(path + a, ext, ext_len + 1);
- return 1;
+ return true;
}
/* Converts "/foo/bar.txt" to "/foo/" and "bar.txt"
@@ -1485,8 +1632,8 @@ int BLI_ensure_extension(char *path, size_t maxlen, const char *ext)
* */
void BLI_split_dirfile(const char *string, char *dir, char *file, const size_t dirlen, const size_t filelen)
{
- char *lslash_str = BLI_last_slash(string);
- size_t lslash = lslash_str ? (size_t)(lslash_str - string) + 1 : 0;
+ const char *lslash_str = BLI_last_slash(string);
+ const size_t lslash = lslash_str ? (size_t)(lslash_str - string) + 1 : 0;
if (dir) {
if (lslash) {
@@ -1502,17 +1649,26 @@ void BLI_split_dirfile(const char *string, char *dir, char *file, const size_t d
}
}
+/**
+ * Copies the parent directory part of string into *dir, max length dirlen.
+ */
void BLI_split_dir_part(const char *string, char *dir, const size_t dirlen)
{
BLI_split_dirfile(string, dir, NULL, dirlen, 0);
}
+/**
+ * Copies the leaf filename part of string into *file, max length filelen.
+ */
void BLI_split_file_part(const char *string, char *file, const size_t filelen)
{
BLI_split_dirfile(string, NULL, file, 0, filelen);
}
-/* simple appending of filename to dir, does not check for valid path! */
+/**
+ * Simple appending of filename to dir, does not check for valid path!
+ * Puts result into *dst, which may be same area as *dir.
+ */
void BLI_join_dirfile(char *dst, const size_t maxlen, const char *dir, const char *file)
{
size_t dirlen = BLI_strnlen(dir, maxlen);
@@ -1549,10 +1705,15 @@ void BLI_join_dirfile(char *dst, const size_t maxlen, const char *dir, const cha
BLI_strncpy(dst + dirlen, file, maxlen - dirlen);
}
-/* like pythons os.path.basename( ) */
-char *BLI_path_basename(char *path)
+/**
+ * like pythons os.path.basename()
+ *
+ * \return The pointer into \a path string immediately after last slash,
+ * or start of \a path if none found.
+ */
+const char *BLI_path_basename(const char *path)
{
- char *filename = BLI_last_slash(path);
+ const char * const filename = BLI_last_slash(path);
return filename ? filename + 1 : path;
}
@@ -1591,11 +1752,29 @@ char *BLI_path_basename(char *path)
* this function returns wrong results!
* XXX: test on empty base_dir and return an error ?
*/
-int BLI_rebase_path(char *abs, size_t abs_len, char *rel, size_t rel_len, const char *base_dir, const char *src_dir, const char *dest_dir)
+
+/**
+ *
+ * \param abs Optional string to return new full path
+ * \param abs_len Size of *abs string
+ * \param rel Optional area to return new path relative to parent directory of .blend file
+ * (only meaningful if item is in a subdirectory thereof)
+ * \param rel_len Size of *rel area
+ * \param base_dir Path of .blend file
+ * \param src_dir Original path of item (any initial "//" will be expanded to
+ * parent directory of .blend file)
+ * \param dest_dir New directory into which item will be moved
+ * \return bli_rebase_state
+ *
+ * \note Not actually used anywhere!
+ */
+int BLI_rebase_path(char *abs, size_t abs_len,
+ char *rel, size_t rel_len,
+ const char *base_dir, const char *src_dir, const char *dest_dir)
{
- char path[FILE_MAX];
- char dir[FILE_MAX];
- char base[FILE_MAX];
+ char path[FILE_MAX]; /* original full path of item */
+ char dir[FILE_MAX]; /* directory part of src_dir */
+ char base[FILE_MAX]; /* basename part of src_dir */
char blend_dir[FILE_MAX]; /* directory, where current .blend file resides */
char dest_path[FILE_MAX];
char rel_dir[FILE_MAX];
@@ -1627,21 +1806,23 @@ int BLI_rebase_path(char *abs, size_t abs_len, char *rel, size_t rel_len, const
/* if image is "below" current .blend file directory */
if (!BLI_path_ncmp(path, blend_dir, len)) {
- /* if image is _in_ current .blend file directory */
if (BLI_path_cmp(dir, blend_dir) == 0) {
+ /* image is directly in .blend file parent directory => put directly in dest_dir */
BLI_join_dirfile(dest_path, sizeof(dest_path), dest_dir, base);
}
- /* "below" */
else {
+ /* "below" (in subdirectory of .blend file parent directory) => put in same relative directory structure in dest_dir */
/* rel = image_path_dir - blend_dir */
BLI_strncpy(rel_dir, dir + len, sizeof(rel_dir));
-
+ /* subdirectories relative to blend_dir */
BLI_join_dirfile(dest_path, sizeof(dest_path), dest_dir, rel_dir);
+ /* same subdirectories relative to dest_dir */
BLI_join_dirfile(dest_path, sizeof(dest_path), dest_path, base);
+ /* keeping original item basename */
}
}
- /* image is out of current directory */
+ /* image is out of current directory -- just put straight in dest_dir */
else {
BLI_join_dirfile(dest_path, sizeof(dest_path), dest_dir, base);
}
@@ -1651,7 +1832,7 @@ int BLI_rebase_path(char *abs, size_t abs_len, char *rel, size_t rel_len, const
if (rel) {
strncat(rel, rel_dir, rel_len);
- strncat(rel, base, rel_len);
+ strncat(rel, base, rel_len); /* FIXME: could overflow rel area! */
}
/* return 2 if (src == dest) */
@@ -1663,12 +1844,13 @@ int BLI_rebase_path(char *abs, size_t abs_len, char *rel, size_t rel_len, const
return BLI_REBASE_OK;
}
-char *BLI_first_slash(char *string)
+/**
+ * Returns pointer to the leftmost path separator in string. Not actually used anywhere.
+ */
+const char *BLI_first_slash(const char *string)
{
- char *ffslash, *fbslash;
-
- ffslash = strchr(string, '/');
- fbslash = strchr(string, '\\');
+ char * const ffslash = strchr(string, '/');
+ char * const fbslash = strchr(string, '\\');
if (!ffslash) return fbslash;
else if (!fbslash) return ffslash;
@@ -1677,12 +1859,13 @@ char *BLI_first_slash(char *string)
else return fbslash;
}
-char *BLI_last_slash(const char *string)
+/**
+ * Returns pointer to the rightmost path separator in string.
+ */
+const char *BLI_last_slash(const char *string)
{
- char *lfslash, *lbslash;
-
- lfslash = strrchr(string, '/');
- lbslash = strrchr(string, '\\');
+ const char * const lfslash = strrchr(string, '/');
+ const char * const lbslash = strrchr(string, '\\');
if (!lfslash) return lbslash;
else if (!lbslash) return lfslash;
@@ -1691,7 +1874,10 @@ char *BLI_last_slash(const char *string)
else return lfslash;
}
-/* adds a slash if there isn't one there already */
+/**
+ * Appends a slash to string if there isn't one there already.
+ * Returns the new length of the string.
+ */
int BLI_add_slash(char *string)
{
int len = strlen(string);
@@ -1703,7 +1889,9 @@ int BLI_add_slash(char *string)
return len;
}
-/* removes a slash if there is one */
+/**
+ * Removes the last slash and everything after it to the end of string, if there is one.
+ */
void BLI_del_slash(char *string)
{
int len = strlen(string);
@@ -1718,6 +1906,11 @@ void BLI_del_slash(char *string)
}
}
+/**
+ * Tries appending each of the semicolon-separated extensions in the PATHEXT
+ * environment variable (Windows-only) onto *name in turn until such a file is found.
+ * Returns success/failure.
+ */
static int add_win32_extension(char *name)
{
int retval = 0;
@@ -1934,16 +2127,26 @@ static void BLI_where_is_temp(char *fullname, const size_t maxlen, char *userdir
}
}
+/**
+ * Sets btempdir to userdir if specified and is a valid directory, otherwise
+ * chooses a suitable OS-specific temporary directory.
+ */
void BLI_init_temporary_dir(char *userdir)
{
BLI_where_is_temp(btempdir, FILE_MAX, userdir);
}
+/**
+ * Returns the path to the temporary directory.
+ */
const char *BLI_temporary_dir(void)
{
return btempdir;
}
+/**
+ * Puts in *dir path to OS-specific temporary directory.
+ */
void BLI_system_temporary_dir(char *dir)
{
BLI_where_is_temp(dir, FILE_MAX, NULL);
@@ -1951,6 +2154,10 @@ void BLI_system_temporary_dir(char *dir)
#ifdef WITH_ICONV
+/**
+ * Converts a string encoded in the charset named by *code to UTF-8.
+ * Opens a new iconv context each time it is run, which is probably not the
+ * most efficient. */
void BLI_string_to_utf8(char *original, char *utf_8, const char *code)
{
size_t inbytesleft = strlen(original);
@@ -1971,6 +2178,7 @@ void BLI_string_to_utf8(char *original, char *utf_8, const char *code)
rv = iconv(cd, &original, &inbytesleft, &utf_8, &outbytesleft);
if (rv == (size_t) -1) {
printf("iconv Error\n");
+ iconv_close(cd);
return;
}
*utf_8 = '\0';
diff --git a/source/blender/blenlib/intern/rct.c b/source/blender/blenlib/intern/rct.c
index 4bd7715ea7a..127855161c0 100644
--- a/source/blender/blenlib/intern/rct.c
+++ b/source/blender/blenlib/intern/rct.c
@@ -48,23 +48,23 @@
*
* \return True if \a rect is empty.
*/
-int BLI_rcti_is_empty(const rcti *rect)
+bool BLI_rcti_is_empty(const rcti *rect)
{
return ((rect->xmax <= rect->xmin) || (rect->ymax <= rect->ymin));
}
-int BLI_rctf_is_empty(const rctf *rect)
+bool BLI_rctf_is_empty(const rctf *rect)
{
return ((rect->xmax <= rect->xmin) || (rect->ymax <= rect->ymin));
}
-int BLI_rcti_isect_pt(const rcti *rect, const int x, const int y)
+bool BLI_rcti_isect_pt(const rcti *rect, const int x, const int y)
{
- if (x < rect->xmin) return 0;
- if (x > rect->xmax) return 0;
- if (y < rect->ymin) return 0;
- if (y > rect->ymax) return 0;
- return 1;
+ if (x < rect->xmin) return false;
+ if (x > rect->xmax) return false;
+ if (y < rect->ymin) return false;
+ if (y > rect->ymax) return false;
+ return true;
}
/**
@@ -74,31 +74,31 @@ int BLI_rcti_isect_pt(const rcti *rect, const int x, const int y)
*
* \return True if \a rect is empty.
*/
-int BLI_rcti_isect_pt_v(const rcti *rect, const int xy[2])
+bool BLI_rcti_isect_pt_v(const rcti *rect, const int xy[2])
{
- if (xy[0] < rect->xmin) return 0;
- if (xy[0] > rect->xmax) return 0;
- if (xy[1] < rect->ymin) return 0;
- if (xy[1] > rect->ymax) return 0;
- return 1;
+ if (xy[0] < rect->xmin) return false;
+ if (xy[0] > rect->xmax) return false;
+ if (xy[1] < rect->ymin) return false;
+ if (xy[1] > rect->ymax) return false;
+ return true;
}
-int BLI_rctf_isect_pt(const rctf *rect, const float x, const float y)
+bool BLI_rctf_isect_pt(const rctf *rect, const float x, const float y)
{
- if (x < rect->xmin) return 0;
- if (x > rect->xmax) return 0;
- if (y < rect->ymin) return 0;
- if (y > rect->ymax) return 0;
- return 1;
+ if (x < rect->xmin) return false;
+ if (x > rect->xmax) return false;
+ if (y < rect->ymin) return false;
+ if (y > rect->ymax) return false;
+ return true;
}
-int BLI_rctf_isect_pt_v(const rctf *rect, const float xy[2])
+bool BLI_rctf_isect_pt_v(const rctf *rect, const float xy[2])
{
- if (xy[0] < rect->xmin) return 0;
- if (xy[0] > rect->xmax) return 0;
- if (xy[1] < rect->ymin) return 0;
- if (xy[1] > rect->ymax) return 0;
- return 1;
+ if (xy[0] < rect->xmin) return false;
+ if (xy[0] > rect->xmax) return false;
+ if (xy[1] < rect->ymin) return false;
+ if (xy[1] > rect->ymax) return false;
+ return true;
}
/* based closely on 'isect_line_line_v2_int', but in modified so corner cases are treated as intersections */
@@ -127,17 +127,17 @@ static int isect_segments_fl(const float v1[2], const float v2[2], const float v
}
}
-int BLI_rcti_isect_segment(const rcti *rect, const int s1[2], const int s2[2])
+bool BLI_rcti_isect_segment(const rcti *rect, const int s1[2], const int s2[2])
{
/* first do outside-bounds check for both points of the segment */
- if (s1[0] < rect->xmin && s2[0] < rect->xmin) return 0;
- if (s1[0] > rect->xmax && s2[0] > rect->xmax) return 0;
- if (s1[1] < rect->ymin && s2[1] < rect->ymin) return 0;
- if (s1[1] > rect->ymax && s2[1] > rect->ymax) return 0;
+ if (s1[0] < rect->xmin && s2[0] < rect->xmin) return false;
+ if (s1[0] > rect->xmax && s2[0] > rect->xmax) return false;
+ if (s1[1] < rect->ymin && s2[1] < rect->ymin) return false;
+ if (s1[1] > rect->ymax && s2[1] > rect->ymax) return false;
/* if either points intersect then we definetly intersect */
if (BLI_rcti_isect_pt_v(rect, s1) || BLI_rcti_isect_pt_v(rect, s2)) {
- return 1;
+ return true;
}
else {
/* both points are outside but may insersect the rect */
@@ -147,32 +147,32 @@ int BLI_rcti_isect_segment(const rcti *rect, const int s1[2], const int s2[2])
tvec1[0] = rect->xmin; tvec1[1] = rect->ymin;
tvec2[0] = rect->xmin; tvec2[1] = rect->ymax;
if (isect_segments_i(s1, s2, tvec1, tvec2)) {
- return 1;
+ return true;
}
/* diagonal: [\] */
tvec1[0] = rect->xmin; tvec1[1] = rect->ymax;
tvec2[0] = rect->xmax; tvec2[1] = rect->ymin;
if (isect_segments_i(s1, s2, tvec1, tvec2)) {
- return 1;
+ return true;
}
/* no intersection */
- return 0;
+ return false;
}
}
-int BLI_rctf_isect_segment(const rctf *rect, const float s1[2], const float s2[2])
+bool BLI_rctf_isect_segment(const rctf *rect, const float s1[2], const float s2[2])
{
/* first do outside-bounds check for both points of the segment */
- if (s1[0] < rect->xmin && s2[0] < rect->xmin) return 0;
- if (s1[0] > rect->xmax && s2[0] > rect->xmax) return 0;
- if (s1[1] < rect->ymin && s2[1] < rect->ymin) return 0;
- if (s1[1] > rect->ymax && s2[1] > rect->ymax) return 0;
+ if (s1[0] < rect->xmin && s2[0] < rect->xmin) return false;
+ if (s1[0] > rect->xmax && s2[0] > rect->xmax) return false;
+ if (s1[1] < rect->ymin && s2[1] < rect->ymin) return false;
+ if (s1[1] > rect->ymax && s2[1] > rect->ymax) return false;
/* if either points intersect then we definetly intersect */
if (BLI_rctf_isect_pt_v(rect, s1) || BLI_rctf_isect_pt_v(rect, s2)) {
- return 1;
+ return true;
}
else {
/* both points are outside but may insersect the rect */
@@ -182,18 +182,18 @@ int BLI_rctf_isect_segment(const rctf *rect, const float s1[2], const float s2[2
tvec1[0] = rect->xmin; tvec1[1] = rect->ymin;
tvec2[0] = rect->xmin; tvec2[1] = rect->ymax;
if (isect_segments_fl(s1, s2, tvec1, tvec2)) {
- return 1;
+ return true;
}
/* diagonal: [\] */
tvec1[0] = rect->xmin; tvec1[1] = rect->ymax;
tvec2[0] = rect->xmax; tvec2[1] = rect->ymin;
if (isect_segments_fl(s1, s2, tvec1, tvec2)) {
- return 1;
+ return true;
}
/* no intersection */
- return 0;
+ return false;
}
}
@@ -353,49 +353,49 @@ void BLI_rctf_interp(rctf *rect, const rctf *rect_a, const rctf *rect_b, const f
/* BLI_rcti_interp() not needed yet */
-int BLI_rctf_clamp_pt_v(const struct rctf *rect, float xy[2])
+bool BLI_rctf_clamp_pt_v(const struct rctf *rect, float xy[2])
{
- int change = 0;
- if (xy[0] < rect->xmin) { xy[0] = rect->xmin; change = 1; }
- if (xy[0] > rect->xmax) { xy[0] = rect->xmax; change = 1; }
- if (xy[1] < rect->ymin) { xy[1] = rect->ymin; change = 1; }
- if (xy[1] > rect->ymax) { xy[1] = rect->ymax; change = 1; }
+ bool change = false;
+ if (xy[0] < rect->xmin) { xy[0] = rect->xmin; change = true; }
+ if (xy[0] > rect->xmax) { xy[0] = rect->xmax; change = true; }
+ if (xy[1] < rect->ymin) { xy[1] = rect->ymin; change = true; }
+ if (xy[1] > rect->ymax) { xy[1] = rect->ymax; change = true; }
return change;
}
-int BLI_rcti_clamp_pt_v(const struct rcti *rect, int xy[2])
+bool BLI_rcti_clamp_pt_v(const struct rcti *rect, int xy[2])
{
- int change = 0;
- if (xy[0] < rect->xmin) { xy[0] = rect->xmin; change = 1; }
- if (xy[0] > rect->xmax) { xy[0] = rect->xmax; change = 1; }
- if (xy[1] < rect->ymin) { xy[1] = rect->ymin; change = 1; }
- if (xy[1] > rect->ymax) { xy[1] = rect->ymax; change = 1; }
+ bool change = false;
+ if (xy[0] < rect->xmin) { xy[0] = rect->xmin; change = true; }
+ if (xy[0] > rect->xmax) { xy[0] = rect->xmax; change = true; }
+ if (xy[1] < rect->ymin) { xy[1] = rect->ymin; change = true; }
+ if (xy[1] > rect->ymax) { xy[1] = rect->ymax; change = true; }
return change;
}
-int BLI_rctf_compare(const struct rctf *rect_a, const struct rctf *rect_b, const float limit)
+bool BLI_rctf_compare(const struct rctf *rect_a, const struct rctf *rect_b, const float limit)
{
if (fabsf(rect_a->xmin - rect_b->xmin) < limit)
if (fabsf(rect_a->xmax - rect_b->xmax) < limit)
if (fabsf(rect_a->ymin - rect_b->ymin) < limit)
if (fabsf(rect_a->ymax - rect_b->ymax) < limit)
- return 1;
+ return true;
- return 0;
+ return false;
}
-int BLI_rcti_compare(const struct rcti *rect_a, const struct rcti *rect_b)
+bool BLI_rcti_compare(const struct rcti *rect_a, const struct rcti *rect_b)
{
if (rect_a->xmin == rect_b->xmin)
if (rect_a->xmax == rect_b->xmax)
if (rect_a->ymin == rect_b->ymin)
if (rect_a->ymax == rect_b->ymax)
- return 1;
+ return true;
- return 0;
+ return false;
}
-int BLI_rctf_isect(const rctf *src1, const rctf *src2, rctf *dest)
+bool BLI_rctf_isect(const rctf *src1, const rctf *src2, rctf *dest)
{
float xmin, xmax;
float ymin, ymax;
@@ -412,7 +412,7 @@ int BLI_rctf_isect(const rctf *src1, const rctf *src2, rctf *dest)
dest->ymin = ymin;
dest->ymax = ymax;
}
- return 1;
+ return true;
}
else {
if (dest) {
@@ -421,11 +421,11 @@ int BLI_rctf_isect(const rctf *src1, const rctf *src2, rctf *dest)
dest->ymin = 0;
dest->ymax = 0;
}
- return 0;
+ return false;
}
}
-int BLI_rcti_isect(const rcti *src1, const rcti *src2, rcti *dest)
+bool BLI_rcti_isect(const rcti *src1, const rcti *src2, rcti *dest)
{
int xmin, xmax;
int ymin, ymax;
@@ -442,7 +442,7 @@ int BLI_rcti_isect(const rcti *src1, const rcti *src2, rcti *dest)
dest->ymin = ymin;
dest->ymax = ymax;
}
- return 1;
+ return true;
}
else {
if (dest) {
@@ -451,7 +451,7 @@ int BLI_rcti_isect(const rcti *src1, const rcti *src2, rcti *dest)
dest->ymin = 0;
dest->ymax = 0;
}
- return 0;
+ return false;
}
}
diff --git a/source/blender/blenlib/intern/storage.c b/source/blender/blenlib/intern/storage.c
index 1358fdd2a62..71cd5e529a2 100644
--- a/source/blender/blenlib/intern/storage.c
+++ b/source/blender/blenlib/intern/storage.c
@@ -71,6 +71,7 @@
#ifdef WIN32
# include <io.h>
# include <direct.h>
+# include <limits.h> /* PATH_MAX */
# include "BLI_winstuff.h"
# include "utfconv.h"
#else
@@ -91,14 +92,14 @@
#include "BLI_fileops_types.h"
#include "BLI_path_util.h"
-/* vars: */
-static int totnum, actnum;
-static struct direntry *files;
+#include "../imbuf/IMB_imbuf.h"
-static struct ListBase dirbase_ = {NULL, NULL};
-static struct ListBase *dirbase = &dirbase_;
-
-/* can return NULL when the size is not big enough */
+/**
+ * Copies the current working directory into *dir (max size maxncpy), and
+ * returns a pointer to same.
+ *
+ * \note can return NULL when the size is not big enough
+ */
char *BLI_current_working_dir(char *dir, const size_t maxncpy)
{
const char *pwd = getenv("PWD");
@@ -110,26 +111,33 @@ char *BLI_current_working_dir(char *dir, const size_t maxncpy)
return getcwd(dir, maxncpy);
}
-
+/*
+ * Ordering function for sorting lists of files/directories. Returns -1 if
+ * entry1 belongs before entry2, 0 if they are equal, 1 if they should be swapped.
+ */
static int bli_compare(struct direntry *entry1, struct direntry *entry2)
{
/* type is equal to stat.st_mode */
+ /* directories come before non-directories */
if (S_ISDIR(entry1->type)) {
if (S_ISDIR(entry2->type) == 0) return (-1);
}
else {
if (S_ISDIR(entry2->type)) return (1);
}
+ /* non-regular files come after regular files */
if (S_ISREG(entry1->type)) {
if (S_ISREG(entry2->type) == 0) return (-1);
}
else {
if (S_ISREG(entry2->type)) return (1);
}
+ /* arbitrary, but consistent, ordering of different types of non-regular files */
if ((entry1->type & S_IFMT) < (entry2->type & S_IFMT)) return (-1);
if ((entry1->type & S_IFMT) > (entry2->type & S_IFMT)) return (1);
-
+
+ /* OK, now we know their S_IFMT fields are the same, go on to a name comparison */
/* make sure "." and ".." are always first */
if (strcmp(entry1->relname, ".") == 0) return (-1);
if (strcmp(entry2->relname, ".") == 0) return (1);
@@ -139,7 +147,10 @@ static int bli_compare(struct direntry *entry1, struct direntry *entry2)
return (BLI_natstrcmp(entry1->relname, entry2->relname));
}
-
+/**
+ * Returns the number of free bytes on the volume containing the specified pathname. */
+/* Not actually used anywhere.
+ */
double BLI_dir_free_space(const char *dir)
{
#ifdef WIN32
@@ -180,7 +191,9 @@ double BLI_dir_free_space(const char *dir)
slash = strrchr(name, '/');
if (slash) slash[1] = 0;
}
- else strcpy(name, "/");
+ else {
+ strcpy(name, "/");
+ }
#if defined(__FreeBSD__) || defined(linux) || defined(__OpenBSD__) || defined(__APPLE__) || defined(__GNU__) || defined(__GLIBC__)
if (statfs(name, &disk)) return(-1);
@@ -197,89 +210,77 @@ double BLI_dir_free_space(const char *dir)
#endif
}
-static void bli_builddir(const char *dirname, const char *relname)
+struct BuildDirCtx {
+ struct direntry *files; /* array[nrfiles] */
+ int nrfiles;
+};
+
+/**
+ * Scans the directory named *dirname and appends entries for its contents to files.
+ */
+static void bli_builddir(struct BuildDirCtx *dir_ctx, const char *dirname)
{
- struct dirent *fname;
- struct dirlink *dlink;
- int rellen, newnum = 0;
- char buf[256];
+ struct ListBase dirbase = {NULL, NULL};
+ int newnum = 0;
DIR *dir;
- BLI_strncpy(buf, relname, sizeof(buf));
- rellen = strlen(relname);
-
- if (rellen) {
- buf[rellen] = '/';
- rellen++;
- }
-#ifndef WIN32
- if (chdir(dirname) == -1) {
- perror(dirname);
- return;
- }
-#else
- UTF16_ENCODE(dirname);
- if (!SetCurrentDirectoryW(dirname_16)) {
- perror(dirname);
- free(dirname_16);
- return;
- }
- UTF16_UN_ENCODE(dirname);
+ if ((dir = opendir(dirname)) != NULL) {
-#endif
- if ((dir = (DIR *)opendir("."))) {
- while ((fname = (struct dirent *) readdir(dir)) != NULL) {
- dlink = (struct dirlink *)malloc(sizeof(struct dirlink));
- if (dlink) {
- BLI_strncpy(buf + rellen, fname->d_name, sizeof(buf) - rellen);
- dlink->name = BLI_strdup(buf);
- BLI_addhead(dirbase, dlink);
+ const struct dirent *fname;
+ while ((fname = readdir(dir)) != NULL) {
+ struct dirlink * const dlink = (struct dirlink *)malloc(sizeof(struct dirlink));
+ if (dlink != NULL) {
+ dlink->name = BLI_strdup(fname->d_name);
+ BLI_addhead(&dirbase, dlink);
newnum++;
}
}
-
+
if (newnum) {
- if (files) {
- void *tmp = realloc(files, (totnum + newnum) * sizeof(struct direntry));
+ if (dir_ctx->files) {
+ void * const tmp = realloc(dir_ctx->files, (dir_ctx->nrfiles + newnum) * sizeof(struct direntry));
if (tmp) {
- files = (struct direntry *)tmp;
+ dir_ctx->files = (struct direntry *)tmp;
}
else { /* realloc fail */
- free(files);
- files = NULL;
+ free(dir_ctx->files);
+ dir_ctx->files = NULL;
}
}
- if (files == NULL)
- files = (struct direntry *)malloc(newnum * sizeof(struct direntry));
+ if (dir_ctx->files == NULL)
+ dir_ctx->files = (struct direntry *)malloc(newnum * sizeof(struct direntry));
- if (files) {
- dlink = (struct dirlink *) dirbase->first;
+ if (dir_ctx->files) {
+ struct dirlink * dlink = (struct dirlink *) dirbase.first;
+ struct direntry *file = &dir_ctx->files[dir_ctx->nrfiles];
while (dlink) {
- memset(&files[actnum], 0, sizeof(struct direntry));
- files[actnum].relname = dlink->name;
- files[actnum].path = BLI_strdupcat(dirname, dlink->name);
+ char fullname[PATH_MAX];
+ memset(file, 0, sizeof(struct direntry));
+ file->relname = dlink->name;
+ file->path = BLI_strdupcat(dirname, dlink->name);
+ BLI_join_dirfile(fullname, sizeof(fullname), dirname, dlink->name);
// use 64 bit file size, only needed for WIN32 and WIN64.
// Excluding other than current MSVC compiler until able to test
#ifdef WIN32
{
- wchar_t *name_16 = alloc_utf16_from_8(dlink->name, 0);
-#if (defined(WIN32) || defined(WIN64)) && (_MSC_VER >= 1500)
- _wstat64(name_16, &files[actnum].s);
+ wchar_t *name_16 = alloc_utf16_from_8(fullname, 0);
+#if defined(_MSC_VER) && (_MSC_VER >= 1500)
+ _wstat64(name_16, &file->s);
#elif defined(__MINGW32__)
- _stati64(dlink->name, &files[actnum].s);
+ _stati64(fullname, &file->s);
#endif
free(name_16);
}
#else
- stat(dlink->name, &files[actnum].s);
+ stat(fullname, &file->s);
#endif
- files[actnum].type = files[actnum].s.st_mode;
- files[actnum].flags = 0;
- totnum++;
- actnum++;
+ file->type = file->s.st_mode;
+ file->flags = 0;
+ dir_ctx->nrfiles++;
+ file++;
dlink = dlink->next;
}
}
@@ -288,8 +289,10 @@ static void bli_builddir(const char *dirname, const char *relname)
exit(1);
}
- BLI_freelist(dirbase);
- if (files) qsort(files, actnum, sizeof(struct direntry), (int (*)(const void *, const void *))bli_compare);
+ BLI_freelist(&dirbase);
+ if (dir_ctx->files) {
+ qsort(dir_ctx->files, dir_ctx->nrfiles, sizeof(struct direntry), (int (*)(const void *, const void *))bli_compare);
+ }
}
else {
printf("%s empty directory\n", dirname);
@@ -302,12 +305,17 @@ static void bli_builddir(const char *dirname, const char *relname)
}
}
-static void bli_adddirstrings(void)
+/**
+ * Fills in the "mode[123]", "size" and "string" fields in the elements of the files
+ * array with descriptive details about each item. "string" will have a format similar to "ls -l".
+ */
+static void bli_adddirstrings(struct BuildDirCtx *dir_ctx)
{
char datum[100];
- char buf[512];
+// char buf[512]; // UNUSED
char size[250];
- static const char *types[8] = {"---", "--x", "-w-", "-wx", "r--", "r-x", "rw-", "rwx"};
+ const char *types[8] = {"---", "--x", "-w-", "-wx", "r--", "r-x", "rw-", "rwx"};
+ /* symbolic display, indexed by mode field value */
int num, mode;
#ifdef WIN32
__int64 st_size;
@@ -319,7 +327,7 @@ static void bli_adddirstrings(void)
struct tm *tm;
time_t zero = 0;
- for (num = 0, file = files; num < actnum; num++, file++) {
+ for (num = 0, file = dir_ctx->files; num < dir_ctx->nrfiles; num++, file++) {
#ifdef WIN32
mode = 0;
BLI_strncpy(file->mode1, types[0], sizeof(file->mode1));
@@ -330,7 +338,7 @@ static void bli_adddirstrings(void)
BLI_strncpy(file->mode1, types[(mode & 0700) >> 6], sizeof(file->mode1));
BLI_strncpy(file->mode2, types[(mode & 0070) >> 3], sizeof(file->mode2));
- BLI_strncpy(file->mode3, types[(mode & 0007)], sizeof(file->mode3));
+ BLI_strncpy(file->mode3, types[(mode & 0007)], sizeof(file->mode3));
if (((mode & S_ISGID) == S_ISGID) && (file->mode2[2] == '-')) file->mode2[2] = 'l';
@@ -375,6 +383,9 @@ static void bli_adddirstrings(void)
*/
st_size = file->s.st_size;
+ /* FIXME: Either change decimal prefixes to binary ones
+ * <http://en.wikipedia.org/wiki/Binary_prefix>, or change
+ * divisor factors from 1024 to 1000. */
if (st_size > 1024 * 1024 * 1024) {
BLI_snprintf(file->size, sizeof(file->size), "%.2f GB", ((double)st_size) / (1024 * 1024 * 1024));
}
@@ -408,61 +419,86 @@ static void bli_adddirstrings(void)
BLI_snprintf(size, sizeof(size), "%10d", (int) st_size);
}
+#if 0
BLI_snprintf(buf, sizeof(buf), "%s %s %s %7s %s %s %10s %s",
file->mode1, file->mode2, file->mode3, file->owner,
file->date, file->time, size, file->relname);
-
- file->string = BLI_strdup(buf);
+#endif
}
}
+/**
+ * Scans the contents of the directory named *dirname, and allocates and fills in an
+ * array of entries describing them in *filelist. The length of the array is the function result.
+ */
unsigned int BLI_dir_contents(const char *dirname, struct direntry **filelist)
{
- /* reset global variables
- * memory stored in files is free()'d in
- * filesel.c:freefilelist() */
+ struct BuildDirCtx dir_ctx;
- actnum = totnum = 0;
- files = NULL;
+ dir_ctx.nrfiles = 0;
+ dir_ctx.files = NULL;
- bli_builddir(dirname, "");
- bli_adddirstrings();
+ bli_builddir(&dir_ctx, dirname);
+ bli_adddirstrings(&dir_ctx);
- if (files) {
- *(filelist) = files;
+ if (dir_ctx.files) {
+ *filelist = dir_ctx.files;
}
else {
// keep blender happy. Blender stores this in a variable
// where 0 has special meaning.....
- *(filelist) = files = malloc(sizeof(struct direntry));
+ *filelist = malloc(sizeof(struct direntry));
}
- return(actnum);
+ return dir_ctx.nrfiles;
}
+/* frees storage for an array of direntries, including the array itself. */
+void BLI_free_filelist(struct direntry *filelist, unsigned int nrentries)
+{
+ unsigned int i;
+ for (i = 0; i < nrentries; ++i) {
+ struct direntry * const entry = filelist + i;
+ if (entry->image) {
+ IMB_freeImBuf(entry->image);
+ }
+ if (entry->relname)
+ MEM_freeN(entry->relname);
+ if (entry->path)
+ MEM_freeN(entry->path);
+ /* entry->poin assumed not to point to anything needing freeing here */
+ }
+ free(filelist);
+}
+
+
+/**
+ * Returns the file size of an opened file descriptor.
+ */
size_t BLI_file_descriptor_size(int file)
{
- struct stat buf;
-
- if (file <= 0) return (-1);
- fstat(file, &buf); /* CHANGE */
- return (buf.st_size);
+ struct stat st;
+ if ((file < 0) || (fstat(file, &st) == -1))
+ return -1;
+ return st.st_size;
}
+/**
+ * Returns the size of a file.
+ */
size_t BLI_file_size(const char *path)
{
- int size, file = BLI_open(path, O_BINARY | O_RDONLY, 0);
-
- if (file == -1)
+ struct stat stats;
+ if (BLI_stat(path, &stats) == -1)
return -1;
-
- size = BLI_file_descriptor_size(file);
- close(file);
- return size;
+ return stats.st_size;
}
-
+/**
+ * Returns the st_mode from statting the specified path name, or 0 if it couldn't be statted
+ * (most likely doesn't exist or no access).
+ */
int BLI_exists(const char *name)
{
#if defined(WIN32)
@@ -509,18 +545,27 @@ int BLI_stat(const char *path, struct stat *buffer)
}
#endif
-/* would be better in fileops.c except that it needs stat.h so add here */
-int BLI_is_dir(const char *file)
+/**
+ * Does the specified path point to a directory?
+ * \note Would be better in fileops.c except that it needs stat.h so add here
+ */
+bool BLI_is_dir(const char *file)
{
return S_ISDIR(BLI_exists(file));
}
-int BLI_is_file(const char *path)
+/**
+ * Does the specified path point to a non-directory?
+ */
+bool BLI_is_file(const char *path)
{
- int mode = BLI_exists(path);
+ const int mode = BLI_exists(path);
return (mode && !S_ISDIR(mode));
}
+/**
+ * Reads the contents of a text file and returns the lines in a linked list.
+ */
LinkNode *BLI_file_read_as_lines(const char *name)
{
FILE *fp = BLI_fopen(name, "r");
@@ -549,6 +594,9 @@ LinkNode *BLI_file_read_as_lines(const char *name)
char *line = BLI_strdupn(&buf[last], i - last);
BLI_linklist_prepend(&lines, line);
+ /* faster to build singly-linked list in reverse order */
+ /* alternatively, could process buffer in reverse order so
+ * list ends up right way round to start with */
last = i + 1;
}
}
@@ -557,18 +605,22 @@ LinkNode *BLI_file_read_as_lines(const char *name)
}
fclose(fp);
-
+
+ /* get them the right way round */
BLI_linklist_reverse(&lines);
return lines;
}
+/*
+ * Frees memory from a previous call to BLI_file_read_as_lines.
+ */
void BLI_file_free_lines(LinkNode *lines)
{
- BLI_linklist_free(lines, (void (*)(void *))MEM_freeN);
+ BLI_linklist_freeN(lines);
}
/** is file1 older then file2 */
-int BLI_file_older(const char *file1, const char *file2)
+bool BLI_file_older(const char *file1, const char *file2)
{
#ifdef WIN32
struct _stat st1, st2;
@@ -576,16 +628,16 @@ int BLI_file_older(const char *file1, const char *file2)
UTF16_ENCODE(file1);
UTF16_ENCODE(file2);
- if (_wstat(file1_16, &st1)) return 0;
- if (_wstat(file2_16, &st2)) return 0;
+ if (_wstat(file1_16, &st1)) return false;
+ if (_wstat(file2_16, &st2)) return false;
UTF16_UN_ENCODE(file2);
UTF16_UN_ENCODE(file1);
#else
struct stat st1, st2;
- if (stat(file1, &st1)) return 0;
- if (stat(file2, &st2)) return 0;
+ if (stat(file1, &st1)) return false;
+ if (stat(file2, &st2)) return false;
#endif
return (st1.st_mtime < st2.st_mtime);
}
diff --git a/source/blender/blenlib/intern/string.c b/source/blender/blenlib/intern/string.c
index 3500f3f1805..906a3095f91 100644
--- a/source/blender/blenlib/intern/string.c
+++ b/source/blender/blenlib/intern/string.c
@@ -43,6 +43,15 @@
#include "BLI_utildefines.h"
+/**
+ * Duplicates the first \a len bytes of cstring \a str
+ * into a newly mallocN'd string and returns it. \a str
+ * is assumed to be at least len bytes long.
+ *
+ * \param str The string to be duplicated
+ * \param len The number of bytes to duplicate
+ * \retval Returns the duplicated string
+ */
char *BLI_strdupn(const char *str, const size_t len)
{
char *n = MEM_mallocN(len + 1, "strdup");
@@ -51,11 +60,25 @@ char *BLI_strdupn(const char *str, const size_t len)
return n;
}
+
+/**
+ * Duplicates the cstring \a str into a newly mallocN'd
+ * string and returns it.
+ *
+ * \param str The string to be duplicated
+ * \retval Returns the duplicated string
+ */
char *BLI_strdup(const char *str)
{
return BLI_strdupn(str, strlen(str));
}
+/**
+ * Appends the two strings, and returns new mallocN'ed string
+ * \param str1 first string for copy
+ * \param str2 second string for append
+ * \retval Returns dst
+ */
char *BLI_strdupcat(const char *__restrict str1, const char *__restrict str2)
{
size_t len;
@@ -69,18 +92,52 @@ char *BLI_strdupcat(const char *__restrict str1, const char *__restrict str2)
return n;
}
+/**
+ * Like strncpy but ensures dst is always
+ * '\0' terminated.
+ *
+ * \param dst Destination for copy
+ * \param src Source string to copy
+ * \param maxncpy Maximum number of characters to copy (generally
+ * the size of dst)
+ * \retval Returns dst
+ */
char *BLI_strncpy(char *__restrict dst, const char *__restrict src, const size_t maxncpy)
{
- size_t srclen = strlen(src);
- size_t cpylen = (srclen > (maxncpy - 1)) ? (maxncpy - 1) : srclen;
+ size_t srclen = BLI_strnlen(src, maxncpy - 1);
BLI_assert(maxncpy != 0);
-
- memcpy(dst, src, cpylen);
- dst[cpylen] = '\0';
-
+
+ memcpy(dst, src, srclen);
+ dst[srclen] = '\0';
return dst;
}
+/**
+ * Like strncpy but ensures dst is always
+ * '\0' terminated.
+ *
+ * \note This is a duplicate of #BLI_strncpy that returns bytes copied.
+ * And is a drop in replacement for 'snprintf(str, sizeof(str), "%s", arg);'
+ *
+ * \param dst Destination for copy
+ * \param src Source string to copy
+ * \param maxncpy Maximum number of characters to copy (generally
+ * the size of dst)
+ * \retval The number of bytes copied (The only difference from BLI_strncpy).
+ */
+size_t BLI_strncpy_rlen(char *__restrict dst, const char *__restrict src, const size_t maxncpy)
+{
+ size_t srclen = BLI_strnlen(src, maxncpy - 1);
+ BLI_assert(maxncpy != 0);
+
+ memcpy(dst, src, srclen);
+ dst[srclen] = '\0';
+ return srclen;
+}
+
+/**
+ * Portable replacement for #vsnprintf
+ */
size_t BLI_vsnprintf(char *__restrict buffer, size_t count, const char *__restrict format, va_list arg)
{
size_t n;
@@ -101,6 +158,9 @@ size_t BLI_vsnprintf(char *__restrict buffer, size_t count, const char *__restri
return n;
}
+/**
+ * Portable replacement for #snprintf
+ */
size_t BLI_snprintf(char *__restrict buffer, size_t count, const char *__restrict format, ...)
{
size_t n;
@@ -113,6 +173,10 @@ size_t BLI_snprintf(char *__restrict buffer, size_t count, const char *__restric
return n;
}
+/**
+ * Print formatted string into a newly #MEM_mallocN'd string
+ * and return it.
+ */
char *BLI_sprintfN(const char *__restrict format, ...)
{
DynStr *ds;
@@ -180,17 +244,17 @@ escape_finish:
return len;
}
-
-/* Makes a copy of the text within the "" that appear after some text 'blahblah'
+/**
+ * Makes a copy of the text within the "" that appear after some text 'blahblah'
* i.e. for string 'pose["apples"]' with prefix 'pose[', it should grab "apples"
- *
- * - str: is the entire string to chop
- * - prefix: is the part of the string to leave out
*
- * Assume that the strings returned must be freed afterwards, and that the inputs will contain
+ * - str: is the entire string to chop
+ * - prefix: is the part of the string to leave out
+ *
+ * Assume that the strings returned must be freed afterwards, and that the inputs will contain
* data we want...
*
- * TODO, return the offset and a length so as to avoid doing an allocation.
+ * \return the offset and a length so as to avoid doing an allocation.
*/
char *BLI_str_quoted_substrN(const char *__restrict str, const char *__restrict prefix)
{
@@ -210,12 +274,19 @@ char *BLI_str_quoted_substrN(const char *__restrict str, const char *__restrict
return BLI_strdupn("", 0);
}
-/* Replaces all occurrences of oldText with newText in str, returning a new string that doesn't
- * contain the 'replaced' occurrences.
+/**
+ * Returns a copy of the cstring \a str into a newly mallocN'd
+ * string with all instances of oldText replaced with newText,
+ * and returns it.
+ *
+ * \note A rather wasteful string-replacement utility, though this shall do for now...
+ * Feel free to replace this with an even safe + nicer alternative
+ *
+ * \param str The string to replace occurrences of oldText in
+ * \param oldText The text in the string to find and replace
+ * \param newText The text in the string to find and replace
+ * \retval Returns the duplicated string
*/
-
-/* A rather wasteful string-replacement utility, though this shall do for now...
- * Feel free to replace this with an even safe + nicer alternative */
char *BLI_replacestr(char *__restrict str, const char *__restrict oldText, const char *__restrict newText)
{
DynStr *ds = NULL;
@@ -282,12 +353,19 @@ char *BLI_replacestr(char *__restrict str, const char *__restrict oldText, const
}
}
+/**
+ * Compare two strings without regard to case.
+ *
+ * \retval True if the strings are equal, false otherwise.
+ */
int BLI_strcaseeq(const char *a, const char *b)
{
return (BLI_strcasecmp(a, b) == 0);
}
-/* strcasestr not available in MSVC */
+/**
+ * Portable replacement for #strcasestr (not available in MSVC)
+ */
char *BLI_strcasestr(const char *s, const char *find)
{
register char c, sc;
@@ -431,10 +509,15 @@ void BLI_timestr(double _time, char *str)
}
/* determine the length of a fixed-size string */
-size_t BLI_strnlen(const char *str, const size_t maxlen)
+size_t BLI_strnlen(const char *s, size_t maxlen)
{
- const char *end = memchr(str, '\0', maxlen);
- return end ? (size_t) (end - str) : maxlen;
+ size_t len;
+
+ for (len = 0; len < maxlen; len++, s++) {
+ if (!*s)
+ break;
+ }
+ return len;
}
void BLI_ascii_strtolower(char *str, const size_t len)
@@ -454,3 +537,31 @@ void BLI_ascii_strtoupper(char *str, const size_t len)
if (str[i] >= 'a' && str[i] <= 'z')
str[i] -= 'a' - 'A';
}
+
+/**
+ * Strip trailing zeros from a float, eg:
+ * 0.0000 -> 0.0
+ * 2.0010 -> 2.001
+ *
+ * \param str
+ * \param len
+ * \return The number of zeto's stripped.
+ */
+int BLI_str_rstrip_float_zero(char *str, const char pad)
+{
+ char *p = strchr(str, '.');
+ int totstrip = 0;
+ if (p) {
+ char *end_p;
+ p++; /* position at first decimal place */
+ end_p = p + (strlen(p) - 1); /* position at last character */
+ if (end_p > p) {
+ while (end_p != p && *end_p == '0') {
+ *end_p = pad;
+ end_p--;
+ }
+ }
+ }
+
+ return totstrip;
+}
diff --git a/source/blender/blenlib/intern/string_utf8.c b/source/blender/blenlib/intern/string_utf8.c
index 26235de4dd2..fe8f3c20ab4 100644
--- a/source/blender/blenlib/intern/string_utf8.c
+++ b/source/blender/blenlib/intern/string_utf8.c
@@ -33,6 +33,7 @@
#include <string.h>
#include <wchar.h>
#include <wctype.h>
+#include <wcwidth.h>
#include <stdio.h>
#include <stdlib.h>
@@ -317,6 +318,42 @@ size_t BLI_strncpy_wchar_from_utf8(wchar_t *__restrict dst_w, const char *__rest
/* end wchar_t / utf8 functions */
/* --------------------------------------------------------------------------*/
+/* count columns that character/string occupies, based on wcwidth.c */
+
+int BLI_wcwidth(wchar_t ucs)
+{
+ return mk_wcwidth(ucs);
+}
+
+int BLI_wcswidth(const wchar_t *pwcs, size_t n)
+{
+ return mk_wcswidth(pwcs, n);
+}
+
+int BLI_str_utf8_char_width(const char *p)
+{
+ unsigned int unicode = BLI_str_utf8_as_unicode(p);
+ if (unicode == BLI_UTF8_ERR)
+ return -1;
+
+ return BLI_wcwidth((wchar_t)unicode);
+}
+
+int BLI_str_utf8_char_width_safe(const char *p)
+{
+ int columns;
+
+ unsigned int unicode = BLI_str_utf8_as_unicode(p);
+ if (unicode == BLI_UTF8_ERR)
+ return 1;
+
+ columns = BLI_wcwidth((wchar_t)unicode);
+
+ return (columns < 0) ? 1 : columns;
+}
+
+/* --------------------------------------------------------------------------*/
+
/* copied from glib's gutf8.c, added 'Err' arg */
/* note, glib uses unsigned int for unicode, best we do the same,
diff --git a/source/blender/blenlib/intern/winstuff.c b/source/blender/blenlib/intern/winstuff.c
index 65fb490b218..d11bee255c2 100644
--- a/source/blender/blenlib/intern/winstuff.c
+++ b/source/blender/blenlib/intern/winstuff.c
@@ -38,8 +38,6 @@
#include <conio.h>
#include "MEM_guardedalloc.h"
-#include "BLI_path_util.h"
-#include "BLI_string.h"
#include "../blenkernel/BKE_global.h" /* G.background, bad level include (no function calls) */
@@ -47,6 +45,7 @@
#include "BLI_winstuff.h"
#include "BLI_utildefines.h"
#include "BLI_path_util.h"
+#include "BLI_string.h"
#include "utf_winfunc.h"
#include "utfconv.h"
@@ -141,7 +140,7 @@ void RegisterBlendExtension(void)
lresult = RegCreateKeyEx(root, ".blend", 0,
NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hkey, &dwd);
if (lresult == ERROR_SUCCESS) {
- sprintf(buffer, "%s", "blendfile");
+ strcpy(buffer, "blendfile");
lresult = RegSetValueEx(hkey, NULL, 0, REG_SZ, (BYTE *)buffer, strlen(buffer) + 1);
RegCloseKey(hkey);
}
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index 4bd8f82562c..5834e2b9927 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -381,7 +381,7 @@ static void *oldnewmap_liblookup(OldNewMap *onm, void *addr, void *lib)
for (i = 0, entry = onm->entries; i < nentries; i++, entry++) {
if (entry->old == addr) {
- ID *id = id = entry->newp;
+ ID *id = entry->newp;
if (id && (!lib || id->lib)) {
return id;
}
@@ -496,16 +496,6 @@ void blo_split_main(ListBase *mainlist, Main *main)
split_libdata(lbarray[i], main->next);
}
-/* removes things like /blah/blah/../../blah/ etc, then writes in *name the full path */
-static void cleanup_path(const char *relabase, char *name)
-{
- char filename[FILE_MAXFILE];
-
- BLI_splitdirstring(name, filename);
- BLI_cleanup_dir(relabase, name);
- strcat(name, filename);
-}
-
static void read_file_version(FileData *fd, Main *main)
{
BHead *bhead;
@@ -534,7 +524,7 @@ static Main *blo_find_main(FileData *fd, const char *filepath, const char *relab
char name1[FILE_MAX];
BLI_strncpy(name1, filepath, sizeof(name1));
- cleanup_path(relabase, name1);
+ BLI_cleanup_path(relabase, name1);
// printf("blo_find_main: relabase %s\n", relabase);
// printf("blo_find_main: original in %s\n", filepath);
@@ -1178,7 +1168,7 @@ int BLO_is_a_library(const char *path, char *dir, char *group)
dir[len - 1] = '\0';
/* Find the last slash */
- fd = BLI_last_slash(dir);
+ fd = (char *)BLI_last_slash(dir);
if (fd == NULL) return 0;
*fd = 0;
@@ -1187,10 +1177,10 @@ int BLO_is_a_library(const char *path, char *dir, char *group)
*fd = '/'; /* put back the removed slash separating the dir and the .blend file name */
}
else {
- char *gp = fd + 1; // in case we have a .blend file, gp points to the group
+ const char * const gp = fd + 1; // in case we have a .blend file, gp points to the group
/* Find the last slash */
- fd = BLI_last_slash(dir);
+ fd = (char *)BLI_last_slash(dir);
if (!fd || !BLO_has_bfile_extension(fd+1)) return 0;
/* now we know that we are in a blend file and it is safe to
@@ -3259,7 +3249,9 @@ static void direct_link_curve(FileData *fd, Curve *cu)
cu->strinfo= newdataadr(fd, cu->strinfo);
cu->tb = newdataadr(fd, cu->tb);
- if (cu->vfont == NULL) link_list(fd, &(cu->nurb));
+ if (cu->vfont == NULL) {
+ link_list(fd, &(cu->nurb));
+ }
else {
cu->nurb.first=cu->nurb.last= NULL;
@@ -3839,8 +3831,10 @@ static void lib_link_mesh(FileData *fd, Main *main)
me->mat[i] = newlibadr_us(fd, me->id.lib, me->mat[i]);
}
}
- else me->totcol = 0;
-
+ else {
+ me->totcol = 0;
+ }
+
me->ipo = newlibadr_us(fd, me->id.lib, me->ipo); // XXX: deprecated: old anim sys
me->key = newlibadr_us(fd, me->id.lib, me->key);
me->texcomesh = newlibadr_us(fd, me->id.lib, me->texcomesh);
@@ -5345,8 +5339,9 @@ static void direct_link_scene(FileData *fd, Scene *sce)
/* link cache */
direct_link_pointcache_list(fd, &rbw->ptcaches, &rbw->pointcache, FALSE);
/* make sure simulation starts from the beginning after loading file */
- if (rbw->pointcache)
- rbw->ltime = rbw->pointcache->startframe;
+ if (rbw->pointcache) {
+ rbw->ltime = (float)rbw->pointcache->startframe;
+ }
}
}
@@ -5750,7 +5745,9 @@ void blo_lib_link_screen_restore(Main *newmain, bScreen *curscreen, Scene *cursc
}
#endif
}
- else if (v3d->scenelock) v3d->lay = sc->scene->lay;
+ else if (v3d->scenelock) {
+ v3d->lay = sc->scene->lay;
+ }
/* not very nice, but could help */
if ((v3d->layact & v3d->lay) == 0) v3d->layact = v3d->lay;
@@ -5946,6 +5943,7 @@ static void direct_link_region(FileData *fd, ARegion *ar, int spacetype)
rv3d->clipbb = newdataadr(fd, rv3d->clipbb);
rv3d->depths = NULL;
+ rv3d->gpuoffscreen = NULL;
rv3d->ri = NULL;
rv3d->render_engine = NULL;
rv3d->sms = NULL;
@@ -6111,7 +6109,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;
+ soops->tree.first = soops->tree.last= NULL;
}
else if (sl->spacetype == SPACE_IMAGE) {
SpaceImage *sima = (SpaceImage *)sl;
@@ -6282,7 +6280,7 @@ static void direct_link_library(FileData *fd, Library *lib, Main *main)
}
/* make sure we have full path in lib->filepath */
BLI_strncpy(lib->filepath, lib->name, sizeof(lib->name));
- cleanup_path(fd->relabase, lib->filepath);
+ BLI_cleanup_path(fd->relabase, lib->filepath);
// printf("direct_link_library: name %s\n", lib->name);
// printf("direct_link_library: filepath %s\n", lib->filepath);
@@ -7647,6 +7645,21 @@ static void do_versions_affine_tracker_track(MovieTrackingTrack *track)
}
}
+/* initialize userdef with non-UI dependency stuff */
+/* other initializers (such as theme color defaults) go to resources.c */
+static void do_versions_userdef(FileData *fd, BlendFileData *bfd)
+{
+ Main *bmain = bfd->main;
+ UserDef *user = bfd->user;
+
+ if (user == NULL) return;
+
+ if (bmain->versionfile < 267) {
+
+ if (!DNA_struct_elem_find(fd->filesdna, "UserDef", "short", "image_gpubuffer_limit"))
+ user->image_gpubuffer_limit = 10;
+ }
+}
static void do_versions(FileData *fd, Library *lib, Main *main)
{
@@ -8872,8 +8885,8 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
if (main->versionfile < 265 || (main->versionfile == 265 && main->subversionfile < 5)) {
Scene *scene;
- Image *image, *nimage;
- Tex *tex, *otex;
+ Image *image;
+ Tex *tex;
bNodeTreeType *ntreetype;
bNodeTree *ntree;
@@ -8920,67 +8933,17 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
else {
BKE_image_alpha_mode_from_extension(image);
}
-
- image->flag &= ~IMA_DONE_TAG;
}
- /* use alpha flag moved from texture to image datablock */
for (tex = main->tex.first; tex; tex = tex->id.next) {
if (tex->type == TEX_IMAGE && (tex->imaflag & TEX_USEALPHA) == 0) {
image = blo_do_versions_newlibadr(fd, tex->id.lib, tex->ima);
- /* skip if no image or already tested */
- if (!image || (image->flag & (IMA_DONE_TAG|IMA_IGNORE_ALPHA)))
- continue;
-
- image->flag |= IMA_DONE_TAG;
-
- /* we might have some textures using alpha and others not, so we check if
- * they exist and duplicate the image datablock if necessary */
- for (otex = main->tex.first; otex; otex = otex->id.next)
- if (otex->type == TEX_IMAGE && (otex->imaflag & TEX_USEALPHA))
- if (image == blo_do_versions_newlibadr(fd, otex->id.lib, otex->ima))
- break;
-
- /* no duplication if the texture and image datablock are not
- * from the same .blend file, the image datablock may not have
- * been loaded from a library file otherwise */
- if (otex && (tex->id.lib == image->id.lib)) {
- /* copy image datablock */
- nimage = BKE_image_copy(main, image);
- nimage->flag |= IMA_IGNORE_ALPHA|IMA_DONE_TAG;
- nimage->id.us--;
-
- /* we need to do some trickery to make file loading think
- * this new datablock is part of file we're loading */
- blo_do_versions_oldnewmap_insert(fd->libmap, nimage, nimage, 0);
- nimage->id.lib = image->id.lib;
- nimage->id.flag |= (image->id.flag & LIB_NEED_LINK);
-
- /* assign new image, and update the users counts accordingly */
- for (otex = main->tex.first; otex; otex = otex->id.next) {
- if (otex->type == TEX_IMAGE && (otex->imaflag & TEX_USEALPHA) == 0) {
- if (image == blo_do_versions_newlibadr(fd, otex->id.lib, otex->ima)) {
- if (!(otex->id.flag & LIB_NEED_LINK)) {
- image->id.us--;
- nimage->id.us++;
- }
- otex->ima = nimage;
- break;
- }
- }
- }
- }
- else {
- /* no other textures using alpha, just set the flag */
+ if (image && (image->flag & IMA_DO_PREMUL) == 0)
image->flag |= IMA_IGNORE_ALPHA;
- }
}
}
- for (image = main->image.first; image; image = image->id.next)
- image->flag &= ~IMA_DONE_TAG;
-
ntreetype = ntreeGetType(NTREE_COMPOSIT);
if (ntreetype && ntreetype->foreach_nodetree)
ntreetype->foreach_nodetree(main, fd, do_version_node_straight_image_alpha_workaround);
@@ -8988,6 +8951,15 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
for (ntree = main->nodetree.first; ntree; ntree = ntree->id.next)
do_version_node_straight_image_alpha_workaround(fd, NULL, ntree);
}
+ else if (main->versionfile < 266 || (main->versionfile == 266 && main->subversionfile < 1)) {
+ /* texture use alpha was removed for 2.66 but added back again for 2.66a,
+ * for compatibility all textures assumed it to be enabled */
+ Tex *tex;
+
+ for (tex = main->tex.first; tex; tex = tex->id.next)
+ if (tex->type == TEX_IMAGE)
+ tex->imaflag |= TEX_USEALPHA;
+ }
if (main->versionfile < 265 || (main->versionfile == 265 && main->subversionfile < 7)) {
Curve *cu;
@@ -9024,14 +8996,14 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
}
}
- if (!MAIN_VERSION_ATLEAST(main, 265, 8)) {
+ if (MAIN_VERSION_OLDER(main, 265, 9)) {
Mesh *me;
for (me = main->mesh.first; me; me = me->id.next) {
BKE_mesh_do_versions_cd_flag_init(me);
}
}
- if (!MAIN_VERSION_ATLEAST(main, 265, 9)) {
+ if (MAIN_VERSION_OLDER(main, 265, 10)) {
Brush *br;
for (br = main->brush.first; br; br = br->id.next) {
if (br->ob_mode & OB_MODE_TEXTURE_PAINT) {
@@ -9041,7 +9013,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
}
// add storage for compositor translate nodes when not existing
- if (!MAIN_VERSION_ATLEAST(main, 265, 10)) {
+ if (MAIN_VERSION_OLDER(main, 265, 11)) {
bNodeTreeType *ntreetype;
bNodeTree *ntree;
@@ -9053,8 +9025,17 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
do_version_node_fix_translate_wrapping(NULL, NULL, ntree);
}
- // if (main->versionfile < 265 || (main->versionfile == 265 && main->subversionfile < 7)) {
-
+ if (main->versionfile < 267) {
+
+ /* TIP: to initialize new variables added, use the new function
+ DNA_struct_elem_find(fd->filesdna, "structname", "typename", "varname")
+ example:
+ if (!DNA_struct_elem_find(fd->filesdna, "UserDef", "short", "image_gpubuffer_limit"))
+ user->image_gpubuffer_limit = 10;
+ */
+
+ }
+
#ifdef WITH_FREESTYLE
/* default values in Freestyle settings */
{
@@ -9155,7 +9136,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
#endif
/* 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! */
+ /* WATCH IT 2!: Userdef struct init see do_versions_userdef() above! */
/* don't forget to set version number in blender.c! */
}
@@ -9355,9 +9336,11 @@ BlendFileData *blo_read_file_internal(FileData *fd, const char *filepath)
}
/* do before read_libraries, but skip undo case */
-// if (fd->memfile==NULL) (the mesh shuffle hacks don't work yet? ton)
+ if (fd->memfile==NULL)
do_versions(fd, NULL, bfd->main);
+ do_versions_userdef(fd, bfd);
+
read_libraries(fd, &mainlist);
blo_join_main(&mainlist);
@@ -10806,7 +10789,7 @@ static void read_libraries(FileData *basefd, ListBase *mainlist)
PackedFile *pf = mainptr->curlib->packedfile;
BKE_reportf_wrap(basefd->reports, RPT_INFO, TIP_("Read packed library: '%s'"),
- mainptr->curlib->name);
+ mainptr->curlib->name);
fd = blo_openblendermemory(pf->data, pf->size, basefd->reports);
@@ -10814,9 +10797,9 @@ static void read_libraries(FileData *basefd, ListBase *mainlist)
BLI_strncpy(fd->relabase, mainptr->curlib->filepath, sizeof(fd->relabase));
}
else {
- BKE_reportf_wrap(basefd->reports, RPT_INFO, TIP_("Read library: '%s', '%s'"),
- mainptr->curlib->filepath, mainptr->curlib->name);
- fd = blo_openblenderfile(mainptr->curlib->filepath, basefd->reports);
+ BKE_reportf_wrap(basefd->reports, RPT_INFO, TIP_("Read library: '%s', '%s'"),
+ mainptr->curlib->filepath, mainptr->curlib->name);
+ fd = blo_openblenderfile(mainptr->curlib->filepath, basefd->reports);
}
/* allow typing in a new lib path */
if (G.debug_value == -666) {
@@ -10831,7 +10814,7 @@ static void read_libraries(FileData *basefd, ListBase *mainlist)
if (scanf("%s", newlib_path) > 0) {
BLI_strncpy(mainptr->curlib->name, newlib_path, sizeof(mainptr->curlib->name));
BLI_strncpy(mainptr->curlib->filepath, newlib_path, sizeof(mainptr->curlib->filepath));
- cleanup_path(G.main->name, mainptr->curlib->filepath);
+ BLI_cleanup_path(G.main->name, mainptr->curlib->filepath);
fd = blo_openblenderfile(mainptr->curlib->filepath, basefd->reports);
@@ -10863,7 +10846,9 @@ static void read_libraries(FileData *basefd, ListBase *mainlist)
/* subversion */
read_file_version(fd, mainptr);
}
- else mainptr->curlib->filedata = NULL;
+ else {
+ mainptr->curlib->filedata = NULL;
+ }
if (fd == NULL) {
BKE_reportf_wrap(basefd->reports, RPT_WARNING, TIP_("Cannot find lib '%s'"),
diff --git a/source/blender/blenloader/intern/versioning_250.c b/source/blender/blenloader/intern/versioning_250.c
index f4d841fd22a..36f3ea3654c 100644
--- a/source/blender/blenloader/intern/versioning_250.c
+++ b/source/blender/blenloader/intern/versioning_250.c
@@ -480,7 +480,7 @@ static void versions_gpencil_add_main(ListBase *lb, ID *id, const char *name)
*( (short *)id->name )= ID_GD;
new_id(lb, id, name);
- /* alphabetic insterion: is in new_id */
+ /* alphabetic insertion: is in new_id */
if (G.debug & G_DEBUG)
printf("Converted GPencil to ID: %s\n", id->name + 2);
diff --git a/source/blender/blenloader/intern/versioning_legacy.c b/source/blender/blenloader/intern/versioning_legacy.c
index 65a60e11ab3..0fba8c4b2ab 100644
--- a/source/blender/blenloader/intern/versioning_legacy.c
+++ b/source/blender/blenloader/intern/versioning_legacy.c
@@ -1547,7 +1547,9 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *main)
else if (sbuts->mainb == BUTS_EDIT) {
sbuts->mainb = CONTEXT_EDITING;
}
- else sbuts->mainb = CONTEXT_SCENE;
+ else {
+ sbuts->mainb = CONTEXT_SCENE;
+ }
}
}
}
@@ -2550,7 +2552,7 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *main)
if (main->subversionfile < 4) {
for (sce = main->scene.first; sce; sce = sce->id.next) {
sce->r.bake_mode = 1; /* prevent to include render stuff here */
- sce->r.bake_filter = 2;
+ sce->r.bake_filter = 16;
sce->r.bake_osa = 5;
sce->r.bake_flag = R_BAKE_CLEAR;
}
diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c
index 50e1e229eba..f9b8fbaca53 100644
--- a/source/blender/blenloader/intern/writefile.c
+++ b/source/blender/blenloader/intern/writefile.c
@@ -383,6 +383,17 @@ static void writedata(WriteData *wd, int filecode, int len, const void *adr) /*
if (len) mywrite(wd, adr, len);
}
+/* use this to force writing of lists in same order as reading (using link_list) */
+static void writelist(WriteData *wd, int filecode, const char *structname, ListBase *lb)
+{
+ Link *link = lb->first;
+
+ while (link) {
+ writestruct(wd, filecode, structname, 1, link);
+ link = link->next;
+ }
+}
+
/* *************** writing some direct data structs used in more code parts **************** */
/*These functions are used by blender's .blend system for file saving/loading.*/
void IDP_WriteProperty_OnlyData(IDProperty *prop, void *wd);
@@ -462,6 +473,9 @@ static void write_fmodifiers(WriteData *wd, ListBase *fmodifiers)
{
FModifier *fcm;
+ /* Write all modifiers first (for faster reloading) */
+ writelist(wd, DATA, "FModifier", fmodifiers);
+
/* Modifiers */
for (fcm= fmodifiers->first; fcm; fcm= fcm->next) {
FModifierTypeInfo *fmi= fmodifier_get_typeinfo(fcm);
@@ -502,9 +516,6 @@ static void write_fmodifiers(WriteData *wd, ListBase *fmodifiers)
break;
}
}
-
- /* Write the modifier */
- writestruct(wd, DATA, "FModifier", 1, fcm);
}
}
@@ -512,10 +523,8 @@ static void write_fcurves(WriteData *wd, ListBase *fcurves)
{
FCurve *fcu;
+ writelist(wd, DATA, "FCurve", fcurves);
for (fcu=fcurves->first; fcu; fcu=fcu->next) {
- /* F-Curve */
- writestruct(wd, DATA, "FCurve", 1, fcu);
-
/* curve data */
if (fcu->bezt)
writestruct(wd, DATA, "BezTriple", fcu->totvert, fcu->bezt);
@@ -533,9 +542,8 @@ static void write_fcurves(WriteData *wd, ListBase *fcurves)
writestruct(wd, DATA, "ChannelDriver", 1, driver);
/* variables */
- for (dvar= driver->variables.first; dvar; dvar= dvar->next) {
- writestruct(wd, DATA, "DriverVar", 1, dvar);
-
+ writelist(wd, DATA, "DriverVar", &driver->variables);
+ for (dvar= driver->variables.first; dvar; dvar= dvar->next) {
DRIVER_TARGETS_USED_LOOPER(dvar)
{
if (dtar->rna_path)
@@ -601,10 +609,8 @@ static void write_nlastrips(WriteData *wd, ListBase *strips)
{
NlaStrip *strip;
+ writelist(wd, DATA, "NlaStrip", strips);
for (strip= strips->first; strip; strip= strip->next) {
- /* write the strip first */
- writestruct(wd, DATA, "NlaStrip", 1, strip);
-
/* write the strip's F-Curves and modifiers */
write_fcurves(wd, &strip->fcurves);
write_fmodifiers(wd, &strip->modifiers);
@@ -801,14 +807,15 @@ typedef struct RenderInfo {
static void write_renderinfo(WriteData *wd, Main *mainvar)
{
bScreen *curscreen;
- Scene *sce;
+ Scene *sce, *curscene = NULL;
RenderInfo data;
/* XXX in future, handle multiple windows with multiple screens? */
current_screen_compat(mainvar, &curscreen);
-
+ if (curscreen) curscene = curscreen->scene;
+
for (sce= mainvar->scene.first; sce; sce= sce->id.next) {
- if (sce->id.lib == NULL && (sce == curscreen->scene || (sce->r.scemode & R_BG_RENDER))) {
+ if (sce->id.lib == NULL && (sce == curscene || (sce->r.scemode & R_BG_RENDER))) {
data.sfra = sce->r.sfra;
data.efra = sce->r.efra;
memset(data.scene_name, 0, sizeof(data.scene_name));
@@ -2354,16 +2361,16 @@ static void write_gpencils(WriteData *wd, ListBase *lb)
writestruct(wd, ID_GD, "bGPdata", 1, gpd);
/* write grease-pencil layers to file */
+ writelist(wd, DATA, "bGPDlayer", &gpd->layers);
for (gpl= gpd->layers.first; gpl; gpl= gpl->next) {
- writestruct(wd, DATA, "bGPDlayer", 1, gpl);
/* write this layer's frames to file */
+ writelist(wd, DATA, "bGPDframe", &gpl->frames);
for (gpf= gpl->frames.first; gpf; gpf= gpf->next) {
- writestruct(wd, DATA, "bGPDframe", 1, gpf);
/* write strokes */
+ writelist(wd, DATA, "bGPDstroke", &gpf->strokes);
for (gps= gpf->strokes.first; gps; gps= gps->next) {
- writestruct(wd, DATA, "bGPDstroke", 1, gps);
writestruct(wd, DATA, "bGPDspoint", gps->totpoints, gps->points);
}
}
@@ -2594,7 +2601,7 @@ static void write_libraries(WriteData *wd, Main *main)
/* to be able to restore quit.blend and temp saves, the packed blend has to be in undo buffers... */
/* XXX needs rethink, just like save UI in undo files now - would be nice to append things only for the]
- quit.blend and temp saves */
+ * quit.blend and temp saves */
if (foundone) {
writestruct(wd, ID_LI, "Library", 1, main->curlib);
@@ -3386,7 +3393,7 @@ int BLO_write_file(Main *mainvar, const char *filepath, int write_flags, ReportL
return 0;
}
- BLI_delete(tempname, 0, 0);
+ BLI_delete(tempname, false, false);
}
else if (-1==ret) {
BKE_report(reports, RPT_ERROR, "Failed opening .gz file");
diff --git a/source/blender/bmesh/CMakeLists.txt b/source/blender/bmesh/CMakeLists.txt
index bf719a5c790..c3ec5dd83b3 100644
--- a/source/blender/bmesh/CMakeLists.txt
+++ b/source/blender/bmesh/CMakeLists.txt
@@ -57,7 +57,6 @@ set(SRC
operators/bmo_smooth_laplacian.c
operators/bmo_symmetrize.c
operators/bmo_subdivide.c
- operators/bmo_subdivide.h
operators/bmo_triangulate.c
operators/bmo_unsubdivide.c
operators/bmo_utils.c
diff --git a/source/blender/bmesh/SConscript b/source/blender/bmesh/SConscript
index fa6bdbcf26f..de839f7f6a6 100644
--- a/source/blender/bmesh/SConscript
+++ b/source/blender/bmesh/SConscript
@@ -34,16 +34,16 @@ sources += env.Glob('operators/*.c')
sources += env.Glob('tools/*.c')
incs = [
- './',
- '../blenfont',
- '../blenlib',
- '../makesdna',
- '../blenkernel',
- '#/intern/guardedalloc',
- '#/extern/bullet2/src',
- '#/extern/rangetree',
- '#/intern/opennl/extern'
- ]
+ './',
+ '../blenfont',
+ '../blenlib',
+ '../makesdna',
+ '../blenkernel',
+ '#/intern/guardedalloc',
+ '#/extern/bullet2/src',
+ '#/extern/rangetree',
+ '#/intern/opennl/extern'
+ ]
defs = []
diff --git a/source/blender/bmesh/bmesh_class.h b/source/blender/bmesh/bmesh_class.h
index 6dc0218da93..845785a26d7 100644
--- a/source/blender/bmesh/bmesh_class.h
+++ b/source/blender/bmesh/bmesh_class.h
@@ -252,6 +252,9 @@ enum {
* not have functions clobber them */
};
+struct BPy_BMGeneric;
+extern void bpy_bm_generic_invalidate(struct BPy_BMGeneric *self);
+
/* defines */
#define BM_ELEM_CD_GET_VOID_P(ele, offset) \
(assert(offset != -1), (void *)((char *)(ele)->head.data + (offset)))
diff --git a/source/blender/bmesh/intern/bmesh_core.c b/source/blender/bmesh/intern/bmesh_core.c
index 643e73e02b4..a11d45a7a5a 100644
--- a/source/blender/bmesh/intern/bmesh_core.c
+++ b/source/blender/bmesh/intern/bmesh_core.c
@@ -942,7 +942,7 @@ static bool disk_is_flagged(BMVert *v, int flag)
*/
BMFace *BM_faces_join(BMesh *bm, BMFace **faces, int totface, const bool do_del)
{
- BMFace *f, *newf;
+ BMFace *f, *f_new;
#ifdef USE_BMESH_HOLES
BMLoopList *lst;
ListBase holes = {NULL, NULL};
@@ -1036,15 +1036,15 @@ BMFace *BM_faces_join(BMesh *bm, BMFace **faces, int totface, const bool do_del)
}
/* create region face */
- newf = tote ? BM_face_create_ngon(bm, v1, v2, edges, tote, 0) : NULL;
- if (UNLIKELY(!newf || BMO_error_occurred(bm))) {
+ f_new = tote ? BM_face_create_ngon(bm, v1, v2, edges, tote, 0) : NULL;
+ if (UNLIKELY(!f_new || BMO_error_occurred(bm))) {
if (!BMO_error_occurred(bm))
err = N_("Invalid boundary region to join faces");
goto error;
}
/* copy over loop data */
- l_iter = l_first = BM_FACE_FIRST_LOOP(newf);
+ l_iter = l_first = BM_FACE_FIRST_LOOP(f_new);
do {
BMLoop *l2 = l_iter->radial_next;
@@ -1064,34 +1064,34 @@ BMFace *BM_faces_join(BMesh *bm, BMFace **faces, int totface, const bool do_del)
}
} while ((l_iter = l_iter->next) != l_first);
- BM_elem_attrs_copy(bm, bm, faces[0], newf);
+ BM_elem_attrs_copy(bm, bm, faces[0], f_new);
#ifdef USE_BMESH_HOLES
/* add holes */
- BLI_movelisttolist(&newf->loops, &holes);
+ BLI_movelisttolist(&f_new->loops, &holes);
#endif
/* update loop face pointer */
#ifdef USE_BMESH_HOLES
- for (lst = newf->loops.first; lst; lst = lst->next)
+ for (lst = f_new->loops.first; lst; lst = lst->next)
#endif
{
#ifdef USE_BMESH_HOLES
l_iter = l_first = lst->first;
#else
- l_iter = l_first = BM_FACE_FIRST_LOOP(newf);
+ l_iter = l_first = BM_FACE_FIRST_LOOP(f_new);
#endif
do {
- l_iter->f = newf;
+ l_iter->f = f_new;
} while ((l_iter = l_iter->next) != l_first);
}
bm_elements_systag_disable(faces, totface, _FLAG_JF);
- BM_ELEM_API_FLAG_DISABLE(newf, _FLAG_JF);
+ BM_ELEM_API_FLAG_DISABLE(f_new, _FLAG_JF);
/* handle multi-res data */
if (CustomData_has_layer(&bm->ldata, CD_MDISPS)) {
- l_iter = l_first = BM_FACE_FIRST_LOOP(newf);
+ l_iter = l_first = BM_FACE_FIRST_LOOP(f_new);
do {
for (i = 0; i < totface; i++) {
BM_loop_interp_multires(bm, l_iter, faces[i]);
@@ -1120,8 +1120,8 @@ BMFace *BM_faces_join(BMesh *bm, BMFace **faces, int totface, const bool do_del)
BLI_array_free(deledges);
BLI_array_free(delverts);
- BM_CHECK_ELEMENT(newf);
- return newf;
+ BM_CHECK_ELEMENT(f_new);
+ return f_new;
error:
bm_elements_systag_disable(faces, totface, _FLAG_JF);
@@ -1210,18 +1210,18 @@ BMFace *bmesh_sfme(BMesh *bm, BMFace *f, BMVert *v1, BMVert *v2,
BMFace *f2;
BMLoop *l_iter, *l_first;
- BMLoop *v1loop = NULL, *v2loop = NULL, *f1loop = NULL, *f2loop = NULL;
+ BMLoop *l_v1 = NULL, *l_v2 = NULL, *l_f1 = NULL, *l_f2 = NULL;
BMEdge *e;
int i, len, f1len, f2len;
/* verify that v1 and v2 are in face */
len = f->len;
for (i = 0, l_iter = BM_FACE_FIRST_LOOP(f); i < len; i++, l_iter = l_iter->next) {
- if (l_iter->v == v1) v1loop = l_iter;
- else if (l_iter->v == v2) v2loop = l_iter;
+ if (l_iter->v == v1) l_v1 = l_iter;
+ else if (l_iter->v == v2) l_v2 = l_iter;
}
- if (!v1loop || !v2loop) {
+ if (!l_v1 || !l_v2) {
return NULL;
}
@@ -1229,28 +1229,28 @@ BMFace *bmesh_sfme(BMesh *bm, BMFace *f, BMVert *v1, BMVert *v2,
e = BM_edge_create(bm, v1, v2, example, no_double ? BM_CREATE_NO_DOUBLE : 0);
f2 = bm_face_create__sfme(bm, f);
- f1loop = bm_loop_create(bm, v2, e, f, v2loop, 0);
- f2loop = bm_loop_create(bm, v1, e, f2, v1loop, 0);
+ l_f1 = bm_loop_create(bm, v2, e, f, l_v2, 0);
+ l_f2 = bm_loop_create(bm, v1, e, f2, l_v1, 0);
- f1loop->prev = v2loop->prev;
- f2loop->prev = v1loop->prev;
- v2loop->prev->next = f1loop;
- v1loop->prev->next = f2loop;
+ l_f1->prev = l_v2->prev;
+ l_f2->prev = l_v1->prev;
+ l_v2->prev->next = l_f1;
+ l_v1->prev->next = l_f2;
- f1loop->next = v1loop;
- f2loop->next = v2loop;
- v1loop->prev = f1loop;
- v2loop->prev = f2loop;
+ l_f1->next = l_v1;
+ l_f2->next = l_v2;
+ l_v1->prev = l_f1;
+ l_v2->prev = l_f2;
#ifdef USE_BMESH_HOLES
lst = f->loops.first;
lst2 = f2->loops.first;
- lst2->first = lst2->last = f2loop;
- lst->first = lst->last = f1loop;
+ lst2->first = lst2->last = l_f2;
+ lst->first = lst->last = l_f1;
#else
/* find which of the faces the original first loop is in */
- l_iter = l_first = f1loop;
+ l_iter = l_first = l_f1;
first_loop_f1 = 0;
do {
if (l_iter == f->l_first)
@@ -1261,23 +1261,23 @@ BMFace *bmesh_sfme(BMesh *bm, BMFace *f, BMVert *v1, BMVert *v2,
/* original first loop was in f1, find a suitable first loop for f2
* which is as similar as possible to f1. the order matters for tools
* such as duplifaces. */
- if (f->l_first->prev == f1loop)
- f2->l_first = f2loop->prev;
- else if (f->l_first->next == f1loop)
- f2->l_first = f2loop->next;
+ if (f->l_first->prev == l_f1)
+ f2->l_first = l_f2->prev;
+ else if (f->l_first->next == l_f1)
+ f2->l_first = l_f2->next;
else
- f2->l_first = f2loop;
+ f2->l_first = l_f2;
}
else {
/* original first loop was in f2, further do same as above */
f2->l_first = f->l_first;
- if (f->l_first->prev == f2loop)
- f->l_first = f1loop->prev;
- else if (f->l_first->next == f2loop)
- f->l_first = f1loop->next;
+ if (f->l_first->prev == l_f2)
+ f->l_first = l_f1->prev;
+ else if (f->l_first->next == l_f2)
+ f->l_first = l_f1->next;
else
- f->l_first = f1loop;
+ f->l_first = l_f1;
}
#endif
@@ -1293,8 +1293,8 @@ BMFace *bmesh_sfme(BMesh *bm, BMFace *f, BMVert *v1, BMVert *v2,
} while ((l_iter = l_iter->next) != l_first);
/* link up the new loops into the new edges radial */
- bmesh_radial_append(e, f1loop);
- bmesh_radial_append(e, f2loop);
+ bmesh_radial_append(e, l_f1);
+ bmesh_radial_append(e, l_f2);
f2->len = f2len;
@@ -1306,7 +1306,7 @@ BMFace *bmesh_sfme(BMesh *bm, BMFace *f, BMVert *v1, BMVert *v2,
f->len = f1len;
- if (r_l) *r_l = f2loop;
+ if (r_l) *r_l = l_f2;
#ifdef USE_BMESH_HOLES
if (holes) {
@@ -1349,77 +1349,77 @@ BMFace *bmesh_sfme(BMesh *bm, BMFace *f, BMVert *v1, BMVert *v2,
*/
BMVert *bmesh_semv(BMesh *bm, BMVert *tv, BMEdge *e, BMEdge **r_e)
{
- BMLoop *nextl;
- BMEdge *ne;
- BMVert *nv, *ov;
+ BMLoop *l_next;
+ BMEdge *e_new;
+ BMVert *v_new, *v_old;
int i, valence1 = 0, valence2 = 0;
bool edok;
BLI_assert(bmesh_vert_in_edge(e, tv) != false);
- ov = bmesh_edge_other_vert_get(e, tv);
+ v_old = bmesh_edge_other_vert_get(e, tv);
- valence1 = bmesh_disk_count(ov);
+ valence1 = bmesh_disk_count(v_old);
valence2 = bmesh_disk_count(tv);
- nv = BM_vert_create(bm, tv->co, tv, 0);
- ne = BM_edge_create(bm, nv, tv, e, 0);
+ v_new = BM_vert_create(bm, tv->co, tv, 0);
+ e_new = BM_edge_create(bm, v_new, tv, e, 0);
- bmesh_disk_edge_remove(ne, tv);
- bmesh_disk_edge_remove(ne, nv);
+ bmesh_disk_edge_remove(e_new, tv);
+ bmesh_disk_edge_remove(e_new, v_new);
/* remove e from tv's disk cycle */
bmesh_disk_edge_remove(e, tv);
- /* swap out tv for nv in e */
- bmesh_edge_swapverts(e, tv, nv);
+ /* swap out tv for v_new in e */
+ bmesh_edge_swapverts(e, tv, v_new);
- /* add e to nv's disk cycle */
- bmesh_disk_edge_append(e, nv);
+ /* add e to v_new's disk cycle */
+ bmesh_disk_edge_append(e, v_new);
- /* add ne to nv's disk cycle */
- bmesh_disk_edge_append(ne, nv);
+ /* add e_new to v_new's disk cycle */
+ bmesh_disk_edge_append(e_new, v_new);
- /* add ne to tv's disk cycle */
- bmesh_disk_edge_append(ne, tv);
+ /* add e_new to tv's disk cycle */
+ bmesh_disk_edge_append(e_new, tv);
/* verify disk cycles */
- edok = bmesh_disk_validate(valence1, ov->e, ov);
+ edok = bmesh_disk_validate(valence1, v_old->e, v_old);
BMESH_ASSERT(edok != false);
edok = bmesh_disk_validate(valence2, tv->e, tv);
BMESH_ASSERT(edok != false);
- edok = bmesh_disk_validate(2, nv->e, nv);
+ edok = bmesh_disk_validate(2, v_new->e, v_new);
BMESH_ASSERT(edok != false);
/* Split the radial cycle if present */
- nextl = e->l;
+ l_next = e->l;
e->l = NULL;
- if (nextl) {
- BMLoop *nl, *l;
- int radlen = bmesh_radial_length(nextl);
+ if (l_next) {
+ BMLoop *l_new, *l;
+ int radlen = bmesh_radial_length(l_next);
int first1 = 0, first2 = 0;
/* Take the next loop. Remove it from radial. Split it. Append to appropriate radials */
- while (nextl) {
- l = nextl;
+ while (l_next) {
+ l = l_next;
l->f->len++;
- nextl = nextl != nextl->radial_next ? nextl->radial_next : NULL;
+ l_next = l_next != l_next->radial_next ? l_next->radial_next : NULL;
bmesh_radial_loop_remove(l, NULL);
- nl = bm_loop_create(bm, NULL, NULL, l->f, l, 0);
- nl->prev = l;
- nl->next = (l->next);
- nl->prev->next = nl;
- nl->next->prev = nl;
- nl->v = nv;
+ l_new = bm_loop_create(bm, NULL, NULL, l->f, l, 0);
+ l_new->prev = l;
+ l_new->next = (l->next);
+ l_new->prev->next = l_new;
+ l_new->next->prev = l_new;
+ l_new->v = v_new;
/* assign the correct edge to the correct loop */
- if (bmesh_verts_in_edge(nl->v, nl->next->v, e)) {
- nl->e = e;
- l->e = ne;
+ if (bmesh_verts_in_edge(l_new->v, l_new->next->v, e)) {
+ l_new->e = e;
+ l->e = e_new;
- /* append l into ne's rad cycle */
+ /* append l into e_new's rad cycle */
if (!first1) {
first1 = 1;
l->radial_next = l->radial_prev = NULL;
@@ -1430,14 +1430,14 @@ BMVert *bmesh_semv(BMesh *bm, BMVert *tv, BMEdge *e, BMEdge **r_e)
l->radial_next = l->radial_prev = NULL;
}
- bmesh_radial_append(nl->e, nl);
+ bmesh_radial_append(l_new->e, l_new);
bmesh_radial_append(l->e, l);
}
- else if (bmesh_verts_in_edge(nl->v, nl->next->v, ne)) {
- nl->e = ne;
+ else if (bmesh_verts_in_edge(l_new->v, l_new->next->v, e_new)) {
+ l_new->e = e_new;
l->e = e;
- /* append l into ne's rad cycle */
+ /* append l into e_new's rad cycle */
if (!first1) {
first1 = 1;
l->radial_next = l->radial_prev = NULL;
@@ -1448,7 +1448,7 @@ BMVert *bmesh_semv(BMesh *bm, BMVert *tv, BMEdge *e, BMEdge **r_e)
l->radial_next = l->radial_prev = NULL;
}
- bmesh_radial_append(nl->e, nl);
+ bmesh_radial_append(l_new->e, l_new);
bmesh_radial_append(l->e, l);
}
@@ -1457,14 +1457,14 @@ BMVert *bmesh_semv(BMesh *bm, BMVert *tv, BMEdge *e, BMEdge **r_e)
/* verify length of radial cycle */
edok = bmesh_radial_validate(radlen, e->l);
BMESH_ASSERT(edok != false);
- edok = bmesh_radial_validate(radlen, ne->l);
+ edok = bmesh_radial_validate(radlen, e_new->l);
BMESH_ASSERT(edok != false);
/* verify loop->v and loop->next->v pointers for e */
for (i = 0, l = e->l; i < radlen; i++, l = l->radial_next) {
BMESH_ASSERT(l->e == e);
//BMESH_ASSERT(l->radial_next == l);
- BMESH_ASSERT(!(l->prev->e != ne && l->next->e != ne));
+ BMESH_ASSERT(!(l->prev->e != e_new && l->next->e != e_new));
edok = bmesh_verts_in_edge(l->v, l->next->v, e);
BMESH_ASSERT(edok != false);
@@ -1477,12 +1477,12 @@ BMVert *bmesh_semv(BMesh *bm, BMVert *tv, BMEdge *e, BMEdge **r_e)
BM_CHECK_ELEMENT(l->e);
BM_CHECK_ELEMENT(l->f);
}
- /* verify loop->v and loop->next->v pointers for ne */
- for (i = 0, l = ne->l; i < radlen; i++, l = l->radial_next) {
- BMESH_ASSERT(l->e == ne);
+ /* verify loop->v and loop->next->v pointers for e_new */
+ for (i = 0, l = e_new->l; i < radlen; i++, l = l->radial_next) {
+ BMESH_ASSERT(l->e == e_new);
// BMESH_ASSERT(l->radial_next == l);
BMESH_ASSERT(!(l->prev->e != e && l->next->e != e));
- edok = bmesh_verts_in_edge(l->v, l->next->v, ne);
+ edok = bmesh_verts_in_edge(l->v, l->next->v, e_new);
BMESH_ASSERT(edok != false);
BMESH_ASSERT(l->v != l->next->v);
BMESH_ASSERT(l->e != l->next->e);
@@ -1494,20 +1494,20 @@ BMVert *bmesh_semv(BMesh *bm, BMVert *tv, BMEdge *e, BMEdge **r_e)
}
}
- BM_CHECK_ELEMENT(ne);
- BM_CHECK_ELEMENT(nv);
- BM_CHECK_ELEMENT(ov);
+ BM_CHECK_ELEMENT(e_new);
+ BM_CHECK_ELEMENT(v_new);
+ BM_CHECK_ELEMENT(v_old);
BM_CHECK_ELEMENT(e);
BM_CHECK_ELEMENT(tv);
- if (r_e) *r_e = ne;
- return nv;
+ if (r_e) *r_e = e_new;
+ return v_new;
}
/**
* \brief Join Edge Kill Vert (JEKV)
*
- * Takes an edge \a ke and pointer to one of its vertices \a kv
+ * Takes an edge \a e_kill and pointer to one of its vertices \a v_kill
* and collapses the edge on that vertex.
*
* \par Examples:
@@ -1535,25 +1535,25 @@ BMVert *bmesh_semv(BMesh *bm, BMVert *tv, BMEdge *e, BMEdge **r_e)
* faces with just 2 edges. It is up to the caller to decide what to do with
* these faces.
*/
-BMEdge *bmesh_jekv(BMesh *bm, BMEdge *ke, BMVert *kv, const bool check_edge_double)
+BMEdge *bmesh_jekv(BMesh *bm, BMEdge *e_kill, BMVert *v_kill, const bool check_edge_double)
{
- BMEdge *oe;
- BMVert *ov, *tv;
- BMLoop *killoop, *l;
+ BMEdge *e_old;
+ BMVert *v_old, *tv;
+ BMLoop *l_kill, *l;
int len, radlen = 0, i, valence1, valence2;
bool edok, halt = false;
- if (bmesh_vert_in_edge(ke, kv) == 0) {
+ if (bmesh_vert_in_edge(e_kill, v_kill) == 0) {
return NULL;
}
- len = bmesh_disk_count(kv);
+ len = bmesh_disk_count(v_kill);
if (len == 2) {
- 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 edges */
+ e_old = bmesh_disk_edge_next(e_kill, v_kill);
+ tv = bmesh_edge_other_vert_get(e_kill, v_kill);
+ v_old = bmesh_edge_other_vert_get(e_old, v_kill);
+ halt = bmesh_verts_in_edge(v_kill, tv, e_old); /* check for double edges */
if (halt) {
return NULL;
@@ -1561,56 +1561,56 @@ BMEdge *bmesh_jekv(BMesh *bm, BMEdge *ke, BMVert *kv, const bool check_edge_doub
else {
BMEdge *e_splice;
- /* For verification later, count valence of ov and tv */
- valence1 = bmesh_disk_count(ov);
+ /* For verification later, count valence of v_old and tv */
+ valence1 = bmesh_disk_count(v_old);
valence2 = bmesh_disk_count(tv);
if (check_edge_double) {
- e_splice = BM_edge_exists(tv, ov);
+ e_splice = BM_edge_exists(tv, v_old);
}
- /* remove oe from kv's disk cycle */
- bmesh_disk_edge_remove(oe, kv);
- /* relink oe->kv to be oe->tv */
- bmesh_edge_swapverts(oe, kv, tv);
- /* append oe to tv's disk cycle */
- bmesh_disk_edge_append(oe, tv);
- /* remove ke from tv's disk cycle */
- bmesh_disk_edge_remove(ke, tv);
-
- /* deal with radial cycle of ke */
- radlen = bmesh_radial_length(ke->l);
- if (ke->l) {
- /* first step, fix the neighboring loops of all loops in ke's radial cycle */
- for (i = 0, killoop = ke->l; i < radlen; i++, killoop = killoop->radial_next) {
+ /* remove e_old from v_kill's disk cycle */
+ bmesh_disk_edge_remove(e_old, v_kill);
+ /* relink e_old->v_kill to be e_old->tv */
+ bmesh_edge_swapverts(e_old, v_kill, tv);
+ /* append e_old to tv's disk cycle */
+ bmesh_disk_edge_append(e_old, tv);
+ /* remove e_kill from tv's disk cycle */
+ bmesh_disk_edge_remove(e_kill, tv);
+
+ /* deal with radial cycle of e_kill */
+ radlen = bmesh_radial_length(e_kill->l);
+ if (e_kill->l) {
+ /* first step, fix the neighboring loops of all loops in e_kill's radial cycle */
+ for (i = 0, l_kill = e_kill->l; i < radlen; i++, l_kill = l_kill->radial_next) {
/* relink loops and fix vertex pointer */
- if (killoop->next->v == kv) {
- killoop->next->v = tv;
+ if (l_kill->next->v == v_kill) {
+ l_kill->next->v = tv;
}
- killoop->next->prev = killoop->prev;
- killoop->prev->next = killoop->next;
- if (BM_FACE_FIRST_LOOP(killoop->f) == killoop) {
- BM_FACE_FIRST_LOOP(killoop->f) = killoop->next;
+ l_kill->next->prev = l_kill->prev;
+ l_kill->prev->next = l_kill->next;
+ if (BM_FACE_FIRST_LOOP(l_kill->f) == l_kill) {
+ BM_FACE_FIRST_LOOP(l_kill->f) = l_kill->next;
}
- killoop->next = NULL;
- killoop->prev = NULL;
+ l_kill->next = NULL;
+ l_kill->prev = NULL;
/* fix len attribute of face */
- killoop->f->len--;
+ l_kill->f->len--;
}
- /* second step, remove all the hanging loops attached to ke */
- radlen = bmesh_radial_length(ke->l);
+ /* second step, remove all the hanging loops attached to e_kill */
+ radlen = bmesh_radial_length(e_kill->l);
if (LIKELY(radlen)) {
BMLoop **loops = BLI_array_alloca(loops, radlen);
- killoop = ke->l;
+ l_kill = e_kill->l;
/* this should be wrapped into a bme_free_radial function to be used by bmesh_KF as well... */
for (i = 0; i < radlen; i++) {
- loops[i] = killoop;
- killoop = killoop->radial_next;
+ loops[i] = l_kill;
+ l_kill = l_kill->radial_next;
}
for (i = 0; i < radlen; i++) {
bm->totloop--;
@@ -1618,27 +1618,27 @@ BMEdge *bmesh_jekv(BMesh *bm, BMEdge *ke, BMVert *kv, const bool check_edge_doub
}
}
- /* Validate radial cycle of oe */
- edok = bmesh_radial_validate(radlen, oe->l);
+ /* Validate radial cycle of e_old */
+ edok = bmesh_radial_validate(radlen, e_old->l);
BMESH_ASSERT(edok != false);
}
/* deallocate edge */
- bm_kill_only_edge(bm, ke);
+ bm_kill_only_edge(bm, e_kill);
/* deallocate vertex */
- bm_kill_only_vert(bm, kv);
+ bm_kill_only_vert(bm, v_kill);
- /* Validate disk cycle lengths of ov, tv are unchanged */
- edok = bmesh_disk_validate(valence1, ov->e, ov);
+ /* Validate disk cycle lengths of v_old, tv are unchanged */
+ edok = bmesh_disk_validate(valence1, v_old->e, v_old);
BMESH_ASSERT(edok != false);
edok = bmesh_disk_validate(valence2, tv->e, tv);
BMESH_ASSERT(edok != false);
- /* Validate loop cycle of all faces attached to 'oe' */
- for (i = 0, l = oe->l; i < radlen; i++, l = l->radial_next) {
- BMESH_ASSERT(l->e == oe);
- edok = bmesh_verts_in_edge(l->v, l->next->v, oe);
+ /* Validate loop cycle of all faces attached to 'e_old' */
+ for (i = 0, l = e_old->l; i < radlen; i++, l = l->radial_next) {
+ BMESH_ASSERT(l->e == e_old);
+ edok = bmesh_verts_in_edge(l->v, l->next->v, e_old);
BMESH_ASSERT(edok != false);
edok = bmesh_loop_validate(l->f);
BMESH_ASSERT(edok != false);
@@ -1652,15 +1652,15 @@ BMEdge *bmesh_jekv(BMesh *bm, BMEdge *ke, BMVert *kv, const bool check_edge_doub
if (check_edge_double) {
if (e_splice) {
/* removes e_splice */
- BM_edge_splice(bm, e_splice, oe);
+ BM_edge_splice(bm, e_splice, e_old);
}
}
- BM_CHECK_ELEMENT(ov);
+ BM_CHECK_ELEMENT(v_old);
BM_CHECK_ELEMENT(tv);
- BM_CHECK_ELEMENT(oe);
+ BM_CHECK_ELEMENT(e_old);
- return oe;
+ return e_old;
}
}
return NULL;
@@ -1699,9 +1699,9 @@ BMEdge *bmesh_jekv(BMesh *bm, BMEdge *ke, BMVert *kv, const bool check_edge_doub
*/
BMFace *bmesh_jfke(BMesh *bm, BMFace *f1, BMFace *f2, BMEdge *e)
{
- BMLoop *l_iter, *f1loop = NULL, *f2loop = NULL;
- int newlen = 0, i, f1len = 0, f2len = 0, edok;
-
+ BMLoop *l_iter, *l_f1 = NULL, *l_f2 = NULL;
+ int newlen = 0, i, f1len = 0, f2len = 0;
+ bool edok;
/* can't join a face to itself */
if (f1 == f2) {
return NULL;
@@ -1716,23 +1716,23 @@ BMFace *bmesh_jfke(BMesh *bm, BMFace *f1, BMFace *f2, BMEdge *e)
f1len = f1->len;
f2len = f2->len;
- if (!((f1loop = BM_face_edge_share_loop(f1, e)) &&
- (f2loop = BM_face_edge_share_loop(f2, e))))
+ if (!((l_f1 = BM_face_edge_share_loop(f1, e)) &&
+ (l_f2 = BM_face_edge_share_loop(f2, e))))
{
return NULL;
}
/* validate direction of f2's loop cycle is compatible */
- if (f1loop->v == f2loop->v) {
+ if (l_f1->v == l_f2->v) {
return NULL;
}
/* validate that for each face, each vertex has another edge in its disk cycle that is
* not e, and not shared. */
- if (bmesh_radial_face_find(f1loop->next->e, f2) ||
- bmesh_radial_face_find(f1loop->prev->e, f2) ||
- bmesh_radial_face_find(f2loop->next->e, f1) ||
- bmesh_radial_face_find(f2loop->prev->e, f1) )
+ if (bmesh_radial_face_find(l_f1->next->e, f2) ||
+ bmesh_radial_face_find(l_f1->prev->e, f2) ||
+ bmesh_radial_face_find(l_f2->next->e, f1) ||
+ bmesh_radial_face_find(l_f2->prev->e, f1) )
{
return NULL;
}
@@ -1751,12 +1751,12 @@ BMFace *bmesh_jfke(BMesh *bm, BMFace *f1, BMFace *f2, BMEdge *e)
}
for (i = 0, l_iter = BM_FACE_FIRST_LOOP(f1); i < f1len; i++, l_iter = l_iter->next) {
- if (l_iter != f1loop) {
+ if (l_iter != l_f1) {
BM_elem_flag_enable(l_iter->v, BM_ELEM_INTERNAL_TAG);
}
}
for (i = 0, l_iter = BM_FACE_FIRST_LOOP(f2); i < f2len; i++, l_iter = l_iter->next) {
- if (l_iter != f2loop) {
+ if (l_iter != l_f2) {
/* as soon as a duplicate is found, bail out */
if (BM_elem_flag_test(l_iter->v, BM_ELEM_INTERNAL_TAG)) {
return NULL;
@@ -1765,15 +1765,15 @@ BMFace *bmesh_jfke(BMesh *bm, BMFace *f1, BMFace *f2, BMEdge *e)
}
/* join the two loop */
- f1loop->prev->next = f2loop->next;
- f2loop->next->prev = f1loop->prev;
+ l_f1->prev->next = l_f2->next;
+ l_f2->next->prev = l_f1->prev;
- f1loop->next->prev = f2loop->prev;
- f2loop->prev->next = f1loop->next;
+ l_f1->next->prev = l_f2->prev;
+ l_f2->prev->next = l_f1->next;
- /* if f1loop was baseloop, make f1loop->next the base. */
- if (BM_FACE_FIRST_LOOP(f1) == f1loop)
- BM_FACE_FIRST_LOOP(f1) = f1loop->next;
+ /* if l_f1 was baseloop, make l_f1->next the base. */
+ if (BM_FACE_FIRST_LOOP(f1) == l_f1)
+ BM_FACE_FIRST_LOOP(f1) = l_f1->next;
/* increase length of f1 */
f1->len += (f2->len - 2);
@@ -1784,18 +1784,18 @@ BMFace *bmesh_jfke(BMesh *bm, BMFace *f1, BMFace *f2, BMEdge *e)
l_iter->f = f1;
/* remove edge from the disk cycle of its two vertices */
- bmesh_disk_edge_remove(f1loop->e, f1loop->e->v1);
- bmesh_disk_edge_remove(f1loop->e, f1loop->e->v2);
+ bmesh_disk_edge_remove(l_f1->e, l_f1->e->v1);
+ bmesh_disk_edge_remove(l_f1->e, l_f1->e->v2);
/* deallocate edge and its two loops as well as f2 */
if (bm->etoolflagpool) {
- BLI_mempool_free(bm->etoolflagpool, f1loop->e->oflags);
+ BLI_mempool_free(bm->etoolflagpool, l_f1->e->oflags);
}
- BLI_mempool_free(bm->epool, f1loop->e);
+ BLI_mempool_free(bm->epool, l_f1->e);
bm->totedge--;
- BLI_mempool_free(bm->lpool, f1loop);
+ BLI_mempool_free(bm->lpool, l_f1);
bm->totloop--;
- BLI_mempool_free(bm->lpool, f2loop);
+ BLI_mempool_free(bm->lpool, l_f2);
bm->totloop--;
if (bm->ftoolflagpool) {
BLI_mempool_free(bm->ftoolflagpool, f2->oflags);
@@ -1889,7 +1889,7 @@ bool bmesh_vert_separate(BMesh *bm, BMVert *v, BMVert ***r_vout, int *r_vout_len
BMLoop *l;
BMEdge *e;
int i, maxindex;
- BMLoop *nl;
+ BMLoop *l_new;
visithash = BLI_ghash_ptr_new(__func__);
@@ -1908,9 +1908,9 @@ bool bmesh_vert_separate(BMesh *bm, BMVert *v, BMVert ***r_vout, int *r_vout_len
BLI_ghash_insert(visithash, e, SET_INT_IN_POINTER(maxindex));
BM_ITER_ELEM (l, &liter, e, BM_LOOPS_OF_EDGE) {
- nl = (l->v == v) ? l->prev : l->next;
- if (!BLI_ghash_haskey(visithash, nl->e)) {
- BLI_array_append(stack, nl->e);
+ l_new = (l->v == v) ? l->prev : l->next;
+ if (!BLI_ghash_haskey(visithash, l_new->e)) {
+ BLI_array_append(stack, l_new->e);
}
}
}
@@ -2072,7 +2072,7 @@ bool BM_edge_splice(BMesh *bm, BMEdge *e, BMEdge *e_target)
*/
bool bmesh_edge_separate(BMesh *bm, BMEdge *e, BMLoop *l_sep)
{
- BMEdge *ne;
+ BMEdge *e_new;
int radlen;
BLI_assert(l_sep->e == e);
@@ -2088,15 +2088,15 @@ bool bmesh_edge_separate(BMesh *bm, BMEdge *e, BMLoop *l_sep)
e->l = l_sep->radial_next;
}
- ne = BM_edge_create(bm, e->v1, e->v2, e, 0);
+ e_new = BM_edge_create(bm, e->v1, e->v2, e, 0);
bmesh_radial_loop_remove(l_sep, e);
- bmesh_radial_append(ne, l_sep);
- l_sep->e = ne;
+ bmesh_radial_append(e_new, l_sep);
+ l_sep->e = e_new;
BLI_assert(bmesh_radial_length(e->l) == radlen - 1);
- BLI_assert(bmesh_radial_length(ne->l) == 1);
+ BLI_assert(bmesh_radial_length(e_new->l) == 1);
- BM_CHECK_ELEMENT(ne);
+ BM_CHECK_ELEMENT(e_new);
BM_CHECK_ELEMENT(e);
return true;
@@ -2105,57 +2105,57 @@ bool bmesh_edge_separate(BMesh *bm, BMEdge *e, BMLoop *l_sep)
/**
* \brief Un-glue Region Make Vert (URMV)
*
- * Disconnects a face from its vertex fan at loop \a sl
+ * Disconnects a face from its vertex fan at loop \a l_sep
*
* \return The newly created BMVert
*/
-BMVert *bmesh_urmv_loop(BMesh *bm, BMLoop *sl)
+BMVert *bmesh_urmv_loop(BMesh *bm, BMLoop *l_sep)
{
BMVert **vtar;
int len, i;
- BMVert *nv = NULL;
- BMVert *sv = sl->v;
+ BMVert *v_new = NULL;
+ BMVert *v_sep = l_sep->v;
/* peel the face from the edge radials on both sides of the
* loop vert, disconnecting the face from its fan */
- bmesh_edge_separate(bm, sl->e, sl);
- bmesh_edge_separate(bm, sl->prev->e, sl->prev);
+ bmesh_edge_separate(bm, l_sep->e, l_sep);
+ bmesh_edge_separate(bm, l_sep->prev->e, l_sep->prev);
- if (bmesh_disk_count(sv) == 2) {
- /* If there are still only two edges out of sv, then
+ if (bmesh_disk_count(v_sep) == 2) {
+ /* If there are still only two edges out of v_sep, then
* this whole URMV was just a no-op, so exit now. */
- return sv;
+ return v_sep;
}
/* Update the disk start, so that v->e points to an edge
* not touching the split loop. This is so that BM_vert_split
- * will leave the original sv on some *other* fan (not the
+ * will leave the original v_sep on some *other* fan (not the
* one-face fan that holds the unglue face). */
- while (sv->e == sl->e || sv->e == sl->prev->e) {
- sv->e = bmesh_disk_edge_next(sv->e, sv);
+ while (v_sep->e == l_sep->e || v_sep->e == l_sep->prev->e) {
+ v_sep->e = bmesh_disk_edge_next(v_sep->e, v_sep);
}
/* Split all fans connected to the vert, duplicating it for
* each fans. */
- bmesh_vert_separate(bm, sv, &vtar, &len);
+ bmesh_vert_separate(bm, v_sep, &vtar, &len);
/* There should have been at least two fans cut apart here,
* otherwise the early exit would have kicked in. */
BLI_assert(len >= 2);
- nv = sl->v;
+ v_new = l_sep->v;
/* Desired result here is that a new vert should always be
* created for the unglue face. This is so we can glue any
* extras back into the original vert. */
- BLI_assert(nv != sv);
- BLI_assert(sv == vtar[0]);
+ BLI_assert(v_new != v_sep);
+ BLI_assert(v_sep == vtar[0]);
/* If there are more than two verts as a result, glue together
* all the verts except the one this URMV intended to create */
if (len > 2) {
for (i = 0; i < len; i++) {
- if (vtar[i] == nv) {
+ if (vtar[i] == v_new) {
break;
}
}
@@ -2174,18 +2174,18 @@ BMVert *bmesh_urmv_loop(BMesh *bm, BMLoop *sl)
MEM_freeN(vtar);
- return nv;
+ return v_new;
}
/**
* \brief Unglue Region Make Vert (URMV)
*
- * Disconnects sf from the vertex fan at \a sv
+ * Disconnects f_sep from the vertex fan at \a v_sep
*
* \return The newly created BMVert
*/
-BMVert *bmesh_urmv(BMesh *bm, BMFace *sf, BMVert *sv)
+BMVert *bmesh_urmv(BMesh *bm, BMFace *f_sep, BMVert *v_sep)
{
- BMLoop *l = BM_face_vert_share_loop(sf, sv);
+ BMLoop *l = BM_face_vert_share_loop(f_sep, v_sep);
return bmesh_urmv_loop(bm, l);
}
diff --git a/source/blender/bmesh/intern/bmesh_core.h b/source/blender/bmesh/intern/bmesh_core.h
index d8cfc973394..a1f378aaa5d 100644
--- a/source/blender/bmesh/intern/bmesh_core.h
+++ b/source/blender/bmesh/intern/bmesh_core.h
@@ -73,9 +73,9 @@ BMFace *bmesh_sfme(BMesh *bm, BMFace *f, BMVert *v1,
);
BMVert *bmesh_semv(BMesh *bm, BMVert *tv, BMEdge *e, BMEdge **r_e);
-BMEdge *bmesh_jekv(BMesh *bm, BMEdge *ke, BMVert *kv, const bool check_edge_splice);
+BMEdge *bmesh_jekv(BMesh *bm, BMEdge *e_kill, BMVert *v_kill, const bool check_edge_splice);
BMFace *bmesh_jfke(BMesh *bm, BMFace *f1, BMFace *f2, BMEdge *e);
-BMVert *bmesh_urmv(BMesh *bm, BMFace *sf, BMVert *sv);
-BMVert *bmesh_urmv_loop(BMesh *bm, BMLoop *sl);
+BMVert *bmesh_urmv(BMesh *bm, BMFace *f_sep, BMVert *v_sep);
+BMVert *bmesh_urmv_loop(BMesh *bm, BMLoop *l_sep);
#endif /* __BMESH_CORE_H__ */
diff --git a/source/blender/bmesh/intern/bmesh_interp.c b/source/blender/bmesh/intern/bmesh_interp.c
index 44b8baace4c..d0ab0ea5d60 100644
--- a/source/blender/bmesh/intern/bmesh_interp.c
+++ b/source/blender/bmesh/intern/bmesh_interp.c
@@ -126,7 +126,7 @@ void BM_data_interp_face_vert_edge(BMesh *bm, BMVert *v1, BMVert *UNUSED(v2), BM
{
void *src[2];
float w[2];
- BMLoop *v1loop = NULL, *vloop = NULL, *v2loop = NULL;
+ BMLoop *l_v1 = NULL, *l_v = NULL, *l_v2 = NULL;
BMLoop *l_iter = NULL;
if (!e1->l) {
@@ -139,23 +139,23 @@ void BM_data_interp_face_vert_edge(BMesh *bm, BMVert *v1, BMVert *UNUSED(v2), BM
l_iter = e1->l;
do {
if (l_iter->v == v1) {
- v1loop = l_iter;
- vloop = v1loop->next;
- v2loop = vloop->next;
+ l_v1 = l_iter;
+ l_v = l_v1->next;
+ l_v2 = l_v->next;
}
else if (l_iter->v == v) {
- v1loop = l_iter->next;
- vloop = l_iter;
- v2loop = l_iter->prev;
+ l_v1 = l_iter->next;
+ l_v = l_iter;
+ l_v2 = l_iter->prev;
}
- if (!v1loop || !v2loop)
+ if (!l_v1 || !l_v2)
return;
- src[0] = v1loop->head.data;
- src[1] = v2loop->head.data;
+ src[0] = l_v1->head.data;
+ src[1] = l_v2->head.data;
- CustomData_bmesh_interp(&bm->ldata, src, w, NULL, 2, vloop->head.data);
+ CustomData_bmesh_interp(&bm->ldata, src, w, NULL, 2, l_v->head.data);
} while ((l_iter = l_iter->radial_next) != e1->l);
}
diff --git a/source/blender/bmesh/intern/bmesh_log.c b/source/blender/bmesh/intern/bmesh_log.c
index 36a5412e401..c7be4424a21 100644
--- a/source/blender/bmesh/intern/bmesh_log.c
+++ b/source/blender/bmesh/intern/bmesh_log.c
@@ -20,11 +20,11 @@
#include "MEM_guardedalloc.h"
+#include "BLI_utildefines.h"
#include "BLI_ghash.h"
#include "BLI_listbase.h"
#include "BLI_math.h"
#include "BLI_mempool.h"
-#include "BLI_utildefines.h"
#include "BKE_customdata.h"
diff --git a/source/blender/bmesh/intern/bmesh_mesh.c b/source/blender/bmesh/intern/bmesh_mesh.c
index 3c4fa490477..b9352a25063 100644
--- a/source/blender/bmesh/intern/bmesh_mesh.c
+++ b/source/blender/bmesh/intern/bmesh_mesh.c
@@ -247,8 +247,6 @@ void BM_mesh_free(BMesh *bm)
if (bm->py_handle) {
/* keep this out of 'BM_mesh_data_free' because we want python
* to be able to clear the mesh and maintain access. */
- extern void bpy_bm_generic_invalidate(void *self);
-
bpy_bm_generic_invalidate(bm->py_handle);
bm->py_handle = NULL;
}
diff --git a/source/blender/bmesh/intern/bmesh_mesh_conv.c b/source/blender/bmesh/intern/bmesh_mesh_conv.c
index 4c0c1507dbf..e0c8cb61900 100644
--- a/source/blender/bmesh/intern/bmesh_mesh_conv.c
+++ b/source/blender/bmesh/intern/bmesh_mesh_conv.c
@@ -782,7 +782,9 @@ void BM_mesh_bm_to_me(BMesh *bm, Mesh *me, bool do_tessface)
hmd->indexar[j++] = BM_elem_index_get(eve);
}
}
- else j++;
+ else {
+ j++;
+ }
}
hmd->totindex = j;
diff --git a/source/blender/bmesh/intern/bmesh_mods.c b/source/blender/bmesh/intern/bmesh_mods.c
index d98598cac89..afb3fc8112c 100644
--- a/source/blender/bmesh/intern/bmesh_mods.c
+++ b/source/blender/bmesh/intern/bmesh_mods.c
@@ -300,14 +300,14 @@ BMEdge *BM_verts_connect(BMesh *bm, BMVert *v1, BMVert *v2, BMFace **r_f)
BM_ITER_ELEM (f_iter, &fiter, v1, BM_FACES_OF_VERT) {
BM_ITER_ELEM (v_iter, &viter, f_iter, BM_FACES_OF_VERT) {
if (v_iter == v2) {
- BMLoop *nl;
+ BMLoop *l_new;
- f_iter = BM_face_split(bm, f_iter, v1, v2, &nl, NULL, false);
+ f_iter = BM_face_split(bm, f_iter, v1, v2, &l_new, NULL, false);
if (r_f) {
*r_f = f_iter;
}
- return nl->e;
+ return l_new->e;
}
}
}
@@ -339,51 +339,51 @@ BMFace *BM_face_split(BMesh *bm, BMFace *f, BMVert *v1, BMVert *v2, BMLoop **r_l
BMEdge *example, const bool no_double)
{
const bool has_mdisp = CustomData_has_layer(&bm->ldata, CD_MDISPS);
- BMFace *nf, *of;
+ BMFace *f_new, *f_tmp;
BLI_assert(v1 != v2);
/* do we have a multires layer? */
if (has_mdisp) {
- of = BM_face_copy(bm, f, false, false);
+ f_tmp = BM_face_copy(bm, f, false, false);
}
#ifdef USE_BMESH_HOLES
- nf = bmesh_sfme(bm, f, v1, v2, r_l, NULL, example, no_double);
+ f_new = bmesh_sfme(bm, f, v1, v2, r_l, NULL, example, no_double);
#else
- nf = bmesh_sfme(bm, f, v1, v2, r_l, example, no_double);
+ f_new = bmesh_sfme(bm, f, v1, v2, r_l, example, no_double);
#endif
- if (nf) {
- BM_elem_attrs_copy(bm, bm, f, nf);
- copy_v3_v3(nf->no, f->no);
+ if (f_new) {
+ BM_elem_attrs_copy(bm, bm, f, f_new);
+ copy_v3_v3(f_new->no, f->no);
/* handle multires update */
- if (has_mdisp && (nf != f)) {
+ if (has_mdisp && (f_new != f)) {
BMLoop *l_iter;
BMLoop *l_first;
l_iter = l_first = BM_FACE_FIRST_LOOP(f);
do {
- BM_loop_interp_multires(bm, l_iter, of);
+ BM_loop_interp_multires(bm, l_iter, f_tmp);
} while ((l_iter = l_iter->next) != l_first);
- l_iter = l_first = BM_FACE_FIRST_LOOP(nf);
+ l_iter = l_first = BM_FACE_FIRST_LOOP(f_new);
do {
- BM_loop_interp_multires(bm, l_iter, of);
+ BM_loop_interp_multires(bm, l_iter, f_tmp);
} while ((l_iter = l_iter->next) != l_first);
- BM_face_kill(bm, of);
+ BM_face_kill(bm, f_tmp);
#if 0
/* BM_face_multires_bounds_smooth doesn't flip displacement correct */
BM_face_multires_bounds_smooth(bm, f);
- BM_face_multires_bounds_smooth(bm, nf);
+ BM_face_multires_bounds_smooth(bm, f_new);
#endif
}
}
- return nf;
+ return f_new;
}
/**
@@ -406,62 +406,62 @@ BMFace *BM_face_split(BMesh *bm, BMFace *f, BMVert *v1, BMVert *v2, BMLoop **r_l
BMFace *BM_face_split_n(BMesh *bm, BMFace *f, BMVert *v1, BMVert *v2, float cos[][3], int n,
BMLoop **r_l, BMEdge *example)
{
- BMFace *nf, *of;
+ BMFace *f_new, *f_tmp;
BMLoop *l_dummy;
- BMEdge *e, *newe;
- BMVert *newv;
+ BMEdge *e, *e_new;
+ BMVert *v_new;
int i, j;
BLI_assert(v1 != v2);
- of = BM_face_copy(bm, f, true, true);
+ f_tmp = BM_face_copy(bm, f, true, true);
if (!r_l)
r_l = &l_dummy;
#ifdef USE_BMESH_HOLES
- nf = bmesh_sfme(bm, f, v1, v2, r_l, NULL, example, false);
+ f_new = bmesh_sfme(bm, f, v1, v2, r_l, NULL, example, false);
#else
- nf = bmesh_sfme(bm, f, v1, v2, r_l, example, false);
+ f_new = bmesh_sfme(bm, f, v1, v2, r_l, example, false);
#endif
- /* bmesh_sfme returns in r_l a Loop for nf going from v1 to v2.
+ /* bmesh_sfme returns in r_l a Loop for f_new going from v1 to v2.
* The radial_next is for f and goes from v2 to v1 */
- if (nf) {
- BM_elem_attrs_copy(bm, bm, f, nf);
- copy_v3_v3(nf->no, f->no);
+ if (f_new) {
+ BM_elem_attrs_copy(bm, bm, f, f_new);
+ copy_v3_v3(f_new->no, f->no);
e = (*r_l)->e;
for (i = 0; i < n; i++) {
- newv = bmesh_semv(bm, v2, e, &newe);
- BLI_assert(newv != NULL);
- /* bmesh_semv returns in newe the edge going from newv to tv */
- copy_v3_v3(newv->co, cos[i]);
+ v_new = bmesh_semv(bm, v2, e, &e_new);
+ BLI_assert(v_new != NULL);
+ /* bmesh_semv returns in e_new the edge going from v_new to tv */
+ copy_v3_v3(v_new->co, cos[i]);
- /* interpolate the loop data for the loops with (v == newv), using orig face */
+ /* interpolate the loop data for the loops with (v == v_new), using orig face */
for (j = 0; j < 2; j++) {
- BMEdge *e_iter = (j == 0) ? e : newe;
+ BMEdge *e_iter = (j == 0) ? e : e_new;
BMLoop *l_iter = e_iter->l;
do {
- if (l_iter->v == newv) {
+ if (l_iter->v == v_new) {
/* this interpolates both loop and vertex data */
- BM_loop_interp_from_face(bm, l_iter, of, true, true);
+ BM_loop_interp_from_face(bm, l_iter, f_tmp, true, true);
}
} while ((l_iter = l_iter->radial_next) != e_iter->l);
}
- e = newe;
+ e = e_new;
}
}
- BM_face_verts_kill(bm, of);
+ BM_face_verts_kill(bm, f_tmp);
- return nf;
+ return f_new;
}
/**
* \brief Vert Collapse Faces
*
- * Collapses vertex \a kv that has only two manifold edges
+ * Collapses vertex \a v_kill that has only two manifold edges
* onto a vertex it shares an edge with.
* \a fac defines the amount of interpolation for Custom Data.
*
@@ -472,8 +472,8 @@ BMFace *BM_face_split_n(BMesh *bm, BMFace *f, BMVert *v1, BMVert *v2, float cos[
* Except this takes a factor and merges custom data.
*
* \param bm The bmesh
- * \param ke The edge to collapse
- * \param kv The vertex to collapse into the edge
+ * \param e_kill The edge to collapse
+ * \param v_kill The vertex to collapse into the edge
* \param fac The factor along the edge
* \param join_faces When true the faces around the vertex will be joined
* otherwise collapse the vertex by merging the 2 edges this vert touches into one.
@@ -481,11 +481,11 @@ BMFace *BM_face_split_n(BMesh *bm, BMFace *f, BMVert *v1, BMVert *v2, float cos[
*
* \returns The New Edge
*/
-BMEdge *BM_vert_collapse_faces(BMesh *bm, BMEdge *ke, BMVert *kv, float fac,
+BMEdge *BM_vert_collapse_faces(BMesh *bm, BMEdge *e_kill, BMVert *v_kill, float fac,
const bool join_faces, const bool kill_degenerate_faces)
{
- BMEdge *ne = NULL;
- BMVert *tv = bmesh_edge_other_vert_get(ke, kv);
+ BMEdge *e_new = NULL;
+ BMVert *tv = bmesh_edge_other_vert_get(e_kill, v_kill);
BMEdge *e2;
BMVert *tv2;
@@ -497,17 +497,17 @@ BMEdge *BM_vert_collapse_faces(BMesh *bm, BMEdge *ke, BMVert *kv, float fac,
float w[2];
/* Only intended to be called for 2-valence vertices */
- BLI_assert(bmesh_disk_count(kv) <= 2);
+ BLI_assert(bmesh_disk_count(v_kill) <= 2);
/* first modify the face loop data */
w[0] = 1.0f - fac;
w[1] = fac;
- if (ke->l) {
- l_iter = ke->l;
+ if (e_kill->l) {
+ l_iter = e_kill->l;
do {
- if (l_iter->v == tv && l_iter->next->v == kv) {
+ if (l_iter->v == tv && l_iter->next->v == v_kill) {
tvloop = l_iter;
kvloop = l_iter->next;
@@ -515,30 +515,30 @@ BMEdge *BM_vert_collapse_faces(BMesh *bm, BMEdge *ke, BMVert *kv, float fac,
src[1] = tvloop->head.data;
CustomData_bmesh_interp(&bm->ldata, src, w, NULL, 2, kvloop->head.data);
}
- } while ((l_iter = l_iter->radial_next) != ke->l);
+ } while ((l_iter = l_iter->radial_next) != e_kill->l);
}
/* now interpolate the vertex data */
- BM_data_interp_from_verts(bm, kv, tv, kv, fac);
+ BM_data_interp_from_verts(bm, v_kill, tv, v_kill, fac);
- e2 = bmesh_disk_edge_next(ke, kv);
- tv2 = BM_edge_other_vert(e2, kv);
+ e2 = bmesh_disk_edge_next(e_kill, v_kill);
+ tv2 = BM_edge_other_vert(e2, v_kill);
if (join_faces) {
BMFace **faces = NULL;
BMFace *f;
BLI_array_staticdeclare(faces, 8);
- BM_ITER_ELEM (f, &iter, kv, BM_FACES_OF_VERT) {
+ BM_ITER_ELEM (f, &iter, v_kill, BM_FACES_OF_VERT) {
BLI_array_append(faces, f);
}
if (BLI_array_count(faces) >= 2) {
BMFace *f2 = BM_faces_join(bm, faces, BLI_array_count(faces), true);
if (f2) {
- BMLoop *nl = NULL;
- if (BM_face_split(bm, f2, tv, tv2, &nl, NULL, false)) {
- ne = nl->e;
+ BMLoop *l_new = NULL;
+ if (BM_face_split(bm, f2, tv, tv2, &l_new, NULL, false)) {
+ e_new = l_new->e;
}
}
}
@@ -549,16 +549,16 @@ BMEdge *BM_vert_collapse_faces(BMesh *bm, BMEdge *ke, BMVert *kv, float fac,
/* single face or no faces */
/* same as BM_vert_collapse_edge() however we already
* have vars to perform this operation so don't call. */
- ne = bmesh_jekv(bm, ke, kv, true);
- /* ne = BM_edge_exists(tv, tv2); */ /* same as return above */
+ e_new = bmesh_jekv(bm, e_kill, v_kill, true);
+ /* e_new = BM_edge_exists(tv, tv2); */ /* same as return above */
- if (ne && kill_degenerate_faces) {
+ if (e_new && kill_degenerate_faces) {
BLI_array_declare(bad_faces);
BMFace **bad_faces = NULL;
BMIter fiter;
BMFace *f;
- BMVert *verts[2] = {ne->v1, ne->v2};
+ BMVert *verts[2] = {e_new->v1, e_new->v2};
int i;
for (i = 0; i < 2; i++) {
@@ -577,7 +577,7 @@ BMEdge *BM_vert_collapse_faces(BMesh *bm, BMEdge *ke, BMVert *kv, float fac,
}
}
- return ne;
+ return e_new;
}
@@ -588,37 +588,37 @@ BMEdge *BM_vert_collapse_faces(BMesh *bm, BMEdge *ke, BMVert *kv, float fac,
*
* \return The New Edge
*/
-BMEdge *BM_vert_collapse_edge(BMesh *bm, BMEdge *ke, BMVert *kv,
+BMEdge *BM_vert_collapse_edge(BMesh *bm, BMEdge *e_kill, BMVert *v_kill,
const bool kill_degenerate_faces)
{
/* nice example implementation but we want loops to have their customdata
* accounted for */
#if 0
- BMEdge *ne = NULL;
+ BMEdge *e_new = NULL;
/* Collapse between 2 edges */
/* in this case we want to keep all faces and not join them,
* rather just get rid of the vertex - see bug [#28645] */
- BMVert *tv = bmesh_edge_other_vert_get(ke, kv);
+ BMVert *tv = bmesh_edge_other_vert_get(e_kill, v_kill);
if (tv) {
- BMEdge *e2 = bmesh_disk_edge_next(ke, kv);
+ BMEdge *e2 = bmesh_disk_edge_next(e_kill, v_kill);
if (e2) {
- BMVert *tv2 = BM_edge_other_vert(e2, kv);
+ BMVert *tv2 = BM_edge_other_vert(e2, v_kill);
if (tv2) {
/* only action, other calls here only get the edge to return */
- ne = bmesh_jekv(bm, ke, kv);
+ e_new = bmesh_jekv(bm, e_kill, v_kill);
- /* ne = BM_edge_exists(tv, tv2); */ /* same as return above */
+ /* e_new = BM_edge_exists(tv, tv2); */ /* same as return above */
}
}
}
- return ne;
+ return e_new;
#else
/* with these args faces are never joined, same as above
* but account for loop customdata */
- return BM_vert_collapse_faces(bm, ke, kv, 1.0f, false, kill_degenerate_faces);
+ return BM_vert_collapse_faces(bm, e_kill, v_kill, 1.0f, false, kill_degenerate_faces);
#endif
}
@@ -637,7 +637,7 @@ BMEdge *BM_vert_collapse_edge(BMesh *bm, BMEdge *ke, BMVert *kv,
*/
BMVert *BM_edge_split(BMesh *bm, BMEdge *e, BMVert *v, BMEdge **r_e, float percent)
{
- BMVert *nv, *v2;
+ BMVert *v_new, *v2;
BMFace **oldfaces = NULL;
BMEdge *e_dummy;
BLI_array_staticdeclare(oldfaces, 32);
@@ -668,21 +668,21 @@ BMVert *BM_edge_split(BMesh *bm, BMEdge *e, BMVert *v, BMEdge **r_e, float perce
}
v2 = bmesh_edge_other_vert_get(e, v);
- nv = bmesh_semv(bm, v, e, r_e);
+ v_new = bmesh_semv(bm, v, e, r_e);
- BLI_assert(nv != NULL);
+ BLI_assert(v_new != NULL);
- sub_v3_v3v3(nv->co, v2->co, v->co);
- madd_v3_v3v3fl(nv->co, v->co, nv->co, percent);
+ sub_v3_v3v3(v_new->co, v2->co, v->co);
+ madd_v3_v3v3fl(v_new->co, v->co, v_new->co, percent);
if (r_e) {
(*r_e)->head.hflag = e->head.hflag;
BM_elem_attrs_copy(bm, bm, e, *r_e);
}
- /* v->nv->v2 */
- BM_data_interp_face_vert_edge(bm, v2, v, nv, e, percent);
- BM_data_interp_from_verts(bm, v, v2, nv, percent);
+ /* v->v_new->v2 */
+ BM_data_interp_face_vert_edge(bm, v2, v, v_new, e, percent);
+ BM_data_interp_from_verts(bm, v, v2, v_new, percent);
if (do_mdisp) {
int i, j;
@@ -742,7 +742,7 @@ BMVert *BM_edge_split(BMesh *bm, BMEdge *e, BMVert *v, BMEdge **r_e, float perce
BLI_array_free(oldfaces);
}
- return nv;
+ return v_new;
}
/**
@@ -752,13 +752,13 @@ BMVert *BM_edge_split_n(BMesh *bm, BMEdge *e, int numcuts)
{
int i;
float percent;
- BMVert *nv = NULL;
+ BMVert *v_new = NULL;
for (i = 0; i < numcuts; i++) {
percent = 1.0f / (float)(numcuts + 1 - i);
- nv = BM_edge_split(bm, e, e->v2, NULL, percent);
+ v_new = BM_edge_split(bm, e, e->v2, NULL, percent);
}
- return nv;
+ return v_new;
}
#if 0
diff --git a/source/blender/bmesh/intern/bmesh_mods.h b/source/blender/bmesh/intern/bmesh_mods.h
index 358268cb589..93d6ca10edb 100644
--- a/source/blender/bmesh/intern/bmesh_mods.h
+++ b/source/blender/bmesh/intern/bmesh_mods.h
@@ -47,9 +47,9 @@ BMFace *BM_face_split_n(BMesh *bm, BMFace *f,
float cos[][3], int n,
BMLoop **r_l, BMEdge *example);
-BMEdge *BM_vert_collapse_faces(BMesh *bm, BMEdge *ke, BMVert *kv, float fac,
+BMEdge *BM_vert_collapse_faces(BMesh *bm, BMEdge *e_kill, BMVert *v_kill, float fac,
const bool join_faces, const bool kill_degenerate_faces);
-BMEdge *BM_vert_collapse_edge(BMesh *bm, BMEdge *ke, BMVert *kv,
+BMEdge *BM_vert_collapse_edge(BMesh *bm, BMEdge *e_kill, BMVert *v_kill,
const bool kill_degenerate_faces);
diff --git a/source/blender/bmesh/intern/bmesh_operator_api.h b/source/blender/bmesh/intern/bmesh_operator_api.h
index fd6571d136e..978aec0c610 100644
--- a/source/blender/bmesh/intern/bmesh_operator_api.h
+++ b/source/blender/bmesh/intern/bmesh_operator_api.h
@@ -451,7 +451,7 @@ typedef struct BMOIter {
char restrictmask; /* bitwise '&' with BMHeader.htype */
} BMOIter;
-void *BMO_slot_buffer_elem_first(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name);
+void *BMO_slot_buffer_get_first(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name);
void *BMO_iter_new(BMOIter *iter,
BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name,
diff --git a/source/blender/bmesh/intern/bmesh_operator_api_inline.h b/source/blender/bmesh/intern/bmesh_operator_api_inline.h
index 053d70349e8..0e1d4fec4d3 100644
--- a/source/blender/bmesh/intern/bmesh_operator_api_inline.h
+++ b/source/blender/bmesh/intern/bmesh_operator_api_inline.h
@@ -120,13 +120,13 @@ BLI_INLINE void BMO_slot_map_empty_insert(BMOperator *op, BMOpSlot *slot,
BMO_slot_map_insert(op, slot, element, NULL, 0);
}
-BLI_INLINE int BMO_slot_map_contains(BMOpSlot *slot, const void *element)
+BLI_INLINE bool BMO_slot_map_contains(BMOpSlot *slot, const void *element)
{
BLI_assert(slot->slot_type == BMO_OP_SLOT_MAPPING);
/* sanity check */
if (UNLIKELY(slot->data.ghash == NULL)) {
- return 0;
+ return false;
}
return BLI_ghash_haskey(slot->data.ghash, element);
diff --git a/source/blender/bmesh/intern/bmesh_operators.c b/source/blender/bmesh/intern/bmesh_operators.c
index 00f8dbe06bf..f52dd7f2be9 100644
--- a/source/blender/bmesh/intern/bmesh_operators.c
+++ b/source/blender/bmesh/intern/bmesh_operators.c
@@ -1355,7 +1355,7 @@ static void bmo_flag_layer_clear(BMesh *bm)
bm->elem_index_dirty &= ~(BM_VERT | BM_EDGE | BM_FACE);
}
-void *BMO_slot_buffer_elem_first(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name)
+void *BMO_slot_buffer_get_first(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name)
{
BMOpSlot *slot = BMO_slot_get(slot_args, slot_name);
@@ -1521,7 +1521,7 @@ static int bmo_name_to_slotcode(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char
int i = 0;
while (slot_args->slot_name) {
- if (strncmp(identifier, slot_args->slot_name, MAX_SLOTNAME) == 0) {
+ if (STREQLEN(identifier, slot_args->slot_name, MAX_SLOTNAME)) {
return i;
}
slot_args++;
@@ -1546,7 +1546,7 @@ static int bmo_opname_to_opcode(const char *opname)
int i;
for (i = 0; i < bmo_opdefines_total; i++) {
- if (!strcmp(opname, bmo_opdefines[i]->opname)) {
+ if (STREQ(opname, bmo_opdefines[i]->opname)) {
return i;
}
}
diff --git a/source/blender/bmesh/intern/bmesh_operators_private.h b/source/blender/bmesh/intern/bmesh_operators_private.h
index ea9ad2ed151..1aa4383d761 100644
--- a/source/blender/bmesh/intern/bmesh_operators_private.h
+++ b/source/blender/bmesh/intern/bmesh_operators_private.h
@@ -30,9 +30,6 @@
struct BMesh;
struct BMOperator;
-void BMO_push(BMesh *bm, BMOperator *op);
-void BMO_pop(BMesh *bm);
-
void bmo_automerge_exec(BMesh *bm, BMOperator *op);
void bmo_average_vert_facedata_exec(BMesh *bm, BMOperator *op);
void bmo_beautify_fill_exec(BMesh *bm, BMOperator *op);
diff --git a/source/blender/bmesh/intern/bmesh_polygon.c b/source/blender/bmesh/intern/bmesh_polygon.c
index 9592c34fc75..4041fc2c755 100644
--- a/source/blender/bmesh/intern/bmesh_polygon.c
+++ b/source/blender/bmesh/intern/bmesh_polygon.c
@@ -35,12 +35,17 @@
* degenerate faces.
*/
-#include "BLI_math.h"
-#include "BLI_array.h"
+#include "DNA_listBase.h"
#include "MEM_guardedalloc.h"
+#include "BLI_math.h"
+#include "BLI_array.h"
+#include "BLI_scanfill.h"
+#include "BLI_listbase.h"
+
#include "bmesh.h"
+
#include "intern/bmesh_private.h"
/**
@@ -151,6 +156,103 @@ static void bm_face_calc_poly_normal_vertex_cos(BMFace *f, float n[3],
}
/**
+ * For tools that insist on using triangles, ideally we would cache this data.
+ *
+ * \param r_loops Store face loop pointers, (f->len)
+ * \param r_index Store triangle triples, indicies into \a r_loops, ((f->len - 2) * 3)
+ */
+int BM_face_calc_tessellation(BMFace *f, BMLoop **r_loops, int (*_r_index)[3])
+{
+ int *r_index = (int *)_r_index;
+ BMLoop *l_first = BM_FACE_FIRST_LOOP(f);
+ BMLoop *l_iter;
+ int totfilltri;
+
+ if (f->len == 3) {
+ *r_loops++ = (l_iter = l_first);
+ *r_loops++ = (l_iter = l_iter->next);
+ *r_loops++ = ( l_iter->next);
+
+ r_index[0] = 0;
+ r_index[1] = 1;
+ r_index[2] = 2;
+ totfilltri = 1;
+ }
+ else if (f->len == 4) {
+ *r_loops++ = (l_iter = l_first);
+ *r_loops++ = (l_iter = l_iter->next);
+ *r_loops++ = (l_iter = l_iter->next);
+ *r_loops++ = ( l_iter->next);
+
+ r_index[0] = 0;
+ r_index[1] = 1;
+ r_index[2] = 2;
+
+ r_index[3] = 0;
+ r_index[4] = 2;
+ r_index[5] = 3;
+ totfilltri = 2;
+ }
+ else {
+ int j;
+
+ ScanFillContext sf_ctx;
+ ScanFillVert *sf_vert, *sf_vert_last = NULL, *sf_vert_first = NULL;
+ /* ScanFillEdge *e; */ /* UNUSED */
+ ScanFillFace *sf_tri;
+
+ BLI_scanfill_begin(&sf_ctx);
+
+ j = 0;
+ l_iter = l_first;
+ do {
+ sf_vert = BLI_scanfill_vert_add(&sf_ctx, l_iter->v->co);
+ sf_vert->tmp.p = l_iter;
+
+ if (sf_vert_last) {
+ /* e = */ BLI_scanfill_edge_add(&sf_ctx, sf_vert_last, sf_vert);
+ }
+
+ sf_vert_last = sf_vert;
+ if (sf_vert_first == NULL) {
+ sf_vert_first = sf_vert;
+ }
+
+ r_loops[j] = l_iter;
+
+ /* mark order */
+ BM_elem_index_set(l_iter, j++); /* set_loop */
+
+ } while ((l_iter = l_iter->next) != l_first);
+
+ /* complete the loop */
+ BLI_scanfill_edge_add(&sf_ctx, sf_vert_first, sf_vert);
+
+ totfilltri = BLI_scanfill_calc_ex(&sf_ctx, 0, f->no);
+ BLI_assert(totfilltri <= f->len - 2);
+ BLI_assert(totfilltri == BLI_countlist(&sf_ctx.fillfacebase));
+
+ for (sf_tri = sf_ctx.fillfacebase.first; sf_tri; sf_tri = sf_tri->next) {
+ int i1 = BM_elem_index_get((BMLoop *)sf_tri->v1->tmp.p);
+ int i2 = BM_elem_index_get((BMLoop *)sf_tri->v2->tmp.p);
+ int i3 = BM_elem_index_get((BMLoop *)sf_tri->v3->tmp.p);
+
+ if (i1 > i2) { SWAP(int, i1, i2); }
+ if (i2 > i3) { SWAP(int, i2, i3); }
+ if (i1 > i2) { SWAP(int, i1, i2); }
+
+ *r_index++ = i1;
+ *r_index++ = i2;
+ *r_index++ = i3;
+ }
+
+ BLI_scanfill_end(&sf_ctx);
+ }
+
+ return totfilltri;
+}
+
+/**
* get the area of the face
*/
float BM_face_calc_area(BMFace *f)
diff --git a/source/blender/bmesh/intern/bmesh_polygon.h b/source/blender/bmesh/intern/bmesh_polygon.h
index 601caae2337..c439a41f672 100644
--- a/source/blender/bmesh/intern/bmesh_polygon.h
+++ b/source/blender/bmesh/intern/bmesh_polygon.h
@@ -27,6 +27,12 @@
* \ingroup bmesh
*/
+int BM_face_calc_tessellation(BMFace *f, BMLoop **r_loops, int (*r_index)[3])
+#ifdef __GNUC__
+ __attribute__((warn_unused_result))
+ __attribute__((nonnull))
+#endif
+;
float BM_face_calc_area(BMFace *f);
float BM_face_calc_perimeter(BMFace *f);
void BM_face_calc_center_bounds(BMFace *f, float center[3]);
diff --git a/source/blender/bmesh/intern/bmesh_queries.c b/source/blender/bmesh/intern/bmesh_queries.c
index 44dc483d5a7..26b0e42a1c1 100644
--- a/source/blender/bmesh/intern/bmesh_queries.c
+++ b/source/blender/bmesh/intern/bmesh_queries.c
@@ -680,7 +680,7 @@ bool BM_edge_is_wire(BMEdge *e)
*/
bool BM_vert_is_manifold(BMVert *v)
{
- BMEdge *e, *oe;
+ BMEdge *e, *e_old;
BMLoop *l;
int len, count, flag;
@@ -691,7 +691,7 @@ bool BM_vert_is_manifold(BMVert *v)
/* count edges while looking for non-manifold edges */
len = 0;
- oe = e = v->e;
+ e_old = e = v->e;
do {
/* loose edge or edge shared by more than two faces,
* edges with 1 face user are OK, otherwise we could
@@ -700,14 +700,14 @@ bool BM_vert_is_manifold(BMVert *v)
return false;
}
len++;
- } while ((e = bmesh_disk_edge_next(e, v)) != oe);
+ } while ((e = bmesh_disk_edge_next(e, v)) != e_old);
count = 1;
flag = 1;
e = NULL;
- oe = v->e;
- l = oe->l;
- while (e != oe) {
+ e_old = v->e;
+ l = e_old->l;
+ while (e != e_old) {
l = (l->v == v) ? l->prev : l->next;
e = l->e;
count++; /* count the edges */
@@ -716,13 +716,13 @@ bool BM_vert_is_manifold(BMVert *v)
/* we've hit the edge of an open mesh, reset once */
flag = 0;
count = 1;
- oe = e;
+ e_old = e;
e = NULL;
- l = oe->l;
+ l = e_old->l;
}
else if (l->radial_next == l) {
/* break the loop */
- e = oe;
+ e = e_old;
}
else {
l = l->radial_next;
@@ -769,9 +769,9 @@ int BM_edge_is_manifold(BMEdge *e)
bool BM_edge_is_contiguous(BMEdge *e)
{
const BMLoop *l = e->l;
- const BMLoop *l_other = l->radial_next;
- return (l && (l_other != l) && /* not 0 or 1 face users */
- (l_other->radial_next == l) && /* 2 face users */
+ const BMLoop *l_other;
+ return (l && ((l_other = l->radial_next) != l) && /* not 0 or 1 face users */
+ (l_other->radial_next == l) && /* 2 face users */
(l_other->v != l->v));
}
@@ -1352,6 +1352,8 @@ BMEdge *BM_edge_exists(BMVert *v1, BMVert *v2)
BMIter iter;
BMEdge *e;
+ BLI_assert(v1 != v2);
+
BM_ITER_ELEM (e, &iter, v1, BM_EDGES_OF_VERT) {
if (e->v1 == v2 || e->v2 == v2)
return e;
@@ -1652,3 +1654,38 @@ bool BM_face_is_any_edge_flag_test(BMFace *f, const char hflag)
} while ((l_iter = l_iter->next) != l_first);
return false;
}
+
+static void bm_mesh_calc_volume_face(BMFace *f, float *r_vol)
+{
+ int tottri = f->len - 2;
+ BMLoop **loops = BLI_array_alloca(loops, f->len);
+ int (*index)[3] = BLI_array_alloca(index, tottri);
+ int j;
+
+ tottri = BM_face_calc_tessellation(f, loops, index);
+ BLI_assert(tottri <= f->len - 2);
+
+ for (j = 0; j < tottri; j++) {
+ const float *p1 = loops[index[j][0]]->v->co;
+ const float *p2 = loops[index[j][1]]->v->co;
+ const float *p3 = loops[index[j][2]]->v->co;
+
+ /* co1.dot(co2.cross(co3)) / 6.0 */
+ float cross[3];
+ cross_v3_v3v3(cross, p2, p3);
+ *r_vol += (1.0f / 6.0f) * dot_v3v3(p1, cross);
+ }
+}
+float BM_mesh_calc_volume(BMesh *bm)
+{
+ /* warning, calls own tessellation function, may be slow */
+ float vol = 0.0f;
+ BMFace *f;
+ BMIter fiter;
+
+ BM_ITER_MESH (f, &fiter, bm, BM_FACES_OF_MESH) {
+ bm_mesh_calc_volume_face(f, &vol);
+ }
+
+ return fabsf(vol);
+}
diff --git a/source/blender/bmesh/intern/bmesh_queries.h b/source/blender/bmesh/intern/bmesh_queries.h
index 7cb5749a4bf..f894912aad3 100644
--- a/source/blender/bmesh/intern/bmesh_queries.h
+++ b/source/blender/bmesh/intern/bmesh_queries.h
@@ -110,4 +110,6 @@ bool BM_edge_is_any_vert_flag_test(BMEdge *e, const char hflag);
bool BM_face_is_any_vert_flag_test(BMFace *f, const char hflag);
bool BM_face_is_any_edge_flag_test(BMFace *f, const char hflag);
+float BM_mesh_calc_volume(BMesh *bm);
+
#endif /* __BMESH_QUERIES_H__ */
diff --git a/source/blender/bmesh/intern/bmesh_structure.c b/source/blender/bmesh/intern/bmesh_structure.c
index 2f568a498c5..0398f9c558f 100644
--- a/source/blender/bmesh/intern/bmesh_structure.c
+++ b/source/blender/bmesh/intern/bmesh_structure.c
@@ -63,15 +63,15 @@ BMVert *bmesh_edge_other_vert_get(BMEdge *e, BMVert *v)
return NULL;
}
-bool bmesh_edge_swapverts(BMEdge *e, BMVert *orig, BMVert *newv)
+bool bmesh_edge_swapverts(BMEdge *e, BMVert *v_orig, BMVert *v_new)
{
- if (e->v1 == orig) {
- e->v1 = newv;
+ if (e->v1 == v_orig) {
+ e->v1 = v_new;
e->v1_disk_link.next = e->v1_disk_link.prev = NULL;
return true;
}
- else if (e->v2 == orig) {
- e->v2 = newv;
+ else if (e->v2 == v_orig) {
+ e->v2 = v_new;
e->v2_disk_link.next = e->v2_disk_link.prev = NULL;
return true;
}
diff --git a/source/blender/bmesh/intern/bmesh_walkers_impl.c b/source/blender/bmesh/intern/bmesh_walkers_impl.c
index ac6d4089372..a50b708961c 100644
--- a/source/blender/bmesh/intern/bmesh_walkers_impl.c
+++ b/source/blender/bmesh/intern/bmesh_walkers_impl.c
@@ -163,7 +163,7 @@ static void *bmw_ShellWalker_step(BMWalker *walker)
static void *bmw_ShellWalker_step(BMWalker *walker)
{
BMEdge *curedge, *next = NULL;
- BMVert *ov = NULL;
+ BMVert *v_old = NULL;
bool restrictpass = true;
BMwShellWalker shellWalk = *((BMwShellWalker *)BMW_current_state(walker));
@@ -183,7 +183,7 @@ static void *bmw_ShellWalker_step(BMWalker *walker)
{
BMwShellWalker *newstate;
- ov = BM_edge_other_vert(curedge, shellWalk.base);
+ v_old = BM_edge_other_vert(curedge, shellWalk.base);
/* push a new state onto the stac */
newState = BMW_state_add(walker);
@@ -191,7 +191,7 @@ static void *bmw_ShellWalker_step(BMWalker *walker)
/* populate the new stat */
- newState->base = ov;
+ newState->base = v_old;
newState->curedge = curedge;
}
}
diff --git a/source/blender/bmesh/operators/bmo_bevel.c b/source/blender/bmesh/operators/bmo_bevel.c
index 795531d6776..052ae9336ab 100644
--- a/source/blender/bmesh/operators/bmo_bevel.c
+++ b/source/blender/bmesh/operators/bmo_bevel.c
@@ -55,7 +55,7 @@ void bmo_bevel_exec(BMesh *bm, BMOperator *op)
}
}
- BM_mesh_bevel(bm, offset, seg, vonly, false, NULL, -1);
+ BM_mesh_bevel(bm, offset, seg, vonly, false, false, NULL, -1);
BMO_slot_buffer_from_enabled_hflag(bm, op, op->slots_out, "faces.out", BM_FACE, BM_ELEM_TAG);
}
diff --git a/source/blender/bmesh/operators/bmo_connect.c b/source/blender/bmesh/operators/bmo_connect.c
index 9a17ebea38d..dc00d020083 100644
--- a/source/blender/bmesh/operators/bmo_connect.c
+++ b/source/blender/bmesh/operators/bmo_connect.c
@@ -44,10 +44,10 @@
void bmo_connect_verts_exec(BMesh *bm, BMOperator *op)
{
BMIter iter, liter;
- BMFace *f, *nf;
+ BMFace *f, *f_new;
BMLoop *(*loops_split)[2] = NULL;
BLI_array_declare(loops_split);
- BMLoop *l, *nl, *lastl = NULL;
+ BMLoop *l, *l_new;
BMVert *(*verts_pair)[2] = NULL;
BLI_array_declare(verts_pair);
int i;
@@ -56,7 +56,8 @@ void bmo_connect_verts_exec(BMesh *bm, BMOperator *op)
/* BMESH_TODO, loop over vert faces:
* faster then looping over all faces, then searching each for flagged verts*/
- for (f = BM_iter_new(&iter, bm, BM_FACES_OF_MESH, NULL); f; f = BM_iter_step(&iter)) {
+ BM_ITER_MESH (f, &iter, bm, BM_FACES_OF_MESH) {
+ BMLoop *l_last;
BLI_array_empty(loops_split);
BLI_array_empty(verts_pair);
@@ -64,22 +65,21 @@ void bmo_connect_verts_exec(BMesh *bm, BMOperator *op)
continue;
}
- l = BM_iter_new(&liter, bm, BM_LOOPS_OF_FACE, f);
- lastl = NULL;
- for ( ; l; l = BM_iter_step(&liter)) {
+ l_last = NULL;
+ BM_ITER_ELEM (l, &liter, f, BM_LOOPS_OF_FACE) {
if (BMO_elem_flag_test(bm, l->v, VERT_INPUT)) {
- if (!lastl) {
- lastl = l;
+ if (!l_last) {
+ l_last = l;
continue;
}
- if (lastl != l->prev && lastl != l->next) {
+ if (l_last != l->prev && l_last != l->next) {
BLI_array_grow_one(loops_split);
- loops_split[BLI_array_count(loops_split) - 1][0] = lastl;
+ loops_split[BLI_array_count(loops_split) - 1][0] = l_last;
loops_split[BLI_array_count(loops_split) - 1][1] = l;
}
- lastl = l;
+ l_last = l;
}
}
@@ -106,16 +106,16 @@ void bmo_connect_verts_exec(BMesh *bm, BMOperator *op)
}
for (i = 0; i < BLI_array_count(verts_pair); i++) {
- nf = BM_face_split(bm, f, verts_pair[i][0], verts_pair[i][1], &nl, NULL, false);
- f = nf;
+ f_new = BM_face_split(bm, f, verts_pair[i][0], verts_pair[i][1], &l_new, NULL, false);
+ f = f_new;
- if (!nl || !nf) {
+ if (!l_new || !f_new) {
BMO_error_raise(bm, op, BMERR_CONNECTVERT_FAILED, NULL);
BLI_array_free(loops_split);
return;
}
- BMO_elem_flag_enable(bm, nf, FACE_NEW);
- BMO_elem_flag_enable(bm, nl->e, EDGE_OUT);
+ BMO_elem_flag_enable(bm, f_new, FACE_NEW);
+ BMO_elem_flag_enable(bm, l_new->e, EDGE_OUT);
}
}
@@ -160,19 +160,19 @@ static int clamp_index(const int x, const int len)
* isn't there should be... */
#define ARRAY_SWAP(elemtype, arr1, arr2) \
{ \
- int i; \
+ int i_; \
elemtype *arr_tmp = NULL; \
BLI_array_declare(arr_tmp); \
- for (i = 0; i < BLI_array_count(arr1); i++) { \
- BLI_array_append(arr_tmp, arr1[i]); \
+ for (i_ = 0; i_ < BLI_array_count(arr1); i_++) { \
+ BLI_array_append(arr_tmp, arr1[i_]); \
} \
BLI_array_empty(arr1); \
- for (i = 0; i < BLI_array_count(arr2); i++) { \
- BLI_array_append(arr1, arr2[i]); \
+ for (i_ = 0; i_ < BLI_array_count(arr2); i_++) { \
+ BLI_array_append(arr1, arr2[i_]); \
} \
BLI_array_empty(arr2); \
- for (i = 0; i < BLI_array_count(arr_tmp); i++) { \
- BLI_array_append(arr2, arr_tmp[i]); \
+ for (i_ = 0; i_ < BLI_array_count(arr_tmp); i_++) { \
+ BLI_array_append(arr2, arr_tmp[i_]); \
} \
BLI_array_free(arr_tmp); \
} (void)0
@@ -228,8 +228,8 @@ void bmo_bridge_loops_exec(BMesh *bm, BMOperator *op)
BMO_ITER (e, &siter, op->slots_in, "edges", BM_EDGE) {
if (!BMO_elem_flag_test(bm, e, EDGE_DONE)) {
- BMVert *v, *ov;
- /* BMEdge *e2, *e3, *oe = e; */ /* UNUSED */
+ BMVert *v, *v_old;
+ /* BMEdge *e2, *e3, *e_old = e; */ /* UNUSED */
BMEdge *e2, *e3;
if (c > 2) {
@@ -265,7 +265,7 @@ void bmo_bridge_loops_exec(BMesh *bm, BMOperator *op)
e2 = e;
e = e2;
- ov = v;
+ v_old = v;
do {
if (c == 0) {
BLI_array_append(ee1, e2);
@@ -301,7 +301,7 @@ void bmo_bridge_loops_exec(BMesh *bm, BMOperator *op)
}
/* test for connected loops, and set cl1 or cl2 if so */
- if (v == ov) {
+ if (v == v_old) {
if (c == 0) {
cl1 = 1;
}
diff --git a/source/blender/bmesh/operators/bmo_create.c b/source/blender/bmesh/operators/bmo_create.c
index ae07c2cf0bc..9fab89f8e0a 100644
--- a/source/blender/bmesh/operators/bmo_create.c
+++ b/source/blender/bmesh/operators/bmo_create.c
@@ -26,12 +26,12 @@
#include "MEM_guardedalloc.h"
-#include "BLI_heap.h"
#include "BLI_listbase.h"
#include "BLI_math.h"
#include "BLI_array.h"
#include "BLI_smallhash.h"
#include "BLI_rand.h"
+#include "BLI_heap.h"
#include "bmesh.h"
@@ -810,9 +810,9 @@ static EPath *edge_find_shortest_path(BMesh *bm, BMOperator *op, BMEdge *edge, E
}
if (use_restrict) {
- int *group = (int *)BMO_slot_map_data_get(slot_restrict, e);
- if (group) {
- if (!(*group & path->group)) {
+ int *group_flag = (int *)BMO_slot_map_data_get(slot_restrict, e);
+ if (group_flag) {
+ if (!(*group_flag & path->group)) {
v2 = NULL;
continue;
}
@@ -925,15 +925,12 @@ void bmo_edgenet_fill_exec(BMesh *bm, BMOperator *op)
BMO_elem_flag_enable(bm, f, ELE_ORIG);
}
- i = 0;
- BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) {
+ BM_ITER_MESH_INDEX (e, &iter, bm, BM_EDGES_OF_MESH, i) {
BM_elem_index_set(e, i); /* set_inline */
if (!BMO_elem_flag_test(bm, e, EDGE_MARK)) {
edata[i].tag = 2;
}
-
- i++;
}
bm->elem_index_dirty &= ~BM_EDGE;
@@ -1491,6 +1488,7 @@ void bmo_contextual_create_exec(BMesh *bm, BMOperator *op)
if (use_smooth) {
BM_elem_flag_enable(f, BM_ELEM_SMOOTH);
}
+ BMO_slot_buffer_from_enabled_flag(bm, op, op->slots_out, "faces.out", BM_FACE, ELE_OUT);
}
MEM_freeN(vert_arr);
diff --git a/source/blender/bmesh/operators/bmo_dissolve.c b/source/blender/bmesh/operators/bmo_dissolve.c
index 47b2497816f..a78a8ec5197 100644
--- a/source/blender/bmesh/operators/bmo_dissolve.c
+++ b/source/blender/bmesh/operators/bmo_dissolve.c
@@ -41,7 +41,7 @@
#define VERT_MARK 1
-static bool UNUSED_FUNCTION(check_hole_in_region) (BMesh * bm, BMFace * f)
+static bool UNUSED_FUNCTION(check_hole_in_region) (BMesh *bm, BMFace *f)
{
BMWalker regwalker;
BMIter liter2;
@@ -75,11 +75,12 @@ static bool UNUSED_FUNCTION(check_hole_in_region) (BMesh * bm, BMFace * f)
void bmo_dissolve_faces_exec(BMesh *bm, BMOperator *op)
{
BMOIter oiter;
- BMFace *f, *f2 /* , *nf = NULL */;
+ BMFace *f;
BLI_array_declare(faces);
BLI_array_declare(regions);
BMFace ***regions = NULL;
BMFace **faces = NULL;
+ BMFace *act_face = bm->act_face;
BMWalker regwalker;
int i;
@@ -100,7 +101,7 @@ void bmo_dissolve_faces_exec(BMesh *bm, BMOperator *op)
/* collect region */
BMO_ITER (f, &oiter, op->slots_in, "faces", BM_FACE) {
-
+ BMFace *f_iter;
if (!BMO_elem_flag_test(bm, f, FACE_MARK)) {
continue;
}
@@ -113,15 +114,15 @@ void bmo_dissolve_faces_exec(BMesh *bm, BMOperator *op)
BMW_FLAG_NOP, /* no need to check BMW_FLAG_TEST_HIDDEN, faces are already marked by the bmo */
BMW_NIL_LAY);
- for (f2 = BMW_begin(&regwalker, f); f2; f2 = BMW_step(&regwalker)) {
- BLI_array_append(faces, f2);
+ for (f_iter = BMW_begin(&regwalker, f); f_iter; f_iter = BMW_step(&regwalker)) {
+ BLI_array_append(faces, f_iter);
}
BMW_end(&regwalker);
for (i = 0; i < BLI_array_count(faces); i++) {
- f2 = faces[i];
- BMO_elem_flag_disable(bm, f2, FACE_MARK);
- BMO_elem_flag_enable(bm, f2, FACE_ORIG);
+ f_iter = faces[i];
+ BMO_elem_flag_disable(bm, f_iter, FACE_MARK);
+ BMO_elem_flag_enable(bm, f_iter, FACE_ORIG);
}
if (BMO_error_occurred(bm)) {
@@ -135,6 +136,7 @@ void bmo_dissolve_faces_exec(BMesh *bm, BMOperator *op)
}
for (i = 0; i < BLI_array_count(regions); i++) {
+ BMFace *f_new;
int tot = 0;
faces = regions[i];
@@ -147,8 +149,15 @@ void bmo_dissolve_faces_exec(BMesh *bm, BMOperator *op)
while (faces[tot])
tot++;
- f = BM_faces_join(bm, faces, tot, true);
- if (!f) {
+ f_new = BM_faces_join(bm, faces, tot, true);
+
+ if (f_new) {
+ /* maintain active face */
+ if (act_face && bm->act_face == NULL) {
+ bm->act_face = f_new;
+ }
+ }
+ else {
BMO_error_raise(bm, op, BMERR_DISSOLVEFACES_FAILED,
"Could not create merged face");
goto cleanup;
@@ -156,8 +165,8 @@ void bmo_dissolve_faces_exec(BMesh *bm, BMOperator *op)
/* if making the new face failed (e.g. overlapping test)
* unmark the original faces for deletion */
- BMO_elem_flag_disable(bm, f, FACE_ORIG);
- BMO_elem_flag_enable(bm, f, FACE_NEW);
+ BMO_elem_flag_disable(bm, f_new, FACE_ORIG);
+ BMO_elem_flag_enable(bm, f_new, FACE_NEW);
}
@@ -196,23 +205,33 @@ cleanup:
void bmo_dissolve_edgeloop_exec(BMesh *bm, BMOperator *op)
{
/* BMOperator fop; */
+ BMFace *act_face = bm->act_face;
BMOIter oiter;
BMIter iter;
BMVert *v, **verts = NULL;
BLI_array_declare(verts);
BMEdge *e;
- BMFace *fa, *fb;
int i;
BMO_ITER (e, &oiter, op->slots_in, "edges", BM_EDGE) {
+ BMFace *fa, *fb;
+
if (BM_edge_face_pair(e, &fa, &fb)) {
+ BMFace *f_new;
BMO_elem_flag_enable(bm, e->v1, VERT_MARK);
BMO_elem_flag_enable(bm, e->v2, VERT_MARK);
/* BMESH_TODO - check on delaying edge removal since we may end up removing more then
* one edge, and later reference a removed edge */
- BM_faces_join_pair(bm, fa, fb, e, true);
+ f_new = BM_faces_join_pair(bm, fa, fb, e, true);
+
+ if (f_new) {
+ /* maintain active face */
+ if (act_face && bm->act_face == NULL) {
+ bm->act_face = f_new;
+ }
+ }
}
}
@@ -245,9 +264,9 @@ void bmo_dissolve_edges_exec(BMesh *bm, BMOperator *op)
/* might want to make this an option or mode - campbell */
/* BMOperator fop; */
+ BMFace *act_face = bm->act_face;
BMOIter eiter;
BMEdge *e;
-
BMIter viter;
BMVert *v;
@@ -263,12 +282,20 @@ void bmo_dissolve_edges_exec(BMesh *bm, BMOperator *op)
BMFace *fa, *fb;
if (BM_edge_face_pair(e, &fa, &fb)) {
+ BMFace *f_new;
/* join faces */
/* BMESH_TODO - check on delaying edge removal since we may end up removing more then
* one edge, and later reference a removed edge */
- BM_faces_join_pair(bm, fa, fb, e, true);
+ f_new = BM_faces_join_pair(bm, fa, fb, e, true);
+
+ if (f_new) {
+ /* maintain active face */
+ if (act_face && bm->act_face == NULL) {
+ bm->act_face = f_new;
+ }
+ }
}
}
@@ -285,34 +312,32 @@ void bmo_dissolve_edges_exec(BMesh *bm, BMOperator *op)
static bool test_extra_verts(BMesh *bm, BMVert *v)
{
- BMIter iter, liter, iter2, iter3;
- BMFace *f, *f2;
+ BMIter fiter, liter, eiter, fiter_sub;
+ BMFace *f;
BMLoop *l;
BMEdge *e;
- bool found;
/* test faces around verts for verts that would be wrongly killed
* by dissolve faces. */
- f = BM_iter_new(&iter, bm, BM_FACES_OF_VERT, v);
- for ( ; f; f = BM_iter_step(&iter)) {
- l = BM_iter_new(&liter, bm, BM_LOOPS_OF_FACE, f);
- for ( ; l; l = BM_iter_step(&liter)) {
+ BM_ITER_ELEM(f, &fiter, v, BM_FACES_OF_VERT) {
+ BM_ITER_ELEM(l, &liter, f, BM_LOOPS_OF_FACE) {
if (!BMO_elem_flag_test(bm, l->v, VERT_MARK)) {
/* if an edge around a vert is a boundary edge,
* then dissolve faces won't destroy it.
* also if it forms a boundary with one
* of the face region */
- found = false;
- e = BM_iter_new(&iter2, bm, BM_EDGES_OF_VERT, l->v);
- for ( ; e; e = BM_iter_step(&iter2)) {
+ bool found = false;
+ BM_ITER_ELEM(e, &eiter, l->v, BM_EDGES_OF_VERT) {
+ BMFace *f_iter;
if (BM_edge_is_boundary(e)) {
found = true;
}
- f2 = BM_iter_new(&iter3, bm, BM_FACES_OF_EDGE, e);
- for ( ; f2; f2 = BM_iter_step(&iter3)) {
- if (!BMO_elem_flag_test(bm, f2, FACE_MARK)) {
- found = true;
- break;
+ else {
+ BM_ITER_ELEM(f_iter, &fiter_sub, e, BM_FACES_OF_EDGE) {
+ if (!BMO_elem_flag_test(bm, f_iter, FACE_MARK)) {
+ found = true;
+ break;
+ }
}
}
if (found == true) {
diff --git a/source/blender/bmesh/operators/bmo_extrude.c b/source/blender/bmesh/operators/bmo_extrude.c
index 4fde6150f05..62220510623 100644
--- a/source/blender/bmesh/operators/bmo_extrude.c
+++ b/source/blender/bmesh/operators/bmo_extrude.c
@@ -30,6 +30,7 @@
#include "BLI_math.h"
#include "BLI_array.h"
+#include "BLI_buffer.h"
#include "BKE_customdata.h"
@@ -271,7 +272,7 @@ void bmo_extrude_face_region_exec(BMesh *bm, BMOperator *op)
BMOIter siter;
BMIter iter, fiter, viter;
BMEdge *e, *e_new;
- BMVert *v, *v2;
+ BMVert *v;
BMFace *f;
bool found, fwd, delorig = false;
BMOpSlot *slot_facemap_out;
@@ -441,7 +442,7 @@ void bmo_extrude_face_region_exec(BMesh *bm, BMOperator *op)
/* link isolated vert */
for (v = BMO_iter_new(&siter, dupeop.slots_out, "isovert_map.out", 0); v; v = BMO_iter_step(&siter)) {
- v2 = *((void **)BMO_iter_map_value(&siter));
+ BMVert *v2 = *((void **)BMO_iter_map_value(&siter));
BM_edge_create(bm, v, v2, v->e, BM_CREATE_NO_DOUBLE);
}
@@ -612,15 +613,18 @@ static void solidify_add_thickness(BMesh *bm, const float dist)
float *vert_accum = vert_angles + bm->totvert;
int i, index;
+ BLI_buffer_declare_static(float, face_angles_buf, BLI_BUFFER_NOP, BM_DEFAULT_NGON_STACK_SIZE);
+ BLI_buffer_declare_static(float *, verts_buf, BLI_BUFFER_NOP, 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)) {
/* array for passing verts to angle_poly_v3 */
- float *face_angles = BLI_array_alloca(face_angles, f->len);
+ float *face_angles = BLI_buffer_resize_data(&face_angles_buf, float, f->len);
/* array for receiving angles from angle_poly_v3 */
- float **verts = BLI_array_alloca(verts, f->len);
+ float **verts = BLI_buffer_resize_data(&verts_buf, float *, f->len);
BM_ITER_ELEM_INDEX (l, &loopIter, f, BM_LOOPS_OF_FACE, i) {
verts[i] = l->v->co;
@@ -639,6 +643,9 @@ static void solidify_add_thickness(BMesh *bm, const float dist)
}
}
+ BLI_buffer_free(&face_angles_buf);
+ BLI_buffer_free(&verts_buf);
+
BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) {
index = BM_elem_index_get(v);
if (vert_accum[index]) { /* zero if unselected */
diff --git a/source/blender/bmesh/operators/bmo_hull.c b/source/blender/bmesh/operators/bmo_hull.c
index 5e2404c9919..7dc2884c5ed 100644
--- a/source/blender/bmesh/operators/bmo_hull.c
+++ b/source/blender/bmesh/operators/bmo_hull.c
@@ -28,11 +28,11 @@
#include "MEM_guardedalloc.h"
+#include "BLI_utildefines.h"
#include "BLI_array.h"
#include "BLI_ghash.h"
#include "BLI_listbase.h"
#include "BLI_math.h"
-#include "BLI_utildefines.h"
#include "Bullet-C-Api.h"
diff --git a/source/blender/bmesh/operators/bmo_removedoubles.c b/source/blender/bmesh/operators/bmo_removedoubles.c
index 7beac676868..8b65764fe1c 100644
--- a/source/blender/bmesh/operators/bmo_removedoubles.c
+++ b/source/blender/bmesh/operators/bmo_removedoubles.c
@@ -40,7 +40,7 @@ static void remdoubles_splitface(BMFace *f, BMesh *bm, BMOperator *op, BMOpSlot
{
BMIter liter;
BMLoop *l;
- BMVert *v2, *doub;
+ BMVert *v2, *v_double;
bool split = false;
BM_ITER_ELEM (l, &liter, f, BM_LOOPS_OF_FACE) {
@@ -51,15 +51,15 @@ static void remdoubles_splitface(BMFace *f, BMesh *bm, BMOperator *op, BMOpSlot
(v2 != l->prev->v) &&
(v2 != l->next->v))
{
- doub = l->v;
+ v_double = l->v;
split = true;
break;
}
}
- if (split && doub != v2) {
- BMLoop *nl;
- BMFace *f2 = BM_face_split(bm, f, doub, v2, &nl, NULL, false);
+ if (split && v_double != v2) {
+ BMLoop *l_new;
+ BMFace *f2 = BM_face_split(bm, f, v_double, v2, &l_new, NULL, false);
remdoubles_splitface(f, bm, op, slot_targetmap);
remdoubles_splitface(f2, bm, op, slot_targetmap);
diff --git a/source/blender/bmesh/operators/bmo_smooth_laplacian.c b/source/blender/bmesh/operators/bmo_smooth_laplacian.c
index ba755a866de..6b91d5fded9 100644
--- a/source/blender/bmesh/operators/bmo_smooth_laplacian.c
+++ b/source/blender/bmesh/operators/bmo_smooth_laplacian.c
@@ -29,10 +29,10 @@
#include "DNA_meshdata_types.h"
#include "BLI_array.h"
-#include "BLI_heap.h"
#include "BLI_math.h"
#include "BLI_math_geom.h"
#include "BLI_smallhash.h"
+#include "BLI_heap.h"
#include "BKE_customdata.h"
#include "BKE_mesh.h"
@@ -69,7 +69,6 @@ struct BLaplacianSystem {
};
typedef struct BLaplacianSystem LaplacianSystem;
-static float compute_volume(BMesh *bm);
static float cotan_weight(float *v1, float *v2, float *v3);
static int vert_is_boundary(BMVert *v);
static LaplacianSystem *init_laplacian_system(int a_numEdges, int a_numFaces, int a_numVerts);
@@ -85,7 +84,6 @@ static void delete_void_pointer(void *data)
{
if (data) {
MEM_freeN(data);
- data = NULL;
}
}
@@ -416,45 +414,6 @@ static int vert_is_boundary(BMVert *v)
return 0;
}
-static float compute_volume(BMesh *bm)
-{
- float vol = 0.0f;
- float x1, y1, z1, x2, y2, z2, x3, y3, z3, x4, y4, z4;
- int i;
- BMFace *f;
- BMIter fiter;
- BMIter vi;
- BMVert *vn;
- BMVert *vf[4];
-
- BM_ITER_MESH (f, &fiter, bm, BM_FACES_OF_MESH) {
- BM_ITER_ELEM_INDEX (vn, &vi, f, BM_VERTS_OF_FACE, i) {
- vf[i] = vn;
- }
- x1 = vf[0]->co[0];
- y1 = vf[0]->co[1];
- z1 = vf[0]->co[2];
-
- x2 = vf[1]->co[0];
- y2 = vf[1]->co[1];
- z2 = vf[1]->co[2];
-
- x3 = vf[2]->co[0];
- y3 = vf[2]->co[1];
- z3 = vf[2]->co[2];
-
- vol += (1.0f / 6.0f) * (0.0f - x3 * y2 * z1 + x2 * y3 * z1 + x3 * y1 * z2 - x1 * y3 * z2 - x2 * y1 * z3 + x1 * y2 * z3);
-
- if (i == 4) {
- x4 = vf[3]->co[0];
- y4 = vf[3]->co[1];
- z4 = vf[3]->co[2];
- vol += (1.0f / 6.0f) * (x1 * y3 * z4 - x1 * y4 * z3 - x3 * y1 * z4 + x3 * z1 * y4 + y1 * x4 * z3 - x4 * y3 * z1);
- }
- }
- return fabs(vol);
-}
-
static void volume_preservation(BMOperator *op, float vini, float vend, int usex, int usey, int usez)
{
float beta;
@@ -510,7 +469,7 @@ static void validate_solution(LaplacianSystem *sys, int usex, int usey, int usez
}
if (preserve_volume) {
- vini = compute_volume(sys->bm);
+ vini = BM_mesh_calc_volume(sys->bm);
}
BMO_ITER (v, &siter, sys->op->slots_in, "verts", BM_VERT) {
m_vertex_id = BM_elem_index_get(v);
@@ -527,7 +486,7 @@ static void validate_solution(LaplacianSystem *sys, int usex, int usey, int usez
}
}
if (preserve_volume) {
- vend = compute_volume(sys->bm);
+ vend = BM_mesh_calc_volume(sys->bm);
volume_preservation(sys->op, vini, vend, usex, usey, usez);
}
diff --git a/source/blender/bmesh/operators/bmo_subdivide.c b/source/blender/bmesh/operators/bmo_subdivide.c
index 36ad8ef506b..88e903c1651 100644
--- a/source/blender/bmesh/operators/bmo_subdivide.c
+++ b/source/blender/bmesh/operators/bmo_subdivide.c
@@ -40,7 +40,47 @@
#include "intern/bmesh_operators_private.h" /* own include */
-#include "bmo_subdivide.h" /* own include */
+typedef struct SubDParams {
+ int numcuts;
+ float smooth;
+ float fractal;
+ float along_normal;
+ //int beauty;
+ bool use_smooth;
+ bool use_sphere;
+ bool use_fractal;
+ int seed;
+ int origkey; /* shapekey holding displaced vertex coordinates for current geometry */
+ BMOperator *op;
+ BMOpSlot *slot_edge_percents; /* BMO_slot_get(params->op->slots_in, "edge_percents"); */
+ BMOpSlot *slot_custom_patterns; /* BMO_slot_get(params->op->slots_in, "custom_patterns"); */
+ float fractal_ofs[3];
+} SubDParams;
+
+typedef void (*subd_pattern_fill_fp)(BMesh *bm, BMFace *face, BMVert **verts,
+ const SubDParams *params);
+
+/*
+ * note: this is a pattern-based edge subdivider.
+ * it tries to match a pattern to edge selections on faces,
+ * then executes functions to cut them.
+ */
+typedef struct SubDPattern {
+ int seledges[20]; /* selected edges mask, for splitting */
+
+ /* verts starts at the first new vert cut, not the first vert in the face */
+ subd_pattern_fill_fp connectexec;
+ int len; /* total number of verts, before any subdivision */
+} SubDPattern;
+
+/* generic subdivision rules:
+ *
+ * - two selected edges in a face should make a link
+ * between them.
+ *
+ * - one edge should do, what? make pretty topology, or just
+ * split the edge only?
+ */
/* flags for all elements share a common bitfield space */
#define SUBD_SPLIT 1
@@ -71,29 +111,29 @@
/* connects face with smallest len, which I think should always be correct for
* edge subdivision */
-static BMEdge *connect_smallest_face(BMesh *bm, BMVert *v1, BMVert *v2, BMFace **r_nf)
+static BMEdge *connect_smallest_face(BMesh *bm, BMVert *v1, BMVert *v2, BMFace **r_f_new)
{
BMIter iter, iter2;
BMVert *v;
- BMLoop *nl;
- BMFace *face, *curf = NULL;
+ BMLoop *l_new;
+ BMFace *f, *f_cur = NULL;
/* this isn't the best thing in the world. it doesn't handle cases where there's
* multiple faces yet. that might require a convexity test to figure out which
* face is "best" and who knows what for non-manifold conditions. */
- for (face = BM_iter_new(&iter, bm, BM_FACES_OF_VERT, v1); face; face = BM_iter_step(&iter)) {
- for (v = BM_iter_new(&iter2, bm, BM_VERTS_OF_FACE, face); v; v = BM_iter_step(&iter2)) {
+ for (f = BM_iter_new(&iter, bm, BM_FACES_OF_VERT, v1); f; f = BM_iter_step(&iter)) {
+ for (v = BM_iter_new(&iter2, bm, BM_VERTS_OF_FACE, f); v; v = BM_iter_step(&iter2)) {
if (v == v2) {
- if (!curf || face->len < curf->len) curf = face;
+ if (!f_cur || f->len < f_cur->len) f_cur = f;
}
}
}
- if (curf) {
- face = BM_face_split(bm, curf, v1, v2, &nl, NULL, false);
+ if (f_cur) {
+ f = BM_face_split(bm, f_cur, v1, v2, &l_new, NULL, false);
- if (r_nf) *r_nf = face;
- return nl ? nl->e : NULL;
+ if (r_f_new) *r_f_new = f;
+ return l_new ? l_new->e : NULL;
}
return NULL;
@@ -151,7 +191,7 @@ static void alter_co(BMesh *bm, BMVert *v, BMEdge *UNUSED(origed), const SubDPar
mid_v3_v3v3(normal, vsta->no, vend->no);
ortho_basis_v3v3_v3(base1, base2, normal);
- add_v3_v3v3(co2, v->co, params->off);
+ add_v3_v3v3(co2, v->co, params->fractal_ofs);
mul_v3_fl(co2, 10.0f);
tvec[0] = fac * (BLI_gTurbulence(1.0, co2[0], co2[1], co2[2], 15, 0, 2) - 0.5f);
@@ -242,31 +282,31 @@ static BMVert *subdivideedgenum(BMesh *bm, BMEdge *edge, BMEdge *oedge,
static void bm_subdivide_multicut(BMesh *bm, BMEdge *edge, const SubDParams *params,
BMVert *vsta, BMVert *vend)
{
- BMEdge *eed = edge, *newe, temp = *edge;
- BMVert *v, ov1 = *edge->v1, ov2 = *edge->v2, *v1 = edge->v1, *v2 = edge->v2;
+ BMEdge *eed = edge, *e_new, e_tmp = *edge;
+ BMVert *v, v1_tmp = *edge->v1, v2_tmp = *edge->v2, *v1 = edge->v1, *v2 = edge->v2;
int i, numcuts = params->numcuts;
- temp.v1 = &ov1;
- temp.v2 = &ov2;
+ e_tmp.v1 = &v1_tmp;
+ e_tmp.v2 = &v2_tmp;
for (i = 0; i < numcuts; i++) {
- v = subdivideedgenum(bm, eed, &temp, i, params->numcuts, params, &newe, vsta, vend);
+ v = subdivideedgenum(bm, eed, &e_tmp, i, params->numcuts, params, &e_new, vsta, vend);
BMO_elem_flag_enable(bm, v, SUBD_SPLIT);
BMO_elem_flag_enable(bm, eed, SUBD_SPLIT);
- BMO_elem_flag_enable(bm, newe, SUBD_SPLIT);
+ BMO_elem_flag_enable(bm, e_new, SUBD_SPLIT);
BMO_elem_flag_enable(bm, v, ELE_SPLIT);
BMO_elem_flag_enable(bm, eed, ELE_SPLIT);
- BMO_elem_flag_enable(bm, newe, SUBD_SPLIT);
+ BMO_elem_flag_enable(bm, e_new, SUBD_SPLIT);
BM_CHECK_ELEMENT(v);
if (v->e) BM_CHECK_ELEMENT(v->e);
if (v->e && v->e->l) BM_CHECK_ELEMENT(v->e->l->f);
}
- alter_co(bm, v1, &temp, params, 0, &ov1, &ov2);
- alter_co(bm, v2, &temp, params, 1.0, &ov1, &ov2);
+ alter_co(bm, v1, &e_tmp, params, 0, &v1_tmp, &v2_tmp);
+ alter_co(bm, v2, &e_tmp, params, 1.0, &v1_tmp, &v2_tmp);
}
/* note: the patterns are rotated as necessary to
@@ -286,7 +326,7 @@ static void bm_subdivide_multicut(BMesh *bm, BMEdge *edge, const SubDParams *par
static void quad_1edge_split(BMesh *bm, BMFace *UNUSED(face),
BMVert **verts, const SubDParams *params)
{
- BMFace *nf;
+ BMFace *f_new;
int i, add, numcuts = params->numcuts;
/* if it's odd, the middle face is a quad, otherwise it's a triangle */
@@ -296,16 +336,16 @@ static void quad_1edge_split(BMesh *bm, BMFace *UNUSED(face),
if (i == numcuts / 2) {
add -= 1;
}
- connect_smallest_face(bm, verts[i], verts[numcuts + add], &nf);
+ connect_smallest_face(bm, verts[i], verts[numcuts + add], &f_new);
}
}
else {
add = 2;
for (i = 0; i < numcuts; i++) {
- connect_smallest_face(bm, verts[i], verts[numcuts + add], &nf);
+ connect_smallest_face(bm, verts[i], verts[numcuts + add], &f_new);
if (i == numcuts / 2) {
add -= 1;
- connect_smallest_face(bm, verts[i], verts[numcuts + add], &nf);
+ connect_smallest_face(bm, verts[i], verts[numcuts + add], &f_new);
}
}
@@ -332,13 +372,13 @@ static const SubDPattern quad_1edge = {
static void quad_2edge_split_path(BMesh *bm, BMFace *UNUSED(face), BMVert **verts,
const SubDParams *params)
{
- BMFace *nf;
+ BMFace *f_new;
int i, numcuts = params->numcuts;
for (i = 0; i < numcuts; i++) {
- connect_smallest_face(bm, verts[i], verts[numcuts + (numcuts - i)], &nf);
+ connect_smallest_face(bm, verts[i], verts[numcuts + (numcuts - i)], &f_new);
}
- connect_smallest_face(bm, verts[numcuts * 2 + 3], verts[numcuts * 2 + 1], &nf);
+ connect_smallest_face(bm, verts[numcuts * 2 + 3], verts[numcuts * 2 + 1], &f_new);
}
static const SubDPattern quad_2edge_path = {
@@ -360,27 +400,27 @@ static const SubDPattern quad_2edge_path = {
static void quad_2edge_split_innervert(BMesh *bm, BMFace *UNUSED(face), BMVert **verts,
const SubDParams *params)
{
- BMFace *nf;
- BMVert *v, *lastv;
- BMEdge *e, *ne, olde;
+ BMFace *f_new;
+ BMVert *v, *v_last;
+ BMEdge *e, *e_new, e_tmp;
int i, numcuts = params->numcuts;
- lastv = verts[numcuts];
+ v_last = verts[numcuts];
for (i = numcuts - 1; i >= 0; i--) {
- e = connect_smallest_face(bm, verts[i], verts[numcuts + (numcuts - i)], &nf);
+ e = connect_smallest_face(bm, verts[i], verts[numcuts + (numcuts - i)], &f_new);
- olde = *e;
- v = bm_subdivide_edge_addvert(bm, e, &olde, params, 0.5f, 0.5f, &ne, e->v1, e->v2);
+ e_tmp = *e;
+ v = bm_subdivide_edge_addvert(bm, e, &e_tmp, params, 0.5f, 0.5f, &e_new, e->v1, e->v2);
if (i != numcuts - 1) {
- connect_smallest_face(bm, lastv, v, &nf);
+ connect_smallest_face(bm, v_last, v, &f_new);
}
- lastv = v;
+ v_last = v;
}
- connect_smallest_face(bm, lastv, verts[numcuts * 2 + 2], &nf);
+ connect_smallest_face(bm, v_last, verts[numcuts * 2 + 2], &f_new);
}
static const SubDPattern quad_2edge_innervert = {
@@ -402,15 +442,15 @@ static const SubDPattern quad_2edge_innervert = {
static void quad_2edge_split_fan(BMesh *bm, BMFace *UNUSED(face), BMVert **verts,
const SubDParams *params)
{
- BMFace *nf;
+ BMFace *f_new;
/* BMVert *v; */ /* UNUSED */
- /* BMVert *lastv = verts[2]; */ /* UNUSED */
- /* BMEdge *e, *ne; */ /* UNUSED */
+ /* BMVert *v_last = verts[2]; */ /* UNUSED */
+ /* BMEdge *e, *e_new; */ /* UNUSED */
int i, numcuts = params->numcuts;
for (i = 0; i < numcuts; i++) {
- connect_smallest_face(bm, verts[i], verts[numcuts * 2 + 2], &nf);
- connect_smallest_face(bm, verts[numcuts + (numcuts - i)], verts[numcuts * 2 + 2], &nf);
+ connect_smallest_face(bm, verts[i], verts[numcuts * 2 + 2], &f_new);
+ connect_smallest_face(bm, verts[numcuts + (numcuts - i)], verts[numcuts * 2 + 2], &f_new);
}
}
@@ -435,21 +475,21 @@ static const SubDPattern quad_2edge_fan = {
static void quad_3edge_split(BMesh *bm, BMFace *UNUSED(face), BMVert **verts,
const SubDParams *params)
{
- BMFace *nf;
+ BMFace *f_new;
int i, add = 0, numcuts = params->numcuts;
for (i = 0; i < numcuts; i++) {
if (i == numcuts / 2) {
if (numcuts % 2 != 0) {
- connect_smallest_face(bm, verts[numcuts - i - 1 + add], verts[i + numcuts + 1], &nf);
+ connect_smallest_face(bm, verts[numcuts - i - 1 + add], verts[i + numcuts + 1], &f_new);
}
add = numcuts * 2 + 2;
}
- connect_smallest_face(bm, verts[numcuts - i - 1 + add], verts[i + numcuts + 1], &nf);
+ connect_smallest_face(bm, verts[numcuts - i - 1 + add], verts[i + numcuts + 1], &f_new);
}
for (i = 0; i < numcuts / 2 + 1; i++) {
- connect_smallest_face(bm, verts[i], verts[(numcuts - i) + numcuts * 2 + 1], &nf);
+ connect_smallest_face(bm, verts[i], verts[(numcuts - i) + numcuts * 2 + 1], &f_new);
}
}
@@ -474,9 +514,9 @@ static const SubDPattern quad_3edge = {
static void quad_4edge_subdivide(BMesh *bm, BMFace *UNUSED(face), BMVert **verts,
const SubDParams *params)
{
- BMFace *nf;
+ BMFace *f_new;
BMVert *v, *v1, *v2;
- BMEdge *e, *ne, temp;
+ BMEdge *e, *e_new, e_tmp;
BMVert **lines;
int numcuts = params->numcuts;
int i, j, a, b, s = numcuts + 2 /* , totv = numcuts * 4 + 4 */;
@@ -501,25 +541,25 @@ static void quad_4edge_subdivide(BMesh *bm, BMFace *UNUSED(face), BMVert **verts
a = i;
b = numcuts + 1 + numcuts + 1 + (numcuts - i - 1);
- e = connect_smallest_face(bm, verts[a], verts[b], &nf);
+ e = connect_smallest_face(bm, verts[a], verts[b], &f_new);
if (!e)
continue;
BMO_elem_flag_enable(bm, e, ELE_INNER);
- BMO_elem_flag_enable(bm, nf, ELE_INNER);
+ BMO_elem_flag_enable(bm, f_new, ELE_INNER);
v1 = lines[(i + 1) * s] = verts[a];
v2 = lines[(i + 1) * s + s - 1] = verts[b];
- temp = *e;
+ e_tmp = *e;
for (a = 0; a < numcuts; a++) {
- v = subdivideedgenum(bm, e, &temp, a, numcuts, params, &ne,
+ v = subdivideedgenum(bm, e, &e_tmp, a, numcuts, params, &e_new,
v1, v2);
BMESH_ASSERT(v != NULL);
- BMO_elem_flag_enable(bm, ne, ELE_INNER);
+ BMO_elem_flag_enable(bm, e_new, ELE_INNER);
lines[(i + 1) * s + a + 1] = v;
}
}
@@ -528,12 +568,12 @@ static void quad_4edge_subdivide(BMesh *bm, BMFace *UNUSED(face), BMVert **verts
for (j = 1; j < numcuts + 1; j++) {
a = i * s + j;
b = (i - 1) * s + j;
- e = connect_smallest_face(bm, lines[a], lines[b], &nf);
+ e = connect_smallest_face(bm, lines[a], lines[b], &f_new);
if (!e)
continue;
BMO_elem_flag_enable(bm, e, ELE_INNER);
- BMO_elem_flag_enable(bm, nf, ELE_INNER);
+ BMO_elem_flag_enable(bm, f_new, ELE_INNER);
}
}
@@ -555,11 +595,11 @@ static void quad_4edge_subdivide(BMesh *bm, BMFace *UNUSED(face), BMVert **verts
static void tri_1edge_split(BMesh *bm, BMFace *UNUSED(face), BMVert **verts,
const SubDParams *params)
{
- BMFace *nf;
+ BMFace *f_new;
int i, numcuts = params->numcuts;
for (i = 0; i < numcuts; i++) {
- connect_smallest_face(bm, verts[i], verts[numcuts + 1], &nf);
+ connect_smallest_face(bm, verts[i], verts[numcuts + 1], &f_new);
}
}
@@ -584,9 +624,9 @@ static const SubDPattern tri_1edge = {
static void tri_3edge_subdivide(BMesh *bm, BMFace *UNUSED(face), BMVert **verts,
const SubDParams *params)
{
- BMFace *nf;
- BMEdge *e, *ne, temp;
- BMVert ***lines, *v, ov1, ov2;
+ BMFace *f_new;
+ BMEdge *e, *e_new, e_tmp;
+ BMVert ***lines, *v, v1_tmp, v2_tmp;
void *stackarr[1];
int i, j, a, b, numcuts = params->numcuts;
@@ -607,26 +647,26 @@ static void tri_3edge_subdivide(BMesh *bm, BMFace *UNUSED(face), BMVert **verts,
lines[i + 1] = MEM_callocN(sizeof(void *) * (2 + i), "triangle vert table row");
a = numcuts * 2 + 2 + i;
b = numcuts + numcuts - i;
- e = connect_smallest_face(bm, verts[a], verts[b], &nf);
+ e = connect_smallest_face(bm, verts[a], verts[b], &f_new);
if (!e) goto cleanup;
BMO_elem_flag_enable(bm, e, ELE_INNER);
- BMO_elem_flag_enable(bm, nf, ELE_INNER);
+ BMO_elem_flag_enable(bm, f_new, ELE_INNER);
lines[i + 1][0] = verts[a];
lines[i + 1][i + 1] = verts[b];
- temp = *e;
- ov1 = *verts[a];
- ov2 = *verts[b];
- temp.v1 = &ov1;
- temp.v2 = &ov2;
+ e_tmp = *e;
+ v1_tmp = *verts[a];
+ v2_tmp = *verts[b];
+ e_tmp.v1 = &v1_tmp;
+ e_tmp.v2 = &v2_tmp;
for (j = 0; j < i; j++) {
- v = subdivideedgenum(bm, e, &temp, j, i, params, &ne,
+ v = subdivideedgenum(bm, e, &e_tmp, j, i, params, &e_new,
verts[a], verts[b]);
lines[i + 1][j + 1] = v;
- BMO_elem_flag_enable(bm, ne, ELE_INNER);
+ BMO_elem_flag_enable(bm, e_new, ELE_INNER);
}
}
@@ -644,15 +684,15 @@ static void tri_3edge_subdivide(BMesh *bm, BMFace *UNUSED(face), BMVert **verts,
*/
for (i = 1; i < numcuts + 1; i++) {
for (j = 0; j < i; j++) {
- e = connect_smallest_face(bm, lines[i][j], lines[i + 1][j + 1], &nf);
+ e = connect_smallest_face(bm, lines[i][j], lines[i + 1][j + 1], &f_new);
BMO_elem_flag_enable(bm, e, ELE_INNER);
- BMO_elem_flag_enable(bm, nf, ELE_INNER);
+ BMO_elem_flag_enable(bm, f_new, ELE_INNER);
- e = connect_smallest_face(bm, lines[i][j + 1], lines[i + 1][j + 1], &nf);
+ e = connect_smallest_face(bm, lines[i][j + 1], lines[i + 1][j + 1], &f_new);
BMO_elem_flag_enable(bm, e, ELE_INNER);
- BMO_elem_flag_enable(bm, nf, ELE_INNER);
+ BMO_elem_flag_enable(bm, f_new, ELE_INNER);
}
}
@@ -711,7 +751,7 @@ void bmo_subdivide_edges_exec(BMesh *bm, BMOperator *op)
BLI_array_declare(loops_split);
BMLoop **loops = NULL;
BLI_array_declare(loops);
- BMLoop *nl, *l;
+ BMLoop *l_new, *l;
BMFace *face;
BLI_array_declare(verts);
float smooth, fractal, along_normal;
@@ -731,9 +771,7 @@ void bmo_subdivide_edges_exec(BMesh *bm, BMOperator *op)
use_grid_fill = BMO_slot_bool_get(op->slots_in, "use_grid_fill");
use_only_quads = BMO_slot_bool_get(op->slots_in, "use_only_quads");
use_sphere = BMO_slot_bool_get(op->slots_in, "use_sphere");
-
- BLI_srandom(seed);
-
+
patterns[1] = NULL;
/* straight cut is patterns[1] == NULL */
switch (cornertype) {
@@ -790,9 +828,14 @@ void bmo_subdivide_edges_exec(BMesh *bm, BMOperator *op)
params.use_fractal = (fractal != 0.0f);
params.use_sphere = use_sphere;
params.origkey = skey;
- params.off[0] = (float)BLI_drand() * 200.0f;
- params.off[1] = (float)BLI_drand() * 200.0f;
- params.off[2] = (float)BLI_drand() * 200.0f;
+
+ if (params.use_fractal) {
+ BLI_srandom(seed);
+
+ params.fractal_ofs[0] = (float)BLI_drand() * 200.0f;
+ params.fractal_ofs[1] = (float)BLI_drand() * 200.0f;
+ params.fractal_ofs[2] = (float)BLI_drand() * 200.0f;
+ }
BMO_slot_map_to_flag(bm, op->slots_in, "custom_patterns",
BM_FACE, FACE_CUSTOMFILL);
@@ -820,9 +863,9 @@ void bmo_subdivide_edges_exec(BMesh *bm, BMOperator *op)
matched = 0;
totesel = 0;
- BM_ITER_ELEM_INDEX (nl, &liter, face, BM_LOOPS_OF_FACE, i) {
- edges[i] = nl->e;
- verts[i] = nl->v;
+ BM_ITER_ELEM_INDEX (l_new, &liter, face, BM_LOOPS_OF_FACE, i) {
+ edges[i] = l_new->e;
+ verts[i] = l_new->v;
if (BMO_elem_flag_test(bm, edges[i], SUBD_SPLIT)) {
if (!e1) e1 = edges[i];
@@ -1042,8 +1085,8 @@ void bmo_subdivide_edges_exec(BMesh *bm, BMOperator *op)
if (loops_split[j][0]) {
BLI_assert(BM_edge_exists(loops_split[j][0]->v, loops_split[j][1]->v) == NULL);
- /* BMFace *nf = */ /* UNUSED */
- BM_face_split(bm, face, loops_split[j][0]->v, loops_split[j][1]->v, &nl, NULL, false);
+ /* BMFace *f_new = */ /* UNUSED */
+ BM_face_split(bm, face, loops_split[j][0]->v, loops_split[j][1]->v, &l_new, NULL, false);
}
}
@@ -1054,8 +1097,8 @@ void bmo_subdivide_edges_exec(BMesh *bm, BMOperator *op)
}
a = 0;
- BM_ITER_ELEM_INDEX (nl, &liter, face, BM_LOOPS_OF_FACE, j) {
- if (nl->v == facedata[i].start) {
+ BM_ITER_ELEM_INDEX (l_new, &liter, face, BM_LOOPS_OF_FACE, j) {
+ if (l_new->v == facedata[i].start) {
a = j + 1;
break;
}
@@ -1063,9 +1106,9 @@ void bmo_subdivide_edges_exec(BMesh *bm, BMOperator *op)
BLI_array_grow_items(verts, face->len);
- BM_ITER_ELEM_INDEX (nl, &liter, face, BM_LOOPS_OF_FACE, j) {
+ BM_ITER_ELEM_INDEX (l_new, &liter, face, BM_LOOPS_OF_FACE, j) {
b = (j - a + face->len) % face->len;
- verts[b] = nl->v;
+ verts[b] = l_new->v;
}
BM_CHECK_ELEMENT(face);
diff --git a/source/blender/bmesh/operators/bmo_subdivide.h b/source/blender/bmesh/operators/bmo_subdivide.h
deleted file mode 100644
index 529075aab02..00000000000
--- a/source/blender/bmesh/operators/bmo_subdivide.h
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * ***** 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): Joseph Eagar.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file blender/bmesh/operators/bmo_subdivide.h
- * \ingroup bmesh
- */
-
-#ifndef __BMO_SUBDIVIDE_H__
-#define __BMO_SUBDIVIDE_H__
-
-typedef struct SubDParams {
- int numcuts;
- float smooth;
- float fractal;
- float along_normal;
- //int beauty;
- short use_smooth;
- short use_sphere;
- short use_fractal;
- int seed;
- int origkey; /* shapekey holding displaced vertex coordinates for current geometry */
- BMOperator *op;
- BMOpSlot *slot_edge_percents; /* BMO_slot_get(params->op->slots_in, "edge_percents"); */
- BMOpSlot *slot_custom_patterns; /* BMO_slot_get(params->op->slots_in, "custom_patterns"); */
- float off[3];
-} SubDParams;
-
-typedef void (*subd_pattern_fill_fp)(BMesh *bm, BMFace *face, BMVert **verts,
- const SubDParams *params);
-
-/*
- * note: this is a pattern-based edge subdivider.
- * it tries to match a pattern to edge selections on faces,
- * then executes functions to cut them.
- */
-typedef struct SubDPattern {
- int seledges[20]; /* selected edges mask, for splitting */
-
- /* verts starts at the first new vert cut, not the first vert in the face */
- subd_pattern_fill_fp connectexec;
- int len; /* total number of verts, before any subdivision */
-} SubDPattern;
-
-/* generic subdivision rules:
- *
- * - two selected edges in a face should make a link
- * between them.
- *
- * - one edge should do, what? make pretty topology, or just
- * split the edge only?
- */
-
-#endif /* __BMO_SUBDIVIDE_H__ */
diff --git a/source/blender/bmesh/operators/bmo_wireframe.c b/source/blender/bmesh/operators/bmo_wireframe.c
index 0d603faf3c4..00838533104 100644
--- a/source/blender/bmesh/operators/bmo_wireframe.c
+++ b/source/blender/bmesh/operators/bmo_wireframe.c
@@ -151,8 +151,6 @@ static bool bm_loop_is_radial_boundary(BMLoop *l_first)
return true;
}
-extern float BM_vert_calc_mean_tagged_edge_length(BMVert *v);
-
void bmo_wireframe_exec(BMesh *bm, BMOperator *op)
{
const bool use_boundary = BMO_slot_bool_get(op->slots_in, "use_boundary");
diff --git a/source/blender/bmesh/tools/bmesh_bevel.c b/source/blender/bmesh/tools/bmesh_bevel.c
index 5adef16de14..f685b741176 100644
--- a/source/blender/bmesh/tools/bmesh_bevel.c
+++ b/source/blender/bmesh/tools/bmesh_bevel.c
@@ -375,8 +375,8 @@ static void offset_meet(EdgeHalf *e1, EdgeHalf *e2, BMVert *v, BMFace *f,
}
}
-/* Like offset_meet, but here f1 and f2 must not be NULL and give the
- * planes in which to run the offset lines.
+/* Like offset_meet, but with a mid edge between them that is used
+ * to calculate the planes in which to run the offset lines.
* They may not meet exactly: the offsets for the edges may be different
* or both the planes and the lines may be angled so that they can't meet.
* In that case, pick a close point on emid, which should be the dividing
@@ -384,16 +384,13 @@ static void offset_meet(EdgeHalf *e1, EdgeHalf *e2, BMVert *v, BMFace *f,
* TODO: should have a global 'offset consistency' prepass to adjust offset
* widths so that all edges have the same offset at both ends. */
static void offset_in_two_planes(EdgeHalf *e1, EdgeHalf *e2, EdgeHalf *emid,
- BMVert *v, BMFace *f1, BMFace *f2, float meetco[3])
+ BMVert *v, float meetco[3])
{
float dir1[3], dir2[3], dirmid[3], norm_perp1[3], norm_perp2[3],
off1a[3], off1b[3], off2a[3], off2b[3], isect2[3], co[3],
f1no[3], f2no[3];
int iret;
- BLI_assert(f1 != NULL && f2 != NULL);
- (void)f1, (void)f2; /* UNUSED */
-
/* get direction vectors for two offset lines */
sub_v3_v3v3(dir1, v->co, BM_edge_other_vert(e1->e, v)->co);
sub_v3_v3v3(dir2, BM_edge_other_vert(e2->e, v)->co, v->co);
@@ -692,8 +689,7 @@ static void build_boundary(BevelParams *bp, BevVert *bv)
if (e->prev->prev->is_bev) {
BLI_assert(e->prev->prev != e); /* see: edgecount 2, selcount 1 case */
/* find meet point between e->prev->prev and e and attach e->prev there */
- offset_in_two_planes(e->prev->prev, e, e->prev, bv->v,
- e->prev->prev->fnext, e->fprev, co);
+ offset_in_two_planes(e->prev->prev, e, e->prev, bv->v, co);
v = add_new_bound_vert(mem_arena, vm, co);
v->efirst = e->prev->prev;
v->elast = v->ebev = e;
@@ -2056,6 +2052,51 @@ static void bevel_build_edge_polygons(BMesh *bm, BevelParams *bp, BMEdge *bme)
}
}
+/*
+ * Calculate and return an offset that is the lesser of the current
+ * bp.offset and the maximum possible offset before geometry
+ * collisions happen.
+ * Currently this is a quick and dirty estimate of the max
+ * possible: half the minimum edge length of any vertex involved
+ * in a bevel. This is usually conservative.
+ * The correct calculation is quite complicated.
+ * TODO: implement this correctly.
+ */
+static float bevel_limit_offset(BMesh *bm, BevelParams *bp)
+{
+ BMVert *v;
+ BMEdge *e;
+ BMIter v_iter, e_iter;
+ float limited_offset, half_elen;
+ bool vbeveled;
+
+ limited_offset = bp->offset;
+ BM_ITER_MESH(v, &v_iter, bm, BM_VERTS_OF_MESH) {
+ if (BM_elem_flag_test(v, BM_ELEM_TAG)) {
+ if (bp->vertex_only) {
+ vbeveled = true;
+ }
+ else {
+ vbeveled = false;
+ BM_ITER_ELEM(e, &e_iter, v, BM_EDGES_OF_VERT) {
+ if (BM_elem_flag_test(BM_edge_other_vert(e, v), BM_ELEM_TAG)) {
+ vbeveled = true;
+ break;
+ }
+ }
+ }
+ if (vbeveled) {
+ BM_ITER_ELEM(e, &e_iter, v, BM_EDGES_OF_VERT) {
+ half_elen = 0.5f * BM_edge_calc_length(e);
+ if (half_elen < limited_offset)
+ limited_offset = half_elen;
+ }
+ }
+ }
+ }
+ return limited_offset;
+}
+
/**
* - Currently only bevels BM_ELEM_TAG'd verts and edges.
*
@@ -2063,10 +2104,13 @@ static void bevel_build_edge_polygons(BMesh *bm, BevelParams *bp, BMEdge *bme)
* the caller needs to ensure this is cleared before calling
* if its going to use this face tag.
*
+ * - If limit_offset is set, adjusts offset down if necessary
+ * to avoid geometry collisions.
+ *
* \warning all tagged edges _must_ be manifold.
*/
void BM_mesh_bevel(BMesh *bm, const float offset, const float segments,
- const bool vertex_only, const bool use_weights,
+ const bool vertex_only, const bool use_weights, const bool limit_offset,
const struct MDeformVert *dvert, const int vertex_group)
{
BMIter iter;
@@ -2087,6 +2131,9 @@ void BM_mesh_bevel(BMesh *bm, const float offset, const float segments,
bp.mem_arena = BLI_memarena_new((1 << 16), __func__);
BLI_memarena_use_calloc(bp.mem_arena);
+ if (limit_offset)
+ bp.offset = bevel_limit_offset(bm, &bp);
+
/* The analysis of the input vertices and execution additional constructions */
BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) {
if (BM_elem_flag_test(v, BM_ELEM_TAG)) {
diff --git a/source/blender/bmesh/tools/bmesh_bevel.h b/source/blender/bmesh/tools/bmesh_bevel.h
index f214125fa1c..bee26357aca 100644
--- a/source/blender/bmesh/tools/bmesh_bevel.h
+++ b/source/blender/bmesh/tools/bmesh_bevel.h
@@ -30,7 +30,7 @@
struct MDeformVert;
void BM_mesh_bevel(BMesh *bm, const float offset, const float segments,
- const bool vertex_only, const bool use_weights,
+ const bool vertex_only, const bool use_weights, const bool limit_offset,
const struct MDeformVert *dvert, const int vertex_group);
#endif /* __BMESH_BEVEL_H__ */
diff --git a/source/blender/bmesh/tools/bmesh_decimate_dissolve.c b/source/blender/bmesh/tools/bmesh_decimate_dissolve.c
index 3a724769f2a..a5122b242be 100644
--- a/source/blender/bmesh/tools/bmesh_decimate_dissolve.c
+++ b/source/blender/bmesh/tools/bmesh_decimate_dissolve.c
@@ -114,14 +114,14 @@ void BM_mesh_decimate_dissolve_ex(BMesh *bm, const float angle_limit, const bool
/* check twice because cumulative effect could dissolve over angle limit */
(BM_edge_calc_face_angle(e) < angle_limit))
{
- BMFace *nf = BM_faces_join_pair(bm, e->l->f,
- e->l->radial_next->f,
- e,
- false); /* join faces */
+ BMFace *f_new = BM_faces_join_pair(bm, e->l->f,
+ e->l->radial_next->f,
+ e,
+ false); /* join faces */
/* there may be some errors, we don't mind, just move on */
- if (nf) {
- BM_face_normal_update(nf);
+ if (f_new) {
+ BM_face_normal_update(f_new);
}
else {
BMO_error_clear(bm);
@@ -210,10 +210,10 @@ void BM_mesh_decimate_dissolve_ex(BMesh *bm, const float angle_limit, const bool
/* check twice because cumulative effect could dissolve over angle limit */
bm_vert_edge_face_angle(v) < angle_limit)
{
- BMEdge *ne = BM_vert_collapse_edge(bm, v->e, v, true); /* join edges */
+ BMEdge *e_new = BM_vert_collapse_edge(bm, v->e, v, true); /* join edges */
- if (ne && ne->l) {
- BM_edge_normals_update(ne);
+ if (e_new && e_new->l) {
+ BM_edge_normals_update(e_new);
}
}
}
diff --git a/source/blender/bmesh/tools/bmesh_decimate_unsubdivide.c b/source/blender/bmesh/tools/bmesh_decimate_unsubdivide.c
index 7e9a5784552..c48e83686b5 100644
--- a/source/blender/bmesh/tools/bmesh_decimate_unsubdivide.c
+++ b/source/blender/bmesh/tools/bmesh_decimate_unsubdivide.c
@@ -181,7 +181,6 @@ void BM_mesh_decimate_unsubdivide_ex(BMesh *bm, const int iterations, const bool
unsigned vert_seek_b_tot = 0;
#endif
- BMVert *v;
BMIter iter;
const unsigned int offset = 0;
@@ -192,12 +191,14 @@ void BM_mesh_decimate_unsubdivide_ex(BMesh *bm, const int iterations, const bool
/* if tag_only is set, we assume the caller knows what verts to tag
* needed for the operator */
if (tag_only == false) {
+ BMVert *v;
BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) {
BM_elem_flag_enable(v, BM_ELEM_TAG);
}
}
for (iter_step = 0; iter_step < iterations; iter_step++) {
+ BMVert *v;
bool iter_done;
BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) {
@@ -223,7 +224,6 @@ void BM_mesh_decimate_unsubdivide_ex(BMesh *bm, const int iterations, const bool
unsigned int i;
#endif
BMVert *v_first = NULL;
- BMVert *v;
/* we could avoid iterating from the start each time */
BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) {
diff --git a/source/blender/bmesh/tools/bmesh_edgesplit.c b/source/blender/bmesh/tools/bmesh_edgesplit.c
index 1d3f973dbc0..3ae5c712f0a 100644
--- a/source/blender/bmesh/tools/bmesh_edgesplit.c
+++ b/source/blender/bmesh/tools/bmesh_edgesplit.c
@@ -48,7 +48,6 @@ static void bm_edgesplit_validate_seams(BMesh *bm)
BMEdge *e;
unsigned char *vtouch;
- unsigned char *vt;
BM_mesh_elem_index_ensure(bm, BM_VERT);
@@ -65,6 +64,7 @@ static void bm_edgesplit_validate_seams(BMesh *bm)
BM_elem_flag_disable(e, BM_ELEM_TAG);
}
else if (BM_edge_is_boundary(e)) {
+ 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)++;
diff --git a/source/blender/collada/AnimationExporter.cpp b/source/blender/collada/AnimationExporter.cpp
index a69f7918e40..48958fbfc90 100644
--- a/source/blender/collada/AnimationExporter.cpp
+++ b/source/blender/collada/AnimationExporter.cpp
@@ -36,9 +36,10 @@ void forEachObjectInExportSet(Scene *sce, Functor &f, LinkNode *export_set)
}
}
-void AnimationExporter::exportAnimations(Scene *sce)
+bool AnimationExporter::exportAnimations(Scene *sce)
{
- if (hasAnimations(sce)) {
+ bool has_animations = hasAnimations(sce);
+ if (has_animations) {
this->scene = sce;
openLibrary();
@@ -47,6 +48,7 @@ void AnimationExporter::exportAnimations(Scene *sce)
closeLibrary();
}
+ return has_animations;
}
// called for each exported object
@@ -257,6 +259,12 @@ std::string AnimationExporter::getObjectBoneName(Object *ob, const FCurve *fcu)
return id_name(ob);
}
+std::string AnimationExporter::getAnimationPathId(const FCurve *fcu)
+{
+ std::string rna_path = std::string(fcu->rna_path);
+ return translate_id(rna_path);
+}
+
//convert f-curves to animation curves and write
void AnimationExporter::dae_animation(Object *ob, FCurve *fcu, char *transformName, bool is_param, Material *ma)
{
@@ -303,16 +311,27 @@ void AnimationExporter::dae_animation(Object *ob, FCurve *fcu, char *transformNa
//Create anim Id
if (ob->type == OB_ARMATURE) {
ob_name = getObjectBoneName(ob, fcu);
- BLI_snprintf(anim_id, sizeof(anim_id), "%s_%s.%s", (char *)translate_id(ob_name).c_str(),
- transformName, axis_name);
+ BLI_snprintf(
+ anim_id,
+ sizeof(anim_id),
+ "%s_%s.%s",
+ (char *)translate_id(ob_name).c_str(),
+ (char *)translate_id(transformName).c_str(),
+ axis_name);
}
else {
if (ma)
ob_name = id_name(ob) + "_material";
else
ob_name = id_name(ob);
- BLI_snprintf(anim_id, sizeof(anim_id), "%s_%s_%s", (char *)translate_id(ob_name).c_str(),
- fcu->rna_path, axis_name);
+
+ BLI_snprintf(
+ anim_id,
+ sizeof(anim_id),
+ "%s_%s_%s",
+ (char *)translate_id(ob_name).c_str(),
+ (char *)getAnimationPathId(fcu).c_str(),
+ axis_name);
}
openAnimation(anim_id, COLLADABU::Utils::EMPTY_STRING);
@@ -882,7 +901,7 @@ std::string AnimationExporter::create_source_from_vector(COLLADASW::InputSemanti
}
-std::string AnimationExporter::create_4x4_source(std::vector<float> &frames, Object * ob, Bone *bone, const std::string& anim_id)
+std::string AnimationExporter::create_4x4_source(std::vector<float> &frames, Object *ob, Bone *bone, const std::string &anim_id)
{
COLLADASW::InputSemantic::Semantics semantic = COLLADASW::InputSemantic::OUTPUT;
std::string source_id = anim_id + get_semantic_suffix(semantic);
diff --git a/source/blender/collada/AnimationExporter.h b/source/blender/collada/AnimationExporter.h
index d2f50b22d02..a6f1b89aedb 100644
--- a/source/blender/collada/AnimationExporter.h
+++ b/source/blender/collada/AnimationExporter.h
@@ -98,7 +98,7 @@ public:
{ this->sw = sw; }
- void exportAnimations(Scene *sce);
+ bool exportAnimations(Scene *sce);
// called for each exported object
void operator() (Object *ob);
@@ -141,7 +141,7 @@ protected:
std::string get_semantic_suffix(COLLADASW::InputSemantic::Semantics semantic);
void add_source_parameters(COLLADASW::SourceBase::ParameterNameList& param,
- COLLADASW::InputSemantic::Semantics semantic, bool is_rot, const char *axis, bool transform);
+ COLLADASW::InputSemantic::Semantics semantic, bool is_rot, const char *axis, bool transform);
void get_source_values(BezTriple *bezt, COLLADASW::InputSemantic::Semantics semantic, bool rotation, float *values, int *length);
@@ -184,6 +184,7 @@ protected:
char *extract_transform_name(char *rna_path);
std::string getObjectBoneName(Object *ob, const FCurve * fcu);
+ std::string getAnimationPathId(const FCurve *fcu);
void getBakedPoseData(Object *obarm, int startFrame, int endFrame, bool ActionBake, bool ActionBakeFirstFrame);
diff --git a/source/blender/collada/ArmatureImporter.cpp b/source/blender/collada/ArmatureImporter.cpp
index 221a5008f10..ed84dee046f 100644
--- a/source/blender/collada/ArmatureImporter.cpp
+++ b/source/blender/collada/ArmatureImporter.cpp
@@ -134,10 +134,10 @@ void ArmatureImporter::create_bone(SkinInfo* skin, COLLADAFW::Node *node, EditBo
// set parent tail
if (parent && totchild == 1) {
- copy_v3_v3(parent->tail, bone->head);
+ copy_v3_v3(parent->tail, bone->head);
// not setting BONE_CONNECTED because this would lock child bone location with respect to parent
- bone->flag |= BONE_CONNECTED;
+ bone->flag |= BONE_CONNECTED;
// XXX increase this to prevent "very" small bones?
const float epsilon = 0.000001f;
diff --git a/source/blender/collada/ControllerExporter.cpp b/source/blender/collada/ControllerExporter.cpp
index 6b367b9cea9..35fcc926bea 100644
--- a/source/blender/collada/ControllerExporter.cpp
+++ b/source/blender/collada/ControllerExporter.cpp
@@ -404,7 +404,7 @@ void ControllerExporter::add_weight_extras(Key *key)
kb = kb->next;
for (; kb; kb = kb->next) {
// XXX why is the weight not used here and set to 0.0?
- float weight = kb->curval;
+ // float weight = kb->curval;
extra.addExtraTechniqueParameter ("KHR", "morph_weights" , 0.000, "MORPH_WEIGHT_TO_TARGET");
}
}
diff --git a/source/blender/collada/DocumentExporter.cpp b/source/blender/collada/DocumentExporter.cpp
index 71909b33db8..c03316e1fe5 100644
--- a/source/blender/collada/DocumentExporter.cpp
+++ b/source/blender/collada/DocumentExporter.cpp
@@ -266,20 +266,32 @@ void DocumentExporter::exportCurrentScene(Scene *sce)
// <library_animations>
AnimationExporter ae(&sw, this->export_settings);
- ae.exportAnimations(sce);
+ bool has_animations = ae.exportAnimations(sce);
// <library_controllers>
ArmatureExporter arm_exporter(&sw, this->export_settings);
ControllerExporter controller_exporter(&sw , this->export_settings);
- //for Morph controller export, removing the check
- /*if (bc_has_object_type(export_set, OB_ARMATURE))
- {*/
- controller_exporter.export_controllers(sce);
- //}
+ if (bc_has_object_type(export_set, OB_ARMATURE) || this->export_settings->include_shapekeys)
+ {
+ controller_exporter.export_controllers(sce);
+ }
// <library_visual_scenes>
SceneExporter se(&sw, &arm_exporter, this->export_settings);
+
+ if (has_animations && this->export_settings->export_transformation_type == BC_TRANSFORMATION_TYPE_MATRIX) {
+ // channels adressing <matrix> objects is not (yet) supported
+ // So we force usage of <location>, <translation> and <scale>
+ fprintf(stdout,
+ "For animated Ojects we must use decomposed <matrix> elements,\n" \
+ "Forcing usage of TransLocRot transformation type.");
+ se.setExportTransformationType(BC_TRANSFORMATION_TYPE_TRANSROTLOC);
+ }
+ else {
+ se.setExportTransformationType(this->export_settings->export_transformation_type);
+ }
+
se.exportScene(sce);
// <scene>
diff --git a/source/blender/collada/EffectExporter.cpp b/source/blender/collada/EffectExporter.cpp
index e4a654dc99a..6741e92cb5c 100644
--- a/source/blender/collada/EffectExporter.cpp
+++ b/source/blender/collada/EffectExporter.cpp
@@ -323,10 +323,10 @@ void EffectsExporter::operator()(Material *ma, Object *ob)
{
if (me->pdata.layers[i].type == CD_MTEXPOLY) {
MTexPoly *txface = (MTexPoly *)me->pdata.layers[i].data;
- MFace *mface = me->mface;
- for (int j = 0; j < me->totpoly; j++, mface++, txface++) {
+ MPoly *mpoly = me->mpoly;
+ for (int j = 0; j < me->totpoly; j++, mpoly++, txface++) {
- Material *mat = give_current_material(ob, mface->mat_nr + 1);
+ Material *mat = give_current_material(ob, mpoly->mat_nr + 1);
if (mat != ma)
continue;
diff --git a/source/blender/collada/ExportSettings.h b/source/blender/collada/ExportSettings.h
index ec71fb2747c..f9eb4cbc26f 100644
--- a/source/blender/collada/ExportSettings.h
+++ b/source/blender/collada/ExportSettings.h
@@ -28,6 +28,7 @@
#define __EXPORTSETTINGS_H__
#include "collada.h"
+#include "collada.h"
struct ExportSettings {
public:
@@ -48,6 +49,7 @@ public:
bool triangulate;
bool use_object_instantiation;
bool sort_by_name;
+ BC_export_transformation_type export_transformation_type;
bool second_life;
char *filepath;
diff --git a/source/blender/collada/ExtraHandler.cpp b/source/blender/collada/ExtraHandler.cpp
index bcf7e573d24..7b8d315b8c5 100644
--- a/source/blender/collada/ExtraHandler.cpp
+++ b/source/blender/collada/ExtraHandler.cpp
@@ -57,7 +57,7 @@ bool ExtraHandler::textData(const char *text, size_t textLength)
if (currentElement.length() == 0 || currentExtraTags == 0) return false;
- BLI_snprintf(buf, textLength + 1, "%s", text);
+ BLI_strncpy(buf, text, textLength + 1);
currentExtraTags->addTag(currentElement, std::string(buf));
return true;
}
diff --git a/source/blender/collada/GeometryExporter.cpp b/source/blender/collada/GeometryExporter.cpp
index 751628acf53..6644c46ac86 100644
--- a/source/blender/collada/GeometryExporter.cpp
+++ b/source/blender/collada/GeometryExporter.cpp
@@ -76,7 +76,6 @@ void GeometryExporter::operator()(Object *ob)
#endif
bool use_instantiation = this->export_settings->use_object_instantiation;
- bool triangulate = this->export_settings->triangulate;
Mesh *me = bc_get_mesh_copy( mScene,
ob,
this->export_settings->export_mesh_type,
@@ -379,8 +378,6 @@ void GeometryExporter::createPolylist(short material_index,
// <p>
int texindex = 0;
- unsigned int vi = 0;
- unsigned int ni = 0;
for (i = 0; i < totpolys; i++) {
MPoly *p = &mpolys[i];
int loop_count = p->totloop;
@@ -442,19 +439,14 @@ void GeometryExporter::createVertsSource(std::string geom_id, Mesh *me)
void GeometryExporter::createVertexColorSource(std::string geom_id, Mesh *me)
{
- if (!CustomData_has_layer(&me->fdata, CD_MCOL))
+ if (!CustomData_has_layer(&me->ldata, CD_MLOOPCOL))
return;
- MFace *f;
- int totcolor = 0, i, j;
-
- for (i = 0, f = me->mface; i < me->totface; i++, f++)
- totcolor += f->v4 ? 4 : 3;
COLLADASW::FloatSourceF source(mSW);
source.setId(getIdBySemantics(geom_id, COLLADASW::InputSemantic::COLOR));
source.setArrayId(getIdBySemantics(geom_id, COLLADASW::InputSemantic::COLOR) + ARRAY_ID_SUFFIX);
- source.setAccessorCount(totcolor);
+ source.setAccessorCount(me->totloop);
source.setAccessorStride(3);
COLLADASW::SourceBase::ParameterNameList &param = source.getParameterNameList();
@@ -464,14 +456,21 @@ void GeometryExporter::createVertexColorSource(std::string geom_id, Mesh *me)
source.prepareToAppendValues();
- int index = CustomData_get_active_layer_index(&me->fdata, CD_MCOL);
-
- MCol *mcol = (MCol *)me->fdata.layers[index].data;
- MCol *c = mcol;
+ int index = CustomData_get_active_layer_index(&me->ldata, CD_MLOOPCOL);
+ MCol *mcol = (MCol *)me->ldata.layers[index].data;
- for (i = 0, f = me->mface; i < me->totface; i++, c += 4, f++)
- for (j = 0; j < (f->v4 ? 4 : 3); j++)
- source.appendValues(c[j].b / 255.0f, c[j].g / 255.0f, c[j].r / 255.0f);
+ MPoly *mpoly;
+ int i;
+ for (i = 0, mpoly = me->mpoly; i < me->totpoly; i++, mpoly++) {
+ MCol *color = mcol + mpoly->loopstart;
+ for (int j = 0; j < mpoly->totloop; j++, color++) {
+ source.appendValues(
+ color->b / 255.0f,
+ color->g / 255.0f,
+ color->r / 255.0f
+ );
+ }
+ }
source.finish();
}
@@ -563,19 +562,19 @@ void GeometryExporter::createNormalsSource(std::string geom_id, Mesh *me, std::v
void GeometryExporter::create_normals(std::vector<Normal> &normals, std::vector<BCPolygonNormalsIndices> &polygons_normals, Mesh *me)
{
- MVert *vert = me->mvert;
std::map<unsigned int, unsigned int> shared_normal_indices;
+ int last_normal_index = -1;
+ MVert *verts = me->mvert;
+ MLoop *mloops = me->mloop;
for (int poly_index = 0; poly_index < me->totpoly; poly_index++) {
MPoly *mpoly = &me->mpoly[poly_index];
- MLoop *mloops = me->mloop;
- unsigned int last_normal_index = -1;
if (!(mpoly->flag & ME_SMOOTH)) {
- // For flat faces calculate use face normal as vertex normal:
+ // For flat faces use face normal as vertex normal:
float vector[3];
- BKE_mesh_calc_poly_normal(mpoly, mloops, vert, vector);
+ BKE_mesh_calc_poly_normal(mpoly, mloops, verts, vector);
Normal n = { vector[0], vector[1], vector[2] };
normals.push_back(n);
@@ -593,8 +592,7 @@ void GeometryExporter::create_normals(std::vector<Normal> &normals, std::vector<
else {
float vector[3];
- normal_short_to_float_v3(vector, vert[vertex_index].no);
- normalize_v3(vector);
+ normal_short_to_float_v3(vector, verts[vertex_index].no);
Normal n = { vector[0], vector[1], vector[2] };
normals.push_back(n);
diff --git a/source/blender/collada/GeometryExporter.h b/source/blender/collada/GeometryExporter.h
index 4b1427c11ca..3719072fe0c 100644
--- a/source/blender/collada/GeometryExporter.h
+++ b/source/blender/collada/GeometryExporter.h
@@ -117,7 +117,7 @@ private:
struct GeometryFunctor {
// f should have
- // void operator()(Object* ob)
+ // void operator()(Object *ob)
template<class Functor>
void forEachMeshObjectInExportSet(Scene *sce, Functor &f, LinkNode *export_set)
{
diff --git a/source/blender/collada/MaterialExporter.h b/source/blender/collada/MaterialExporter.h
index 09d10846b53..ef44bf8a03e 100644
--- a/source/blender/collada/MaterialExporter.h
+++ b/source/blender/collada/MaterialExporter.h
@@ -88,7 +88,7 @@ public:
struct MaterialFunctor {
// calls f for each unique material linked to each object in sce
// f should have
- // void operator()(Material* ma)
+ // void operator()(Material *ma)
template<class Functor>
void forEachMaterialInExportSet(Scene *sce, Functor &f, LinkNode *export_set)
{
diff --git a/source/blender/collada/MeshImporter.cpp b/source/blender/collada/MeshImporter.cpp
index 69944563b6a..71d3ada03dd 100644
--- a/source/blender/collada/MeshImporter.cpp
+++ b/source/blender/collada/MeshImporter.cpp
@@ -384,7 +384,6 @@ void MeshImporter::allocate_poly_data(COLLADAFW::Mesh *collada_mesh, Mesh *me)
for (int i = 0; i < totuvset; i++) {
COLLADAFW::MeshVertexData::InputInfos *info = collada_mesh->getUVCoords().getInputInfosArray()[i];
COLLADAFW::String &uvname = info->mName;
- int x = 0;
// Allocate space for UV_data
CustomData_add_layer_named(&me->pdata, CD_MTEXPOLY, CD_DEFAULT, NULL, me->totpoly, uvname.c_str());
CustomData_add_layer_named(&me->ldata, CD_MLOOPUV, CD_DEFAULT, NULL, me->totloop, uvname.c_str());
@@ -556,7 +555,7 @@ void MeshImporter::read_polys(COLLADAFW::Mesh *collada_mesh, Mesh *me)
int collada_meshtype = mp->getPrimitiveType();
- // since we cannot set mpoly->mat_nr here, we store a portion of me->mface in Primitive
+ // since we cannot set mpoly->mat_nr here, we store a portion of me->mpoly in Primitive
Primitive prim = {mpoly, 0};
COLLADAFW::IndexListArray& index_list_array = mp->getUVCoordIndicesArray();
@@ -1085,7 +1084,7 @@ bool MeshImporter::write_geometry(const COLLADAFW::Geometry *geom)
read_vertices(mesh, me);
read_polys(mesh, me);
- BKE_mesh_calc_edges(me, 0);
+ BKE_mesh_calc_edges(me, false, false);
// read_lines() must be called after the face edges have been generated.
// Oterwise the loose edges will be silently deleted again.
diff --git a/source/blender/collada/MeshImporter.h b/source/blender/collada/MeshImporter.h
index 751e6faf02b..5275420f4b5 100644
--- a/source/blender/collada/MeshImporter.h
+++ b/source/blender/collada/MeshImporter.h
@@ -154,22 +154,22 @@ public:
virtual Mesh *get_mesh_by_geom_uid(const COLLADAFW::UniqueId& geom_uid);
MTex *assign_textures_to_uvlayer(COLLADAFW::TextureCoordinateBinding &ctexture,
- Mesh *me, TexIndexTextureArrayMap& texindex_texarray_map,
- MTex *color_texture);
+ Mesh *me, TexIndexTextureArrayMap& texindex_texarray_map,
+ MTex *color_texture);
void optimize_material_assignements();
MTFace *assign_material_to_geom(COLLADAFW::MaterialBinding cmaterial,
- std::map<COLLADAFW::UniqueId, Material*>& uid_material_map,
- Object *ob, const COLLADAFW::UniqueId *geom_uid,
- char *layername, MTFace *texture_face,
- std::map<Material*, TexIndexTextureArrayMap>& material_texture_mapping_map, short mat_index);
+ std::map<COLLADAFW::UniqueId, Material*>& uid_material_map,
+ Object *ob, const COLLADAFW::UniqueId *geom_uid,
+ char *layername, MTFace *texture_face,
+ std::map<Material*, TexIndexTextureArrayMap>& material_texture_mapping_map, short mat_index);
Object *create_mesh_object(COLLADAFW::Node *node, COLLADAFW::InstanceGeometry *geom,
- bool isController,
- std::map<COLLADAFW::UniqueId, Material*>& uid_material_map,
- std::map<Material*, TexIndexTextureArrayMap>& material_texture_mapping_map);
+ bool isController,
+ std::map<COLLADAFW::UniqueId, Material*>& uid_material_map,
+ std::map<Material*, TexIndexTextureArrayMap>& material_texture_mapping_map);
// create a mesh storing a pointer in a map so it can be retrieved later by geometry UID
bool write_geometry(const COLLADAFW::Geometry* geom);
diff --git a/source/blender/collada/SceneExporter.cpp b/source/blender/collada/SceneExporter.cpp
index dbf7d40b373..f3844be525e 100644
--- a/source/blender/collada/SceneExporter.cpp
+++ b/source/blender/collada/SceneExporter.cpp
@@ -36,7 +36,12 @@ SceneExporter::SceneExporter(COLLADASW::StreamWriter *sw, ArmatureExporter *arm,
: COLLADASW::LibraryVisualScenes(sw), arm_exporter(arm), export_settings(export_settings)
{
}
-
+
+void SceneExporter::setExportTransformationType(BC_export_transformation_type transformation_type)
+{
+ this->transformation_type = transformation_type;
+}
+
void SceneExporter::exportScene(Scene *sce)
{
// <library_visual_scenes> <visual_scene>
@@ -84,6 +89,7 @@ void SceneExporter::exportHierarchy(Scene *sce)
}
}
+
void SceneExporter::writeNodes(Object *ob, Scene *sce)
{
// Add associated armature first if available
@@ -130,8 +136,9 @@ void SceneExporter::writeNodes(Object *ob, Scene *sce)
if (ob->type == OB_MESH && armature_exported)
// for skinned mesh we write obmat in <bind_shape_matrix>
TransformWriter::add_node_transform_identity(colladaNode);
- else
- TransformWriter::add_node_transform_ob(colladaNode, ob);
+ else {
+ TransformWriter::add_node_transform_ob(colladaNode, ob, this->transformation_type);
+ }
// <instance_geometry>
if (ob->type == OB_MESH) {
diff --git a/source/blender/collada/SceneExporter.h b/source/blender/collada/SceneExporter.h
index f438c002f91..c7c15dba2cb 100644
--- a/source/blender/collada/SceneExporter.h
+++ b/source/blender/collada/SceneExporter.h
@@ -97,8 +97,10 @@ class SceneExporter: COLLADASW::LibraryVisualScenes, protected TransformWriter,
public:
SceneExporter(COLLADASW::StreamWriter *sw, ArmatureExporter *arm, const ExportSettings *export_settings);
void exportScene(Scene *sce);
+ void setExportTransformationType(BC_export_transformation_type transformation_type);
private:
+ BC_export_transformation_type transformation_type;
// required for writeNodes() for bone-parented objects
friend class ArmatureExporter;
void exportHierarchy(Scene *sce);
diff --git a/source/blender/collada/TransformWriter.cpp b/source/blender/collada/TransformWriter.cpp
index fa813e0b961..e1c32482835 100644
--- a/source/blender/collada/TransformWriter.cpp
+++ b/source/blender/collada/TransformWriter.cpp
@@ -51,13 +51,17 @@ void TransformWriter::add_node_transform(COLLADASW::Node& node, float mat[4][4],
converter->mat4_to_dae_double(dmat, local);
TransformBase::decompose(local, loc, rot, NULL, scale);
- //if (node.getType() == COLLADASW::Node::JOINT)
- node.addMatrix("transform", dmat);
- //else
- //add_transform(node, loc, rot, scale);
+
+ if (node.getType() == COLLADASW::Node::JOINT) {
+ // XXX Why are joints handled differently ?
+ node.addMatrix("transform", dmat);
+ }
+ else {
+ add_transform(node, loc, rot, scale);
+ }
}
-void TransformWriter::add_node_transform_ob(COLLADASW::Node& node, Object *ob)
+void TransformWriter::add_node_transform_ob(COLLADASW::Node& node, Object *ob, BC_export_transformation_type transformation_type)
{
#if 0
float rot[3], loc[3], scale[3];
@@ -114,8 +118,23 @@ void TransformWriter::add_node_transform_ob(COLLADASW::Node& node, Object *ob)
double d_obmat[4][4];
converter.mat4_to_dae_double(d_obmat, ob->obmat);
- node.addMatrix("transform",d_obmat);
- //add_transform(node, ob->loc, ob->rot, ob->size);
+
+ switch (transformation_type) {
+ case BC_TRANSFORMATION_TYPE_MATRIX : {
+ node.addMatrix("transform",d_obmat);
+ break;
+ }
+ case BC_TRANSFORMATION_TYPE_TRANSROTLOC: {
+ add_transform(node, ob->loc, ob->rot, ob->size);
+ break;
+ }
+ case BC_TRANSFORMATION_TYPE_BOTH : {
+ node.addMatrix("transform",d_obmat);
+ add_transform(node, ob->loc, ob->rot, ob->size);
+ break;
+ }
+ }
+
}
void TransformWriter::add_node_transform_identity(COLLADASW::Node& node)
diff --git a/source/blender/collada/TransformWriter.h b/source/blender/collada/TransformWriter.h
index d2a4b54a570..7f69a4b9c95 100644
--- a/source/blender/collada/TransformWriter.h
+++ b/source/blender/collada/TransformWriter.h
@@ -33,13 +33,14 @@
#include "DNA_object_types.h"
#include "collada_internal.h"
+#include "collada.h"
class TransformWriter : protected TransformBase
{
protected:
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);
+ void add_node_transform_ob(COLLADASW::Node& node, Object *ob, BC_export_transformation_type transformation_type);
void add_node_transform_identity(COLLADASW::Node& node);
diff --git a/source/blender/collada/collada.cpp b/source/blender/collada/collada.cpp
index e75123c1e76..1eb5ac6ca4d 100644
--- a/source/blender/collada/collada.cpp
+++ b/source/blender/collada/collada.cpp
@@ -78,6 +78,7 @@ int collada_export(Scene *sce,
int triangulate,
int use_object_instantiation,
int sort_by_name,
+ BC_export_transformation_type export_transformation_type,
int second_life)
{
ExportSettings export_settings;
@@ -85,7 +86,7 @@ int collada_export(Scene *sce,
/* annoying, collada crashes if file cant be created! [#27162] */
if (!BLI_exists(filepath)) {
BLI_make_existing_file(filepath); /* makes the dir if its not there */
- if (BLI_file_touch(filepath) == 0) {
+ if (!BLI_file_touch(filepath)) {
fprintf(stdout, "Collada export: Can not create: %s\n", filepath);
return 0;
}
@@ -107,10 +108,11 @@ int collada_export(Scene *sce,
export_settings.include_material_textures= include_material_textures != 0;
export_settings.use_texture_copies = use_texture_copies != 0;
- export_settings.triangulate = triangulate != 0;
- export_settings.use_object_instantiation = use_object_instantiation != 0;
- export_settings.sort_by_name = sort_by_name != 0;
- export_settings.second_life = second_life != 0;
+ export_settings.triangulate = triangulate != 0;
+ export_settings.use_object_instantiation = use_object_instantiation != 0;
+ export_settings.sort_by_name = sort_by_name != 0;
+ export_settings.export_transformation_type = export_transformation_type;
+ export_settings.second_life = second_life != 0;
int includeFilter = OB_REL_NONE;
diff --git a/source/blender/collada/collada.h b/source/blender/collada/collada.h
index 642259da7fc..b3a8156b6fe 100644
--- a/source/blender/collada/collada.h
+++ b/source/blender/collada/collada.h
@@ -41,6 +41,12 @@ typedef enum BC_export_mesh_type {
BC_MESH_TYPE_RENDER
} BC_export_mesh_type;
+typedef enum BC_export_transformation_type {
+ BC_TRANSFORMATION_TYPE_MATRIX,
+ BC_TRANSFORMATION_TYPE_TRANSROTLOC,
+ BC_TRANSFORMATION_TYPE_BOTH
+} BC_export_transformation_type;
+
struct bContext;
struct Scene;
@@ -48,8 +54,8 @@ struct Scene;
* both return 1 on success, 0 on error
*/
int collada_import(bContext *C,
- const char *filepath,
- int import_units);
+ const char *filepath,
+ int import_units);
int collada_export(Scene *sce,
const char *filepath,
@@ -62,14 +68,15 @@ int collada_export(Scene *sce,
int include_shapekeys,
int deform_bones_only,
- int active_uv_only,
- int include_uv_textures,
- int include_material_textures,
- int use_texture_copies,
+ int active_uv_only,
+ int include_uv_textures,
+ int include_material_textures,
+ int use_texture_copies,
int triangulate,
int use_object_instantiation,
int sort_by_name,
+ BC_export_transformation_type export_transformation_type,
int second_life);
diff --git a/source/blender/collada/collada_internal.cpp b/source/blender/collada/collada_internal.cpp
index 85f98dad437..c3df2f0dc2f 100644
--- a/source/blender/collada/collada_internal.cpp
+++ b/source/blender/collada/collada_internal.cpp
@@ -224,6 +224,12 @@ void clear_global_id_map()
}
/** Look at documentation of translate_map */
+std::string translate_id(const char *idString)
+{
+ std::string id = std::string(idString);
+ return translate_id(id);
+}
+
std::string translate_id(const std::string &id)
{
if (id.size() == 0) {
diff --git a/source/blender/collada/collada_internal.h b/source/blender/collada/collada_internal.h
index 7d59932bac9..2e855764f4b 100644
--- a/source/blender/collada/collada_internal.h
+++ b/source/blender/collada/collada_internal.h
@@ -92,6 +92,7 @@ public:
extern void clear_global_id_map();
/** Look at documentation of translate_map */
extern std::string translate_id(const std::string &id);
+extern std::string translate_id(const char *idString);
extern std::string id_name(void *id);
diff --git a/source/blender/collada/collada_utils.cpp b/source/blender/collada/collada_utils.cpp
index c56aa3fdaf0..66f7feb8928 100644
--- a/source/blender/collada/collada_utils.cpp
+++ b/source/blender/collada/collada_utils.cpp
@@ -116,11 +116,11 @@ int bc_set_parent(Object *ob, Object *par, bContext *C, bool is_parent_space)
DAG_id_tag_update(&ob->id, OB_RECALC_OB | OB_RECALC_DATA);
DAG_id_tag_update(&par->id, OB_RECALC_OB);
- /** done once after import
+ /** done once after import */
+#if 0
DAG_relations_tag_update(bmain);
WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, NULL);
- */
-
+#endif
return true;
}
@@ -299,15 +299,17 @@ int bc_get_active_UVLayer(Object *ob)
return CustomData_get_active_layer_index(&me->fdata, CD_MTFACE);
}
-std::string bc_url_encode(std::string data) {
+std::string bc_url_encode(std::string data)
+{
/* XXX We probably do not need to do a full encoding.
- But in case that is necessary,then it can be added here.
- */
+ * But in case that is necessary,then it can be added here.
+ */
return bc_replace_string(data,"#", "%23");
}
std::string bc_replace_string(std::string data, const std::string& pattern,
- const std::string& replacement) {
+ const std::string& replacement)
+{
size_t pos = 0;
while((pos = data.find(pattern, pos)) != std::string::npos) {
data.replace(pos, pattern.length(), replacement);
@@ -317,15 +319,15 @@ std::string bc_replace_string(std::string data, const std::string& pattern,
}
/**
- Calculate a rescale factor such that the imported scene's scale
- is preserved. I.e. 1 meter in the import will also be
- 1 meter in the current scene.
- XXX : I am not sure if it is correct to map 1 Blender Unit
- to 1 Meter for unit type NONE. But it looks reasonable to me.
-*/
+ * Calculate a rescale factor such that the imported scene's scale
+ * is preserved. I.e. 1 meter in the import will also be
+ * 1 meter in the current scene.
+ * XXX : I am not sure if it is correct to map 1 Blender Unit
+ * to 1 Meter for unit type NONE. But it looks reasonable to me.
+ */
void bc_match_scale(std::vector<Object *> *objects_done,
- Scene &sce,
- UnitConverter &bc_unit) {
+ Scene &sce,
+ UnitConverter &bc_unit) {
Object *ob = NULL;
diff --git a/source/blender/compositor/COM_compositor.h b/source/blender/compositor/COM_compositor.h
index a64583b68ff..fc546188816 100644
--- a/source/blender/compositor/COM_compositor.h
+++ b/source/blender/compositor/COM_compositor.h
@@ -20,9 +20,9 @@
* Monique Dewanchand
*/
- #ifdef __cplusplus
+#ifdef __cplusplus
extern "C" {
- #endif
+#endif
#include "DNA_color_types.h"
#include "DNA_node_types.h"
diff --git a/source/blender/compositor/intern/COM_ExecutionGroup.cpp b/source/blender/compositor/intern/COM_ExecutionGroup.cpp
index ffc36281874..14fd7e0b6cf 100644
--- a/source/blender/compositor/intern/COM_ExecutionGroup.cpp
+++ b/source/blender/compositor/intern/COM_ExecutionGroup.cpp
@@ -40,6 +40,8 @@
#include "MEM_guardedalloc.h"
#include "BLI_math.h"
+#include "BLI_string.h"
+#include "BKE_global.h"
#include "PIL_time.h"
#include "WM_api.h"
#include "WM_types.h"
@@ -60,6 +62,8 @@ ExecutionGroup::ExecutionGroup()
this->m_openCL = false;
this->m_singleThreaded = false;
this->m_chunksFinished = 0;
+ BLI_rcti_init(&this->m_viewerBorder, 0, 0, 0, 0);
+ this->m_executionStartTime = 0;
}
CompositorPriority ExecutionGroup::getRenderPriotrity()
@@ -196,6 +200,7 @@ void ExecutionGroup::determineResolution(unsigned int resolution[2])
resolution[0] = operation->getWidth();
resolution[1] = operation->getHeight();
this->setResolution(resolution);
+ BLI_rcti_init(&this->m_viewerBorder, 0, this->m_width, 0, this->m_height);
}
void ExecutionGroup::determineNumberOfChunks()
@@ -207,8 +212,10 @@ void ExecutionGroup::determineNumberOfChunks()
}
else {
const float chunkSizef = this->m_chunkSize;
- this->m_numberOfXChunks = ceil(this->m_width / chunkSizef);
- this->m_numberOfYChunks = ceil(this->m_height / chunkSizef);
+ const int border_width = BLI_rcti_size_x(&this->m_viewerBorder);
+ const int border_height = BLI_rcti_size_y(&this->m_viewerBorder);
+ this->m_numberOfXChunks = ceil(border_width / chunkSizef);
+ this->m_numberOfYChunks = ceil(border_height / chunkSizef);
this->m_numberOfChunks = this->m_numberOfXChunks * this->m_numberOfYChunks;
}
}
@@ -225,6 +232,8 @@ void ExecutionGroup::execute(ExecutionSystem *graph)
if (this->m_numberOfChunks == 0) {return; } /// @note: early break out
unsigned int chunkNumber;
+ this->m_executionStartTime = PIL_check_seconds_timer();
+
this->m_chunksFinished = 0;
this->m_bTree = bTree;
unsigned int index;
@@ -245,6 +254,9 @@ void ExecutionGroup::execute(ExecutionSystem *graph)
chunkorder = viewer->getChunkOrder();
}
+ const int border_width = BLI_rcti_size_x(&this->m_viewerBorder);
+ const int border_height = BLI_rcti_size_y(&this->m_viewerBorder);
+
switch (chunkorder) {
case COM_TO_RANDOM:
for (index = 0; index < 2 * this->m_numberOfChunks; index++) {
@@ -258,14 +270,14 @@ void ExecutionGroup::execute(ExecutionSystem *graph)
case COM_TO_CENTER_OUT:
{
ChunkOrderHotspot *hotspots[1];
- hotspots[0] = new ChunkOrderHotspot(this->m_width * centerX, this->m_height * centerY, 0.0f);
+ hotspots[0] = new ChunkOrderHotspot(border_width * centerX, border_height * centerY, 0.0f);
rcti rect;
ChunkOrder *chunkOrders = (ChunkOrder *)MEM_mallocN(sizeof(ChunkOrder) * this->m_numberOfChunks, __func__);
for (index = 0; index < this->m_numberOfChunks; index++) {
determineChunkRect(&rect, index);
chunkOrders[index].setChunkNumber(index);
- chunkOrders[index].setX(rect.xmin);
- chunkOrders[index].setY(rect.ymin);
+ chunkOrders[index].setX(rect.xmin - this->m_viewerBorder.xmin);
+ chunkOrders[index].setY(rect.ymin - this->m_viewerBorder.ymin);
chunkOrders[index].determineDistance(hotspots, 1);
}
@@ -281,10 +293,10 @@ void ExecutionGroup::execute(ExecutionSystem *graph)
case COM_TO_RULE_OF_THIRDS:
{
ChunkOrderHotspot *hotspots[9];
- unsigned int tx = this->m_width / 6;
- unsigned int ty = this->m_height / 6;
- unsigned int mx = this->m_width / 2;
- unsigned int my = this->m_height / 2;
+ unsigned int tx = border_width / 6;
+ unsigned int ty = border_height / 6;
+ unsigned int mx = border_width / 2;
+ unsigned int my = border_height / 2;
unsigned int bx = mx + 2 * tx;
unsigned int by = my + 2 * ty;
@@ -303,8 +315,8 @@ void ExecutionGroup::execute(ExecutionSystem *graph)
for (index = 0; index < this->m_numberOfChunks; index++) {
determineChunkRect(&rect, index);
chunkOrders[index].setChunkNumber(index);
- chunkOrders[index].setX(rect.xmin);
- chunkOrders[index].setY(rect.ymin);
+ chunkOrders[index].setX(rect.xmin - this->m_viewerBorder.xmin);
+ chunkOrders[index].setY(rect.ymin - this->m_viewerBorder.ymin);
chunkOrders[index].determineDistance(hotspots, 9);
}
@@ -403,6 +415,35 @@ MemoryBuffer *ExecutionGroup::constructConsolidatedMemoryBuffer(MemoryProxy *mem
return result;
}
+void ExecutionGroup::printBackgroundStats(void)
+{
+ uintptr_t mem_in_use, mmap_in_use, peak_memory;
+ float megs_used_memory, mmap_used_memory, megs_peak_memory;
+ double execution_time;
+ char timestr[64];
+
+ execution_time = PIL_check_seconds_timer() - this->m_executionStartTime;
+
+ mem_in_use = MEM_get_memory_in_use();
+ mmap_in_use = MEM_get_mapped_memory_in_use();
+ peak_memory = MEM_get_peak_memory();
+
+ megs_used_memory = (mem_in_use - mmap_in_use) / (1024.0 * 1024.0);
+ mmap_used_memory = (mmap_in_use) / (1024.0 * 1024.0);
+ megs_peak_memory = (peak_memory) / (1024.0 * 1024.0);
+
+ fprintf(stdout, "Mem:%.2fM (%.2fM, Peak %.2fM) ",
+ megs_used_memory, mmap_used_memory, megs_peak_memory);
+
+ BLI_timestr(execution_time, timestr);
+ printf("| Elapsed %s ", timestr);
+ printf("| Tree %s, Tile %d-%d ", this->m_bTree->id.name + 2,
+ this->m_chunksFinished, this->m_numberOfChunks);
+
+ fputc('\n', stdout);
+ fflush(stdout);
+}
+
void ExecutionGroup::finalizeChunkExecution(int chunkNumber, MemoryBuffer **memoryBuffers)
{
if (this->m_chunkExecutionStates[chunkNumber] == COM_ES_SCHEDULED)
@@ -426,18 +467,26 @@ void ExecutionGroup::finalizeChunkExecution(int chunkNumber, MemoryBuffer **memo
float progress = this->m_chunksFinished;
progress /= this->m_numberOfChunks;
this->m_bTree->progress(this->m_bTree->prh, progress);
+
+ if (G.background)
+ printBackgroundStats();
}
}
inline void ExecutionGroup::determineChunkRect(rcti *rect, const unsigned int xChunk, const unsigned int yChunk) const
{
+ const int border_width = BLI_rcti_size_x(&this->m_viewerBorder);
+ const int border_height = BLI_rcti_size_y(&this->m_viewerBorder);
+
if (this->m_singleThreaded) {
- BLI_rcti_init(rect, 0, this->m_width, 0, this->m_height);
+ BLI_rcti_init(rect, this->m_viewerBorder.xmin, border_width, this->m_viewerBorder.ymin, border_height);
}
else {
- const unsigned int minx = xChunk * this->m_chunkSize;
- const unsigned int miny = yChunk * this->m_chunkSize;
- BLI_rcti_init(rect, minx, min(minx + this->m_chunkSize, this->m_width), miny, min(miny + this->m_chunkSize, this->m_height));
+ const unsigned int minx = xChunk * this->m_chunkSize + this->m_viewerBorder.xmin;
+ const unsigned int miny = yChunk * this->m_chunkSize + this->m_viewerBorder.ymin;
+ const unsigned int width = min((unsigned int) this->m_viewerBorder.xmax, this->m_width);
+ const unsigned int height = min((unsigned int) this->m_viewerBorder.ymax, this->m_height);
+ BLI_rcti_init(rect, min(minx, this->m_width), min(minx + this->m_chunkSize, width), min(miny, this->m_height), min(miny + this->m_chunkSize, height));
}
}
@@ -472,9 +521,9 @@ bool ExecutionGroup::scheduleAreaWhenPossible(ExecutionSystem *graph, rcti *area
float chunkSizef = this->m_chunkSize;
int indexx, indexy;
- int minxchunk = floor(area->xmin / chunkSizef);
+ int minxchunk = floor((area->xmin - this->m_viewerBorder.xmin) / chunkSizef);
int maxxchunk = ceil((area->xmax - 1) / chunkSizef);
- int minychunk = floor(area->ymin / chunkSizef);
+ int minychunk = floor((area->ymin - this->m_viewerBorder.ymin) / chunkSizef);
int maxychunk = ceil((area->ymax - 1) / chunkSizef);
minxchunk = max(minxchunk, 0);
minychunk = max(minychunk, 0);
@@ -574,3 +623,13 @@ bool ExecutionGroup::isOpenCL()
{
return this->m_openCL;
}
+
+void ExecutionGroup::setViewerBorder(float xmin, float xmax, float ymin, float ymax)
+{
+ NodeOperation *operation = this->getOutputNodeOperation();
+
+ if (operation->isViewerOperation() || operation->isPreviewOperation()) {
+ BLI_rcti_init(&this->m_viewerBorder, xmin * this->m_width, xmax * this->m_width,
+ ymin * this->m_height, ymax * this->m_height);
+ }
+}
diff --git a/source/blender/compositor/intern/COM_ExecutionGroup.h b/source/blender/compositor/intern/COM_ExecutionGroup.h
index 00104c24194..b5f02e05be1 100644
--- a/source/blender/compositor/intern/COM_ExecutionGroup.h
+++ b/source/blender/compositor/intern/COM_ExecutionGroup.h
@@ -161,7 +161,18 @@ private:
* @see openCL
*/
bool m_initialized;
-
+
+ /**
+ * @brief denotes boundary for border compositing
+ * @note measured in pixel space
+ */
+ rcti m_viewerBorder;
+
+ /**
+ * @brief start time of execution
+ */
+ double m_executionStartTime;
+
// methods
/**
* @brief check whether parameter operation can be added to the execution group
@@ -335,6 +346,11 @@ public:
* @see determineChunkRect
*/
MemoryBuffer *allocateOutputBuffer(int chunkNumber, rcti *rect);
+
+ /**
+ * @brief print execution statistics to stdout when running in a background mode
+ */
+ void printBackgroundStats(void);
/**
* @brief after a chunk is executed the needed resources can be freed or unlocked.
@@ -395,6 +411,12 @@ public:
*/
CompositorPriority getRenderPriotrity();
+ /**
+ * @brief set border for viewer operation
+ * @note all the coordinates are assumed to be in normalized space
+ */
+ void setViewerBorder(float xmin, float xmax, float ymin, float ymax);
+
#ifdef WITH_CXX_GUARDEDALLOC
MEM_CXX_CLASS_ALLOC_FUNCS("COM:ExecutionGroup")
#endif
diff --git a/source/blender/compositor/intern/COM_ExecutionSystem.cpp b/source/blender/compositor/intern/COM_ExecutionSystem.cpp
index 1ec4ac7699b..2b2af73d0c8 100644
--- a/source/blender/compositor/intern/COM_ExecutionSystem.cpp
+++ b/source/blender/compositor/intern/COM_ExecutionSystem.cpp
@@ -78,11 +78,22 @@ ExecutionSystem::ExecutionSystem(RenderData *rd, bNodeTree *editingtree, bool re
this->groupOperations(); /* group operations in ExecutionGroups */
unsigned int index;
unsigned int resolution[2];
+
+ rctf *viewer_border = &editingtree->viewer_border;
+ bool use_viewer_border = (editingtree->flag & NTREE_VIEWER_BORDER) &&
+ viewer_border->xmin < viewer_border->xmax &&
+ viewer_border->ymin < viewer_border->ymax;
+
for (index = 0; index < this->m_groups.size(); index++) {
resolution[0] = 0;
resolution[1] = 0;
ExecutionGroup *executionGroup = this->m_groups[index];
executionGroup->determineResolution(resolution);
+
+ if (use_viewer_border) {
+ executionGroup->setViewerBorder(viewer_border->xmin, viewer_border->xmax,
+ viewer_border->ymin, viewer_border->ymax);
+ }
}
#ifdef COM_DEBUG
diff --git a/source/blender/compositor/nodes/COM_CompositorNode.cpp b/source/blender/compositor/nodes/COM_CompositorNode.cpp
index fc4dea8cee3..a78f96adfc6 100644
--- a/source/blender/compositor/nodes/COM_CompositorNode.cpp
+++ b/source/blender/compositor/nodes/COM_CompositorNode.cpp
@@ -41,10 +41,11 @@ void CompositorNode::convertToOperations(ExecutionSystem *graph, CompositorConte
compositorOperation->setSceneName(editorNode->id->name);
compositorOperation->setRenderData(context->getRenderData());
compositorOperation->setbNodeTree(context->getbNodeTree());
- compositorOperation->setIgnoreAlpha(editorNode->custom2 & 1);
+ compositorOperation->setIgnoreAlpha(editorNode->custom2 & CMP_NODE_OUTPUT_IGNORE_ALPHA);
imageSocket->relinkConnections(compositorOperation->getInputSocket(0), 0, graph);
alphaSocket->relinkConnections(compositorOperation->getInputSocket(1));
depthSocket->relinkConnections(compositorOperation->getInputSocket(2));
graph->addOperation(compositorOperation);
addPreviewOperation(graph, context, compositorOperation->getInputSocket(0));
}
+
diff --git a/source/blender/compositor/nodes/COM_MixNode.cpp b/source/blender/compositor/nodes/COM_MixNode.cpp
index ab4e464327d..3e8f1fb0f74 100644
--- a/source/blender/compositor/nodes/COM_MixNode.cpp
+++ b/source/blender/compositor/nodes/COM_MixNode.cpp
@@ -124,6 +124,16 @@ void MixNode::convertToOperations(ExecutionSystem *graph, CompositorContext *con
convertProg->setUseValueAlphaMultiply(useAlphaPremultiply);
convertProg->setUseClamp(useClamp);
+ if (color1Socket->isConnected()) {
+ convertProg->setResolutionInputSocketIndex(1);
+ }
+ else {
+ if (color2Socket->isConnected())
+ convertProg->setResolutionInputSocketIndex(2);
+ else
+ convertProg->setResolutionInputSocketIndex(0);
+ }
+
valueSocket->relinkConnections(convertProg->getInputSocket(0), 0, graph);
color1Socket->relinkConnections(convertProg->getInputSocket(1), 1, graph);
color2Socket->relinkConnections(convertProg->getInputSocket(2), 2, graph);
diff --git a/source/blender/compositor/nodes/COM_ViewerNode.cpp b/source/blender/compositor/nodes/COM_ViewerNode.cpp
index 94f3c2ebd80..8f9e58fee13 100644
--- a/source/blender/compositor/nodes/COM_ViewerNode.cpp
+++ b/source/blender/compositor/nodes/COM_ViewerNode.cpp
@@ -47,7 +47,7 @@ void ViewerNode::convertToOperations(ExecutionSystem *graph, CompositorContext *
viewerOperation->setChunkOrder((OrderOfChunks)editorNode->custom1);
viewerOperation->setCenterX(editorNode->custom3);
viewerOperation->setCenterY(editorNode->custom4);
- viewerOperation->setIgnoreAlpha(editorNode->custom2 & 1);
+ viewerOperation->setIgnoreAlpha(editorNode->custom2 & CMP_NODE_OUTPUT_IGNORE_ALPHA);
viewerOperation->setViewSettings(context->getViewSettings());
viewerOperation->setDisplaySettings(context->getDisplaySettings());
diff --git a/source/blender/compositor/operations/COM_MixBaseOperation.cpp b/source/blender/compositor/operations/COM_MixBaseOperation.cpp
index 2d40629e764..438fb84ebb7 100644
--- a/source/blender/compositor/operations/COM_MixBaseOperation.cpp
+++ b/source/blender/compositor/operations/COM_MixBaseOperation.cpp
@@ -69,29 +69,3 @@ void MixBaseOperation::deinitExecution()
this->m_inputColor1Operation = NULL;
this->m_inputColor2Operation = NULL;
}
-
-void MixBaseOperation::determineResolution(unsigned int resolution[2], unsigned int preferredResolution[2])
-{
- InputSocket *socket;
- unsigned int tempPreferredResolution[2] = {0, 0};
- unsigned int tempResolution[2];
-
- socket = this->getInputSocket(1);
- socket->determineResolution(tempResolution, tempPreferredResolution);
- if ((tempResolution[0] != 0) && (tempResolution[1] != 0)) {
- this->setResolutionInputSocketIndex(1);
- }
- else {
- socket = this->getInputSocket(2);
- tempPreferredResolution[0] = 0;
- tempPreferredResolution[1] = 0;
- socket->determineResolution(tempResolution, tempPreferredResolution);
- if ((tempResolution[0] != 0) && (tempResolution[1] != 0)) {
- this->setResolutionInputSocketIndex(2);
- }
- else {
- this->setResolutionInputSocketIndex(0);
- }
- }
- NodeOperation::determineResolution(resolution, preferredResolution);
-}
diff --git a/source/blender/compositor/operations/COM_MixBaseOperation.h b/source/blender/compositor/operations/COM_MixBaseOperation.h
index 88d1d00c2bf..75ca1c3f6c6 100644
--- a/source/blender/compositor/operations/COM_MixBaseOperation.h
+++ b/source/blender/compositor/operations/COM_MixBaseOperation.h
@@ -71,8 +71,6 @@ public:
*/
void deinitExecution();
- void determineResolution(unsigned int resolution[2], unsigned int preferredResolution[2]);
-
void setUseValueAlphaMultiply(const bool value) { this->m_valueAlphaMultiply = value; }
bool useValueAlphaMultiply() { return this->m_valueAlphaMultiply; }
void setUseClamp(bool value) { this->m_useClamp = value; }
diff --git a/source/blender/compositor/operations/COM_PreviewOperation.h b/source/blender/compositor/operations/COM_PreviewOperation.h
index 9e774d0e41b..0da6b8e4e56 100644
--- a/source/blender/compositor/operations/COM_PreviewOperation.h
+++ b/source/blender/compositor/operations/COM_PreviewOperation.h
@@ -26,6 +26,7 @@
#include "DNA_image_types.h"
#include "DNA_color_types.h"
#include "BLI_rect.h"
+#include "BKE_global.h"
class PreviewOperation : public NodeOperation {
protected:
@@ -42,7 +43,7 @@ protected:
const ColorManagedDisplaySettings *m_displaySettings;
public:
PreviewOperation(const ColorManagedViewSettings *viewSettings, const ColorManagedDisplaySettings *displaySettings);
- bool isOutputOperation(bool rendering) const { return true; }
+ bool isOutputOperation(bool rendering) const { return !G.background; }
void initExecution();
void deinitExecution();
const CompositorPriority getRenderPriority() const;
diff --git a/source/blender/compositor/operations/COM_TextureOperation.cpp b/source/blender/compositor/operations/COM_TextureOperation.cpp
index 23a3abe61ee..08f6f8ada4a 100644
--- a/source/blender/compositor/operations/COM_TextureOperation.cpp
+++ b/source/blender/compositor/operations/COM_TextureOperation.cpp
@@ -25,7 +25,7 @@
#include "BLI_listbase.h"
#include "BKE_image.h"
-TextureBaseOperation::TextureBaseOperation() : NodeOperation()
+TextureBaseOperation::TextureBaseOperation() : SingleThreadedNodeOperation()
{
this->addInputSocket(COM_DT_VECTOR); //offset
this->addInputSocket(COM_DT_VECTOR); //size
@@ -48,6 +48,7 @@ void TextureBaseOperation::initExecution()
this->m_inputOffset = getInputSocketReader(0);
this->m_inputSize = getInputSocketReader(1);
this->m_pool = BKE_image_pool_new();
+ SingleThreadedNodeOperation::initExecution();
}
void TextureBaseOperation::deinitExecution()
{
@@ -55,6 +56,7 @@ void TextureBaseOperation::deinitExecution()
this->m_inputOffset = NULL;
BKE_image_pool_free(this->m_pool);
this->m_pool = NULL;
+ SingleThreadedNodeOperation::deinitExecution();
}
void TextureBaseOperation::determineResolution(unsigned int resolution[2], unsigned int preferredResolution[2])
@@ -89,8 +91,8 @@ void TextureBaseOperation::executePixel(float output[4], float x, float y, Pixel
int retval;
const float cx = this->getWidth() / 2;
const float cy = this->getHeight() / 2;
- const float u = (cx - x) / this->getWidth() * 2;
- const float v = (cy - y) / this->getHeight() * 2;
+ const float u = (x - cx) / this->getWidth() * 2;
+ const float v = (y - cy) / this->getHeight() * 2;
this->m_inputSize->read(textureSize, x, y, sampler);
this->m_inputOffset->read(textureOffset, x, y, sampler);
@@ -115,3 +117,26 @@ void TextureBaseOperation::executePixel(float output[4], float x, float y, Pixel
output[0] = output[1] = output[2] = output[3];
}
}
+
+MemoryBuffer *TextureBaseOperation::createMemoryBuffer(rcti *rect2)
+{
+ int height = getHeight();
+ int width = getWidth();
+
+ rcti rect;
+ rect.xmin = 0;
+ rect.ymin = 0;
+ rect.xmax = width;
+ rect.ymax = height;
+ MemoryBuffer *result = new MemoryBuffer(NULL, &rect);
+
+ float *data = result->getBuffer();
+
+ for (int y = 0; y < height; y++) {
+ for (int x = 0; x < width; x++, data += 4) {
+ this->executePixel(data, x, y, COM_PS_NEAREST);
+ }
+ }
+
+ return result;
+}
diff --git a/source/blender/compositor/operations/COM_TextureOperation.h b/source/blender/compositor/operations/COM_TextureOperation.h
index 227ad37579a..fc9369099a6 100644
--- a/source/blender/compositor/operations/COM_TextureOperation.h
+++ b/source/blender/compositor/operations/COM_TextureOperation.h
@@ -24,7 +24,7 @@
#ifndef _COM_TextureOperation_h
#define _COM_TextureOperation_h
-#include "COM_NodeOperation.h"
+#include "COM_SingleThreadedNodeOperation.h"
#include "DNA_texture_types.h"
#include "BLI_listbase.h"
extern "C" {
@@ -39,7 +39,7 @@ extern "C" {
*
* @todo: rename to operation.
*/
-class TextureBaseOperation : public NodeOperation {
+class TextureBaseOperation : public SingleThreadedNodeOperation {
private:
Tex *m_texture;
const RenderData *m_rd;
@@ -59,6 +59,7 @@ protected:
*/
TextureBaseOperation();
+ MemoryBuffer *createMemoryBuffer(rcti *rect2);
public:
void executePixel(float output[4], float x, float y, PixelSampler sampler);
diff --git a/source/blender/compositor/operations/COM_TranslateOperation.cpp b/source/blender/compositor/operations/COM_TranslateOperation.cpp
index 9f6924eb428..e2582c3b67b 100644
--- a/source/blender/compositor/operations/COM_TranslateOperation.cpp
+++ b/source/blender/compositor/operations/COM_TranslateOperation.cpp
@@ -42,8 +42,6 @@ void TranslateOperation::initExecution()
this->m_inputOperation = this->getInputSocketReader(0);
this->m_inputXOperation = this->getInputSocketReader(1);
this->m_inputYOperation = this->getInputSocketReader(2);
-
- ensureDelta();
}
void TranslateOperation::deinitExecution()
diff --git a/source/blender/compositor/operations/COM_ViewerBaseOperation.h b/source/blender/compositor/operations/COM_ViewerBaseOperation.h
index 9f7e80ad6fc..7ead96b5c29 100644
--- a/source/blender/compositor/operations/COM_ViewerBaseOperation.h
+++ b/source/blender/compositor/operations/COM_ViewerBaseOperation.h
@@ -25,6 +25,7 @@
#include "COM_NodeOperation.h"
#include "DNA_image_types.h"
#include "BLI_rect.h"
+#include "BKE_global.h"
class ViewerBaseOperation : public NodeOperation {
protected:
@@ -45,7 +46,7 @@ protected:
const ColorManagedDisplaySettings *m_displaySettings;
public:
- bool isOutputOperation(bool rendering) const { return isActiveViewerOutput(); }
+ bool isOutputOperation(bool rendering) const { if (G.background) return false; return isActiveViewerOutput(); }
void initExecution();
void deinitExecution();
void setImage(Image *image) { this->m_image = image; }
diff --git a/source/blender/editors/animation/anim_channels_defines.c b/source/blender/editors/animation/anim_channels_defines.c
index 533420ad641..d6188720cdf 100644
--- a/source/blender/editors/animation/anim_channels_defines.c
+++ b/source/blender/editors/animation/anim_channels_defines.c
@@ -384,6 +384,10 @@ static short acf_generic_dataexpand_setting_valid(bAnimContext *ac, bAnimListEle
case ACHANNEL_SETTING_MUTE:
return ((ac) && (ac->spacetype == SPACE_NLA));
+ /* select is ok for most "ds*" channels (e.g. dsmat) */
+ case ACHANNEL_SETTING_SELECT:
+ return 1;
+
/* other flags are never supported */
default:
return 0;
@@ -425,7 +429,7 @@ static void acf_summary_backdrop(bAnimContext *ac, bAnimListElem *ale, float ymi
static void acf_summary_name(bAnimListElem *UNUSED(ale), char *name)
{
if (name)
- BLI_strncpy(name, "DopeSheet Summary", ANIM_CHAN_NAME_SIZE);
+ BLI_strncpy(name, IFACE_("DopeSheet Summary"), ANIM_CHAN_NAME_SIZE);
}
// FIXME: this is really a temp icon I think
@@ -896,6 +900,27 @@ static void acf_fcurve_name(bAnimListElem *ale, char *name)
getname_anim_fcurve(name, ale->id, ale->data);
}
+/* "name" property for fcurve entries */
+static short acf_fcurve_name_prop(bAnimListElem *ale, PointerRNA *ptr, PropertyRNA **prop)
+{
+ FCurve *fcu = (FCurve *)ale->data;
+
+ /* Ctrl-Click Usability Convenience Hack:
+ * For disabled F-Curves, allow access to the RNA Path
+ * as our "name" so that user can perform quick fixes
+ */
+ if (fcu->flag & FCURVE_DISABLED) {
+ RNA_pointer_create(ale->id, &RNA_FCurve, ale->data, ptr);
+ *prop = RNA_struct_find_property(ptr, "data_path");
+ }
+ else {
+ /* for "normal" F-Curves - no editable name, but *prop may not be set properly yet... */
+ *prop = NULL;
+ }
+
+ return (*prop != NULL);
+}
+
/* check if some setting exists for this channel */
static short acf_fcurve_setting_valid(bAnimContext *ac, bAnimListElem *ale, int setting)
{
@@ -967,7 +992,7 @@ static bAnimChannelType ACF_FCURVE =
acf_generic_group_offset, /* offset */
acf_fcurve_name, /* name */
- NULL, /* name prop */
+ acf_fcurve_name_prop, /* name prop */
NULL, /* icon */
acf_fcurve_setting_valid, /* has setting */
@@ -1070,7 +1095,7 @@ static int acf_filldrivers_icon(bAnimListElem *UNUSED(ale))
static void acf_filldrivers_name(bAnimListElem *UNUSED(ale), char *name)
{
- BLI_strncpy(name, "Drivers", ANIM_CHAN_NAME_SIZE);
+ BLI_strncpy(name, IFACE_("Drivers"), ANIM_CHAN_NAME_SIZE);
}
/* check if some setting exists for this channel */
@@ -2338,7 +2363,7 @@ static void acf_shapekey_name(bAnimListElem *ale, char *name)
if (kb->name[0])
BLI_strncpy(name, kb->name, ANIM_CHAN_NAME_SIZE);
else
- BLI_snprintf(name, ANIM_CHAN_NAME_SIZE, "Key %d", ale->index);
+ BLI_snprintf(name, ANIM_CHAN_NAME_SIZE, IFACE_("Key %d"), ale->index);
}
}
@@ -3490,10 +3515,13 @@ void ANIM_channel_draw_widgets(bContext *C, bAnimContext *ac, bAnimListElem *ale
/* if rename index matches, add widget for this */
if (ac->ads->renameIndex == channel_index + 1) {
- PointerRNA ptr;
- PropertyRNA *prop;
+ PointerRNA ptr = {{NULL}};
+ PropertyRNA *prop = NULL;
- /* draw renaming widget if we can get RNA pointer for it */
+ /* draw renaming widget if we can get RNA pointer for it
+ * NOTE: property may only be available in some cases, even if we have
+ * a callback available (e.g. broken F-Curve rename)
+ */
if (acf->name_prop(ale, &ptr, &prop)) {
uiBut *but;
diff --git a/source/blender/editors/animation/anim_channels_edit.c b/source/blender/editors/animation/anim_channels_edit.c
index 15a8222dec2..dd18d07732d 100644
--- a/source/blender/editors/animation/anim_channels_edit.c
+++ b/source/blender/editors/animation/anim_channels_edit.c
@@ -2272,7 +2272,7 @@ static void rename_anim_channels(bAnimContext *ac, int channel_index)
ED_region_tag_redraw(ac->ar);
}
-static int animchannels_rename_invoke(bContext *C, wmOperator *UNUSED(op), wmEvent *evt)
+static int animchannels_rename_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *event)
{
bAnimContext ac;
ARegion *ar;
@@ -2293,7 +2293,7 @@ static int animchannels_rename_invoke(bContext *C, wmOperator *UNUSED(op), wmEve
* so that the tops of channels get caught ok. Since ACHANNEL_FIRST is really ACHANNEL_HEIGHT, we simply use
* ACHANNEL_HEIGHT_HALF.
*/
- UI_view2d_region_to_view(v2d, evt->mval[0], evt->mval[1], &x, &y);
+ UI_view2d_region_to_view(v2d, event->mval[0], event->mval[1], &x, &y);
if (ac.datatype == ANIMCONT_NLA) {
SpaceNla *snla = (SpaceNla *)ac.sl;
@@ -2609,7 +2609,7 @@ static int mouse_anim_channels(bAnimContext *ac, float UNUSED(x), int channel_in
/* ------------------- */
/* handle clicking */
-static int animchannels_mouseclick_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int animchannels_mouseclick_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
bAnimContext ac;
ARegion *ar;
@@ -2667,7 +2667,7 @@ static void ANIM_OT_channels_click(wmOperatorType *ot)
ot->poll = animedit_poll_channels_active;
/* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ ot->flag = OPTYPE_UNDO;
/* properties */
/* NOTE: don't save settings, otherwise, can end up with some weird behaviour (sticky extend) */
diff --git a/source/blender/editors/animation/anim_filter.c b/source/blender/editors/animation/anim_filter.c
index 3480db2c5d8..7648d998216 100644
--- a/source/blender/editors/animation/anim_filter.c
+++ b/source/blender/editors/animation/anim_filter.c
@@ -449,7 +449,7 @@ short ANIM_animdata_get_context(const bContext *C, bAnimContext *ac)
if (ANIMDATA_HAS_NLA(id)) { \
nlaOk \
} \
- else if (!(ads->filterflag & ADS_FILTER_NLA_NOACT) && ANIMDATA_HAS_KEYS(id)) { \
+ else if (!(ads->filterflag & ADS_FILTER_NLA_NOACT) || ANIMDATA_HAS_KEYS(id)) { \
nlaOk \
} \
} \
@@ -1001,22 +1001,39 @@ static short skip_fcurve_with_name(bDopeSheet *ads, FCurve *fcu, ID *owner_id)
/* Check if F-Curve has errors and/or is disabled
* > returns: (bool) True if F-Curve has errors/is disabled
*/
-static short fcurve_has_errors(FCurve *fcu)
+static bool fcurve_has_errors(FCurve *fcu)
{
/* F-Curve disabled - path eval error */
if (fcu->flag & FCURVE_DISABLED) {
- return 1;
+ return true;
}
/* driver? */
if (fcu->driver) {
- /* for now, just check if the entire thing got disabled... */
- if (fcu->driver->flag & DRIVER_FLAG_INVALID)
- return 1;
+ ChannelDriver *driver = fcu->driver;
+ DriverVar *dvar;
+
+ /* error flag on driver usually means that there is an error
+ * BUT this may not hold with PyDrivers as this flag gets cleared
+ * if no critical errors prevent the driver from working...
+ */
+ if (driver->flag & DRIVER_FLAG_INVALID)
+ return true;
+
+ /* check variables for other things that need linting... */
+ // TODO: maybe it would be more efficient just to have a quick flag for this?
+ for (dvar = driver->variables.first; dvar; dvar = dvar->next) {
+ DRIVER_TARGETS_USED_LOOPER(dvar)
+ {
+ if (dtar->flag & DTAR_FLAG_INVALID)
+ return true;
+ }
+ DRIVER_TARGETS_LOOPER_END
+ }
}
/* no errors found */
- return 0;
+ return false;
}
/* find the next F-Curve that is usable for inclusion */
@@ -1060,7 +1077,7 @@ static FCurve *animfilter_fcurve_next(bDopeSheet *ads, FCurve *first, bActionGro
/* error-based filtering... */
if ((ads) && (ads->filterflag & ADS_FILTER_ONLY_ERRORS)) {
/* skip if no errors... */
- if (fcurve_has_errors(fcu) == 0)
+ if (fcurve_has_errors(fcu) == false)
continue;
}
@@ -1297,7 +1314,9 @@ static size_t animfilter_block_data(bAnimContext *ac, ListBase *anim_data, bDope
ANIMDATA_FILTER_CASES(iat,
{ /* AnimData */
/* specifically filter animdata block */
- ANIMCHANNEL_NEW_CHANNEL(adt, ANIMTYPE_ANIMDATA, id);
+ if (ANIMCHANNEL_SELOK(SEL_ANIMDATA(adt)) ) {
+ ANIMCHANNEL_NEW_CHANNEL(adt, ANIMTYPE_ANIMDATA, id);
+ }
},
{ /* NLA */
items += animfilter_nla(ac, anim_data, ads, adt, filter_mode, id);
@@ -1347,7 +1366,9 @@ static size_t animdata_filter_shapekey(bAnimContext *ac, ListBase *anim_data, Ke
// TODO: somehow manage to pass dopesheet info down here too?
if (key->adt) {
if (filter_mode & ANIMFILTER_ANIMDATA) {
- ANIMCHANNEL_NEW_CHANNEL(key->adt, ANIMTYPE_ANIMDATA, key);
+ if (ANIMCHANNEL_SELOK(SEL_ANIMDATA(key->adt)) ) {
+ ANIMCHANNEL_NEW_CHANNEL(key->adt, ANIMTYPE_ANIMDATA, key);
+ }
}
else if (key->adt->action) {
items = animfilter_action(ac, anim_data, NULL, key->adt->action, filter_mode, (ID *)key);
diff --git a/source/blender/editors/animation/anim_ipo_utils.c b/source/blender/editors/animation/anim_ipo_utils.c
index b6d24e21057..2352cad0cbc 100644
--- a/source/blender/editors/animation/anim_ipo_utils.c
+++ b/source/blender/editors/animation/anim_ipo_utils.c
@@ -42,6 +42,8 @@
#include "BLI_math.h"
#include "BLI_utildefines.h"
+#include "BLF_translation.h"
+
#include "DNA_anim_types.h"
#include "RNA_access.h"
@@ -63,9 +65,9 @@ int getname_anim_fcurve(char *name, ID *id, FCurve *fcu)
return icon;
else if (ELEM3(NULL, id, fcu, fcu->rna_path)) {
if (fcu == NULL)
- strcpy(name, "<invalid>");
+ strcpy(name, IFACE_("<invalid>"));
else if (fcu->rna_path == NULL)
- strcpy(name, "<no path>");
+ strcpy(name, IFACE_("<no path>"));
else /* id == NULL */
BLI_snprintf(name, 256, "%s[%d]", fcu->rna_path, fcu->array_index);
}
diff --git a/source/blender/editors/animation/anim_markers.c b/source/blender/editors/animation/anim_markers.c
index 62725cb6c70..7a3fc3a8d9b 100644
--- a/source/blender/editors/animation/anim_markers.c
+++ b/source/blender/editors/animation/anim_markers.c
@@ -28,7 +28,6 @@
* \ingroup edanimation
*/
-
#include <math.h>
#include "MEM_guardedalloc.h"
@@ -36,10 +35,6 @@
#include "DNA_scene_types.h"
#include "DNA_object_types.h"
-#include "RNA_access.h"
-#include "RNA_define.h"
-#include "RNA_enum_types.h"
-
#include "BLI_blenlib.h"
#include "BLI_math_base.h"
#include "BLI_utildefines.h"
@@ -51,6 +46,10 @@
#include "BKE_scene.h"
#include "BKE_screen.h"
+#include "RNA_access.h"
+#include "RNA_define.h"
+#include "RNA_enum_types.h"
+
#include "WM_api.h"
#include "WM_types.h"
@@ -277,7 +276,9 @@ static void add_marker_to_cfra_elem(ListBase *lb, TimeMarker *marker, short only
ce->sel = marker->flag;
return;
}
- else if (ce->cfra > marker->frame) break;
+ else if (ce->cfra > marker->frame) {
+ break;
+ }
}
cen = MEM_callocN(sizeof(CfraElem), "add_to_cfra_elem");
@@ -513,8 +514,8 @@ static int ed_markers_poll_markers_exist(bContext *C)
* that operator would otherwise have used. If NULL, the operator's standard
* exec() callback will be called instead in the appropriate places.
*/
-static int ed_markers_opwrap_invoke_custom(bContext *C, wmOperator *op, wmEvent *evt,
- int (*invoke_func)(bContext *, wmOperator *, wmEvent *))
+static int ed_markers_opwrap_invoke_custom(bContext *C, wmOperator *op, const wmEvent *event,
+ int (*invoke_func)(bContext *, wmOperator *, const wmEvent *))
{
ScrArea *sa = CTX_wm_area(C);
int retval = OPERATOR_PASS_THROUGH;
@@ -523,7 +524,7 @@ static int ed_markers_opwrap_invoke_custom(bContext *C, wmOperator *op, wmEvent
/* allow operator to run now */
if (invoke_func)
- retval = invoke_func(C, op, evt);
+ retval = invoke_func(C, op, event);
else if (op->type->exec)
retval = op->type->exec(C, op);
else
@@ -544,9 +545,9 @@ static int ed_markers_opwrap_invoke_custom(bContext *C, wmOperator *op, wmEvent
* though will need to implement their own wrapper which calls the second-tier callback themselves
* (passing through the custom invoke function they use)
*/
-static int ed_markers_opwrap_invoke(bContext *C, wmOperator *op, wmEvent *evt)
+static int ed_markers_opwrap_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
- return ed_markers_opwrap_invoke_custom(C, op, evt, NULL);
+ return ed_markers_opwrap_invoke_custom(C, op, event, NULL);
}
/* ************************** add markers *************************** */
@@ -684,14 +685,14 @@ static void ed_marker_move_exit(bContext *C, wmOperator *op)
ED_area_headerprint(CTX_wm_area(C), NULL);
}
-static int ed_marker_move_invoke(bContext *C, wmOperator *op, wmEvent *evt)
+static int ed_marker_move_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
if (ed_marker_move_init(C, op)) {
MarkerMove *mm = op->customdata;
- mm->evtx = evt->x;
- mm->firstx = evt->x;
- mm->event_type = evt->type;
+ mm->evtx = event->x;
+ mm->firstx = event->x;
+ mm->event_type = event->type;
/* add temp handler */
WM_event_add_modal_handler(C, op);
@@ -705,9 +706,9 @@ static int ed_marker_move_invoke(bContext *C, wmOperator *op, wmEvent *evt)
return OPERATOR_CANCELLED;
}
-static int ed_marker_move_invoke_wrapper(bContext *C, wmOperator *op, wmEvent *evt)
+static int ed_marker_move_invoke_wrapper(bContext *C, wmOperator *op, const wmEvent *event)
{
- return ed_markers_opwrap_invoke_custom(C, op, evt, ed_marker_move_invoke);
+ return ed_markers_opwrap_invoke_custom(C, op, event, ed_marker_move_invoke);
}
/* note, init has to be called succesfully */
@@ -756,7 +757,7 @@ static int ed_marker_move_cancel(bContext *C, wmOperator *op)
-static int ed_marker_move_modal(bContext *C, wmOperator *op, wmEvent *evt)
+static int ed_marker_move_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
Scene *scene = CTX_data_scene(C);
MarkerMove *mm = op->customdata;
@@ -765,14 +766,14 @@ static int ed_marker_move_modal(bContext *C, wmOperator *op, wmEvent *evt)
float dx, fac;
char str[256];
- switch (evt->type) {
+ switch (event->type) {
case ESCKEY:
ed_marker_move_cancel(C, op);
return OPERATOR_CANCELLED;
case RIGHTMOUSE:
/* press = user manually demands transform to be canceled */
- if (evt->val == KM_PRESS) {
+ if (event->val == KM_PRESS) {
ed_marker_move_cancel(C, op);
return OPERATOR_CANCELLED;
}
@@ -782,7 +783,7 @@ static int ed_marker_move_modal(bContext *C, wmOperator *op, wmEvent *evt)
case PADENTER:
case LEFTMOUSE:
case MIDDLEMOUSE:
- if (WM_modal_tweak_exit(evt, mm->event_type)) {
+ if (WM_modal_tweak_exit(event, mm->event_type)) {
ed_marker_move_exit(C, op);
WM_event_add_notifier(C, NC_SCENE | ND_MARKERS, NULL);
WM_event_add_notifier(C, NC_ANIMATION | ND_MARKERS, NULL);
@@ -795,17 +796,17 @@ static int ed_marker_move_modal(bContext *C, wmOperator *op, wmEvent *evt)
dx = BLI_rctf_size_x(&v2d->cur) / BLI_rcti_size_x(&v2d->mask);
- if (evt->x != mm->evtx) { /* XXX maybe init for first time */
+ if (event->x != mm->evtx) { /* XXX maybe init for first time */
int a, offs, totmark = 0;
- mm->evtx = evt->x;
+ mm->evtx = event->x;
- fac = ((float)(evt->x - mm->firstx) * dx);
+ fac = ((float)(event->x - mm->firstx) * dx);
if (mm->slink->spacetype == SPACE_TIME)
- apply_keyb_grid(evt->shift, evt->ctrl, &fac, 0.0, FPS, 0.1 * FPS, 0);
+ apply_keyb_grid(event->shift, event->ctrl, &fac, 0.0, FPS, 0.1 * FPS, 0);
else
- apply_keyb_grid(evt->shift, evt->ctrl, &fac, 0.0, 1.0, 0.1, 0 /*was: U.flag & USER_AUTOGRABGRID*/);
+ apply_keyb_grid(event->shift, event->ctrl, &fac, 0.0, 1.0, 0.1, 0 /*was: U.flag & USER_AUTOGRABGRID*/);
offs = (int)fac;
RNA_int_set(op->ptr, "frames", offs);
@@ -864,8 +865,8 @@ static int ed_marker_move_modal(bContext *C, wmOperator *op, wmEvent *evt)
}
}
- if (evt->val == KM_PRESS) {
- if (handleNumInput(&mm->num, evt)) {
+ if (event->val == KM_PRESS) {
+ if (handleNumInput(&mm->num, event)) {
char str_tx[NUM_STR_REP_LEN];
float value = RNA_int_get(op->ptr, "frames");
applyNumInput(&mm->num, &value);
@@ -981,15 +982,15 @@ static int ed_marker_duplicate_exec(bContext *C, wmOperator *op)
}
-static int ed_marker_duplicate_invoke(bContext *C, wmOperator *op, wmEvent *evt)
+static int ed_marker_duplicate_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
ed_marker_duplicate_apply(C);
- return ed_marker_move_invoke(C, op, evt);
+ return ed_marker_move_invoke(C, op, event);
}
-static int ed_marker_duplicate_invoke_wrapper(bContext *C, wmOperator *op, wmEvent *evt)
+static int ed_marker_duplicate_invoke_wrapper(bContext *C, wmOperator *op, const wmEvent *event)
{
- return ed_markers_opwrap_invoke_custom(C, op, evt, ed_marker_duplicate_invoke);
+ return ed_markers_opwrap_invoke_custom(C, op, event, ed_marker_duplicate_invoke);
}
static void MARKER_OT_duplicate(wmOperatorType *ot)
@@ -1036,7 +1037,7 @@ static void select_timeline_marker_frame(ListBase *markers, int frame, unsigned
}
}
-static int ed_marker_select(bContext *C, wmEvent *evt, int extend, int camera)
+static int ed_marker_select(bContext *C, const wmEvent *event, int extend, int camera)
{
ListBase *markers = ED_context_get_markers(C);
ARegion *ar = CTX_wm_region(C);
@@ -1047,8 +1048,8 @@ static int ed_marker_select(bContext *C, wmEvent *evt, int extend, int camera)
if (markers == NULL)
return OPERATOR_PASS_THROUGH;
- x = evt->x - ar->winrct.xmin;
- y = evt->y - ar->winrct.ymin;
+ x = event->x - ar->winrct.xmin;
+ y = event->y - ar->winrct.ymin;
UI_view2d_region_to_view(v2d, x, y, &viewx, NULL);
@@ -1103,19 +1104,19 @@ static int ed_marker_select(bContext *C, wmEvent *evt, int extend, int camera)
return OPERATOR_FINISHED | OPERATOR_PASS_THROUGH;
}
-static int ed_marker_select_invoke(bContext *C, wmOperator *op, wmEvent *evt)
+static int ed_marker_select_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
short extend = RNA_boolean_get(op->ptr, "extend");
short camera = 0;
#ifdef DURIAN_CAMERA_SWITCH
camera = RNA_boolean_get(op->ptr, "camera");
#endif
- return ed_marker_select(C, evt, extend, camera);
+ return ed_marker_select(C, event, extend, camera);
}
-static int ed_marker_select_invoke_wrapper(bContext *C, wmOperator *op, wmEvent *evt)
+static int ed_marker_select_invoke_wrapper(bContext *C, wmOperator *op, const wmEvent *event)
{
- return ed_markers_opwrap_invoke_custom(C, op, evt, ed_marker_select_invoke);
+ return ed_markers_opwrap_invoke_custom(C, op, event, ed_marker_select_invoke);
}
static void MARKER_OT_select(wmOperatorType *ot)
@@ -1200,9 +1201,9 @@ static int ed_marker_border_select_exec(bContext *C, wmOperator *op)
return 1;
}
-static int ed_marker_select_border_invoke_wrapper(bContext *C, wmOperator *op, wmEvent *evt)
+static int ed_marker_select_border_invoke_wrapper(bContext *C, wmOperator *op, const wmEvent *event)
{
- return ed_markers_opwrap_invoke_custom(C, op, evt, WM_border_select_invoke);
+ return ed_markers_opwrap_invoke_custom(C, op, event, WM_border_select_invoke);
}
static void MARKER_OT_select_border(wmOperatorType *ot)
@@ -1309,10 +1310,10 @@ static int ed_marker_delete_exec(bContext *C, wmOperator *UNUSED(op))
return OPERATOR_FINISHED;
}
-static int ed_marker_delete_invoke_wrapper(bContext *C, wmOperator *op, wmEvent *evt)
+static int ed_marker_delete_invoke_wrapper(bContext *C, wmOperator *op, const wmEvent *event)
{
// XXX: must we keep these confirmations?
- return ed_markers_opwrap_invoke_custom(C, op, evt, WM_operator_confirm);
+ return ed_markers_opwrap_invoke_custom(C, op, event, WM_operator_confirm);
}
static void MARKER_OT_delete(wmOperatorType *ot)
@@ -1352,7 +1353,7 @@ static int ed_marker_rename_exec(bContext *C, wmOperator *op)
}
}
-static int ed_marker_rename_invoke_wrapper(bContext *C, wmOperator *op, wmEvent *evt)
+static int ed_marker_rename_invoke_wrapper(bContext *C, wmOperator *op, const wmEvent *event)
{
/* must initialize the marker name first if there is a marker selected */
TimeMarker *marker = ED_markers_get_first_selected(ED_context_get_markers(C));
@@ -1360,7 +1361,7 @@ static int ed_marker_rename_invoke_wrapper(bContext *C, wmOperator *op, wmEvent
RNA_string_set(op->ptr, "name", marker->name);
/* now see if the operator is usable */
- return ed_markers_opwrap_invoke_custom(C, op, evt, WM_operator_props_popup);
+ return ed_markers_opwrap_invoke_custom(C, op, event, WM_operator_props_popup);
}
static void MARKER_OT_rename(wmOperatorType *ot)
@@ -1414,9 +1415,9 @@ static int ed_marker_make_links_scene_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int ed_marker_make_links_scene_invoke_wrapper(bContext *C, wmOperator *op, wmEvent *evt)
+static int ed_marker_make_links_scene_invoke_wrapper(bContext *C, wmOperator *op, const wmEvent *event)
{
- return ed_markers_opwrap_invoke_custom(C, op, evt, WM_menu_invoke);
+ return ed_markers_opwrap_invoke_custom(C, op, event, WM_menu_invoke);
}
static void MARKER_OT_make_links_scene(wmOperatorType *ot)
diff --git a/source/blender/editors/animation/anim_ops.c b/source/blender/editors/animation/anim_ops.c
index 6687cce88cd..b9a3daa4e51 100644
--- a/source/blender/editors/animation/anim_ops.c
+++ b/source/blender/editors/animation/anim_ops.c
@@ -115,7 +115,7 @@ static int change_frame_exec(bContext *C, wmOperator *op)
/* ---- */
/* Get frame from mouse coordinates */
-static int frame_from_event(bContext *C, wmEvent *event)
+static int frame_from_event(bContext *C, const wmEvent *event)
{
ARegion *region = CTX_wm_region(C);
float viewx;
@@ -128,7 +128,7 @@ static int frame_from_event(bContext *C, wmEvent *event)
}
/* Modal Operator init */
-static int change_frame_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int change_frame_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
/* Change to frame that mouse is over before adding modal handler,
* as user could click on a single frame (jump to frame) as well as
@@ -145,7 +145,7 @@ static int change_frame_invoke(bContext *C, wmOperator *op, wmEvent *event)
}
/* Modal event handling of frame changing */
-static int change_frame_modal(bContext *C, wmOperator *op, wmEvent *event)
+static int change_frame_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
/* execute the events */
switch (event->type) {
diff --git a/source/blender/editors/animation/keyframing.c b/source/blender/editors/animation/keyframing.c
index 6d1e6eab26b..ed8398b7c8b 100644
--- a/source/blender/editors/animation/keyframing.c
+++ b/source/blender/editors/animation/keyframing.c
@@ -714,7 +714,6 @@ static float visualkey_get_value(PointerRNA *ptr, PropertyRNA *prop, int array_i
else if (ptr->type == &RNA_PoseBone) {
Object *ob = (Object *)ptr->id.data; /* we assume that this is always set, and is an object */
bPoseChannel *pchan = (bPoseChannel *)ptr->data;
- float tmat[4][4];
/* Although it is not strictly required for this particular space conversion,
* arg1 must not be null, as there is a null check for the other conversions to
@@ -1298,7 +1297,7 @@ void ANIM_OT_keyframe_insert(wmOperatorType *ot)
* then calls the menu if necessary before
*/
-static int insert_key_menu_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int insert_key_menu_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
Scene *scene = CTX_data_scene(C);
@@ -1308,7 +1307,7 @@ static int insert_key_menu_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(e
uiLayout *layout;
/* call the menu, which will call this operator again, hence the canceled */
- pup = uiPupMenuBegin(C, op->type->name, ICON_NONE);
+ pup = uiPupMenuBegin(C, RNA_struct_ui_name(op->type->srna), ICON_NONE);
layout = uiPupMenuLayout(pup);
uiItemsEnumO(layout, "ANIM_OT_keyframe_insert_menu", "type");
uiPupMenuEnd(C, pup);
@@ -1624,17 +1623,21 @@ static int insert_key_button_exec(bContext *C, wmOperator *op)
success += insert_keyframe_direct(op->reports, ptr, prop, fcu, cfra, 0);
}
else {
- if (G.debug & G_DEBUG)
- printf("Button Insert-Key: no path to property\n");
- BKE_report(op->reports, RPT_WARNING, "Failed to resolve path to property, try using a keying set instead");
+ BKE_report(op->reports, RPT_WARNING,
+ "Failed to resolve path to property, try manually specifying this using a Keying Set instead");
}
}
- else if (G.debug & G_DEBUG) {
- printf("ptr.data = %p, prop = %p,", (void *)ptr.data, (void *)prop);
- if (prop)
- printf("animatable = %d\n", RNA_property_animateable(&ptr, prop));
- else
- printf("animatable = NULL\n");
+ else {
+ if (prop && !RNA_property_animateable(&ptr, prop)) {
+ BKE_reportf(op->reports, RPT_WARNING,
+ "\"%s\" property cannot be animated",
+ RNA_property_identifier(prop));
+ }
+ else {
+ BKE_reportf(op->reports, RPT_WARNING,
+ "Button doesn't appear to have any property information attached (ptr.data = %p, prop = %p)",
+ (void *)ptr.data, (void *)prop);
+ }
}
if (success) {
diff --git a/source/blender/editors/animation/keyingsets.c b/source/blender/editors/animation/keyingsets.c
index 4e8d7bdafe5..ad09fcb5966 100644
--- a/source/blender/editors/animation/keyingsets.c
+++ b/source/blender/editors/animation/keyingsets.c
@@ -468,7 +468,7 @@ void ANIM_OT_keyingset_button_remove(wmOperatorType *ot)
/* Change Active KeyingSet Operator ------------------------ */
/* This operator checks if a menu should be shown for choosing the KeyingSet to make the active one */
-static int keyingset_active_menu_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int keyingset_active_menu_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
uiPopupMenu *pup;
uiLayout *layout;
@@ -879,7 +879,7 @@ short ANIM_validate_keyingset(bContext *C, ListBase *dsources, KeyingSet *ks)
if (ksi == NULL)
return MODIFYKEY_MISSING_TYPEINFO;
/* TODO: check for missing callbacks! */
-
+
/* check if it can be used in the current context */
if (ksi->poll(ksi, C)) {
/* if a list of data sources are provided, run a special iterator over them,
diff --git a/source/blender/editors/armature/armature_add.c b/source/blender/editors/armature/armature_add.c
index 531c0551c87..28fb74f0cdd 100644
--- a/source/blender/editors/armature/armature_add.c
+++ b/source/blender/editors/armature/armature_add.c
@@ -214,7 +214,7 @@ static int armature_click_extrude_exec(bContext *C, wmOperator *UNUSED(op))
return OPERATOR_FINISHED;
}
-static int armature_click_extrude_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int armature_click_extrude_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
/* TODO most of this code is copied from set3dcursor_invoke,
* it would be better to reuse code in set3dcursor_invoke */
@@ -320,8 +320,8 @@ void updateDuplicateSubtargetObjects(EditBone *dupBone, ListBase *editbones, Obj
bConstraint *curcon;
ListBase *conlist;
- if ( (pchan = BKE_pose_channel_verify(dst_ob->pose, dupBone->name)) ) {
- if ( (conlist = &pchan->constraints) ) {
+ if ((pchan = BKE_pose_channel_verify(dst_ob->pose, dupBone->name))) {
+ if ((conlist = &pchan->constraints)) {
for (curcon = conlist->first; curcon; curcon = curcon->next) {
/* does this constraint have a subtarget in
* this armature?
diff --git a/source/blender/editors/armature/armature_naming.c b/source/blender/editors/armature/armature_naming.c
index 6417a795712..561e196bf41 100644
--- a/source/blender/editors/armature/armature_naming.c
+++ b/source/blender/editors/armature/armature_naming.c
@@ -72,7 +72,7 @@ EditBone *editbone_name_exists(ListBase *edbo, const char *name)
}
/* note: there's a unique_bone_name() too! */
-static int editbone_unique_check(void *arg, const char *name)
+static bool editbone_unique_check(void *arg, const char *name)
{
struct {ListBase *lb; void *bone; } *data = arg;
EditBone *dupli = editbone_name_exists(data->lb, name);
@@ -91,7 +91,7 @@ void unique_editbone_name(ListBase *edbo, char *name, EditBone *bone)
/* ************************************************** */
/* Bone Renaming - API */
-static int bone_unique_check(void *arg, const char *name)
+static bool bone_unique_check(void *arg, const char *name)
{
return BKE_armature_find_bone_name((bArmature *)arg, name) != NULL;
}
@@ -152,7 +152,9 @@ void ED_armature_bone_rename(bArmature *arm, const char *oldnamep, const char *n
unique_editbone_name(arm->edbo, newname, NULL);
BLI_strncpy(eBone->name, newname, MAXBONENAME);
}
- else return;
+ else {
+ return;
+ }
}
else {
Bone *bone = BKE_armature_find_bone_name(arm, oldname);
@@ -161,7 +163,9 @@ void ED_armature_bone_rename(bArmature *arm, const char *oldnamep, const char *n
unique_bone_name(arm, newname);
BLI_strncpy(bone->name, newname, MAXBONENAME);
}
- else return;
+ else {
+ return;
+ }
}
/* do entire dbase - objects */
diff --git a/source/blender/editors/armature/armature_relations.c b/source/blender/editors/armature/armature_relations.c
index c64bb5c4683..3a4dc31c82d 100644
--- a/source/blender/editors/armature/armature_relations.c
+++ b/source/blender/editors/armature/armature_relations.c
@@ -671,7 +671,7 @@ static int armature_parent_set_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int armature_parent_set_invoke(bContext *C, wmOperator *UNUSED(op), wmEvent *UNUSED(event))
+static int armature_parent_set_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *UNUSED(event))
{
EditBone *actbone = CTX_data_active_bone(C);
uiPopupMenu *pup = uiPupMenuBegin(C, CTX_IFACE_(BLF_I18NCONTEXT_OPERATOR_DEFAULT, "Make Parent"), ICON_NONE);
diff --git a/source/blender/editors/armature/armature_select.c b/source/blender/editors/armature/armature_select.c
index b7a436cc209..7ff318bb6b6 100644
--- a/source/blender/editors/armature/armature_select.c
+++ b/source/blender/editors/armature/armature_select.c
@@ -166,7 +166,7 @@ void *get_nearest_bone(bContext *C, short findunsel, int x, int y)
/* called in space.c */
/* previously "selectconnected_armature" */
-static int armature_select_linked_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int armature_select_linked_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
bArmature *arm;
EditBone *bone, *curBone, *next;
@@ -323,7 +323,9 @@ static EditBone *get_nearest_editbonepoint(ViewContext *vc, const int mval[2],
else
dep = 2;
}
- else dep = 2;
+ else {
+ dep = 2;
+ }
}
else {
/* bone found */
@@ -333,7 +335,9 @@ static EditBone *get_nearest_editbonepoint(ViewContext *vc, const int mval[2],
else
dep = 3;
}
- else dep = 3;
+ else {
+ dep = 3;
+ }
}
if (ebone == ebone_next_act) {
@@ -390,8 +394,10 @@ void ED_armature_deselect_all(Object *obedit, int toggle)
// }
}
}
- else sel = toggle;
-
+ else {
+ sel = toggle;
+ }
+
/* Set the flags */
for (eBone = arm->edbo->first; eBone; eBone = eBone->next) {
if (sel == 2) {
diff --git a/source/blender/editors/armature/armature_utils.c b/source/blender/editors/armature/armature_utils.c
index 05f48ad73f4..4120be08b46 100644
--- a/source/blender/editors/armature/armature_utils.c
+++ b/source/blender/editors/armature/armature_utils.c
@@ -147,6 +147,15 @@ void ED_armature_edit_bone_remove(bArmature *arm, EditBone *exBone)
bone_free(arm, exBone);
}
+bool ED_armature_ebone_is_child_recursive(EditBone *ebone_parent, EditBone *ebone_child)
+{
+ for (ebone_child = ebone_child->parent; ebone_child; ebone_child = ebone_child->parent) {
+ if (ebone_child == ebone_parent)
+ return true;
+ }
+ return false;
+}
+
/* *************************************************************** */
/* Mirroring */
diff --git a/source/blender/editors/armature/editarmature_generate.c b/source/blender/editors/armature/editarmature_generate.c
index 89772d38e8f..bade93af8c1 100644
--- a/source/blender/editors/armature/editarmature_generate.c
+++ b/source/blender/editors/armature/editarmature_generate.c
@@ -263,7 +263,7 @@ EditBone *subdivideArcBy(ToolSettings *toolsettings, bArmature *arm, ListBase *U
parent = ED_armature_edit_bone_add(arm, "Bone");
copy_v3_v3(parent->head, iter->p);
- if (iter->size > 0) {
+ if (iter->size > FLT_EPSILON) {
parent->rad_head = iter->size * size_buffer;
}
@@ -278,7 +278,7 @@ EditBone *subdivideArcBy(ToolSettings *toolsettings, bArmature *arm, ListBase *U
child->parent = parent;
child->flag |= BONE_CONNECTED;
- if (iter->size > 0) {
+ if (iter->size > FLT_EPSILON) {
child->rad_head = iter->size * size_buffer;
parent->rad_tail = iter->size * size_buffer;
}
@@ -299,7 +299,7 @@ EditBone *subdivideArcBy(ToolSettings *toolsettings, bArmature *arm, ListBase *U
iter->tail(iter);
copy_v3_v3(parent->tail, iter->p);
- if (iter->size > 0) {
+ if (iter->size > FLT_EPSILON) {
parent->rad_tail = iter->size * size_buffer;
}
diff --git a/source/blender/editors/armature/editarmature_retarget.c b/source/blender/editors/armature/editarmature_retarget.c
index 62cce6b2c1e..536c5ff1f7c 100644
--- a/source/blender/editors/armature/editarmature_retarget.c
+++ b/source/blender/editors/armature/editarmature_retarget.c
@@ -409,11 +409,11 @@ static void renameTemplateBone(char *name, char *template_name, ListBase *editbo
for (i = 0, j = 0; i < (MAXBONENAME - 1) && j < (MAXBONENAME - 1) && template_name[i] != '\0'; i++) {
if (template_name[i] == '&') {
if (template_name[i + 1] == 'S' || template_name[i + 1] == 's') {
- j += sprintf(name + j, "%s", side_string);
+ j += BLI_strncpy_rlen(name + j, side_string, MAXBONENAME);
i++;
}
else if (template_name[i + 1] == 'N' || template_name[i + 1] == 'n') {
- j += sprintf(name + j, "%s", num_string);
+ j += BLI_strncpy_rlen(name + j, num_string, MAXBONENAME);
i++;
}
else {
@@ -896,7 +896,7 @@ static void RIG_reconnectControlBones(RigGraph *rg)
/* look on deform bones first */
BLI_ghashIterator_init(&ghi, rg->bones_map);
- for (; !BLI_ghashIterator_isDone(&ghi); BLI_ghashIterator_step(&ghi)) {
+ for (; BLI_ghashIterator_notDone(&ghi); BLI_ghashIterator_step(&ghi)) {
EditBone *bone = (EditBone *)BLI_ghashIterator_getValue(&ghi);
/* don't link with parent */
diff --git a/source/blender/editors/armature/editarmature_sketch.c b/source/blender/editors/armature/editarmature_sketch.c
index ec96c574f75..a3515e0983d 100644
--- a/source/blender/editors/armature/editarmature_sketch.c
+++ b/source/blender/editors/armature/editarmature_sketch.c
@@ -28,9 +28,6 @@
#include "DNA_scene_types.h"
#include "DNA_armature_types.h"
-#include "RNA_define.h"
-#include "RNA_access.h"
-
#include "BLI_blenlib.h"
#include "BLI_math.h"
@@ -39,6 +36,9 @@
#include "BKE_context.h"
#include "BKE_sketch.h"
+#include "RNA_define.h"
+#include "RNA_access.h"
+
#include "ED_view3d.h"
#include "ED_screen.h"
@@ -170,20 +170,20 @@ const char *BIF_listTemplates(const bContext *UNUSED(C))
GHashIterator ghi;
const char *menu_header = IFACE_("Template %t|None %x0|");
char *p;
+ const size_t template_size = (BLI_ghash_size(TEMPLATES_HASH) * 32 + 30);
if (TEMPLATES_MENU != NULL) {
MEM_freeN(TEMPLATES_MENU);
}
- TEMPLATES_MENU = MEM_callocN(sizeof(char) * (BLI_ghash_size(TEMPLATES_HASH) * 32 + 30), "skeleton template menu");
+ TEMPLATES_MENU = MEM_callocN(sizeof(char) * template_size, "skeleton template menu");
p = TEMPLATES_MENU;
-
- p += sprintf(TEMPLATES_MENU, "%s", menu_header);
+ p += BLI_strncpy_rlen(p, menu_header, template_size);
BLI_ghashIterator_init(&ghi, TEMPLATES_HASH);
- while (!BLI_ghashIterator_isDone(&ghi)) {
+ while (BLI_ghashIterator_notDone(&ghi)) {
Object *ob = BLI_ghashIterator_getValue(&ghi);
int key = GET_INT_FROM_POINTER(BLI_ghashIterator_getKey(&ghi));
@@ -203,7 +203,7 @@ int BIF_currentTemplate(const bContext *C)
GHashIterator ghi;
BLI_ghashIterator_init(&ghi, TEMPLATES_HASH);
- while (!BLI_ghashIterator_isDone(&ghi)) {
+ while (BLI_ghashIterator_notDone(&ghi)) {
Object *ob = BLI_ghashIterator_getValue(&ghi);
int key = GET_INT_FROM_POINTER(BLI_ghashIterator_getKey(&ghi));
@@ -922,17 +922,18 @@ static void sk_projectDrawPoint(bContext *C, float vec[3], SK_Stroke *stk, SK_Dr
float fp[3] = {0, 0, 0};
float dvec[3];
float mval_f[2];
+ float zfac;
if (last != NULL) {
copy_v3_v3(fp, last->p);
}
- initgrabz(ar->regiondata, fp[0], fp[1], fp[2]);
+ zfac = ED_view3d_calc_zfac(ar->regiondata, fp, NULL);
/* method taken from editview.c - mouse_cursor() */
if (ED_view3d_project_short_global(ar, fp, cval, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) {
VECSUB2D(mval_f, cval, dd->mval);
- ED_view3d_win_to_delta(ar, mval_f, dvec);
+ ED_view3d_win_to_delta(ar, mval_f, dvec, zfac);
sub_v3_v3v3(vec, fp, dvec);
}
else {
@@ -2231,7 +2232,7 @@ void BDR_drawSketch(const bContext *C)
}
}
-static int sketch_delete(bContext *C, wmOperator *UNUSED(op), wmEvent *UNUSED(event))
+static int sketch_delete(bContext *C, wmOperator *UNUSED(op), const wmEvent *UNUSED(event))
{
SK_Sketch *sketch = contextSketch(C, 0);
if (sketch) {
@@ -2328,7 +2329,7 @@ SK_Sketch *viewcontextSketch(ViewContext *vc, int create)
return sketch;
}
-static int sketch_convert(bContext *C, wmOperator *UNUSED(op), wmEvent *UNUSED(event))
+static int sketch_convert(bContext *C, wmOperator *UNUSED(op), const wmEvent *UNUSED(event))
{
SK_Sketch *sketch = contextSketch(C, 0);
if (sketch != NULL) {
@@ -2338,7 +2339,7 @@ static int sketch_convert(bContext *C, wmOperator *UNUSED(op), wmEvent *UNUSED(e
return OPERATOR_FINISHED;
}
-static int sketch_cancel(bContext *C, wmOperator *UNUSED(op), wmEvent *UNUSED(event))
+static int sketch_cancel(bContext *C, wmOperator *UNUSED(op), const wmEvent *UNUSED(event))
{
SK_Sketch *sketch = contextSketch(C, 0);
if (sketch != NULL) {
@@ -2349,7 +2350,7 @@ static int sketch_cancel(bContext *C, wmOperator *UNUSED(op), wmEvent *UNUSED(ev
return OPERATOR_PASS_THROUGH;
}
-static int sketch_finish(bContext *C, wmOperator *UNUSED(op), wmEvent *UNUSED(event))
+static int sketch_finish(bContext *C, wmOperator *UNUSED(op), const wmEvent *UNUSED(event))
{
SK_Sketch *sketch = contextSketch(C, 0);
if (sketch != NULL) {
@@ -2361,7 +2362,7 @@ static int sketch_finish(bContext *C, wmOperator *UNUSED(op), wmEvent *UNUSED(ev
return OPERATOR_PASS_THROUGH;
}
-static int sketch_select(bContext *C, wmOperator *UNUSED(op), wmEvent *event)
+static int sketch_select(bContext *C, wmOperator *UNUSED(op), const wmEvent *event)
{
SK_Sketch *sketch = contextSketch(C, 0);
if (sketch) {
@@ -2381,7 +2382,7 @@ static int sketch_draw_stroke_cancel(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
-static int sketch_draw_stroke(bContext *C, wmOperator *op, wmEvent *event)
+static int sketch_draw_stroke(bContext *C, wmOperator *op, const wmEvent *event)
{
short snap = RNA_boolean_get(op->ptr, "snap");
SK_DrawData *dd;
@@ -2407,7 +2408,7 @@ static int sketch_draw_gesture_cancel(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
-static int sketch_draw_gesture(bContext *C, wmOperator *op, wmEvent *event)
+static int sketch_draw_gesture(bContext *C, wmOperator *op, const wmEvent *event)
{
short snap = RNA_boolean_get(op->ptr, "snap");
SK_DrawData *dd;
@@ -2425,7 +2426,7 @@ static int sketch_draw_gesture(bContext *C, wmOperator *op, wmEvent *event)
return OPERATOR_RUNNING_MODAL;
}
-static int sketch_draw_modal(bContext *C, wmOperator *op, wmEvent *event, short gesture, SK_Stroke *stk)
+static int sketch_draw_modal(bContext *C, wmOperator *op, const wmEvent *event, short gesture, SK_Stroke *stk)
{
short snap = RNA_boolean_get(op->ptr, "snap");
SK_DrawData *dd = op->customdata;
@@ -2483,19 +2484,19 @@ static int sketch_draw_modal(bContext *C, wmOperator *op, wmEvent *event, short
return retval;
}
-static int sketch_draw_stroke_modal(bContext *C, wmOperator *op, wmEvent *event)
+static int sketch_draw_stroke_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
SK_Sketch *sketch = contextSketch(C, 1); /* create just to be sure */
return sketch_draw_modal(C, op, event, 0, sketch->active_stroke);
}
-static int sketch_draw_gesture_modal(bContext *C, wmOperator *op, wmEvent *event)
+static int sketch_draw_gesture_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
SK_Sketch *sketch = contextSketch(C, 1); /* create just to be sure */
return sketch_draw_modal(C, op, event, 1, sketch->gesture);
}
-static int sketch_draw_preview(bContext *C, wmOperator *op, wmEvent *event)
+static int sketch_draw_preview(bContext *C, wmOperator *op, const wmEvent *event)
{
short snap = RNA_boolean_get(op->ptr, "snap");
SK_Sketch *sketch = contextSketch(C, 0);
diff --git a/source/blender/editors/armature/pose_edit.c b/source/blender/editors/armature/pose_edit.c
index 3d1d5d2f6ba..40b96132699 100644
--- a/source/blender/editors/armature/pose_edit.c
+++ b/source/blender/editors/armature/pose_edit.c
@@ -201,7 +201,7 @@ void ED_pose_recalculate_paths(Scene *scene, Object *ob)
/* show popup to determine settings */
-static int pose_calculate_paths_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int pose_calculate_paths_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
Object *ob = BKE_object_pose_armature_get(CTX_data_active_object(C));
@@ -793,7 +793,7 @@ void ARMATURE_OT_layers_show_all(wmOperatorType *ot)
/* ------------------- */
/* Present a popup to get the layers that should be used */
-static int pose_armature_layers_invoke(bContext *C, wmOperator *op, wmEvent *evt)
+static int pose_armature_layers_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
Object *ob = BKE_object_pose_armature_get(CTX_data_active_object(C));
bArmature *arm = (ob) ? ob->data : NULL;
@@ -810,7 +810,7 @@ static int pose_armature_layers_invoke(bContext *C, wmOperator *op, wmEvent *evt
RNA_boolean_set_array(op->ptr, "layers", layers);
/* part to sync with other similar operators... */
- return WM_operator_props_popup(C, op, evt);
+ return WM_operator_props_popup(C, op, event);
}
/* Set the visible layers for the active armature (edit and pose modes) */
@@ -879,7 +879,7 @@ void ARMATURE_OT_armature_layers(wmOperatorType *ot)
/* ------------------- */
/* Present a popup to get the layers that should be used */
-static int pose_bone_layers_invoke(bContext *C, wmOperator *op, wmEvent *evt)
+static int pose_bone_layers_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
int layers[32] = {0}; /* hardcoded for now - we can only have 32 armature layers, so this should be fine... */
@@ -900,7 +900,7 @@ static int pose_bone_layers_invoke(bContext *C, wmOperator *op, wmEvent *evt)
RNA_boolean_set_array(op->ptr, "layers", layers);
/* part to sync with other similar operators... */
- return WM_operator_props_popup(C, op, evt);
+ return WM_operator_props_popup(C, op, event);
}
/* Set the visible layers for the active armature (edit and pose modes) */
@@ -954,7 +954,7 @@ void POSE_OT_bone_layers(wmOperatorType *ot)
/* ------------------- */
/* Present a popup to get the layers that should be used */
-static int armature_bone_layers_invoke(bContext *C, wmOperator *op, wmEvent *evt)
+static int armature_bone_layers_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
int layers[32] = {0}; /* hardcoded for now - we can only have 32 armature layers, so this should be fine... */
@@ -975,7 +975,7 @@ static int armature_bone_layers_invoke(bContext *C, wmOperator *op, wmEvent *evt
RNA_boolean_set_array(op->ptr, "layers", layers);
/* part to sync with other similar operators... */
- return WM_operator_props_popup(C, op, evt);
+ return WM_operator_props_popup(C, op, event);
}
/* Set the visible layers for the active armature (edit and pose modes) */
diff --git a/source/blender/editors/armature/pose_group.c b/source/blender/editors/armature/pose_group.c
index 06a88f013d7..99f54de134a 100644
--- a/source/blender/editors/armature/pose_group.c
+++ b/source/blender/editors/armature/pose_group.c
@@ -126,7 +126,7 @@ void POSE_OT_group_remove(wmOperatorType *ot)
/* ------------ */
/* invoke callback which presents a list of bone-groups for the user to choose from */
-static int pose_groups_menu_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(evt))
+static int pose_groups_menu_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
Object *ob = ED_pose_object_from_context(C);
bPose *pose;
diff --git a/source/blender/editors/armature/pose_lib.c b/source/blender/editors/armature/pose_lib.c
index 457874c7ae6..09c0f7e9647 100644
--- a/source/blender/editors/armature/pose_lib.c
+++ b/source/blender/editors/armature/pose_lib.c
@@ -389,7 +389,7 @@ static void poselib_add_menu_invoke__replacemenu(bContext *C, uiLayout *layout,
}
}
-static int poselib_add_menu_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(evt))
+static int poselib_add_menu_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
Scene *scene = CTX_data_scene(C);
Object *ob = get_poselib_object(C);
@@ -613,7 +613,7 @@ void POSELIB_OT_pose_remove(wmOperatorType *ot)
ot->prop = prop;
}
-static int poselib_rename_invoke(bContext *C, wmOperator *op, wmEvent *evt)
+static int poselib_rename_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
Object *ob = get_poselib_object(C);
bAction *act = (ob) ? ob->poselib : NULL;
@@ -638,7 +638,7 @@ static int poselib_rename_invoke(bContext *C, wmOperator *op, wmEvent *evt)
}
/* part to sync with other similar operators... */
- return WM_operator_props_popup(C, op, evt);
+ return WM_operator_props_popup(C, op, event);
}
static int poselib_rename_exec(bContext *C, wmOperator *op)
@@ -1185,7 +1185,7 @@ static void poselib_preview_handle_search(tPoseLib_PreviewData *pld, unsigned sh
}
/* handle events for poselib_preview_poses */
-static int poselib_preview_handle_event(bContext *UNUSED(C), wmOperator *op, wmEvent *event)
+static int poselib_preview_handle_event(bContext *UNUSED(C), wmOperator *op, const wmEvent *event)
{
tPoseLib_PreviewData *pld = op->customdata;
int ret = OPERATOR_RUNNING_MODAL;
@@ -1539,7 +1539,7 @@ static int poselib_preview_cancel(bContext *C, wmOperator *op)
}
/* main modal status check */
-static int poselib_preview_modal(bContext *C, wmOperator *op, wmEvent *event)
+static int poselib_preview_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
tPoseLib_PreviewData *pld = op->customdata;
int ret;
@@ -1559,7 +1559,7 @@ static int poselib_preview_modal(bContext *C, wmOperator *op, wmEvent *event)
}
/* Modal Operator init */
-static int poselib_preview_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int poselib_preview_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
tPoseLib_PreviewData *pld;
diff --git a/source/blender/editors/armature/pose_select.c b/source/blender/editors/armature/pose_select.c
index 186c7a1fe89..4fa1389426d 100644
--- a/source/blender/editors/armature/pose_select.c
+++ b/source/blender/editors/armature/pose_select.c
@@ -208,7 +208,7 @@ static void selectconnected_posebonechildren(Object *ob, Bone *bone, int extend)
/* within active object context */
/* previously known as "selectconnected_posearmature" */
-static int pose_select_connected_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int pose_select_connected_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
Object *ob = BKE_object_pose_armature_get(CTX_data_active_object(C));
bArmature *arm = (bArmature *)ob->data;
diff --git a/source/blender/editors/armature/pose_slide.c b/source/blender/editors/armature/pose_slide.c
index fee37a9c0fb..4d6f8f520f5 100644
--- a/source/blender/editors/armature/pose_slide.c
+++ b/source/blender/editors/armature/pose_slide.c
@@ -614,12 +614,12 @@ static int pose_slide_invoke_common(bContext *C, wmOperator *op, tPoseSlideOp *p
}
/* common code for modal() */
-static int pose_slide_modal(bContext *C, wmOperator *op, wmEvent *evt)
+static int pose_slide_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
tPoseSlideOp *pso = op->customdata;
wmWindow *win = CTX_wm_window(C);
- switch (evt->type) {
+ switch (event->type) {
case LEFTMOUSE: /* confirm */
case RETKEY:
{
@@ -660,7 +660,7 @@ static int pose_slide_modal(bContext *C, wmOperator *op, wmEvent *evt)
/* calculate percentage based on position of mouse (we only use x-axis for now.
* since this is more convenient for users to do), and store new percentage value
*/
- pso->percentage = (evt->x - pso->ar->winrct.xmin) / ((float)pso->ar->winx);
+ pso->percentage = (event->x - pso->ar->winrct.xmin) / ((float)pso->ar->winx);
RNA_float_set(op->ptr, "percentage", pso->percentage);
/* update percentage indicator in header */
@@ -717,7 +717,7 @@ static void pose_slide_opdef_properties(wmOperatorType *ot)
/* ------------------------------------ */
/* invoke() - for 'push' mode */
-static int pose_slide_push_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(evt))
+static int pose_slide_push_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
tPoseSlideOp *pso;
@@ -774,7 +774,7 @@ void POSE_OT_push(wmOperatorType *ot)
/* ........................ */
/* invoke() - for 'relax' mode */
-static int pose_slide_relax_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(evt))
+static int pose_slide_relax_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
tPoseSlideOp *pso;
@@ -831,7 +831,7 @@ void POSE_OT_relax(wmOperatorType *ot)
/* ........................ */
/* invoke() - for 'breakdown' mode */
-static int pose_slide_breakdown_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(evt))
+static int pose_slide_breakdown_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
tPoseSlideOp *pso;
diff --git a/source/blender/editors/armature/reeb.c b/source/blender/editors/armature/reeb.c
index 454b0f0bceb..d04938fd59b 100644
--- a/source/blender/editors/armature/reeb.c
+++ b/source/blender/editors/armature/reeb.c
@@ -1659,7 +1659,7 @@ int filterSmartReebGraph(ReebGraph *UNUSED(rg), float UNUSED(threshold))
float avg_vec[3] = {0, 0, 0};
for (BLI_ghashIterator_init(&ghi, arc->faces);
- !BLI_ghashIterator_isDone(&ghi);
+ BLI_ghashIterator_notDone(&ghi);
BLI_ghashIterator_step(&ghi))
{
EditFace *efa = BLI_ghashIterator_getValue(&ghi);
@@ -2045,7 +2045,7 @@ void mergeArcFaces(ReebGraph *UNUSED(rg), ReebArc *aDst, ReebArc *aSrc)
GHashIterator ghi;
for (BLI_ghashIterator_init(&ghi, aSrc->faces);
- !BLI_ghashIterator_isDone(&ghi);
+ BLI_ghashIterator_notDone(&ghi);
BLI_ghashIterator_step(&ghi))
{
EditFace *efa = BLI_ghashIterator_getValue(&ghi);
diff --git a/source/blender/editors/curve/editcurve.c b/source/blender/editors/curve/editcurve.c
index d01e5c5d9bf..e134507600e 100644
--- a/source/blender/editors/curve/editcurve.c
+++ b/source/blender/editors/curve/editcurve.c
@@ -626,7 +626,9 @@ static void switch_keys_direction(Curve *cu, Nurb *actnu)
bezt++;
}
}
- else fp += a * 12;
+ else {
+ fp += a * 12;
+ }
}
else {
BPoint *bp = nu->bp;
@@ -640,7 +642,9 @@ static void switch_keys_direction(Curve *cu, Nurb *actnu)
bp++;
}
}
- else fp += a * 4;
+ else {
+ fp += a * 4;
+ }
}
nu = nu->next;
@@ -672,7 +676,7 @@ static GHash *dupli_keyIndexHash(GHash *keyindex)
gh = BLI_ghash_ptr_new("dupli_keyIndex gh");
for (hashIter = BLI_ghashIterator_new(keyindex);
- !BLI_ghashIterator_isDone(hashIter);
+ BLI_ghashIterator_notDone(hashIter);
BLI_ghashIterator_step(hashIter))
{
void *cv = BLI_ghashIterator_getKey(hashIter);
@@ -1473,7 +1477,9 @@ static short isNurbselUV(Nurb *nu, int *u, int *v, int flag)
if (*u == -1) *u = b;
else return 0;
}
- else if (sel > 1) return 0; /* because sel == 1 is still ok */
+ else if (sel > 1) {
+ return 0; /* because sel == 1 is still ok */
+ }
}
for (a = 0; a < nu->pntsu; a++) {
@@ -1486,7 +1492,9 @@ static short isNurbselUV(Nurb *nu, int *u, int *v, int flag)
if (*v == -1) *v = a;
else return 0;
}
- else if (sel > 1) return 0;
+ else if (sel > 1) {
+ return 0;
+ }
}
if (*u == -1 && *v > -1) return 1;
@@ -1781,7 +1789,7 @@ static short extrudeflagNurb(EditNurb *editnurb, int flag)
else {
/* which row or column is selected */
- if (isNurbselUV(nu, &u, &v, flag) ) {
+ if (isNurbselUV(nu, &u, &v, flag)) {
/* deselect all */
bp = nu->bp;
@@ -1872,7 +1880,7 @@ static void adduplicateflagNurb(Object *obedit, short flag)
for (a = 0; a < nu->pntsu; a++) {
enda = -1;
starta = a;
- while ( (bezt->f1 & flag) || (bezt->f2 & flag) || (bezt->f3 & flag) ) {
+ while ((bezt->f1 & flag) || (bezt->f2 & flag) || (bezt->f3 & flag)) {
select_beztriple(bezt, DESELECT, flag, HIDDEN);
enda = a;
if (a >= nu->pntsu - 1) break;
@@ -2431,12 +2439,12 @@ static void select_adjacent_cp(ListBase *editnurb, short next, short cont, short
BezTriple *bezt;
BPoint *bp;
int a;
- short lastsel = 0;
+ short lastsel = false;
if (next == 0) return;
for (nu = editnurb->first; nu; nu = nu->next) {
- lastsel = 0;
+ lastsel = false;
if (nu->type == CU_BEZIER) {
a = nu->pntsu;
bezt = nu->bezt;
@@ -2447,12 +2455,12 @@ static void select_adjacent_cp(ListBase *editnurb, short next, short cont, short
bezt += next;
if (!(bezt->f2 & SELECT) || (selstatus == 0)) {
short sel = select_beztriple(bezt, selstatus, 1, VISIBLE);
- if ((sel == 1) && (cont == 0)) lastsel = 1;
+ if ((sel == 1) && (cont == 0)) lastsel = true;
}
}
else {
bezt += next;
- lastsel = 0;
+ lastsel = false;
}
/* move around in zigzag way so that we go through each */
bezt -= (next - next / abs(next));
@@ -2468,12 +2476,12 @@ static void select_adjacent_cp(ListBase *editnurb, short next, short cont, short
bp += next;
if (!(bp->f1 & SELECT) || (selstatus == 0)) {
short sel = select_bpoint(bp, selstatus, 1, VISIBLE);
- if ((sel == 1) && (cont == 0)) lastsel = 1;
+ if ((sel == 1) && (cont == 0)) lastsel = true;
}
}
else {
bp += next;
- lastsel = 0;
+ lastsel = false;
}
/* move around in zigzag way so that we go through each */
bp -= (next - next / abs(next));
@@ -2878,7 +2886,7 @@ static void subdividenurb(Object *obedit, int number_cuts)
keyIndex_updateBezt(editnurb, prevbezt, beztn, 1);
beztn++;
- if (BEZSELECTED_HIDDENHANDLES(cu, prevbezt) && BEZSELECTED_HIDDENHANDLES(cu, bezt) ) {
+ if (BEZSELECTED_HIDDENHANDLES(cu, prevbezt) && BEZSELECTED_HIDDENHANDLES(cu, bezt)) {
float prevvec[3][3];
memcpy(prevvec, prevbezt->vec, sizeof(float) * 9);
@@ -3062,7 +3070,7 @@ static void subdividenurb(Object *obedit, int number_cuts)
bp++;
}
}
- if (sel == (nu->pntsu * nu->pntsv) ) { /* subdivide entire nurb */
+ if (sel == (nu->pntsu * nu->pntsv)) { /* subdivide entire nurb */
/* Global subdivision is a special case of partial
* subdivision. Strange it is considered separately... */
@@ -3332,7 +3340,7 @@ static void findselectedNurbvert(ListBase *editnurb, Nurb **nu, BezTriple **bezt
bezt1 = nu1->bezt;
a = nu1->pntsu;
while (a--) {
- if ( (bezt1->f1 & SELECT) || (bezt1->f2 & SELECT) || (bezt1->f3 & SELECT) ) {
+ if ((bezt1->f1 & SELECT) || (bezt1->f2 & SELECT) || (bezt1->f3 & SELECT)) {
if (*nu != NULL && *nu != nu1) {
*nu = NULL;
*bp = NULL;
@@ -3803,7 +3811,7 @@ static void merge_2_nurb(wmOperator *op, ListBase *editnurb, Nurb *nu1, Nurb *nu
/* first nurbs: u = resolu-1 selected */
- if (is_u_selected(nu1, nu1->pntsu - 1) ) {
+ if (is_u_selected(nu1, nu1->pntsu - 1)) {
/* pass */
}
else {
@@ -3835,7 +3843,7 @@ static void merge_2_nurb(wmOperator *op, ListBase *editnurb, Nurb *nu1, Nurb *nu
}
/* 2nd nurbs: u = 0 selected */
- if (is_u_selected(nu2, 0) ) {
+ if (is_u_selected(nu2, 0)) {
/* pass */
}
else {
@@ -4041,9 +4049,11 @@ static int make_segment_exec(bContext *C, wmOperator *op)
if ((nu->flagu & CU_NURB_CYCLIC) == 0) { /* not cyclic */
if (nu->type == CU_BEZIER) {
if (nu1 == NULL) {
- if (BEZSELECTED_HIDDENHANDLES(cu, nu->bezt) ) nu1 = nu;
+ if (BEZSELECTED_HIDDENHANDLES(cu, nu->bezt)) {
+ nu1 = nu;
+ }
else {
- if (BEZSELECTED_HIDDENHANDLES(cu, &(nu->bezt[nu->pntsu - 1])) ) {
+ if (BEZSELECTED_HIDDENHANDLES(cu, &(nu->bezt[nu->pntsu - 1]))) {
nu1 = nu;
BKE_nurb_direction_switch(nu);
keyData_switchDirectionNurb(cu, nu);
@@ -4051,23 +4061,27 @@ static int make_segment_exec(bContext *C, wmOperator *op)
}
}
else if (nu2 == NULL) {
- if (BEZSELECTED_HIDDENHANDLES(cu, nu->bezt) ) {
+ if (BEZSELECTED_HIDDENHANDLES(cu, nu->bezt)) {
nu2 = nu;
BKE_nurb_direction_switch(nu);
keyData_switchDirectionNurb(cu, nu);
}
else {
- if (BEZSELECTED_HIDDENHANDLES(cu, &(nu->bezt[nu->pntsu - 1])) ) {
+ if (BEZSELECTED_HIDDENHANDLES(cu, &(nu->bezt[nu->pntsu - 1]))) {
nu2 = nu;
}
}
}
- else break;
+ else {
+ break;
+ }
}
else if (nu->pntsv == 1) {
bp = nu->bp;
if (nu1 == NULL) {
- if (bp->f1 & SELECT) nu1 = nu;
+ if (bp->f1 & SELECT) {
+ nu1 = nu;
+ }
else {
bp = bp + (nu->pntsu - 1);
if (bp->f1 & SELECT) {
@@ -4090,7 +4104,9 @@ static int make_segment_exec(bContext *C, wmOperator *op)
}
}
}
- else break;
+ else {
+ break;
+ }
}
}
}
@@ -4421,7 +4437,7 @@ static int spin_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int spin_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int spin_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
Scene *scene = CTX_data_scene(C);
View3D *v3d = CTX_wm_view3d(C);
@@ -4495,7 +4511,9 @@ static int addvert_Nurb(bContext *C, short mode, float location[3])
newnu->resolu = cu->resolu;
newnu->flag |= CU_SMOOTH;
}
- else memcpy(newnu, nu, sizeof(Nurb));
+ else {
+ memcpy(newnu, nu, sizeof(Nurb));
+ }
BLI_addtail(&editnurb->nurbs, newnu);
set_actNurb(obedit, newnu);
@@ -4609,7 +4627,9 @@ static int addvert_Nurb(bContext *C, short mode, float location[3])
bezt = newbezt;
ok = 1;
}
- else bezt = NULL;
+ else {
+ bezt = NULL;
+ }
if (bezt) {
if (!newnu) nu->pntsu++;
@@ -4687,7 +4707,9 @@ static int addvert_Nurb(bContext *C, short mode, float location[3])
bp = newbp;
ok = 1;
}
- else bp = NULL;
+ else {
+ bp = NULL;
+ }
if (bp) {
if (mode == 'e') {
@@ -4705,7 +4727,9 @@ static int addvert_Nurb(bContext *C, short mode, float location[3])
nu->pntsu++;
BKE_nurb_knot_calc_u(nu);
}
- else BKE_nurb_knot_calc_u(newnu);
+ else {
+ BKE_nurb_knot_calc_u(newnu);
+ }
}
}
@@ -4732,7 +4756,7 @@ static int add_vertex_exec(bContext *C, wmOperator *op)
return addvert_Nurb(C, 0, location);
}
-static int add_vertex_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int add_vertex_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
RegionView3D *rv3d = CTX_wm_region_view3d(C);
@@ -4761,7 +4785,7 @@ static int add_vertex_invoke(bContext *C, wmOperator *op, wmEvent *event)
copy_v3_v3(location, give_cursor(vc.scene, vc.v3d));
}
- view3d_get_view_aligned_coordinate(&vc, location, event->mval, TRUE);
+ view3d_get_view_aligned_coordinate(vc.ar, location, event->mval, true);
RNA_float_set_array(op->ptr, "location", location);
}
@@ -4864,7 +4888,7 @@ static int toggle_cyclic_exec(bContext *C, wmOperator *op)
a = nu->pntsu;
bezt = nu->bezt;
while (a--) {
- if (BEZSELECTED_HIDDENHANDLES(cu, bezt) ) {
+ if (BEZSELECTED_HIDDENHANDLES(cu, bezt)) {
nu->flagu ^= CU_NURB_CYCLIC;
break;
}
@@ -4915,7 +4939,7 @@ static int toggle_cyclic_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int toggle_cyclic_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int toggle_cyclic_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
Object *obedit = CTX_data_edit_object(C);
ListBase *editnurb = object_editcurve_get(obedit);
@@ -4983,7 +5007,7 @@ static int select_linked_exec(bContext *C, wmOperator *UNUSED(op))
bezt = nu->bezt;
a = nu->pntsu;
while (a--) {
- if ( (bezt->f1 & SELECT) || (bezt->f2 & SELECT) || (bezt->f3 & SELECT) ) {
+ if ((bezt->f1 & SELECT) || (bezt->f2 & SELECT) || (bezt->f3 & SELECT)) {
a = nu->pntsu;
bezt = nu->bezt;
while (a--) {
@@ -5018,7 +5042,7 @@ static int select_linked_exec(bContext *C, wmOperator *UNUSED(op))
return OPERATOR_FINISHED;
}
-static int select_linked_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int select_linked_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
return select_linked_exec(C, op);
}
@@ -5044,7 +5068,7 @@ void CURVE_OT_select_linked(wmOperatorType *ot)
/***************** select linked pick operator ******************/
-static int select_linked_pick_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int select_linked_pick_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
Object *obedit = CTX_data_edit_object(C);
ViewContext vc;
@@ -5333,7 +5357,7 @@ static int select_less_exec(bContext *C, wmOperator *UNUSED(op))
BPoint *bp;
BezTriple *bezt;
int a;
- short sel = 0, lastsel = 0;
+ short sel = 0, lastsel = false;
short *selbpoints;
if (obedit->type == OB_SURF) {
@@ -5344,44 +5368,54 @@ static int select_less_exec(bContext *C, wmOperator *UNUSED(op))
while (a--) {
if ((bp->hide == 0) && (bp->f1 & SELECT)) {
sel = 0;
-
+
/* check if neighbors have been selected */
/* edges of surface are an exception */
- if ((a + 1) % nu->pntsu == 0) sel++;
+ if ((a + 1) % nu->pntsu == 0) {
+ sel++;
+ }
else {
bp--;
if ((selbpoints[a + 1] == 1) || ((bp->hide == 0) && (bp->f1 & SELECT))) sel++;
bp++;
}
- if ((a + 1) % nu->pntsu == 1) sel++;
+ if ((a + 1) % nu->pntsu == 1) {
+ sel++;
+ }
else {
bp++;
if ((bp->hide == 0) && (bp->f1 & SELECT)) sel++;
bp--;
}
- if (a + 1 > nu->pntsu * nu->pntsv - nu->pntsu) sel++;
+ if (a + 1 > nu->pntsu * nu->pntsv - nu->pntsu) {
+ sel++;
+ }
else {
bp -= nu->pntsu;
if ((selbpoints[a + nu->pntsu] == 1) || ((bp->hide == 0) && (bp->f1 & SELECT))) sel++;
bp += nu->pntsu;
}
-
- if (a < nu->pntsu) sel++;
+
+ if (a < nu->pntsu) {
+ sel++;
+ }
else {
bp += nu->pntsu;
if ((bp->hide == 0) && (bp->f1 & SELECT)) sel++;
bp -= nu->pntsu;
}
-
+
if (sel != 4) {
select_bpoint(bp, DESELECT, 1, VISIBLE);
selbpoints[a] = 1;
}
}
- else lastsel = 0;
-
+ else {
+ lastsel = false;
+ }
+
bp++;
}
@@ -5390,26 +5424,29 @@ static int select_less_exec(bContext *C, wmOperator *UNUSED(op))
}
else {
for (nu = editnurb->first; nu; nu = nu->next) {
- lastsel = 0;
+ lastsel = false;
/* check what type of curve/nurb it is */
if (nu->type == CU_BEZIER) {
a = nu->pntsu;
bezt = nu->bezt;
while (a--) {
if ((bezt->hide == 0) && (bezt->f2 & SELECT)) {
- if (lastsel == 1) sel = 1;
- else sel = 0;
-
+ sel = (lastsel == 1);
+
/* check if neighbors have been selected */
/* first and last are exceptions */
- if (a == nu->pntsu - 1) sel++;
+ if (a == nu->pntsu - 1) {
+ sel++;
+ }
else {
bezt--;
if ((bezt->hide == 0) && (bezt->f2 & SELECT)) sel++;
bezt++;
}
- if (a == 0) sel++;
+ if (a == 0) {
+ sel++;
+ }
else {
bezt++;
if ((bezt->hide == 0) && (bezt->f2 & SELECT)) sel++;
@@ -5418,12 +5455,16 @@ static int select_less_exec(bContext *C, wmOperator *UNUSED(op))
if (sel != 2) {
select_beztriple(bezt, DESELECT, 1, VISIBLE);
- lastsel = 1;
+ lastsel = true;
+ }
+ else {
+ lastsel = false;
}
- else lastsel = 0;
}
- else lastsel = 0;
-
+ else {
+ lastsel = false;
+ }
+
bezt++;
}
}
@@ -5436,28 +5477,36 @@ static int select_less_exec(bContext *C, wmOperator *UNUSED(op))
else sel = 0;
/* first and last are exceptions */
- if (a == nu->pntsu * nu->pntsv - 1) sel++;
+ if (a == nu->pntsu * nu->pntsv - 1) {
+ sel++;
+ }
else {
bp--;
if ((bp->hide == 0) && (bp->f1 & SELECT)) sel++;
bp++;
}
- if (a == 0) sel++;
+ if (a == 0) {
+ sel++;
+ }
else {
bp++;
if ((bp->hide == 0) && (bp->f1 & SELECT)) sel++;
bp--;
}
-
+
if (sel != 2) {
select_bpoint(bp, DESELECT, 1, VISIBLE);
- lastsel = 1;
+ lastsel = true;
+ }
+ else {
+ lastsel = false;
}
- else lastsel = 0;
}
- else lastsel = 0;
-
+ else {
+ lastsel = false;
+ }
+
bp++;
}
}
@@ -5820,7 +5869,7 @@ static int delete_exec(bContext *C, wmOperator *op)
int delta = 0;
bezt = nu->bezt;
for (a = 0; a < nu->pntsu; a++) {
- if (BEZSELECTED_HIDDENHANDLES(cu, bezt) ) {
+ if (BEZSELECTED_HIDDENHANDLES(cu, bezt)) {
memmove(bezt, bezt + 1, (nu->pntsu - a - 1) * sizeof(BezTriple));
keyIndex_delBezt(editnurb, bezt + delta);
keyIndex_updateBezt(editnurb, bezt + 1, bezt, nu->pntsu - a - 1);
@@ -5829,7 +5878,9 @@ static int delete_exec(bContext *C, wmOperator *op)
type = 1;
delta++;
}
- else bezt++;
+ else {
+ bezt++;
+ }
}
if (type) {
bezt1 = (BezTriple *)MEM_mallocN((nu->pntsu) * sizeof(BezTriple), "delNurb");
@@ -5889,16 +5940,16 @@ static int delete_exec(bContext *C, wmOperator *op)
if (nu->type == CU_BEZIER) {
bezt = nu->bezt;
for (a = 0; a < nu->pntsu - 1; a++) {
- if (BEZSELECTED_HIDDENHANDLES(cu, bezt) ) {
+ if (BEZSELECTED_HIDDENHANDLES(cu, bezt)) {
bezt1 = bezt;
bezt2 = bezt + 1;
if ((bezt2->f1 & SELECT) || (bezt2->f2 & SELECT) || (bezt2->f3 & SELECT)) {
/* pass */
}
else { /* maybe do not make cyclic */
- if (a == 0 && (nu->flagu & CU_NURB_CYCLIC) ) {
+ if (a == 0 && (nu->flagu & CU_NURB_CYCLIC)) {
bezt2 = bezt + (nu->pntsu - 1);
- if ( (bezt2->f1 & SELECT) || (bezt2->f2 & SELECT) || (bezt2->f3 & SELECT) ) {
+ if ((bezt2->f1 & SELECT) || (bezt2->f2 & SELECT) || (bezt2->f3 & SELECT)) {
nu->flagu &= ~CU_NURB_CYCLIC;
BKE_nurb_handles_calc(nu);
WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data);
@@ -5925,7 +5976,7 @@ static int delete_exec(bContext *C, wmOperator *op)
/* pass */
}
else { /* maybe do not make cyclic */
- if (a == 0 && (nu->flagu & CU_NURB_CYCLIC) ) {
+ if (a == 0 && (nu->flagu & CU_NURB_CYCLIC)) {
bp2 = bp + (nu->pntsu - 1);
if (bp2->f1 & SELECT) {
nu->flagu &= ~CU_NURB_CYCLIC;
@@ -6046,7 +6097,7 @@ static int delete_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int delete_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int delete_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
Object *obedit = CTX_data_edit_object(C);
uiPopupMenu *pup;
@@ -6187,10 +6238,12 @@ int join_curve_exec(bContext *C, wmOperator *UNUSED(op))
if (ob->totcol) { /* TODO, merge material lists */
CLAMP(newnu->mat_nr, 0, ob->totcol - 1);
}
- else newnu->mat_nr = 0;
+ else {
+ newnu->mat_nr = 0;
+ }
BLI_addtail(&tempbase, newnu);
- if ( (bezt = newnu->bezt) ) {
+ if ((bezt = newnu->bezt)) {
a = newnu->pntsu;
while (a--) {
mul_m4_v3(cmat, bezt->vec[0]);
@@ -6200,7 +6253,7 @@ int join_curve_exec(bContext *C, wmOperator *UNUSED(op))
}
BKE_nurb_handles_calc(newnu);
}
- if ( (bp = newnu->bp) ) {
+ if ((bp = newnu->bp)) {
a = newnu->pntsu * nu->pntsv;
while (a--) {
mul_m4_v3(cmat, bp->vec);
@@ -6653,14 +6706,18 @@ static int curvesurf_prim_add(bContext *C, wmOperator *op, int type, int isSurf)
if (type & CU_PRIM_PATH)
cu->flag |= CU_PATH | CU_3D;
}
- else DAG_id_tag_update(&obedit->id, OB_RECALC_DATA);
+ else {
+ DAG_id_tag_update(&obedit->id, OB_RECALC_DATA);
+ }
}
else { /* adding surface */
if (obedit == NULL || obedit->type != OB_SURF) {
obedit = ED_object_add_type(C, OB_SURF, loc, rot, TRUE, layer);
newob = 1;
}
- else DAG_id_tag_update(&obedit->id, OB_RECALC_DATA);
+ else {
+ DAG_id_tag_update(&obedit->id, OB_RECALC_DATA);
+ }
}
/* rename here, the undo stack checks name for valid undo pushes */
diff --git a/source/blender/editors/curve/editfont.c b/source/blender/editors/curve/editfont.c
index af6b90a9958..63444c5c17e 100644
--- a/source/blender/editors/curve/editfont.c
+++ b/source/blender/editors/curve/editfont.c
@@ -405,7 +405,7 @@ static int paste_file_exec(bContext *C, wmOperator *op)
return retval;
}
-static int paste_file_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int paste_file_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
if (RNA_struct_property_is_set(op->ptr, "filepath"))
return paste_file_exec(C, op);
@@ -1221,16 +1221,16 @@ static int insert_text_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int insert_text_invoke(bContext *C, wmOperator *op, wmEvent *evt)
+static int insert_text_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
Scene *scene = CTX_data_scene(C);
Object *obedit = CTX_data_edit_object(C);
Curve *cu = obedit->data;
EditFont *ef = cu->editfont;
static int accentcode = 0;
- uintptr_t ascii = evt->ascii;
- int alt = evt->alt, shift = evt->shift, ctrl = evt->ctrl;
- int event = evt->type, val = evt->val;
+ uintptr_t ascii = event->ascii;
+ int alt = event->alt, shift = event->shift, ctrl = event->ctrl;
+ int event_type = event->type, event_val = event->val;
wchar_t inserted_text[2] = {0};
if (RNA_struct_property_is_set(op->ptr, "text"))
@@ -1243,26 +1243,26 @@ static int insert_text_invoke(bContext *C, wmOperator *op, wmEvent *evt)
}
/* tab should exit editmode, but we allow it to be typed using modifier keys */
- if (event == TABKEY) {
+ if (event_type == TABKEY) {
if ((alt || ctrl || shift) == 0)
return OPERATOR_PASS_THROUGH;
else
ascii = 9;
}
- if (event == BACKSPACEKEY) {
+ if (event_type == BACKSPACEKEY) {
if (alt && cu->len != 0 && cu->pos > 0)
accentcode = 1;
return OPERATOR_PASS_THROUGH;
}
- if (val && (ascii || evt->utf8_buf[0])) {
+ if (event_val && (ascii || event->utf8_buf[0])) {
/* handle case like TAB (== 9) */
if ( (ascii > 31 && ascii < 254 && ascii != 127) ||
(ascii == 13) ||
(ascii == 10) ||
(ascii == 8) ||
- (evt->utf8_buf[0]))
+ (event->utf8_buf[0]))
{
if (accentcode) {
@@ -1272,8 +1272,8 @@ static int insert_text_invoke(bContext *C, wmOperator *op, wmEvent *evt)
}
accentcode = 0;
}
- else if (evt->utf8_buf[0]) {
- BLI_strncpy_wchar_from_utf8(inserted_text, evt->utf8_buf, 1);
+ else if (event->utf8_buf[0]) {
+ BLI_strncpy_wchar_from_utf8(inserted_text, event->utf8_buf, 1);
ascii = inserted_text[0];
insert_into_textbuf(obedit, ascii);
accentcode = 0;
@@ -1307,7 +1307,7 @@ static int insert_text_invoke(bContext *C, wmOperator *op, wmEvent *evt)
}
/* reset property? */
- if (val == 0)
+ if (event_val == 0)
accentcode = 0;
return OPERATOR_FINISHED;
@@ -1643,7 +1643,7 @@ static int font_open_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int open_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int open_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
VFont *vfont = NULL;
char *path;
diff --git a/source/blender/editors/datafiles/SConscript b/source/blender/editors/datafiles/SConscript
index c17ab386fe6..d4e6ed4aff8 100644
--- a/source/blender/editors/datafiles/SConscript
+++ b/source/blender/editors/datafiles/SConscript
@@ -35,75 +35,75 @@ incs = ""
# generated data files
import os
sources.extend((
- os.path.join(env['DATA_SOURCES'], "bfont.pfb.c"),
- os.path.join(env['DATA_SOURCES'], "bfont.ttf.c"),
- os.path.join(env['DATA_SOURCES'], "bmonofont.ttf.c"),
+ os.path.join(env['DATA_SOURCES'], "bfont.pfb.c"),
+ os.path.join(env['DATA_SOURCES'], "bfont.ttf.c"),
+ os.path.join(env['DATA_SOURCES'], "bmonofont.ttf.c"),
- os.path.join(env['DATA_SOURCES'], "splash.png.c"),
- os.path.join(env['DATA_SOURCES'], "blender_icons16.png.c"),
- os.path.join(env['DATA_SOURCES'], "blender_icons32.png.c"),
- os.path.join(env['DATA_SOURCES'], "prvicons.png.c"),
+ os.path.join(env['DATA_SOURCES'], "splash.png.c"),
+ os.path.join(env['DATA_SOURCES'], "blender_icons16.png.c"),
+ os.path.join(env['DATA_SOURCES'], "blender_icons32.png.c"),
+ os.path.join(env['DATA_SOURCES'], "prvicons.png.c"),
- os.path.join(env['DATA_SOURCES'], "startup.blend.c"),
- os.path.join(env['DATA_SOURCES'], "preview.blend.c"),
- os.path.join(env['DATA_SOURCES'], "preview_cycles.blend.c"),
-
- os.path.join(env['DATA_SOURCES'], "add.png.c"),
- os.path.join(env['DATA_SOURCES'], "blob.png.c"),
- os.path.join(env['DATA_SOURCES'], "blur.png.c"),
- os.path.join(env['DATA_SOURCES'], "clay.png.c"),
- os.path.join(env['DATA_SOURCES'], "claystrips.png.c"),
- os.path.join(env['DATA_SOURCES'], "clone.png.c"),
- os.path.join(env['DATA_SOURCES'], "crease.png.c"),
- os.path.join(env['DATA_SOURCES'], "darken.png.c"),
- os.path.join(env['DATA_SOURCES'], "draw.png.c"),
- os.path.join(env['DATA_SOURCES'], "fill.png.c"),
- os.path.join(env['DATA_SOURCES'], "flatten.png.c"),
- os.path.join(env['DATA_SOURCES'], "grab.png.c"),
- os.path.join(env['DATA_SOURCES'], "inflate.png.c"),
- os.path.join(env['DATA_SOURCES'], "layer.png.c"),
- os.path.join(env['DATA_SOURCES'], "lighten.png.c"),
- os.path.join(env['DATA_SOURCES'], "mask.png.c"),
- os.path.join(env['DATA_SOURCES'], "mix.png.c"),
- os.path.join(env['DATA_SOURCES'], "multiply.png.c"),
- os.path.join(env['DATA_SOURCES'], "nudge.png.c"),
- os.path.join(env['DATA_SOURCES'], "pinch.png.c"),
- os.path.join(env['DATA_SOURCES'], "scrape.png.c"),
- os.path.join(env['DATA_SOURCES'], "smear.png.c"),
- os.path.join(env['DATA_SOURCES'], "smooth.png.c"),
- os.path.join(env['DATA_SOURCES'], "snake_hook.png.c"),
- os.path.join(env['DATA_SOURCES'], "soften.png.c"),
- os.path.join(env['DATA_SOURCES'], "subtract.png.c"),
- os.path.join(env['DATA_SOURCES'], "texdraw.png.c"),
- os.path.join(env['DATA_SOURCES'], "thumb.png.c"),
- os.path.join(env['DATA_SOURCES'], "twist.png.c"),
- os.path.join(env['DATA_SOURCES'], "vertexdraw.png.c"),
-
- os.path.join(env['DATA_SOURCES'], "mc01.jpg.c"),
- os.path.join(env['DATA_SOURCES'], "mc02.jpg.c"),
- os.path.join(env['DATA_SOURCES'], "mc03.jpg.c"),
- os.path.join(env['DATA_SOURCES'], "mc04.jpg.c"),
- os.path.join(env['DATA_SOURCES'], "mc05.jpg.c"),
- os.path.join(env['DATA_SOURCES'], "mc06.jpg.c"),
- os.path.join(env['DATA_SOURCES'], "mc07.jpg.c"),
- os.path.join(env['DATA_SOURCES'], "mc08.jpg.c"),
- os.path.join(env['DATA_SOURCES'], "mc09.jpg.c"),
- os.path.join(env['DATA_SOURCES'], "mc10.jpg.c"),
- os.path.join(env['DATA_SOURCES'], "mc11.jpg.c"),
- os.path.join(env['DATA_SOURCES'], "mc12.jpg.c"),
- os.path.join(env['DATA_SOURCES'], "mc13.jpg.c"),
- os.path.join(env['DATA_SOURCES'], "mc14.jpg.c"),
- os.path.join(env['DATA_SOURCES'], "mc15.jpg.c"),
- os.path.join(env['DATA_SOURCES'], "mc16.jpg.c"),
- os.path.join(env['DATA_SOURCES'], "mc17.jpg.c"),
- os.path.join(env['DATA_SOURCES'], "mc18.jpg.c"),
- os.path.join(env['DATA_SOURCES'], "mc19.jpg.c"),
- os.path.join(env['DATA_SOURCES'], "mc20.jpg.c"),
- os.path.join(env['DATA_SOURCES'], "mc21.jpg.c"),
- os.path.join(env['DATA_SOURCES'], "mc22.jpg.c"),
- os.path.join(env['DATA_SOURCES'], "mc23.jpg.c"),
- os.path.join(env['DATA_SOURCES'], "mc24.jpg.c"),
+ os.path.join(env['DATA_SOURCES'], "startup.blend.c"),
+ os.path.join(env['DATA_SOURCES'], "preview.blend.c"),
+ os.path.join(env['DATA_SOURCES'], "preview_cycles.blend.c"),
- ))
+ os.path.join(env['DATA_SOURCES'], "add.png.c"),
+ os.path.join(env['DATA_SOURCES'], "blob.png.c"),
+ os.path.join(env['DATA_SOURCES'], "blur.png.c"),
+ os.path.join(env['DATA_SOURCES'], "clay.png.c"),
+ os.path.join(env['DATA_SOURCES'], "claystrips.png.c"),
+ os.path.join(env['DATA_SOURCES'], "clone.png.c"),
+ os.path.join(env['DATA_SOURCES'], "crease.png.c"),
+ os.path.join(env['DATA_SOURCES'], "darken.png.c"),
+ os.path.join(env['DATA_SOURCES'], "draw.png.c"),
+ os.path.join(env['DATA_SOURCES'], "fill.png.c"),
+ os.path.join(env['DATA_SOURCES'], "flatten.png.c"),
+ os.path.join(env['DATA_SOURCES'], "grab.png.c"),
+ os.path.join(env['DATA_SOURCES'], "inflate.png.c"),
+ os.path.join(env['DATA_SOURCES'], "layer.png.c"),
+ os.path.join(env['DATA_SOURCES'], "lighten.png.c"),
+ os.path.join(env['DATA_SOURCES'], "mask.png.c"),
+ os.path.join(env['DATA_SOURCES'], "mix.png.c"),
+ os.path.join(env['DATA_SOURCES'], "multiply.png.c"),
+ os.path.join(env['DATA_SOURCES'], "nudge.png.c"),
+ os.path.join(env['DATA_SOURCES'], "pinch.png.c"),
+ os.path.join(env['DATA_SOURCES'], "scrape.png.c"),
+ os.path.join(env['DATA_SOURCES'], "smear.png.c"),
+ os.path.join(env['DATA_SOURCES'], "smooth.png.c"),
+ os.path.join(env['DATA_SOURCES'], "snake_hook.png.c"),
+ os.path.join(env['DATA_SOURCES'], "soften.png.c"),
+ os.path.join(env['DATA_SOURCES'], "subtract.png.c"),
+ os.path.join(env['DATA_SOURCES'], "texdraw.png.c"),
+ os.path.join(env['DATA_SOURCES'], "thumb.png.c"),
+ os.path.join(env['DATA_SOURCES'], "twist.png.c"),
+ os.path.join(env['DATA_SOURCES'], "vertexdraw.png.c"),
+
+ os.path.join(env['DATA_SOURCES'], "mc01.jpg.c"),
+ os.path.join(env['DATA_SOURCES'], "mc02.jpg.c"),
+ os.path.join(env['DATA_SOURCES'], "mc03.jpg.c"),
+ os.path.join(env['DATA_SOURCES'], "mc04.jpg.c"),
+ os.path.join(env['DATA_SOURCES'], "mc05.jpg.c"),
+ os.path.join(env['DATA_SOURCES'], "mc06.jpg.c"),
+ os.path.join(env['DATA_SOURCES'], "mc07.jpg.c"),
+ os.path.join(env['DATA_SOURCES'], "mc08.jpg.c"),
+ os.path.join(env['DATA_SOURCES'], "mc09.jpg.c"),
+ os.path.join(env['DATA_SOURCES'], "mc10.jpg.c"),
+ os.path.join(env['DATA_SOURCES'], "mc11.jpg.c"),
+ os.path.join(env['DATA_SOURCES'], "mc12.jpg.c"),
+ os.path.join(env['DATA_SOURCES'], "mc13.jpg.c"),
+ os.path.join(env['DATA_SOURCES'], "mc14.jpg.c"),
+ os.path.join(env['DATA_SOURCES'], "mc15.jpg.c"),
+ os.path.join(env['DATA_SOURCES'], "mc16.jpg.c"),
+ os.path.join(env['DATA_SOURCES'], "mc17.jpg.c"),
+ os.path.join(env['DATA_SOURCES'], "mc18.jpg.c"),
+ os.path.join(env['DATA_SOURCES'], "mc19.jpg.c"),
+ os.path.join(env['DATA_SOURCES'], "mc20.jpg.c"),
+ os.path.join(env['DATA_SOURCES'], "mc21.jpg.c"),
+ os.path.join(env['DATA_SOURCES'], "mc22.jpg.c"),
+ os.path.join(env['DATA_SOURCES'], "mc23.jpg.c"),
+ os.path.join(env['DATA_SOURCES'], "mc24.jpg.c"),
+
+ ))
env.BlenderLib ( 'bf_editor_datafiles', sources, Split(incs), [], libtype=['core', 'player'], priority=[235, 30] )
diff --git a/source/blender/editors/gpencil/gpencil_buttons.c b/source/blender/editors/gpencil/gpencil_buttons.c
index 0aa109a0aef..19c1bc34f5c 100644
--- a/source/blender/editors/gpencil/gpencil_buttons.c
+++ b/source/blender/editors/gpencil/gpencil_buttons.c
@@ -86,6 +86,29 @@ static void gp_ui_dellayer_cb(bContext *C, void *gpd, void *gpl)
WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
}
+/* move layer up */
+static void gp_ui_layer_up_cb(bContext *C, void *gpd_v, void *gpl_v)
+{
+ bGPdata *gpd = gpd_v;
+ bGPDlayer *gpl = gpl_v;
+
+ BLI_remlink(&gpd->layers, gpl);
+ BLI_insertlinkbefore(&gpd->layers, gpl->prev, gpl);
+
+ WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
+}
+
+/* move layer down */
+static void gp_ui_layer_down_cb(bContext *C, void *gpd_v, void *gpl_v)
+{
+ bGPdata *gpd = gpd_v;
+ bGPDlayer *gpl = gpl_v;
+
+ BLI_remlink(&gpd->layers, gpl);
+ BLI_insertlinkafter(&gpd->layers, gpl->next, gpl);
+
+ WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
+}
/* ------- Drawing Code ------- */
@@ -174,6 +197,18 @@ static void gp_drawui_layer(uiLayout *layout, bGPdata *gpd, bGPDlayer *gpl, cons
/* name */
uiItemR(sub, &ptr, "info", 0, "", ICON_NONE);
+ /* move up/down */
+ if (gpl->prev) {
+ but = uiDefIconBut(block, BUT, 0, ICON_TRIA_UP, 0, 0, UI_UNIT_X, UI_UNIT_Y,
+ NULL, 0.0, 0.0, 0.0, 0.0, TIP_("Move layer up"));
+ uiButSetFunc(but, gp_ui_layer_up_cb, gpd, gpl);
+ }
+ if (gpl->next) {
+ but = uiDefIconBut(block, BUT, 0, ICON_TRIA_DOWN, 0, 0, UI_UNIT_X, UI_UNIT_Y,
+ NULL, 0.0, 0.0, 0.0, 0.0, TIP_("Move layer down"));
+ uiButSetFunc(but, gp_ui_layer_down_cb, gpd, gpl);
+ }
+
/* delete 'button' */
uiBlockSetEmboss(block, UI_EMBOSSN);
/* right-align ............................... */
diff --git a/source/blender/editors/gpencil/gpencil_paint.c b/source/blender/editors/gpencil/gpencil_paint.c
index 46815450bf2..bc68ad8869a 100644
--- a/source/blender/editors/gpencil/gpencil_paint.c
+++ b/source/blender/editors/gpencil/gpencil_paint.c
@@ -277,6 +277,7 @@ static void gp_stroke_convertcoords(tGPsdata *p, const int mval[2], float out[3]
int mval_prj[2];
float rvec[3], dvec[3];
float mval_f[2];
+ float zfac;
/* Current method just converts each point in screen-coordinates to
* 3D-coordinates using the 3D-cursor as reference. In general, this
@@ -288,12 +289,13 @@ static void gp_stroke_convertcoords(tGPsdata *p, const int mval[2], float out[3]
*/
gp_get_3d_reference(p, rvec);
+ zfac = ED_view3d_calc_zfac(p->ar->regiondata, rvec, NULL);
/* method taken from editview.c - mouse_cursor() */
/* TODO, use ED_view3d_project_float_global */
if (ED_view3d_project_int_global(p->ar, rvec, mval_prj, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) {
VECSUB2D(mval_f, mval_prj, mval);
- ED_view3d_win_to_delta(p->ar, mval_f, dvec);
+ ED_view3d_win_to_delta(p->ar, mval_f, dvec, zfac);
sub_v3_v3v3(out, rvec, dvec);
}
else {
@@ -1237,13 +1239,6 @@ static void gp_paint_initstroke(tGPsdata *p, short paintmode)
switch (p->sa->spacetype) {
case SPACE_VIEW3D:
{
- RegionView3D *rv3d = p->ar->regiondata;
- float rvec[3];
-
- /* get reference point for 3d space placement */
- gp_get_3d_reference(p, rvec);
- initgrabz(rv3d, rvec[0], rvec[1], rvec[2]);
-
p->gpd->sbuffer_sflag |= GP_STROKE_3DSPACE;
}
break;
@@ -1551,7 +1546,7 @@ static void gpencil_draw_apply(wmOperator *op, tGPsdata *p)
}
/* handle draw event */
-static void gpencil_draw_apply_event(wmOperator *op, wmEvent *event)
+static void gpencil_draw_apply_event(wmOperator *op, const wmEvent *event)
{
tGPsdata *p = op->customdata;
PointerRNA itemptr;
@@ -1689,7 +1684,7 @@ static int gpencil_draw_exec(bContext *C, wmOperator *op)
/* ------------------------------- */
/* start of interactive drawing part of operator */
-static int gpencil_draw_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int gpencil_draw_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
tGPsdata *p = NULL;
wmWindow *win = CTX_wm_window(C);
@@ -1800,7 +1795,7 @@ static void gpencil_stroke_end(wmOperator *op)
}
/* events handling during interactive drawing part of operator */
-static int gpencil_draw_modal(bContext *C, wmOperator *op, wmEvent *event)
+static int gpencil_draw_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
tGPsdata *p = op->customdata;
int estate = OPERATOR_PASS_THROUGH; /* default exit state - pass through to support MMB view nav, etc. */
diff --git a/source/blender/editors/include/BIF_glutil.h b/source/blender/editors/include/BIF_glutil.h
index 31f89063f05..39d1e283f54 100644
--- a/source/blender/editors/include/BIF_glutil.h
+++ b/source/blender/editors/include/BIF_glutil.h
@@ -129,7 +129,7 @@ void glaRasterPosSafe2f(float x, float y, float known_good_x, float known_good_y
void glaDrawPixelsSafe(float x, float y, int img_w, int img_h, int row_w, int format, int type, void *rect);
/**
- * Functions like a limited glDrawPixels, but actually draws the
+ * glaDrawPixelsTex - Functions like a limited glDrawPixels, but actually draws the
* image using textures, which can be tremendously faster on low-end
* cards, and also avoids problems with the raster position being
* clipped when offscreen. The routine respects the glPixelZoom values,
@@ -141,9 +141,17 @@ void glaDrawPixelsSafe(float x, float y, int img_w, int img_h, int row_w, int fo
* 1-to-1 mapping to screen space.
*/
-void glaDrawPixelsTex(float x, float y, int img_w, int img_h, int format, void *rect);
+void glaDrawPixelsTex(float x, float y, int img_w, int img_h, int format, int zoomfilter, void *rect);
-void glaDrawPixelsTexScaled(float x, float y, int img_w, int img_h, int format, void *rect, float scaleX, float scaleY);
+/**
+ * glaDrawPixelsAuto - Switches between texture or pixel drawing using UserDef.
+ * only RGBA
+ * needs glaDefine2DArea to be set.
+ */
+void glaDrawPixelsAuto(float x, float y, int img_w, int img_h, int format, int zoomfilter, void *rect);
+
+
+void glaDrawPixelsTexScaled(float x, float y, int img_w, int img_h, int format, int zoomfilter, void *rect, float scaleX, float scaleY);
/* 2D Drawing Assistance */
diff --git a/source/blender/editors/include/ED_anim_api.h b/source/blender/editors/include/ED_anim_api.h
index 414d2075bf6..625ef27f4f7 100644
--- a/source/blender/editors/include/ED_anim_api.h
+++ b/source/blender/editors/include/ED_anim_api.h
@@ -298,11 +298,14 @@ typedef enum eAnimFilter_Flags {
#define SEL_MASKLAY(masklay) (masklay->flag & SELECT)
-
/* NLA only */
#define SEL_NLT(nlt) (nlt->flag & NLATRACK_SELECTED)
#define EDITABLE_NLT(nlt) ((nlt->flag & NLATRACK_PROTECTED) == 0)
+
+/* AnimData - NLA mostly... */
+#define SEL_ANIMDATA(adt) (adt->flag & ADT_UI_SELECTED)
+
/* -------------- Channel Defines -------------- */
/* channel heights */
diff --git a/source/blender/editors/include/ED_armature.h b/source/blender/editors/include/ED_armature.h
index 30ac360cab6..310b60f13e8 100644
--- a/source/blender/editors/include/ED_armature.h
+++ b/source/blender/editors/include/ED_armature.h
@@ -61,7 +61,7 @@ typedef struct EditBone {
* normal bones when leaving editmode. */
void *temp; /* Used to store temporary data */
- char name[64]; /* MAX_NAME */
+ char name[64]; /* MAXBONENAME */
float roll; /* Roll along axis. We'll ultimately use the axis/angle method
* for determining the transformation matrix of the bone. The axis
* is tail-head while roll provides the angle. Refer to Graphics
@@ -135,6 +135,7 @@ void ED_armature_validate_active(struct bArmature *arm);
void add_primitive_bone(struct Scene *scene, struct View3D *v3d, struct RegionView3D *rv3d);
struct EditBone *ED_armature_edit_bone_add(struct bArmature *arm, const char *name);
void ED_armature_edit_bone_remove(struct bArmature *arm, EditBone *exBone);
+bool ED_armature_ebone_is_child_recursive(EditBone *ebone_parent, EditBone *ebone_child);
void transform_armature_mirror_update(struct Object *obedit);
void ED_armature_origin_set(struct Scene *scene, struct Object *ob, float cursor[3], int centermode, int around);
diff --git a/source/blender/editors/include/ED_curve.h b/source/blender/editors/include/ED_curve.h
index d66cc49a5d0..66c1798f507 100644
--- a/source/blender/editors/include/ED_curve.h
+++ b/source/blender/editors/include/ED_curve.h
@@ -63,8 +63,6 @@ void load_editNurb(struct Object *obedit);
void make_editNurb(struct Object *obedit);
void free_editNurb(struct Object *obedit);
-void BKE_curve_editNurb_free(struct Curve *cu);
-
int mouse_nurb(struct bContext *C, const int mval[2], int extend, int deselect, int toggle);
struct Nurb *add_nurbs_primitive(struct bContext *C, struct Object *obedit, float mat[4][4], int type, int newob);
diff --git a/source/blender/editors/include/ED_fileselect.h b/source/blender/editors/include/ED_fileselect.h
index d45504b3325..b7d9f811349 100644
--- a/source/blender/editors/include/ED_fileselect.h
+++ b/source/blender/editors/include/ED_fileselect.h
@@ -31,10 +31,11 @@
#ifndef __ED_FILESELECT_H__
#define __ED_FILESELECT_H__
-struct SpaceFile;
struct ARegion;
struct FileSelectParams;
+struct SpaceFile;
struct bContext;
+struct wmWindowManager;
#define FILE_LAYOUT_HOR 1
#define FILE_LAYOUT_VER 2
@@ -99,9 +100,9 @@ void ED_fileselect_layout_tilepos(FileLayout *layout, int tile, int *x, int *y);
void ED_operatormacros_file(void);
-void ED_fileselect_clear(struct bContext *C, struct SpaceFile *sfile);
+void ED_fileselect_clear(struct wmWindowManager *wm, struct SpaceFile *sfile);
-void ED_fileselect_exit(struct bContext *C, struct SpaceFile *sfile);
+void ED_fileselect_exit(struct wmWindowManager *wm, struct SpaceFile *sfile);
int ED_file_extension_icon(const char *relname);
diff --git a/source/blender/editors/include/ED_mesh.h b/source/blender/editors/include/ED_mesh.h
index d3de2593b9d..e704b8f0bf3 100644
--- a/source/blender/editors/include/ED_mesh.h
+++ b/source/blender/editors/include/ED_mesh.h
@@ -172,17 +172,10 @@ void em_setup_viewcontext(struct bContext *C, struct ViewContext *vc); /* renam
extern unsigned int bm_vertoffs, bm_solidoffs, bm_wireoffs;
-
/* mesh_ops.c */
void ED_operatortypes_mesh(void);
void ED_operatormacros_mesh(void);
void ED_keymap_mesh(struct wmKeyConfig *keyconf);
-void ED_keymap_mesh(struct wmKeyConfig *keyconf);
-
-
-/* spacetypes.c */
-void ED_spacetypes_init(void);
-
/* editmesh_tools.c (could be moved) */
void EMBM_project_snap_verts(struct bContext *C, struct ARegion *ar, struct BMEditMesh *em);
@@ -193,13 +186,14 @@ void paintface_flush_flags(struct Object *ob);
int paintface_mouse_select(struct bContext *C, struct Object *ob, const int mval[2], int extend, int deselect, int toggle);
int do_paintface_box_select(struct ViewContext *vc, struct rcti *rect, int select, int extend);
void paintface_deselect_all_visible(struct Object *ob, int action, short flush_flags);
-void paintface_select_linked(struct bContext *C, struct Object *ob, int mval[2], int mode);
+void paintface_select_linked(struct bContext *C, struct Object *ob, const int mval[2], int mode);
int paintface_minmax(struct Object *ob, float r_min[3], float r_max[3]);
void paintface_hide(struct Object *ob, const int unselected);
void paintface_reveal(struct Object *ob);
void paintvert_deselect_all_visible(struct Object *ob, int action, short flush_flags);
+void paintvert_select_ungrouped(struct Object *ob, short extend, short flush_flags);
void paintvert_flush_flags(struct Object *ob);
/* mirrtopo */
diff --git a/source/blender/editors/include/ED_numinput.h b/source/blender/editors/include/ED_numinput.h
index 126ea13f0b2..e7d80d96f89 100644
--- a/source/blender/editors/include/ED_numinput.h
+++ b/source/blender/editors/include/ED_numinput.h
@@ -61,7 +61,7 @@ void initNumInput(NumInput *n);
void outputNumInput(NumInput *n, char *str);
short hasNumInput(NumInput *n);
void applyNumInput(NumInput *n, float *vec);
-char handleNumInput(NumInput *n, struct wmEvent *event);
+char handleNumInput(NumInput *n, const struct wmEvent *event);
#define NUM_MODAL_INCREMENT_UP 18
#define NUM_MODAL_INCREMENT_DOWN 19
diff --git a/source/blender/editors/include/ED_screen.h b/source/blender/editors/include/ED_screen.h
index 72208a8e93d..d073eaa5607 100644
--- a/source/blender/editors/include/ED_screen.h
+++ b/source/blender/editors/include/ED_screen.h
@@ -71,7 +71,6 @@ void ED_region_visible_rect(struct ARegion *ar, struct rcti *rect);
/* spaces */
-void ED_spacetypes_init(void);
void ED_spacetypes_keymap(struct wmKeyConfig *keyconf);
int ED_area_header_switchbutton(const struct bContext *C, struct uiBlock *block, int yco);
int ED_area_header_standardbuttons(const struct bContext *C, struct uiBlock *block, int yco);
diff --git a/source/blender/editors/include/ED_sequencer.h b/source/blender/editors/include/ED_sequencer.h
index 23d173aebdc..21477a72014 100644
--- a/source/blender/editors/include/ED_sequencer.h
+++ b/source/blender/editors/include/ED_sequencer.h
@@ -31,7 +31,7 @@ struct Scene;
struct Sequence;
struct SpaceSeq;
-void ED_sequencer_select_sequence_single(struct Scene *scene, struct Sequence *seq, int deselect_all);
+void ED_sequencer_select_sequence_single(struct Scene *scene, struct Sequence *seq, bool deselect_all);
void ED_sequencer_deselect_all(struct Scene *scene);
int ED_space_sequencer_maskedit_mask_poll(struct bContext *C);
diff --git a/source/blender/editors/include/ED_space_api.h b/source/blender/editors/include/ED_space_api.h
index c8521cb194a..a40cf90f7ad 100644
--- a/source/blender/editors/include/ED_space_api.h
+++ b/source/blender/editors/include/ED_space_api.h
@@ -34,6 +34,8 @@
struct ARegionType;
struct bContext;
+void ED_spacetypes_init(void);
+
/* the pluginnable API for export to editors */
/* calls for registering default spaces */
diff --git a/source/blender/editors/include/ED_transform.h b/source/blender/editors/include/ED_transform.h
index a41aaca15bd..6101d03b946 100644
--- a/source/blender/editors/include/ED_transform.h
+++ b/source/blender/editors/include/ED_transform.h
@@ -151,7 +151,7 @@ void Transform_Properties(struct wmOperatorType *ot, int flags);
/* view3d manipulators */
-int BIF_do_manipulator(struct bContext *C, struct wmEvent *event, struct wmOperator *op);
+int BIF_do_manipulator(struct bContext *C, const struct wmEvent *event, struct wmOperator *op);
void BIF_draw_manipulator(const struct bContext *C);
/* Snapping */
@@ -177,12 +177,12 @@ typedef enum SnapMode {
#define SNAP_MIN_DISTANCE 30
-int peelObjectsTransForm(struct TransInfo *t, struct ListBase *depth_peels, const float mval[2], SnapMode mode);
-int peelObjectsContext(struct bContext *C, struct ListBase *depth_peels, const float mval[2], SnapMode mode);
-int snapObjectsTransform(struct TransInfo *t, const float mval[2], int *r_dist, float r_loc[3], float r_no[3], SnapMode mode);
-int snapObjectsContext(struct bContext *C, const float mval[2], int *r_dist, float r_loc[3], float r_no[3], SnapMode mode);
-int snapNodesTransform(struct TransInfo *t, const int mval[2], int *r_dist, float r_loc[2], char *r_node_border, SnapMode mode);
-int snapNodesContext(struct bContext *C, const int mval[2], int *r_dist, float r_loc[2], char *r_node_border, SnapMode mode);
+bool peelObjectsTransForm(struct TransInfo *t, struct ListBase *depth_peels, const float mval[2], SnapMode mode);
+bool peelObjectsContext(struct bContext *C, struct ListBase *depth_peels, const float mval[2], SnapMode mode);
+bool snapObjectsTransform(struct TransInfo *t, const float mval[2], int *r_dist, float r_loc[3], float r_no[3], SnapMode mode);
+bool snapObjectsContext(struct bContext *C, const float mval[2], int *r_dist, float r_loc[3], float r_no[3], SnapMode mode);
+bool snapNodesTransform(struct TransInfo *t, const int mval[2], int *r_dist, float r_loc[2], char *r_node_border, SnapMode mode);
+bool snapNodesContext(struct bContext *C, const int mval[2], int *r_dist, float r_loc[2], char *r_node_border, SnapMode mode);
#endif
diff --git a/source/blender/editors/include/ED_view3d.h b/source/blender/editors/include/ED_view3d.h
index d89d66dd62c..470bbe616cf 100644
--- a/source/blender/editors/include/ED_view3d.h
+++ b/source/blender/editors/include/ED_view3d.h
@@ -39,7 +39,6 @@ struct BMVert;
struct BPoint;
struct Base;
struct BezTriple;
-struct BezTriple;
struct BoundBox;
struct EditBone;
struct ImBuf;
@@ -47,7 +46,6 @@ struct MVert;
struct Main;
struct MetaElem;
struct Nurb;
-struct Nurb;
struct Object;
struct RegionView3D;
struct Scene;
@@ -174,52 +172,58 @@ void pose_foreachScreenBone(
/* view3d_project.c */
-void ED_view3d_project_float_v2_m4(const struct ARegion *a, const float co[3], float r_co[2], float mat[4][4]);
-void ED_view3d_project_float_v3_m4(struct ARegion *a, const float co[3], float r_co[3], float mat[4][4]);
+void ED_view3d_project_float_v2_m4(const struct ARegion *ar, const float co[3], float r_co[2], float mat[4][4]);
+void ED_view3d_project_float_v3_m4(const struct ARegion *ar, const float co[3], float r_co[3], float mat[4][4]);
-eV3DProjStatus ED_view3d_project_base(struct ARegion *ar, struct Base *base);
+eV3DProjStatus ED_view3d_project_base(const struct ARegion *ar, struct Base *base);
/* *** short *** */
-eV3DProjStatus ED_view3d_project_short_ex(struct ARegion *ar, float perspmat[4][4], const int is_local,
+eV3DProjStatus ED_view3d_project_short_ex(const struct ARegion *ar, float perspmat[4][4], const bool is_local,
const float co[3], short r_co[2], const eV3DProjTest flag);
-eV3DProjStatus ED_view3d_project_short_global(struct ARegion *ar, const float co[3], short r_co[2], const eV3DProjTest flag);
-eV3DProjStatus ED_view3d_project_short_object(struct ARegion *ar, const float co[3], short r_co[2], const eV3DProjTest flag);
+eV3DProjStatus ED_view3d_project_short_global(const struct ARegion *ar, const float co[3], short r_co[2], const eV3DProjTest flag);
+eV3DProjStatus ED_view3d_project_short_object(const struct ARegion *ar, const float co[3], short r_co[2], const eV3DProjTest flag);
/* *** int *** */
-eV3DProjStatus ED_view3d_project_int_ex(struct ARegion *ar, float perspmat[4][4], const int is_local,
+eV3DProjStatus ED_view3d_project_int_ex(const struct ARegion *ar, float perspmat[4][4], const bool is_local,
const float co[3], int r_co[2], const eV3DProjTest flag);
-eV3DProjStatus ED_view3d_project_int_global(struct ARegion *ar, const float co[3], int r_co[2], const eV3DProjTest flag);
-eV3DProjStatus ED_view3d_project_int_object(struct ARegion *ar, const float co[3], int r_co[2], const eV3DProjTest flag);
+eV3DProjStatus ED_view3d_project_int_global(const struct ARegion *ar, const float co[3], int r_co[2], const eV3DProjTest flag);
+eV3DProjStatus ED_view3d_project_int_object(const struct ARegion *ar, const float co[3], int r_co[2], const eV3DProjTest flag);
/* *** float *** */
-eV3DProjStatus ED_view3d_project_float_ex(struct ARegion *ar, float perspmat[4][4], const int is_local,
- const float co[3], float r_co[2], const eV3DProjTest flag);
-eV3DProjStatus ED_view3d_project_float_global(struct ARegion *ar, const float co[3], float r_co[2], const eV3DProjTest flag);
-eV3DProjStatus ED_view3d_project_float_object(struct ARegion *ar, const float co[3], float r_co[2], const eV3DProjTest flag);
-
-int initgrabz(struct RegionView3D *rv3d, float x, float y, float z);
-void ED_view3d_win_to_ray(struct ARegion *ar, struct View3D *v3d, const float mval[2], float ray_start[3], float ray_normal[3]);
-void ED_view3d_global_to_vector(struct RegionView3D *rv3d, const float coord[3], float vec[3]);
-void ED_view3d_win_to_3d(struct ARegion *ar, const float depth_pt[3], const float mval[2], float out[3]);
-void ED_view3d_win_to_delta(struct ARegion *ar, const float mval[2], float out[3]);
-void ED_view3d_win_to_vector(struct ARegion *ar, const float mval[2], float out[3]);
-void ED_view3d_win_to_segment(struct ARegion *ar, struct View3D *v3d, const float mval[2], float ray_start[3], float ray_end[3]);
-int ED_view3d_win_to_segment_clip(struct ARegion *ar, struct View3D *v3d, const float mval[2], float ray_start[3], float ray_end[3]);
-void ED_view3d_ob_project_mat_get(struct RegionView3D *v3d, struct Object *ob, float pmat[4][4]);
+eV3DProjStatus ED_view3d_project_float_ex(const struct ARegion *ar, float perspmat[4][4], const bool is_local,
+ const float co[3], float r_co[2], const eV3DProjTest flag);
+eV3DProjStatus ED_view3d_project_float_global(const struct ARegion *ar, const float co[3], float r_co[2], const eV3DProjTest flag);
+eV3DProjStatus ED_view3d_project_float_object(const struct ARegion *ar, const float co[3], float r_co[2], const eV3DProjTest flag);
+
+float ED_view3d_calc_zfac(const struct RegionView3D *rv3d, const float co[3], bool *r_flip);
+void ED_view3d_win_to_ray(const struct ARegion *ar, struct View3D *v3d, const float mval[2], float ray_start[3], float ray_normal[3]);
+void ED_view3d_global_to_vector(const struct RegionView3D *rv3d, const float coord[3], float vec[3]);
+void ED_view3d_win_to_3d(const struct ARegion *ar, const float depth_pt[3], const float mval[2], float out[3]);
+void ED_view3d_win_to_delta(const struct ARegion *ar, const float mval[2], float out[3], const float zfac);
+void ED_view3d_win_to_vector(const struct ARegion *ar, const float mval[2], float out[3]);
+void ED_view3d_win_to_segment(const struct ARegion *ar, struct View3D *v3d, const float mval[2], float ray_start[3], float ray_end[3]);
+int ED_view3d_win_to_segment_clip(const struct ARegion *ar, struct View3D *v3d, const float mval[2], float ray_start[3], float ray_end[3]);
+void ED_view3d_ob_project_mat_get(const struct RegionView3D *v3d, struct Object *ob, float pmat[4][4]);
void ED_view3d_unproject(struct bglMats *mats, float out[3], const float x, const float y, const float z);
/* end */
-int ED_view3d_clip_range_get(struct View3D *v3d, struct RegionView3D *rv3d, float *clipsta, float *clipend);
-int ED_view3d_viewplane_get(struct View3D *v3d, struct RegionView3D *rv3d, int winxi, int winyi, struct rctf *viewplane, float *clipsta, float *clipend);
-void ED_view3d_calc_camera_border(struct Scene *scene, struct ARegion *ar, struct View3D *v3d, struct RegionView3D *rv3d, struct rctf *viewborder_r, short no_shift);
-void ED_view3d_calc_camera_border_size(struct Scene *scene, struct ARegion *ar, struct View3D *v3d, struct RegionView3D *rv3d, float size_r[2]);
+bool ED_view3d_clip_range_get(struct View3D *v3d, struct RegionView3D *rv3d,
+ float *r_clipsta, float *r_clipend, const bool use_ortho_factor);
+bool ED_view3d_viewplane_get(struct View3D *v3d, struct RegionView3D *rv3d, int winxi, int winyi,
+ struct rctf *r_viewplane, float *r_clipsta, float *r_clipend);
+void ED_view3d_calc_camera_border(struct Scene *scene, struct ARegion *ar,
+ struct View3D *v3d, struct RegionView3D *rv3d,
+ struct rctf *viewborder_r, const bool no_shift);
+void ED_view3d_calc_camera_border_size(struct Scene *scene, struct ARegion *ar,
+ struct View3D *v3d, struct RegionView3D *rv3d,
+ float r_size[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][4]);
-int ED_view3d_clipping_test(struct RegionView3D *rv3d, const float vec[3], const int is_local);
+int ED_view3d_clipping_test(struct RegionView3D *rv3d, const float co[3], const bool is_local);
void ED_view3d_clipping_set(struct RegionView3D *rv3d);
void ED_view3d_clipping_enable(void);
void ED_view3d_clipping_disable(void);
@@ -255,7 +259,8 @@ short view3d_opengl_select(struct ViewContext *vc, unsigned int *buffer, unsigne
void view3d_set_viewcontext(struct bContext *C, struct ViewContext *vc);
void view3d_operator_needs_opengl(const struct bContext *C);
void view3d_region_operator_needs_opengl(struct wmWindow *win, struct ARegion *ar);
-int view3d_get_view_aligned_coordinate(struct ViewContext *vc, float fp[3], const int mval[2], const short do_fallback);
+bool view3d_get_view_aligned_coordinate(struct ARegion *ar, float fp[3], const int mval[2], const bool do_fallback);
+void view3d_opengl_read_pixels(struct ARegion *ar, int x, int y, int w, int h, int format, int type, void *data);
void view3d_get_transformation(const struct ARegion *ar, struct RegionView3D *rv3d, struct Object *ob, struct bglMats *mats);
/* XXX should move to BLI_math */
@@ -285,7 +290,7 @@ void ED_view3d_offscreen_sky_color_get(struct Scene *scene, float sky_color[3]);
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][4], float winmat[4][4]);
-int ED_view3d_lock(struct RegionView3D *rv3d);
+bool ED_view3d_lock(struct RegionView3D *rv3d);
uint64_t ED_view3d_datamask(struct Scene *scene, struct View3D *v3d);
uint64_t ED_view3d_screen_datamask(struct bScreen *screen);
diff --git a/source/blender/editors/include/UI_resources.h b/source/blender/editors/include/UI_resources.h
index 450d97eb20e..2ac66fb1919 100644
--- a/source/blender/editors/include/UI_resources.h
+++ b/source/blender/editors/include/UI_resources.h
@@ -87,6 +87,7 @@ enum {
TH_TRANSFORM,
TH_VERTEX,
TH_VERTEX_SELECT,
+ TH_VERTEX_UNREFERENCED,
TH_VERTEX_SIZE,
TH_OUTLINE_WIDTH,
TH_EDGE,
diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c
index 2c17a629ed4..4f0d788d733 100644
--- a/source/blender/editors/interface/interface.c
+++ b/source/blender/editors/interface/interface.c
@@ -231,7 +231,9 @@ static void ui_text_bounds_block(uiBlock *block, float offset)
nextcol = 1;
col++;
}
- else nextcol = 0;
+ else {
+ nextcol = 0;
+ }
bt->rect.xmin = x1addval;
bt->rect.xmax = bt->rect.xmin + i + block->bounds;
@@ -1461,6 +1463,8 @@ double ui_get_but_val(uiBut *but)
if (but->rnaprop) {
prop = but->rnaprop;
+ BLI_assert(but->rnaindex != -1);
+
switch (RNA_property_type(prop)) {
case PROP_BOOLEAN:
if (RNA_property_array_check(prop))
@@ -1642,6 +1646,9 @@ static double ui_get_but_scale_unit(uiBut *but, double value)
if (unit_type == PROP_UNIT_LENGTH) {
return value * (double)unit->scale_length;
}
+ else if (unit_type == PROP_UNIT_CAMERA) {
+ return value * (double)unit->scale_length;
+ }
else if (unit_type == PROP_UNIT_AREA) {
return value * pow(unit->scale_length, 2);
}
@@ -1674,18 +1681,28 @@ void ui_convert_to_unit_alt_name(uiBut *but, char *str, size_t maxlen)
}
}
-static void ui_get_but_string_unit(uiBut *but, char *str, int len_max, double value, int pad)
+/**
+ * \param float_precision Override the button precision.
+ */
+static void ui_get_but_string_unit(uiBut *but, char *str, int len_max, double value, int pad, int float_precision)
{
UnitSettings *unit = but->block->unit;
int do_split = unit->flag & USER_UNIT_OPT_SPLIT;
int unit_type = uiButGetUnitType(but);
- int precision = but->a2;
+ int precision;
if (unit->scale_length < 0.0001f) unit->scale_length = 1.0f; // XXX do_versions
- /* Sanity checks */
- if (precision > PRECISION_FLOAT_MAX) precision = PRECISION_FLOAT_MAX;
- else if (precision == 0) precision = 2;
+ /* Use precision override? */
+ if (float_precision == -1) {
+ /* Sanity checks */
+ precision = (int)but->a2;
+ if (precision > PRECISION_FLOAT_MAX) precision = PRECISION_FLOAT_MAX;
+ else if (precision == 0) precision = 2;
+ }
+ else {
+ precision = float_precision;
+ }
bUnit_AsString(str, len_max, ui_get_but_scale_unit(but, value), precision,
unit->system, RNA_SUBTYPE_UNIT_VALUE(unit_type), do_split, pad);
@@ -1706,8 +1723,10 @@ static float ui_get_but_step_unit(uiBut *but, float step_default)
}
}
-
-void ui_get_but_string(uiBut *but, char *str, size_t maxlen)
+/**
+ * \param float_precision For number buttons the precission to use or -1 to fallback to the button default.
+ */
+void ui_get_but_string_ex(uiBut *but, char *str, const size_t maxlen, const int float_precision)
{
if (but->rnaprop && ELEM4(but->type, TEX, IDPOIN, SEARCH_MENU, SEARCH_MENU_UNLINK)) {
PropertyType type;
@@ -1779,10 +1798,10 @@ void ui_get_but_string(uiBut *but, char *str, size_t maxlen)
if (ui_is_but_float(but)) {
if (ui_is_but_unit(but)) {
- ui_get_but_string_unit(but, str, maxlen, value, 0);
+ ui_get_but_string_unit(but, str, maxlen, value, 0, float_precision);
}
else {
- const int prec = ui_but_float_precision(but, value);
+ const int prec = (float_precision == -1) ? ui_but_float_precision(but, value) : float_precision;
BLI_snprintf(str, maxlen, "%.*f", prec, value);
}
}
@@ -1790,6 +1809,10 @@ void ui_get_but_string(uiBut *but, char *str, size_t maxlen)
BLI_snprintf(str, maxlen, "%d", (int)value);
}
}
+void ui_get_but_string(uiBut *but, char *str, const size_t maxlen)
+{
+ ui_get_but_string_ex(but, str, maxlen, -1);
+}
#ifdef WITH_PYTHON
@@ -1984,7 +2007,8 @@ static double soft_range_round_down(double value, double max)
return newmax;
}
-void ui_set_but_soft_range(uiBut *but, double value)
+/* note: this could be split up into functions which handle arrays and not */
+static void ui_set_but_soft_range(uiBut *but)
{
/* ideally we would not limit this but practically, its more then
* enough worst case is very long vectors wont use a smart soft-range
@@ -1993,14 +2017,14 @@ void ui_set_but_soft_range(uiBut *but, double value)
if (but->rnaprop) {
const PropertyType type = RNA_property_type(but->rnaprop);
double softmin, softmax /*, step, precision*/;
- double value_min = value;
- double value_max = value;
+ double value_min;
+ double value_max;
/* clamp button range to something reasonable in case
* we get -inf/inf from RNA properties */
if (type == PROP_INT) {
+ const bool is_array = RNA_property_array_check(but->rnaprop);
int imin, imax, istep;
- const int array_len = RNA_property_array_length(&but->rnapoin, but->rnaprop);
RNA_property_int_ui_range(&but->rnapoin, but->rnaprop, &imin, &imax, &istep);
softmin = (imin == INT_MIN) ? -1e4 : imin;
@@ -2008,16 +2032,19 @@ void ui_set_but_soft_range(uiBut *but, double value)
/*step = istep;*/ /*UNUSED*/
/*precision = 1;*/ /*UNUSED*/
- if (array_len >= 2) {
+ if (is_array) {
int value_range[2];
RNA_property_int_get_array_range(&but->rnapoin, but->rnaprop, value_range);
value_min = (double)value_range[0];
value_max = (double)value_range[1];
}
+ else {
+ value_min = value_max = (double)RNA_property_int_get(&but->rnapoin, but->rnaprop);
+ }
}
else if (type == PROP_FLOAT) {
+ const bool is_array = RNA_property_array_check(but->rnaprop);
float fmin, fmax, fstep, fprecision;
- const int array_len = RNA_property_array_length(&but->rnapoin, but->rnaprop);
RNA_property_float_ui_range(&but->rnapoin, but->rnaprop, &fmin, &fmax, &fstep, &fprecision);
softmin = (fmin == -FLT_MAX) ? (float)-1e4 : fmin;
@@ -2025,15 +2052,19 @@ void ui_set_but_soft_range(uiBut *but, double value)
/*step = fstep;*/ /*UNUSED*/
/*precision = fprecision;*/ /*UNUSED*/
- if (array_len >= 2) {
+ if (is_array) {
float value_range[2];
RNA_property_float_get_array_range(&but->rnapoin, but->rnaprop, value_range);
value_min = (double)value_range[0];
value_max = (double)value_range[1];
}
+ else {
+ value_min = value_max = (double)RNA_property_float_get(&but->rnapoin, but->rnaprop);
+ }
}
- else
+ else {
return;
+ }
/* if the value goes out of the soft/max range, adapt the range */
if (value_min + 1e-10 < softmin) {
@@ -2260,8 +2291,7 @@ void ui_check_but(uiBut *but)
/* only update soft range while not editing */
if (but->rnaprop && !(but->editval || but->editstr || but->editvec)) {
- UI_GET_BUT_VALUE_INIT(but, value);
- ui_set_but_soft_range(but, value);
+ ui_set_but_soft_range(but);
}
/* test for min and max, icon sliders, etc */
@@ -2345,7 +2375,7 @@ void ui_check_but(uiBut *but)
/* support length type buttons */
else if (ui_is_but_unit(but)) {
char new_str[sizeof(but->drawstr)];
- ui_get_but_string_unit(but, new_str, sizeof(new_str), value, TRUE);
+ ui_get_but_string_unit(but, new_str, sizeof(new_str), value, TRUE, -1);
BLI_snprintf(but->drawstr, sizeof(but->drawstr), "%s%s", but->str, new_str);
}
else {
@@ -2530,7 +2560,9 @@ static void ui_block_do_align_but(uiBut *first, short nr)
else
flag = UI_BUT_ALIGN_TOP | UI_BUT_ALIGN_LEFT;
}
- else flag = UI_BUT_ALIGN_TOP;
+ else {
+ flag = UI_BUT_ALIGN_TOP;
+ }
}
}
else if (buts_are_horiz(but, next)) {
@@ -2550,7 +2582,9 @@ static void ui_block_do_align_but(uiBut *first, short nr)
if (bt == NULL || bt->alignnr != nr) flag = UI_BUT_ALIGN_TOP | UI_BUT_ALIGN_RIGHT;
}
}
- else flag |= UI_BUT_ALIGN_LEFT;
+ else {
+ flag |= UI_BUT_ALIGN_LEFT;
+ }
}
else {
if (cols == 0) {
@@ -2712,8 +2746,8 @@ static uiBut *ui_def_but(uiBlock *block, int type, int retval, const char *str,
but->retval = retval;
slen = strlen(str);
- if (slen >= UI_MAX_NAME_STR - 1) {
- but->str = MEM_mallocN(slen + 2, "ui_def_but str"); /* why +2 ? */
+ if (slen >= UI_MAX_NAME_STR) {
+ but->str = MEM_mallocN(slen + 1, "ui_def_but str");
}
else {
but->str = but->strdata;
@@ -3016,7 +3050,7 @@ static uiBut *ui_def_but_operator_ptr(uiBlock *block, int type, wmOperatorType *
}
#if 0 /* UNUSED */
-static uiBut *UNUSED_FUNCTION(ui_def_but_operator) (uiBlock * block, int type, const char *opname, int opcontext, const char *str, int x, int y, short width, short height, const char *tip)
+static uiBut *UNUSED_FUNCTION(ui_def_but_operator) (uiBlock *block, int type, const char *opname, int opcontext, const char *str, int x, int y, short width, short height, const char *tip)
{
wmOperatorType *ot = WM_operatortype_find(opname, 0);
if (str == NULL && ot == NULL) str = opname;
diff --git a/source/blender/editors/interface/interface_draw.c b/source/blender/editors/interface/interface_draw.c
index e19e89af5da..5486e12c6bf 100644
--- a/source/blender/editors/interface/interface_draw.c
+++ b/source/blender/editors/interface/interface_draw.c
@@ -97,7 +97,9 @@ void uiDrawBox(int mode, float minx, float miny, float maxx, float maxy, float r
}
glVertex2f(maxx, miny + rad);
}
- else glVertex2f(maxx, miny);
+ else {
+ glVertex2f(maxx, miny);
+ }
/* corner right-top */
if (roundboxtype & UI_CNR_TOP_RIGHT) {
@@ -107,7 +109,9 @@ void uiDrawBox(int mode, float minx, float miny, float maxx, float maxy, float r
}
glVertex2f(maxx - rad, maxy);
}
- else glVertex2f(maxx, maxy);
+ else {
+ glVertex2f(maxx, maxy);
+ }
/* corner left-top */
if (roundboxtype & UI_CNR_TOP_LEFT) {
@@ -117,7 +121,9 @@ void uiDrawBox(int mode, float minx, float miny, float maxx, float maxy, float r
}
glVertex2f(minx, maxy - rad);
}
- else glVertex2f(minx, maxy);
+ else {
+ glVertex2f(minx, maxy);
+ }
/* corner left-bottom */
if (roundboxtype & UI_CNR_BOTTOM_LEFT) {
@@ -127,7 +133,9 @@ void uiDrawBox(int mode, float minx, float miny, float maxx, float maxy, float r
}
glVertex2f(minx + rad, miny);
}
- else glVertex2f(minx, miny);
+ else {
+ glVertex2f(minx, miny);
+ }
glEnd();
}
@@ -381,16 +389,7 @@ void uiRoundRect(float minx, float miny, float maxx, float maxy, float rad)
/* (old, used in outliner) plain antialiased filled box */
void uiRoundBox(float minx, float miny, float maxx, float maxy, float rad)
{
- float color[4];
-
- if (roundboxtype & UI_RB_ALPHA) {
- glGetFloatv(GL_CURRENT_COLOR, color);
- color[3] = 0.5;
- glColor4fv(color);
- glEnable(GL_BLEND);
- }
-
- ui_draw_anti_roundbox(GL_POLYGON, minx, miny, maxx, maxy, rad);
+ ui_draw_anti_roundbox(GL_POLYGON, minx, miny, maxx, maxy, rad, roundboxtype & UI_RB_ALPHA);
}
@@ -454,8 +453,7 @@ void ui_draw_but_IMAGE(ARegion *UNUSED(ar), uiBut *but, uiWidgetColors *UNUSED(w
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);
+ glaDrawPixelsAuto((float)rect->xmin, (float)rect->ymin, ibuf->x, ibuf->y, GL_UNSIGNED_BYTE, GL_NEAREST, ibuf->rect);
glPixelZoom(1.0f, 1.0f);
@@ -1301,8 +1299,10 @@ void ui_draw_but_NORMAL(uiBut *but, uiWidgetColors *wcol, rcti *rect)
glEndList();
}
- else glCallList(displist);
-
+ else {
+ glCallList(displist);
+ }
+
/* restore */
glDisable(GL_LIGHTING);
glDisable(GL_CULL_FACE);
@@ -1602,7 +1602,7 @@ void ui_draw_but_TRACKPREVIEW(ARegion *ar, uiBut *but, uiWidgetColors *UNUSED(wc
tmpibuf = BKE_tracking_sample_pattern(scopes->frame_width, scopes->frame_height,
scopes->track_search, scopes->track,
- &scopes->undist_marker, scopes->use_track_mask,
+ &scopes->undist_marker, TRUE, scopes->use_track_mask,
width, height, scopes->track_pos);
if (tmpibuf) {
diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c
index e0d6c293be5..12a6343c7e7 100644
--- a/source/blender/editors/interface/interface_handlers.c
+++ b/source/blender/editors/interface/interface_handlers.c
@@ -235,14 +235,13 @@ void ui_pan_to_scroll(const wmEvent *event, int *type, int *val)
BLI_assert(*type == MOUSEPAN);
/* sign differs, reset */
- if ((dy > 0 && lastdy < 0) || (dy < 0 && lastdy > 0))
+ if ((dy > 0 && lastdy < 0) || (dy < 0 && lastdy > 0)) {
lastdy = dy;
+ }
else {
lastdy += dy;
if (ABS(lastdy) > (int)UI_UNIT_Y) {
- int dy = event->prevy - event->y;
-
if (U.uiflag2 & USER_TRACKPAD_NATURAL)
dy = -dy;
@@ -804,8 +803,6 @@ static void ui_drag_toggle_set(bContext *C, uiDragToggleHandle *drag_info, const
* button we mouse over is X or Y aligned, then lock the mouse to that axis after.
*/
if (drag_info->xy_lock[0] == false && drag_info->xy_lock[1] == false) {
- ARegion *ar = CTX_wm_region(C);
-
/* first store the buttons original coords */
uiBut *but = ui_but_find_mouse_over(ar, xy_input[0], xy_input[1]);
if (but) {
@@ -1402,7 +1399,11 @@ static void ui_but_copy_paste(bContext *C, uiBut *but, uiHandleButtonData *data,
/* pass */
}
else if (mode == 'c') {
- ui_get_but_string(but, buf, sizeof(buf));
+ /* Get many decimal places, then strip trailing zeros.
+ * note: too high values start to give strange results (6 or so is ok) */
+ ui_get_but_string_ex(but, buf, sizeof(buf), 6);
+ BLI_str_rstrip_float_zero(buf, '\0');
+
WM_clipboard_text_set(buf, 0);
}
else {
@@ -1984,6 +1985,10 @@ static void ui_textedit_begin(bContext *C, uiBut *but, uiHandleButtonData *data)
data->str = MEM_callocN(sizeof(char) * data->maxlen + 1, "textedit str");
ui_get_but_string(but, data->str, data->maxlen);
+ if (ui_is_but_float(but) && !ui_is_but_unit(but)) {
+ BLI_str_rstrip_float_zero(data->str, '\0');
+ }
+
if (ELEM3(but->type, NUM, NUMABS, NUMSLI)) {
ui_convert_to_unit_alt_name(but, data->str, data->maxlen);
}
@@ -2327,7 +2332,7 @@ static void ui_numedit_begin(uiBut *but, uiHandleButtonData *data)
data->coba = (ColorBand *)but->poin;
but->editcoba = data->coba;
}
- else if (ELEM3(but->type, BUT_NORMAL, HSVCUBE, HSVCIRCLE)) {
+ else if (ELEM4(but->type, BUT_NORMAL, HSVCUBE, HSVCIRCLE, COLOR)) {
ui_get_but_vectorf(but, data->origvec);
copy_v3_v3(data->vec, data->origvec);
but->editvec = data->vec;
@@ -3149,9 +3154,6 @@ static bool ui_numedit_but_SLI(uiBut *but, uiHandleButtonData *data,
BLI_rctf_clamp_pt_v(&but->rect, data->ungrab_mval);
}
#endif
- if (is_horizontal == false) {
- mx_fl = my_fl;
- }
/* done correcting mouse */
@@ -5013,7 +5015,7 @@ static int ui_but_menu(bContext *C, uiBut *but)
uiLayoutSetOperatorContext(layout, WM_OP_INVOKE_DEFAULT);
if (but->rnapoin.data && but->rnaprop) {
- short is_anim = RNA_property_animateable(&but->rnapoin, but->rnaprop);
+ bool is_anim = RNA_property_animateable(&but->rnapoin, but->rnaprop);
/* second slower test, saved people finding keyframe items in menus when its not possible */
if (is_anim)
@@ -6294,7 +6296,7 @@ static void ui_handle_button_activate(bContext *C, ARegion *ar, uiBut *but, uiBu
static int ui_handle_button_event(bContext *C, const wmEvent *event, uiBut *but)
{
uiHandleButtonData *data = but->active;
- const uiButtonActivateType state_orig = data->state;
+ const uiHandleButtonState state_orig = data->state;
uiBlock *block;
ARegion *ar;
int retval;
@@ -6466,9 +6468,9 @@ static int ui_handle_button_event(bContext *C, const wmEvent *event, uiBut *but)
* This is needed to make sure if a button was active,
* it stays active while the mouse is over it.
* This avoids adding mousemoves, see: [#33466] */
- if (ELEM(state_orig, BUTTON_ACTIVATE, BUTTON_ACTIVATE_OVER)) {
+ if (ELEM(state_orig, BUTTON_STATE_INIT, BUTTON_STATE_HIGHLIGHT)) {
if (ui_but_find_mouse_over(ar, event->x, event->y) == but) {
- button_activate_init(C, ar, but, state_orig);
+ button_activate_init(C, ar, but, BUTTON_ACTIVATE_OVER);
}
}
}
diff --git a/source/blender/editors/interface/interface_icons.c b/source/blender/editors/interface/interface_icons.c
index 086e9dad895..09686d7b416 100644
--- a/source/blender/editors/interface/interface_icons.c
+++ b/source/blender/editors/interface/interface_icons.c
@@ -47,6 +47,7 @@
#include "BLI_math.h"
#include "BLI_blenlib.h"
#include "BLI_utildefines.h"
+#include "BLI_fileops_types.h"
#include "DNA_brush_types.h"
#include "DNA_dynamicpaint_types.h"
@@ -703,10 +704,8 @@ static void init_iconfile_list(struct ListBase *list)
{
IconFile *ifile;
struct direntry *dir;
- int restoredir = 1; /* restore to current directory */
int totfile, i, index = 1;
const char *icondir;
- char olddir[FILE_MAX];
list->first = list->last = NULL;
icondir = BLI_get_folder(BLENDER_DATAFILES, "icons");
@@ -714,12 +713,7 @@ static void init_iconfile_list(struct ListBase *list)
if (icondir == NULL)
return;
- /* since BLI_dir_contents changes the current working directory, restore it
- * back to old value afterwards */
- if (!BLI_current_working_dir(olddir, sizeof(olddir)))
- restoredir = 0;
totfile = BLI_dir_contents(icondir, &dir);
- if (restoredir && !chdir(olddir)) {} /* fix warning about checking return value */
for (i = 0; i < totfile; i++) {
if ((dir[i].type & S_IFREG)) {
@@ -766,18 +760,8 @@ static void init_iconfile_list(struct ListBase *list)
}
}
}
-
- /* free temporary direntry structure that's been created by BLI_dir_contents() */
- i = totfile - 1;
-
- for (; i >= 0; i--) {
- MEM_freeN(dir[i].relname);
- MEM_freeN(dir[i].path);
- if (dir[i].string) {
- MEM_freeN(dir[i].string);
- }
- }
- free(dir);
+
+ BLI_free_filelist(dir, totfile);
dir = NULL;
}
diff --git a/source/blender/editors/interface/interface_intern.h b/source/blender/editors/interface/interface_intern.h
index 9093e8f8d30..6065fcfe574 100644
--- a/source/blender/editors/interface/interface_intern.h
+++ b/source/blender/editors/interface/interface_intern.h
@@ -394,7 +394,8 @@ extern void ui_set_but_vectorf(uiBut *but, const float vec[3]);
extern void ui_hsvcircle_vals_from_pos(float *val_rad, float *val_dist, const rcti *rect,
const float mx, const float my);
-extern void ui_get_but_string(uiBut *but, char *str, size_t maxlen);
+extern void ui_get_but_string_ex(uiBut *but, char *str, const size_t maxlen, const int float_precision);
+extern void ui_get_but_string(uiBut *but, char *str, const size_t maxlen);
extern void ui_convert_to_unit_alt_name(uiBut *but, char *str, size_t maxlen);
extern int ui_set_but_string(struct bContext *C, uiBut *but, const char *str);
extern int ui_get_but_string_max_length(uiBut *but);
@@ -402,8 +403,6 @@ extern int ui_set_but_string_eval_num(struct bContext *C, uiBut *but, const char
extern void ui_set_but_default(struct bContext *C, short all);
-extern void ui_set_but_soft_range(uiBut *but, double value);
-
extern void ui_check_but(uiBut *but);
extern int ui_is_but_float(uiBut *but);
extern int ui_is_but_bool(uiBut *but);
@@ -523,7 +522,7 @@ extern void ui_button_text_password_hide(char password_str[UI_MAX_DRAW_STR], uiB
/* interface_widgets.c */
void ui_draw_anti_tria(float x1, float y1, float x2, float y2, float x3, float y3);
-void ui_draw_anti_roundbox(int mode, float minx, float miny, float maxx, float maxy, float rad);
+void ui_draw_anti_roundbox(int mode, float minx, float miny, float maxx, float maxy, float rad, bool use_alpha);
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);
diff --git a/source/blender/editors/interface/interface_layout.c b/source/blender/editors/interface/interface_layout.c
index 1e95b4df762..2ca26ae5317 100644
--- a/source/blender/editors/interface/interface_layout.c
+++ b/source/blender/editors/interface/interface_layout.c
@@ -1567,7 +1567,7 @@ void uiItemM(uiLayout *layout, bContext *UNUSED(C), const char *menuname, const
}
if (!name) {
- name = IFACE_(mt->label);
+ name = CTX_IFACE_(mt->translation_context, mt->label);
}
if (layout->root->type == UI_LAYOUT_MENU && !icon)
@@ -2369,6 +2369,7 @@ uiLayout *uiLayoutAbsolute(uiLayout *layout, int align)
litem->active = 1;
litem->enabled = 1;
litem->context = layout->context;
+ litem->redalert = layout->redalert;
BLI_addtail(&layout->items, litem);
uiBlockSetCurLayout(layout->root->block, litem);
@@ -2396,6 +2397,7 @@ uiLayout *uiLayoutOverlap(uiLayout *layout)
litem->active = 1;
litem->enabled = 1;
litem->context = layout->context;
+ litem->redalert = layout->redalert;
BLI_addtail(&layout->items, litem);
uiBlockSetCurLayout(layout->root->block, litem);
@@ -2415,6 +2417,7 @@ uiLayout *uiLayoutSplit(uiLayout *layout, float percentage, int align)
split->litem.enabled = 1;
split->litem.context = layout->context;
split->litem.space = layout->root->style->columnspace;
+ split->litem.redalert = layout->redalert;
split->litem.w = layout->w;
split->percentage = percentage;
BLI_addtail(&layout->items, split);
diff --git a/source/blender/editors/interface/interface_ops.c b/source/blender/editors/interface/interface_ops.c
index 3298859ee0c..145deb35667 100644
--- a/source/blender/editors/interface/interface_ops.c
+++ b/source/blender/editors/interface/interface_ops.c
@@ -239,7 +239,7 @@ static void eyedropper_color_sample_accum(bContext *C, Eyedropper *eye, int mx,
}
/* main modal status check */
-static int eyedropper_modal(bContext *C, wmOperator *op, wmEvent *event)
+static int eyedropper_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
Eyedropper *eye = (Eyedropper *)op->customdata;
@@ -285,7 +285,7 @@ static int eyedropper_modal(bContext *C, wmOperator *op, wmEvent *event)
}
/* Modal Operator init */
-static int eyedropper_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int eyedropper_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
/* init */
if (eyedropper_init(C, op)) {
@@ -853,7 +853,7 @@ static int editsource_exec(bContext *C, wmOperator *op)
ED_region_do_draw(C, ar);
for (BLI_ghashIterator_init(&ghi, ui_editsource_info->hash);
- !BLI_ghashIterator_isDone(&ghi);
+ BLI_ghashIterator_notDone(&ghi);
BLI_ghashIterator_step(&ghi))
{
uiBut *but_key = BLI_ghashIterator_getKey(&ghi);
diff --git a/source/blender/editors/interface/interface_panel.c b/source/blender/editors/interface/interface_panel.c
index e466c481151..a741ea432a5 100644
--- a/source/blender/editors/interface/interface_panel.c
+++ b/source/blender/editors/interface/interface_panel.c
@@ -191,7 +191,7 @@ static void ui_panel_copy_offset(Panel *pa, Panel *papar)
Panel *uiBeginPanel(ScrArea *sa, ARegion *ar, uiBlock *block, PanelType *pt, int *open)
{
Panel *pa, *patab, *palast, *panext;
- char *drawname = pt->label;
+ const char *drawname = CTX_IFACE_(pt->translation_context, pt->label);
char *idname = pt->idname;
char *tabname = pt->idname;
char *hookname = NULL;
@@ -469,7 +469,7 @@ static void ui_draw_aligned_panel_header(uiStyle *style, uiBlock *block, rcti *r
Panel *panel = block->panel;
rcti hrect;
int pnl_icons;
- const char *activename = IFACE_(panel->drawname[0] ? panel->drawname : panel->panelname);
+ const char *activename = panel->drawname[0] ? panel->drawname : panel->panelname;
/* + 0.001f to avoid flirting with float inaccuracy */
if (panel->control & UI_PNL_CLOSE) pnl_icons = (panel->labelofs + 2 * PNL_ICON + 5) / block->aspect + 0.001f;
diff --git a/source/blender/editors/interface/interface_regions.c b/source/blender/editors/interface/interface_regions.c
index 03c127f33c8..febd1820e5c 100644
--- a/source/blender/editors/interface/interface_regions.c
+++ b/source/blender/editors/interface/interface_regions.c
@@ -663,9 +663,9 @@ ARegion *ui_tooltip_create(bContext *C, ARegion *butregion, uiBut *but)
/* 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) {
- 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);
+ float ofsx_fl = rect_fl.xmin, ofsy_fl = rect_fl.ymax;
+ ui_block_to_window_fl(butregion, but->block, &ofsx_fl, &ofsy_fl);
+ BLI_rctf_translate(&rect_fl, ofsx_fl - rect_fl.xmin, ofsy_fl - rect_fl.ymax);
}
BLI_rcti_rctf_copy(&rect_i, &rect_fl);
diff --git a/source/blender/editors/interface/interface_style.c b/source/blender/editors/interface/interface_style.c
index ef24ea951e3..dd4886a7243 100644
--- a/source/blender/editors/interface/interface_style.c
+++ b/source/blender/editors/interface/interface_style.c
@@ -216,7 +216,7 @@ void uiStyleFontDrawRotated(uiFontStyle *fs, rcti *rect, const char *str)
/* rotate counter-clockwise for now (assumes left-to-right language)*/
xofs += height;
yofs = BLF_width(fs->uifont_id, str) + 5;
- angle = 90.0f;
+ angle = (float)M_PI / 2.0f;
/* translate rect to vertical */
txtrect.xmin = rect->xmin - BLI_rcti_size_y(rect);
@@ -330,6 +330,8 @@ void uiStyleInit(void)
{
uiFont *font = U.uifonts.first;
uiStyle *style = U.uistyles.first;
+ int monofont_size = datatoc_bmonofont_ttf_size;
+ unsigned char *monofont_ttf = (unsigned char *)datatoc_bmonofont_ttf;
/* recover from uninitialized dpi */
if (U.dpi == 0)
@@ -400,15 +402,33 @@ void uiStyleInit(void)
ui_style_new(&U.uistyles, "Default Style", UIFONT_DEFAULT);
}
+#ifdef WITH_INTERNATIONAL
+ /* use unicode font for text editor and interactive console */
+ if (U.transopts & USER_DOTRANSLATE) {
+ monofont_ttf = BLF_get_unifont_mono(&monofont_size);
+
+ if (!monofont_ttf) {
+ /* fall back if not found */
+ monofont_size = datatoc_bmonofont_ttf_size;
+ monofont_ttf = (unsigned char *)datatoc_bmonofont_ttf;
+ }
+ }
+
+ /* reload */
+ BLF_unload("monospace");
+ blf_mono_font = -1;
+ blf_mono_font_render = -1;
+#endif
+
/* XXX, this should be moved into a style, but for now best only load the monospaced font once. */
if (blf_mono_font == -1)
- blf_mono_font = BLF_load_mem_unique("monospace", (unsigned char *)datatoc_bmonofont_ttf, datatoc_bmonofont_ttf_size);
+ blf_mono_font = BLF_load_mem_unique("monospace", monofont_ttf, monofont_size);
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_mono_font_render = BLF_load_mem_unique("monospace", monofont_ttf, monofont_size);
BLF_size(blf_mono_font_render, 12 * U.pixelsize, 72 );
}
diff --git a/source/blender/editors/interface/interface_templates.c b/source/blender/editors/interface/interface_templates.c
index 83540cef9fc..afb44101910 100644
--- a/source/blender/editors/interface/interface_templates.c
+++ b/source/blender/editors/interface/interface_templates.c
@@ -281,11 +281,13 @@ static void template_id_cb(bContext *C, void *arg_litem, void *arg_event)
if (id->flag & LIB_FAKEUSER) id_us_plus(id);
else id_us_min(id);
}
- else return;
+ else {
+ return;
+ }
break;
case UI_ID_LOCAL:
if (id) {
- if (id_make_local(id, 0)) {
+ if (id_make_local(id, false)) {
/* reassign to get get proper updates/notifiers */
idptr = RNA_property_pointer_get(&template->ptr, template->prop);
RNA_property_pointer_set(&template->ptr, template->prop, idptr);
@@ -465,7 +467,7 @@ static void template_ID(bContext *C, uiLayout *layout, TemplateID *template, Str
else {
but = uiDefIconBut(block, BUT, 0, ICON_LIBRARY_DATA_DIRECT, 0, 0, UI_UNIT_X, UI_UNIT_Y,
NULL, 0, 0, 0, 0, TIP_("Direct linked library datablock, click to make local"));
- if (!id_make_local(id, 1 /* test */) || (idfrom && idfrom->lib))
+ if (!id_make_local(id, true /* test */) || (idfrom && idfrom->lib))
uiButSetFlag(but, UI_BUT_DISABLED);
}
@@ -483,7 +485,7 @@ static void template_ID(bContext *C, uiLayout *layout, TemplateID *template, Str
uiButSetNFunc(but, template_id_cb, MEM_dupallocN(template), SET_INT_IN_POINTER(UI_ID_ALONE));
if (/* test only */
- (id_copy(id, NULL, 1) == FALSE) ||
+ (id_copy(id, NULL, true) == false) ||
(idfrom && idfrom->lib) ||
(editable == FALSE) ||
/* object in editmode - don't change data */
@@ -676,7 +678,7 @@ void uiTemplateAnyID(uiLayout *layout, PointerRNA *ptr, const char *propname, co
const char *text)
{
PropertyRNA *propID, *propType;
- uiLayout *row;
+ uiLayout *split, *row, *sub;
/* get properties... */
propID = RNA_struct_find_property(ptr, propname);
@@ -692,22 +694,34 @@ void uiTemplateAnyID(uiLayout *layout, PointerRNA *ptr, const char *propname, co
}
/* Start drawing UI Elements using standard defines */
- row = uiLayoutRow(layout, TRUE);
+ split = uiLayoutSplit(layout, 0.33f, FALSE); /* NOTE: split amount here needs to be synced with normal labels */
+
+ /* FIRST PART ................................................ */
+ row = uiLayoutRow(split, FALSE);
/* Label - either use the provided text, or will become "ID-Block:" */
if (text) {
if (text[0])
uiItemL(row, text, ICON_NONE);
}
- else
+ else {
uiItemL(row, IFACE_("ID-Block:"), ICON_NONE);
+ }
+
+ /* SECOND PART ................................................ */
+ row = uiLayoutRow(split, TRUE);
/* ID-Type Selector - just have a menu of icons */
- /* FIXME: the icon-only setting doesn't work when we supply a blank name */
- uiItemFullR(row, ptr, propType, 0, 0, UI_ITEM_R_ICON_ONLY, "", ICON_NONE);
+ sub = uiLayoutRow(row, TRUE); /* HACK: special group just for the enum, otherwise we */
+ uiLayoutSetAlignment(sub, UI_LAYOUT_ALIGN_LEFT); /* we get ugly layout with text included too... */
+
+ uiItemFullR(sub, ptr, propType, 0, 0, UI_ITEM_R_ICON_ONLY, "", ICON_NONE);
/* ID-Block Selector - just use pointer widget... */
- uiItemFullR(row, ptr, propID, 0, 0, 0, "", ICON_NONE);
+ sub = uiLayoutRow(row, TRUE); /* HACK: special group to counteract the effects of the previous */
+ uiLayoutSetAlignment(sub, UI_LAYOUT_ALIGN_EXPAND); /* enum, which now pushes everything too far right */
+
+ uiItemFullR(sub, ptr, propID, 0, 0, 0, "", ICON_NONE);
}
/********************* RNA Path Builder Template ********************/
@@ -2135,10 +2149,10 @@ static void curvemap_buttons_layout(uiLayout *layout, PointerRNA *ptr, char labe
uiLayoutRow(layout, TRUE);
uiBlockSetNFunc(block, curvemap_buttons_update, MEM_dupallocN(cb), cumap);
- bt = uiDefButF(block, NUM, 0, "X", 0, 2 * UI_UNIT_Y, UI_UNIT_X * 10, UI_UNIT_Y,
- &cmp->x, bounds.xmin, bounds.xmax, 1, 5, "");
- bt = uiDefButF(block, NUM, 0, "Y", 0, 1 * UI_UNIT_Y, UI_UNIT_X * 10, UI_UNIT_Y,
- &cmp->y, bounds.ymin, bounds.ymax, 1, 5, "");
+ uiDefButF(block, NUM, 0, "X", 0, 2 * UI_UNIT_Y, UI_UNIT_X * 10, UI_UNIT_Y,
+ &cmp->x, bounds.xmin, bounds.xmax, 1, 5, "");
+ uiDefButF(block, NUM, 0, "Y", 0, 1 * UI_UNIT_Y, UI_UNIT_X * 10, UI_UNIT_Y,
+ &cmp->y, bounds.ymin, bounds.ymax, 1, 5, "");
}
/* black/white levels */
@@ -2727,7 +2741,7 @@ static void operator_search_cb(const bContext *C, void *UNUSED(arg), const char
{
GHashIterator *iter = WM_operatortype_iter();
- for (; !BLI_ghashIterator_isDone(iter); BLI_ghashIterator_step(iter)) {
+ for (; BLI_ghashIterator_notDone(iter); BLI_ghashIterator_step(iter)) {
wmOperatorType *ot = BLI_ghashIterator_getValue(iter);
if ((ot->flag & OPTYPE_INTERNAL) && (G.debug & G_DEBUG_WM) == 0)
diff --git a/source/blender/editors/interface/interface_widgets.c b/source/blender/editors/interface/interface_widgets.c
index dd7b1d0ee06..78b6d2541fd 100644
--- a/source/blender/editors/interface/interface_widgets.c
+++ b/source/blender/editors/interface/interface_widgets.c
@@ -218,13 +218,16 @@ void ui_draw_anti_tria(float x1, float y1, float x2, float y2, float x3, float y
glDisable(GL_BLEND);
}
-void ui_draw_anti_roundbox(int mode, float minx, float miny, float maxx, float maxy, float rad)
+void ui_draw_anti_roundbox(int mode, float minx, float miny, float maxx, float maxy, float rad, bool use_alpha)
{
float color[4];
int j;
glEnable(GL_BLEND);
glGetFloatv(GL_CURRENT_COLOR, color);
+ if (use_alpha) {
+ color[3] = 0.5f;
+ }
color[3] *= 0.125f;
glColor4fv(color);
@@ -1289,7 +1292,9 @@ static void widget_draw_text_icon(uiFontStyle *fstyle, uiWidgetColors *wcol, uiB
else if ((but->block->flag & UI_BLOCK_LOOP) && (but->type == BUT)) {
ui_text_clip_left(fstyle, but, rect);
}
- else but->ofs = 0;
+ else {
+ but->ofs = 0;
+ }
/* check for button text label */
if (but->type == ICONTEXTROW) {
diff --git a/source/blender/editors/interface/resources.c b/source/blender/editors/interface/resources.c
index acea6e133f4..09122737373 100644
--- a/source/blender/editors/interface/resources.c
+++ b/source/blender/editors/interface/resources.c
@@ -279,6 +279,8 @@ const unsigned char *UI_ThemeGetColorPtr(bTheme *btheme, int spacetype, int colo
cp = ts->vertex; break;
case TH_VERTEX_SELECT:
cp = ts->vertex_select; break;
+ case TH_VERTEX_UNREFERENCED:
+ cp = ts->vertex_unreferenced; break;
case TH_VERTEX_SIZE:
cp = &ts->vertex_size; break;
case TH_OUTLINE_WIDTH:
@@ -445,7 +447,6 @@ const unsigned char *UI_ThemeGetColorPtr(bTheme *btheme, int spacetype, int colo
case TH_HANDLE_VERTEX_SIZE:
cp = &ts->handle_vertex_size;
break;
-
case TH_DOPESHEET_CHANNELOB:
cp = ts->ds_channel;
break;
@@ -718,6 +719,8 @@ void ui_theme_init_default(void)
/* space view3d */
btheme->tv3d.panelcolors.show_back = FALSE;
btheme->tv3d.panelcolors.show_header = FALSE;
+ rgba_char_args_set_fl(btheme->tv3d.panelcolors.back, 0.45, 0.45, 0.45, 0.5);
+ rgba_char_args_set_fl(btheme->tv3d.panelcolors.header, 0, 0, 0, 0.01);
rgba_char_args_set_fl(btheme->tv3d.back, 0.225, 0.225, 0.225, 1.0);
rgba_char_args_set(btheme->tv3d.text, 0, 0, 0, 255);
rgba_char_args_set(btheme->tv3d.text_hi, 255, 255, 255, 255);
@@ -742,6 +745,7 @@ void ui_theme_init_default(void)
rgba_char_args_set(btheme->tv3d.transform, 0xff, 0xff, 0xff, 255);
rgba_char_args_set(btheme->tv3d.vertex, 0, 0, 0, 255);
rgba_char_args_set(btheme->tv3d.vertex_select, 255, 133, 0, 255);
+ rgba_char_args_set(btheme->tv3d.vertex_unreferenced, 0, 0, 0, 255);
btheme->tv3d.vertex_size = 3;
btheme->tv3d.outline_width = 1;
rgba_char_args_set(btheme->tv3d.edge, 0x0, 0x0, 0x0, 255);
@@ -1376,7 +1380,7 @@ void init_userdef_do_versions(void)
/* signal for derivedmesh to use colorband */
/* run in case this was on and is now off in the user prefs [#28096] */
- vDM_ColorBand_store((U.flag & USER_CUSTOM_RANGE) ? (&U.coba_weight) : NULL);
+ vDM_ColorBand_store((U.flag & USER_CUSTOM_RANGE) ? (&U.coba_weight) : NULL, UI_GetTheme()->tv3d.vertex_unreferenced);
if (bmain->versionfile <= 191) {
strcpy(U.sounddir, "/");
diff --git a/source/blender/editors/interface/view2d.c b/source/blender/editors/interface/view2d.c
index ad6428c7e80..8a6de9a549b 100644
--- a/source/blender/editors/interface/view2d.c
+++ b/source/blender/editors/interface/view2d.c
@@ -457,8 +457,12 @@ static void ui_view2d_curRect_validate_resize(View2D *v2d, int resize, int mask_
if (ABS(winx - v2d->oldwinx) > ABS(winy - v2d->oldwiny)) do_y = FALSE;
else do_x = FALSE;
}
- else if (winRatio > 1.0f) do_x = FALSE;
- else do_x = TRUE;
+ else if (winRatio > 1.0f) {
+ do_x = FALSE;
+ }
+ else {
+ do_x = TRUE;
+ }
}
do_cur = do_x;
/* do_win = do_y; */ /* UNUSED */
diff --git a/source/blender/editors/interface/view2d_ops.c b/source/blender/editors/interface/view2d_ops.c
index daa78957231..e283bd1351a 100644
--- a/source/blender/editors/interface/view2d_ops.c
+++ b/source/blender/editors/interface/view2d_ops.c
@@ -187,7 +187,7 @@ static int view_pan_exec(bContext *C, wmOperator *op)
}
/* set up modal operator and relevant settings */
-static int view_pan_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int view_pan_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
wmWindow *window = CTX_wm_window(C);
v2dViewPanData *vpd;
@@ -231,7 +231,7 @@ static int view_pan_invoke(bContext *C, wmOperator *op, wmEvent *event)
}
/* handle user input - calculations of mouse-movement need to be done here, not in the apply callback! */
-static int view_pan_modal(bContext *C, wmOperator *op, wmEvent *event)
+static int view_pan_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
v2dViewPanData *vpd = op->customdata;
@@ -700,7 +700,7 @@ static int view_zoomin_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int view_zoomin_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int view_zoomin_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
v2dViewZoomData *vzd;
@@ -769,7 +769,7 @@ static int view_zoomout_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int view_zoomout_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int view_zoomout_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
v2dViewZoomData *vzd;
@@ -924,7 +924,7 @@ static int view_zoomdrag_exec(bContext *C, wmOperator *op)
}
/* set up modal operator and relevant settings */
-static int view_zoomdrag_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int view_zoomdrag_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
wmWindow *window = CTX_wm_window(C);
v2dViewZoomData *vzd;
@@ -1005,7 +1005,7 @@ static int view_zoomdrag_invoke(bContext *C, wmOperator *op, wmEvent *event)
}
/* handle user input - calculations of mouse-movement need to be done here, not in the apply callback! */
-static int view_zoomdrag_modal(bContext *C, wmOperator *op, wmEvent *event)
+static int view_zoomdrag_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
v2dViewZoomData *vzd = op->customdata;
View2D *v2d = vzd->v2d;
@@ -1328,7 +1328,7 @@ void UI_view2d_smooth_view(bContext *C, ARegion *ar,
}
/* only meant for timer usage */
-static int view2d_smoothview_invoke(bContext *C, wmOperator *UNUSED(op), wmEvent *event)
+static int view2d_smoothview_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *event)
{
ARegion *ar = CTX_wm_region(C);
View2D *v2d = &ar->v2d;
@@ -1488,7 +1488,7 @@ static short mouse_in_scroller_handle(int mouse, int sc_min, int sc_max, int sh_
}
/* initialize customdata for scroller manipulation operator */
-static void scroller_activate_init(bContext *C, wmOperator *op, wmEvent *event, short in_scroller)
+static void scroller_activate_init(bContext *C, wmOperator *op, const wmEvent *event, short in_scroller)
{
v2dScrollerMove *vsm;
View2DScrollers *scrollers;
@@ -1637,7 +1637,7 @@ static void scroller_activate_apply(bContext *C, wmOperator *op)
}
/* handle user input for scrollers - calculations of mouse-movement need to be done here, not in the apply callback! */
-static int scroller_activate_modal(bContext *C, wmOperator *op, wmEvent *event)
+static int scroller_activate_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
v2dScrollerMove *vsm = op->customdata;
@@ -1707,7 +1707,7 @@ static int scroller_activate_modal(bContext *C, wmOperator *op, wmEvent *event)
/* a click (or click drag in progress) should have occurred, so check if it happened in scrollbar */
-static int scroller_activate_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int scroller_activate_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
ARegion *ar = CTX_wm_region(C);
View2D *v2d = &ar->v2d;
diff --git a/source/blender/editors/io/io_collada.c b/source/blender/editors/io/io_collada.c
index 4908c101a7c..c673e0fb2b0 100644
--- a/source/blender/editors/io/io_collada.c
+++ b/source/blender/editors/io/io_collada.c
@@ -56,7 +56,7 @@
#include "io_collada.h"
-static int wm_collada_export_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int wm_collada_export_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
if (!RNA_struct_property_is_set(op->ptr, "filepath")) {
char filepath[FILE_MAX];
@@ -95,6 +95,7 @@ static int wm_collada_export_exec(bContext *C, wmOperator *op)
int triangulate;
int use_object_instantiation;
int sort_by_name;
+ int export_transformation_type;
int second_life;
if (!RNA_struct_property_is_set(op->ptr, "filepath")) {
@@ -115,14 +116,15 @@ static int wm_collada_export_exec(bContext *C, wmOperator *op)
deform_bones_only = RNA_boolean_get(op->ptr, "deform_bones_only");
include_uv_textures = RNA_boolean_get(op->ptr, "include_uv_textures");
- include_material_textures= RNA_boolean_get(op->ptr, "include_material_textures");
+ include_material_textures = RNA_boolean_get(op->ptr, "include_material_textures");
use_texture_copies = RNA_boolean_get(op->ptr, "use_texture_copies");
active_uv_only = RNA_boolean_get(op->ptr, "active_uv_only");
- triangulate = RNA_boolean_get(op->ptr, "triangulate");
- use_object_instantiation = RNA_boolean_get(op->ptr, "use_object_instantiation");
- sort_by_name = RNA_boolean_get(op->ptr, "sort_by_name");
- second_life = RNA_boolean_get(op->ptr, "second_life");
+ triangulate = RNA_boolean_get(op->ptr, "triangulate");
+ use_object_instantiation = RNA_boolean_get(op->ptr, "use_object_instantiation");
+ sort_by_name = RNA_boolean_get(op->ptr, "sort_by_name");
+ export_transformation_type = RNA_enum_get(op->ptr, "export_transformation_type_selection");
+ second_life = RNA_boolean_get(op->ptr, "second_life");
/* get editmode results */
ED_object_exit_editmode(C, 0); /* 0 = does not exit editmode */
@@ -145,6 +147,7 @@ static int wm_collada_export_exec(bContext *C, wmOperator *op)
triangulate,
use_object_instantiation,
sort_by_name,
+ export_transformation_type,
second_life))
{
return OPERATOR_FINISHED;
@@ -224,6 +227,12 @@ static void uiCollada_exportSettings(uiLayout *layout, PointerRNA *imfptr)
uiItemR(row, imfptr, "triangulate", 0, NULL, ICON_NONE);
row = uiLayoutRow(box, FALSE);
uiItemR(row, imfptr, "use_object_instantiation", 0, NULL, ICON_NONE);
+
+ row = uiLayoutRow(box, FALSE);
+ split = uiLayoutSplit(row, 0.6f, UI_LAYOUT_ALIGN_RIGHT);
+ uiItemL(split, IFACE_("Transformation Type"), ICON_NONE);
+ uiItemR(split, imfptr, "export_transformation_type_selection", 0, "", ICON_NONE);
+
row = uiLayoutRow(box, FALSE);
uiItemR(row, imfptr, "sort_by_name", 0, NULL, ICON_NONE);
@@ -245,6 +254,13 @@ void WM_OT_collada_export(wmOperatorType *ot)
{0, NULL, 0, NULL, NULL}
};
+ static EnumPropertyItem prop_bc_export_transformation_type[] = {
+ {BC_TRANSFORMATION_TYPE_MATRIX, "matrix", 0, "Matrix", "Use <matrix> to specify transformations"},
+ {BC_TRANSFORMATION_TYPE_TRANSROTLOC, "transrotloc", 0, "TransRotLoc", "Use <translate>, <rotate>, <scale> to specify transformations"},
+ {BC_TRANSFORMATION_TYPE_BOTH, "both", 0, "Both", "Use <matrix> AND <translate>, <rotate>, <scale> to specify transformations"},
+ {0, NULL, 0, NULL, NULL}
+ };
+
ot->name = "Export COLLADA";
ot->description = "Save a Collada file";
ot->idname = "WM_OT_collada_export";
@@ -308,6 +324,12 @@ void WM_OT_collada_export(wmOperatorType *ot)
RNA_def_boolean(ot->srna, "sort_by_name", 0, "Sort by Object name",
"Sort exported data by Object name");
+ RNA_def_int(ot->srna, "export_transformation_type", 0, INT_MIN, INT_MAX,
+ "Transform", "Transformation type for translation, scale and rotation", INT_MIN, INT_MAX);
+
+ RNA_def_enum(ot->srna, "export_transformation_type_selection", prop_bc_export_transformation_type, 0,
+ "Transform", "Transformation type for translation, scale and rotation");
+
RNA_def_boolean(ot->srna, "second_life", 0, "Export for Second Life",
"Compatibility mode for Second Life");
}
diff --git a/source/blender/editors/mask/mask_add.c b/source/blender/editors/mask/mask_add.c
index 77abe43bba7..33a6aa2d43d 100644
--- a/source/blender/editors/mask/mask_add.c
+++ b/source/blender/editors/mask/mask_add.c
@@ -629,7 +629,7 @@ static int add_vertex_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int add_vertex_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int add_vertex_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
ScrArea *sa = CTX_wm_area(C);
ARegion *ar = CTX_wm_region(C);
@@ -703,7 +703,7 @@ static int add_feather_vertex_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
-static int add_feather_vertex_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int add_feather_vertex_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
ScrArea *sa = CTX_wm_area(C);
ARegion *ar = CTX_wm_region(C);
diff --git a/source/blender/editors/mask/mask_ops.c b/source/blender/editors/mask/mask_ops.c
index 0a996c11f14..ff8e27ac264 100644
--- a/source/blender/editors/mask/mask_ops.c
+++ b/source/blender/editors/mask/mask_ops.c
@@ -438,7 +438,7 @@ static int slide_point_check_initial_feather(MaskSpline *spline)
return TRUE;
}
-static void *slide_point_customdata(bContext *C, wmOperator *op, wmEvent *event)
+static void *slide_point_customdata(bContext *C, wmOperator *op, const wmEvent *event)
{
ScrArea *sa = CTX_wm_area(C);
ARegion *ar = CTX_wm_region(C);
@@ -525,7 +525,7 @@ static void *slide_point_customdata(bContext *C, wmOperator *op, wmEvent *event)
return customdata;
}
-static int slide_point_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int slide_point_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
SlidePointData *slidedata = slide_point_customdata(C, op, event);
@@ -634,7 +634,7 @@ static void free_slide_point_data(SlidePointData *data)
MEM_freeN(data);
}
-static int slide_point_modal(bContext *C, wmOperator *op, wmEvent *event)
+static int slide_point_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
SlidePointData *data = (SlidePointData *)op->customdata;
BezTriple *bezt = &data->point->bezt;
diff --git a/source/blender/editors/mask/mask_select.c b/source/blender/editors/mask/mask_select.c
index cd1a47754f8..ccc2fad5f52 100644
--- a/source/blender/editors/mask/mask_select.c
+++ b/source/blender/editors/mask/mask_select.c
@@ -361,7 +361,7 @@ static int select_exec(bContext *C, wmOperator *op)
return OPERATOR_PASS_THROUGH;
}
-static int select_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int select_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
ScrArea *sa = CTX_wm_area(C);
ARegion *ar = CTX_wm_region(C);
@@ -689,7 +689,7 @@ void MASK_OT_select_circle(wmOperatorType *ot)
RNA_def_int(ot->srna, "gesture_mode", 0, INT_MIN, INT_MAX, "Gesture Mode", "", INT_MIN, INT_MAX);
}
-static int mask_select_linked_pick_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int mask_select_linked_pick_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
ScrArea *sa = CTX_wm_area(C);
ARegion *ar = CTX_wm_region(C);
diff --git a/source/blender/editors/mesh/CMakeLists.txt b/source/blender/editors/mesh/CMakeLists.txt
index b51d55aaf0e..a76872d6e30 100644
--- a/source/blender/editors/mesh/CMakeLists.txt
+++ b/source/blender/editors/mesh/CMakeLists.txt
@@ -26,6 +26,7 @@ set(INC
../../blenlib
../../blenloader
../../bmesh
+ ../../gpu
../../imbuf
../../makesdna
../../makesrna
@@ -43,6 +44,7 @@ set(SRC
editmesh_add.c
editmesh_bvh.c
editmesh_knife.c
+ editmesh_knife_project.c
editmesh_loopcut.c
editmesh_rip.c
editmesh_select.c
diff --git a/source/blender/editors/mesh/editface.c b/source/blender/editors/mesh/editface.c
index 7ddf2b54a88..260d01d726a 100644
--- a/source/blender/editors/mesh/editface.c
+++ b/source/blender/editors/mesh/editface.c
@@ -294,7 +294,7 @@ static void select_linked_tfaces_with_seams(int mode, Mesh *me, unsigned int ind
MEM_freeN(linkflag);
}
-void paintface_select_linked(bContext *UNUSED(C), Object *ob, int UNUSED(mval[2]), int mode)
+void paintface_select_linked(bContext *UNUSED(C), Object *ob, const int UNUSED(mval[2]), int mode)
{
Mesh *me;
unsigned int index = 0;
@@ -525,7 +525,9 @@ int paintface_mouse_select(struct bContext *C, Object *ob, const int mval[2], in
else
mpoly_sel->flag |= ME_FACE_SEL;
}
- else mpoly_sel->flag |= ME_FACE_SEL;
+ else {
+ mpoly_sel->flag |= ME_FACE_SEL;
+ }
/* image window redraw */
@@ -568,7 +570,7 @@ int do_paintface_box_select(ViewContext *vc, rcti *rect, int select, int extend)
ibuf = IMB_allocImBuf(sx, sy, 32, IB_rect);
rt = ibuf->rect;
- glReadPixels(rect->xmin + vc->ar->winrct.xmin, rect->ymin + vc->ar->winrct.ymin, sx, sy, GL_RGBA, GL_UNSIGNED_BYTE, ibuf->rect);
+ view3d_opengl_read_pixels(vc->ar, rect->xmin, rect->ymin, sx, sy, GL_RGBA, GL_UNSIGNED_BYTE, ibuf->rect);
if (ENDIAN_ORDER == B_ENDIAN) IMB_convert_rgba_to_abgr(ibuf);
a = sx * sy;
@@ -710,6 +712,37 @@ void paintvert_deselect_all_visible(Object *ob, int action, short flush_flags)
}
}
+void paintvert_select_ungrouped(Object *ob, short extend, short flush_flags)
+{
+ Mesh *me = BKE_mesh_from_object(ob);
+ MVert *mv;
+ MDeformVert *dv;
+ int a, tot;
+
+ if (me == NULL || me->dvert == NULL) {
+ return;
+ }
+
+ if (!extend) {
+ paintvert_deselect_all_visible(ob, SEL_DESELECT, FALSE);
+ }
+
+ dv = me->dvert;
+ tot = me->totvert;
+
+ for (a = 0, mv = me->mvert; a < tot; a++, mv++, dv++) {
+ if ((mv->flag & ME_HIDE) == 0) {
+ if (dv->dw == NULL) {
+ /* if null weight then not grouped */
+ mv->flag |= SELECT;
+ }
+ }
+ }
+
+ if (flush_flags) {
+ paintvert_flush_flags(ob);
+ }
+}
/* ********************* MESH VERTEX MIRR TOPO LOOKUP *************** */
/* note, this is not the best place for the function to be but moved
diff --git a/source/blender/editors/mesh/editmesh_add.c b/source/blender/editors/mesh/editmesh_add.c
index a356f9fca7f..174715495f6 100644
--- a/source/blender/editors/mesh/editmesh_add.c
+++ b/source/blender/editors/mesh/editmesh_add.c
@@ -32,15 +32,14 @@
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
-#include "RNA_define.h"
-#include "RNA_access.h"
-
#include "BLI_math.h"
#include "BKE_context.h"
#include "BKE_library.h"
#include "BKE_tessmesh.h"
+#include "RNA_define.h"
+#include "RNA_access.h"
#include "WM_api.h"
#include "WM_types.h"
diff --git a/source/blender/editors/mesh/editmesh_knife.c b/source/blender/editors/mesh/editmesh_knife.c
index d7dbe3506b1..b5b6a92cbf5 100644
--- a/source/blender/editors/mesh/editmesh_knife.c
+++ b/source/blender/editors/mesh/editmesh_knife.c
@@ -37,6 +37,7 @@
#include "BLI_blenlib.h"
#include "BLI_array.h"
+#include "BLI_linklist.h"
#include "BLI_math.h"
#include "BLI_smallhash.h"
#include "BLI_memarena.h"
@@ -90,7 +91,8 @@ typedef struct KnifeVert {
ListBase faces;
float co[3], cageco[3], sco[3]; /* sco is screen coordinates for cageco */
- short flag, draw, isface, inspace;
+ bool is_face, in_space;
+ bool draw;
} KnifeVert;
typedef struct Ref {
@@ -102,9 +104,9 @@ typedef struct KnifeEdge {
KnifeVert *v1, *v2;
BMFace *basef; /* face to restrict face fill to */
ListBase faces;
- int draw;
- BMEdge *e, *oe; /* non-NULL if this is an original edge */
+ BMEdge *e /* , *e_old */; /* non-NULL if this is an original edge */
+ bool draw;
} KnifeEdge;
typedef struct BMEdgeHit {
@@ -128,7 +130,7 @@ typedef struct KnifePosData {
KnifeVert *vert;
KnifeEdge *edge;
BMFace *bmface;
- int is_space;
+ bool is_space;
float mval[2]; /* mouse screen position (may be non-integral if snapped to something) */
} KnifePosData;
@@ -137,7 +139,8 @@ typedef struct KnifePosData {
typedef struct KnifeTool_OpData {
ARegion *ar; /* region that knifetool was activated in */
void *draw_handle; /* for drawing preview loop */
- ViewContext vc;
+ ViewContext vc; /* note: _don't_ use 'mval', instead use the one we define below */
+ float mval[2]; /* mouse value with snapping applied */
//bContext *C;
Object *ob;
@@ -173,12 +176,15 @@ typedef struct KnifeTool_OpData {
KnifeColors colors;
+ /* run by the UI or not */
+ bool is_interactive;
+
/* operatpr options */
- char cut_through; /* preference, can be modified at runtime (that feature may go) */
- char only_select; /* set on initialization */
- char select_result; /* set on initialization */
+ bool cut_through; /* preference, can be modified at runtime (that feature may go) */
+ bool only_select; /* set on initialization */
+ bool select_result; /* set on initialization */
- short is_ortho;
+ bool is_ortho;
float ortho_extent;
float clipsta, clipend;
@@ -189,8 +195,10 @@ typedef struct KnifeTool_OpData {
MODE_PANNING
} mode;
- int snap_midpoints, prevmode, extend;
- int ignore_edge_snapping, ignore_vert_snapping;
+ int prevmode;
+ bool snap_midpoints, extend;
+ bool ignore_edge_snapping;
+ bool ignore_vert_snapping;
enum {
ANGLE_FREE,
@@ -228,14 +236,16 @@ static void knife_update_header(bContext *C, KnifeTool_OpData *kcd)
ED_area_headerprint(CTX_wm_area(C), header);
}
+#if 0
BLI_INLINE int round_ftoi(float x)
{
return x > 0.0f ? (int)(x + 0.5f) : (int)(x - 0.5f);
}
+#endif
-static void knife_project_v3(KnifeTool_OpData *kcd, const float co[3], float sco[3])
+static void knife_project_v3(const KnifeTool_OpData *kcd, const float co[3], float sco[3])
{
- ED_view3d_project_float_v3_m4(kcd->ar, co, sco, kcd->projmat);
+ ED_view3d_project_float_v3_m4(kcd->ar, co, sco, (float (*)[4])kcd->projmat);
}
static void knife_pos_data_clear(KnifePosData *kpd)
@@ -245,8 +255,7 @@ static void knife_pos_data_clear(KnifePosData *kpd)
kpd->vert = NULL;
kpd->edge = NULL;
kpd->bmface = NULL;
- kpd->mval[0] = 0.0f;
- kpd->mval[1] = 0.0f;
+ zero_v2(kpd->mval);
}
static ListBase *knife_empty_list(KnifeTool_OpData *kcd)
@@ -494,7 +503,7 @@ static void knife_add_single_cut(KnifeTool_OpData *kcd)
if (kcd->prev.edge && kcd->prev.edge == kcd->curr.edge)
return;
- kfe->draw = 1;
+ kfe->draw = true;
if (kcd->prev.vert) {
kfe->v1 = kcd->prev.vert;
@@ -505,9 +514,9 @@ static void knife_add_single_cut(KnifeTool_OpData *kcd)
else {
kfe->v1 = new_knife_vert(kcd, kcd->prev.co, kcd->prev.co);
kfe->v1->draw = kfe->draw = !kcd->prev.is_space;
- kfe->v1->inspace = kcd->prev.is_space;
+ kfe->v1->in_space = kcd->prev.is_space;
kfe->draw = !kcd->prev.is_space;
- kfe->v1->isface = 1;
+ kfe->v1->is_face = true;
if (kfe->v1->draw && kcd->prev.bmface)
knife_append_list(kcd, &kfe->v1->faces, kcd->prev.bmface);
}
@@ -522,13 +531,13 @@ static void knife_add_single_cut(KnifeTool_OpData *kcd)
else {
kfe->v2 = new_knife_vert(kcd, kcd->curr.co, kcd->curr.co);
kfe->v2->draw = !kcd->curr.is_space;
- kfe->v2->isface = 1;
- kfe->v2->inspace = kcd->curr.is_space;
+ kfe->v2->is_face = true;
+ kfe->v2->in_space = kcd->curr.is_space;
if (kfe->v2->draw && kcd->curr.bmface)
knife_append_list(kcd, &kfe->v2->faces, kcd->curr.bmface);
if (kcd->curr.is_space)
- kfe->draw = 0;
+ kfe->draw = false;
kcd->curr.vert = kfe->v2;
}
@@ -632,11 +641,10 @@ static void knife_add_single_cut_through(KnifeTool_OpData *kcd, KnifeVert *v1, K
KnifeEdge *kfenew;
kfenew = new_knife_edge(kcd);
- kfenew->draw = 1;
kfenew->basef = f;
kfenew->v1 = v1;
kfenew->v2 = v2;
- kfenew->draw = 1;
+ kfenew->draw = true;
knife_add_to_vert_edges(kcd, kfenew);
@@ -650,7 +658,7 @@ static void knife_get_vert_faces(KnifeTool_OpData *kcd, KnifeVert *kfv, BMFace *
BMFace *f;
Ref *r;
- if (kfv->isface && facef) {
+ if (kfv->is_face && facef) {
knife_append_list(kcd, lst, facef);
}
else if (kfv->v) {
@@ -689,7 +697,7 @@ static void knife_cut_through(KnifeTool_OpData *kcd)
ListBase firstfaces = {NULL, NULL}, lastfaces = {NULL, NULL};
Ref *r, *r2;
KnifeEdge **splitkfe;
- int i, j, found;
+ int i, j;
if (!kcd->totlinehit) {
/* if no linehits then no interesting back face stuff to do */
@@ -727,15 +735,15 @@ static void knife_cut_through(KnifeTool_OpData *kcd)
/* For each face incident to firstv,
* find the first following linehit (if any) sharing that face and connect */
for (r = firstfaces.first; r; r = r->next) {
+ bool found = false;
f = r->ref;
- found = 0;
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) {
v2 = splitkfe[j] ? kfe2->v1 : knife_split_edge(kcd, kfe2, lh2->hit, &splitkfe[j]);
knife_add_single_cut_through(kcd, firstv, v2, f);
- found = 1;
+ found = true;
break;
}
}
@@ -757,8 +765,8 @@ static void knife_cut_through(KnifeTool_OpData *kcd)
/* For each face attached to edge for this linehit,
* find the first following linehit (if any) sharing that face and connect */
for (r = kfe->faces.first; r; r = r->next) {
+ bool found = false;
f = r->ref;
- found = 0;
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) {
@@ -766,7 +774,7 @@ static void knife_cut_through(KnifeTool_OpData *kcd)
v1 = splitkfe[i] ? kfe->v1 : knife_split_edge(kcd, kfe, lh->hit, &splitkfe[i]);
v2 = splitkfe[j] ? kfe2->v1 : knife_split_edge(kcd, kfe2, lh2->hit, &splitkfe[j]);
knife_add_single_cut_through(kcd, v1, v2, f);
- found = 1;
+ found = true;
break;
}
}
@@ -890,7 +898,7 @@ static void knife_finish_cut(KnifeTool_OpData *UNUSED(kcd))
}
-static void knifetool_draw_angle_snapping(KnifeTool_OpData *kcd)
+static void knifetool_draw_angle_snapping(const KnifeTool_OpData *kcd)
{
bglMats mats;
double u[3], u1[2], u2[2], v1[3], v2[3], dx, dy;
@@ -1006,7 +1014,7 @@ static void knife_init_colors(KnifeColors *colors)
static void knifetool_draw(const bContext *C, ARegion *UNUSED(ar), void *arg)
{
View3D *v3d = CTX_wm_view3d(C);
- KnifeTool_OpData *kcd = arg;
+ const KnifeTool_OpData *kcd = arg;
if (v3d->zbuf) glDisable(GL_DEPTH_TEST);
@@ -1062,7 +1070,7 @@ static void knifetool_draw(const bContext *C, ARegion *UNUSED(ar), void *arg)
if (kcd->totlinehit > 0) {
const float vthresh4 = kcd->vthresh / 4.0f;
- const float vthresh4_squared = vthresh4 * vthresh4;
+ const float vthresh4_sq = vthresh4 * vthresh4;
BMEdgeHit *lh;
int i;
@@ -1082,12 +1090,12 @@ static void knifetool_draw(const bContext *C, ARegion *UNUSED(ar), void *arg)
knife_project_v3(kcd, lh->kfe->v2->cageco, sv2);
knife_project_v3(kcd, lh->cagehit, lh->schit);
- if (len_squared_v2v2(lh->schit, sv1) < vthresh4_squared) {
+ if (len_squared_v2v2(lh->schit, sv1) < vthresh4_sq) {
copy_v3_v3(lh->cagehit, lh->kfe->v1->cageco);
glVertex3fv(lh->cagehit);
lh->v = lh->kfe->v1;
}
- else if (len_squared_v2v2(lh->schit, sv2) < vthresh4_squared) {
+ else if (len_squared_v2v2(lh->schit, sv2) < vthresh4_sq) {
copy_v3_v3(lh->cagehit, lh->kfe->v2->cageco);
glVertex3fv(lh->cagehit);
lh->v = lh->kfe->v2;
@@ -1179,7 +1187,7 @@ static BMEdgeHit *knife_edge_tri_isect(KnifeTool_OpData *kcd, BMBVHTree *bmtree,
/* for comparing distances, error of intersection depends on triangle scale.
* need to scale down before squaring for accurate comparison */
const float depsilon = (FLT_EPSILON / 2.0f) * len_v3_tri_side_max(v1, v2, v3);
- const float depsilon_squared = depsilon * depsilon;
+ const float depsilon_sq = depsilon * depsilon;
copy_v3_v3(cos + 0, v1);
copy_v3_v3(cos + 3, v2);
@@ -1213,14 +1221,14 @@ static BMEdgeHit *knife_edge_tri_isect(KnifeTool_OpData *kcd, BMBVHTree *bmtree,
interp_v3_v3v3(p, kfe->v1->cageco, kfe->v2->cageco, lambda);
- if (kcd->curr.vert && len_squared_v3v3(kcd->curr.vert->cageco, p) < depsilon_squared) {
+ if (kcd->curr.vert && len_squared_v3v3(kcd->curr.vert->cageco, p) < depsilon_sq) {
continue;
}
- if (kcd->prev.vert && len_squared_v3v3(kcd->prev.vert->cageco, p) < depsilon_squared) {
+ if (kcd->prev.vert && len_squared_v3v3(kcd->prev.vert->cageco, p) < depsilon_sq) {
continue;
}
- if (len_squared_v3v3(kcd->prev.cage, p) < depsilon_squared ||
- len_squared_v3v3(kcd->curr.cage, p) < depsilon_squared)
+ if (len_squared_v3v3(kcd->prev.cage, p) < depsilon_sq ||
+ len_squared_v3v3(kcd->curr.cage, p) < depsilon_sq)
{
continue;
}
@@ -1266,8 +1274,8 @@ static BMEdgeHit *knife_edge_tri_isect(KnifeTool_OpData *kcd, BMBVHTree *bmtree,
if (!hitf && !BLI_smallhash_haskey(ehash, (intptr_t)kfe)) {
BMEdgeHit hit;
- if (len_squared_v3v3(p, kcd->curr.co) < depsilon_squared ||
- len_squared_v3v3(p, kcd->prev.co) < depsilon_squared)
+ if (len_squared_v3v3(p, kcd->curr.co) < depsilon_sq ||
+ len_squared_v3v3(p, kcd->prev.co) < depsilon_sq)
{
continue;
}
@@ -1381,7 +1389,7 @@ static void knife_find_line_hits(KnifeTool_OpData *kcd)
knife_project_v3(kcd, v1, s1);
knife_project_v3(kcd, v2, s2);
- if (len_v2v2(s1, s2) < 1)
+ if (len_squared_v2v2(s1, s2) < 1)
return;
/* unproject screen line */
@@ -1481,7 +1489,7 @@ static void knife_input_ray_segment(KnifeTool_OpData *kcd, const float mval[2],
mul_m4_v3(kcd->ob->imat, r_origin_ofs);
}
-static BMFace *knife_find_closest_face(KnifeTool_OpData *kcd, float co[3], float cageco[3], int *is_space)
+static BMFace *knife_find_closest_face(KnifeTool_OpData *kcd, float co[3], float cageco[3], bool *is_space)
{
BMFace *f;
float dist = KMAXDIST;
@@ -1499,13 +1507,15 @@ static BMFace *knife_find_closest_face(KnifeTool_OpData *kcd, float co[3], float
*is_space = !f;
if (!f) {
- /* try to use backbuffer selection method if ray casting failed */
- f = EDBM_face_find_nearest(&kcd->vc, &dist);
+ if (kcd->is_interactive) {
+ /* try to use backbuffer selection method if ray casting failed */
+ f = EDBM_face_find_nearest(&kcd->vc, &dist);
- /* cheat for now; just put in the origin instead
- * of a true coordinate on the face.
- * This just puts a point 1.0f infront of the view. */
- add_v3_v3v3(co, origin, ray);
+ /* cheat for now; just put in the origin instead
+ * of a true coordinate on the face.
+ * This just puts a point 1.0f infront of the view. */
+ add_v3_v3v3(co, origin, ray);
+ }
}
return f;
@@ -1513,18 +1523,21 @@ static BMFace *knife_find_closest_face(KnifeTool_OpData *kcd, float co[3], float
/* find the 2d screen space density of vertices within a radius. used to scale snapping
* distance for picking edges/verts.*/
-static int knife_sample_screen_density(KnifeTool_OpData *kcd, float radius)
+static int knife_sample_screen_density(KnifeTool_OpData *kcd, const float radius)
{
BMFace *f;
- int is_space;
+ bool is_space;
float co[3], cageco[3], sco[3];
+ BLI_assert(kcd->is_interactive == true);
+
f = knife_find_closest_face(kcd, co, cageco, &is_space);
if (f && !is_space) {
+ const float radius_sq = radius * radius;
ListBase *lst;
Ref *ref;
- float dis;
+ float dis_sq;
int c = 0;
knife_project_v3(kcd, cageco, sco);
@@ -1539,8 +1552,8 @@ static int knife_sample_screen_density(KnifeTool_OpData *kcd, float radius)
knife_project_v3(kcd, kfv->cageco, kfv->sco);
- dis = len_v2v2(kfv->sco, sco);
- if (dis < radius) {
+ dis_sq = len_squared_v2v2(kfv->sco, sco);
+ if (dis_sq < radius_sq) {
if (kcd->vc.rv3d->rflag & RV3D_CLIPPING) {
if (ED_view3d_clipping_test(kcd->vc.rv3d, kfv->cageco, TRUE) == 0) {
c++;
@@ -1563,7 +1576,14 @@ static int knife_sample_screen_density(KnifeTool_OpData *kcd, float radius)
* surrounding mesh (in screen space)*/
static float knife_snap_size(KnifeTool_OpData *kcd, float maxsize)
{
- float density = (float)knife_sample_screen_density(kcd, maxsize * 2.0f);
+ float density;
+
+ if (kcd->is_interactive) {
+ density = (float)knife_sample_screen_density(kcd, maxsize * 2.0f);
+ }
+ else {
+ density = 1.0f;
+ }
if (density < 1.0f)
density = 1.0f;
@@ -1572,7 +1592,7 @@ static float knife_snap_size(KnifeTool_OpData *kcd, float maxsize)
}
/* p is closest point on edge to the mouse cursor */
-static KnifeEdge *knife_find_closest_edge(KnifeTool_OpData *kcd, float p[3], float cagep[3], BMFace **fptr, int *is_space)
+static KnifeEdge *knife_find_closest_edge(KnifeTool_OpData *kcd, float p[3], float cagep[3], BMFace **fptr, bool *is_space)
{
BMFace *f;
float co[3], cageco[3], sco[3], maxdist = knife_snap_size(kcd, kcd->ethresh);
@@ -1668,7 +1688,7 @@ static KnifeEdge *knife_find_closest_edge(KnifeTool_OpData *kcd, float p[3], flo
/* find a vertex near the mouse cursor, if it exists */
static KnifeVert *knife_find_closest_vert(KnifeTool_OpData *kcd, float p[3], float cagep[3], BMFace **fptr,
- int *is_space)
+ bool *is_space)
{
BMFace *f;
float co[3], cageco[3], sco[3], maxdist = knife_snap_size(kcd, kcd->vthresh);
@@ -1684,10 +1704,11 @@ static KnifeVert *knife_find_closest_vert(KnifeTool_OpData *kcd, float p[3], flo
kcd->curr.bmface = f;
if (f) {
+ const float maxdist_sq = maxdist * maxdist;
ListBase *lst;
Ref *ref;
KnifeVert *curv = NULL;
- float dis, curdis = FLT_MAX;
+ float dis_sq, curdis_sq = FLT_MAX;
knife_project_v3(kcd, cageco, sco);
@@ -1701,17 +1722,17 @@ static KnifeVert *knife_find_closest_vert(KnifeTool_OpData *kcd, float p[3], flo
knife_project_v3(kcd, kfv->cageco, kfv->sco);
- dis = len_v2v2(kfv->sco, sco);
- if (dis < curdis && dis < maxdist) {
+ dis_sq = len_squared_v2v2(kfv->sco, sco);
+ if (dis_sq < curdis_sq && dis_sq < maxdist_sq) {
if (kcd->vc.rv3d->rflag & RV3D_CLIPPING) {
if (ED_view3d_clipping_test(kcd->vc.rv3d, kfv->cageco, TRUE) == 0) {
curv = kfv;
- curdis = dis;
+ curdis_sq = dis_sq;
}
}
else {
curv = kfv;
- curdis = dis;
+ curdis_sq = dis_sq;
}
}
}
@@ -1747,7 +1768,7 @@ static KnifeVert *knife_find_closest_vert(KnifeTool_OpData *kcd, float p[3], flo
return NULL;
}
-/* update both kcd->curr.mval and kcd->vc.mval to snap to required angle */
+/* update both kcd->curr.mval and kcd->mval to snap to required angle */
static void knife_snap_angle(KnifeTool_OpData *kcd)
{
float dx, dy;
@@ -1784,16 +1805,14 @@ static void knife_snap_angle(KnifeTool_OpData *kcd)
kcd->curr.mval[0] = kcd->prev.mval[0];
}
- kcd->vc.mval[0] = round_ftoi(kcd->curr.mval[0]);
- kcd->vc.mval[1] = round_ftoi(kcd->curr.mval[1]);
+ copy_v2_v2(kcd->mval, kcd->curr.mval);
}
/* update active knife edge/vert pointers */
static int knife_update_active(KnifeTool_OpData *kcd)
{
knife_pos_data_clear(&kcd->curr);
- kcd->curr.mval[0] = (float)kcd->vc.mval[0];
- kcd->curr.mval[1] = (float)kcd->vc.mval[1];
+ copy_v2_v2(kcd->curr.mval, kcd->mval);
if (kcd->angle_snapping != ANGLE_FREE && kcd->mode == MODE_DRAGGING)
knife_snap_angle(kcd);
@@ -1994,14 +2013,14 @@ static void knifenet_fill_faces(KnifeTool_OpData *kcd)
i++;
if (kfe->e && kfe->v1->v == kfe->e->v1 && kfe->v2->v == kfe->e->v2) {
- kfe->oe = kfe->e;
+ kfe->e_old = kfe->e;
continue;
}
j++;
if (kfe->e) {
- kfe->oe = kfe->e;
+ kfe->e_old = kfe->e;
BMO_elem_flag_enable(bm, kfe->e, DEL);
BMO_elem_flag_disable(bm, kfe->e, BOUNDARY);
@@ -2027,13 +2046,13 @@ static void knifenet_fill_faces(KnifeTool_OpData *kcd)
if (!kfe->v1 || !kfe->v2 || kfe->v1->inspace || kfe->v2->inspace)
continue;
- if (!(kfe->oe && kfe->v1->v == kfe->oe->v1 && kfe->v2->v == kfe->oe->v2))
+ if (!(kfe->e_old && kfe->v1->v == kfe->e_old->v1 && kfe->v2->v == kfe->e_old->v2))
continue;
k++;
BMO_elem_flag_enable(bm, kfe->e, BOUNDARY);
- kfe->oe = kfe->e;
+ kfe->e_old = kfe->e;
for (ref = kfe->faces.first; ref; ref = ref->next) {
f = ref->ref;
@@ -2096,7 +2115,7 @@ static void knifenet_fill_faces(KnifeTool_OpData *kcd)
if (sf_vert->poly_nr > 1 && sf_vert_last->poly_nr > 1) {
ScanFillEdge *sf_edge;
sf_edge = BLI_scanfill_edge_add(&sf_ctx, sf_vert_last, sf_vert);
- if (entry->kfe->oe)
+ if (entry->kfe->e_old)
sf_edge->f = SF_EDGE_BOUNDARY; /* mark as original boundary edge */
BMO_elem_flag_disable(bm, entry->kfe->e->v1, DEL);
@@ -2239,15 +2258,15 @@ static void sort_by_frac_along(ListBase *lst, BMEdge *e)
/* The chain so far goes from an instantiated vertex to kfv (some may be reversed).
* If possible, complete the chain to another instantiated vertex and return 1, else return 0.
* The visited hash says which KnifeVert's have already been tried, not including kfv. */
-static int find_chain_search(KnifeTool_OpData *kcd, KnifeVert *kfv, ListBase *fedges, SmallHash *visited,
- ListBase *chain)
+static bool find_chain_search(KnifeTool_OpData *kcd, KnifeVert *kfv, ListBase *fedges, SmallHash *visited,
+ ListBase *chain)
{
Ref *r;
KnifeEdge *kfe;
KnifeVert *kfv_other;
if (kfv->v)
- return TRUE;
+ return true;
BLI_smallhash_insert(visited, (uintptr_t)kfv, NULL);
/* Try all possible next edges. Could either go through fedges
@@ -2264,22 +2283,22 @@ static int find_chain_search(KnifeTool_OpData *kcd, KnifeVert *kfv, ListBase *fe
if (kfv_other && !BLI_smallhash_haskey(visited, (uintptr_t)kfv_other)) {
knife_append_list(kcd, chain, kfe);
if (find_chain_search(kcd, kfv_other, fedges, visited, chain))
- return TRUE;
+ return true;
BLI_remlink(chain, chain->last);
}
}
- return FALSE;
+ return false;
}
static ListBase *find_chain_from_vertex(KnifeTool_OpData *kcd, KnifeEdge *kfe, BMVert *v, ListBase *fedges)
{
SmallHash visited_, *visited = &visited_;
ListBase *ans;
- int found;
+ bool found;
ans = knife_empty_list(kcd);
knife_append_list(kcd, ans, kfe);
- found = 0;
+ found = false;
BLI_smallhash_init(visited);
if (kfe->v1->v == v) {
BLI_smallhash_insert(visited, (uintptr_t)(kfe->v1), NULL);
@@ -2340,15 +2359,15 @@ static ListBase *find_chain(KnifeTool_OpData *kcd, ListBase *fedges)
/* The hole so far goes from kfvfirst to kfv (some may be reversed).
* If possible, complete the hole back to kfvfirst and return 1, else return 0.
* The visited hash says which KnifeVert's have already been tried, not including kfv or kfvfirst. */
-static int find_hole_search(KnifeTool_OpData *kcd, KnifeVert *kfvfirst, KnifeVert *kfv, ListBase *fedges,
- SmallHash *visited, ListBase *hole)
+static bool find_hole_search(KnifeTool_OpData *kcd, KnifeVert *kfvfirst, KnifeVert *kfv, ListBase *fedges,
+ SmallHash *visited, ListBase *hole)
{
Ref *r;
KnifeEdge *kfe, *kfelast;
KnifeVert *kfv_other;
if (kfv == kfvfirst)
- return TRUE;
+ return true;
BLI_smallhash_insert(visited, (uintptr_t)kfv, NULL);
kfelast = ((Ref *)hole->last)->ref;
@@ -2366,11 +2385,11 @@ static int find_hole_search(KnifeTool_OpData *kcd, KnifeVert *kfvfirst, KnifeVer
if (kfv_other && !BLI_smallhash_haskey(visited, (uintptr_t)kfv_other)) {
knife_append_list(kcd, hole, kfe);
if (find_hole_search(kcd, kfvfirst, kfv_other, fedges, visited, hole))
- return TRUE;
+ return true;
BLI_remlink(hole, hole->last);
}
}
- return FALSE;
+ return false;
}
/* Find a hole (simple cycle with no instantiated vertices).
@@ -2381,10 +2400,10 @@ static ListBase *find_hole(KnifeTool_OpData *kcd, ListBase *fedges)
Ref *r, *ref;
KnifeEdge *kfe;
SmallHash visited_, *visited = &visited_;
- int found;
+ bool found;
ans = NULL;
- found = FALSE;
+ found = false;
for (r = fedges->first; r && !found; r = r->next) {
kfe = r->ref;
@@ -2853,10 +2872,8 @@ static void knife_make_cuts(KnifeTool_OpData *kcd)
#endif
/* called on tool confirmation */
-static void knifetool_finish(wmOperator *op)
+static void knifetool_finish_ex(KnifeTool_OpData *kcd)
{
- KnifeTool_OpData *kcd = op->customdata;
-
#if SCANFILL_CUTS
knifenet_fill_faces(kcd);
#else
@@ -2866,19 +2883,10 @@ static void knifetool_finish(wmOperator *op)
EDBM_mesh_normals_update(kcd->em);
EDBM_update_generic(kcd->em, TRUE, TRUE);
}
-
-/* copied from paint_image.c */
-static int project_knife_view_clip(View3D *v3d, RegionView3D *rv3d, float *clipsta, float *clipend)
+static void knifetool_finish(wmOperator *op)
{
- int orth = ED_view3d_clip_range_get(v3d, rv3d, clipsta, clipend);
-
- if (orth) { /* only needed for ortho */
- float fac = 2.0f / ((*clipend) - (*clipsta));
- *clipsta *= fac;
- *clipend *= fac;
- }
-
- return orth;
+ KnifeTool_OpData *kcd = op->customdata;
+ knifetool_finish_ex(kcd);
}
static void knife_recalc_projmat(KnifeTool_OpData *kcd)
@@ -2887,22 +2895,22 @@ static void knife_recalc_projmat(KnifeTool_OpData *kcd)
ED_view3d_ob_project_mat_get(kcd->ar->regiondata, kcd->ob, kcd->projmat);
//mult_m4_m4m4(kcd->projmat, kcd->vc.rv3d->winmat, kcd->vc.rv3d->viewmat);
- kcd->is_ortho = project_knife_view_clip(kcd->vc.v3d, kcd->vc.rv3d,
- &kcd->clipsta, &kcd->clipend);
+ kcd->is_ortho = ED_view3d_clip_range_get(kcd->vc.v3d, kcd->vc.rv3d,
+ &kcd->clipsta, &kcd->clipend, true);
}
/* called when modal loop selection is done... */
-static void knifetool_exit(bContext *C, wmOperator *op)
+static void knifetool_exit_ex(bContext *C, KnifeTool_OpData *kcd)
{
- KnifeTool_OpData *kcd = op->customdata;
-
if (!kcd)
return;
- WM_cursor_restore(CTX_wm_window(C));
+ if (kcd->is_interactive) {
+ WM_cursor_restore(CTX_wm_window(C));
- /* deactivate the extra drawing stuff in 3D-View */
- ED_region_draw_cb_exit(kcd->ar->type, kcd->draw_handle);
+ /* deactivate the extra drawing stuff in 3D-View */
+ ED_region_draw_cb_exit(kcd->ar->type, kcd->draw_handle);
+ }
/* free the custom data */
BLI_mempool_destroy(kcd->refs);
@@ -2927,6 +2935,11 @@ static void knifetool_exit(bContext *C, wmOperator *op)
/* destroy kcd itself */
MEM_freeN(kcd);
+}
+static void knifetool_exit(bContext *C, wmOperator *op)
+{
+ KnifeTool_OpData *kcd = op->customdata;
+ knifetool_exit_ex(C, kcd);
op->customdata = NULL;
}
@@ -2944,35 +2957,36 @@ static void cage_mapped_verts_callback(void *userData, int index, const float co
}
}
-static void knifetool_update_mval(KnifeTool_OpData *kcd, int mval_i[2])
+static void knifetool_update_mval(KnifeTool_OpData *kcd, const float mval[2])
{
knife_recalc_projmat(kcd);
- kcd->vc.mval[0] = mval_i[0];
- kcd->vc.mval[1] = mval_i[1];
+ copy_v2_v2(kcd->mval, mval);
if (knife_update_active(kcd)) {
ED_region_tag_redraw(kcd->ar);
}
}
+static void knifetool_update_mval_i(KnifeTool_OpData *kcd, const int mval_i[2])
+{
+ float mval[2] = {UNPACK2(mval_i)};
+ knifetool_update_mval(kcd, mval);
+}
+
/* called when modal loop selection gets set up... */
-static int knifetool_init(bContext *C, wmOperator *op, int UNUSED(do_cut))
+static void knifetool_init(bContext *C, KnifeTool_OpData *kcd,
+ const bool only_select, const bool cut_through, const bool is_interactive)
{
- KnifeTool_OpData *kcd;
Scene *scene = CTX_data_scene(C);
Object *obedit = CTX_data_edit_object(C);
DerivedMesh *cage, *final;
SmallHash shash;
void *data[3];
- const short only_select = RNA_boolean_get(op->ptr, "only_selected");
-
- /* alloc new customdata */
- kcd = op->customdata = MEM_callocN(sizeof(KnifeTool_OpData), "knifetool Modal Op Data");
/* assign the drawing handle for drawing preview line... */
kcd->ob = obedit;
kcd->ar = CTX_wm_region(C);
- kcd->draw_handle = ED_region_draw_cb_activate(kcd->ar->type, knifetool_draw, kcd, REGION_DRAW_POST_VIEW);
+
em_setup_viewcontext(C, &kcd->vc);
kcd->em = BMEdit_FromObject(kcd->ob);
@@ -2998,7 +3012,7 @@ static int knifetool_init(bContext *C, wmOperator *op, int UNUSED(do_cut))
kcd->vthresh = KMAXDIST - 1;
kcd->ethresh = KMAXDIST;
- kcd->extend = 1;
+ kcd->extend = true;
knife_recalc_projmat(kcd);
@@ -3013,7 +3027,8 @@ static int knifetool_init(bContext *C, wmOperator *op, int UNUSED(do_cut))
kcd->kedgefacemap = BLI_ghash_ptr_new("knife origvertmap");
/* cut all the way through the mesh if use_occlude_geometry button not pushed */
- kcd->cut_through = !RNA_boolean_get(op->ptr, "use_occlude_geometry");
+ kcd->is_interactive = is_interactive;
+ kcd->cut_through = cut_through;
kcd->only_select = only_select;
/* can't usefully select resulting edges in face mode */
@@ -3022,9 +3037,11 @@ static int knifetool_init(bContext *C, wmOperator *op, int UNUSED(do_cut))
knife_pos_data_clear(&kcd->curr);
knife_pos_data_clear(&kcd->prev);
- knife_init_colors(&kcd->colors);
+ if (is_interactive) {
+ kcd->draw_handle = ED_region_draw_cb_activate(kcd->ar->type, knifetool_draw, kcd, REGION_DRAW_POST_VIEW);
- return 1;
+ knife_init_colors(&kcd->colors);
+ }
}
static int knifetool_cancel(bContext *C, wmOperator *op)
@@ -3034,21 +3051,25 @@ static int knifetool_cancel(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
-static int knifetool_invoke(bContext *C, wmOperator *op, wmEvent *evt)
+static int knifetool_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
+ const bool only_select = RNA_boolean_get(op->ptr, "only_selected");
+ const bool cut_through = !RNA_boolean_get(op->ptr, "use_occlude_geometry");
+
KnifeTool_OpData *kcd;
view3d_operator_needs_opengl(C);
- if (!knifetool_init(C, op, 0))
- return OPERATOR_CANCELLED;
+ /* alloc new customdata */
+ kcd = op->customdata = MEM_callocN(sizeof(KnifeTool_OpData), __func__);
+
+ knifetool_init(C, kcd, only_select, cut_through, true);
/* add a modal handler for this operator - handles loop selection */
WM_cursor_modal(CTX_wm_window(C), BC_KNIFECURSOR);
WM_event_add_modal_handler(C, op);
- kcd = op->customdata;
- knifetool_update_mval(kcd, evt->mval);
+ knifetool_update_mval_i(kcd, event->mval);
knife_update_header(C, kcd);
@@ -3119,11 +3140,11 @@ wmKeyMap *knifetool_modal_keymap(wmKeyConfig *keyconf)
return keymap;
}
-static int knifetool_modal(bContext *C, wmOperator *op, wmEvent *event)
+static int knifetool_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
Object *obedit = CTX_data_edit_object(C);
KnifeTool_OpData *kcd = op->customdata;
- int do_refresh = FALSE;
+ bool do_refresh = false;
if (!obedit || obedit->type != OB_MESH || BMEdit_FromObject(obedit) != kcd->em) {
knifetool_exit(C, op);
@@ -3158,7 +3179,7 @@ static int knifetool_modal(bContext *C, wmOperator *op, wmEvent *event)
return OPERATOR_FINISHED;
case KNF_MODAL_MIDPOINT_ON:
- kcd->snap_midpoints = 1;
+ kcd->snap_midpoints = true;
knife_recalc_projmat(kcd);
knife_update_active(kcd);
@@ -3167,7 +3188,7 @@ static int knifetool_modal(bContext *C, wmOperator *op, wmEvent *event)
do_refresh = TRUE;
break;
case KNF_MODAL_MIDPOINT_OFF:
- kcd->snap_midpoints = 0;
+ kcd->snap_midpoints = false;
knife_recalc_projmat(kcd);
knife_update_active(kcd);
@@ -3177,13 +3198,13 @@ static int knifetool_modal(bContext *C, wmOperator *op, wmEvent *event)
break;
case KNF_MODEL_IGNORE_SNAP_ON:
ED_region_tag_redraw(kcd->ar);
- kcd->ignore_vert_snapping = kcd->ignore_edge_snapping = 1;
+ kcd->ignore_vert_snapping = kcd->ignore_edge_snapping = true;
knife_update_header(C, kcd);
do_refresh = TRUE;
break;
case KNF_MODEL_IGNORE_SNAP_OFF:
ED_region_tag_redraw(kcd->ar);
- kcd->ignore_vert_snapping = kcd->ignore_edge_snapping = 0;
+ kcd->ignore_vert_snapping = kcd->ignore_edge_snapping = false;
knife_update_header(C, kcd);
do_refresh = TRUE;
break;
@@ -3241,7 +3262,7 @@ static int knifetool_modal(bContext *C, wmOperator *op, wmEvent *event)
case MOUSEMOVE: /* mouse moved somewhere to select another loop */
if (kcd->mode != MODE_PANNING) {
- knifetool_update_mval(kcd, event->mval);
+ knifetool_update_mval_i(kcd, event->mval);
}
break;
@@ -3251,7 +3272,7 @@ static int knifetool_modal(bContext *C, wmOperator *op, wmEvent *event)
if (do_refresh) {
/* we don't really need to update mval,
* but this happens to be the best way to refresh at the moment */
- knifetool_update_mval(kcd, event->mval);
+ knifetool_update_mval_i(kcd, event->mval);
}
/* keep going until the user confirms */
@@ -3277,3 +3298,229 @@ void MESH_OT_knife_tool(wmOperatorType *ot)
RNA_def_boolean(ot->srna, "use_occlude_geometry", TRUE, "Occlude Geometry", "Only cut the front most geometry");
RNA_def_boolean(ot->srna, "only_selected", FALSE, "Only Selected", "Only cut selected geometry");
}
+
+
+/* -------------------------------------------------------------------- */
+/* Knife tool as a utility function
+ * that can be used for internal slicing operations */
+
+/**
+ * Return a point inside the face.
+ *
+ * tessellation here seems way overkill,
+ * but without this its very hard to know of a point is inside the face
+ */
+static void edvm_mesh_knife_face_point(BMFace *f, float r_cent[3])
+{
+ int tottri = f->len - 2;
+ BMLoop **loops = BLI_array_alloca(loops, f->len);
+ int (*index)[3] = BLI_array_alloca(index, tottri);
+ int j;
+
+ float const *best_co[3] = {NULL};
+ float best_area = -1.0f;
+ bool ok = false;
+
+ tottri = BM_face_calc_tessellation(f, loops, index);
+ BLI_assert(tottri <= f->len - 2);
+
+ for (j = 0; j < tottri; j++) {
+ const float *p1 = loops[index[j][0]]->v->co;
+ const float *p2 = loops[index[j][1]]->v->co;
+ const float *p3 = loops[index[j][2]]->v->co;
+ float area;
+
+ float cross[3];
+ cross_v3_v3v3(cross, p2, p3);
+ area = fabsf(dot_v3v3(p1, cross));
+ if (area > best_area) {
+ best_co[0] = p1;
+ best_co[1] = p2;
+ best_co[2] = p3;
+ best_area = area;
+ ok = true;
+ }
+ }
+
+ if (ok) {
+ mid_v3_v3v3v3(r_cent, best_co[0], best_co[1], best_co[2]);
+ }
+ else {
+ mid_v3_v3v3v3(r_cent, loops[0]->v->co, loops[1]->v->co, loops[2]->v->co);
+ }
+}
+
+static bool edbm_mesh_knife_face_isect(ARegion *ar, LinkNode *polys, BMFace *f, float projmat[4][4])
+{
+ float cent_ss[2];
+ float cent[3];
+
+ edvm_mesh_knife_face_point(f, cent);
+
+ ED_view3d_project_float_v2_m4(ar, cent, cent_ss, projmat);
+
+ /* check */
+ {
+ LinkNode *p = polys;
+ int isect = 0;
+
+ while (p) {
+ const float (*mval_fl)[2] = p->link;
+ const int mval_tot = MEM_allocN_len(mval_fl) / sizeof(*mval_fl);
+ isect += (int)isect_point_poly_v2(cent_ss, mval_fl, mval_tot - 1);
+ p = p->next;
+ }
+
+ if (isect % 2) {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+/**
+ * \param use_tag When set, tag all faces inside the polylines.
+ */
+void EDBM_mesh_knife(bContext *C, LinkNode *polys, bool use_tag)
+{
+ KnifeTool_OpData *kcd;
+
+ view3d_operator_needs_opengl(C);
+
+ /* init */
+ {
+ const bool only_select = false;
+ const bool cut_through = false;
+ const bool is_interactive = false; /* can enable for testing */
+
+ kcd = MEM_callocN(sizeof(KnifeTool_OpData), __func__);
+
+ knifetool_init(C, kcd, only_select, cut_through, is_interactive);
+
+ kcd->ignore_edge_snapping = true;
+ kcd->ignore_vert_snapping = true;
+
+ if (use_tag) {
+ BM_mesh_elem_hflag_enable_all(kcd->em->bm, BM_EDGE, BM_ELEM_TAG, false);
+ }
+ }
+
+ /* execute */
+ {
+ LinkNode *p = polys;
+
+ knife_recalc_projmat(kcd);
+
+ while (p) {
+ const float (*mval_fl)[2] = p->link;
+ const int mval_tot = MEM_allocN_len(mval_fl) / sizeof(*mval_fl);
+ int i;
+
+ for (i = 0; i < mval_tot; i++) {
+ knifetool_update_mval(kcd, mval_fl[i]);
+ if (i == 0) {
+ knife_start_cut(kcd);
+ kcd->mode = MODE_DRAGGING;
+ }
+ else {
+ knife_add_cut(kcd);
+ }
+ }
+ knife_finish_cut(kcd);
+ kcd->mode = MODE_IDLE;
+ p = p->next;
+ }
+ }
+
+ /* finish */
+ {
+ knifetool_finish_ex(kcd);
+
+ /* tag faces inside! */
+ if (use_tag) {
+ BMesh *bm = kcd->em->bm;
+ float projmat[4][4];
+
+ BMEdge *e;
+ BMIter iter;
+
+ bool keep_search;
+
+ ED_view3d_ob_project_mat_get(kcd->ar->regiondata, kcd->ob, projmat);
+
+ /* use face-loop tag to store if we have intersected */
+#define F_ISECT_IS_UNKNOWN(f) BM_elem_flag_test(BM_FACE_FIRST_LOOP(f), BM_ELEM_TAG)
+#define F_ISECT_SET_UNKNOWN(f) BM_elem_flag_enable(BM_FACE_FIRST_LOOP(f), BM_ELEM_TAG)
+#define F_ISECT_SET_OUTSIDE(f) BM_elem_flag_disable(BM_FACE_FIRST_LOOP(f), BM_ELEM_TAG)
+ {
+ BMFace *f;
+ BM_ITER_MESH (f, &iter, bm, BM_FACES_OF_MESH) {
+ F_ISECT_SET_UNKNOWN(f);
+ BM_elem_flag_disable(f, BM_ELEM_TAG);
+ }
+ }
+
+ /* tag all faces linked to cut edges */
+ BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) {
+ /* check are we tagged?, then we are an original face */
+ if (BM_elem_flag_test(e, BM_ELEM_TAG) == false) {
+ BMFace *f;
+ BMIter fiter;
+ BM_ITER_ELEM (f, &fiter, e, BM_FACES_OF_EDGE) {
+ if (edbm_mesh_knife_face_isect(kcd->ar, polys, f, projmat)) {
+ BM_elem_flag_enable(f, BM_ELEM_TAG);
+ }
+ }
+ }
+ }
+
+ /* expand tags for faces which are not cut, but are inside the polys */
+ do {
+ BMFace *f;
+ keep_search = false;
+ BM_ITER_MESH (f, &iter, bm, BM_FACES_OF_MESH) {
+ if (BM_elem_flag_test(f, BM_ELEM_TAG) == false && (F_ISECT_IS_UNKNOWN(f))) {
+ /* am I connected to a tagged face via an un-tagged edge (ie, not across a cut) */
+ BMLoop *l_first = BM_FACE_FIRST_LOOP(f);
+ BMLoop *l_iter = l_first;
+ bool found = false;
+
+ do {
+ if (BM_elem_flag_test(l_iter->e, BM_ELEM_TAG) != false) {
+ /* now check if the adjacent faces is tagged */
+ BMLoop *l_radial_iter = l_iter->radial_next;
+ if (l_radial_iter != l_iter) {
+ do {
+ if (BM_elem_flag_test(l_radial_iter->f, BM_ELEM_TAG)) {
+ found = true;
+ }
+ } while ((l_radial_iter = l_radial_iter->radial_next) != l_iter && (found == false));
+ }
+ }
+ } while ((l_iter = l_iter->next) != l_first && (found == false));
+
+ if (found) {
+ if (edbm_mesh_knife_face_isect(kcd->ar, polys, f, projmat)) {
+ BM_elem_flag_enable(f, BM_ELEM_TAG);
+ keep_search = true;
+ }
+ else {
+ /* don't loose time on this face again, set it as outside */
+ F_ISECT_SET_OUTSIDE(f);
+ }
+ }
+ }
+ }
+ } while (keep_search);
+
+#undef F_ISECT_IS_UNKNOWN
+#undef F_ISECT_SET_UNKNOWN
+#undef F_ISECT_SET_OUTSIDE
+
+ }
+
+ knifetool_exit_ex(C, kcd);
+ kcd = NULL;
+ }
+}
diff --git a/source/blender/editors/mesh/editmesh_knife_project.c b/source/blender/editors/mesh/editmesh_knife_project.c
new file mode 100644
index 00000000000..c581ce5a2e8
--- /dev/null
+++ b/source/blender/editors/mesh/editmesh_knife_project.c
@@ -0,0 +1,168 @@
+/*
+ * ***** 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) 2007 Blender Foundation.
+ * All rights reserved.
+ *
+ *
+ * Contributor(s): Campbell Barton
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/editors/mesh/editmesh_knife_project.c
+ * \ingroup edmesh
+ */
+
+#include "DNA_curve_types.h"
+#include "DNA_scene_types.h"
+#include "DNA_object_types.h"
+#include "DNA_screen_types.h"
+#include "DNA_windowmanager_types.h"
+
+#include "BLI_utildefines.h"
+#include "BLI_math.h"
+#include "BLI_linklist.h"
+#include "BLI_listbase.h"
+
+#include "BKE_library.h"
+#include "BKE_mesh.h"
+#include "BKE_context.h"
+#include "BKE_curve.h"
+#include "BKE_cdderivedmesh.h"
+#include "BKE_tessmesh.h"
+#include "BKE_report.h"
+
+#include "MEM_guardedalloc.h"
+
+#include "WM_types.h"
+
+#include "ED_screen.h"
+#include "ED_view3d.h"
+
+#include "mesh_intern.h"
+
+
+static LinkNode *knifeproject_poly_from_object(ARegion *ar, Scene *scene, Object *ob, LinkNode *polys)
+{
+ DerivedMesh *dm;
+ bool dm_needsFree;
+
+ if (ob->type == OB_MESH || ob->derivedFinal) {
+ dm = ob->derivedFinal ? ob->derivedFinal : mesh_get_derived_final(scene, ob, CD_MASK_BAREMESH);
+ dm_needsFree = false;
+ }
+ else if (ELEM3(ob->type, OB_FONT, OB_CURVE, OB_SURF)) {
+ dm = CDDM_from_curve(ob);
+ dm_needsFree = true;
+ }
+ else {
+ dm = NULL;
+ }
+
+ if (dm) {
+ ListBase nurbslist = {NULL, NULL};
+ float projmat[4][4];
+
+ BKE_mesh_to_curve_nurblist(dm, &nurbslist, 0); /* wire */
+ BKE_mesh_to_curve_nurblist(dm, &nurbslist, 1); /* boundary */
+
+ ED_view3d_ob_project_mat_get(ar->regiondata, ob, projmat);
+
+ if (nurbslist.first) {
+ Nurb *nu;
+ for (nu = nurbslist.first; nu; nu = nu->next) {
+ if (nu->bp) {
+ int a;
+ BPoint *bp;
+ bool is_cyclic = (nu->flagu & CU_NURB_CYCLIC) != 0;
+ float (*mval)[2] = MEM_mallocN(sizeof(*mval) * (nu->pntsu + is_cyclic), __func__);
+
+ for (bp = nu->bp, a = 0; a < nu->pntsu; a++, bp++) {
+ ED_view3d_project_float_v3_m4(ar, bp->vec, mval[a], projmat);
+ }
+ if (is_cyclic) {
+ copy_v2_v2(mval[a], mval[0]);
+ }
+
+ BLI_linklist_prepend(&polys, mval);
+ }
+ }
+ }
+
+ BKE_nurbList_free(&nurbslist);
+
+ if (dm_needsFree) {
+ dm->release(dm);
+ }
+ }
+
+
+ return polys;
+}
+
+static int knifeproject_exec(bContext *C, wmOperator *op)
+{
+ ARegion *ar = CTX_wm_region(C);
+ Scene *scene = CTX_data_scene(C);
+ Object *obedit = CTX_data_edit_object(C);
+ BMEditMesh *em = BMEdit_FromObject(obedit);
+
+ LinkNode *polys = NULL;
+
+ CTX_DATA_BEGIN (C, Object *, ob, selected_objects)
+ {
+ if (ob != obedit) {
+ polys = knifeproject_poly_from_object(ar, scene, ob, polys);
+ }
+ }
+ CTX_DATA_END;
+
+ if (polys) {
+ EDBM_mesh_knife(C, polys, true);
+
+ /* select only tagged faces */
+ BM_mesh_elem_hflag_disable_all(em->bm, BM_VERT | BM_EDGE | BM_FACE, BM_ELEM_SELECT, false);
+ BM_mesh_elem_hflag_enable_test(em->bm, BM_FACE, BM_ELEM_SELECT, true, BM_ELEM_TAG);
+
+ BM_mesh_select_mode_flush(em->bm);
+
+ BLI_linklist_freeN(polys);
+
+ return OPERATOR_FINISHED;
+ }
+ else {
+ BKE_report(op->reports, RPT_ERROR, "No other selected objects found to use for projection");
+ return OPERATOR_CANCELLED;
+ }
+}
+
+void MESH_OT_knife_project(wmOperatorType *ot)
+{
+ /* description */
+ ot->name = "Knife Project";
+ ot->idname = "MESH_OT_knife_project";
+ ot->description = "Use other objects outlines & boundaries to project knife cuts";
+
+ /* callbacks */
+ ot->exec = knifeproject_exec;
+ ot->poll = ED_operator_editmesh_view3d;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_BLOCKING;
+}
+
diff --git a/source/blender/editors/mesh/editmesh_loopcut.c b/source/blender/editors/mesh/editmesh_loopcut.c
index 83542915ec2..5b9864ca239 100644
--- a/source/blender/editors/mesh/editmesh_loopcut.c
+++ b/source/blender/editors/mesh/editmesh_loopcut.c
@@ -385,7 +385,7 @@ static int ringcut_cancel(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
-static int ringcut_invoke(bContext *C, wmOperator *op, wmEvent *evt)
+static int ringcut_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
ScrArea *sa = CTX_wm_area(C);
Object *obedit = CTX_data_edit_object(C);
@@ -405,8 +405,7 @@ static int ringcut_invoke(bContext *C, wmOperator *op, wmEvent *evt)
WM_event_add_modal_handler(C, op);
lcd = op->customdata;
- lcd->vc.mval[0] = evt->mval[0];
- lcd->vc.mval[1] = evt->mval[1];
+ copy_v2_v2_int(lcd->vc.mval, event->mval);
edge = EDBM_edge_find_nearest(&lcd->vc, &dist);
if (edge != lcd->eed) {
@@ -419,7 +418,7 @@ static int ringcut_invoke(bContext *C, wmOperator *op, wmEvent *evt)
return OPERATOR_RUNNING_MODAL;
}
-static int loopcut_modal(bContext *C, wmOperator *op, wmEvent *event)
+static int loopcut_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
float smoothness = RNA_float_get(op->ptr, "smoothness");
int cuts = RNA_int_get(op->ptr, "number_cuts");
diff --git a/source/blender/editors/mesh/editmesh_rip.c b/source/blender/editors/mesh/editmesh_rip.c
index 6cbf5e88cee..8198e088e5a 100644
--- a/source/blender/editors/mesh/editmesh_rip.c
+++ b/source/blender/editors/mesh/editmesh_rip.c
@@ -33,9 +33,6 @@
#include "DNA_object_types.h"
-#include "RNA_define.h"
-#include "RNA_access.h"
-
#include "BLI_math.h"
#include "BLI_array.h"
@@ -43,6 +40,9 @@
#include "BKE_report.h"
#include "BKE_tessmesh.h"
+#include "RNA_define.h"
+#include "RNA_access.h"
+
#include "WM_types.h"
#include "ED_mesh.h"
@@ -499,16 +499,9 @@ static void edbm_tagged_loop_pairs_do_fill_faces(BMesh *bm, UnorderedLoopPair *u
BM_elem_attrs_copy(bm, bm, BM_edge_other_loop(ulp->l_pair[0]->e, l_iter), l_iter);
}
else {
- if (v_shared == f_verts[0]) {
- BM_elem_attrs_copy(bm, bm, BM_edge_other_loop(ulp->l_pair[0]->e, l_iter), l_iter); l_iter = l_iter->next;
- BM_elem_attrs_copy(bm, bm, BM_edge_other_loop(ulp->l_pair[0]->e, l_iter), l_iter); l_iter = l_iter->next;
- BM_elem_attrs_copy(bm, bm, BM_edge_other_loop(ulp->l_pair[1]->e, l_iter), l_iter);
- }
- else {
- BM_elem_attrs_copy(bm, bm, BM_edge_other_loop(ulp->l_pair[0]->e, l_iter), l_iter); l_iter = l_iter->next;
- BM_elem_attrs_copy(bm, bm, BM_edge_other_loop(ulp->l_pair[0]->e, l_iter), l_iter); l_iter = l_iter->next;
- BM_elem_attrs_copy(bm, bm, BM_edge_other_loop(ulp->l_pair[1]->e, l_iter), l_iter);
- }
+ BM_elem_attrs_copy(bm, bm, BM_edge_other_loop(ulp->l_pair[0]->e, l_iter), l_iter); l_iter = l_iter->next;
+ BM_elem_attrs_copy(bm, bm, BM_edge_other_loop(ulp->l_pair[0]->e, l_iter), l_iter); l_iter = l_iter->next;
+ BM_elem_attrs_copy(bm, bm, BM_edge_other_loop(ulp->l_pair[1]->e, l_iter), l_iter);
}
}
@@ -538,7 +531,7 @@ static int edbm_rip_call_edgesplit(BMEditMesh *em, wmOperator *op)
/**
* This is the main vert ripping function (rip when one vertex is selected)
*/
-static int edbm_rip_invoke__vert(bContext *C, wmOperator *op, wmEvent *event)
+static int edbm_rip_invoke__vert(bContext *C, wmOperator *op, const wmEvent *event)
{
const int do_fill = RNA_boolean_get(op->ptr, "use_fill");
UnorderedLoopPair *fill_uloop_pairs = NULL;
@@ -860,7 +853,7 @@ static int edbm_rip_invoke__vert(bContext *C, wmOperator *op, wmEvent *event)
/**
* This is the main edge ripping function
*/
-static int edbm_rip_invoke__edge(bContext *C, wmOperator *op, wmEvent *event)
+static int edbm_rip_invoke__edge(bContext *C, wmOperator *op, const wmEvent *event)
{
const int do_fill = RNA_boolean_get(op->ptr, "use_fill");
UnorderedLoopPair *fill_uloop_pairs = NULL;
@@ -988,7 +981,7 @@ static int edbm_rip_invoke__edge(bContext *C, wmOperator *op, wmEvent *event)
}
/* based on mouse cursor position, it defines how is being ripped */
-static int edbm_rip_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int edbm_rip_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
Object *obedit = CTX_data_edit_object(C);
BMEditMesh *em = BMEdit_FromObject(obedit);
diff --git a/source/blender/editors/mesh/editmesh_select.c b/source/blender/editors/mesh/editmesh_select.c
index 1016c08e1c4..a1c302c6a63 100644
--- a/source/blender/editors/mesh/editmesh_select.c
+++ b/source/blender/editors/mesh/editmesh_select.c
@@ -66,6 +66,8 @@
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
+#include "GPU_extensions.h"
+
#include "mesh_intern.h"
#include "UI_resources.h"
@@ -253,6 +255,9 @@ int EDBM_backbuf_border_mask_init(ViewContext *vc, const int mcords[][2], short
dr = buf->rect;
+ if (vc->rv3d->gpuoffscreen)
+ GPU_offscreen_bind(vc->rv3d->gpuoffscreen);
+
/* draw the mask */
glDisable(GL_DEPTH_TEST);
@@ -270,6 +275,9 @@ int EDBM_backbuf_border_mask_init(ViewContext *vc, const int mcords[][2], short
glFinish(); /* to be sure readpixels sees mask */
+ if (vc->rv3d->gpuoffscreen)
+ GPU_offscreen_unbind(vc->rv3d->gpuoffscreen);
+
/* grab mask */
bufmask = view3d_read_backbuf(vc, xmin, ymin, xmax, ymax);
@@ -308,8 +316,10 @@ int EDBM_backbuf_circle_init(ViewContext *vc, short xs, short ys, short rads)
return 0;
}
}
- else if (vc->v3d->drawtype < OB_SOLID || (vc->v3d->flag & V3D_ZBUF_SELECT) == 0) return 0;
-
+ else if (vc->v3d->drawtype < OB_SOLID || (vc->v3d->flag & V3D_ZBUF_SELECT) == 0) {
+ return 0;
+ }
+
xmin = xs - rads; xmax = xs + rads;
ymin = ys - rads; ymax = ys + rads;
buf = view3d_read_backbuf(vc, xmin, ymin, xmax, ymax);
@@ -932,7 +942,7 @@ static int edbm_select_mode_exec(bContext *C, wmOperator *op)
}
}
-static int edbm_select_mode_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int edbm_select_mode_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
/* detecting these options based on shift/ctrl here is weak, but it's done
* to make this work when clicking buttons or menus */
@@ -1084,7 +1094,7 @@ void MESH_OT_loop_multi_select(wmOperatorType *ot)
/* ***************** loop select (non modal) ************** */
-static void mouse_mesh_loop(bContext *C, int mval[2], short extend, short deselect, short toggle, short ring)
+static void mouse_mesh_loop(bContext *C, const int mval[2], short extend, short deselect, short toggle, short ring)
{
ViewContext vc;
BMEditMesh *em;
@@ -1171,7 +1181,7 @@ static void mouse_mesh_loop(bContext *C, int mval[2], short extend, short desele
/* Select the face of eed which is the nearest of mouse. */
BMFace *f, *efa = NULL;
BMIter iterf;
- float best_dist = MAXFLOAT;
+ float best_dist = FLT_MAX;
/* We can't be sure this has already been set... */
ED_view3d_init_mats_rv3d(vc.obedit, vc.rv3d);
@@ -1203,7 +1213,7 @@ static void mouse_mesh_loop(bContext *C, int mval[2], short extend, short desele
}
}
-static int edbm_select_loop_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int edbm_select_loop_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
view3d_operator_needs_opengl(C);
@@ -1754,7 +1764,7 @@ static int mouse_mesh_shortest_path_face(ViewContext *vc)
/* ******************* operator for edge and face tag ****************** */
-static int edbm_shortest_path_select_invoke(bContext *C, wmOperator *UNUSED(op), wmEvent *event)
+static int edbm_shortest_path_select_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *event)
{
ViewContext vc;
BMEditMesh *em;
@@ -2252,7 +2262,7 @@ static void linked_limit_default(bContext *C, wmOperator *op)
}
}
-static int edbm_select_linked_pick_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int edbm_select_linked_pick_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
Object *obedit = CTX_data_edit_object(C);
ViewContext vc;
@@ -2995,6 +3005,59 @@ void MESH_OT_select_random(wmOperatorType *ot)
RNA_def_boolean(ot->srna, "extend", false, "Extend", "Extend the selection");
}
+static int edbm_select_ungrouped_exec(bContext *C, wmOperator *op)
+{
+ Object *obedit = CTX_data_edit_object(C);
+ BMEditMesh *em = BMEdit_FromObject(obedit);
+ BMVert *eve;
+ BMIter iter;
+
+ if (!em->selectmode == SCE_SELECT_VERTEX) {
+ BKE_report(op->reports, RPT_ERROR, "Does not work out of vertex selection mode");
+ return OPERATOR_CANCELLED;
+ }
+
+ if (obedit->defbase.first == NULL) {
+ BKE_report(op->reports, RPT_ERROR, "No weights/vertex groups on object");
+ return OPERATOR_CANCELLED;
+ }
+
+ if (!RNA_boolean_get(op->ptr, "extend")) {
+ EDBM_flag_disable_all(em, BM_ELEM_SELECT);
+ }
+
+ BM_ITER_MESH (eve, &iter, em->bm, BM_VERTS_OF_MESH) {
+ if (!BM_elem_flag_test(eve, BM_ELEM_HIDDEN)) {
+ MDeformVert *dv = CustomData_bmesh_get(&em->bm->vdata, eve->head.data, CD_MDEFORMVERT);
+ /* no dv or dv set with no weight */
+ if (dv == NULL || (dv && dv->dw == NULL)) {
+ BM_vert_select_set(em->bm, eve, true);
+ }
+ }
+ }
+
+ WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data);
+
+ return OPERATOR_FINISHED;
+}
+
+void MESH_OT_select_ungrouped(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Select Ungrouped";
+ ot->idname = "MESH_OT_select_ungrouped";
+ ot->description = "Select vertices without a group";
+
+ /* api callbacks */
+ ot->exec = edbm_select_ungrouped_exec;
+ ot->poll = ED_operator_editmesh;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+
+ RNA_def_boolean(ot->srna, "extend", false, "Extend", "Extend the selection");
+}
+
static int edbm_select_next_loop_exec(bContext *C, wmOperator *UNUSED(op))
{
Object *obedit = CTX_data_edit_object(C);
diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c
index c35f942cf33..36a1d30c85e 100644
--- a/source/blender/editors/mesh/editmesh_tools.c
+++ b/source/blender/editors/mesh/editmesh_tools.c
@@ -39,10 +39,6 @@
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
-#include "RNA_define.h"
-#include "RNA_access.h"
-#include "RNA_enum_types.h"
-
#include "BLI_blenlib.h"
#include "BLI_noise.h"
#include "BLI_math.h"
@@ -59,6 +55,10 @@
#include "BKE_main.h"
#include "BKE_tessmesh.h"
+#include "RNA_define.h"
+#include "RNA_access.h"
+#include "RNA_enum_types.h"
+
#include "WM_api.h"
#include "WM_types.h"
@@ -77,6 +77,8 @@
#include "mesh_intern.h"
+#define USE_FACE_CREATE_SEL_EXTEND
+
#define MVAL_PIXEL_MARGIN 5.0f
/* allow accumulated normals to form a new direction but don't
@@ -333,10 +335,7 @@ static short edbm_extrude_edge(Object *obedit, BMEditMesh *em, const char hflag,
mult_m4_m4m4(mtx, imtx, obedit->obmat);
}
- for (edge = BM_iter_new(&iter, bm, BM_EDGES_OF_MESH, NULL);
- edge;
- edge = BM_iter_step(&iter))
- {
+ BM_ITER_MESH (edge, &iter, bm, BM_EDGES_OF_MESH) {
if (BM_elem_flag_test(edge, hflag) &&
BM_edge_is_boundary(edge) &&
BM_elem_flag_test(edge->l->f, hflag))
@@ -779,7 +778,7 @@ void MESH_OT_select_interior_faces(wmOperatorType *ot)
}
/* *************** add-click-mesh (extrude) operator ************** */
-static int edbm_dupli_extrude_cursor_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int edbm_dupli_extrude_cursor_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
ViewContext vc;
BMVert *v1;
@@ -863,7 +862,7 @@ static int edbm_dupli_extrude_cursor_invoke(bContext *C, wmOperator *op, wmEvent
copy_v3_v3(min, cent);
mul_m4_v3(vc.obedit->obmat, min); /* view space */
- view3d_get_view_aligned_coordinate(&vc, min, event->mval, TRUE);
+ view3d_get_view_aligned_coordinate(vc.ar, min, event->mval, true);
mul_m4_v3(vc.obedit->imat, min); // back in object space
sub_v3_v3(min, cent);
@@ -912,7 +911,7 @@ static int edbm_dupli_extrude_cursor_invoke(bContext *C, wmOperator *op, wmEvent
BMOIter oiter;
copy_v3_v3(min, curs);
- view3d_get_view_aligned_coordinate(&vc, min, event->mval, FALSE);
+ view3d_get_view_aligned_coordinate(vc.ar, min, event->mval, false);
invert_m4_m4(vc.obedit->imat, vc.obedit->obmat);
mul_m4_v3(vc.obedit->imat, min); // back in object space
@@ -1099,6 +1098,140 @@ static int edbm_add_edge_face__smooth_get(BMesh *bm)
return (vote_on_smooth[0] < vote_on_smooth[1]);
}
+#ifdef USE_FACE_CREATE_SEL_EXTEND
+/**
+ * Function used to get a fixed number of edges linked to a vertex that passes a test function.
+ * This is used so we can request all boundary edges connected to a vertex for eg.
+ */
+static int edbm_add_edge_face_exec__vert_edge_lookup(BMVert *v, BMEdge *e_used, BMEdge **e_arr, const int e_arr_len,
+ bool (* func)(BMEdge *))
+{
+ BMIter iter;
+ BMEdge *e_iter;
+ int i = 0;
+ BM_ITER_ELEM (e_iter, &iter, v, BM_EDGES_OF_VERT) {
+ if (BM_elem_flag_test(e_iter, BM_ELEM_HIDDEN) == false) {
+ if ((e_used == NULL) || (e_used != e_iter)) {
+ if (func(e_iter)) {
+ e_arr[i++] = e_iter;
+ if (i >= e_arr_len) {
+ break;
+ }
+ }
+ }
+ }
+ }
+ return i;
+}
+
+static BMElem *edbm_add_edge_face_exec__tricky_extend_sel(BMesh *bm)
+{
+ BMIter iter;
+ bool found = false;
+
+ if (bm->totvertsel == 1 && bm->totedgesel == 0 && bm->totfacesel == 0) {
+ /* first look for 2 boundary edges */
+ BMVert *v;
+
+ BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) {
+ if (BM_elem_flag_test(v, BM_ELEM_SELECT)) {
+ found = true;
+ break;
+ }
+ }
+
+ if (found) {
+ BMEdge *ed_pair[3];
+ if (
+ ((edbm_add_edge_face_exec__vert_edge_lookup(v, NULL, ed_pair, 3, BM_edge_is_wire) == 2) &&
+ (BM_edge_share_face_check(ed_pair[0], ed_pair[1]) == false)) ||
+
+ ((edbm_add_edge_face_exec__vert_edge_lookup(v, NULL, ed_pair, 3, BM_edge_is_boundary) == 2) &&
+ (BM_edge_share_face_check(ed_pair[0], ed_pair[1]) == false))
+ )
+ {
+ BMEdge *e_other = BM_edge_exists(BM_edge_other_vert(ed_pair[0], v),
+ BM_edge_other_vert(ed_pair[1], v));
+ BM_edge_select_set(bm, ed_pair[0], true);
+ BM_edge_select_set(bm, ed_pair[1], true);
+ if (e_other) {
+ BM_edge_select_set(bm, e_other, true);
+ }
+ return (BMElem *)v;
+ }
+ }
+ }
+ else if (bm->totvertsel == 2 && bm->totedgesel == 1 && bm->totfacesel == 0) {
+ /* first look for 2 boundary edges */
+ BMEdge *e;
+
+ BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) {
+ if (BM_elem_flag_test(e, BM_ELEM_SELECT)) {
+ found = true;
+ break;
+ }
+ }
+ if (found) {
+ BMEdge *ed_pair_v1[2];
+ BMEdge *ed_pair_v2[2];
+ if (
+ ((edbm_add_edge_face_exec__vert_edge_lookup(e->v1, e, ed_pair_v1, 2, BM_edge_is_wire) == 1) &&
+ (edbm_add_edge_face_exec__vert_edge_lookup(e->v2, e, ed_pair_v2, 2, BM_edge_is_wire) == 1) &&
+ (BM_edge_share_face_check(e, ed_pair_v1[0]) == false) &&
+ (BM_edge_share_face_check(e, ed_pair_v2[0]) == false)) ||
+
+ ((edbm_add_edge_face_exec__vert_edge_lookup(e->v1, e, ed_pair_v1, 2, BM_edge_is_boundary) == 1) &&
+ (edbm_add_edge_face_exec__vert_edge_lookup(e->v2, e, ed_pair_v2, 2, BM_edge_is_boundary) == 1) &&
+ (BM_edge_share_face_check(e, ed_pair_v1[0]) == false) &&
+ (BM_edge_share_face_check(e, ed_pair_v2[0]) == false))
+ )
+ {
+ BMVert *v1_other = BM_edge_other_vert(ed_pair_v1[0], e->v1);
+ BMVert *v2_other = BM_edge_other_vert(ed_pair_v2[0], e->v2);
+ BMEdge *e_other = (v1_other != v2_other) ? BM_edge_exists(v1_other, v2_other) : NULL;
+ BM_edge_select_set(bm, ed_pair_v1[0], true);
+ BM_edge_select_set(bm, ed_pair_v2[0], true);
+ if (e_other) {
+ BM_edge_select_set(bm, e_other, true);
+ }
+ return (BMElem *)e;
+ }
+ }
+ }
+
+ return NULL;
+}
+static void edbm_add_edge_face_exec__tricky_finalize_sel(BMesh *bm, BMElem *ele_desel, BMFace *f)
+{
+ /* now we need to find the edge that isnt connected to this element */
+ BM_select_history_clear(bm);
+
+ if (ele_desel->head.htype == BM_VERT) {
+ BMLoop *l = BM_face_vert_share_loop(f, (BMVert *)ele_desel);
+ BLI_assert(f->len == 3);
+ BM_face_select_set(bm, f, false);
+ BM_vert_select_set(bm, (BMVert *)ele_desel, false);
+
+ BM_edge_select_set(bm, l->next->e, true);
+ BM_select_history_store(bm, l->next->e);
+ }
+ else {
+ BMLoop *l = BM_face_edge_share_loop(f, (BMEdge *)ele_desel);
+ BLI_assert(f->len == 4 || f->len == 3);
+ BM_face_select_set(bm, f, false);
+ BM_edge_select_set(bm, (BMEdge *)ele_desel, false);
+ if (f->len == 4) {
+ BM_edge_select_set(bm, l->next->next->e, true);
+ BM_select_history_store(bm, l->next->next->e);
+ }
+ else {
+ BM_vert_select_set(bm, l->next->next->v, true);
+ BM_select_history_store(bm, l->next->next->v);
+ }
+ }
+}
+#endif /* USE_FACE_CREATE_SEL_EXTEND */
+
static int edbm_add_edge_face_exec(bContext *C, wmOperator *op)
{
BMOperator bmop;
@@ -1107,6 +1240,15 @@ static int edbm_add_edge_face_exec(bContext *C, wmOperator *op)
const short use_smooth = edbm_add_edge_face__smooth_get(em->bm);
/* when this is used to dissolve we could avoid this, but checking isnt too slow */
+#ifdef USE_FACE_CREATE_SEL_EXTEND
+ BMElem *ele_desel;
+ BMFace *ele_desel_face;
+
+ /* be extra clever, figure out if a partial selection should be extended so we can create geometry
+ * with single vert or single edge selection */
+ ele_desel = edbm_add_edge_face_exec__tricky_extend_sel(em->bm);
+#endif
+
if (!EDBM_op_init(em, &bmop, op,
"contextual_create geom=%hfev mat_nr=%i use_smooth=%b",
BM_ELEM_SELECT, em->mat_nr, use_smooth))
@@ -1115,8 +1257,22 @@ static int edbm_add_edge_face_exec(bContext *C, wmOperator *op)
}
BMO_op_exec(em->bm, &bmop);
- BMO_slot_buffer_hflag_enable(em->bm, bmop.slots_out, "faces.out", BM_FACE, BM_ELEM_SELECT, TRUE);
- BMO_slot_buffer_hflag_enable(em->bm, bmop.slots_out, "edges.out", BM_EDGE, BM_ELEM_SELECT, TRUE);
+
+#ifdef USE_FACE_CREATE_SEL_EXTEND
+ /* normally we would want to leave the new geometry selected,
+ * but being able to press F many times to add geometry is too useful! */
+ if (ele_desel &&
+ (BMO_slot_buffer_count(bmop.slots_out, "faces.out") == 1) &&
+ (ele_desel_face = BMO_slot_buffer_get_first(bmop.slots_out, "faces.out")))
+ {
+ edbm_add_edge_face_exec__tricky_finalize_sel(em->bm, ele_desel, ele_desel_face);
+ }
+ else
+#endif
+ {
+ BMO_slot_buffer_hflag_enable(em->bm, bmop.slots_out, "faces.out", BM_FACE, BM_ELEM_SELECT, true);
+ BMO_slot_buffer_hflag_enable(em->bm, bmop.slots_out, "edges.out", BM_EDGE, BM_ELEM_SELECT, true);
+ }
if (!EDBM_op_finish(em, &bmop, op, TRUE)) {
return OPERATOR_CANCELLED;
@@ -1355,7 +1511,7 @@ static int edbm_duplicate_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int edbm_duplicate_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int edbm_duplicate_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
WM_cursor_wait(1);
edbm_duplicate_exec(C, op);
@@ -2005,12 +2161,22 @@ static int merge_firstlast(BMEditMesh *em, int first, int uvmerge, wmOperator *w
BMVert *mergevert;
BMEditSelection *ese;
+ /* operator could be called directly from shortcut or python,
+ * so do extra check for data here
+ */
+
/* do sanity check in mergemenu in edit.c ?*/
if (first == 0) {
+ if (!em->bm->selected.last || ((BMEditSelection *)em->bm->selected.last)->htype != BM_VERT)
+ return OPERATOR_CANCELLED;
+
ese = em->bm->selected.last;
mergevert = (BMVert *)ese->ele;
}
else {
+ if (!em->bm->selected.first || ((BMEditSelection *)em->bm->selected.first)->htype != BM_VERT)
+ return OPERATOR_CANCELLED;
+
ese = em->bm->selected.first;
mergevert = (BMVert *)ese->ele;
}
@@ -2293,8 +2459,12 @@ static int edbm_select_vertex_path_exec(bContext *C, wmOperator *op)
if (!BM_elem_flag_test(eve, BM_ELEM_SELECT) || BM_elem_flag_test(eve, BM_ELEM_HIDDEN))
continue;
- if (svert == NULL) svert = eve;
- else if (evert == NULL) evert = eve;
+ if (svert == NULL) {
+ svert = eve;
+ }
+ else if (evert == NULL) {
+ evert = eve;
+ }
else {
/* more than two vertices are selected,
* show warning message and cancel operator */
@@ -3225,6 +3395,16 @@ static int edbm_separate_exec(bContext *C, wmOperator *op)
Base *base = CTX_data_active_base(C);
BMEditMesh *em = BMEdit_FromObject(base->object);
+ if (type == 0) {
+ if ((em->bm->totvertsel == 0) &&
+ (em->bm->totedgesel == 0) &&
+ (em->bm->totfacesel == 0))
+ {
+ BKE_report(op->reports, RPT_ERROR, "Nothing selected");
+ return OPERATOR_CANCELLED;
+ }
+ }
+
/* editmode separate */
if (type == 0) retval = mesh_separate_selected(bmain, scene, base, em->bm);
else if (type == 1) retval = mesh_separate_material(bmain, scene, base, em->bm);
@@ -3689,7 +3869,7 @@ static int edbm_spin_exec(bContext *C, wmOperator *op)
}
/* get center and axis, in global coords */
-static int edbm_spin_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int edbm_spin_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
Scene *scene = CTX_data_scene(C);
View3D *v3d = CTX_wm_view3d(C);
@@ -3759,9 +3939,10 @@ static int edbm_screw_exec(bContext *C, wmOperator *op)
/* find two vertices with valence count == 1, more or less is wrong */
v1 = NULL;
v2 = NULL;
- for (eve = BM_iter_new(&iter, em->bm, BM_VERTS_OF_MESH, NULL); eve; eve = BM_iter_step(&iter)) {
+
+ BM_ITER_MESH (eve, &iter, em->bm, BM_VERTS_OF_MESH) {
valence = 0;
- for (eed = BM_iter_new(&eiter, em->bm, BM_EDGES_OF_VERT, eve); eed; eed = BM_iter_step(&eiter)) {
+ BM_ITER_ELEM (eed, &eiter, eve, BM_EDGES_OF_VERT) {
if (BM_elem_flag_test(eed, BM_ELEM_SELECT)) {
valence++;
}
@@ -3812,7 +3993,7 @@ static int edbm_screw_exec(bContext *C, wmOperator *op)
}
/* get center and axis, in global coords */
-static int edbm_screw_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int edbm_screw_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
Scene *scene = CTX_data_scene(C);
View3D *v3d = CTX_wm_view3d(C);
@@ -4505,7 +4686,7 @@ static int edbm_sort_elements_draw_check_prop(PointerRNA *ptr, PropertyRNA *prop
int action = RNA_enum_get(ptr, "type");
/* Only show seed for randomize action! */
- if (strcmp(prop_id, "seed") == 0) {
+ if (STREQ(prop_id, "seed")) {
if (action == SRT_RANDOMIZE)
return TRUE;
else
@@ -4513,7 +4694,7 @@ static int edbm_sort_elements_draw_check_prop(PointerRNA *ptr, PropertyRNA *prop
}
/* Hide seed for reverse and randomize actions! */
- if (strcmp(prop_id, "reverse") == 0) {
+ if (STREQ(prop_id, "reverse")) {
if (ELEM(action, SRT_RANDOMIZE, SRT_REVERSE))
return FALSE;
else
@@ -4804,7 +4985,7 @@ static int edbm_bevel_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int edbm_bevel_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int edbm_bevel_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
/* TODO make modal keymap (see fly mode) */
RegionView3D *rv3d = CTX_wm_region_view3d(C);
@@ -4841,7 +5022,7 @@ static int edbm_bevel_invoke(bContext *C, wmOperator *op, wmEvent *event)
return OPERATOR_RUNNING_MODAL;
}
-static float edbm_bevel_mval_factor(wmOperator *op, wmEvent *event)
+static float edbm_bevel_mval_factor(wmOperator *op, const wmEvent *event)
{
BevelData *opdata = op->customdata;
int use_dist = TRUE;
@@ -4880,7 +5061,7 @@ static float edbm_bevel_mval_factor(wmOperator *op, wmEvent *event)
return factor;
}
-static int edbm_bevel_modal(bContext *C, wmOperator *op, wmEvent *event)
+static int edbm_bevel_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
BevelData *opdata = op->customdata;
int segments = RNA_int_get(op->ptr, "segments");
@@ -5186,7 +5367,7 @@ static int edbm_inset_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int edbm_inset_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int edbm_inset_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
RegionView3D *rv3d = CTX_wm_region_view3d(C);
InsetData *opdata;
@@ -5216,7 +5397,7 @@ static int edbm_inset_invoke(bContext *C, wmOperator *op, wmEvent *event)
return OPERATOR_RUNNING_MODAL;
}
-static int edbm_inset_modal(bContext *C, wmOperator *op, wmEvent *event)
+static int edbm_inset_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
InsetData *opdata = op->customdata;
diff --git a/source/blender/editors/mesh/mesh_data.c b/source/blender/editors/mesh/mesh_data.c
index 0c9a5aab537..99f526f95f3 100644
--- a/source/blender/editors/mesh/mesh_data.c
+++ b/source/blender/editors/mesh/mesh_data.c
@@ -36,6 +36,7 @@
#include "DNA_scene_types.h"
#include "DNA_view3d_types.h"
+#include "BLI_utildefines.h"
#include "BLI_path_util.h"
#include "BLI_array.h"
#include "BLI_math.h"
@@ -570,7 +571,7 @@ void MESH_OT_uv_texture_add(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
-static int drop_named_image_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int drop_named_image_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
Main *bmain = CTX_data_main(C);
Scene *scene = CTX_data_scene(C);
@@ -884,7 +885,7 @@ void ED_mesh_update(Mesh *mesh, bContext *C, int calc_edges, int calc_tessface)
}
if (calc_edges || ((mesh->totpoly || mesh->totface) && mesh->totedge == 0))
- BKE_mesh_calc_edges(mesh, calc_edges);
+ BKE_mesh_calc_edges(mesh, calc_edges, true);
if (calc_tessface) {
if (tessface_input == FALSE) {
diff --git a/source/blender/editors/mesh/mesh_intern.h b/source/blender/editors/mesh/mesh_intern.h
index fe4917acdac..5dab022dd2f 100644
--- a/source/blender/editors/mesh/mesh_intern.h
+++ b/source/blender/editors/mesh/mesh_intern.h
@@ -48,6 +48,7 @@ struct wmKeyConfig;
struct wmKeyMap;
struct wmOperator;
struct wmOperatorType;
+struct LinkNode;
/* ******************** editmesh_utils.c */
@@ -77,7 +78,6 @@ int EDBM_op_init(struct BMEditMesh *em, struct BMOperator *bmop,
int EDBM_op_finish(struct BMEditMesh *em, struct BMOperator *bmop,
struct wmOperator *op, const int report);
-void EDBM_flag_disable_all(struct BMEditMesh *em, const char hflag);
void EDBM_stats_update(struct BMEditMesh *em);
/* ******************** editface.c */
@@ -128,6 +128,7 @@ void MESH_OT_select_shortest_path(struct wmOperatorType *ot);
void MESH_OT_select_similar(struct wmOperatorType *ot);
void MESH_OT_select_mode(struct wmOperatorType *ot);
void MESH_OT_select_random(struct wmOperatorType *ot);
+void MESH_OT_select_ungrouped(struct wmOperatorType *ot);
void MESH_OT_loop_multi_select(struct wmOperatorType *ot);
void MESH_OT_mark_seam(struct wmOperatorType *ot);
void MESH_OT_mark_sharp(struct wmOperatorType *ot);
@@ -211,6 +212,8 @@ void MESH_OT_edgering_select(struct wmOperatorType *ot);
void MESH_OT_loopcut(struct wmOperatorType *ot);
void MESH_OT_knife_tool(struct wmOperatorType *ot);
+void MESH_OT_knife_project(wmOperatorType *ot);
+
void MESH_OT_bevel(struct wmOperatorType *ot);
void MESH_OT_bridge_edge_loops(struct wmOperatorType *ot);
@@ -228,4 +231,6 @@ void MESH_OT_navmesh_face_add(struct wmOperatorType *ot);
void MESH_OT_navmesh_reset(struct wmOperatorType *ot);
void MESH_OT_navmesh_clear(struct wmOperatorType *ot);
+void EDBM_mesh_knife(struct bContext *C, struct LinkNode *polys, bool use_tag);
+
#endif /* __MESH_INTERN_H__ */
diff --git a/source/blender/editors/mesh/mesh_ops.c b/source/blender/editors/mesh/mesh_ops.c
index 140681304b2..cf3877a8d93 100644
--- a/source/blender/editors/mesh/mesh_ops.c
+++ b/source/blender/editors/mesh/mesh_ops.c
@@ -59,6 +59,7 @@ void ED_operatortypes_mesh(void)
WM_operatortype_append(MESH_OT_select_linked);
WM_operatortype_append(MESH_OT_select_linked_pick);
WM_operatortype_append(MESH_OT_select_random);
+ WM_operatortype_append(MESH_OT_select_ungrouped);
WM_operatortype_append(MESH_OT_hide);
WM_operatortype_append(MESH_OT_reveal);
WM_operatortype_append(MESH_OT_select_face_by_sides);
@@ -155,6 +156,7 @@ void ED_operatortypes_mesh(void)
WM_operatortype_append(MESH_OT_select_nth);
WM_operatortype_append(MESH_OT_vert_connect);
WM_operatortype_append(MESH_OT_knife_tool);
+ WM_operatortype_append(MESH_OT_knife_project);
WM_operatortype_append(MESH_OT_bevel);
diff --git a/source/blender/editors/mesh/meshtools.c b/source/blender/editors/mesh/meshtools.c
index 378f6374336..3d4d204299f 100644
--- a/source/blender/editors/mesh/meshtools.c
+++ b/source/blender/editors/mesh/meshtools.c
@@ -789,7 +789,9 @@ static intptr_t mesh_octree_find_index(MocNode **bt, MVert *mvert, const float c
return (*bt)->index[a];
}
}
- else return -1;
+ else {
+ return -1;
+ }
}
if ( (*bt)->next)
return mesh_octree_find_index(&(*bt)->next, mvert, co);
diff --git a/source/blender/editors/metaball/mball_edit.c b/source/blender/editors/metaball/mball_edit.c
index 6c056df5a38..6781624aec6 100644
--- a/source/blender/editors/metaball/mball_edit.c
+++ b/source/blender/editors/metaball/mball_edit.c
@@ -254,7 +254,7 @@ static int duplicate_metaelems_exec(bContext *C, wmOperator *UNUSED(op))
return OPERATOR_FINISHED;
}
-static int duplicate_metaelems_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int duplicate_metaelems_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
int retv = duplicate_metaelems_exec(C, op);
diff --git a/source/blender/editors/metaball/mball_ops.c b/source/blender/editors/metaball/mball_ops.c
index f91d57424a1..8c705aac0d2 100644
--- a/source/blender/editors/metaball/mball_ops.c
+++ b/source/blender/editors/metaball/mball_ops.c
@@ -28,17 +28,17 @@
* \ingroup edmeta
*/
+#include "BLI_utildefines.h"
+
#include "RNA_access.h"
+#include "WM_api.h"
+#include "WM_types.h"
+
#include "ED_mball.h"
#include "ED_screen.h"
#include "ED_object.h"
-#include "BLI_utildefines.h"
-
-#include "WM_api.h"
-#include "WM_types.h"
-
#include "mball_intern.h"
void ED_operatortypes_metaball(void)
diff --git a/source/blender/editors/object/object_add.c b/source/blender/editors/object/object_add.c
index 997cbb71683..dbb0d55a2b1 100644
--- a/source/blender/editors/object/object_add.c
+++ b/source/blender/editors/object/object_add.c
@@ -49,11 +49,13 @@
#include "DNA_vfont_types.h"
#include "DNA_actuator_types.h"
+#include "BLI_utildefines.h"
#include "BLI_ghash.h"
#include "BLI_listbase.h"
#include "BLI_math.h"
#include "BLI_string.h"
-#include "BLI_utildefines.h"
+
+#include "BLF_translation.h"
#include "BKE_anim.h"
#include "BKE_animsys.h"
@@ -662,7 +664,9 @@ static int object_armature_add_exec(bContext *C, wmOperator *op)
ED_object_enter_editmode(C, 0);
newob = 1;
}
- else DAG_id_tag_update(&obedit->id, OB_RECALC_DATA);
+ else {
+ DAG_id_tag_update(&obedit->id, OB_RECALC_DATA);
+ }
if (obedit == NULL) {
BKE_report(op->reports, RPT_ERROR, "Cannot create editmode armature");
@@ -736,7 +740,7 @@ void OBJECT_OT_empty_add(wmOperatorType *ot)
ED_object_add_generic_props(ot, FALSE);
}
-static int empty_drop_named_image_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int empty_drop_named_image_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
Base *base = NULL;
Image *ima = NULL;
@@ -872,6 +876,7 @@ void OBJECT_OT_lamp_add(wmOperatorType *ot)
/* properties */
ot->prop = RNA_def_enum(ot->srna, "type", lamp_type_items, 0, "Type", "");
+ RNA_def_property_translation_context(ot->prop, BLF_I18NCONTEXT_ID_LAMP);
ED_object_add_generic_props(ot, FALSE);
}
@@ -1482,7 +1487,7 @@ static int convert_exec(bContext *C, wmOperator *op)
newob = ob;
}
- BKE_mesh_from_curve(scene, newob);
+ BKE_mesh_to_curve(scene, newob);
if (newob->type == OB_CURVE)
BKE_object_free_modifiers(newob); /* after derivedmesh calls! */
diff --git a/source/blender/editors/object/object_bake.c b/source/blender/editors/object/object_bake.c
index a680230fb32..dc54207b4e6 100644
--- a/source/blender/editors/object/object_bake.c
+++ b/source/blender/editors/object/object_bake.c
@@ -138,7 +138,9 @@ static int multiresbake_check(bContext *C, wmOperator *op)
}
}
}
- else ok = 0;
+ else {
+ ok = 0;
+ }
if (!ok) {
BKE_report(op->reports, RPT_ERROR, "Multires data baking requires multi-resolution object");
@@ -696,7 +698,7 @@ static void bake_freejob(void *bkv)
}
/* catch esc */
-static int objects_bake_render_modal(bContext *C, wmOperator *UNUSED(op), wmEvent *event)
+static int objects_bake_render_modal(bContext *C, wmOperator *UNUSED(op), const wmEvent *event)
{
/* no running blender, remove handler and pass through */
if (0 == WM_jobs_test(CTX_wm_manager(C), CTX_data_scene(C), WM_JOB_TYPE_OBJECT_BAKE_TEXTURE))
@@ -719,7 +721,7 @@ static int is_multires_bake(Scene *scene)
return 0;
}
-static int objects_bake_render_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(_event))
+static int objects_bake_render_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(_event))
{
Scene *scene = CTX_data_scene(C);
int result = OPERATOR_CANCELLED;
diff --git a/source/blender/editors/object/object_constraint.c b/source/blender/editors/object/object_constraint.c
index 1bed7d7dd11..8e2a87c7c64 100644
--- a/source/blender/editors/object/object_constraint.c
+++ b/source/blender/editors/object/object_constraint.c
@@ -435,7 +435,9 @@ static void test_constraints(Object *owner, bPoseChannel *pchan)
curcon->flag |= CONSTRAINT_DISABLE;
}
}
- else curcon->flag |= CONSTRAINT_DISABLE;
+ else {
+ curcon->flag |= CONSTRAINT_DISABLE;
+ }
}
}
else if (curcon->type == CONSTRAINT_TYPE_CAMERASOLVER) {
@@ -645,7 +647,7 @@ static int stretchto_reset_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int stretchto_reset_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int stretchto_reset_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
if (edit_constraint_invoke_properties(C, op))
return stretchto_reset_exec(C, op);
@@ -691,7 +693,7 @@ static int limitdistance_reset_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int limitdistance_reset_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int limitdistance_reset_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
if (edit_constraint_invoke_properties(C, op))
return limitdistance_reset_exec(C, op);
@@ -827,7 +829,7 @@ static int childof_set_inverse_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int childof_set_inverse_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int childof_set_inverse_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
if (edit_constraint_invoke_properties(C, op))
return childof_set_inverse_exec(C, op);
@@ -874,7 +876,7 @@ static int childof_clear_inverse_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int childof_clear_inverse_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int childof_clear_inverse_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
if (edit_constraint_invoke_properties(C, op))
return childof_clear_inverse_exec(C, op);
@@ -991,7 +993,7 @@ static int followpath_path_animate_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int followpath_path_animate_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int followpath_path_animate_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
/* hook up invoke properties for figuring out which constraint we're dealing with */
if (edit_constraint_invoke_properties(C, op)) {
@@ -1049,7 +1051,7 @@ static int objectsolver_set_inverse_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int objectsolver_set_inverse_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int objectsolver_set_inverse_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
if (edit_constraint_invoke_properties(C, op))
return objectsolver_set_inverse_exec(C, op);
@@ -1095,7 +1097,7 @@ static int objectsolver_clear_inverse_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int objectsolver_clear_inverse_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int objectsolver_clear_inverse_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
if (edit_constraint_invoke_properties(C, op))
return objectsolver_clear_inverse_exec(C, op);
@@ -1231,7 +1233,7 @@ static int constraint_move_down_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
-static int constraint_move_down_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int constraint_move_down_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
if (edit_constraint_invoke_properties(C, op))
return constraint_move_down_exec(C, op);
@@ -1280,7 +1282,7 @@ static int constraint_move_up_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
-static int constraint_move_up_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int constraint_move_up_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
if (edit_constraint_invoke_properties(C, op))
return constraint_move_up_exec(C, op);
@@ -1848,7 +1850,7 @@ void POSE_OT_constraint_add_with_targets(wmOperatorType *ot)
// TODO: should these be here, or back in editors/armature/poseobject.c again?
/* present menu with options + validation for targets to use */
-static int pose_ik_add_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(evt))
+static int pose_ik_add_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
Object *ob = BKE_object_pose_armature_get(CTX_data_active_object(C));
bPoseChannel *pchan = BKE_pose_channel_active(ob);
diff --git a/source/blender/editors/object/object_edit.c b/source/blender/editors/object/object_edit.c
index b94c9e940dc..ca57ab76c57 100644
--- a/source/blender/editors/object/object_edit.c
+++ b/source/blender/editors/object/object_edit.c
@@ -1012,7 +1012,7 @@ static void copy_attr(Main *bmain, Scene *scene, View3D *v3d, short event)
DAG_relations_tag_update(bmain);
}
-static void UNUSED_FUNCTION(copy_attr_menu) (Main * bmain, Scene * scene, View3D * v3d)
+static void UNUSED_FUNCTION(copy_attr_menu) (Main *bmain, Scene *scene, View3D *v3d)
{
Object *ob;
short event;
@@ -1132,7 +1132,7 @@ void ED_objects_recalculate_paths(bContext *C, Scene *scene)
/* show popup to determine settings */
-static int object_calculate_paths_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int object_calculate_paths_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
Object *ob = CTX_data_active_object(C);
@@ -1358,7 +1358,7 @@ void OBJECT_OT_shade_smooth(wmOperatorType *ot)
/* ********************** */
-static void UNUSED_FUNCTION(image_aspect) (Scene * scene, View3D * v3d)
+static void UNUSED_FUNCTION(image_aspect) (Scene *scene, View3D *v3d)
{
/* all selected objects with an image map: scale in image aspect */
Base *base;
diff --git a/source/blender/editors/object/object_intern.h b/source/blender/editors/object/object_intern.h
index a302aa65fd0..163a869613b 100644
--- a/source/blender/editors/object/object_intern.h
+++ b/source/blender/editors/object/object_intern.h
@@ -138,6 +138,7 @@ void OBJECT_OT_hook_recenter(struct wmOperatorType *ot);
/* object_lattice.c */
void LATTICE_OT_select_all(struct wmOperatorType *ot);
+void LATTICE_OT_select_ungrouped(struct wmOperatorType *ot);
void LATTICE_OT_make_regular(struct wmOperatorType *ot);
void LATTICE_OT_flip(struct wmOperatorType *ot);
diff --git a/source/blender/editors/object/object_lattice.c b/source/blender/editors/object/object_lattice.c
index c9eae776ac7..053f1ffabd0 100644
--- a/source/blender/editors/object/object_lattice.c
+++ b/source/blender/editors/object/object_lattice.c
@@ -53,6 +53,7 @@
#include "BKE_key.h"
#include "BKE_lattice.h"
#include "BKE_deform.h"
+#include "BKE_report.h"
#include "ED_lattice.h"
#include "ED_object.h"
@@ -255,6 +256,58 @@ void LATTICE_OT_select_all(wmOperatorType *ot)
WM_operator_properties_select_all(ot);
}
+/************************** Select Ungrouped Verts Operator *************************/
+
+static int lattice_select_ungrouped_exec(bContext *C, wmOperator *op)
+{
+ Object *obedit = CTX_data_edit_object(C);
+ Lattice *lt = ((Lattice *)obedit->data)->editlatt->latt;
+ MDeformVert *dv;
+ BPoint *bp;
+ int a, tot;
+
+ if (obedit->defbase.first == NULL || lt->dvert == NULL) {
+ BKE_report(op->reports, RPT_ERROR, "No weights/vertex groups on object");
+ return OPERATOR_CANCELLED;
+ }
+
+ if (!RNA_boolean_get(op->ptr, "extend")) {
+ ED_setflagsLatt(obedit, 0);
+ }
+
+ dv = lt->dvert;
+ tot = lt->pntsu * lt->pntsv * lt->pntsw;
+
+ for (a = 0, bp = lt->def; a < tot; a++, bp++, dv++) {
+ if (bp->hide == 0) {
+ if (dv->dw == NULL) {
+ bp->f1 |= SELECT;
+ }
+ }
+ }
+
+ WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data);
+
+ return OPERATOR_FINISHED;
+}
+
+void LATTICE_OT_select_ungrouped(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Select Ungrouped";
+ ot->idname = "LATTICE_OT_select_ungrouped";
+ ot->description = "Select vertices without a group";
+
+ /* api callbacks */
+ ot->exec = lattice_select_ungrouped_exec;
+ ot->poll = ED_operator_editlattice;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+
+ RNA_def_boolean(ot->srna, "extend", false, "Extend", "Extend the selection");
+}
+
/************************** Make Regular Operator *************************/
static int make_regular_poll(bContext *C)
diff --git a/source/blender/editors/object/object_modifier.c b/source/blender/editors/object/object_modifier.c
index 8d29813e2ac..d66620c2ff6 100644
--- a/source/blender/editors/object/object_modifier.c
+++ b/source/blender/editors/object/object_modifier.c
@@ -892,7 +892,7 @@ static int modifier_remove_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int modifier_remove_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int modifier_remove_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
if (edit_modifier_invoke_properties(C, op))
return modifier_remove_exec(C, op);
@@ -931,7 +931,7 @@ static int modifier_move_up_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int modifier_move_up_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int modifier_move_up_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
if (edit_modifier_invoke_properties(C, op))
return modifier_move_up_exec(C, op);
@@ -970,7 +970,7 @@ static int modifier_move_down_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int modifier_move_down_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int modifier_move_down_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
if (edit_modifier_invoke_properties(C, op))
return modifier_move_down_exec(C, op);
@@ -1012,7 +1012,7 @@ static int modifier_apply_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int modifier_apply_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int modifier_apply_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
if (edit_modifier_invoke_properties(C, op))
return modifier_apply_exec(C, op);
@@ -1061,7 +1061,7 @@ static int modifier_convert_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int modifier_convert_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int modifier_convert_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
if (edit_modifier_invoke_properties(C, op))
return modifier_convert_exec(C, op);
@@ -1100,7 +1100,7 @@ static int modifier_copy_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int modifier_copy_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int modifier_copy_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
if (edit_modifier_invoke_properties(C, op))
return modifier_copy_exec(C, op);
@@ -1149,7 +1149,7 @@ static int multires_higher_levels_delete_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int multires_higher_levels_delete_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int multires_higher_levels_delete_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
if (edit_modifier_invoke_properties(C, op))
return multires_higher_levels_delete_exec(C, op);
@@ -1199,7 +1199,7 @@ static int multires_subdivide_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int multires_subdivide_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int multires_subdivide_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
if (edit_modifier_invoke_properties(C, op))
return multires_subdivide_exec(C, op);
@@ -1263,7 +1263,7 @@ static int multires_reshape_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int multires_reshape_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int multires_reshape_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
if (edit_modifier_invoke_properties(C, op))
return multires_reshape_exec(C, op);
@@ -1314,7 +1314,7 @@ static int multires_external_save_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int multires_external_save_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int multires_external_save_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
Object *ob = ED_object_active_context(C);
MultiresModifierData *mmd;
@@ -1410,7 +1410,7 @@ static int multires_base_apply_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int multires_base_apply_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int multires_base_apply_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
if (edit_modifier_invoke_properties(C, op))
return multires_base_apply_exec(C, op);
@@ -1834,7 +1834,7 @@ static int skin_armature_create_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int skin_armature_create_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int skin_armature_create_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
if (edit_modifier_invoke_properties(C, op))
return skin_armature_create_exec(C, op);
@@ -1927,7 +1927,7 @@ static int meshdeform_bind_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int meshdeform_bind_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int meshdeform_bind_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
if (edit_modifier_invoke_properties(C, op))
return meshdeform_bind_exec(C, op);
@@ -1975,7 +1975,7 @@ static int explode_refresh_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int explode_refresh_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int explode_refresh_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
if (edit_modifier_invoke_properties(C, op))
return explode_refresh_exec(C, op);
@@ -2191,7 +2191,7 @@ static int ocean_bake_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int ocean_bake_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int ocean_bake_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
if (edit_modifier_invoke_properties(C, op))
return ocean_bake_exec(C, op);
diff --git a/source/blender/editors/object/object_ops.c b/source/blender/editors/object/object_ops.c
index e5aaaffade8..594dfd6e271 100644
--- a/source/blender/editors/object/object_ops.c
+++ b/source/blender/editors/object/object_ops.c
@@ -211,6 +211,7 @@ void ED_operatortypes_object(void)
WM_operatortype_append(OBJECT_OT_shape_key_move);
WM_operatortype_append(LATTICE_OT_select_all);
+ WM_operatortype_append(LATTICE_OT_select_ungrouped);
WM_operatortype_append(LATTICE_OT_make_regular);
WM_operatortype_append(LATTICE_OT_flip);
@@ -364,7 +365,7 @@ void ED_keymap_object(wmKeyConfig *keyconf)
kmi = WM_keymap_add_item(keymap, "OBJECT_OT_delete", XKEY, KM_PRESS, KM_SHIFT, 0);
RNA_boolean_set(kmi->ptr, "use_global", TRUE);
- WM_keymap_add_item(keymap, "OBJECT_OT_delete", DELKEY, KM_PRESS, 0, 0);
+ kmi = WM_keymap_add_item(keymap, "OBJECT_OT_delete", DELKEY, KM_PRESS, 0, 0);
RNA_boolean_set(kmi->ptr, "use_global", FALSE);
kmi = WM_keymap_add_item(keymap, "OBJECT_OT_delete", DELKEY, KM_PRESS, KM_SHIFT, 0);
RNA_boolean_set(kmi->ptr, "use_global", TRUE);
diff --git a/source/blender/editors/object/object_relations.c b/source/blender/editors/object/object_relations.c
index f9dde043607..6039ff6d34b 100644
--- a/source/blender/editors/object/object_relations.c
+++ b/source/blender/editors/object/object_relations.c
@@ -215,7 +215,7 @@ static int vertex_parent_set_exec(bContext *C, wmOperator *op)
}
}
- if (v4 || !((v1 && v2 == 0 && v3 == 0) || (v1 && v2 && v3)) ) {
+ if (v4 || !((v1 && v2 == 0 && v3 == 0) || (v1 && v2 && v3))) {
BKE_report(op->reports, RPT_ERROR, "Select either 1 or 3 vertices to parent to");
return OPERATOR_CANCELLED;
}
@@ -286,7 +286,7 @@ void OBJECT_OT_vertex_parent_set(wmOperatorType *ot)
/********************** Make Proxy Operator *************************/
/* set the object to proxify */
-static int make_proxy_invoke(bContext *C, wmOperator *op, wmEvent *evt)
+static int make_proxy_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
Scene *scene = CTX_data_scene(C);
Object *ob = ED_object_active_context(C);
@@ -299,7 +299,7 @@ static int make_proxy_invoke(bContext *C, wmOperator *op, wmEvent *evt)
if (ob->dup_group && ob->dup_group->id.lib) {
/* gives menu with list of objects in group */
//proxy_group_objects_menu(C, op, ob, ob->dup_group);
- WM_enum_search_invoke(C, op, evt);
+ WM_enum_search_invoke(C, op, event);
return OPERATOR_CANCELLED;
}
@@ -608,8 +608,10 @@ int ED_object_parent_set(ReportList *reports, Main *bmain, Scene *scene, Object
cu->flag |= CU_PATH | CU_FOLLOW;
BKE_displist_make_curveTypes(scene, par, 0); /* force creation of path data */
}
- else cu->flag |= CU_FOLLOW;
-
+ else {
+ cu->flag |= CU_FOLLOW;
+ }
+
/* if follow, add F-Curve for ctime (i.e. "eval_time") so that path-follow works */
if (partype == PAR_FOLLOW) {
/* get or create F-Curve */
@@ -797,7 +799,7 @@ static int parent_set_exec(bContext *C, wmOperator *op)
}
-static int parent_set_invoke(bContext *C, wmOperator *UNUSED(op), wmEvent *UNUSED(event))
+static int parent_set_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *UNUSED(event))
{
Object *ob = ED_object_active_context(C);
uiPopupMenu *pup = uiPupMenuBegin(C, IFACE_("Set Parent To"), ICON_NONE);
@@ -1227,7 +1229,7 @@ static unsigned int move_to_layer_init(bContext *C, wmOperator *op)
return lay;
}
-static int move_to_layer_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int move_to_layer_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
View3D *v3d = CTX_wm_view3d(C);
if (v3d && v3d->localvd) {
@@ -1541,6 +1543,7 @@ static int make_links_data_exec(bContext *C, wmOperator *op)
DAG_relations_tag_update(bmain);
WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, CTX_wm_view3d(C));
+ WM_event_add_notifier(C, NC_OBJECT, NULL);
return OPERATOR_FINISHED;
}
@@ -1928,11 +1931,11 @@ static void make_local_makelocalmaterial(Material *ma)
AnimData *adt;
int b;
- id_make_local(&ma->id, 0);
+ id_make_local(&ma->id, false);
for (b = 0; b < MAX_MTEX; b++)
if (ma->mtex[b] && ma->mtex[b]->tex)
- id_make_local(&ma->mtex[b]->tex->id, 0);
+ id_make_local(&ma->mtex[b]->tex->id, false);
adt = BKE_animdata_from_id(&ma->id);
if (adt) BKE_animdata_make_local(adt);
@@ -1958,7 +1961,7 @@ static int make_local_exec(bContext *C, wmOperator *op)
int a, b, mode = RNA_enum_get(op->ptr, "type");
if (mode == MAKE_LOCAL_ALL) {
- BKE_library_make_local(bmain, NULL, 0); /* NULL is all libs */
+ BKE_library_make_local(bmain, NULL, false); /* NULL is all libs */
WM_event_add_notifier(C, NC_WINDOW, NULL);
return OPERATOR_FINISHED;
}
@@ -1968,7 +1971,7 @@ static int make_local_exec(bContext *C, wmOperator *op)
CTX_DATA_BEGIN (C, Object *, ob, selected_objects)
{
if (ob->id.lib)
- id_make_local(&ob->id, 0);
+ id_make_local(&ob->id, false);
}
CTX_DATA_END;
@@ -1986,7 +1989,7 @@ static int make_local_exec(bContext *C, wmOperator *op)
id = ob->data;
if (id && (ELEM(mode, MAKE_LOCAL_SELECT_OBDATA, MAKE_LOCAL_SELECT_OBDATA_MATERIAL))) {
- id_make_local(id, 0);
+ id_make_local(id, false);
adt = BKE_animdata_from_id(id);
if (adt) BKE_animdata_make_local(adt);
@@ -2002,7 +2005,7 @@ static int make_local_exec(bContext *C, wmOperator *op)
}
for (psys = ob->particlesystem.first; psys; psys = psys->next)
- id_make_local(&psys->part->id, 0);
+ id_make_local(&psys->part->id, false);
adt = BKE_animdata_from_id(&ob->id);
if (adt) BKE_animdata_make_local(adt);
@@ -2017,7 +2020,7 @@ static int make_local_exec(bContext *C, wmOperator *op)
for (b = 0; b < MAX_MTEX; b++)
if (la->mtex[b] && la->mtex[b]->tex)
- id_make_local(&la->mtex[b]->tex->id, 0);
+ id_make_local(&la->mtex[b]->tex->id, false);
}
else {
for (a = 0; a < ob->totcol; a++) {
@@ -2130,7 +2133,7 @@ void OBJECT_OT_make_single_user(wmOperatorType *ot)
RNA_def_boolean(ot->srna, "animation", 0, "Object Animation", "Make animation data local to each object");
}
-static int drop_named_material_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int drop_named_material_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
Base *base = ED_view3d_give_base_under_cursor(C, event->mval);
Material *ma;
diff --git a/source/blender/editors/object/object_transform.c b/source/blender/editors/object/object_transform.c
index 3fa6c301fcb..80d494a6a07 100644
--- a/source/blender/editors/object/object_transform.c
+++ b/source/blender/editors/object/object_transform.c
@@ -795,8 +795,8 @@ static int object_origin_set_exec(bContext *C, wmOperator *op)
if (centermode == ORIGIN_TO_CURSOR) { /* done */ }
else if (centermode == ORIGIN_TO_CENTER_OF_MASS) { BKE_mesh_center_centroid(me, cent); }
- else if (around == V3D_CENTROID) { BKE_mesh_center_median(me, cent); }
- else { BKE_mesh_center_bounds(me, cent); }
+ else if (around == V3D_CENTROID) { BKE_mesh_center_median(me, cent); }
+ else { BKE_mesh_center_bounds(me, cent); }
negate_v3_v3(cent_neg, cent);
BKE_mesh_translate(me, cent_neg, 1);
@@ -808,9 +808,9 @@ static int object_origin_set_exec(bContext *C, wmOperator *op)
else if (ELEM(ob->type, OB_CURVE, OB_SURF)) {
Curve *cu = ob->data;
- if (centermode == ORIGIN_TO_CURSOR) { /* done */ }
+ if (centermode == ORIGIN_TO_CURSOR) { /* done */ }
else if (around == V3D_CENTROID) { BKE_curve_center_median(cu, cent); }
- else { BKE_curve_center_bounds(cu, cent); }
+ else { BKE_curve_center_bounds(cu, cent); }
/* don't allow Z change if curve is 2D */
if ((ob->type == OB_CURVE) && !(cu->flag & CU_3D))
@@ -889,9 +889,9 @@ static int object_origin_set_exec(bContext *C, wmOperator *op)
else if (ob->type == OB_MBALL) {
MetaBall *mb = ob->data;
- if (centermode == ORIGIN_TO_CURSOR) { /* done */ }
+ if (centermode == ORIGIN_TO_CURSOR) { /* done */ }
else if (around == V3D_CENTROID) { BKE_mball_center_median(mb, cent); }
- else { BKE_mball_center_bounds(mb, cent); }
+ else { BKE_mball_center_bounds(mb, cent); }
negate_v3_v3(cent_neg, cent);
BKE_mball_translate(mb, cent_neg);
@@ -910,9 +910,9 @@ static int object_origin_set_exec(bContext *C, wmOperator *op)
else if (ob->type == OB_LATTICE) {
Lattice *lt = ob->data;
- if (centermode == ORIGIN_TO_CURSOR) { /* done */ }
+ if (centermode == ORIGIN_TO_CURSOR) { /* done */ }
else if (around == V3D_CENTROID) { BKE_lattice_center_median(lt, cent); }
- else { BKE_lattice_center_bounds(lt, cent); }
+ else { BKE_lattice_center_bounds(lt, cent); }
negate_v3_v3(cent_neg, cent);
BKE_lattice_translate(lt, cent_neg, 1);
diff --git a/source/blender/editors/object/object_vgroup.c b/source/blender/editors/object/object_vgroup.c
index ef882b2486b..5abbb7124c0 100644
--- a/source/blender/editors/object/object_vgroup.c
+++ b/source/blender/editors/object/object_vgroup.c
@@ -1037,7 +1037,7 @@ static void vgroup_duplicate(Object *ob)
BLI_snprintf(name, sizeof(name), "%s_copy", dg->name);
}
else {
- BLI_snprintf(name, sizeof(name), "%s", dg->name);
+ BLI_strncpy(name, dg->name, sizeof(name));
}
cdg = defgroup_duplicate(dg);
diff --git a/source/blender/editors/physics/particle_edit.c b/source/blender/editors/physics/particle_edit.c
index 31079de275e..329f1f67c4a 100644
--- a/source/blender/editors/physics/particle_edit.c
+++ b/source/blender/editors/physics/particle_edit.c
@@ -430,15 +430,6 @@ static int key_test_depth(PEData *data, const float co[3], const int screen_co[2
gluProject(co[0], co[1], co[2], data->mats.modelview, data->mats.projection,
(GLint *)data->mats.viewport, &ux, &uy, &uz);
-#if 0 /* works well but too slow on some systems [#23118] */
- screen_co[0] += (short)data->vc.ar->winrct.xmin;
- screen_co[1] += (short)data->vc.ar->winrct.ymin;
-
- /* PE_set_view3d_data calls this. no need to call here */
- /* view3d_validate_backbuf(&data->vc); */
- glReadPixels(screen_co[0], screen_co[1], 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &depth);
-#else /* faster to use depths, these are calculated in PE_set_view3d_data */
-
/* check if screen_co is within bounds because brush_cut uses out of screen coords */
if (screen_co[0] >= 0 && screen_co[0] < vd->w && screen_co[1] >= 0 && screen_co[1] < vd->h) {
BLI_assert(vd && vd->depths);
@@ -447,7 +438,6 @@ static int key_test_depth(PEData *data, const float co[3], const int screen_co[2
}
else
return 0;
-#endif
if ((float)uz - 0.00001f > depth)
return 0;
@@ -1555,7 +1545,7 @@ static int select_linked_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int select_linked_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int select_linked_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
RNA_int_set_array(op->ptr, "location", event->mval);
return select_linked_exec(C, op);
@@ -3476,6 +3466,7 @@ typedef struct BrushEdit {
int first;
int lastmouse[2];
+ float zfac;
/* optional cached view settings to avoid setting on every mousemove */
PEData data;
@@ -3498,7 +3489,6 @@ static int brush_edit_init(bContext *C, wmOperator *op)
INIT_MINMAX(min, max);
PE_minmax(scene, min, max);
mid_v3_v3v3(min, min, max);
- initgrabz(ar->regiondata, min[0], min[1], min[2]);
bedit= MEM_callocN(sizeof(BrushEdit), "BrushEdit");
bedit->first= 1;
@@ -3508,6 +3498,8 @@ static int brush_edit_init(bContext *C, wmOperator *op)
bedit->ob= ob;
bedit->edit= edit;
+ bedit->zfac = ED_view3d_calc_zfac(ar->regiondata, min, NULL);
+
/* cache view depths and settings for re-use */
PE_set_view3d_data(C, &bedit->data);
@@ -3587,7 +3579,7 @@ static void brush_edit_apply(bContext *C, wmOperator *op, PointerRNA *itemptr)
invert_m4_m4(ob->imat, ob->obmat);
- ED_view3d_win_to_delta(ar, mval_f, vec);
+ ED_view3d_win_to_delta(ar, mval_f, vec, bedit->zfac);
data.dvec= vec;
foreach_mouse_hit_key(&data, brush_comb, selected);
@@ -3757,7 +3749,7 @@ static int brush_edit_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static void brush_edit_apply_event(bContext *C, wmOperator *op, wmEvent *event)
+static void brush_edit_apply_event(bContext *C, wmOperator *op, const wmEvent *event)
{
PointerRNA itemptr;
float mouse[2];
@@ -3774,7 +3766,7 @@ static void brush_edit_apply_event(bContext *C, wmOperator *op, wmEvent *event)
brush_edit_apply(C, op, &itemptr);
}
-static int brush_edit_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int brush_edit_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
if (!brush_edit_init(C, op))
return OPERATOR_CANCELLED;
@@ -3786,7 +3778,7 @@ static int brush_edit_invoke(bContext *C, wmOperator *op, wmEvent *event)
return OPERATOR_RUNNING_MODAL;
}
-static int brush_edit_modal(bContext *C, wmOperator *op, wmEvent *event)
+static int brush_edit_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
switch (event->type) {
case LEFTMOUSE:
diff --git a/source/blender/editors/physics/physics_fluid.c b/source/blender/editors/physics/physics_fluid.c
index fc55b2b5915..df723b06259 100644
--- a/source/blender/editors/physics/physics_fluid.c
+++ b/source/blender/editors/physics/physics_fluid.c
@@ -679,18 +679,15 @@ static int fluid_init_filepaths(Object *fsDomain, char *targetDir, char *targetF
if (fileCfg) {
dirExist = 1; fclose(fileCfg);
// remove cfg dummy from directory test
- BLI_delete(targetFile, 0, 0);
+ BLI_delete(targetFile, false, false);
}
if (targetDir[0] == '\0' || (!dirExist)) {
- char blendDir[FILE_MAX];
char blendFile[FILE_MAX];
// invalid dir, reset to current/previous
- BLI_strncpy(blendDir, G.main->name, FILE_MAX);
- BLI_splitdirstring(blendDir, blendFile);
+ BLI_split_file_part(G.main->name, blendFile, sizeof(blendFile));
BLI_replace_extension(blendFile, FILE_MAX, ""); /* strip .blend */
-
BLI_snprintf(newSurfdataPath, FILE_MAX, "//fluidsimdata/%s_%s_", blendFile, fsDomain->id.name);
BLI_snprintf(debugStrBuffer, 256, "fluidsimBake::error - warning resetting output dir to '%s'\n", newSurfdataPath);
@@ -852,9 +849,9 @@ static void fluidsim_delete_until_lastframe(FluidsimSettings *fss, const char *r
curFrame++;
if ((exists = BLI_exists(targetFile))) {
- BLI_delete(targetFile, 0, 0);
- BLI_delete(targetFileVel, 0, 0);
- BLI_delete(previewFile, 0, 0);
+ BLI_delete(targetFile, false, false);
+ BLI_delete(targetFileVel, false, false);
+ BLI_delete(previewFile, false, false);
}
} while (exists);
@@ -1130,7 +1127,7 @@ static int fluidsimBake(bContext *UNUSED(C), ReportList *UNUSED(reports), Object
/***************************** Operators ******************************/
-static int fluid_bake_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int fluid_bake_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
/* only one bake job at a time */
if (WM_jobs_test(CTX_wm_manager(C), CTX_data_scene(C), WM_JOB_TYPE_OBJECT_SIM_FLUID))
diff --git a/source/blender/editors/physics/physics_ops.c b/source/blender/editors/physics/physics_ops.c
index 51a66886c6e..2ede7047b74 100644
--- a/source/blender/editors/physics/physics_ops.c
+++ b/source/blender/editors/physics/physics_ops.c
@@ -27,9 +27,9 @@
* \ingroup edphys
*/
-
#include <stdlib.h>
+#include "BLI_utildefines.h"
#include "RNA_access.h"
@@ -39,8 +39,6 @@
#include "ED_physics.h"
#include "ED_object.h"
-#include "BLI_utildefines.h"
-
#include "physics_intern.h" // own include
diff --git a/source/blender/editors/physics/rigidbody_object.c b/source/blender/editors/physics/rigidbody_object.c
index 6bcdf6e07aa..9c03c6173a5 100644
--- a/source/blender/editors/physics/rigidbody_object.c
+++ b/source/blender/editors/physics/rigidbody_object.c
@@ -44,6 +44,8 @@
#include "BLI_blenlib.h"
#include "BLI_math.h"
+#include "BLF_translation.h"
+
#include "BKE_context.h"
#include "BKE_depsgraph.h"
#include "BKE_global.h"
@@ -374,61 +376,61 @@ typedef struct rbMaterialDensityItem {
* 3) http://www.avlandesign.com/density_metal.htm
*/
static rbMaterialDensityItem RB_MATERIAL_DENSITY_TABLE[] = {
- {"Air", 1.0f}, /* not quite; adapted from 1.43 for oxygen for use as default */
- {"Acrylic", 1400.0f},
- {"Asphalt (Crushed)", 721.0f},
- {"Bark", 240.0f},
- {"Beans (Cocoa)", 593.0f},
- {"Beans (Soy)", 721.0f},
- {"Brick (Pressed)", 2400.0f},
- {"Brick (Common)", 2000.0f},
- {"Brick (Soft)", 1600.0f},
- {"Brass", 8216.0f},
- {"Bronze", 8860.0f},
- {"Carbon (Solid)", 2146.0f},
- {"Cardboard", 689.0f},
- {"Cast Iron", 7150.0f},
- //{"Cement", 1442.0f},
- {"Chalk (Solid)", 2499.0f},
- //{"Coffee (Fresh/Roast)", ~500},
- {"Concrete", 2320.0f},
- {"Charcoal", 208.0f},
- {"Cork", 240.0f},
- {"Copper", 8933.0f},
- {"Garbage", 481.0f},
- {"Glass (Broken)", 1940.0f},
- {"Glass (Solid)", 2190.0f},
- {"Gold", 19282.0f},
- {"Granite (Broken)", 1650.0f},
- {"Granite (Solid)", 2691.0f},
- {"Gravel", 2780.0f},
- {"Ice (Crushed)", 593.0f},
- {"Ice (Solid)", 919.0f},
- {"Iron", 7874.0f},
- {"Lead", 11342.0f},
- {"Limestone (Broken)", 1554.0f},
- {"Limestone (Solid)", 2611.0f},
- {"Marble (Broken)", 1570.0f},
- {"Marble (Solid)", 2563.0f},
- {"Paper", 1201.0f},
- {"Peanuts (Shelled)", 641.0f},
- {"Peanuts (Not Shelled)", 272.0f},
- {"Plaster", 849.0f},
- {"Plastic", 1200.0f},
- {"Polystyrene", 1050.0f},
- {"Rubber", 1522.0f},
- {"Silver", 10501.0f},
- {"Steel", 7860.0f},
- {"Stone", 2515.0f},
- {"Stone (Crushed)", 1602.0f},
- {"Timber", 610.0f}
+ {N_("Air"), 1.0f}, /* not quite; adapted from 1.43 for oxygen for use as default */
+ {N_("Acrylic"), 1400.0f},
+ {N_("Asphalt (Crushed)"), 721.0f},
+ {N_("Bark"), 240.0f},
+ {N_("Beans (Cocoa)"), 593.0f},
+ {N_("Beans (Soy)"), 721.0f},
+ {N_("Brick (Pressed)"), 2400.0f},
+ {N_("Brick (Common)"), 2000.0f},
+ {N_("Brick (Soft)"), 1600.0f},
+ {N_("Brass"), 8216.0f},
+ {N_("Bronze"), 8860.0f},
+ {N_("Carbon (Solid)"), 2146.0f},
+ {N_("Cardboard"), 689.0f},
+ {N_("Cast Iron"), 7150.0f},
+ /* {N_("Cement"), 1442.0f}, */
+ {N_("Chalk (Solid)"), 2499.0f},
+ /* {N_("Coffee (Fresh/Roast)"), ~500}, */
+ {N_("Concrete"), 2320.0f},
+ {N_("Charcoal"), 208.0f},
+ {N_("Cork"), 240.0f},
+ {N_("Copper"), 8933.0f},
+ {N_("Garbage"), 481.0f},
+ {N_("Glass (Broken)"), 1940.0f},
+ {N_("Glass (Solid)"), 2190.0f},
+ {N_("Gold"), 19282.0f},
+ {N_("Granite (Broken)"), 1650.0f},
+ {N_("Granite (Solid)"), 2691.0f},
+ {N_("Gravel"), 2780.0f},
+ {N_("Ice (Crushed)"), 593.0f},
+ {N_("Ice (Solid)"), 919.0f},
+ {N_("Iron"), 7874.0f},
+ {N_("Lead"), 11342.0f},
+ {N_("Limestone (Broken)"), 1554.0f},
+ {N_("Limestone (Solid)"), 2611.0f},
+ {N_("Marble (Broken)"), 1570.0f},
+ {N_("Marble (Solid)"), 2563.0f},
+ {N_("Paper"), 1201.0f},
+ {N_("Peanuts (Shelled)"), 641.0f},
+ {N_("Peanuts (Not Shelled)"), 272.0f},
+ {N_("Plaster"), 849.0f},
+ {N_("Plastic"), 1200.0f},
+ {N_("Polystyrene"), 1050.0f},
+ {N_("Rubber"), 1522.0f},
+ {N_("Silver"), 10501.0f},
+ {N_("Steel"), 7860.0f},
+ {N_("Stone"), 2515.0f},
+ {N_("Stone (Crushed)"), 1602.0f},
+ {N_("Timber"), 610.0f}
};
static const int NUM_RB_MATERIAL_PRESETS = sizeof(RB_MATERIAL_DENSITY_TABLE) / sizeof(rbMaterialDensityItem);
/* dynamically generate list of items
* - Although there is a runtime cost, this has a lower maintenance cost
- * in the long run than other two-list solutions...
+ * in the long run than other two-list solutions...
*/
static EnumPropertyItem *rigidbody_materials_itemf(bContext *UNUSED(C), PointerRNA *UNUSED(ptr), PropertyRNA *UNUSED(prop), int *free)
{
@@ -441,14 +443,16 @@ static EnumPropertyItem *rigidbody_materials_itemf(bContext *UNUSED(C), PointerR
for (i = 0; i < NUM_RB_MATERIAL_PRESETS; i++) {
rbMaterialDensityItem *preset = &RB_MATERIAL_DENSITY_TABLE[i];
- item_tmp.identifier = item_tmp.name = preset->name;
+ item_tmp.identifier = preset->name;
+ item_tmp.name = IFACE_(preset->name);
item_tmp.value = i;
RNA_enum_item_add(&item, &totitem, &item_tmp);
}
/* add special "custom" entry to the end of the list */
{
- item_tmp.identifier = item_tmp.name = "Custom";
+ item_tmp.identifier = "Custom";
+ item_tmp.name = IFACE_("Custom");
item_tmp.value = -1;
RNA_enum_item_add(&item, &totitem, &item_tmp);
}
diff --git a/source/blender/editors/physics/rigidbody_world.c b/source/blender/editors/physics/rigidbody_world.c
index babe32c74b2..b7430cb8a95 100644
--- a/source/blender/editors/physics/rigidbody_world.c
+++ b/source/blender/editors/physics/rigidbody_world.c
@@ -175,7 +175,7 @@ static int rigidbody_world_export_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int rigidbody_world_export_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(evt))
+static int rigidbody_world_export_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
if (!RNA_struct_property_is_set(op->ptr, "relative_path"))
RNA_boolean_set(op->ptr, "relative_path", (U.flag & USER_RELPATHS));
diff --git a/source/blender/editors/render/SConscript b/source/blender/editors/render/SConscript
index 9d1de2fc700..25af8080d51 100644
--- a/source/blender/editors/render/SConscript
+++ b/source/blender/editors/render/SConscript
@@ -33,7 +33,7 @@ incs = '../include ../../blenlib ../../blenkernel ../../makesdna ../../imbuf'
incs += ' ../../windowmanager #/intern/guardedalloc #/extern/glew/include'
incs += ' ../../gpu'
incs += ' ../../makesrna ../../render/extern/include #/intern/elbeem/extern'
-incs += ' ../../blenloader ../../bmesh'
+incs += ' ../../blenloader ../../bmesh ../../blenfont'
if env['OURPLATFORM'] == 'linux':
cflags='-pthread'
diff --git a/source/blender/editors/render/render_internal.c b/source/blender/editors/render/render_internal.c
index deb6eaf2c22..b138bc63a68 100644
--- a/source/blender/editors/render/render_internal.c
+++ b/source/blender/editors/render/render_internal.c
@@ -39,6 +39,8 @@
#include "BLI_rand.h"
#include "BLI_utildefines.h"
+#include "BLF_translation.h"
+
#include "DNA_scene_types.h"
#include "BKE_blender.h"
@@ -281,38 +283,39 @@ static void make_renderinfo_string(RenderStats *rs, Scene *scene, char *str)
megs_peak_memory = (peak_memory) / (1024.0 * 1024.0);
if (scene->lay & 0xFF000000)
- spos += sprintf(spos, "Localview | ");
+ spos += sprintf(spos, IFACE_("Localview | "));
else if (scene->r.scemode & R_SINGLE_LAYER)
- spos += sprintf(spos, "Single Layer | ");
+ spos += sprintf(spos, IFACE_("Single Layer | "));
- spos += sprintf(spos, "Frame:%d ", (scene->r.cfra));
+ spos += sprintf(spos, IFACE_("Frame:%d "), (scene->r.cfra));
if (rs->statstr) {
spos += sprintf(spos, "| %s ", rs->statstr);
}
else {
- if (rs->totvert) spos += sprintf(spos, "Ve:%d ", rs->totvert);
- if (rs->totface) spos += sprintf(spos, "Fa:%d ", rs->totface);
- if (rs->tothalo) spos += sprintf(spos, "Ha:%d ", rs->tothalo);
- if (rs->totstrand) spos += sprintf(spos, "St:%d ", rs->totstrand);
- if (rs->totlamp) spos += sprintf(spos, "La:%d ", rs->totlamp);
+ if (rs->totvert) spos += sprintf(spos, IFACE_("Ve:%d "), rs->totvert);
+ if (rs->totface) spos += sprintf(spos, IFACE_("Fa:%d "), rs->totface);
+ if (rs->tothalo) spos += sprintf(spos, IFACE_("Ha:%d "), rs->tothalo);
+ if (rs->totstrand) spos += sprintf(spos, IFACE_("St:%d "), rs->totstrand);
+ if (rs->totlamp) spos += sprintf(spos, IFACE_("La:%d "), rs->totlamp);
if (rs->mem_peak == 0.0f)
- spos += sprintf(spos, "Mem:%.2fM (%.2fM, peak %.2fM) ", megs_used_memory, mmap_used_memory, megs_peak_memory);
+ spos += sprintf(spos, IFACE_("Mem:%.2fM (%.2fM, Peak %.2fM) "),
+ megs_used_memory, mmap_used_memory, megs_peak_memory);
else
- spos += sprintf(spos, "Mem:%.2fM, Peak: %.2fM ", rs->mem_used, rs->mem_peak);
+ spos += sprintf(spos, IFACE_("Mem:%.2fM, Peak: %.2fM "), rs->mem_used, rs->mem_peak);
if (rs->curfield)
- spos += sprintf(spos, "Field %d ", rs->curfield);
+ spos += sprintf(spos, IFACE_("Field %d "), rs->curfield);
if (rs->curblur)
- spos += sprintf(spos, "Blur %d ", rs->curblur);
+ spos += sprintf(spos, IFACE_("Blur %d "), rs->curblur);
}
BLI_timestr(rs->lastframetime, info_time_str);
- spos += sprintf(spos, "Time:%s ", info_time_str);
+ spos += sprintf(spos, IFACE_("Time:%s "), info_time_str);
if (rs->curfsa)
- spos += sprintf(spos, "| Full Sample %d ", rs->curfsa);
+ spos += sprintf(spos, IFACE_("| Full Sample %d "), rs->curfsa);
if (rs->infostr && rs->infostr[0])
spos += sprintf(spos, "| %s ", rs->infostr);
@@ -462,7 +465,7 @@ static void render_drawlock(void *UNUSED(rjv), int lock)
}
/* catch esc */
-static int screen_render_modal(bContext *C, wmOperator *op, wmEvent *event)
+static int screen_render_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
Scene *scene = (Scene *) op->customdata;
@@ -481,7 +484,7 @@ static int screen_render_modal(bContext *C, wmOperator *op, wmEvent *event)
}
/* using context, starts job */
-static int screen_render_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int screen_render_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
/* new render clears all callbacks */
Main *mainp;
diff --git a/source/blender/editors/render/render_opengl.c b/source/blender/editors/render/render_opengl.c
index ea18f2c8fbb..f47d737beca 100644
--- a/source/blender/editors/render/render_opengl.c
+++ b/source/blender/editors/render/render_opengl.c
@@ -638,7 +638,7 @@ static int screen_opengl_render_anim_step(bContext *C, wmOperator *op)
}
-static int screen_opengl_render_modal(bContext *C, wmOperator *op, wmEvent *event)
+static int screen_opengl_render_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
OGLRender *oglrender = op->customdata;
int anim = RNA_boolean_get(op->ptr, "animation");
@@ -677,7 +677,7 @@ static int screen_opengl_render_modal(bContext *C, wmOperator *op, wmEvent *even
return OPERATOR_RUNNING_MODAL;
}
-static int screen_opengl_render_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int screen_opengl_render_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
OGLRender *oglrender;
int anim = RNA_boolean_get(op->ptr, "animation");
diff --git a/source/blender/editors/render/render_preview.c b/source/blender/editors/render/render_preview.c
index dfc80e4cf51..7802e5460ff 100644
--- a/source/blender/editors/render/render_preview.c
+++ b/source/blender/editors/render/render_preview.c
@@ -110,7 +110,7 @@ ImBuf *get_brush_icon(Brush *brush)
static const int flags = IB_rect | IB_multilayer | IB_metadata;
char path[FILE_MAX];
- char *folder;
+ const char *folder;
if (!(brush->icon_imbuf)) {
if (brush->flag & BRUSH_CUSTOM_ICON) {
@@ -188,8 +188,8 @@ typedef struct IconPreview {
/* *************************** Preview for buttons *********************** */
-static Main *pr_main = NULL;
-static Main *pr_main_cycles = NULL;
+static Main *G_pr_main = NULL;
+static Main *G_pr_main_cycles = NULL;
#ifndef WITH_HEADLESS
static Main *load_main_from_memory(char *blend, int blend_size)
@@ -214,18 +214,18 @@ static Main *load_main_from_memory(char *blend, int blend_size)
void ED_preview_init_dbase(void)
{
#ifndef WITH_HEADLESS
- pr_main = load_main_from_memory(datatoc_preview_blend, datatoc_preview_blend_size);
- pr_main_cycles = load_main_from_memory(datatoc_preview_cycles_blend, datatoc_preview_cycles_blend_size);
+ G_pr_main = load_main_from_memory(datatoc_preview_blend, datatoc_preview_blend_size);
+ G_pr_main_cycles = load_main_from_memory(datatoc_preview_cycles_blend, datatoc_preview_cycles_blend_size);
#endif
}
void ED_preview_free_dbase(void)
{
- if (pr_main)
- free_main(pr_main);
+ if (G_pr_main)
+ free_main(G_pr_main);
- if (pr_main_cycles)
- free_main(pr_main_cycles);
+ if (G_pr_main_cycles)
+ free_main(G_pr_main_cycles);
}
static int preview_mat_has_sss(Material *mat, bNodeTree *ntree)
@@ -425,15 +425,16 @@ static Scene *preview_prepare_scene(Scene *scene, ID *id, int id_type, ShaderPre
if (tex && sp->slot)
mat->mtex[0]->which_output = sp->slot->which_output;
-
+
+ mat->mtex[0]->mapto &= ~MAP_ALPHA;
+ mat->alpha = 1.0f;
+
/* show alpha in this case */
if (tex == NULL || (tex->flag & TEX_PRV_ALPHA)) {
- mat->mtex[0]->mapto |= MAP_ALPHA;
- mat->alpha = 0.0f;
- }
- else {
- mat->mtex[0]->mapto &= ~MAP_ALPHA;
- mat->alpha = 1.0f;
+ if (!(tex && tex->type == TEX_IMAGE && (tex->imaflag & (TEX_USEALPHA | TEX_CALCALPHA)) == 0)) {
+ mat->mtex[0]->mapto |= MAP_ALPHA;
+ mat->alpha = 0.0f;
+ }
}
}
}
@@ -670,8 +671,10 @@ static void shader_preview_render(ShaderPreview *sp, ID *id, int split, int firs
if (first) sizex = sp->sizex / 2;
else sizex = sp->sizex - sp->sizex / 2;
}
- else sizex = sp->sizex;
-
+ else {
+ sizex = sp->sizex;
+ }
+
/* we have to set preview variables first */
sce = preview_get_scene(pr_main);
if (sce) {
@@ -1025,7 +1028,7 @@ static void icon_preview_startjob_all_sizes(void *customdata, short *stop, short
sp->pr_method = PR_ICON_RENDER;
sp->pr_rect = cur_size->rect;
sp->id = ip->id;
- sp->pr_main = pr_main;
+ sp->pr_main = G_pr_main;
common_preview_startjob(sp, stop, do_update, progress);
shader_preview_free(sp);
@@ -1128,9 +1131,9 @@ void ED_preview_shader_job(const bContext *C, void *owner, ID *id, ID *parent, M
/* hardcoded preview .blend for cycles/internal, this should be solved
* once with custom preview .blend path for external engines */
if (BKE_scene_use_new_shading_nodes(scene))
- sp->pr_main = pr_main_cycles;
+ sp->pr_main = G_pr_main_cycles;
else
- sp->pr_main = pr_main;
+ sp->pr_main = G_pr_main;
if (ob && ob->totcol) copy_v4_v4(sp->col, ob->col);
else sp->col[0] = sp->col[1] = sp->col[2] = sp->col[3] = 1.0f;
diff --git a/source/blender/editors/render/render_shading.c b/source/blender/editors/render/render_shading.c
index aa1edb1c1b1..decc5b131ae 100644
--- a/source/blender/editors/render/render_shading.c
+++ b/source/blender/editors/render/render_shading.c
@@ -1327,7 +1327,7 @@ static int envmap_save_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int envmap_save_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int envmap_save_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
//Scene *scene= CTX_data_scene(C);
diff --git a/source/blender/editors/render/render_update.c b/source/blender/editors/render/render_update.c
index 16d7923baff..a467b053443 100644
--- a/source/blender/editors/render/render_update.c
+++ b/source/blender/editors/render/render_update.c
@@ -394,8 +394,6 @@ static void texture_changed(Main *bmain, Tex *tex)
if (dm && totmaterial && material) {
for (a = 0; a < *totmaterial; a++) {
- Material *ma;
-
if (ob->matbits && ob->matbits[a])
ma = ob->mat[a];
else
diff --git a/source/blender/editors/render/render_view.c b/source/blender/editors/render/render_view.c
index 8b2ac740e47..186d0d20623 100644
--- a/source/blender/editors/render/render_view.c
+++ b/source/blender/editors/render/render_view.c
@@ -275,7 +275,7 @@ void RENDER_OT_view_cancel(struct wmOperatorType *ot)
/************************* show render viewer *****************/
-static int render_view_show_invoke(bContext *C, wmOperator *UNUSED(op), wmEvent *event)
+static int render_view_show_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *event)
{
wmWindow *wincur = CTX_wm_window(C);
diff --git a/source/blender/editors/screen/area.c b/source/blender/editors/screen/area.c
index 1b7cd4a6d20..2d6e8d0ada0 100644
--- a/source/blender/editors/screen/area.c
+++ b/source/blender/editors/screen/area.c
@@ -67,6 +67,8 @@
#include "screen_intern.h"
+extern void ui_draw_anti_tria(float x1, float y1, float x2, float y2, float x3, float y3); /* xxx temp */
+
/* general area and region code */
static void region_draw_emboss(ARegion *ar, rcti *scirct)
@@ -245,8 +247,6 @@ static void draw_azone_plus(float x1, float y1, float x2, float y2)
static void region_draw_azone_tab_plus(AZone *az)
{
- extern void ui_draw_anti_tria(float x1, float y1, float x2, float y2, float x3, float y3); /* xxx temp */
-
glEnable(GL_BLEND);
/* add code to draw region hidden as 'too small' */
@@ -321,8 +321,6 @@ static void region_draw_azone_tab(AZone *az)
static void region_draw_azone_tria(AZone *az)
{
- extern void ui_draw_anti_tria(float x1, float y1, float x2, float y2, float x3, float y3); /* xxx temp */
-
glEnable(GL_BLEND);
//UI_GetThemeColor3fv(TH_HEADER, col);
glColor4f(0.0f, 0.0f, 0.0f, 0.35f);
@@ -590,7 +588,7 @@ 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 (0.2f * U.widget_unit)
+#define AZONEPAD_EDGE (0.1f * U.widget_unit)
#define AZONEPAD_ICON (0.45f * U.widget_unit)
static void region_azone_edge(AZone *az, ARegion *ar)
{
@@ -599,22 +597,22 @@ static void region_azone_edge(AZone *az, ARegion *ar)
az->x1 = ar->winrct.xmin;
az->y1 = ar->winrct.ymax - AZONEPAD_EDGE;
az->x2 = ar->winrct.xmax;
- az->y2 = ar->winrct.ymax;
+ az->y2 = ar->winrct.ymax + AZONEPAD_EDGE;
break;
case AE_BOTTOM_TO_TOPLEFT:
az->x1 = ar->winrct.xmin;
az->y1 = ar->winrct.ymin + AZONEPAD_EDGE;
az->x2 = ar->winrct.xmax;
- az->y2 = ar->winrct.ymin;
+ az->y2 = ar->winrct.ymin - AZONEPAD_EDGE;
break;
case AE_LEFT_TO_TOPRIGHT:
- az->x1 = ar->winrct.xmin;
+ az->x1 = ar->winrct.xmin - AZONEPAD_EDGE;
az->y1 = ar->winrct.ymin;
az->x2 = ar->winrct.xmin + AZONEPAD_EDGE;
az->y2 = ar->winrct.ymax;
break;
case AE_RIGHT_TO_TOPLEFT:
- az->x1 = ar->winrct.xmax;
+ az->x1 = ar->winrct.xmax + AZONEPAD_EDGE;
az->y1 = ar->winrct.ymin;
az->x2 = ar->winrct.xmax - AZONEPAD_EDGE;
az->y2 = ar->winrct.ymax;
@@ -1071,7 +1069,9 @@ static void region_rect_recursive(wmWindow *win, ScrArea *sa, ARegion *ar, rcti
if (G.debug & G_DEBUG)
printf("region quadsplit failed\n");
}
- else quad = 1;
+ else {
+ quad = 1;
+ }
}
if (quad) {
if (quad == 1) { /* left bottom */
@@ -1746,7 +1746,9 @@ void ED_region_panels(const bContext *C, ARegion *ar, int vertical, const char *
/* uiScalePanels(ar, BLI_rctf_size_x(&v2d->cur));
break; */
}
- else break;
+ else {
+ break;
+ }
}
diff --git a/source/blender/editors/screen/glutil.c b/source/blender/editors/screen/glutil.c
index 105c2dc88d1..8501b53afae 100644
--- a/source/blender/editors/screen/glutil.c
+++ b/source/blender/editors/screen/glutil.c
@@ -482,7 +482,7 @@ static int get_cached_work_texture(int *w_r, int *h_r)
return texid;
}
-void glaDrawPixelsTexScaled(float x, float y, int img_w, int img_h, int format, void *rect, float scaleX, float scaleY)
+void glaDrawPixelsTexScaled(float x, float y, int img_w, int img_h, int format, int zoomfilter, void *rect, float scaleX, float scaleY)
{
unsigned char *uc_rect = (unsigned char *) rect;
float *f_rect = (float *)rect;
@@ -503,6 +503,7 @@ void glaDrawPixelsTexScaled(float x, float y, int img_w, int img_h, int format,
/* don't want nasty border artifacts */
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, zoomfilter);
#ifdef __APPLE__
/* workaround for os x 10.5/10.6 driver bug: http://lists.apple.com/archives/Mac-opengl/2008/Jul/msg00117.html */
@@ -560,10 +561,10 @@ void glaDrawPixelsTexScaled(float x, float y, int img_w, int img_h, int format,
glEnable(GL_TEXTURE_2D);
glBegin(GL_QUADS);
glTexCoord2f((float)(0 + offset_left) / tex_w, (float)(0 + offset_bot) / tex_h);
- glVertex2f(rast_x + (float)offset_left * xzoom, rast_y + (float)offset_bot * xzoom);
+ glVertex2f(rast_x + (float)offset_left * xzoom, rast_y + (float)offset_bot * yzoom);
glTexCoord2f((float)(subpart_w - offset_right) / tex_w, (float)(0 + offset_bot) / tex_h);
- glVertex2f(rast_x + (float)(subpart_w - offset_right) * xzoom * scaleX, rast_y + (float)offset_bot * xzoom);
+ glVertex2f(rast_x + (float)(subpart_w - offset_right) * xzoom * scaleX, rast_y + (float)offset_bot * yzoom);
glTexCoord2f((float)(subpart_w - offset_right) / tex_w, (float)(subpart_h - offset_top) / tex_h);
glVertex2f(rast_x + (float)(subpart_w - offset_right) * xzoom * scaleX, rast_y + (float)(subpart_h - offset_top) * yzoom * scaleY);
@@ -585,9 +586,9 @@ void glaDrawPixelsTexScaled(float x, float y, int img_w, int img_h, int format,
#endif
}
-void glaDrawPixelsTex(float x, float y, int img_w, int img_h, int format, void *rect)
+void glaDrawPixelsTex(float x, float y, int img_w, int img_h, int format, int zoomfilter, void *rect)
{
- glaDrawPixelsTexScaled(x, y, img_w, img_h, format, rect, 1.0f, 1.0f);
+ glaDrawPixelsTexScaled(x, y, img_w, img_h, format, zoomfilter, rect, 1.0f, 1.0f);
}
void glaDrawPixelsSafe(float x, float y, int img_w, int img_h, int row_w, int format, int type, void *rect)
@@ -669,6 +670,22 @@ void glaDrawPixelsSafe(float x, float y, int img_w, int img_h, int row_w, int fo
}
}
+/* uses either DrawPixelsSafe or DrawPixelsTex, based on user defined maximum */
+void glaDrawPixelsAuto(float x, float y, int img_w, int img_h, int format, int zoomfilter, void *rect)
+{
+ if (U.image_gpubuffer_limit) {
+ /* Megapixels, use float math to prevent overflow */
+ float img_size = ((float)img_w * (float)img_h) / (1024.0f * 1024.0f);
+
+ if (U.image_gpubuffer_limit > (int)img_size) {
+ glColor4f(1.0, 1.0, 1.0, 1.0);
+ glaDrawPixelsTex(x, y, img_w, img_h, format, zoomfilter, rect);
+ return;
+ }
+ }
+ glaDrawPixelsSafe(x, y, img_w, img_h, img_w, GL_RGBA, format, rect);
+}
+
/* 2D Drawing Assistance */
void glaDefine2DArea(rcti *screen_rect)
@@ -807,7 +824,9 @@ void bglBegin(int mode)
pointhack = floor(value[0] + 0.5f);
if (pointhack > 4) pointhack = 4;
}
- else glBegin(mode);
+ else {
+ glBegin(mode);
+ }
}
}
@@ -835,7 +854,9 @@ void bglVertex3fv(const float vec[3])
glRasterPos3fv(vec);
glBitmap(pointhack, pointhack, (float)pointhack / 2.0f, (float)pointhack / 2.0f, 0.0, 0.0, Squaredot);
}
- else glVertex3fv(vec);
+ else {
+ glVertex3fv(vec);
+ }
break;
}
}
@@ -848,7 +869,9 @@ void bglVertex3f(float x, float y, float z)
glRasterPos3f(x, y, z);
glBitmap(pointhack, pointhack, (float)pointhack / 2.0f, (float)pointhack / 2.0f, 0.0, 0.0, Squaredot);
}
- else glVertex3f(x, y, z);
+ else {
+ glVertex3f(x, y, z);
+ }
break;
}
}
@@ -861,7 +884,9 @@ void bglVertex2fv(const float vec[2])
glRasterPos2fv(vec);
glBitmap(pointhack, pointhack, (float)pointhack / 2, pointhack / 2, 0.0, 0.0, Squaredot);
}
- else glVertex2fv(vec);
+ else {
+ glVertex2fv(vec);
+ }
break;
}
}
diff --git a/source/blender/editors/screen/screen_edit.c b/source/blender/editors/screen/screen_edit.c
index 7c22dff1b01..6045bdfebfe 100644
--- a/source/blender/editors/screen/screen_edit.c
+++ b/source/blender/editors/screen/screen_edit.c
@@ -194,7 +194,9 @@ void removenotused_scrverts(bScreen *sc)
BLI_remlink(&sc->vertbase, sv);
MEM_freeN(sv);
}
- else sv->flag = 0;
+ else {
+ sv->flag = 0;
+ }
sv = svn;
}
}
@@ -250,7 +252,9 @@ void removenotused_scredges(bScreen *sc)
BLI_remlink(&sc->edgebase, se);
MEM_freeN(se);
}
- else se->flag = 0;
+ else {
+ se->flag = 0;
+ }
se = sen;
}
}
@@ -1133,8 +1137,12 @@ void ED_screens_initialize(wmWindowManager *wm)
void ED_region_exit(bContext *C, ARegion *ar)
{
+ wmWindowManager *wm = CTX_wm_manager(C);
ARegion *prevar = CTX_wm_region(C);
+ if (ar->type && ar->type->exit)
+ ar->type->exit(wm, ar);
+
CTX_wm_region_set(C, ar);
WM_event_remove_handlers(C, &ar->handlers);
if (ar->swinid)
@@ -1153,18 +1161,12 @@ void ED_region_exit(bContext *C, ARegion *ar)
void ED_area_exit(bContext *C, ScrArea *sa)
{
+ wmWindowManager *wm = CTX_wm_manager(C);
ScrArea *prevsa = CTX_wm_area(C);
ARegion *ar;
- if (sa->spacetype == SPACE_FILE) {
- SpaceLink *sl = sa->spacedata.first;
- if (sl && sl->spacetype == SPACE_FILE) {
- ED_fileselect_exit(C, (SpaceFile *)sl);
- }
- }
- else if (sa->spacetype == SPACE_VIEW3D) {
- ED_render_engine_area_exit(sa);
- }
+ if (sa->type && sa->type->exit)
+ sa->type->exit(wm, sa);
CTX_wm_area_set(C, sa);
for (ar = sa->regionbase.first; ar; ar = ar->next)
diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c
index fcd0968d52f..1906a3259a9 100644
--- a/source/blender/editors/screen/screen_ops.c
+++ b/source/blender/editors/screen/screen_ops.c
@@ -644,7 +644,7 @@ static void actionzone_apply(bContext *C, wmOperator *op, int type)
wm_event_add(win, &event);
}
-static int actionzone_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int actionzone_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
AZone *az = is_in_area_actionzone(CTX_wm_area(C), &event->x);
sActionzoneData *sad;
@@ -674,7 +674,7 @@ static int actionzone_invoke(bContext *C, wmOperator *op, wmEvent *event)
}
-static int actionzone_modal(bContext *C, wmOperator *op, wmEvent *event)
+static int actionzone_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
sActionzoneData *sad = op->customdata;
int deltax, deltay;
@@ -769,7 +769,7 @@ typedef struct sAreaSwapData {
ScrArea *sa1, *sa2;
} sAreaSwapData;
-static int area_swap_init(wmOperator *op, wmEvent *event)
+static int area_swap_init(wmOperator *op, const wmEvent *event)
{
sAreaSwapData *sd = NULL;
sActionzoneData *sad = event->customdata;
@@ -800,7 +800,7 @@ static int area_swap_cancel(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
-static int area_swap_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int area_swap_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
if (!area_swap_init(op, event))
@@ -814,7 +814,7 @@ static int area_swap_invoke(bContext *C, wmOperator *op, wmEvent *event)
}
-static int area_swap_modal(bContext *C, wmOperator *op, wmEvent *event)
+static int area_swap_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
sActionzoneData *sad = op->customdata;
@@ -866,7 +866,7 @@ static void SCREEN_OT_area_swap(wmOperatorType *ot)
/* *********** Duplicate area as new window operator ****************** */
/* operator callback */
-static int area_dupli_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int area_dupli_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
wmWindow *newwin, *win;
bScreen *newsc, *sc;
@@ -1100,7 +1100,7 @@ static int area_move_exec(bContext *C, wmOperator *op)
}
/* interaction callback */
-static int area_move_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int area_move_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
RNA_int_set(op->ptr, "x", event->x);
RNA_int_set(op->ptr, "y", event->y);
@@ -1125,7 +1125,7 @@ static int area_move_cancel(bContext *C, wmOperator *op)
}
/* modal callback for while moving edges */
-static int area_move_modal(bContext *C, wmOperator *op, wmEvent *event)
+static int area_move_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
sAreaMoveData *md = op->customdata;
int delta, x, y;
@@ -1382,7 +1382,7 @@ static void area_split_exit(bContext *C, wmOperator *op)
/* UI callback, adds new handler */
-static int area_split_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int area_split_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
sAreaSplitData *sd;
int dir;
@@ -1514,7 +1514,7 @@ static int area_split_cancel(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
-static int area_split_modal(bContext *C, wmOperator *op, wmEvent *event)
+static int area_split_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
sAreaSplitData *sd = (sAreaSplitData *)op->customdata;
float fac;
@@ -1697,7 +1697,7 @@ static int area_max_regionsize(ScrArea *sa, ARegion *scalear, AZEdge edge)
return dist;
}
-static int region_scale_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int region_scale_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
sActionzoneData *sad = event->customdata;
AZone *az;
@@ -1795,7 +1795,7 @@ static void region_scale_toggle_hidden(bContext *C, RegionMoveData *rmd)
region_scale_validate_size(rmd);
}
-static int region_scale_modal(bContext *C, wmOperator *op, wmEvent *event)
+static int region_scale_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
RegionMoveData *rmd = op->customdata;
int delta;
@@ -2318,7 +2318,7 @@ static int area_join_exec(bContext *C, wmOperator *op)
}
/* interaction callback */
-static int area_join_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int area_join_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
if (event->type == EVT_ACTIONZONE_AREA) {
@@ -2374,7 +2374,7 @@ static int area_join_cancel(bContext *C, wmOperator *op)
}
/* modal callback while selecting area (space) that will be removed */
-static int area_join_modal(bContext *C, wmOperator *op, wmEvent *event)
+static int area_join_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
bScreen *sc = CTX_wm_screen(C);
sAreaJoinData *jd = (sAreaJoinData *)op->customdata;
@@ -2490,7 +2490,7 @@ static void SCREEN_OT_area_join(wmOperatorType *ot)
/* ******************************* */
-static int screen_area_options_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int screen_area_options_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
uiPopupMenu *pup;
uiLayout *layout;
@@ -2604,7 +2604,7 @@ static void SCREEN_OT_repeat_last(wmOperatorType *ot)
}
-static int repeat_history_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int repeat_history_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
wmWindowManager *wm = CTX_wm_manager(C);
wmOperator *lastop;
@@ -2661,7 +2661,7 @@ static void SCREEN_OT_repeat_history(wmOperatorType *ot)
/* ********************** redo operator ***************************** */
-static int redo_last_invoke(bContext *C, wmOperator *UNUSED(op), wmEvent *UNUSED(event))
+static int redo_last_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *UNUSED(event))
{
wmOperator *lastop = WM_operator_last_redo(C);
@@ -2958,7 +2958,7 @@ void ED_screens_header_tools_menu_create(bContext *C, uiLayout *layout, void *UN
}
}
-static int header_toolbox_invoke(bContext *C, wmOperator *UNUSED(op), wmEvent *UNUSED(event))
+static int header_toolbox_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *UNUSED(event))
{
uiPopupMenu *pup;
uiLayout *layout;
@@ -3071,7 +3071,7 @@ static int match_region_with_redraws(int spacetype, int regiontype, int redraws)
return 0;
}
-static int screen_animation_step(bContext *C, wmOperator *UNUSED(op), wmEvent *event)
+static int screen_animation_step(bContext *C, wmOperator *UNUSED(op), const wmEvent *event)
{
bScreen *screen = CTX_wm_screen(C);
@@ -3421,7 +3421,7 @@ static void SCREEN_OT_back_to_previous(struct wmOperatorType *ot)
/* *********** show user pref window ****** */
-static int userpref_show_invoke(bContext *C, wmOperator *UNUSED(op), wmEvent *event)
+static int userpref_show_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *event)
{
wmWindow *win = CTX_wm_window(C);
rcti rect;
@@ -3696,7 +3696,7 @@ void region_blend_start(bContext *C, ScrArea *sa, ARegion *ar)
}
/* 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)
+static int region_blend_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *event)
{
RegionAlphaInfo *rgi;
wmTimer *timer = event->customdata;
@@ -3820,7 +3820,7 @@ static void keymap_modal_set(wmKeyConfig *keyconf)
}
-static int open_file_drop_poll(bContext *UNUSED(C), wmDrag *drag, wmEvent *UNUSED(event))
+static int open_file_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUSED(event))
{
if (drag->type == WM_DRAG_PATH) {
if (drag->icon == ICON_FILE_BLEND)
diff --git a/source/blender/editors/screen/screendump.c b/source/blender/editors/screen/screendump.c
index 9cde62e8302..0fbb4c25e78 100644
--- a/source/blender/editors/screen/screendump.c
+++ b/source/blender/editors/screen/screendump.c
@@ -204,7 +204,7 @@ static int screenshot_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int screenshot_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int screenshot_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
if (screenshot_data_create(C, op)) {
if (RNA_struct_property_is_set(op->ptr, "filepath"))
diff --git a/source/blender/editors/sculpt_paint/CMakeLists.txt b/source/blender/editors/sculpt_paint/CMakeLists.txt
index 5bed31e2e52..0899fb97a2a 100644
--- a/source/blender/editors/sculpt_paint/CMakeLists.txt
+++ b/source/blender/editors/sculpt_paint/CMakeLists.txt
@@ -23,6 +23,7 @@ set(INC
../uvedit
../../blenkernel
../../blenlib
+ ../../blenfont
../../blenloader
../../bmesh
../../gpu
@@ -43,6 +44,7 @@ set(SRC
paint_hide.c
paint_image.c
paint_image_2d.c
+ paint_image_proj.c
paint_mask.c
paint_ops.c
paint_stroke.c
@@ -57,4 +59,8 @@ set(SRC
sculpt_intern.h
)
+if(WITH_INTERNATIONAL)
+ add_definitions(-DWITH_INTERNATIONAL)
+endif()
+
blender_add_lib(bf_editor_sculpt_paint "${SRC}" "${INC}" "${INC_SYS}")
diff --git a/source/blender/editors/sculpt_paint/SConscript b/source/blender/editors/sculpt_paint/SConscript
index 6767e06f65b..d10666de637 100644
--- a/source/blender/editors/sculpt_paint/SConscript
+++ b/source/blender/editors/sculpt_paint/SConscript
@@ -31,7 +31,7 @@ sources = env.Glob('*.c')
defs = []
-incs = '../include ../../blenlib ../../blenkernel ../../makesdna ../../imbuf'
+incs = '../include ../../blenlib ../../blenfont ../../blenkernel ../../makesdna ../../imbuf'
incs += ' ../../windowmanager #/intern/guardedalloc #/extern/glew/include'
incs += ' ../../render/extern/include'
incs += ' ../../gpu ../../makesrna ../../blenloader ../../bmesh ../uvedit'
@@ -47,4 +47,7 @@ if env['OURPLATFORM'] == 'linuxcross':
if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'linuxcross', 'win64-vc', 'win64-mingw'):
incs += ' ' + env['BF_PTHREADS_INC']
+if env['WITH_BF_INTERNATIONAL']:
+ defs.append('WITH_INTERNATIONAL')
+
env.BlenderLib ( 'bf_editors_sculpt_paint', sources, Split(incs), defines=defs, libtype=['core'], priority=[40] )
diff --git a/source/blender/editors/sculpt_paint/paint_cursor.c b/source/blender/editors/sculpt_paint/paint_cursor.c
index ffea5af74a3..8d9cbbbcf11 100644
--- a/source/blender/editors/sculpt_paint/paint_cursor.c
+++ b/source/blender/editors/sculpt_paint/paint_cursor.c
@@ -207,14 +207,14 @@ static int load_tex(Brush *br, ViewContext *vc)
x = (float)i / size;
y = (float)j / size;
- x -= 0.5f;
- y -= 0.5f;
-
if (br->mtex.brush_map_mode == MTEX_MAP_MODE_TILED) {
x *= vc->ar->winx / radius;
y *= vc->ar->winy / radius;
}
else {
+ x -= 0.5f;
+ y -= 0.5f;
+
x *= 2;
y *= 2;
}
@@ -345,14 +345,14 @@ static int sculpt_get_brush_geometry(bContext *C, ViewContext *vc,
{
Scene *scene = CTX_data_scene(C);
Paint *paint = paint_get_active_from_context(C);
- float window[2];
+ float mouse[2];
int hit;
- window[0] = x + vc->ar->winrct.xmin;
- window[1] = y + vc->ar->winrct.ymin;
+ mouse[0] = x;
+ mouse[1] = y;
if (vc->obact->sculpt && vc->obact->sculpt->pbvh &&
- sculpt_stroke_get_location(C, location, window))
+ sculpt_stroke_get_location(C, location, mouse))
{
Brush *brush = paint_brush(paint);
*pixel_radius =
@@ -420,8 +420,7 @@ static void paint_draw_alpha_overlay(UnifiedPaintSettings *ups, Brush *brush,
if (brush->mtex.brush_map_mode == MTEX_MAP_MODE_VIEW) {
/* brush rotation */
glTranslatef(0.5, 0.5, 0);
- glRotatef((double)RAD2DEGF((brush->flag & BRUSH_RAKE) ?
- ups->last_angle : ups->special_rotation),
+ glRotatef((double)RAD2DEGF(ups->brush_rotation),
0.0, 0.0, 1.0);
glTranslatef(-0.5f, -0.5f, 0);
@@ -434,11 +433,10 @@ static void paint_draw_alpha_overlay(UnifiedPaintSettings *ups, Brush *brush,
if (ups->draw_anchored) {
const float *aim = ups->anchored_initial_mouse;
- const rcti *win = &vc->ar->winrct;
- quad.xmin = aim[0] - ups->anchored_size - win->xmin;
- quad.ymin = aim[1] - ups->anchored_size - win->ymin;
- quad.xmax = aim[0] + ups->anchored_size - win->xmin;
- quad.ymax = aim[1] + ups->anchored_size - win->ymin;
+ quad.xmin = aim[0] - ups->anchored_size;
+ quad.ymin = aim[1] - ups->anchored_size;
+ quad.xmax = aim[0] + ups->anchored_size;
+ quad.ymax = aim[1] + ups->anchored_size;
}
else {
const int radius = BKE_brush_size_get(vc->scene, brush);
@@ -537,38 +535,22 @@ static void paint_draw_cursor(bContext *C, int x, int y, void *UNUSED(unused))
* mouse over too, not just during a stroke */
view3d_set_viewcontext(C, &vc);
+ if (brush->flag & BRUSH_RAKE)
+ /* here, translation contains the mouse coordinates. */
+ paint_calculate_rake_rotation(ups, translation);
+
+ /* draw overlay */
+ paint_draw_alpha_overlay(ups, brush, &vc, x, y);
+
/* TODO: as sculpt and other paint modes are unified, this
* special mode of drawing will go away */
if (vc.obact->sculpt) {
float location[3];
int pixel_radius, hit;
- /* this is probably here so that rake takes into
- * account the brush movements before the stroke
- * starts, but this doesn't really belong in draw code
- * TODO) */
- {
- const float u = 0.5f;
- const float v = 1 - u;
- const float r = 20;
-
- const float dx = ups->last_x - x;
- const float dy = ups->last_y - y;
-
- if (dx * dx + dy * dy >= r * r) {
- ups->last_angle = atan2(dx, dy);
-
- ups->last_x = u * ups->last_x + v * x;
- ups->last_y = u * ups->last_y + v * y;
- }
- }
-
/* test if brush is over the mesh */
hit = sculpt_get_brush_geometry(C, &vc, x, y, &pixel_radius, location);
- /* draw overlay */
- paint_draw_alpha_overlay(ups, brush, &vc, x, y);
-
if (BKE_brush_use_locked_size(scene, brush))
BKE_brush_size_set(scene, brush, pixel_radius);
@@ -590,8 +572,8 @@ static void paint_draw_cursor(bContext *C, int x, int y, void *UNUSED(unused))
if (ups->draw_anchored) {
final_radius = ups->anchored_size;
- translation[0] = ups->anchored_initial_mouse[0] - vc.ar->winrct.xmin;
- translation[1] = ups->anchored_initial_mouse[1] - vc.ar->winrct.ymin;
+ translation[0] = ups->anchored_initial_mouse[0];
+ translation[1] = ups->anchored_initial_mouse[1];
}
}
diff --git a/source/blender/editors/sculpt_paint/paint_hide.c b/source/blender/editors/sculpt_paint/paint_hide.c
index d50261a3b98..14eb358f20f 100644
--- a/source/blender/editors/sculpt_paint/paint_hide.c
+++ b/source/blender/editors/sculpt_paint/paint_hide.c
@@ -424,7 +424,7 @@ static int hide_show_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int hide_show_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int hide_show_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
PartialVisArea area = RNA_enum_get(op->ptr, "area");
diff --git a/source/blender/editors/sculpt_paint/paint_image.c b/source/blender/editors/sculpt_paint/paint_image.c
index edeb66d9281..144dfa948d0 100644
--- a/source/blender/editors/sculpt_paint/paint_image.c
+++ b/source/blender/editors/sculpt_paint/paint_image.c
@@ -101,298 +101,8 @@
#include "paint_intern.h"
-/* Defines and Structs */
-/* FTOCHAR as inline function */
-BLI_INLINE unsigned char f_to_char(const float val)
-{
- return FTOCHAR(val);
-}
-
-
-#define IMAPAINT_CHAR_TO_FLOAT(c) ((c) / 255.0f)
-
-#define IMAPAINT_FLOAT_RGB_TO_CHAR(c, f) { \
- (c)[0] = f_to_char((f)[0]); \
- (c)[1] = f_to_char((f)[1]); \
- (c)[2] = f_to_char((f)[2]); \
-} (void)0
-#define IMAPAINT_FLOAT_RGBA_TO_CHAR(c, f) { \
- (c)[0] = f_to_char((f)[0]); \
- (c)[1] = f_to_char((f)[1]); \
- (c)[2] = f_to_char((f)[2]); \
- (c)[3] = f_to_char((f)[3]); \
-} (void)0
-#define IMAPAINT_CHAR_RGB_TO_FLOAT(f, c) { \
- (f)[0] = IMAPAINT_CHAR_TO_FLOAT((c)[0]); \
- (f)[1] = IMAPAINT_CHAR_TO_FLOAT((c)[1]); \
- (f)[2] = IMAPAINT_CHAR_TO_FLOAT((c)[2]); \
-} (void)0
-#define IMAPAINT_CHAR_RGBA_TO_FLOAT(f, c) { \
- (f)[0] = IMAPAINT_CHAR_TO_FLOAT((c)[0]); \
- (f)[1] = IMAPAINT_CHAR_TO_FLOAT((c)[1]); \
- (f)[2] = IMAPAINT_CHAR_TO_FLOAT((c)[2]); \
- (f)[3] = IMAPAINT_CHAR_TO_FLOAT((c)[3]); \
-} (void)0
-
-#define IMAPAINT_FLOAT_RGB_COPY(a, b) copy_v3_v3(a, b)
-
#define IMAPAINT_TILE_BITS 6
#define IMAPAINT_TILE_SIZE (1 << IMAPAINT_TILE_BITS)
-#define IMAPAINT_TILE_NUMBER(size) (((size) + IMAPAINT_TILE_SIZE - 1) >> IMAPAINT_TILE_BITS)
-
-static void imapaint_image_update(SpaceImage *sima, Image *image, ImBuf *ibuf, short texpaint);
-
-
-typedef struct ImagePaintState {
- SpaceImage *sima;
- View2D *v2d;
- Scene *scene;
- bScreen *screen;
-
- Brush *brush;
- short tool, blend;
- Image *image;
- ImBuf *canvas;
- ImBuf *clonecanvas;
- char *warnpackedfile;
- char *warnmultifile;
-
- /* viewport texture paint only, but _not_ project paint */
- Object *ob;
- int faceindex;
- float uv[2];
- int do_facesel;
-
- DerivedMesh *dm;
- int dm_totface;
- int dm_release;
-
- MFace *dm_mface;
- MTFace *dm_mtface;
-} ImagePaintState;
-
-typedef struct ImagePaintPartialRedraw {
- int x1, y1, x2, y2; /* XXX, could use 'rcti' */
- int enabled;
-} ImagePaintPartialRedraw;
-
-typedef struct ImagePaintRegion {
- int destx, desty;
- int srcx, srcy;
- int width, height;
-} ImagePaintRegion;
-
-/* ProjectionPaint defines */
-
-/* approx the number of buckets to have under the brush,
- * used with the brush size to set the ps->buckets_x and ps->buckets_y value.
- *
- * When 3 - a brush should have ~9 buckets under it at once
- * ...this helps for threading while painting as well as
- * avoiding initializing pixels that wont touch the brush */
-#define PROJ_BUCKET_BRUSH_DIV 4
-
-#define PROJ_BUCKET_RECT_MIN 4
-#define PROJ_BUCKET_RECT_MAX 256
-
-#define PROJ_BOUNDBOX_DIV 8
-#define PROJ_BOUNDBOX_SQUARED (PROJ_BOUNDBOX_DIV * PROJ_BOUNDBOX_DIV)
-
-//#define PROJ_DEBUG_PAINT 1
-//#define PROJ_DEBUG_NOSEAMBLEED 1
-//#define PROJ_DEBUG_PRINT_CLIP 1
-#define PROJ_DEBUG_WINCLIP 1
-
-/* projectFaceSeamFlags options */
-//#define PROJ_FACE_IGNORE (1<<0) /* When the face is hidden, backfacing or occluded */
-//#define PROJ_FACE_INIT (1<<1) /* When we have initialized the faces data */
-#define PROJ_FACE_SEAM1 (1 << 0) /* If this face has a seam on any of its edges */
-#define PROJ_FACE_SEAM2 (1 << 1)
-#define PROJ_FACE_SEAM3 (1 << 2)
-#define PROJ_FACE_SEAM4 (1 << 3)
-
-#define PROJ_FACE_NOSEAM1 (1 << 4)
-#define PROJ_FACE_NOSEAM2 (1 << 5)
-#define PROJ_FACE_NOSEAM3 (1 << 6)
-#define PROJ_FACE_NOSEAM4 (1 << 7)
-
-#define PROJ_SRC_VIEW 1
-#define PROJ_SRC_IMAGE_CAM 2
-#define PROJ_SRC_IMAGE_VIEW 3
-
-#define PROJ_VIEW_DATA_ID "view_data"
-#define PROJ_VIEW_DATA_SIZE (4 * 4 + 4 * 4 + 3) /* viewmat + winmat + clipsta + clipend + is_ortho */
-
-
-/* a slightly scaled down face is used to get fake 3D location for edge pixels in the seams
- * as this number approaches 1.0f the likelihood increases of float precision errors where
- * it is occluded by an adjacent face */
-#define PROJ_FACE_SCALE_SEAM 0.99f
-
-#define PROJ_BUCKET_NULL 0
-#define PROJ_BUCKET_INIT (1 << 0)
-// #define PROJ_BUCKET_CLONE_INIT (1<<1)
-
-/* used for testing doubles, if a point is on a line etc */
-#define PROJ_GEOM_TOLERANCE 0.00075f
-
-/* vert flags */
-#define PROJ_VERT_CULL 1
-
-/* This is mainly a convenience struct used so we can keep an array of images we use
- * Thir imbufs, etc, in 1 array, When using threads this array is copied for each thread
- * because 'partRedrawRect' and 'touch' values would not be thread safe */
-typedef struct ProjPaintImage {
- Image *ima;
- ImBuf *ibuf;
- ImagePaintPartialRedraw *partRedrawRect;
- void **undoRect; /* only used to build undo tiles after painting */
- int touch;
-} ProjPaintImage;
-
-/* Main projection painting struct passed to all projection painting functions */
-typedef struct ProjPaintState {
- View3D *v3d;
- RegionView3D *rv3d;
- ARegion *ar;
- Scene *scene;
- int source; /* PROJ_SRC_**** */
-
- Brush *brush;
- short tool, blend;
- Object *ob;
- /* end similarities with ImagePaintState */
-
- DerivedMesh *dm;
- int dm_totface;
- int dm_totvert;
- int dm_release;
-
- MVert *dm_mvert;
- MFace *dm_mface;
- MTFace *dm_mtface;
- MTFace *dm_mtface_clone; /* other UV map, use for cloning between layers */
- MTFace *dm_mtface_stencil;
-
- /* projection painting only */
- MemArena *arena_mt[BLENDER_MAX_THREADS]; /* for multithreading, the first item is sometimes used for non threaded cases too */
- LinkNode **bucketRect; /* screen sized 2D array, each pixel has a linked list of ProjPixel's */
- LinkNode **bucketFaces; /* bucketRect aligned array linkList of faces overlapping each bucket */
- unsigned char *bucketFlags; /* store if the bucks have been initialized */
-#ifndef PROJ_DEBUG_NOSEAMBLEED
- char *faceSeamFlags; /* store info about faces, if they are initialized etc*/
- float (*faceSeamUVs)[4][2]; /* expanded UVs for faces to use as seams */
- LinkNode **vertFaces; /* Only needed for when seam_bleed_px is enabled, use to find UV seams */
-#endif
- char *vertFlags; /* store options per vert, now only store if the vert is pointing away from the view */
- int buckets_x; /* The size of the bucket grid, the grid span's screenMin/screenMax so you can paint outsize the screen or with 2 brushes at once */
- int buckets_y;
-
- ProjPaintImage *projImages;
-
- int pixel_sizeof; /* result of project_paint_pixel_sizeof(), constant per stroke */
-
- int image_tot; /* size of projectImages array */
-
- float (*screenCoords)[4]; /* verts projected into floating point screen space */
-
- float screenMin[2]; /* 2D bounds for mesh verts on the screen's plane (screenspace) */
- float screenMax[2];
- float screen_width; /* Calculated from screenMin & screenMax */
- float screen_height;
- int winx, winy; /* from the carea or from the projection render */
-
- /* options for projection painting */
- int do_layer_clone;
- int do_layer_stencil;
- int do_layer_stencil_inv;
-
- short do_occlude; /* Use raytraced occlusion? - ortherwise will paint right through to the back*/
- short do_backfacecull; /* ignore faces with normals pointing away, skips a lot of raycasts if your normals are correctly flipped */
- short do_mask_normal; /* mask out pixels based on their normals */
- short do_new_shading_nodes; /* cache BKE_scene_use_new_shading_nodes value */
- float normal_angle; /* what angle to mask at*/
- float normal_angle_inner;
- float normal_angle_range; /* difference between normal_angle and normal_angle_inner, for easy access */
-
- short is_ortho;
- bool do_masking; /* use masking during painting. Some operations such as airbrush may disable */
- short is_texbrush; /* only to avoid running */
-#ifndef PROJ_DEBUG_NOSEAMBLEED
- float seam_bleed_px;
-#endif
- /* clone vars */
- float cloneOffset[2];
-
- float projectMat[4][4]; /* Projection matrix, use for getting screen coords */
- float viewDir[3]; /* View vector, use for do_backfacecull and for ray casting with an ortho viewport */
- float viewPos[3]; /* View location in object relative 3D space, so can compare to verts */
- float clipsta, clipend;
-
- /* reproject vars */
- Image *reproject_image;
- ImBuf *reproject_ibuf;
-
-
- /* threads */
- int thread_tot;
- int bucketMin[2];
- int bucketMax[2];
- int context_bucket_x, context_bucket_y; /* must lock threads while accessing these */
-} ProjPaintState;
-
-typedef union pixelPointer {
- float *f_pt; /* float buffer */
- unsigned int *uint_pt; /* 2 ways to access a char buffer */
- unsigned char *ch_pt;
-} PixelPointer;
-
-typedef union pixelStore {
- unsigned char ch[4];
- unsigned int uint;
- float f[4];
-} PixelStore;
-
-typedef struct ProjPixel {
- float projCoSS[2]; /* the floating point screen projection of this pixel */
- float worldCoSS[3];
- /* Only used when the airbrush is disabled.
- * Store the max mask value to avoid painting over an area with a lower opacity
- * with an advantage that we can avoid touching the pixel at all, if the
- * new mask value is lower then mask_max */
- unsigned short mask_max;
-
- /* for various reasons we may want to mask out painting onto this pixel */
- unsigned short mask;
-
- short x_px, y_px;
-
- PixelStore origColor;
- PixelStore newColor;
- PixelPointer pixel;
-
- short image_index; /* if anyone wants to paint onto more then 32768 images they can bite me */
- unsigned char bb_cell_index;
-} ProjPixel;
-
-typedef struct ProjPixelClone {
- struct ProjPixel __pp;
- PixelStore clonepx;
-} ProjPixelClone;
-
-/* blur, store surrounding colors */
-#define PROJ_PIXEL_SOFTEN_TOT 4
-/* blur picking offset (in screenspace) */
-#define PROJ_PIXEL_SOFTEN_OFS_PX 1.0f
-
-static const float proj_pixel_soften_v2[PROJ_PIXEL_SOFTEN_TOT][2] = {
- {-PROJ_PIXEL_SOFTEN_OFS_PX, 0.0f},
- { 0.0f, -PROJ_PIXEL_SOFTEN_OFS_PX},
- { 0.0f, PROJ_PIXEL_SOFTEN_OFS_PX},
- { PROJ_PIXEL_SOFTEN_OFS_PX, 0.0f},
-};
-
-/* Finish projection painting structs */
typedef struct UndoImageTile {
struct UndoImageTile *next, *prev;
@@ -411,8 +121,21 @@ typedef struct UndoImageTile {
char gen_type;
} UndoImageTile;
+/* this is a static resource for non-globality,
+ * Maybe it should be exposed as part of the
+ * paint operation, but for now just give a public interface */
static ImagePaintPartialRedraw imapaintpartial = {0, 0, 0, 0, 0};
+ImagePaintPartialRedraw *get_imapaintpartial(void)
+{
+ return &imapaintpartial;
+}
+
+void set_imapaintpartial(struct ImagePaintPartialRedraw *ippr)
+{
+ imapaintpartial = *ippr;
+}
+
/* UNDO */
static void undo_copy_tile(UndoImageTile *tile, ImBuf *tmpibuf, ImBuf *ibuf, int restore)
@@ -433,7 +156,7 @@ static void undo_copy_tile(UndoImageTile *tile, ImBuf *tmpibuf, ImBuf *ibuf, int
tile->y * IMAPAINT_TILE_SIZE, 0, 0, IMAPAINT_TILE_SIZE, IMAPAINT_TILE_SIZE);
}
-static void *image_undo_push_tile(Image *ima, ImBuf *ibuf, ImBuf **tmpibuf, int x_tile, int y_tile)
+void *image_undo_push_tile(Image *ima, ImBuf *ibuf, ImBuf **tmpibuf, int x_tile, int y_tile)
{
ListBase *lb = undo_paint_push_get_list(UNDO_PAINT_IMAGE);
UndoImageTile *tile;
@@ -472,7 +195,7 @@ static void *image_undo_push_tile(Image *ima, ImBuf *ibuf, ImBuf **tmpibuf, int
return tile->rect.pt;
}
-static void image_undo_restore(bContext *C, ListBase *lb)
+void image_undo_restore(bContext *C, ListBase *lb)
{
Main *bmain = CTX_data_main(C);
Image *ima = NULL;
@@ -481,7 +204,7 @@ static void image_undo_restore(bContext *C, ListBase *lb)
tmpibuf = IMB_allocImBuf(IMAPAINT_TILE_SIZE, IMAPAINT_TILE_SIZE, 32,
IB_rectfloat | IB_rect);
-
+
for (tile = lb->first; tile; tile = tile->next) {
short use_float;
@@ -538,7 +261,7 @@ static void image_undo_restore(bContext *C, ListBase *lb)
IMB_freeImBuf(tmpibuf);
}
-static void image_undo_free(ListBase *lb)
+void image_undo_free(ListBase *lb)
{
UndoImageTile *tile;
@@ -546,3839 +269,14 @@ static void image_undo_free(ListBase *lb)
MEM_freeN(tile->rect.pt);
}
-/* get active image for face depending on old/new shading system */
-
-static Image *imapaint_face_image(const ImagePaintState *s, int face_index)
-{
- Image *ima;
-
- if (BKE_scene_use_new_shading_nodes(s->scene)) {
- MFace *mf = &s->dm_mface[face_index];
- ED_object_get_active_image(s->ob, mf->mat_nr + 1, &ima, NULL, NULL);
- }
- else {
- MTFace *tf = &s->dm_mtface[face_index];
- ima = tf->tpage;
- }
-
- return ima;
-}
-
-static Image *project_paint_face_image(const ProjPaintState *ps, MTFace *dm_mtface, int face_index)
-{
- Image *ima;
-
- if (ps->do_new_shading_nodes) { /* cached BKE_scene_use_new_shading_nodes result */
- MFace *mf = ps->dm_mface + face_index;
- ED_object_get_active_image(ps->ob, mf->mat_nr + 1, &ima, NULL, NULL);
- }
- else {
- ima = dm_mtface[face_index].tpage;
- }
-
- return ima;
-}
-
-/* fast projection bucket array lookup, use the safe version for bound checking */
-static int project_bucket_offset(const ProjPaintState *ps, const float projCoSS[2])
-{
- /* If we were not dealing with screenspace 2D coords we could simple do...
- * ps->bucketRect[x + (y*ps->buckets_y)] */
-
- /* please explain?
- * projCoSS[0] - ps->screenMin[0] : zero origin
- * ... / ps->screen_width : range from 0.0 to 1.0
- * ... * ps->buckets_x : use as a bucket index
- *
- * Second multiplication does similar but for vertical offset
- */
- return ( (int)(((projCoSS[0] - ps->screenMin[0]) / ps->screen_width) * ps->buckets_x)) +
- (((int)(((projCoSS[1] - ps->screenMin[1]) / ps->screen_height) * ps->buckets_y)) * ps->buckets_x);
-}
-
-static int project_bucket_offset_safe(const ProjPaintState *ps, const float projCoSS[2])
-{
- int bucket_index = project_bucket_offset(ps, projCoSS);
-
- if (bucket_index < 0 || bucket_index >= ps->buckets_x * ps->buckets_y) {
- return -1;
- }
- else {
- return bucket_index;
- }
-}
-
-/* still use 2D X,Y space but this works for verts transformed by a perspective matrix, using their 4th component as a weight */
-static void barycentric_weights_v2_persp(const float v1[4], const float v2[4], const float v3[4], const float co[2], float w[3])
-{
- float wtot_inv, wtot;
-
- w[0] = area_tri_signed_v2(v2, v3, co) / v1[3];
- w[1] = area_tri_signed_v2(v3, v1, co) / v2[3];
- w[2] = area_tri_signed_v2(v1, v2, co) / v3[3];
- wtot = w[0] + w[1] + w[2];
-
- if (wtot != 0.0f) {
- wtot_inv = 1.0f / wtot;
-
- w[0] = w[0] * wtot_inv;
- w[1] = w[1] * wtot_inv;
- w[2] = w[2] * wtot_inv;
- }
- else /* dummy values for zero area face */
- w[0] = w[1] = w[2] = 1.0f / 3.0f;
-}
-
-static float VecZDepthOrtho(const float pt[2],
- const float v1[3], const float v2[3], const float v3[3],
- float w[3])
-{
- barycentric_weights_v2(v1, v2, v3, pt, w);
- return (v1[2] * w[0]) + (v2[2] * w[1]) + (v3[2] * w[2]);
-}
-
-static float VecZDepthPersp(const float pt[2],
- const float v1[4], const float v2[4], const float v3[4],
- float w[3])
-{
- float wtot_inv, wtot;
- float w_tmp[3];
-
- barycentric_weights_v2_persp(v1, v2, v3, pt, w);
- /* for the depth we need the weights to match what
- * barycentric_weights_v2 would return, in this case its easiest just to
- * undo the 4th axis division and make it unit-sum
- *
- * don't call barycentric_weights_v2() because our callers expect 'w'
- * to be weighted from the perspective */
- w_tmp[0] = w[0] * v1[3];
- w_tmp[1] = w[1] * v2[3];
- w_tmp[2] = w[2] * v3[3];
-
- wtot = w_tmp[0] + w_tmp[1] + w_tmp[2];
-
- if (wtot != 0.0f) {
- wtot_inv = 1.0f / wtot;
-
- w_tmp[0] = w_tmp[0] * wtot_inv;
- w_tmp[1] = w_tmp[1] * wtot_inv;
- w_tmp[2] = w_tmp[2] * wtot_inv;
- }
- else /* dummy values for zero area face */
- w_tmp[0] = w_tmp[1] = w_tmp[2] = 1.0f / 3.0f;
- /* done mimicing barycentric_weights_v2() */
-
- return (v1[2] * w_tmp[0]) + (v2[2] * w_tmp[1]) + (v3[2] * w_tmp[2]);
-}
-
-
-/* Return the top-most face index that the screen space coord 'pt' touches (or -1) */
-static int project_paint_PickFace(const ProjPaintState *ps, float pt[2], float w[3], int *side)
-{
- LinkNode *node;
- float w_tmp[3];
- float *v1, *v2, *v3, *v4;
- int bucket_index;
- int face_index;
- int best_side = -1;
- int best_face_index = -1;
- float z_depth_best = FLT_MAX, z_depth;
- MFace *mf;
-
- bucket_index = project_bucket_offset_safe(ps, pt);
- if (bucket_index == -1)
- return -1;
-
-
-
- /* we could return 0 for 1 face buckets, as long as this function assumes
- * that the point its testing is only every originated from an existing face */
-
- for (node = ps->bucketFaces[bucket_index]; node; node = node->next) {
- face_index = GET_INT_FROM_POINTER(node->link);
- mf = ps->dm_mface + face_index;
-
- v1 = ps->screenCoords[mf->v1];
- v2 = ps->screenCoords[mf->v2];
- v3 = ps->screenCoords[mf->v3];
-
- if (isect_point_tri_v2(pt, v1, v2, v3)) {
- if (ps->is_ortho) z_depth = VecZDepthOrtho(pt, v1, v2, v3, w_tmp);
- else z_depth = VecZDepthPersp(pt, v1, v2, v3, w_tmp);
-
- if (z_depth < z_depth_best) {
- best_face_index = face_index;
- best_side = 0;
- z_depth_best = z_depth;
- copy_v3_v3(w, w_tmp);
- }
- }
- else if (mf->v4) {
- v4 = ps->screenCoords[mf->v4];
-
- if (isect_point_tri_v2(pt, v1, v3, v4)) {
- if (ps->is_ortho) z_depth = VecZDepthOrtho(pt, v1, v3, v4, w_tmp);
- else z_depth = VecZDepthPersp(pt, v1, v3, v4, w_tmp);
-
- if (z_depth < z_depth_best) {
- best_face_index = face_index;
- best_side = 1;
- z_depth_best = z_depth;
- copy_v3_v3(w, w_tmp);
- }
- }
- }
- }
-
- *side = best_side;
- return best_face_index; /* will be -1 or a valid face */
-}
-
-/* Converts a uv coord into a pixel location wrapping if the uv is outside 0-1 range */
-static void uvco_to_wrapped_pxco(float uv[2], int ibuf_x, int ibuf_y, float *x, float *y)
-{
- /* use */
- *x = (float)fmodf(uv[0], 1.0f);
- *y = (float)fmodf(uv[1], 1.0f);
-
- if (*x < 0.0f) *x += 1.0f;
- if (*y < 0.0f) *y += 1.0f;
-
- *x = *x * ibuf_x - 0.5f;
- *y = *y * ibuf_y - 0.5f;
-}
-
-/* Set the top-most face color that the screen space coord 'pt' touches (or return 0 if none touch) */
-static int project_paint_PickColor(const ProjPaintState *ps, float pt[2], float *rgba_fp, unsigned char *rgba, const int interp)
-{
- float w[3], uv[2];
- int side;
- int face_index;
- MTFace *tf;
- Image *ima;
- ImBuf *ibuf;
- int xi, yi;
-
-
- face_index = project_paint_PickFace(ps, pt, w, &side);
-
- if (face_index == -1)
- return 0;
-
- tf = ps->dm_mtface + face_index;
-
- if (side == 0) {
- interp_v2_v2v2v2(uv, tf->uv[0], tf->uv[1], tf->uv[2], w);
- }
- else { /* QUAD */
- interp_v2_v2v2v2(uv, tf->uv[0], tf->uv[2], tf->uv[3], w);
- }
-
- ima = project_paint_face_image(ps, ps->dm_mtface, face_index);
- ibuf = ima->ibufs.first; /* we must have got the imbuf before getting here */
- if (!ibuf) return 0;
-
- if (interp) {
- float x, y;
- uvco_to_wrapped_pxco(uv, ibuf->x, ibuf->y, &x, &y);
-
- if (ibuf->rect_float) {
- if (rgba_fp) {
- bilinear_interpolation_color_wrap(ibuf, NULL, rgba_fp, x, y);
- }
- else {
- float rgba_tmp_f[4];
- bilinear_interpolation_color_wrap(ibuf, NULL, rgba_tmp_f, x, y);
- IMAPAINT_FLOAT_RGBA_TO_CHAR(rgba, rgba_tmp_f);
- }
- }
- else {
- if (rgba) {
- bilinear_interpolation_color_wrap(ibuf, rgba, NULL, x, y);
- }
- else {
- unsigned char rgba_tmp[4];
- bilinear_interpolation_color_wrap(ibuf, rgba_tmp, NULL, x, y);
- IMAPAINT_CHAR_RGBA_TO_FLOAT(rgba_fp, rgba_tmp);
- }
- }
- }
- else {
- //xi = (int)((uv[0]*ibuf->x) + 0.5f);
- //yi = (int)((uv[1]*ibuf->y) + 0.5f);
- //if (xi < 0 || xi >= ibuf->x || yi < 0 || yi >= ibuf->y) return 0;
-
- /* wrap */
- xi = ((int)(uv[0] * ibuf->x)) % ibuf->x;
- if (xi < 0) xi += ibuf->x;
- yi = ((int)(uv[1] * ibuf->y)) % ibuf->y;
- if (yi < 0) yi += ibuf->y;
-
-
- if (rgba) {
- if (ibuf->rect_float) {
- float *rgba_tmp_fp = ibuf->rect_float + (xi + yi * ibuf->x * 4);
- IMAPAINT_FLOAT_RGBA_TO_CHAR(rgba, rgba_tmp_fp);
- }
- else {
- *((unsigned int *)rgba) = *(unsigned int *)(((char *)ibuf->rect) + ((xi + yi * ibuf->x) * 4));
- }
- }
-
- if (rgba_fp) {
- if (ibuf->rect_float) {
- copy_v4_v4(rgba_fp, (ibuf->rect_float + ((xi + yi * ibuf->x) * 4)));
- }
- else {
- char *tmp_ch = ((char *)ibuf->rect) + ((xi + yi * ibuf->x) * 4);
- IMAPAINT_CHAR_RGBA_TO_FLOAT(rgba_fp, tmp_ch);
- }
- }
- }
- return 1;
-}
-
-/* Check if 'pt' is infront of the 3 verts on the Z axis (used for screenspace occlusuion test)
- * return...
- * 0 : no occlusion
- * -1 : no occlusion but 2D intersection is true (avoid testing the other half of a quad)
- * 1 : occluded
- * 2 : occluded with w[3] weights set (need to know in some cases) */
-
-static int project_paint_occlude_ptv(float pt[3], float v1[4], float v2[4], float v3[4], float w[3], int is_ortho)
-{
- /* if all are behind us, return false */
- if (v1[2] > pt[2] && v2[2] > pt[2] && v3[2] > pt[2])
- return 0;
-
- /* do a 2D point in try intersection */
- if (!isect_point_tri_v2(pt, v1, v2, v3))
- return 0; /* we know there is */
-
-
- /* From here on we know there IS an intersection */
- /* if ALL of the verts are infront of us then we know it intersects ? */
- if (v1[2] < pt[2] && v2[2] < pt[2] && v3[2] < pt[2]) {
- return 1;
- }
- else {
- /* we intersect? - find the exact depth at the point of intersection */
- /* Is this point is occluded by another face? */
- if (is_ortho) {
- if (VecZDepthOrtho(pt, v1, v2, v3, w) < pt[2]) return 2;
- }
- else {
- if (VecZDepthPersp(pt, v1, v2, v3, w) < pt[2]) return 2;
- }
- }
- return -1;
-}
-
-
-static int project_paint_occlude_ptv_clip(const ProjPaintState *ps, const MFace *mf,
- float pt[3], float v1[4], float v2[4], float v3[4],
- const int side)
-{
- float w[3], wco[3];
- int ret = project_paint_occlude_ptv(pt, v1, v2, v3, w, ps->is_ortho);
-
- if (ret <= 0)
- return ret;
-
- if (ret == 1) { /* weights not calculated */
- if (ps->is_ortho) barycentric_weights_v2(v1, v2, v3, pt, w);
- else barycentric_weights_v2_persp(v1, v2, v3, pt, w);
- }
-
- /* Test if we're in the clipped area, */
- if (side) interp_v3_v3v3v3(wco, ps->dm_mvert[mf->v1].co, ps->dm_mvert[mf->v3].co, ps->dm_mvert[mf->v4].co, w);
- else interp_v3_v3v3v3(wco, ps->dm_mvert[mf->v1].co, ps->dm_mvert[mf->v2].co, ps->dm_mvert[mf->v3].co, w);
-
- if (!ED_view3d_clipping_test(ps->rv3d, wco, TRUE)) {
- return 1;
- }
-
- return -1;
-}
-
-
-/* Check if a screenspace location is occluded by any other faces
- * check, pixelScreenCo must be in screenspace, its Z-Depth only needs to be used for comparison
- * and doesn't need to be correct in relation to X and Y coords (this is the case in perspective view) */
-static int project_bucket_point_occluded(const ProjPaintState *ps, LinkNode *bucketFace, const int orig_face, float pixelScreenCo[4])
-{
- MFace *mf;
- int face_index;
- int isect_ret;
- float w[3]; /* not needed when clipping */
- const short do_clip = ps->rv3d ? ps->rv3d->rflag & RV3D_CLIPPING : 0;
-
- /* we could return 0 for 1 face buckets, as long as this function assumes
- * that the point its testing is only every originated from an existing face */
-
- for (; bucketFace; bucketFace = bucketFace->next) {
- face_index = GET_INT_FROM_POINTER(bucketFace->link);
-
- if (orig_face != face_index) {
- mf = ps->dm_mface + face_index;
- if (do_clip)
- isect_ret = project_paint_occlude_ptv_clip(ps, mf, pixelScreenCo, ps->screenCoords[mf->v1], ps->screenCoords[mf->v2], ps->screenCoords[mf->v3], 0);
- else
- isect_ret = project_paint_occlude_ptv(pixelScreenCo, ps->screenCoords[mf->v1], ps->screenCoords[mf->v2], ps->screenCoords[mf->v3], w, ps->is_ortho);
-
- /* Note, if (isect_ret == -1) then we don't want to test the other side of the quad */
- if (isect_ret == 0 && mf->v4) {
- if (do_clip)
- isect_ret = project_paint_occlude_ptv_clip(ps, mf, pixelScreenCo, ps->screenCoords[mf->v1], ps->screenCoords[mf->v3], ps->screenCoords[mf->v4], 1);
- else
- isect_ret = project_paint_occlude_ptv(pixelScreenCo, ps->screenCoords[mf->v1], ps->screenCoords[mf->v3], ps->screenCoords[mf->v4], w, ps->is_ortho);
- }
- if (isect_ret >= 1) {
- /* TODO - we may want to cache the first hit,
- * it is not possible to swap the face order in the list anymore */
- return 1;
- }
- }
- }
- return 0;
-}
-
-/* basic line intersection, could move to math_geom.c, 2 points with a horiz line
- * 1 for an intersection, 2 if the first point is aligned, 3 if the second point is aligned */
-#define ISECT_TRUE 1
-#define ISECT_TRUE_P1 2
-#define ISECT_TRUE_P2 3
-static int line_isect_y(const float p1[2], const float p2[2], const float y_level, float *x_isect)
-{
- float y_diff;
-
- if (y_level == p1[1]) { /* are we touching the first point? - no interpolation needed */
- *x_isect = p1[0];
- return ISECT_TRUE_P1;
- }
- if (y_level == p2[1]) { /* are we touching the second point? - no interpolation needed */
- *x_isect = p2[0];
- return ISECT_TRUE_P2;
- }
-
- y_diff = fabsf(p1[1] - p2[1]); /* yuck, horizontal line, we cant do much here */
-
- if (y_diff < 0.000001f) {
- *x_isect = (p1[0] + p2[0]) * 0.5f;
- return ISECT_TRUE;
- }
-
- if (p1[1] > y_level && p2[1] < y_level) {
- *x_isect = (p2[0] * (p1[1] - y_level) + p1[0] * (y_level - p2[1])) / y_diff; /*(p1[1]-p2[1]);*/
- return ISECT_TRUE;
- }
- else if (p1[1] < y_level && p2[1] > y_level) {
- *x_isect = (p2[0] * (y_level - p1[1]) + p1[0] * (p2[1] - y_level)) / y_diff; /*(p2[1]-p1[1]);*/
- return ISECT_TRUE;
- }
- else {
- return 0;
- }
-}
-
-static int line_isect_x(const float p1[2], const float p2[2], const float x_level, float *y_isect)
-{
- float x_diff;
-
- if (x_level == p1[0]) { /* are we touching the first point? - no interpolation needed */
- *y_isect = p1[1];
- return ISECT_TRUE_P1;
- }
- if (x_level == p2[0]) { /* are we touching the second point? - no interpolation needed */
- *y_isect = p2[1];
- return ISECT_TRUE_P2;
- }
-
- x_diff = fabsf(p1[0] - p2[0]); /* yuck, horizontal line, we cant do much here */
-
- if (x_diff < 0.000001f) { /* yuck, vertical line, we cant do much here */
- *y_isect = (p1[0] + p2[0]) * 0.5f;
- return ISECT_TRUE;
- }
-
- if (p1[0] > x_level && p2[0] < x_level) {
- *y_isect = (p2[1] * (p1[0] - x_level) + p1[1] * (x_level - p2[0])) / x_diff; /*(p1[0]-p2[0]);*/
- return ISECT_TRUE;
- }
- else if (p1[0] < x_level && p2[0] > x_level) {
- *y_isect = (p2[1] * (x_level - p1[0]) + p1[1] * (p2[0] - x_level)) / x_diff; /*(p2[0]-p1[0]);*/
- return ISECT_TRUE;
- }
- else {
- return 0;
- }
-}
-
-/* simple func use for comparing UV locations to check if there are seams.
- * Its possible this gives incorrect results, when the UVs for 1 face go into the next
- * tile, but do not do this for the adjacent face, it could return a false positive.
- * This is so unlikely that Id not worry about it. */
-#ifndef PROJ_DEBUG_NOSEAMBLEED
-static int cmp_uv(const float vec2a[2], const float vec2b[2])
-{
- /* if the UV's are not between 0.0 and 1.0 */
- float xa = (float)fmodf(vec2a[0], 1.0f);
- float ya = (float)fmodf(vec2a[1], 1.0f);
-
- float xb = (float)fmodf(vec2b[0], 1.0f);
- float yb = (float)fmodf(vec2b[1], 1.0f);
-
- if (xa < 0.0f) xa += 1.0f;
- if (ya < 0.0f) ya += 1.0f;
-
- if (xb < 0.0f) xb += 1.0f;
- if (yb < 0.0f) yb += 1.0f;
-
- return ((fabsf(xa - xb) < PROJ_GEOM_TOLERANCE) && (fabsf(ya - yb) < PROJ_GEOM_TOLERANCE)) ? 1 : 0;
-}
-#endif
-
-/* set min_px and max_px to the image space bounds of the UV coords
- * return zero if there is no area in the returned rectangle */
-#ifndef PROJ_DEBUG_NOSEAMBLEED
-static int pixel_bounds_uv(
- const float uv1[2], const float uv2[2], const float uv3[2], const float uv4[2],
- rcti *bounds_px,
- const int ibuf_x, const int ibuf_y,
- int is_quad
- )
-{
- float min_uv[2], max_uv[2]; /* UV bounds */
-
- INIT_MINMAX2(min_uv, max_uv);
-
- minmax_v2v2_v2(min_uv, max_uv, uv1);
- minmax_v2v2_v2(min_uv, max_uv, uv2);
- minmax_v2v2_v2(min_uv, max_uv, uv3);
- if (is_quad)
- minmax_v2v2_v2(min_uv, max_uv, uv4);
-
- bounds_px->xmin = (int)(ibuf_x * min_uv[0]);
- bounds_px->ymin = (int)(ibuf_y * min_uv[1]);
-
- bounds_px->xmax = (int)(ibuf_x * max_uv[0]) + 1;
- bounds_px->ymax = (int)(ibuf_y * max_uv[1]) + 1;
-
- /*printf("%d %d %d %d\n", min_px[0], min_px[1], max_px[0], max_px[1]);*/
-
- /* face uses no UV area when quantized to pixels? */
- return (bounds_px->xmin == bounds_px->xmax || bounds_px->ymin == bounds_px->ymax) ? 0 : 1;
-}
-#endif
-
-static int pixel_bounds_array(float (*uv)[2], rcti *bounds_px, const int ibuf_x, const int ibuf_y, int tot)
-{
- float min_uv[2], max_uv[2]; /* UV bounds */
-
- if (tot == 0) {
- return 0;
- }
-
- INIT_MINMAX2(min_uv, max_uv);
-
- while (tot--) {
- minmax_v2v2_v2(min_uv, max_uv, (*uv));
- uv++;
- }
-
- bounds_px->xmin = (int)(ibuf_x * min_uv[0]);
- bounds_px->ymin = (int)(ibuf_y * min_uv[1]);
-
- bounds_px->xmax = (int)(ibuf_x * max_uv[0]) + 1;
- bounds_px->ymax = (int)(ibuf_y * max_uv[1]) + 1;
-
- /*printf("%d %d %d %d\n", min_px[0], min_px[1], max_px[0], max_px[1]);*/
-
- /* face uses no UV area when quantized to pixels? */
- return (bounds_px->xmin == bounds_px->xmax || bounds_px->ymin == bounds_px->ymax) ? 0 : 1;
-}
-
-#ifndef PROJ_DEBUG_NOSEAMBLEED
-
-/* This function returns 1 if this face has a seam along the 2 face-vert indices
- * 'orig_i1_fidx' and 'orig_i2_fidx' */
-static int check_seam(const ProjPaintState *ps, const int orig_face, const int orig_i1_fidx, const int orig_i2_fidx, int *other_face, int *orig_fidx)
-{
- LinkNode *node;
- int face_index;
- unsigned int i1, i2;
- int i1_fidx = -1, i2_fidx = -1; /* index in face */
- MFace *mf;
- MTFace *tf;
- const MFace *orig_mf = ps->dm_mface + orig_face;
- const MTFace *orig_tf = ps->dm_mtface + orig_face;
-
- /* vert indices from face vert order indices */
- i1 = (*(&orig_mf->v1 + orig_i1_fidx));
- i2 = (*(&orig_mf->v1 + orig_i2_fidx));
-
- for (node = ps->vertFaces[i1]; node; node = node->next) {
- face_index = GET_INT_FROM_POINTER(node->link);
-
- if (face_index != orig_face) {
- mf = ps->dm_mface + face_index;
- /* could check if the 2 faces images match here,
- * but then there wouldn't be a way to return the opposite face's info */
-
-
- /* We need to know the order of the verts in the adjacent face
- * set the i1_fidx and i2_fidx to (0,1,2,3) */
- if (mf->v1 == i1) i1_fidx = 0;
- else if (mf->v2 == i1) i1_fidx = 1;
- else if (mf->v3 == i1) i1_fidx = 2;
- else if (mf->v4 && mf->v4 == i1) i1_fidx = 3;
-
- if (mf->v1 == i2) i2_fidx = 0;
- else if (mf->v2 == i2) i2_fidx = 1;
- else if (mf->v3 == i2) i2_fidx = 2;
- else if (mf->v4 && mf->v4 == i2) i2_fidx = 3;
-
- /* Only need to check if 'i2_fidx' is valid because we know i1_fidx is the same vert on both faces */
- if (i2_fidx != -1) {
- Image *tpage = project_paint_face_image(ps, ps->dm_mtface, face_index);
- Image *orig_tpage = project_paint_face_image(ps, ps->dm_mtface, orig_face);
-
- /* This IS an adjacent face!, now lets check if the UVs are ok */
- tf = ps->dm_mtface + face_index;
-
- /* set up the other face */
- *other_face = face_index;
- *orig_fidx = (i1_fidx < i2_fidx) ? i1_fidx : i2_fidx;
-
- /* first test if they have the same image */
- if ((orig_tpage == tpage) &&
- cmp_uv(orig_tf->uv[orig_i1_fidx], tf->uv[i1_fidx]) &&
- cmp_uv(orig_tf->uv[orig_i2_fidx], tf->uv[i2_fidx]) )
- {
- // printf("SEAM (NONE)\n");
- return 0;
-
- }
- else {
- // printf("SEAM (UV GAP)\n");
- return 1;
- }
- }
- }
- }
- // printf("SEAM (NO FACE)\n");
- *other_face = -1;
- return 1;
-}
-
-/* Calculate outset UV's, this is not the same as simply scaling the UVs,
- * since the outset coords are a margin that keep an even distance from the original UV's,
- * note that the image aspect is taken into account */
-static void uv_image_outset(float (*orig_uv)[2], float (*outset_uv)[2], const float scaler, const int ibuf_x, const int ibuf_y, const int is_quad)
-{
- float a1, a2, a3, a4 = 0.0f;
- float puv[4][2]; /* pixelspace uv's */
- float no1[2], no2[2], no3[2], no4[2]; /* normals */
- float dir1[2], dir2[2], dir3[2], dir4[2];
- float ibuf_inv[2];
-
- ibuf_inv[0] = 1.0f / (float)ibuf_x;
- ibuf_inv[1] = 1.0f / (float)ibuf_y;
-
- /* make UV's in pixel space so we can */
- puv[0][0] = orig_uv[0][0] * ibuf_x;
- puv[0][1] = orig_uv[0][1] * ibuf_y;
-
- puv[1][0] = orig_uv[1][0] * ibuf_x;
- puv[1][1] = orig_uv[1][1] * ibuf_y;
-
- puv[2][0] = orig_uv[2][0] * ibuf_x;
- puv[2][1] = orig_uv[2][1] * ibuf_y;
-
- if (is_quad) {
- puv[3][0] = orig_uv[3][0] * ibuf_x;
- puv[3][1] = orig_uv[3][1] * ibuf_y;
- }
-
- /* face edge directions */
- sub_v2_v2v2(dir1, puv[1], puv[0]);
- sub_v2_v2v2(dir2, puv[2], puv[1]);
- normalize_v2(dir1);
- normalize_v2(dir2);
-
- if (is_quad) {
- sub_v2_v2v2(dir3, puv[3], puv[2]);
- sub_v2_v2v2(dir4, puv[0], puv[3]);
- normalize_v2(dir3);
- normalize_v2(dir4);
- }
- else {
- sub_v2_v2v2(dir3, puv[0], puv[2]);
- normalize_v2(dir3);
- }
-
- /* TODO - angle_normalized_v2v2(...) * (M_PI/180.0f)
- * This is incorrect. Its already given radians but without it wont work.
- * need to look into a fix - campbell */
- if (is_quad) {
- a1 = shell_angle_to_dist(angle_normalized_v2v2(dir4, dir1) * ((float)M_PI / 180.0f));
- a2 = shell_angle_to_dist(angle_normalized_v2v2(dir1, dir2) * ((float)M_PI / 180.0f));
- a3 = shell_angle_to_dist(angle_normalized_v2v2(dir2, dir3) * ((float)M_PI / 180.0f));
- a4 = shell_angle_to_dist(angle_normalized_v2v2(dir3, dir4) * ((float)M_PI / 180.0f));
- }
- else {
- a1 = shell_angle_to_dist(angle_normalized_v2v2(dir3, dir1) * ((float)M_PI / 180.0f));
- a2 = shell_angle_to_dist(angle_normalized_v2v2(dir1, dir2) * ((float)M_PI / 180.0f));
- a3 = shell_angle_to_dist(angle_normalized_v2v2(dir2, dir3) * ((float)M_PI / 180.0f));
- }
-
- if (is_quad) {
- sub_v2_v2v2(no1, dir4, dir1);
- sub_v2_v2v2(no2, dir1, dir2);
- sub_v2_v2v2(no3, dir2, dir3);
- sub_v2_v2v2(no4, dir3, dir4);
- normalize_v2(no1);
- normalize_v2(no2);
- normalize_v2(no3);
- normalize_v2(no4);
- mul_v2_fl(no1, a1 * scaler);
- mul_v2_fl(no2, a2 * scaler);
- mul_v2_fl(no3, a3 * scaler);
- mul_v2_fl(no4, a4 * scaler);
- add_v2_v2v2(outset_uv[0], puv[0], no1);
- add_v2_v2v2(outset_uv[1], puv[1], no2);
- add_v2_v2v2(outset_uv[2], puv[2], no3);
- add_v2_v2v2(outset_uv[3], puv[3], no4);
- mul_v2_v2(outset_uv[0], ibuf_inv);
- mul_v2_v2(outset_uv[1], ibuf_inv);
- mul_v2_v2(outset_uv[2], ibuf_inv);
- mul_v2_v2(outset_uv[3], ibuf_inv);
- }
- else {
- sub_v2_v2v2(no1, dir3, dir1);
- sub_v2_v2v2(no2, dir1, dir2);
- sub_v2_v2v2(no3, dir2, dir3);
- normalize_v2(no1);
- normalize_v2(no2);
- normalize_v2(no3);
- mul_v2_fl(no1, a1 * scaler);
- mul_v2_fl(no2, a2 * scaler);
- mul_v2_fl(no3, a3 * scaler);
- add_v2_v2v2(outset_uv[0], puv[0], no1);
- add_v2_v2v2(outset_uv[1], puv[1], no2);
- add_v2_v2v2(outset_uv[2], puv[2], no3);
-
- mul_v2_v2(outset_uv[0], ibuf_inv);
- mul_v2_v2(outset_uv[1], ibuf_inv);
- mul_v2_v2(outset_uv[2], ibuf_inv);
- }
-}
-
-/*
- * Be tricky with flags, first 4 bits are PROJ_FACE_SEAM1 to 4, last 4 bits are PROJ_FACE_NOSEAM1 to 4
- * 1<<i - where i is (0-3)
- *
- * If we're multithreadng, make sure threads are locked when this is called
- */
-static void project_face_seams_init(const ProjPaintState *ps, const int face_index, const int is_quad)
-{
- int other_face, other_fidx; /* vars for the other face, we also set its flag */
- int fidx1 = is_quad ? 3 : 2;
- int fidx2 = 0; /* next fidx in the face (0,1,2,3) -> (1,2,3,0) or (0,1,2) -> (1,2,0) for a tri */
-
- do {
- if ((ps->faceSeamFlags[face_index] & (1 << fidx1 | 16 << fidx1)) == 0) {
- if (check_seam(ps, face_index, fidx1, fidx2, &other_face, &other_fidx)) {
- ps->faceSeamFlags[face_index] |= 1 << fidx1;
- if (other_face != -1)
- ps->faceSeamFlags[other_face] |= 1 << other_fidx;
- }
- else {
- ps->faceSeamFlags[face_index] |= 16 << fidx1;
- if (other_face != -1)
- ps->faceSeamFlags[other_face] |= 16 << other_fidx; /* second 4 bits for disabled */
- }
- }
-
- fidx2 = fidx1;
- } while (fidx1--);
-}
-#endif // PROJ_DEBUG_NOSEAMBLEED
-
-
-/* Converts a UV location to a 3D screenspace location
- * Takes a 'uv' and 3 UV coords, and sets the values of pixelScreenCo
- *
- * This is used for finding a pixels location in screenspace for painting */
-static void screen_px_from_ortho(
- float uv[2],
- float v1co[3], float v2co[3], float v3co[3], /* Screenspace coords */
- float uv1co[2], float uv2co[2], float uv3co[2],
- float pixelScreenCo[4],
- float w[3])
-{
- barycentric_weights_v2(uv1co, uv2co, uv3co, uv, w);
- interp_v3_v3v3v3(pixelScreenCo, v1co, v2co, v3co, w);
-}
-
-/* same as screen_px_from_ortho except we need to take into account
- * the perspective W coord for each vert */
-static void screen_px_from_persp(
- float uv[2],
- float v1co[4], float v2co[4], float v3co[4], /* screenspace coords */
- float uv1co[2], float uv2co[2], float uv3co[2],
- float pixelScreenCo[4],
- float w[3])
-{
-
- float wtot_inv, wtot;
- barycentric_weights_v2(uv1co, uv2co, uv3co, uv, w);
-
- /* re-weight from the 4th coord of each screen vert */
- w[0] *= v1co[3];
- w[1] *= v2co[3];
- w[2] *= v3co[3];
-
- wtot = w[0] + w[1] + w[2];
-
- if (wtot > 0.0f) {
- wtot_inv = 1.0f / wtot;
- w[0] *= wtot_inv;
- w[1] *= wtot_inv;
- w[2] *= wtot_inv;
- }
- else {
- w[0] = w[1] = w[2] = 1.0f / 3.0f; /* dummy values for zero area face */
- }
- /* done re-weighting */
-
- interp_v3_v3v3v3(pixelScreenCo, v1co, v2co, v3co, w);
-}
-
-static void project_face_pixel(const MTFace *tf_other, ImBuf *ibuf_other, const float w[3], int side, unsigned char rgba_ub[4], float rgba_f[4])
-{
- float *uvCo1, *uvCo2, *uvCo3;
- float uv_other[2], x, y;
-
- uvCo1 = (float *)tf_other->uv[0];
- if (side == 1) {
- uvCo2 = (float *)tf_other->uv[2];
- uvCo3 = (float *)tf_other->uv[3];
- }
- else {
- uvCo2 = (float *)tf_other->uv[1];
- uvCo3 = (float *)tf_other->uv[2];
- }
-
- interp_v2_v2v2v2(uv_other, uvCo1, uvCo2, uvCo3, (float *)w);
-
- /* use */
- uvco_to_wrapped_pxco(uv_other, ibuf_other->x, ibuf_other->y, &x, &y);
-
-
- if (ibuf_other->rect_float) { /* from float to float */
- bilinear_interpolation_color_wrap(ibuf_other, NULL, rgba_f, x, y);
- }
- else { /* from char to float */
- bilinear_interpolation_color_wrap(ibuf_other, rgba_ub, NULL, x, y);
- }
-
-}
-
-/* run this outside project_paint_uvpixel_init since pixels with mask 0 don't need init */
-static float project_paint_uvpixel_mask(
- const ProjPaintState *ps,
- const int face_index,
- const int side,
- const float w[3])
-{
- float mask;
-
- /* Image Mask */
- if (ps->do_layer_stencil) {
- /* another UV maps image is masking this one's */
- ImBuf *ibuf_other;
- Image *other_tpage = project_paint_face_image(ps, ps->dm_mtface_stencil, face_index);
- const MTFace *tf_other = ps->dm_mtface_stencil + face_index;
-
- if (other_tpage && (ibuf_other = BKE_image_acquire_ibuf(other_tpage, NULL, NULL))) {
- /* BKE_image_acquire_ibuf - TODO - this may be slow */
- unsigned char rgba_ub[4];
- float rgba_f[4];
-
- project_face_pixel(tf_other, ibuf_other, w, side, rgba_ub, rgba_f);
-
- if (ibuf_other->rect_float) { /* from float to float */
- mask = ((rgba_f[0] + rgba_f[1] + rgba_f[2]) / 3.0f) * rgba_f[3];
- }
- else { /* from char to float */
- mask = ((rgba_ub[0] + rgba_ub[1] + rgba_ub[2]) / (256 * 3.0f)) * (rgba_ub[3] / 256.0f);
- }
-
- BKE_image_release_ibuf(other_tpage, ibuf_other, NULL);
-
- if (!ps->do_layer_stencil_inv) /* matching the gimps layer mask black/white rules, white==full opacity */
- mask = (1.0f - mask);
-
- if (mask == 0.0f) {
- return 0.0f;
- }
- }
- else {
- return 0.0f;
- }
- }
- else {
- mask = 1.0f;
- }
-
- /* calculate mask */
- if (ps->do_mask_normal) {
- MFace *mf = &ps->dm_mface[face_index];
- float no[3], angle;
- if (mf->flag & ME_SMOOTH) {
- short *no1, *no2, *no3;
- no1 = ps->dm_mvert[mf->v1].no;
- if (side == 1) {
- no2 = ps->dm_mvert[mf->v3].no;
- no3 = ps->dm_mvert[mf->v4].no;
- }
- else {
- no2 = ps->dm_mvert[mf->v2].no;
- no3 = ps->dm_mvert[mf->v3].no;
- }
-
- no[0] = w[0] * no1[0] + w[1] * no2[0] + w[2] * no3[0];
- no[1] = w[0] * no1[1] + w[1] * no2[1] + w[2] * no3[1];
- no[2] = w[0] * no1[2] + w[1] * no2[2] + w[2] * no3[2];
- normalize_v3(no);
- }
- else {
- /* incase the */
-#if 1
- /* normalizing per pixel isn't optimal, we could cache or check ps->*/
- if (mf->v4)
- normal_quad_v3(no,
- ps->dm_mvert[mf->v1].co,
- ps->dm_mvert[mf->v2].co,
- ps->dm_mvert[mf->v3].co,
- ps->dm_mvert[mf->v4].co);
- else
- normal_tri_v3(no,
- ps->dm_mvert[mf->v1].co,
- ps->dm_mvert[mf->v2].co,
- ps->dm_mvert[mf->v3].co);
-#else
- /* don't use because some modifiers dont have normal data (subsurf for eg) */
- copy_v3_v3(no, (float *)ps->dm->getTessFaceData(ps->dm, face_index, CD_NORMAL));
-#endif
- }
-
- /* now we can use the normal as a mask */
- if (ps->is_ortho) {
- angle = angle_normalized_v3v3((float *)ps->viewDir, no);
- }
- else {
- /* Annoying but for the perspective view we need to get the pixels location in 3D space :/ */
- float viewDirPersp[3];
- float *co1, *co2, *co3;
- co1 = ps->dm_mvert[mf->v1].co;
- if (side == 1) {
- co2 = ps->dm_mvert[mf->v3].co;
- co3 = ps->dm_mvert[mf->v4].co;
- }
- else {
- co2 = ps->dm_mvert[mf->v2].co;
- co3 = ps->dm_mvert[mf->v3].co;
- }
-
- /* Get the direction from the viewPoint to the pixel and normalize */
- viewDirPersp[0] = (ps->viewPos[0] - (w[0] * co1[0] + w[1] * co2[0] + w[2] * co3[0]));
- viewDirPersp[1] = (ps->viewPos[1] - (w[0] * co1[1] + w[1] * co2[1] + w[2] * co3[1]));
- viewDirPersp[2] = (ps->viewPos[2] - (w[0] * co1[2] + w[1] * co2[2] + w[2] * co3[2]));
- normalize_v3(viewDirPersp);
-
- angle = angle_normalized_v3v3(viewDirPersp, no);
- }
-
- if (angle >= ps->normal_angle) {
- return 0.0f; /* outsize the normal limit*/
- }
- else if (angle > ps->normal_angle_inner) {
- mask *= (ps->normal_angle - angle) / ps->normal_angle_range;
- } /* otherwise no mask normal is needed, were within the limit */
- }
-
- /* This only works when the opacity dosnt change while painting, stylus pressure messes with this
- * so don't use it. */
- // if (ps->is_airbrush == 0) mask *= BKE_brush_alpha_get(ps->brush);
-
- return mask;
-}
-
-static int project_paint_pixel_sizeof(const short tool)
-{
- if ((tool == PAINT_TOOL_CLONE) || (tool == PAINT_TOOL_SMEAR)) {
- return sizeof(ProjPixelClone);
- }
- else {
- return sizeof(ProjPixel);
- }
-}
-
-
-/* run this function when we know a bucket's, face's pixel can be initialized,
- * return the ProjPixel which is added to 'ps->bucketRect[bucket_index]' */
-static ProjPixel *project_paint_uvpixel_init(
- const ProjPaintState *ps,
- MemArena *arena,
- const ImBuf *ibuf,
- short x_px, short y_px,
- const float mask,
- const int face_index,
- const int image_index,
- const float pixelScreenCo[4],
- const float world_spaceCo[3],
- const int side,
- const float w[3])
-{
- ProjPixel *projPixel;
-
- /* wrap pixel location */
- x_px = x_px % ibuf->x;
- if (x_px < 0) x_px += ibuf->x;
- y_px = y_px % ibuf->y;
- if (y_px < 0) y_px += ibuf->y;
-
- BLI_assert(ps->pixel_sizeof == project_paint_pixel_sizeof(ps->tool));
- projPixel = (ProjPixel *)BLI_memarena_alloc(arena, ps->pixel_sizeof);
- //memset(projPixel, 0, size);
-
- if (ibuf->rect_float) {
- projPixel->pixel.f_pt = ibuf->rect_float + ((x_px + y_px * ibuf->x) * 4);
- projPixel->origColor.f[0] = projPixel->newColor.f[0] = projPixel->pixel.f_pt[0];
- projPixel->origColor.f[1] = projPixel->newColor.f[1] = projPixel->pixel.f_pt[1];
- projPixel->origColor.f[2] = projPixel->newColor.f[2] = projPixel->pixel.f_pt[2];
- projPixel->origColor.f[3] = projPixel->newColor.f[3] = projPixel->pixel.f_pt[3];
- }
- else {
- projPixel->pixel.ch_pt = ((unsigned char *)ibuf->rect + ((x_px + y_px * ibuf->x) * 4));
- projPixel->origColor.uint = projPixel->newColor.uint = *projPixel->pixel.uint_pt;
- }
-
- /* screenspace unclamped, we could keep its z and w values but don't need them at the moment */
- if (ps->brush->mtex.brush_map_mode == MTEX_MAP_MODE_3D) {
- copy_v3_v3(projPixel->worldCoSS, world_spaceCo);
- }
-
- copy_v2_v2(projPixel->projCoSS, pixelScreenCo);
-
- projPixel->x_px = x_px;
- projPixel->y_px = y_px;
-
- projPixel->mask = (unsigned short)(mask * 65535);
- projPixel->mask_max = 0;
-
- /* which bounding box cell are we in?, needed for undo */
- projPixel->bb_cell_index = ((int)(((float)x_px / (float)ibuf->x) * PROJ_BOUNDBOX_DIV)) +
- ((int)(((float)y_px / (float)ibuf->y) * PROJ_BOUNDBOX_DIV)) * PROJ_BOUNDBOX_DIV;
-
- /* done with view3d_project_float inline */
- if (ps->tool == PAINT_TOOL_CLONE) {
- if (ps->dm_mtface_clone) {
- ImBuf *ibuf_other;
- Image *other_tpage = project_paint_face_image(ps, ps->dm_mtface_clone, face_index);
- const MTFace *tf_other = ps->dm_mtface_clone + face_index;
-
- if (other_tpage && (ibuf_other = BKE_image_acquire_ibuf(other_tpage, NULL, NULL))) {
- /* BKE_image_acquire_ibuf - TODO - this may be slow */
-
- if (ibuf->rect_float) {
- if (ibuf_other->rect_float) { /* from float to float */
- project_face_pixel(tf_other, ibuf_other, w, side, NULL, ((ProjPixelClone *)projPixel)->clonepx.f);
- }
- else { /* from char to float */
- unsigned char rgba_ub[4];
- project_face_pixel(tf_other, ibuf_other, w, side, rgba_ub, NULL);
- IMAPAINT_CHAR_RGBA_TO_FLOAT(((ProjPixelClone *)projPixel)->clonepx.f, rgba_ub);
- }
- }
- else {
- if (ibuf_other->rect_float) { /* float to char */
- float rgba[4];
- project_face_pixel(tf_other, ibuf_other, w, side, NULL, rgba);
- IMAPAINT_FLOAT_RGBA_TO_CHAR(((ProjPixelClone *)projPixel)->clonepx.ch, rgba);
- }
- else { /* char to char */
- project_face_pixel(tf_other, ibuf_other, w, side, ((ProjPixelClone *)projPixel)->clonepx.ch, NULL);
- }
- }
-
- BKE_image_release_ibuf(other_tpage, ibuf_other, NULL);
- }
- else {
- if (ibuf->rect_float) {
- ((ProjPixelClone *)projPixel)->clonepx.f[3] = 0;
- }
- else {
- ((ProjPixelClone *)projPixel)->clonepx.ch[3] = 0;
- }
- }
-
- }
- else {
- float co[2];
- sub_v2_v2v2(co, projPixel->projCoSS, (float *)ps->cloneOffset);
-
- /* no need to initialize the bucket, we're only checking buckets faces and for this
- * the faces are already initialized in project_paint_delayed_face_init(...) */
- if (ibuf->rect_float) {
- if (!project_paint_PickColor(ps, co, ((ProjPixelClone *)projPixel)->clonepx.f, NULL, 1)) {
- ((ProjPixelClone *)projPixel)->clonepx.f[3] = 0; /* zero alpha - ignore */
- }
- }
- else {
- if (!project_paint_PickColor(ps, co, NULL, ((ProjPixelClone *)projPixel)->clonepx.ch, 1)) {
- ((ProjPixelClone *)projPixel)->clonepx.ch[3] = 0; /* zero alpha - ignore */
- }
- }
- }
- }
-
-#ifdef PROJ_DEBUG_PAINT
- if (ibuf->rect_float) projPixel->pixel.f_pt[0] = 0;
- else projPixel->pixel.ch_pt[0] = 0;
-#endif
- projPixel->image_index = image_index;
-
- return projPixel;
-}
-
-static int line_clip_rect2f(
- rctf *rect,
- const float l1[2], const float l2[2],
- float l1_clip[2], float l2_clip[2])
-{
- /* first account for horizontal, then vertical lines */
- /* horiz */
- if (fabsf(l1[1] - l2[1]) < PROJ_GEOM_TOLERANCE) {
- /* is the line out of range on its Y axis? */
- if (l1[1] < rect->ymin || l1[1] > rect->ymax) {
- return 0;
- }
- /* line is out of range on its X axis */
- if ((l1[0] < rect->xmin && l2[0] < rect->xmin) || (l1[0] > rect->xmax && l2[0] > rect->xmax)) {
- return 0;
- }
-
-
- if (fabsf(l1[0] - l2[0]) < PROJ_GEOM_TOLERANCE) { /* this is a single point (or close to)*/
- if (BLI_rctf_isect_pt_v(rect, l1)) {
- copy_v2_v2(l1_clip, l1);
- copy_v2_v2(l2_clip, l2);
- return 1;
- }
- else {
- return 0;
- }
- }
-
- copy_v2_v2(l1_clip, l1);
- copy_v2_v2(l2_clip, l2);
- CLAMP(l1_clip[0], rect->xmin, rect->xmax);
- CLAMP(l2_clip[0], rect->xmin, rect->xmax);
- return 1;
- }
- else if (fabsf(l1[0] - l2[0]) < PROJ_GEOM_TOLERANCE) {
- /* is the line out of range on its X axis? */
- if (l1[0] < rect->xmin || l1[0] > rect->xmax) {
- return 0;
- }
-
- /* line is out of range on its Y axis */
- if ((l1[1] < rect->ymin && l2[1] < rect->ymin) || (l1[1] > rect->ymax && l2[1] > rect->ymax)) {
- return 0;
- }
-
- if (fabsf(l1[1] - l2[1]) < PROJ_GEOM_TOLERANCE) { /* this is a single point (or close to)*/
- if (BLI_rctf_isect_pt_v(rect, l1)) {
- copy_v2_v2(l1_clip, l1);
- copy_v2_v2(l2_clip, l2);
- return 1;
- }
- else {
- return 0;
- }
- }
-
- copy_v2_v2(l1_clip, l1);
- copy_v2_v2(l2_clip, l2);
- CLAMP(l1_clip[1], rect->ymin, rect->ymax);
- CLAMP(l2_clip[1], rect->ymin, rect->ymax);
- return 1;
- }
- else {
- float isect;
- short ok1 = 0;
- short ok2 = 0;
-
- /* Done with vertical lines */
-
- /* are either of the points inside the rectangle ? */
- if (BLI_rctf_isect_pt_v(rect, l1)) {
- copy_v2_v2(l1_clip, l1);
- ok1 = 1;
- }
-
- if (BLI_rctf_isect_pt_v(rect, l2)) {
- copy_v2_v2(l2_clip, l2);
- ok2 = 1;
- }
-
- /* line inside rect */
- if (ok1 && ok2) return 1;
-
- /* top/bottom */
- if (line_isect_y(l1, l2, rect->ymin, &isect) && (isect >= rect->xmin) && (isect <= rect->xmax)) {
- if (l1[1] < l2[1]) { /* line 1 is outside */
- l1_clip[0] = isect;
- l1_clip[1] = rect->ymin;
- ok1 = 1;
- }
- else {
- l2_clip[0] = isect;
- l2_clip[1] = rect->ymin;
- ok2 = 2;
- }
- }
-
- if (ok1 && ok2) return 1;
-
- if (line_isect_y(l1, l2, rect->ymax, &isect) && (isect >= rect->xmin) && (isect <= rect->xmax)) {
- if (l1[1] > l2[1]) { /* line 1 is outside */
- l1_clip[0] = isect;
- l1_clip[1] = rect->ymax;
- ok1 = 1;
- }
- else {
- l2_clip[0] = isect;
- l2_clip[1] = rect->ymax;
- ok2 = 2;
- }
- }
-
- if (ok1 && ok2) return 1;
-
- /* left/right */
- if (line_isect_x(l1, l2, rect->xmin, &isect) && (isect >= rect->ymin) && (isect <= rect->ymax)) {
- if (l1[0] < l2[0]) { /* line 1 is outside */
- l1_clip[0] = rect->xmin;
- l1_clip[1] = isect;
- ok1 = 1;
- }
- else {
- l2_clip[0] = rect->xmin;
- l2_clip[1] = isect;
- ok2 = 2;
- }
- }
-
- if (ok1 && ok2) return 1;
-
- if (line_isect_x(l1, l2, rect->xmax, &isect) && (isect >= rect->ymin) && (isect <= rect->ymax)) {
- if (l1[0] > l2[0]) { /* line 1 is outside */
- l1_clip[0] = rect->xmax;
- l1_clip[1] = isect;
- ok1 = 1;
- }
- else {
- l2_clip[0] = rect->xmax;
- l2_clip[1] = isect;
- ok2 = 2;
- }
- }
-
- if (ok1 && ok2) {
- return 1;
- }
- else {
- return 0;
- }
- }
-}
-
-
-
-/* scale the quad & tri about its center
- * scaling by PROJ_FACE_SCALE_SEAM (0.99x) is used for getting fake UV pixel coords that are on the
- * edge of the face but slightly inside it occlusion tests don't return hits on adjacent faces */
-#ifndef PROJ_DEBUG_NOSEAMBLEED
-static void scale_quad(float insetCos[4][3], float *origCos[4], const float inset)
-{
- float cent[3];
- cent[0] = (origCos[0][0] + origCos[1][0] + origCos[2][0] + origCos[3][0]) / 4.0f;
- cent[1] = (origCos[0][1] + origCos[1][1] + origCos[2][1] + origCos[3][1]) / 4.0f;
- cent[2] = (origCos[0][2] + origCos[1][2] + origCos[2][2] + origCos[3][2]) / 4.0f;
-
- sub_v3_v3v3(insetCos[0], origCos[0], cent);
- sub_v3_v3v3(insetCos[1], origCos[1], cent);
- sub_v3_v3v3(insetCos[2], origCos[2], cent);
- sub_v3_v3v3(insetCos[3], origCos[3], cent);
-
- mul_v3_fl(insetCos[0], inset);
- mul_v3_fl(insetCos[1], inset);
- mul_v3_fl(insetCos[2], inset);
- mul_v3_fl(insetCos[3], inset);
-
- add_v3_v3(insetCos[0], cent);
- add_v3_v3(insetCos[1], cent);
- add_v3_v3(insetCos[2], cent);
- add_v3_v3(insetCos[3], cent);
-}
-
-
-static void scale_tri(float insetCos[4][3], float *origCos[4], const float inset)
-{
- float cent[3];
- cent[0] = (origCos[0][0] + origCos[1][0] + origCos[2][0]) / 3.0f;
- cent[1] = (origCos[0][1] + origCos[1][1] + origCos[2][1]) / 3.0f;
- cent[2] = (origCos[0][2] + origCos[1][2] + origCos[2][2]) / 3.0f;
-
- sub_v3_v3v3(insetCos[0], origCos[0], cent);
- sub_v3_v3v3(insetCos[1], origCos[1], cent);
- sub_v3_v3v3(insetCos[2], origCos[2], cent);
-
- mul_v3_fl(insetCos[0], inset);
- mul_v3_fl(insetCos[1], inset);
- mul_v3_fl(insetCos[2], inset);
-
- add_v3_v3(insetCos[0], cent);
- add_v3_v3(insetCos[1], cent);
- add_v3_v3(insetCos[2], cent);
-}
-#endif //PROJ_DEBUG_NOSEAMBLEED
-
-static float len_squared_v2v2_alt(const float *v1, const float v2_1, const float v2_2)
-{
- float x, y;
-
- x = v1[0] - v2_1;
- y = v1[1] - v2_2;
- return x * x + y * y;
-}
-
-/* note, use a squared value so we can use len_squared_v2v2
- * be sure that you have done a bounds check first or this may fail */
-/* only give bucket_bounds as an arg because we need it elsewhere */
-static int project_bucket_isect_circle(const float cent[2], const float radius_squared, rctf *bucket_bounds)
-{
-
- /* Would normally to a simple intersection test, however we know the bounds of these 2 already intersect
- * so we only need to test if the center is inside the vertical or horizontal bounds on either axis,
- * this is even less work then an intersection test
- */
-#if 0
- if (BLI_rctf_isect_pt_v(bucket_bounds, cent))
- return 1;
-#endif
-
- if ((bucket_bounds->xmin <= cent[0] && bucket_bounds->xmax >= cent[0]) ||
- (bucket_bounds->ymin <= cent[1] && bucket_bounds->ymax >= cent[1]))
- {
- return 1;
- }
-
- /* out of bounds left */
- if (cent[0] < bucket_bounds->xmin) {
- /* lower left out of radius test */
- if (cent[1] < bucket_bounds->ymin) {
- return (len_squared_v2v2_alt(cent, bucket_bounds->xmin, bucket_bounds->ymin) < radius_squared) ? 1 : 0;
- }
- /* top left test */
- else if (cent[1] > bucket_bounds->ymax) {
- return (len_squared_v2v2_alt(cent, bucket_bounds->xmin, bucket_bounds->ymax) < radius_squared) ? 1 : 0;
- }
- }
- else if (cent[0] > bucket_bounds->xmax) {
- /* lower right out of radius test */
- if (cent[1] < bucket_bounds->ymin) {
- return (len_squared_v2v2_alt(cent, bucket_bounds->xmax, bucket_bounds->ymin) < radius_squared) ? 1 : 0;
- }
- /* top right test */
- else if (cent[1] > bucket_bounds->ymax) {
- return (len_squared_v2v2_alt(cent, bucket_bounds->xmax, bucket_bounds->ymax) < radius_squared) ? 1 : 0;
- }
- }
-
- return 0;
-}
-
-
-
-/* Note for rect_to_uvspace_ortho() and rect_to_uvspace_persp()
- * in ortho view this function gives good results when bucket_bounds are outside the triangle
- * however in some cases, perspective view will mess up with faces that have minimal screenspace area
- * (viewed from the side)
- *
- * for this reason its not reliable in this case so we'll use the Simple Barycentric'
- * funcs that only account for points inside the triangle.
- * however switching back to this for ortho is always an option */
-
-static void rect_to_uvspace_ortho(
- rctf *bucket_bounds,
- float *v1coSS, float *v2coSS, float *v3coSS,
- float *uv1co, float *uv2co, float *uv3co,
- float bucket_bounds_uv[4][2],
- const int flip)
-{
- float uv[2];
- float w[3];
-
- /* get the UV space bounding box */
- uv[0] = bucket_bounds->xmax;
- uv[1] = bucket_bounds->ymin;
- barycentric_weights_v2(v1coSS, v2coSS, v3coSS, uv, w);
- interp_v2_v2v2v2(bucket_bounds_uv[flip ? 3 : 0], uv1co, uv2co, uv3co, w);
-
- //uv[0] = bucket_bounds->xmax; // set above
- uv[1] = bucket_bounds->ymax;
- barycentric_weights_v2(v1coSS, v2coSS, v3coSS, uv, w);
- interp_v2_v2v2v2(bucket_bounds_uv[flip ? 2 : 1], uv1co, uv2co, uv3co, w);
-
- uv[0] = bucket_bounds->xmin;
- //uv[1] = bucket_bounds->ymax; // set above
- barycentric_weights_v2(v1coSS, v2coSS, v3coSS, uv, w);
- interp_v2_v2v2v2(bucket_bounds_uv[flip ? 1 : 2], uv1co, uv2co, uv3co, w);
-
- //uv[0] = bucket_bounds->xmin; // set above
- uv[1] = bucket_bounds->ymin;
- barycentric_weights_v2(v1coSS, v2coSS, v3coSS, uv, w);
- interp_v2_v2v2v2(bucket_bounds_uv[flip ? 0 : 3], uv1co, uv2co, uv3co, w);
-}
-
-/* same as above but use barycentric_weights_v2_persp */
-static void rect_to_uvspace_persp(
- rctf *bucket_bounds,
- float *v1coSS, float *v2coSS, float *v3coSS,
- float *uv1co, float *uv2co, float *uv3co,
- float bucket_bounds_uv[4][2],
- const int flip
- )
-{
- float uv[2];
- float w[3];
-
- /* get the UV space bounding box */
- uv[0] = bucket_bounds->xmax;
- uv[1] = bucket_bounds->ymin;
- barycentric_weights_v2_persp(v1coSS, v2coSS, v3coSS, uv, w);
- interp_v2_v2v2v2(bucket_bounds_uv[flip ? 3 : 0], uv1co, uv2co, uv3co, w);
-
- //uv[0] = bucket_bounds->xmax; // set above
- uv[1] = bucket_bounds->ymax;
- barycentric_weights_v2_persp(v1coSS, v2coSS, v3coSS, uv, w);
- interp_v2_v2v2v2(bucket_bounds_uv[flip ? 2 : 1], uv1co, uv2co, uv3co, w);
-
- uv[0] = bucket_bounds->xmin;
- //uv[1] = bucket_bounds->ymax; // set above
- barycentric_weights_v2_persp(v1coSS, v2coSS, v3coSS, uv, w);
- interp_v2_v2v2v2(bucket_bounds_uv[flip ? 1 : 2], uv1co, uv2co, uv3co, w);
-
- //uv[0] = bucket_bounds->xmin; // set above
- uv[1] = bucket_bounds->ymin;
- barycentric_weights_v2_persp(v1coSS, v2coSS, v3coSS, uv, w);
- interp_v2_v2v2v2(bucket_bounds_uv[flip ? 0 : 3], uv1co, uv2co, uv3co, w);
-}
-
-/* This works as we need it to but we can save a few steps and not use it */
-
-#if 0
-static float angle_2d_clockwise(const float p1[2], const float p2[2], const float p3[2])
-{
- float v1[2], v2[2];
-
- v1[0] = p1[0] - p2[0]; v1[1] = p1[1] - p2[1];
- v2[0] = p3[0] - p2[0]; v2[1] = p3[1] - p2[1];
-
- return -atan2(v1[0] * v2[1] - v1[1] * v2[0], v1[0] * v2[0] + v1[1] * v2[1]);
-}
-#endif
-
-#define ISECT_1 (1)
-#define ISECT_2 (1 << 1)
-#define ISECT_3 (1 << 2)
-#define ISECT_4 (1 << 3)
-#define ISECT_ALL3 ((1 << 3) - 1)
-#define ISECT_ALL4 ((1 << 4) - 1)
-
-/* limit must be a fraction over 1.0f */
-static int IsectPT2Df_limit(float pt[2], float v1[2], float v2[2], float v3[2], float limit)
-{
- return ((area_tri_v2(pt, v1, v2) + area_tri_v2(pt, v2, v3) + area_tri_v2(pt, v3, v1)) / (area_tri_v2(v1, v2, v3))) < limit;
-}
-
-/* Clip the face by a bucket and set the uv-space bucket_bounds_uv
- * so we have the clipped UV's to do pixel intersection tests with
- * */
-static int float_z_sort_flip(const void *p1, const void *p2)
-{
- return (((float *)p1)[2] < ((float *)p2)[2] ? 1 : -1);
-}
-
-static int float_z_sort(const void *p1, const void *p2)
-{
- return (((float *)p1)[2] < ((float *)p2)[2] ? -1 : 1);
-}
-
-static void project_bucket_clip_face(
- const int is_ortho,
- rctf *bucket_bounds,
- float *v1coSS, float *v2coSS, float *v3coSS,
- float *uv1co, float *uv2co, float *uv3co,
- float bucket_bounds_uv[8][2],
- int *tot)
-{
- int inside_bucket_flag = 0;
- int inside_face_flag = 0;
- const int flip = ((line_point_side_v2(v1coSS, v2coSS, v3coSS) > 0.0f) != (line_point_side_v2(uv1co, uv2co, uv3co) > 0.0f));
-
- float bucket_bounds_ss[4][2];
-
- /* get the UV space bounding box */
- inside_bucket_flag |= BLI_rctf_isect_pt_v(bucket_bounds, v1coSS);
- inside_bucket_flag |= BLI_rctf_isect_pt_v(bucket_bounds, v2coSS) << 1;
- inside_bucket_flag |= BLI_rctf_isect_pt_v(bucket_bounds, v3coSS) << 2;
-
- if (inside_bucket_flag == ISECT_ALL3) {
- /* all screenspace points are inside the bucket bounding box, this means we don't need to clip and can simply return the UVs */
- if (flip) { /* facing the back? */
- copy_v2_v2(bucket_bounds_uv[0], uv3co);
- copy_v2_v2(bucket_bounds_uv[1], uv2co);
- copy_v2_v2(bucket_bounds_uv[2], uv1co);
- }
- else {
- copy_v2_v2(bucket_bounds_uv[0], uv1co);
- copy_v2_v2(bucket_bounds_uv[1], uv2co);
- copy_v2_v2(bucket_bounds_uv[2], uv3co);
- }
-
- *tot = 3;
- return;
- }
-
- /* get the UV space bounding box */
- /* use IsectPT2Df_limit here so we catch points are are touching the tri edge (or a small fraction over) */
- bucket_bounds_ss[0][0] = bucket_bounds->xmax;
- bucket_bounds_ss[0][1] = bucket_bounds->ymin;
- inside_face_flag |= (IsectPT2Df_limit(bucket_bounds_ss[0], v1coSS, v2coSS, v3coSS, 1 + PROJ_GEOM_TOLERANCE) ? ISECT_1 : 0);
-
- bucket_bounds_ss[1][0] = bucket_bounds->xmax;
- bucket_bounds_ss[1][1] = bucket_bounds->ymax;
- inside_face_flag |= (IsectPT2Df_limit(bucket_bounds_ss[1], v1coSS, v2coSS, v3coSS, 1 + PROJ_GEOM_TOLERANCE) ? ISECT_2 : 0);
-
- bucket_bounds_ss[2][0] = bucket_bounds->xmin;
- bucket_bounds_ss[2][1] = bucket_bounds->ymax;
- inside_face_flag |= (IsectPT2Df_limit(bucket_bounds_ss[2], v1coSS, v2coSS, v3coSS, 1 + PROJ_GEOM_TOLERANCE) ? ISECT_3 : 0);
-
- bucket_bounds_ss[3][0] = bucket_bounds->xmin;
- bucket_bounds_ss[3][1] = bucket_bounds->ymin;
- inside_face_flag |= (IsectPT2Df_limit(bucket_bounds_ss[3], v1coSS, v2coSS, v3coSS, 1 + PROJ_GEOM_TOLERANCE) ? ISECT_4 : 0);
-
- if (inside_face_flag == ISECT_ALL4) {
- /* bucket is totally inside the screenspace face, we can safely use weights */
-
- if (is_ortho) rect_to_uvspace_ortho(bucket_bounds, v1coSS, v2coSS, v3coSS, uv1co, uv2co, uv3co, bucket_bounds_uv, flip);
- else rect_to_uvspace_persp(bucket_bounds, v1coSS, v2coSS, v3coSS, uv1co, uv2co, uv3co, bucket_bounds_uv, flip);
-
- *tot = 4;
- return;
- }
- else {
- /* The Complicated Case!
- *
- * The 2 cases above are where the face is inside the bucket or the bucket is inside the face.
- *
- * we need to make a convex polyline from the intersection between the screenspace face
- * and the bucket bounds.
- *
- * There are a number of ways this could be done, currently it just collects all intersecting verts,
- * and line intersections, then sorts them clockwise, this is a lot easier then evaluating the geometry to
- * do a correct clipping on both shapes. */
-
-
- /* add a bunch of points, we know must make up the convex hull which is the clipped rect and triangle */
-
-
-
- /* Maximum possible 6 intersections when using a rectangle and triangle */
- float isectVCosSS[8][3]; /* The 3rd float is used to store angle for qsort(), NOT as a Z location */
- float v1_clipSS[2], v2_clipSS[2];
- float w[3];
-
- /* calc center */
- float cent[2] = {0.0f, 0.0f};
- /*float up[2] = {0.0f, 1.0f};*/
- int i;
- short doubles;
-
- (*tot) = 0;
-
- if (inside_face_flag & ISECT_1) { copy_v2_v2(isectVCosSS[*tot], bucket_bounds_ss[0]); (*tot)++; }
- if (inside_face_flag & ISECT_2) { copy_v2_v2(isectVCosSS[*tot], bucket_bounds_ss[1]); (*tot)++; }
- if (inside_face_flag & ISECT_3) { copy_v2_v2(isectVCosSS[*tot], bucket_bounds_ss[2]); (*tot)++; }
- if (inside_face_flag & ISECT_4) { copy_v2_v2(isectVCosSS[*tot], bucket_bounds_ss[3]); (*tot)++; }
-
- if (inside_bucket_flag & ISECT_1) { copy_v2_v2(isectVCosSS[*tot], v1coSS); (*tot)++; }
- if (inside_bucket_flag & ISECT_2) { copy_v2_v2(isectVCosSS[*tot], v2coSS); (*tot)++; }
- if (inside_bucket_flag & ISECT_3) { copy_v2_v2(isectVCosSS[*tot], v3coSS); (*tot)++; }
-
- if ((inside_bucket_flag & (ISECT_1 | ISECT_2)) != (ISECT_1 | ISECT_2)) {
- if (line_clip_rect2f(bucket_bounds, v1coSS, v2coSS, v1_clipSS, v2_clipSS)) {
- if ((inside_bucket_flag & ISECT_1) == 0) { copy_v2_v2(isectVCosSS[*tot], v1_clipSS); (*tot)++; }
- if ((inside_bucket_flag & ISECT_2) == 0) { copy_v2_v2(isectVCosSS[*tot], v2_clipSS); (*tot)++; }
- }
- }
-
- if ((inside_bucket_flag & (ISECT_2 | ISECT_3)) != (ISECT_2 | ISECT_3)) {
- if (line_clip_rect2f(bucket_bounds, v2coSS, v3coSS, v1_clipSS, v2_clipSS)) {
- if ((inside_bucket_flag & ISECT_2) == 0) { copy_v2_v2(isectVCosSS[*tot], v1_clipSS); (*tot)++; }
- if ((inside_bucket_flag & ISECT_3) == 0) { copy_v2_v2(isectVCosSS[*tot], v2_clipSS); (*tot)++; }
- }
- }
-
- if ((inside_bucket_flag & (ISECT_3 | ISECT_1)) != (ISECT_3 | ISECT_1)) {
- if (line_clip_rect2f(bucket_bounds, v3coSS, v1coSS, v1_clipSS, v2_clipSS)) {
- if ((inside_bucket_flag & ISECT_3) == 0) { copy_v2_v2(isectVCosSS[*tot], v1_clipSS); (*tot)++; }
- if ((inside_bucket_flag & ISECT_1) == 0) { copy_v2_v2(isectVCosSS[*tot], v2_clipSS); (*tot)++; }
- }
- }
-
-
- if ((*tot) < 3) { /* no intersections to speak of */
- *tot = 0;
- return;
- }
-
- /* now we have all points we need, collect their angles and sort them clockwise */
-
- for (i = 0; i < (*tot); i++) {
- cent[0] += isectVCosSS[i][0];
- cent[1] += isectVCosSS[i][1];
- }
- cent[0] = cent[0] / (float)(*tot);
- cent[1] = cent[1] / (float)(*tot);
-
-
-
- /* Collect angles for every point around the center point */
-
-
-#if 0 /* uses a few more cycles then the above loop */
- for (i = 0; i < (*tot); i++) {
- isectVCosSS[i][2] = angle_2d_clockwise(up, cent, isectVCosSS[i]);
- }
-#endif
-
- v1_clipSS[0] = cent[0]; /* Abuse this var for the loop below */
- v1_clipSS[1] = cent[1] + 1.0f;
-
- for (i = 0; i < (*tot); i++) {
- v2_clipSS[0] = isectVCosSS[i][0] - cent[0];
- v2_clipSS[1] = isectVCosSS[i][1] - cent[1];
- isectVCosSS[i][2] = atan2f(v1_clipSS[0] * v2_clipSS[1] - v1_clipSS[1] * v2_clipSS[0], v1_clipSS[0] * v2_clipSS[0] + v1_clipSS[1] * v2_clipSS[1]);
- }
-
- if (flip) qsort(isectVCosSS, *tot, sizeof(float) * 3, float_z_sort_flip);
- else qsort(isectVCosSS, *tot, sizeof(float) * 3, float_z_sort);
-
- /* remove doubles */
- /* first/last check */
- if (fabsf(isectVCosSS[0][0] - isectVCosSS[(*tot) - 1][0]) < PROJ_GEOM_TOLERANCE &&
- fabsf(isectVCosSS[0][1] - isectVCosSS[(*tot) - 1][1]) < PROJ_GEOM_TOLERANCE)
- {
- (*tot)--;
- }
-
- /* its possible there is only a few left after remove doubles */
- if ((*tot) < 3) {
- // printf("removed too many doubles A\n");
- *tot = 0;
- return;
- }
-
- doubles = TRUE;
- while (doubles == TRUE) {
- doubles = FALSE;
- for (i = 1; i < (*tot); i++) {
- if (fabsf(isectVCosSS[i - 1][0] - isectVCosSS[i][0]) < PROJ_GEOM_TOLERANCE &&
- fabsf(isectVCosSS[i - 1][1] - isectVCosSS[i][1]) < PROJ_GEOM_TOLERANCE)
- {
- int j;
- for (j = i + 1; j < (*tot); j++) {
- isectVCosSS[j - 1][0] = isectVCosSS[j][0];
- isectVCosSS[j - 1][1] = isectVCosSS[j][1];
- }
- doubles = TRUE; /* keep looking for more doubles */
- (*tot)--;
- }
- }
- }
-
- /* its possible there is only a few left after remove doubles */
- if ((*tot) < 3) {
- // printf("removed too many doubles B\n");
- *tot = 0;
- return;
- }
-
-
- if (is_ortho) {
- for (i = 0; i < (*tot); i++) {
- barycentric_weights_v2(v1coSS, v2coSS, v3coSS, isectVCosSS[i], w);
- interp_v2_v2v2v2(bucket_bounds_uv[i], uv1co, uv2co, uv3co, w);
- }
- }
- else {
- for (i = 0; i < (*tot); i++) {
- barycentric_weights_v2_persp(v1coSS, v2coSS, v3coSS, isectVCosSS[i], w);
- interp_v2_v2v2v2(bucket_bounds_uv[i], uv1co, uv2co, uv3co, w);
- }
- }
- }
-
-#ifdef PROJ_DEBUG_PRINT_CLIP
- /* include this at the bottom of the above function to debug the output */
-
- {
- /* If there are ever any problems, */
- float test_uv[4][2];
- int i;
- if (is_ortho) rect_to_uvspace_ortho(bucket_bounds, v1coSS, v2coSS, v3coSS, uv1co, uv2co, uv3co, test_uv, flip);
- else rect_to_uvspace_persp(bucket_bounds, v1coSS, v2coSS, v3coSS, uv1co, uv2co, uv3co, test_uv, flip);
- printf("( [(%f,%f), (%f,%f), (%f,%f), (%f,%f)], ", test_uv[0][0], test_uv[0][1], test_uv[1][0], test_uv[1][1], test_uv[2][0], test_uv[2][1], test_uv[3][0], test_uv[3][1]);
-
- printf(" [(%f,%f), (%f,%f), (%f,%f)], ", uv1co[0], uv1co[1], uv2co[0], uv2co[1], uv3co[0], uv3co[1]);
-
- printf("[");
- for (i = 0; i < (*tot); i++) {
- printf("(%f, %f),", bucket_bounds_uv[i][0], bucket_bounds_uv[i][1]);
- }
- printf("]),\\\n");
- }
-#endif
-}
-
-/*
- * # This script creates faces in a blender scene from printed data above.
- *
- * project_ls = [
- * ...(output from above block)...
- * ]
- *
- * from Blender import Scene, Mesh, Window, sys, Mathutils
- *
- * import bpy
- *
- * V = Mathutils.Vector
- *
- * def main():
- * sce = bpy.data.scenes.active
- *
- * for item in project_ls:
- * bb = item[0]
- * uv = item[1]
- * poly = item[2]
- *
- * me = bpy.data.meshes.new()
- * ob = sce.objects.new(me)
- *
- * me.verts.extend([V(bb[0]).xyz, V(bb[1]).xyz, V(bb[2]).xyz, V(bb[3]).xyz])
- * me.faces.extend([(0,1,2,3),])
- * me.verts.extend([V(uv[0]).xyz, V(uv[1]).xyz, V(uv[2]).xyz])
- * me.faces.extend([(4,5,6),])
- *
- * vs = [V(p).xyz for p in poly]
- * print len(vs)
- * l = len(me.verts)
- * me.verts.extend(vs)
- *
- * i = l
- * while i < len(me.verts):
- * ii = i + 1
- * if ii == len(me.verts):
- * ii = l
- * me.edges.extend([i, ii])
- * i += 1
- *
- * if __name__ == '__main__':
- * main()
- */
-
-
-#undef ISECT_1
-#undef ISECT_2
-#undef ISECT_3
-#undef ISECT_4
-#undef ISECT_ALL3
-#undef ISECT_ALL4
-
-
-/* checks if pt is inside a convex 2D polyline, the polyline must be ordered rotating clockwise
- * otherwise it would have to test for mixed (line_point_side_v2 > 0.0f) cases */
-static int IsectPoly2Df(const float pt[2], float uv[][2], const int tot)
-{
- int i;
- if (line_point_side_v2(uv[tot - 1], uv[0], pt) < 0.0f)
- return 0;
-
- for (i = 1; i < tot; i++) {
- if (line_point_side_v2(uv[i - 1], uv[i], pt) < 0.0f)
- return 0;
-
- }
-
- return 1;
-}
-static int IsectPoly2Df_twoside(const float pt[2], float uv[][2], const int tot)
-{
- int i;
- int side = (line_point_side_v2(uv[tot - 1], uv[0], pt) > 0.0f);
-
- for (i = 1; i < tot; i++) {
- if ((line_point_side_v2(uv[i - 1], uv[i], pt) > 0.0f) != side)
- return 0;
-
- }
-
- return 1;
-}
-
-/* One of the most important function for projection painting, since it selects the pixels to be added into each bucket.
- * initialize pixels from this face where it intersects with the bucket_index, optionally initialize pixels for removing seams */
-static void project_paint_face_init(const ProjPaintState *ps, const int thread_index, const int bucket_index, const int face_index, const int image_index, rctf *bucket_bounds, const ImBuf *ibuf, const short clamp_u, const short clamp_v)
-{
- /* Projection vars, to get the 3D locations into screen space */
- MemArena *arena = ps->arena_mt[thread_index];
- LinkNode **bucketPixelNodes = ps->bucketRect + bucket_index;
- LinkNode *bucketFaceNodes = ps->bucketFaces[bucket_index];
-
- const MFace *mf = ps->dm_mface + face_index;
- const MTFace *tf = ps->dm_mtface + face_index;
-
- /* UV/pixel seeking data */
- int x; /* Image X-Pixel */
- int y; /* Image Y-Pixel */
- float mask;
- float uv[2]; /* Image floating point UV - same as x, y but from 0.0-1.0 */
-
- int side;
- float *v1coSS, *v2coSS, *v3coSS; /* vert co screen-space, these will be assigned to mf->v1,2,3 or mf->v1,3,4 */
-
- float *vCo[4]; /* vertex screenspace coords */
-
- float w[3], wco[3];
-
- float *uv1co, *uv2co, *uv3co; /* for convenience only, these will be assigned to tf->uv[0],1,2 or tf->uv[0],2,3 */
- float pixelScreenCo[4];
- bool do_3d_mapping = ps->brush->mtex.brush_map_mode == MTEX_MAP_MODE_3D;
-
- rcti bounds_px; /* ispace bounds */
- /* vars for getting uvspace bounds */
-
- float tf_uv_pxoffset[4][2]; /* bucket bounds in UV space so we can init pixels only for this face, */
- float xhalfpx, yhalfpx;
- const float ibuf_xf = (float)ibuf->x, ibuf_yf = (float)ibuf->y;
-
- int has_x_isect = 0, has_isect = 0; /* for early loop exit */
-
- int i1, i2, i3;
-
- float uv_clip[8][2];
- int uv_clip_tot;
- const short is_ortho = ps->is_ortho;
- const short do_backfacecull = ps->do_backfacecull;
- const short do_clip = ps->rv3d ? ps->rv3d->rflag & RV3D_CLIPPING : 0;
-
- vCo[0] = ps->dm_mvert[mf->v1].co;
- vCo[1] = ps->dm_mvert[mf->v2].co;
- vCo[2] = ps->dm_mvert[mf->v3].co;
-
-
- /* Use tf_uv_pxoffset instead of tf->uv so we can offset the UV half a pixel
- * this is done so we can avoid offsetting all the pixels by 0.5 which causes
- * problems when wrapping negative coords */
- xhalfpx = (0.5f + (PROJ_GEOM_TOLERANCE / 3.0f)) / ibuf_xf;
- yhalfpx = (0.5f + (PROJ_GEOM_TOLERANCE / 4.0f)) / ibuf_yf;
-
- /* Note about (PROJ_GEOM_TOLERANCE/x) above...
- * Needed to add this offset since UV coords are often quads aligned to pixels.
- * In this case pixels can be exactly between 2 triangles causing nasty
- * artifacts.
- *
- * This workaround can be removed and painting will still work on most cases
- * but since the first thing most people try is painting onto a quad- better make it work.
- */
-
-
-
- tf_uv_pxoffset[0][0] = tf->uv[0][0] - xhalfpx;
- tf_uv_pxoffset[0][1] = tf->uv[0][1] - yhalfpx;
-
- tf_uv_pxoffset[1][0] = tf->uv[1][0] - xhalfpx;
- tf_uv_pxoffset[1][1] = tf->uv[1][1] - yhalfpx;
-
- tf_uv_pxoffset[2][0] = tf->uv[2][0] - xhalfpx;
- tf_uv_pxoffset[2][1] = tf->uv[2][1] - yhalfpx;
-
- if (mf->v4) {
- vCo[3] = ps->dm_mvert[mf->v4].co;
-
- tf_uv_pxoffset[3][0] = tf->uv[3][0] - xhalfpx;
- tf_uv_pxoffset[3][1] = tf->uv[3][1] - yhalfpx;
- side = 1;
- }
- else {
- side = 0;
- }
-
- do {
- if (side == 1) {
- i1 = 0; i2 = 2; i3 = 3;
- }
- else {
- i1 = 0; i2 = 1; i3 = 2;
- }
-
- uv1co = tf_uv_pxoffset[i1]; // was tf->uv[i1];
- uv2co = tf_uv_pxoffset[i2]; // was tf->uv[i2];
- uv3co = tf_uv_pxoffset[i3]; // was tf->uv[i3];
-
- v1coSS = ps->screenCoords[(*(&mf->v1 + i1))];
- v2coSS = ps->screenCoords[(*(&mf->v1 + i2))];
- v3coSS = ps->screenCoords[(*(&mf->v1 + i3))];
-
- /* This funtion gives is a concave polyline in UV space from the clipped quad and tri*/
- project_bucket_clip_face(
- is_ortho, bucket_bounds,
- v1coSS, v2coSS, v3coSS,
- uv1co, uv2co, uv3co,
- uv_clip, &uv_clip_tot
- );
-
- /* sometimes this happens, better just allow for 8 intersectiosn even though there should be max 6 */
-#if 0
- if (uv_clip_tot > 6) {
- printf("this should never happen! %d\n", uv_clip_tot);
- }
-#endif
-
- if (pixel_bounds_array(uv_clip, &bounds_px, ibuf->x, ibuf->y, uv_clip_tot)) {
-
- if (clamp_u) {
- CLAMP(bounds_px.xmin, 0, ibuf->x);
- CLAMP(bounds_px.xmax, 0, ibuf->x);
- }
-
- if (clamp_v) {
- CLAMP(bounds_px.ymin, 0, ibuf->y);
- CLAMP(bounds_px.ymax, 0, ibuf->y);
- }
-
- /* clip face and */
-
- has_isect = 0;
- for (y = bounds_px.ymin; y < bounds_px.ymax; y++) {
- //uv[1] = (((float)y) + 0.5f) / (float)ibuf->y;
- uv[1] = (float)y / ibuf_yf; /* use pixel offset UV coords instead */
-
- has_x_isect = 0;
- for (x = bounds_px.xmin; x < bounds_px.xmax; x++) {
- //uv[0] = (((float)x) + 0.5f) / ibuf->x;
- uv[0] = (float)x / ibuf_xf; /* use pixel offset UV coords instead */
-
- /* Note about IsectPoly2Df_twoside, checking the face or uv flipping doesnt work,
- * could check the poly direction but better to do this */
- if ((do_backfacecull == TRUE && IsectPoly2Df(uv, uv_clip, uv_clip_tot)) ||
- (do_backfacecull == FALSE && IsectPoly2Df_twoside(uv, uv_clip, uv_clip_tot)))
- {
-
- has_x_isect = has_isect = 1;
-
- if (is_ortho) screen_px_from_ortho(uv, v1coSS, v2coSS, v3coSS, uv1co, uv2co, uv3co, pixelScreenCo, w);
- else screen_px_from_persp(uv, v1coSS, v2coSS, v3coSS, uv1co, uv2co, uv3co, pixelScreenCo, w);
-
- /* a pity we need to get the worldspace pixel location here */
- if (do_clip || do_3d_mapping) {
- interp_v3_v3v3v3(wco, ps->dm_mvert[(*(&mf->v1 + i1))].co, ps->dm_mvert[(*(&mf->v1 + i2))].co, ps->dm_mvert[(*(&mf->v1 + i3))].co, w);
- if (do_clip && ED_view3d_clipping_test(ps->rv3d, wco, TRUE)) {
- continue; /* Watch out that no code below this needs to run */
- }
- }
-
- /* Is this UV visible from the view? - raytrace */
- /* project_paint_PickFace is less complex, use for testing */
- //if (project_paint_PickFace(ps, pixelScreenCo, w, &side) == face_index) {
- if ((ps->do_occlude == FALSE) ||
- !project_bucket_point_occluded(ps, bucketFaceNodes, face_index, pixelScreenCo))
- {
- mask = project_paint_uvpixel_mask(ps, face_index, side, w);
-
- if (mask > 0.0f) {
- BLI_linklist_prepend_arena(
- bucketPixelNodes,
- project_paint_uvpixel_init(ps, arena, ibuf, x, y, mask, face_index,
- image_index, pixelScreenCo, wco, side, w),
- arena
- );
- }
- }
-
- }
-//#if 0
- else if (has_x_isect) {
- /* assuming the face is not a bow-tie - we know we cant intersect again on the X */
- break;
- }
-//#endif
- }
-
-
-#if 0 /* TODO - investigate why this dosnt work sometimes! it should! */
- /* no intersection for this entire row, after some intersection above means we can quit now */
- if (has_x_isect == 0 && has_isect) {
- break;
- }
-#endif
- }
- }
- } while (side--);
-
-
-
-#ifndef PROJ_DEBUG_NOSEAMBLEED
- if (ps->seam_bleed_px > 0.0f) {
- int face_seam_flag;
-
- if (ps->thread_tot > 1)
- BLI_lock_thread(LOCK_CUSTOM1); /* Other threads could be modifying these vars */
-
- face_seam_flag = ps->faceSeamFlags[face_index];
-
- /* are any of our edges un-initialized? */
- if ((face_seam_flag & (PROJ_FACE_SEAM1 | PROJ_FACE_NOSEAM1)) == 0 ||
- (face_seam_flag & (PROJ_FACE_SEAM2 | PROJ_FACE_NOSEAM2)) == 0 ||
- (face_seam_flag & (PROJ_FACE_SEAM3 | PROJ_FACE_NOSEAM3)) == 0 ||
- (face_seam_flag & (PROJ_FACE_SEAM4 | PROJ_FACE_NOSEAM4)) == 0)
- {
- project_face_seams_init(ps, face_index, mf->v4);
- face_seam_flag = ps->faceSeamFlags[face_index];
- //printf("seams - %d %d %d %d\n", flag&PROJ_FACE_SEAM1, flag&PROJ_FACE_SEAM2, flag&PROJ_FACE_SEAM3, flag&PROJ_FACE_SEAM4);
- }
-
- if ((face_seam_flag & (PROJ_FACE_SEAM1 | PROJ_FACE_SEAM2 | PROJ_FACE_SEAM3 | PROJ_FACE_SEAM4)) == 0) {
-
- if (ps->thread_tot > 1)
- BLI_unlock_thread(LOCK_CUSTOM1); /* Other threads could be modifying these vars */
-
- }
- else {
- /* we have a seam - deal with it! */
-
- /* Now create new UV's for the seam face */
- float (*outset_uv)[2] = ps->faceSeamUVs[face_index];
- float insetCos[4][3]; /* inset face coords. NOTE!!! ScreenSace for ortho, Worldspace in prespective view */
-
- float *vCoSS[4]; /* vertex screenspace coords */
-
- float bucket_clip_edges[2][2]; /* store the screenspace coords of the face, clipped by the bucket's screen aligned rectangle */
- float edge_verts_inset_clip[2][3];
- int fidx1, fidx2; /* face edge pairs - loop throuh these ((0,1), (1,2), (2,3), (3,0)) or ((0,1), (1,2), (2,0)) for a tri */
-
- float seam_subsection[4][2];
- float fac1, fac2, ftot;
-
-
- if (outset_uv[0][0] == FLT_MAX) /* first time initialize */
- uv_image_outset(tf_uv_pxoffset, outset_uv, ps->seam_bleed_px, ibuf->x, ibuf->y, mf->v4);
-
- /* ps->faceSeamUVs cant be modified when threading, now this is done we can unlock */
- if (ps->thread_tot > 1)
- BLI_unlock_thread(LOCK_CUSTOM1); /* Other threads could be modifying these vars */
-
- vCoSS[0] = ps->screenCoords[mf->v1];
- vCoSS[1] = ps->screenCoords[mf->v2];
- vCoSS[2] = ps->screenCoords[mf->v3];
- if (mf->v4)
- vCoSS[3] = ps->screenCoords[mf->v4];
-
- /* PROJ_FACE_SCALE_SEAM must be slightly less then 1.0f */
- if (is_ortho) {
- if (mf->v4) scale_quad(insetCos, vCoSS, PROJ_FACE_SCALE_SEAM);
- else scale_tri(insetCos, vCoSS, PROJ_FACE_SCALE_SEAM);
- }
- else {
- if (mf->v4) scale_quad(insetCos, vCo, PROJ_FACE_SCALE_SEAM);
- else scale_tri(insetCos, vCo, PROJ_FACE_SCALE_SEAM);
- }
-
- side = 0; /* for triangles this wont need to change */
-
- for (fidx1 = 0; fidx1 < (mf->v4 ? 4 : 3); fidx1++) {
- if (mf->v4) fidx2 = (fidx1 == 3) ? 0 : fidx1 + 1; /* next fidx in the face (0,1,2,3) -> (1,2,3,0) */
- else fidx2 = (fidx1 == 2) ? 0 : fidx1 + 1; /* next fidx in the face (0,1,2) -> (1,2,0) */
-
- if ((face_seam_flag & (1 << fidx1)) && /* 1<<fidx1 -> PROJ_FACE_SEAM# */
- line_clip_rect2f(bucket_bounds, vCoSS[fidx1], vCoSS[fidx2], bucket_clip_edges[0], bucket_clip_edges[1]))
- {
-
- ftot = len_v2v2(vCoSS[fidx1], vCoSS[fidx2]); /* screenspace edge length */
-
- if (ftot > 0.0f) { /* avoid div by zero */
- if (mf->v4) {
- if (fidx1 == 2 || fidx2 == 2) side = 1;
- else side = 0;
- }
-
- fac1 = len_v2v2(vCoSS[fidx1], bucket_clip_edges[0]) / ftot;
- fac2 = len_v2v2(vCoSS[fidx1], bucket_clip_edges[1]) / ftot;
-
- interp_v2_v2v2(seam_subsection[0], tf_uv_pxoffset[fidx1], tf_uv_pxoffset[fidx2], fac1);
- interp_v2_v2v2(seam_subsection[1], tf_uv_pxoffset[fidx1], tf_uv_pxoffset[fidx2], fac2);
-
- interp_v2_v2v2(seam_subsection[2], outset_uv[fidx1], outset_uv[fidx2], fac2);
- interp_v2_v2v2(seam_subsection[3], outset_uv[fidx1], outset_uv[fidx2], fac1);
-
- /* if the bucket_clip_edges values Z values was kept we could avoid this
- * Inset needs to be added so occlusion tests wont hit adjacent faces */
- interp_v3_v3v3(edge_verts_inset_clip[0], insetCos[fidx1], insetCos[fidx2], fac1);
- interp_v3_v3v3(edge_verts_inset_clip[1], insetCos[fidx1], insetCos[fidx2], fac2);
-
-
- if (pixel_bounds_uv(seam_subsection[0], seam_subsection[1], seam_subsection[2], seam_subsection[3], &bounds_px, ibuf->x, ibuf->y, 1)) {
- /* bounds between the seam rect and the uvspace bucket pixels */
-
- has_isect = 0;
- for (y = bounds_px.ymin; y < bounds_px.ymax; y++) {
- // uv[1] = (((float)y) + 0.5f) / (float)ibuf->y;
- uv[1] = (float)y / ibuf_yf; /* use offset uvs instead */
-
- has_x_isect = 0;
- for (x = bounds_px.xmin; x < bounds_px.xmax; x++) {
- //uv[0] = (((float)x) + 0.5f) / (float)ibuf->x;
- uv[0] = (float)x / ibuf_xf; /* use offset uvs instead */
-
- /* test we're inside uvspace bucket and triangle bounds */
- if (isect_point_quad_v2(uv, seam_subsection[0], seam_subsection[1], seam_subsection[2], seam_subsection[3])) {
- float fac;
-
- /* We need to find the closest point along the face edge,
- * getting the screen_px_from_*** wont work because our actual location
- * is not relevant, since we are outside the face, Use VecLerpf to find
- * our location on the side of the face's UV */
-#if 0
- if (is_ortho) screen_px_from_ortho(ps, uv, v1co, v2co, v3co, uv1co, uv2co, uv3co, pixelScreenCo);
- else screen_px_from_persp(ps, uv, v1co, v2co, v3co, uv1co, uv2co, uv3co, pixelScreenCo);
-#endif
-
- /* Since this is a seam we need to work out where on the line this pixel is */
- //fac = line_point_factor_v2(uv, uv_seam_quad[0], uv_seam_quad[1]);
-
- fac = line_point_factor_v2(uv, seam_subsection[0], seam_subsection[1]);
- if (fac < 0.0f) { copy_v3_v3(pixelScreenCo, edge_verts_inset_clip[0]); }
- else if (fac > 1.0f) { copy_v3_v3(pixelScreenCo, edge_verts_inset_clip[1]); }
- else { interp_v3_v3v3(pixelScreenCo, edge_verts_inset_clip[0], edge_verts_inset_clip[1], fac); }
-
- if (!is_ortho) {
- pixelScreenCo[3] = 1.0f;
- mul_m4_v4((float(*)[4])ps->projectMat, pixelScreenCo); /* cast because of const */
- pixelScreenCo[0] = (float)(ps->winx / 2.0f) + (ps->winx / 2.0f) * pixelScreenCo[0] / pixelScreenCo[3];
- pixelScreenCo[1] = (float)(ps->winy / 2.0f) + (ps->winy / 2.0f) * pixelScreenCo[1] / pixelScreenCo[3];
- pixelScreenCo[2] = pixelScreenCo[2] / pixelScreenCo[3]; /* Use the depth for bucket point occlusion */
- }
-
- if ((ps->do_occlude == FALSE) ||
- !project_bucket_point_occluded(ps, bucketFaceNodes, face_index, pixelScreenCo))
- {
- /* Only bother calculating the weights if we intersect */
- if (ps->do_mask_normal || ps->dm_mtface_clone) {
-#if 1
- /* get the UV on the line since we want to copy the pixels from there for bleeding */
- float uv_close[2];
- float uv_fac = closest_to_line_v2(uv_close, uv, tf_uv_pxoffset[fidx1], tf_uv_pxoffset[fidx2]);
- if (uv_fac < 0.0f) copy_v2_v2(uv_close, tf_uv_pxoffset[fidx1]);
- else if (uv_fac > 1.0f) copy_v2_v2(uv_close, tf_uv_pxoffset[fidx2]);
-
- if (side) {
- barycentric_weights_v2(tf_uv_pxoffset[0], tf_uv_pxoffset[2], tf_uv_pxoffset[3], uv_close, w);
- }
- else {
- barycentric_weights_v2(tf_uv_pxoffset[0], tf_uv_pxoffset[1], tf_uv_pxoffset[2], uv_close, w);
- }
-#else /* this is buggy with quads, don't use for now */
-
- /* Cheat, we know where we are along the edge so work out the weights from that */
- uv_fac = fac1 + (uv_fac * (fac2 - fac1));
-
- w[0] = w[1] = w[2] = 0.0;
- if (side) {
- w[fidx1 ? fidx1 - 1 : 0] = 1.0f - uv_fac;
- w[fidx2 ? fidx2 - 1 : 0] = uv_fac;
- }
- else {
- w[fidx1] = 1.0f - uv_fac;
- w[fidx2] = uv_fac;
- }
-#endif
- }
-
- /* a pity we need to get the worldspace pixel location here */
- if (do_clip || do_3d_mapping) {
- if (side) interp_v3_v3v3v3(wco, ps->dm_mvert[mf->v1].co, ps->dm_mvert[mf->v3].co, ps->dm_mvert[mf->v4].co, w);
- else interp_v3_v3v3v3(wco, ps->dm_mvert[mf->v1].co, ps->dm_mvert[mf->v2].co, ps->dm_mvert[mf->v3].co, w);
-
- if (do_clip && ED_view3d_clipping_test(ps->rv3d, wco, TRUE)) {
- continue; /* Watch out that no code below this needs to run */
- }
- }
-
- mask = project_paint_uvpixel_mask(ps, face_index, side, w);
-
- if (mask > 0.0f) {
- BLI_linklist_prepend_arena(
- bucketPixelNodes,
- project_paint_uvpixel_init(ps, arena, ibuf, x, y, mask, face_index, image_index, pixelScreenCo, wco, side, w),
- arena
- );
- }
-
- }
- }
- else if (has_x_isect) {
- /* assuming the face is not a bow-tie - we know we cant intersect again on the X */
- break;
- }
- }
-
-#if 0 /* TODO - investigate why this dosnt work sometimes! it should! */
- /* no intersection for this entire row, after some intersection above means we can quit now */
- if (has_x_isect == 0 && has_isect) {
- break;
- }
-#endif
- }
- }
- }
- }
- }
- }
- }
-#endif // PROJ_DEBUG_NOSEAMBLEED
-}
-
-
-/* takes floating point screenspace min/max and returns int min/max to be used as indices for ps->bucketRect, ps->bucketFlags */
-static void project_paint_bucket_bounds(const ProjPaintState *ps, const float min[2], const float max[2], int bucketMin[2], int bucketMax[2])
-{
- /* divide by bucketWidth & bucketHeight so the bounds are offset in bucket grid units */
- /* XXX: the offset of 0.5 is always truncated to zero and the offset of 1.5f is always truncated to 1, is this really correct?? - jwilkins */
- bucketMin[0] = (int)((int)(((float)(min[0] - ps->screenMin[0]) / ps->screen_width) * ps->buckets_x) + 0.5f); /* these offsets of 0.5 and 1.5 seem odd but they are correct */
- bucketMin[1] = (int)((int)(((float)(min[1] - ps->screenMin[1]) / ps->screen_height) * ps->buckets_y) + 0.5f);
-
- bucketMax[0] = (int)((int)(((float)(max[0] - ps->screenMin[0]) / ps->screen_width) * ps->buckets_x) + 1.5f);
- bucketMax[1] = (int)((int)(((float)(max[1] - ps->screenMin[1]) / ps->screen_height) * ps->buckets_y) + 1.5f);
-
- /* in case the rect is outside the mesh 2d bounds */
- CLAMP(bucketMin[0], 0, ps->buckets_x);
- CLAMP(bucketMin[1], 0, ps->buckets_y);
-
- CLAMP(bucketMax[0], 0, ps->buckets_x);
- CLAMP(bucketMax[1], 0, ps->buckets_y);
-}
-
-/* set bucket_bounds to a screen space-aligned floating point bound-box */
-static void project_bucket_bounds(const ProjPaintState *ps, const int bucket_x, const int bucket_y, rctf *bucket_bounds)
-{
- bucket_bounds->xmin = ps->screenMin[0] + ((bucket_x) * (ps->screen_width / ps->buckets_x)); /* left */
- bucket_bounds->xmax = ps->screenMin[0] + ((bucket_x + 1) * (ps->screen_width / ps->buckets_x)); /* right */
-
- bucket_bounds->ymin = ps->screenMin[1] + ((bucket_y) * (ps->screen_height / ps->buckets_y)); /* bottom */
- bucket_bounds->ymax = ps->screenMin[1] + ((bucket_y + 1) * (ps->screen_height / ps->buckets_y)); /* top */
-}
-
-/* Fill this bucket with pixels from the faces that intersect it.
- *
- * have bucket_bounds as an argument so we don't need to give bucket_x/y the rect function needs */
-static void project_bucket_init(const ProjPaintState *ps, const int thread_index, const int bucket_index, rctf *bucket_bounds)
-{
- LinkNode *node;
- int face_index, image_index = 0;
- ImBuf *ibuf = NULL;
- Image *tpage_last = NULL, *tpage;
- Image *ima = NULL;
-
- if (ps->image_tot == 1) {
- /* Simple loop, no context switching */
- ibuf = ps->projImages[0].ibuf;
- ima = ps->projImages[0].ima;
-
- for (node = ps->bucketFaces[bucket_index]; node; node = node->next) {
- project_paint_face_init(ps, thread_index, bucket_index, GET_INT_FROM_POINTER(node->link), 0, bucket_bounds, ibuf, ima->tpageflag & IMA_CLAMP_U, ima->tpageflag & IMA_CLAMP_V);
- }
- }
- else {
-
- /* More complicated loop, switch between images */
- for (node = ps->bucketFaces[bucket_index]; node; node = node->next) {
- face_index = GET_INT_FROM_POINTER(node->link);
-
- /* Image context switching */
- tpage = project_paint_face_image(ps, ps->dm_mtface, face_index);
- if (tpage_last != tpage) {
- tpage_last = tpage;
-
- for (image_index = 0; image_index < ps->image_tot; image_index++) {
- if (ps->projImages[image_index].ima == tpage_last) {
- ibuf = ps->projImages[image_index].ibuf;
- ima = ps->projImages[image_index].ima;
- break;
- }
- }
- }
- /* context switching done */
-
- project_paint_face_init(ps, thread_index, bucket_index, face_index, image_index, bucket_bounds, ibuf, ima->tpageflag & IMA_CLAMP_U, ima->tpageflag & IMA_CLAMP_V);
- }
- }
-
- ps->bucketFlags[bucket_index] |= PROJ_BUCKET_INIT;
-}
-
-
-/* We want to know if a bucket and a face overlap in screen-space
- *
- * Note, if this ever returns false positives its not that bad, since a face in the bounding area will have its pixels
- * calculated when it might not be needed later, (at the moment at least)
- * obviously it shouldn't have bugs though */
-
-static int project_bucket_face_isect(ProjPaintState *ps, int bucket_x, int bucket_y, const MFace *mf)
-{
- /* TODO - replace this with a tricker method that uses sideofline for all screenCoords's edges against the closest bucket corner */
- rctf bucket_bounds;
- float p1[2], p2[2], p3[2], p4[2];
- float *v, *v1, *v2, *v3, *v4 = NULL;
- int fidx;
-
- project_bucket_bounds(ps, bucket_x, bucket_y, &bucket_bounds);
-
- /* Is one of the faces verts in the bucket bounds? */
-
- fidx = mf->v4 ? 3 : 2;
- do {
- v = ps->screenCoords[(*(&mf->v1 + fidx))];
- if (BLI_rctf_isect_pt_v(&bucket_bounds, v)) {
- return 1;
- }
- } while (fidx--);
-
- v1 = ps->screenCoords[mf->v1];
- v2 = ps->screenCoords[mf->v2];
- v3 = ps->screenCoords[mf->v3];
- if (mf->v4) {
- v4 = ps->screenCoords[mf->v4];
- }
-
- p1[0] = bucket_bounds.xmin; p1[1] = bucket_bounds.ymin;
- p2[0] = bucket_bounds.xmin; p2[1] = bucket_bounds.ymax;
- p3[0] = bucket_bounds.xmax; p3[1] = bucket_bounds.ymax;
- p4[0] = bucket_bounds.xmax; p4[1] = bucket_bounds.ymin;
-
- if (mf->v4) {
- if (isect_point_quad_v2(p1, v1, v2, v3, v4) ||
- isect_point_quad_v2(p2, v1, v2, v3, v4) ||
- isect_point_quad_v2(p3, v1, v2, v3, v4) ||
- isect_point_quad_v2(p4, v1, v2, v3, v4) ||
-
- /* we can avoid testing v3,v1 because another intersection MUST exist if this intersects */
- (isect_line_line_v2(p1, p2, v1, v2) || isect_line_line_v2(p1, p2, v2, v3) || isect_line_line_v2(p1, p2, v3, v4)) ||
- (isect_line_line_v2(p2, p3, v1, v2) || isect_line_line_v2(p2, p3, v2, v3) || isect_line_line_v2(p2, p3, v3, v4)) ||
- (isect_line_line_v2(p3, p4, v1, v2) || isect_line_line_v2(p3, p4, v2, v3) || isect_line_line_v2(p3, p4, v3, v4)) ||
- (isect_line_line_v2(p4, p1, v1, v2) || isect_line_line_v2(p4, p1, v2, v3) || isect_line_line_v2(p4, p1, v3, v4)))
- {
- return 1;
- }
- }
- else {
- if (isect_point_tri_v2(p1, v1, v2, v3) ||
- isect_point_tri_v2(p2, v1, v2, v3) ||
- isect_point_tri_v2(p3, v1, v2, v3) ||
- isect_point_tri_v2(p4, v1, v2, v3) ||
- /* we can avoid testing v3,v1 because another intersection MUST exist if this intersects */
- (isect_line_line_v2(p1, p2, v1, v2) || isect_line_line_v2(p1, p2, v2, v3)) ||
- (isect_line_line_v2(p2, p3, v1, v2) || isect_line_line_v2(p2, p3, v2, v3)) ||
- (isect_line_line_v2(p3, p4, v1, v2) || isect_line_line_v2(p3, p4, v2, v3)) ||
- (isect_line_line_v2(p4, p1, v1, v2) || isect_line_line_v2(p4, p1, v2, v3)))
- {
- return 1;
- }
- }
-
- return 0;
-}
-
-/* Add faces to the bucket but don't initialize its pixels
- * TODO - when painting occluded, sort the faces on their min-Z and only add faces that faces that are not occluded */
-static void project_paint_delayed_face_init(ProjPaintState *ps, const MFace *mf, const int face_index)
-{
- float min[2], max[2], *vCoSS;
- int bucketMin[2], bucketMax[2]; /* for ps->bucketRect indexing */
- int fidx, bucket_x, bucket_y;
- int has_x_isect = -1, has_isect = 0; /* for early loop exit */
- MemArena *arena = ps->arena_mt[0]; /* just use the first thread arena since threading has not started yet */
-
- INIT_MINMAX2(min, max);
-
- fidx = mf->v4 ? 3 : 2;
- do {
- vCoSS = ps->screenCoords[*(&mf->v1 + fidx)];
- minmax_v2v2_v2(min, max, vCoSS);
- } while (fidx--);
-
- project_paint_bucket_bounds(ps, min, max, bucketMin, bucketMax);
-
- for (bucket_y = bucketMin[1]; bucket_y < bucketMax[1]; bucket_y++) {
- has_x_isect = 0;
- for (bucket_x = bucketMin[0]; bucket_x < bucketMax[0]; bucket_x++) {
- if (project_bucket_face_isect(ps, bucket_x, bucket_y, mf)) {
- int bucket_index = bucket_x + (bucket_y * ps->buckets_x);
- BLI_linklist_prepend_arena(
- &ps->bucketFaces[bucket_index],
- SET_INT_IN_POINTER(face_index), /* cast to a pointer to shut up the compiler */
- arena
- );
-
- has_x_isect = has_isect = 1;
- }
- else if (has_x_isect) {
- /* assuming the face is not a bow-tie - we know we cant intersect again on the X */
- break;
- }
- }
-
- /* no intersection for this entire row, after some intersection above means we can quit now */
- if (has_x_isect == 0 && has_isect) {
- break;
- }
- }
-
-#ifndef PROJ_DEBUG_NOSEAMBLEED
- if (ps->seam_bleed_px > 0.0f) {
- if (!mf->v4) {
- ps->faceSeamFlags[face_index] |= PROJ_FACE_NOSEAM4; /* so this wont show up as an untagged edge */
- }
- **ps->faceSeamUVs[face_index] = FLT_MAX; /* set as uninitialized */
- }
-#endif
-}
-
-static int project_paint_view_clip(View3D *v3d, RegionView3D *rv3d, float *clipsta, float *clipend)
-{
- int orth = ED_view3d_clip_range_get(v3d, rv3d, clipsta, clipend);
-
- if (orth) { /* only needed for ortho */
- float fac = 2.0f / ((*clipend) - (*clipsta));
- *clipsta *= fac;
- *clipend *= fac;
- }
-
- return orth;
-}
-
-/* run once per stroke before projection painting */
-static void project_paint_begin(ProjPaintState *ps)
-{
- /* Viewport vars */
- float mat[3][3];
-
- float no[3];
-
- float *projScreenCo; /* Note, we could have 4D vectors are only needed for */
- float projMargin;
-
- /* Image Vars - keep track of images we have used */
- LinkNode *image_LinkList = NULL;
- LinkNode *node;
-
- ProjPaintImage *projIma;
- Image *tpage_last = NULL, *tpage;
-
- /* Face vars */
- MFace *mf;
- MTFace *tf;
-
- int a, i; /* generic looping vars */
- int image_index = -1, face_index;
- MVert *mv;
-
- MemArena *arena; /* at the moment this is just ps->arena_mt[0], but use this to show were not multithreading */
-
- const int diameter = 2 * BKE_brush_size_get(ps->scene, ps->brush);
-
- /* ---- end defines ---- */
-
- if (ps->source == PROJ_SRC_VIEW)
- ED_view3d_clipping_local(ps->rv3d, ps->ob->obmat); /* faster clipping lookups */
-
- /* paint onto the derived mesh */
-
- /* Workaround for subsurf selection, try the display mesh first */
- if (ps->source == PROJ_SRC_IMAGE_CAM) {
- /* using render mesh, assume only camera was rendered from */
- ps->dm = mesh_create_derived_render(ps->scene, ps->ob, ps->scene->customdata_mask | CD_MASK_MTFACE);
- ps->dm_release = TRUE;
- }
- else if (ps->ob->derivedFinal && CustomData_has_layer(&ps->ob->derivedFinal->faceData, CD_MTFACE)) {
- ps->dm = ps->ob->derivedFinal;
- ps->dm_release = FALSE;
- }
- else {
- ps->dm = mesh_get_derived_final(ps->scene, ps->ob, ps->scene->customdata_mask | CD_MASK_MTFACE);
- ps->dm_release = TRUE;
- }
-
- if (!CustomData_has_layer(&ps->dm->faceData, CD_MTFACE) ) {
-
- if (ps->dm_release)
- ps->dm->release(ps->dm);
-
- ps->dm = NULL;
- return;
- }
-
- ps->dm_mvert = ps->dm->getVertArray(ps->dm);
- ps->dm_mface = ps->dm->getTessFaceArray(ps->dm);
- ps->dm_mtface = ps->dm->getTessFaceDataArray(ps->dm, CD_MTFACE);
-
- ps->dm_totvert = ps->dm->getNumVerts(ps->dm);
- ps->dm_totface = ps->dm->getNumTessFaces(ps->dm);
-
- /* use clone mtface? */
-
-
- /* Note, use the original mesh for getting the clone and mask layer index
- * this avoids re-generating the derived mesh just to get the new index */
- if (ps->do_layer_clone) {
- //int layer_num = CustomData_get_clone_layer(&ps->dm->faceData, CD_MTFACE);
- int layer_num = CustomData_get_clone_layer(&((Mesh *)ps->ob->data)->fdata, CD_MTFACE);
- if (layer_num != -1)
- ps->dm_mtface_clone = CustomData_get_layer_n(&ps->dm->faceData, CD_MTFACE, layer_num);
-
- if (ps->dm_mtface_clone == NULL || ps->dm_mtface_clone == ps->dm_mtface) {
- ps->do_layer_clone = FALSE;
- ps->dm_mtface_clone = NULL;
- printf("ACK!\n");
- }
- }
-
- if (ps->do_layer_stencil) {
- //int layer_num = CustomData_get_stencil_layer(&ps->dm->faceData, CD_MTFACE);
- int layer_num = CustomData_get_stencil_layer(&((Mesh *)ps->ob->data)->fdata, CD_MTFACE);
- if (layer_num != -1)
- ps->dm_mtface_stencil = CustomData_get_layer_n(&ps->dm->faceData, CD_MTFACE, layer_num);
-
- if (ps->dm_mtface_stencil == NULL || ps->dm_mtface_stencil == ps->dm_mtface) {
- ps->do_layer_stencil = FALSE;
- ps->dm_mtface_stencil = NULL;
- }
- }
-
- /* when using subsurf or multires, mface arrays are thrown away, we need to keep a copy */
- if (ps->dm->type != DM_TYPE_CDDM) {
- ps->dm_mvert = MEM_dupallocN(ps->dm_mvert);
- ps->dm_mface = MEM_dupallocN(ps->dm_mface);
- /* looks like these are ok for now.*/
-#if 0
- ps->dm_mtface = MEM_dupallocN(ps->dm_mtface);
- ps->dm_mtface_clone = MEM_dupallocN(ps->dm_mtface_clone);
- ps->dm_mtface_stencil = MEM_dupallocN(ps->dm_mtface_stencil);
-#endif
- }
-
- ps->viewDir[0] = 0.0f;
- ps->viewDir[1] = 0.0f;
- ps->viewDir[2] = 1.0f;
-
- {
- float viewmat[4][4];
- float viewinv[4][4];
-
- invert_m4_m4(ps->ob->imat, ps->ob->obmat);
-
- if (ps->source == PROJ_SRC_VIEW) {
- /* normal drawing */
- ps->winx = ps->ar->winx;
- ps->winy = ps->ar->winy;
-
- copy_m4_m4(viewmat, ps->rv3d->viewmat);
- copy_m4_m4(viewinv, ps->rv3d->viewinv);
-
- ED_view3d_ob_project_mat_get(ps->rv3d, ps->ob, ps->projectMat);
-
- ps->is_ortho = project_paint_view_clip(ps->v3d, ps->rv3d, &ps->clipsta, &ps->clipend);
- }
- else {
- /* re-projection */
- float winmat[4][4];
- float vmat[4][4];
-
- ps->winx = ps->reproject_ibuf->x;
- ps->winy = ps->reproject_ibuf->y;
-
- if (ps->source == PROJ_SRC_IMAGE_VIEW) {
- /* image stores camera data, tricky */
- IDProperty *idgroup = IDP_GetProperties(&ps->reproject_image->id, 0);
- IDProperty *view_data = IDP_GetPropertyFromGroup(idgroup, PROJ_VIEW_DATA_ID);
-
- float *array = (float *)IDP_Array(view_data);
-
- /* use image array, written when creating image */
- memcpy(winmat, array, sizeof(winmat)); array += sizeof(winmat) / sizeof(float);
- memcpy(viewmat, array, sizeof(viewmat)); array += sizeof(viewmat) / sizeof(float);
- ps->clipsta = array[0];
- ps->clipend = array[1];
- ps->is_ortho = array[2] ? 1 : 0;
-
- invert_m4_m4(viewinv, viewmat);
- }
- else if (ps->source == PROJ_SRC_IMAGE_CAM) {
- Object *cam_ob = ps->scene->camera;
- CameraParams params;
-
- /* viewmat & viewinv */
- copy_m4_m4(viewinv, cam_ob->obmat);
- normalize_m4(viewinv);
- invert_m4_m4(viewmat, viewinv);
-
- /* window matrix, clipping and ortho */
- BKE_camera_params_init(&params);
- BKE_camera_params_from_object(&params, cam_ob);
- BKE_camera_params_compute_viewplane(&params, ps->winx, ps->winy, 1.0f, 1.0f);
- BKE_camera_params_compute_matrix(&params);
-
- copy_m4_m4(winmat, params.winmat);
- ps->clipsta = params.clipsta;
- ps->clipend = params.clipend;
- ps->is_ortho = params.is_ortho;
- }
-
- /* same as #ED_view3d_ob_project_mat_get */
- mult_m4_m4m4(vmat, viewmat, ps->ob->obmat);
- mult_m4_m4m4(ps->projectMat, winmat, vmat);
- }
-
-
- /* viewDir - object relative */
- invert_m4_m4(ps->ob->imat, ps->ob->obmat);
- copy_m3_m4(mat, viewinv);
- mul_m3_v3(mat, ps->viewDir);
- copy_m3_m4(mat, ps->ob->imat);
- mul_m3_v3(mat, ps->viewDir);
- normalize_v3(ps->viewDir);
-
- /* viewPos - object relative */
- copy_v3_v3(ps->viewPos, viewinv[3]);
- copy_m3_m4(mat, ps->ob->imat);
- mul_m3_v3(mat, ps->viewPos);
- add_v3_v3(ps->viewPos, ps->ob->imat[3]);
- }
-
- /* calculate vert screen coords
- * run this early so we can calculate the x/y resolution of our bucket rect */
- INIT_MINMAX2(ps->screenMin, ps->screenMax);
-
- ps->screenCoords = MEM_mallocN(sizeof(float) * ps->dm_totvert * 4, "ProjectPaint ScreenVerts");
- projScreenCo = *ps->screenCoords;
-
- if (ps->is_ortho) {
- for (a = 0, mv = ps->dm_mvert; a < ps->dm_totvert; a++, mv++, projScreenCo += 4) {
- mul_v3_m4v3(projScreenCo, ps->projectMat, mv->co);
-
- /* screen space, not clamped */
- projScreenCo[0] = (float)(ps->winx / 2.0f) + (ps->winx / 2.0f) * projScreenCo[0];
- projScreenCo[1] = (float)(ps->winy / 2.0f) + (ps->winy / 2.0f) * projScreenCo[1];
- minmax_v2v2_v2(ps->screenMin, ps->screenMax, projScreenCo);
- }
- }
- else {
- for (a = 0, mv = ps->dm_mvert; a < ps->dm_totvert; a++, mv++, projScreenCo += 4) {
- copy_v3_v3(projScreenCo, mv->co);
- projScreenCo[3] = 1.0f;
-
- mul_m4_v4(ps->projectMat, projScreenCo);
-
- if (projScreenCo[3] > ps->clipsta) {
- /* screen space, not clamped */
- projScreenCo[0] = (float)(ps->winx / 2.0f) + (ps->winx / 2.0f) * projScreenCo[0] / projScreenCo[3];
- projScreenCo[1] = (float)(ps->winy / 2.0f) + (ps->winy / 2.0f) * projScreenCo[1] / projScreenCo[3];
- projScreenCo[2] = projScreenCo[2] / projScreenCo[3]; /* Use the depth for bucket point occlusion */
- minmax_v2v2_v2(ps->screenMin, ps->screenMax, projScreenCo);
- }
- else {
- /* TODO - deal with cases where 1 side of a face goes behind the view ?
- *
- * After some research this is actually very tricky, only option is to
- * clip the derived mesh before painting, which is a Pain */
- projScreenCo[0] = FLT_MAX;
- }
- }
- }
-
- /* If this border is not added we get artifacts for faces that
- * have a parallel edge and at the bounds of the the 2D projected verts eg
- * - a single screen aligned quad */
- projMargin = (ps->screenMax[0] - ps->screenMin[0]) * 0.000001f;
- ps->screenMax[0] += projMargin;
- ps->screenMin[0] -= projMargin;
- projMargin = (ps->screenMax[1] - ps->screenMin[1]) * 0.000001f;
- ps->screenMax[1] += projMargin;
- ps->screenMin[1] -= projMargin;
-
- if (ps->source == PROJ_SRC_VIEW) {
-#ifdef PROJ_DEBUG_WINCLIP
- CLAMP(ps->screenMin[0], (float)(-diameter), (float)(ps->winx + diameter));
- CLAMP(ps->screenMax[0], (float)(-diameter), (float)(ps->winx + diameter));
-
- CLAMP(ps->screenMin[1], (float)(-diameter), (float)(ps->winy + diameter));
- CLAMP(ps->screenMax[1], (float)(-diameter), (float)(ps->winy + diameter));
-#endif
- }
- else { /* re-projection, use bounds */
- ps->screenMin[0] = 0;
- ps->screenMax[0] = (float)(ps->winx);
-
- ps->screenMin[1] = 0;
- ps->screenMax[1] = (float)(ps->winy);
- }
-
- /* only for convenience */
- ps->screen_width = ps->screenMax[0] - ps->screenMin[0];
- ps->screen_height = ps->screenMax[1] - ps->screenMin[1];
-
- ps->buckets_x = (int)(ps->screen_width / (((float)diameter) / PROJ_BUCKET_BRUSH_DIV));
- ps->buckets_y = (int)(ps->screen_height / (((float)diameter) / PROJ_BUCKET_BRUSH_DIV));
-
- /* printf("\tscreenspace bucket division x:%d y:%d\n", ps->buckets_x, ps->buckets_y); */
-
- /* really high values could cause problems since it has to allocate a few
- * (ps->buckets_x*ps->buckets_y) sized arrays */
- CLAMP(ps->buckets_x, PROJ_BUCKET_RECT_MIN, PROJ_BUCKET_RECT_MAX);
- CLAMP(ps->buckets_y, PROJ_BUCKET_RECT_MIN, PROJ_BUCKET_RECT_MAX);
-
- ps->bucketRect = (LinkNode **)MEM_callocN(sizeof(LinkNode *) * ps->buckets_x * ps->buckets_y, "paint-bucketRect");
- ps->bucketFaces = (LinkNode **)MEM_callocN(sizeof(LinkNode *) * ps->buckets_x * ps->buckets_y, "paint-bucketFaces");
-
- ps->bucketFlags = (unsigned char *)MEM_callocN(sizeof(char) * ps->buckets_x * ps->buckets_y, "paint-bucketFaces");
-#ifndef PROJ_DEBUG_NOSEAMBLEED
- if (ps->seam_bleed_px > 0.0f) {
- ps->vertFaces = (LinkNode **)MEM_callocN(sizeof(LinkNode *) * ps->dm_totvert, "paint-vertFaces");
- ps->faceSeamFlags = (char *)MEM_callocN(sizeof(char) * ps->dm_totface, "paint-faceSeamFlags");
- ps->faceSeamUVs = MEM_mallocN(sizeof(float) * ps->dm_totface * 8, "paint-faceSeamUVs");
- }
-#endif
-
- /* Thread stuff
- *
- * very small brushes run a lot slower multithreaded since the advantage with
- * threads is being able to fill in multiple buckets at once.
- * Only use threads for bigger brushes. */
-
- if (ps->scene->r.mode & R_FIXED_THREADS) {
- ps->thread_tot = ps->scene->r.threads;
- }
- else {
- ps->thread_tot = BLI_system_thread_count();
- }
- for (a = 0; a < ps->thread_tot; a++) {
- ps->arena_mt[a] = BLI_memarena_new(1 << 16, "project paint arena");
- }
-
- arena = ps->arena_mt[0];
-
- if (ps->do_backfacecull && ps->do_mask_normal) {
- float viewDirPersp[3];
-
- ps->vertFlags = MEM_callocN(sizeof(char) * ps->dm_totvert, "paint-vertFlags");
-
- for (a = 0, mv = ps->dm_mvert; a < ps->dm_totvert; a++, mv++) {
- normal_short_to_float_v3(no, mv->no);
-
- if (ps->is_ortho) {
- if (angle_normalized_v3v3(ps->viewDir, no) >= ps->normal_angle) { /* 1 vert of this face is towards us */
- ps->vertFlags[a] |= PROJ_VERT_CULL;
- }
- }
- else {
- sub_v3_v3v3(viewDirPersp, ps->viewPos, mv->co);
- normalize_v3(viewDirPersp);
- if (angle_normalized_v3v3(viewDirPersp, no) >= ps->normal_angle) { /* 1 vert of this face is towards us */
- ps->vertFlags[a] |= PROJ_VERT_CULL;
- }
- }
- }
- }
-
-
- for (face_index = 0, tf = ps->dm_mtface, mf = ps->dm_mface; face_index < ps->dm_totface; mf++, tf++, face_index++) {
-
-#ifndef PROJ_DEBUG_NOSEAMBLEED
- /* add face user if we have bleed enabled, set the UV seam flags later */
- /* annoying but we need to add all faces even ones we never use elsewhere */
- if (ps->seam_bleed_px > 0.0f) {
- BLI_linklist_prepend_arena(&ps->vertFaces[mf->v1], SET_INT_IN_POINTER(face_index), arena);
- BLI_linklist_prepend_arena(&ps->vertFaces[mf->v2], SET_INT_IN_POINTER(face_index), arena);
- BLI_linklist_prepend_arena(&ps->vertFaces[mf->v3], SET_INT_IN_POINTER(face_index), arena);
- if (mf->v4) {
- BLI_linklist_prepend_arena(&ps->vertFaces[mf->v4], SET_INT_IN_POINTER(face_index), arena);
- }
- }
-#endif
-
- tpage = project_paint_face_image(ps, ps->dm_mtface, face_index);
-
- if (tpage && ((((Mesh *)ps->ob->data)->editflag & ME_EDIT_PAINT_FACE_SEL) == 0 || mf->flag & ME_FACE_SEL)) {
-
- float *v1coSS, *v2coSS, *v3coSS, *v4coSS = NULL;
-
- v1coSS = ps->screenCoords[mf->v1];
- v2coSS = ps->screenCoords[mf->v2];
- v3coSS = ps->screenCoords[mf->v3];
- if (mf->v4) {
- v4coSS = ps->screenCoords[mf->v4];
- }
-
-
- if (!ps->is_ortho) {
- if (v1coSS[0] == FLT_MAX ||
- v2coSS[0] == FLT_MAX ||
- v3coSS[0] == FLT_MAX ||
- (mf->v4 && v4coSS[0] == FLT_MAX))
- {
- continue;
- }
- }
-
-#ifdef PROJ_DEBUG_WINCLIP
- /* ignore faces outside the view */
- if (
- (v1coSS[0] < ps->screenMin[0] &&
- v2coSS[0] < ps->screenMin[0] &&
- v3coSS[0] < ps->screenMin[0] &&
- (mf->v4 && v4coSS[0] < ps->screenMin[0])) ||
-
- (v1coSS[0] > ps->screenMax[0] &&
- v2coSS[0] > ps->screenMax[0] &&
- v3coSS[0] > ps->screenMax[0] &&
- (mf->v4 && v4coSS[0] > ps->screenMax[0])) ||
-
- (v1coSS[1] < ps->screenMin[1] &&
- v2coSS[1] < ps->screenMin[1] &&
- v3coSS[1] < ps->screenMin[1] &&
- (mf->v4 && v4coSS[1] < ps->screenMin[1])) ||
-
- (v1coSS[1] > ps->screenMax[1] &&
- v2coSS[1] > ps->screenMax[1] &&
- v3coSS[1] > ps->screenMax[1] &&
- (mf->v4 && v4coSS[1] > ps->screenMax[1]))
- )
- {
- continue;
- }
-
-#endif //PROJ_DEBUG_WINCLIP
-
-
- if (ps->do_backfacecull) {
- if (ps->do_mask_normal) {
- /* Since we are interpolating the normals of faces, we want to make
- * sure all the verts are pointing away from the view,
- * not just the face */
- if ((ps->vertFlags[mf->v1] & PROJ_VERT_CULL) &&
- (ps->vertFlags[mf->v2] & PROJ_VERT_CULL) &&
- (ps->vertFlags[mf->v3] & PROJ_VERT_CULL) &&
- (mf->v4 == 0 || ps->vertFlags[mf->v4] & PROJ_VERT_CULL)
- )
- {
- continue;
- }
- }
- else {
- if (line_point_side_v2(v1coSS, v2coSS, v3coSS) < 0.0f) {
- continue;
- }
-
- }
- }
-
- if (tpage_last != tpage) {
-
- image_index = BLI_linklist_index(image_LinkList, tpage);
-
- if (image_index == -1 && BKE_image_has_ibuf(tpage, NULL)) { /* MemArena dosnt have an append func */
- BLI_linklist_append(&image_LinkList, tpage);
- image_index = ps->image_tot;
- ps->image_tot++;
- }
-
- tpage_last = tpage;
- }
-
- if (image_index != -1) {
- /* Initialize the faces screen pixels */
- /* Add this to a list to initialize later */
- project_paint_delayed_face_init(ps, mf, face_index);
- }
- }
- }
-
- /* build an array of images we use*/
- projIma = ps->projImages = (ProjPaintImage *)BLI_memarena_alloc(arena, sizeof(ProjPaintImage) * ps->image_tot);
-
- for (node = image_LinkList, i = 0; node; node = node->next, i++, projIma++) {
- projIma->ima = node->link;
- projIma->touch = 0;
- projIma->ibuf = BKE_image_acquire_ibuf(projIma->ima, NULL, NULL);
- projIma->partRedrawRect = BLI_memarena_alloc(arena, sizeof(ImagePaintPartialRedraw) * PROJ_BOUNDBOX_SQUARED);
- memset(projIma->partRedrawRect, 0, sizeof(ImagePaintPartialRedraw) * PROJ_BOUNDBOX_SQUARED);
- }
-
- /* we have built the array, discard the linked list */
- BLI_linklist_free(image_LinkList, NULL);
-}
-
-static void project_paint_begin_clone(ProjPaintState *ps, int mouse[2])
-{
- /* setup clone offset */
- if (ps->tool == PAINT_TOOL_CLONE) {
- float projCo[4];
- copy_v3_v3(projCo, give_cursor(ps->scene, ps->v3d));
- mul_m4_v3(ps->ob->imat, projCo);
-
- projCo[3] = 1.0f;
- mul_m4_v4(ps->projectMat, projCo);
- ps->cloneOffset[0] = mouse[0] - ((float)(ps->winx / 2.0f) + (ps->winx / 2.0f) * projCo[0] / projCo[3]);
- ps->cloneOffset[1] = mouse[1] - ((float)(ps->winy / 2.0f) + (ps->winy / 2.0f) * projCo[1] / projCo[3]);
- }
-}
-
-static void project_paint_end(ProjPaintState *ps)
-{
- int a;
- ProjPaintImage *projIma;
-
- /* build undo data from original pixel colors */
- if (U.uiflag & USER_GLOBALUNDO) {
- ProjPixel *projPixel;
- ImBuf *tmpibuf = NULL, *tmpibuf_float = NULL;
- LinkNode *pixel_node;
- void *tilerect;
- MemArena *arena = ps->arena_mt[0]; /* threaded arena re-used for non threaded case */
-
- int bucket_tot = (ps->buckets_x * ps->buckets_y); /* we could get an X/Y but easier to loop through all possible buckets */
- int bucket_index;
- int tile_index;
- int x_round, y_round;
- int x_tile, y_tile;
- int is_float = -1;
-
- /* context */
- ProjPaintImage *last_projIma;
- int last_image_index = -1;
- int last_tile_width = 0;
-
- for (a = 0, last_projIma = ps->projImages; a < ps->image_tot; a++, last_projIma++) {
- int size = sizeof(void **) * IMAPAINT_TILE_NUMBER(last_projIma->ibuf->x) * IMAPAINT_TILE_NUMBER(last_projIma->ibuf->y);
- last_projIma->undoRect = (void **) BLI_memarena_alloc(arena, size);
- memset(last_projIma->undoRect, 0, size);
- last_projIma->ibuf->userflags |= IB_BITMAPDIRTY;
- }
-
- for (bucket_index = 0; bucket_index < bucket_tot; bucket_index++) {
- /* loop through all pixels */
- for (pixel_node = ps->bucketRect[bucket_index]; pixel_node; pixel_node = pixel_node->next) {
-
- /* ok we have a pixel, was it modified? */
- projPixel = (ProjPixel *)pixel_node->link;
-
- if (last_image_index != projPixel->image_index) {
- /* set the context */
- last_image_index = projPixel->image_index;
- last_projIma = ps->projImages + last_image_index;
- last_tile_width = IMAPAINT_TILE_NUMBER(last_projIma->ibuf->x);
- is_float = last_projIma->ibuf->rect_float ? 1 : 0;
- }
-
-
- if ((is_float == 0 && projPixel->origColor.uint != *projPixel->pixel.uint_pt) ||
- (is_float == 1 &&
- (projPixel->origColor.f[0] != projPixel->pixel.f_pt[0] ||
- projPixel->origColor.f[1] != projPixel->pixel.f_pt[1] ||
- projPixel->origColor.f[2] != projPixel->pixel.f_pt[2] ||
- projPixel->origColor.f[3] != projPixel->pixel.f_pt[3]))
- )
- {
-
- x_tile = projPixel->x_px >> IMAPAINT_TILE_BITS;
- y_tile = projPixel->y_px >> IMAPAINT_TILE_BITS;
-
- x_round = x_tile * IMAPAINT_TILE_SIZE;
- y_round = y_tile * IMAPAINT_TILE_SIZE;
-
- tile_index = x_tile + y_tile * last_tile_width;
-
- if (last_projIma->undoRect[tile_index] == NULL) {
- /* add the undo tile from the modified image, then write the original colors back into it */
- tilerect = last_projIma->undoRect[tile_index] = image_undo_push_tile(last_projIma->ima, last_projIma->ibuf, is_float ? (&tmpibuf_float) : (&tmpibuf), x_tile, y_tile);
- }
- else {
- tilerect = last_projIma->undoRect[tile_index];
- }
-
- /* This is a BIT ODD, but overwrite the undo tiles image info with this pixels original color
- * because allocating the tiles along the way slows down painting */
-
- if (is_float) {
- float *rgba_fp = (float *)tilerect + (((projPixel->x_px - x_round) + (projPixel->y_px - y_round) * IMAPAINT_TILE_SIZE)) * 4;
- copy_v4_v4(rgba_fp, projPixel->origColor.f);
- }
- else {
- ((unsigned int *)tilerect)[(projPixel->x_px - x_round) + (projPixel->y_px - y_round) * IMAPAINT_TILE_SIZE] = projPixel->origColor.uint;
- }
- }
- }
- }
-
- if (tmpibuf) IMB_freeImBuf(tmpibuf);
- if (tmpibuf_float) IMB_freeImBuf(tmpibuf_float);
- }
- /* done calculating undo data */
-
- /* dereference used image buffers */
- for (a = 0, projIma = ps->projImages; a < ps->image_tot; a++, projIma++) {
- BKE_image_release_ibuf(projIma->ima, projIma->ibuf, NULL);
- }
-
- BKE_image_release_ibuf(ps->reproject_image, ps->reproject_ibuf, NULL);
-
- MEM_freeN(ps->screenCoords);
- MEM_freeN(ps->bucketRect);
- MEM_freeN(ps->bucketFaces);
- MEM_freeN(ps->bucketFlags);
-
-#ifndef PROJ_DEBUG_NOSEAMBLEED
- if (ps->seam_bleed_px > 0.0f) {
- MEM_freeN(ps->vertFaces);
- MEM_freeN(ps->faceSeamFlags);
- MEM_freeN(ps->faceSeamUVs);
- }
-#endif
-
- if (ps->vertFlags) MEM_freeN(ps->vertFlags);
-
- for (a = 0; a < ps->thread_tot; a++) {
- BLI_memarena_free(ps->arena_mt[a]);
- }
-
- /* copy for subsurf/multires, so throw away */
- if (ps->dm->type != DM_TYPE_CDDM) {
- if (ps->dm_mvert) MEM_freeN(ps->dm_mvert);
- if (ps->dm_mface) MEM_freeN(ps->dm_mface);
- /* looks like these don't need copying */
-#if 0
- if (ps->dm_mtface) MEM_freeN(ps->dm_mtface);
- if (ps->dm_mtface_clone) MEM_freeN(ps->dm_mtface_clone);
- if (ps->dm_mtface_stencil) MEM_freeN(ps->dm_mtface_stencil);
-#endif
- }
-
- if (ps->dm_release)
- ps->dm->release(ps->dm);
-}
-
-/* 1 = an undo, -1 is a redo. */
-static void partial_redraw_array_init(ImagePaintPartialRedraw *pr)
-{
- int tot = PROJ_BOUNDBOX_SQUARED;
- while (tot--) {
- pr->x1 = 10000000;
- pr->y1 = 10000000;
-
- pr->x2 = -1;
- pr->y2 = -1;
-
- pr->enabled = 1;
-
- pr++;
- }
-}
-
-
-static int partial_redraw_array_merge(ImagePaintPartialRedraw *pr, ImagePaintPartialRedraw *pr_other, int tot)
-{
- int touch = 0;
- while (tot--) {
- pr->x1 = min_ii(pr->x1, pr_other->x1);
- pr->y1 = min_ii(pr->y1, pr_other->y1);
-
- pr->x2 = max_ii(pr->x2, pr_other->x2);
- pr->y2 = max_ii(pr->y2, pr_other->y2);
-
- if (pr->x2 != -1)
- touch = 1;
-
- pr++; pr_other++;
- }
-
- return touch;
-}
-
-/* Loop over all images on this mesh and update any we have touched */
-static int project_image_refresh_tagged(ProjPaintState *ps)
-{
- ImagePaintPartialRedraw *pr;
- ProjPaintImage *projIma;
- int a, i;
- int redraw = 0;
-
-
- for (a = 0, projIma = ps->projImages; a < ps->image_tot; a++, projIma++) {
- if (projIma->touch) {
- /* look over each bound cell */
- for (i = 0; i < PROJ_BOUNDBOX_SQUARED; i++) {
- pr = &(projIma->partRedrawRect[i]);
- if (pr->x2 != -1) { /* TODO - use 'enabled' ? */
- imapaintpartial = *pr;
- imapaint_image_update(NULL, projIma->ima, projIma->ibuf, 1); /*last 1 is for texpaint*/
- redraw = 1;
- }
- }
-
- projIma->touch = 0; /* clear for reuse */
- }
- }
-
- return redraw;
-}
-
-/* run this per painting onto each mouse location */
-static int project_bucket_iter_init(ProjPaintState *ps, const float mval_f[2])
-{
- if (ps->source == PROJ_SRC_VIEW) {
- float min_brush[2], max_brush[2];
- const float radius = (float)BKE_brush_size_get(ps->scene, ps->brush);
-
- /* so we don't have a bucket bounds that is way too small to paint into */
- // if (radius < 1.0f) radius = 1.0f; // this doesn't work yet :/
-
- min_brush[0] = mval_f[0] - radius;
- min_brush[1] = mval_f[1] - radius;
-
- max_brush[0] = mval_f[0] + radius;
- max_brush[1] = mval_f[1] + radius;
-
- /* offset to make this a valid bucket index */
- project_paint_bucket_bounds(ps, min_brush, max_brush, ps->bucketMin, ps->bucketMax);
-
- /* mouse outside the model areas? */
- if (ps->bucketMin[0] == ps->bucketMax[0] || ps->bucketMin[1] == ps->bucketMax[1]) {
- return 0;
- }
-
- ps->context_bucket_x = ps->bucketMin[0];
- ps->context_bucket_y = ps->bucketMin[1];
- }
- else { /* reproject: PROJ_SRC_* */
- ps->bucketMin[0] = 0;
- ps->bucketMin[1] = 0;
-
- ps->bucketMax[0] = ps->buckets_x;
- ps->bucketMax[1] = ps->buckets_y;
-
- ps->context_bucket_x = 0;
- ps->context_bucket_y = 0;
- }
- return 1;
-}
-
-
-static int project_bucket_iter_next(ProjPaintState *ps, int *bucket_index, rctf *bucket_bounds, const float mval[2])
-{
- const int diameter = 2 * BKE_brush_size_get(ps->scene, ps->brush);
-
- if (ps->thread_tot > 1)
- BLI_lock_thread(LOCK_CUSTOM1);
-
- //printf("%d %d\n", ps->context_bucket_x, ps->context_bucket_y);
-
- for (; ps->context_bucket_y < ps->bucketMax[1]; ps->context_bucket_y++) {
- for (; ps->context_bucket_x < ps->bucketMax[0]; ps->context_bucket_x++) {
-
- /* use bucket_bounds for project_bucket_isect_circle and project_bucket_init*/
- project_bucket_bounds(ps, ps->context_bucket_x, ps->context_bucket_y, bucket_bounds);
-
- if ((ps->source != PROJ_SRC_VIEW) ||
- project_bucket_isect_circle(mval, (float)(diameter * diameter), bucket_bounds))
- {
- *bucket_index = ps->context_bucket_x + (ps->context_bucket_y * ps->buckets_x);
- ps->context_bucket_x++;
-
- if (ps->thread_tot > 1)
- BLI_unlock_thread(LOCK_CUSTOM1);
-
- return 1;
- }
- }
- ps->context_bucket_x = ps->bucketMin[0];
- }
-
- if (ps->thread_tot > 1)
- BLI_unlock_thread(LOCK_CUSTOM1);
- return 0;
-}
-
-/* Each thread gets one of these, also used as an argument to pass to project_paint_op */
-typedef struct ProjectHandle {
- /* args */
- ProjPaintState *ps;
- float prevmval[2];
- float mval[2];
-
- /* annoying but we need to have image bounds per thread, then merge into ps->projectPartialRedraws */
- ProjPaintImage *projImages; /* array of partial redraws */
-
- /* thread settings */
- int thread_index;
-
- struct ImagePool *pool;
-} ProjectHandle;
-
-static void blend_color_mix(unsigned char cp[4], const unsigned char cp1[4], const unsigned char cp2[4], const int fac)
-{
- /* this and other blending modes previously used >>8 instead of /255. both
- * are not equivalent (>>8 is /256), and the former results in rounding
- * errors that can turn colors black fast after repeated blending */
- const int mfac = 255 - fac;
-
- cp[0] = (mfac * cp1[0] + fac * cp2[0]) / 255;
- cp[1] = (mfac * cp1[1] + fac * cp2[1]) / 255;
- cp[2] = (mfac * cp1[2] + fac * cp2[2]) / 255;
- cp[3] = (mfac * cp1[3] + fac * cp2[3]) / 255;
-}
-
-static void blend_color_mix_float(float cp[4], const float cp1[4], const float cp2[4], const float fac)
-{
- const float mfac = 1.0f - fac;
- cp[0] = mfac * cp1[0] + fac * cp2[0];
- cp[1] = mfac * cp1[1] + fac * cp2[1];
- cp[2] = mfac * cp1[2] + fac * cp2[2];
- cp[3] = mfac * cp1[3] + fac * cp2[3];
-}
-
-static void blend_color_mix_accum(unsigned char cp[4], const unsigned char cp1[4], const unsigned char cp2[4], const int fac)
-{
- /* this and other blending modes previously used >>8 instead of /255. both
- * are not equivalent (>>8 is /256), and the former results in rounding
- * errors that can turn colors black fast after repeated blending */
- const int mfac = 255 - fac;
- const int alpha = cp1[3] + ((fac * cp2[3]) / 255);
-
- cp[0] = (mfac * cp1[0] + fac * cp2[0]) / 255;
- cp[1] = (mfac * cp1[1] + fac * cp2[1]) / 255;
- cp[2] = (mfac * cp1[2] + fac * cp2[2]) / 255;
- cp[3] = alpha > 255 ? 255 : alpha;
-}
-static void blend_color_mix_accum_float(float cp[4], const float cp1[4], const unsigned char cp2[4], const float fac)
-{
- const float mfac = 1.0f - fac;
- const float alpha = cp1[3] + (fac * (cp2[3] / 255.0f));
-
- cp[0] = (mfac * cp1[0] + (fac * (cp2[0] / 255.0f)));
- cp[1] = (mfac * cp1[1] + (fac * (cp2[1] / 255.0f)));
- cp[2] = (mfac * cp1[2] + (fac * (cp2[2] / 255.0f)));
- cp[3] = alpha > 1.0f ? 1.0f : alpha;
-}
-
-
-static void do_projectpaint_clone(ProjPaintState *ps, ProjPixel *projPixel, float alpha, float mask)
-{
- if (ps->do_masking && mask < 1.0f) {
- projPixel->newColor.uint = IMB_blend_color(projPixel->newColor.uint, ((ProjPixelClone *)projPixel)->clonepx.uint, (int)(alpha * 255), ps->blend);
- blend_color_mix(projPixel->pixel.ch_pt, projPixel->origColor.ch, projPixel->newColor.ch, (int)(mask * 255));
- }
- else {
- *projPixel->pixel.uint_pt = IMB_blend_color(*projPixel->pixel.uint_pt, ((ProjPixelClone *)projPixel)->clonepx.uint, (int)(alpha * mask * 255), ps->blend);
- }
-}
-
-static void do_projectpaint_clone_f(ProjPaintState *ps, ProjPixel *projPixel, float alpha, float mask)
-{
- if (ps->do_masking && mask < 1.0f) {
- IMB_blend_color_float(projPixel->newColor.f, projPixel->newColor.f, ((ProjPixelClone *)projPixel)->clonepx.f, alpha, ps->blend);
- blend_color_mix_float(projPixel->pixel.f_pt, projPixel->origColor.f, projPixel->newColor.f, mask);
- }
- else {
- IMB_blend_color_float(projPixel->pixel.f_pt, projPixel->pixel.f_pt, ((ProjPixelClone *)projPixel)->clonepx.f, alpha * mask, ps->blend);
- }
-}
-
-/* do_projectpaint_smear*
- *
- * note, mask is used to modify the alpha here, this is not correct since it allows
- * accumulation of color greater then 'projPixel->mask' however in the case of smear its not
- * really that important to be correct as it is with clone and painting
- */
-static void do_projectpaint_smear(ProjPaintState *ps, ProjPixel *projPixel, float alpha, float mask, MemArena *smearArena, LinkNode **smearPixels, float co[2])
-{
- unsigned char rgba_ub[4];
-
- if (project_paint_PickColor(ps, co, NULL, rgba_ub, 1) == 0)
- return;
- /* ((ProjPixelClone *)projPixel)->clonepx.uint = IMB_blend_color(*projPixel->pixel.uint_pt, *((unsigned int *)rgba_ub), (int)(alpha*mask*255), ps->blend); */
- blend_color_mix(((ProjPixelClone *)projPixel)->clonepx.ch, projPixel->pixel.ch_pt, rgba_ub, (int)(alpha * mask * 255));
- BLI_linklist_prepend_arena(smearPixels, (void *)projPixel, smearArena);
-}
-
-static void do_projectpaint_smear_f(ProjPaintState *ps, ProjPixel *projPixel, float alpha, float mask, MemArena *smearArena, LinkNode **smearPixels_f, float co[2])
-{
- float rgba[4];
-
- if (project_paint_PickColor(ps, co, rgba, NULL, 1) == 0)
- return;
-
- /* (ProjPixelClone *)projPixel)->clonepx.uint = IMB_blend_color(*((unsigned int *)rgba_smear), *((unsigned int *)rgba_ub), (int)(alpha*mask*255), ps->blend); */
- blend_color_mix_float(((ProjPixelClone *)projPixel)->clonepx.f, projPixel->pixel.f_pt, rgba, alpha * mask);
- BLI_linklist_prepend_arena(smearPixels_f, (void *)projPixel, smearArena);
-}
-
-/* do_projectpaint_soften for float & byte
- */
-static float inv_pow2(float f)
-{
- f = 1.0f - f;
- f = f * f;
- return 1.0f - f;
-}
-
-static void do_projectpaint_soften_f(ProjPaintState *ps, ProjPixel *projPixel, float alpha, float mask, MemArena *softenArena, LinkNode **softenPixels)
-{
- unsigned int accum_tot = 0;
- unsigned int i;
-
- float *rgba = projPixel->newColor.f;
-
- /* sigh, alpha values tend to need to be a _lot_ stronger with blur */
- mask = inv_pow2(mask);
- alpha = inv_pow2(alpha);
-
- /* rather then painting, accumulate surrounding colors */
- zero_v4(rgba);
-
- for (i = 0; i < PROJ_PIXEL_SOFTEN_TOT; i++) {
- float co_ofs[2];
- float rgba_tmp[4];
- sub_v2_v2v2(co_ofs, projPixel->projCoSS, proj_pixel_soften_v2[i]);
- if (project_paint_PickColor(ps, co_ofs, rgba_tmp, NULL, TRUE)) {
- add_v4_v4(rgba, rgba_tmp);
- accum_tot++;
- }
- }
-
- if (LIKELY(accum_tot != 0)) {
- mul_v4_fl(rgba, 1.0f / (float)accum_tot);
- blend_color_mix_float(rgba, projPixel->pixel.f_pt, rgba, alpha);
- if (mask < 1.0f) blend_color_mix_float(rgba, projPixel->origColor.f, rgba, mask);
- BLI_linklist_prepend_arena(softenPixels, (void *)projPixel, softenArena);
- }
-}
-
-static void do_projectpaint_soften(ProjPaintState *ps, ProjPixel *projPixel, float alpha, float mask, MemArena *softenArena, LinkNode **softenPixels)
-{
- unsigned int accum_tot = 0;
- unsigned int i;
-
- float rgba[4]; /* convert to byte after */
-
- /* sigh, alpha values tend to need to be a _lot_ stronger with blur */
- mask = inv_pow2(mask);
- alpha = inv_pow2(alpha);
-
- /* rather then painting, accumulate surrounding colors */
- zero_v4(rgba);
-
- for (i = 0; i < PROJ_PIXEL_SOFTEN_TOT; i++) {
- float co_ofs[2];
- float rgba_tmp[4];
- sub_v2_v2v2(co_ofs, projPixel->projCoSS, proj_pixel_soften_v2[i]);
- if (project_paint_PickColor(ps, co_ofs, rgba_tmp, NULL, TRUE)) {
- add_v4_v4(rgba, rgba_tmp);
- accum_tot++;
- }
- }
-
- if (LIKELY(accum_tot != 0)) {
- unsigned char *rgba_ub = projPixel->newColor.ch;
-
- mul_v4_fl(rgba, 1.0f / (float)accum_tot);
- IMAPAINT_FLOAT_RGBA_TO_CHAR(rgba_ub, rgba);
-
- blend_color_mix(rgba_ub, projPixel->pixel.ch_pt, rgba_ub, (int)(alpha * 255));
- if (mask != 1.0f) blend_color_mix(rgba_ub, projPixel->origColor.ch, rgba_ub, (int)(mask * 255));
- BLI_linklist_prepend_arena(softenPixels, (void *)projPixel, softenArena);
- }
-}
-
-BLI_INLINE void rgba_float_to_uchar__mul_v3(unsigned char rgba_ub[4], const float rgba[4], const float rgb[3])
-{
- rgba_ub[0] = f_to_char(rgba[0] * rgb[0]);
- rgba_ub[1] = f_to_char(rgba[1] * rgb[1]);
- rgba_ub[2] = f_to_char(rgba[2] * rgb[2]);
- rgba_ub[3] = f_to_char(rgba[3]);
-}
-
-static void do_projectpaint_draw(ProjPaintState *ps, ProjPixel *projPixel, const float rgba[4], float alpha, float mask)
-{
- unsigned char rgba_ub[4];
-
- if (ps->is_texbrush) {
- rgba_float_to_uchar__mul_v3(rgba_ub, rgba, ps->brush->rgb);
- }
- else {
- IMAPAINT_FLOAT_RGB_TO_CHAR(rgba_ub, ps->brush->rgb);
- rgba_ub[3] = 255;
- }
-
- if (ps->do_masking && mask < 1.0f) {
- projPixel->newColor.uint = IMB_blend_color(projPixel->newColor.uint, *((unsigned int *)rgba_ub), (int)(alpha * 255), ps->blend);
- blend_color_mix(projPixel->pixel.ch_pt, projPixel->origColor.ch, projPixel->newColor.ch, (int)(mask * 255));
- }
- else {
- *projPixel->pixel.uint_pt = IMB_blend_color(*projPixel->pixel.uint_pt, *((unsigned int *)rgba_ub), (int)(alpha * mask * 255), ps->blend);
- }
-}
-
-static void do_projectpaint_draw_f(ProjPaintState *ps, ProjPixel *projPixel, float rgba[4], float alpha, float mask, int use_color_correction)
-{
- if (ps->is_texbrush) {
- /* rgba already holds a texture result here from higher level function */
- if (use_color_correction) {
- float rgba_br[3];
- srgb_to_linearrgb_v3_v3(rgba_br, ps->brush->rgb);
- mul_v3_v3(rgba, rgba_br);
- }
- else {
- mul_v3_v3(rgba, ps->brush->rgb);
- }
- }
- else {
- if (use_color_correction) {
- srgb_to_linearrgb_v3_v3(rgba, ps->brush->rgb);
- }
- else {
- copy_v3_v3(rgba, ps->brush->rgb);
- }
- rgba[3] = 1.0;
- }
-
- if (ps->do_masking && mask < 1.0f) {
- IMB_blend_color_float(projPixel->newColor.f, projPixel->newColor.f, rgba, alpha, ps->blend);
- blend_color_mix_float(projPixel->pixel.f_pt, projPixel->origColor.f, projPixel->newColor.f, mask);
- }
- else {
- IMB_blend_color_float(projPixel->pixel.f_pt, projPixel->pixel.f_pt, rgba, alpha * mask, ps->blend);
- }
-}
-
-
-
-/* run this for single and multithreaded painting */
-static void *do_projectpaint_thread(void *ph_v)
-{
- /* First unpack args from the struct */
- ProjPaintState *ps = ((ProjectHandle *)ph_v)->ps;
- ProjPaintImage *projImages = ((ProjectHandle *)ph_v)->projImages;
- const float *lastpos = ((ProjectHandle *)ph_v)->prevmval;
- const float *pos = ((ProjectHandle *)ph_v)->mval;
- const int thread_index = ((ProjectHandle *)ph_v)->thread_index;
- struct ImagePool *pool = ((ProjectHandle *)ph_v)->pool;
- /* Done with args from ProjectHandle */
-
- LinkNode *node;
- ProjPixel *projPixel;
- Brush *brush = ps->brush;
-
- int last_index = -1;
- ProjPaintImage *last_projIma = NULL;
- ImagePaintPartialRedraw *last_partial_redraw_cell;
-
- float rgba[4], alpha, dist_nosqrt, dist;
-
- float falloff;
- int bucket_index;
- int is_floatbuf = 0;
- int use_color_correction = FALSE;
- const short tool = ps->tool;
- rctf bucket_bounds;
-
- /* for smear only */
- float pos_ofs[2] = {0};
- float co[2];
- float mask = 1.0f; /* airbrush wont use mask */
- unsigned short mask_short;
- const float radius = (float)BKE_brush_size_get(ps->scene, brush);
- const float radius_squared = radius * radius; /* avoid a square root with every dist comparison */
-
- short lock_alpha = ELEM(brush->blend, IMB_BLEND_ERASE_ALPHA, IMB_BLEND_ADD_ALPHA) ? 0 : brush->flag & BRUSH_LOCK_ALPHA;
-
- LinkNode *smearPixels = NULL;
- LinkNode *smearPixels_f = NULL;
- MemArena *smearArena = NULL; /* mem arena for this brush projection only */
-
- LinkNode *softenPixels = NULL;
- LinkNode *softenPixels_f = NULL;
- MemArena *softenArena = NULL; /* mem arena for this brush projection only */
-
- if (tool == PAINT_TOOL_SMEAR) {
- pos_ofs[0] = pos[0] - lastpos[0];
- pos_ofs[1] = pos[1] - lastpos[1];
-
- smearArena = BLI_memarena_new(1 << 16, "paint smear arena");
- }
- else if (tool == PAINT_TOOL_SOFTEN) {
- softenArena = BLI_memarena_new(1 << 16, "paint soften arena");
- }
-
- /* printf("brush bounds %d %d %d %d\n", bucketMin[0], bucketMin[1], bucketMax[0], bucketMax[1]); */
-
- while (project_bucket_iter_next(ps, &bucket_index, &bucket_bounds, pos)) {
-
- /* Check this bucket and its faces are initialized */
- if (ps->bucketFlags[bucket_index] == PROJ_BUCKET_NULL) {
- /* No pixels initialized */
- project_bucket_init(ps, thread_index, bucket_index, &bucket_bounds);
- }
-
- if (ps->source != PROJ_SRC_VIEW) {
-
- /* Re-Projection, simple, no brushes! */
-
- for (node = ps->bucketRect[bucket_index]; node; node = node->next) {
- projPixel = (ProjPixel *)node->link;
-
- /* copy of code below */
- if (last_index != projPixel->image_index) {
- last_index = projPixel->image_index;
- last_projIma = projImages + last_index;
-
- last_projIma->touch = 1;
- is_floatbuf = last_projIma->ibuf->rect_float ? 1 : 0;
- use_color_correction = TRUE;
- }
- /* end copy */
-
- if (is_floatbuf) {
- /* re-project buffer is assumed byte - TODO, allow float */
- bicubic_interpolation_color(ps->reproject_ibuf, projPixel->newColor.ch, NULL,
- projPixel->projCoSS[0], projPixel->projCoSS[1]);
- if (projPixel->newColor.ch[3]) {
- mask = ((float)projPixel->mask) / 65535.0f;
- blend_color_mix_accum_float(projPixel->pixel.f_pt, projPixel->origColor.f,
- projPixel->newColor.ch, (mask * (projPixel->newColor.ch[3] / 255.0f)));
- }
- }
- else {
- /* re-project buffer is assumed byte - TODO, allow float */
- bicubic_interpolation_color(ps->reproject_ibuf, projPixel->newColor.ch, NULL,
- projPixel->projCoSS[0], projPixel->projCoSS[1]);
- if (projPixel->newColor.ch[3]) {
- mask = ((float)projPixel->mask) / 65535.0f;
- blend_color_mix_accum(projPixel->pixel.ch_pt, projPixel->origColor.ch,
- projPixel->newColor.ch, (int)(mask * projPixel->newColor.ch[3]));
- }
- }
- }
- }
- else {
- /* Normal brush painting */
-
- for (node = ps->bucketRect[bucket_index]; node; node = node->next) {
-
- projPixel = (ProjPixel *)node->link;
-
- dist_nosqrt = len_squared_v2v2(projPixel->projCoSS, pos);
-
- /*if (dist < radius) {*/ /* correct but uses a sqrtf */
- if (dist_nosqrt <= radius_squared) {
- float samplecos[3];
- dist = sqrtf(dist_nosqrt);
-
- falloff = BKE_brush_curve_strength_clamp(ps->brush, dist, radius);
-
- if (ps->is_texbrush) {
- MTex *mtex = &brush->mtex;
- if (mtex->brush_map_mode == MTEX_MAP_MODE_VIEW) {
- sub_v2_v2v2(samplecos, projPixel->projCoSS, pos);
- }
- /* taking 3d copy to account for 3D mapping too. It gets concatenated during sampling */
- else if (mtex->brush_map_mode == MTEX_MAP_MODE_3D)
- copy_v3_v3(samplecos, projPixel->worldCoSS);
- else
- copy_v3_v3(samplecos, projPixel->projCoSS);
- }
-
- if (falloff > 0.0f) {
- if (ps->is_texbrush) {
- /* note, for clone and smear, we only use the alpha, could be a special function */
- BKE_brush_sample_tex(ps->scene, brush, samplecos, rgba, thread_index, pool);
- alpha = rgba[3];
- }
- else {
- alpha = 1.0f;
- }
-
- if (!ps->do_masking) {
- /* for an aurbrush there is no real mask, so just multiply the alpha by it */
- alpha *= falloff * BKE_brush_alpha_get(ps->scene, brush);
- mask = ((float)projPixel->mask) / 65535.0f;
- }
- else {
- /* This brush dosnt accumulate so add some curve to the brushes falloff */
- falloff = 1.0f - falloff;
- falloff = 1.0f - (falloff * falloff);
-
- mask_short = (unsigned short)(projPixel->mask * (BKE_brush_alpha_get(ps->scene, brush) * falloff));
- if (mask_short > projPixel->mask_max) {
- mask = ((float)mask_short) / 65535.0f;
- projPixel->mask_max = mask_short;
- }
- else {
- /*mask = ((float)projPixel->mask_max)/65535.0f;*/
-
- /* Go onto the next pixel */
- continue;
- }
- }
-
- if (alpha > 0.0f) {
-
- /* copy of code above */
- if (last_index != projPixel->image_index) {
- last_index = projPixel->image_index;
- last_projIma = projImages + last_index;
-
- last_projIma->touch = 1;
- is_floatbuf = last_projIma->ibuf->rect_float ? 1 : 0;
- use_color_correction = TRUE;
- }
- /* end copy */
-
- last_partial_redraw_cell = last_projIma->partRedrawRect + projPixel->bb_cell_index;
- last_partial_redraw_cell->x1 = min_ii(last_partial_redraw_cell->x1, (int)projPixel->x_px);
- last_partial_redraw_cell->y1 = min_ii(last_partial_redraw_cell->y1, (int)projPixel->y_px);
-
- last_partial_redraw_cell->x2 = max_ii(last_partial_redraw_cell->x2, (int)projPixel->x_px + 1);
- last_partial_redraw_cell->y2 = max_ii(last_partial_redraw_cell->y2, (int)projPixel->y_px + 1);
-
-
- switch (tool) {
- case PAINT_TOOL_CLONE:
- if (is_floatbuf) {
- if (((ProjPixelClone *)projPixel)->clonepx.f[3]) {
- do_projectpaint_clone_f(ps, projPixel, alpha, mask); /* rgba isn't used for cloning, only alpha */
- }
- }
- else {
- if (((ProjPixelClone *)projPixel)->clonepx.ch[3]) {
- do_projectpaint_clone(ps, projPixel, alpha, mask); /* rgba isn't used for cloning, only alpha */
- }
- }
- break;
- case PAINT_TOOL_SMEAR:
- sub_v2_v2v2(co, projPixel->projCoSS, pos_ofs);
-
- if (is_floatbuf) do_projectpaint_smear_f(ps, projPixel, alpha, mask, smearArena, &smearPixels_f, co);
- else do_projectpaint_smear(ps, projPixel, alpha, mask, smearArena, &smearPixels, co);
- break;
- case PAINT_TOOL_SOFTEN:
- if (is_floatbuf) do_projectpaint_soften_f(ps, projPixel, alpha, mask, softenArena, &softenPixels_f);
- else do_projectpaint_soften(ps, projPixel, alpha, mask, softenArena, &softenPixels);
- break;
- default:
- if (is_floatbuf) do_projectpaint_draw_f(ps, projPixel, rgba, alpha, mask, use_color_correction);
- else do_projectpaint_draw(ps, projPixel, rgba, alpha, mask);
- break;
- }
- }
-
- if (lock_alpha) {
- if (is_floatbuf) projPixel->pixel.f_pt[3] = projPixel->origColor.f[3];
- else projPixel->pixel.ch_pt[3] = projPixel->origColor.ch[3];
- }
-
- /* done painting */
- }
- }
- }
- }
- }
-
-
- if (tool == PAINT_TOOL_SMEAR) {
-
- for (node = smearPixels; node; node = node->next) { /* this wont run for a float image */
- projPixel = node->link;
- *projPixel->pixel.uint_pt = ((ProjPixelClone *)projPixel)->clonepx.uint;
- }
-
- for (node = smearPixels_f; node; node = node->next) {
- projPixel = node->link;
- copy_v4_v4(projPixel->pixel.f_pt, ((ProjPixelClone *)projPixel)->clonepx.f);
- }
-
- BLI_memarena_free(smearArena);
- }
- else if (tool == PAINT_TOOL_SOFTEN) {
-
- for (node = softenPixels; node; node = node->next) { /* this wont run for a float image */
- projPixel = node->link;
- *projPixel->pixel.uint_pt = projPixel->newColor.uint;
- }
-
- for (node = softenPixels_f; node; node = node->next) {
- projPixel = node->link;
- copy_v4_v4(projPixel->pixel.f_pt, projPixel->newColor.f);
- }
-
- BLI_memarena_free(softenArena);
- }
-
- return NULL;
-}
-
-static int project_paint_op(void *state, ImBuf *UNUSED(ibufb), const float lastpos[2], const float pos[2])
-{
- /* First unpack args from the struct */
- ProjPaintState *ps = (ProjPaintState *)state;
- int touch_any = 0;
-
- ProjectHandle handles[BLENDER_MAX_THREADS];
- ListBase threads;
- int a, i;
-
- struct ImagePool *pool;
-
- if (!project_bucket_iter_init(ps, pos)) {
- return 0;
- }
-
- if (ps->thread_tot > 1)
- BLI_init_threads(&threads, do_projectpaint_thread, ps->thread_tot);
-
- pool = BKE_image_pool_new();
-
- /* get the threads running */
- for (a = 0; a < ps->thread_tot; a++) {
-
- /* set defaults in handles */
- //memset(&handles[a], 0, sizeof(BakeShade));
-
- handles[a].ps = ps;
- copy_v2_v2(handles[a].mval, pos);
- copy_v2_v2(handles[a].prevmval, lastpos);
-
- /* thread specific */
- handles[a].thread_index = a;
-
- handles[a].projImages = (ProjPaintImage *)BLI_memarena_alloc(ps->arena_mt[a], ps->image_tot * sizeof(ProjPaintImage));
-
- memcpy(handles[a].projImages, ps->projImages, ps->image_tot * sizeof(ProjPaintImage));
-
- /* image bounds */
- for (i = 0; i < ps->image_tot; i++) {
- handles[a].projImages[i].partRedrawRect = (ImagePaintPartialRedraw *)BLI_memarena_alloc(ps->arena_mt[a], sizeof(ImagePaintPartialRedraw) * PROJ_BOUNDBOX_SQUARED);
- memcpy(handles[a].projImages[i].partRedrawRect, ps->projImages[i].partRedrawRect, sizeof(ImagePaintPartialRedraw) * PROJ_BOUNDBOX_SQUARED);
- }
-
- handles[a].pool = pool;
-
- if (ps->thread_tot > 1)
- BLI_insert_thread(&threads, &handles[a]);
- }
-
- if (ps->thread_tot > 1) /* wait for everything to be done */
- BLI_end_threads(&threads);
- else
- do_projectpaint_thread(&handles[0]);
-
-
- BKE_image_pool_free(pool);
-
- /* move threaded bounds back into ps->projectPartialRedraws */
- for (i = 0; i < ps->image_tot; i++) {
- int touch = 0;
- for (a = 0; a < ps->thread_tot; a++) {
- touch |= partial_redraw_array_merge(ps->projImages[i].partRedrawRect, handles[a].projImages[i].partRedrawRect, PROJ_BOUNDBOX_SQUARED);
- }
-
- if (touch) {
- ps->projImages[i].touch = 1;
- touch_any = 1;
- }
- }
-
- return touch_any;
-}
-
-
-static int project_paint_sub_stroke(ProjPaintState *ps, BrushPainter *painter, const int UNUSED(prevmval_i[2]), const int mval_i[2], double time, float pressure)
-{
-
- /* Use mouse coords as floats for projection painting */
- float pos[2];
-
- pos[0] = (float)(mval_i[0]);
- pos[1] = (float)(mval_i[1]);
-
- // we may want to use this later
- // BKE_brush_painter_require_imbuf(painter, ((ibuf->rect_float) ? 1 : 0), 0, 0);
-
- if (BKE_brush_painter_paint(painter, project_paint_op, pos, time, pressure, ps, 0)) {
- return 1;
- }
- else return 0;
-}
-
-
-static int project_paint_stroke(ProjPaintState *ps, BrushPainter *painter, const int prevmval_i[2], const int mval_i[2], double time, float pressure)
-{
- int a, redraw;
-
- for (a = 0; a < ps->image_tot; a++)
- partial_redraw_array_init(ps->projImages[a].partRedrawRect);
-
- redraw = project_paint_sub_stroke(ps, painter, prevmval_i, mval_i, time, pressure);
-
- if (project_image_refresh_tagged(ps))
- return redraw;
-
- return 0;
-}
-
/* Imagepaint Partial Redraw & Dirty Region */
-static void imapaint_clear_partial_redraw(void)
+void imapaint_clear_partial_redraw(void)
{
memset(&imapaintpartial, 0, sizeof(imapaintpartial));
}
-static void imapaint_dirty_region(Image *ima, ImBuf *ibuf, int x, int y, int w, int h)
+void imapaint_dirty_region(Image *ima, ImBuf *ibuf, int x, int y, int w, int h)
{
ImBuf *tmpibuf = NULL;
int srcx = 0, srcy = 0, origx;
@@ -4417,7 +315,7 @@ static void imapaint_dirty_region(Image *ima, ImBuf *ibuf, int x, int y, int w,
IMB_freeImBuf(tmpibuf);
}
-static void imapaint_image_update(SpaceImage *sima, Image *image, ImBuf *ibuf, short texpaint)
+void imapaint_image_update(SpaceImage *sima, Image *image, ImBuf *ibuf, short texpaint)
{
if (imapaintpartial.x1 != imapaintpartial.x2 &&
imapaintpartial.y1 != imapaintpartial.y2)
@@ -4438,447 +336,6 @@ static void imapaint_image_update(SpaceImage *sima, Image *image, ImBuf *ibuf, s
}
}
-/* Image Paint Operations */
-
-/* keep these functions in sync */
-static void imapaint_ibuf_rgb_get(ImBuf *ibuf, int x, int y, const short is_torus, float r_rgb[3])
-{
- if (is_torus) {
- x %= ibuf->x;
- if (x < 0) x += ibuf->x;
- y %= ibuf->y;
- if (y < 0) y += ibuf->y;
- }
-
- if (ibuf->rect_float) {
- float *rrgbf = ibuf->rect_float + (ibuf->x * y + x) * 4;
- IMAPAINT_FLOAT_RGB_COPY(r_rgb, rrgbf);
- }
- else {
- char *rrgb = (char *)ibuf->rect + (ibuf->x * y + x) * 4;
- IMAPAINT_CHAR_RGB_TO_FLOAT(r_rgb, rrgb);
- }
-}
-static void imapaint_ibuf_rgb_set(ImBuf *ibuf, int x, int y, const short is_torus, const float rgb[3])
-{
- if (is_torus) {
- x %= ibuf->x;
- if (x < 0) x += ibuf->x;
- y %= ibuf->y;
- if (y < 0) y += ibuf->y;
- }
-
- if (ibuf->rect_float) {
- float *rrgbf = ibuf->rect_float + (ibuf->x * y + x) * 4;
- IMAPAINT_FLOAT_RGB_COPY(rrgbf, rgb);
- }
- else {
- char *rrgb = (char *)ibuf->rect + (ibuf->x * y + x) * 4;
- IMAPAINT_FLOAT_RGB_TO_CHAR(rrgb, rgb);
- }
-}
-
-static int imapaint_ibuf_add_if(ImBuf *ibuf, unsigned int x, unsigned int y, float *outrgb, short torus)
-{
- float inrgb[3];
-
- // XXX: signed unsigned mismatch
- if ((x >= (unsigned int)(ibuf->x)) || (y >= (unsigned int)(ibuf->y))) {
- if (torus) imapaint_ibuf_rgb_get(ibuf, x, y, 1, inrgb);
- else return 0;
- }
- else {
- imapaint_ibuf_rgb_get(ibuf, x, y, 0, inrgb);
- }
-
- outrgb[0] += inrgb[0];
- outrgb[1] += inrgb[1];
- outrgb[2] += inrgb[2];
-
- return 1;
-}
-
-static void imapaint_lift_soften(ImBuf *ibuf, ImBuf *ibufb, int *pos, const short is_torus)
-{
- int x, y, count, xi, yi, xo, yo;
- int out_off[2], in_off[2], dim[2];
- float outrgb[3];
-
- dim[0] = ibufb->x;
- dim[1] = ibufb->y;
- in_off[0] = pos[0];
- in_off[1] = pos[1];
- out_off[0] = out_off[1] = 0;
-
- if (!is_torus) {
- IMB_rectclip(ibuf, ibufb, &in_off[0], &in_off[1], &out_off[0],
- &out_off[1], &dim[0], &dim[1]);
-
- if ((dim[0] == 0) || (dim[1] == 0))
- return;
- }
-
- for (y = 0; y < dim[1]; y++) {
- for (x = 0; x < dim[0]; x++) {
- /* get input pixel */
- xi = in_off[0] + x;
- yi = in_off[1] + y;
-
- count = 1;
- imapaint_ibuf_rgb_get(ibuf, xi, yi, is_torus, outrgb);
-
- count += imapaint_ibuf_add_if(ibuf, xi - 1, yi - 1, outrgb, is_torus);
- count += imapaint_ibuf_add_if(ibuf, xi - 1, yi, outrgb, is_torus);
- count += imapaint_ibuf_add_if(ibuf, xi - 1, yi + 1, outrgb, is_torus);
-
- count += imapaint_ibuf_add_if(ibuf, xi, yi - 1, outrgb, is_torus);
- count += imapaint_ibuf_add_if(ibuf, xi, yi + 1, outrgb, is_torus);
-
- count += imapaint_ibuf_add_if(ibuf, xi + 1, yi - 1, outrgb, is_torus);
- count += imapaint_ibuf_add_if(ibuf, xi + 1, yi, outrgb, is_torus);
- count += imapaint_ibuf_add_if(ibuf, xi + 1, yi + 1, outrgb, is_torus);
-
- mul_v3_fl(outrgb, 1.0f / (float)count);
-
- /* write into brush buffer */
- xo = out_off[0] + x;
- yo = out_off[1] + y;
- imapaint_ibuf_rgb_set(ibufb, xo, yo, 0, outrgb);
- }
- }
-}
-
-static void imapaint_set_region(ImagePaintRegion *region, int destx, int desty, int srcx, int srcy, int width, int height)
-{
- region->destx = destx;
- region->desty = desty;
- region->srcx = srcx;
- region->srcy = srcy;
- region->width = width;
- region->height = height;
-}
-
-static int imapaint_torus_split_region(ImagePaintRegion region[4], ImBuf *dbuf, ImBuf *sbuf)
-{
- int destx = region->destx;
- int desty = region->desty;
- int srcx = region->srcx;
- int srcy = region->srcy;
- int width = region->width;
- int height = region->height;
- int origw, origh, w, h, tot = 0;
-
- /* convert destination and source coordinates to be within image */
- destx = destx % dbuf->x;
- if (destx < 0) destx += dbuf->x;
- desty = desty % dbuf->y;
- if (desty < 0) desty += dbuf->y;
- srcx = srcx % sbuf->x;
- if (srcx < 0) srcx += sbuf->x;
- srcy = srcy % sbuf->y;
- if (srcy < 0) srcy += sbuf->y;
-
- /* clip width of blending area to destination imbuf, to avoid writing the
- * same pixel twice */
- origw = w = (width > dbuf->x) ? dbuf->x : width;
- origh = h = (height > dbuf->y) ? dbuf->y : height;
-
- /* clip within image */
- IMB_rectclip(dbuf, sbuf, &destx, &desty, &srcx, &srcy, &w, &h);
- imapaint_set_region(&region[tot++], destx, desty, srcx, srcy, w, h);
-
- /* do 3 other rects if needed */
- if (w < origw)
- imapaint_set_region(&region[tot++], (destx + w) % dbuf->x, desty, (srcx + w) % sbuf->x, srcy, origw - w, h);
- if (h < origh)
- imapaint_set_region(&region[tot++], destx, (desty + h) % dbuf->y, srcx, (srcy + h) % sbuf->y, w, origh - h);
- if ((w < origw) && (h < origh))
- imapaint_set_region(&region[tot++], (destx + w) % dbuf->x, (desty + h) % dbuf->y, (srcx + w) % sbuf->x, (srcy + h) % sbuf->y, origw - w, origh - h);
-
- return tot;
-}
-
-static void imapaint_lift_smear(ImBuf *ibuf, ImBuf *ibufb, int *pos)
-{
- ImagePaintRegion region[4];
- int a, tot;
-
- imapaint_set_region(region, 0, 0, pos[0], pos[1], ibufb->x, ibufb->y);
- tot = imapaint_torus_split_region(region, ibufb, ibuf);
-
- for (a = 0; a < tot; a++)
- IMB_rectblend(ibufb, ibuf, region[a].destx, region[a].desty,
- region[a].srcx, region[a].srcy,
- region[a].width, region[a].height, IMB_BLEND_COPY_RGB);
-}
-
-static ImBuf *imapaint_lift_clone(ImBuf *ibuf, ImBuf *ibufb, int *pos)
-{
- /* note: allocImbuf returns zero'd memory, so regions outside image will
- * have zero alpha, and hence not be blended onto the image */
- int w = ibufb->x, h = ibufb->y, destx = 0, desty = 0, srcx = pos[0], srcy = pos[1];
- ImBuf *clonebuf = IMB_allocImBuf(w, h, ibufb->planes, ibufb->flags);
-
- IMB_rectclip(clonebuf, ibuf, &destx, &desty, &srcx, &srcy, &w, &h);
- IMB_rectblend(clonebuf, ibuf, destx, desty, srcx, srcy, w, h,
- IMB_BLEND_COPY_RGB);
- IMB_rectblend(clonebuf, ibufb, destx, desty, destx, desty, w, h,
- IMB_BLEND_COPY_ALPHA);
-
- return clonebuf;
-}
-
-static void imapaint_convert_brushco(ImBuf *ibufb, const float pos[2], int ipos[2])
-{
- ipos[0] = (int)floorf((pos[0] - ibufb->x / 2) + 1.0f);
- ipos[1] = (int)floorf((pos[1] - ibufb->y / 2) + 1.0f);
-}
-
-/* dosnt run for projection painting
- * only the old style painting in the 3d view */
-static int imapaint_paint_op(void *state, ImBuf *ibufb, const float lastpos[2], const float pos[2])
-{
- ImagePaintState *s = ((ImagePaintState *)state);
- ImBuf *clonebuf = NULL, *frombuf;
- ImagePaintRegion region[4];
- short torus = s->brush->flag & BRUSH_TORUS;
- short blend = s->blend;
- float *offset = s->brush->clone.offset;
- float liftpos[2];
- int bpos[2], blastpos[2], bliftpos[2];
- int a, tot;
-
- imapaint_convert_brushco(ibufb, pos, bpos);
-
- /* lift from canvas */
- if (s->tool == PAINT_TOOL_SOFTEN) {
- imapaint_lift_soften(s->canvas, ibufb, bpos, torus);
- }
- else if (s->tool == PAINT_TOOL_SMEAR) {
- if (lastpos[0] == pos[0] && lastpos[1] == pos[1])
- return 0;
-
- imapaint_convert_brushco(ibufb, lastpos, blastpos);
- imapaint_lift_smear(s->canvas, ibufb, blastpos);
- }
- else if (s->tool == PAINT_TOOL_CLONE && s->clonecanvas) {
- liftpos[0] = pos[0] - offset[0] * s->canvas->x;
- liftpos[1] = pos[1] - offset[1] * s->canvas->y;
-
- imapaint_convert_brushco(ibufb, liftpos, bliftpos);
- clonebuf = imapaint_lift_clone(s->clonecanvas, ibufb, bliftpos);
- }
-
- frombuf = (clonebuf) ? clonebuf : ibufb;
-
- if (torus) {
- imapaint_set_region(region, bpos[0], bpos[1], 0, 0, frombuf->x, frombuf->y);
- tot = imapaint_torus_split_region(region, s->canvas, frombuf);
- }
- else {
- imapaint_set_region(region, bpos[0], bpos[1], 0, 0, frombuf->x, frombuf->y);
- tot = 1;
- }
-
- /* blend into canvas */
- for (a = 0; a < tot; a++) {
- imapaint_dirty_region(s->image, s->canvas,
- region[a].destx, region[a].desty,
- region[a].width, region[a].height);
-
- IMB_rectblend(s->canvas, frombuf,
- region[a].destx, region[a].desty,
- region[a].srcx, region[a].srcy,
- region[a].width, region[a].height, blend);
- }
-
- if (clonebuf) IMB_freeImBuf(clonebuf);
-
- return 1;
-}
-
-/* 3D TexturePaint */
-
-static int texpaint_break_stroke(float *prevuv, float *fwuv, float *bkuv, float *uv)
-{
- float d1[2], d2[2];
- float mismatch = len_v2v2(fwuv, uv);
- float len1 = len_v2v2(prevuv, fwuv);
- float len2 = len_v2v2(bkuv, uv);
-
- sub_v2_v2v2(d1, fwuv, prevuv);
- sub_v2_v2v2(d2, uv, bkuv);
-
- return ((dot_v2v2(d1, d2) < 0.0f) || (mismatch > MAX2(len1, len2) * 2));
-}
-
-/* ImagePaint Common */
-
-static int imapaint_canvas_set(ImagePaintState *s, Image *ima)
-{
- ImBuf *ibuf = BKE_image_acquire_ibuf(ima, s->sima ? &s->sima->iuser : NULL, NULL);
-
- /* verify that we can paint and set canvas */
- if (ima == NULL) {
- return 0;
- }
- else if (ima->packedfile && ima->rr) {
- s->warnpackedfile = ima->id.name + 2;
- return 0;
- }
- else if (ibuf && ibuf->channels != 4) {
- s->warnmultifile = ima->id.name + 2;
- return 0;
- }
- else if (!ibuf || !(ibuf->rect || ibuf->rect_float))
- return 0;
-
- s->image = ima;
- s->canvas = ibuf;
-
- /* set clone canvas */
- if (s->tool == PAINT_TOOL_CLONE) {
- ima = s->brush->clone.image;
- ibuf = BKE_image_acquire_ibuf(ima, s->sima ? &s->sima->iuser : NULL, NULL);
-
- if (!ima || !ibuf || !(ibuf->rect || ibuf->rect_float)) {
- BKE_image_release_ibuf(ima, ibuf, NULL);
- BKE_image_release_ibuf(s->image, s->canvas, NULL);
- return 0;
- }
-
- s->clonecanvas = ibuf;
-
- /* temporarily add float rect for cloning */
- if (s->canvas->rect_float && !s->clonecanvas->rect_float) {
- IMB_float_from_rect(s->clonecanvas);
- }
- else if (!s->canvas->rect_float && !s->clonecanvas->rect)
- IMB_rect_from_float(s->clonecanvas);
- }
-
- return 1;
-}
-
-static void imapaint_canvas_free(ImagePaintState *s)
-{
- BKE_image_release_ibuf(s->image, s->canvas, NULL);
- BKE_image_release_ibuf(s->brush->clone.image, s->clonecanvas, NULL);
-}
-
-static int imapaint_paint_sub_stroke(ImagePaintState *s, BrushPainter *painter, Image *image, short texpaint, float *uv, double time, int update, float pressure)
-{
- ImBuf *ibuf = BKE_image_acquire_ibuf(image, s->sima ? &s->sima->iuser : NULL, NULL);
- float pos[2];
- int is_data;
-
- if (!ibuf)
- return 0;
-
- is_data = ibuf->colormanage_flag & IMB_COLORMANAGE_IS_DATA;
-
- pos[0] = uv[0] * ibuf->x;
- pos[1] = uv[1] * ibuf->y;
-
- BKE_brush_painter_require_imbuf(painter, ((ibuf->rect_float) ? 1 : 0), 0, 0);
-
- /* OCIO_TODO: float buffers are now always linear, so always use color correction
- * this should probably be changed when texture painting color space is supported
- */
- if (BKE_brush_painter_paint(painter, imapaint_paint_op, pos, time, pressure, s, is_data == FALSE)) {
- if (update)
- imapaint_image_update(s->sima, image, ibuf, texpaint);
- BKE_image_release_ibuf(image, ibuf, NULL);
- return 1;
- }
- else {
- BKE_image_release_ibuf(image, ibuf, NULL);
- return 0;
- }
-}
-
-static int imapaint_paint_stroke(ViewContext *vc, ImagePaintState *s, BrushPainter *painter, short texpaint, const int prevmval[2], const int mval[2], double time, float pressure)
-{
- Image *newimage = NULL;
- float fwuv[2], bkuv[2], newuv[2];
- unsigned int newfaceindex;
- int breakstroke = 0, redraw = 0;
-
- if (texpaint) {
- /* pick new face and image */
- if (imapaint_pick_face(vc, mval, &newfaceindex, s->dm_totface) &&
- ((s->do_facesel == FALSE) || (s->dm_mface[newfaceindex].flag & ME_FACE_SEL)))
- {
- ImBuf *ibuf;
-
- newimage = imapaint_face_image(s, newfaceindex);
- ibuf = BKE_image_acquire_ibuf(newimage, s->sima ? &s->sima->iuser : NULL, NULL);
-
- if (ibuf && ibuf->rect)
- imapaint_pick_uv(s->scene, s->ob, newfaceindex, mval, newuv);
- else {
- newimage = NULL;
- newuv[0] = newuv[1] = 0.0f;
- }
-
- BKE_image_release_ibuf(newimage, ibuf, NULL);
- }
- else
- newuv[0] = newuv[1] = 0.0f;
-
- /* see if stroke is broken, and if so finish painting in old position */
- if (s->image) {
- imapaint_pick_uv(s->scene, s->ob, s->faceindex, mval, fwuv);
- imapaint_pick_uv(s->scene, s->ob, newfaceindex, prevmval, bkuv);
-
- if (newimage == s->image)
- breakstroke = texpaint_break_stroke(s->uv, fwuv, bkuv, newuv);
- else
- breakstroke = 1;
- }
- else
- fwuv[0] = fwuv[1] = 0.0f;
-
- if (breakstroke) {
- imapaint_pick_uv(s->scene, s->ob, s->faceindex, mval, fwuv);
- redraw |= imapaint_paint_sub_stroke(s, painter, s->image, texpaint,
- fwuv, time, 1, pressure);
- imapaint_clear_partial_redraw();
- BKE_brush_painter_break_stroke(painter);
- }
-
- /* set new canvas */
- if (newimage && (newimage != s->image))
- if (!imapaint_canvas_set(s, newimage))
- newimage = NULL;
-
- /* paint in new image */
- if (newimage) {
- if (breakstroke)
- redraw |= imapaint_paint_sub_stroke(s, painter, newimage,
- texpaint, bkuv, time, 0, pressure);
- redraw |= imapaint_paint_sub_stroke(s, painter, newimage, texpaint,
- newuv, time, 1, pressure);
- }
-
- /* update state */
- s->image = newimage;
- s->faceindex = newfaceindex;
- s->uv[0] = newuv[0];
- s->uv[1] = newuv[1];
- }
- else {
- UI_view2d_region_to_view(s->v2d, mval[0], mval[1], &newuv[0], &newuv[1]);
- redraw |= imapaint_paint_sub_stroke(s, painter, s->image, texpaint, newuv,
- time, 1, pressure);
- }
-
- if (redraw)
- imapaint_clear_partial_redraw();
-
- return redraw;
-}
-
/************************ image paint poll ************************/
static Brush *image_paint_brush(bContext *C)
@@ -4889,16 +346,6 @@ static Brush *image_paint_brush(bContext *C)
return paint_brush(&settings->imapaint.paint);
}
-static Brush *uv_sculpt_brush(bContext *C)
-{
- Scene *scene = CTX_data_scene(C);
- ToolSettings *settings = scene->toolsettings;
-
- if (!settings->uvsculpt)
- return NULL;
- return paint_brush(&settings->uvsculpt->paint);
-}
-
static int image_paint_poll(bContext *C)
{
Object *obact = CTX_data_active_object(C);
@@ -4924,38 +371,6 @@ static int image_paint_poll(bContext *C)
return 0;
}
-static int uv_sculpt_brush_poll(bContext *C)
-{
- BMEditMesh *em;
- int ret;
- Object *obedit = CTX_data_edit_object(C);
- SpaceImage *sima = CTX_wm_space_image(C);
- Scene *scene = CTX_data_scene(C);
- ToolSettings *toolsettings = scene->toolsettings;
-
- if (!uv_sculpt_brush(C) || !obedit || obedit->type != OB_MESH)
- return 0;
-
- em = BMEdit_FromObject(obedit);
- ret = EDBM_mtexpoly_check(em);
-
- if (ret && sima) {
- ARegion *ar = CTX_wm_region(C);
- if ((toolsettings->use_uv_sculpt) && ar->regiontype == RGN_TYPE_WINDOW)
- return 1;
- }
-
- return 0;
-}
-
-static int image_paint_3d_poll(bContext *C)
-{
- if (CTX_wm_region_view3d(C))
- return image_paint_poll(C);
-
- return 0;
-}
-
static int image_paint_2d_clone_poll(bContext *C)
{
Brush *brush = image_paint_brush(C);
@@ -4969,339 +384,173 @@ static int image_paint_2d_clone_poll(bContext *C)
}
/************************ paint operator ************************/
-
-typedef enum PaintMode {
+typedef enum TexPaintMode {
PAINT_MODE_2D,
- PAINT_MODE_3D,
PAINT_MODE_3D_PROJECT
-} PaintMode;
+} TexPaintMode;
typedef struct PaintOperation {
- PaintMode mode;
+ TexPaintMode mode;
- BrushPainter *painter;
- ImagePaintState s;
- ProjPaintState ps;
+ void *custom_paint;
- int first;
int prevmouse[2];
- int orig_brush_size;
double starttime;
ViewContext vc;
wmTimer *timer;
-
- short restore_projection;
} PaintOperation;
-static void paint_redraw(bContext *C, ImagePaintState *s, int texpaint, int final)
+void paint_brush_init_tex(Brush *brush)
{
- if (final) {
- if (s->image && !(texpaint || (s->sima && s->sima->lock)))
- GPU_free_image(s->image);
-
- /* compositor listener deals with updating */
- WM_event_add_notifier(C, NC_IMAGE | NA_EDITED, s->image);
- }
- else {
- if (!s->sima || !s->sima->lock)
- ED_region_tag_redraw(CTX_wm_region(C));
- else
- WM_event_add_notifier(C, NC_IMAGE | NA_EDITED, s->image);
+ /* init mtex nodes */
+ if (brush) {
+ MTex *mtex = &brush->mtex;
+ if (mtex->tex && mtex->tex->nodetree)
+ ntreeTexBeginExecTree(mtex->tex->nodetree, 1); /* has internal flag to detect it only does it once */
}
}
-/* initialize project paint settings from context */
-static void project_state_init(bContext *C, Object *ob, ProjPaintState *ps)
+void paint_brush_exit_tex(Brush *brush)
{
- Scene *scene = CTX_data_scene(C);
- ToolSettings *settings = scene->toolsettings;
-
- /* brush */
- ps->brush = paint_brush(&settings->imapaint.paint);
- if (ps->brush) {
- Brush *brush = ps->brush;
- ps->tool = brush->imagepaint_tool;
- ps->blend = brush->blend;
-
- /* disable for 3d mapping also because painting on mirrored mesh can create "stripes" */
- ps->do_masking = (brush->flag & BRUSH_AIRBRUSH || brush->mtex.brush_map_mode == MTEX_MAP_MODE_VIEW ||
- brush->mtex.brush_map_mode == MTEX_MAP_MODE_3D) ? false : true;
- ps->is_texbrush = (brush->mtex.tex) ? 1 : 0;
- }
- else {
- /* brush may be NULL*/
- ps->do_masking = false;
- ps->is_texbrush = false;
+ if (brush) {
+ MTex *mtex = &brush->mtex;
+ if (mtex->tex && mtex->tex->nodetree)
+ ntreeTexEndExecTree(mtex->tex->nodetree->execdata, 1);
}
+}
- /* sizeof(ProjPixel), since we alloc this a _lot_ */
- ps->pixel_sizeof = project_paint_pixel_sizeof(ps->tool);
- BLI_assert(ps->pixel_sizeof >= sizeof(ProjPixel));
-
- /* these can be NULL */
- ps->v3d = CTX_wm_view3d(C);
- ps->rv3d = CTX_wm_region_view3d(C);
- ps->ar = CTX_wm_region(C);
-
- ps->scene = scene;
- ps->ob = ob; /* allow override of active object */
-
- /* setup projection painting data */
- ps->do_backfacecull = (settings->imapaint.flag & IMAGEPAINT_PROJECT_BACKFACE) ? 0 : 1;
- ps->do_occlude = (settings->imapaint.flag & IMAGEPAINT_PROJECT_XRAY) ? 0 : 1;
- ps->do_mask_normal = (settings->imapaint.flag & IMAGEPAINT_PROJECT_FLAT) ? 0 : 1;
- ps->do_new_shading_nodes = BKE_scene_use_new_shading_nodes(scene); /* only cache the value */
-
- if (ps->tool == PAINT_TOOL_CLONE)
- ps->do_layer_clone = (settings->imapaint.flag & IMAGEPAINT_PROJECT_LAYER_CLONE);
-
- ps->do_layer_stencil = (settings->imapaint.flag & IMAGEPAINT_PROJECT_LAYER_STENCIL) ? 1 : 0;
- ps->do_layer_stencil_inv = (settings->imapaint.flag & IMAGEPAINT_PROJECT_LAYER_STENCIL_INV) ? 1 : 0;
-
-
-#ifndef PROJ_DEBUG_NOSEAMBLEED
- ps->seam_bleed_px = settings->imapaint.seam_bleed; /* pixel num to bleed */
-#endif
- if (ps->do_mask_normal) {
- ps->normal_angle_inner = settings->imapaint.normal_angle;
- ps->normal_angle = (ps->normal_angle_inner + 90.0f) * 0.5f;
+static void paint_redraw(const bContext *C, PaintOperation *pop, int final)
+{
+ if (pop->mode == PAINT_MODE_2D) {
+ paint_2d_redraw(C, pop->custom_paint, final);
}
else {
- ps->normal_angle_inner = ps->normal_angle = settings->imapaint.normal_angle;
- }
-
- ps->normal_angle_inner *= (float)(M_PI_2 / 90);
- ps->normal_angle *= (float)(M_PI_2 / 90);
- ps->normal_angle_range = ps->normal_angle - ps->normal_angle_inner;
-
- if (ps->normal_angle_range <= 0.0f)
- ps->do_mask_normal = FALSE; /* no need to do blending */
-}
-
-static void paint_brush_init_tex(Brush *brush)
-{
- /* init mtex nodes */
- if (brush) {
- MTex *mtex = &brush->mtex;
- if (mtex->tex && mtex->tex->nodetree)
- ntreeTexBeginExecTree(mtex->tex->nodetree, 1); /* has internal flag to detect it only does it once */
+ if (final) {
+ /* compositor listener deals with updating */
+ WM_event_add_notifier(C, NC_IMAGE | NA_EDITED, NULL);
+ }
+ else {
+ ED_region_tag_redraw(CTX_wm_region(C));
+ }
}
-
}
-static int texture_paint_init(bContext *C, wmOperator *op)
+static PaintOperation * texture_paint_init(bContext *C, wmOperator *op, const wmEvent *event)
{
Scene *scene = CTX_data_scene(C);
ToolSettings *settings = scene->toolsettings;
- Brush *brush = paint_brush(&settings->imapaint.paint);
PaintOperation *pop = MEM_callocN(sizeof(PaintOperation), "PaintOperation"); /* caller frees */
+ int mode = RNA_enum_get(op->ptr, "mode");
+ view3d_set_viewcontext(C, &pop->vc);
+
+ /* TODO Should avoid putting this here. Instead, last position should be requested
+ * from stroke system. */
+ pop->prevmouse[0] = event->mval[0];
+ pop->prevmouse[1] = event->mval[1];
- pop->first = 1;
- op->customdata = pop;
/* initialize from context */
if (CTX_wm_region_view3d(C)) {
- pop->mode = PAINT_MODE_3D;
-
- if (!(settings->imapaint.flag & IMAGEPAINT_PROJECT_DISABLE))
- pop->mode = PAINT_MODE_3D_PROJECT;
- else
- view3d_set_viewcontext(C, &pop->vc);
+ pop->mode = PAINT_MODE_3D_PROJECT;
+ pop->custom_paint = paint_proj_new_stroke(C, OBACT, pop->prevmouse, mode);
}
else {
- pop->s.sima = CTX_wm_space_image(C);
- pop->s.v2d = &CTX_wm_region(C)->v2d;
+ pop->mode = PAINT_MODE_2D;
+ pop->custom_paint = paint_2d_new_stroke(C, op);
}
- pop->s.scene = scene;
- pop->s.screen = CTX_wm_screen(C);
-
- pop->s.brush = brush;
- pop->s.tool = brush->imagepaint_tool;
- if (pop->mode == PAINT_MODE_3D && (pop->s.tool == PAINT_TOOL_CLONE))
- pop->s.tool = PAINT_TOOL_DRAW;
- pop->s.blend = brush->blend;
- pop->orig_brush_size = BKE_brush_size_get(scene, brush);
-
- if (pop->mode != PAINT_MODE_2D) {
- Object *ob = OBACT;
- Mesh *me = BKE_mesh_from_object(ob);
-
- if (!me) {
- return 0;
- }
-
- pop->s.ob = ob;
- pop->s.do_facesel = (me->editflag & ME_EDIT_PAINT_FACE_SEL) != 0;
-
- /* for non prohect paint we need */
- /* fill in derived mesh */
- if (ob->derivedFinal && CustomData_has_layer(&ob->derivedFinal->faceData, CD_MTFACE)) {
- pop->s.dm = ob->derivedFinal;
- pop->s.dm_release = FALSE;
- }
- else {
- pop->s.dm = mesh_get_derived_final(pop->s.scene, ob, pop->s.scene->customdata_mask | CD_MASK_MTFACE);
- pop->s.dm_release = TRUE;
- }
-
- if (!CustomData_has_layer(&pop->s.dm->faceData, CD_MTFACE)) {
-
- if (pop->s.dm_release)
- pop->s.dm->release(pop->s.dm);
-
- pop->s.dm = NULL;
- return 0;
- }
-
- pop->s.dm_mface = pop->s.dm->getTessFaceArray(pop->s.dm);
- pop->s.dm_mtface = pop->s.dm->getTessFaceDataArray(pop->s.dm, CD_MTFACE);
- pop->s.dm_totface = pop->s.dm->getNumTessFaces(pop->s.dm);
- }
- else {
- pop->s.image = pop->s.sima->image;
-
- if (!imapaint_canvas_set(&pop->s, pop->s.image)) {
- if (pop->s.warnmultifile)
- BKE_report(op->reports, RPT_WARNING, "Image requires 4 color channels to paint");
- if (pop->s.warnpackedfile)
- BKE_report(op->reports, RPT_WARNING, "Packed MultiLayer files cannot be painted");
-
- return 0;
- }
+ if (!pop->custom_paint) {
+ MEM_freeN(pop);
+ return NULL;
}
- /* note, if we have no UVs on the derived mesh, then we must return here */
- if (pop->mode == PAINT_MODE_3D_PROJECT) {
-
- /* initialize all data from the context */
- project_state_init(C, OBACT, &pop->ps);
-
- /* needed so multiple threads don't try to initialize the brush at once (can leak memory) */
- curvemapping_initialize(pop->ps.brush->curve);
-
- paint_brush_init_tex(pop->ps.brush);
-
- pop->ps.source = PROJ_SRC_VIEW;
-
- if (pop->ps.ob == NULL || !(pop->ps.ob->lay & pop->ps.v3d->lay))
- return 0;
-
- /* Don't allow brush size below 2 */
- if (BKE_brush_size_get(scene, brush) < 2)
- BKE_brush_size_set(scene, brush, 2);
-
- /* allocate and initialize spatial data structures */
- project_paint_begin(&pop->ps);
-
- if (pop->ps.dm == NULL)
- return 0;
- }
- else {
- paint_brush_init_tex(pop->s.brush);
- }
-
settings->imapaint.flag |= IMAGEPAINT_DRAWING;
undo_paint_push_begin(UNDO_PAINT_IMAGE, op->type->name,
image_undo_restore, image_undo_free);
- /* create painter */
- pop->painter = BKE_brush_painter_new(scene, pop->s.brush);
-
{
UnifiedPaintSettings *ups = &settings->unified_paint_settings;
ups->draw_pressure = true;
}
- return 1;
+ return pop;
}
-static void paint_apply(bContext *C, wmOperator *op, PointerRNA *itemptr)
+static void paint_stroke_update_step(bContext *C, struct PaintStroke *stroke, PointerRNA *itemptr)
{
- PaintOperation *pop = op->customdata;
- float time, mousef[2];
+ PaintOperation *pop = paint_stroke_mode_data(stroke);
+ Scene *scene = CTX_data_scene(C);
+ Brush *brush = paint_brush(&scene->toolsettings->imapaint.paint);
+
+ /* initial brush values. Maybe it should be considered moving these to stroke system */
+ float startsize = BKE_brush_size_get(scene, brush);
+ float startalpha = BKE_brush_alpha_get(scene, brush);
+
+ float mousef[2];
float pressure;
- int mouse[2], redraw;
+ int mouse[2], redraw, eraser;
RNA_float_get_array(itemptr, "mouse", mousef);
mouse[0] = (int)(mousef[0]);
mouse[1] = (int)(mousef[1]);
- time = RNA_float_get(itemptr, "time");
pressure = RNA_float_get(itemptr, "pressure");
+ eraser = RNA_boolean_get(itemptr, "pen_flip");
- if (pop->first)
- project_paint_begin_clone(&pop->ps, mouse);
-
- if (pop->mode == PAINT_MODE_3D)
- view3d_operator_needs_opengl(C);
+ if (BKE_brush_use_alpha_pressure(scene, brush))
+ BKE_brush_alpha_set(scene, brush, max_ff(0.0f, startalpha * pressure));
+ if (BKE_brush_use_size_pressure(scene, brush))
+ BKE_brush_size_set(scene, brush, max_ff(1.0f, startsize * pressure));
if (pop->mode == PAINT_MODE_3D_PROJECT) {
- redraw = project_paint_stroke(&pop->ps, pop->painter, pop->prevmouse, mouse, time, pressure);
- pop->prevmouse[0] = mouse[0];
- pop->prevmouse[1] = mouse[1];
-
+ redraw = paint_proj_stroke(C, pop->custom_paint, pop->prevmouse, mouse);
}
else {
- redraw = imapaint_paint_stroke(&pop->vc, &pop->s, pop->painter, pop->mode == PAINT_MODE_3D, pop->prevmouse, mouse, time, pressure);
- pop->prevmouse[0] = mouse[0];
- pop->prevmouse[1] = mouse[1];
+ redraw = paint_2d_stroke(pop->custom_paint, pop->prevmouse, mouse, eraser);
}
- if (redraw)
- paint_redraw(C, &pop->s, pop->mode == PAINT_MODE_3D, 0);
+ pop->prevmouse[0] = mouse[0];
+ pop->prevmouse[1] = mouse[1];
- pop->first = 0;
-}
+ /* restore brush values */
+ BKE_brush_alpha_set(scene, brush, startalpha);
+ BKE_brush_size_set(scene, brush, startsize);
+
+
+ if (redraw)
+ paint_redraw(C, pop, 0);
-static void paint_brush_exit_tex(Brush *brush)
-{
- if (brush) {
- MTex *mtex = &brush->mtex;
- if (mtex->tex && mtex->tex->nodetree)
- ntreeTexEndExecTree(mtex->tex->nodetree->execdata, 1);
- }
}
-static void paint_exit(bContext *C, wmOperator *op)
+static void paint_stroke_done(const bContext *C, struct PaintStroke *stroke)
{
Scene *scene = CTX_data_scene(C);
ToolSettings *settings = scene->toolsettings;
- PaintOperation *pop = op->customdata;
+ PaintOperation *pop = paint_stroke_mode_data(stroke);
+
+ paint_redraw(C, pop, 1);
if (pop->timer)
WM_event_remove_timer(CTX_wm_manager(C), CTX_wm_window(C), pop->timer);
- if (pop->restore_projection)
- settings->imapaint.flag &= ~IMAGEPAINT_PROJECT_DISABLE;
-
settings->imapaint.flag &= ~IMAGEPAINT_DRAWING;
- imapaint_canvas_free(&pop->s);
- BKE_brush_painter_free(pop->painter);
if (pop->mode == PAINT_MODE_3D_PROJECT) {
- BKE_brush_size_set(scene, pop->ps.brush, pop->orig_brush_size);
- paint_brush_exit_tex(pop->ps.brush);
-
- project_paint_end(&pop->ps);
+ paint_proj_stroke_done(pop->custom_paint);
}
else {
- paint_brush_exit_tex(pop->s.brush);
-
- /* non projection 3d paint, could move into own function of more needs adding */
- if (pop->s.dm_release)
- pop->s.dm->release(pop->s.dm);
+ paint_2d_stroke_done(pop->custom_paint);
}
-
- paint_redraw(C, &pop->s, pop->mode == PAINT_MODE_3D, 1);
+
undo_paint_push_end(UNDO_PAINT_IMAGE);
-
+
+ /* duplicate warning, see texpaint_init
if (pop->s.warnmultifile)
BKE_reportf(op->reports, RPT_WARNING, "Image requires 4 color channels to paint: %s", pop->s.warnmultifile);
if (pop->s.warnpackedfile)
BKE_reportf(op->reports, RPT_WARNING, "Packed MultiLayer files cannot be painted: %s", pop->s.warnpackedfile);
-
+ */
MEM_freeN(pop);
{
@@ -5310,159 +559,69 @@ static void paint_exit(bContext *C, wmOperator *op)
}
}
-static int paint_exec(bContext *C, wmOperator *op)
+static int paint_stroke_test_start(bContext *UNUSED(C), wmOperator *UNUSED(op), const float UNUSED(mouse[2]))
{
- if (!texture_paint_init(C, op)) {
- MEM_freeN(op->customdata);
- return OPERATOR_CANCELLED;
- }
-
- RNA_BEGIN (op->ptr, itemptr, "stroke")
- {
- paint_apply(C, op, &itemptr);
- }
- RNA_END;
-
- paint_exit(C, op);
-
- return OPERATOR_FINISHED;
+ return true;
}
-static void paint_apply_event(bContext *C, wmOperator *op, wmEvent *event)
-{
- const Scene *scene = CTX_data_scene(C);
- PaintOperation *pop = op->customdata;
- PointerRNA itemptr;
- float pressure, mousef[2];
- double time;
- int tablet;
-
- time = PIL_check_seconds_timer();
-
- tablet = 0;
- pop->s.blend = pop->s.brush->blend;
-
- if (event->tablet_data) {
- wmTabletData *wmtab = event->tablet_data;
-
- tablet = (wmtab->Active != EVT_TABLET_NONE);
- pressure = wmtab->Pressure;
- if (wmtab->Active == EVT_TABLET_ERASER)
- pop->s.blend = IMB_BLEND_ERASE_ALPHA;
- }
- else {
- BLI_assert(fabsf(WM_cursor_pressure(CTX_wm_window(C))) == 1.0f);
- pressure = 1.0f;
- }
-
- if (pop->first) {
- pop->prevmouse[0] = event->mval[0];
- pop->prevmouse[1] = event->mval[1];
- pop->starttime = time;
-
- /* special exception here for too high pressure values on first touch in
- * windows for some tablets, then we just skip first touch .. */
- if (tablet && (pressure >= 0.99f) && ((pop->s.brush->flag & BRUSH_SPACING_PRESSURE) || BKE_brush_use_alpha_pressure(scene, pop->s.brush) || BKE_brush_use_size_pressure(scene, pop->s.brush)))
- return;
-
- /* This can be removed once fixed properly in
- * BKE_brush_painter_paint(BrushPainter *painter, BrushFunc func, float *pos, double time, float pressure, void *user)
- * at zero pressure we should do nothing 1/2^12 is 0.0002 which is the sensitivity of the most sensitive pen tablet available */
- if (tablet && (pressure < 0.0002f) && ((pop->s.brush->flag & BRUSH_SPACING_PRESSURE) || BKE_brush_use_alpha_pressure(scene, pop->s.brush) || BKE_brush_use_size_pressure(scene, pop->s.brush)))
- return;
-
- }
-
- /* fill in stroke */
- RNA_collection_add(op->ptr, "stroke", &itemptr);
-
- mousef[0] = (float)(event->mval[0]);
- mousef[1] = (float)(event->mval[1]);
- RNA_float_set_array(&itemptr, "mouse", mousef);
- RNA_float_set(&itemptr, "time", (float)(time - pop->starttime));
- RNA_float_set(&itemptr, "pressure", pressure);
-
- /* apply */
- paint_apply(C, op, &itemptr);
-
- {
- UnifiedPaintSettings *ups = &scene->toolsettings->unified_paint_settings;
- ups->pressure_value = pressure;
- }
-}
-static int paint_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int paint_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
PaintOperation *pop;
+ struct PaintStroke *stroke;
+ int retval;
- if (!texture_paint_init(C, op)) {
- MEM_freeN(op->customdata);
+ if (!(pop = texture_paint_init(C, op, event))) {
return OPERATOR_CANCELLED;
}
- paint_apply_event(C, op, event);
-
- pop = op->customdata;
+ stroke = op->customdata = paint_stroke_new(C, NULL, paint_stroke_test_start,
+ paint_stroke_update_step,
+ paint_stroke_done, event->type);
+ paint_stroke_set_mode_data(stroke, pop);
+ /* add modal handler */
WM_event_add_modal_handler(C, op);
- if (pop->s.brush->flag & BRUSH_AIRBRUSH)
- pop->timer = WM_event_add_timer(CTX_wm_manager(C), CTX_wm_window(C), TIMER, 0.01f);
+ retval = op->type->modal(C, op, event);
+ OPERATOR_RETVAL_CHECK(retval);
+ BLI_assert(retval == OPERATOR_RUNNING_MODAL);
return OPERATOR_RUNNING_MODAL;
}
-static int paint_modal(bContext *C, wmOperator *op, wmEvent *event)
-{
- PaintOperation *pop = op->customdata;
-
- switch (event->type) {
- case LEFTMOUSE:
- case MIDDLEMOUSE:
- case RIGHTMOUSE: // XXX hardcoded
- paint_exit(C, op);
- return OPERATOR_FINISHED;
- case MOUSEMOVE:
- case INBETWEEN_MOUSEMOVE:
- paint_apply_event(C, op, event);
- break;
- case TIMER:
- if (event->customdata == pop->timer)
- paint_apply_event(C, op, event);
- break;
- }
-
- return OPERATOR_RUNNING_MODAL;
-}
-
-static int paint_cancel(bContext *C, wmOperator *op)
-{
- paint_exit(C, op);
-
- return OPERATOR_CANCELLED;
-}
void PAINT_OT_image_paint(wmOperatorType *ot)
{
+ static EnumPropertyItem stroke_mode_items[] = {
+ {BRUSH_STROKE_NORMAL, "NORMAL", 0, "Normal", "Apply brush normally"},
+ {BRUSH_STROKE_INVERT, "INVERT", 0, "Invert", "Invert action of brush for duration of stroke"},
+ {0}
+ };
+
/* identifiers */
ot->name = "Image Paint";
ot->idname = "PAINT_OT_image_paint";
ot->description = "Paint a stroke into the image";
-
+
/* api callbacks */
- ot->exec = paint_exec;
ot->invoke = paint_invoke;
- ot->modal = paint_modal;
- ot->cancel = paint_cancel;
+ ot->modal = paint_stroke_modal;
+ /* ot->exec = paint_exec; <-- needs stroke property */
ot->poll = image_paint_poll;
+ ot->cancel = paint_stroke_cancel;
/* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_BLOCKING;
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_BLOCKING;
+
+ RNA_def_enum(ot->srna, "mode", stroke_mode_items, BRUSH_STROKE_NORMAL,
+ "Paint Stroke Mode",
+ "Action taken when a paint stroke is made");
- /* properties */
RNA_def_collection_runtime(ot->srna, "stroke", &RNA_OperatorStrokeElement, "Stroke", "");
}
-static int get_imapaint_zoom(bContext *C, float *zoomx, float *zoomy)
+
+int get_imapaint_zoom(bContext *C, float *zoomx, float *zoomy)
{
RegionView3D *rv3d = CTX_wm_region_view3d(C);
@@ -5484,7 +643,7 @@ static int get_imapaint_zoom(bContext *C, float *zoomx, float *zoomy)
/************************ cursor drawing *******************************/
-static void brush_drawcursor(bContext *C, int x, int y, void *UNUSED(customdata))
+void brush_drawcursor_texpaint_uvsculpt(bContext *C, int x, int y, void *UNUSED(customdata))
{
#define PX_SIZE_FADE_MAX 12.0f
#define PX_SIZE_FADE_MIN 4.0f
@@ -5560,7 +719,8 @@ static void toggle_paint_cursor(bContext *C, int enable)
settings->imapaint.paintcursor = NULL;
}
else if (enable)
- settings->imapaint.paintcursor = WM_paint_cursor_activate(wm, image_paint_poll, brush_drawcursor, NULL);
+ settings->imapaint.paintcursor =
+ WM_paint_cursor_activate(wm, image_paint_poll, brush_drawcursor_texpaint_uvsculpt, NULL);
}
/* enable the paint cursor if it isn't already.
@@ -5587,32 +747,11 @@ void ED_space_image_paint_update(wmWindowManager *wm, ToolSettings *settings)
if (!imapaint->paintcursor) {
imapaint->paintcursor =
WM_paint_cursor_activate(wm, image_paint_poll,
- brush_drawcursor, NULL);
+ brush_drawcursor_texpaint_uvsculpt, NULL);
}
}
}
-
-void ED_space_image_uv_sculpt_update(wmWindowManager *wm, ToolSettings *settings)
-{
- if (settings->use_uv_sculpt) {
- if (!settings->uvsculpt) {
- settings->uvsculpt = MEM_callocN(sizeof(*settings->uvsculpt), "UV Smooth paint");
- settings->uv_sculpt_tool = UV_SCULPT_TOOL_GRAB;
- settings->uv_sculpt_settings = UV_SCULPT_LOCK_BORDERS | UV_SCULPT_ALL_ISLANDS;
- settings->uv_relax_method = UV_SCULPT_TOOL_RELAX_LAPLACIAN;
- }
-
- BKE_paint_init(&settings->uvsculpt->paint, PAINT_CURSOR_SCULPT);
-
- WM_paint_cursor_activate(wm, uv_sculpt_brush_poll,
- brush_drawcursor, NULL);
- }
- else {
- if (settings->uvsculpt)
- settings->uvsculpt->paint.flags &= ~PAINT_SHOW_BRUSH;
- }
-}
/************************ grab clone operator ************************/
typedef struct GrabClone {
@@ -5637,7 +776,7 @@ static int grab_clone_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int grab_clone_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int grab_clone_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
Brush *brush = image_paint_brush(C);
GrabClone *cmv;
@@ -5653,7 +792,7 @@ static int grab_clone_invoke(bContext *C, wmOperator *op, wmEvent *event)
return OPERATOR_RUNNING_MODAL;
}
-static int grab_clone_modal(bContext *C, wmOperator *op, wmEvent *event)
+static int grab_clone_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
Brush *brush = image_paint_brush(C);
ARegion *ar = CTX_wm_region(C);
@@ -5728,7 +867,7 @@ static int sample_color_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int sample_color_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int sample_color_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
RNA_int_set_array(op->ptr, "location", event->mval);
sample_color_exec(C, op);
@@ -5738,7 +877,7 @@ static int sample_color_invoke(bContext *C, wmOperator *op, wmEvent *event)
return OPERATOR_RUNNING_MODAL;
}
-static int sample_color_modal(bContext *C, wmOperator *op, wmEvent *event)
+static int sample_color_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
switch (event->type) {
case LEFTMOUSE:
@@ -5793,57 +932,6 @@ void PAINT_OT_sample_color(wmOperatorType *ot)
RNA_def_int_vector(ot->srna, "location", 2, NULL, 0, INT_MAX, "Location", "Cursor location in region coordinates", 0, 16384);
}
-/******************** set clone cursor operator ********************/
-
-static int set_clone_cursor_exec(bContext *C, wmOperator *op)
-{
- Scene *scene = CTX_data_scene(C);
- View3D *v3d = CTX_wm_view3d(C);
- float *cursor = give_cursor(scene, v3d);
-
- RNA_float_get_array(op->ptr, "location", cursor);
-
- ED_area_tag_redraw(CTX_wm_area(C));
-
- return OPERATOR_FINISHED;
-}
-
-static int set_clone_cursor_invoke(bContext *C, wmOperator *op, wmEvent *event)
-{
- Scene *scene = CTX_data_scene(C);
- View3D *v3d = CTX_wm_view3d(C);
- ARegion *ar = CTX_wm_region(C);
- float location[3];
-
- view3d_operator_needs_opengl(C);
-
- if (!ED_view3d_autodist(scene, ar, v3d, event->mval, location))
- return OPERATOR_CANCELLED;
-
- RNA_float_set_array(op->ptr, "location", location);
-
- return set_clone_cursor_exec(C, op);
-}
-
-void PAINT_OT_clone_cursor_set(wmOperatorType *ot)
-{
- /* identifiers */
- ot->name = "Set Clone Cursor";
- ot->idname = "PAINT_OT_clone_cursor_set";
- ot->description = "Set the location of the clone cursor";
-
- /* api callbacks */
- ot->exec = set_clone_cursor_exec;
- ot->invoke = set_clone_cursor_invoke;
- ot->poll = image_paint_3d_poll;
-
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
- /* properties */
- RNA_def_float_vector(ot->srna, "location", 3, NULL, -FLT_MAX, FLT_MAX, "Location", "Cursor location in world space coordinates", -10000.0f, 10000.0f);
-}
-
/******************** texture paint toggle operator ********************/
static int texture_paint_toggle_poll(bContext *C)
@@ -5937,11 +1025,6 @@ int image_texture_paint_poll(bContext *C)
return (texture_paint_poll(C) || image_paint_poll(C));
}
-int uv_sculpt_poll(bContext *C)
-{
- return uv_sculpt_brush_poll(C);
-}
-
int facemask_paint_poll(bContext *C)
{
return paint_facesel_test(CTX_data_active_object(C));
@@ -5956,201 +1039,4 @@ int mask_paint_poll(bContext *C)
{
return paint_facesel_test(CTX_data_active_object(C)) || paint_vertsel_test(CTX_data_active_object(C));
}
-/* use project paint to re-apply an image */
-static int texture_paint_camera_project_exec(bContext *C, wmOperator *op)
-{
- Image *image = BLI_findlink(&CTX_data_main(C)->image, RNA_enum_get(op->ptr, "image"));
- Scene *scene = CTX_data_scene(C);
- ProjPaintState ps = {NULL};
- int orig_brush_size;
- IDProperty *idgroup;
- IDProperty *view_data = NULL;
-
- project_state_init(C, OBACT, &ps);
-
- if (ps.ob == NULL || ps.ob->type != OB_MESH) {
- BKE_report(op->reports, RPT_ERROR, "No active mesh object");
- return OPERATOR_CANCELLED;
- }
-
- if (image == NULL) {
- BKE_report(op->reports, RPT_ERROR, "Image could not be found");
- return OPERATOR_CANCELLED;
- }
-
- ps.reproject_image = image;
- ps.reproject_ibuf = BKE_image_acquire_ibuf(image, NULL, NULL);
-
- if (ps.reproject_ibuf == NULL || ps.reproject_ibuf->rect == NULL) {
- BKE_report(op->reports, RPT_ERROR, "Image data could not be found");
- return OPERATOR_CANCELLED;
- }
-
- idgroup = IDP_GetProperties(&image->id, 0);
-
- if (idgroup) {
- view_data = IDP_GetPropertyTypeFromGroup(idgroup, PROJ_VIEW_DATA_ID, IDP_ARRAY);
-
- /* type check to make sure its ok */
- if (view_data->len != PROJ_VIEW_DATA_SIZE || view_data->subtype != IDP_FLOAT) {
- BKE_report(op->reports, RPT_ERROR, "Image project data invalid");
- return OPERATOR_CANCELLED;
- }
- }
-
- if (view_data) {
- /* image has stored view projection info */
- ps.source = PROJ_SRC_IMAGE_VIEW;
- }
- else {
- ps.source = PROJ_SRC_IMAGE_CAM;
-
- if (scene->camera == NULL) {
- BKE_report(op->reports, RPT_ERROR, "No active camera set");
- return OPERATOR_CANCELLED;
- }
- }
-
- /* override */
- ps.is_texbrush = 0;
- ps.do_masking = false;
- orig_brush_size = BKE_brush_size_get(scene, ps.brush);
- BKE_brush_size_set(scene, ps.brush, 32); /* cover the whole image */
-
- ps.tool = PAINT_TOOL_DRAW; /* so pixels are initialized with minimal info */
-
- scene->toolsettings->imapaint.flag |= IMAGEPAINT_DRAWING;
-
- undo_paint_push_begin(UNDO_PAINT_IMAGE, op->type->name,
- image_undo_restore, image_undo_free);
-
- /* allocate and initialize spatial data structures */
- project_paint_begin(&ps);
-
- if (ps.dm == NULL) {
- BKE_brush_size_set(scene, ps.brush, orig_brush_size);
- return OPERATOR_CANCELLED;
- }
- else {
- float pos[2] = {0.0, 0.0};
- float lastpos[2] = {0.0, 0.0};
- int a;
-
- for (a = 0; a < ps.image_tot; a++)
- partial_redraw_array_init(ps.projImages[a].partRedrawRect);
-
- project_paint_op(&ps, NULL, lastpos, pos);
-
- project_image_refresh_tagged(&ps);
-
- for (a = 0; a < ps.image_tot; a++) {
- GPU_free_image(ps.projImages[a].ima);
- WM_event_add_notifier(C, NC_IMAGE | NA_EDITED, ps.projImages[a].ima);
- }
- }
-
- project_paint_end(&ps);
-
- scene->toolsettings->imapaint.flag &= ~IMAGEPAINT_DRAWING;
- BKE_brush_size_set(scene, ps.brush, orig_brush_size);
-
- return OPERATOR_FINISHED;
-}
-
-void PAINT_OT_project_image(wmOperatorType *ot)
-{
- PropertyRNA *prop;
-
- /* identifiers */
- ot->name = "Project Image";
- ot->idname = "PAINT_OT_project_image";
- ot->description = "Project an edited render from the active camera back onto the object";
-
- /* api callbacks */
- ot->invoke = WM_enum_search_invoke;
- ot->exec = texture_paint_camera_project_exec;
-
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
- prop = RNA_def_enum(ot->srna, "image", DummyRNA_NULL_items, 0, "Image", "");
- RNA_def_enum_funcs(prop, RNA_image_itemf);
- ot->prop = prop;
-}
-
-static int texture_paint_image_from_view_exec(bContext *C, wmOperator *op)
-{
- Image *image;
- ImBuf *ibuf;
- char filename[FILE_MAX];
-
- Scene *scene = CTX_data_scene(C);
- ToolSettings *settings = scene->toolsettings;
- int w = settings->imapaint.screen_grab_size[0];
- int h = settings->imapaint.screen_grab_size[1];
- int maxsize;
- char err_out[256] = "unknown";
-
- RNA_string_get(op->ptr, "filepath", filename);
-
- glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxsize);
- if (w > maxsize) w = maxsize;
- if (h > maxsize) h = maxsize;
-
- ibuf = ED_view3d_draw_offscreen_imbuf(CTX_data_scene(C), CTX_wm_view3d(C), CTX_wm_region(C), w, h, IB_rect, FALSE, R_ALPHAPREMUL, err_out);
- if (!ibuf) {
- /* Mostly happens when OpenGL offscreen buffer was failed to create, */
- /* but could be other reasons. Should be handled in the future. nazgul */
- BKE_reportf(op->reports, RPT_ERROR, "Failed to create OpenGL off-screen buffer: %s", err_out);
- return OPERATOR_CANCELLED;
- }
-
- image = BKE_image_add_from_imbuf(ibuf);
-
- if (image) {
- /* now for the trickyness. store the view projection here!
- * re-projection will reuse this */
- View3D *v3d = CTX_wm_view3d(C);
- RegionView3D *rv3d = CTX_wm_region_view3d(C);
-
- IDPropertyTemplate val;
- IDProperty *idgroup = IDP_GetProperties(&image->id, 1);
- IDProperty *view_data;
- int orth;
- float *array;
-
- val.array.len = PROJ_VIEW_DATA_SIZE;
- val.array.type = IDP_FLOAT;
- view_data = IDP_New(IDP_ARRAY, &val, PROJ_VIEW_DATA_ID);
-
- array = (float *)IDP_Array(view_data);
- memcpy(array, rv3d->winmat, sizeof(rv3d->winmat)); array += sizeof(rv3d->winmat) / sizeof(float);
- memcpy(array, rv3d->viewmat, sizeof(rv3d->viewmat)); array += sizeof(rv3d->viewmat) / sizeof(float);
- orth = project_paint_view_clip(v3d, rv3d, &array[0], &array[1]);
- array[2] = orth ? 1.0f : 0.0f; /* using float for a bool is dodgy but since its an extra member in the array... easier then adding a single bool prop */
-
- IDP_AddToGroup(idgroup, view_data);
-
- rename_id(&image->id, "image_view");
- }
-
- return OPERATOR_FINISHED;
-}
-
-void PAINT_OT_image_from_view(wmOperatorType *ot)
-{
- /* identifiers */
- ot->name = "Image from View";
- ot->idname = "PAINT_OT_image_from_view";
- ot->description = "Make an image from the current 3D view for re-projection";
-
- /* api callbacks */
- ot->exec = texture_paint_image_from_view_exec;
- ot->poll = ED_operator_region_view3d_active;
-
- /* flags */
- ot->flag = OPTYPE_REGISTER;
-
- RNA_def_string_file_name(ot->srna, "filepath", "", FILE_MAX, "File Path", "Name of the file");
-}
diff --git a/source/blender/editors/sculpt_paint/paint_image_2d.c b/source/blender/editors/sculpt_paint/paint_image_2d.c
index 84250853f38..ed1b25d1b4e 100644
--- a/source/blender/editors/sculpt_paint/paint_image_2d.c
+++ b/source/blender/editors/sculpt_paint/paint_image_2d.c
@@ -35,17 +35,56 @@
#include "DNA_brush_types.h"
#include "DNA_scene_types.h"
+#include "DNA_space_types.h"
+#include "DNA_object_types.h"
+#include "BLI_math.h"
+
+#include "BKE_context.h"
#include "BKE_brush.h"
+#include "BKE_main.h"
+#include "BKE_image.h"
+#include "BKE_paint.h"
+#include "BKE_report.h"
-#include "BLI_math.h"
+#include "ED_screen.h"
#include "IMB_imbuf.h"
#include "IMB_imbuf_types.h"
+#include "IMB_colormanagement.h"
+
+#include "WM_api.h"
+#include "WM_types.h"
+
+#include "UI_view2d.h"
#include "RE_shader_ext.h"
- /* Brush Painting for 2D image editor */
+#include "GPU_draw.h"
+
+#include "paint_intern.h"
+
+/* Brush Painting for 2D image editor */
+
+/* Defines and Structs */
+/* FTOCHAR as inline function */
+BLI_INLINE unsigned char f_to_char(const float val)
+{
+ return FTOCHAR(val);
+}
+#define IMAPAINT_FLOAT_RGB_TO_CHAR(c, f) { \
+ (c)[0] = f_to_char((f)[0]); \
+ (c)[1] = f_to_char((f)[1]); \
+ (c)[2] = f_to_char((f)[2]); \
+} (void)0
+
+#define IMAPAINT_CHAR_RGB_TO_FLOAT(f, c) { \
+ (f)[0] = IMAPAINT_CHAR_TO_FLOAT((c)[0]); \
+ (f)[1] = IMAPAINT_CHAR_TO_FLOAT((c)[1]); \
+ (f)[2] = IMAPAINT_CHAR_TO_FLOAT((c)[2]); \
+} (void)0
+
+#define IMAPAINT_FLOAT_RGB_COPY(a, b) copy_v3_v3(a, b)
typedef struct BrushPainterCache {
short enabled;
@@ -57,38 +96,55 @@ typedef struct BrushPainterCache {
int lastsize;
float lastalpha;
float lastjitter;
+ float last_rotation;
ImBuf *ibuf;
ImBuf *texibuf;
ImBuf *maskibuf;
} BrushPainterCache;
-struct BrushPainter {
+typedef struct BrushPainter {
Scene *scene;
Brush *brush;
- float lastmousepos[2]; /* mouse position of last paint call */
-
- float accumdistance; /* accumulated distance of brush since last paint op */
float lastpaintpos[2]; /* position of last paint op */
float startpaintpos[2]; /* position of first paint */
- double accumtime; /* accumulated time since last paint op (airbrush) */
- double lasttime; /* time of last update */
-
- float lastpressure;
-
short firsttouch; /* first paint op */
- float startsize;
- float startalpha;
- float startjitter;
- float startspacing;
-
BrushPainterCache cache;
-};
+} BrushPainter;
+
+typedef struct ImagePaintRegion {
+ int destx, desty;
+ int srcx, srcy;
+ int width, height;
+} ImagePaintRegion;
+
+typedef struct ImagePaintState {
+ BrushPainter *painter;
+ SpaceImage *sima;
+ View2D *v2d;
+ Scene *scene;
+ bScreen *screen;
-BrushPainter *BKE_brush_painter_new(Scene *scene, Brush *brush)
+ Brush *brush;
+ short tool, blend;
+ Image *image;
+ ImBuf *canvas;
+ ImBuf *clonecanvas;
+ char *warnpackedfile;
+ char *warnmultifile;
+
+ /* viewport texture paint only, but _not_ project paint */
+ Object *ob;
+ int faceindex;
+ float uv[2];
+ int do_facesel;
+} ImagePaintState;
+
+
+static BrushPainter *brush_painter_2d_new(Scene *scene, Brush *brush)
{
BrushPainter *painter = MEM_callocN(sizeof(BrushPainter), "BrushPainter");
@@ -97,29 +153,11 @@ BrushPainter *BKE_brush_painter_new(Scene *scene, Brush *brush)
painter->firsttouch = 1;
painter->cache.lastsize = -1; /* force ibuf create in refresh */
- painter->startsize = BKE_brush_size_get(scene, brush);
- painter->startalpha = BKE_brush_alpha_get(scene, brush);
- painter->startjitter = brush->jitter;
- painter->startspacing = brush->spacing;
-
return painter;
}
-static void brush_pressure_apply(BrushPainter *painter, Brush *brush, float pressure)
-{
- if (BKE_brush_use_alpha_pressure(painter->scene, brush))
- BKE_brush_alpha_set(painter->scene, brush, max_ff(0.0f, painter->startalpha * pressure));
- if (BKE_brush_use_size_pressure(painter->scene, brush))
- BKE_brush_size_set(painter->scene, brush, max_ff(1.0f, painter->startsize * pressure));
- if (brush->flag & BRUSH_JITTER_PRESSURE)
- brush->jitter = max_ff(0.0f, painter->startjitter * pressure);
- if (brush->flag & BRUSH_SPACING_PRESSURE)
- brush->spacing = max_ff(1.0f, painter->startspacing * (1.5f - pressure));
-}
-
-
-void BKE_brush_painter_require_imbuf(BrushPainter *painter, short flt, short texonly, int size)
+static void brush_painter_2d_require_imbuf(BrushPainter *painter, short flt, short texonly, int size)
{
if ((painter->cache.flt != flt) || (painter->cache.size != size) ||
((painter->cache.texonly != texonly) && texonly))
@@ -142,22 +180,15 @@ void BKE_brush_painter_require_imbuf(BrushPainter *painter, short flt, short tex
painter->cache.enabled = 1;
}
-void BKE_brush_painter_free(BrushPainter *painter)
+static void brush_painter_2d_free(BrushPainter *painter)
{
- Brush *brush = painter->brush;
-
- BKE_brush_size_set(painter->scene, brush, painter->startsize);
- BKE_brush_alpha_set(painter->scene, brush, painter->startalpha);
- brush->jitter = painter->startjitter;
- brush->spacing = painter->startspacing;
-
if (painter->cache.ibuf) IMB_freeImBuf(painter->cache.ibuf);
if (painter->cache.texibuf) IMB_freeImBuf(painter->cache.texibuf);
if (painter->cache.maskibuf) IMB_freeImBuf(painter->cache.maskibuf);
MEM_freeN(painter);
}
-static void brush_painter_do_partial(BrushPainter *painter, ImBuf *oldtexibuf,
+static void brush_painter_2d_do_partial(BrushPainter *painter, ImBuf *oldtexibuf,
int x, int y, int w, int h, int xt, int yt,
const float pos[2])
{
@@ -204,7 +235,7 @@ static void brush_painter_do_partial(BrushPainter *painter, ImBuf *oldtexibuf,
xy[0] = x + xoff;
xy[1] = y + yoff;
- BKE_brush_sample_tex_2D(scene, brush, xy, tf, 0);
+ BKE_brush_sample_tex_2D(scene, brush, xy, tf, NULL);
}
bf[0] = tf[0] * mf[0];
@@ -235,7 +266,7 @@ static void brush_painter_do_partial(BrushPainter *painter, ImBuf *oldtexibuf,
xy[0] = x + xoff;
xy[1] = y + yoff;
- BKE_brush_sample_tex_2D(scene, brush, xy, rgba, 0);
+ BKE_brush_sample_tex_2D(scene, brush, xy, rgba, NULL);
rgba_float_to_uchar(t, rgba);
}
@@ -248,7 +279,7 @@ static void brush_painter_do_partial(BrushPainter *painter, ImBuf *oldtexibuf,
}
}
-static void brush_painter_tiled_tex_partial_update(BrushPainter *painter, const float pos[2])
+static void brush_painter_2d_tiled_tex_partial_update(BrushPainter *painter, const float pos[2])
{
const Scene *scene = painter->scene;
Brush *brush = painter->brush;
@@ -286,25 +317,26 @@ static void brush_painter_tiled_tex_partial_update(BrushPainter *painter, const
/* blend existing texture in new position */
if ((x1 < x2) && (y1 < y2))
- brush_painter_do_partial(painter, oldtexibuf, x1, y1, x2, y2, srcx, srcy, pos);
+ brush_painter_2d_do_partial(painter, oldtexibuf, x1, y1, x2, y2, srcx, srcy, pos);
if (oldtexibuf)
IMB_freeImBuf(oldtexibuf);
/* sample texture in new areas */
if ((0 < x1) && (0 < ibuf->y))
- brush_painter_do_partial(painter, NULL, 0, 0, x1, ibuf->y, 0, 0, pos);
+ brush_painter_2d_do_partial(painter, NULL, 0, 0, x1, ibuf->y, 0, 0, pos);
if ((x2 < ibuf->x) && (0 < ibuf->y))
- brush_painter_do_partial(painter, NULL, x2, 0, ibuf->x, ibuf->y, 0, 0, pos);
+ brush_painter_2d_do_partial(painter, NULL, x2, 0, ibuf->x, ibuf->y, 0, 0, pos);
if ((x1 < x2) && (0 < y1))
- brush_painter_do_partial(painter, NULL, x1, 0, x2, y1, 0, 0, pos);
+ brush_painter_2d_do_partial(painter, NULL, x1, 0, x2, y1, 0, 0, pos);
if ((x1 < x2) && (y2 < ibuf->y))
- brush_painter_do_partial(painter, NULL, x1, y2, x2, ibuf->y, 0, 0, pos);
+ brush_painter_2d_do_partial(painter, NULL, x1, y2, x2, ibuf->y, 0, 0, pos);
}
-static void brush_painter_refresh_cache(BrushPainter *painter, const float pos[2], int use_color_correction)
+static void brush_painter_2d_refresh_cache(BrushPainter *painter, const float pos[2], int use_color_correction)
{
const Scene *scene = painter->scene;
+ UnifiedPaintSettings *ups = &scene->toolsettings->unified_paint_settings;
Brush *brush = painter->brush;
BrushPainterCache *cache = &painter->cache;
MTex *mtex = &brush->mtex;
@@ -313,10 +345,16 @@ static void brush_painter_refresh_cache(BrushPainter *painter, const float pos[2
const int diameter = 2 * BKE_brush_size_get(scene, brush);
const float alpha = BKE_brush_alpha_get(scene, brush);
const bool do_tiled = ELEM(brush->mtex.brush_map_mode, MTEX_MAP_MODE_TILED, MTEX_MAP_MODE_3D);
+ float rotation = -mtex->rot;
+
+ if (mtex->brush_map_mode == MTEX_MAP_MODE_VIEW) {
+ rotation += ups->brush_rotation;
+ }
if (diameter != cache->lastsize ||
alpha != cache->lastalpha ||
- brush->jitter != cache->lastjitter)
+ brush->jitter != cache->lastjitter ||
+ rotation != cache->last_rotation)
{
if (cache->ibuf) {
IMB_freeImBuf(cache->ibuf);
@@ -332,7 +370,7 @@ static void brush_painter_refresh_cache(BrushPainter *painter, const float pos[2
if (do_tiled) {
BKE_brush_imbuf_new(scene, brush, flt, 3, size, &cache->maskibuf, use_color_correction);
- brush_painter_tiled_tex_partial_update(painter, pos);
+ brush_painter_2d_tiled_tex_partial_update(painter, pos);
}
else
BKE_brush_imbuf_new(scene, brush, flt, 2, size, &cache->ibuf, use_color_correction);
@@ -340,221 +378,447 @@ static void brush_painter_refresh_cache(BrushPainter *painter, const float pos[2
cache->lastsize = diameter;
cache->lastalpha = alpha;
cache->lastjitter = brush->jitter;
+ cache->last_rotation = rotation;
}
else if (do_tiled && mtex && mtex->tex) {
int dx = (int)painter->lastpaintpos[0] - (int)pos[0];
int dy = (int)painter->lastpaintpos[1] - (int)pos[1];
if ((dx != 0) || (dy != 0))
- brush_painter_tiled_tex_partial_update(painter, pos);
+ brush_painter_2d_tiled_tex_partial_update(painter, pos);
}
}
-void BKE_brush_painter_break_stroke(BrushPainter *painter)
+/* keep these functions in sync */
+static void paint_2d_ibuf_rgb_get(ImBuf *ibuf, int x, int y, const short is_torus, float r_rgb[3])
{
- painter->firsttouch = 1;
+ if (is_torus) {
+ x %= ibuf->x;
+ if (x < 0) x += ibuf->x;
+ y %= ibuf->y;
+ if (y < 0) y += ibuf->y;
+ }
+
+ if (ibuf->rect_float) {
+ float *rrgbf = ibuf->rect_float + (ibuf->x * y + x) * 4;
+ IMAPAINT_FLOAT_RGB_COPY(r_rgb, rrgbf);
+ }
+ else {
+ char *rrgb = (char *)ibuf->rect + (ibuf->x * y + x) * 4;
+ IMAPAINT_CHAR_RGB_TO_FLOAT(r_rgb, rrgb);
+ }
}
+static void paint_2d_ibuf_rgb_set(ImBuf *ibuf, int x, int y, const short is_torus, const float rgb[3])
+{
+ if (is_torus) {
+ x %= ibuf->x;
+ if (x < 0) x += ibuf->x;
+ y %= ibuf->y;
+ if (y < 0) y += ibuf->y;
+ }
+ if (ibuf->rect_float) {
+ float *rrgbf = ibuf->rect_float + (ibuf->x * y + x) * 4;
+ IMAPAINT_FLOAT_RGB_COPY(rrgbf, rgb);
+ }
+ else {
+ char *rrgb = (char *)ibuf->rect + (ibuf->x * y + x) * 4;
+ IMAPAINT_FLOAT_RGB_TO_CHAR(rrgb, rgb);
+ }
+}
-int BKE_brush_painter_paint(BrushPainter *painter, BrushFunc func, const float pos[2], double time, float pressure,
- void *user, int use_color_correction)
+static int paint_2d_ibuf_add_if(ImBuf *ibuf, unsigned int x, unsigned int y, float *outrgb, short torus)
{
- Scene *scene = painter->scene;
- Brush *brush = painter->brush;
- int totpaintops = 0;
+ float inrgb[3];
- if (pressure == 0.0f) {
- if (painter->lastpressure) // XXX - hack, operator misses
- pressure = painter->lastpressure;
- else
- pressure = 1.0f; /* zero pressure == not using tablet */
- }
- if (painter->firsttouch) {
- /* paint exactly once on first touch */
- painter->startpaintpos[0] = pos[0];
- painter->startpaintpos[1] = pos[1];
-
- brush_pressure_apply(painter, brush, pressure);
- if (painter->cache.enabled)
- brush_painter_refresh_cache(painter, pos, use_color_correction);
- totpaintops += func(user, painter->cache.ibuf, pos, pos);
-
- painter->lasttime = time;
- painter->firsttouch = 0;
- painter->lastpaintpos[0] = pos[0];
- painter->lastpaintpos[1] = pos[1];
- }
-#if 0
- else if (painter->brush->flag & BRUSH_AIRBRUSH) {
- float spacing, step, paintpos[2], dmousepos[2], len;
- double starttime, curtime = time;
-
- /* compute brush spacing adapted to brush size */
- spacing = brush->rate; //radius*brush->spacing * 0.01f;
-
- /* setup starting time, direction vector and accumulated time */
- starttime = painter->accumtime;
- sub_v2_v2v2(dmousepos, pos, painter->lastmousepos);
- len = normalize_v2(dmousepos);
- painter->accumtime += curtime - painter->lasttime;
-
- /* do paint op over unpainted time distance */
- while (painter->accumtime >= spacing) {
- step = (spacing - starttime) * len;
- paintpos[0] = painter->lastmousepos[0] + dmousepos[0] * step;
- paintpos[1] = painter->lastmousepos[1] + dmousepos[1] * step;
-
- if (painter->cache.enabled)
- brush_painter_refresh_cache(painter);
- totpaintops += func(user, painter->cache.ibuf,
- painter->lastpaintpos, paintpos);
-
- painter->lastpaintpos[0] = paintpos[0];
- painter->lastpaintpos[1] = paintpos[1];
- painter->accumtime -= spacing;
- starttime -= spacing;
- }
-
- painter->lasttime = curtime;
+ // XXX: signed unsigned mismatch
+ if ((x >= (unsigned int)(ibuf->x)) || (y >= (unsigned int)(ibuf->y))) {
+ if (torus) paint_2d_ibuf_rgb_get(ibuf, x, y, 1, inrgb);
+ else return 0;
}
-#endif
else {
- float startdistance, spacing, step, paintpos[2], dmousepos[2], finalpos[2];
- float t, len, press;
- const int radius = BKE_brush_size_get(scene, brush);
-
- /* compute brush spacing adapted to brush radius, spacing may depend
- * on pressure, so update it */
- brush_pressure_apply(painter, brush, painter->lastpressure);
- spacing = max_ff(1.0f, radius) * brush->spacing * 0.01f;
-
- /* setup starting distance, direction vector and accumulated distance */
- startdistance = painter->accumdistance;
- sub_v2_v2v2(dmousepos, pos, painter->lastmousepos);
- len = normalize_v2(dmousepos);
- painter->accumdistance += len;
-
- if (brush->flag & BRUSH_SPACE) {
- /* do paint op over unpainted distance */
- while ((len > 0.0f) && (painter->accumdistance >= spacing)) {
- step = spacing - startdistance;
- paintpos[0] = painter->lastmousepos[0] + dmousepos[0] * step;
- paintpos[1] = painter->lastmousepos[1] + dmousepos[1] * step;
-
- t = step / len;
- press = (1.0f - t) * painter->lastpressure + t * pressure;
- brush_pressure_apply(painter, brush, press);
- spacing = max_ff(1.0f, radius) * brush->spacing * 0.01f;
-
- BKE_brush_jitter_pos(scene, brush, paintpos, finalpos);
-
- if (painter->cache.enabled)
- brush_painter_refresh_cache(painter, finalpos, use_color_correction);
-
- totpaintops +=
- func(user, painter->cache.ibuf, painter->lastpaintpos, finalpos);
-
- painter->lastpaintpos[0] = paintpos[0];
- painter->lastpaintpos[1] = paintpos[1];
- painter->accumdistance -= spacing;
- startdistance -= spacing;
- }
- }
- else {
- BKE_brush_jitter_pos(scene, brush, pos, finalpos);
+ paint_2d_ibuf_rgb_get(ibuf, x, y, 0, inrgb);
+ }
- if (painter->cache.enabled)
- brush_painter_refresh_cache(painter, finalpos, use_color_correction);
+ outrgb[0] += inrgb[0];
+ outrgb[1] += inrgb[1];
+ outrgb[2] += inrgb[2];
- totpaintops += func(user, painter->cache.ibuf, pos, finalpos);
+ return 1;
+}
- painter->lastpaintpos[0] = pos[0];
- painter->lastpaintpos[1] = pos[1];
- painter->accumdistance = 0;
- }
+static void paint_2d_lift_soften(ImBuf *ibuf, ImBuf *ibufb, int *pos, const short is_torus)
+{
+ int x, y, count, xi, yi, xo, yo;
+ int out_off[2], in_off[2], dim[2];
+ float outrgb[3];
+
+ dim[0] = ibufb->x;
+ dim[1] = ibufb->y;
+ in_off[0] = pos[0];
+ in_off[1] = pos[1];
+ out_off[0] = out_off[1] = 0;
+
+ if (!is_torus) {
+ IMB_rectclip(ibuf, ibufb, &in_off[0], &in_off[1], &out_off[0],
+ &out_off[1], &dim[0], &dim[1]);
+
+ if ((dim[0] == 0) || (dim[1] == 0))
+ return;
+ }
- /* do airbrush paint ops, based on the number of paint ops left over
- * from regular painting. this is a temporary solution until we have
- * accurate time stamps for mouse move events */
- if (brush->flag & BRUSH_AIRBRUSH) {
- double curtime = time;
- double painttime = brush->rate * totpaintops;
+ for (y = 0; y < dim[1]; y++) {
+ for (x = 0; x < dim[0]; x++) {
+ /* get input pixel */
+ xi = in_off[0] + x;
+ yi = in_off[1] + y;
- painter->accumtime += curtime - painter->lasttime;
- if (painter->accumtime <= painttime)
- painter->accumtime = 0.0;
- else
- painter->accumtime -= painttime;
+ count = 1;
+ paint_2d_ibuf_rgb_get(ibuf, xi, yi, is_torus, outrgb);
- while (painter->accumtime >= (double)brush->rate) {
- brush_pressure_apply(painter, brush, pressure);
+ count += paint_2d_ibuf_add_if(ibuf, xi - 1, yi - 1, outrgb, is_torus);
+ count += paint_2d_ibuf_add_if(ibuf, xi - 1, yi, outrgb, is_torus);
+ count += paint_2d_ibuf_add_if(ibuf, xi - 1, yi + 1, outrgb, is_torus);
- BKE_brush_jitter_pos(scene, brush, pos, finalpos);
+ count += paint_2d_ibuf_add_if(ibuf, xi, yi - 1, outrgb, is_torus);
+ count += paint_2d_ibuf_add_if(ibuf, xi, yi + 1, outrgb, is_torus);
- if (painter->cache.enabled)
- brush_painter_refresh_cache(painter, finalpos, use_color_correction);
+ count += paint_2d_ibuf_add_if(ibuf, xi + 1, yi - 1, outrgb, is_torus);
+ count += paint_2d_ibuf_add_if(ibuf, xi + 1, yi, outrgb, is_torus);
+ count += paint_2d_ibuf_add_if(ibuf, xi + 1, yi + 1, outrgb, is_torus);
- totpaintops +=
- func(user, painter->cache.ibuf, painter->lastmousepos, finalpos);
- painter->accumtime -= (double)brush->rate;
- }
+ mul_v3_fl(outrgb, 1.0f / (float)count);
- painter->lasttime = curtime;
+ /* write into brush buffer */
+ xo = out_off[0] + x;
+ yo = out_off[1] + y;
+ paint_2d_ibuf_rgb_set(ibufb, xo, yo, 0, outrgb);
}
}
+}
- painter->lastmousepos[0] = pos[0];
- painter->lastmousepos[1] = pos[1];
- painter->lastpressure = pressure;
+static void paint_2d_set_region(ImagePaintRegion *region, int destx, int desty, int srcx, int srcy, int width, int height)
+{
+ region->destx = destx;
+ region->desty = desty;
+ region->srcx = srcx;
+ region->srcy = srcy;
+ region->width = width;
+ region->height = height;
+}
+
+static int paint_2d_torus_split_region(ImagePaintRegion region[4], ImBuf *dbuf, ImBuf *sbuf)
+{
+ int destx = region->destx;
+ int desty = region->desty;
+ int srcx = region->srcx;
+ int srcy = region->srcy;
+ int width = region->width;
+ int height = region->height;
+ int origw, origh, w, h, tot = 0;
+
+ /* convert destination and source coordinates to be within image */
+ destx = destx % dbuf->x;
+ if (destx < 0) destx += dbuf->x;
+ desty = desty % dbuf->y;
+ if (desty < 0) desty += dbuf->y;
+ srcx = srcx % sbuf->x;
+ if (srcx < 0) srcx += sbuf->x;
+ srcy = srcy % sbuf->y;
+ if (srcy < 0) srcy += sbuf->y;
+
+ /* clip width of blending area to destination imbuf, to avoid writing the
+ * same pixel twice */
+ origw = w = (width > dbuf->x) ? dbuf->x : width;
+ origh = h = (height > dbuf->y) ? dbuf->y : height;
+
+ /* clip within image */
+ IMB_rectclip(dbuf, sbuf, &destx, &desty, &srcx, &srcy, &w, &h);
+ paint_2d_set_region(&region[tot++], destx, desty, srcx, srcy, w, h);
+
+ /* do 3 other rects if needed */
+ if (w < origw)
+ paint_2d_set_region(&region[tot++], (destx + w) % dbuf->x, desty, (srcx + w) % sbuf->x, srcy, origw - w, h);
+ if (h < origh)
+ paint_2d_set_region(&region[tot++], destx, (desty + h) % dbuf->y, srcx, (srcy + h) % sbuf->y, w, origh - h);
+ if ((w < origw) && (h < origh))
+ paint_2d_set_region(&region[tot++], (destx + w) % dbuf->x, (desty + h) % dbuf->y, (srcx + w) % sbuf->x, (srcy + h) % sbuf->y, origw - w, origh - h);
+
+ return tot;
+}
- BKE_brush_alpha_set(scene, brush, painter->startalpha);
- BKE_brush_size_set(scene, brush, painter->startsize);
- brush->jitter = painter->startjitter;
- brush->spacing = painter->startspacing;
+static void paint_2d_lift_smear(ImBuf *ibuf, ImBuf *ibufb, int *pos)
+{
+ ImagePaintRegion region[4];
+ int a, tot;
+
+ paint_2d_set_region(region, 0, 0, pos[0], pos[1], ibufb->x, ibufb->y);
+ tot = paint_2d_torus_split_region(region, ibufb, ibuf);
+
+ for (a = 0; a < tot; a++)
+ IMB_rectblend(ibufb, ibuf, region[a].destx, region[a].desty,
+ region[a].srcx, region[a].srcy,
+ region[a].width, region[a].height, IMB_BLEND_COPY_RGB);
+}
- return totpaintops;
+static ImBuf *paint_2d_lift_clone(ImBuf *ibuf, ImBuf *ibufb, int *pos)
+{
+ /* note: allocImbuf returns zero'd memory, so regions outside image will
+ * have zero alpha, and hence not be blended onto the image */
+ int w = ibufb->x, h = ibufb->y, destx = 0, desty = 0, srcx = pos[0], srcy = pos[1];
+ ImBuf *clonebuf = IMB_allocImBuf(w, h, ibufb->planes, ibufb->flags);
+
+ IMB_rectclip(clonebuf, ibuf, &destx, &desty, &srcx, &srcy, &w, &h);
+ IMB_rectblend(clonebuf, ibuf, destx, desty, srcx, srcy, w, h,
+ IMB_BLEND_COPY_RGB);
+ IMB_rectblend(clonebuf, ibufb, destx, desty, destx, desty, w, h,
+ IMB_BLEND_COPY_ALPHA);
+
+ return clonebuf;
}
+static void paint_2d_convert_brushco(ImBuf *ibufb, const float pos[2], int ipos[2])
+{
+ ipos[0] = (int)floorf((pos[0] - ibufb->x / 2) + 1.0f);
+ ipos[1] = (int)floorf((pos[1] - ibufb->y / 2) + 1.0f);
+}
-/* TODO: should probably be unified with BrushPainter stuff? */
-unsigned int *BKE_brush_gen_texture_cache(Brush *br, int half_side)
+static int paint_2d_op(void *state, ImBuf *ibufb, const float lastpos[2], const float pos[2])
{
- unsigned int *texcache = NULL;
- MTex *mtex = &br->mtex;
- TexResult texres = {0};
- int hasrgb, ix, iy;
- int side = half_side * 2;
-
- if (mtex->tex) {
- float x, y, step = 2.0 / side, co[3];
-
- texcache = MEM_callocN(sizeof(int) * side * side, "Brush texture cache");
-
- /*do normalized cannonical view coords for texture*/
- for (y = -1.0, iy = 0; iy < side; iy++, y += step) {
- for (x = -1.0, ix = 0; ix < side; ix++, x += step) {
- co[0] = x;
- co[1] = y;
- co[2] = 0.0f;
-
- /* This is copied from displace modifier code */
- hasrgb = multitex_ext(mtex->tex, co, NULL, NULL, 0, &texres, NULL);
-
- /* if the texture gave an RGB value, we assume it didn't give a valid
- * intensity, so calculate one (formula from do_material_tex).
- * if the texture didn't give an RGB value, copy the intensity across
- */
- if (hasrgb & TEX_RGB)
- texres.tin = rgb_to_grayscale(&texres.tr);
-
- ((char *)texcache)[(iy * side + ix) * 4] =
- ((char *)texcache)[(iy * side + ix) * 4 + 1] =
- ((char *)texcache)[(iy * side + ix) * 4 + 2] =
- ((char *)texcache)[(iy * side + ix) * 4 + 3] = (char)(texres.tin * 255.0f);
- }
+ ImagePaintState *s = ((ImagePaintState *)state);
+ ImBuf *clonebuf = NULL, *frombuf;
+ ImagePaintRegion region[4];
+ short torus = s->brush->flag & BRUSH_TORUS;
+ short blend = s->blend;
+ float *offset = s->brush->clone.offset;
+ float liftpos[2];
+ int bpos[2], blastpos[2], bliftpos[2];
+ int a, tot;
+
+ paint_2d_convert_brushco(ibufb, pos, bpos);
+
+ /* lift from canvas */
+ if (s->tool == PAINT_TOOL_SOFTEN) {
+ paint_2d_lift_soften(s->canvas, ibufb, bpos, torus);
+ }
+ else if (s->tool == PAINT_TOOL_SMEAR) {
+ if (lastpos[0] == pos[0] && lastpos[1] == pos[1])
+ return 0;
+
+ paint_2d_convert_brushco(ibufb, lastpos, blastpos);
+ paint_2d_lift_smear(s->canvas, ibufb, blastpos);
+ }
+ else if (s->tool == PAINT_TOOL_CLONE && s->clonecanvas) {
+ liftpos[0] = pos[0] - offset[0] * s->canvas->x;
+ liftpos[1] = pos[1] - offset[1] * s->canvas->y;
+
+ paint_2d_convert_brushco(ibufb, liftpos, bliftpos);
+ clonebuf = paint_2d_lift_clone(s->clonecanvas, ibufb, bliftpos);
+ }
+
+ frombuf = (clonebuf) ? clonebuf : ibufb;
+
+ if (torus) {
+ paint_2d_set_region(region, bpos[0], bpos[1], 0, 0, frombuf->x, frombuf->y);
+ tot = paint_2d_torus_split_region(region, s->canvas, frombuf);
+ }
+ else {
+ paint_2d_set_region(region, bpos[0], bpos[1], 0, 0, frombuf->x, frombuf->y);
+ tot = 1;
+ }
+
+ /* blend into canvas */
+ for (a = 0; a < tot; a++) {
+ imapaint_dirty_region(s->image, s->canvas,
+ region[a].destx, region[a].desty,
+ region[a].width, region[a].height);
+
+ IMB_rectblend(s->canvas, frombuf,
+ region[a].destx, region[a].desty,
+ region[a].srcx, region[a].srcy,
+ region[a].width, region[a].height, blend);
+ }
+
+ if (clonebuf) IMB_freeImBuf(clonebuf);
+
+ return 1;
+}
+
+
+static int paint_2d_canvas_set(ImagePaintState *s, Image *ima)
+{
+ ImBuf *ibuf = BKE_image_acquire_ibuf(ima, s->sima ? &s->sima->iuser : NULL, NULL);
+
+ /* verify that we can paint and set canvas */
+ if (ima == NULL) {
+ return 0;
+ }
+ else if (ima->packedfile && ima->rr) {
+ s->warnpackedfile = ima->id.name + 2;
+ return 0;
+ }
+ else if (ibuf && ibuf->channels != 4) {
+ s->warnmultifile = ima->id.name + 2;
+ return 0;
+ }
+ else if (!ibuf || !(ibuf->rect || ibuf->rect_float))
+ return 0;
+
+ s->image = ima;
+ s->canvas = ibuf;
+
+ /* set clone canvas */
+ if (s->tool == PAINT_TOOL_CLONE) {
+ ima = s->brush->clone.image;
+ ibuf = BKE_image_acquire_ibuf(ima, s->sima ? &s->sima->iuser : NULL, NULL);
+
+ if (!ima || !ibuf || !(ibuf->rect || ibuf->rect_float)) {
+ BKE_image_release_ibuf(ima, ibuf, NULL);
+ BKE_image_release_ibuf(s->image, s->canvas, NULL);
+ return 0;
+ }
+
+ s->clonecanvas = ibuf;
+
+ /* temporarily add float rect for cloning */
+ if (s->canvas->rect_float && !s->clonecanvas->rect_float) {
+ IMB_float_from_rect(s->clonecanvas);
}
+ else if (!s->canvas->rect_float && !s->clonecanvas->rect)
+ IMB_rect_from_float(s->clonecanvas);
}
- return texcache;
+ return 1;
}
+static void paint_2d_canvas_free(ImagePaintState *s)
+{
+ BKE_image_release_ibuf(s->image, s->canvas, NULL);
+ BKE_image_release_ibuf(s->brush->clone.image, s->clonecanvas, NULL);
+}
+
+int paint_2d_stroke(void *ps, const int prev_mval[2], const int mval[2], int eraser)
+{
+ float newuv[2], olduv[2];
+ int redraw = 0;
+ ImagePaintState *s = ps;
+ BrushPainter *painter = s->painter;
+ ImBuf *ibuf = BKE_image_acquire_ibuf(s->image, s->sima ? &s->sima->iuser : NULL, NULL);
+ const bool is_data = (ibuf && ibuf->colormanage_flag & IMB_COLORMANAGE_IS_DATA);
+
+ if (!ibuf)
+ return 0;
+
+ s->blend = s->brush->blend;
+ if (eraser)
+ s->blend = IMB_BLEND_ERASE_ALPHA;
+
+ UI_view2d_region_to_view(s->v2d, mval[0], mval[1], &newuv[0], &newuv[1]);
+ UI_view2d_region_to_view(s->v2d, prev_mval[0], prev_mval[1], &olduv[0], &olduv[1]);
+
+ newuv[0] *= ibuf->x;
+ newuv[1] *= ibuf->y;
+
+ olduv[0] *= ibuf->x;
+ olduv[1] *= ibuf->y;
+
+ if (painter->firsttouch) {
+ /* paint exactly once on first touch */
+ painter->startpaintpos[0] = newuv[0];
+ painter->startpaintpos[1] = newuv[1];
+
+ painter->firsttouch = 0;
+ copy_v2_v2(painter->lastpaintpos, newuv);
+ }
+ else {
+ copy_v2_v2(painter->lastpaintpos, olduv);
+ }
+ /* OCIO_TODO: float buffers are now always linear, so always use color correction
+ * this should probably be changed when texture painting color space is supported
+ */
+ brush_painter_2d_require_imbuf(painter, ((ibuf->rect_float) ? 1 : 0), 0, 0);
+
+ if (painter->cache.enabled)
+ brush_painter_2d_refresh_cache(painter, newuv, is_data == false);
+
+ if (paint_2d_op(s, painter->cache.ibuf, olduv, newuv)) {
+ imapaint_image_update(s->sima, s->image, ibuf, false);
+ BKE_image_release_ibuf(s->image, ibuf, NULL);
+ redraw |= 1;
+ }
+ else {
+ BKE_image_release_ibuf(s->image, ibuf, NULL);
+ }
+
+ if (redraw)
+ imapaint_clear_partial_redraw();
+
+ return redraw;
+}
+
+void *paint_2d_new_stroke(bContext *C, wmOperator *op)
+{
+ Scene *scene = CTX_data_scene(C);
+ ToolSettings *settings = scene->toolsettings;
+ Brush *brush = paint_brush(&settings->imapaint.paint);
+
+ ImagePaintState *s = MEM_callocN(sizeof(ImagePaintState), "ImagePaintState");
+
+ s->sima = CTX_wm_space_image(C);
+ s->v2d = &CTX_wm_region(C)->v2d;
+ s->scene = scene;
+ s->screen = CTX_wm_screen(C);
+
+ s->brush = brush;
+ s->tool = brush->imagepaint_tool;
+ s->blend = brush->blend;
+
+ s->image = s->sima->image;
+
+ if (!paint_2d_canvas_set(s, s->image)) {
+ if (s->warnmultifile)
+ BKE_report(op->reports, RPT_WARNING, "Image requires 4 color channels to paint");
+ if (s->warnpackedfile)
+ BKE_report(op->reports, RPT_WARNING, "Packed MultiLayer files cannot be painted");
+
+ MEM_freeN(s);
+ return NULL;
+ }
+
+ paint_brush_init_tex(s->brush);
+
+ /* create painter */
+ s->painter = brush_painter_2d_new(scene, s->brush);
+
+ return s;
+}
+
+void paint_2d_redraw (const bContext *C, void *ps, int final)
+{
+ ImagePaintState *s = ps;
+
+ if (final) {
+ if (s->image && !(s->sima && s->sima->lock))
+ GPU_free_image(s->image);
+
+ /* compositor listener deals with updating */
+ WM_event_add_notifier(C, NC_IMAGE | NA_EDITED, s->image);
+ }
+ else {
+ if (!s->sima || !s->sima->lock)
+ ED_region_tag_redraw(CTX_wm_region(C));
+ else
+ WM_event_add_notifier(C, NC_IMAGE | NA_EDITED, s->image);
+ }
+}
+
+void paint_2d_stroke_done(void *ps)
+{
+ ImagePaintState *s = ps;
+
+ paint_2d_canvas_free(s);
+ brush_painter_2d_free(s->painter);
+ paint_brush_exit_tex(s->brush);
+
+ MEM_freeN(s);
+}
diff --git a/source/blender/editors/sculpt_paint/paint_image_proj.c b/source/blender/editors/sculpt_paint/paint_image_proj.c
new file mode 100644
index 00000000000..96916236279
--- /dev/null
+++ b/source/blender/editors/sculpt_paint/paint_image_proj.c
@@ -0,0 +1,4465 @@
+/*
+ * ***** 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.
+ *
+ * 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) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: some of this file.
+ *
+ * Contributor(s): Jens Ole Wund (bjornmose), Campbell Barton (ideasman42)
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/editors/sculpt_paint/paint_image_proj.c
+ * \ingroup edsculpt
+ * \brief Functions to paint images in 2D and 3D.
+ */
+
+#include <float.h>
+#include <string.h>
+#include <stdio.h>
+#include <math.h>
+
+#include "MEM_guardedalloc.h"
+
+#ifdef WIN32
+# include "BLI_winstuff.h"
+#endif
+
+#include "BLI_math.h"
+#include "BLI_blenlib.h"
+#include "BLI_linklist.h"
+#include "BLI_memarena.h"
+#include "BLI_threads.h"
+#include "BLI_utildefines.h"
+
+#include "PIL_time.h"
+
+#include "IMB_imbuf.h"
+#include "IMB_imbuf_types.h"
+
+#include "DNA_brush_types.h"
+#include "DNA_mesh_types.h"
+#include "DNA_node_types.h"
+#include "DNA_object_types.h"
+
+#include "BKE_camera.h"
+#include "BKE_context.h"
+#include "BKE_depsgraph.h"
+#include "BKE_DerivedMesh.h"
+#include "BKE_idprop.h"
+#include "BKE_brush.h"
+#include "BKE_image.h"
+#include "BKE_library.h"
+#include "BKE_main.h"
+#include "BKE_mesh.h"
+#include "BKE_node.h"
+#include "BKE_object.h"
+#include "BKE_paint.h"
+#include "BKE_report.h"
+#include "BKE_scene.h"
+#include "BKE_colortools.h"
+
+#include "BKE_tessmesh.h"
+
+#include "BIF_gl.h"
+#include "BIF_glutil.h"
+
+#include "UI_view2d.h"
+
+#include "ED_image.h"
+#include "ED_screen.h"
+#include "ED_sculpt.h"
+#include "ED_uvedit.h"
+#include "ED_view3d.h"
+#include "ED_mesh.h"
+
+#include "WM_api.h"
+#include "WM_types.h"
+
+#include "RNA_access.h"
+#include "RNA_define.h"
+#include "RNA_enum_types.h"
+
+#include "GPU_draw.h"
+
+#include "IMB_colormanagement.h"
+
+#include "paint_intern.h"
+
+/* Defines and Structs */
+/* FTOCHAR as inline function */
+BLI_INLINE unsigned char f_to_char(const float val)
+{
+ return FTOCHAR(val);
+}
+
+#define IMAPAINT_FLOAT_RGBA_TO_CHAR(c, f) { \
+ (c)[0] = f_to_char((f)[0]); \
+ (c)[1] = f_to_char((f)[1]); \
+ (c)[2] = f_to_char((f)[2]); \
+ (c)[3] = f_to_char((f)[3]); \
+} (void)0
+
+#define IMAPAINT_CHAR_RGBA_TO_FLOAT(f, c) { \
+ (f)[0] = IMAPAINT_CHAR_TO_FLOAT((c)[0]); \
+ (f)[1] = IMAPAINT_CHAR_TO_FLOAT((c)[1]); \
+ (f)[2] = IMAPAINT_CHAR_TO_FLOAT((c)[2]); \
+ (f)[3] = IMAPAINT_CHAR_TO_FLOAT((c)[3]); \
+} (void)0
+
+#define IMAPAINT_FLOAT_RGB_TO_CHAR(c, f) { \
+ (c)[0] = f_to_char((f)[0]); \
+ (c)[1] = f_to_char((f)[1]); \
+ (c)[2] = f_to_char((f)[2]); \
+} (void)0
+
+/* ProjectionPaint defines */
+
+/* approx the number of buckets to have under the brush,
+ * used with the brush size to set the ps->buckets_x and ps->buckets_y value.
+ *
+ * When 3 - a brush should have ~9 buckets under it at once
+ * ...this helps for threading while painting as well as
+ * avoiding initializing pixels that wont touch the brush */
+#define PROJ_BUCKET_BRUSH_DIV 4
+
+#define PROJ_BUCKET_RECT_MIN 4
+#define PROJ_BUCKET_RECT_MAX 256
+
+#define PROJ_BOUNDBOX_DIV 8
+#define PROJ_BOUNDBOX_SQUARED (PROJ_BOUNDBOX_DIV * PROJ_BOUNDBOX_DIV)
+
+//#define PROJ_DEBUG_PAINT 1
+//#define PROJ_DEBUG_NOSEAMBLEED 1
+//#define PROJ_DEBUG_PRINT_CLIP 1
+#define PROJ_DEBUG_WINCLIP 1
+
+/* projectFaceSeamFlags options */
+//#define PROJ_FACE_IGNORE (1<<0) /* When the face is hidden, backfacing or occluded */
+//#define PROJ_FACE_INIT (1<<1) /* When we have initialized the faces data */
+#define PROJ_FACE_SEAM1 (1 << 0) /* If this face has a seam on any of its edges */
+#define PROJ_FACE_SEAM2 (1 << 1)
+#define PROJ_FACE_SEAM3 (1 << 2)
+#define PROJ_FACE_SEAM4 (1 << 3)
+
+#define PROJ_FACE_NOSEAM1 (1 << 4)
+#define PROJ_FACE_NOSEAM2 (1 << 5)
+#define PROJ_FACE_NOSEAM3 (1 << 6)
+#define PROJ_FACE_NOSEAM4 (1 << 7)
+
+#define PROJ_SRC_VIEW 1
+#define PROJ_SRC_IMAGE_CAM 2
+#define PROJ_SRC_IMAGE_VIEW 3
+
+#define PROJ_VIEW_DATA_ID "view_data"
+#define PROJ_VIEW_DATA_SIZE (4 * 4 + 4 * 4 + 3) /* viewmat + winmat + clipsta + clipend + is_ortho */
+
+
+/* a slightly scaled down face is used to get fake 3D location for edge pixels in the seams
+ * as this number approaches 1.0f the likelihood increases of float precision errors where
+ * it is occluded by an adjacent face */
+#define PROJ_FACE_SCALE_SEAM 0.99f
+
+#define PROJ_BUCKET_NULL 0
+#define PROJ_BUCKET_INIT (1 << 0)
+// #define PROJ_BUCKET_CLONE_INIT (1<<1)
+
+/* used for testing doubles, if a point is on a line etc */
+#define PROJ_GEOM_TOLERANCE 0.00075f
+
+/* vert flags */
+#define PROJ_VERT_CULL 1
+
+/* This is mainly a convenience struct used so we can keep an array of images we use
+ * Thir imbufs, etc, in 1 array, When using threads this array is copied for each thread
+ * because 'partRedrawRect' and 'touch' values would not be thread safe */
+typedef struct ProjPaintImage {
+ Image *ima;
+ ImBuf *ibuf;
+ ImagePaintPartialRedraw *partRedrawRect;
+ void **undoRect; /* only used to build undo tiles after painting */
+ int touch;
+} ProjPaintImage;
+
+/* Main projection painting struct passed to all projection painting functions */
+typedef struct ProjPaintState {
+ View3D *v3d;
+ RegionView3D *rv3d;
+ ARegion *ar;
+ Scene *scene;
+ int source; /* PROJ_SRC_**** */
+
+ Brush *brush;
+ short tool, blend, mode;
+ int orig_brush_size;
+ Object *ob;
+ /* end similarities with ImagePaintState */
+
+ DerivedMesh *dm;
+ int dm_totface;
+ int dm_totvert;
+ int dm_release;
+
+ MVert *dm_mvert;
+ MFace *dm_mface;
+ MTFace *dm_mtface;
+ MTFace *dm_mtface_clone; /* other UV map, use for cloning between layers */
+ MTFace *dm_mtface_stencil;
+
+ /* projection painting only */
+ MemArena *arena_mt[BLENDER_MAX_THREADS]; /* for multithreading, the first item is sometimes used for non threaded cases too */
+ LinkNode **bucketRect; /* screen sized 2D array, each pixel has a linked list of ProjPixel's */
+ LinkNode **bucketFaces; /* bucketRect aligned array linkList of faces overlapping each bucket */
+ unsigned char *bucketFlags; /* store if the bucks have been initialized */
+#ifndef PROJ_DEBUG_NOSEAMBLEED
+ char *faceSeamFlags; /* store info about faces, if they are initialized etc*/
+ float (*faceSeamUVs)[4][2]; /* expanded UVs for faces to use as seams */
+ LinkNode **vertFaces; /* Only needed for when seam_bleed_px is enabled, use to find UV seams */
+#endif
+ char *vertFlags; /* store options per vert, now only store if the vert is pointing away from the view */
+ int buckets_x; /* The size of the bucket grid, the grid span's screenMin/screenMax so you can paint outsize the screen or with 2 brushes at once */
+ int buckets_y;
+
+ ProjPaintImage *projImages;
+
+ int pixel_sizeof; /* result of project_paint_pixel_sizeof(), constant per stroke */
+
+ int image_tot; /* size of projectImages array */
+
+ float (*screenCoords)[4]; /* verts projected into floating point screen space */
+
+ float screenMin[2]; /* 2D bounds for mesh verts on the screen's plane (screenspace) */
+ float screenMax[2];
+ float screen_width; /* Calculated from screenMin & screenMax */
+ float screen_height;
+ int winx, winy; /* from the carea or from the projection render */
+
+ /* options for projection painting */
+ int do_layer_clone;
+ int do_layer_stencil;
+ int do_layer_stencil_inv;
+
+ short do_occlude; /* Use raytraced occlusion? - ortherwise will paint right through to the back*/
+ short do_backfacecull; /* ignore faces with normals pointing away, skips a lot of raycasts if your normals are correctly flipped */
+ short do_mask_normal; /* mask out pixels based on their normals */
+ short do_new_shading_nodes; /* cache BKE_scene_use_new_shading_nodes value */
+ float normal_angle; /* what angle to mask at*/
+ float normal_angle_inner;
+ float normal_angle_range; /* difference between normal_angle and normal_angle_inner, for easy access */
+
+ short is_ortho;
+ bool do_masking; /* use masking during painting. Some operations such as airbrush may disable */
+ short is_texbrush; /* only to avoid running */
+#ifndef PROJ_DEBUG_NOSEAMBLEED
+ float seam_bleed_px;
+#endif
+ /* clone vars */
+ float cloneOffset[2];
+
+ float projectMat[4][4]; /* Projection matrix, use for getting screen coords */
+ float viewDir[3]; /* View vector, use for do_backfacecull and for ray casting with an ortho viewport */
+ float viewPos[3]; /* View location in object relative 3D space, so can compare to verts */
+ float clipsta, clipend;
+
+ /* reproject vars */
+ Image *reproject_image;
+ ImBuf *reproject_ibuf;
+
+
+ /* threads */
+ int thread_tot;
+ int bucketMin[2];
+ int bucketMax[2];
+ int context_bucket_x, context_bucket_y; /* must lock threads while accessing these */
+} ProjPaintState;
+
+typedef union pixelPointer {
+ float *f_pt; /* float buffer */
+ unsigned int *uint_pt; /* 2 ways to access a char buffer */
+ unsigned char *ch_pt;
+} PixelPointer;
+
+typedef union pixelStore {
+ unsigned char ch[4];
+ unsigned int uint;
+ float f[4];
+} PixelStore;
+
+typedef struct ProjPixel {
+ float projCoSS[2]; /* the floating point screen projection of this pixel */
+ float worldCoSS[3];
+ /* Only used when the airbrush is disabled.
+ * Store the max mask value to avoid painting over an area with a lower opacity
+ * with an advantage that we can avoid touching the pixel at all, if the
+ * new mask value is lower then mask_max */
+ unsigned short mask_max;
+
+ /* for various reasons we may want to mask out painting onto this pixel */
+ unsigned short mask;
+
+ short x_px, y_px;
+
+ PixelStore origColor;
+ PixelStore newColor;
+ PixelPointer pixel;
+
+ short image_index; /* if anyone wants to paint onto more then 32768 images they can bite me */
+ unsigned char bb_cell_index;
+} ProjPixel;
+
+typedef struct ProjPixelClone {
+ struct ProjPixel __pp;
+ PixelStore clonepx;
+} ProjPixelClone;
+
+/* blur, store surrounding colors */
+#define PROJ_PIXEL_SOFTEN_TOT 4
+/* blur picking offset (in screenspace) */
+#define PROJ_PIXEL_SOFTEN_OFS_PX 1.0f
+
+static const float proj_pixel_soften_v2[PROJ_PIXEL_SOFTEN_TOT][2] = {
+ {-PROJ_PIXEL_SOFTEN_OFS_PX, 0.0f},
+ { 0.0f, -PROJ_PIXEL_SOFTEN_OFS_PX},
+ { 0.0f, PROJ_PIXEL_SOFTEN_OFS_PX},
+ { PROJ_PIXEL_SOFTEN_OFS_PX, 0.0f},
+};
+
+/* Finish projection painting structs */
+
+static Image *project_paint_face_image(const ProjPaintState *ps, MTFace *dm_mtface, int face_index)
+{
+ Image *ima;
+
+ if (ps->do_new_shading_nodes) { /* cached BKE_scene_use_new_shading_nodes result */
+ MFace *mf = ps->dm_mface + face_index;
+ ED_object_get_active_image(ps->ob, mf->mat_nr + 1, &ima, NULL, NULL);
+ }
+ else {
+ ima = dm_mtface[face_index].tpage;
+ }
+
+ return ima;
+}
+
+/* fast projection bucket array lookup, use the safe version for bound checking */
+static int project_bucket_offset(const ProjPaintState *ps, const float projCoSS[2])
+{
+ /* If we were not dealing with screenspace 2D coords we could simple do...
+ * ps->bucketRect[x + (y*ps->buckets_y)] */
+
+ /* please explain?
+ * projCoSS[0] - ps->screenMin[0] : zero origin
+ * ... / ps->screen_width : range from 0.0 to 1.0
+ * ... * ps->buckets_x : use as a bucket index
+ *
+ * Second multiplication does similar but for vertical offset
+ */
+ return ( (int)(((projCoSS[0] - ps->screenMin[0]) / ps->screen_width) * ps->buckets_x)) +
+ (((int)(((projCoSS[1] - ps->screenMin[1]) / ps->screen_height) * ps->buckets_y)) * ps->buckets_x);
+}
+
+static int project_bucket_offset_safe(const ProjPaintState *ps, const float projCoSS[2])
+{
+ int bucket_index = project_bucket_offset(ps, projCoSS);
+
+ if (bucket_index < 0 || bucket_index >= ps->buckets_x * ps->buckets_y) {
+ return -1;
+ }
+ else {
+ return bucket_index;
+ }
+}
+
+/* still use 2D X,Y space but this works for verts transformed by a perspective matrix, using their 4th component as a weight */
+static void barycentric_weights_v2_persp(const float v1[4], const float v2[4], const float v3[4], const float co[2], float w[3])
+{
+ float wtot_inv, wtot;
+
+ w[0] = area_tri_signed_v2(v2, v3, co) / v1[3];
+ w[1] = area_tri_signed_v2(v3, v1, co) / v2[3];
+ w[2] = area_tri_signed_v2(v1, v2, co) / v3[3];
+ wtot = w[0] + w[1] + w[2];
+
+ if (wtot != 0.0f) {
+ wtot_inv = 1.0f / wtot;
+
+ w[0] = w[0] * wtot_inv;
+ w[1] = w[1] * wtot_inv;
+ w[2] = w[2] * wtot_inv;
+ }
+ else /* dummy values for zero area face */
+ w[0] = w[1] = w[2] = 1.0f / 3.0f;
+}
+
+static float VecZDepthOrtho(const float pt[2],
+ const float v1[3], const float v2[3], const float v3[3],
+ float w[3])
+{
+ barycentric_weights_v2(v1, v2, v3, pt, w);
+ return (v1[2] * w[0]) + (v2[2] * w[1]) + (v3[2] * w[2]);
+}
+
+static float VecZDepthPersp(const float pt[2],
+ const float v1[4], const float v2[4], const float v3[4],
+ float w[3])
+{
+ float wtot_inv, wtot;
+ float w_tmp[3];
+
+ barycentric_weights_v2_persp(v1, v2, v3, pt, w);
+ /* for the depth we need the weights to match what
+ * barycentric_weights_v2 would return, in this case its easiest just to
+ * undo the 4th axis division and make it unit-sum
+ *
+ * don't call barycentric_weights_v2() because our callers expect 'w'
+ * to be weighted from the perspective */
+ w_tmp[0] = w[0] * v1[3];
+ w_tmp[1] = w[1] * v2[3];
+ w_tmp[2] = w[2] * v3[3];
+
+ wtot = w_tmp[0] + w_tmp[1] + w_tmp[2];
+
+ if (wtot != 0.0f) {
+ wtot_inv = 1.0f / wtot;
+
+ w_tmp[0] = w_tmp[0] * wtot_inv;
+ w_tmp[1] = w_tmp[1] * wtot_inv;
+ w_tmp[2] = w_tmp[2] * wtot_inv;
+ }
+ else /* dummy values for zero area face */
+ w_tmp[0] = w_tmp[1] = w_tmp[2] = 1.0f / 3.0f;
+ /* done mimicing barycentric_weights_v2() */
+
+ return (v1[2] * w_tmp[0]) + (v2[2] * w_tmp[1]) + (v3[2] * w_tmp[2]);
+}
+
+
+/* Return the top-most face index that the screen space coord 'pt' touches (or -1) */
+static int project_paint_PickFace(const ProjPaintState *ps, const float pt[2], float w[3], int *side)
+{
+ LinkNode *node;
+ float w_tmp[3];
+ float *v1, *v2, *v3, *v4;
+ int bucket_index;
+ int face_index;
+ int best_side = -1;
+ int best_face_index = -1;
+ float z_depth_best = FLT_MAX, z_depth;
+ MFace *mf;
+
+ bucket_index = project_bucket_offset_safe(ps, pt);
+ if (bucket_index == -1)
+ return -1;
+
+
+
+ /* we could return 0 for 1 face buckets, as long as this function assumes
+ * that the point its testing is only every originated from an existing face */
+
+ for (node = ps->bucketFaces[bucket_index]; node; node = node->next) {
+ face_index = GET_INT_FROM_POINTER(node->link);
+ mf = ps->dm_mface + face_index;
+
+ v1 = ps->screenCoords[mf->v1];
+ v2 = ps->screenCoords[mf->v2];
+ v3 = ps->screenCoords[mf->v3];
+
+ if (isect_point_tri_v2(pt, v1, v2, v3)) {
+ if (ps->is_ortho) z_depth = VecZDepthOrtho(pt, v1, v2, v3, w_tmp);
+ else z_depth = VecZDepthPersp(pt, v1, v2, v3, w_tmp);
+
+ if (z_depth < z_depth_best) {
+ best_face_index = face_index;
+ best_side = 0;
+ z_depth_best = z_depth;
+ copy_v3_v3(w, w_tmp);
+ }
+ }
+ else if (mf->v4) {
+ v4 = ps->screenCoords[mf->v4];
+
+ if (isect_point_tri_v2(pt, v1, v3, v4)) {
+ if (ps->is_ortho) z_depth = VecZDepthOrtho(pt, v1, v3, v4, w_tmp);
+ else z_depth = VecZDepthPersp(pt, v1, v3, v4, w_tmp);
+
+ if (z_depth < z_depth_best) {
+ best_face_index = face_index;
+ best_side = 1;
+ z_depth_best = z_depth;
+ copy_v3_v3(w, w_tmp);
+ }
+ }
+ }
+ }
+
+ *side = best_side;
+ return best_face_index; /* will be -1 or a valid face */
+}
+
+/* Converts a uv coord into a pixel location wrapping if the uv is outside 0-1 range */
+static void uvco_to_wrapped_pxco(float uv[2], int ibuf_x, int ibuf_y, float *x, float *y)
+{
+ /* use */
+ *x = (float)fmodf(uv[0], 1.0f);
+ *y = (float)fmodf(uv[1], 1.0f);
+
+ if (*x < 0.0f) *x += 1.0f;
+ if (*y < 0.0f) *y += 1.0f;
+
+ *x = *x * ibuf_x - 0.5f;
+ *y = *y * ibuf_y - 0.5f;
+}
+
+/* Set the top-most face color that the screen space coord 'pt' touches (or return 0 if none touch) */
+static int project_paint_PickColor(const ProjPaintState *ps, const float pt[2],
+ float *rgba_fp, unsigned char *rgba, const int interp)
+{
+ float w[3], uv[2];
+ int side;
+ int face_index;
+ MTFace *tf;
+ Image *ima;
+ ImBuf *ibuf;
+ int xi, yi;
+
+
+ face_index = project_paint_PickFace(ps, pt, w, &side);
+
+ if (face_index == -1)
+ return 0;
+
+ tf = ps->dm_mtface + face_index;
+
+ if (side == 0) {
+ interp_v2_v2v2v2(uv, tf->uv[0], tf->uv[1], tf->uv[2], w);
+ }
+ else { /* QUAD */
+ interp_v2_v2v2v2(uv, tf->uv[0], tf->uv[2], tf->uv[3], w);
+ }
+
+ ima = project_paint_face_image(ps, ps->dm_mtface, face_index);
+ ibuf = ima->ibufs.first; /* we must have got the imbuf before getting here */
+ if (!ibuf) return 0;
+
+ if (interp) {
+ float x, y;
+ uvco_to_wrapped_pxco(uv, ibuf->x, ibuf->y, &x, &y);
+
+ if (ibuf->rect_float) {
+ if (rgba_fp) {
+ bilinear_interpolation_color_wrap(ibuf, NULL, rgba_fp, x, y);
+ }
+ else {
+ float rgba_tmp_f[4];
+ bilinear_interpolation_color_wrap(ibuf, NULL, rgba_tmp_f, x, y);
+ IMAPAINT_FLOAT_RGBA_TO_CHAR(rgba, rgba_tmp_f);
+ }
+ }
+ else {
+ if (rgba) {
+ bilinear_interpolation_color_wrap(ibuf, rgba, NULL, x, y);
+ }
+ else {
+ unsigned char rgba_tmp[4];
+ bilinear_interpolation_color_wrap(ibuf, rgba_tmp, NULL, x, y);
+ IMAPAINT_CHAR_RGBA_TO_FLOAT(rgba_fp, rgba_tmp);
+ }
+ }
+ }
+ else {
+ //xi = (int)((uv[0]*ibuf->x) + 0.5f);
+ //yi = (int)((uv[1]*ibuf->y) + 0.5f);
+ //if (xi < 0 || xi >= ibuf->x || yi < 0 || yi >= ibuf->y) return 0;
+
+ /* wrap */
+ xi = ((int)(uv[0] * ibuf->x)) % ibuf->x;
+ if (xi < 0) xi += ibuf->x;
+ yi = ((int)(uv[1] * ibuf->y)) % ibuf->y;
+ if (yi < 0) yi += ibuf->y;
+
+
+ if (rgba) {
+ if (ibuf->rect_float) {
+ float *rgba_tmp_fp = ibuf->rect_float + (xi + yi * ibuf->x * 4);
+ IMAPAINT_FLOAT_RGBA_TO_CHAR(rgba, rgba_tmp_fp);
+ }
+ else {
+ *((unsigned int *)rgba) = *(unsigned int *)(((char *)ibuf->rect) + ((xi + yi * ibuf->x) * 4));
+ }
+ }
+
+ if (rgba_fp) {
+ if (ibuf->rect_float) {
+ copy_v4_v4(rgba_fp, (ibuf->rect_float + ((xi + yi * ibuf->x) * 4)));
+ }
+ else {
+ char *tmp_ch = ((char *)ibuf->rect) + ((xi + yi * ibuf->x) * 4);
+ IMAPAINT_CHAR_RGBA_TO_FLOAT(rgba_fp, tmp_ch);
+ }
+ }
+ }
+ return 1;
+}
+
+/* Check if 'pt' is infront of the 3 verts on the Z axis (used for screenspace occlusuion test)
+ * return...
+ * 0 : no occlusion
+ * -1 : no occlusion but 2D intersection is true (avoid testing the other half of a quad)
+ * 1 : occluded
+ * 2 : occluded with w[3] weights set (need to know in some cases) */
+
+static int project_paint_occlude_ptv(float pt[3], float v1[4], float v2[4], float v3[4], float w[3], int is_ortho)
+{
+ /* if all are behind us, return false */
+ if (v1[2] > pt[2] && v2[2] > pt[2] && v3[2] > pt[2])
+ return 0;
+
+ /* do a 2D point in try intersection */
+ if (!isect_point_tri_v2(pt, v1, v2, v3))
+ return 0; /* we know there is */
+
+
+ /* From here on we know there IS an intersection */
+ /* if ALL of the verts are infront of us then we know it intersects ? */
+ if (v1[2] < pt[2] && v2[2] < pt[2] && v3[2] < pt[2]) {
+ return 1;
+ }
+ else {
+ /* we intersect? - find the exact depth at the point of intersection */
+ /* Is this point is occluded by another face? */
+ if (is_ortho) {
+ if (VecZDepthOrtho(pt, v1, v2, v3, w) < pt[2]) return 2;
+ }
+ else {
+ if (VecZDepthPersp(pt, v1, v2, v3, w) < pt[2]) return 2;
+ }
+ }
+ return -1;
+}
+
+
+static int project_paint_occlude_ptv_clip(const ProjPaintState *ps, const MFace *mf,
+ float pt[3], float v1[4], float v2[4], float v3[4],
+ const int side)
+{
+ float w[3], wco[3];
+ int ret = project_paint_occlude_ptv(pt, v1, v2, v3, w, ps->is_ortho);
+
+ if (ret <= 0)
+ return ret;
+
+ if (ret == 1) { /* weights not calculated */
+ if (ps->is_ortho) barycentric_weights_v2(v1, v2, v3, pt, w);
+ else barycentric_weights_v2_persp(v1, v2, v3, pt, w);
+ }
+
+ /* Test if we're in the clipped area, */
+ if (side) interp_v3_v3v3v3(wco, ps->dm_mvert[mf->v1].co, ps->dm_mvert[mf->v3].co, ps->dm_mvert[mf->v4].co, w);
+ else interp_v3_v3v3v3(wco, ps->dm_mvert[mf->v1].co, ps->dm_mvert[mf->v2].co, ps->dm_mvert[mf->v3].co, w);
+
+ if (!ED_view3d_clipping_test(ps->rv3d, wco, TRUE)) {
+ return 1;
+ }
+
+ return -1;
+}
+
+
+/* Check if a screenspace location is occluded by any other faces
+ * check, pixelScreenCo must be in screenspace, its Z-Depth only needs to be used for comparison
+ * and doesn't need to be correct in relation to X and Y coords (this is the case in perspective view) */
+static int project_bucket_point_occluded(const ProjPaintState *ps, LinkNode *bucketFace, const int orig_face, float pixelScreenCo[4])
+{
+ MFace *mf;
+ int face_index;
+ int isect_ret;
+ float w[3]; /* not needed when clipping */
+ const short do_clip = ps->rv3d ? ps->rv3d->rflag & RV3D_CLIPPING : 0;
+
+ /* we could return 0 for 1 face buckets, as long as this function assumes
+ * that the point its testing is only every originated from an existing face */
+
+ for (; bucketFace; bucketFace = bucketFace->next) {
+ face_index = GET_INT_FROM_POINTER(bucketFace->link);
+
+ if (orig_face != face_index) {
+ mf = ps->dm_mface + face_index;
+ if (do_clip)
+ isect_ret = project_paint_occlude_ptv_clip(ps, mf, pixelScreenCo, ps->screenCoords[mf->v1], ps->screenCoords[mf->v2], ps->screenCoords[mf->v3], 0);
+ else
+ isect_ret = project_paint_occlude_ptv(pixelScreenCo, ps->screenCoords[mf->v1], ps->screenCoords[mf->v2], ps->screenCoords[mf->v3], w, ps->is_ortho);
+
+ /* Note, if (isect_ret == -1) then we don't want to test the other side of the quad */
+ if (isect_ret == 0 && mf->v4) {
+ if (do_clip)
+ isect_ret = project_paint_occlude_ptv_clip(ps, mf, pixelScreenCo, ps->screenCoords[mf->v1], ps->screenCoords[mf->v3], ps->screenCoords[mf->v4], 1);
+ else
+ isect_ret = project_paint_occlude_ptv(pixelScreenCo, ps->screenCoords[mf->v1], ps->screenCoords[mf->v3], ps->screenCoords[mf->v4], w, ps->is_ortho);
+ }
+ if (isect_ret >= 1) {
+ /* TODO - we may want to cache the first hit,
+ * it is not possible to swap the face order in the list anymore */
+ return 1;
+ }
+ }
+ }
+ return 0;
+}
+
+/* basic line intersection, could move to math_geom.c, 2 points with a horiz line
+ * 1 for an intersection, 2 if the first point is aligned, 3 if the second point is aligned */
+#define ISECT_TRUE 1
+#define ISECT_TRUE_P1 2
+#define ISECT_TRUE_P2 3
+static int line_isect_y(const float p1[2], const float p2[2], const float y_level, float *x_isect)
+{
+ float y_diff;
+
+ if (y_level == p1[1]) { /* are we touching the first point? - no interpolation needed */
+ *x_isect = p1[0];
+ return ISECT_TRUE_P1;
+ }
+ if (y_level == p2[1]) { /* are we touching the second point? - no interpolation needed */
+ *x_isect = p2[0];
+ return ISECT_TRUE_P2;
+ }
+
+ y_diff = fabsf(p1[1] - p2[1]); /* yuck, horizontal line, we cant do much here */
+
+ if (y_diff < 0.000001f) {
+ *x_isect = (p1[0] + p2[0]) * 0.5f;
+ return ISECT_TRUE;
+ }
+
+ if (p1[1] > y_level && p2[1] < y_level) {
+ *x_isect = (p2[0] * (p1[1] - y_level) + p1[0] * (y_level - p2[1])) / y_diff; /*(p1[1]-p2[1]);*/
+ return ISECT_TRUE;
+ }
+ else if (p1[1] < y_level && p2[1] > y_level) {
+ *x_isect = (p2[0] * (y_level - p1[1]) + p1[0] * (p2[1] - y_level)) / y_diff; /*(p2[1]-p1[1]);*/
+ return ISECT_TRUE;
+ }
+ else {
+ return 0;
+ }
+}
+
+static int line_isect_x(const float p1[2], const float p2[2], const float x_level, float *y_isect)
+{
+ float x_diff;
+
+ if (x_level == p1[0]) { /* are we touching the first point? - no interpolation needed */
+ *y_isect = p1[1];
+ return ISECT_TRUE_P1;
+ }
+ if (x_level == p2[0]) { /* are we touching the second point? - no interpolation needed */
+ *y_isect = p2[1];
+ return ISECT_TRUE_P2;
+ }
+
+ x_diff = fabsf(p1[0] - p2[0]); /* yuck, horizontal line, we cant do much here */
+
+ if (x_diff < 0.000001f) { /* yuck, vertical line, we cant do much here */
+ *y_isect = (p1[0] + p2[0]) * 0.5f;
+ return ISECT_TRUE;
+ }
+
+ if (p1[0] > x_level && p2[0] < x_level) {
+ *y_isect = (p2[1] * (p1[0] - x_level) + p1[1] * (x_level - p2[0])) / x_diff; /*(p1[0]-p2[0]);*/
+ return ISECT_TRUE;
+ }
+ else if (p1[0] < x_level && p2[0] > x_level) {
+ *y_isect = (p2[1] * (x_level - p1[0]) + p1[1] * (p2[0] - x_level)) / x_diff; /*(p2[0]-p1[0]);*/
+ return ISECT_TRUE;
+ }
+ else {
+ return 0;
+ }
+}
+
+/* simple func use for comparing UV locations to check if there are seams.
+ * Its possible this gives incorrect results, when the UVs for 1 face go into the next
+ * tile, but do not do this for the adjacent face, it could return a false positive.
+ * This is so unlikely that Id not worry about it. */
+#ifndef PROJ_DEBUG_NOSEAMBLEED
+static int cmp_uv(const float vec2a[2], const float vec2b[2])
+{
+ /* if the UV's are not between 0.0 and 1.0 */
+ float xa = (float)fmodf(vec2a[0], 1.0f);
+ float ya = (float)fmodf(vec2a[1], 1.0f);
+
+ float xb = (float)fmodf(vec2b[0], 1.0f);
+ float yb = (float)fmodf(vec2b[1], 1.0f);
+
+ if (xa < 0.0f) xa += 1.0f;
+ if (ya < 0.0f) ya += 1.0f;
+
+ if (xb < 0.0f) xb += 1.0f;
+ if (yb < 0.0f) yb += 1.0f;
+
+ return ((fabsf(xa - xb) < PROJ_GEOM_TOLERANCE) && (fabsf(ya - yb) < PROJ_GEOM_TOLERANCE)) ? 1 : 0;
+}
+#endif
+
+/* set min_px and max_px to the image space bounds of the UV coords
+ * return zero if there is no area in the returned rectangle */
+#ifndef PROJ_DEBUG_NOSEAMBLEED
+static int pixel_bounds_uv(
+ const float uv1[2], const float uv2[2], const float uv3[2], const float uv4[2],
+ rcti *bounds_px,
+ const int ibuf_x, const int ibuf_y,
+ int is_quad
+ )
+{
+ float min_uv[2], max_uv[2]; /* UV bounds */
+
+ INIT_MINMAX2(min_uv, max_uv);
+
+ minmax_v2v2_v2(min_uv, max_uv, uv1);
+ minmax_v2v2_v2(min_uv, max_uv, uv2);
+ minmax_v2v2_v2(min_uv, max_uv, uv3);
+ if (is_quad)
+ minmax_v2v2_v2(min_uv, max_uv, uv4);
+
+ bounds_px->xmin = (int)(ibuf_x * min_uv[0]);
+ bounds_px->ymin = (int)(ibuf_y * min_uv[1]);
+
+ bounds_px->xmax = (int)(ibuf_x * max_uv[0]) + 1;
+ bounds_px->ymax = (int)(ibuf_y * max_uv[1]) + 1;
+
+ /*printf("%d %d %d %d\n", min_px[0], min_px[1], max_px[0], max_px[1]);*/
+
+ /* face uses no UV area when quantized to pixels? */
+ return (bounds_px->xmin == bounds_px->xmax || bounds_px->ymin == bounds_px->ymax) ? 0 : 1;
+}
+#endif
+
+static int pixel_bounds_array(float (*uv)[2], rcti *bounds_px, const int ibuf_x, const int ibuf_y, int tot)
+{
+ float min_uv[2], max_uv[2]; /* UV bounds */
+
+ if (tot == 0) {
+ return 0;
+ }
+
+ INIT_MINMAX2(min_uv, max_uv);
+
+ while (tot--) {
+ minmax_v2v2_v2(min_uv, max_uv, (*uv));
+ uv++;
+ }
+
+ bounds_px->xmin = (int)(ibuf_x * min_uv[0]);
+ bounds_px->ymin = (int)(ibuf_y * min_uv[1]);
+
+ bounds_px->xmax = (int)(ibuf_x * max_uv[0]) + 1;
+ bounds_px->ymax = (int)(ibuf_y * max_uv[1]) + 1;
+
+ /*printf("%d %d %d %d\n", min_px[0], min_px[1], max_px[0], max_px[1]);*/
+
+ /* face uses no UV area when quantized to pixels? */
+ return (bounds_px->xmin == bounds_px->xmax || bounds_px->ymin == bounds_px->ymax) ? 0 : 1;
+}
+
+#ifndef PROJ_DEBUG_NOSEAMBLEED
+
+/* This function returns 1 if this face has a seam along the 2 face-vert indices
+ * 'orig_i1_fidx' and 'orig_i2_fidx' */
+static int check_seam(const ProjPaintState *ps, const int orig_face, const int orig_i1_fidx, const int orig_i2_fidx, int *other_face, int *orig_fidx)
+{
+ LinkNode *node;
+ int face_index;
+ unsigned int i1, i2;
+ int i1_fidx = -1, i2_fidx = -1; /* index in face */
+ MFace *mf;
+ MTFace *tf;
+ const MFace *orig_mf = ps->dm_mface + orig_face;
+ const MTFace *orig_tf = ps->dm_mtface + orig_face;
+
+ /* vert indices from face vert order indices */
+ i1 = (*(&orig_mf->v1 + orig_i1_fidx));
+ i2 = (*(&orig_mf->v1 + orig_i2_fidx));
+
+ for (node = ps->vertFaces[i1]; node; node = node->next) {
+ face_index = GET_INT_FROM_POINTER(node->link);
+
+ if (face_index != orig_face) {
+ mf = ps->dm_mface + face_index;
+ /* could check if the 2 faces images match here,
+ * but then there wouldn't be a way to return the opposite face's info */
+
+
+ /* We need to know the order of the verts in the adjacent face
+ * set the i1_fidx and i2_fidx to (0,1,2,3) */
+ if (mf->v1 == i1) i1_fidx = 0;
+ else if (mf->v2 == i1) i1_fidx = 1;
+ else if (mf->v3 == i1) i1_fidx = 2;
+ else if (mf->v4 && mf->v4 == i1) i1_fidx = 3;
+
+ if (mf->v1 == i2) i2_fidx = 0;
+ else if (mf->v2 == i2) i2_fidx = 1;
+ else if (mf->v3 == i2) i2_fidx = 2;
+ else if (mf->v4 && mf->v4 == i2) i2_fidx = 3;
+
+ /* Only need to check if 'i2_fidx' is valid because we know i1_fidx is the same vert on both faces */
+ if (i2_fidx != -1) {
+ Image *tpage = project_paint_face_image(ps, ps->dm_mtface, face_index);
+ Image *orig_tpage = project_paint_face_image(ps, ps->dm_mtface, orig_face);
+
+ /* This IS an adjacent face!, now lets check if the UVs are ok */
+ tf = ps->dm_mtface + face_index;
+
+ /* set up the other face */
+ *other_face = face_index;
+ *orig_fidx = (i1_fidx < i2_fidx) ? i1_fidx : i2_fidx;
+
+ /* first test if they have the same image */
+ if ((orig_tpage == tpage) &&
+ cmp_uv(orig_tf->uv[orig_i1_fidx], tf->uv[i1_fidx]) &&
+ cmp_uv(orig_tf->uv[orig_i2_fidx], tf->uv[i2_fidx]) )
+ {
+ // printf("SEAM (NONE)\n");
+ return 0;
+
+ }
+ else {
+ // printf("SEAM (UV GAP)\n");
+ return 1;
+ }
+ }
+ }
+ }
+ // printf("SEAM (NO FACE)\n");
+ *other_face = -1;
+ return 1;
+}
+
+/* Calculate outset UV's, this is not the same as simply scaling the UVs,
+ * since the outset coords are a margin that keep an even distance from the original UV's,
+ * note that the image aspect is taken into account */
+static void uv_image_outset(float (*orig_uv)[2], float (*outset_uv)[2], const float scaler,
+ const int ibuf_x, const int ibuf_y, const int is_quad)
+{
+ float a1, a2, a3, a4 = 0.0f;
+ float puv[4][2]; /* pixelspace uv's */
+ float no1[2], no2[2], no3[2], no4[2]; /* normals */
+ float dir1[2], dir2[2], dir3[2], dir4[2];
+ float ibuf_inv[2];
+
+ ibuf_inv[0] = 1.0f / (float)ibuf_x;
+ ibuf_inv[1] = 1.0f / (float)ibuf_y;
+
+ /* make UV's in pixel space so we can */
+ puv[0][0] = orig_uv[0][0] * ibuf_x;
+ puv[0][1] = orig_uv[0][1] * ibuf_y;
+
+ puv[1][0] = orig_uv[1][0] * ibuf_x;
+ puv[1][1] = orig_uv[1][1] * ibuf_y;
+
+ puv[2][0] = orig_uv[2][0] * ibuf_x;
+ puv[2][1] = orig_uv[2][1] * ibuf_y;
+
+ if (is_quad) {
+ puv[3][0] = orig_uv[3][0] * ibuf_x;
+ puv[3][1] = orig_uv[3][1] * ibuf_y;
+ }
+
+ /* face edge directions */
+ sub_v2_v2v2(dir1, puv[1], puv[0]);
+ sub_v2_v2v2(dir2, puv[2], puv[1]);
+ normalize_v2(dir1);
+ normalize_v2(dir2);
+
+ if (is_quad) {
+ sub_v2_v2v2(dir3, puv[3], puv[2]);
+ sub_v2_v2v2(dir4, puv[0], puv[3]);
+ normalize_v2(dir3);
+ normalize_v2(dir4);
+ }
+ else {
+ sub_v2_v2v2(dir3, puv[0], puv[2]);
+ normalize_v2(dir3);
+ }
+
+ /* TODO - angle_normalized_v2v2(...) * (M_PI/180.0f)
+ * This is incorrect. Its already given radians but without it wont work.
+ * need to look into a fix - campbell */
+ if (is_quad) {
+ a1 = shell_angle_to_dist(angle_normalized_v2v2(dir4, dir1) * ((float)M_PI / 180.0f));
+ a2 = shell_angle_to_dist(angle_normalized_v2v2(dir1, dir2) * ((float)M_PI / 180.0f));
+ a3 = shell_angle_to_dist(angle_normalized_v2v2(dir2, dir3) * ((float)M_PI / 180.0f));
+ a4 = shell_angle_to_dist(angle_normalized_v2v2(dir3, dir4) * ((float)M_PI / 180.0f));
+ }
+ else {
+ a1 = shell_angle_to_dist(angle_normalized_v2v2(dir3, dir1) * ((float)M_PI / 180.0f));
+ a2 = shell_angle_to_dist(angle_normalized_v2v2(dir1, dir2) * ((float)M_PI / 180.0f));
+ a3 = shell_angle_to_dist(angle_normalized_v2v2(dir2, dir3) * ((float)M_PI / 180.0f));
+ }
+
+ if (is_quad) {
+ sub_v2_v2v2(no1, dir4, dir1);
+ sub_v2_v2v2(no2, dir1, dir2);
+ sub_v2_v2v2(no3, dir2, dir3);
+ sub_v2_v2v2(no4, dir3, dir4);
+ normalize_v2(no1);
+ normalize_v2(no2);
+ normalize_v2(no3);
+ normalize_v2(no4);
+ mul_v2_fl(no1, a1 * scaler);
+ mul_v2_fl(no2, a2 * scaler);
+ mul_v2_fl(no3, a3 * scaler);
+ mul_v2_fl(no4, a4 * scaler);
+ add_v2_v2v2(outset_uv[0], puv[0], no1);
+ add_v2_v2v2(outset_uv[1], puv[1], no2);
+ add_v2_v2v2(outset_uv[2], puv[2], no3);
+ add_v2_v2v2(outset_uv[3], puv[3], no4);
+ mul_v2_v2(outset_uv[0], ibuf_inv);
+ mul_v2_v2(outset_uv[1], ibuf_inv);
+ mul_v2_v2(outset_uv[2], ibuf_inv);
+ mul_v2_v2(outset_uv[3], ibuf_inv);
+ }
+ else {
+ sub_v2_v2v2(no1, dir3, dir1);
+ sub_v2_v2v2(no2, dir1, dir2);
+ sub_v2_v2v2(no3, dir2, dir3);
+ normalize_v2(no1);
+ normalize_v2(no2);
+ normalize_v2(no3);
+ mul_v2_fl(no1, a1 * scaler);
+ mul_v2_fl(no2, a2 * scaler);
+ mul_v2_fl(no3, a3 * scaler);
+ add_v2_v2v2(outset_uv[0], puv[0], no1);
+ add_v2_v2v2(outset_uv[1], puv[1], no2);
+ add_v2_v2v2(outset_uv[2], puv[2], no3);
+
+ mul_v2_v2(outset_uv[0], ibuf_inv);
+ mul_v2_v2(outset_uv[1], ibuf_inv);
+ mul_v2_v2(outset_uv[2], ibuf_inv);
+ }
+}
+
+/*
+ * Be tricky with flags, first 4 bits are PROJ_FACE_SEAM1 to 4, last 4 bits are PROJ_FACE_NOSEAM1 to 4
+ * 1<<i - where i is (0-3)
+ *
+ * If we're multithreadng, make sure threads are locked when this is called
+ */
+static void project_face_seams_init(const ProjPaintState *ps, const int face_index, const int is_quad)
+{
+ int other_face, other_fidx; /* vars for the other face, we also set its flag */
+ int fidx1 = is_quad ? 3 : 2;
+ int fidx2 = 0; /* next fidx in the face (0,1,2,3) -> (1,2,3,0) or (0,1,2) -> (1,2,0) for a tri */
+
+ do {
+ if ((ps->faceSeamFlags[face_index] & (1 << fidx1 | 16 << fidx1)) == 0) {
+ if (check_seam(ps, face_index, fidx1, fidx2, &other_face, &other_fidx)) {
+ ps->faceSeamFlags[face_index] |= 1 << fidx1;
+ if (other_face != -1)
+ ps->faceSeamFlags[other_face] |= 1 << other_fidx;
+ }
+ else {
+ ps->faceSeamFlags[face_index] |= 16 << fidx1;
+ if (other_face != -1)
+ ps->faceSeamFlags[other_face] |= 16 << other_fidx; /* second 4 bits for disabled */
+ }
+ }
+
+ fidx2 = fidx1;
+ } while (fidx1--);
+}
+#endif // PROJ_DEBUG_NOSEAMBLEED
+
+
+/* Converts a UV location to a 3D screenspace location
+ * Takes a 'uv' and 3 UV coords, and sets the values of pixelScreenCo
+ *
+ * This is used for finding a pixels location in screenspace for painting */
+static void screen_px_from_ortho(
+ float uv[2],
+ float v1co[3], float v2co[3], float v3co[3], /* Screenspace coords */
+ float uv1co[2], float uv2co[2], float uv3co[2],
+ float pixelScreenCo[4],
+ float w[3])
+{
+ barycentric_weights_v2(uv1co, uv2co, uv3co, uv, w);
+ interp_v3_v3v3v3(pixelScreenCo, v1co, v2co, v3co, w);
+}
+
+/* same as screen_px_from_ortho except we need to take into account
+ * the perspective W coord for each vert */
+static void screen_px_from_persp(
+ float uv[2],
+ float v1co[4], float v2co[4], float v3co[4], /* screenspace coords */
+ float uv1co[2], float uv2co[2], float uv3co[2],
+ float pixelScreenCo[4],
+ float w[3])
+{
+
+ float wtot_inv, wtot;
+ barycentric_weights_v2(uv1co, uv2co, uv3co, uv, w);
+
+ /* re-weight from the 4th coord of each screen vert */
+ w[0] *= v1co[3];
+ w[1] *= v2co[3];
+ w[2] *= v3co[3];
+
+ wtot = w[0] + w[1] + w[2];
+
+ if (wtot > 0.0f) {
+ wtot_inv = 1.0f / wtot;
+ w[0] *= wtot_inv;
+ w[1] *= wtot_inv;
+ w[2] *= wtot_inv;
+ }
+ else {
+ w[0] = w[1] = w[2] = 1.0f / 3.0f; /* dummy values for zero area face */
+ }
+ /* done re-weighting */
+
+ interp_v3_v3v3v3(pixelScreenCo, v1co, v2co, v3co, w);
+}
+
+static void project_face_pixel(const MTFace *tf_other, ImBuf *ibuf_other, const float w[3],
+ int side, unsigned char rgba_ub[4], float rgba_f[4])
+{
+ float *uvCo1, *uvCo2, *uvCo3;
+ float uv_other[2], x, y;
+
+ uvCo1 = (float *)tf_other->uv[0];
+ if (side == 1) {
+ uvCo2 = (float *)tf_other->uv[2];
+ uvCo3 = (float *)tf_other->uv[3];
+ }
+ else {
+ uvCo2 = (float *)tf_other->uv[1];
+ uvCo3 = (float *)tf_other->uv[2];
+ }
+
+ interp_v2_v2v2v2(uv_other, uvCo1, uvCo2, uvCo3, (float *)w);
+
+ /* use */
+ uvco_to_wrapped_pxco(uv_other, ibuf_other->x, ibuf_other->y, &x, &y);
+
+
+ if (ibuf_other->rect_float) { /* from float to float */
+ bilinear_interpolation_color_wrap(ibuf_other, NULL, rgba_f, x, y);
+ }
+ else { /* from char to float */
+ bilinear_interpolation_color_wrap(ibuf_other, rgba_ub, NULL, x, y);
+ }
+
+}
+
+/* run this outside project_paint_uvpixel_init since pixels with mask 0 don't need init */
+static float project_paint_uvpixel_mask(
+ const ProjPaintState *ps,
+ const int face_index,
+ const int side,
+ const float w[3])
+{
+ float mask;
+
+ /* Image Mask */
+ if (ps->do_layer_stencil) {
+ /* another UV maps image is masking this one's */
+ ImBuf *ibuf_other;
+ Image *other_tpage = project_paint_face_image(ps, ps->dm_mtface_stencil, face_index);
+ const MTFace *tf_other = ps->dm_mtface_stencil + face_index;
+
+ if (other_tpage && (ibuf_other = BKE_image_acquire_ibuf(other_tpage, NULL, NULL))) {
+ /* BKE_image_acquire_ibuf - TODO - this may be slow */
+ unsigned char rgba_ub[4];
+ float rgba_f[4];
+
+ project_face_pixel(tf_other, ibuf_other, w, side, rgba_ub, rgba_f);
+
+ if (ibuf_other->rect_float) { /* from float to float */
+ mask = ((rgba_f[0] + rgba_f[1] + rgba_f[2]) / 3.0f) * rgba_f[3];
+ }
+ else { /* from char to float */
+ mask = ((rgba_ub[0] + rgba_ub[1] + rgba_ub[2]) / (256 * 3.0f)) * (rgba_ub[3] / 256.0f);
+ }
+
+ BKE_image_release_ibuf(other_tpage, ibuf_other, NULL);
+
+ if (!ps->do_layer_stencil_inv) /* matching the gimps layer mask black/white rules, white==full opacity */
+ mask = (1.0f - mask);
+
+ if (mask == 0.0f) {
+ return 0.0f;
+ }
+ }
+ else {
+ return 0.0f;
+ }
+ }
+ else {
+ mask = 1.0f;
+ }
+
+ /* calculate mask */
+ if (ps->do_mask_normal) {
+ MFace *mf = &ps->dm_mface[face_index];
+ float no[3], angle;
+ if (mf->flag & ME_SMOOTH) {
+ short *no1, *no2, *no3;
+ no1 = ps->dm_mvert[mf->v1].no;
+ if (side == 1) {
+ no2 = ps->dm_mvert[mf->v3].no;
+ no3 = ps->dm_mvert[mf->v4].no;
+ }
+ else {
+ no2 = ps->dm_mvert[mf->v2].no;
+ no3 = ps->dm_mvert[mf->v3].no;
+ }
+
+ no[0] = w[0] * no1[0] + w[1] * no2[0] + w[2] * no3[0];
+ no[1] = w[0] * no1[1] + w[1] * no2[1] + w[2] * no3[1];
+ no[2] = w[0] * no1[2] + w[1] * no2[2] + w[2] * no3[2];
+ normalize_v3(no);
+ }
+ else {
+ /* incase the */
+#if 1
+ /* normalizing per pixel isn't optimal, we could cache or check ps->*/
+ if (mf->v4)
+ normal_quad_v3(no,
+ ps->dm_mvert[mf->v1].co,
+ ps->dm_mvert[mf->v2].co,
+ ps->dm_mvert[mf->v3].co,
+ ps->dm_mvert[mf->v4].co);
+ else
+ normal_tri_v3(no,
+ ps->dm_mvert[mf->v1].co,
+ ps->dm_mvert[mf->v2].co,
+ ps->dm_mvert[mf->v3].co);
+#else
+ /* don't use because some modifiers dont have normal data (subsurf for eg) */
+ copy_v3_v3(no, (float *)ps->dm->getTessFaceData(ps->dm, face_index, CD_NORMAL));
+#endif
+ }
+
+ /* now we can use the normal as a mask */
+ if (ps->is_ortho) {
+ angle = angle_normalized_v3v3((float *)ps->viewDir, no);
+ }
+ else {
+ /* Annoying but for the perspective view we need to get the pixels location in 3D space :/ */
+ float viewDirPersp[3];
+ float *co1, *co2, *co3;
+ co1 = ps->dm_mvert[mf->v1].co;
+ if (side == 1) {
+ co2 = ps->dm_mvert[mf->v3].co;
+ co3 = ps->dm_mvert[mf->v4].co;
+ }
+ else {
+ co2 = ps->dm_mvert[mf->v2].co;
+ co3 = ps->dm_mvert[mf->v3].co;
+ }
+
+ /* Get the direction from the viewPoint to the pixel and normalize */
+ viewDirPersp[0] = (ps->viewPos[0] - (w[0] * co1[0] + w[1] * co2[0] + w[2] * co3[0]));
+ viewDirPersp[1] = (ps->viewPos[1] - (w[0] * co1[1] + w[1] * co2[1] + w[2] * co3[1]));
+ viewDirPersp[2] = (ps->viewPos[2] - (w[0] * co1[2] + w[1] * co2[2] + w[2] * co3[2]));
+ normalize_v3(viewDirPersp);
+
+ angle = angle_normalized_v3v3(viewDirPersp, no);
+ }
+
+ if (angle >= ps->normal_angle) {
+ return 0.0f; /* outsize the normal limit*/
+ }
+ else if (angle > ps->normal_angle_inner) {
+ mask *= (ps->normal_angle - angle) / ps->normal_angle_range;
+ } /* otherwise no mask normal is needed, were within the limit */
+ }
+
+ /* This only works when the opacity dosnt change while painting, stylus pressure messes with this
+ * so don't use it. */
+ // if (ps->is_airbrush == 0) mask *= BKE_brush_alpha_get(ps->brush);
+
+ return mask;
+}
+
+static int project_paint_pixel_sizeof(const short tool)
+{
+ if ((tool == PAINT_TOOL_CLONE) || (tool == PAINT_TOOL_SMEAR)) {
+ return sizeof(ProjPixelClone);
+ }
+ else {
+ return sizeof(ProjPixel);
+ }
+}
+
+
+/* run this function when we know a bucket's, face's pixel can be initialized,
+ * return the ProjPixel which is added to 'ps->bucketRect[bucket_index]' */
+static ProjPixel *project_paint_uvpixel_init(
+ const ProjPaintState *ps,
+ MemArena *arena,
+ const ImBuf *ibuf,
+ short x_px, short y_px,
+ const float mask,
+ const int face_index,
+ const int image_index,
+ const float pixelScreenCo[4],
+ const float world_spaceCo[3],
+ const int side,
+ const float w[3])
+{
+ ProjPixel *projPixel;
+
+ /* wrap pixel location */
+ x_px = x_px % ibuf->x;
+ if (x_px < 0) x_px += ibuf->x;
+ y_px = y_px % ibuf->y;
+ if (y_px < 0) y_px += ibuf->y;
+
+ BLI_assert(ps->pixel_sizeof == project_paint_pixel_sizeof(ps->tool));
+ projPixel = (ProjPixel *)BLI_memarena_alloc(arena, ps->pixel_sizeof);
+ //memset(projPixel, 0, size);
+
+ if (ibuf->rect_float) {
+ projPixel->pixel.f_pt = ibuf->rect_float + ((x_px + y_px * ibuf->x) * 4);
+ projPixel->origColor.f[0] = projPixel->newColor.f[0] = projPixel->pixel.f_pt[0];
+ projPixel->origColor.f[1] = projPixel->newColor.f[1] = projPixel->pixel.f_pt[1];
+ projPixel->origColor.f[2] = projPixel->newColor.f[2] = projPixel->pixel.f_pt[2];
+ projPixel->origColor.f[3] = projPixel->newColor.f[3] = projPixel->pixel.f_pt[3];
+ }
+ else {
+ projPixel->pixel.ch_pt = ((unsigned char *)ibuf->rect + ((x_px + y_px * ibuf->x) * 4));
+ projPixel->origColor.uint = projPixel->newColor.uint = *projPixel->pixel.uint_pt;
+ }
+
+ /* screenspace unclamped, we could keep its z and w values but don't need them at the moment */
+ if (ps->brush->mtex.brush_map_mode == MTEX_MAP_MODE_3D) {
+ copy_v3_v3(projPixel->worldCoSS, world_spaceCo);
+ }
+
+ copy_v2_v2(projPixel->projCoSS, pixelScreenCo);
+
+ projPixel->x_px = x_px;
+ projPixel->y_px = y_px;
+
+ projPixel->mask = (unsigned short)(mask * 65535);
+ projPixel->mask_max = 0;
+
+ /* which bounding box cell are we in?, needed for undo */
+ projPixel->bb_cell_index = ((int)(((float)x_px / (float)ibuf->x) * PROJ_BOUNDBOX_DIV)) +
+ ((int)(((float)y_px / (float)ibuf->y) * PROJ_BOUNDBOX_DIV)) * PROJ_BOUNDBOX_DIV;
+
+ /* done with view3d_project_float inline */
+ if (ps->tool == PAINT_TOOL_CLONE) {
+ if (ps->dm_mtface_clone) {
+ ImBuf *ibuf_other;
+ Image *other_tpage = project_paint_face_image(ps, ps->dm_mtface_clone, face_index);
+ const MTFace *tf_other = ps->dm_mtface_clone + face_index;
+
+ if (other_tpage && (ibuf_other = BKE_image_acquire_ibuf(other_tpage, NULL, NULL))) {
+ /* BKE_image_acquire_ibuf - TODO - this may be slow */
+
+ if (ibuf->rect_float) {
+ if (ibuf_other->rect_float) { /* from float to float */
+ project_face_pixel(tf_other, ibuf_other, w, side, NULL, ((ProjPixelClone *)projPixel)->clonepx.f);
+ }
+ else { /* from char to float */
+ unsigned char rgba_ub[4];
+ float rgba[4];
+ project_face_pixel(tf_other, ibuf_other, w, side, rgba_ub, NULL);
+ srgb_to_linearrgb_uchar4(rgba, rgba_ub);
+ straight_to_premul_v4_v4(((ProjPixelClone *)projPixel)->clonepx.f, rgba);
+ }
+ }
+ else {
+ if (ibuf_other->rect_float) { /* float to char */
+ float rgba[4];
+ project_face_pixel(tf_other, ibuf_other, w, side, NULL, rgba);
+ premul_to_straight_v4(rgba);
+ linearrgb_to_srgb_uchar3(((ProjPixelClone *)projPixel)->clonepx.ch, rgba);
+ }
+ else { /* char to char */
+ project_face_pixel(tf_other, ibuf_other, w, side, ((ProjPixelClone *)projPixel)->clonepx.ch, NULL);
+ }
+ }
+
+ BKE_image_release_ibuf(other_tpage, ibuf_other, NULL);
+ }
+ else {
+ if (ibuf->rect_float) {
+ ((ProjPixelClone *)projPixel)->clonepx.f[3] = 0;
+ }
+ else {
+ ((ProjPixelClone *)projPixel)->clonepx.ch[3] = 0;
+ }
+ }
+
+ }
+ else {
+ float co[2];
+ sub_v2_v2v2(co, projPixel->projCoSS, (float *)ps->cloneOffset);
+
+ /* no need to initialize the bucket, we're only checking buckets faces and for this
+ * the faces are already initialized in project_paint_delayed_face_init(...) */
+ if (ibuf->rect_float) {
+ if (!project_paint_PickColor(ps, co, ((ProjPixelClone *)projPixel)->clonepx.f, NULL, 1)) {
+ ((ProjPixelClone *)projPixel)->clonepx.f[3] = 0; /* zero alpha - ignore */
+ }
+ }
+ else {
+ if (!project_paint_PickColor(ps, co, NULL, ((ProjPixelClone *)projPixel)->clonepx.ch, 1)) {
+ ((ProjPixelClone *)projPixel)->clonepx.ch[3] = 0; /* zero alpha - ignore */
+ }
+ }
+ }
+ }
+
+#ifdef PROJ_DEBUG_PAINT
+ if (ibuf->rect_float) projPixel->pixel.f_pt[0] = 0;
+ else projPixel->pixel.ch_pt[0] = 0;
+#endif
+ projPixel->image_index = image_index;
+
+ return projPixel;
+}
+
+static int line_clip_rect2f(
+ rctf *rect,
+ const float l1[2], const float l2[2],
+ float l1_clip[2], float l2_clip[2])
+{
+ /* first account for horizontal, then vertical lines */
+ /* horiz */
+ if (fabsf(l1[1] - l2[1]) < PROJ_GEOM_TOLERANCE) {
+ /* is the line out of range on its Y axis? */
+ if (l1[1] < rect->ymin || l1[1] > rect->ymax) {
+ return 0;
+ }
+ /* line is out of range on its X axis */
+ if ((l1[0] < rect->xmin && l2[0] < rect->xmin) || (l1[0] > rect->xmax && l2[0] > rect->xmax)) {
+ return 0;
+ }
+
+
+ if (fabsf(l1[0] - l2[0]) < PROJ_GEOM_TOLERANCE) { /* this is a single point (or close to)*/
+ if (BLI_rctf_isect_pt_v(rect, l1)) {
+ copy_v2_v2(l1_clip, l1);
+ copy_v2_v2(l2_clip, l2);
+ return 1;
+ }
+ else {
+ return 0;
+ }
+ }
+
+ copy_v2_v2(l1_clip, l1);
+ copy_v2_v2(l2_clip, l2);
+ CLAMP(l1_clip[0], rect->xmin, rect->xmax);
+ CLAMP(l2_clip[0], rect->xmin, rect->xmax);
+ return 1;
+ }
+ else if (fabsf(l1[0] - l2[0]) < PROJ_GEOM_TOLERANCE) {
+ /* is the line out of range on its X axis? */
+ if (l1[0] < rect->xmin || l1[0] > rect->xmax) {
+ return 0;
+ }
+
+ /* line is out of range on its Y axis */
+ if ((l1[1] < rect->ymin && l2[1] < rect->ymin) || (l1[1] > rect->ymax && l2[1] > rect->ymax)) {
+ return 0;
+ }
+
+ if (fabsf(l1[1] - l2[1]) < PROJ_GEOM_TOLERANCE) { /* this is a single point (or close to)*/
+ if (BLI_rctf_isect_pt_v(rect, l1)) {
+ copy_v2_v2(l1_clip, l1);
+ copy_v2_v2(l2_clip, l2);
+ return 1;
+ }
+ else {
+ return 0;
+ }
+ }
+
+ copy_v2_v2(l1_clip, l1);
+ copy_v2_v2(l2_clip, l2);
+ CLAMP(l1_clip[1], rect->ymin, rect->ymax);
+ CLAMP(l2_clip[1], rect->ymin, rect->ymax);
+ return 1;
+ }
+ else {
+ float isect;
+ short ok1 = 0;
+ short ok2 = 0;
+
+ /* Done with vertical lines */
+
+ /* are either of the points inside the rectangle ? */
+ if (BLI_rctf_isect_pt_v(rect, l1)) {
+ copy_v2_v2(l1_clip, l1);
+ ok1 = 1;
+ }
+
+ if (BLI_rctf_isect_pt_v(rect, l2)) {
+ copy_v2_v2(l2_clip, l2);
+ ok2 = 1;
+ }
+
+ /* line inside rect */
+ if (ok1 && ok2) return 1;
+
+ /* top/bottom */
+ if (line_isect_y(l1, l2, rect->ymin, &isect) && (isect >= rect->xmin) && (isect <= rect->xmax)) {
+ if (l1[1] < l2[1]) { /* line 1 is outside */
+ l1_clip[0] = isect;
+ l1_clip[1] = rect->ymin;
+ ok1 = 1;
+ }
+ else {
+ l2_clip[0] = isect;
+ l2_clip[1] = rect->ymin;
+ ok2 = 2;
+ }
+ }
+
+ if (ok1 && ok2) return 1;
+
+ if (line_isect_y(l1, l2, rect->ymax, &isect) && (isect >= rect->xmin) && (isect <= rect->xmax)) {
+ if (l1[1] > l2[1]) { /* line 1 is outside */
+ l1_clip[0] = isect;
+ l1_clip[1] = rect->ymax;
+ ok1 = 1;
+ }
+ else {
+ l2_clip[0] = isect;
+ l2_clip[1] = rect->ymax;
+ ok2 = 2;
+ }
+ }
+
+ if (ok1 && ok2) return 1;
+
+ /* left/right */
+ if (line_isect_x(l1, l2, rect->xmin, &isect) && (isect >= rect->ymin) && (isect <= rect->ymax)) {
+ if (l1[0] < l2[0]) { /* line 1 is outside */
+ l1_clip[0] = rect->xmin;
+ l1_clip[1] = isect;
+ ok1 = 1;
+ }
+ else {
+ l2_clip[0] = rect->xmin;
+ l2_clip[1] = isect;
+ ok2 = 2;
+ }
+ }
+
+ if (ok1 && ok2) return 1;
+
+ if (line_isect_x(l1, l2, rect->xmax, &isect) && (isect >= rect->ymin) && (isect <= rect->ymax)) {
+ if (l1[0] > l2[0]) { /* line 1 is outside */
+ l1_clip[0] = rect->xmax;
+ l1_clip[1] = isect;
+ ok1 = 1;
+ }
+ else {
+ l2_clip[0] = rect->xmax;
+ l2_clip[1] = isect;
+ ok2 = 2;
+ }
+ }
+
+ if (ok1 && ok2) {
+ return 1;
+ }
+ else {
+ return 0;
+ }
+ }
+}
+
+
+
+/* scale the quad & tri about its center
+ * scaling by PROJ_FACE_SCALE_SEAM (0.99x) is used for getting fake UV pixel coords that are on the
+ * edge of the face but slightly inside it occlusion tests don't return hits on adjacent faces */
+#ifndef PROJ_DEBUG_NOSEAMBLEED
+static void scale_quad(float insetCos[4][3], float *origCos[4], const float inset)
+{
+ float cent[3];
+ cent[0] = (origCos[0][0] + origCos[1][0] + origCos[2][0] + origCos[3][0]) / 4.0f;
+ cent[1] = (origCos[0][1] + origCos[1][1] + origCos[2][1] + origCos[3][1]) / 4.0f;
+ cent[2] = (origCos[0][2] + origCos[1][2] + origCos[2][2] + origCos[3][2]) / 4.0f;
+
+ sub_v3_v3v3(insetCos[0], origCos[0], cent);
+ sub_v3_v3v3(insetCos[1], origCos[1], cent);
+ sub_v3_v3v3(insetCos[2], origCos[2], cent);
+ sub_v3_v3v3(insetCos[3], origCos[3], cent);
+
+ mul_v3_fl(insetCos[0], inset);
+ mul_v3_fl(insetCos[1], inset);
+ mul_v3_fl(insetCos[2], inset);
+ mul_v3_fl(insetCos[3], inset);
+
+ add_v3_v3(insetCos[0], cent);
+ add_v3_v3(insetCos[1], cent);
+ add_v3_v3(insetCos[2], cent);
+ add_v3_v3(insetCos[3], cent);
+}
+
+
+static void scale_tri(float insetCos[4][3], float *origCos[4], const float inset)
+{
+ float cent[3];
+ cent[0] = (origCos[0][0] + origCos[1][0] + origCos[2][0]) / 3.0f;
+ cent[1] = (origCos[0][1] + origCos[1][1] + origCos[2][1]) / 3.0f;
+ cent[2] = (origCos[0][2] + origCos[1][2] + origCos[2][2]) / 3.0f;
+
+ sub_v3_v3v3(insetCos[0], origCos[0], cent);
+ sub_v3_v3v3(insetCos[1], origCos[1], cent);
+ sub_v3_v3v3(insetCos[2], origCos[2], cent);
+
+ mul_v3_fl(insetCos[0], inset);
+ mul_v3_fl(insetCos[1], inset);
+ mul_v3_fl(insetCos[2], inset);
+
+ add_v3_v3(insetCos[0], cent);
+ add_v3_v3(insetCos[1], cent);
+ add_v3_v3(insetCos[2], cent);
+}
+#endif //PROJ_DEBUG_NOSEAMBLEED
+
+static float len_squared_v2v2_alt(const float *v1, const float v2_1, const float v2_2)
+{
+ float x, y;
+
+ x = v1[0] - v2_1;
+ y = v1[1] - v2_2;
+ return x * x + y * y;
+}
+
+/* note, use a squared value so we can use len_squared_v2v2
+ * be sure that you have done a bounds check first or this may fail */
+/* only give bucket_bounds as an arg because we need it elsewhere */
+static int project_bucket_isect_circle(const float cent[2], const float radius_squared, rctf *bucket_bounds)
+{
+
+ /* Would normally to a simple intersection test, however we know the bounds of these 2 already intersect
+ * so we only need to test if the center is inside the vertical or horizontal bounds on either axis,
+ * this is even less work then an intersection test
+ */
+#if 0
+ if (BLI_rctf_isect_pt_v(bucket_bounds, cent))
+ return 1;
+#endif
+
+ if ((bucket_bounds->xmin <= cent[0] && bucket_bounds->xmax >= cent[0]) ||
+ (bucket_bounds->ymin <= cent[1] && bucket_bounds->ymax >= cent[1]))
+ {
+ return 1;
+ }
+
+ /* out of bounds left */
+ if (cent[0] < bucket_bounds->xmin) {
+ /* lower left out of radius test */
+ if (cent[1] < bucket_bounds->ymin) {
+ return (len_squared_v2v2_alt(cent, bucket_bounds->xmin, bucket_bounds->ymin) < radius_squared) ? 1 : 0;
+ }
+ /* top left test */
+ else if (cent[1] > bucket_bounds->ymax) {
+ return (len_squared_v2v2_alt(cent, bucket_bounds->xmin, bucket_bounds->ymax) < radius_squared) ? 1 : 0;
+ }
+ }
+ else if (cent[0] > bucket_bounds->xmax) {
+ /* lower right out of radius test */
+ if (cent[1] < bucket_bounds->ymin) {
+ return (len_squared_v2v2_alt(cent, bucket_bounds->xmax, bucket_bounds->ymin) < radius_squared) ? 1 : 0;
+ }
+ /* top right test */
+ else if (cent[1] > bucket_bounds->ymax) {
+ return (len_squared_v2v2_alt(cent, bucket_bounds->xmax, bucket_bounds->ymax) < radius_squared) ? 1 : 0;
+ }
+ }
+
+ return 0;
+}
+
+
+
+/* Note for rect_to_uvspace_ortho() and rect_to_uvspace_persp()
+ * in ortho view this function gives good results when bucket_bounds are outside the triangle
+ * however in some cases, perspective view will mess up with faces that have minimal screenspace area
+ * (viewed from the side)
+ *
+ * for this reason its not reliable in this case so we'll use the Simple Barycentric'
+ * funcs that only account for points inside the triangle.
+ * however switching back to this for ortho is always an option */
+
+static void rect_to_uvspace_ortho(
+ rctf *bucket_bounds,
+ float *v1coSS, float *v2coSS, float *v3coSS,
+ float *uv1co, float *uv2co, float *uv3co,
+ float bucket_bounds_uv[4][2],
+ const int flip)
+{
+ float uv[2];
+ float w[3];
+
+ /* get the UV space bounding box */
+ uv[0] = bucket_bounds->xmax;
+ uv[1] = bucket_bounds->ymin;
+ barycentric_weights_v2(v1coSS, v2coSS, v3coSS, uv, w);
+ interp_v2_v2v2v2(bucket_bounds_uv[flip ? 3 : 0], uv1co, uv2co, uv3co, w);
+
+ //uv[0] = bucket_bounds->xmax; // set above
+ uv[1] = bucket_bounds->ymax;
+ barycentric_weights_v2(v1coSS, v2coSS, v3coSS, uv, w);
+ interp_v2_v2v2v2(bucket_bounds_uv[flip ? 2 : 1], uv1co, uv2co, uv3co, w);
+
+ uv[0] = bucket_bounds->xmin;
+ //uv[1] = bucket_bounds->ymax; // set above
+ barycentric_weights_v2(v1coSS, v2coSS, v3coSS, uv, w);
+ interp_v2_v2v2v2(bucket_bounds_uv[flip ? 1 : 2], uv1co, uv2co, uv3co, w);
+
+ //uv[0] = bucket_bounds->xmin; // set above
+ uv[1] = bucket_bounds->ymin;
+ barycentric_weights_v2(v1coSS, v2coSS, v3coSS, uv, w);
+ interp_v2_v2v2v2(bucket_bounds_uv[flip ? 0 : 3], uv1co, uv2co, uv3co, w);
+}
+
+/* same as above but use barycentric_weights_v2_persp */
+static void rect_to_uvspace_persp(
+ rctf *bucket_bounds,
+ float *v1coSS, float *v2coSS, float *v3coSS,
+ float *uv1co, float *uv2co, float *uv3co,
+ float bucket_bounds_uv[4][2],
+ const int flip
+ )
+{
+ float uv[2];
+ float w[3];
+
+ /* get the UV space bounding box */
+ uv[0] = bucket_bounds->xmax;
+ uv[1] = bucket_bounds->ymin;
+ barycentric_weights_v2_persp(v1coSS, v2coSS, v3coSS, uv, w);
+ interp_v2_v2v2v2(bucket_bounds_uv[flip ? 3 : 0], uv1co, uv2co, uv3co, w);
+
+ //uv[0] = bucket_bounds->xmax; // set above
+ uv[1] = bucket_bounds->ymax;
+ barycentric_weights_v2_persp(v1coSS, v2coSS, v3coSS, uv, w);
+ interp_v2_v2v2v2(bucket_bounds_uv[flip ? 2 : 1], uv1co, uv2co, uv3co, w);
+
+ uv[0] = bucket_bounds->xmin;
+ //uv[1] = bucket_bounds->ymax; // set above
+ barycentric_weights_v2_persp(v1coSS, v2coSS, v3coSS, uv, w);
+ interp_v2_v2v2v2(bucket_bounds_uv[flip ? 1 : 2], uv1co, uv2co, uv3co, w);
+
+ //uv[0] = bucket_bounds->xmin; // set above
+ uv[1] = bucket_bounds->ymin;
+ barycentric_weights_v2_persp(v1coSS, v2coSS, v3coSS, uv, w);
+ interp_v2_v2v2v2(bucket_bounds_uv[flip ? 0 : 3], uv1co, uv2co, uv3co, w);
+}
+
+/* This works as we need it to but we can save a few steps and not use it */
+
+#if 0
+static float angle_2d_clockwise(const float p1[2], const float p2[2], const float p3[2])
+{
+ float v1[2], v2[2];
+
+ v1[0] = p1[0] - p2[0]; v1[1] = p1[1] - p2[1];
+ v2[0] = p3[0] - p2[0]; v2[1] = p3[1] - p2[1];
+
+ return -atan2(v1[0] * v2[1] - v1[1] * v2[0], v1[0] * v2[0] + v1[1] * v2[1]);
+}
+#endif
+
+#define ISECT_1 (1)
+#define ISECT_2 (1 << 1)
+#define ISECT_3 (1 << 2)
+#define ISECT_4 (1 << 3)
+#define ISECT_ALL3 ((1 << 3) - 1)
+#define ISECT_ALL4 ((1 << 4) - 1)
+
+/* limit must be a fraction over 1.0f */
+static int IsectPT2Df_limit(float pt[2], float v1[2], float v2[2], float v3[2], float limit)
+{
+ return ((area_tri_v2(pt, v1, v2) + area_tri_v2(pt, v2, v3) + area_tri_v2(pt, v3, v1)) / (area_tri_v2(v1, v2, v3))) < limit;
+}
+
+/* Clip the face by a bucket and set the uv-space bucket_bounds_uv
+ * so we have the clipped UV's to do pixel intersection tests with
+ * */
+static int float_z_sort_flip(const void *p1, const void *p2)
+{
+ return (((float *)p1)[2] < ((float *)p2)[2] ? 1 : -1);
+}
+
+static int float_z_sort(const void *p1, const void *p2)
+{
+ return (((float *)p1)[2] < ((float *)p2)[2] ? -1 : 1);
+}
+
+static void project_bucket_clip_face(
+ const int is_ortho,
+ rctf *bucket_bounds,
+ float *v1coSS, float *v2coSS, float *v3coSS,
+ float *uv1co, float *uv2co, float *uv3co,
+ float bucket_bounds_uv[8][2],
+ int *tot)
+{
+ int inside_bucket_flag = 0;
+ int inside_face_flag = 0;
+ const int flip = ((line_point_side_v2(v1coSS, v2coSS, v3coSS) > 0.0f) != (line_point_side_v2(uv1co, uv2co, uv3co) > 0.0f));
+
+ float bucket_bounds_ss[4][2];
+
+ /* get the UV space bounding box */
+ inside_bucket_flag |= BLI_rctf_isect_pt_v(bucket_bounds, v1coSS);
+ inside_bucket_flag |= BLI_rctf_isect_pt_v(bucket_bounds, v2coSS) << 1;
+ inside_bucket_flag |= BLI_rctf_isect_pt_v(bucket_bounds, v3coSS) << 2;
+
+ if (inside_bucket_flag == ISECT_ALL3) {
+ /* all screenspace points are inside the bucket bounding box, this means we don't need to clip and can simply return the UVs */
+ if (flip) { /* facing the back? */
+ copy_v2_v2(bucket_bounds_uv[0], uv3co);
+ copy_v2_v2(bucket_bounds_uv[1], uv2co);
+ copy_v2_v2(bucket_bounds_uv[2], uv1co);
+ }
+ else {
+ copy_v2_v2(bucket_bounds_uv[0], uv1co);
+ copy_v2_v2(bucket_bounds_uv[1], uv2co);
+ copy_v2_v2(bucket_bounds_uv[2], uv3co);
+ }
+
+ *tot = 3;
+ return;
+ }
+
+ /* get the UV space bounding box */
+ /* use IsectPT2Df_limit here so we catch points are are touching the tri edge (or a small fraction over) */
+ bucket_bounds_ss[0][0] = bucket_bounds->xmax;
+ bucket_bounds_ss[0][1] = bucket_bounds->ymin;
+ inside_face_flag |= (IsectPT2Df_limit(bucket_bounds_ss[0], v1coSS, v2coSS, v3coSS, 1 + PROJ_GEOM_TOLERANCE) ? ISECT_1 : 0);
+
+ bucket_bounds_ss[1][0] = bucket_bounds->xmax;
+ bucket_bounds_ss[1][1] = bucket_bounds->ymax;
+ inside_face_flag |= (IsectPT2Df_limit(bucket_bounds_ss[1], v1coSS, v2coSS, v3coSS, 1 + PROJ_GEOM_TOLERANCE) ? ISECT_2 : 0);
+
+ bucket_bounds_ss[2][0] = bucket_bounds->xmin;
+ bucket_bounds_ss[2][1] = bucket_bounds->ymax;
+ inside_face_flag |= (IsectPT2Df_limit(bucket_bounds_ss[2], v1coSS, v2coSS, v3coSS, 1 + PROJ_GEOM_TOLERANCE) ? ISECT_3 : 0);
+
+ bucket_bounds_ss[3][0] = bucket_bounds->xmin;
+ bucket_bounds_ss[3][1] = bucket_bounds->ymin;
+ inside_face_flag |= (IsectPT2Df_limit(bucket_bounds_ss[3], v1coSS, v2coSS, v3coSS, 1 + PROJ_GEOM_TOLERANCE) ? ISECT_4 : 0);
+
+ if (inside_face_flag == ISECT_ALL4) {
+ /* bucket is totally inside the screenspace face, we can safely use weights */
+
+ if (is_ortho) rect_to_uvspace_ortho(bucket_bounds, v1coSS, v2coSS, v3coSS, uv1co, uv2co, uv3co, bucket_bounds_uv, flip);
+ else rect_to_uvspace_persp(bucket_bounds, v1coSS, v2coSS, v3coSS, uv1co, uv2co, uv3co, bucket_bounds_uv, flip);
+
+ *tot = 4;
+ return;
+ }
+ else {
+ /* The Complicated Case!
+ *
+ * The 2 cases above are where the face is inside the bucket or the bucket is inside the face.
+ *
+ * we need to make a convex polyline from the intersection between the screenspace face
+ * and the bucket bounds.
+ *
+ * There are a number of ways this could be done, currently it just collects all intersecting verts,
+ * and line intersections, then sorts them clockwise, this is a lot easier then evaluating the geometry to
+ * do a correct clipping on both shapes. */
+
+
+ /* add a bunch of points, we know must make up the convex hull which is the clipped rect and triangle */
+
+
+
+ /* Maximum possible 6 intersections when using a rectangle and triangle */
+ float isectVCosSS[8][3]; /* The 3rd float is used to store angle for qsort(), NOT as a Z location */
+ float v1_clipSS[2], v2_clipSS[2];
+ float w[3];
+
+ /* calc center */
+ float cent[2] = {0.0f, 0.0f};
+ /*float up[2] = {0.0f, 1.0f};*/
+ int i;
+ short doubles;
+
+ (*tot) = 0;
+
+ if (inside_face_flag & ISECT_1) { copy_v2_v2(isectVCosSS[*tot], bucket_bounds_ss[0]); (*tot)++; }
+ if (inside_face_flag & ISECT_2) { copy_v2_v2(isectVCosSS[*tot], bucket_bounds_ss[1]); (*tot)++; }
+ if (inside_face_flag & ISECT_3) { copy_v2_v2(isectVCosSS[*tot], bucket_bounds_ss[2]); (*tot)++; }
+ if (inside_face_flag & ISECT_4) { copy_v2_v2(isectVCosSS[*tot], bucket_bounds_ss[3]); (*tot)++; }
+
+ if (inside_bucket_flag & ISECT_1) { copy_v2_v2(isectVCosSS[*tot], v1coSS); (*tot)++; }
+ if (inside_bucket_flag & ISECT_2) { copy_v2_v2(isectVCosSS[*tot], v2coSS); (*tot)++; }
+ if (inside_bucket_flag & ISECT_3) { copy_v2_v2(isectVCosSS[*tot], v3coSS); (*tot)++; }
+
+ if ((inside_bucket_flag & (ISECT_1 | ISECT_2)) != (ISECT_1 | ISECT_2)) {
+ if (line_clip_rect2f(bucket_bounds, v1coSS, v2coSS, v1_clipSS, v2_clipSS)) {
+ if ((inside_bucket_flag & ISECT_1) == 0) { copy_v2_v2(isectVCosSS[*tot], v1_clipSS); (*tot)++; }
+ if ((inside_bucket_flag & ISECT_2) == 0) { copy_v2_v2(isectVCosSS[*tot], v2_clipSS); (*tot)++; }
+ }
+ }
+
+ if ((inside_bucket_flag & (ISECT_2 | ISECT_3)) != (ISECT_2 | ISECT_3)) {
+ if (line_clip_rect2f(bucket_bounds, v2coSS, v3coSS, v1_clipSS, v2_clipSS)) {
+ if ((inside_bucket_flag & ISECT_2) == 0) { copy_v2_v2(isectVCosSS[*tot], v1_clipSS); (*tot)++; }
+ if ((inside_bucket_flag & ISECT_3) == 0) { copy_v2_v2(isectVCosSS[*tot], v2_clipSS); (*tot)++; }
+ }
+ }
+
+ if ((inside_bucket_flag & (ISECT_3 | ISECT_1)) != (ISECT_3 | ISECT_1)) {
+ if (line_clip_rect2f(bucket_bounds, v3coSS, v1coSS, v1_clipSS, v2_clipSS)) {
+ if ((inside_bucket_flag & ISECT_3) == 0) { copy_v2_v2(isectVCosSS[*tot], v1_clipSS); (*tot)++; }
+ if ((inside_bucket_flag & ISECT_1) == 0) { copy_v2_v2(isectVCosSS[*tot], v2_clipSS); (*tot)++; }
+ }
+ }
+
+
+ if ((*tot) < 3) { /* no intersections to speak of */
+ *tot = 0;
+ return;
+ }
+
+ /* now we have all points we need, collect their angles and sort them clockwise */
+
+ for (i = 0; i < (*tot); i++) {
+ cent[0] += isectVCosSS[i][0];
+ cent[1] += isectVCosSS[i][1];
+ }
+ cent[0] = cent[0] / (float)(*tot);
+ cent[1] = cent[1] / (float)(*tot);
+
+
+
+ /* Collect angles for every point around the center point */
+
+
+#if 0 /* uses a few more cycles then the above loop */
+ for (i = 0; i < (*tot); i++) {
+ isectVCosSS[i][2] = angle_2d_clockwise(up, cent, isectVCosSS[i]);
+ }
+#endif
+
+ v1_clipSS[0] = cent[0]; /* Abuse this var for the loop below */
+ v1_clipSS[1] = cent[1] + 1.0f;
+
+ for (i = 0; i < (*tot); i++) {
+ v2_clipSS[0] = isectVCosSS[i][0] - cent[0];
+ v2_clipSS[1] = isectVCosSS[i][1] - cent[1];
+ isectVCosSS[i][2] = atan2f(v1_clipSS[0] * v2_clipSS[1] - v1_clipSS[1] * v2_clipSS[0], v1_clipSS[0] * v2_clipSS[0] + v1_clipSS[1] * v2_clipSS[1]);
+ }
+
+ if (flip) qsort(isectVCosSS, *tot, sizeof(float) * 3, float_z_sort_flip);
+ else qsort(isectVCosSS, *tot, sizeof(float) * 3, float_z_sort);
+
+ /* remove doubles */
+ /* first/last check */
+ if (fabsf(isectVCosSS[0][0] - isectVCosSS[(*tot) - 1][0]) < PROJ_GEOM_TOLERANCE &&
+ fabsf(isectVCosSS[0][1] - isectVCosSS[(*tot) - 1][1]) < PROJ_GEOM_TOLERANCE)
+ {
+ (*tot)--;
+ }
+
+ /* its possible there is only a few left after remove doubles */
+ if ((*tot) < 3) {
+ // printf("removed too many doubles A\n");
+ *tot = 0;
+ return;
+ }
+
+ doubles = TRUE;
+ while (doubles == TRUE) {
+ doubles = FALSE;
+ for (i = 1; i < (*tot); i++) {
+ if (fabsf(isectVCosSS[i - 1][0] - isectVCosSS[i][0]) < PROJ_GEOM_TOLERANCE &&
+ fabsf(isectVCosSS[i - 1][1] - isectVCosSS[i][1]) < PROJ_GEOM_TOLERANCE)
+ {
+ int j;
+ for (j = i + 1; j < (*tot); j++) {
+ isectVCosSS[j - 1][0] = isectVCosSS[j][0];
+ isectVCosSS[j - 1][1] = isectVCosSS[j][1];
+ }
+ doubles = TRUE; /* keep looking for more doubles */
+ (*tot)--;
+ }
+ }
+ }
+
+ /* its possible there is only a few left after remove doubles */
+ if ((*tot) < 3) {
+ // printf("removed too many doubles B\n");
+ *tot = 0;
+ return;
+ }
+
+
+ if (is_ortho) {
+ for (i = 0; i < (*tot); i++) {
+ barycentric_weights_v2(v1coSS, v2coSS, v3coSS, isectVCosSS[i], w);
+ interp_v2_v2v2v2(bucket_bounds_uv[i], uv1co, uv2co, uv3co, w);
+ }
+ }
+ else {
+ for (i = 0; i < (*tot); i++) {
+ barycentric_weights_v2_persp(v1coSS, v2coSS, v3coSS, isectVCosSS[i], w);
+ interp_v2_v2v2v2(bucket_bounds_uv[i], uv1co, uv2co, uv3co, w);
+ }
+ }
+ }
+
+#ifdef PROJ_DEBUG_PRINT_CLIP
+ /* include this at the bottom of the above function to debug the output */
+
+ {
+ /* If there are ever any problems, */
+ float test_uv[4][2];
+ int i;
+ if (is_ortho) rect_to_uvspace_ortho(bucket_bounds, v1coSS, v2coSS, v3coSS, uv1co, uv2co, uv3co, test_uv, flip);
+ else rect_to_uvspace_persp(bucket_bounds, v1coSS, v2coSS, v3coSS, uv1co, uv2co, uv3co, test_uv, flip);
+ printf("( [(%f,%f), (%f,%f), (%f,%f), (%f,%f)], ", test_uv[0][0], test_uv[0][1], test_uv[1][0], test_uv[1][1], test_uv[2][0], test_uv[2][1], test_uv[3][0], test_uv[3][1]);
+
+ printf(" [(%f,%f), (%f,%f), (%f,%f)], ", uv1co[0], uv1co[1], uv2co[0], uv2co[1], uv3co[0], uv3co[1]);
+
+ printf("[");
+ for (i = 0; i < (*tot); i++) {
+ printf("(%f, %f),", bucket_bounds_uv[i][0], bucket_bounds_uv[i][1]);
+ }
+ printf("]),\\\n");
+ }
+#endif
+}
+
+/*
+ * # This script creates faces in a blender scene from printed data above.
+ *
+ * project_ls = [
+ * ...(output from above block)...
+ * ]
+ *
+ * from Blender import Scene, Mesh, Window, sys, Mathutils
+ *
+ * import bpy
+ *
+ * V = Mathutils.Vector
+ *
+ * def main():
+ * sce = bpy.data.scenes.active
+ *
+ * for item in project_ls:
+ * bb = item[0]
+ * uv = item[1]
+ * poly = item[2]
+ *
+ * me = bpy.data.meshes.new()
+ * ob = sce.objects.new(me)
+ *
+ * me.verts.extend([V(bb[0]).xyz, V(bb[1]).xyz, V(bb[2]).xyz, V(bb[3]).xyz])
+ * me.faces.extend([(0,1,2,3),])
+ * me.verts.extend([V(uv[0]).xyz, V(uv[1]).xyz, V(uv[2]).xyz])
+ * me.faces.extend([(4,5,6),])
+ *
+ * vs = [V(p).xyz for p in poly]
+ * print len(vs)
+ * l = len(me.verts)
+ * me.verts.extend(vs)
+ *
+ * i = l
+ * while i < len(me.verts):
+ * ii = i + 1
+ * if ii == len(me.verts):
+ * ii = l
+ * me.edges.extend([i, ii])
+ * i += 1
+ *
+ * if __name__ == '__main__':
+ * main()
+ */
+
+
+#undef ISECT_1
+#undef ISECT_2
+#undef ISECT_3
+#undef ISECT_4
+#undef ISECT_ALL3
+#undef ISECT_ALL4
+
+
+/* checks if pt is inside a convex 2D polyline, the polyline must be ordered rotating clockwise
+ * otherwise it would have to test for mixed (line_point_side_v2 > 0.0f) cases */
+static int IsectPoly2Df(const float pt[2], float uv[][2], const int tot)
+{
+ int i;
+ if (line_point_side_v2(uv[tot - 1], uv[0], pt) < 0.0f)
+ return 0;
+
+ for (i = 1; i < tot; i++) {
+ if (line_point_side_v2(uv[i - 1], uv[i], pt) < 0.0f)
+ return 0;
+
+ }
+
+ return 1;
+}
+static int IsectPoly2Df_twoside(const float pt[2], float uv[][2], const int tot)
+{
+ int i;
+ int side = (line_point_side_v2(uv[tot - 1], uv[0], pt) > 0.0f);
+
+ for (i = 1; i < tot; i++) {
+ if ((line_point_side_v2(uv[i - 1], uv[i], pt) > 0.0f) != side)
+ return 0;
+
+ }
+
+ return 1;
+}
+
+/* One of the most important function for projection painting, since it selects the pixels to be added into each bucket.
+ * initialize pixels from this face where it intersects with the bucket_index, optionally initialize pixels for removing seams */
+static void project_paint_face_init(const ProjPaintState *ps, const int thread_index, const int bucket_index, const int face_index, const int image_index, rctf *bucket_bounds, const ImBuf *ibuf, const short clamp_u, const short clamp_v)
+{
+ /* Projection vars, to get the 3D locations into screen space */
+ MemArena *arena = ps->arena_mt[thread_index];
+ LinkNode **bucketPixelNodes = ps->bucketRect + bucket_index;
+ LinkNode *bucketFaceNodes = ps->bucketFaces[bucket_index];
+
+ const MFace *mf = ps->dm_mface + face_index;
+ const MTFace *tf = ps->dm_mtface + face_index;
+
+ /* UV/pixel seeking data */
+ int x; /* Image X-Pixel */
+ int y; /* Image Y-Pixel */
+ float mask;
+ float uv[2]; /* Image floating point UV - same as x, y but from 0.0-1.0 */
+
+ int side;
+ float *v1coSS, *v2coSS, *v3coSS; /* vert co screen-space, these will be assigned to mf->v1,2,3 or mf->v1,3,4 */
+
+ float *vCo[4]; /* vertex screenspace coords */
+
+ float w[3], wco[3];
+
+ float *uv1co, *uv2co, *uv3co; /* for convenience only, these will be assigned to tf->uv[0],1,2 or tf->uv[0],2,3 */
+ float pixelScreenCo[4];
+ bool do_3d_mapping = ps->brush->mtex.brush_map_mode == MTEX_MAP_MODE_3D;
+
+ rcti bounds_px; /* ispace bounds */
+ /* vars for getting uvspace bounds */
+
+ float tf_uv_pxoffset[4][2]; /* bucket bounds in UV space so we can init pixels only for this face, */
+ float xhalfpx, yhalfpx;
+ const float ibuf_xf = (float)ibuf->x, ibuf_yf = (float)ibuf->y;
+
+ int has_x_isect = 0, has_isect = 0; /* for early loop exit */
+
+ int i1, i2, i3;
+
+ float uv_clip[8][2];
+ int uv_clip_tot;
+ const short is_ortho = ps->is_ortho;
+ const short do_backfacecull = ps->do_backfacecull;
+ const short do_clip = ps->rv3d ? ps->rv3d->rflag & RV3D_CLIPPING : 0;
+
+ vCo[0] = ps->dm_mvert[mf->v1].co;
+ vCo[1] = ps->dm_mvert[mf->v2].co;
+ vCo[2] = ps->dm_mvert[mf->v3].co;
+
+
+ /* Use tf_uv_pxoffset instead of tf->uv so we can offset the UV half a pixel
+ * this is done so we can avoid offsetting all the pixels by 0.5 which causes
+ * problems when wrapping negative coords */
+ xhalfpx = (0.5f + (PROJ_GEOM_TOLERANCE / 3.0f)) / ibuf_xf;
+ yhalfpx = (0.5f + (PROJ_GEOM_TOLERANCE / 4.0f)) / ibuf_yf;
+
+ /* Note about (PROJ_GEOM_TOLERANCE/x) above...
+ * Needed to add this offset since UV coords are often quads aligned to pixels.
+ * In this case pixels can be exactly between 2 triangles causing nasty
+ * artifacts.
+ *
+ * This workaround can be removed and painting will still work on most cases
+ * but since the first thing most people try is painting onto a quad- better make it work.
+ */
+
+
+
+ tf_uv_pxoffset[0][0] = tf->uv[0][0] - xhalfpx;
+ tf_uv_pxoffset[0][1] = tf->uv[0][1] - yhalfpx;
+
+ tf_uv_pxoffset[1][0] = tf->uv[1][0] - xhalfpx;
+ tf_uv_pxoffset[1][1] = tf->uv[1][1] - yhalfpx;
+
+ tf_uv_pxoffset[2][0] = tf->uv[2][0] - xhalfpx;
+ tf_uv_pxoffset[2][1] = tf->uv[2][1] - yhalfpx;
+
+ if (mf->v4) {
+ vCo[3] = ps->dm_mvert[mf->v4].co;
+
+ tf_uv_pxoffset[3][0] = tf->uv[3][0] - xhalfpx;
+ tf_uv_pxoffset[3][1] = tf->uv[3][1] - yhalfpx;
+ side = 1;
+ }
+ else {
+ side = 0;
+ }
+
+ do {
+ if (side == 1) {
+ i1 = 0; i2 = 2; i3 = 3;
+ }
+ else {
+ i1 = 0; i2 = 1; i3 = 2;
+ }
+
+ uv1co = tf_uv_pxoffset[i1]; // was tf->uv[i1];
+ uv2co = tf_uv_pxoffset[i2]; // was tf->uv[i2];
+ uv3co = tf_uv_pxoffset[i3]; // was tf->uv[i3];
+
+ v1coSS = ps->screenCoords[(*(&mf->v1 + i1))];
+ v2coSS = ps->screenCoords[(*(&mf->v1 + i2))];
+ v3coSS = ps->screenCoords[(*(&mf->v1 + i3))];
+
+ /* This funtion gives is a concave polyline in UV space from the clipped quad and tri*/
+ project_bucket_clip_face(
+ is_ortho, bucket_bounds,
+ v1coSS, v2coSS, v3coSS,
+ uv1co, uv2co, uv3co,
+ uv_clip, &uv_clip_tot
+ );
+
+ /* sometimes this happens, better just allow for 8 intersectiosn even though there should be max 6 */
+#if 0
+ if (uv_clip_tot > 6) {
+ printf("this should never happen! %d\n", uv_clip_tot);
+ }
+#endif
+
+ if (pixel_bounds_array(uv_clip, &bounds_px, ibuf->x, ibuf->y, uv_clip_tot)) {
+
+ if (clamp_u) {
+ CLAMP(bounds_px.xmin, 0, ibuf->x);
+ CLAMP(bounds_px.xmax, 0, ibuf->x);
+ }
+
+ if (clamp_v) {
+ CLAMP(bounds_px.ymin, 0, ibuf->y);
+ CLAMP(bounds_px.ymax, 0, ibuf->y);
+ }
+
+ /* clip face and */
+
+ has_isect = 0;
+ for (y = bounds_px.ymin; y < bounds_px.ymax; y++) {
+ //uv[1] = (((float)y) + 0.5f) / (float)ibuf->y;
+ uv[1] = (float)y / ibuf_yf; /* use pixel offset UV coords instead */
+
+ has_x_isect = 0;
+ for (x = bounds_px.xmin; x < bounds_px.xmax; x++) {
+ //uv[0] = (((float)x) + 0.5f) / ibuf->x;
+ uv[0] = (float)x / ibuf_xf; /* use pixel offset UV coords instead */
+
+ /* Note about IsectPoly2Df_twoside, checking the face or uv flipping doesnt work,
+ * could check the poly direction but better to do this */
+ if ((do_backfacecull == TRUE && IsectPoly2Df(uv, uv_clip, uv_clip_tot)) ||
+ (do_backfacecull == FALSE && IsectPoly2Df_twoside(uv, uv_clip, uv_clip_tot)))
+ {
+
+ has_x_isect = has_isect = 1;
+
+ if (is_ortho) screen_px_from_ortho(uv, v1coSS, v2coSS, v3coSS, uv1co, uv2co, uv3co, pixelScreenCo, w);
+ else screen_px_from_persp(uv, v1coSS, v2coSS, v3coSS, uv1co, uv2co, uv3co, pixelScreenCo, w);
+
+ /* a pity we need to get the worldspace pixel location here */
+ if (do_clip || do_3d_mapping) {
+ interp_v3_v3v3v3(wco, ps->dm_mvert[(*(&mf->v1 + i1))].co, ps->dm_mvert[(*(&mf->v1 + i2))].co, ps->dm_mvert[(*(&mf->v1 + i3))].co, w);
+ if (do_clip && ED_view3d_clipping_test(ps->rv3d, wco, TRUE)) {
+ continue; /* Watch out that no code below this needs to run */
+ }
+ }
+
+ /* Is this UV visible from the view? - raytrace */
+ /* project_paint_PickFace is less complex, use for testing */
+ //if (project_paint_PickFace(ps, pixelScreenCo, w, &side) == face_index) {
+ if ((ps->do_occlude == FALSE) ||
+ !project_bucket_point_occluded(ps, bucketFaceNodes, face_index, pixelScreenCo))
+ {
+ mask = project_paint_uvpixel_mask(ps, face_index, side, w);
+
+ if (mask > 0.0f) {
+ BLI_linklist_prepend_arena(
+ bucketPixelNodes,
+ project_paint_uvpixel_init(ps, arena, ibuf, x, y, mask, face_index,
+ image_index, pixelScreenCo, wco, side, w),
+ arena
+ );
+ }
+ }
+
+ }
+//#if 0
+ else if (has_x_isect) {
+ /* assuming the face is not a bow-tie - we know we cant intersect again on the X */
+ break;
+ }
+//#endif
+ }
+
+
+#if 0 /* TODO - investigate why this dosnt work sometimes! it should! */
+ /* no intersection for this entire row, after some intersection above means we can quit now */
+ if (has_x_isect == 0 && has_isect) {
+ break;
+ }
+#endif
+ }
+ }
+ } while (side--);
+
+
+
+#ifndef PROJ_DEBUG_NOSEAMBLEED
+ if (ps->seam_bleed_px > 0.0f) {
+ int face_seam_flag;
+
+ if (ps->thread_tot > 1)
+ BLI_lock_thread(LOCK_CUSTOM1); /* Other threads could be modifying these vars */
+
+ face_seam_flag = ps->faceSeamFlags[face_index];
+
+ /* are any of our edges un-initialized? */
+ if ((face_seam_flag & (PROJ_FACE_SEAM1 | PROJ_FACE_NOSEAM1)) == 0 ||
+ (face_seam_flag & (PROJ_FACE_SEAM2 | PROJ_FACE_NOSEAM2)) == 0 ||
+ (face_seam_flag & (PROJ_FACE_SEAM3 | PROJ_FACE_NOSEAM3)) == 0 ||
+ (face_seam_flag & (PROJ_FACE_SEAM4 | PROJ_FACE_NOSEAM4)) == 0)
+ {
+ project_face_seams_init(ps, face_index, mf->v4);
+ face_seam_flag = ps->faceSeamFlags[face_index];
+ //printf("seams - %d %d %d %d\n", flag&PROJ_FACE_SEAM1, flag&PROJ_FACE_SEAM2, flag&PROJ_FACE_SEAM3, flag&PROJ_FACE_SEAM4);
+ }
+
+ if ((face_seam_flag & (PROJ_FACE_SEAM1 | PROJ_FACE_SEAM2 | PROJ_FACE_SEAM3 | PROJ_FACE_SEAM4)) == 0) {
+
+ if (ps->thread_tot > 1)
+ BLI_unlock_thread(LOCK_CUSTOM1); /* Other threads could be modifying these vars */
+
+ }
+ else {
+ /* we have a seam - deal with it! */
+
+ /* Now create new UV's for the seam face */
+ float (*outset_uv)[2] = ps->faceSeamUVs[face_index];
+ float insetCos[4][3]; /* inset face coords. NOTE!!! ScreenSace for ortho, Worldspace in prespective view */
+
+ float *vCoSS[4]; /* vertex screenspace coords */
+
+ float bucket_clip_edges[2][2]; /* store the screenspace coords of the face, clipped by the bucket's screen aligned rectangle */
+ float edge_verts_inset_clip[2][3];
+ int fidx1, fidx2; /* face edge pairs - loop throuh these ((0,1), (1,2), (2,3), (3,0)) or ((0,1), (1,2), (2,0)) for a tri */
+
+ float seam_subsection[4][2];
+ float fac1, fac2, ftot;
+
+
+ if (outset_uv[0][0] == FLT_MAX) /* first time initialize */
+ uv_image_outset(tf_uv_pxoffset, outset_uv, ps->seam_bleed_px, ibuf->x, ibuf->y, mf->v4);
+
+ /* ps->faceSeamUVs cant be modified when threading, now this is done we can unlock */
+ if (ps->thread_tot > 1)
+ BLI_unlock_thread(LOCK_CUSTOM1); /* Other threads could be modifying these vars */
+
+ vCoSS[0] = ps->screenCoords[mf->v1];
+ vCoSS[1] = ps->screenCoords[mf->v2];
+ vCoSS[2] = ps->screenCoords[mf->v3];
+ if (mf->v4)
+ vCoSS[3] = ps->screenCoords[mf->v4];
+
+ /* PROJ_FACE_SCALE_SEAM must be slightly less then 1.0f */
+ if (is_ortho) {
+ if (mf->v4) scale_quad(insetCos, vCoSS, PROJ_FACE_SCALE_SEAM);
+ else scale_tri(insetCos, vCoSS, PROJ_FACE_SCALE_SEAM);
+ }
+ else {
+ if (mf->v4) scale_quad(insetCos, vCo, PROJ_FACE_SCALE_SEAM);
+ else scale_tri(insetCos, vCo, PROJ_FACE_SCALE_SEAM);
+ }
+
+ side = 0; /* for triangles this wont need to change */
+
+ for (fidx1 = 0; fidx1 < (mf->v4 ? 4 : 3); fidx1++) {
+ if (mf->v4) fidx2 = (fidx1 == 3) ? 0 : fidx1 + 1; /* next fidx in the face (0,1,2,3) -> (1,2,3,0) */
+ else fidx2 = (fidx1 == 2) ? 0 : fidx1 + 1; /* next fidx in the face (0,1,2) -> (1,2,0) */
+
+ if ((face_seam_flag & (1 << fidx1)) && /* 1<<fidx1 -> PROJ_FACE_SEAM# */
+ line_clip_rect2f(bucket_bounds, vCoSS[fidx1], vCoSS[fidx2], bucket_clip_edges[0], bucket_clip_edges[1]))
+ {
+
+ ftot = len_v2v2(vCoSS[fidx1], vCoSS[fidx2]); /* screenspace edge length */
+
+ if (ftot > 0.0f) { /* avoid div by zero */
+ if (mf->v4) {
+ if (fidx1 == 2 || fidx2 == 2) side = 1;
+ else side = 0;
+ }
+
+ fac1 = len_v2v2(vCoSS[fidx1], bucket_clip_edges[0]) / ftot;
+ fac2 = len_v2v2(vCoSS[fidx1], bucket_clip_edges[1]) / ftot;
+
+ interp_v2_v2v2(seam_subsection[0], tf_uv_pxoffset[fidx1], tf_uv_pxoffset[fidx2], fac1);
+ interp_v2_v2v2(seam_subsection[1], tf_uv_pxoffset[fidx1], tf_uv_pxoffset[fidx2], fac2);
+
+ interp_v2_v2v2(seam_subsection[2], outset_uv[fidx1], outset_uv[fidx2], fac2);
+ interp_v2_v2v2(seam_subsection[3], outset_uv[fidx1], outset_uv[fidx2], fac1);
+
+ /* if the bucket_clip_edges values Z values was kept we could avoid this
+ * Inset needs to be added so occlusion tests wont hit adjacent faces */
+ interp_v3_v3v3(edge_verts_inset_clip[0], insetCos[fidx1], insetCos[fidx2], fac1);
+ interp_v3_v3v3(edge_verts_inset_clip[1], insetCos[fidx1], insetCos[fidx2], fac2);
+
+
+ if (pixel_bounds_uv(seam_subsection[0], seam_subsection[1], seam_subsection[2], seam_subsection[3], &bounds_px, ibuf->x, ibuf->y, 1)) {
+ /* bounds between the seam rect and the uvspace bucket pixels */
+
+ has_isect = 0;
+ for (y = bounds_px.ymin; y < bounds_px.ymax; y++) {
+ // uv[1] = (((float)y) + 0.5f) / (float)ibuf->y;
+ uv[1] = (float)y / ibuf_yf; /* use offset uvs instead */
+
+ has_x_isect = 0;
+ for (x = bounds_px.xmin; x < bounds_px.xmax; x++) {
+ //uv[0] = (((float)x) + 0.5f) / (float)ibuf->x;
+ uv[0] = (float)x / ibuf_xf; /* use offset uvs instead */
+
+ /* test we're inside uvspace bucket and triangle bounds */
+ if (isect_point_quad_v2(uv, seam_subsection[0], seam_subsection[1], seam_subsection[2], seam_subsection[3])) {
+ float fac;
+
+ /* We need to find the closest point along the face edge,
+ * getting the screen_px_from_*** wont work because our actual location
+ * is not relevant, since we are outside the face, Use VecLerpf to find
+ * our location on the side of the face's UV */
+#if 0
+ if (is_ortho) screen_px_from_ortho(ps, uv, v1co, v2co, v3co, uv1co, uv2co, uv3co, pixelScreenCo);
+ else screen_px_from_persp(ps, uv, v1co, v2co, v3co, uv1co, uv2co, uv3co, pixelScreenCo);
+#endif
+
+ /* Since this is a seam we need to work out where on the line this pixel is */
+ //fac = line_point_factor_v2(uv, uv_seam_quad[0], uv_seam_quad[1]);
+
+ fac = line_point_factor_v2(uv, seam_subsection[0], seam_subsection[1]);
+ if (fac < 0.0f) { copy_v3_v3(pixelScreenCo, edge_verts_inset_clip[0]); }
+ else if (fac > 1.0f) { copy_v3_v3(pixelScreenCo, edge_verts_inset_clip[1]); }
+ else { interp_v3_v3v3(pixelScreenCo, edge_verts_inset_clip[0], edge_verts_inset_clip[1], fac); }
+
+ if (!is_ortho) {
+ pixelScreenCo[3] = 1.0f;
+ mul_m4_v4((float(*)[4])ps->projectMat, pixelScreenCo); /* cast because of const */
+ pixelScreenCo[0] = (float)(ps->winx / 2.0f) + (ps->winx / 2.0f) * pixelScreenCo[0] / pixelScreenCo[3];
+ pixelScreenCo[1] = (float)(ps->winy / 2.0f) + (ps->winy / 2.0f) * pixelScreenCo[1] / pixelScreenCo[3];
+ pixelScreenCo[2] = pixelScreenCo[2] / pixelScreenCo[3]; /* Use the depth for bucket point occlusion */
+ }
+
+ if ((ps->do_occlude == FALSE) ||
+ !project_bucket_point_occluded(ps, bucketFaceNodes, face_index, pixelScreenCo))
+ {
+ /* Only bother calculating the weights if we intersect */
+ if (ps->do_mask_normal || ps->dm_mtface_clone) {
+#if 1
+ /* get the UV on the line since we want to copy the pixels from there for bleeding */
+ float uv_close[2];
+ float uv_fac = closest_to_line_v2(uv_close, uv, tf_uv_pxoffset[fidx1], tf_uv_pxoffset[fidx2]);
+ if (uv_fac < 0.0f) copy_v2_v2(uv_close, tf_uv_pxoffset[fidx1]);
+ else if (uv_fac > 1.0f) copy_v2_v2(uv_close, tf_uv_pxoffset[fidx2]);
+
+ if (side) {
+ barycentric_weights_v2(tf_uv_pxoffset[0], tf_uv_pxoffset[2], tf_uv_pxoffset[3], uv_close, w);
+ }
+ else {
+ barycentric_weights_v2(tf_uv_pxoffset[0], tf_uv_pxoffset[1], tf_uv_pxoffset[2], uv_close, w);
+ }
+#else /* this is buggy with quads, don't use for now */
+
+ /* Cheat, we know where we are along the edge so work out the weights from that */
+ uv_fac = fac1 + (uv_fac * (fac2 - fac1));
+
+ w[0] = w[1] = w[2] = 0.0;
+ if (side) {
+ w[fidx1 ? fidx1 - 1 : 0] = 1.0f - uv_fac;
+ w[fidx2 ? fidx2 - 1 : 0] = uv_fac;
+ }
+ else {
+ w[fidx1] = 1.0f - uv_fac;
+ w[fidx2] = uv_fac;
+ }
+#endif
+ }
+
+ /* a pity we need to get the worldspace pixel location here */
+ if (do_clip || do_3d_mapping) {
+ if (side) interp_v3_v3v3v3(wco, ps->dm_mvert[mf->v1].co, ps->dm_mvert[mf->v3].co, ps->dm_mvert[mf->v4].co, w);
+ else interp_v3_v3v3v3(wco, ps->dm_mvert[mf->v1].co, ps->dm_mvert[mf->v2].co, ps->dm_mvert[mf->v3].co, w);
+
+ if (do_clip && ED_view3d_clipping_test(ps->rv3d, wco, TRUE)) {
+ continue; /* Watch out that no code below this needs to run */
+ }
+ }
+
+ mask = project_paint_uvpixel_mask(ps, face_index, side, w);
+
+ if (mask > 0.0f) {
+ BLI_linklist_prepend_arena(
+ bucketPixelNodes,
+ project_paint_uvpixel_init(ps, arena, ibuf, x, y, mask, face_index, image_index, pixelScreenCo, wco, side, w),
+ arena
+ );
+ }
+
+ }
+ }
+ else if (has_x_isect) {
+ /* assuming the face is not a bow-tie - we know we cant intersect again on the X */
+ break;
+ }
+ }
+
+#if 0 /* TODO - investigate why this dosnt work sometimes! it should! */
+ /* no intersection for this entire row, after some intersection above means we can quit now */
+ if (has_x_isect == 0 && has_isect) {
+ break;
+ }
+#endif
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+#endif // PROJ_DEBUG_NOSEAMBLEED
+}
+
+
+/* takes floating point screenspace min/max and returns int min/max to be used as indices for ps->bucketRect, ps->bucketFlags */
+static void project_paint_bucket_bounds(const ProjPaintState *ps, const float min[2], const float max[2], int bucketMin[2], int bucketMax[2])
+{
+ /* divide by bucketWidth & bucketHeight so the bounds are offset in bucket grid units */
+ /* XXX: the offset of 0.5 is always truncated to zero and the offset of 1.5f is always truncated to 1, is this really correct?? - jwilkins */
+ bucketMin[0] = (int)((int)(((float)(min[0] - ps->screenMin[0]) / ps->screen_width) * ps->buckets_x) + 0.5f); /* these offsets of 0.5 and 1.5 seem odd but they are correct */
+ bucketMin[1] = (int)((int)(((float)(min[1] - ps->screenMin[1]) / ps->screen_height) * ps->buckets_y) + 0.5f);
+
+ bucketMax[0] = (int)((int)(((float)(max[0] - ps->screenMin[0]) / ps->screen_width) * ps->buckets_x) + 1.5f);
+ bucketMax[1] = (int)((int)(((float)(max[1] - ps->screenMin[1]) / ps->screen_height) * ps->buckets_y) + 1.5f);
+
+ /* in case the rect is outside the mesh 2d bounds */
+ CLAMP(bucketMin[0], 0, ps->buckets_x);
+ CLAMP(bucketMin[1], 0, ps->buckets_y);
+
+ CLAMP(bucketMax[0], 0, ps->buckets_x);
+ CLAMP(bucketMax[1], 0, ps->buckets_y);
+}
+
+/* set bucket_bounds to a screen space-aligned floating point bound-box */
+static void project_bucket_bounds(const ProjPaintState *ps, const int bucket_x, const int bucket_y, rctf *bucket_bounds)
+{
+ bucket_bounds->xmin = ps->screenMin[0] + ((bucket_x) * (ps->screen_width / ps->buckets_x)); /* left */
+ bucket_bounds->xmax = ps->screenMin[0] + ((bucket_x + 1) * (ps->screen_width / ps->buckets_x)); /* right */
+
+ bucket_bounds->ymin = ps->screenMin[1] + ((bucket_y) * (ps->screen_height / ps->buckets_y)); /* bottom */
+ bucket_bounds->ymax = ps->screenMin[1] + ((bucket_y + 1) * (ps->screen_height / ps->buckets_y)); /* top */
+}
+
+/* Fill this bucket with pixels from the faces that intersect it.
+ *
+ * have bucket_bounds as an argument so we don't need to give bucket_x/y the rect function needs */
+static void project_bucket_init(const ProjPaintState *ps, const int thread_index, const int bucket_index, rctf *bucket_bounds)
+{
+ LinkNode *node;
+ int face_index, image_index = 0;
+ ImBuf *ibuf = NULL;
+ Image *tpage_last = NULL, *tpage;
+ Image *ima = NULL;
+
+ if (ps->image_tot == 1) {
+ /* Simple loop, no context switching */
+ ibuf = ps->projImages[0].ibuf;
+ ima = ps->projImages[0].ima;
+
+ for (node = ps->bucketFaces[bucket_index]; node; node = node->next) {
+ project_paint_face_init(ps, thread_index, bucket_index, GET_INT_FROM_POINTER(node->link), 0, bucket_bounds, ibuf, ima->tpageflag & IMA_CLAMP_U, ima->tpageflag & IMA_CLAMP_V);
+ }
+ }
+ else {
+
+ /* More complicated loop, switch between images */
+ for (node = ps->bucketFaces[bucket_index]; node; node = node->next) {
+ face_index = GET_INT_FROM_POINTER(node->link);
+
+ /* Image context switching */
+ tpage = project_paint_face_image(ps, ps->dm_mtface, face_index);
+ if (tpage_last != tpage) {
+ tpage_last = tpage;
+
+ for (image_index = 0; image_index < ps->image_tot; image_index++) {
+ if (ps->projImages[image_index].ima == tpage_last) {
+ ibuf = ps->projImages[image_index].ibuf;
+ ima = ps->projImages[image_index].ima;
+ break;
+ }
+ }
+ }
+ /* context switching done */
+
+ project_paint_face_init(ps, thread_index, bucket_index, face_index, image_index, bucket_bounds, ibuf, ima->tpageflag & IMA_CLAMP_U, ima->tpageflag & IMA_CLAMP_V);
+ }
+ }
+
+ ps->bucketFlags[bucket_index] |= PROJ_BUCKET_INIT;
+}
+
+
+/* We want to know if a bucket and a face overlap in screen-space
+ *
+ * Note, if this ever returns false positives its not that bad, since a face in the bounding area will have its pixels
+ * calculated when it might not be needed later, (at the moment at least)
+ * obviously it shouldn't have bugs though */
+
+static int project_bucket_face_isect(ProjPaintState *ps, int bucket_x, int bucket_y, const MFace *mf)
+{
+ /* TODO - replace this with a tricker method that uses sideofline for all screenCoords's edges against the closest bucket corner */
+ rctf bucket_bounds;
+ float p1[2], p2[2], p3[2], p4[2];
+ float *v, *v1, *v2, *v3, *v4 = NULL;
+ int fidx;
+
+ project_bucket_bounds(ps, bucket_x, bucket_y, &bucket_bounds);
+
+ /* Is one of the faces verts in the bucket bounds? */
+
+ fidx = mf->v4 ? 3 : 2;
+ do {
+ v = ps->screenCoords[(*(&mf->v1 + fidx))];
+ if (BLI_rctf_isect_pt_v(&bucket_bounds, v)) {
+ return 1;
+ }
+ } while (fidx--);
+
+ v1 = ps->screenCoords[mf->v1];
+ v2 = ps->screenCoords[mf->v2];
+ v3 = ps->screenCoords[mf->v3];
+ if (mf->v4) {
+ v4 = ps->screenCoords[mf->v4];
+ }
+
+ p1[0] = bucket_bounds.xmin; p1[1] = bucket_bounds.ymin;
+ p2[0] = bucket_bounds.xmin; p2[1] = bucket_bounds.ymax;
+ p3[0] = bucket_bounds.xmax; p3[1] = bucket_bounds.ymax;
+ p4[0] = bucket_bounds.xmax; p4[1] = bucket_bounds.ymin;
+
+ if (mf->v4) {
+ if (isect_point_quad_v2(p1, v1, v2, v3, v4) ||
+ isect_point_quad_v2(p2, v1, v2, v3, v4) ||
+ isect_point_quad_v2(p3, v1, v2, v3, v4) ||
+ isect_point_quad_v2(p4, v1, v2, v3, v4) ||
+
+ /* we can avoid testing v3,v1 because another intersection MUST exist if this intersects */
+ (isect_line_line_v2(p1, p2, v1, v2) || isect_line_line_v2(p1, p2, v2, v3) || isect_line_line_v2(p1, p2, v3, v4)) ||
+ (isect_line_line_v2(p2, p3, v1, v2) || isect_line_line_v2(p2, p3, v2, v3) || isect_line_line_v2(p2, p3, v3, v4)) ||
+ (isect_line_line_v2(p3, p4, v1, v2) || isect_line_line_v2(p3, p4, v2, v3) || isect_line_line_v2(p3, p4, v3, v4)) ||
+ (isect_line_line_v2(p4, p1, v1, v2) || isect_line_line_v2(p4, p1, v2, v3) || isect_line_line_v2(p4, p1, v3, v4)))
+ {
+ return 1;
+ }
+ }
+ else {
+ if (isect_point_tri_v2(p1, v1, v2, v3) ||
+ isect_point_tri_v2(p2, v1, v2, v3) ||
+ isect_point_tri_v2(p3, v1, v2, v3) ||
+ isect_point_tri_v2(p4, v1, v2, v3) ||
+ /* we can avoid testing v3,v1 because another intersection MUST exist if this intersects */
+ (isect_line_line_v2(p1, p2, v1, v2) || isect_line_line_v2(p1, p2, v2, v3)) ||
+ (isect_line_line_v2(p2, p3, v1, v2) || isect_line_line_v2(p2, p3, v2, v3)) ||
+ (isect_line_line_v2(p3, p4, v1, v2) || isect_line_line_v2(p3, p4, v2, v3)) ||
+ (isect_line_line_v2(p4, p1, v1, v2) || isect_line_line_v2(p4, p1, v2, v3)))
+ {
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+/* Add faces to the bucket but don't initialize its pixels
+ * TODO - when painting occluded, sort the faces on their min-Z and only add faces that faces that are not occluded */
+static void project_paint_delayed_face_init(ProjPaintState *ps, const MFace *mf, const int face_index)
+{
+ float min[2], max[2], *vCoSS;
+ int bucketMin[2], bucketMax[2]; /* for ps->bucketRect indexing */
+ int fidx, bucket_x, bucket_y;
+ int has_x_isect = -1, has_isect = 0; /* for early loop exit */
+ MemArena *arena = ps->arena_mt[0]; /* just use the first thread arena since threading has not started yet */
+
+ INIT_MINMAX2(min, max);
+
+ fidx = mf->v4 ? 3 : 2;
+ do {
+ vCoSS = ps->screenCoords[*(&mf->v1 + fidx)];
+ minmax_v2v2_v2(min, max, vCoSS);
+ } while (fidx--);
+
+ project_paint_bucket_bounds(ps, min, max, bucketMin, bucketMax);
+
+ for (bucket_y = bucketMin[1]; bucket_y < bucketMax[1]; bucket_y++) {
+ has_x_isect = 0;
+ for (bucket_x = bucketMin[0]; bucket_x < bucketMax[0]; bucket_x++) {
+ if (project_bucket_face_isect(ps, bucket_x, bucket_y, mf)) {
+ int bucket_index = bucket_x + (bucket_y * ps->buckets_x);
+ BLI_linklist_prepend_arena(
+ &ps->bucketFaces[bucket_index],
+ SET_INT_IN_POINTER(face_index), /* cast to a pointer to shut up the compiler */
+ arena
+ );
+
+ has_x_isect = has_isect = 1;
+ }
+ else if (has_x_isect) {
+ /* assuming the face is not a bow-tie - we know we cant intersect again on the X */
+ break;
+ }
+ }
+
+ /* no intersection for this entire row, after some intersection above means we can quit now */
+ if (has_x_isect == 0 && has_isect) {
+ break;
+ }
+ }
+
+#ifndef PROJ_DEBUG_NOSEAMBLEED
+ if (ps->seam_bleed_px > 0.0f) {
+ if (!mf->v4) {
+ ps->faceSeamFlags[face_index] |= PROJ_FACE_NOSEAM4; /* so this wont show up as an untagged edge */
+ }
+ **ps->faceSeamUVs[face_index] = FLT_MAX; /* set as uninitialized */
+ }
+#endif
+}
+
+/* run once per stroke before projection painting */
+static void project_paint_begin(ProjPaintState *ps)
+{
+ /* Viewport vars */
+ float mat[3][3];
+
+ float no[3];
+
+ float *projScreenCo; /* Note, we could have 4D vectors are only needed for */
+ float projMargin;
+
+ /* Image Vars - keep track of images we have used */
+ LinkNode *image_LinkList = NULL;
+ LinkNode *node;
+
+ ProjPaintImage *projIma;
+ Image *tpage_last = NULL, *tpage;
+
+ /* Face vars */
+ MFace *mf;
+ MTFace *tf;
+
+ int a, i; /* generic looping vars */
+ int image_index = -1, face_index;
+ MVert *mv;
+
+ MemArena *arena; /* at the moment this is just ps->arena_mt[0], but use this to show were not multithreading */
+
+ const int diameter = 2 * BKE_brush_size_get(ps->scene, ps->brush);
+
+ /* ---- end defines ---- */
+
+ if (ps->source == PROJ_SRC_VIEW)
+ ED_view3d_clipping_local(ps->rv3d, ps->ob->obmat); /* faster clipping lookups */
+
+ /* paint onto the derived mesh */
+
+ /* Workaround for subsurf selection, try the display mesh first */
+ if (ps->source == PROJ_SRC_IMAGE_CAM) {
+ /* using render mesh, assume only camera was rendered from */
+ ps->dm = mesh_create_derived_render(ps->scene, ps->ob, ps->scene->customdata_mask | CD_MASK_MTFACE);
+ ps->dm_release = TRUE;
+ }
+ else if (ps->ob->derivedFinal && CustomData_has_layer(&ps->ob->derivedFinal->faceData, CD_MTFACE)) {
+ ps->dm = ps->ob->derivedFinal;
+ ps->dm_release = FALSE;
+ }
+ else {
+ ps->dm = mesh_get_derived_final(ps->scene, ps->ob, ps->scene->customdata_mask | CD_MASK_MTFACE);
+ ps->dm_release = TRUE;
+ }
+
+ if (!CustomData_has_layer(&ps->dm->faceData, CD_MTFACE) ) {
+
+ if (ps->dm_release)
+ ps->dm->release(ps->dm);
+
+ ps->dm = NULL;
+ return;
+ }
+
+ ps->dm_mvert = ps->dm->getVertArray(ps->dm);
+ ps->dm_mface = ps->dm->getTessFaceArray(ps->dm);
+ ps->dm_mtface = ps->dm->getTessFaceDataArray(ps->dm, CD_MTFACE);
+
+ ps->dm_totvert = ps->dm->getNumVerts(ps->dm);
+ ps->dm_totface = ps->dm->getNumTessFaces(ps->dm);
+
+ /* use clone mtface? */
+
+
+ /* Note, use the original mesh for getting the clone and mask layer index
+ * this avoids re-generating the derived mesh just to get the new index */
+ if (ps->do_layer_clone) {
+ //int layer_num = CustomData_get_clone_layer(&ps->dm->faceData, CD_MTFACE);
+ int layer_num = CustomData_get_clone_layer(&((Mesh *)ps->ob->data)->fdata, CD_MTFACE);
+ if (layer_num != -1)
+ ps->dm_mtface_clone = CustomData_get_layer_n(&ps->dm->faceData, CD_MTFACE, layer_num);
+
+ if (ps->dm_mtface_clone == NULL || ps->dm_mtface_clone == ps->dm_mtface) {
+ ps->do_layer_clone = FALSE;
+ ps->dm_mtface_clone = NULL;
+ printf("ACK!\n");
+ }
+ }
+
+ if (ps->do_layer_stencil) {
+ //int layer_num = CustomData_get_stencil_layer(&ps->dm->faceData, CD_MTFACE);
+ int layer_num = CustomData_get_stencil_layer(&((Mesh *)ps->ob->data)->fdata, CD_MTFACE);
+ if (layer_num != -1)
+ ps->dm_mtface_stencil = CustomData_get_layer_n(&ps->dm->faceData, CD_MTFACE, layer_num);
+
+ if (ps->dm_mtface_stencil == NULL || ps->dm_mtface_stencil == ps->dm_mtface) {
+ ps->do_layer_stencil = FALSE;
+ ps->dm_mtface_stencil = NULL;
+ }
+ }
+
+ /* when using subsurf or multires, mface arrays are thrown away, we need to keep a copy */
+ if (ps->dm->type != DM_TYPE_CDDM) {
+ ps->dm_mvert = MEM_dupallocN(ps->dm_mvert);
+ ps->dm_mface = MEM_dupallocN(ps->dm_mface);
+ /* looks like these are ok for now.*/
+#if 0
+ ps->dm_mtface = MEM_dupallocN(ps->dm_mtface);
+ ps->dm_mtface_clone = MEM_dupallocN(ps->dm_mtface_clone);
+ ps->dm_mtface_stencil = MEM_dupallocN(ps->dm_mtface_stencil);
+#endif
+ }
+
+ ps->viewDir[0] = 0.0f;
+ ps->viewDir[1] = 0.0f;
+ ps->viewDir[2] = 1.0f;
+
+ {
+ float viewmat[4][4];
+ float viewinv[4][4];
+
+ invert_m4_m4(ps->ob->imat, ps->ob->obmat);
+
+ if (ps->source == PROJ_SRC_VIEW) {
+ /* normal drawing */
+ ps->winx = ps->ar->winx;
+ ps->winy = ps->ar->winy;
+
+ copy_m4_m4(viewmat, ps->rv3d->viewmat);
+ copy_m4_m4(viewinv, ps->rv3d->viewinv);
+
+ ED_view3d_ob_project_mat_get(ps->rv3d, ps->ob, ps->projectMat);
+
+ ps->is_ortho = ED_view3d_clip_range_get(ps->v3d, ps->rv3d, &ps->clipsta, &ps->clipend, true);
+ }
+ else {
+ /* re-projection */
+ float winmat[4][4];
+ float vmat[4][4];
+
+ ps->winx = ps->reproject_ibuf->x;
+ ps->winy = ps->reproject_ibuf->y;
+
+ if (ps->source == PROJ_SRC_IMAGE_VIEW) {
+ /* image stores camera data, tricky */
+ IDProperty *idgroup = IDP_GetProperties(&ps->reproject_image->id, 0);
+ IDProperty *view_data = IDP_GetPropertyFromGroup(idgroup, PROJ_VIEW_DATA_ID);
+
+ float *array = (float *)IDP_Array(view_data);
+
+ /* use image array, written when creating image */
+ memcpy(winmat, array, sizeof(winmat)); array += sizeof(winmat) / sizeof(float);
+ memcpy(viewmat, array, sizeof(viewmat)); array += sizeof(viewmat) / sizeof(float);
+ ps->clipsta = array[0];
+ ps->clipend = array[1];
+ ps->is_ortho = array[2] ? 1 : 0;
+
+ invert_m4_m4(viewinv, viewmat);
+ }
+ else if (ps->source == PROJ_SRC_IMAGE_CAM) {
+ Object *cam_ob = ps->scene->camera;
+ CameraParams params;
+
+ /* viewmat & viewinv */
+ copy_m4_m4(viewinv, cam_ob->obmat);
+ normalize_m4(viewinv);
+ invert_m4_m4(viewmat, viewinv);
+
+ /* window matrix, clipping and ortho */
+ BKE_camera_params_init(&params);
+ BKE_camera_params_from_object(&params, cam_ob);
+ BKE_camera_params_compute_viewplane(&params, ps->winx, ps->winy, 1.0f, 1.0f);
+ BKE_camera_params_compute_matrix(&params);
+
+ copy_m4_m4(winmat, params.winmat);
+ ps->clipsta = params.clipsta;
+ ps->clipend = params.clipend;
+ ps->is_ortho = params.is_ortho;
+ }
+
+ /* same as #ED_view3d_ob_project_mat_get */
+ mult_m4_m4m4(vmat, viewmat, ps->ob->obmat);
+ mult_m4_m4m4(ps->projectMat, winmat, vmat);
+ }
+
+
+ /* viewDir - object relative */
+ invert_m4_m4(ps->ob->imat, ps->ob->obmat);
+ copy_m3_m4(mat, viewinv);
+ mul_m3_v3(mat, ps->viewDir);
+ copy_m3_m4(mat, ps->ob->imat);
+ mul_m3_v3(mat, ps->viewDir);
+ normalize_v3(ps->viewDir);
+
+ /* viewPos - object relative */
+ copy_v3_v3(ps->viewPos, viewinv[3]);
+ copy_m3_m4(mat, ps->ob->imat);
+ mul_m3_v3(mat, ps->viewPos);
+ add_v3_v3(ps->viewPos, ps->ob->imat[3]);
+ }
+
+ /* calculate vert screen coords
+ * run this early so we can calculate the x/y resolution of our bucket rect */
+ INIT_MINMAX2(ps->screenMin, ps->screenMax);
+
+ ps->screenCoords = MEM_mallocN(sizeof(float) * ps->dm_totvert * 4, "ProjectPaint ScreenVerts");
+ projScreenCo = *ps->screenCoords;
+
+ if (ps->is_ortho) {
+ for (a = 0, mv = ps->dm_mvert; a < ps->dm_totvert; a++, mv++, projScreenCo += 4) {
+ mul_v3_m4v3(projScreenCo, ps->projectMat, mv->co);
+
+ /* screen space, not clamped */
+ projScreenCo[0] = (float)(ps->winx / 2.0f) + (ps->winx / 2.0f) * projScreenCo[0];
+ projScreenCo[1] = (float)(ps->winy / 2.0f) + (ps->winy / 2.0f) * projScreenCo[1];
+ minmax_v2v2_v2(ps->screenMin, ps->screenMax, projScreenCo);
+ }
+ }
+ else {
+ for (a = 0, mv = ps->dm_mvert; a < ps->dm_totvert; a++, mv++, projScreenCo += 4) {
+ copy_v3_v3(projScreenCo, mv->co);
+ projScreenCo[3] = 1.0f;
+
+ mul_m4_v4(ps->projectMat, projScreenCo);
+
+ if (projScreenCo[3] > ps->clipsta) {
+ /* screen space, not clamped */
+ projScreenCo[0] = (float)(ps->winx / 2.0f) + (ps->winx / 2.0f) * projScreenCo[0] / projScreenCo[3];
+ projScreenCo[1] = (float)(ps->winy / 2.0f) + (ps->winy / 2.0f) * projScreenCo[1] / projScreenCo[3];
+ projScreenCo[2] = projScreenCo[2] / projScreenCo[3]; /* Use the depth for bucket point occlusion */
+ minmax_v2v2_v2(ps->screenMin, ps->screenMax, projScreenCo);
+ }
+ else {
+ /* TODO - deal with cases where 1 side of a face goes behind the view ?
+ *
+ * After some research this is actually very tricky, only option is to
+ * clip the derived mesh before painting, which is a Pain */
+ projScreenCo[0] = FLT_MAX;
+ }
+ }
+ }
+
+ /* If this border is not added we get artifacts for faces that
+ * have a parallel edge and at the bounds of the the 2D projected verts eg
+ * - a single screen aligned quad */
+ projMargin = (ps->screenMax[0] - ps->screenMin[0]) * 0.000001f;
+ ps->screenMax[0] += projMargin;
+ ps->screenMin[0] -= projMargin;
+ projMargin = (ps->screenMax[1] - ps->screenMin[1]) * 0.000001f;
+ ps->screenMax[1] += projMargin;
+ ps->screenMin[1] -= projMargin;
+
+ if (ps->source == PROJ_SRC_VIEW) {
+#ifdef PROJ_DEBUG_WINCLIP
+ CLAMP(ps->screenMin[0], (float)(-diameter), (float)(ps->winx + diameter));
+ CLAMP(ps->screenMax[0], (float)(-diameter), (float)(ps->winx + diameter));
+
+ CLAMP(ps->screenMin[1], (float)(-diameter), (float)(ps->winy + diameter));
+ CLAMP(ps->screenMax[1], (float)(-diameter), (float)(ps->winy + diameter));
+#endif
+ }
+ else { /* re-projection, use bounds */
+ ps->screenMin[0] = 0;
+ ps->screenMax[0] = (float)(ps->winx);
+
+ ps->screenMin[1] = 0;
+ ps->screenMax[1] = (float)(ps->winy);
+ }
+
+ /* only for convenience */
+ ps->screen_width = ps->screenMax[0] - ps->screenMin[0];
+ ps->screen_height = ps->screenMax[1] - ps->screenMin[1];
+
+ ps->buckets_x = (int)(ps->screen_width / (((float)diameter) / PROJ_BUCKET_BRUSH_DIV));
+ ps->buckets_y = (int)(ps->screen_height / (((float)diameter) / PROJ_BUCKET_BRUSH_DIV));
+
+ /* printf("\tscreenspace bucket division x:%d y:%d\n", ps->buckets_x, ps->buckets_y); */
+
+ /* really high values could cause problems since it has to allocate a few
+ * (ps->buckets_x*ps->buckets_y) sized arrays */
+ CLAMP(ps->buckets_x, PROJ_BUCKET_RECT_MIN, PROJ_BUCKET_RECT_MAX);
+ CLAMP(ps->buckets_y, PROJ_BUCKET_RECT_MIN, PROJ_BUCKET_RECT_MAX);
+
+ ps->bucketRect = (LinkNode **)MEM_callocN(sizeof(LinkNode *) * ps->buckets_x * ps->buckets_y, "paint-bucketRect");
+ ps->bucketFaces = (LinkNode **)MEM_callocN(sizeof(LinkNode *) * ps->buckets_x * ps->buckets_y, "paint-bucketFaces");
+
+ ps->bucketFlags = (unsigned char *)MEM_callocN(sizeof(char) * ps->buckets_x * ps->buckets_y, "paint-bucketFaces");
+#ifndef PROJ_DEBUG_NOSEAMBLEED
+ if (ps->seam_bleed_px > 0.0f) {
+ ps->vertFaces = (LinkNode **)MEM_callocN(sizeof(LinkNode *) * ps->dm_totvert, "paint-vertFaces");
+ ps->faceSeamFlags = (char *)MEM_callocN(sizeof(char) * ps->dm_totface, "paint-faceSeamFlags");
+ ps->faceSeamUVs = MEM_mallocN(sizeof(float) * ps->dm_totface * 8, "paint-faceSeamUVs");
+ }
+#endif
+
+ /* Thread stuff
+ *
+ * very small brushes run a lot slower multithreaded since the advantage with
+ * threads is being able to fill in multiple buckets at once.
+ * Only use threads for bigger brushes. */
+
+ if (ps->scene->r.mode & R_FIXED_THREADS) {
+ ps->thread_tot = ps->scene->r.threads;
+ }
+ else {
+ ps->thread_tot = BLI_system_thread_count();
+ }
+ for (a = 0; a < ps->thread_tot; a++) {
+ ps->arena_mt[a] = BLI_memarena_new(1 << 16, "project paint arena");
+ }
+
+ arena = ps->arena_mt[0];
+
+ if (ps->do_backfacecull && ps->do_mask_normal) {
+ float viewDirPersp[3];
+
+ ps->vertFlags = MEM_callocN(sizeof(char) * ps->dm_totvert, "paint-vertFlags");
+
+ for (a = 0, mv = ps->dm_mvert; a < ps->dm_totvert; a++, mv++) {
+ normal_short_to_float_v3(no, mv->no);
+
+ if (ps->is_ortho) {
+ if (angle_normalized_v3v3(ps->viewDir, no) >= ps->normal_angle) { /* 1 vert of this face is towards us */
+ ps->vertFlags[a] |= PROJ_VERT_CULL;
+ }
+ }
+ else {
+ sub_v3_v3v3(viewDirPersp, ps->viewPos, mv->co);
+ normalize_v3(viewDirPersp);
+ if (angle_normalized_v3v3(viewDirPersp, no) >= ps->normal_angle) { /* 1 vert of this face is towards us */
+ ps->vertFlags[a] |= PROJ_VERT_CULL;
+ }
+ }
+ }
+ }
+
+
+ for (face_index = 0, tf = ps->dm_mtface, mf = ps->dm_mface; face_index < ps->dm_totface; mf++, tf++, face_index++) {
+
+#ifndef PROJ_DEBUG_NOSEAMBLEED
+ /* add face user if we have bleed enabled, set the UV seam flags later */
+ /* annoying but we need to add all faces even ones we never use elsewhere */
+ if (ps->seam_bleed_px > 0.0f) {
+ BLI_linklist_prepend_arena(&ps->vertFaces[mf->v1], SET_INT_IN_POINTER(face_index), arena);
+ BLI_linklist_prepend_arena(&ps->vertFaces[mf->v2], SET_INT_IN_POINTER(face_index), arena);
+ BLI_linklist_prepend_arena(&ps->vertFaces[mf->v3], SET_INT_IN_POINTER(face_index), arena);
+ if (mf->v4) {
+ BLI_linklist_prepend_arena(&ps->vertFaces[mf->v4], SET_INT_IN_POINTER(face_index), arena);
+ }
+ }
+#endif
+
+ tpage = project_paint_face_image(ps, ps->dm_mtface, face_index);
+
+ if (tpage && ((((Mesh *)ps->ob->data)->editflag & ME_EDIT_PAINT_FACE_SEL) == 0 || mf->flag & ME_FACE_SEL)) {
+
+ float *v1coSS, *v2coSS, *v3coSS, *v4coSS = NULL;
+
+ v1coSS = ps->screenCoords[mf->v1];
+ v2coSS = ps->screenCoords[mf->v2];
+ v3coSS = ps->screenCoords[mf->v3];
+ if (mf->v4) {
+ v4coSS = ps->screenCoords[mf->v4];
+ }
+
+
+ if (!ps->is_ortho) {
+ if (v1coSS[0] == FLT_MAX ||
+ v2coSS[0] == FLT_MAX ||
+ v3coSS[0] == FLT_MAX ||
+ (mf->v4 && v4coSS[0] == FLT_MAX))
+ {
+ continue;
+ }
+ }
+
+#ifdef PROJ_DEBUG_WINCLIP
+ /* ignore faces outside the view */
+ if (
+ (v1coSS[0] < ps->screenMin[0] &&
+ v2coSS[0] < ps->screenMin[0] &&
+ v3coSS[0] < ps->screenMin[0] &&
+ (mf->v4 && v4coSS[0] < ps->screenMin[0])) ||
+
+ (v1coSS[0] > ps->screenMax[0] &&
+ v2coSS[0] > ps->screenMax[0] &&
+ v3coSS[0] > ps->screenMax[0] &&
+ (mf->v4 && v4coSS[0] > ps->screenMax[0])) ||
+
+ (v1coSS[1] < ps->screenMin[1] &&
+ v2coSS[1] < ps->screenMin[1] &&
+ v3coSS[1] < ps->screenMin[1] &&
+ (mf->v4 && v4coSS[1] < ps->screenMin[1])) ||
+
+ (v1coSS[1] > ps->screenMax[1] &&
+ v2coSS[1] > ps->screenMax[1] &&
+ v3coSS[1] > ps->screenMax[1] &&
+ (mf->v4 && v4coSS[1] > ps->screenMax[1]))
+ )
+ {
+ continue;
+ }
+
+#endif //PROJ_DEBUG_WINCLIP
+
+
+ if (ps->do_backfacecull) {
+ if (ps->do_mask_normal) {
+ /* Since we are interpolating the normals of faces, we want to make
+ * sure all the verts are pointing away from the view,
+ * not just the face */
+ if ((ps->vertFlags[mf->v1] & PROJ_VERT_CULL) &&
+ (ps->vertFlags[mf->v2] & PROJ_VERT_CULL) &&
+ (ps->vertFlags[mf->v3] & PROJ_VERT_CULL) &&
+ (mf->v4 == 0 || ps->vertFlags[mf->v4] & PROJ_VERT_CULL)
+ )
+ {
+ continue;
+ }
+ }
+ else {
+ if (line_point_side_v2(v1coSS, v2coSS, v3coSS) < 0.0f) {
+ continue;
+ }
+
+ }
+ }
+
+ if (tpage_last != tpage) {
+
+ image_index = BLI_linklist_index(image_LinkList, tpage);
+
+ if (image_index == -1 && BKE_image_has_ibuf(tpage, NULL)) { /* MemArena dosnt have an append func */
+ BLI_linklist_append(&image_LinkList, tpage);
+ image_index = ps->image_tot;
+ ps->image_tot++;
+ }
+
+ tpage_last = tpage;
+ }
+
+ if (image_index != -1) {
+ /* Initialize the faces screen pixels */
+ /* Add this to a list to initialize later */
+ project_paint_delayed_face_init(ps, mf, face_index);
+ }
+ }
+ }
+
+ /* build an array of images we use*/
+ projIma = ps->projImages = (ProjPaintImage *)BLI_memarena_alloc(arena, sizeof(ProjPaintImage) * ps->image_tot);
+
+ for (node = image_LinkList, i = 0; node; node = node->next, i++, projIma++) {
+ projIma->ima = node->link;
+ projIma->touch = 0;
+ projIma->ibuf = BKE_image_acquire_ibuf(projIma->ima, NULL, NULL);
+ projIma->partRedrawRect = BLI_memarena_alloc(arena, sizeof(ImagePaintPartialRedraw) * PROJ_BOUNDBOX_SQUARED);
+ memset(projIma->partRedrawRect, 0, sizeof(ImagePaintPartialRedraw) * PROJ_BOUNDBOX_SQUARED);
+ }
+
+ /* we have built the array, discard the linked list */
+ BLI_linklist_free(image_LinkList, NULL);
+}
+
+static void paint_proj_begin_clone(ProjPaintState *ps, const int mouse[2])
+{
+ /* setup clone offset */
+ if (ps->tool == PAINT_TOOL_CLONE) {
+ float projCo[4];
+ copy_v3_v3(projCo, give_cursor(ps->scene, ps->v3d));
+ mul_m4_v3(ps->ob->imat, projCo);
+
+ projCo[3] = 1.0f;
+ mul_m4_v4(ps->projectMat, projCo);
+ ps->cloneOffset[0] = mouse[0] - ((float)(ps->winx / 2.0f) + (ps->winx / 2.0f) * projCo[0] / projCo[3]);
+ ps->cloneOffset[1] = mouse[1] - ((float)(ps->winy / 2.0f) + (ps->winy / 2.0f) * projCo[1] / projCo[3]);
+ }
+}
+
+static void project_paint_end(ProjPaintState *ps)
+{
+ int a;
+ ProjPaintImage *projIma;
+
+ /* build undo data from original pixel colors */
+ if (U.uiflag & USER_GLOBALUNDO) {
+ ProjPixel *projPixel;
+ ImBuf *tmpibuf = NULL, *tmpibuf_float = NULL;
+ LinkNode *pixel_node;
+ void *tilerect;
+ MemArena *arena = ps->arena_mt[0]; /* threaded arena re-used for non threaded case */
+
+ int bucket_tot = (ps->buckets_x * ps->buckets_y); /* we could get an X/Y but easier to loop through all possible buckets */
+ int bucket_index;
+ int tile_index;
+ int x_round, y_round;
+ int x_tile, y_tile;
+ int is_float = -1;
+
+ /* context */
+ ProjPaintImage *last_projIma;
+ int last_image_index = -1;
+ int last_tile_width = 0;
+
+ for (a = 0, last_projIma = ps->projImages; a < ps->image_tot; a++, last_projIma++) {
+ int size = sizeof(void **) * IMAPAINT_TILE_NUMBER(last_projIma->ibuf->x) * IMAPAINT_TILE_NUMBER(last_projIma->ibuf->y);
+ last_projIma->undoRect = (void **) BLI_memarena_alloc(arena, size);
+ memset(last_projIma->undoRect, 0, size);
+ last_projIma->ibuf->userflags |= IB_BITMAPDIRTY;
+ }
+
+ for (bucket_index = 0; bucket_index < bucket_tot; bucket_index++) {
+ /* loop through all pixels */
+ for (pixel_node = ps->bucketRect[bucket_index]; pixel_node; pixel_node = pixel_node->next) {
+
+ /* ok we have a pixel, was it modified? */
+ projPixel = (ProjPixel *)pixel_node->link;
+
+ if (last_image_index != projPixel->image_index) {
+ /* set the context */
+ last_image_index = projPixel->image_index;
+ last_projIma = ps->projImages + last_image_index;
+ last_tile_width = IMAPAINT_TILE_NUMBER(last_projIma->ibuf->x);
+ is_float = last_projIma->ibuf->rect_float ? 1 : 0;
+ }
+
+
+ if ((is_float == 0 && projPixel->origColor.uint != *projPixel->pixel.uint_pt) ||
+ (is_float == 1 &&
+ (projPixel->origColor.f[0] != projPixel->pixel.f_pt[0] ||
+ projPixel->origColor.f[1] != projPixel->pixel.f_pt[1] ||
+ projPixel->origColor.f[2] != projPixel->pixel.f_pt[2] ||
+ projPixel->origColor.f[3] != projPixel->pixel.f_pt[3]))
+ )
+ {
+
+ x_tile = projPixel->x_px >> IMAPAINT_TILE_BITS;
+ y_tile = projPixel->y_px >> IMAPAINT_TILE_BITS;
+
+ x_round = x_tile * IMAPAINT_TILE_SIZE;
+ y_round = y_tile * IMAPAINT_TILE_SIZE;
+
+ tile_index = x_tile + y_tile * last_tile_width;
+
+ if (last_projIma->undoRect[tile_index] == NULL) {
+ /* add the undo tile from the modified image, then write the original colors back into it */
+ tilerect = last_projIma->undoRect[tile_index] = image_undo_push_tile(last_projIma->ima, last_projIma->ibuf, is_float ? (&tmpibuf_float) : (&tmpibuf), x_tile, y_tile);
+ }
+ else {
+ tilerect = last_projIma->undoRect[tile_index];
+ }
+
+ /* This is a BIT ODD, but overwrite the undo tiles image info with this pixels original color
+ * because allocating the tiles along the way slows down painting */
+
+ if (is_float) {
+ float *rgba_fp = (float *)tilerect + (((projPixel->x_px - x_round) + (projPixel->y_px - y_round) * IMAPAINT_TILE_SIZE)) * 4;
+ copy_v4_v4(rgba_fp, projPixel->origColor.f);
+ }
+ else {
+ ((unsigned int *)tilerect)[(projPixel->x_px - x_round) + (projPixel->y_px - y_round) * IMAPAINT_TILE_SIZE] = projPixel->origColor.uint;
+ }
+ }
+ }
+ }
+
+ if (tmpibuf) IMB_freeImBuf(tmpibuf);
+ if (tmpibuf_float) IMB_freeImBuf(tmpibuf_float);
+ }
+ /* done calculating undo data */
+
+ /* dereference used image buffers */
+ for (a = 0, projIma = ps->projImages; a < ps->image_tot; a++, projIma++) {
+ BKE_image_release_ibuf(projIma->ima, projIma->ibuf, NULL);
+ }
+
+ BKE_image_release_ibuf(ps->reproject_image, ps->reproject_ibuf, NULL);
+
+ MEM_freeN(ps->screenCoords);
+ MEM_freeN(ps->bucketRect);
+ MEM_freeN(ps->bucketFaces);
+ MEM_freeN(ps->bucketFlags);
+
+#ifndef PROJ_DEBUG_NOSEAMBLEED
+ if (ps->seam_bleed_px > 0.0f) {
+ MEM_freeN(ps->vertFaces);
+ MEM_freeN(ps->faceSeamFlags);
+ MEM_freeN(ps->faceSeamUVs);
+ }
+#endif
+
+ if (ps->vertFlags) MEM_freeN(ps->vertFlags);
+
+ for (a = 0; a < ps->thread_tot; a++) {
+ BLI_memarena_free(ps->arena_mt[a]);
+ }
+
+ /* copy for subsurf/multires, so throw away */
+ if (ps->dm->type != DM_TYPE_CDDM) {
+ if (ps->dm_mvert) MEM_freeN(ps->dm_mvert);
+ if (ps->dm_mface) MEM_freeN(ps->dm_mface);
+ /* looks like these don't need copying */
+#if 0
+ if (ps->dm_mtface) MEM_freeN(ps->dm_mtface);
+ if (ps->dm_mtface_clone) MEM_freeN(ps->dm_mtface_clone);
+ if (ps->dm_mtface_stencil) MEM_freeN(ps->dm_mtface_stencil);
+#endif
+ }
+
+ if (ps->dm_release)
+ ps->dm->release(ps->dm);
+}
+
+/* 1 = an undo, -1 is a redo. */
+static void partial_redraw_array_init(ImagePaintPartialRedraw *pr)
+{
+ int tot = PROJ_BOUNDBOX_SQUARED;
+ while (tot--) {
+ pr->x1 = 10000000;
+ pr->y1 = 10000000;
+
+ pr->x2 = -1;
+ pr->y2 = -1;
+
+ pr->enabled = 1;
+
+ pr++;
+ }
+}
+
+
+static int partial_redraw_array_merge(ImagePaintPartialRedraw *pr, ImagePaintPartialRedraw *pr_other, int tot)
+{
+ int touch = 0;
+ while (tot--) {
+ pr->x1 = min_ii(pr->x1, pr_other->x1);
+ pr->y1 = min_ii(pr->y1, pr_other->y1);
+
+ pr->x2 = max_ii(pr->x2, pr_other->x2);
+ pr->y2 = max_ii(pr->y2, pr_other->y2);
+
+ if (pr->x2 != -1)
+ touch = 1;
+
+ pr++; pr_other++;
+ }
+
+ return touch;
+}
+
+/* Loop over all images on this mesh and update any we have touched */
+static int project_image_refresh_tagged(ProjPaintState *ps)
+{
+ ImagePaintPartialRedraw *pr;
+ ProjPaintImage *projIma;
+ int a, i;
+ int redraw = 0;
+
+
+ for (a = 0, projIma = ps->projImages; a < ps->image_tot; a++, projIma++) {
+ if (projIma->touch) {
+ /* look over each bound cell */
+ for (i = 0; i < PROJ_BOUNDBOX_SQUARED; i++) {
+ pr = &(projIma->partRedrawRect[i]);
+ if (pr->x2 != -1) { /* TODO - use 'enabled' ? */
+ set_imapaintpartial(pr);
+ imapaint_image_update(NULL, projIma->ima, projIma->ibuf, true);
+ redraw = 1;
+ }
+ }
+
+ projIma->touch = 0; /* clear for reuse */
+ }
+ }
+
+ return redraw;
+}
+
+/* run this per painting onto each mouse location */
+static int project_bucket_iter_init(ProjPaintState *ps, const float mval_f[2])
+{
+ if (ps->source == PROJ_SRC_VIEW) {
+ float min_brush[2], max_brush[2];
+ const float radius = (float)BKE_brush_size_get(ps->scene, ps->brush);
+
+ /* so we don't have a bucket bounds that is way too small to paint into */
+ // if (radius < 1.0f) radius = 1.0f; // this doesn't work yet :/
+
+ min_brush[0] = mval_f[0] - radius;
+ min_brush[1] = mval_f[1] - radius;
+
+ max_brush[0] = mval_f[0] + radius;
+ max_brush[1] = mval_f[1] + radius;
+
+ /* offset to make this a valid bucket index */
+ project_paint_bucket_bounds(ps, min_brush, max_brush, ps->bucketMin, ps->bucketMax);
+
+ /* mouse outside the model areas? */
+ if (ps->bucketMin[0] == ps->bucketMax[0] || ps->bucketMin[1] == ps->bucketMax[1]) {
+ return 0;
+ }
+
+ ps->context_bucket_x = ps->bucketMin[0];
+ ps->context_bucket_y = ps->bucketMin[1];
+ }
+ else { /* reproject: PROJ_SRC_* */
+ ps->bucketMin[0] = 0;
+ ps->bucketMin[1] = 0;
+
+ ps->bucketMax[0] = ps->buckets_x;
+ ps->bucketMax[1] = ps->buckets_y;
+
+ ps->context_bucket_x = 0;
+ ps->context_bucket_y = 0;
+ }
+ return 1;
+}
+
+
+static int project_bucket_iter_next(ProjPaintState *ps, int *bucket_index, rctf *bucket_bounds, const float mval[2])
+{
+ const int diameter = 2 * BKE_brush_size_get(ps->scene, ps->brush);
+
+ if (ps->thread_tot > 1)
+ BLI_lock_thread(LOCK_CUSTOM1);
+
+ //printf("%d %d\n", ps->context_bucket_x, ps->context_bucket_y);
+
+ for (; ps->context_bucket_y < ps->bucketMax[1]; ps->context_bucket_y++) {
+ for (; ps->context_bucket_x < ps->bucketMax[0]; ps->context_bucket_x++) {
+
+ /* use bucket_bounds for project_bucket_isect_circle and project_bucket_init*/
+ project_bucket_bounds(ps, ps->context_bucket_x, ps->context_bucket_y, bucket_bounds);
+
+ if ((ps->source != PROJ_SRC_VIEW) ||
+ project_bucket_isect_circle(mval, (float)(diameter * diameter), bucket_bounds))
+ {
+ *bucket_index = ps->context_bucket_x + (ps->context_bucket_y * ps->buckets_x);
+ ps->context_bucket_x++;
+
+ if (ps->thread_tot > 1)
+ BLI_unlock_thread(LOCK_CUSTOM1);
+
+ return 1;
+ }
+ }
+ ps->context_bucket_x = ps->bucketMin[0];
+ }
+
+ if (ps->thread_tot > 1)
+ BLI_unlock_thread(LOCK_CUSTOM1);
+ return 0;
+}
+
+/* Each thread gets one of these, also used as an argument to pass to project_paint_op */
+typedef struct ProjectHandle {
+ /* args */
+ ProjPaintState *ps;
+ float prevmval[2];
+ float mval[2];
+
+ /* annoying but we need to have image bounds per thread, then merge into ps->projectPartialRedraws */
+ ProjPaintImage *projImages; /* array of partial redraws */
+
+ /* thread settings */
+ int thread_index;
+
+ struct ImagePool *pool;
+} ProjectHandle;
+
+static void blend_color_mix(unsigned char cp[4], const unsigned char cp1[4], const unsigned char cp2[4], const int fac)
+{
+ /* this and other blending modes previously used >>8 instead of /255. both
+ * are not equivalent (>>8 is /256), and the former results in rounding
+ * errors that can turn colors black fast after repeated blending */
+ const int mfac = 255 - fac;
+
+ cp[0] = (mfac * cp1[0] + fac * cp2[0]) / 255;
+ cp[1] = (mfac * cp1[1] + fac * cp2[1]) / 255;
+ cp[2] = (mfac * cp1[2] + fac * cp2[2]) / 255;
+ cp[3] = (mfac * cp1[3] + fac * cp2[3]) / 255;
+}
+
+static void blend_color_mix_float(float cp[4], const float cp1[4], const float cp2[4], const float fac)
+{
+ const float mfac = 1.0f - fac;
+ cp[0] = mfac * cp1[0] + fac * cp2[0];
+ cp[1] = mfac * cp1[1] + fac * cp2[1];
+ cp[2] = mfac * cp1[2] + fac * cp2[2];
+ cp[3] = mfac * cp1[3] + fac * cp2[3];
+}
+
+static void blend_color_mix_accum(unsigned char cp[4], const unsigned char cp1[4], const unsigned char cp2[4], const int fac)
+{
+ /* this and other blending modes previously used >>8 instead of /255. both
+ * are not equivalent (>>8 is /256), and the former results in rounding
+ * errors that can turn colors black fast after repeated blending */
+ const int mfac = 255 - fac;
+ const int alpha = cp1[3] + ((fac * cp2[3]) / 255);
+
+ cp[0] = (mfac * cp1[0] + fac * cp2[0]) / 255;
+ cp[1] = (mfac * cp1[1] + fac * cp2[1]) / 255;
+ cp[2] = (mfac * cp1[2] + fac * cp2[2]) / 255;
+ cp[3] = alpha > 255 ? 255 : alpha;
+}
+static void blend_color_mix_accum_float(float cp[4], const float cp1[4], const unsigned char cp2[4], const float fac)
+{
+ const float mfac = 1.0f - fac;
+ const float alpha = cp1[3] + (fac * (cp2[3] / 255.0f));
+
+ cp[0] = (mfac * cp1[0] + (fac * (cp2[0] / 255.0f)));
+ cp[1] = (mfac * cp1[1] + (fac * (cp2[1] / 255.0f)));
+ cp[2] = (mfac * cp1[2] + (fac * (cp2[2] / 255.0f)));
+ cp[3] = alpha > 1.0f ? 1.0f : alpha;
+}
+
+
+static void do_projectpaint_clone(ProjPaintState *ps, ProjPixel *projPixel, float alpha, float mask)
+{
+ if (ps->do_masking && mask < 1.0f) {
+ projPixel->newColor.uint = IMB_blend_color(projPixel->newColor.uint, ((ProjPixelClone *)projPixel)->clonepx.uint, (int)(alpha * 255), ps->blend);
+ blend_color_mix(projPixel->pixel.ch_pt, projPixel->origColor.ch, projPixel->newColor.ch, (int)(mask * 255));
+ }
+ else {
+ *projPixel->pixel.uint_pt = IMB_blend_color(*projPixel->pixel.uint_pt, ((ProjPixelClone *)projPixel)->clonepx.uint, (int)(alpha * mask * 255), ps->blend);
+ }
+}
+
+static void do_projectpaint_clone_f(ProjPaintState *ps, ProjPixel *projPixel, float alpha, float mask)
+{
+ if (ps->do_masking && mask < 1.0f) {
+ IMB_blend_color_float(projPixel->newColor.f, projPixel->newColor.f, ((ProjPixelClone *)projPixel)->clonepx.f, alpha, ps->blend);
+ blend_color_mix_float(projPixel->pixel.f_pt, projPixel->origColor.f, projPixel->newColor.f, mask);
+ }
+ else {
+ IMB_blend_color_float(projPixel->pixel.f_pt, projPixel->pixel.f_pt, ((ProjPixelClone *)projPixel)->clonepx.f, alpha * mask, ps->blend);
+ }
+}
+
+/* do_projectpaint_smear*
+ *
+ * note, mask is used to modify the alpha here, this is not correct since it allows
+ * accumulation of color greater then 'projPixel->mask' however in the case of smear its not
+ * really that important to be correct as it is with clone and painting
+ */
+static void do_projectpaint_smear(ProjPaintState *ps, ProjPixel *projPixel, float alpha, float mask,
+ MemArena *smearArena, LinkNode **smearPixels, const float co[2])
+{
+ unsigned char rgba_ub[4];
+
+ if (project_paint_PickColor(ps, co, NULL, rgba_ub, 1) == 0)
+ return;
+ /* ((ProjPixelClone *)projPixel)->clonepx.uint = IMB_blend_color(*projPixel->pixel.uint_pt, *((unsigned int *)rgba_ub), (int)(alpha*mask*255), ps->blend); */
+ blend_color_mix(((ProjPixelClone *)projPixel)->clonepx.ch, projPixel->pixel.ch_pt, rgba_ub, (int)(alpha * mask * 255));
+ BLI_linklist_prepend_arena(smearPixels, (void *)projPixel, smearArena);
+}
+
+static void do_projectpaint_smear_f(ProjPaintState *ps, ProjPixel *projPixel, float alpha, float mask,
+ MemArena *smearArena, LinkNode **smearPixels_f, const float co[2])
+{
+ float rgba[4];
+
+ if (project_paint_PickColor(ps, co, rgba, NULL, 1) == 0)
+ return;
+
+ /* (ProjPixelClone *)projPixel)->clonepx.uint = IMB_blend_color(*((unsigned int *)rgba_smear), *((unsigned int *)rgba_ub), (int)(alpha*mask*255), ps->blend); */
+ blend_color_mix_float(((ProjPixelClone *)projPixel)->clonepx.f, projPixel->pixel.f_pt, rgba, alpha * mask);
+ BLI_linklist_prepend_arena(smearPixels_f, (void *)projPixel, smearArena);
+}
+
+/* do_projectpaint_soften for float & byte
+ */
+static float inv_pow2(float f)
+{
+ f = 1.0f - f;
+ f = f * f;
+ return 1.0f - f;
+}
+
+static void do_projectpaint_soften_f(ProjPaintState *ps, ProjPixel *projPixel, float alpha, float mask,
+ MemArena *softenArena, LinkNode **softenPixels)
+{
+ unsigned int accum_tot = 0;
+ unsigned int i;
+
+ float *rgba = projPixel->newColor.f;
+
+ /* sigh, alpha values tend to need to be a _lot_ stronger with blur */
+ mask = inv_pow2(mask);
+ alpha = inv_pow2(alpha);
+
+ /* rather then painting, accumulate surrounding colors */
+ zero_v4(rgba);
+
+ for (i = 0; i < PROJ_PIXEL_SOFTEN_TOT; i++) {
+ float co_ofs[2];
+ float rgba_tmp[4];
+ sub_v2_v2v2(co_ofs, projPixel->projCoSS, proj_pixel_soften_v2[i]);
+ if (project_paint_PickColor(ps, co_ofs, rgba_tmp, NULL, TRUE)) {
+ add_v4_v4(rgba, rgba_tmp);
+ accum_tot++;
+ }
+ }
+
+ if (LIKELY(accum_tot != 0)) {
+ mul_v4_fl(rgba, 1.0f / (float)accum_tot);
+ blend_color_mix_float(rgba, projPixel->pixel.f_pt, rgba, alpha);
+ if (mask < 1.0f) blend_color_mix_float(rgba, projPixel->origColor.f, rgba, mask);
+ BLI_linklist_prepend_arena(softenPixels, (void *)projPixel, softenArena);
+ }
+}
+
+static void do_projectpaint_soften(ProjPaintState *ps, ProjPixel *projPixel, float alpha, float mask,
+ MemArena *softenArena, LinkNode **softenPixels)
+{
+ unsigned int accum_tot = 0;
+ unsigned int i;
+
+ float rgba[4]; /* convert to byte after */
+
+ /* sigh, alpha values tend to need to be a _lot_ stronger with blur */
+ mask = inv_pow2(mask);
+ alpha = inv_pow2(alpha);
+
+ /* rather then painting, accumulate surrounding colors */
+ zero_v4(rgba);
+
+ for (i = 0; i < PROJ_PIXEL_SOFTEN_TOT; i++) {
+ float co_ofs[2];
+ float rgba_tmp[4];
+ sub_v2_v2v2(co_ofs, projPixel->projCoSS, proj_pixel_soften_v2[i]);
+ if (project_paint_PickColor(ps, co_ofs, rgba_tmp, NULL, TRUE)) {
+ add_v4_v4(rgba, rgba_tmp);
+ accum_tot++;
+ }
+ }
+
+ if (LIKELY(accum_tot != 0)) {
+ unsigned char *rgba_ub = projPixel->newColor.ch;
+
+ mul_v4_fl(rgba, 1.0f / (float)accum_tot);
+ IMAPAINT_FLOAT_RGBA_TO_CHAR(rgba_ub, rgba);
+
+ blend_color_mix(rgba_ub, projPixel->pixel.ch_pt, rgba_ub, (int)(alpha * 255));
+ if (mask != 1.0f) blend_color_mix(rgba_ub, projPixel->origColor.ch, rgba_ub, (int)(mask * 255));
+ BLI_linklist_prepend_arena(softenPixels, (void *)projPixel, softenArena);
+ }
+}
+
+BLI_INLINE void rgba_float_to_uchar__mul_v3(unsigned char rgba_ub[4], const float rgba[4], const float rgb[3])
+{
+ rgba_ub[0] = f_to_char(rgba[0] * rgb[0]);
+ rgba_ub[1] = f_to_char(rgba[1] * rgb[1]);
+ rgba_ub[2] = f_to_char(rgba[2] * rgb[2]);
+ rgba_ub[3] = f_to_char(rgba[3]);
+}
+
+static void do_projectpaint_draw(ProjPaintState *ps, ProjPixel *projPixel, const float rgba[4], float alpha, float mask)
+{
+ unsigned char rgba_ub[4];
+
+ if (ps->is_texbrush) {
+ rgba_float_to_uchar__mul_v3(rgba_ub, rgba, ps->brush->rgb);
+ }
+ else {
+ IMAPAINT_FLOAT_RGB_TO_CHAR(rgba_ub, ps->brush->rgb);
+ rgba_ub[3] = 255;
+ }
+
+ if (ps->do_masking && mask < 1.0f) {
+ projPixel->newColor.uint = IMB_blend_color(projPixel->newColor.uint, *((unsigned int *)rgba_ub), (int)(alpha * 255), ps->blend);
+ blend_color_mix(projPixel->pixel.ch_pt, projPixel->origColor.ch, projPixel->newColor.ch, (int)(mask * 255));
+ }
+ else {
+ *projPixel->pixel.uint_pt = IMB_blend_color(*projPixel->pixel.uint_pt, *((unsigned int *)rgba_ub), (int)(alpha * mask * 255), ps->blend);
+ }
+}
+
+static void do_projectpaint_draw_f(ProjPaintState *ps, ProjPixel *projPixel, float rgba[4], float alpha, float mask)
+{
+ if (ps->is_texbrush) {
+ /* rgba already holds a texture result here from higher level function */
+ float rgba_br[3];
+ srgb_to_linearrgb_v3_v3(rgba_br, ps->brush->rgb);
+ mul_v3_v3(rgba, rgba_br);
+ }
+ else {
+ srgb_to_linearrgb_v3_v3(rgba, ps->brush->rgb);
+ rgba[3] = 1.0;
+ }
+
+ if (ps->do_masking && mask < 1.0f) {
+ IMB_blend_color_float(projPixel->newColor.f, projPixel->newColor.f, rgba, alpha, ps->blend);
+ blend_color_mix_float(projPixel->pixel.f_pt, projPixel->origColor.f, projPixel->newColor.f, mask);
+ }
+ else {
+ IMB_blend_color_float(projPixel->pixel.f_pt, projPixel->pixel.f_pt, rgba, alpha * mask, ps->blend);
+ }
+}
+
+
+
+/* run this for single and multithreaded painting */
+static void *do_projectpaint_thread(void *ph_v)
+{
+ /* First unpack args from the struct */
+ ProjPaintState *ps = ((ProjectHandle *)ph_v)->ps;
+ ProjPaintImage *projImages = ((ProjectHandle *)ph_v)->projImages;
+ const float *lastpos = ((ProjectHandle *)ph_v)->prevmval;
+ const float *pos = ((ProjectHandle *)ph_v)->mval;
+ const int thread_index = ((ProjectHandle *)ph_v)->thread_index;
+ struct ImagePool *pool = ((ProjectHandle *)ph_v)->pool;
+ /* Done with args from ProjectHandle */
+
+ LinkNode *node;
+ ProjPixel *projPixel;
+ Brush *brush = ps->brush;
+
+ int last_index = -1;
+ ProjPaintImage *last_projIma = NULL;
+ ImagePaintPartialRedraw *last_partial_redraw_cell;
+
+ float rgba[4], alpha, dist_nosqrt, dist;
+
+ float falloff;
+ int bucket_index;
+ int is_floatbuf = 0;
+ const short tool = ps->tool;
+ rctf bucket_bounds;
+
+ /* for smear only */
+ float pos_ofs[2] = {0};
+ float co[2];
+ float mask = 1.0f; /* airbrush wont use mask */
+ unsigned short mask_short;
+ const float radius = (float)BKE_brush_size_get(ps->scene, brush);
+ const float radius_squared = radius * radius; /* avoid a square root with every dist comparison */
+
+ short lock_alpha = ELEM(brush->blend, IMB_BLEND_ERASE_ALPHA, IMB_BLEND_ADD_ALPHA) ? 0 : brush->flag & BRUSH_LOCK_ALPHA;
+
+ LinkNode *smearPixels = NULL;
+ LinkNode *smearPixels_f = NULL;
+ MemArena *smearArena = NULL; /* mem arena for this brush projection only */
+
+ LinkNode *softenPixels = NULL;
+ LinkNode *softenPixels_f = NULL;
+ MemArena *softenArena = NULL; /* mem arena for this brush projection only */
+
+ if (tool == PAINT_TOOL_SMEAR) {
+ pos_ofs[0] = pos[0] - lastpos[0];
+ pos_ofs[1] = pos[1] - lastpos[1];
+
+ smearArena = BLI_memarena_new(1 << 16, "paint smear arena");
+ }
+ else if (tool == PAINT_TOOL_SOFTEN) {
+ softenArena = BLI_memarena_new(1 << 16, "paint soften arena");
+ }
+
+ /* printf("brush bounds %d %d %d %d\n", bucketMin[0], bucketMin[1], bucketMax[0], bucketMax[1]); */
+
+ while (project_bucket_iter_next(ps, &bucket_index, &bucket_bounds, pos)) {
+
+ /* Check this bucket and its faces are initialized */
+ if (ps->bucketFlags[bucket_index] == PROJ_BUCKET_NULL) {
+ /* No pixels initialized */
+ project_bucket_init(ps, thread_index, bucket_index, &bucket_bounds);
+ }
+
+ if (ps->source != PROJ_SRC_VIEW) {
+
+ /* Re-Projection, simple, no brushes! */
+
+ for (node = ps->bucketRect[bucket_index]; node; node = node->next) {
+ projPixel = (ProjPixel *)node->link;
+
+ /* copy of code below */
+ if (last_index != projPixel->image_index) {
+ last_index = projPixel->image_index;
+ last_projIma = projImages + last_index;
+
+ last_projIma->touch = 1;
+ is_floatbuf = last_projIma->ibuf->rect_float ? 1 : 0;
+ }
+ /* end copy */
+
+ if (is_floatbuf) {
+ /* re-project buffer is assumed byte - TODO, allow float */
+ bicubic_interpolation_color(ps->reproject_ibuf, projPixel->newColor.ch, NULL,
+ projPixel->projCoSS[0], projPixel->projCoSS[1]);
+ if (projPixel->newColor.ch[3]) {
+ mask = ((float)projPixel->mask) / 65535.0f;
+ blend_color_mix_accum_float(projPixel->pixel.f_pt, projPixel->origColor.f,
+ projPixel->newColor.ch, (mask * (projPixel->newColor.ch[3] / 255.0f)));
+ }
+ }
+ else {
+ /* re-project buffer is assumed byte - TODO, allow float */
+ bicubic_interpolation_color(ps->reproject_ibuf, projPixel->newColor.ch, NULL,
+ projPixel->projCoSS[0], projPixel->projCoSS[1]);
+ if (projPixel->newColor.ch[3]) {
+ mask = ((float)projPixel->mask) / 65535.0f;
+ blend_color_mix_accum(projPixel->pixel.ch_pt, projPixel->origColor.ch,
+ projPixel->newColor.ch, (int)(mask * projPixel->newColor.ch[3]));
+ }
+ }
+ }
+ }
+ else {
+ /* Normal brush painting */
+
+ for (node = ps->bucketRect[bucket_index]; node; node = node->next) {
+
+ projPixel = (ProjPixel *)node->link;
+
+ dist_nosqrt = len_squared_v2v2(projPixel->projCoSS, pos);
+
+ /*if (dist < radius) {*/ /* correct but uses a sqrtf */
+ if (dist_nosqrt <= radius_squared) {
+ float samplecos[3];
+ dist = sqrtf(dist_nosqrt);
+
+ falloff = BKE_brush_curve_strength_clamp(ps->brush, dist, radius);
+
+ if (ps->is_texbrush) {
+ MTex *mtex = &brush->mtex;
+ /* taking 3d copy to account for 3D mapping too. It gets concatenated during sampling */
+ if (mtex->brush_map_mode == MTEX_MAP_MODE_3D) {
+ copy_v3_v3(samplecos, projPixel->worldCoSS);
+ }
+ else {
+ copy_v2_v2(samplecos, projPixel->projCoSS);
+ samplecos[2] = 0.0f;
+ }
+ }
+
+ if (falloff > 0.0f) {
+ if (ps->is_texbrush) {
+ /* note, for clone and smear, we only use the alpha, could be a special function */
+ BKE_brush_sample_tex_3D(ps->scene, brush, samplecos, rgba, thread_index, pool);
+ alpha = rgba[3];
+ }
+ else {
+ alpha = 1.0f;
+ }
+
+ if (!ps->do_masking) {
+ /* for an aurbrush there is no real mask, so just multiply the alpha by it */
+ alpha *= falloff * BKE_brush_alpha_get(ps->scene, brush);
+ mask = ((float)projPixel->mask) / 65535.0f;
+ }
+ else {
+ /* This brush dosnt accumulate so add some curve to the brushes falloff */
+ falloff = 1.0f - falloff;
+ falloff = 1.0f - (falloff * falloff);
+
+ mask_short = (unsigned short)(projPixel->mask * (BKE_brush_alpha_get(ps->scene, brush) * falloff));
+ if (mask_short > projPixel->mask_max) {
+ mask = ((float)mask_short) / 65535.0f;
+ projPixel->mask_max = mask_short;
+ }
+ else {
+ /*mask = ((float)projPixel->mask_max)/65535.0f;*/
+
+ /* Go onto the next pixel */
+ continue;
+ }
+ }
+
+ if (alpha > 0.0f) {
+
+ /* copy of code above */
+ if (last_index != projPixel->image_index) {
+ last_index = projPixel->image_index;
+ last_projIma = projImages + last_index;
+
+ last_projIma->touch = 1;
+ is_floatbuf = last_projIma->ibuf->rect_float ? 1 : 0;
+ }
+ /* end copy */
+
+ last_partial_redraw_cell = last_projIma->partRedrawRect + projPixel->bb_cell_index;
+ last_partial_redraw_cell->x1 = min_ii(last_partial_redraw_cell->x1, (int)projPixel->x_px);
+ last_partial_redraw_cell->y1 = min_ii(last_partial_redraw_cell->y1, (int)projPixel->y_px);
+
+ last_partial_redraw_cell->x2 = max_ii(last_partial_redraw_cell->x2, (int)projPixel->x_px + 1);
+ last_partial_redraw_cell->y2 = max_ii(last_partial_redraw_cell->y2, (int)projPixel->y_px + 1);
+
+
+ switch (tool) {
+ case PAINT_TOOL_CLONE:
+ if (is_floatbuf) {
+ if (((ProjPixelClone *)projPixel)->clonepx.f[3]) {
+ do_projectpaint_clone_f(ps, projPixel, alpha, mask); /* rgba isn't used for cloning, only alpha */
+ }
+ }
+ else {
+ if (((ProjPixelClone *)projPixel)->clonepx.ch[3]) {
+ do_projectpaint_clone(ps, projPixel, alpha, mask); /* rgba isn't used for cloning, only alpha */
+ }
+ }
+ break;
+ case PAINT_TOOL_SMEAR:
+ sub_v2_v2v2(co, projPixel->projCoSS, pos_ofs);
+
+ if (is_floatbuf) do_projectpaint_smear_f(ps, projPixel, alpha, mask, smearArena, &smearPixels_f, co);
+ else do_projectpaint_smear(ps, projPixel, alpha, mask, smearArena, &smearPixels, co);
+ break;
+ case PAINT_TOOL_SOFTEN:
+ if (is_floatbuf) do_projectpaint_soften_f(ps, projPixel, alpha, mask, softenArena, &softenPixels_f);
+ else do_projectpaint_soften(ps, projPixel, alpha, mask, softenArena, &softenPixels);
+ break;
+ default:
+ if (is_floatbuf) do_projectpaint_draw_f(ps, projPixel, rgba, alpha, mask);
+ else do_projectpaint_draw(ps, projPixel, rgba, alpha, mask);
+ break;
+ }
+ }
+
+ if (lock_alpha) {
+ if (is_floatbuf) projPixel->pixel.f_pt[3] = projPixel->origColor.f[3];
+ else projPixel->pixel.ch_pt[3] = projPixel->origColor.ch[3];
+ }
+
+ /* done painting */
+ }
+ }
+ }
+ }
+ }
+
+
+ if (tool == PAINT_TOOL_SMEAR) {
+
+ for (node = smearPixels; node; node = node->next) { /* this wont run for a float image */
+ projPixel = node->link;
+ *projPixel->pixel.uint_pt = ((ProjPixelClone *)projPixel)->clonepx.uint;
+ }
+
+ for (node = smearPixels_f; node; node = node->next) {
+ projPixel = node->link;
+ copy_v4_v4(projPixel->pixel.f_pt, ((ProjPixelClone *)projPixel)->clonepx.f);
+ }
+
+ BLI_memarena_free(smearArena);
+ }
+ else if (tool == PAINT_TOOL_SOFTEN) {
+
+ for (node = softenPixels; node; node = node->next) { /* this wont run for a float image */
+ projPixel = node->link;
+ *projPixel->pixel.uint_pt = projPixel->newColor.uint;
+ }
+
+ for (node = softenPixels_f; node; node = node->next) {
+ projPixel = node->link;
+ copy_v4_v4(projPixel->pixel.f_pt, projPixel->newColor.f);
+ }
+
+ BLI_memarena_free(softenArena);
+ }
+
+ return NULL;
+}
+
+static int project_paint_op(void *state, const float lastpos[2], const float pos[2])
+{
+ /* First unpack args from the struct */
+ ProjPaintState *ps = (ProjPaintState *)state;
+ int touch_any = 0;
+
+ ProjectHandle handles[BLENDER_MAX_THREADS];
+ ListBase threads;
+ int a, i;
+
+ struct ImagePool *pool;
+
+ if (!project_bucket_iter_init(ps, pos)) {
+ return 0;
+ }
+
+ if (ps->thread_tot > 1)
+ BLI_init_threads(&threads, do_projectpaint_thread, ps->thread_tot);
+
+ pool = BKE_image_pool_new();
+
+ /* get the threads running */
+ for (a = 0; a < ps->thread_tot; a++) {
+
+ /* set defaults in handles */
+ //memset(&handles[a], 0, sizeof(BakeShade));
+
+ handles[a].ps = ps;
+ copy_v2_v2(handles[a].mval, pos);
+ copy_v2_v2(handles[a].prevmval, lastpos);
+
+ /* thread specific */
+ handles[a].thread_index = a;
+
+ handles[a].projImages = (ProjPaintImage *)BLI_memarena_alloc(ps->arena_mt[a], ps->image_tot * sizeof(ProjPaintImage));
+
+ memcpy(handles[a].projImages, ps->projImages, ps->image_tot * sizeof(ProjPaintImage));
+
+ /* image bounds */
+ for (i = 0; i < ps->image_tot; i++) {
+ handles[a].projImages[i].partRedrawRect = (ImagePaintPartialRedraw *)BLI_memarena_alloc(ps->arena_mt[a], sizeof(ImagePaintPartialRedraw) * PROJ_BOUNDBOX_SQUARED);
+ memcpy(handles[a].projImages[i].partRedrawRect, ps->projImages[i].partRedrawRect, sizeof(ImagePaintPartialRedraw) * PROJ_BOUNDBOX_SQUARED);
+ }
+
+ handles[a].pool = pool;
+
+ if (ps->thread_tot > 1)
+ BLI_insert_thread(&threads, &handles[a]);
+ }
+
+ if (ps->thread_tot > 1) /* wait for everything to be done */
+ BLI_end_threads(&threads);
+ else
+ do_projectpaint_thread(&handles[0]);
+
+
+ BKE_image_pool_free(pool);
+
+ /* move threaded bounds back into ps->projectPartialRedraws */
+ for (i = 0; i < ps->image_tot; i++) {
+ int touch = 0;
+ for (a = 0; a < ps->thread_tot; a++) {
+ touch |= partial_redraw_array_merge(ps->projImages[i].partRedrawRect, handles[a].projImages[i].partRedrawRect, PROJ_BOUNDBOX_SQUARED);
+ }
+
+ if (touch) {
+ ps->projImages[i].touch = 1;
+ touch_any = 1;
+ }
+ }
+
+ return touch_any;
+}
+
+
+int paint_proj_stroke(bContext *C, void *pps, const int prevmval_i[2], const int mval_i[2])
+{
+ ProjPaintState *ps = pps;
+ int a, redraw;
+ float pos[2], prev_pos[2];
+
+ pos[0] = (float)(mval_i[0]);
+ pos[1] = (float)(mval_i[1]);
+
+ prev_pos[0] = (float)(prevmval_i[0]);
+ prev_pos[1] = (float)(prevmval_i[1]);
+
+ /* clone gets special treatment here to avoid going through image initialization */
+ if (ps->tool == PAINT_TOOL_CLONE && ps->mode == BRUSH_STROKE_INVERT) {
+ Scene *scene = ps->scene;
+ View3D *v3d = ps->v3d;
+ float *cursor = give_cursor(scene, v3d);
+
+ view3d_operator_needs_opengl(C);
+
+ if (!ED_view3d_autodist(scene, ps->ar, v3d, mval_i, cursor))
+ return 0;
+
+ ED_region_tag_redraw(ps->ar);
+
+ return 0;
+ }
+
+ for (a = 0; a < ps->image_tot; a++)
+ partial_redraw_array_init(ps->projImages[a].partRedrawRect);
+
+ redraw = project_paint_op(ps, prev_pos, pos) ? 1 : 0;
+
+ if (project_image_refresh_tagged(ps))
+ return redraw;
+
+ return 0;
+}
+
+
+/* initialize project paint settings from context */
+static void project_state_init(bContext *C, Object *ob, ProjPaintState *ps, int mode)
+{
+ Scene *scene = CTX_data_scene(C);
+ ToolSettings *settings = scene->toolsettings;
+
+ /* brush */
+ ps->mode = mode;
+ ps->brush = paint_brush(&settings->imapaint.paint);
+ if (ps->brush) {
+ Brush *brush = ps->brush;
+ ps->tool = brush->imagepaint_tool;
+ ps->blend = brush->blend;
+
+ /* disable for 3d mapping also because painting on mirrored mesh can create "stripes" */
+ ps->do_masking = (brush->flag & BRUSH_AIRBRUSH || brush->mtex.brush_map_mode == MTEX_MAP_MODE_VIEW ||
+ brush->mtex.brush_map_mode == MTEX_MAP_MODE_3D) ? false : true;
+ ps->is_texbrush = (brush->mtex.tex && brush->imagepaint_tool == PAINT_TOOL_DRAW) ? 1 : 0;
+ }
+ else {
+ /* brush may be NULL*/
+ ps->do_masking = false;
+ ps->is_texbrush = false;
+ }
+
+ /* sizeof(ProjPixel), since we alloc this a _lot_ */
+ ps->pixel_sizeof = project_paint_pixel_sizeof(ps->tool);
+ BLI_assert(ps->pixel_sizeof >= sizeof(ProjPixel));
+
+ /* these can be NULL */
+ ps->v3d = CTX_wm_view3d(C);
+ ps->rv3d = CTX_wm_region_view3d(C);
+ ps->ar = CTX_wm_region(C);
+
+ ps->scene = scene;
+ ps->ob = ob; /* allow override of active object */
+
+ /* setup projection painting data */
+ ps->do_backfacecull = (settings->imapaint.flag & IMAGEPAINT_PROJECT_BACKFACE) ? 0 : 1;
+ ps->do_occlude = (settings->imapaint.flag & IMAGEPAINT_PROJECT_XRAY) ? 0 : 1;
+ ps->do_mask_normal = (settings->imapaint.flag & IMAGEPAINT_PROJECT_FLAT) ? 0 : 1;
+ ps->do_new_shading_nodes = BKE_scene_use_new_shading_nodes(scene); /* only cache the value */
+
+ if (ps->tool == PAINT_TOOL_CLONE)
+ ps->do_layer_clone = (settings->imapaint.flag & IMAGEPAINT_PROJECT_LAYER_CLONE);
+
+ ps->do_layer_stencil = (settings->imapaint.flag & IMAGEPAINT_PROJECT_LAYER_STENCIL) ? 1 : 0;
+ ps->do_layer_stencil_inv = (settings->imapaint.flag & IMAGEPAINT_PROJECT_LAYER_STENCIL_INV) ? 1 : 0;
+
+
+#ifndef PROJ_DEBUG_NOSEAMBLEED
+ ps->seam_bleed_px = settings->imapaint.seam_bleed; /* pixel num to bleed */
+#endif
+
+ if (ps->do_mask_normal) {
+ ps->normal_angle_inner = settings->imapaint.normal_angle;
+ ps->normal_angle = (ps->normal_angle_inner + 90.0f) * 0.5f;
+ }
+ else {
+ ps->normal_angle_inner = ps->normal_angle = settings->imapaint.normal_angle;
+ }
+
+ ps->normal_angle_inner *= (float)(M_PI_2 / 90);
+ ps->normal_angle *= (float)(M_PI_2 / 90);
+ ps->normal_angle_range = ps->normal_angle - ps->normal_angle_inner;
+
+ if (ps->normal_angle_range <= 0.0f)
+ ps->do_mask_normal = FALSE; /* no need to do blending */
+
+ return;
+}
+
+void *paint_proj_new_stroke(bContext *C, Object *ob, const int mouse[2], int mode)
+{
+ ProjPaintState *ps = MEM_callocN(sizeof(ProjPaintState), "ProjectionPaintState");
+ project_state_init(C, ob, ps, mode);
+
+ if (ps->tool == PAINT_TOOL_CLONE && mode == BRUSH_STROKE_INVERT) {
+ view3d_operator_needs_opengl(C);
+ return ps;
+ }
+
+ /* needed so multiple threads don't try to initialize the brush at once (can leak memory) */
+ curvemapping_initialize(ps->brush->curve);
+
+ paint_brush_init_tex(ps->brush);
+
+ ps->source = PROJ_SRC_VIEW;
+
+ if (ps->ob == NULL || !(ps->ob->lay & ps->v3d->lay)) {
+ MEM_freeN(ps);
+ return NULL;
+ }
+
+ ps->orig_brush_size = BKE_brush_size_get(ps->scene, ps->brush);
+
+ /* Don't allow brush size below 2 */
+ if (BKE_brush_size_get(ps->scene, ps->brush) < 2)
+ BKE_brush_size_set(ps->scene, ps->brush, 2);
+
+ /* allocate and initialize spatial data structures */
+ project_paint_begin(ps);
+
+ if (ps->dm == NULL) {
+ MEM_freeN(ps);
+ return NULL;
+ }
+
+ paint_proj_begin_clone(ps, mouse);
+
+ return ps;
+}
+
+void paint_proj_stroke_done(void *pps)
+{
+ ProjPaintState *ps = pps;
+ if (ps->tool == PAINT_TOOL_CLONE && ps->mode == BRUSH_STROKE_INVERT) {
+ MEM_freeN(ps);
+ return;
+ }
+ BKE_brush_size_set(ps->scene, ps->brush, ps->orig_brush_size);
+
+ paint_brush_exit_tex(ps->brush);
+
+ project_paint_end(ps);
+ MEM_freeN(ps);
+}
+/* use project paint to re-apply an image */
+static int texture_paint_camera_project_exec(bContext *C, wmOperator *op)
+{
+ Image *image = BLI_findlink(&CTX_data_main(C)->image, RNA_enum_get(op->ptr, "image"));
+ Scene *scene = CTX_data_scene(C);
+ ProjPaintState ps = {NULL};
+ int orig_brush_size;
+ IDProperty *idgroup;
+ IDProperty *view_data = NULL;
+
+ project_state_init(C, OBACT, &ps, BRUSH_STROKE_NORMAL);
+
+ if (ps.ob == NULL || ps.ob->type != OB_MESH) {
+ BKE_report(op->reports, RPT_ERROR, "No active mesh object");
+ return OPERATOR_CANCELLED;
+ }
+
+ if (image == NULL) {
+ BKE_report(op->reports, RPT_ERROR, "Image could not be found");
+ return OPERATOR_CANCELLED;
+ }
+
+ ps.reproject_image = image;
+ ps.reproject_ibuf = BKE_image_acquire_ibuf(image, NULL, NULL);
+
+ if (ps.reproject_ibuf == NULL || ps.reproject_ibuf->rect == NULL) {
+ BKE_report(op->reports, RPT_ERROR, "Image data could not be found");
+ return OPERATOR_CANCELLED;
+ }
+
+ idgroup = IDP_GetProperties(&image->id, 0);
+
+ if (idgroup) {
+ view_data = IDP_GetPropertyTypeFromGroup(idgroup, PROJ_VIEW_DATA_ID, IDP_ARRAY);
+
+ /* type check to make sure its ok */
+ if (view_data->len != PROJ_VIEW_DATA_SIZE || view_data->subtype != IDP_FLOAT) {
+ BKE_report(op->reports, RPT_ERROR, "Image project data invalid");
+ return OPERATOR_CANCELLED;
+ }
+ }
+
+ if (view_data) {
+ /* image has stored view projection info */
+ ps.source = PROJ_SRC_IMAGE_VIEW;
+ }
+ else {
+ ps.source = PROJ_SRC_IMAGE_CAM;
+
+ if (scene->camera == NULL) {
+ BKE_report(op->reports, RPT_ERROR, "No active camera set");
+ return OPERATOR_CANCELLED;
+ }
+ }
+
+ /* override */
+ ps.is_texbrush = 0;
+ ps.do_masking = false;
+ orig_brush_size = BKE_brush_size_get(scene, ps.brush);
+ BKE_brush_size_set(scene, ps.brush, 32); /* cover the whole image */
+
+ ps.tool = PAINT_TOOL_DRAW; /* so pixels are initialized with minimal info */
+
+ scene->toolsettings->imapaint.flag |= IMAGEPAINT_DRAWING;
+
+ undo_paint_push_begin(UNDO_PAINT_IMAGE, op->type->name,
+ image_undo_restore, image_undo_free);
+
+ /* allocate and initialize spatial data structures */
+ project_paint_begin(&ps);
+
+ if (ps.dm == NULL) {
+ BKE_brush_size_set(scene, ps.brush, orig_brush_size);
+ return OPERATOR_CANCELLED;
+ }
+ else {
+ float pos[2] = {0.0, 0.0};
+ float lastpos[2] = {0.0, 0.0};
+ int a;
+
+ for (a = 0; a < ps.image_tot; a++)
+ partial_redraw_array_init(ps.projImages[a].partRedrawRect);
+
+ project_paint_op(&ps, lastpos, pos);
+
+ project_image_refresh_tagged(&ps);
+
+ for (a = 0; a < ps.image_tot; a++) {
+ GPU_free_image(ps.projImages[a].ima);
+ WM_event_add_notifier(C, NC_IMAGE | NA_EDITED, ps.projImages[a].ima);
+ }
+ }
+
+ project_paint_end(&ps);
+
+ scene->toolsettings->imapaint.flag &= ~IMAGEPAINT_DRAWING;
+ BKE_brush_size_set(scene, ps.brush, orig_brush_size);
+
+ return OPERATOR_FINISHED;
+}
+
+void PAINT_OT_project_image(wmOperatorType *ot)
+{
+ PropertyRNA *prop;
+
+ /* identifiers */
+ ot->name = "Project Image";
+ ot->idname = "PAINT_OT_project_image";
+ ot->description = "Project an edited render from the active camera back onto the object";
+
+ /* api callbacks */
+ ot->invoke = WM_enum_search_invoke;
+ ot->exec = texture_paint_camera_project_exec;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+
+ prop = RNA_def_enum(ot->srna, "image", DummyRNA_NULL_items, 0, "Image", "");
+ RNA_def_enum_funcs(prop, RNA_image_itemf);
+ ot->prop = prop;
+}
+
+static int texture_paint_image_from_view_exec(bContext *C, wmOperator *op)
+{
+ Image *image;
+ ImBuf *ibuf;
+ char filename[FILE_MAX];
+
+ Scene *scene = CTX_data_scene(C);
+ ToolSettings *settings = scene->toolsettings;
+ int w = settings->imapaint.screen_grab_size[0];
+ int h = settings->imapaint.screen_grab_size[1];
+ int maxsize;
+ char err_out[256] = "unknown";
+
+ RNA_string_get(op->ptr, "filepath", filename);
+
+ glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxsize);
+
+ if (w > maxsize) w = maxsize;
+ if (h > maxsize) h = maxsize;
+
+ ibuf = ED_view3d_draw_offscreen_imbuf(CTX_data_scene(C), CTX_wm_view3d(C), CTX_wm_region(C), w, h, IB_rect, FALSE, R_ALPHAPREMUL, err_out);
+ if (!ibuf) {
+ /* Mostly happens when OpenGL offscreen buffer was failed to create, */
+ /* but could be other reasons. Should be handled in the future. nazgul */
+ BKE_reportf(op->reports, RPT_ERROR, "Failed to create OpenGL off-screen buffer: %s", err_out);
+ return OPERATOR_CANCELLED;
+ }
+
+ image = BKE_image_add_from_imbuf(ibuf);
+
+ if (image) {
+ /* now for the trickyness. store the view projection here!
+ * re-projection will reuse this */
+ View3D *v3d = CTX_wm_view3d(C);
+ RegionView3D *rv3d = CTX_wm_region_view3d(C);
+
+ IDPropertyTemplate val;
+ IDProperty *idgroup = IDP_GetProperties(&image->id, 1);
+ IDProperty *view_data;
+ bool is_ortho;
+ float *array;
+
+ val.array.len = PROJ_VIEW_DATA_SIZE;
+ val.array.type = IDP_FLOAT;
+ view_data = IDP_New(IDP_ARRAY, &val, PROJ_VIEW_DATA_ID);
+
+ array = (float *)IDP_Array(view_data);
+ memcpy(array, rv3d->winmat, sizeof(rv3d->winmat)); array += sizeof(rv3d->winmat) / sizeof(float);
+ memcpy(array, rv3d->viewmat, sizeof(rv3d->viewmat)); array += sizeof(rv3d->viewmat) / sizeof(float);
+ is_ortho = ED_view3d_clip_range_get(v3d, rv3d, &array[0], &array[1], true);
+ array[2] = is_ortho ? 1.0f : 0.0f; /* using float for a bool is dodgy but since its an extra member in the array... easier then adding a single bool prop */
+
+ IDP_AddToGroup(idgroup, view_data);
+
+ rename_id(&image->id, "image_view");
+ }
+
+ return OPERATOR_FINISHED;
+}
+
+void PAINT_OT_image_from_view(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Image from View";
+ ot->idname = "PAINT_OT_image_from_view";
+ ot->description = "Make an image from the current 3D view for re-projection";
+
+ /* api callbacks */
+ ot->exec = texture_paint_image_from_view_exec;
+ ot->poll = ED_operator_region_view3d_active;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER;
+
+ RNA_def_string_file_name(ot->srna, "filepath", "", FILE_MAX, "File Path", "Name of the file");
+}
diff --git a/source/blender/editors/sculpt_paint/paint_intern.h b/source/blender/editors/sculpt_paint/paint_intern.h
index e7c3ddd071b..a15795dc2da 100644
--- a/source/blender/editors/sculpt_paint/paint_intern.h
+++ b/source/blender/editors/sculpt_paint/paint_intern.h
@@ -50,6 +50,8 @@ struct ViewContext;
struct wmEvent;
struct wmOperator;
struct wmOperatorType;
+struct ImagePaintState;
+enum PaintMode;
/* paint_stroke.c */
typedef int (*StrokeGetLocation)(struct bContext *C, float location[3], const float mouse[2]);
@@ -62,11 +64,14 @@ struct PaintStroke *paint_stroke_new(struct bContext *C,
StrokeUpdateStep update_step, StrokeDone done, int event_type);
void paint_stroke_data_free(struct wmOperator *op);
-bool paint_space_stroke_enabled(struct Brush *br);
-bool paint_supports_dynamic_size(struct Brush *br);
+bool paint_space_stroke_enabled(struct Brush *br, enum PaintMode mode);
+bool paint_supports_dynamic_size(struct Brush *br, enum PaintMode mode);
+bool paint_supports_dynamic_tex_coords(struct Brush *br, enum PaintMode mode);
+bool paint_supports_smooth_stroke(struct Brush *br, enum PaintMode mode);
+bool paint_supports_jitter(enum PaintMode mode);
struct wmKeyMap *paint_stroke_modal_keymap(struct wmKeyConfig *keyconf);
-int paint_stroke_modal(struct bContext *C, struct wmOperator *op, struct wmEvent *event);
+int paint_stroke_modal(struct bContext *C, struct wmOperator *op, const struct wmEvent *event);
int paint_stroke_exec(struct bContext *C, struct wmOperator *op);
int paint_stroke_cancel(struct bContext *C, struct wmOperator *op);
struct ViewContext *paint_stroke_view_context(struct PaintStroke *stroke);
@@ -103,16 +108,46 @@ void PAINT_OT_vertex_paint(struct wmOperatorType *ot);
unsigned int vpaint_get_current_col(struct VPaint *vp);
/* paint_image.c */
+typedef struct ImagePaintPartialRedraw {
+ int x1, y1, x2, y2; /* XXX, could use 'rcti' */
+ int enabled;
+} ImagePaintPartialRedraw;
+
+#define IMAPAINT_TILE_BITS 6
+#define IMAPAINT_TILE_SIZE (1 << IMAPAINT_TILE_BITS)
+#define IMAPAINT_TILE_NUMBER(size) (((size) + IMAPAINT_TILE_SIZE - 1) >> IMAPAINT_TILE_BITS)
+
+#define IMAPAINT_CHAR_TO_FLOAT(c) ((c) / 255.0f)
+
int image_texture_paint_poll(struct bContext *C);
+void *image_undo_push_tile(struct Image *ima, struct ImBuf *ibuf, struct ImBuf **tmpibuf, int x_tile, int y_tile);
+void image_undo_restore(struct bContext *C, struct ListBase *lb);
+void image_undo_free(struct ListBase *lb);
+void imapaint_image_update(struct SpaceImage *sima, struct Image *image, struct ImBuf *ibuf, short texpaint);
+struct ImagePaintPartialRedraw *get_imapaintpartial(void);
+void set_imapaintpartial(struct ImagePaintPartialRedraw * ippr);
+void imapaint_clear_partial_redraw(void);
+void imapaint_dirty_region(struct Image *ima, struct ImBuf *ibuf, int x, int y, int w, int h);
+int get_imapaint_zoom(struct bContext *C, float *zoomx, float *zoomy);
+void *paint_2d_new_stroke(struct bContext *, struct wmOperator *);
+void paint_2d_redraw(const bContext *C, void *ps, int final);
+void paint_2d_stroke_done(void *ps);
+int paint_2d_stroke(void *ps, const int prev_mval[2], const int mval[2], int eraser);
+void *paint_proj_new_stroke(struct bContext *C, struct Object *ob, const int mouse[2], int mode);
+int paint_proj_stroke(struct bContext *C, void *ps, const int prevmval_i[2], const int mval_i[2]);
+void paint_proj_stroke_done(void *ps);
+void paint_brush_init_tex(struct Brush *brush);
+void paint_brush_exit_tex(struct Brush *brush);
-void PAINT_OT_image_paint(struct wmOperatorType *ot);
void PAINT_OT_grab_clone(struct wmOperatorType *ot);
void PAINT_OT_sample_color(struct wmOperatorType *ot);
-void PAINT_OT_clone_cursor_set(struct wmOperatorType *ot);
void PAINT_OT_texture_paint_toggle(struct wmOperatorType *ot);
void PAINT_OT_project_image(struct wmOperatorType *ot);
void PAINT_OT_image_from_view(struct wmOperatorType *ot);
+/* new texture painting */
+void PAINT_OT_image_paint(struct wmOperatorType *ot);
+
/* uv sculpting */
int uv_sculpt_poll(struct bContext *C);
@@ -144,6 +179,7 @@ float paint_calc_object_space_radius(struct ViewContext *vc, const float center[
float paint_get_tex_pixel(struct Brush *br, float u, float v, struct ImagePool *pool);
int imapaint_pick_face(struct ViewContext *vc, const int mval[2], unsigned int *index, unsigned int totface);
void imapaint_pick_uv(struct Scene *scene, struct Object *ob, unsigned int faceindex, const int xy[2], float uv[2]);
+void brush_drawcursor_texpaint_uvsculpt(struct bContext *C, int x, int y, void *customdata);
void paint_sample_color(const struct bContext *C, struct ARegion *ar, int x, int y);
void BRUSH_OT_curve_preset(struct wmOperatorType *ot);
@@ -155,6 +191,7 @@ void PAINT_OT_face_select_hide(struct wmOperatorType *ot);
void PAINT_OT_face_select_reveal(struct wmOperatorType *ot);
void PAINT_OT_vert_select_all(struct wmOperatorType *ot);
+void PAINT_OT_vert_select_ungrouped(struct wmOperatorType *ot);
int vert_paint_poll(struct bContext *C);
int mask_paint_poll(struct bContext *C);
diff --git a/source/blender/editors/sculpt_paint/paint_mask.c b/source/blender/editors/sculpt_paint/paint_mask.c
index dffb8c39bf2..e0b3905b30f 100644
--- a/source/blender/editors/sculpt_paint/paint_mask.c
+++ b/source/blender/editors/sculpt_paint/paint_mask.c
@@ -38,6 +38,7 @@
#include "DNA_meshdata_types.h"
#include "DNA_object_types.h"
+#include "BLI_utildefines.h"
#include "BKE_pbvh.h"
#include "BKE_ccg.h"
#include "BKE_context.h"
diff --git a/source/blender/editors/sculpt_paint/paint_ops.c b/source/blender/editors/sculpt_paint/paint_ops.c
index 7385c2f0cf1..120d0a3b10a 100644
--- a/source/blender/editors/sculpt_paint/paint_ops.c
+++ b/source/blender/editors/sculpt_paint/paint_ops.c
@@ -467,7 +467,6 @@ void ED_operatortypes_paint(void)
WM_operatortype_append(PAINT_OT_image_paint);
WM_operatortype_append(PAINT_OT_sample_color);
WM_operatortype_append(PAINT_OT_grab_clone);
- WM_operatortype_append(PAINT_OT_clone_cursor_set);
WM_operatortype_append(PAINT_OT_project_image);
WM_operatortype_append(PAINT_OT_image_from_view);
@@ -485,6 +484,7 @@ void ED_operatortypes_paint(void)
/* vertex selection */
WM_operatortype_append(PAINT_OT_vert_select_all);
+ WM_operatortype_append(PAINT_OT_vert_select_ungrouped);
/* vertex */
WM_operatortype_append(PAINT_OT_vertex_paint_toggle);
@@ -533,7 +533,7 @@ static void ed_keymap_paint_brush_size(wmKeyMap *keymap, const char *UNUSED(path
typedef enum {
RC_COLOR = 1,
RC_ROTATION = 2,
- RC_ZOOM = 4,
+ RC_ZOOM = 4
} RCFlags;
static void set_brush_rc_path(PointerRNA *ptr, const char *brush_path,
@@ -707,11 +707,17 @@ void ED_keymap_paint(wmKeyConfig *keyconf)
ed_keymap_paint_brush_switch(keymap, "vertex_paint");
ed_keymap_paint_brush_size(keymap, "tool_settings.vertex_paint.brush.size");
- ed_keymap_paint_brush_radial_control(keymap, "vertex_paint", RC_COLOR);
+ ed_keymap_paint_brush_radial_control(keymap, "vertex_paint", RC_COLOR | RC_ROTATION);
kmi = WM_keymap_add_item(keymap, "WM_OT_context_toggle", MKEY, KM_PRESS, 0, 0); /* mask toggle */
RNA_string_set(kmi->ptr, "data_path", "vertex_paint_object.data.use_paint_mask");
+ kmi = WM_keymap_add_item(keymap, "WM_OT_context_toggle", SKEY, KM_PRESS, KM_SHIFT, 0);
+ RNA_string_set(kmi->ptr, "data_path", "tool_settings.vertex_paint.brush.use_smooth_stroke");
+
+ kmi = WM_keymap_add_item(keymap, "WM_OT_context_menu_enum", RKEY, KM_PRESS, 0, 0);
+ RNA_string_set(kmi->ptr, "data_path", "tool_settings.vertex_paint.brush.texture_angle_source_random");
+
/* Weight Paint mode */
keymap = WM_keymap_find(keyconf, "Weight Paint", 0, 0);
keymap->poll = weight_paint_mode_poll;
@@ -741,7 +747,9 @@ void ED_keymap_paint(wmKeyConfig *keyconf)
WM_keymap_verify_item(keymap, "PAINT_OT_weight_from_bones", WKEY, KM_PRESS, 0, 0);
-
+ kmi = WM_keymap_add_item(keymap, "WM_OT_context_toggle", SKEY, KM_PRESS, KM_SHIFT, 0);
+ RNA_string_set(kmi->ptr, "data_path", "tool_settings.weight_paint.brush.use_smooth_stroke");
+
/*Weight paint's Vertex Selection Mode */
keymap = WM_keymap_find(keyconf, "Weight Paint Vertex Selection", 0, 0);
keymap->poll = vert_paint_poll;
@@ -759,18 +767,24 @@ void ED_keymap_paint(wmKeyConfig *keyconf)
keymap = WM_keymap_find(keyconf, "Image Paint", 0, 0);
keymap->poll = image_texture_paint_poll;
- WM_keymap_add_item(keymap, "PAINT_OT_image_paint", LEFTMOUSE, KM_PRESS, 0, 0);
+ RNA_enum_set(WM_keymap_add_item(keymap, "PAINT_OT_image_paint", LEFTMOUSE, KM_PRESS, 0, 0)->ptr, "mode", BRUSH_STROKE_NORMAL);
+ RNA_enum_set(WM_keymap_add_item(keymap, "PAINT_OT_image_paint", LEFTMOUSE, KM_PRESS, KM_CTRL, 0)->ptr, "mode", BRUSH_STROKE_INVERT);
WM_keymap_add_item(keymap, "PAINT_OT_grab_clone", RIGHTMOUSE, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "PAINT_OT_sample_color", RIGHTMOUSE, KM_PRESS, 0, 0);
- WM_keymap_add_item(keymap, "PAINT_OT_clone_cursor_set", LEFTMOUSE, KM_PRESS, KM_CTRL, 0);
ed_keymap_paint_brush_switch(keymap, "image_paint");
ed_keymap_paint_brush_size(keymap, "tool_settings.image_paint.brush.size");
- ed_keymap_paint_brush_radial_control(keymap, "image_paint", RC_COLOR | RC_ZOOM);
+ ed_keymap_paint_brush_radial_control(keymap, "image_paint", RC_COLOR | RC_ZOOM | RC_ROTATION);
kmi = WM_keymap_add_item(keymap, "WM_OT_context_toggle", MKEY, KM_PRESS, 0, 0); /* mask toggle */
RNA_string_set(kmi->ptr, "data_path", "image_paint_object.data.use_paint_mask");
+ kmi = WM_keymap_add_item(keymap, "WM_OT_context_toggle", SKEY, KM_PRESS, KM_SHIFT, 0);
+ RNA_string_set(kmi->ptr, "data_path", "tool_settings.image_paint.brush.use_smooth_stroke");
+
+ kmi = WM_keymap_add_item(keymap, "WM_OT_context_menu_enum", RKEY, KM_PRESS, 0, 0);
+ RNA_string_set(kmi->ptr, "data_path", "tool_settings.image_paint.brush.texture_angle_source_random");
+
/* face-mask mode */
keymap = WM_keymap_find(keyconf, "Face Mask", 0, 0);
keymap->poll = facemask_paint_poll;
diff --git a/source/blender/editors/sculpt_paint/paint_stroke.c b/source/blender/editors/sculpt_paint/paint_stroke.c
index 5d9313485d2..8c5552f48bc 100644
--- a/source/blender/editors/sculpt_paint/paint_stroke.c
+++ b/source/blender/editors/sculpt_paint/paint_stroke.c
@@ -35,6 +35,7 @@
#include "BLI_math.h"
#include "BLI_utildefines.h"
+#include "BLI_rand.h"
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
@@ -91,6 +92,12 @@ typedef struct PaintStroke {
/* event that started stroke, for modal() return */
int event_type;
+ bool brush_init;
+ float initial_mouse[2];
+ float cached_pressure;
+
+ float zoom_2d;
+
StrokeGetLocation get_location;
StrokeTestStart test_start;
StrokeUpdateStep update_step;
@@ -104,23 +111,21 @@ static void paint_draw_smooth_stroke(bContext *C, int x, int y, void *customdata
Brush *brush = paint_brush(paint);
PaintStroke *stroke = customdata;
- glColor4ubv(paint->paint_cursor_col);
- glEnable(GL_LINE_SMOOTH);
- glEnable(GL_BLEND);
-
if (stroke && brush && (brush->flag & BRUSH_SMOOTH_STROKE)) {
- ARegion *ar = CTX_wm_region(C);
- sdrawline(x, y, (int)stroke->last_mouse_position[0] - ar->winrct.xmin,
- (int)stroke->last_mouse_position[1] - ar->winrct.ymin);
+ glColor4ubv(paint->paint_cursor_col);
+ glEnable(GL_LINE_SMOOTH);
+ glEnable(GL_BLEND);
+
+ sdrawline(x, y, (int)stroke->last_mouse_position[0],
+ (int)stroke->last_mouse_position[1]);
+ glDisable(GL_BLEND);
+ glDisable(GL_LINE_SMOOTH);
}
-
- glDisable(GL_BLEND);
- glDisable(GL_LINE_SMOOTH);
}
/* if this is a tablet event, return tablet pressure and set *pen_flip
* to 1 if the eraser tool is being used, 0 otherwise */
-static float event_tablet_data(wmEvent *event, int *pen_flip)
+static float event_tablet_data(const wmEvent *event, int *pen_flip)
{
int erasor = 0;
float pressure = 1;
@@ -138,11 +143,105 @@ static float event_tablet_data(wmEvent *event, int *pen_flip)
return pressure;
}
+
+/* Initialize the stroke cache variants from operator properties */
+static void paint_brush_update(bContext *C, Brush *brush, PaintMode mode,
+ struct PaintStroke *stroke,
+ const float mouse[2], float pressure)
+{
+ Scene *scene = CTX_data_scene(C);
+ UnifiedPaintSettings *ups = &scene->toolsettings->unified_paint_settings;
+
+ /* XXX: Use pressure value from first brush step for brushes which don't
+ * support strokes (grab, thumb). They depends on initial state and
+ * brush coord/pressure/etc.
+ * It's more an events design issue, which doesn't split coordinate/pressure/angle
+ * changing events. We should avoid this after events system re-design */
+ if (paint_supports_dynamic_size(brush, mode) || !stroke->brush_init) {
+ copy_v2_v2(stroke->initial_mouse, mouse);
+ copy_v2_v2(ups->tex_mouse, mouse);
+ stroke->cached_pressure = pressure;
+ }
+
+ /* Truly temporary data that isn't stored in properties */
+
+ ups->draw_pressure = TRUE;
+ ups->pressure_value = stroke->cached_pressure;
+
+ ups->pixel_radius = BKE_brush_size_get(scene, brush);
+
+ if (BKE_brush_use_size_pressure(scene, brush) && paint_supports_dynamic_size(brush, mode)) {
+ ups->pixel_radius *= stroke->cached_pressure;
+ }
+
+ if (!(brush->flag & BRUSH_ANCHORED ||
+ ELEM4(brush->sculpt_tool, SCULPT_TOOL_GRAB, SCULPT_TOOL_SNAKE_HOOK,
+ SCULPT_TOOL_THUMB, SCULPT_TOOL_ROTATE)))
+ {
+ copy_v2_v2(ups->tex_mouse, mouse);
+
+ if ((brush->mtex.brush_map_mode == MTEX_MAP_MODE_VIEW) &&
+ (brush->flag & BRUSH_RANDOM_ROTATION) &&
+ !(brush->flag & BRUSH_RAKE))
+ {
+ ups->brush_rotation = 2.0f * (float)M_PI * BLI_frand();
+ }
+ }
+
+ if (brush->flag & BRUSH_ANCHORED) {
+ bool hit = false;
+ float halfway[2];
+
+ const float dx = mouse[0] - stroke->initial_mouse[0];
+ const float dy = mouse[1] - stroke->initial_mouse[1];
+
+ ups->anchored_size = ups->pixel_radius = sqrt(dx * dx + dy * dy);
+
+ ups->brush_rotation = atan2(dx, dy) + M_PI;
+
+ if (brush->flag & BRUSH_EDGE_TO_EDGE) {
+ float out[3];
+
+ halfway[0] = dx * 0.5f + stroke->initial_mouse[0];
+ halfway[1] = dy * 0.5f + stroke->initial_mouse[1];
+
+ if (stroke->get_location) {
+ if (stroke->get_location(C, out, halfway)) {
+ hit = true;
+ }
+ }
+ else {
+ hit = true;
+ }
+ }
+ if (hit) {
+ copy_v2_v2(ups->anchored_initial_mouse, halfway);
+ copy_v2_v2(ups->tex_mouse, halfway);
+ ups->anchored_size /= 2.0f;
+ ups->pixel_radius /= 2.0f;
+ }
+ else
+ copy_v2_v2(ups->anchored_initial_mouse, stroke->initial_mouse);
+
+ ups->draw_anchored = 1;
+ }
+ else if (brush->flag & BRUSH_RAKE) {
+ if (!stroke->brush_init)
+ copy_v2_v2(ups->last_rake, mouse);
+ else
+ paint_calculate_rake_rotation(ups, mouse);
+ }
+
+ stroke->brush_init = TRUE;
+}
+
+
/* Put the location of the next stroke dot into the stroke RNA and apply it to the mesh */
-static void paint_brush_stroke_add_step(bContext *C, wmOperator *op, wmEvent *event, const float mouse_in[2])
+static void paint_brush_stroke_add_step(bContext *C, wmOperator *op, const wmEvent *event, const float mouse_in[2])
{
Scene *scene = CTX_data_scene(C);
Paint *paint = paint_get_active_from_context(C);
+ PaintMode mode = paintmode_get_active_from_context(C);
Brush *brush = paint_brush(paint);
PaintStroke *stroke = op->customdata;
float mouse_out[2];
@@ -154,19 +253,45 @@ static void paint_brush_stroke_add_step(bContext *C, wmOperator *op, wmEvent *ev
/* see if tablet affects event */
pressure = event_tablet_data(event, &pen_flip);
+/* the following code is adapted from texture paint. It may not be needed but leaving here
+ * just in case for reference (code in texpaint removed as part of refactoring).
+ * It's strange that only texpaint had these guards. */
+#if 0
+ /* special exception here for too high pressure values on first touch in
+ * windows for some tablets, then we just skip first touch .. */
+ if (tablet && (pressure >= 0.99f) && ((pop->s.brush->flag & BRUSH_SPACING_PRESSURE) || BKE_brush_use_alpha_pressure(scene, pop->s.brush) || BKE_brush_use_size_pressure(scene, pop->s.brush)))
+ return;
+
+ /* This can be removed once fixed properly in
+ * BKE_brush_painter_paint(BrushPainter *painter, BrushFunc func, float *pos, double time, float pressure, void *user)
+ * at zero pressure we should do nothing 1/2^12 is 0.0002 which is the sensitivity of the most sensitive pen tablet available */
+ if (tablet && (pressure < 0.0002f) && ((pop->s.brush->flag & BRUSH_SPACING_PRESSURE) || BKE_brush_use_alpha_pressure(scene, pop->s.brush) || BKE_brush_use_size_pressure(scene, pop->s.brush)))
+ return;
+#endif
+
+ /* copy last position -before- jittering, or space fill code
+ * will create too many dabs */
+ copy_v2_v2(stroke->last_mouse_position, mouse_in);
+
+ paint_brush_update(C, brush, mode, stroke, mouse_in, pressure);
+
/* TODO: as sculpt and other paint modes are unified, this
* separation will go away */
- if (stroke->vc.obact->sculpt) {
+ if (paint_supports_jitter(mode)) {
float delta[2];
+ float factor = stroke->zoom_2d;
+
+ if (brush->flag & BRUSH_JITTER_PRESSURE)
+ factor *= pressure;
BKE_brush_jitter_pos(scene, brush, mouse_in, mouse_out);
/* XXX: meh, this is round about because
* BKE_brush_jitter_pos isn't written in the best way to
* be reused here */
- if (brush->flag & BRUSH_JITTER_PRESSURE) {
+ if (factor != 1.0f) {
sub_v2_v2v2(delta, mouse_out, mouse_in);
- mul_v2_fl(delta, pressure);
+ mul_v2_fl(delta, factor);
add_v2_v2v2(mouse_out, mouse_in, delta);
}
}
@@ -188,34 +313,25 @@ static void paint_brush_stroke_add_step(bContext *C, wmOperator *op, wmEvent *ev
RNA_boolean_set(&itemptr, "pen_flip", pen_flip);
RNA_float_set(&itemptr, "pressure", pressure);
- copy_v2_v2(stroke->last_mouse_position, mouse_out);
-
stroke->update_step(C, stroke, &itemptr);
}
/* Returns zero if no sculpt changes should be made, non-zero otherwise */
static int paint_smooth_stroke(PaintStroke *stroke, float output[2],
- const PaintSample *sample)
+ const PaintSample *sample, PaintMode mode)
{
output[0] = sample->mouse[0];
output[1] = sample->mouse[1];
- if ((stroke->brush->flag & BRUSH_SMOOTH_STROKE) &&
- !ELEM4(stroke->brush->sculpt_tool,
- SCULPT_TOOL_GRAB,
- SCULPT_TOOL_THUMB,
- SCULPT_TOOL_ROTATE,
- SCULPT_TOOL_SNAKE_HOOK) &&
- !(stroke->brush->flag & BRUSH_ANCHORED) &&
- !(stroke->brush->flag & BRUSH_RESTORE_MESH))
- {
+ if (paint_supports_smooth_stroke(stroke->brush, mode)) {
+ float radius = stroke->brush->smooth_stroke_radius * stroke->zoom_2d;
float u = stroke->brush->smooth_stroke_factor, v = 1.0f - u;
float dx = stroke->last_mouse_position[0] - sample->mouse[0];
float dy = stroke->last_mouse_position[1] - sample->mouse[1];
/* If the mouse is moving within the radius of the last move,
* don't update the mouse position. This allows sharp turns. */
- if (dx * dx + dy * dy < stroke->brush->smooth_stroke_radius * stroke->brush->smooth_stroke_radius)
+ if (dx * dx + dy * dy < radius * radius)
return 0;
output[0] = sample->mouse[0] * v + stroke->last_mouse_position[0] * u;
@@ -227,12 +343,14 @@ static int paint_smooth_stroke(PaintStroke *stroke, float output[2],
/* For brushes with stroke spacing enabled, moves mouse in steps
* towards the final mouse location. */
-static int paint_space_stroke(bContext *C, wmOperator *op, wmEvent *event, const float final_mouse[2])
+static int paint_space_stroke(bContext *C, wmOperator *op, const wmEvent *event, const float final_mouse[2])
{
PaintStroke *stroke = op->customdata;
+ PaintMode mode = paintmode_get_active_from_context(C);
+
int cnt = 0;
- if (paint_space_stroke_enabled(stroke->brush)) {
+ if (paint_space_stroke_enabled(stroke->brush, mode)) {
float mouse[2];
float vec[2];
float length, scale;
@@ -246,17 +364,28 @@ static int paint_space_stroke(bContext *C, wmOperator *op, wmEvent *event, const
const Scene *scene = CTX_data_scene(C);
int steps;
int i;
- float pressure = 1.0f;
+ float size_pressure = 1.0f;
+ float pressure = event_tablet_data(event, NULL);
/* XXX mysterious :) what has 'use size' do with this here... if you don't check for it, pressure fails */
if (BKE_brush_use_size_pressure(scene, stroke->brush))
- pressure = event_tablet_data(event, NULL);
+ size_pressure = pressure;
- if (pressure > FLT_EPSILON) {
+ if (size_pressure > FLT_EPSILON) {
/* brushes can have a minimum size of 1.0 but with pressure it can be smaller then a pixel
* causing very high step sizes, hanging blender [#32381] */
- const float size_clamp = max_ff(1.0f, BKE_brush_size_get(scene, stroke->brush) * pressure);
- scale = (size_clamp * stroke->brush->spacing / 50.0f) / length;
+ const float size_clamp = max_ff(1.0f, BKE_brush_size_get(scene, stroke->brush) * size_pressure);
+ float spacing = stroke->brush->spacing;
+
+ /* stroke system is used for 2d paint too, so we need to account for
+ * the fact that brush can be scaled there. */
+
+ if (stroke->brush->flag & BRUSH_SPACING_PRESSURE)
+ spacing = max_ff(1.0f, spacing * (1.5f - pressure));
+
+ spacing *= stroke->zoom_2d;
+
+ scale = (size_clamp * spacing / 50.0f) / length;
if (scale > FLT_EPSILON) {
mul_v2_fl(vec, scale);
@@ -286,7 +415,8 @@ PaintStroke *paint_stroke_new(bContext *C,
stroke->brush = paint_brush(paint_get_active_from_context(C));
view3d_set_viewcontext(C, &stroke->vc);
- view3d_get_transformation(stroke->vc.ar, stroke->vc.rv3d, stroke->vc.obact, &stroke->mats);
+ if (stroke->vc.v3d)
+ view3d_get_transformation(stroke->vc.ar, stroke->vc.rv3d, stroke->vc.obact, &stroke->mats);
stroke->get_location = get_location;
stroke->test_start = test_start;
@@ -324,16 +454,77 @@ static void stroke_done(struct bContext *C, struct wmOperator *op)
}
/* Returns zero if the stroke dots should not be spaced, non-zero otherwise */
-bool paint_space_stroke_enabled(Brush *br)
+bool paint_space_stroke_enabled(Brush *br, PaintMode mode)
+{
+ return (br->flag & BRUSH_SPACE) && paint_supports_dynamic_size(br, mode);
+}
+
+/* return true if the brush size can change during paint (normally used for pressure) */
+bool paint_supports_dynamic_size(Brush *br, PaintMode mode)
{
- return (br->flag & BRUSH_SPACE) && paint_supports_dynamic_size(br);
+ if (br->flag & BRUSH_ANCHORED)
+ return false;
+
+ switch (mode) {
+ case PAINT_SCULPT:
+ if (ELEM4(br->sculpt_tool,
+ SCULPT_TOOL_GRAB,
+ SCULPT_TOOL_THUMB,
+ SCULPT_TOOL_ROTATE,
+ SCULPT_TOOL_SNAKE_HOOK))
+ {
+ return false;
+ }
+ default:
+ ;
+ }
+ return true;
+}
+
+bool paint_supports_smooth_stroke(Brush *br, PaintMode mode)
+{
+ if (!(br->flag & BRUSH_SMOOTH_STROKE) ||
+ (br->flag & BRUSH_ANCHORED) ||
+ (br->flag & BRUSH_RESTORE_MESH))
+ {
+ return false;
+ }
+
+ switch (mode) {
+ case PAINT_SCULPT:
+ if (ELEM4(br->sculpt_tool,
+ SCULPT_TOOL_GRAB,
+ SCULPT_TOOL_THUMB,
+ SCULPT_TOOL_ROTATE,
+ SCULPT_TOOL_SNAKE_HOOK))
+ {
+ return false;
+ }
+ default:
+ ;
+ }
+ return true;
}
/* return true if the brush size can change during paint (normally used for pressure) */
-bool paint_supports_dynamic_size(Brush *br)
+bool paint_supports_dynamic_tex_coords(Brush *br, PaintMode mode)
{
- return !(br->flag & BRUSH_ANCHORED) &&
- !ELEM4(br->sculpt_tool, SCULPT_TOOL_GRAB, SCULPT_TOOL_THUMB, SCULPT_TOOL_ROTATE, SCULPT_TOOL_SNAKE_HOOK);
+ if (br->flag & BRUSH_ANCHORED)
+ return false;
+
+ switch (mode) {
+ case PAINT_SCULPT:
+ if (ELEM4(br->sculpt_tool, SCULPT_TOOL_GRAB, SCULPT_TOOL_THUMB, SCULPT_TOOL_ROTATE, SCULPT_TOOL_SNAKE_HOOK))
+ return false;
+ default:
+ ;
+ }
+ return true;
+}
+
+bool paint_supports_jitter(PaintMode mode)
+{
+ return ELEM3(mode, PAINT_SCULPT, PAINT_TEXTURE_PROJECTIVE, PAINT_TEXTURE_2D);
}
#define PAINT_STROKE_MODAL_CANCEL 1
@@ -400,17 +591,22 @@ static void paint_stroke_sample_average(const PaintStroke *stroke,
/*printf("avg=(%f, %f), num=%d\n", average->mouse[0], average->mouse[1], stroke->num_samples);*/
}
-int paint_stroke_modal(bContext *C, wmOperator *op, wmEvent *event)
+int paint_stroke_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
Paint *p = paint_get_active_from_context(C);
+ PaintMode mode = paintmode_get_active_from_context(C);
PaintStroke *stroke = op->customdata;
PaintSample sample_average;
float mouse[2];
int first = 0;
+ float zoomx, zoomy;
- paint_stroke_add_sample(p, stroke, event->x, event->y);
+ paint_stroke_add_sample(p, stroke, event->mval[0], event->mval[1]);
paint_stroke_sample_average(stroke, &sample_average);
+ get_imapaint_zoom(C, &zoomx, &zoomy);
+ stroke->zoom_2d = max_ff(zoomx, zoomy);
+
/* let NDOF motion pass through to the 3D view so we can paint and rotate simultaneously!
* this isn't perfect... even when an extra MOUSEMOVE is spoofed, the stroke discards it
* since the 2D deltas are zero -- code in this file needs to be updated to use the
@@ -452,8 +648,8 @@ int paint_stroke_modal(bContext *C, wmOperator *op, wmEvent *event)
(event->type == TIMER && (event->customdata == stroke->timer)) )
{
if (stroke->stroke_started) {
- if (paint_smooth_stroke(stroke, mouse, &sample_average)) {
- if (paint_space_stroke_enabled(stroke->brush)) {
+ if (paint_smooth_stroke(stroke, mouse, &sample_average, mode)) {
+ if (paint_space_stroke_enabled(stroke->brush, mode)) {
if (!paint_space_stroke(C, op, event, mouse)) {
//ED_region_tag_redraw(ar);
}
@@ -472,7 +668,7 @@ int paint_stroke_modal(bContext *C, wmOperator *op, wmEvent *event)
* instead of waiting till we have moved the space distance */
if (first &&
stroke->stroke_started &&
- paint_space_stroke_enabled(stroke->brush) &&
+ paint_space_stroke_enabled(stroke->brush, mode) &&
!(stroke->brush->flag & BRUSH_ANCHORED) &&
!(stroke->brush->flag & BRUSH_SMOOTH_STROKE))
{
diff --git a/source/blender/editors/sculpt_paint/paint_utils.c b/source/blender/editors/sculpt_paint/paint_utils.c
index dc3f310b405..5e88c7b5730 100644
--- a/source/blender/editors/sculpt_paint/paint_utils.c
+++ b/source/blender/editors/sculpt_paint/paint_utils.c
@@ -47,6 +47,7 @@
#include "BKE_context.h"
#include "BKE_DerivedMesh.h"
#include "BKE_paint.h"
+#include "BKE_report.h"
#include "RNA_access.h"
#include "RNA_define.h"
@@ -160,12 +161,12 @@ float paint_calc_object_space_radius(ViewContext *vc, const float center[3],
Object *ob = vc->obact;
float delta[3], scale, loc[3];
const float mval_f[2] = {pixel_radius, 0.0f};
+ float zfac;
mul_v3_m4v3(loc, ob->obmat, center);
- initgrabz(vc->rv3d, loc[0], loc[1], loc[2]);
-
- ED_view3d_win_to_delta(vc->ar, mval_f, delta);
+ zfac = ED_view3d_calc_zfac(vc->rv3d, loc, NULL);
+ ED_view3d_win_to_delta(vc->ar, mval_f, delta, zfac);
scale = fabsf(mat4_to_scale(ob->obmat));
scale = (scale == 0.0f) ? 1.0f : scale;
@@ -414,7 +415,7 @@ void PAINT_OT_face_select_linked(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
-static int paint_select_linked_pick_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int paint_select_linked_pick_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
int mode = RNA_boolean_get(op->ptr, "extend") ? 1 : 0;
paintface_select_linked(C, CTX_data_active_object(C), event->mval, mode);
@@ -484,6 +485,39 @@ void PAINT_OT_vert_select_all(wmOperatorType *ot)
WM_operator_properties_select_all(ot);
}
+
+static int vert_select_ungrouped_exec(bContext *C, wmOperator *op)
+{
+ Object *ob = CTX_data_active_object(C);
+ Mesh *me = ob->data;
+
+ if ((ob->defbase.first == NULL) || (me->dvert == NULL)) {
+ BKE_report(op->reports, RPT_ERROR, "No weights/vertex groups on object");
+ return OPERATOR_CANCELLED;
+ }
+
+ paintvert_select_ungrouped(ob, RNA_boolean_get(op->ptr, "extend"), TRUE);
+ ED_region_tag_redraw(CTX_wm_region(C));
+ return OPERATOR_FINISHED;
+}
+
+void PAINT_OT_vert_select_ungrouped(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Select Ungrouped";
+ ot->idname = "PAINT_OT_vert_select_ungrouped";
+ ot->description = "Select vertices without a group";
+
+ /* api callbacks */
+ ot->exec = vert_select_ungrouped_exec;
+ ot->poll = vert_paint_poll;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+
+ RNA_def_boolean(ot->srna, "extend", false, "Extend", "Extend the selection");
+}
+
static int face_select_hide_exec(bContext *C, wmOperator *op)
{
const int unselected = RNA_boolean_get(op->ptr, "unselected");
diff --git a/source/blender/editors/sculpt_paint/paint_vertex.c b/source/blender/editors/sculpt_paint/paint_vertex.c
index 0277e1e11dc..2bdcda1430d 100644
--- a/source/blender/editors/sculpt_paint/paint_vertex.c
+++ b/source/blender/editors/sculpt_paint/paint_vertex.c
@@ -43,6 +43,7 @@
#include "BLI_blenlib.h"
#include "BLI_math.h"
+#include "BLI_math_color.h"
#include "BLI_memarena.h"
#include "BLI_utildefines.h"
#include "BLI_ghash.h"
@@ -854,36 +855,46 @@ 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 co[3],
- const float mval[2], const float brush_size_pressure)
+static float calc_vp_strength_col_dl(VPaint *vp, ViewContext *vc, const float co[3],
+ const float mval[2], const float brush_size_pressure, float rgba[4])
{
- float vertco[2];
+ float co_ss[2]; /* screenspace */
if (ED_view3d_project_float_object(vc->ar,
- co, vertco,
+ co, co_ss,
V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_NEAR) == V3D_PROJ_RET_OK)
{
float delta[2];
float dist_squared;
- sub_v2_v2v2(delta, mval, vertco);
+ sub_v2_v2v2(delta, mval, co_ss);
dist_squared = dot_v2v2(delta, delta); /* len squared */
if (dist_squared <= brush_size_pressure * brush_size_pressure) {
Brush *brush = paint_brush(&vp->paint);
const float dist = sqrtf(dist_squared);
+ if (brush->mtex.tex && rgba) {
+ if (brush->mtex.brush_map_mode == MTEX_MAP_MODE_3D) {
+ BKE_brush_sample_tex_3D(vc->scene, brush, co, rgba, 0, NULL);
+ }
+ else {
+ const float co_ss_3d[3] = {co_ss[0], co_ss[1], 0.0f}; /* we need a 3rd empty value */
+ BKE_brush_sample_tex_3D(vc->scene, brush, co_ss_3d, rgba, 0, NULL);
+ }
+ }
return BKE_brush_curve_strength_clamp(brush, dist, brush_size_pressure);
}
}
-
+ if (rgba)
+ zero_v4(rgba);
return 0.0f;
}
-static float calc_vp_alpha_dl(VPaint *vp, ViewContext *vc,
+static float calc_vp_alpha_col_dl(VPaint *vp, ViewContext *vc,
float vpimat[3][3], const DMCoNo *v_co_no,
const float mval[2],
- const float brush_size_pressure, const float brush_alpha_pressure)
+ const float brush_size_pressure, const float brush_alpha_pressure, float rgba[4])
{
- float strength = calc_vp_strength_dl(vp, vc, v_co_no->co, mval, brush_size_pressure);
+ float strength = calc_vp_strength_col_dl(vp, vc, v_co_no->co, mval, brush_size_pressure, rgba);
if (strength > 0.0f) {
float alpha = brush_alpha_pressure * strength;
@@ -1015,7 +1026,7 @@ static float wpaint_blend(VPaint *wp, float weight, float weight_prev,
/* sets wp->weight to the closest weight value to vertex */
/* note: we cant sample frontbuf, weight colors are interpolated too unpredictable */
-static int weight_sample_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int weight_sample_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
ViewContext vc;
Mesh *me;
@@ -1467,7 +1478,7 @@ static void enforce_locks(MDeformVert *odv, MDeformVert *ndv,
MDeformWeight *ndw;
MDeformWeight *odw;
- float changed_sum = 0.0f;
+ // float changed_sum = 0.0f; // UNUSED
char *change_status;
@@ -1496,7 +1507,7 @@ static void enforce_locks(MDeformVert *odv, MDeformVert *ndv,
}
else if (ndw->weight != odw->weight) { /* changed groups are handled here */
totchange += ndw->weight - odw->weight;
- changed_sum += ndw->weight;
+ // changed_sum += ndw->weight; // UNUSED
change_status[i] = 2; /* was altered already */
total_changed++;
} /* unchanged, unlocked bone groups are handled here */
@@ -2239,11 +2250,6 @@ static void wpaint_stroke_update_step(bContext *C, struct PaintStroke *stroke, P
mult_m4_m4m4(mat, vc->rv3d->persmat, ob->obmat);
RNA_float_get_array(itemptr, "mouse", mval);
- mval[0] -= vc->ar->winrct.xmin;
- mval[1] -= vc->ar->winrct.ymin;
-
-
-
/* *** setup WeightPaintInfo - pass onto do_weight_paint_vertex *** */
wpi.defbase_tot = wpd->defbase_tot;
@@ -2312,7 +2318,7 @@ static void wpaint_stroke_update_step(bContext *C, struct PaintStroke *stroke, P
#define WP_BLUR_ACCUM(v_idx_var) \
{ \
const unsigned int vidx = v_idx_var; \
- const float fac = calc_vp_strength_dl(wp, vc, wpd->vertexcosnos[vidx].co, mval, brush_size_pressure); \
+ const float fac = calc_vp_strength_col_dl(wp, vc, wpd->vertexcosnos[vidx].co, mval, brush_size_pressure, NULL); \
if (fac > 0.0f) { \
MDeformWeight *dw = dw_func(&me->dvert[vidx], wpi.vgroup_active); \
paintweight += dw ? (dw->weight * fac) : 0.0f; \
@@ -2382,8 +2388,8 @@ static void wpaint_stroke_update_step(bContext *C, struct PaintStroke *stroke, P
{ \
unsigned int vidx = v_idx_var; \
if (me->dvert[vidx].flag) { \
- alpha = calc_vp_alpha_dl(wp, vc, wpd->wpimat, &wpd->vertexcosnos[vidx], \
- mval, brush_size_pressure, brush_alpha_pressure); \
+ alpha = calc_vp_alpha_col_dl(wp, vc, wpd->wpimat, &wpd->vertexcosnos[vidx], \
+ mval, brush_size_pressure, brush_alpha_pressure, NULL); \
if (alpha) { \
do_weight_paint_vertex(wp, ob, &wpi, vidx, alpha, paintweight); \
} \
@@ -2480,7 +2486,7 @@ static void wpaint_stroke_done(const bContext *C, struct PaintStroke *stroke)
}
-static int wpaint_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int wpaint_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
int retval;
@@ -2667,6 +2673,8 @@ typedef struct VPaintData {
/* mpoly -> mface mapping */
MemArena *polyfacemap_arena;
ListBase *polyfacemap;
+
+ bool is_texbrush;
} VPaintData;
static void vpaint_build_poly_facemap(struct VPaintData *vd, Mesh *me)
@@ -2703,6 +2711,7 @@ static int vpaint_stroke_test_start(bContext *C, struct wmOperator *op, const fl
ToolSettings *ts = CTX_data_tool_settings(C);
struct PaintStroke *stroke = op->customdata;
VPaint *vp = ts->vpaint;
+ Brush *brush = paint_brush(&vp->paint);
struct VPaintData *vpd;
Object *ob = CTX_data_active_object(C);
Mesh *me;
@@ -2732,6 +2741,8 @@ static int vpaint_stroke_test_start(bContext *C, struct wmOperator *op, const fl
vpd->indexar = get_indexarray(me);
vpd->paintcol = vpaint_get_current_col(vp);
+ vpd->is_texbrush = !(brush->vertexpaint_tool == PAINT_BLEND_BLUR) &&
+ brush->mtex.tex;
/* are we painting onto a modified mesh?,
* if not we can skip face map trickyness */
@@ -2808,12 +2819,24 @@ static void vpaint_paint_poly(VPaint *vp, VPaintData *vpd, Mesh *me,
ml = me->mloop + mpoly->loopstart;
for (i = 0; i < mpoly->totloop; i++, ml++) {
- alpha = calc_vp_alpha_dl(vp, vc, vpd->vpimat,
+ float rgba[4];
+ unsigned int paintcol;
+ alpha = calc_vp_alpha_col_dl(vp, vc, vpd->vpimat,
&vpd->vertexcosnos[ml->v], mval,
- brush_size_pressure, brush_alpha_pressure);
+ brush_size_pressure, brush_alpha_pressure, rgba);
+
+ if (vpd->is_texbrush) {
+ float rgba_br[3];
+ rgb_uchar_to_float(rgba_br, (const unsigned char *)&vpd->paintcol);
+ mul_v3_v3(rgba_br, rgba);
+ rgb_float_to_uchar((unsigned char *)&paintcol, rgba_br);
+ }
+ else
+ paintcol = vpd->paintcol;
+
if (alpha > 0.0f) {
const int alpha_i = (int)(alpha * 255.0f);
- lcol[i] = vpaint_blend(vp, lcol[i], lcolorig[i], vpd->paintcol, alpha_i, brush_alpha_pressure_i);
+ lcol[i] = vpaint_blend(vp, lcol[i], lcolorig[i], paintcol, alpha_i, brush_alpha_pressure_i);
}
}
@@ -2872,10 +2895,6 @@ static void vpaint_stroke_update_step(bContext *C, struct PaintStroke *stroke, P
/* load projection matrix */
mult_m4_m4m4(mat, vc->rv3d->persmat, ob->obmat);
- mval[0] -= vc->ar->winrct.xmin;
- mval[1] -= vc->ar->winrct.ymin;
-
-
/* which faces are involved */
if (vp->flag & VP_AREA) {
totindex = sample_backbuf_area(vc, indexar, me->totpoly, mval[0], mval[1], brush_size_pressure);
@@ -2959,7 +2978,7 @@ static void vpaint_stroke_done(const bContext *C, struct PaintStroke *stroke)
MEM_freeN(vpd);
}
-static int vpaint_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int vpaint_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
int retval;
@@ -3165,7 +3184,7 @@ static void gradientVert__mapFunc(void *userData, int index, const float co[3],
}
}
-static int paint_weight_gradient_modal(bContext *C, wmOperator *op, wmEvent *event)
+static int paint_weight_gradient_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
int ret = WM_gesture_straightline_modal(C, op, event);
@@ -3273,7 +3292,7 @@ static int paint_weight_gradient_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int paint_weight_gradient_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int paint_weight_gradient_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
int ret;
diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c
index 90e7645032b..376622e95a6 100644
--- a/source/blender/editors/sculpt_paint/sculpt.c
+++ b/source/blender/editors/sculpt_paint/sculpt.c
@@ -43,6 +43,8 @@
#include "BLI_threads.h"
#include "BLI_rand.h"
+#include "BLF_translation.h"
+
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
#include "DNA_node_types.h"
@@ -243,7 +245,6 @@ typedef struct StrokeCache {
float pressure;
float mouse[2];
float bstrength;
- float tex_mouse[2];
/* The rest is temporary storage that isn't saved as a property */
@@ -257,8 +258,8 @@ typedef struct StrokeCache {
Brush *brush;
float (*face_norms)[3]; /* Copy of the mesh faces' normals */
- float special_rotation; /* Texture rotation (radians) for anchored and rake modes */
- int pixel_radius, previous_pixel_radius;
+
+ float special_rotation;
float grab_delta[3], grab_delta_symmetry[3];
float old_grab_location[3], orig_grab_location[3];
@@ -282,8 +283,8 @@ typedef struct StrokeCache {
int radial_symmetry_pass;
float symm_rot_mat[4][4];
float symm_rot_mat_inv[4][4];
- float last_rake[2]; /* Last location of updating rake rotation */
int original;
+ float anchored_location[3];
float vertex_rotation;
@@ -316,8 +317,8 @@ typedef struct {
/* Initialize a SculptOrigVertData for accessing original vertex data;
* handles BMesh, mesh, and multires */
static void sculpt_orig_vert_data_unode_init(SculptOrigVertData *data,
- Object *ob,
- SculptUndoNode *unode)
+ Object *ob,
+ SculptUndoNode *unode)
{
SculptSession *ss = ob->sculpt;
BMesh *bm = ss->bm;
@@ -338,19 +339,18 @@ static void sculpt_orig_vert_data_unode_init(SculptOrigVertData *data,
/* Initialize a SculptOrigVertData for accessing original vertex data;
* handles BMesh, mesh, and multires */
static void sculpt_orig_vert_data_init(SculptOrigVertData *data,
- Object *ob,
- PBVHNode *node)
+ Object *ob,
+ PBVHNode *node)
{
SculptUndoNode *unode;
unode = sculpt_undo_push_node(ob, node, SCULPT_UNDO_COORDS);
sculpt_orig_vert_data_unode_init(data, ob, unode);
-
}
/* Update a SculptOrigVertData for a particular vertex from the PBVH
* iterator */
static void sculpt_orig_vert_data_update(SculptOrigVertData *orig_data,
- PBVHVertexIter *iter)
+ PBVHVertexIter *iter)
{
if (orig_data->unode->type == SCULPT_UNDO_COORDS) {
if (orig_data->coords) {
@@ -387,30 +387,30 @@ static void sculpt_orig_vert_data_update(SculptOrigVertData *orig_data,
Others, like smooth, are better without. Same goes for alt-
key smoothing. */
static int sculpt_stroke_dynamic_topology(const SculptSession *ss,
- const Brush *brush)
+ const Brush *brush)
{
return ((BKE_pbvh_type(ss->pbvh) == PBVH_BMESH) &&
- (!ss->cache || (!ss->cache->alt_smooth)) &&
-
- /* Requires mesh restore, which doesn't work with
- * dynamic-topology */
- !(brush->flag & BRUSH_ANCHORED) &&
- !(brush->flag & BRUSH_RESTORE_MESH) &&
+ (!ss->cache || (!ss->cache->alt_smooth)) &&
- (!ELEM6(brush->sculpt_tool,
- /* These brushes, as currently coded, cannot
- * support dynamic topology */
- SCULPT_TOOL_GRAB,
- SCULPT_TOOL_ROTATE,
- SCULPT_TOOL_THUMB,
- SCULPT_TOOL_LAYER,
+ /* Requires mesh restore, which doesn't work with
+ * dynamic-topology */
+ !(brush->flag & BRUSH_ANCHORED) &&
+ !(brush->flag & BRUSH_RESTORE_MESH) &&
+
+ (!ELEM6(brush->sculpt_tool,
+ /* These brushes, as currently coded, cannot
+ * support dynamic topology */
+ SCULPT_TOOL_GRAB,
+ SCULPT_TOOL_ROTATE,
+ SCULPT_TOOL_THUMB,
+ SCULPT_TOOL_LAYER,
- /* These brushes could handle dynamic topology,
- * but user feedback indicates it's better not
- * to */
- SCULPT_TOOL_SMOOTH,
- SCULPT_TOOL_MASK)));
+ /* These brushes could handle dynamic topology,
+ * but user feedback indicates it's better not
+ * to */
+ SCULPT_TOOL_SMOOTH,
+ SCULPT_TOOL_MASK)));
}
/*** paint mesh ***/
@@ -439,7 +439,7 @@ static void paint_mesh_restore_co(Sculpt *sd, Object *ob)
for (n = 0; n < totnode; n++) {
SculptUndoNode *unode;
SculptUndoType type = (brush->sculpt_tool == SCULPT_TOOL_MASK ?
- SCULPT_UNDO_MASK : SCULPT_UNDO_COORDS);
+ SCULPT_UNDO_MASK : SCULPT_UNDO_COORDS);
if (ss->bm) {
unode = sculpt_undo_push_node(ob, nodes[n], type);
@@ -545,13 +545,32 @@ typedef struct SculptBrushTest {
float radius_squared;
float location[3];
float dist;
+
+ /* View3d clipping - only set rv3d for clipping */
+ RegionView3D *clip_rv3d;
} SculptBrushTest;
static void sculpt_brush_test_init(SculptSession *ss, SculptBrushTest *test)
{
+ RegionView3D *rv3d = ss->cache->vc->rv3d;
+
test->radius_squared = ss->cache->radius_squared;
copy_v3_v3(test->location, ss->cache->location);
test->dist = 0.0f; /* just for initialize */
+
+
+ if (rv3d->rflag & RV3D_CLIPPING) {
+ test->clip_rv3d = rv3d;
+ }
+ else {
+ test->clip_rv3d = NULL;
+ }
+}
+
+BLI_INLINE bool sculpt_brush_test_clipping(SculptBrushTest *test, const float co[3])
+{
+ RegionView3D *rv3d = test->clip_rv3d;
+ return (rv3d && (ED_view3d_clipping_test(rv3d, co, true)));
}
static int sculpt_brush_test(SculptBrushTest *test, const float co[3])
@@ -559,6 +578,9 @@ static int sculpt_brush_test(SculptBrushTest *test, const float co[3])
float distsq = len_squared_v3v3(co, test->location);
if (distsq <= test->radius_squared) {
+ if (sculpt_brush_test_clipping(test, co)) {
+ return 0;
+ }
test->dist = sqrt(distsq);
return 1;
}
@@ -572,6 +594,9 @@ static int sculpt_brush_test_sq(SculptBrushTest *test, const float co[3])
float distsq = len_squared_v3v3(co, test->location);
if (distsq <= test->radius_squared) {
+ if (sculpt_brush_test_clipping(test, co)) {
+ return 0;
+ }
test->dist = distsq;
return 1;
}
@@ -582,6 +607,9 @@ static int sculpt_brush_test_sq(SculptBrushTest *test, const float co[3])
static int sculpt_brush_test_fast(SculptBrushTest *test, float co[3])
{
+ if (sculpt_brush_test_clipping(test, co)) {
+ return 0;
+ }
return len_squared_v3v3(co, test->location) <= test->radius_squared;
}
@@ -590,6 +618,10 @@ static int sculpt_brush_test_cube(SculptBrushTest *test, float co[3], float loca
float side = M_SQRT1_2;
float local_co[3];
+ if (sculpt_brush_test_clipping(test, co)) {
+ return 0;
+ }
+
mul_v3_m4v3(local_co, local, co);
local_co[0] = fabs(local_co[0]);
@@ -890,25 +922,22 @@ static float tex_strength(SculptSession *ss, Brush *br,
const float fno[3],
const float mask)
{
+ const Scene *scene = ss->cache->vc->scene;
MTex *mtex = &br->mtex;
float avg = 1;
+ float rgba[4];
if (!mtex->tex) {
avg = 1;
}
else if (mtex->brush_map_mode == MTEX_MAP_MODE_3D) {
- float jnk;
-
/* Get strength by feeding the vertex
* location directly into a texture */
- externtex(mtex, point, &avg,
- &jnk, &jnk, &jnk, &jnk, 0, ss->tex_pool);
+ avg = BKE_brush_sample_tex_3D(scene, br, point, rgba, 0, ss->tex_pool);
}
else if (ss->texcache) {
- float rotation = -mtex->rot;
float symm_point[3], point_2d[2];
float x = 0.0f, y = 0.0f; /* Quite warnings */
- float radius = 1.0f; /* Quite warnings */
/* if the active area is being applied for symmetry, flip it
* across the symmetry axis and rotate it back to the original
@@ -922,77 +951,33 @@ static float tex_strength(SculptSession *ss, Brush *br,
ED_view3d_project_float_v2_m4(ss->cache->vc->ar, symm_point, point_2d, ss->cache->projection_mat);
- if (mtex->brush_map_mode == MTEX_MAP_MODE_VIEW) {
- /* keep coordinates relative to mouse */
-
- rotation += ss->cache->special_rotation;
-
- point_2d[0] -= ss->cache->tex_mouse[0];
- point_2d[1] -= ss->cache->tex_mouse[1];
-
- /* use pressure adjusted size for fixed mode */
- radius = ss->cache->pixel_radius;
-
- x = point_2d[0] + ss->cache->vc->ar->winrct.xmin;
- y = point_2d[1] + ss->cache->vc->ar->winrct.ymin;
- }
- else if (mtex->brush_map_mode == MTEX_MAP_MODE_TILED) {
- /* leave the coordinates relative to the screen */
-
- /* use unadjusted size for tiled mode */
- radius = BKE_brush_size_get(ss->cache->vc->scene, br);
-
- x = point_2d[0];
- y = point_2d[1];
- }
- else if (mtex->brush_map_mode == MTEX_MAP_MODE_AREA) {
+ /* still no symmetry supported for other paint modes.
+ * Sculpt does it DIY */
+ if (mtex->brush_map_mode == MTEX_MAP_MODE_AREA) {
/* Similar to fixed mode, but projects from brush angle
* rather than view direction */
- /* Rotation is handled by the brush_local_mat */
- rotation = 0;
-
mul_m4_v3(ss->cache->brush_local_mat, symm_point);
x = symm_point[0];
y = symm_point[1];
- }
- if (mtex->brush_map_mode != MTEX_MAP_MODE_AREA) {
- x /= ss->cache->vc->ar->winx;
- y /= ss->cache->vc->ar->winy;
+ x *= br->mtex.size[0];
+ y *= br->mtex.size[1];
- if (mtex->brush_map_mode == MTEX_MAP_MODE_TILED) {
- x -= 0.5f;
- y -= 0.5f;
- }
-
- x *= ss->cache->vc->ar->winx / radius;
- y *= ss->cache->vc->ar->winy / radius;
- }
+ x += br->mtex.ofs[0];
+ y += br->mtex.ofs[1];
- /* it is probably worth optimizing for those cases where
- * the texture is not rotated by skipping the calls to
- * atan2, sqrtf, sin, and cos. */
- if (rotation > 0.001f || rotation < -0.001f) {
- const float angle = atan2f(y, x) + rotation;
- const float flen = sqrtf(x * x + y * y);
+ avg = paint_get_tex_pixel(br, x, y, ss->tex_pool);
- x = flen * cosf(angle);
- y = flen * sinf(angle);
+ avg += br->texture_sample_bias;
+ }
+ else {
+ const float point_3d[3] = {point_2d[0], point_2d[1], 0.0f};
+ avg = BKE_brush_sample_tex_3D(scene, br, point_3d, rgba, 0, ss->tex_pool);
}
-
- x *= br->mtex.size[0];
- y *= br->mtex.size[1];
-
- x += br->mtex.ofs[0];
- y += br->mtex.ofs[1];
-
- avg = paint_get_tex_pixel(br, x, y, ss->tex_pool);
}
- avg += br->texture_sample_bias;
-
/* Falloff curve */
avg *= BKE_brush_curve_strength(br, len, ss->cache->radius);
@@ -1203,11 +1188,12 @@ static void calc_local_y(ViewContext *vc, const float center[3], float y[3])
{
Object *ob = vc->obact;
float loc[3], mval_f[2] = {0.0f, 1.0f};
+ float zfac;
mul_v3_m4v3(loc, ob->imat, center);
- initgrabz(vc->rv3d, loc[0], loc[1], loc[2]);
+ zfac = ED_view3d_calc_zfac(vc->rv3d, loc, NULL);
- ED_view3d_win_to_delta(vc->ar, mval_f, y);
+ ED_view3d_win_to_delta(vc->ar, mval_f, y, zfac);
normalize_v3(y);
add_v3_v3(y, ob->loc);
@@ -3173,8 +3159,8 @@ static void sculpt_combine_proxies(Sculpt *sd, Object *ob)
if (use_orco) {
if (ss->bm) {
copy_v3_v3(val,
- BM_log_original_vert_co(ss->bm_log,
- vd.bm_vert));
+ BM_log_original_vert_co(ss->bm_log,
+ vd.bm_vert));
}
else
copy_v3_v3(val, orco[vd.i]);
@@ -3342,7 +3328,7 @@ static void sculpt_fix_noise_tear(Sculpt *sd, Object *ob)
}
static void do_symmetrical_brush_actions(Sculpt *sd, Object *ob,
- BrushActionFunc action)
+ BrushActionFunc action)
{
Brush *brush = paint_brush(&sd->paint);
SculptSession *ss = ob->sculpt;
@@ -3480,7 +3466,9 @@ void sculpt_update_mesh_elements(Scene *scene, Sculpt *sd, Object *ob,
}
}
}
- else free_sculptsession_deformMats(ss);
+ else {
+ free_sculptsession_deformMats(ss);
+ }
/* if pbvh is deformed, key block is already applied to it */
if (ss->kb && !BKE_pbvh_isDeformed(ss->pbvh)) {
@@ -3673,27 +3661,28 @@ static void sculpt_update_cache_invariants(bContext *C, Sculpt *sd, SculptSessio
Brush *brush = paint_brush(&sd->paint);
ViewContext *vc = paint_stroke_view_context(op->customdata);
Object *ob = CTX_data_active_object(C);
+ float rot[3][3], scale[3], loc[3];
int i;
int mode;
ss->cache = cache;
/* Set scaling adjustment */
- ss->cache->scale[0] = 1.0f / ob->size[0];
- ss->cache->scale[1] = 1.0f / ob->size[1];
- ss->cache->scale[2] = 1.0f / ob->size[2];
+ cache->scale[0] = 1.0f / ob->size[0];
+ cache->scale[1] = 1.0f / ob->size[1];
+ cache->scale[2] = 1.0f / ob->size[2];
- ss->cache->plane_trim_squared = brush->plane_trim * brush->plane_trim;
+ cache->plane_trim_squared = brush->plane_trim * brush->plane_trim;
- ss->cache->flag = 0;
+ cache->flag = 0;
sculpt_init_mirror_clipping(ob, ss);
/* Initial mouse location */
if (mouse)
- copy_v2_v2(ss->cache->initial_mouse, mouse);
+ copy_v2_v2(cache->initial_mouse, mouse);
else
- zero_v2(ss->cache->initial_mouse);
+ zero_v2(cache->initial_mouse);
mode = RNA_enum_get(op->ptr, "mode");
cache->invert = mode == BRUSH_STROKE_INVERT;
@@ -3705,7 +3694,7 @@ static void sculpt_update_cache_invariants(bContext *C, Sculpt *sd, SculptSessio
else brush->flag &= ~BRUSH_INVERTED;
/* Alt-Smooth */
- if (ss->cache->alt_smooth) {
+ if (cache->alt_smooth) {
if (brush->sculpt_tool == SCULPT_TOOL_MASK) {
cache->saved_mask_brush_tool = brush->mask_tool;
brush->mask_tool = BRUSH_MASK_SMOOTH;
@@ -3726,7 +3715,7 @@ static void sculpt_update_cache_invariants(bContext *C, Sculpt *sd, SculptSessio
}
copy_v2_v2(cache->mouse, cache->initial_mouse);
- copy_v2_v2(cache->tex_mouse, cache->initial_mouse);
+ copy_v2_v2(ups->tex_mouse, cache->initial_mouse);
/* Truly temporary data that isn't stored in properties */
@@ -3737,7 +3726,12 @@ static void sculpt_update_cache_invariants(bContext *C, Sculpt *sd, SculptSessio
/* cache projection matrix */
ED_view3d_ob_project_mat_get(cache->vc->rv3d, ob, cache->projection_mat);
+ mat4_to_loc_rot_size(loc, rot, scale, ob->obmat);
+ /* transposing an orthonormal matrix inverts */
+ transpose_m3(rot);
ED_view3d_global_to_vector(cache->vc->rv3d, cache->vc->rv3d->twmat[3], cache->true_view_normal);
+ /* This takes care of rotated mesh. Instead of rotating every normal, we inverse rotate view normal. */
+ mul_m3_v3(rot, cache->true_view_normal);
/* Initialize layer brush displacements and persistent coords */
if (brush->sculpt_tool == SCULPT_TOOL_LAYER) {
/* not supported yet for multires or dynamic topology */
@@ -3748,7 +3742,9 @@ static void sculpt_update_cache_invariants(bContext *C, Sculpt *sd, SculptSessio
ss->layer_co = MEM_mallocN(sizeof(float) * 3 * ss->totvert,
"sculpt mesh vertices copy");
- if (ss->deform_cos) memcpy(ss->layer_co, ss->deform_cos, ss->totvert);
+ if (ss->deform_cos) {
+ memcpy(ss->layer_co, ss->deform_cos, ss->totvert);
+ }
else {
for (i = 0; i < ss->totvert; ++i) {
copy_v3_v3(ss->layer_co[i], ss->mvert[i].co);
@@ -3779,8 +3775,6 @@ static void sculpt_update_cache_invariants(bContext *C, Sculpt *sd, SculptSessio
}
}
- cache->special_rotation = (brush->flag & BRUSH_RAKE) ? ups->last_angle : 0;
-
cache->first_time = 1;
cache->vertex_rotation = 0;
@@ -3793,8 +3787,8 @@ static void sculpt_update_brush_delta(UnifiedPaintSettings *ups, Object *ob, Bru
SculptSession *ss = ob->sculpt;
StrokeCache *cache = ss->cache;
float mouse[2] = {
- cache->mouse[0] - cache->vc->ar->winrct.xmin,
- cache->mouse[1] - cache->vc->ar->winrct.ymin
+ cache->mouse[0],
+ cache->mouse[1]
};
int tool = brush->sculpt_tool;
@@ -3814,8 +3808,6 @@ static void sculpt_update_brush_delta(UnifiedPaintSettings *ups, Object *ob, Bru
/* compute 3d coordinate at same z from original location + mouse */
mul_v3_m4v3(loc, ob->obmat, cache->orig_grab_location);
- initgrabz(cache->vc->rv3d, loc[0], loc[1], loc[2]);
-
ED_view3d_win_to_3d(cache->vc->ar, loc, mouse, grab_location);
/* compute delta to move verts by */
@@ -3853,9 +3845,9 @@ static void sculpt_update_brush_delta(UnifiedPaintSettings *ups, Object *ob, Bru
copy_v3_v3(cache->old_grab_location, grab_location);
if (tool == SCULPT_TOOL_GRAB)
- copy_v3_v3(ups->anchored_location, cache->true_location);
+ copy_v3_v3(cache->anchored_location, cache->true_location);
else if (tool == SCULPT_TOOL_THUMB)
- copy_v3_v3(ups->anchored_location, cache->orig_grab_location);
+ copy_v3_v3(cache->anchored_location, cache->orig_grab_location);
if (ELEM(tool, SCULPT_TOOL_GRAB, SCULPT_TOOL_THUMB)) {
/* location stays the same for finding vertices in brush radius */
@@ -3863,7 +3855,7 @@ static void sculpt_update_brush_delta(UnifiedPaintSettings *ups, Object *ob, Bru
ups->draw_anchored = 1;
copy_v2_v2(ups->anchored_initial_mouse, cache->initial_mouse);
- ups->anchored_size = cache->pixel_radius;
+ ups->anchored_size = ups->pixel_radius;
}
}
}
@@ -3898,18 +3890,11 @@ static void sculpt_update_cache_variants(bContext *C, Sculpt *sd, Object *ob,
* brush coord/pressure/etc.
* It's more an events design issue, which doesn't split coordinate/pressure/angle
* changing events. We should avoid this after events system re-design */
- if (paint_supports_dynamic_size(brush) || cache->first_time) {
+ if (paint_supports_dynamic_size(brush, PAINT_SCULPT) || cache->first_time) {
cache->pressure = RNA_float_get(ptr, "pressure");
}
/* Truly temporary data that isn't stored in properties */
-
- ups->draw_pressure = 1;
- ups->pressure_value = cache->pressure;
-
- cache->previous_pixel_radius = cache->pixel_radius;
- cache->pixel_radius = BKE_brush_size_get(scene, brush);
-
if (cache->first_time) {
if (!BKE_brush_use_locked_size(scene, brush)) {
cache->initial_radius = paint_calc_object_space_radius(cache->vc,
@@ -3922,8 +3907,7 @@ static void sculpt_update_cache_variants(bContext *C, Sculpt *sd, Object *ob,
}
}
- if (BKE_brush_use_size_pressure(scene, brush) && paint_supports_dynamic_size(brush)) {
- cache->pixel_radius *= cache->pressure;
+ if (BKE_brush_use_size_pressure(scene, brush) && paint_supports_dynamic_size(brush, PAINT_SCULPT)) {
cache->radius = cache->initial_radius * cache->pressure;
}
else {
@@ -3932,77 +3916,25 @@ static void sculpt_update_cache_variants(bContext *C, Sculpt *sd, Object *ob,
cache->radius_squared = cache->radius * cache->radius;
- if (!(brush->flag & BRUSH_ANCHORED ||
- ELEM4(brush->sculpt_tool, SCULPT_TOOL_GRAB, SCULPT_TOOL_SNAKE_HOOK,
- SCULPT_TOOL_THUMB, SCULPT_TOOL_ROTATE)))
- {
- copy_v2_v2(cache->tex_mouse, cache->mouse);
-
- if ((brush->mtex.brush_map_mode == MTEX_MAP_MODE_VIEW) &&
- (brush->flag & BRUSH_RANDOM_ROTATION) &&
- !(brush->flag & BRUSH_RAKE))
- {
- cache->special_rotation = 2.0f * (float)M_PI * BLI_frand();
- }
- }
-
if (brush->flag & BRUSH_ANCHORED) {
- int hit = 0;
-
- const float dx = cache->mouse[0] - cache->initial_mouse[0];
- const float dy = cache->mouse[1] - cache->initial_mouse[1];
-
- ups->anchored_size = cache->pixel_radius = sqrt(dx * dx + dy * dy);
-
- cache->special_rotation = atan2(dx, dy) + M_PI;
-
if (brush->flag & BRUSH_EDGE_TO_EDGE) {
float halfway[2];
float out[3];
-
- halfway[0] = dx * 0.5f + cache->initial_mouse[0];
- halfway[1] = dy * 0.5f + cache->initial_mouse[1];
+ halfway[0] = 0.5f * (cache->mouse[0] + cache->initial_mouse[0]);
+ halfway[1] = 0.5f * (cache->mouse[1] + cache->initial_mouse[1]);
if (sculpt_stroke_get_location(C, out, halfway)) {
- copy_v3_v3(ups->anchored_location, out);
- copy_v2_v2(ups->anchored_initial_mouse, halfway);
- copy_v2_v2(cache->tex_mouse, halfway);
- copy_v3_v3(cache->true_location, ups->anchored_location);
- ups->anchored_size /= 2.0f;
- cache->pixel_radius /= 2.0f;
- hit = 1;
+ copy_v3_v3(cache->anchored_location, out);
+ copy_v3_v3(cache->true_location, cache->anchored_location);
}
}
- if (!hit)
- copy_v2_v2(ups->anchored_initial_mouse, cache->initial_mouse);
-
cache->radius = paint_calc_object_space_radius(paint_stroke_view_context(stroke),
cache->true_location,
- cache->pixel_radius);
+ ups->pixel_radius);
cache->radius_squared = cache->radius * cache->radius;
- copy_v3_v3(ups->anchored_location, cache->true_location);
-
- ups->draw_anchored = 1;
- }
- else if (brush->flag & BRUSH_RAKE) {
- const float u = 0.5f;
- const float v = 1 - u;
- const float r = 20;
-
- const float dx = cache->last_rake[0] - cache->mouse[0];
- const float dy = cache->last_rake[1] - cache->mouse[1];
-
- if (cache->first_time) {
- copy_v2_v2(cache->last_rake, cache->mouse);
- }
- else if (dx * dx + dy * dy >= r * r) {
- cache->special_rotation = atan2(dx, dy);
-
- cache->last_rake[0] = u * cache->last_rake[0] + v * cache->mouse[0];
- cache->last_rake[1] = u * cache->last_rake[1] + v * cache->mouse[1];
- }
+ copy_v3_v3(cache->anchored_location, cache->true_location);
}
sculpt_update_brush_delta(ups, ob, brush);
@@ -4015,14 +3947,14 @@ static void sculpt_update_cache_variants(bContext *C, Sculpt *sd, Object *ob,
ups->draw_anchored = 1;
copy_v2_v2(ups->anchored_initial_mouse, cache->initial_mouse);
- copy_v3_v3(ups->anchored_location, cache->true_location);
- ups->anchored_size = cache->pixel_radius;
+ copy_v3_v3(cache->anchored_location, cache->true_location);
+ ups->anchored_size = ups->pixel_radius;
}
- ups->special_rotation = cache->special_rotation;
+ cache->special_rotation = ups->brush_rotation;
}
-/* Returns true iff any of the smoothing modes are active (currently
+/* Returns true if any of the smoothing modes are active (currently
* one of smooth brush, autosmooth, mask smooth, or shift-key
* smooth) */
static int sculpt_any_smooth_mode(const Brush *brush,
@@ -4098,7 +4030,6 @@ int sculpt_stroke_get_location(bContext *C, float out[3], const float mouse[2])
StrokeCache *cache;
float ray_start[3], ray_end[3], ray_normal[3], dist;
float obimat[4][4];
- float mval[2];
SculptRaycastData srd;
view3d_set_viewcontext(C, &vc);
@@ -4109,11 +4040,8 @@ int sculpt_stroke_get_location(bContext *C, float out[3], const float mouse[2])
sculpt_stroke_modifiers_check(C, ob);
- mval[0] = mouse[0] - vc.ar->winrct.xmin;
- mval[1] = mouse[1] - vc.ar->winrct.ymin;
-
/* TODO: what if the segment is totally clipped? (return == 0) */
- ED_view3d_win_to_segment_clip(vc.ar, vc.v3d, mval, ray_start, ray_end);
+ ED_view3d_win_to_segment_clip(vc.ar, vc.v3d, mouse, ray_start, ray_end);
invert_m4_m4(obimat, ob->obmat);
mul_m4_v3(obimat, ray_start);
@@ -4279,6 +4207,7 @@ static int sculpt_stroke_test_start(bContext *C, struct wmOperator *op,
static void sculpt_stroke_update_step(bContext *C, struct PaintStroke *stroke, PointerRNA *itemptr)
{
+ UnifiedPaintSettings *ups = &CTX_data_tool_settings(C)->unified_paint_settings;
Sculpt *sd = CTX_data_tool_settings(C)->sculpt;
Object *ob = CTX_data_active_object(C);
SculptSession *ss = ob->sculpt;
@@ -4289,9 +4218,9 @@ static void sculpt_stroke_update_step(bContext *C, struct PaintStroke *stroke, P
sculpt_restore_mesh(sd, ob);
BKE_pbvh_bmesh_detail_size_set(ss->pbvh,
- (ss->cache->radius /
- (float)ss->cache->pixel_radius) *
- (float)sd->detail_size);
+ (ss->cache->radius /
+ (float)ups->pixel_radius) *
+ (float)sd->detail_size);
if (sculpt_stroke_dynamic_topology(ss, brush)) {
do_symmetrical_brush_actions(sd, ob, sculpt_topology_update);
@@ -4335,7 +4264,6 @@ static void sculpt_stroke_done(const bContext *C, struct PaintStroke *UNUSED(str
/* reset values used to draw brush after completing the stroke */
ups->draw_anchored = 0;
ups->draw_pressure = 0;
- ups->special_rotation = 0;
/* Finished */
if (ss->cache) {
@@ -4390,7 +4318,7 @@ static void sculpt_stroke_done(const bContext *C, struct PaintStroke *UNUSED(str
sculpt_brush_exit_tex(sd);
}
-static int sculpt_brush_stroke_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int sculpt_brush_stroke_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
struct PaintStroke *stroke;
int ignore_background_click;
@@ -4407,8 +4335,7 @@ static int sculpt_brush_stroke_invoke(bContext *C, wmOperator *op, wmEvent *even
op->customdata = stroke;
/* For tablet rotation */
- ignore_background_click = RNA_boolean_get(op->ptr,
- "ignore_background_click");
+ ignore_background_click = RNA_boolean_get(op->ptr, "ignore_background_click");
if (ignore_background_click && !over_mesh(C, op, event->x, event->y)) {
paint_stroke_data_free(op);
@@ -4487,8 +4414,7 @@ static void SCULPT_OT_brush_stroke(wmOperatorType *ot)
/* properties */
- RNA_def_collection_runtime(ot->srna, "stroke", &RNA_OperatorStrokeElement,
- "Stroke", "");
+ RNA_def_collection_runtime(ot->srna, "stroke", &RNA_OperatorStrokeElement, "Stroke", "");
RNA_def_enum(ot->srna, "mode", stroke_mode_items, BRUSH_STROKE_NORMAL,
"Sculpt Stroke Mode",
@@ -4570,7 +4496,7 @@ void sculpt_dynamic_topology_enable(bContext *C)
sculpt_pbvh_clear(ob);
ss->bm_smooth_shading = (scene->toolsettings->sculpt->flags &
- SCULPT_DYNTOPO_SMOOTH_SHADING);
+ SCULPT_DYNTOPO_SMOOTH_SHADING);
/* Create triangles-only BMesh */
ss->bm = BM_mesh_create(&bm_mesh_allocsize_default);
@@ -4596,7 +4522,7 @@ void sculpt_dynamic_topology_enable(bContext *C)
* If 'unode' is given, the BMesh's data is copied out to the unode
* before the BMesh is deleted so that it can be restored from */
void sculpt_dynamic_topology_disable(bContext *C,
- SculptUndoNode *unode)
+ SculptUndoNode *unode)
{
Object *ob = CTX_data_active_object(C);
SculptSession *ss = ob->sculpt;
@@ -4619,13 +4545,13 @@ void sculpt_dynamic_topology_disable(bContext *C,
me->totedge = unode->bm_enter_totedge;
me->totface = 0;
CustomData_copy(&unode->bm_enter_vdata, &me->vdata, CD_MASK_MESH,
- CD_DUPLICATE, unode->bm_enter_totvert);
+ CD_DUPLICATE, unode->bm_enter_totvert);
CustomData_copy(&unode->bm_enter_edata, &me->edata, CD_MASK_MESH,
- CD_DUPLICATE, unode->bm_enter_totedge);
+ CD_DUPLICATE, unode->bm_enter_totedge);
CustomData_copy(&unode->bm_enter_ldata, &me->ldata, CD_MASK_MESH,
- CD_DUPLICATE, unode->bm_enter_totloop);
+ CD_DUPLICATE, unode->bm_enter_totloop);
CustomData_copy(&unode->bm_enter_pdata, &me->pdata, CD_MASK_MESH,
- CD_DUPLICATE, unode->bm_enter_totpoly);
+ CD_DUPLICATE, unode->bm_enter_totpoly);
mesh_update_customdata_pointers(me, FALSE);
}
@@ -4665,28 +4591,23 @@ static int sculpt_dynamic_topology_toggle_exec(bContext *C, wmOperator *UNUSED(o
return OPERATOR_FINISHED;
}
-static int sculpt_dynamic_topology_toggle_invoke(bContext *C, wmOperator *op,
- wmEvent *UNUSED(event))
+static int sculpt_dynamic_topology_toggle_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
Object *ob = CTX_data_active_object(C);
Mesh *me = ob->data;
SculptSession *ss = ob->sculpt;
- const char *msg = "Dynamic-topology sculpting will not preserve"
- "vertex colors, UVs, or other customdata";
+ const char *msg = TIP_("Dynamic-topology sculpting will not preserve vertex colors, UVs, or other customdata");
if (!ss->bm) {
int i;
for (i = 0; i < CD_NUMTYPES; i++) {
- if (!ELEM7(i, CD_MVERT, CD_MEDGE, CD_MFACE,
- CD_MLOOP, CD_MPOLY, CD_PAINT_MASK,
- CD_ORIGINDEX) &&
+ if (!ELEM7(i, CD_MVERT, CD_MEDGE, CD_MFACE, CD_MLOOP, CD_MPOLY, CD_PAINT_MASK, CD_ORIGINDEX) &&
(CustomData_has_layer(&me->vdata, i) ||
CustomData_has_layer(&me->edata, i) ||
CustomData_has_layer(&me->fdata, i)))
{
- /* The mesh has customdata that will be lost, let the
- * user confirm this is OK */
+ /* The mesh has customdata that will be lost, let the user confirm this is OK */
return WM_operator_confirm_message(C, op, msg);
}
}
diff --git a/source/blender/editors/sculpt_paint/sculpt_intern.h b/source/blender/editors/sculpt_paint/sculpt_intern.h
index fa1bdd6ca82..82a07c9e3be 100644
--- a/source/blender/editors/sculpt_paint/sculpt_intern.h
+++ b/source/blender/editors/sculpt_paint/sculpt_intern.h
@@ -62,9 +62,6 @@ int sculpt_poll(struct bContext *C);
void sculpt_update_mesh_elements(struct Scene *scene, struct Sculpt *sd, struct Object *ob,
int need_pmap, int need_mask);
-/* Deformed mesh sculpt */
-void free_sculptsession_deformMats(struct SculptSession *ss);
-
/* Stroke */
int sculpt_stroke_get_location(bContext *C, float out[3], const float mouse[2]);
diff --git a/source/blender/editors/sculpt_paint/sculpt_undo.c b/source/blender/editors/sculpt_paint/sculpt_undo.c
index 406756f4197..2cc09ea2aa9 100644
--- a/source/blender/editors/sculpt_paint/sculpt_undo.c
+++ b/source/blender/editors/sculpt_paint/sculpt_undo.c
@@ -131,7 +131,9 @@ static int sculpt_undo_restore_coords(bContext *C, DerivedMesh *dm, SculptUndoNo
vertCos = BKE_key_convert_to_vertcos(ob, ss->kb);
for (i = 0; i < unode->totvert; i++) {
- if (ss->modifiers_active) sculpt_undo_restore_deformed(ss, unode, i, index[i], vertCos[index[i]]);
+ if (ss->modifiers_active) {
+ sculpt_undo_restore_deformed(ss, unode, i, index[i], vertCos[index[i]]);
+ }
else {
if (unode->orig_co) swap_v3_v3(vertCos[index[i]], unode->orig_co[i]);
else swap_v3_v3(vertCos[index[i]], unode->co[i]);
@@ -149,7 +151,9 @@ static int sculpt_undo_restore_coords(bContext *C, DerivedMesh *dm, SculptUndoNo
}
else {
for (i = 0; i < unode->totvert; i++) {
- if (ss->modifiers_active) sculpt_undo_restore_deformed(ss, unode, i, index[i], mvert[index[i]].co);
+ if (ss->modifiers_active) {
+ sculpt_undo_restore_deformed(ss, unode, i, index[i], mvert[index[i]].co);
+ }
else {
if (unode->orig_co) swap_v3_v3(mvert[index[i]].co, unode->orig_co[i]);
else swap_v3_v3(mvert[index[i]].co, unode->co[i]);
@@ -263,8 +267,8 @@ static int sculpt_undo_restore_mask(bContext *C, DerivedMesh *dm, SculptUndoNode
}
static void sculpt_undo_bmesh_restore_generic(SculptUndoNode *unode,
- Object *ob,
- SculptSession *ss)
+ Object *ob,
+ SculptSession *ss)
{
if (unode->applied) {
BM_log_undo(ss->bm, ss->bm_log);
@@ -282,7 +286,7 @@ static void sculpt_undo_bmesh_restore_generic(SculptUndoNode *unode,
/* Create empty sculpt BMesh and enable logging */
static void sculpt_undo_bmesh_enable(Object *ob,
- SculptUndoNode *unode)
+ SculptUndoNode *unode)
{
SculptSession *ss = ob->sculpt;
Mesh *me = ob->data;
@@ -296,13 +300,13 @@ static void sculpt_undo_bmesh_enable(Object *ob,
/* Restore the BMLog using saved entries */
ss->bm_log = BM_log_from_existing_entries_create(ss->bm,
- unode->bm_entry);
+ unode->bm_entry);
}
static void sculpt_undo_bmesh_restore_begin(bContext *C,
- SculptUndoNode *unode,
- Object *ob,
- SculptSession *ss)
+ SculptUndoNode *unode,
+ Object *ob,
+ SculptSession *ss)
{
if (unode->applied) {
sculpt_dynamic_topology_disable(C, unode);
@@ -319,9 +323,9 @@ static void sculpt_undo_bmesh_restore_begin(bContext *C,
}
static void sculpt_undo_bmesh_restore_end(bContext *C,
- SculptUndoNode *unode,
- Object *ob,
- SculptSession *ss)
+ SculptUndoNode *unode,
+ Object *ob,
+ SculptSession *ss)
{
if (unode->applied) {
sculpt_undo_bmesh_enable(ob, unode);
@@ -343,9 +347,9 @@ static void sculpt_undo_bmesh_restore_end(bContext *C,
* Returns TRUE if this was a dynamic-topology undo step, otherwise
* returns FALSE to indicate the non-dyntopo code should run. */
static int sculpt_undo_bmesh_restore(bContext *C,
- SculptUndoNode *unode,
- Object *ob,
- SculptSession *ss)
+ SculptUndoNode *unode,
+ Object *ob,
+ SculptSession *ss)
{
switch (unode->type) {
case SCULPT_UNDO_DYNTOPO_BEGIN:
@@ -375,7 +379,6 @@ static void sculpt_undo_restore(bContext *C, ListBase *lb)
DerivedMesh *dm;
SculptSession *ss = ob->sculpt;
SculptUndoNode *unode;
- MultiresModifierData *mmd;
int update = FALSE, rebuild = FALSE;
int need_mask = FALSE;
@@ -446,7 +449,7 @@ static void sculpt_undo_restore(bContext *C, ListBase *lb)
BKE_pbvh_search_callback(ss->pbvh, NULL, NULL, update_cb, &rebuild);
BKE_pbvh_update(ss->pbvh, PBVH_UpdateBB | PBVH_UpdateOriginalBB | PBVH_UpdateRedraw, NULL);
- if ((mmd = sculpt_multires_active(scene, ob))) {
+ if (sculpt_multires_active(scene, ob)) {
if (rebuild)
multires_mark_as_modified(ob, MULTIRES_HIDDEN_MODIFIED);
else
@@ -563,7 +566,7 @@ static SculptUndoNode *sculpt_undo_alloc_node(Object *ob, PBVHNode *node,
if (node) {
BKE_pbvh_node_num_verts(ss->pbvh, node, &totvert, &allvert);
BKE_pbvh_node_get_grids(ss->pbvh, node, &grids, &totgrid,
- &maxgrid, &gridsize, NULL, NULL);
+ &maxgrid, &gridsize, NULL, NULL);
unode->totvert = totvert;
}
@@ -673,8 +676,8 @@ static void sculpt_undo_store_mask(Object *ob, SculptUndoNode *unode)
}
static SculptUndoNode *sculpt_undo_bmesh_push(Object *ob,
- PBVHNode *node,
- SculptUndoType type)
+ PBVHNode *node,
+ SculptUndoType type)
{
ListBase *lb = undo_paint_push_get_list(UNDO_PAINT_MESH);
SculptUndoNode *unode = lb->first;
@@ -701,13 +704,13 @@ static SculptUndoNode *sculpt_undo_bmesh_push(Object *ob,
* (converting polys to triangles) that the BMLog can't
* fully restore from */
CustomData_copy(&me->vdata, &unode->bm_enter_vdata, CD_MASK_MESH,
- CD_DUPLICATE, me->totvert);
+ CD_DUPLICATE, me->totvert);
CustomData_copy(&me->edata, &unode->bm_enter_edata, CD_MASK_MESH,
- CD_DUPLICATE, me->totedge);
+ CD_DUPLICATE, me->totedge);
CustomData_copy(&me->ldata, &unode->bm_enter_ldata, CD_MASK_MESH,
- CD_DUPLICATE, me->totloop);
+ CD_DUPLICATE, me->totloop);
CustomData_copy(&me->pdata, &unode->bm_enter_pdata, CD_MASK_MESH,
- CD_DUPLICATE, me->totpoly);
+ CD_DUPLICATE, me->totpoly);
unode->bm_enter_totvert = me->totvert;
unode->bm_enter_totedge = me->totedge;
unode->bm_enter_totloop = me->totloop;
@@ -756,9 +759,9 @@ SculptUndoNode *sculpt_undo_push_node(Object *ob, PBVHNode *node,
BLI_lock_thread(LOCK_CUSTOM1);
if (ss->bm ||
- ELEM(type,
- SCULPT_UNDO_DYNTOPO_BEGIN,
- SCULPT_UNDO_DYNTOPO_END))
+ ELEM(type,
+ SCULPT_UNDO_DYNTOPO_BEGIN,
+ SCULPT_UNDO_DYNTOPO_END))
{
/* Dynamic topology stores only one undo node per stroke,
* regardless of the number of PBVH nodes modified */
diff --git a/source/blender/editors/sculpt_paint/sculpt_uv.c b/source/blender/editors/sculpt_paint/sculpt_uv.c
index 0bcccd9479c..7cdfb6d22b2 100644
--- a/source/blender/editors/sculpt_paint/sculpt_uv.c
+++ b/source/blender/editors/sculpt_paint/sculpt_uv.c
@@ -144,6 +144,69 @@ typedef struct UvSculptData {
char invert;
} UvSculptData;
+
+static Brush *uv_sculpt_brush(bContext *C)
+{
+ Scene *scene = CTX_data_scene(C);
+ ToolSettings *settings = scene->toolsettings;
+
+ if (!settings->uvsculpt)
+ return NULL;
+ return paint_brush(&settings->uvsculpt->paint);
+}
+
+
+static int uv_sculpt_brush_poll(bContext *C)
+{
+ BMEditMesh *em;
+ int ret;
+ Object *obedit = CTX_data_edit_object(C);
+ SpaceImage *sima = CTX_wm_space_image(C);
+ Scene *scene = CTX_data_scene(C);
+ ToolSettings *toolsettings = scene->toolsettings;
+
+ if (!uv_sculpt_brush(C) || !obedit || obedit->type != OB_MESH)
+ return 0;
+
+ em = BMEdit_FromObject(obedit);
+ ret = EDBM_mtexpoly_check(em);
+
+ if (ret && sima) {
+ ARegion *ar = CTX_wm_region(C);
+ if ((toolsettings->use_uv_sculpt) && ar->regiontype == RGN_TYPE_WINDOW)
+ return 1;
+ }
+
+ return 0;
+}
+
+
+void ED_space_image_uv_sculpt_update(wmWindowManager *wm, ToolSettings *settings)
+{
+ if (settings->use_uv_sculpt) {
+ if (!settings->uvsculpt) {
+ settings->uvsculpt = MEM_callocN(sizeof(*settings->uvsculpt), "UV Smooth paint");
+ settings->uv_sculpt_tool = UV_SCULPT_TOOL_GRAB;
+ settings->uv_sculpt_settings = UV_SCULPT_LOCK_BORDERS | UV_SCULPT_ALL_ISLANDS;
+ settings->uv_relax_method = UV_SCULPT_TOOL_RELAX_LAPLACIAN;
+ }
+
+ BKE_paint_init(&settings->uvsculpt->paint, PAINT_CURSOR_SCULPT);
+
+ WM_paint_cursor_activate(wm, uv_sculpt_brush_poll,
+ brush_drawcursor_texpaint_uvsculpt, NULL);
+ }
+ else {
+ if (settings->uvsculpt)
+ settings->uvsculpt->paint.flags &= ~PAINT_SHOW_BRUSH;
+ }
+}
+
+int uv_sculpt_poll(bContext *C)
+{
+ return uv_sculpt_brush_poll(C);
+}
+
/*********** Improved Laplacian Relaxation Operator ************************/
/* original code by Raul Fernandez Hernandez "farsthary" *
* adapted to uv smoothing by Antony Riakiatakis *
@@ -294,7 +357,7 @@ static void laplacian_relaxation_iteration_uv(BMEditMesh *em, UvSculptData *scul
}
-static void uv_sculpt_stroke_apply(bContext *C, wmOperator *op, wmEvent *event, Object *obedit)
+static void uv_sculpt_stroke_apply(bContext *C, wmOperator *op, const wmEvent *event, Object *obedit)
{
float co[2], radius, radius_root;
Scene *scene = CTX_data_scene(C);
@@ -464,7 +527,7 @@ static int uv_edge_compare(const void *a, const void *b)
}
-static UvSculptData *uv_sculpt_stroke_init(bContext *C, wmOperator *op, wmEvent *event)
+static UvSculptData *uv_sculpt_stroke_init(bContext *C, wmOperator *op, const wmEvent *event)
{
Scene *scene = CTX_data_scene(C);
Object *obedit = CTX_data_edit_object(C);
@@ -649,7 +712,7 @@ static UvSculptData *uv_sculpt_stroke_init(bContext *C, wmOperator *op, wmEvent
return NULL;
}
/* fill the edges with data */
- for (i = 0; !BLI_ghashIterator_isDone(ghi); BLI_ghashIterator_step(ghi)) {
+ for (i = 0; BLI_ghashIterator_notDone(ghi); BLI_ghashIterator_step(ghi)) {
data->uvedges[i++] = *((UvEdge *)BLI_ghashIterator_getKey(ghi));
}
data->totalUvEdges = BLI_ghash_size(edgeHash);
@@ -731,7 +794,7 @@ static UvSculptData *uv_sculpt_stroke_init(bContext *C, wmOperator *op, wmEvent
return op->customdata;
}
-static int uv_sculpt_stroke_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int uv_sculpt_stroke_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
UvSculptData *data;
Object *obedit = CTX_data_edit_object(C);
@@ -754,7 +817,7 @@ static int uv_sculpt_stroke_invoke(bContext *C, wmOperator *op, wmEvent *event)
}
-static int uv_sculpt_stroke_modal(bContext *C, wmOperator *op, wmEvent *event)
+static int uv_sculpt_stroke_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
UvSculptData *data = (UvSculptData *)op->customdata;
Object *obedit = CTX_data_edit_object(C);
diff --git a/source/blender/editors/sound/sound_ops.c b/source/blender/editors/sound/sound_ops.c
index eb138bfeeef..d25fd00514c 100644
--- a/source/blender/editors/sound/sound_ops.c
+++ b/source/blender/editors/sound/sound_ops.c
@@ -160,7 +160,7 @@ static int sound_open_exec(bContext *UNUSED(C), wmOperator *op)
#endif
-static int sound_open_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int sound_open_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
if (RNA_struct_property_is_set(op->ptr, "filepath"))
return sound_open_exec(C, op);
@@ -439,7 +439,7 @@ static int sound_mixdown_check(bContext *UNUSED(C), wmOperator *op)
#endif // WITH_AUDASPACE
-static int sound_mixdown_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int sound_mixdown_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
if (RNA_struct_property_is_set(op->ptr, "filepath"))
return sound_mixdown_exec(C, op);
@@ -747,7 +747,7 @@ static int sound_unpack_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int sound_unpack_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int sound_unpack_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
Editing *ed = CTX_data_scene(C)->ed;
bSound *sound;
diff --git a/source/blender/editors/space_action/action_edit.c b/source/blender/editors/space_action/action_edit.c
index 7e99e6c065d..803e7b71c77 100644
--- a/source/blender/editors/space_action/action_edit.c
+++ b/source/blender/editors/space_action/action_edit.c
@@ -742,7 +742,7 @@ static int actkeys_duplicate_exec(bContext *C, wmOperator *UNUSED(op))
return OPERATOR_FINISHED;
}
-static int actkeys_duplicate_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int actkeys_duplicate_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
actkeys_duplicate_exec(C, op);
diff --git a/source/blender/editors/space_action/action_select.c b/source/blender/editors/space_action/action_select.c
index 964a6a20c37..b6d2d31f0ad 100644
--- a/source/blender/editors/space_action/action_select.c
+++ b/source/blender/editors/space_action/action_select.c
@@ -872,7 +872,7 @@ static int actkeys_select_leftright_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int actkeys_select_leftright_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int actkeys_select_leftright_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
bAnimContext ac;
short leftright = RNA_enum_get(op->ptr, "mode");
@@ -1223,7 +1223,7 @@ static void mouse_action_keys(bAnimContext *ac, const int mval[2], short select_
}
/* handle clicking */
-static int actkeys_clickselect_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int actkeys_clickselect_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
bAnimContext ac;
/* ARegion *ar; */ /* UNUSED */
@@ -1264,16 +1264,17 @@ void ACTION_OT_clickselect(wmOperatorType *ot)
ot->idname = "ACTION_OT_clickselect";
ot->description = "Select keyframes by clicking on them";
- /* api callbacks - absolutely no exec() this yet... */
+ /* callbacks */
ot->invoke = actkeys_clickselect_invoke;
ot->poll = ED_operator_action_active;
/* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ ot->flag = OPTYPE_UNDO;
/* properties */
prop = RNA_def_boolean(ot->srna, "extend", 0, "Extend Select", ""); // SHIFTKEY
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
+
prop = RNA_def_boolean(ot->srna, "column", 0, "Column Select", ""); // ALTKEY
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
}
diff --git a/source/blender/editors/space_buttons/buttons_ops.c b/source/blender/editors/space_buttons/buttons_ops.c
index 8b6682ff1c9..dcc61cfa544 100644
--- a/source/blender/editors/space_buttons/buttons_ops.c
+++ b/source/blender/editors/space_buttons/buttons_ops.c
@@ -35,10 +35,10 @@
#include "DNA_userdef_types.h"
+#include "BLI_utildefines.h"
#include "BLI_fileops.h"
#include "BLI_path_util.h"
#include "BLI_string.h"
-#include "BLI_utildefines.h"
#include "BLF_translation.h"
@@ -62,7 +62,7 @@
/********************** toolbox operator *********************/
-static int toolbox_invoke(bContext *C, wmOperator *UNUSED(op), wmEvent *UNUSED(event))
+static int toolbox_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *UNUSED(event))
{
bScreen *sc = CTX_wm_screen(C);
SpaceButs *sbuts = CTX_wm_space_buts(C);
@@ -113,7 +113,6 @@ static int file_browse_exec(bContext *C, wmOperator *op)
/* add slash for directories, important for some properties */
if (RNA_property_subtype(fbo->prop) == PROP_DIRPATH) {
- char name[FILE_MAX];
int is_relative = RNA_boolean_get(op->ptr, "relative_path");
id = fbo->ptr.id.data;
@@ -132,8 +131,10 @@ static int file_browse_exec(bContext *C, wmOperator *op)
}
BLI_add_slash(str);
}
- else
- BLI_splitdirstring(str, name);
+ else {
+ char * const lslash = (char *)BLI_last_slash(str);
+ if (lslash) lslash[1] = '\0';
+ }
}
RNA_property_string_set(&fbo->ptr, fbo->prop, str);
@@ -164,7 +165,7 @@ static int file_browse_cancel(bContext *UNUSED(C), wmOperator *op)
return OPERATOR_CANCELLED;
}
-static int file_browse_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int file_browse_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
PointerRNA ptr;
PropertyRNA *prop;
@@ -189,7 +190,7 @@ static int file_browse_invoke(bContext *C, wmOperator *op, wmEvent *event)
PointerRNA props_ptr;
if (event->alt) {
- char *lslash = BLI_last_slash(str);
+ char *lslash = (char *)BLI_last_slash(str);
if (lslash)
*lslash = '\0';
}
diff --git a/source/blender/editors/space_buttons/buttons_texture.c b/source/blender/editors/space_buttons/buttons_texture.c
index 16d194d0929..1643921e4dd 100644
--- a/source/blender/editors/space_buttons/buttons_texture.c
+++ b/source/blender/editors/space_buttons/buttons_texture.c
@@ -404,7 +404,7 @@ void uiTemplateTextureUser(uiLayout *layout, bContext *C)
}
/* create button */
- BLI_snprintf(name, UI_MAX_NAME_STR, "%s", user->name);
+ BLI_strncpy(name, user->name, UI_MAX_NAME_STR);
if (user->icon) {
but = uiDefIconTextMenuBut(block, template_texture_user_menu, NULL,
diff --git a/source/blender/editors/space_clip/SConscript b/source/blender/editors/space_clip/SConscript
index c65a076186f..840a3b49f2b 100644
--- a/source/blender/editors/space_clip/SConscript
+++ b/source/blender/editors/space_clip/SConscript
@@ -34,5 +34,8 @@ incs += ' ../../makesrna ../../windowmanager #/intern/guardedalloc #/extern/glew
if env['WITH_BF_INTERNATIONAL']:
defs.append('WITH_INTERNATIONAL')
+
+if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'linuxcross', 'win64-vc', 'win64-mingw'):
+ incs += ' ' + env['BF_PTHREADS_INC']
env.BlenderLib ( 'bf_editors_space_clip', sources, Split(incs), defs, libtype=['core'], priority=[95] )
diff --git a/source/blender/editors/space_clip/clip_dopesheet_ops.c b/source/blender/editors/space_clip/clip_dopesheet_ops.c
index 09f6271b6ef..e5cd7247c43 100644
--- a/source/blender/editors/space_clip/clip_dopesheet_ops.c
+++ b/source/blender/editors/space_clip/clip_dopesheet_ops.c
@@ -59,12 +59,11 @@
#include "clip_intern.h" // own include
-#if 0
-static int ED_space_clip_dopesheet_poll(bContext *C)
+static int space_clip_dopesheet_poll(bContext *C)
{
- SpaceClip *sc = CTX_wm_space_clip(C);
+ if (ED_space_clip_tracking_poll(C)) {
+ SpaceClip *sc = CTX_wm_space_clip(C);
- if (sc && sc->clip) {
if (sc->view == SC_VIEW_DOPESHEET) {
ARegion *ar = CTX_wm_region(C);
@@ -74,7 +73,6 @@ static int ED_space_clip_dopesheet_poll(bContext *C)
return FALSE;
}
-#endif
/********************** select channel operator *********************/
@@ -129,7 +127,7 @@ static int dopesheet_select_channel_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int dopesheet_select_channel_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int dopesheet_select_channel_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
ARegion *ar = CTX_wm_region(C);
float location[2];
@@ -161,3 +159,54 @@ void CLIP_OT_dopesheet_select_channel(wmOperatorType *ot)
RNA_def_boolean(ot->srna, "extend", 0,
"Extend", "Extend selection rather than clearing the existing selection");
}
+
+/********************** View All operator *********************/
+
+static int dopesheet_view_all_exec(bContext *C, wmOperator *UNUSED(op))
+{
+ SpaceClip *sc = CTX_wm_space_clip(C);
+ ARegion *ar = CTX_wm_region(C);
+ View2D *v2d = &ar->v2d;
+ MovieClip *clip = ED_space_clip_get_clip(sc);
+ MovieTracking *tracking = &clip->tracking;
+ MovieTrackingDopesheet *dopesheet = &tracking->dopesheet;
+ MovieTrackingDopesheetChannel *channel;
+ int frame_min = INT_MAX, frame_max = INT_MIN;
+
+ for (channel = dopesheet->channels.first; channel; channel = channel->next) {
+ frame_min = min_ii(frame_min, channel->segments[0]);
+ frame_max = max_ii(frame_max, channel->segments[channel->tot_segment]);
+ }
+
+ if (frame_min < frame_max) {
+ float extra;
+
+ v2d->cur.xmin = frame_min;
+ v2d->cur.xmax = frame_max;
+
+ /* we need an extra "buffer" factor on either side so that the endpoints are visible */
+ extra = 0.01f * BLI_rctf_size_x(&v2d->cur);
+ v2d->cur.xmin -= extra;
+ v2d->cur.xmax += extra;
+
+ ED_region_tag_redraw(ar);
+ }
+
+
+ return OPERATOR_FINISHED;
+}
+
+void CLIP_OT_dopesheet_view_all(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "View All";
+ ot->description = "Reset viewable area to show full keyframe range";
+ ot->idname = "CLIP_OT_dopesheet_view_all";
+
+ /* api callbacks */
+ ot->exec = dopesheet_view_all_exec;
+ ot->poll = space_clip_dopesheet_poll;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+}
diff --git a/source/blender/editors/space_clip/clip_draw.c b/source/blender/editors/space_clip/clip_draw.c
index 56f2998b047..58626c79363 100644
--- a/source/blender/editors/space_clip/clip_draw.c
+++ b/source/blender/editors/space_clip/clip_draw.c
@@ -944,7 +944,7 @@ static void draw_marker_texts(SpaceClip *sc, MovieTrackingTrack *track, MovieTra
if (state[0])
BLI_snprintf(str, sizeof(str), "%s: %s", track->name, state);
else
- BLI_snprintf(str, sizeof(str), "%s", track->name);
+ BLI_strncpy(str, track->name, sizeof(str));
BLF_position(fontid, pos[0], pos[1], 0.0f);
BLF_draw(fontid, str, sizeof(str));
diff --git a/source/blender/editors/space_clip/clip_graph_ops.c b/source/blender/editors/space_clip/clip_graph_ops.c
index fa235bd2997..edc6ac1ecf7 100644
--- a/source/blender/editors/space_clip/clip_graph_ops.c
+++ b/source/blender/editors/space_clip/clip_graph_ops.c
@@ -276,7 +276,7 @@ static int select_exec(bContext *C, wmOperator *op)
return mouse_select(C, co, extend);
}
-static int select_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int select_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
ARegion *ar = CTX_wm_region(C);
float co[2];
diff --git a/source/blender/editors/space_clip/clip_intern.h b/source/blender/editors/space_clip/clip_intern.h
index 432032e9dbf..cd7da4229d2 100644
--- a/source/blender/editors/space_clip/clip_intern.h
+++ b/source/blender/editors/space_clip/clip_intern.h
@@ -67,6 +67,7 @@ void clip_draw_dopesheet_channels(const struct bContext *C, struct ARegion *ar);
/* clip_dopesheet_ops.c */
void CLIP_OT_dopesheet_select_channel(struct wmOperatorType *ot);
+void CLIP_OT_dopesheet_view_all(struct wmOperatorType *ot);
/* clip_draw.c */
void clip_draw_main(const struct bContext *C, struct SpaceClip *sc, struct ARegion *ar);
@@ -133,7 +134,7 @@ void clip_draw_cfra(struct SpaceClip *sc, struct ARegion *ar, struct Scene *scen
void clip_draw_sfra_efra(struct View2D *v2d, struct Scene *scene);
/* tracking_ops.c */
-struct MovieTrackingTrack *tracking_marker_check_slide(struct bContext *C, struct wmEvent *event,
+struct MovieTrackingTrack *tracking_marker_check_slide(struct bContext *C, const struct wmEvent *event,
int *area_r, int *action_r, int *corner_r);
void CLIP_OT_add_marker(struct wmOperatorType *ot);
diff --git a/source/blender/editors/space_clip/clip_ops.c b/source/blender/editors/space_clip/clip_ops.c
index dfb69be6f18..914eb9526a8 100644
--- a/source/blender/editors/space_clip/clip_ops.c
+++ b/source/blender/editors/space_clip/clip_ops.c
@@ -30,16 +30,26 @@
*/
#include <errno.h>
+#include <sys/types.h>
+#include <fcntl.h>
+
+#ifndef WIN32
+# include <unistd.h>
+#else
+# include <io.h>
+#endif
#include "MEM_guardedalloc.h"
#include "DNA_userdef_types.h"
#include "DNA_scene_types.h" /* min/max frames */
-#include "BLI_path_util.h"
#include "BLI_utildefines.h"
+#include "BLI_fileops.h"
+#include "BLI_path_util.h"
#include "BLI_math.h"
#include "BLI_rect.h"
+#include "BLI_threads.h"
#include "BLF_translation.h"
@@ -113,7 +123,7 @@ static void sclip_zoom_set_factor(const bContext *C, float zoomfac, float locati
sclip_zoom_set(C, sc->zoom * zoomfac, location);
}
-static void sclip_zoom_set_factor_exec(bContext *C, wmEvent *event, float factor)
+static void sclip_zoom_set_factor_exec(bContext *C, const wmEvent *event, float factor)
{
ARegion *ar = CTX_wm_region(C);
@@ -230,7 +240,7 @@ static int open_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int open_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int open_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
SpaceClip *sc = CTX_wm_space_clip(C);
char path[FILE_MAX];
@@ -318,7 +328,7 @@ typedef struct ViewPanData {
float *vec;
} ViewPanData;
-static void view_pan_init(bContext *C, wmOperator *op, wmEvent *event)
+static void view_pan_init(bContext *C, wmOperator *op, const wmEvent *event)
{
SpaceClip *sc = CTX_wm_space_clip(C);
ViewPanData *vpd;
@@ -377,7 +387,7 @@ static int view_pan_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int view_pan_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int view_pan_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
if (event->type == MOUSEPAN) {
SpaceClip *sc = CTX_wm_space_clip(C);
@@ -399,7 +409,7 @@ static int view_pan_invoke(bContext *C, wmOperator *op, wmEvent *event)
}
}
-static int view_pan_modal(bContext *C, wmOperator *op, wmEvent *event)
+static int view_pan_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
SpaceClip *sc = CTX_wm_space_clip(C);
ViewPanData *vpd = op->customdata;
@@ -471,7 +481,7 @@ typedef struct ViewZoomData {
float location[2];
} ViewZoomData;
-static void view_zoom_init(bContext *C, wmOperator *op, wmEvent *event)
+static void view_zoom_init(bContext *C, wmOperator *op, const wmEvent *event)
{
SpaceClip *sc = CTX_wm_space_clip(C);
ARegion *ar = CTX_wm_region(C);
@@ -514,7 +524,7 @@ static int view_zoom_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int view_zoom_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int view_zoom_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
if (event->type == MOUSEZOOM || event->type == MOUSEPAN) {
float delta, factor;
@@ -538,7 +548,7 @@ static int view_zoom_invoke(bContext *C, wmOperator *op, wmEvent *event)
}
}
-static int view_zoom_modal(bContext *C, wmOperator *op, wmEvent *event)
+static int view_zoom_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
ViewZoomData *vpd = op->customdata;
float delta, factor;
@@ -611,7 +621,7 @@ static int view_zoom_in_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int view_zoom_in_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int view_zoom_in_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
SpaceClip *sc = CTX_wm_space_clip(C);
ARegion *ar = CTX_wm_region(C);
@@ -654,7 +664,7 @@ static int view_zoom_out_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int view_zoom_out_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int view_zoom_out_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
SpaceClip *sc = CTX_wm_space_clip(C);
ARegion *ar = CTX_wm_region(C);
@@ -844,7 +854,7 @@ static int change_frame_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int frame_from_event(bContext *C, wmEvent *event)
+static int frame_from_event(bContext *C, const wmEvent *event)
{
ARegion *ar = CTX_wm_region(C);
Scene *scene = CTX_data_scene(C);
@@ -866,7 +876,7 @@ static int frame_from_event(bContext *C, wmEvent *event)
return framenr;
}
-static int change_frame_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int change_frame_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
ARegion *ar = CTX_wm_region(C);
@@ -885,7 +895,7 @@ static int change_frame_invoke(bContext *C, wmOperator *op, wmEvent *event)
return OPERATOR_RUNNING_MODAL;
}
-static int change_frame_modal(bContext *C, wmOperator *op, wmEvent *event)
+static int change_frame_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
switch (event->type) {
case ESCKEY:
@@ -971,46 +981,39 @@ static int proxy_bitflag_to_array(int size_flag, int build_sizes[4], int undisto
return build_count;
}
-/* only this runs inside thread */
-static void proxy_startjob(void *pjv, short *stop, short *do_update, float *progress)
+/* simple case for movies -- handle frame-by-frame, do threading within single frame */
+static void do_movie_proxy(void *pjv, int *UNUSED(build_sizes), int UNUSED(build_count),
+ int *build_undistort_sizes, int build_undistort_count,
+ short *stop, short *do_update, float *progress)
{
ProxyJob *pj = pjv;
Scene *scene = pj->scene;
MovieClip *clip = pj->clip;
struct MovieDistortion *distortion = NULL;
- short size_flag;
int cfra, sfra = SFRA, efra = EFRA;
- int build_sizes[4], build_count = 0;
- int build_undistort_sizes[4], build_undistort_count = 0;
- size_flag = clip->proxy.build_size_flag;
-
- build_count = proxy_bitflag_to_array(size_flag, build_sizes, 0);
- build_undistort_count = proxy_bitflag_to_array(size_flag, build_undistort_sizes, 1);
-
- if (clip->source == MCLIP_SRC_MOVIE) {
- if (pj->index_context)
- IMB_anim_index_rebuild(pj->index_context, stop, do_update, progress);
+ if (pj->index_context)
+ IMB_anim_index_rebuild(pj->index_context, stop, do_update, progress);
- if (!build_undistort_count) {
- if (*stop)
- pj->stop = 1;
+ if (!build_undistort_count) {
+ if (*stop)
+ pj->stop = 1;
- return;
- }
- else {
- sfra = 1;
- efra = IMB_anim_get_duration(clip->anim, IMB_TC_NONE);
- }
+ return;
}
+ else {
+ sfra = 1;
+ efra = IMB_anim_get_duration(clip->anim, IMB_TC_NONE);
+ }
+
+ if (build_undistort_count) {
+ int threads = BLI_system_thread_count();
- if (build_undistort_count)
distortion = BKE_tracking_distortion_new();
+ BKE_tracking_distortion_set_threads(distortion, threads);
+ }
for (cfra = sfra; cfra <= efra; cfra++) {
- if (clip->source != MCLIP_SRC_MOVIE)
- BKE_movieclip_build_proxy_frame(clip, pj->clip_flag, NULL, cfra, build_sizes, build_count, 0);
-
BKE_movieclip_build_proxy_frame(clip, pj->clip_flag, distortion, cfra,
build_undistort_sizes, build_undistort_count, 1);
@@ -1028,6 +1031,193 @@ static void proxy_startjob(void *pjv, short *stop, short *do_update, float *prog
pj->stop = 1;
}
+/* *****
+ * special case for sequences -- handle different frames in different threads,
+ * loading from disk happens in critical section, decoding frame happens from
+ * thread for maximal speed
+ */
+
+typedef struct ProxyQueue {
+ int cfra;
+ int sfra;
+ int efra;
+ SpinLock spin;
+
+ short *stop;
+ short *do_update;
+ float *progress;
+} ProxyQueue;
+
+typedef struct ProxyThread {
+ MovieClip *clip;
+ ProxyQueue *queue;
+
+ struct MovieDistortion *distortion;
+
+ int *build_sizes, build_count;
+ int *build_undistort_sizes, build_undistort_count;
+} ProxyThread;
+
+static unsigned char *proxy_thread_next_frame(ProxyQueue *queue, MovieClip *clip, size_t *size_r, int *cfra_r)
+{
+ unsigned char *mem = NULL;
+
+ BLI_spin_lock(&queue->spin);
+ if (!*queue->stop && queue->cfra <= queue->efra) {
+ char name[FILE_MAX];
+ size_t size;
+ int file;
+
+ BKE_movieclip_filename_for_frame(clip, queue->cfra, name);
+
+ file = open(name, O_BINARY | O_RDONLY, 0);
+ if (file < 0) {
+ BLI_spin_unlock(&queue->spin);
+ return NULL;
+ }
+
+ size = BLI_file_descriptor_size(file);
+ if (size < 1) {
+ close(file);
+ BLI_spin_unlock(&queue->spin);
+ return NULL;
+ }
+
+ mem = MEM_mallocN(size, "movieclip proxy memory file");
+
+ if (read(file, mem, size) != size) {
+ close(file);
+ BLI_spin_unlock(&queue->spin);
+ MEM_freeN(mem);
+ return NULL;
+ }
+
+ *size_r = size;
+ *cfra_r = queue->cfra;
+
+ queue->cfra++;
+ close(file);
+
+ *queue->do_update = 1;
+ *queue->progress = (float)(queue->cfra - queue->sfra) / (queue->efra - queue->sfra);
+ }
+ BLI_spin_unlock(&queue->spin);
+
+ return mem;
+}
+
+static void *do_proxy_thread(void *data_v)
+{
+ ProxyThread *data = (ProxyThread *) data_v;
+ unsigned char *mem;
+ size_t size;
+ int cfra;
+
+ while ((mem = proxy_thread_next_frame(data->queue, data->clip, &size, &cfra))) {
+ ImBuf *ibuf;
+
+ ibuf = IMB_ibImageFromMemory(mem, size, IB_rect | IB_multilayer | IB_alphamode_detect, NULL, "proxy frame");
+
+ BKE_movieclip_build_proxy_frame_for_ibuf(data->clip, ibuf, NULL, cfra,
+ data->build_sizes, data->build_count, FALSE);
+
+ BKE_movieclip_build_proxy_frame_for_ibuf(data->clip, ibuf, data->distortion, cfra,
+ data->build_undistort_sizes, data->build_undistort_count, TRUE);
+
+ IMB_freeImBuf(ibuf);
+
+ MEM_freeN(mem);
+ }
+
+ return NULL;
+}
+
+static void do_sequence_proxy(void *pjv, int *build_sizes, int build_count,
+ int *build_undistort_sizes, int build_undistort_count,
+ short *stop, short *do_update, float *progress)
+{
+ ProxyJob *pj = pjv;
+ MovieClip *clip = pj->clip;
+ Scene *scene = pj->scene;
+ int sfra = SFRA, efra = EFRA;
+ ProxyThread *handles;
+ ListBase threads;
+ int i, tot_thread = BLI_system_thread_count();
+ ProxyQueue queue;
+
+ BLI_spin_init(&queue.spin);
+
+ queue.cfra = sfra;
+ queue.sfra = sfra;
+ queue.efra = efra;
+ queue.stop = stop;
+ queue.do_update = do_update;
+ queue.progress = progress;
+
+ handles = MEM_callocN(sizeof(ProxyThread) * tot_thread, "proxy threaded handles");
+
+ if (tot_thread > 1)
+ BLI_init_threads(&threads, do_proxy_thread, tot_thread);
+
+ for (i = 0; i < tot_thread; i++) {
+ ProxyThread *handle = &handles[i];
+
+ handle->clip = clip;
+ handle->queue = &queue;
+
+ handle->build_count = build_count;
+ handle->build_sizes = build_sizes;
+
+ handle->build_undistort_count = build_undistort_count;
+ handle->build_undistort_sizes = build_undistort_sizes;
+
+ if (build_undistort_count)
+ handle->distortion = BKE_tracking_distortion_new();
+
+ if (tot_thread > 1)
+ BLI_insert_thread(&threads, handle);
+ }
+
+ if (tot_thread > 1)
+ BLI_end_threads(&threads);
+ else
+ do_proxy_thread(handles);
+
+ MEM_freeN(handles);
+
+ if (build_undistort_count) {
+ for (i = 0; i < tot_thread; i++) {
+ ProxyThread *handle = &handles[i];
+
+ BKE_tracking_distortion_free(handle->distortion);
+ }
+ }
+}
+
+static void proxy_startjob(void *pjv, short *stop, short *do_update, float *progress)
+{
+ ProxyJob *pj = pjv;
+ MovieClip *clip = pj->clip;
+
+ short size_flag;
+ int build_sizes[4], build_count = 0;
+ int build_undistort_sizes[4], build_undistort_count = 0;
+
+ size_flag = clip->proxy.build_size_flag;
+
+ build_count = proxy_bitflag_to_array(size_flag, build_sizes, 0);
+ build_undistort_count = proxy_bitflag_to_array(size_flag, build_undistort_sizes, 1);
+
+ if (clip->source == MCLIP_SRC_MOVIE) {
+ do_movie_proxy(pjv, build_sizes, build_count, build_undistort_sizes,
+ build_undistort_count, stop, do_update, progress);
+ }
+ else {
+ do_sequence_proxy(pjv, build_sizes, build_count, build_undistort_sizes,
+ build_undistort_count, stop, do_update, progress);
+ }
+}
+
static void proxy_endjob(void *pjv)
{
ProxyJob *pj = pjv;
@@ -1134,7 +1324,7 @@ void CLIP_OT_mode_set(wmOperatorType *ot)
* that explains the negative signs in the code below
*/
-static int clip_view_ndof_invoke(bContext *C, wmOperator *UNUSED(op), wmEvent *event)
+static int clip_view_ndof_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *event)
{
if (event->type != NDOF_MOTION)
return OPERATOR_CANCELLED;
diff --git a/source/blender/editors/space_clip/clip_toolbar.c b/source/blender/editors/space_clip/clip_toolbar.c
index 7543988b5aa..10175d07300 100644
--- a/source/blender/editors/space_clip/clip_toolbar.c
+++ b/source/blender/editors/space_clip/clip_toolbar.c
@@ -33,8 +33,6 @@
#include "DNA_windowmanager_types.h"
-#include "RNA_access.h"
-
#include "MEM_guardedalloc.h"
#include "BLI_blenlib.h"
@@ -45,12 +43,14 @@
#include "BKE_context.h"
#include "BKE_screen.h"
-#include "ED_screen.h"
-#include "ED_util.h"
+#include "RNA_access.h"
#include "WM_types.h"
#include "WM_api.h"
+#include "ED_screen.h"
+#include "ED_util.h"
+
#include "UI_interface.h"
#include "UI_resources.h"
diff --git a/source/blender/editors/space_clip/space_clip.c b/source/blender/editors/space_clip/space_clip.c
index f0c0e7b72fd..4f9757a6640 100644
--- a/source/blender/editors/space_clip/space_clip.c
+++ b/source/blender/editors/space_clip/space_clip.c
@@ -534,6 +534,7 @@ static void clip_operatortypes(void)
/* ** clip_dopesheet_ops.c ** */
WM_operatortype_append(CLIP_OT_dopesheet_select_channel);
+ WM_operatortype_append(CLIP_OT_dopesheet_view_all);
}
static void clip_keymap(struct wmKeyConfig *keyconf)
@@ -768,6 +769,8 @@ static void clip_keymap(struct wmKeyConfig *keyconf)
kmi = WM_keymap_add_item(keymap, "CLIP_OT_dopesheet_select_channel", ACTIONMOUSE, KM_PRESS, 0, 0);
RNA_boolean_set(kmi->ptr, "extend", TRUE); /* toggle */
+
+ WM_keymap_add_item(keymap, "CLIP_OT_dopesheet_view_all", HOMEKEY, KM_PRESS, 0, 0);
}
const char *clip_context_dir[] = {"edit_movieclip", "edit_mask", NULL};
@@ -796,7 +799,7 @@ static int clip_context(const bContext *C, const char *member, bContextDataResul
}
/* dropboxes */
-static int clip_drop_poll(bContext *UNUSED(C), wmDrag *drag, wmEvent *UNUSED(event))
+static int clip_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUSED(event))
{
if (drag->type == WM_DRAG_PATH)
if (ELEM3(drag->icon, 0, ICON_FILE_IMAGE, ICON_FILE_BLANK)) /* rule might not work? */
@@ -1191,6 +1194,9 @@ static void clip_preview_area_init(wmWindowManager *wm, ARegion *ar)
keymap = WM_keymap_find(wm->defaultconf, "Clip Graph Editor", SPACE_CLIP, 0);
WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct);
+
+ keymap = WM_keymap_find(wm->defaultconf, "Clip Dopesheet Editor", SPACE_CLIP, 0);
+ WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct);
}
static void graph_area_draw(const bContext *C, ARegion *ar)
diff --git a/source/blender/editors/space_clip/tracking_ops.c b/source/blender/editors/space_clip/tracking_ops.c
index ac7ebd9ddac..a51315d9a16 100644
--- a/source/blender/editors/space_clip/tracking_ops.c
+++ b/source/blender/editors/space_clip/tracking_ops.c
@@ -124,7 +124,7 @@ static int add_marker_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int add_marker_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int add_marker_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
SpaceClip *sc = CTX_wm_space_clip(C);
ARegion *ar = CTX_wm_region(C);
@@ -282,7 +282,7 @@ static void slide_marker_tilt_slider(MovieTrackingMarker *marker, float slider[2
}
static SlideMarkerData *create_slide_marker_data(SpaceClip *sc, MovieTrackingTrack *track,
- MovieTrackingMarker *marker, wmEvent *event,
+ MovieTrackingMarker *marker, const wmEvent *event,
int area, int corner, int action, int width, int height)
{
SlideMarkerData *data = MEM_callocN(sizeof(SlideMarkerData), "slide marker data");
@@ -524,7 +524,7 @@ static void show_cursor(bContext *C)
WM_cursor_set(win, CURSOR_STD);
}
-MovieTrackingTrack *tracking_marker_check_slide(bContext *C, wmEvent *event, int *area_r, int *action_r, int *corner_r)
+MovieTrackingTrack *tracking_marker_check_slide(bContext *C, const wmEvent *event, int *area_r, int *action_r, int *corner_r)
{
SpaceClip *sc = CTX_wm_space_clip(C);
ARegion *ar = CTX_wm_region(C);
@@ -623,7 +623,7 @@ MovieTrackingTrack *tracking_marker_check_slide(bContext *C, wmEvent *event, int
return NULL;
}
-static void *slide_marker_customdata(bContext *C, wmEvent *event)
+static void *slide_marker_customdata(bContext *C, const wmEvent *event)
{
SpaceClip *sc = CTX_wm_space_clip(C);
ARegion *ar = CTX_wm_region(C);
@@ -652,7 +652,7 @@ static void *slide_marker_customdata(bContext *C, wmEvent *event)
return customdata;
}
-static int slide_marker_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int slide_marker_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
SlideMarkerData *slidedata = slide_marker_customdata(C, event);
@@ -703,7 +703,7 @@ static void free_slide_data(SlideMarkerData *data)
MEM_freeN(data);
}
-static int slide_marker_modal(bContext *C, wmOperator *op, wmEvent *event)
+static int slide_marker_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
SpaceClip *sc = CTX_wm_space_clip(C);
ARegion *ar = CTX_wm_region(C);
@@ -1228,7 +1228,7 @@ static int track_markers_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int track_markers_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int track_markers_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
TrackMarkersJob *tmj;
ScrArea *sa = CTX_wm_area(C);
@@ -1286,7 +1286,7 @@ static int track_markers_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(eve
return OPERATOR_RUNNING_MODAL;
}
-static int track_markers_modal(bContext *C, wmOperator *UNUSED(op), wmEvent *event)
+static int track_markers_modal(bContext *C, wmOperator *UNUSED(op), const wmEvent *event)
{
/* no running tracking, remove handler and pass through */
if (0 == WM_jobs_test(CTX_wm_manager(C), CTX_wm_area(C), WM_JOB_TYPE_ANY))
@@ -1457,7 +1457,7 @@ static int solve_camera_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int solve_camera_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int solve_camera_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
SolveCameraJob *scj;
ScrArea *sa = CTX_wm_area(C);
@@ -1507,7 +1507,7 @@ static int solve_camera_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(even
return OPERATOR_RUNNING_MODAL;
}
-static int solve_camera_modal(bContext *C, wmOperator *UNUSED(op), wmEvent *event)
+static int solve_camera_modal(bContext *C, wmOperator *UNUSED(op), const wmEvent *event)
{
/* no running solver, remove handler and pass through */
if (0 == WM_jobs_test(CTX_wm_manager(C), CTX_wm_area(C), WM_JOB_TYPE_ANY))
@@ -2334,7 +2334,7 @@ static int set_scale_exec(bContext *C, wmOperator *op)
return do_set_scale(C, op, 0);
}
-static int set_scale_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int set_scale_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
SpaceClip *sc = CTX_wm_space_clip(C);
MovieClip *clip = ED_space_clip_get_clip(sc);
@@ -2390,7 +2390,7 @@ static int set_solution_scale_exec(bContext *C, wmOperator *op)
return do_set_scale(C, op, 1);
}
-static int set_solution_scale_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int set_solution_scale_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
SpaceClip *sc = CTX_wm_space_clip(C);
MovieClip *clip = ED_space_clip_get_clip(sc);
@@ -3258,7 +3258,7 @@ static int clean_tracks_exec(bContext *C, wmOperator *op)
next = track->next;
if ((track->flag & TRACK_HIDDEN) == 0 && (track->flag & TRACK_LOCKED) == 0) {
- int ok = 1;
+ bool ok;
ok = (is_track_clean(track, frames, action == TRACKING_CLEAN_DELETE_SEGMENT)) &&
(error == 0.0f || (track->flag & TRACK_HAS_BUNDLE) == 0 || track->error < error);
@@ -3295,7 +3295,7 @@ static int clean_tracks_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int clean_tracks_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int clean_tracks_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
SpaceClip *sc = CTX_wm_space_clip(C);
MovieClip *clip = ED_space_clip_get_clip(sc);
diff --git a/source/blender/editors/space_clip/tracking_select.c b/source/blender/editors/space_clip/tracking_select.c
index bec50130230..b03209173d8 100644
--- a/source/blender/editors/space_clip/tracking_select.c
+++ b/source/blender/editors/space_clip/tracking_select.c
@@ -268,6 +268,17 @@ static int mouse_select(bContext *C, float co[2], int extend)
return OPERATOR_FINISHED;
}
+static int select_poll(bContext *C)
+{
+ SpaceClip *sc = CTX_wm_space_clip(C);
+
+ if (sc) {
+ return sc->clip && sc->view == SC_VIEW_CLIP;
+ }
+
+ return FALSE;
+}
+
static int select_exec(bContext *C, wmOperator *op)
{
float co[2];
@@ -279,7 +290,7 @@ static int select_exec(bContext *C, wmOperator *op)
return mouse_select(C, co, extend);
}
-static int select_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int select_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
SpaceClip *sc = CTX_wm_space_clip(C);
ARegion *ar = CTX_wm_region(C);
@@ -317,8 +328,7 @@ void CLIP_OT_select(wmOperatorType *ot)
/* api callbacks */
ot->exec = select_exec;
ot->invoke = select_invoke;
- //ot->poll = ED_space_clip_tracking_poll; // so mask view can Ctrl+RMB markers
- ot->poll = ED_space_clip_view_clip_poll;
+ ot->poll = select_poll;
/* flags */
ot->flag = OPTYPE_UNDO;
diff --git a/source/blender/editors/space_console/console_draw.c b/source/blender/editors/space_console/console_draw.c
index 73747239255..cb191d0b15e 100644
--- a/source/blender/editors/space_console/console_draw.c
+++ b/source/blender/editors/space_console/console_draw.c
@@ -150,6 +150,26 @@ static int console_textview_line_get(struct TextViewContext *tvc, const char **l
return 1;
}
+static void console_cursor_wrap_offset(const char *str, int width, int *row, int *column, const char *end)
+{
+ int col;
+
+ for (; *str; str += BLI_str_utf8_size_safe(str)) {
+ col = BLI_str_utf8_char_width_safe(str);
+
+ if (*column + col > width) {
+ (*row)++;
+ *column = 0;
+ }
+
+ if (end && str >= end)
+ break;
+
+ *column += col;
+ }
+ return;
+}
+
static int console_textview_line_color(struct TextViewContext *tvc, unsigned char fg[3], unsigned char UNUSED(bg[3]))
{
ConsoleLine *cl_iter = (ConsoleLine *)tvc->iter;
@@ -158,24 +178,18 @@ static int console_textview_line_color(struct TextViewContext *tvc, unsigned cha
if (tvc->iter_index == 0) {
const SpaceConsole *sc = (SpaceConsole *)tvc->arg1;
const ConsoleLine *cl = (ConsoleLine *)sc->history.last;
- const int prompt_len = BLI_strlen_utf8(sc->prompt);
- const int cursor_loc = BLI_strnlen_utf8(cl->line, cl->cursor) + prompt_len;
- const int line_len = BLI_strlen_utf8(cl->line) + prompt_len;
+ int offl = 0, offc = 0;
int xy[2] = {CONSOLE_DRAW_MARGIN, CONSOLE_DRAW_MARGIN};
int pen[2];
xy[1] += tvc->lheight / 6;
- /* account for wrapping */
- if (line_len < tvc->console_width) {
- /* simple case, no wrapping */
- pen[0] = tvc->cwidth * cursor_loc;
- pen[1] = -2;
- }
- else {
- /* wrap */
- pen[0] = tvc->cwidth * (cursor_loc % tvc->console_width);
- pen[1] = -2 + (((line_len / tvc->console_width) - (cursor_loc / tvc->console_width)) * tvc->lheight);
- }
+ console_cursor_wrap_offset(sc->prompt, tvc->console_width, &offl, &offc, NULL);
+ console_cursor_wrap_offset(cl->line, tvc->console_width, &offl, &offc, cl->line + cl->cursor);
+ pen[0] = tvc->cwidth * offc;
+ pen[1] = -2 - tvc->lheight * offl;
+
+ console_cursor_wrap_offset(cl->line + cl->cursor, tvc->console_width, &offl, &offc, NULL);
+ pen[1] += tvc->lheight * offl;
/* cursor */
UI_GetThemeColor3ubv(TH_CONSOLE_CURSOR, fg);
diff --git a/source/blender/editors/space_console/console_ops.c b/source/blender/editors/space_console/console_ops.c
index 1242d123a41..b735dee5bdf 100644
--- a/source/blender/editors/space_console/console_ops.c
+++ b/source/blender/editors/space_console/console_ops.c
@@ -390,7 +390,7 @@ static int console_insert_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int console_insert_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int console_insert_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
// if (!RNA_struct_property_is_set(op->ptr, "text")) { /* always set from keymap XXX */
if (!RNA_string_length(op->ptr, "text")) {
@@ -1042,7 +1042,7 @@ static void console_cursor_set_to_pos(SpaceConsole *sc, ARegion *ar, SetConsoleC
}
}
-static void console_modal_select_apply(bContext *C, wmOperator *op, wmEvent *event)
+static void console_modal_select_apply(bContext *C, wmOperator *op, const wmEvent *event)
{
SpaceConsole *sc = CTX_wm_space_console(C);
ARegion *ar = CTX_wm_region(C);
@@ -1080,7 +1080,7 @@ static void console_cursor_set_exit(bContext *UNUSED(C), wmOperator *op)
MEM_freeN(scu);
}
-static int console_modal_select_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int console_modal_select_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
SpaceConsole *sc = CTX_wm_space_console(C);
// ARegion *ar = CTX_wm_region(C);
@@ -1101,7 +1101,7 @@ static int console_modal_select_invoke(bContext *C, wmOperator *op, wmEvent *eve
return OPERATOR_RUNNING_MODAL;
}
-static int console_modal_select(bContext *C, wmOperator *op, wmEvent *event)
+static int console_modal_select(bContext *C, wmOperator *op, const wmEvent *event)
{
switch (event->type) {
case LEFTMOUSE:
diff --git a/source/blender/editors/space_console/space_console.c b/source/blender/editors/space_console/space_console.c
index eed269ff70f..4243ae4e2df 100644
--- a/source/blender/editors/space_console/space_console.c
+++ b/source/blender/editors/space_console/space_console.c
@@ -160,7 +160,7 @@ static void console_main_area_init(wmWindowManager *wm, ARegion *ar)
/* ************* dropboxes ************* */
-static int id_drop_poll(bContext *UNUSED(C), wmDrag *drag, wmEvent *UNUSED(event))
+static int id_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUSED(event))
{
// SpaceConsole *sc = CTX_wm_space_console(C);
if (drag->type == WM_DRAG_ID)
@@ -179,7 +179,7 @@ static void id_drop_copy(wmDrag *drag, wmDropBox *drop)
MEM_freeN(text);
}
-static int path_drop_poll(bContext *UNUSED(C), wmDrag *drag, wmEvent *UNUSED(event))
+static int path_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUSED(event))
{
// SpaceConsole *sc = CTX_wm_space_console(C);
if (drag->type == WM_DRAG_PATH)
diff --git a/source/blender/editors/space_file/file_draw.c b/source/blender/editors/space_file/file_draw.c
index afe32ec0b85..5b6b8656072 100644
--- a/source/blender/editors/space_file/file_draw.c
+++ b/source/blender/editors/space_file/file_draw.c
@@ -35,6 +35,7 @@
#include "BLI_blenlib.h"
#include "BLI_utildefines.h"
#include "BLI_dynstr.h"
+#include "BLI_fileops_types.h"
#ifdef WIN32
# include "BLI_winstuff.h"
@@ -55,6 +56,7 @@
#include "MEM_guardedalloc.h"
#include "DNA_userdef_types.h"
+#include "DNA_windowmanager_types.h"
#include "RNA_access.h"
@@ -374,7 +376,7 @@ static void file_draw_preview(uiBlock *block, struct direntry *file, int sx, int
/* the image */
glColor4f(1.0, 1.0, 1.0, 1.0);
- glaDrawPixelsTexScaled((float)xco, (float)yco, imb->x, imb->y, GL_UNSIGNED_BYTE, imb->rect, scale, scale);
+ glaDrawPixelsTexScaled((float)xco, (float)yco, imb->x, imb->y, GL_UNSIGNED_BYTE, GL_NEAREST, imb->rect, scale, scale);
/* border */
if (dropshadow) {
@@ -396,6 +398,7 @@ static void renamebutton_cb(bContext *C, void *UNUSED(arg1), char *oldname)
char newname[FILE_MAX + 12];
char orgname[FILE_MAX + 12];
char filename[FILE_MAX + 12];
+ wmWindowManager *wm = CTX_wm_manager(C);
SpaceFile *sfile = (SpaceFile *)CTX_wm_space_data(C);
ARegion *ar = CTX_wm_region(C);
@@ -407,7 +410,7 @@ static void renamebutton_cb(bContext *C, void *UNUSED(arg1), char *oldname)
if (!BLI_exists(newname)) {
BLI_rename(orgname, newname);
/* to make sure we show what is on disk */
- ED_fileselect_clear(C, sfile);
+ ED_fileselect_clear(wm, sfile);
}
ED_region_tag_redraw(ar);
diff --git a/source/blender/editors/space_file/file_ops.c b/source/blender/editors/space_file/file_ops.c
index 79a578a86d1..f705831c715 100644
--- a/source/blender/editors/space_file/file_ops.c
+++ b/source/blender/editors/space_file/file_ops.c
@@ -30,6 +30,7 @@
#include "BLI_blenlib.h"
#include "BLI_utildefines.h"
+#include "BLI_fileops_types.h"
#include "BKE_context.h"
#include "BKE_screen.h"
@@ -227,7 +228,7 @@ static FileSelect file_select(bContext *C, const rcti *rect, FileSelType select,
return retval;
}
-static int file_border_select_modal(bContext *C, wmOperator *op, wmEvent *event)
+static int file_border_select_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
ARegion *ar = CTX_wm_region(C);
SpaceFile *sfile = CTX_wm_space_file(C);
@@ -310,7 +311,7 @@ void FILE_OT_select_border(wmOperatorType *ot)
WM_operator_properties_gesture_border(ot, 1);
}
-static int file_select_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int file_select_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
ARegion *ar = CTX_wm_region(C);
SpaceFile *sfile = CTX_wm_space_file(C);
@@ -584,7 +585,7 @@ int file_highlight_set(SpaceFile *sfile, ARegion *ar, int mx, int my)
return (params->active_file != origfile);
}
-static int file_highlight_invoke(bContext *C, wmOperator *UNUSED(op), wmEvent *event)
+static int file_highlight_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *event)
{
ARegion *ar = CTX_wm_region(C);
SpaceFile *sfile = CTX_wm_space_file(C);
@@ -611,12 +612,13 @@ void FILE_OT_highlight(struct wmOperatorType *ot)
int file_cancel_exec(bContext *C, wmOperator *UNUSED(unused))
{
+ wmWindowManager *wm = CTX_wm_manager(C);
SpaceFile *sfile = CTX_wm_space_file(C);
wmOperator *op = sfile->op;
sfile->op = NULL;
- WM_event_fileselect_event(C, op, EVT_FILESELECT_CANCEL);
+ WM_event_fileselect_event(wm, op, EVT_FILESELECT_CANCEL);
return OPERATOR_FINISHED;
}
@@ -779,6 +781,7 @@ int file_draw_check_exists(SpaceFile *sfile)
/* sends events now, so things get handled on windowqueue level */
int file_exec(bContext *C, wmOperator *exec_op)
{
+ wmWindowManager *wm = CTX_wm_manager(C);
SpaceFile *sfile = CTX_wm_space_file(C);
char filepath[FILE_MAX];
@@ -810,7 +813,7 @@ int file_exec(bContext *C, wmOperator *exec_op)
BLI_make_file_string(G.main->name, filepath, BLI_get_folder_create(BLENDER_USER_CONFIG, NULL), BLENDER_BOOKMARK_FILE);
fsmenu_write_file(fsmenu_get(), filepath);
- WM_event_fileselect_event(C, op, EVT_FILESELECT_EXEC);
+ WM_event_fileselect_event(wm, op, EVT_FILESELECT_EXEC);
}
@@ -870,10 +873,11 @@ void FILE_OT_parent(struct wmOperatorType *ot)
static int file_refresh_exec(bContext *C, wmOperator *UNUSED(unused))
{
+ wmWindowManager *wm = CTX_wm_manager(C);
SpaceFile *sfile = CTX_wm_space_file(C);
struct FSMenu *fsmenu = fsmenu_get();
- ED_fileselect_clear(C, sfile);
+ ED_fileselect_clear(wm, sfile);
/* refresh system directory menu */
fsmenu_refresh_system_category(fsmenu);
@@ -949,7 +953,7 @@ int file_next_exec(bContext *C, wmOperator *UNUSED(unused))
/* only meant for timer usage */
-static int file_smoothscroll_invoke(bContext *C, wmOperator *UNUSED(op), wmEvent *event)
+static int file_smoothscroll_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *event)
{
ScrArea *sa = CTX_wm_area(C);
SpaceFile *sfile = CTX_wm_space_file(C);
@@ -1087,6 +1091,7 @@ int file_directory_new_exec(bContext *C, wmOperator *op)
char path[FILE_MAX];
int generate_name = 1;
+ wmWindowManager *wm = CTX_wm_manager(C);
SpaceFile *sfile = CTX_wm_space_file(C);
if (!sfile->params) {
@@ -1125,7 +1130,7 @@ int file_directory_new_exec(bContext *C, wmOperator *op)
sfile->scroll_offset = 0;
/* reload dir to make sure we're seeing what's in the directory */
- ED_fileselect_clear(C, sfile);
+ ED_fileselect_clear(wm, sfile);
WM_event_add_notifier(C, NC_SPACE | ND_SPACE_FILE_LIST, NULL);
return OPERATOR_FINISHED;
@@ -1189,7 +1194,7 @@ static void file_expand_directory(bContext *C)
}
}
-static int file_directory_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int file_directory_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
SpaceFile *sfile = CTX_wm_space_file(C);
@@ -1227,7 +1232,6 @@ int file_directory_exec(bContext *C, wmOperator *UNUSED(unused))
}
BLI_cleanup_dir(G.main->name, sfile->params->dir);
- BLI_add_slash(sfile->params->dir);
file_change_dir(C, 1);
WM_event_add_notifier(C, NC_SPACE | ND_SPACE_FILE_LIST, NULL);
@@ -1291,11 +1295,12 @@ void FILE_OT_refresh(struct wmOperatorType *ot)
static int file_hidedot_exec(bContext *C, wmOperator *UNUSED(unused))
{
+ wmWindowManager *wm = CTX_wm_manager(C);
SpaceFile *sfile = CTX_wm_space_file(C);
if (sfile->params) {
sfile->params->flag ^= FILE_HIDE_DOT;
- ED_fileselect_clear(C, sfile);
+ ED_fileselect_clear(wm, sfile);
WM_event_add_notifier(C, NC_SPACE | ND_SPACE_FILE_LIST, NULL);
}
@@ -1477,14 +1482,15 @@ static int file_delete_poll(bContext *C)
int file_delete_exec(bContext *C, wmOperator *UNUSED(op))
{
char str[FILE_MAX];
+ wmWindowManager *wm = CTX_wm_manager(C);
SpaceFile *sfile = CTX_wm_space_file(C);
struct direntry *file;
file = filelist_file(sfile->files, sfile->params->active_file);
BLI_make_file_string(G.main->name, str, sfile->params->dir, file->relname);
- BLI_delete(str, 0, 0);
- ED_fileselect_clear(C, sfile);
+ BLI_delete(str, false, false);
+ ED_fileselect_clear(wm, sfile);
WM_event_add_notifier(C, NC_SPACE | ND_SPACE_FILE_LIST, NULL);
return OPERATOR_FINISHED;
diff --git a/source/blender/editors/space_file/filelist.c b/source/blender/editors/space_file/filelist.c
index 142eb2214a1..f1e707f8802 100644
--- a/source/blender/editors/space_file/filelist.c
+++ b/source/blender/editors/space_file/filelist.c
@@ -48,6 +48,7 @@
#include "BLI_linklist.h"
#include "BLI_threads.h"
#include "BLI_utildefines.h"
+#include "BLI_fileops_types.h"
#ifdef WIN32
# include "BLI_winstuff.h"
@@ -545,8 +546,6 @@ FileList *filelist_new(short type)
void filelist_free(struct FileList *filelist)
{
- int i;
-
if (!filelist) {
printf("Attempting to delete empty filelist.\n");
return;
@@ -557,23 +556,8 @@ void filelist_free(struct FileList *filelist)
filelist->fidx = NULL;
}
- for (i = 0; i < filelist->numfiles; ++i) {
- if (filelist->filelist[i].image) {
- IMB_freeImBuf(filelist->filelist[i].image);
- }
- filelist->filelist[i].image = NULL;
- if (filelist->filelist[i].relname)
- MEM_freeN(filelist->filelist[i].relname);
- if (filelist->filelist[i].path)
- MEM_freeN(filelist->filelist[i].path);
- filelist->filelist[i].relname = NULL;
- if (filelist->filelist[i].string)
- MEM_freeN(filelist->filelist[i].string);
- filelist->filelist[i].string = NULL;
- }
-
+ BLI_free_filelist(filelist->filelist, filelist->numfiles);
filelist->numfiles = 0;
- free(filelist->filelist);
filelist->filelist = NULL;
filelist->filter = 0;
filelist->filter_glob[0] = '\0';
@@ -874,18 +858,14 @@ static void filelist_setfiletypes(struct FileList *filelist)
static void filelist_read_dir(struct FileList *filelist)
{
- char wdir[FILE_MAX] = "";
if (!filelist) return;
filelist->fidx = NULL;
filelist->filelist = NULL;
- BLI_current_working_dir(wdir, sizeof(wdir)); /* backup cwd to restore after */
-
BLI_cleanup_dir(G.main->name, filelist->dir);
filelist->numfiles = BLI_dir_contents(filelist->dir, &(filelist->filelist));
- if (!chdir(wdir)) {} /* fix warning about not checking return value */
filelist_setfiletypes(filelist);
filelist_filter(filelist);
}
@@ -1033,7 +1013,7 @@ static int groupname_to_code(const char *group)
char *lslash;
BLI_strncpy(buf, group, sizeof(buf));
- lslash = BLI_last_slash(buf);
+ lslash = (char *)BLI_last_slash(buf);
if (lslash)
lslash[0] = '\0';
@@ -1364,7 +1344,7 @@ static void thumbnails_free(void *tjv)
}
-void thumbnails_start(struct FileList *filelist, const struct bContext *C)
+void thumbnails_start(FileList *filelist, const bContext *C)
{
wmJob *wm_job;
ThumbnailJob *tj;
@@ -1376,7 +1356,7 @@ void thumbnails_start(struct FileList *filelist, const struct bContext *C)
for (idx = 0; idx < filelist->numfiles; idx++) {
if (!filelist->filelist[idx].image) {
if ( (filelist->filelist[idx].flags & (IMAGEFILE | MOVIEFILE | BLENDERFILE | BLENDERFILE_BACKUP)) ) {
- FileImage *limg = MEM_callocN(sizeof(struct FileImage), "loadimage");
+ FileImage *limg = MEM_callocN(sizeof(FileImage), "loadimage");
BLI_strncpy(limg->path, filelist->filelist[idx].path, FILE_MAX);
limg->index = idx;
limg->flags = filelist->filelist[idx].flags;
@@ -1398,12 +1378,12 @@ void thumbnails_start(struct FileList *filelist, const struct bContext *C)
WM_jobs_start(CTX_wm_manager(C), wm_job);
}
-void thumbnails_stop(struct FileList *filelist, const struct bContext *C)
+void thumbnails_stop(wmWindowManager *wm, FileList *filelist)
{
- WM_jobs_kill(CTX_wm_manager(C), filelist, NULL);
+ WM_jobs_kill(wm, filelist, NULL);
}
-int thumbnails_running(struct FileList *filelist, const struct bContext *C)
+int thumbnails_running(wmWindowManager *wm, FileList *filelist)
{
- return WM_jobs_test(CTX_wm_manager(C), filelist, WM_JOB_TYPE_FILESEL_THUMBNAIL);
+ return WM_jobs_test(wm, filelist, WM_JOB_TYPE_FILESEL_THUMBNAIL);
}
diff --git a/source/blender/editors/space_file/filelist.h b/source/blender/editors/space_file/filelist.h
index 32a31c51229..d093d427eae 100644
--- a/source/blender/editors/space_file/filelist.h
+++ b/source/blender/editors/space_file/filelist.h
@@ -37,15 +37,16 @@
extern "C" {
#endif
+struct BlendHandle;
struct FileList;
+struct FileSelection;
struct FolderList;
-struct direntry;
-struct BlendHandle;
-struct Scene;
struct Main;
-struct rcti;
struct ReportList;
-struct FileSelection;
+struct Scene;
+struct direntry;
+struct rcti;
+struct wmWindowManager;
typedef enum FileSelType {
FILE_SEL_REMOVE = 0,
@@ -99,9 +100,9 @@ void folderlist_popdir(struct ListBase *folderlist, char *dir);
void folderlist_pushdir(struct ListBase *folderlist, const char *dir);
int folderlist_clear_next(struct SpaceFile *sfile);
-void thumbnails_stop(struct FileList *filelist, const struct bContext *C);
void thumbnails_start(struct FileList *filelist, const struct bContext *C);
-int thumbnails_running(struct FileList *filelist, const struct bContext *C);
+void thumbnails_stop(struct wmWindowManager *wm, struct FileList *filelist);
+int thumbnails_running(struct wmWindowManager *wm, struct FileList *filelist);
#ifdef __cplusplus
}
diff --git a/source/blender/editors/space_file/filesel.c b/source/blender/editors/space_file/filesel.c
index 3c6f6358171..b8db7dc97b7 100644
--- a/source/blender/editors/space_file/filesel.c
+++ b/source/blender/editors/space_file/filesel.c
@@ -58,6 +58,7 @@
#include "BLI_linklist.h"
#include "BLI_dynstr.h"
#include "BLI_utildefines.h"
+#include "BLI_fileops_types.h"
#include "BKE_context.h"
#include "BKE_global.h"
@@ -577,13 +578,14 @@ FileLayout *ED_fileselect_get_layout(struct SpaceFile *sfile, ARegion *ar)
void file_change_dir(bContext *C, int checkdir)
{
+ wmWindowManager *wm = CTX_wm_manager(C);
SpaceFile *sfile = CTX_wm_space_file(C);
if (sfile->params) {
- ED_fileselect_clear(C, sfile);
+ ED_fileselect_clear(wm, sfile);
- if (checkdir && BLI_is_dir(sfile->params->dir) == 0) {
+ if (checkdir && !BLI_is_dir(sfile->params->dir)) {
BLI_strncpy(sfile->params->dir, filelist_dir(sfile->files), sizeof(sfile->params->dir));
/* could return but just refresh the current dir */
}
@@ -690,24 +692,24 @@ void autocomplete_file(struct bContext *C, char *str, void *UNUSED(arg_v))
}
}
-void ED_fileselect_clear(struct bContext *C, struct SpaceFile *sfile)
+void ED_fileselect_clear(struct wmWindowManager *wm, struct SpaceFile *sfile)
{
/* only NULL in rare cases - [#29734] */
if (sfile->files) {
- thumbnails_stop(sfile->files, C);
+ thumbnails_stop(wm, sfile->files);
filelist_freelib(sfile->files);
filelist_free(sfile->files);
}
sfile->params->active_file = -1;
- WM_event_add_notifier(C, NC_SPACE | ND_SPACE_FILE_LIST, NULL);
+ WM_main_add_notifier(NC_SPACE | ND_SPACE_FILE_LIST, NULL);
}
-void ED_fileselect_exit(struct bContext *C, struct SpaceFile *sfile)
+void ED_fileselect_exit(struct wmWindowManager *wm, struct SpaceFile *sfile)
{
if (!sfile) return;
if (sfile->op) {
- WM_event_fileselect_event(C, sfile->op, EVT_FILESELECT_EXTERNAL_CANCEL);
+ WM_event_fileselect_event(wm, sfile->op, EVT_FILESELECT_EXTERNAL_CANCEL);
sfile->op = NULL;
}
@@ -715,7 +717,7 @@ void ED_fileselect_exit(struct bContext *C, struct SpaceFile *sfile)
folderlist_free(sfile->folders_next);
if (sfile->files) {
- ED_fileselect_clear(C, sfile);
+ ED_fileselect_clear(wm, sfile);
MEM_freeN(sfile->files);
sfile->files = NULL;
}
diff --git a/source/blender/editors/space_file/fsmenu.c b/source/blender/editors/space_file/fsmenu.c
index 5f1f9a3ab22..04c68e5ea68 100644
--- a/source/blender/editors/space_file/fsmenu.c
+++ b/source/blender/editors/space_file/fsmenu.c
@@ -281,14 +281,14 @@ void fsmenu_write_file(struct FSMenu *fsmenu, const char *filename)
void fsmenu_read_bookmarks(struct FSMenu *fsmenu, const char *filename)
{
- char line[256];
+ char line[FILE_MAXDIR];
FSMenuCategory category = FS_CATEGORY_BOOKMARKS;
FILE *fp;
fp = BLI_fopen(filename, "r");
if (!fp) return;
- while (fgets(line, 256, fp) != NULL) { /* read a line */
+ while (fgets(line, sizeof(line), fp) != NULL) { /* read a line */
if (strncmp(line, "[Bookmarks]", 11) == 0) {
category = FS_CATEGORY_BOOKMARKS;
}
@@ -318,7 +318,7 @@ void fsmenu_read_bookmarks(struct FSMenu *fsmenu, const char *filename)
void fsmenu_read_system(struct FSMenu *fsmenu, int read_bookmarks)
{
- char line[256];
+ char line[FILE_MAXDIR];
#ifdef WIN32
/* Add the drive names to the listing */
{
@@ -376,25 +376,25 @@ void fsmenu_read_system(struct FSMenu *fsmenu, int read_bookmarks)
* TODO : replace hardcoded paths with proper BLI_get_folder calls */
home = getenv("HOME");
if (read_bookmarks && home) {
- BLI_snprintf(line, 256, "%s/", home);
+ BLI_snprintf(line, sizeof(line), "%s/", home);
fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM_BOOKMARKS, line, FS_INSERT_SORTED);
- BLI_snprintf(line, 256, "%s/Desktop/", home);
+ BLI_snprintf(line, sizeof(line), "%s/Desktop/", home);
if (BLI_exists(line)) {
fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM_BOOKMARKS, line, FS_INSERT_SORTED);
}
- BLI_snprintf(line, 256, "%s/Documents/", home);
+ BLI_snprintf(line, sizeof(line), "%s/Documents/", home);
if (BLI_exists(line)) {
fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM_BOOKMARKS, line, FS_INSERT_SORTED);
}
- BLI_snprintf(line, 256, "%s/Pictures/", home);
+ BLI_snprintf(line, sizeof(line), "%s/Pictures/", home);
if (BLI_exists(line)) {
fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM_BOOKMARKS, line, FS_INSERT_SORTED);
}
- BLI_snprintf(line, 256, "%s/Music/", home);
+ BLI_snprintf(line, sizeof(line), "%s/Music/", home);
if (BLI_exists(line)) {
fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM_BOOKMARKS, line, FS_INSERT_SORTED);
}
- BLI_snprintf(line, 256, "%s/Movies/", home);
+ BLI_snprintf(line, sizeof(line), "%s/Movies/", home);
if (BLI_exists(line)) {
fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM_BOOKMARKS, line, FS_INSERT_SORTED);
}
@@ -427,7 +427,7 @@ void fsmenu_read_system(struct FSMenu *fsmenu, int read_bookmarks)
pathString = CFURLCopyFileSystemPath(cfURL, kCFURLPOSIXPathStyle);
- if (!CFStringGetCString(pathString, line, 256, kCFStringEncodingASCII))
+ if (!CFStringGetCString(pathString, line, sizeof(line), kCFStringEncodingASCII))
continue;
fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM, line, FS_INSERT_SORTED);
@@ -480,7 +480,7 @@ void fsmenu_read_system(struct FSMenu *fsmenu, int read_bookmarks)
pathString = CFURLCopyFileSystemPath(cfURL, kCFURLPOSIXPathStyle);
- if (!CFStringGetCString(pathString, line, 256, kCFStringEncodingASCII))
+ if (!CFStringGetCString(pathString, line, sizeof(line), kCFStringEncodingASCII))
continue;
fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM_BOOKMARKS, line, FS_INSERT_SORTED);
@@ -499,9 +499,9 @@ void fsmenu_read_system(struct FSMenu *fsmenu, int read_bookmarks)
const char *home = getenv("HOME");
if (read_bookmarks && home) {
- BLI_snprintf(line, FILE_MAXDIR, "%s/", home);
+ BLI_snprintf(line, sizeof(line), "%s/", home);
fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM_BOOKMARKS, line, FS_INSERT_SORTED);
- BLI_snprintf(line, FILE_MAXDIR, "%s/Desktop/", home);
+ BLI_snprintf(line, sizeof(line), "%s/Desktop/", home);
if (BLI_exists(line)) {
fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM_BOOKMARKS, line, FS_INSERT_SORTED);
}
@@ -527,7 +527,7 @@ void fsmenu_read_system(struct FSMenu *fsmenu, int read_bookmarks)
len = strlen(mnt->mnt_dir);
if (len && mnt->mnt_dir[len - 1] != '/') {
- BLI_snprintf(line, FILE_MAXDIR, "%s/", mnt->mnt_dir);
+ BLI_snprintf(line, sizeof(line), "%s/", mnt->mnt_dir);
fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM, line, FS_INSERT_SORTED);
}
else {
diff --git a/source/blender/editors/space_file/space_file.c b/source/blender/editors/space_file/space_file.c
index 0a4b922bb38..698c355fad3 100644
--- a/source/blender/editors/space_file/space_file.c
+++ b/source/blender/editors/space_file/space_file.c
@@ -28,13 +28,9 @@
* \ingroup spfile
*/
-
#include <string.h>
#include <stdio.h>
-
-#include "RNA_access.h"
-
#include "MEM_guardedalloc.h"
#include "BIF_gl.h"
@@ -45,11 +41,17 @@
#include "BLI_math.h"
#include "BLI_rand.h"
#include "BLI_utildefines.h"
+#include "BLI_fileops_types.h"
#include "BKE_context.h"
#include "BKE_screen.h"
#include "BKE_global.h"
+#include "RNA_access.h"
+
+#include "WM_api.h"
+#include "WM_types.h"
+
#include "ED_space_api.h"
#include "ED_screen.h"
#include "ED_fileselect.h"
@@ -57,9 +59,6 @@
#include "IMB_imbuf_types.h"
#include "IMB_thumbs.h"
-#include "WM_api.h"
-#include "WM_types.h"
-
#include "UI_resources.h"
#include "UI_view2d.h"
@@ -147,7 +146,7 @@ static void file_free(SpaceLink *sl)
/* spacetype; init callback, area size changes, screen set, etc */
-static void file_init(struct wmWindowManager *UNUSED(wm), ScrArea *sa)
+static void file_init(wmWindowManager *UNUSED(wm), ScrArea *sa)
{
SpaceFile *sfile = (SpaceFile *)sa->spacedata.first;
//printf("file_init\n");
@@ -158,6 +157,12 @@ static void file_init(struct wmWindowManager *UNUSED(wm), ScrArea *sa)
if (sfile->layout) sfile->layout->dirty = TRUE;
}
+static void file_exit(wmWindowManager *wm, ScrArea *sa)
+{
+ SpaceFile *sfile = (SpaceFile *)sa->spacedata.first;
+
+ ED_fileselect_exit(wm, sfile);
+}
static SpaceLink *file_duplicate(SpaceLink *sl)
{
@@ -187,6 +192,7 @@ static SpaceLink *file_duplicate(SpaceLink *sl)
static void file_refresh(const bContext *C, ScrArea *UNUSED(sa))
{
+ wmWindowManager *wm = CTX_wm_manager(C);
SpaceFile *sfile = CTX_wm_space_file(C);
FileSelectParams *params = ED_fileselect_get_params(sfile);
@@ -202,7 +208,7 @@ static void file_refresh(const bContext *C, ScrArea *UNUSED(sa))
filelist_setfilter_types(sfile->files, params->filter_glob);
if (filelist_empty(sfile->files)) {
- thumbnails_stop(sfile->files, C);
+ thumbnails_stop(wm, sfile->files);
filelist_readdir(sfile->files);
if (params->sort != FILE_SORT_NONE) {
filelist_sort(sfile->files, params->sort);
@@ -214,7 +220,7 @@ static void file_refresh(const bContext *C, ScrArea *UNUSED(sa))
}
else {
if (params->sort != FILE_SORT_NONE) {
- thumbnails_stop(sfile->files, C);
+ thumbnails_stop(wm, sfile->files);
filelist_sort(sfile->files, params->sort);
if (params->display == FILE_IMGDISPLAY) {
thumbnails_start(sfile->files, C);
@@ -222,14 +228,14 @@ static void file_refresh(const bContext *C, ScrArea *UNUSED(sa))
}
else {
if (params->display == FILE_IMGDISPLAY) {
- if (!thumbnails_running(sfile->files, C)) {
+ if (!thumbnails_running(wm, sfile->files)) {
thumbnails_start(sfile->files, C);
}
}
else {
/* stop any running thumbnail jobs if we're not
* displaying them - speedup for NFS */
- thumbnails_stop(sfile->files, C);
+ thumbnails_stop(wm, sfile->files);
}
filelist_filter(sfile->files);
}
@@ -577,6 +583,7 @@ void ED_spacetype_file(void)
st->new = file_new;
st->free = file_free;
st->init = file_init;
+ st->exit = file_exit;
st->duplicate = file_duplicate;
st->refresh = file_refresh;
st->listener = file_listener;
@@ -629,7 +636,7 @@ void ED_spacetype_file(void)
void ED_file_init(void)
{
- char *cfgdir = BLI_get_folder(BLENDER_USER_CONFIG, NULL);
+ const char * const cfgdir = BLI_get_folder(BLENDER_USER_CONFIG, NULL);
fsmenu_read_system(fsmenu_get(), TRUE);
diff --git a/source/blender/editors/space_graph/graph_edit.c b/source/blender/editors/space_graph/graph_edit.c
index b92430ce0e9..a51fef6c692 100644
--- a/source/blender/editors/space_graph/graph_edit.c
+++ b/source/blender/editors/space_graph/graph_edit.c
@@ -609,7 +609,7 @@ static int graphkeys_click_insert_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int graphkeys_click_insert_invoke(bContext *C, wmOperator *op, wmEvent *evt)
+static int graphkeys_click_insert_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
bAnimContext ac;
ARegion *ar;
@@ -625,8 +625,8 @@ static int graphkeys_click_insert_invoke(bContext *C, wmOperator *op, wmEvent *e
ar = ac.ar;
v2d = &ar->v2d;
- mval[0] = (evt->x - ar->winrct.xmin);
- mval[1] = (evt->y - ar->winrct.ymin);
+ mval[0] = (event->x - ar->winrct.xmin);
+ mval[1] = (event->y - ar->winrct.ymin);
UI_view2d_region_to_view(v2d, mval[0], mval[1], &x, &y);
@@ -835,7 +835,7 @@ static int graphkeys_duplicate_exec(bContext *C, wmOperator *UNUSED(op))
return OPERATOR_FINISHED;
}
-static int graphkeys_duplicate_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int graphkeys_duplicate_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
graphkeys_duplicate_exec(C, op);
@@ -1190,7 +1190,7 @@ static int graphkeys_sound_bake_exec(bContext *UNUSED(C), wmOperator *op)
#endif //WITH_AUDASPACE
-static int graphkeys_sound_bake_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int graphkeys_sound_bake_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
bAnimContext ac;
@@ -2132,7 +2132,7 @@ void GRAPH_OT_smooth(wmOperatorType *ot)
/* ******************** Add F-Modifier Operator *********************** */
/* present a special customised popup menu for this, with some filtering */
-static int graph_fmodifier_add_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int graph_fmodifier_add_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
wmOperatorType *ot = WM_operatortype_find("GRAPH_OT_fmodifier_add", 1);
uiPopupMenu *pup;
@@ -2196,8 +2196,9 @@ static int graph_fmodifier_add_exec(bContext *C, wmOperator *op)
/* add F-Modifier of specified type to active F-Curve, and make it the active one */
fcm = add_fmodifier(&fcu->modifiers, type);
- if (fcm)
+ if (fcm) {
set_active_fmodifier(&fcu->modifiers, fcm);
+ }
else {
BKE_report(op->reports, RPT_ERROR, "Modifier could not be added (see console for details)");
break;
diff --git a/source/blender/editors/space_graph/graph_ops.c b/source/blender/editors/space_graph/graph_ops.c
index 54b417e740a..acb9e42d91b 100644
--- a/source/blender/editors/space_graph/graph_ops.c
+++ b/source/blender/editors/space_graph/graph_ops.c
@@ -109,7 +109,7 @@ static int graphview_cursor_exec(bContext *C, wmOperator *op)
/* ... */
/* set the operator properties from the initial event */
-static void graphview_cursor_setprops(bContext *C, wmOperator *op, wmEvent *event)
+static void graphview_cursor_setprops(bContext *C, wmOperator *op, const wmEvent *event)
{
ARegion *ar = CTX_wm_region(C);
float viewx, viewy;
@@ -128,7 +128,7 @@ static void graphview_cursor_setprops(bContext *C, wmOperator *op, wmEvent *even
}
/* Modal Operator init */
-static int graphview_cursor_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int graphview_cursor_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
/* Change to frame that mouse is over before adding modal handler,
* as user could click on a single frame (jump to frame) as well as
@@ -145,7 +145,7 @@ static int graphview_cursor_invoke(bContext *C, wmOperator *op, wmEvent *event)
}
/* Modal event handling of cursor changing */
-static int graphview_cursor_modal(bContext *C, wmOperator *op, wmEvent *event)
+static int graphview_cursor_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
/* execute the events */
switch (event->type) {
diff --git a/source/blender/editors/space_graph/graph_select.c b/source/blender/editors/space_graph/graph_select.c
index 978b3224850..cbec3072c44 100644
--- a/source/blender/editors/space_graph/graph_select.c
+++ b/source/blender/editors/space_graph/graph_select.c
@@ -815,7 +815,7 @@ static int graphkeys_select_leftright_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int graphkeys_select_leftright_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int graphkeys_select_leftright_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
bAnimContext ac;
short leftright = RNA_enum_get(op->ptr, "mode");
@@ -1297,7 +1297,7 @@ static void graphkeys_mselect_column(bAnimContext *ac, const int mval[2], short
/* ------------------- */
/* handle clicking */
-static int graphkeys_clickselect_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int graphkeys_clickselect_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
bAnimContext ac;
short selectmode;
@@ -1342,10 +1342,13 @@ void GRAPH_OT_clickselect(wmOperatorType *ot)
ot->idname = "GRAPH_OT_clickselect";
ot->description = "Select keyframes by clicking on them";
- /* api callbacks */
+ /* callbacks */
ot->invoke = graphkeys_clickselect_invoke;
ot->poll = graphop_visible_keyframes_poll;
+ /* flags */
+ ot->flag = OPTYPE_UNDO;
+
/* properties */
prop = RNA_def_boolean(ot->srna, "extend", 0, "Extend Select", ""); // SHIFTKEY
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
diff --git a/source/blender/editors/space_image/SConscript b/source/blender/editors/space_image/SConscript
index 6e7c5982d6e..68f747270a3 100644
--- a/source/blender/editors/space_image/SConscript
+++ b/source/blender/editors/space_image/SConscript
@@ -44,7 +44,7 @@ if env['WITH_BF_OPENJPEG']:
if env['WITH_BF_TIFF']:
defs.append('WITH_TIFF')
if env['WITH_BF_CINEON']:
- defs.append('WITH_CINEON')
+ defs.append('WITH_CINEON')
if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'linuxcross', 'win64-vc', 'win64-mingw'):
incs += ' ' + env['BF_PTHREADS_INC']
diff --git a/source/blender/editors/space_image/image_buttons.c b/source/blender/editors/space_image/image_buttons.c
index 6237958e723..70001b59528 100644
--- a/source/blender/editors/space_image/image_buttons.c
+++ b/source/blender/editors/space_image/image_buttons.c
@@ -73,51 +73,55 @@
/* proto */
-static void image_info(Scene *scene, ImageUser *iuser, Image *ima, ImBuf *ibuf, char *str)
+static void image_info(Scene *scene, ImageUser *iuser, Image *ima, ImBuf *ibuf, char *str, size_t len)
{
- int ofs = 0;
+ size_t ofs = 0;
str[0] = 0;
-
- if (ima == NULL) return;
+ if (ima == NULL)
+ return;
if (ibuf == NULL) {
- ofs += sprintf(str, IFACE_("Can't Load Image"));
+ ofs += BLI_strncpy_rlen(str + ofs, IFACE_("Can't Load Image"), len - ofs);
}
else {
if (ima->source == IMA_SRC_MOVIE) {
- ofs += sprintf(str, IFACE_("Movie"));
+ ofs += BLI_strncpy_rlen(str + ofs, IFACE_("Movie"), len - ofs);
if (ima->anim)
- ofs += sprintf(str + ofs, IFACE_(" %d frs"), IMB_anim_get_duration(ima->anim, IMB_TC_RECORD_RUN));
+ ofs += BLI_snprintf(str + ofs, len - ofs, IFACE_(" %d frs"),
+ IMB_anim_get_duration(ima->anim, IMB_TC_RECORD_RUN));
+ }
+ else {
+ ofs += BLI_strncpy_rlen(str, IFACE_("Image"), len - ofs);
}
- else
- ofs += sprintf(str, IFACE_("Image"));
- ofs += sprintf(str + ofs, IFACE_(": size %d x %d,"), ibuf->x, ibuf->y);
+ ofs += BLI_snprintf(str + ofs, len - ofs, IFACE_(": size %d x %d,"), ibuf->x, ibuf->y);
if (ibuf->rect_float) {
if (ibuf->channels != 4) {
- ofs += sprintf(str + ofs, IFACE_("%d float channel(s)"), ibuf->channels);
+ ofs += BLI_snprintf(str + ofs, len - ofs, IFACE_("%d float channel(s)"), ibuf->channels);
}
else if (ibuf->planes == R_IMF_PLANES_RGBA)
- ofs += sprintf(str + ofs, IFACE_(" RGBA float"));
+ ofs += BLI_strncpy_rlen(str + ofs, IFACE_(" RGBA float"), len - ofs);
else
- ofs += sprintf(str + ofs, IFACE_(" RGB float"));
+ ofs += BLI_strncpy_rlen(str + ofs, IFACE_(" RGB float"), len - ofs);
}
else {
if (ibuf->planes == R_IMF_PLANES_RGBA)
- ofs += sprintf(str + ofs, IFACE_(" RGBA byte"));
+ ofs += BLI_strncpy_rlen(str + ofs, IFACE_(" RGBA byte"), len - ofs);
else
- ofs += sprintf(str + ofs, IFACE_(" RGB byte"));
+ ofs += BLI_strncpy_rlen(str + ofs, IFACE_(" RGB byte"), len - ofs);
}
if (ibuf->zbuf || ibuf->zbuf_float)
- ofs += sprintf(str + ofs, IFACE_(" + Z"));
+ ofs += BLI_strncpy_rlen(str + ofs, IFACE_(" + Z"), len - ofs);
if (ima->source == IMA_SRC_SEQUENCE) {
- char *file = BLI_last_slash(ibuf->name);
- if (file == NULL) file = ibuf->name;
- else file++;
- ofs += sprintf(str + ofs, ", %s", file);
+ const char *file = BLI_last_slash(ibuf->name);
+ if (file == NULL)
+ file = ibuf->name;
+ else
+ file++;
+ ofs += BLI_snprintf(str + ofs, len - ofs, ", %s", file);
}
}
@@ -125,10 +129,8 @@ static void image_info(Scene *scene, ImageUser *iuser, Image *ima, ImBuf *ibuf,
if (ima->source == IMA_SRC_SEQUENCE) {
/* don't use iuser->framenr directly because it may not be updated if auto-refresh is off */
const int framenr = BKE_image_user_frame_get(iuser, CFRA, 0, NULL);
- ofs += sprintf(str + ofs, IFACE_(", Frame: %d"), framenr);
+ ofs += BLI_snprintf(str + ofs, len - ofs, IFACE_(", Frame: %d"), framenr);
}
-
- (void)ofs;
}
/* gets active viewer user */
@@ -539,16 +541,17 @@ static void rna_update_cb(bContext *C, void *arg_cb, void *UNUSED(arg))
void uiTemplateImage(uiLayout *layout, bContext *C, PointerRNA *ptr, const char *propname, PointerRNA *userptr, int compact)
{
+#define MAX_INFO_LEN 128
+
PropertyRNA *prop;
PointerRNA imaptr;
RNAUpdateCb *cb;
Image *ima;
ImageUser *iuser;
- ImBuf *ibuf;
Scene *scene = CTX_data_scene(C);
uiLayout *row, *split, *col;
uiBlock *block;
- char str[128];
+ char str[MAX_INFO_LEN];
void *lock;
@@ -591,8 +594,8 @@ void uiTemplateImage(uiLayout *layout, bContext *C, PointerRNA *ptr, const char
uiBlockSetNFunc(block, rna_update_cb, MEM_dupallocN(cb), NULL);
if (ima->source == IMA_SRC_VIEWER) {
- ibuf = BKE_image_acquire_ibuf(ima, iuser, &lock);
- image_info(scene, iuser, ima, ibuf, str);
+ ImBuf *ibuf = BKE_image_acquire_ibuf(ima, iuser, &lock);
+ image_info(scene, iuser, ima, ibuf, str, MAX_INFO_LEN);
BKE_image_release_ibuf(ima, ibuf, lock);
uiItemL(layout, ima->id.name + 2, ICON_NONE);
@@ -661,8 +664,8 @@ void uiTemplateImage(uiLayout *layout, bContext *C, PointerRNA *ptr, const char
}
else if (ima->source != IMA_SRC_GENERATED) {
if (compact == 0) {
- ibuf = BKE_image_acquire_ibuf(ima, iuser, &lock);
- image_info(scene, iuser, ima, ibuf, str);
+ ImBuf *ibuf = BKE_image_acquire_ibuf(ima, iuser, &lock);
+ image_info(scene, iuser, ima, ibuf, str, MAX_INFO_LEN);
BKE_image_release_ibuf(ima, ibuf, lock);
uiItemL(layout, str, ICON_NONE);
}
@@ -750,6 +753,8 @@ void uiTemplateImage(uiLayout *layout, bContext *C, PointerRNA *ptr, const char
}
MEM_freeN(cb);
+
+#undef MAX_INFO_LEN
}
void uiTemplateImageSettings(uiLayout *layout, PointerRNA *imfptr, int color_management)
diff --git a/source/blender/editors/space_image/image_draw.c b/source/blender/editors/space_image/image_draw.c
index cae71885b87..e69ce56c9d9 100644
--- a/source/blender/editors/space_image/image_draw.c
+++ b/source/blender/editors/space_image/image_draw.c
@@ -491,6 +491,8 @@ static void draw_image_buffer(const bContext *C, SpaceImage *sima, ARegion *ar,
/* set zoom */
glPixelZoom(zoomx, zoomy);
+ glaDefine2DArea(&ar->winrct);
+
/* find window pixel coordinates of origin */
UI_view2d_to_region_no_clip(&ar->v2d, fx, fy, &x, &y);
@@ -523,11 +525,7 @@ static void draw_image_buffer(const bContext *C, SpaceImage *sima, ARegion *ar,
display_buffer = IMB_display_buffer_acquire_ctx(C, ibuf, &cache_handle);
if (display_buffer)
- glaDrawPixelsSafe(x, y, ibuf->x, ibuf->y, ibuf->x, GL_RGBA, GL_UNSIGNED_BYTE, display_buffer);
-#if 0
- else
- glaDrawPixelsSafe(x, y, ibuf->x, ibuf->y, ibuf->x, GL_RGBA, GL_FLOAT, ibuf->rect_float);
-#endif
+ glaDrawPixelsAuto(x, y, ibuf->x, ibuf->y, GL_UNSIGNED_BYTE, GL_NEAREST, display_buffer);
IMB_display_buffer_release(cache_handle);
diff --git a/source/blender/editors/space_image/image_ops.c b/source/blender/editors/space_image/image_ops.c
index b913b3528ac..54230d35312 100644
--- a/source/blender/editors/space_image/image_ops.c
+++ b/source/blender/editors/space_image/image_ops.c
@@ -162,7 +162,7 @@ static int space_image_file_exists_poll(bContext *C)
if (BLI_exists(name) == FALSE) {
CTX_wm_operator_poll_msg_set(C, "image file not found");
}
- else if (BLI_file_is_writable(name) == FALSE) {
+ else if (!BLI_file_is_writable(name)) {
CTX_wm_operator_poll_msg_set(C, "image path can't be written to");
}
else {
@@ -238,7 +238,7 @@ typedef struct ViewPanData {
int event_type;
} ViewPanData;
-static void image_view_pan_init(bContext *C, wmOperator *op, wmEvent *event)
+static void image_view_pan_init(bContext *C, wmOperator *op, const wmEvent *event)
{
SpaceImage *sima = CTX_wm_space_image(C);
ViewPanData *vpd;
@@ -293,7 +293,7 @@ static int image_view_pan_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int image_view_pan_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int image_view_pan_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
if (event->type == MOUSEPAN) {
SpaceImage *sima = CTX_wm_space_image(C);
@@ -312,7 +312,7 @@ static int image_view_pan_invoke(bContext *C, wmOperator *op, wmEvent *event)
}
}
-static int image_view_pan_modal(bContext *C, wmOperator *op, wmEvent *event)
+static int image_view_pan_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
SpaceImage *sima = CTX_wm_space_image(C);
ViewPanData *vpd = op->customdata;
@@ -383,7 +383,7 @@ typedef struct ViewZoomData {
ARegion *ar;
} ViewZoomData;
-static void image_view_zoom_init(bContext *C, wmOperator *op, wmEvent *event)
+static void image_view_zoom_init(bContext *C, wmOperator *op, const wmEvent *event)
{
SpaceImage *sima = CTX_wm_space_image(C);
ARegion *ar = CTX_wm_region(C);
@@ -455,7 +455,7 @@ enum {
VIEW_CONFIRM
};
-static int image_view_zoom_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int image_view_zoom_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
if (event->type == MOUSEZOOM || event->type == MOUSEPAN) {
SpaceImage *sima = CTX_wm_space_image(C);
@@ -525,7 +525,7 @@ static void image_zoom_apply(ViewZoomData *vpd, wmOperator *op, const int x, con
ED_region_tag_redraw(vpd->ar);
}
-static int image_view_zoom_modal(bContext *C, wmOperator *op, wmEvent *event)
+static int image_view_zoom_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
ViewZoomData *vpd = op->customdata;
short event_code = VIEW_PASS;
@@ -589,7 +589,7 @@ void IMAGE_OT_view_zoom(wmOperatorType *ot)
* that explains the negative signs in the code below
*/
-static int image_view_ndof_invoke(bContext *C, wmOperator *UNUSED(op), wmEvent *event)
+static int image_view_ndof_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *event)
{
if (event->type != NDOF_MOTION)
return OPERATOR_CANCELLED;
@@ -773,7 +773,7 @@ static int image_view_zoom_in_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int image_view_zoom_in_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int image_view_zoom_in_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
ARegion *ar = CTX_wm_region(C);
float location[2];
@@ -815,7 +815,7 @@ static int image_view_zoom_out_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int image_view_zoom_out_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int image_view_zoom_out_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
ARegion *ar = CTX_wm_region(C);
float location[2];
@@ -978,7 +978,7 @@ static int image_open_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int image_open_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int image_open_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
SpaceImage *sima = CTX_wm_space_image(C); /* XXX other space types can call */
char *path = U.textudir;
@@ -1128,7 +1128,7 @@ static int image_replace_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int image_replace_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int image_replace_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
SpaceImage *sima = CTX_wm_space_image(C);
@@ -1442,7 +1442,7 @@ static int image_save_as_check(bContext *UNUSED(C), wmOperator *op)
return WM_operator_filesel_ensure_ext_imtype(op, imf);
}
-static int image_save_as_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int image_save_as_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
SpaceImage *sima = CTX_wm_space_image(C);
Image *ima = ED_space_image(sima);
@@ -1603,7 +1603,7 @@ static int image_save_sequence_exec(bContext *C, wmOperator *op)
SpaceImage *sima = CTX_wm_space_image(C);
ImBuf *ibuf;
int tot = 0;
- char di[FILE_MAX], fi[FILE_MAX];
+ char di[FILE_MAX];
if (sima->image == NULL)
return OPERATOR_CANCELLED;
@@ -1632,10 +1632,8 @@ static int image_save_sequence_exec(bContext *C, wmOperator *op)
for (ibuf = sima->image->ibufs.first; ibuf; ibuf = ibuf->next)
if (ibuf->userflags & IB_BITMAPDIRTY)
break;
-
- BLI_strncpy(di, ibuf->name, FILE_MAX);
- BLI_splitdirstring(di, fi);
-
+
+ BLI_split_dir_part(ibuf->name, di, sizeof(di));
BKE_reportf(op->reports, RPT_INFO, "%d image(s) will be saved in %s", tot, di);
for (ibuf = sima->image->ibufs.first; ibuf; ibuf = ibuf->next) {
@@ -1775,7 +1773,7 @@ static int image_new_exec(bContext *C, wmOperator *op)
/* XXX, Ton is not a fan of OK buttons but using this function to avoid undo/redo bug while in mesh-editmode, - campbell */
/* XXX Note: the WM_operator_props_dialog_popup() doesn't work for uiIDContextProperty(), image is not being that way */
-static int image_new_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int image_new_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
return WM_operator_props_dialog_popup(C, op, 15 * UI_UNIT_X, 5 * UI_UNIT_Y);
@@ -1945,7 +1943,7 @@ static int image_pack_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int image_pack_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int image_pack_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
Image *ima = CTX_data_edit_image(C);
ImBuf *ibuf;
@@ -2029,7 +2027,7 @@ static int image_unpack_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int image_unpack_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int image_unpack_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
Image *ima = CTX_data_edit_image(C);
@@ -2145,7 +2143,7 @@ int ED_space_image_color_sample(SpaceImage *sima, ARegion *ar, int mval[2], floa
return ret;
}
-static void image_sample_apply(bContext *C, wmOperator *op, wmEvent *event)
+static void image_sample_apply(bContext *C, wmOperator *op, const wmEvent *event)
{
SpaceImage *sima = CTX_wm_space_image(C);
ARegion *ar = CTX_wm_region(C);
@@ -2271,7 +2269,7 @@ static void image_sample_exit(bContext *C, wmOperator *op)
MEM_freeN(info);
}
-static int image_sample_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int image_sample_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
SpaceImage *sima = CTX_wm_space_image(C);
ARegion *ar = CTX_wm_region(C);
@@ -2292,7 +2290,7 @@ static int image_sample_invoke(bContext *C, wmOperator *op, wmEvent *event)
return OPERATOR_RUNNING_MODAL;
}
-static int image_sample_modal(bContext *C, wmOperator *op, wmEvent *event)
+static int image_sample_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
switch (event->type) {
case LEFTMOUSE:
@@ -2378,7 +2376,7 @@ static int image_sample_line_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int image_sample_line_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int image_sample_line_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
SpaceImage *sima = CTX_wm_space_image(C);
@@ -2533,7 +2531,7 @@ static int image_record_composite_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int image_record_composite_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int image_record_composite_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
RecordCompositeData *rcd;
@@ -2550,7 +2548,7 @@ static int image_record_composite_invoke(bContext *C, wmOperator *op, wmEvent *U
return OPERATOR_RUNNING_MODAL;
}
-static int image_record_composite_modal(bContext *C, wmOperator *op, wmEvent *event)
+static int image_record_composite_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
RecordCompositeData *rcd = op->customdata;
diff --git a/source/blender/editors/space_image/space_image.c b/source/blender/editors/space_image/space_image.c
index d82a46e9578..761becdbf8e 100644
--- a/source/blender/editors/space_image/space_image.c
+++ b/source/blender/editors/space_image/space_image.c
@@ -337,7 +337,7 @@ static void image_keymap(struct wmKeyConfig *keyconf)
}
/* dropboxes */
-static int image_drop_poll(bContext *UNUSED(C), wmDrag *drag, wmEvent *UNUSED(event))
+static int image_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUSED(event))
{
if (drag->type == WM_DRAG_PATH)
if (ELEM3(drag->icon, 0, ICON_FILE_IMAGE, ICON_FILE_BLANK)) /* rule might not work? */
diff --git a/source/blender/editors/space_info/info_ops.c b/source/blender/editors/space_info/info_ops.c
index 04f6a5152e6..c68473820e3 100644
--- a/source/blender/editors/space_info/info_ops.c
+++ b/source/blender/editors/space_info/info_ops.c
@@ -104,7 +104,7 @@ static int unpack_libraries_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int unpack_libraries_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int unpack_libraries_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
return WM_operator_confirm_message(C, op, "Unpack Blender Libraries - creates directories, all new paths should work");
}
@@ -137,7 +137,7 @@ static int pack_all_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int pack_all_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int pack_all_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
Main *bmain = CTX_data_main(C);
Image *ima;
@@ -203,7 +203,7 @@ static int unpack_all_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int unpack_all_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int unpack_all_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
Main *bmain = CTX_data_main(C);
uiPopupMenu *pup;
@@ -288,7 +288,7 @@ static int unpack_item_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int unpack_item_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int unpack_item_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
uiPopupMenu *pup;
uiLayout *layout;
@@ -429,7 +429,7 @@ static int find_missing_files_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int find_missing_files_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int find_missing_files_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
/* XXX file open button text "Find Missing Files" */
WM_event_add_fileselect(C, op);
@@ -469,7 +469,7 @@ void FILE_OT_find_missing_files(wmOperatorType *ot)
#define ERROR_TIMEOUT 10.0f
#define ERROR_COLOR_TIMEOUT 6.0f
#define COLLAPSE_TIMEOUT 0.25f
-static int update_reports_display_invoke(bContext *C, wmOperator *UNUSED(op), wmEvent *event)
+static int update_reports_display_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *event)
{
wmWindowManager *wm = CTX_wm_manager(C);
ReportList *reports = CTX_wm_reports(C);
diff --git a/source/blender/editors/space_info/info_report.c b/source/blender/editors/space_info/info_report.c
index 3050563e538..b096b8f3e2b 100644
--- a/source/blender/editors/space_info/info_report.c
+++ b/source/blender/editors/space_info/info_report.c
@@ -127,7 +127,7 @@ static int select_report_pick_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int select_report_pick_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int select_report_pick_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
SpaceInfo *sinfo = CTX_wm_space_info(C);
ARegion *ar = CTX_wm_region(C);
diff --git a/source/blender/editors/space_info/info_stats.c b/source/blender/editors/space_info/info_stats.c
index 976769752f9..b2e9427c799 100644
--- a/source/blender/editors/space_info/info_stats.c
+++ b/source/blender/editors/space_info/info_stats.c
@@ -38,8 +38,9 @@
#include "DNA_meta_types.h"
#include "DNA_scene_types.h"
-#include "BLI_utildefines.h"
#include "BLI_math.h"
+#include "BLI_string.h"
+#include "BLI_utildefines.h"
#include "BLF_translation.h"
@@ -58,6 +59,7 @@
#include "ED_armature.h"
#include "ED_mesh.h"
+#define MAX_INFO_LEN 512
typedef struct SceneStats {
int totvert, totvertsel;
@@ -68,7 +70,7 @@ typedef struct SceneStats {
int totlamp, totlampsel;
int tottri, totmesh;
- char infostr[512];
+ char infostr[MAX_INFO_LEN];
} SceneStats;
static void stats_object(Object *ob, int sel, int totob, SceneStats *stats)
@@ -357,60 +359,70 @@ static void stats_update(Scene *scene)
static void stats_string(Scene *scene)
{
+#define MAX_INFO_MEM_LEN 64
SceneStats *stats = scene->stats;
Object *ob = (scene->basact) ? scene->basact->object : NULL;
uintptr_t mem_in_use, mmap_in_use;
- char memstr[64];
+ char memstr[MAX_INFO_MEM_LEN];
char *s;
+ size_t ofs = 0;
mem_in_use = MEM_get_memory_in_use();
mmap_in_use = MEM_get_mapped_memory_in_use();
/* get memory statistics */
- s = memstr + sprintf(memstr, IFACE_(" | Mem:%.2fM"), (double)((mem_in_use - mmap_in_use) >> 10) / 1024.0);
+ s = memstr;
+ ofs += BLI_snprintf(s + ofs, MAX_INFO_MEM_LEN - ofs, IFACE_(" | Mem:%.2fM"),
+ (double)((mem_in_use - mmap_in_use) >> 10) / 1024.0);
if (mmap_in_use)
- sprintf(s, IFACE_(" (%.2fM)"), (double)((mmap_in_use) >> 10) / 1024.0);
+ BLI_snprintf(s + ofs, MAX_INFO_MEM_LEN - ofs, IFACE_(" (%.2fM)"), (double)((mmap_in_use) >> 10) / 1024.0);
s = stats->infostr;
-
- s += sprintf(s, "%s | ", versionstr);
+ ofs = 0;
+
+ ofs += BLI_snprintf(s + ofs, MAX_INFO_LEN - ofs, "%s | ", versionstr);
if (scene->obedit) {
if (BKE_keyblock_from_object(scene->obedit))
- s += sprintf(s, IFACE_("(Key) "));
+ ofs += BLI_strncpy_rlen(s + ofs, IFACE_("(Key) "), MAX_INFO_LEN - ofs);
if (scene->obedit->type == OB_MESH) {
- s += sprintf(s, IFACE_("Verts:%d/%d | Edges:%d/%d | Faces:%d/%d | Tris:%d"),
- stats->totvertsel, stats->totvert, stats->totedgesel, stats->totedge, stats->totfacesel,
- stats->totface, stats->tottri);
+ ofs += BLI_snprintf(s + ofs, MAX_INFO_LEN - ofs,
+ IFACE_("Verts:%d/%d | Edges:%d/%d | Faces:%d/%d | Tris:%d"),
+ stats->totvertsel, stats->totvert, stats->totedgesel, stats->totedge,
+ stats->totfacesel, stats->totface, stats->tottri);
}
else if (scene->obedit->type == OB_ARMATURE) {
- s += sprintf(s, IFACE_("Verts:%d/%d | Bones:%d/%d"), stats->totvertsel, stats->totvert, stats->totbonesel,
- stats->totbone);
+ ofs += BLI_snprintf(s + ofs, MAX_INFO_LEN - ofs, IFACE_("Verts:%d/%d | Bones:%d/%d"), stats->totvertsel,
+ stats->totvert, stats->totbonesel, stats->totbone);
}
else {
- s += sprintf(s, IFACE_("Verts:%d/%d"), stats->totvertsel, stats->totvert);
+ ofs += BLI_snprintf(s + ofs, MAX_INFO_LEN - ofs, IFACE_("Verts:%d/%d"), stats->totvertsel, stats->totvert);
}
- strcat(s, memstr);
+ ofs += BLI_strncpy_rlen(s + ofs, memstr, MAX_INFO_LEN - ofs);
}
else if (ob && (ob->mode & OB_MODE_POSE)) {
- s += sprintf(s, IFACE_("Bones:%d/%d %s"),
- stats->totbonesel, stats->totbone, memstr);
+ ofs += BLI_snprintf(s + ofs, MAX_INFO_LEN - ofs, IFACE_("Bones:%d/%d %s"),
+ stats->totbonesel, stats->totbone, memstr);
}
else if (stats_is_object_dynamic_topology_sculpt(ob)) {
- s += sprintf(s, IFACE_("Verts:%d | Tris:%d"), stats->totvert, stats->tottri);
+ ofs += BLI_snprintf(s + ofs, MAX_INFO_LEN - ofs, IFACE_("Verts:%d | Tris:%d"), stats->totvert, stats->tottri);
}
else {
- s += sprintf(s, IFACE_("Verts:%d | Faces:%d | Tris:%d | Objects:%d/%d | Lamps:%d/%d%s"),
- stats->totvert, stats->totface, stats->tottri, stats->totobjsel, stats->totobj, stats->totlampsel,
- stats->totlamp, memstr);
+ ofs += BLI_snprintf(s + ofs, MAX_INFO_LEN - ofs,
+ IFACE_("Verts:%d | Faces:%d | Tris:%d | Objects:%d/%d | Lamps:%d/%d%s"), stats->totvert,
+ stats->totface, stats->tottri, stats->totobjsel, stats->totobj, stats->totlampsel,
+ stats->totlamp, memstr);
}
if (ob)
- sprintf(s, " | %s", ob->id.name + 2);
+ BLI_snprintf(s + ofs, MAX_INFO_LEN - ofs, " | %s", ob->id.name + 2);
+#undef MAX_INFO_MEM_LEN
}
+#undef MAX_INFO_LEN
+
void ED_info_stats_clear(Scene *scene)
{
if (scene->stats) {
diff --git a/source/blender/editors/space_info/textview.c b/source/blender/editors/space_info/textview.c
index 66f4904c340..e53cbdd04af 100644
--- a/source/blender/editors/space_info/textview.c
+++ b/source/blender/editors/space_info/textview.c
@@ -31,14 +31,19 @@
#include <limits.h>
#include <assert.h>
+#include "MEM_guardedalloc.h"
+
#include "BLF_api.h"
#include "BLI_math.h"
#include "BLI_utildefines.h"
+#include "BLI_string_utf8.h"
#include "BIF_gl.h"
#include "BIF_glutil.h"
+#include "BKE_text.h"
+
#include "ED_datafiles.h"
#include "textview.h"
@@ -68,12 +73,12 @@ BLI_INLINE void console_step_sel(ConsoleDrawContext *cdc, const int 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,
- const unsigned char bg_sel[4])
+static void console_draw_sel(const char *str, const int sel[2], const int xy[2], const int str_len_draw,
+ int cwidth, int lheight, const unsigned char bg_sel[4])
{
if (sel[0] <= str_len_draw && sel[1] >= 0) {
- const int sta = max_ii(sel[0], 0);
- const int end = min_ii(sel[1], str_len_draw);
+ const int sta = txt_utf8_offset_to_column(str, max_ii(sel[0], 0));
+ const int end = txt_utf8_offset_to_column(str, min_ii(sel[1], str_len_draw));
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
@@ -85,38 +90,72 @@ static void console_draw_sel(const int sel[2], const int xy[2], const int str_le
}
}
+/* warning: allocated memory for 'offsets' must be freed by caller */
+static int console_wrap_offsets(const char *str, int len, int width, int *lines, int **offsets)
+{
+ int i, end; /* column */
+ int j; /* mem */
+
+ *lines = 1;
+
+ *offsets = MEM_callocN(sizeof(**offsets) * (len * BLI_UTF8_WIDTH_MAX / MAX2(1, width - (BLI_UTF8_WIDTH_MAX - 1)) + 1),
+ "console_wrap_offsets");
+ (*offsets)[0] = 0;
+
+ for (i = 0, end = width, j = 0; j < len && str[j]; j += BLI_str_utf8_size_safe(str + j)) {
+ int columns = BLI_str_utf8_char_width_safe(str + j);
+
+ if (i + columns > end) {
+ (*offsets)[*lines] = j;
+ (*lines)++;
+
+ end = i + width;
+ }
+ i += columns;
+ }
+ return j; /* return actual length */
+}
+
/* 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, const int str_len,
+static int console_draw_string(ConsoleDrawContext *cdc, const char *str, int str_len,
const unsigned char fg[3], const unsigned char bg[3], const unsigned char bg_sel[4])
{
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;
+ int tot_lines; /* total number of lines for wrapping */
+ int *offsets; /* offsets of line beginnings for wrapping */
+ int y_next;
const int mono = blf_mono_font;
+ str_len = console_wrap_offsets(str, str_len, cdc->console_width, &tot_lines, &offsets);
+ y_next = cdc->xy[1] + cdc->lheight * tot_lines;
+
/* just advance the height */
if (cdc->draw == 0) {
- if (cdc->pos_pick && (cdc->mval[1] != INT_MAX)) {
- if (cdc->xy[1] <= cdc->mval[1]) {
- if ((y_next >= cdc->mval[1])) {
- int ofs = (int)floor(((float)cdc->mval[0] / (float)cdc->cwidth));
-
- /* wrap */
- if (str_len > cdc->console_width)
- ofs += cdc->console_width * ((int)((((float)(y_next - cdc->mval[1]) /
- (float)(y_next - cdc->xy[1])) * tot_lines)));
-
- CLAMP(ofs, 0, str_len);
- *cdc->pos_pick += str_len - ofs;
+ if (cdc->pos_pick && cdc->mval[1] != INT_MAX && cdc->xy[1] <= cdc->mval[1]) {
+ if (y_next >= cdc->mval[1]) {
+ int ofs = 0;
+
+ /* wrap */
+ if (tot_lines > 1) {
+ int iofs = (int)((float)(y_next - cdc->mval[1]) / cdc->lheight);
+ ofs += offsets[MIN2(iofs, tot_lines - 1)];
}
- else
- *cdc->pos_pick += str_len + 1;
+
+ /* last part */
+ ofs += txt_utf8_column_to_offset(str + ofs,
+ (int)floor((float)cdc->mval[0] / cdc->cwidth));
+
+ CLAMP(ofs, 0, str_len);
+ *cdc->pos_pick += str_len - ofs;
}
+ else
+ *cdc->pos_pick += str_len + 1;
}
cdc->xy[1] = y_next;
+ MEM_freeN(offsets);
return 1;
}
else if (y_next - cdc->lheight < cdc->ymin) {
@@ -128,12 +167,15 @@ static int console_draw_string(ConsoleDrawContext *cdc, const char *str, const i
console_step_sel(cdc, -(str_len + 1));
}
+ MEM_freeN(offsets);
return 1;
}
if (tot_lines > 1) { /* wrap? */
- const int initial_offset = ((tot_lines - 1) * cdc->console_width);
- const char *line_stride = str + initial_offset; /* advance to the last line and draw it first */
+ const int initial_offset = offsets[tot_lines - 1];
+ size_t len = str_len - initial_offset;
+ const char *s = str + initial_offset;
+ int i;
int sel_orig[2];
copy_v2_v2_int(sel_orig, cdc->sel);
@@ -151,36 +193,38 @@ static int console_draw_string(ConsoleDrawContext *cdc, const char *str, const i
/* last part needs no clipping */
BLF_position(mono, cdc->xy[0], cdc->xy[1], 0);
- BLF_draw(mono, line_stride, str_len - initial_offset);
+ BLF_draw_mono(mono, s, len, cdc->cwidth);
if (cdc->sel[0] != cdc->sel[1]) {
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, bg_sel);
- console_step_sel(cdc, cdc->console_width);
+ console_draw_sel(s, cdc->sel, cdc->xy, len, cdc->cwidth, cdc->lheight, bg_sel);
glColor3ubv(fg);
}
cdc->xy[1] += cdc->lheight;
- line_stride -= cdc->console_width;
-
- for (; line_stride >= str; line_stride -= cdc->console_width) {
+ for (i = tot_lines - 1; i > 0; i--) {
+ len = offsets[i] - offsets[i - 1];
+ s = str + offsets[i - 1];
+
BLF_position(mono, cdc->xy[0], cdc->xy[1], 0);
- BLF_draw(mono, line_stride, cdc->console_width);
+ BLF_draw_mono(mono, s, len, cdc->cwidth);
if (cdc->sel[0] != cdc->sel[1]) {
+ console_step_sel(cdc, len);
// glColor4ub(0, 255, 0, 96); // debug
- console_draw_sel(cdc->sel, cdc->xy, cdc->console_width, cdc->cwidth, cdc->lheight, bg_sel);
- console_step_sel(cdc, cdc->console_width);
+ console_draw_sel(s, cdc->sel, cdc->xy, len, cdc->cwidth, cdc->lheight, bg_sel);
glColor3ubv(fg);
}
cdc->xy[1] += cdc->lheight;
/* check if were out of view bounds */
- if (cdc->xy[1] > cdc->ymax)
+ if (cdc->xy[1] > cdc->ymax) {
+ MEM_freeN(offsets);
return 0;
+ }
}
copy_v2_v2_int(cdc->sel, sel_orig);
@@ -196,7 +240,7 @@ static int console_draw_string(ConsoleDrawContext *cdc, const char *str, const i
glColor3ubv(fg);
BLF_position(mono, cdc->xy[0], cdc->xy[1], 0);
- BLF_draw(mono, str, str_len);
+ BLF_draw_mono(mono, str, str_len, cdc->cwidth);
if (cdc->sel[0] != cdc->sel[1]) {
int isel[2];
@@ -205,16 +249,19 @@ static int console_draw_string(ConsoleDrawContext *cdc, const char *str, const i
isel[1] = str_len - cdc->sel[0];
// glColor4ub(255, 255, 0, 96); // debug
- console_draw_sel(isel, cdc->xy, str_len, cdc->cwidth, cdc->lheight, bg_sel);
+ console_draw_sel(str, isel, cdc->xy, str_len, cdc->cwidth, cdc->lheight, bg_sel);
console_step_sel(cdc, -(str_len + 1));
}
cdc->xy[1] += cdc->lheight;
- if (cdc->xy[1] > cdc->ymax)
+ if (cdc->xy[1] > cdc->ymax) {
+ MEM_freeN(offsets);
return 0;
+ }
}
+ MEM_freeN(offsets);
return 1;
}
diff --git a/source/blender/editors/space_logic/logic_ops.c b/source/blender/editors/space_logic/logic_ops.c
index 2313885dbaf..5f2ecbf1b2b 100644
--- a/source/blender/editors/space_logic/logic_ops.c
+++ b/source/blender/editors/space_logic/logic_ops.c
@@ -122,7 +122,7 @@ static Object *edit_object_property_get(bContext *C, wmOperator *op)
/* if ob_name is valid try to find the object with this name
* otherwise gets the active object */
- if (BLI_strnlen(ob_name, MAX_NAME) > 0)
+ if (*ob_name)
ob = BLI_findstring(&(CTX_data_main(C)->object), ob_name, offsetof(ID, name) + 2);
else
ob = ED_object_active_context(C);
@@ -250,7 +250,7 @@ static int sensor_remove_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int sensor_remove_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int sensor_remove_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
if (edit_sensor_invoke_properties(C, op))
return sensor_remove_exec(C, op);
@@ -295,12 +295,13 @@ static int sensor_add_exec(bContext *C, wmOperator *op)
prop = RNA_struct_find_property(&sens_ptr, "type");
RNA_string_get(op->ptr, "name", name);
- if (BLI_strnlen(name, MAX_NAME) < 1) {
+ if (*name) {
+ BLI_strncpy(sens->name, name, sizeof(sens->name));
+ }
+ else {
RNA_property_enum_name(C, &sens_ptr, prop, RNA_property_enum_get(&sens_ptr, prop), &sens_name);
BLI_strncpy(sens->name, sens_name, sizeof(sens->name));
}
- else
- BLI_strncpy(sens->name, name, sizeof(sens->name));
make_unique_prop_names(C, sens->name);
ob->scaflag |= OB_SHOWSENS;
@@ -355,7 +356,7 @@ static int controller_remove_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int controller_remove_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int controller_remove_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
if (edit_controller_invoke_properties(C, op))
return controller_remove_exec(C, op);
@@ -401,12 +402,13 @@ static int controller_add_exec(bContext *C, wmOperator *op)
prop = RNA_struct_find_property(&cont_ptr, "type");
RNA_string_get(op->ptr, "name", name);
- if (BLI_strnlen(name, MAX_NAME) < 1) {
+ if (*name) {
+ BLI_strncpy(cont->name, name, sizeof(cont->name));
+ }
+ else {
RNA_property_enum_name(C, &cont_ptr, prop, RNA_property_enum_get(&cont_ptr, prop), &cont_name);
BLI_strncpy(cont->name, cont_name, sizeof(cont->name));
}
- else
- BLI_strncpy(cont->name, name, sizeof(cont->name));
make_unique_prop_names(C, cont->name);
/* set the controller state mask from the current object state.
@@ -473,7 +475,7 @@ static int actuator_remove_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int actuator_remove_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int actuator_remove_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
if (edit_actuator_invoke_properties(C, op))
return actuator_remove_exec(C, op);
@@ -518,12 +520,13 @@ static int actuator_add_exec(bContext *C, wmOperator *op)
prop = RNA_struct_find_property(&act_ptr, "type");
RNA_string_get(op->ptr, "name", name);
- if (BLI_strnlen(name, MAX_NAME) < 1) {
+ if (*name) {
+ BLI_strncpy(act->name, name, sizeof(act->name));
+ }
+ else {
RNA_property_enum_name(C, &act_ptr, prop, RNA_property_enum_get(&act_ptr, prop), &act_name);
BLI_strncpy(act->name, act_name, sizeof(act->name));
}
- else
- BLI_strncpy(act->name, name, sizeof(act->name));
make_unique_prop_names(C, act->name);
ob->scaflag |= OB_SHOWACT;
@@ -583,7 +586,7 @@ static int sensor_move_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int sensor_move_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int sensor_move_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
if (edit_sensor_invoke_properties(C, op)) {
return sensor_move_exec(C, op);
@@ -628,7 +631,7 @@ static int controller_move_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int controller_move_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int controller_move_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
if (edit_controller_invoke_properties(C, op)) {
return controller_move_exec(C, op);
@@ -673,7 +676,7 @@ static int actuator_move_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int actuator_move_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int actuator_move_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
if (edit_actuator_invoke_properties(C, op)) {
return actuator_move_exec(C, op);
@@ -711,7 +714,7 @@ static int texface_convert_exec(bContext *C, wmOperator *UNUSED(op))
return OPERATOR_FINISHED;
}
-static int texface_convert_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int texface_convert_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
return texface_convert_exec(C, op);
}
diff --git a/source/blender/editors/space_nla/nla_buttons.c b/source/blender/editors/space_nla/nla_buttons.c
index 31c773e613e..b2cae8e5496 100644
--- a/source/blender/editors/space_nla/nla_buttons.c
+++ b/source/blender/editors/space_nla/nla_buttons.c
@@ -131,7 +131,6 @@ static int nla_panel_context(const bContext *C, PointerRNA *adt_ptr, PointerRNA
case ANIMTYPE_SCENE: /* Top-Level Widgets doubling up as datablocks */
case ANIMTYPE_OBJECT:
- case ANIMTYPE_FILLACTD: /* Action Expander */
case ANIMTYPE_DSMAT: /* Datablock AnimData Expanders */
case ANIMTYPE_DSLAM:
case ANIMTYPE_DSCAM:
@@ -142,22 +141,34 @@ static int nla_panel_context(const bContext *C, PointerRNA *adt_ptr, PointerRNA
case ANIMTYPE_DSPART:
case ANIMTYPE_DSMBALL:
case ANIMTYPE_DSARM:
+ case ANIMTYPE_DSMESH:
+ case ANIMTYPE_DSTEX:
+ case ANIMTYPE_DSLAT:
#ifdef WITH_FREESTYLE
case ANIMTYPE_DSLINESTYLE:
#endif
case ANIMTYPE_DSSPK:
{
/* for these channels, we only do AnimData */
- if (ale->id && ale->adt) {
- if (adt_ptr) {
- /* AnimData pointer */
- RNA_pointer_create(ale->id, &RNA_AnimData, ale->adt, adt_ptr);
-
- /* set found status to -1, since setting to 1 would break the loop
- * and potentially skip an active NLA-Track in some cases...
- */
- found = -1;
+ if (ale->adt && adt_ptr) {
+ ID *id;
+
+ if ((ale->data == NULL) || (ale->type == ANIMTYPE_OBJECT)) {
+ /* ale->data is not an ID block! */
+ id = ale->id;
}
+ else {
+ /* ale->data is always the proper ID block we need, but ale->id may not be (i.e. for textures) */
+ id = (ID *)ale->data;
+ }
+
+ /* AnimData pointer */
+ RNA_pointer_create(id, &RNA_AnimData, ale->adt, adt_ptr);
+
+ /* set found status to -1, since setting to 1 would break the loop
+ * and potentially skip an active NLA-Track in some cases...
+ */
+ found = -1;
}
}
break;
@@ -250,6 +261,28 @@ static void nla_panel_animdata(const bContext *C, Panel *pa)
block = uiLayoutGetBlock(layout);
uiBlockSetHandleFunc(block, do_nla_region_buttons, NULL);
+ /* AnimData Source Properties ----------------------------------- */
+
+ /* icon + id-block name of block where AnimData came from to prevent
+ * accidentally changing the properties of the wrong action
+ */
+ if (adt_ptr.id.data) {
+ ID *id = adt_ptr.id.data;
+ PointerRNA id_ptr;
+
+ RNA_id_pointer_create(id, &id_ptr);
+
+ /* ID-block name > AnimData */
+ row = uiLayoutRow(layout, TRUE);
+ uiLayoutSetAlignment(row, UI_LAYOUT_ALIGN_LEFT);
+
+ uiItemL(row, id->name + 2, RNA_struct_ui_icon(id_ptr.type)); /* id-block (src) */
+ uiItemL(row, "", VICO_SMALL_TRI_RIGHT_VEC); /* expander */
+ uiItemL(row, IFACE_("Animation Data"), ICON_ANIM_DATA); /* animdata */
+
+ uiItemS(layout);
+ }
+
/* Active Action Properties ------------------------------------- */
/* action */
row = uiLayoutRow(layout, TRUE);
diff --git a/source/blender/editors/space_nla/nla_channels.c b/source/blender/editors/space_nla/nla_channels.c
index 97581cefc2b..6d091e3c7c4 100644
--- a/source/blender/editors/space_nla/nla_channels.c
+++ b/source/blender/editors/space_nla/nla_channels.c
@@ -48,6 +48,7 @@
#include "BKE_context.h"
#include "BKE_global.h"
#include "BKE_screen.h"
+#include "BKE_report.h"
#include "ED_anim_api.h"
#include "ED_keyframes_edit.h"
@@ -140,7 +141,7 @@ static int mouse_nla_channels(bAnimContext *ac, float x, int channel_index, shor
}
else {
Base *b;
-
+
/* deselect all */
/* TODO: should this deselect all other types of channels too? */
for (b = sce->base.first; b; b = b->next) {
@@ -268,6 +269,7 @@ static int mouse_nla_channels(bAnimContext *ac, float x, int channel_index, shor
{
AnimData *adt = BKE_animdata_from_id(ale->id);
+ /* button area... */
if (x >= (v2d->cur.xmax - NLACHANNEL_BUTTON_WIDTH)) {
if (nlaedit_is_tweakmode_on(ac) == 0) {
/* 'push-down' action - only usable when not in TweakMode */
@@ -283,6 +285,30 @@ static int mouse_nla_channels(bAnimContext *ac, float x, int channel_index, shor
/* changes to NLA-Action occurred */
notifierFlags |= ND_NLA_ACTCHANGE;
}
+ /* OR rest of name... */
+ else {
+ /* NOTE: rest of NLA-Action name doubles for operating on the AnimData block
+ * - this is useful when there's no clear divider, and makes more sense in
+ * the case of users trying to use this to change actions
+ */
+
+ /* select/deselect */
+ if (selectmode == SELECT_INVERT) {
+ /* inverse selection status of this AnimData block only */
+ adt->flag ^= ADT_UI_SELECTED;
+ }
+ else {
+ /* select AnimData block by itself */
+ ANIM_deselect_anim_channels(ac, ac->data, ac->datatype, 0, ACHANNEL_SETFLAG_CLEAR);
+ adt->flag |= ADT_UI_SELECTED;
+ }
+
+ /* set active? */
+ if (adt->flag & ADT_UI_SELECTED)
+ adt->flag |= ADT_UI_ACTIVE;
+
+ notifierFlags |= (ND_ANIMCHAN | NA_SELECTED);
+ }
}
break;
@@ -301,7 +327,7 @@ static int mouse_nla_channels(bAnimContext *ac, float x, int channel_index, shor
/* ------------------- */
/* handle clicking */
-static int nlachannels_mouseclick_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int nlachannels_mouseclick_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
bAnimContext ac;
SpaceNla *snla;
@@ -358,7 +384,7 @@ void NLA_OT_channels_click(wmOperatorType *ot)
ot->poll = ED_operator_nla_active;
/* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ ot->flag = OPTYPE_UNDO;
/* props */
prop = RNA_def_boolean(ot->srna, "extend", 0, "Extend Select", ""); // SHIFTKEY
@@ -371,24 +397,18 @@ void NLA_OT_channels_click(wmOperatorType *ot)
/* ******************** Add Tracks Operator ***************************** */
/* Add NLA Tracks to the same AnimData block as a selected track, or above the selected tracks */
-static int nlaedit_add_tracks_exec(bContext *C, wmOperator *op)
+/* helper - add NLA Tracks alongside existing ones */
+static bool nlaedit_add_tracks_existing(bAnimContext *ac, bool above_sel)
{
- bAnimContext ac;
-
ListBase anim_data = {NULL, NULL};
bAnimListElem *ale;
int filter;
-
AnimData *lastAdt = NULL;
- short above_sel = RNA_boolean_get(op->ptr, "above_selected");
+ bool added = false;
- /* get editor data */
- if (ANIM_animdata_get_context(C, &ac) == 0)
- return OPERATOR_CANCELLED;
-
- /* get a list of the AnimData blocks being shown in the NLA */
- filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_SEL);
- ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
+ /* get a list of the (selected) NLA Tracks being shown in the NLA */
+ filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_SEL | ANIMFILTER_NODUPLIS);
+ ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
/* add tracks... */
for (ale = anim_data.first; ale; ale = ale->next) {
@@ -402,11 +422,13 @@ static int nlaedit_add_tracks_exec(bContext *C, wmOperator *op)
if (above_sel) {
/* just add a new one above this one */
add_nlatrack(adt, nlt);
+ added = true;
}
else if ((lastAdt == NULL) || (adt != lastAdt)) {
/* add one track to the top of the owning AnimData's stack, then don't add anymore to this stack */
add_nlatrack(adt, NULL);
lastAdt = adt;
+ added = true;
}
}
}
@@ -414,17 +436,80 @@ static int nlaedit_add_tracks_exec(bContext *C, wmOperator *op)
/* free temp data */
BLI_freelistN(&anim_data);
- /* set notifier that things have changed */
- WM_event_add_notifier(C, NC_ANIMATION | ND_NLA | NA_EDITED, NULL);
+ return added;
+}
+
+/* helper - add NLA Tracks to empty (and selected) AnimData blocks */
+static bool nlaedit_add_tracks_empty(bAnimContext *ac)
+{
+ ListBase anim_data = {NULL, NULL};
+ bAnimListElem *ale;
+ int filter;
+ bool added = false;
- /* done */
- return OPERATOR_FINISHED;
+ /* get a list of the selected AnimData blocks in the NLA */
+ filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_ANIMDATA | ANIMFILTER_SEL | ANIMFILTER_NODUPLIS);
+ ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
+
+ /* check if selected AnimData blocks are empty, and add tracks if so... */
+ for (ale = anim_data.first; ale; ale = ale->next) {
+ AnimData *adt = ale->adt;
+
+ /* sanity check */
+ BLI_assert(adt->flag & ADT_UI_SELECTED);
+
+ /* ensure it is empty */
+ if (adt->nla_tracks.first == NULL) {
+ /* add new track to this AnimData block then */
+ add_nlatrack(adt, NULL);
+ added = true;
+ }
+ }
+
+ /* cleanup */
+ BLI_freelistN(&anim_data);
+
+ return added;
+}
+
+/* ----- */
+
+static int nlaedit_add_tracks_exec(bContext *C, wmOperator *op)
+{
+ bAnimContext ac;
+ bool above_sel = RNA_boolean_get(op->ptr, "above_selected");
+ bool op_done = false;
+
+ /* get editor data */
+ if (ANIM_animdata_get_context(C, &ac) == 0)
+ return OPERATOR_CANCELLED;
+
+ /* perform adding in two passes - existing first so that we don't double up for empty */
+ op_done |= nlaedit_add_tracks_existing(&ac, above_sel);
+ op_done |= nlaedit_add_tracks_empty(&ac);
+
+ /* done? */
+ if (op_done) {
+ /* set notifier that things have changed */
+ WM_event_add_notifier(C, NC_ANIMATION | ND_NLA | NA_EDITED, NULL);
+
+ /* done */
+ return OPERATOR_FINISHED;
+ }
+ else {
+ /* failed to add any tracks */
+ BKE_report(op->reports, RPT_WARNING,
+ "Select an existing NLA Track or an empty action line first");
+
+ /* not done */
+ return OPERATOR_CANCELLED;
+ }
}
void NLA_OT_tracks_add(wmOperatorType *ot)
{
/* identifiers */
- ot->name = "Add Track(s)";
+ ot->name = "Add Tracks";
ot->idname = "NLA_OT_tracks_add";
ot->description = "Add NLA-Tracks above/after the selected tracks";
@@ -485,11 +570,11 @@ static int nlaedit_delete_tracks_exec(bContext *C, wmOperator *UNUSED(op))
return OPERATOR_FINISHED;
}
-void NLA_OT_delete_tracks(wmOperatorType *ot)
+void NLA_OT_tracks_delete(wmOperatorType *ot)
{
/* identifiers */
ot->name = "Delete Tracks";
- ot->idname = "NLA_OT_delete_tracks";
+ ot->idname = "NLA_OT_tracks_delete";
ot->description = "Delete selected NLA-Tracks and the strips they contain";
/* api callbacks */
@@ -501,3 +586,59 @@ void NLA_OT_delete_tracks(wmOperatorType *ot)
}
/* *********************************************** */
+/* AnimData Related Operators */
+
+/* ******************** Include Objects Operator ***************************** */
+/* Include selected objects in NLA Editor, by giving them AnimData blocks
+ * NOTE: This doesn't help for non-object AnimData, where we do not have any effective
+ * selection mechanism in place. Unfortunately, this means that non-object AnimData
+ * once again becomes a second-class citizen here. However, at least for the most
+ * common use case, we now have a nice shortcut again.
+ */
+
+static int nlaedit_objects_add_exec(bContext *C, wmOperator *UNUSED(op))
+{
+ bAnimContext ac;
+ SpaceNla *snla;
+
+ /* get editor data */
+ if (ANIM_animdata_get_context(C, &ac) == 0)
+ return OPERATOR_CANCELLED;
+
+ /* ensure that filters are set so that the effect will be immediately visible */
+ snla = (SpaceNla *)ac.sl;
+ if (snla && snla->ads) {
+ snla->ads->filterflag &= ~ADS_FILTER_NLA_NOACT;
+ }
+
+ /* operate on selected objects... */
+ CTX_DATA_BEGIN (C, Object *, ob, selected_objects)
+ {
+ /* ensure that object has AnimData... that's all */
+ BKE_id_add_animdata(&ob->id);
+ }
+ CTX_DATA_END;
+
+ /* set notifier that things have changed */
+ WM_event_add_notifier(C, NC_ANIMATION | ND_NLA | NA_EDITED, NULL);
+
+ /* done */
+ return OPERATOR_FINISHED;
+}
+
+void NLA_OT_selected_objects_add(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Include Selected Objects";
+ ot->idname = "NLA_OT_selected_objects_add";
+ ot->description = "Make selected objects appear in NLA Editor by adding Animation Data";
+
+ /* api callbacks */
+ ot->exec = nlaedit_objects_add_exec;
+ ot->poll = nlaop_poll_tweakmode_off;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+}
+
+/* *********************************************** */
diff --git a/source/blender/editors/space_nla/nla_draw.c b/source/blender/editors/space_nla/nla_draw.c
index acfb4a51b14..56f2ec9ebe1 100644
--- a/source/blender/editors/space_nla/nla_draw.c
+++ b/source/blender/editors/space_nla/nla_draw.c
@@ -695,11 +695,8 @@ static void draw_nla_channel_list_gl(bAnimContext *ac, ListBase *anim_data, View
special = ICON_ACTION;
- if (act)
- BLI_snprintf(name, sizeof(name), "%s", act->id.name + 2);
- else
- BLI_strncpy(name, "<No Action>", sizeof(name));
-
+ BLI_strncpy(name, act ? act->id.name + 2 : "<No Action>", sizeof(name));
+
/* draw manually still */
do_draw = TRUE;
}
@@ -759,7 +756,6 @@ static void draw_nla_channel_list_gl(bAnimContext *ac, ListBase *anim_data, View
glEnable(GL_BLEND);
/* draw backing strip behind channel name */
- // FIXME: hardcoded colors!!!
if (group == 5) {
float color[4];
diff --git a/source/blender/editors/space_nla/nla_edit.c b/source/blender/editors/space_nla/nla_edit.c
index 484eb47fa8e..17d403789cf 100644
--- a/source/blender/editors/space_nla/nla_edit.c
+++ b/source/blender/editors/space_nla/nla_edit.c
@@ -200,7 +200,7 @@ static int nlaedit_disable_tweakmode_exec(bContext *C, wmOperator *op)
for (ale = anim_data.first; ale; ale = ale->next) {
AnimData *adt = ale->data;
- /* try entering tweakmode if valid */
+ /* to be sure, just exit tweakmode... */
BKE_nla_tweakmode_exit(adt);
}
@@ -891,7 +891,7 @@ static int nlaedit_duplicate_exec(bContext *C, wmOperator *UNUSED(op))
return OPERATOR_CANCELLED;
}
-static int nlaedit_duplicate_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int nlaedit_duplicate_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
nlaedit_duplicate_exec(C, op);
@@ -1627,7 +1627,7 @@ void NLA_OT_action_sync_length(wmOperatorType *ot)
/* api callbacks */
ot->exec = nlaedit_sync_actlen_exec;
- ot->poll = ED_operator_nla_active; // XXX: is this satisfactory... probably requires a check for active strip...
+ ot->poll = nlaop_poll_tweakmode_off;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
@@ -1801,7 +1801,7 @@ void NLA_OT_clear_scale(wmOperatorType *ot)
/* defines for snap keyframes tool */
static EnumPropertyItem prop_nlaedit_snap_types[] = {
- {NLAEDIT_SNAP_CFRA, "CFRA", 0, "Current frame", ""},
+ {NLAEDIT_SNAP_CFRA, "CFRA", 0, "Current Frame", ""},
{NLAEDIT_SNAP_NEAREST_FRAME, "NEAREST_FRAME", 0, "Nearest Frame", ""}, // XXX as single entry?
{NLAEDIT_SNAP_NEAREST_SECOND, "NEAREST_SECOND", 0, "Nearest Second", ""}, // XXX as single entry?
{NLAEDIT_SNAP_NEAREST_MARKER, "NEAREST_MARKER", 0, "Nearest Marker", ""},
@@ -1947,7 +1947,7 @@ void NLA_OT_snap(wmOperatorType *ot)
/* ******************** Add F-Modifier Operator *********************** */
/* present a special customised popup menu for this, with some filtering */
-static int nla_fmodifier_add_invoke(bContext *C, wmOperator *UNUSED(op), wmEvent *UNUSED(event))
+static int nla_fmodifier_add_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *UNUSED(event))
{
uiPopupMenu *pup;
uiLayout *layout;
@@ -2021,8 +2021,9 @@ static int nla_fmodifier_add_exec(bContext *C, wmOperator *op)
/* add F-Modifier of specified type to selected, and make it the active one */
fcm = add_fmodifier(&strip->modifiers, type);
- if (fcm)
+ if (fcm) {
set_active_fmodifier(&strip->modifiers, fcm);
+ }
else {
BKE_reportf(op->reports, RPT_ERROR,
"Modifier could not be added to (%s : %s) (see console for details)",
@@ -2101,8 +2102,10 @@ static int nla_fmodifier_copy_exec(bContext *C, wmOperator *op)
BKE_report(op->reports, RPT_ERROR, "No F-Modifiers available to be copied");
return OPERATOR_CANCELLED;
}
- else
+ else {
+ /* no updates needed - copy is non-destructive operation */
return OPERATOR_FINISHED;
+ }
}
void NLA_OT_fmodifier_copy(wmOperatorType *ot)
@@ -2156,8 +2159,6 @@ static int nla_fmodifier_paste_exec(bContext *C, wmOperator *op)
/* successful or not? */
if (ok) {
- /* set notifier that things have changed */
- /* set notifier that things have changed */
WM_event_add_notifier(C, NC_ANIMATION | ND_NLA | NA_EDITED, NULL);
return OPERATOR_FINISHED;
}
diff --git a/source/blender/editors/space_nla/nla_intern.h b/source/blender/editors/space_nla/nla_intern.h
index 398d2d5f1f4..450b85738ad 100644
--- a/source/blender/editors/space_nla/nla_intern.h
+++ b/source/blender/editors/space_nla/nla_intern.h
@@ -125,7 +125,9 @@ void NLA_OT_fmodifier_paste(wmOperatorType *ot);
void NLA_OT_channels_click(wmOperatorType *ot);
void NLA_OT_tracks_add(wmOperatorType *ot);
-void NLA_OT_delete_tracks(wmOperatorType *ot);
+void NLA_OT_tracks_delete(wmOperatorType *ot);
+
+void NLA_OT_selected_objects_add(wmOperatorType *ot);
/* **************************************** */
/* nla_ops.c */
diff --git a/source/blender/editors/space_nla/nla_ops.c b/source/blender/editors/space_nla/nla_ops.c
index 54ade829c0d..fb0f11ffd87 100644
--- a/source/blender/editors/space_nla/nla_ops.c
+++ b/source/blender/editors/space_nla/nla_ops.c
@@ -120,7 +120,9 @@ void nla_operatortypes(void)
WM_operatortype_append(NLA_OT_channels_click);
WM_operatortype_append(NLA_OT_tracks_add);
- WM_operatortype_append(NLA_OT_delete_tracks);
+ WM_operatortype_append(NLA_OT_tracks_delete);
+
+ WM_operatortype_append(NLA_OT_selected_objects_add);
/* select */
WM_operatortype_append(NLA_OT_click_select);
@@ -188,8 +190,8 @@ static void nla_keymap_channels(wmKeyMap *keymap)
RNA_boolean_set(kmi->ptr, "above_selected", TRUE);
/* delete tracks */
- WM_keymap_add_item(keymap, "NLA_OT_delete_tracks", XKEY, KM_PRESS, 0, 0);
- WM_keymap_add_item(keymap, "NLA_OT_delete_tracks", DELKEY, KM_PRESS, 0, 0);
+ WM_keymap_add_item(keymap, "NLA_OT_tracks_delete", XKEY, KM_PRESS, 0, 0);
+ WM_keymap_add_item(keymap, "NLA_OT_tracks_delete", DELKEY, KM_PRESS, 0, 0);
}
static void nla_keymap_main(wmKeyConfig *keyconf, wmKeyMap *keymap)
diff --git a/source/blender/editors/space_nla/nla_select.c b/source/blender/editors/space_nla/nla_select.c
index 97553b7aa56..3e414233add 100644
--- a/source/blender/editors/space_nla/nla_select.c
+++ b/source/blender/editors/space_nla/nla_select.c
@@ -451,7 +451,7 @@ static int nlaedit_select_leftright_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int nlaedit_select_leftright_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int nlaedit_select_leftright_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
bAnimContext ac;
short leftright = RNA_enum_get(op->ptr, "mode");
@@ -613,7 +613,7 @@ static void mouse_nla_strips(bContext *C, bAnimContext *ac, const int mval[2], s
/* ------------------- */
/* handle clicking */
-static int nlaedit_clickselect_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int nlaedit_clickselect_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
bAnimContext ac;
/* Scene *scene; */ /* UNUSED */
@@ -660,7 +660,7 @@ void NLA_OT_click_select(wmOperatorType *ot)
ot->poll = ED_operator_nla_active;
/* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ ot->flag = OPTYPE_UNDO;
/* properties */
prop = RNA_def_boolean(ot->srna, "extend", 0, "Extend Select", ""); // SHIFTKEY
diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c
index 8a2e03f2660..4a14d6ba6fd 100644
--- a/source/blender/editors/space_node/drawnode.c
+++ b/source/blender/editors/space_node/drawnode.c
@@ -687,14 +687,14 @@ 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 = 1.0f;
+ const float dpi_fac = UI_DPI_FAC;
bNodeTree *ngroup = (bNodeTree *)gnode->id;
bNodeSocketType *stype = ntreeGetSocketType(gsock ? gsock->type : sock->type);
uiBut *bt;
float offset;
int draw_value;
const float node_group_frame = NODE_GROUP_FRAME * dpi_fac;
- const float socket_size = NODE_SOCKSIZE * dpi_fac;
+ const float socket_size = NODE_SOCKSIZE;
const float arrowbutw = 0.8f * UI_UNIT_X;
const short co_text_w = 72 * dpi_fac;
const float co_margin = 6.0f * dpi_fac;
@@ -799,12 +799,12 @@ 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 = 1.0f;
+ 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 index;
-
+
/* backdrop header */
glEnable(GL_BLEND);
uiSetRoundBox(UI_CNR_TOP_LEFT | UI_CNR_TOP_RIGHT);
@@ -1296,11 +1296,11 @@ static void node_shader_buts_mapping(uiLayout *layout, bContext *UNUSED(C), Poin
uiItemR(row, ptr, "scale", 0, "", ICON_NONE);
row = uiLayoutRow(layout, TRUE);
- uiItemR(row, ptr, "use_min", 0, "Min", ICON_NONE);
+ uiItemR(row, ptr, "use_min", 0, IFACE_("Min"), ICON_NONE);
uiItemR(row, ptr, "min", 0, "", ICON_NONE);
row = uiLayoutRow(layout, TRUE);
- uiItemR(row, ptr, "use_max", 0, "Max", ICON_NONE);
+ uiItemR(row, ptr, "use_max", 0, IFACE_("Max"), ICON_NONE);
uiItemR(row, ptr, "max", 0, "", ICON_NONE);
}
@@ -3301,7 +3301,7 @@ void draw_nodespace_back_pix(const bContext *C, ARegion *ar, SpaceNode *snode)
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glPixelZoom(snode->zoom, snode->zoom);
- glaDrawPixelsSafe(x, y, ibuf->x, ibuf->y, ibuf->x, GL_RGBA, GL_UNSIGNED_BYTE, display_buffer);
+ glaDrawPixelsAuto(x, y, ibuf->x, ibuf->y, GL_UNSIGNED_BYTE, GL_LINEAR, display_buffer);
glPixelZoom(1.0f, 1.0f);
glDisable(GL_BLEND);
@@ -3309,7 +3309,7 @@ void draw_nodespace_back_pix(const bContext *C, ARegion *ar, SpaceNode *snode)
else {
glPixelZoom(snode->zoom, snode->zoom);
- glaDrawPixelsSafe(x, y, ibuf->x, ibuf->y, ibuf->x, GL_RGBA, GL_UNSIGNED_BYTE, display_buffer);
+ glaDrawPixelsAuto(x, y, ibuf->x, ibuf->y, GL_UNSIGNED_BYTE, GL_LINEAR, display_buffer);
glPixelZoom(1.0f, 1.0f);
}
@@ -3320,6 +3320,7 @@ void draw_nodespace_back_pix(const bContext *C, ARegion *ar, SpaceNode *snode)
/** @note draw selected info on backdrop */
if (snode->edittree) {
bNode *node = snode->edittree->nodes.first;
+ rctf *viewer_border = &snode->edittree->viewer_border;
while (node) {
if (node->flag & NODE_SELECT) {
if (node->typeinfo->uibackdropfunc) {
@@ -3328,6 +3329,23 @@ void draw_nodespace_back_pix(const bContext *C, ARegion *ar, SpaceNode *snode)
}
node = node->next;
}
+
+ if ((snode->edittree->flag & NTREE_VIEWER_BORDER) &&
+ viewer_border->xmin < viewer_border->xmax &&
+ viewer_border->ymin < viewer_border->ymax)
+ {
+ glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
+ setlinestyle(3);
+ cpack(0x4040FF);
+
+ glRectf(x + snode->zoom * viewer_border->xmin * ibuf->x,
+ y + snode->zoom * viewer_border->ymin * ibuf->y,
+ x + snode->zoom * viewer_border->xmax * ibuf->x,
+ y + snode->zoom * viewer_border->ymax * ibuf->y);
+
+ setlinestyle(0);
+ glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
+ }
}
glMatrixMode(GL_PROJECTION);
@@ -3340,57 +3358,6 @@ void draw_nodespace_back_pix(const bContext *C, ARegion *ar, SpaceNode *snode)
}
}
-#if 0
-/* note: needs to be userpref or opengl profile option */
-static void draw_nodespace_back_tex(ScrArea *sa, SpaceNode *snode)
-{
-
- draw_nodespace_grid(snode);
-
- if (snode->flag & SNODE_BACKDRAW) {
- Image *ima = BKE_image_verify_viewer(IMA_TYPE_COMPOSITE, "Viewer Node");
- ImBuf *ibuf = BKE_image_acquire_ibuf(ima, NULL, NULL);
- if (ibuf) {
- int x, y;
- float zoom = 1.0;
-
- glMatrixMode(GL_PROJECTION);
- glPushMatrix();
- glMatrixMode(GL_MODELVIEW);
- glPushMatrix();
-
- glaDefine2DArea(&sa->winrct);
-
- if (ibuf->x > sa->winx || ibuf->y > sa->winy) {
- float zoomx, zoomy;
- zoomx = (float)sa->winx / ibuf->x;
- zoomy = (float)sa->winy / ibuf->y;
- zoom = min_ff(zoomx, zoomy);
- }
-
- x = (sa->winx - zoom * ibuf->x) / 2 + snode->xof;
- y = (sa->winy - zoom * ibuf->y) / 2 + snode->yof;
-
- glPixelZoom(zoom, zoom);
-
- glColor4f(1.0, 1.0, 1.0, 1.0);
- if (ibuf->rect)
- glaDrawPixelsTex(x, y, ibuf->x, ibuf->y, GL_UNSIGNED_BYTE, ibuf->rect);
- else if (ibuf->channels == 4)
- glaDrawPixelsTex(x, y, ibuf->x, ibuf->y, GL_FLOAT, ibuf->rect_float);
-
- glPixelZoom(1.0, 1.0);
-
- glMatrixMode(GL_PROJECTION);
- glPopMatrix();
- glMatrixMode(GL_MODELVIEW);
- glPopMatrix();
-
- BKE_image_release_ibuf(ima, ibuf, NULL);
- }
- }
-}
-#endif
/* if v2d not NULL, it clips and returns 0 if not visible */
int node_link_bezier_points(View2D *v2d, SpaceNode *snode, bNodeLink *link, float coord_array[][2], int resol)
diff --git a/source/blender/editors/space_node/node_add.c b/source/blender/editors/space_node/node_add.c
index 4943bb45113..235d91ecd92 100644
--- a/source/blender/editors/space_node/node_add.c
+++ b/source/blender/editors/space_node/node_add.c
@@ -400,7 +400,7 @@ static int node_add_file_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int node_add_file_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int node_add_file_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
ARegion *ar = CTX_wm_region(C);
SpaceNode *snode = CTX_wm_space_node(C);
diff --git a/source/blender/editors/space_node/node_draw.c b/source/blender/editors/space_node/node_draw.c
index 34f7799d47c..d6a3a6a6a3f 100644
--- a/source/blender/editors/space_node/node_draw.c
+++ b/source/blender/editors/space_node/node_draw.c
@@ -629,7 +629,7 @@ static void node_draw_preview(bNodePreview *preview, rctf *prv)
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); /* premul graphics */
glColor4f(1.0, 1.0, 1.0, 1.0);
- glaDrawPixelsTex(prv->xmin, prv->ymin, preview->xsize, preview->ysize, GL_UNSIGNED_BYTE, preview->rect);
+ glaDrawPixelsTex(prv->xmin, prv->ymin, preview->xsize, preview->ysize, GL_UNSIGNED_BYTE, GL_LINEAR, preview->rect);
glDisable(GL_BLEND);
glPixelZoom(1.0f, 1.0f);
diff --git a/source/blender/editors/space_node/node_edit.c b/source/blender/editors/space_node/node_edit.c
index fb4e4f62e52..941bd783c39 100644
--- a/source/blender/editors/space_node/node_edit.c
+++ b/source/blender/editors/space_node/node_edit.c
@@ -73,6 +73,8 @@
#include "GPU_material.h"
+#include "IMB_imbuf_types.h"
+
#include "node_intern.h" /* own include */
#define USE_ESC_COMPO
@@ -835,7 +837,7 @@ typedef struct NodeSizeWidget {
int directions;
} NodeSizeWidget;
-static void node_resize_init(bContext *C, wmOperator *op, wmEvent *UNUSED(event), bNode *node, int dir)
+static void node_resize_init(bContext *C, wmOperator *op, const wmEvent *UNUSED(event), bNode *node, int dir)
{
SpaceNode *snode = CTX_wm_space_node(C);
@@ -868,7 +870,7 @@ static void node_resize_exit(bContext *C, wmOperator *op, int UNUSED(cancel))
op->customdata = NULL;
}
-static int node_resize_modal(bContext *C, wmOperator *op, wmEvent *event)
+static int node_resize_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
SpaceNode *snode = CTX_wm_space_node(C);
ARegion *ar = CTX_wm_region(C);
@@ -971,7 +973,7 @@ static int node_resize_modal(bContext *C, wmOperator *op, wmEvent *event)
return OPERATOR_RUNNING_MODAL;
}
-static int node_resize_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int node_resize_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
SpaceNode *snode = CTX_wm_space_node(C);
ARegion *ar = CTX_wm_region(C);
@@ -1055,7 +1057,7 @@ void node_set_hidden_sockets(SpaceNode *snode, bNode *node, int set)
}
/* return 0, nothing done */
-static int UNUSED_FUNCTION(node_mouse_groupheader) (SpaceNode * snode)
+static int UNUSED_FUNCTION(node_mouse_groupheader) (SpaceNode *snode)
{
bNode *gnode;
float mx = 0, my = 0;
@@ -2138,7 +2140,7 @@ static int node_clipboard_paste_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int node_clipboard_paste_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int node_clipboard_paste_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
ARegion *ar = CTX_wm_region(C);
SpaceNode *snode = CTX_wm_space_node(C);
@@ -2281,3 +2283,105 @@ void NODE_OT_shader_script_update(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
+/* ********************** Viewer border ******************/
+
+static void viewer_border_corner_to_backdrop(SpaceNode *snode, ARegion *ar, int x, int y,
+ int backdrop_width, int backdrop_height,
+ float *fx, float *fy)
+{
+ float bufx, bufy;
+
+ bufx = backdrop_width * snode->zoom;
+ bufy = backdrop_height * snode->zoom;
+
+ *fx = (bufx > 0.0f ? ((float) x - 0.5f * ar->winx - snode->xof) / bufx + 0.5f : 0.0f);
+ *fy = (bufy > 0.0f ? ((float) y - 0.5f * ar->winy - snode->yof) / bufy + 0.5f : 0.0f);
+}
+
+static int viewer_border_exec(bContext *C, wmOperator *op)
+{
+ Image *ima;
+ void *lock;
+ ImBuf *ibuf;
+
+ ED_preview_kill_jobs(C);
+
+ ima = BKE_image_verify_viewer(IMA_TYPE_COMPOSITE, "Viewer Node");
+ ibuf = BKE_image_acquire_ibuf(ima, NULL, &lock);
+
+ if (ibuf) {
+ ARegion *ar = CTX_wm_region(C);
+ SpaceNode *snode = CTX_wm_space_node(C);
+ bNodeTree *btree = snode->edittree;
+ rcti rect;
+ rctf rectf;
+
+ /* get border from operator */
+ WM_operator_properties_border_to_rcti(op, &rect);
+
+ /* convert border to unified space within backdrop image */
+ viewer_border_corner_to_backdrop(snode, ar, rect.xmin, rect.ymin, ibuf->x, ibuf->y,
+ &rectf.xmin, &rectf.ymin);
+
+ viewer_border_corner_to_backdrop(snode, ar, rect.xmax, rect.ymax, ibuf->x, ibuf->y,
+ &rectf.xmax, &rectf.ymax);
+
+ /* clamp coordinates */
+ rectf.xmin = max_ff(rectf.xmin, 0.0f);
+ rectf.ymin = max_ff(rectf.ymin, 0.0f);
+ rectf.xmax = min_ff(rectf.xmax, 1.0f);
+ rectf.ymax = min_ff(rectf.ymax, 1.0f);
+
+ if (rectf.xmin < rectf.xmax && rectf.ymin < rectf.ymax) {
+ btree->viewer_border = rectf;
+
+ if (rectf.xmin == 0.0f && rectf.ymin == 0.0f &&
+ rectf.xmax == 1.0f && rectf.ymax == 1.0f)
+ {
+ btree->flag &= ~NTREE_VIEWER_BORDER;
+ }
+ else {
+ if (ibuf->rect)
+ memset(ibuf->rect, 0, 4 * ibuf->x * ibuf->y);
+
+ if (ibuf->rect_float)
+ memset(ibuf->rect_float, 0, 4 * ibuf->x * ibuf->y * sizeof(float));
+
+ ibuf->userflags |= IB_DISPLAY_BUFFER_INVALID;
+
+ btree->flag |= NTREE_VIEWER_BORDER;
+ }
+
+ snode_notify(C, snode);
+ WM_event_add_notifier(C, NC_NODE | ND_DISPLAY, NULL);
+ }
+ else {
+ btree->flag &= ~NTREE_VIEWER_BORDER;
+ }
+ }
+
+ BKE_image_release_ibuf(ima, ibuf, lock);
+
+ return OPERATOR_FINISHED;
+}
+
+void NODE_OT_viewer_border(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Viewer Border";
+ ot->description = "Set the boundaries for viewer operations";
+ ot->idname = "NODE_OT_viewer_border";
+
+ /* api callbacks */
+ ot->invoke = WM_border_select_invoke;
+ ot->exec = viewer_border_exec;
+ ot->modal = WM_border_select_modal;
+ ot->cancel = WM_border_select_cancel;
+ ot->poll = composite_node_active;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+
+ /* properties */
+ WM_operator_properties_gesture_border(ot, TRUE);
+}
diff --git a/source/blender/editors/space_node/node_group.c b/source/blender/editors/space_node/node_group.c
index 7b7b98f132c..6696284b169 100644
--- a/source/blender/editors/space_node/node_group.c
+++ b/source/blender/editors/space_node/node_group.c
@@ -133,7 +133,7 @@ static int node_group_edit_exec(bContext *C, wmOperator *UNUSED(op))
return OPERATOR_FINISHED;
}
-static int node_group_edit_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int node_group_edit_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
SpaceNode *snode = CTX_wm_space_node(C);
bNode *gnode;
@@ -789,7 +789,7 @@ static int node_group_separate_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int node_group_separate_invoke(bContext *C, wmOperator *UNUSED(op), wmEvent *UNUSED(event))
+static int node_group_separate_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *UNUSED(event))
{
uiPopupMenu *pup = uiPupMenuBegin(C, CTX_IFACE_(BLF_I18NCONTEXT_OPERATOR_DEFAULT, "Separate"), ICON_NONE);
uiLayout *layout = uiPupMenuLayout(pup);
@@ -1146,7 +1146,7 @@ static int node_group_make_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int node_group_make_invoke(bContext *C, wmOperator *UNUSED(op), wmEvent *UNUSED(event))
+static int node_group_make_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *UNUSED(event))
{
SpaceNode *snode = CTX_wm_space_node(C);
bNode *act = nodeGetActive(snode->edittree);
diff --git a/source/blender/editors/space_node/node_intern.h b/source/blender/editors/space_node/node_intern.h
index e8dd1cf1528..cbf7101a101 100644
--- a/source/blender/editors/space_node/node_intern.h
+++ b/source/blender/editors/space_node/node_intern.h
@@ -217,6 +217,8 @@ void NODE_OT_clipboard_paste(struct wmOperatorType *ot);
void NODE_OT_shader_script_update(struct wmOperatorType *ot);
+void NODE_OT_viewer_border(struct wmOperatorType *ot);
+
extern const char *node_context_dir[];
// XXXXXX
diff --git a/source/blender/editors/space_node/node_ops.c b/source/blender/editors/space_node/node_ops.c
index 8adccd9e6c4..d16c6627d3f 100644
--- a/source/blender/editors/space_node/node_ops.c
+++ b/source/blender/editors/space_node/node_ops.c
@@ -120,6 +120,8 @@ void node_operatortypes(void)
WM_operatortype_append(NODE_OT_clipboard_paste);
WM_operatortype_append(NODE_OT_shader_script_update);
+
+ WM_operatortype_append(NODE_OT_viewer_border);
}
void ED_operatormacros_node(void)
@@ -298,5 +300,7 @@ void node_keymap(struct wmKeyConfig *keyconf)
WM_keymap_add_item(keymap, "NODE_OT_clipboard_copy", CKEY, KM_PRESS, KM_CTRL, 0);
WM_keymap_add_item(keymap, "NODE_OT_clipboard_paste", VKEY, KM_PRESS, KM_CTRL, 0);
+ WM_keymap_add_item(keymap, "NODE_OT_viewer_border", BKEY, KM_PRESS, KM_CTRL, 0);
+
transform_keymap_for_space(keyconf, keymap, SPACE_NODE);
}
diff --git a/source/blender/editors/space_node/node_relationships.c b/source/blender/editors/space_node/node_relationships.c
index 8d7eef22822..097e4f418e0 100644
--- a/source/blender/editors/space_node/node_relationships.c
+++ b/source/blender/editors/space_node/node_relationships.c
@@ -448,7 +448,7 @@ static int outside_group_rect(SpaceNode *snode)
/* loop that adds a nodelink, called by function below */
/* in_out = starting socket */
-static int node_link_modal(bContext *C, wmOperator *op, wmEvent *event)
+static int node_link_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
SpaceNode *snode = CTX_wm_space_node(C);
ARegion *ar = CTX_wm_region(C);
@@ -702,7 +702,7 @@ static bNodeLinkDrag *node_link_init(SpaceNode *snode, int detach)
return nldrag;
}
-static int node_link_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int node_link_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
SpaceNode *snode = CTX_wm_space_node(C);
ARegion *ar = CTX_wm_region(C);
@@ -840,7 +840,9 @@ static int cut_links_exec(bContext *C, wmOperator *op)
if (i > 1) {
int found = FALSE;
bNodeLink *link, *next;
-
+
+ ED_preview_kill_jobs(C);
+
for (link = snode->edittree->links.first; link; link = next) {
next = link->next;
@@ -1181,7 +1183,7 @@ static int node_attach_exec(bContext *C, wmOperator *UNUSED(op))
return OPERATOR_FINISHED;
}
-static int node_attach_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int node_attach_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
ARegion *ar = CTX_wm_region(C);
SpaceNode *snode = CTX_wm_space_node(C);
diff --git a/source/blender/editors/space_node/node_select.c b/source/blender/editors/space_node/node_select.c
index 7d2b80d50ba..c917b8ee756 100644
--- a/source/blender/editors/space_node/node_select.c
+++ b/source/blender/editors/space_node/node_select.c
@@ -429,7 +429,7 @@ static int node_select_exec(bContext *C, wmOperator *op)
}
}
-static int node_select_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int node_select_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
RNA_int_set(op->ptr, "mouse_x", event->mval[0]);
RNA_int_set(op->ptr, "mouse_y", event->mval[1]);
@@ -494,7 +494,7 @@ static int node_borderselect_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int node_border_select_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int node_border_select_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
int tweak = RNA_boolean_get(op->ptr, "tweak");
diff --git a/source/blender/editors/space_node/node_view.c b/source/blender/editors/space_node/node_view.c
index a69e73c1489..a8e84e0a0e5 100644
--- a/source/blender/editors/space_node/node_view.c
+++ b/source/blender/editors/space_node/node_view.c
@@ -196,7 +196,7 @@ typedef struct NodeViewMove {
int xmin, ymin, xmax, ymax;
} NodeViewMove;
-static int snode_bg_viewmove_modal(bContext *C, wmOperator *op, wmEvent *event)
+static int snode_bg_viewmove_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
SpaceNode *snode = CTX_wm_space_node(C);
ARegion *ar = CTX_wm_region(C);
@@ -231,7 +231,7 @@ static int snode_bg_viewmove_modal(bContext *C, wmOperator *op, wmEvent *event)
return OPERATOR_RUNNING_MODAL;
}
-static int snode_bg_viewmove_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int snode_bg_viewmove_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
SpaceNode *snode = CTX_wm_space_node(C);
ARegion *ar = CTX_wm_region(C);
@@ -413,7 +413,7 @@ int ED_space_node_color_sample(SpaceNode *snode, ARegion *ar, int mval[2], float
return ret;
}
-static void sample_apply(bContext *C, wmOperator *op, wmEvent *event)
+static void sample_apply(bContext *C, wmOperator *op, const wmEvent *event)
{
SpaceNode *snode = CTX_wm_space_node(C);
ARegion *ar = CTX_wm_region(C);
@@ -513,7 +513,7 @@ static void sample_exit(bContext *C, wmOperator *op)
MEM_freeN(info);
}
-static int sample_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int sample_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
SpaceNode *snode = CTX_wm_space_node(C);
ARegion *ar = CTX_wm_region(C);
@@ -534,7 +534,7 @@ static int sample_invoke(bContext *C, wmOperator *op, wmEvent *event)
return OPERATOR_RUNNING_MODAL;
}
-static int sample_modal(bContext *C, wmOperator *op, wmEvent *event)
+static int sample_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
switch (event->type) {
case LEFTMOUSE:
diff --git a/source/blender/editors/space_node/space_node.c b/source/blender/editors/space_node/space_node.c
index 264bea5f871..75f28baf558 100644
--- a/source/blender/editors/space_node/space_node.c
+++ b/source/blender/editors/space_node/space_node.c
@@ -423,7 +423,7 @@ static void node_main_area_draw(const bContext *C, ARegion *ar)
/* ************* dropboxes ************* */
-static int node_drop_poll(bContext *UNUSED(C), wmDrag *drag, wmEvent *UNUSED(event))
+static int node_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUSED(event))
{
if (drag->type == WM_DRAG_ID) {
ID *id = (ID *)drag->poin;
diff --git a/source/blender/editors/space_outliner/outliner_draw.c b/source/blender/editors/space_outliner/outliner_draw.c
index cacbc6d6268..26a0d0a2fa8 100644
--- a/source/blender/editors/space_outliner/outliner_draw.c
+++ b/source/blender/editors/space_outliner/outliner_draw.c
@@ -41,6 +41,8 @@
#include "BLI_utildefines.h"
#include "BLI_ghash.h"
+#include "BLF_translation.h"
+
#include "BKE_context.h"
#include "BKE_deform.h"
#include "BKE_depsgraph.h"
@@ -50,6 +52,7 @@
#include "BKE_modifier.h"
#include "BKE_report.h"
#include "BKE_scene.h"
+#include "BKE_object.h"
#include "ED_armature.h"
#include "ED_object.h"
@@ -129,11 +132,66 @@ static void outliner_rna_width(SpaceOops *soops, ListBase *lb, int *w, int start
/* ****************************************************** */
+static void restrictbutton_recursive_ebone(bContext *C, EditBone *ebone_parent, int flag, bool set_flag)
+{
+ Object *obedit = CTX_data_edit_object(C);
+ bArmature *arm = obedit->data;
+ EditBone *ebone;
+
+ for (ebone = arm->edbo->first; ebone; ebone = ebone->next) {
+ if (ED_armature_ebone_is_child_recursive(ebone_parent, ebone)) {
+ if (set_flag) {
+ ebone->flag &= ~(BONE_TIPSEL | BONE_SELECTED | BONE_ROOTSEL);
+ ebone->flag |= flag;
+ }
+ else {
+ ebone->flag &= ~flag;
+ }
+ }
+ }
+}
+
+static void restrictbutton_recursive_bone(bContext *C, bArmature *arm, Bone *bone_parent, int flag, bool set_flag)
+{
+ Bone *bone;
+ for (bone = bone_parent->childbase.first; bone; bone = bone->next) {
+ if (set_flag) {
+ bone->flag &= ~(BONE_TIPSEL | BONE_SELECTED | BONE_ROOTSEL);
+ bone->flag |= flag;
+ }
+ else {
+ bone->flag &= ~flag;
+ }
+ restrictbutton_recursive_bone(C, arm, bone, flag, set_flag);
+ }
+
+}
+
+static void restrictbutton_recursive_child(bContext *C, Scene *scene, Object *ob_parent, char flag,
+ bool state, bool deselect)
+{
+ Main *bmain = CTX_data_main(C);
+ Object *ob;
+ for (ob = bmain->object.first; ob; ob = ob->id.next) {
+ if (BKE_object_is_child_recursive(ob_parent, ob)) {
+ if (state) {
+ ob->restrictflag |= flag;
+ if (deselect) {
+ ED_base_object_select(BKE_scene_base_find(scene, ob), BA_DESELECT);
+ }
+ }
+ else {
+ ob->restrictflag &= ~flag;
+ }
+ }
+ }
+}
+
static void restrictbutton_view_cb(bContext *C, void *poin, void *poin2)
{
Scene *scene = (Scene *)poin;
Object *ob = (Object *)poin2;
-
+
if (!common_restrict_check(C, ob)) return;
/* deselect objects that are invisible */
@@ -142,6 +200,12 @@ static void restrictbutton_view_cb(bContext *C, void *poin, void *poin2)
* so have to do loop to find it. */
ED_base_object_select(BKE_scene_base_find(scene, ob), BA_DESELECT);
}
+
+ if (CTX_wm_window(C)->eventstate->ctrl) {
+ restrictbutton_recursive_child(C, scene, ob, OB_RESTRICT_VIEW,
+ (ob->restrictflag & OB_RESTRICT_VIEW) != 0, true);
+ }
+
WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene);
}
@@ -159,12 +223,25 @@ static void restrictbutton_sel_cb(bContext *C, void *poin, void *poin2)
* so have to do loop to find it. */
ED_base_object_select(BKE_scene_base_find(scene, ob), BA_DESELECT);
}
+
+ if (CTX_wm_window(C)->eventstate->ctrl) {
+ restrictbutton_recursive_child(C, scene, ob, OB_RESTRICT_SELECT,
+ (ob->restrictflag & OB_RESTRICT_SELECT) != 0, true);
+ }
+
WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene);
}
-static void restrictbutton_rend_cb(bContext *C, void *poin, void *UNUSED(poin2))
+static void restrictbutton_rend_cb(bContext *C, void *poin, void *poin2)
{
+ Object *ob = (Object *)poin2;
+
+ if (CTX_wm_window(C)->eventstate->ctrl) {
+ restrictbutton_recursive_child(C, (Scene *)poin, ob, OB_RESTRICT_RENDER,
+ (ob->restrictflag & OB_RESTRICT_RENDER) != 0, false);
+ }
+
WM_event_add_notifier(C, NC_SCENE | ND_OB_RENDER, poin);
}
@@ -182,19 +259,59 @@ static void restrictbutton_modifier_cb(bContext *C, void *UNUSED(poin), void *po
WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob);
}
-static void restrictbutton_bone_cb(bContext *C, void *UNUSED(poin), void *poin2)
+static void restrictbutton_bone_visibility_cb(bContext *C, void *poin, void *poin2)
{
+ bArmature *arm = (bArmature *)poin;
Bone *bone = (Bone *)poin2;
if (bone && (bone->flag & BONE_HIDDEN_P))
bone->flag &= ~(BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL);
+
+ if (CTX_wm_window(C)->eventstate->ctrl) {
+ restrictbutton_recursive_bone(C, arm, bone, BONE_HIDDEN_P, (bone->flag & BONE_HIDDEN_P) != 0);
+ }
+
+ WM_event_add_notifier(C, NC_OBJECT | ND_POSE, NULL);
+}
+
+static void restrictbutton_bone_select_cb(bContext *C, void *poin, void *poin2)
+{
+ bArmature *arm = (bArmature *)poin;
+ Bone *bone = (Bone *)poin2;
+ if (bone && (bone->flag & BONE_UNSELECTABLE))
+ bone->flag &= ~(BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL);
+
+ if (CTX_wm_window(C)->eventstate->ctrl) {
+ restrictbutton_recursive_bone(C, arm, bone, BONE_UNSELECTABLE, (bone->flag & BONE_UNSELECTABLE) != 0);
+ }
+
WM_event_add_notifier(C, NC_OBJECT | ND_POSE, NULL);
}
-static void restrictbutton_ebone_cb(bContext *C, void *UNUSED(poin), void *poin2)
+static void restrictbutton_ebone_select_cb(bContext *C, void *UNUSED(poin), void *poin2)
{
EditBone *ebone = (EditBone *)poin2;
- if (ebone && (ebone->flag & BONE_HIDDEN_A))
+
+ if (ebone->flag & BONE_UNSELECTABLE) {
ebone->flag &= ~(BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL);
+ }
+
+ if (CTX_wm_window(C)->eventstate->ctrl) {
+ restrictbutton_recursive_ebone(C, ebone, BONE_UNSELECTABLE, (ebone->flag & BONE_UNSELECTABLE) != 0);
+ }
+
+ WM_event_add_notifier(C, NC_OBJECT | ND_POSE, NULL);
+}
+
+static void restrictbutton_ebone_visibility_cb(bContext *C, void *UNUSED(poin), void *poin2)
+{
+ EditBone *ebone = (EditBone *)poin2;
+ if (ebone->flag & BONE_HIDDEN_A) {
+ ebone->flag &= ~(BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL);
+ }
+
+ if (CTX_wm_window(C)->eventstate->ctrl) {
+ restrictbutton_recursive_ebone(C, ebone, BONE_HIDDEN_A, (ebone->flag & BONE_HIDDEN_A) != 0);
+ }
WM_event_add_notifier(C, NC_OBJECT | ND_POSE, NULL);
}
@@ -238,7 +355,7 @@ static int group_select_flag(Group *gr)
}
void restrictbutton_gr_restrict_flag(void *poin, void *poin2, int flag)
-{
+{
Scene *scene = (Scene *)poin;
GroupObject *gob;
Group *gr = (Group *)poin2;
@@ -297,7 +414,7 @@ static void namebutton_cb(bContext *C, void *tsep, char *oldname)
TreeElement *te = outliner_find_tse(soops, tselem);
if (tselem->type == 0) {
- test_idbutton(tselem->id->name + 2); // library.c, unique name and alpha sort
+ test_idbutton(tselem->id->name); // library.c, unique name and alpha sort
switch (GS(tselem->id->name)) {
case ID_MA:
@@ -332,7 +449,7 @@ static void namebutton_cb(bContext *C, void *tsep, char *oldname)
defgroup_unique_name(te->directdata, (Object *)tselem->id); // id = object
break;
case TSE_NLA_ACTION:
- test_idbutton(tselem->id->name + 2);
+ test_idbutton(tselem->id->name);
break;
case TSE_EBONE:
{
@@ -389,7 +506,8 @@ static void namebutton_cb(bContext *C, void *tsep, char *oldname)
Object *ob = (Object *)tselem->id; // id = object
bActionGroup *grp = te->directdata;
- BLI_uniquename(&ob->pose->agroups, grp, "Group", '.', offsetof(bActionGroup, name), sizeof(grp->name));
+ BLI_uniquename(&ob->pose->agroups, grp, "Group", '.', offsetof(bActionGroup, name),
+ sizeof(grp->name));
WM_event_add_notifier(C, NC_OBJECT | ND_POSE, ob);
}
break;
@@ -422,17 +540,20 @@ static void outliner_draw_restrictbuts(uiBlock *block, Scene *scene, ARegion *ar
uiBlockSetEmboss(block, UI_EMBOSSN);
bt = uiDefIconButR(block, ICONTOG, 0, ICON_RESTRICT_VIEW_OFF,
(int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_VIEWX), (int)te->ys, UI_UNIT_X, UI_UNIT_Y,
- &ptr, "hide", -1, 0, 0, -1, -1, NULL);
+ &ptr, "hide", -1, 0, 0, -1, -1,
+ TIP_("Restrict viewport visibility (Ctrl - Recursive)"));
uiButSetFunc(bt, restrictbutton_view_cb, scene, ob);
bt = uiDefIconButR(block, ICONTOG, 0, ICON_RESTRICT_SELECT_OFF,
(int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_SELECTX), (int)te->ys, UI_UNIT_X, UI_UNIT_Y,
- &ptr, "hide_select", -1, 0, 0, -1, -1, NULL);
+ &ptr, "hide_select", -1, 0, 0, -1, -1,
+ TIP_("Restrict viewport selection (Ctrl - Recursive)"));
uiButSetFunc(bt, restrictbutton_sel_cb, scene, ob);
bt = uiDefIconButR(block, ICONTOG, 0, ICON_RESTRICT_RENDER_OFF,
(int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_RENDERX), (int)te->ys, UI_UNIT_X, UI_UNIT_Y,
- &ptr, "hide_render", -1, 0, 0, -1, -1, NULL);
+ &ptr, "hide_render", -1, 0, 0, -1, -1,
+ TIP_("Restrict rendering (Ctrl - Recursive)"));
uiButSetFunc(bt, restrictbutton_rend_cb, scene, ob);
uiBlockSetEmboss(block, UI_EMBOSS);
@@ -447,19 +568,19 @@ static void outliner_draw_restrictbuts(uiBlock *block, Scene *scene, ARegion *ar
restrict_bool = group_restrict_flag(gr, OB_RESTRICT_VIEW);
bt = uiDefIconBut(block, ICONTOG, 0, restrict_bool ? ICON_RESTRICT_VIEW_ON : ICON_RESTRICT_VIEW_OFF,
(int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_VIEWX), (int)te->ys, UI_UNIT_X, UI_UNIT_Y,
- NULL, 0, 0, 0, 0, "Restrict/Allow visibility in the 3D View");
+ NULL, 0, 0, 0, 0, TIP_("Restrict/Allow visibility in the 3D View"));
uiButSetFunc(bt, restrictbutton_gr_restrict_view, scene, gr);
restrict_bool = group_restrict_flag(gr, OB_RESTRICT_SELECT);
bt = uiDefIconBut(block, ICONTOG, 0, restrict_bool ? ICON_RESTRICT_SELECT_ON : ICON_RESTRICT_SELECT_OFF,
(int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_SELECTX), (int)te->ys, UI_UNIT_X, UI_UNIT_Y,
- NULL, 0, 0, 0, 0, "Restrict/Allow selection in the 3D View");
+ NULL, 0, 0, 0, 0, TIP_("Restrict/Allow selection in the 3D View"));
uiButSetFunc(bt, restrictbutton_gr_restrict_select, scene, gr);
restrict_bool = group_restrict_flag(gr, OB_RESTRICT_RENDER);
bt = uiDefIconBut(block, ICONTOG, 0, restrict_bool ? ICON_RESTRICT_RENDER_ON : ICON_RESTRICT_RENDER_OFF,
(int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_RENDERX), (int)te->ys, UI_UNIT_X, UI_UNIT_Y,
- NULL, 0, 0, 0, 0, "Restrict/Allow renderability");
+ NULL, 0, 0, 0, 0, TIP_("Restrict/Allow renderability"));
uiButSetFunc(bt, restrictbutton_gr_restrict_render, scene, gr);
uiBlockSetEmboss(block, UI_EMBOSS);
@@ -469,8 +590,8 @@ static void outliner_draw_restrictbuts(uiBlock *block, Scene *scene, ARegion *ar
uiBlockSetEmboss(block, UI_EMBOSSN);
bt = uiDefIconButBitI(block, ICONTOGN, SCE_LAY_DISABLE, 0, ICON_CHECKBOX_HLT - 1,
- (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_VIEWX), (int)te->ys, UI_UNIT_X, UI_UNIT_Y,
- te->directdata, 0, 0, 0, 0, "Render this RenderLayer");
+ (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_VIEWX), (int)te->ys, UI_UNIT_X,
+ UI_UNIT_Y, te->directdata, 0, 0, 0, 0, TIP_("Render this RenderLayer"));
uiButSetFunc(bt, restrictbutton_r_lay_cb, tselem->id, NULL);
uiBlockSetEmboss(block, UI_EMBOSS);
@@ -483,8 +604,8 @@ static void outliner_draw_restrictbuts(uiBlock *block, Scene *scene, ARegion *ar
bt = uiDefIconButBitI(block, ICONTOG, passflag, 0, ICON_CHECKBOX_HLT - 1,
- (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_VIEWX), (int)te->ys, UI_UNIT_X, UI_UNIT_Y,
- layflag, 0, 0, 0, 0, "Render this Pass");
+ (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_VIEWX), (int)te->ys, UI_UNIT_X,
+ UI_UNIT_Y, layflag, 0, 0, 0, 0, TIP_("Render this Pass"));
uiButSetFunc(bt, restrictbutton_r_lay_cb, tselem->id, NULL);
layflag++; /* is lay_xor */
@@ -492,8 +613,8 @@ static void outliner_draw_restrictbuts(uiBlock *block, Scene *scene, ARegion *ar
SCE_PASS_INDIRECT, SCE_PASS_EMIT, SCE_PASS_ENVIRONMENT))
{
bt = uiDefIconButBitI(block, TOG, passflag, 0, (*layflag & passflag) ? ICON_DOT : ICON_BLANK1,
- (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_SELECTX), (int)te->ys, UI_UNIT_X, UI_UNIT_Y,
- layflag, 0, 0, 0, 0, "Exclude this Pass from Combined");
+ (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_SELECTX), (int)te->ys, UI_UNIT_X,
+ UI_UNIT_Y, layflag, 0, 0, 0, 0, TIP_("Exclude this Pass from Combined"));
}
uiButSetFunc(bt, restrictbutton_r_lay_cb, tselem->id, NULL);
@@ -505,43 +626,49 @@ static void outliner_draw_restrictbuts(uiBlock *block, Scene *scene, ARegion *ar
uiBlockSetEmboss(block, UI_EMBOSSN);
bt = uiDefIconButBitI(block, ICONTOGN, eModifierMode_Realtime, 0, ICON_RESTRICT_VIEW_OFF,
- (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_VIEWX), (int)te->ys, UI_UNIT_X, UI_UNIT_Y,
- &(md->mode), 0, 0, 0, 0, "Restrict/Allow visibility in the 3D View");
+ (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_VIEWX), (int)te->ys, UI_UNIT_X,
+ UI_UNIT_Y, &(md->mode), 0, 0, 0, 0,
+ TIP_("Restrict/Allow visibility in the 3D View"));
uiButSetFunc(bt, restrictbutton_modifier_cb, scene, ob);
bt = uiDefIconButBitI(block, ICONTOGN, eModifierMode_Render, 0, ICON_RESTRICT_RENDER_OFF,
- (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_RENDERX), (int)te->ys, UI_UNIT_X, UI_UNIT_Y,
- &(md->mode), 0, 0, 0, 0, "Restrict/Allow renderability");
+ (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_RENDERX), (int)te->ys, UI_UNIT_X,
+ UI_UNIT_Y, &(md->mode), 0, 0, 0, 0, TIP_("Restrict/Allow renderability"));
uiButSetFunc(bt, restrictbutton_modifier_cb, scene, ob);
}
else if (tselem->type == TSE_POSE_CHANNEL) {
bPoseChannel *pchan = (bPoseChannel *)te->directdata;
Bone *bone = pchan->bone;
+ ob = (Object *)tselem->id;
uiBlockSetEmboss(block, UI_EMBOSSN);
bt = uiDefIconButBitI(block, ICONTOG, BONE_HIDDEN_P, 0, ICON_RESTRICT_VIEW_OFF,
- (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_VIEWX), (int)te->ys, UI_UNIT_X, UI_UNIT_Y,
- &(bone->flag), 0, 0, 0, 0, "Restrict/Allow visibility in the 3D View");
- uiButSetFunc(bt, restrictbutton_bone_cb, NULL, bone);
+ (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_VIEWX), (int)te->ys, UI_UNIT_X,
+ UI_UNIT_Y, &(bone->flag), 0, 0, 0, 0,
+ TIP_("Restrict/Allow visibility in the 3D View"));
+ uiButSetFunc(bt, restrictbutton_bone_visibility_cb, ob->data, bone);
bt = uiDefIconButBitI(block, ICONTOG, BONE_UNSELECTABLE, 0, ICON_RESTRICT_SELECT_OFF,
- (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_SELECTX), (int)te->ys, UI_UNIT_X, UI_UNIT_Y,
- &(bone->flag), 0, 0, 0, 0, "Restrict/Allow selection in the 3D View");
- uiButSetFunc(bt, restrictbutton_bone_cb, NULL, NULL);
+ (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_SELECTX), (int)te->ys, UI_UNIT_X,
+ UI_UNIT_Y, &(bone->flag), 0, 0, 0, 0,
+ TIP_("Restrict/Allow selection in the 3D View"));
+ uiButSetFunc(bt, restrictbutton_bone_select_cb, ob->data, bone);
}
else if (tselem->type == TSE_EBONE) {
EditBone *ebone = (EditBone *)te->directdata;
uiBlockSetEmboss(block, UI_EMBOSSN);
bt = uiDefIconButBitI(block, ICONTOG, BONE_HIDDEN_A, 0, ICON_RESTRICT_VIEW_OFF,
- (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_VIEWX), (int)te->ys, UI_UNIT_X, UI_UNIT_Y,
- &(ebone->flag), 0, 0, 0, 0, "Restrict/Allow visibility in the 3D View");
- uiButSetFunc(bt, restrictbutton_ebone_cb, NULL, ebone);
+ (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_VIEWX), (int)te->ys, UI_UNIT_X,
+ UI_UNIT_Y, &(ebone->flag), 0, 0, 0, 0,
+ TIP_("Restrict/Allow visibility in the 3D View"));
+ uiButSetFunc(bt, restrictbutton_ebone_visibility_cb, NULL, ebone);
bt = uiDefIconButBitI(block, ICONTOG, BONE_UNSELECTABLE, 0, ICON_RESTRICT_SELECT_OFF,
- (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_SELECTX), (int)te->ys, UI_UNIT_X, UI_UNIT_Y,
- &(ebone->flag), 0, 0, 0, 0, "Restrict/Allow selection in the 3D View");
- uiButSetFunc(bt, restrictbutton_ebone_cb, NULL, NULL);
+ (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_SELECTX), (int)te->ys, UI_UNIT_X,
+ UI_UNIT_Y, &(ebone->flag), 0, 0, 0, 0,
+ TIP_("Restrict/Allow selection in the 3D View"));
+ uiButSetFunc(bt, restrictbutton_ebone_select_cb, NULL, ebone);
}
}
@@ -571,7 +698,7 @@ static void outliner_draw_rnacols(ARegion *ar, int sizex)
}
static void outliner_draw_rnabuts(uiBlock *block, Scene *scene, ARegion *ar, SpaceOops *soops, int sizex, ListBase *lb)
-{
+{
TreeElement *te;
TreeStoreElem *tselem;
PointerRNA *ptr;
@@ -586,14 +713,17 @@ static void outliner_draw_rnabuts(uiBlock *block, Scene *scene, ARegion *ar, Spa
ptr = &te->rnaptr;
prop = te->directdata;
- if (!(RNA_property_type(prop) == PROP_POINTER && (TSELEM_OPEN(tselem, soops))) )
- uiDefAutoButR(block, ptr, prop, -1, "", ICON_NONE, sizex, (int)te->ys, OL_RNA_COL_SIZEX, UI_UNIT_Y - 1);
+ if (!(RNA_property_type(prop) == PROP_POINTER && (TSELEM_OPEN(tselem, soops)))) {
+ uiDefAutoButR(block, ptr, prop, -1, "", ICON_NONE, sizex, (int)te->ys, OL_RNA_COL_SIZEX,
+ UI_UNIT_Y - 1);
+ }
}
else if (tselem->type == TSE_RNA_ARRAY_ELEM) {
ptr = &te->rnaptr;
prop = te->directdata;
- uiDefAutoButR(block, ptr, prop, te->index, "", ICON_NONE, sizex, (int)te->ys, OL_RNA_COL_SIZEX, UI_UNIT_Y - 1);
+ uiDefAutoButR(block, ptr, prop, te->index, "", ICON_NONE, sizex, (int)te->ys, OL_RNA_COL_SIZEX,
+ UI_UNIT_Y - 1);
}
}
@@ -615,7 +745,7 @@ static void operator_search_cb(const struct bContext *UNUSED(C), void *UNUSED(ar
{
GHashIterator *iter = WM_operatortype_iter();
- for (; !BLI_ghashIterator_isDone(iter); BLI_ghashIterator_step(iter)) {
+ for (; BLI_ghashIterator_notDone(iter); BLI_ghashIterator_step(iter)) {
wmOperatorType *ot = BLI_ghashIterator_getValue(iter);
if (BLI_strcasestr(ot->idname, str)) {
@@ -806,7 +936,8 @@ static void outliner_draw_keymapbuts(uiBlock *block, ARegion *ar, SpaceOops *soo
/* pass */
}
else {
- uiDefBlockBut(block, operator_search_menu, kmi, "", xstart, (int)te->ys + 1, butw1, UI_UNIT_Y - 1, "Assign new Operator");
+ uiDefBlockBut(block, operator_search_menu, kmi, "", xstart, (int)te->ys + 1, butw1, UI_UNIT_Y - 1,
+ TIP_("Assign new Operator"));
}
xstart += butw1 + 10;
@@ -814,43 +945,58 @@ static void outliner_draw_keymapbuts(uiBlock *block, ARegion *ar, SpaceOops *soo
kmi->maptype = keymap_menu_type(kmi->type);
str = keymap_type_menu();
- but = uiDefButS(block, MENU, 0, str, xstart, (int)te->ys + 1, butw2, UI_UNIT_Y - 1, &kmi->maptype, 0, 0, 0, 0, "Event type");
+ but = uiDefButS(block, MENU, 0, str, xstart, (int)te->ys + 1, butw2, UI_UNIT_Y - 1, &kmi->maptype,
+ 0, 0, 0, 0, TIP_("Event type"));
uiButSetFunc(but, keymap_type_cb, kmi, NULL);
xstart += butw2 + 5;
/* edit actual event */
switch (kmi->maptype) {
case OL_KM_KEYBOARD:
- uiDefKeyevtButS(block, 0, "", xstart, (int)te->ys + 1, butw2, UI_UNIT_Y - 1, &kmi->type, "Key code");
+ uiDefKeyevtButS(block, 0, "", xstart, (int)te->ys + 1, butw2, UI_UNIT_Y - 1, &kmi->type,
+ TIP_("Key code"));
xstart += butw2 + 5;
break;
case OL_KM_MOUSE:
str = keymap_mouse_menu();
- uiDefButS(block, MENU, 0, str, xstart, (int)te->ys + 1, butw2, UI_UNIT_Y - 1, &kmi->type, 0, 0, 0, 0, "Mouse button");
+ uiDefButS(block, MENU, 0, str, xstart, (int)te->ys + 1, butw2, UI_UNIT_Y - 1, &kmi->type,
+ 0, 0, 0, 0, TIP_("Mouse button"));
xstart += butw2 + 5;
break;
case OL_KM_TWEAK:
str = keymap_tweak_menu();
- uiDefButS(block, MENU, 0, str, xstart, (int)te->ys + 1, butw2, UI_UNIT_Y - 1, &kmi->type, 0, 0, 0, 0, "Tweak gesture");
+ uiDefButS(block, MENU, 0, str, xstart, (int)te->ys + 1, butw2, UI_UNIT_Y - 1, &kmi->type,
+ 0, 0, 0, 0, TIP_("Tweak gesture"));
xstart += butw2 + 5;
str = keymap_tweak_dir_menu();
- uiDefButS(block, MENU, 0, str, xstart, (int)te->ys + 1, butw2, UI_UNIT_Y - 1, &kmi->val, 0, 0, 0, 0, "Tweak gesture direction");
+ uiDefButS(block, MENU, 0, str, xstart, (int)te->ys + 1, butw2, UI_UNIT_Y - 1, &kmi->val,
+ 0, 0, 0, 0, TIP_("Tweak gesture direction"));
xstart += butw2 + 5;
break;
}
/* modifiers */
- uiDefButS(block, OPTION, 0, "Shift", xstart, (int)te->ys + 1, butw3 + 5, UI_UNIT_Y - 1, &kmi->shift, 0, 0, 0, 0, "Modifier"); xstart += butw3 + 5;
- uiDefButS(block, OPTION, 0, "Ctrl", xstart, (int)te->ys + 1, butw3, UI_UNIT_Y - 1, &kmi->ctrl, 0, 0, 0, 0, "Modifier"); xstart += butw3;
- uiDefButS(block, OPTION, 0, "Alt", xstart, (int)te->ys + 1, butw3, UI_UNIT_Y - 1, &kmi->alt, 0, 0, 0, 0, "Modifier"); xstart += butw3;
- uiDefButS(block, OPTION, 0, "OS", xstart, (int)te->ys + 1, butw3, UI_UNIT_Y - 1, &kmi->oskey, 0, 0, 0, 0, "Modifier"); xstart += butw3;
- xstart += 5;
- uiDefKeyevtButS(block, 0, "", xstart, (int)te->ys + 1, butw3, UI_UNIT_Y - 1, &kmi->keymodifier, "Key Modifier code");
+ uiDefButS(block, OPTION, 0, IFACE_("Shift"), xstart, (int)te->ys + 1, butw3 + 5, UI_UNIT_Y - 1,
+ &kmi->shift, 0, 0, 0, 0, TIP_("Modifier"));
+ xstart += butw3 + 5;
+ uiDefButS(block, OPTION, 0, IFACE_("Ctrl"), xstart, (int)te->ys + 1, butw3, UI_UNIT_Y - 1, &kmi->ctrl,
+ 0, 0, 0, 0, TIP_("Modifier"));
+ xstart += butw3;
+ uiDefButS(block, OPTION, 0, IFACE_("Alt"), xstart, (int)te->ys + 1, butw3, UI_UNIT_Y - 1, &kmi->alt,
+ 0, 0, 0, 0, TIP_("Modifier"));
+ xstart += butw3;
+ uiDefButS(block, OPTION, 0, IFACE_("OS"), xstart, (int)te->ys + 1, butw3, UI_UNIT_Y - 1, &kmi->oskey,
+ 0, 0, 0, 0, TIP_("Modifier"));
+ xstart += butw3 + 5;
+ uiDefKeyevtButS(block, 0, "", xstart, (int)te->ys + 1, butw3, UI_UNIT_Y - 1, &kmi->keymodifier,
+ TIP_("Key Modifier code"));
xstart += butw3 + 5;
/* rna property */
if (kmi->ptr && kmi->ptr->data) {
- uiDefBut(block, LABEL, 0, "(RNA property)", xstart, (int)te->ys + 1, butw2, UI_UNIT_Y - 1, NULL, 0, 0, 0, 0, ""); xstart += butw2;
+ uiDefBut(block, LABEL, 0, IFACE_("(RNA property)"), xstart, (int)te->ys + 1, butw2, UI_UNIT_Y - 1,
+ NULL, 0, 0, 0, 0, "");
+ xstart += butw2;
}
(void)xstart;
@@ -878,7 +1024,8 @@ static void outliner_buttons(const bContext *C, uiBlock *block, ARegion *ar, Spa
/* If we add support to rename Sequence.
* need change this.
*/
- if (tselem->type == TSE_POSE_BASE) continue; // prevent crash when trying to rename 'pose' entry of armature
+ // prevent crash when trying to rename 'pose' entry of armature
+ if (tselem->type == TSE_POSE_BASE) continue;
if (tselem->type == TSE_EBONE) len = sizeof(((EditBone *) 0)->name);
else if (tselem->type == TSE_MODIFIER) len = sizeof(((ModifierData *) 0)->name);
@@ -891,7 +1038,8 @@ static void outliner_buttons(const bContext *C, uiBlock *block, ARegion *ar, Spa
spx = te->xs + 2 * UI_UNIT_X - 4;
if (spx + dx + 10 > ar->v2d.cur.xmax) dx = ar->v2d.cur.xmax - spx - 10;
- bt = uiDefBut(block, TEX, OL_NAMEBUTTON, "", spx, (int)te->ys, dx + 10, UI_UNIT_Y - 1, (void *)te->name, 1.0, (float)len, 0, 0, "");
+ bt = uiDefBut(block, TEX, OL_NAMEBUTTON, "", spx, (int)te->ys, dx + 10, UI_UNIT_Y - 1, (void *)te->name,
+ 1.0, (float)len, 0, 0, "");
uiButSetRenameFunc(bt, namebutton_cb, tselem);
/* returns false if button got removed */
@@ -924,7 +1072,8 @@ static void tselem_draw_icon_uibut(struct DrawIconArg *arg, int icon)
glDisable(GL_BLEND);
}
else {
- 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 : "");
+ 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);
@@ -932,7 +1081,8 @@ 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)
+static void tselem_draw_icon(uiBlock *block, int xmax, float x, float y, TreeStoreElem *tselem, TreeElement *te,
+ float alpha)
{
struct DrawIconArg arg;
float aspect;
@@ -1217,7 +1367,8 @@ static void tselem_draw_icon(uiBlock *block, int xmax, float x, float y, TreeSto
}
}
-static void outliner_draw_iconrow(bContext *C, uiBlock *block, Scene *scene, SpaceOops *soops, ListBase *lb, int level, int xmax, int *offsx, int ys)
+static void outliner_draw_iconrow(bContext *C, uiBlock *block, Scene *scene, SpaceOops *soops, ListBase *lb, int level,
+ int xmax, int *offsx, int ys)
{
TreeElement *te;
TreeStoreElem *tselem;
@@ -1236,12 +1387,20 @@ static void outliner_draw_iconrow(bContext *C, uiBlock *block, Scene *scene, Spa
/* active blocks get white circle */
if (tselem->type == 0) {
- if (te->idcode == ID_OB) active = (OBACT == (Object *)tselem->id);
- else if (scene->obedit && scene->obedit->data == tselem->id) active = 1; // XXX use context?
- else active = tree_element_active(C, scene, soops, te, 0);
+ if (te->idcode == ID_OB) {
+ active = (OBACT == (Object *)tselem->id);
+ }
+ else if (scene->obedit && scene->obedit->data == tselem->id) {
+ active = 1; // XXX use context?
+ }
+ else {
+ active = tree_element_active(C, scene, soops, te, 0);
+ }
}
- else active = tree_element_type_active(NULL, scene, soops, te, tselem, 0);
-
+ else {
+ active = tree_element_type_active(NULL, scene, soops, te, tselem, 0, false);
+ }
+
if (active) {
float ufac = UI_UNIT_X / 20.0f;
@@ -1286,7 +1445,8 @@ static void outliner_set_coord_tree_element(SpaceOops *soops, TreeElement *te, i
}
-static void outliner_draw_tree_element(bContext *C, uiBlock *block, Scene *scene, ARegion *ar, SpaceOops *soops, TreeElement *te, int startx, int *starty)
+static void outliner_draw_tree_element(bContext *C, uiBlock *block, Scene *scene, ARegion *ar, SpaceOops *soops,
+ TreeElement *te, int startx, int *starty)
{
TreeElement *ten;
TreeStoreElem *tselem;
@@ -1377,7 +1537,7 @@ static void outliner_draw_tree_element(bContext *C, uiBlock *block, Scene *scene
}
}
else {
- if (tree_element_type_active(NULL, scene, soops, te, tselem, 0) ) active = 2;
+ if (tree_element_type_active(NULL, scene, soops, te, tselem, 0, false) ) active = 2;
glColor4ub(220, 220, 255, alpha);
}
@@ -1685,15 +1845,17 @@ void draw_outliner(const bContext *C)
sizex_rna = max_ii(OL_RNA_COLX, sizex_rna + OL_RNA_COL_SPACEX);
/* get width of data (for setting 'tot' rect, this is column 1 + column 2 + a bit extra) */
- if (soops->outlinevis == SO_KEYMAP)
- sizex = sizex_rna + OL_RNA_COL_SIZEX * 3 + 50; // XXX this is only really a quick hack to make this wide enough...
+ if (soops->outlinevis == SO_KEYMAP)
+ // XXX this is only really a quick hack to make this wide enough...
+ sizex = sizex_rna + OL_RNA_COL_SIZEX * 3 + 50;
else
sizex = sizex_rna + OL_RNA_COL_SIZEX + 50;
}
else {
/* width must take into account restriction columns (if visible) so that entries will still be visible */
//outliner_width(soops, &soops->tree, &sizex);
- outliner_rna_width(soops, &soops->tree, &sizex, 0); // XXX should use outliner_width instead when te->xend will be set correctly...
+ // XXX should use outliner_width instead when te->xend will be set correctly...
+ outliner_rna_width(soops, &soops->tree, &sizex, 0);
/* constant offset for restriction columns */
// XXX this isn't that great yet...
diff --git a/source/blender/editors/space_outliner/outliner_edit.c b/source/blender/editors/space_outliner/outliner_edit.c
index 9a1b3628196..1e67e099508 100644
--- a/source/blender/editors/space_outliner/outliner_edit.c
+++ b/source/blender/editors/space_outliner/outliner_edit.c
@@ -146,7 +146,7 @@ static int do_outliner_item_openclose(bContext *C, SpaceOops *soops, TreeElement
}
/* event can enterkey, then it opens/closes */
-static int outliner_item_openclose(bContext *C, wmOperator *op, wmEvent *event)
+static int outliner_item_openclose(bContext *C, wmOperator *op, const wmEvent *event)
{
ARegion *ar = CTX_wm_region(C);
SpaceOops *soops = CTX_wm_space_outliner(C);
@@ -222,12 +222,12 @@ static int do_outliner_item_rename(bContext *C, ARegion *ar, SpaceOops *soops, T
if (mval[1] > te->ys && mval[1] < te->ys + UI_UNIT_Y) {
TreeStoreElem *tselem = TREESTORE(te);
- /* name and first icon */
- if (mval[0] > te->xs + UI_UNIT_X && mval[0] < te->xend) {
-
+ /* click on name */
+ if (mval[0] > te->xs + UI_UNIT_X * 2 && mval[0] < te->xend) {
do_item_rename(ar, te, tselem, reports);
+ return 1;
}
- return 1;
+ return 0;
}
for (te = te->subtree.first; te; te = te->next) {
@@ -236,20 +236,24 @@ static int do_outliner_item_rename(bContext *C, ARegion *ar, SpaceOops *soops, T
return 0;
}
-static int outliner_item_rename(bContext *C, wmOperator *UNUSED(op), wmEvent *event)
+static int outliner_item_rename(bContext *C, wmOperator *UNUSED(op), const wmEvent *event)
{
ARegion *ar = CTX_wm_region(C);
SpaceOops *soops = CTX_wm_space_outliner(C);
TreeElement *te;
float fmval[2];
+ bool change = false;
UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], fmval, fmval + 1);
for (te = soops->tree.first; te; te = te->next) {
- if (do_outliner_item_rename(C, ar, soops, te, fmval)) break;
+ if (do_outliner_item_rename(C, ar, soops, te, fmval)) {
+ change = true;
+ break;
+ }
}
- return OPERATOR_FINISHED;
+ return change ? OPERATOR_FINISHED : OPERATOR_PASS_THROUGH;
}
@@ -890,9 +894,13 @@ static void tree_element_show_hierarchy(Scene *scene, SpaceOops *soops, ListBase
else tselem->flag |= TSE_CLOSED;
}
}
- else tselem->flag |= TSE_CLOSED;
-
- if (TSELEM_OPEN(tselem, soops)) tree_element_show_hierarchy(scene, soops, &te->subtree);
+ else {
+ tselem->flag |= TSE_CLOSED;
+ }
+
+ if (TSELEM_OPEN(tselem, soops)) {
+ tree_element_show_hierarchy(scene, soops, &te->subtree);
+ }
}
}
@@ -1440,7 +1448,7 @@ static int parent_drop_exec(bContext *C, wmOperator *op)
}
/* Used for drag and drop parenting */
-TreeElement *outliner_dropzone_parent(bContext *C, wmEvent *event, TreeElement *te, float *fmval)
+TreeElement *outliner_dropzone_parent(bContext *C, const wmEvent *event, TreeElement *te, const float fmval[2])
{
SpaceOops *soops = CTX_wm_space_outliner(C);
TreeStoreElem *tselem = TREESTORE(te);
@@ -1469,7 +1477,7 @@ TreeElement *outliner_dropzone_parent(bContext *C, wmEvent *event, TreeElement *
return NULL;
}
-static int parent_drop_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int parent_drop_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
Object *par = NULL;
Object *ob = NULL;
@@ -1643,7 +1651,7 @@ void OUTLINER_OT_parent_drop(wmOperatorType *ot)
RNA_def_enum(ot->srna, "type", prop_make_parent_types, 0, "Type", "");
}
-int outliner_dropzone_parent_clear(bContext *C, wmEvent *event, TreeElement *te, float *fmval)
+int outliner_dropzone_parent_clear(bContext *C, const wmEvent *event, TreeElement *te, const float fmval[2])
{
SpaceOops *soops = CTX_wm_space_outliner(C);
TreeStoreElem *tselem = TREESTORE(te);
@@ -1681,7 +1689,7 @@ int outliner_dropzone_parent_clear(bContext *C, wmEvent *event, TreeElement *te,
return 0;
}
-static int parent_clear_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int parent_clear_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
Main *bmain = CTX_data_main(C);
Scene *scene = NULL;
@@ -1730,7 +1738,7 @@ void OUTLINER_OT_parent_clear(wmOperatorType *ot)
RNA_def_enum(ot->srna, "type", prop_clear_parent_types, 0, "Type", "");
}
-TreeElement *outliner_dropzone_scene(bContext *C, wmEvent *UNUSED(event), TreeElement *te, float *fmval)
+TreeElement *outliner_dropzone_scene(bContext *C, const wmEvent *UNUSED(event), TreeElement *te, const float fmval[2])
{
SpaceOops *soops = CTX_wm_space_outliner(C);
TreeStoreElem *tselem = TREESTORE(te);
@@ -1746,7 +1754,7 @@ TreeElement *outliner_dropzone_scene(bContext *C, wmEvent *UNUSED(event), TreeEl
return NULL;
}
-static int scene_drop_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int scene_drop_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
Scene *scene = NULL;
Object *ob = NULL;
@@ -1822,7 +1830,7 @@ void OUTLINER_OT_scene_drop(wmOperatorType *ot)
RNA_def_string(ot->srna, "scene", "Scene", MAX_ID_NAME, "Scene", "Target Scene");
}
-static int material_drop_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int material_drop_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
Material *ma = NULL;
Object *ob = NULL;
diff --git a/source/blender/editors/space_outliner/outliner_intern.h b/source/blender/editors/space_outliner/outliner_intern.h
index 63452de18d0..a918357ced2 100644
--- a/source/blender/editors/space_outliner/outliner_intern.h
+++ b/source/blender/editors/space_outliner/outliner_intern.h
@@ -165,8 +165,9 @@ void draw_outliner(const struct bContext *C);
void restrictbutton_gr_restrict_flag(void *poin, void *poin2, int flag);
/* outliner_select.c -------------------------------------------- */
-int tree_element_type_active(struct bContext *C, struct Scene *scene, struct SpaceOops *soops, TreeElement *te, TreeStoreElem *tselem, int set);
+int tree_element_type_active(struct bContext *C, struct Scene *scene, struct SpaceOops *soops, TreeElement *te, TreeStoreElem *tselem, int set, bool recursive);
int tree_element_active(struct bContext *C, struct Scene *scene, SpaceOops *soops, TreeElement *te, int set);
+int outliner_item_do_activate(struct bContext *C, int x, int y, bool extend, bool recursive);
/* outliner_edit.c ---------------------------------------------- */
@@ -189,9 +190,9 @@ void group_toggle_renderability_cb(struct bContext *C, struct Scene *scene, Tree
void item_rename_cb(struct bContext *C, struct Scene *scene, TreeElement *te, struct TreeStoreElem *tsep, struct TreeStoreElem *tselem);
-TreeElement *outliner_dropzone_parent(struct bContext *C, struct wmEvent *event, struct TreeElement *te, float *fmval);
-int outliner_dropzone_parent_clear(struct bContext *C, struct wmEvent *event, struct TreeElement *te, float *fmval);
-TreeElement *outliner_dropzone_scene(struct bContext *C, struct wmEvent *event, struct TreeElement *te, float *fmval);
+TreeElement *outliner_dropzone_parent(struct bContext *C, const struct wmEvent *event, struct TreeElement *te, const float fmval[2]);
+int outliner_dropzone_parent_clear(struct bContext *C, const struct wmEvent *event, struct TreeElement *te, const float fmval[2]);
+TreeElement *outliner_dropzone_scene(struct bContext *C, const struct wmEvent *event, struct TreeElement *te, const float fmval[2]);
/* ...................................................... */
void OUTLINER_OT_item_activate(struct wmOperatorType *ot);
diff --git a/source/blender/editors/space_outliner/outliner_ops.c b/source/blender/editors/space_outliner/outliner_ops.c
index 1dd043409a5..b9e3942a7ce 100644
--- a/source/blender/editors/space_outliner/outliner_ops.c
+++ b/source/blender/editors/space_outliner/outliner_ops.c
@@ -30,12 +30,12 @@
#include "DNA_space_types.h"
-#include "WM_api.h"
-#include "WM_types.h"
+#include "BLI_utildefines.h"
#include "RNA_access.h"
-#include "BLI_utildefines.h"
+#include "WM_api.h"
+#include "WM_types.h"
#include "outliner_intern.h"
@@ -88,10 +88,22 @@ void outliner_keymap(wmKeyConfig *keyconf)
WM_keymap_add_item(keymap, "OUTLINER_OT_item_rename", LEFTMOUSE, KM_DBL_CLICK, 0, 0);
kmi = WM_keymap_add_item(keymap, "OUTLINER_OT_item_activate", LEFTMOUSE, KM_CLICK, 0, 0);
+ RNA_boolean_set(kmi->ptr, "recursive", FALSE);
RNA_boolean_set(kmi->ptr, "extend", FALSE);
+
kmi = WM_keymap_add_item(keymap, "OUTLINER_OT_item_activate", LEFTMOUSE, KM_CLICK, KM_SHIFT, 0);
+ RNA_boolean_set(kmi->ptr, "recursive", FALSE);
+ RNA_boolean_set(kmi->ptr, "extend", TRUE);
+
+ kmi = WM_keymap_add_item(keymap, "OUTLINER_OT_item_activate", LEFTMOUSE, KM_CLICK, KM_CTRL, 0);
+ RNA_boolean_set(kmi->ptr, "recursive", TRUE);
+ RNA_boolean_set(kmi->ptr, "extend", FALSE);
+
+ kmi = WM_keymap_add_item(keymap, "OUTLINER_OT_item_activate", LEFTMOUSE, KM_CLICK, KM_CTRL | KM_SHIFT, 0);
+ RNA_boolean_set(kmi->ptr, "recursive", TRUE);
RNA_boolean_set(kmi->ptr, "extend", TRUE);
+
WM_keymap_add_item(keymap, "OUTLINER_OT_select_border", BKEY, KM_PRESS, 0, 0);
kmi = WM_keymap_add_item(keymap, "OUTLINER_OT_item_openclose", RETKEY, KM_PRESS, 0, 0);
diff --git a/source/blender/editors/space_outliner/outliner_select.c b/source/blender/editors/space_outliner/outliner_select.c
index fa337ba7af1..6fcfb457615 100644
--- a/source/blender/editors/space_outliner/outliner_select.c
+++ b/source/blender/editors/space_outliner/outliner_select.c
@@ -47,8 +47,11 @@
#include "BKE_context.h"
#include "BKE_depsgraph.h"
+#include "BKE_main.h"
+#include "BKE_object.h"
#include "BKE_scene.h"
#include "BKE_sequencer.h"
+#include "BKE_armature.h"
#include "ED_armature.h"
#include "ED_object.h"
@@ -140,7 +143,50 @@ static int tree_element_active_renderlayer(bContext *C, TreeElement *te, TreeSto
return 0;
}
-static int tree_element_set_active_object(bContext *C, Scene *scene, SpaceOops *soops, TreeElement *te, int set)
+/**
+ * Select object tree:
+ * CTRL+LMB: Select/Deselect object and all cildren
+ * CTRL+SHIFT+LMB: Add/Remove object and all children
+ */
+static void do_outliner_object_select_recursive(Scene *scene, Object *ob_parent, bool select)
+{
+ Base *base;
+
+ for (base = FIRSTBASE; base; base = base->next) {
+ Object *ob = base->object;
+ if ((((ob->restrictflag & OB_RESTRICT_VIEW) == 0) && BKE_object_is_child_recursive(ob_parent, ob))) {
+ ED_base_object_select(base, select ? BA_SELECT : BA_DESELECT);
+ }
+ }
+}
+
+static void do_outliner_bone_select_recursive(bArmature *arm, Bone *bone_parent, bool select)
+{
+ Bone *bone;
+ for (bone = bone_parent->childbase.first; bone; bone = bone->next) {
+ if (select && PBONE_SELECTABLE(arm, bone))
+ bone->flag |= BONE_SELECTED;
+ else
+ bone->flag &= ~(BONE_TIPSEL | BONE_SELECTED | BONE_ROOTSEL);
+ do_outliner_bone_select_recursive(arm, bone, select);
+ }
+}
+
+static void do_outliner_ebone_select_recursive(bArmature *arm, EditBone *ebone_parent, bool select)
+{
+ EditBone *ebone;
+ for (ebone = ebone_parent->next; ebone; ebone = ebone->next) {
+ if (ED_armature_ebone_is_child_recursive(ebone_parent, ebone)) {
+ if (select && EBONE_SELECTABLE(arm, ebone))
+ ebone->flag |= BONE_TIPSEL | BONE_SELECTED | BONE_ROOTSEL;
+ else
+ ebone->flag &= ~(BONE_TIPSEL | BONE_SELECTED | BONE_ROOTSEL);
+ }
+ }
+}
+
+static int tree_element_set_active_object(bContext *C, Scene *scene, SpaceOops *soops,
+ TreeElement *te, int set, bool recursive)
{
TreeStoreElem *tselem = TREESTORE(te);
Scene *sce;
@@ -148,7 +194,9 @@ static int tree_element_set_active_object(bContext *C, Scene *scene, SpaceOops
Object *ob = NULL;
/* if id is not object, we search back */
- if (te->idcode == ID_OB) ob = (Object *)tselem->id;
+ if (te->idcode == ID_OB) {
+ ob = (Object *)tselem->id;
+ }
else {
ob = (Object *)outliner_search_back(soops, te, ID_OB);
if (ob == OBACT) return 0;
@@ -176,6 +224,12 @@ static int tree_element_set_active_object(bContext *C, Scene *scene, SpaceOops
BKE_scene_base_deselect_all(scene);
ED_base_object_select(base, BA_SELECT);
}
+
+ if (recursive) {
+ /* Recursive select/deselect for Object hierarchies */
+ do_outliner_object_select_recursive(scene, ob, (ob->flag & SELECT) != 0);
+ }
+
if (C) {
ED_base_object_activate(C, base); /* adds notifier */
WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene);
@@ -312,7 +366,9 @@ static int tree_element_active_lamp(bContext *UNUSED(C), Scene *scene, SpaceOops
if (set) {
// XXX extern_set_butspace(F5KEY, 0);
}
- else return 1;
+ else {
+ return 1;
+ }
return 0;
}
@@ -395,7 +451,7 @@ static int tree_element_active_posegroup(bContext *C, Scene *scene, TreeElement
return 0;
}
-static int tree_element_active_posechannel(bContext *C, Scene *scene, TreeElement *te, TreeStoreElem *tselem, int set)
+static int tree_element_active_posechannel(bContext *C, Scene *scene, TreeElement *te, TreeStoreElem *tselem, int set, bool recursive)
{
Object *ob = (Object *)tselem->id;
bArmature *arm = ob->data;
@@ -404,9 +460,13 @@ static int tree_element_active_posechannel(bContext *C, Scene *scene, TreeElemen
if (set) {
if (!(pchan->bone->flag & BONE_HIDDEN_P)) {
- if (set == 2) ED_pose_deselectall(ob, 2); // 2 = clear active tag
- else ED_pose_deselectall(ob, 0); // 0 = deselect
-
+ if (set != 2) {
+ bPoseChannel *pchannel;
+ /* single select forces all other bones to get unselected */
+ for (pchannel = ob->pose->chanbase.first; pchannel; pchannel = pchannel->next)
+ pchannel->bone->flag &= ~(BONE_TIPSEL | BONE_SELECTED | BONE_ROOTSEL);
+ }
+
if (set == 2 && (pchan->bone->flag & BONE_SELECTED)) {
pchan->bone->flag &= ~BONE_SELECTED;
}
@@ -414,7 +474,12 @@ static int tree_element_active_posechannel(bContext *C, Scene *scene, TreeElemen
pchan->bone->flag |= BONE_SELECTED;
arm->act_bone = pchan->bone;
}
-
+
+ if (recursive) {
+ /* Recursive select/deselect */
+ do_outliner_bone_select_recursive(arm, pchan->bone, (pchan->bone->flag & BONE_SELECTED) != 0);
+ }
+
WM_event_add_notifier(C, NC_OBJECT | ND_BONE_ACTIVE, ob);
}
@@ -427,7 +492,7 @@ static int tree_element_active_posechannel(bContext *C, Scene *scene, TreeElemen
return 0;
}
-static int tree_element_active_bone(bContext *C, Scene *scene, TreeElement *te, TreeStoreElem *tselem, int set)
+static int tree_element_active_bone(bContext *C, Scene *scene, TreeElement *te, TreeStoreElem *tselem, int set, bool recursive)
{
bArmature *arm = (bArmature *)tselem->id;
Bone *bone = te->directdata;
@@ -436,8 +501,12 @@ static int tree_element_active_bone(bContext *C, Scene *scene, TreeElement *te,
if (!(bone->flag & BONE_HIDDEN_P)) {
Object *ob = OBACT;
if (ob) {
- if (set == 2) ED_pose_deselectall(ob, 2); // 2 is clear active tag
- else ED_pose_deselectall(ob, 0);
+ if (set != 2) {
+ bPoseChannel *pchannel;
+ /* single select forces all other bones to get unselected */
+ for (pchannel = ob->pose->chanbase.first; pchannel; pchannel = pchannel->next)
+ pchannel->bone->flag &= ~(BONE_TIPSEL | BONE_SELECTED | BONE_ROOTSEL);
+ }
}
if (set == 2 && (bone->flag & BONE_SELECTED)) {
@@ -447,6 +516,12 @@ static int tree_element_active_bone(bContext *C, Scene *scene, TreeElement *te,
bone->flag |= BONE_SELECTED;
arm->act_bone = bone;
}
+
+ if (recursive) {
+ /* Recursive select/deselect */
+ do_outliner_bone_select_recursive(arm, bone, (bone->flag & BONE_SELECTED) != 0);
+ }
+
WM_event_add_notifier(C, NC_OBJECT | ND_BONE_ACTIVE, ob);
}
@@ -479,35 +554,42 @@ static void tree_element_active_ebone__sel(bContext *C, Scene *scene, bArmature
WM_event_add_notifier(C, NC_OBJECT | ND_BONE_ACTIVE, scene->obedit);
}
-static int tree_element_active_ebone(bContext *C, Scene *scene, TreeElement *te, TreeStoreElem *UNUSED(tselem), int set)
+static int tree_element_active_ebone(bContext *C, Scene *scene, TreeElement *te, TreeStoreElem *UNUSED(tselem), int set, bool recursive)
{
bArmature *arm = scene->obedit->data;
EditBone *ebone = te->directdata;
-
- if (set == 1) {
- if (!(ebone->flag & BONE_HIDDEN_A)) {
- ED_armature_deselect_all(scene->obedit, 0); // deselect
- tree_element_active_ebone__sel(C, scene, arm, ebone, TRUE);
- return 1;
- }
- }
- else if (set == 2) {
- if (!(ebone->flag & BONE_HIDDEN_A)) {
- if (!(ebone->flag & BONE_SELECTED)) {
+ int status = 0;
+ if (set) {
+ if (set == 1) {
+ if (!(ebone->flag & BONE_HIDDEN_A)) {
+ ED_armature_deselect_all(scene->obedit, 0); // deselect
tree_element_active_ebone__sel(C, scene, arm, ebone, TRUE);
- return 1;
+ status = 1;
}
- else {
- /* entirely selected, so de-select */
- tree_element_active_ebone__sel(C, scene, arm, ebone, FALSE);
- return 0;
+ }
+ else if (set == 2) {
+ if (!(ebone->flag & BONE_HIDDEN_A)) {
+ if (!(ebone->flag & BONE_SELECTED)) {
+ tree_element_active_ebone__sel(C, scene, arm, ebone, TRUE);
+ status = 1;
+ }
+ else {
+ /* entirely selected, so de-select */
+ tree_element_active_ebone__sel(C, scene, arm, ebone, FALSE);
+ status = 0;
+ }
}
}
+
+ if (recursive) {
+ /* Recursive select/deselect */
+ do_outliner_ebone_select_recursive(arm, ebone, (ebone->flag & BONE_SELECTED) != 0);
+ }
}
else if (ebone->flag & BONE_SELECTED) {
- return 1;
+ status = 1;
}
- return 0;
+ return status;
}
static int tree_element_active_modifier(bContext *C, TreeElement *UNUSED(te), TreeStoreElem *tselem, int set)
@@ -675,19 +757,19 @@ int tree_element_active(bContext *C, Scene *scene, SpaceOops *soops, TreeElement
/* generic call for non-id data to make/check active in UI */
/* Context can be NULL when set==0 */
int tree_element_type_active(bContext *C, Scene *scene, SpaceOops *soops,
- TreeElement *te, TreeStoreElem *tselem, int set)
+ TreeElement *te, TreeStoreElem *tselem, int set, bool recursive)
{
switch (tselem->type) {
case TSE_DEFGROUP:
return tree_element_active_defgroup(C, scene, te, tselem, set);
case TSE_BONE:
- return tree_element_active_bone(C, scene, te, tselem, set);
+ return tree_element_active_bone(C, scene, te, tselem, set, recursive);
case TSE_EBONE:
- return tree_element_active_ebone(C, scene, te, tselem, set);
+ return tree_element_active_ebone(C, scene, te, tselem, set, recursive);
case TSE_MODIFIER:
return tree_element_active_modifier(C, te, tselem, set);
case TSE_LINKED_OB:
- if (set) tree_element_set_active_object(C, scene, soops, te, set);
+ if (set) tree_element_set_active_object(C, scene, soops, te, set, FALSE);
else if (tselem->id == (ID *)OBACT) return 1;
break;
case TSE_LINKED_PSYS:
@@ -695,7 +777,7 @@ int tree_element_type_active(bContext *C, Scene *scene, SpaceOops *soops,
case TSE_POSE_BASE:
return tree_element_active_pose(C, scene, te, tselem, set);
case TSE_POSE_CHANNEL:
- return tree_element_active_posechannel(C, scene, te, tselem, set);
+ return tree_element_active_posechannel(C, scene, te, tselem, set, recursive);
case TSE_CONSTRAINT:
return tree_element_active_constraint(C, te, tselem, set);
case TSE_R_LAYER:
@@ -716,7 +798,7 @@ int tree_element_type_active(bContext *C, Scene *scene, SpaceOops *soops,
/* ================================================ */
static int do_outliner_item_activate(bContext *C, Scene *scene, ARegion *ar, SpaceOops *soops,
- TreeElement *te, int extend, const float mval[2])
+ TreeElement *te, bool extend, bool recursive, const float mval[2])
{
if (mval[1] > te->ys && mval[1] < te->ys + UI_UNIT_Y) {
@@ -748,7 +830,9 @@ static int do_outliner_item_activate(bContext *C, Scene *scene, ARegion *ar, Spa
/* always makes active object */
if (tselem->type != TSE_SEQUENCE && tselem->type != TSE_SEQ_STRIP && tselem->type != TSE_SEQUENCE_DUP)
- tree_element_set_active_object(C, scene, soops, te, 1 + (extend != 0 && tselem->type == 0));
+ tree_element_set_active_object(C, scene, soops, te,
+ 1 + (extend != 0 && tselem->type == 0),
+ recursive && tselem->type == 0 );
if (tselem->type == 0) { // the lib blocks
/* editmode? */
@@ -791,31 +875,31 @@ static int do_outliner_item_activate(bContext *C, Scene *scene, ARegion *ar, Spa
else { // rest of types
tree_element_active(C, scene, soops, te, 1);
}
-
+
+ }
+ else {
+ tree_element_type_active(C, scene, soops, te, tselem, 1 + (extend != 0), recursive);
}
- else tree_element_type_active(C, scene, soops, te, tselem, 1 + (extend != 0));
return 1;
}
}
for (te = te->subtree.first; te; te = te->next) {
- if (do_outliner_item_activate(C, scene, ar, soops, te, extend, mval)) return 1;
+ if (do_outliner_item_activate(C, scene, ar, soops, te, extend, recursive, mval)) return 1;
}
return 0;
}
-/* event can enterkey, then it opens/closes */
-static int outliner_item_activate(bContext *C, wmOperator *op, wmEvent *event)
+int outliner_item_do_activate(bContext *C, int x, int y, bool extend, bool recursive)
{
Scene *scene = CTX_data_scene(C);
ARegion *ar = CTX_wm_region(C);
SpaceOops *soops = CTX_wm_space_outliner(C);
TreeElement *te;
float fmval[2];
- int extend = RNA_boolean_get(op->ptr, "extend");
- UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], fmval, fmval + 1);
+ UI_view2d_region_to_view(&ar->v2d, x, y, fmval, fmval + 1);
if (!ELEM3(soops->outlinevis, SO_DATABLOCKS, SO_USERDEF, SO_KEYMAP) &&
!(soops->flag & SO_HIDE_RESTRICTCOLS) &&
@@ -825,7 +909,7 @@ static int outliner_item_activate(bContext *C, wmOperator *op, wmEvent *event)
}
for (te = soops->tree.first; te; te = te->next) {
- if (do_outliner_item_activate(C, scene, ar, soops, te, extend, fmval)) break;
+ if (do_outliner_item_activate(C, scene, ar, soops, te, extend, recursive, fmval)) break;
}
if (te) {
@@ -855,6 +939,16 @@ static int outliner_item_activate(bContext *C, wmOperator *op, wmEvent *event)
return OPERATOR_FINISHED;
}
+/* event can enterkey, then it opens/closes */
+static int outliner_item_activate(bContext *C, wmOperator *op, const wmEvent *event)
+{
+ bool extend = RNA_boolean_get(op->ptr, "extend");
+ bool recursive = RNA_boolean_get(op->ptr, "recursive");
+ int x = event->mval[0];
+ int y = event->mval[1];
+ return outliner_item_do_activate(C, x, y, extend, recursive);
+}
+
void OUTLINER_OT_item_activate(wmOperatorType *ot)
{
ot->name = "Activate Item";
@@ -865,7 +959,8 @@ void OUTLINER_OT_item_activate(wmOperatorType *ot)
ot->poll = ED_operator_outliner_active;
- RNA_def_boolean(ot->srna, "extend", 1, "Extend", "Extend selection for activation");
+ RNA_def_boolean(ot->srna, "extend", true, "Extend", "Extend selection for activation");
+ RNA_def_boolean(ot->srna, "recursive", false, "Recursive", "Select Objects and their children");
}
/* ****************************************************** */
diff --git a/source/blender/editors/space_outliner/outliner_tools.c b/source/blender/editors/space_outliner/outliner_tools.c
index cd04c8c6bd1..258f0338d1e 100644
--- a/source/blender/editors/space_outliner/outliner_tools.c
+++ b/source/blender/editors/space_outliner/outliner_tools.c
@@ -75,6 +75,7 @@
#include "outliner_intern.h"
+
/* ****************************************************** */
/* ************ SELECTION OPERATIONS ********* */
@@ -190,8 +191,10 @@ static void unlink_texture_cb(bContext *UNUSED(C), Scene *UNUSED(scene), TreeEle
World *wrld = (World *)tsep->id;
mtex = wrld->mtex;
}
- else return;
-
+ else {
+ return;
+ }
+
for (a = 0; a < MAX_MTEX; a++) {
if (a == te->index && mtex[a]) {
if (mtex[a]->tex) {
@@ -264,6 +267,17 @@ static void object_select_cb(bContext *UNUSED(C), Scene *scene, TreeElement *te,
}
}
+static void object_select_hierarchy_cb(bContext *C, Scene *UNUSED(scene), TreeElement *UNUSED(te),
+ TreeStoreElem *UNUSED(tsep), TreeStoreElem *UNUSED(tselem))
+{
+ /* From where do i get the x,y coordinate of the mouse event ? */
+ wmWindow *win = CTX_wm_window(C);
+ int x = win->eventstate->mval[0];
+ int y = win->eventstate->mval[1];
+ outliner_item_do_activate(C, x, y, true, true);
+}
+
+
static void object_deselect_cb(bContext *UNUSED(C), Scene *scene, TreeElement *te,
TreeStoreElem *UNUSED(tsep), TreeStoreElem *tselem)
{
@@ -300,7 +314,7 @@ static void id_local_cb(bContext *C, Scene *UNUSED(scene), TreeElement *UNUSED(t
if (tselem->id->lib && (tselem->id->flag & LIB_EXTERN)) {
/* if the ID type has no special local function,
* just clear the lib */
- if (id_make_local(tselem->id, FALSE) == FALSE) {
+ if (id_make_local(tselem->id, false) == false) {
Main *bmain = CTX_data_main(C);
id_clear_lib_data(bmain, tselem->id);
}
@@ -526,9 +540,9 @@ static void sequence_cb(int event, TreeElement *te, TreeStoreElem *tselem, void
Sequence *seq = (Sequence *)te->directdata;
if (event == 1) {
Scene *scene = (Scene *)scene_ptr;
- Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
+ Editing *ed = BKE_sequencer_editing_get(scene, false);
if (BLI_findindex(ed->seqbasep, seq) != -1) {
- ED_sequencer_select_sequence_single(scene, seq, TRUE);
+ ED_sequencer_select_sequence_single(scene, seq, true);
}
}
@@ -569,15 +583,29 @@ static void outliner_do_data_operation(SpaceOops *soops, int type, int event, Li
/* **************************************** */
+enum {
+ OL_OP_ENDMARKER = 0,
+ OL_OP_SELECT,
+ OL_OP_DESELECT,
+ OL_OP_SELECT_HIERARCHY,
+ OL_OP_DELETE,
+ OL_OP_LOCALIZED, /* disabled, see below */
+ OL_OP_TOGVIS,
+ OL_OP_TOGSEL,
+ OL_OP_TOGREN,
+ OL_OP_RENAME
+};
+
static EnumPropertyItem prop_object_op_types[] = {
- {1, "SELECT", 0, "Select", ""},
- {2, "DESELECT", 0, "Deselect", ""},
- {4, "DELETE", 0, "Delete", ""},
- {6, "TOGVIS", 0, "Toggle Visible", ""},
- {7, "TOGSEL", 0, "Toggle Selectable", ""},
- {8, "TOGREN", 0, "Toggle Renderable", ""},
- {9, "RENAME", 0, "Rename", ""},
- {0, NULL, 0, NULL, NULL}
+ {OL_OP_SELECT, "SELECT", 0, "Select", ""},
+ {OL_OP_DESELECT, "DESELECT", 0, "Deselect", ""},
+ {OL_OP_SELECT_HIERARCHY, "SELECT_HIERARCHY", 0, "Select Hierarchy", ""},
+ {OL_OP_DELETE, "DELETE", 0, "Delete", ""},
+ {OL_OP_TOGVIS, "TOGVIS", 0, "Toggle Visible", ""},
+ {OL_OP_TOGSEL, "TOGSEL", 0, "Toggle Selectable", ""},
+ {OL_OP_TOGREN, "TOGREN", 0, "Toggle Renderable", ""},
+ {OL_OP_RENAME, "RENAME", 0, "Rename", ""},
+ {OL_OP_ENDMARKER, NULL, 0, NULL, NULL}
};
static int outliner_object_operation_exec(bContext *C, wmOperator *op)
@@ -594,7 +622,7 @@ static int outliner_object_operation_exec(bContext *C, wmOperator *op)
event = RNA_enum_get(op->ptr, "type");
- if (event == 1) {
+ if (event == OL_OP_SELECT) {
Scene *sce = scene; // to be able to delete, scenes are set...
outliner_do_object_operation(C, scene, soops, &soops->tree, object_select_cb);
if (scene != sce) {
@@ -604,12 +632,21 @@ static int outliner_object_operation_exec(bContext *C, wmOperator *op)
str = "Select Objects";
WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene);
}
- else if (event == 2) {
+ else if (event == OL_OP_SELECT_HIERARCHY) {
+ Scene *sce = scene; // to be able to delete, scenes are set...
+ outliner_do_object_operation(C, scene, soops, &soops->tree, object_select_hierarchy_cb);
+ if (scene != sce) {
+ ED_screen_set_scene(C, CTX_wm_screen(C), sce);
+ }
+ str = "Select Object Hierarchy";
+ WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene);
+ }
+ else if (event == OL_OP_DESELECT) {
outliner_do_object_operation(C, scene, soops, &soops->tree, object_deselect_cb);
str = "Deselect Objects";
WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene);
}
- else if (event == 4) {
+ else if (event == OL_OP_DELETE) {
outliner_do_object_operation(C, scene, soops, &soops->tree, object_delete_cb);
/* XXX: tree management normally happens from draw_outliner(), but when
@@ -623,26 +660,26 @@ static int outliner_object_operation_exec(bContext *C, wmOperator *op)
str = "Delete Objects";
WM_event_add_notifier(C, NC_SCENE | ND_OB_ACTIVE, scene);
}
- else if (event == 5) { /* disabled, see above enum (ton) */
+ else if (event == OL_OP_LOCALIZED) { /* disabled, see above enum (ton) */
outliner_do_object_operation(C, scene, soops, &soops->tree, id_local_cb);
str = "Localized Objects";
}
- else if (event == 6) {
+ else if (event == OL_OP_TOGVIS) {
outliner_do_object_operation(C, scene, soops, &soops->tree, object_toggle_visibility_cb);
str = "Toggle Visibility";
WM_event_add_notifier(C, NC_SCENE | ND_OB_VISIBLE, scene);
}
- else if (event == 7) {
+ else if (event == OL_OP_TOGSEL) {
outliner_do_object_operation(C, scene, soops, &soops->tree, object_toggle_selectability_cb);
str = "Toggle Selectability";
WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene);
}
- else if (event == 8) {
+ else if (event == OL_OP_TOGREN) {
outliner_do_object_operation(C, scene, soops, &soops->tree, object_toggle_renderability_cb);
str = "Toggle Renderability";
WM_event_add_notifier(C, NC_SCENE | ND_OB_RENDER, scene);
}
- else if (event == 9) {
+ else if (event == OL_OP_RENAME) {
outliner_do_object_operation(C, scene, soops, &soops->tree, item_rename_cb);
str = "Rename Object";
}
@@ -1229,7 +1266,7 @@ void OUTLINER_OT_data_operation(wmOperatorType *ot)
static int do_outliner_operation_event(bContext *C, Scene *scene, ARegion *ar, SpaceOops *soops,
- TreeElement *te, wmEvent *event, const float mval[2])
+ TreeElement *te, const wmEvent *event, const float mval[2])
{
ReportList *reports = CTX_wm_reports(C); // XXX...
@@ -1259,7 +1296,9 @@ static int do_outliner_operation_event(bContext *C, Scene *scene, ARegion *ar, S
WM_operator_name_call(C, "OUTLINER_OT_object_operation", WM_OP_INVOKE_REGION_WIN, NULL);
}
else if (idlevel) {
- if (idlevel == -1 || datalevel) BKE_report(reports, RPT_WARNING, "Mixed selection");
+ if (idlevel == -1 || datalevel) {
+ BKE_report(reports, RPT_WARNING, "Mixed selection");
+ }
else {
if (idlevel == ID_GR)
WM_operator_name_call(C, "OUTLINER_OT_group_operation", WM_OP_INVOKE_REGION_WIN, NULL);
@@ -1268,7 +1307,9 @@ static int do_outliner_operation_event(bContext *C, Scene *scene, ARegion *ar, S
}
}
else if (datalevel) {
- if (datalevel == -1) BKE_report(reports, RPT_WARNING, "Mixed selection");
+ if (datalevel == -1) {
+ BKE_report(reports, RPT_WARNING, "Mixed selection");
+ }
else {
if (datalevel == TSE_ANIM_DATA)
WM_operator_name_call(C, "OUTLINER_OT_animdata_operation", WM_OP_INVOKE_REGION_WIN, NULL);
@@ -1295,7 +1336,7 @@ static int do_outliner_operation_event(bContext *C, Scene *scene, ARegion *ar, S
}
-static int outliner_operation(bContext *C, wmOperator *UNUSED(op), wmEvent *event)
+static int outliner_operation(bContext *C, wmOperator *UNUSED(op), const wmEvent *event)
{
Scene *scene = CTX_data_scene(C);
ARegion *ar = CTX_wm_region(C);
diff --git a/source/blender/editors/space_outliner/outliner_tree.c b/source/blender/editors/space_outliner/outliner_tree.c
index f723fbedc7b..19bc1db2b5d 100644
--- a/source/blender/editors/space_outliner/outliner_tree.c
+++ b/source/blender/editors/space_outliner/outliner_tree.c
@@ -64,6 +64,8 @@
#include "BLI_utildefines.h"
#include "BLI_math.h"
+#include "BLF_translation.h"
+
#include "BKE_fcurve.h"
#include "BKE_main.h"
#include "BKE_library.h"
@@ -322,7 +324,7 @@ static void outliner_add_passes(SpaceOops *soops, TreeElement *tenla, ID *id, Sc
* in order to not overflow short tselem->nr */
te = outliner_add_element(soops, &tenla->subtree, id, tenla, TSE_R_PASS, LOG2I(SCE_PASS_COMBINED));
- te->name = "Combined";
+ te->name = IFACE_("Combined");
te->directdata = &srl->passflag;
/* save cpu cycles, but we add the first to invoke an open/close triangle */
@@ -331,71 +333,71 @@ static void outliner_add_passes(SpaceOops *soops, TreeElement *tenla, ID *id, Sc
return;
te = outliner_add_element(soops, &tenla->subtree, id, tenla, TSE_R_PASS, LOG2I(SCE_PASS_Z));
- te->name = "Z";
+ te->name = IFACE_("Z");
te->directdata = &srl->passflag;
te = outliner_add_element(soops, &tenla->subtree, id, tenla, TSE_R_PASS, LOG2I(SCE_PASS_VECTOR));
- te->name = "Vector";
+ te->name = IFACE_("Vector");
te->directdata = &srl->passflag;
te = outliner_add_element(soops, &tenla->subtree, id, tenla, TSE_R_PASS, LOG2I(SCE_PASS_NORMAL));
- te->name = "Normal";
+ te->name = IFACE_("Normal");
te->directdata = &srl->passflag;
te = outliner_add_element(soops, &tenla->subtree, id, tenla, TSE_R_PASS, LOG2I(SCE_PASS_UV));
- te->name = "UV";
+ te->name = IFACE_("UV");
te->directdata = &srl->passflag;
te = outliner_add_element(soops, &tenla->subtree, id, tenla, TSE_R_PASS, LOG2I(SCE_PASS_MIST));
- te->name = "Mist";
+ te->name = IFACE_("Mist");
te->directdata = &srl->passflag;
te = outliner_add_element(soops, &tenla->subtree, id, tenla, TSE_R_PASS, LOG2I(SCE_PASS_INDEXOB));
- te->name = "Index Object";
+ te->name = IFACE_("Index Object");
te->directdata = &srl->passflag;
te = outliner_add_element(soops, &tenla->subtree, id, tenla, TSE_R_PASS, LOG2I(SCE_PASS_INDEXMA));
- te->name = "Index Material";
+ te->name = IFACE_("Index Material");
te->directdata = &srl->passflag;
te = outliner_add_element(soops, &tenla->subtree, id, tenla, TSE_R_PASS, LOG2I(SCE_PASS_RGBA));
- te->name = "Color";
+ te->name = IFACE_("Color");
te->directdata = &srl->passflag;
te = outliner_add_element(soops, &tenla->subtree, id, tenla, TSE_R_PASS, LOG2I(SCE_PASS_DIFFUSE));
- te->name = "Diffuse";
+ te->name = IFACE_("Diffuse");
te->directdata = &srl->passflag;
te = outliner_add_element(soops, &tenla->subtree, id, tenla, TSE_R_PASS, LOG2I(SCE_PASS_SPEC));
- te->name = "Specular";
+ te->name = IFACE_("Specular");
te->directdata = &srl->passflag;
te = outliner_add_element(soops, &tenla->subtree, id, tenla, TSE_R_PASS, LOG2I(SCE_PASS_SHADOW));
- te->name = "Shadow";
+ te->name = IFACE_("Shadow");
te->directdata = &srl->passflag;
te = outliner_add_element(soops, &tenla->subtree, id, tenla, TSE_R_PASS, LOG2I(SCE_PASS_AO));
- te->name = "AO";
+ te->name = IFACE_("AO");
te->directdata = &srl->passflag;
te = outliner_add_element(soops, &tenla->subtree, id, tenla, TSE_R_PASS, LOG2I(SCE_PASS_REFLECT));
- te->name = "Reflection";
+ te->name = IFACE_("Reflection");
te->directdata = &srl->passflag;
te = outliner_add_element(soops, &tenla->subtree, id, tenla, TSE_R_PASS, LOG2I(SCE_PASS_REFRACT));
- te->name = "Refraction";
+ te->name = IFACE_("Refraction");
te->directdata = &srl->passflag;
te = outliner_add_element(soops, &tenla->subtree, id, tenla, TSE_R_PASS, LOG2I(SCE_PASS_INDIRECT));
- te->name = "Indirect";
+ te->name = IFACE_("Indirect");
te->directdata = &srl->passflag;
te = outliner_add_element(soops, &tenla->subtree, id, tenla, TSE_R_PASS, LOG2I(SCE_PASS_ENVIRONMENT));
- te->name = "Environment";
+ te->name = IFACE_("Environment");
te->directdata = &srl->passflag;
te = outliner_add_element(soops, &tenla->subtree, id, tenla, TSE_R_PASS, LOG2I(SCE_PASS_EMIT));
- te->name = "Emit";
+ te->name = IFACE_("Emit");
te->directdata = &srl->passflag;
}
@@ -407,7 +409,7 @@ static void outliner_add_scene_contents(SpaceOops *soops, ListBase *lb, Scene *s
TreeElement *tenla = outliner_add_element(soops, lb, sce, te, TSE_R_LAYER_BASE, 0);
int a;
- tenla->name = "RenderLayers";
+ tenla->name = IFACE_("RenderLayers");
for (a = 0, srl = sce->r.layers.first; srl; srl = srl->next, a++) {
TreeElement *tenlay = outliner_add_element(soops, &tenla->subtree, sce, te, TSE_R_LAYER, a);
tenlay->name = srl->name;
@@ -449,7 +451,7 @@ static void outliner_add_object_contents(SpaceOops *soops, TreeElement *te, Tree
TreeElement *ten;
TreeElement *tenla = outliner_add_element(soops, &te->subtree, ob, te, TSE_POSE_BASE, 0);
- tenla->name = "Pose";
+ tenla->name = IFACE_("Pose");
/* channels undefined in editmode, but we want the 'tenla' pose icon itself */
if ((arm->edbo == NULL) && (ob->mode & OB_MODE_POSE)) {
@@ -468,7 +470,7 @@ static void outliner_add_object_contents(SpaceOops *soops, TreeElement *te, Tree
TreeElement *tenla1 = outliner_add_element(soops, &ten->subtree, ob, ten, TSE_CONSTRAINT_BASE, 0);
//char *str;
- tenla1->name = "Constraints";
+ tenla1->name = IFACE_("Constraints");
for (con = pchan->constraints.first; con; con = con->next, const_index++) {
ten1 = outliner_add_element(soops, &tenla1->subtree, ob, tenla1, TSE_CONSTRAINT, const_index);
#if 0 /* disabled as it needs to be reworked for recoded constraints system */
@@ -508,7 +510,7 @@ static void outliner_add_object_contents(SpaceOops *soops, TreeElement *te, Tree
TreeElement *tenla = outliner_add_element(soops, &te->subtree, ob, te, TSE_POSEGRP_BASE, 0);
int a = 0;
- tenla->name = "Bone Groups";
+ tenla->name = IFACE_("Bone Groups");
for (agrp = ob->pose->agroups.first; agrp; agrp = agrp->next, a++) {
ten = outliner_add_element(soops, &tenla->subtree, ob, tenla, TSE_POSEGRP, a);
ten->name = agrp->name;
@@ -527,7 +529,7 @@ static void outliner_add_object_contents(SpaceOops *soops, TreeElement *te, Tree
TreeElement *tenla = outliner_add_element(soops, &te->subtree, ob, te, TSE_CONSTRAINT_BASE, 0);
//char *str;
- tenla->name = "Constraints";
+ tenla->name = IFACE_("Constraints");
for (con = ob->constraints.first, a = 0; con; con = con->next, a++) {
ten = outliner_add_element(soops, &tenla->subtree, ob, tenla, TSE_CONSTRAINT, a);
#if 0 /* disabled due to constraints system targets recode... code here needs review */
@@ -547,7 +549,7 @@ static void outliner_add_object_contents(SpaceOops *soops, TreeElement *te, Tree
TreeElement *temod = outliner_add_element(soops, &te->subtree, ob, te, TSE_MODIFIER_BASE, 0);
int index;
- temod->name = "Modifiers";
+ temod->name = IFACE_("Modifiers");
for (index = 0, md = ob->modifiers.first; md; index++, md = md->next) {
TreeElement *te = outliner_add_element(soops, &temod->subtree, ob, temod, TSE_MODIFIER, index);
te->name = md->name;
@@ -582,7 +584,7 @@ static void outliner_add_object_contents(SpaceOops *soops, TreeElement *te, Tree
TreeElement *ten;
TreeElement *tenla = outliner_add_element(soops, &te->subtree, ob, te, TSE_DEFGROUP_BASE, 0);
- tenla->name = "Vertex Groups";
+ tenla->name = IFACE_("Vertex Groups");
for (defgroup = ob->defbase.first, a = 0; defgroup; defgroup = defgroup->next, a++) {
ten = outliner_add_element(soops, &tenla->subtree, ob, tenla, TSE_DEFGROUP, a);
ten->name = defgroup->name;
@@ -856,7 +858,7 @@ static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *i
AnimData *adt = (AnimData *)iat->adt;
/* this element's info */
- te->name = "Animation";
+ te->name = IFACE_("Animation");
te->directdata = adt;
/* Action */
@@ -868,7 +870,7 @@ static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *i
ID *lastadded = NULL;
FCurve *fcu;
- ted->name = "Drivers";
+ ted->name = IFACE_("Drivers");
for (fcu = adt->drivers.first; fcu; fcu = fcu->next) {
if (fcu->driver && fcu->driver->variables.first) {
@@ -897,7 +899,7 @@ static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *i
NlaTrack *nlt;
int a = 0;
- tenla->name = "NLA Tracks";
+ tenla->name = IFACE_("NLA Tracks");
for (nlt = adt->nla_tracks.first; nlt; nlt = nlt->next) {
TreeElement *tenlt = outliner_add_element(soops, &tenla->subtree, nlt, tenla, TSE_NLA_TRACK, a);
@@ -951,7 +953,7 @@ static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *i
if (strip->dir)
te->name = strip->dir;
else
- te->name = "Strip None";
+ te->name = IFACE_("Strip None");
te->directdata = strip;
}
else if (type == TSE_SEQUENCE_DUP) {
@@ -970,7 +972,7 @@ static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *i
/* we do lazy build, for speed and to avoid infinite recusion */
if (ptr->data == NULL) {
- te->name = "(empty)";
+ te->name = IFACE_("(empty)");
}
else if (type == TSE_RNA_STRUCT) {
/* struct */
@@ -1096,7 +1098,7 @@ static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *i
ten->directdata = kmi;
if (kmi->propvalue) {
- ten->name = "Modal map, not yet";
+ ten->name = IFACE_("Modal map, not yet");
}
else {
WM_operator_py_idname(opname, ot->idname);
@@ -1257,19 +1259,23 @@ static int treesort_obtype_alpha(const void *v1, const void *v2)
const tTreeSort *x1 = v1, *x2 = v2;
/* first put objects last (hierarchy) */
- if (x1->idcode == ID_OB && x2->idcode != ID_OB) return 1;
- else if (x2->idcode == ID_OB && x1->idcode != ID_OB) return -1;
+ if (x1->idcode == ID_OB && x2->idcode != ID_OB) {
+ return 1;
+ }
+ else if (x2->idcode == ID_OB && x1->idcode != ID_OB) {
+ return -1;
+ }
else {
/* 2nd we check ob type */
if (x1->idcode == ID_OB && x2->idcode == ID_OB) {
- if (((Object *)x1->id)->type > ((Object *)x2->id)->type) return 1;
+ if (((Object *)x1->id)->type > ((Object *)x2->id)->type) return 1;
else if (((Object *)x1->id)->type > ((Object *)x2->id)->type) return -1;
else return 0;
}
else {
int comp = strcmp(x1->name, x2->name);
- if (comp > 0) return 1;
+ if (comp > 0) return 1;
else if (comp < 0) return -1;
return 0;
}
@@ -1502,7 +1508,7 @@ void outliner_build_tree(Main *mainvar, Scene *scene, SpaceOops *soops)
/* current file first - mainvar provides tselem with unique pointer - not used */
ten = outliner_add_element(soops, &soops->tree, mainvar, NULL, TSE_ID_BASE, 0);
- ten->name = "Current File";
+ ten->name = IFACE_("Current File");
tselem = TREESTORE(ten);
if (!tselem->used)
diff --git a/source/blender/editors/space_outliner/space_outliner.c b/source/blender/editors/space_outliner/space_outliner.c
index 4bf88376b74..3849aaf78c1 100644
--- a/source/blender/editors/space_outliner/space_outliner.c
+++ b/source/blender/editors/space_outliner/space_outliner.c
@@ -90,7 +90,7 @@ static void outliner_main_area_init(wmWindowManager *wm, ARegion *ar)
WM_event_add_dropbox_handler(&ar->handlers, lb);
}
-static int outliner_parent_drop_poll(bContext *C, wmDrag *drag, wmEvent *event)
+static int outliner_parent_drop_poll(bContext *C, wmDrag *drag, const wmEvent *event)
{
ARegion *ar = CTX_wm_region(C);
SpaceOops *soops = CTX_wm_space_outliner(C);
@@ -135,7 +135,7 @@ static void outliner_parent_drop_copy(wmDrag *drag, wmDropBox *drop)
RNA_string_set(drop->ptr, "child", id->name + 2);
}
-static int outliner_parent_clear_poll(bContext *C, wmDrag *drag, wmEvent *event)
+static int outliner_parent_clear_poll(bContext *C, wmDrag *drag, const wmEvent *event)
{
ARegion *ar = CTX_wm_region(C);
SpaceOops *soops = CTX_wm_space_outliner(C);
@@ -176,7 +176,7 @@ static void outliner_parent_clear_copy(wmDrag *drag, wmDropBox *drop)
RNA_enum_set(drop->ptr, "type", 0);
}
-static int outliner_scene_drop_poll(bContext *C, wmDrag *drag, wmEvent *event)
+static int outliner_scene_drop_poll(bContext *C, wmDrag *drag, const wmEvent *event)
{
ARegion *ar = CTX_wm_region(C);
SpaceOops *soops = CTX_wm_space_outliner(C);
@@ -205,7 +205,7 @@ static void outliner_scene_drop_copy(wmDrag *drag, wmDropBox *drop)
RNA_string_set(drop->ptr, "object", id->name + 2);
}
-static int outliner_material_drop_poll(bContext *C, wmDrag *drag, wmEvent *event)
+static int outliner_material_drop_poll(bContext *C, wmDrag *drag, const wmEvent *event)
{
ARegion *ar = CTX_wm_region(C);
SpaceOops *soops = CTX_wm_space_outliner(C);
@@ -316,6 +316,10 @@ static void outliner_main_area_listener(ARegion *ar, wmNotifier *wmn)
/* all modifier actions now */
ED_region_tag_redraw(ar);
break;
+ default:
+ /* Trigger update for NC_OBJECT itself */
+ ED_region_tag_redraw(ar);
+ break;
}
break;
case NC_GROUP:
diff --git a/source/blender/editors/space_sequencer/sequencer_add.c b/source/blender/editors/space_sequencer/sequencer_add.c
index 78a76532487..571779a7524 100644
--- a/source/blender/editors/space_sequencer/sequencer_add.c
+++ b/source/blender/editors/space_sequencer/sequencer_add.c
@@ -294,7 +294,7 @@ static int sequencer_add_scene_strip_exec(bContext *C, wmOperator *op)
}
-static int sequencer_add_scene_strip_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int sequencer_add_scene_strip_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
if (!ED_operator_sequencer_active(C)) {
BKE_report(op->reports, RPT_ERROR, "Sequencer area not active");
@@ -392,7 +392,7 @@ static int sequencer_add_movieclip_strip_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int sequencer_add_movieclip_strip_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int sequencer_add_movieclip_strip_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
if (!ED_operator_sequencer_active(C)) {
BKE_report(op->reports, RPT_ERROR, "Sequencer area not active");
@@ -489,7 +489,7 @@ static int sequencer_add_mask_strip_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int sequencer_add_mask_strip_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int sequencer_add_mask_strip_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
if (!ED_operator_sequencer_active(C)) {
BKE_report(op->reports, RPT_ERROR, "Sequencer area not active");
@@ -602,7 +602,7 @@ static int sequencer_add_movie_strip_exec(bContext *C, wmOperator *op)
}
-static int sequencer_add_movie_strip_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int sequencer_add_movie_strip_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
if (!ED_operator_sequencer_active(C)) {
@@ -657,7 +657,7 @@ static int sequencer_add_sound_strip_exec(bContext *C, wmOperator *op)
return sequencer_add_generic_strip_exec(C, op, BKE_sequencer_add_sound_strip);
}
-static int sequencer_add_sound_strip_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int sequencer_add_sound_strip_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
if (!ED_operator_sequencer_active(C)) {
@@ -769,7 +769,7 @@ static int sequencer_add_image_strip_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int sequencer_add_image_strip_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int sequencer_add_image_strip_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
if (!ED_operator_sequencer_active(C)) {
@@ -921,7 +921,7 @@ static int sequencer_add_effect_strip_exec(bContext *C, wmOperator *op)
/* add color */
-static int sequencer_add_effect_strip_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int sequencer_add_effect_strip_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
short is_type_set = RNA_struct_property_is_set(op->ptr, "type");
int type = -1;
diff --git a/source/blender/editors/space_sequencer/sequencer_draw.c b/source/blender/editors/space_sequencer/sequencer_draw.c
index 396878cbfeb..7ebe04f666b 100644
--- a/source/blender/editors/space_sequencer/sequencer_draw.c
+++ b/source/blender/editors/space_sequencer/sequencer_draw.c
@@ -813,7 +813,9 @@ static void UNUSED_FUNCTION(set_special_seq_update) (int val)
if (val) {
// XXX special_seq_update = find_nearest_seq(&x);
}
- else special_seq_update = NULL;
+ else {
+ special_seq_update = NULL;
+ }
}
ImBuf *sequencer_ibuf_get(struct Main *bmain, Scene *scene, SpaceSeq *sseq, int cfra, int frame_ofs)
diff --git a/source/blender/editors/space_sequencer/sequencer_edit.c b/source/blender/editors/space_sequencer/sequencer_edit.c
index 7be2d51a3c0..f0ed8d4107d 100644
--- a/source/blender/editors/space_sequencer/sequencer_edit.c
+++ b/source/blender/editors/space_sequencer/sequencer_edit.c
@@ -520,7 +520,7 @@ int seq_effect_find_selected(Scene *scene, Sequence *activeseq, int type, Sequen
return 0;
}
if ((seq != activeseq) && (seq != seq2)) {
- if (seq2 == NULL) seq2 = seq;
+ if (seq2 == NULL) seq2 = seq;
else if (seq1 == NULL) seq1 = seq;
else if (seq3 == NULL) seq3 = seq;
else {
@@ -889,7 +889,7 @@ static int insert_gap(Scene *scene, int gap, int cfra)
return done;
}
-static void UNUSED_FUNCTION(touch_seq_files) (Scene * scene)
+static void UNUSED_FUNCTION(touch_seq_files) (Scene *scene)
{
Sequence *seq;
Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
@@ -946,7 +946,7 @@ static void set_filter_seq(Scene *scene)
}
#endif
-static void UNUSED_FUNCTION(seq_remap_paths) (Scene * scene)
+static void UNUSED_FUNCTION(seq_remap_paths) (Scene *scene)
{
Sequence *seq, *last_seq = BKE_sequencer_active_get(scene);
Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
@@ -988,7 +988,7 @@ static void UNUSED_FUNCTION(seq_remap_paths) (Scene * scene)
}
-static void UNUSED_FUNCTION(no_gaps) (Scene * scene)
+static void UNUSED_FUNCTION(no_gaps) (Scene *scene)
{
Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
int cfra, first = 0, done;
@@ -1121,7 +1121,7 @@ static int sequencer_snap_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int sequencer_snap_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int sequencer_snap_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
Scene *scene = CTX_data_scene(C);
@@ -1546,7 +1546,7 @@ static int sequencer_cut_exec(bContext *C, wmOperator *op)
}
-static int sequencer_cut_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int sequencer_cut_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
Scene *scene = CTX_data_scene(C);
View2D *v2d = UI_view2d_fromcontext(C);
@@ -1695,7 +1695,7 @@ static int sequencer_delete_exec(bContext *C, wmOperator *UNUSED(op))
return OPERATOR_FINISHED;
}
-static int sequencer_delete_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int sequencer_delete_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
ARegion *ar = CTX_wm_region(C);
@@ -3105,7 +3105,7 @@ static int sequencer_change_path_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int sequencer_change_path_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int sequencer_change_path_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
Scene *scene = CTX_data_scene(C);
Sequence *seq = BKE_sequencer_active_get(scene);
diff --git a/source/blender/editors/space_sequencer/sequencer_select.c b/source/blender/editors/space_sequencer/sequencer_select.c
index 0d1ecb76d0e..3269e772be6 100644
--- a/source/blender/editors/space_sequencer/sequencer_select.c
+++ b/source/blender/editors/space_sequencer/sequencer_select.c
@@ -162,7 +162,7 @@ void select_surround_from_last(Scene *scene)
}
#endif
-void ED_sequencer_select_sequence_single(Scene * scene, Sequence * seq, int deselect_all)
+void ED_sequencer_select_sequence_single(Scene *scene, Sequence *seq, bool deselect_all)
{
Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
@@ -315,7 +315,7 @@ void SEQUENCER_OT_select_inverse(struct wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
-static int sequencer_select_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int sequencer_select_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
View2D *v2d = UI_view2d_fromcontext(C);
Scene *scene = CTX_data_scene(C);
@@ -552,8 +552,6 @@ void SEQUENCER_OT_select(wmOperatorType *ot)
}
-
-
/* run recursively to select linked */
static int select_more_less_seq__internal(Scene *scene, int sel, int linked)
{
@@ -670,7 +668,7 @@ void SEQUENCER_OT_select_less(wmOperatorType *ot)
/* select pick linked operator (uses the mouse) */
-static int sequencer_select_linked_pick_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int sequencer_select_linked_pick_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
Scene *scene = CTX_data_scene(C);
View2D *v2d = UI_view2d_fromcontext(C);
diff --git a/source/blender/editors/space_sequencer/sequencer_view.c b/source/blender/editors/space_sequencer/sequencer_view.c
index 92b17393114..7dcd3a70870 100644
--- a/source/blender/editors/space_sequencer/sequencer_view.c
+++ b/source/blender/editors/space_sequencer/sequencer_view.c
@@ -85,7 +85,7 @@ static void sample_draw(const bContext *C, ARegion *ar, void *arg_info)
}
}
-static void sample_apply(bContext *C, wmOperator *op, wmEvent *event)
+static void sample_apply(bContext *C, wmOperator *op, const wmEvent *event)
{
Main *bmain = CTX_data_main(C);
Scene *scene = CTX_data_scene(C);
@@ -168,7 +168,7 @@ static void sample_exit(bContext *C, wmOperator *op)
MEM_freeN(info);
}
-static int sample_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int sample_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
ARegion *ar = CTX_wm_region(C);
SpaceSeq *sseq = CTX_wm_space_seq(C);
@@ -189,7 +189,7 @@ static int sample_invoke(bContext *C, wmOperator *op, wmEvent *event)
return OPERATOR_RUNNING_MODAL;
}
-static int sample_modal(bContext *C, wmOperator *op, wmEvent *event)
+static int sample_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
switch (event->type) {
case LEFTMOUSE:
diff --git a/source/blender/editors/space_sequencer/space_sequencer.c b/source/blender/editors/space_sequencer/space_sequencer.c
index 4c6b909882c..ffe89407715 100644
--- a/source/blender/editors/space_sequencer/space_sequencer.c
+++ b/source/blender/editors/space_sequencer/space_sequencer.c
@@ -373,7 +373,7 @@ static void sequencer_main_area_draw(const bContext *C, ARegion *ar)
/* ************* dropboxes ************* */
-static int image_drop_poll(bContext *C, wmDrag *drag, wmEvent *event)
+static int image_drop_poll(bContext *C, wmDrag *drag, const wmEvent *event)
{
ARegion *ar = CTX_wm_region(C);
Scene *scene = CTX_data_scene(C);
@@ -387,7 +387,7 @@ static int image_drop_poll(bContext *C, wmDrag *drag, wmEvent *event)
return 0;
}
-static int movie_drop_poll(bContext *C, wmDrag *drag, wmEvent *event)
+static int movie_drop_poll(bContext *C, wmDrag *drag, const wmEvent *event)
{
ARegion *ar = CTX_wm_region(C);
Scene *scene = CTX_data_scene(C);
@@ -400,7 +400,7 @@ static int movie_drop_poll(bContext *C, wmDrag *drag, wmEvent *event)
return 0;
}
-static int sound_drop_poll(bContext *C, wmDrag *drag, wmEvent *event)
+static int sound_drop_poll(bContext *C, wmDrag *drag, const wmEvent *event)
{
ARegion *ar = CTX_wm_region(C);
Scene *scene = CTX_data_scene(C);
diff --git a/source/blender/editors/space_text/space_text.c b/source/blender/editors/space_text/space_text.c
index ff9d1329721..110e0ab5bc4 100644
--- a/source/blender/editors/space_text/space_text.c
+++ b/source/blender/editors/space_text/space_text.c
@@ -458,7 +458,7 @@ static void text_cursor(wmWindow *win, ScrArea *UNUSED(sa), ARegion *UNUSED(ar))
/* ************* dropboxes ************* */
-static int text_drop_poll(bContext *UNUSED(C), wmDrag *drag, wmEvent *UNUSED(event))
+static int text_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUSED(event))
{
if (drag->type == WM_DRAG_PATH)
if (ELEM(drag->icon, ICON_FILE_SCRIPT, ICON_FILE_BLANK)) /* rule might not work? */
diff --git a/source/blender/editors/space_text/text_autocomplete.c b/source/blender/editors/space_text/text_autocomplete.c
index 7c18b5c283a..838ffb948b1 100644
--- a/source/blender/editors/space_text/text_autocomplete.c
+++ b/source/blender/editors/space_text/text_autocomplete.c
@@ -220,7 +220,7 @@ static GHash *text_autocomplete_build(Text *text)
TextFormatType *tft;
tft = ED_text_format_get(text);
- for (; !BLI_ghashIterator_isDone(iter); BLI_ghashIterator_step(iter)) {
+ for (; BLI_ghashIterator_notDone(iter); BLI_ghashIterator_step(iter)) {
const char *s = BLI_ghashIterator_getValue(iter);
texttool_suggest_add(s, tft->format_identifier(s));
}
@@ -282,7 +282,7 @@ static void confirm_suggestion(Text *text)
/* -- */
-static int text_autocomplete_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int text_autocomplete_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
SpaceText *st = CTX_wm_space_text(C);
Text *text = CTX_data_edit_text(C);
@@ -313,7 +313,7 @@ static int text_autocomplete_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED
static int doc_scroll = 0;
-static int text_autocomplete_modal(bContext *C, wmOperator *op, wmEvent *event)
+static int text_autocomplete_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
SpaceText *st = CTX_wm_space_text(C);
ScrArea *sa = CTX_wm_area(C);
diff --git a/source/blender/editors/space_text/text_draw.c b/source/blender/editors/space_text/text_draw.c
index c264368e714..95fd7fce878 100644
--- a/source/blender/editors/space_text/text_draw.c
+++ b/source/blender/editors/space_text/text_draw.c
@@ -67,12 +67,14 @@ static void text_font_end(SpaceText *UNUSED(st))
{
}
-static int text_font_draw(SpaceText *UNUSED(st), int x, int y, const char *str)
+static int text_font_draw(SpaceText *st, int x, int y, const char *str)
{
+ int columns;
+
BLF_position(mono, x, y, 0);
- BLF_draw(mono, str, BLF_DRAW_STR_DUMMY_MAX);
+ columns = BLF_draw_mono(mono, str, BLF_DRAW_STR_DUMMY_MAX, st->cwidth);
- return BLF_width(mono, str);
+ return st->cwidth * columns;
}
static int text_font_draw_character(SpaceText *st, int x, int y, char c)
@@ -85,10 +87,13 @@ static int text_font_draw_character(SpaceText *st, int x, int y, char c)
static int text_font_draw_character_utf8(SpaceText *st, int x, int y, const char *c)
{
+ int columns;
+
const size_t len = BLI_str_utf8_size_safe(c);
BLF_position(mono, x, y, 0);
- BLF_draw(mono, c, len);
- return st->cwidth;
+ columns = BLF_draw_mono(mono, c, len, st->cwidth);
+
+ return st->cwidth * columns;
}
#if 0
@@ -216,7 +221,7 @@ void wrap_offset(SpaceText *st, ARegion *ar, TextLine *linein, int cursin, int *
}
max = wrap_width(st, ar);
- cursin = txt_utf8_offset_to_index(linein->line, cursin);
+ cursin = txt_utf8_offset_to_column(linein->line, cursin);
while (linep) {
start = 0;
@@ -225,6 +230,7 @@ void wrap_offset(SpaceText *st, ARegion *ar, TextLine *linein, int cursin, int *
*offc = 0;
for (i = 0, j = 0; linep->line[j]; j += BLI_str_utf8_size_safe(linep->line + j)) {
int chars;
+ int columns = BLI_str_utf8_char_width_safe(linep->line + j); /* = 1 for tab */
/* Mimic replacement of tabs */
ch = linep->line[j];
@@ -238,7 +244,9 @@ void wrap_offset(SpaceText *st, ARegion *ar, TextLine *linein, int cursin, int *
}
while (chars--) {
- if (i - start >= max) {
+ if (i + columns - start > max) {
+ end = MIN2(end, i);
+
if (chop && linep == linein && i >= cursin) {
if (i == cursin) {
(*offl)++;
@@ -261,7 +269,7 @@ void wrap_offset(SpaceText *st, ARegion *ar, TextLine *linein, int cursin, int *
if (linep == linein && i >= cursin)
return;
}
- i++;
+ i += columns;
}
}
if (linep == linein) break;
@@ -286,9 +294,10 @@ void wrap_offset_in_line(SpaceText *st, ARegion *ar, TextLine *linein, int cursi
end = max;
chop = 1;
*offc = 0;
- cursin = txt_utf8_offset_to_index(linein->line, cursin);
+ cursin = txt_utf8_offset_to_column(linein->line, cursin);
for (i = 0, j = 0; linein->line[j]; j += BLI_str_utf8_size_safe(linein->line + j)) {
+ int columns = BLI_str_utf8_char_width_safe(linein->line + j); /* = 1 for tab */
/* Mimic replacement of tabs */
ch = linein->line[j];
@@ -301,7 +310,9 @@ void wrap_offset_in_line(SpaceText *st, ARegion *ar, TextLine *linein, int cursi
chars = 1;
while (chars--) {
- if (i - start >= max) {
+ if (i + columns - start > max) {
+ end = MIN2(end, i);
+
if (chop && i >= cursin) {
if (i == cursin) {
(*offl)++;
@@ -324,7 +335,7 @@ void wrap_offset_in_line(SpaceText *st, ARegion *ar, TextLine *linein, int cursi
if (i >= cursin)
return;
}
- i++;
+ i += columns;
}
}
}
@@ -337,24 +348,35 @@ int text_get_char_pos(SpaceText *st, const char *line, int cur)
if (line[i] == '\t')
a += st->tabnumber - a % st->tabnumber;
else
- a++;
+ a += BLI_str_utf8_char_width_safe(line + i);
}
return a;
}
-static const char *txt_utf8_get_nth(const char *str, int n)
+static const char *txt_utf8_forward_columns(const char *str, int columns, int *padding)
{
- int pos = 0;
- while (str[pos] && n--) {
- pos += BLI_str_utf8_size_safe(str + pos);
+ int col;
+ const char *p = str;
+ while (*p) {
+ col = BLI_str_utf8_char_width(p);
+ if (columns - col < 0)
+ break;
+ columns -= col;
+ p += BLI_str_utf8_size_safe(p);
+ if (columns == 0)
+ break;
}
- return str + pos;
+ if (padding)
+ *padding = *p ? columns : 0;
+ return p;
}
static int text_draw_wrapped(SpaceText *st, const char *str, int x, int y, int w, const char *format, int skip)
{
FlattenString fs;
- int basex, i, a, start, end, max, lines; /* view */
+ int basex, lines;
+ int i, wrap, end, max, columns, padding; /* column */
+ int a, fstart, fpos; /* utf8 chars */
int mi, ma, mstart, mend; /* mem */
char fmt_prev = 0xff;
@@ -365,41 +387,46 @@ static int text_draw_wrapped(SpaceText *st, const char *str, int x, int y, int w
basex = x;
lines = 1;
- start = 0; mstart = 0;
- end = max; mend = txt_utf8_get_nth(str, max) - str;
+ fpos = fstart = 0; mstart = 0;
+ mend = txt_utf8_forward_columns(str, max, &padding) - str;
+ end = wrap = max - padding;
- for (i = 0, mi = 0; str[mi]; i++, mi += BLI_str_utf8_size_safe(str + mi)) {
- if (i - start >= max) {
+ for (i = 0, mi = 0; str[mi]; i += columns, mi += BLI_str_utf8_size_safe(str + mi)) {
+ columns = BLI_str_utf8_char_width_safe(str + mi);
+ if (i + columns > end) {
/* skip hidden part of line */
if (skip) {
skip--;
- start = end; mstart = mend;
- end += max; mend = txt_utf8_get_nth(str + mend, max) - str;
+ fstart = fpos; mstart = mend;
+ mend = txt_utf8_forward_columns(str + mend, max, &padding) - str;
+ end = (wrap += max - padding);
continue;
}
/* Draw the visible portion of text on the overshot line */
- for (a = start, ma = mstart; a < end; a++, ma += BLI_str_utf8_size_safe(str + ma)) {
+ for (a = fstart, ma = mstart; ma < mend; a++, ma += BLI_str_utf8_size_safe(str + ma)) {
if (st->showsyntax && format) {
if (fmt_prev != format[a]) format_draw_color(fmt_prev = format[a]);
}
x += text_font_draw_character_utf8(st, x, y, str + ma);
+ fpos++;
}
y -= st->lheight_dpi + TXT_LINE_SPACING;
x = basex;
lines++;
- start = end; mstart = mend;
- end += max; mend = txt_utf8_get_nth(str + mend, max) - str;
+ fstart = fpos; mstart = mend;
+ mend = txt_utf8_forward_columns(str + mend, max, &padding) - str;
+ end = (wrap += max - padding);
if (y <= 0) break;
}
else if (str[mi] == ' ' || str[mi] == '-') {
- end = i + 1; mend = mi + 1;
+ wrap = i + 1; mend = mi + 1;
}
}
/* Draw the remaining text */
- for (a = start, ma = mstart; str[ma] && y > 0; a++, ma += BLI_str_utf8_size_safe(str + ma)) {
+ for (a = fstart, ma = mstart; str[ma] && y > 0; a++, ma += BLI_str_utf8_size_safe(str + ma)) {
if (st->showsyntax && format) {
if (fmt_prev != format[a]) format_draw_color(fmt_prev = format[a]);
}
@@ -412,53 +439,55 @@ static int text_draw_wrapped(SpaceText *st, const char *str, int x, int y, int w
return lines;
}
-static int text_draw(SpaceText *st, char *str, int cshift, int maxwidth, int draw, int x, int y, const char *format)
+static void text_draw(SpaceText *st, char *str, int cshift, int maxwidth, int x, int y, const char *format)
{
FlattenString fs;
- int *acc, r = 0;
- const char *in;
+ int columns, size, n, w = 0, padding, amount = 0;
+ const char *in = NULL;
- int w = flatten_string(st, &fs, str);
- if (w < cshift) {
- flatten_string_free(&fs);
- return 0; /* String is shorter than shift */
- }
-
- in = txt_utf8_get_nth(fs.buf, cshift);
- acc = fs.accum + cshift;
- w = w - cshift;
+ for (n = flatten_string(st, &fs, str), str = fs.buf; n > 0; n--) {
+ columns = BLI_str_utf8_char_width_safe(str);
+ size = BLI_str_utf8_size_safe(str);
- if (draw) {
- int amount = maxwidth ? MIN2(w, maxwidth) : w;
-
- if (st->showsyntax && format) {
- int a, str_shift = 0;
- char fmt_prev = 0xff;
- format = format + cshift;
-
- for (a = 0; a < amount; a++) {
- if (format[a] != fmt_prev) format_draw_color(fmt_prev = format[a]);
- x += text_font_draw_character_utf8(st, x, y, in + str_shift);
- str_shift += BLI_str_utf8_size_safe(in + str_shift);
+ if (!in) {
+ if (w >= cshift) {
+ padding = w - cshift;
+ in = str;
}
+ else if (format)
+ format++;
}
- else {
- text_font_draw(st, x, y, in);
+ if (in) {
+ if (maxwidth && w + columns > cshift + maxwidth)
+ break;
+ amount++;
+ }
+
+ w += columns;
+ str += size;
+ }
+ if (!in) {
+ flatten_string_free(&fs);
+ return; /* String is shorter than shift or ends with a padding */
+ }
+
+ x += st->cwidth * padding;
+
+ if (st->showsyntax && format) {
+ int a, str_shift = 0;
+ char fmt_prev = 0xff;
+
+ for (a = 0; a < amount; a++) {
+ if (format[a] != fmt_prev) format_draw_color(fmt_prev = format[a]);
+ x += text_font_draw_character_utf8(st, x, y, in + str_shift);
+ str_shift += BLI_str_utf8_size_safe(in + str_shift);
}
}
else {
- while (w-- && *acc++ < maxwidth)
- r += st->cwidth;
+ text_font_draw(st, x, y, in);
}
flatten_string_free(&fs);
-
- if (cshift && r == 0)
- return 0;
- else if (st->showlinenrs)
- return r + TXT_OFFSET + TEXTXLOC;
- else
- return r + TXT_OFFSET;
}
/************************ cache utilities *****************************/
@@ -672,25 +701,29 @@ int text_get_visible_lines(SpaceText *st, ARegion *ar, const char *str)
start = 0;
end = max;
for (i = 0, j = 0; str[j]; j += BLI_str_utf8_size_safe(str + j)) {
+ int columns = BLI_str_utf8_char_width_safe(str + j); /* = 1 for tab */
+
/* Mimic replacement of tabs */
ch = str[j];
if (ch == '\t') {
chars = st->tabnumber - i % st->tabnumber;
ch = ' ';
}
- else chars = 1;
+ else {
+ chars = 1;
+ }
while (chars--) {
- if (i - start >= max) {
+ if (i + columns - start > max) {
lines++;
- start = end;
+ start = MIN2(end, i);
end += max;
}
else if (ch == ' ' || ch == '-') {
end = i + 1;
}
- i++;
+ i += columns;
}
}
@@ -712,7 +745,9 @@ int text_get_span_wrap(SpaceText *st, ARegion *ar, TextLine *from, TextLine *to)
return ret;
}
- else return txt_get_span(from, to);
+ else {
+ return txt_get_span(from, to);
+ }
}
int text_get_total_lines(SpaceText *st, ARegion *ar)
@@ -927,7 +962,7 @@ static void draw_documentation(SpaceText *st, ARegion *ar)
buf[i] = '\0';
if (lines >= 0) {
y -= st->lheight_dpi;
- text_draw(st, buf, 0, 0, 1, x + 4, y - 3, NULL);
+ text_draw(st, buf, 0, 0, x + 4, y - 3, NULL);
}
i = 0; br = DOC_WIDTH; lines++;
}
@@ -936,7 +971,7 @@ static void draw_documentation(SpaceText *st, ARegion *ar)
buf[br] = '\0';
if (lines >= 0) {
y -= st->lheight_dpi;
- text_draw(st, buf, 0, 0, 1, x + 4, y - 3, NULL);
+ text_draw(st, buf, 0, 0, x + 4, y - 3, NULL);
}
p -= i - br - 1; /* Rewind pointer to last break */
i = 0; br = DOC_WIDTH; lines++;
@@ -955,9 +990,9 @@ static void draw_documentation(SpaceText *st, ARegion *ar)
static void draw_suggestion_list(SpaceText *st, ARegion *ar)
{
SuggItem *item, *first, *last, *sel;
- TextLine *tmp;
- char str[SUGG_LIST_WIDTH + 1];
- int w, boxw = 0, boxh, i, l, x, y, *top;
+ char str[SUGG_LIST_WIDTH * BLI_UTF8_MAX + 1];
+ int offl, offc, vcurl, vcurc;
+ int w, boxw = 0, boxh, i, x, y, *top;
const int lheight = st->lheight_dpi + TXT_LINE_SPACING;
const int margin_x = 2;
@@ -973,24 +1008,24 @@ static void draw_suggestion_list(SpaceText *st, ARegion *ar)
sel = texttool_suggest_selected();
top = texttool_suggest_top();
- /* Count the visible lines to the cursor */
- for (tmp = st->text->curl, l = -st->top; tmp; tmp = tmp->prev, l++) ;
- if (l < 0) return;
-
- if (st->showlinenrs) {
- x = st->cwidth * (st->text->curc - st->left) + TXT_OFFSET + TEXTXLOC - 4;
- }
- else {
- x = st->cwidth * (st->text->curc - st->left) + TXT_OFFSET - 4;
- }
+ wrap_offset(st, ar, st->text->curl, st->text->curc, &offl, &offc);
+ vcurl = txt_get_span(st->text->lines.first, st->text->curl) - st->top + offl;
+ vcurc = text_get_char_pos(st, st->text->curl->line, st->text->curc) - st->left + offc;
+
+ x = st->showlinenrs ? TXT_OFFSET + TEXTXLOC : TXT_OFFSET;
+ x += vcurc * st->cwidth - 4;
+ y = ar->winy - (vcurl + 1) * lheight - 2;
+
/* offset back so the start of the text lines up with the suggestions,
* not essential but makes suggestions easier to follow */
x -= st->cwidth * (st->text->curc - text_find_identifier_start(st->text->curl->line, st->text->curc));
- y = ar->winy - lheight * l - 2;
boxw = SUGG_LIST_WIDTH * st->cwidth + 20;
boxh = SUGG_LIST_SIZE * lheight + 8;
+ if (x + boxw > ar->winx)
+ x = MAX2(0, ar->winx - boxw);
+
/* not needed but stands out nicer */
uiDrawBoxShadow(220, x, y - boxh, x + boxw, y);
@@ -1003,12 +1038,13 @@ static void draw_suggestion_list(SpaceText *st, ARegion *ar)
for (i = 0, item = first; i < *top && item->next; i++, item = item->next) ;
for (i = 0; i < SUGG_LIST_SIZE && item; i++, item = item->next) {
+ int len = txt_utf8_forward_columns(item->name, SUGG_LIST_WIDTH, NULL) - item->name;
y -= lheight;
- BLI_strncpy(str, item->name, SUGG_LIST_WIDTH);
+ BLI_strncpy(str, item->name, len + 1);
- w = BLF_width(mono, str);
+ w = st->cwidth * text_get_char_pos(st, str, len);
if (item == sel) {
UI_ThemeColor(TH_SHADE2);
@@ -1016,7 +1052,7 @@ static void draw_suggestion_list(SpaceText *st, ARegion *ar)
}
format_draw_color(item->type);
- text_draw(st, str, 0, 0, 1, x + margin_x, y - 1, NULL);
+ text_draw(st, str, 0, 0, x + margin_x, y - 1, NULL);
if (item == last) break;
}
@@ -1378,7 +1414,7 @@ void draw_text_main(SpaceText *st, ARegion *ar)
}
else {
/* draw unwrapped text */
- text_draw(st, tmp->line, st->left, ar->winx / st->cwidth, 1, x, y, tmp->format);
+ text_draw(st, tmp->line, st->left, ar->winx / st->cwidth, x, y, tmp->format);
y -= st->lheight_dpi + TXT_LINE_SPACING;
}
@@ -1435,8 +1471,6 @@ void text_scroll_to_cursor(SpaceText *st, ScrArea *sa)
winx = ar->winx;
break;
}
-
- winx -= TXT_SCROLL_WIDTH;
text_update_character_width(st);
@@ -1454,10 +1488,11 @@ void text_scroll_to_cursor(SpaceText *st, ScrArea *sa)
st->left = 0;
}
else {
- x = text_draw(st, text->sell->line, st->left, text->selc, 0, 0, 0, NULL);
+ x = st->cwidth * (text_get_char_pos(st, text->sell->line, text->selc) - st->left);
+ winx -= TXT_OFFSET + (st->showlinenrs ? TEXTXLOC : 0) + TXT_SCROLL_WIDTH;
- if (x == 0 || x > winx)
- st->left = text->curc - 0.5 * winx / st->cwidth;
+ if (x <= 0 || x > winx)
+ st->left += (x - winx / 2) / st->cwidth;
}
if (st->top < 0) st->top = 0;
diff --git a/source/blender/editors/space_text/text_format.c b/source/blender/editors/space_text/text_format.c
index 3c7897200ed..b29c6420d60 100644
--- a/source/blender/editors/space_text/text_format.c
+++ b/source/blender/editors/space_text/text_format.c
@@ -144,7 +144,7 @@ int text_check_format_len(TextLine *line, unsigned int len)
* Fill the string with formatting constant,
* advancing \a str_p and \a fmt_p
*
- * \param len length in bytes
+ * \param len length in bytes of \a fmt_p to fill.
*/
void text_format_fill(const char **str_p, char **fmt_p, const char type, const int len)
{
diff --git a/source/blender/editors/space_text/text_format_lua.c b/source/blender/editors/space_text/text_format_lua.c
index 6c72e043930..f74d1cf8e8b 100644
--- a/source/blender/editors/space_text/text_format_lua.c
+++ b/source/blender/editors/space_text/text_format_lua.c
@@ -237,7 +237,7 @@ static void txtfmt_lua_format_line(SpaceText *st, TextLine *line, const int do_n
}
/* Single line comment */
else if (*str == '-' && *(str + 1) == '-') {
- text_format_fill(&str, &fmt, FMT_TYPE_COMMENT, len - (int)(str - fs.buf));
+ text_format_fill(&str, &fmt, FMT_TYPE_COMMENT, len - (int)(fmt - line->format));
}
else if (*str == '"' || *str == '\'') {
/* Strings */
diff --git a/source/blender/editors/space_text/text_format_osl.c b/source/blender/editors/space_text/text_format_osl.c
index 7d493eb1f62..c95929a720f 100644
--- a/source/blender/editors/space_text/text_format_osl.c
+++ b/source/blender/editors/space_text/text_format_osl.c
@@ -141,10 +141,10 @@ static int txtfmt_osl_find_specialvar(const char *string)
int i, len;
/* OSL shader types */
- if (STR_LITERAL_STARTSWITH(string, "shader", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "surface", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "volume", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "displacement", len)) i = len;
+ if (STR_LITERAL_STARTSWITH(string, "shader", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "surface", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "volume", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "displacement", len)) i = len;
else i = 0;
/* If next source char is an identifier (eg. 'i' in "definate") no match */
@@ -252,7 +252,7 @@ static void txtfmt_osl_format_line(SpaceText *st, TextLine *line, const int do_n
/* Deal with comments first */
if (*str == '/' && *(str + 1) == '/') {
/* fill the remaining line */
- text_format_fill(&str, &fmt, FMT_TYPE_COMMENT, len - (int)(str - fs.buf));
+ text_format_fill(&str, &fmt, FMT_TYPE_COMMENT, len - (int)(fmt - line->format));
}
/* C-Style (multi-line) comments */
else if (*str == '/' && *(str + 1) == '*') {
diff --git a/source/blender/editors/space_text/text_format_py.c b/source/blender/editors/space_text/text_format_py.c
index 902d60dcb3e..9562d57041f 100644
--- a/source/blender/editors/space_text/text_format_py.c
+++ b/source/blender/editors/space_text/text_format_py.c
@@ -233,7 +233,7 @@ static void txtfmt_py_format_line(SpaceText *st, TextLine *line, const int do_ne
/* Deal with comments first */
if (*str == '#') {
/* fill the remaining line */
- text_format_fill(&str, &fmt, FMT_TYPE_COMMENT, len - (int)(str - fs.buf));
+ text_format_fill(&str, &fmt, FMT_TYPE_COMMENT, len - (int)(fmt - line->format));
}
else if (*str == '"' || *str == '\'') {
/* Strings */
diff --git a/source/blender/editors/space_text/text_ops.c b/source/blender/editors/space_text/text_ops.c
index b45961bff11..cdbb3e7c600 100644
--- a/source/blender/editors/space_text/text_ops.c
+++ b/source/blender/editors/space_text/text_ops.c
@@ -72,7 +72,7 @@
/************************ poll ***************************/
-BLI_INLINE int text_pixel_x_to_index(SpaceText *st, const int x)
+BLI_INLINE int text_pixel_x_to_column(SpaceText *st, const int x)
{
/* add half the char width so mouse cursor selection is inbetween letters */
return (x + (st->cwidth / 2)) / st->cwidth;
@@ -278,7 +278,7 @@ static int text_open_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int text_open_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int text_open_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
Text *text = CTX_data_edit_text(C);
char *path = (text && text->name) ? text->name : G.main->name;
@@ -539,7 +539,7 @@ static int text_save_as_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int text_save_as_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int text_save_as_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
Text *text = CTX_data_edit_text(C);
char *str;
@@ -1011,7 +1011,7 @@ static int text_line_break_exec(bContext *C, wmOperator *UNUSED(op))
text_drawcache_tag_update(st, 0);
// double check tabs/spaces before splitting the line
- curts = setcurr_tab_spaces(text, space);
+ curts = txt_setcurr_tab_spaces(text, space);
txt_split_curline(text);
for (a = 0; a < curts; a++) {
@@ -1407,25 +1407,31 @@ static int text_get_cursor_rel(SpaceText *st, ARegion *ar, TextLine *linein, int
for (i = 0, j = 0; loop; j += BLI_str_utf8_size_safe(linein->line + j)) {
int chars;
+ int columns = BLI_str_utf8_char_width_safe(linein->line + j); /* = 1 for tab */
+
/* Mimic replacement of tabs */
ch = linein->line[j];
if (ch == '\t') {
chars = st->tabnumber - i % st->tabnumber;
ch = ' ';
}
- else chars = 1;
+ else {
+ chars = 1;
+ }
while (chars--) {
- if (rell == 0 && i - start == relc) {
+ if (rell == 0 && i - start <= relc && i + columns - start > relc) {
/* current position could be wrapped to next line */
/* this should be checked when end of current line would be reached */
selc = j;
found = 1;
}
- else if (i - end == relc) {
+ else if (i - end <= relc && i + columns - end > relc) {
curs = j;
}
- if (i - start >= max) {
+ if (i + columns - start > max) {
+ end = MIN2(end, i);
+
if (found) {
/* exact cursor position was found, check if it's */
/* still on needed line (hasn't been wrapped) */
@@ -1441,7 +1447,7 @@ static int text_get_cursor_rel(SpaceText *st, ARegion *ar, TextLine *linein, int
chop = 1;
rell--;
- if (rell == 0 && i - start >= relc) {
+ if (rell == 0 && i + columns - start > relc) {
selc = curs;
loop = 0;
break;
@@ -1458,7 +1464,7 @@ static int text_get_cursor_rel(SpaceText *st, ARegion *ar, TextLine *linein, int
break;
}
- if (rell == 0 && i - start >= relc) {
+ if (rell == 0 && i + columns - start > relc) {
selc = curs;
loop = 0;
break;
@@ -1467,7 +1473,7 @@ static int text_get_cursor_rel(SpaceText *st, ARegion *ar, TextLine *linein, int
endj = j;
chop = 0;
}
- i++;
+ i += columns;
}
}
@@ -1585,20 +1591,26 @@ static void txt_wrap_move_bol(SpaceText *st, ARegion *ar, short sel)
for (i = 0, j = 0; loop; j += BLI_str_utf8_size_safe((*linep)->line + j)) {
int chars;
+ int columns = BLI_str_utf8_char_width_safe((*linep)->line + j); /* = 1 for tab */
+
/* Mimic replacement of tabs */
ch = (*linep)->line[j];
if (ch == '\t') {
chars = st->tabnumber - i % st->tabnumber;
ch = ' ';
}
- else chars = 1;
+ else {
+ chars = 1;
+ }
while (chars--) {
- if (i - start >= max) {
+ if (i + columns - start > max) {
+ end = MIN2(end, i);
+
*charp = endj;
if (j >= oldc) {
- if (ch == '\0') *charp = txt_utf8_index_to_offset((*linep)->line, start);
+ if (ch == '\0') *charp = txt_utf8_column_to_offset((*linep)->line, start);
loop = 0;
break;
}
@@ -1611,7 +1623,7 @@ static void txt_wrap_move_bol(SpaceText *st, ARegion *ar, short sel)
}
else if (ch == ' ' || ch == '-' || ch == '\0') {
if (j >= oldc) {
- *charp = txt_utf8_index_to_offset((*linep)->line, start);
+ *charp = txt_utf8_column_to_offset((*linep)->line, start);
loop = 0;
break;
}
@@ -1620,7 +1632,7 @@ static void txt_wrap_move_bol(SpaceText *st, ARegion *ar, short sel)
endj = j + 1;
chop = 0;
}
- i++;
+ i += columns;
}
}
@@ -1651,16 +1663,22 @@ static void txt_wrap_move_eol(SpaceText *st, ARegion *ar, short sel)
for (i = 0, j = 0; loop; j += BLI_str_utf8_size_safe((*linep)->line + j)) {
int chars;
+ int columns = BLI_str_utf8_char_width_safe((*linep)->line + j); /* = 1 for tab */
+
/* Mimic replacement of tabs */
ch = (*linep)->line[j];
if (ch == '\t') {
chars = st->tabnumber - i % st->tabnumber;
ch = ' ';
}
- else chars = 1;
+ else {
+ chars = 1;
+ }
while (chars--) {
- if (i - start >= max) {
+ if (i + columns - start > max) {
+ end = MIN2(end, i);
+
if (chop) endj = BLI_str_prev_char_utf8((*linep)->line + j) - (*linep)->line;
if (endj >= oldc) {
@@ -1684,7 +1702,7 @@ static void txt_wrap_move_eol(SpaceText *st, ARegion *ar, short sel)
endj = j;
chop = 0;
}
- i++;
+ i += columns;
}
}
@@ -1716,7 +1734,9 @@ static void txt_wrap_move_up(SpaceText *st, ARegion *ar, short sel)
visible_lines = text_get_visible_lines(st, ar, (*linep)->line);
*charp = text_get_cursor_rel(st, ar, *linep, visible_lines - 1, col);
}
- else *charp = 0;
+ else {
+ *charp = 0;
+ }
}
if (!sel) txt_pop_sel(text);
@@ -1745,7 +1765,9 @@ static void txt_wrap_move_down(SpaceText *st, ARegion *ar, short sel)
*linep = (*linep)->next;
*charp = text_get_cursor_rel(st, ar, *linep, 0, col);
}
- else *charp = (*linep)->len;
+ else {
+ *charp = (*linep)->len;
+ }
}
if (!sel) txt_pop_sel(text);
@@ -1927,7 +1949,7 @@ static int text_jump_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int text_jump_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int text_jump_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
return WM_operator_props_dialog_popup(C, op, 10 * UI_UNIT_X, 5 * UI_UNIT_Y);
@@ -2085,7 +2107,7 @@ static int text_scroll_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static void text_scroll_apply(bContext *C, wmOperator *op, wmEvent *event)
+static void text_scroll_apply(bContext *C, wmOperator *op, const wmEvent *event)
{
SpaceText *st = CTX_wm_space_text(C);
ARegion *ar = CTX_wm_region(C);
@@ -2142,7 +2164,7 @@ static void scroll_exit(bContext *C, wmOperator *op)
MEM_freeN(op->customdata);
}
-static int text_scroll_modal(bContext *C, wmOperator *op, wmEvent *event)
+static int text_scroll_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
TextScroll *tsc = op->customdata;
SpaceText *st = CTX_wm_space_text(C);
@@ -2182,7 +2204,7 @@ static int text_scroll_cancel(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
-static int text_scroll_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int text_scroll_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
SpaceText *st = CTX_wm_space_text(C);
TextScroll *tsc;
@@ -2259,7 +2281,7 @@ static int text_region_scroll_poll(bContext *C)
return 1;
}
-static int text_scroll_bar_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int text_scroll_bar_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
SpaceText *st = CTX_wm_space_text(C);
ARegion *ar = CTX_wm_region(C);
@@ -2342,7 +2364,7 @@ typedef struct SetSelection {
short old[2];
} SetSelection;
-static int flatten_len(SpaceText *st, const char *str)
+static int flatten_width(SpaceText *st, const char *str)
{
int i, total = 0;
@@ -2350,20 +2372,30 @@ static int flatten_len(SpaceText *st, const char *str)
if (str[i] == '\t') {
total += st->tabnumber - total % st->tabnumber;
}
- else total++;
+ else {
+ total += BLI_str_utf8_char_width_safe(str + i);
+ }
}
return total;
}
-static int flatten_index_to_offset(SpaceText *st, const char *str, int index)
+static int flatten_column_to_offset(SpaceText *st, const char *str, int index)
{
- int i, j;
- for (i = 0, j = 0; i < index; j += BLI_str_utf8_size_safe(str + j))
+ int i = 0, j = 0, col;
+
+ while (*(str + j)) {
if (str[j] == '\t')
- i += st->tabnumber - i % st->tabnumber;
+ col = st->tabnumber - i % st->tabnumber;
else
- i++;
+ col = BLI_str_utf8_char_width_safe(str + j);
+
+ if (i + col > index)
+ break;
+
+ i += col;
+ j += BLI_str_utf8_size_safe(str + j);
+ }
return j;
}
@@ -2390,7 +2422,7 @@ static TextLine *get_first_visible_line(SpaceText *st, ARegion *ar, int *y)
static void text_cursor_set_to_pos_wrapped(SpaceText *st, ARegion *ar, int x, int y, int sel)
{
Text *text = st->text;
- int max = wrap_width(st, ar); /* view */
+ int max = wrap_width(st, ar); /* column */
int charp = -1; /* mem */
int loop = 1, found = 0; /* flags */
char ch;
@@ -2399,12 +2431,13 @@ static void text_cursor_set_to_pos_wrapped(SpaceText *st, ARegion *ar, int x, in
TextLine *linep = get_first_visible_line(st, ar, &y);
while (loop && linep) {
- int i = 0, start = 0, end = max; /* view */
+ int i = 0, start = 0, end = max; /* column */
int j = 0, curs = 0, endj = 0; /* mem */
int chop = 1; /* flags */
for (; loop; j += BLI_str_utf8_size_safe(linep->line + j)) {
int chars;
+ int columns = BLI_str_utf8_char_width_safe(linep->line + j); /* = 1 for tab */
/* Mimic replacement of tabs */
ch = linep->line[j];
@@ -2412,7 +2445,9 @@ static void text_cursor_set_to_pos_wrapped(SpaceText *st, ARegion *ar, int x, in
chars = st->tabnumber - i % st->tabnumber;
ch = ' ';
}
- else chars = 1;
+ else {
+ chars = 1;
+ }
while (chars--) {
/* Gone too far, go back to last wrap point */
@@ -2422,17 +2457,19 @@ static void text_cursor_set_to_pos_wrapped(SpaceText *st, ARegion *ar, int x, in
break;
/* Exactly at the cursor */
}
- else if (y == 0 && i - start == x) {
+ else if (y == 0 && i - start <= x && i + columns - start > x) {
/* current position could be wrapped to next line */
/* this should be checked when end of current line would be reached */
charp = curs = j;
found = 1;
/* Prepare curs for next wrap */
}
- else if (i - end == x) {
+ else if (i - end <= x && i + columns - end > x) {
curs = j;
}
- if (i - start >= max) {
+ if (i + columns - start > max) {
+ end = MIN2(end, i);
+
if (found) {
/* exact cursor position was found, check if it's */
/* still on needed line (hasn't been wrapped) */
@@ -2449,7 +2486,7 @@ static void text_cursor_set_to_pos_wrapped(SpaceText *st, ARegion *ar, int x, in
y--;
chop = 1;
- if (y == 0 && i - start >= x) {
+ if (y == 0 && i + columns - start > x) {
charp = curs;
loop = 0;
break;
@@ -2461,7 +2498,7 @@ static void text_cursor_set_to_pos_wrapped(SpaceText *st, ARegion *ar, int x, in
break;
}
- if (y == 0 && i - start >= x) {
+ if (y == 0 && i + columns - start > x) {
charp = curs;
loop = 0;
break;
@@ -2470,7 +2507,7 @@ static void text_cursor_set_to_pos_wrapped(SpaceText *st, ARegion *ar, int x, in
endj = j;
chop = 0;
}
- i++;
+ i += columns;
}
if (ch == '\0') break;
@@ -2509,7 +2546,7 @@ static void text_cursor_set_to_pos(SpaceText *st, ARegion *ar, int x, int y, int
else x -= TXT_OFFSET;
if (x < 0) x = 0;
- x = text_pixel_x_to_index(st, x) + st->left;
+ x = text_pixel_x_to_column(st, x) + st->left;
if (st->wordwrap) {
text_cursor_set_to_pos_wrapped(st, ar, x, y, sel);
@@ -2532,14 +2569,14 @@ static void text_cursor_set_to_pos(SpaceText *st, ARegion *ar, int x, int y, int
}
- w = flatten_len(st, (*linep)->line);
- if (x < w) *charp = flatten_index_to_offset(st, (*linep)->line, x);
+ w = flatten_width(st, (*linep)->line);
+ if (x < w) *charp = flatten_column_to_offset(st, (*linep)->line, x);
else *charp = (*linep)->len;
}
if (!sel) txt_pop_sel(text);
}
-static void text_cursor_set_apply(bContext *C, wmOperator *op, wmEvent *event)
+static void text_cursor_set_apply(bContext *C, wmOperator *op, const wmEvent *event)
{
SpaceText *st = CTX_wm_space_text(C);
ARegion *ar = CTX_wm_region(C);
@@ -2594,7 +2631,7 @@ static void text_cursor_set_exit(bContext *C, wmOperator *op)
MEM_freeN(ssel);
}
-static int text_set_selection_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int text_set_selection_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
SpaceText *st = CTX_wm_space_text(C);
SetSelection *ssel;
@@ -2619,7 +2656,7 @@ static int text_set_selection_invoke(bContext *C, wmOperator *op, wmEvent *event
return OPERATOR_RUNNING_MODAL;
}
-static int text_set_selection_modal(bContext *C, wmOperator *op, wmEvent *event)
+static int text_set_selection_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
switch (event->type) {
case LEFTMOUSE:
@@ -2675,7 +2712,7 @@ static int text_cursor_set_exec(bContext *C, wmOperator *op)
return OPERATOR_PASS_THROUGH;
}
-static int text_cursor_set_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int text_cursor_set_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
SpaceText *st = CTX_wm_space_text(C);
@@ -2707,7 +2744,7 @@ void TEXT_OT_cursor_set(wmOperatorType *ot)
/******************* line number operator **********************/
-static int text_line_number_invoke(bContext *C, wmOperator *UNUSED(op), wmEvent *event)
+static int text_line_number_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *event)
{
SpaceText *st = CTX_wm_space_text(C);
Text *text = CTX_data_edit_text(C);
@@ -2797,7 +2834,7 @@ static int text_insert_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int text_insert_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int text_insert_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
int ret;
@@ -3100,7 +3137,7 @@ static int text_resolve_conflict_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
-static int text_resolve_conflict_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int text_resolve_conflict_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
Text *text = CTX_data_edit_text(C);
uiPopupMenu *pup;
diff --git a/source/blender/editors/space_view3d/CMakeLists.txt b/source/blender/editors/space_view3d/CMakeLists.txt
index 462619a7e8b..a04371a5ed9 100644
--- a/source/blender/editors/space_view3d/CMakeLists.txt
+++ b/source/blender/editors/space_view3d/CMakeLists.txt
@@ -54,6 +54,7 @@ set(SRC
view3d_iterators.c
view3d_ops.c
view3d_project.c
+ view3d_ruler.c
view3d_select.c
view3d_snap.c
view3d_toolbar.c
diff --git a/source/blender/editors/space_view3d/drawmesh.c b/source/blender/editors/space_view3d/drawmesh.c
index 2cef10e1981..9000ccbf324 100644
--- a/source/blender/editors/space_view3d/drawmesh.c
+++ b/source/blender/editors/space_view3d/drawmesh.c
@@ -428,7 +428,9 @@ static DMDrawOption draw_tface__set_draw_legacy(MTFace *tface, int has_mcol, int
return DM_DRAW_OPTION_NO_MCOL; /* Don't set color */
}
else if (!has_mcol) {
- if (tface) glColor3f(1.0, 1.0, 1.0);
+ if (tface) {
+ glColor3f(1.0, 1.0, 1.0);
+ }
else {
if (ma) {
float col[3];
@@ -437,7 +439,9 @@ static DMDrawOption draw_tface__set_draw_legacy(MTFace *tface, int has_mcol, int
glColor3fv(col);
}
- else glColor3f(1.0, 1.0, 1.0);
+ else {
+ glColor3f(1.0, 1.0, 1.0);
+ }
}
return DM_DRAW_OPTION_NO_MCOL; /* Don't set color */
}
diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c
index 158b75c494a..743b53ce16c 100644
--- a/source/blender/editors/space_view3d/drawobject.c
+++ b/source/blender/editors/space_view3d/drawobject.c
@@ -615,7 +615,7 @@ static void draw_empty_image(Object *ob, const short dflag, const unsigned char
glColor4fv(ob->col);
/* Draw the Image on the screen */
- glaDrawPixelsTex(ofs_x, ofs_y, ima_x, ima_y, GL_UNSIGNED_BYTE, ibuf->rect);
+ glaDrawPixelsTex(ofs_x, ofs_y, ima_x, ima_y, GL_UNSIGNED_BYTE, GL_LINEAR, ibuf->rect);
glPixelTransferf(GL_ALPHA_SCALE, 1.0f);
glDisable(GL_BLEND);
@@ -812,17 +812,6 @@ void view3d_cached_text_draw_end(View3D *v3d, ARegion *ar, int depth_write, floa
}
for (vos = strings->first; vos; vos = vos->next) {
- /* too slow, reading opengl info while drawing is very bad,
- * better to see if we can use the zbuffer while in pixel space - campbell */
-#if 0
- if (v3d->zbuf && (vos->flag & V3D_CACHE_TEXT_ZBUF)) {
- gluProject(vos->vec[0], vos->vec[1], vos->vec[2], mats.modelview, mats.projection, (GLint *)mats.viewport, &ux, &uy, &uz);
- glReadPixels(ar->winrct.xmin + vos->mval[0] + vos->xoffs, ar->winrct.ymin + vos->mval[1], 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &depth);
-
- if (uz > depth)
- continue;
- }
-#endif
if (vos->sco[0] != IS_CLIPPED) {
const char *str = (char *)(vos + 1);
@@ -3862,7 +3851,7 @@ static int drawDispList(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *bas
if (v3d->flag2 & V3D_BACKFACE_CULLING) {
/* not all displists use same in/out normal direction convention */
glEnable(GL_CULL_FACE);
- glCullFace((base->object->type == OB_MBALL) ? GL_BACK : GL_FRONT);
+ glCullFace((base->object->type == OB_MBALL || base->object->derivedFinal) ? GL_BACK : GL_FRONT);
}
retval = drawDispList_nobackface(scene, v3d, rv3d, base, dt, dflag, ob_wire_col);
@@ -3968,7 +3957,9 @@ static void draw_particle(ParticleKey *state, int draw_as, short draw, float pix
if (draw_as == PART_DRAW_AXIS) {
copy_v3_v3(vec2, state->co);
}
- else sub_v3_v3v3(vec2, state->co, vec);
+ else {
+ sub_v3_v3v3(vec2, state->co, vec);
+ }
add_v3_v3(vec, state->co);
copy_v3_v3(pdd->vd, vec); pdd->vd += 3;
@@ -3980,7 +3971,9 @@ static void draw_particle(ParticleKey *state, int draw_as, short draw, float pix
if (draw_as == PART_DRAW_AXIS) {
copy_v3_v3(vec2, state->co);
}
- else sub_v3_v3v3(vec2, state->co, vec);
+ else {
+ sub_v3_v3v3(vec2, state->co, vec);
+ }
add_v3_v3(vec, state->co);
@@ -6055,8 +6048,10 @@ static void drawtexspace(Object *ob)
copy_v3_v3(size, mb->size);
copy_v3_v3(loc, mb->loc);
}
- else return;
-
+ else {
+ return;
+ }
+
vec[0][0] = vec[1][0] = vec[2][0] = vec[3][0] = loc[0] - size[0];
vec[4][0] = vec[5][0] = vec[6][0] = vec[7][0] = loc[0] + size[0];
diff --git a/source/blender/editors/space_view3d/space_view3d.c b/source/blender/editors/space_view3d/space_view3d.c
index 57755231240..d332fb9f8b3 100644
--- a/source/blender/editors/space_view3d/space_view3d.c
+++ b/source/blender/editors/space_view3d/space_view3d.c
@@ -48,10 +48,12 @@
#include "BKE_object.h"
#include "BKE_screen.h"
+#include "ED_render.h"
#include "ED_space_api.h"
#include "ED_screen.h"
#include "ED_object.h"
+#include "GPU_extensions.h"
#include "GPU_material.h"
#include "BIF_gl.h"
@@ -350,7 +352,7 @@ static void view3d_free(SpaceLink *sl)
/* spacetype; init callback */
-static void view3d_init(struct wmWindowManager *UNUSED(wm), ScrArea *UNUSED(sa))
+static void view3d_init(wmWindowManager *UNUSED(wm), ScrArea *UNUSED(sa))
{
}
@@ -469,7 +471,22 @@ static void view3d_main_area_init(wmWindowManager *wm, ARegion *ar)
}
-static int view3d_ob_drop_poll(bContext *UNUSED(C), wmDrag *drag, wmEvent *UNUSED(event))
+static void view3d_main_area_exit(wmWindowManager *UNUSED(wm), ARegion *ar)
+{
+ RegionView3D *rv3d = ar->regiondata;
+
+ if (rv3d->render_engine) {
+ RE_engine_free(rv3d->render_engine);
+ rv3d->render_engine = NULL;
+ }
+
+ if (rv3d->gpuoffscreen) {
+ GPU_offscreen_free(rv3d->gpuoffscreen);
+ rv3d->gpuoffscreen = NULL;
+ }
+}
+
+static int view3d_ob_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUSED(event))
{
if (drag->type == WM_DRAG_ID) {
ID *id = (ID *)drag->poin;
@@ -479,7 +496,7 @@ static int view3d_ob_drop_poll(bContext *UNUSED(C), wmDrag *drag, wmEvent *UNUSE
return 0;
}
-static int view3d_group_drop_poll(bContext *UNUSED(C), wmDrag *drag, wmEvent *UNUSED(event))
+static int view3d_group_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUSED(event))
{
if (drag->type == WM_DRAG_ID) {
ID *id = (ID *)drag->poin;
@@ -489,7 +506,7 @@ static int view3d_group_drop_poll(bContext *UNUSED(C), wmDrag *drag, wmEvent *UN
return 0;
}
-static int view3d_mat_drop_poll(bContext *UNUSED(C), wmDrag *drag, wmEvent *UNUSED(event))
+static int view3d_mat_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUSED(event))
{
if (drag->type == WM_DRAG_ID) {
ID *id = (ID *)drag->poin;
@@ -499,7 +516,7 @@ static int view3d_mat_drop_poll(bContext *UNUSED(C), wmDrag *drag, wmEvent *UNUS
return 0;
}
-static int view3d_ima_drop_poll(bContext *UNUSED(C), wmDrag *drag, wmEvent *UNUSED(event))
+static int view3d_ima_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUSED(event))
{
if (drag->type == WM_DRAG_ID) {
ID *id = (ID *)drag->poin;
@@ -513,7 +530,7 @@ static int view3d_ima_drop_poll(bContext *UNUSED(C), wmDrag *drag, wmEvent *UNUS
return 0;
}
-static int view3d_ima_bg_drop_poll(bContext *C, wmDrag *drag, wmEvent *event)
+static int view3d_ima_bg_drop_poll(bContext *C, wmDrag *drag, const wmEvent *event)
{
if (event->ctrl)
return false;
@@ -524,7 +541,7 @@ static int view3d_ima_bg_drop_poll(bContext *C, wmDrag *drag, wmEvent *event)
return 0;
}
-static int view3d_ima_empty_drop_poll(bContext *C, wmDrag *drag, wmEvent *event)
+static int view3d_ima_empty_drop_poll(bContext *C, wmDrag *drag, const wmEvent *event)
{
Base *base = ED_view3d_give_base_under_cursor(C, event->mval);
@@ -535,7 +552,7 @@ static int view3d_ima_empty_drop_poll(bContext *C, wmDrag *drag, wmEvent *event)
return 0;
}
-static int view3d_ima_mesh_drop_poll(bContext *C, wmDrag *drag, wmEvent *event)
+static int view3d_ima_mesh_drop_poll(bContext *C, wmDrag *drag, const wmEvent *event)
{
Base *base = ED_view3d_give_base_under_cursor(C, event->mval);
@@ -615,6 +632,10 @@ static void view3d_main_area_free(ARegion *ar)
if (rv3d->sms) {
MEM_freeN(rv3d->sms);
}
+ if (rv3d->gpuoffscreen) {
+ GPU_offscreen_free(rv3d->gpuoffscreen);
+ }
+
MEM_freeN(rv3d);
ar->regiondata = NULL;
}
@@ -633,6 +654,7 @@ static void *view3d_main_area_duplicate(void *poin)
new->clipbb = MEM_dupallocN(rv3d->clipbb);
new->depths = NULL;
+ new->gpuoffscreen = NULL;
new->ri = NULL;
new->render_engine = NULL;
new->gpd = NULL;
@@ -1216,6 +1238,7 @@ void ED_spacetype_view3d(void)
art->keymapflag = ED_KEYMAP_GPENCIL;
art->draw = view3d_main_area_draw;
art->init = view3d_main_area_init;
+ art->exit = view3d_main_area_exit;
art->free = view3d_main_area_free;
art->duplicate = view3d_main_area_duplicate;
art->listener = view3d_main_area_listener;
diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c
index 4aaa3332252..8fdc9416513 100644
--- a/source/blender/editors/space_view3d/view3d_draw.c
+++ b/source/blender/editors/space_view3d/view3d_draw.c
@@ -219,15 +219,12 @@ void ED_view3d_clipping_enable(void)
}
}
-static int view3d_clipping_test(const float vec[3], float clip[6][4])
+static int view3d_clipping_test(const float co[3], float clip[6][4])
{
- float view[3];
- copy_v3_v3(view, vec);
-
- if (0.0f < clip[0][3] + dot_v3v3(view, clip[0]))
- if (0.0f < clip[1][3] + dot_v3v3(view, clip[1]))
- if (0.0f < clip[2][3] + dot_v3v3(view, clip[2]))
- if (0.0f < clip[3][3] + dot_v3v3(view, clip[3]))
+ if (0.0f < clip[0][3] + dot_v3v3(co, clip[0]))
+ if (0.0f < clip[1][3] + dot_v3v3(co, clip[1]))
+ if (0.0f < clip[2][3] + dot_v3v3(co, clip[2]))
+ if (0.0f < clip[3][3] + dot_v3v3(co, clip[3]))
return 0;
return 1;
@@ -235,9 +232,9 @@ static int view3d_clipping_test(const float vec[3], float clip[6][4])
/* for 'local' ED_view3d_clipping_local must run first
* then all comparisons can be done in localspace */
-int ED_view3d_clipping_test(RegionView3D *rv3d, const float vec[3], const int is_local)
+int ED_view3d_clipping_test(RegionView3D *rv3d, const float co[3], const bool is_local)
{
- return view3d_clipping_test(vec, is_local ? rv3d->clip_local : rv3d->clip);
+ return view3d_clipping_test(co, is_local ? rv3d->clip_local : rv3d->clip);
}
/* ********* end custom clipping *********** */
@@ -971,7 +968,7 @@ static void draw_selected_name(Scene *scene, Object *ob, rcti *rect)
}
static void view3d_camera_border(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D *rv3d,
- rctf *viewborder_r, short no_shift, short no_zoom)
+ rctf *r_viewborder, const bool no_shift, const bool no_zoom)
{
CameraParams params;
rctf rect_view, rect_camera;
@@ -995,25 +992,25 @@ static void view3d_camera_border(Scene *scene, ARegion *ar, View3D *v3d, RegionV
rect_camera = params.viewplane;
/* get camera border within viewport */
- viewborder_r->xmin = ((rect_camera.xmin - rect_view.xmin) / BLI_rctf_size_x(&rect_view)) * ar->winx;
- viewborder_r->xmax = ((rect_camera.xmax - rect_view.xmin) / BLI_rctf_size_x(&rect_view)) * ar->winx;
- viewborder_r->ymin = ((rect_camera.ymin - rect_view.ymin) / BLI_rctf_size_y(&rect_view)) * ar->winy;
- viewborder_r->ymax = ((rect_camera.ymax - rect_view.ymin) / BLI_rctf_size_y(&rect_view)) * ar->winy;
+ r_viewborder->xmin = ((rect_camera.xmin - rect_view.xmin) / BLI_rctf_size_x(&rect_view)) * ar->winx;
+ r_viewborder->xmax = ((rect_camera.xmax - rect_view.xmin) / BLI_rctf_size_x(&rect_view)) * ar->winx;
+ r_viewborder->ymin = ((rect_camera.ymin - rect_view.ymin) / BLI_rctf_size_y(&rect_view)) * ar->winy;
+ r_viewborder->ymax = ((rect_camera.ymax - rect_view.ymin) / BLI_rctf_size_y(&rect_view)) * ar->winy;
}
-void ED_view3d_calc_camera_border_size(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D *rv3d, float size_r[2])
+void ED_view3d_calc_camera_border_size(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D *rv3d, float r_size[2])
{
rctf viewborder;
view3d_camera_border(scene, ar, v3d, rv3d, &viewborder, TRUE, TRUE);
- size_r[0] = BLI_rctf_size_x(&viewborder);
- size_r[1] = BLI_rctf_size_y(&viewborder);
+ r_size[0] = BLI_rctf_size_x(&viewborder);
+ r_size[1] = BLI_rctf_size_y(&viewborder);
}
void ED_view3d_calc_camera_border(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D *rv3d,
- rctf *viewborder_r, short no_shift)
+ rctf *viewborder_r, const bool no_shift)
{
- view3d_camera_border(scene, ar, v3d, rv3d, viewborder_r, no_shift, FALSE);
+ view3d_camera_border(scene, ar, v3d, rv3d, viewborder_r, no_shift, false);
}
static void drawviewborder_grid3(float x1, float x2, float y1, float y2, float fac)
@@ -1316,11 +1313,6 @@ static void backdrawview3d(Scene *scene, ARegion *ar, View3D *v3d)
{
/* do nothing */
}
- else if ((base && (base->object->mode & OB_MODE_TEXTURE_PAINT)) &&
- scene->toolsettings && (scene->toolsettings->imapaint.flag & IMAGEPAINT_PROJECT_DISABLE))
- {
- /* do nothing */
- }
else if ((base && (base->object->mode & OB_MODE_PARTICLE_EDIT)) &&
v3d->drawtype > OB_WIRE && (v3d->flag & V3D_ZBUF_SELECT))
{
@@ -1356,7 +1348,35 @@ static void backdrawview3d(Scene *scene, ARegion *ar, View3D *v3d)
if (multisample_enabled)
glDisable(GL_MULTISAMPLE_ARB);
- glScissor(ar->winrct.xmin, ar->winrct.ymin, BLI_rcti_size_x(&ar->winrct), BLI_rcti_size_y(&ar->winrct));
+ if (U.ogl_multisamples != USER_MULTISAMPLE_NONE) {
+ /* for multisample we use an offscreen FBO. multisample drawing can fail
+ * with color coded selection drawing, and reading back depths from such
+ * a buffer can also cause a few seconds freeze on OS X / NVidia. */
+ int w = BLI_rcti_size_x(&ar->winrct);
+ int h = BLI_rcti_size_y(&ar->winrct);
+ char error[256];
+
+ if (rv3d->gpuoffscreen) {
+ if (GPU_offscreen_width(rv3d->gpuoffscreen) != w ||
+ GPU_offscreen_height(rv3d->gpuoffscreen) != h)
+ {
+ GPU_offscreen_free(rv3d->gpuoffscreen);
+ rv3d->gpuoffscreen = NULL;
+ }
+ }
+
+ if (!rv3d->gpuoffscreen) {
+ rv3d->gpuoffscreen = GPU_offscreen_create(w, h, error);
+
+ if (!rv3d->gpuoffscreen)
+ fprintf(stderr, "Failed to create offscreen selection buffer for multisample: %s\n", error);
+ }
+ }
+
+ if (rv3d->gpuoffscreen)
+ GPU_offscreen_bind(rv3d->gpuoffscreen);
+ else
+ 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) {
@@ -1375,9 +1395,13 @@ static void backdrawview3d(Scene *scene, ARegion *ar, View3D *v3d)
if (base && (base->lay & v3d->lay))
draw_object_backbufsel(scene, v3d, rv3d, base->object);
+
+ if (rv3d->gpuoffscreen)
+ GPU_offscreen_unbind(rv3d->gpuoffscreen);
+ else
+ ar->swap = 0; /* mark invalid backbuf for wm draw */
v3d->flag &= ~V3D_INVALID_BACKBUF;
- ar->swap = 0; /* mark invalid backbuf for wm draw */
G.f &= ~G_BACKBUFSEL;
v3d->zbuf = FALSE;
@@ -1394,6 +1418,21 @@ static void backdrawview3d(Scene *scene, ARegion *ar, View3D *v3d)
}
+void view3d_opengl_read_pixels(ARegion *ar, int x, int y, int w, int h, int format, int type, void *data)
+{
+ RegionView3D *rv3d = ar->regiondata;
+
+ if (rv3d->gpuoffscreen) {
+ GPU_offscreen_bind(rv3d->gpuoffscreen);
+ glReadBuffer(GL_COLOR_ATTACHMENT0_EXT);
+ glReadPixels(x, y, w, h, format, type, data);
+ GPU_offscreen_unbind(rv3d->gpuoffscreen);
+ }
+ else {
+ glReadPixels(ar->winrct.xmin + x, ar->winrct.ymin + y, w, h, format, type, data);
+ }
+}
+
void view3d_validate_backbuf(ViewContext *vc)
{
if (vc->v3d->flag & V3D_INVALID_BACKBUF)
@@ -1409,12 +1448,9 @@ unsigned int view3d_sample_backbuf(ViewContext *vc, int x, int y)
return 0;
}
- x += vc->ar->winrct.xmin;
- y += vc->ar->winrct.ymin;
-
view3d_validate_backbuf(vc);
- glReadPixels(x, y, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &col);
+ view3d_opengl_read_pixels(vc->ar, x, y, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &col);
glReadBuffer(GL_BACK);
if (ENDIAN_ORDER == B_ENDIAN) {
@@ -1445,8 +1481,8 @@ ImBuf *view3d_read_backbuf(ViewContext *vc, short xmin, short ymin, short xmax,
view3d_validate_backbuf(vc);
- glReadPixels(vc->ar->winrct.xmin + xminc,
- vc->ar->winrct.ymin + yminc,
+ view3d_opengl_read_pixels(vc->ar,
+ xminc, yminc,
(xmaxc - xminc + 1),
(ymaxc - yminc + 1),
GL_RGBA, GL_UNSIGNED_BYTE, ibuf->rect);
@@ -1573,7 +1609,7 @@ static void view3d_draw_bgpic(Scene *scene, ARegion *ar, View3D *v3d,
float fac, asp, zoomx, zoomy;
float x1, y1, x2, y2;
- ImBuf *ibuf = NULL, *freeibuf;
+ ImBuf *ibuf = NULL, *freeibuf, *releaseibuf;
Image *ima;
MovieClip *clip;
@@ -1583,6 +1619,7 @@ static void view3d_draw_bgpic(Scene *scene, ARegion *ar, View3D *v3d,
continue;
freeibuf = NULL;
+ releaseibuf = NULL;
if (bgpic->source == V3D_BGPIC_IMAGE) {
ima = bgpic->ima;
if (ima == NULL)
@@ -1593,7 +1630,7 @@ static void view3d_draw_bgpic(Scene *scene, ARegion *ar, View3D *v3d,
}
else {
ibuf = BKE_image_acquire_ibuf(ima, &bgpic->iuser, NULL);
- freeibuf = ibuf;
+ releaseibuf = ibuf;
}
image_aspect[0] = ima->aspx;
@@ -1608,7 +1645,9 @@ static void view3d_draw_bgpic(Scene *scene, ARegion *ar, View3D *v3d,
if (scene->camera)
clip = BKE_object_movieclip_get(scene, scene->camera, 1);
}
- else clip = bgpic->clip;
+ else {
+ clip = bgpic->clip;
+ }
if (clip == NULL)
continue;
@@ -1636,6 +1675,8 @@ static void view3d_draw_bgpic(Scene *scene, ARegion *ar, View3D *v3d,
if ((ibuf->rect == NULL && ibuf->rect_float == NULL) || ibuf->channels != 4) { /* invalid image format */
if (freeibuf)
IMB_freeImBuf(freeibuf);
+ if (releaseibuf)
+ BKE_image_release_ibuf(ima, releaseibuf, NULL);
continue;
}
@@ -1708,10 +1749,12 @@ static void view3d_draw_bgpic(Scene *scene, ARegion *ar, View3D *v3d,
float tvec[3];
float sco[2];
const float mval_f[2] = {1.0f, 0.0f};
+ const float co_zero[3] = {0};
+ float zfac;
/* calc window coord */
- initgrabz(rv3d, 0.0, 0.0, 0.0);
- ED_view3d_win_to_delta(ar, mval_f, tvec);
+ zfac = ED_view3d_calc_zfac(rv3d, co_zero, NULL);
+ ED_view3d_win_to_delta(ar, mval_f, tvec, zfac);
fac = max_ff(fabsf(tvec[0]), max_ff(fabsf(tvec[1]), fabsf(tvec[2]))); /* largest abs axis */
fac = 1.0f / fac;
@@ -1731,6 +1774,8 @@ static void view3d_draw_bgpic(Scene *scene, ARegion *ar, View3D *v3d,
if (x2 < 0 || y2 < 0 || x1 > ar->winx || y1 > ar->winy) {
if (freeibuf)
IMB_freeImBuf(freeibuf);
+ if (releaseibuf)
+ BKE_image_release_ibuf(ima, releaseibuf, NULL);
continue;
}
@@ -1774,7 +1819,7 @@ static void view3d_draw_bgpic(Scene *scene, ARegion *ar, View3D *v3d,
glPixelZoom(zoomx, zoomy);
glColor4f(1.0f, 1.0f, 1.0f, 1.0f - bgpic->blend);
- glaDrawPixelsTex(x1, y1, ibuf->x, ibuf->y, GL_UNSIGNED_BYTE, ibuf->rect);
+ glaDrawPixelsAuto(x1, y1, ibuf->x, ibuf->y, GL_UNSIGNED_BYTE, GL_LINEAR, ibuf->rect);
glPixelZoom(1.0, 1.0);
glPixelTransferf(GL_ALPHA_SCALE, 1.0f);
@@ -1789,9 +1834,10 @@ static void view3d_draw_bgpic(Scene *scene, ARegion *ar, View3D *v3d,
glDepthMask(1);
if (v3d->zbuf) glEnable(GL_DEPTH_TEST);
- if (freeibuf) {
+ if (freeibuf)
IMB_freeImBuf(freeibuf);
- }
+ if (releaseibuf)
+ BKE_image_release_ibuf(ima, releaseibuf, NULL);
}
}
}
@@ -2102,7 +2148,7 @@ void view3d_update_depths_rect(ARegion *ar, ViewDepths *d, rcti *rect)
}
if (d->damaged) {
- glReadPixels(ar->winrct.xmin + d->x, ar->winrct.ymin + d->y, d->w, d->h, GL_DEPTH_COMPONENT, GL_FLOAT, d->depths);
+ view3d_opengl_read_pixels(ar, d->x, d->y, d->w, d->h, GL_DEPTH_COMPONENT, GL_FLOAT, d->depths);
glGetDoublev(GL_DEPTH_RANGE, d->depth_range);
d->damaged = FALSE;
}
@@ -2130,9 +2176,7 @@ void ED_view3d_depth_update(ARegion *ar)
}
if (d->damaged) {
- glReadPixels(ar->winrct.xmin, ar->winrct.ymin, d->w, d->h,
- GL_DEPTH_COMPONENT, GL_FLOAT, d->depths);
-
+ view3d_opengl_read_pixels(ar, 0, 0, d->w, d->h, GL_DEPTH_COMPONENT, GL_FLOAT, d->depths);
glGetDoublev(GL_DEPTH_RANGE, d->depth_range);
d->damaged = 0;
@@ -2999,7 +3043,7 @@ static void view3d_main_area_clear(Scene *scene, View3D *v3d, ARegion *ar)
#define VIEWGRAD_RES_Y 16
GLubyte grid_col[VIEWGRAD_RES_X][VIEWGRAD_RES_Y][4];
- static float grid_pos[VIEWGRAD_RES_X][VIEWGRAD_RES_Y][2];
+ static float grid_pos[VIEWGRAD_RES_X][VIEWGRAD_RES_Y][3];
static GLushort indices[VIEWGRAD_RES_X - 1][VIEWGRAD_RES_X - 1][4];
static char buf_calculated = FALSE;
@@ -3008,8 +3052,6 @@ static void view3d_main_area_clear(Scene *scene, View3D *v3d, ARegion *ar)
IMB_colormanagement_pixel_to_display_space_v3(col_zen, &scene->world->zenr, &scene->view_settings,
&scene->display_settings);
- glClear(GL_DEPTH_BUFFER_BIT);
-
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
@@ -3029,6 +3071,7 @@ static void view3d_main_area_clear(Scene *scene, View3D *v3d, ARegion *ar)
/* -1..1 range */
grid_pos[x][y][0] = (xf - 0.5f) * 2.0f;
grid_pos[x][y][1] = (yf - 0.5f) * 2.0f;
+ grid_pos[x][y][2] = 1.0;
}
}
@@ -3082,15 +3125,22 @@ static void view3d_main_area_clear(Scene *scene, View3D *v3d, ARegion *ar)
}
}
+ glEnable(GL_DEPTH_TEST);
+ glDepthFunc(GL_ALWAYS);
+
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);
- glVertexPointer(2, GL_FLOAT, 0, grid_pos);
+ glVertexPointer(3, GL_FLOAT, 0, grid_pos);
glColorPointer(4, GL_UNSIGNED_BYTE, 0, grid_col);
glDrawElements(GL_QUADS, (VIEWGRAD_RES_X - 1) * (VIEWGRAD_RES_Y - 1) * 4, GL_UNSIGNED_SHORT, indices);
+
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_COLOR_ARRAY);
+ glDepthFunc(GL_LEQUAL);
+ glDisable(GL_DEPTH_TEST);
+
glMatrixMode(GL_PROJECTION);
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
@@ -3112,9 +3162,6 @@ static void view3d_main_area_clear(Scene *scene, View3D *v3d, ARegion *ar)
}
else {
if (UI_GetThemeValue(TH_SHOW_BACK_GRAD)) {
- /* only clear depth buffer here */
- glClear(GL_DEPTH_BUFFER_BIT);
-
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
@@ -3122,17 +3169,22 @@ static void view3d_main_area_clear(Scene *scene, View3D *v3d, ARegion *ar)
glPushMatrix();
glLoadIdentity();
+ glEnable(GL_DEPTH_TEST);
+ glDepthFunc(GL_ALWAYS);
glShadeModel(GL_SMOOTH);
glBegin(GL_QUADS);
UI_ThemeColor(TH_LOW_GRAD);
- glVertex2f(-1.0, -1.0);
- glVertex2f(1.0, -1.0);
+ glVertex3f(-1.0, -1.0, 1.0);
+ glVertex3f(1.0, -1.0, 1.0);
UI_ThemeColor(TH_HIGH_GRAD);
- glVertex2f(1.0, 1.0);
- glVertex2f(-1.0, 1.0);
+ glVertex3f(1.0, 1.0, 1.0);
+ glVertex3f(-1.0, 1.0, 1.0);
glEnd();
glShadeModel(GL_FLAT);
+ glDepthFunc(GL_LEQUAL);
+ glDisable(GL_DEPTH_TEST);
+
glMatrixMode(GL_PROJECTION);
glPopMatrix();
diff --git a/source/blender/editors/space_view3d/view3d_edit.c b/source/blender/editors/space_view3d/view3d_edit.c
index 5f54f0dcfc8..8c8332075a2 100644
--- a/source/blender/editors/space_view3d/view3d_edit.c
+++ b/source/blender/editors/space_view3d/view3d_edit.c
@@ -368,6 +368,7 @@ typedef struct ViewOpsData {
float reverse, dist0, camzoom0;
float grid, far;
short axis_snap; /* view rotate only */
+ float zfac;
/* use for orbit selection and auto-dist */
float ofs[3], dyn_ofs[3];
@@ -407,7 +408,7 @@ static void calctrackballvec(const rcti *rect, int mx, int my, float vec[3])
}
-static void viewops_data_create(bContext *C, wmOperator *op, wmEvent *event)
+static void viewops_data_create(bContext *C, wmOperator *op, const wmEvent *event)
{
static float lastofs[3] = {0, 0, 0};
RegionView3D *rv3d;
@@ -504,7 +505,11 @@ static void viewops_data_create(bContext *C, wmOperator *op, wmEvent *event)
calctrackballvec(&vod->ar->winrct, event->x, event->y, vod->trackvec);
- initgrabz(rv3d, -rv3d->ofs[0], -rv3d->ofs[1], -rv3d->ofs[2]);
+ {
+ float tvec[3];
+ negate_v3_v3(tvec, rv3d->ofs);
+ vod->zfac = ED_view3d_calc_zfac(rv3d, tvec, NULL);
+ }
vod->reverse = 1.0f;
if (rv3d->persmat[2][1] < 0.0f)
@@ -836,7 +841,7 @@ static void viewrotate_apply(ViewOpsData *vod, int x, int y)
ED_region_tag_redraw(vod->ar);
}
-static int viewrotate_modal(bContext *C, wmOperator *op, wmEvent *event)
+static int viewrotate_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
ViewOpsData *vod = op->customdata;
short event_code = VIEW_PASS;
@@ -885,7 +890,7 @@ static int viewrotate_modal(bContext *C, wmOperator *op, wmEvent *event)
return OPERATOR_RUNNING_MODAL;
}
-static int viewrotate_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int viewrotate_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
ViewOpsData *vod;
RegionView3D *rv3d;
@@ -1092,7 +1097,7 @@ static void view3d_ndof_orbit(const struct wmNDOFMotionData *ndof, RegionView3D
* -- zooming
* -- panning in rotationally-locked views
*/
-static int ndof_orbit_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int ndof_orbit_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
if (event->type != NDOF_MOTION)
@@ -1174,7 +1179,7 @@ void VIEW3D_OT_ndof_orbit(struct wmOperatorType *ot)
}
-static int ndof_orbit_zoom_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int ndof_orbit_zoom_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
if (event->type != NDOF_MOTION)
@@ -1272,7 +1277,7 @@ void VIEW3D_OT_ndof_orbit_zoom(struct wmOperatorType *ot)
/* -- "pan" navigation
* -- zoom or dolly?
*/
-static int ndof_pan_invoke(bContext *C, wmOperator *UNUSED(op), wmEvent *event)
+static int ndof_pan_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *event)
{
if (event->type != NDOF_MOTION)
return OPERATOR_CANCELLED;
@@ -1366,7 +1371,7 @@ void VIEW3D_OT_ndof_pan(struct wmOperatorType *ot)
/*
* this is basically just the pan only code + the rotate only code crammed into one function that does both
*/
-static int ndof_all_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int ndof_all_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
if (event->type != NDOF_MOTION) {
return OPERATOR_CANCELLED;
@@ -1508,7 +1513,7 @@ static void viewmove_apply(ViewOpsData *vod, int x, int y)
mval_f[0] = x - vod->oldx;
mval_f[1] = y - vod->oldy;
- ED_view3d_win_to_delta(vod->ar, mval_f, dvec);
+ ED_view3d_win_to_delta(vod->ar, mval_f, dvec, vod->zfac);
add_v3_v3(vod->rv3d->ofs, dvec);
@@ -1525,7 +1530,7 @@ static void viewmove_apply(ViewOpsData *vod, int x, int y)
}
-static int viewmove_modal(bContext *C, wmOperator *op, wmEvent *event)
+static int viewmove_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
ViewOpsData *vod = op->customdata;
@@ -1568,7 +1573,7 @@ static int viewmove_modal(bContext *C, wmOperator *op, wmEvent *event)
return OPERATOR_RUNNING_MODAL;
}
-static int viewmove_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int viewmove_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
ViewOpsData *vod;
@@ -1665,15 +1670,16 @@ static void view_zoom_mouseloc(ARegion *ar, float dfac, int mx, int my)
float tpos[3];
float mval_f[2];
float new_dist;
+ float zfac;
negate_v3_v3(tpos, rv3d->ofs);
- /* Project cursor position into 3D space */
- initgrabz(rv3d, tpos[0], tpos[1], tpos[2]);
-
mval_f[0] = (float)(((mx - ar->winrct.xmin) * 2) - ar->winx) / 2.0f;
mval_f[1] = (float)(((my - ar->winrct.ymin) * 2) - ar->winy) / 2.0f;
- ED_view3d_win_to_delta(ar, mval_f, dvec);
+
+ /* Project cursor position into 3D space */
+ zfac = ED_view3d_calc_zfac(rv3d, tpos, NULL);
+ ED_view3d_win_to_delta(ar, mval_f, dvec, zfac);
/* Calculate view target position for dolly */
add_v3_v3v3(tvec, tpos, dvec);
@@ -1788,7 +1794,7 @@ static void viewzoom_apply(ViewOpsData *vod, const int x, const int y, const sho
}
-static int viewzoom_modal(bContext *C, wmOperator *op, wmEvent *event)
+static int viewzoom_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
ViewOpsData *vod = op->customdata;
short event_code = VIEW_PASS;
@@ -1933,7 +1939,7 @@ void viewdolly_modal_keymap(wmKeyConfig *keyconf)
}
/* viewdolly_invoke() copied this function, changes here may apply there */
-static int viewzoom_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int viewzoom_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
ViewOpsData *vod;
@@ -2053,7 +2059,7 @@ static void viewdolly_apply(ViewOpsData *vod, int x, int y, const short zoom_inv
}
-static int viewdolly_modal(bContext *C, wmOperator *op, wmEvent *event)
+static int viewdolly_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
ViewOpsData *vod = op->customdata;
short event_code = VIEW_PASS;
@@ -2145,7 +2151,7 @@ static int viewdolly_exec(bContext *C, wmOperator *op)
}
/* copied from viewzoom_invoke(), changes here may apply there */
-static int viewdolly_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int viewdolly_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
ViewOpsData *vod;
@@ -2957,14 +2963,20 @@ static int view3d_zoom_border_exec(bContext *C, wmOperator *op)
}
else {
float mval_f[2];
+ float zfac;
+
/* We cant use the depth, fallback to the old way that dosnt set the center depth */
copy_v3_v3(new_ofs, rv3d->ofs);
- initgrabz(rv3d, -new_ofs[0], -new_ofs[1], -new_ofs[2]);
+ {
+ float tvec[3];
+ negate_v3_v3(tvec, new_ofs);
+ zfac = ED_view3d_calc_zfac(rv3d, tvec, NULL);
+ }
mval_f[0] = (rect.xmin + rect.xmax - vb[0]) / 2.0f;
mval_f[1] = (rect.ymin + rect.ymax - vb[1]) / 2.0f;
- ED_view3d_win_to_delta(ar, mval_f, dvec);
+ ED_view3d_win_to_delta(ar, mval_f, dvec, zfac);
/* center the view to the center of the rectangle */
sub_v3_v3(new_ofs, dvec);
}
@@ -2997,7 +3009,7 @@ static int view3d_zoom_border_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int view3d_zoom_border_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int view3d_zoom_border_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
View3D *v3d = CTX_wm_view3d(C);
RegionView3D *rv3d = CTX_wm_region_view3d(C);
@@ -3415,16 +3427,19 @@ static int viewpan_exec(bContext *C, wmOperator *op)
ARegion *ar = CTX_wm_region(C);
RegionView3D *rv3d = CTX_wm_region_view3d(C);
float vec[3];
+ const float co_zero[3] = {0.0f};
float mval_f[2] = {0.0f, 0.0f};
+ float zfac;
int pandir;
pandir = RNA_enum_get(op->ptr, "type");
- initgrabz(rv3d, 0.0, 0.0, 0.0);
- if (pandir == V3D_VIEW_PANRIGHT) { mval_f[0] = -32.0f; ED_view3d_win_to_delta(ar, mval_f, vec); }
- else if (pandir == V3D_VIEW_PANLEFT) { mval_f[0] = 32.0f; ED_view3d_win_to_delta(ar, mval_f, vec); }
- else if (pandir == V3D_VIEW_PANUP) { mval_f[1] = -25.0f; ED_view3d_win_to_delta(ar, mval_f, vec); }
- else if (pandir == V3D_VIEW_PANDOWN) { mval_f[1] = 25.0f; ED_view3d_win_to_delta(ar, mval_f, vec); }
+ zfac = ED_view3d_calc_zfac(rv3d, co_zero, NULL);
+ if (pandir == V3D_VIEW_PANRIGHT) { mval_f[0] = -32.0f; }
+ else if (pandir == V3D_VIEW_PANLEFT) { mval_f[0] = 32.0f; }
+ else if (pandir == V3D_VIEW_PANUP) { mval_f[1] = -25.0f; }
+ else if (pandir == V3D_VIEW_PANDOWN) { mval_f[1] = 25.0f; }
+ ED_view3d_win_to_delta(ar, mval_f, vec, zfac);
add_v3_v3(rv3d->ofs, vec);
if (rv3d->viewlock & RV3D_BOXVIEW)
@@ -3506,7 +3521,7 @@ static int background_image_add_exec(bContext *C, wmOperator *UNUSED(op))
return OPERATOR_FINISHED;
}
-static int background_image_add_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int background_image_add_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
View3D *v3d = CTX_wm_view3d(C);
Image *ima = NULL;
@@ -3661,7 +3676,7 @@ static int view3d_clipping_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int view3d_clipping_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int view3d_clipping_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
RegionView3D *rv3d = CTX_wm_region_view3d(C);
ARegion *ar = CTX_wm_region(C);
@@ -3713,15 +3728,16 @@ void ED_view3d_cursor3d_position(bContext *C, float fp[3], const int mval[2])
View3D *v3d = CTX_wm_view3d(C);
RegionView3D *rv3d = CTX_wm_region_view3d(C);
float mval_fl[2];
- int flip;
+ float zfac;
+ bool flip;
- flip = initgrabz(rv3d, fp[0], fp[1], fp[2]);
+ zfac = ED_view3d_calc_zfac(rv3d, fp, &flip);
/* reset the depth based on the view offset (we _know_ the offset is infront of us) */
if (flip) {
negate_v3_v3(fp, rv3d->ofs);
/* re initialize, no need to check flip again */
- /* flip = */ initgrabz(rv3d, fp[0], fp[1], fp[2]);
+ zfac = ED_view3d_calc_zfac(rv3d, fp, NULL /* &flip */ );
}
if (ED_view3d_project_float_global(ar, fp, mval_fl, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) {
@@ -3736,17 +3752,17 @@ void ED_view3d_cursor3d_position(bContext *C, float fp[3], const int mval[2])
if (depth_used == FALSE) {
float dvec[3];
VECSUB2D(mval_fl, mval_fl, mval);
- ED_view3d_win_to_delta(ar, mval_fl, dvec);
+ ED_view3d_win_to_delta(ar, mval_fl, dvec, zfac);
sub_v3_v3(fp, dvec);
}
}
else {
- const float dx = ((float)(mval[0] - (ar->winx / 2))) * rv3d->zfac / (ar->winx / 2);
- const float dy = ((float)(mval[1] - (ar->winy / 2))) * rv3d->zfac / (ar->winy / 2);
+ const float dx = ((float)(mval[0] - (ar->winx / 2))) * zfac / (ar->winx / 2);
+ const float dy = ((float)(mval[1] - (ar->winy / 2))) * zfac / (ar->winy / 2);
const float fz = (rv3d->persmat[0][3] * fp[0] +
rv3d->persmat[1][3] * fp[1] +
rv3d->persmat[2][3] * fp[2] +
- rv3d->persmat[3][3]) / rv3d->zfac;
+ rv3d->persmat[3][3]) / zfac;
fp[0] = (rv3d->persinv[0][0] * dx + rv3d->persinv[1][0] * dy + rv3d->persinv[2][0] * fz) - rv3d->ofs[0];
fp[1] = (rv3d->persinv[0][1] * dx + rv3d->persinv[1][1] * dy + rv3d->persinv[2][1] * fz) - rv3d->ofs[1];
@@ -3755,7 +3771,7 @@ void ED_view3d_cursor3d_position(bContext *C, float fp[3], const int mval[2])
}
-static int view3d_cursor3d_invoke(bContext *C, wmOperator *UNUSED(op), wmEvent *event)
+static int view3d_cursor3d_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *event)
{
Scene *scene = CTX_data_scene(C);
View3D *v3d = CTX_wm_view3d(C);
@@ -3794,7 +3810,7 @@ void VIEW3D_OT_cursor3d(wmOperatorType *ot)
/* ***************** manipulator op ******************* */
-static int manipulator_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int manipulator_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
View3D *v3d = CTX_wm_view3d(C);
@@ -3830,7 +3846,7 @@ void VIEW3D_OT_manipulator(wmOperatorType *ot)
Transform_Properties(ot, P_CONSTRAINT);
}
-static int enable_manipulator_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int enable_manipulator_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
View3D *v3d = CTX_wm_view3d(C);
diff --git a/source/blender/editors/space_view3d/view3d_fly.c b/source/blender/editors/space_view3d/view3d_fly.c
index c2e75a1c5d9..700027d62a2 100644
--- a/source/blender/editors/space_view3d/view3d_fly.c
+++ b/source/blender/editors/space_view3d/view3d_fly.c
@@ -272,7 +272,7 @@ static void drawFlyPixel(const struct bContext *UNUSED(C), ARegion *UNUSED(ar),
#define FLY_CANCEL 1
#define FLY_CONFIRM 2
-static int initFlyInfo(bContext *C, FlyInfo *fly, wmOperator *op, wmEvent *event)
+static int initFlyInfo(bContext *C, FlyInfo *fly, wmOperator *op, const wmEvent *event)
{
wmWindow *win = CTX_wm_window(C);
float upvec[3]; /* tmp */
@@ -486,7 +486,7 @@ static int flyEnd(bContext *C, FlyInfo *fly)
return OPERATOR_CANCELLED;
}
-static void flyEvent(FlyInfo *fly, wmEvent *event)
+static void flyEvent(FlyInfo *fly, const wmEvent *event)
{
if (event->type == TIMER && event->customdata == fly->timer) {
fly->redraw = 1;
@@ -1179,7 +1179,7 @@ static int flyApply_ndof(bContext *C, FlyInfo *fly)
return OPERATOR_FINISHED;
}
-static int fly_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int fly_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
RegionView3D *rv3d = CTX_wm_region_view3d(C);
FlyInfo *fly;
@@ -1214,7 +1214,7 @@ static int fly_cancel(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
-static int fly_modal(bContext *C, wmOperator *op, wmEvent *event)
+static int fly_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
int exit_code;
short do_draw = FALSE;
diff --git a/source/blender/editors/space_view3d/view3d_header.c b/source/blender/editors/space_view3d/view3d_header.c
index e078fa8eda1..430ed8698d7 100644
--- a/source/blender/editors/space_view3d/view3d_header.c
+++ b/source/blender/editors/space_view3d/view3d_header.c
@@ -28,7 +28,6 @@
* \ingroup spview3d
*/
-
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
@@ -37,8 +36,6 @@
#include "DNA_object_types.h"
#include "DNA_mesh_types.h"
-#include "RNA_access.h"
-
#include "MEM_guardedalloc.h"
#include "BLI_math.h"
@@ -57,18 +54,19 @@
#include "BKE_screen.h"
#include "BKE_tessmesh.h"
+#include "RNA_access.h"
+#include "RNA_define.h"
+#include "RNA_enum_types.h"
+
+#include "WM_api.h"
+#include "WM_types.h"
+
#include "ED_mesh.h"
#include "ED_util.h"
#include "ED_screen.h"
#include "ED_transform.h"
#include "ED_types.h"
-#include "WM_api.h"
-#include "WM_types.h"
-
-#include "RNA_define.h"
-#include "RNA_enum_types.h"
-
#include "UI_interface.h"
#include "UI_resources.h"
@@ -209,7 +207,7 @@ static int view3d_layers_exec(bContext *C, wmOperator *op)
/* applies shift and alt, lazy coding or ok? :) */
/* the local per-keymap-entry keymap will solve it */
-static int view3d_layers_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int view3d_layers_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
if (event->ctrl || event->oskey)
return OPERATOR_PASS_THROUGH;
diff --git a/source/blender/editors/space_view3d/view3d_intern.h b/source/blender/editors/space_view3d/view3d_intern.h
index d4cfa9076a6..26ed8e1885c 100644
--- a/source/blender/editors/space_view3d/view3d_intern.h
+++ b/source/blender/editors/space_view3d/view3d_intern.h
@@ -108,6 +108,9 @@ float ndof_to_axis_angle(const struct wmNDOFMotionData *ndof, float axis[3]);
void view3d_keymap(struct wmKeyConfig *keyconf);
void VIEW3D_OT_fly(struct wmOperatorType *ot);
+/* view3d_ruler.c */
+void VIEW3D_OT_ruler(struct wmOperatorType *ot);
+
/* drawanim.c */
void draw_motion_paths_init(View3D *v3d, struct ARegion *ar);
void draw_motion_path_instance(Scene *scene,
diff --git a/source/blender/editors/space_view3d/view3d_ops.c b/source/blender/editors/space_view3d/view3d_ops.c
index bf1c5404c0e..e567ebda4b7 100644
--- a/source/blender/editors/space_view3d/view3d_ops.c
+++ b/source/blender/editors/space_view3d/view3d_ops.c
@@ -166,6 +166,7 @@ void view3d_operatortypes(void)
WM_operatortype_append(VIEW3D_OT_localview);
WM_operatortype_append(VIEW3D_OT_game_start);
WM_operatortype_append(VIEW3D_OT_fly);
+ WM_operatortype_append(VIEW3D_OT_ruler);
WM_operatortype_append(VIEW3D_OT_layers);
WM_operatortype_append(VIEW3D_OT_copybuffer);
WM_operatortype_append(VIEW3D_OT_pastebuffer);
diff --git a/source/blender/editors/space_view3d/view3d_project.c b/source/blender/editors/space_view3d/view3d_project.c
index bc1656ff7c6..30a100283cc 100644
--- a/source/blender/editors/space_view3d/view3d_project.c
+++ b/source/blender/editors/space_view3d/view3d_project.c
@@ -73,7 +73,7 @@ void ED_view3d_project_float_v2_m4(const ARegion *ar, const float co[3], float r
/**
* \note use #ED_view3d_ob_project_mat_get to get projecting mat
*/
-void ED_view3d_project_float_v3_m4(ARegion *ar, const float vec[3], float r_co[3], float mat[4][4])
+void ED_view3d_project_float_v3_m4(const ARegion *ar, const float vec[3], float r_co[3], float mat[4][4])
{
float vec4[4];
@@ -97,7 +97,7 @@ void ED_view3d_project_float_v3_m4(ARegion *ar, const float vec[3], float r_co[3
/* Clipping Projection Functions
* ***************************** */
-eV3DProjStatus ED_view3d_project_base(struct ARegion *ar, struct Base *base)
+eV3DProjStatus ED_view3d_project_base(const struct ARegion *ar, struct Base *base)
{
eV3DProjStatus ret = ED_view3d_project_short_global(ar, base->object->obmat[3], &base->sx, V3D_PROJ_TEST_CLIP_DEFAULT);
@@ -113,8 +113,8 @@ eV3DProjStatus ED_view3d_project_base(struct ARegion *ar, struct Base *base)
* - 'rv3d->perspmat', is_local == FALSE
* - 'rv3d->persmatob', is_local == TRUE
*/
-static eV3DProjStatus ed_view3d_project__internal(ARegion *ar,
- float perspmat[4][4], const int is_local, /* normally hidden */
+static eV3DProjStatus ed_view3d_project__internal(const ARegion *ar,
+ float perspmat[4][4], const bool is_local, /* normally hidden */
const float co[3], float r_co[2], const eV3DProjTest flag)
{
float vec4[4];
@@ -171,7 +171,7 @@ static eV3DProjStatus ed_view3d_project__internal(ARegion *ar,
return V3D_PROJ_RET_OK;
}
-eV3DProjStatus ED_view3d_project_short_ex(ARegion *ar, float perspmat[4][4], const int is_local,
+eV3DProjStatus ED_view3d_project_short_ex(const ARegion *ar, float perspmat[4][4], const bool is_local,
const float co[3], short r_co[2], const eV3DProjTest flag)
{
float tvec[2];
@@ -190,7 +190,7 @@ eV3DProjStatus ED_view3d_project_short_ex(ARegion *ar, float perspmat[4][4], con
return ret;
}
-eV3DProjStatus ED_view3d_project_int_ex(ARegion *ar, float perspmat[4][4], const int is_local,
+eV3DProjStatus ED_view3d_project_int_ex(const ARegion *ar, float perspmat[4][4], const bool is_local,
const float co[3], int r_co[2], const eV3DProjTest flag)
{
float tvec[2];
@@ -209,7 +209,7 @@ eV3DProjStatus ED_view3d_project_int_ex(ARegion *ar, float perspmat[4][4], const
return ret;
}
-eV3DProjStatus ED_view3d_project_float_ex(ARegion *ar, float perspmat[4][4], const int is_local,
+eV3DProjStatus ED_view3d_project_float_ex(const ARegion *ar, float perspmat[4][4], const bool is_local,
const float co[3], float r_co[2], const eV3DProjTest flag)
{
float tvec[2];
@@ -228,39 +228,39 @@ eV3DProjStatus ED_view3d_project_float_ex(ARegion *ar, float perspmat[4][4], con
}
/* --- short --- */
-eV3DProjStatus ED_view3d_project_short_global(ARegion *ar, const float co[3], short r_co[2], const eV3DProjTest flag)
+eV3DProjStatus ED_view3d_project_short_global(const ARegion *ar, const float co[3], short r_co[2], const eV3DProjTest flag)
{
RegionView3D *rv3d = ar->regiondata;
return ED_view3d_project_short_ex(ar, rv3d->persmat, FALSE, co, r_co, flag);
}
/* object space, use ED_view3d_init_mats_rv3d before calling */
-eV3DProjStatus ED_view3d_project_short_object(ARegion *ar, const float co[3], short r_co[2], const eV3DProjTest flag)
+eV3DProjStatus ED_view3d_project_short_object(const ARegion *ar, const float co[3], short r_co[2], const eV3DProjTest flag)
{
RegionView3D *rv3d = ar->regiondata;
return ED_view3d_project_short_ex(ar, rv3d->persmatob, TRUE, co, r_co, flag);
}
/* --- int --- */
-eV3DProjStatus ED_view3d_project_int_global(ARegion *ar, const float co[3], int r_co[2], const eV3DProjTest flag)
+eV3DProjStatus ED_view3d_project_int_global(const ARegion *ar, const float co[3], int r_co[2], const eV3DProjTest flag)
{
RegionView3D *rv3d = ar->regiondata;
return ED_view3d_project_int_ex(ar, rv3d->persmat, FALSE, co, r_co, flag);
}
/* object space, use ED_view3d_init_mats_rv3d before calling */
-eV3DProjStatus ED_view3d_project_int_object(ARegion *ar, const float co[3], int r_co[2], const eV3DProjTest flag)
+eV3DProjStatus ED_view3d_project_int_object(const ARegion *ar, const float co[3], int r_co[2], const eV3DProjTest flag)
{
RegionView3D *rv3d = ar->regiondata;
return ED_view3d_project_int_ex(ar, rv3d->persmatob, TRUE, co, r_co, flag);
}
/* --- float --- */
-eV3DProjStatus ED_view3d_project_float_global(ARegion *ar, const float co[3], float r_co[2], const eV3DProjTest flag)
+eV3DProjStatus ED_view3d_project_float_global(const ARegion *ar, const float co[3], float r_co[2], const eV3DProjTest flag)
{
RegionView3D *rv3d = ar->regiondata;
return ED_view3d_project_float_ex(ar, rv3d->persmat, FALSE, co, r_co, flag);
}
/* object space, use ED_view3d_init_mats_rv3d before calling */
-eV3DProjStatus ED_view3d_project_float_object(ARegion *ar, const float co[3], float r_co[2], const eV3DProjTest flag)
+eV3DProjStatus ED_view3d_project_float_object(const ARegion *ar, const float co[3], float r_co[2], const eV3DProjTest flag)
{
RegionView3D *rv3d = ar->regiondata;
return ED_view3d_project_float_ex(ar, rv3d->persmatob, TRUE, co, r_co, flag);
@@ -271,28 +271,30 @@ eV3DProjStatus ED_view3d_project_float_object(ARegion *ar, const float co[3], fl
/* More Generic Window/Ray/Vector projection functions
* *************************************************** */
-/* odd function, need to document better */
-int initgrabz(RegionView3D *rv3d, float x, float y, float z)
+/**
+ * Caculate a depth value from \a co, use with #ED_view3d_win_to_delta
+ */
+float ED_view3d_calc_zfac(const RegionView3D *rv3d, const float co[3], bool *r_flip)
{
- int flip = FALSE;
- if (rv3d == NULL) return flip;
- rv3d->zfac = rv3d->persmat[0][3] * x + rv3d->persmat[1][3] * y + rv3d->persmat[2][3] * z + rv3d->persmat[3][3];
- if (rv3d->zfac < 0.0f)
- flip = TRUE;
+ float zfac = mul_project_m4_v3_zfac((float (*)[4])rv3d->persmat, co);
+
+ if (r_flip) {
+ *r_flip = (zfac < 0.0f);
+ }
+
/* if x,y,z is exactly the viewport offset, zfac is 0 and we don't want that
- * (accounting for near zero values)
- */
- if (rv3d->zfac < 1.e-6f && rv3d->zfac > -1.e-6f) rv3d->zfac = 1.0f;
+ * (accounting for near zero values) */
+ if (zfac < 1.e-6f && zfac > -1.e-6f) {
+ zfac = 1.0f;
+ }
/* Negative zfac means x, y, z was behind the camera (in perspective).
- * This gives flipped directions, so revert back to ok default case.
- */
- /* NOTE: I've changed this to flip zfac to be positive again for now so that GPencil draws ok
- * Aligorith, 2009Aug31 */
- //if (rv3d->zfac < 0.0f) rv3d->zfac = 1.0f;
- if (rv3d->zfac < 0.0f) rv3d->zfac = -rv3d->zfac;
-
- return flip;
+ * This gives flipped directions, so revert back to ok default case. */
+ if (zfac < 0.0f) {
+ zfac = -zfac;
+ }
+
+ return zfac;
}
/**
@@ -306,7 +308,7 @@ int initgrabz(RegionView3D *rv3d, float x, float y, float z)
* \param ray_start The world-space starting point of the segment.
* \param ray_normal The normalized world-space direction of towards mval.
*/
-void ED_view3d_win_to_ray(ARegion *ar, View3D *v3d, const float mval[2], float ray_start[3], float ray_normal[3])
+void ED_view3d_win_to_ray(const ARegion *ar, View3D *v3d, const float mval[2], float ray_start[3], float ray_normal[3])
{
float ray_end[3];
@@ -322,7 +324,7 @@ void ED_view3d_win_to_ray(ARegion *ar, View3D *v3d, const float mval[2], float r
* \param coord The world-space location.
* \param vec The resulting normalized vector.
*/
-void ED_view3d_global_to_vector(RegionView3D *rv3d, const float coord[3], float vec[3])
+void ED_view3d_global_to_vector(const RegionView3D *rv3d, const float coord[3], float vec[3])
{
if (rv3d->is_persp) {
float p1[4], p2[4];
@@ -331,11 +333,11 @@ void ED_view3d_global_to_vector(RegionView3D *rv3d, const float coord[3], float
p1[3] = 1.0f;
copy_v3_v3(p2, p1);
p2[3] = 1.0f;
- mul_m4_v4(rv3d->viewmat, p2);
+ mul_m4_v4((float (*)[4])rv3d->viewmat, p2);
mul_v3_fl(p2, 2.0f);
- mul_m4_v4(rv3d->viewinv, p2);
+ mul_m4_v4((float (*)[4])rv3d->viewinv, p2);
sub_v3_v3v3(vec, p1, p2);
}
@@ -352,7 +354,7 @@ void ED_view3d_global_to_vector(RegionView3D *rv3d, const float coord[3], float
* \param mval The area relative location (such as event->mval converted to floats).
* \param out The resulting world-space location.
*/
-void ED_view3d_win_to_3d(ARegion *ar, const float depth_pt[3], const float mval[2], float out[3])
+void ED_view3d_win_to_3d(const ARegion *ar, const float depth_pt[3], const float mval[2], float out[3])
{
RegionView3D *rv3d = ar->regiondata;
@@ -384,19 +386,19 @@ void ED_view3d_win_to_3d(ARegion *ar, const float depth_pt[3], const float mval[
/**
* Calculate a 3d difference vector from 2d window offset.
- * note that initgrabz() must be called first to determine
+ * note that ED_view3d_calc_zfac() must be called first to determine
* the depth used to calculate the delta.
* \param ar The region (used for the window width and height).
* \param mval The area relative 2d difference (such as event->mval[0] - other_x).
* \param out The resulting world-space delta.
*/
-void ED_view3d_win_to_delta(ARegion *ar, const float mval[2], float out[3])
+void ED_view3d_win_to_delta(const ARegion *ar, const float mval[2], float out[3], const float zfac)
{
RegionView3D *rv3d = ar->regiondata;
float dx, dy;
- dx = 2.0f * mval[0] * rv3d->zfac / ar->winx;
- dy = 2.0f * mval[1] * rv3d->zfac / ar->winy;
+ dx = 2.0f * mval[0] * zfac / ar->winx;
+ dy = 2.0f * mval[1] * zfac / ar->winy;
out[0] = (rv3d->persinv[0][0] * dx + rv3d->persinv[1][0] * dy);
out[1] = (rv3d->persinv[0][1] * dx + rv3d->persinv[1][1] * dy);
@@ -408,7 +410,7 @@ void ED_view3d_win_to_delta(ARegion *ar, const float mval[2], float out[3])
* This direction vector starts and the view in the direction of the 2d window coordinates.
* In orthographic view all window coordinates yield the same vector.
*
- * \note doesn't rely on initgrabz
+ * \note doesn't rely on ED_view3d_calc_zfac
* for perspective view, get the vector direction to
* the mouse cursor as a normalized vector.
*
@@ -416,7 +418,7 @@ void ED_view3d_win_to_delta(ARegion *ar, const float mval[2], float out[3])
* \param mval The area relative 2d location (such as event->mval converted to floats).
* \param out The resulting normalized world-space direction vector.
*/
-void ED_view3d_win_to_vector(ARegion *ar, const float mval[2], float out[3])
+void ED_view3d_win_to_vector(const ARegion *ar, const float mval[2], float out[3])
{
RegionView3D *rv3d = ar->regiondata;
@@ -433,7 +435,7 @@ void ED_view3d_win_to_vector(ARegion *ar, const float mval[2], float out[3])
normalize_v3(out);
}
-void ED_view3d_win_to_segment(ARegion *ar, View3D *v3d, const float mval[2], float ray_start[3], float ray_end[3])
+void ED_view3d_win_to_segment(const ARegion *ar, View3D *v3d, const float mval[2], float ray_start[3], float ray_end[3])
{
RegionView3D *rv3d = ar->regiondata;
@@ -472,7 +474,7 @@ void ED_view3d_win_to_segment(ARegion *ar, View3D *v3d, const float mval[2], flo
* \param ray_end The world-space end point of the segment.
* \return success, FALSE if the segment is totally clipped.
*/
-int ED_view3d_win_to_segment_clip(ARegion *ar, View3D *v3d, const float mval[2], float ray_start[3], float ray_end[3])
+int ED_view3d_win_to_segment_clip(const ARegion *ar, View3D *v3d, const float mval[2], float ray_start[3], float ray_end[3])
{
RegionView3D *rv3d = ar->regiondata;
ED_view3d_win_to_segment(ar, v3d, mval, ray_start, ray_end);
@@ -503,12 +505,12 @@ int ED_view3d_win_to_segment_clip(ARegion *ar, View3D *v3d, const float mval[2],
/* Utility functions for projection
* ******************************** */
-void ED_view3d_ob_project_mat_get(RegionView3D *rv3d, Object *ob, float pmat[4][4])
+void ED_view3d_ob_project_mat_get(const RegionView3D *rv3d, Object *ob, float pmat[4][4])
{
float vmat[4][4];
- mult_m4_m4m4(vmat, rv3d->viewmat, ob->obmat);
- mult_m4_m4m4(pmat, rv3d->winmat, vmat);
+ mult_m4_m4m4(vmat, (float (*)[4])rv3d->viewmat, ob->obmat);
+ mult_m4_m4m4(pmat, (float (*)[4])rv3d->winmat, vmat);
}
/**
diff --git a/source/blender/editors/space_view3d/view3d_ruler.c b/source/blender/editors/space_view3d/view3d_ruler.c
new file mode 100644
index 00000000000..410d20a1dc0
--- /dev/null
+++ b/source/blender/editors/space_view3d/view3d_ruler.c
@@ -0,0 +1,939 @@
+/*
+ * ***** 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/editors/space_view3d/view3d_ruler.c
+ * \ingroup spview3d
+ */
+
+/* defines VIEW3D_OT_ruler modal operator */
+
+#include "DNA_scene_types.h"
+#include "DNA_gpencil_types.h"
+
+#include "MEM_guardedalloc.h"
+
+#include "BLI_math.h"
+#include "BLI_blenlib.h"
+
+#include "BKE_context.h"
+#include "BKE_unit.h"
+#include "BKE_gpencil.h"
+
+#include "BIF_gl.h"
+
+#include "WM_api.h"
+#include "WM_types.h"
+
+#include "ED_screen.h"
+#include "ED_space_api.h"
+
+#include "BLF_api.h"
+#include "BIF_glutil.h"
+
+#include "UI_resources.h"
+#include "UI_interface.h"
+
+#include "view3d_intern.h" /* own include */
+
+
+/* -------------------------------------------------------------------- */
+/* Snapping (could be own function) */
+/* NOTE - this is not very nice use of transform snapping */
+#include "ED_transform.h"
+#include "../transform/transform.h"
+
+static bool ED_view3d_snap_co(bContext *C, float r_co[3], const float co_ss[2],
+ bool use_vert, bool use_edge, bool use_face)
+{
+ TransInfo t = {0};
+ int dist = 12; /* snap dist */
+ float r_no_dummy[3];
+ bool ret = false;
+ char backup_snap_mode;
+ Base *backup_baseact;
+
+ t.scene = CTX_data_scene(C);
+ t.view = CTX_wm_view3d(C);
+ t.ar = CTX_wm_region(C);
+ t.obedit = CTX_data_edit_object(C);
+
+ backup_snap_mode = t.scene->toolsettings->snap_mode;
+ backup_baseact = t.scene->basact;
+ t.scene->basact = NULL;
+
+ /* try snap edge, then face if it fails */
+ if (use_vert) {
+ t.scene->toolsettings->snap_mode = SCE_SNAP_MODE_VERTEX;
+ ret = snapObjectsTransform(&t, co_ss, &dist, r_co, r_no_dummy, SNAP_ALL);
+ }
+ if (use_edge && (ret == false)) {
+ t.scene->toolsettings->snap_mode = SCE_SNAP_MODE_EDGE;
+ ret = snapObjectsTransform(&t, co_ss, &dist, r_co, r_no_dummy, SNAP_ALL);
+ }
+ if (use_face && (ret == false)) {
+ t.scene->toolsettings->snap_mode = SCE_SNAP_MODE_FACE;
+ ret = snapObjectsTransform(&t, co_ss, &dist, r_co, r_no_dummy, SNAP_ALL);
+ }
+
+ t.scene->toolsettings->snap_mode = backup_snap_mode;
+ t.scene->basact = backup_baseact;
+
+ return ret;
+}
+/* done snapping */
+
+
+/* -------------------------------------------------------------------- */
+/* Ruler Item (we can have many) */
+enum {
+ RULERITEM_USE_ANGLE = (1 << 0), /* use protractor */
+ RULERITEM_USE_RAYCAST = (1 << 1)
+};
+
+enum {
+ RULERITEM_DIRECTION_IN = 0,
+ RULERITEM_DIRECTION_OUT
+};
+
+#define RULER_PICK_DIST 75.0f
+#define RULER_PICK_DIST_SQ (RULER_PICK_DIST * RULER_PICK_DIST)
+
+typedef struct RulerItem {
+ struct RulerItem *next, *prev;
+
+ /* worldspace coords, middle being optional */
+ float co[3][3];
+
+ /* selected coord */
+ char co_index; /* 0 -> 2*/
+
+ int flag;
+ int raycast_dir; /* RULER_DIRECTION_* */
+} RulerItem;
+
+enum {
+ RULER_STATE_NORMAL = 0,
+ RULER_STATE_DRAG
+};
+
+
+/* -------------------------------------------------------------------- */
+/* Ruler Info (one per session) */
+
+typedef struct RulerInfo {
+ ListBase items;
+ int item_active;
+ int flag;
+ int snap_flag;
+ int state;
+
+ /* --- */
+ ARegion *ar;
+ void *draw_handle_pixel;
+} RulerInfo;
+
+/* -------------------------------------------------------------------- */
+/* local functions */
+static RulerItem *ruler_item_add(RulerInfo *ruler_info)
+{
+ RulerItem *ruler_item = MEM_callocN(sizeof(RulerItem), "RulerItem");
+ BLI_addtail(&ruler_info->items, ruler_item);
+ return ruler_item;
+}
+
+static void ruler_item_remove(RulerInfo *ruler_info, RulerItem *ruler_item)
+{
+ BLI_remlink(&ruler_info->items, ruler_item);
+ MEM_freeN(ruler_item);
+}
+
+static RulerItem *ruler_item_active_get(RulerInfo *ruler_info)
+{
+ return BLI_findlink(&ruler_info->items, ruler_info->item_active);
+}
+
+static void ruler_item_active_set(RulerInfo *ruler_info, RulerItem *ruler_item)
+{
+ ruler_info->item_active = BLI_findindex(&ruler_info->items, ruler_item);
+}
+
+static void ruler_item_as_string(RulerItem *ruler_item, UnitSettings *unit,
+ char *numstr, size_t numstr_size, int prec)
+{
+ const int do_split = unit->flag & USER_UNIT_OPT_SPLIT;
+
+ if (ruler_item->flag & RULERITEM_USE_ANGLE) {
+ const float ruler_angle = angle_v3v3v3(ruler_item->co[0],
+ ruler_item->co[1],
+ ruler_item->co[2]);
+
+ if (unit->system == USER_UNIT_NONE) {
+ BLI_snprintf(numstr, numstr_size, "%.*f°", prec, RAD2DEGF(ruler_angle));
+ }
+ else {
+ bUnit_AsString(numstr, numstr_size,
+ (double)ruler_angle,
+ prec, unit->system, B_UNIT_ROTATION, do_split, false);
+ }
+ }
+ else {
+ const float ruler_len = len_v3v3(ruler_item->co[0],
+ ruler_item->co[2]);
+
+ if (unit->system == USER_UNIT_NONE) {
+ BLI_snprintf(numstr, numstr_size, "%.*f", prec, ruler_len);
+ }
+ else {
+ bUnit_AsString(numstr, numstr_size,
+ (double)(ruler_len * unit->scale_length),
+ prec, unit->system, B_UNIT_LENGTH, do_split, false);
+ }
+ }
+
+}
+
+static bool view3d_ruler_pick(RulerInfo *ruler_info, const float mval[2],
+ RulerItem **r_ruler_item, int *r_co_index)
+{
+ ARegion *ar = ruler_info->ar;
+ RulerItem *ruler_item;
+
+ float dist_best = RULER_PICK_DIST_SQ;
+ RulerItem *ruler_item_best = NULL;
+ int co_index_best = -1;
+
+ for (ruler_item = ruler_info->items.first; ruler_item; ruler_item = ruler_item->next) {
+ float co_ss[3][2];
+ float dist;
+ int j;
+
+ /* should these be checked? - ok for now not to */
+ for (j = 0; j < 3; j++) {
+ ED_view3d_project_float_global(ar, ruler_item->co[j], co_ss[j], V3D_PROJ_TEST_NOP);
+ }
+
+ if (ruler_item->flag & RULERITEM_USE_ANGLE) {
+ dist = min_ff(dist_squared_to_line_segment_v2(mval, co_ss[0], co_ss[1]),
+ dist_squared_to_line_segment_v2(mval, co_ss[1], co_ss[2]));
+ if (dist < dist_best) {
+ dist_best = dist;
+ ruler_item_best = ruler_item;
+
+ {
+ float dist_points[3] = {len_squared_v2v2(co_ss[0], mval),
+ len_squared_v2v2(co_ss[1], mval),
+ len_squared_v2v2(co_ss[2], mval)};
+ if (min_fff(UNPACK3(dist_points)) < RULER_PICK_DIST_SQ) {
+ co_index_best = min_axis_v3(dist_points);
+ }
+ else {
+ co_index_best = -1;
+ }
+ }
+ }
+ }
+ else {
+ dist = dist_squared_to_line_segment_v2(mval, co_ss[0], co_ss[2]);
+ if (dist < dist_best) {
+ dist_best = dist;
+ ruler_item_best = ruler_item;
+
+ {
+ float dist_points[2] = {len_squared_v2v2(co_ss[0], mval),
+ len_squared_v2v2(co_ss[2], mval)};
+ if (min_ff(UNPACK2(dist_points)) < RULER_PICK_DIST_SQ) {
+ co_index_best = (dist_points[0] < dist_points[1]) ? 0 : 2;
+ }
+ else {
+ co_index_best = -1;
+ }
+ }
+ }
+ }
+ }
+
+ if (ruler_item_best) {
+ *r_ruler_item = ruler_item_best;
+ *r_co_index = co_index_best;
+ return true;
+ }
+ else {
+ *r_ruler_item = NULL;
+ *r_co_index = -1;
+ return false;
+ }
+}
+
+#define RULER_ID "RulerData3D"
+static bool view3d_ruler_to_gpencil(bContext *C, RulerInfo *ruler_info)
+{
+ Scene *scene = CTX_data_scene(C);
+ bGPDlayer *gpl;
+ bGPDframe *gpf;
+ bGPDstroke *gps;
+ RulerItem *ruler_item;
+ const char *ruler_name = RULER_ID;
+ bool change = false;
+
+ if (scene->gpd == NULL) {
+ scene->gpd = gpencil_data_addnew("GPencil");
+ }
+
+ gpl = BLI_findstring(&scene->gpd->layers, ruler_name, offsetof(bGPDlayer, info));
+ if (gpl == NULL) {
+ gpl = gpencil_layer_addnew(scene->gpd, ruler_name, false);
+ gpl->thickness = 1;
+ gpl->flag |= GP_LAYER_HIDE;
+ }
+
+ gpf = gpencil_layer_getframe(gpl, CFRA, true);
+ free_gpencil_strokes(gpf);
+
+ for (ruler_item = ruler_info->items.first; ruler_item; ruler_item = ruler_item->next) {
+ bGPDspoint *pt;
+ int j;
+
+ /* allocate memory for a new stroke */
+ gps = MEM_callocN(sizeof(bGPDstroke), "gp_stroke");
+ if (ruler_item->flag & RULERITEM_USE_ANGLE) {
+ gps->totpoints = 3;
+ pt = gps->points = MEM_callocN(sizeof(bGPDspoint) * gps->totpoints, "gp_stroke_points");
+ for (j = 0; j < 3; j++) {
+ copy_v3_v3(&pt->x, ruler_item->co[j]);
+ pt->pressure = 1.0f;
+ pt++;
+ }
+ }
+ else {
+ gps->totpoints = 2;
+ pt = gps->points = MEM_callocN(sizeof(bGPDspoint) * gps->totpoints, "gp_stroke_points");
+ for (j = 0; j < 3; j += 2) {
+ copy_v3_v3(&pt->x, ruler_item->co[j]);
+ pt->pressure = 1.0f;
+ pt++;
+ }
+ }
+ gps->flag = GP_STROKE_3DSPACE;
+ BLI_addtail(&gpf->strokes, gps);
+ change = true;
+ }
+
+ return change;
+}
+
+static bool view3d_ruler_from_gpencil(bContext *C, RulerInfo *ruler_info)
+{
+ Scene *scene = CTX_data_scene(C);
+ bool change = false;
+
+ if (scene->gpd) {
+ bGPDlayer *gpl;
+ const char *ruler_name = RULER_ID;
+ gpl = BLI_findstring(&scene->gpd->layers, ruler_name, offsetof(bGPDlayer, info));
+ if (gpl) {
+ bGPDframe *gpf;
+ gpf = gpencil_layer_getframe(gpl, CFRA, false);
+ if (gpf) {
+ bGPDstroke *gps;
+ for (gps = gpf->strokes.first; gps; gps = gps->next) {
+ bGPDspoint *pt = gps->points;
+ int j;
+ if (gps->totpoints == 3) {
+ RulerItem *ruler_item = ruler_item_add(ruler_info);
+ for (j = 0; j < 3; j++) {
+ copy_v3_v3(ruler_item->co[j], &pt->x);
+ pt++;
+ }
+ ruler_item->flag |= RULERITEM_USE_ANGLE;
+ change = true;
+ }
+ else if (gps->totpoints == 2) {
+ RulerItem *ruler_item = ruler_item_add(ruler_info);
+ for (j = 0; j < 3; j += 2) {
+ copy_v3_v3(ruler_item->co[j], &pt->x);
+ pt++;
+ }
+ change = true;
+ }
+ }
+ }
+ }
+ }
+
+ return change;
+}
+
+/* -------------------------------------------------------------------- */
+/* local callbacks */
+
+static void ruler_info_draw_pixel(const struct bContext *C, ARegion *ar, void *arg)
+{
+ Scene *scene = CTX_data_scene(C);
+ UnitSettings *unit = &scene->unit;
+ RulerItem *ruler_item;
+ RulerInfo *ruler_info = arg;
+ RegionView3D *rv3d = ruler_info->ar->regiondata;
+// ARegion *ar = ruler_info->ar;
+ const float cap_size = 4.0f;
+ const float bg_margin = 4.0f * U.pixelsize;
+ const float bg_radius = 4.0f * U.pixelsize;
+ const float arc_size = 64.0f * U.pixelsize;
+#define ARC_STEPS 24
+ const int arc_steps = ARC_STEPS;
+ int i;
+ //unsigned int color_act = 0x666600;
+ unsigned int color_act = 0xffffff;
+ unsigned int color_base = 0x0;
+ unsigned char color_back[4] = {0xff, 0xff, 0xff, 0x80};
+ unsigned char color_text[3];
+ unsigned char color_wire[3];
+
+ /* anti-aliased lines for more consistent appearance */
+ glEnable(GL_LINE_SMOOTH);
+
+ BLF_enable(blf_mono_font, BLF_ROTATION);
+ BLF_size(blf_mono_font, 14 * U.pixelsize, U.dpi);
+ BLF_rotation(blf_mono_font, 0.0f);
+
+ UI_GetThemeColor3ubv(TH_TEXT, color_text);
+ UI_GetThemeColor3ubv(TH_WIRE, color_wire);
+
+ for (ruler_item = ruler_info->items.first, i = 0; ruler_item; ruler_item = ruler_item->next, i++) {
+ const bool is_act = (i == ruler_info->item_active);
+ float dir_ruler[2];
+ float co_ss[3][2];
+ int j;
+
+ /* should these be checked? - ok for now not to */
+ for (j = 0; j < 3; j++) {
+ ED_view3d_project_float_global(ar, ruler_item->co[j], co_ss[j], V3D_PROJ_TEST_NOP);
+ }
+
+ glEnable(GL_BLEND);
+
+ cpack(is_act ? color_act : color_base);
+
+ if (ruler_item->flag & RULERITEM_USE_ANGLE) {
+ glBegin(GL_LINE_STRIP);
+ for (j = 0; j < 3; j++) {
+ glVertex2fv(co_ss[j]);
+ }
+ glEnd();
+ cpack(0xaaaaaa);
+ setlinestyle(3);
+ glBegin(GL_LINE_STRIP);
+ for (j = 0; j < 3; j++) {
+ glVertex2fv(co_ss[j]);
+ }
+ glEnd();
+ setlinestyle(0);
+
+ /* arc */
+ {
+ float dir_tmp[3];
+ float co_tmp[3];
+ float arc_ss_coords[ARC_STEPS + 1][2];
+
+ float dir_a[3];
+ float dir_b[3];
+ float quat[4];
+ float axis[3];
+ float angle;
+ const float px_scale = (ED_view3d_pixel_size(rv3d, ruler_item->co[1]) *
+ min_fff(arc_size,
+ len_v2v2(co_ss[0], co_ss[1]) / 2.0f,
+ len_v2v2(co_ss[2], co_ss[1]) / 2.0f));
+
+ sub_v3_v3v3(dir_a, ruler_item->co[0], ruler_item->co[1]);
+ sub_v3_v3v3(dir_b, ruler_item->co[2], ruler_item->co[1]);
+ normalize_v3(dir_a);
+ normalize_v3(dir_b);
+
+ cross_v3_v3v3(axis, dir_a, dir_b);
+ angle = angle_normalized_v3v3(dir_a, dir_b);
+
+ axis_angle_to_quat(quat, axis, angle / arc_steps);
+
+ copy_v3_v3(dir_tmp, dir_a);
+
+ glColor3ubv(color_wire);
+
+ for (j = 0; j <= arc_steps; j++) {
+ madd_v3_v3v3fl(co_tmp, ruler_item->co[1], dir_tmp, px_scale);
+ ED_view3d_project_float_global(ar, co_tmp, arc_ss_coords[j], V3D_PROJ_TEST_NOP);
+ mul_qt_v3(quat, dir_tmp);
+ }
+
+ glEnableClientState(GL_VERTEX_ARRAY);
+ glVertexPointer(2, GL_FLOAT, 0, arc_ss_coords);
+ glDrawArrays(GL_LINE_STRIP, 0, arc_steps + 1);
+ glDisableClientState(GL_VERTEX_ARRAY);
+ }
+
+ /* text */
+ {
+ char numstr[256];
+ float numstr_size[2];
+ float pos[2];
+ const int prec = 2; /* XXX, todo, make optional */
+
+ ruler_item_as_string(ruler_item, unit, numstr, sizeof(numstr), prec);
+
+ BLF_width_and_height(blf_mono_font, numstr, &numstr_size[0], &numstr_size[1]);
+
+ pos[0] = co_ss[1][0] + (cap_size * 2.0f);
+ pos[1] = co_ss[1][1] - (numstr_size[1] / 2.0f);
+
+ /* draw text (bg) */
+ glColor4ubv(color_back);
+ uiSetRoundBox(UI_CNR_ALL);
+ uiRoundBox(pos[0] - bg_margin, pos[1] - bg_margin,
+ pos[0] + bg_margin + numstr_size[0], pos[1] + bg_margin + numstr_size[1],
+ bg_radius);
+ /* draw text */
+ glColor3ubv(color_text);
+ BLF_position(blf_mono_font, pos[0], pos[1], 0.0f);
+ BLF_rotation(blf_mono_font, 0.0f);
+ BLF_draw(blf_mono_font, numstr, sizeof(numstr));
+ }
+
+ /* capping */
+ {
+ float rot_90_vec_a[2];
+ float rot_90_vec_b[2];
+ float cap[2];
+
+ sub_v2_v2v2(dir_ruler, co_ss[0], co_ss[1]);
+ rot_90_vec_a[0] = -dir_ruler[1];
+ rot_90_vec_a[1] = dir_ruler[0];
+ normalize_v2(rot_90_vec_a);
+
+ sub_v2_v2v2(dir_ruler, co_ss[1], co_ss[2]);
+ rot_90_vec_b[0] = -dir_ruler[1];
+ rot_90_vec_b[1] = dir_ruler[0];
+ normalize_v2(rot_90_vec_b);
+
+ glEnable(GL_BLEND);
+
+ glColor3ubv(color_wire);
+
+ glBegin(GL_LINES);
+
+ madd_v2_v2v2fl(cap, co_ss[0], rot_90_vec_a, cap_size);
+ glVertex2fv(cap);
+ madd_v2_v2v2fl(cap, co_ss[0], rot_90_vec_a, -cap_size);
+ glVertex2fv(cap);
+
+ madd_v2_v2v2fl(cap, co_ss[2], rot_90_vec_b, cap_size);
+ glVertex2fv(cap);
+ madd_v2_v2v2fl(cap, co_ss[2], rot_90_vec_b, -cap_size);
+ glVertex2fv(cap);
+
+ /* angle vertex */
+ glVertex2f(co_ss[1][0] - cap_size, co_ss[1][1] - cap_size);
+ glVertex2f(co_ss[1][0] + cap_size, co_ss[1][1] + cap_size);
+ glVertex2f(co_ss[1][0] - cap_size, co_ss[1][1] + cap_size);
+ glVertex2f(co_ss[1][0] + cap_size, co_ss[1][1] - cap_size);
+ glEnd();
+
+ glDisable(GL_BLEND);
+ }
+ }
+ else {
+ glBegin(GL_LINE_STRIP);
+ for (j = 0; j < 3; j += 2) {
+ glVertex2fv(co_ss[j]);
+ }
+ glEnd();
+ cpack(0xaaaaaa);
+ setlinestyle(3);
+ glBegin(GL_LINE_STRIP);
+ for (j = 0; j < 3; j += 2) {
+ glVertex2fv(co_ss[j]);
+ }
+ glEnd();
+ setlinestyle(0);
+
+ sub_v2_v2v2(dir_ruler, co_ss[0], co_ss[2]);
+
+ /* text */
+ {
+ char numstr[256];
+ float numstr_size[2];
+ const int prec = 6; /* XXX, todo, make optional */
+ float pos[2];
+
+ ruler_item_as_string(ruler_item, unit, numstr, sizeof(numstr), prec);
+
+ BLF_width_and_height(blf_mono_font, numstr, &numstr_size[0], &numstr_size[1]);
+
+ mid_v2_v2v2(pos, co_ss[0], co_ss[2]);
+
+ /* center text */
+ pos[0] -= numstr_size[0] / 2.0f;
+ pos[1] -= numstr_size[1] / 2.0f;
+
+ /* draw text (bg) */
+ glColor4ubv(color_back);
+ uiSetRoundBox(UI_CNR_ALL);
+ uiRoundBox(pos[0] - bg_margin, pos[1] - bg_margin,
+ pos[0] + bg_margin + numstr_size[0], pos[1] + bg_margin + numstr_size[1],
+ bg_radius);
+ /* draw text */
+ glColor3ubv(color_text);
+ BLF_position(blf_mono_font, pos[0], pos[1], 0.0f);
+ BLF_draw(blf_mono_font, numstr, sizeof(numstr));
+ }
+
+ /* capping */
+ {
+ float rot_90_vec[2] = {-dir_ruler[1], dir_ruler[0]};
+ float cap[2];
+
+ normalize_v2(rot_90_vec);
+
+ glEnable(GL_BLEND);
+ glColor3ubv(color_wire);
+
+ glBegin(GL_LINES);
+ madd_v2_v2v2fl(cap, co_ss[0], rot_90_vec, cap_size);
+ glVertex2fv(cap);
+ madd_v2_v2v2fl(cap, co_ss[0], rot_90_vec, -cap_size);
+ glVertex2fv(cap);
+
+ madd_v2_v2v2fl(cap, co_ss[2], rot_90_vec, cap_size);
+ glVertex2fv(cap);
+ madd_v2_v2v2fl(cap, co_ss[2], rot_90_vec, -cap_size);
+ glVertex2fv(cap);
+ glEnd();
+
+ glDisable(GL_BLEND);
+ }
+ }
+ }
+
+ glDisable(GL_LINE_SMOOTH);
+
+ BLF_disable(blf_mono_font, BLF_ROTATION);
+
+#undef ARC_STEPS
+}
+
+/* free, use for both cancel and finish */
+static void view3d_ruler_end(const struct bContext *UNUSED(C), RulerInfo *ruler_info)
+{
+ ED_region_draw_cb_exit(ruler_info->ar->type, ruler_info->draw_handle_pixel);
+}
+
+static void view3d_ruler_free(RulerInfo *ruler_info)
+{
+ BLI_freelistN(&ruler_info->items);
+ MEM_freeN(ruler_info);
+}
+
+static void view3d_ruler_item_project(RulerInfo *ruler_info, float r_co[3],
+ const int xy[2])
+{
+ view3d_get_view_aligned_coordinate(ruler_info->ar, r_co, xy, true);
+}
+
+/* use for mousemove events */
+static bool view3d_ruler_item_mousemove(bContext *C, RulerInfo *ruler_info, const int mval[2], const bool do_snap)
+{
+ RulerItem *ruler_item = ruler_item_active_get(ruler_info);
+
+ if (ruler_item) {
+ float *co = ruler_item->co[ruler_item->co_index];
+ view3d_ruler_item_project(ruler_info, co, mval);
+ if (do_snap) {
+ const float mval_fl[2] = {UNPACK2(mval)};
+ ED_view3d_snap_co(C, co, mval_fl, true, true, true);
+ }
+ return true;
+ }
+ else {
+ return false;
+ }
+}
+
+static void view3d_ruler_header_update(ScrArea *sa)
+{
+ const char *text = "Ctrl+LMB: Add, "
+ "Del: Remove, "
+ "Ctrl+Drag: Snap, "
+ "Ctrl+C: Copy Value, "
+ "Enter: Store, "
+ "Esc: Cancel";
+
+ ED_area_headerprint(sa, text);
+}
+
+/* -------------------------------------------------------------------- */
+/* Operator callbacks */
+
+static int view3d_ruler_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
+{
+ wmWindow *win = CTX_wm_window(C);
+ ScrArea *sa = CTX_wm_area(C);
+ ARegion *ar = CTX_wm_region(C);
+ RulerInfo *ruler_info;
+
+ ruler_info = MEM_callocN(sizeof(RulerInfo), "RulerInfo");
+
+ if (view3d_ruler_from_gpencil(C, ruler_info)) {
+ WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, NULL);
+ }
+
+ op->customdata = ruler_info;
+
+ ruler_info->ar = ar;
+ ruler_info->draw_handle_pixel = ED_region_draw_cb_activate(ar->type, ruler_info_draw_pixel,
+ ruler_info, REGION_DRAW_POST_PIXEL);
+
+ view3d_ruler_header_update(sa);
+
+ WM_cursor_modal(win, BC_CROSSCURSOR);
+ WM_event_add_modal_handler(C, op);
+
+ return OPERATOR_RUNNING_MODAL;
+}
+
+static int view3d_ruler_cancel(bContext *C, wmOperator *op)
+{
+ RulerInfo *ruler_info = op->customdata;
+
+ view3d_ruler_end(C, ruler_info);
+ view3d_ruler_free(ruler_info);
+ op->customdata = NULL;
+
+ return OPERATOR_CANCELLED;
+}
+
+static int view3d_ruler_modal(bContext *C, wmOperator *op, const wmEvent *event)
+{
+ bool do_draw = false;
+ int exit_code = OPERATOR_RUNNING_MODAL;
+ RulerInfo *ruler_info = op->customdata;
+ ARegion *ar = ruler_info->ar;
+ RegionView3D *rv3d = ar->regiondata;
+
+ (void)C;
+
+ switch (event->type) {
+ case LEFTMOUSE:
+ if (event->val == KM_RELEASE) {
+ if (ruler_info->state == RULER_STATE_DRAG) {
+ /* rubber-band angle removal */
+ RulerItem *ruler_item = ruler_item_active_get(ruler_info);
+ if (ruler_item && (ruler_item->co_index == 1) && (ruler_item->flag & RULERITEM_USE_ANGLE)) {
+ if (!BLI_rcti_isect_pt_v(&ar->winrct, &event->x)) {
+ ruler_item->flag &= ~RULERITEM_USE_ANGLE;
+ do_draw = true;
+ }
+ }
+ ruler_info->state = RULER_STATE_NORMAL;
+ }
+ }
+ else {
+ if (ruler_info->state == RULER_STATE_NORMAL) {
+
+ if (event->ctrl ||
+ /* weak - but user friendly */
+ (ruler_info->items.first == NULL))
+ {
+ /* Create new line */
+ RulerItem *ruler_item;
+ /* check if we want to drag an existing point or add a new one */
+ ruler_info->state = RULER_STATE_DRAG;
+
+ ruler_item = ruler_item_add(ruler_info);
+ ruler_item_active_set(ruler_info, ruler_item);
+
+ negate_v3_v3(ruler_item->co[0], rv3d->ofs);
+ view3d_ruler_item_project(ruler_info, ruler_item->co[0], event->mval);
+
+ /* snap the first point added, not essential but handy */
+ {
+ ruler_item->co_index = 0;
+ view3d_ruler_item_mousemove(C, ruler_info, event->mval, true);
+ }
+
+ copy_v3_v3(ruler_item->co[2], ruler_item->co[0]);
+ ruler_item->co_index = 2;
+
+ do_draw = true;
+ }
+ else {
+ float mval_fl[2] = {UNPACK2(event->mval)};
+ RulerItem *ruler_item_pick;
+ int co_index;
+
+ /* select and drag */
+ if (view3d_ruler_pick(ruler_info, mval_fl, &ruler_item_pick, &co_index)) {
+ if (co_index == -1) {
+ if ((ruler_item_pick->flag & RULERITEM_USE_ANGLE) == 0) {
+ /* Add Center Point */
+ ruler_item_active_set(ruler_info, ruler_item_pick);
+ ruler_item_pick->flag |= RULERITEM_USE_ANGLE;
+ ruler_item_pick->co_index = 1;
+ ruler_info->state = RULER_STATE_DRAG;
+
+ /* find the factor */
+ {
+ float co_ss[2][2];
+ float fac;
+
+ ED_view3d_project_float_global(ar, ruler_item_pick->co[0], co_ss[0], V3D_PROJ_TEST_NOP);
+ ED_view3d_project_float_global(ar, ruler_item_pick->co[2], co_ss[1], V3D_PROJ_TEST_NOP);
+
+ fac = line_point_factor_v2(mval_fl, co_ss[0], co_ss[1]);
+ CLAMP(fac, 0.0f, 1.0f);
+
+ interp_v3_v3v3(ruler_item_pick->co[1],
+ ruler_item_pick->co[0],
+ ruler_item_pick->co[2], fac);
+ }
+
+ /* update the new location */
+ view3d_ruler_item_mousemove(C, ruler_info, event->mval, event->ctrl != 0);
+ do_draw = true;
+ }
+ }
+ else {
+ ruler_item_active_set(ruler_info, ruler_item_pick);
+ ruler_item_pick->co_index = co_index;
+ ruler_info->state = RULER_STATE_DRAG;
+ do_draw = true;
+ }
+ }
+ else {
+ exit_code = OPERATOR_PASS_THROUGH;
+ }
+
+ }
+ }
+ }
+ break;
+ case CKEY:
+ {
+ if (event->ctrl) {
+ RulerItem *ruler_item = ruler_item_active_get(ruler_info);
+ if (ruler_item) {
+ const int prec = 8;
+ char numstr[256];
+ Scene *scene = CTX_data_scene(C);
+ UnitSettings *unit = &scene->unit;
+
+ ruler_item_as_string(ruler_item, unit, numstr, sizeof(numstr), prec);
+ WM_clipboard_text_set((void *) numstr, false);
+ }
+ }
+ }
+ case RIGHTCTRLKEY:
+ case LEFTCTRLKEY:
+ {
+ WM_event_add_mousemove(C);
+ break;
+ }
+ case MOUSEMOVE:
+ {
+ if (ruler_info->state == RULER_STATE_DRAG) {
+ if (view3d_ruler_item_mousemove(C, ruler_info, event->mval, event->ctrl != 0)) {
+ do_draw = true;
+ }
+ }
+ break;
+ }
+ case ESCKEY:
+ {
+ do_draw = true;
+ exit_code = OPERATOR_CANCELLED;
+ break;
+ }
+ case RETKEY:
+ {
+ view3d_ruler_to_gpencil(C, ruler_info);
+ do_draw = true;
+ exit_code = OPERATOR_FINISHED;
+ break;
+ }
+ case DELKEY:
+ {
+ if (event->val == KM_PRESS) {
+ if (ruler_info->state == RULER_STATE_NORMAL) {
+ RulerItem *ruler_item = ruler_item_active_get(ruler_info);
+ if (ruler_item) {
+ ruler_item_remove(ruler_info, ruler_item);
+ ruler_info->item_active = -1;
+ do_draw = true;
+ }
+ }
+ }
+ break;
+ }
+ default:
+ exit_code = OPERATOR_PASS_THROUGH;
+ break;
+
+ }
+
+ if (do_draw) {
+ ScrArea *sa = CTX_wm_area(C);
+
+ view3d_ruler_header_update(sa);
+
+ /* all 3d views draw rulers */
+ WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, NULL);
+ }
+
+ if (ELEM(exit_code, OPERATOR_FINISHED, OPERATOR_CANCELLED)) {
+ wmWindow *win = CTX_wm_window(C);
+ ScrArea *sa = CTX_wm_area(C);
+
+ WM_cursor_restore(win);
+
+ view3d_ruler_end(C, ruler_info);
+ view3d_ruler_free(ruler_info);
+ op->customdata = NULL;
+
+ ED_area_headerprint(sa, NULL);
+ }
+
+ return exit_code;
+}
+
+void VIEW3D_OT_ruler(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "3D Ruler & Protractor";
+ ot->description = "Interactive ruler";
+ ot->idname = "VIEW3D_OT_ruler";
+
+ /* api callbacks */
+ ot->invoke = view3d_ruler_invoke;
+ ot->cancel = view3d_ruler_cancel;
+ ot->modal = view3d_ruler_modal;
+ ot->poll = ED_operator_view3d_active;
+
+ /* flags */
+ ot->flag = 0;
+}
diff --git a/source/blender/editors/space_view3d/view3d_select.c b/source/blender/editors/space_view3d/view3d_select.c
index 24260898066..b441e48f59d 100644
--- a/source/blender/editors/space_view3d/view3d_select.c
+++ b/source/blender/editors/space_view3d/view3d_select.c
@@ -108,23 +108,23 @@ void view3d_set_viewcontext(bContext *C, ViewContext *vc)
vc->obedit = CTX_data_edit_object(C);
}
-int view3d_get_view_aligned_coordinate(ViewContext *vc, float fp[3], const int mval[2], const short do_fallback)
+/**
+ * Re-project \a fp so it stays on the same view-plane but is under \a mval (normally the cursor location).
+ */
+bool view3d_get_view_aligned_coordinate(ARegion *ar, float fp[3], const int mval[2], const bool do_fallback)
{
+ RegionView3D *rv3d = ar->regiondata;
float dvec[3];
int mval_cpy[2];
eV3DProjStatus ret;
- mval_cpy[0] = mval[0];
- mval_cpy[1] = mval[1];
-
- ret = ED_view3d_project_int_global(vc->ar, fp, mval_cpy, V3D_PROJ_TEST_NOP);
-
- initgrabz(vc->rv3d, fp[0], fp[1], fp[2]);
+ ret = ED_view3d_project_int_global(ar, fp, mval_cpy, V3D_PROJ_TEST_NOP);
if (ret == V3D_PROJ_RET_OK) {
const float mval_f[2] = {(float)(mval_cpy[0] - mval[0]),
(float)(mval_cpy[1] - mval[1])};
- ED_view3d_win_to_delta(vc->ar, mval_f, dvec);
+ const float zfac = ED_view3d_calc_zfac(rv3d, fp, NULL);
+ ED_view3d_win_to_delta(ar, mval_f, dvec, zfac);
sub_v3_v3(fp, dvec);
return TRUE;
@@ -132,11 +132,11 @@ int view3d_get_view_aligned_coordinate(ViewContext *vc, float fp[3], const int m
else {
/* fallback to the view center */
if (do_fallback) {
- negate_v3_v3(fp, vc->rv3d->ofs);
- return view3d_get_view_aligned_coordinate(vc, fp, mval, FALSE);
+ negate_v3_v3(fp, rv3d->ofs);
+ return view3d_get_view_aligned_coordinate(ar, fp, mval, false);
}
else {
- return FALSE;
+ return false;
}
}
}
@@ -177,10 +177,9 @@ static void edbm_backbuf_check_and_select_verts(BMEditMesh *em, int select)
{
BMVert *eve;
BMIter iter;
- int index = bm_wireoffs;
+ unsigned int index = bm_wireoffs;
- eve = BM_iter_new(&iter, em->bm, BM_VERTS_OF_MESH, NULL);
- for (; eve; eve = BM_iter_step(&iter), index++) {
+ for (eve = BM_iter_new(&iter, em->bm, BM_VERTS_OF_MESH, NULL); eve; eve = BM_iter_step(&iter), index++) {
if (!BM_elem_flag_test(eve, BM_ELEM_HIDDEN)) {
if (EDBM_backbuf_check(index)) {
BM_vert_select_set(em->bm, eve, select);
@@ -209,7 +208,7 @@ static void edbm_backbuf_check_and_select_faces(BMEditMesh *em, int select)
{
BMFace *efa;
BMIter iter;
- int index = 1;
+ unsigned int index = 1;
efa = BM_iter_new(&iter, em->bm, BM_FACES_OF_MESH, NULL);
for (; efa; efa = BM_iter_step(&iter), index++) {
@@ -226,11 +225,11 @@ static void edbm_backbuf_check_and_select_faces(BMEditMesh *em, int select)
static void edbm_backbuf_check_and_select_verts_obmode(Mesh *me, int select)
{
MVert *mv = me->mvert;
- int a;
+ unsigned int index;
if (mv) {
- for (a = 1; a <= me->totvert; a++, mv++) {
- if (EDBM_backbuf_check(a)) {
+ for (index = 1; index <= me->totvert; index++, mv++) {
+ if (EDBM_backbuf_check(index)) {
if (!(mv->flag & ME_HIDE)) {
mv->flag = select ? (mv->flag | SELECT) : (mv->flag & ~SELECT);
}
@@ -243,11 +242,11 @@ static void edbm_backbuf_check_and_select_verts_obmode(Mesh *me, int select)
static void edbm_backbuf_check_and_select_tfaces(Mesh *me, int select)
{
MPoly *mpoly = me->mpoly;
- int a;
+ unsigned int index;
if (mpoly) {
- for (a = 1; a <= me->totpoly; a++, mpoly++) {
- if (EDBM_backbuf_check(a)) {
+ for (index = 1; index <= me->totpoly; index++, mpoly++) {
+ if (EDBM_backbuf_check(index)) {
mpoly->flag = select ? (mpoly->flag | ME_FACE_SEL) : (mpoly->flag & ~ME_FACE_SEL);
}
}
@@ -733,7 +732,7 @@ static void do_lasso_select_meta(ViewContext *vc, const int mcords[][2], short m
MetaBall *mb = (MetaBall *)vc->obedit->data;
if (extend == 0 && select)
- BKE_mball_deselect_all(mb);
+ BKE_mball_deselect_all(mb);
BLI_lasso_boundbox(&rect, mcords, moves);
@@ -780,9 +779,6 @@ static void do_lasso_select_paintvert(ViewContext *vc, const int mcords[][2], sh
}
else {
LassoSelectUserData data;
- rcti rect;
-
- BLI_lasso_boundbox(&rect, mcords, moves);
view3d_userdata_lassoselect_init(&data, vc, &rect, mcords, moves, select);
@@ -1054,7 +1050,7 @@ static int object_select_menu_exec(bContext *C, wmOperator *op)
CTX_DATA_BEGIN (C, Base *, base, selectable_bases)
{
/* this is a bit dodjy, there should only be ONE object with this name, but library objects can mess this up */
- if (strcmp(name, base->object->id.name + 2) == 0) {
+ if (STREQ(name, base->object->id.name + 2)) {
ED_base_object_activate(C, base);
ED_base_object_select(base, BA_SELECT);
changed = 1;
@@ -2230,7 +2226,7 @@ static int mouse_weight_paint_vertex_select(bContext *C, const int mval[2], shor
/* ****** Mouse Select ****** */
-static int view3d_select_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int view3d_select_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
Object *obedit = CTX_data_edit_object(C);
Object *obact = CTX_data_active_object(C);
diff --git a/source/blender/editors/space_view3d/view3d_toolbar.c b/source/blender/editors/space_view3d/view3d_toolbar.c
index bb5b7aa6911..d3bf8a30792 100644
--- a/source/blender/editors/space_view3d/view3d_toolbar.c
+++ b/source/blender/editors/space_view3d/view3d_toolbar.c
@@ -156,7 +156,7 @@ static void operator_search_cb(const struct bContext *C, void *UNUSED(arg), cons
{
GHashIterator *iter = WM_operatortype_iter();
- for (; !BLI_ghashIterator_isDone(iter); BLI_ghashIterator_step(iter)) {
+ for (; BLI_ghashIterator_notDone(iter); BLI_ghashIterator_step(iter)) {
wmOperatorType *ot = BLI_ghashIterator_getValue(iter);
if (BLI_strcasestr(ot->name, str)) {
diff --git a/source/blender/editors/space_view3d/view3d_view.c b/source/blender/editors/space_view3d/view3d_view.c
index fba1ce328ba..b2e10fa8457 100644
--- a/source/blender/editors/space_view3d/view3d_view.c
+++ b/source/blender/editors/space_view3d/view3d_view.c
@@ -294,7 +294,7 @@ void view3d_smooth_view(bContext *C, View3D *v3d, ARegion *ar, Object *oldcamera
}
/* only meant for timer usage */
-static int view3d_smoothview_invoke(bContext *C, wmOperator *UNUSED(op), wmEvent *event)
+static int view3d_smoothview_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *event)
{
View3D *v3d = CTX_wm_view3d(C);
RegionView3D *rv3d = CTX_wm_region_view3d(C);
@@ -667,22 +667,29 @@ void ED_view3d_depth_tag_update(RegionView3D *rv3d)
}
/* copies logic of get_view3d_viewplane(), keep in sync */
-int ED_view3d_clip_range_get(View3D *v3d, RegionView3D *rv3d, float *clipsta, float *clipend)
+bool ED_view3d_clip_range_get(View3D *v3d, RegionView3D *rv3d, float *r_clipsta, float *r_clipend,
+ const bool use_ortho_factor)
{
CameraParams params;
BKE_camera_params_init(&params);
BKE_camera_params_from_view3d(&params, v3d, rv3d);
- if (clipsta) *clipsta = params.clipsta;
- if (clipend) *clipend = params.clipend;
+ if (use_ortho_factor && params.is_ortho) {
+ const float fac = 2.0f / (params.clipend - params.clipsta);
+ params.clipsta *= fac;
+ params.clipend *= fac;
+ }
+
+ if (r_clipsta) *r_clipsta = params.clipsta;
+ if (r_clipend) *r_clipend = params.clipend;
return params.is_ortho;
}
/* also exposed in previewrender.c */
-int ED_view3d_viewplane_get(View3D *v3d, RegionView3D *rv3d, int winx, int winy,
- rctf *viewplane, float *clipsta, float *clipend)
+bool ED_view3d_viewplane_get(View3D *v3d, RegionView3D *rv3d, int winx, int winy,
+ rctf *r_viewplane, float *r_clipsta, float *r_clipend)
{
CameraParams params;
@@ -690,9 +697,9 @@ int ED_view3d_viewplane_get(View3D *v3d, RegionView3D *rv3d, int winx, int winy,
BKE_camera_params_from_view3d(&params, v3d, rv3d);
BKE_camera_params_compute_viewplane(&params, winx, winy, 1.0f, 1.0f);
- if (viewplane) *viewplane = params.viewplane;
- if (clipsta) *clipsta = params.clipsta;
- if (clipend) *clipend = params.clipend;
+ if (r_viewplane) *r_viewplane = params.viewplane;
+ if (r_clipsta) *r_clipsta = params.clipsta;
+ if (r_clipend) *r_clipend = params.clipend;
return params.is_ortho;
}
@@ -791,7 +798,7 @@ static void obmat_to_viewmat(View3D *v3d, RegionView3D *rv3d, Object *ob, short
#define QUATSET(a, b, c, d, e) { a[0] = b; a[1] = c; a[2] = d; a[3] = e; } (void)0
-int ED_view3d_lock(RegionView3D *rv3d)
+bool ED_view3d_lock(RegionView3D *rv3d)
{
switch (rv3d->view) {
case RV3D_VIEW_BOTTOM:
@@ -818,10 +825,10 @@ int ED_view3d_lock(RegionView3D *rv3d)
QUATSET(rv3d->viewquat, 0.5, -0.5, -0.5, -0.5);
break;
default:
- return FALSE;
+ return false;
}
- return TRUE;
+ return true;
}
/* don't set windows active in here, is used by renderwin too */
@@ -863,7 +870,9 @@ void setviewmatrixview3d(Scene *scene, View3D *v3d, RegionView3D *rv3d)
copy_v3_v3(vec, give_cursor(scene, v3d));
translate_m4(rv3d->viewmat, -vec[0], -vec[1], -vec[2]);
}
- else translate_m4(rv3d->viewmat, rv3d->ofs[0], rv3d->ofs[1], rv3d->ofs[2]);
+ else {
+ translate_m4(rv3d->viewmat, rv3d->ofs[0], rv3d->ofs[1], rv3d->ofs[2]);
+ }
}
}
@@ -1558,11 +1567,7 @@ static void UNUSED_FUNCTION(view3d_align_axis_to_vector)(View3D *v3d, RegionView
float ED_view3d_pixel_size(RegionView3D *rv3d, const float co[3])
{
- return (rv3d->persmat[3][3] + (
- rv3d->persmat[0][3] * co[0] +
- rv3d->persmat[1][3] * co[1] +
- rv3d->persmat[2][3] * co[2])
- ) * rv3d->pixsize * U.pixelsize;
+ return mul_project_m4_v3_zfac(rv3d->persmat, co) * 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.c b/source/blender/editors/transform/transform.c
index c8874d13cac..64e49abd761 100644
--- a/source/blender/editors/transform/transform.c
+++ b/source/blender/editors/transform/transform.c
@@ -98,6 +98,8 @@
#include "transform.h"
+#define MAX_INFO_LEN 256
+
static void drawTransformApply(const struct bContext *C, ARegion *ar, void *arg);
static int doEdgeSlide(TransInfo *t, float perc);
static int doVertSlide(TransInfo *t, float perc);
@@ -183,7 +185,7 @@ void convertViewVec(TransInfo *t, float r_vec[3], int dx, int dy)
{
if ((t->spacetype == SPACE_VIEW3D) && (t->ar->regiontype == RGN_TYPE_WINDOW)) {
const float mval_f[2] = {(float)dx, (float)dy};
- ED_view3d_win_to_delta(t->ar, mval_f, r_vec);
+ ED_view3d_win_to_delta(t->ar, mval_f, r_vec, t->zfac);
}
else if (t->spacetype == SPACE_IMAGE) {
float aspx, aspy;
@@ -864,7 +866,7 @@ static void transform_event_xyz_constraint(TransInfo *t, short key_type, char cm
}
}
-int transformEvent(TransInfo *t, wmEvent *event)
+int transformEvent(TransInfo *t, const wmEvent *event)
{
float mati[3][3] = MAT3_UNITY;
char cmode = constraintModeToChar(t);
@@ -1298,7 +1300,9 @@ int transformEvent(TransInfo *t, wmEvent *event)
if (t->flag & T_AUTOIK) {
transform_autoik_update(t, 1);
}
- else view_editmove(event->type);
+ else {
+ view_editmove(event->type);
+ }
t->redraw = 1;
break;
case PADMINUS:
@@ -1313,7 +1317,9 @@ int transformEvent(TransInfo *t, wmEvent *event)
if (t->flag & T_AUTOIK) {
transform_autoik_update(t, -1);
}
- else view_editmove(event->type);
+ else {
+ view_editmove(event->type);
+ }
t->redraw = 1;
break;
case LEFTALTKEY:
@@ -1854,7 +1860,7 @@ void saveTransform(bContext *C, TransInfo *t, wmOperator *op)
}
/* note: caller needs to free 't' on a 0 return */
-int initTransform(bContext *C, TransInfo *t, wmOperator *op, wmEvent *event, int mode)
+int initTransform(bContext *C, TransInfo *t, wmOperator *op, const wmEvent *event, int mode)
{
int options = 0;
PropertyRNA *prop;
@@ -2654,11 +2660,12 @@ void initWarp(TransInfo *t)
mid_v3_v3v3(t->center, min, max);
- if (max[0] == min[0]) max[0] += 0.1f; /* not optimal, but flipping is better than invalid garbage (i.e. division by zero!) */
+ if (max[0] == min[0])
+ max[0] += 0.1f; /* not optimal, but flipping is better than invalid garbage (i.e. division by zero!) */
t->val = (max[0] - min[0]) / 2.0f; /* t->val is X dimension projected boundbox */
}
-int handleEventWarp(TransInfo *t, wmEvent *event)
+int handleEventWarp(TransInfo *t, const wmEvent *event)
{
int status = 0;
@@ -2681,7 +2688,7 @@ int Warp(TransInfo *t, const int UNUSED(mval[2]))
float vec[3], circumfac, dist, phi0, co, si, cursor[3], gcursor[3];
const float *curs;
int i;
- char str[50];
+ char str[MAX_INFO_LEN];
curs = give_cursor(t->scene, t->view);
/*
@@ -2716,13 +2723,13 @@ int Warp(TransInfo *t, const int UNUSED(mval[2]))
outputNumInput(&(t->num), c);
- sprintf(str, IFACE_("Warp: %s"), c);
+ BLI_snprintf(str, MAX_INFO_LEN, IFACE_("Warp: %s"), c);
circumfac = DEG2RADF(circumfac);
}
else {
/* default header print */
- sprintf(str, IFACE_("Warp: %.3f"), RAD2DEGF(circumfac));
+ BLI_snprintf(str, MAX_INFO_LEN, IFACE_("Warp: %.3f"), RAD2DEGF(circumfac));
}
t->values[0] = circumfac;
@@ -2799,7 +2806,7 @@ void initShear(TransInfo *t)
t->flag |= T_NO_CONSTRAINT;
}
-int handleEventShear(TransInfo *t, wmEvent *event)
+int handleEventShear(TransInfo *t, const wmEvent *event)
{
int status = 0;
@@ -2840,7 +2847,7 @@ int Shear(TransInfo *t, const int UNUSED(mval[2]))
float smat[3][3], tmat[3][3], totmat[3][3], persmat[3][3], persinv[3][3];
float value;
int i;
- char str[50];
+ char str[MAX_INFO_LEN];
copy_m3_m4(persmat, t->viewmat);
invert_m3_m3(persinv, persmat);
@@ -2857,11 +2864,11 @@ int Shear(TransInfo *t, const int UNUSED(mval[2]))
outputNumInput(&(t->num), c);
- sprintf(str, IFACE_("Shear: %s %s"), c, t->proptext);
+ BLI_snprintf(str, MAX_INFO_LEN, IFACE_("Shear: %s %s"), c, t->proptext);
}
else {
/* default header print */
- sprintf(str, IFACE_("Shear: %.3f %s (Press X or Y to set shear axis)"), value, t->proptext);
+ BLI_snprintf(str, MAX_INFO_LEN, IFACE_("Shear: %.3f %s (Press X or Y to set shear axis)"), value, t->proptext);
}
t->values[0] = value;
@@ -2937,10 +2944,11 @@ void initResize(TransInfo *t)
t->num.increment = t->snap[1];
}
+/* We assume str is MAX_INFO_LEN long. */
static void headerResize(TransInfo *t, float vec[3], char *str)
{
char tvec[NUM_STR_REP_LEN * 3];
- char *spos = str;
+ size_t ofs = 0;
if (hasNumInput(&t->num)) {
outputNumInput(&(t->num), tvec);
}
@@ -2949,37 +2957,36 @@ static void headerResize(TransInfo *t, float vec[3], char *str)
BLI_snprintf(&tvec[NUM_STR_REP_LEN], NUM_STR_REP_LEN, "%.4f", vec[1]);
BLI_snprintf(&tvec[NUM_STR_REP_LEN * 2], NUM_STR_REP_LEN, "%.4f", vec[2]);
}
-
+
if (t->con.mode & CON_APPLY) {
switch (t->num.idx_max) {
case 0:
- spos += sprintf(spos, IFACE_("Scale: %s%s %s"), &tvec[0], t->con.text, t->proptext);
+ ofs += BLI_snprintf(str + ofs, MAX_INFO_LEN - ofs, IFACE_("Scale: %s%s %s"),
+ &tvec[0], t->con.text, t->proptext);
break;
case 1:
- spos += sprintf(spos, IFACE_("Scale: %s : %s%s %s"), &tvec[0], &tvec[NUM_STR_REP_LEN],
- t->con.text, t->proptext);
+ ofs += BLI_snprintf(str + ofs, MAX_INFO_LEN - ofs, IFACE_("Scale: %s : %s%s %s"),
+ &tvec[0], &tvec[NUM_STR_REP_LEN], t->con.text, t->proptext);
break;
case 2:
- spos += sprintf(spos, IFACE_("Scale: %s : %s : %s%s %s"), &tvec[0], &tvec[NUM_STR_REP_LEN],
- &tvec[NUM_STR_REP_LEN * 2], t->con.text, t->proptext);
+ ofs += BLI_snprintf(str + ofs, MAX_INFO_LEN - ofs, IFACE_("Scale: %s : %s : %s%s %s"), &tvec[0],
+ &tvec[NUM_STR_REP_LEN], &tvec[NUM_STR_REP_LEN * 2], t->con.text, t->proptext);
}
}
else {
if (t->flag & T_2D_EDIT) {
- spos += sprintf(spos, IFACE_("Scale X: %s Y: %s%s %s"), &tvec[0], &tvec[NUM_STR_REP_LEN],
- t->con.text, t->proptext);
+ ofs += BLI_snprintf(str + ofs, MAX_INFO_LEN - ofs, IFACE_("Scale X: %s Y: %s%s %s"),
+ &tvec[0], &tvec[NUM_STR_REP_LEN], t->con.text, t->proptext);
}
else {
- spos += sprintf(spos, IFACE_("Scale X: %s Y: %s Z: %s%s %s"), &tvec[0], &tvec[NUM_STR_REP_LEN],
- &tvec[NUM_STR_REP_LEN * 2], t->con.text, t->proptext);
+ ofs += BLI_snprintf(str + ofs, MAX_INFO_LEN - ofs, IFACE_("Scale X: %s Y: %s Z: %s%s %s"),
+ &tvec[0], &tvec[NUM_STR_REP_LEN], &tvec[NUM_STR_REP_LEN * 2], t->con.text, t->proptext);
}
}
-
+
if (t->flag & (T_PROP_EDIT | T_PROP_CONNECTED)) {
- spos += sprintf(spos, IFACE_(" Proportional size: %.2f"), t->prop_size);
+ ofs += BLI_snprintf(str + ofs, MAX_INFO_LEN - ofs, IFACE_(" Proportional size: %.2f"), t->prop_size);
}
-
- (void)spos;
}
/* FLT_EPSILON is too small [#29633], 0.0000001f starts to flip */
@@ -3114,7 +3121,7 @@ int Resize(TransInfo *t, const int mval[2])
float size[3], mat[3][3];
float ratio;
int i;
- char str[200];
+ char str[MAX_INFO_LEN];
/* for manipulator, center handle, the scaling can't be done relative to center */
if ((t->flag & T_USES_MANIPULATOR) && t->con.mode == 0) {
@@ -3219,7 +3226,7 @@ int SkinResize(TransInfo *t, const int UNUSED(mval[2]))
float size[3], mat[3][3];
float ratio;
int i;
- char str[200];
+ char str[MAX_INFO_LEN];
ratio = t->values[0];
size[0] = size[1] = size[2] = ratio;
@@ -3313,7 +3320,7 @@ int ToSphere(TransInfo *t, const int UNUSED(mval[2]))
float vec[3];
float ratio, radius;
int i;
- char str[64];
+ char str[MAX_INFO_LEN];
TransData *td = t->data;
ratio = t->values[0];
@@ -3335,11 +3342,11 @@ int ToSphere(TransInfo *t, const int UNUSED(mval[2]))
outputNumInput(&(t->num), c);
- sprintf(str, IFACE_("To Sphere: %s %s"), c, t->proptext);
+ BLI_snprintf(str, MAX_INFO_LEN, IFACE_("To Sphere: %s %s"), c, t->proptext);
}
else {
/* default header print */
- sprintf(str, IFACE_("To Sphere: %.4f %s"), ratio, t->proptext);
+ BLI_snprintf(str, MAX_INFO_LEN, IFACE_("To Sphere: %.4f %s"), ratio, t->proptext);
}
@@ -3528,7 +3535,8 @@ static void ElementRotation(TransInfo *t, TransData *td, float mat[3][3], short
quat_to_axis_angle(td->ext->rotAxis, td->ext->rotAngle, tquat);
/* this function works on end result */
- protectedAxisAngleBits(td->protectflag, td->ext->rotAxis, td->ext->rotAngle, td->ext->irotAxis, td->ext->irotAngle);
+ protectedAxisAngleBits(td->protectflag, td->ext->rotAxis, td->ext->rotAngle, td->ext->irotAxis,
+ td->ext->irotAngle);
}
else {
float eulmat[3][3];
@@ -3575,12 +3583,15 @@ static void ElementRotation(TransInfo *t, TransData *td, float mat[3][3], short
if ((t->flag & T_V3D_ALIGN) == 0) { // align mode doesn't rotate objects itself
/* euler or quaternion? */
if ((td->ext->rotOrder == ROT_MODE_QUAT) || (td->flag & TD_USEQUAT)) {
- mul_serie_m3(fmat, td->mtx, mat, td->smtx, NULL, NULL, NULL, NULL, NULL);
- mat3_to_quat(quat, fmat); // Actual transform
-
- mul_qt_qtqt(td->ext->quat, quat, td->ext->iquat);
- /* this function works on end result */
- protectedQuaternionBits(td->protectflag, td->ext->quat, td->ext->iquat);
+ /* can be called for texture space translate for example, then opt out */
+ if (td->ext->quat) {
+ mul_serie_m3(fmat, td->mtx, mat, td->smtx, NULL, NULL, NULL, NULL, NULL);
+ mat3_to_quat(quat, fmat); // Actual transform
+
+ mul_qt_qtqt(td->ext->quat, quat, td->ext->iquat);
+ /* this function works on end result */
+ protectedQuaternionBits(td->protectflag, td->ext->quat, td->ext->iquat);
+ }
}
else if (td->ext->rotOrder == ROT_MODE_AXISANGLE) {
/* calculate effect based on quats */
@@ -3595,7 +3606,8 @@ static void ElementRotation(TransInfo *t, TransData *td, float mat[3][3], short
quat_to_axis_angle(td->ext->rotAxis, td->ext->rotAngle, tquat);
/* this function works on end result */
- protectedAxisAngleBits(td->protectflag, td->ext->rotAxis, td->ext->rotAngle, td->ext->irotAxis, td->ext->irotAngle);
+ protectedAxisAngleBits(td->protectflag, td->ext->rotAxis, td->ext->rotAngle, td->ext->irotAxis,
+ td->ext->irotAngle);
}
else {
float obmat[3][3];
@@ -3654,14 +3666,15 @@ static void applyRotation(TransInfo *t, float angle, float axis[3])
int Rotation(TransInfo *t, const int UNUSED(mval[2]))
{
- char str[128], *spos = str;
-
+ char str[MAX_INFO_LEN];
+ size_t ofs = 0;
+
float final;
final = t->values[0];
-
+
snapGrid(t, &final);
-
+
if ((t->con.mode & CON_APPLY) && t->con.applyRot) {
t->con.applyRot(t, NULL, t->axis, NULL);
}
@@ -3669,9 +3682,9 @@ int Rotation(TransInfo *t, const int UNUSED(mval[2]))
/* reset axis if constraint is not set */
copy_v3_v3(t->axis, t->axis_orig);
}
-
+
applySnapping(t, &final);
-
+
if (hasNumInput(&t->num)) {
char c[NUM_STR_REP_LEN];
@@ -3679,19 +3692,19 @@ int Rotation(TransInfo *t, const int UNUSED(mval[2]))
outputNumInput(&(t->num), c);
- spos += sprintf(spos, IFACE_("Rot: %s %s %s"), &c[0], t->con.text, t->proptext);
+ ofs += BLI_snprintf(str + ofs, MAX_INFO_LEN - ofs, IFACE_("Rot: %s %s %s"), &c[0], t->con.text, t->proptext);
/* Clamp between -180 and 180 */
final = angle_wrap_rad(DEG2RADF(final));
}
else {
- spos += sprintf(spos, IFACE_("Rot: %.2f%s %s"), RAD2DEGF(final), t->con.text, t->proptext);
+ ofs += BLI_snprintf(str + ofs, MAX_INFO_LEN - ofs, IFACE_("Rot: %.2f%s %s"),
+ RAD2DEGF(final), t->con.text, t->proptext);
}
if (t->flag & (T_PROP_EDIT | T_PROP_CONNECTED)) {
- spos += sprintf(spos, IFACE_(" Proportional size: %.2f"), t->prop_size);
+ ofs += BLI_snprintf(str + ofs, MAX_INFO_LEN - ofs, IFACE_(" Proportional size: %.2f"), t->prop_size);
}
- (void)spos;
t->values[0] = final;
@@ -3756,7 +3769,8 @@ static void applyTrackball(TransInfo *t, float axis1[3], float axis2[3], float a
int Trackball(TransInfo *t, const int UNUSED(mval[2]))
{
- char str[128], *spos = str;
+ char str[MAX_INFO_LEN];
+ size_t ofs = 0;
float axis1[3], axis2[3];
float mat[3][3], totmat[3][3], smat[3][3];
float phi[2];
@@ -3778,19 +3792,20 @@ int Trackball(TransInfo *t, const int UNUSED(mval[2]))
outputNumInput(&(t->num), c);
- spos += sprintf(spos, IFACE_("Trackball: %s %s %s"), &c[0], &c[NUM_STR_REP_LEN], t->proptext);
+ ofs += BLI_snprintf(str + ofs, MAX_INFO_LEN - ofs, IFACE_("Trackball: %s %s %s"),
+ &c[0], &c[NUM_STR_REP_LEN], t->proptext);
phi[0] = DEG2RADF(phi[0]);
phi[1] = DEG2RADF(phi[1]);
}
else {
- spos += sprintf(spos, IFACE_("Trackball: %.2f %.2f %s"), RAD2DEGF(phi[0]), RAD2DEGF(phi[1]), t->proptext);
+ ofs += BLI_snprintf(str + ofs, MAX_INFO_LEN - ofs, IFACE_("Trackball: %.2f %.2f %s"),
+ RAD2DEGF(phi[0]), RAD2DEGF(phi[1]), t->proptext);
}
if (t->flag & (T_PROP_EDIT | T_PROP_CONNECTED)) {
- spos += sprintf(spos, IFACE_(" Proportional size: %.2f"), t->prop_size);
+ ofs += BLI_snprintf(str + ofs, MAX_INFO_LEN - ofs, IFACE_(" Proportional size: %.2f"), t->prop_size);
}
- (void)spos;
vec_rot_to_mat3(smat, axis1, phi[0]);
vec_rot_to_mat3(totmat, axis2, phi[1]);
@@ -3854,9 +3869,10 @@ void initTranslation(TransInfo *t)
t->num.increment = t->snap[1];
}
+/* We assume str is MAX_INFO_LEN long. */
static void headerTranslation(TransInfo *t, float vec[3], char *str)
{
- char *spos = str;
+ size_t ofs = 0;
char tvec[NUM_STR_REP_LEN * 3];
char distvec[NUM_STR_REP_LEN];
char autoik[NUM_STR_REP_LEN];
@@ -3877,29 +3893,30 @@ static void headerTranslation(TransInfo *t, float vec[3], char *str)
int i, do_split = t->scene->unit.flag & USER_UNIT_OPT_SPLIT ? 1 : 0;
for (i = 0; i < 3; i++) {
- bUnit_AsString(&tvec[i * NUM_STR_REP_LEN], NUM_STR_REP_LEN, dvec[i] * t->scene->unit.scale_length,
+ bUnit_AsString(&tvec[NUM_STR_REP_LEN * i], NUM_STR_REP_LEN, dvec[i] * t->scene->unit.scale_length,
4, t->scene->unit.system, B_UNIT_LENGTH, do_split, 1);
}
}
else {
- sprintf(&tvec[0], "%.4f", dvec[0]);
- sprintf(&tvec[NUM_STR_REP_LEN], "%.4f", dvec[1]);
- sprintf(&tvec[NUM_STR_REP_LEN * 2], "%.4f", dvec[2]);
+ BLI_snprintf(&tvec[0], NUM_STR_REP_LEN, "%.4f", dvec[0]);
+ BLI_snprintf(&tvec[NUM_STR_REP_LEN], NUM_STR_REP_LEN, "%.4f", dvec[1]);
+ BLI_snprintf(&tvec[NUM_STR_REP_LEN * 2], NUM_STR_REP_LEN, "%.4f", dvec[2]);
}
}
if (!(t->flag & T_2D_EDIT) && t->scene->unit.system)
- bUnit_AsString(distvec, sizeof(distvec), dist * t->scene->unit.scale_length, 4, t->scene->unit.system, B_UNIT_LENGTH, t->scene->unit.flag & USER_UNIT_OPT_SPLIT, 0);
+ bUnit_AsString(distvec, sizeof(distvec), dist * t->scene->unit.scale_length, 4, t->scene->unit.system,
+ B_UNIT_LENGTH, t->scene->unit.flag & USER_UNIT_OPT_SPLIT, 0);
else if (dist > 1e10f || dist < -1e10f) /* prevent string buffer overflow */
- sprintf(distvec, "%.4e", dist);
+ BLI_snprintf(distvec, NUM_STR_REP_LEN, "%.4e", dist);
else
- sprintf(distvec, "%.4f", dist);
+ BLI_snprintf(distvec, NUM_STR_REP_LEN, "%.4f", dist);
if (t->flag & T_AUTOIK) {
short chainlen = t->settings->autoik_chainlen;
if (chainlen)
- sprintf(autoik, IFACE_("AutoIK-Len: %d"), chainlen);
+ BLI_snprintf(autoik, NUM_STR_REP_LEN, IFACE_("AutoIK-Len: %d"), chainlen);
else
autoik[0] = '\0';
}
@@ -3909,32 +3926,34 @@ static void headerTranslation(TransInfo *t, float vec[3], char *str)
if (t->con.mode & CON_APPLY) {
switch (t->num.idx_max) {
case 0:
- spos += sprintf(spos, "D: %s (%s)%s %s %s", &tvec[0], distvec, t->con.text, t->proptext, &autoik[0]);
+ ofs += BLI_snprintf(str + ofs, MAX_INFO_LEN - ofs, "D: %s (%s)%s %s %s",
+ &tvec[0], distvec, t->con.text, t->proptext, autoik);
break;
case 1:
- spos += sprintf(spos, "D: %s D: %s (%s)%s %s %s", &tvec[0], &tvec[NUM_STR_REP_LEN],
- distvec, t->con.text, t->proptext, &autoik[0]);
+ ofs += BLI_snprintf(str + ofs, MAX_INFO_LEN - ofs, "D: %s D: %s (%s)%s %s %s",
+ &tvec[0], &tvec[NUM_STR_REP_LEN], distvec, t->con.text, t->proptext, autoik);
break;
case 2:
- spos += sprintf(spos, "D: %s D: %s D: %s (%s)%s %s %s", &tvec[0], &tvec[NUM_STR_REP_LEN],
- &tvec[NUM_STR_REP_LEN * 2], distvec, t->con.text, t->proptext, &autoik[0]);
+ ofs += BLI_snprintf(str + ofs, MAX_INFO_LEN - ofs, "D: %s D: %s D: %s (%s)%s %s %s",
+ &tvec[0], &tvec[NUM_STR_REP_LEN], &tvec[NUM_STR_REP_LEN * 2], distvec,
+ t->con.text, t->proptext, autoik);
}
}
else {
if (t->flag & T_2D_EDIT) {
- spos += sprintf(spos, "Dx: %s Dy: %s (%s)%s %s", &tvec[0], &tvec[NUM_STR_REP_LEN],
- distvec, t->con.text, t->proptext);
+ ofs += BLI_snprintf(str + ofs, MAX_INFO_LEN - ofs, "Dx: %s Dy: %s (%s)%s %s",
+ &tvec[0], &tvec[NUM_STR_REP_LEN], distvec, t->con.text, t->proptext);
}
else {
- spos += sprintf(spos, "Dx: %s Dy: %s Dz: %s (%s)%s %s %s", &tvec[0], &tvec[NUM_STR_REP_LEN],
- &tvec[NUM_STR_REP_LEN * 2], distvec, t->con.text, t->proptext, &autoik[0]);
+ ofs += BLI_snprintf(str + ofs, MAX_INFO_LEN - ofs, "Dx: %s Dy: %s Dz: %s (%s)%s %s %s",
+ &tvec[0], &tvec[NUM_STR_REP_LEN], &tvec[NUM_STR_REP_LEN * 2], distvec, t->con.text,
+ t->proptext, autoik);
}
}
-
+
if (t->flag & (T_PROP_EDIT | T_PROP_CONNECTED)) {
- spos += sprintf(spos, IFACE_(" Proportional size: %.2f"), t->prop_size);
+ ofs += BLI_snprintf(str + ofs, MAX_INFO_LEN - ofs, IFACE_(" Proportional size: %.2f"), t->prop_size);
}
- (void)spos;
}
static void applyTranslation(TransInfo *t, float vec[3])
@@ -4006,7 +4025,7 @@ static void applyTranslation(TransInfo *t, float vec[3])
/* uses t->vec to store actual translation in */
int Translation(TransInfo *t, const int UNUSED(mval[2]))
{
- char str[250];
+ char str[MAX_INFO_LEN];
if (t->con.mode & CON_APPLY) {
float pvec[3] = {0.0f, 0.0f, 0.0f};
@@ -4082,8 +4101,8 @@ int ShrinkFatten(TransInfo *t, const int UNUSED(mval[2]))
{
float distance;
int i;
- char str[128];
- char *str_p;
+ char str[MAX_INFO_LEN];
+ size_t ofs = 0;
TransData *td = t->data;
distance = -t->values[0];
@@ -4093,31 +4112,30 @@ int ShrinkFatten(TransInfo *t, const int UNUSED(mval[2]))
applyNumInput(&t->num, &distance);
/* header print for NumInput */
- str_p = str;
- str_p += BLI_snprintf(str_p, sizeof(str), IFACE_("Shrink/Fatten:"));
+ ofs += BLI_strncpy_rlen(str + ofs, IFACE_("Shrink/Fatten:"), MAX_INFO_LEN - ofs);
if (hasNumInput(&t->num)) {
char c[NUM_STR_REP_LEN];
outputNumInput(&(t->num), c);
- str_p += BLI_snprintf(str_p, sizeof(str) - (str_p - str), " %s", c);
+ ofs += BLI_snprintf(str + ofs, MAX_INFO_LEN - ofs, " %s", c);
}
else {
/* default header print */
- str_p += BLI_snprintf(str_p, sizeof(str) - (str_p - str), " %.4f", distance);
+ ofs += BLI_snprintf(str + ofs, MAX_INFO_LEN - ofs, " %.4f", distance);
}
if (t->proptext[0]) {
- str_p += BLI_snprintf(str_p, sizeof(str) - (str_p - str), " %s", t->proptext);
+ ofs += BLI_snprintf(str + ofs, MAX_INFO_LEN - ofs, " %s", t->proptext);
}
- str_p += BLI_snprintf(str_p, sizeof(str) - (str_p - str), ", (");
+ ofs += BLI_snprintf(str + ofs, MAX_INFO_LEN - ofs, ", (");
{
wmKeyMapItem *kmi = WM_modalkeymap_find_propvalue(t->keymap, TFM_MODAL_RESIZE);
if (kmi) {
- str_p += WM_keymap_item_to_string(kmi, str_p, sizeof(str) - (str_p - str));
+ ofs += WM_keymap_item_to_string(kmi, str + ofs, MAX_INFO_LEN - ofs);
}
}
- str_p += BLI_snprintf(str_p, sizeof(str) - (str_p - str), IFACE_(" or Alt) Even Thickness %s"),
- (t->flag & T_ALT_TRANSFORM) ? IFACE_("ON") : IFACE_("OFF"));
+ BLI_snprintf(str + ofs, MAX_INFO_LEN - ofs, IFACE_(" or Alt) Even Thickness %s"),
+ (t->flag & T_ALT_TRANSFORM) ? IFACE_("ON") : IFACE_("OFF"));
/* done with header string */
@@ -4173,7 +4191,7 @@ int Tilt(TransInfo *t, const int UNUSED(mval[2]))
{
TransData *td = t->data;
int i;
- char str[50];
+ char str[MAX_INFO_LEN];
float final;
@@ -4188,7 +4206,7 @@ int Tilt(TransInfo *t, const int UNUSED(mval[2]))
outputNumInput(&(t->num), c);
- sprintf(str, IFACE_("Tilt: %s° %s"), &c[0], t->proptext);
+ BLI_snprintf(str, MAX_INFO_LEN, IFACE_("Tilt: %s° %s"), &c[0], t->proptext);
final = DEG2RADF(final);
@@ -4196,7 +4214,7 @@ int Tilt(TransInfo *t, const int UNUSED(mval[2]))
t->values[0] = final;
}
else {
- sprintf(str, IFACE_("Tilt: %.2f° %s"), RAD2DEGF(final), t->proptext);
+ BLI_snprintf(str, MAX_INFO_LEN, IFACE_("Tilt: %.2f° %s"), RAD2DEGF(final), t->proptext);
}
for (i = 0; i < t->total; i++, td++) {
@@ -4247,7 +4265,7 @@ int CurveShrinkFatten(TransInfo *t, const int UNUSED(mval[2]))
TransData *td = t->data;
float ratio;
int i;
- char str[50];
+ char str[MAX_INFO_LEN];
ratio = t->values[0];
@@ -4260,10 +4278,10 @@ int CurveShrinkFatten(TransInfo *t, const int UNUSED(mval[2]))
char c[NUM_STR_REP_LEN];
outputNumInput(&(t->num), c);
- sprintf(str, IFACE_("Shrink/Fatten: %s"), c);
+ BLI_snprintf(str, MAX_INFO_LEN, IFACE_("Shrink/Fatten: %s"), c);
}
else {
- sprintf(str, IFACE_("Shrink/Fatten: %3f"), ratio);
+ BLI_snprintf(str, MAX_INFO_LEN, IFACE_("Shrink/Fatten: %3f"), ratio);
}
for (i = 0; i < t->total; i++, td++) {
@@ -4315,7 +4333,7 @@ int MaskShrinkFatten(TransInfo *t, const int UNUSED(mval[2]))
TransData *td;
float ratio;
int i, initial_feather = FALSE;
- char str[50];
+ char str[MAX_INFO_LEN];
ratio = t->values[0];
@@ -4328,10 +4346,10 @@ int MaskShrinkFatten(TransInfo *t, const int UNUSED(mval[2]))
char c[NUM_STR_REP_LEN];
outputNumInput(&(t->num), c);
- sprintf(str, IFACE_("Feather Shrink/Fatten: %s"), c);
+ BLI_snprintf(str, MAX_INFO_LEN, IFACE_("Feather Shrink/Fatten: %s"), c);
}
else {
- sprintf(str, IFACE_("Feather Shrink/Fatten: %3f"), ratio);
+ BLI_snprintf(str, MAX_INFO_LEN, IFACE_("Feather Shrink/Fatten: %3f"), ratio);
}
/* detect if no points have feather yet */
@@ -4401,7 +4419,7 @@ int PushPull(TransInfo *t, const int UNUSED(mval[2]))
float vec[3], axis[3];
float distance;
int i;
- char str[128];
+ char str[MAX_INFO_LEN];
TransData *td = t->data;
distance = t->values[0];
@@ -4416,11 +4434,11 @@ int PushPull(TransInfo *t, const int UNUSED(mval[2]))
outputNumInput(&(t->num), c);
- sprintf(str, IFACE_("Push/Pull: %s%s %s"), c, t->con.text, t->proptext);
+ BLI_snprintf(str, MAX_INFO_LEN, IFACE_("Push/Pull: %s%s %s"), c, t->con.text, t->proptext);
}
else {
/* default header print */
- sprintf(str, IFACE_("Push/Pull: %.4f%s %s"), distance, t->con.text, t->proptext);
+ BLI_snprintf(str, MAX_INFO_LEN, IFACE_("Push/Pull: %.4f%s %s"), distance, t->con.text, t->proptext);
}
t->values[0] = distance;
@@ -4496,7 +4514,7 @@ void initBevel(TransInfo *t)
}
}
-int handleEventBevel(TransInfo *t, wmEvent *event)
+int handleEventBevel(TransInfo *t, const wmEvent *event)
{
if (event->val == KM_PRESS) {
if (!G.editBMesh) return 0;
@@ -4533,7 +4551,7 @@ int Bevel(TransInfo *t, const int UNUSED(mval[2]))
{
float distance, d;
int i;
- char str[128];
+ char str[MAX_INFO_LEN];
const char *mode;
TransData *td = t->data;
@@ -4552,11 +4570,11 @@ int Bevel(TransInfo *t, const int UNUSED(mval[2]))
outputNumInput(&(t->num), c);
- sprintf(str, IFACE_("Bevel - Dist: %s, Mode: %s (MMB to toggle))"), c, mode);
+ BLI_snprintf(str, MAX_INFO_LEN, IFACE_("Bevel - Dist: %s, Mode: %s (MMB to toggle))"), c, mode);
}
else {
/* default header print */
- sprintf(str, IFACE_("Bevel - Dist: %.4f, Mode: %s (MMB to toggle))"), distance, mode);
+ BLI_snprintf(str, MAX_INFO_LEN, IFACE_("Bevel - Dist: %.4f, Mode: %s (MMB to toggle))"), distance, mode);
}
if (distance < 0) distance = -distance;
@@ -4602,7 +4620,7 @@ int BevelWeight(TransInfo *t, const int UNUSED(mval[2]))
TransData *td = t->data;
float weight;
int i;
- char str[50];
+ char str[MAX_INFO_LEN];
weight = t->values[0];
@@ -4620,16 +4638,16 @@ int BevelWeight(TransInfo *t, const int UNUSED(mval[2]))
outputNumInput(&(t->num), c);
if (weight >= 0.0f)
- sprintf(str, IFACE_("Bevel Weight: +%s %s"), c, t->proptext);
+ BLI_snprintf(str, MAX_INFO_LEN, IFACE_("Bevel Weight: +%s %s"), c, t->proptext);
else
- sprintf(str, IFACE_("Bevel Weight: %s %s"), c, t->proptext);
+ BLI_snprintf(str, MAX_INFO_LEN, IFACE_("Bevel Weight: %s %s"), c, t->proptext);
}
else {
/* default header print */
if (weight >= 0.0f)
- sprintf(str, IFACE_("Bevel Weight: +%.3f %s"), weight, t->proptext);
+ BLI_snprintf(str, MAX_INFO_LEN, IFACE_("Bevel Weight: +%.3f %s"), weight, t->proptext);
else
- sprintf(str, IFACE_("Bevel Weight: %.3f %s"), weight, t->proptext);
+ BLI_snprintf(str, MAX_INFO_LEN, IFACE_("Bevel Weight: %.3f %s"), weight, t->proptext);
}
for (i = 0; i < t->total; i++, td++) {
@@ -4675,7 +4693,7 @@ int Crease(TransInfo *t, const int UNUSED(mval[2]))
TransData *td = t->data;
float crease;
int i;
- char str[50];
+ char str[MAX_INFO_LEN];
crease = t->values[0];
@@ -4693,16 +4711,16 @@ int Crease(TransInfo *t, const int UNUSED(mval[2]))
outputNumInput(&(t->num), c);
if (crease >= 0.0f)
- sprintf(str, IFACE_("Crease: +%s %s"), c, t->proptext);
+ BLI_snprintf(str, MAX_INFO_LEN, IFACE_("Crease: +%s %s"), c, t->proptext);
else
- sprintf(str, IFACE_("Crease: %s %s"), c, t->proptext);
+ BLI_snprintf(str, MAX_INFO_LEN, IFACE_("Crease: %s %s"), c, t->proptext);
}
else {
/* default header print */
if (crease >= 0.0f)
- sprintf(str, IFACE_("Crease: +%.3f %s"), crease, t->proptext);
+ BLI_snprintf(str, MAX_INFO_LEN, IFACE_("Crease: +%.3f %s"), crease, t->proptext);
else
- sprintf(str, IFACE_("Crease: %.3f %s"), crease, t->proptext);
+ BLI_snprintf(str, MAX_INFO_LEN, IFACE_("Crease: %.3f %s"), crease, t->proptext);
}
for (i = 0; i < t->total; i++, td++) {
@@ -4746,6 +4764,7 @@ void initBoneSize(TransInfo *t)
t->num.increment = t->snap[1];
}
+/* We assume str is MAX_INFO_LEN long. */
static void headerBoneSize(TransInfo *t, float vec[3], char *str)
{
char tvec[NUM_STR_REP_LEN * 3];
@@ -4753,22 +4772,22 @@ static void headerBoneSize(TransInfo *t, float vec[3], char *str)
outputNumInput(&(t->num), tvec);
}
else {
- sprintf(&tvec[0], "%.4f", vec[0]);
- sprintf(&tvec[NUM_STR_REP_LEN], "%.4f", vec[1]);
- sprintf(&tvec[NUM_STR_REP_LEN * 2], "%.4f", vec[2]);
+ BLI_snprintf(&tvec[0], NUM_STR_REP_LEN, "%.4f", vec[0]);
+ BLI_snprintf(&tvec[NUM_STR_REP_LEN], NUM_STR_REP_LEN, "%.4f", vec[1]);
+ BLI_snprintf(&tvec[NUM_STR_REP_LEN * 2], NUM_STR_REP_LEN, "%.4f", vec[2]);
}
/* hmm... perhaps the y-axis values don't need to be shown? */
if (t->con.mode & CON_APPLY) {
if (t->num.idx_max == 0)
- sprintf(str, IFACE_("ScaleB: %s%s %s"), &tvec[0], t->con.text, t->proptext);
+ BLI_snprintf(str, MAX_INFO_LEN, IFACE_("ScaleB: %s%s %s"), &tvec[0], t->con.text, t->proptext);
else
- sprintf(str, IFACE_("ScaleB: %s : %s : %s%s %s"), &tvec[0], &tvec[NUM_STR_REP_LEN],
- &tvec[NUM_STR_REP_LEN * 2], t->con.text, t->proptext);
+ BLI_snprintf(str, MAX_INFO_LEN, IFACE_("ScaleB: %s : %s : %s%s %s"),
+ &tvec[0], &tvec[NUM_STR_REP_LEN], &tvec[NUM_STR_REP_LEN * 2], t->con.text, t->proptext);
}
else {
- sprintf(str, IFACE_("ScaleB X: %s Y: %s Z: %s%s %s"), &tvec[0], &tvec[NUM_STR_REP_LEN],
- &tvec[NUM_STR_REP_LEN * 2], t->con.text, t->proptext);
+ BLI_snprintf(str, MAX_INFO_LEN, IFACE_("ScaleB X: %s Y: %s Z: %s%s %s"),
+ &tvec[0], &tvec[NUM_STR_REP_LEN], &tvec[NUM_STR_REP_LEN * 2], t->con.text, t->proptext);
}
}
@@ -4798,7 +4817,7 @@ int BoneSize(TransInfo *t, const int mval[2])
float size[3], mat[3][3];
float ratio;
int i;
- char str[60];
+ char str[MAX_INFO_LEN];
// TRANSFORM_FIX_ME MOVE TO MOUSE INPUT
/* for manipulator, center handle, the scaling can't be done relative to center */
@@ -4871,7 +4890,7 @@ int BoneEnvelope(TransInfo *t, const int UNUSED(mval[2]))
TransData *td = t->data;
float ratio;
int i;
- char str[50];
+ char str[MAX_INFO_LEN];
ratio = t->values[0];
@@ -4884,10 +4903,10 @@ int BoneEnvelope(TransInfo *t, const int UNUSED(mval[2]))
char c[NUM_STR_REP_LEN];
outputNumInput(&(t->num), c);
- sprintf(str, IFACE_("Envelope: %s"), c);
+ BLI_snprintf(str, MAX_INFO_LEN, IFACE_("Envelope: %s"), c);
}
else {
- sprintf(str, IFACE_("Envelope: %3f"), ratio);
+ BLI_snprintf(str, MAX_INFO_LEN, IFACE_("Envelope: %3f"), ratio);
}
for (i = 0; i < t->total; i++, td++) {
@@ -5604,7 +5623,8 @@ void projectEdgeSlideData(TransInfo *t, bool is_final)
f_copy_flip = BLI_smallhash_lookup(&sld->origfaces, (uintptr_t)e_sel->l->f);
}
else if (BM_vert_in_face(e_sel->l->radial_next->f, sv->down)) {
- f_copy_flip = BLI_smallhash_lookup(&sld->origfaces, (uintptr_t)e_sel->l->radial_next->f);
+ f_copy_flip = BLI_smallhash_lookup(&sld->origfaces,
+ (uintptr_t)e_sel->l->radial_next->f);
}
}
@@ -5613,7 +5633,8 @@ void projectEdgeSlideData(TransInfo *t, bool is_final)
f_copy_flip = BLI_smallhash_lookup(&sld->origfaces, (uintptr_t)e_sel->l->f);
}
else if (BM_vert_in_face(e_sel->l->radial_next->f, sv->up)) {
- f_copy_flip = BLI_smallhash_lookup(&sld->origfaces, (uintptr_t)e_sel->l->radial_next->f);
+ f_copy_flip = BLI_smallhash_lookup(&sld->origfaces,
+ (uintptr_t)e_sel->l->radial_next->f);
}
}
@@ -5746,7 +5767,7 @@ void initEdgeSlide(TransInfo *t)
t->flag |= T_NO_CONSTRAINT | T_NO_PROJECT;
}
-int handleEventEdgeSlide(struct TransInfo *t, struct wmEvent *event)
+int handleEventEdgeSlide(struct TransInfo *t, const struct wmEvent *event)
{
if (t->mode == TFM_EDGE_SLIDE) {
EdgeSlideData *sld = t->customData;
@@ -5929,12 +5950,15 @@ static int doEdgeSlide(TransInfo *t, float perc)
int EdgeSlide(TransInfo *t, const int UNUSED(mval[2]))
{
- char str[128];
+ char str[MAX_INFO_LEN];
float final;
EdgeSlideData *sld = t->customData;
bool flipped = sld->flipped_vtx;
bool is_proportional = sld->is_proportional;
+ const char *on_str = IFACE_("ON");
+ const char *off_str = IFACE_("OFF");
+
final = t->values[0];
snapGrid(t, &final);
@@ -5949,12 +5973,12 @@ int EdgeSlide(TransInfo *t, const int UNUSED(mval[2]))
outputNumInput(&(t->num), c);
- BLI_snprintf(str, sizeof(str), IFACE_("Edge Slide: %s (E)ven: %s, (F)lipped: %s"),
- &c[0], !is_proportional ? IFACE_("ON") : IFACE_("OFF"), flipped ? IFACE_("ON") : IFACE_("OFF"));
+ BLI_snprintf(str, MAX_INFO_LEN, IFACE_("Edge Slide: %s (E)ven: %s, (F)lipped: %s"),
+ &c[0], !is_proportional ? on_str : off_str, flipped ? on_str : off_str);
}
else {
- BLI_snprintf(str, sizeof(str), IFACE_("Edge Slide: %.4f (E)ven: %s, (F)lipped: %s"),
- final, !is_proportional ? IFACE_("ON") : IFACE_("OFF"), flipped ? IFACE_("ON") : IFACE_("OFF"));
+ BLI_snprintf(str, MAX_INFO_LEN, IFACE_("Edge Slide: %.4f (E)ven: %s, (F)lipped: %s"),
+ final, !is_proportional ? on_str : off_str, flipped ? on_str : off_str);
}
CLAMP(final, -1.0f, 1.0f);
@@ -5962,10 +5986,11 @@ int EdgeSlide(TransInfo *t, const int UNUSED(mval[2]))
t->values[0] = final;
/*do stuff here*/
- if (t->customData)
+ if (t->customData) {
doEdgeSlide(t, final);
+ }
else {
- strcpy(str, IFACE_("Invalid Edge Selection"));
+ BLI_strncpy(str, IFACE_("Invalid Edge Selection"), MAX_INFO_LEN);
t->state = TRANS_CANCEL;
}
@@ -6249,7 +6274,7 @@ void initVertSlide(TransInfo *t)
t->flag |= T_NO_CONSTRAINT | T_NO_PROJECT;
}
-int handleEventVertSlide(struct TransInfo *t, struct wmEvent *event)
+int handleEventVertSlide(struct TransInfo *t, const struct wmEvent *event)
{
if (t->mode == TFM_VERT_SLIDE) {
VertSlideData *sld = t->customData;
@@ -6434,8 +6459,8 @@ static int doVertSlide(TransInfo *t, float perc)
int VertSlide(TransInfo *t, const int UNUSED(mval[2]))
{
- char str[128];
- char *str_p;
+ char str[MAX_INFO_LEN];
+ size_t ofs = 0;
float final;
VertSlideData *sld = t->customData;
const bool flipped = sld->flipped_vtx;
@@ -6443,6 +6468,9 @@ int VertSlide(TransInfo *t, const int UNUSED(mval[2]))
const bool is_clamp = !(t->flag & T_ALT_TRANSFORM);
const bool is_constrained = !(is_clamp == false || hasNumInput(&t->num));
+ const char *on_str = IFACE_("ON");
+ const char *off_str = IFACE_("OFF");
+
final = t->values[0];
snapGrid(t, &final);
@@ -6453,25 +6481,21 @@ int VertSlide(TransInfo *t, const int UNUSED(mval[2]))
}
/* header string */
- str_p = str;
- str_p += BLI_snprintf(str_p, sizeof(str), IFACE_("Vert Slide: "));
+ ofs += BLI_strncpy_rlen(str + ofs, IFACE_("Vert Slide: "), MAX_INFO_LEN - ofs);
if (hasNumInput(&t->num)) {
char c[NUM_STR_REP_LEN];
applyNumInput(&t->num, &final);
outputNumInput(&(t->num), c);
- str_p += BLI_snprintf(str_p, sizeof(str) - (str_p - str), "%s", &c[0]);
+ ofs += BLI_strncpy_rlen(str + ofs, &c[0], MAX_INFO_LEN - ofs);
}
else {
- str_p += BLI_snprintf(str_p, sizeof(str) - (str_p - str), "%.4f ", final);
+ ofs += BLI_snprintf(str + ofs, MAX_INFO_LEN - ofs, "%.4f ", final);
}
- str_p += BLI_snprintf(str_p, sizeof(str) - (str_p - str), IFACE_("(E)ven: %s, "),
- !is_proportional ? IFACE_("ON") : IFACE_("OFF"));
+ ofs += BLI_snprintf(str + ofs, MAX_INFO_LEN - ofs, IFACE_("(E)ven: %s, "), !is_proportional ? on_str : off_str);
if (!is_proportional) {
- str_p += BLI_snprintf(str_p, sizeof(str) - (str_p - str), IFACE_("(F)lipped: %s, "),
- flipped ? IFACE_("ON") : IFACE_("OFF"));
+ ofs += BLI_snprintf(str + ofs, MAX_INFO_LEN - ofs, IFACE_("(F)lipped: %s, "), flipped ? on_str : off_str);
}
- str_p += BLI_snprintf(str_p, sizeof(str) - (str_p - str), IFACE_("Alt or (C)lamp: %s"),
- is_clamp ? IFACE_("ON") : IFACE_("OFF"));
+ ofs += BLI_snprintf(str + ofs, MAX_INFO_LEN - ofs, IFACE_("Alt or (C)lamp: %s"), is_clamp ? on_str : off_str);
/* done with header string */
/*do stuff here*/
@@ -6479,7 +6503,7 @@ int VertSlide(TransInfo *t, const int UNUSED(mval[2]))
doVertSlide(t, final);
}
else {
- strcpy(str, IFACE_("Invalid Vert Selection"));
+ BLI_strncpy(str, IFACE_("Invalid Vert Selection"), MAX_INFO_LEN);
t->state = TRANS_CANCEL;
}
@@ -6515,7 +6539,7 @@ int BoneRoll(TransInfo *t, const int UNUSED(mval[2]))
{
TransData *td = t->data;
int i;
- char str[50];
+ char str[MAX_INFO_LEN];
float final;
@@ -6530,12 +6554,12 @@ int BoneRoll(TransInfo *t, const int UNUSED(mval[2]))
outputNumInput(&(t->num), c);
- sprintf(str, IFACE_("Roll: %s"), &c[0]);
+ BLI_snprintf(str, MAX_INFO_LEN, IFACE_("Roll: %s"), &c[0]);
final = DEG2RADF(final);
}
else {
- sprintf(str, IFACE_("Roll: %.2f"), RAD2DEGF(final));
+ BLI_snprintf(str, MAX_INFO_LEN, IFACE_("Roll: %.2f"), RAD2DEGF(final));
}
/* set roll values */
@@ -6577,7 +6601,7 @@ int BakeTime(TransInfo *t, const int mval[2])
TransData *td = t->data;
float time;
int i;
- char str[50];
+ char str[MAX_INFO_LEN];
float fac = 0.1f;
@@ -6601,16 +6625,16 @@ int BakeTime(TransInfo *t, const int mval[2])
outputNumInput(&(t->num), c);
if (time >= 0.0f)
- sprintf(str, IFACE_("Time: +%s %s"), c, t->proptext);
+ BLI_snprintf(str, MAX_INFO_LEN, IFACE_("Time: +%s %s"), c, t->proptext);
else
- sprintf(str, IFACE_("Time: %s %s"), c, t->proptext);
+ BLI_snprintf(str, MAX_INFO_LEN, IFACE_("Time: %s %s"), c, t->proptext);
}
else {
/* default header print */
if (time >= 0.0f)
- sprintf(str, IFACE_("Time: +%.3f %s"), time, t->proptext);
+ BLI_snprintf(str, MAX_INFO_LEN, IFACE_("Time: +%.3f %s"), time, t->proptext);
else
- sprintf(str, IFACE_("Time: %.3f %s"), time, t->proptext);
+ BLI_snprintf(str, MAX_INFO_LEN, IFACE_("Time: %.3f %s"), time, t->proptext);
}
for (i = 0; i < t->total; i++, td++) {
@@ -6652,7 +6676,7 @@ int Mirror(TransInfo *t, const int UNUSED(mval[2]))
TransData *td;
float size[3], mat[3][3];
int i;
- char str[200];
+ char str[MAX_INFO_LEN];
/*
* OPTIMIZATION:
@@ -6670,7 +6694,7 @@ int Mirror(TransInfo *t, const int UNUSED(mval[2]))
t->con.applySize(t, NULL, mat);
}
- sprintf(str, IFACE_("Mirror%s"), t->con.text);
+ BLI_snprintf(str, MAX_INFO_LEN, IFACE_("Mirror%s"), t->con.text);
for (i = 0, td = t->data; i < t->total; i++, td++) {
if (td->flag & TD_NOACTION)
@@ -6787,29 +6811,29 @@ void initSeqSlide(TransInfo *t)
t->num.increment = t->snap[1];
}
-static void headerSeqSlide(TransInfo *t, float val[2], char *str, size_t str_len)
+/* We assume str is MAX_INFO_LEN long. */
+static void headerSeqSlide(TransInfo *t, float val[2], char *str)
{
char tvec[NUM_STR_REP_LEN * 3];
- char *str_p;
+ size_t ofs = 0;
if (hasNumInput(&t->num)) {
outputNumInput(&(t->num), tvec);
}
else {
- sprintf(&tvec[0], "%.0f, %.0f", val[0], val[1]);
+ BLI_snprintf(&tvec[0], NUM_STR_REP_LEN, "%.0f, %.0f", val[0], val[1]);
}
- str_p = str;
- str_p += BLI_snprintf(str, str_len, IFACE_("Sequence Slide: %s%s, ("), &tvec[0], t->con.text);
+ ofs += BLI_snprintf(str + ofs, MAX_INFO_LEN - ofs, IFACE_("Sequence Slide: %s%s, ("), &tvec[0], t->con.text);
{
wmKeyMapItem *kmi = WM_modalkeymap_find_propvalue(t->keymap, TFM_MODAL_TRANSLATE);
if (kmi) {
- str_p += WM_keymap_item_to_string(kmi, str_p, str_len - (str_p - str));
+ ofs += WM_keymap_item_to_string(kmi, str + ofs, MAX_INFO_LEN - ofs);
}
}
- str_p += BLI_snprintf(str_p, str_len - (str_p - str), IFACE_(" or Alt) Expand to fit %s"),
- (t->flag & T_ALT_TRANSFORM) ? IFACE_("ON") : IFACE_("OFF"));
+ ofs += BLI_snprintf(str + ofs, MAX_INFO_LEN - ofs, IFACE_(" or Alt) Expand to fit %s"),
+ (t->flag & T_ALT_TRANSFORM) ? IFACE_("ON") : IFACE_("OFF"));
}
static void applySeqSlide(TransInfo *t, float val[2])
@@ -6837,7 +6861,7 @@ static void applySeqSlide(TransInfo *t, float val[2])
int SeqSlide(TransInfo *t, const int UNUSED(mval[2]))
{
- char str[200];
+ char str[MAX_INFO_LEN];
if (t->con.mode & CON_APPLY) {
float pvec[3] = {0.0f, 0.0f, 0.0f};
@@ -6853,7 +6877,7 @@ int SeqSlide(TransInfo *t, const int UNUSED(mval[2]))
t->values[0] = floor(t->values[0] + 0.5f);
t->values[1] = floor(t->values[1] + 0.5f);
- headerSeqSlide(t, t->values, str, sizeof(str));
+ headerSeqSlide(t, t->values, str);
applySeqSlide(t, t->values);
recalcData(t);
@@ -6953,7 +6977,11 @@ static void doAnimEdit_SnapFrame(TransInfo *t, TransData *td, TransData2D *td2d,
#if 0 /* 'do_time' disabled for now */
const Scene *scene = t->scene;
- const short do_time = 0; //getAnimEdit_DrawTime(t); // NOTE: this works, but may be confusing behavior given the option's label, hence disabled
+#if 0 /* NOTE: this works, but may be confusing behavior given the option's label, hence disabled */
+ const short do_time = getAnimEdit_DrawTime(t);
+#else
+ const short do_time = 0;
+#endif
const double secf = FPS;
#endif
double val;
@@ -7041,6 +7069,7 @@ void initTimeTranslate(TransInfo *t)
t->num.increment = t->snap[1];
}
+/* We assume str is MAX_INFO_LEN long. */
static void headerTimeTranslate(TransInfo *t, char *str)
{
char tvec[NUM_STR_REP_LEN * 3];
@@ -7069,12 +7098,12 @@ static void headerTimeTranslate(TransInfo *t, char *str)
}
if (autosnap == SACTSNAP_FRAME)
- sprintf(&tvec[0], "%d.00 (%.4f)", (int)val, val);
+ BLI_snprintf(&tvec[0], NUM_STR_REP_LEN, "%d.00 (%.4f)", (int)val, val);
else
- sprintf(&tvec[0], "%.4f", val);
+ BLI_snprintf(&tvec[0], NUM_STR_REP_LEN, "%.4f", val);
}
- sprintf(str, IFACE_("DeltaX: %s"), &tvec[0]);
+ BLI_snprintf(str, MAX_INFO_LEN, IFACE_("DeltaX: %s"), &tvec[0]);
}
static void applyTimeTranslate(TransInfo *t, float UNUSED(sval))
@@ -7138,7 +7167,7 @@ int TimeTranslate(TransInfo *t, const int mval[2])
{
View2D *v2d = (View2D *)t->view;
float cval[2], sval[2];
- char str[200];
+ char str[MAX_INFO_LEN];
/* calculate translation amount from mouse movement - in 'time-grid space' */
UI_view2d_region_to_view(v2d, mval[0], mval[0], &cval[0], &cval[1]);
@@ -7196,6 +7225,7 @@ void initTimeSlide(TransInfo *t)
t->num.increment = t->snap[1];
}
+/* We assume str is MAX_INFO_LEN long. */
static void headerTimeSlide(TransInfo *t, float sval, char *str)
{
char tvec[NUM_STR_REP_LEN * 3];
@@ -7212,10 +7242,10 @@ static void headerTimeSlide(TransInfo *t, float sval, char *str)
val = 2.0f * (cval - sval) / (maxx - minx);
CLAMP(val, -1.0f, 1.0f);
- sprintf(&tvec[0], "%.4f", val);
+ BLI_snprintf(&tvec[0], NUM_STR_REP_LEN, "%.4f", val);
}
- sprintf(str, IFACE_("TimeSlide: %s"), &tvec[0]);
+ BLI_snprintf(str, MAX_INFO_LEN, IFACE_("TimeSlide: %s"), &tvec[0]);
}
static void applyTimeSlide(TransInfo *t, float sval)
@@ -7271,7 +7301,7 @@ int TimeSlide(TransInfo *t, const int mval[2])
float cval[2], sval[2];
float minx = *((float *)(t->customData));
float maxx = *((float *)(t->customData) + 1);
- char str[200];
+ char str[MAX_INFO_LEN];
/* calculate mouse co-ordinates */
UI_view2d_region_to_view(v2d, mval[0], mval[1], &cval[0], &cval[1]);
@@ -7338,6 +7368,7 @@ void initTimeScale(TransInfo *t)
t->num.increment = t->snap[1];
}
+/* We assume str is MAX_INFO_LEN long. */
static void headerTimeScale(TransInfo *t, char *str)
{
char tvec[NUM_STR_REP_LEN * 3];
@@ -7345,9 +7376,9 @@ static void headerTimeScale(TransInfo *t, char *str)
if (hasNumInput(&t->num))
outputNumInput(&(t->num), tvec);
else
- sprintf(&tvec[0], "%.4f", t->values[0]);
+ BLI_snprintf(&tvec[0], NUM_STR_REP_LEN, "%.4f", t->values[0]);
- sprintf(str, IFACE_("ScaleX: %s"), &tvec[0]);
+ BLI_snprintf(str, MAX_INFO_LEN, IFACE_("ScaleX: %s"), &tvec[0]);
}
static void applyTimeScale(TransInfo *t)
@@ -7392,7 +7423,7 @@ static void applyTimeScale(TransInfo *t)
int TimeScale(TransInfo *t, const int UNUSED(mval[2]))
{
- char str[200];
+ char str[MAX_INFO_LEN];
/* handle numeric-input stuff */
t->vec[0] = t->values[0];
@@ -7423,3 +7454,5 @@ bool checkUseLocalCenter_GraphEdit(TransInfo *t)
{
return ((t->around == V3D_LOCAL) && !ELEM3(t->mode, TFM_TRANSLATION, TFM_TIME_TRANSLATE, TFM_TIME_SLIDE));
}
+
+#undef MAX_INFO_LEN
diff --git a/source/blender/editors/transform/transform.h b/source/blender/editors/transform/transform.h
index dbf56f658ac..a551ef5008e 100644
--- a/source/blender/editors/transform/transform.h
+++ b/source/blender/editors/transform/transform.h
@@ -288,7 +288,7 @@ typedef struct TransInfo {
float fac; /* factor for distance based transform */
int (*transform)(struct TransInfo *, const int *);
/* transform function pointer */
- int (*handleEvent)(struct TransInfo *, struct wmEvent *);
+ int (*handleEvent)(struct TransInfo *, const struct wmEvent *);
/* event handler function pointer RETURN 1 if redraw is needed */
int total; /* total number of transformed data */
TransData *data; /* transformed data (array) */
@@ -354,6 +354,7 @@ typedef struct TransInfo {
struct wmTimer *animtimer;
struct wmKeyMap *keymap; /* so we can do lookups for header text */
int mval[2]; /* current mouse position */
+ float zfac; /* use for 3d view */
struct Object *obedit;
void *draw_handle_apply;
void *draw_handle_view;
@@ -474,9 +475,9 @@ typedef struct TransInfo {
#define POINT_INIT 4
#define MULTI_POINTS 8
-int initTransform(struct bContext *C, struct TransInfo *t, struct wmOperator *op, struct wmEvent *event, int mode);
+int initTransform(struct bContext *C, struct TransInfo *t, struct wmOperator *op, const struct wmEvent *event, int mode);
void saveTransform(struct bContext *C, struct TransInfo *t, struct wmOperator *op);
-int transformEvent(TransInfo *t, struct wmEvent *event);
+int transformEvent(TransInfo *t, const struct wmEvent *event);
void transformApply(struct bContext *C, TransInfo *t);
int transformEnd(struct bContext *C, TransInfo *t);
@@ -491,11 +492,11 @@ void applyAspectRatio(TransInfo *t, float *vec);
void removeAspectRatio(TransInfo *t, float *vec);
void initWarp(TransInfo *t);
-int handleEventWarp(TransInfo *t, struct wmEvent *event);
+int handleEventWarp(TransInfo *t, const struct wmEvent *event);
int Warp(TransInfo *t, const int mval[2]);
void initShear(TransInfo *t);
-int handleEventShear(TransInfo *t, struct wmEvent *event);
+int handleEventShear(TransInfo *t, const struct wmEvent *event);
int Shear(TransInfo *t, const int mval[2]);
void initResize(TransInfo *t);
@@ -532,7 +533,7 @@ void initPushPull(TransInfo *t);
int PushPull(TransInfo *t, const int mval[2]);
void initBevel(TransInfo *t);
-int handleEventBevel(TransInfo *t, struct wmEvent *event);
+int handleEventBevel(TransInfo *t, const struct wmEvent *event);
int Bevel(TransInfo *t, const int mval[2]);
void initBevelWeight(TransInfo *t);
@@ -551,11 +552,11 @@ void initBoneRoll(TransInfo *t);
int BoneRoll(TransInfo *t, const int mval[2]);
void initEdgeSlide(TransInfo *t);
-int handleEventEdgeSlide(TransInfo *t, struct wmEvent *event);
+int handleEventEdgeSlide(TransInfo *t, const struct wmEvent *event);
int EdgeSlide(TransInfo *t, const int mval[2]);
void initVertSlide(TransInfo *t);
-int handleEventVertSlide(TransInfo *t, struct wmEvent *event);
+int handleEventVertSlide(TransInfo *t, const struct wmEvent *event);
int VertSlide(TransInfo *t, const int mval[2]);
void initTimeTranslate(TransInfo *t);
@@ -658,7 +659,7 @@ void initSnapping(struct TransInfo *t, struct wmOperator *op);
void applyProject(TransInfo *t);
void applySnapping(TransInfo *t, float *vec);
void resetSnapping(TransInfo *t);
-int handleSnapping(TransInfo *t, struct wmEvent *event);
+int handleSnapping(TransInfo *t, const struct wmEvent *event);
void drawSnapping(const struct bContext *C, TransInfo *t);
int usingSnappingNormal(TransInfo *t);
int validSnappingNormal(TransInfo *t);
@@ -687,7 +688,7 @@ typedef enum {
void initMouseInput(TransInfo *t, MouseInput *mi, const int center[2], const int mval[2]);
void initMouseInputMode(TransInfo *t, MouseInput *mi, MouseInputMode mode);
-int handleMouseInput(struct TransInfo *t, struct MouseInput *mi, struct wmEvent *event);
+int handleMouseInput(struct TransInfo *t, struct MouseInput *mi, const struct wmEvent *event);
void applyMouseInput(struct TransInfo *t, struct MouseInput *mi, const int mval[2], float output[3]);
void setCustomPoints(TransInfo *t, MouseInput *mi, const int start[2], const int end[2]);
@@ -695,7 +696,7 @@ void setInputPostFct(MouseInput *mi, void (*post)(struct TransInfo *t, float val
/*********************** Generics ********************************/
-int initTransInfo(struct bContext *C, TransInfo *t, struct wmOperator *op, struct wmEvent *event);
+int initTransInfo(struct bContext *C, TransInfo *t, struct wmOperator *op, const struct wmEvent *event);
void postTrans (struct bContext *C, TransInfo *t);
void resetTransRestrictions(TransInfo *t);
diff --git a/source/blender/editors/transform/transform_constraints.c b/source/blender/editors/transform/transform_constraints.c
index c4d61472f18..f3026205ea2 100644
--- a/source/blender/editors/transform/transform_constraints.c
+++ b/source/blender/editors/transform/transform_constraints.c
@@ -29,19 +29,17 @@
* \ingroup edtransform
*/
-
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
#ifndef WIN32
-#include <unistd.h>
+# include <unistd.h>
#else
-#include <io.h>
+# include <io.h>
#endif
-
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
#include "DNA_screen_types.h"
@@ -53,13 +51,13 @@
#include "BKE_context.h"
-#include "ED_image.h"
-#include "ED_view3d.h"
-
#include "BLI_math.h"
#include "BLI_utildefines.h"
#include "BLI_string.h"
+#include "ED_image.h"
+#include "ED_view3d.h"
+
#include "BLF_translation.h"
#include "UI_resources.h"
@@ -867,11 +865,11 @@ static void setNearestAxis2d(TransInfo *t)
/* no correction needed... just use whichever one is lower */
if (abs(t->mval[0] - t->con.imval[0]) < abs(t->mval[1] - t->con.imval[1]) ) {
t->con.mode |= CON_AXIS1;
- BLI_snprintf(t->con.text, sizeof(t->con.text), IFACE_(" along Y axis"));
+ BLI_strncpy(t->con.text, IFACE_(" along Y axis"), sizeof(t->con.text));
}
else {
t->con.mode |= CON_AXIS0;
- BLI_snprintf(t->con.text, sizeof(t->con.text), IFACE_(" along X axis"));
+ BLI_strncpy(t->con.text, IFACE_(" along X axis"), sizeof(t->con.text));
}
}
@@ -892,9 +890,9 @@ static void setNearestAxis3d(TransInfo *t)
* and to overflow the short integers.
* The formula used is a bit stupid, just a simplification of the subtraction
* of two 2D points 30 pixels apart (that's the last factor in the formula) after
- * projecting them with window_to_3d_delta and then get the length of that vector.
+ * projecting them with ED_view3d_win_to_delta and then get the length of that vector.
*/
- zfac = t->persmat[0][3] * t->center[0] + t->persmat[1][3] * t->center[1] + t->persmat[2][3] * t->center[2] + t->persmat[3][3];
+ zfac = mul_project_m4_v3_zfac(t->persmat, t->center);
zfac = len_v3(t->persinv[0]) * 2.0f / t->ar->winx * zfac * 30.0f;
for (i = 0; i < 3; i++) {
diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c
index 57816e7546c..b8a39cae381 100644
--- a/source/blender/editors/transform/transform_conversions.c
+++ b/source/blender/editors/transform/transform_conversions.c
@@ -223,7 +223,9 @@ static void set_prop_dist(TransInfo *t, short with_dist)
tob->rdist = dist;
}
}
- else break; // by definition transdata has selected items in beginning
+ else {
+ break; /* by definition transdata has selected items in beginning */
+ }
}
if (with_dist) {
tob->dist = tob->rdist;
@@ -1291,7 +1293,7 @@ static void calc_distanceCurveVerts(TransData *head, TransData *tail)
}
}
else {
- td->dist = MAXFLOAT;
+ td->dist = FLT_MAX;
td->flag |= TD_NOTCONNECTED;
}
}
@@ -2048,7 +2050,9 @@ static void createTransEditVerts(TransInfo *t)
if (propmode & T_PROP_CONNECTED)
dists = MEM_mallocN(em->bm->totvert * sizeof(float), "scratch nears");
}
- else t->total = countsel;
+ else {
+ t->total = countsel;
+ }
tob = t->data = MEM_callocN(t->total * sizeof(TransData), "TransObData(Mesh EditMode)");
if (ELEM(t->mode, TFM_SKIN_RESIZE, TFM_SHRINKFATTEN)) {
@@ -2127,7 +2131,7 @@ static void createTransEditVerts(TransInfo *t)
}
else {
tob->flag |= TD_NOTCONNECTED;
- tob->dist = MAXFLOAT;
+ tob->dist = FLT_MAX;
}
}
@@ -2363,7 +2367,7 @@ static void UVsToTransData(SpaceImage *sima, TransData *td, TransData2D *td2d, f
td->dist = 0.0;
}
else {
- td->dist = MAXFLOAT;
+ td->dist = FLT_MAX;
}
unit_m3(td->mtx);
unit_m3(td->smtx);
@@ -3500,7 +3504,7 @@ static void bezt_to_transdata(TransData *td, TransData2D *td2d, AnimData *adt, B
td->dist = 0.0f;
}
else
- td->dist = MAXFLOAT;
+ td->dist = FLT_MAX;
if (ishandle)
td->flag |= TD_NOTIMESNAP;
@@ -3584,7 +3588,9 @@ static void createTransGraphEditData(bContext *C, TransInfo *t)
if (ELEM3(t->mode, TFM_TRANSLATION, TFM_TIME_TRANSLATE, TFM_TIME_SLIDE)) {
/* for 'normal' pivots - just include anything that is selected.
* this works a bit differently in translation modes */
- if (sel2) count++;
+ if (sel2) {
+ count++;
+ }
else {
if (sel1) count++;
if (sel3) count++;
@@ -6594,7 +6600,7 @@ void createTransData(bContext *C, TransInfo *t)
sort_trans_data_dist(t);
}
}
- else if (ob && (ob->mode & (OB_MODE_SCULPT | OB_MODE_TEXTURE_PAINT))) {
+ else if (ob && (ob->mode & (OB_MODE_ALL_PAINT))) {
/* sculpt mode and project paint have own undo stack
* transform ops redo clears sculpt/project undo stack.
*
diff --git a/source/blender/editors/transform/transform_generics.c b/source/blender/editors/transform/transform_generics.c
index c2a331f5249..2a3b0bc8726 100644
--- a/source/blender/editors/transform/transform_generics.c
+++ b/source/blender/editors/transform/transform_generics.c
@@ -1012,7 +1012,7 @@ void resetTransRestrictions(TransInfo *t)
}
/* the *op can be NULL */
-int initTransInfo(bContext *C, TransInfo *t, wmOperator *op, wmEvent *event)
+int initTransInfo(bContext *C, TransInfo *t, wmOperator *op, const wmEvent *event)
{
Scene *sce = CTX_data_scene(C);
ToolSettings *ts = CTX_data_tool_settings(C);
@@ -1669,7 +1669,7 @@ void calculateCenter(TransInfo *t)
projectIntView(t, axis, t->center2d);
- /* rotate only needs correct 2d center, grab needs initgrabz() value */
+ /* rotate only needs correct 2d center, grab needs ED_view3d_calc_zfac() value */
if (t->mode == TFM_TRANSLATION) {
copy_v3_v3(t->center, axis);
copy_v3_v3(t->con.center, t->center);
@@ -1679,18 +1679,16 @@ void calculateCenter(TransInfo *t)
}
if (t->spacetype == SPACE_VIEW3D) {
- /* initgrabz() defines a factor for perspective depth correction, used in window_to_3d_delta() */
+ /* ED_view3d_calc_zfac() defines a factor for perspective depth correction, used in ED_view3d_win_to_delta() */
+ float vec[3];
if (t->flag & (T_EDIT | T_POSE)) {
Object *ob = t->obedit ? t->obedit : t->poseobj;
- float vec[3];
-
- copy_v3_v3(vec, t->center);
- mul_m4_v3(ob->obmat, vec);
- initgrabz(t->ar->regiondata, vec[0], vec[1], vec[2]);
+ mul_v3_m4v3(vec, ob->obmat, t->center);
}
else {
- initgrabz(t->ar->regiondata, t->center[0], t->center[1], t->center[2]);
+ copy_v3_v3(vec, t->center);
}
+ t->zfac = ED_view3d_calc_zfac(t->ar->regiondata, vec, NULL);
}
}
diff --git a/source/blender/editors/transform/transform_input.c b/source/blender/editors/transform/transform_input.c
index 4e9a54692a5..4943a3a2fe7 100644
--- a/source/blender/editors/transform/transform_input.c
+++ b/source/blender/editors/transform/transform_input.c
@@ -393,7 +393,7 @@ void applyMouseInput(TransInfo *t, MouseInput *mi, const int mval[2], float outp
}
}
-int handleMouseInput(TransInfo *t, MouseInput *mi, wmEvent *event)
+int handleMouseInput(TransInfo *t, MouseInput *mi, const wmEvent *event)
{
int redraw = TREDRAW_NOTHING;
diff --git a/source/blender/editors/transform/transform_manipulator.c b/source/blender/editors/transform/transform_manipulator.c
index 54fb567b8a2..bea1f9da057 100644
--- a/source/blender/editors/transform/transform_manipulator.c
+++ b/source/blender/editors/transform/transform_manipulator.c
@@ -856,7 +856,7 @@ static void axis_sort_v3(const float axis_values[3], int r_axis_order[3])
}
else {
if (v[1] < v[2]) { SWAP_AXIS(0, 1); }
- else { SWAP_AXIS(0, 2); }
+ else { SWAP_AXIS(0, 2); }
}
if (v[2] < v[1]) { SWAP_AXIS(1, 2); }
@@ -1293,7 +1293,9 @@ static void draw_manipulator_scale(View3D *v3d, RegionView3D *rv3d, int moving,
dz = 1.0;
}
- else dz = 1.0f - 4.0f * cusize;
+ else {
+ dz = 1.0f - 4.0f * cusize;
+ }
if (moving) {
float matt[4][4];
@@ -1739,8 +1741,12 @@ static int manipulator_selectbuf(ScrArea *sa, ARegion *ar, const int mval[2], fl
dep = buffer[4 * a + 1];
val = buffer[4 * a + 3];
- if (val == MAN_TRANS_C) return MAN_TRANS_C;
- else if (val == MAN_SCALE_C) return MAN_SCALE_C;
+ if (val == MAN_TRANS_C) {
+ return MAN_TRANS_C;
+ }
+ else if (val == MAN_SCALE_C) {
+ return MAN_SCALE_C;
+ }
else {
if (val & MAN_ROT_C) {
if (minvalrot == 0 || dep < mindeprot) {
@@ -1767,7 +1773,7 @@ static int manipulator_selectbuf(ScrArea *sa, ARegion *ar, const int mval[2], fl
/* return 0; nothing happened */
-int BIF_do_manipulator(bContext *C, struct wmEvent *event, wmOperator *op)
+int BIF_do_manipulator(bContext *C, const struct wmEvent *event, wmOperator *op)
{
ScrArea *sa = CTX_wm_area(C);
View3D *v3d = sa->spacedata.first;
@@ -1855,8 +1861,15 @@ int BIF_do_manipulator(bContext *C, struct wmEvent *event, wmOperator *op)
//wm_operator_invoke(C, WM_operatortype_find("TRANSFORM_OT_resize", 0), event, op->ptr, NULL, FALSE);
}
else if (drawflags == MAN_ROT_T) { /* trackball need special case, init is different */
- WM_operator_name_call(C, "TRANSFORM_OT_trackball", WM_OP_INVOKE_DEFAULT, op->ptr);
- //wm_operator_invoke(C, WM_operatortype_find("TRANSFORM_OT_trackball", 0), event, op->ptr, NULL, FALSE);
+ /* Do not pass op->ptr!!! trackball has no "constraint" properties!
+ * See [#34621], it's a miracle it did not cause more problems!!! */
+ /* However, we need to copy the "release_confirm" property... */
+ PointerRNA props_ptr;
+ WM_operator_properties_create(&props_ptr, "TRANSFORM_OT_trackball");
+ RNA_boolean_set(&props_ptr, "release_confirm", RNA_boolean_get(op->ptr, "release_confirm"));
+
+ WM_operator_name_call(C, "TRANSFORM_OT_trackball", WM_OP_INVOKE_DEFAULT, &props_ptr);
+ //wm_operator_invoke(C, WM_operatortype_find("TRANSFORM_OT_trackball", 0), event, NULL, NULL, FALSE);
}
else if (drawflags & MAN_ROT_C) {
switch (drawflags) {
diff --git a/source/blender/editors/transform/transform_ops.c b/source/blender/editors/transform/transform_ops.c
index 0392c0f47a2..60b0c655691 100644
--- a/source/blender/editors/transform/transform_ops.c
+++ b/source/blender/editors/transform/transform_ops.c
@@ -24,16 +24,11 @@
* \ingroup edtransform
*/
-
#include "MEM_guardedalloc.h"
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
-#include "RNA_access.h"
-#include "RNA_define.h"
-#include "RNA_enum_types.h"
-
#include "BLI_math.h"
#include "BLI_utildefines.h"
@@ -44,6 +39,10 @@
#include "BKE_armature.h"
#include "BKE_report.h"
+#include "RNA_access.h"
+#include "RNA_define.h"
+#include "RNA_enum_types.h"
+
#include "WM_api.h"
#include "WM_types.h"
@@ -166,7 +165,7 @@ static int select_orientation_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int select_orientation_invoke(bContext *C, wmOperator *UNUSED(op), wmEvent *UNUSED(event))
+static int select_orientation_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *UNUSED(event))
{
uiPopupMenu *pup;
uiLayout *layout;
@@ -213,7 +212,7 @@ static int delete_orientation_exec(bContext *C, wmOperator *UNUSED(op))
return OPERATOR_FINISHED;
}
-static int delete_orientation_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int delete_orientation_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
return delete_orientation_exec(C, op);
}
@@ -269,7 +268,7 @@ static int create_orientation_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int create_orientation_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int create_orientation_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
return create_orientation_exec(C, op);
}
@@ -301,7 +300,7 @@ static void transformops_exit(bContext *C, wmOperator *op)
G.moving = 0;
}
-static int transformops_data(bContext *C, wmOperator *op, wmEvent *event)
+static int transformops_data(bContext *C, wmOperator *op, const wmEvent *event)
{
int retval = 1;
if (op->customdata == NULL) {
@@ -335,7 +334,7 @@ static int transformops_data(bContext *C, wmOperator *op, wmEvent *event)
return retval; /* return 0 on error */
}
-static int transform_modal(bContext *C, wmOperator *op, wmEvent *event)
+static int transform_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
int exit_code;
@@ -402,7 +401,7 @@ static int transform_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int transform_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int transform_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
if (!transformops_data(C, op, event)) {
G.moving = 0;
@@ -431,7 +430,6 @@ void Transform_Properties(struct wmOperatorType *ot, int flags)
/* Make this not hidden when there's a nice axis selection widget */
RNA_def_property_flag(prop, PROP_HIDDEN);
RNA_def_property_ui_text(prop, "Axis", "The axis around which the transformation occurs");
-
}
if (flags & P_CONSTRAINT) {
@@ -439,8 +437,6 @@ void Transform_Properties(struct wmOperatorType *ot, int flags)
prop = RNA_def_property(ot->srna, "constraint_orientation", PROP_ENUM, PROP_NONE);
RNA_def_property_ui_text(prop, "Orientation", "Transformation orientation");
RNA_def_enum_funcs(prop, rna_TransformOrientation_itemf);
-
-
}
if (flags & P_MIRROR) {
@@ -558,6 +554,8 @@ static void TRANSFORM_OT_skin_resize(struct wmOperatorType *ot)
static void TRANSFORM_OT_trackball(struct wmOperatorType *ot)
{
+ PropertyRNA *prop;
+
/* identifiers */
ot->name = "Trackball";
ot->description = "Trackball style rotation of selected items";
@@ -571,7 +569,9 @@ static void TRANSFORM_OT_trackball(struct wmOperatorType *ot)
ot->cancel = transform_cancel;
ot->poll = ED_operator_screenactive;
- RNA_def_float_vector(ot->srna, "value", 2, VecOne, -FLT_MAX, FLT_MAX, "Angle", "", -FLT_MAX, FLT_MAX);
+ /* Maybe we could use float_vector_xyz here too? */
+ prop = RNA_def_float_vector(ot->srna, "value", 2, NULL, -FLT_MAX, FLT_MAX, "Angle", "", -FLT_MAX, FLT_MAX);
+ RNA_def_property_subtype(prop, PROP_ANGLE);
Transform_Properties(ot, P_PROPORTIONAL | P_MIRROR | P_SNAP);
}
@@ -841,7 +841,7 @@ static void TRANSFORM_OT_seq_slide(struct wmOperatorType *ot)
ot->cancel = transform_cancel;
ot->poll = ED_operator_sequencer_active;
- RNA_def_float_vector(ot->srna, "value", 2, VecOne, -FLT_MAX, FLT_MAX, "Angle", "", -FLT_MAX, FLT_MAX);
+ RNA_def_float_vector_xyz(ot->srna, "value", 2, NULL, -FLT_MAX, FLT_MAX, "Vector", "", -FLT_MAX, FLT_MAX);
Transform_Properties(ot, P_SNAP);
}
diff --git a/source/blender/editors/transform/transform_orientations.c b/source/blender/editors/transform/transform_orientations.c
index e507d062b0e..4fe36a15802 100644
--- a/source/blender/editors/transform/transform_orientations.c
+++ b/source/blender/editors/transform/transform_orientations.c
@@ -89,7 +89,7 @@ static TransformOrientation *findOrientationName(ListBase *lb, const char *name)
return NULL;
}
-static int uniqueOrientationNameCheck(void *arg, const char *name)
+static bool uniqueOrientationNameCheck(void *arg, const char *name)
{
return findOrientationName((ListBase *)arg, name) != NULL;
}
@@ -409,14 +409,16 @@ const char *BIF_menustringTransformOrientation(const bContext *C, const char *ti
int i = V3D_MANIP_CUSTOM;
char *str_menu, *p;
const int elem_size = MAX_NAME + 4;
+ size_t str_menu_size;
title = IFACE_(title);
- str_menu = MEM_callocN(strlen(menu) + strlen(title) + 1 + elem_size * BIF_countTransformOrientation(C), "UserTransSpace from matrix");
+ str_menu_size = strlen(menu) + strlen(title) + 1 + (elem_size * BIF_countTransformOrientation(C));
+ str_menu = MEM_callocN(str_menu_size, "UserTransSpace from matrix");
+
p = str_menu;
-
- p += sprintf(str_menu, "%s", title);
- p += sprintf(p, "%s", menu);
+ p += BLI_strncpy_rlen(p, title, str_menu_size);
+ p += BLI_strncpy_rlen(p, menu, str_menu_size - (p - str_menu));
for (ts = transform_spaces->first; ts; ts = ts->next) {
p += sprintf(p, "|%s %%x%d", ts->name, i++);
diff --git a/source/blender/editors/transform/transform_snap.c b/source/blender/editors/transform/transform_snap.c
index 2efd35327c7..c92cd77449e 100644
--- a/source/blender/editors/transform/transform_snap.c
+++ b/source/blender/editors/transform/transform_snap.c
@@ -47,8 +47,6 @@
#include "DNA_view3d_types.h"
#include "DNA_windowmanager_types.h"
-#include "RNA_access.h"
-
#include "BLI_math.h"
#include "BLI_blenlib.h"
#include "BLI_utildefines.h"
@@ -62,6 +60,10 @@
#include "BKE_tessmesh.h"
#include "BKE_mesh.h"
+#include "RNA_access.h"
+
+#include "WM_types.h"
+
#include "ED_armature.h"
#include "ED_image.h"
#include "ED_mesh.h"
@@ -69,8 +71,6 @@
#include "ED_uvedit.h"
#include "ED_view3d.h"
-#include "WM_types.h"
-
#include "UI_resources.h"
#include "UI_view2d.h"
@@ -103,7 +103,7 @@ static float ResizeBetween(TransInfo *t, float p1[3], float p2[3]);
/****************** IMPLEMENTATIONS *********************/
-static int snapNodeTest(View2D *v2d, bNode *node, SnapMode mode);
+static bool snapNodeTest(View2D *v2d, bNode *node, SnapMode mode);
static NodeBorder snapNodeBorder(int snap_node_mode);
#if 0
@@ -260,7 +260,7 @@ void drawSnapping(const struct bContext *C, TransInfo *t)
}
}
-int handleSnapping(TransInfo *t, wmEvent *event)
+int handleSnapping(TransInfo *t, const wmEvent *event)
{
int status = 0;
@@ -807,7 +807,7 @@ static float ResizeBetween(TransInfo *t, float p1[3], float p2[3])
/********************** CALC **************************/
-static void UNUSED_FUNCTION(CalcSnapGrid) (TransInfo * t, float *UNUSED(vec))
+static void UNUSED_FUNCTION(CalcSnapGrid) (TransInfo *t, float *UNUSED(vec))
{
snapGridAction(t, t->tsnap.snapPoint, BIG_GEARS);
}
@@ -818,7 +818,7 @@ static void CalcSnapGeometry(TransInfo *t, float *UNUSED(vec))
float loc[3];
float no[3];
float mval[2];
- int found = 0;
+ bool found = false;
int dist = SNAP_MIN_DISTANCE; // Use a user defined value here
mval[0] = t->mval[0];
@@ -901,7 +901,7 @@ static void CalcSnapGeometry(TransInfo *t, float *UNUSED(vec))
no[0] = 0.0;
no[1] = 0.0;
no[2] = 1.0;
- found = 1;
+ found = true;
}
BLI_freelistN(&depth_peels);
@@ -910,7 +910,7 @@ static void CalcSnapGeometry(TransInfo *t, float *UNUSED(vec))
found = snapObjectsTransform(t, mval, &dist, loc, no, t->tsnap.modeSelect);
}
- if (found == 1) {
+ if (found == true) {
float tangent[3];
sub_v3_v3v3(tangent, loc, t->tsnap.snapPoint);
@@ -1144,13 +1144,13 @@ 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][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)
+static bool 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)
{
float intersect[3] = {0, 0, 0}, ray_end[3], dvec[3];
int result;
- int retval = 0;
+ bool retval = false;
copy_v3_v3(ray_end, ray_normal_local);
mul_v3_fl(ray_end, 2000);
@@ -1206,7 +1206,7 @@ static int snapEdge(ARegion *ar, float v1co[3], short v1no[3], float v2co[3], sh
float n1[3], n2[3];
*r_depth = new_depth;
- retval = 1;
+ retval = true;
sub_v3_v3v3(edge_loc, v1co, v2co);
sub_v3_v3v3(vec, intersect, v2co);
@@ -1231,11 +1231,11 @@ 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][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)
+static bool 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)
{
- int retval = 0;
+ bool retval = false;
float dvec[3];
sub_v3_v3v3(dvec, vco, ray_start_local);
@@ -1262,7 +1262,7 @@ static int snapVertex(ARegion *ar, float vco[3], short vno[3], float obmat[4][4]
if (new_dist <= *r_dist && new_depth < *r_depth) {
*r_depth = new_depth;
- retval = 1;
+ retval = true;
copy_v3_v3(r_loc, location);
@@ -1279,13 +1279,13 @@ static int snapVertex(ARegion *ar, float vco[3], short vno[3], float obmat[4][4]
return retval;
}
-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)
+static bool 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)
{
float imat[4][4];
float ray_start_local[3], ray_normal_local[3];
- int retval = 0;
+ bool retval = false;
invert_m4_m4(imat, obmat);
@@ -1342,11 +1342,11 @@ 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][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)
+static bool 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)
{
- int retval = 0;
+ bool retval = false;
int totvert = dm->getNumVerts(dm);
int totface = dm->getNumTessFaces(dm);
@@ -1514,12 +1514,12 @@ 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][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)
+static bool 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)
{
ToolSettings *ts = scene->toolsettings;
- int retval = 0;
+ bool retval = false;
if (ob->type == OB_MESH) {
BMEditMesh *em;
@@ -1546,12 +1546,12 @@ static int snapObject(Scene *scene, ARegion *ar, Object *ob, int editobject, flo
return retval;
}
-static int snapObjects(Scene *scene, View3D *v3d, ARegion *ar, Object *obedit, const float mval[2],
- int *r_dist, float r_loc[3], float r_no[3], SnapMode mode)
+static bool snapObjects(Scene *scene, View3D *v3d, ARegion *ar, Object *obedit, const float mval[2],
+ int *r_dist, float r_loc[3], float r_no[3], SnapMode mode)
{
Base *base;
- float depth = FLT_MAX;
- int retval = 0;
+ float depth = (FLT_MAX / 2.0f); /* use half of flt-max so we can scale up without an exception */
+ bool retval = false;
float ray_start[3], ray_normal[3];
ED_view3d_win_to_ray(ar, v3d, mval, ray_start, ray_normal);
@@ -1602,12 +1602,12 @@ static int snapObjects(Scene *scene, View3D *v3d, ARegion *ar, Object *obedit, c
return retval;
}
-int snapObjectsTransform(TransInfo *t, const float mval[2], int *r_dist, float r_loc[3], float r_no[3], SnapMode mode)
+bool snapObjectsTransform(TransInfo *t, const float mval[2], int *r_dist, float r_loc[3], float r_no[3], SnapMode mode)
{
return snapObjects(t->scene, t->view, t->ar, t->obedit, mval, r_dist, r_loc, r_no, mode);
}
-int snapObjectsContext(bContext *C, const float mval[2], int *r_dist, float r_loc[3], float r_no[3], SnapMode mode)
+bool snapObjectsContext(bContext *C, const float mval[2], int *r_dist, float r_loc[3], float r_no[3], SnapMode mode)
{
ScrArea *sa = CTX_wm_area(C);
View3D *v3d = sa->spacedata.first;
@@ -1667,11 +1667,11 @@ 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][4],
- const float ray_start[3], const float ray_normal[3], const float UNUSED(mval[2]),
- ListBase *depth_peels)
+static bool 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)
{
- int retval = 0;
+ bool retval = false;
int totvert = dm->getNumVerts(dm);
int totface = dm->getNumTessFaces(dm);
@@ -1776,10 +1776,11 @@ static int peelDerivedMesh(Object *ob, DerivedMesh *dm, float obmat[4][4],
return retval;
}
-static int peelObjects(Scene *scene, View3D *v3d, ARegion *ar, Object *obedit, ListBase *depth_peels, const float mval[2], SnapMode mode)
+static bool peelObjects(Scene *scene, View3D *v3d, ARegion *ar, Object *obedit,
+ ListBase *depth_peels, const float mval[2], SnapMode mode)
{
Base *base;
- int retval = 0;
+ bool retval = false;
float ray_start[3], ray_normal[3];
ED_view3d_win_to_ray(ar, v3d, mval, ray_start, ray_normal);
@@ -1798,7 +1799,7 @@ static int peelObjects(Scene *scene, View3D *v3d, ARegion *ar, Object *obedit, L
if (dob->type == OB_MESH) {
BMEditMesh *em;
DerivedMesh *dm = NULL;
- int val;
+ bool val;
if (dob != obedit) {
dm = mesh_get_derived_final(scene, dob, CD_MASK_BAREMESH);
@@ -1822,7 +1823,7 @@ static int peelObjects(Scene *scene, View3D *v3d, ARegion *ar, Object *obedit, L
}
if (ob->type == OB_MESH) {
- int val = 0;
+ bool val = false;
if (ob != obedit && ((mode == SNAP_NOT_SELECTED && (base->flag & (SELECT | BA_WAS_SEL)) == 0) || ELEM(mode, SNAP_ALL, SNAP_NOT_OBEDIT))) {
DerivedMesh *dm = mesh_get_derived_final(scene, ob, CD_MASK_BAREMESH);
@@ -1850,12 +1851,12 @@ static int peelObjects(Scene *scene, View3D *v3d, ARegion *ar, Object *obedit, L
return retval;
}
-int peelObjectsTransForm(TransInfo *t, ListBase *depth_peels, const float mval[2], SnapMode mode)
+bool peelObjectsTransForm(TransInfo *t, ListBase *depth_peels, const float mval[2], SnapMode mode)
{
return peelObjects(t->scene, t->view, t->ar, t->obedit, depth_peels, mval, mode);
}
-int peelObjectsContext(bContext *C, ListBase *depth_peels, const float mval[2], SnapMode mode)
+bool peelObjectsContext(bContext *C, ListBase *depth_peels, const float mval[2], SnapMode mode)
{
ScrArea *sa = CTX_wm_area(C);
View3D *v3d = sa->spacedata.first;
@@ -1865,7 +1866,7 @@ int peelObjectsContext(bContext *C, ListBase *depth_peels, const float mval[2],
/******************** NODES ***********************************/
-static int snapNodeTest(View2D *v2d, bNode *node, SnapMode mode)
+static bool snapNodeTest(View2D *v2d, bNode *node, SnapMode mode)
{
/* node is use for snapping only if a) snap mode matches and b) node is inside the view */
return ((mode == SNAP_NOT_SELECTED && !(node->flag & NODE_SELECT)) ||
@@ -1887,12 +1888,12 @@ static NodeBorder snapNodeBorder(int snap_node_mode)
return 0;
}
-static int snapNode(ToolSettings *ts, SpaceNode *UNUSED(snode), ARegion *ar, bNode *node, const int mval[2],
- float r_loc[2], int *r_dist, char *r_node_border)
+static bool snapNode(ToolSettings *ts, SpaceNode *UNUSED(snode), ARegion *ar, bNode *node, const int mval[2],
+ float r_loc[2], int *r_dist, char *r_node_border)
{
View2D *v2d = &ar->v2d;
NodeBorder border = snapNodeBorder(ts->snap_node_mode);
- int retval = 0;
+ bool retval = false;
rcti totr;
int new_dist;
@@ -1905,7 +1906,7 @@ static int snapNode(ToolSettings *ts, SpaceNode *UNUSED(snode), ARegion *ar, bNo
UI_view2d_region_to_view(v2d, totr.xmin, mval[1], &r_loc[0], &r_loc[1]);
*r_dist = new_dist;
*r_node_border = NODE_LEFT;
- retval = 1;
+ retval = true;
}
}
@@ -1915,7 +1916,7 @@ static int snapNode(ToolSettings *ts, SpaceNode *UNUSED(snode), ARegion *ar, bNo
UI_view2d_region_to_view(v2d, totr.xmax, mval[1], &r_loc[0], &r_loc[1]);
*r_dist = new_dist;
*r_node_border = NODE_RIGHT;
- retval = 1;
+ retval = true;
}
}
@@ -1925,7 +1926,7 @@ static int snapNode(ToolSettings *ts, SpaceNode *UNUSED(snode), ARegion *ar, bNo
UI_view2d_region_to_view(v2d, mval[0], totr.ymin, &r_loc[0], &r_loc[1]);
*r_dist = new_dist;
*r_node_border = NODE_BOTTOM;
- retval = 1;
+ retval = true;
}
}
@@ -1935,19 +1936,19 @@ static int snapNode(ToolSettings *ts, SpaceNode *UNUSED(snode), ARegion *ar, bNo
UI_view2d_region_to_view(v2d, mval[0], totr.ymax, &r_loc[0], &r_loc[1]);
*r_dist = new_dist;
*r_node_border = NODE_TOP;
- retval = 1;
+ retval = true;
}
}
return retval;
}
-static int snapNodes(ToolSettings *ts, SpaceNode *snode, ARegion *ar, const int mval[2],
+static bool snapNodes(ToolSettings *ts, SpaceNode *snode, ARegion *ar, const int mval[2],
int *r_dist, float r_loc[2], char *r_node_border, SnapMode mode)
{
bNodeTree *ntree = snode->edittree;
bNode *node;
- int retval = 0;
+ bool retval = false;
*r_node_border = 0;
@@ -1959,12 +1960,12 @@ static int snapNodes(ToolSettings *ts, SpaceNode *snode, ARegion *ar, const int
return retval;
}
-int snapNodesTransform(TransInfo *t, const int mval[2], int *r_dist, float r_loc[2], char *r_node_border, SnapMode mode)
+bool snapNodesTransform(TransInfo *t, const int mval[2], int *r_dist, float r_loc[2], char *r_node_border, SnapMode mode)
{
return snapNodes(t->settings, t->sa->spacedata.first, t->ar, mval, r_dist, r_loc, r_node_border, mode);
}
-int snapNodesContext(bContext *C, const int mval[2], int *r_dist, float r_loc[2], char *r_node_border, SnapMode mode)
+bool snapNodesContext(bContext *C, const int mval[2], int *r_dist, float r_loc[2], char *r_node_border, SnapMode mode)
{
Scene *scene = CTX_data_scene(C);
return snapNodes(scene->toolsettings, CTX_wm_space_node(C), CTX_wm_region(C), mval, r_dist, r_loc, r_node_border, mode);
diff --git a/source/blender/editors/util/ed_util.c b/source/blender/editors/util/ed_util.c
index f0f31b1e793..73062c57526 100644
--- a/source/blender/editors/util/ed_util.c
+++ b/source/blender/editors/util/ed_util.c
@@ -187,8 +187,7 @@ void unpack_menu(bContext *C, const char *opname, const char *id_name, const cha
if (G.relbase_valid) {
char local_name[FILE_MAXDIR + FILE_MAX], fi[FILE_MAX];
- BLI_strncpy(local_name, abs_name, sizeof(local_name));
- BLI_splitdirstring(local_name, fi);
+ BLI_split_file_part(abs_name, fi, sizeof(fi));
BLI_snprintf(local_name, sizeof(local_name), "//%s/%s", folder, fi);
if (strcmp(abs_name, local_name) != 0) {
switch (checkPackedFile(local_name, pf)) {
diff --git a/source/blender/editors/util/editmode_undo.c b/source/blender/editors/util/editmode_undo.c
index c8c26ed771d..7f4e05ddefa 100644
--- a/source/blender/editors/util/editmode_undo.c
+++ b/source/blender/editors/util/editmode_undo.c
@@ -246,7 +246,9 @@ void undo_editmode_step(bContext *C, int step)
}
else if (step == 1) {
- if (curundo == NULL || curundo->prev == NULL) error("No more steps to undo");
+ if (curundo == NULL || curundo->prev == NULL) {
+ error("No more steps to undo");
+ }
else {
if (G.debug & G_DEBUG) printf("undo %s\n", curundo->name);
curundo = curundo->prev;
@@ -256,7 +258,9 @@ void undo_editmode_step(bContext *C, int step)
else {
/* curundo has to remain current situation! */
- if (curundo == NULL || curundo->next == NULL) error("No more steps to redo");
+ if (curundo == NULL || curundo->next == NULL) {
+ error("No more steps to redo");
+ }
else {
undo_restore(curundo->next, curundo->getdata(C), obedit->data);
curundo = curundo->next;
diff --git a/source/blender/editors/util/numinput.c b/source/blender/editors/util/numinput.c
index 0ec16ead35d..98a1b54c452 100644
--- a/source/blender/editors/util/numinput.c
+++ b/source/blender/editors/util/numinput.c
@@ -163,7 +163,7 @@ void applyNumInput(NumInput *n, float *vec)
}
}
-char handleNumInput(NumInput *n, wmEvent *event)
+char handleNumInput(NumInput *n, const wmEvent *event)
{
float Val = 0;
short idx = n->idx, idx_max = n->idx_max;
diff --git a/source/blender/editors/util/undo.c b/source/blender/editors/util/undo.c
index ac2ee21d09d..fc603f7a593 100644
--- a/source/blender/editors/util/undo.c
+++ b/source/blender/editors/util/undo.c
@@ -475,7 +475,7 @@ static EnumPropertyItem *rna_undo_itemf(bContext *C, int undosys, int *totitem)
}
-static int undo_history_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int undo_history_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
int undosys, totitem = 0;
diff --git a/source/blender/editors/uvedit/uvedit_draw.c b/source/blender/editors/uvedit/uvedit_draw.c
index ea7e17af086..ba4879b38ca 100644
--- a/source/blender/editors/uvedit/uvedit_draw.c
+++ b/source/blender/editors/uvedit/uvedit_draw.c
@@ -50,6 +50,7 @@
#include "BKE_tessmesh.h"
#include "BLI_array.h"
+#include "BLI_buffer.h"
#include "BIF_gl.h"
#include "BIF_glutil.h"
@@ -177,6 +178,9 @@ static void draw_uvs_stretch(SpaceImage *sima, Scene *scene, BMEditMesh *em, MTe
const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV);
const int cd_poly_tex_offset = CustomData_get_offset(&bm->pdata, CD_MTEXPOLY);
+ BLI_buffer_declare_static(vec2f, tf_uv_buf, BLI_BUFFER_NOP, BM_DEFAULT_NGON_STACK_SIZE);
+ BLI_buffer_declare_static(vec2f, tf_uvorig_buf, BLI_BUFFER_NOP, BM_DEFAULT_NGON_STACK_SIZE);
+
ED_space_image_get_uv_aspect(sima, &aspx, &aspy);
switch (sima->dt_uvstretch) {
@@ -186,8 +190,8 @@ static void draw_uvs_stretch(SpaceImage *sima, Scene *scene, BMEditMesh *em, MTe
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);
+ float (*tf_uv)[2] = (float (*)[2])BLI_buffer_resize_data(&tf_uv_buf, vec2f, efa_len);
+ float (*tf_uvorig)[2] = (float (*)[2])BLI_buffer_resize_data(&tf_uvorig_buf, vec2f, efa_len);
tf = BM_ELEM_CD_GET_VOID_P(efa, cd_poly_tex_offset);
BM_ITER_ELEM_INDEX (l, &liter, efa, BM_LOOPS_OF_FACE, i) {
@@ -229,8 +233,8 @@ static void draw_uvs_stretch(SpaceImage *sima, Scene *scene, BMEditMesh *em, MTe
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);
+ float (*tf_uv)[2] = (float (*)[2])BLI_buffer_resize_data(&tf_uv_buf, vec2f, efa_len);
+ float (*tf_uvorig)[2] = (float (*)[2])BLI_buffer_resize_data(&tf_uvorig_buf, vec2f, efa_len);
area = BM_face_calc_area(efa) / totarea;
@@ -268,6 +272,11 @@ static void draw_uvs_stretch(SpaceImage *sima, Scene *scene, BMEditMesh *em, MTe
{
float a;
+ BLI_buffer_declare_static(float, uvang_buf, BLI_BUFFER_NOP, BM_DEFAULT_NGON_STACK_SIZE);
+ BLI_buffer_declare_static(float, ang_buf, BLI_BUFFER_NOP, BM_DEFAULT_NGON_STACK_SIZE);
+ BLI_buffer_declare_static(vec3f, av_buf, BLI_BUFFER_NOP, BM_DEFAULT_NGON_STACK_SIZE);
+ BLI_buffer_declare_static(vec2f, auv_buf, BLI_BUFFER_NOP, BM_DEFAULT_NGON_STACK_SIZE);
+
col[3] = 0.5f; /* hard coded alpha, not that nice */
glShadeModel(GL_SMOOTH);
@@ -277,12 +286,12 @@ static void draw_uvs_stretch(SpaceImage *sima, Scene *scene, BMEditMesh *em, MTe
if (uvedit_face_visible_test(scene, ima, efa, tf)) {
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);
+ float (*tf_uv)[2] = (float (*)[2])BLI_buffer_resize_data(&tf_uv_buf, vec2f, efa_len);
+ float (*tf_uvorig)[2] = (float (*)[2])BLI_buffer_resize_data(&tf_uvorig_buf, vec2f, efa_len);
+ float *uvang = BLI_buffer_resize_data(&uvang_buf, float, efa_len);
+ float *ang = BLI_buffer_resize_data(&ang_buf, float, efa_len);
+ float (*av)[3] = (float (*)[3])BLI_buffer_resize_data(&av_buf, vec3f, efa_len);
+ float (*auv)[2] = (float (*)[2])BLI_buffer_resize_data(&auv_buf, vec2f, efa_len);
int j;
BM_elem_flag_enable(efa, BM_ELEM_TAG);
@@ -329,11 +338,19 @@ static void draw_uvs_stretch(SpaceImage *sima, Scene *scene, BMEditMesh *em, MTe
}
}
+ BLI_buffer_free(&uvang_buf);
+ BLI_buffer_free(&ang_buf);
+ BLI_buffer_free(&av_buf);
+ BLI_buffer_free(&auv_buf);
+
glShadeModel(GL_FLAT);
break;
}
}
+
+ BLI_buffer_free(&tf_uv_buf);
+ BLI_buffer_free(&tf_uvorig_buf);
}
static void draw_uvs_other(Scene *scene, Object *obedit, Image *curimage)
diff --git a/source/blender/editors/uvedit/uvedit_ops.c b/source/blender/editors/uvedit/uvedit_ops.c
index fbb6250c05b..85375bcaf83 100644
--- a/source/blender/editors/uvedit/uvedit_ops.c
+++ b/source/blender/editors/uvedit/uvedit_ops.c
@@ -2236,7 +2236,7 @@ static int select_exec(bContext *C, wmOperator *op)
return mouse_select(C, co, extend, loop);
}
-static int select_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int select_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
ARegion *ar = CTX_wm_region(C);
float co[2];
@@ -2281,7 +2281,7 @@ static int select_loop_exec(bContext *C, wmOperator *op)
return mouse_select(C, co, extend, loop);
}
-static int select_loop_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int select_loop_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
ARegion *ar = CTX_wm_region(C);
float co[2];
@@ -2314,7 +2314,7 @@ static void UV_OT_select_loop(wmOperatorType *ot)
/* ******************** linked select operator **************** */
-static int select_linked_internal(bContext *C, wmOperator *op, wmEvent *event, int pick)
+static int select_linked_internal(bContext *C, wmOperator *op, const wmEvent *event, int pick)
{
SpaceImage *sima = CTX_wm_space_image(C);
Scene *scene = CTX_data_scene(C);
@@ -2384,7 +2384,7 @@ static void UV_OT_select_linked(wmOperatorType *ot)
"Extend", "Extend selection rather than clearing the existing selection");
}
-static int select_linked_pick_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int select_linked_pick_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
return select_linked_internal(C, op, event, 1);
}
@@ -3748,7 +3748,7 @@ static int set_2d_cursor_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int set_2d_cursor_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int set_2d_cursor_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
ARegion *ar = CTX_wm_region(C);
float location[2];
@@ -3799,7 +3799,7 @@ static int set_tile_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
-static int set_tile_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int set_tile_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
SpaceImage *sima = CTX_wm_space_image(C);
Image *ima = CTX_data_edit_image(C);
diff --git a/source/blender/editors/uvedit/uvedit_smart_stitch.c b/source/blender/editors/uvedit/uvedit_smart_stitch.c
index 5bb8105cd14..4c56a016176 100644
--- a/source/blender/editors/uvedit/uvedit_smart_stitch.c
+++ b/source/blender/editors/uvedit/uvedit_smart_stitch.c
@@ -41,6 +41,7 @@
#include "DNA_meshdata_types.h"
#include "DNA_scene_types.h"
+#include "BLI_utildefines.h"
#include "BLI_ghash.h"
#include "BLI_math.h"
#include "BLI_math_vector.h"
@@ -1748,7 +1749,7 @@ static int stitch_init(bContext *C, wmOperator *op)
state->total_separate_edges = total_edges;
/* fill the edges with data */
- for (i = 0, BLI_ghashIterator_init(ghi, edge_hash); !BLI_ghashIterator_isDone(ghi); BLI_ghashIterator_step(ghi)) {
+ for (i = 0, BLI_ghashIterator_init(ghi, edge_hash); BLI_ghashIterator_notDone(ghi); BLI_ghashIterator_step(ghi)) {
edges[i++] = *((UvEdge *)BLI_ghashIterator_getKey(ghi));
}
@@ -1910,7 +1911,7 @@ static int stitch_init(bContext *C, wmOperator *op)
return 1;
}
-static int stitch_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int stitch_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
Object *obedit = CTX_data_edit_object(C);
if (!stitch_init(C, op))
@@ -2000,7 +2001,7 @@ static int stitch_exec(bContext *C, wmOperator *op)
}
}
-static void stitch_select(bContext *C, Scene *scene, wmEvent *event, StitchState *state)
+static void stitch_select(bContext *C, Scene *scene, const wmEvent *event, StitchState *state)
{
/* add uv under mouse to processed uv's */
float co[2];
@@ -2034,7 +2035,7 @@ static void stitch_select(bContext *C, Scene *scene, wmEvent *event, StitchState
}
}
-static int stitch_modal(bContext *C, wmOperator *op, wmEvent *event)
+static int stitch_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
StitchState *state;
Scene *scene = CTX_data_scene(C);
diff --git a/source/blender/editors/uvedit/uvedit_unwrap_ops.c b/source/blender/editors/uvedit/uvedit_unwrap_ops.c
index 4ddf4bd6a5c..9de43fc9d6b 100644
--- a/source/blender/editors/uvedit/uvedit_unwrap_ops.c
+++ b/source/blender/editors/uvedit/uvedit_unwrap_ops.c
@@ -654,7 +654,7 @@ static int minimize_stretch_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int minimize_stretch_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int minimize_stretch_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
MinStretch *ms;
@@ -670,7 +670,7 @@ static int minimize_stretch_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(
return OPERATOR_RUNNING_MODAL;
}
-static int minimize_stretch_modal(bContext *C, wmOperator *op, wmEvent *event)
+static int minimize_stretch_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
MinStretch *ms = op->customdata;
diff --git a/source/blender/gpu/CMakeLists.txt b/source/blender/gpu/CMakeLists.txt
index faeb0f721f4..485f5d65853 100644
--- a/source/blender/gpu/CMakeLists.txt
+++ b/source/blender/gpu/CMakeLists.txt
@@ -50,21 +50,22 @@ set(SRC
intern/gpu_codegen.c
intern/gpu_draw.c
intern/gpu_extensions.c
- intern/gpu_fixed_material.c
intern/gpu_material.c
+ intern/gpu_simple_shader.c
GPU_buffers.h
GPU_draw.h
GPU_extensions.h
GPU_material.h
+ GPU_simple_shader.h
intern/gpu_codegen.h
)
-data_to_c_simple(shaders/gpu_shader_fixed_fragment.glsl SRC)
-data_to_c_simple(shaders/gpu_shader_fixed_vertex.glsl SRC)
data_to_c_simple(shaders/gpu_shader_material.glsl SRC)
data_to_c_simple(shaders/gpu_shader_sep_gaussian_blur_frag.glsl SRC)
data_to_c_simple(shaders/gpu_shader_sep_gaussian_blur_vert.glsl SRC)
+data_to_c_simple(shaders/gpu_shader_simple_frag.glsl SRC)
+data_to_c_simple(shaders/gpu_shader_simple_vert.glsl SRC)
data_to_c_simple(shaders/gpu_shader_vertex.glsl SRC)
data_to_c_simple(shaders/gpu_shader_vsm_store_frag.glsl SRC)
data_to_c_simple(shaders/gpu_shader_vsm_store_vert.glsl SRC)
diff --git a/source/blender/gpu/GPU_extensions.h b/source/blender/gpu/GPU_extensions.h
index 7492304bd40..0ae45775473 100644
--- a/source/blender/gpu/GPU_extensions.h
+++ b/source/blender/gpu/GPU_extensions.h
@@ -157,6 +157,8 @@ void GPU_offscreen_free(GPUOffScreen *ofs);
void GPU_offscreen_bind(GPUOffScreen *ofs);
void GPU_offscreen_unbind(GPUOffScreen *ofs);
void GPU_offscreen_read_pixels(GPUOffScreen *ofs, int type, void *pixels);
+int GPU_offscreen_width(GPUOffScreen *ofs);
+int GPU_offscreen_height(GPUOffScreen *ofs);
/* GPU Shader
* - only for fragment shaders now
@@ -201,30 +203,6 @@ typedef struct GPUVertexAttribs {
int totlayer;
} GPUVertexAttribs;
-/* Fixed Function Materials */
-
-typedef enum GPUFixedMaterialOption {
- GPU_FIXED_COLOR_MATERIAL = (1<<0), /* replace diffuse with glcolor */
- GPU_FIXED_SOLID_LIGHTING = (1<<1), /* use solid lighting (only 3 directional lights) */
- GPU_FIXED_SCENE_LIGHTING = (1<<2), /* use scene lighting (up to 8 arbitrary lights) */
- GPU_FIXED_TWO_SIDED = (1<<3), /* flip normals towards viewer */
- GPU_FIXED_TEXTURE_2D = (1<<4), /* use 2D texture to replace diffuse color */
-
- GPU_FIXED_OPTIONS_NUM = 5,
- GPU_FIXED_OPTION_COMBINATIONS = (1<<GPU_FIXED_OPTIONS_NUM)
-} GPUFixedMaterialOption;
-
-void GPU_fixed_materials_init(void);
-void GPU_fixed_materials_exit(void);
-
-void GPU_fixed_material_shader_bind(int options);
-void GPU_fixed_material_shader_unbind(void);
-
-void GPU_fixed_material_colors(const float diffuse[3], const float specular[3],
- int shininess, float alpha);
-
-bool GPU_fixed_material_need_normals(void);
-
#ifdef __cplusplus
}
#endif
diff --git a/source/blender/gpu/GPU_simple_shader.h b/source/blender/gpu/GPU_simple_shader.h
new file mode 100644
index 00000000000..c8fb1f09b04
--- /dev/null
+++ b/source/blender/gpu/GPU_simple_shader.h
@@ -0,0 +1,89 @@
+/*
+ * ***** 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) 2005 Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): Brecht Van Lommel.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file GPU_simple_shader.h
+ * \ingroup gpu
+ */
+
+#ifndef __GPU_SIMPLE_SHADER_H__
+#define __GPU_SIMPLE_SHADER_H__
+
+#include "BLI_utildefines.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Fixed Function Shader */
+
+typedef enum GPUSimpleShaderOption {
+ GPU_SHADER_OVERRIDE_DIFFUSE = (1<<0), /* replace diffuse with glcolor */
+ GPU_SHADER_LIGHTING = (1<<1), /* use lighting */
+ GPU_SHADER_TWO_SIDED = (1<<2), /* flip normals towards viewer */
+ GPU_SHADER_TEXTURE_2D = (1<<3), /* use 2D texture to replace diffuse color */
+
+ GPU_SHADER_SOLID_LIGHTING = (1<<4), /* use faster lighting (set automatically) */
+ GPU_SHADER_OPTIONS_NUM = 5,
+ GPU_SHADER_OPTION_COMBINATIONS = (1<<GPU_SHADER_OPTIONS_NUM)
+} GPUSimpleShaderOption;
+
+void GPU_simple_shaders_init(void);
+void GPU_simple_shaders_exit(void);
+
+void GPU_simple_shader_bind(int options);
+void GPU_simple_shader_unbind(void);
+
+void GPU_simple_shader_colors(const float diffuse[3], const float specular[3],
+ int shininess, float alpha);
+
+bool GPU_simple_shader_need_normals(void);
+
+/* Fixed Function Lighting */
+
+typedef struct GPULightData {
+ float position[4];
+ float diffuse[4];
+ float specular[4];
+
+ float constant_attenuation;
+ float linear_attenuation;
+ float quadratic_attenuation;
+
+ float spot_direction[3];
+ float spot_cutoff;
+ float spot_exponent;
+} GPULightData;
+
+void GPU_simple_shader_light_set(int light_num, GPULightData *light);
+void GPU_simple_shader_light_set_viewer(bool local);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/source/blender/gpu/SConscript b/source/blender/gpu/SConscript
index ccea40c0909..6e3722e403a 100644
--- a/source/blender/gpu/SConscript
+++ b/source/blender/gpu/SConscript
@@ -44,19 +44,19 @@ if env['WITH_BF_SMOKE']:
defs.append('WITH_SMOKE')
if env['WITH_BF_DDS']:
- defs.append('WITH_DDS')
+ defs.append('WITH_DDS')
# generated data files
import os
sources.extend((
- os.path.join(env['DATA_SOURCES'], "gpu_shader_fixed_fragment.glsl.c"),
- os.path.join(env['DATA_SOURCES'], "gpu_shader_fixed_vertex.glsl.c"),
- os.path.join(env['DATA_SOURCES'], "gpu_shader_material.glsl.c"),
- os.path.join(env['DATA_SOURCES'], "gpu_shader_sep_gaussian_blur_frag.glsl.c"),
- os.path.join(env['DATA_SOURCES'], "gpu_shader_sep_gaussian_blur_vert.glsl.c"),
- os.path.join(env['DATA_SOURCES'], "gpu_shader_vertex.glsl.c"),
- os.path.join(env['DATA_SOURCES'], "gpu_shader_vsm_store_frag.glsl.c"),
- os.path.join(env['DATA_SOURCES'], "gpu_shader_vsm_store_vert.glsl.c"),
- ))
+ os.path.join(env['DATA_SOURCES'], "gpu_shader_simple_frag.glsl.c"),
+ os.path.join(env['DATA_SOURCES'], "gpu_shader_simple_vert.glsl.c"),
+ os.path.join(env['DATA_SOURCES'], "gpu_shader_material.glsl.c"),
+ os.path.join(env['DATA_SOURCES'], "gpu_shader_sep_gaussian_blur_frag.glsl.c"),
+ os.path.join(env['DATA_SOURCES'], "gpu_shader_sep_gaussian_blur_vert.glsl.c"),
+ os.path.join(env['DATA_SOURCES'], "gpu_shader_vertex.glsl.c"),
+ os.path.join(env['DATA_SOURCES'], "gpu_shader_vsm_store_frag.glsl.c"),
+ os.path.join(env['DATA_SOURCES'], "gpu_shader_vsm_store_vert.glsl.c"),
+ ))
env.BlenderLib ( 'bf_gpu', sources, Split(incs), defines = defs, libtype=['core','player'], priority=[160,110] )
diff --git a/source/blender/gpu/intern/gpu_codegen.c b/source/blender/gpu/intern/gpu_codegen.c
index 59953659a2c..840b16a4567 100644
--- a/source/blender/gpu/intern/gpu_codegen.c
+++ b/source/blender/gpu/intern/gpu_codegen.c
@@ -197,7 +197,7 @@ static char *gpu_generate_function_prototyps(GHash *hash)
* generated code, to avoid have to add the actual code & recompile all */
ghi = BLI_ghashIterator_new(hash);
- for (; !BLI_ghashIterator_isDone(ghi); BLI_ghashIterator_step(ghi)) {
+ for (; BLI_ghashIterator_notDone(ghi); BLI_ghashIterator_step(ghi)) {
name = BLI_ghashIterator_getValue(ghi);
function = BLI_ghashIterator_getValue(ghi);
diff --git a/source/blender/gpu/intern/gpu_draw.c b/source/blender/gpu/intern/gpu_draw.c
index c631f7efbe9..fc3bf75e784 100644
--- a/source/blender/gpu/intern/gpu_draw.c
+++ b/source/blender/gpu/intern/gpu_draw.c
@@ -189,30 +189,21 @@ void GPU_render_text(MTFace *tface, int mode,
/* Checking powers of two for images since opengl 1.x requires it */
-static int is_pow2_limit(int num)
+static bool is_power_of_2_resolution(int w, int h)
{
- /* take texture clamping into account */
-
- /* XXX: texturepaint not global! */
-#if 0
- if (G.f & G_TEXTUREPAINT)
- return 1;*/
-#endif
+ return is_power_of_2_i(w) && is_power_of_2_i(h);
+}
- if (U.glreslimit != 0 && num > U.glreslimit)
- return 0;
+static bool is_over_resolution_limit(int w, int h)
+{
+ if (U.glreslimit != 0)
+ return (w > U.glreslimit || h > U.glreslimit);
- return is_power_of_2_i(num);
+ return false;
}
-static int smaller_pow2_limit(int num)
+static int smaller_power_of_2_limit(int num)
{
- /* XXX: texturepaint not global! */
-#if 0
- if (G.f & G_TEXTUREPAINT)
- return 1;*/
-#endif
-
/* take texture clamping into account */
if (U.glreslimit != 0 && num > U.glreslimit)
return U.glreslimit;
@@ -670,7 +661,7 @@ int GPU_verify_image(Image *ima, ImageUser *iuser, int tftile, int compare, int
}
/* Image *ima can be NULL */
-void GPU_create_gl_tex(unsigned int *bind, unsigned int *pix, float * frect, int rectw, int recth, int mipmap, int use_high_bit_depth, Image *ima)
+void GPU_create_gl_tex(unsigned int *bind, unsigned int *pix, float *frect, int rectw, int recth, int mipmap, int use_high_bit_depth, Image *ima)
{
unsigned int *scalerect = NULL;
float *fscalerect = NULL;
@@ -681,9 +672,10 @@ void GPU_create_gl_tex(unsigned int *bind, unsigned int *pix, float * frect, int
/* scale if not a power of two. this is not strictly necessary for newer
* GPUs (OpenGL version >= 2.0) since they support non-power-of-two-textures
* Then don't bother scaling for hardware that supports NPOT textures! */
- if (!GPU_non_power_of_two_support() && (!is_pow2_limit(rectw) || !is_pow2_limit(recth))) {
- rectw= smaller_pow2_limit(rectw);
- recth= smaller_pow2_limit(recth);
+ if ((!GPU_non_power_of_two_support() && !is_power_of_2_resolution(rectw, recth)) ||
+ is_over_resolution_limit(rectw, recth)) {
+ rectw= smaller_power_of_2_limit(rectw);
+ recth= smaller_power_of_2_limit(recth);
if (use_high_bit_depth) {
fscalerect= MEM_mallocN(rectw*recth*sizeof(*fscalerect)*4, "fscalerect");
@@ -772,7 +764,7 @@ int GPU_upload_dxt_texture(ImBuf *ibuf)
return FALSE;
}
- if (!is_power_of_2_i(width) || !is_power_of_2_i(height)) {
+ if (!is_power_of_2_resolution(width, height)) {
printf("Unable to load non-power-of-two DXT image resolution, falling back to uncompressed\n");
return FALSE;
}
diff --git a/source/blender/gpu/intern/gpu_extensions.c b/source/blender/gpu/intern/gpu_extensions.c
index 56aa4b222cb..c7a421a49fc 100644
--- a/source/blender/gpu/intern/gpu_extensions.c
+++ b/source/blender/gpu/intern/gpu_extensions.c
@@ -44,6 +44,7 @@
#include "GPU_draw.h"
#include "GPU_extensions.h"
+#include "GPU_simple_shader.h"
#include "gpu_codegen.h"
#include <stdlib.h>
@@ -206,14 +207,14 @@ void GPU_extensions_init(void)
GG.os = GPU_OS_UNIX;
#endif
- GPU_fixed_materials_init();
+ GPU_simple_shaders_init();
}
void GPU_extensions_exit(void)
{
gpu_extensions_init = 0;
GPU_codegen_exit();
- GPU_fixed_materials_exit();
+ GPU_simple_shaders_exit();
}
int GPU_glsl_support(void)
@@ -904,10 +905,8 @@ void GPU_framebuffer_texture_bind(GPUFrameBuffer *UNUSED(fb), GPUTexture *tex, i
glMatrixMode(GL_PROJECTION);
glPushMatrix();
- glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
- glLoadIdentity();
}
void GPU_framebuffer_texture_unbind(GPUFrameBuffer *UNUSED(fb), GPUTexture *UNUSED(tex))
@@ -1095,6 +1094,16 @@ void GPU_offscreen_read_pixels(GPUOffScreen *ofs, int type, void *pixels)
glReadPixels(0, 0, ofs->w, ofs->h, GL_RGBA, type, pixels);
}
+int GPU_offscreen_width(GPUOffScreen *ofs)
+{
+ return ofs->w;
+}
+
+int GPU_offscreen_height(GPUOffScreen *ofs)
+{
+ return ofs->h;
+}
+
/* GPUShader */
struct GPUShader {
@@ -1127,6 +1136,19 @@ static void shader_print_errors(const char *task, char *log, const char *code)
fprintf(stderr, "%s\n", log);
}
+static const char *gpu_shader_standard_defines(void)
+{
+ /* some useful defines to detect GPU type */
+ if(GPU_type_matches(GPU_DEVICE_ATI, GPU_OS_ANY, GPU_DRIVER_ANY))
+ return "#define GPU_ATI\n";
+ else if(GPU_type_matches(GPU_DEVICE_NVIDIA, GPU_OS_ANY, GPU_DRIVER_ANY))
+ return "#define GPU_NVIDIA\n";
+ else if(GPU_type_matches(GPU_DEVICE_INTEL, GPU_OS_ANY, GPU_DRIVER_ANY))
+ return "#define GPU_INTEL\n";
+
+ return "";
+}
+
GPUShader *GPU_shader_create(const char *vertexcode, const char *fragcode, const char *libcode, const char *defines)
{
GLint status;
@@ -1155,9 +1177,11 @@ GPUShader *GPU_shader_create(const char *vertexcode, const char *fragcode, const
}
if (vertexcode) {
- const char *source[2];
+ const char *source[3];
int num_source = 0;
+ source[num_source++] = gpu_shader_standard_defines();
+
if (defines) source[num_source++] = defines;
if (vertexcode) source[num_source++] = vertexcode;
@@ -1177,9 +1201,11 @@ GPUShader *GPU_shader_create(const char *vertexcode, const char *fragcode, const
}
if (fragcode) {
- const char *source[3];
+ const char *source[4];
int num_source = 0;
+ source[num_source++] = gpu_shader_standard_defines();
+
if (defines) source[num_source++] = defines;
if (libcode) source[num_source++] = libcode;
if (fragcode) source[num_source++] = fragcode;
@@ -1264,7 +1290,7 @@ void GPU_shader_bind(GPUShader *shader)
GPU_print_error("Post Shader Bind");
}
-void GPU_shader_unbind()
+void GPU_shader_unbind(void)
{
GPU_print_error("Pre Shader Unbind");
glUseProgramObjectARB(0);
diff --git a/source/blender/gpu/intern/gpu_fixed_material.c b/source/blender/gpu/intern/gpu_fixed_material.c
deleted file mode 100644
index d5a04c88e89..00000000000
--- a/source/blender/gpu/intern/gpu_fixed_material.c
+++ /dev/null
@@ -1,191 +0,0 @@
-/*
- * ***** 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) 2013 Blender Foundation.
- * All rights reserved.
- *
- * The Original Code is: all of this file.
- *
- * Contributor(s): Brecht Van Lommel.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file blender/gpu/intern/gpu_fixed_material.c
- * \ingroup gpu
- */
-
-/* GLSL shaders to replace fixed function OpenGL materials and lighting. These
- * are deprecated in newer OpenGL versions and missing in OpenGL ES 2.0. Also,
- * two sided lighting is no longer natively supported on NVidia cards which
- * results in slow software fallback.
- *
- * Todo:
- * - Replace glLight and glMaterial functions entirely with GLSL uniforms, to
- * make OpenGL ES 2.0 work.
- * - Replace glTexCoord and glColor with generic attributes.
- * - Optimize for case where fewer than 3 or 8 lights are used.
- * - Optimize for case where specular is not used.
- * - Optimize for case where no texture matrix is used.
- */
-
-#include "GL/glew.h"
-
-#include "BLI_math.h"
-#include "BLI_utildefines.h"
-
-#include "DNA_mesh_types.h"
-#include "DNA_object_types.h"
-
-#include "GPU_extensions.h"
-
-/* Fixed function material types */
-
-static struct {
- GPUShader *cached_shaders[GPU_FIXED_OPTION_COMBINATIONS];
- bool failed_shaders[GPU_FIXED_OPTION_COMBINATIONS];
-
- bool need_normals;
-} GPU_MATERIAL_STATE;
-
-/* Init / exit */
-
-void GPU_fixed_materials_init()
-{
- memset(&GPU_MATERIAL_STATE, 0, sizeof(GPU_MATERIAL_STATE));
-}
-
-void GPU_fixed_materials_exit()
-{
- int i;
-
- for (i = 0; i < GPU_FIXED_OPTION_COMBINATIONS; i++)
- if (GPU_MATERIAL_STATE.cached_shaders[i])
- GPU_shader_free(GPU_MATERIAL_STATE.cached_shaders[i]);
-}
-
-/* Shader lookup / create */
-
-static GPUShader *gpu_fixed_material_shader(int options)
-{
- /* glsl code */
- extern char datatoc_gpu_shader_fixed_vertex_glsl[];
- extern char datatoc_gpu_shader_fixed_fragment_glsl[];
-
- /* cached shaders */
- GPUShader *shader = GPU_MATERIAL_STATE.cached_shaders[options];
-
- if (!shader && !GPU_MATERIAL_STATE.failed_shaders[options]) {
- /* create shader if it doesn't exist yet */
- char defines[64*GPU_FIXED_OPTIONS_NUM] = "";
-
- if (options & GPU_FIXED_COLOR_MATERIAL)
- strcat(defines, "#define USE_COLOR\n");
- if (options & GPU_FIXED_TWO_SIDED)
- strcat(defines, "#define USE_TWO_SIDED\n");
- if (options & GPU_FIXED_SOLID_LIGHTING)
- strcat(defines, "#define USE_SOLID_LIGHTING\n");
- if (options & GPU_FIXED_SCENE_LIGHTING)
- strcat(defines, "#define USE_SCENE_LIGHTING\n");
- if (options & GPU_FIXED_TEXTURE_2D)
- strcat(defines, "#define USE_TEXTURE\n");
-
- shader = GPU_shader_create(
- datatoc_gpu_shader_fixed_vertex_glsl,
- datatoc_gpu_shader_fixed_fragment_glsl,
- NULL, defines);
-
- if (shader) {
- /* set texture map to first texture unit */
- if (options & GPU_FIXED_TEXTURE_2D)
- glUniform1i(GPU_shader_get_uniform(shader, "texture_map"), 0);
-
- GPU_MATERIAL_STATE.cached_shaders[options] = shader;
- }
- else
- GPU_MATERIAL_STATE.failed_shaders[options] = true;
- }
-
- return shader;
-}
-
-/* Bind / unbind */
-
-void GPU_fixed_material_shader_bind(int options)
-{
- if (GPU_glsl_support()) {
- GPUShader *shader = gpu_fixed_material_shader(options);
-
- if (shader)
- GPU_shader_bind(shader);
- }
- else {
- if (options & (GPU_FIXED_SOLID_LIGHTING|GPU_FIXED_SCENE_LIGHTING))
- glEnable(GL_LIGHTING);
-
- if (options & GPU_FIXED_TWO_SIDED)
- glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
-
- if (options & GPU_FIXED_COLOR_MATERIAL) {
- glEnable(GL_COLOR_MATERIAL);
- glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE);
- }
-
- if (options & GPU_FIXED_TEXTURE_2D)
- glEnable(GL_TEXTURE_2D);
- }
-
- /* temporary hack, should be solved outside of this file */
- GPU_MATERIAL_STATE.need_normals = (options & (GPU_FIXED_SOLID_LIGHTING|GPU_FIXED_SCENE_LIGHTING));
-}
-
-void GPU_fixed_material_shader_unbind()
-{
- if (GPU_glsl_support()) {
- GPU_shader_unbind();
- }
- else {
- glDisable(GL_LIGHTING);
- glDisable(GL_COLOR_MATERIAL);
- glDisable(GL_TEXTURE_2D);
- glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE);
- }
-}
-
-/* Material Colors */
-
-void GPU_fixed_material_colors(const float diffuse[3], const float specular[3],
- int shininess, float alpha)
-{
- float gl_diffuse[4], gl_specular[4];
-
- copy_v3_v3(gl_diffuse, diffuse);
- gl_diffuse[3] = alpha;
-
- copy_v3_v3(gl_specular, specular);
- gl_specular[3] = 1.0f;
-
- glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, diffuse);
- glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, specular);
- glMateriali(GL_FRONT_AND_BACK, GL_SHININESS, CLAMPIS(shininess, 1, 128));
-}
-
-bool GPU_fixed_material_need_normals()
-{
- return GPU_MATERIAL_STATE.need_normals;
-}
-
diff --git a/source/blender/gpu/intern/gpu_material.c b/source/blender/gpu/intern/gpu_material.c
index d7ac6febfb7..636c44d3e80 100644
--- a/source/blender/gpu/intern/gpu_material.c
+++ b/source/blender/gpu/intern/gpu_material.c
@@ -1035,7 +1035,7 @@ static void do_material_tex(GPUShadeInput *shi)
GPU_link(mat, "mtex_image", texco, GPU_image(tex->ima, &tex->iuser, FALSE), &tin, &trgb);
rgbnor= TEX_RGB;
- talpha = (tex->ima->flag & IMA_IGNORE_ALPHA) == 0;
+ talpha = ((tex->imaflag & TEX_USEALPHA) && tex->ima && (tex->ima->flag & IMA_IGNORE_ALPHA) == 0);
}
else {
continue;
diff --git a/source/blender/gpu/intern/gpu_simple_shader.c b/source/blender/gpu/intern/gpu_simple_shader.c
new file mode 100644
index 00000000000..b29d6c2e681
--- /dev/null
+++ b/source/blender/gpu/intern/gpu_simple_shader.c
@@ -0,0 +1,283 @@
+/*
+ * ***** 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) 2013 Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): Brecht Van Lommel.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/gpu/intern/gpu_simple_shader.c
+ * \ingroup gpu
+ */
+
+/* GLSL shaders to replace fixed function OpenGL materials and lighting. These
+ * are deprecated in newer OpenGL versions and missing in OpenGL ES 2.0. Also,
+ * two sided lighting is no longer natively supported on NVidia cards which
+ * results in slow software fallback.
+ *
+ * Todo:
+ * - Replace glLight and glMaterial functions entirely with GLSL uniforms, to
+ * make OpenGL ES 2.0 work.
+ * - Replace glTexCoord and glColor with generic attributes.
+ * - Optimize for case where fewer than 3 or 8 lights are used.
+ * - Optimize for case where specular is not used.
+ * - Optimize for case where no texture matrix is used.
+ */
+
+#include "GL/glew.h"
+
+#include "BLI_math.h"
+#include "BLI_utildefines.h"
+
+#include "DNA_mesh_types.h"
+#include "DNA_object_types.h"
+
+#include "GPU_extensions.h"
+#include "GPU_simple_shader.h"
+
+/* State */
+
+#define NUM_OPENGL_LIGHTS 8
+
+static struct {
+ GPUShader *cached_shaders[GPU_SHADER_OPTION_COMBINATIONS];
+ bool failed_shaders[GPU_SHADER_OPTION_COMBINATIONS];
+
+ bool need_normals;
+
+ int lights_enabled;
+ int lights_directional;
+} GPU_MATERIAL_STATE;
+
+/* Init / exit */
+
+void GPU_simple_shaders_init(void)
+{
+ memset(&GPU_MATERIAL_STATE, 0, sizeof(GPU_MATERIAL_STATE));
+}
+
+void GPU_simple_shaders_exit(void)
+{
+ int i;
+
+ for (i = 0; i < GPU_SHADER_OPTION_COMBINATIONS; i++)
+ if (GPU_MATERIAL_STATE.cached_shaders[i])
+ GPU_shader_free(GPU_MATERIAL_STATE.cached_shaders[i]);
+}
+
+/* Shader lookup / create */
+
+static bool solid_compatible_lighting(void)
+{
+ int enabled = GPU_MATERIAL_STATE.lights_enabled;
+ int directional = GPU_MATERIAL_STATE.lights_directional;
+
+ /* more than 3 lights? */
+ if (enabled >= (1 << 3))
+ return false;
+
+ /* all directional? */
+ return ((directional & enabled) == enabled);
+}
+
+#if 0
+static int detect_options()
+{
+ GLint two_sided;
+ int options = 0;
+
+ if (glIsEnabled(GL_TEXTURE_2D))
+ options |= GPU_SHADER_TEXTURE_2D;
+ if (glIsEnabled(GL_COLOR_MATERIAL))
+ options |= GPU_SHADER_OVERRIDE_DIFFUSE;
+
+ if (glIsEnabled(GL_LIGHTING))
+ options |= GPU_SHADER_LIGHTING;
+
+ glGetIntegerv(GL_LIGHT_MODEL_TWO_SIDE, &two_sided);
+ if (two_sided == GL_TRUE)
+ options |= GPU_SHADER_TWO_SIDED;
+
+ return options;
+}
+#endif
+
+static GPUShader *gpu_simple_shader(int options)
+{
+ /* glsl code */
+ extern char datatoc_gpu_shader_simple_vert_glsl[];
+ extern char datatoc_gpu_shader_simple_frag_glsl[];
+ GPUShader *shader;
+
+ /* detect if we can do faster lighting for solid draw mode */
+ if (options & GPU_SHADER_LIGHTING)
+ if (solid_compatible_lighting())
+ options |= GPU_SHADER_SOLID_LIGHTING;
+
+ /* cached shaders */
+ shader = GPU_MATERIAL_STATE.cached_shaders[options];
+
+ if (!shader && !GPU_MATERIAL_STATE.failed_shaders[options]) {
+ /* create shader if it doesn't exist yet */
+ char defines[64*GPU_SHADER_OPTIONS_NUM] = "";
+
+ if (options & GPU_SHADER_OVERRIDE_DIFFUSE)
+ strcat(defines, "#define USE_COLOR\n");
+ if (options & GPU_SHADER_TWO_SIDED)
+ strcat(defines, "#define USE_TWO_SIDED\n");
+ if (options & GPU_SHADER_TEXTURE_2D)
+ strcat(defines, "#define USE_TEXTURE\n");
+
+ if (options & GPU_SHADER_SOLID_LIGHTING)
+ strcat(defines, "#define USE_SOLID_LIGHTING\n");
+ else if (options & GPU_SHADER_LIGHTING)
+ strcat(defines, "#define USE_SCENE_LIGHTING\n");
+
+ shader = GPU_shader_create(
+ datatoc_gpu_shader_simple_vert_glsl,
+ datatoc_gpu_shader_simple_frag_glsl,
+ NULL, defines);
+
+ if (shader) {
+ /* set texture map to first texture unit */
+ if (options & GPU_SHADER_TEXTURE_2D)
+ glUniform1i(GPU_shader_get_uniform(shader, "texture_map"), 0);
+
+ GPU_MATERIAL_STATE.cached_shaders[options] = shader;
+ }
+ else
+ GPU_MATERIAL_STATE.failed_shaders[options] = true;
+ }
+
+ return shader;
+}
+
+/* Bind / unbind */
+
+void GPU_simple_shader_bind(int options)
+{
+ if (GPU_glsl_support()) {
+ GPUShader *shader = gpu_simple_shader(options);
+
+ if (shader)
+ GPU_shader_bind(shader);
+ }
+ else {
+ // XXX where does this fit, depends on ortho/persp?
+
+ if (options & GPU_SHADER_LIGHTING)
+ glEnable(GL_LIGHTING);
+
+ if (options & GPU_SHADER_TWO_SIDED)
+ glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
+
+ if (options & GPU_SHADER_OVERRIDE_DIFFUSE) {
+ glEnable(GL_COLOR_MATERIAL);
+ glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE);
+ }
+
+ if (options & GPU_SHADER_TEXTURE_2D)
+ glEnable(GL_TEXTURE_2D);
+ }
+
+ /* temporary hack, should be solved outside of this file */
+ GPU_MATERIAL_STATE.need_normals = (options & GPU_SHADER_LIGHTING);
+}
+
+void GPU_simple_shader_unbind(void)
+{
+ if (GPU_glsl_support()) {
+ GPU_shader_unbind();
+ }
+ else {
+ glDisable(GL_LIGHTING);
+ glDisable(GL_COLOR_MATERIAL);
+ glDisable(GL_TEXTURE_2D);
+ glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE);
+ }
+}
+
+/* Material Colors */
+
+void GPU_simple_shader_colors(const float diffuse[3], const float specular[3],
+ int shininess, float alpha)
+{
+ float gl_diffuse[4], gl_specular[4];
+
+ copy_v3_v3(gl_diffuse, diffuse);
+ gl_diffuse[3] = alpha;
+
+ copy_v3_v3(gl_specular, specular);
+ gl_specular[3] = 1.0f;
+
+ glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, gl_diffuse);
+ glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, gl_specular);
+ glMateriali(GL_FRONT_AND_BACK, GL_SHININESS, CLAMPIS(shininess, 1, 128));
+}
+
+bool GPU_simple_shader_need_normals(void)
+{
+ return GPU_MATERIAL_STATE.need_normals;
+}
+
+void GPU_simple_shader_light_set(int light_num, GPULightData *light)
+{
+ int light_bit = (1 << light_num);
+
+ GPU_MATERIAL_STATE.lights_enabled &= ~light_bit;
+ GPU_MATERIAL_STATE.lights_directional &= ~light_bit;
+
+ if (light) {
+ glEnable(GL_LIGHT0+light_num);
+
+ glLightfv(GL_LIGHT0+light_num, GL_POSITION, light->position);
+ glLightfv(GL_LIGHT0+light_num, GL_DIFFUSE, light->diffuse);
+ glLightfv(GL_LIGHT0+light_num, GL_SPECULAR, light->specular);
+
+ glLightf(GL_LIGHT0+light_num, GL_CONSTANT_ATTENUATION, light->constant_attenuation);
+ glLightf(GL_LIGHT0+light_num, GL_LINEAR_ATTENUATION, light->linear_attenuation);
+ glLightf(GL_LIGHT0+light_num, GL_QUADRATIC_ATTENUATION, light->quadratic_attenuation);
+
+ glLightfv(GL_LIGHT0+light_num, GL_SPOT_DIRECTION, light->spot_direction);
+ glLightf(GL_LIGHT0+light_num, GL_SPOT_CUTOFF, light->spot_cutoff);
+ glLightf(GL_LIGHT0+light_num, GL_SPOT_EXPONENT, light->spot_exponent);
+
+ GPU_MATERIAL_STATE.lights_enabled |= light_bit;
+ if(light->position[3] == 0.0f)
+ GPU_MATERIAL_STATE.lights_directional |= light_bit;
+ }
+ else {
+ const float zero[4] = {0.0f, 0.0f, 0.0f, 0.0f};
+
+ glLightfv(GL_LIGHT0+light_num, GL_POSITION, zero);
+ glLightfv(GL_LIGHT0+light_num, GL_DIFFUSE, zero);
+ glLightfv(GL_LIGHT0+light_num, GL_SPECULAR, zero);
+
+ glDisable(GL_LIGHT0+light_num);
+ }
+}
+
+void GPU_simple_shader_light_set_viewer(bool local)
+{
+ glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, (local)? GL_TRUE: GL_FALSE);
+}
+
diff --git a/source/blender/gpu/shaders/gpu_shader_material.glsl b/source/blender/gpu/shaders/gpu_shader_material.glsl
index 8fc18bf8726..4fc04175bba 100644
--- a/source/blender/gpu/shaders/gpu_shader_material.glsl
+++ b/source/blender/gpu/shaders/gpu_shader_material.glsl
@@ -233,7 +233,7 @@ void math_pow(float val1, float val2, out float outval)
else {
float val2_mod_1 = mod(abs(val2), 1.0);
- if (val2_mod_1 > 0.999 || val2_mod_1 < 0.001)
+ if (val2_mod_1 > 0.999 || val2_mod_1 < 0.001)
outval = compatible_pow(val1, floor(val2 + 0.5));
else
outval = 0.0;
diff --git a/source/blender/gpu/shaders/gpu_shader_fixed_fragment.glsl b/source/blender/gpu/shaders/gpu_shader_simple_frag.glsl
index 9610e0cf5aa..9610e0cf5aa 100644
--- a/source/blender/gpu/shaders/gpu_shader_fixed_fragment.glsl
+++ b/source/blender/gpu/shaders/gpu_shader_simple_frag.glsl
diff --git a/source/blender/gpu/shaders/gpu_shader_fixed_vertex.glsl b/source/blender/gpu/shaders/gpu_shader_simple_vert.glsl
index 612f9cff6aa..9491eaa672d 100644
--- a/source/blender/gpu/shaders/gpu_shader_fixed_vertex.glsl
+++ b/source/blender/gpu/shaders/gpu_shader_simple_vert.glsl
@@ -29,11 +29,9 @@ void main()
gl_Position = gl_ProjectionMatrix * co;
-#ifdef __GLSL_CG_DATA_TYPES
- // Setting gl_ClipVertex is necessary to get glClipPlane working on NVIDIA graphic cards.
- // gl_ClipVertex works only on NVIDIA graphic cards so we have to check with
- // __GLSL_CG_DATA_TYPES if a NVIDIA graphic card is used (Cg support).
- // gl_ClipVerte is supported up to GLSL 1.20.
+#ifdef GPU_NVIDIA
+ // Setting gl_ClipVertex is necessary to get glClipPlane working on NVIDIA
+ // graphic cards, while on ATI it can cause a software fallback.
gl_ClipVertex = gl_ModelViewMatrix * gl_Vertex;
#endif
diff --git a/source/blender/gpu/shaders/gpu_shader_vertex.glsl b/source/blender/gpu/shaders/gpu_shader_vertex.glsl
index 9e0db44ed31..8741a13ea9b 100644
--- a/source/blender/gpu/shaders/gpu_shader_vertex.glsl
+++ b/source/blender/gpu/shaders/gpu_shader_vertex.glsl
@@ -10,11 +10,9 @@ void main()
varnormal = normalize(gl_NormalMatrix * gl_Normal);
gl_Position = gl_ProjectionMatrix * co;
- // Setting gl_ClipVertex is necessary to get glClipPlane working on NVIDIA graphic cards.
- // gl_ClipVertex works only on NVIDIA graphic cards so we have to check with
- // __GLSL_CG_DATA_TYPES if a NVIDIA graphic card is used (Cg support).
- // gl_ClipVerte is supported up to GLSL 1.20.
-#ifdef __GLSL_CG_DATA_TYPES
+#ifdef GPU_NVIDIA
+ // Setting gl_ClipVertex is necessary to get glClipPlane working on NVIDIA
+ // graphic cards, while on ATI it can cause a software fallback.
gl_ClipVertex = gl_ModelViewMatrix * gl_Vertex;
#endif
diff --git a/source/blender/ikplugin/intern/iksolver_plugin.c b/source/blender/ikplugin/intern/iksolver_plugin.c
index 67f0694797b..9ec115f10e8 100644
--- a/source/blender/ikplugin/intern/iksolver_plugin.c
+++ b/source/blender/ikplugin/intern/iksolver_plugin.c
@@ -200,7 +200,9 @@ static void make_dmats(bPoseChannel *pchan)
invert_m4_m4(iR_parmat, pchan->parent->pose_mat);
mult_m4_m4m4(pchan->chan_mat, iR_parmat, pchan->pose_mat); // delta mat
}
- else copy_m4_m4(pchan->chan_mat, pchan->pose_mat);
+ else {
+ copy_m4_m4(pchan->chan_mat, pchan->pose_mat);
+ }
}
/* applies IK matrix to pchan, IK is done separated */
diff --git a/source/blender/imbuf/IMB_imbuf.h b/source/blender/imbuf/IMB_imbuf.h
index a19433dbd2f..48c14fc07f2 100644
--- a/source/blender/imbuf/IMB_imbuf.h
+++ b/source/blender/imbuf/IMB_imbuf.h
@@ -338,6 +338,12 @@ struct ImBuf *IMB_scalefastImBuf(struct ImBuf *ibuf, unsigned int newx, unsigned
/**
*
+ * \attention Defined in scaling.c
+ */
+void IMB_scaleImBuf_threaded(struct ImBuf *ibuf, unsigned int newx, unsigned int newy);
+
+/**
+ *
* \attention Defined in writeimage.c
*/
short IMB_saveiff(struct ImBuf *ibuf, const char *filepath, int flags);
diff --git a/source/blender/imbuf/IMB_imbuf_types.h b/source/blender/imbuf/IMB_imbuf_types.h
index dde8d4d4ab7..a3629d079a3 100644
--- a/source/blender/imbuf/IMB_imbuf_types.h
+++ b/source/blender/imbuf/IMB_imbuf_types.h
@@ -179,6 +179,7 @@ typedef struct ImBuf {
* Note that the lower 11 bits is used for storing custom flags
*/
#define IB_CUSTOM_FLAGS_MASK 0x7ff
+#define IB_ALPHA_MASK 0xff
#define PNG (1 << 30)
#define TGA (1 << 28)
diff --git a/source/blender/imbuf/SConscript b/source/blender/imbuf/SConscript
index f76da8cd9d0..453cf6a509e 100644
--- a/source/blender/imbuf/SConscript
+++ b/source/blender/imbuf/SConscript
@@ -53,7 +53,7 @@ else:
if env['WITH_BF_TIFF']:
defs.append('WITH_TIFF')
else:
- sources.remove(os.path.join('intern', 'tiff.c'))
+ sources.remove(os.path.join('intern', 'tiff.c'))
if env['WITH_BF_DDS']:
defs.append('WITH_DDS')
@@ -64,7 +64,7 @@ if env['WITH_BF_CINEON']:
if env['WITH_BF_HDR']:
defs.append('WITH_HDR')
else:
- sources.remove(os.path.join('intern', 'radiance_hdr.c'))
+ sources.remove(os.path.join('intern', 'radiance_hdr.c'))
if env['WITH_BF_FFMPEG']:
defs.append('WITH_FFMPEG')
@@ -74,7 +74,7 @@ if env['WITH_BF_OPENJPEG']:
defs.append('WITH_OPENJPEG')
incs += ' ' + env['BF_OPENJPEG_INC']
else:
- sources.remove(os.path.join('intern', 'jp2.c'))
+ sources.remove(os.path.join('intern', 'jp2.c'))
if env['WITH_BF_REDCODE']:
defs.append('WITH_REDCODE')
diff --git a/source/blender/imbuf/intern/IMB_colormanagement_intern.h b/source/blender/imbuf/intern/IMB_colormanagement_intern.h
index e2a8e1e3442..c372e125a66 100644
--- a/source/blender/imbuf/intern/IMB_colormanagement_intern.h
+++ b/source/blender/imbuf/intern/IMB_colormanagement_intern.h
@@ -36,11 +36,14 @@
struct OCIO_ConstProcessorRcPtr;
struct ImBuf;
+#define MAX_COLORSPACE_NAME 64
+#define MAX_COLORSPACE_DESCRIPTION 512
+
typedef struct ColorSpace {
struct ColorSpace *next, *prev;
int index;
- char name[64];
- char description[64];
+ char name[MAX_COLORSPACE_NAME];
+ char description[MAX_COLORSPACE_DESCRIPTION];
struct OCIO_ConstProcessorRcPtr *to_scene_linear;
struct OCIO_ConstProcessorRcPtr *from_scene_linear;
@@ -52,7 +55,7 @@ typedef struct ColorSpace {
typedef struct ColorManagedDisplay {
struct ColorManagedDisplay *next, *prev;
int index;
- char name[64];
+ char name[MAX_COLORSPACE_NAME];
ListBase views;
struct OCIO_ConstProcessorRcPtr *to_scene_linear;
@@ -62,7 +65,7 @@ typedef struct ColorManagedDisplay {
typedef struct ColorManagedView {
struct ColorManagedView *next, *prev;
int index;
- char name[64];
+ char name[MAX_COLORSPACE_NAME];
} ColorManagedView;
/* ** Initialization / De-initialization ** */
diff --git a/source/blender/imbuf/intern/IMB_indexer.h b/source/blender/imbuf/intern/IMB_indexer.h
index 9c95531e90d..d114df945ae 100644
--- a/source/blender/imbuf/intern/IMB_indexer.h
+++ b/source/blender/imbuf/intern/IMB_indexer.h
@@ -116,9 +116,6 @@ void IMB_indexer_close(struct anim_index * idx);
void IMB_free_indices(struct anim * anim);
-int IMB_anim_index_get_frame_index(
- struct anim *anim, IMB_Timecode_Type tc, int position);
-
struct anim *IMB_anim_open_proxy(
struct anim *anim, IMB_Proxy_Size preview_size);
struct anim_index * IMB_anim_open_index(
diff --git a/source/blender/imbuf/intern/anim_movie.c b/source/blender/imbuf/intern/anim_movie.c
index 8d79482ed18..4ef1f962a0f 100644
--- a/source/blender/imbuf/intern/anim_movie.c
+++ b/source/blender/imbuf/intern/anim_movie.c
@@ -64,9 +64,9 @@
#include <io.h>
#endif
+#include "BLI_utildefines.h"
#include "BLI_string.h"
#include "BLI_path_util.h"
-#include "BLI_utildefines.h"
#include "BLI_math_base.h"
#include "MEM_guardedalloc.h"
@@ -822,10 +822,10 @@ static int ffmpeg_decode_video_frame(struct anim *anim)
if (rval == AVERROR_EOF) {
/* this sets size and data fields to zero,
- which is necessary to decode the remaining data
- in the decoder engine after EOF. It also prevents a memory
- leak, since av_read_frame spills out a full size packet even
- on EOF... (and: it's save to call on NULL packets) */
+ * which is necessary to decode the remaining data
+ * in the decoder engine after EOF. It also prevents a memory
+ * leak, since av_read_frame spills out a full size packet even
+ * on EOF... (and: it's save to call on NULL packets) */
av_free_packet(&anim->next_packet);
diff --git a/source/blender/imbuf/intern/bmp.c b/source/blender/imbuf/intern/bmp.c
index 32733668052..856124ab5cb 100644
--- a/source/blender/imbuf/intern/bmp.c
+++ b/source/blender/imbuf/intern/bmp.c
@@ -29,6 +29,7 @@
* \ingroup imbuf
*/
+#include "BLI_utildefines.h"
#include "BLI_fileops.h"
#include "imbuf.h"
@@ -60,6 +61,7 @@ typedef struct BMPINFOHEADER {
unsigned int biClrImportant;
} BMPINFOHEADER;
+#if 0
typedef struct BMPHEADER {
unsigned short biType;
unsigned int biSize;
@@ -67,6 +69,7 @@ typedef struct BMPHEADER {
unsigned short biRes2;
unsigned int biOffBits;
} BMPHEADER;
+#endif
#define BMP_FILEHEADER_SIZE 14
@@ -125,6 +128,7 @@ struct ImBuf *imb_bmp_decode(unsigned char *mem, size_t size, int flags, char co
int x, y, depth, skip, i;
unsigned char *bmp, *rect;
unsigned short col;
+ double xppm, yppm;
(void)size; /* unused */
@@ -144,6 +148,8 @@ struct ImBuf *imb_bmp_decode(unsigned char *mem, size_t size, int flags, char co
x = LITTLE_LONG(bmi.biWidth);
y = LITTLE_LONG(bmi.biHeight);
depth = LITTLE_SHORT(bmi.biBitCount);
+ xppm = LITTLE_LONG(bmi.biXPelsPerMeter);
+ yppm = LITTLE_LONG(bmi.biYPelsPerMeter);
#if 0
printf("skip: %d, x: %d y: %d, depth: %d (%x)\n", skip, x, y,
@@ -199,6 +205,8 @@ struct ImBuf *imb_bmp_decode(unsigned char *mem, size_t size, int flags, char co
}
if (ibuf) {
+ ibuf->ppm[0] = xppm;
+ ibuf->ppm[1] = yppm;
ibuf->ftype = BMP;
}
@@ -250,8 +258,8 @@ int imb_savebmp(struct ImBuf *ibuf, const char *name, int flags)
putShortLSB(24, ofile);
putIntLSB(0, ofile);
putIntLSB(bytesize + BMP_FILEHEADER_SIZE + sizeof(infoheader), ofile);
- putIntLSB(0, ofile);
- putIntLSB(0, ofile);
+ putIntLSB((int)(ibuf->ppm[0] + 0.5), ofile);
+ putIntLSB((int)(ibuf->ppm[1] + 0.5), ofile);
putIntLSB(0, ofile);
putIntLSB(0, ofile);
diff --git a/source/blender/imbuf/intern/cineon/cineon_dpx.c b/source/blender/imbuf/intern/cineon/cineon_dpx.c
index ba84063f317..48bda418d82 100644
--- a/source/blender/imbuf/intern/cineon/cineon_dpx.c
+++ b/source/blender/imbuf/intern/cineon/cineon_dpx.c
@@ -70,30 +70,23 @@ static struct ImBuf *imb_load_dpx_cineon(unsigned char *mem, size_t size, int us
logImageGetSize(image, &width, &height, &depth);
- if (width == 0 || height == 0) {
- logImageClose(image);
- return 0;
- }
-
ibuf = IMB_allocImBuf(width, height, 32, IB_rectfloat | flags);
if (ibuf == 0) {
logImageClose(image);
return 0;
}
- if (logImageGetDataRGBA(image, ibuf->rect_float, 1) != 0) {
- /* Conversion not possible (probably because the format is unsupported) */
- logImageClose(image);
- MEM_freeN(ibuf);
- return 0;
+ if (!(flags & IB_test)) {
+ if (logImageGetDataRGBA(image, ibuf->rect_float, 1) != 0) {
+ logImageClose(image);
+ IMB_freeImBuf(ibuf);
+ return 0;
+ }
+ IMB_flipy(ibuf);
}
logImageClose(image);
ibuf->ftype = use_cineon ? CINEON : DPX;
- IMB_flipy(ibuf);
-
- if (flags & IB_rect)
- IMB_rect_from_float(ibuf);
if (flags & IB_alphamode_detect)
ibuf->flags |= IB_alphamode_premul;
@@ -141,7 +134,7 @@ static int imb_save_dpx_cineon(ImBuf *ibuf, const char *filename, int use_cineon
if (ibuf->rect_float != 0 && bitspersample != 8) {
/* don't use the float buffer to save 8 bpp picture to prevent color banding
- (there's no dithering algorithm behing the logImageSetDataRGBA function) */
+ * (there's no dithering algorithm behing the logImageSetDataRGBA function) */
fbuf = (float *)MEM_mallocN(ibuf->x * ibuf->y * 4 * sizeof(float), "fbuf in imb_save_dpx_cineon");
diff --git a/source/blender/imbuf/intern/cineon/cineonlib.c b/source/blender/imbuf/intern/cineon/cineonlib.c
index b858251a6b9..4b9ca1dd539 100644
--- a/source/blender/imbuf/intern/cineon/cineonlib.c
+++ b/source/blender/imbuf/intern/cineon/cineonlib.c
@@ -196,6 +196,13 @@ LogImageFile *cineonOpen(const unsigned char *byteStuff, int fromMemory, size_t
cineon->width = swap_uint(header.imageHeader.element[0].pixels_per_line, cineon->isMSB);
cineon->height = swap_uint(header.imageHeader.element[0].lines_per_image, cineon->isMSB);
+
+ if (cineon->width == 0 || cineon->height == 0) {
+ if (verbose) printf("Cineon: Wrong image dimension: %dx%d\n", cineon->width, cineon->height);
+ logImageClose(cineon);
+ return 0;
+ }
+
cineon->depth = header.imageHeader.elements_per_image;
cineon->srcFormat = format_Cineon;
@@ -205,6 +212,7 @@ LogImageFile *cineonOpen(const unsigned char *byteStuff, int fromMemory, size_t
cineon->numElements = header.imageHeader.elements_per_image;
else {
if (verbose) printf("Cineon: Data interleave not supported: %d\n", header.imageHeader.interleave);
+ logImageClose(cineon);
return 0;
}
@@ -235,6 +243,7 @@ LogImageFile *cineonOpen(const unsigned char *byteStuff, int fromMemory, size_t
}
else {
if (verbose) printf("Cineon: Cineon image depth unsupported: %d\n", cineon->depth);
+ logImageClose(cineon);
return 0;
}
@@ -264,6 +273,7 @@ LogImageFile *cineonOpen(const unsigned char *byteStuff, int fromMemory, size_t
default:
/* Not supported */
if (verbose) printf("Cineon: packing unsupported: %d\n", header.imageHeader.packing);
+ logImageClose(cineon);
return 0;
}
diff --git a/source/blender/imbuf/intern/cineon/dpxlib.c b/source/blender/imbuf/intern/cineon/dpxlib.c
index aeebf46a632..10c90b1b891 100644
--- a/source/blender/imbuf/intern/cineon/dpxlib.c
+++ b/source/blender/imbuf/intern/cineon/dpxlib.c
@@ -192,8 +192,21 @@ LogImageFile *dpxOpen(const unsigned char *byteStuff, int fromMemory, size_t buf
dpx->srcFormat = format_DPX;
dpx->numElements = swap_ushort(header.imageHeader.elements_per_image, dpx->isMSB);
+ if (dpx->numElements == 0) {
+ if (verbose) printf("DPX: Wrong number of elements: %d\n", dpx->numElements);
+ logImageClose(dpx);
+ return 0;
+ }
+
dpx->width = swap_uint(header.imageHeader.pixels_per_line, dpx->isMSB);
dpx->height = swap_uint(header.imageHeader.lines_per_element, dpx->isMSB);
+
+ if (dpx->width == 0 || dpx->height == 0) {
+ if (verbose) printf("DPX: Wrong image dimension: %dx%d\n", dpx->width, dpx->height);
+ logImageClose(dpx);
+ return 0;
+ }
+
dpx->depth = 0;
for (i = 0; i < dpx->numElements; i++) {
@@ -242,8 +255,23 @@ LogImageFile *dpxOpen(const unsigned char *byteStuff, int fromMemory, size_t buf
}
dpx->element[i].bitsPerSample = header.imageHeader.element[i].bits_per_sample;
+ if (dpx->element[i].bitsPerSample != 1 && dpx->element[i].bitsPerSample != 8 &&
+ dpx->element[i].bitsPerSample != 10 && dpx->element[i].bitsPerSample != 12 &&
+ dpx->element[i].bitsPerSample != 16)
+ {
+ if (verbose) printf("DPX: Unsupported bitsPerSample for elements %d: %d\n", i, dpx->element[i].bitsPerSample);
+ logImageClose(dpx);
+ return 0;
+ }
+
dpx->element[i].maxValue = powf(2, dpx->element[i].bitsPerSample) - 1.0f;
+
dpx->element[i].packing = swap_ushort(header.imageHeader.element[i].packing, dpx->isMSB);
+ if (dpx->element[i].packing > 2) {
+ if (verbose) printf("DPX: Unsupported packing for element %d: %d\n", i, dpx->element[i].packing);
+ logImageClose(dpx);
+ return 0;
+ }
/* Sometimes, the offset is not set correctly in the header */
dpx->element[i].dataOffset = swap_uint(header.imageHeader.element[i].data_offset, dpx->isMSB);
@@ -323,7 +351,6 @@ LogImageFile *dpxOpen(const unsigned char *byteStuff, int fromMemory, size_t buf
(dpx->referenceWhite == DPX_UNDEFINED_R32 || dpx->referenceWhite <= dpx->referenceBlack || isnan(dpx->referenceWhite)) ||
(dpx->gamma == DPX_UNDEFINED_R32 || dpx->gamma <= 0 || isnan(dpx->gamma)))
{
-
dpx->referenceBlack = 95.0f / 1023.0f * dpx->element[0].maxValue;
dpx->referenceWhite = 685.0f / 1023.0f * dpx->element[0].maxValue;
dpx->gamma = 1.7f;
diff --git a/source/blender/imbuf/intern/cineon/logImageCore.c b/source/blender/imbuf/intern/cineon/logImageCore.c
index 3911e5c2ef3..332ad913d19 100644
--- a/source/blender/imbuf/intern/cineon/logImageCore.c
+++ b/source/blender/imbuf/intern/cineon/logImageCore.c
@@ -374,7 +374,7 @@ int logImageGetDataRGBA(LogImageFile *logImage, float *data, int dataIsLinearRGB
LogImageElement mergedElement;
/* Determine the depth of the picture and if there's a separate alpha element.
- If the element is supported, load it into an unsigned ints array. */
+ * If the element is supported, load it into an unsigned ints array. */
memset(&elementData, 0, 8 * sizeof(float *));
hasAlpha = 0;
diff --git a/source/blender/imbuf/intern/colormanagement.c b/source/blender/imbuf/intern/colormanagement.c
index cfeacff7f4a..505ba2599df 100644
--- a/source/blender/imbuf/intern/colormanagement.c
+++ b/source/blender/imbuf/intern/colormanagement.c
@@ -71,7 +71,6 @@
/*********************** Global declarations *************************/
-#define MAX_COLORSPACE_NAME 64
#define DISPLAY_BUFFER_CHANNELS 4
/* ** list of all supported color spaces, displays and views */
@@ -1700,7 +1699,7 @@ ImBuf *IMB_colormanagement_imbuf_for_write(ImBuf *ibuf, int save_as_render, int
{
ImBuf *colormanaged_ibuf = ibuf;
int do_colormanagement;
- int is_movie = BKE_imtype_is_movie(image_format_data->imtype);
+ bool is_movie = BKE_imtype_is_movie(image_format_data->imtype);
int requires_linear_float = BKE_imtype_requires_linear_float(image_format_data->imtype);
int do_alpha_under = image_format_data->planes != R_IMF_PLANES_RGBA;
@@ -1854,6 +1853,14 @@ unsigned char *IMB_display_buffer_acquire(ImBuf *ibuf, const ColorManagedViewSet
applied_view_settings = &default_view_settings;
}
+ /* early out: no float buffer and byte buffer is already in display space,
+ * let's just use if
+ */
+ if (ibuf->rect_float == NULL && ibuf->rect_colorspace) {
+ if (is_ibuf_rect_in_display_space(ibuf, applied_view_settings, display_settings))
+ return (unsigned char *) ibuf->rect;
+ }
+
colormanage_view_settings_to_cache(&cache_view_settings, applied_view_settings);
colormanage_display_settings_to_cache(&cache_display_settings, display_settings);
diff --git a/source/blender/imbuf/intern/dds/BlockDXT.cpp b/source/blender/imbuf/intern/dds/BlockDXT.cpp
index db2ca5969ec..348e1e9f53a 100644
--- a/source/blender/imbuf/intern/dds/BlockDXT.cpp
+++ b/source/blender/imbuf/intern/dds/BlockDXT.cpp
@@ -250,7 +250,7 @@ void BlockDXT1::decodeBlockNV5x(ColorBlock * block) const
}
}
-void BlockDXT1::setIndices(int * idx)
+void BlockDXT1::setIndices(int *idx)
{
indices = 0;
for (uint i = 0; i < 16; i++) {
@@ -595,7 +595,7 @@ void BlockCTX1::decodeBlock(ColorBlock * block) const
}
}
-void BlockCTX1::setIndices(int * idx)
+void BlockCTX1::setIndices(int *idx)
{
indices = 0;
for (uint i = 0; i < 16; i++) {
diff --git a/source/blender/imbuf/intern/dds/DirectDrawSurface.cpp b/source/blender/imbuf/intern/dds/DirectDrawSurface.cpp
index ccf72f9af86..df15cb3e357 100644
--- a/source/blender/imbuf/intern/dds/DirectDrawSurface.cpp
+++ b/source/blender/imbuf/intern/dds/DirectDrawSurface.cpp
@@ -1092,7 +1092,7 @@ void DirectDrawSurface::setUserVersion(int version)
header.setUserVersion(version);
}
-void DirectDrawSurface::mipmap(Image * img, uint face, uint mipmap)
+void DirectDrawSurface::mipmap(Image *img, uint face, uint mipmap)
{
stream.seek(offset(face, mipmap));
@@ -1158,7 +1158,7 @@ void* DirectDrawSurface::readData(uint &rsize)
return data;
}
-void DirectDrawSurface::readLinearImage(Image * img)
+void DirectDrawSurface::readLinearImage(Image *img)
{
const uint w = img->width();
@@ -1204,7 +1204,7 @@ void DirectDrawSurface::readLinearImage(Image * img)
}
}
-void DirectDrawSurface::readBlockImage(Image * img)
+void DirectDrawSurface::readBlockImage(Image *img)
{
const uint w = img->width();
@@ -1246,7 +1246,7 @@ static Color32 buildNormal(uint8 x, uint8 y)
}
-void DirectDrawSurface::readBlock(ColorBlock * rgba)
+void DirectDrawSurface::readBlock(ColorBlock *rgba)
{
uint fourcc = header.pf.fourcc;
diff --git a/source/blender/imbuf/intern/dds/FlipDXT.cpp b/source/blender/imbuf/intern/dds/FlipDXT.cpp
index 660643530ba..4f63d17dc90 100644
--- a/source/blender/imbuf/intern/dds/FlipDXT.cpp
+++ b/source/blender/imbuf/intern/dds/FlipDXT.cpp
@@ -241,7 +241,7 @@ int FlipDXTCImage(unsigned int width, unsigned int height, unsigned int levels,
memcpy(line2, temp_line, row_bytes);
}
- delete temp_line;
+ delete[] temp_line;
}
// mip levels are contiguous.
diff --git a/source/blender/imbuf/intern/indexer.c b/source/blender/imbuf/intern/indexer.c
index 56e5be7c12a..002ffd409a2 100644
--- a/source/blender/imbuf/intern/indexer.c
+++ b/source/blender/imbuf/intern/indexer.c
@@ -361,17 +361,16 @@ int IMB_timecode_to_array_index(IMB_Timecode_Type tc)
* - rebuild helper functions
* ---------------------------------------------------------------------- */
-static void get_index_dir(struct anim *anim, char *index_dir)
+static void get_index_dir(struct anim *anim, char *index_dir, size_t index_dir_len)
{
if (!anim->index_dir[0]) {
char fname[FILE_MAXFILE];
- BLI_strncpy(index_dir, anim->name, FILE_MAXDIR);
- BLI_splitdirstring(index_dir, fname);
- BLI_join_dirfile(index_dir, FILE_MAXDIR, index_dir, "BL_proxy");
- BLI_join_dirfile(index_dir, FILE_MAXDIR, index_dir, fname);
+ BLI_split_dirfile(anim->name, index_dir, fname, index_dir_len, sizeof(fname));
+ BLI_join_dirfile(index_dir, index_dir_len, index_dir, "BL_proxy");
+ BLI_join_dirfile(index_dir, index_dir_len, index_dir, fname);
}
else {
- BLI_strncpy(index_dir, anim->index_dir, FILE_MAXDIR);
+ BLI_strncpy(index_dir, anim->index_dir, index_dir_len);
}
}
@@ -396,7 +395,7 @@ static void get_proxy_filename(struct anim *anim, IMB_Proxy_Size preview_size,
BLI_snprintf(proxy_temp_name, sizeof(proxy_temp_name), "proxy_%d%s_part.avi",
(int) (proxy_fac[i] * 100), stream_suffix);
- get_index_dir(anim, index_dir);
+ get_index_dir(anim, index_dir, sizeof(index_dir));
BLI_join_dirfile(fname, FILE_MAXFILE + FILE_MAXDIR, index_dir,
temp ? proxy_temp_name : proxy_name);
@@ -425,7 +424,7 @@ static void get_tc_filename(struct anim *anim, IMB_Timecode_Type tc,
BLI_snprintf(index_name, 256, index_names[i], stream_suffix);
- get_index_dir(anim, index_dir);
+ get_index_dir(anim, index_dir, sizeof(index_dir));
BLI_join_dirfile(fname, FILE_MAXFILE + FILE_MAXDIR,
index_dir, index_name);
@@ -492,7 +491,7 @@ static struct proxy_output_ctx *alloc_proxy_output_ffmpeg(
rv->of = avformat_alloc_context();
rv->of->oformat = av_guess_format("avi", NULL, NULL);
- BLI_snprintf(rv->of->filename, sizeof(rv->of->filename), "%s", fname);
+ BLI_strncpy(rv->of->filename, fname, sizeof(rv->of->filename));
fprintf(stderr, "Starting work on proxy: %s\n", rv->of->filename);
diff --git a/source/blender/imbuf/intern/iris.c b/source/blender/imbuf/intern/iris.c
index 47bd3e54a6f..ac1bb246dce 100644
--- a/source/blender/imbuf/intern/iris.c
+++ b/source/blender/imbuf/intern/iris.c
@@ -32,6 +32,7 @@
#include <string.h>
+#include "BLI_utildefines.h"
#include "BLI_fileops.h"
#include "MEM_guardedalloc.h"
diff --git a/source/blender/imbuf/intern/jpeg.c b/source/blender/imbuf/intern/jpeg.c
index 6a5b534c688..bf0e4187aa6 100644
--- a/source/blender/imbuf/intern/jpeg.c
+++ b/source/blender/imbuf/intern/jpeg.c
@@ -37,6 +37,7 @@
#include "MEM_guardedalloc.h"
+#include "BLI_utildefines.h"
#include "BLI_string.h"
#include "BLI_fileops.h"
@@ -120,10 +121,12 @@ static void jpeg_error(j_common_ptr cinfo)
* INPUT HANDLER FROM MEMORY
*---------------------------------------------------------- */
+#if 0
typedef struct {
unsigned char *buffer;
int filled;
} buffer_struct;
+#endif
typedef struct {
struct jpeg_source_mgr pub; /* public fields */
diff --git a/source/blender/imbuf/intern/moviecache.c b/source/blender/imbuf/intern/moviecache.c
index d5aa635f548..a168c9c3051 100644
--- a/source/blender/imbuf/intern/moviecache.c
+++ b/source/blender/imbuf/intern/moviecache.c
@@ -145,7 +145,7 @@ static void check_unused_keys(MovieCache *cache)
GHashIterator *iter;
iter = BLI_ghashIterator_new(cache->hash);
- while (!BLI_ghashIterator_isDone(iter)) {
+ while (BLI_ghashIterator_notDone(iter)) {
MovieCacheKey *key = BLI_ghashIterator_getKey(iter);
MovieCacheItem *item = BLI_ghashIterator_getValue(iter);
int remove = 0;
@@ -408,7 +408,7 @@ void IMB_moviecache_cleanup(MovieCache *cache, int (cleanup_check_cb) (void *use
GHashIterator *iter;
iter = BLI_ghashIterator_new(cache->hash);
- while (!BLI_ghashIterator_isDone(iter)) {
+ while (BLI_ghashIterator_notDone(iter)) {
MovieCacheKey *key = BLI_ghashIterator_getKey(iter);
int remove;
@@ -457,7 +457,7 @@ void IMB_moviecache_get_cache_segments(MovieCache *cache, int proxy, int render_
iter = BLI_ghashIterator_new(cache->hash);
a = 0;
- while (!BLI_ghashIterator_isDone(iter)) {
+ while (BLI_ghashIterator_notDone(iter)) {
MovieCacheKey *key = BLI_ghashIterator_getKey(iter);
MovieCacheItem *item = BLI_ghashIterator_getValue(iter);
int framenr, curproxy, curflags;
diff --git a/source/blender/imbuf/intern/openexr/openexr_api.cpp b/source/blender/imbuf/intern/openexr/openexr_api.cpp
index 1b7aa1e7e63..043bb8da83c 100644
--- a/source/blender/imbuf/intern/openexr/openexr_api.cpp
+++ b/source/blender/imbuf/intern/openexr/openexr_api.cpp
@@ -85,6 +85,7 @@ _CRTIMP void __cdecl _invalid_parameter_noinfo(void)
#include <ImfCompression.h>
#include <ImfCompressionAttribute.h>
#include <ImfStringAttribute.h>
+#include <ImfStandardAttributes.h>
using namespace Imf;
using namespace Imath;
@@ -302,6 +303,9 @@ static void openexr_header_metadata(Header *header, struct ImBuf *ibuf)
for (info = ibuf->metadata; info; info = info->next)
header->insert(info->key, StringAttribute(info->value));
+
+ if (ibuf->ppm[0] > 0.0f)
+ addXDensity(*header, ibuf->ppm[0] / 39.3700787f); /* 1 meter = 39.3700787 inches */
}
static int imb_save_openexr_half(struct ImBuf *ibuf, const char *name, int flags)
@@ -886,6 +890,8 @@ static int imb_exr_split_channel_name(ExrChannel *echan, char *layname, char *pa
/* some multilayers have the combined buffer with names A B G R saved */
if (name[1] == 0) {
echan->chan_id = name[0];
+ layname[0] = '\0';
+ strcpy(passname, "Combined");
return 1;
}
@@ -1142,6 +1148,12 @@ struct ImBuf *imb_load_openexr(unsigned char *mem, size_t size, int flags, char
const int is_alpha = exr_has_alpha(file);
ibuf = IMB_allocImBuf(width, height, is_alpha ? 32 : 24, 0);
+
+ if (hasXDensity(file->header())) {
+ ibuf->ppm[0] = xDensity(file->header()) * 39.3700787f;
+ ibuf->ppm[1] = ibuf->ppm[0] * file->header().pixelAspectRatio();
+ }
+
ibuf->ftype = OPENEXR;
if (!(flags & IB_test)) {
diff --git a/source/blender/imbuf/intern/png.c b/source/blender/imbuf/intern/png.c
index 68385f22a7a..a7e05612472 100644
--- a/source/blender/imbuf/intern/png.c
+++ b/source/blender/imbuf/intern/png.c
@@ -33,6 +33,7 @@
#include "png.h"
+#include "BLI_utildefines.h"
#include "BLI_fileops.h"
#include "BLI_math.h"
diff --git a/source/blender/imbuf/intern/radiance_hdr.c b/source/blender/imbuf/intern/radiance_hdr.c
index d09adeb09b5..d45438e2853 100644
--- a/source/blender/imbuf/intern/radiance_hdr.c
+++ b/source/blender/imbuf/intern/radiance_hdr.c
@@ -43,6 +43,7 @@
#include "MEM_guardedalloc.h"
+#include "BLI_utildefines.h"
#include "BLI_fileops.h"
#include "imbuf.h"
@@ -318,7 +319,9 @@ static int fwritecolrs(FILE *file, int width, int channels, unsigned char *ibufs
putc((unsigned char)(128 + cnt), file);
putc(rgbe_scan[beg][i], file);
}
- else cnt = 0;
+ else {
+ cnt = 0;
+ }
}
}
MEM_freeN(rgbe_scan);
diff --git a/source/blender/imbuf/intern/readimage.c b/source/blender/imbuf/intern/readimage.c
index 4d47d883444..d73fa9a7ab7 100644
--- a/source/blender/imbuf/intern/readimage.c
+++ b/source/blender/imbuf/intern/readimage.c
@@ -43,12 +43,11 @@
#endif
#include <stdlib.h>
+#include "BLI_utildefines.h"
#include "BLI_string.h"
#include "BLI_path_util.h"
#include "BLI_fileops.h"
-#include "BLI_utildefines.h"
-
#include "imbuf.h"
#include "IMB_imbuf_types.h"
#include "IMB_imbuf.h"
diff --git a/source/blender/imbuf/intern/rectop.c b/source/blender/imbuf/intern/rectop.c
index 0b739b9fe92..8b60d1a96df 100644
--- a/source/blender/imbuf/intern/rectop.c
+++ b/source/blender/imbuf/intern/rectop.c
@@ -121,6 +121,27 @@ static void blend_color_darken(char cp[3], const char cp1[3], const char cp2[3],
}
}
+static void blend_color_erase_alpha(char cp[4], const char cp1[4], const char cp2[4], const int fac)
+{
+ int temp = (cp1[3] - fac * cp2[3] / 255);
+
+ cp[0] = cp1[0];
+ cp[1] = cp1[1];
+ cp[2] = cp1[2];
+ cp[3] = (temp < 0) ? 0 : temp;
+}
+
+static void blend_color_add_alpha(char cp[4], const char cp1[4], const char cp2[4], const int fac)
+{
+ int temp = (cp1[3] + fac * cp2[3] / 255);
+
+ cp[0] = cp1[0];
+ cp[1] = cp1[1];
+ cp[2] = cp1[2];
+ cp[3] = (temp < 0) ? 0 : temp;
+}
+
+
unsigned int IMB_blend_color(unsigned int src1, unsigned int src2, int fac, IMB_BlendMode mode)
{
unsigned int dst;
@@ -230,6 +251,26 @@ static void blend_color_darken_float(float cp[3], const float cp1[3], const floa
blend_color_mix_float(cp, cp1, cp2, fac);
}
+static void blend_color_erase_alpha_float(float cp[4], const float cp1[4], const float cp2[4], const float fac)
+{
+ cp[0] = cp1[0];
+ cp[1] = cp1[1];
+ cp[2] = cp1[2];
+
+ cp[3] = (cp1[3] - fac * cp2[3]);
+ if (cp[3] < 0.0f) cp[3] = 0.0f;
+}
+
+static void blend_color_add_alpha_float(float cp[4], const float cp1[4], const float cp2[4], const float fac)
+{
+ cp[0] = cp1[0];
+ cp[1] = cp1[1];
+ cp[2] = cp1[2];
+
+ cp[3] = (cp1[3] + fac * cp2[3]);
+ if (cp[3] < 0.0f) cp[3] = 0.0f;
+}
+
void IMB_blend_color_float(float *dst, float *src1, float *src2, float fac, IMB_BlendMode mode)
{
if (fac == 0) {
@@ -326,12 +367,18 @@ void IMB_rectcpy(struct ImBuf *dbuf, struct ImBuf *sbuf, int destx,
IMB_BLEND_COPY);
}
+typedef void (*IMB_blend_func)(char *dst, const char *src1, const char *src2, const int fac);
+typedef void (*IMB_blend_func_float)(float *dst, const float *src1, const float *src2, const float fac);
+
+
void IMB_rectblend(struct ImBuf *dbuf, struct ImBuf *sbuf, int destx,
int desty, int srcx, int srcy, int width, int height, IMB_BlendMode mode)
{
unsigned int *drect = NULL, *srect = NULL, *dr, *sr;
float *drectf = NULL, *srectf = NULL, *drf, *srf;
int do_float, do_char, srcskip, destskip, x;
+ IMB_blend_func func = NULL;
+ IMB_blend_func_float func_float = NULL;
if (dbuf == NULL) return;
@@ -427,13 +474,52 @@ void IMB_rectblend(struct ImBuf *dbuf, struct ImBuf *sbuf, int destx,
}
}
else {
+ switch (mode) {
+ case IMB_BLEND_MIX:
+ func = blend_color_mix;
+ func_float = blend_color_mix_float;
+ break;
+ case IMB_BLEND_ADD:
+ func = blend_color_add;
+ func_float = blend_color_add_float;
+ break;
+ case IMB_BLEND_SUB:
+ func = blend_color_sub;
+ func_float = blend_color_sub_float;
+ break;
+ case IMB_BLEND_MUL:
+ func = blend_color_mul;
+ func_float = blend_color_mul_float;
+ break;
+ case IMB_BLEND_LIGHTEN:
+ func = blend_color_lighten;
+ func_float = blend_color_lighten_float;
+ break;
+ case IMB_BLEND_DARKEN:
+ func = blend_color_darken;
+ func_float = blend_color_darken_float;
+ break;
+ case IMB_BLEND_ERASE_ALPHA:
+ func = blend_color_erase_alpha;
+ func_float = blend_color_erase_alpha_float;
+ break;
+ case IMB_BLEND_ADD_ALPHA:
+ func = blend_color_add_alpha;
+ func_float = blend_color_add_alpha_float;
+ break;
+ default:
+ break;
+ }
+
/* blend */
for (; height > 0; height--) {
if (do_char) {
dr = drect;
sr = srect;
- for (x = width; x > 0; x--, dr++, sr++)
- *dr = IMB_blend_color(*dr, *sr, ((char *)sr)[3], mode);
+ for (x = width; x > 0; x--, dr++, sr++) {
+ if (*sr & IB_ALPHA_MASK)
+ func((char *)dr, (char *)dr, (char *)sr, ((char *)sr)[3]);
+ }
drect += destskip;
srect += srcskip;
@@ -442,9 +528,10 @@ void IMB_rectblend(struct ImBuf *dbuf, struct ImBuf *sbuf, int destx,
if (do_float) {
drf = drectf;
srf = srectf;
- for (x = width; x > 0; x--, drf += 4, srf += 4)
- IMB_blend_color_float(drf, drf, srf, srf[3], mode);
-
+ for (x = width; x > 0; x--, drf += 4, srf += 4) {
+ if (srf[3] != 0)
+ func_float(drf, drf, srf, srf[3]);
+ }
drectf += destskip * 4;
srectf += srcskip * 4;
}
diff --git a/source/blender/imbuf/intern/scaling.c b/source/blender/imbuf/intern/scaling.c
index 1050d3f8715..51619e18980 100644
--- a/source/blender/imbuf/intern/scaling.c
+++ b/source/blender/imbuf/intern/scaling.c
@@ -34,6 +34,7 @@
#include "BLI_utildefines.h"
#include "BLI_math_color.h"
+#include "BLI_math_interp.h"
#include "MEM_guardedalloc.h"
#include "imbuf.h"
@@ -1604,3 +1605,113 @@ struct ImBuf *IMB_scalefastImBuf(struct ImBuf *ibuf, unsigned int newx, unsigned
return(ibuf);
}
+/* ******** threaded scaling ******** */
+
+typedef struct ScaleTreadInitData {
+ ImBuf *ibuf;
+
+ unsigned int newx;
+ unsigned int newy;
+
+ unsigned char *byte_buffer;
+ float *float_buffer;
+} ScaleTreadInitData;
+
+typedef struct ScaleThreadData {
+ ImBuf *ibuf;
+
+ unsigned int newx;
+ unsigned int newy;
+
+ int start_line;
+ int tot_line;
+
+ unsigned char *byte_buffer;
+ float *float_buffer;
+} ScaleThreadData;
+
+static void scale_thread_init(void *data_v, int start_line, int tot_line, void *init_data_v)
+{
+ ScaleThreadData *data = (ScaleThreadData *) data_v;
+ ScaleTreadInitData *init_data = (ScaleTreadInitData *) init_data_v;
+
+ data->ibuf = init_data->ibuf;
+
+ data->newx = init_data->newx;
+ data->newy = init_data->newy;
+
+ data->start_line = start_line;
+ data->tot_line = tot_line;
+
+ data->byte_buffer = init_data->byte_buffer;
+ data->float_buffer = init_data->float_buffer;
+}
+
+static void *do_scale_thread(void *data_v)
+{
+ ScaleThreadData *data = (ScaleThreadData *) data_v;
+ ImBuf *ibuf = data->ibuf;
+ int i;
+ float factor_x = (float) ibuf->x / data->newx;
+ float factor_y = (float) ibuf->y / data->newy;
+
+ for (i = 0; i < data->tot_line; i++) {
+ int y = data->start_line + i;
+ int x;
+
+ for (x = 0; x < data->newx; x++) {
+ float u = (float) x * factor_x;
+ float v = (float) y * factor_y;
+ int offset = y * data->newx + x;
+
+ if (data->byte_buffer) {
+ unsigned char *pixel = data->byte_buffer + 4 * offset;
+ BLI_bilinear_interpolation_char((unsigned char *) ibuf->rect, pixel, ibuf->x, ibuf->y, 4, u, v);
+ }
+
+ if (data->float_buffer) {
+ float *pixel = data->float_buffer + ibuf->channels * offset;
+ BLI_bilinear_interpolation_fl(ibuf->rect_float, pixel, ibuf->x, ibuf->y, ibuf->channels, u, v);
+ }
+ }
+ }
+
+ return NULL;
+}
+
+void IMB_scaleImBuf_threaded(ImBuf *ibuf, unsigned int newx, unsigned int newy)
+{
+ ScaleTreadInitData init_data = {0};
+
+ /* prepare initialization data */
+ init_data.ibuf = ibuf;
+
+ init_data.newx = newx;
+ init_data.newy = newy;
+
+ if (ibuf->rect)
+ init_data.byte_buffer = MEM_mallocN(4 * newx * newy * sizeof(char), "threaded scale byte buffer");
+
+ if (ibuf->rect_float)
+ init_data.float_buffer = MEM_mallocN(ibuf->channels * newx * newy * sizeof(float), "threaded scale float buffer");
+
+ /* actual scaling threads */
+ IMB_processor_apply_threaded(newy, sizeof(ScaleThreadData), &init_data,
+ scale_thread_init, do_scale_thread);
+
+ /* alter image buffer */
+ ibuf->x = newx;
+ ibuf->y = newy;
+
+ if (ibuf->rect) {
+ imb_freerectImBuf(ibuf);
+ ibuf->mall |= IB_rect;
+ ibuf->rect = (unsigned int *) init_data.byte_buffer;
+ }
+
+ if (ibuf->rect_float) {
+ imb_freerectfloatImBuf(ibuf);
+ ibuf->mall |= IB_rectfloat;
+ ibuf->rect_float = init_data.float_buffer;
+ }
+}
diff --git a/source/blender/imbuf/intern/targa.c b/source/blender/imbuf/intern/targa.c
index eaad77f1ff9..0c30af60388 100644
--- a/source/blender/imbuf/intern/targa.c
+++ b/source/blender/imbuf/intern/targa.c
@@ -34,6 +34,7 @@
# include <io.h>
#endif
+#include "BLI_utildefines.h"
#include "BLI_fileops.h"
#include "MEM_guardedalloc.h"
@@ -76,8 +77,8 @@ static int tga_out1(unsigned int data, FILE *file)
uchar *p;
p = (uchar *) &data;
- if (putc(p[0], file) == EOF) return(EOF);
- return (~EOF);
+ if (putc(p[0], file) == EOF) return EOF;
+ return ~EOF;
}
static int tga_out2(unsigned int data, FILE *file)
@@ -85,9 +86,9 @@ static int tga_out2(unsigned int data, FILE *file)
uchar *p;
p = (uchar *) &data;
- if (putc(p[0], file) == EOF) return(EOF);
- if (putc(p[1], file) == EOF) return(EOF);
- return (~EOF);
+ if (putc(p[0], file) == EOF) return EOF;
+ if (putc(p[1], file) == EOF) return EOF;
+ return ~EOF;
}
@@ -96,10 +97,10 @@ static int tga_out3(unsigned int data, FILE *file)
uchar *p;
p = (uchar *) &data;
- if (putc(p[2], file) == EOF) return(EOF);
- if (putc(p[1], file) == EOF) return(EOF);
- if (putc(p[0], file) == EOF) return(EOF);
- return (~EOF);
+ if (putc(p[2], file) == EOF) return EOF;
+ if (putc(p[1], file) == EOF) return EOF;
+ if (putc(p[0], file) == EOF) return EOF;
+ return ~EOF;
}
@@ -109,11 +110,11 @@ static int tga_out4(unsigned int data, FILE *file)
p = (uchar *) &data;
/* order = bgra */
- if (putc(p[2], file) == EOF) return(EOF);
- if (putc(p[1], file) == EOF) return(EOF);
- if (putc(p[0], file) == EOF) return(EOF);
- if (putc(p[3], file) == EOF) return(EOF);
- return (~EOF);
+ if (putc(p[2], file) == EOF) return EOF;
+ if (putc(p[1], file) == EOF) return EOF;
+ if (putc(p[0], file) == EOF) return EOF;
+ if (putc(p[3], file) == EOF) return EOF;
+ return ~EOF;
}
static short makebody_tga(ImBuf *ibuf, FILE *file, int (*out)(unsigned int, FILE *))
@@ -153,9 +154,9 @@ static short makebody_tga(ImBuf *ibuf, FILE *file, int (*out)(unsigned int, FILE
last = copy;
if (copy >= 128) last = 128;
copy -= last;
- if (fputc(last - 1, file) == EOF) return(0);
+ if (fputc(last - 1, file) == EOF) return 0;
do {
- if (out(*rect++, file) == EOF) return(0);
+ if (out(*rect++, file) == EOF) return 0;
} while (--last != 0);
}
rectstart = rect;
@@ -176,23 +177,23 @@ static short makebody_tga(ImBuf *ibuf, FILE *file, int (*out)(unsigned int, FILE
while (copy) {
if (copy > 128) {
- if (fputc(255, file) == EOF) return(0);
+ if (fputc(255, file) == EOF) return 0;
copy -= 128;
}
else {
if (copy == 1) {
- if (fputc(0, file) == EOF) return(0);
+ if (fputc(0, file) == EOF) return 0;
}
- else if (fputc(127 + copy, file) == EOF) return(0);
+ else if (fputc(127 + copy, file) == EOF) return 0;
copy = 0;
}
- if (out(last, file) == EOF) return(0);
+ if (out(last, file) == EOF) return 0;
}
copy = TRUE;
}
}
}
- return (1);
+ return 1;
}
static int dumptarga(struct ImBuf *ibuf, FILE *file)
@@ -200,15 +201,15 @@ static int dumptarga(struct ImBuf *ibuf, FILE *file)
int size;
uchar *rect;
- if (ibuf == NULL) return (0);
- if (ibuf->rect == NULL) return (0);
+ if (ibuf == NULL) return 0;
+ if (ibuf->rect == NULL) return 0;
size = ibuf->x * ibuf->y;
rect = (uchar *) ibuf->rect;
if (ibuf->planes <= 8) {
while (size > 0) {
- if (putc(*rect, file) == EOF) return (0);
+ if (putc(*rect, file) == EOF) return 0;
size--;
rect += 4;
}
@@ -216,7 +217,7 @@ static int dumptarga(struct ImBuf *ibuf, FILE *file)
else if (ibuf->planes <= 16) {
while (size > 0) {
putc(rect[0], file);
- if (putc(rect[1], file) == EOF) return (0);
+ if (putc(rect[1], file) == EOF) return 0;
size--;
rect += 4;
}
@@ -225,7 +226,7 @@ static int dumptarga(struct ImBuf *ibuf, FILE *file)
while (size > 0) {
putc(rect[2], file);
putc(rect[1], file);
- if (putc(rect[0], file) == EOF) return (0);
+ if (putc(rect[0], file) == EOF) return 0;
size--;
rect += 4;
}
@@ -235,14 +236,16 @@ static int dumptarga(struct ImBuf *ibuf, FILE *file)
putc(rect[2], file);
putc(rect[1], file);
putc(rect[0], file);
- if (putc(rect[3], file) == EOF) return (0);
+ if (putc(rect[3], file) == EOF) return 0;
size--;
rect += 4;
}
}
- else return (0);
-
- return (1);
+ else {
+ return 0;
+ }
+
+ return 1;
}
@@ -284,7 +287,7 @@ int imb_savetarga(struct ImBuf *ibuf, const char *name, int flags)
if (fwrite(buf, 1, 18, fildes) != 18) {
fclose(fildes);
- return (0);
+ return 0;
}
if (ibuf->ftype == RAWTGA) {
@@ -308,7 +311,7 @@ int imb_savetarga(struct ImBuf *ibuf, const char *name, int flags)
}
fclose(fildes);
- return (ok);
+ return ok;
}
@@ -328,7 +331,7 @@ static int checktarga(TARGA *tga, unsigned char *mem)
tga->pixsize = mem[16];
tga->imgdes = mem[17];
- if (tga->maptyp > 1) return(0);
+ if (tga->maptyp > 1) return 0;
switch (tga->imgtyp) {
case 1: /* raw cmap */
case 2: /* raw rgb */
@@ -338,14 +341,14 @@ static int checktarga(TARGA *tga, unsigned char *mem)
case 11: /* b&w */
break;
default:
- return(0);
+ return 0;
}
- if (tga->mapsize && tga->mapbits > 32) return(0);
- if (tga->xsize <= 0 || tga->xsize >= 8192) return(0);
- if (tga->ysize <= 0 || tga->ysize >= 8192) return(0);
- if (tga->pixsize > 32) return(0);
- if (tga->pixsize == 0) return(0);
- return(1);
+ if (tga->mapsize && tga->mapbits > 32) return 0;
+ if (tga->xsize <= 0 || tga->xsize >= 8192) return 0;
+ if (tga->ysize <= 0 || tga->ysize >= 8192) return 0;
+ if (tga->pixsize > 32) return 0;
+ if (tga->pixsize == 0) return 0;
+ return 1;
}
int imb_is_a_targa(unsigned char *buf)
@@ -556,14 +559,16 @@ ImBuf *imb_loadtarga(unsigned char *mem, size_t mem_size, int flags, char colors
unsigned int *rect, *cmap = NULL /*, mincol = 0*/, maxcol = 0;
uchar *cp = (uchar *) &col;
- if (checktarga(&tga, mem) == 0) return(NULL);
+ if (checktarga(&tga, mem) == 0) {
+ return NULL;
+ }
colorspace_set_default_role(colorspace, IM_MAX_SPACE, COLOR_ROLE_DEFAULT_BYTE);
if (flags & IB_test) ibuf = IMB_allocImBuf(tga.xsize, tga.ysize, tga.pixsize, 0);
else ibuf = IMB_allocImBuf(tga.xsize, tga.ysize, (tga.pixsize + 0x7) & ~0x7, IB_rect);
- if (ibuf == NULL) return(NULL);
+ if (ibuf == NULL) return NULL;
ibuf->ftype = TGA;
mem = mem + 18 + tga.numid;
@@ -612,7 +617,9 @@ ImBuf *imb_loadtarga(unsigned char *mem, size_t mem_size, int flags, char colors
}
}
- if (flags & IB_test) return (ibuf);
+ if (flags & IB_test) {
+ return ibuf;
+ }
if (tga.imgtyp != 1 && tga.imgtyp != 9) { /* happens sometimes (beuh) */
if (cmap) {
@@ -692,5 +699,5 @@ ImBuf *imb_loadtarga(unsigned char *mem, size_t mem_size, int flags, char colors
if (ibuf->rect)
IMB_convert_rgba_to_abgr(ibuf);
- return(ibuf);
+ return ibuf;
}
diff --git a/source/blender/imbuf/intern/thumbs.c b/source/blender/imbuf/intern/thumbs.c
index c1d80ad9067..51c6c2fc2d9 100644
--- a/source/blender/imbuf/intern/thumbs.c
+++ b/source/blender/imbuf/intern/thumbs.c
@@ -34,6 +34,7 @@
#include "MEM_guardedalloc.h"
+#include "BLI_utildefines.h"
#include "BLI_string.h"
#include "BLI_path_util.h"
#include "BLI_fileops.h"
@@ -422,7 +423,7 @@ void IMB_thumb_delete(const char *path, ThumbSize size)
return;
}
if (BLI_exists(thumb)) {
- BLI_delete(thumb, 0, 0);
+ BLI_delete(thumb, false, false);
}
}
}
@@ -447,7 +448,7 @@ ImBuf *IMB_thumb_manage(const char *path, ThumbSize size, ThumbSource source)
if (BLI_exists(thumb)) {
/* clear out of date fail case */
if (BLI_file_older(thumb, path)) {
- BLI_delete(thumb, 0, 0);
+ BLI_delete(thumb, false, false);
}
else {
return NULL;
diff --git a/source/blender/imbuf/intern/util.c b/source/blender/imbuf/intern/util.c
index 549a95e383d..68d1c906a1f 100644
--- a/source/blender/imbuf/intern/util.c
+++ b/source/blender/imbuf/intern/util.c
@@ -41,9 +41,9 @@
#include <stdlib.h>
+#include "BLI_utildefines.h"
#include "BLI_path_util.h"
#include "BLI_fileops.h"
-#include "BLI_utildefines.h"
#include "BLI_string.h"
#include "DNA_userdef_types.h"
diff --git a/source/blender/makesdna/DNA_brush_types.h b/source/blender/makesdna/DNA_brush_types.h
index 62d696ec255..147791b4835 100644
--- a/source/blender/makesdna/DNA_brush_types.h
+++ b/source/blender/makesdna/DNA_brush_types.h
@@ -71,6 +71,8 @@ typedef struct Brush {
int size; /* brush diameter */
int flag; /* general purpose flag */
float jitter; /* jitter the position of the brush */
+ int jitter_absolute; /* absolute jitter in pixels */
+ int pad;
int spacing; /* spacing of paint operations */
int smooth_stroke_radius; /* turning radius (in pixels) for smooth stroke */
float smooth_stroke_factor; /* higher values limit fast changes in the stroke direction */
@@ -137,7 +139,8 @@ typedef enum BrushFlags {
/* temporary flag which sets up automatically for correct brush
* drawing when inverted modal operator is running */
- BRUSH_INVERTED = (1 << 29)
+ BRUSH_INVERTED = (1 << 29),
+ BRUSH_ABSOLUTE_JITTER = (1 << 30)
} BrushFlags;
/* Brush.sculpt_tool */
diff --git a/source/blender/makesdna/DNA_genfile.h b/source/blender/makesdna/DNA_genfile.h
index ac75b03c742..96d71288c62 100644
--- a/source/blender/makesdna/DNA_genfile.h
+++ b/source/blender/makesdna/DNA_genfile.h
@@ -71,6 +71,8 @@ void *DNA_struct_reconstruct(struct SDNA *newsdna, struct SDNA *oldsdna, char *c
int DNA_elem_array_size(const char *astr, int len);
int DNA_elem_offset(struct SDNA *sdna, const char *stype, const char *vartype, const char *name);
+bool DNA_struct_elem_find(struct SDNA *sdna, const char *stype, const char *vartype, const char *name);
+
int DNA_elem_type_size(const eSDNA_Type elem_nr);
diff --git a/source/blender/makesdna/DNA_modifier_types.h b/source/blender/makesdna/DNA_modifier_types.h
index 117eac0e42b..66685c131d4 100644
--- a/source/blender/makesdna/DNA_modifier_types.h
+++ b/source/blender/makesdna/DNA_modifier_types.h
@@ -744,6 +744,8 @@ typedef struct SolidifyModifierData {
float offset; /* new surface offset level*/
float offset_fac; /* midpoint of the offset */
float offset_fac_vg; /* factor for the minimum weight to use when vgroups are used, avoids 0.0 weights giving duplicate geometry */
+ float offset_clamp; /* clamp offset based on surrounding geometry */
+ float pad;
float crease_inner;
float crease_outer;
float crease_rim;
diff --git a/source/blender/makesdna/DNA_node_types.h b/source/blender/makesdna/DNA_node_types.h
index 62c997b72c6..2e24b6ed78d 100644
--- a/source/blender/makesdna/DNA_node_types.h
+++ b/source/blender/makesdna/DNA_node_types.h
@@ -279,6 +279,8 @@ typedef struct bNodeTree {
short render_quality; /* Quality setting when rendering */
int chunksize; /* tile size for compositor engine */
+ rctf viewer_border;
+
ListBase inputs, outputs; /* external sockets for group nodes */
/* execution data */
@@ -313,6 +315,7 @@ typedef struct bNodeTree {
#define NTREE_COM_OPENCL 2 /* use opencl */
#define NTREE_TWO_PASS 4 /* two pass */
#define NTREE_COM_GROUPNODE_BUFFER 8 /* use groupnode buffers */
+#define NTREE_VIEWER_BORDER 16 /* use a border for viewer nodes */
/* XXX not nice, but needed as a temporary flags
* for group updates after library linking.
@@ -857,4 +860,7 @@ typedef struct NodeShaderNormalMap {
/* image */
#define CMP_NODE_IMAGE_USE_STRAIGHT_OUTPUT 1
+/* viewer and cmposite output */
+#define CMP_NODE_OUTPUT_IGNORE_ALPHA 1
+
#endif
diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h
index aa395dd0493..702df31f832 100644
--- a/source/blender/makesdna/DNA_scene_types.h
+++ b/source/blender/makesdna/DNA_scene_types.h
@@ -904,20 +904,25 @@ typedef struct UnifiedPaintSettings {
/* rake rotation */
/* record movement of mouse so that rake can start at an intuitive angle */
- float last_x, last_y;
- float last_angle;
+ float last_rake[2];
+ int pad;
- float special_rotation;
+ float brush_rotation;
// all this below is used to communicate with the cursor drawing routine
int draw_anchored;
int anchored_size;
- float anchored_location[3];
float anchored_initial_mouse[2];
/* drawing pressure */
int draw_pressure;
float pressure_value;
+
+ /* position of mouse, used to sample the texture */
+ float tex_mouse[2];
+ /* radius of brush, premultiplied with pressure.
+ * In case of anchored brushes contains that radius */
+ float pixel_radius;
} UnifiedPaintSettings;
typedef enum {
@@ -1534,7 +1539,6 @@ typedef enum SculptFlags {
// #define IMAGEPAINT_DRAW_TOOL_DRAWING 4 // deprecated
/* projection painting only */
-#define IMAGEPAINT_PROJECT_DISABLE 8 /* Non projection 3D painting */
#define IMAGEPAINT_PROJECT_XRAY 16
#define IMAGEPAINT_PROJECT_BACKFACE 32
#define IMAGEPAINT_PROJECT_FLAT 64
diff --git a/source/blender/makesdna/DNA_texture_types.h b/source/blender/makesdna/DNA_texture_types.h
index ea4f281efd6..dd63e6aad59 100644
--- a/source/blender/makesdna/DNA_texture_types.h
+++ b/source/blender/makesdna/DNA_texture_types.h
@@ -340,7 +340,7 @@ typedef struct ColorMapping {
/* imaflag */
#define TEX_INTERPOL 1
-#define TEX_USEALPHA 2 /* deprecated, used for versioning only */
+#define TEX_USEALPHA 2
#define TEX_MIPMAP 4
#define TEX_IMAROT 16
#define TEX_CALCALPHA 32
diff --git a/source/blender/makesdna/DNA_userdef_types.h b/source/blender/makesdna/DNA_userdef_types.h
index 0e5f0aea401..950483ba3ff 100644
--- a/source/blender/makesdna/DNA_userdef_types.h
+++ b/source/blender/makesdna/DNA_userdef_types.h
@@ -229,7 +229,7 @@ typedef struct ThemeSpace {
char wire[4], select[4];
char lamp[4], speaker[4], empty[4], camera[4], pad[8];
char active[4], group[4], group_active[4], transform[4];
- char vertex[4], vertex_select[4];
+ char vertex[4], vertex_select[4], vertex_unreferenced[4];
char edge[4], edge_select[4];
char edge_seam[4], edge_sharp[4], edge_facesel[4], edge_crease[4];
char face[4], face_select[4]; /* solid faces */
@@ -270,6 +270,7 @@ typedef struct ThemeSpace {
char handle_vertex[4];
char handle_vertex_select[4];
+ char pad2[4];
char handle_vertex_size;
@@ -453,7 +454,7 @@ typedef struct UserDef {
short ogl_multisamples; /* amount of samples for OpenGL FSA, if zero no FSA */
- short pad4;
+ short image_gpubuffer_limit; /* If set, amount of mega-pixels to use for texture drawing of images */
float glalphaclip;
diff --git a/source/blender/makesdna/DNA_view3d_types.h b/source/blender/makesdna/DNA_view3d_types.h
index d9d6db5ff91..294c47aa9db 100644
--- a/source/blender/makesdna/DNA_view3d_types.h
+++ b/source/blender/makesdna/DNA_view3d_types.h
@@ -107,6 +107,7 @@ typedef struct RegionView3D {
struct RenderInfo *ri;
struct RenderEngine *render_engine;
struct ViewDepths *depths;
+ void *gpuoffscreen;
/* animated smooth view */
struct SmoothView3DStore *sms;
@@ -118,7 +119,6 @@ typedef struct RegionView3D {
float viewquat[4]; /* view rotation, must be kept normalized */
float dist; /* distance from 'ofs' along -viewinv[2] vector, where result is negative as is 'ofs' */
- float zfac; /* initgrabz() result */
float camdx, camdy; /* camera view offsets, 1.0 = viewplane moves entire width/height */
float pixsize; /* runtime only */
float ofs[3]; /* view center & orbit pivot, negative of worldspace location,
@@ -129,10 +129,11 @@ typedef struct RegionView3D {
char persp;
char view;
char viewlock;
+ char pad[4];
short twdrawflag;
short rflag;
-
+
/* last view (use when switching out of camera view) */
float lviewquat[4];
diff --git a/source/blender/makesdna/intern/dna_genfile.c b/source/blender/makesdna/intern/dna_genfile.c
index 86014c4e80e..1225821102a 100644
--- a/source/blender/makesdna/intern/dna_genfile.c
+++ b/source/blender/makesdna/intern/dna_genfile.c
@@ -1314,6 +1314,22 @@ int DNA_elem_offset(SDNA *sdna, const char *stype, const char *vartype, const ch
return (int)((intptr_t)cp);
}
+bool DNA_struct_elem_find(SDNA *sdna, const char *stype, const char *vartype, const char *name)
+{
+
+ const int SDNAnr = DNA_struct_find_nr(sdna, stype);
+
+ if (SDNAnr >= 0) {
+ const short * const spo = sdna->structs[SDNAnr];
+ char * const cp = find_elem(sdna, vartype, name, spo, NULL, NULL);
+
+ if (cp) return true;
+ return (int)((intptr_t)cp);
+ }
+ return false;
+}
+
+
/**
* Returns the size in bytes of a primitive type.
*/
diff --git a/source/blender/makesdna/intern/makesdna.c b/source/blender/makesdna/intern/makesdna.c
index dd65ce53b92..acc6597d2c7 100644
--- a/source/blender/makesdna/intern/makesdna.c
+++ b/source/blender/makesdna/intern/makesdna.c
@@ -255,7 +255,9 @@ static int add_type(const char *str, int len)
}
/* append new type */
- if (nr_types == 0) cp = typedata;
+ if (nr_types == 0) {
+ cp = typedata;
+ }
else {
cp = types[nr_types - 1] + strlen(types[nr_types - 1]) + 1;
}
@@ -401,7 +403,9 @@ static int add_name(const char *str)
}
/* append new type */
- if (nr_names == 0) cp = namedata;
+ if (nr_names == 0) {
+ cp = namedata;
+ }
else {
cp = names[nr_names - 1] + strlen(names[nr_names - 1]) + 1;
}
diff --git a/source/blender/makesrna/RNA_access.h b/source/blender/makesrna/RNA_access.h
index 821b429e75c..770508cd625 100644
--- a/source/blender/makesrna/RNA_access.h
+++ b/source/blender/makesrna/RNA_access.h
@@ -392,7 +392,6 @@ extern StructRNA RNA_MouseSensor;
extern StructRNA RNA_MovieSequence;
extern StructRNA RNA_MovieClipSequence;
extern StructRNA RNA_MovieTracking;
-extern StructRNA RNA_MovieTrackingTrack;
extern StructRNA RNA_MovieTrackingObject;
extern StructRNA RNA_MovieTrackingTrack;
extern StructRNA RNA_MulticamSequence;
@@ -703,10 +702,10 @@ PropertyRNA *RNA_struct_name_property(StructRNA *type);
PropertyRNA *RNA_struct_iterator_property(StructRNA *type);
StructRNA *RNA_struct_base(StructRNA *type);
-int RNA_struct_is_ID(StructRNA *type);
-int RNA_struct_is_a(StructRNA *type, StructRNA *srna);
+bool RNA_struct_is_ID(StructRNA *type);
+bool RNA_struct_is_a(StructRNA *type, StructRNA *srna);
-int RNA_struct_undo_check(StructRNA *type);
+bool RNA_struct_undo_check(StructRNA *type);
StructRegisterFunc RNA_struct_register(StructRNA *type);
StructUnregisterFunc RNA_struct_unregister(StructRNA *type);
@@ -718,13 +717,13 @@ void RNA_struct_py_type_set(StructRNA *srna, void *py_type);
void *RNA_struct_blender_type_get(StructRNA *srna);
void RNA_struct_blender_type_set(StructRNA *srna, void *blender_type);
-struct IDProperty *RNA_struct_idprops(PointerRNA *ptr, int create);
-int RNA_struct_idprops_check(StructRNA *srna);
-int RNA_struct_idprops_register_check(StructRNA *type);
-int RNA_struct_idprops_unset(PointerRNA *ptr, const char *identifier);
+struct IDProperty *RNA_struct_idprops(PointerRNA *ptr, bool create);
+bool RNA_struct_idprops_check(StructRNA *srna);
+bool RNA_struct_idprops_register_check(StructRNA *type);
+bool RNA_struct_idprops_unset(PointerRNA *ptr, const char *identifier);
PropertyRNA *RNA_struct_find_property(PointerRNA *ptr, const char *identifier);
-int RNA_struct_contains_property(PointerRNA *ptr, PropertyRNA *prop_test);
+bool RNA_struct_contains_property(PointerRNA *ptr, PropertyRNA *prop_test);
/* lower level functions for access to type properties */
const struct ListBase *RNA_struct_type_properties(StructRNA *srna);
@@ -751,12 +750,12 @@ PropertyUnit RNA_property_unit(PropertyRNA *prop);
int RNA_property_flag(PropertyRNA *prop);
void *RNA_property_py_data_get(PropertyRNA *prop);
-int RNA_property_array_length(PointerRNA *ptr, PropertyRNA *prop);
-int RNA_property_array_check(PropertyRNA *prop);
-int RNA_property_multi_array_length(PointerRNA *ptr, PropertyRNA *prop, int dimension);
-int RNA_property_array_dimension(PointerRNA *ptr, PropertyRNA *prop, int length[]);
+int RNA_property_array_length(PointerRNA *ptr, PropertyRNA *prop);
+bool RNA_property_array_check(PropertyRNA *prop);
+int RNA_property_multi_array_length(PointerRNA *ptr, PropertyRNA *prop, int dimension);
+int RNA_property_array_dimension(PointerRNA *ptr, PropertyRNA *prop, int length[]);
char RNA_property_array_item_char(PropertyRNA *prop, int index);
-int RNA_property_array_item_index(PropertyRNA *prop, char name);
+int RNA_property_array_item_index(PropertyRNA *prop, char name);
int RNA_property_string_maxlength(PropertyRNA *prop);
@@ -776,31 +775,31 @@ void RNA_property_float_ui_range(PointerRNA *ptr, PropertyRNA *prop, float *soft
int RNA_property_float_clamp(PointerRNA *ptr, PropertyRNA *prop, float *value);
int RNA_property_int_clamp(PointerRNA *ptr, PropertyRNA *prop, int *value);
-int RNA_enum_identifier(EnumPropertyItem *item, const int value, const char **identifier);
-int RNA_enum_bitflag_identifiers(EnumPropertyItem *item, const int value, const char **identifier);
-int RNA_enum_name(EnumPropertyItem *item, const int value, const char **name);
-int RNA_enum_description(EnumPropertyItem *item, const int value, const char **description);
+bool RNA_enum_identifier(EnumPropertyItem *item, const int value, const char **identifier);
+int RNA_enum_bitflag_identifiers(EnumPropertyItem *item, const int value, const char **identifier);
+bool RNA_enum_name(EnumPropertyItem *item, const int value, const char **r_name);
+bool RNA_enum_description(EnumPropertyItem *item, const int value, const char **description);
void RNA_property_enum_items(struct bContext *C, PointerRNA *ptr, PropertyRNA *prop, EnumPropertyItem **item, int *totitem, int *free);
void RNA_property_enum_items_gettexted(struct bContext *C, PointerRNA *ptr, PropertyRNA *prop, EnumPropertyItem **item, int *totitem, int *free);
-int RNA_property_enum_value(struct bContext *C, PointerRNA *ptr, PropertyRNA *prop, const char *identifier, int *value);
-int RNA_property_enum_identifier(struct bContext *C, PointerRNA *ptr, PropertyRNA *prop, const int value, const char **identifier);
-int RNA_property_enum_name(struct bContext *C, PointerRNA *ptr, PropertyRNA *prop, const int value, const char **name);
+bool RNA_property_enum_value(struct bContext *C, PointerRNA *ptr, PropertyRNA *prop, const char *identifier, int *r_value);
+bool RNA_property_enum_identifier(struct bContext *C, PointerRNA *ptr, PropertyRNA *prop, const int value, const char **identifier);
+bool RNA_property_enum_name(struct bContext *C, PointerRNA *ptr, PropertyRNA *prop, const int value, const char **name);
int RNA_property_enum_bitflag_identifiers(struct bContext *C, PointerRNA *ptr, PropertyRNA *prop, const int value, const char **identifier);
StructRNA *RNA_property_pointer_type(PointerRNA *ptr, PropertyRNA *prop);
int RNA_property_pointer_poll(PointerRNA *ptr, PropertyRNA *prop, PointerRNA *value);
-int RNA_property_editable(PointerRNA *ptr, PropertyRNA *prop);
-int RNA_property_editable_index(PointerRNA *ptr, PropertyRNA *prop, int index);
-int RNA_property_editable_flag(PointerRNA *ptr, PropertyRNA *prop); /* without lib check, only checks the flag */
-int RNA_property_animateable(PointerRNA *ptr, PropertyRNA *prop);
-int RNA_property_animated(PointerRNA *ptr, PropertyRNA *prop);
-int RNA_property_path_from_ID_check(PointerRNA *ptr, PropertyRNA *prop); /* slow, use with care */
+bool RNA_property_editable(PointerRNA *ptr, PropertyRNA *prop);
+bool RNA_property_editable_index(PointerRNA *ptr, PropertyRNA *prop, int index);
+bool RNA_property_editable_flag(PointerRNA *ptr, PropertyRNA *prop); /* without lib check, only checks the flag */
+bool RNA_property_animateable(PointerRNA *ptr, PropertyRNA *prop);
+bool RNA_property_animated(PointerRNA *ptr, PropertyRNA *prop);
+bool RNA_property_path_from_ID_check(PointerRNA *ptr, PropertyRNA *prop); /* slow, use with care */
void RNA_property_update(struct bContext *C, PointerRNA *ptr, PropertyRNA *prop);
void RNA_property_update_main(struct Main *bmain, struct Scene *scene, PointerRNA *ptr, PropertyRNA *prop);
-int RNA_property_update_check(struct PropertyRNA *prop);
+bool RNA_property_update_check(struct PropertyRNA *prop);
void RNA_property_update_cache_add(PointerRNA *ptr, PropertyRNA *prop);
void RNA_property_update_cache_flush(struct Main *bmain, struct Scene *scene);
@@ -865,7 +864,7 @@ int RNA_property_collection_lookup_index(PointerRNA *ptr, PropertyRNA *prop, Poi
int RNA_property_collection_lookup_int(PointerRNA *ptr, PropertyRNA *prop, int key, PointerRNA *r_ptr);
int RNA_property_collection_lookup_string(PointerRNA *ptr, PropertyRNA *prop, const char *key, PointerRNA *r_ptr);
int RNA_property_collection_assign_int(PointerRNA *ptr, PropertyRNA *prop, const int key, const PointerRNA *assign_ptr);
-int RNA_property_collection_type_get(PointerRNA *ptr, PropertyRNA *prop, PointerRNA *r_ptr);
+bool RNA_property_collection_type_get(PointerRNA *ptr, PropertyRNA *prop, PointerRNA *r_ptr);
/* efficient functions to set properties for arrays */
int RNA_property_collection_raw_array(PointerRNA *ptr, PropertyRNA *prop, PropertyRNA *itemprop, RawArray *array);
@@ -879,13 +878,13 @@ RawPropertyType RNA_property_raw_type(PropertyRNA *prop);
void RNA_property_pointer_add(PointerRNA *ptr, PropertyRNA *prop);
void RNA_property_pointer_remove(PointerRNA *ptr, PropertyRNA *prop);
void RNA_property_collection_add(PointerRNA *ptr, PropertyRNA *prop, PointerRNA *r_ptr);
-int RNA_property_collection_remove(PointerRNA *ptr, PropertyRNA *prop, int key);
+bool RNA_property_collection_remove(PointerRNA *ptr, PropertyRNA *prop, int key);
void RNA_property_collection_clear(PointerRNA *ptr, PropertyRNA *prop);
-int RNA_property_collection_move(PointerRNA *ptr, PropertyRNA *prop, int key, int pos);
+bool RNA_property_collection_move(PointerRNA *ptr, PropertyRNA *prop, int key, int pos);
/* copy/reset */
-int RNA_property_copy(PointerRNA *ptr, PointerRNA *fromptr, PropertyRNA *prop, int index);
-int RNA_property_reset(PointerRNA *ptr, PropertyRNA *prop, int index);
+bool RNA_property_copy(PointerRNA *ptr, PointerRNA *fromptr, PropertyRNA *prop, int index);
+bool RNA_property_reset(PointerRNA *ptr, PropertyRNA *prop, int index);
/* Path
*
@@ -924,36 +923,36 @@ char *RNA_path_property_py(struct PointerRNA *ptr, struct PropertyRNA *prop, int
* There is no support for pointers and collections here yet, these can be
* added when ID properties support them. */
-int RNA_boolean_get(PointerRNA *ptr, const char *name);
+int RNA_boolean_get(PointerRNA *ptr, const char *name);
void RNA_boolean_set(PointerRNA *ptr, const char *name, int value);
void RNA_boolean_get_array(PointerRNA *ptr, const char *name, int *values);
void RNA_boolean_set_array(PointerRNA *ptr, const char *name, const int *values);
-int RNA_int_get(PointerRNA *ptr, const char *name);
+int RNA_int_get(PointerRNA *ptr, const char *name);
void RNA_int_set(PointerRNA *ptr, const char *name, int value);
void RNA_int_get_array(PointerRNA *ptr, const char *name, int *values);
void RNA_int_set_array(PointerRNA *ptr, const char *name, const int *values);
float RNA_float_get(PointerRNA *ptr, const char *name);
-void RNA_float_set(PointerRNA *ptr, const char *name, float value);
-void RNA_float_get_array(PointerRNA *ptr, const char *name, float *values);
-void RNA_float_set_array(PointerRNA *ptr, const char *name, const float *values);
+void RNA_float_set(PointerRNA *ptr, const char *name, float value);
+void RNA_float_get_array(PointerRNA *ptr, const char *name, float *values);
+void RNA_float_set_array(PointerRNA *ptr, const char *name, const float *values);
-int RNA_enum_get(PointerRNA *ptr, const char *name);
+int RNA_enum_get(PointerRNA *ptr, const char *name);
void RNA_enum_set(PointerRNA *ptr, const char *name, int value);
void RNA_enum_set_identifier(PointerRNA *ptr, const char *name, const char *id);
-int RNA_enum_is_equal(struct bContext *C, PointerRNA *ptr, const char *name, const char *enumname);
+bool RNA_enum_is_equal(struct bContext *C, PointerRNA *ptr, const char *name, const char *enumname);
/* lower level functions that don't use a PointerRNA */
-int RNA_enum_value_from_id(EnumPropertyItem *item, const char *identifier, int *value);
-int RNA_enum_id_from_value(EnumPropertyItem *item, int value, const char **identifier);
-int RNA_enum_icon_from_value(EnumPropertyItem *item, int value, int *icon);
-int RNA_enum_name_from_value(EnumPropertyItem *item, int value, const char **name);
+bool RNA_enum_value_from_id(EnumPropertyItem *item, const char *identifier, int *r_value);
+bool RNA_enum_id_from_value(EnumPropertyItem *item, int value, const char **r_identifier);
+bool RNA_enum_icon_from_value(EnumPropertyItem *item, int value, int *r_icon);
+bool RNA_enum_name_from_value(EnumPropertyItem *item, int value, const char **r_name);
-void RNA_string_get(PointerRNA *ptr, const char *name, char *value);
+void RNA_string_get(PointerRNA *ptr, const char *name, char *value);
char *RNA_string_get_alloc(PointerRNA *ptr, const char *name, char *fixedbuf, int fixedlen);
-int RNA_string_length(PointerRNA *ptr, const char *name);
-void RNA_string_set(PointerRNA *ptr, const char *name, const char *value);
+int RNA_string_length(PointerRNA *ptr, const char *name);
+void RNA_string_set(PointerRNA *ptr, const char *name, const char *value);
/**
* Retrieve the named property from PointerRNA.
@@ -964,7 +963,7 @@ void RNA_pointer_set(PointerRNA *ptr, const char *name, PointerRNA ptr_value);
void RNA_pointer_add(PointerRNA *ptr, const char *name);
void RNA_collection_begin(PointerRNA *ptr, const char *name, CollectionPropertyIterator *iter);
-int RNA_collection_length(PointerRNA *ptr, const char *name);
+int RNA_collection_length(PointerRNA *ptr, const char *name);
void RNA_collection_add(PointerRNA *ptr, const char *name, PointerRNA *r_value);
void RNA_collection_clear(PointerRNA *ptr, const char *name);
@@ -1014,11 +1013,11 @@ void RNA_collection_clear(PointerRNA *ptr, const char *name);
}
/* check if the idproperty exists, for operators */
-int RNA_property_is_set_ex(PointerRNA *ptr, PropertyRNA *prop, int use_ghost);
-int RNA_property_is_set(PointerRNA *ptr, PropertyRNA *prop);
-int RNA_struct_property_is_set_ex(PointerRNA *ptr, const char *identifier, int use_ghost);
-int RNA_struct_property_is_set(PointerRNA *ptr, const char *identifier);
-int RNA_property_is_idprop(PropertyRNA *prop);
+bool RNA_property_is_set_ex(PointerRNA *ptr, PropertyRNA *prop, bool use_ghost);
+bool RNA_property_is_set(PointerRNA *ptr, PropertyRNA *prop);
+bool RNA_struct_property_is_set_ex(PointerRNA *ptr, const char *identifier, bool use_ghost);
+bool RNA_struct_property_is_set(PointerRNA *ptr, const char *identifier);
+bool RNA_property_is_idprop(PropertyRNA *prop);
/* python compatible string representation of this property, (must be freed!) */
char *RNA_property_as_string(struct bContext *C, PointerRNA *ptr, PropertyRNA *prop, int index);
@@ -1063,21 +1062,27 @@ int RNA_parameter_length_get_data(ParameterList *parms, PropertyRNA *parm, void
void RNA_parameter_length_set(ParameterList *parms, PropertyRNA *parm, int length);
void RNA_parameter_length_set_data(ParameterList *parms, PropertyRNA *parm, void *data, int length);
-int RNA_function_call(struct bContext *C, struct ReportList *reports, PointerRNA *ptr, FunctionRNA *func, ParameterList *parms);
-int RNA_function_call_lookup(struct bContext *C, struct ReportList *reports, PointerRNA *ptr, const char *identifier, ParameterList *parms);
+int RNA_function_call(struct bContext *C, struct ReportList *reports, PointerRNA *ptr,
+ FunctionRNA *func, ParameterList *parms);
+int RNA_function_call_lookup(struct bContext *C, struct ReportList *reports, PointerRNA *ptr,
+ const char *identifier, ParameterList *parms);
-int RNA_function_call_direct(struct bContext *C, struct ReportList *reports, PointerRNA *ptr, FunctionRNA *func, const char *format, ...)
+int RNA_function_call_direct(struct bContext *C, struct ReportList *reports, PointerRNA *ptr,
+ FunctionRNA *func, const char *format, ...)
#ifdef __GNUC__
__attribute__ ((format(printf, 5, 6)))
#endif
;
-int RNA_function_call_direct_lookup(struct bContext *C, struct ReportList *reports, PointerRNA *ptr, const char *identifier, const char *format, ...)
+int RNA_function_call_direct_lookup(struct bContext *C, struct ReportList *reports, PointerRNA *ptr,
+ const char *identifier, const char *format, ...)
#ifdef __GNUC__
__attribute__ ((format(printf, 5, 6)))
#endif
;
-int RNA_function_call_direct_va(struct bContext *C, struct ReportList *reports, PointerRNA *ptr, FunctionRNA *func, const char *format, va_list args);
-int RNA_function_call_direct_va_lookup(struct bContext *C, struct ReportList *reports, PointerRNA *ptr, const char *identifier, const char *format, va_list args);
+int RNA_function_call_direct_va(struct bContext *C, struct ReportList *reports, PointerRNA *ptr,
+ FunctionRNA *func, const char *format, va_list args);
+int RNA_function_call_direct_va_lookup(struct bContext *C, struct ReportList *reports, PointerRNA *ptr,
+ const char *identifier, const char *format, va_list args);
/* ID */
diff --git a/source/blender/makesrna/RNA_types.h b/source/blender/makesrna/RNA_types.h
index 54d2efcf4cf..b69c95d0363 100644
--- a/source/blender/makesrna/RNA_types.h
+++ b/source/blender/makesrna/RNA_types.h
@@ -88,7 +88,8 @@ typedef enum PropertyUnit {
PROP_UNIT_ROTATION = (5 << 16), /* radians */
PROP_UNIT_TIME = (6 << 16), /* frame */
PROP_UNIT_VELOCITY = (7 << 16), /* m/s */
- PROP_UNIT_ACCELERATION = (8 << 16) /* m/(s^2) */
+ PROP_UNIT_ACCELERATION = (8 << 16), /* m/(s^2) */
+ PROP_UNIT_CAMERA = (9 << 16) /* mm */
} PropertyUnit;
#define RNA_SUBTYPE_UNIT(subtype) ((subtype) & 0x00FF0000)
@@ -122,6 +123,7 @@ typedef enum PropertySubType {
PROP_TIME = 17 | PROP_UNIT_TIME,
/* distance in 3d space, don't use for pixel distance for eg. */
PROP_DISTANCE = 18 | PROP_UNIT_LENGTH,
+ PROP_DISTANCE_CAMERA = 19 | PROP_UNIT_CAMERA,
/* number arrays */
PROP_COLOR = 20,
diff --git a/source/blender/makesrna/intern/makesrna.c b/source/blender/makesrna/intern/makesrna.c
index 3cd75ab10f0..0d5c1eb2352 100644
--- a/source/blender/makesrna/intern/makesrna.c
+++ b/source/blender/makesrna/intern/makesrna.c
@@ -24,7 +24,6 @@
* \ingroup RNA
*/
-
#include <float.h>
#include <limits.h>
#include <stdio.h>
@@ -34,6 +33,8 @@
#include "MEM_guardedalloc.h"
+#include "BLI_utildefines.h"
+
#include "RNA_access.h"
#include "RNA_define.h"
#include "RNA_types.h"
@@ -2450,6 +2451,7 @@ static const char *rna_property_subtypename(PropertySubType type)
case PROP_ANGLE: return "PROP_ANGLE";
case PROP_TIME: return "PROP_TIME";
case PROP_DISTANCE: return "PROP_DISTANCE";
+ case PROP_DISTANCE_CAMERA: return "PROP_DISTANCE_CAMERA";
case PROP_COLOR: return "PROP_COLOR";
case PROP_TRANSLATION: return "PROP_TRANSLATION";
case PROP_DIRECTION: return "PROP_DIRECTION";
@@ -2490,6 +2492,7 @@ static const char *rna_property_subtype_unit(PropertySubType type)
case PROP_UNIT_TIME: return "PROP_UNIT_TIME";
case PROP_UNIT_VELOCITY: return "PROP_UNIT_VELOCITY";
case PROP_UNIT_ACCELERATION: return "PROP_UNIT_ACCELERATION";
+ case PROP_UNIT_CAMERA: return "PROP_UNIT_CAMERA";
default: return "PROP_UNIT_UNKNOWN";
}
}
@@ -3172,7 +3175,9 @@ static void rna_generate_struct(BlenderRNA *UNUSED(brna), StructRNA *srna, FILE
fprintf(f, "\t(PropertyRNA *)&rna_%s_%s, ", base->identifier, prop->identifier);
}
- else fprintf(f, "\tNULL, ");
+ else {
+ fprintf(f, "\tNULL, ");
+ }
prop = srna->iteratorproperty;
base = srna;
diff --git a/source/blender/makesrna/intern/rna_ID.c b/source/blender/makesrna/intern/rna_ID.c
index 18281d4d251..1716864f23f 100644
--- a/source/blender/makesrna/intern/rna_ID.c
+++ b/source/blender/makesrna/intern/rna_ID.c
@@ -24,18 +24,19 @@
* \ingroup RNA
*/
-
#include <stdlib.h>
#include <stdio.h>
-#include "RNA_access.h"
-#include "RNA_define.h"
-
#include "DNA_ID.h"
#include "DNA_vfont_types.h"
#include "DNA_material_types.h"
#include "DNA_object_types.h"
+#include "BLI_utildefines.h"
+
+#include "RNA_access.h"
+#include "RNA_define.h"
+
#include "WM_types.h"
#include "rna_internal.h"
@@ -105,7 +106,7 @@ void rna_ID_name_set(PointerRNA *ptr, const char *value)
{
ID *id = (ID *)ptr->data;
BLI_strncpy_utf8(id->name + 2, value, sizeof(id->name) - 2);
- test_idbutton(id->name + 2);
+ test_idbutton(id->name);
}
static int rna_ID_name_editable(PointerRNA *ptr)
@@ -205,7 +206,7 @@ StructRNA *rna_ID_refine(PointerRNA *ptr)
return ID_code_to_RNA_type(GS(id->name));
}
-IDProperty *rna_ID_idprops(PointerRNA *ptr, int create)
+IDProperty *rna_ID_idprops(PointerRNA *ptr, bool create)
{
return IDP_GetProperties(ptr->data, create);
}
@@ -224,7 +225,7 @@ void rna_ID_fake_user_set(PointerRNA *ptr, int value)
}
}
-IDProperty *rna_PropertyGroup_idprops(PointerRNA *ptr, int UNUSED(create))
+IDProperty *rna_PropertyGroup_idprops(PointerRNA *ptr, bool UNUSED(create))
{
return ptr->data;
}
@@ -269,7 +270,7 @@ static ID *rna_ID_copy(ID *id)
{
ID *newid;
- if (id_copy(id, &newid, 0)) {
+ if (id_copy(id, &newid, false)) {
if (newid) id_us_min(newid);
return newid;
}
diff --git a/source/blender/makesrna/intern/rna_access.c b/source/blender/makesrna/intern/rna_access.c
index 6035326e0ae..f3efbd0d53e 100644
--- a/source/blender/makesrna/intern/rna_access.c
+++ b/source/blender/makesrna/intern/rna_access.c
@@ -52,12 +52,11 @@
#include "BKE_main.h"
#include "BKE_report.h"
-
-#include "WM_api.h"
-
#include "RNA_access.h"
#include "RNA_define.h"
+#include "WM_api.h"
+
/* flush updates */
#include "DNA_object_types.h"
#include "BKE_depsgraph.h"
@@ -258,7 +257,7 @@ static IDProperty *rna_idproperty_ui(PropertyRNA *prop)
return NULL;
}
-IDProperty *RNA_struct_idprops(PointerRNA *ptr, int create)
+IDProperty *RNA_struct_idprops(PointerRNA *ptr, bool create)
{
StructRNA *type = ptr->type;
@@ -268,9 +267,9 @@ IDProperty *RNA_struct_idprops(PointerRNA *ptr, int create)
return NULL;
}
-int RNA_struct_idprops_check(StructRNA *srna)
+bool RNA_struct_idprops_check(StructRNA *srna)
{
- return (srna && srna->idproperties) ? 1 : 0;
+ return (srna && srna->idproperties);
}
static IDProperty *rna_idproperty_find(PointerRNA *ptr, const char *name)
@@ -299,15 +298,15 @@ static int rna_ensure_property_array_length(PointerRNA *ptr, PropertyRNA *prop)
}
}
-static int rna_ensure_property_array_check(PropertyRNA *prop)
+static bool rna_ensure_property_array_check(PropertyRNA *prop)
{
if (prop->magic == RNA_MAGIC) {
- return (prop->getlength || prop->totarraylength) ? 1 : 0;
+ return (prop->getlength || prop->totarraylength);
}
else {
IDProperty *idprop = (IDProperty *)prop;
- return idprop->type == IDP_ARRAY ? 1 : 0;
+ return (idprop->type == IDP_ARRAY);
}
}
@@ -329,7 +328,7 @@ static void rna_ensure_property_multi_array_length(PointerRNA *ptr, PropertyRNA
}
}
-static int rna_idproperty_verify_valid(PointerRNA *ptr, PropertyRNA *prop, IDProperty *idprop)
+static bool rna_idproperty_verify_valid(PointerRNA *ptr, PropertyRNA *prop, IDProperty *idprop)
{
/* this verifies if the idproperty actually matches the property
* description and otherwise removes it. this is to ensure that
@@ -339,40 +338,40 @@ static int rna_idproperty_verify_valid(PointerRNA *ptr, PropertyRNA *prop, IDPro
switch (idprop->type) {
case IDP_IDPARRAY:
if (prop->type != PROP_COLLECTION)
- return 0;
+ return false;
break;
case IDP_ARRAY:
if (rna_ensure_property_array_length(ptr, prop) != idprop->len)
- return 0;
+ return false;
if (idprop->subtype == IDP_FLOAT && prop->type != PROP_FLOAT)
- return 0;
+ return false;
if (idprop->subtype == IDP_INT && !ELEM3(prop->type, PROP_BOOLEAN, PROP_INT, PROP_ENUM))
- return 0;
+ return false;
break;
case IDP_INT:
if (!ELEM3(prop->type, PROP_BOOLEAN, PROP_INT, PROP_ENUM))
- return 0;
+ return false;
break;
case IDP_FLOAT:
case IDP_DOUBLE:
if (prop->type != PROP_FLOAT)
- return 0;
+ return false;
break;
case IDP_STRING:
if (prop->type != PROP_STRING)
- return 0;
+ return false;
break;
case IDP_GROUP:
if (prop->type != PROP_POINTER)
- return 0;
+ return false;
break;
default:
- return 0;
+ return false;
}
- return 1;
+ return true;
}
static PropertyRNA *typemap[IDP_NUMTYPES] = {
@@ -549,23 +548,23 @@ StructRNA *RNA_struct_base(StructRNA *type)
return type->base;
}
-int RNA_struct_is_ID(StructRNA *type)
+bool RNA_struct_is_ID(StructRNA *type)
{
return (type->flag & STRUCT_ID) != 0;
}
-int RNA_struct_undo_check(StructRNA *type)
+bool RNA_struct_undo_check(StructRNA *type)
{
return (type->flag & STRUCT_UNDO) != 0;
}
-int RNA_struct_idprops_register_check(StructRNA *type)
+bool RNA_struct_idprops_register_check(StructRNA *type)
{
return (type->flag & STRUCT_NO_IDPROPERTIES) == 0;
}
/* remove an id-property */
-int RNA_struct_idprops_unset(PointerRNA *ptr, const char *identifier)
+bool RNA_struct_idprops_unset(PointerRNA *ptr, const char *identifier)
{
IDProperty *group = RNA_struct_idprops(ptr, 0);
@@ -576,25 +575,25 @@ int RNA_struct_idprops_unset(PointerRNA *ptr, const char *identifier)
IDP_FreeProperty(idp);
MEM_freeN(idp);
- return 1;
+ return true;
}
}
- return 0;
+ return false;
}
-int RNA_struct_is_a(StructRNA *type, StructRNA *srna)
+bool RNA_struct_is_a(StructRNA *type, StructRNA *srna)
{
StructRNA *base;
if (!type)
- return 0;
+ return false;
/* ptr->type is always maximally refined */
for (base = type; base; base = base->base)
if (base == srna)
- return 1;
+ return true;
- return 0;
+ return false;
}
PropertyRNA *RNA_struct_find_property(PointerRNA *ptr, const char *identifier)
@@ -637,13 +636,13 @@ static PropertyRNA *RNA_struct_find_nested(PointerRNA *ptr, StructRNA *srna)
return prop;
}
-int RNA_struct_contains_property(PointerRNA *ptr, PropertyRNA *prop_test)
+bool RNA_struct_contains_property(PointerRNA *ptr, PropertyRNA *prop_test)
{
/* note, prop_test could be freed memory, only use for comparison */
/* validate the RNA is ok */
PropertyRNA *iterprop;
- int found = FALSE;
+ bool found = false;
iterprop = RNA_struct_iterator_property(ptr->type);
@@ -651,7 +650,7 @@ int RNA_struct_contains_property(PointerRNA *ptr, PropertyRNA *prop_test)
{
/* PropertyRNA *prop = itemptr.data; */
if (prop_test == (PropertyRNA *)itemptr.data) {
- found = TRUE;
+ found = true;
break;
}
}
@@ -812,7 +811,7 @@ int RNA_property_array_length(PointerRNA *ptr, PropertyRNA *prop)
return rna_ensure_property_array_length(ptr, prop);
}
-int RNA_property_array_check(PropertyRNA *prop)
+bool RNA_property_array_check(PropertyRNA *prop)
{
return rna_ensure_property_array_check(prop);
}
@@ -845,6 +844,8 @@ char RNA_property_array_item_char(PropertyRNA *prop, int index)
const char *coloritem = "RGBA";
PropertySubType subtype = rna_ensure_property(prop)->subtype;
+ BLI_assert(index >= 0);
+
/* get string to use for array index */
if ((index < 4) && ELEM(subtype, PROP_QUATERNION, PROP_AXISANGLE)) {
return quatitem[index];
@@ -1272,17 +1273,18 @@ void RNA_property_enum_items_gettexted(bContext *C, PointerRNA *ptr, PropertyRNA
}
-int RNA_property_enum_value(bContext *C, PointerRNA *ptr, PropertyRNA *prop, const char *identifier, int *value)
+bool RNA_property_enum_value(bContext *C, PointerRNA *ptr, PropertyRNA *prop, const char *identifier, int *r_value)
{
EnumPropertyItem *item, *item_array;
- int free, found;
+ int free;
+ bool found;
RNA_property_enum_items(C, ptr, prop, &item_array, NULL, &free);
if (item_array) {
for (item = item_array; item->identifier; item++) {
if (item->identifier[0] && strcmp(item->identifier, identifier) == 0) {
- *value = item->value;
+ *r_value = item->value;
break;
}
}
@@ -1294,97 +1296,100 @@ int RNA_property_enum_value(bContext *C, PointerRNA *ptr, PropertyRNA *prop, con
}
}
else {
- found = 0;
+ found = false;
}
return found;
}
-int RNA_enum_identifier(EnumPropertyItem *item, const int value, const char **identifier)
+bool RNA_enum_identifier(EnumPropertyItem *item, const int value, const char **identifier)
{
for (; item->identifier; item++) {
if (item->identifier[0] && item->value == value) {
*identifier = item->identifier;
- return 1;
+ return true;
}
}
- return 0;
+ return false;
}
-int RNA_enum_bitflag_identifiers(EnumPropertyItem *item, const int value, const char **identifier)
+int RNA_enum_bitflag_identifiers(EnumPropertyItem *item, const int value, const char **r_identifier)
{
int index = 0;
for (; item->identifier; item++) {
if (item->identifier[0] && item->value & value) {
- identifier[index++] = item->identifier;
+ r_identifier[index++] = item->identifier;
}
}
- identifier[index] = NULL;
+ r_identifier[index] = NULL;
return index;
}
-int RNA_enum_name(EnumPropertyItem *item, const int value, const char **name)
+bool RNA_enum_name(EnumPropertyItem *item, const int value, const char **r_name)
{
for (; item->identifier; item++) {
if (item->identifier[0] && item->value == value) {
- *name = item->name;
- return 1;
+ *r_name = item->name;
+ return true;
}
}
- return 0;
+ return false;
}
-int RNA_enum_description(EnumPropertyItem *item, const int value, const char **description)
+bool RNA_enum_description(EnumPropertyItem *item, const int value, const char **r_description)
{
for (; item->identifier; item++) {
if (item->identifier[0] && item->value == value) {
- *description = item->description;
- return 1;
+ *r_description = item->description;
+ return true;
}
}
- return 0;
+ return false;
}
-int RNA_property_enum_identifier(bContext *C, PointerRNA *ptr, PropertyRNA *prop, const int value,
- const char **identifier)
+bool RNA_property_enum_identifier(bContext *C, PointerRNA *ptr, PropertyRNA *prop, const int value,
+ const char **identifier)
{
EnumPropertyItem *item = NULL;
- int result, free;
+ int free;
RNA_property_enum_items(C, ptr, prop, &item, NULL, &free);
if (item) {
+ bool result;
result = RNA_enum_identifier(item, value, identifier);
if (free)
MEM_freeN(item);
return result;
}
- return 0;
+ return false;
}
-int RNA_property_enum_name(bContext *C, PointerRNA *ptr, PropertyRNA *prop, const int value, const char **name)
+bool RNA_property_enum_name(bContext *C, PointerRNA *ptr, PropertyRNA *prop, const int value, const char **name)
{
EnumPropertyItem *item = NULL;
- int result, free;
+ int free;
RNA_property_enum_items(C, ptr, prop, &item, NULL, &free);
if (item) {
+ bool result;
result = RNA_enum_name(item, value, name);
if (free)
MEM_freeN(item);
return result;
}
- return 0;
+ return false;
}
int RNA_property_enum_bitflag_identifiers(bContext *C, PointerRNA *ptr, PropertyRNA *prop, const int value,
const char **identifier)
{
EnumPropertyItem *item = NULL;
- int result, free;
+ int free;
RNA_property_enum_items(C, ptr, prop, &item, NULL, &free);
if (item) {
+ int result;
result = RNA_enum_bitflag_identifiers(item, value, identifier);
if (free)
MEM_freeN(item);
@@ -1415,7 +1420,7 @@ int RNA_property_ui_icon(PropertyRNA *prop)
return rna_ensure_property(prop)->icon;
}
-int RNA_property_editable(PointerRNA *ptr, PropertyRNA *prop)
+bool RNA_property_editable(PointerRNA *ptr, PropertyRNA *prop)
{
ID *id = ptr->id.data;
int flag;
@@ -1425,21 +1430,23 @@ int RNA_property_editable(PointerRNA *ptr, PropertyRNA *prop)
return (flag & PROP_EDITABLE) && (!id || !id->lib || (prop->flag & PROP_LIB_EXCEPTION));
}
-int RNA_property_editable_flag(PointerRNA *ptr, PropertyRNA *prop)
+bool RNA_property_editable_flag(PointerRNA *ptr, PropertyRNA *prop)
{
int flag;
prop = rna_ensure_property(prop);
flag = prop->editable ? prop->editable(ptr) : prop->flag;
- return (flag & PROP_EDITABLE);
+ return (flag & PROP_EDITABLE) != 0;
}
/* same as RNA_property_editable(), except this checks individual items in an array */
-int RNA_property_editable_index(PointerRNA *ptr, PropertyRNA *prop, int index)
+bool RNA_property_editable_index(PointerRNA *ptr, PropertyRNA *prop, int index)
{
ID *id;
int flag;
+ BLI_assert(index >= 0);
+
prop = rna_ensure_property(prop);
flag = prop->flag;
@@ -1455,34 +1462,34 @@ int RNA_property_editable_index(PointerRNA *ptr, PropertyRNA *prop, int index)
return (flag & PROP_EDITABLE) && (!id || !id->lib || (prop->flag & PROP_LIB_EXCEPTION));
}
-int RNA_property_animateable(PointerRNA *ptr, PropertyRNA *prop)
+bool RNA_property_animateable(PointerRNA *ptr, PropertyRNA *prop)
{
/* check that base ID-block can support animation data */
if (!id_type_can_have_animdata(ptr->id.data))
- return 0;
+ return false;
prop = rna_ensure_property(prop);
if (!(prop->flag & PROP_ANIMATABLE))
- return 0;
+ return false;
- return (prop->flag & PROP_EDITABLE);
+ return (prop->flag & PROP_EDITABLE) != 0;
}
-int RNA_property_animated(PointerRNA *UNUSED(ptr), PropertyRNA *UNUSED(prop))
+bool RNA_property_animated(PointerRNA *UNUSED(ptr), PropertyRNA *UNUSED(prop))
{
/* would need to ask animation system */
- return 0;
+ return false;
}
/* this function is to check if its possible to create a valid path from the ID
* its slow so don't call in a loop */
-int RNA_property_path_from_ID_check(PointerRNA *ptr, PropertyRNA *prop)
+bool RNA_property_path_from_ID_check(PointerRNA *ptr, PropertyRNA *prop)
{
char *path = RNA_path_from_ID_to_property(ptr, prop);
- int ret = 0;
+ bool ret = false;
if (path) {
PointerRNA id_ptr;
@@ -1493,9 +1500,6 @@ int RNA_property_path_from_ID_check(PointerRNA *ptr, PropertyRNA *prop)
if (RNA_path_resolve(&id_ptr, path, &r_ptr, &r_prop) == TRUE) {
ret = (prop == r_prop);
}
- else {
- ret = FALSE;
- }
MEM_freeN(path);
}
@@ -1540,7 +1544,7 @@ static void rna_property_update(bContext *C, Main *bmain, Scene *scene, PointerR
/* must keep in sync with 'rna_property_update'
* note, its possible this returns a false positive in the case of PROP_CONTEXT_UPDATE
* but this isn't likely to be a performance problem. */
-int RNA_property_update_check(PropertyRNA *prop)
+bool RNA_property_update_check(PropertyRNA *prop)
{
return (prop->magic != RNA_MAGIC || prop->update || prop->noteflag);
}
@@ -1670,7 +1674,7 @@ int RNA_property_boolean_get(PointerRNA *ptr, PropertyRNA *prop)
IDProperty *idprop;
BLI_assert(RNA_property_type(prop) == PROP_BOOLEAN);
- BLI_assert(RNA_property_array_check(prop) == 0);
+ BLI_assert(RNA_property_array_check(prop) == false);
if ((idprop = rna_idproperty_check(&prop, ptr)))
return IDP_Int(idprop);
@@ -1688,7 +1692,7 @@ void RNA_property_boolean_set(PointerRNA *ptr, PropertyRNA *prop, int value)
IDProperty *idprop;
BLI_assert(RNA_property_type(prop) == PROP_BOOLEAN);
- BLI_assert(RNA_property_array_check(prop) == 0);
+ BLI_assert(RNA_property_array_check(prop) == false);
/* just in case other values are passed */
if (value) value = 1;
@@ -1721,7 +1725,7 @@ void RNA_property_boolean_get_array(PointerRNA *ptr, PropertyRNA *prop, int *val
IDProperty *idprop;
BLI_assert(RNA_property_type(prop) == PROP_BOOLEAN);
- BLI_assert(RNA_property_array_check(prop) != 0);
+ BLI_assert(RNA_property_array_check(prop) != false);
if ((idprop = rna_idproperty_check(&prop, ptr))) {
if (prop->arraydimension == 0)
@@ -1747,7 +1751,8 @@ int RNA_property_boolean_get_index(PointerRNA *ptr, PropertyRNA *prop, int index
int len = rna_ensure_property_array_length(ptr, prop);
BLI_assert(RNA_property_type(prop) == PROP_BOOLEAN);
- BLI_assert(RNA_property_array_check(prop) != 0);
+ BLI_assert(RNA_property_array_check(prop) != false);
+ BLI_assert(index >= 0);
if (len <= RNA_MAX_ARRAY_LENGTH) {
RNA_property_boolean_get_array(ptr, prop, tmp);
@@ -1771,7 +1776,7 @@ void RNA_property_boolean_set_array(PointerRNA *ptr, PropertyRNA *prop, const in
IDProperty *idprop;
BLI_assert(RNA_property_type(prop) == PROP_BOOLEAN);
- BLI_assert(RNA_property_array_check(prop) != 0);
+ BLI_assert(RNA_property_array_check(prop) != false);
if ((idprop = rna_idproperty_check(&prop, ptr))) {
if (prop->arraydimension == 0)
@@ -1809,7 +1814,8 @@ void RNA_property_boolean_set_index(PointerRNA *ptr, PropertyRNA *prop, int inde
int len = rna_ensure_property_array_length(ptr, prop);
BLI_assert(RNA_property_type(prop) == PROP_BOOLEAN);
- BLI_assert(RNA_property_array_check(prop) != 0);
+ BLI_assert(RNA_property_array_check(prop) != false);
+ BLI_assert(index >= 0);
if (len <= RNA_MAX_ARRAY_LENGTH) {
RNA_property_boolean_get_array(ptr, prop, tmp);
@@ -1832,7 +1838,7 @@ int RNA_property_boolean_get_default(PointerRNA *UNUSED(ptr), PropertyRNA *prop)
BoolPropertyRNA *bprop = (BoolPropertyRNA *)prop;
BLI_assert(RNA_property_type(prop) == PROP_BOOLEAN);
- BLI_assert(RNA_property_array_check(prop) == 0);
+ BLI_assert(RNA_property_array_check(prop) == false);
return bprop->defaultvalue;
}
@@ -1842,7 +1848,7 @@ void RNA_property_boolean_get_default_array(PointerRNA *UNUSED(ptr), PropertyRNA
BoolPropertyRNA *bprop = (BoolPropertyRNA *)prop;
BLI_assert(RNA_property_type(prop) == PROP_BOOLEAN);
- BLI_assert(RNA_property_array_check(prop) != 0);
+ BLI_assert(RNA_property_array_check(prop) != false);
if (prop->arraydimension == 0)
values[0] = bprop->defaultvalue;
@@ -1858,7 +1864,8 @@ int RNA_property_boolean_get_default_index(PointerRNA *ptr, PropertyRNA *prop, i
int len = rna_ensure_property_array_length(ptr, prop);
BLI_assert(RNA_property_type(prop) == PROP_BOOLEAN);
- BLI_assert(RNA_property_array_check(prop) != 0);
+ BLI_assert(RNA_property_array_check(prop) != false);
+ BLI_assert(index >= 0);
if (len <= RNA_MAX_ARRAY_LENGTH) {
RNA_property_boolean_get_default_array(ptr, prop, tmp);
@@ -1882,7 +1889,7 @@ int RNA_property_int_get(PointerRNA *ptr, PropertyRNA *prop)
IDProperty *idprop;
BLI_assert(RNA_property_type(prop) == PROP_INT);
- BLI_assert(RNA_property_array_check(prop) == 0);
+ BLI_assert(RNA_property_array_check(prop) == false);
if ((idprop = rna_idproperty_check(&prop, ptr)))
return IDP_Int(idprop);
@@ -1900,7 +1907,7 @@ void RNA_property_int_set(PointerRNA *ptr, PropertyRNA *prop, int value)
IDProperty *idprop;
BLI_assert(RNA_property_type(prop) == PROP_INT);
- BLI_assert(RNA_property_array_check(prop) == 0);
+ BLI_assert(RNA_property_array_check(prop) == false);
/* useful to check on bad values but set function should clamp */
/* BLI_assert(RNA_property_int_clamp(ptr, prop, &value) == 0); */
@@ -1932,7 +1939,7 @@ void RNA_property_int_get_array(PointerRNA *ptr, PropertyRNA *prop, int *values)
IDProperty *idprop;
BLI_assert(RNA_property_type(prop) == PROP_INT);
- BLI_assert(RNA_property_array_check(prop) != 0);
+ BLI_assert(RNA_property_array_check(prop) != false);
if ((idprop = rna_idproperty_check(&prop, ptr))) {
if (prop->arraydimension == 0)
@@ -1995,7 +2002,8 @@ int RNA_property_int_get_index(PointerRNA *ptr, PropertyRNA *prop, int index)
int len = rna_ensure_property_array_length(ptr, prop);
BLI_assert(RNA_property_type(prop) == PROP_INT);
- BLI_assert(RNA_property_array_check(prop) != 0);
+ BLI_assert(RNA_property_array_check(prop) != false);
+ BLI_assert(index >= 0);
if (len <= RNA_MAX_ARRAY_LENGTH) {
RNA_property_int_get_array(ptr, prop, tmp);
@@ -2019,7 +2027,7 @@ void RNA_property_int_set_array(PointerRNA *ptr, PropertyRNA *prop, const int *v
IDProperty *idprop;
BLI_assert(RNA_property_type(prop) == PROP_INT);
- BLI_assert(RNA_property_array_check(prop) != 0);
+ BLI_assert(RNA_property_array_check(prop) != false);
if ((idprop = rna_idproperty_check(&prop, ptr))) {
if (prop->arraydimension == 0)
@@ -2059,7 +2067,8 @@ void RNA_property_int_set_index(PointerRNA *ptr, PropertyRNA *prop, int index, i
int len = rna_ensure_property_array_length(ptr, prop);
BLI_assert(RNA_property_type(prop) == PROP_INT);
- BLI_assert(RNA_property_array_check(prop) != 0);
+ BLI_assert(RNA_property_array_check(prop) != false);
+ BLI_assert(index >= 0);
if (len <= RNA_MAX_ARRAY_LENGTH) {
RNA_property_int_get_array(ptr, prop, tmp);
@@ -2088,7 +2097,7 @@ void RNA_property_int_get_default_array(PointerRNA *UNUSED(ptr), PropertyRNA *pr
IntPropertyRNA *iprop = (IntPropertyRNA *)prop;
BLI_assert(RNA_property_type(prop) == PROP_INT);
- BLI_assert(RNA_property_array_check(prop) != 0);
+ BLI_assert(RNA_property_array_check(prop) != false);
if (prop->arraydimension == 0)
values[0] = iprop->defaultvalue;
@@ -2103,6 +2112,10 @@ int RNA_property_int_get_default_index(PointerRNA *ptr, PropertyRNA *prop, int i
int tmp[RNA_MAX_ARRAY_LENGTH];
int len = rna_ensure_property_array_length(ptr, prop);
+ BLI_assert(RNA_property_type(prop) == PROP_INT);
+ BLI_assert(RNA_property_array_check(prop) != false);
+ BLI_assert(index >= 0);
+
if (len <= RNA_MAX_ARRAY_LENGTH) {
RNA_property_int_get_default_array(ptr, prop, tmp);
return tmp[index];
@@ -2125,7 +2138,7 @@ float RNA_property_float_get(PointerRNA *ptr, PropertyRNA *prop)
IDProperty *idprop;
BLI_assert(RNA_property_type(prop) == PROP_FLOAT);
- BLI_assert(RNA_property_array_check(prop) == 0);
+ BLI_assert(RNA_property_array_check(prop) == false);
if ((idprop = rna_idproperty_check(&prop, ptr))) {
if (idprop->type == IDP_FLOAT)
@@ -2147,7 +2160,7 @@ void RNA_property_float_set(PointerRNA *ptr, PropertyRNA *prop, float value)
IDProperty *idprop;
BLI_assert(RNA_property_type(prop) == PROP_FLOAT);
- BLI_assert(RNA_property_array_check(prop) == 0);
+ BLI_assert(RNA_property_array_check(prop) == false);
/* useful to check on bad values but set function should clamp */
/* BLI_assert(RNA_property_float_clamp(ptr, prop, &value) == 0); */
@@ -2186,7 +2199,7 @@ void RNA_property_float_get_array(PointerRNA *ptr, PropertyRNA *prop, float *val
int i;
BLI_assert(RNA_property_type(prop) == PROP_FLOAT);
- BLI_assert(RNA_property_array_check(prop) != 0);
+ BLI_assert(RNA_property_array_check(prop) != false);
if ((idprop = rna_idproperty_check(&prop, ptr))) {
if (prop->arraydimension == 0)
@@ -2254,7 +2267,8 @@ float RNA_property_float_get_index(PointerRNA *ptr, PropertyRNA *prop, int index
int len = rna_ensure_property_array_length(ptr, prop);
BLI_assert(RNA_property_type(prop) == PROP_FLOAT);
- BLI_assert(RNA_property_array_check(prop) != 0);
+ BLI_assert(RNA_property_array_check(prop) != false);
+ BLI_assert(index >= 0);
if (len <= RNA_MAX_ARRAY_LENGTH) {
RNA_property_float_get_array(ptr, prop, tmp);
@@ -2270,7 +2284,6 @@ float RNA_property_float_get_index(PointerRNA *ptr, PropertyRNA *prop, int index
return value;
}
-
}
void RNA_property_float_set_array(PointerRNA *ptr, PropertyRNA *prop, const float *values)
@@ -2280,7 +2293,7 @@ void RNA_property_float_set_array(PointerRNA *ptr, PropertyRNA *prop, const floa
int i;
BLI_assert(RNA_property_type(prop) == PROP_FLOAT);
- BLI_assert(RNA_property_array_check(prop) != 0);
+ BLI_assert(RNA_property_array_check(prop) != false);
if ((idprop = rna_idproperty_check(&prop, ptr))) {
if (prop->arraydimension == 0) {
@@ -2331,7 +2344,8 @@ void RNA_property_float_set_index(PointerRNA *ptr, PropertyRNA *prop, int index,
int len = rna_ensure_property_array_length(ptr, prop);
BLI_assert(RNA_property_type(prop) == PROP_FLOAT);
- BLI_assert(RNA_property_array_check(prop) != 0);
+ BLI_assert(RNA_property_array_check(prop) != false);
+ BLI_assert(index >= 0);
if (len <= RNA_MAX_ARRAY_LENGTH) {
RNA_property_float_get_array(ptr, prop, tmp);
@@ -2354,7 +2368,7 @@ float RNA_property_float_get_default(PointerRNA *UNUSED(ptr), PropertyRNA *prop)
FloatPropertyRNA *fprop = (FloatPropertyRNA *)prop;
BLI_assert(RNA_property_type(prop) == PROP_FLOAT);
- BLI_assert(RNA_property_array_check(prop) == 0);
+ BLI_assert(RNA_property_array_check(prop) == false);
return fprop->defaultvalue;
}
@@ -2364,7 +2378,7 @@ void RNA_property_float_get_default_array(PointerRNA *UNUSED(ptr), PropertyRNA *
FloatPropertyRNA *fprop = (FloatPropertyRNA *)prop;
BLI_assert(RNA_property_type(prop) == PROP_FLOAT);
- BLI_assert(RNA_property_array_check(prop) != 0);
+ BLI_assert(RNA_property_array_check(prop) != false);
if (prop->arraydimension == 0)
values[0] = fprop->defaultvalue;
@@ -2380,7 +2394,8 @@ float RNA_property_float_get_default_index(PointerRNA *ptr, PropertyRNA *prop, i
int len = rna_ensure_property_array_length(ptr, prop);
BLI_assert(RNA_property_type(prop) == PROP_FLOAT);
- BLI_assert(RNA_property_array_check(prop) != 0);
+ BLI_assert(RNA_property_array_check(prop) != false);
+ BLI_assert(index >= 0);
if (len <= RNA_MAX_ARRAY_LENGTH) {
RNA_property_float_get_default_array(ptr, prop, tmp);
@@ -2864,7 +2879,7 @@ void RNA_property_collection_add(PointerRNA *ptr, PropertyRNA *prop, PointerRNA
}
}
-int RNA_property_collection_remove(PointerRNA *ptr, PropertyRNA *prop, int key)
+bool RNA_property_collection_remove(PointerRNA *ptr, PropertyRNA *prop, int key)
{
IDProperty *idprop;
/* CollectionPropertyRNA *cprop = (CollectionPropertyRNA *)prop; */
@@ -2889,10 +2904,11 @@ int RNA_property_collection_remove(PointerRNA *ptr, PropertyRNA *prop, int key)
IDP_ResizeIDPArray(idprop, len - 1);
}
- return 1;
+ return true;
+ }
+ else if (prop->flag & PROP_IDPROPERTY) {
+ return true;
}
- else if (prop->flag & PROP_IDPROPERTY)
- return 1;
/* py api calls directly */
#if 0
@@ -2904,15 +2920,15 @@ int RNA_property_collection_remove(PointerRNA *ptr, PropertyRNA *prop, int key)
RNA_parameter_list_free(&params);
}
- return 0;
+ return false;
}
/*else
printf("%s %s.%s: only supported for id properties.\n", __func__, ptr->type->identifier, prop->identifier);*/
#endif
- return 0;
+ return false;
}
-int RNA_property_collection_move(PointerRNA *ptr, PropertyRNA *prop, int key, int pos)
+bool RNA_property_collection_move(PointerRNA *ptr, PropertyRNA *prop, int key, int pos)
{
IDProperty *idprop;
@@ -2934,12 +2950,13 @@ int RNA_property_collection_move(PointerRNA *ptr, PropertyRNA *prop, int key, in
memcpy(&array[pos], &tmp, sizeof(IDProperty));
}
- return 1;
+ return true;
+ }
+ else if (prop->flag & PROP_IDPROPERTY) {
+ return true;
}
- else if (prop->flag & PROP_IDPROPERTY)
- return 1;
- return 0;
+ return false;
}
void RNA_property_collection_clear(PointerRNA *ptr, PropertyRNA *prop)
@@ -3066,7 +3083,7 @@ int RNA_property_collection_assign_int(PointerRNA *ptr, PropertyRNA *prop, const
return 0;
}
-int RNA_property_collection_type_get(PointerRNA *ptr, PropertyRNA *prop, PointerRNA *r_ptr)
+bool RNA_property_collection_type_get(PointerRNA *ptr, PropertyRNA *prop, PointerRNA *r_ptr)
{
BLI_assert(RNA_property_type(prop) == PROP_COLLECTION);
@@ -4557,7 +4574,7 @@ void RNA_enum_set_identifier(PointerRNA *ptr, const char *name, const char *id)
}
}
-int RNA_enum_is_equal(bContext *C, PointerRNA *ptr, const char *name, const char *enumname)
+bool RNA_enum_is_equal(bContext *C, PointerRNA *ptr, const char *name, const char *enumname)
{
PropertyRNA *prop = RNA_struct_find_property(ptr, name);
EnumPropertyItem *item;
@@ -4574,60 +4591,60 @@ int RNA_enum_is_equal(bContext *C, PointerRNA *ptr, const char *name, const char
MEM_freeN(item);
printf("%s: %s.%s item %s not found.\n", __func__, ptr->type->identifier, name, enumname);
- return 0;
+ return false;
}
else {
printf("%s: %s.%s not found.\n", __func__, ptr->type->identifier, name);
- return 0;
+ return false;
}
}
-int RNA_enum_value_from_id(EnumPropertyItem *item, const char *identifier, int *value)
+bool RNA_enum_value_from_id(EnumPropertyItem *item, const char *identifier, int *r_value)
{
for (; item->identifier; item++) {
if (strcmp(item->identifier, identifier) == 0) {
- *value = item->value;
- return 1;
+ *r_value = item->value;
+ return true;
}
}
- return 0;
+ return false;
}
-int RNA_enum_id_from_value(EnumPropertyItem *item, int value, const char **identifier)
+bool RNA_enum_id_from_value(EnumPropertyItem *item, int value, const char **r_identifier)
{
for (; item->identifier; item++) {
if (item->value == value) {
- *identifier = item->identifier;
- return 1;
+ *r_identifier = item->identifier;
+ return true;
}
}
- return 0;
+ return false;
}
-int RNA_enum_icon_from_value(EnumPropertyItem *item, int value, int *icon)
+bool RNA_enum_icon_from_value(EnumPropertyItem *item, int value, int *r_icon)
{
for (; item->identifier; item++) {
if (item->value == value) {
- *icon = item->icon;
- return 1;
+ *r_icon = item->icon;
+ return true;
}
}
- return 0;
+ return false;
}
-int RNA_enum_name_from_value(EnumPropertyItem *item, int value, const char **name)
+bool RNA_enum_name_from_value(EnumPropertyItem *item, int value, const char **r_name)
{
for (; item->identifier; item++) {
if (item->value == value) {
- *name = item->name;
- return 1;
+ *r_name = item->name;
+ return true;
}
}
- return 0;
+ return false;
}
void RNA_string_get(PointerRNA *ptr, const char *name, char *value)
@@ -4758,29 +4775,29 @@ int RNA_collection_length(PointerRNA *ptr, const char *name)
}
}
-int RNA_property_is_set_ex(PointerRNA *ptr, PropertyRNA *prop, int use_ghost)
+bool RNA_property_is_set_ex(PointerRNA *ptr, PropertyRNA *prop, bool use_ghost)
{
if (prop->flag & PROP_IDPROPERTY) {
IDProperty *idprop = rna_idproperty_find(ptr, prop->identifier);
- return ((idprop != NULL) && (use_ghost == FALSE || !(idprop->flag & IDP_FLAG_GHOST)));
+ return ((idprop != NULL) && (use_ghost == false || !(idprop->flag & IDP_FLAG_GHOST)));
}
else {
- return 1;
+ return true;
}
}
-int RNA_property_is_set(PointerRNA *ptr, PropertyRNA *prop)
+bool RNA_property_is_set(PointerRNA *ptr, PropertyRNA *prop)
{
if (prop->flag & PROP_IDPROPERTY) {
IDProperty *idprop = rna_idproperty_find(ptr, prop->identifier);
return ((idprop != NULL) && !(idprop->flag & IDP_FLAG_GHOST));
}
else {
- return 1;
+ return true;
}
}
-int RNA_struct_property_is_set_ex(PointerRNA *ptr, const char *identifier, int use_ghost)
+bool RNA_struct_property_is_set_ex(PointerRNA *ptr, const char *identifier, bool use_ghost)
{
PropertyRNA *prop = RNA_struct_find_property(ptr, identifier);
@@ -4794,7 +4811,7 @@ int RNA_struct_property_is_set_ex(PointerRNA *ptr, const char *identifier, int u
}
}
-int RNA_struct_property_is_set(PointerRNA *ptr, const char *identifier)
+bool RNA_struct_property_is_set(PointerRNA *ptr, const char *identifier)
{
PropertyRNA *prop = RNA_struct_find_property(ptr, identifier);
@@ -4808,7 +4825,7 @@ int RNA_struct_property_is_set(PointerRNA *ptr, const char *identifier)
}
}
-int RNA_property_is_idprop(PropertyRNA *prop)
+bool RNA_property_is_idprop(PropertyRNA *prop)
{
return (prop->magic != RNA_MAGIC);
}
@@ -5887,7 +5904,7 @@ int RNA_function_call_direct_va_lookup(bContext *C, ReportList *reports, Pointer
return 0;
}
-int RNA_property_reset(PointerRNA *ptr, PropertyRNA *prop, int index)
+bool RNA_property_reset(PointerRNA *ptr, PropertyRNA *prop, int index)
{
int len;
@@ -5915,7 +5932,7 @@ int RNA_property_reset(PointerRNA *ptr, PropertyRNA *prop, int index)
int value = RNA_property_boolean_get_default(ptr, prop);
RNA_property_boolean_set(ptr, prop, value);
}
- return 1;
+ return true;
case PROP_INT:
if (len) {
if (index == -1) {
@@ -5935,7 +5952,7 @@ int RNA_property_reset(PointerRNA *ptr, PropertyRNA *prop, int index)
int value = RNA_property_int_get_default(ptr, prop);
RNA_property_int_set(ptr, prop, value);
}
- return 1;
+ return true;
case PROP_FLOAT:
if (len) {
if (index == -1) {
@@ -5955,12 +5972,12 @@ int RNA_property_reset(PointerRNA *ptr, PropertyRNA *prop, int index)
float value = RNA_property_float_get_default(ptr, prop);
RNA_property_float_set(ptr, prop, value);
}
- return 1;
+ return true;
case PROP_ENUM:
{
int value = RNA_property_enum_get_default(ptr, prop);
RNA_property_enum_set(ptr, prop, value);
- return 1;
+ return true;
}
case PROP_STRING:
@@ -5968,23 +5985,23 @@ int RNA_property_reset(PointerRNA *ptr, PropertyRNA *prop, int index)
char *value = RNA_property_string_get_default_alloc(ptr, prop, NULL, 0);
RNA_property_string_set(ptr, prop, value);
MEM_freeN(value);
- return 1;
+ return true;
}
case PROP_POINTER:
{
PointerRNA value = RNA_property_pointer_get_default(ptr, prop);
RNA_property_pointer_set(ptr, prop, value);
- return 1;
+ return true;
}
default:
/* FIXME: are there still any cases that haven't been handled? comment out "default" block to check :) */
- return 0;
+ return false;
}
}
-int RNA_property_copy(PointerRNA *ptr, PointerRNA *fromptr, PropertyRNA *prop, int index)
+bool RNA_property_copy(PointerRNA *ptr, PointerRNA *fromptr, PropertyRNA *prop, int index)
{
int len, fromlen;
@@ -5993,7 +6010,7 @@ int RNA_property_copy(PointerRNA *ptr, PointerRNA *fromptr, PropertyRNA *prop, i
fromlen = RNA_property_array_length(fromptr, prop);
if (len != fromlen)
- return 0;
+ return false;
/* get and set the default values as appropriate for the various types */
switch (RNA_property_type(prop)) {
@@ -6016,7 +6033,7 @@ int RNA_property_copy(PointerRNA *ptr, PointerRNA *fromptr, PropertyRNA *prop, i
int value = RNA_property_boolean_get(fromptr, prop);
RNA_property_boolean_set(ptr, prop, value);
}
- return 1;
+ return true;
case PROP_INT:
if (len) {
if (index == -1) {
@@ -6036,7 +6053,7 @@ int RNA_property_copy(PointerRNA *ptr, PointerRNA *fromptr, PropertyRNA *prop, i
int value = RNA_property_int_get(fromptr, prop);
RNA_property_int_set(ptr, prop, value);
}
- return 1;
+ return true;
case PROP_FLOAT:
if (len) {
if (index == -1) {
@@ -6056,31 +6073,31 @@ int RNA_property_copy(PointerRNA *ptr, PointerRNA *fromptr, PropertyRNA *prop, i
float value = RNA_property_float_get(fromptr, prop);
RNA_property_float_set(ptr, prop, value);
}
- return 1;
+ return true;
case PROP_ENUM:
{
int value = RNA_property_enum_get(fromptr, prop);
RNA_property_enum_set(ptr, prop, value);
- return 1;
+ return true;
}
case PROP_POINTER:
{
PointerRNA value = RNA_property_pointer_get(fromptr, prop);
RNA_property_pointer_set(ptr, prop, value);
- return 1;
+ return true;
}
case PROP_STRING:
{
char *value = RNA_property_string_get_alloc(fromptr, prop, NULL, 0, NULL);
RNA_property_string_set(ptr, prop, value);
MEM_freeN(value);
- return 1;
+ return true;
}
default:
- return 0;
+ return false;
}
- return 0;
+ return false;
}
/* use RNA_warning macro which includes __func__ suffix */
diff --git a/source/blender/makesrna/intern/rna_action.c b/source/blender/makesrna/intern/rna_action.c
index 457066aed7c..e9bf40a58b1 100644
--- a/source/blender/makesrna/intern/rna_action.c
+++ b/source/blender/makesrna/intern/rna_action.c
@@ -24,15 +24,8 @@
* \ingroup RNA
*/
-
#include <stdlib.h>
-#include "RNA_access.h"
-#include "RNA_define.h"
-#include "RNA_enum_types.h"
-
-#include "rna_internal.h"
-
#include "DNA_anim_types.h"
#include "DNA_action_types.h"
#include "DNA_scene_types.h"
@@ -43,6 +36,12 @@
#include "BKE_action.h"
+#include "RNA_access.h"
+#include "RNA_define.h"
+#include "RNA_enum_types.h"
+
+#include "rna_internal.h"
+
#include "WM_types.h"
diff --git a/source/blender/makesrna/intern/rna_actuator.c b/source/blender/makesrna/intern/rna_actuator.c
index fe4a23cb393..2c022e80ddd 100644
--- a/source/blender/makesrna/intern/rna_actuator.c
+++ b/source/blender/makesrna/intern/rna_actuator.c
@@ -27,22 +27,23 @@
#include <stdlib.h>
-#include "RNA_define.h"
-#include "RNA_access.h"
-#include "RNA_enum_types.h"
-
-#include "rna_internal.h"
#include "DNA_constraint_types.h"
#include "DNA_object_types.h"
#include "DNA_actuator_types.h"
#include "DNA_scene_types.h" /* for MAXFRAME */
-#include "WM_types.h"
-
#include "BLI_utildefines.h"
#include "BLF_translation.h"
+#include "RNA_define.h"
+#include "RNA_access.h"
+#include "RNA_enum_types.h"
+
+#include "rna_internal.h"
+
+#include "WM_types.h"
+
/* Always keep in alphabetical order */
EnumPropertyItem actuator_type_items[] = {
{ACT_ACTION, "ACTION", 0, "Action", ""},
diff --git a/source/blender/makesrna/intern/rna_animation.c b/source/blender/makesrna/intern/rna_animation.c
index d6ea53f6ab3..50f156dd985 100644
--- a/source/blender/makesrna/intern/rna_animation.c
+++ b/source/blender/makesrna/intern/rna_animation.c
@@ -26,12 +26,6 @@
#include <stdlib.h>
-#include "RNA_access.h"
-#include "RNA_define.h"
-#include "RNA_enum_types.h"
-
-#include "rna_internal.h"
-
#include "DNA_anim_types.h"
#include "DNA_action_types.h"
#include "DNA_scene_types.h"
@@ -40,10 +34,16 @@
#include "MEM_guardedalloc.h"
-#include "ED_keyframing.h"
+#include "RNA_access.h"
+#include "RNA_define.h"
+#include "RNA_enum_types.h"
+
+#include "rna_internal.h"
#include "WM_types.h"
+#include "ED_keyframing.h"
+
/* exported for use in API */
EnumPropertyItem keyingset_path_grouping_items[] = {
{KSP_GROUP_NAMED, "NAMED", 0, "Named Group", ""},
@@ -895,6 +895,7 @@ static void rna_def_animdata(BlenderRNA *brna)
srna = RNA_def_struct(brna, "AnimData", NULL);
RNA_def_struct_ui_text(srna, "Animation Data", "Animation data for datablock");
+ RNA_def_struct_ui_icon(srna, ICON_ANIM_DATA);
/* NLA */
prop = RNA_def_property(srna, "nla_tracks", PROP_COLLECTION, PROP_NONE);
diff --git a/source/blender/makesrna/intern/rna_animviz.c b/source/blender/makesrna/intern/rna_animviz.c
index 68075823a86..9f8f30b00a7 100644
--- a/source/blender/makesrna/intern/rna_animviz.c
+++ b/source/blender/makesrna/intern/rna_animviz.c
@@ -24,19 +24,20 @@
* \ingroup RNA
*/
-
#include <stdlib.h>
#include "RNA_define.h"
-#include "rna_internal.h"
-
#include "DNA_anim_types.h"
#include "DNA_action_types.h"
#include "DNA_scene_types.h"
+#include "BLI_utildefines.h"
+
#include "MEM_guardedalloc.h"
+#include "rna_internal.h"
+
#include "WM_types.h"
/* Which part of bone(s) get baked */
diff --git a/source/blender/makesrna/intern/rna_armature.c b/source/blender/makesrna/intern/rna_armature.c
index 6c48ed25b60..1bc6c7e4f6f 100644
--- a/source/blender/makesrna/intern/rna_armature.c
+++ b/source/blender/makesrna/intern/rna_armature.c
@@ -207,7 +207,7 @@ static char *rna_Bone_path(PointerRNA *ptr)
return BLI_sprintfN("bones[\"%s\"]", bone->name);
}
-static IDProperty *rna_Bone_idprops(PointerRNA *ptr, int create)
+static IDProperty *rna_Bone_idprops(PointerRNA *ptr, bool create)
{
Bone *bone = ptr->data;
@@ -219,7 +219,7 @@ static IDProperty *rna_Bone_idprops(PointerRNA *ptr, int create)
return bone->prop;
}
-static IDProperty *rna_EditBone_idprops(PointerRNA *ptr, int create)
+static IDProperty *rna_EditBone_idprops(PointerRNA *ptr, bool create)
{
EditBone *ebone = ptr->data;
diff --git a/source/blender/makesrna/intern/rna_boid.c b/source/blender/makesrna/intern/rna_boid.c
index 63f4e480468..9d44ae87b57 100644
--- a/source/blender/makesrna/intern/rna_boid.c
+++ b/source/blender/makesrna/intern/rna_boid.c
@@ -29,20 +29,21 @@
* \ingroup RNA
*/
-
#include <float.h>
#include <limits.h>
#include <stdlib.h>
-#include "RNA_define.h"
-
-#include "rna_internal.h"
-
#include "DNA_scene_types.h"
#include "DNA_boid_types.h"
#include "DNA_object_types.h"
#include "DNA_particle_types.h"
+#include "BLI_utildefines.h"
+
+#include "RNA_define.h"
+
+#include "rna_internal.h"
+
#include "WM_api.h"
#include "WM_types.h"
diff --git a/source/blender/makesrna/intern/rna_brush.c b/source/blender/makesrna/intern/rna_brush.c
index c995d3b52c7..8480427c433 100644
--- a/source/blender/makesrna/intern/rna_brush.c
+++ b/source/blender/makesrna/intern/rna_brush.c
@@ -24,14 +24,11 @@
* \ingroup RNA
*/
-
#include <stdlib.h>
#include <assert.h>
#include "RNA_define.h"
-#include "rna_internal.h"
-
#include "DNA_brush_types.h"
#include "DNA_texture_types.h"
#include "DNA_scene_types.h"
@@ -39,6 +36,8 @@
#include "BLI_math.h"
+#include "rna_internal.h"
+
#include "IMB_imbuf.h"
#include "WM_types.h"
@@ -107,7 +106,7 @@ EnumPropertyItem brush_image_tool_items[] = {
#include "WM_api.h"
-static int rna_SculptCapabilities_has_accumulate_get(PointerRNA *ptr)
+static int rna_SculptToolCapabilities_has_accumulate_get(PointerRNA *ptr)
{
Brush *br = (Brush *)ptr->data;
return ELEM6(br->sculpt_tool,
@@ -115,19 +114,19 @@ static int rna_SculptCapabilities_has_accumulate_get(PointerRNA *ptr)
SCULPT_TOOL_DRAW, SCULPT_TOOL_INFLATE, SCULPT_TOOL_LAYER);
}
-static int rna_SculptCapabilities_has_auto_smooth_get(PointerRNA *ptr)
+static int rna_SculptToolCapabilities_has_auto_smooth_get(PointerRNA *ptr)
{
Brush *br = (Brush *)ptr->data;
return !ELEM(br->sculpt_tool, SCULPT_TOOL_MASK, SCULPT_TOOL_SMOOTH);
}
-static int rna_SculptCapabilities_has_height_get(PointerRNA *ptr)
+static int rna_SculptToolCapabilities_has_height_get(PointerRNA *ptr)
{
Brush *br = (Brush *)ptr->data;
return br->sculpt_tool == SCULPT_TOOL_LAYER;
}
-static int rna_SculptCapabilities_has_jitter_get(PointerRNA *ptr)
+static int rna_SculptToolCapabilities_has_jitter_get(PointerRNA *ptr)
{
Brush *br = (Brush *)ptr->data;
return (!(br->flag & BRUSH_ANCHORED) &&
@@ -137,13 +136,13 @@ static int rna_SculptCapabilities_has_jitter_get(PointerRNA *ptr)
SCULPT_TOOL_SNAKE_HOOK, SCULPT_TOOL_THUMB));
}
-static int rna_SculptCapabilities_has_normal_weight_get(PointerRNA *ptr)
+static int rna_SculptToolCapabilities_has_normal_weight_get(PointerRNA *ptr)
{
Brush *br = (Brush *)ptr->data;
return ELEM(br->sculpt_tool, SCULPT_TOOL_GRAB, SCULPT_TOOL_SNAKE_HOOK);
}
-static int rna_SculptCapabilities_has_overlay_get(PointerRNA *ptr)
+static int rna_BrushCapabilities_has_overlay_get(PointerRNA *ptr)
{
Brush *br = (Brush *)ptr->data;
return ELEM(br->mtex.brush_map_mode,
@@ -151,38 +150,43 @@ static int rna_SculptCapabilities_has_overlay_get(PointerRNA *ptr)
MTEX_MAP_MODE_TILED);
}
-static int rna_SculptCapabilities_has_persistence_get(PointerRNA *ptr)
+static int rna_SculptToolCapabilities_has_persistence_get(PointerRNA *ptr)
{
Brush *br = (Brush *)ptr->data;
return br->sculpt_tool == SCULPT_TOOL_LAYER;
}
-static int rna_SculptCapabilities_has_pinch_factor_get(PointerRNA *ptr)
+static int rna_SculptToolCapabilities_has_pinch_factor_get(PointerRNA *ptr)
{
Brush *br = (Brush *)ptr->data;
return ELEM(br->sculpt_tool, SCULPT_TOOL_BLOB, SCULPT_TOOL_CREASE);
}
-static int rna_SculptCapabilities_has_plane_offset_get(PointerRNA *ptr)
+static int rna_SculptToolCapabilities_has_plane_offset_get(PointerRNA *ptr)
{
Brush *br = (Brush *)ptr->data;
return ELEM5(br->sculpt_tool, SCULPT_TOOL_CLAY, SCULPT_TOOL_CLAY_STRIPS,
SCULPT_TOOL_FILL, SCULPT_TOOL_FLATTEN, SCULPT_TOOL_SCRAPE);
}
-static int rna_SculptCapabilities_has_random_texture_angle_get(PointerRNA *ptr)
+static int rna_SculptToolCapabilities_has_random_texture_angle_get(PointerRNA *ptr)
+{
+ Brush *br = (Brush *)ptr->data;
+ return (!ELEM4(br->sculpt_tool,
+ SCULPT_TOOL_GRAB, SCULPT_TOOL_ROTATE,
+ SCULPT_TOOL_SNAKE_HOOK, SCULPT_TOOL_THUMB));
+}
+
+static int rna_BrushCapabilities_has_random_texture_angle_get(PointerRNA *ptr)
{
Brush *br = (Brush *)ptr->data;
return (ELEM(br->mtex.brush_map_mode,
MTEX_MAP_MODE_VIEW,
MTEX_MAP_MODE_AREA) &&
- !(br->flag & BRUSH_ANCHORED) &&
- !ELEM4(br->sculpt_tool,
- SCULPT_TOOL_GRAB, SCULPT_TOOL_ROTATE,
- SCULPT_TOOL_SNAKE_HOOK, SCULPT_TOOL_THUMB));
+ !(br->flag & BRUSH_ANCHORED));
}
-static int rna_SculptCapabilities_has_sculpt_plane_get(PointerRNA *ptr)
+static int rna_SculptToolCapabilities_has_sculpt_plane_get(PointerRNA *ptr)
{
Brush *br = (Brush *)ptr->data;
return !ELEM4(br->sculpt_tool, SCULPT_TOOL_INFLATE,
@@ -190,7 +194,7 @@ static int rna_SculptCapabilities_has_sculpt_plane_get(PointerRNA *ptr)
SCULPT_TOOL_SMOOTH);
}
-static int rna_SculptCapabilities_has_secondary_color_get(PointerRNA *ptr)
+static int rna_SculptToolCapabilities_has_secondary_color_get(PointerRNA *ptr)
{
Brush *br = (Brush *)ptr->data;
return ELEM10(br->sculpt_tool,
@@ -200,7 +204,7 @@ static int rna_SculptCapabilities_has_secondary_color_get(PointerRNA *ptr)
SCULPT_TOOL_SCRAPE);
}
-static int rna_SculptCapabilities_has_smooth_stroke_get(PointerRNA *ptr)
+static int rna_SculptToolCapabilities_has_smooth_stroke_get(PointerRNA *ptr)
{
Brush *br = (Brush *)ptr->data;
return (!(br->flag & BRUSH_ANCHORED) &&
@@ -210,7 +214,7 @@ static int rna_SculptCapabilities_has_smooth_stroke_get(PointerRNA *ptr)
SCULPT_TOOL_SNAKE_HOOK, SCULPT_TOOL_THUMB));
}
-static int rna_SculptCapabilities_has_space_attenuation_get(PointerRNA *ptr)
+static int rna_SculptToolCapabilities_has_space_attenuation_get(PointerRNA *ptr)
{
Brush *br = (Brush *)ptr->data;
return ((br->flag & BRUSH_SPACE) &&
@@ -218,22 +222,19 @@ static int rna_SculptCapabilities_has_space_attenuation_get(PointerRNA *ptr)
SCULPT_TOOL_SMOOTH, SCULPT_TOOL_SNAKE_HOOK));
}
-static int rna_SculptCapabilities_has_spacing_get(PointerRNA *ptr)
+static int rna_BrushCapabilities_has_spacing_get(PointerRNA *ptr)
{
Brush *br = (Brush *)ptr->data;
- return (!(br->flag & BRUSH_ANCHORED) &&
- !ELEM4(br->sculpt_tool,
- SCULPT_TOOL_GRAB, SCULPT_TOOL_ROTATE,
- SCULPT_TOOL_SNAKE_HOOK, SCULPT_TOOL_THUMB));
+ return (!(br->flag & BRUSH_ANCHORED));
}
-static int rna_SculptCapabilities_has_strength_get(PointerRNA *ptr)
+static int rna_SculptToolCapabilities_has_strength_get(PointerRNA *ptr)
{
Brush *br = (Brush *)ptr->data;
return !ELEM(br->sculpt_tool, SCULPT_TOOL_GRAB, SCULPT_TOOL_SNAKE_HOOK);
}
-static int rna_SculptCapabilities_has_texture_angle_get(PointerRNA *ptr)
+static int rna_BrushCapabilities_has_texture_angle_get(PointerRNA *ptr)
{
Brush *br = (Brush *)ptr->data;
return ELEM3(br->mtex.brush_map_mode,
@@ -242,7 +243,7 @@ static int rna_SculptCapabilities_has_texture_angle_get(PointerRNA *ptr)
MTEX_MAP_MODE_TILED);
}
-static int rna_SculptCapabilities_has_texture_angle_source_get(PointerRNA *ptr)
+static int rna_BrushCapabilities_has_texture_angle_source_get(PointerRNA *ptr)
{
Brush *br = (Brush *)ptr->data;
return ELEM(br->mtex.brush_map_mode,
@@ -250,9 +251,14 @@ static int rna_SculptCapabilities_has_texture_angle_source_get(PointerRNA *ptr)
MTEX_MAP_MODE_AREA);
}
-static PointerRNA rna_Brush_sculpt_capabilities_get(PointerRNA *ptr)
+static PointerRNA rna_Sculpt_sculpt_tool_capabilities_get(PointerRNA *ptr)
+{
+ return rna_pointer_inherit_refine(ptr, &RNA_SculptToolCapabilities, ptr->id.data);
+}
+
+static PointerRNA rna_Brush_capabilities_get(PointerRNA *ptr)
{
- return rna_pointer_inherit_refine(ptr, &RNA_SculptCapabilities, ptr->id.data);
+ return rna_pointer_inherit_refine(ptr, &RNA_BrushCapabilities, ptr->id.data);
}
static void rna_Brush_reset_icon(Brush *br, const char *UNUSED(type))
@@ -464,41 +470,66 @@ static void rna_def_sculpt_capabilities(BlenderRNA *brna)
StructRNA *srna;
PropertyRNA *prop;
- srna = RNA_def_struct(brna, "SculptCapabilities", NULL);
+ srna = RNA_def_struct(brna, "SculptToolCapabilities", NULL);
RNA_def_struct_sdna(srna, "Brush");
RNA_def_struct_nested(brna, srna, "Brush");
RNA_def_struct_ui_text(srna, "Sculpt Capabilities",
"Read-only indications of which brush operations "
"are supported by the current sculpt tool");
+#define SCULPT_TOOL_CAPABILITY(prop_name_, ui_name_) \
+ prop = RNA_def_property(srna, #prop_name_, \
+ PROP_BOOLEAN, PROP_NONE); \
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE); \
+ RNA_def_property_boolean_funcs(prop, "rna_SculptToolCapabilities_" \
+ #prop_name_ "_get", NULL); \
+ RNA_def_property_ui_text(prop, ui_name_, NULL)
+
+ SCULPT_TOOL_CAPABILITY(has_accumulate, "Has Accumulate");
+ SCULPT_TOOL_CAPABILITY(has_auto_smooth, "Has Auto Smooth");
+ SCULPT_TOOL_CAPABILITY(has_height, "Has Height");
+ SCULPT_TOOL_CAPABILITY(has_jitter, "Has Jitter");
+ SCULPT_TOOL_CAPABILITY(has_normal_weight, "Has Crease/Pinch Factor");
+ SCULPT_TOOL_CAPABILITY(has_persistence, "Has Persistence");
+ SCULPT_TOOL_CAPABILITY(has_pinch_factor, "Has Pinch Factor");
+ SCULPT_TOOL_CAPABILITY(has_plane_offset, "Has Plane Offset");
+ SCULPT_TOOL_CAPABILITY(has_random_texture_angle, "Has Random Texture Angle");
+ SCULPT_TOOL_CAPABILITY(has_sculpt_plane, "Has Sculpt Plane");
+ SCULPT_TOOL_CAPABILITY(has_secondary_color, "Has Secondary Color");
+ SCULPT_TOOL_CAPABILITY(has_smooth_stroke, "Has Smooth Stroke");
+ SCULPT_TOOL_CAPABILITY(has_space_attenuation, "Has Space Attenuation");
+ SCULPT_TOOL_CAPABILITY(has_strength, "Has Strength");
+
+#undef SCULPT_CAPABILITY
+}
+
+static void rna_def_brush_capabilities(BlenderRNA *brna)
+{
+ StructRNA *srna;
+ PropertyRNA *prop;
+
+ srna = RNA_def_struct(brna, "BrushCapabilities", NULL);
+ RNA_def_struct_sdna(srna, "Brush");
+ RNA_def_struct_nested(brna, srna, "Brush");
+ RNA_def_struct_ui_text(srna, "Brush Capabilities",
+ "Read-only indications of which brush operations "
+ "are supported by the current brush");
+
#define BRUSH_CAPABILITY(prop_name_, ui_name_) \
prop = RNA_def_property(srna, #prop_name_, \
PROP_BOOLEAN, PROP_NONE); \
RNA_def_property_clear_flag(prop, PROP_EDITABLE); \
- RNA_def_property_boolean_funcs(prop, "rna_SculptCapabilities_" \
+ RNA_def_property_boolean_funcs(prop, "rna_BrushCapabilities_" \
#prop_name_ "_get", NULL); \
RNA_def_property_ui_text(prop, ui_name_, NULL)
- BRUSH_CAPABILITY(has_accumulate, "Has Accumulate");
- BRUSH_CAPABILITY(has_auto_smooth, "Has Auto Smooth");
- BRUSH_CAPABILITY(has_height, "Has Height");
- BRUSH_CAPABILITY(has_jitter, "Has Jitter");
- BRUSH_CAPABILITY(has_normal_weight, "Has Crease/Pinch Factor");
BRUSH_CAPABILITY(has_overlay, "Has Overlay");
- BRUSH_CAPABILITY(has_persistence, "Has Persistence");
- BRUSH_CAPABILITY(has_pinch_factor, "Has Pinch Factor");
- BRUSH_CAPABILITY(has_plane_offset, "Has Plane Offset");
BRUSH_CAPABILITY(has_random_texture_angle, "Has Random Texture Angle");
- BRUSH_CAPABILITY(has_sculpt_plane, "Has Sculpt Plane");
- BRUSH_CAPABILITY(has_secondary_color, "Has Secondary Color");
- BRUSH_CAPABILITY(has_smooth_stroke, "Has Smooth Stroke");
- BRUSH_CAPABILITY(has_space_attenuation, "Has Space Attenuation");
- BRUSH_CAPABILITY(has_spacing, "Has Spacing");
- BRUSH_CAPABILITY(has_strength, "Has Strength");
BRUSH_CAPABILITY(has_texture_angle, "Has Texture Angle");
BRUSH_CAPABILITY(has_texture_angle_source, "Has Texture Angle Source");
+ BRUSH_CAPABILITY(has_spacing, "Has Spacing");
-#undef SCULPT_CAPABILITY
+#undef BRUSH_CAPABILITY
}
static void rna_def_brush(BlenderRNA *brna)
@@ -634,10 +665,17 @@ static void rna_def_brush(BlenderRNA *brna)
prop = RNA_def_property(srna, "jitter", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "jitter");
- RNA_def_property_range(prop, 0.0f, 1.0f);
+ RNA_def_property_range(prop, 0.0f, 1000.0f);
+ RNA_def_property_ui_range(prop, 0.0f, 2.0f, 0.1, 4);
RNA_def_property_ui_text(prop, "Jitter", "Jitter the position of the brush while painting");
RNA_def_property_update(prop, 0, "rna_Brush_update");
+ prop = RNA_def_property(srna, "jitter_absolute", PROP_INT, PROP_NONE);
+ RNA_def_property_int_sdna(prop, NULL, "jitter_absolute");
+ RNA_def_property_range(prop, 0, 1000000);
+ RNA_def_property_ui_text(prop, "Jitter", "Jitter the position of the brush in pixels while painting");
+ RNA_def_property_update(prop, 0, "rna_Brush_update");
+
prop = RNA_def_property(srna, "spacing", PROP_INT, PROP_PERCENTAGE);
RNA_def_property_int_sdna(prop, NULL, "spacing");
RNA_def_property_range(prop, 1, 1000);
@@ -794,6 +832,11 @@ static void rna_def_brush(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Rake", "Rotate the brush texture to match the stroke direction");
RNA_def_property_update(prop, 0, "rna_Brush_update");
+ prop = RNA_def_property(srna, "use_relative_jitter", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", BRUSH_ABSOLUTE_JITTER);
+ RNA_def_property_ui_text(prop, "Absolute Jitter", "Jittering happens in screen space, not relative to brush size");
+ RNA_def_property_update(prop, 0, "rna_Brush_update");
+
prop = RNA_def_property(srna, "use_random_rotation", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", BRUSH_RANDOM_ROTATION);
RNA_def_property_ui_text(prop, "Random Rotation", "Rotate the brush texture at random");
@@ -957,11 +1000,17 @@ static void rna_def_brush(BlenderRNA *brna)
RNA_def_property_ui_range(prop, -1.0f, 1.0f, 10.0f, 3);
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_IMAGE, "rna_Brush_update");
+ prop = RNA_def_property(srna, "brush_capabilities", PROP_POINTER, PROP_NONE);
+ RNA_def_property_flag(prop, PROP_NEVER_NULL);
+ RNA_def_property_struct_type(prop, "BrushCapabilities");
+ RNA_def_property_pointer_funcs(prop, "rna_Brush_capabilities_get", NULL, NULL, NULL);
+ RNA_def_property_ui_text(prop, "Brush Capabilities", "Brush's capabilities");
+
/* brush capabilities (mode-dependent) */
prop = RNA_def_property(srna, "sculpt_capabilities", PROP_POINTER, PROP_NONE);
RNA_def_property_flag(prop, PROP_NEVER_NULL);
- RNA_def_property_struct_type(prop, "SculptCapabilities");
- RNA_def_property_pointer_funcs(prop, "rna_Brush_sculpt_capabilities_get", NULL, NULL, NULL);
+ RNA_def_property_struct_type(prop, "SculptToolCapabilities");
+ RNA_def_property_pointer_funcs(prop, "rna_Sculpt_sculpt_tool_capabilities_get", NULL, NULL, NULL);
RNA_def_property_ui_text(prop, "Sculpt Capabilities", "Brush's capabilities in sculpt mode");
}
@@ -1023,6 +1072,7 @@ static void rna_def_operator_stroke_element(BlenderRNA *brna)
void RNA_def_brush(BlenderRNA *brna)
{
rna_def_brush(brna);
+ rna_def_brush_capabilities(brna);
rna_def_sculpt_capabilities(brna);
rna_def_brush_texture_slot(brna);
rna_def_operator_stroke_element(brna);
diff --git a/source/blender/makesrna/intern/rna_camera.c b/source/blender/makesrna/intern/rna_camera.c
index 5f11663c057..5743fcf2b9f 100644
--- a/source/blender/makesrna/intern/rna_camera.c
+++ b/source/blender/makesrna/intern/rna_camera.c
@@ -24,17 +24,16 @@
* \ingroup RNA
*/
-
#include <stdlib.h>
-#include "RNA_define.h"
-
-#include "rna_internal.h"
-
#include "DNA_camera_types.h"
#include "BLI_math.h"
+#include "RNA_define.h"
+
+#include "rna_internal.h"
+
#include "WM_types.h"
#ifdef RNA_RUNTIME
@@ -186,20 +185,20 @@ void RNA_def_camera(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Clip End", "Camera far clipping distance");
RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, NULL);
- prop = RNA_def_property(srna, "lens", PROP_FLOAT, PROP_NONE);
+ prop = RNA_def_property(srna, "lens", PROP_FLOAT, PROP_DISTANCE_CAMERA);
RNA_def_property_float_sdna(prop, NULL, "lens");
RNA_def_property_range(prop, 1.0f, 5000.0f);
RNA_def_property_ui_text(prop, "Focal Length", "Perspective Camera lens value in millimeters");
RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, "rna_Camera_update");
- prop = RNA_def_property(srna, "sensor_width", PROP_FLOAT, PROP_NONE);
+ prop = RNA_def_property(srna, "sensor_width", PROP_FLOAT, PROP_DISTANCE_CAMERA);
RNA_def_property_float_sdna(prop, NULL, "sensor_x");
RNA_def_property_range(prop, 1.0f, FLT_MAX);
RNA_def_property_ui_range(prop, 1.0f, 100.f, 1, 2);
RNA_def_property_ui_text(prop, "Sensor Width", "Horizontal size of the image sensor area in millimeters");
RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, "rna_Camera_update");
- prop = RNA_def_property(srna, "sensor_height", PROP_FLOAT, PROP_NONE);
+ prop = RNA_def_property(srna, "sensor_height", PROP_FLOAT, PROP_DISTANCE_CAMERA);
RNA_def_property_float_sdna(prop, NULL, "sensor_y");
RNA_def_property_range(prop, 1.0f, FLT_MAX);
RNA_def_property_ui_range(prop, 1.0f, 100.f, 1, 2);
diff --git a/source/blender/makesrna/intern/rna_cloth.c b/source/blender/makesrna/intern/rna_cloth.c
index 69de86da007..1bf15fd0838 100644
--- a/source/blender/makesrna/intern/rna_cloth.c
+++ b/source/blender/makesrna/intern/rna_cloth.c
@@ -24,14 +24,9 @@
* \ingroup RNA
*/
-
#include <stdlib.h>
#include <limits.h>
-#include "RNA_define.h"
-
-#include "rna_internal.h"
-
#include "BKE_cloth.h"
#include "BKE_modifier.h"
@@ -39,6 +34,10 @@
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
+#include "RNA_define.h"
+
+#include "rna_internal.h"
+
#include "WM_api.h"
#include "WM_types.h"
diff --git a/source/blender/makesrna/intern/rna_color.c b/source/blender/makesrna/intern/rna_color.c
index f32f28e8143..c5f6744bcbe 100644
--- a/source/blender/makesrna/intern/rna_color.c
+++ b/source/blender/makesrna/intern/rna_color.c
@@ -24,16 +24,17 @@
* \ingroup RNA
*/
-
#include <stdlib.h>
#include <stdio.h>
-#include "RNA_define.h"
-#include "rna_internal.h"
-
#include "DNA_color_types.h"
#include "DNA_texture_types.h"
+#include "BLI_utildefines.h"
+
+#include "RNA_define.h"
+#include "rna_internal.h"
+
#include "WM_api.h"
#include "WM_types.h"
@@ -415,7 +416,8 @@ static void rna_ColorManagedDisplaySettings_display_device_set(struct PointerRNA
}
}
-static EnumPropertyItem *rna_ColorManagedDisplaySettings_display_device_itemf(bContext *C, PointerRNA *ptr, PropertyRNA *UNUSED(prop), int *free)
+static EnumPropertyItem *rna_ColorManagedDisplaySettings_display_device_itemf(bContext *UNUSED(C), PointerRNA *ptr,
+ PropertyRNA *UNUSED(prop), int *free)
{
EnumPropertyItem *items = NULL;
int totitem = 0;
@@ -462,7 +464,8 @@ static void rna_ColorManagedViewSettings_view_transform_set(PointerRNA *ptr, int
}
}
-static EnumPropertyItem *rna_ColorManagedViewSettings_view_transform_itemf(bContext *C, PointerRNA *ptr, PropertyRNA *UNUSED(prop), int *free)
+static EnumPropertyItem *rna_ColorManagedViewSettings_view_transform_itemf(bContext *C, PointerRNA *ptr,
+ PropertyRNA *UNUSED(prop), int *free)
{
Scene *scene = CTX_data_scene(C);
EnumPropertyItem *items = NULL;
@@ -509,7 +512,8 @@ static void rna_ColorManagedColorspaceSettings_colorspace_set(struct PointerRNA
}
}
-static EnumPropertyItem *rna_ColorManagedColorspaceSettings_colorspace_itemf(bContext *C, PointerRNA *ptr, PropertyRNA *UNUSED(prop), int *free)
+static EnumPropertyItem *rna_ColorManagedColorspaceSettings_colorspace_itemf(bContext *UNUSED(C), PointerRNA *ptr,
+ PropertyRNA *UNUSED(prop), int *free)
{
EnumPropertyItem *items = NULL;
int totitem = 0;
@@ -1015,6 +1019,7 @@ static void rna_def_colormanage(BlenderRNA *brna)
RNA_def_struct_ui_text(srna, "ColorManagedInputColorspaceSettings", "Input color space settings");
prop = RNA_def_property(srna, "name", PROP_ENUM, PROP_NONE);
+ RNA_def_property_flag(prop, PROP_ENUM_NO_CONTEXT);
RNA_def_property_enum_items(prop, color_space_items);
RNA_def_property_enum_funcs(prop, "rna_ColorManagedColorspaceSettings_colorspace_get",
"rna_ColorManagedColorspaceSettings_colorspace_set",
@@ -1026,6 +1031,7 @@ static void rna_def_colormanage(BlenderRNA *brna)
RNA_def_struct_ui_text(srna, "ColorManagedSequencerColorspaceSettings", "Input color space settings");
prop = RNA_def_property(srna, "name", PROP_ENUM, PROP_NONE);
+ RNA_def_property_flag(prop, PROP_ENUM_NO_CONTEXT);
RNA_def_property_enum_items(prop, color_space_items);
RNA_def_property_enum_funcs(prop, "rna_ColorManagedColorspaceSettings_colorspace_get",
"rna_ColorManagedColorspaceSettings_colorspace_set",
diff --git a/source/blender/makesrna/intern/rna_constraint.c b/source/blender/makesrna/intern/rna_constraint.c
index 956483890f5..4ced8326560 100644
--- a/source/blender/makesrna/intern/rna_constraint.c
+++ b/source/blender/makesrna/intern/rna_constraint.c
@@ -24,13 +24,8 @@
* \ingroup RNA
*/
-
#include <stdlib.h>
-#include "RNA_define.h"
-
-#include "rna_internal.h"
-
#include "BLI_math.h"
#include "BLF_translation.h"
@@ -41,46 +36,73 @@
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
-#include "ED_object.h"
+#include "RNA_define.h"
+
+#include "rna_internal.h"
+
#include "WM_types.h"
+#include "ED_object.h"
+
/* please keep the names in sync with constraint.c */
EnumPropertyItem constraint_type_items[] = {
{0, "", 0, N_("Motion Tracking"), ""},
{CONSTRAINT_TYPE_CAMERASOLVER, "CAMERA_SOLVER", ICON_CONSTRAINT_DATA, "Camera Solver", ""},
{CONSTRAINT_TYPE_OBJECTSOLVER, "OBJECT_SOLVER", ICON_CONSTRAINT_DATA, "Object Solver", ""},
- {CONSTRAINT_TYPE_FOLLOWTRACK, "FOLLOW_TRACK", ICON_CONSTRAINT_DATA, "Follow Track", ""},
+ {CONSTRAINT_TYPE_FOLLOWTRACK, "FOLLOW_TRACK", ICON_CONSTRAINT_DATA, "Follow Track", ""},
{0, "", 0, N_("Transform"), ""},
- {CONSTRAINT_TYPE_LOCLIKE, "COPY_LOCATION", ICON_CONSTRAINT_DATA, "Copy Location", ""},
- {CONSTRAINT_TYPE_ROTLIKE, "COPY_ROTATION", ICON_CONSTRAINT_DATA, "Copy Rotation", ""},
- {CONSTRAINT_TYPE_SIZELIKE, "COPY_SCALE", ICON_CONSTRAINT_DATA, "Copy Scale", ""},
- {CONSTRAINT_TYPE_TRANSLIKE, "COPY_TRANSFORMS", ICON_CONSTRAINT_DATA, "Copy Transforms", ""},
- {CONSTRAINT_TYPE_DISTLIMIT, "LIMIT_DISTANCE", ICON_CONSTRAINT_DATA, "Limit Distance", ""},
- {CONSTRAINT_TYPE_LOCLIMIT, "LIMIT_LOCATION", ICON_CONSTRAINT_DATA, "Limit Location", ""},
- {CONSTRAINT_TYPE_ROTLIMIT, "LIMIT_ROTATION", ICON_CONSTRAINT_DATA, "Limit Rotation", ""},
- {CONSTRAINT_TYPE_SIZELIMIT, "LIMIT_SCALE", ICON_CONSTRAINT_DATA, "Limit Scale", ""},
- {CONSTRAINT_TYPE_SAMEVOL, "MAINTAIN_VOLUME", ICON_CONSTRAINT_DATA, "Maintain Volume", ""},
- {CONSTRAINT_TYPE_TRANSFORM, "TRANSFORM", ICON_CONSTRAINT_DATA, "Transformation", ""},
+ {CONSTRAINT_TYPE_LOCLIKE, "COPY_LOCATION", ICON_CONSTRAINT_DATA, "Copy Location",
+ "Copy the location of a target (with an optional offset), so that they move together"},
+ {CONSTRAINT_TYPE_ROTLIKE, "COPY_ROTATION", ICON_CONSTRAINT_DATA, "Copy Rotation",
+ "Copy the rotation of a target (with an optional offset), so that they rotate together"},
+ {CONSTRAINT_TYPE_SIZELIKE, "COPY_SCALE", ICON_CONSTRAINT_DATA, "Copy Scale",
+ "Copy the scale factors of a target (with an optional offset), so that they are scaled by the same amount"},
+ {CONSTRAINT_TYPE_TRANSLIKE, "COPY_TRANSFORMS", ICON_CONSTRAINT_DATA, "Copy Transforms",
+ "Copy all the transformations of a target, so that they move together"},
+ {CONSTRAINT_TYPE_DISTLIMIT, "LIMIT_DISTANCE", ICON_CONSTRAINT_DATA, "Limit Distance",
+ "Restrict movements to within a certain distance of a target (at the time of constraint evaluation only)"},
+ {CONSTRAINT_TYPE_LOCLIMIT, "LIMIT_LOCATION", ICON_CONSTRAINT_DATA, "Limit Location",
+ "Restrict movement along each axis within given ranges"},
+ {CONSTRAINT_TYPE_ROTLIMIT, "LIMIT_ROTATION", ICON_CONSTRAINT_DATA, "Limit Rotation",
+ "Restrict rotation along each axis within given ranges"},
+ {CONSTRAINT_TYPE_SIZELIMIT, "LIMIT_SCALE", ICON_CONSTRAINT_DATA, "Limit Scale",
+ "Restrict scaling along each axis with given ranges"},
+ {CONSTRAINT_TYPE_SAMEVOL, "MAINTAIN_VOLUME", ICON_CONSTRAINT_DATA, "Maintain Volume",
+ "Compensate for scaling one axis by applying suitable scaling to the other two axes"},
+ {CONSTRAINT_TYPE_TRANSFORM, "TRANSFORM", ICON_CONSTRAINT_DATA, "Transformation",
+ "Use one transform property from target to control another (or same) property on owner"},
{0, "", 0, N_("Tracking"), ""},
- {CONSTRAINT_TYPE_CLAMPTO, "CLAMP_TO", ICON_CONSTRAINT_DATA, "Clamp To", ""},
+ {CONSTRAINT_TYPE_CLAMPTO, "CLAMP_TO", ICON_CONSTRAINT_DATA, "Clamp To",
+ "Restrict movements to lie along a curve by remapping location along curve's longest axis"},
{CONSTRAINT_TYPE_DAMPTRACK, "DAMPED_TRACK", ICON_CONSTRAINT_DATA, "Damped Track",
- "Tracking by taking the shortest path"},
- {CONSTRAINT_TYPE_KINEMATIC, "IK", ICON_CONSTRAINT_DATA, "Inverse Kinematics", ""},
+ "Point towards a target by performing the smallest rotation necessary"},
+ {CONSTRAINT_TYPE_KINEMATIC, "IK", ICON_CONSTRAINT_DATA, "Inverse Kinematics",
+ "Control a chain of bones by specifying the endpoint target (Bones only)"},
{CONSTRAINT_TYPE_LOCKTRACK, "LOCKED_TRACK", ICON_CONSTRAINT_DATA, "Locked Track",
- "Tracking along a single axis"},
- {CONSTRAINT_TYPE_SPLINEIK, "SPLINE_IK", ICON_CONSTRAINT_DATA, "Spline IK", ""},
- {CONSTRAINT_TYPE_STRETCHTO, "STRETCH_TO", ICON_CONSTRAINT_DATA, "Stretch To", ""},
- {CONSTRAINT_TYPE_TRACKTO, "TRACK_TO", ICON_CONSTRAINT_DATA, "Track To",
- "Legacy tracking constraint prone to twisting artifacts"},
+ "Rotate around the specified ('locked') axis to point towards a target"},
+ {CONSTRAINT_TYPE_SPLINEIK, "SPLINE_IK", ICON_CONSTRAINT_DATA, "Spline IK",
+ "Align chain of bones along a curve (Bones only)"},
+ {CONSTRAINT_TYPE_STRETCHTO, "STRETCH_TO", ICON_CONSTRAINT_DATA, "Stretch To",
+ "Stretch along Y-Axis to point towards a target"},
+ {CONSTRAINT_TYPE_TRACKTO, "TRACK_TO", ICON_CONSTRAINT_DATA, "Track To",
+ "Legacy tracking constraint prone to twisting artifacts"},
{0, "", 0, N_("Relationship"), ""},
- {CONSTRAINT_TYPE_ACTION, "ACTION", ICON_CONSTRAINT_DATA, "Action", ""},
- {CONSTRAINT_TYPE_CHILDOF, "CHILD_OF", ICON_CONSTRAINT_DATA, "Child Of", ""},
- {CONSTRAINT_TYPE_MINMAX, "FLOOR", ICON_CONSTRAINT_DATA, "Floor", ""},
- {CONSTRAINT_TYPE_FOLLOWPATH, "FOLLOW_PATH", ICON_CONSTRAINT_DATA, "Follow Path", ""},
- {CONSTRAINT_TYPE_PIVOT, "PIVOT", ICON_CONSTRAINT_DATA, "Pivot", ""},
- {CONSTRAINT_TYPE_RIGIDBODYJOINT, "RIGID_BODY_JOINT", ICON_CONSTRAINT_DATA, "Rigid Body Joint", ""},
- {CONSTRAINT_TYPE_PYTHON, "SCRIPT", ICON_CONSTRAINT_DATA, "Script", ""},
- {CONSTRAINT_TYPE_SHRINKWRAP, "SHRINKWRAP", ICON_CONSTRAINT_DATA, "Shrinkwrap", ""},
+ {CONSTRAINT_TYPE_ACTION, "ACTION", ICON_CONSTRAINT_DATA, "Action",
+ "Use transform property of target to look up pose for owner from an Action"},
+ {CONSTRAINT_TYPE_CHILDOF, "CHILD_OF", ICON_CONSTRAINT_DATA, "Child Of",
+ "Make target the 'detachable' parent of owner"},
+ {CONSTRAINT_TYPE_MINMAX, "FLOOR", ICON_CONSTRAINT_DATA, "Floor",
+ "Use position (and optionally rotation) of target to define a 'wall' or 'floor' that the owner can not cross"},
+ {CONSTRAINT_TYPE_FOLLOWPATH, "FOLLOW_PATH", ICON_CONSTRAINT_DATA, "Follow Path",
+ "Use to animate an object/bone following a path"},
+ {CONSTRAINT_TYPE_PIVOT, "PIVOT", ICON_CONSTRAINT_DATA, "Pivot",
+ "Change pivot point for transforms (buggy)"},
+ {CONSTRAINT_TYPE_RIGIDBODYJOINT, "RIGID_BODY_JOINT", ICON_CONSTRAINT_DATA, "Rigid Body Joint",
+ "Use to define a Rigid Body Constraint (for Game Engine use only)"},
+ {CONSTRAINT_TYPE_PYTHON, "SCRIPT", ICON_CONSTRAINT_DATA, "Script",
+ "Custom constraint(s) written in Python (Not yet implemented)"},
+ {CONSTRAINT_TYPE_SHRINKWRAP, "SHRINKWRAP", ICON_CONSTRAINT_DATA, "Shrinkwrap",
+ "Restrict movements to surface of target mesh"},
{0, NULL, 0, NULL, NULL}
};
diff --git a/source/blender/makesrna/intern/rna_context.c b/source/blender/makesrna/intern/rna_context.c
index 4204506e67b..d7a679e9702 100644
--- a/source/blender/makesrna/intern/rna_context.c
+++ b/source/blender/makesrna/intern/rna_context.c
@@ -24,17 +24,17 @@
* \ingroup RNA
*/
-
#include <stdlib.h>
#include "DNA_ID.h"
#include "DNA_userdef_types.h"
+#include "BLI_utildefines.h"
+#include "BKE_context.h"
+
#include "RNA_access.h"
#include "RNA_define.h"
-#include "BKE_context.h"
-
#include "rna_internal.h" /* own include */
#ifdef RNA_RUNTIME
diff --git a/source/blender/makesrna/intern/rna_controller.c b/source/blender/makesrna/intern/rna_controller.c
index c59e376da82..472cc6e89e6 100644
--- a/source/blender/makesrna/intern/rna_controller.c
+++ b/source/blender/makesrna/intern/rna_controller.c
@@ -24,15 +24,18 @@
* \ingroup RNA
*/
-
#include <stdlib.h>
-#include "WM_types.h"
+#include "DNA_object_types.h"
+#include "DNA_controller_types.h"
+
+#include "BLI_utildefines.h"
+
#include "RNA_define.h"
#include "rna_internal.h"
-#include "DNA_object_types.h"
-#include "DNA_controller_types.h"
+
+#include "WM_types.h"
EnumPropertyItem controller_type_items[] = {
{CONT_LOGIC_AND, "LOGIC_AND", 0, "And", "Logic And"},
diff --git a/source/blender/makesrna/intern/rna_curve.c b/source/blender/makesrna/intern/rna_curve.c
index b7ef76eeaf3..dba33bb9ab5 100644
--- a/source/blender/makesrna/intern/rna_curve.c
+++ b/source/blender/makesrna/intern/rna_curve.c
@@ -26,11 +26,6 @@
#include <stdlib.h>
-#include "RNA_access.h"
-#include "RNA_define.h"
-
-#include "rna_internal.h"
-
#include "DNA_curve_types.h"
#include "DNA_key_types.h"
#include "DNA_material_types.h"
@@ -40,6 +35,11 @@
#include "BKE_font.h"
+#include "RNA_access.h"
+#include "RNA_define.h"
+
+#include "rna_internal.h"
+
#include "WM_types.h"
#include "BKE_curve.h"
diff --git a/source/blender/makesrna/intern/rna_dynamicpaint.c b/source/blender/makesrna/intern/rna_dynamicpaint.c
index a505ae0dec2..8d30a0be0f1 100644
--- a/source/blender/makesrna/intern/rna_dynamicpaint.c
+++ b/source/blender/makesrna/intern/rna_dynamicpaint.c
@@ -24,14 +24,9 @@
* \ingroup RNA
*/
-
#include <stdlib.h>
#include <limits.h>
-#include "RNA_define.h"
-
-#include "rna_internal.h"
-
#include "BLI_math_base.h"
#include "BKE_modifier.h"
@@ -43,6 +38,10 @@
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
+#include "RNA_define.h"
+
+#include "rna_internal.h"
+
#include "WM_types.h"
EnumPropertyItem prop_dynamicpaint_type_items[] = {
diff --git a/source/blender/makesrna/intern/rna_fcurve.c b/source/blender/makesrna/intern/rna_fcurve.c
index a91832268e2..f6f8b14d0e2 100644
--- a/source/blender/makesrna/intern/rna_fcurve.c
+++ b/source/blender/makesrna/intern/rna_fcurve.c
@@ -24,15 +24,8 @@
* \ingroup RNA
*/
-
#include <stdlib.h>
-#include "RNA_access.h"
-#include "RNA_define.h"
-#include "RNA_enum_types.h"
-
-#include "rna_internal.h"
-
#include "DNA_anim_types.h"
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
@@ -43,6 +36,12 @@
#include "BKE_action.h"
+#include "RNA_access.h"
+#include "RNA_define.h"
+#include "RNA_enum_types.h"
+
+#include "rna_internal.h"
+
#include "WM_types.h"
#include "ED_keyframing.h"
diff --git a/source/blender/makesrna/intern/rna_fluidsim.c b/source/blender/makesrna/intern/rna_fluidsim.c
index 84ff53ee68f..9ff83daa2f8 100644
--- a/source/blender/makesrna/intern/rna_fluidsim.c
+++ b/source/blender/makesrna/intern/rna_fluidsim.c
@@ -28,6 +28,7 @@
#include "DNA_object_fluidsim.h"
+#include "BLI_utildefines.h"
#include "BLI_path_util.h"
#include "RNA_define.h"
diff --git a/source/blender/makesrna/intern/rna_gpencil.c b/source/blender/makesrna/intern/rna_gpencil.c
index 9461a816652..7156b76bab2 100644
--- a/source/blender/makesrna/intern/rna_gpencil.c
+++ b/source/blender/makesrna/intern/rna_gpencil.c
@@ -24,19 +24,20 @@
* \ingroup RNA
*/
-
#include <stdlib.h>
-#include "RNA_access.h"
-#include "RNA_define.h"
-
-#include "rna_internal.h"
-
#include "DNA_gpencil_types.h"
#include "DNA_scene_types.h"
#include "MEM_guardedalloc.h"
+#include "BLI_utildefines.h"
+
+#include "RNA_access.h"
+#include "RNA_define.h"
+
+#include "rna_internal.h"
+
#include "WM_types.h"
#ifdef RNA_RUNTIME
@@ -547,7 +548,9 @@ static void rna_def_gpencil_layer(BlenderRNA *brna)
RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", GP_LAYER_NO_XRAY);
RNA_def_property_ui_text(prop, "X Ray", "Make the layer draw in front of objects");
RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update");
-
+
+
+ /* Layers API */
func = RNA_def_function(srna, "clear", "rna_GPencil_layer_clear");
RNA_def_function_ui_description(func, "Remove all the grease pencil layer data");
}
diff --git a/source/blender/makesrna/intern/rna_group.c b/source/blender/makesrna/intern/rna_group.c
index 4baf46fd0b5..1ac59f9caed 100644
--- a/source/blender/makesrna/intern/rna_group.c
+++ b/source/blender/makesrna/intern/rna_group.c
@@ -24,15 +24,16 @@
* \ingroup RNA
*/
-
#include <stdlib.h>
+#include "DNA_group_types.h"
+
+#include "BLI_utildefines.h"
+
#include "RNA_define.h"
#include "rna_internal.h"
-#include "DNA_group_types.h"
-
#ifdef RNA_RUNTIME
#include "DNA_scene_types.h"
diff --git a/source/blender/makesrna/intern/rna_image.c b/source/blender/makesrna/intern/rna_image.c
index be462e20ee7..81136193883 100644
--- a/source/blender/makesrna/intern/rna_image.c
+++ b/source/blender/makesrna/intern/rna_image.c
@@ -24,21 +24,22 @@
* \ingroup RNA
*/
-
#include <stdlib.h>
-#include "RNA_define.h"
-#include "RNA_enum_types.h"
-
-#include "rna_internal.h"
-
#include "DNA_image_types.h"
#include "DNA_scene_types.h"
+#include "BLI_utildefines.h"
+
#include "BKE_context.h"
#include "BKE_depsgraph.h"
#include "BKE_image.h"
+#include "RNA_define.h"
+#include "RNA_enum_types.h"
+
+#include "rna_internal.h"
+
#include "WM_types.h"
#include "WM_api.h"
@@ -454,7 +455,6 @@ static void rna_def_imageuser(BlenderRNA *brna)
RNA_def_property_int_sdna(prop, NULL, "offset");
RNA_def_property_ui_text(prop, "Offset", "Offset the number of the frame to use in the animation");
RNA_def_property_update(prop, 0, "rna_ImageUser_update");
- RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
prop = RNA_def_property(srna, "frame_start", PROP_INT, PROP_TIME);
RNA_def_property_int_sdna(prop, NULL, "sfra");
diff --git a/source/blender/makesrna/intern/rna_image_api.c b/source/blender/makesrna/intern/rna_image_api.c
index 5d45e0d23b6..c1769f02974 100644
--- a/source/blender/makesrna/intern/rna_image_api.c
+++ b/source/blender/makesrna/intern/rna_image_api.c
@@ -34,13 +34,15 @@
#include <string.h>
#include <time.h>
-#include "RNA_define.h"
-#include "RNA_enum_types.h"
-
#include "DNA_packedFile_types.h"
+#include "BLI_utildefines.h"
+
#include "BIF_gl.h"
+#include "RNA_define.h"
+#include "RNA_enum_types.h"
+
#include "rna_internal.h" /* own include */
#ifdef RNA_RUNTIME
diff --git a/source/blender/makesrna/intern/rna_internal.h b/source/blender/makesrna/intern/rna_internal.h
index 1c0909c946f..550a3d8f353 100644
--- a/source/blender/makesrna/intern/rna_internal.h
+++ b/source/blender/makesrna/intern/rna_internal.h
@@ -24,12 +24,13 @@
* \ingroup RNA
*/
-
#ifndef __RNA_INTERNAL_H__
#define __RNA_INTERNAL_H__
#include "UI_resources.h"
+#include "BLI_utildefines.h"
+
#include "rna_internal_types.h"
#define RNA_MAGIC ((int)~0)
@@ -211,9 +212,9 @@ void rna_ID_name_get(struct PointerRNA *ptr, char *value);
int rna_ID_name_length(struct PointerRNA *ptr);
void rna_ID_name_set(struct PointerRNA *ptr, const char *value);
struct StructRNA *rna_ID_refine(struct PointerRNA *ptr);
-struct IDProperty *rna_ID_idprops(struct PointerRNA *ptr, int create);
+struct IDProperty *rna_ID_idprops(struct PointerRNA *ptr, bool create);
void rna_ID_fake_user_set(struct PointerRNA *ptr, int value);
-struct IDProperty *rna_PropertyGroup_idprops(struct PointerRNA *ptr, int create);
+struct IDProperty *rna_PropertyGroup_idprops(struct PointerRNA *ptr, bool create);
void rna_PropertyGroup_unregister(struct Main *bmain, struct StructRNA *type);
struct StructRNA *rna_PropertyGroup_register(struct Main *bmain, struct ReportList *reports, void *data,
const char *identifier, StructValidateFunc validate,
@@ -422,6 +423,4 @@ int rna_IDMaterials_assign_int(struct PointerRNA *ptr, int key, const struct Poi
void rna_RenderLayer_rect_set(PointerRNA *ptr, const float *values);
void rna_RenderPass_rect_set(PointerRNA *ptr, const float *values);
-#endif /* __RNA_INTERNAL_H__ */
-
-
+#endif /* __RNA_INTERNAL_H__ */
diff --git a/source/blender/makesrna/intern/rna_internal_types.h b/source/blender/makesrna/intern/rna_internal_types.h
index 43ec09de010..1dce89c343d 100644
--- a/source/blender/makesrna/intern/rna_internal_types.h
+++ b/source/blender/makesrna/intern/rna_internal_types.h
@@ -66,7 +66,7 @@ typedef void (*ContextPropUpdateFunc)(struct bContext *C, struct PointerRNA *ptr
typedef void (*ContextUpdateFunc)(struct bContext *C, struct PointerRNA *ptr);
typedef int (*EditableFunc)(struct PointerRNA *ptr);
typedef int (*ItemEditableFunc)(struct PointerRNA *ptr, int index);
-typedef struct IDProperty *(*IDPropertiesFunc)(struct PointerRNA *ptr, int create);
+typedef struct IDProperty *(*IDPropertiesFunc)(struct PointerRNA *ptr, bool create);
typedef struct StructRNA *(*StructRefineFunc)(struct PointerRNA *ptr);
typedef char *(*StructPathFunc)(struct PointerRNA *ptr);
diff --git a/source/blender/makesrna/intern/rna_key.c b/source/blender/makesrna/intern/rna_key.c
index 33bbaeec282..1577019f22a 100644
--- a/source/blender/makesrna/intern/rna_key.c
+++ b/source/blender/makesrna/intern/rna_key.c
@@ -24,14 +24,8 @@
* \ingroup RNA
*/
-
#include <stdlib.h>
-#include "RNA_access.h"
-#include "RNA_define.h"
-
-#include "rna_internal.h"
-
#include "DNA_ID.h"
#include "DNA_scene_types.h"
#include "DNA_curve_types.h"
@@ -39,6 +33,13 @@
#include "DNA_lattice_types.h"
#include "DNA_mesh_types.h"
+#include "BLI_utildefines.h"
+
+#include "RNA_access.h"
+#include "RNA_define.h"
+
+#include "rna_internal.h"
+
#ifdef RNA_RUNTIME
#include <stddef.h>
diff --git a/source/blender/makesrna/intern/rna_lamp.c b/source/blender/makesrna/intern/rna_lamp.c
index 660f6fc6ab7..912f4d914cb 100644
--- a/source/blender/makesrna/intern/rna_lamp.c
+++ b/source/blender/makesrna/intern/rna_lamp.c
@@ -24,20 +24,20 @@
* \ingroup RNA
*/
-
#include <stdlib.h>
+#include "BLI_math_base.h"
+
+#include "BLF_translation.h"
+
#include "RNA_define.h"
#include "RNA_enum_types.h"
-
#include "rna_internal.h"
#include "DNA_lamp_types.h"
#include "DNA_material_types.h"
#include "DNA_texture_types.h"
-#include "BLI_math_base.h"
-
#ifdef RNA_RUNTIME
#include "MEM_guardedalloc.h"
@@ -364,6 +364,7 @@ static void rna_def_lamp(BlenderRNA *brna)
prop = RNA_def_property(srna, "type", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_items(prop, lamp_type_items);
RNA_def_property_ui_text(prop, "Type", "Type of Lamp");
+ RNA_def_property_translation_context(prop, BLF_I18NCONTEXT_ID_LAMP);
RNA_def_property_update(prop, 0, "rna_Lamp_draw_update");
prop = RNA_def_property(srna, "distance", PROP_FLOAT, PROP_DISTANCE);
diff --git a/source/blender/makesrna/intern/rna_lattice.c b/source/blender/makesrna/intern/rna_lattice.c
index e4a29d9c674..b2790a25e47 100644
--- a/source/blender/makesrna/intern/rna_lattice.c
+++ b/source/blender/makesrna/intern/rna_lattice.c
@@ -24,19 +24,19 @@
* \ingroup RNA
*/
-
#include <stdlib.h>
-#include "RNA_define.h"
-#include "RNA_enum_types.h"
-
-#include "rna_internal.h"
-
#include "DNA_curve_types.h"
#include "DNA_key_types.h"
#include "DNA_lattice_types.h"
#include "DNA_meshdata_types.h"
+#include "BLI_utildefines.h"
+
+#include "RNA_define.h"
+#include "RNA_enum_types.h"
+#include "rna_internal.h"
+
#ifdef RNA_RUNTIME
#include "DNA_object_types.h"
diff --git a/source/blender/makesrna/intern/rna_main.c b/source/blender/makesrna/intern/rna_main.c
index 32db099c0c0..06a7b4aa11b 100644
--- a/source/blender/makesrna/intern/rna_main.c
+++ b/source/blender/makesrna/intern/rna_main.c
@@ -27,6 +27,7 @@
#include <stdlib.h>
#include <string.h>
+#include "BLI_utildefines.h"
#include "BLI_path_util.h"
#include "RNA_define.h"
diff --git a/source/blender/makesrna/intern/rna_main_api.c b/source/blender/makesrna/intern/rna_main_api.c
index 75ad64b1f29..de7911aeccb 100644
--- a/source/blender/makesrna/intern/rna_main_api.c
+++ b/source/blender/makesrna/intern/rna_main_api.c
@@ -36,8 +36,8 @@
#include "DNA_ID.h"
#include "DNA_modifier_types.h"
-#include "BLI_path_util.h"
#include "BLI_utildefines.h"
+#include "BLI_path_util.h"
#include "RNA_define.h"
#include "RNA_access.h"
diff --git a/source/blender/makesrna/intern/rna_mask.c b/source/blender/makesrna/intern/rna_mask.c
index 3f23a376ea3..72b0030ee23 100644
--- a/source/blender/makesrna/intern/rna_mask.c
+++ b/source/blender/makesrna/intern/rna_mask.c
@@ -31,6 +31,10 @@
#include "MEM_guardedalloc.h"
+#include "DNA_mask_types.h"
+#include "DNA_object_types.h" /* SELECT */
+#include "DNA_scene_types.h"
+
#include "BKE_movieclip.h"
#include "BKE_tracking.h"
@@ -39,10 +43,6 @@
#include "rna_internal.h"
-#include "DNA_mask_types.h"
-#include "DNA_object_types.h" /* SELECT */
-#include "DNA_scene_types.h"
-
#include "WM_types.h"
#include "IMB_imbuf_types.h"
diff --git a/source/blender/makesrna/intern/rna_material.c b/source/blender/makesrna/intern/rna_material.c
index 35173c290de..d1c81200e6a 100644
--- a/source/blender/makesrna/intern/rna_material.c
+++ b/source/blender/makesrna/intern/rna_material.c
@@ -24,17 +24,16 @@
* \ingroup RNA
*/
-
#include <float.h>
#include <stdlib.h>
+#include "DNA_material_types.h"
+#include "DNA_texture_types.h"
+
#include "RNA_define.h"
#include "rna_internal.h"
-#include "DNA_material_types.h"
-#include "DNA_texture_types.h"
-
#include "WM_api.h"
#include "WM_types.h"
diff --git a/source/blender/makesrna/intern/rna_mesh.c b/source/blender/makesrna/intern/rna_mesh.c
index 2fcec014a9c..73d77c2d0c4 100644
--- a/source/blender/makesrna/intern/rna_mesh.c
+++ b/source/blender/makesrna/intern/rna_mesh.c
@@ -28,28 +28,27 @@
* \ingroup RNA
*/
-
#include <stdlib.h>
#include "MEM_guardedalloc.h"
-#include "RNA_access.h"
-#include "RNA_define.h"
-#include "RNA_types.h"
-
-#include "rna_internal.h"
-
#include "DNA_material_types.h"
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
#include "DNA_object_types.h"
-#include "WM_types.h"
-
#include "BLI_array.h"
#include "BLI_math_base.h"
#include "BLI_math_rotation.h"
+#include "RNA_access.h"
+#include "RNA_define.h"
+#include "RNA_types.h"
+
+#include "rna_internal.h"
+
+#include "WM_types.h"
+
#ifdef RNA_RUNTIME
#include "DNA_scene_types.h"
@@ -552,7 +551,7 @@ DEFINE_CUSTOMDATA_LAYER_COLLECTION_ACTIVEITEM(uv_layer, ldata, CD_MLOOPUV, rende
/* MeshUVLoopLayer */
-static char *rna_MeshUVLoopLayer_path(PointerRNA * ptr)
+static char *rna_MeshUVLoopLayer_path(PointerRNA *ptr)
{
return BLI_sprintfN("uv_layers[\"%s\"]", ((CustomDataLayer *)ptr->data)->name);
}
diff --git a/source/blender/makesrna/intern/rna_meta.c b/source/blender/makesrna/intern/rna_meta.c
index 4813f25dea7..f38151fd721 100644
--- a/source/blender/makesrna/intern/rna_meta.c
+++ b/source/blender/makesrna/intern/rna_meta.c
@@ -24,18 +24,19 @@
* \ingroup RNA
*/
-
#include <stdlib.h>
+#include "DNA_mesh_types.h"
+#include "DNA_meta_types.h"
+
+#include "BLI_utildefines.h"
+
#include "RNA_access.h"
#include "RNA_define.h"
#include "RNA_enum_types.h"
#include "rna_internal.h"
-#include "DNA_mesh_types.h"
-#include "DNA_meta_types.h"
-
#ifdef RNA_RUNTIME
#include "BLI_math.h"
diff --git a/source/blender/makesrna/intern/rna_modifier.c b/source/blender/makesrna/intern/rna_modifier.c
index 810999033a4..fa436e30200 100644
--- a/source/blender/makesrna/intern/rna_modifier.c
+++ b/source/blender/makesrna/intern/rna_modifier.c
@@ -29,11 +29,6 @@
#include <limits.h>
#include <stdlib.h>
-#include "RNA_define.h"
-#include "RNA_enum_types.h"
-
-#include "rna_internal.h"
-
#include "DNA_armature_types.h"
#include "DNA_mesh_types.h"
#include "DNA_modifier_types.h"
@@ -53,6 +48,11 @@
#include "BKE_multires.h"
#include "BKE_smoke.h" /* For smokeModifier_free & smokeModifier_createType */
+#include "RNA_define.h"
+#include "RNA_enum_types.h"
+
+#include "rna_internal.h"
+
#include "WM_api.h"
#include "WM_types.h"
@@ -2593,6 +2593,13 @@ static void rna_def_modifier_simpledeform(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Factor", "Amount to deform object");
RNA_def_property_update(prop, 0, "rna_Modifier_update");
+ prop = RNA_def_property(srna, "angle", PROP_FLOAT, PROP_ANGLE);
+ RNA_def_property_float_sdna(prop, NULL, "factor");
+ RNA_def_property_range(prop, -FLT_MAX, FLT_MAX);
+ RNA_def_property_ui_range(prop, -10, 10, 1, 3);
+ RNA_def_property_ui_text(prop, "Angle", "Angle of deformation");
+ RNA_def_property_update(prop, 0, "rna_Modifier_update");
+
prop = RNA_def_property(srna, "limits", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "limit");
RNA_def_property_array(prop, 2);
@@ -2641,6 +2648,13 @@ static void rna_def_modifier_solidify(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Thickness", "Thickness of the shell");
RNA_def_property_update(prop, 0, "rna_Modifier_update");
+ prop = RNA_def_property(srna, "thickness_clamp", PROP_FLOAT, PROP_FACTOR);
+ RNA_def_property_float_sdna(prop, NULL, "offset_clamp");
+ RNA_def_property_range(prop, 0, 100.0);
+ RNA_def_property_ui_range(prop, 0, 2.0, 0.1, 4);
+ RNA_def_property_ui_text(prop, "Clamp", "Offset clamp based on geometry scale");
+ RNA_def_property_update(prop, 0, "rna_Modifier_update");
+
prop = RNA_def_property(srna, "thickness_vertex_group", PROP_FLOAT, PROP_FACTOR);
RNA_def_property_float_sdna(prop, NULL, "offset_fac_vg");
RNA_def_property_range(prop, 0.0, 1.0);
diff --git a/source/blender/makesrna/intern/rna_movieclip.c b/source/blender/makesrna/intern/rna_movieclip.c
index 3b018591455..cc3d5e5ca5e 100644
--- a/source/blender/makesrna/intern/rna_movieclip.c
+++ b/source/blender/makesrna/intern/rna_movieclip.c
@@ -25,7 +25,6 @@
* \ingroup RNA
*/
-
#include <stdlib.h>
#include <limits.h>
@@ -34,13 +33,13 @@
#include "BKE_movieclip.h"
#include "BKE_tracking.h"
+#include "DNA_movieclip_types.h"
+#include "DNA_scene_types.h"
+
#include "RNA_define.h"
#include "rna_internal.h"
-#include "DNA_movieclip_types.h"
-#include "DNA_scene_types.h"
-
#include "WM_types.h"
#include "IMB_imbuf_types.h"
diff --git a/source/blender/makesrna/intern/rna_nla.c b/source/blender/makesrna/intern/rna_nla.c
index 2b7f6a182a0..9afaad96019 100644
--- a/source/blender/makesrna/intern/rna_nla.c
+++ b/source/blender/makesrna/intern/rna_nla.c
@@ -24,20 +24,21 @@
* \ingroup RNA
*/
-
#include <stdlib.h>
-#include "RNA_access.h"
-#include "RNA_define.h"
-
-#include "rna_internal.h"
-
#include "DNA_anim_types.h"
#include "DNA_action_types.h"
#include "DNA_scene_types.h"
+#include "BLI_utildefines.h"
+
#include "MEM_guardedalloc.h"
+#include "RNA_access.h"
+#include "RNA_define.h"
+
+#include "rna_internal.h"
+
#include "WM_api.h"
#include "WM_types.h"
diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c
index 73fe5f3a48d..933b7a78b59 100644
--- a/source/blender/makesrna/intern/rna_nodetree.c
+++ b/source/blender/makesrna/intern/rna_nodetree.c
@@ -27,13 +27,6 @@
#include <stdlib.h>
#include <string.h>
-#include "RNA_access.h"
-#include "RNA_define.h"
-#include "RNA_enum_types.h"
-
-#include "rna_internal.h"
-#include "rna_internal_types.h"
-
#include "BLI_listbase.h"
#include "BLI_math.h"
#include "BLI_string.h"
@@ -54,7 +47,15 @@
#include "BKE_texture.h"
#include "BKE_idprop.h"
+#include "RNA_access.h"
+#include "RNA_define.h"
+#include "RNA_enum_types.h"
+
+#include "rna_internal.h"
+#include "rna_internal_types.h"
+
#include "IMB_imbuf.h"
+#include "IMB_imbuf_types.h"
#include "WM_types.h"
@@ -521,6 +522,38 @@ static void rna_Node_material_update(Main *bmain, Scene *scene, PointerRNA *ptr)
node_update(bmain, scene, ntree, node);
}
+static void rna_NodeTree_update(Main *bmain, Scene *scene, PointerRNA *ptr)
+{
+ bNodeTree *ntree = (bNodeTree *)ptr->id.data;
+
+ /* when using border, make it so no old data from outside of
+ * border is hanging around
+ * ideally shouldn't be in RNA callback, but how to teach
+ * compo to only clear frame when border usage is actually
+ * toggling
+ */
+ if (ntree->flag & NTREE_VIEWER_BORDER) {
+ Image *ima = BKE_image_verify_viewer(IMA_TYPE_COMPOSITE, "Viewer Node");
+ void *lock;
+ ImBuf *ibuf = BKE_image_acquire_ibuf(ima, NULL, &lock);
+
+ if (ibuf) {
+ if (ibuf->rect)
+ memset(ibuf->rect, 0, 4 * ibuf->x * ibuf->y);
+
+ if (ibuf->rect_float)
+ memset(ibuf->rect_float, 0, 4 * ibuf->x * ibuf->y * sizeof(float));
+
+ ibuf->userflags |= IB_DISPLAY_BUFFER_INVALID;
+ }
+
+ BKE_image_release_ibuf(ima, ibuf, lock);
+ }
+
+ WM_main_add_notifier(NC_NODE | NA_EDITED, NULL);
+ WM_main_add_notifier(NC_SCENE | ND_NODES, &ntree->id);
+}
+
static void rna_NodeGroup_update(Main *bmain, Scene *scene, PointerRNA *ptr)
{
bNodeTree *ntree = (bNodeTree *)ptr->id.data;
@@ -1009,6 +1042,16 @@ static bNodeSocket *rna_NodeTree_output_expose(bNodeTree *ntree, ReportList *rep
return NULL;
}
+static void rna_Image_Node_update_id(Main *bmain, Scene *scene, PointerRNA *ptr)
+{
+ bNodeTree *ntree = (bNodeTree *)ptr->id.data;
+ bNode *node = (bNode *)ptr->data;
+
+ node->update |= NODE_UPDATE_ID;
+ node_update(bmain, scene, ntree, node);
+ node->update &= ~NODE_UPDATE_ID;
+}
+
static void rna_Mapping_Node_update(Main *bmain, Scene *scene, PointerRNA *ptr)
{
bNode *node = ptr->data;
@@ -1193,7 +1236,7 @@ static void rna_ShaderNodeScript_bytecode_set(PointerRNA *ptr, const char *value
nss->bytecode = NULL;
}
-static IDProperty *rna_ShaderNodeScript_idprops(PointerRNA *ptr, int create)
+static IDProperty *rna_ShaderNodeScript_idprops(PointerRNA *ptr, bool create)
{
bNode *node = (bNode *)ptr->data;
NodeShaderScript *nss = node->storage;
@@ -2411,7 +2454,7 @@ static void def_cmp_image(StructRNA *srna)
RNA_def_property_struct_type(prop, "Image");
RNA_def_property_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "Image", "");
- RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
+ RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Image_Node_update_id");
prop = RNA_def_property(srna, "use_straight_alpha_output", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "custom1", CMP_NODE_IMAGE_USE_STRAIGHT_OUTPUT);
@@ -4091,7 +4134,7 @@ static void def_cmp_viewer(StructRNA *srna)
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
prop = RNA_def_property(srna, "use_alpha", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_negative_sdna(prop, NULL, "custom2", 1);
+ RNA_def_property_boolean_negative_sdna(prop, NULL, "custom2", CMP_NODE_OUTPUT_IGNORE_ALPHA);
RNA_def_property_ui_text(prop, "Use Alpha", "Colors are treated alpha premultiplied, or colors output straight (alpha gets set to 1)");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
}
@@ -4101,7 +4144,7 @@ static void def_cmp_composite(StructRNA *srna)
PropertyRNA *prop;
prop = RNA_def_property(srna, "use_alpha", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_negative_sdna(prop, NULL, "custom2", 1);
+ RNA_def_property_boolean_negative_sdna(prop, NULL, "custom2", CMP_NODE_OUTPUT_IGNORE_ALPHA);
RNA_def_property_ui_text(prop, "Use Alpha", "Colors are treated alpha premultiplied, or colors output straight (alpha gets set to 1)");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
}
@@ -4985,6 +5028,11 @@ static void rna_def_composite_nodetree(BlenderRNA *brna)
RNA_def_property_boolean_sdna(prop, NULL, "flag", NTREE_TWO_PASS);
RNA_def_property_ui_text(prop, "Two Pass", "Use two pass execution during editing: first calculate fast nodes, "
"second pass calculate all nodes");
+
+ prop = RNA_def_property(srna, "use_viewer_border", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", NTREE_VIEWER_BORDER);
+ RNA_def_property_ui_text(prop, "Viewer Border", "Use boundaries for viewer nodes and composite backdrop");
+ RNA_def_property_update(prop, NC_NODE | ND_DISPLAY, "rna_NodeTree_update");
}
static void rna_def_shader_nodetree(BlenderRNA *brna)
diff --git a/source/blender/makesrna/intern/rna_object.c b/source/blender/makesrna/intern/rna_object.c
index 2c736df1ed2..531794f7ab4 100644
--- a/source/blender/makesrna/intern/rna_object.c
+++ b/source/blender/makesrna/intern/rna_object.c
@@ -24,16 +24,9 @@
* \ingroup RNA
*/
-
#include <stdio.h>
#include <stdlib.h>
-#include "RNA_access.h"
-#include "RNA_define.h"
-#include "RNA_enum_types.h"
-
-#include "rna_internal.h"
-
#include "DNA_action_types.h"
#include "DNA_customdata_types.h"
#include "DNA_controller_types.h"
@@ -52,6 +45,12 @@
#include "BKE_tessmesh.h"
#include "BKE_group.h" /* needed for object_in_group() */
+#include "RNA_access.h"
+#include "RNA_define.h"
+#include "RNA_enum_types.h"
+
+#include "rna_internal.h"
+
#include "BLO_sys_types.h" /* needed for intptr_t used in ED_mesh.h */
#include "ED_mesh.h"
diff --git a/source/blender/makesrna/intern/rna_object_force.c b/source/blender/makesrna/intern/rna_object_force.c
index ec974df54d5..ab8b54334fe 100644
--- a/source/blender/makesrna/intern/rna_object_force.c
+++ b/source/blender/makesrna/intern/rna_object_force.c
@@ -24,13 +24,8 @@
* \ingroup RNA
*/
-
#include <stdlib.h>
-#include "RNA_define.h"
-
-#include "rna_internal.h"
-
#include "DNA_cloth_types.h"
#include "DNA_object_types.h"
#include "DNA_object_force.h"
@@ -38,6 +33,10 @@
#include "DNA_scene_types.h"
#include "DNA_smoke_types.h"
+#include "RNA_define.h"
+
+#include "rna_internal.h"
+
#include "WM_api.h"
#include "WM_types.h"
@@ -484,7 +483,7 @@ static void rna_FieldSettings_update(Main *UNUSED(bmain), Scene *UNUSED(scene),
part->pd->tex = NULL;
}
- if (part->pd2->forcefield != PFIELD_TEXTURE && part->pd2->tex) {
+ if (part->pd2 && part->pd2->forcefield != PFIELD_TEXTURE && part->pd2->tex) {
part->pd2->tex->id.us--;
part->pd2->tex = NULL;
}
diff --git a/source/blender/makesrna/intern/rna_packedfile.c b/source/blender/makesrna/intern/rna_packedfile.c
index e691ca46c69..a72188591a1 100644
--- a/source/blender/makesrna/intern/rna_packedfile.c
+++ b/source/blender/makesrna/intern/rna_packedfile.c
@@ -24,15 +24,16 @@
* \ingroup RNA
*/
-
#include <stdlib.h>
+#include "BLI_utildefines.h"
+
+#include "DNA_packedFile_types.h"
+
#include "RNA_define.h"
#include "rna_internal.h"
-#include "DNA_packedFile_types.h"
-
EnumPropertyItem unpack_method_items[] = {
{PF_USE_LOCAL, "USE_LOCAL", 0, "Use Local File", ""},
{PF_WRITE_LOCAL, "WRITE_LOCAL", 0, "Write Local File (overwrite existing)", ""},
diff --git a/source/blender/makesrna/intern/rna_particle.c b/source/blender/makesrna/intern/rna_particle.c
index 4bf5de03b05..c675aa6ebc3 100644
--- a/source/blender/makesrna/intern/rna_particle.c
+++ b/source/blender/makesrna/intern/rna_particle.c
@@ -27,16 +27,10 @@
* \ingroup RNA
*/
-
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
-#include "RNA_define.h"
-#include "RNA_enum_types.h"
-
-#include "rna_internal.h"
-
#include "DNA_material_types.h"
#include "DNA_meshdata_types.h"
#include "DNA_modifier_types.h"
@@ -48,6 +42,11 @@
#include "DNA_boid_types.h"
#include "DNA_texture_types.h"
+#include "RNA_define.h"
+#include "RNA_enum_types.h"
+
+#include "rna_internal.h"
+
#include "WM_types.h"
#include "WM_api.h"
diff --git a/source/blender/makesrna/intern/rna_pose.c b/source/blender/makesrna/intern/rna_pose.c
index 1ed675962f3..6a1b3d4cfc5 100644
--- a/source/blender/makesrna/intern/rna_pose.c
+++ b/source/blender/makesrna/intern/rna_pose.c
@@ -159,7 +159,7 @@ static void rna_BoneGroup_name_set(PointerRNA *ptr, const char *value)
BLI_uniquename(&ob->pose->agroups, agrp, "Group", '.', offsetof(bActionGroup, name), sizeof(agrp->name));
}
-static IDProperty *rna_PoseBone_idprops(PointerRNA *ptr, int create)
+static IDProperty *rna_PoseBone_idprops(PointerRNA *ptr, bool create)
{
bPoseChannel *pchan = ptr->data;
@@ -444,7 +444,7 @@ static void rna_pose_bgroup_name_index_set(PointerRNA *ptr, const char *value, s
int a;
for (a = 1, grp = pose->agroups.first; grp; grp = grp->next, a++) {
- if (strcmp(grp->name, value) == 0) {
+ if (STREQ(grp->name, value)) {
*index = a;
return;
}
@@ -459,7 +459,7 @@ static void rna_pose_pgroup_name_set(PointerRNA *ptr, const char *value, char *r
bActionGroup *grp;
for (grp = pose->agroups.first; grp; grp = grp->next) {
- if (strcmp(grp->name, value) == 0) {
+ if (STREQ(grp->name, value)) {
BLI_strncpy(result, value, maxlen);
return;
}
diff --git a/source/blender/makesrna/intern/rna_render.c b/source/blender/makesrna/intern/rna_render.c
index e2e373d8beb..8cf352311f7 100644
--- a/source/blender/makesrna/intern/rna_render.c
+++ b/source/blender/makesrna/intern/rna_render.c
@@ -28,6 +28,7 @@
#include "DNA_scene_types.h"
+#include "BLI_utildefines.h"
#include "BLI_path_util.h"
#include "RNA_define.h"
@@ -225,6 +226,20 @@ static StructRNA *rna_RenderEngine_refine(PointerRNA *ptr)
return (engine->type && engine->type->ext.srna) ? engine->type->ext.srna : &RNA_RenderEngine;
}
+static PointerRNA rna_RenderEngine_render_get(PointerRNA *ptr)
+{
+ RenderEngine *engine = (RenderEngine *)ptr->data;
+
+ if (engine->re) {
+ RenderData *r = RE_engine_get_render_data(engine->re);
+
+ return rna_pointer_inherit_refine(ptr, &RNA_RenderSettings, r);
+ }
+ else {
+ return rna_pointer_inherit_refine(ptr, &RNA_RenderSettings, NULL);
+ }
+}
+
static void rna_RenderResult_layers_begin(CollectionPropertyIterator *iter, PointerRNA *ptr)
{
RenderResult *rr = (RenderResult *)ptr->data;
@@ -406,6 +421,12 @@ static void rna_def_render_engine(BlenderRNA *brna)
RNA_def_property_int_sdna(prop, NULL, "resolution_y");
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+ /* Render Data */
+ prop = RNA_def_property(srna, "render", PROP_POINTER, PROP_NONE);
+ RNA_def_property_struct_type(prop, "RenderSettings");
+ RNA_def_property_pointer_funcs(prop, "rna_RenderEngine_render_get", NULL, NULL, NULL);
+ RNA_def_property_ui_text(prop, "Render Data", "");
+
prop = RNA_def_property(srna, "use_highlight_tiles", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", RE_ENGINE_HIGHLIGHT_TILES);
diff --git a/source/blender/makesrna/intern/rna_rna.c b/source/blender/makesrna/intern/rna_rna.c
index 9bd20d854e7..17b01de1eeb 100644
--- a/source/blender/makesrna/intern/rna_rna.c
+++ b/source/blender/makesrna/intern/rna_rna.c
@@ -24,11 +24,12 @@
* \ingroup RNA
*/
-
#include <stdlib.h>
#include "DNA_ID.h"
+#include "BLI_utildefines.h"
+
#include "RNA_access.h"
#include "RNA_define.h"
#include "RNA_enum_types.h"
@@ -65,6 +66,7 @@ EnumPropertyItem property_subtype_items[] = {
{PROP_ANGLE, "ANGLE", 0, "Angle", ""},
{PROP_TIME, "TIME", 0, "Time", ""},
{PROP_DISTANCE, "DISTANCE", 0, "Distance", ""},
+ {PROP_DISTANCE_CAMERA, "DISTANCE_CAMERA", 0, "Camera Distance", ""},
/* number arrays */
{PROP_COLOR, "COLOR", 0, "Color", ""},
@@ -96,6 +98,7 @@ EnumPropertyItem property_unit_items[] = {
{PROP_UNIT_TIME, "TIME", 0, "Time", ""},
{PROP_UNIT_VELOCITY, "VELOCITY", 0, "Velocity", ""},
{PROP_UNIT_ACCELERATION, "ACCELERATION", 0, "Acceleration", ""},
+ {PROP_UNIT_CAMERA, "CAMERA", 0, "Camera", ""},
{0, NULL, 0, NULL, NULL}
};
diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c
index 906c8853179..23a3c2188da 100644
--- a/source/blender/makesrna/intern/rna_scene.c
+++ b/source/blender/makesrna/intern/rna_scene.c
@@ -26,11 +26,6 @@
#include <stdlib.h>
-#include "RNA_define.h"
-#include "RNA_enum_types.h"
-
-#include "rna_internal.h"
-
#include "DNA_brush_types.h"
#include "DNA_group_types.h"
#include "DNA_modifier_types.h"
@@ -49,6 +44,11 @@
#include "BKE_tessmesh.h"
+#include "RNA_define.h"
+#include "RNA_enum_types.h"
+
+#include "rna_internal.h"
+
/* Include for Bake Options */
#include "RE_engine.h"
#include "RE_pipeline.h"
@@ -3578,8 +3578,9 @@ static void rna_def_scene_ffmpeg_settings(BlenderRNA *brna)
{CODEC_ID_THEORA, "THEORA", 0, "Theora", ""},
{CODEC_ID_FLV1, "FLASH", 0, "Flash Video", ""},
{CODEC_ID_FFV1, "FFV1", 0, "FFmpeg video codec #1", ""},
- {CODEC_ID_QTRLE, "QTRLE", 0, "QTRLE", ""},
+ {CODEC_ID_QTRLE, "QTRLE", 0, "QT rle / QT Animation", ""},
{CODEC_ID_DNXHD, "DNXHD", 0, "DNxHD", ""},
+ {CODEC_ID_PNG, "PNG", 0, "PNG", ""},
{0, NULL, 0, NULL, NULL}
};
diff --git a/source/blender/makesrna/intern/rna_scene_api.c b/source/blender/makesrna/intern/rna_scene_api.c
index b3619330e7a..82f054e62e0 100644
--- a/source/blender/makesrna/intern/rna_scene_api.c
+++ b/source/blender/makesrna/intern/rna_scene_api.c
@@ -32,6 +32,7 @@
#include <stdlib.h>
#include <stdio.h>
+#include "BLI_utildefines.h"
#include "BLI_path_util.h"
#include "RNA_define.h"
@@ -114,12 +115,13 @@ static void rna_Scene_collada_export(
int use_ngons,
int use_object_instantiation,
int sort_by_name,
+ int export_transformation_type,
int second_life)
{
collada_export(scene, filepath, apply_modifiers, export_mesh_type, selected,
include_children, include_armatures, include_shapekeys, deform_bones_only,
active_uv_only, include_uv_textures, include_material_textures,
- use_texture_copies, use_ngons, use_object_instantiation, sort_by_name, second_life);
+ use_texture_copies, use_ngons, use_object_instantiation, sort_by_name, export_transformation_type, second_life);
}
#endif
@@ -165,6 +167,10 @@ void RNA_api_scene(StructRNA *srna)
parm = RNA_def_boolean(func, "use_object_instantiation", 1, "Use Object Instances", "Instantiate multiple Objects from same Data");
parm = RNA_def_boolean(func, "sort_by_name", 0, "Sort by Object name", "Sort exported data by Object name");
parm = RNA_def_boolean(func, "second_life", 0, "Export for Second Life", "Compatibility mode for Second Life");
+
+ parm = RNA_def_int(func, "export_transformation_type", 0, INT_MIN, INT_MAX,
+ "Transformation", "Transformation type for translation, scale and rotation", INT_MIN, INT_MAX);
+
RNA_def_function_ui_description(func, "Export to collada file");
#endif
}
diff --git a/source/blender/makesrna/intern/rna_sculpt_paint.c b/source/blender/makesrna/intern/rna_sculpt_paint.c
index e0687295c70..b8b4ad5bb76 100644
--- a/source/blender/makesrna/intern/rna_sculpt_paint.c
+++ b/source/blender/makesrna/intern/rna_sculpt_paint.c
@@ -451,12 +451,7 @@ static void rna_def_image_paint(BlenderRNA *brna)
RNA_def_struct_path_func(srna, "rna_ImagePaintSettings_path");
RNA_def_struct_ui_text(srna, "Image Paint", "Properties of image and texture painting mode");
- /* booleans */
- prop = RNA_def_property(srna, "use_projection", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", IMAGEPAINT_PROJECT_DISABLE);
- RNA_def_property_ui_text(prop, "Project Paint",
- "Use projection painting for improved consistency in the brush strokes");
-
+ /* booleans */
prop = RNA_def_property(srna, "use_occlude", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", IMAGEPAINT_PROJECT_XRAY);
RNA_def_property_ui_text(prop, "Occlude", "Only paint onto the faces directly under the brush (slower)");
diff --git a/source/blender/makesrna/intern/rna_sensor.c b/source/blender/makesrna/intern/rna_sensor.c
index 6097fa2ae96..547d0ff78c9 100644
--- a/source/blender/makesrna/intern/rna_sensor.c
+++ b/source/blender/makesrna/intern/rna_sensor.c
@@ -24,19 +24,20 @@
* \ingroup RNA
*/
-
#include <stdlib.h>
+#include "DNA_constraint_types.h"
+#include "DNA_object_types.h"
+#include "DNA_sensor_types.h"
+
+#include "BLI_utildefines.h"
+
#include "RNA_define.h"
#include "RNA_enum_types.h"
#include "RNA_access.h"
#include "rna_internal.h"
-#include "DNA_constraint_types.h"
-#include "DNA_object_types.h"
-#include "DNA_sensor_types.h"
-
#include "WM_types.h"
/* Always keep in alphabetical order */
diff --git a/source/blender/makesrna/intern/rna_sensor_api.c b/source/blender/makesrna/intern/rna_sensor_api.c
index d920cbef4a2..476f0589bc9 100644
--- a/source/blender/makesrna/intern/rna_sensor_api.c
+++ b/source/blender/makesrna/intern/rna_sensor_api.c
@@ -28,15 +28,17 @@
* \ingroup RNA
*/
-
#include <stdlib.h>
#include <stdio.h>
-#include "WM_types.h"
+#include "BLI_utildefines.h"
+
#include "RNA_define.h"
#include "rna_internal.h" /* own include */
+#include "WM_types.h"
+
#ifdef RNA_RUNTIME
#include "BKE_sca.h"
diff --git a/source/blender/makesrna/intern/rna_sequencer.c b/source/blender/makesrna/intern/rna_sequencer.c
index a2704619ee6..9b81f042358 100644
--- a/source/blender/makesrna/intern/rna_sequencer.c
+++ b/source/blender/makesrna/intern/rna_sequencer.c
@@ -24,16 +24,9 @@
* \ingroup RNA
*/
-
#include <stdlib.h>
#include <limits.h>
-#include "RNA_access.h"
-#include "RNA_define.h"
-#include "RNA_enum_types.h"
-
-#include "rna_internal.h"
-
#include "DNA_anim_types.h"
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
@@ -49,6 +42,12 @@
#include "MEM_guardedalloc.h"
+#include "RNA_access.h"
+#include "RNA_define.h"
+#include "RNA_enum_types.h"
+
+#include "rna_internal.h"
+
#include "WM_types.h"
#include "BLF_translation.h"
diff --git a/source/blender/makesrna/intern/rna_sequencer_api.c b/source/blender/makesrna/intern/rna_sequencer_api.c
index 386263c784e..0c58d5cab6b 100644
--- a/source/blender/makesrna/intern/rna_sequencer_api.c
+++ b/source/blender/makesrna/intern/rna_sequencer_api.c
@@ -28,17 +28,17 @@
#include <stdio.h>
#include <string.h>
+#include "DNA_scene_types.h"
+#include "DNA_sequence_types.h"
+
+#include "BLI_utildefines.h"
+
#include "RNA_define.h"
#include "RNA_access.h"
#include "RNA_define.h"
#include "rna_internal.h"
-#include "DNA_scene_types.h"
-#include "DNA_sequence_types.h"
-
-#include "BLI_utildefines.h"
-
#ifdef RNA_RUNTIME
//#include "DNA_anim_types.h"
diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c
index f1f4c13731f..4bfc54c25ed 100644
--- a/source/blender/makesrna/intern/rna_space.c
+++ b/source/blender/makesrna/intern/rna_space.c
@@ -24,16 +24,10 @@
* \ingroup RNA
*/
-
#include <stdlib.h>
#include "MEM_guardedalloc.h"
-#include "RNA_access.h"
-#include "RNA_define.h"
-
-#include "rna_internal.h"
-
#include "BLF_translation.h"
#include "BKE_key.h"
@@ -49,6 +43,11 @@
#include "DNA_mask_types.h"
#include "DNA_view3d_types.h"
+#include "RNA_access.h"
+#include "RNA_define.h"
+
+#include "rna_internal.h"
+
#include "WM_api.h"
#include "WM_types.h"
@@ -3340,6 +3339,7 @@ static void rna_def_space_clip(BlenderRNA *brna)
RNA_def_property_enum_sdna(prop, NULL, "view");
RNA_def_property_enum_items(prop, view_items);
RNA_def_property_ui_text(prop, "View", "Type of the clip editor view");
+ RNA_def_property_translation_context(prop, BLF_I18NCONTEXT_ID_MOVIECLIP);
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_CLIP, "rna_SpaceClipEditor_view_type_update");
/* show pattern */
@@ -3513,6 +3513,7 @@ static void rna_def_space_clip(BlenderRNA *brna)
RNA_def_property_enum_sdna(prop, NULL, "gpencil_src");
RNA_def_property_enum_items(prop, gpencil_source_items);
RNA_def_property_ui_text(prop, "Grease Pencil Source", "Where the grease pencil comes from");
+ RNA_def_property_translation_context(prop, BLF_I18NCONTEXT_ID_MOVIECLIP);
RNA_def_property_update(prop, NC_MOVIECLIP | ND_DISPLAY, NULL);
/* pivot point */
diff --git a/source/blender/makesrna/intern/rna_text_api.c b/source/blender/makesrna/intern/rna_text_api.c
index 5f67f367195..de398bc10a6 100644
--- a/source/blender/makesrna/intern/rna_text_api.c
+++ b/source/blender/makesrna/intern/rna_text_api.c
@@ -24,10 +24,11 @@
* \ingroup RNA
*/
-
#include <stdlib.h>
#include <stdio.h>
+#include "BLI_utildefines.h"
+
#include "RNA_define.h"
#include "rna_internal.h" /* own include */
diff --git a/source/blender/makesrna/intern/rna_texture.c b/source/blender/makesrna/intern/rna_texture.c
index e007fe67c0b..d86e5fd0d9c 100644
--- a/source/blender/makesrna/intern/rna_texture.c
+++ b/source/blender/makesrna/intern/rna_texture.c
@@ -24,16 +24,10 @@
* \ingroup RNA
*/
-
#include <float.h>
#include <stdio.h>
#include <stdlib.h>
-#include "RNA_define.h"
-#include "RNA_enum_types.h"
-
-#include "rna_internal.h"
-
#include "DNA_brush_types.h"
#include "DNA_lamp_types.h"
#include "DNA_material_types.h"
@@ -48,6 +42,11 @@
#include "BKE_node.h"
+#include "RNA_define.h"
+#include "RNA_enum_types.h"
+
+#include "rna_internal.h"
+
#include "WM_api.h"
#include "WM_types.h"
@@ -1196,6 +1195,11 @@ static void rna_def_texture_image(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Flip Axis", "Flip the texture's X and Y axis");
RNA_def_property_update(prop, 0, "rna_Texture_update");
+ prop = RNA_def_property(srna, "use_alpha", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "imaflag", TEX_USEALPHA);
+ RNA_def_property_ui_text(prop, "Use Alpha", "Use the alpha channel information in the image");
+ RNA_def_property_update(prop, 0, "rna_Texture_update");
+
prop = RNA_def_property(srna, "use_calculate_alpha", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "imaflag", TEX_CALCALPHA);
RNA_def_property_ui_text(prop, "Calculate Alpha", "Calculate an alpha channel based on RGB values in the image");
diff --git a/source/blender/makesrna/intern/rna_texture_api.c b/source/blender/makesrna/intern/rna_texture_api.c
index 218fda361fa..10ac5a9548a 100644
--- a/source/blender/makesrna/intern/rna_texture_api.c
+++ b/source/blender/makesrna/intern/rna_texture_api.c
@@ -28,6 +28,7 @@
#include <stdio.h>
#include <string.h>
+#include "BLI_utildefines.h"
#include "BLI_path_util.h"
#include "RNA_define.h"
diff --git a/source/blender/makesrna/intern/rna_timeline.c b/source/blender/makesrna/intern/rna_timeline.c
index 3842fe95894..a732b550261 100644
--- a/source/blender/makesrna/intern/rna_timeline.c
+++ b/source/blender/makesrna/intern/rna_timeline.c
@@ -24,15 +24,14 @@
* \ingroup RNA
*/
-
#include <stdlib.h>
+#include "DNA_scene_types.h"
+
#include "RNA_define.h"
#include "rna_internal.h"
-#include "DNA_scene_types.h"
-
#include "WM_types.h"
#ifdef RNA_RUNTIME
diff --git a/source/blender/makesrna/intern/rna_tracking.c b/source/blender/makesrna/intern/rna_tracking.c
index 798395b9fef..6f0478b5eec 100644
--- a/source/blender/makesrna/intern/rna_tracking.c
+++ b/source/blender/makesrna/intern/rna_tracking.c
@@ -113,6 +113,7 @@ static void rna_tracking_active_object_index_set(PointerRNA *ptr, int value)
MovieClip *clip = (MovieClip *)ptr->id.data;
clip->tracking.objectnr = value;
+ BKE_tracking_dopesheet_tag_update(&clip->tracking);
}
static void rna_tracking_active_object_index_range(PointerRNA *ptr, int *min, int *max, int *softmin, int *softmax)
diff --git a/source/blender/makesrna/intern/rna_ui.c b/source/blender/makesrna/intern/rna_ui.c
index e5585b4f72d..05056574a71 100644
--- a/source/blender/makesrna/intern/rna_ui.c
+++ b/source/blender/makesrna/intern/rna_ui.c
@@ -29,6 +29,8 @@
#include "DNA_screen_types.h"
+#include "BLF_translation.h"
+
#include "RNA_define.h"
#include "rna_internal.h"
@@ -226,6 +228,7 @@ static StructRNA *rna_Panel_register(Main *bmain, ReportList *reports, void *dat
memcpy(pt, &dummypt, sizeof(dummypt));
pt->ext.srna = RNA_def_struct_ptr(&BLENDER_RNA, pt->idname, &RNA_Panel);
+ RNA_def_struct_translation_context(pt->ext.srna, pt->translation_context);
pt->ext.data = data;
pt->ext.call = call;
pt->ext.free = free;
@@ -573,6 +576,7 @@ static StructRNA *rna_Menu_register(Main *bmain, ReportList *reports, void *data
}
mt->ext.srna = RNA_def_struct_ptr(&BLENDER_RNA, mt->idname, &RNA_Menu);
+ RNA_def_struct_translation_context(mt->ext.srna, mt->translation_context);
mt->ext.data = data;
mt->ext.call = call;
mt->ext.free = free;
@@ -773,6 +777,7 @@ static void rna_def_panel(BlenderRNA *brna)
RNA_def_struct_sdna(srna, "Panel");
RNA_def_struct_refine_func(srna, "rna_Panel_refine");
RNA_def_struct_register_funcs(srna, "rna_Panel_register", "rna_Panel_unregister", NULL);
+ RNA_def_struct_translation_context(srna, BLF_I18NCONTEXT_DEFAULT);
/* poll */
func = RNA_def_function(srna, "poll", NULL);
@@ -819,7 +824,13 @@ static void rna_def_panel(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Label",
"The panel label, shows up in the panel header at the right of the "
"triangle used to collapse the panel");
-
+
+ prop = RNA_def_property(srna, "bl_translation_context", PROP_STRING, PROP_NONE);
+ RNA_def_property_string_sdna(prop, NULL, "type->translation_context");
+ RNA_def_property_string_default(prop, BLF_I18NCONTEXT_DEFAULT);
+ RNA_def_property_flag(prop, PROP_REGISTER_OPTIONAL);
+ RNA_define_verify_sdna(TRUE);
+
prop = RNA_def_property(srna, "bl_space_type", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "type->space_type");
RNA_def_property_enum_items(prop, space_type_items);
@@ -956,6 +967,7 @@ static void rna_def_menu(BlenderRNA *brna)
RNA_def_struct_sdna(srna, "Menu");
RNA_def_struct_refine_func(srna, "rna_Menu_refine");
RNA_def_struct_register_funcs(srna, "rna_Menu_register", "rna_Menu_unregister", NULL);
+ RNA_def_struct_translation_context(srna, BLF_I18NCONTEXT_DEFAULT);
/* poll */
func = RNA_def_function(srna, "poll", NULL);
@@ -972,7 +984,7 @@ static void rna_def_menu(BlenderRNA *brna)
parm = RNA_def_pointer(func, "context", "Context", "", "");
RNA_def_property_flag(parm, PROP_REQUIRED);
- RNA_define_verify_sdna(0); /* not in sdna */
+ RNA_define_verify_sdna(FALSE); /* not in sdna */
prop = RNA_def_property(srna, "layout", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_sdna(prop, NULL, "layout");
@@ -994,6 +1006,11 @@ static void rna_def_menu(BlenderRNA *brna)
RNA_def_property_flag(prop, PROP_REGISTER);
RNA_def_property_ui_text(prop, "Label", "The menu label");
+ prop = RNA_def_property(srna, "bl_translation_context", PROP_STRING, PROP_NONE);
+ RNA_def_property_string_sdna(prop, NULL, "type->translation_context");
+ RNA_def_property_string_default(prop, BLF_I18NCONTEXT_DEFAULT);
+ RNA_def_property_flag(prop, PROP_REGISTER_OPTIONAL);
+
prop = RNA_def_property(srna, "bl_description", PROP_STRING, PROP_NONE);
RNA_def_property_string_sdna(prop, NULL, "type->description");
RNA_def_property_string_maxlength(prop, RNA_DYN_DESCR_MAX); /* else it uses the pointer size! */
diff --git a/source/blender/makesrna/intern/rna_ui_api.c b/source/blender/makesrna/intern/rna_ui_api.c
index 0ce98e0b364..0204fa5367b 100644
--- a/source/blender/makesrna/intern/rna_ui_api.c
+++ b/source/blender/makesrna/intern/rna_ui_api.c
@@ -595,7 +595,7 @@ void RNA_api_ui_layout(StructRNA *srna)
func = RNA_def_function(srna, "label", "rna_uiItemL");
RNA_def_function_ui_description(func, "Item. Display text and/or icon in the layout");
- api_ui_item_common(func);
+ api_ui_item_common(func);
parm = RNA_def_property(func, "icon_value", PROP_INT, PROP_UNSIGNED);
RNA_def_property_ui_text(parm, "Icon Value",
"Override automatic icon of the item "
diff --git a/source/blender/makesrna/intern/rna_userdef.c b/source/blender/makesrna/intern/rna_userdef.c
index 6c6bb560192..c7b5d30e4d1 100644
--- a/source/blender/makesrna/intern/rna_userdef.c
+++ b/source/blender/makesrna/intern/rna_userdef.c
@@ -26,12 +26,6 @@
#include <stdlib.h>
-#include "RNA_access.h"
-#include "RNA_define.h"
-#include "RNA_enum_types.h"
-
-#include "rna_internal.h"
-
#include "DNA_curve_types.h"
#include "DNA_space_types.h"
#include "DNA_userdef_types.h"
@@ -39,16 +33,22 @@
#include "DNA_view3d_types.h"
#include "DNA_scene_types.h"
-#include "WM_api.h"
-#include "WM_types.h"
-
#include "BLI_utildefines.h"
-#include "BLF_translation.h"
-
#include "BKE_sound.h"
#include "BKE_addon.h"
+#include "RNA_access.h"
+#include "RNA_define.h"
+#include "RNA_enum_types.h"
+
+#include "rna_internal.h"
+
+#include "WM_api.h"
+#include "WM_types.h"
+
+#include "BLF_translation.h"
+
#ifdef WITH_CYCLES
static EnumPropertyItem compute_device_type_items[] = {
{USER_COMPUTE_DEVICE_NONE, "NONE", 0, "None", "Don't use compute device"},
@@ -278,7 +278,8 @@ static void rna_UserDef_weight_color_update(Main *bmain, Scene *scene, PointerRN
{
Object *ob;
- vDM_ColorBand_store((U.flag & USER_CUSTOM_RANGE) ? (&U.coba_weight) : NULL);
+ bTheme *btheme = UI_GetTheme();
+ vDM_ColorBand_store((U.flag & USER_CUSTOM_RANGE) ? (&U.coba_weight) : NULL, btheme->tv3d.vertex_unreferenced);
for (ob = bmain->object.first; ob; ob = ob->id.next) {
if (ob->mode & OB_MODE_WEIGHT_PAINT)
@@ -442,7 +443,7 @@ static EnumPropertyItem *rna_lang_enum_properties_itemf(bContext *UNUSED(C), Poi
}
#endif
-static IDProperty *rna_AddonPref_idprops(PointerRNA *ptr, int create)
+static IDProperty *rna_AddonPref_idprops(PointerRNA *ptr, bool create)
{
if (create && !ptr->data) {
IDPropertyTemplate val = {0};
@@ -1164,6 +1165,11 @@ static void rna_def_userdef_theme_spaces_vertex(StructRNA *srna)
RNA_def_property_range(prop, 1, 10);
RNA_def_property_ui_text(prop, "Vertex Size", "");
RNA_def_property_update(prop, 0, "rna_userdef_update");
+
+ prop = RNA_def_property(srna, "vertex_unreferenced", PROP_FLOAT, PROP_COLOR_GAMMA);
+ RNA_def_property_array(prop, 3);
+ RNA_def_property_ui_text(prop, "Vertex Group Unreferenced", "");
+ RNA_def_property_update(prop, 0, "rna_userdef_update");
}
static void rna_def_userdef_theme_spaces_edge(StructRNA *srna)
@@ -3464,6 +3470,12 @@ static void rna_def_userdef_system(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "GPU Mipmap Generation", "Generate Image Mipmaps on the GPU");
RNA_def_property_update(prop, 0, "rna_userdef_gl_gpu_mipmaps");
+ prop = RNA_def_property(srna, "image_gpubuffer_limit", PROP_INT, PROP_NONE);
+ RNA_def_property_int_sdna(prop, NULL, "image_gpubuffer_limit");
+ RNA_def_property_range(prop, 0, 128);
+ RNA_def_property_ui_text(prop, "Image GPU draw limit", "If set, amount of Mega Pixels to use for drawing Images as GPU textures");
+
+
prop = RNA_def_property(srna, "use_vertex_buffer_objects", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_negative_sdna(prop, NULL, "gameflags", USER_DISABLE_VBO);
RNA_def_property_ui_text(prop, "VBOs",
diff --git a/source/blender/makesrna/intern/rna_wm.c b/source/blender/makesrna/intern/rna_wm.c
index 0c1c5d8f64a..f42197ec0a9 100644
--- a/source/blender/makesrna/intern/rna_wm.c
+++ b/source/blender/makesrna/intern/rna_wm.c
@@ -24,20 +24,23 @@
* \ingroup RNA
*/
-
#include <stdlib.h>
+#include "DNA_screen_types.h"
+#include "DNA_space_types.h"
+#include "DNA_userdef_types.h"
+#include "DNA_windowmanager_types.h"
+
+#include "BLI_utildefines.h"
+
+#include "BLF_translation.h"
+
#include "RNA_access.h"
#include "RNA_define.h"
#include "RNA_enum_types.h"
#include "rna_internal.h"
-#include "DNA_screen_types.h"
-#include "DNA_space_types.h"
-#include "DNA_userdef_types.h"
-#include "DNA_windowmanager_types.h"
-
#include "WM_types.h"
EnumPropertyItem event_keymouse_value_items[] = {
@@ -466,7 +469,7 @@ static StructRNA *rna_OperatorProperties_refine(PointerRNA *ptr)
return ptr->type;
}
-static IDProperty *rna_OperatorProperties_idprops(PointerRNA *ptr, int create)
+static IDProperty *rna_OperatorProperties_idprops(PointerRNA *ptr, bool create)
{
if (create && !ptr->data) {
IDPropertyTemplate val = {0};
@@ -946,7 +949,7 @@ static int operator_check(bContext *C, wmOperator *op)
return result;
}
-static int operator_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int operator_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
extern FunctionRNA rna_Operator_invoke_func;
@@ -973,7 +976,7 @@ static int operator_invoke(bContext *C, wmOperator *op, wmEvent *event)
}
/* same as invoke */
-static int operator_modal(bContext *C, wmOperator *op, wmEvent *event)
+static int operator_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
extern FunctionRNA rna_Operator_modal_func;
@@ -1049,6 +1052,7 @@ void macro_wrapper(wmOperatorType *ot, void *userdata);
static char _operator_idname[OP_MAX_TYPENAME];
static char _operator_name[OP_MAX_TYPENAME];
static char _operator_descr[RNA_DYN_DESCR_MAX];
+static char _operator_ctxt[RNA_DYN_DESCR_MAX];
static StructRNA *rna_Operator_register(Main *bmain, ReportList *reports, void *data, const char *identifier,
StructValidateFunc validate, StructCallbackFunc call, StructFreeFunc free)
{
@@ -1062,10 +1066,13 @@ static StructRNA *rna_Operator_register(Main *bmain, ReportList *reports, void *
dummyot.idname = _operator_idname; /* only assigne the pointer, string is NULL'd */
dummyot.name = _operator_name; /* only assigne the pointer, string is NULL'd */
dummyot.description = _operator_descr; /* only assigne the pointer, string is NULL'd */
+ dummyot.translation_context = _operator_ctxt; /* only assigne the pointer, string is NULL'd */
RNA_pointer_create(NULL, &RNA_Operator, &dummyop, &dummyotr);
/* clear in case they are left unset */
_operator_idname[0] = _operator_name[0] = _operator_descr[0] = '\0';
+ /* We have to set default op context! */
+ strcpy(_operator_ctxt, BLF_I18NCONTEXT_OPERATOR_DEFAULT);
/* validate the python class */
if (validate(&dummyotr, data, have_function) != 0)
@@ -1116,9 +1123,10 @@ static StructRNA *rna_Operator_register(Main *bmain, ReportList *reports, void *
int idlen = strlen(_operator_idname) + 4;
int namelen = strlen(_operator_name) + 1;
int desclen = strlen(_operator_descr) + 1;
+ int ctxtlen = strlen(_operator_ctxt) + 1;
char *ch;
/* 2 terminators and 3 to convert a.b -> A_OT_b */
- ch = MEM_callocN(sizeof(char) * (idlen + namelen + desclen), "_operator_idname");
+ ch = MEM_callocN(sizeof(char) * (idlen + namelen + desclen + ctxtlen), "_operator_idname");
WM_operator_bl_idname(ch, _operator_idname); /* convert the idname from python */
dummyot.idname = ch;
ch += idlen;
@@ -1127,6 +1135,9 @@ static StructRNA *rna_Operator_register(Main *bmain, ReportList *reports, void *
ch += namelen;
strcpy(ch, _operator_descr);
dummyot.description = ch;
+ ch += desclen;
+ strcpy(ch, _operator_ctxt);
+ dummyot.translation_context = ch;
}
}
@@ -1143,6 +1154,7 @@ static StructRNA *rna_Operator_register(Main *bmain, ReportList *reports, void *
/* create a new operator type */
dummyot.ext.srna = RNA_def_struct_ptr(&BLENDER_RNA, dummyot.idname, &RNA_Operator);
RNA_def_struct_flag(dummyot.ext.srna, STRUCT_NO_IDPROPERTIES); /* operator properties are registered separately */
+ RNA_def_struct_translation_context(dummyot.ext.srna, dummyot.translation_context);
dummyot.ext.data = data;
dummyot.ext.call = call;
dummyot.ext.free = free;
@@ -1181,8 +1193,14 @@ static StructRNA *rna_MacroOperator_register(Main *bmain, ReportList *reports, v
dummyot.idname = _operator_idname; /* only assigne the pointer, string is NULL'd */
dummyot.name = _operator_name; /* only assigne the pointer, string is NULL'd */
dummyot.description = _operator_descr; /* only assigne the pointer, string is NULL'd */
+ dummyot.translation_context = _operator_ctxt; /* only assigne the pointer, string is NULL'd */
RNA_pointer_create(NULL, &RNA_Macro, &dummyop, &dummyotr);
+ /* clear in case they are left unset */
+ _operator_idname[0] = _operator_name[0] = _operator_descr[0] = '\0';
+ /* We have to set default op context! */
+ strcpy(_operator_ctxt, BLF_I18NCONTEXT_OPERATOR_DEFAULT);
+
/* validate the python class */
if (validate(&dummyotr, data, have_function) != 0)
return NULL;
@@ -1192,9 +1210,10 @@ static StructRNA *rna_MacroOperator_register(Main *bmain, ReportList *reports, v
int idlen = strlen(_operator_idname) + 4;
int namelen = strlen(_operator_name) + 1;
int desclen = strlen(_operator_descr) + 1;
+ int ctxtlen = strlen(_operator_ctxt) + 1;
char *ch;
/* 2 terminators and 3 to convert a.b -> A_OT_b */
- ch = MEM_callocN(sizeof(char) * (idlen + namelen + desclen), "_operator_idname");
+ ch = MEM_callocN(sizeof(char) * (idlen + namelen + desclen + ctxtlen), "_operator_idname");
WM_operator_bl_idname(ch, _operator_idname); /* convert the idname from python */
dummyot.idname = ch;
ch += idlen;
@@ -1203,6 +1222,9 @@ static StructRNA *rna_MacroOperator_register(Main *bmain, ReportList *reports, v
ch += namelen;
strcpy(ch, _operator_descr);
dummyot.description = ch;
+ ch += desclen;
+ strcpy(ch, _operator_ctxt);
+ dummyot.translation_context = ch;
}
if (strlen(identifier) >= sizeof(dummyop.idname)) {
@@ -1223,6 +1245,7 @@ static StructRNA *rna_MacroOperator_register(Main *bmain, ReportList *reports, v
/* create a new operator type */
dummyot.ext.srna = RNA_def_struct_ptr(&BLENDER_RNA, dummyot.idname, &RNA_Operator);
+ RNA_def_struct_translation_context(dummyot.ext.srna, dummyot.translation_context);
dummyot.ext.data = data;
dummyot.ext.call = call;
dummyot.ext.free = free;
@@ -1272,6 +1295,16 @@ static void rna_Operator_bl_label_set(PointerRNA *ptr, const char *value)
assert(!"setting the bl_label on a non-builtin operator");
}
+static void rna_Operator_bl_translation_context_set(PointerRNA *ptr, const char *value)
+{
+ wmOperator *data = (wmOperator *)(ptr->data);
+ char *str = (char *)data->type->translation_context;
+ if (!str[0])
+ BLI_strncpy(str, value, RNA_DYN_DESCR_MAX); /* utf8 already ensured */
+ else
+ assert(!"setting the bl_translation_context on a non-builtin operator");
+}
+
static void rna_Operator_bl_description_set(PointerRNA *ptr, const char *value)
{
wmOperator *data = (wmOperator *)(ptr->data);
@@ -1302,6 +1335,7 @@ static void rna_def_operator(BlenderRNA *brna)
#ifdef WITH_PYTHON
RNA_def_struct_register_funcs(srna, "rna_Operator_register", "rna_Operator_unregister", "rna_Operator_instance");
#endif
+ RNA_def_struct_translation_context(srna, BLF_I18NCONTEXT_OPERATOR_DEFAULT);
prop = RNA_def_property(srna, "name", PROP_STRING, PROP_NONE);
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
@@ -1340,6 +1374,14 @@ static void rna_def_operator(BlenderRNA *brna)
/* RNA_def_property_clear_flag(prop, PROP_EDITABLE); */
RNA_def_property_flag(prop, PROP_REGISTER);
+ prop = RNA_def_property(srna, "bl_translation_context", PROP_STRING, PROP_NONE);
+ RNA_def_property_string_sdna(prop, NULL, "type->translation_context");
+ RNA_def_property_string_maxlength(prop, RNA_DYN_DESCR_MAX); /* else it uses the pointer size! */
+ RNA_def_property_string_funcs(prop, NULL, NULL, "rna_Operator_bl_translation_context_set");
+ RNA_def_property_string_default(prop, BLF_I18NCONTEXT_OPERATOR_DEFAULT);
+ RNA_def_property_flag(prop, PROP_REGISTER_OPTIONAL);
+ RNA_def_property_clear_flag(prop, PROP_NEVER_NULL); /* check for NULL */
+
prop = RNA_def_property(srna, "bl_description", PROP_STRING, PROP_NONE);
RNA_def_property_string_sdna(prop, NULL, "type->description");
RNA_def_property_string_maxlength(prop, RNA_DYN_DESCR_MAX); /* else it uses the pointer size! */
@@ -1376,6 +1418,7 @@ static void rna_def_macro_operator(BlenderRNA *brna)
RNA_def_struct_register_funcs(srna, "rna_MacroOperator_register", "rna_Operator_unregister",
"rna_Operator_instance");
#endif
+ RNA_def_struct_translation_context(srna, BLF_I18NCONTEXT_OPERATOR_DEFAULT);
prop = RNA_def_property(srna, "name", PROP_STRING, PROP_NONE);
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
@@ -1404,6 +1447,14 @@ static void rna_def_macro_operator(BlenderRNA *brna)
/* RNA_def_property_clear_flag(prop, PROP_EDITABLE); */
RNA_def_property_flag(prop, PROP_REGISTER);
+ prop = RNA_def_property(srna, "bl_translation_context", PROP_STRING, PROP_NONE);
+ RNA_def_property_string_sdna(prop, NULL, "type->translation_context");
+ RNA_def_property_string_maxlength(prop, RNA_DYN_DESCR_MAX); /* else it uses the pointer size! */
+ RNA_def_property_string_funcs(prop, NULL, NULL, "rna_Operator_bl_translation_context_set");
+ RNA_def_property_string_default(prop, BLF_I18NCONTEXT_OPERATOR_DEFAULT);
+ RNA_def_property_flag(prop, PROP_REGISTER_OPTIONAL);
+ RNA_def_property_clear_flag(prop, PROP_NEVER_NULL); /* check for NULL */
+
prop = RNA_def_property(srna, "bl_description", PROP_STRING, PROP_NONE);
RNA_def_property_string_sdna(prop, NULL, "type->description");
RNA_def_property_string_maxlength(prop, RNA_DYN_DESCR_MAX); /* else it uses the pointer size! */
diff --git a/source/blender/makesrna/intern/rna_wm_api.c b/source/blender/makesrna/intern/rna_wm_api.c
index b7895cc0e2d..64c5f7ae220 100644
--- a/source/blender/makesrna/intern/rna_wm_api.c
+++ b/source/blender/makesrna/intern/rna_wm_api.c
@@ -86,6 +86,16 @@ static void rna_event_timer_remove(struct wmWindowManager *wm, wmTimer *timer)
WM_event_remove_timer(wm, timer->win, timer);
}
+/* wrap these because of 'const wmEvent *' */
+static int rna_Operator_confirm(bContext *C, wmOperator *op, wmEvent *event)
+{
+ return WM_operator_confirm(C, op, event);
+}
+static int rna_Operator_props_popup(bContext *C, wmOperator *op, wmEvent *event)
+{
+ return WM_operator_props_popup(C, op, event);
+}
+
static wmKeyMapItem *rna_KeyMap_item_new(wmKeyMap *km, ReportList *reports, const char *idname, int type, int value,
int any, int shift, int ctrl, int alt, int oskey, int keymodifier, int head)
{
@@ -266,7 +276,7 @@ void RNA_api_wm(StructRNA *srna)
/* invoke functions, for use with python */
- func = RNA_def_function(srna, "invoke_props_popup", "WM_operator_props_popup");
+ func = RNA_def_function(srna, "invoke_props_popup", "rna_Operator_props_popup");
RNA_def_function_ui_description(func, "Operator popup invoke");
rna_generic_op_invoke(func, WM_GEN_INVOKE_EVENT | WM_GEN_INVOKE_RETURN);
@@ -284,7 +294,7 @@ void RNA_api_wm(StructRNA *srna)
RNA_def_function_ui_description(func, "Operator popup invoke");
rna_generic_op_invoke(func, WM_GEN_INVOKE_SIZE | WM_GEN_INVOKE_RETURN);
- func = RNA_def_function(srna, "invoke_confirm", "WM_operator_confirm");
+ func = RNA_def_function(srna, "invoke_confirm", "rna_Operator_confirm");
RNA_def_function_ui_description(func, "Operator confirmation");
rna_generic_op_invoke(func, WM_GEN_INVOKE_EVENT | WM_GEN_INVOKE_RETURN);
diff --git a/source/blender/modifiers/intern/MOD_array.c b/source/blender/modifiers/intern/MOD_array.c
index 3ca2c364345..bc65b27be0c 100644
--- a/source/blender/modifiers/intern/MOD_array.c
+++ b/source/blender/modifiers/intern/MOD_array.c
@@ -338,7 +338,6 @@ static DerivedMesh *arrayModifier_doArray(ArrayModifierData *amd,
/* offset matrix */
float offset[4][4];
float final_offset[4][4];
- float tmp_mat[4][4];
float length = amd->length;
int count = amd->count, maxVerts;
int *indexMap = NULL;
@@ -418,6 +417,7 @@ static DerivedMesh *arrayModifier_doArray(ArrayModifierData *amd,
unit_m4(final_offset);
for (j = 0; j < count - 1; j++) {
+ float tmp_mat[4][4];
mult_m4_m4m4(tmp_mat, offset, final_offset);
copy_m4_m4(final_offset, tmp_mat);
}
diff --git a/source/blender/modifiers/intern/MOD_bevel.c b/source/blender/modifiers/intern/MOD_bevel.c
index 1942fe12a54..b14c4ba0ad1 100644
--- a/source/blender/modifiers/intern/MOD_bevel.c
+++ b/source/blender/modifiers/intern/MOD_bevel.c
@@ -160,7 +160,8 @@ static DerivedMesh *applyModifier(ModifierData *md, struct Object *ob,
}
BM_mesh_bevel(bm, bmd->value, bmd->res,
- vertex_only, bmd->lim_flags & BME_BEVEL_WEIGHT, dvert, vgroup);
+ vertex_only, bmd->lim_flags & BME_BEVEL_WEIGHT, true,
+ dvert, vgroup);
result = CDDM_from_bmesh(bm, TRUE);
diff --git a/source/blender/modifiers/intern/MOD_build.c b/source/blender/modifiers/intern/MOD_build.c
index c5a756733f5..0f5f9db2ee6 100644
--- a/source/blender/modifiers/intern/MOD_build.c
+++ b/source/blender/modifiers/intern/MOD_build.c
@@ -230,7 +230,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *UNUSED(ob),
/* copy the vertices across */
for (hashIter = BLI_ghashIterator_new(vertHash);
- !BLI_ghashIterator_isDone(hashIter);
+ BLI_ghashIterator_notDone(hashIter);
BLI_ghashIterator_step(hashIter)
)
{
diff --git a/source/blender/modifiers/intern/MOD_cloth.c b/source/blender/modifiers/intern/MOD_cloth.c
index 54f3efcc84c..808dfbae810 100644
--- a/source/blender/modifiers/intern/MOD_cloth.c
+++ b/source/blender/modifiers/intern/MOD_cloth.c
@@ -155,7 +155,6 @@ static void copyData(ModifierData *md, ModifierData *target)
if (clmd->sim_parms->effector_weights)
tclmd->sim_parms->effector_weights = MEM_dupallocN(clmd->sim_parms->effector_weights);
tclmd->coll_parms = MEM_dupallocN(clmd->coll_parms);
- tclmd->point_cache = BKE_ptcache_copy_list(&tclmd->ptcaches, &clmd->ptcaches, FALSE);
tclmd->clothObject = NULL;
}
diff --git a/source/blender/modifiers/intern/MOD_laplaciansmooth.c b/source/blender/modifiers/intern/MOD_laplaciansmooth.c
index 62da82a2af1..743cd1a829e 100644
--- a/source/blender/modifiers/intern/MOD_laplaciansmooth.c
+++ b/source/blender/modifiers/intern/MOD_laplaciansmooth.c
@@ -100,7 +100,6 @@ static void delete_void_pointer(void *data)
{
if (data) {
MEM_freeN(data);
- data = NULL;
}
}
@@ -242,7 +241,7 @@ static CustomDataMask required_data_mask(Object *UNUSED(ob), ModifierData *md)
static float average_area_quad_v3(float *v1, float *v2, float *v3, float *v4)
{
- float areaq = 0.0f;
+ float areaq;
areaq = area_tri_v3(v1, v2, v3) + area_tri_v3(v1, v2, v4) + area_tri_v3(v1, v3, v4);
return areaq / 2.0f;
}
@@ -520,7 +519,7 @@ static void fill_laplacian_matrix(LaplacianSystem *sys)
}
}
-static void validate_solution(LaplacianSystem * sys, short flag, float lambda, float lambda_border)
+static void validate_solution(LaplacianSystem *sys, short flag, float lambda, float lambda_border)
{
int i;
float lam;
diff --git a/source/blender/modifiers/intern/MOD_mask.c b/source/blender/modifiers/intern/MOD_mask.c
index 23ce8cdeb21..b86802340dc 100644
--- a/source/blender/modifiers/intern/MOD_mask.c
+++ b/source/blender/modifiers/intern/MOD_mask.c
@@ -316,7 +316,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob,
/* using ghash-iterators, map data into new mesh */
/* vertices */
for (hashIter = BLI_ghashIterator_new(vertHash);
- !BLI_ghashIterator_isDone(hashIter);
+ BLI_ghashIterator_notDone(hashIter);
BLI_ghashIterator_step(hashIter) )
{
MVert source;
@@ -334,7 +334,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob,
/* edges */
for (hashIter = BLI_ghashIterator_new(edgeHash);
- !BLI_ghashIterator_isDone(hashIter);
+ BLI_ghashIterator_notDone(hashIter);
BLI_ghashIterator_step(hashIter))
{
MEdge source;
@@ -355,7 +355,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob,
/* faces */
for (hashIter = BLI_ghashIterator_new(polyHash);
- !BLI_ghashIterator_isDone(hashIter);
+ BLI_ghashIterator_notDone(hashIter);
BLI_ghashIterator_step(hashIter) )
{
int oldIndex = GET_INT_FROM_POINTER(BLI_ghashIterator_getKey(hashIter));
diff --git a/source/blender/modifiers/intern/MOD_meshcache_pc2.c b/source/blender/modifiers/intern/MOD_meshcache_pc2.c
index 1ecb347d174..b20f62a8e77 100644
--- a/source/blender/modifiers/intern/MOD_meshcache_pc2.c
+++ b/source/blender/modifiers/intern/MOD_meshcache_pc2.c
@@ -62,7 +62,7 @@ static bool meshcache_read_pc2_head(FILE *fp, const int verts_tot,
}
#ifdef __BIG_ENDIAN__
- BLI_endian_switch_int32_array(&pc2_head->huh, (sizeof(*pc2_head) - sizeof(pc2_head->header)) / sizeof(int));
+ BLI_endian_switch_int32_array(&pc2_head->file_version, (sizeof(*pc2_head) - sizeof(pc2_head->header)) / sizeof(int));
#endif
if (pc2_head->verts_tot != verts_tot) {
diff --git a/source/blender/modifiers/intern/MOD_particleinstance.c b/source/blender/modifiers/intern/MOD_particleinstance.c
index 4984682455a..63dcb5d942d 100644
--- a/source/blender/modifiers/intern/MOD_particleinstance.c
+++ b/source/blender/modifiers/intern/MOD_particleinstance.c
@@ -209,7 +209,9 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob,
if (psys == NULL || psys->totpart == 0)
return derivedData;
}
- else return derivedData;
+ else {
+ return derivedData;
+ }
if (pimd->flag & eParticleInstanceFlag_Parents)
totpart += psys->totpart;
diff --git a/source/blender/modifiers/intern/MOD_skin.c b/source/blender/modifiers/intern/MOD_skin.c
index 81c53185825..c10e10350db 100644
--- a/source/blender/modifiers/intern/MOD_skin.c
+++ b/source/blender/modifiers/intern/MOD_skin.c
@@ -869,7 +869,7 @@ static DerivedMesh *subdivide_base(DerivedMesh *orig)
if (vg) {
vg->def_nr = dv1->dw[j].def_nr;
vg->w1 = dv1->dw[j].weight;
- vg->w1 = dv2->dw[k].weight;
+ vg->w2 = dv2->dw[k].weight;
}
}
}
diff --git a/source/blender/modifiers/intern/MOD_solidify.c b/source/blender/modifiers/intern/MOD_solidify.c
index a198eaf8ca9..9cdd52f2375 100644
--- a/source/blender/modifiers/intern/MOD_solidify.c
+++ b/source/blender/modifiers/intern/MOD_solidify.c
@@ -251,7 +251,8 @@ static DerivedMesh *applyModifier(
const float ofs_new = smd->offset + ofs_orig;
const float offset_fac_vg = smd->offset_fac_vg;
const float offset_fac_vg_inv = 1.0f - smd->offset_fac_vg;
- const int do_flip = (smd->flag & MOD_SOLIDIFY_FLIP) != 0;
+ const bool do_flip = (smd->flag & MOD_SOLIDIFY_FLIP) != 0;
+ const bool do_clamp = (smd->offset_clamp != 0.0f);
/* weights */
MDeformVert *dvert, *dv = NULL;
@@ -423,6 +424,20 @@ static DerivedMesh *applyModifier(
float scalar_short;
float scalar_short_vgroup;
+ /* for clamping */
+ float *vert_lens = NULL;
+ const float offset = fabsf(smd->offset) * smd->offset_clamp;
+ const float offset_sq = offset * offset;
+
+ if (do_clamp) {
+ vert_lens = MEM_callocN(sizeof(float) * numVerts, "vert_lens");
+ fill_vn_fl(vert_lens, numVerts, FLT_MAX);
+ for (i = 0; i < numEdges; i++) {
+ const float ed_len = len_squared_v3v3(mvert[medge[i].v1].co, mvert[medge[i].v2].co);
+ vert_lens[medge[i].v1] = min_ff(vert_lens[medge[i].v1], ed_len);
+ vert_lens[medge[i].v2] = min_ff(vert_lens[medge[i].v2], ed_len);
+ }
+ }
if (ofs_new != 0.0f) {
scalar_short = scalar_short_vgroup = ofs_new / 32767.0f;
@@ -435,6 +450,16 @@ static DerivedMesh *applyModifier(
scalar_short_vgroup = (offset_fac_vg + (scalar_short_vgroup * offset_fac_vg_inv)) * scalar_short;
dv++;
}
+ if (do_clamp) {
+ /* always reset becaise we may have set before */
+ if (dv == NULL) {
+ scalar_short_vgroup = scalar_short;
+ }
+ if (vert_lens[i] < offset_sq) {
+ float scalar = sqrtf(vert_lens[i]) / offset;
+ scalar_short_vgroup *= scalar;
+ }
+ }
madd_v3v3short_fl(mv->co, mv->no, scalar_short_vgroup);
}
}
@@ -450,9 +475,23 @@ static DerivedMesh *applyModifier(
scalar_short_vgroup = (offset_fac_vg + (scalar_short_vgroup * offset_fac_vg_inv)) * scalar_short;
dv++;
}
+ if (do_clamp) {
+ /* always reset becaise we may have set before */
+ if (dv == NULL) {
+ scalar_short_vgroup = scalar_short;
+ }
+ if (vert_lens[i] < offset_sq) {
+ float scalar = sqrtf(vert_lens[i]) / offset;
+ scalar_short_vgroup *= scalar;
+ }
+ }
madd_v3v3short_fl(mv->co, mv->no, scalar_short_vgroup);
}
}
+
+ if (do_clamp) {
+ MEM_freeN(vert_lens);
+ }
}
else {
/* make a face normal layer if not present */
@@ -540,6 +579,25 @@ static DerivedMesh *applyModifier(
}
}
+ if (do_clamp) {
+ float *vert_lens = MEM_callocN(sizeof(float) * numVerts, "vert_lens");
+ const float offset = fabsf(smd->offset) * smd->offset_clamp;
+ const float offset_sq = offset * offset;
+ fill_vn_fl(vert_lens, numVerts, FLT_MAX);
+ for (i = 0; i < numEdges; i++) {
+ const float ed_len = len_squared_v3v3(mvert[medge[i].v1].co, mvert[medge[i].v2].co);
+ vert_lens[medge[i].v1] = min_ff(vert_lens[medge[i].v1], ed_len);
+ vert_lens[medge[i].v2] = min_ff(vert_lens[medge[i].v2], ed_len);
+ }
+ for (i = 0; i < numVerts; i++) {
+ if (vert_lens[i] < offset_sq) {
+ float scalar = sqrtf(vert_lens[i]) / offset;
+ vert_angles[i] *= scalar;
+ }
+ }
+ MEM_freeN(vert_lens);
+ }
+
if (ofs_new) {
mv = mvert + (((ofs_new >= ofs_orig) == do_flip) ? numVerts : 0);
diff --git a/source/blender/nodes/composite/nodes/node_composite_outputFile.c b/source/blender/nodes/composite/nodes/node_composite_outputFile.c
index dff09b93845..d9a146ddaad 100644
--- a/source/blender/nodes/composite/nodes/node_composite_outputFile.c
+++ b/source/blender/nodes/composite/nodes/node_composite_outputFile.c
@@ -31,6 +31,7 @@
#include <string.h>
+#include "BLI_utildefines.h"
#include "BLI_path_util.h"
#include "node_composite_util.h"
@@ -44,7 +45,7 @@
/* **************** OUTPUT FILE ******************** */
/* find unique path */
-static int unique_path_unique_check(void *arg, const char *name)
+static bool unique_path_unique_check(void *arg, const char *name)
{
struct {ListBase *lb; bNodeSocket *sock;} *data= arg;
bNodeSocket *sock;
@@ -52,10 +53,10 @@ static int unique_path_unique_check(void *arg, const char *name)
if (sock != data->sock) {
NodeImageMultiFileSocket *sockdata = sock->storage;
if (strcmp(sockdata->path, name)==0)
- return 1;
+ return true;
}
}
- return 0;
+ return false;
}
void ntreeCompositOutputFileUniquePath(ListBase *list, bNodeSocket *sock, const char defname[], char delim)
{
@@ -73,7 +74,7 @@ void ntreeCompositOutputFileUniquePath(ListBase *list, bNodeSocket *sock, const
}
/* find unique EXR layer */
-static int unique_layer_unique_check(void *arg, const char *name)
+static bool unique_layer_unique_check(void *arg, const char *name)
{
struct {ListBase *lb; bNodeSocket *sock;} *data= arg;
bNodeSocket *sock;
@@ -81,10 +82,10 @@ static int unique_layer_unique_check(void *arg, const char *name)
if (sock != data->sock) {
NodeImageMultiFileSocket *sockdata = sock->storage;
if (strcmp(sockdata->layer, name)==0)
- return 1;
+ return true;
}
}
- return 0;
+ return false;
}
void ntreeCompositOutputFileUniqueLayer(ListBase *list, bNodeSocket *sock, const char defname[], char delim)
{
diff --git a/source/blender/nodes/composite/nodes/node_composite_trackpos.c b/source/blender/nodes/composite/nodes/node_composite_trackpos.c
index 8014e879894..1583680720a 100644
--- a/source/blender/nodes/composite/nodes/node_composite_trackpos.c
+++ b/source/blender/nodes/composite/nodes/node_composite_trackpos.c
@@ -34,8 +34,8 @@
#include "node_composite_util.h"
static bNodeSocketTemplate cmp_node_trackpos_out[] = {
- { SOCK_FLOAT, 1, N_("X")},
- { SOCK_FLOAT, 1, N_("Y")},
+ { SOCK_FLOAT, 0, N_("X")},
+ { SOCK_FLOAT, 0, N_("Y")},
{ -1, 0, "" }
};
diff --git a/source/blender/python/bmesh/bmesh_py_ops.c b/source/blender/python/bmesh/bmesh_py_ops.c
index 0a2091af5df..cc87d34d769 100644
--- a/source/blender/python/bmesh/bmesh_py_ops.c
+++ b/source/blender/python/bmesh/bmesh_py_ops.c
@@ -159,7 +159,7 @@ static PyObject *bpy_bmesh_ops_fakemod_getattro(PyObject *UNUSED(self), PyObject
const char *opname = _PyUnicode_AsString(pyname);
for (i = 0; i < tot; i++) {
- if (strcmp(bmo_opdefines[i]->opname, opname) == 0) {
+ if (STREQ(bmo_opdefines[i]->opname, opname)) {
return bpy_bmesh_op_CreatePyObject(opname);
}
}
diff --git a/source/blender/python/bmesh/bmesh_py_ops_call.c b/source/blender/python/bmesh/bmesh_py_ops_call.c
index fad3e4a35cd..4d728b76707 100644
--- a/source/blender/python/bmesh/bmesh_py_ops_call.c
+++ b/source/blender/python/bmesh/bmesh_py_ops_call.c
@@ -727,7 +727,7 @@ PyObject *BPy_BMO_call(BPy_BMeshOpFunc *self, PyObject *args, PyObject *kw)
return NULL;
}
- slot = BMO_slot_get(bmop.slots_in, slot_name);
+ slot = BMO_slot_get(bmop.slots_in, slot_name);
/* now assign the value */
if (bpy_slot_from_py(bm, &bmop, slot, value,
diff --git a/source/blender/python/bmesh/bmesh_py_types.h b/source/blender/python/bmesh/bmesh_py_types.h
index 8e6d04ec9ba..f02b94be526 100644
--- a/source/blender/python/bmesh/bmesh_py_types.h
+++ b/source/blender/python/bmesh/bmesh_py_types.h
@@ -168,7 +168,7 @@ int BPy_BMElem_CheckHType(PyTypeObject *type, const char htype);
char *BPy_BMElem_StringFromHType_ex(const char htype, char ret[32]);
char *BPy_BMElem_StringFromHType(const char htype);
-void bpy_bm_generic_invalidate(BPy_BMGeneric *self);
+// void bpy_bm_generic_invalidate(BPy_BMGeneric *self);
int bpy_bm_generic_valid_check(BPy_BMGeneric *self);
int bpy_bm_generic_valid_check_source(BPy_BMGeneric *self, BMesh *bm_source, const char *error_prefix);
diff --git a/source/blender/python/bmesh/bmesh_py_types_meshdata.h b/source/blender/python/bmesh/bmesh_py_types_meshdata.h
index c9e8dce97a0..8280e5c3bc5 100644
--- a/source/blender/python/bmesh/bmesh_py_types_meshdata.h
+++ b/source/blender/python/bmesh/bmesh_py_types_meshdata.h
@@ -51,9 +51,6 @@ PyObject *BPy_BMTexPoly_CreatePyObject(struct MTexPoly *mloopuv);
int BPy_BMLoopUV_AssignPyObject(struct MLoopUV *data, PyObject *value);
PyObject *BPy_BMLoopUV_CreatePyObject(struct MLoopUV *data);
-int BPy_BMLoopUV_AssignPyObject(struct MLoopUV *data, PyObject *value);
-PyObject *BPy_BMLoopUV_CreatePyObject(struct MLoopUV *data);
-
int BPy_BMLoopColor_AssignPyObject(struct MLoopCol *data, PyObject *value);
PyObject *BPy_BMLoopColor_CreatePyObject(struct MLoopCol *data);
diff --git a/source/blender/python/generic/idprop_py_api.c b/source/blender/python/generic/idprop_py_api.c
index a0e2f1a0854..85bb8125a3a 100644
--- a/source/blender/python/generic/idprop_py_api.c
+++ b/source/blender/python/generic/idprop_py_api.c
@@ -470,7 +470,9 @@ const char *BPy_IDProperty_Map_ValidateAndCreate(PyObject *name_obj, IDProperty
Py_XDECREF(keys);
Py_XDECREF(vals);
}
- else return "invalid property value";
+ else {
+ return "invalid property value";
+ }
if (group->type == IDP_IDPARRAY) {
IDP_AppendArray(group, prop);
diff --git a/source/blender/python/generic/py_capi_utils.c b/source/blender/python/generic/py_capi_utils.c
index 56d9e2ac0dd..2876d7666f4 100644
--- a/source/blender/python/generic/py_capi_utils.c
+++ b/source/blender/python/generic/py_capi_utils.c
@@ -751,7 +751,7 @@ void *PyC_RNA_AsPointer(PyObject *value, const char *type_name)
PyObject *as_pointer;
PyObject *pointer;
- if (!strcmp(Py_TYPE(value)->tp_name, type_name) &&
+ if (STREQ(Py_TYPE(value)->tp_name, type_name) &&
(as_pointer = PyObject_GetAttrString(value, "as_pointer")) != NULL &&
PyCallable_Check(as_pointer))
{
@@ -804,7 +804,7 @@ char *PyC_FlagSet_AsString(PyC_FlagSet *item)
int PyC_FlagSet_ValueFromID_int(PyC_FlagSet *item, const char *identifier, int *value)
{
for ( ; item->identifier; item++) {
- if (strcmp(item->identifier, identifier) == 0) {
+ if (STREQ(item->identifier, identifier)) {
*value = item->value;
return 1;
}
diff --git a/source/blender/python/intern/bpy.c b/source/blender/python/intern/bpy.c
index 1f8385288bd..01567a87fdf 100644
--- a/source/blender/python/intern/bpy.c
+++ b/source/blender/python/intern/bpy.c
@@ -32,13 +32,17 @@
#include <Python.h>
-#include "RNA_types.h"
-#include "RNA_access.h"
-
+#include "BLI_utildefines.h"
#include "BLI_path_util.h"
#include "BLI_string.h"
+
+#include "BKE_main.h"
+#include "BKE_global.h" /* XXX, G.main only */
+#include "BKE_blender.h"
#include "BKE_bpath.h"
-#include "BLI_utildefines.h"
+
+#include "RNA_types.h"
+#include "RNA_access.h"
#include "bpy.h"
#include "bpy_util.h"
@@ -48,10 +52,6 @@
#include "bpy_library.h"
#include "bpy_operator.h"
-#include "BKE_main.h"
-#include "BKE_global.h" /* XXX, G.main only */
-#include "BKE_blender.h"
-
#include "MEM_guardedalloc.h"
/* external util modules */
@@ -78,7 +78,7 @@ static PyObject *bpy_script_paths(PyObject *UNUSED(self))
{
PyObject *ret = PyTuple_New(2);
PyObject *item;
- char *path;
+ const char *path;
path = BLI_get_folder(BLENDER_SYSTEM_SCRIPTS, NULL);
item = PyUnicode_DecodeFSDefault(path ? path : "");
@@ -151,16 +151,16 @@ static PyObject *bpy_user_resource(PyObject *UNUSED(self), PyObject *args, PyObj
int folder_id;
static const char *kwlist[] = {"type", "subdir", NULL};
- char *path;
+ const char *path;
if (!PyArg_ParseTupleAndKeywords(args, kw, "s|s:user_resource", (char **)kwlist, &type, &subdir))
return NULL;
/* stupid string compare */
- if (!strcmp(type, "DATAFILES")) folder_id = BLENDER_USER_DATAFILES;
- else if (!strcmp(type, "CONFIG")) folder_id = BLENDER_USER_CONFIG;
- else if (!strcmp(type, "SCRIPTS")) folder_id = BLENDER_USER_SCRIPTS;
- else if (!strcmp(type, "AUTOSAVE")) folder_id = BLENDER_USER_AUTOSAVE;
+ if (STREQ(type, "DATAFILES")) folder_id = BLENDER_USER_DATAFILES;
+ else if (STREQ(type, "CONFIG")) folder_id = BLENDER_USER_CONFIG;
+ else if (STREQ(type, "SCRIPTS")) folder_id = BLENDER_USER_SCRIPTS;
+ else if (STREQ(type, "AUTOSAVE")) folder_id = BLENDER_USER_AUTOSAVE;
else {
PyErr_SetString(PyExc_ValueError, "invalid resource argument");
return NULL;
@@ -195,15 +195,15 @@ static PyObject *bpy_resource_path(PyObject *UNUSED(self), PyObject *args, PyObj
int major = BLENDER_VERSION / 100, minor = BLENDER_VERSION % 100;
static const char *kwlist[] = {"type", "major", "minor", NULL};
int folder_id;
- char *path;
+ const char *path;
if (!PyArg_ParseTupleAndKeywords(args, kw, "s|ii:resource_path", (char **)kwlist, &type, &major, &minor))
return NULL;
/* stupid string compare */
- if (!strcmp(type, "USER")) folder_id = BLENDER_RESOURCE_PATH_USER;
- else if (!strcmp(type, "LOCAL")) folder_id = BLENDER_RESOURCE_PATH_LOCAL;
- else if (!strcmp(type, "SYSTEM")) folder_id = BLENDER_RESOURCE_PATH_SYSTEM;
+ if (STREQ(type, "USER")) folder_id = BLENDER_RESOURCE_PATH_USER;
+ else if (STREQ(type, "LOCAL")) folder_id = BLENDER_RESOURCE_PATH_LOCAL;
+ else if (STREQ(type, "SYSTEM")) folder_id = BLENDER_RESOURCE_PATH_SYSTEM;
else {
PyErr_SetString(PyExc_ValueError, "invalid resource argument");
return NULL;
@@ -249,7 +249,7 @@ void BPy_init_modules(void)
PyObject *mod;
/* Needs to be first since this dir is needed for future modules */
- char *modpath = BLI_get_folder(BLENDER_SYSTEM_SCRIPTS, "modules");
+ const char * const modpath = BLI_get_folder(BLENDER_SYSTEM_SCRIPTS, "modules");
if (modpath) {
// printf("bpy: found module path '%s'.\n", modpath);
PyObject *sys_path = PySys_GetObject("path"); /* borrow */
diff --git a/source/blender/python/intern/bpy_app.c b/source/blender/python/intern/bpy_app.c
index 7889b9a7f0b..e5180c58d56 100644
--- a/source/blender/python/intern/bpy_app.c
+++ b/source/blender/python/intern/bpy_app.c
@@ -41,9 +41,8 @@
#include "bpy_app_handlers.h"
#include "bpy_driver.h"
-#include "BLI_path_util.h"
#include "BLI_utildefines.h"
-
+#include "BLI_path_util.h"
#include "BKE_blender.h"
#include "BKE_global.h"
diff --git a/source/blender/python/intern/bpy_app_translations.c b/source/blender/python/intern/bpy_app_translations.c
index 7c89972b486..35c39814124 100644
--- a/source/blender/python/intern/bpy_app_translations.c
+++ b/source/blender/python/intern/bpy_app_translations.c
@@ -32,9 +32,9 @@
/* XXX Why bloody hell isn't that included in Python.h???? */
#include <structmember.h>
+#include "BLI_utildefines.h"
#include "BLI_string.h"
#include "BLI_ghash.h"
-#include "BLI_utildefines.h"
#include "BPY_extern.h"
#include "bpy_app_translations.h"
diff --git a/source/blender/python/intern/bpy_interface.c b/source/blender/python/intern/bpy_interface.c
index 90199a403dc..552df561bbd 100644
--- a/source/blender/python/intern/bpy_interface.c
+++ b/source/blender/python/intern/bpy_interface.c
@@ -39,13 +39,13 @@
#include "MEM_guardedalloc.h"
+#include "BLI_utildefines.h"
#include "BLI_path_util.h"
#include "BLI_fileops.h"
#include "BLI_listbase.h"
#include "BLI_math_base.h"
#include "BLI_string.h"
#include "BLI_string_utf8.h"
-#include "BLI_utildefines.h"
#include "BLI_threads.h"
#include "RNA_types.h"
@@ -931,11 +931,7 @@ static void bpy_module_free(void *UNUSED(mod))
/* EVIL, define text.c functions here... */
-extern int text_check_identifier_unicode(const unsigned int ch);
-extern int text_check_identifier_nodigit_unicode(const unsigned int ch);
-extern int text_check_identifier(const char ch);
-extern int text_check_identifier_nodigit(const char ch);
-
+/* BKE_text.h */
int text_check_identifier_unicode(const unsigned int ch)
{
return (ch < 255 && text_check_identifier((char)ch)) || Py_UNICODE_ISALNUM(ch);
diff --git a/source/blender/python/intern/bpy_library.c b/source/blender/python/intern/bpy_library.c
index ec6322a1a11..3f66fb7b337 100644
--- a/source/blender/python/intern/bpy_library.c
+++ b/source/blender/python/intern/bpy_library.c
@@ -411,7 +411,7 @@ static PyObject *bpy_lib_exit(BPy_Library *self, PyObject *UNUSED(args))
/* append, rather than linking */
if ((self->flag & FILE_LINK) == 0) {
- BKE_library_make_local(bmain, lib, 1);
+ BKE_library_make_local(bmain, lib, true);
}
}
diff --git a/source/blender/python/intern/bpy_operator.c b/source/blender/python/intern/bpy_operator.c
index ee885684e03..26c043f796f 100644
--- a/source/blender/python/intern/bpy_operator.c
+++ b/source/blender/python/intern/bpy_operator.c
@@ -369,7 +369,7 @@ static PyObject *pyop_dir(PyObject *UNUSED(self))
GHashIterator *iter = WM_operatortype_iter();
PyObject *list = PyList_New(0), *name;
- for ( ; !BLI_ghashIterator_isDone(iter); BLI_ghashIterator_step(iter)) {
+ for ( ; BLI_ghashIterator_notDone(iter); BLI_ghashIterator_step(iter)) {
wmOperatorType *ot = BLI_ghashIterator_getValue(iter);
name = PyUnicode_FromString(ot->idname);
diff --git a/source/blender/python/intern/bpy_operator_wrap.c b/source/blender/python/intern/bpy_operator_wrap.c
index 9d92ff51213..1c722243424 100644
--- a/source/blender/python/intern/bpy_operator_wrap.c
+++ b/source/blender/python/intern/bpy_operator_wrap.c
@@ -127,6 +127,11 @@ void operator_wrapper(wmOperatorType *ot, void *userdata)
*ot = *((wmOperatorType *)userdata);
ot->srna = srna; /* restore */
+ /* Use i18n context from ext.srna if possible (py operators). */
+ if (ot->ext.srna) {
+ RNA_def_struct_translation_context(ot->srna, RNA_struct_translation_context(ot->ext.srna));
+ }
+
operator_properties_init(ot);
}
@@ -143,6 +148,11 @@ void macro_wrapper(wmOperatorType *ot, void *userdata)
ot->ui = data->ui;
ot->ext = data->ext;
+ /* Use i18n context from ext.srna if possible (py operators). */
+ if (ot->ext.srna) {
+ RNA_def_struct_translation_context(ot->srna, RNA_struct_translation_context(ot->ext.srna));
+ }
+
operator_properties_init(ot);
}
diff --git a/source/blender/python/intern/bpy_props.c b/source/blender/python/intern/bpy_props.c
index 830c2c8de3a..c330eb1549d 100644
--- a/source/blender/python/intern/bpy_props.c
+++ b/source/blender/python/intern/bpy_props.c
@@ -1265,9 +1265,11 @@ static int icon_id_from_name(const char *name)
int id;
if (name[0]) {
- for (item = icon_items, id = 0; item->identifier; item++, id++)
- if (strcmp(item->name, name) == 0)
+ for (item = icon_items, id = 0; item->identifier; item++, id++) {
+ if (STREQ(item->name, name)) {
return item->value;
+ }
+ }
}
return 0;
@@ -1353,7 +1355,7 @@ static EnumPropertyItem *enum_items_from_py(PyObject *seq_fast, PyObject *def, i
tmp.value = i;
}
- if (def && def_used == 0 && strcmp(def_cmp, tmp.identifier) == 0) {
+ if (def && def_used == 0 && STREQ(def_cmp, tmp.identifier)) {
*defvalue = tmp.value;
def_used++; /* only ever 1 */
}
diff --git a/source/blender/python/intern/bpy_rna.c b/source/blender/python/intern/bpy_rna.c
index cef4e23242d..0adb5e2e90e 100644
--- a/source/blender/python/intern/bpy_rna.c
+++ b/source/blender/python/intern/bpy_rna.c
@@ -250,7 +250,7 @@ static void id_release_weakref_list(struct ID *id, GHash *weakinfo_hash)
fprintf(stdout, "id_release_weakref: '%s', %d items\n", id->name, BLI_ghash_size(weakinfo_hash));
#endif
- while (!BLI_ghashIterator_isDone(&weakinfo_hash_iter)) {
+ while (BLI_ghashIterator_notDone(&weakinfo_hash_iter)) {
PyObject *weakref = (PyObject *)BLI_ghashIterator_getKey(&weakinfo_hash_iter);
PyObject *item = PyWeakref_GET_OBJECT(weakref);
if (item != Py_None) {
@@ -1427,7 +1427,9 @@ int pyrna_pydict_to_props(PointerRNA *ptr, PyObject *kw, int all_args, const cha
{
arg_name = RNA_property_identifier(prop);
- if (strcmp(arg_name, "rna_type") == 0) continue;
+ if (STREQ(arg_name, "rna_type")) {
+ continue;
+ }
if (kw == NULL) {
PyErr_Format(PyExc_TypeError,
@@ -2223,7 +2225,7 @@ static int pyrna_prop_collection_subscript_str_lib_pair_ptr(BPy_PropertyRNA *sel
RNA_PROP_BEGIN (&self->ptr, itemptr, self->prop)
{
ID *id = itemptr.data; /* always an ID */
- if (id->lib == lib && (strncmp(keyname, id->name + 2, sizeof(id->name) - 2) == 0)) {
+ if (id->lib == lib && (STREQLEN(keyname, id->name + 2, sizeof(id->name) - 2))) {
found = true;
if (r_ptr) {
*r_ptr = itemptr;
@@ -3463,7 +3465,7 @@ static PyObject *pyrna_struct_getattro(BPy_StructRNA *self, PyObject *pyname)
}
else if (name[0] == '_') { /* rna can't start with a "_", so for __dict__ and similar we can skip using rna lookups */
/* annoying exception, maybe we need to have different types for this... */
- if ((strcmp(name, "__getitem__") == 0 || strcmp(name, "__setitem__") == 0) && !RNA_struct_idprops_check(self->ptr.type)) {
+ if ((STREQ(name, "__getitem__") || STREQ(name, "__setitem__")) && !RNA_struct_idprops_check(self->ptr.type)) {
PyErr_SetString(PyExc_AttributeError, "bpy_struct: no __getitem__ support for this type");
ret = NULL;
}
@@ -4939,7 +4941,7 @@ static PyObject *small_dict_get_item_string(PyObject *dict, const char *key_look
while (PyDict_Next(dict, &pos, &key, &value)) {
if (PyUnicode_Check(key)) {
- if (strcmp(key_lookup, _PyUnicode_AsString(key)) == 0) {
+ if (STREQ(key_lookup, _PyUnicode_AsString(key))) {
return value;
}
}
@@ -5139,7 +5141,7 @@ static PyObject *pyrna_func_call(BPy_FunctionRNA *self, PyObject *args, PyObject
RNA_parameter_list_begin(&parms, &iter);
for (; iter.valid; RNA_parameter_list_next(&iter)) {
parm = iter.parm;
- if (strcmp(arg_name, RNA_property_identifier(parm)) == 0) {
+ if (STREQ(arg_name, RNA_property_identifier(parm))) {
found = true;
break;
}
@@ -6937,7 +6939,7 @@ static int bpy_class_validate_recursive(PointerRNA *dummyptr, StructRNA *srna, v
/* Sneaky workaround to use the class name as the bl_idname */
#define BPY_REPLACEMENT_STRING(rna_attr, py_attr) \
- (strcmp(identifier, rna_attr) == 0) { \
+ (STREQ(identifier, rna_attr)) { \
item = PyObject_GetAttr(py_class, py_attr); \
if (item && item != Py_None) { \
if (pyrna_py_to_prop(dummyptr, prop, NULL, \
@@ -6948,7 +6950,7 @@ static int bpy_class_validate_recursive(PointerRNA *dummyptr, StructRNA *srna, v
} \
} \
Py_XDECREF(item); \
- } /* intendionally allow else here */
+ } /* intentionally allow else here */
if BPY_REPLACEMENT_STRING("bl_idname", bpy_intern_str___name__)
else if BPY_REPLACEMENT_STRING("bl_description", bpy_intern_str___doc__)
diff --git a/source/blender/python/intern/bpy_traceback.c b/source/blender/python/intern/bpy_traceback.c
index 48bf65a841b..81d12e9d9a6 100644
--- a/source/blender/python/intern/bpy_traceback.c
+++ b/source/blender/python/intern/bpy_traceback.c
@@ -29,6 +29,7 @@
#include <Python.h>
#include <frameobject.h>
+#include "BLI_utildefines.h"
#include "BLI_path_util.h"
#include "BLI_string.h"
diff --git a/source/blender/python/mathutils/mathutils_Matrix.c b/source/blender/python/mathutils/mathutils_Matrix.c
index da2888045d0..1fcebf29f28 100644
--- a/source/blender/python/mathutils/mathutils_Matrix.c
+++ b/source/blender/python/mathutils/mathutils_Matrix.c
@@ -829,10 +829,10 @@ static PyObject *C_Matrix_Shear(PyObject *cls, PyObject *args)
mat[0] = 1.0f;
mat[3] = 1.0f;
- if (strcmp(plane, "X") == 0) {
+ if (STREQ(plane, "X")) {
mat[2] = factor;
}
- else if (strcmp(plane, "Y") == 0) {
+ else if (STREQ(plane, "Y")) {
mat[1] = factor;
}
else {
@@ -855,15 +855,15 @@ static PyObject *C_Matrix_Shear(PyObject *cls, PyObject *args)
mat[4] = 1.0f;
mat[8] = 1.0f;
- if (strcmp(plane, "XY") == 0) {
+ if (STREQ(plane, "XY")) {
mat[6] = factor[0];
mat[7] = factor[1];
}
- else if (strcmp(plane, "XZ") == 0) {
+ else if (STREQ(plane, "XZ")) {
mat[3] = factor[0];
mat[5] = factor[1];
}
- else if (strcmp(plane, "YZ") == 0) {
+ else if (STREQ(plane, "YZ")) {
mat[1] = factor[0];
mat[2] = factor[1];
}
diff --git a/source/blender/quicktime/apple/qtkit_import.m b/source/blender/quicktime/apple/qtkit_import.m
index 2e910e38871..974c2555ee5 100644
--- a/source/blender/quicktime/apple/qtkit_import.m
+++ b/source/blender/quicktime/apple/qtkit_import.m
@@ -32,6 +32,7 @@
#include "BLO_sys_types.h"
#include "BKE_global.h"
+#include "BLI_utildefines.h"
#include "BLI_dynstr.h"
#include "BLI_path_util.h"
diff --git a/source/blender/quicktime/apple/quicktime_export.c b/source/blender/quicktime/apple/quicktime_export.c
index c85df29de92..5e114bf7379 100644
--- a/source/blender/quicktime/apple/quicktime_export.c
+++ b/source/blender/quicktime/apple/quicktime_export.c
@@ -559,7 +559,7 @@ int start_qt(struct Scene *scene, struct RenderData *rd, int rectx, int recty, R
#ifdef __APPLE__
EnterMoviesOnThread(0);
- sprintf(theFullPath, "%s", name);
+ strcpy(theFullPath, name);
/* hack: create an empty file to make FSPathMakeRef() happy */
myFile = open(theFullPath, O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IRUSR | S_IWUSR);
@@ -575,7 +575,7 @@ int start_qt(struct Scene *scene, struct RenderData *rd, int rectx, int recty, R
#endif
#ifdef _WIN32
qtname = get_valid_qtname(name);
- sprintf(theFullPath, "%s", qtname);
+ strcpy(theFullPath, qtname);
strcpy(name, qtname);
MEM_freeN(qtname);
diff --git a/source/blender/quicktime/apple/quicktime_import.c b/source/blender/quicktime/apple/quicktime_import.c
index e44eba2bfe0..9481a37e3c7 100644
--- a/source/blender/quicktime/apple/quicktime_import.c
+++ b/source/blender/quicktime/apple/quicktime_import.c
@@ -210,13 +210,13 @@ int anim_is_quicktime(const char *name)
if (QTIME_DEBUG) printf("qt: checking as movie: %s\n", name);
#ifdef __APPLE__
- sprintf(theFullPath, "%s", name);
+ strcpy(theFullPath, name);
err = FSPathMakeRef(theFullPath, &myRef, 0);
err = FSGetCatalogInfo(&myRef, kFSCatInfoNone, NULL, NULL, &theFSSpec, NULL);
#else
qtname = get_valid_qtname(name);
- sprintf(theFullPath, "%s", qtname);
+ strcpy(theFullPath, qtname);
MEM_freeN(qtname);
CopyCStringToPascal(theFullPath, dst);
@@ -461,13 +461,13 @@ int startquicktime(struct anim *anim)
if (QTIME_DEBUG) printf("qt: attempting to load as movie %s\n", anim->name);
#ifdef __APPLE__
- sprintf(theFullPath, "%s", anim->name);
+ strcpy(theFullPath, anim->name);
err = FSPathMakeRef(theFullPath, &myRef, 0);
err = FSGetCatalogInfo(&myRef, kFSCatInfoNone, NULL, NULL, &theFSSpec, NULL);
#else
qtname = get_valid_qtname(anim->name);
- sprintf(theFullPath, "%s", qtname);
+ strcpy(theFullPath, qtname);
MEM_freeN(qtname);
CopyCStringToPascal(theFullPath, dst);
@@ -592,7 +592,7 @@ int imb_is_a_quicktime(char *name)
return 0;
}
- sprintf(theFullPath, "%s", name);
+ strcpy(theFullPath, name);
#ifdef __APPLE__
err = FSPathMakeRef(theFullPath, &myRef, 0);
err = FSGetCatalogInfo(&myRef, kFSCatInfoNone, NULL, NULL, &theFSSpec, NULL);
diff --git a/source/blender/render/CMakeLists.txt b/source/blender/render/CMakeLists.txt
index 12d36ccfdd2..f284f80df96 100644
--- a/source/blender/render/CMakeLists.txt
+++ b/source/blender/render/CMakeLists.txt
@@ -165,6 +165,10 @@ if(WITH_GAMEENGINE)
add_definitions(-DWITH_GAMEENGINE)
endif()
+if(WITH_INTERNATIONAL)
+ add_definitions(-DWITH_INTERNATIONAL)
+endif()
+
if(APPLE)
# SSE math is enabled by default on x86_64
if(CMAKE_OSX_ARCHITECTURES MATCHES "i386")
diff --git a/source/blender/render/SConscript b/source/blender/render/SConscript
index c4309577ae9..9606c2c0f9c 100644
--- a/source/blender/render/SConscript
+++ b/source/blender/render/SConscript
@@ -90,6 +90,9 @@ if env['WITH_BF_FREESTYLE']:
if env['WITH_BF_GAMEENGINE']:
defs.append('WITH_GAMEENGINE')
+if env['WITH_BF_INTERNATIONAL']:
+ defs.append('WITH_INTERNATIONAL')
+
if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'linuxcross', 'win64-vc', 'win64-mingw'):
incs += ' ' + env['BF_PTHREADS_INC']
diff --git a/source/blender/render/extern/include/RE_engine.h b/source/blender/render/extern/include/RE_engine.h
index b687acae1f7..5df860750fc 100644
--- a/source/blender/render/extern/include/RE_engine.h
+++ b/source/blender/render/extern/include/RE_engine.h
@@ -33,12 +33,14 @@
#define __RE_ENGINE_H__
#include "DNA_listBase.h"
+#include "DNA_scene_types.h"
#include "RNA_types.h"
struct bNode;
struct bNodeTree;
struct Object;
struct Render;
+struct RenderData;
struct RenderEngine;
struct RenderEngineType;
struct RenderLayer;
@@ -134,6 +136,7 @@ void RE_engines_exit(void);
RenderEngineType *RE_engines_find(const char *idname);
void RE_engine_get_current_tiles(struct Render *re, int *total_tiles_r, rcti **tiles_r);
+struct RenderData *RE_engine_get_render_data(struct Render *re);
#endif /* __RE_ENGINE_H__ */
diff --git a/source/blender/render/intern/raytrace/rayobject.cpp b/source/blender/render/intern/raytrace/rayobject.cpp
index b31aff82777..9e639501fdd 100644
--- a/source/blender/render/intern/raytrace/rayobject.cpp
+++ b/source/blender/render/intern/raytrace/rayobject.cpp
@@ -87,7 +87,7 @@ MALWAYS_INLINE void rayface_from_vlak(RayFace *rayface, ObjectInstanceRen *obi,
RayObject *RE_rayface_from_vlak(RayFace *rayface, ObjectInstanceRen *obi, VlakRen *vlr)
{
- return rayface_from_coords(rayface, obi, vlr, vlr->v1->co, vlr->v2->co, vlr->v3->co, vlr->v4 ? vlr->v4->co : 0);
+ return rayface_from_coords(rayface, obi, vlr, vlr->v1->co, vlr->v2->co, vlr->v3->co, vlr->v4 ? vlr->v4->co : NULL);
}
RayObject *RE_rayface_from_coords(RayFace *rayface, void *ob, void *face, float *v1, float *v2, float *v3, float *v4)
diff --git a/source/blender/render/intern/raytrace/rayobject_rtbuild.cpp b/source/blender/render/intern/raytrace/rayobject_rtbuild.cpp
index 4195b103811..1d67a8c4f44 100644
--- a/source/blender/render/intern/raytrace/rayobject_rtbuild.cpp
+++ b/source/blender/render/intern/raytrace/rayobject_rtbuild.cpp
@@ -50,15 +50,15 @@ static bool selected_node(RTBuilder::Object *node)
static void rtbuild_init(RTBuilder *b)
{
b->split_axis = -1;
- b->primitives.begin = 0;
- b->primitives.end = 0;
+ b->primitives.begin = NULL;
+ b->primitives.end = NULL;
b->primitives.maxsize = 0;
for (int i = 0; i < RTBUILD_MAX_CHILDS; i++)
b->child_offset[i] = 0;
for (int i = 0; i < 3; i++)
- b->sorted_begin[i] = b->sorted_end[i] = 0;
+ b->sorted_begin[i] = b->sorted_end[i] = NULL;
INIT_MINMAX(b->bb, b->bb + 3);
}
@@ -178,8 +178,8 @@ RTBuilder *rtbuild_get_child(RTBuilder *b, int child, RTBuilder *tmp)
tmp->sorted_end[i] = b->sorted_begin[i] + b->child_offset[child + 1];
}
else {
- tmp->sorted_begin[i] = 0;
- tmp->sorted_end[i] = 0;
+ tmp->sorted_begin[i] = NULL;
+ tmp->sorted_end[i] = NULL;
}
return tmp;
diff --git a/source/blender/render/intern/source/bake.c b/source/blender/render/intern/source/bake.c
index 7c5d6038e0a..c20b0c6da16 100644
--- a/source/blender/render/intern/source/bake.c
+++ b/source/blender/render/intern/source/bake.c
@@ -622,7 +622,7 @@ static int get_next_bake_face(BakeShade *bs)
continue;
if (*origindex >= me->totpoly) {
/* Small hack for Array modifier, which gives false
- original indices - z0r */
+ * original indices - z0r */
continue;
}
#if 0
diff --git a/source/blender/render/intern/source/convertblender.c b/source/blender/render/intern/source/convertblender.c
index cbc357b3d60..2ff612e7c0f 100644
--- a/source/blender/render/intern/source/convertblender.c
+++ b/source/blender/render/intern/source/convertblender.c
@@ -46,6 +46,8 @@
# include "BLI_edgehash.h"
#endif
+#include "BLF_translation.h"
+
#include "DNA_armature_types.h"
#include "DNA_camera_types.h"
#include "DNA_material_types.h"
@@ -3554,9 +3556,9 @@ static void init_render_mesh(Render *re, ObjectRen *obr, int timeoffset)
if (need_origindex) {
/* Find original index of mpoly for this tessface. Options:
- - Modified mesh; two-step look up from tessface -> modified mpoly -> original mpoly
- - OR Tesselated mesh; look up from tessface -> mpoly
- - OR Failsafe; tessface == mpoly. Could probably assert(false) in this case? */
+ * - Modified mesh; two-step look up from tessface -> modified mpoly -> original mpoly
+ * - OR Tesselated mesh; look up from tessface -> mpoly
+ * - OR Failsafe; tessface == mpoly. Could probably assert(false) in this case? */
int *origindex;
origindex = RE_vlakren_get_origindex(obr, vlr, 1);
if (index_mf_to_mpoly && index_mp_to_orig)
@@ -5214,7 +5216,7 @@ void RE_Database_FromScene(Render *re, Main *bmain, Scene *scene, unsigned int l
tothalo= re->tothalo;
if (!re->test_break(re->tbh)) {
if (re->wrld.mode & WO_STARS) {
- re->i.infostr= "Creating Starfield";
+ re->i.infostr = IFACE_("Creating Starfield");
re->stats_draw(re->sdh, &re->i);
RE_make_stars(re, NULL, NULL, NULL, NULL);
}
@@ -5223,7 +5225,7 @@ void RE_Database_FromScene(Render *re, Main *bmain, Scene *scene, unsigned int l
init_camera_inside_volumes(re);
- re->i.infostr= "Creating Shadowbuffers";
+ re->i.infostr = IFACE_("Creating Shadowbuffers");
re->stats_draw(re->sdh, &re->i);
/* SHADOW BUFFER */
@@ -5273,7 +5275,7 @@ void RE_Database_FromScene(Render *re, Main *bmain, Scene *scene, unsigned int l
else
re->i.convertdone = TRUE;
- re->i.infostr= NULL;
+ re->i.infostr = NULL;
re->stats_draw(re->sdh, &re->i);
}
@@ -5686,7 +5688,7 @@ void RE_Database_FromScene_Vectors(Render *re, Main *bmain, Scene *sce, unsigned
ListBase strandsurface;
int step;
- re->i.infostr= "Calculating previous frame vectors";
+ re->i.infostr = IFACE_("Calculating previous frame vectors");
re->r.mode |= R_SPEED;
speedvector_project(re, NULL, NULL, NULL); /* initializes projection code */
@@ -5705,7 +5707,7 @@ void RE_Database_FromScene_Vectors(Render *re, Main *bmain, Scene *sce, unsigned
if (!re->test_break(re->tbh)) {
/* creates entire dbase */
- re->i.infostr= "Calculating next frame vectors";
+ re->i.infostr = IFACE_("Calculating next frame vectors");
database_fromscene_vectors(re, sce, lay, +1);
}
@@ -5791,7 +5793,7 @@ void RE_Database_FromScene_Vectors(Render *re, Main *bmain, Scene *sce, unsigned
}
}
- re->i.infostr= NULL;
+ re->i.infostr = NULL;
re->stats_draw(re->sdh, &re->i);
}
diff --git a/source/blender/render/intern/source/envmap.c b/source/blender/render/intern/source/envmap.c
index 9adae6f49ba..c5872c52e0f 100644
--- a/source/blender/render/intern/source/envmap.c
+++ b/source/blender/render/intern/source/envmap.c
@@ -38,6 +38,8 @@
#include "BLI_threads.h"
#include "BLI_utildefines.h"
+#include "BLF_translation.h"
+
#include "IMB_imbuf_types.h"
#include "IMB_imbuf.h" /* for rectcpy */
@@ -512,7 +514,7 @@ void make_envmaps(Render *re)
trace = (re->r.mode & R_RAYTRACE);
re->r.mode &= ~R_RAYTRACE;
- re->i.infostr = "Creating Environment maps";
+ re->i.infostr = IFACE_("Creating Environment maps");
re->stats_draw(re->sdh, &re->i);
/* 5 = hardcoded max recursion level */
diff --git a/source/blender/render/intern/source/external_engine.c b/source/blender/render/intern/source/external_engine.c
index 22a49bcbbc3..4a48b6cc5f4 100644
--- a/source/blender/render/intern/source/external_engine.c
+++ b/source/blender/render/intern/source/external_engine.c
@@ -385,6 +385,11 @@ void RE_engine_get_current_tiles(Render *re, int *total_tiles_r, rcti **tiles_r)
*tiles_r = tiles;
}
+RenderData *RE_engine_get_render_data(Render *re)
+{
+ return &re->r;
+}
+
/* Render */
int RE_engine_render(Render *re, int do_all)
diff --git a/source/blender/render/intern/source/imagetexture.c b/source/blender/render/intern/source/imagetexture.c
index 12286fc9999..756fb098882 100644
--- a/source/blender/render/intern/source/imagetexture.c
+++ b/source/blender/render/intern/source/imagetexture.c
@@ -224,7 +224,7 @@ int imagewrap(Tex *tex, Image *ima, ImBuf *ibuf, const float texvec[3], TexResul
}
/* keep this before interpolation [#29761] */
- if (tex->ima && (tex->ima->flag & IMA_IGNORE_ALPHA) == 0) {
+ if ((tex->imaflag & TEX_USEALPHA) && tex->ima && (tex->ima->flag & IMA_IGNORE_ALPHA) == 0) {
if ((tex->imaflag & TEX_CALCALPHA) == 0) {
texres->talpha = TRUE;
}
@@ -274,14 +274,18 @@ int imagewrap(Tex *tex, Image *ima, ImBuf *ibuf, const float texvec[3], TexResul
ibuf_get_color(col, ibuf, x+1, y);
val2= (col[0]+col[1]+col[2]);
}
- else val2= val1;
+ else {
+ val2= val1;
+ }
if (y<ibuf->y-1) {
float col[4];
ibuf_get_color(col, ibuf, x, y+1);
- val3= (col[0]+col[1]+col[2]);
+ val3 = (col[0]+col[1]+col[2]);
+ }
+ else {
+ val3 = val1;
}
- else val3= val1;
/* do not mix up x and y here! */
texres->nor[0]= (val1-val2);
@@ -289,13 +293,19 @@ int imagewrap(Tex *tex, Image *ima, ImBuf *ibuf, const float texvec[3], TexResul
}
}
- if (texres->talpha) texres->tin= texres->ta;
+ if (texres->talpha) {
+ texres->tin = texres->ta;
+ }
else if (tex->imaflag & TEX_CALCALPHA) {
texres->ta = texres->tin = max_fff(texres->tr, texres->tg, texres->tb);
}
- else texres->ta= texres->tin= 1.0;
+ else {
+ texres->ta = texres->tin = 1.0;
+ }
- if (tex->flag & TEX_NEGALPHA) texres->ta= 1.0f-texres->ta;
+ if (tex->flag & TEX_NEGALPHA) {
+ texres->ta = 1.0f - texres->ta;
+ }
/* de-premul, this is being premulled in shade_input_do_shade() */
if (texres->ta!=1.0f && texres->ta>1e-4f) {
@@ -829,7 +839,7 @@ static float EWA_WTS[EWA_MAXIDX + 1] = {
#endif
//static int ISNAN(float x) { return (x != x); }
-static void radangle2imp(float a2, float b2, float th, float* A, float* B, float* C, float* F)
+static void radangle2imp(float a2, float b2, float th, float *A, float *B, float *C, float *F)
{
float ct2 = cosf(th);
const float st2 = 1.0f - ct2 * ct2; /* <- sin(th)^2 */
@@ -841,7 +851,7 @@ static void radangle2imp(float a2, float b2, float th, float* A, float* B, float
}
/* all tests here are done to make sure possible overflows are hopefully minimized */
-static void imp2radangle(float A, float B, float C, float F, float* a, float* b, float* th, float* ecc)
+static void imp2radangle(float A, float B, float C, float F, float *a, float *b, float *th, float *ecc)
{
if (F <= 1e-5f) { /* use arbitrary major radius, zero minor, infinite eccentricity */
*a = sqrtf(A > C ? A : C);
@@ -1098,7 +1108,7 @@ static int imagewraposa_aniso(Tex *tex, Image *ima, ImBuf *ibuf, const float tex
/* mipmap test */
image_mipmap_test(tex, ibuf);
- if (tex->ima && (tex->ima->flag & IMA_IGNORE_ALPHA) == 0) {
+ if ((tex->imaflag & TEX_USEALPHA) && tex->ima && (tex->ima->flag & IMA_IGNORE_ALPHA) == 0) {
if ((tex->imaflag & TEX_CALCALPHA) == 0)
texres->talpha = 1;
}
@@ -1514,7 +1524,7 @@ int imagewraposa(Tex *tex, Image *ima, ImBuf *ibuf, const float texvec[3], const
/* mipmap test */
image_mipmap_test(tex, ibuf);
- if (tex->ima && (tex->ima->flag & IMA_IGNORE_ALPHA) == 0) {
+ if ((tex->imaflag & TEX_USEALPHA) && tex->ima && (tex->ima->flag & IMA_IGNORE_ALPHA) == 0) {
if ((tex->imaflag & TEX_CALCALPHA) == 0) {
texres->talpha = TRUE;
}
@@ -1838,7 +1848,9 @@ int imagewraposa(Tex *tex, Image *ima, ImBuf *ibuf, const float texvec[3], const
if (tex->imaflag & TEX_CALCALPHA) {
texres->ta = texres->tin = texres->ta * max_fff(texres->tr, texres->tg, texres->tb);
}
- else texres->tin= texres->ta;
+ else {
+ texres->tin = texres->ta;
+ }
if (tex->flag & TEX_NEGALPHA) texres->ta= 1.0f-texres->ta;
diff --git a/source/blender/render/intern/source/occlusion.c b/source/blender/render/intern/source/occlusion.c
index 1c594ef7db2..50f9d6caff6 100644
--- a/source/blender/render/intern/source/occlusion.c
+++ b/source/blender/render/intern/source/occlusion.c
@@ -44,6 +44,8 @@
#include "BLI_threads.h"
#include "BLI_utildefines.h"
+#include "BLF_translation.h"
+
#include "BKE_global.h"
#include "BKE_scene.h"
@@ -1257,7 +1259,7 @@ void make_occ_tree(Render *re)
/* ugly, needed for occ_face */
R = *re;
- re->i.infostr = "Occlusion preprocessing";
+ re->i.infostr = IFACE_("Occlusion preprocessing");
re->stats_draw(re->sdh, &re->i);
re->occlusiontree = tree = occ_tree_build(re);
diff --git a/source/blender/render/intern/source/pipeline.c b/source/blender/render/intern/source/pipeline.c
index ce18723b8c0..753eab4c6ab 100644
--- a/source/blender/render/intern/source/pipeline.c
+++ b/source/blender/render/intern/source/pipeline.c
@@ -55,6 +55,8 @@
#include "BLI_rand.h"
#include "BLI_callbacks.h"
+#include "BLF_translation.h"
+
#include "BKE_animsys.h" /* <------ should this be here?, needed for sequencer update */
#include "BKE_camera.h"
#include "BKE_global.h"
@@ -160,22 +162,23 @@ static void stats_background(void *UNUSED(arg), RenderStats *rs)
mmap_used_memory = (mmap_in_use) / (1024.0 * 1024.0);
megs_peak_memory = (peak_memory) / (1024.0 * 1024.0);
- fprintf(stdout, "Fra:%d Mem:%.2fM (%.2fM, peak %.2fM) ", rs->cfra,
+ fprintf(stdout, IFACE_("Fra:%d Mem:%.2fM (%.2fM, Peak %.2fM) "), rs->cfra,
megs_used_memory, mmap_used_memory, megs_peak_memory);
if (rs->curfield)
- fprintf(stdout, "Field %d ", rs->curfield);
+ fprintf(stdout, IFACE_("Field %d "), rs->curfield);
if (rs->curblur)
- fprintf(stdout, "Blur %d ", rs->curblur);
+ fprintf(stdout, IFACE_("Blur %d "), rs->curblur);
if (rs->infostr) {
fprintf(stdout, "| %s", rs->infostr);
}
else {
if (rs->tothalo)
- fprintf(stdout, "Sce: %s Ve:%d Fa:%d Ha:%d La:%d", rs->scene_name, rs->totvert, rs->totface, rs->tothalo, rs->totlamp);
+ fprintf(stdout, IFACE_("Sce: %s Ve:%d Fa:%d Ha:%d La:%d"),
+ rs->scene_name, rs->totvert, rs->totface, rs->tothalo, rs->totlamp);
else
- fprintf(stdout, "Sce: %s Ve:%d Fa:%d La:%d", rs->scene_name, rs->totvert, rs->totface, rs->totlamp);
+ fprintf(stdout, IFACE_("Sce: %s Ve:%d Fa:%d La:%d"), rs->scene_name, rs->totvert, rs->totface, rs->totlamp);
}
BLI_callback_exec(G.main, NULL, BLI_CB_EVT_RENDER_STATS);
@@ -458,13 +461,43 @@ void RE_InitState(Render *re, Render *source, RenderData *rd, SceneRenderLayer *
re->i.starttime = PIL_check_seconds_timer();
re->r = *rd; /* hardcopy */
-
+
+ if (source) {
+ /* reuse border flags from source renderer */
+ re->r.mode &= ~(R_BORDER | R_CROP);
+ re->r.mode |= source->r.mode & (R_BORDER | R_CROP);
+
+ /* dimensions shall be shared between all renderers */
+ re->r.xsch = source->r.xsch;
+ re->r.ysch = source->r.ysch;
+ re->r.size = source->r.size;
+ }
+
re->winx = winx;
re->winy = winy;
- if (disprect) {
+ if (source && (source->r.mode & R_BORDER)) {
+ /* eeh, doesn't seem original bordered disprect is storing anywhere
+ * after insertion on black happening in do_render_fields_blur_3d(),
+ * so for now simply re-calculate disprect using border from source
+ * renderer (sergey)
+ */
+
+ re->disprect.xmin = source->r.border.xmin * winx;
+ re->disprect.xmax = source->r.border.xmax * winx;
+
+ re->disprect.ymin = source->r.border.ymin * winy;
+ re->disprect.ymax = source->r.border.ymax * winy;
+
+ re->rectx = BLI_rcti_size_x(&re->disprect);
+ re->recty = BLI_rcti_size_y(&re->disprect);
+
+ /* copy border itself, since it could be used by external engines */
+ re->r.border = source->r.border;
+ }
+ else if (disprect) {
re->disprect = *disprect;
- re->rectx = BLI_rcti_size_x(disprect);
- re->recty = BLI_rcti_size_y(disprect);
+ re->rectx = BLI_rcti_size_x(&re->disprect);
+ re->recty = BLI_rcti_size_y(&re->disprect);
}
else {
re->disprect.xmin = re->disprect.ymin = 0;
@@ -826,7 +859,7 @@ static void print_part_stats(Render *re, RenderPart *pa)
{
char str[64];
- BLI_snprintf(str, sizeof(str), "%s, Part %d-%d", re->scene->id.name + 2, pa->nr, re->i.totpart);
+ BLI_snprintf(str, sizeof(str), IFACE_("%s, Part %d-%d"), re->scene->id.name + 2, pa->nr, re->i.totpart);
re->i.infostr = str;
re->stats_draw(re->sdh, &re->i);
re->i.infostr = NULL;
@@ -972,7 +1005,20 @@ static void threaded_tile_processor(Render *re)
if ((g_break=re->test_break(re->tbh)))
break;
}
-
+
+ if (g_break) {
+ /* review the done queue and handle all the render parts,
+ * so no unfreed render result are lurking around
+ */
+ BLI_thread_queue_nowait(donequeue);
+ while ((pa = BLI_thread_queue_pop(donequeue))) {
+ if (pa->result) {
+ render_result_free_list(&pa->fullresult, pa->result);
+ pa->result = NULL;
+ }
+ }
+ }
+
BLI_thread_queue_free(donequeue);
BLI_thread_queue_free(workqueue);
@@ -2091,7 +2137,7 @@ int RE_is_rendering_allowed(Scene *scene, Object *camera_override, ReportList *r
render_result_exr_file_path(scene, "", 0, str);
- if (BLI_file_is_writable(str) == 0) {
+ if (!BLI_file_is_writable(str)) {
BKE_report(reports, RPT_ERROR, "Cannot save render buffers, check the temp default path");
return 0;
}
@@ -2532,7 +2578,7 @@ void RE_BlenderAnim(Render *re, Main *bmain, Scene *scene, Object *camera_overri
/* remove touched file */
if (BKE_imtype_is_movie(scene->r.im_format.imtype) == 0) {
if (scene->r.mode & R_TOUCH && BLI_exists(name) && BLI_file_size(name) == 0) {
- BLI_delete(name, 0, 0);
+ BLI_delete(name, false, false);
}
}
diff --git a/source/blender/render/intern/source/pointdensity.c b/source/blender/render/intern/source/pointdensity.c
index 3ca4015ff7b..d740780ec30 100644
--- a/source/blender/render/intern/source/pointdensity.c
+++ b/source/blender/render/intern/source/pointdensity.c
@@ -40,6 +40,8 @@
#include "BLI_kdopbvh.h"
#include "BLI_utildefines.h"
+#include "BLF_translation.h"
+
#include "BKE_DerivedMesh.h"
#include "BKE_global.h"
#include "BKE_lattice.h"
@@ -299,7 +301,7 @@ void make_pointdensities(Render *re)
if (re->scene->r.scemode & R_PREVIEWBUTS)
return;
- re->i.infostr= "Caching Point Densities";
+ re->i.infostr = IFACE_("Caching Point Densities");
re->stats_draw(re->sdh, &re->i);
for (tex= re->main->tex.first; tex; tex= tex->id.next) {
@@ -308,7 +310,7 @@ void make_pointdensities(Render *re)
}
}
- re->i.infostr= NULL;
+ re->i.infostr = NULL;
re->stats_draw(re->sdh, &re->i);
}
diff --git a/source/blender/render/intern/source/rayshade.c b/source/blender/render/intern/source/rayshade.c
index fe23f31c6d7..88c0719fa59 100644
--- a/source/blender/render/intern/source/rayshade.c
+++ b/source/blender/render/intern/source/rayshade.c
@@ -47,6 +47,8 @@
#include "BLI_rand.h"
#include "BLI_utildefines.h"
+#include "BLF_translation.h"
+
#include "BKE_global.h"
#include "BKE_node.h"
@@ -400,7 +402,7 @@ static void makeraytree_single(Render *re)
}
if (!test_break(re)) {
- re->i.infostr= "Raytree.. building";
+ re->i.infostr = IFACE_("Raytree.. building");
re->stats_draw(re->sdh, &re->i);
RE_rayobject_done(raytree);
@@ -412,7 +414,7 @@ void makeraytree(Render *re)
float min[3], max[3], sub[3];
int i;
- re->i.infostr= "Raytree.. preparing";
+ re->i.infostr = IFACE_("Raytree.. preparing");
re->stats_draw(re->sdh, &re->i);
/* disable options not yet supported by octree,
@@ -425,7 +427,7 @@ void makeraytree(Render *re)
if (test_break(re)) {
freeraytree(re);
- re->i.infostr= "Raytree building canceled";
+ re->i.infostr = IFACE_("Raytree building canceled");
re->stats_draw(re->sdh, &re->i);
}
else {
@@ -446,7 +448,7 @@ void makeraytree(Render *re)
re->maxdist = len_v3(sub);
- re->i.infostr= "Raytree finished";
+ re->i.infostr = IFACE_("Raytree finished");
re->stats_draw(re->sdh, &re->i);
}
diff --git a/source/blender/render/intern/source/render_result.c b/source/blender/render/intern/source/render_result.c
index be1a3806e43..21e7b698610 100644
--- a/source/blender/render/intern/source/render_result.c
+++ b/source/blender/render/intern/source/render_result.c
@@ -35,13 +35,13 @@
#include "MEM_guardedalloc.h"
+#include "BLI_utildefines.h"
#include "BLI_fileops.h"
#include "BLI_listbase.h"
#include "BLI_path_util.h"
#include "BLI_rect.h"
#include "BLI_string.h"
#include "BLI_threads.h"
-#include "BLI_utildefines.h"
#include "BKE_image.h"
#include "BKE_global.h"
@@ -990,11 +990,9 @@ void render_result_exr_file_merge(RenderResult *rr, RenderResult *rrpart)
/* path to temporary exr file */
void render_result_exr_file_path(Scene *scene, const char *layname, int sample, char *filepath)
{
- char di[FILE_MAX], name[FILE_MAXFILE + MAX_ID_NAME + MAX_ID_NAME + 100], fi[FILE_MAXFILE];
-
- BLI_strncpy(di, G.main->name, FILE_MAX);
- BLI_splitdirstring(di, fi);
+ char name[FILE_MAXFILE + MAX_ID_NAME + MAX_ID_NAME + 100], fi[FILE_MAXFILE];
+ BLI_split_file_part(G.main->name, fi, sizeof(fi));
if (sample == 0)
BLI_snprintf(name, sizeof(name), "%s_%s_%s.exr", fi, scene->id.name + 2, layname);
else
diff --git a/source/blender/render/intern/source/sss.c b/source/blender/render/intern/source/sss.c
index 6d0e15ea46e..9d6391ccb59 100644
--- a/source/blender/render/intern/source/sss.c
+++ b/source/blender/render/intern/source/sss.c
@@ -55,6 +55,8 @@
#include "BLI_ghash.h"
#include "BLI_memarena.h"
+#include "BLF_translation.h"
+
#include "PIL_time.h"
#include "DNA_material_types.h"
@@ -994,7 +996,7 @@ void make_sss_tree(Render *re)
re->sss_hash= BLI_ghash_ptr_new("make_sss_tree gh");
- re->i.infostr= "SSS preprocessing";
+ re->i.infostr = IFACE_("SSS preprocessing");
re->stats_draw(re->sdh, &re->i);
for (mat= re->main->mat.first; mat; mat= mat->id.next)
@@ -1016,7 +1018,7 @@ void free_sss(Render *re)
if (re->sss_hash) {
GHashIterator *it= BLI_ghashIterator_new(re->sss_hash);
- while (!BLI_ghashIterator_isDone(it)) {
+ while (BLI_ghashIterator_notDone(it)) {
sss_free_tree(BLI_ghashIterator_getValue(it));
BLI_ghashIterator_step(it);
}
diff --git a/source/blender/render/intern/source/volume_precache.c b/source/blender/render/intern/source/volume_precache.c
index a9db197ed48..028217b8609 100644
--- a/source/blender/render/intern/source/volume_precache.c
+++ b/source/blender/render/intern/source/volume_precache.c
@@ -43,6 +43,8 @@
#include "BLI_voxel.h"
#include "BLI_utildefines.h"
+#include "BLF_translation.h"
+
#include "PIL_time.h"
#include "RE_shader_ext.h"
@@ -400,10 +402,11 @@ static void multiple_scattering_diffusion(Render *re, VolumePrecache *vp, Materi
/* Displays progress every second */
if (time-lasttime>1.0) {
char str[64];
- BLI_snprintf(str, sizeof(str), "Simulating multiple scattering: %d%%", (int)(100.0f * (c / total)));
- re->i.infostr= str;
+ BLI_snprintf(str, sizeof(str), IFACE_("Simulating multiple scattering: %d%%"),
+ (int)(100.0f * (c / total)));
+ re->i.infostr = str;
re->stats_draw(re->sdh, &re->i);
- re->i.infostr= NULL;
+ re->i.infostr = NULL;
lasttime= time;
}
}
@@ -742,11 +745,12 @@ static void vol_precache_objectinstance_threads(Render *re, ObjectInstanceRen *o
time= PIL_check_seconds_timer();
if (time-lasttime>1.0) {
char str[64];
- BLI_snprintf(str, sizeof(str), "Precaching volume: %d%%", (int)(100.0f * ((float)counter / (float)totparts)));
- re->i.infostr= str;
+ BLI_snprintf(str, sizeof(str), IFACE_("Precaching volume: %d%%"),
+ (int)(100.0f * ((float)counter / (float)totparts)));
+ re->i.infostr = str;
re->stats_draw(re->sdh, &re->i);
- re->i.infostr= NULL;
- lasttime= time;
+ re->i.infostr = NULL;
+ lasttime = time;
}
}
@@ -784,7 +788,7 @@ void volume_precache(Render *re)
ObjectInstanceRen *obi;
VolumeOb *vo;
- re->i.infostr= "Volume preprocessing";
+ re->i.infostr = IFACE_("Volume preprocessing");
re->stats_draw(re->sdh, &re->i);
for (vo= re->volumes.first; vo; vo= vo->next) {
@@ -803,7 +807,7 @@ void volume_precache(Render *re)
}
}
- re->i.infostr= NULL;
+ re->i.infostr = NULL;
re->stats_draw(re->sdh, &re->i);
}
diff --git a/source/blender/render/intern/source/voxeldata.c b/source/blender/render/intern/source/voxeldata.c
index 92099060bf5..9990ad7e900 100644
--- a/source/blender/render/intern/source/voxeldata.c
+++ b/source/blender/render/intern/source/voxeldata.c
@@ -34,6 +34,10 @@
#include <stdlib.h>
#include <stdio.h>
+#ifdef WIN32
+#include "BLI_winstuff.h"
+#endif
+
#include "MEM_guardedalloc.h"
#include "BLI_math.h"
@@ -41,6 +45,8 @@
#include "BLI_voxel.h"
#include "BLI_utildefines.h"
+#include "BLF_translation.h"
+
#include "IMB_imbuf.h"
#include "IMB_imbuf_types.h"
@@ -400,7 +406,7 @@ void make_voxeldata(struct Render *re)
{
Tex *tex;
- re->i.infostr = "Loading voxel datasets";
+ re->i.infostr = IFACE_("Loading voxel datasets");
re->stats_draw(re->sdh, &re->i);
/* XXX: should be doing only textures used in this render */
diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h
index 57fe518dd46..4cac73b4cf6 100644
--- a/source/blender/windowmanager/WM_api.h
+++ b/source/blender/windowmanager/WM_api.h
@@ -165,7 +165,7 @@ struct wmEventHandler *WM_event_add_dropbox_handler(ListBase *handlers, ListBase
/* mouse */
void WM_event_add_mousemove(struct bContext *C);
void WM_event_add_mousemove_window(struct wmWindow *window);
-int WM_modal_tweak_exit(struct wmEvent *evt, int tweak_event);
+int WM_modal_tweak_exit(const struct wmEvent *event, int tweak_event);
/* notifiers */
void WM_event_add_notifier(const struct bContext *C, unsigned int type, void *reference);
@@ -180,19 +180,19 @@ void WM_event_timer_sleep(struct wmWindowManager *wm, struct wmWindow *win, str
/* operator api, default callbacks */
/* invoke callback, uses enum property named "type" */
-int WM_operator_view3d_distance_invoke(struct bContext *C, struct wmOperator *op, struct wmEvent *event);
-int WM_menu_invoke (struct bContext *C, struct wmOperator *op, struct wmEvent *event);
-int WM_enum_search_invoke(struct bContext *C, struct wmOperator *op, struct wmEvent *event);
+int WM_operator_view3d_distance_invoke(struct bContext *C, struct wmOperator *op, const struct wmEvent *event);
+int WM_menu_invoke (struct bContext *C, struct wmOperator *op, const struct wmEvent *event);
+int WM_enum_search_invoke(struct bContext *C, struct wmOperator *op, const struct wmEvent *event);
/* invoke callback, confirm menu + exec */
-int WM_operator_confirm (struct bContext *C, struct wmOperator *op, struct wmEvent *event);
+int WM_operator_confirm (struct bContext *C, struct wmOperator *op, const struct wmEvent *event);
/* invoke callback, file selector "filepath" unset + exec */
-int WM_operator_filesel (struct bContext *C, struct wmOperator *op, struct wmEvent *event);
+int WM_operator_filesel (struct bContext *C, struct wmOperator *op, const struct wmEvent *event);
int WM_operator_filesel_ensure_ext_imtype(wmOperator *op, const struct ImageFormatData *im_format);
/* poll callback, context checks */
int WM_operator_winactive (struct bContext *C);
/* invoke callback, exec + redo popup */
-int WM_operator_props_popup_call(struct bContext *C, struct wmOperator *op, struct wmEvent *event);
-int WM_operator_props_popup (struct bContext *C, struct wmOperator *op, struct wmEvent *event);
+int WM_operator_props_popup_call(struct bContext *C, struct wmOperator *op, const struct wmEvent *event);
+int WM_operator_props_popup (struct bContext *C, struct wmOperator *op, const struct wmEvent *event);
int WM_operator_props_dialog_popup (struct bContext *C, struct wmOperator *op, int width, int height);
int WM_operator_redo_popup (struct bContext *C, struct wmOperator *op);
int WM_operator_ui_popup (struct bContext *C, struct wmOperator *op, int width, int height);
@@ -282,31 +282,31 @@ void WM_menutype_freelink(struct MenuType *mt);
void WM_menutype_free(void);
/* default operator callbacks for border/circle/lasso */
-int WM_border_select_invoke (struct bContext *C, struct wmOperator *op, struct wmEvent *event);
-int WM_border_select_modal (struct bContext *C, struct wmOperator *op, struct wmEvent *event);
+int WM_border_select_invoke (struct bContext *C, struct wmOperator *op, const struct wmEvent *event);
+int WM_border_select_modal (struct bContext *C, struct wmOperator *op, const struct wmEvent *event);
int WM_border_select_cancel(struct bContext *C, struct wmOperator *op);
-int WM_gesture_circle_invoke(struct bContext *C, struct wmOperator *op, struct wmEvent *event);
-int WM_gesture_circle_modal(struct bContext *C, struct wmOperator *op, struct wmEvent *event);
+int WM_gesture_circle_invoke(struct bContext *C, struct wmOperator *op, const struct wmEvent *event);
+int WM_gesture_circle_modal(struct bContext *C, struct wmOperator *op, const struct wmEvent *event);
int WM_gesture_circle_cancel(struct bContext *C, struct wmOperator *op);
-int WM_gesture_lines_invoke(struct bContext *C, struct wmOperator *op, struct wmEvent *event);
-int WM_gesture_lines_modal(struct bContext *C, struct wmOperator *op, struct wmEvent *event);
+int WM_gesture_lines_invoke(struct bContext *C, struct wmOperator *op, const struct wmEvent *event);
+int WM_gesture_lines_modal(struct bContext *C, struct wmOperator *op, const struct wmEvent *event);
int WM_gesture_lines_cancel(struct bContext *C, struct wmOperator *op);
-int WM_gesture_lasso_invoke(struct bContext *C, struct wmOperator *op, struct wmEvent *event);
-int WM_gesture_lasso_modal(struct bContext *C, struct wmOperator *op, struct wmEvent *event);
+int WM_gesture_lasso_invoke(struct bContext *C, struct wmOperator *op, const struct wmEvent *event);
+int WM_gesture_lasso_modal(struct bContext *C, struct wmOperator *op, const struct wmEvent *event);
int WM_gesture_lasso_cancel(struct bContext *C, struct wmOperator *op);
const int (*WM_gesture_lasso_path_to_array(struct bContext *C, struct wmOperator *op, int *mcords_tot))[2];
-int WM_gesture_straightline_invoke(struct bContext *C, struct wmOperator *op, struct wmEvent *event);
-int WM_gesture_straightline_modal(struct bContext *C, struct wmOperator *op, struct wmEvent *event);
+int WM_gesture_straightline_invoke(struct bContext *C, struct wmOperator *op, const struct wmEvent *event);
+int WM_gesture_straightline_modal(struct bContext *C, struct wmOperator *op, const struct wmEvent *event);
int WM_gesture_straightline_cancel(struct bContext *C, struct wmOperator *op);
/* Gesture manager API */
-struct wmGesture *WM_gesture_new(struct bContext *C, struct wmEvent *event, int type);
+struct wmGesture *WM_gesture_new(struct bContext *C, const struct wmEvent *event, int type);
void WM_gesture_end(struct bContext *C, struct wmGesture *gesture);
void WM_gestures_remove(struct bContext *C);
/* fileselecting support */
void WM_event_add_fileselect(struct bContext *C, struct wmOperator *op);
-void WM_event_fileselect_event(struct bContext *C, void *ophandle, int eventval);
+void WM_event_fileselect_event(struct wmWindowManager *wm, void *ophandle, int eventval);
#ifndef NDEBUG
void WM_event_print(const struct wmEvent *event);
#endif
@@ -317,7 +317,7 @@ void WM_operator_region_active_win_set(struct bContext *C);
struct wmDrag *WM_event_start_drag(struct bContext *C, int icon, int type, void *poin, double value);
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),
+struct wmDropBox *WM_dropbox_add(ListBase *lb, const char *idname, int (*poll)(struct bContext *, struct wmDrag *, const struct wmEvent *event),
void (*copy)(struct wmDrag *, struct wmDropBox *));
ListBase *WM_dropboxmap_find(const char *idname, int spaceid, int regionid);
diff --git a/source/blender/windowmanager/WM_types.h b/source/blender/windowmanager/WM_types.h
index 881d4464ed6..a42e4438311 100644
--- a/source/blender/windowmanager/WM_types.h
+++ b/source/blender/windowmanager/WM_types.h
@@ -515,6 +515,7 @@ typedef struct wmTimer {
typedef struct wmOperatorType {
const char *name; /* text for ui, undo */
const char *idname; /* unique identifier */
+ const char *translation_context;
const char *description; /* tooltips and python docs */
/* this callback executes the operator without any interactive input,
@@ -537,13 +538,13 @@ typedef struct wmOperatorType {
* any further events are handled in modal. if the operation is
* canceled due to some external reason, cancel is called
* - see defines below for return values */
- int (*invoke)(struct bContext *, struct wmOperator *, struct wmEvent *)
+ int (*invoke)(struct bContext *, struct wmOperator *, const struct wmEvent *)
#ifdef __GNUC__
__attribute__((warn_unused_result))
#endif
;
int (*cancel)(struct bContext *, struct wmOperator *);
- int (*modal)(struct bContext *, struct wmOperator *, struct wmEvent *)
+ int (*modal)(struct bContext *, struct wmOperator *, const struct wmEvent *)
#ifdef __GNUC__
__attribute__((warn_unused_result))
#endif
@@ -648,7 +649,7 @@ typedef struct wmDropBox {
struct wmDropBox *next, *prev;
/* test if the dropbox is active, then can print optype name */
- int (*poll)(struct bContext *, struct wmDrag *, wmEvent *);
+ int (*poll)(struct bContext *, struct wmDrag *, const wmEvent *);
/* before exec, this copies drag info to wmDrop properties */
void (*copy)(struct wmDrag *, struct wmDropBox *);
diff --git a/source/blender/windowmanager/intern/wm.c b/source/blender/windowmanager/intern/wm.c
index a01f7301ec2..29e0fcf302f 100644
--- a/source/blender/windowmanager/intern/wm.c
+++ b/source/blender/windowmanager/intern/wm.c
@@ -218,7 +218,7 @@ void WM_uilisttype_free(void)
{
GHashIterator *iter = BLI_ghashIterator_new(uilisttypes_hash);
- for (; !BLI_ghashIterator_isDone(iter); BLI_ghashIterator_step(iter)) {
+ for (; BLI_ghashIterator_notDone(iter); BLI_ghashIterator_step(iter)) {
uiListType *ult = BLI_ghashIterator_getValue(iter);
if (ult->ext.free) {
ult->ext.free(ult->ext.data);
@@ -271,7 +271,7 @@ void WM_menutype_free(void)
{
GHashIterator *iter = BLI_ghashIterator_new(menutypes_hash);
- for (; !BLI_ghashIterator_isDone(iter); BLI_ghashIterator_step(iter)) {
+ for (; BLI_ghashIterator_notDone(iter); BLI_ghashIterator_step(iter)) {
MenuType *mt = BLI_ghashIterator_getValue(iter);
if (mt->ext.free) {
mt->ext.free(mt->ext.data);
diff --git a/source/blender/windowmanager/intern/wm_dragdrop.c b/source/blender/windowmanager/intern/wm_dragdrop.c
index 0581000e07c..ed066117b28 100644
--- a/source/blender/windowmanager/intern/wm_dragdrop.c
+++ b/source/blender/windowmanager/intern/wm_dragdrop.c
@@ -103,7 +103,7 @@ ListBase *WM_dropboxmap_find(const char *idname, int spaceid, int regionid)
-wmDropBox *WM_dropbox_add(ListBase *lb, const char *idname, int (*poll)(bContext *, wmDrag *, wmEvent *),
+wmDropBox *WM_dropbox_add(ListBase *lb, const char *idname, int (*poll)(bContext *, wmDrag *, const wmEvent *),
void (*copy)(wmDrag *, wmDropBox *))
{
wmDropBox *drop = MEM_callocN(sizeof(wmDropBox), "wmDropBox");
@@ -323,7 +323,7 @@ void wm_drags_draw(bContext *C, wmWindow *win, rcti *rect)
drag_rect_minmax(rect, x, y, x + drag->sx, y + drag->sy);
else {
glColor4f(1.0, 1.0, 1.0, 0.65); /* this blends texture */
- glaDrawPixelsTexScaled(x, y, drag->imb->x, drag->imb->y, GL_UNSIGNED_BYTE, drag->imb->rect, drag->scale, drag->scale);
+ glaDrawPixelsTexScaled(x, y, drag->imb->x, drag->imb->y, GL_UNSIGNED_BYTE, GL_NEAREST, drag->imb->rect, drag->scale, drag->scale);
}
}
else {
diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c
index 4e181ec930b..b2647626f3a 100644
--- a/source/blender/windowmanager/intern/wm_event_system.c
+++ b/source/blender/windowmanager/intern/wm_event_system.c
@@ -2244,12 +2244,12 @@ void wm_event_do_handlers(bContext *C)
/* ********** filesector handling ************ */
-void WM_event_fileselect_event(bContext *C, void *ophandle, int eventval)
+void WM_event_fileselect_event(wmWindowManager *wm, void *ophandle, int eventval)
{
/* add to all windows! */
wmWindow *win;
- for (win = CTX_wm_manager(C)->windows.first; win; win = win->next) {
+ for (win = wm->windows.first; win; win = win->next) {
wmEvent event = *win->eventstate;
event.type = EVT_FILESELECT;
@@ -2271,6 +2271,7 @@ void WM_event_fileselect_event(bContext *C, void *ophandle, int eventval)
void WM_event_add_fileselect(bContext *C, wmOperator *op)
{
wmEventHandler *handler, *handlernext;
+ wmWindowManager *wm = CTX_wm_manager(C);
wmWindow *win = CTX_wm_window(C);
int full = 1; // XXX preset?
@@ -2302,7 +2303,7 @@ void WM_event_add_fileselect(bContext *C, wmOperator *op)
op->type->check(C, op); /* ignore return value */
}
- WM_event_fileselect_event(C, op, full ? EVT_FILESELECT_FULL_OPEN : EVT_FILESELECT_OPEN);
+ WM_event_fileselect_event(wm, op, full ? EVT_FILESELECT_FULL_OPEN : EVT_FILESELECT_OPEN);
}
#if 0
@@ -2487,14 +2488,14 @@ void WM_event_add_mousemove_window(wmWindow *window)
}
/* for modal callbacks, check configuration for how to interpret exit with tweaks */
-int WM_modal_tweak_exit(wmEvent *evt, int tweak_event)
+int WM_modal_tweak_exit(const wmEvent *event, int tweak_event)
{
/* if the release-confirm userpref setting is enabled,
* tweak events can be canceled when mouse is released
*/
if (U.flag & USER_RELEASECONFIRM) {
/* option on, so can exit with km-release */
- if (evt->val == KM_RELEASE) {
+ if (event->val == KM_RELEASE) {
switch (tweak_event) {
case EVT_TWEAK_L:
case EVT_TWEAK_M:
@@ -2515,7 +2516,7 @@ int WM_modal_tweak_exit(wmEvent *evt, int tweak_event)
* some items (i.e. markers) being tweaked may end up getting
* dropped all over
*/
- if (evt->val != KM_RELEASE)
+ if (event->val != KM_RELEASE)
return 1;
}
@@ -2745,9 +2746,9 @@ static void attach_ndof_data(wmEvent *event, const GHOST_TEventNDOFMotionData *g
}
/* imperfect but probably usable... draw/enable drags to other windows */
-static wmWindow *wm_event_cursor_other_windows(wmWindowManager *wm, wmWindow *win, wmEvent *evt)
+static wmWindow *wm_event_cursor_other_windows(wmWindowManager *wm, wmWindow *win, wmEvent *event)
{
- int mx = evt->x, my = evt->y;
+ int mx = event->x, my = event->y;
if (wm->windows.first == wm->windows.last)
return NULL;
@@ -2779,8 +2780,8 @@ static wmWindow *wm_event_cursor_other_windows(wmWindowManager *wm, wmWindow *wi
if (mx - posx >= 0 && owin->posy >= 0 &&
mx - posx <= WM_window_pixels_x(owin) && my - posy <= WM_window_pixels_y(owin))
{
- evt->x = mx - (int)(U.pixelsize * owin->posx);
- evt->y = my - (int)(U.pixelsize * owin->posy);
+ event->x = mx - (int)(U.pixelsize * owin->posx);
+ event->y = my - (int)(U.pixelsize * owin->posy);
return owin;
}
diff --git a/source/blender/windowmanager/intern/wm_files.c b/source/blender/windowmanager/intern/wm_files.c
index d1156f77e41..c682165eb69 100644
--- a/source/blender/windowmanager/intern/wm_files.c
+++ b/source/blender/windowmanager/intern/wm_files.c
@@ -509,7 +509,7 @@ int wm_homefile_read(bContext *C, ReportList *UNUSED(reports), short from_memory
G.relbase_valid = 0;
if (!from_memory) {
- char *cfgdir = BLI_get_folder(BLENDER_USER_CONFIG, NULL);
+ const char * const cfgdir = BLI_get_folder(BLENDER_USER_CONFIG, NULL);
if (cfgdir) {
BLI_make_file_string(G.main->name, startstr, cfgdir, BLENDER_STARTUP_FILE);
BLI_make_file_string(G.main->name, prefstr, cfgdir, BLENDER_USERPREF_FILE);
@@ -533,7 +533,8 @@ int wm_homefile_read(bContext *C, ReportList *UNUSED(reports), short from_memory
}
if (U.themes.first == NULL) {
- printf("\nNote: No (valid) '%s' found, fall back to built-in default.\n\n", startstr);
+ if (G.debug & G_DEBUG)
+ printf("\nNote: No (valid) '%s' found, fall back to built-in default.\n\n", startstr);
success = 0;
}
}
@@ -621,7 +622,7 @@ void wm_read_history(void)
struct RecentFile *recent;
char *line;
int num;
- char *cfgdir = BLI_get_folder(BLENDER_USER_CONFIG, NULL);
+ const char * const cfgdir = BLI_get_folder(BLENDER_USER_CONFIG, NULL);
if (!cfgdir) return;
@@ -650,7 +651,7 @@ static void write_history(void)
{
struct RecentFile *recent, *next_recent;
char name[FILE_MAX];
- char *user_config_dir;
+ const char *user_config_dir;
FILE *fp;
int i;
@@ -1051,7 +1052,7 @@ void wm_autosave_delete(void)
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);
+ if (U.uiflag & USER_GLOBALUNDO) BLI_delete(filename, false, false);
else BLI_rename(filename, str);
}
}
diff --git a/source/blender/windowmanager/intern/wm_gesture.c b/source/blender/windowmanager/intern/wm_gesture.c
index 302bf61756a..adf159bcfee 100644
--- a/source/blender/windowmanager/intern/wm_gesture.c
+++ b/source/blender/windowmanager/intern/wm_gesture.c
@@ -58,7 +58,7 @@
/* context checked on having screen, window and area */
-wmGesture *WM_gesture_new(bContext *C, wmEvent *event, int type)
+wmGesture *WM_gesture_new(bContext *C, const wmEvent *event, int type)
{
wmGesture *gesture = MEM_callocN(sizeof(wmGesture), "new gesture");
wmWindow *window = CTX_wm_window(C);
diff --git a/source/blender/windowmanager/intern/wm_init_exit.c b/source/blender/windowmanager/intern/wm_init_exit.c
index da0c6dd2a63..6e557647d12 100644
--- a/source/blender/windowmanager/intern/wm_init_exit.c
+++ b/source/blender/windowmanager/intern/wm_init_exit.c
@@ -449,6 +449,7 @@ void WM_exit_ext(bContext *C, const short do_python)
#ifdef WITH_INTERNATIONAL
BLF_free_unifont();
+ BLF_free_unifont_mono();
BLF_lang_free();
#endif
diff --git a/source/blender/windowmanager/intern/wm_jobs.c b/source/blender/windowmanager/intern/wm_jobs.c
index 3c3e2c0feaa..c637b77738e 100644
--- a/source/blender/windowmanager/intern/wm_jobs.c
+++ b/source/blender/windowmanager/intern/wm_jobs.c
@@ -363,7 +363,9 @@ void WM_jobs_start(wmWindowManager *wm, wmJob *wm_job)
if (G.debug & G_DEBUG_JOBS)
wm_job->start_time = PIL_check_seconds_timer();
}
- else printf("job fails, not initialized\n");
+ else {
+ printf("job fails, not initialized\n");
+ }
}
}
diff --git a/source/blender/windowmanager/intern/wm_keymap.c b/source/blender/windowmanager/intern/wm_keymap.c
index 92a310ac34e..20e715c18d0 100644
--- a/source/blender/windowmanager/intern/wm_keymap.c
+++ b/source/blender/windowmanager/intern/wm_keymap.c
@@ -836,7 +836,7 @@ int WM_keymap_item_to_string(wmKeyMapItem *kmi, char *str, int len)
}
strcat(buf, WM_key_event_string(kmi->type));
- return BLI_snprintf(str, len, "%s", buf);
+ return BLI_strncpy_rlen(str, buf, len);
}
static wmKeyMapItem *wm_keymap_item_find_handlers(
diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c
index 678c77d0d88..8ea507f97e8 100644
--- a/source/blender/windowmanager/intern/wm_operators.c
+++ b/source/blender/windowmanager/intern/wm_operators.c
@@ -248,7 +248,7 @@ static int wm_macro_exec(bContext *C, wmOperator *op)
return wm_macro_end(op, retval);
}
-static int wm_macro_invoke_internal(bContext *C, wmOperator *op, wmEvent *event, wmOperator *opm)
+static int wm_macro_invoke_internal(bContext *C, wmOperator *op, const wmEvent *event, wmOperator *opm)
{
int retval = OPERATOR_FINISHED;
@@ -275,13 +275,13 @@ static int wm_macro_invoke_internal(bContext *C, wmOperator *op, wmEvent *event,
return wm_macro_end(op, retval);
}
-static int wm_macro_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int wm_macro_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
wm_macro_start(op);
return wm_macro_invoke_internal(C, op, event, op->macro.first);
}
-static int wm_macro_modal(bContext *C, wmOperator *op, wmEvent *event)
+static int wm_macro_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
wmOperator *opm = op->opm;
int retval = OPERATOR_FINISHED;
@@ -381,7 +381,9 @@ wmOperatorType *WM_operatortype_append_macro(const char *idname, const char *nam
RNA_def_struct_ui_text(ot->srna, ot->name, ot->description);
RNA_def_struct_identifier(ot->srna, ot->idname);
- RNA_def_struct_translation_context(ot->srna, BLF_I18NCONTEXT_OPERATOR_DEFAULT);
+ /* Use i18n context from ext.srna if possible (py operators). */
+ RNA_def_struct_translation_context(ot->srna, ot->ext.srna ? RNA_struct_translation_context(ot->ext.srna) :
+ BLF_I18NCONTEXT_OPERATOR_DEFAULT);
BLI_ghash_insert(global_ops_hash, (void *)ot->idname, ot);
@@ -875,7 +877,7 @@ void WM_operator_properties_free(PointerRNA *ptr)
/* ************ default op callbacks, exported *********** */
-int WM_operator_view3d_distance_invoke(struct bContext *C, struct wmOperator *op, struct wmEvent *UNUSED(event))
+int WM_operator_view3d_distance_invoke(struct bContext *C, struct wmOperator *op, const struct wmEvent *UNUSED(event))
{
Scene *scene = CTX_data_scene(C);
View3D *v3d = CTX_wm_view3d(C);
@@ -905,7 +907,7 @@ int WM_operator_view3d_distance_invoke(struct bContext *C, struct wmOperator *op
}
/* invoke callback, uses enum property named "type" */
-int WM_menu_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+int WM_menu_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
PropertyRNA *prop = op->type->prop;
uiPopupMenu *pup;
@@ -1024,7 +1026,7 @@ static uiBlock *wm_enum_search_menu(bContext *C, ARegion *ar, void *arg_op)
}
-int WM_enum_search_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+int WM_enum_search_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
uiPupBlock(C, wm_enum_search_menu, op);
return OPERATOR_CANCELLED;
@@ -1051,13 +1053,13 @@ int WM_operator_confirm_message(bContext *C, wmOperator *op, const char *message
}
-int WM_operator_confirm(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+int WM_operator_confirm(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
return WM_operator_confirm_message(C, op, NULL);
}
/* op->invoke, opens fileselect if path property not set, otherwise executes */
-int WM_operator_filesel(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+int WM_operator_filesel(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
if (RNA_struct_property_is_set(op->ptr, "filepath")) {
return WM_operator_call_notest(C, op); /* call exec direct */
@@ -1475,12 +1477,12 @@ static int wm_operator_props_popup_ex(bContext *C, wmOperator *op, const int do_
* This way - the button values correspond to the result of the operator.
* Without this, first access to a button will make the result jump,
* see [#32452] */
-int WM_operator_props_popup_call(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+int WM_operator_props_popup_call(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
return wm_operator_props_popup_ex(C, op, TRUE);
}
-int WM_operator_props_popup(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+int WM_operator_props_popup(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
return wm_operator_props_popup_ex(C, op, FALSE);
}
@@ -1529,7 +1531,7 @@ static int wm_debug_menu_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int wm_debug_menu_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int wm_debug_menu_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
RNA_int_set(op->ptr, "debug_value", G.debug_value);
return WM_operator_props_dialog_popup(C, op, 9 * UI_UNIT_X, UI_UNIT_Y);
@@ -1598,14 +1600,14 @@ static void wm_block_splash_refreshmenu(bContext *UNUSED(C), void *UNUSED(arg_bl
static int wm_resource_check_prev(void)
{
- char *res = BLI_get_folder_version(BLENDER_RESOURCE_PATH_USER, BLENDER_VERSION, TRUE);
+ const char *res = BLI_get_folder_version(BLENDER_RESOURCE_PATH_USER, BLENDER_VERSION, true);
// if (res) printf("USER: %s\n", res);
#if 0 /* ignore the local folder */
if (res == NULL) {
/* with a local dir, copying old files isn't useful since local dir get priority for config */
- res = BLI_get_folder_version(BLENDER_RESOURCE_PATH_LOCAL, BLENDER_VERSION, TRUE);
+ res = BLI_get_folder_version(BLENDER_RESOURCE_PATH_LOCAL, BLENDER_VERSION, true);
}
#endif
@@ -1614,7 +1616,7 @@ static int wm_resource_check_prev(void)
return FALSE;
}
else {
- return (BLI_get_folder_version(BLENDER_RESOURCE_PATH_USER, BLENDER_VERSION - 1, TRUE) != NULL);
+ return (BLI_get_folder_version(BLENDER_RESOURCE_PATH_USER, BLENDER_VERSION - 1, true) != NULL);
}
}
@@ -1704,7 +1706,7 @@ static uiBlock *wm_block_create_splash(bContext *C, ARegion *ar, void *UNUSED(ar
uiItemStringO(col, IFACE_("Blender Website"), ICON_URL, "WM_OT_url_open", "url", "http://www.blender.org");
uiItemStringO(col, IFACE_("User Community"), ICON_URL, "WM_OT_url_open", "url",
"http://www.blender.org/community/user-community");
- if (strcmp(STRINGIFY(BLENDER_VERSION_CYCLE), "release") == 0) {
+ if (STREQ(STRINGIFY(BLENDER_VERSION_CYCLE), "release")) {
BLI_snprintf(url, sizeof(url), "http://www.blender.org/documentation/blender_python_api_%d_%d"
STRINGIFY(BLENDER_VERSION_CHAR) "_release",
BLENDER_VERSION / 100, BLENDER_VERSION % 100);
@@ -1742,7 +1744,7 @@ static uiBlock *wm_block_create_splash(bContext *C, ARegion *ar, void *UNUSED(ar
return block;
}
-static int wm_splash_invoke(bContext *C, wmOperator *UNUSED(op), wmEvent *UNUSED(event))
+static int wm_splash_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *UNUSED(event))
{
uiPupBlock(C, wm_block_create_splash, NULL);
@@ -1796,7 +1798,7 @@ static int wm_search_menu_exec(bContext *UNUSED(C), wmOperator *UNUSED(op))
return OPERATOR_FINISHED;
}
-static int wm_search_menu_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int wm_search_menu_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
uiPupBlock(C, wm_block_search_menu, op);
@@ -1944,7 +1946,7 @@ static void open_set_use_scripts(wmOperator *op)
}
}
-static int wm_open_mainfile_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int wm_open_mainfile_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
const char *openname = G.main->name;
@@ -2034,7 +2036,7 @@ static int wm_link_append_poll(bContext *C)
return 0;
}
-static int wm_link_append_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int wm_link_append_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
if (RNA_struct_property_is_set(op->ptr, "filepath")) {
return WM_operator_call_notest(C, op);
@@ -2168,7 +2170,7 @@ static int wm_link_append_exec(bContext *C, wmOperator *op)
/* append, rather than linking */
if ((flag & FILE_LINK) == 0) {
Library *lib = BLI_findstring(&bmain->library, libname, offsetof(Library, filepath));
- if (lib) BKE_library_make_local(bmain, lib, 1);
+ if (lib) BKE_library_make_local(bmain, lib, true);
else BLI_assert(!"cant find name of just added library!");
}
@@ -2289,7 +2291,7 @@ static int wm_recover_auto_save_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int wm_recover_auto_save_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int wm_recover_auto_save_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
char filename[FILE_MAX];
@@ -2319,7 +2321,7 @@ static void WM_OT_recover_auto_save(wmOperatorType *ot)
static void untitled(char *filepath)
{
if (G.save_over == 0 && strlen(filepath) < FILE_MAX - 16) {
- char *c = BLI_last_slash(filepath);
+ char *c = (char *)BLI_last_slash(filepath);
if (c)
strcpy(&c[1], "untitled.blend");
@@ -2338,7 +2340,7 @@ static void save_set_compress(wmOperator *op)
}
}
-static int wm_save_as_mainfile_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int wm_save_as_mainfile_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
char name[FILE_MAX];
@@ -2409,7 +2411,7 @@ static int blend_save_check(bContext *UNUSED(C), wmOperator *op)
RNA_string_get(op->ptr, "filepath", filepath);
if (!BLO_has_bfile_extension(filepath)) {
/* some users would prefer BLI_replace_extension(),
- * we keep getting knit-picking bug reports about this - campbell */
+ * we keep getting nitpicking bug reports about this - campbell */
BLI_ensure_extension(filepath, FILE_MAX, ".blend");
RNA_string_set(op->ptr, "filepath", filepath);
return TRUE;
@@ -2444,7 +2446,7 @@ static void WM_OT_save_as_mainfile(wmOperatorType *ot)
/* *************** save file directly ******** */
-static int wm_save_mainfile_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int wm_save_mainfile_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
char name[FILE_MAX];
int ret;
@@ -2650,7 +2652,7 @@ static void wm_gesture_end(bContext *C, wmOperator *op)
WM_cursor_restore(CTX_wm_window(C));
}
-int WM_border_select_invoke(bContext *C, wmOperator *op, wmEvent *event)
+int WM_border_select_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
if (ISTWEAK(event->type))
op->customdata = WM_gesture_new(C, event, WM_GESTURE_RECT);
@@ -2665,7 +2667,7 @@ int WM_border_select_invoke(bContext *C, wmOperator *op, wmEvent *event)
return OPERATOR_RUNNING_MODAL;
}
-int WM_border_select_modal(bContext *C, wmOperator *op, wmEvent *event)
+int WM_border_select_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
wmGesture *gesture = op->customdata;
rcti *rect = gesture->customdata;
@@ -2734,7 +2736,7 @@ int WM_border_select_cancel(bContext *C, wmOperator *op)
int circle_select_size = 25; /* XXX - need some operator memory thing! */
#endif
-int WM_gesture_circle_invoke(bContext *C, wmOperator *op, wmEvent *event)
+int WM_gesture_circle_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
op->customdata = WM_gesture_new(C, event, WM_GESTURE_CIRCLE);
@@ -2769,7 +2771,7 @@ static void gesture_circle_apply(bContext *C, wmOperator *op)
#endif
}
-int WM_gesture_circle_modal(bContext *C, wmOperator *op, wmEvent *event)
+int WM_gesture_circle_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
wmGesture *gesture = op->customdata;
rcti *rect = gesture->customdata;
@@ -2787,7 +2789,18 @@ int WM_gesture_circle_modal(bContext *C, wmOperator *op, wmEvent *event)
gesture_circle_apply(C, op);
}
else if (event->type == EVT_MODAL_MAP) {
+ float fac;
+
switch (event->val) {
+ case GESTURE_MODAL_CIRCLE_SIZE:
+ fac = 0.3f * (event->y - event->prevy);
+ if (fac > 0)
+ rect->xmax += ceil(fac);
+ else
+ rect->xmax += floor(fac);
+ if (rect->xmax < 1) rect->xmax = 1;
+ wm_gesture_tag_redraw(C);
+ break;
case GESTURE_MODAL_CIRCLE_ADD:
rect->xmax += 2 + rect->xmax / 10;
wm_gesture_tag_redraw(C);
@@ -2854,7 +2867,7 @@ void WM_OT_circle_gesture(wmOperatorType *ot)
/* **************** Tweak gesture *************** */
-static void tweak_gesture_modal(bContext *C, wmEvent *event)
+static void tweak_gesture_modal(bContext *C, const wmEvent *event)
{
wmWindow *window = CTX_wm_window(C);
wmGesture *gesture = window->tweak;
@@ -2896,7 +2909,9 @@ static void tweak_gesture_modal(bContext *C, wmEvent *event)
WM_gesture_end(C, gesture);
/* when tweak fails we should give the other keymap entries a chance */
- event->val = KM_RELEASE;
+
+ /* XXX, assigning to readonly, BAD JUJU! */
+ ((wmEvent *)event)->val = KM_RELEASE;
}
break;
default:
@@ -2932,7 +2947,7 @@ void wm_tweakevent_test(bContext *C, wmEvent *event, int action)
/* *********************** lasso gesture ****************** */
-int WM_gesture_lasso_invoke(bContext *C, wmOperator *op, wmEvent *event)
+int WM_gesture_lasso_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
op->customdata = WM_gesture_new(C, event, WM_GESTURE_LASSO);
@@ -2947,7 +2962,7 @@ int WM_gesture_lasso_invoke(bContext *C, wmOperator *op, wmEvent *event)
return OPERATOR_RUNNING_MODAL;
}
-int WM_gesture_lines_invoke(bContext *C, wmOperator *op, wmEvent *event)
+int WM_gesture_lines_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
op->customdata = WM_gesture_new(C, event, WM_GESTURE_LINES);
@@ -2989,7 +3004,7 @@ static void gesture_lasso_apply(bContext *C, wmOperator *op)
}
}
-int WM_gesture_lasso_modal(bContext *C, wmOperator *op, wmEvent *event)
+int WM_gesture_lasso_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
wmGesture *gesture = op->customdata;
int sx, sy;
@@ -3045,7 +3060,7 @@ int WM_gesture_lasso_modal(bContext *C, wmOperator *op, wmEvent *event)
return OPERATOR_RUNNING_MODAL;
}
-int WM_gesture_lines_modal(bContext *C, wmOperator *op, wmEvent *event)
+int WM_gesture_lines_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
return WM_gesture_lasso_modal(C, op, event);
}
@@ -3164,7 +3179,7 @@ static int straightline_apply(bContext *C, wmOperator *op)
}
-int WM_gesture_straightline_invoke(bContext *C, wmOperator *op, wmEvent *event)
+int WM_gesture_straightline_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
op->customdata = WM_gesture_new(C, event, WM_GESTURE_STRAIGHTLINE);
@@ -3179,7 +3194,7 @@ int WM_gesture_straightline_invoke(bContext *C, wmOperator *op, wmEvent *event)
return OPERATOR_RUNNING_MODAL;
}
-int WM_gesture_straightline_modal(bContext *C, wmOperator *op, wmEvent *event)
+int WM_gesture_straightline_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
wmGesture *gesture = op->customdata;
rcti *rect = gesture->customdata;
@@ -3271,7 +3286,7 @@ typedef struct {
void *cursor;
} RadialControl;
-static void radial_control_set_initial_mouse(RadialControl *rc, wmEvent *event)
+static void radial_control_set_initial_mouse(RadialControl *rc, const wmEvent *event)
{
float d[2] = {0, 0};
float zoom[2] = {1, 1};
@@ -3587,7 +3602,7 @@ static int radial_control_get_properties(bContext *C, wmOperator *op)
return 1;
}
-static int radial_control_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int radial_control_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
wmWindowManager *wm;
RadialControl *rc;
@@ -3684,7 +3699,7 @@ static int radial_control_cancel(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
-static int radial_control_modal(bContext *C, wmOperator *op, wmEvent *event)
+static int radial_control_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
RadialControl *rc = op->customdata;
float new_value, dist, zoom[2];
@@ -4062,6 +4077,7 @@ static void gesture_circle_modal_keymap(wmKeyConfig *keyconf)
{GESTURE_MODAL_CONFIRM, "CONFIRM", 0, "Confirm", ""},
{GESTURE_MODAL_CIRCLE_ADD, "ADD", 0, "Add", ""},
{GESTURE_MODAL_CIRCLE_SUB, "SUBTRACT", 0, "Subtract", ""},
+ {GESTURE_MODAL_CIRCLE_SIZE, "SIZE", 0, "Size", ""},
{GESTURE_MODAL_SELECT, "SELECT", 0, "Select", ""},
{GESTURE_MODAL_DESELECT, "DESELECT", 0, "DeSelect", ""},
@@ -4100,6 +4116,7 @@ static void gesture_circle_modal_keymap(wmKeyConfig *keyconf)
WM_modalkeymap_add_item(keymap, PADMINUS, KM_PRESS, 0, 0, GESTURE_MODAL_CIRCLE_SUB);
WM_modalkeymap_add_item(keymap, WHEELDOWNMOUSE, KM_PRESS, 0, 0, GESTURE_MODAL_CIRCLE_ADD);
WM_modalkeymap_add_item(keymap, PADPLUSKEY, KM_PRESS, 0, 0, GESTURE_MODAL_CIRCLE_ADD);
+ WM_modalkeymap_add_item(keymap, MOUSEPAN, 0, 0, 0, GESTURE_MODAL_CIRCLE_SIZE);
/* assign map to operators */
WM_modalkeymap_assign(keymap, "VIEW3D_OT_select_circle");
@@ -4184,6 +4201,7 @@ static void gesture_border_modal_keymap(wmKeyConfig *keyconf)
WM_modalkeymap_assign(keymap, "MARKER_OT_select_border");
WM_modalkeymap_assign(keymap, "NLA_OT_select_border");
WM_modalkeymap_assign(keymap, "NODE_OT_select_border");
+ WM_modalkeymap_assign(keymap, "NODE_OT_viewer_border");
WM_modalkeymap_assign(keymap, "PAINT_OT_hide_show");
WM_modalkeymap_assign(keymap, "OUTLINER_OT_select_border");
// WM_modalkeymap_assign(keymap, "SCREEN_OT_border_select"); // template
diff --git a/source/blender/windowmanager/intern/wm_playanim.c b/source/blender/windowmanager/intern/wm_playanim.c
index b510956dbc1..a289d182f1c 100644
--- a/source/blender/windowmanager/intern/wm_playanim.c
+++ b/source/blender/windowmanager/intern/wm_playanim.c
@@ -49,12 +49,12 @@
#include "PIL_time.h"
+#include "BLI_utildefines.h"
#include "BLI_fileops.h"
#include "BLI_listbase.h"
#include "BLI_path_util.h"
#include "BLI_rect.h"
#include "BLI_string.h"
-#include "BLI_utildefines.h"
#include "IMB_imbuf_types.h"
#include "IMB_imbuf.h"
@@ -76,10 +76,16 @@
#include "WM_api.h" /* only for WM_main_playanim */
struct PlayState;
-static void playanim_window_zoom(const struct PlayState *ps, const float zoom_offset);
+static void playanim_window_zoom(struct PlayState *ps, const float zoom_offset);
typedef struct PlayState {
+ /* window and viewport size */
+ int win_x, win_y;
+
+ /* current zoom level */
+ float zoom;
+
/* playback state */
short direction;
short next_frame;
@@ -91,7 +97,7 @@ typedef struct PlayState {
short wait2;
short stopped;
short go;
-
+
int fstep;
/* current picture */
@@ -103,6 +109,9 @@ typedef struct PlayState {
/* saves passing args */
struct ImBuf *curframe_ibuf;
+
+ /* restarts player for file drop */
+ char dropped_file[FILE_MAX];
} PlayState;
/* for debugging */
@@ -204,7 +213,6 @@ typedef struct PlayAnimPict {
static struct ListBase picsbase = {NULL, NULL};
static int fromdisk = FALSE;
-static float zoomx = 1.0, zoomy = 1.0;
static double ptottime = 0.0, swaptime = 0.04;
static PlayAnimPict *playanim_step(PlayAnimPict *playanim, int step)
@@ -234,8 +242,9 @@ static int pupdate_time(void)
return (ptottime < 0);
}
-static void playanim_toscreen(PlayAnimPict *picture, struct ImBuf *ibuf, int fontid, int fstep)
+static void playanim_toscreen(PlayState *ps, PlayAnimPict *picture, struct ImBuf *ibuf, int fontid, int fstep)
{
+ float offsx, offsy;
if (ibuf == NULL) {
printf("%s: no ibuf for picture '%s'\n", __func__, picture ? picture->name : "<NIL>");
@@ -250,17 +259,29 @@ static void playanim_toscreen(PlayAnimPict *picture, struct ImBuf *ibuf, int fon
GHOST_ActivateWindowDrawingContext(g_WS.ghost_window);
- glRasterPos2f(0.0f, 0.0f);
+ /* offset within window */
+ offsx = 0.5f * (((float)ps->win_x - ps->zoom * ibuf->x) / (float)ps->win_x);
+ offsy = 0.5f * (((float)ps->win_y - ps->zoom * ibuf->y) / (float)ps->win_y);
- glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ CLAMP(offsx, 0.0f, 1.0f);
+ CLAMP(offsy, 0.0f, 1.0f);
+ glRasterPos2f(offsx, offsy);
- fdrawcheckerboard(0.0f, 0.0f, ibuf->x, ibuf->y);
+ glClearColor(0.1, 0.1, 0.1, 0.0);
+ glClear(GL_COLOR_BUFFER_BIT);
+
+ /* checkerboard for case alpha */
+ if (ibuf->planes == 32) {
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ fdrawcheckerboard(offsx, offsy, offsx + (ps->zoom * ibuf->x) / (float)ps->win_x, offsy + (ps->zoom * ibuf->y) / (float)ps->win_y);
+ }
+
glDrawPixels(ibuf->x, ibuf->y, GL_RGBA, GL_UNSIGNED_BYTE, ibuf->rect);
glDisable(GL_BLEND);
-
+
pupdate_time();
if (picture && (g_WS.qual & (WS_QUAL_SHIFT | WS_QUAL_LMOUSE)) && (fontid != -1)) {
@@ -283,7 +304,7 @@ static void playanim_toscreen(PlayAnimPict *picture, struct ImBuf *ibuf, int fon
GHOST_SwapWindowBuffers(g_WS.ghost_window);
}
-static void build_pict_list(char *first, int totframes, int fstep, int fontid)
+static void build_pict_list(PlayState *ps, char *first, int totframes, int fstep, int fontid)
{
char *mem, filepath[FILE_MAX];
// short val;
@@ -299,7 +320,7 @@ static void build_pict_list(char *first, int totframes, int fstep, int fontid)
int pic;
ibuf = IMB_anim_absolute(anim, 0, IMB_TC_NONE, IMB_PROXY_NONE);
if (ibuf) {
- playanim_toscreen(NULL, ibuf, fontid, fstep);
+ playanim_toscreen(ps, NULL, ibuf, fontid, fstep);
IMB_freeImBuf(ibuf);
}
@@ -402,7 +423,7 @@ static void build_pict_list(char *first, int totframes, int fstep, int fontid)
ibuf = IMB_loadiffname(picture->name, picture->IB_flags, NULL);
}
if (ibuf) {
- playanim_toscreen(picture, ibuf, fontid, fstep);
+ playanim_toscreen(ps, picture, ibuf, fontid, fstep);
IMB_freeImBuf(ibuf);
}
pupdate_time();
@@ -587,7 +608,9 @@ static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr ps_void)
case GHOST_kKeyPeriod:
case GHOST_kKeyNumpadPeriod:
if (val) {
- if (ps->sstep) ps->wait2 = FALSE;
+ if (ps->sstep) {
+ ps->wait2 = FALSE;
+ }
else {
ps->sstep = TRUE;
ps->wait2 = !ps->wait2;
@@ -704,28 +727,33 @@ static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr ps_void)
case GHOST_kEventWindowSize:
case GHOST_kEventWindowMove:
{
- int sizex, sizey;
-
- playanim_window_get_size(&sizex, &sizey);
+ float zoomx, zoomy;
+
+ playanim_window_get_size(&ps->win_x, &ps->win_y);
GHOST_ActivateWindowDrawingContext(g_WS.ghost_window);
- glViewport(0, 0, sizex, sizey);
- glScissor(0, 0, sizex, sizey);
-
- zoomx = (float) sizex / ps->ibufx;
- zoomy = (float) sizey / ps->ibufy;
- zoomx = floor(zoomx + 0.5f);
- zoomy = floor(zoomy + 0.5f);
- if (zoomx < 1.0f) zoomx = 1.0f;
- if (zoomy < 1.0f) zoomy = 1.0f;
-
- sizex = zoomx * ps->ibufx;
- sizey = zoomy * ps->ibufy;
+ zoomx = (float) ps->win_x / ps->ibufx;
+ zoomy = (float) ps->win_y / ps->ibufy;
+
+ /* zoom always show entire image */
+ ps->zoom = MIN2(zoomx, zoomy);
+
+ /* zoom steps of 2 for speed */
+ ps->zoom = floor(ps->zoom + 0.5f);
+ if (ps->zoom < 1.0f) ps->zoom = 1.0f;
+
+ glViewport(0, 0, ps->win_x, ps->win_y);
+ glScissor(0, 0, ps->win_x, ps->win_y);
+
+ /* unified matrix, note it affects offset for drawing */
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ glOrtho(0.0f, 1.0f, 0.0f, 1.0f, -1.0f, 1.0f);
+ glMatrixMode(GL_MODELVIEW);
- glPixelZoom(zoomx, zoomy);
- glEnable(GL_DITHER);
+ glPixelZoom(ps->zoom, ps->zoom);
ptottime = 0.0;
- playanim_toscreen(ps->picture, ps->curframe_ibuf, ps->fontid, ps->fstep);
+ playanim_toscreen(ps, ps->picture, ps->curframe_ibuf, ps->fontid, ps->fstep);
break;
}
@@ -735,6 +763,23 @@ static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr ps_void)
ps->go = FALSE;
break;
}
+ case GHOST_kEventDraggingDropDone:
+ {
+ GHOST_TEventDragnDropData *ddd = GHOST_GetEventData(evt);
+
+ if (ddd->dataType == GHOST_kDragnDropTypeFilenames) {
+ GHOST_TStringArray *stra = ddd->data;
+ int a;
+
+ for (a = 0; a < stra->count; a++) {
+ BLI_strncpy(ps->dropped_file, (char *)stra->strings[a], sizeof(ps->dropped_file));
+ ps->go = FALSE;
+ printf("drop file %s\n", stra->strings[a]);
+ break; /* only one drop element supported now */
+ }
+ }
+ break;
+ }
default:
/* quiet warnings */
break;
@@ -765,32 +810,31 @@ static void playanim_window_open(const char *title, int posx, int posy, int size
FALSE /* no stereo */, FALSE);
}
-static void playanim_window_zoom(const PlayState *ps, const float zoom_offset)
+static void playanim_window_zoom(PlayState *ps, const float zoom_offset)
{
int sizex, sizey;
/* int ofsx, ofsy; */ /* UNUSED */
- if (zoomx + zoom_offset > 0.0f) zoomx += zoom_offset;
- if (zoomy + zoom_offset > 0.0f) zoomy += zoom_offset;
+ if (ps->zoom + zoom_offset > 0.0f) ps->zoom += zoom_offset;
// playanim_window_get_position(&ofsx, &ofsy);
playanim_window_get_size(&sizex, &sizey);
/* ofsx += sizex / 2; */ /* UNUSED */
/* ofsy += sizey / 2; */ /* UNUSED */
- sizex = zoomx * ps->ibufx;
- sizey = zoomy * ps->ibufy;
+ sizex = ps->zoom * ps->ibufx;
+ sizey = ps->zoom * ps->ibufy;
/* ofsx -= sizex / 2; */ /* UNUSED */
/* ofsy -= sizey / 2; */ /* UNUSED */
// window_set_position(g_WS.ghost_window,sizex,sizey);
GHOST_SetClientSize(g_WS.ghost_window, sizex, sizey);
}
-void WM_main_playanim(int argc, const char **argv)
+/* return path for restart */
+static char *wm_main_playanim_intern(int argc, const char **argv)
{
struct ImBuf *ibuf = NULL;
- char filepath[FILE_MAX];
+ static char filepath[FILE_MAX]; /* abused to return dropped file path */
GHOST_TUns32 maxwinx, maxwiny;
- /* short c233 = FALSE, yuvx = FALSE; */ /* UNUSED */
int i;
/* This was done to disambiguate the name for use under c++. */
struct anim *anim = NULL;
@@ -798,7 +842,7 @@ void WM_main_playanim(int argc, const char **argv)
int sfra = -1;
int efra = -1;
int totblock;
-
+
PlayState ps = {0};
/* ps.doubleb = TRUE;*/ /* UNUSED */
@@ -813,6 +857,8 @@ void WM_main_playanim(int argc, const char **argv)
ps.wait2 = FALSE;
ps.stopped = FALSE;
ps.picture = NULL;
+ ps.dropped_file[0] = 0;
+ ps.zoom = 1.0f;
/* resetmap = FALSE */
ps.fstep = 1;
@@ -918,20 +964,16 @@ void WM_main_playanim(int argc, const char **argv)
#endif
#endif //XXX25
- /* XXX, fixme zr */
{
-// extern void add_to_mainqueue(wmWindow *win, void *user_data, short evt, short val, char ascii);
GHOST_EventConsumerHandle consumer = GHOST_CreateEventConsumer(ghost_event_proc, &ps);
g_WS.ghost_system = GHOST_CreateSystem();
GHOST_AddEventConsumer(g_WS.ghost_system, consumer);
-
-
playanim_window_open("Blender:Anim", start_x, start_y, ibuf->x, ibuf->y, 0);
-//XXX25 window_set_handler(g_WS.ghost_window, add_to_mainqueue, NULL);
+ /* unified matrix, note it affects offset for drawing */
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0.0f, 1.0f, 0.0f, 1.0f, -1.0f, 1.0f);
@@ -949,11 +991,15 @@ void WM_main_playanim(int argc, const char **argv)
ps.ibufx = ibuf->x;
ps.ibufy = ibuf->y;
+
+ ps.win_x = ps.ibufx;
+ ps.win_y = ps.ibufy;
if (maxwinx % ibuf->x) maxwinx = ibuf->x * (1 + (maxwinx / ibuf->x));
if (maxwiny % ibuf->y) maxwiny = ibuf->y * (1 + (maxwiny / ibuf->y));
- glClearColor(0.0, 0.0, 0.0, 0.0);
+
+ glClearColor(0.1, 0.1, 0.1, 0.0);
glClear(GL_COLOR_BUFFER_BIT);
GHOST_SwapWindowBuffers(g_WS.ghost_window);
@@ -964,11 +1010,11 @@ void WM_main_playanim(int argc, const char **argv)
efra = MAXFRAME;
}
- build_pict_list(filepath, (efra - sfra) + 1, ps.fstep, ps.fontid);
+ build_pict_list(&ps, filepath, (efra - sfra) + 1, ps.fstep, ps.fontid);
for (i = 2; i < argc; i++) {
BLI_strncpy(filepath, argv[i], sizeof(filepath));
- build_pict_list(filepath, (efra - sfra) + 1, ps.fstep, ps.fontid);
+ build_pict_list(&ps, filepath, (efra - sfra) + 1, ps.fstep, ps.fontid);
}
IMB_freeImBuf(ibuf);
@@ -1041,8 +1087,8 @@ void WM_main_playanim(int argc, const char **argv)
while (pupdate_time()) PIL_sleep_ms(1);
ptottime -= swaptime;
- playanim_toscreen(ps.picture, ibuf, ps.fontid, ps.fstep);
- } /* else deleten */
+ playanim_toscreen(&ps, ps.picture, ibuf, ps.fontid, ps.fstep);
+ } /* else delete */
else {
printf("error: can't play this image type\n");
exit(0);
@@ -1060,16 +1106,17 @@ void WM_main_playanim(int argc, const char **argv)
ps.next_frame = ps.direction;
- while ((hasevent = GHOST_ProcessEvents(g_WS.ghost_system, 0) || ps.wait2 != 0)) {
+ while ( (hasevent = GHOST_ProcessEvents(g_WS.ghost_system, 0)) || ps.wait2 != 0) {
if (hasevent) {
GHOST_DispatchEvents(g_WS.ghost_system);
}
+ /* Note, this still draws for mousemoves on pause */
if (ps.wait2) {
if (hasevent) {
if (ibuf) {
while (pupdate_time()) PIL_sleep_ms(1);
ptottime -= swaptime;
- playanim_toscreen(ps.picture, ibuf, ps.fontid, ps.fstep);
+ playanim_toscreen(&ps, ps.picture, ibuf, ps.fontid, ps.fstep);
}
}
}
@@ -1142,12 +1189,20 @@ void WM_main_playanim(int argc, const char **argv)
#else
/* we still miss freeing a lot!,
* but many areas could skip initialization too for anim play */
- IMB_exit();
- BKE_images_exit();
+
BLF_exit();
#endif
GHOST_DisposeWindow(g_WS.ghost_system, g_WS.ghost_window);
+ /* early exit, IMB and BKE should be exited only in end */
+ if (ps.dropped_file) {
+ BLI_strncpy(filepath, ps.dropped_file, sizeof(filepath));
+ return filepath;
+ }
+
+ IMB_exit();
+ BKE_images_exit();
+
totblock = MEM_get_memory_blocks_in_use();
if (totblock != 0) {
/* prints many bAKey, bArgument's which are tricky to fix */
@@ -1156,4 +1211,25 @@ void WM_main_playanim(int argc, const char **argv)
MEM_printmemlist();
#endif
}
+
+ return NULL;
+}
+
+
+void WM_main_playanim(int argc, const char **argv)
+{
+ bool looping = true;
+
+ while (looping) {
+ char *filepath = wm_main_playanim_intern(argc, argv);
+
+ if (filepath) { /* use simple args */
+ argv[1] = "-a";
+ argv[2] = filepath;
+ argc = 3;
+ }
+ else {
+ looping = false;
+ }
+ }
}
diff --git a/source/blender/windowmanager/intern/wm_subwindow.c b/source/blender/windowmanager/intern/wm_subwindow.c
index 20406ac463d..01bebe8a1b8 100644
--- a/source/blender/windowmanager/intern/wm_subwindow.c
+++ b/source/blender/windowmanager/intern/wm_subwindow.c
@@ -257,9 +257,9 @@ void wmSubWindowScissorSet(wmWindow *win, int swinid, rcti *srct)
glViewport(_curswin->winrct.xmin, _curswin->winrct.ymin, width, height);
if (srct) {
- 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);
+ int scissor_width = BLI_rcti_size_x(srct) + 1; /* only here */
+ int scissor_height = BLI_rcti_size_y(srct) + 1;
+ glScissor(srct->xmin, srct->ymin, scissor_width, scissor_height);
}
else
glScissor(_curswin->winrct.xmin, _curswin->winrct.ymin, width, height);
diff --git a/source/blender/windowmanager/intern/wm_window.c b/source/blender/windowmanager/intern/wm_window.c
index a1ab0de49cf..53698ca7e9e 100644
--- a/source/blender/windowmanager/intern/wm_window.c
+++ b/source/blender/windowmanager/intern/wm_window.c
@@ -28,7 +28,6 @@
* \ingroup wm
*/
-
#include <math.h>
#include <stdlib.h>
#include <stdio.h>
@@ -37,7 +36,6 @@
#include "DNA_listBase.h"
#include "DNA_screen_types.h"
#include "DNA_windowmanager_types.h"
-#include "RNA_access.h"
#include "MEM_guardedalloc.h"
@@ -55,9 +53,10 @@
#include "BKE_global.h"
#include "BKE_main.h"
-
#include "BIF_gl.h"
+#include "RNA_access.h"
+
#include "WM_api.h"
#include "WM_types.h"
#include "wm.h"
@@ -445,11 +444,15 @@ void wm_window_add_ghostwindows(wmWindowManager *wm)
#endif
#if !defined(__APPLE__) && !defined(WIN32) /* X11 */
- /* X11, start maximized but use default same size */
+ /* X11, start maximized but use default sane size */
wm_init_state.size_x = min_ii(wm_init_state.size_x, WM_WIN_INIT_SIZE_X);
wm_init_state.size_y = min_ii(wm_init_state.size_y, WM_WIN_INIT_SIZE_Y);
+ /* pad */
+ wm_init_state.start_x = WM_WIN_INIT_PAD;
+ wm_init_state.start_y = WM_WIN_INIT_PAD;
+ wm_init_state.size_x -= WM_WIN_INIT_PAD * 2;
+ wm_init_state.size_y -= WM_WIN_INIT_PAD * 2;
#endif
-
}
for (win = wm->windows.first; win; win = win->next) {
@@ -460,19 +463,7 @@ void wm_window_add_ghostwindows(wmWindowManager *wm)
win->sizex = wm_init_state.size_x;
win->sizey = wm_init_state.size_y;
-#if !defined(__APPLE__) && !defined(WIN32) /* X11 */
- if (wm_init_state.override_flag & WIN_OVERRIDE_GEOM) {
- /* we can't properly resize a maximized window */
- win->windowstate = GHOST_kWindowStateNormal;
- }
- else {
- /* loading without userpref, default to maximized */
- win->windowstate = GHOST_kWindowStateMaximized;
- }
-#else
win->windowstate = GHOST_kWindowStateNormal;
-#endif
-
wm_init_state.override_flag &= ~WIN_OVERRIDE_GEOM;
}
@@ -1253,7 +1244,9 @@ void WM_clipboard_text_set(char *buf, int selection)
if (*p == '\n') {
*(p2++) = '\r'; *p2 = '\n';
}
- else *p2 = *p;
+ else {
+ *p2 = *p;
+ }
}
*p2 = '\0';
diff --git a/source/blender/windowmanager/wm_event_types.h b/source/blender/windowmanager/wm_event_types.h
index bc7e7efdcfd..338ef8bc65b 100644
--- a/source/blender/windowmanager/wm_event_types.h
+++ b/source/blender/windowmanager/wm_event_types.h
@@ -384,6 +384,8 @@ enum {
#define GESTURE_MODAL_IN 9
#define GESTURE_MODAL_OUT 10
+#define GESTURE_MODAL_CIRCLE_SIZE 11 /* circle sel: size brush (for trackpad event) */
+
#endif /* __WM_EVENT_TYPES_H__ */
diff --git a/source/blender/windowmanager/wm_window.h b/source/blender/windowmanager/wm_window.h
index c4c64ed429f..a0546c88b78 100644
--- a/source/blender/windowmanager/wm_window.h
+++ b/source/blender/windowmanager/wm_window.h
@@ -74,6 +74,7 @@ int wm_window_fullscreen_toggle_exec(bContext *C, struct wmOperator *op);
* Clamped by real desktop limits */
#define WM_WIN_INIT_SIZE_X 1800
#define WM_WIN_INIT_SIZE_Y 1000
+#define WM_WIN_INIT_PAD 40
#endif /* __WM_WINDOW_H__ */
diff --git a/source/blenderplayer/CMakeLists.txt b/source/blenderplayer/CMakeLists.txt
index 5e65324d893..c775f7d3279 100644
--- a/source/blenderplayer/CMakeLists.txt
+++ b/source/blenderplayer/CMakeLists.txt
@@ -150,6 +150,7 @@ endif()
bf_intern_opencolorio
bf_intern_opennl
extern_rangetree
+ extern_wcwidth
)
if(WITH_MOD_CLOTH_ELTOPO)
diff --git a/source/blenderplayer/bad_level_call_stubs/stubs.c b/source/blenderplayer/bad_level_call_stubs/stubs.c
index 5e8a0b2a06b..c76992677d5 100644
--- a/source/blenderplayer/bad_level_call_stubs/stubs.c
+++ b/source/blenderplayer/bad_level_call_stubs/stubs.c
@@ -71,6 +71,7 @@ struct Mask;
struct Material;
struct MenuType;
struct Mesh;
+struct MetaBall;
struct ModifierData;
struct MovieClip;
struct MultiresModifierData;
@@ -116,6 +117,7 @@ struct bNodeSocket;
struct bNodeTree;
struct bPoseChannel;
struct bPythonConstraint;
+struct bTheme;
struct uiLayout;
struct wmEvent;
struct wmKeyConfig;
@@ -201,7 +203,7 @@ void WM_menutype_free(void) {}
void WM_menutype_freelink(struct MenuType *mt) {}
int WM_menutype_add(struct MenuType *mt) {return 0;}
int WM_operator_props_dialog_popup(struct bContext *C, struct wmOperator *op, int width, int height) {return 0;}
-int WM_operator_confirm(struct bContext *C, struct wmOperator *op, struct wmEvent *event) {return 0;}
+int WM_operator_confirm(struct bContext *C, struct wmOperator *op, const struct wmEvent *event) {return 0;}
struct MenuType *WM_menutype_find(const char *idname, int quiet) {return (struct MenuType *) NULL;}
void WM_operator_stack_clear(struct bContext *C) {}
void WM_operator_handlers_clear(struct bContext *C, struct wmOperatorType *ot) {}
@@ -420,6 +422,7 @@ void uiLayoutSetContextPointer(struct uiLayout *layout, char *name, struct Point
char *uiLayoutIntrospect(struct uiLayout *layout) {return (char *)NULL;}
void UI_reinit_font(void) {}
int UI_rnaptr_icon_get(struct bContext *C, struct PointerRNA *ptr, int rnaicon, int big) {return 0;}
+struct bTheme *UI_GetTheme(void) {return (struct bTheme *) NULL;};
/* rna template */
void uiTemplateAnyID(struct uiLayout *layout, struct bContext *C, struct PointerRNA *ptr, char *propname, char *text) {}
@@ -466,6 +469,7 @@ struct RenderResult *RE_engine_begin_result(struct RenderEngine *engine, int x,
struct RenderResult *RE_AcquireResultRead(struct Render *re) {return (struct RenderResult *) NULL;}
struct RenderResult *RE_AcquireResultWrite(struct Render *re) {return (struct RenderResult *) NULL;}
struct RenderStats *RE_GetStats(struct Render *re) {return (struct RenderStats *) NULL;}
+struct RenderData *RE_engine_get_render_data(struct Render *re) {return (struct RenderData *) NULL;}
void RE_engine_update_result(struct RenderEngine *engine, struct RenderResult *result) {}
void RE_engine_update_progress(struct RenderEngine *engine, float progress) {}
void RE_engine_end_result(struct RenderEngine *engine, struct RenderResult *result) {}
@@ -524,7 +528,6 @@ float sculpt_get_brush_alpha(struct Brush *brush) {return 0.0f;}
void sculpt_set_brush_alpha(struct Brush *brush, float alpha) {}
void ED_sculpt_modifiers_changed(struct Object *ob) {}
void ED_mesh_calc_tessface(struct Mesh *mesh) {}
-void BKE_brush_gen_texture_cache(struct Brush *br, int half_side) {}
/* bpy/python internal api */
void operator_wrapper(struct wmOperatorType *ot, void *userdata) {}
diff --git a/source/creator/CMakeLists.txt b/source/creator/CMakeLists.txt
index d858f7ac62d..551579dcf65 100644
--- a/source/creator/CMakeLists.txt
+++ b/source/creator/CMakeLists.txt
@@ -927,6 +927,7 @@ endif()
bf_intern_raskter
bf_intern_opencolorio
extern_rangetree
+ extern_wcwidth
)
if(WITH_COMPOSITOR)
diff --git a/source/gameengine/BlenderRoutines/KX_BlenderGL.cpp b/source/gameengine/BlenderRoutines/KX_BlenderGL.cpp
index 3a9a10dd0cc..f24392352b0 100644
--- a/source/gameengine/BlenderRoutines/KX_BlenderGL.cpp
+++ b/source/gameengine/BlenderRoutines/KX_BlenderGL.cpp
@@ -166,7 +166,7 @@ void BL_draw_gamedebug_box(int xco, int yco, int width, int height, float percen
}
/* Print 3D text */
-void BL_print_game_line(int fontid, const char* text, int size, int dpi, float* color, double* mat, float aspect)
+void BL_print_game_line(int fontid, const char *text, int size, int dpi, float *color, double *mat, float aspect)
{
/* gl prepping */
DisableForText();
diff --git a/source/gameengine/BlenderRoutines/KX_BlenderInputDevice.h b/source/gameengine/BlenderRoutines/KX_BlenderInputDevice.h
index 2a96d4c5216..0ce479cad6f 100644
--- a/source/gameengine/BlenderRoutines/KX_BlenderInputDevice.h
+++ b/source/gameengine/BlenderRoutines/KX_BlenderInputDevice.h
@@ -64,7 +64,7 @@ public:
}
KX_EnumInputs ToNative(unsigned short incode) {
- return ConvertKeyCode(incode);
+ return ConvertKeyCode(incode);
}
virtual bool IsPressed(SCA_IInputDevice::KX_EnumInputs inputcode)=0;
diff --git a/source/gameengine/Expressions/Value.h b/source/gameengine/Expressions/Value.h
index c4af3255f4a..580691d88c4 100644
--- a/source/gameengine/Expressions/Value.h
+++ b/source/gameengine/Expressions/Value.h
@@ -253,9 +253,9 @@ public:
// Increase global reference count, used to see at the end of the program
// if all CValue-derived classes have been dereferenced to 0
//debug(gRefCountValue++);
- #ifdef _DEBUG
+#ifdef _DEBUG
//gRefCountValue++;
- #endif
+#endif
m_refcount++;
return this;
}
@@ -266,9 +266,9 @@ public:
// Decrease global reference count, used to see at the end of the program
// if all CValue-derived classes have been dereferenced to 0
//debug(gRefCountValue--);
- #ifdef _DEBUG
+#ifdef _DEBUG
//gRefCountValue--;
- #endif
+#endif
// Decrease local reference count, if it reaches 0 the object should be freed
if (--m_refcount > 0)
{
diff --git a/source/gameengine/GameLogic/SCA_IActuator.h b/source/gameengine/GameLogic/SCA_IActuator.h
index 090df1e75e2..aed49bc1822 100644
--- a/source/gameengine/GameLogic/SCA_IActuator.h
+++ b/source/gameengine/GameLogic/SCA_IActuator.h
@@ -131,7 +131,7 @@ public:
virtual void ProcessReplica();
/**
- * Return true iff all the current events
+ * Return true if all the current events
* are negative. The definition of negative event is
* not immediately clear. But usually refers to key-up events
* or events where no action is required.
diff --git a/source/gameengine/GamePlayer/common/GPC_Canvas.h b/source/gameengine/GamePlayer/common/GPC_Canvas.h
index 00c5911a8b4..07f96166ec2 100644
--- a/source/gameengine/GamePlayer/common/GPC_Canvas.h
+++ b/source/gameengine/GamePlayer/common/GPC_Canvas.h
@@ -36,8 +36,8 @@
#include "RAS_Rect.h"
#ifdef WIN32
- #pragma warning (disable:4786) // suppress stl-MSVC debug info warning
- #include <windows.h>
+# pragma warning (disable:4786) // suppress stl-MSVC debug info warning
+# include <windows.h>
#endif /* WIN32 */
#include "GL/glew.h"
diff --git a/source/gameengine/GamePlayer/ghost/GPG_ghost.cpp b/source/gameengine/GamePlayer/ghost/GPG_ghost.cpp
index c1f43306eba..5d843cccf85 100644
--- a/source/gameengine/GamePlayer/ghost/GPG_ghost.cpp
+++ b/source/gameengine/GamePlayer/ghost/GPG_ghost.cpp
@@ -1055,6 +1055,7 @@ int main(int argc, char** argv)
#ifdef WITH_INTERNATIONAL
BLF_free_unifont();
+ BLF_free_unifont_mono();
BLF_lang_free();
#endif
diff --git a/source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp b/source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp
index 4a5a1704979..ece6abc9447 100644
--- a/source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp
+++ b/source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp
@@ -68,8 +68,8 @@ extern "C"{
#include "KX_BulletPhysicsController.h"
#include "btBulletDynamicsCommon.h"
- #ifdef WIN32
-#if _MSC_VER >= 1310
+#ifdef WIN32
+#if defined(_MSC_VER) && (_MSC_VER >= 1310)
//only use SIMD Hull code under Win32
//#define TEST_HULL 1
#ifdef TEST_HULL
diff --git a/source/gameengine/Ketsji/KX_GameObject.cpp b/source/gameengine/Ketsji/KX_GameObject.cpp
index 3a60ccc85e9..ae5758b8597 100644
--- a/source/gameengine/Ketsji/KX_GameObject.cpp
+++ b/source/gameengine/Ketsji/KX_GameObject.cpp
@@ -2742,11 +2742,11 @@ PyObject *KX_GameObject::PyGetReactionForce()
// only can get the velocity if we have a physics object connected to us...
// XXX - Currently not working with bullet intergration, see KX_BulletPhysicsController.cpp's getReactionForce
- /*
+#if 0
if (GetPhysicsController())
return PyObjectFrom(GetPhysicsController()->getReactionForce());
return PyObjectFrom(dummy_point);
- */
+#endif
return Py_BuildValue("fff", 0.0, 0.0, 0.0);
diff --git a/source/gameengine/Ketsji/KX_PythonInit.cpp b/source/gameengine/Ketsji/KX_PythonInit.cpp
index a54d4909db9..22715214324 100644
--- a/source/gameengine/Ketsji/KX_PythonInit.cpp
+++ b/source/gameengine/Ketsji/KX_PythonInit.cpp
@@ -1888,7 +1888,7 @@ PyObject *initGamePlayerPythonScripting(const STR_String& progname, TPythonSecur
* somehow it remembers the sys.path - Campbell
*/
static bool first_time = true;
- char *py_path_bundle = BLI_get_folder(BLENDER_SYSTEM_PYTHON, NULL);
+ const char * const py_path_bundle = BLI_get_folder(BLENDER_SYSTEM_PYTHON, NULL);
#if 0 // TODO - py3
STR_String pname = progname;
diff --git a/source/gameengine/Network/NG_NetworkScene.h b/source/gameengine/Network/NG_NetworkScene.h
index 10dad210128..e6233852ee2 100644
--- a/source/gameengine/Network/NG_NetworkScene.h
+++ b/source/gameengine/Network/NG_NetworkScene.h
@@ -42,7 +42,7 @@
//MSVC defines SendMessage as a win api function, even though we aren't using it
#ifdef SendMessage
- #undef SendMessage
+# undef SendMessage
#endif
using namespace std;
diff --git a/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp b/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp
index 702452bc77e..9fb86dec569 100644
--- a/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp
+++ b/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp
@@ -1206,7 +1206,7 @@ PHY_IPhysicsController* CcdPhysicsEnvironment::rayTest(PHY_IRayCastFilterCallbac
{
// soft body using different face numbering because of randomization
// hopefully we have stored the original face number in m_tag
- btSoftBody* softBody = static_cast<btSoftBody*>(rayCallback.m_collisionObject);
+ const btSoftBody* softBody = static_cast<const btSoftBody*>(rayCallback.m_collisionObject);
if (softBody->m_faces[hitTriangleIndex].m_tag != 0)
{
rayCallback.m_hitTriangleIndex = (int)((uintptr_t)(softBody->m_faces[hitTriangleIndex].m_tag)-1);
@@ -1226,7 +1226,7 @@ PHY_IPhysicsController* CcdPhysicsEnvironment::rayTest(PHY_IRayCastFilterCallbac
if (shape->isSoftBody())
{
// soft body give points directly in world coordinate
- btSoftBody* softBody = static_cast<btSoftBody*>(rayCallback.m_collisionObject);
+ const btSoftBody* softBody = static_cast<const btSoftBody*>(rayCallback.m_collisionObject);
v1 = softBody->m_faces[hitTriangleIndex].m_n[0]->m_x;
v2 = softBody->m_faces[hitTriangleIndex].m_n[1]->m_x;
v3 = softBody->m_faces[hitTriangleIndex].m_n[2]->m_x;
@@ -1274,7 +1274,7 @@ PHY_IPhysicsController* CcdPhysicsEnvironment::rayTest(PHY_IRayCastFilterCallbac
if (shape->isSoftBody())
{
// we can get the real normal directly from the body
- btSoftBody* softBody = static_cast<btSoftBody*>(rayCallback.m_collisionObject);
+ const btSoftBody* softBody = static_cast<const btSoftBody*>(rayCallback.m_collisionObject);
rayCallback.m_hitNormalWorld = softBody->m_faces[hitTriangleIndex].m_normal;
} else
{
@@ -2211,8 +2211,8 @@ void CcdPhysicsEnvironment::CallbackTriggers()
int numContacts = manifold->getNumContacts();
if (numContacts)
{
- btRigidBody* rb0 = static_cast<btRigidBody*>(manifold->getBody0());
- btRigidBody* rb1 = static_cast<btRigidBody*>(manifold->getBody1());
+ const btRigidBody* rb0 = static_cast<const btRigidBody*>(manifold->getBody0());
+ const btRigidBody* rb1 = static_cast<const btRigidBody*>(manifold->getBody1());
if (m_debugDrawer && (m_debugDrawer->getDebugMode() & btIDebugDraw::DBG_DrawContactPoints))
{
for (int j=0;j<numContacts;j++)
@@ -2223,8 +2223,8 @@ void CcdPhysicsEnvironment::CallbackTriggers()
m_debugDrawer->drawContactPoint(cp.m_positionWorldOnB,cp.m_normalWorldOnB,cp.getDistance(),cp.getLifeTime(),color);
}
}
- btRigidBody* obj0 = rb0;
- btRigidBody* obj1 = rb1;
+ const btRigidBody* obj0 = rb0;
+ const btRigidBody* obj1 = rb1;
//m_internalOwner is set in 'addPhysicsController'
CcdPhysicsController* ctrl0 = static_cast<CcdPhysicsController*>(obj0->getUserPointer());
diff --git a/source/gameengine/Rasterizer/RAS_2DFilterManager.cpp b/source/gameengine/Rasterizer/RAS_2DFilterManager.cpp
index ab0f62c84c7..e093b7cd722 100644
--- a/source/gameengine/Rasterizer/RAS_2DFilterManager.cpp
+++ b/source/gameengine/Rasterizer/RAS_2DFilterManager.cpp
@@ -435,6 +435,9 @@ void RAS_2DFilterManager::RenderFilters(RAS_ICanvas* canvas)
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
// if the last rendered face had alpha add it would messes with the color of the plane we apply 2DFilter to
glDisable(GL_BLEND);
+ // fix for [#34523] alpha buffer is now available for all OSs
+ glDisable(GL_ALPHA_TEST);
+
glPushMatrix(); //GL_MODELVIEW
glLoadIdentity(); // GL_MODELVIEW
glMatrixMode(GL_TEXTURE);
@@ -465,7 +468,8 @@ void RAS_2DFilterManager::RenderFilters(RAS_ICanvas* canvas)
}
glEnable(GL_DEPTH_TEST);
- canvas->SetViewPort(viewport[0],viewport[1],viewport[2],viewport[3]);
+ //We can't pass the results of canvas->GetViewPort() directly because canvas->SetViewPort() does some extra math [#34517]
+ canvas->SetViewPort(0, 0, viewport[2]-1, viewport[3]-1);
EndShaderProgram();
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
diff --git a/source/tests/bl_pyapi_mathutils.py b/source/tests/bl_pyapi_mathutils.py
index a37f74463ee..1754644e813 100644
--- a/source/tests/bl_pyapi_mathutils.py
+++ b/source/tests/bl_pyapi_mathutils.py
@@ -89,7 +89,7 @@ class MatrixTesting(unittest.TestCase):
(19, 26, 33),
(29, 40, 51)))
- self.assertEqual(mat1*mat2, prod_mat1)
+ self.assertEqual(mat1 * mat2, prod_mat1)
self.assertEqual(mat2 * mat1, prod_mat2)
def test_mat4x4_vec3D_mult(self):
diff --git a/source/tests/bl_run_operators.py b/source/tests/bl_run_operators.py
index 0202f7c64fb..e6f1cc56eb0 100644
--- a/source/tests/bl_run_operators.py
+++ b/source/tests/bl_run_operators.py
@@ -139,7 +139,9 @@ if USE_ATTRSET:
if subvalue == parent:
continue
-
+ # grr, recursive!
+ if prop == "point_caches":
+ continue
subvalue_type = type(subvalue)
yield value, prop, subvalue_type
subvalue_id = getattr(subvalue, "id_data", Ellipsis)