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:
authorAlexander Pinzon <apinzonf@gmail.com>2013-08-14 23:49:37 +0400
committerAlexander Pinzon <apinzonf@gmail.com>2013-08-14 23:49:37 +0400
commit54741c2311f0c01885f8b4a818b11cea38f7085d (patch)
tree6326ea3ef022e11a2592423257f59a892aaa7174 /source
parent0b09beb16702af4acfd7d591dc6d3b2b8f8098b3 (diff)
parent503b7d5b9a385fdcd220df3142857300d912d80c (diff)
svn merge ^/trunk/blender 58498:59138
Diffstat (limited to 'source')
-rw-r--r--source/blender/avi/intern/avi.c12
-rw-r--r--source/blender/avi/intern/avi_mjpeg.c49
-rw-r--r--source/blender/blenfont/BLF_api.h4
-rw-r--r--source/blender/blenfont/intern/blf_glyph.c2
-rw-r--r--source/blender/blenkernel/BKE_DerivedMesh.h11
-rw-r--r--source/blender/blenkernel/BKE_blender.h5
-rw-r--r--source/blender/blenkernel/BKE_bmesh.h98
-rw-r--r--source/blender/blenkernel/BKE_context.h4
-rw-r--r--source/blender/blenkernel/BKE_curve.h11
-rw-r--r--source/blender/blenkernel/BKE_global.h1
-rw-r--r--source/blender/blenkernel/BKE_image.h2
-rw-r--r--source/blender/blenkernel/BKE_material.h6
-rw-r--r--source/blender/blenkernel/BKE_mesh.h3
-rw-r--r--source/blender/blenkernel/BKE_node.h63
-rw-r--r--source/blender/blenkernel/BKE_pbvh.h2
-rw-r--r--source/blender/blenkernel/BKE_screen.h1
-rw-r--r--source/blender/blenkernel/BKE_sequencer.h8
-rw-r--r--source/blender/blenkernel/CMakeLists.txt1
-rw-r--r--source/blender/blenkernel/intern/DerivedMesh.c11
-rw-r--r--source/blender/blenkernel/intern/action.c8
-rw-r--r--source/blender/blenkernel/intern/anim.c2
-rw-r--r--source/blender/blenkernel/intern/anim_sys.c2
-rw-r--r--source/blender/blenkernel/intern/armature.c11
-rw-r--r--source/blender/blenkernel/intern/blender.c2
-rw-r--r--source/blender/blenkernel/intern/camera.c29
-rw-r--r--source/blender/blenkernel/intern/cdderivedmesh.c73
-rw-r--r--source/blender/blenkernel/intern/cloth.c1
-rw-r--r--source/blender/blenkernel/intern/constraint.c8
-rw-r--r--source/blender/blenkernel/intern/context.c4
-rw-r--r--source/blender/blenkernel/intern/curve.c307
-rw-r--r--source/blender/blenkernel/intern/customdata.c57
-rw-r--r--source/blender/blenkernel/intern/deform.c4
-rw-r--r--source/blender/blenkernel/intern/dynamicpaint.c24
-rw-r--r--source/blender/blenkernel/intern/editderivedmesh.c362
-rw-r--r--source/blender/blenkernel/intern/fmodifier.c16
-rw-r--r--source/blender/blenkernel/intern/image.c11
-rw-r--r--source/blender/blenkernel/intern/image_gen.c2
-rw-r--r--source/blender/blenkernel/intern/key.c17
-rw-r--r--source/blender/blenkernel/intern/library.c11
-rw-r--r--source/blender/blenkernel/intern/mask.c4
-rw-r--r--source/blender/blenkernel/intern/material.c153
-rw-r--r--source/blender/blenkernel/intern/mesh.c34
-rw-r--r--source/blender/blenkernel/intern/mesh_validate.c2
-rw-r--r--source/blender/blenkernel/intern/modifiers_bmesh.c7
-rw-r--r--source/blender/blenkernel/intern/movieclip.c12
-rw-r--r--source/blender/blenkernel/intern/multires.c36
-rw-r--r--source/blender/blenkernel/intern/navmesh_conversion.c3
-rw-r--r--source/blender/blenkernel/intern/node.c4
-rw-r--r--source/blender/blenkernel/intern/object.c32
-rw-r--r--source/blender/blenkernel/intern/packedFile.c15
-rw-r--r--source/blender/blenkernel/intern/particle.c4
-rw-r--r--source/blender/blenkernel/intern/pbvh.c50
-rw-r--r--source/blender/blenkernel/intern/pbvh_bmesh.c7
-rw-r--r--source/blender/blenkernel/intern/pbvh_intern.h4
-rw-r--r--source/blender/blenkernel/intern/pointcache.c13
-rw-r--r--source/blender/blenkernel/intern/property.c6
-rw-r--r--source/blender/blenkernel/intern/screen.c5
-rw-r--r--source/blender/blenkernel/intern/sequencer.c135
-rw-r--r--source/blender/blenkernel/intern/shrinkwrap.c4
-rw-r--r--source/blender/blenkernel/intern/sketch.c2
-rw-r--r--source/blender/blenkernel/intern/smoke.c17
-rw-r--r--source/blender/blenkernel/intern/sound.c4
-rw-r--r--source/blender/blenkernel/intern/subsurf_ccg.c35
-rw-r--r--source/blender/blenkernel/intern/text.c18
-rw-r--r--source/blender/blenkernel/intern/texture.c36
-rw-r--r--source/blender/blenkernel/intern/tracking.c68
-rw-r--r--source/blender/blenlib/BLI_alloca.h46
-rw-r--r--source/blender/blenlib/BLI_array.h44
-rw-r--r--source/blender/blenlib/BLI_bitmap.h4
-rw-r--r--source/blender/blenlib/BLI_buffer.h4
-rw-r--r--source/blender/blenlib/BLI_ghash.h2
-rw-r--r--source/blender/blenlib/BLI_math_base.h8
-rw-r--r--source/blender/blenlib/BLI_math_geom.h12
-rw-r--r--source/blender/blenlib/BLI_math_matrix.h19
-rw-r--r--source/blender/blenlib/BLI_math_vector.h98
-rw-r--r--source/blender/blenlib/BLI_memarena.h2
-rw-r--r--source/blender/blenlib/BLI_mempool.h24
-rw-r--r--source/blender/blenlib/BLI_path_util.h13
-rw-r--r--source/blender/blenlib/BLI_string.h10
-rw-r--r--source/blender/blenlib/BLI_string_utf8.h60
-rw-r--r--source/blender/blenlib/BLI_utildefines.h7
-rw-r--r--source/blender/blenlib/CMakeLists.txt1
-rw-r--r--source/blender/blenlib/intern/BLI_array.c42
-rw-r--r--source/blender/blenlib/intern/BLI_ghash.c3
-rw-r--r--source/blender/blenlib/intern/BLI_heap.c6
-rw-r--r--source/blender/blenlib/intern/BLI_kdtree.c2
-rw-r--r--source/blender/blenlib/intern/BLI_mempool.c37
-rw-r--r--source/blender/blenlib/intern/buffer.c9
-rw-r--r--source/blender/blenlib/intern/fileops.c12
-rw-r--r--source/blender/blenlib/intern/math_geom.c271
-rw-r--r--source/blender/blenlib/intern/math_matrix.c54
-rw-r--r--source/blender/blenlib/intern/math_vector_inline.c15
-rw-r--r--source/blender/blenlib/intern/path_util.c53
-rw-r--r--source/blender/blenlib/intern/scanfill.c8
-rw-r--r--source/blender/blenlib/intern/storage.c9
-rw-r--r--source/blender/blenlib/intern/string.c67
-rw-r--r--source/blender/blenlib/intern/string_utf8.c8
-rw-r--r--source/blender/blenlib/intern/voronoi.c4
-rw-r--r--source/blender/blenloader/intern/readfile.c188
-rw-r--r--source/blender/blenloader/intern/runtime.c4
-rw-r--r--source/blender/blenloader/intern/writefile.c64
-rw-r--r--source/blender/bmesh/CMakeLists.txt7
-rw-r--r--source/blender/bmesh/bmesh.h1
-rw-r--r--source/blender/bmesh/intern/bmesh_construct.c51
-rw-r--r--source/blender/bmesh/intern/bmesh_construct.h1
-rw-r--r--source/blender/bmesh/intern/bmesh_core.c82
-rw-r--r--source/blender/bmesh/intern/bmesh_core.h8
-rw-r--r--source/blender/bmesh/intern/bmesh_edgeloop.c2
-rw-r--r--source/blender/bmesh/intern/bmesh_interp.c5
-rw-r--r--source/blender/bmesh/intern/bmesh_marking.c124
-rw-r--r--source/blender/bmesh/intern/bmesh_marking.h7
-rw-r--r--source/blender/bmesh/intern/bmesh_mesh_conv.c29
-rw-r--r--source/blender/bmesh/intern/bmesh_mods.c29
-rw-r--r--source/blender/bmesh/intern/bmesh_opdefines.c59
-rw-r--r--source/blender/bmesh/intern/bmesh_operators.c9
-rw-r--r--source/blender/bmesh/intern/bmesh_operators.h2
-rw-r--r--source/blender/bmesh/intern/bmesh_operators_private.h2
-rw-r--r--source/blender/bmesh/intern/bmesh_polygon.c77
-rw-r--r--source/blender/bmesh/intern/bmesh_polygon.h10
-rw-r--r--source/blender/bmesh/intern/bmesh_private.h4
-rw-r--r--source/blender/bmesh/intern/bmesh_queries.c293
-rw-r--r--source/blender/bmesh/intern/bmesh_queries.h51
-rw-r--r--source/blender/bmesh/intern/bmesh_structure.c69
-rw-r--r--source/blender/bmesh/intern/bmesh_structure.h23
-rw-r--r--source/blender/bmesh/intern/bmesh_walkers.c7
-rw-r--r--source/blender/bmesh/operators/bmo_beautify.c8
-rw-r--r--source/blender/bmesh/operators/bmo_bridge.c14
-rw-r--r--source/blender/bmesh/operators/bmo_connect.c2
-rw-r--r--source/blender/bmesh/operators/bmo_connect_nonplanar.c229
-rw-r--r--source/blender/bmesh/operators/bmo_connect_pair.c18
-rw-r--r--source/blender/bmesh/operators/bmo_create.c2
-rw-r--r--source/blender/bmesh/operators/bmo_dissolve.c9
-rw-r--r--source/blender/bmesh/operators/bmo_dupe.c42
-rw-r--r--source/blender/bmesh/operators/bmo_edgenet.c176
-rw-r--r--source/blender/bmesh/operators/bmo_fill_holes.c137
-rw-r--r--source/blender/bmesh/operators/bmo_inset.c6
-rw-r--r--source/blender/bmesh/operators/bmo_join_triangles.c161
-rw-r--r--source/blender/bmesh/operators/bmo_normals.c7
-rw-r--r--source/blender/bmesh/operators/bmo_smooth_laplacian.c2
-rw-r--r--source/blender/bmesh/operators/bmo_split_edges.c3
-rw-r--r--source/blender/bmesh/operators/bmo_subdivide.c38
-rw-r--r--source/blender/bmesh/operators/bmo_subdivide_edgering.c7
-rw-r--r--source/blender/bmesh/operators/bmo_utils.c32
-rw-r--r--source/blender/bmesh/operators/bmo_wireframe.c4
-rw-r--r--source/blender/bmesh/tools/BME_bevel.c1160
-rw-r--r--source/blender/bmesh/tools/bmesh_bevel.c1
-rw-r--r--source/blender/bmesh/tools/bmesh_decimate.h3
-rw-r--r--source/blender/bmesh/tools/bmesh_decimate_collapse.c2
-rw-r--r--source/blender/bmesh/tools/bmesh_decimate_dissolve.c357
-rw-r--r--source/blender/bmesh/tools/bmesh_edgesplit.c71
-rw-r--r--source/blender/bmesh/tools/bmesh_edgesplit.h2
-rw-r--r--source/blender/bmesh/tools/bmesh_triangulate.c2
-rw-r--r--source/blender/collada/ArmatureImporter.cpp30
-rw-r--r--source/blender/collada/DocumentImporter.cpp46
-rw-r--r--source/blender/collada/MeshImporter.cpp7
-rw-r--r--source/blender/collada/SkinInfo.cpp4
-rw-r--r--source/blender/collada/TransformReader.cpp4
-rw-r--r--source/blender/collada/collada_internal.cpp46
-rw-r--r--source/blender/collada/collada_internal.h6
-rw-r--r--source/blender/collada/collada_utils.cpp65
-rw-r--r--source/blender/collada/collada_utils.h3
-rw-r--r--source/blender/compositor/CMakeLists.txt6
-rw-r--r--source/blender/compositor/COM_compositor.h2
-rw-r--r--source/blender/compositor/intern/COM_ExecutionGroup.cpp2
-rw-r--r--source/blender/compositor/intern/COM_ExecutionSystemHelper.cpp4
-rw-r--r--source/blender/compositor/intern/COM_SocketReader.h6
-rw-r--r--source/blender/compositor/intern/COM_WorkScheduler.cpp2
-rw-r--r--source/blender/compositor/nodes/COM_RenderLayersNode.cpp3
-rw-r--r--source/blender/compositor/nodes/COM_SplitViewerNode.cpp45
-rw-r--r--source/blender/compositor/operations/COM_ConvertColorToBWOperation.cpp2
-rw-r--r--source/blender/compositor/operations/COM_ConvertColorToValueProg.cpp2
-rw-r--r--source/blender/compositor/operations/COM_MathBaseOperation.cpp72
-rw-r--r--source/blender/compositor/operations/COM_MixAddOperation.cpp1
-rw-r--r--source/blender/compositor/operations/COM_MixBurnOperation.cpp9
-rw-r--r--source/blender/compositor/operations/COM_MixColorOperation.cpp9
-rw-r--r--source/blender/compositor/operations/COM_MixDarkenOperation.cpp9
-rw-r--r--source/blender/compositor/operations/COM_MixDifferenceOperation.cpp11
-rw-r--r--source/blender/compositor/operations/COM_MixDivideOperation.cpp11
-rw-r--r--source/blender/compositor/operations/COM_MixDodgeOperation.cpp9
-rw-r--r--source/blender/compositor/operations/COM_MixHueOperation.cpp9
-rw-r--r--source/blender/compositor/operations/COM_MixLightenOperation.cpp11
-rw-r--r--source/blender/compositor/operations/COM_MixLinearLightOperation.cpp13
-rw-r--r--source/blender/compositor/operations/COM_MixOverlayOperation.cpp9
-rw-r--r--source/blender/compositor/operations/COM_MixSaturationOperation.cpp9
-rw-r--r--source/blender/compositor/operations/COM_MixScreenOperation.cpp10
-rw-r--r--source/blender/compositor/operations/COM_MixSoftLightOperation.cpp9
-rw-r--r--source/blender/compositor/operations/COM_MixSubtractOperation.cpp9
-rw-r--r--source/blender/compositor/operations/COM_MixValueOperation.cpp9
-rw-r--r--source/blender/compositor/operations/COM_SplitOperation.cpp (renamed from source/blender/compositor/operations/COM_SplitViewerOperation.cpp)55
-rw-r--r--source/blender/compositor/operations/COM_SplitOperation.h (renamed from source/blender/compositor/operations/COM_SplitViewerOperation.h)15
-rw-r--r--source/blender/compositor/operations/COM_ViewerBaseOperation.cpp123
-rw-r--r--source/blender/compositor/operations/COM_ViewerBaseOperation.h75
-rw-r--r--source/blender/compositor/operations/COM_ViewerOperation.cpp81
-rw-r--r--source/blender/compositor/operations/COM_ViewerOperation.h42
-rw-r--r--source/blender/editors/animation/anim_intern.h4
-rw-r--r--source/blender/editors/animation/anim_markers.c4
-rw-r--r--source/blender/editors/animation/keyframes_draw.c8
-rw-r--r--source/blender/editors/animation/keyframes_general.c3
-rw-r--r--source/blender/editors/armature/armature_edit.c10
-rw-r--r--source/blender/editors/armature/armature_relations.c9
-rw-r--r--source/blender/editors/armature/armature_select.c8
-rw-r--r--source/blender/editors/armature/armature_skinning.c2
-rw-r--r--source/blender/editors/armature/armature_utils.c27
-rw-r--r--source/blender/editors/armature/pose_edit.c3
-rw-r--r--source/blender/editors/armature/pose_select.c2
-rw-r--r--source/blender/editors/armature/pose_transform.c2
-rw-r--r--source/blender/editors/armature/pose_utils.c2
-rw-r--r--source/blender/editors/curve/curve_intern.h2
-rw-r--r--source/blender/editors/curve/curve_ops.c2
-rw-r--r--source/blender/editors/curve/editcurve.c210
-rw-r--r--source/blender/editors/curve/editfont.c34
-rw-r--r--source/blender/editors/include/BIF_glutil.h1
-rw-r--r--source/blender/editors/include/ED_armature.h4
-rw-r--r--source/blender/editors/include/ED_transform.h18
-rw-r--r--source/blender/editors/include/UI_interface.h12
-rw-r--r--source/blender/editors/interface/interface.c85
-rw-r--r--source/blender/editors/interface/interface_draw.c2
-rw-r--r--source/blender/editors/interface/interface_handlers.c74
-rw-r--r--source/blender/editors/interface/interface_intern.h2
-rw-r--r--source/blender/editors/interface/interface_layout.c6
-rw-r--r--source/blender/editors/interface/interface_ops.c14
-rw-r--r--source/blender/editors/interface/interface_regions.c12
-rw-r--r--source/blender/editors/interface/interface_templates.c8
-rw-r--r--source/blender/editors/interface/resources.c4
-rw-r--r--source/blender/editors/interface/view2d_ops.c2
-rw-r--r--source/blender/editors/mask/mask_draw.c2
-rw-r--r--source/blender/editors/mask/mask_ops.c2
-rw-r--r--source/blender/editors/mask/mask_select.c7
-rw-r--r--source/blender/editors/mesh/editface.c112
-rw-r--r--source/blender/editors/mesh/editmesh_add.c53
-rw-r--r--source/blender/editors/mesh/editmesh_extrude.c33
-rw-r--r--source/blender/editors/mesh/editmesh_knife.c31
-rw-r--r--source/blender/editors/mesh/editmesh_loopcut.c4
-rw-r--r--source/blender/editors/mesh/editmesh_rip.c41
-rw-r--r--source/blender/editors/mesh/editmesh_select.c20
-rw-r--r--source/blender/editors/mesh/editmesh_tools.c249
-rw-r--r--source/blender/editors/mesh/editmesh_utils.c13
-rw-r--r--source/blender/editors/mesh/mesh_data.c2
-rw-r--r--source/blender/editors/mesh/mesh_intern.h6
-rw-r--r--source/blender/editors/mesh/mesh_navmesh.c2
-rw-r--r--source/blender/editors/mesh/mesh_ops.c6
-rw-r--r--source/blender/editors/mesh/meshtools.c4
-rw-r--r--source/blender/editors/object/object_add.c10
-rw-r--r--source/blender/editors/object/object_bake.c23
-rw-r--r--source/blender/editors/object/object_edit.c10
-rw-r--r--source/blender/editors/object/object_group.c92
-rw-r--r--source/blender/editors/object/object_hook.c4
-rw-r--r--source/blender/editors/object/object_lattice.c4
-rw-r--r--source/blender/editors/object/object_modifier.c18
-rw-r--r--source/blender/editors/object/object_relations.c2
-rw-r--r--source/blender/editors/object/object_vgroup.c1
-rw-r--r--source/blender/editors/render/render_internal.c4
-rw-r--r--source/blender/editors/render/render_opengl.c12
-rw-r--r--source/blender/editors/render/render_preview.c2
-rw-r--r--source/blender/editors/render/render_shading.c4
-rw-r--r--source/blender/editors/screen/area.c21
-rw-r--r--source/blender/editors/screen/screen_edit.c9
-rw-r--r--source/blender/editors/screen/screen_ops.c13
-rw-r--r--source/blender/editors/sculpt_paint/paint_hide.c4
-rw-r--r--source/blender/editors/sculpt_paint/paint_image_proj.c23
-rw-r--r--source/blender/editors/sculpt_paint/paint_ops.c4
-rw-r--r--source/blender/editors/sculpt_paint/paint_stroke.c4
-rw-r--r--source/blender/editors/sculpt_paint/paint_utils.c2
-rw-r--r--source/blender/editors/sculpt_paint/paint_vertex.c14
-rw-r--r--source/blender/editors/sculpt_paint/paint_vertex_proj.c4
-rw-r--r--source/blender/editors/sculpt_paint/sculpt.c28
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_intern.h4
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_undo.c8
-rw-r--r--source/blender/editors/space_buttons/space_buttons.c1
-rw-r--r--source/blender/editors/space_clip/tracking_ops.c10
-rw-r--r--source/blender/editors/space_file/space_file.c4
-rw-r--r--source/blender/editors/space_graph/graph_buttons.c34
-rw-r--r--source/blender/editors/space_image/image_buttons.c8
-rw-r--r--source/blender/editors/space_logic/logic_buttons.c4
-rw-r--r--source/blender/editors/space_logic/logic_window.c7
-rw-r--r--source/blender/editors/space_nla/nla_buttons.c10
-rw-r--r--source/blender/editors/space_node/drawnode.c10
-rw-r--r--source/blender/editors/space_node/node_add.c65
-rw-r--r--source/blender/editors/space_node/node_buttons.c4
-rw-r--r--source/blender/editors/space_node/node_edit.c4
-rw-r--r--source/blender/editors/space_node/node_intern.h1
-rw-r--r--source/blender/editors/space_node/node_ops.c1
-rw-r--r--source/blender/editors/space_node/node_relationships.c4
-rw-r--r--source/blender/editors/space_node/node_select.c2
-rw-r--r--source/blender/editors/space_node/node_toolbar.c4
-rw-r--r--source/blender/editors/space_node/node_view.c4
-rw-r--r--source/blender/editors/space_node/space_node.c22
-rw-r--r--source/blender/editors/space_outliner/outliner_draw.c85
-rw-r--r--source/blender/editors/space_outliner/outliner_edit.c31
-rw-r--r--source/blender/editors/space_outliner/outliner_intern.h19
-rw-r--r--source/blender/editors/space_outliner/outliner_select.c4
-rw-r--r--source/blender/editors/space_outliner/outliner_tools.c9
-rw-r--r--source/blender/editors/space_outliner/outliner_tree.c216
-rw-r--r--source/blender/editors/space_outliner/space_outliner.c14
-rw-r--r--source/blender/editors/space_sequencer/sequencer_buttons.c4
-rw-r--r--source/blender/editors/space_sequencer/sequencer_edit.c29
-rw-r--r--source/blender/editors/space_time/space_time.c5
-rw-r--r--source/blender/editors/space_view3d/drawarmature.c18
-rw-r--r--source/blender/editors/space_view3d/drawmesh.c6
-rw-r--r--source/blender/editors/space_view3d/drawobject.c105
-rw-r--r--source/blender/editors/space_view3d/drawvolume.c8
-rw-r--r--source/blender/editors/space_view3d/space_view3d.c39
-rw-r--r--source/blender/editors/space_view3d/view3d_buttons.c39
-rw-r--r--source/blender/editors/space_view3d/view3d_draw.c28
-rw-r--r--source/blender/editors/space_view3d/view3d_edit.c34
-rw-r--r--source/blender/editors/space_view3d/view3d_iterators.c6
-rw-r--r--source/blender/editors/space_view3d/view3d_select.c13
-rw-r--r--source/blender/editors/space_view3d/view3d_snap.c30
-rw-r--r--source/blender/editors/space_view3d/view3d_toolbar.c6
-rw-r--r--source/blender/editors/space_view3d/view3d_view.c110
-rw-r--r--source/blender/editors/transform/transform.c37
-rw-r--r--source/blender/editors/transform/transform.h2
-rw-r--r--source/blender/editors/transform/transform_conversions.c264
-rw-r--r--source/blender/editors/transform/transform_orientations.c172
-rw-r--r--source/blender/editors/util/crazyspace.c19
-rw-r--r--source/blender/editors/uvedit/uvedit_draw.c70
-rw-r--r--source/blender/editors/uvedit/uvedit_ops.c3
-rw-r--r--source/blender/editors/uvedit/uvedit_parametrizer.c6
-rw-r--r--source/blender/editors/uvedit/uvedit_unwrap_ops.c4
-rw-r--r--source/blender/freestyle/intern/application/AppView.h1
-rw-r--r--source/blender/freestyle/intern/application/Controller.h1
-rw-r--r--source/blender/freestyle/intern/blender_interface/BlenderFileLoader.h1
-rw-r--r--source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.h5
-rw-r--r--source/blender/freestyle/intern/blender_interface/BlenderStyleModule.h5
-rw-r--r--source/blender/freestyle/intern/blender_interface/BlenderTextureManager.h5
-rw-r--r--source/blender/freestyle/intern/geometry/BBox.h1
-rw-r--r--source/blender/freestyle/intern/geometry/FastGrid.h5
-rw-r--r--source/blender/freestyle/intern/geometry/FitCurve.cpp2
-rw-r--r--source/blender/freestyle/intern/geometry/Grid.h3
-rw-r--r--source/blender/freestyle/intern/geometry/Noise.h1
-rw-r--r--source/blender/freestyle/intern/geometry/Polygon.h1
-rw-r--r--source/blender/freestyle/intern/geometry/SweepLine.h2
-rw-r--r--source/blender/freestyle/intern/geometry/VecMat.h2
-rw-r--r--source/blender/freestyle/intern/geometry/normal_cycle.h1
-rw-r--r--source/blender/freestyle/intern/image/GaussianFilter.h1
-rw-r--r--source/blender/freestyle/intern/image/Image.h1
-rw-r--r--source/blender/freestyle/intern/python/Interface0D/BPy_CurvePoint.cpp4
-rw-r--r--source/blender/freestyle/intern/python/Interface0D/BPy_SVertex.cpp1
-rw-r--r--source/blender/freestyle/intern/scene_graph/DrawingStyle.h1
-rw-r--r--source/blender/freestyle/intern/scene_graph/FrsMaterial.h1
-rw-r--r--source/blender/freestyle/intern/scene_graph/IndexedFaceSet.h5
-rw-r--r--source/blender/freestyle/intern/scene_graph/LineRep.h5
-rw-r--r--source/blender/freestyle/intern/scene_graph/Node.h5
-rw-r--r--source/blender/freestyle/intern/scene_graph/NodeCamera.h15
-rw-r--r--source/blender/freestyle/intern/scene_graph/NodeDrawingStyle.h5
-rw-r--r--source/blender/freestyle/intern/stroke/Module.h1
-rw-r--r--source/blender/freestyle/intern/stroke/Operators.h1
-rw-r--r--source/blender/freestyle/intern/stroke/Predicates0D.h2
-rw-r--r--source/blender/freestyle/intern/stroke/Stroke.h1
-rw-r--r--source/blender/freestyle/intern/stroke/StrokeRenderer.h1
-rw-r--r--source/blender/freestyle/intern/stroke/StrokeRep.cpp8
-rw-r--r--source/blender/freestyle/intern/stroke/StrokeRep.h1
-rw-r--r--source/blender/freestyle/intern/stroke/StrokeTesselator.h1
-rw-r--r--source/blender/freestyle/intern/stroke/StyleModule.h1
-rw-r--r--source/blender/freestyle/intern/system/BaseIterator.h1
-rw-r--r--source/blender/freestyle/intern/system/BaseObject.h1
-rw-r--r--source/blender/freestyle/intern/system/Exception.h1
-rw-r--r--source/blender/freestyle/intern/system/Id.h1
-rw-r--r--source/blender/freestyle/intern/system/Interpreter.h1
-rw-r--r--source/blender/freestyle/intern/system/ProgressBar.h1
-rw-r--r--source/blender/freestyle/intern/system/PseudoNoise.h1
-rw-r--r--source/blender/freestyle/intern/system/RandGen.h1
-rw-r--r--source/blender/freestyle/intern/system/RenderMonitor.h1
-rw-r--r--source/blender/freestyle/intern/system/TimeStamp.h1
-rw-r--r--source/blender/freestyle/intern/system/TimeUtils.h1
-rw-r--r--source/blender/freestyle/intern/view_map/BoxGrid.h3
-rw-r--r--source/blender/freestyle/intern/view_map/FEdgeXDetector.h1
-rw-r--r--source/blender/freestyle/intern/view_map/Functions1D.h2
-rw-r--r--source/blender/freestyle/intern/view_map/GridDensityProvider.h1
-rw-r--r--source/blender/freestyle/intern/view_map/Interface1D.h1
-rw-r--r--source/blender/freestyle/intern/view_map/OccluderSource.h1
-rw-r--r--source/blender/freestyle/intern/view_map/SphericalGrid.h2
-rw-r--r--source/blender/freestyle/intern/view_map/SteerableViewMap.cpp2
-rw-r--r--source/blender/freestyle/intern/view_map/SteerableViewMap.h1
-rw-r--r--source/blender/freestyle/intern/view_map/ViewEdgeXBuilder.h1
-rw-r--r--source/blender/freestyle/intern/view_map/ViewMap.h20
-rw-r--r--source/blender/freestyle/intern/view_map/ViewMapBuilder.h1
-rw-r--r--source/blender/freestyle/intern/view_map/ViewMapIO.cpp4
-rw-r--r--source/blender/freestyle/intern/view_map/ViewMapIterators.h15
-rw-r--r--source/blender/freestyle/intern/view_map/ViewMapTesselator.h11
-rw-r--r--source/blender/freestyle/intern/winged_edge/WEdge.h4
-rw-r--r--source/blender/freestyle/intern/winged_edge/WFillGrid.h1
-rw-r--r--source/blender/freestyle/intern/winged_edge/WSFillGrid.h7
-rw-r--r--source/blender/freestyle/intern/winged_edge/WXEdge.h20
-rw-r--r--source/blender/freestyle/intern/winged_edge/WXEdgeBuilder.h5
-rw-r--r--source/blender/freestyle/intern/winged_edge/WingedEdgeBuilder.h7
-rw-r--r--source/blender/gpu/GPU_buffers.h1
-rw-r--r--source/blender/gpu/intern/gpu_buffers.c28
-rw-r--r--source/blender/gpu/intern/gpu_draw.c3
-rw-r--r--source/blender/gpu/intern/gpu_extensions.c2
-rw-r--r--source/blender/imbuf/intern/bmp.c43
-rw-r--r--source/blender/imbuf/intern/colormanagement.c6
-rw-r--r--source/blender/imbuf/intern/indexer.c4
-rw-r--r--source/blender/imbuf/intern/thumbs.c37
-rw-r--r--source/blender/imbuf/intern/util.c8
-rw-r--r--source/blender/makesdna/DNA_dynamicpaint_types.h3
-rw-r--r--source/blender/makesdna/DNA_image_types.h2
-rw-r--r--source/blender/makesdna/DNA_mesh_types.h1
-rw-r--r--source/blender/makesdna/DNA_modifier_types.h32
-rw-r--r--source/blender/makesdna/DNA_node_types.h15
-rw-r--r--source/blender/makesdna/DNA_outliner_types.h9
-rw-r--r--source/blender/makesdna/DNA_scene_types.h67
-rw-r--r--source/blender/makesdna/DNA_sound_types.h1
-rw-r--r--source/blender/makesdna/DNA_space_types.h5
-rw-r--r--source/blender/makesrna/SConscript4
-rw-r--r--source/blender/makesrna/intern/CMakeLists.txt5
-rw-r--r--source/blender/makesrna/intern/SConscript6
-rw-r--r--source/blender/makesrna/intern/makesrna.c113
-rw-r--r--source/blender/makesrna/intern/rna_ID.c40
-rw-r--r--source/blender/makesrna/intern/rna_access.c11
-rw-r--r--source/blender/makesrna/intern/rna_armature.c11
-rw-r--r--source/blender/makesrna/intern/rna_brush.c6
-rw-r--r--source/blender/makesrna/intern/rna_color.c1
-rw-r--r--source/blender/makesrna/intern/rna_define.c22
-rw-r--r--source/blender/makesrna/intern/rna_dynamicpaint.c6
-rw-r--r--source/blender/makesrna/intern/rna_gpencil.c8
-rw-r--r--source/blender/makesrna/intern/rna_internal.h1
-rw-r--r--source/blender/makesrna/intern/rna_mesh.c1
-rw-r--r--source/blender/makesrna/intern/rna_meta.c17
-rw-r--r--source/blender/makesrna/intern/rna_modifier.c30
-rw-r--r--source/blender/makesrna/intern/rna_nodetree.c38
-rw-r--r--source/blender/makesrna/intern/rna_object_api.c19
-rw-r--r--source/blender/makesrna/intern/rna_object_force.c1
-rw-r--r--source/blender/makesrna/intern/rna_render.c3
-rw-r--r--source/blender/makesrna/intern/rna_scene.c32
-rw-r--r--source/blender/modifiers/intern/MOD_bevel.c55
-rw-r--r--source/blender/modifiers/intern/MOD_boolean_util.c4
-rw-r--r--source/blender/modifiers/intern/MOD_cloth.c6
-rw-r--r--source/blender/modifiers/intern/MOD_decimate.c2
-rw-r--r--source/blender/modifiers/intern/MOD_edgesplit.c3
-rw-r--r--source/blender/modifiers/intern/MOD_laplaciansmooth.c2
-rw-r--r--source/blender/modifiers/intern/MOD_mirror.c1
-rw-r--r--source/blender/modifiers/intern/MOD_ocean.c13
-rw-r--r--source/blender/modifiers/intern/MOD_simpledeform.c13
-rw-r--r--source/blender/modifiers/intern/MOD_skin.c8
-rw-r--r--source/blender/modifiers/intern/MOD_warp.c4
-rw-r--r--source/blender/modifiers/intern/MOD_weightvg_util.c5
-rw-r--r--source/blender/modifiers/intern/MOD_weightvgedit.c2
-rw-r--r--source/blender/modifiers/intern/MOD_weightvgproximity.c2
-rw-r--r--source/blender/nodes/CMakeLists.txt3
-rw-r--r--source/blender/nodes/NOD_shader.h4
-rw-r--r--source/blender/nodes/NOD_static_types.h4
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_image.c74
-rw-r--r--source/blender/nodes/intern/node_common.c37
-rw-r--r--source/blender/nodes/intern/node_exec.c4
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_blackbody.c54
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_light_path.c1
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_math.c1
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_sepcombHSV.c80
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_subsurface_scattering.c2
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_vectTransform.c66
-rw-r--r--source/blender/nodes/texture/node_texture_tree.c4
-rw-r--r--source/blender/nodes/texture/nodes/node_texture_output.c15
-rw-r--r--source/blender/python/bmesh/bmesh_py_ops.c4
-rw-r--r--source/blender/python/bmesh/bmesh_py_types_meshdata.c2
-rw-r--r--source/blender/python/bmesh/bmesh_py_utils.c12
-rw-r--r--source/blender/python/intern/bpy_rna.c2
-rw-r--r--source/blender/quicktime/apple/quicktime_export.c10
-rw-r--r--source/blender/render/intern/include/zbuf.h12
-rw-r--r--source/blender/render/intern/raytrace/rayobject_octree.cpp2
-rw-r--r--source/blender/render/intern/source/bake.c2
-rw-r--r--source/blender/render/intern/source/convertblender.c104
-rw-r--r--source/blender/render/intern/source/envmap.c4
-rw-r--r--source/blender/render/intern/source/external_engine.c2
-rw-r--r--source/blender/render/intern/source/initrender.c4
-rw-r--r--source/blender/render/intern/source/multires_bake.c2
-rw-r--r--source/blender/render/intern/source/occlusion.c8
-rw-r--r--source/blender/render/intern/source/pipeline.c2
-rw-r--r--source/blender/render/intern/source/pointdensity.c77
-rw-r--r--source/blender/render/intern/source/rayshade.c18
-rw-r--r--source/blender/render/intern/source/render_result.c33
-rw-r--r--source/blender/render/intern/source/render_texture.c14
-rw-r--r--source/blender/render/intern/source/shadbuf.c4
-rw-r--r--source/blender/render/intern/source/strand.c2
-rw-r--r--source/blender/render/intern/source/voxeldata.c2
-rw-r--r--source/blender/render/intern/source/zbuf.c43
-rw-r--r--source/blender/windowmanager/WM_api.h4
-rw-r--r--source/blender/windowmanager/intern/wm_draw.c2
-rw-r--r--source/blender/windowmanager/intern/wm_event_system.c18
-rw-r--r--source/blender/windowmanager/intern/wm_keymap.c17
-rw-r--r--source/blender/windowmanager/intern/wm_operators.c14
-rw-r--r--source/blender/windowmanager/intern/wm_subwindow.c16
-rw-r--r--source/blender/windowmanager/intern/wm_window.c17
-rw-r--r--source/blender/windowmanager/wm_window.h2
-rw-r--r--source/blenderplayer/bad_level_call_stubs/stubs.c1
-rw-r--r--source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp16
-rw-r--r--source/gameengine/BlenderRoutines/KX_BlenderCanvas.cpp10
-rw-r--r--source/gameengine/BlenderRoutines/KX_BlenderCanvas.h10
-rw-r--r--source/gameengine/BlenderRoutines/KX_BlenderGL.cpp10
-rw-r--r--source/gameengine/BlenderRoutines/KX_BlenderGL.h2
-rw-r--r--source/gameengine/BlenderRoutines/KX_BlenderRenderTools.cpp8
-rw-r--r--source/gameengine/Converter/BL_ArmatureConstraint.cpp2
-rw-r--r--source/gameengine/Converter/KX_BlenderSceneConverter.cpp2
-rw-r--r--source/gameengine/Converter/KX_ConvertActuators.cpp14
-rw-r--r--source/gameengine/Converter/KX_ConvertSensors.cpp27
-rw-r--r--source/gameengine/Expressions/FloatValue.cpp9
-rw-r--r--source/gameengine/Expressions/IntValue.cpp9
-rw-r--r--source/gameengine/GamePlayer/common/GPC_RenderTools.cpp6
-rw-r--r--source/gameengine/GamePlayer/ghost/GPG_Application.cpp16
-rw-r--r--source/gameengine/GamePlayer/ghost/GPG_Canvas.cpp14
-rw-r--r--source/gameengine/GamePlayer/ghost/GPG_Canvas.h3
-rw-r--r--source/gameengine/GamePlayer/ghost/GPG_ghost.cpp15
-rw-r--r--source/gameengine/Ketsji/BL_ActionManager.cpp6
-rw-r--r--source/gameengine/Ketsji/KX_BlenderMaterial.cpp5
-rw-r--r--source/gameengine/Ketsji/KX_BlenderMaterial.h1
-rw-r--r--source/gameengine/Ketsji/KX_Camera.cpp30
-rw-r--r--source/gameengine/Ketsji/KX_Camera.h2
-rw-r--r--source/gameengine/Ketsji/KX_Dome.cpp20
-rw-r--r--source/gameengine/Ketsji/KX_KetsjiEngine.cpp6
-rw-r--r--source/gameengine/Ketsji/KX_KetsjiEngine.h5
-rw-r--r--source/gameengine/Ketsji/KX_MeshProxy.cpp13
-rw-r--r--source/gameengine/Ketsji/KX_NavMeshObject.cpp14
-rw-r--r--source/gameengine/Ketsji/KX_ObstacleSimulation.cpp197
-rw-r--r--source/gameengine/Ketsji/KX_PolyProxy.h6
-rw-r--r--source/gameengine/Ketsji/KX_PythonInit.cpp37
-rw-r--r--source/gameengine/Physics/Bullet/CcdPhysicsController.cpp39
-rw-r--r--source/gameengine/Rasterizer/RAS_2DFilterManager.cpp17
-rw-r--r--source/gameengine/Rasterizer/RAS_2DFilterManager.h2
-rw-r--r--source/gameengine/Rasterizer/RAS_ICanvas.h11
-rw-r--r--source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageIM.cpp1
-rw-r--r--source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageVA.cpp1
-rw-r--r--source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageVBO.cpp1
-rw-r--r--source/gameengine/SceneGraph/SG_Tree.cpp9
-rw-r--r--source/gameengine/VideoTexture/BlendType.h2
-rw-r--r--source/gameengine/VideoTexture/Exception.cpp2
-rw-r--r--source/gameengine/VideoTexture/FilterSource.h2
-rw-r--r--source/gameengine/VideoTexture/ImageMix.h2
-rw-r--r--source/gameengine/VideoTexture/ImageRender.cpp4
528 files changed, 7131 insertions, 5890 deletions
diff --git a/source/blender/avi/intern/avi.c b/source/blender/avi/intern/avi.c
index 48e64695822..dd52a27c022 100644
--- a/source/blender/avi/intern/avi.c
+++ b/source/blender/avi/intern/avi.c
@@ -811,12 +811,16 @@ AviError AVI_open_compress(char *name, AviMovie *movie, int streams, ...)
movie->streams[i].sh.fcc = FCC("strh");
movie->streams[i].sh.size = 56;
movie->streams[i].sh.Type = avi_get_format_type(movie->streams[i].format);
- if (movie->streams[i].sh.Type == 0)
+ if (movie->streams[i].sh.Type == 0) {
+ va_end(ap);
return AVI_ERROR_FORMAT;
+ }
movie->streams[i].sh.Handler = avi_get_format_fcc(movie->streams[i].format);
- if (movie->streams[i].sh.Handler == 0)
+ if (movie->streams[i].sh.Handler == 0) {
+ va_end(ap);
return AVI_ERROR_FORMAT;
+ }
movie->streams[i].sh.Flags = 0;
movie->streams[i].sh.Priority = 0;
@@ -950,6 +954,8 @@ AviError AVI_open_compress(char *name, AviMovie *movie, int streams, ...)
PUT_FCCN((header_pos2 - header_pos1 + 4L), movie->fp);
+ va_end(ap);
+
return AVI_ERROR_NONE;
}
@@ -969,7 +975,7 @@ AviError AVI_write_frame(AviMovie *movie, int frame_num, ...)
/* Allocate the new memory for the index entry */
- if (frame_num + 1 > movie->index_entries) {
+ if (frame_num >= movie->index_entries) {
const size_t entry_size = (movie->header->Streams + 1) * sizeof(AviIndexEntry);
movie->entries = (AviIndexEntry *)MEM_recallocN(movie->entries, (frame_num + 1) * entry_size);
movie->index_entries = frame_num + 1;
diff --git a/source/blender/avi/intern/avi_mjpeg.c b/source/blender/avi/intern/avi_mjpeg.c
index 91b8fa5a060..a2d48c724de 100644
--- a/source/blender/avi/intern/avi_mjpeg.c
+++ b/source/blender/avi/intern/avi_mjpeg.c
@@ -44,8 +44,6 @@
#include "avi_mjpeg.h"
-#define PADUP(num, amt) ((num + (amt - 1)) & ~(amt - 1))
-
static void jpegmemdestmgr_build(j_compress_ptr cinfo, unsigned char *buffer, int bufsize);
static void jpegmemsrcmgr_build(j_decompress_ptr dinfo, unsigned char *buffer, int bufsize);
@@ -294,56 +292,13 @@ static void deinterlace(int odd, unsigned char *to, unsigned char *from, int wid
static int check_and_decode_jpeg(unsigned char *inbuf, unsigned char *outbuf, int width, int height, int bufsize)
{
- /* JPEG's are always multiples of 16, extra is cropped out AVI's */
- if ((width & 0xF) || (height & 0xF)) {
- int i, rrowstride, jrowstride;
- int jwidth = PADUP(width, 16);
- int jheight = PADUP(height, 16);
- unsigned char *tmpbuf = MEM_mallocN(jwidth * jheight * 3, "avi.check_and_decode_jpeg");
- int ret = Decode_JPEG(inbuf, tmpbuf, jwidth, jheight, bufsize);
-
- /* crop the tmpbuf into the real buffer */
- rrowstride = width * 3;
- jrowstride = jwidth * 3;
- for (i = 0; i < height; i++)
- memcpy(&outbuf[i * rrowstride], &tmpbuf[i * jrowstride], rrowstride);
- MEM_freeN(tmpbuf);
-
- return ret;
- }
- else {
- return Decode_JPEG(inbuf, outbuf, width, height, bufsize);
- }
+ return Decode_JPEG(inbuf, outbuf, width, height, bufsize);
}
static void check_and_compress_jpeg(int quality, unsigned char *outbuf, const unsigned char *inbuf,
int width, int height, int bufsize)
{
- /* JPEG's are always multiples of 16, extra is ignored in AVI's */
- if ((width & 0xF) || (height & 0xF)) {
- int i, rrowstride, jrowstride;
- int jwidth = PADUP(width, 16);
- int jheight = PADUP(height, 16);
- unsigned char *tmpbuf = MEM_mallocN(jwidth * jheight * 3, "avi.check_and_compress_jpeg");
-
- /* resize the realbuf into the tmpbuf */
- rrowstride = width * 3;
- jrowstride = jwidth * 3;
- for (i = 0; i < jheight; i++) {
- if (i < height)
- memcpy(&tmpbuf[i * jrowstride], &inbuf[i * rrowstride], rrowstride);
- else
- memset(&tmpbuf[i * jrowstride], 0, rrowstride);
- memset(&tmpbuf[i * jrowstride + rrowstride], 0, jrowstride - rrowstride);
- }
-
- Compress_JPEG(quality, outbuf, tmpbuf, jwidth, jheight, bufsize);
-
- MEM_freeN(tmpbuf);
- }
- else {
- Compress_JPEG(quality, outbuf, inbuf, width, height, bufsize);
- }
+ Compress_JPEG(quality, outbuf, inbuf, width, height, bufsize);
}
void *avi_converter_from_mjpeg(AviMovie *movie, int stream, unsigned char *buffer, int *size)
diff --git a/source/blender/blenfont/BLF_api.h b/source/blender/blenfont/BLF_api.h
index fd8bd196717..8f77f8c984d 100644
--- a/source/blender/blenfont/BLF_api.h
+++ b/source/blender/blenfont/BLF_api.h
@@ -149,11 +149,11 @@ void BLF_shadow_offset(int fontid, int x, int y);
/* Set the buffer, size and number of channels to draw, one thing to take care is call
* this function with NULL pointer when we finish, for example:
*
- * BLF_buffer(my_fbuf, my_cbuf, 100, 100, 4, TRUE);
+ * BLF_buffer(my_fbuf, my_cbuf, 100, 100, 4, TRUE, NULL);
*
* ... set color, position and draw ...
*
- * BLF_buffer(NULL, NULL, 0, 0, 0, FALSE);
+ * BLF_buffer(NULL, NULL, NULL, 0, 0, FALSE, NULL);
*/
void BLF_buffer(int fontid, float *fbuf, unsigned char *cbuf, int w, int h, int nch, struct ColorManagedDisplay *display);
diff --git a/source/blender/blenfont/intern/blf_glyph.c b/source/blender/blenfont/intern/blf_glyph.c
index 55424145b43..37e874fa396 100644
--- a/source/blender/blenfont/intern/blf_glyph.c
+++ b/source/blender/blenfont/intern/blf_glyph.c
@@ -152,7 +152,7 @@ void blf_glyph_cache_free(GlyphCacheBLF *gc)
}
}
- if (gc->cur_tex + 1 > 0)
+ if (gc->cur_tex > -1)
glDeleteTextures(gc->cur_tex + 1, gc->textures);
MEM_freeN((void *)gc->textures);
MEM_freeN(gc);
diff --git a/source/blender/blenkernel/BKE_DerivedMesh.h b/source/blender/blenkernel/BKE_DerivedMesh.h
index 40fc71e82ca..8396380fd06 100644
--- a/source/blender/blenkernel/BKE_DerivedMesh.h
+++ b/source/blender/blenkernel/BKE_DerivedMesh.h
@@ -152,6 +152,11 @@ typedef enum DMDrawFlag {
DM_DRAW_ALWAYS_SMOOTH = 2
} DMDrawFlag;
+typedef enum DMForeachFlag {
+ DM_FOREACH_NOP = 0,
+ DM_FOREACH_USE_NORMAL = (1 << 0), /* foreachMappedVert, foreachMappedFaceCenter */
+} DMForeachFlag;
+
typedef enum DMDirtyFlag {
/* dm has valid tessellated faces, but tessellated CDDATA need to be updated. */
DM_DIRTY_TESS_CDLAYERS = 1 << 0,
@@ -285,7 +290,8 @@ struct DerivedMesh {
void (*foreachMappedVert)(DerivedMesh *dm,
void (*func)(void *userData, int index, const float co[3],
const float no_f[3], const short no_s[3]),
- void *userData);
+ void *userData,
+ DMForeachFlag flag);
/** Iterate over each mapped edge in the derived mesh, calling the
* given function with the original edge and the mapped edge's new
@@ -303,7 +309,8 @@ struct DerivedMesh {
void (*foreachMappedFaceCenter)(DerivedMesh *dm,
void (*func)(void *userData, int index,
const float cent[3], const float no[3]),
- void *userData);
+ void *userData,
+ DMForeachFlag flag);
/** Iterate over all vertex points, calling DO_MINMAX with given args.
*
diff --git a/source/blender/blenkernel/BKE_blender.h b/source/blender/blenkernel/BKE_blender.h
index 8c556e00aaa..84e24df43e5 100644
--- a/source/blender/blenkernel/BKE_blender.h
+++ b/source/blender/blenkernel/BKE_blender.h
@@ -42,15 +42,14 @@ extern "C" {
* and keep comment above the defines.
* Use STRINGIFY() rather than defining with quotes */
#define BLENDER_VERSION 268
-#define BLENDER_SUBVERSION 0
-
+#define BLENDER_SUBVERSION 2
/* 262 was the last editmesh release but it has compatibility code for bmesh data */
#define BLENDER_MINVERSION 262
#define BLENDER_MINSUBVERSION 0
/* 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_bmesh.h b/source/blender/blenkernel/BKE_bmesh.h
deleted file mode 100644
index 0dfab26e9f0..00000000000
--- a/source/blender/blenkernel/BKE_bmesh.h
+++ /dev/null
@@ -1,98 +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) 2004 Blender Foundation.
- * All rights reserved.
- *
- * The Original Code is: all of this file.
- *
- * Contributor(s): Geoffrey Bantle.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-#ifndef __BKE_BMESH_H__
-#define __BKE_BMESH_H__
-
-/** \file BKE_bmesh.h
- * \ingroup bke
- * \since January 2007
- * \brief BMesh modeler structure and functions.
- *
- */
-
-/*NOTE: this is the bmesh 1.0 code. it's completely outdated.*/
-
-/* uncomment to use the new bevel operator as a modifier */
-#define USE_BM_BEVEL_OP_AS_MOD
-
-/* bevel tool defines */
-/* element flags */
-#define BME_BEVEL_ORIG 1
-#define BME_BEVEL_BEVEL (1 << 1)
-#define BME_BEVEL_NONMAN (1 << 2)
-#define BME_BEVEL_WIRE (1 << 3)
-
-/* tool options */
-#define BME_BEVEL_SELECT 1
-#define BME_BEVEL_VERT (1 << 1)
-#define BME_BEVEL_RADIUS (1 << 2)
-#define BME_BEVEL_ANGLE (1 << 3)
-#define BME_BEVEL_WEIGHT (1 << 4)
-#define BME_BEVEL_VGROUP (1 << 5)
-//~ #define BME_BEVEL_EWEIGHT (1<<4)
-//~ #define BME_BEVEL_VWEIGHT (1<<5)
-#define BME_BEVEL_PERCENT (1 << 6)
-#define BME_BEVEL_EMIN (1 << 7)
-#define BME_BEVEL_EMAX (1 << 8)
-#define BME_BEVEL_RUNNING (1 << 9)
-#define BME_BEVEL_RES (1 << 10)
-
-#define BME_BEVEL_EVEN (1 << 11) /* this is a new setting not related to old (trunk bmesh bevel code) but adding
- * here because they are mixed - campbell */
-#define BME_BEVEL_DIST (1 << 12) /* same as above */
-
-#define BME_BEVEL_OVERLAP_OK (1 << 13)
-
-typedef struct BME_TransData {
- struct BMesh *bm; /* the bmesh the vert belongs to */
- struct BMVert *v; /* pointer to the vert this tdata applies to */
- float co[3]; /* the original coordinate */
- float org[3]; /* the origin */
- float vec[3]; /* a directional vector; always, always normalize! */
- void *loc; /* a pointer to the data to transform (likely the vert's cos) */
- float factor; /* primary scaling factor; also accumulates number of weighted edges for beveling tool */
- float weight; /* another scaling factor; used primarily for propogating vertex weights to transforms; */
- /* weight is also used across recursive bevels to help with the math */
- float maxfactor; /* the unscaled, original factor (used only by "edge verts" in recursive beveling) */
- float *max; /* the maximum distance this vert can be transformed; negative is infinite
- * it points to the "parent" maxfactor (where maxfactor makes little sense)
- * where the max limit is stored (limits are stored per-corner) */
-} BME_TransData;
-
-typedef struct BME_TransData_Head {
- struct GHash *gh; /* the hash structure for element lookup */
- struct MemArena *ma; /* the memory "pool" we will be drawing individual elements from */
- int len;
-} BME_TransData_Head;
-
-struct BME_TransData *BME_get_transdata(struct BME_TransData_Head *td, struct BMVert *v);
-void BME_free_transdata(struct BME_TransData_Head *td);
-struct BMesh *BME_bevel(struct BMesh *bm, float value, int res, int options, int defgrp_index, float angle,
- BME_TransData_Head **rtd);
-
-#endif
diff --git a/source/blender/blenkernel/BKE_context.h b/source/blender/blenkernel/BKE_context.h
index 285077f258c..c6a6b0672d1 100644
--- a/source/blender/blenkernel/BKE_context.h
+++ b/source/blender/blenkernel/BKE_context.h
@@ -200,8 +200,8 @@ void CTX_data_dir_set(bContextDataResult *result, const char **member);
void CTX_data_type_set(struct bContextDataResult *result, short type);
short CTX_data_type_get(struct bContextDataResult *result);
-int CTX_data_equals(const char *member, const char *str);
-int CTX_data_dir(const char *member);
+bool CTX_data_equals(const char *member, const char *str);
+bool CTX_data_dir(const char *member);
#if 0
void CTX_data_pointer_set(bContextDataResult *result, void *data);
diff --git a/source/blender/blenkernel/BKE_curve.h b/source/blender/blenkernel/BKE_curve.h
index 3be77086336..baa90e7a856 100644
--- a/source/blender/blenkernel/BKE_curve.h
+++ b/source/blender/blenkernel/BKE_curve.h
@@ -69,7 +69,8 @@ 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);
+void BKE_curve_material_index_remove(struct Curve *cu, int index);
+void BKE_curve_material_index_clear(struct Curve *cu);
ListBase *BKE_curve_nurbs_get(struct Curve *cu);
@@ -129,6 +130,14 @@ bool BKE_nurb_type_convert(struct Nurb *nu, const short type, const bool use_han
void BKE_nurb_points_add(struct Nurb *nu, int number);
void BKE_nurb_bezierPoints_add(struct Nurb *nu, int number);
+struct BezTriple *BKE_nurb_bezt_get_next(struct Nurb *nu, struct BezTriple *bezt);
+struct BezTriple *BKE_nurb_bezt_get_prev(struct Nurb *nu, struct BezTriple *bezt);
+struct BPoint *BKE_nurb_bpoint_get_next(struct Nurb *nu, struct BPoint *bp);
+struct BPoint *BKE_nurb_bpoint_get_prev(struct Nurb *nu, struct BPoint *bp);
+
+void BKE_nurb_bezt_calc_normal(struct Nurb *nu, struct BezTriple *bezt, float r_normal[3]);
+void BKE_nurb_bezt_calc_plane(struct Nurb *nu, struct BezTriple *bezt, float r_plane[3]);
+
void BKE_nurb_handle_calc(struct BezTriple *bezt, struct BezTriple *prev, struct BezTriple *next, int mode);
void BKE_nurb_handles_calc(struct Nurb *nu);
diff --git a/source/blender/blenkernel/BKE_global.h b/source/blender/blenkernel/BKE_global.h
index 0699344a887..9d33af1a0f4 100644
--- a/source/blender/blenkernel/BKE_global.h
+++ b/source/blender/blenkernel/BKE_global.h
@@ -46,7 +46,6 @@ extern "C" {
/* forwards */
struct Main;
struct Object;
-struct BME_Glob;
typedef struct Global {
diff --git a/source/blender/blenkernel/BKE_image.h b/source/blender/blenkernel/BKE_image.h
index eefaac07b12..7b5abbba7f8 100644
--- a/source/blender/blenkernel/BKE_image.h
+++ b/source/blender/blenkernel/BKE_image.h
@@ -161,7 +161,7 @@ struct Image *BKE_image_load(struct Main *bmain, const char *filepath);
struct Image *BKE_image_load_exists(const char *filepath);
/* adds image, adds ibuf, generates color or pattern */
-struct Image *BKE_image_add_generated(struct Main *bmain, unsigned int width, unsigned int height, const char *name, int depth, int floatbuf, short gen_type, float color[4]);
+struct Image *BKE_image_add_generated(struct Main *bmain, unsigned int width, unsigned int height, const char *name, int depth, int floatbuf, short gen_type, const float color[4]);
/* adds image from imbuf, owns imbuf */
struct Image *BKE_image_add_from_imbuf(struct ImBuf *ibuf);
diff --git a/source/blender/blenkernel/BKE_material.h b/source/blender/blenkernel/BKE_material.h
index 7c47380f838..f52dc030873 100644
--- a/source/blender/blenkernel/BKE_material.h
+++ b/source/blender/blenkernel/BKE_material.h
@@ -87,9 +87,9 @@ int object_add_material_slot(struct Object *ob);
int object_remove_material_slot(struct Object *ob);
/* rna api */
-void material_append_id(struct ID *id, struct Material *ma);
-struct Material *material_pop_id(struct ID *id, int index, int remove_material_slot); /* index is an int because of RNA */
-
+void BKE_material_append_id(struct ID *id, struct Material *ma);
+struct Material *BKE_material_pop_id(struct ID *id, int index, bool update_data); /* index is an int because of RNA */
+void BKE_material_clear_id(struct ID *id, bool update_data);
/* rendering */
void init_render_material(struct Material *, int, float *);
diff --git a/source/blender/blenkernel/BKE_mesh.h b/source/blender/blenkernel/BKE_mesh.h
index 1c88a5c45dd..e582af77d61 100644
--- a/source/blender/blenkernel/BKE_mesh.h
+++ b/source/blender/blenkernel/BKE_mesh.h
@@ -188,7 +188,8 @@ void BKE_mesh_from_nurbs_displist(struct Object *ob, struct ListBase *dispbase,
void BKE_mesh_from_nurbs(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_material_index_remove(struct Mesh *me, short index);
+void BKE_mesh_material_index_clear(struct Mesh *me);
void BKE_mesh_smooth_flag_set(struct Object *meshOb, int enableSmooth);
void BKE_mesh_convert_mfaces_to_mpolys(struct Mesh *mesh);
void BKE_mesh_do_versions_convert_mfaces_to_mpolys(struct Mesh *mesh);
diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h
index b43747ab33a..4e9e18d43e3 100644
--- a/source/blender/blenkernel/BKE_node.h
+++ b/source/blender/blenkernel/BKE_node.h
@@ -742,6 +742,10 @@ struct ShadeResult;
#define SH_NODE_WIREFRAME 178
#define SH_NODE_BSDF_TOON 179
#define SH_NODE_WAVELENGTH 180
+#define SH_NODE_BLACKBODY 181
+#define SH_NODE_VECT_TRANSFORM 182
+#define SH_NODE_SEPHSV 183
+#define SH_NODE_COMBHSV 184
/* custom defines options for Material node */
#define SH_NODE_MAT_DIFF 1
@@ -774,34 +778,37 @@ void ntreeGPUMaterialNodes(struct bNodeTree *ntree, struct GPUMateria
/* ************** COMPOSITE NODES *************** */
/* output socket defines */
-#define RRES_OUT_IMAGE 0
-#define RRES_OUT_ALPHA 1
-#define RRES_OUT_Z 2
-#define RRES_OUT_NORMAL 3
-#define RRES_OUT_UV 4
-#define RRES_OUT_VEC 5
-#define RRES_OUT_RGBA 6
-#define RRES_OUT_DIFF 7
-#define RRES_OUT_SPEC 8
-#define RRES_OUT_SHADOW 9
-#define RRES_OUT_AO 10
-#define RRES_OUT_REFLECT 11
-#define RRES_OUT_REFRACT 12
-#define RRES_OUT_INDIRECT 13
-#define RRES_OUT_INDEXOB 14
-#define RRES_OUT_INDEXMA 15
-#define RRES_OUT_MIST 16
-#define RRES_OUT_EMIT 17
-#define RRES_OUT_ENV 18
-#define RRES_OUT_DIFF_DIRECT 19
-#define RRES_OUT_DIFF_INDIRECT 20
-#define RRES_OUT_DIFF_COLOR 21
-#define RRES_OUT_GLOSSY_DIRECT 22
-#define RRES_OUT_GLOSSY_INDIRECT 23
-#define RRES_OUT_GLOSSY_COLOR 24
-#define RRES_OUT_TRANSM_DIRECT 25
-#define RRES_OUT_TRANSM_INDIRECT 26
-#define RRES_OUT_TRANSM_COLOR 27
+#define RRES_OUT_IMAGE 0
+#define RRES_OUT_ALPHA 1
+#define RRES_OUT_Z 2
+#define RRES_OUT_NORMAL 3
+#define RRES_OUT_UV 4
+#define RRES_OUT_VEC 5
+#define RRES_OUT_RGBA 6
+#define RRES_OUT_DIFF 7
+#define RRES_OUT_SPEC 8
+#define RRES_OUT_SHADOW 9
+#define RRES_OUT_AO 10
+#define RRES_OUT_REFLECT 11
+#define RRES_OUT_REFRACT 12
+#define RRES_OUT_INDIRECT 13
+#define RRES_OUT_INDEXOB 14
+#define RRES_OUT_INDEXMA 15
+#define RRES_OUT_MIST 16
+#define RRES_OUT_EMIT 17
+#define RRES_OUT_ENV 18
+#define RRES_OUT_DIFF_DIRECT 19
+#define RRES_OUT_DIFF_INDIRECT 20
+#define RRES_OUT_DIFF_COLOR 21
+#define RRES_OUT_GLOSSY_DIRECT 22
+#define RRES_OUT_GLOSSY_INDIRECT 23
+#define RRES_OUT_GLOSSY_COLOR 24
+#define RRES_OUT_TRANSM_DIRECT 25
+#define RRES_OUT_TRANSM_INDIRECT 26
+#define RRES_OUT_TRANSM_COLOR 27
+#define RRES_OUT_SUBSURFACE_DIRECT 28
+#define RRES_OUT_SUBSURFACE_INDIRECT 29
+#define RRES_OUT_SUBSURFACE_COLOR 30
/* note: types are needed to restore callbacks, don't change values */
#define CMP_NODE_VIEWER 201
diff --git a/source/blender/blenkernel/BKE_pbvh.h b/source/blender/blenkernel/BKE_pbvh.h
index 48c16f8db38..7d3d8d7dcbd 100644
--- a/source/blender/blenkernel/BKE_pbvh.h
+++ b/source/blender/blenkernel/BKE_pbvh.h
@@ -223,7 +223,7 @@ typedef struct PBVHVertexIter {
struct CCGElem **grids;
struct CCGElem *grid;
struct CCGKey *key;
- BLI_bitmap *grid_hidden, gh;
+ BLI_bitmap **grid_hidden, *gh;
int *grid_indices;
int totgrid;
int gridsize;
diff --git a/source/blender/blenkernel/BKE_screen.h b/source/blender/blenkernel/BKE_screen.h
index b5a6c6fb821..c883bdf74e0 100644
--- a/source/blender/blenkernel/BKE_screen.h
+++ b/source/blender/blenkernel/BKE_screen.h
@@ -254,6 +254,7 @@ struct SpaceType *BKE_spacetype_from_id(int spaceid);
struct ARegionType *BKE_regiontype_from_id(struct SpaceType *st, int regionid);
const struct ListBase *BKE_spacetypes_list(void);
void BKE_spacetype_register(struct SpaceType *st);
+int BKE_spacetype_exists(int spaceid);
void BKE_spacetypes_free(void); /* only for quitting blender */
/* spacedata */
diff --git a/source/blender/blenkernel/BKE_sequencer.h b/source/blender/blenkernel/BKE_sequencer.h
index 4494d127082..78018f04458 100644
--- a/source/blender/blenkernel/BKE_sequencer.h
+++ b/source/blender/blenkernel/BKE_sequencer.h
@@ -208,6 +208,10 @@ int BKE_sequencer_recursive_apply(struct Sequence *seq, int (*apply_func)(struct
void BKE_sequencer_free_clipboard(void);
+void BKE_sequence_clipboard_pointers_free(struct Sequence *seq);
+void BKE_sequence_clipboard_pointers_store(struct Sequence *seq);
+void BKE_sequence_clipboard_pointers_restore(struct Sequence *seq, struct Main *bmain);
+
void BKE_sequence_free(struct Scene *scene, struct Sequence *seq);
const char *BKE_sequence_give_name(struct Sequence *seq);
void BKE_sequence_calc(struct Scene *scene, struct Sequence *seq);
@@ -261,7 +265,7 @@ void BKE_sequencer_preprocessed_cache_cleanup_sequence(struct Sequence *seq);
/* **********************************************************************
* seqeffects.c
*
- * Sequencer effect strip managment functions
+ * Sequencer effect strip management functions
* **********************************************************************
*/
@@ -319,8 +323,6 @@ void BKE_sequence_base_dupli_recursive(struct Scene *scene, struct Scene *scene_
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);
-void BKE_sequencer_clear_mask_in_clipboard(struct Mask *mask);
struct Sequence *BKE_sequence_get_by_name(struct ListBase *seqbase, const char *name, int recursive);
diff --git a/source/blender/blenkernel/CMakeLists.txt b/source/blender/blenkernel/CMakeLists.txt
index 2f51f9f17fe..655e0d65133 100644
--- a/source/blender/blenkernel/CMakeLists.txt
+++ b/source/blender/blenkernel/CMakeLists.txt
@@ -165,7 +165,6 @@ set(SRC
BKE_armature.h
BKE_autoexec.h
BKE_blender.h
- BKE_bmesh.h
BKE_bmfont.h
BKE_bmfont_types.h
BKE_boids.h
diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c
index 7a7d4c7d24a..2ece90183bd 100644
--- a/source/blender/blenkernel/intern/DerivedMesh.c
+++ b/source/blender/blenkernel/intern/DerivedMesh.c
@@ -46,7 +46,6 @@
#include "BLI_blenlib.h"
#include "BLI_math.h"
#include "BLI_memarena.h"
-#include "BLI_array.h"
#include "BLI_utildefines.h"
#include "BLI_linklist.h"
@@ -531,7 +530,9 @@ void DM_to_mesh(DerivedMesh *dm, Mesh *me, Object *ob, CustomDataMask mask)
}
/* copy texture space */
- BKE_mesh_texspace_copy_from_object(&tmp, ob);
+ if (ob) {
+ BKE_mesh_texspace_copy_from_object(&tmp, ob);
+ }
/* not all DerivedMeshes store their verts/edges/faces in CustomData, so
* we set them here in case they are missing */
@@ -2634,9 +2635,9 @@ void DM_add_tangent_layer(DerivedMesh *dm)
/* new computation method */
{
- SGLSLMeshToTangent mesh2tangent = {0};
- SMikkTSpaceContext sContext = {0};
- SMikkTSpaceInterface sInterface = {0};
+ SGLSLMeshToTangent mesh2tangent = {NULL};
+ SMikkTSpaceContext sContext = {NULL};
+ SMikkTSpaceInterface sInterface = {NULL};
mesh2tangent.precomputedFaceNormals = nors;
mesh2tangent.mtface = mtface;
diff --git a/source/blender/blenkernel/intern/action.c b/source/blender/blenkernel/intern/action.c
index 70fbf2d39e8..bfef3542c45 100644
--- a/source/blender/blenkernel/intern/action.c
+++ b/source/blender/blenkernel/intern/action.c
@@ -613,9 +613,12 @@ void BKE_pose_channels_hash_free(bPose *pose)
}
}
-
void BKE_pose_channel_free(bPoseChannel *pchan)
{
+ if (pchan->custom) {
+ id_us_min(&pchan->custom->id);
+ pchan->custom = NULL;
+ }
if (pchan->mpath) {
animviz_free_motionpath(pchan->mpath);
@@ -727,6 +730,9 @@ void BKE_pose_channel_copy_data(bPoseChannel *pchan, const bPoseChannel *pchan_f
/* custom shape */
pchan->custom = pchan_from->custom;
+ if (pchan->custom) {
+ id_us_plus(&pchan->custom->id);
+ }
}
diff --git a/source/blender/blenkernel/intern/anim.c b/source/blender/blenkernel/intern/anim.c
index 9fea3d2e13f..ba680147201 100644
--- a/source/blender/blenkernel/intern/anim.c
+++ b/source/blender/blenkernel/intern/anim.c
@@ -1036,7 +1036,7 @@ static void vertex_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, fl
if (ob->type != OB_MBALL) ob->flag |= OB_DONE; /* doesnt render */
if (me->edit_btmesh) {
- dm->foreachMappedVert(dm, vertex_dupli__mapFunc, (void *) &vdd);
+ dm->foreachMappedVert(dm, vertex_dupli__mapFunc, (void *) &vdd, DM_FOREACH_USE_NORMAL);
}
else {
for (a = 0; a < totvert; a++) {
diff --git a/source/blender/blenkernel/intern/anim_sys.c b/source/blender/blenkernel/intern/anim_sys.c
index 001964087b8..4b05b0800a5 100644
--- a/source/blender/blenkernel/intern/anim_sys.c
+++ b/source/blender/blenkernel/intern/anim_sys.c
@@ -39,8 +39,8 @@
#include "MEM_guardedalloc.h"
#include "BLI_utildefines.h"
-#include "BLI_array.h"
#include "BLI_blenlib.h"
+#include "BLI_alloca.h"
#include "BLI_dynstr.h"
#include "BLF_translation.h"
diff --git a/source/blender/blenkernel/intern/armature.c b/source/blender/blenkernel/intern/armature.c
index d37ccae3089..f006710dc21 100644
--- a/source/blender/blenkernel/intern/armature.c
+++ b/source/blender/blenkernel/intern/armature.c
@@ -1605,7 +1605,10 @@ static void pose_proxy_synchronize(Object *ob, Object *from, int layer_protected
pchanw.next = pchan->next;
pchanw.parent = pchan->parent;
pchanw.child = pchan->child;
-
+
+ pchanw.mpath = pchan->mpath;
+ pchan->mpath = NULL;
+
/* this is freed so copy a copy, else undo crashes */
if (pchanw.prop) {
pchanw.prop = IDP_CopyProperty(pchanw.prop);
@@ -1652,10 +1655,16 @@ static void pose_proxy_synchronize(Object *ob, Object *from, int layer_protected
/* copy data in temp back over to the cleaned-out (but still allocated) original channel */
*pchan = pchanw;
+ if (pchan->custom) {
+ id_us_plus(&pchan->custom->id);
+ }
}
else {
/* always copy custom shape */
pchan->custom = pchanp->custom;
+ if (pchan->custom) {
+ id_us_plus(&pchan->custom->id);
+ }
if (pchanp->custom_tx)
pchan->custom_tx = BKE_pose_channel_find_name(pose, pchanp->custom_tx->name);
diff --git a/source/blender/blenkernel/intern/blender.c b/source/blender/blenkernel/intern/blender.c
index 29a8a615601..26f481e5341 100644
--- a/source/blender/blenkernel/intern/blender.c
+++ b/source/blender/blenkernel/intern/blender.c
@@ -816,7 +816,7 @@ int BKE_undo_save_file(const char *filename)
* to avoid writing to a symlink - use 'O_EXCL' (CVE-2008-1103) */
errno = 0;
file = BLI_open(filename, flag, 0666);
- if (file == -1) {
+ if (file < 0) {
if (errno == EEXIST) {
errno = 0;
file = BLI_open(filename, flag & ~O_CREAT, 0666);
diff --git a/source/blender/blenkernel/intern/camera.c b/source/blender/blenkernel/intern/camera.c
index a47cab7f236..f9444ca2cf9 100644
--- a/source/blender/blenkernel/intern/camera.c
+++ b/source/blender/blenkernel/intern/camera.c
@@ -408,26 +408,33 @@ void BKE_camera_view_frame_ex(Scene *scene, Camera *camera, float drawsize, cons
}
else {
/* that way it's always visible - clipsta+0.1 */
- float fac;
- float half_sensor = 0.5f * ((camera->sensor_fit == CAMERA_SENSOR_FIT_VERT) ? (camera->sensor_y) : (camera->sensor_x));
+ float fac, scale_x, scale_y;
+ float half_sensor = 0.5f * ((camera->sensor_fit == CAMERA_SENSOR_FIT_VERT) ?
+ (camera->sensor_y) : (camera->sensor_x));
- *r_drawsize = drawsize / ((scale[0] + scale[1] + scale[2]) / 3.0f);
if (do_clip) {
/* fixed depth, variable size (avoids exceeding clipping range) */
- depth = -(camera->clipsta + 0.1f);
- fac = depth / (camera->lens / (-half_sensor) * scale[2]);
+ /* r_drawsize shouldn't be used in this case, set to dummy value */
+ *r_drawsize = 1.0f;
+ depth = -(camera->clipsta + 0.1f) * scale[2];
+ fac = depth / (camera->lens / (-half_sensor));
+ scale_x = 1.0f;
+ scale_y = 1.0f;
}
else {
/* fixed size, variable depth (stays a reasonable size in the 3D view) */
+ *r_drawsize = drawsize / ((scale[0] + scale[1] + scale[2]) / 3.0f);
depth = *r_drawsize * camera->lens / (-half_sensor) * scale[2];
fac = *r_drawsize;
+ scale_x = scale[0];
+ scale_y = scale[1];
}
- facx = fac * r_asp[0] * scale[0];
- facy = fac * r_asp[1] * scale[1];
- r_shift[0] = camera->shiftx * fac * 2 * scale[0];
- r_shift[1] = camera->shifty * fac * 2 * scale[1];
+ facx = fac * r_asp[0] * scale_x;
+ facy = fac * r_asp[1] * scale_y;
+ r_shift[0] = camera->shiftx * fac * 2.0f * scale_x;
+ r_shift[1] = camera->shifty * fac * 2.0f * scale_y;
}
r_vec[0][0] = r_shift[0] + facx; r_vec[0][1] = r_shift[1] + facy; r_vec[0][2] = depth;
@@ -455,7 +462,7 @@ typedef struct CameraViewFrameData {
unsigned int tot;
} CameraViewFrameData;
-static void BKE_camera_to_frame_view_cb(const float co[3], void *user_data)
+static void camera_to_frame_view_cb(const float co[3], void *user_data)
{
CameraViewFrameData *data = (CameraViewFrameData *)user_data;
unsigned int i;
@@ -519,7 +526,7 @@ int BKE_camera_view_frame_fit_to_scene(Scene *scene, struct View3D *v3d, Object
data_cb.tot = 0;
/* run callback on all visible points */
BKE_scene_foreach_display_point(scene, v3d, BA_SELECT,
- BKE_camera_to_frame_view_cb, &data_cb);
+ camera_to_frame_view_cb, &data_cb);
if (data_cb.tot <= 1) {
return FALSE;
diff --git a/source/blender/blenkernel/intern/cdderivedmesh.c b/source/blender/blenkernel/intern/cdderivedmesh.c
index faa4d8d3071..6205c8016b6 100644
--- a/source/blender/blenkernel/intern/cdderivedmesh.c
+++ b/source/blender/blenkernel/intern/cdderivedmesh.c
@@ -40,7 +40,6 @@
#include "BLI_blenlib.h"
#include "BLI_edgehash.h"
#include "BLI_math.h"
-#include "BLI_array.h"
#include "BLI_smallhash.h"
#include "BLI_utildefines.h"
#include "BLI_scanfill.h"
@@ -1548,19 +1547,26 @@ static void cdDM_drawMappedEdges(DerivedMesh *dm, DMSetDrawOptions setDrawOption
static void cdDM_foreachMappedVert(
DerivedMesh *dm,
void (*func)(void *userData, int index, const float co[3], const float no_f[3], const short no_s[3]),
- void *userData)
+ void *userData,
+ DMForeachFlag flag)
{
MVert *mv = CDDM_get_verts(dm);
- int i, orig, *index = DM_get_vert_data_layer(dm, CD_ORIGINDEX);
+ int *index = DM_get_vert_data_layer(dm, CD_ORIGINDEX);
+ int i;
- for (i = 0; i < dm->numVertData; i++, mv++) {
- if (index) {
- orig = *index++;
+ if (index) {
+ for (i = 0; i < dm->numVertData; i++, mv++) {
+ const short *no = (flag & DM_FOREACH_USE_NORMAL) ? mv->no : NULL;
+ const int orig = *index++;
if (orig == ORIGINDEX_NONE) continue;
- func(userData, orig, mv->co, NULL, mv->no);
+ func(userData, orig, mv->co, NULL, no);
+ }
+ }
+ else {
+ for (i = 0; i < dm->numVertData; i++, mv++) {
+ const short *no = (flag & DM_FOREACH_USE_NORMAL) ? mv->no : NULL;
+ func(userData, i, mv->co, NULL, no);
}
- else
- func(userData, i, mv->co, NULL, mv->no);
}
}
@@ -1588,47 +1594,37 @@ static void cdDM_foreachMappedEdge(
static void cdDM_foreachMappedFaceCenter(
DerivedMesh *dm,
void (*func)(void *userData, int index, const float cent[3], const float no[3]),
- void *userData)
+ void *userData,
+ DMForeachFlag flag)
{
CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
MVert *mvert = cddm->mvert;
MPoly *mp;
MLoop *ml;
- int i, j, orig, *index;
+ int i, orig, *index;
index = CustomData_get_layer(&dm->polyData, CD_ORIGINDEX);
mp = cddm->mpoly;
for (i = 0; i < dm->numPolyData; i++, mp++) {
float cent[3];
- float no[3];
+ float *no, _no[3];
if (index) {
orig = *index++;
if (orig == ORIGINDEX_NONE) continue;
}
- else
+ else {
orig = i;
+ }
ml = &cddm->mloop[mp->loopstart];
- cent[0] = cent[1] = cent[2] = 0.0f;
- for (j = 0; j < mp->totloop; j++, ml++) {
- add_v3_v3v3(cent, cent, mvert[ml->v].co);
- }
- mul_v3_fl(cent, 1.0f / (float)j);
+ BKE_mesh_calc_poly_center(mp, ml, mvert, cent);
- ml = &cddm->mloop[mp->loopstart];
- if (j > 3) {
- normal_quad_v3(no,
- mvert[(ml + 0)->v].co,
- mvert[(ml + 1)->v].co,
- mvert[(ml + 2)->v].co,
- mvert[(ml + 3)->v].co);
+ if (flag & DM_FOREACH_USE_NORMAL) {
+ BKE_mesh_calc_poly_normal(mp, ml, mvert, (no = _no));
}
else {
- normal_tri_v3(no,
- mvert[(ml + 0)->v].co,
- mvert[(ml + 1)->v].co,
- mvert[(ml + 2)->v].co);
+ no = NULL;
}
func(userData, orig, cent, no);
@@ -1973,8 +1969,7 @@ static DerivedMesh *cddm_from_bmesh_ex(struct BMesh *bm, int use_mdisps,
index = dm->getVertDataArray(dm, CD_ORIGINDEX);
- eve = BM_iter_new(&iter, bm, BM_VERTS_OF_MESH, NULL);
- for (i = 0; eve; eve = BM_iter_step(&iter), i++, index++) {
+ BM_ITER_MESH_INDEX (eve, &iter, bm, BM_VERTS_OF_MESH, i) {
MVert *mv = &mvert[i];
copy_v3_v3(mv->co, eve->co);
@@ -1987,15 +1982,14 @@ static DerivedMesh *cddm_from_bmesh_ex(struct BMesh *bm, int use_mdisps,
if (cd_vert_bweight_offset != -1) mv->bweight = BM_ELEM_CD_GET_FLOAT_AS_UCHAR(eve, cd_vert_bweight_offset);
- if (add_orig) *index = i;
+ if (add_orig) *index++ = i;
CustomData_from_bmesh_block(&bm->vdata, &dm->vertData, eve->head.data, i);
}
bm->elem_index_dirty &= ~BM_VERT;
index = dm->getEdgeDataArray(dm, CD_ORIGINDEX);
- eed = BM_iter_new(&iter, bm, BM_EDGES_OF_MESH, NULL);
- for (i = 0; eed; eed = BM_iter_step(&iter), i++, index++) {
+ BM_ITER_MESH_INDEX (eed, &iter, bm, BM_EDGES_OF_MESH, i) {
MEdge *med = &medge[i];
BM_elem_index_set(eed, i); /* set_inline */
@@ -2017,7 +2011,7 @@ static DerivedMesh *cddm_from_bmesh_ex(struct BMesh *bm, int use_mdisps,
if (cd_edge_bweight_offset != -1) med->bweight = BM_ELEM_CD_GET_FLOAT_AS_UCHAR(eed, cd_edge_bweight_offset);
CustomData_from_bmesh_block(&bm->edata, &dm->edgeData, eed->head.data, i);
- if (add_orig) *index = i;
+ if (add_orig) *index++ = i;
}
bm->elem_index_dirty &= ~BM_EDGE;
@@ -2027,7 +2021,7 @@ static DerivedMesh *cddm_from_bmesh_ex(struct BMesh *bm, int use_mdisps,
BM_mesh_elem_index_ensure(bm, BM_FACE);
index = dm->getTessFaceDataArray(dm, CD_ORIGINDEX);
- for (i = 0; i < dm->numTessFaceData; i++, index++) {
+ for (i = 0; i < dm->numTessFaceData; i++) {
MFace *mf = &mface[i];
const BMLoop **l = em_looptris[i];
efa = l[0]->f;
@@ -2040,7 +2034,7 @@ static DerivedMesh *cddm_from_bmesh_ex(struct BMesh *bm, int use_mdisps,
mf->flag = BM_face_flag_to_mflag(efa);
/* map mfaces to polygons in the same cddm intentionally */
- *index = BM_elem_index_get(efa);
+ *index++ = BM_elem_index_get(efa);
loops_to_customdata_corners(bm, &dm->faceData, i, l, numCol, numTex);
test_index_face(mf, &dm->faceData, i, 3);
@@ -2049,8 +2043,7 @@ static DerivedMesh *cddm_from_bmesh_ex(struct BMesh *bm, int use_mdisps,
index = CustomData_get_layer(&dm->polyData, CD_ORIGINDEX);
j = 0;
- efa = BM_iter_new(&iter, bm, BM_FACES_OF_MESH, NULL);
- for (i = 0; efa; i++, efa = BM_iter_step(&iter), index++) {
+ BM_ITER_MESH_INDEX (efa, &iter, bm, BM_FACES_OF_MESH, i) {
BMLoop *l_iter;
BMLoop *l_first;
MPoly *mp = &mpoly[i];
@@ -2074,7 +2067,7 @@ static DerivedMesh *cddm_from_bmesh_ex(struct BMesh *bm, int use_mdisps,
CustomData_from_bmesh_block(&bm->pdata, &dm->polyData, efa->head.data, i);
- if (add_orig) *index = i;
+ if (add_orig) *index++ = i;
}
bm->elem_index_dirty &= ~BM_FACE;
diff --git a/source/blender/blenkernel/intern/cloth.c b/source/blender/blenkernel/intern/cloth.c
index a7311d5efc7..05ffd4a6265 100644
--- a/source/blender/blenkernel/intern/cloth.c
+++ b/source/blender/blenkernel/intern/cloth.c
@@ -476,7 +476,6 @@ void clothModifier_do(ClothModifierData *clmd, Scene *scene, Object *ob, Derived
BKE_ptcache_validate(cache, 0);
cache->last_exact= 0;
cache->flag &= ~PTCACHE_REDO_NEEDED;
- return;
}
// unused in the moment, calculated separately in implicit.c
diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c
index b8d851d082a..eda770ddf30 100644
--- a/source/blender/blenkernel/intern/constraint.c
+++ b/source/blender/blenkernel/intern/constraint.c
@@ -1227,7 +1227,7 @@ static void followpath_get_tarmat(bConstraint *con, bConstraintOb *cob, bConstra
copy_v3_v3(totmat[3], vec);
- mul_serie_m4(ct->matrix, ct->tar->obmat, totmat, NULL, NULL, NULL, NULL, NULL, NULL);
+ mul_m4_m4m4(ct->matrix, ct->tar->obmat, totmat);
}
}
}
@@ -1253,7 +1253,7 @@ static void followpath_evaluate(bConstraint *con, bConstraintOb *cob, ListBase *
mat4_to_size(size, cob->matrix);
/* apply targetmat - containing location on path, and rotation */
- mul_serie_m4(cob->matrix, ct->matrix, obmat, NULL, NULL, NULL, NULL, NULL, NULL);
+ mul_m4_m4m4(cob->matrix, ct->matrix, obmat);
/* un-apply scaling caused by path */
if ((data->followflag & FOLLOWPATH_RADIUS) == 0) { /* XXX - assume that scale correction means that radius will have some scale error in it - Campbell */
@@ -2080,6 +2080,8 @@ static void actcon_get_tarmat(bConstraint *con, bConstraintOb *cob, bConstraintT
axis = data->type - 20;
}
+ BLI_assert((unsigned int)axis < 3);
+
/* Target defines the animation */
s = (vec[axis] - data->min) / (data->max - data->min);
CLAMP(s, 0, 1);
@@ -3120,7 +3122,7 @@ static void clampto_evaluate(bConstraint *con, bConstraintOb *cob, ListBase *tar
unit_m4(totmat);
copy_v3_v3(totmat[3], vec);
- mul_serie_m4(targetMatrix, ct->tar->obmat, totmat, NULL, NULL, NULL, NULL, NULL, NULL);
+ mul_m4_m4m4(targetMatrix, ct->tar->obmat, totmat);
}
}
diff --git a/source/blender/blenkernel/intern/context.c b/source/blender/blenkernel/intern/context.c
index bbf254cd7d1..622b4f6df5a 100644
--- a/source/blender/blenkernel/intern/context.c
+++ b/source/blender/blenkernel/intern/context.c
@@ -531,12 +531,12 @@ ListBase CTX_data_dir_get(const bContext *C)
return CTX_data_dir_get_ex(C, TRUE, FALSE, FALSE);
}
-int CTX_data_equals(const char *member, const char *str)
+bool CTX_data_equals(const char *member, const char *str)
{
return (strcmp(member, str) == 0);
}
-int CTX_data_dir(const char *member)
+bool CTX_data_dir(const char *member)
{
return member[0] == '\0';
}
diff --git a/source/blender/blenkernel/intern/curve.c b/source/blender/blenkernel/intern/curve.c
index b6c4505bd78..2285d7d8dc0 100644
--- a/source/blender/blenkernel/intern/curve.c
+++ b/source/blender/blenkernel/intern/curve.c
@@ -681,6 +681,143 @@ void BKE_nurb_bezierPoints_add(Nurb *nu, int number)
nu->pntsu += number;
}
+
+BezTriple *BKE_nurb_bezt_get_next(Nurb *nu, BezTriple *bezt)
+{
+ BezTriple *bezt_next;
+
+ BLI_assert(ARRAY_HAS_ITEM(bezt, nu->bezt, nu->pntsu));
+
+ if (bezt == &nu->bezt[nu->pntsu - 1]) {
+ if (nu->flagu & CU_NURB_CYCLIC) {
+ bezt_next = nu->bezt;
+ }
+ else {
+ bezt_next = NULL;
+ }
+ }
+ else {
+ bezt_next = bezt + 1;
+ }
+
+ return bezt_next;
+}
+
+BPoint *BKE_nurb_bpoint_get_next(Nurb *nu, BPoint *bp)
+{
+ BPoint *bp_next;
+
+ BLI_assert(ARRAY_HAS_ITEM(bp, nu->bp, nu->pntsu));
+
+ if (bp == &nu->bp[nu->pntsu - 1]) {
+ if (nu->flagu & CU_NURB_CYCLIC) {
+ bp_next = nu->bp;
+ }
+ else {
+ bp_next = NULL;
+ }
+ }
+ else {
+ bp_next = bp + 1;
+ }
+
+ return bp_next;
+}
+
+BezTriple *BKE_nurb_bezt_get_prev(Nurb *nu, BezTriple *bezt)
+{
+ BezTriple *bezt_prev;
+
+ BLI_assert(ARRAY_HAS_ITEM(bezt, nu->bezt, nu->pntsu));
+
+ if (bezt == nu->bezt) {
+ if (nu->flagu & CU_NURB_CYCLIC) {
+ bezt_prev = &nu->bezt[nu->pntsu - 1];
+ }
+ else {
+ bezt_prev = NULL;
+ }
+ }
+ else {
+ bezt_prev = bezt - 1;
+ }
+
+ return bezt_prev;
+}
+
+BPoint *BKE_nurb_bpoint_get_prev(Nurb *nu, BPoint *bp)
+{
+ BPoint *bp_prev;
+
+ BLI_assert(ARRAY_HAS_ITEM(bp, nu->bp, nu->pntsu));
+
+ if (bp == nu->bp) {
+ if (nu->flagu & CU_NURB_CYCLIC) {
+ bp_prev = &nu->bp[nu->pntsu - 1];
+ }
+ else {
+ bp_prev = NULL;
+ }
+ }
+ else {
+ bp_prev = bp - 1;
+ }
+
+ return bp_prev;
+}
+
+void BKE_nurb_bezt_calc_normal(struct Nurb *UNUSED(nu), struct BezTriple *bezt, float r_normal[3])
+{
+ /* calculate the axis matrix from the spline */
+ float dir_prev[3], dir_next[3];
+
+ sub_v3_v3v3(dir_prev, bezt->vec[0], bezt->vec[1]);
+ sub_v3_v3v3(dir_next, bezt->vec[1], bezt->vec[2]);
+
+ normalize_v3(dir_prev);
+ normalize_v3(dir_next);
+
+ add_v3_v3v3(r_normal, dir_prev, dir_next);
+ normalize_v3(r_normal);
+}
+
+void BKE_nurb_bezt_calc_plane(struct Nurb *nu, struct BezTriple *bezt, float r_plane[3])
+{
+ float dir_prev[3], dir_next[3];
+
+ sub_v3_v3v3(dir_prev, bezt->vec[0], bezt->vec[1]);
+ sub_v3_v3v3(dir_next, bezt->vec[1], bezt->vec[2]);
+
+ normalize_v3(dir_prev);
+ normalize_v3(dir_next);
+
+ cross_v3_v3v3(r_plane, dir_prev, dir_next);
+ if (normalize_v3(r_plane) < FLT_EPSILON) {
+ BezTriple *bezt_prev = BKE_nurb_bezt_get_prev(nu, bezt);
+ BezTriple *bezt_next = BKE_nurb_bezt_get_next(nu, bezt);
+
+ if (bezt_prev) {
+ sub_v3_v3v3(dir_prev, bezt_prev->vec[1], bezt->vec[1]);
+ normalize_v3(dir_prev);
+ }
+ if (bezt_next) {
+ sub_v3_v3v3(dir_next, bezt->vec[1], bezt_next->vec[1]);
+ normalize_v3(dir_next);
+ }
+ cross_v3_v3v3(r_plane, dir_prev, dir_next);
+ }
+
+ /* matches with bones more closely */
+ {
+ float dir_mid[3], tvec[3];
+ add_v3_v3v3(dir_mid, dir_prev, dir_next);
+ cross_v3_v3v3(tvec, r_plane, dir_mid);
+ copy_v3_v3(r_plane, tvec);
+ }
+
+ normalize_v3(r_plane);
+}
+
/* ~~~~~~~~~~~~~~~~~~~~Non Uniform Rational B Spline calculations ~~~~~~~~~~~ */
@@ -1853,36 +1990,35 @@ static void alfa_bezpart(BezTriple *prevbezt, BezTriple *bezt, Nurb *nu, float *
/* make_bevel_list_3D_* funcs, at a minimum these must
* fill in the bezp->quat and bezp->dir values */
-/* correct non-cyclic cases by copying direction and rotation
- * values onto the first & last end-points */
-static void bevel_list_cyclic_fix_3D(BevList *bl)
-{
- BevPoint *bevp, *bevp1;
-
- bevp = (BevPoint *)(bl + 1);
- bevp1 = bevp + 1;
- copy_qt_qt(bevp->quat, bevp1->quat);
- copy_v3_v3(bevp->dir, bevp1->dir);
- copy_v3_v3(bevp->tan, bevp1->tan);
- bevp = (BevPoint *)(bl + 1);
- bevp += (bl->nr - 1);
- bevp1 = bevp - 1;
- copy_qt_qt(bevp->quat, bevp1->quat);
- copy_v3_v3(bevp->dir, bevp1->dir);
- copy_v3_v3(bevp->tan, bevp1->tan);
-}
-
/* utility for make_bevel_list_3D_* funcs */
static void bevel_list_calc_bisect(BevList *bl)
{
BevPoint *bevp2, *bevp1, *bevp0;
int nr;
+ bool is_cyclic = bl->poly != -1;
- bevp2 = (BevPoint *)(bl + 1);
- bevp1 = bevp2 + (bl->nr - 1);
- bevp0 = bevp1 - 1;
+ if (is_cyclic) {
+ bevp2 = (BevPoint *)(bl + 1);
+ bevp1 = bevp2 + (bl->nr - 1);
+ bevp0 = bevp1 - 1;
+ nr = bl->nr;
+ }
+ else {
+ /* If spline is not cyclic, direction of first and
+ * last bevel points matches direction of CV handle.
+ *
+ * This is getting calculated earlier when we know
+ * CV's handles and here we might simply skip evaluation
+ * of direction for this guys.
+ */
+
+ bevp0 = (BevPoint *)(bl + 1);
+ bevp1 = bevp0 + 1;
+ bevp2 = bevp1 + 1;
+
+ nr = bl->nr - 2;
+ }
- nr = bl->nr;
while (nr--) {
/* totally simple */
bisect_v3_v3v3v3(bevp1->dir, bevp0->vec, bevp1->vec, bevp2->vec);
@@ -1988,22 +2124,30 @@ static void bevel_list_smooth(BevList *bl, int smooth_iter)
static void make_bevel_list_3D_zup(BevList *bl)
{
- BevPoint *bevp2, *bevp1, *bevp0; /* standard for all make_bevel_list_3D_* funcs */
- int nr;
+ BevPoint *bevp = (BevPoint *)(bl + 1);
+ int nr = bl->nr;
- bevp2 = (BevPoint *)(bl + 1);
- bevp1 = bevp2 + (bl->nr - 1);
- bevp0 = bevp1 - 1;
+ bevel_list_calc_bisect(bl);
- nr = bl->nr;
while (nr--) {
- /* totally simple */
- bisect_v3_v3v3v3(bevp1->dir, bevp0->vec, bevp1->vec, bevp2->vec);
- vec_to_quat(bevp1->quat, bevp1->dir, 5, 1);
+ vec_to_quat(bevp->quat, bevp->dir, 5, 1);
+ bevp++;
+ }
+}
- bevp0 = bevp1;
- bevp1 = bevp2;
- bevp2++;
+static void minimum_twist_between_two_points(BevPoint *current_point, BevPoint *previous_point)
+{
+ float angle = angle_normalized_v3v3(previous_point->dir, current_point->dir);
+ float q[4];
+
+ if (angle > 0.0f) { /* otherwise we can keep as is */
+ float cross_tmp[3];
+ cross_v3_v3v3(cross_tmp, previous_point->dir, current_point->dir);
+ axis_angle_to_quat(q, cross_tmp, angle);
+ mul_qt_qtqt(current_point->quat, q, previous_point->quat);
+ }
+ else {
+ copy_qt_qt(current_point->quat, previous_point->quat);
}
}
@@ -2026,17 +2170,7 @@ static void make_bevel_list_3D_minimum_twist(BevList *bl)
vec_to_quat(bevp1->quat, bevp1->dir, 5, 1);
}
else {
- float angle = angle_normalized_v3v3(bevp0->dir, bevp1->dir);
-
- if (angle > 0.0f) { /* otherwise we can keep as is */
- float cross_tmp[3];
- cross_v3_v3v3(cross_tmp, bevp0->dir, bevp1->dir);
- axis_angle_to_quat(q, cross_tmp, angle);
- mul_qt_qtqt(bevp1->quat, q, bevp0->quat);
- }
- else {
- copy_qt_qt(bevp1->quat, bevp0->quat);
- }
+ minimum_twist_between_two_points(bevp1, bevp0);
}
bevp0 = bevp1;
@@ -2107,6 +2241,21 @@ static void make_bevel_list_3D_minimum_twist(BevList *bl)
bevp2++;
}
}
+ else {
+ /* Need to correct quat for the first/last point,
+ * this is so because previously it was only calculated
+ * using it's own direction, which might not correspond
+ * the twist of neighbor point.
+ */
+ bevp1 = (BevPoint *)(bl + 1);
+ bevp0 = bevp1 + 1;
+ minimum_twist_between_two_points(bevp1, bevp0);
+
+ bevp2 = (BevPoint *)(bl + 1);
+ bevp1 = bevp2 + (bl->nr - 1);
+ bevp0 = bevp1 - 1;
+ minimum_twist_between_two_points(bevp1, bevp0);
+ }
}
static void make_bevel_list_3D_tangent(BevList *bl)
@@ -2117,8 +2266,6 @@ static void make_bevel_list_3D_tangent(BevList *bl)
float bevp0_tan[3];
bevel_list_calc_bisect(bl);
- if (bl->poly == -1) /* check its not cyclic */
- bevel_list_cyclic_fix_3D(bl); // XXX - run this now so tangents will be right before doing the flipping
bevel_list_flip_tangents(bl);
/* correct the tangents */
@@ -2176,9 +2323,6 @@ static void make_bevel_list_3D(BevList *bl, int smooth_iter, int twist_mode)
break;
}
- if (bl->poly == -1) /* check its not cyclic */
- bevel_list_cyclic_fix_3D(bl);
-
if (smooth_iter)
bevel_list_smooth(bl, smooth_iter);
@@ -2264,9 +2408,23 @@ static void make_bevel_list_2D(BevList *bl)
bevp1 = bevp - 1;
bevp->sina = bevp1->sina;
bevp->cosa = bevp1->cosa;
+ }
+}
+
+static void bevlist_firstlast_direction_calc_from_bpoint(Nurb *nu, BevList *bl)
+{
+ if (nu->pntsu > 1) {
+ BPoint *first_bp = nu->bp, *last_bp = nu->bp + (nu->pntsu - 1);
+ BevPoint *first_bevp, *last_bevp;
- /* correct for the dir/quat, see above why its needed */
- bevel_list_cyclic_fix_3D(bl);
+ first_bevp = (BevPoint *)(bl + 1);
+ last_bevp = first_bevp + (bl->nr - 1);
+
+ sub_v3_v3v3(first_bevp->dir, (first_bp + 1)->vec, first_bp->vec);
+ normalize_v3(first_bevp->dir);
+
+ sub_v3_v3v3(last_bevp->dir, last_bp->vec, (last_bp - 1)->vec);
+ normalize_v3(last_bevp->dir);
}
}
@@ -2353,6 +2511,10 @@ void BKE_curve_bevelList_make(Object *ob)
bevp++;
bp++;
}
+
+ if ((nu->flagu & CU_NURB_CYCLIC) == 0) {
+ bevlist_firstlast_direction_calc_from_bpoint(nu, bl);
+ }
}
else if (nu->type == CU_BEZIER) {
/* in case last point is not cyclic */
@@ -2375,6 +2537,9 @@ void BKE_curve_bevelList_make(Object *ob)
bezt++;
}
+ sub_v3_v3v3(bevp->dir, prevbezt->vec[2], prevbezt->vec[1]);
+ normalize_v3(bevp->dir);
+
while (a--) {
if (prevbezt->h2 == HD_VECT && bezt->h1 == HD_VECT) {
@@ -2436,6 +2601,10 @@ void BKE_curve_bevelList_make(Object *ob)
bevp->alfa = prevbezt->alfa;
bevp->radius = prevbezt->radius;
bevp->weight = prevbezt->weight;
+
+ sub_v3_v3v3(bevp->dir, prevbezt->vec[1], prevbezt->vec[0]);
+ normalize_v3(bevp->dir);
+
bl->nr++;
}
}
@@ -2456,6 +2625,10 @@ void BKE_curve_bevelList_make(Object *ob)
do_radius ? &bevp->radius : NULL,
do_weight ? &bevp->weight : NULL,
resolu, sizeof(BevPoint));
+
+ if ((nu->flagu & CU_NURB_CYCLIC) == 0) {
+ bevlist_firstlast_direction_calc_from_bpoint(nu, bl);
+ }
}
}
}
@@ -3646,7 +3819,7 @@ void BKE_curve_translate(Curve *cu, float offset[3], int do_keys)
}
}
-void BKE_curve_delete_material_index(Curve *cu, int index)
+void BKE_curve_material_index_remove(Curve *cu, int index)
{
const int curvetype = BKE_curve_type_get(cu);
@@ -3665,8 +3838,32 @@ void BKE_curve_delete_material_index(Curve *cu, int index)
for (nu = cu->nurb.first; nu; nu = nu->next) {
if (nu->mat_nr && nu->mat_nr >= index) {
nu->mat_nr--;
- if (curvetype == OB_CURVE)
+ if (curvetype == OB_CURVE) {
nu->charidx--;
+ }
+ }
+ }
+ }
+}
+
+void BKE_curve_material_index_clear(Curve *cu)
+{
+ const int curvetype = BKE_curve_type_get(cu);
+
+ if (curvetype == OB_FONT) {
+ struct CharInfo *info = cu->strinfo;
+ int i;
+ for (i = cu->len - 1; i >= 0; i--, info++) {
+ info->mat_nr = 0;
+ }
+ }
+ else {
+ Nurb *nu;
+
+ for (nu = cu->nurb.first; nu; nu = nu->next) {
+ nu->mat_nr = 0;
+ if (curvetype == OB_CURVE) {
+ nu->charidx = 0;
}
}
}
diff --git a/source/blender/blenkernel/intern/customdata.c b/source/blender/blenkernel/intern/customdata.c
index 92b3c26c91a..d69ec6a9597 100644
--- a/source/blender/blenkernel/intern/customdata.c
+++ b/source/blender/blenkernel/intern/customdata.c
@@ -218,9 +218,16 @@ static void layerFree_bmesh_elem_py_ptr(void *data, int count, int size)
static void layerInterp_mdeformvert(void **sources, const float *weights,
const float *UNUSED(sub_weights), int count, void *dest)
{
+ /* a single linked list of MDeformWeight's
+ * use this to avoid double allocs (which LinkNode would do) */
+ struct MDeformWeight_Link {
+ struct MDeformWeight_Link *next;
+ MDeformWeight dw;
+ };
+
MDeformVert *dvert = dest;
- LinkNode *dest_dw = NULL; /* a list of lists of MDeformWeight pointers */
- LinkNode *node;
+ struct MDeformWeight_Link *dest_dwlink = NULL;
+ struct MDeformWeight_Link *node;
int i, j, totweight;
if (count <= 0) return;
@@ -238,8 +245,8 @@ static void layerInterp_mdeformvert(void **sources, const float *weights,
if (weight == 0.0f)
continue;
- for (node = dest_dw; node; node = node->next) {
- MDeformWeight *tmp_dw = (MDeformWeight *)node->link;
+ for (node = dest_dwlink; node; node = node->next) {
+ MDeformWeight *tmp_dw = &node->dw;
if (tmp_dw->def_nr == dw->def_nr) {
tmp_dw->weight += weight;
@@ -249,11 +256,14 @@ static void layerInterp_mdeformvert(void **sources, const float *weights,
/* if this def_nr is not in the list, add it */
if (!node) {
- MDeformWeight *tmp_dw = MEM_callocN(sizeof(*tmp_dw),
- "layerInterp_mdeformvert tmp_dw");
- tmp_dw->def_nr = dw->def_nr;
- tmp_dw->weight = weight;
- BLI_linklist_prepend(&dest_dw, tmp_dw);
+ struct MDeformWeight_Link *tmp_dwlink = MEM_mallocN(sizeof(*tmp_dwlink), __func__);
+ tmp_dwlink->dw.def_nr = dw->def_nr;
+ tmp_dwlink->dw.weight = weight;
+
+ /* inline linklist */
+ tmp_dwlink->next = dest_dwlink;
+ dest_dwlink = tmp_dwlink;
+
totweight++;
}
}
@@ -262,20 +272,31 @@ static void layerInterp_mdeformvert(void **sources, const float *weights,
/* delay writing to the destination incase dest is in sources */
/* now we know how many unique deform weights there are, so realloc */
- if (dvert->dw) MEM_freeN(dvert->dw);
+ if (dvert->dw && (dvert->totweight == totweight)) {
+ /* pass (fastpath if we don't need to realloc) */
+ }
+ else {
+ if (dvert->dw) {
+ MEM_freeN(dvert->dw);
+ }
+
+ if (totweight) {
+ dvert->dw = MEM_mallocN(sizeof(*dvert->dw) * totweight, __func__);
+ }
+ }
if (totweight) {
- dvert->dw = MEM_mallocN(sizeof(*dvert->dw) * totweight,
- "layerInterp_mdeformvert dvert->dw");
+ struct MDeformWeight_Link *node_next;
dvert->totweight = totweight;
-
- for (i = 0, node = dest_dw; node; node = node->next, ++i)
- dvert->dw[i] = *((MDeformWeight *)node->link);
+ for (i = 0, node = dest_dwlink; node; node = node_next, i++) {
+ node_next = node->next;
+ dvert->dw[i] = node->dw;
+ MEM_freeN(node);
+ }
}
- else
+ else {
memset(dvert, 0, sizeof(*dvert));
-
- BLI_linklist_free(dest_dw, MEM_freeN);
+ }
}
static void layerCopy_tface(const void *source, void *dest, int count)
diff --git a/source/blender/blenkernel/intern/deform.c b/source/blender/blenkernel/intern/deform.c
index 0dd9d8550bb..882085aa5db 100644
--- a/source/blender/blenkernel/intern/deform.c
+++ b/source/blender/blenkernel/intern/deform.c
@@ -537,7 +537,7 @@ void BKE_deform_split_suffix(const char string[MAX_VGROUP_NAME], char body[MAX_V
body[0] = suf[0] = '\0';
- for (i = len - 1; i > 1; i--) {
+ for (i = len; i > 0; i--) {
if (is_char_sep(string[i])) {
BLI_strncpy(body, string, i + 1);
BLI_strncpy(suf, string + i, (len + 1) - i);
@@ -545,7 +545,7 @@ void BKE_deform_split_suffix(const char string[MAX_VGROUP_NAME], char body[MAX_V
}
}
- BLI_strncpy(body, string, len);
+ memcpy(body, string, len + 1);
}
/* "a.b.c" -> ("a.", "b.c") */
diff --git a/source/blender/blenkernel/intern/dynamicpaint.c b/source/blender/blenkernel/intern/dynamicpaint.c
index 1d5eaf3a1fc..a62ca530bf9 100644
--- a/source/blender/blenkernel/intern/dynamicpaint.c
+++ b/source/blender/blenkernel/intern/dynamicpaint.c
@@ -1078,6 +1078,7 @@ DynamicPaintSurface *dynamicPaint_createNewSurface(DynamicPaintCanvasSettings *c
surface->wave_speed = 1.0f;
surface->wave_timescale = 1.0f;
surface->wave_spring = 0.20f;
+ surface->wave_smoothness = 1.0f;
modifier_path_init(surface->image_output_path, sizeof(surface->image_output_path), "cache_dynamicpaint");
@@ -1253,6 +1254,7 @@ void dynamicPaint_Modifier_copy(struct DynamicPaintModifierData *pmd, struct Dyn
t_surface->wave_speed = surface->wave_speed;
t_surface->wave_timescale = surface->wave_timescale;
t_surface->wave_spring = surface->wave_spring;
+ t_surface->wave_smoothness = surface->wave_smoothness;
BLI_strncpy(t_surface->uvlayer_name, surface->uvlayer_name, sizeof(t_surface->uvlayer_name));
BLI_strncpy(t_surface->image_output_path, surface->image_output_path, sizeof(t_surface->image_output_path));
@@ -3288,7 +3290,7 @@ static int dynamicPaint_paintMesh(DynamicPaintSurface *surface,
if (!brush->dm) return 0;
{
- BVHTreeFromMesh treeData = {0};
+ BVHTreeFromMesh treeData = {NULL};
float avg_brushNor[3] = {0.0f};
float brush_radius = brush->paint_distance * surface->radius_scale;
int numOfVerts;
@@ -4465,6 +4467,7 @@ static void dynamicPaint_doWaveStep(DynamicPaintSurface *surface, float timescal
int steps, ss;
float dt, min_dist, damp_factor;
float wave_speed = surface->wave_speed;
+ float wave_max_slope = (surface->wave_smoothness >= 0.01f) ? (0.5f / surface->wave_smoothness) : 0.0f;
double average_dist = 0.0f;
const float canvas_size = getSurfaceDimension(sData);
float wave_scale = CANVAS_REL_SIZE / canvas_size;
@@ -4503,7 +4506,7 @@ static void dynamicPaint_doWaveStep(DynamicPaintSurface *surface, float timescal
for (index = 0; index < sData->total_points; index++) {
PaintWavePoint *wPoint = &((PaintWavePoint *)sData->type_data)[index];
int numOfNeighs = sData->adj_data->n_num[index];
- float force = 0.0f, avg_dist = 0.0f, avg_height = 0.0f;
+ float force = 0.0f, avg_dist = 0.0f, avg_height = 0.0f, avg_n_height = 0.0f;
int numOfN = 0, numOfRN = 0;
int i;
@@ -4522,11 +4525,12 @@ static void dynamicPaint_doWaveStep(DynamicPaintSurface *surface, float timescal
/* count average height for edge points for open borders */
if (!(sData->adj_data->flags[sData->adj_data->n_target[n_index]] & ADJ_ON_MESH_EDGE)) {
- avg_height += tPoint->height;
+ avg_n_height += tPoint->height;
numOfRN++;
}
force += (tPoint->height - wPoint->height) / (dist * dist);
+ avg_height += tPoint->height;
}
avg_dist = (numOfN) ? avg_dist / numOfN : 0.0f;
@@ -4534,8 +4538,8 @@ static void dynamicPaint_doWaveStep(DynamicPaintSurface *surface, float timescal
sData->adj_data->flags[index] & ADJ_ON_MESH_EDGE)
{
/* if open borders, apply a fake height to keep waves going on */
- avg_height = (numOfRN) ? avg_height / numOfRN : 0.0f;
- wPoint->height = (dt * wave_speed * avg_height + wPoint->height * avg_dist) / (avg_dist + dt * wave_speed);
+ avg_n_height = (numOfRN) ? avg_n_height / numOfRN : 0.0f;
+ wPoint->height = (dt * wave_speed * avg_n_height + wPoint->height * avg_dist) / (avg_dist + dt * wave_speed);
}
/* else do wave eq */
else {
@@ -4549,6 +4553,14 @@ static void dynamicPaint_doWaveStep(DynamicPaintSurface *surface, float timescal
wPoint->velocity *= damp_factor;
/* and new height */
wPoint->height += wPoint->velocity * dt;
+
+ /* limit wave slope steepness */
+ if (wave_max_slope && avg_dist) {
+ float max_offset = wave_max_slope * avg_dist;
+ float offset = (numOfN) ? (avg_height / numOfN - wPoint->height) : 0.0f;
+ if (offset > max_offset) wPoint->height += offset - max_offset;
+ if (offset < -max_offset) wPoint->height += offset + max_offset;
+ }
}
}
}
@@ -4965,7 +4977,7 @@ static int dynamicPaint_doStep(Scene *scene, Object *ob, DynamicPaintSurface *su
/* make sure we're dealing with a brush */
if (pmd2->brush) {
DynamicPaintBrushSettings *brush = pmd2->brush;
- BrushMaterials bMats = {0};
+ BrushMaterials bMats = {NULL};
/* calculate brush speed vectors if required */
if (surface->type == MOD_DPAINT_SURFACE_T_PAINT && brush->flags & MOD_DPAINT_DO_SMUDGE) {
diff --git a/source/blender/blenkernel/intern/editderivedmesh.c b/source/blender/blenkernel/intern/editderivedmesh.c
index ddd5e4a1e02..e8e56c6f17b 100644
--- a/source/blender/blenkernel/intern/editderivedmesh.c
+++ b/source/blender/blenkernel/intern/editderivedmesh.c
@@ -69,11 +69,120 @@ typedef struct EditDerivedBMesh {
BMEditMesh *em;
- float (*vertexCos)[3];
- float (*vertexNos)[3];
- float (*polyNos)[3];
+ /** when set, \a vertexNos, polyNos are lazy initialized */
+ const float (*vertexCos)[3];
+
+ /** lazy initialize (when \a vertexCos is set) */
+ float const (*vertexNos)[3];
+ float const (*polyNos)[3];
+ /** also lazy init but dont depend on \a vertexCos */
+ const float (*polyCos)[3];
} EditDerivedBMesh;
+/* -------------------------------------------------------------------- */
+/* Lazy initialize datastructures */
+
+static void emDM_ensurePolyNormals(EditDerivedBMesh *bmdm);
+
+static void emDM_ensureVertNormals(EditDerivedBMesh *bmdm)
+{
+ if (bmdm->vertexCos && (bmdm->vertexNos == NULL)) {
+
+ BMesh *bm = bmdm->em->bm;
+ const float (*vertexCos)[3], (*polyNos)[3];
+ float (*vertexNos)[3];
+
+ BMFace *efa;
+ BMVert *eve;
+ BMIter fiter;
+ BMIter viter;
+ int i;
+
+ vertexCos = bmdm->vertexCos;
+ vertexNos = MEM_callocN(sizeof(*vertexNos) * bm->totvert, __func__);
+
+ /* calculate vertex normals from poly normals */
+ emDM_ensurePolyNormals(bmdm);
+
+ BM_mesh_elem_index_ensure(bm, BM_FACE);
+
+ vertexCos = bmdm->vertexCos;
+ polyNos = bmdm->polyNos;
+
+ BM_ITER_MESH_INDEX (eve, &viter, bm, BM_VERTS_OF_MESH, i) {
+ float *no = vertexNos[i];
+ BM_ITER_ELEM (efa, &fiter, eve, BM_FACES_OF_VERT) {
+ add_v3_v3(no, polyNos[BM_elem_index_get(efa)]);
+ }
+
+ /* following Mesh convention; we use vertex coordinate itself
+ * for normal in this case */
+ if (UNLIKELY(normalize_v3(no) == 0.0f)) {
+ normalize_v3_v3(no, vertexCos[i]);
+ }
+ }
+
+ bmdm->vertexNos = (const float (*)[3])vertexNos;
+ }
+}
+
+static void emDM_ensurePolyNormals(EditDerivedBMesh *bmdm)
+{
+ if (bmdm->vertexCos && (bmdm->polyNos == NULL)) {
+ BMesh *bm = bmdm->em->bm;
+ const float (*vertexCos)[3];
+ float (*polyNos)[3];
+
+ BMFace *efa;
+ BMIter fiter;
+ int i;
+
+ BM_mesh_elem_index_ensure(bm, BM_VERT);
+
+ polyNos = MEM_mallocN(sizeof(*polyNos) * bm->totface, __func__);
+
+ vertexCos = bmdm->vertexCos;
+
+ BM_ITER_MESH_INDEX (efa, &fiter, bm, BM_FACES_OF_MESH, i) {
+ BM_elem_index_set(efa, i); /* set_inline */
+ BM_face_calc_normal_vcos(bm, efa, polyNos[i], vertexCos);
+ }
+ bm->elem_index_dirty &= ~BM_FACE;
+
+ bmdm->polyNos = (const float (*)[3])polyNos;
+ }
+}
+
+static void emDM_ensurePolyCenters(EditDerivedBMesh *bmdm)
+{
+ if (bmdm->polyCos == NULL) {
+ BMesh *bm = bmdm->em->bm;
+ float (*polyCos)[3];
+
+ BMFace *efa;
+ BMIter fiter;
+ int i;
+
+ polyCos = MEM_mallocN(sizeof(*polyCos) * bm->totface, __func__);
+
+ if (bmdm->vertexCos) {
+ const float (*vertexCos)[3];
+ vertexCos = bmdm->vertexCos;
+
+ BM_ITER_MESH_INDEX (efa, &fiter, bm, BM_FACES_OF_MESH, i) {
+ BM_face_calc_center_mean_vcos(bm, efa, polyCos[i], vertexCos);
+ }
+ }
+ else {
+ BM_ITER_MESH_INDEX (efa, &fiter, bm, BM_FACES_OF_MESH, i) {
+ BM_face_calc_center_mean(efa, polyCos[i]);
+ }
+ }
+
+ bmdm->polyCos = (const float (*)[3])polyCos;
+ }
+}
+
static void emDM_calcNormals(DerivedMesh *dm)
{
/* Nothing to do: normals are already calculated and stored on the
@@ -86,9 +195,11 @@ static void emDM_recalcTessellation(DerivedMesh *UNUSED(dm))
/* do nothing */
}
-static void emDM_foreachMappedVert(DerivedMesh *dm,
- void (*func)(void *userData, int index, const float co[3], const float no_f[3], const short no_s[3]),
- void *userData)
+static void emDM_foreachMappedVert(
+ DerivedMesh *dm,
+ void (*func)(void *userData, int index, const float co[3], const float no_f[3], const short no_s[3]),
+ void *userData,
+ DMForeachFlag flag)
{
EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
BMesh *bm = bmdm->em->bm;
@@ -97,13 +208,26 @@ static void emDM_foreachMappedVert(DerivedMesh *dm,
int i;
if (bmdm->vertexCos) {
+ const float (*vertexCos)[3] = bmdm->vertexCos;
+ const float (*vertexNos)[3];
+
+ if (flag & DM_FOREACH_USE_NORMAL) {
+ emDM_ensureVertNormals(bmdm);
+ vertexNos = bmdm->vertexNos;
+ }
+ else {
+ vertexNos = NULL;
+ }
+
BM_ITER_MESH_INDEX (eve, &iter, bm, BM_VERTS_OF_MESH, i) {
- func(userData, i, bmdm->vertexCos[i], bmdm->vertexNos[i], NULL);
+ const float *no = (flag & DM_FOREACH_USE_NORMAL) ? vertexNos[i] : NULL;
+ func(userData, i, vertexCos[i], no, NULL);
}
}
else {
BM_ITER_MESH_INDEX (eve, &iter, bm, BM_VERTS_OF_MESH, i) {
- func(userData, i, eve->co, eve->no, NULL);
+ const float *no = (flag & DM_FOREACH_USE_NORMAL) ? eve->no : NULL;
+ func(userData, i, eve->co, no, NULL);
}
}
}
@@ -248,56 +372,42 @@ static void emDM_drawUVEdges(DerivedMesh *dm)
glEnd();
}
-static void emDM__calcFaceCent(BMFace *efa, float cent[3], float (*vertexCos)[3])
-{
- BMIter liter;
- BMLoop *l;
- int tot = 0;
-
- zero_v3(cent);
-
- /*simple (and stupid) median (average) based method :/ */
-
- if (vertexCos) {
- BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
- add_v3_v3(cent, vertexCos[BM_elem_index_get(l->v)]);
- tot++;
- }
- }
- else {
- BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
- add_v3_v3(cent, l->v->co);
- tot++;
- }
- }
-
- if (tot == 0) return;
- mul_v3_fl(cent, 1.0f / (float)tot);
-}
-
-static void emDM_foreachMappedFaceCenter(DerivedMesh *dm,
- void (*func)(void *userData, int index, const float co[3], const float no[3]),
- void *userData)
+static void emDM_foreachMappedFaceCenter(
+ DerivedMesh *dm,
+ void (*func)(void *userData, int index, const float co[3], const float no[3]),
+ void *userData,
+ DMForeachFlag flag)
{
EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
BMesh *bm = bmdm->em->bm;
- float (*polyNos)[3] = NULL;
+ const float (*polyNos)[3];
+ const float (*polyCos)[3];
BMFace *efa;
BMIter iter;
- float cent[3];
int i;
- /* ensure for face center calculation */
- if (bmdm->vertexCos) {
- BM_mesh_elem_index_ensure(bm, BM_VERT);
- polyNos = bmdm->polyNos;
+ emDM_ensurePolyCenters(bmdm);
+ polyCos = bmdm->polyCos; /* always set */
- BLI_assert(polyNos != NULL);
+ if (flag & DM_FOREACH_USE_NORMAL) {
+ emDM_ensurePolyNormals(bmdm);
+ polyNos = bmdm->polyNos; /* maybe NULL */
+ }
+ else {
+ polyNos = NULL;
}
- BM_ITER_MESH_INDEX (efa, &iter, bm, BM_FACES_OF_MESH, i) {
- emDM__calcFaceCent(efa, cent, bmdm->vertexCos);
- func(userData, i, cent, polyNos ? polyNos[i] : efa->no);
+ if (polyNos) {
+ BM_ITER_MESH_INDEX (efa, &iter, bm, BM_FACES_OF_MESH, i) {
+ const float *no = polyNos[i];
+ func(userData, i, polyCos[i], no);
+ }
+ }
+ else {
+ BM_ITER_MESH_INDEX (efa, &iter, bm, BM_FACES_OF_MESH, i) {
+ const float *no = (flag & DM_FOREACH_USE_NORMAL) ? efa->no : NULL;
+ func(userData, i, polyCos[i], no);
+ }
}
}
@@ -349,10 +459,20 @@ static void emDM_drawMappedFaces(DerivedMesh *dm,
if (bmdm->vertexCos) {
/* add direct access */
- float (*vertexCos)[3] = bmdm->vertexCos;
- float (*vertexNos)[3] = bmdm->vertexNos;
- float (*polyNos)[3] = bmdm->polyNos;
- // int *triPolyMap = bmdm->triPolyMap;
+ const float (*vertexCos)[3] = bmdm->vertexCos;
+ const float (*vertexNos)[3];
+ const float (*polyNos)[3];
+
+ if (skip_normals) {
+ vertexNos = NULL;
+ polyNos = NULL;
+ }
+ else {
+ emDM_ensureVertNormals(bmdm);
+ emDM_ensurePolyNormals(bmdm);
+ vertexNos = bmdm->vertexNos;
+ polyNos = bmdm->polyNos;
+ }
BM_mesh_elem_index_ensure(bm, BM_VERT | BM_FACE);
@@ -561,9 +681,6 @@ static void emDM_drawFacesTex_common(DerivedMesh *dm,
BMEditMesh *em = bmdm->em;
BMesh *bm = em->bm;
struct BMLoop *(*looptris)[3] = em->looptris;
- float (*vertexCos)[3] = bmdm->vertexCos;
- float (*vertexNos)[3] = bmdm->vertexNos;
- float (*polyNos)[3] = bmdm->polyNos;
BMFace *efa;
MLoopUV *luv[3], dummyluv = {{0}};
MLoopCol *lcol[3] = {NULL} /* , dummylcol = {0} */;
@@ -593,7 +710,17 @@ static void emDM_drawFacesTex_common(DerivedMesh *dm,
BM_mesh_elem_index_ensure(bm, BM_VERT);
}
- if (vertexCos) {
+ if (bmdm->vertexCos) {
+ /* add direct access */
+ const float (*vertexCos)[3] = bmdm->vertexCos;
+ const float (*vertexNos)[3];
+ const float (*polyNos)[3];
+
+ emDM_ensureVertNormals(bmdm);
+ emDM_ensurePolyNormals(bmdm);
+ vertexNos = bmdm->vertexNos;
+ polyNos = bmdm->polyNos;
+
BM_mesh_elem_index_ensure(bm, BM_VERT);
for (i = 0; i < em->tottri; i++) {
@@ -791,9 +918,11 @@ static void emDM_drawMappedFacesGLSL(DerivedMesh *dm,
BMEditMesh *em = bmdm->em;
BMesh *bm = em->bm;
struct BMLoop *(*looptris)[3] = em->looptris;
- float (*vertexCos)[3] = bmdm->vertexCos;
- float (*vertexNos)[3] = bmdm->vertexNos;
- float (*polyNos)[3] = bmdm->polyNos;
+ /* add direct access */
+ const float (*vertexCos)[3] = bmdm->vertexCos;
+ const float (*vertexNos)[3];
+ const float (*polyNos)[3];
+
BMFace *efa;
DMVertexAttribs attribs;
GPUVertexAttribs gattribs;
@@ -805,6 +934,11 @@ static void emDM_drawMappedFacesGLSL(DerivedMesh *dm,
memset(&attribs, 0, sizeof(attribs));
+ emDM_ensureVertNormals(bmdm);
+ emDM_ensurePolyNormals(bmdm);
+ vertexNos = bmdm->vertexNos;
+ polyNos = bmdm->polyNos;
+
/* always use smooth shading even for flat faces, else vertex colors wont interpolate */
glShadeModel(GL_SMOOTH);
BM_mesh_elem_index_ensure(bm, BM_VERT | BM_FACE);
@@ -926,16 +1060,22 @@ static void emDM_drawMappedFacesMat(DerivedMesh *dm,
BMEditMesh *em = bmdm->em;
BMesh *bm = em->bm;
struct BMLoop *(*looptris)[3] = em->looptris;
- float (*vertexCos)[3] = bmdm->vertexCos;
- float (*vertexNos)[3] = bmdm->vertexNos;
- float (*polyNos)[3] = bmdm->polyNos;
+ const float (*vertexCos)[3] = bmdm->vertexCos;
+ const float (*vertexNos)[3];
+ const float (*polyNos)[3];
BMFace *efa;
- DMVertexAttribs attribs = {{{0}}};
+ DMVertexAttribs attribs = {{{NULL}}};
GPUVertexAttribs gattribs;
int i, matnr, new_matnr;
matnr = -1;
+ emDM_ensureVertNormals(bmdm);
+ emDM_ensurePolyNormals(bmdm);
+
+ vertexNos = bmdm->vertexNos;
+ polyNos = bmdm->polyNos;
+
/* always use smooth shading even for flat faces, else vertex colors wont interpolate */
glShadeModel(GL_SMOOTH);
@@ -1139,7 +1279,9 @@ static void emDM_getVertNo(DerivedMesh *dm, int index, float r_no[3])
return;
}
- if (bmdm->vertexNos) {
+
+ if (bmdm->vertexCos) {
+ emDM_ensureVertNormals(bmdm);
copy_v3_v3(r_no, bmdm->vertexNos[index]);
}
else {
@@ -1159,7 +1301,8 @@ static void emDM_getPolyNo(DerivedMesh *dm, int index, float r_no[3])
return;
}
- if (bmdm->polyNos) {
+ if (bmdm->vertexCos) {
+ emDM_ensurePolyNormals(bmdm);
copy_v3_v3(r_no, bmdm->polyNos[index]);
}
else {
@@ -1313,18 +1456,19 @@ static void emDM_copyLoopArray(DerivedMesh *dm, MLoop *r_loop)
{
EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
BMesh *bm = bmdm->em->bm;
- BMIter iter, liter;
+ BMIter iter;
BMFace *efa;
- BMLoop *l;
BM_mesh_elem_index_ensure(bm, BM_VERT | BM_EDGE);
BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) {
- BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
- r_loop->v = BM_elem_index_get(l->v);
- r_loop->e = BM_elem_index_get(l->e);
+ BMLoop *l_iter, *l_first;
+ l_iter = l_first = BM_FACE_FIRST_LOOP(efa);
+ do {
+ r_loop->v = BM_elem_index_get(l_iter->v);
+ r_loop->e = BM_elem_index_get(l_iter->e);
r_loop++;
- }
+ } while ((l_iter = l_iter->next) != l_first);
}
}
@@ -1438,9 +1582,17 @@ static void emDM_release(DerivedMesh *dm)
if (DM_release(dm)) {
if (bmdm->vertexCos) {
- MEM_freeN(bmdm->vertexCos);
- MEM_freeN(bmdm->vertexNos);
- MEM_freeN(bmdm->polyNos);
+ MEM_freeN((void *)bmdm->vertexCos);
+ if (bmdm->vertexNos) {
+ MEM_freeN((void *)bmdm->vertexNos);
+ }
+ if (bmdm->polyNos) {
+ MEM_freeN((void *)bmdm->polyNos);
+ }
+ }
+
+ if (bmdm->polyCos) {
+ MEM_freeN((void *)bmdm->polyCos);
}
MEM_freeN(bmdm);
@@ -1549,7 +1701,7 @@ DerivedMesh *getEditDerivedBMesh(BMEditMesh *em,
bmdm->dm.release = emDM_release;
- bmdm->vertexCos = vertexCos;
+ bmdm->vertexCos = (const float (*)[3])vertexCos;
bmdm->dm.deformedOnly = (vertexCos != NULL);
if (cd_dvert_offset != -1) {
@@ -1578,38 +1730,6 @@ DerivedMesh *getEditDerivedBMesh(BMEditMesh *em,
}
}
- if (vertexCos) {
- BMFace *efa;
- BMVert *eve;
- BMIter fiter;
- BMIter viter;
- int i;
-
- BM_mesh_elem_index_ensure(bm, BM_VERT);
-
- bmdm->vertexNos = MEM_callocN(sizeof(*bmdm->vertexNos) * bm->totvert, "bmdm_vno");
- bmdm->polyNos = MEM_mallocN(sizeof(*bmdm->polyNos) * bm->totface, "bmdm_pno");
-
- BM_ITER_MESH_INDEX (efa, &fiter, bm, BM_FACES_OF_MESH, i) {
- BM_elem_index_set(efa, i); /* set_inline */
- BM_face_normal_update_vcos(bm, efa, bmdm->polyNos[i], (float const (*)[3])vertexCos);
- }
- bm->elem_index_dirty &= ~BM_FACE;
-
- BM_ITER_MESH_INDEX (eve, &viter, bm, BM_VERTS_OF_MESH, i) {
- float *no = bmdm->vertexNos[i];
- BM_ITER_ELEM (efa, &fiter, eve, BM_FACES_OF_VERT) {
- add_v3_v3(no, bmdm->polyNos[BM_elem_index_get(efa)]);
- }
-
- /* following Mesh convention; we use vertex coordinate itself
- * for normal in this case */
- if (UNLIKELY(normalize_v3(no) == 0.0f)) {
- normalize_v3_v3(no, vertexCos[i]);
- }
- }
- }
-
return (DerivedMesh *)bmdm;
}
@@ -1877,7 +1997,7 @@ static void statvis_calc_intersect(
static void statvis_calc_distort(
BMEditMesh *em,
- const float (*vertexCos)[3],
+ const float (*vertexCos)[3], const float (*polyNos)[3],
/* values for calculating */
const float min, const float max,
/* result */
@@ -1886,7 +2006,7 @@ static void statvis_calc_distort(
BMIter iter;
BMesh *bm = em->bm;
BMFace *f;
- float f_no[3];
+ const float *f_no;
int index;
const float minmax_irange = 1.0f / (max - min);
@@ -1903,10 +2023,10 @@ static void statvis_calc_distort(
else {
BMLoop *l_iter, *l_first;
if (vertexCos) {
- BM_face_normal_update_vcos(bm, f, f_no, vertexCos);
+ f_no = polyNos[index];
}
else {
- copy_v3_v3(f_no, f->no);
+ f_no = f->no;
}
fac = 0.0f;
@@ -2006,7 +2126,7 @@ void BKE_editmesh_statvis_calc(BMEditMesh *em, DerivedMesh *dm,
{
BKE_editmesh_color_ensure(em, BM_FACE);
statvis_calc_overhang(
- em, bmdm ? (const float (*)[3])bmdm->polyNos : NULL,
+ em, bmdm ? bmdm->polyNos : NULL,
statvis->overhang_min / (float)M_PI,
statvis->overhang_max / (float)M_PI,
statvis->overhang_axis,
@@ -2018,7 +2138,7 @@ void BKE_editmesh_statvis_calc(BMEditMesh *em, DerivedMesh *dm,
const float scale = 1.0f / mat4_to_scale(em->ob->obmat);
BKE_editmesh_color_ensure(em, BM_FACE);
statvis_calc_thickness(
- em, bmdm ? (const float (*)[3])bmdm->vertexCos : NULL,
+ em, bmdm ? bmdm->vertexCos : NULL,
statvis->thickness_min * scale,
statvis->thickness_max * scale,
statvis->thickness_samples,
@@ -2029,15 +2149,19 @@ void BKE_editmesh_statvis_calc(BMEditMesh *em, DerivedMesh *dm,
{
BKE_editmesh_color_ensure(em, BM_FACE);
statvis_calc_intersect(
- em, bmdm ? (const float (*)[3])bmdm->vertexCos : NULL,
+ em, bmdm ? bmdm->vertexCos : NULL,
em->derivedFaceColor);
break;
}
case SCE_STATVIS_DISTORT:
{
BKE_editmesh_color_ensure(em, BM_FACE);
+
+ if (bmdm)
+ emDM_ensurePolyNormals(bmdm);
+
statvis_calc_distort(
- em, bmdm ? (const float (*)[3])bmdm->vertexCos : NULL,
+ em, bmdm ? bmdm->vertexCos : NULL, bmdm ? bmdm->polyNos : NULL,
statvis->distort_min,
statvis->distort_max,
em->derivedFaceColor);
@@ -2047,7 +2171,7 @@ void BKE_editmesh_statvis_calc(BMEditMesh *em, DerivedMesh *dm,
{
BKE_editmesh_color_ensure(em, BM_VERT);
statvis_calc_sharp(
- em, bmdm ? (const float (*)[3])bmdm->vertexCos : NULL,
+ em, bmdm ? bmdm->vertexCos : NULL,
statvis->sharp_min,
statvis->sharp_max,
/* in this case they are vertex colors */
@@ -2065,7 +2189,7 @@ void BKE_editmesh_statvis_calc(BMEditMesh *em, DerivedMesh *dm,
struct CageUserData {
int totvert;
float (*cos_cage)[3];
- BLI_bitmap visit_bitmap;
+ BLI_bitmap *visit_bitmap;
};
static void cage_mapped_verts_callback(void *userData, int index, const float co[3],
@@ -2082,7 +2206,7 @@ static void cage_mapped_verts_callback(void *userData, int index, const float co
float (*BKE_editmesh_vertexCos_get(BMEditMesh *em, Scene *scene, int *r_numVerts))[3]
{
DerivedMesh *cage, *final;
- BLI_bitmap visit_bitmap;
+ BLI_bitmap *visit_bitmap;
struct CageUserData data;
float (*cos_cage)[3];
@@ -2097,7 +2221,7 @@ float (*BKE_editmesh_vertexCos_get(BMEditMesh *em, Scene *scene, int *r_numVerts
data.cos_cage = cos_cage;
data.visit_bitmap = visit_bitmap;
- cage->foreachMappedVert(cage, cage_mapped_verts_callback, &data);
+ cage->foreachMappedVert(cage, cage_mapped_verts_callback, &data, DM_FOREACH_NOP);
MEM_freeN(visit_bitmap);
diff --git a/source/blender/blenkernel/intern/fmodifier.c b/source/blender/blenkernel/intern/fmodifier.c
index 915c75a0e7f..f24edfea136 100644
--- a/source/blender/blenkernel/intern/fmodifier.c
+++ b/source/blender/blenkernel/intern/fmodifier.c
@@ -144,12 +144,8 @@ static void fcm_generator_verify(FModifier *fcm)
const int arraysize_new = data->poly_order + 1;
/* arraysize needs to be order+1, so resize if not */
if (data->arraysize != arraysize_new) {
- if (data->coefficients) {
- data->coefficients = MEM_recallocN(data->coefficients, sizeof(float) * arraysize_new);
- }
- else {
- data->coefficients = MEM_callocN(sizeof(float) * arraysize_new, "FMod_Generator_Coefs");
- }
+ data->coefficients = MEM_recallocN(data->coefficients,
+ sizeof(float) * arraysize_new);
data->arraysize = arraysize_new;
}
break;
@@ -159,12 +155,8 @@ static void fcm_generator_verify(FModifier *fcm)
const int arraysize_new = data->poly_order * 2;
/* arraysize needs to be (2 * order), so resize if not */
if (data->arraysize != arraysize_new) {
- if (data->coefficients) {
- data->coefficients = MEM_recallocN(data->coefficients, sizeof(float) * arraysize_new);
- }
- else {
- data->coefficients = MEM_callocN(sizeof(float) * arraysize_new, "FMod_Generator_Coefs");
- }
+ data->coefficients = MEM_recallocN(data->coefficients,
+ sizeof(float) * arraysize_new);
data->arraysize = arraysize_new;
}
break;
diff --git a/source/blender/blenkernel/intern/image.c b/source/blender/blenkernel/intern/image.c
index 1a444d497a0..86382c64ed3 100644
--- a/source/blender/blenkernel/intern/image.c
+++ b/source/blender/blenkernel/intern/image.c
@@ -597,7 +597,8 @@ Image *BKE_image_load(Main *bmain, const char *filepath)
/* exists? */
file = BLI_open(str, O_BINARY | O_RDONLY, 0);
- if (file == -1) return NULL;
+ if (file < 0)
+ return NULL;
close(file);
/* create a short library name */
@@ -652,7 +653,7 @@ Image *BKE_image_load_exists(const char *filepath)
}
static ImBuf *add_ibuf_size(unsigned int width, unsigned int height, const char *name, int depth, int floatbuf, short gen_type,
- float color[4], ColorManagedColorspaceSettings *colorspace_settings)
+ const float color[4], ColorManagedColorspaceSettings *colorspace_settings)
{
ImBuf *ibuf;
unsigned char *rect = NULL;
@@ -709,7 +710,7 @@ static ImBuf *add_ibuf_size(unsigned int width, unsigned int height, const char
}
/* adds new image block, creates ImBuf and initializes color */
-Image *BKE_image_add_generated(Main *bmain, unsigned int width, unsigned int height, const char *name, int depth, int floatbuf, short gen_type, float color[4])
+Image *BKE_image_add_generated(Main *bmain, unsigned int width, unsigned int height, const char *name, int depth, int floatbuf, short gen_type, const float color[4])
{
/* on save, type is changed to FILE in editsima.c */
Image *ima = image_alloc(bmain, name, IMA_SRC_GENERATED, IMA_TYPE_UV_TEST);
@@ -722,6 +723,7 @@ Image *BKE_image_add_generated(Main *bmain, unsigned int width, unsigned int hei
ima->gen_y = height;
ima->gen_type = gen_type;
ima->gen_flag |= (floatbuf ? IMA_GEN_FLOAT : 0);
+ ima->gen_depth = depth;
ibuf = add_ibuf_size(width, height, ima->name, depth, floatbuf, gen_type, color, &ima->colorspace_settings);
image_assign_ibuf(ima, ibuf, IMA_NO_INDEX, 0);
@@ -2995,7 +2997,8 @@ static ImBuf *image_acquire_ibuf(Image *ima, ImageUser *iuser, void **lock_r)
/* UV testgrid or black or solid etc */
if (ima->gen_x == 0) ima->gen_x = 1024;
if (ima->gen_y == 0) ima->gen_y = 1024;
- ibuf = add_ibuf_size(ima->gen_x, ima->gen_y, ima->name, 24, (ima->gen_flag & IMA_GEN_FLOAT) != 0, ima->gen_type,
+ if (ima->gen_depth == 0) ima->gen_depth = 24;
+ ibuf = add_ibuf_size(ima->gen_x, ima->gen_y, ima->name, ima->gen_depth, (ima->gen_flag & IMA_GEN_FLOAT) != 0, ima->gen_type,
color, &ima->colorspace_settings);
image_assign_ibuf(ima, ibuf, IMA_NO_INDEX, 0);
ima->ok = IMA_OK_LOADED;
diff --git a/source/blender/blenkernel/intern/image_gen.c b/source/blender/blenkernel/intern/image_gen.c
index eda22a095ef..71b4f9947a4 100644
--- a/source/blender/blenkernel/intern/image_gen.c
+++ b/source/blender/blenkernel/intern/image_gen.c
@@ -336,7 +336,7 @@ static void checker_board_text(unsigned char *rect, float *rect_float, int width
}
/* cleanup the buffer. */
- BLF_buffer(mono, NULL, NULL, 0, 0, 0, FALSE);
+ BLF_buffer(mono, NULL, NULL, 0, 0, 0, NULL);
}
void BKE_image_buf_fill_checker_color(unsigned char *rect, float *rect_float, int width, int height)
diff --git a/source/blender/blenkernel/intern/key.c b/source/blender/blenkernel/intern/key.c
index a79fa3873f5..d2d2cb1c2d0 100644
--- a/source/blender/blenkernel/intern/key.c
+++ b/source/blender/blenkernel/intern/key.c
@@ -190,7 +190,8 @@ Key *BKE_key_copy_nolib(Key *key)
Key *keyn;
KeyBlock *kbn, *kb;
- if (key == 0) return 0;
+ if (key == NULL)
+ return NULL;
keyn = MEM_dupallocN(key);
@@ -533,7 +534,7 @@ static char *key_block_get_data(Key *key, KeyBlock *actkb, KeyBlock *kb, char **
if (me->edit_btmesh && me->edit_btmesh->bm->totvert == kb->totelem) {
a = 0;
- co = MEM_callocN(sizeof(float) * 3 * me->edit_btmesh->bm->totvert, "key_block_get_data");
+ co = MEM_mallocN(sizeof(float) * 3 * me->edit_btmesh->bm->totvert, "key_block_get_data");
BM_ITER_MESH (eve, &iter, me->edit_btmesh->bm, BM_VERTS_OF_MESH) {
copy_v3_v3(co[a], eve->co);
@@ -1091,7 +1092,7 @@ static float *get_weights_array(Object *ob, char *vgroup)
float *weights;
int i;
- weights = MEM_callocN(totvert * sizeof(float), "weights");
+ weights = MEM_mallocN(totvert * sizeof(float), "weights");
if (em) {
const int cd_dvert_offset = CustomData_get_offset(&em->bm->vdata, CD_MDEFORMVERT);
@@ -1622,7 +1623,7 @@ void BKE_key_convert_from_lattice(Lattice *lt, KeyBlock *kb)
if (kb->data) MEM_freeN(kb->data);
- kb->data = MEM_callocN(lt->key->elemsize * tot, "kb->data");
+ kb->data = MEM_mallocN(lt->key->elemsize * tot, "kb->data");
kb->totelem = tot;
bp = lt->def;
@@ -1664,7 +1665,7 @@ void BKE_key_convert_from_curve(Curve *cu, KeyBlock *kb, ListBase *nurb)
if (kb->data) MEM_freeN(kb->data);
- kb->data = MEM_callocN(cu->key->elemsize * tot, "kb->data");
+ kb->data = MEM_mallocN(cu->key->elemsize * tot, "kb->data");
kb->totelem = tot;
nu = nurb->first;
@@ -1762,7 +1763,7 @@ void BKE_key_convert_from_mesh(Mesh *me, KeyBlock *kb)
if (kb->data) MEM_freeN(kb->data);
- kb->data = MEM_callocN(me->key->elemsize * me->totvert, "kb->data");
+ kb->data = MEM_mallocN(me->key->elemsize * me->totvert, "kb->data");
kb->totelem = me->totvert;
mvert = me->mvert;
@@ -1812,7 +1813,7 @@ float (*BKE_key_convert_to_vertcos(Object *ob, KeyBlock *kb))[3]
if (tot == 0) return NULL;
- vertCos = MEM_callocN(tot * sizeof(*vertCos), "BKE_key_convert_to_vertcos vertCos");
+ vertCos = MEM_mallocN(tot * sizeof(*vertCos), "BKE_key_convert_to_vertcos vertCos");
/* Copy coords to array */
co = (float *)vertCos;
@@ -1895,7 +1896,7 @@ void BKE_key_convert_from_vertcos(Object *ob, KeyBlock *kb, float (*vertCos)[3])
return;
}
- fp = kb->data = MEM_callocN(tot * elemsize, "BKE_key_convert_to_vertcos vertCos");
+ fp = kb->data = MEM_mallocN(tot * elemsize, "BKE_key_convert_to_vertcos vertCos");
/* Copy coords to keyblock */
diff --git a/source/blender/blenkernel/intern/library.c b/source/blender/blenkernel/intern/library.c
index 7eb4a3a2a8d..c23fa097d3e 100644
--- a/source/blender/blenkernel/intern/library.c
+++ b/source/blender/blenkernel/intern/library.c
@@ -1264,17 +1264,13 @@ static ID *is_dupid(ListBase *lb, ID *id, const char *name)
static bool check_for_dupid(ListBase *lb, ID *id, char *name)
{
ID *idtest;
- int nr = 0, nrtest, a, left_len;
+ int nr = 0, a, left_len;
#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];
- /* make sure input name is terminated properly */
- /* 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 (true) {
/* phase 1: id already exists? */
@@ -1301,6 +1297,7 @@ static bool check_for_dupid(ListBase *lb, ID *id, char *name)
}
for (idtest = lb->first; idtest; idtest = idtest->next) {
+ int nrtest;
if ( (id != idtest) &&
(idtest->lib == NULL) &&
(*name == *(idtest->name + 2)) &&
@@ -1315,8 +1312,8 @@ static bool check_for_dupid(ListBase *lb, ID *id, char *name)
nr = nrtest + 1; /* track largest unused */
}
}
- /* At this point, nr will be at least 1. */
- BLI_assert(nr >= 1);
+ /* At this point, 'nr' will typically be at least 1. (but not always) */
+ // BLI_assert(nr >= 1);
/* decide which value of nr to use */
for (a = 0; a < MAX_IN_USE; a++) {
diff --git a/source/blender/blenkernel/intern/mask.c b/source/blender/blenkernel/intern/mask.c
index b3c5ceefb2d..e3f30bad5cf 100644
--- a/source/blender/blenkernel/intern/mask.c
+++ b/source/blender/blenkernel/intern/mask.c
@@ -602,7 +602,7 @@ float BKE_mask_point_weight(MaskSpline *spline, MaskSplinePoint *point, const fl
float cur_u = 0.0f, cur_w = 0.0f, next_u = 0.0f, next_w = 0.0f, fac; /* Quite warnings */
int i;
- for (i = 0; i < point->tot_uw + 1; i++) {
+ for (i = 0; i <= point->tot_uw; i++) {
if (i == 0) {
cur_u = 0.0f;
@@ -939,8 +939,6 @@ void BKE_mask_free(Main *bmain, Mask *mask)
SpaceLink *sl;
Scene *scene;
- BKE_sequencer_clear_mask_in_clipboard(mask);
-
for (scr = bmain->screen.first; scr; scr = scr->id.next) {
for (area = scr->areabase.first; area; area = area->next) {
for (sl = area->spacedata.first; sl; sl = sl->next) {
diff --git a/source/blender/blenkernel/intern/material.c b/source/blender/blenkernel/intern/material.c
index e14b51975c8..1bda662a8b0 100644
--- a/source/blender/blenkernel/intern/material.c
+++ b/source/blender/blenkernel/intern/material.c
@@ -537,17 +537,17 @@ short *give_totcolp_id(ID *id)
return NULL;
}
-static void data_delete_material_index_id(ID *id, short index)
+static void material_data_index_remove_id(ID *id, short index)
{
/* ensure we don't try get materials from non-obdata */
BLI_assert(OB_DATA_SUPPORT_ID(GS(id->name)));
switch (GS(id->name)) {
case ID_ME:
- BKE_mesh_delete_material_index((Mesh *)id, index);
+ BKE_mesh_material_index_remove((Mesh *)id, index);
break;
case ID_CU:
- BKE_curve_delete_material_index((Curve *)id, index);
+ BKE_curve_material_index_remove((Curve *)id, index);
break;
case ID_MB:
/* meta-elems don't have materials atm */
@@ -555,7 +555,25 @@ static void data_delete_material_index_id(ID *id, short index)
}
}
-void material_append_id(ID *id, Material *ma)
+static void material_data_index_clear_id(ID *id)
+{
+ /* ensure we don't try get materials from non-obdata */
+ BLI_assert(OB_DATA_SUPPORT_ID(GS(id->name)));
+
+ switch (GS(id->name)) {
+ case ID_ME:
+ BKE_mesh_material_index_clear((Mesh *)id);
+ break;
+ case ID_CU:
+ BKE_curve_material_index_clear((Curve *)id);
+ break;
+ case ID_MB:
+ /* meta-elems don't have materials atm */
+ break;
+ }
+}
+
+void BKE_material_append_id(ID *id, Material *ma)
{
Material ***matar;
if ((matar = give_matarar_id(id))) {
@@ -572,7 +590,7 @@ void material_append_id(ID *id, Material *ma)
}
}
-Material *material_pop_id(ID *id, int index_i, int remove_material_slot)
+Material *BKE_material_pop_id(ID *id, int index_i, bool update_data)
{
short index = (short)index_i;
Material *ret = NULL;
@@ -583,40 +601,48 @@ Material *material_pop_id(ID *id, int index_i, int remove_material_slot)
ret = (*matar)[index];
id_us_min((ID *)ret);
- if (remove_material_slot) {
- if (*totcol <= 1) {
- *totcol = 0;
- MEM_freeN(*matar);
- *matar = NULL;
- }
- else {
- Material **mat;
- if (index + 1 != (*totcol))
- memmove((*matar) + index, (*matar) + (index + 1), sizeof(void *) * ((*totcol) - (index + 1)));
-
- (*totcol)--;
-
- mat = MEM_callocN(sizeof(void *) * (*totcol), "newmatar");
- memcpy(mat, *matar, sizeof(void *) * (*totcol));
- MEM_freeN(*matar);
-
- *matar = mat;
- test_object_materials(G.main, id);
- }
+ if (*totcol <= 1) {
+ *totcol = 0;
+ MEM_freeN(*matar);
+ *matar = NULL;
+ }
+ else {
+ if (index + 1 != (*totcol))
+ memmove((*matar) + index, (*matar) + (index + 1), sizeof(void *) * ((*totcol) - (index + 1)));
- /* decrease mat_nr index */
- data_delete_material_index_id(id, index);
+ (*totcol)--;
+ *matar = MEM_reallocN(*matar, sizeof(void *) * (*totcol));
+ test_object_materials(G.main, id);
}
- /* don't remove material slot, only clear it*/
- else
- (*matar)[index] = NULL;
+ if (update_data) {
+ /* decrease mat_nr index */
+ material_data_index_remove_id(id, index);
+ }
}
}
return ret;
}
+void BKE_material_clear_id(struct ID *id, bool update_data)
+{
+ Material ***matar;
+ if ((matar = give_matarar_id(id))) {
+ short *totcol = give_totcolp_id(id);
+ *totcol = 0;
+ if (*matar) {
+ MEM_freeN(*matar);
+ *matar = NULL;
+ }
+
+ if (update_data) {
+ /* decrease mat_nr index */
+ material_data_index_clear_id(id);
+ }
+ }
+}
+
Material *give_current_material(Object *ob, short act)
{
Material ***matarar, *ma;
@@ -1148,55 +1174,6 @@ void material_drivers_update(Scene *scene, Material *ma, float ctime)
ma->id.flag &= ~LIB_DOIT;
}
-
-/* ****************** */
-#if 0 /* UNUSED */
-static char colname_array[125][20] = {
-"Black", "DarkRed", "HalfRed", "Red", "Red",
-"DarkGreen", "DarkOlive", "Brown", "Chocolate", "OrangeRed",
-"HalfGreen", "GreenOlive", "DryOlive", "Goldenrod", "DarkOrange",
-"LightGreen", "Chartreuse", "YellowGreen", "Yellow", "Gold",
-"Green", "LawnGreen", "GreenYellow", "LightOlive", "Yellow",
-"DarkBlue", "DarkPurple", "HotPink", "VioletPink", "RedPink",
-"SlateGray", "DarkGray", "PalePurple", "IndianRed", "Tomato",
-"SeaGreen", "PaleGreen", "GreenKhaki", "LightBrown", "LightSalmon",
-"SpringGreen", "PaleGreen", "MediumOlive", "YellowBrown", "LightGold",
-"LightGreen", "LightGreen", "LightGreen", "GreenYellow", "PaleYellow",
-"HalfBlue", "DarkSky", "HalfMagenta", "VioletRed", "DeepPink",
-"SteelBlue", "SkyBlue", "Orchid", "LightHotPink", "HotPink",
-"SeaGreen", "SlateGray", "MediumGray", "Burlywood", "LightPink",
-"SpringGreen", "Aquamarine", "PaleGreen", "Khaki", "PaleOrange",
-"SpringGreen", "SeaGreen", "PaleGreen", "PaleWhite", "YellowWhite",
-"LightBlue", "Purple", "MediumOrchid", "Magenta", "Magenta",
-"RoyalBlue", "SlateBlue", "MediumOrchid", "Orchid", "Magenta",
-"DeepSkyBlue", "LightSteelBlue", "LightSkyBlue", "Violet", "LightPink",
-"Cyan", "DarkTurquoise", "SkyBlue", "Gray", "Snow",
-"Mint", "Mint", "Aquamarine", "MintCream", "Ivory",
-"Blue", "Blue", "DarkMagenta", "DarkOrchid", "Magenta",
-"SkyBlue", "RoyalBlue", "LightSlateBlue", "MediumOrchid", "Magenta",
-"DodgerBlue", "SteelBlue", "MediumPurple", "PalePurple", "Plum",
-"DeepSkyBlue", "PaleBlue", "LightSkyBlue", "PalePurple", "Thistle",
-"Cyan", "ColdBlue", "PaleTurquoise", "GhostWhite", "White"
-};
-
-void automatname(Material *ma)
-{
- int nr, r, g, b;
- float ref;
-
- if (ma == NULL) return;
- if (ma->mode & MA_SHLESS) ref = 1.0;
- else ref = ma->ref;
-
- r = (int)(4.99f * (ref * ma->r));
- g = (int)(4.99f * (ref * ma->g));
- b = (int)(4.99f * (ref * ma->b));
- nr = r + 5 * g + 25 * b;
- if (nr > 124) nr = 124;
- new_id(&G.main->mat, (ID *)ma, colname_array[nr]);
-
-}
-#endif
int object_remove_material_slot(Object *ob)
{
@@ -1225,7 +1202,9 @@ int object_remove_material_slot(Object *ob)
totcolp = give_totcolp(ob);
matarar = give_matarar(ob);
- if (*matarar == NULL) return FALSE;
+ if (ELEM(NULL, matarar, *matarar)) {
+ return false;
+ }
/* can happen on face selection in editmode */
if (ob->actcol > ob->totcol) {
@@ -1274,7 +1253,7 @@ int object_remove_material_slot(Object *ob)
/* check indices from mesh */
if (ELEM4(ob->type, OB_MESH, OB_CURVE, OB_SURF, OB_FONT)) {
- data_delete_material_index_id((ID *)ob->data, actcol - 1);
+ material_data_index_remove_id((ID *)ob->data, actcol - 1);
BKE_displist_free(&ob->disp);
}
@@ -1750,7 +1729,7 @@ static short mesh_getmaterialnumber(Mesh *me, Material *ma)
/* append material */
static short mesh_addmaterial(Mesh *me, Material *ma)
{
- material_append_id(&me->id, NULL);
+ BKE_material_append_id(&me->id, NULL);
me->mat[me->totcol - 1] = ma;
id_us_plus(&ma->id);
@@ -1887,8 +1866,14 @@ static void convert_tfacematerial(Main *main, Material *ma)
mf->mat_nr = mat_nr;
}
/* remove material from mesh */
- for (a = 0; a < me->totcol; )
- if (me->mat[a] == ma) material_pop_id(&me->id, a, 1); else a++;
+ for (a = 0; a < me->totcol; ) {
+ if (me->mat[a] == ma) {
+ BKE_material_pop_id(&me->id, a, true);
+ }
+ else {
+ a++;
+ }
+ }
}
}
diff --git a/source/blender/blenkernel/intern/mesh.c b/source/blender/blenkernel/intern/mesh.c
index 439965420f7..0db1f92f70f 100644
--- a/source/blender/blenkernel/intern/mesh.c
+++ b/source/blender/blenkernel/intern/mesh.c
@@ -51,6 +51,7 @@
#include "BLI_bitmap.h"
#include "BLI_scanfill.h"
#include "BLI_array.h"
+#include "BLI_alloca.h"
#include "BKE_animsys.h"
#include "BKE_main.h"
@@ -1851,20 +1852,37 @@ void BKE_mesh_to_curve(Scene *scene, Object *ob)
}
}
-void BKE_mesh_delete_material_index(Mesh *me, short index)
+void BKE_mesh_material_index_remove(Mesh *me, short index)
{
+ MPoly *mp;
+ MFace *mf;
int i;
- for (i = 0; i < me->totpoly; i++) {
- MPoly *mp = &((MPoly *) me->mpoly)[i];
- if (mp->mat_nr && mp->mat_nr >= index)
+ for (mp = me->mpoly, i = 0; i < me->totpoly; i++, mp++) {
+ if (mp->mat_nr && mp->mat_nr >= index) {
mp->mat_nr--;
+ }
}
-
- for (i = 0; i < me->totface; i++) {
- MFace *mf = &((MFace *) me->mface)[i];
- if (mf->mat_nr && mf->mat_nr >= index)
+
+ for (mf = me->mface, i = 0; i < me->totface; i++, mf++) {
+ if (mf->mat_nr && mf->mat_nr >= index) {
mf->mat_nr--;
+ }
+ }
+}
+
+void BKE_mesh_material_index_clear(Mesh *me)
+{
+ MPoly *mp;
+ MFace *mf;
+ int i;
+
+ for (mp = me->mpoly, i = 0; i < me->totpoly; i++, mp++) {
+ mp->mat_nr = 0;
+ }
+
+ for (mf = me->mface, i = 0; i < me->totface; i++, mf++) {
+ mf->mat_nr = 0;
}
}
diff --git a/source/blender/blenkernel/intern/mesh_validate.c b/source/blender/blenkernel/intern/mesh_validate.c
index 878651cdb39..2eced15a147 100644
--- a/source/blender/blenkernel/intern/mesh_validate.c
+++ b/source/blender/blenkernel/intern/mesh_validate.c
@@ -294,7 +294,7 @@ int BKE_mesh_validate_arrays(Mesh *mesh,
# define CHECK_FACE_EDGE(a, b) \
if (!BLI_edgehash_haskey(edge_hash, mf->a, mf->b)) { \
PRINT(" face %u: edge " STRINGIFY(a) "/" STRINGIFY(b) \
- " (%u,%u) is missing egde data\n", i, mf->a, mf->b); \
+ " (%u,%u) is missing edge data\n", i, mf->a, mf->b); \
do_edge_recalc = TRUE; \
} (void)0
diff --git a/source/blender/blenkernel/intern/modifiers_bmesh.c b/source/blender/blenkernel/intern/modifiers_bmesh.c
index b7257028316..290b0684e40 100644
--- a/source/blender/blenkernel/intern/modifiers_bmesh.c
+++ b/source/blender/blenkernel/intern/modifiers_bmesh.c
@@ -28,16 +28,15 @@
* \ingroup bke
*/
-#include "BLI_math.h"
-
#include "MEM_guardedalloc.h"
+#include "BLI_math.h"
+#include "BLI_alloca.h"
+
#include "DNA_object_types.h"
-#include "BLI_array.h"
#include "BKE_DerivedMesh.h"
-#include "BKE_bmesh.h"
#include "BKE_editmesh.h"
/* Static function for alloc */
diff --git a/source/blender/blenkernel/intern/movieclip.c b/source/blender/blenkernel/intern/movieclip.c
index ef3b7ca0bdf..bf4a63c52a8 100644
--- a/source/blender/blenkernel/intern/movieclip.c
+++ b/source/blender/blenkernel/intern/movieclip.c
@@ -625,7 +625,7 @@ MovieClip *BKE_movieclip_file_add(Main *bmain, const char *name)
/* exists? */
file = BLI_open(str, O_BINARY | O_RDONLY, 0);
- if (file == -1)
+ if (file < 0)
return NULL;
close(file);
@@ -1395,8 +1395,6 @@ void BKE_movieclip_build_proxy_frame_for_ibuf(MovieClip *clip, ImBuf *ibuf, stru
void BKE_movieclip_free(MovieClip *clip)
{
- BKE_sequencer_clear_movieclip_in_clipboard(clip);
-
free_buffers(clip);
BKE_tracking_free(&clip->tracking);
@@ -1441,21 +1439,19 @@ void BKE_movieclip_unlink(Main *bmain, MovieClip *clip)
bConstraint *con;
for (con = ob->constraints.first; con; con = con->next) {
- bConstraintTypeInfo *cti = BKE_constraint_get_typeinfo(con);
-
- if (cti->type == CONSTRAINT_TYPE_FOLLOWTRACK) {
+ if (con->type == CONSTRAINT_TYPE_FOLLOWTRACK) {
bFollowTrackConstraint *data = (bFollowTrackConstraint *) con->data;
if (data->clip == clip)
data->clip = NULL;
}
- else if (cti->type == CONSTRAINT_TYPE_CAMERASOLVER) {
+ else if (con->type == CONSTRAINT_TYPE_CAMERASOLVER) {
bCameraSolverConstraint *data = (bCameraSolverConstraint *) con->data;
if (data->clip == clip)
data->clip = NULL;
}
- else if (cti->type == CONSTRAINT_TYPE_OBJECTSOLVER) {
+ else if (con->type == CONSTRAINT_TYPE_OBJECTSOLVER) {
bObjectSolverConstraint *data = (bObjectSolverConstraint *) con->data;
if (data->clip == clip)
diff --git a/source/blender/blenkernel/intern/multires.c b/source/blender/blenkernel/intern/multires.c
index cba4c9206c9..32ca3ea6d5a 100644
--- a/source/blender/blenkernel/intern/multires.c
+++ b/source/blender/blenkernel/intern/multires.c
@@ -105,15 +105,15 @@ void multires_customdata_delete(Mesh *me)
}
/** Grid hiding **/
-static BLI_bitmap multires_mdisps_upsample_hidden(BLI_bitmap lo_hidden,
- int lo_level,
- int hi_level,
+static BLI_bitmap *multires_mdisps_upsample_hidden(BLI_bitmap *lo_hidden,
+ int lo_level,
+ int hi_level,
- /* assumed to be at hi_level (or
- * null) */
- BLI_bitmap prev_hidden)
+ /* assumed to be at hi_level (or
+ * null) */
+ BLI_bitmap *prev_hidden)
{
- BLI_bitmap subd;
+ BLI_bitmap *subd;
int hi_gridsize = ccg_gridsize(hi_level);
int lo_gridsize = ccg_gridsize(lo_level);
int yh, xh, xl, yl, xo, yo, hi_ndx;
@@ -168,11 +168,11 @@ static BLI_bitmap multires_mdisps_upsample_hidden(BLI_bitmap lo_hidden,
return subd;
}
-static BLI_bitmap multires_mdisps_downsample_hidden(BLI_bitmap old_hidden,
- int old_level,
- int new_level)
+static BLI_bitmap *multires_mdisps_downsample_hidden(BLI_bitmap *old_hidden,
+ int old_level,
+ int new_level)
{
- BLI_bitmap new_hidden;
+ BLI_bitmap *new_hidden;
int new_gridsize = ccg_gridsize(new_level);
int old_gridsize = ccg_gridsize(old_level);
int x, y, factor, old_value;
@@ -200,7 +200,7 @@ static void multires_output_hidden_to_ccgdm(CCGDerivedMesh *ccgdm,
Mesh *me, int level)
{
const MDisps *mdisps = CustomData_get_layer(&me->ldata, CD_MDISPS);
- BLI_bitmap *grid_hidden = ccgdm->gridHidden;
+ BLI_bitmap **grid_hidden = ccgdm->gridHidden;
int *gridOffset;
int i, j;
@@ -210,7 +210,7 @@ static void multires_output_hidden_to_ccgdm(CCGDerivedMesh *ccgdm,
for (j = 0; j < me->mpoly[i].totloop; j++) {
int g = gridOffset[i] + j;
const MDisps *md = &mdisps[g];
- BLI_bitmap gh = md->hidden;
+ BLI_bitmap *gh = md->hidden;
if (gh) {
grid_hidden[g] =
@@ -224,7 +224,7 @@ static void multires_output_hidden_to_ccgdm(CCGDerivedMesh *ccgdm,
* the current level of md.hidden) */
static void multires_mdisps_subdivide_hidden(MDisps *md, int new_level)
{
- BLI_bitmap subd;
+ BLI_bitmap *subd;
BLI_assert(md->hidden);
@@ -245,7 +245,7 @@ static void multires_mdisps_subdivide_hidden(MDisps *md, int new_level)
static MDisps *multires_mdisps_initialize_hidden(Mesh *me, int level)
{
MDisps *mdisps = CustomData_add_layer(&me->ldata, CD_MDISPS,
- CD_CALLOC, 0, me->totloop);
+ CD_CALLOC, NULL, me->totloop);
int gridsize = ccg_gridsize(level);
int gridarea = gridsize * gridsize;
int i, j, k;
@@ -647,7 +647,7 @@ static void multires_del_higher(MultiresModifierData *mmd, Object *ob, int lvl)
multires_copy_grid(ndisps, hdisps, nsize, hsize);
if (mdisp->hidden) {
- BLI_bitmap gh =
+ BLI_bitmap *gh =
multires_mdisps_downsample_hidden(mdisp->hidden,
mdisp->level,
lvl);
@@ -1251,7 +1251,7 @@ void multires_modifier_update_mdisps(struct DerivedMesh *dm)
void multires_modifier_update_hidden(DerivedMesh *dm)
{
CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm;
- BLI_bitmap *grid_hidden = ccgdm->gridHidden;
+ BLI_bitmap **grid_hidden = ccgdm->gridHidden;
Mesh *me = ccgdm->multires.ob->data;
MDisps *mdisps = CustomData_get_layer(&me->ldata, CD_MDISPS);
int totlvl = ccgdm->multires.totlvl;
@@ -1262,7 +1262,7 @@ void multires_modifier_update_hidden(DerivedMesh *dm)
for (i = 0; i < me->totloop; i++) {
MDisps *md = &mdisps[i];
- BLI_bitmap gh = grid_hidden[i];
+ BLI_bitmap *gh = grid_hidden[i];
if (!gh && md->hidden) {
MEM_freeN(md->hidden);
diff --git a/source/blender/blenkernel/intern/navmesh_conversion.c b/source/blender/blenkernel/intern/navmesh_conversion.c
index 75e6ce9837d..1d662ae3116 100644
--- a/source/blender/blenkernel/intern/navmesh_conversion.c
+++ b/source/blender/blenkernel/intern/navmesh_conversion.c
@@ -440,9 +440,6 @@ int buildNavMeshDataByDerivedMesh(DerivedMesh *dm, int *vertsPerPoly,
int ntris = 0, *recastData = NULL;
unsigned short *tris = NULL;
- /* Don't bother converting if there is nothing to convert */
- if (!*nverts) return 0;
-
res = buildRawVertIndicesData(dm, nverts, verts, &ntris, &tris, trisToFacesMap, &recastData);
if (!res) {
printf("Converting navmesh: Error! Can't get vertices and indices from mesh\n");
diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c
index 84dfa70abfc..5001aa01653 100644
--- a/source/blender/blenkernel/intern/node.c
+++ b/source/blender/blenkernel/intern/node.c
@@ -3406,6 +3406,7 @@ static void registerShaderNodes(void)
register_node_type_sh_rgb();
register_node_type_sh_wireframe();
register_node_type_sh_wavelength();
+ register_node_type_sh_blackbody();
register_node_type_sh_mix_rgb();
register_node_type_sh_valtorgb();
register_node_type_sh_rgbtobw();
@@ -3417,11 +3418,14 @@ static void registerShaderNodes(void)
register_node_type_sh_curve_rgb();
register_node_type_sh_math();
register_node_type_sh_vect_math();
+ register_node_type_sh_vect_transform();
register_node_type_sh_squeeze();
register_node_type_sh_material_ext();
register_node_type_sh_invert();
register_node_type_sh_seprgb();
register_node_type_sh_combrgb();
+ register_node_type_sh_sephsv();
+ register_node_type_sh_combhsv();
register_node_type_sh_hue_sat();
register_node_type_sh_attribute();
diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c
index daa57afe14e..962209bef87 100644
--- a/source/blender/blenkernel/intern/object.c
+++ b/source/blender/blenkernel/intern/object.c
@@ -678,9 +678,10 @@ void BKE_object_unlink(Object *ob)
SpaceOops *so = (SpaceOops *)sl;
if (so->treestore) {
- TreeStoreElem *tselem = so->treestore->data;
- int i;
- for (i = 0; i < so->treestore->usedelem; i++, tselem++) {
+ TreeStoreElem *tselem;
+ BLI_mempool_iter iter;
+ BLI_mempool_iternew(so->treestore, &iter);
+ while ((tselem = BLI_mempool_iterstep(&iter))) {
if (tselem->id == (ID *)ob) tselem->id = NULL;
}
}
@@ -693,6 +694,14 @@ void BKE_object_unlink(Object *ob)
sbuts->pinid = NULL;
}
}
+ else if (sl->spacetype == SPACE_NODE) {
+ SpaceNode *snode = (SpaceNode *)sl;
+
+ if (snode->from == (ID *)ob) {
+ snode->flag &= ~SNODE_PIN;
+ snode->from = NULL;
+ }
+ }
}
sa = sa->next;
@@ -2029,15 +2038,13 @@ static void solve_parenting(Scene *scene, Object *ob, Object *par, float obmat[4
}
}
- if (ok) mul_serie_m4(totmat, par->obmat, tmat,
- NULL, NULL, NULL, NULL, NULL, NULL);
+ if (ok) mul_m4_m4m4(totmat, par->obmat, tmat);
else copy_m4_m4(totmat, par->obmat);
break;
case PARBONE:
ob_parbone(ob, par, tmat);
- mul_serie_m4(totmat, par->obmat, tmat,
- NULL, NULL, NULL, NULL, NULL, NULL);
+ mul_m4_m4m4(totmat, par->obmat, tmat);
break;
case PARVERT1:
@@ -2053,8 +2060,7 @@ static void solve_parenting(Scene *scene, Object *ob, Object *par, float obmat[4
case PARVERT3:
ob_parvert3(ob, par, tmat);
- mul_serie_m4(totmat, par->obmat, tmat,
- NULL, NULL, NULL, NULL, NULL, NULL);
+ mul_m4_m4m4(totmat, par->obmat, tmat);
break;
case PARSKEL:
@@ -2063,10 +2069,8 @@ static void solve_parenting(Scene *scene, Object *ob, Object *par, float obmat[4
}
/* total */
- mul_serie_m4(tmat, totmat, ob->parentinv,
- NULL, NULL, NULL, NULL, NULL, NULL);
- mul_serie_m4(obmat, tmat, locmat,
- NULL, NULL, NULL, NULL, NULL, NULL);
+ mul_m4_m4m4(tmat, totmat, ob->parentinv);
+ mul_m4_m4m4(obmat, tmat, locmat);
if (simul) {
@@ -2539,7 +2543,7 @@ void BKE_scene_foreach_display_point(
Object *ob;
for (base = FIRSTBASE; base; base = base->next) {
- if (BASE_VISIBLE(v3d, base) && (base->flag & flag) == flag) {
+ if (BASE_VISIBLE_BGMODE(v3d, scene, base) && (base->flag & flag) == flag) {
ob = base->object;
if ((ob->transflag & OB_DUPLI) == 0) {
diff --git a/source/blender/blenkernel/intern/packedFile.c b/source/blender/blenkernel/intern/packedFile.c
index 11d58c945fd..62ea16b9fb4 100644
--- a/source/blender/blenkernel/intern/packedFile.c
+++ b/source/blender/blenkernel/intern/packedFile.c
@@ -202,7 +202,7 @@ PackedFile *newPackedFile(ReportList *reports, const char *filename, const char
* and create a PackedFile structure */
file = BLI_open(name, O_BINARY | O_RDONLY, 0);
- if (file <= 0) {
+ if (file < 0) {
BKE_reportf(reports, RPT_ERROR, "Unable to pack file, source path '%s' not found", name);
}
else {
@@ -327,20 +327,21 @@ int writePackedFile(ReportList *reports, const char *filename, PackedFile *pf, i
BLI_make_existing_file(name);
file = BLI_open(name, O_BINARY + O_WRONLY + O_CREAT + O_TRUNC, 0666);
- if (file >= 0) {
+ if (file < 0) {
+ BKE_reportf(reports, RPT_ERROR, "Error creating file '%s'", name);
+ ret_value = RET_ERROR;
+ }
+ else {
if (write(file, pf->data, pf->size) != pf->size) {
BKE_reportf(reports, RPT_ERROR, "Error writing file '%s'", name);
ret_value = RET_ERROR;
}
- else
+ else {
BKE_reportf(reports, RPT_INFO, "Saved packed file to: %s", name);
+ }
close(file);
}
- else {
- BKE_reportf(reports, RPT_ERROR, "Error creating file '%s'", name);
- ret_value = RET_ERROR;
- }
if (remove_tmp) {
if (ret_value == RET_ERROR) {
diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c
index 6bea4bec3ce..6b754743c11 100644
--- a/source/blender/blenkernel/intern/particle.c
+++ b/source/blender/blenkernel/intern/particle.c
@@ -3836,7 +3836,7 @@ static void get_cpa_texture(DerivedMesh *dm, ParticleSystem *psys, ParticleSetti
for (m = 0; m < MAX_MTEX; m++, mtexp++) {
mtex = *mtexp;
- if (mtex && mtex->mapto) {
+ if (mtex && mtex->tex && mtex->mapto) {
float def = mtex->def_var;
short blend = mtex->blendtype;
short texco = mtex->texco;
@@ -3904,7 +3904,7 @@ void psys_get_texture(ParticleSimulationData *sim, ParticleData *pa, ParticleTex
for (m = 0; m < MAX_MTEX; m++, mtexp++) {
mtex = *mtexp;
- if (mtex && mtex->mapto) {
+ if (mtex && mtex->tex && mtex->mapto) {
float def = mtex->def_var;
short blend = mtex->blendtype;
short texco = mtex->texco;
diff --git a/source/blender/blenkernel/intern/pbvh.c b/source/blender/blenkernel/intern/pbvh.c
index 99e6e898685..205159c94a1 100644
--- a/source/blender/blenkernel/intern/pbvh.c
+++ b/source/blender/blenkernel/intern/pbvh.c
@@ -538,7 +538,7 @@ void BKE_pbvh_build_mesh(PBVH *bvh, MFace *faces, MVert *verts, int totface, int
/* Do a full rebuild with on Grids data structure */
void BKE_pbvh_build_grids(PBVH *bvh, CCGElem **grids, DMGridAdjacency *gridadj,
- int totgrid, CCGKey *key, void **gridfaces, DMFlagMat *flagmats, BLI_bitmap *grid_hidden)
+ int totgrid, CCGKey *key, void **gridfaces, DMFlagMat *flagmats, BLI_bitmap **grid_hidden)
{
BBC *prim_bbc = NULL;
BB cb;
@@ -753,7 +753,7 @@ void BKE_pbvh_search_gather(PBVH *bvh,
PBVHNode ***r_array, int *r_tot)
{
PBVHIter iter;
- PBVHNode **array = NULL, **newarray, *node;
+ PBVHNode **array = NULL, *node;
int tot = 0, space = 0;
pbvh_iter_begin(&iter, bvh, scb, search_data);
@@ -763,14 +763,7 @@ void BKE_pbvh_search_gather(PBVH *bvh,
if (tot == space) {
/* resize array if needed */
space = (tot == 0) ? 32 : space * 2;
- newarray = MEM_callocN(sizeof(PBVHNode) * space, "PBVHNodeSearch");
-
- if (array) {
- memcpy(newarray, array, sizeof(PBVHNode) * tot);
- MEM_freeN(array);
- }
-
- array = newarray;
+ array = MEM_recallocN_id(array, sizeof(PBVHNode *) * space, __func__);
}
array[tot] = node;
@@ -845,12 +838,12 @@ static void free_tree(node_tree *tree)
{
if (tree->left) {
free_tree(tree->left);
- tree->left = 0;
+ tree->left = NULL;
}
if (tree->right) {
free_tree(tree->right);
- tree->right = 0;
+ tree->right = NULL;
}
free(tree);
@@ -867,7 +860,7 @@ static void BKE_pbvh_search_callback_occluded(PBVH *bvh,
{
PBVHIter iter;
PBVHNode *node;
- node_tree *tree = 0;
+ node_tree *tree = NULL;
pbvh_iter_begin(&iter, bvh, scb, search_data);
@@ -1253,7 +1246,7 @@ void BKE_pbvh_bounding_box(const PBVH *bvh, float min[3], float max[3])
}
}
-BLI_bitmap *BKE_pbvh_grid_hidden(const PBVH *bvh)
+BLI_bitmap **BKE_pbvh_grid_hidden(const PBVH *bvh)
{
BLI_assert(bvh->type == PBVH_GRIDS);
return bvh->grid_hidden;
@@ -1363,7 +1356,7 @@ void BKE_pbvh_node_get_proxies(PBVHNode *node, PBVHProxyNode **proxies, int *pro
if (proxy_count) *proxy_count = node->proxy_count;
}
else {
- if (proxies) *proxies = 0;
+ if (proxies) *proxies = NULL;
if (proxy_count) *proxy_count = 0;
}
}
@@ -1469,7 +1462,7 @@ static int pbvh_grids_node_raycast(PBVH *bvh, PBVHNode *node,
for (i = 0; i < totgrid; ++i) {
CCGElem *grid = bvh->grids[node->prim_indices[i]];
- BLI_bitmap gh;
+ BLI_bitmap *gh;
if (!grid)
continue;
@@ -1664,7 +1657,7 @@ void BKE_pbvh_draw(PBVH *bvh, float (*planes)[4], float (*face_nors)[3],
}
void BKE_pbvh_grids_update(PBVH *bvh, CCGElem **grids, DMGridAdjacency *gridadj, void **gridfaces,
- DMFlagMat *flagmats, BLI_bitmap *grid_hidden)
+ DMFlagMat *flagmats, BLI_bitmap **grid_hidden)
{
int a;
@@ -1795,11 +1788,11 @@ void BKE_pbvh_node_free_proxies(PBVHNode *node)
for (p = 0; p < node->proxy_count; p++) {
MEM_freeN(node->proxies[p].co);
- node->proxies[p].co = 0;
+ node->proxies[p].co = NULL;
}
MEM_freeN(node->proxies);
- node->proxies = 0;
+ node->proxies = NULL;
node->proxy_count = 0;
}
@@ -1807,7 +1800,7 @@ void BKE_pbvh_node_free_proxies(PBVHNode *node)
void BKE_pbvh_gather_proxies(PBVH *pbvh, PBVHNode ***r_array, int *r_tot)
{
- PBVHNode **array = NULL, **newarray, *node;
+ PBVHNode **array = NULL, *node;
int tot = 0, space = 0;
int n;
@@ -1818,14 +1811,7 @@ void BKE_pbvh_gather_proxies(PBVH *pbvh, PBVHNode ***r_array, int *r_tot)
if (tot == space) {
/* resize array if needed */
space = (tot == 0) ? 32 : space * 2;
- newarray = MEM_callocN(sizeof(PBVHNode) * space, "BKE_pbvh_gather_proxies");
-
- if (array) {
- memcpy(newarray, array, sizeof(PBVHNode) * tot);
- MEM_freeN(array);
- }
-
- array = newarray;
+ array = MEM_recallocN_id(array, sizeof(PBVHNode *) * space, __func__);
}
array[tot] = node;
@@ -1850,10 +1836,10 @@ void pbvh_vertex_iter_init(PBVH *bvh, PBVHNode *node,
int *grid_indices, *vert_indices;
int totgrid, gridsize, uniq_verts, totvert;
- vi->grid = 0;
- vi->no = 0;
- vi->fno = 0;
- vi->mvert = 0;
+ vi->grid = NULL;
+ vi->no = NULL;
+ vi->fno = NULL;
+ vi->mvert = NULL;
BKE_pbvh_node_get_grids(bvh, node, &grid_indices, &totgrid, NULL, &gridsize, &grids, NULL);
BKE_pbvh_node_num_verts(bvh, node, &uniq_verts, &totvert);
diff --git a/source/blender/blenkernel/intern/pbvh_bmesh.c b/source/blender/blenkernel/intern/pbvh_bmesh.c
index c6a5552dbf7..cd21f8ad968 100644
--- a/source/blender/blenkernel/intern/pbvh_bmesh.c
+++ b/source/blender/blenkernel/intern/pbvh_bmesh.c
@@ -294,7 +294,7 @@ static BMVert *pbvh_bmesh_vert_create(PBVH *bvh, int node_index,
static BMFace *pbvh_bmesh_face_create(PBVH *bvh, int node_index,
BMVert *v_tri[3], BMEdge *e_tri[3],
- const BMFace *UNUSED(example))
+ const BMFace *f_example)
{
BMFace *f;
void *val = SET_INT_IN_POINTER(node_index);
@@ -302,9 +302,10 @@ static BMFace *pbvh_bmesh_face_create(PBVH *bvh, int node_index,
/* ensure we never add existing face */
BLI_assert(BM_face_exists(v_tri, 3, NULL) == false);
- /* Note: passing NULL for the 'example' parameter, profiling shows
- * a small performance bump */
f = BM_face_create(bvh->bm, v_tri, e_tri, 3, 0);
+ // BM_elem_attrs_copy(bvh->bm, bvh->bm, f_example, f);
+ f->mat_nr = f_example->mat_nr;
+
if (!BLI_ghash_haskey(bvh->bm_face_to_node, f)) {
BLI_ghash_insert(bvh->nodes[node_index].bm_faces, f, NULL);
diff --git a/source/blender/blenkernel/intern/pbvh_intern.h b/source/blender/blenkernel/intern/pbvh_intern.h
index b3f7bf6e3d1..4154b8e4799 100644
--- a/source/blender/blenkernel/intern/pbvh_intern.h
+++ b/source/blender/blenkernel/intern/pbvh_intern.h
@@ -139,11 +139,11 @@ struct PBVH {
void **gridfaces;
const DMFlagMat *grid_flag_mats;
int totgrid;
- BLI_bitmap *grid_hidden;
+ BLI_bitmap **grid_hidden;
/* Only used during BVH build and update,
* don't need to remain valid after */
- BLI_bitmap vert_bitmap;
+ BLI_bitmap *vert_bitmap;
#ifdef PERFCNTRS
int perf_modified;
diff --git a/source/blender/blenkernel/intern/pointcache.c b/source/blender/blenkernel/intern/pointcache.c
index 06748dfc44d..93f6965e97b 100644
--- a/source/blender/blenkernel/intern/pointcache.c
+++ b/source/blender/blenkernel/intern/pointcache.c
@@ -268,8 +268,9 @@ static int ptcache_particle_write(int index, void *psys_v, void **data, int cfr
PTCACHE_DATA_FROM(data, BPHYS_DATA_SIZE, &pa->size);
PTCACHE_DATA_FROM(data, BPHYS_DATA_TIMES, times);
- if (boid)
+ if (boid) {
PTCACHE_DATA_FROM(data, BPHYS_DATA_BOIDS, &boid->data);
+ }
/* return flag 1+1=2 for newly born particles to copy exact birth location to previously cached frame */
return 1 + (pa->state.time >= pa->time && pa->prev_state.time <= pa->time);
@@ -304,8 +305,9 @@ static void ptcache_particle_read(int index, void *psys_v, void **data, float cf
else if (cfra > pa->dietime)
pa->state.time = pa->dietime;
- if (data[BPHYS_DATA_SIZE])
+ if (data[BPHYS_DATA_SIZE]) {
PTCACHE_DATA_TO(data, BPHYS_DATA_SIZE, 0, &pa->size);
+ }
if (data[BPHYS_DATA_TIMES]) {
float times[3];
@@ -926,7 +928,7 @@ 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);
+ printf("Dynamic Paint: Invalid cache version: '%c%c%c%c'!\n", UNPACK4(version));
return 0;
}
@@ -3576,6 +3578,11 @@ void BKE_ptcache_load_external(PTCacheID *pid)
cache->flag &= ~(PTCACHE_OUTDATED|PTCACHE_FRAMES_SKIPPED);
}
+ /* make sure all new frames are loaded */
+ if (cache->cached_frames) {
+ MEM_freeN(cache->cached_frames);
+ cache->cached_frames=NULL;
+ }
BKE_ptcache_update_info(pid);
}
diff --git a/source/blender/blenkernel/intern/property.c b/source/blender/blenkernel/intern/property.c
index ec23a7db8a1..73f2a864e32 100644
--- a/source/blender/blenkernel/intern/property.c
+++ b/source/blender/blenkernel/intern/property.c
@@ -177,9 +177,9 @@ void BKE_bproperty_unique(bProperty *first, bProperty *prop, int force)
i = 0;
do { /* ensure we have enough chars for the new number in the name */
- BLI_snprintf(num, sizeof(num), "%d", i++);
- BLI_strncpy(new_name, base_name, sizeof(prop->name) - strlen(num));
- strcat(new_name, num);
+ const size_t num_len = BLI_snprintf(num, sizeof(num), "%d", i++);
+ BLI_snprintf(new_name, sizeof(prop->name),
+ "%.*s%s", (int)(sizeof(prop->name) - num_len), base_name, num);
} while (bproperty_get(first, prop, new_name));
BLI_strncpy(prop->name, new_name, sizeof(prop->name));
diff --git a/source/blender/blenkernel/intern/screen.c b/source/blender/blenkernel/intern/screen.c
index 01f57b95378..fe2f52d79fd 100644
--- a/source/blender/blenkernel/intern/screen.c
+++ b/source/blender/blenkernel/intern/screen.c
@@ -136,6 +136,11 @@ void BKE_spacetype_register(SpaceType *st)
BLI_addtail(&spacetypes, st);
}
+int BKE_spacetype_exists(int spaceid)
+{
+ return BKE_spacetype_from_id(spaceid) != NULL;
+}
+
/* ***************** Space handling ********************** */
void BKE_spacedata_freelist(ListBase *lb)
diff --git a/source/blender/blenkernel/intern/sequencer.c b/source/blender/blenkernel/intern/sequencer.c
index b080cfcff2f..34b19e3f357 100644
--- a/source/blender/blenkernel/intern/sequencer.c
+++ b/source/blender/blenkernel/intern/sequencer.c
@@ -65,6 +65,7 @@
#include "BKE_fcurve.h"
#include "BKE_scene.h"
#include "BKE_mask.h"
+#include "BKE_library.h"
#include "RNA_access.h"
@@ -265,6 +266,7 @@ static void seq_free_clipboard_recursive(Sequence *seq_parent)
seq_free_clipboard_recursive(seq);
}
+ BKE_sequence_clipboard_pointers_free(seq_parent);
BKE_sequence_free_ex(NULL, seq_parent, FALSE);
}
@@ -279,6 +281,101 @@ void BKE_sequencer_free_clipboard(void)
seqbase_clipboard.first = seqbase_clipboard.last = NULL;
}
+/* -------------------------------------------------------------------- */
+/* Manage pointers in the clipboard.
+ * note that these pointers should _never_ be access in the sequencer,
+ * they are only for storage while in the clipboard
+ * notice 'newid' is used for temp pointer storage here, validate on access.
+ */
+#define ID_PT (*id_pt)
+static void seqclipboard_ptr_free(ID **id_pt)
+{
+ if (ID_PT) {
+ BLI_assert(ID_PT->newid != NULL);
+ MEM_freeN(ID_PT);
+ ID_PT = NULL;
+ }
+}
+static void seqclipboard_ptr_store(ID **id_pt)
+{
+ if (ID_PT) {
+ ID *id_prev = ID_PT;
+ ID_PT = MEM_dupallocN(ID_PT);
+ ID_PT->newid = id_prev;
+ }
+}
+static void seqclipboard_ptr_restore(Main *bmain, ID **id_pt)
+{
+ if (ID_PT) {
+ const ListBase *lb = which_libbase(bmain, GS(ID_PT->name));
+ void *id_restore;
+
+ BLI_assert(ID_PT->newid != NULL);
+ if (BLI_findindex(lb, (ID_PT)->newid) != -1) {
+ /* the pointer is still valid */
+ id_restore = (ID_PT)->newid;
+ }
+ else {
+ /* the pointer of the same name still exists */
+ id_restore = BLI_findstring(lb, (ID_PT)->name + 2, offsetof(ID, name) + 2);
+ }
+
+ if (id_restore == NULL) {
+ /* check for a data with the same filename */
+ switch (GS(ID_PT->name)) {
+ case ID_SO:
+ {
+ id_restore = BLI_findstring(lb, ((bSound *)ID_PT)->name, offsetof(bSound, name));
+ if (id_restore == NULL) {
+ id_restore = sound_new_file(bmain, ((bSound *)ID_PT)->name);
+ (ID_PT)->newid = id_restore; /* reuse next time */
+ }
+ break;
+ }
+ case ID_MC:
+ {
+ id_restore = BLI_findstring(lb, ((MovieClip *)ID_PT)->name, offsetof(MovieClip, name));
+ if (id_restore == NULL) {
+ id_restore = BKE_movieclip_file_add(bmain, ((MovieClip *)ID_PT)->name);
+ (ID_PT)->newid = id_restore; /* reuse next time */
+ }
+ break;
+ }
+ }
+ }
+
+ ID_PT = id_restore;
+ }
+}
+#undef ID_PT
+
+void BKE_sequence_clipboard_pointers_free(Sequence *seq)
+{
+ seqclipboard_ptr_free((ID **)&seq->scene);
+ seqclipboard_ptr_free((ID **)&seq->scene_camera);
+ seqclipboard_ptr_free((ID **)&seq->clip);
+ seqclipboard_ptr_free((ID **)&seq->mask);
+ seqclipboard_ptr_free((ID **)&seq->sound);
+}
+void BKE_sequence_clipboard_pointers_store(Sequence *seq)
+{
+ seqclipboard_ptr_store((ID **)&seq->scene);
+ seqclipboard_ptr_store((ID **)&seq->scene_camera);
+ seqclipboard_ptr_store((ID **)&seq->clip);
+ seqclipboard_ptr_store((ID **)&seq->mask);
+ seqclipboard_ptr_store((ID **)&seq->sound);
+}
+void BKE_sequence_clipboard_pointers_restore(Sequence *seq, Main *bmain)
+{
+ seqclipboard_ptr_restore(bmain, (ID **)&seq->scene);
+ seqclipboard_ptr_restore(bmain, (ID **)&seq->scene_camera);
+ seqclipboard_ptr_restore(bmain, (ID **)&seq->clip);
+ seqclipboard_ptr_restore(bmain, (ID **)&seq->mask);
+ seqclipboard_ptr_restore(bmain, (ID **)&seq->sound);
+}
+/* end clipboard pointer mess */
+
+
Editing *BKE_sequencer_editing_ensure(Scene *scene)
{
if (scene->ed == NULL) {
@@ -818,33 +915,6 @@ void BKE_sequencer_clear_scene_in_allseqs(Main *bmain, Scene *scene)
BKE_sequencer_base_recursive_apply(&scene_iter->ed->seqbase, clear_scene_in_allseqs_cb, scene);
}
}
-
- /* also clear clipboard */
- BKE_sequencer_base_recursive_apply(&seqbase_clipboard, clear_scene_in_allseqs_cb, scene);
-}
-
-static int clear_movieclip_in_clipboard_cb(Sequence *seq, void *arg_pt)
-{
- if (seq->clip == (MovieClip *)arg_pt)
- seq->clip = NULL;
- return 1;
-}
-
-void BKE_sequencer_clear_movieclip_in_clipboard(MovieClip *clip)
-{
- BKE_sequencer_base_recursive_apply(&seqbase_clipboard, clear_movieclip_in_clipboard_cb, clip);
-}
-
-static int clear_mask_in_clipboard_cb(Sequence *seq, void *arg_pt)
-{
- if (seq->mask == (Mask *)arg_pt)
- seq->mask = NULL;
- return 1;
-}
-
-void BKE_sequencer_clear_mask_in_clipboard(Mask *mask)
-{
- BKE_sequencer_base_recursive_apply(&seqbase_clipboard, clear_mask_in_clipboard_cb, mask);
}
typedef struct SeqUniqueInfo {
@@ -4245,6 +4315,12 @@ static Sequence *seq_dupli(Scene *scene, Scene *scene_to, Sequence *seq, int dup
if (seq->scene_sound)
seqn->scene_sound = sound_scene_add_scene_sound_defaults(sce_audio, seqn);
}
+ else if (seq->type == SEQ_TYPE_MOVIECLIP) {
+ /* avoid assert */
+ }
+ else if (seq->type == SEQ_TYPE_MASK) {
+ /* avoid assert */
+ }
else if (seq->type == SEQ_TYPE_MOVIE) {
seqn->strip->stripdata =
MEM_dupallocN(seq->strip->stripdata);
@@ -4256,7 +4332,7 @@ static Sequence *seq_dupli(Scene *scene, Scene *scene_to, Sequence *seq, int dup
if (seq->scene_sound)
seqn->scene_sound = sound_add_scene_sound_defaults(sce_audio, seqn);
- seqn->sound->id.us++;
+ id_us_plus((ID *)seqn->sound);
}
else if (seq->type == SEQ_TYPE_IMAGE) {
seqn->strip->stripdata =
@@ -4278,7 +4354,8 @@ static Sequence *seq_dupli(Scene *scene, Scene *scene_to, Sequence *seq, int dup
}
else {
- fprintf(stderr, "Aiiiiekkk! sequence type not handled in duplicate!\nExpect a crash now...\n");
+ /* sequence type not handled in duplicate! Expect a crash now... */
+ BLI_assert(0);
}
if (dupe_flag & SEQ_DUPE_UNIQUE_NAME)
diff --git a/source/blender/blenkernel/intern/shrinkwrap.c b/source/blender/blenkernel/intern/shrinkwrap.c
index 10065910532..b9843ad0619 100644
--- a/source/blender/blenkernel/intern/shrinkwrap.c
+++ b/source/blender/blenkernel/intern/shrinkwrap.c
@@ -86,7 +86,7 @@ void space_transform_from_matrixs(SpaceTransform *data, float local[4][4], float
{
float itarget[4][4];
invert_m4_m4(itarget, target);
- mul_serie_m4(data->local2target, itarget, local, NULL, NULL, NULL, NULL, NULL, NULL);
+ mul_m4_m4m4(data->local2target, itarget, local);
invert_m4_m4(data->target2local, data->local2target);
}
@@ -428,7 +428,7 @@ static void shrinkwrap_calc_nearest_surface_point(ShrinkwrapCalcData *calc)
BVHTreeNearest nearest = NULL_BVHTreeNearest;
/* Create a bvh-tree of the given target */
- TIMEIT_BENCH(bvhtree_from_mesh_faces(&treeData, calc->target, 0.0, 2, 6), bvhtree_faces);
+ bvhtree_from_mesh_faces(&treeData, calc->target, 0.0, 2, 6);
if (treeData.tree == NULL) {
OUT_OF_MEMORY();
return;
diff --git a/source/blender/blenkernel/intern/sketch.c b/source/blender/blenkernel/intern/sketch.c
index 707d97a1cf1..bbd637a0a77 100644
--- a/source/blender/blenkernel/intern/sketch.c
+++ b/source/blender/blenkernel/intern/sketch.c
@@ -487,7 +487,7 @@ void sk_endContinuousStroke(SK_Stroke *stk)
void sk_updateNextPoint(SK_Sketch *sketch, SK_Stroke *stk)
{
if (stk) {
- memcpy(&sketch->next_point, stk->points[stk->nb_points - 1].p, sizeof(SK_Point));
+ memcpy(&(sketch->next_point), &(stk->points[stk->nb_points - 1]), sizeof(SK_Point));
}
}
diff --git a/source/blender/blenkernel/intern/smoke.c b/source/blender/blenkernel/intern/smoke.c
index b2c0a45cbc4..bb65955e3b5 100644
--- a/source/blender/blenkernel/intern/smoke.c
+++ b/source/blender/blenkernel/intern/smoke.c
@@ -259,7 +259,10 @@ static void smoke_set_domain_from_derivedmesh(SmokeDomainSettings *sds, Object *
zero_v3_int(sds->base_res);
copy_v3_v3(sds->cell_size, size);
}
- mul_v3_v3(size, ob->size);
+ /* apply object scale */
+ for (i = 0; i < 3; i++) {
+ size[i] = fabs(size[i] * ob->size[i]);
+ }
copy_v3_v3(sds->global_size, size);
copy_v3_v3(sds->dp0, min);
@@ -272,21 +275,21 @@ static void smoke_set_domain_from_derivedmesh(SmokeDomainSettings *sds, Object *
/* define grid resolutions from longest domain side */
if (size[0] >= MAX2(size[1], size[2])) {
scale = res / size[0];
- sds->scale = size[0] / ob->size[0];
+ sds->scale = size[0] / fabs(ob->size[0]);
sds->base_res[0] = res;
sds->base_res[1] = (int)(size[1] * scale + 0.5f);
sds->base_res[2] = (int)(size[2] * scale + 0.5f);
}
else if (size[1] >= MAX2(size[0], size[2])) {
scale = res / size[1];
- sds->scale = size[1] / ob->size[1];
+ sds->scale = size[1] / fabs(ob->size[1]);
sds->base_res[0] = (int)(size[0] * scale + 0.5f);
sds->base_res[1] = res;
sds->base_res[2] = (int)(size[2] * scale + 0.5f);
}
else {
scale = res / size[2];
- sds->scale = size[2] / ob->size[2];
+ sds->scale = size[2] / fabs(ob->size[2]);
sds->base_res[0] = (int)(size[0] * scale + 0.5f);
sds->base_res[1] = (int)(size[1] * scale + 0.5f);
sds->base_res[2] = res;
@@ -719,7 +722,7 @@ static void obstacles_from_derivedmesh(Object *coll_ob, SmokeDomainSettings *sds
DerivedMesh *dm = NULL;
MVert *mvert = NULL;
MFace *mface = NULL;
- BVHTreeFromMesh treeData = {0};
+ BVHTreeFromMesh treeData = {NULL};
int numverts, i, z;
float surface_distance = 0.6;
@@ -1570,7 +1573,7 @@ static void emit_from_derivedmesh(Object *flow_ob, SmokeDomainSettings *sds, Smo
MVert *mvert_orig = NULL;
MFace *mface = NULL;
MTFace *tface = NULL;
- BVHTreeFromMesh treeData = {0};
+ BVHTreeFromMesh treeData = {NULL};
int numOfVerts, i, z;
float flow_center[3] = {0};
@@ -2105,7 +2108,7 @@ static void update_flowsfluids(Scene *scene, Object *ob, SmokeDomainSettings *sd
// float scene_subframe = scene->r.subframe; // UNUSED
int subframe;
for (subframe = 0; subframe <= subframes; subframe++) {
- EmissionMap em_temp = {0};
+ EmissionMap em_temp = {NULL};
float sample_size = 1.0f / (float)(subframes+1);
float prev_frame_pos = sample_size * (float)(subframe+1);
float sdt = dt * sample_size;
diff --git a/source/blender/blenkernel/intern/sound.c b/source/blender/blenkernel/intern/sound.c
index feff8f95fd7..2f8eb7d9931 100644
--- a/source/blender/blenkernel/intern/sound.c
+++ b/source/blender/blenkernel/intern/sound.c
@@ -60,10 +60,6 @@
#include "BKE_sequencer.h"
#include "BKE_scene.h"
-// evil quiet NaN definition
-static const int NAN_INT = 0x7FC00000;
-#define NAN_FLT *((float *)(&NAN_INT))
-
#ifdef WITH_AUDASPACE
// evil global ;-)
static int sound_cfra;
diff --git a/source/blender/blenkernel/intern/subsurf_ccg.c b/source/blender/blenkernel/intern/subsurf_ccg.c
index 26a5dada108..35482d9553d 100644
--- a/source/blender/blenkernel/intern/subsurf_ccg.c
+++ b/source/blender/blenkernel/intern/subsurf_ccg.c
@@ -1505,7 +1505,8 @@ static void ccgdm_getVertCos(DerivedMesh *dm, float (*cos)[3])
static void ccgDM_foreachMappedVert(
DerivedMesh *dm,
void (*func)(void *userData, int index, const float co[3], const float no_f[3], const short no_s[3]),
- void *userData)
+ void *userData,
+ DMForeachFlag flag)
{
CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm;
CCGVertIterator *vi;
@@ -1514,11 +1515,13 @@ static void ccgDM_foreachMappedVert(
for (vi = ccgSubSurf_getVertIterator(ccgdm->ss); !ccgVertIterator_isStopped(vi); ccgVertIterator_next(vi)) {
CCGVert *v = ccgVertIterator_getCurrent(vi);
- CCGElem *vd = ccgSubSurf_getVertData(ccgdm->ss, v);
- int index = ccgDM_getVertMapIndex(ccgdm->ss, v);
+ const int index = ccgDM_getVertMapIndex(ccgdm->ss, v);
- if (index != -1)
- func(userData, index, CCG_elem_co(&key, vd), CCG_elem_no(&key, vd), NULL);
+ if (index != -1) {
+ CCGElem *vd = ccgSubSurf_getVertData(ccgdm->ss, v);
+ const float *no = (flag & DM_FOREACH_USE_NORMAL) ? CCG_elem_no(&key, vd) : NULL;
+ func(userData, index, CCG_elem_co(&key, vd), no, NULL);
+ }
}
ccgVertIterator_free(vi);
@@ -1539,12 +1542,13 @@ static void ccgDM_foreachMappedEdge(
for (ei = ccgSubSurf_getEdgeIterator(ss); !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) {
CCGEdge *e = ccgEdgeIterator_getCurrent(ei);
- CCGElem *edgeData = ccgSubSurf_getEdgeDataArray(ss, e);
- int index = ccgDM_getEdgeMapIndex(ss, e);
+ const int index = ccgDM_getEdgeMapIndex(ss, e);
if (index != -1) {
- for (i = 0; i < edgeSize - 1; i++)
+ CCGElem *edgeData = ccgSubSurf_getEdgeDataArray(ss, e);
+ for (i = 0; i < edgeSize - 1; i++) {
func(userData, index, CCG_elem_offset_co(&key, edgeData, i), CCG_elem_offset_co(&key, edgeData, i + 1));
+ }
}
}
@@ -2530,7 +2534,8 @@ static void ccgDM_drawMappedEdgesInterp(DerivedMesh *dm,
static void ccgDM_foreachMappedFaceCenter(
DerivedMesh *dm,
void (*func)(void *userData, int index, const float co[3], const float no[3]),
- void *userData)
+ void *userData,
+ DMForeachFlag flag)
{
CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm;
CCGSubSurf *ss = ccgdm->ss;
@@ -2541,13 +2546,13 @@ static void ccgDM_foreachMappedFaceCenter(
for (fi = ccgSubSurf_getFaceIterator(ss); !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) {
CCGFace *f = ccgFaceIterator_getCurrent(fi);
- int index = ccgDM_getFaceMapIndex(ss, f);
+ const int index = ccgDM_getFaceMapIndex(ss, f);
if (index != -1) {
/* Face center data normal isn't updated atm. */
CCGElem *vd = ccgSubSurf_getFaceGridData(ss, f, 0, 0, 0);
-
- func(userData, index, CCG_elem_co(&key, vd), CCG_elem_no(&key, vd));
+ const float *no = (flag & DM_FOREACH_USE_NORMAL) ? CCG_elem_no(&key, vd) : NULL;
+ func(userData, index, CCG_elem_co(&key, vd), no);
}
}
@@ -2925,7 +2930,7 @@ static void ccgdm_create_grids(DerivedMesh *dm)
gridFaces = MEM_mallocN(sizeof(CCGFace *) * numGrids, "ccgdm.gridFaces");
gridFlagMats = MEM_mallocN(sizeof(DMFlagMat) * numGrids, "ccgdm.gridFlagMats");
- ccgdm->gridHidden = MEM_callocN(sizeof(BLI_bitmap) * numGrids, "ccgdm.gridHidden");
+ ccgdm->gridHidden = MEM_callocN(sizeof(*ccgdm->gridHidden) * numGrids, "ccgdm.gridHidden");
for (gIndex = 0, index = 0; index < numFaces; index++) {
CCGFace *f = ccgdm->faceMap[index].face;
@@ -2997,7 +3002,7 @@ static DMFlagMat *ccgDM_getGridFlagMats(DerivedMesh *dm)
return ccgdm->gridFlagMats;
}
-static BLI_bitmap *ccgDM_getGridHidden(DerivedMesh *dm)
+static BLI_bitmap **ccgDM_getGridHidden(DerivedMesh *dm)
{
CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm;
@@ -3134,7 +3139,7 @@ static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss,
int numTex, numCol;
int hasPCol, hasOrigSpace;
int gridInternalEdges;
- WeightTable wtable = {0};
+ WeightTable wtable = {NULL};
/* MCol *mcol; */ /* UNUSED */
MEdge *medge = NULL;
/* MFace *mface = NULL; */
diff --git a/source/blender/blenkernel/intern/text.c b/source/blender/blenkernel/intern/text.c
index 8d63be5fbd5..f0c01e25598 100644
--- a/source/blender/blenkernel/intern/text.c
+++ b/source/blender/blenkernel/intern/text.c
@@ -2359,7 +2359,7 @@ static void txt_delete_line(Text *text, TextLine *line)
static void txt_combine_lines(Text *text, TextLine *linea, TextLine *lineb)
{
- char *tmp;
+ char *tmp, *s;
if (!text) return;
@@ -2368,8 +2368,10 @@ static void txt_combine_lines(Text *text, TextLine *linea, TextLine *lineb)
tmp = MEM_mallocN(linea->len + lineb->len + 1, "textline_string");
- strcpy(tmp, linea->line);
- strcat(tmp, lineb->line);
+ s = tmp;
+ s += BLI_strcpy_rlen(s, linea->line);
+ s += BLI_strcpy_rlen(s, lineb->line);
+ (void)s;
make_new_line(linea, tmp);
@@ -2622,10 +2624,6 @@ void txt_indent(Text *text)
return;
}
- if (!text) return;
- if (!text->curl) return;
- if (!text->sell) return;
-
/* insert spaces rather than tabs */
if (text->flags & TXT_TABSTOSPACES) {
add = tab_to_spaces;
@@ -2685,9 +2683,9 @@ void txt_unindent(Text *text)
/* hardcoded: TXT_TABSIZE = 4 spaces: */
int spaceslen = TXT_TABSIZE;
- if (!text) return;
- if (!text->curl) return;
- if (!text->sell) return;
+ if (ELEM3(NULL, text, text->curl, text->sell)) {
+ return;
+ }
/* insert spaces rather than tabs */
if (text->flags & TXT_TABSTOSPACES) {
diff --git a/source/blender/blenkernel/intern/texture.c b/source/blender/blenkernel/intern/texture.c
index 1d0b0deae7e..e2b7358525a 100644
--- a/source/blender/blenkernel/intern/texture.c
+++ b/source/blender/blenkernel/intern/texture.c
@@ -906,42 +906,6 @@ void BKE_texture_make_local(Tex *tex)
}
}
-/* ------------------------------------------------------------------------- */
-#if 0 /* UNUSED */
-void autotexname(Tex *tex)
-{
- Main *bmain = G.main;
- char texstr[20][15] = {"None", "Clouds", "Wood", "Marble", "Magic", "Blend",
- "Stucci", "Noise", "Image", "EnvMap", "Musgrave",
- "Voronoi", "DistNoise", "Point Density", "Voxel Data", "Ocean", "", "", ""};
- Image *ima;
- char di[FILE_MAXDIR], fi[FILE_MAXFILE];
-
- if (tex) {
- if (tex->use_nodes) {
- new_id(&bmain->tex, (ID *)tex, "Noddy");
- }
- else if (tex->type == TEX_IMAGE) {
- ima = tex->ima;
- if (ima) {
- 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]);
- }
- }
-}
-#endif
-
-/* ------------------------------------------------------------------------- */
-
Tex *give_current_object_texture(Object *ob)
{
Material *ma, *node_ma;
diff --git a/source/blender/blenkernel/intern/tracking.c b/source/blender/blenkernel/intern/tracking.c
index 2c561dd4472..4c363292898 100644
--- a/source/blender/blenkernel/intern/tracking.c
+++ b/source/blender/blenkernel/intern/tracking.c
@@ -654,7 +654,7 @@ void BKE_tracking_track_flag_clear(MovieTrackingTrack *track, int area, int flag
*/
int BKE_tracking_track_has_marker_at_frame(MovieTrackingTrack *track, int framenr)
{
- return BKE_tracking_marker_get_exact(track, framenr) != 0;
+ return BKE_tracking_marker_get_exact(track, framenr) != NULL;
}
/* Check whether track has got enabled marker at specified frame.
@@ -1534,7 +1534,7 @@ void BKE_tracking_camera_get_reconstructed_interpolate(MovieTracking *tracking,
/*********************** Distortion/Undistortion *************************/
-static void cameraIntrinscisOptionsFromTracking(libmv_cameraIntrinsicsOptions *camera_intrinsics_options,
+static void cameraIntrinscisOptionsFromTracking(libmv_CameraIntrinsicsOptions *camera_intrinsics_options,
MovieTracking *tracking, int calibration_width, int calibration_height)
{
MovieTrackingCamera *camera = &tracking->camera;
@@ -1559,7 +1559,7 @@ MovieDistortion *BKE_tracking_distortion_new(void)
distortion = MEM_callocN(sizeof(MovieDistortion), "BKE_tracking_distortion_create");
- distortion->intrinsics = libmv_CameraIntrinsicsNewEmpty();
+ distortion->intrinsics = libmv_cameraIntrinsicsNewEmpty();
return distortion;
}
@@ -1567,17 +1567,17 @@ MovieDistortion *BKE_tracking_distortion_new(void)
void BKE_tracking_distortion_update(MovieDistortion *distortion, MovieTracking *tracking,
int calibration_width, int calibration_height)
{
- libmv_cameraIntrinsicsOptions camera_intrinsics_options;
+ libmv_CameraIntrinsicsOptions camera_intrinsics_options;
cameraIntrinscisOptionsFromTracking(&camera_intrinsics_options, tracking,
calibration_width, calibration_height);
- libmv_CameraIntrinsicsUpdate(&camera_intrinsics_options, distortion->intrinsics);
+ libmv_cameraIntrinsicsUpdate(&camera_intrinsics_options, distortion->intrinsics);
}
void BKE_tracking_distortion_set_threads(MovieDistortion *distortion, int threads)
{
- libmv_CameraIntrinsicsSetThreads(distortion->intrinsics, threads);
+ libmv_cameraIntrinsicsSetThreads(distortion->intrinsics, threads);
}
MovieDistortion *BKE_tracking_distortion_copy(MovieDistortion *distortion)
@@ -1586,7 +1586,7 @@ MovieDistortion *BKE_tracking_distortion_copy(MovieDistortion *distortion)
new_distortion = MEM_callocN(sizeof(MovieDistortion), "BKE_tracking_distortion_create");
- new_distortion->intrinsics = libmv_CameraIntrinsicsCopy(distortion->intrinsics);
+ new_distortion->intrinsics = libmv_cameraIntrinsicsCopy(distortion->intrinsics);
return new_distortion;
}
@@ -1602,12 +1602,12 @@ ImBuf *BKE_tracking_distortion_exec(MovieDistortion *distortion, MovieTracking *
if (ibuf->rect_float) {
if (undistort) {
- libmv_CameraIntrinsicsUndistortFloat(distortion->intrinsics,
+ libmv_cameraIntrinsicsUndistortFloat(distortion->intrinsics,
ibuf->rect_float, resibuf->rect_float,
ibuf->x, ibuf->y, overscan, ibuf->channels);
}
else {
- libmv_CameraIntrinsicsDistortFloat(distortion->intrinsics,
+ libmv_cameraIntrinsicsDistortFloat(distortion->intrinsics,
ibuf->rect_float, resibuf->rect_float,
ibuf->x, ibuf->y, overscan, ibuf->channels);
}
@@ -1617,12 +1617,12 @@ ImBuf *BKE_tracking_distortion_exec(MovieDistortion *distortion, MovieTracking *
}
else {
if (undistort) {
- libmv_CameraIntrinsicsUndistortByte(distortion->intrinsics,
+ libmv_cameraIntrinsicsUndistortByte(distortion->intrinsics,
(unsigned char *)ibuf->rect, (unsigned char *)resibuf->rect,
ibuf->x, ibuf->y, overscan, ibuf->channels);
}
else {
- libmv_CameraIntrinsicsDistortByte(distortion->intrinsics,
+ libmv_cameraIntrinsicsDistortByte(distortion->intrinsics,
(unsigned char *)ibuf->rect, (unsigned char *)resibuf->rect,
ibuf->x, ibuf->y, overscan, ibuf->channels);
}
@@ -1633,7 +1633,7 @@ ImBuf *BKE_tracking_distortion_exec(MovieDistortion *distortion, MovieTracking *
void BKE_tracking_distortion_free(MovieDistortion *distortion)
{
- libmv_CameraIntrinsicsDestroy(distortion->intrinsics);
+ libmv_cameraIntrinsicsDestroy(distortion->intrinsics);
MEM_freeN(distortion);
}
@@ -1642,7 +1642,7 @@ void BKE_tracking_distort_v2(MovieTracking *tracking, const float co[2], float r
{
MovieTrackingCamera *camera = &tracking->camera;
- libmv_cameraIntrinsicsOptions camera_intrinsics_options;
+ libmv_CameraIntrinsicsOptions camera_intrinsics_options;
double x, y;
float aspy = 1.0f / tracking->camera.pixel_aspect;
@@ -1652,7 +1652,7 @@ void BKE_tracking_distort_v2(MovieTracking *tracking, const float co[2], float r
x = (co[0] - camera->principal[0]) / camera->focal;
y = (co[1] - camera->principal[1] * aspy) / camera->focal;
- libmv_ApplyCameraIntrinsics(&camera_intrinsics_options, x, y, &x, &y);
+ libmv_cameraIntrinsicsApply(&camera_intrinsics_options, x, y, &x, &y);
/* result is in image coords already */
r_co[0] = x;
@@ -1663,13 +1663,13 @@ void BKE_tracking_undistort_v2(MovieTracking *tracking, const float co[2], float
{
MovieTrackingCamera *camera = &tracking->camera;
- libmv_cameraIntrinsicsOptions camera_intrinsics_options;
+ libmv_CameraIntrinsicsOptions camera_intrinsics_options;
double x = co[0], y = co[1];
float aspy = 1.0f / tracking->camera.pixel_aspect;
cameraIntrinscisOptionsFromTracking(&camera_intrinsics_options, tracking, 0, 0);
- libmv_InvertCameraIntrinsics(&camera_intrinsics_options, x, y, &x, &y);
+ libmv_cameraIntrinsicsInvert(&camera_intrinsics_options, x, y, &x, &y);
r_co[0] = (float)x * camera->focal + camera->principal[0];
r_co[1] = (float)y * camera->focal + camera->principal[1] * aspy;
@@ -2529,7 +2529,7 @@ static bool track_context_update_reference(MovieTrackingContext *context, TrackC
/* Fill in libmv tracker options structure with settings need to be used to perform track. */
static void tracking_configure_tracker(MovieTrackingTrack *track, float *mask,
- struct libmv_trackRegionOptions *options)
+ libmv_TrackRegionOptions *options)
{
options->motion_model = track->motion_model;
@@ -2654,8 +2654,8 @@ static bool configure_and_run_tracker(ImBuf *destination_ibuf, MovieTrackingTrac
double src_pixel_x[5], src_pixel_y[5];
/* Settings for the tracker */
- struct libmv_trackRegionOptions options = {0};
- struct libmv_trackRegionResult result;
+ libmv_TrackRegionOptions options = {0};
+ libmv_TrackRegionResult result;
float *patch_new;
@@ -2930,17 +2930,17 @@ static struct libmv_Tracks *libmv_tracks_new(ListBase *tracksbase, int width, in
}
/* Retrieve refined camera intrinsics from libmv to blender. */
-static void reconstruct_retrieve_libmv_intrinscis(MovieReconstructContext *context, MovieTracking *tracking)
+static void reconstruct_retrieve_libmv_intrinsics(MovieReconstructContext *context, MovieTracking *tracking)
{
struct libmv_Reconstruction *libmv_reconstruction = context->reconstruction;
- struct libmv_CameraIntrinsics *libmv_intrinsics = libmv_ReconstructionExtractIntrinsics(libmv_reconstruction);
+ struct libmv_CameraIntrinsics *libmv_intrinsics = libmv_reconstructionExtractIntrinsics(libmv_reconstruction);
float aspy = 1.0f / tracking->camera.pixel_aspect;
double focal_length, principal_x, principal_y, k1, k2, k3;
int width, height;
- libmv_CameraIntrinsicsExtract(libmv_intrinsics, &focal_length, &principal_x, &principal_y,
+ libmv_cameraIntrinsicsExtract(libmv_intrinsics, &focal_length, &principal_x, &principal_y,
&k1, &k2, &k3, &width, &height);
tracking->camera.focal = focal_length;
@@ -2987,13 +2987,13 @@ static int reconstruct_retrieve_libmv_tracks(MovieReconstructContext *context, M
while (track) {
double pos[3];
- if (libmv_reporojectionPointForTrack(libmv_reconstruction, tracknr, pos)) {
+ if (libmv_reprojectionPointForTrack(libmv_reconstruction, tracknr, pos)) {
track->bundle_pos[0] = pos[0];
track->bundle_pos[1] = pos[1];
track->bundle_pos[2] = pos[2];
track->flag |= TRACK_HAS_BUNDLE;
- track->error = libmv_reporojectionErrorForTrack(libmv_reconstruction, tracknr);
+ track->error = libmv_reprojectionErrorForTrack(libmv_reconstruction, tracknr);
}
else {
track->flag &= ~TRACK_HAS_BUNDLE;
@@ -3017,10 +3017,10 @@ static int reconstruct_retrieve_libmv_tracks(MovieReconstructContext *context, M
for (a = sfra; a <= efra; a++) {
double matd[4][4];
- if (libmv_reporojectionCameraForImage(libmv_reconstruction, a, matd)) {
+ if (libmv_reprojectionCameraForImage(libmv_reconstruction, a, matd)) {
int i, j;
float mat[4][4];
- float error = libmv_reporojectionErrorForImage(libmv_reconstruction, a);
+ float error = libmv_reprojectionErrorForImage(libmv_reconstruction, a);
for (i = 0; i < 4; i++) {
for (j = 0; j < 4; j++)
@@ -3081,8 +3081,8 @@ static int reconstruct_retrieve_libmv_tracks(MovieReconstructContext *context, M
/* Retrieve all the libmv data from context to blender's side data blocks. */
static int reconstruct_retrieve_libmv(MovieReconstructContext *context, MovieTracking *tracking)
{
- /* take the intrinscis back from libmv */
- reconstruct_retrieve_libmv_intrinscis(context, tracking);
+ /* take the intrinsics back from libmv */
+ reconstruct_retrieve_libmv_intrinsics(context, tracking);
return reconstruct_retrieve_libmv_tracks(context, tracking);
}
@@ -3243,7 +3243,7 @@ MovieReconstructContext *BKE_tracking_reconstruction_context_new(MovieTracking *
void BKE_tracking_reconstruction_context_free(MovieReconstructContext *context)
{
if (context->reconstruction)
- libmv_destroyReconstruction(context->reconstruction);
+ libmv_reconstructionDestroy(context->reconstruction);
libmv_tracksDestroy(context->tracks);
@@ -3266,7 +3266,7 @@ static void reconstruct_update_solve_cb(void *customdata, double progress, const
}
/* FIll in camera intrinsics structure from reconstruction context. */
-static void camraIntrincicsOptionsFromContext(libmv_cameraIntrinsicsOptions *camera_intrinsics_options,
+static void camraIntrincicsOptionsFromContext(libmv_CameraIntrinsicsOptions *camera_intrinsics_options,
MovieReconstructContext *context)
{
camera_intrinsics_options->focal_length = context->focal_length;
@@ -3283,7 +3283,7 @@ static void camraIntrincicsOptionsFromContext(libmv_cameraIntrinsicsOptions *cam
}
/* Fill in reconstruction options structure from reconstruction context. */
-static void reconstructionOptionsFromContext(libmv_reconstructionOptions *reconstruction_options,
+static void reconstructionOptionsFromContext(libmv_ReconstructionOptions *reconstruction_options,
MovieReconstructContext *context)
{
reconstruction_options->select_keyframes = context->select_keyframes;
@@ -3313,8 +3313,8 @@ void BKE_tracking_reconstruction_solve(MovieReconstructContext *context, short *
ReconstructProgressData progressdata;
- libmv_cameraIntrinsicsOptions camera_intrinsics_options;
- libmv_reconstructionOptions reconstruction_options;
+ libmv_CameraIntrinsicsOptions camera_intrinsics_options;
+ libmv_ReconstructionOptions reconstruction_options;
progressdata.stop = stop;
progressdata.do_update = do_update;
@@ -3558,7 +3558,7 @@ void BKE_tracking_detect_fast(MovieTracking *tracking, ListBase *tracksbase, ImB
framenr, ibuf->x, ibuf->y, layer,
place_outside_layer ? true : false);
- libmv_destroyFeatures(features);
+ libmv_featuresDestroy(features);
}
/*********************** 2D stabilization *************************/
diff --git a/source/blender/blenlib/BLI_alloca.h b/source/blender/blenlib/BLI_alloca.h
new file mode 100644
index 00000000000..b93f5b7123e
--- /dev/null
+++ b/source/blender/blenlib/BLI_alloca.h
@@ -0,0 +1,46 @@
+/*
+ * ***** 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.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#ifndef __BLI_ALLOCA_H__
+
+/** \file BLI_alloca.h
+ * \ingroup bli
+ *
+ * Defines alloca and utility macro BLI_array_alloca
+ */
+
+/* BLI_array_alloca / alloca */
+#ifdef _MSC_VER
+# define alloca _alloca
+#endif
+
+#if defined(__MINGW32__)
+# include <malloc.h> /* mingw needs for alloca() */
+#endif
+
+#if defined(__GNUC__) || defined(__clang__)
+#define BLI_array_alloca(arr, realsize) \
+ (typeof(arr))alloca(sizeof(*arr) * (realsize))
+#else
+#define BLI_array_alloca(arr, realsize) \
+ alloca(sizeof(*arr) * (realsize))
+#endif
+
+#endif /* __BLI_ALLOCA_H__ */
diff --git a/source/blender/blenlib/BLI_array.h b/source/blender/blenlib/BLI_array.h
index 3fb50afdeac..566fc95eb4f 100644
--- a/source/blender/blenlib/BLI_array.h
+++ b/source/blender/blenlib/BLI_array.h
@@ -40,11 +40,11 @@
#define _bli_array_totalsize_dynamic(arr) ( \
((arr) == NULL) ? \
0 : \
- MEM_allocN_len(arr) / sizeof(*arr) \
+ MEM_allocN_len(arr) / sizeof(*(arr)) \
)
#define _bli_array_totalsize_static(arr) \
- (sizeof(_##arr##_static) / sizeof(*arr))
+ (sizeof(_##arr##_static) / sizeof(*(arr)))
#define _bli_array_totalsize(arr) ( \
(size_t) \
@@ -66,8 +66,9 @@ void _bli_array_grow_func(void **arr_p, const void *arr_static,
/* -------------------------------------------------------------------- */
/* public defines */
+/* use sizeof(*(arr)) to ensure the array exists and is an array */
#define BLI_array_declare(arr) \
- int _##arr##_count = 0; \
+ int _##arr##_count = ((void)(sizeof(*(arr))), 0); \
void *_##arr##_static = NULL
/* this will use stack space, up to maxstatic array elements, before
@@ -95,7 +96,7 @@ void _bli_array_grow_func(void **arr_p, const void *arr_static,
(LIKELY(_bli_array_totalsize(arr) >= _##arr##_count + num) ? \
(void)0 /* do nothing */ : \
_bli_array_grow_func((void **)&(arr), _##arr##_static, \
- sizeof(*arr), _##arr##_count, num, \
+ sizeof(*(arr)), _##arr##_count, num, \
"BLI_array." #arr), \
(void)0) /* msvc2008 needs this */ \
), \
@@ -148,8 +149,8 @@ void _bli_array_grow_func(void **arr_p, const void *arr_static,
/* only to prevent unused warnings */
#define BLI_array_fake_user(arr) \
- (void)_##arr##_count, \
- (void)_##arr##_static
+ ((void)_##arr##_count, \
+ (void)_##arr##_static)
/* -------------------------------------------------------------------- */
@@ -161,7 +162,7 @@ void _bli_array_grow_func(void **arr_p, const void *arr_static,
* but use when the max size is known ahead of time */
#define BLI_array_fixedstack_declare(arr, maxstatic, realsize, allocstr) \
char _##arr##_static[maxstatic * sizeof(*(arr))]; \
- const int _##arr##_is_static = ((void *)_##arr##_static) != ( \
+ const bool _##arr##_is_static = ((void *)_##arr##_static) != ( \
arr = ((realsize) <= maxstatic) ? \
(void *)_##arr##_static : \
MEM_mallocN(sizeof(*(arr)) * (realsize), allocstr) \
@@ -173,30 +174,13 @@ void _bli_array_grow_func(void **arr_p, const void *arr_static,
} (void)0
-/* alloca */
-#ifdef _MSC_VER
-# define alloca _alloca
-#endif
-
-#if defined(__MINGW32__)
-# include <malloc.h> /* mingw needs for alloca() */
-#endif
-
-#if defined(__GNUC__) || defined(__clang__)
-#define BLI_array_alloca(arr, realsize) \
- (typeof(arr))alloca(sizeof(*arr) * (realsize))
-
-#define BLI_array_alloca_and_count(arr, realsize) \
- (typeof(arr))alloca(sizeof(*arr) * (realsize)); \
- const int _##arr##_count = (realsize)
+void _bli_array_reverse(void *arr, unsigned int arr_len, size_t arr_stride);
+#define BLI_array_reverse(arr, arr_len) \
+ _bli_array_reverse(arr, arr_len, sizeof(*(arr)))
-#else
-#define BLI_array_alloca(arr, realsize) \
- alloca(sizeof(*arr) * (realsize))
+void _bli_array_wrap(void *arr, unsigned int arr_len, size_t arr_stride, int dir);
+#define BLI_array_wrap(arr, arr_len, dir) \
+ _bli_array_wrap(arr, arr_len, sizeof(*(arr)), dir)
-#define BLI_array_alloca_and_count(arr, realsize) \
- alloca(sizeof(*arr) * (realsize)); \
- const int _##arr##_count = (realsize)
-#endif
#endif /* __BLI_ARRAY_H__ */
diff --git a/source/blender/blenlib/BLI_bitmap.h b/source/blender/blenlib/BLI_bitmap.h
index 02e5d6bd797..ca98d28cc40 100644
--- a/source/blender/blenlib/BLI_bitmap.h
+++ b/source/blender/blenlib/BLI_bitmap.h
@@ -26,7 +26,7 @@
#ifndef __BLI_BITMAP_H__
#define __BLI_BITMAP_H__
-typedef unsigned int *BLI_bitmap;
+typedef unsigned int BLI_bitmap;
/* warning: the bitmap does not keep track of its own size or check
* for out-of-bounds access */
@@ -48,7 +48,7 @@ typedef unsigned int *BLI_bitmap;
/* allocate memory for a bitmap with '_tot' bits; free
* with MEM_freeN() */
#define BLI_BITMAP_NEW(_tot, _alloc_string) \
- ((BLI_bitmap)MEM_callocN(BLI_BITMAP_SIZE(_tot), \
+ ((BLI_bitmap *)MEM_callocN(BLI_BITMAP_SIZE(_tot), \
_alloc_string))
/* get the value of a single bit at '_index' */
diff --git a/source/blender/blenlib/BLI_buffer.h b/source/blender/blenlib/BLI_buffer.h
index fe835e7cadc..461b56e157f 100644
--- a/source/blender/blenlib/BLI_buffer.h
+++ b/source/blender/blenlib/BLI_buffer.h
@@ -53,11 +53,11 @@ enum {
#define BLI_buffer_declare_static(type_, name_, flag_, static_count_) \
char name_ ## user; /* warn for free only */ \
- type_ *name_ ## _static_[static_count_]; \
+ type_ name_ ## _static_[static_count_]; \
BLI_Buffer name_ = { \
/* clear the static memory if this is a calloc'd array */ \
((void)((flag_ & BLI_BUFFER_USE_CALLOC) ? \
- memset(name_ ## _static_, 0, sizeof(name_ ## _static_)) : 0\
+ memset(name_ ## _static_, 0, sizeof(name_ ## _static_)) : NULL \
), /* memset-end */ \
name_ ## _static_), \
sizeof(type_), \
diff --git a/source/blender/blenlib/BLI_ghash.h b/source/blender/blenlib/BLI_ghash.h
index 930715b4bc6..3ad0e18c8d7 100644
--- a/source/blender/blenlib/BLI_ghash.h
+++ b/source/blender/blenlib/BLI_ghash.h
@@ -73,7 +73,7 @@ void *BLI_ghash_lookup(GHash *gh, const void *key);
bool BLI_ghash_remove(GHash *gh, void *key, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfreefp);
void BLI_ghash_clear(GHash *gh, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfreefp);
void *BLI_ghash_pop(GHash *gh, void *key, GHashKeyFreeFP keyfreefp);
-bool BLI_ghash_haskey(GHash *gh, const void *key);
+bool BLI_ghash_haskey(GHash *gh, const void *key);
int BLI_ghash_size(GHash *gh);
/* *** */
diff --git a/source/blender/blenlib/BLI_math_base.h b/source/blender/blenlib/BLI_math_base.h
index 4b71babdba1..69dbd3253f0 100644
--- a/source/blender/blenlib/BLI_math_base.h
+++ b/source/blender/blenlib/BLI_math_base.h
@@ -80,6 +80,14 @@
#define MAXFLOAT ((float)3.40282347e+38)
#endif
+#if defined(__GNUC__)
+# define NAN_FLT __builtin_nanf("")
+#else
+/* evil quiet NaN definition */
+static const int NAN_INT = 0x7FC00000;
+# define NAN_FLT (*((float *)(&NAN_INT)))
+#endif
+
/* do not redefine functions from C99 or POSIX.1-2001 */
#if !(defined(_ISOC99_SOURCE) || (defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 200112L))
diff --git a/source/blender/blenlib/BLI_math_geom.h b/source/blender/blenlib/BLI_math_geom.h
index f9671f57acd..6cb7103be9b 100644
--- a/source/blender/blenlib/BLI_math_geom.h
+++ b/source/blender/blenlib/BLI_math_geom.h
@@ -147,10 +147,6 @@ int isect_point_tri_v2(const float pt[2], const float v1[2], const float v2[2],
int isect_point_tri_v2_cw(const float pt[2], const float v1[2], const float v2[2], const float v3[2]);
int isect_point_tri_v2_int(const int x1, const int y1, const int x2, const int y2, const int a, const int b);
bool isect_point_tri_prism_v3(const float p[3], const float v1[3], const float v2[3], const float v3[3]);
-void isect_point_quad_uv_v2(const float v0[2], const float v1[2], const float v2[2], const float v3[2],
- const float pt[2], float r_uv[2]);
-void isect_point_face_uv_v2(const int isquad, const float v0[2], const float v1[2], const float v2[2],
- const float v3[2], const float pt[2], float r_uv[2]);
/* axis-aligned bounding box */
bool isect_aabb_aabb_v3(const float min1[3], const float max1[3], const float min2[3], const float max2[3]);
@@ -198,7 +194,7 @@ void barycentric_weights_v2(const float v1[2], const float v2[2], const float v3
void barycentric_weights_v2_quad(const float v1[2], const float v2[2], const float v3[2], const float v4[2],
const float co[2], float w[4]);
-int barycentric_coords_v2(const float v1[2], const float v2[2], const float v3[2], const float co[2], float w[3]);
+bool barycentric_coords_v2(const float v1[2], const float v2[2], const float v3[2], const float co[2], float w[3]);
int barycentric_inside_triangle_v2(const float w[3]);
void resolve_tri_uv(float r_uv[2], const float st[2], const float st0[2], const float st1[2], const float st2[2]);
@@ -273,9 +269,9 @@ MINLINE void madd_sh_shfl(float r[9], const float sh[3], const float f);
float form_factor_quad(const float p[3], const float n[3],
const float q0[3], const float q1[3], const float q2[3], const float q3[3]);
-int form_factor_visible_quad(const float p[3], const float n[3],
- const float v0[3], const float v1[3], const float v2[3],
- float q0[3], float q1[3], float q2[3], float q3[3]);
+bool form_factor_visible_quad(const float p[3], const float n[3],
+ const float v0[3], const float v1[3], const float v2[3],
+ float q0[3], float q1[3], float q2[3], float q3[3]);
float form_factor_hemi_poly(float p[3], float n[3],
float v1[3], float v2[3], float v3[3], float v4[3]);
diff --git a/source/blender/blenlib/BLI_math_matrix.h b/source/blender/blenlib/BLI_math_matrix.h
index 723122d7814..c305cc9a030 100644
--- a/source/blender/blenlib/BLI_math_matrix.h
+++ b/source/blender/blenlib/BLI_math_matrix.h
@@ -133,12 +133,12 @@ void normalize_m4_m4(float R[4][4], float A[4][4]);
void orthogonalize_m3(float R[3][3], int axis);
void orthogonalize_m4(float R[4][4], int axis);
-int is_orthogonal_m3(float mat[3][3]);
-int is_orthogonal_m4(float mat[4][4]);
-int is_orthonormal_m3(float mat[3][3]);
-int is_orthonormal_m4(float mat[4][4]);
+bool is_orthogonal_m3(float mat[3][3]);
+bool is_orthogonal_m4(float mat[4][4]);
+bool is_orthonormal_m3(float mat[3][3]);
+bool is_orthonormal_m4(float mat[4][4]);
-int is_uniform_scaled_m3(float mat[3][3]);
+bool is_uniform_scaled_m3(float mat[3][3]);
void adjoint_m2_m2(float R[2][2], float A[2][2]);
void adjoint_m3_m3(float R[3][3], float A[3][3]);
@@ -175,7 +175,7 @@ void mat4_to_size(float r[3], float M[4][4]);
void translate_m4(float mat[4][4], float tx, float ty, float tz);
void rotate_m4(float mat[4][4], const char axis, const float angle);
void rotate_m2(float mat[2][2], const float angle);
-
+void transform_pivot_set_m4(float mat[4][4], const float pivot[3]);
void mat3_to_rot_size(float rot[3][3], float size[3], float mat3[3][3]);
void mat4_to_loc_rot_size(float loc[3], float rot[3][3], float size[3], float wmat[4][4]);
@@ -194,8 +194,11 @@ void loc_axisangle_size_to_mat4(float R[4][4],
void blend_m3_m3m3(float R[3][3], float A[3][3], float B[3][3], const float t);
void blend_m4_m4m4(float R[4][4], float A[4][4], float B[4][4], const float t);
-int is_negative_m3(float mat[3][3]);
-int is_negative_m4(float mat[4][4]);
+bool is_negative_m3(float mat[3][3]);
+bool is_negative_m4(float mat[4][4]);
+
+bool is_zero_m3(float mat[3][3]);
+bool is_zero_m4(float mat[4][4]);
/*********************************** Other ***********************************/
diff --git a/source/blender/blenlib/BLI_math_vector.h b/source/blender/blenlib/BLI_math_vector.h
index 304e2ea7fde..e163c06440c 100644
--- a/source/blender/blenlib/BLI_math_vector.h
+++ b/source/blender/blenlib/BLI_math_vector.h
@@ -36,10 +36,6 @@ extern "C" {
#include "BLI_math_inline.h"
-#if BLI_MATH_DO_INLINE
-#include "intern/math_vector_inline.c"
-#endif
-
/************************************* Init ***********************************/
#ifdef BLI_MATH_GCC_WARN_PRAGMA
@@ -47,6 +43,12 @@ extern "C" {
# pragma GCC diagnostic ignored "-Wredundant-decls"
#endif
+#ifdef __GNUC__
+# define UNUSED_RESULT_ATTR __attribute__((warn_unused_result))
+#else
+# define UNUSED_RESULT_ATTR
+#endif
+
MINLINE void zero_v2(float r[2]);
MINLINE void zero_v3(float r[3]);
MINLINE void zero_v4(float r[4]);
@@ -115,7 +117,10 @@ MINLINE void mul_v3_v3(float r[3], const float a[3]);
MINLINE void mul_v3_v3v3(float r[3], const float a[3], const float b[3]);
MINLINE void mul_v4_fl(float r[4], float f);
MINLINE void mul_v4_v4fl(float r[3], const float a[3], float f);
-MINLINE float mul_project_m4_v3_zfac(float mat[4][4], const float co[3]);
+MINLINE float mul_project_m4_v3_zfac(float mat[4][4], const float co[3]) UNUSED_RESULT_ATTR;
+MINLINE float dot_m3_v3_row_x(float M[3][3], const float a[3]) UNUSED_RESULT_ATTR;
+MINLINE float dot_m3_v3_row_y(float M[3][3], const float a[3]) UNUSED_RESULT_ATTR;
+MINLINE float dot_m3_v3_row_z(float M[3][3], const float a[3]) UNUSED_RESULT_ATTR;
MINLINE void madd_v3_v3fl(float r[3], const float a[3], float f);
MINLINE void madd_v3_v3v3(float r[3], const float a[3], const float b[3]);
@@ -134,10 +139,10 @@ MINLINE void negate_v4_v4(float r[4], const float a[3]);
MINLINE void negate_v3_short(short r[3]);
-MINLINE float dot_v2v2(const float a[2], const float b[2]);
-MINLINE float dot_v3v3(const float a[3], const float b[3]);
+MINLINE float dot_v2v2(const float a[2], const float b[2]) UNUSED_RESULT_ATTR;
+MINLINE float dot_v3v3(const float a[3], const float b[3]) UNUSED_RESULT_ATTR;
-MINLINE float cross_v2v2(const float a[2], const float b[2]);
+MINLINE float cross_v2v2(const float a[2], const float b[2]) UNUSED_RESULT_ATTR;
MINLINE void cross_v3_v3v3(float r[3], const float a[3], const float b[3]);
MINLINE void add_newell_cross_v3_v3v3(float n[3], const float v_prev[3], const float v_curr[3]);
@@ -146,20 +151,20 @@ MINLINE void star_m3_v3(float rmat[3][3], float a[3]);
/*********************************** Length **********************************/
-MINLINE float len_squared_v2(const float v[2]);
-MINLINE float len_squared_v3(const float v[3]);
-MINLINE float len_manhattan_v2(const float v[2]);
-MINLINE int len_manhattan_v2_int(const int v[2]);
-MINLINE float len_manhattan_v3(const float v[3]);
-MINLINE float len_v2(const float a[2]);
-MINLINE float len_v2v2(const float a[2], const float b[2]);
-MINLINE float len_squared_v2v2(const float a[2], const float b[2]);
-MINLINE float len_squared_v3v3(const float a[3], const float b[3]);
-MINLINE float len_manhattan_v2v2(const float a[2], const float b[2]);
-MINLINE int len_manhattan_v2v2_int(const int a[2], const int b[2]);
-MINLINE float len_manhattan_v3v3(const float a[3], const float b[3]);
-MINLINE float len_v3(const float a[3]);
-MINLINE float len_v3v3(const float a[3], const float b[3]);
+MINLINE float len_squared_v2(const float v[2]) UNUSED_RESULT_ATTR;
+MINLINE float len_squared_v3(const float v[3]) UNUSED_RESULT_ATTR;
+MINLINE float len_manhattan_v2(const float v[2]) UNUSED_RESULT_ATTR;
+MINLINE int len_manhattan_v2_int(const int v[2]) UNUSED_RESULT_ATTR;
+MINLINE float len_manhattan_v3(const float v[3]) UNUSED_RESULT_ATTR;
+MINLINE float len_v2(const float a[2]) UNUSED_RESULT_ATTR;
+MINLINE float len_v2v2(const float a[2], const float b[2]) UNUSED_RESULT_ATTR;
+MINLINE float len_squared_v2v2(const float a[2], const float b[2]) UNUSED_RESULT_ATTR;
+MINLINE float len_squared_v3v3(const float a[3], const float b[3]) UNUSED_RESULT_ATTR;
+MINLINE float len_manhattan_v2v2(const float a[2], const float b[2]) UNUSED_RESULT_ATTR;
+MINLINE int len_manhattan_v2v2_int(const int a[2], const int b[2]) UNUSED_RESULT_ATTR;
+MINLINE float len_manhattan_v3v3(const float a[3], const float b[3]) UNUSED_RESULT_ATTR;
+MINLINE float len_v3(const float a[3]) UNUSED_RESULT_ATTR;
+MINLINE float len_v3v3(const float a[3], const float b[3]) UNUSED_RESULT_ATTR;
MINLINE float normalize_v2(float r[2]);
MINLINE float normalize_v2_v2(float r[2], const float a[2]);
@@ -191,35 +196,35 @@ void flip_v2_v2v2(float v[2], const float v1[2], const float v2[2]);
/********************************* Comparison ********************************/
-MINLINE int is_zero_v3(const float a[3]);
-MINLINE int is_zero_v4(const float a[4]);
-MINLINE int is_one_v3(const float a[3]);
+MINLINE int is_zero_v3(const float a[3]) UNUSED_RESULT_ATTR;
+MINLINE int is_zero_v4(const float a[4]) UNUSED_RESULT_ATTR;
+MINLINE int is_one_v3(const float a[3]) UNUSED_RESULT_ATTR;
-MINLINE int equals_v2v2(const float v1[2], const float v2[2]);
-MINLINE int equals_v3v3(const float a[3], const float b[3]);
-MINLINE int compare_v2v2(const float a[2], const float b[2], const float limit);
-MINLINE int compare_v3v3(const float a[3], const float b[3], const float limit);
-MINLINE int compare_len_v3v3(const float a[3], const float b[3], const float limit);
+MINLINE int equals_v2v2(const float v1[2], const float v2[2]) UNUSED_RESULT_ATTR;
+MINLINE int equals_v3v3(const float a[3], const float b[3]) UNUSED_RESULT_ATTR;
+MINLINE int compare_v2v2(const float a[2], const float b[2], const float limit) UNUSED_RESULT_ATTR;
+MINLINE int compare_v3v3(const float a[3], const float b[3], const float limit) UNUSED_RESULT_ATTR;
+MINLINE int compare_len_v3v3(const float a[3], const float b[3], const float limit) UNUSED_RESULT_ATTR;
-MINLINE int compare_v4v4(const float a[4], const float b[4], const float limit);
-MINLINE int equals_v4v4(const float a[4], const float b[4]);
+MINLINE int compare_v4v4(const float a[4], const float b[4], const float limit) UNUSED_RESULT_ATTR;
+MINLINE int equals_v4v4(const float a[4], const float b[4]) UNUSED_RESULT_ATTR;
-MINLINE float line_point_side_v2(const float l1[2], const float l2[2], const float pt[2]);
+MINLINE float line_point_side_v2(const float l1[2], const float l2[2], const float pt[2]) UNUSED_RESULT_ATTR;
/********************************** Angles ***********************************/
/* - angle with 2 arguments is angle between vector */
/* - angle with 3 arguments is angle between 3 points at the middle point */
/* - angle_normalized_* is faster equivalent if vectors are normalized */
-float angle_v2v2(const float a[2], const float b[2]);
-float angle_signed_v2v2(const float v1[2], const float v2[2]);
-float angle_v2v2v2(const float a[2], const float b[2], const float c[2]);
-float angle_normalized_v2v2(const float a[2], const float b[2]);
-float angle_v3v3(const float a[3], const float b[3]);
-float angle_v3v3v3(const float a[3], const float b[3], const float c[3]);
-float cos_v3v3v3(const float p1[3], const float p2[3], const float p3[3]);
-float angle_normalized_v3v3(const float v1[3], const float v2[3]);
-float angle_on_axis_v3v3v3_v3(const float v1[3], const float v2[3], const float v3[3], const float axis[3]);
+float angle_v2v2(const float a[2], const float b[2]) UNUSED_RESULT_ATTR;
+float angle_signed_v2v2(const float v1[2], const float v2[2]) UNUSED_RESULT_ATTR;
+float angle_v2v2v2(const float a[2], const float b[2], const float c[2]) UNUSED_RESULT_ATTR;
+float angle_normalized_v2v2(const float a[2], const float b[2]) UNUSED_RESULT_ATTR;
+float angle_v3v3(const float a[3], const float b[3]) UNUSED_RESULT_ATTR;
+float angle_v3v3v3(const float a[3], const float b[3], const float c[3]) UNUSED_RESULT_ATTR;
+float cos_v3v3v3(const float p1[3], const float p2[3], const float p3[3]) UNUSED_RESULT_ATTR;
+float angle_normalized_v3v3(const float v1[3], const float v2[3]) UNUSED_RESULT_ATTR;
+float angle_on_axis_v3v3v3_v3(const float v1[3], const float v2[3], const float v3[3], const float axis[3]) UNUSED_RESULT_ATTR;
void angle_tri_v3(float angles[3], const float v1[3], const float v2[3], const float v3[3]);
void angle_quad_v3(float angles[4], const float v1[3], const float v2[3], const float v3[3], const float v4[3]);
void angle_poly_v3(float *angles, const float *verts[3], int len);
@@ -255,7 +260,7 @@ void axis_sort_v3(const float axis_values[3], int r_axis_order[3]);
/***************************** Array Functions *******************************/
/* attempted to follow fixed length vertex functions. names could be improved*/
-double dot_vn_vn(const float *array_src_a, const float *array_src_b, const int size);
+double dot_vn_vn(const float *array_src_a, const float *array_src_b, const int size) UNUSED_RESULT_ATTR;
float normalize_vn_vn(float *array_tar, const float *array_src, const int size);
float normalize_vn(float *array_tar, const int size);
void range_vn_i(int *array_tar, const int size, const int start);
@@ -277,9 +282,16 @@ 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);
+/**************************** Inline Definitions ******************************/
+
+#if BLI_MATH_DO_INLINE
+#include "intern/math_vector_inline.c"
+#endif
+
#ifdef BLI_MATH_GCC_WARN_PRAGMA
# pragma GCC diagnostic pop
#endif
+#undef UNUSED_RESULT_ATTR
#ifdef __cplusplus
}
diff --git a/source/blender/blenlib/BLI_memarena.h b/source/blender/blenlib/BLI_memarena.h
index 092bb639b91..d54dab42e05 100644
--- a/source/blender/blenlib/BLI_memarena.h
+++ b/source/blender/blenlib/BLI_memarena.h
@@ -55,6 +55,7 @@ typedef struct MemArena MemArena;
struct MemArena *BLI_memarena_new(const int bufsize, const char *name)
#if MEM_GNU_ATTRIBUTES
+__attribute__((malloc))
__attribute__((warn_unused_result))
__attribute__((nonnull(2)))
#endif
@@ -85,6 +86,7 @@ __attribute__((nonnull(1)))
void *BLI_memarena_alloc(struct MemArena *ma, int size)
#if MEM_GNU_ATTRIBUTES
+__attribute__((malloc))
__attribute__((warn_unused_result))
__attribute__((nonnull(1)))
__attribute__((alloc_size(2)))
diff --git a/source/blender/blenlib/BLI_mempool.h b/source/blender/blenlib/BLI_mempool.h
index a1cbad73239..1c470d59062 100644
--- a/source/blender/blenlib/BLI_mempool.h
+++ b/source/blender/blenlib/BLI_mempool.h
@@ -50,17 +50,20 @@ typedef struct BLI_mempool BLI_mempool;
BLI_mempool *BLI_mempool_create(int esize, int totelem, int pchunk, int flag)
#ifdef __GNUC__
+__attribute__((malloc))
__attribute__((warn_unused_result))
#endif
;
void *BLI_mempool_alloc(BLI_mempool *pool)
#ifdef __GNUC__
+__attribute__((malloc))
__attribute__((warn_unused_result))
__attribute__((nonnull(1)))
#endif
;
void *BLI_mempool_calloc(BLI_mempool *pool)
#ifdef __GNUC__
+__attribute__((malloc))
__attribute__((warn_unused_result))
__attribute__((nonnull(1)))
#endif
@@ -86,14 +89,29 @@ __attribute__((warn_unused_result))
__attribute__((nonnull(1)))
#endif
;
-void BLI_mempool_as_array(BLI_mempool *pool, void **data)
+void BLI_mempool_as_table(BLI_mempool *pool, void **data)
#ifdef __GNUC__
-__attribute__((nonnull(1)))
+__attribute__((nonnull(1, 2)))
+#endif
+;
+
+void **BLI_mempool_as_tableN(BLI_mempool *pool, const char *allocstr)
+#ifdef __GNUC__
+__attribute__((malloc))
+__attribute__((warn_unused_result))
+__attribute__((nonnull(1, 2)))
+#endif
+;
+
+void BLI_mempool_as_array(BLI_mempool *pool, void *data)
+#ifdef __GNUC__
+__attribute__((nonnull(1, 2)))
#endif
;
-void *BLI_mempool_as_arrayN(BLI_mempool *pool, const char *allocstr)
+void *BLI_mempool_as_arrayN(BLI_mempool *pool, const char *allocstr)
#ifdef __GNUC__
+__attribute__((malloc))
__attribute__((warn_unused_result))
__attribute__((nonnull(1, 2)))
#endif
diff --git a/source/blender/blenlib/BLI_path_util.h b/source/blender/blenlib/BLI_path_util.h
index e0a34e35acc..cb812fe8595 100644
--- a/source/blender/blenlib/BLI_path_util.h
+++ b/source/blender/blenlib/BLI_path_util.h
@@ -89,7 +89,18 @@ 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);
+void BLI_path_append(char *__restrict dst, const size_t maxlen,
+ const char *__restrict file)
+#ifdef __GNUC__
+__attribute__((nonnull))
+#endif
+;
+void BLI_join_dirfile(char *__restrict string, const size_t maxlen,
+ const char *__restrict dir, const char *__restrict file)
+#ifdef __GNUC__
+__attribute__((nonnull))
+#endif
+;
const char *BLI_path_basename(const char *path);
typedef enum bli_rebase_state {
diff --git a/source/blender/blenlib/BLI_string.h b/source/blender/blenlib/BLI_string.h
index 02eb0734f8c..6c66d2f4e18 100644
--- a/source/blender/blenlib/BLI_string.h
+++ b/source/blender/blenlib/BLI_string.h
@@ -40,6 +40,7 @@ extern "C" {
char *BLI_strdupn(const char *str, const size_t len)
#ifdef __GNUC__
+__attribute__((malloc))
__attribute__((warn_unused_result))
__attribute__((nonnull))
#endif
@@ -47,6 +48,7 @@ __attribute__((nonnull))
char *BLI_strdup(const char *str)
#ifdef __GNUC__
+__attribute__((malloc))
__attribute__((warn_unused_result))
__attribute__((nonnull))
#endif
@@ -54,6 +56,7 @@ __attribute__((nonnull))
char *BLI_strdupcat(const char *__restrict str1, const char *__restrict str2)
#ifdef __GNUC__
+__attribute__((malloc))
__attribute__((warn_unused_result))
__attribute__((nonnull))
#endif
@@ -81,13 +84,15 @@ __attribute__((nonnull))
char *BLI_str_quoted_substrN(const char *__restrict str, const char *__restrict prefix)
#ifdef __GNUC__
+__attribute__((malloc))
__attribute__((warn_unused_result))
__attribute__((nonnull))
#endif
;
-char *BLI_replacestr(char *__restrict str, const char *__restrict oldText, const char *__restrict newText)
+char *BLI_replacestrN(const char *__restrict str, const char *__restrict substr_old, const char *__restrict substr_new)
#ifdef __GNUC__
+__attribute__((malloc))
__attribute__((warn_unused_result))
__attribute__((nonnull))
#endif
@@ -108,6 +113,7 @@ __attribute__ ((format(printf, 3, 0)))
char *BLI_sprintfN(const char *__restrict format, ...)
#ifdef __GNUC__
+__attribute__((malloc))
__attribute__ ((format(printf, 1, 2)))
__attribute__((warn_unused_result))
__attribute__((nonnull))
@@ -183,4 +189,4 @@ __attribute__((nonnull))
}
#endif
-#endif
+#endif /* __BLI_STRING_H__ */
diff --git a/source/blender/blenlib/BLI_string_utf8.h b/source/blender/blenlib/BLI_string_utf8.h
index adef843d2cc..db32190494a 100644
--- a/source/blender/blenlib/BLI_string_utf8.h
+++ b/source/blender/blenlib/BLI_string_utf8.h
@@ -31,43 +31,57 @@
extern "C" {
#endif
-char *BLI_strncpy_utf8(char *__restrict dst, const char *__restrict src, size_t maxncpy);
-char *BLI_strncat_utf8(char *__restrict dst, const char *__restrict src, size_t maxncpy);
-int BLI_utf8_invalid_byte(const char *str, int length);
-int BLI_utf8_invalid_strip(char *str, int length);
+#ifdef __GNUC__
+# define ATTR_NONULL __attribute__((nonnull))
+# define ATTR_NONULL_FIRST __attribute__((nonnull(1)))
+# define ATTR_UNUSED_RESULT __attribute__((warn_unused_result))
+#else
+# define ATTR_NONULL
+# define ATTR_NONULL_FIRST
+# define ATTR_UNUSED_RESULT
+#endif
+
+char *BLI_strncpy_utf8(char *__restrict dst, const char *__restrict src, size_t maxncpy) ATTR_NONULL;
+char *BLI_strncat_utf8(char *__restrict dst, const char *__restrict src, size_t maxncpy) ATTR_NONULL;
+int BLI_utf8_invalid_byte(const char *str, int length) ATTR_NONULL;
+int BLI_utf8_invalid_strip(char *str, int length) ATTR_NONULL;
-int BLI_str_utf8_size(const char *p); /* warning, can return -1 on bad chars */
-int BLI_str_utf8_size_safe(const char *p);
+int BLI_str_utf8_size(const char *p) ATTR_NONULL; /* warning, can return -1 on bad chars */
+int BLI_str_utf8_size_safe(const char *p) ATTR_NONULL;
/* copied from glib */
-unsigned int BLI_str_utf8_as_unicode(const char *p);
-unsigned int BLI_str_utf8_as_unicode_and_size(const char *__restrict p, size_t *__restrict index);
-unsigned int BLI_str_utf8_as_unicode_and_size_safe(const char *__restrict p, size_t *__restrict index);
-unsigned int BLI_str_utf8_as_unicode_step(const char *__restrict p, size_t *__restrict index);
+unsigned int BLI_str_utf8_as_unicode(const char *p) ATTR_NONULL;
+unsigned int BLI_str_utf8_as_unicode_and_size(const char *__restrict p, size_t *__restrict index) ATTR_NONULL;
+unsigned int BLI_str_utf8_as_unicode_and_size_safe(const char *__restrict p, size_t *__restrict index) ATTR_NONULL;
+unsigned int BLI_str_utf8_as_unicode_step(const char *__restrict p, size_t *__restrict index) ATTR_NONULL;
size_t BLI_str_utf8_from_unicode(unsigned int c, char *outbuf);
-char *BLI_str_find_prev_char_utf8(const char *str, const char *p);
-char *BLI_str_find_next_char_utf8(const char *p, const char *end);
-char *BLI_str_prev_char_utf8(const char *p);
+char *BLI_str_find_prev_char_utf8(const char *str, const char *p) ATTR_NONULL;
+char *BLI_str_find_next_char_utf8(const char *p, const char *end) ATTR_NONULL_FIRST;
+char *BLI_str_prev_char_utf8(const char *p) ATTR_NONULL;
/* wchar_t functions, copied from blenders own font.c originally */
-size_t BLI_wstrlen_utf8(const wchar_t *src);
-size_t BLI_strlen_utf8_ex(const char *strc, int *r_len_bytes);
-size_t BLI_strlen_utf8(const char *strc);
-size_t BLI_strnlen_utf8_ex(const char *strc, const size_t maxlen, int *r_len_bytes);
-size_t BLI_strnlen_utf8(const char *strc, 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);
+size_t BLI_wstrlen_utf8(const wchar_t *src) ATTR_NONULL;
+size_t BLI_strlen_utf8_ex(const char *strc, size_t *r_len_bytes) ATTR_NONULL;
+size_t BLI_strlen_utf8(const char *strc) ATTR_NONULL;
+size_t BLI_strnlen_utf8_ex(const char *strc, const size_t maxlen, size_t *r_len_bytes) ATTR_NONULL;
+size_t BLI_strnlen_utf8(const char *strc, const size_t maxlen) ATTR_NONULL;
+size_t BLI_strncpy_wchar_as_utf8(char *__restrict dst, const wchar_t *__restrict src, const size_t maxcpy) ATTR_NONULL;
+size_t BLI_strncpy_wchar_from_utf8(wchar_t *__restrict dst, const char *__restrict src, const size_t maxcpy) ATTR_NONULL;
/* 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);
+int BLI_wcswidth(const wchar_t *pwcs, size_t n) ATTR_NONULL;
+int BLI_str_utf8_char_width(const char *p) ATTR_NONULL; /* warning, can return -1 on bad chars */
+int BLI_str_utf8_char_width_safe(const char *p) ATTR_NONULL;
#define BLI_UTF8_MAX 6 /* mem */
#define BLI_UTF8_WIDTH_MAX 2 /* columns */
#define BLI_UTF8_ERR ((unsigned int)-1)
+#undef ATTR_NONULL
+#undef ATTR_NONULL_FIRST
+#undef ATTR_UNUSED_RESULT
+
#ifdef __cplusplus
}
#endif
diff --git a/source/blender/blenlib/BLI_utildefines.h b/source/blender/blenlib/BLI_utildefines.h
index 4d80080ed86..63235ad9c82 100644
--- a/source/blender/blenlib/BLI_utildefines.h
+++ b/source/blender/blenlib/BLI_utildefines.h
@@ -388,8 +388,11 @@
# define BLI_assert(a) (void)0
#endif
-/* C++ can't use _Static_assert, expects static_assert() but c++0x only */
-#if (!defined(__cplusplus)) && (defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 406)) /* gcc4.6+ only */
+/* C++ can't use _Static_assert, expects static_assert() but c++0x only,
+ * Coverity also errors out. */
+#if (!defined(__cplusplus)) && \
+ (!defined(__COVERITY__)) && \
+ (defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 406)) /* gcc4.6+ only */
# define BLI_STATIC_ASSERT(a, msg) _Static_assert(a, msg);
#else
/* TODO msvc, clang */
diff --git a/source/blender/blenlib/CMakeLists.txt b/source/blender/blenlib/CMakeLists.txt
index 1d94ca9afbc..b6b69116e67 100644
--- a/source/blender/blenlib/CMakeLists.txt
+++ b/source/blender/blenlib/CMakeLists.txt
@@ -99,6 +99,7 @@ set(SRC
intern/winstuff.c
BLI_args.h
+ BLI_alloca.h
BLI_array.h
BLI_bitmap.h
BLI_blenlib.h
diff --git a/source/blender/blenlib/intern/BLI_array.c b/source/blender/blenlib/intern/BLI_array.c
index 5823b7db3f1..510bf072513 100644
--- a/source/blender/blenlib/intern/BLI_array.c
+++ b/source/blender/blenlib/intern/BLI_array.c
@@ -59,9 +59,14 @@
*/
#include <string.h>
+#include <stdlib.h>
#include "BLI_array.h"
+#include "BLI_sys_types.h"
+#include "BLI_utildefines.h"
+#include "BLI_alloca.h"
+
#include "MEM_guardedalloc.h"
/**
@@ -95,3 +100,40 @@ void _bli_array_grow_func(void **arr_p, const void *arr_static,
arr_count += num;
#endif
}
+
+void _bli_array_reverse(void *arr_v, unsigned int arr_len, size_t arr_stride)
+{
+ const unsigned int arr_half_stride = (arr_len / 2) * arr_stride;
+ unsigned int i, i_end;
+ char *arr = arr_v;
+ char *buf = BLI_array_alloca(buf, arr_stride);
+
+ for (i = 0, i_end = (arr_len - 1) * arr_stride;
+ i < arr_half_stride;
+ i += arr_stride, i_end -= arr_stride)
+ {
+ memcpy(buf, &arr[i], arr_stride);
+ memcpy(&arr[i], &arr[i_end], arr_stride);
+ memcpy(&arr[i_end], buf, arr_stride);
+ }
+}
+
+void _bli_array_wrap(void *arr_v, unsigned int arr_len, size_t arr_stride, int dir)
+{
+ char *arr = arr_v;
+ char *buf = BLI_array_alloca(buf, arr_stride);
+
+ if (dir == -1) {
+ memcpy(buf, arr, arr_stride);
+ memmove(arr, arr + arr_stride, arr_stride * (arr_len - 1));
+ memcpy(arr + (arr_stride * (arr_len - 1)), buf, arr_stride);
+ }
+ else if (dir == 1) {
+ memcpy(buf, arr + (arr_stride * (arr_len - 1)), arr_stride);
+ memmove(arr + arr_stride, arr, arr_stride * (arr_len - 1));
+ memcpy(arr, buf, arr_stride);
+ }
+ else {
+ BLI_assert(0);
+ }
+}
diff --git a/source/blender/blenlib/intern/BLI_ghash.c b/source/blender/blenlib/intern/BLI_ghash.c
index 10b3c01d274..14dfbcffebe 100644
--- a/source/blender/blenlib/intern/BLI_ghash.c
+++ b/source/blender/blenlib/intern/BLI_ghash.c
@@ -179,7 +179,8 @@ void BLI_ghash_clear(GHash *gh, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfree
gh->nentries = 0;
gh->nbuckets = hashsizes[gh->cursize];
- gh->buckets = MEM_recallocN(gh->buckets, gh->nbuckets * sizeof(*gh->buckets));
+ MEM_freeN(gh->buckets);
+ gh->buckets = MEM_callocN(gh->nbuckets * sizeof(*gh->buckets), "buckets");
}
/* same as above but return the value,
diff --git a/source/blender/blenlib/intern/BLI_heap.c b/source/blender/blenlib/intern/BLI_heap.c
index c645db4c15e..0aaa3e13b3f 100644
--- a/source/blender/blenlib/intern/BLI_heap.c
+++ b/source/blender/blenlib/intern/BLI_heap.c
@@ -163,7 +163,7 @@ HeapNode *BLI_heap_insert(Heap *heap, float value, void *ptr)
{
HeapNode *node;
- if (UNLIKELY((heap->size + 1) > heap->bufsize)) {
+ if (UNLIKELY(heap->size >= heap->bufsize)) {
heap->bufsize *= 2;
heap->tree = MEM_reallocN(heap->tree, heap->bufsize * sizeof(*heap->tree));
}
@@ -184,7 +184,7 @@ HeapNode *BLI_heap_insert(Heap *heap, float value, void *ptr)
heap->size++;
- heap_up(heap, heap->size - 1);
+ heap_up(heap, node->index);
return node;
}
@@ -230,6 +230,8 @@ void BLI_heap_remove(Heap *heap, HeapNode *node)
{
unsigned int i = node->index;
+ BLI_assert(heap->size != 0);
+
while (i > 0) {
unsigned int p = HEAP_PARENT(i);
diff --git a/source/blender/blenlib/intern/BLI_kdtree.c b/source/blender/blenlib/intern/BLI_kdtree.c
index 0e7602b7e6b..dd54fe681b0 100644
--- a/source/blender/blenlib/intern/BLI_kdtree.c
+++ b/source/blender/blenlib/intern/BLI_kdtree.c
@@ -349,7 +349,7 @@ static void add_in_range(KDTreeNearest **ptn, int found, int *totfoundstack, int
{
KDTreeNearest *to;
- if (found + 1 > *totfoundstack) {
+ if (found >= *totfoundstack) {
KDTreeNearest *temp = MEM_callocN((*totfoundstack + 50) * sizeof(KDTreeNode), "psys_treefoundstack");
memcpy(temp, *ptn, *totfoundstack * sizeof(KDTreeNearest));
if (*ptn)
diff --git a/source/blender/blenlib/intern/BLI_mempool.c b/source/blender/blenlib/intern/BLI_mempool.c
index 217a4b9d266..bb326a23d59 100644
--- a/source/blender/blenlib/intern/BLI_mempool.c
+++ b/source/blender/blenlib/intern/BLI_mempool.c
@@ -334,27 +334,56 @@ void *BLI_mempool_findelem(BLI_mempool *pool, int index)
}
/**
+ * Fill in \a data with pointers to each element of the mempool,
+ * to create lookup table.
+ *
* \param data array of pointers at least the size of 'pool->totused'
*/
-void BLI_mempool_as_array(BLI_mempool *pool, void **data)
+void BLI_mempool_as_table(BLI_mempool *pool, void **data)
{
BLI_mempool_iter iter;
void *elem;
void **p = data;
BLI_assert(pool->flag & BLI_MEMPOOL_ALLOW_ITER);
BLI_mempool_iternew(pool, &iter);
- for (elem = BLI_mempool_iterstep(&iter); elem; elem = BLI_mempool_iterstep(&iter)) {
+ while ((elem = BLI_mempool_iterstep(&iter))) {
*p++ = elem;
}
BLI_assert((p - data) == pool->totused);
}
/**
- * Allocate an array from the mempool.
+ * A version of #BLI_mempool_as_table that allocates and returns the data.
+ */
+void **BLI_mempool_as_tableN(BLI_mempool *pool, const char *allocstr)
+{
+ void **data = MEM_mallocN((size_t)pool->totused * sizeof(void *), allocstr);
+ BLI_mempool_as_table(pool, data);
+ return data;
+}
+
+/**
+ * Fill in \a data with the contents of the mempool.
+ */
+void BLI_mempool_as_array(BLI_mempool *pool, void *data)
+{
+ BLI_mempool_iter iter;
+ char *elem, *p = data;
+ BLI_assert(pool->flag & BLI_MEMPOOL_ALLOW_ITER);
+ BLI_mempool_iternew(pool, &iter);
+ while ((elem = BLI_mempool_iterstep(&iter))) {
+ memcpy(p, elem, (size_t)pool->esize);
+ p += pool->esize;
+ }
+ BLI_assert((p - (char *)data) == pool->totused * pool->esize);
+}
+
+/**
+ * A version of #BLI_mempool_as_array that allocates and returns the data.
*/
void *BLI_mempool_as_arrayN(BLI_mempool *pool, const char *allocstr)
{
- void *data = MEM_mallocN((size_t)(BLI_mempool_count(pool) * pool->esize), allocstr);
+ char *data = MEM_mallocN((size_t)(pool->totused * pool->esize), allocstr);
BLI_mempool_as_array(pool, data);
return data;
}
diff --git a/source/blender/blenlib/intern/buffer.c b/source/blender/blenlib/intern/buffer.c
index aac3a3bc3f3..36fb04a7bb7 100644
--- a/source/blender/blenlib/intern/buffer.c
+++ b/source/blender/blenlib/intern/buffer.c
@@ -34,9 +34,12 @@ static void *buffer_alloc(BLI_Buffer *buffer, int len)
static void *buffer_realloc(BLI_Buffer *buffer, int len)
{
- return ((buffer->flag & BLI_BUFFER_USE_CALLOC) ?
- MEM_recallocN : MEM_reallocN)
- (buffer->data, (buffer->elem_size * len));
+ if (buffer->flag & BLI_BUFFER_USE_CALLOC) {
+ return MEM_recallocN(buffer->data, buffer->elem_size * len);
+ }
+ else {
+ return MEM_reallocN(buffer->data, buffer->elem_size * len);
+ }
}
void BLI_buffer_resize(BLI_Buffer *buffer, int new_count)
diff --git a/source/blender/blenlib/intern/fileops.c b/source/blender/blenlib/intern/fileops.c
index 26b9e08c7f6..4809ba59aaf 100644
--- a/source/blender/blenlib/intern/fileops.c
+++ b/source/blender/blenlib/intern/fileops.c
@@ -445,7 +445,7 @@ static void join_dirfile_alloc(char **dst, size_t *alloc_len, const char *dir, c
size_t len = strlen(dir) + strlen(file) + 1;
if (*dst == NULL)
- *dst = MEM_callocN(len + 1, "join_dirfile_alloc path");
+ *dst = MEM_mallocN(len + 1, "join_dirfile_alloc path");
else if (*alloc_len < len)
*dst = MEM_reallocN(*dst, len + 1);
@@ -911,18 +911,15 @@ void BLI_dir_create_recursive(const char *dirname)
char static_buf[MAXPATHLEN];
#endif
char *tmp;
- int needs_free;
if (BLI_exists(dirname)) return;
#ifdef MAXPATHLEN
size = MAXPATHLEN;
tmp = static_buf;
- needs_free = 0;
#else
size = strlen(dirname) + 1;
- tmp = MEM_callocN(size, "BLI_dir_create_recursive tmp");
- needs_free = 1;
+ tmp = MEM_callocN(size, __func__);
#endif
BLI_strncpy(tmp, dirname, size);
@@ -934,8 +931,9 @@ void BLI_dir_create_recursive(const char *dirname)
BLI_dir_create_recursive(tmp);
}
- if (needs_free)
- MEM_freeN(tmp);
+#ifndef MAXPATHLEN
+ MEM_freeN(tmp);
+#endif
mkdir(dirname, 0777);
}
diff --git a/source/blender/blenlib/intern/math_geom.c b/source/blender/blenlib/intern/math_geom.c
index 0e7ff521ce8..9b8fd0ad85b 100644
--- a/source/blender/blenlib/intern/math_geom.c
+++ b/source/blender/blenlib/intern/math_geom.c
@@ -695,60 +695,6 @@ int isect_line_sphere_v2(const float l1[2], const float l2[2],
}
}
-/**
- * \return
- * -1: collinear
- * 1: intersection
- */
-static short IsectLLPt2Df(const float x0, const float y0, const float x1, const float y1,
- const float x2, const float y2, const float x3, const float y3, float *xi, float *yi)
-
-{
- /*
- * this function computes the intersection of the sent lines
- * and returns the intersection point, note that the function assumes
- * the lines intersect. the function can handle vertical as well
- * as horizontal lines. note the function isn't very clever, it simply
- * applies the math, but we don't need speed since this is a
- * pre-processing step
- */
- float c1, c2; /* constants of linear equations */
- float det_inv; /* the inverse of the determinant of the coefficient */
- float m1, m2; /* the slopes of each line */
- /*
- * compute slopes, note the cludge for infinity, however, this will
- * be close enough
- */
- if (fabsf(x1 - x0) > 0.000001f)
- m1 = (y1 - y0) / (x1 - x0);
- else
- return -1; /*m1 = (float)1e+10;*/ /* close enough to infinity */
-
- if (fabsf(x3 - x2) > 0.000001f)
- m2 = (y3 - y2) / (x3 - x2);
- else
- return -1; /*m2 = (float)1e+10;*/ /* close enough to infinity */
-
- if (fabsf(m1 - m2) < 0.000001f)
- return -1; /* parallel lines */
-
- /* compute constants */
-
- c1 = (y0 - m1 * x0);
- c2 = (y2 - m2 * x2);
-
- /* compute the inverse of the determinate */
-
- det_inv = 1.0f / (-m1 + m2);
-
- /* use Kramers rule to compute xi and yi */
-
- *xi = ((-c2 + c1) * det_inv);
- *yi = ((m2 * c1 - m1 * c2) * det_inv);
-
- return 1;
-}
-
/* point in polygon (keep float and int versions in sync) */
bool isect_point_poly_v2(const float pt[2], const float verts[][2], const int nr)
{
@@ -1718,193 +1664,6 @@ void limit_dist_v3(float v1[3], float v2[3], const float dist)
}
}
-/* Similar to LineIntersectsTriangleUV, except it operates on a quad and in 2d, assumes point is in quad */
-void isect_point_quad_uv_v2(const float v0[2], const float v1[2], const float v2[2], const float v3[2],
- const float pt[2], float r_uv[2])
-{
- float x0, y0, x1, y1, wtot, v2d[2], w1, w2;
-
- /* used for parallel lines */
- float pt3d[3], l1[3], l2[3], pt_on_line[3];
-
- /* compute 2 edges of the quad intersection point */
- if (IsectLLPt2Df(v0[0], v0[1], v1[0], v1[1], v2[0], v2[1], v3[0], v3[1], &x0, &y0) == 1) {
- /* the intersection point between the quad-edge intersection and the point in the quad we want the uv's for */
- /* should never be paralle !! */
- /*printf("\tnot parallel 1\n");*/
- IsectLLPt2Df(pt[0], pt[1], x0, y0, v0[0], v0[1], v3[0], v3[1], &x1, &y1);
-
- /* Get the weights from the new intersection point, to each edge */
- v2d[0] = x1 - v0[0];
- v2d[1] = y1 - v0[1];
- w1 = len_v2(v2d);
-
- v2d[0] = x1 - v3[0]; /* some but for the other vert */
- v2d[1] = y1 - v3[1];
- w2 = len_v2(v2d);
- wtot = w1 + w2;
- /*w1 = w1/wtot;*/
- /*w2 = w2/wtot;*/
- r_uv[0] = w1 / wtot;
- }
- else {
- /* lines are parallel, lambda_cp_line_ex is 3d grrr */
- /*printf("\tparallel1\n");*/
- pt3d[0] = pt[0];
- pt3d[1] = pt[1];
- pt3d[2] = l1[2] = l2[2] = 0.0f;
-
- l1[0] = v0[0];
- l1[1] = v0[1];
- l2[0] = v1[0];
- l2[1] = v1[1];
- closest_to_line_v3(pt_on_line, pt3d, l1, l2);
- v2d[0] = pt[0] - pt_on_line[0]; /* same, for the other vert */
- v2d[1] = pt[1] - pt_on_line[1];
- w1 = len_v2(v2d);
-
- l1[0] = v2[0];
- l1[1] = v2[1];
- l2[0] = v3[0];
- l2[1] = v3[1];
- closest_to_line_v3(pt_on_line, pt3d, l1, l2);
- v2d[0] = pt[0] - pt_on_line[0]; /* same, for the other vert */
- v2d[1] = pt[1] - pt_on_line[1];
- w2 = len_v2(v2d);
- wtot = w1 + w2;
- r_uv[0] = w1 / wtot;
- }
-
- /* Same as above to calc the uv[1] value, alternate calculation */
-
- if (IsectLLPt2Df(v0[0], v0[1], v3[0], v3[1], v1[0], v1[1], v2[0], v2[1], &x0, &y0) == 1) { /* was v0,v1 v2,v3 now v0,v3 v1,v2*/
- /* never paralle if above was not */
- /*printf("\tnot parallel2\n");*/
- IsectLLPt2Df(pt[0], pt[1], x0, y0, v0[0], v0[1], v1[0], v1[1], &x1, &y1); /* was v0,v3 now v0,v1*/
-
- v2d[0] = x1 - v0[0];
- v2d[1] = y1 - v0[1];
- w1 = len_v2(v2d);
-
- v2d[0] = x1 - v1[0];
- v2d[1] = y1 - v1[1];
- w2 = len_v2(v2d);
- wtot = w1 + w2;
- r_uv[1] = w1 / wtot;
- }
- else {
- /* lines are parallel, lambda_cp_line_ex is 3d grrr */
- /*printf("\tparallel2\n");*/
- pt3d[0] = pt[0];
- pt3d[1] = pt[1];
- pt3d[2] = l1[2] = l2[2] = 0.0f;
-
-
- l1[0] = v0[0];
- l1[1] = v0[1];
- l2[0] = v3[0];
- l2[1] = v3[1];
- closest_to_line_v3(pt_on_line, pt3d, l1, l2);
- v2d[0] = pt[0] - pt_on_line[0]; /* some but for the other vert */
- v2d[1] = pt[1] - pt_on_line[1];
- w1 = len_v2(v2d);
-
- l1[0] = v1[0];
- l1[1] = v1[1];
- l2[0] = v2[0];
- l2[1] = v2[1];
- closest_to_line_v3(pt_on_line, pt3d, l1, l2);
- v2d[0] = pt[0] - pt_on_line[0]; /* some but for the other vert */
- v2d[1] = pt[1] - pt_on_line[1];
- w2 = len_v2(v2d);
- wtot = w1 + w2;
- r_uv[1] = w1 / wtot;
- }
- /* may need to flip UV's here */
-}
-
-/* same as above but does tri's and quads, tri's are a bit of a hack */
-void isect_point_face_uv_v2(const int isquad,
- const float v0[2], const float v1[2], const float v2[2], const float v3[2],
- const float pt[2], float r_uv[2])
-{
- if (isquad) {
- isect_point_quad_uv_v2(v0, v1, v2, v3, pt, r_uv);
- }
- else {
- /* not for quads, use for our abuse of LineIntersectsTriangleUV */
- float p1_3d[3], p2_3d[3], v0_3d[3], v1_3d[3], v2_3d[3], lambda;
-
- p1_3d[0] = p2_3d[0] = r_uv[0];
- p1_3d[1] = p2_3d[1] = r_uv[1];
- p1_3d[2] = 1.0f;
- p2_3d[2] = -1.0f;
- v0_3d[2] = v1_3d[2] = v2_3d[2] = 0.0;
-
- /* generate a new fuv, (this is possibly a non optimal solution,
- * since we only need 2d calculation but use 3d func's)
- *
- * this method makes an imaginary triangle in 2d space using the UV's from the derived mesh face
- * Then find new uv coords using the fuv and this face with LineIntersectsTriangleUV.
- * This means the new values will be correct in relation to the derived meshes face.
- */
- copy_v2_v2(v0_3d, v0);
- copy_v2_v2(v1_3d, v1);
- copy_v2_v2(v2_3d, v2);
-
- /* Doing this in 3D is not nice */
- isect_line_tri_v3(p1_3d, p2_3d, v0_3d, v1_3d, v2_3d, &lambda, r_uv);
- }
-}
-
-#if 0 /* XXX this version used to be used in isect_point_tri_v2_int() and was called IsPointInTri2D */
-
-int isect_point_tri_v2(float pt[2], float v1[2], float v2[2], float v3[2])
-{
- float inp1, inp2, inp3;
-
- inp1 = (v2[0] - v1[0]) * (v1[1] - pt[1]) + (v1[1] - v2[1]) * (v1[0] - pt[0]);
- inp2 = (v3[0] - v2[0]) * (v2[1] - pt[1]) + (v2[1] - v3[1]) * (v2[0] - pt[0]);
- inp3 = (v1[0] - v3[0]) * (v3[1] - pt[1]) + (v3[1] - v1[1]) * (v3[0] - pt[0]);
-
- if (inp1 <= 0.0f && inp2 <= 0.0f && inp3 <= 0.0f) return 1;
- if (inp1 >= 0.0f && inp2 >= 0.0f && inp3 >= 0.0f) return 1;
-
- return 0;
-}
-#endif
-
-#if 0
-
-int isect_point_tri_v2(float v0[2], float v1[2], float v2[2], float pt[2])
-{
- /* not for quads, use for our abuse of LineIntersectsTriangleUV */
- float p1_3d[3], p2_3d[3], v0_3d[3], v1_3d[3], v2_3d[3];
- /* not used */
- float lambda, uv[3];
-
- p1_3d[0] = p2_3d[0] = uv[0] = pt[0];
- p1_3d[1] = p2_3d[1] = uv[1] = uv[2] = pt[1];
- p1_3d[2] = 1.0f;
- p2_3d[2] = -1.0f;
- v0_3d[2] = v1_3d[2] = v2_3d[2] = 0.0;
-
- /* generate a new fuv, (this is possibly a non optimal solution,
- * since we only need 2d calculation but use 3d func's)
- *
- * this method makes an imaginary triangle in 2d space using the UV's from the derived mesh face
- * Then find new uv coords using the fuv and this face with LineIntersectsTriangleUV.
- * This means the new values will be correct in relation to the derived meshes face.
- */
- copy_v2_v2(v0_3d, v0);
- copy_v2_v2(v1_3d, v1);
- copy_v2_v2(v2_3d, v2);
-
- /* Doing this in 3D is not nice */
- return isect_line_tri_v3(p1_3d, p2_3d, v0_3d, v1_3d, v2_3d, &lambda, uv);
-}
-#endif
-
/*
* x1,y2
* | \
@@ -2326,7 +2085,7 @@ int barycentric_inside_triangle_v2(const float w[3])
}
/* returns 0 for degenerated triangles */
-int barycentric_coords_v2(const float v1[2], const float v2[2], const float v3[2], const float co[2], float w[3])
+bool barycentric_coords_v2(const float v1[2], const float v2[2], const float v3[2], const float co[2], float w[3])
{
float x = co[0], y = co[1];
float x1 = v1[0], y1 = v1[1];
@@ -2339,10 +2098,10 @@ int barycentric_coords_v2(const float v1[2], const float v2[2], const float v3[2
w[1] = ((y3 - y1) * (x - x3) + (x1 - x3) * (y - y3)) / det;
w[2] = 1.0f - w[0] - w[1];
- return 1;
+ return true;
}
- return 0;
+ return false;
}
/* used by projection painting
@@ -3384,9 +3143,9 @@ static void vec_add_dir(float r[3], const float v1[3], const float v2[3], const
r[2] = v1[2] + fac * (v2[2] - v1[2]);
}
-int form_factor_visible_quad(const float p[3], const float n[3],
- const float v0[3], const float v1[3], const float v2[3],
- float q0[3], float q1[3], float q2[3], float q3[3])
+bool form_factor_visible_quad(const float p[3], const float n[3],
+ const float v0[3], const float v1[3], const float v2[3],
+ float q0[3], float q1[3], float q2[3], float q3[3])
{
static const float epsilon = 1e-6f;
float c, sd[3];
@@ -3507,11 +3266,11 @@ int form_factor_visible_quad(const float p[3], const float n[3],
}
else if (sd[2] < 0) {
/* --- */
- return 0;
+ return false;
}
else {
/* --0 */
- return 0;
+ return false;
}
}
else {
@@ -3524,11 +3283,11 @@ int form_factor_visible_quad(const float p[3], const float n[3],
}
else if (sd[2] < 0) {
/* -0- */
- return 0;
+ return false;
}
else {
/* -00 */
- return 0;
+ return false;
}
}
}
@@ -3566,11 +3325,11 @@ int form_factor_visible_quad(const float p[3], const float n[3],
}
else if (sd[2] < 0) {
/* 0-- */
- return 0;
+ return false;
}
else {
/* 0-0 */
- return 0;
+ return false;
}
}
else {
@@ -3583,16 +3342,16 @@ int form_factor_visible_quad(const float p[3], const float n[3],
}
else if (sd[2] < 0) {
/* 00- */
- return 0;
+ return false;
}
else {
/* 000 */
- return 0;
+ return false;
}
}
}
- return 1;
+ return true;
}
/* altivec optimization, this works, but is unused */
diff --git a/source/blender/blenlib/intern/math_matrix.c b/source/blender/blenlib/intern/math_matrix.c
index 312805e23f6..611b3298c38 100644
--- a/source/blender/blenlib/intern/math_matrix.c
+++ b/source/blender/blenlib/intern/math_matrix.c
@@ -433,6 +433,8 @@ void mul_m4_v4d(float mat[4][4], double r[4])
void mul_v3_m3v3(float r[3], float M[3][3], const float a[3])
{
+ BLI_assert(r != a);
+
r[0] = M[0][0] * a[0] + M[1][0] * a[1] + M[2][0] * a[2];
r[1] = M[0][1] * a[0] + M[1][1] * a[1] + M[2][1] * a[2];
r[2] = M[0][2] * a[0] + M[1][2] * a[1] + M[2][2] * a[2];
@@ -440,6 +442,8 @@ void mul_v3_m3v3(float r[3], float M[3][3], const float a[3])
void mul_v2_m3v3(float r[2], float M[3][3], const float a[3])
{
+ BLI_assert(r != a);
+
r[0] = M[0][0] * a[0] + M[1][0] * a[1] + M[2][0] * a[2];
r[1] = M[0][1] * a[0] + M[1][1] * a[1] + M[2][1] * a[2];
}
@@ -930,7 +934,7 @@ void orthogonalize_m4(float mat[4][4], int axis)
mul_v3_fl(mat[2], size[2]);
}
-int is_orthogonal_m3(float m[3][3])
+bool is_orthogonal_m3(float m[3][3])
{
int i, j;
@@ -944,7 +948,7 @@ int is_orthogonal_m3(float m[3][3])
return 1;
}
-int is_orthogonal_m4(float m[4][4])
+bool is_orthogonal_m4(float m[4][4])
{
int i, j;
@@ -959,7 +963,7 @@ int is_orthogonal_m4(float m[4][4])
return 1;
}
-int is_orthonormal_m3(float m[3][3])
+bool is_orthonormal_m3(float m[3][3])
{
if (is_orthogonal_m3(m)) {
int i;
@@ -974,7 +978,7 @@ int is_orthonormal_m3(float m[3][3])
return 0;
}
-int is_orthonormal_m4(float m[4][4])
+bool is_orthonormal_m4(float m[4][4])
{
if (is_orthogonal_m4(m)) {
int i;
@@ -989,7 +993,7 @@ int is_orthonormal_m4(float m[4][4])
return 0;
}
-int is_uniform_scaled_m3(float m[3][3])
+bool is_uniform_scaled_m3(float m[3][3])
{
const float eps = 1e-7;
float t[3][3];
@@ -1374,6 +1378,28 @@ void rotate_m2(float mat[2][2], const float angle)
mat[1][0] = -mat[0][1];
}
+/**
+ * Scale or rotate around a pivot point,
+ * a convenience function to avoid having to do inline.
+ *
+ * Since its common to make a scale/rotation matrix that pivots around an arbitrary point.
+ *
+ * Typical use case is to make 3x3 matrix, copy to 4x4, then pass to this function.
+ */
+void transform_pivot_set_m4(float mat[4][4], const float pivot[3])
+{
+ float tmat[4][4];
+
+ unit_m4(tmat);
+
+ copy_v3_v3(tmat[3], pivot);
+ mul_m4_m4m4(mat, tmat, mat);
+
+ /* invert the matrix */
+ negate_v3(tmat[3]);
+ mul_m4_m4m4(mat, mat, tmat);
+}
+
void blend_m3_m3m3(float out[3][3], float dst[3][3], float src[3][3], const float srcweight)
{
float srot[3][3], drot[3][3];
@@ -1419,20 +1445,34 @@ void blend_m4_m4m4(float out[4][4], float dst[4][4], float src[4][4], const floa
loc_quat_size_to_mat4(out, floc, fquat, fsize);
}
-int is_negative_m3(float mat[3][3])
+bool is_negative_m3(float mat[3][3])
{
float vec[3];
cross_v3_v3v3(vec, mat[0], mat[1]);
return (dot_v3v3(vec, mat[2]) < 0.0f);
}
-int is_negative_m4(float mat[4][4])
+bool is_negative_m4(float mat[4][4])
{
float vec[3];
cross_v3_v3v3(vec, mat[0], mat[1]);
return (dot_v3v3(vec, mat[2]) < 0.0f);
}
+bool is_zero_m3(float mat[3][3])
+{
+ return (is_zero_v3(mat[0]) &&
+ is_zero_v3(mat[1]) &&
+ is_zero_v3(mat[2]));
+}
+bool is_zero_m4(float mat[4][4])
+{
+ return (is_zero_v4(mat[0]) &&
+ is_zero_v4(mat[1]) &&
+ is_zero_v4(mat[2]) &&
+ is_zero_v4(mat[3]));
+}
+
/* make a 4x4 matrix out of 3 transform components */
/* matrices are made in the order: scale * rot * loc */
/* TODO: need to have a version that allows for rotation order... */
diff --git a/source/blender/blenlib/intern/math_vector_inline.c b/source/blender/blenlib/intern/math_vector_inline.c
index d77b1ecf017..8e5040d983b 100644
--- a/source/blender/blenlib/intern/math_vector_inline.c
+++ b/source/blender/blenlib/intern/math_vector_inline.c
@@ -418,6 +418,21 @@ MINLINE float mul_project_m4_v3_zfac(float mat[4][4], const float co[3])
(mat[2][3] * co[2]) + mat[3][3];
}
+/**
+ * Has the effect of mul_m3_v3(), on a single axis.
+ */
+MINLINE float dot_m3_v3_row_x(float M[3][3], const float a[3])
+{
+ return M[0][0] * a[0] + M[1][0] * a[1] + M[2][0] * a[2];
+}
+MINLINE float dot_m3_v3_row_y(float M[3][3], const float a[3])
+{
+ return M[0][1] * a[0] + M[1][1] * a[1] + M[2][1] * a[2];
+}
+MINLINE float dot_m3_v3_row_z(float M[3][3], const float a[3])
+{
+ return M[0][2] * a[0] + M[1][2] * a[1] + M[2][2] * a[2];
+}
MINLINE void madd_v2_v2fl(float r[2], const float a[2], float f)
{
diff --git a/source/blender/blenlib/intern/path_util.c b/source/blender/blenlib/intern/path_util.c
index c5205ed5d18..2c06a812c8a 100644
--- a/source/blender/blenlib/intern/path_util.c
+++ b/source/blender/blenlib/intern/path_util.c
@@ -695,8 +695,10 @@ bool BLI_path_frame(char *path, int frame, int digits)
if (stringframe_chars(path, &ch_sta, &ch_end)) { /* warning, ch_end is the last # +1 */
char tmp[FILE_MAX];
- sprintf(tmp, "%.*s%.*d%s", ch_sta, path, ch_end - ch_sta, frame, path + ch_end);
- strcpy(path, tmp);
+ BLI_snprintf(tmp, sizeof(tmp),
+ "%.*s%.*d%s",
+ ch_sta, path, ch_end - ch_sta, frame, path + ch_end);
+ BLI_strncpy(path, tmp, FILE_MAX);
return true;
}
return false;
@@ -1689,6 +1691,26 @@ void BLI_split_file_part(const char *string, char *file, const size_t filelen)
}
/**
+ * Append a filename to a dir, ensuring slash separates.
+ */
+void BLI_path_append(char *dst, const size_t maxlen, const char *file)
+{
+ size_t dirlen = BLI_strnlen(dst, maxlen);
+
+ /* inline BLI_add_slash */
+ if ((dirlen > 0) && (dst[dirlen - 1] != SEP)) {
+ dst[dirlen++] = SEP;
+ dst[dirlen] = '\0';
+ }
+
+ if (dirlen >= maxlen) {
+ return; /* fills the path */
+ }
+
+ BLI_strncpy(dst + dirlen, file, maxlen - dirlen);
+}
+
+/**
* Simple appending of filename to dir, does not check for valid path!
* Puts result into *dst, which may be same area as *dir.
*/
@@ -1696,15 +1718,16 @@ void BLI_join_dirfile(char *dst, const size_t maxlen, const char *dir, const cha
{
size_t dirlen = BLI_strnlen(dir, maxlen);
- if (dst != dir) {
- if (dirlen == maxlen) {
- memcpy(dst, dir, dirlen);
- dst[dirlen - 1] = '\0';
- return; /* dir fills the path */
- }
- else {
- memcpy(dst, dir, dirlen + 1);
- }
+ /* args can't match */
+ BLI_assert(!ELEM(dst, dir, file));
+
+ if (dirlen == maxlen) {
+ memcpy(dst, dir, dirlen);
+ dst[dirlen - 1] = '\0';
+ return; /* dir fills the path */
+ }
+ else {
+ memcpy(dst, dir, dirlen + 1);
}
if (dirlen + 1 >= maxlen) {
@@ -1721,10 +1744,6 @@ void BLI_join_dirfile(char *dst, const size_t maxlen, const char *dir, const cha
return; /* fills the path */
}
- if (file == NULL) {
- return;
- }
-
BLI_strncpy(dst + dirlen, file, maxlen - dirlen);
}
@@ -1840,7 +1859,7 @@ int BLI_rebase_path(char *abs, size_t abs_len,
/* 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);
+ BLI_path_append(dest_path, sizeof(dest_path), base);
/* keeping original item basename */
}
@@ -2061,7 +2080,7 @@ static void bli_where_am_i(char *fullname, const size_t maxlen, const char *name
else {
strncpy(filename, path, sizeof(filename));
}
- BLI_join_dirfile(fullname, maxlen, fullname, name);
+ BLI_path_append(fullname, maxlen, name);
if (add_win32_extension(filename)) {
BLI_strncpy(fullname, filename, maxlen);
break;
diff --git a/source/blender/blenlib/intern/scanfill.c b/source/blender/blenlib/intern/scanfill.c
index 873ce302b9c..c7163874dca 100644
--- a/source/blender/blenlib/intern/scanfill.c
+++ b/source/blender/blenlib/intern/scanfill.c
@@ -379,10 +379,10 @@ static ScanFillVertLink *addedgetoscanlist(ScanFillContext *sf_ctx, ScanFillEdge
sc = (ScanFillVertLink *)bsearch(&scsearch, sf_ctx->_scdata, len,
sizeof(ScanFillVertLink), vergscdata);
- if (sc == 0) printf("Error in search edge: %p\n", (void *)eed);
+ if (sc == NULL) printf("Error in search edge: %p\n", (void *)eed);
else if (addedgetoscanvert(sc, eed) == 0) return sc;
- return 0;
+ return NULL;
}
static short boundinsideEV(ScanFillEdge *eed, ScanFillVert *eve)
@@ -669,7 +669,7 @@ static int scanfill(ScanFillContext *sf_ctx, PolyFill *pf, const int flag)
a = verts;
break;
}
- if (ed2 == 0) {
+ if (ed2 == NULL) {
sc->edge_first = sc->edge_last = NULL;
/* printf("just 1 edge to vert\n"); */
BLI_addtail(&sf_ctx->filledgebase, ed1);
@@ -1051,7 +1051,7 @@ int BLI_scanfill_calc_ex(ScanFillContext *sf_ctx, const int flag, const float no
eed = nexted;
}
}
- if (sf_ctx->filledgebase.first == 0) {
+ if (sf_ctx->filledgebase.first == NULL) {
/* printf("All edges removed\n"); */
return 0;
}
diff --git a/source/blender/blenlib/intern/storage.c b/source/blender/blenlib/intern/storage.c
index aeeae000fff..34c6e632131 100644
--- a/source/blender/blenlib/intern/storage.c
+++ b/source/blender/blenlib/intern/storage.c
@@ -388,17 +388,14 @@ static void bli_adddirstrings(struct BuildDirCtx *dir_ctx)
*/
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));
+ BLI_snprintf(file->size, sizeof(file->size), "%.2f GiB", ((double)st_size) / (1024 * 1024 * 1024));
}
else if (st_size > 1024 * 1024) {
- BLI_snprintf(file->size, sizeof(file->size), "%.1f MB", ((double)st_size) / (1024 * 1024));
+ BLI_snprintf(file->size, sizeof(file->size), "%.1f MiB", ((double)st_size) / (1024 * 1024));
}
else if (st_size > 1024) {
- BLI_snprintf(file->size, sizeof(file->size), "%d KB", (int)(st_size / 1024));
+ BLI_snprintf(file->size, sizeof(file->size), "%d KiB", (int)(st_size / 1024));
}
else {
BLI_snprintf(file->size, sizeof(file->size), "%d B", (int)st_size);
diff --git a/source/blender/blenlib/intern/string.c b/source/blender/blenlib/intern/string.c
index cb0d4ae307d..572b142d044 100644
--- a/source/blender/blenlib/intern/string.c
+++ b/source/blender/blenlib/intern/string.c
@@ -87,15 +87,18 @@ char *BLI_strdup(const char *str)
*/
char *BLI_strdupcat(const char *__restrict str1, const char *__restrict str2)
{
- size_t len;
- char *n;
-
- len = strlen(str1) + strlen(str2);
- n = MEM_mallocN(len + 1, "strdupcat");
- strcpy(n, str1);
- strcat(n, str2);
+ /* include the NULL terminator of str2 only */
+ const size_t str1_len = strlen(str1);
+ const size_t str2_len = strlen(str2) + 1;
+ char *str, *s;
- return n;
+ str = MEM_mallocN(str1_len + str2_len, "strdupcat");
+ s = str;
+
+ memcpy(s, str1, str1_len); s += str1_len;
+ memcpy(s, str2, str2_len);
+
+ return str;
}
/**
@@ -302,34 +305,30 @@ char *BLI_str_quoted_substrN(const char *__restrict str, const char *__restrict
}
/**
+ * string with all instances of substr_old replaced with substr_new,
* 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
+ * \param str The string to replace occurrences of substr_old in
+ * \param substr_old The text in the string to find and replace
+ * \param substr_new 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)
+char *BLI_replacestrN(const char *__restrict str, const char *__restrict substr_old, const char *__restrict substr_new)
{
DynStr *ds = NULL;
- size_t lenOld = strlen(oldText);
- char *match;
-
- /* sanity checks */
- if ((str == NULL) || (str[0] == 0))
- return NULL;
- else if ((oldText == NULL) || (newText == NULL) || (oldText[0] == 0))
- return BLI_strdup(str);
-
+ size_t len_old = strlen(substr_old);
+ const char *match;
+
+ BLI_assert(substr_old[0] != '\0');
+
/* while we can still find a match for the old substring that we're searching for,
* keep dicing and replacing
*/
- while ( (match = strstr(str, oldText)) ) {
+ while ((match = strstr(str, substr_old))) {
/* the assembly buffer only gets created when we actually need to rebuild the string */
if (ds == NULL)
ds = BLI_dynstr_new();
@@ -338,39 +337,35 @@ char *BLI_replacestr(char *__restrict str, const char *__restrict oldText, const
* copy the text up to this position and advance the current position in the string
*/
if (str != match) {
- /* replace the token at the 'match' position with \0 so that the copied string will be ok,
- * add the segment of the string from str to match to the buffer, then restore the value at match
+ /* add the segment of the string from str to match to the buffer, then restore the value at match
*/
- match[0] = 0;
- BLI_dynstr_append(ds, str);
- match[0] = oldText[0];
+ BLI_dynstr_nappend(ds, str, (match - str));
/* now our current position should be set on the start of the match */
str = match;
}
/* add the replacement text to the accumulation buffer */
- BLI_dynstr_append(ds, newText);
+ BLI_dynstr_append(ds, substr_new);
/* advance the current position of the string up to the end of the replaced segment */
- str += lenOld;
+ str += len_old;
}
/* finish off and return a new string that has had all occurrences of */
if (ds) {
- char *newStr;
+ char *str_new;
/* add what's left of the string to the assembly buffer
- * - we've been adjusting str to point at the end of the replaced segments
+ * - we've been adjusting str to point at the end of the replaced segments
*/
- if (str != NULL)
- BLI_dynstr_append(ds, str);
+ BLI_dynstr_append(ds, str);
/* convert to new c-string (MEM_malloc'd), and free the buffer */
- newStr = BLI_dynstr_get_cstring(ds);
+ str_new = BLI_dynstr_get_cstring(ds);
BLI_dynstr_free(ds);
- return newStr;
+ return str_new;
}
else {
/* just create a new copy of the entire string - we avoid going through the assembly buffer
diff --git a/source/blender/blenlib/intern/string_utf8.c b/source/blender/blenlib/intern/string_utf8.c
index d435ed8f6e7..225b3c5538f 100644
--- a/source/blender/blenlib/intern/string_utf8.c
+++ b/source/blender/blenlib/intern/string_utf8.c
@@ -260,7 +260,7 @@ size_t BLI_wstrlen_utf8(const wchar_t *src)
return len;
}
-size_t BLI_strlen_utf8_ex(const char *strc, int *r_len_bytes)
+size_t BLI_strlen_utf8_ex(const char *strc, size_t *r_len_bytes)
{
size_t len;
const char *strc_orig = strc;
@@ -268,7 +268,7 @@ size_t BLI_strlen_utf8_ex(const char *strc, int *r_len_bytes)
for (len = 0; *strc; len++)
strc += BLI_str_utf8_size_safe(strc);
- *r_len_bytes = (strc - strc_orig);
+ *r_len_bytes = (size_t)(strc - strc_orig);
return len;
}
@@ -282,7 +282,7 @@ size_t BLI_strlen_utf8(const char *strc)
return len;
}
-size_t BLI_strnlen_utf8_ex(const char *strc, const size_t maxlen, int *r_len_bytes)
+size_t BLI_strnlen_utf8_ex(const char *strc, const size_t maxlen, size_t *r_len_bytes)
{
size_t len;
const char *strc_orig = strc;
@@ -292,7 +292,7 @@ size_t BLI_strnlen_utf8_ex(const char *strc, const size_t maxlen, int *r_len_byt
strc += BLI_str_utf8_size_safe(strc);
}
- *r_len_bytes = (strc - strc_orig);
+ *r_len_bytes = (size_t)(strc - strc_orig);
return len;
}
diff --git a/source/blender/blenlib/intern/voronoi.c b/source/blender/blenlib/intern/voronoi.c
index 7a545090090..3f6adff1eda 100644
--- a/source/blender/blenlib/intern/voronoi.c
+++ b/source/blender/blenlib/intern/voronoi.c
@@ -121,7 +121,7 @@ static VoronoiParabola *voronoiParabola_new(void)
parabola->is_leaf = FALSE;
parabola->event = NULL;
parabola->edge = NULL;
- parabola->parent = 0;
+ parabola->parent = NULL;
return parabola;
}
@@ -134,7 +134,7 @@ static VoronoiParabola *voronoiParabola_newSite(float site[2])
parabola->is_leaf = TRUE;
parabola->event = NULL;
parabola->edge = NULL;
- parabola->parent = 0;
+ parabola->parent = NULL;
return parabola;
}
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index 50273cb33f3..1f8bbfbec88 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -108,6 +108,7 @@
#include "BLI_math.h"
#include "BLI_edgehash.h"
#include "BLI_threads.h"
+#include "BLI_mempool.h"
#include "BLF_translation.h"
@@ -327,7 +328,7 @@ void blo_do_versions_oldnewmap_insert(OldNewMap *onm, void *oldaddr, void *newad
oldnewmap_insert(onm, oldaddr, newaddr, nr);
}
-static void *oldnewmap_lookup_and_inc(OldNewMap *onm, void *addr)
+static void *oldnewmap_lookup_and_inc(OldNewMap *onm, void *addr, bool increase_users)
{
int i;
@@ -337,7 +338,8 @@ static void *oldnewmap_lookup_and_inc(OldNewMap *onm, void *addr)
OldNew *entry = &onm->entries[++onm->lasthit];
if (entry->old == addr) {
- entry->nr++;
+ if (increase_users)
+ entry->nr++;
return entry->newp;
}
}
@@ -348,7 +350,8 @@ static void *oldnewmap_lookup_and_inc(OldNewMap *onm, void *addr)
if (entry->old == addr) {
onm->lasthit = i;
- entry->nr++;
+ if (increase_users)
+ entry->nr++;
return entry->newp;
}
}
@@ -1200,34 +1203,39 @@ int BLO_is_a_library(const char *path, char *dir, char *group)
static void *newdataadr(FileData *fd, void *adr) /* only direct databocks */
{
- return oldnewmap_lookup_and_inc(fd->datamap, adr);
+ return oldnewmap_lookup_and_inc(fd->datamap, adr, true);
+}
+
+static void *newdataadr_no_us(FileData *fd, void *adr) /* only direct databocks */
+{
+ return oldnewmap_lookup_and_inc(fd->datamap, adr, false);
}
static void *newglobadr(FileData *fd, void *adr) /* direct datablocks with global linking */
{
- return oldnewmap_lookup_and_inc(fd->globmap, adr);
+ return oldnewmap_lookup_and_inc(fd->globmap, adr, true);
}
static void *newimaadr(FileData *fd, void *adr) /* used to restore image data after undo */
{
if (fd->imamap && adr)
- return oldnewmap_lookup_and_inc(fd->imamap, adr);
+ return oldnewmap_lookup_and_inc(fd->imamap, adr, true);
return NULL;
}
static void *newmclipadr(FileData *fd, void *adr) /* used to restore movie clip data after undo */
{
if (fd->movieclipmap && adr)
- return oldnewmap_lookup_and_inc(fd->movieclipmap, adr);
+ return oldnewmap_lookup_and_inc(fd->movieclipmap, adr, true);
return NULL;
}
static void *newpackedadr(FileData *fd, void *adr) /* used to restore packed data after undo */
{
if (fd->packedmap && adr)
- return oldnewmap_lookup_and_inc(fd->packedmap, adr);
+ return oldnewmap_lookup_and_inc(fd->packedmap, adr, true);
- return oldnewmap_lookup_and_inc(fd->datamap, adr);
+ return oldnewmap_lookup_and_inc(fd->datamap, adr, true);
}
@@ -5684,16 +5692,24 @@ static void lib_link_screen(FileData *fd, Main *main)
}
else if (sl->spacetype == SPACE_OUTLINER) {
SpaceOops *so= (SpaceOops *)sl;
- TreeStoreElem *tselem;
- int a;
-
so->search_tse.id = newlibadr(fd, NULL, so->search_tse.id);
if (so->treestore) {
- tselem = so->treestore->data;
- for (a=0; a < so->treestore->usedelem; a++, tselem++) {
+ TreeStoreElem *tselem;
+ BLI_mempool_iter iter;
+
+ BLI_mempool_iternew(so->treestore, &iter);
+ while ((tselem = BLI_mempool_iterstep(&iter))) {
tselem->id = newlibadr(fd, NULL, tselem->id);
}
+ if (so->treehash) {
+ /* update hash table, because it depends on ids too */
+ BLI_ghash_clear(so->treehash, NULL, NULL);
+ BLI_mempool_iternew(so->treestore, &iter);
+ while ((tselem = BLI_mempool_iterstep(&iter))) {
+ BLI_ghash_insert(so->treehash, tselem, tselem);
+ }
+ }
}
}
else if (sl->spacetype == SPACE_NODE) {
@@ -5803,21 +5819,23 @@ static void *restore_pointer_by_name(Main *mainp, ID *id, int user)
return NULL;
}
+static void lib_link_seq_clipboard_pt_restore(ID *id, Main *newmain)
+{
+ if (id) {
+ /* clipboard must ensure this */
+ BLI_assert(id->newid != NULL);
+ id->newid = restore_pointer_by_name(newmain, (ID *)id->newid, 1);
+ }
+}
static int lib_link_seq_clipboard_cb(Sequence *seq, void *arg_pt)
{
Main *newmain = (Main *)arg_pt;
-
- if (seq->sound) {
- seq->sound = restore_pointer_by_name(newmain, (ID *)seq->sound, 0);
- seq->sound->id.us++;
- }
-
- if (seq->scene)
- seq->scene = restore_pointer_by_name(newmain, (ID *)seq->scene, 1);
-
- if (seq->scene_camera)
- seq->scene_camera = restore_pointer_by_name(newmain, (ID *)seq->scene_camera, 1);
-
+
+ lib_link_seq_clipboard_pt_restore((ID *)seq->scene, newmain);
+ lib_link_seq_clipboard_pt_restore((ID *)seq->scene_camera, newmain);
+ lib_link_seq_clipboard_pt_restore((ID *)seq->clip, newmain);
+ lib_link_seq_clipboard_pt_restore((ID *)seq->mask, newmain);
+ lib_link_seq_clipboard_pt_restore((ID *)seq->sound, newmain);
return 1;
}
@@ -6014,16 +6032,25 @@ void blo_lib_link_screen_restore(Main *newmain, bScreen *curscreen, Scene *cursc
}
else if (sl->spacetype == SPACE_OUTLINER) {
SpaceOops *so= (SpaceOops *)sl;
- int a;
so->search_tse.id = restore_pointer_by_name(newmain, so->search_tse.id, 0);
if (so->treestore) {
- TreeStore *ts = so->treestore;
- TreeStoreElem *tselem = ts->data;
- for (a = 0; a < ts->usedelem; a++, tselem++) {
+ TreeStoreElem *tselem;
+ BLI_mempool_iter iter;
+
+ BLI_mempool_iternew(so->treestore, &iter);
+ while ((tselem = BLI_mempool_iterstep(&iter))) {
tselem->id = restore_pointer_by_name(newmain, tselem->id, 0);
}
+ if (so->treehash) {
+ /* update hash table, because it depends on ids too */
+ BLI_ghash_clear(so->treehash, NULL, NULL);
+ BLI_mempool_iternew(so->treestore, &iter);
+ while ((tselem = BLI_mempool_iterstep(&iter))) {
+ BLI_ghash_insert(so->treehash, tselem, tselem);
+ }
+ }
}
}
else if (sl->spacetype == SPACE_NODE) {
@@ -6111,20 +6138,26 @@ static void direct_link_region(FileData *fd, ARegion *ar, int spacetype)
ui_list->type = NULL;
}
- ar->regiondata = newdataadr(fd, ar->regiondata);
- if (ar->regiondata) {
- if (spacetype == SPACE_VIEW3D) {
- RegionView3D *rv3d = ar->regiondata;
-
- rv3d->localvd = newdataadr(fd, rv3d->localvd);
- rv3d->clipbb = newdataadr(fd, rv3d->clipbb);
-
- rv3d->depths = NULL;
- rv3d->gpuoffscreen = NULL;
- rv3d->ri = NULL;
- rv3d->render_engine = NULL;
- rv3d->sms = NULL;
- rv3d->smooth_timer = NULL;
+ if (spacetype == SPACE_EMPTY) {
+ /* unkown space type, don't leak regiondata */
+ ar->regiondata = NULL;
+ }
+ else {
+ ar->regiondata = newdataadr(fd, ar->regiondata);
+ if (ar->regiondata) {
+ if (spacetype == SPACE_VIEW3D) {
+ RegionView3D *rv3d = ar->regiondata;
+
+ rv3d->localvd = newdataadr(fd, rv3d->localvd);
+ rv3d->clipbb = newdataadr(fd, rv3d->clipbb);
+
+ rv3d->depths = NULL;
+ rv3d->gpuoffscreen = NULL;
+ rv3d->ri = NULL;
+ rv3d->render_engine = NULL;
+ rv3d->sms = NULL;
+ rv3d->smooth_timer = NULL;
+ }
}
}
@@ -6211,6 +6244,11 @@ static bool direct_link_screen(FileData *fd, bScreen *sc)
sa->handlers.first = sa->handlers.last = NULL;
sa->type = NULL; /* spacetype callbacks */
sa->region_active_win = -1;
+
+ /* if we do not have the spacetype registered (game player), we cannot
+ * free it, so don't allocate any new memory for such spacetypes. */
+ if (!BKE_spacetype_exists(sa->spacetype))
+ sa->spacetype = SPACE_EMPTY;
for (ar = sa->regionbase.first; ar; ar = ar->next)
direct_link_region(fd, ar, sa->spacetype);
@@ -6228,7 +6266,12 @@ static bool direct_link_screen(FileData *fd, bScreen *sc)
for (sl = sa->spacedata.first; sl; sl = sl->next) {
link_list(fd, &(sl->regionbase));
-
+
+ /* if we do not have the spacetype registered (game player), we cannot
+ * free it, so don't allocate any new memory for such spacetypes. */
+ if (!BKE_spacetype_exists(sl->spacetype))
+ sl->spacetype = SPACE_EMPTY;
+
for (ar = sl->regionbase.first; ar; ar = ar->next)
direct_link_region(fd, ar, sl->spacetype);
@@ -6281,13 +6324,28 @@ static bool direct_link_screen(FileData *fd, bScreen *sc)
else if (sl->spacetype == SPACE_OUTLINER) {
SpaceOops *soops = (SpaceOops *) sl;
- soops->treestore = newdataadr(fd, soops->treestore);
- if (soops->treestore) {
- soops->treestore->data = newdataadr(fd, soops->treestore->data);
+ /* use newdataadr_no_us and do not free old memory avoidign double
+ * frees and use of freed memory. this could happen because of a
+ * bug fixed in revision 58959 where the treestore memory address
+ * was not unique */
+ TreeStore *ts = newdataadr_no_us(fd, soops->treestore);
+ soops->treestore = NULL;
+ if (ts) {
+ TreeStoreElem *elems = newdataadr_no_us(fd, ts->data);
+
+ soops->treestore = BLI_mempool_create(sizeof(TreeStoreElem), ts->usedelem,
+ 512, BLI_MEMPOOL_ALLOW_ITER);
+ if (ts->usedelem && elems) {
+ int i;
+ for (i = 0; i < ts->usedelem; i++) {
+ TreeStoreElem *new_elem = BLI_mempool_alloc(soops->treestore);
+ *new_elem = elems[i];
+ }
+ }
/* we only saved what was used */
- soops->treestore->totelem = soops->treestore->usedelem;
soops->storeflag |= SO_TREESTORE_CLEANUP; // at first draw
}
+ soops->treehash = NULL;
soops->tree.first = soops->tree.last= NULL;
}
else if (sl->spacetype == SPACE_IMAGE) {
@@ -7244,7 +7302,7 @@ static void link_global(FileData *fd, BlendFileData *bfd)
}
}
-void convert_tface_mt(FileData *fd, Main *main)
+static void convert_tface_mt(FileData *fd, Main *main)
{
Main *gmain;
@@ -8140,12 +8198,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
for (ob = main->object.first; ob; ob = ob->id.next) {
bConstraint *con;
for (con = ob->constraints.first; con; con = con->next) {
- bConstraintTypeInfo *cti = BKE_constraint_get_typeinfo(con);
-
- if (!cti)
- continue;
-
- if (cti->type == CONSTRAINT_TYPE_OBJECTSOLVER) {
+ if (con->type == CONSTRAINT_TYPE_OBJECTSOLVER) {
bObjectSolverConstraint *data = (bObjectSolverConstraint *)con->data;
if (data->invmat[3][3] == 0.0f)
@@ -9487,7 +9540,29 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
}
}
+ if (!MAIN_VERSION_ATLEAST(main, 268, 1)) {
+ Brush *brush;
+ for (brush = main->brush.first; brush; brush = brush->id.next) {
+ brush->spacing = MAX2(1, brush->spacing);
+ }
+ }
+
+ if (!MAIN_VERSION_ATLEAST(main, 268, 2)) {
+ Brush *brush;
+ #define BRUSH_FIXED (1 << 6)
+ for (brush = main->brush.first; brush; brush = brush->id.next) {
+ brush->flag &= ~BRUSH_FIXED;
+ if(brush->cursor_overlay_alpha < 2)
+ brush->cursor_overlay_alpha = 33;
+ if(brush->texture_overlay_alpha < 2)
+ brush->texture_overlay_alpha = 33;
+ if(brush->mask_overlay_alpha <2)
+ brush->mask_overlay_alpha = 33;
+ }
+ #undef BRUSH_FIXED
+ }
+
{
bScreen *sc;
Object *ob;
@@ -10113,6 +10188,7 @@ static void expand_texture(FileData *fd, Main *mainvar, Tex *tex)
static void expand_brush(FileData *fd, Main *mainvar, Brush *brush)
{
expand_doit(fd, mainvar, brush->mtex.tex);
+ expand_doit(fd, mainvar, brush->mask_mtex.tex);
expand_doit(fd, mainvar, brush->clone.image);
}
diff --git a/source/blender/blenloader/intern/runtime.c b/source/blender/blenloader/intern/runtime.c
index d6fd2f92443..ca9f2faf998 100644
--- a/source/blender/blenloader/intern/runtime.c
+++ b/source/blender/blenloader/intern/runtime.c
@@ -72,7 +72,7 @@ int BLO_is_a_runtime(const char *path)
int datastart;
char buf[8];
- if (fd == -1)
+ if (fd < 0)
goto cleanup;
lseek(fd, -12, SEEK_END);
@@ -104,7 +104,7 @@ BlendFileData *BLO_read_runtime(const char *path, ReportList *reports)
fd = BLI_open(path, O_BINARY | O_RDONLY, 0);
- if (fd == -1) {
+ if (fd < 0) {
BKE_reportf(reports, RPT_ERROR, "Unable to open '%s': %s", path, strerror(errno));
goto cleanup;
}
diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c
index dd4361be1ff..4f0ccd3c626 100644
--- a/source/blender/blenloader/intern/writefile.c
+++ b/source/blender/blenloader/intern/writefile.c
@@ -144,12 +144,13 @@
#include "BLI_bitmap.h"
#include "BLI_blenlib.h"
#include "BLI_linklist.h"
-#include "BKE_bpath.h"
#include "BLI_math.h"
#include "BLI_utildefines.h"
+#include "BLI_mempool.h"
#include "BKE_action.h"
#include "BKE_blender.h"
+#include "BKE_bpath.h"
#include "BKE_curve.h"
#include "BKE_constraint.h"
#include "BKE_global.h" // for G
@@ -1660,8 +1661,8 @@ static void write_curves(WriteData *wd, ListBase *idbase)
if (cu->vfont) {
/* TODO, sort out 'cu->len', in editmode its character, object mode its bytes */
- int len_bytes;
- int len_chars = BLI_strlen_utf8_ex(cu->str, &len_bytes);
+ size_t len_bytes;
+ size_t len_chars = BLI_strlen_utf8_ex(cu->str, &len_bytes);
writedata(wd, DATA, len_bytes + 1, cu->str);
writestruct(wd, DATA, "CharInfo", len_chars + 1, cu->strinfo);
@@ -2393,12 +2394,55 @@ static void write_region(WriteData *wd, ARegion *ar, int spacetype)
}
}
+static void write_soops(WriteData *wd, SpaceOops *so, LinkNode **tmp_mem_list)
+{
+ BLI_mempool *ts = so->treestore;
+
+ if (ts) {
+ int elems = BLI_mempool_count(ts);
+ /* linearize mempool to array */
+ TreeStoreElem *data = elems ? BLI_mempool_as_arrayN(ts, "TreeStoreElem") : NULL;
+
+ if (data) {
+ TreeStore *ts_flat = MEM_callocN(sizeof(TreeStore), "TreeStore");
+
+ ts_flat->usedelem = elems;
+ ts_flat->totelem = elems;
+ ts_flat->data = data;
+
+ /* temporarily replace mempool-treestore by flat-treestore */
+ so->treestore = (BLI_mempool *)ts_flat;
+ writestruct(wd, DATA, "SpaceOops", 1, so);
+
+ writestruct(wd, DATA, "TreeStore", 1, ts_flat);
+ writestruct(wd, DATA, "TreeStoreElem", elems, data);
+
+ /* we do not free the pointers immediately, because if we have multiple
+ * outliners in a screen we might get the same address on the next
+ * malloc, which makes the address no longer unique and so invalid for
+ * lookups on file read, causing crashes or double frees */
+ BLI_linklist_append(tmp_mem_list, ts_flat);
+ BLI_linklist_append(tmp_mem_list, data);
+ }
+ else {
+ so->treestore = NULL;
+ writestruct(wd, DATA, "SpaceOops", 1, so);
+ }
+
+ /* restore old treestore */
+ so->treestore = ts;
+ } else {
+ writestruct(wd, DATA, "SpaceOops", 1, so);
+ }
+}
+
static void write_screens(WriteData *wd, ListBase *scrbase)
{
bScreen *sc;
ScrArea *sa;
ScrVert *sv;
ScrEdge *se;
+ LinkNode *tmp_mem_list = NULL;
sc= scrbase->first;
while (sc) {
@@ -2475,15 +2519,7 @@ static void write_screens(WriteData *wd, ListBase *scrbase)
}
else if (sl->spacetype==SPACE_OUTLINER) {
SpaceOops *so= (SpaceOops *)sl;
-
- writestruct(wd, DATA, "SpaceOops", 1, so);
-
- /* outliner */
- if (so->treestore) {
- writestruct(wd, DATA, "TreeStore", 1, so->treestore);
- if (so->treestore->data)
- writestruct(wd, DATA, "TreeStoreElem", so->treestore->usedelem, so->treestore->data);
- }
+ write_soops(wd, so, &tmp_mem_list);
}
else if (sl->spacetype==SPACE_IMAGE) {
SpaceImage *sima= (SpaceImage *)sl;
@@ -2548,6 +2584,8 @@ static void write_screens(WriteData *wd, ListBase *scrbase)
sc= sc->id.next;
}
+
+ BLI_linklist_freeN(tmp_mem_list);
/* flush helps the compression for undo-save */
mywrite(wd, MYWRITE_FLUSH, 0);
@@ -3378,7 +3416,7 @@ int BLO_write_file(Main *mainvar, const char *filepath, int write_flags, ReportL
BLI_snprintf(tempname, sizeof(tempname), "%s@", filepath);
file = BLI_open(tempname, O_BINARY+O_WRONLY+O_CREAT+O_TRUNC, 0666);
- if (file == -1) {
+ if (file < 0) {
BKE_reportf(reports, RPT_ERROR, "Cannot open file %s for writing: %s", tempname, strerror(errno));
return 0;
}
diff --git a/source/blender/bmesh/CMakeLists.txt b/source/blender/bmesh/CMakeLists.txt
index b3dd2f57523..228ebcb96c4 100644
--- a/source/blender/bmesh/CMakeLists.txt
+++ b/source/blender/bmesh/CMakeLists.txt
@@ -23,7 +23,7 @@
#
# ***** END GPL LICENSE BLOCK *****
-set(INC
+set(INC
.
../blenfont
../blenkernel
@@ -43,6 +43,7 @@ set(SRC
operators/bmo_bevel.c
operators/bmo_bridge.c
operators/bmo_connect.c
+ operators/bmo_connect_nonplanar.c
operators/bmo_connect_pair.c
operators/bmo_create.c
operators/bmo_dissolve.c
@@ -50,7 +51,8 @@ set(SRC
operators/bmo_edgenet.c
operators/bmo_extrude.c
operators/bmo_fill_edgeloop.c
- operators/bmo_fill_grid.c
+ operators/bmo_fill_grid.c
+ operators/bmo_fill_holes.c
operators/bmo_hull.c
operators/bmo_inset.c
operators/bmo_join_triangles.c
@@ -115,7 +117,6 @@ set(SRC
intern/bmesh_operator_api.h
intern/bmesh_error.h
- tools/BME_bevel.c
tools/bmesh_bevel.c
tools/bmesh_bevel.h
tools/bmesh_decimate_collapse.c
diff --git a/source/blender/bmesh/bmesh.h b/source/blender/bmesh/bmesh.h
index 022dfe452e7..d1d93bbfd1d 100644
--- a/source/blender/bmesh/bmesh.h
+++ b/source/blender/bmesh/bmesh.h
@@ -271,6 +271,7 @@ extern "C" {
#include "tools/bmesh_bevel.h"
#include "tools/bmesh_decimate.h"
+#include "tools/bmesh_edgesplit.h"
#include "tools/bmesh_path.h"
#include "tools/bmesh_triangulate.h"
diff --git a/source/blender/bmesh/intern/bmesh_construct.c b/source/blender/bmesh/intern/bmesh_construct.c
index 1af4836c225..f5856ee94b3 100644
--- a/source/blender/bmesh/intern/bmesh_construct.c
+++ b/source/blender/bmesh/intern/bmesh_construct.c
@@ -33,7 +33,7 @@
#include "MEM_guardedalloc.h"
-#include "BLI_array.h"
+#include "BLI_alloca.h"
#include "BLI_math.h"
#include "BKE_customdata.h"
@@ -200,6 +200,8 @@ BMFace *BM_face_create_ngon(BMesh *bm, BMVert *v1, BMVert *v2, BMEdge **edges, c
ev1 = edges[0]->v1;
ev2 = edges[0]->v2;
+ BLI_assert(ELEM(v1, ev1, ev2) && ELEM(v2, ev1, ev2));
+
if (v1 == ev2) {
/* Swapping here improves performance and consistency of face
* structure in the special case that the edges are already in
@@ -322,6 +324,7 @@ BMFace *BM_face_create_ngon_verts(BMesh *bm, BMVert **vert_arr, const int len, c
BMEdge **edge_arr = BLI_array_alloca(edge_arr, len);
unsigned int winding[2] = {0, 0};
int i, i_prev = len - 1;
+ BMVert *v_winding[2] = {vert_arr[i_prev], vert_arr[0]};
BLI_assert(len > 2);
@@ -344,6 +347,7 @@ BMFace *BM_face_create_ngon_verts(BMesh *bm, BMVert **vert_arr, const int len, c
/* we want to use the reverse winding to the existing order */
BM_edge_ordered_verts(edge_arr[i], &test_v2, &test_v1);
winding[(vert_arr[i_prev] == test_v2)]++;
+ BLI_assert(vert_arr[i_prev] == test_v2 || vert_arr[i_prev] == test_v1);
}
}
@@ -370,7 +374,11 @@ BMFace *BM_face_create_ngon_verts(BMesh *bm, BMVert **vert_arr, const int len, c
/* --- */
/* create the face */
- return BM_face_create_ngon(bm, vert_arr[winding[0]], vert_arr[winding[1]], edge_arr, len, create_flag);
+ return BM_face_create_ngon(
+ bm,
+ v_winding[winding[0]],
+ v_winding[winding[1]],
+ edge_arr, len, create_flag);
}
@@ -515,7 +523,7 @@ BMFace *BM_face_create_ngon_vcloud(BMesh *bm, BMVert **vert_arr, int len, const
/* --- */
/* create edges and find the winding (if faces are attached to any existing edges) */
- vert_arr_map = MEM_mallocN(sizeof(BMVert **) * len, __func__);
+ vert_arr_map = MEM_mallocN(sizeof(BMVert *) * len, __func__);
for (i = 0; i < len; i++) {
vert_arr_map[i] = vert_arr[vang[i].index];
@@ -817,11 +825,6 @@ void BM_elem_attrs_copy_ex(BMesh *bm_src, BMesh *bm_dst, const void *ele_src_v,
BLI_assert(ele_src->htype == ele_dst->htype);
- if (ele_src->htype != ele_dst->htype) {
- BLI_assert(!"type mismatch");
- return;
- }
-
if ((hflag_mask & BM_ELEM_SELECT) == 0) {
/* First we copy select */
if (BM_elem_flag_test((BMElem *)ele_src, BM_ELEM_SELECT)) {
@@ -833,6 +836,9 @@ void BM_elem_attrs_copy_ex(BMesh *bm_src, BMesh *bm_dst, const void *ele_src_v,
if (hflag_mask == 0) {
ele_dst->hflag = ele_src->hflag;
}
+ else if (hflag_mask == 0xff) {
+ /* pass */
+ }
else {
ele_dst->hflag = ((ele_dst->hflag & hflag_mask) | (ele_src->hflag & ~hflag_mask));
}
@@ -860,7 +866,19 @@ void BM_elem_attrs_copy_ex(BMesh *bm_src, BMesh *bm_dst, const void *ele_src_v,
void BM_elem_attrs_copy(BMesh *bm_src, BMesh *bm_dst, const void *ele_src, void *ele_dst)
{
/* BMESH_TODO, default 'use_flags' to false */
- BM_elem_attrs_copy_ex(bm_src, bm_dst, ele_src, ele_dst, 0);
+ BM_elem_attrs_copy_ex(bm_src, bm_dst, ele_src, ele_dst, BM_ELEM_SELECT);
+}
+
+void BM_elem_select_copy(BMesh *bm_dst, BMesh *UNUSED(bm_src), void *ele_dst_v, const void *ele_src_v)
+{
+ BMHeader *ele_dst = ele_dst_v;
+ const BMHeader *ele_src = ele_src_v;
+
+ BLI_assert(ele_src->htype == ele_dst->htype);
+
+ if ((ele_src->hflag & BM_ELEM_SELECT) != (ele_dst->hflag & BM_ELEM_SELECT)) {
+ BM_elem_select_set(bm_dst, (BMElem *)ele_dst, (ele_src->hflag & BM_ELEM_SELECT) != 0);
+ }
}
/* helper function for 'BM_mesh_copy' */
@@ -894,7 +912,8 @@ static BMFace *bm_mesh_copy_new_face(BMesh *bm_new, BMesh *bm_old,
/* use totface in case adding some faces fails */
BM_elem_index_set(f_new, (bm_new->totface - 1)); /* set_inline */
- BM_elem_attrs_copy(bm_old, bm_new, f, f_new);
+ BM_elem_attrs_copy_ex(bm_old, bm_new, f, f_new, 0xff);
+ f_new->head.hflag = f->head.hflag; /* low level! don't do this for normal api use */
j = 0;
l_iter = l_first = BM_FACE_FIRST_LOOP(f_new);
@@ -951,7 +970,8 @@ BMesh *BM_mesh_copy(BMesh *bm_old)
BM_ITER_MESH_INDEX (v, &iter, bm_old, BM_VERTS_OF_MESH, i) {
/* copy between meshes so cant use 'example' argument */
v_new = BM_vert_create(bm_new, v->co, NULL, BM_CREATE_SKIP_CD);
- BM_elem_attrs_copy(bm_old, bm_new, v, v_new);
+ BM_elem_attrs_copy_ex(bm_old, bm_new, v, v_new, 0xff);
+ v_new->head.hflag = v->head.hflag; /* low level! don't do this for normal api use */
vtable[i] = v_new;
BM_elem_index_set(v, i); /* set_inline */
BM_elem_index_set(v_new, i); /* set_inline */
@@ -968,7 +988,8 @@ BMesh *BM_mesh_copy(BMesh *bm_old)
vtable[BM_elem_index_get(e->v2)],
e, BM_CREATE_SKIP_CD);
- BM_elem_attrs_copy(bm_old, bm_new, e, e_new);
+ BM_elem_attrs_copy_ex(bm_old, bm_new, e, e_new, 0xff);
+ e_new->head.hflag = e->head.hflag; /* low level! don't do this for normal api use */
etable[i] = e_new;
BM_elem_index_set(e, i); /* set_inline */
BM_elem_index_set(e_new, i); /* set_inline */
@@ -991,6 +1012,12 @@ BMesh *BM_mesh_copy(BMesh *bm_old)
bm_old->elem_index_dirty &= ~BM_FACE;
bm_new->elem_index_dirty &= ~BM_FACE;
+
+ /* low level! don't do this for normal api use */
+ bm_new->totvertsel = bm_old->totvertsel;
+ bm_new->totedgesel = bm_old->totedgesel;
+ bm_new->totfacesel = bm_old->totfacesel;
+
/* safety check */
BLI_assert(i == bm_old->totface);
diff --git a/source/blender/bmesh/intern/bmesh_construct.h b/source/blender/bmesh/intern/bmesh_construct.h
index 3dcb1eb1ccb..f0bd7b316e9 100644
--- a/source/blender/bmesh/intern/bmesh_construct.h
+++ b/source/blender/bmesh/intern/bmesh_construct.h
@@ -53,6 +53,7 @@ void BMO_remove_tagged_context(BMesh *bm, const short oflag, const int type);
void BM_elem_attrs_copy_ex(BMesh *bm_src, BMesh *bm_dst, const void *ele_src_v, void *ele_dst_v,
const char hflag_mask);
void BM_elem_attrs_copy(BMesh *bm_src, BMesh *bm_dst, const void *ele_src_v, void *ele_dst_v);
+void BM_elem_select_copy(BMesh *bm_dst, BMesh *bm_src, void *ele_dst_v, const void *ele_src_v);
void BM_mesh_copy_init_customdata(BMesh *bm_dst, BMesh *bm_src, const struct BMAllocTemplate *allocsize);
BMesh *BM_mesh_copy(BMesh *bm_old);
diff --git a/source/blender/bmesh/intern/bmesh_core.c b/source/blender/bmesh/intern/bmesh_core.c
index 05c462ac672..b296c367575 100644
--- a/source/blender/bmesh/intern/bmesh_core.c
+++ b/source/blender/bmesh/intern/bmesh_core.c
@@ -30,6 +30,7 @@
#include "BLI_math_vector.h"
#include "BLI_listbase.h"
#include "BLI_array.h"
+#include "BLI_alloca.h"
#include "BLI_smallhash.h"
#include "BLF_translation.h"
@@ -594,7 +595,7 @@ static void bm_kill_only_loop(BMesh *bm, BMLoop *l)
*/
void BM_face_edges_kill(BMesh *bm, BMFace *f)
{
- BMEdge **edges = BLI_array_alloca_and_count(edges, f->len);
+ BMEdge **edges = BLI_array_alloca(edges, f->len);
BMLoop *l_iter;
BMLoop *l_first;
int i = 0;
@@ -604,7 +605,7 @@ void BM_face_edges_kill(BMesh *bm, BMFace *f)
edges[i++] = l_iter->e;
} while ((l_iter = l_iter->next) != l_first);
- for (i = 0; i < BLI_array_count(edges); i++) {
+ for (i = 0; i < f->len; i++) {
BM_edge_kill(bm, edges[i]);
}
}
@@ -615,7 +616,7 @@ void BM_face_edges_kill(BMesh *bm, BMFace *f)
*/
void BM_face_verts_kill(BMesh *bm, BMFace *f)
{
- BMVert **verts = BLI_array_alloca_and_count(verts, f->len);
+ BMVert **verts = BLI_array_alloca(verts, f->len);
BMLoop *l_iter;
BMLoop *l_first;
int i = 0;
@@ -625,7 +626,7 @@ void BM_face_verts_kill(BMesh *bm, BMFace *f)
verts[i++] = l_iter->v;
} while ((l_iter = l_iter->next) != l_first);
- for (i = 0; i < BLI_array_count(verts); i++) {
+ for (i = 0; i < f->len; i++) {
BM_vert_kill(bm, verts[i]);
}
}
@@ -1368,16 +1369,20 @@ BMVert *bmesh_semv(BMesh *bm, BMVert *tv, BMEdge *e, BMEdge **r_e)
BMLoop *l_next;
BMEdge *e_new;
BMVert *v_new, *v_old;
- int i, valence1 = 0, valence2 = 0;
+#ifndef NDEBUG
+ int valence1, valence2;
bool edok;
+ int i;
+#endif
BLI_assert(bmesh_vert_in_edge(e, tv) != false);
v_old = bmesh_edge_other_vert_get(e, tv);
+#ifndef NDEBUG
valence1 = bmesh_disk_count(v_old);
-
valence2 = bmesh_disk_count(tv);
+#endif
v_new = BM_vert_create(bm, tv->co, tv, 0);
e_new = BM_edge_create(bm, v_new, tv, e, 0);
@@ -1400,6 +1405,7 @@ BMVert *bmesh_semv(BMesh *bm, BMVert *tv, BMEdge *e, BMEdge **r_e)
/* add e_new to tv's disk cycle */
bmesh_disk_edge_append(e_new, tv);
+#ifndef NDEBUG
/* verify disk cycles */
edok = bmesh_disk_validate(valence1, v_old->e, v_old);
BMESH_ASSERT(edok != false);
@@ -1407,13 +1413,16 @@ BMVert *bmesh_semv(BMesh *bm, BMVert *tv, BMEdge *e, BMEdge **r_e)
BMESH_ASSERT(edok != false);
edok = bmesh_disk_validate(2, v_new->e, v_new);
BMESH_ASSERT(edok != false);
+#endif
/* Split the radial cycle if present */
l_next = e->l;
e->l = NULL;
if (l_next) {
BMLoop *l_new, *l;
+#ifndef NDEBUG
int radlen = bmesh_radial_length(l_next);
+#endif
int first1 = 0, first2 = 0;
/* Take the next loop. Remove it from radial. Split it. Append to appropriate radials */
@@ -1470,6 +1479,7 @@ BMVert *bmesh_semv(BMesh *bm, BMVert *tv, BMEdge *e, BMEdge **r_e)
}
+#ifndef NDEBUG
/* verify length of radial cycle */
edok = bmesh_radial_validate(radlen, e->l);
BMESH_ASSERT(edok != false);
@@ -1508,6 +1518,7 @@ BMVert *bmesh_semv(BMesh *bm, BMVert *tv, BMEdge *e, BMEdge **r_e)
BM_CHECK_ELEMENT(l->e);
BM_CHECK_ELEMENT(l->f);
}
+#endif
}
BM_CHECK_ELEMENT(e_new);
@@ -1555,8 +1566,8 @@ BMEdge *bmesh_jekv(BMesh *bm, BMEdge *e_kill, BMVert *v_kill, const bool check_e
{
BMEdge *e_old;
BMVert *v_old, *tv;
- BMLoop *l_kill, *l;
- int len, radlen = 0, i, valence1, valence2;
+ BMLoop *l_kill;
+ int len, radlen = 0, i;
bool edok, halt = false;
if (bmesh_vert_in_edge(e_kill, v_kill) == 0) {
@@ -1566,6 +1577,11 @@ BMEdge *bmesh_jekv(BMesh *bm, BMEdge *e_kill, BMVert *v_kill, const bool check_e
len = bmesh_disk_count(v_kill);
if (len == 2) {
+#ifndef NDEBUG
+ int valence1, valence2;
+ BMLoop *l;
+#endif
+
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);
@@ -1577,9 +1593,11 @@ BMEdge *bmesh_jekv(BMesh *bm, BMEdge *e_kill, BMVert *v_kill, const bool check_e
else {
BMEdge *e_splice;
+#ifndef NDEBUG
/* For verification later, count valence of v_old and tv */
valence1 = bmesh_disk_count(v_old);
valence2 = bmesh_disk_count(tv);
+#endif
if (check_edge_double) {
e_splice = BM_edge_exists(tv, v_old);
@@ -1645,6 +1663,7 @@ BMEdge *bmesh_jekv(BMesh *bm, BMEdge *e_kill, BMVert *v_kill, const bool check_e
/* deallocate vertex */
bm_kill_only_vert(bm, v_kill);
+#ifndef NDEBUG
/* Validate disk cycle lengths of v_old, tv are unchanged */
edok = bmesh_disk_validate(valence1, v_old->e, v_old);
BMESH_ASSERT(edok != false);
@@ -1664,6 +1683,7 @@ BMEdge *bmesh_jekv(BMesh *bm, BMEdge *e_kill, BMVert *v_kill, const bool check_e
BM_CHECK_ELEMENT(l->e);
BM_CHECK_ELEMENT(l->f);
}
+#endif
if (check_edge_double) {
if (e_splice) {
@@ -1745,10 +1765,10 @@ BMFace *bmesh_jfke(BMesh *bm, BMFace *f1, BMFace *f2, BMEdge *e)
/* 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(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) )
+ if (BM_edge_in_face(l_f1->next->e, f2) ||
+ BM_edge_in_face(l_f1->prev->e, f2) ||
+ BM_edge_in_face(l_f2->next->e, f1) ||
+ BM_edge_in_face(l_f2->prev->e, f1) )
{
return NULL;
}
@@ -1895,7 +1915,8 @@ bool BM_vert_splice(BMesh *bm, BMVert *v, BMVert *v_target)
*
* \return Success
*/
-bool bmesh_vert_separate(BMesh *bm, BMVert *v, BMVert ***r_vout, int *r_vout_len)
+void bmesh_vert_separate(BMesh *bm, BMVert *v, BMVert ***r_vout, int *r_vout_len,
+ const bool copy_select)
{
const int v_edgetot = BM_vert_face_count(v);
BMEdge **stack = BLI_array_alloca(stack, v_edgetot);
@@ -1950,6 +1971,9 @@ bool bmesh_vert_separate(BMesh *bm, BMVert *v, BMVert ***r_vout, int *r_vout_len
verts[0] = v;
for (i = 1; i < maxindex; i++) {
verts[i] = BM_vert_create(bm, v->co, v, 0);
+ if (copy_select) {
+ BM_elem_select_copy(bm, bm, verts[i], v);
+ }
}
/* Replace v with the new verts in each group */
@@ -2019,14 +2043,12 @@ bool bmesh_vert_separate(BMesh *bm, BMVert *v, BMVert ***r_vout, int *r_vout_len
if (r_vout != NULL) {
*r_vout = verts;
}
-
- return true;
}
/**
* High level function which wraps both #bmesh_vert_separate and #bmesh_edge_separate
*/
-bool BM_vert_separate(BMesh *bm, BMVert *v, BMVert ***r_vout, int *r_vout_len,
+void BM_vert_separate(BMesh *bm, BMVert *v, BMVert ***r_vout, int *r_vout_len,
BMEdge **e_in, int e_in_len)
{
int i;
@@ -2034,11 +2056,11 @@ bool BM_vert_separate(BMesh *bm, BMVert *v, BMVert ***r_vout, int *r_vout_len,
for (i = 0; i < e_in_len; i++) {
BMEdge *e = e_in[i];
if (e->l && BM_vert_in_edge(e, v)) {
- bmesh_edge_separate(bm, e, e->l);
+ bmesh_edge_separate(bm, e, e->l, false);
}
}
- return bmesh_vert_separate(bm, v, r_vout, r_vout_len);
+ bmesh_vert_separate(bm, v, r_vout, r_vout_len, false);
}
/**
@@ -2094,18 +2116,20 @@ bool BM_edge_splice(BMesh *bm, BMEdge *e, BMEdge *e_target)
* \note Does nothing if \a l_sep is already the only loop in the
* edge radial.
*/
-bool bmesh_edge_separate(BMesh *bm, BMEdge *e, BMLoop *l_sep)
+void bmesh_edge_separate(BMesh *bm, BMEdge *e, BMLoop *l_sep,
+ const bool copy_select)
{
BMEdge *e_new;
- int radlen;
+#ifndef NDEBUG
+ const int radlen = bmesh_radial_length(e->l);
+#endif
BLI_assert(l_sep->e == e);
BLI_assert(e->l);
- radlen = bmesh_radial_length(e->l);
- if (radlen < 2) {
+ if (BM_edge_is_boundary(e)) {
/* no cut required */
- return true;
+ return;
}
if (l_sep == e->l) {
@@ -2117,13 +2141,15 @@ bool bmesh_edge_separate(BMesh *bm, BMEdge *e, BMLoop *l_sep)
bmesh_radial_append(e_new, l_sep);
l_sep->e = e_new;
+ if (copy_select) {
+ BM_elem_select_copy(bm, bm, e_new, e);
+ }
+
BLI_assert(bmesh_radial_length(e->l) == radlen - 1);
BLI_assert(bmesh_radial_length(e_new->l) == 1);
BM_CHECK_ELEMENT(e_new);
BM_CHECK_ELEMENT(e);
-
- return true;
}
/**
@@ -2142,8 +2168,8 @@ BMVert *bmesh_urmv_loop(BMesh *bm, BMLoop *l_sep)
/* peel the face from the edge radials on both sides of the
* loop vert, disconnecting the face from its fan */
- bmesh_edge_separate(bm, l_sep->e, l_sep);
- bmesh_edge_separate(bm, l_sep->prev->e, l_sep->prev);
+ bmesh_edge_separate(bm, l_sep->e, l_sep, false);
+ bmesh_edge_separate(bm, l_sep->prev->e, l_sep->prev, false);
if (bmesh_disk_count(v_sep) == 2) {
/* If there are still only two edges out of v_sep, then
@@ -2161,7 +2187,7 @@ BMVert *bmesh_urmv_loop(BMesh *bm, BMLoop *l_sep)
/* Split all fans connected to the vert, duplicating it for
* each fans. */
- bmesh_vert_separate(bm, v_sep, &vtar, &len);
+ bmesh_vert_separate(bm, v_sep, &vtar, &len, false);
/* There should have been at least two fans cut apart here,
* otherwise the early exit would have kicked in. */
diff --git a/source/blender/bmesh/intern/bmesh_core.h b/source/blender/bmesh/intern/bmesh_core.h
index 6e691a9a0b5..c9e806335dd 100644
--- a/source/blender/bmesh/intern/bmesh_core.h
+++ b/source/blender/bmesh/intern/bmesh_core.h
@@ -50,16 +50,18 @@ void BM_face_kill(BMesh *bm, BMFace *f);
void BM_edge_kill(BMesh *bm, BMEdge *e);
void BM_vert_kill(BMesh *bm, BMVert *v);
-bool bmesh_edge_separate(BMesh *bm, BMEdge *e, BMLoop *l_sep);
+void bmesh_edge_separate(BMesh *bm, BMEdge *e, BMLoop *l_sep,
+ const bool copy_select);
bool BM_edge_splice(BMesh *bm, BMEdge *e, BMEdge *e_target);
bool BM_vert_splice(BMesh *bm, BMVert *v, BMVert *v_target);
-bool bmesh_vert_separate(BMesh *bm, BMVert *v, BMVert ***r_vout, int *r_vout_len);
+void bmesh_vert_separate(BMesh *bm, BMVert *v, BMVert ***r_vout, int *r_vout_len,
+ const bool copy_select);
bool bmesh_loop_reverse(BMesh *bm, BMFace *f);
BMFace *BM_faces_join(BMesh *bm, BMFace **faces, int totface, const bool do_del);
-bool BM_vert_separate(BMesh *bm, BMVert *v, BMVert ***r_vout, int *r_vout_len,
+void BM_vert_separate(BMesh *bm, BMVert *v, BMVert ***r_vout, int *r_vout_len,
BMEdge **e_in, int e_in_len);
/* EULER API - For modifying structure */
diff --git a/source/blender/bmesh/intern/bmesh_edgeloop.c b/source/blender/bmesh/intern/bmesh_edgeloop.c
index a484bd2fa27..1f052bd206a 100644
--- a/source/blender/bmesh/intern/bmesh_edgeloop.c
+++ b/source/blender/bmesh/intern/bmesh_edgeloop.c
@@ -56,7 +56,7 @@ static int bm_vert_other_tag(BMVert *v, BMVert *v_prev,
BMEdge **r_e)
{
BMIter iter;
- BMEdge *e, *e_next;
+ BMEdge *e, *e_next = NULL;
unsigned int count = 0;
BM_ITER_ELEM (e, &iter, v, BM_EDGES_OF_VERT) {
diff --git a/source/blender/bmesh/intern/bmesh_interp.c b/source/blender/bmesh/intern/bmesh_interp.c
index 446d32de5d2..70d1d4c81df 100644
--- a/source/blender/bmesh/intern/bmesh_interp.c
+++ b/source/blender/bmesh/intern/bmesh_interp.c
@@ -36,7 +36,7 @@
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
-#include "BLI_array.h"
+#include "BLI_alloca.h"
#include "BLI_math.h"
#include "BKE_customdata.h"
@@ -205,6 +205,7 @@ void BM_face_interp_from_face(BMesh *bm, BMFace *target, BMFace *source, const b
int i;
/* convert the 3d coords into 2d for projection */
+ BLI_assert(BM_face_is_normal_valid(source));
axis_dominant_v3_to_m3(axis_mat, source->no);
i = 0;
@@ -638,6 +639,7 @@ void BM_loop_interp_from_face(BMesh *bm, BMLoop *target, BMFace *source,
int i;
/* convert the 3d coords into 2d for projection */
+ BLI_assert(BM_face_is_normal_valid(source));
axis_dominant_v3_to_m3(axis_mat, source->no);
i = 0;
@@ -678,6 +680,7 @@ void BM_vert_interp_from_face(BMesh *bm, BMVert *v, BMFace *source)
int i;
/* convert the 3d coords into 2d for projection */
+ BLI_assert(BM_face_is_normal_valid(source));
axis_dominant_v3_to_m3(axis_mat, source->no);
i = 0;
diff --git a/source/blender/bmesh/intern/bmesh_marking.c b/source/blender/bmesh/intern/bmesh_marking.c
index 61a326bbf97..0a6c0f4b293 100644
--- a/source/blender/bmesh/intern/bmesh_marking.c
+++ b/source/blender/bmesh/intern/bmesh_marking.c
@@ -70,6 +70,79 @@ static void recount_totsels(BMesh *bm)
}
/**
+ * \brief Select Mode Clean
+ *
+ * Remove isolated selected elements when in a mode doesn't support them.
+ * eg: in edge-mode a selected vertex must be connected to a selected edge.
+ *
+ * \note this could be made apart of #BM_mesh_select_mode_flush_ex
+ */
+void BM_mesh_select_mode_clean_ex(BMesh *bm, const short selectmode)
+{
+ if (selectmode & SCE_SELECT_VERTEX) {
+ /* pass */
+ }
+ else if (selectmode & SCE_SELECT_EDGE) {
+ BMIter iter;
+
+ if (bm->totvertsel) {
+ BMVert *v;
+ BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) {
+ BM_elem_flag_disable(v, BM_ELEM_SELECT);
+ }
+ bm->totvertsel = 0;
+ }
+
+ if (bm->totedgesel) {
+ BMEdge *e;
+ BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) {
+ if (BM_elem_flag_test(e, BM_ELEM_SELECT)) {
+ BM_vert_select_set(bm, e->v1, true);
+ BM_vert_select_set(bm, e->v2, true);
+ }
+ }
+ }
+ }
+ else if (selectmode & SCE_SELECT_FACE) {
+ BMIter iter;
+
+ if (bm->totvertsel) {
+ BMVert *v;
+ BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) {
+ BM_elem_flag_disable(v, BM_ELEM_SELECT);
+ }
+ bm->totvertsel = 0;
+ }
+
+ if (bm->totedgesel) {
+ BMEdge *e;
+ BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) {
+ BM_elem_flag_disable(e, BM_ELEM_SELECT);
+ }
+ bm->totedgesel = 0;
+ }
+
+ if (bm->totfacesel) {
+ BMFace *f;
+ BM_ITER_MESH (f, &iter, bm, BM_FACES_OF_MESH) {
+ if (BM_elem_flag_test(f, BM_ELEM_SELECT)) {
+ BMLoop *l_iter, *l_first;
+ l_iter = l_first = BM_FACE_FIRST_LOOP(f);
+ do {
+ BM_edge_select_set(bm, l_iter->e, true);
+ } while ((l_iter = l_iter->next) != l_first);
+ }
+ }
+ }
+ }
+}
+
+void BM_mesh_select_mode_clean(BMesh *bm)
+{
+ BM_mesh_select_mode_clean_ex(bm, bm->selectmode);
+}
+
+/**
* \brief Select Mode Flush
*
* Makes sure to flush selections 'upwards'
@@ -329,18 +402,15 @@ void BM_edge_select_set(BMesh *bm, BMEdge *e, const bool select)
if (BM_elem_flag_test(e, BM_ELEM_SELECT)) bm->totedgesel -= 1;
BM_elem_flag_disable(e, BM_ELEM_SELECT);
- if (bm->selectmode == SCE_SELECT_EDGE ||
- bm->selectmode == SCE_SELECT_FACE ||
- bm->selectmode == (SCE_SELECT_EDGE | SCE_SELECT_FACE))
- {
-
+ if ((bm->selectmode & SCE_SELECT_VERTEX) == 0) {
BMIter iter;
BMVert *verts[2] = {e->v1, e->v2};
BMEdge *e2;
int i;
+ /* check if the vert is used by a selected edge */
for (i = 0; i < 2; i++) {
- int deselect = 1;
+ bool deselect = true;
for (e2 = BM_iter_new(&iter, bm, BM_EDGES_OF_VERT, verts[i]); e2; e2 = BM_iter_step(&iter)) {
if (e2 == e) {
@@ -348,7 +418,7 @@ void BM_edge_select_set(BMesh *bm, BMEdge *e, const bool select)
}
if (BM_elem_flag_test(e2, BM_ELEM_SELECT)) {
- deselect = 0;
+ deselect = false;
break;
}
}
@@ -501,19 +571,19 @@ static int bm_mesh_flag_count(BMesh *bm, const char htype, const char hflag,
BLI_assert((htype & ~BM_ALL_NOLOOP) == 0);
if (htype & BM_VERT) {
- for (ele = BM_iter_new(&iter, bm, BM_VERTS_OF_MESH, NULL); ele; ele = BM_iter_step(&iter)) {
+ BM_ITER_MESH (ele, &iter, bm, BM_VERTS_OF_MESH) {
if (respecthide && BM_elem_flag_test(ele, BM_ELEM_HIDDEN)) continue;
if (BM_elem_flag_test_bool(ele, hflag) == test_for_enabled) tot++;
}
}
if (htype & BM_EDGE) {
- for (ele = BM_iter_new(&iter, bm, BM_EDGES_OF_MESH, NULL); ele; ele = BM_iter_step(&iter)) {
+ BM_ITER_MESH (ele, &iter, bm, BM_EDGES_OF_MESH) {
if (respecthide && BM_elem_flag_test(ele, BM_ELEM_HIDDEN)) continue;
if (BM_elem_flag_test_bool(ele, hflag) == test_for_enabled) tot++;
}
}
if (htype & BM_FACE) {
- for (ele = BM_iter_new(&iter, bm, BM_FACES_OF_MESH, NULL); ele; ele = BM_iter_step(&iter)) {
+ BM_ITER_MESH (ele, &iter, bm, BM_FACES_OF_MESH) {
if (respecthide && BM_elem_flag_test(ele, BM_ELEM_HIDDEN)) continue;
if (BM_elem_flag_test_bool(ele, hflag) == test_for_enabled) tot++;
}
@@ -746,6 +816,13 @@ void BM_editselection_plane(BMEditSelection *ese, float r_plane[3])
}
}
+static BMEditSelection *bm_select_history_create(BMHeader *ele)
+{
+ BMEditSelection *ese = (BMEditSelection *) MEM_callocN(sizeof(BMEditSelection), "BMEdit Selection");
+ ese->htype = ele->htype;
+ ese->ele = (BMElem *)ele;
+ return ese;
+}
/* --- macro wrapped funcs --- */
bool _bm_select_history_check(BMesh *bm, const BMHeader *ele)
@@ -767,9 +844,7 @@ bool _bm_select_history_remove(BMesh *bm, BMHeader *ele)
void _bm_select_history_store_notest(BMesh *bm, BMHeader *ele)
{
- BMEditSelection *ese = (BMEditSelection *) MEM_callocN(sizeof(BMEditSelection), "BMEdit Selection");
- ese->htype = ele->htype;
- ese->ele = (BMElem *)ele;
+ BMEditSelection *ese = bm_select_history_create(ele);
BLI_addtail(&(bm->selected), ese);
}
@@ -779,6 +854,20 @@ void _bm_select_history_store(BMesh *bm, BMHeader *ele)
BM_select_history_store_notest(bm, (BMElem *)ele);
}
}
+
+
+void _bm_select_history_store_after_notest(BMesh *bm, BMEditSelection *ese_ref, BMHeader *ele)
+{
+ BMEditSelection *ese = bm_select_history_create(ele);
+ BLI_insertlinkafter(&(bm->selected), ese_ref, ese);
+}
+
+void _bm_select_history_store_after(BMesh *bm, BMEditSelection *ese_ref, BMHeader *ele)
+{
+ if (!BM_select_history_check(bm, (BMElem *)ele)) {
+ BM_select_history_store_after_notest(bm, ese_ref, (BMElem *)ele);
+ }
+}
/* --- end macro wrapped funcs --- */
@@ -791,16 +880,13 @@ void BM_select_history_clear(BMesh *bm)
void BM_select_history_validate(BMesh *bm)
{
- BMEditSelection *ese, *nextese;
-
- ese = bm->selected.first;
+ BMEditSelection *ese, *ese_next;
- while (ese) {
- nextese = ese->next;
+ for (ese = bm->selected.first; ese; ese = ese_next) {
+ ese_next = ese->next;
if (!BM_elem_flag_test(ese->ele, BM_ELEM_SELECT)) {
BLI_freelinkN(&(bm->selected), ese);
}
- ese = nextese;
}
}
diff --git a/source/blender/bmesh/intern/bmesh_marking.h b/source/blender/bmesh/intern/bmesh_marking.h
index b7040e63458..f23eac61278 100644
--- a/source/blender/bmesh/intern/bmesh_marking.h
+++ b/source/blender/bmesh/intern/bmesh_marking.h
@@ -59,6 +59,9 @@ void BM_vert_select_set(BMesh *bm, BMVert *v, const bool select);
void BM_edge_select_set(BMesh *bm, BMEdge *e, const bool select);
void BM_face_select_set(BMesh *bm, BMFace *f, const bool select);
+void BM_mesh_select_mode_clean_ex(BMesh *bm, const short selectmode);
+void BM_mesh_select_mode_clean(BMesh *bm);
+
void BM_mesh_select_mode_set(BMesh *bm, int selectmode);
void BM_mesh_select_mode_flush_ex(BMesh *bm, const short selectmode);
void BM_mesh_select_mode_flush(BMesh *bm);
@@ -84,11 +87,15 @@ void BM_editselection_plane(BMEditSelection *ese, float r_plane[3]);
#define BM_select_history_remove(bm, ele) _bm_select_history_remove(bm, &(ele)->head)
#define BM_select_history_store_notest(bm, ele) _bm_select_history_store_notest(bm, &(ele)->head)
#define BM_select_history_store(bm, ele) _bm_select_history_store(bm, &(ele)->head)
+#define BM_select_history_store_after_notest(bm, ese_ref, ele) _bm_select_history_store_after_notest(bm, ese_ref, &(ele)->head)
+#define BM_select_history_store_after(bm, ese, ese_ref) _bm_select_history_store_after(bm, ese_ref, &(ele)->head)
bool _bm_select_history_check(BMesh *bm, const BMHeader *ele);
bool _bm_select_history_remove(BMesh *bm, BMHeader *ele);
void _bm_select_history_store_notest(BMesh *bm, BMHeader *ele);
void _bm_select_history_store(BMesh *bm, BMHeader *ele);
+void _bm_select_history_store_after(BMesh *bm, BMEditSelection *ese_ref, BMHeader *ele);
+void _bm_select_history_store_after_notest(BMesh *bm, BMEditSelection *ese_ref, BMHeader *ele);
void BM_select_history_validate(BMesh *bm);
void BM_select_history_clear(BMesh *em);
diff --git a/source/blender/bmesh/intern/bmesh_mesh_conv.c b/source/blender/bmesh/intern/bmesh_mesh_conv.c
index 7c4af8eaa3b..81d4aad0fdf 100644
--- a/source/blender/bmesh/intern/bmesh_mesh_conv.c
+++ b/source/blender/bmesh/intern/bmesh_mesh_conv.c
@@ -84,7 +84,7 @@
#include "MEM_guardedalloc.h"
#include "BLI_listbase.h"
-#include "BLI_array.h"
+#include "BLI_alloca.h"
#include "BLI_math_vector.h"
#include "BKE_mesh.h"
@@ -583,9 +583,8 @@ void BM_mesh_bm_to_me(BMesh *bm, Mesh *me, bool do_tessface)
MEdge *med, *medge;
BMVert *v, *eve;
BMEdge *e;
- BMLoop *l;
BMFace *f;
- BMIter iter, liter;
+ BMIter iter;
int i, j, ototvert;
const int cd_vert_bweight_offset = CustomData_get_offset(&bm->vdata, CD_BWEIGHT);
@@ -699,22 +698,26 @@ void BM_mesh_bm_to_me(BMesh *bm, Mesh *me, bool do_tessface)
i = 0;
j = 0;
BM_ITER_MESH (f, &iter, bm, BM_FACES_OF_MESH) {
+ BMLoop *l_iter, *l_first;
mpoly->loopstart = j;
mpoly->totloop = f->len;
mpoly->mat_nr = f->mat_nr;
mpoly->flag = BM_face_flag_to_mflag(f);
- l = BM_iter_new(&liter, bm, BM_LOOPS_OF_FACE, f);
- for ( ; l; l = BM_iter_step(&liter), j++, mloop++) {
- mloop->e = BM_elem_index_get(l->e);
- mloop->v = BM_elem_index_get(l->v);
+ l_iter = l_first = BM_FACE_FIRST_LOOP(f);
+ do {
+ mloop->e = BM_elem_index_get(l_iter->e);
+ mloop->v = BM_elem_index_get(l_iter->v);
- /* copy over customdat */
- CustomData_from_bmesh_block(&bm->ldata, &me->ldata, l->head.data, j);
- BM_CHECK_ELEMENT(l);
- BM_CHECK_ELEMENT(l->e);
- BM_CHECK_ELEMENT(l->v);
- }
+ /* copy over customdata */
+ CustomData_from_bmesh_block(&bm->ldata, &me->ldata, l_iter->head.data, j);
+
+ j++;
+ mloop++;
+ BM_CHECK_ELEMENT(l_iter);
+ BM_CHECK_ELEMENT(l_iter->e);
+ BM_CHECK_ELEMENT(l_iter->v);
+ } while ((l_iter = l_iter->next) != l_first);
if (f == bm->act_face) me->act_face = i;
diff --git a/source/blender/bmesh/intern/bmesh_mods.c b/source/blender/bmesh/intern/bmesh_mods.c
index cb8e9bd7004..418fc16ea55 100644
--- a/source/blender/bmesh/intern/bmesh_mods.c
+++ b/source/blender/bmesh/intern/bmesh_mods.c
@@ -490,26 +490,22 @@ BMEdge *BM_vert_collapse_faces(BMesh *bm, BMEdge *e_kill, BMVert *v_kill, float
BMEdge *e2;
BMVert *tv2;
- BMIter iter;
- BMLoop *l_iter = NULL, *kvloop = NULL, *tvloop = NULL;
-
- void *src[2];
- float w[2];
-
/* Only intended to be called for 2-valence vertices */
BLI_assert(bmesh_disk_count(v_kill) <= 2);
- /* first modify the face loop data */
- w[0] = 1.0f - fac;
- w[1] = fac;
+ /* first modify the face loop data */
if (e_kill->l) {
+ BMLoop *l_iter;
+ const float w[2] = {1.0f - fac, fac};
+
l_iter = e_kill->l;
do {
if (l_iter->v == tv && l_iter->next->v == v_kill) {
- tvloop = l_iter;
- kvloop = l_iter->next;
+ void *src[2];
+ BMLoop *tvloop = l_iter;
+ BMLoop *kvloop = l_iter->next;
src[0] = kvloop->head.data;
src[1] = tvloop->head.data;
@@ -525,11 +521,12 @@ BMEdge *BM_vert_collapse_faces(BMesh *bm, BMEdge *e_kill, BMVert *v_kill, float
tv2 = BM_edge_other_vert(e2, v_kill);
if (join_faces) {
+ BMIter fiter;
BMFace **faces = NULL;
BMFace *f;
- BLI_array_staticdeclare(faces, 8);
+ BLI_array_staticdeclare(faces, BM_DEFAULT_ITER_STACK_SIZE);
- BM_ITER_ELEM (f, &iter, v_kill, BM_FACES_OF_VERT) {
+ BM_ITER_ELEM (f, &fiter, v_kill, BM_FACES_OF_VERT) {
BLI_array_append(faces, f);
}
@@ -543,6 +540,8 @@ BMEdge *BM_vert_collapse_faces(BMesh *bm, BMEdge *e_kill, BMVert *v_kill, float
}
}
+ BLI_assert(BLI_array_count(faces) < 8);
+
BLI_array_free(faces);
}
else {
@@ -553,8 +552,8 @@ BMEdge *BM_vert_collapse_faces(BMesh *bm, BMEdge *e_kill, BMVert *v_kill, float
/* e_new = BM_edge_exists(tv, tv2); */ /* same as return above */
if (e_new && kill_degenerate_faces) {
- BLI_array_declare(bad_faces);
BMFace **bad_faces = NULL;
+ BLI_array_staticdeclare(bad_faces, BM_DEFAULT_ITER_STACK_SIZE);
BMIter fiter;
BMFace *f;
@@ -1073,7 +1072,7 @@ BMEdge *BM_edge_rotate(BMesh *bm, BMEdge *e, const bool ccw, const short check_f
f_hflag_prev_1 = l1->f->head.hflag;
f_hflag_prev_2 = l2->f->head.hflag;
- /* don't delete the edge, manually remove the egde after so we can copy its attributes */
+ /* don't delete the edge, manually remove the edge after so we can copy its attributes */
f = BM_faces_join_pair(bm, l1->f, l2->f, NULL, true);
if (f == NULL) {
diff --git a/source/blender/bmesh/intern/bmesh_opdefines.c b/source/blender/bmesh/intern/bmesh_opdefines.c
index 497c9e1c153..4f8a851c780 100644
--- a/source/blender/bmesh/intern/bmesh_opdefines.c
+++ b/source/blender/bmesh/intern/bmesh_opdefines.c
@@ -518,6 +518,7 @@ static BMOpDefine bmo_bridge_loops_def = {
{"use_cyclic", BMO_OP_SLOT_BOOL},
{"use_merge", BMO_OP_SLOT_BOOL},
{"merge_factor", BMO_OP_SLOT_FLT},
+ {"twist_offset", BMO_OP_SLOT_INT},
{{'\0'}},
},
/* slots_out */
@@ -552,6 +553,29 @@ static BMOpDefine bmo_grid_fill_def = {
BMO_OPTYPE_FLAG_NORMALS_CALC | BMO_OPTYPE_FLAG_SELECT_FLUSH,
};
+
+/*
+ * Fill Holes.
+ *
+ * Fill boundary edges with faces, copying surrounding customdata.
+ */
+static BMOpDefine bmo_holes_fill_def = {
+ "holes_fill",
+ /* slots_in */
+ {{"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* input edges */
+ {"sides", BMO_OP_SLOT_INT}, /* number of face sides to fill */
+ {{'\0'}},
+ },
+ /* slots_out */
+ /* maps new faces to the group numbers they came from */
+ {{"faces.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* new faces */
+ {{'\0'}},
+ },
+ bmo_holes_fill_exec,
+ BMO_OPTYPE_FLAG_NORMALS_CALC | BMO_OPTYPE_FLAG_SELECT_FLUSH,
+};
+
+
/*
* Edge Loop Fill.
*
@@ -639,6 +663,7 @@ static BMOpDefine bmo_rotate_def = {
{{"cent", BMO_OP_SLOT_VEC}, /* center of rotation */
{"matrix", BMO_OP_SLOT_MAT}, /* matrix defining rotation */
{"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* input vertices */
+ {"space", BMO_OP_SLOT_MAT}, /* matrix to define the space (typically object matrix) */
{{'\0'}},
},
{{{'\0'}}}, /* no output */
@@ -655,6 +680,7 @@ static BMOpDefine bmo_translate_def = {
"translate",
/* slots_in */
{{"vec", BMO_OP_SLOT_VEC}, /* translation offset */
+ {"space", BMO_OP_SLOT_MAT}, /* matrix to define the space (typically object matrix) */
{"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* input vertices */
{{'\0'}},
},
@@ -672,6 +698,7 @@ static BMOpDefine bmo_scale_def = {
"scale",
/* slots_in */
{{"vec", BMO_OP_SLOT_VEC}, /* scale factor */
+ {"space", BMO_OP_SLOT_MAT}, /* matrix to define the space (typically object matrix) */
{"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* input vertices */
{{'\0'}},
},
@@ -691,6 +718,7 @@ static BMOpDefine bmo_transform_def = {
"transform",
/* slots_in */
{{"matrix", BMO_OP_SLOT_MAT}, /* transform matrix */
+ {"space", BMO_OP_SLOT_MAT}, /* matrix to define the space (typically object matrix) */
{"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* input vertices */
{{'\0'}},
},
@@ -840,6 +868,27 @@ static BMOpDefine bmo_connect_verts_def = {
};
/*
+ * Connect Verts Across non Planer Faces.
+ *
+ * Split faces by connecting edges along non planer **faces**.
+ */
+static BMOpDefine bmo_connect_verts_nonplanar_def = {
+ "connect_verts_nonplanar",
+ /* slots_in */
+ {{"angle_limit", BMO_OP_SLOT_FLT}, /* total rotation angle (radians) */
+ {"faces", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}},
+ {{'\0'}},
+ },
+ /* slots_out */
+ {{"edges.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}},
+ {"faces.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}},
+ {{'\0'}},
+ },
+ bmo_connect_verts_nonplanar_exec,
+ BMO_OPTYPE_FLAG_UNTAN_MULTIRES | BMO_OPTYPE_FLAG_NORMALS_CALC | BMO_OPTYPE_FLAG_SELECT_FLUSH,
+};
+
+/*
* Connect Verts.
*
* Split faces by adding edges that connect **verts**.
@@ -947,7 +996,9 @@ static BMOpDefine bmo_dissolve_limit_def = {
{"delimit", BMO_OP_SLOT_INT},
{{'\0'}},
},
- {{{'\0'}}}, /* no output */
+ /* slots_out */
+ {{"region.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}},
+ {{'\0'}}},
bmo_dissolve_limit_exec,
BMO_OPTYPE_FLAG_UNTAN_MULTIRES | BMO_OPTYPE_FLAG_NORMALS_CALC | BMO_OPTYPE_FLAG_SELECT_FLUSH,
};
@@ -1044,7 +1095,7 @@ static BMOpDefine bmo_subdivide_edgering_def = {
{{'\0'}},
},
{{"faces.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* output faces */
- {{'\0'}}}, /* no output */
+ {{'\0'}}},
bmo_subdivide_edgering_exec,
BMO_OPTYPE_FLAG_UNTAN_MULTIRES | BMO_OPTYPE_FLAG_NORMALS_CALC | BMO_OPTYPE_FLAG_SELECT_FLUSH,
};
@@ -1133,6 +1184,7 @@ static BMOpDefine bmo_spin_def = {
{"axis", BMO_OP_SLOT_VEC}, /* rotation axis */
{"dvec", BMO_OP_SLOT_VEC}, /* translation delta per step */
{"angle", BMO_OP_SLOT_FLT}, /* total rotation angle (radians) */
+ {"space", BMO_OP_SLOT_MAT}, /* matrix to define the space (typically object matrix) */
{"steps", BMO_OP_SLOT_INT}, /* number of steps */
{"use_duplicate", BMO_OP_SLOT_BOOL}, /* duplicate or extrude? */
{{'\0'}},
@@ -1224,7 +1276,6 @@ static BMOpDefine bmo_rotate_uvs_def = {
{"use_ccw", BMO_OP_SLOT_BOOL}, /* rotate counter-clockwise if true, otherwise clockwise */
{{'\0'}},
},
- /* slots_out */
{{{'\0'}}}, /* no output */
bmo_rotate_uvs_exec,
BMO_OPTYPE_FLAG_NOP,
@@ -1704,6 +1755,7 @@ const BMOpDefine *bmo_opdefines[] = {
&bmo_collapse_def,
&bmo_collapse_uvs_def,
&bmo_connect_verts_def,
+ &bmo_connect_verts_nonplanar_def,
&bmo_connect_vert_pair_def,
&bmo_contextual_create_def,
#ifdef WITH_BULLET
@@ -1723,6 +1775,7 @@ const BMOpDefine *bmo_opdefines[] = {
&bmo_dissolve_limit_def,
&bmo_dissolve_verts_def,
&bmo_duplicate_def,
+ &bmo_holes_fill_def,
&bmo_edgeloop_fill_def,
&bmo_edgenet_fill_def,
&bmo_edgenet_prepare_def,
diff --git a/source/blender/bmesh/intern/bmesh_operators.c b/source/blender/bmesh/intern/bmesh_operators.c
index 63c00d5b545..b71d5a7e7d4 100644
--- a/source/blender/bmesh/intern/bmesh_operators.c
+++ b/source/blender/bmesh/intern/bmesh_operators.c
@@ -34,7 +34,6 @@
#include "BLI_memarena.h"
#include "BLI_mempool.h"
#include "BLI_listbase.h"
-#include "BLI_array.h"
#include "BLF_translation.h"
@@ -411,7 +410,7 @@ void BMO_slot_mat_set(BMOperator *op, BMOpSlot slot_args[BMO_OP_MAX_SLOTS], cons
slot->data.p = BLI_memarena_alloc(op->arena, sizeof(float) * 4 * 4);
if (size == 4) {
- memcpy(slot->data.p, mat, sizeof(float) * 4 * 4);
+ copy_m4_m4(slot->data.p, (float (*)[4])mat);
}
else if (size == 3) {
copy_m4_m3(slot->data.p, (float (*)[3])mat);
@@ -508,13 +507,13 @@ bool BMO_slot_bool_get(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_na
void *BMO_slot_as_arrayN(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name, int *len)
{
BMOpSlot *slot = BMO_slot_get(slot_args, slot_name);
- void *ret;
+ void **ret;
/* could add support for mapping type */
BLI_assert(slot->slot_type == BMO_OP_SLOT_ELEMENT_BUF);
- ret = MEM_mallocN(sizeof(void **) * slot->len, __func__);
- memcpy(ret, slot->data.buf, sizeof(void **) * slot->len);
+ ret = MEM_mallocN(sizeof(void *) * slot->len, __func__);
+ memcpy(ret, slot->data.buf, sizeof(void *) * slot->len);
*len = slot->len;
return ret;
}
diff --git a/source/blender/bmesh/intern/bmesh_operators.h b/source/blender/bmesh/intern/bmesh_operators.h
index 4c6129cf43f..56d63694d88 100644
--- a/source/blender/bmesh/intern/bmesh_operators.h
+++ b/source/blender/bmesh/intern/bmesh_operators.h
@@ -49,9 +49,9 @@ enum {
};
enum {
+ SUBDIV_SELECT_NONE,
SUBDIV_SELECT_ORIG,
SUBDIV_SELECT_INNER,
- SUBDIV_SELECT_INNER_SEL,
SUBDIV_SELECT_LOOPCUT
};
diff --git a/source/blender/bmesh/intern/bmesh_operators_private.h b/source/blender/bmesh/intern/bmesh_operators_private.h
index e6a4760060c..33c10411c0f 100644
--- a/source/blender/bmesh/intern/bmesh_operators_private.h
+++ b/source/blender/bmesh/intern/bmesh_operators_private.h
@@ -40,6 +40,7 @@ void bmo_bridge_loops_exec(BMesh *bm, BMOperator *op);
void bmo_collapse_exec(BMesh *bm, BMOperator *op);
void bmo_collapse_uvs_exec(BMesh *bm, BMOperator *op);
void bmo_connect_verts_exec(BMesh *bm, BMOperator *op);
+void bmo_connect_verts_nonplanar_exec(BMesh *bm, BMOperator *op);
void bmo_connect_vert_pair_exec(BMesh *bm, BMOperator *op);
void bmo_contextual_create_exec(BMesh *bm, BMOperator *op);
void bmo_convex_hull_exec(BMesh *bm, BMOperator *op);
@@ -58,6 +59,7 @@ void bmo_dissolve_limit_exec(BMesh *bm, BMOperator *op);
void bmo_dissolve_verts_exec(BMesh *bm, BMOperator *op);
void bmo_duplicate_exec(BMesh *bm, BMOperator *op);
void bmo_edgeloop_fill_exec(BMesh *bm, BMOperator *op);
+void bmo_holes_fill_exec(BMesh *bm, BMOperator *op);
void bmo_edgenet_fill_exec(BMesh *bm, BMOperator *op);
void bmo_edgenet_prepare_exec(BMesh *bm, BMOperator *op);
void bmo_extrude_discrete_faces_exec(BMesh *bm, BMOperator *op);
diff --git a/source/blender/bmesh/intern/bmesh_polygon.c b/source/blender/bmesh/intern/bmesh_polygon.c
index 88186df89fb..43b261c118d 100644
--- a/source/blender/bmesh/intern/bmesh_polygon.c
+++ b/source/blender/bmesh/intern/bmesh_polygon.c
@@ -32,8 +32,8 @@
#include "MEM_guardedalloc.h"
+#include "BLI_alloca.h"
#include "BLI_math.h"
-#include "BLI_array.h"
#include "BLI_scanfill.h"
#include "BLI_listbase.h"
@@ -95,7 +95,7 @@ static void calc_poly_normal(float normal[3], float verts[][3], int nverts)
*
* Same as #calc_poly_normal but operates directly on a bmesh face.
*/
-static void bm_face_calc_poly_normal(BMFace *f, float n[3])
+static void bm_face_calc_poly_normal(const BMFace *f, float n[3])
{
BMLoop *l_first = BM_FACE_FIRST_LOOP(f);
BMLoop *l_iter = l_first;
@@ -125,7 +125,7 @@ static void bm_face_calc_poly_normal(BMFace *f, float n[3])
* Same as #calc_poly_normal and #bm_face_calc_poly_normal
* but takes an array of vertex locations.
*/
-static void bm_face_calc_poly_normal_vertex_cos(BMFace *f, float n[3],
+static void bm_face_calc_poly_normal_vertex_cos(BMFace *f, float r_no[3],
float const (*vertexCos)[3])
{
BMLoop *l_first = BM_FACE_FIRST_LOOP(f);
@@ -133,29 +133,47 @@ static void bm_face_calc_poly_normal_vertex_cos(BMFace *f, float n[3],
float const *v_prev = vertexCos[BM_elem_index_get(l_first->prev->v)];
float const *v_curr = vertexCos[BM_elem_index_get(l_first->v)];
- zero_v3(n);
+ zero_v3(r_no);
/* Newell's Method */
do {
- add_newell_cross_v3_v3v3(n, v_prev, v_curr);
+ add_newell_cross_v3_v3v3(r_no, v_prev, v_curr);
l_iter = l_iter->next;
v_prev = v_curr;
v_curr = vertexCos[BM_elem_index_get(l_iter->v)];
} while (l_iter != l_first);
- if (UNLIKELY(normalize_v3(n) == 0.0f)) {
- n[2] = 1.0f; /* other axis set to 0.0 */
+ if (UNLIKELY(normalize_v3(r_no) == 0.0f)) {
+ r_no[2] = 1.0f; /* other axis set to 0.0 */
}
}
/**
+ * \brief COMPUTE POLY CENTER (BMFace)
+ */
+static void bm_face_calc_poly_center_mean_vertex_cos(BMFace *f, float r_cent[3],
+ float const (*vertexCos)[3])
+{
+ BMLoop *l_first = BM_FACE_FIRST_LOOP(f);
+ BMLoop *l_iter = l_first;
+
+ zero_v3(r_cent);
+
+ /* Newell's Method */
+ do {
+ add_v3_v3(r_cent, vertexCos[BM_elem_index_get(l_iter->v)]);
+ } while ((l_iter = l_iter->next) != l_first);
+ mul_v3_fl(r_cent, 1.0f / f->len);
+}
+
+/**
* 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 BM_face_calc_tessellation(const BMFace *f, BMLoop **r_loops, int (*_r_index)[3])
{
int *r_index = (int *)_r_index;
BMLoop *l_first = BM_FACE_FIRST_LOOP(f);
@@ -370,8 +388,7 @@ void BM_face_calc_center_bounds(BMFace *f, float r_cent[3])
*/
void BM_face_calc_center_mean(BMFace *f, float r_cent[3])
{
- BMLoop *l_iter;
- BMLoop *l_first;
+ BMLoop *l_iter, *l_first;
zero_v3(r_cent);
@@ -379,9 +396,7 @@ void BM_face_calc_center_mean(BMFace *f, float r_cent[3])
do {
add_v3_v3(r_cent, l_iter->v->co);
} while ((l_iter = l_iter->next) != l_first);
-
- if (f->len)
- mul_v3_fl(r_cent, 1.0f / (float) f->len);
+ mul_v3_fl(r_cent, 1.0f / (float) f->len);
}
/**
@@ -564,7 +579,7 @@ void BM_vert_normal_update_all(BMVert *v)
* is passed in as well.
*/
-void BM_face_calc_normal(BMFace *f, float r_no[3])
+void BM_face_calc_normal(const BMFace *f, float r_no[3])
{
BMLoop *l;
@@ -601,9 +616,9 @@ void BM_face_normal_update(BMFace *f)
BM_face_calc_normal(f, f->no);
}
-/* exact same as 'bmesh_face_normal_update' but accepts vertex coords */
-void BM_face_normal_update_vcos(BMesh *bm, BMFace *f, float no[3],
- float const (*vertexCos)[3])
+/* exact same as 'BM_face_calc_normal' but accepts vertex coords */
+void BM_face_calc_normal_vcos(BMesh *bm, BMFace *f, float r_no[3],
+ float const (*vertexCos)[3])
{
BMLoop *l;
@@ -620,7 +635,7 @@ void BM_face_normal_update_vcos(BMesh *bm, BMFace *f, float no[3],
const float *co3 = vertexCos[BM_elem_index_get((l = l->next)->v)];
const float *co4 = vertexCos[BM_elem_index_get((l->next)->v)];
- normal_quad_v3(no, co1, co2, co3, co4);
+ normal_quad_v3(r_no, co1, co2, co3, co4);
break;
}
case 3:
@@ -629,22 +644,33 @@ void BM_face_normal_update_vcos(BMesh *bm, BMFace *f, float no[3],
const float *co2 = vertexCos[BM_elem_index_get((l = l->next)->v)];
const float *co3 = vertexCos[BM_elem_index_get((l->next)->v)];
- normal_tri_v3(no, co1, co2, co3);
+ normal_tri_v3(r_no, co1, co2, co3);
break;
}
case 0:
{
- zero_v3(no);
+ zero_v3(r_no);
break;
}
default:
{
- bm_face_calc_poly_normal_vertex_cos(f, no, vertexCos);
+ bm_face_calc_poly_normal_vertex_cos(f, r_no, vertexCos);
break;
}
}
}
+/* exact same as 'BM_face_calc_normal' but accepts vertex coords */
+void BM_face_calc_center_mean_vcos(BMesh *bm, BMFace *f, float r_cent[3],
+ float const (*vertexCos)[3])
+{
+ /* must have valid index data */
+ BLI_assert((bm->elem_index_dirty & BM_VERT) == 0);
+ (void)bm;
+
+ bm_face_calc_poly_center_mean_vertex_cos(f, r_cent, vertexCos);
+}
+
/**
* \brief Face Flip Normal
*
@@ -980,6 +1006,8 @@ void BM_face_triangulate(BMesh *bm, BMFace *f,
float *abscoss = BLI_array_alloca(abscoss, f_len_orig);
float mat[3][3];
+ BLI_assert(BM_face_is_normal_valid(f));
+
axis_dominant_v3_to_m3(mat, f->no);
/* copy vertex coordinates to vertspace area */
@@ -1035,7 +1063,7 @@ void BM_face_legal_splits(BMFace *f, BMLoop *(*loops)[2], int len)
{
const int len2 = len * 2;
BMLoop *l;
- float v1[2], v2[2], v3[2] /*, v4[3 */, no[3], mid[2], *p1, *p2, *p3, *p4;
+ float v1[2], v2[2], v3[2], mid[2], *p1, *p2, *p3, *p4;
float out[2] = {-FLT_MAX, -FLT_MAX};
float axis_mat[3][3];
float (*projverts)[2] = BLI_array_alloca(projverts, f->len);
@@ -1043,10 +1071,9 @@ void BM_face_legal_splits(BMFace *f, BMLoop *(*loops)[2], int len)
float fac1 = 1.0000001f, fac2 = 0.9f; //9999f; //0.999f;
int i, j, a = 0, clen;
- /* TODO, the face normal may already be correct */
- BM_face_calc_normal(f, no);
+ BLI_assert(BM_face_is_normal_valid(f));
- axis_dominant_v3_to_m3(axis_mat, no);
+ axis_dominant_v3_to_m3(axis_mat, f->no);
for (i = 0, l = BM_FACE_FIRST_LOOP(f); i < f->len; i++, l = l->next) {
BM_elem_index_set(l, i); /* set_loop */
diff --git a/source/blender/bmesh/intern/bmesh_polygon.h b/source/blender/bmesh/intern/bmesh_polygon.h
index 2f6b54b91d3..e5dc5c081c3 100644
--- a/source/blender/bmesh/intern/bmesh_polygon.h
+++ b/source/blender/bmesh/intern/bmesh_polygon.h
@@ -27,23 +27,25 @@
* \ingroup bmesh
*/
-int BM_face_calc_tessellation(BMFace *f, BMLoop **r_loops, int (*r_index)[3])
+int BM_face_calc_tessellation(const BMFace *f, BMLoop **r_loops, int (*r_index)[3])
#ifdef __GNUC__
__attribute__((warn_unused_result))
__attribute__((nonnull))
#endif
;
-void BM_face_calc_normal(BMFace *f, float r_no[3]);
+void BM_face_calc_normal(const BMFace *f, float r_no[3]);
+void BM_face_calc_normal_vcos(BMesh *bm, BMFace *f, float r_no[3],
+ float const (*vertexCos)[3]);
float BM_face_calc_area(BMFace *f);
float BM_face_calc_perimeter(BMFace *f);
void BM_face_calc_plane(BMFace *f, float r_plane[3]);
void BM_face_calc_center_bounds(BMFace *f, float center[3]);
void BM_face_calc_center_mean(BMFace *f, float center[3]);
+void BM_face_calc_center_mean_vcos(BMesh *bm, BMFace *f, float r_cent[3],
+ float const (*vertexCos)[3]);
void BM_face_calc_center_mean_weighted(BMFace *f, float center[3]);
void BM_face_normal_update(BMFace *f);
-void BM_face_normal_update_vcos(BMesh *bm, BMFace *f, float no[3],
- float const (*vertexCos)[3]);
void BM_edge_normals_update(BMEdge *e);
diff --git a/source/blender/bmesh/intern/bmesh_private.h b/source/blender/bmesh/intern/bmesh_private.h
index 6fd18c07179..7ec418b2253 100644
--- a/source/blender/bmesh/intern/bmesh_private.h
+++ b/source/blender/bmesh/intern/bmesh_private.h
@@ -53,8 +53,8 @@ int bmesh_elem_check(void *element, const char htype);
} (void)0
#endif
-int bmesh_radial_length(BMLoop *l);
-int bmesh_disk_count(BMVert *v);
+int bmesh_radial_length(const BMLoop *l);
+int bmesh_disk_count(const BMVert *v);
/**
* Internal BMHeader.api_flag
diff --git a/source/blender/bmesh/intern/bmesh_queries.c b/source/blender/bmesh/intern/bmesh_queries.c
index 720997fcef8..6eab3c625fa 100644
--- a/source/blender/bmesh/intern/bmesh_queries.c
+++ b/source/blender/bmesh/intern/bmesh_queries.c
@@ -33,8 +33,8 @@
#include "MEM_guardedalloc.h"
-#include "BLI_array.h"
#include "BLI_math.h"
+#include "BLI_alloca.h"
#include "bmesh.h"
#include "intern/bmesh_private.h"
@@ -336,18 +336,18 @@ bool BM_verts_in_face(BMFace *f, BMVert **varr, int len)
/**
* Returns whether or not a given edge is is part of a given face.
*/
-bool BM_edge_in_face(BMFace *f, BMEdge *e)
+bool BM_edge_in_face(BMEdge *e, BMFace *f)
{
- BMLoop *l_iter;
- BMLoop *l_first;
-
- l_iter = l_first = BM_FACE_FIRST_LOOP(f);
+ if (e->l) {
+ BMLoop *l_iter, *l_first;
- do {
- if (l_iter->e == e) {
- return true;
- }
- } while ((l_iter = l_iter->next) != l_first);
+ l_iter = l_first = e->l;
+ do {
+ if (l_iter->f == f) {
+ return true;
+ }
+ } while ((l_iter = l_iter->radial_next) != l_first);
+ }
return false;
}
@@ -644,7 +644,7 @@ int BM_vert_face_count(BMVert *v)
* Tests whether or not the vertex is part of a wire edge.
* (ie: has no faces attached to it)
*/
-bool BM_vert_is_wire(BMVert *v)
+bool BM_vert_is_wire(const BMVert *v)
{
if (v->e) {
BMEdge *e_first, *e_iter;
@@ -667,7 +667,7 @@ bool BM_vert_is_wire(BMVert *v)
* Tests whether or not the edge is part of a wire.
* (ie: has no faces attached to it)
*/
-bool BM_edge_is_wire(BMEdge *e)
+bool BM_edge_is_wire(const BMEdge *e)
{
return (e->l == NULL);
}
@@ -679,7 +679,7 @@ bool BM_edge_is_wire(BMEdge *e)
* 3: Is part of a an edge with more than 2 faces.
* 4: Is part of a wire edge.
*/
-bool BM_vert_is_manifold(BMVert *v)
+bool BM_vert_is_manifold(const BMVert *v)
{
BMEdge *e, *e_old;
BMLoop *l;
@@ -744,7 +744,7 @@ bool BM_vert_is_manifold(BMVert *v)
*/
#if 1 /* fast path for checking manifold */
-bool BM_edge_is_manifold(BMEdge *e)
+bool BM_edge_is_manifold(const BMEdge *e)
{
const BMLoop *l = e->l;
return (l && (l->radial_next != l) && /* not 0 or 1 face users */
@@ -767,7 +767,7 @@ int BM_edge_is_manifold(BMEdge *e)
* Tests that the edge is manifold and
* that both its faces point the same way.
*/
-bool BM_edge_is_contiguous(BMEdge *e)
+bool BM_edge_is_contiguous(const BMEdge *e)
{
const BMLoop *l = e->l;
const BMLoop *l_other;
@@ -780,7 +780,7 @@ bool BM_edge_is_contiguous(BMEdge *e)
* Check if the edge is convex or concave
* (depends on face winding)
*/
-bool BM_edge_is_convex(BMEdge *e)
+bool BM_edge_is_convex(const BMEdge *e)
{
if (BM_edge_is_manifold(e)) {
BMLoop *l1 = e->l;
@@ -803,7 +803,7 @@ bool BM_edge_is_convex(BMEdge *e)
*/
#if 1 /* fast path for checking boundary */
-bool BM_edge_is_boundary(BMEdge *e)
+bool BM_edge_is_boundary(const BMEdge *e)
{
const BMLoop *l = e->l;
return (l && (l->radial_next == l));
@@ -821,7 +821,7 @@ int BM_edge_is_boundary(BMEdge *e)
}
#endif
-bool BM_vert_is_boundary(BMVert *v)
+bool BM_vert_is_boundary(const BMVert *v)
{
if (v->e) {
BMEdge *e_first, *e_iter;
@@ -884,15 +884,15 @@ bool BM_face_share_face_check(BMFace *f1, BMFace *f2)
/**
* Counts the number of edges two faces share (if any)
*/
-int BM_face_share_edge_count(BMFace *f1, BMFace *f2)
+int BM_face_share_edge_count(BMFace *f_a, BMFace *f_b)
{
BMLoop *l_iter;
BMLoop *l_first;
int count = 0;
- l_iter = l_first = BM_FACE_FIRST_LOOP(f1);
+ l_iter = l_first = BM_FACE_FIRST_LOOP(f_a);
do {
- if (bmesh_radial_face_find(l_iter->e, f2)) {
+ if (BM_edge_in_face(l_iter->e, f_b)) {
count++;
}
} while ((l_iter = l_iter->next) != l_first);
@@ -910,7 +910,7 @@ bool BM_face_share_edge_check(BMFace *f1, BMFace *f2)
l_iter = l_first = BM_FACE_FIRST_LOOP(f1);
do {
- if (bmesh_radial_face_find(l_iter->e, f2)) {
+ if (BM_edge_in_face(l_iter->e, f2)) {
return true;
}
} while ((l_iter = l_iter->next) != l_first);
@@ -930,7 +930,7 @@ bool BM_edge_share_face_check(BMEdge *e1, BMEdge *e2)
l = e1->l;
do {
f = l->f;
- if (bmesh_radial_face_find(e2, f)) {
+ if (BM_edge_in_face(e2, f)) {
return true;
}
l = l->radial_next;
@@ -952,7 +952,7 @@ bool BM_edge_share_quad_check(BMEdge *e1, BMEdge *e2)
do {
f = l->f;
if (f->len == 4) {
- if (bmesh_radial_face_find(e2, f)) {
+ if (BM_edge_in_face(e2, f)) {
return true;
}
}
@@ -1047,8 +1047,8 @@ BMLoop *BM_face_edge_share_loop(BMFace *f, BMEdge *e)
* \note This is in fact quite a simple check, mainly include this function so the intent is more obvious.
* We know these 2 verts will _always_ make up the loops edge
*/
-void BM_edge_ordered_verts_ex(BMEdge *edge, BMVert **r_v1, BMVert **r_v2,
- BMLoop *edge_loop)
+void BM_edge_ordered_verts_ex(const BMEdge *edge, BMVert **r_v1, BMVert **r_v2,
+ const BMLoop *edge_loop)
{
BLI_assert(edge_loop->e == edge);
(void)edge; /* quiet warning in release build */
@@ -1056,7 +1056,7 @@ void BM_edge_ordered_verts_ex(BMEdge *edge, BMVert **r_v1, BMVert **r_v2,
*r_v2 = edge_loop->next->v;
}
-void BM_edge_ordered_verts(BMEdge *edge, BMVert **r_v1, BMVert **r_v2)
+void BM_edge_ordered_verts(const BMEdge *edge, BMVert **r_v1, BMVert **r_v2)
{
BM_edge_ordered_verts_ex(edge, r_v1, r_v2, edge->l);
}
@@ -1065,7 +1065,7 @@ void BM_edge_ordered_verts(BMEdge *edge, BMVert **r_v1, BMVert **r_v2)
* Check if the loop is convex or concave
* (depends on face normal)
*/
-bool BM_loop_is_convex(BMLoop *l)
+bool BM_loop_is_convex(const BMLoop *l)
{
float e_dir_prev[3];
float e_dir_next[3];
@@ -1182,11 +1182,11 @@ void BM_loop_calc_face_tangent(BMLoop *l, float r_tangent[3])
*
* \return angle in radians
*/
-float BM_edge_calc_face_angle(BMEdge *e)
+float BM_edge_calc_face_angle(const BMEdge *e)
{
if (BM_edge_is_manifold(e)) {
- BMLoop *l1 = e->l;
- BMLoop *l2 = e->l->radial_next;
+ const BMLoop *l1 = e->l;
+ const BMLoop *l2 = e->l->radial_next;
return angle_normalized_v3v3(l1->f->no, l2->f->no);
}
else {
@@ -1202,7 +1202,7 @@ float BM_edge_calc_face_angle(BMEdge *e)
*
* \return angle in radians
*/
-float BM_edge_calc_face_angle_signed(BMEdge *e)
+float BM_edge_calc_face_angle_signed(const BMEdge *e)
{
if (BM_edge_is_manifold(e)) {
BMLoop *l1 = e->l;
@@ -1228,7 +1228,7 @@ float BM_edge_calc_face_angle_signed(BMEdge *e)
* \param r_tangent The loop corner tangent to set
*/
-void BM_edge_calc_face_tangent(BMEdge *e, BMLoop *e_loop, float r_tangent[3])
+void BM_edge_calc_face_tangent(const BMEdge *e, const BMLoop *e_loop, float r_tangent[3])
{
float tvec[3];
BMVert *v1, *v2;
@@ -1685,13 +1685,13 @@ bool BM_face_exists_multi_edge(BMEdge **earr, int len)
}
/* convenience functions for checking flags */
-bool BM_edge_is_any_vert_flag_test(BMEdge *e, const char hflag)
+bool BM_edge_is_any_vert_flag_test(const BMEdge *e, const char hflag)
{
return (BM_elem_flag_test(e->v1, hflag) ||
BM_elem_flag_test(e->v2, hflag));
}
-bool BM_face_is_any_vert_flag_test(BMFace *f, const char hflag)
+bool BM_face_is_any_vert_flag_test(const BMFace *f, const char hflag)
{
BMLoop *l_iter;
BMLoop *l_first;
@@ -1705,7 +1705,7 @@ bool BM_face_is_any_vert_flag_test(BMFace *f, const char hflag)
return false;
}
-bool BM_face_is_any_edge_flag_test(BMFace *f, const char hflag)
+bool BM_face_is_any_edge_flag_test(const BMFace *f, const char hflag)
{
BMLoop *l_iter;
BMLoop *l_first;
@@ -1719,7 +1719,19 @@ bool BM_face_is_any_edge_flag_test(BMFace *f, const char hflag)
return false;
}
-static void bm_mesh_calc_volume_face(BMFace *f, float *r_vol)
+/**
+ * Use within assert's to check normals are valid.
+ */
+bool BM_face_is_normal_valid(const BMFace *f)
+{
+ const float eps = 0.0001f;
+ float no[3];
+
+ BM_face_calc_normal(f, no);
+ return len_squared_v3v3(no, f->no) < (eps * eps);
+}
+
+static void bm_mesh_calc_volume_face(const BMFace *f, float *r_vol)
{
int tottri = f->len - 2;
BMLoop **loops = BLI_array_alloca(loops, f->len);
@@ -1758,20 +1770,27 @@ float BM_mesh_calc_volume(BMesh *bm, bool is_signed)
return vol;
}
-
+/* note, almost duplicate of BM_mesh_calc_edge_groups, keep in sync */
/**
- * TODO (as we need)
- * - option to walk over faces by verts.
- * - option to walk over non manifold edges.
+ * Calculate isolated groups of faces with optional filtering.
*
* \param bm the BMesh.
- * \param r_groups_array Array of ints to fill in, length of bm->totface.
+ * \param r_groups_array Array of ints to fill in, length of bm->totface
+ * (or when hflag_test is set, the number of flagged faces).
* \param r_group_index index, length pairs into \a r_groups_array, size of return value
- * int pairs: (array_start, array_length).
+ * int pairs: (array_start, array_length).
+ * \param filter_fn Filter the edges or verts we step over (depends on \a htype_step)
+ * as to which types we deal with.
+ * \param user_data Optional user data for \a filter_fn, can be NULL.
+ * \param hflag_test Optional flag to test faces,
+ * use to exclude faces from the calculation, 0 for all faces.
+ * \param htype_step BM_VERT to walk over face-verts, BM_EDGE to walk over faces edges
+ * (having both set is supported too).
* \return The number of groups found.
*/
int BM_mesh_calc_face_groups(BMesh *bm, int *r_groups_array, int (**r_group_index)[2],
- bool (*filter_fn)(BMElem *, void *user_data), void *user_data, const char htype)
+ BMElemFilterFunc filter_fn, void *user_data,
+ const char hflag_test, const char htype_step)
{
#ifdef DEBUG
int group_index_len = 1;
@@ -1786,11 +1805,11 @@ int BM_mesh_calc_face_groups(BMesh *bm, int *r_groups_array, int (**r_group_inde
int group_curr = 0;
- const unsigned int tot_faces = bm->totface;
+ unsigned int tot_faces = 0;
unsigned int tot_touch = 0;
- BMFace **fstack;
- STACK_DECLARE(fstack);
+ BMFace **stack;
+ STACK_DECLARE(stack);
BMIter iter;
BMFace *f;
@@ -1798,30 +1817,38 @@ int BM_mesh_calc_face_groups(BMesh *bm, int *r_groups_array, int (**r_group_inde
STACK_INIT(group_array);
- BLI_assert(((htype & ~(BM_VERT | BM_EDGE)) == 0) && (htype != 0));
+ BLI_assert(((htype_step & ~(BM_VERT | BM_EDGE)) == 0) && (htype_step != 0));
/* init the array */
BM_ITER_MESH_INDEX (f, &iter, bm, BM_FACES_OF_MESH, i) {
+ if ((hflag_test == 0) || BM_elem_flag_test(f, hflag_test)) {
+ tot_faces++;
+ BM_elem_flag_disable(f, BM_ELEM_TAG);
+ }
+ else {
+ /* never walk over tagged */
+ BM_elem_flag_enable(f, BM_ELEM_TAG);
+ }
+
BM_elem_index_set(f, i); /* set_inline */
- BM_elem_flag_disable(f, BM_ELEM_TAG);
}
bm->elem_index_dirty &= ~BM_FACE;
/* detect groups */
- fstack = MEM_mallocN(sizeof(*fstack) * tot_faces, __func__);
+ stack = MEM_mallocN(sizeof(*stack) * tot_faces, __func__);
while (tot_touch != tot_faces) {
- int *fg;
+ int *group_item;
bool ok = false;
BLI_assert(tot_touch < tot_faces);
- STACK_INIT(fstack);
+ STACK_INIT(stack);
BM_ITER_MESH (f, &iter, bm, BM_FACES_OF_MESH) {
if (BM_elem_flag_test(f, BM_ELEM_TAG) == false) {
BM_elem_flag_enable(f, BM_ELEM_TAG);
- STACK_PUSH(fstack, f);
+ STACK_PUSH(stack, f);
ok = true;
break;
}
@@ -1835,48 +1862,50 @@ int BM_mesh_calc_face_groups(BMesh *bm, int *r_groups_array, int (**r_group_inde
group_index = MEM_reallocN(group_index, sizeof(*group_index) * group_index_len);
}
- fg = group_index[group_curr];
- fg[0] = STACK_SIZE(group_array);
- fg[1] = 0;
+ group_item = group_index[group_curr];
+ group_item[0] = STACK_SIZE(group_array);
+ group_item[1] = 0;
- while ((f = STACK_POP(fstack))) {
+ while ((f = STACK_POP(stack))) {
BMLoop *l_iter, *l_first;
/* add face */
STACK_PUSH(group_array, BM_elem_index_get(f));
tot_touch++;
- fg[1]++;
+ group_item[1]++;
/* done */
- if (htype & BM_EDGE) {
+ if (htype_step & BM_EDGE) {
/* search for other faces */
l_iter = l_first = BM_FACE_FIRST_LOOP(f);
do {
BMLoop *l_radial_iter = l_iter->radial_next;
- if ((l_radial_iter != l_iter) && filter_fn((BMElem *)l_iter->e, user_data)) {
+ if ((l_radial_iter != l_iter) &&
+ ((filter_fn == NULL) || filter_fn((BMElem *)l_iter->e, user_data)))
+ {
do {
BMFace *f_other = l_radial_iter->f;
if (BM_elem_flag_test(f_other, BM_ELEM_TAG) == false) {
BM_elem_flag_enable(f_other, BM_ELEM_TAG);
- STACK_PUSH(fstack, f_other);
+ STACK_PUSH(stack, f_other);
}
} while ((l_radial_iter = l_radial_iter->radial_next) != l_iter);
}
} while ((l_iter = l_iter->next) != l_first);
}
- if (htype & BM_VERT) {
+ if (htype_step & BM_VERT) {
BMIter liter;
/* search for other faces */
l_iter = l_first = BM_FACE_FIRST_LOOP(f);
do {
- if (filter_fn((BMElem *)l_iter->v, user_data)) {
+ if ((filter_fn == NULL) || filter_fn((BMElem *)l_iter->v, user_data)) {
BMLoop *l_other;
BM_ITER_ELEM (l_other, &liter, l_iter, BM_LOOPS_OF_LOOP) {
BMFace *f_other = l_other->f;
if (BM_elem_flag_test(f_other, BM_ELEM_TAG) == false) {
BM_elem_flag_enable(f_other, BM_ELEM_TAG);
- STACK_PUSH(fstack, f_other);
+ STACK_PUSH(stack, f_other);
}
}
}
@@ -1887,7 +1916,139 @@ int BM_mesh_calc_face_groups(BMesh *bm, int *r_groups_array, int (**r_group_inde
group_curr++;
}
- MEM_freeN(fstack);
+ MEM_freeN(stack);
+
+ /* reduce alloc to required size */
+ group_index = MEM_reallocN(group_index, sizeof(*group_index) * group_curr);
+ *r_group_index = group_index;
+
+ return group_curr;
+}
+
+/* note, almost duplicate of BM_mesh_calc_face_groups, keep in sync */
+/**
+ * Calculate isolated groups of edges with optional filtering.
+ *
+ * \param bm the BMesh.
+ * \param r_groups_array Array of ints to fill in, length of bm->totedge
+ * (or when hflag_test is set, the number of flagged edges).
+ * \param r_group_index index, length pairs into \a r_groups_array, size of return value
+ * int pairs: (array_start, array_length).
+ * \param filter_fn Filter the edges or verts we step over (depends on \a htype_step)
+ * as to which types we deal with.
+ * \param user_data Optional user data for \a filter_fn, can be NULL.
+ * \param hflag_test Optional flag to test edges,
+ * use to exclude edges from the calculation, 0 for all edges.
+ * \return The number of groups found.
+ *
+ * \note Unlike #BM_mesh_calc_face_groups there is no 'htype_step' argument,
+ * since we always walk over verts.
+ */
+int BM_mesh_calc_edge_groups(BMesh *bm, int *r_groups_array, int (**r_group_index)[2],
+ BMElemFilterFunc filter_fn, void *user_data,
+ const char hflag_test)
+{
+#ifdef DEBUG
+ int group_index_len = 1;
+#else
+ int group_index_len = 32;
+#endif
+
+ int (*group_index)[2] = MEM_mallocN(sizeof(*group_index) * group_index_len, __func__);
+
+ int *group_array = r_groups_array;
+ STACK_DECLARE(group_array);
+
+ int group_curr = 0;
+
+ unsigned int tot_edges = 0;
+ unsigned int tot_touch = 0;
+
+ BMEdge **stack;
+ STACK_DECLARE(stack);
+
+ BMIter iter;
+ BMEdge *e;
+ int i;
+
+ STACK_INIT(group_array);
+
+ /* init the array */
+ BM_ITER_MESH_INDEX (e, &iter, bm, BM_EDGES_OF_MESH, i) {
+ if ((hflag_test == 0) || BM_elem_flag_test(e, hflag_test)) {
+ tot_edges++;
+ BM_elem_flag_disable(e, BM_ELEM_TAG);
+ }
+ else {
+ /* never walk over tagged */
+ BM_elem_flag_enable(e, BM_ELEM_TAG);
+ }
+
+ BM_elem_index_set(e, i); /* set_inline */
+ }
+ bm->elem_index_dirty &= ~BM_EDGE;
+
+ /* detect groups */
+ stack = MEM_mallocN(sizeof(*stack) * tot_edges, __func__);
+
+ while (tot_touch != tot_edges) {
+ int *group_item;
+ bool ok = false;
+
+ BLI_assert(tot_touch < tot_edges);
+
+ STACK_INIT(stack);
+
+ BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) {
+ if (BM_elem_flag_test(e, BM_ELEM_TAG) == false) {
+ BM_elem_flag_enable(e, BM_ELEM_TAG);
+ STACK_PUSH(stack, e);
+ ok = true;
+ break;
+ }
+ }
+
+ BLI_assert(ok == true);
+
+ /* manage arrays */
+ if (group_index_len == group_curr) {
+ group_index_len *= 2;
+ group_index = MEM_reallocN(group_index, sizeof(*group_index) * group_index_len);
+ }
+
+ group_item = group_index[group_curr];
+ group_item[0] = STACK_SIZE(group_array);
+ group_item[1] = 0;
+
+ while ((e = STACK_POP(stack))) {
+ BMIter viter;
+ BMIter eiter;
+ BMVert *v;
+
+ /* add edge */
+ STACK_PUSH(group_array, BM_elem_index_get(e));
+ tot_touch++;
+ group_item[1]++;
+ /* done */
+
+ /* search for other edges */
+ BM_ITER_ELEM (v, &viter, e, BM_VERTS_OF_EDGE) {
+ if ((filter_fn == NULL) || filter_fn((BMElem *)v, user_data)) {
+ BMEdge *e_other;
+ BM_ITER_ELEM (e_other, &eiter, v, BM_EDGES_OF_VERT) {
+ if (BM_elem_flag_test(e_other, BM_ELEM_TAG) == false) {
+ BM_elem_flag_enable(e_other, BM_ELEM_TAG);
+ STACK_PUSH(stack, e_other);
+ }
+ }
+ }
+ }
+ }
+
+ group_curr++;
+ }
+
+ MEM_freeN(stack);
/* reduce alloc to required size */
group_index = MEM_reallocN(group_index, sizeof(*group_index) * group_curr);
diff --git a/source/blender/bmesh/intern/bmesh_queries.h b/source/blender/bmesh/intern/bmesh_queries.h
index f62de692778..2c931de995e 100644
--- a/source/blender/bmesh/intern/bmesh_queries.h
+++ b/source/blender/bmesh/intern/bmesh_queries.h
@@ -27,11 +27,13 @@
* \ingroup bmesh
*/
+typedef bool (*BMElemFilterFunc)(BMElem *, void *user_data);
+
bool BM_vert_in_face(BMFace *f, BMVert *v);
int BM_verts_in_face_count(BMFace *f, BMVert **varr, int len);
bool BM_verts_in_face(BMFace *f, BMVert **varr, int len);
-bool BM_edge_in_face(BMFace *f, BMEdge *e);
+bool BM_edge_in_face(BMEdge *e, BMFace *f);
bool BM_edge_in_loop(BMEdge *e, BMLoop *l);
bool BM_vert_in_edge(const BMEdge *e, const BMVert *v);
@@ -56,26 +58,26 @@ int BM_edge_face_count(BMEdge *e);
int BM_vert_face_count(BMVert *v);
BMEdge *BM_vert_other_disk_edge(BMVert *v, BMEdge *e);
-bool BM_vert_is_wire(BMVert *v);
-bool BM_edge_is_wire(BMEdge *e);
+bool BM_vert_is_wire(const BMVert *v);
+bool BM_edge_is_wire(const BMEdge *e);
-bool BM_vert_is_manifold(BMVert *v);
-bool BM_edge_is_manifold(BMEdge *e);
-bool BM_vert_is_boundary(BMVert *v);
-bool BM_edge_is_boundary(BMEdge *e);
-bool BM_edge_is_contiguous(BMEdge *e);
-bool BM_edge_is_convex(BMEdge *e);
+bool BM_vert_is_manifold(const BMVert *v);
+bool BM_edge_is_manifold(const BMEdge *e);
+bool BM_vert_is_boundary(const BMVert *v);
+bool BM_edge_is_boundary(const BMEdge *e);
+bool BM_edge_is_contiguous(const BMEdge *e);
+bool BM_edge_is_convex(const BMEdge *e);
-bool BM_loop_is_convex(BMLoop *l);
+bool BM_loop_is_convex(const BMLoop *l);
float BM_loop_calc_face_angle(BMLoop *l);
void BM_loop_calc_face_normal(BMLoop *l, float r_normal[3]);
void BM_loop_calc_face_direction(BMLoop *l, float r_normal[3]);
void BM_loop_calc_face_tangent(BMLoop *l, float r_tangent[3]);
-float BM_edge_calc_face_angle(BMEdge *e);
-float BM_edge_calc_face_angle_signed(BMEdge *e);
-void BM_edge_calc_face_tangent(BMEdge *e, BMLoop *e_loop, float r_tangent[3]);
+float BM_edge_calc_face_angle(const BMEdge *e);
+float BM_edge_calc_face_angle_signed(const BMEdge *e);
+void BM_edge_calc_face_tangent(const BMEdge *e, const BMLoop *e_loop, float r_tangent[3]);
float BM_vert_calc_edge_angle(BMVert *v);
float BM_vert_calc_shell_factor(BMVert *v);
@@ -93,7 +95,7 @@ bool BM_face_exists(BMVert **varr, int len, BMFace **r_existface);
bool BM_face_exists_multi(BMVert **varr, BMEdge **earr, int len);
bool BM_face_exists_multi_edge(BMEdge **earr, int len);
-int BM_face_share_face_count(BMFace *f1, BMFace *f2);
+int BM_face_share_face_count(BMFace *f_a, BMFace *f_b);
int BM_face_share_edge_count(BMFace *f1, BMFace *f2);
bool BM_face_share_face_check(BMFace *f1, BMFace *f2);
@@ -106,17 +108,24 @@ BMVert *BM_edge_share_vert(BMEdge *e1, BMEdge *e2);
BMLoop *BM_face_vert_share_loop(BMFace *f, BMVert *v);
BMLoop *BM_face_edge_share_loop(BMFace *f, BMEdge *e);
-void BM_edge_ordered_verts(BMEdge *edge, BMVert **r_v1, BMVert **r_v2);
-void BM_edge_ordered_verts_ex(BMEdge *edge, BMVert **r_v1, BMVert **r_v2,
- BMLoop *edge_loop);
+void BM_edge_ordered_verts(const BMEdge *edge, BMVert **r_v1, BMVert **r_v2);
+void BM_edge_ordered_verts_ex(const BMEdge *edge, BMVert **r_v1, BMVert **r_v2,
+ const BMLoop *edge_loop);
+
+bool BM_edge_is_any_vert_flag_test(const BMEdge *e, const char hflag);
+bool BM_face_is_any_vert_flag_test(const BMFace *f, const char hflag);
+bool BM_face_is_any_edge_flag_test(const BMFace *f, const char hflag);
-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);
+bool BM_face_is_normal_valid(const BMFace *f);
float BM_mesh_calc_volume(BMesh *bm, bool is_signed);
+
int BM_mesh_calc_face_groups(BMesh *bm, int *r_groups_array, int (**r_group_index)[2],
- bool (*filter_fn)(BMElem *, void *user_data), void *user_data, const char htype);
+ BMElemFilterFunc filter_fn, void *user_data,
+ const char hflag_test, const char htype_step);
+int BM_mesh_calc_edge_groups(BMesh *bm, int *r_groups_array, int (**r_group_index)[2],
+ BMElemFilterFunc filter_fn, void *user_data,
+ const char hflag_test);
/* not really any good place to put this */
float bmesh_subd_falloff_calc(const int falloff, float val);
diff --git a/source/blender/bmesh/intern/bmesh_structure.c b/source/blender/bmesh/intern/bmesh_structure.c
index a0907f0db7a..286425cbacf 100644
--- a/source/blender/bmesh/intern/bmesh_structure.c
+++ b/source/blender/bmesh/intern/bmesh_structure.c
@@ -45,7 +45,7 @@ bool bmesh_vert_in_edge(const BMEdge *e, const BMVert *v)
if (e->v1 == v || e->v2 == v) return true;
return false;
}
-bool bmesh_verts_in_edge(BMVert *v1, BMVert *v2, BMEdge *e)
+bool bmesh_verts_in_edge(const BMVert *v1, const BMVert *v2, const BMEdge *e)
{
if (e->v1 == v1 && e->v2 == v2) return true;
else if (e->v1 == v2 && e->v2 == v1) return true;
@@ -130,7 +130,6 @@ bool bmesh_edge_swapverts(BMEdge *e, BMVert *v_orig, BMVert *v_new)
* Functions relating to this cycle:
* - #bmesh_radial_append
* - #bmesh_radial_loop_remove
- * - #bmesh_radial_face_find
* - #bmesh_radial_facevert_count
* - #bmesh_radial_faceloop_find_first
* - #bmesh_radial_faceloop_find_next
@@ -217,7 +216,7 @@ void bmesh_disk_edge_remove(BMEdge *e, BMVert *v)
*
* \return Pointer to the next edge in the disk cycle for the vertex v.
*/
-BMEdge *bmesh_disk_edge_next(BMEdge *e, BMVert *v)
+BMEdge *bmesh_disk_edge_next(const BMEdge *e, const BMVert *v)
{
if (v == e->v1)
return e->v1_disk_link.next;
@@ -226,7 +225,7 @@ BMEdge *bmesh_disk_edge_next(BMEdge *e, BMVert *v)
return NULL;
}
-BMEdge *bmesh_disk_edge_prev(BMEdge *e, BMVert *v)
+BMEdge *bmesh_disk_edge_prev(const BMEdge *e, const BMVert *v)
{
if (v == e->v1)
return e->v1_disk_link.prev;
@@ -235,7 +234,7 @@ BMEdge *bmesh_disk_edge_prev(BMEdge *e, BMVert *v)
return NULL;
}
-BMEdge *bmesh_disk_edge_exists(BMVert *v1, BMVert *v2)
+BMEdge *bmesh_disk_edge_exists(const BMVert *v1, const BMVert *v2)
{
BMEdge *e_iter, *e_first;
@@ -252,7 +251,7 @@ BMEdge *bmesh_disk_edge_exists(BMVert *v1, BMVert *v2)
return NULL;
}
-int bmesh_disk_count(BMVert *v)
+int bmesh_disk_count(const BMVert *v)
{
if (v->e) {
BMEdge *e_first, *e_iter;
@@ -305,7 +304,7 @@ bool bmesh_disk_validate(int len, BMEdge *e, BMVert *v)
* equivalent to counting the number of
* faces incident upon this vertex
*/
-int bmesh_disk_facevert_count(BMVert *v)
+int bmesh_disk_facevert_count(const BMVert *v)
{
/* is there an edge on this vert at all */
if (v->e) {
@@ -334,29 +333,28 @@ int bmesh_disk_facevert_count(BMVert *v)
* vert's loops attached
* to it.
*/
-BMEdge *bmesh_disk_faceedge_find_first(BMEdge *e, BMVert *v)
+BMEdge *bmesh_disk_faceedge_find_first(const BMEdge *e, const BMVert *v)
{
- BMEdge *searchedge = NULL;
- searchedge = e;
+ const BMEdge *e_find = e;
do {
- if (searchedge->l && bmesh_radial_facevert_count(searchedge->l, v)) {
- return searchedge;
+ if (e_find->l && bmesh_radial_facevert_count(e_find->l, v)) {
+ return (BMEdge *)e_find;
}
- } while ((searchedge = bmesh_disk_edge_next(searchedge, v)) != e);
+ } while ((e_find = bmesh_disk_edge_next(e_find, v)) != e);
return NULL;
}
-BMEdge *bmesh_disk_faceedge_find_next(BMEdge *e, BMVert *v)
+BMEdge *bmesh_disk_faceedge_find_next(const BMEdge *e, const BMVert *v)
{
- BMEdge *searchedge = NULL;
- searchedge = bmesh_disk_edge_next(e, v);
+ BMEdge *e_find = NULL;
+ e_find = bmesh_disk_edge_next(e, v);
do {
- if (searchedge->l && bmesh_radial_facevert_count(searchedge->l, v)) {
- return searchedge;
+ if (e_find->l && bmesh_radial_facevert_count(e_find->l, v)) {
+ return e_find;
}
- } while ((searchedge = bmesh_disk_edge_next(searchedge, v)) != e);
- return e;
+ } while ((e_find = bmesh_disk_edge_next(e_find, v)) != e);
+ return (BMEdge *)e;
}
/*****radial cycle functions, e.g. loops surrounding edges**** */
@@ -436,19 +434,19 @@ void bmesh_radial_loop_remove(BMLoop *l, BMEdge *e)
* Finds the first loop of v around radial
* cycle
*/
-BMLoop *bmesh_radial_faceloop_find_first(BMLoop *l, BMVert *v)
+BMLoop *bmesh_radial_faceloop_find_first(const BMLoop *l, const BMVert *v)
{
- BMLoop *l_iter;
+ const BMLoop *l_iter;
l_iter = l;
do {
if (l_iter->v == v) {
- return l_iter;
+ return (BMLoop *)l_iter;
}
} while ((l_iter = l_iter->radial_next) != l);
return NULL;
}
-BMLoop *bmesh_radial_faceloop_find_next(BMLoop *l, BMVert *v)
+BMLoop *bmesh_radial_faceloop_find_next(const BMLoop *l, const BMVert *v)
{
BMLoop *l_iter;
l_iter = l->radial_next;
@@ -457,12 +455,12 @@ BMLoop *bmesh_radial_faceloop_find_next(BMLoop *l, BMVert *v)
return l_iter;
}
} while ((l_iter = l_iter->radial_next) != l);
- return l;
+ return (BMLoop *)l;
}
-int bmesh_radial_length(BMLoop *l)
+int bmesh_radial_length(const BMLoop *l)
{
- BMLoop *l_iter = l;
+ const BMLoop *l_iter = l;
int i = 0;
if (!l)
@@ -509,28 +507,15 @@ void bmesh_radial_append(BMEdge *e, BMLoop *l)
l->e = e;
}
-bool bmesh_radial_face_find(BMEdge *e, BMFace *f)
-{
- BMLoop *l_iter;
- int i, len;
-
- len = bmesh_radial_length(e->l);
- for (i = 0, l_iter = e->l; i < len; i++, l_iter = l_iter->radial_next) {
- if (l_iter->f == f)
- return true;
- }
- return false;
-}
-
/**
* \brief RADIAL COUNT FACE VERT
*
* Returns the number of times a vertex appears
* in a radial cycle
*/
-int bmesh_radial_facevert_count(BMLoop *l, BMVert *v)
+int bmesh_radial_facevert_count(const BMLoop *l, const BMVert *v)
{
- BMLoop *l_iter;
+ const BMLoop *l_iter;
int count = 0;
l_iter = l;
do {
diff --git a/source/blender/bmesh/intern/bmesh_structure.h b/source/blender/bmesh/intern/bmesh_structure.h
index f10e3a12377..f64fb911ab4 100644
--- a/source/blender/bmesh/intern/bmesh_structure.h
+++ b/source/blender/bmesh/intern/bmesh_structure.h
@@ -47,11 +47,11 @@ bool bmesh_loop_validate(BMFace *f);
/* DISK CYCLE MANAGMENT */
void bmesh_disk_edge_append(BMEdge *e, BMVert *v);
void bmesh_disk_edge_remove(BMEdge *e, BMVert *v);
-BMEdge *bmesh_disk_edge_next(BMEdge *e, BMVert *v);
-BMEdge *bmesh_disk_edge_prev(BMEdge *e, BMVert *v);
-int bmesh_disk_facevert_count(BMVert *v);
-BMEdge *bmesh_disk_faceedge_find_first(BMEdge *e, BMVert *v);
-BMEdge *bmesh_disk_faceedge_find_next(BMEdge *e, BMVert *v);
+BMEdge *bmesh_disk_edge_next(const BMEdge *e, const BMVert *v);
+BMEdge *bmesh_disk_edge_prev(const BMEdge *e, const BMVert *v);
+int bmesh_disk_facevert_count(const BMVert *v);
+BMEdge *bmesh_disk_faceedge_find_first(const BMEdge *e, const BMVert *v);
+BMEdge *bmesh_disk_faceedge_find_next(const BMEdge *e, const BMVert *v);
/* RADIAL CYCLE MANAGMENT */
void bmesh_radial_append(BMEdge *e, BMLoop *l);
@@ -60,19 +60,18 @@ void bmesh_radial_loop_remove(BMLoop *l, BMEdge *e);
* bmesh_radial_loop_next(BMLoop *l) / prev.
* just use member access l->radial_next, l->radial_prev now */
-bool bmesh_radial_face_find(BMEdge *e, BMFace *f);
-int bmesh_radial_facevert_count(BMLoop *l, BMVert *v);
-BMLoop *bmesh_radial_faceloop_find_first(BMLoop *l, BMVert *v);
-BMLoop *bmesh_radial_faceloop_find_next(BMLoop *l, BMVert *v);
-BMLoop *bmesh_radial_faceloop_find_vert(BMFace *f, BMVert *v);
+int bmesh_radial_facevert_count(const BMLoop *l, const BMVert *v);
+BMLoop *bmesh_radial_faceloop_find_first(const BMLoop *l, const BMVert *v);
+BMLoop *bmesh_radial_faceloop_find_next(const BMLoop *l, const BMVert *v);
+BMLoop *bmesh_radial_faceloop_find_vert(const BMFace *f, const BMVert *v);
bool bmesh_radial_validate(int radlen, BMLoop *l);
/* EDGE UTILITIES */
bool bmesh_vert_in_edge(const BMEdge *e, const BMVert *v);
-bool bmesh_verts_in_edge(BMVert *v1, BMVert *v2, BMEdge *e);
+bool bmesh_verts_in_edge(const BMVert *v1, const BMVert *v2, const BMEdge *e);
bool bmesh_edge_swapverts(BMEdge *e, BMVert *orig, BMVert *newv); /* relink edge */
BMVert *bmesh_edge_other_vert_get(BMEdge *e, BMVert *v);
-BMEdge *bmesh_disk_edge_exists(BMVert *v1, BMVert *v2);
+BMEdge *bmesh_disk_edge_exists(const BMVert *v1, const BMVert *v2);
bool bmesh_disk_validate(int len, BMEdge *e, BMVert *v);
#endif /* __BMESH_STRUCTURE_H__ */
diff --git a/source/blender/bmesh/intern/bmesh_walkers.c b/source/blender/bmesh/intern/bmesh_walkers.c
index 04edec01a5c..80b85ab6edd 100644
--- a/source/blender/bmesh/intern/bmesh_walkers.c
+++ b/source/blender/bmesh/intern/bmesh_walkers.c
@@ -92,10 +92,11 @@ void BMW_init(BMWalker *walker, BMesh *bm, int type,
if (UNLIKELY(type >= BMW_MAXWALKERS || type < 0)) {
fprintf(stderr,
- "Invalid walker type in BMW_init; type: %d, "
+ "%s: Invalid walker type in BMW_init; type: %d, "
"searchmask: (v:%d, e:%d, f:%d), flag: %d, layer: %d\n",
- type, mask_vert, mask_edge, mask_face, flag, layer);
- BMESH_ASSERT(0);
+ __func__, type, mask_vert, mask_edge, mask_face, flag, layer);
+ BLI_assert(0);
+ return;
}
if (type != BMW_CUSTOM) {
diff --git a/source/blender/bmesh/operators/bmo_beautify.c b/source/blender/bmesh/operators/bmo_beautify.c
index 2c0bc7f95d9..22b686db64e 100644
--- a/source/blender/bmesh/operators/bmo_beautify.c
+++ b/source/blender/bmesh/operators/bmo_beautify.c
@@ -276,7 +276,7 @@ static void bm_edge_update_beauty_cost_single(BMEdge *e, Heap *eheap, HeapNode *
}
}
-/* we have rotated an edge, tag other egdes and clear this one */
+/* we have rotated an edge, tag other edges and clear this one */
static void bm_edge_update_beauty_cost(BMEdge *e, Heap *eheap, HeapNode **eheap_table, GHash **edge_state_arr,
const int flag)
{
@@ -415,9 +415,9 @@ void bmo_beautify_fill_exec(BMesh *bm, BMOperator *op)
/* edge is manifold and can be rotated */
if (BM_edge_rotate_check(e) &&
- /* faces are tagged */
- BMO_elem_flag_test(bm, e->l->f, FACE_MARK) &&
- BMO_elem_flag_test(bm, e->l->radial_next->f, FACE_MARK))
+ /* faces are tagged */
+ BMO_elem_flag_test(bm, e->l->f, FACE_MARK) &&
+ BMO_elem_flag_test(bm, e->l->radial_next->f, FACE_MARK))
{
BM_elem_index_set(e, edge_array_len); /* set_dirty */
BM_elem_flag_enable(e, BM_ELEM_TAG);
diff --git a/source/blender/bmesh/operators/bmo_bridge.c b/source/blender/bmesh/operators/bmo_bridge.c
index 5b046524e95..f63e742d8ba 100644
--- a/source/blender/bmesh/operators/bmo_bridge.c
+++ b/source/blender/bmesh/operators/bmo_bridge.c
@@ -142,7 +142,7 @@ static bool bm_edge_test_cb(BMEdge *e, void *bm_v)
static void bridge_loop_pair(BMesh *bm,
struct BMEdgeLoopStore *el_store_a,
struct BMEdgeLoopStore *el_store_b,
- const bool use_merge, const float merge_factor)
+ const bool use_merge, const float merge_factor, const int twist_offset)
{
const float eps = 0.00001f;
LinkData *el_a_first, *el_b_first;
@@ -268,6 +268,15 @@ static void bridge_loop_pair(BMesh *bm,
if (is_closed) {
bm_bridge_best_rotation(el_store_a, el_store_b);
+
+ /* add twist */
+ if (twist_offset != 0) {
+ const int len_b = BM_edgeloop_length_get(el_store_b);
+ ListBase *lb_b = BM_edgeloop_verts_get(el_store_b);
+ const int offset = twist_offset % len_b;
+ LinkData *el_b = BLI_rfindlink(lb_b, (offset < 0) ? (offset + len_b) : offset);
+ BLI_rotatelist(lb_b, el_b);
+ }
}
/* Assign after flipping is finalized */
@@ -476,6 +485,7 @@ void bmo_bridge_loops_exec(BMesh *bm, BMOperator *op)
const bool use_merge = BMO_slot_bool_get(op->slots_in, "use_merge");
const float merge_factor = BMO_slot_float_get(op->slots_in, "merge_factor");
const bool use_cyclic = BMO_slot_bool_get(op->slots_in, "use_cyclic") && (use_merge == false);
+ const int twist_offset = BMO_slot_int_get(op->slots_in, "twist_offset");
int count;
bool change = false;
@@ -535,7 +545,7 @@ void bmo_bridge_loops_exec(BMesh *bm, BMOperator *op)
bridge_loop_pair(bm,
(struct BMEdgeLoopStore *)el_store,
(struct BMEdgeLoopStore *)el_store_next,
- use_merge, merge_factor);
+ use_merge, merge_factor, twist_offset);
if (use_pairs) {
el_store = el_store->next;
}
diff --git a/source/blender/bmesh/operators/bmo_connect.c b/source/blender/bmesh/operators/bmo_connect.c
index 50588ad70a9..c718cac4bd6 100644
--- a/source/blender/bmesh/operators/bmo_connect.c
+++ b/source/blender/bmesh/operators/bmo_connect.c
@@ -29,8 +29,8 @@
#include "MEM_guardedalloc.h"
#include "BLI_math.h"
-#include "BLI_array.h"
#include "BLI_utildefines.h"
+#include "BLI_alloca.h"
#include "bmesh.h"
diff --git a/source/blender/bmesh/operators/bmo_connect_nonplanar.c b/source/blender/bmesh/operators/bmo_connect_nonplanar.c
new file mode 100644
index 00000000000..6d30b327a6c
--- /dev/null
+++ b/source/blender/bmesh/operators/bmo_connect_nonplanar.c
@@ -0,0 +1,229 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Contributor(s): Campbell Barton
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/bmesh/operators/bmo_connect_nonplanar.c
+ * \ingroup bmesh
+ *
+ * Connect verts non-planer faces iteratively (splits faces).
+ */
+
+#include "MEM_guardedalloc.h"
+
+#include "BLI_math.h"
+#include "BLI_utildefines.h"
+#include "BLI_alloca.h"
+
+#include "bmesh.h"
+
+#include "intern/bmesh_operators_private.h" /* own include */
+
+#define EDGE_OUT (1 << 0)
+#define FACE_OUT (1 << 1)
+
+/**
+ * Calculates the face subset normal.
+ */
+static bool bm_face_subset_calc_normal(BMLoop *l_first, BMLoop *l_last, float r_no[3])
+{
+ float const *v_prev, *v_curr;
+
+ /* Newell's Method */
+ BMLoop *l_iter = l_first;
+ BMLoop *l_term = l_last->next;
+
+ zero_v3(r_no);
+
+ v_prev = l_last->v->co;
+ do {
+ v_curr = l_iter->v->co;
+ add_newell_cross_v3_v3v3(r_no, v_prev, v_curr);
+ v_prev = v_curr;
+ } while ((l_iter = l_iter->next) != l_term);
+
+ return (normalize_v3(r_no) != 0.0f);
+}
+
+/**
+ * Calculates how non-planar the face subset is.
+ */
+static float bm_face_subset_calc_planar(BMLoop *l_first, BMLoop *l_last, const float no[3])
+{
+ float axis_mat[3][3];
+ float z_prev, z_curr;
+ float delta_z = 0.0f;
+
+ /* Newell's Method */
+ BMLoop *l_iter = l_first;
+ BMLoop *l_term = l_last->next;
+
+ axis_dominant_v3_to_m3(axis_mat, no);
+
+ z_prev = dot_m3_v3_row_z(axis_mat, l_last->v->co);
+ do {
+ z_curr = dot_m3_v3_row_z(axis_mat, l_iter->v->co);
+ delta_z += fabsf(z_curr - z_prev);
+ z_prev = z_curr;
+ } while ((l_iter = l_iter->next) != l_term);
+
+ return delta_z;
+}
+
+static bool bm_face_split_find(BMFace *f, BMVert *v_pair[2], float *r_angle)
+{
+ BMLoop *l_iter, *l_first;
+ BMLoop **l_arr = BLI_array_alloca(l_arr, f->len);
+ const unsigned int f_len = f->len;
+ unsigned int i_a, i_b;
+ bool found = false;
+
+ /* angle finding */
+ float err_best = FLT_MAX;
+ float angle_best = FLT_MAX;
+
+ l_iter = l_first = BM_FACE_FIRST_LOOP(f);
+ i_a = 0;
+ do {
+ l_arr[i_a++] = l_iter;
+ } while ((l_iter = l_iter->next) != l_first);
+
+ /* now for the big search, O(N^2), however faces normally aren't so large */
+ for (i_a = 0; i_a < f_len; i_a++) {
+ BMLoop *l_a = l_arr[i_a];
+ for (i_b = i_a + 2; i_b < f_len; i_b++) {
+ BMLoop *l_b = l_arr[i_b];
+ /* check these are not touching
+ * (we could be smarter here) */
+ if ((l_a->next != l_b) &&
+ (l_a->prev != l_b))
+ {
+ /* first calculate normals */
+ float no_a[3], no_b[3];
+
+ if (bm_face_subset_calc_normal(l_a, l_b, no_a) &&
+ bm_face_subset_calc_normal(l_b, l_a, no_b))
+ {
+ const float err_a = bm_face_subset_calc_planar(l_a, l_b, no_a);
+ const float err_b = bm_face_subset_calc_planar(l_b, l_a, no_b);
+ const float err_test = err_a + err_b;
+
+ if (err_test < err_best) {
+ /* check we're legal (we could batch this) */
+ BMLoop *l_split[2] = {l_a, l_b};
+ BM_face_legal_splits(f, &l_split, 1);
+ if (l_split[0]) {
+ err_best = err_test;
+ v_pair[0] = l_a->v;
+ v_pair[1] = l_b->v;
+
+ angle_best = angle_normalized_v3v3(no_a, no_b);
+ found = true;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ *r_angle = angle_best;
+
+ return found;
+
+
+}
+
+static bool bm_face_split_by_angle(BMesh *bm, BMFace *f, BMFace *r_f_pair[2], const float angle_limit)
+{
+ BMVert *v_pair[2];
+ float angle;
+
+ if (bm_face_split_find(f, v_pair, &angle) && (angle > angle_limit)) {
+ BMFace *f_new;
+ BMLoop *l_new;
+ f_new = BM_face_split(bm, f, v_pair[0], v_pair[1], &l_new, NULL, false);
+ if (f_new) {
+ r_f_pair[0] = f;
+ r_f_pair[1] = f_new;
+
+ BMO_elem_flag_enable(bm, f, FACE_OUT);
+ BMO_elem_flag_enable(bm, f_new, FACE_OUT);
+ BMO_elem_flag_enable(bm, l_new->e, EDGE_OUT);
+ return true;
+ }
+ }
+
+ return false;
+
+}
+
+void bmo_connect_verts_nonplanar_exec(BMesh *bm, BMOperator *op)
+{
+ BMOIter siter;
+ BMFace *f;
+ int totface = 0, totloop = 0;
+ int tottris;
+ BMFace **fstack;
+ STACK_DECLARE(fstack);
+
+ const float angle_limit = BMO_slot_float_get(op->slots_in, "angle_limit");
+
+
+ BMO_ITER (f, &siter, op->slots_in, "faces", BM_FACE) {
+ if (f->len > 3) {
+ totface += 1;
+ totloop += f->len;
+ }
+ }
+
+ if (totface == 0) {
+ return;
+ }
+
+ /* over alloc, if we split every face */
+ tottris = poly_to_tri_count(totface, totloop);
+ fstack = MEM_mallocN(sizeof(BMFace *) * tottris, __func__);
+
+ STACK_INIT(fstack);
+
+ BMO_ITER (f, &siter, op->slots_in, "faces", BM_FACE) {
+ if (f->len > 3) {
+ STACK_PUSH(fstack, f);
+ }
+ }
+
+ while ((f = STACK_POP(fstack))) {
+ BMFace *f_pair[2];
+ if (bm_face_split_by_angle(bm, f, f_pair, angle_limit)) {
+ int j;
+ for (j = 0; j < 2; j++) {
+ BM_face_normal_update(f_pair[j]);
+ if (f_pair[j]->len > 3) {
+ STACK_PUSH(fstack, f_pair[j]);
+ }
+ }
+ }
+ }
+
+ MEM_freeN(fstack);
+
+ BMO_slot_buffer_from_enabled_flag(bm, op, op->slots_out, "edges.out", BM_EDGE, EDGE_OUT);
+ BMO_slot_buffer_from_enabled_flag(bm, op, op->slots_out, "faces.out", BM_FACE, FACE_OUT);
+}
diff --git a/source/blender/bmesh/operators/bmo_connect_pair.c b/source/blender/bmesh/operators/bmo_connect_pair.c
index 872f1cea2c7..0bc29c56256 100644
--- a/source/blender/bmesh/operators/bmo_connect_pair.c
+++ b/source/blender/bmesh/operators/bmo_connect_pair.c
@@ -84,17 +84,11 @@ typedef struct PathLinkState {
float co_prev[3];
} PathLinkState;
-/* only the x axis */
-static float mul_v1_m3v3(float M[3][3], const float a[3])
-{
- return M[0][0] * a[0] + M[1][0] * a[1] + M[2][0] * a[2];
-}
-
static int state_isect_co_pair(const PathContext *pc,
const float co_a[3], const float co_b[3])
{
- const float diff_a = mul_v1_m3v3((float (*)[3])pc->matrix, co_a) - pc->axis_sep;
- const float diff_b = mul_v1_m3v3((float (*)[3])pc->matrix, co_b) - pc->axis_sep;
+ const float diff_a = dot_m3_v3_row_x((float (*)[3])pc->matrix, co_a) - pc->axis_sep;
+ const float diff_b = dot_m3_v3_row_x((float (*)[3])pc->matrix, co_b) - pc->axis_sep;
const int test_a = (fabsf(diff_a) < CONNECT_EPS) ? 0 : (diff_a < 0.0f) ? -1 : 1;
const int test_b = (fabsf(diff_b) < CONNECT_EPS) ? 0 : (diff_b < 0.0f) ? -1 : 1;
@@ -110,7 +104,7 @@ static int state_isect_co_pair(const PathContext *pc,
static int state_isect_co_exact(const PathContext *pc,
const float co[3])
{
- const float diff = mul_v1_m3v3((float (*)[3])pc->matrix, co) - pc->axis_sep;
+ const float diff = dot_m3_v3_row_x((float (*)[3])pc->matrix, co) - pc->axis_sep;
return (fabsf(diff) <= CONNECT_EPS);
}
@@ -119,8 +113,8 @@ static float state_calc_co_pair_fac(const PathContext *pc,
{
float diff_a, diff_b, diff_tot;
- diff_a = fabsf(mul_v1_m3v3((float (*)[3])pc->matrix, co_a) - pc->axis_sep);
- diff_b = fabsf(mul_v1_m3v3((float (*)[3])pc->matrix, co_b) - pc->axis_sep);
+ diff_a = fabsf(dot_m3_v3_row_x((float (*)[3])pc->matrix, co_a) - pc->axis_sep);
+ diff_b = fabsf(dot_m3_v3_row_x((float (*)[3])pc->matrix, co_b) - pc->axis_sep);
diff_tot = (diff_a + diff_b);
return (diff_tot > FLT_EPSILON) ? (diff_a / diff_tot) : 0.5f;
}
@@ -443,7 +437,7 @@ void bmo_connect_vert_pair_exec(BMesh *bm, BMOperator *op)
normalize_v3_v3(pc.matrix[2], basis_nor);
invert_m3(pc.matrix);
- pc.axis_sep = mul_v1_m3v3(pc.matrix, pc.v_a->co);
+ pc.axis_sep = dot_m3_v3_row_x(pc.matrix, pc.v_a->co);
}
/* add first vertex */
diff --git a/source/blender/bmesh/operators/bmo_create.c b/source/blender/bmesh/operators/bmo_create.c
index e43c04f7d08..64d0ec6ac27 100644
--- a/source/blender/bmesh/operators/bmo_create.c
+++ b/source/blender/bmesh/operators/bmo_create.c
@@ -278,7 +278,7 @@ void bmo_contextual_create_exec(BMesh *bm, BMOperator *op)
* this connectivity could be used rather then treating
* them as a bunch of isolated verts. */
- BMVert **vert_arr = MEM_mallocN(sizeof(BMVert **) * totv, __func__);
+ BMVert **vert_arr = MEM_mallocN(sizeof(BMVert *) * totv, __func__);
BMFace *f;
BMO_iter_as_array(op->slots_in, "geom", BM_VERT, (void **)vert_arr, totv);
diff --git a/source/blender/bmesh/operators/bmo_dissolve.c b/source/blender/bmesh/operators/bmo_dissolve.c
index e4f2423ca17..d633182de42 100644
--- a/source/blender/bmesh/operators/bmo_dissolve.c
+++ b/source/blender/bmesh/operators/bmo_dissolve.c
@@ -103,10 +103,10 @@ void bmo_dissolve_faces_exec(BMesh *bm, BMOperator *op)
{
BMOIter oiter;
BMFace *f;
- BLI_array_declare(faces);
- BLI_array_declare(regions);
BMFace ***regions = NULL;
BMFace **faces = NULL;
+ BLI_array_declare(regions);
+ BLI_array_declare(faces);
BMFace *act_face = bm->act_face;
BMWalker regwalker;
int i;
@@ -430,5 +430,8 @@ void bmo_dissolve_limit_exec(BMesh *bm, BMOperator *op)
BM_mesh_decimate_dissolve_ex(bm, angle_limit, do_dissolve_boundaries, delimit,
(BMVert **)BMO_SLOT_AS_BUFFER(vinput), vinput->len,
- (BMEdge **)BMO_SLOT_AS_BUFFER(einput), einput->len);
+ (BMEdge **)BMO_SLOT_AS_BUFFER(einput), einput->len,
+ FACE_NEW);
+
+ BMO_slot_buffer_from_enabled_flag(bm, op, op->slots_out, "region.out", BM_FACE, FACE_NEW);
}
diff --git a/source/blender/bmesh/operators/bmo_dupe.c b/source/blender/bmesh/operators/bmo_dupe.c
index d65e2669a58..1dc7b0a414d 100644
--- a/source/blender/bmesh/operators/bmo_dupe.c
+++ b/source/blender/bmesh/operators/bmo_dupe.c
@@ -28,8 +28,8 @@
#include "MEM_guardedalloc.h"
-#include "BLI_array.h"
#include "BLI_math.h"
+#include "BLI_alloca.h"
#include "bmesh.h"
@@ -150,10 +150,7 @@ static BMFace *copy_face(BMOperator *op,
#endif
/* lookup edge */
- for (i = 0, source_loop = BM_iter_new(&iter, source_mesh, BM_LOOPS_OF_FACE, source_face);
- source_loop;
- source_loop = BM_iter_step(&iter), i++)
- {
+ BM_ITER_ELEM_INDEX (source_loop, &iter, source_face, BM_LOOPS_OF_FACE, i) {
vtar[i] = BLI_ghash_lookup(vhash, source_loop->v);
edar[i] = BLI_ghash_lookup(ehash, source_loop->e);
}
@@ -388,33 +385,30 @@ void bmo_split_exec(BMesh *bm, BMOperator *op)
BMEdge *e;
BMFace *f;
BMIter iter, iter2;
- int found;
/* make sure to remove edges and verts we don't need */
- for (e = BM_iter_new(&iter, bm, BM_EDGES_OF_MESH, NULL); e; e = BM_iter_step(&iter)) {
- found = 0;
- f = BM_iter_new(&iter2, bm, BM_FACES_OF_EDGE, e);
- for ( ; f; f = BM_iter_step(&iter2)) {
+ BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) {
+ bool found = false;
+ BM_ITER_ELEM (f, &iter2, e, BM_FACES_OF_EDGE) {
if (!BMO_elem_flag_test(bm, f, SPLIT_INPUT)) {
- found = 1;
+ found = true;
break;
}
}
- if (!found) {
+ if (found == false) {
BMO_elem_flag_enable(bm, e, SPLIT_INPUT);
}
}
- for (v = BM_iter_new(&iter, bm, BM_VERTS_OF_MESH, NULL); v; v = BM_iter_step(&iter)) {
- found = 0;
- e = BM_iter_new(&iter2, bm, BM_EDGES_OF_VERT, v);
- for ( ; e; e = BM_iter_step(&iter2)) {
+ BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) {
+ bool found = false;
+ BM_ITER_ELEM (e, &iter2, v, BM_EDGES_OF_VERT) {
if (!BMO_elem_flag_test(bm, e, SPLIT_INPUT)) {
- found = 1;
+ found = true;
break;
}
}
- if (!found) {
+ if (found == false) {
BMO_elem_flag_enable(bm, v, SPLIT_INPUT);
}
}
@@ -492,8 +486,8 @@ void bmo_spin_exec(BMesh *bm, BMOperator *op)
BMO_op_initf(bm, &dupop, op->flag, "duplicate geom=%S", op, "geom_last.out");
BMO_op_exec(bm, &dupop);
BMO_op_callf(bm, op->flag,
- "rotate cent=%v matrix=%m3 verts=%S",
- cent, rmat, &dupop, "geom.out");
+ "rotate cent=%v matrix=%m3 space=%s verts=%S",
+ cent, rmat, op, "space", &dupop, "geom.out");
BMO_slot_copy(&dupop, slots_out, "geom.out",
op, slots_out, "geom_last.out");
BMO_op_finish(bm, &dupop);
@@ -503,8 +497,8 @@ void bmo_spin_exec(BMesh *bm, BMOperator *op)
op, "geom_last.out");
BMO_op_exec(bm, &extop);
BMO_op_callf(bm, op->flag,
- "rotate cent=%v matrix=%m3 verts=%S",
- cent, rmat, &extop, "geom.out");
+ "rotate cent=%v matrix=%m3 space=%s verts=%S",
+ cent, rmat, op, "space", &extop, "geom.out");
BMO_slot_copy(&extop, slots_out, "geom.out",
op, slots_out, "geom_last.out");
BMO_op_finish(bm, &extop);
@@ -513,8 +507,8 @@ void bmo_spin_exec(BMesh *bm, BMOperator *op)
if (usedvec) {
mul_m3_v3(rmat, dvec);
BMO_op_callf(bm, op->flag,
- "translate vec=%v verts=%S",
- dvec, op, "geom_last.out");
+ "translate vec=%v space=%s verts=%S",
+ dvec, op, "space", op, "geom_last.out");
}
}
}
diff --git a/source/blender/bmesh/operators/bmo_edgenet.c b/source/blender/bmesh/operators/bmo_edgenet.c
index 903cef05604..923b877b822 100644
--- a/source/blender/bmesh/operators/bmo_edgenet.c
+++ b/source/blender/bmesh/operators/bmo_edgenet.c
@@ -31,6 +31,7 @@
#include "BLI_listbase.h"
#include "BLI_math.h"
#include "BLI_array.h"
+#include "BLI_alloca.h"
#include "BLI_smallhash.h"
#include "BLI_rand.h"
#include "BLI_heap.h"
@@ -302,8 +303,7 @@ static void rotsys_make_consistent(BMesh *bm, EdgeData *edata, VertData *vdata)
BMVert *startv = NULL;
float dis;
- v = BM_iter_new(&iter, bm, BM_VERTS_OF_MESH, NULL);
- for (i = 0; i < bm->totvert; i++, BM_iter_step(&iter)) {
+ BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) {
vd = vdata + BM_elem_index_get(v);
if (vd->tag)
@@ -827,10 +827,8 @@ static EPath *edge_find_shortest_path(BMesh *bm, BMOperator *op, BMEdge *edge, E
}
if (!v2) {
- if (path) {
- edge_free_path(pathbase, path);
- path = NULL;
- }
+ edge_free_path(pathbase, path);
+ path = NULL;
continue;
}
@@ -888,27 +886,82 @@ BLI_INLINE void vote_on_winding(BMEdge *edge, EPathNode *node, unsigned int wind
winding[(test_v1 == node->v)]++;
}
+static BMFace *bm_face_from_path(BMesh *bm, EPath *path,
+ EdgeData *edata,
+ const bool use_fill_check)
+{
+ /* accumulte winding directions for each edge which has a face */
+ const unsigned int path_len = BLI_countlist(&path->nodes);
+ unsigned int winding[2] = {0, 0};
+ unsigned int i;
+
+ EPathNode *node;
+
+ BMVert **verts = BLI_array_alloca(verts, path_len);
+ BMEdge **edges = BLI_array_alloca(edges, path_len);
+ BMEdge *e;
+ BMVert *v;
+
+ for (node = path->nodes.first, i = 0; node; node = node->next, i++) {
+
+ v = node->v;
+ e = BM_edge_exists(v, node->next ?
+ node->next->v :
+ ((EPathNode *)path->nodes.first)->v);
+
+ /* check on the winding */
+ if (e->l) {
+ if (UNLIKELY(count_edge_faces(bm, e) >= 2)) {
+ return NULL;
+ }
+
+ vote_on_winding(e, node, winding);
+ }
+
+ verts[i] = v;
+ edges[i] = e;
+ }
+
+ /* do after incase we bail early, above */
+ for (i = 0; i < path_len; i++) {
+ edata[BM_elem_index_get(edges[i])].ftag++;
+ }
+
+
+ /* if these are even it doesn't really matter what to do,
+ * with consistent geometry one will be zero, the choice is clear */
+ if (winding[0] > winding[1]) {
+ BLI_array_wrap(verts, path_len, -1);
+ BLI_array_reverse(verts, path_len);
+ BLI_array_reverse(edges, path_len);
+ }
+
+ if ((use_fill_check == false) ||
+ /* fairly expensive check - see if there are already faces filling this area */
+ (BM_face_exists_multi(verts, edges, path_len) == false))
+ {
+ return BM_face_create(bm, verts, edges, path_len, BM_CREATE_NO_DOUBLE);
+ }
+ else {
+ return NULL;
+ }
+}
+
void bmo_edgenet_fill_exec(BMesh *bm, BMOperator *op)
{
BMIter iter;
BMOIter siter;
BMFace *f;
BMEdge *e;
- BMVert **verts = NULL;
- BLI_array_declare(verts);
EPath *path;
- EPathNode *node;
EdgeData *edata;
VertData *vdata;
- BMEdge **edges = NULL;
PathBase *pathbase;
- BLI_array_declare(edges);
const bool use_restrict = BMO_slot_bool_get(op->slots_in, "use_restrict");
const bool use_fill_check = BMO_slot_bool_get(op->slots_in, "use_fill_check");
const short mat_nr = BMO_slot_int_get(op->slots_in, "mat_nr");
const bool use_smooth = BMO_slot_bool_get(op->slots_in, "use_smooth");
- int i, j;
- unsigned int winding[2]; /* accumulte winding directions for each edge which has a face */
+ int i;
BMOpSlot *slot_restrict = BMO_slot_get(op->slots_in, "restrict");
BMOpSlot *slot_face_groupmap_out = BMO_slot_get(op->slots_out, "face_groupmap.out");
@@ -981,99 +1034,28 @@ void bmo_edgenet_fill_exec(BMesh *bm, BMOperator *op)
edata[BM_elem_index_get(edge)].tag += 1;
path = edge_find_shortest_path(bm, op, edge, edata, vdata, pathbase, group);
- if (!path)
- continue;
-
- winding[0] = winding[1] = 0;
-
- BLI_array_empty(edges);
- BLI_array_empty(verts);
- i = 0;
- for (node = path->nodes.first; node; node = node->next) {
- if (!node->next)
- continue;
-
- e = BM_edge_exists(node->v, node->next->v);
-
- /* this should never happe */
- if (!e)
- break;
-
- /* check on the winding */
- if (e->l) {
- vote_on_winding(e, node, winding);
- }
-
- edata[BM_elem_index_get(e)].ftag++;
- BLI_array_grow_one(edges);
- edges[i++] = e;
-
- BLI_array_append(verts, node->v);
- }
-
- if (edge->l) {
- vote_on_winding(edge, path->nodes.last, winding);
- }
-
- BLI_array_grow_one(edges);
- edges[i++] = edge;
- edata[BM_elem_index_get(edge)].ftag++;
-
- for (j = 0; j < i; j++) {
- if (count_edge_faces(bm, edges[j]) >= 2) {
- edge_free_path(pathbase, path);
- break;
+ if (path && path->nodes.first) {
+ BMFace *f = bm_face_from_path(bm, path, edata,
+ use_fill_check);
+
+ if (f && !BMO_elem_flag_test(bm, f, ELE_ORIG)) {
+ BMO_elem_flag_enable(bm, f, FACE_NEW);
+ f->mat_nr = mat_nr;
+ if (use_smooth) {
+ BM_elem_flag_enable(f, BM_ELEM_SMOOTH);
+ }
}
- }
- if (j != i) {
- continue;
- }
-
- if (i) {
- BMVert *v1, *v2;
-
- /* to define the winding order must select first edge,
- * otherwise we could leave this as-is */
- edge = edges[0];
-
- /* if these are even it doesn't really matter what to do,
- * with consistent geometry one will be zero, the choice is clear */
- if (winding[0] < winding[1]) {
- v1 = verts[0];
- v2 = verts[1];
- }
- else {
- v1 = verts[1];
- v2 = verts[0];
+ if (use_restrict) {
+ BMO_slot_map_int_insert(op, slot_face_groupmap_out, f, path->group);
}
- if ((use_fill_check == false) ||
- /* fairly expensive check - see if there are already faces filling this area */
- (BM_face_exists_multi_edge(edges, i) == false))
- {
- f = BM_face_create_ngon(bm, v1, v2, edges, i, BM_CREATE_NO_DOUBLE);
- if (f && !BMO_elem_flag_test(bm, f, ELE_ORIG)) {
- BMO_elem_flag_enable(bm, f, FACE_NEW);
- f->mat_nr = mat_nr;
- if (use_smooth) {
- BM_elem_flag_enable(f, BM_ELEM_SMOOTH);
- }
- }
-
- if (use_restrict) {
- BMO_slot_map_int_insert(op, slot_face_groupmap_out, f, path->group);
- }
- }
+ edge_free_path(pathbase, path);
}
-
- edge_free_path(pathbase, path);
}
BMO_slot_buffer_from_enabled_flag(bm, op, op->slots_out, "faces.out", BM_FACE, FACE_NEW);
- BLI_array_free(edges);
- BLI_array_free(verts);
edge_pathbase_free(pathbase);
MEM_freeN(edata);
MEM_freeN(vdata);
diff --git a/source/blender/bmesh/operators/bmo_fill_holes.c b/source/blender/bmesh/operators/bmo_fill_holes.c
new file mode 100644
index 00000000000..40a682e790d
--- /dev/null
+++ b/source/blender/bmesh/operators/bmo_fill_holes.c
@@ -0,0 +1,137 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Contributor(s): Campbell Barton.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/bmesh/operators/bmo_fill_holes.c
+ * \ingroup bmesh
+ *
+ * Fill boundary edge loop(s) with faces.
+ */
+
+#include "MEM_guardedalloc.h"
+
+#include "BLI_listbase.h"
+#include "BLI_alloca.h"
+#include "BLI_math.h"
+
+#include "bmesh.h"
+
+#include "intern/bmesh_operators_private.h" /* own include */
+
+#define EDGE_MARK 2
+#define ELE_OUT 4
+
+/**
+ * Clone of BM_face_find_longest_loop that ensures the loop has an adjacent face
+ */
+static BMLoop *bm_face_find_longest_loop_manifold(BMFace *f)
+{
+ BMLoop *longest_loop = NULL;
+ float longest_len = 0.0f;
+ BMLoop *l_iter, *l_first;
+
+ l_iter = l_first = BM_FACE_FIRST_LOOP(f);
+
+ do {
+ if (BM_edge_is_wire(l_iter->e) == false) {
+ const float len = len_squared_v3v3(l_iter->v->co, l_iter->next->v->co);
+ if (len >= longest_len) {
+ longest_loop = l_iter;
+ longest_len = len;
+ }
+ }
+ } while ((l_iter = l_iter->next) != l_first);
+
+ return longest_loop;
+}
+
+static BMFace *bm_face_from_eloop(BMesh *bm, struct BMEdgeLoopStore *el_store)
+{
+ LinkData *node = BM_edgeloop_verts_get(el_store)->first;
+ const int len = BM_edgeloop_length_get(el_store);
+ BMVert **f_verts = BLI_array_alloca(f_verts, len);
+ BMFace *f;
+ BMLoop *l;
+ unsigned int i = 0;
+
+ do {
+ f_verts[i++] = node->data;
+ } while ((node = node->next));
+
+ f = BM_face_create_ngon_verts(bm, f_verts, len, 0, true, false);
+ BM_face_copy_shared(bm, f);
+
+ l = bm_face_find_longest_loop_manifold(f);
+ if (l) {
+ BMFace *f_other = l->radial_next->f;
+ BLI_assert(l->radial_next != l);
+ BM_elem_attrs_copy(bm, bm, f_other, f);
+ }
+
+ return f;
+}
+
+static bool bm_edge_test_cb(BMEdge *e, void *bm_v)
+{
+ return BMO_elem_flag_test((BMesh *)bm_v, e, EDGE_MARK);
+}
+
+void bmo_holes_fill_exec(BMesh *bm, BMOperator *op)
+{
+ ListBase eloops = {NULL, NULL};
+ LinkData *el_store;
+
+ BMEdge *e;
+ int count;
+
+ BMOIter siter;
+
+ const int sides = BMO_slot_int_get(op->slots_in, "sides");
+
+ /* clear tags */
+
+ BM_mesh_elem_hflag_disable_all(bm, BM_FACE, BM_ELEM_TAG, false);
+
+ /* tag edges that may be apart of loops */
+ BMO_ITER (e, &siter, op->slots_in, "edges", BM_EDGE) {
+ BMO_elem_flag_set(bm, e, EDGE_MARK, BM_edge_is_boundary(e));
+ }
+
+ count = BM_mesh_edgeloops_find(bm, &eloops, bm_edge_test_cb, (void *)bm);
+
+ for (el_store = eloops.first; el_store; el_store = el_store->next) {
+ if (BM_edgeloop_is_closed((struct BMEdgeLoopStore *)el_store)) {
+ const int len = BM_edgeloop_length_get((struct BMEdgeLoopStore *)el_store);
+ if ((sides == 0) || (len <= sides)) {
+ BMFace *f;
+
+ f = bm_face_from_eloop(bm, (struct BMEdgeLoopStore *)el_store);
+ BMO_elem_flag_enable(bm, f, ELE_OUT);
+ }
+ }
+ }
+
+ (void)count;
+
+ BM_mesh_edgeloops_free(&eloops);
+
+ BMO_slot_buffer_from_enabled_flag(bm, op, op->slots_out, "faces.out", BM_FACE, ELE_OUT);
+}
diff --git a/source/blender/bmesh/operators/bmo_inset.c b/source/blender/bmesh/operators/bmo_inset.c
index 97444a50438..a7b98cda2b3 100644
--- a/source/blender/bmesh/operators/bmo_inset.c
+++ b/source/blender/bmesh/operators/bmo_inset.c
@@ -277,6 +277,8 @@ static void bm_interp_face_store(InterpFace *iface, BMesh *bm, BMFace *f, MemAre
void *axis_mat = iface->axis_mat;
int i;
+ BLI_assert(BM_face_is_normal_valid(f));
+
axis_dominant_v3_to_m3(axis_mat, f->no);
iface->f = f;
@@ -455,7 +457,7 @@ void bmo_inset_region_exec(BMesh *bm, BMOperator *op)
/* run the separate arg */
- bmesh_edge_separate(bm, es->e_old, es->l);
+ bmesh_edge_separate(bm, es->e_old, es->l, false);
/* calc edge-split info */
es->e_new = es->l->e;
@@ -533,7 +535,7 @@ void bmo_inset_region_exec(BMesh *bm, BMOperator *op)
/* disable touching twice, this _will_ happen if the flags not disabled */
BM_elem_flag_disable(v, BM_ELEM_TAG);
- bmesh_vert_separate(bm, v, &vout, &r_vout_len);
+ bmesh_vert_separate(bm, v, &vout, &r_vout_len, false);
v = NULL; /* don't use again */
/* in some cases the edge doesn't split off */
diff --git a/source/blender/bmesh/operators/bmo_join_triangles.c b/source/blender/bmesh/operators/bmo_join_triangles.c
index 39f7b0953b1..12065743136 100644
--- a/source/blender/bmesh/operators/bmo_join_triangles.c
+++ b/source/blender/bmesh/operators/bmo_join_triangles.c
@@ -34,7 +34,6 @@
#include "DNA_meshdata_types.h"
#include "BLI_math.h"
-#include "BLI_array.h"
#include "BKE_customdata.h"
@@ -42,6 +41,8 @@
#include "intern/bmesh_operators_private.h" /* own include */
+#define FACE_OUT (1 << 0)
+
/* assumes edges are validated before reaching this poin */
static float measure_facepair(const float v1[3], const float v2[3],
const float v3[3], const float v4[3], float limit)
@@ -195,10 +196,9 @@ static int fplcmp(const void *v1, const void *v2)
{
const JoinEdge *e1 = (JoinEdge *)v1, *e2 = (JoinEdge *)v2;
- if (e1->weight > e2->weight) return 1;
+ if (e1->weight > e2->weight) return 1;
else if (e1->weight < e2->weight) return -1;
-
- return 0;
+ else return 0;
}
void bmo_join_triangles_exec(BMesh *bm, BMOperator *op)
@@ -210,148 +210,141 @@ void bmo_join_triangles_exec(BMesh *bm, BMOperator *op)
const bool do_mat = BMO_slot_bool_get(op->slots_in, "cmp_materials");
const float limit = BMO_slot_float_get(op->slots_in, "limit");
- BMIter iter, liter;
+ BMIter iter;
BMOIter siter;
BMFace *f;
- BMLoop *l;
BMEdge *e;
- BLI_array_declare(jedges);
JoinEdge *jedges = NULL;
- int i, totedge;
+ unsigned i, totedge;
+ unsigned int totedge_tag = 0;
/* flag all edges of all input face */
BMO_ITER (f, &siter, op->slots_in, "faces", BM_FACE) {
- BMO_elem_flag_enable(bm, f, FACE_INPUT);
- BM_ITER_ELEM (l, &liter, f, BM_LOOPS_OF_FACE) {
- BMO_elem_flag_enable(bm, l->e, EDGE_MARK);
+ if (f->len == 3) {
+ BMO_elem_flag_enable(bm, f, FACE_INPUT);
}
}
- /* unflag edges that are invalid; e.g. aren't surrounded by triangle */
+ /* flag edges surrounded by 2 flagged triangles */
BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) {
- BMFace *f1, *f2;
- if (!BMO_elem_flag_test(bm, e, EDGE_MARK))
- continue;
-
- if (!BM_edge_face_pair(e, &f1, &f2)) {
- BMO_elem_flag_disable(bm, e, EDGE_MARK);
- continue;
- }
-
- if (f1->len != 3 || f2->len != 3) {
- BMO_elem_flag_disable(bm, e, EDGE_MARK);
- continue;
+ BMFace *f_a, *f_b;
+ if (BM_edge_face_pair(e, &f_a, &f_b) &&
+ (BMO_elem_flag_test(bm, f_a, FACE_INPUT) && BMO_elem_flag_test(bm, f_b, FACE_INPUT)))
+ {
+ BMO_elem_flag_enable(bm, e, EDGE_MARK);
+ totedge_tag++;
}
+ }
- if (!BMO_elem_flag_test(bm, f1, FACE_INPUT) || !BMO_elem_flag_test(bm, f2, FACE_INPUT)) {
- BMO_elem_flag_disable(bm, e, EDGE_MARK);
- continue;
- }
+ if (totedge_tag == 0) {
+ return;
}
-
+
+ /* over alloc, some of the edges will be delimited */
+ jedges = MEM_mallocN(sizeof(*jedges) * totedge_tag, __func__);
+
i = 0;
BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) {
BMVert *v1, *v2, *v3, *v4;
- BMFace *f1, *f2;
+ BMFace *f_a, *f_b;
float measure;
if (!BMO_elem_flag_test(bm, e, EDGE_MARK))
continue;
- f1 = e->l->f;
- f2 = e->l->radial_next->f;
-
- v1 = e->l->v;
- v2 = e->l->prev->v;
- v3 = e->l->next->v;
- v4 = e->l->radial_next->prev->v;
+ f_a = e->l->f;
+ f_b = e->l->radial_next->f;
if (do_sharp && !BM_elem_flag_test(e, BM_ELEM_SMOOTH))
continue;
- if (do_mat && f1->mat_nr != f2->mat_nr)
+ if (do_mat && f_a->mat_nr != f_b->mat_nr)
continue;
if ((do_uv || do_tf || do_vcol) && (bm_edge_faces_cmp(bm, e, do_uv, do_tf, do_vcol) == false))
continue;
+ v1 = e->l->v;
+ v2 = e->l->prev->v;
+ v3 = e->l->next->v;
+ v4 = e->l->radial_next->prev->v;
+
measure = measure_facepair(v1->co, v2->co, v3->co, v4->co, limit);
if (measure < limit) {
- BLI_array_grow_one(jedges);
-
jedges[i].e = e;
jedges[i].weight = measure;
-
i++;
}
}
- if (!jedges)
- return;
-
- qsort(jedges, BLI_array_count(jedges), sizeof(JoinEdge), fplcmp);
+ totedge = i;
+ qsort(jedges, totedge, sizeof(JoinEdge), fplcmp);
- totedge = BLI_array_count(jedges);
for (i = 0; i < totedge; i++) {
- BMFace *f1, *f2;
+ BMFace *f_a, *f_b;
e = jedges[i].e;
- f1 = e->l->f;
- f2 = e->l->radial_next->f;
-
- if (BMO_elem_flag_test(bm, f1, FACE_MARK) || BMO_elem_flag_test(bm, f2, FACE_MARK))
- continue;
+ f_a = e->l->f;
+ f_b = e->l->radial_next->f;
- BMO_elem_flag_enable(bm, f1, FACE_MARK);
- BMO_elem_flag_enable(bm, f2, FACE_MARK);
- BMO_elem_flag_enable(bm, e, EDGE_CHOSEN);
+ /* check if another edge already claimed this face */
+ if ((BMO_elem_flag_test(bm, f_a, FACE_MARK) == false) ||
+ (BMO_elem_flag_test(bm, f_b, FACE_MARK) == false))
+ {
+ BMO_elem_flag_enable(bm, f_a, FACE_MARK);
+ BMO_elem_flag_enable(bm, f_b, FACE_MARK);
+ BMO_elem_flag_enable(bm, e, EDGE_CHOSEN);
+ }
}
+ MEM_freeN(jedges);
+
+ /* join best weighted */
BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) {
- BMFace *f1, *f2;
+ BMFace *f_new;
+ BMFace *f_a, *f_b;
if (!BMO_elem_flag_test(bm, e, EDGE_CHOSEN))
continue;
-
- BM_edge_face_pair(e, &f1, &f2); /* checked above */
- BM_faces_join_pair(bm, f1, f2, e, true);
+ BM_edge_face_pair(e, &f_a, &f_b); /* checked above */
+ if ((f_a->len == 3 && f_b->len == 3)) {
+ f_new = BM_faces_join_pair(bm, f_a, f_b, e, true);
+ if (f_new) {
+ BMO_elem_flag_enable(bm, f_new, FACE_OUT);
+ }
+ }
}
+ /* join 2-tri islands */
BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) {
if (BMO_elem_flag_test(bm, e, EDGE_MARK)) {
- BMFace *f1, *f2;
+ BMLoop *l_a, *l_b;
+ BMFace *f_a, *f_b;
/* ok, this edge wasn't merged, check if it's
- * in a 2-tri-pair island, and if so merg */
+ * in a 2-tri-pair island, and if so merge */
+ l_a = e->l;
+ l_b = e->l->radial_next;
- f1 = e->l->f;
- f2 = e->l->radial_next->f;
+ f_a = l_a->f;
+ f_b = l_b->f;
- if (f1->len != 3 || f2->len != 3)
- continue;
-
- for (i = 0; i < 2; i++) {
- BM_ITER_ELEM (l, &liter, i ? f2 : f1, BM_LOOPS_OF_FACE) {
- if (l->e != e && BMO_elem_flag_test(bm, l->e, EDGE_MARK)) {
- break;
- }
- }
-
- /* if l isn't NULL, we broke out of the loop */
- if (l) {
- break;
+ /* check the other 2 edges in both tris are untagged */
+ if ((f_a->len == 3 && f_b->len == 3) &&
+ (BMO_elem_flag_test(bm, l_a->next->e, EDGE_MARK) == false) &&
+ (BMO_elem_flag_test(bm, l_a->prev->e, EDGE_MARK) == false) &&
+ (BMO_elem_flag_test(bm, l_b->next->e, EDGE_MARK) == false) &&
+ (BMO_elem_flag_test(bm, l_b->prev->e, EDGE_MARK) == false))
+ {
+ BMFace *f_new;
+ f_new = BM_faces_join_pair(bm, f_a, f_b, e, true);
+ if (f_new) {
+ BMO_elem_flag_enable(bm, f_new, FACE_OUT);
}
}
-
- /* if i isn't 2, we broke out of that loop */
- if (i != 2) {
- continue;
- }
-
- BM_faces_join_pair(bm, f1, f2, e, true);
}
}
- BLI_array_free(jedges);
+ BMO_slot_buffer_from_enabled_flag(bm, op, op->slots_out, "faces.out", BM_FACE, FACE_OUT);
}
diff --git a/source/blender/bmesh/operators/bmo_normals.c b/source/blender/bmesh/operators/bmo_normals.c
index 9d86e7ab275..025b8557331 100644
--- a/source/blender/bmesh/operators/bmo_normals.c
+++ b/source/blender/bmesh/operators/bmo_normals.c
@@ -146,14 +146,15 @@ static void bmo_recalc_face_normals_array(BMesh *bm, BMFace **faces, const int f
void bmo_recalc_face_normals_exec(BMesh *bm, BMOperator *op)
{
- int *groups_array = MEM_mallocN(sizeof(groups_array) * bm->totface, __func__);
+ int *groups_array = MEM_mallocN(sizeof(*groups_array) * bm->totface, __func__);
int faces_len;
BMFace **faces_arr = BM_iter_as_arrayN(bm, BM_FACES_OF_MESH, NULL, &faces_len, NULL, 0);
- BMFace **faces_grp = MEM_mallocN(sizeof(faces_grp) * bm->totface, __func__);
+ BMFace **faces_grp = MEM_mallocN(sizeof(*faces_grp) * bm->totface, __func__);
int (*group_index)[2];
const int group_tot = BM_mesh_calc_face_groups(bm, groups_array, &group_index,
- bmo_recalc_normal_edge_filter_cb, NULL, BM_EDGE);
+ bmo_recalc_normal_edge_filter_cb, NULL,
+ 0, BM_EDGE);
int i;
diff --git a/source/blender/bmesh/operators/bmo_smooth_laplacian.c b/source/blender/bmesh/operators/bmo_smooth_laplacian.c
index 91a52cdabef..3f04e23aa73 100644
--- a/source/blender/bmesh/operators/bmo_smooth_laplacian.c
+++ b/source/blender/bmesh/operators/bmo_smooth_laplacian.c
@@ -220,7 +220,7 @@ static void init_laplacian_matrix(LaplacianSystem *sys)
v1 = vf[0]->co;
v2 = vf[1]->co;
v3 = vf[2]->co;
- v4 = has_4_vert ? vf[3]->co : 0;
+ v4 = has_4_vert ? vf[3]->co : NULL;
if (has_4_vert) {
areaf = area_quad_v3(v1, v2, v3, v4);
diff --git a/source/blender/bmesh/operators/bmo_split_edges.c b/source/blender/bmesh/operators/bmo_split_edges.c
index c0847930422..7eea4c4878d 100644
--- a/source/blender/bmesh/operators/bmo_split_edges.c
+++ b/source/blender/bmesh/operators/bmo_split_edges.c
@@ -29,7 +29,6 @@
#include "BLI_utildefines.h"
#include "bmesh.h"
-#include "tools/bmesh_edgesplit.h"
#include "intern/bmesh_operators_private.h" /* own include */
@@ -48,7 +47,7 @@ void bmo_split_edges_exec(BMesh *bm, BMOperator *op)
}
/* this is where everything happens */
- BM_mesh_edgesplit(bm, use_verts, true);
+ BM_mesh_edgesplit(bm, use_verts, true, false);
BMO_slot_buffer_from_enabled_hflag(bm, op, op->slots_out, "edges.out", BM_EDGE, BM_ELEM_INTERNAL_TAG);
}
diff --git a/source/blender/bmesh/operators/bmo_subdivide.c b/source/blender/bmesh/operators/bmo_subdivide.c
index 6b55d5ea877..e669585a857 100644
--- a/source/blender/bmesh/operators/bmo_subdivide.c
+++ b/source/blender/bmesh/operators/bmo_subdivide.c
@@ -593,7 +593,7 @@ static void quad_4edge_subdivide(BMesh *bm, BMFace *UNUSED(face), BMVert **verts
}
for (i = 1; i < numcuts + 2; i++) {
- for (j = 1; j < numcuts + 1; j++) {
+ for (j = 1; j <= numcuts; j++) {
a = i * s + j;
b = (i - 1) * s + j;
e = connect_smallest_face(bm, lines[a], lines[b], &f_new);
@@ -710,7 +710,7 @@ static void tri_3edge_subdivide(BMesh *bm, BMFace *UNUSED(face), BMVert **verts,
* s s
* </pre>
*/
- for (i = 1; i < numcuts + 1; i++) {
+ for (i = 1; i <= numcuts; i++) {
for (j = 0; j < i; j++) {
e = connect_smallest_face(bm, lines[i][j], lines[i + 1][j + 1], &f_new);
@@ -1203,24 +1203,22 @@ void BM_mesh_esubdivide(BMesh *bm, const char edge_hflag,
BMO_op_exec(bm, &op);
- if (seltype == SUBDIV_SELECT_INNER) {
- BMOIter iter;
- BMElem *ele;
-
- for (ele = BMO_iter_new(&iter, op.slots_out, "geom_inner.out", BM_EDGE | BM_VERT); ele; ele = BMO_iter_step(&iter)) {
- BM_elem_select_set(bm, ele, true);
- }
- }
- else if (seltype == SUBDIV_SELECT_LOOPCUT) {
- BMOIter iter;
- BMElem *ele;
-
- /* deselect input */
- BM_mesh_elem_hflag_disable_all(bm, BM_VERT | BM_EDGE | BM_FACE, BM_ELEM_SELECT, false);
-
- for (ele = BMO_iter_new(&iter, op.slots_out, "geom_inner.out", BM_EDGE); ele; ele = BMO_iter_step(&iter)) {
- BM_edge_select_set(bm, (BMEdge *)ele, true);
- }
+ switch (seltype) {
+ case SUBDIV_SELECT_NONE:
+ break;
+ case SUBDIV_SELECT_ORIG:
+ /* set the newly created data to be selected */
+ BMO_slot_buffer_hflag_enable(bm, op.slots_out, "geom_inner.out", BM_ALL_NOLOOP, BM_ELEM_SELECT, true);
+ BM_mesh_select_flush(bm);
+ break;
+ case SUBDIV_SELECT_INNER:
+ BMO_slot_buffer_hflag_enable(bm, op.slots_out, "geom_inner.out", BM_EDGE | BM_VERT, BM_ELEM_SELECT, true);
+ break;
+ case SUBDIV_SELECT_LOOPCUT:
+ /* deselect input */
+ BM_mesh_elem_hflag_disable_all(bm, BM_VERT | BM_EDGE | BM_FACE, BM_ELEM_SELECT, false);
+ BMO_slot_buffer_hflag_enable(bm, op.slots_out, "geom_inner.out", BM_EDGE, BM_ELEM_SELECT, true);
+ break;
}
BMO_op_finish(bm, &op);
diff --git a/source/blender/bmesh/operators/bmo_subdivide_edgering.c b/source/blender/bmesh/operators/bmo_subdivide_edgering.c
index 44d4b63f5c4..fa39ae68cdf 100644
--- a/source/blender/bmesh/operators/bmo_subdivide_edgering.c
+++ b/source/blender/bmesh/operators/bmo_subdivide_edgering.c
@@ -40,14 +40,13 @@
#include "MEM_guardedalloc.h"
#include "BLI_utildefines.h"
-#include "BLI_array.h"
+#include "BLI_alloca.h"
#include "BLI_math.h"
#include "BLI_listbase.h"
#include "BKE_curve.h"
#include "bmesh.h"
-#include "tools/bmesh_edgesplit.h"
#include "intern/bmesh_operators_private.h" /* own include */
@@ -1167,6 +1166,7 @@ void bmo_subdivide_edgering_exec(BMesh *bm, BMOperator *op)
bm_edgering_pair_ringsubd(bm, lpair, el_store_a, el_store_b,
interp_mode, cuts, smooth, falloff_cache);
bm_edgering_pair_store_free(lpair, interp_mode);
+ change = true;
}
else {
BMO_error_raise(bm, op, BMERR_INVALID_SELECTION,
@@ -1217,6 +1217,7 @@ void bmo_subdivide_edgering_exec(BMesh *bm, BMOperator *op)
bm_edgering_pair_ringsubd(bm, lpair, el_store_a, el_store_b,
interp_mode, cuts, smooth, falloff_cache);
bm_edgering_pair_store_free(lpair, interp_mode);
+ change = true;
}
BLI_assert(bm_verts_tag_count(bm) == 0);
@@ -1229,6 +1230,6 @@ cleanup:
/* flag output */
if (change) {
- BMO_slot_buffer_flag_enable(bm, op->slots_out, "faces.out", BM_FACE, FACE_OUT);
+ BMO_slot_buffer_from_enabled_flag(bm, op, op->slots_out, "faces.out", BM_FACE, FACE_OUT);
}
}
diff --git a/source/blender/bmesh/operators/bmo_utils.c b/source/blender/bmesh/operators/bmo_utils.c
index 2a0a7864499..8b8cab9d881 100644
--- a/source/blender/bmesh/operators/bmo_utils.c
+++ b/source/blender/bmesh/operators/bmo_utils.c
@@ -32,8 +32,8 @@
#include "DNA_meshdata_types.h"
#include "BLI_math.h"
-#include "BLI_array.h"
#include "BLI_heap.h"
+#include "BLI_alloca.h"
#include "BKE_customdata.h"
@@ -55,9 +55,15 @@ void bmo_transform_exec(BMesh *UNUSED(bm), BMOperator *op)
{
BMOIter iter;
BMVert *v;
- float mat[4][4];
+ float mat[4][4], mat_space[4][4], imat_space[4][4];
BMO_slot_mat4_get(op->slots_in, "matrix", mat);
+ BMO_slot_mat4_get(op->slots_in, "space", mat_space);
+
+ if (!is_zero_m4(mat_space)) {
+ invert_m4_m4(imat_space, mat_space);
+ mul_serie_m4(mat, imat_space, mat, mat_space, NULL, NULL, NULL, NULL, NULL);
+ }
BMO_ITER (v, &iter, op->slots_in, "verts", BM_VERT) {
mul_m4_v3(mat, v->co);
@@ -73,7 +79,7 @@ void bmo_translate_exec(BMesh *bm, BMOperator *op)
unit_m4(mat);
copy_v3_v3(mat[3], vec);
- BMO_op_callf(bm, op->flag, "transform matrix=%m4 verts=%s", mat, op, "verts");
+ BMO_op_callf(bm, op->flag, "transform matrix=%m4 space=%s verts=%s", mat, op, "space", op, "verts");
}
void bmo_scale_exec(BMesh *bm, BMOperator *op)
@@ -87,25 +93,19 @@ void bmo_scale_exec(BMesh *bm, BMOperator *op)
mat[1][1] = vec[1];
mat[2][2] = vec[2];
- BMO_op_callf(bm, op->flag, "transform matrix=%m3 verts=%s", mat, op, "verts");
+ BMO_op_callf(bm, op->flag, "transform matrix=%m3 space=%s verts=%s", mat, op, "space", op, "verts");
}
void bmo_rotate_exec(BMesh *bm, BMOperator *op)
{
- float vec[3];
-
- BMO_slot_vec_get(op->slots_in, "cent", vec);
-
- /* there has to be a proper matrix way to do this, but
- * this is how editmesh did it and I'm too tired to think
- * through the math right now. */
- mul_v3_fl(vec, -1.0f);
- BMO_op_callf(bm, op->flag, "translate verts=%s vec=%v", op, "verts", vec);
+ float center[3];
+ float mat[4][4];
- BMO_op_callf(bm, op->flag, "transform matrix=%s verts=%s", op, "matrix", op, "verts");
+ BMO_slot_vec_get(op->slots_in, "cent", center);
+ BMO_slot_mat4_get(op->slots_in, "matrix", mat);
+ transform_pivot_set_m4(mat, center);
- mul_v3_fl(vec, -1.0f);
- BMO_op_callf(bm, op->flag, "translate verts=%s vec=%v", op, "verts", vec);
+ BMO_op_callf(bm, op->flag, "transform matrix=%m4 space=%s verts=%s", mat, op, "space", op, "verts");
}
void bmo_reverse_faces_exec(BMesh *bm, BMOperator *op)
diff --git a/source/blender/bmesh/operators/bmo_wireframe.c b/source/blender/bmesh/operators/bmo_wireframe.c
index fc2e1bbaf3e..c07e2c3bbf2 100644
--- a/source/blender/bmesh/operators/bmo_wireframe.c
+++ b/source/blender/bmesh/operators/bmo_wireframe.c
@@ -177,7 +177,7 @@ void bmo_wireframe_exec(BMesh *bm, BMOperator *op)
/* will over-alloc, but makes for easy lookups by index to keep aligned */
BMVert **verts_boundary = use_boundary ?
- MEM_mallocN(sizeof(BMVert **) * totvert_orig, __func__) : NULL;
+ MEM_mallocN(sizeof(BMVert *) * totvert_orig, __func__) : NULL;
float *verts_relfac = use_relative_offset ?
MEM_mallocN(sizeof(float) * totvert_orig, __func__) : NULL;
@@ -250,7 +250,7 @@ void bmo_wireframe_exec(BMesh *bm, BMOperator *op)
BM_mesh_elem_hflag_disable_all(bm, BM_VERT, BM_ELEM_TAG, false);
}
- verts_loop = MEM_mallocN(sizeof(BMVert **) * verts_loop_tot, __func__);
+ verts_loop = MEM_mallocN(sizeof(BMVert *) * verts_loop_tot, __func__);
verts_loop_tot = 0; /* count up again */
BMO_ITER (f_src, &oiter, op->slots_in, "faces", BM_FACE) {
diff --git a/source/blender/bmesh/tools/BME_bevel.c b/source/blender/bmesh/tools/BME_bevel.c
deleted file mode 100644
index ba553e2f763..00000000000
--- a/source/blender/bmesh/tools/BME_bevel.c
+++ /dev/null
@@ -1,1160 +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) 2004 Blender Foundation.
- * All rights reserved.
- *
- * The Original Code is: all of this file.
- *
- * Contributor(s): Geoffrey Bantle and Levi Schooley.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-#include <math.h>
-
-#include "MEM_guardedalloc.h"
-
-#include "DNA_listBase.h"
-#include "DNA_meshdata_types.h"
-#include "DNA_mesh_types.h"
-
-#include "BLI_math.h"
-#include "BLI_blenlib.h"
-#include "BLI_ghash.h"
-#include "BLI_memarena.h"
-
-#include "BKE_editmesh.h"
-#include "BKE_bmesh.h"
-
-#include "bmesh.h"
-#include "intern/bmesh_private.h"
-
-/* BMESH_TODO
- *
- * Date: 2011-11-24 06:25
- * Sender: Andrew Wiggin
- * Status update: I have code changes to actually make basic bevel modifier work. The things that still need to be done:
- * - clean up the changes
- * - get bevel by weight and bevel by angles working for vertex only bevel.
- * - the code uses adaptations of a couple of bmesh APIs,
- * that work a little differently. for example, a join faces that doesn't just create a new face and then delete the
- * original two faces and all associated loops, it extends one of the original faces to cover all the original loops
- * (except for the loop on the join edge which is of course deleted). the bevel code currently requires this because it
- * expects to be able to continue walking loop lists and doesn't like for loops to be deleted out from under it
- * while working...
- * but bmesh APIs don't do it this way because it makes it trickier to manage the interp during these operations,
- * so I need to decide what to do in these cases.
- */
-
-/* BMESH_TODO - resolve this */
-#define BMESH_263_VERT_BEVEL_WORKAROUND
-
-/* ------- Bevel code starts here -------- */
-
-static BME_TransData_Head *BME_init_transdata(int bufsize)
-{
- BME_TransData_Head *td;
-
- td = MEM_callocN(sizeof(BME_TransData_Head), "BM transdata header");
- td->gh = BLI_ghash_ptr_new("BME_init_transdata gh");
- td->ma = BLI_memarena_new(bufsize, "BME_TransData arena");
- BLI_memarena_use_calloc(td->ma);
-
- return td;
-}
-
-void BME_free_transdata(BME_TransData_Head *td)
-{
- BLI_ghash_free(td->gh, NULL, NULL);
- BLI_memarena_free(td->ma);
- MEM_freeN(td);
-}
-
-static BME_TransData *BME_assign_transdata(BME_TransData_Head *td, BMesh *bm, BMVert *v,
- float *co, float *org, float *vec, float *loc,
- float factor, float weight, float maxfactor, float *max)
-{
- BME_TransData *vtd;
- int is_new = false;
-
- if (v == NULL) {
- return NULL;
- }
-
- if ((vtd = BLI_ghash_lookup(td->gh, v)) == NULL && bm != NULL) {
- vtd = BLI_memarena_alloc(td->ma, sizeof(*vtd));
- BLI_ghash_insert(td->gh, v, vtd);
- td->len++;
- is_new = true;
- }
-
- vtd->bm = bm;
- vtd->v = v;
-
- if (co != NULL) {
- copy_v3_v3(vtd->co, co);
- }
-
- if (org == NULL && is_new) {
- copy_v3_v3(vtd->org, v->co); /* default */
- }
- else if (org != NULL) {
- copy_v3_v3(vtd->org, org);
- }
-
- if (vec != NULL) {
- copy_v3_v3(vtd->vec, vec);
- normalize_v3(vtd->vec);
- }
-
- vtd->loc = loc;
-
- vtd->factor = factor;
- vtd->weight = weight;
- vtd->maxfactor = maxfactor;
- vtd->max = max;
-
- return vtd;
-}
-
-BME_TransData *BME_get_transdata(BME_TransData_Head *td, BMVert *v)
-{
- BME_TransData *vtd;
- vtd = BLI_ghash_lookup(td->gh, v);
- return vtd;
-}
-
-/* a hack (?) to use the transdata memarena to allocate floats for use with the max limits */
-static float *BME_new_transdata_float(BME_TransData_Head *td)
-{
- return BLI_memarena_alloc(td->ma, sizeof(float));
-}
-
-/* ported from before bmesh merge into trunk (was called)
- * problem with this is it creates 2 vert faces */
-static void BME_Bevel_Dissolve_Disk(BMesh *bm, BMVert *v)
-{
- BMFace *f;
- BMEdge *e;
- bool done;
-
- if (v->e) {
- done = false;
- while (!done) {
- done = true;
- e = v->e; /*loop the edge looking for a edge to dissolve*/
- do {
- f = NULL;
- if (BM_edge_is_manifold(e)) {
- f = bmesh_jfke(bm, e->l->f, e->l->radial_next->f, e);
- }
- if (f) {
- done = false;
- break;
- }
- e = bmesh_disk_edge_next(e, v);
- } while (e != v->e);
- }
- BM_vert_collapse_edge(bm, v->e, v, true);
- // bmesh_jekv(bm, v->e, v, false);
- }
-}
-
-static int BME_bevel_is_split_vert(BMesh *bm, BMLoop *l)
-{
- /* look for verts that have already been added to the edge when
- * beveling other polys; this can be determined by testing the
- * vert and the edges around it for originality
- */
- if (!BMO_elem_flag_test(bm, l->v, BME_BEVEL_ORIG) &&
- BMO_elem_flag_test(bm, l->e, BME_BEVEL_ORIG) &&
- BMO_elem_flag_test(bm, l->prev->e, BME_BEVEL_ORIG))
- {
- return 1;
- }
- return 0;
-}
-
-/* get a vector, vec, that points from v1->co to wherever makes sense to
- * the bevel operation as a whole based on the relationship between v1 and v2
- * (won't necessarily be a vec from v1->co to v2->co, though it probably will be);
- * the return value is -1 for failure, 0 if we used vert co's, and 1 if we used transform origins */
-static int BME_bevel_get_vec(float vec[3], BMVert *v1, BMVert *v2, BME_TransData_Head *td)
-{
- BME_TransData *vtd1, *vtd2;
-
- vtd1 = BME_get_transdata(td, v1);
- vtd2 = BME_get_transdata(td, v2);
- if (!vtd1 || !vtd2) {
- //printf("BME_bevel_get_vec() got called without proper BME_TransData\n");
- return -1;
- }
-
- /* compare the transform origins to see if we can use the vert co's;
- * if they belong to different origins, then we will use the origins to determine
- * the vector */
- if (compare_v3v3(vtd1->org, vtd2->org, 0.000001f)) {
- sub_v3_v3v3(vec, v2->co, v1->co);
- if (len_v3(vec) < 0.000001f) {
- zero_v3(vec);
- }
- return 0;
- }
- else {
- sub_v3_v3v3(vec, vtd2->org, vtd1->org);
- if (len_v3(vec) < 0.000001f) {
- zero_v3(vec);
- }
- return 1;
- }
-}
-
-/* "Projects" a vector perpendicular to vec2 against vec1, such that
- * the projected vec1 + vec2 has a min distance of 1 from the "edge" defined by vec2.
- * note: the direction, is_forward, is used in conjunction with up_vec to determine
- * whether this is a convex or concave corner. If it is a concave corner, it will
- * be projected "backwards." If vec1 is before vec2, is_forward should be 0 (we are projecting backwards).
- * vec1 is the vector to project onto (expected to be normalized)
- * vec2 is the direction of projection (pointing away from vec1)
- * up_vec is used for orientation (expected to be normalized)
- * returns the length of the projected vector that lies along vec1 */
-static float BME_bevel_project_vec(float *vec1, float *vec2, float *up_vec,
- int is_forward, BME_TransData_Head *UNUSED(td))
-{
- float factor, vec3[3], tmp[3], c1, c2;
-
- cross_v3_v3v3(tmp, vec1, vec2);
- normalize_v3(tmp);
- factor = dot_v3v3(up_vec, tmp);
- if ((factor > 0 && is_forward) || (factor < 0 && !is_forward)) {
- cross_v3_v3v3(vec3, vec2, tmp); /* hmm, maybe up_vec should be used instead of tmp */
- }
- else {
- cross_v3_v3v3(vec3, tmp, vec2); /* hmm, maybe up_vec should be used instead of tmp */
- }
- normalize_v3(vec3);
- c1 = dot_v3v3(vec3, vec1);
- c2 = dot_v3v3(vec1, vec1);
- if (fabsf(c1) < 0.000001f || fabsf(c2) < 0.000001f) {
- factor = 0.0f;
- }
- else {
- factor = c2 / c1;
- }
-
- return factor;
-}
-
-/* BME_bevel_split_edge() is the main math work-house; its responsibilities are:
- * using the vert and the loop passed, get or make the split vert, set its coordinates
- * and transform properties, and set the max limits.
- * Finally, return the split vert. */
-static BMVert *BME_bevel_split_edge(BMesh *bm, BMVert *v, BMVert *v1, BMLoop *l,
- float *up_vec, float value, BME_TransData_Head *td)
-{
- BME_TransData *vtd, *vtd1, *vtd2;
- BMVert *sv, *v2, *v3, *ov;
- BMLoop *lv1, *lv2;
- BMEdge *ne, *e1, *e2;
- float maxfactor, scale, len, dis, vec1[3], vec2[3], t_up_vec[3];
- int is_edge, forward, is_split_vert;
-
- /* ov, vtd2, and is_split_vert are set but UNUSED */
- (void)ov, (void)vtd2, (void)is_split_vert;
-
- if (l == NULL) {
- /* what you call operator overloading in C :)
- * I wanted to use the same function for both wire edges and poly loops
- * so... here we walk around edges to find the needed verts */
- forward = 1;
- is_split_vert = 0;
- if (v->e == NULL) {
- //printf("We can't split a loose vert's edge!\n");
- return NULL;
- }
- e1 = v->e; /* we just use the first two edges */
- e2 = bmesh_disk_edge_next(v->e, v);
- if (e1 == e2) {
- //printf("You need at least two edges to use BME_bevel_split_edge()\n");
- return NULL;
- }
- v2 = BM_edge_other_vert(e1, v);
- v3 = BM_edge_other_vert(e2, v);
- if (v1 != v2 && v1 != v3) {
- //printf("Error: more than 2 edges in v's disk cycle, or v1 does not share an edge with v\n");
- return NULL;
- }
- if (v1 == v2) {
- v2 = v3;
- }
- else {
- e1 = e2;
- }
- ov = BM_edge_other_vert(e1, v);
- sv = BM_edge_split(bm, e1, v, &ne, 0.0f);
- //BME_data_interp_from_verts(bm, v, ov, sv, 0.25); /* this is technically wrong.. */
- //BME_data_interp_from_faceverts(bm, v, ov, sv, 0.25);
- //BME_data_interp_from_faceverts(bm, ov, v, sv, 0.25);
- BME_assign_transdata(td, bm, sv, sv->co, sv->co, NULL, sv->co, 0, -1, -1, NULL); /* quick default */
- BMO_elem_flag_enable(bm, sv, BME_BEVEL_BEVEL);
- BMO_elem_flag_enable(bm, ne, BME_BEVEL_ORIG); /* mark edge as original, even though it isn't */
- BME_bevel_get_vec(vec1, v1, v, td);
- BME_bevel_get_vec(vec2, v2, v, td);
- cross_v3_v3v3(t_up_vec, vec1, vec2);
- normalize_v3(t_up_vec);
- up_vec = t_up_vec;
- }
- else {
- /* establish loop direction */
- if (l->v == v) {
- forward = 1;
- lv1 = l->next;
- lv2 = l->prev;
- v1 = l->next->v;
- v2 = l->prev->v;
- }
- else if (l->next->v == v) {
- forward = 0;
- lv1 = l;
- lv2 = l->next->next;
- v1 = l->v;
- v2 = l->next->next->v;
- }
- else {
- //printf("ERROR: BME_bevel_split_edge() - v must be adjacent to l\n");
- return NULL;
- }
-
- if (BME_bevel_is_split_vert(bm, lv1)) {
- is_split_vert = 1;
- sv = v1;
- v1 = forward ? l->next->next->v : l->prev->v;
- }
- else {
- is_split_vert = 0;
- ov = BM_edge_other_vert(l->e, v);
- sv = BM_edge_split(bm, l->e, v, &ne, 0.0f);
- //BME_data_interp_from_verts(bm, v, ov, sv, 0.25); /* this is technically wrong.. */
- //BME_data_interp_from_faceverts(bm, v, ov, sv, 0.25);
- //BME_data_interp_from_faceverts(bm, ov, v, sv, 0.25);
- BME_assign_transdata(td, bm, sv, sv->co, sv->co, NULL, sv->co, 0, -1, -1, NULL); /* quick default */
- BMO_elem_flag_enable(bm, sv, BME_BEVEL_BEVEL);
- BMO_elem_flag_enable(bm, ne, BME_BEVEL_ORIG); /* mark edge as original, even though it isn't */
- }
-
- if (BME_bevel_is_split_vert(bm, lv2)) {
- v2 = forward ? lv2->prev->v : lv2->next->v;
- }
- }
-
- is_edge = BME_bevel_get_vec(vec1, v, v1, td); /* get the vector we will be projecting onto */
- BME_bevel_get_vec(vec2, v, v2, td); /* get the vector we will be projecting parallel to */
- len = normalize_v3(vec1);
-
- vtd = BME_get_transdata(td, sv);
- vtd1 = BME_get_transdata(td, v);
- vtd2 = BME_get_transdata(td, v1);
-
- if (vtd1->loc == NULL) {
- /* this is a vert with data only for calculating initial weights */
- if (vtd1->weight < 0.0f) {
- vtd1->weight = 0.0f;
- }
- scale = vtd1->weight / vtd1->factor;
- if (!vtd1->max) {
- vtd1->max = BME_new_transdata_float(td);
- *vtd1->max = -1;
- }
- }
- else {
- scale = vtd1->weight;
- }
- vtd->max = vtd1->max;
-
- if (is_edge && vtd1->loc != NULL) {
- maxfactor = vtd1->maxfactor;
- }
- else {
- maxfactor = scale * BME_bevel_project_vec(vec1, vec2, up_vec, forward, td);
- if (vtd->maxfactor > 0 && vtd->maxfactor < maxfactor) {
- maxfactor = vtd->maxfactor;
- }
- }
-
- dis = BMO_elem_flag_test(bm, v1, BME_BEVEL_ORIG) ? len / 3 : len / 2;
- if (is_edge || dis > maxfactor * value) {
- dis = maxfactor * value;
- }
- madd_v3_v3v3fl(sv->co, v->co, vec1, dis);
- sub_v3_v3v3(vec1, sv->co, vtd1->org);
- dis = normalize_v3(vec1);
- BME_assign_transdata(td, bm, sv, vtd1->org, vtd1->org, vec1, sv->co, dis, scale, maxfactor, vtd->max);
-
- return sv;
-}
-
-#if 0 /* UNUSED */
-static float BME_bevel_set_max(BMVert *v1, BMVert *v2, float value, BME_TransData_Head *td)
-{
- BME_TransData *vtd1, *vtd2;
- float max, fac1, fac2, vec1[3], vec2[3], vec3[3];
-
- BME_bevel_get_vec(vec1, v1, v2, td);
- vtd1 = BME_get_transdata(td, v1);
- vtd2 = BME_get_transdata(td, v2);
-
- if (vtd1->loc == NULL) {
- fac1 = 0;
- }
- else {
- copy_v3_v3(vec2, vtd1->vec);
- mul_v3_fl(vec2, vtd1->factor);
- if (dot_v3v3(vec1, vec1)) {
- project_v3_v3v3(vec2, vec2, vec1);
- fac1 = len_v3(vec2) / value;
- }
- else {
- fac1 = 0;
- }
- }
-
- if (vtd2->loc == NULL) {
- fac2 = 0;
- }
- else {
- copy_v3_v3(vec3, vtd2->vec);
- mul_v3_fl(vec3, vtd2->factor);
- if (dot_v3v3(vec1, vec1)) {
- project_v3_v3v3(vec2, vec3, vec1);
- fac2 = len_v3(vec2) / value;
- }
- else {
- fac2 = 0;
- }
- }
-
- if (fac1 || fac2) {
- max = len_v3(vec1) / (fac1 + fac2);
- if (vtd1->max && (*vtd1->max < 0 || max < *vtd1->max)) {
- *vtd1->max = max;
- }
- if (vtd2->max && (*vtd2->max < 0 || max < *vtd2->max)) {
- *vtd2->max = max;
- }
- }
- else {
- max = -1;
- }
-
- return max;
-}
-#endif
-
-#if 0 /* UNUSED */
-static BMVert *BME_bevel_wire(BMesh *bm, BMVert *v, float value, int res, int UNUSED(options), BME_TransData_Head *td)
-{
- BMVert *ov1, *ov2, *v1, *v2;
-
- ov1 = BM_edge_other_vert(v->e, v);
- ov2 = BM_edge_other_vert(bmesh_disk_edge_next(v->e, v), v);
-
- /* split the edges */
- v1 = BME_bevel_split_edge(bm, v, ov1, NULL, NULL, value, td);
- BMO_elem_flag_enable(bm, v1, BME_BEVEL_NONMAN);
- v2 = BME_bevel_split_edge(bm, v, ov2, NULL, NULL, value, td);
- BMO_elem_flag_enable(bm, v2, BME_BEVEL_NONMAN);
-
- if (value > 0.5) {
- BME_bevel_set_max(v1, ov1, value, td);
- BME_bevel_set_max(v2, ov2, value, td);
- }
-
- /* remove the original vert */
- if (res) {
- /* bmesh_jekv; */
-
- //void BM_vert_collapse_faces(BMesh *bm, BMEdge *ke, BMVert *kv, float fac, int calcnorm) {
- //hrm, why is there a fac here? it just removes a vert
- BM_vert_collapse_edge(bm, v->e, v);
- }
-
- return v1;
-}
-#endif
-
-static BMLoop *BME_bevel_edge(BMesh *bm, BMLoop *l, float value, int UNUSED(options),
- float *up_vec, BME_TransData_Head *td)
-{
- BMVert *v1, *v2, *kv;
- BMLoop *kl = NULL, *nl;
- BMEdge *e, *ke, *se;
- BMFace *f, *jf;
-
- f = l->f;
- e = l->e;
-
- /* sanity check */
- if (!BMO_elem_flag_test(bm, l->e, BME_BEVEL_BEVEL) &&
- (BMO_elem_flag_test(bm, l->v, BME_BEVEL_BEVEL) || BMO_elem_flag_test(bm, l->next->v, BME_BEVEL_BEVEL)))
- {
- return l;
- }
-
- /* checks and operations for prev edge */
- /* first, check to see if this edge was inset previously */
- if (!BMO_elem_flag_test(bm, l->prev->e, BME_BEVEL_ORIG) &&
- !BMO_elem_flag_test(bm, l->v, BME_BEVEL_NONMAN))
- {
- kl = l->prev->radial_next;
- kl = (kl->v == l->v) ? kl->prev : kl->next;
- kv = l->v;
- }
- else {
- kv = NULL;
- }
- /* get/make the first vert to be used in SFME */
- if (BMO_elem_flag_test(bm, l->v, BME_BEVEL_NONMAN)) {
- v1 = l->v;
- }
- else { /* we'll need to split the previous edge */
- v1 = BME_bevel_split_edge(bm, l->v, NULL, l->prev, up_vec, value, td);
- }
- /* if we need to clean up geometry... */
- if (kv) {
- se = l->next->e;
- jf = NULL;
- if (kl->v == kv) {
- BM_face_split(bm, kl->f, kl->prev->v, kl->next->v, &nl, kl->prev->e, true);
- ke = kl->e;
- /* BMESH-TODO: jfke doesn't handle customdata */
- jf = bmesh_jfke(bm, kl->prev->radial_next->f, kl->f, kl->prev->e);
- BM_vert_collapse_edge(bm, ke, kv, false);
- }
- else {
- BM_face_split(bm, kl->f, kl->next->next->v, kl->v, &nl, kl->next->e, true);
- ke = kl->e;
- /* BMESH-TODO: jfke doesn't handle customdata */
- jf = bmesh_jfke(bm, kl->next->radial_next->f, kl->f, kl->next->e);
- BM_vert_collapse_edge(bm, ke, kv, false);
- }
- /* find saved loop pointer */
- l = se->l;
- while (l->f != jf) {
- l = l->radial_next;
- BLI_assert(l != se->l);
- }
- l = l->prev;
- }
-
- /* checks and operations for the next edge */
- /* first, check to see if this edge was inset previously */
- if (!BMO_elem_flag_test(bm, l->next->e, BME_BEVEL_ORIG) &&
- !BMO_elem_flag_test(bm, l->next->v, BME_BEVEL_NONMAN))
- {
- kl = l->next->radial_next;
- kl = (kl->v == l->next->v) ? kl->prev : kl->next;
- kv = l->next->v;
- }
- else {
- kv = NULL;
- }
- /* get/make the second vert to be used in SFME */
- if (BMO_elem_flag_test(bm, l->next->v, BME_BEVEL_NONMAN)) {
- v2 = l->next->v;
- }
- else { /* we'll need to split the next edge */
- v2 = BME_bevel_split_edge(bm, l->next->v, NULL, l->next, up_vec, value, td);
- }
- /* if we need to clean up geometry... */
- if (kv) {
- se = l->e;
- jf = NULL;
- if (kl->v == kv) {
- BM_face_split(bm, kl->f, kl->prev->v, kl->next->v, &nl, kl->prev->e, true);
- ke = kl->e;
- /* BMESH-TODO: jfke doesn't handle customdata */
- jf = bmesh_jfke(bm, kl->prev->radial_next->f, kl->f, kl->prev->e);
- BM_vert_collapse_edge(bm, ke, kv, false);
- }
- else {
- BM_face_split(bm, kl->f, kl->next->next->v, kl->v, &nl, kl->next->e, true);
- ke = kl->e;
- /* BMESH-TODO: jfke doesn't handle customdata */
- jf = bmesh_jfke(bm, kl->next->radial_next->f, kl->f, kl->next->e);
- BM_vert_collapse_edge(bm, ke, kv, false);
- }
- /* find saved loop pointer */
- l = se->l;
- while (l->f != jf) {
- l = l->radial_next;
- BLI_assert(l != se->l);
- }
- }
-
- if (!BMO_elem_flag_test(bm, v1, BME_BEVEL_NONMAN) || !BMO_elem_flag_test(bm, v2, BME_BEVEL_NONMAN)) {
- BM_face_split(bm, f, v2, v1, &l, e, true);
- BMO_elem_flag_enable(bm, l->e, BME_BEVEL_BEVEL);
- l = l->radial_next;
- }
-
- if (l->f != f) {
- //printf("Whoops! You got something out of order in BME_bevel_edge()!\n");
- }
-
- return l;
-}
-
-static BMLoop *BME_bevel_vert(BMesh *bm, BMLoop *l, float value, int UNUSED(options),
- float up_vec[3], BME_TransData_Head *td)
-{
- BMVert *v1, *v2;
- /* BMFace *f; */ /* UNUSED */
-
- /* get/make the first vert to be used in SFME */
- /* may need to split the previous edge */
- v1 = BME_bevel_split_edge(bm, l->v, NULL, l->prev, up_vec, value, td);
-
- /* get/make the second vert to be used in SFME */
- /* may need to split this edge (so move l) */
- l = l->prev;
- v2 = BME_bevel_split_edge(bm, l->next->v, NULL, l->next, up_vec, value, td);
- l = l->next->next;
-
- /* "cut off" this corner */
- /* f = */ BM_face_split(bm, l->f, v2, v1, NULL, l->e, true);
-
- return l;
-}
-
-/*
- * BME_bevel_poly
- *
- * Polygon inset tool:
- *
- * Insets a polygon/face based on the flagss of its vertices
- * and edges. Used by the bevel tool only, for now.
- * The parameter "value" is the distance to inset (should be negative).
- * The parameter "options" is not currently used.
- *
- * Returns -
- * A BMFace pointer to the resulting inner face.
- */
-static BMFace *BME_bevel_poly(BMesh *bm, BMFace *f, float value, int options, BME_TransData_Head *td)
-{
- BMLoop *l /*, *o */;
- BME_TransData *vtd1, *vtd2;
- float up_vec[3], vec1[3], vec2[3], vec3[3], fac1, fac2, max = -1;
- int len, i;
- BMIter iter;
-
- zero_v3(up_vec);
-
- /* find a good normal for this face (there's better ways, I'm sure) */
- BM_ITER_ELEM (l, &iter, f, BM_LOOPS_OF_FACE) {
-#ifdef BMESH_263_VERT_BEVEL_WORKAROUND
- add_newell_cross_v3_v3v3(up_vec, l->prev->v->co, l->v->co);
-#else
- BME_bevel_get_vec(vec1, l->v, l->next->v, td);
- BME_bevel_get_vec(vec2, l->prev->v, l->v, td);
- cross_v3_v3v3(vec3, vec2, vec1);
- add_v3_v3(up_vec, vec3);
-
-#endif
- }
- normalize_v3(up_vec);
-
- /* Can't use a BM_LOOPS_OF_FACE iterator here, because the loops are being modified
- * and so the end condition will never hi */
- for (l = BM_FACE_FIRST_LOOP(f)->prev, i = 0, len = f->len; i < len; i++, l = l->next) {
- if (BMO_elem_flag_test(bm, l->e, BME_BEVEL_BEVEL) && BMO_elem_flag_test(bm, l->e, BME_BEVEL_ORIG)) {
- max = 1.0f;
- l = BME_bevel_edge(bm, l, value, options, up_vec, td);
- }
- else if (BMO_elem_flag_test(bm, l->v, BME_BEVEL_BEVEL) &&
- BMO_elem_flag_test(bm, l->v, BME_BEVEL_ORIG) &&
- !BMO_elem_flag_test(bm, l->prev->e, BME_BEVEL_BEVEL))
- {
- /* avoid making double vertices [#33438] */
- BME_TransData *vtd;
- vtd = BME_get_transdata(td, l->v);
- if (vtd->weight == 0.0f) {
- BMO_elem_flag_disable(bm, l->v, BME_BEVEL_BEVEL);
- }
- else {
- max = 1.0f;
- l = BME_bevel_vert(bm, l, value, options, up_vec, td);
- }
- }
- }
-
- f = l->f;
-
- /* max pass */
- if (value > 0.5f && max > 0.0f) {
- max = -1;
- BM_ITER_ELEM (l, &iter, f, BM_LOOPS_OF_FACE) {
- if (BMO_elem_flag_test(bm, l->e, BME_BEVEL_BEVEL) || BMO_elem_flag_test(bm, l->e, BME_BEVEL_ORIG)) {
- BME_bevel_get_vec(vec1, l->v, l->next->v, td);
- vtd1 = BME_get_transdata(td, l->v);
- vtd2 = BME_get_transdata(td, l->next->v);
- if (vtd1->loc == NULL) {
- fac1 = 0;
- }
- else {
- copy_v3_v3(vec2, vtd1->vec);
- mul_v3_fl(vec2, vtd1->factor);
- if (dot_v3v3(vec1, vec1)) {
- project_v3_v3v3(vec2, vec2, vec1);
- fac1 = len_v3(vec2) / value;
- }
- else {
- fac1 = 0;
- }
- }
- if (vtd2->loc == NULL) {
- fac2 = 0;
- }
- else {
- copy_v3_v3(vec3, vtd2->vec);
- mul_v3_fl(vec3, vtd2->factor);
- if (dot_v3v3(vec1, vec1)) {
- project_v3_v3v3(vec2, vec3, vec1);
- fac2 = len_v3(vec2) / value;
- }
- else {
- fac2 = 0;
- }
- }
- if (fac1 || fac2) {
- max = len_v3(vec1) / (fac1 + fac2);
- if (vtd1->max && (*vtd1->max < 0 || max < *vtd1->max)) {
- *vtd1->max = max;
- }
- if (vtd2->max && (*vtd2->max < 0 || max < *vtd2->max)) {
- *vtd2->max = max;
- }
- }
- }
- }
- }
-
- /* return l->f; */
- return NULL;
-}
-
-static float BME_bevel_get_angle(BMEdge *e, BMVert *v)
-{
- BMVert *v1, *v2;
- BMLoop *l1, *l2;
- float vec1[3], vec2[3], vec3[3], vec4[3];
-
- l1 = e->l;
- l2 = e->l->radial_next;
- if (l1->v == v) {
- v1 = l1->prev->v;
- v2 = l1->next->v;
- }
- else {
- v1 = l1->next->next->v;
- v2 = l1->v;
- }
- sub_v3_v3v3(vec1, v1->co, v->co);
- sub_v3_v3v3(vec2, v2->co, v->co);
- cross_v3_v3v3(vec3, vec1, vec2);
-
- l1 = l2;
- if (l1->v == v) {
- v1 = l1->prev->v;
- v2 = l1->next->v;
- }
- else {
- v1 = l1->next->next->v;
- v2 = l1->v;
- }
- sub_v3_v3v3(vec1, v1->co, v->co);
- sub_v3_v3v3(vec2, v2->co, v->co);
- cross_v3_v3v3(vec4, vec2, vec1);
-
- normalize_v3(vec3);
- normalize_v3(vec4);
-
- return dot_v3v3(vec3, vec4);
-}
-
-static float BME_bevel_get_angle_vert(BMVert *v)
-{
- BMIter iter;
- BMLoop *l;
- float n[3];
- float n_tmp[3];
- float angle_diff = 0.0f;
- float tot_angle = 0.0f;
-
-
- BM_ITER_ELEM (l, &iter, v, BM_LOOPS_OF_VERT) {
- const float angle = BM_loop_calc_face_angle(l);
- tot_angle += angle;
- BM_loop_calc_face_normal(l, n_tmp);
- madd_v3_v3fl(n, n_tmp, angle);
- }
- normalize_v3(n);
-
- BM_ITER_ELEM (l, &iter, v, BM_LOOPS_OF_VERT) {
- /* could cache from before */
- BM_loop_calc_face_normal(l, n_tmp);
- angle_diff += angle_normalized_v3v3(n, n_tmp) * BM_loop_calc_face_angle(l);
- }
-
- /* return cosf(angle_diff + 0.001f); */ /* compare with dot product */
- return (angle_diff / tot_angle) * (float)(M_PI / 2.0);
-}
-
-static void BME_bevel_add_vweight(BME_TransData_Head *td, BMesh *bm, BMVert *v, float weight, float factor, int options)
-{
- BME_TransData *vtd;
-
- if (BMO_elem_flag_test(bm, v, BME_BEVEL_NONMAN)) {
- return;
- }
-
- BMO_elem_flag_enable(bm, v, BME_BEVEL_BEVEL);
- if ((vtd = BME_get_transdata(td, v))) {
- if (options & BME_BEVEL_EMIN) {
- vtd->factor = 1.0;
- if (vtd->weight < 0 || weight < vtd->weight) {
- vtd->weight = weight;
- }
- }
- else if (options & BME_BEVEL_EMAX) {
- vtd->factor = 1.0;
- if (weight > vtd->weight) {
- vtd->weight = weight;
- }
- }
- else if (vtd->weight < 0.0f) {
- vtd->factor = factor;
- vtd->weight = weight;
- }
- else {
- vtd->factor += factor; /* increment number of edges with weights (will be averaged) */
- vtd->weight += weight; /* accumulate all the weights */
- }
- }
- else {
- /* we'll use vtd->loc == NULL to mark that this vert is not moving */
- vtd = BME_assign_transdata(td, bm, v, v->co, NULL, NULL, NULL, factor, weight, -1, NULL);
- }
-}
-
-static void bevel_init_verts(BMesh *bm, int options, float angle, BME_TransData_Head *td)
-{
- BMVert *v;
- BMIter iter;
- float weight;
- /* const float threshold = (options & BME_BEVEL_ANGLE) ? cosf(angle + 0.001) : 0.0f; */ /* UNUSED */
-
- BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) {
- weight = 0.0f;
- if (!BMO_elem_flag_test(bm, v, BME_BEVEL_NONMAN)) {
- /* modifiers should not use selection */
- if (options & BME_BEVEL_SELECT) {
- if (BM_elem_flag_test(v, BM_ELEM_SELECT)) {
- weight = 1.0f;
- }
- }
- /* bevel weight NYI */
- else if (options & BME_BEVEL_WEIGHT) {
- weight = BM_elem_float_data_get(&bm->vdata, v, CD_BWEIGHT);
- }
- else if (options & BME_BEVEL_ANGLE) {
- /* dont set weight_v1/weight_v2 here, add direct */
- if (BME_bevel_get_angle_vert(v) > angle) {
- weight = 1.0f;
- }
- }
- else {
- weight = 1.0f;
- }
-
- if (weight > 0.0f) {
- BMO_elem_flag_enable(bm, v, BME_BEVEL_BEVEL);
- BME_assign_transdata(td, bm, v, v->co, v->co, NULL, NULL, 1.0, weight, -1, NULL);
- }
- }
- }
-}
-
-static void bevel_init_edges(BMesh *bm, int options, float angle, BME_TransData_Head *td)
-{
- BMEdge *e;
- int count;
- float weight;
- BMIter iter;
- const float threshold = (options & BME_BEVEL_ANGLE) ? cosf(angle + 0.001f) : 0.0f;
-
- BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) {
- weight = 0.0f;
- if (!BMO_elem_flag_test(bm, e, BME_BEVEL_NONMAN)) {
- if (options & BME_BEVEL_SELECT) {
- if (BM_elem_flag_test(e, BM_ELEM_SELECT)) {
- weight = 1.0f;
- }
- }
- else if (options & BME_BEVEL_WEIGHT) {
- weight = BM_elem_float_data_get(&bm->edata, e, CD_BWEIGHT);
- }
- else if (options & BME_BEVEL_ANGLE) {
- /* dont set weight_v1/weight_v2 here, add direct */
- if (!BMO_elem_flag_test(bm, e->v1, BME_BEVEL_NONMAN) && BME_bevel_get_angle(e, e->v1) < threshold) {
- BMO_elem_flag_enable(bm, e, BME_BEVEL_BEVEL);
- BME_bevel_add_vweight(td, bm, e->v1, 1.0, 1.0, options);
- }
- else {
- BME_bevel_add_vweight(td, bm, e->v1, 0.0, 1.0, options);
- }
- if (!BMO_elem_flag_test(bm, e->v2, BME_BEVEL_NONMAN) && BME_bevel_get_angle(e, e->v2) < threshold) {
- BMO_elem_flag_enable(bm, e, BME_BEVEL_BEVEL);
- BME_bevel_add_vweight(td, bm, e->v2, 1.0, 1.0, options);
- }
- else {
- BME_bevel_add_vweight(td, bm, e->v2, 0.0, 1.0, options);
- }
- }
- else {
- weight = 1.0f;
- }
-
- if (weight > 0.0f) {
- BMO_elem_flag_enable(bm, e, BME_BEVEL_BEVEL);
- BME_bevel_add_vweight(td, bm, e->v1, weight, 1.0, options);
- BME_bevel_add_vweight(td, bm, e->v2, weight, 1.0, options);
- }
- }
- }
-
- /* clean up edges with 2 faces that share more than one edg */
- BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) {
- if (BMO_elem_flag_test(bm, e, BME_BEVEL_BEVEL)) {
- count = BM_face_share_edge_count(e->l->f, e->l->radial_next->f);
- if (count > 1) BMO_elem_flag_disable(bm, e, BME_BEVEL_BEVEL);
- }
- }
-}
-
-static BMesh *BME_bevel_initialize(BMesh *bm, int options,
- int UNUSED(defgrp_index), float angle, BME_TransData_Head *td)
-{
- BMVert *v /*, *v2 */;
- BMEdge *e /*, *curedg */;
- BMFace *f;
- BMIter iter;
- int /* wire, */ len;
-
- /* tag non-manifold geometry */
- BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) {
- BMO_elem_flag_enable(bm, v, BME_BEVEL_ORIG);
- if (v->e) {
- BME_assign_transdata(td, bm, v, v->co, v->co, NULL, NULL, 0, -1, -1, NULL);
- if (!BM_vert_is_manifold(v)) {
- BMO_elem_flag_enable(bm, v, BME_BEVEL_NONMAN);
- }
-
- /* test wire ver */
- len = BM_vert_edge_count(v);
- if (len == 2 && BM_vert_is_wire(v))
- BMO_elem_flag_disable(bm, v, BME_BEVEL_NONMAN);
- }
- else {
- BMO_elem_flag_enable(bm, v, BME_BEVEL_NONMAN);
- }
- }
-
- BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) {
- BMO_elem_flag_enable(bm, e, BME_BEVEL_ORIG);
- if (!(BM_edge_is_boundary(e) || BM_edge_is_manifold(e))) {
- BMO_elem_flag_enable(bm, e->v1, BME_BEVEL_NONMAN);
- BMO_elem_flag_enable(bm, e->v2, BME_BEVEL_NONMAN);
- BMO_elem_flag_enable(bm, e, BME_BEVEL_NONMAN);
- }
- if (BMO_elem_flag_test(bm, e->v1, BME_BEVEL_NONMAN) || BMO_elem_flag_test(bm, e->v2, BME_BEVEL_NONMAN)) {
- BMO_elem_flag_enable(bm, e, BME_BEVEL_NONMAN);
- }
- }
-
- BM_ITER_MESH (f, &iter, bm, BM_FACES_OF_MESH) {
- BMO_elem_flag_enable(bm, f, BME_BEVEL_ORIG);
- }
-
- if (options & BME_BEVEL_VERT) {
- bevel_init_verts(bm, options, angle, td);
- }
- else {
- bevel_init_edges(bm, options, angle, td);
- }
-
- return bm;
-
-}
-
-#if 0
-
-static BMesh *BME_bevel_reinitialize(BMesh *bm)
-{
- BMVert *v;
- BMEdge *e;
- BMFace *f;
- BMIter iter;
-
- BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) {
- BMO_elem_flag_enable(bm, v, BME_BEVEL_ORIG);
- }
- BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) {
- BMO_elem_flag_enable(bm, e, BME_BEVEL_ORIG);
- }
- BM_ITER_MESH (f, &iter, bm, BM_FACES_OF_MESH) {
- BMO_elem_flag_enable(bm, f, BME_BEVEL_ORIG);
- }
- return bm;
-
-}
-
-#endif
-
-/**
- * BME_bevel_mesh
- *
- * Mesh beveling tool:
- *
- * Bevels an entire mesh. It currently uses the flags of
- * its vertices and edges to track topological changes.
- * The parameter "value" is the distance to inset (should be negative).
- * The parameter "options" is not currently used.
- *
- * \return A BMesh pointer to the BM passed as a parameter.
- */
-
-static BMesh *BME_bevel_mesh(BMesh *bm, float value, int UNUSED(res), int options,
- int UNUSED(defgrp_index), BME_TransData_Head *td)
-{
- BMVert *v;
- BMEdge *e, *curedge;
- BMLoop *l, *l2;
- BMFace *f;
- BMIter iter;
-
- /* unsigned int i, len; */
-
- /* bevel poly */
- BM_ITER_MESH (f, &iter, bm, BM_FACES_OF_MESH) {
- if (BMO_elem_flag_test(bm, f, BME_BEVEL_ORIG)) {
- BME_bevel_poly(bm, f, value, options, td);
- }
- }
-
- /* get rid of beveled edge */
- BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) {
- if (BMO_elem_flag_test(bm, e, BME_BEVEL_BEVEL) && BMO_elem_flag_test(bm, e, BME_BEVEL_ORIG)) {
- BM_faces_join_pair(bm, e->l->f, e->l->radial_next->f, e, true);
- }
- }
-
- /* link up corners and cli */
- BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) {
- if (BMO_elem_flag_test(bm, v, BME_BEVEL_ORIG) && BMO_elem_flag_test(bm, v, BME_BEVEL_BEVEL)) {
- curedge = v->e;
- do {
- l = curedge->l;
- l2 = l->radial_next;
- if (l->v != v) l = l->next;
- if (l2->v != v) l2 = l2->next;
- if (l->f->len > 3)
- BM_face_split(bm, l->f, l->next->v, l->prev->v, &l, l->e, true); /* clip this corner off */
- if (l2->f->len > 3)
- BM_face_split(bm, l2->f, l2->next->v, l2->prev->v, &l, l2->e, true); /* clip this corner off */
- curedge = bmesh_disk_edge_next(curedge, v);
- } while (curedge != v->e);
- BME_Bevel_Dissolve_Disk(bm, v);
- }
- }
-
-#ifdef DEBUG
- /* Debug print, remov */
- BM_ITER_MESH (f, &iter, bm, BM_FACES_OF_MESH) {
- if (f->len == 2) {
- printf("%s: warning, 2 edge face\n", __func__);
- }
- }
-#endif
-
- return bm;
-}
-
-BMesh *BME_bevel(BMesh *bm, float value, int res, int options, int defgrp_index, float angle,
- BME_TransData_Head **rtd)
-{
- BMVert *v;
- BMIter iter;
-
- BME_TransData_Head *td;
- BME_TransData *vtd;
- int i;
- double fac = 1.0, d;
-
- td = BME_init_transdata(BLI_MEMARENA_STD_BUFSIZE);
- /* recursion math courtesy of Martin Poirier (theeth) */
- for (i = 0; i < res - 1; i++) {
- if (i == 0) fac += 1.0 / 3.0;
- else fac += 1.0 / (3.0 * i * 2.0);
- }
- d = 1.0 / fac;
-
- BM_mesh_elem_toolflags_ensure(bm);
-
- for (i = 0; i < res || (res == 0 && i == 0); i++) {
- BMO_push(bm, NULL);
- BME_bevel_initialize(bm, options, defgrp_index, angle, td);
- //if (i != 0) BME_bevel_reinitialize(bm);
- bmesh_edit_begin(bm, 0);
- BME_bevel_mesh(bm, (float)d, res, options, defgrp_index, td);
- bmesh_edit_end(bm, 0);
- d /= (i == 0) ? 3.0 : 2.0;
- BMO_pop(bm);
- }
-
- /* interactive preview? */
- if (rtd) {
- *rtd = td;
- return bm;
- }
-
- /* otherwise apply transforms */
- BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) {
- if ((vtd = BME_get_transdata(td, v))) {
- if (vtd->max && (*vtd->max > 0 && value > *vtd->max)) {
- d = *vtd->max;
- }
- else {
- d = value;
- }
- madd_v3_v3v3fl(v->co, vtd->org, vtd->vec, vtd->factor * (float)d);
- }
- }
-
- BME_free_transdata(td);
- return bm;
-}
diff --git a/source/blender/bmesh/tools/bmesh_bevel.c b/source/blender/bmesh/tools/bmesh_bevel.c
index 6431b6b7cf5..02f0251bff2 100644
--- a/source/blender/bmesh/tools/bmesh_bevel.c
+++ b/source/blender/bmesh/tools/bmesh_bevel.c
@@ -34,6 +34,7 @@
#include "DNA_meshdata_types.h"
#include "BLI_array.h"
+#include "BLI_alloca.h"
#include "BLI_math.h"
#include "BLI_memarena.h"
diff --git a/source/blender/bmesh/tools/bmesh_decimate.h b/source/blender/bmesh/tools/bmesh_decimate.h
index c77cb18c518..a1b26990587 100644
--- a/source/blender/bmesh/tools/bmesh_decimate.h
+++ b/source/blender/bmesh/tools/bmesh_decimate.h
@@ -35,7 +35,8 @@ void BM_mesh_decimate_unsubdivide(BMesh *bm, const int iterations);
void BM_mesh_decimate_dissolve_ex(BMesh *bm, const float angle_limit, const bool do_dissolve_boundaries,
const BMO_Delimit delimit,
BMVert **vinput_arr, const int vinput_len,
- BMEdge **einput_arr, const int einput_len);
+ BMEdge **einput_arr, const int einput_len,
+ const short oflag_out);
void BM_mesh_decimate_dissolve(BMesh *bm, const float angle_limit, const bool do_dissolve_boundaries,
const BMO_Delimit delimit);
diff --git a/source/blender/bmesh/tools/bmesh_decimate_collapse.c b/source/blender/bmesh/tools/bmesh_decimate_collapse.c
index d3ffc348539..4b6835a81fe 100644
--- a/source/blender/bmesh/tools/bmesh_decimate_collapse.c
+++ b/source/blender/bmesh/tools/bmesh_decimate_collapse.c
@@ -345,7 +345,7 @@ static bool bm_decim_triangulate_begin(BMesh *bm)
}
#ifdef USE_SAFETY_CHECKS
- if (BM_edge_exists(l_a->v, l_b->v) == false)
+ if (BM_edge_exists(l_a->v, l_b->v) == NULL)
#endif
{
BMFace *f_new;
diff --git a/source/blender/bmesh/tools/bmesh_decimate_dissolve.c b/source/blender/bmesh/tools/bmesh_decimate_dissolve.c
index 9d4e01d19cd..310357453a3 100644
--- a/source/blender/bmesh/tools/bmesh_decimate_dissolve.c
+++ b/source/blender/bmesh/tools/bmesh_decimate_dissolve.c
@@ -30,18 +30,22 @@
#include "MEM_guardedalloc.h"
#include "BLI_math.h"
+#include "BLI_heap.h"
#include "bmesh.h"
#include "bmesh_decimate.h" /* own include */
-#define UNIT_TO_ANGLE DEG2RADF(90.0f)
-#define ANGLE_TO_UNIT (1.0f / UNIT_TO_ANGLE)
+#define COST_INVALID FLT_MAX
+
/* multiply vertex edge angle by face angle
* this means we are not left with sharp corners between _almost_ planer faces
* convert angles [0-PI/2] -> [0-1], multiply together, then convert back to radians. */
static float bm_vert_edge_face_angle(BMVert *v)
{
+#define UNIT_TO_ANGLE DEG2RADF(90.0f)
+#define ANGLE_TO_UNIT (1.0f / UNIT_TO_ANGLE)
+
const float angle = BM_vert_calc_edge_angle(v);
/* note: could be either edge, it doesn't matter */
if (v->e && BM_edge_is_manifold(v->e)) {
@@ -50,163 +54,184 @@ static float bm_vert_edge_face_angle(BMVert *v)
else {
return angle;
}
-}
#undef UNIT_TO_ANGLE
#undef ANGLE_TO_UNIT
-
-typedef struct DissolveElemWeight {
- BMHeader *ele;
- float weight;
-} DissolveElemWeight;
-
-static int dissolve_elem_cmp(const void *a1, const void *a2)
-{
- const struct DissolveElemWeight *d1 = a1, *d2 = a2;
-
- if (d1->weight > d2->weight) return 1;
- else if (d1->weight < d2->weight) return -1;
- return 0;
}
-void BM_mesh_decimate_dissolve_ex(BMesh *bm, const float angle_limit, const bool do_dissolve_boundaries,
- const BMO_Delimit delimit,
- BMVert **vinput_arr, const int vinput_len,
- BMEdge **einput_arr, const int einput_len)
+static float bm_edge_calc_dissolve_error(const BMEdge *e, const BMO_Delimit delimit)
{
- const float angle_max = (float)M_PI / 2.0f;
- DissolveElemWeight *weight_elems = MEM_mallocN(max_ii(einput_len, vinput_len) *
- sizeof(DissolveElemWeight), __func__);
- int i, tot_found;
- BMIter iter;
- BMEdge *e_iter;
- BMEdge **earray;
-
- int *vert_reverse_lookup;
+ const bool is_contig = BM_edge_is_contiguous(e);
+ float angle;
- /* --- first edges --- */
+ if (!BM_edge_is_manifold(e)) {
+ goto fail;
+ }
- /* wire -> tag */
- BM_ITER_MESH (e_iter, &iter, bm, BM_EDGES_OF_MESH) {
- BM_elem_flag_set(e_iter, BM_ELEM_TAG, BM_edge_is_wire(e_iter));
+ if ((delimit & BMO_DELIM_SEAM) &&
+ (BM_elem_flag_test(e, BM_ELEM_SEAM)))
+ {
+ goto fail;
}
- /* go through and split edge */
- for (i = 0, tot_found = 0; i < einput_len; i++) {
- BMEdge *e = einput_arr[i];
- const bool is_contig = BM_edge_is_contiguous(e);
- float angle;
+ if ((delimit & BMO_DELIM_MATERIAL) &&
+ (e->l->f->mat_nr != e->l->radial_next->f->mat_nr))
+ {
+ goto fail;
+ }
- angle = BM_edge_calc_face_angle(e);
- if (is_contig == false) {
- angle = (float)M_PI - angle;
- }
+ if ((delimit & BMO_DELIM_NORMAL) &&
+ (is_contig == false))
+ {
+ goto fail;
+ }
- if (angle < angle_limit) {
- tot_found++;
- }
- weight_elems[i].ele = (BMHeader *)e;
- weight_elems[i].weight = angle;
+ angle = BM_edge_calc_face_angle(e);
+ if (is_contig == false) {
+ angle = (float)M_PI - angle;
}
- if (tot_found != 0) {
- qsort(weight_elems, einput_len, sizeof(DissolveElemWeight), dissolve_elem_cmp);
+ return angle;
- for (i = 0; i < tot_found; i++) {
- BMEdge *e = (BMEdge *)weight_elems[i].ele;
- const bool is_contig = BM_edge_is_contiguous(e);
- float angle;
+fail:
+ return COST_INVALID;
+}
- /* may have become non-manifold */
- if (!BM_edge_is_manifold(e)) {
- continue;
- }
- if ((delimit & BMO_DELIM_SEAM) &&
- (BM_elem_flag_test(e, BM_ELEM_SEAM)))
- {
- continue;
- }
+void BM_mesh_decimate_dissolve_ex(BMesh *bm, const float angle_limit, const bool do_dissolve_boundaries,
+ const BMO_Delimit delimit,
+ BMVert **vinput_arr, const int vinput_len,
+ BMEdge **einput_arr, const int einput_len,
+ const short oflag_out)
+{
+ const int eheap_table_len = do_dissolve_boundaries ? einput_len : max_ii(einput_len, vinput_len);
+ void *_heap_table = MEM_mallocN(sizeof(HeapNode *) * eheap_table_len, __func__);
- if ((delimit & BMO_DELIM_MATERIAL) &&
- (e->l->f->mat_nr != e->l->radial_next->f->mat_nr))
- {
- continue;
- }
+ int i;
- if ((delimit & BMO_DELIM_NORMAL) &&
- (is_contig == false))
- {
- continue;
- }
+ /* --- first edges --- */
+ if (1) {
+ BMEdge **earray;
+ Heap *eheap;
+ HeapNode **eheap_table = _heap_table;
+ HeapNode *enode_top;
+ int *vert_reverse_lookup;
+ BMIter iter;
+ BMEdge *e_iter;
+
+ /* --- setup heap --- */
+ eheap = BLI_heap_new_ex(einput_len);
+ eheap_table = _heap_table;
+
+ /* wire -> tag */
+ BM_ITER_MESH (e_iter, &iter, bm, BM_EDGES_OF_MESH) {
+ BM_elem_flag_set(e_iter, BM_ELEM_TAG, BM_edge_is_wire(e_iter));
+ BM_elem_index_set(e_iter, -1); /* set dirty */
+ }
+ bm->elem_index_dirty |= BM_EDGE;
+
+ /* build heap */
+ for (i = 0; i < einput_len; i++) {
+ BMEdge *e = einput_arr[i];
+ const float cost = bm_edge_calc_dissolve_error(e, delimit);
+ eheap_table[i] = BLI_heap_insert(eheap, cost, e);
+ BM_elem_index_set(e, i); /* set dirty */
+ }
- /* check twice because cumulative effect could dissolve over angle limit */
- angle = BM_edge_calc_face_angle(e);
- if (is_contig == false) {
- angle = (float)M_PI - angle;
- }
+ while ((BLI_heap_is_empty(eheap) == false) &&
+ (BLI_heap_node_value((enode_top = BLI_heap_top(eheap))) < angle_limit))
+ {
+ BMFace *f_new = NULL;
+ BMEdge *e;
+
+ e = BLI_heap_node_ptr(enode_top);
+ i = BM_elem_index_get(e);
- if (angle < angle_limit) {
- BMFace *f_new = BM_faces_join_pair(bm, e->l->f,
- e->l->radial_next->f,
- e,
- false); /* join faces */
+ if (BM_edge_is_manifold(e)) {
+ 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 (f_new) {
+ BMLoop *l_first, *l_iter;
+
+ BLI_heap_remove(eheap, enode_top);
+ eheap_table[i] = NULL;
+
+ /* update normal */
BM_face_normal_update(f_new);
+ if (oflag_out) {
+ BMO_elem_flag_enable(bm, f_new, oflag_out);
+ }
+
+ /* re-calculate costs */
+ l_iter = l_first = BM_FACE_FIRST_LOOP(f_new);
+ do {
+ const int j = BM_elem_index_get(l_iter->e);
+ if (j != -1 && eheap_table[j]) {
+ const float cost = bm_edge_calc_dissolve_error(l_iter->e, delimit);
+ BLI_heap_remove(eheap, eheap_table[j]);
+ eheap_table[j] = BLI_heap_insert(eheap, cost, l_iter->e);
+ }
+ } while ((l_iter = l_iter->next) != l_first);
}
else {
BMO_error_clear(bm);
}
}
+
+ if (UNLIKELY(f_new == NULL)) {
+ BLI_heap_remove(eheap, enode_top);
+ eheap_table[i] = BLI_heap_insert(eheap, COST_INVALID, e);
+ }
}
- }
- /* prepare for cleanup */
- BM_mesh_elem_index_ensure(bm, BM_VERT);
- vert_reverse_lookup = MEM_mallocN(sizeof(int) * bm->totvert, __func__);
- fill_vn_i(vert_reverse_lookup, bm->totvert, -1);
- for (i = 0, tot_found = 0; i < vinput_len; i++) {
- BMVert *v = vinput_arr[i];
- vert_reverse_lookup[BM_elem_index_get(v)] = i;
- }
+ /* prepare for cleanup */
+ BM_mesh_elem_index_ensure(bm, BM_VERT);
+ vert_reverse_lookup = MEM_mallocN(sizeof(int) * bm->totvert, __func__);
+ fill_vn_i(vert_reverse_lookup, bm->totvert, -1);
+ for (i = 0; i < vinput_len; i++) {
+ BMVert *v = vinput_arr[i];
+ vert_reverse_lookup[BM_elem_index_get(v)] = i;
+ }
- /* --- cleanup --- */
- earray = MEM_mallocN(sizeof(BMEdge *) * bm->totedge, __func__);
- BM_ITER_MESH_INDEX (e_iter, &iter, bm, BM_EDGES_OF_MESH, i) {
- earray[i] = e_iter;
- }
- /* remove all edges/verts left behind from dissolving, NULL'ing the vertex array so we dont re-use */
- for (i = bm->totedge - 1; i != -1; i--) {
- e_iter = earray[i];
-
- if (BM_edge_is_wire(e_iter) && (BM_elem_flag_test(e_iter, BM_ELEM_TAG) == false)) {
- /* edge has become wire */
- int vidx_reverse;
- BMVert *v1 = e_iter->v1;
- BMVert *v2 = e_iter->v2;
- BM_edge_kill(bm, e_iter);
- if (v1->e == NULL) {
- vidx_reverse = vert_reverse_lookup[BM_elem_index_get(v1)];
- if (vidx_reverse != -1) vinput_arr[vidx_reverse] = NULL;
- BM_vert_kill(bm, v1);
- }
- if (v2->e == NULL) {
- vidx_reverse = vert_reverse_lookup[BM_elem_index_get(v2)];
- if (vidx_reverse != -1) vinput_arr[vidx_reverse] = NULL;
- BM_vert_kill(bm, v2);
+ /* --- cleanup --- */
+ earray = MEM_mallocN(sizeof(BMEdge *) * bm->totedge, __func__);
+ BM_ITER_MESH_INDEX (e_iter, &iter, bm, BM_EDGES_OF_MESH, i) {
+ earray[i] = e_iter;
+ }
+ /* remove all edges/verts left behind from dissolving, NULL'ing the vertex array so we dont re-use */
+ for (i = bm->totedge - 1; i != -1; i--) {
+ e_iter = earray[i];
+
+ if (BM_edge_is_wire(e_iter) && (BM_elem_flag_test(e_iter, BM_ELEM_TAG) == false)) {
+ /* edge has become wire */
+ int vidx_reverse;
+ BMVert *v1 = e_iter->v1;
+ BMVert *v2 = e_iter->v2;
+ BM_edge_kill(bm, e_iter);
+ if (v1->e == NULL) {
+ vidx_reverse = vert_reverse_lookup[BM_elem_index_get(v1)];
+ if (vidx_reverse != -1) vinput_arr[vidx_reverse] = NULL;
+ BM_vert_kill(bm, v1);
+ }
+ if (v2->e == NULL) {
+ vidx_reverse = vert_reverse_lookup[BM_elem_index_get(v2)];
+ if (vidx_reverse != -1) vinput_arr[vidx_reverse] = NULL;
+ BM_vert_kill(bm, v2);
+ }
}
}
- }
- MEM_freeN(vert_reverse_lookup);
+ MEM_freeN(vert_reverse_lookup);
+ MEM_freeN(earray);
- MEM_freeN(earray);
+ BLI_heap_free(eheap, NULL);
+ }
/* --- second verts --- */
if (do_dissolve_boundaries) {
- /* simple version of the branch below, sincve we will dissolve _all_ verts that use 2 edges */
+ /* simple version of the branch below, since we will dissolve _all_ verts that use 2 edges */
for (i = 0; i < vinput_len; i++) {
BMVert *v = vinput_arr[i];
if (LIKELY(v != NULL) &&
@@ -217,43 +242,78 @@ void BM_mesh_decimate_dissolve_ex(BMesh *bm, const float angle_limit, const bool
}
}
else {
- for (i = 0, tot_found = 0; i < vinput_len; i++) {
- BMVert *v = vinput_arr[i];
- const float angle = v ? bm_vert_edge_face_angle(v) : angle_limit;
+ Heap *vheap;
+ HeapNode **vheap_table = _heap_table;
+ HeapNode *vnode_top;
- if (angle < angle_limit) {
- weight_elems[i].ele = (BMHeader *)v;
- weight_elems[i].weight = angle;
- tot_found++;
- }
- else {
- weight_elems[i].ele = NULL;
- weight_elems[i].weight = angle_max;
+ BMVert *v_iter;
+ BMIter iter;
+
+ BM_ITER_MESH (v_iter, &iter, bm, BM_VERTS_OF_MESH) {
+ BM_elem_index_set(v_iter, -1); /* set dirty */
+ }
+ bm->elem_index_dirty |= BM_VERT;
+
+ vheap = BLI_heap_new_ex(vinput_len);
+
+ for (i = 0; i < vinput_len; i++) {
+ BMVert *v = vinput_arr[i];
+ if (LIKELY(v != NULL)) {
+ const float cost = bm_vert_edge_face_angle(v);
+ vheap_table[i] = BLI_heap_insert(vheap, cost, v);
+ BM_elem_index_set(v, i); /* set dirty */
}
}
- if (tot_found != 0) {
- qsort(weight_elems, vinput_len, sizeof(DissolveElemWeight), dissolve_elem_cmp);
-
- for (i = 0; i < tot_found; i++) {
- BMVert *v = (BMVert *)weight_elems[i].ele;
- if (LIKELY(v != NULL) &&
- /* topology changes may cause this to be un-collapsable */
- (BM_vert_edge_count(v) == 2) &&
- /* check twice because cumulative effect could dissolve over angle limit */
- bm_vert_edge_face_angle(v) < angle_limit)
- {
- BMEdge *e_new = BM_vert_collapse_edge(bm, v->e, v, true); /* join edges */
-
- if (e_new && e_new->l) {
- BM_edge_normals_update(e_new);
+ while ((BLI_heap_is_empty(vheap) == false) &&
+ (BLI_heap_node_value((vnode_top = BLI_heap_top(vheap))) < angle_limit))
+ {
+ BMEdge *e_new = NULL;
+ BMVert *v;
+
+ v = BLI_heap_node_ptr(vnode_top);
+ i = BM_elem_index_get(v);
+
+ if (BM_vert_edge_count(v) == 2) {
+ e_new = BM_vert_collapse_edge(bm, v->e, v, true); /* join edges */
+
+ if (e_new) {
+
+ BLI_heap_remove(vheap, vnode_top);
+ vheap_table[i] = NULL;
+
+ /* update normal */
+ if (e_new->l) {
+ BMLoop *l_first, *l_iter;
+ l_iter = l_first = e_new->l;
+ do {
+ BM_face_normal_update(l_iter->f);
+ } while ((l_iter = l_iter->radial_next) != l_first);
+
+ }
+
+ /* re-calculate costs */
+ BM_ITER_ELEM(v_iter, &iter, e_new, BM_VERTS_OF_EDGE) {
+ const int j = BM_elem_index_get(v_iter);
+ if (j != -1 && vheap_table[j]) {
+ const float cost = bm_vert_edge_face_angle(v_iter);
+ BLI_heap_remove(vheap, vheap_table[j]);
+ vheap_table[j] = BLI_heap_insert(vheap, cost, v_iter);
+ }
}
}
}
+
+ if (UNLIKELY(e_new == NULL)) {
+ BLI_heap_remove(vheap, vnode_top);
+ vheap_table[i] = BLI_heap_insert(vheap, COST_INVALID, v);
+ }
}
+
+ BLI_heap_free(vheap, NULL);
}
- MEM_freeN(weight_elems);
+ MEM_freeN(_heap_table);
}
void BM_mesh_decimate_dissolve(BMesh *bm, const float angle_limit, const bool do_dissolve_boundaries,
@@ -269,7 +329,8 @@ void BM_mesh_decimate_dissolve(BMesh *bm, const float angle_limit, const bool do
BM_mesh_decimate_dissolve_ex(bm, angle_limit, do_dissolve_boundaries,
delimit,
vinput_arr, vinput_len,
- einput_arr, einput_len);
+ einput_arr, einput_len,
+ 0);
MEM_freeN(vinput_arr);
MEM_freeN(einput_arr);
diff --git a/source/blender/bmesh/tools/bmesh_edgesplit.c b/source/blender/bmesh/tools/bmesh_edgesplit.c
index 3ae5c712f0a..aad600d13fa 100644
--- a/source/blender/bmesh/tools/bmesh_edgesplit.c
+++ b/source/blender/bmesh/tools/bmesh_edgesplit.c
@@ -98,11 +98,26 @@ static void bm_edgesplit_validate_seams(BMesh *bm)
MEM_freeN(vtouch);
}
-void BM_mesh_edgesplit(BMesh *bm, const bool use_verts, const bool tag_only)
+void BM_mesh_edgesplit(BMesh *bm, const bool use_verts, const bool tag_only, const bool copy_select)
{
BMIter iter;
BMEdge *e;
+ bool use_ese = false;
+ GHash *ese_gh = NULL;
+
+ if (copy_select && bm->selected.first) {
+ BMEditSelection *ese;
+
+ ese_gh = BLI_ghash_ptr_new(__func__);
+ for (ese = bm->selected.first; ese; ese = ese->next) {
+ if (ese->htype != BM_FACE) {
+ BLI_ghash_insert(ese_gh, ese->ele, ese);
+ }
+ }
+
+ use_ese = true;
+ }
if (tag_only == false) {
BM_mesh_elem_hflag_enable_all(bm, BM_EDGE | (use_verts ? BM_VERT : 0), BM_ELEM_TAG, false);
@@ -135,9 +150,18 @@ void BM_mesh_edgesplit(BMesh *bm, const bool use_verts, const bool tag_only)
BM_elem_flag_enable(e, BM_ELEM_INTERNAL_TAG);
/* keep splitting until each loop has its own edge */
- do {
- bmesh_edge_separate(bm, e, e->l);
- } while (!BM_edge_is_boundary(e));
+ while (!BM_edge_is_boundary(e)) {
+ BMLoop *l_sep = e->l;
+ bmesh_edge_separate(bm, e, l_sep, copy_select);
+ BLI_assert(l_sep->e != e);
+
+ if (use_ese) {
+ BMEditSelection *ese = BLI_ghash_lookup(ese_gh, e);
+ if (UNLIKELY(ese)) {
+ BM_select_history_store_after_notest(bm, ese, l_sep->e);
+ }
+ }
+ }
BM_elem_flag_enable(e->v1, BM_ELEM_TAG);
BM_elem_flag_enable(e->v2, BM_ELEM_TAG);
@@ -157,14 +181,39 @@ void BM_mesh_edgesplit(BMesh *bm, const bool use_verts, const bool tag_only)
BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) {
if (BM_elem_flag_test(e, BM_ELEM_TAG)) {
- if (BM_elem_flag_test(e->v1, BM_ELEM_TAG)) {
- BM_elem_flag_disable(e->v1, BM_ELEM_TAG);
- bmesh_vert_separate(bm, e->v1, NULL, NULL);
- }
- if (BM_elem_flag_test(e->v2, BM_ELEM_TAG)) {
- BM_elem_flag_disable(e->v2, BM_ELEM_TAG);
- bmesh_vert_separate(bm, e->v2, NULL, NULL);
+ unsigned int i;
+ for (i = 0; i < 2; i++) {
+ BMVert *v = ((&e->v1)[i]);
+ if (BM_elem_flag_test(v, BM_ELEM_TAG)) {
+ BM_elem_flag_disable(v, BM_ELEM_TAG);
+
+ if (use_ese) {
+ BMVert **vtar;
+ int vtar_len;
+
+ bmesh_vert_separate(bm, v, &vtar, &vtar_len, copy_select);
+
+ if (vtar_len) {
+ BMEditSelection *ese = BLI_ghash_lookup(ese_gh, v);
+ if (UNLIKELY(ese)) {
+ int j;
+ for (j = 0; j < vtar_len; j++) {
+ BLI_assert(v != vtar[j]);
+ BM_select_history_store_after_notest(bm, ese, vtar[j]);
+ }
+ }
+ }
+ MEM_freeN(vtar);
+ }
+ else {
+ bmesh_vert_separate(bm, v, NULL, NULL, copy_select);
+ }
+ }
}
}
}
+
+ if (use_ese) {
+ BLI_ghash_free(ese_gh, NULL, NULL);
+ }
}
diff --git a/source/blender/bmesh/tools/bmesh_edgesplit.h b/source/blender/bmesh/tools/bmesh_edgesplit.h
index 8c1231dd794..bd66f6a9e2f 100644
--- a/source/blender/bmesh/tools/bmesh_edgesplit.h
+++ b/source/blender/bmesh/tools/bmesh_edgesplit.h
@@ -27,6 +27,6 @@
* \ingroup bmesh
*/
-void BM_mesh_edgesplit(BMesh *bm, const bool use_verts, const bool tag_only);
+void BM_mesh_edgesplit(BMesh *bm, const bool use_verts, const bool tag_only, const bool copy_select);
#endif /* __BMESH_EDGESPLIT_H__ */
diff --git a/source/blender/bmesh/tools/bmesh_triangulate.c b/source/blender/bmesh/tools/bmesh_triangulate.c
index 79f6c76afc7..2eacf62d68a 100644
--- a/source/blender/bmesh/tools/bmesh_triangulate.c
+++ b/source/blender/bmesh/tools/bmesh_triangulate.c
@@ -30,7 +30,7 @@
#include "MEM_guardedalloc.h"
#include "BLI_utildefines.h"
-#include "BLI_array.h"
+#include "BLI_alloca.h"
#include "bmesh.h"
diff --git a/source/blender/collada/ArmatureImporter.cpp b/source/blender/collada/ArmatureImporter.cpp
index eb92b089f48..5d47ce155c8 100644
--- a/source/blender/collada/ArmatureImporter.cpp
+++ b/source/blender/collada/ArmatureImporter.cpp
@@ -50,7 +50,11 @@ static const char *bc_get_joint_name(T *node)
}
ArmatureImporter::ArmatureImporter(UnitConverter *conv, MeshImporterBase *mesh, Scene *sce) :
- TransformReader(conv), scene(sce), empty(NULL), mesh_importer(mesh) {
+ unit_converter(conv),
+ TransformReader(conv),
+ scene(sce),
+ empty(NULL),
+ mesh_importer(mesh) {
}
ArmatureImporter::~ArmatureImporter()
@@ -82,17 +86,15 @@ JointData *ArmatureImporter::get_joint_data(COLLADAFW::Node *node);
void ArmatureImporter::create_bone(SkinInfo *skin, COLLADAFW::Node *node, EditBone *parent, int totchild,
float parent_mat[4][4], bArmature *arm)
{
+ float mat[4][4];
+ float joint_inv_bind_mat[4][4];
+
//Checking if bone is already made.
std::vector<COLLADAFW::Node *>::iterator it;
it = std::find(finished_joints.begin(), finished_joints.end(), node);
if (it != finished_joints.end()) return;
- float joint_inv_bind_mat[4][4];
-
// JointData* jd = get_joint_data(node);
-
- float mat[4][4];
- float obmat[4][4];
// TODO rename from Node "name" attrs later
EditBone *bone = ED_armature_edit_bone_add(arm, (char *)bc_get_joint_name(node));
@@ -101,9 +103,18 @@ void ArmatureImporter::create_bone(SkinInfo *skin, COLLADAFW::Node *node, EditBo
if (skin && skin->get_joint_inv_bind_matrix(joint_inv_bind_mat, node)) {
// get original world-space matrix
invert_m4_m4(mat, joint_inv_bind_mat);
+
+ // And make local to armature
+ Object *ob_arm = skin->BKE_armature_from_object();
+ if (ob_arm) {
+ float invmat[4][4];
+ invert_m4_m4(invmat, ob_arm->obmat);
+ mul_m4_m4m4(mat, invmat, mat);
+ }
}
// create a bone even if there's no joint data for it (i.e. it has no influence)
else {
+ float obmat[4][4];
// bone-space
get_node_mat(obmat, node, NULL, NULL);
@@ -204,16 +215,21 @@ void ArmatureImporter::add_leaf_bone(float mat[4][4], EditBone *bone, COLLADAFW
void ArmatureImporter::fix_leaf_bones( )
{
+ // Collada only knows Joints, Here we guess a reasonable
+ // leaf bone length
+ float leaf_length = (leaf_bone_length == FLT_MAX) ? 1.0:leaf_bone_length;
+
// just setting tail for leaf bones here
std::vector<LeafBone>::iterator it;
for (it = leaf_bones.begin(); it != leaf_bones.end(); it++) {
+
LeafBone& leaf = *it;
// pointing up
float vec[3] = {0.0f, 0.0f, 0.1f};
sub_v3_v3v3(vec, leaf.bone->tail , leaf.bone->head);
- mul_v3_fl(vec, leaf_bone_length);
+ mul_v3_fl(vec, leaf_length);
add_v3_v3v3(leaf.bone->tail, leaf.bone->head , vec);
}
diff --git a/source/blender/collada/DocumentImporter.cpp b/source/blender/collada/DocumentImporter.cpp
index 80bde1842dd..c6337e27218 100644
--- a/source/blender/collada/DocumentImporter.cpp
+++ b/source/blender/collada/DocumentImporter.cpp
@@ -185,6 +185,9 @@ void DocumentImporter::finish()
Main *bmain = CTX_data_main(mContext);
// TODO: create a new scene except the selected <visual_scene> - use current blender scene for it
Scene *sce = CTX_data_scene(mContext);
+ unit_converter.calculate_scale(*sce);
+
+ std::vector<Object *> *objects_to_scale = new std::vector<Object *>();
/** TODO Break up and put into 2-pass parsing of DAE */
std::vector<const COLLADAFW::VisualScene *>::iterator it;
@@ -221,13 +224,8 @@ void DocumentImporter::finish()
// Write nodes to scene
const COLLADAFW::NodePointerArray& roots = (*it)->getRootNodes();
for (unsigned int i = 0; i < roots.getCount(); i++) {
- std::vector<Object *> *objects_done;
- objects_done = write_node(roots[i], NULL, sce, NULL, false);
-
- if (!this->import_settings->import_units) {
- // Match incoming scene with current unit settings
- bc_match_scale(objects_done, *sce, unit_converter);
- }
+ std::vector<Object *> *objects_done = write_node(roots[i], NULL, sce, NULL, false);
+ objects_to_scale->insert(objects_to_scale->end(), objects_done->begin(), objects_done->end());
}
// update scene
@@ -278,6 +276,8 @@ void DocumentImporter::finish()
DAG_relations_tag_update(bmain);
}
+
+ bc_match_scale(objects_to_scale, unit_converter, !this->import_settings->import_units);
}
@@ -461,6 +461,7 @@ std::vector<Object *> *DocumentImporter::write_node(COLLADAFW::Node *node, COLLA
std::string name = node->getName();
std::vector<Object *> *objects_done = new std::vector<Object *>();
+ std::vector<Object *> *root_objects = new std::vector<Object *>();
fprintf(stderr,
"Writing node id='%s', name='%s'\n",
@@ -473,6 +474,7 @@ std::vector<Object *> *DocumentImporter::write_node(COLLADAFW::Node *node, COLLA
// Here we add the armature "on the fly":
par = bc_add_object(sce, OB_ARMATURE, std::string("Armature").c_str());
objects_done->push_back(par);
+ root_objects->push_back(par);
object_map.insert(std::pair<COLLADAFW::UniqueId, Object *>(node->getUniqueId(), par));
node_map[node->getUniqueId()] = node;
}
@@ -483,7 +485,7 @@ std::vector<Object *> *DocumentImporter::write_node(COLLADAFW::Node *node, COLLA
if (parent_node == NULL) {
// for skeletons without root node all has been done above.
// Skeletons with root node are handled further down.
- return objects_done;
+ return root_objects;
}
}
else {
@@ -512,6 +514,9 @@ std::vector<Object *> *DocumentImporter::write_node(COLLADAFW::Node *node, COLLA
}
else {
objects_done->push_back(ob);
+ if (parent_node == NULL) {
+ root_objects->push_back(ob);
+ }
}
++geom_done;
}
@@ -522,19 +527,29 @@ std::vector<Object *> *DocumentImporter::write_node(COLLADAFW::Node *node, COLLA
std::string name = node->getName();
fprintf(stderr, "<node id=\"%s\", name=\"%s\" >...contains a reference to an unknown instance_camera.\n", id.c_str(), name.c_str());
}
- else
+ else {
objects_done->push_back(ob);
+ if (parent_node == NULL) {
+ root_objects->push_back(ob);
+ }
+ }
++camera_done;
}
while (lamp_done < lamp.getCount()) {
ob = create_lamp_object(lamp[lamp_done], sce);
objects_done->push_back(ob);
+ if (parent_node == NULL) {
+ root_objects->push_back(ob);
+ }
++lamp_done;
}
while (controller_done < controller.getCount()) {
COLLADAFW::InstanceGeometry *geom = (COLLADAFW::InstanceGeometry *)controller[controller_done];
ob = mesh_importer.create_mesh_object(node, geom, true, uid_material_map, material_texture_mapping_map);
objects_done->push_back(ob);
+ if (parent_node == NULL) {
+ root_objects->push_back(ob);
+ }
++controller_done;
}
// XXX instance_node is not supported yet
@@ -550,9 +565,12 @@ std::vector<Object *> *DocumentImporter::write_node(COLLADAFW::Node *node, COLLA
Object *source_ob = (Object *)it2->second;
COLLADAFW::Node *source_node = node_map[node_id];
ob = create_instance_node(source_ob, source_node, node, sce, is_library_node);
+ objects_done->push_back(ob);
+ if (parent_node == NULL) {
+ root_objects->push_back(ob);
+ }
}
}
- if (ob != NULL) objects_done->push_back(ob);
++inst_done;
read_transform = false;
@@ -569,12 +587,14 @@ std::vector<Object *> *DocumentImporter::write_node(COLLADAFW::Node *node, COLLA
ob = bc_add_object(sce, OB_EMPTY, NULL);
}
objects_done->push_back(ob);
-
+ if (parent_node == NULL) {
+ root_objects->push_back(ob);
+ }
}
// XXX: if there're multiple instances, only one is stored
- if (!ob) return objects_done;
+ if (!ob) return root_objects;
for (std::vector<Object *>::iterator it = objects_done->begin(); it != objects_done->end(); ++it) {
ob = *it;
@@ -623,7 +643,7 @@ std::vector<Object *> *DocumentImporter::write_node(COLLADAFW::Node *node, COLLA
write_node(child_nodes[i], node, sce, ob, is_library_node);
}
- return objects_done;
+ return root_objects;
}
/** When this method is called, the writer must write the entire visual scene.
diff --git a/source/blender/collada/MeshImporter.cpp b/source/blender/collada/MeshImporter.cpp
index 1e0f0244072..8aa68ed9d04 100644
--- a/source/blender/collada/MeshImporter.cpp
+++ b/source/blender/collada/MeshImporter.cpp
@@ -618,13 +618,10 @@ void MeshImporter::read_polys(COLLADAFW::Mesh *collada_mesh, Mesh *me)
set_poly_indices(mpoly, mloop, loop_index, position_indices, vcount);
- for (unsigned int l = 0; l < index_list_array.getCount(); l++) {
- int uvset_index = index_list_array[l]->getSetIndex();
-
+ for (unsigned int uvset_index = 0; uvset_index < index_list_array.getCount(); uvset_index++) {
// get mtface by face index and uv set index
MLoopUV *mloopuv = (MLoopUV *)CustomData_get_layer_n(&me->ldata, CD_MLOOPUV, uvset_index);
-
- set_face_uv(mloopuv+loop_index, uvs, start_index, *index_list_array[l], vcount);
+ set_face_uv(mloopuv+loop_index, uvs, start_index, *index_list_array[uvset_index], vcount);
}
if (mp_has_normals) {
diff --git a/source/blender/collada/SkinInfo.cpp b/source/blender/collada/SkinInfo.cpp
index c2770dc3dc5..7ae1750d2ca 100644
--- a/source/blender/collada/SkinInfo.cpp
+++ b/source/blender/collada/SkinInfo.cpp
@@ -226,8 +226,6 @@ void SkinInfo::link_armature(bContext *C, Object *ob, std::map<COLLADAFW::Unique
ArmatureModifierData *amd = (ArmatureModifierData *)md;
amd->object = ob_arm;
- copy_m4_m4(ob->obmat, bind_shape_matrix);
- BKE_object_apply_mat4(ob, ob->obmat, 0, 0);
#if 1
bc_set_parent(ob, ob_arm, C);
#else
@@ -243,6 +241,8 @@ void SkinInfo::link_armature(bContext *C, Object *ob, std::map<COLLADAFW::Unique
DAG_relations_tag_update(bmain);
WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, NULL);
#endif
+ copy_m4_m4(ob->obmat, bind_shape_matrix);
+ BKE_object_apply_mat4(ob, ob->obmat, 0, 0);
amd->deformflag = ARM_DEF_VGROUP;
diff --git a/source/blender/collada/TransformReader.cpp b/source/blender/collada/TransformReader.cpp
index 43faa15b4bb..f8f31304d28 100644
--- a/source/blender/collada/TransformReader.cpp
+++ b/source/blender/collada/TransformReader.cpp
@@ -48,7 +48,9 @@ void TransformReader::get_node_mat(float mat[4][4], COLLADAFW::Node *node, std::
switch (type) {
case COLLADAFW::Transformation::MATRIX:
- // XXX why does this return and discard all following transformations?
+ // When matrix AND Trans/Rot/Scale are defined for a node,
+ // then this is considered as redundant information.
+ // So if we find a Matrix we use that and return.
dae_matrix_to_mat4(tm, mat);
return;
case COLLADAFW::Transformation::TRANSLATE:
diff --git a/source/blender/collada/collada_internal.cpp b/source/blender/collada/collada_internal.cpp
index 069419f938b..567ee22b3d6 100644
--- a/source/blender/collada/collada_internal.cpp
+++ b/source/blender/collada/collada_internal.cpp
@@ -27,7 +27,7 @@
/* COLLADABU_ASSERT, may be able to remove later */
#include "COLLADABUPlatform.h"
-#include "collada_internal.h"
+#include "collada_utils.h"
#include "BLI_linklist.h"
@@ -40,7 +40,7 @@ UnitConverter::UnitConverter() : unit(), up_axis(COLLADAFW::FileInfo::Z_UP)
rotate_m4(y_up_mat4, 'X', 0.5 * M_PI);
unit_m4(z_up_mat4);
-
+ unit_m4(scale_mat4);
}
void UnitConverter::read_asset(const COLLADAFW::FileInfo *asset)
@@ -124,6 +124,48 @@ float(&UnitConverter::get_rotation())[4][4]
}
}
+
+float(&UnitConverter::get_scale())[4][4]
+{
+ return scale_mat4;
+}
+
+void UnitConverter::calculate_scale(Scene &sce)
+{
+ PointerRNA scene_ptr, unit_settings;
+ PropertyRNA *system_ptr, *scale_ptr;
+ RNA_id_pointer_create(&sce.id, &scene_ptr);
+
+ unit_settings = RNA_pointer_get(&scene_ptr, "unit_settings");
+ system_ptr = RNA_struct_find_property(&unit_settings, "system");
+ scale_ptr = RNA_struct_find_property(&unit_settings, "scale_length");
+
+ int type = RNA_property_enum_get(&unit_settings, system_ptr);
+
+ float bl_scale;
+
+ switch (type) {
+ case USER_UNIT_NONE:
+ bl_scale = 1.0; // map 1 Blender unit to 1 Meter
+ break;
+
+ case USER_UNIT_METRIC:
+ bl_scale = RNA_property_float_get(&unit_settings, scale_ptr);
+ break;
+
+ default :
+ bl_scale = RNA_property_float_get(&unit_settings, scale_ptr);
+ // it looks like the conversion to Imperial is done implicitly.
+ // So nothing to do here.
+ break;
+ }
+
+ float rescale[3];
+ rescale[0] = rescale[1] = rescale[2] = getLinearMeter() / bl_scale;
+
+ size_to_mat4(scale_mat4, rescale);
+}
+
void TransformBase::decompose(float mat[4][4], float *loc, float eul[3], float quat[4], float *size)
{
mat4_to_size(size, mat);
diff --git a/source/blender/collada/collada_internal.h b/source/blender/collada/collada_internal.h
index 2e855764f4b..4aa637a6876 100644
--- a/source/blender/collada/collada_internal.h
+++ b/source/blender/collada/collada_internal.h
@@ -50,7 +50,8 @@ private:
float x_up_mat4[4][4];
float y_up_mat4[4][4];
float z_up_mat4[4][4];
-
+ float scale_mat4[4][4];
+
public:
enum UnitSystem {
@@ -79,7 +80,8 @@ public:
void mat4_to_dae_double(double out[4][4], float in[4][4]);
float(&get_rotation())[4][4];
-
+ float(&get_scale())[4][4];
+ void calculate_scale(Scene &sce);
};
diff --git a/source/blender/collada/collada_utils.cpp b/source/blender/collada/collada_utils.cpp
index d4196bacf0d..3e17472e9c2 100644
--- a/source/blender/collada/collada_utils.cpp
+++ b/source/blender/collada/collada_utils.cpp
@@ -324,65 +324,30 @@ 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.
*/
-void bc_match_scale(std::vector<Object *> *objects_done,
- Scene &sce,
- UnitConverter &bc_unit)
-{
- Object *ob = NULL;
-
- PointerRNA scene_ptr, unit_settings;
- PropertyRNA *system_ptr, *scale_ptr;
- RNA_id_pointer_create(&sce.id, &scene_ptr);
-
- unit_settings = RNA_pointer_get(&scene_ptr, "unit_settings");
- system_ptr = RNA_struct_find_property(&unit_settings, "system");
- scale_ptr = RNA_struct_find_property(&unit_settings, "scale_length");
-
- int type = RNA_property_enum_get(&unit_settings, system_ptr);
- float bl_scale;
-
- switch (type) {
- case USER_UNIT_NONE:
- bl_scale = 1.0; // map 1 Blender unit to 1 Meter
- break;
-
- case USER_UNIT_METRIC:
- bl_scale = RNA_property_float_get(&unit_settings, scale_ptr);
- break;
-
- default :
- bl_scale = RNA_property_float_get(&unit_settings, scale_ptr);
- // it looks like the conversion to Imperial is done implicitly.
- // So nothing to do here.
- break;
+void bc_match_scale(Object *ob, UnitConverter &bc_unit, bool scale_to_scene)
+{
+ if (scale_to_scene) {
+ mul_m4_m4m4(ob->obmat, bc_unit.get_scale(), ob->obmat);
}
-
- float scale_conv = bc_unit.getLinearMeter() / bl_scale;
-
- float rescale[3];
- rescale[0] = rescale[1] = rescale[2] = scale_conv;
-
- float size_mat4[4][4];
-
- float axis_mat4[4][4];
- unit_m4(axis_mat4);
-
- size_to_mat4(size_mat4, rescale);
+ mul_m4_m4m4(ob->obmat, bc_unit.get_rotation(), ob->obmat);
+ BKE_object_apply_mat4(ob, ob->obmat, 0, 0);
+}
+void bc_match_scale(std::vector<Object *> *objects_done,
+ UnitConverter &bc_unit,
+ bool scale_to_scene)
+{
for (std::vector<Object *>::iterator it = objects_done->begin();
it != objects_done->end();
++it)
{
- ob = *it;
- mul_m4_m4m4(ob->obmat, size_mat4, ob->obmat);
- mul_m4_m4m4(ob->obmat, bc_unit.get_rotation(), ob->obmat);
- BKE_object_apply_mat4(ob, ob->obmat, 0, 0);
+ Object *ob = *it;
+ if (ob -> parent == NULL) {
+ bc_match_scale(*it, bc_unit, scale_to_scene);
+ }
}
-
}
void bc_triangulate_mesh(Mesh *me)
diff --git a/source/blender/collada/collada_utils.h b/source/blender/collada/collada_utils.h
index f8e6f09e498..4bc2f55cf33 100644
--- a/source/blender/collada/collada_utils.h
+++ b/source/blender/collada/collada_utils.h
@@ -83,7 +83,8 @@ extern int bc_get_active_UVLayer(Object *ob);
extern std::string bc_replace_string(std::string data, const std::string& pattern, const std::string& replacement);
extern std::string bc_url_encode(std::string data);
-extern void bc_match_scale(std::vector<Object *> *objects_done, Scene &sce, UnitConverter &unit_converter);
+extern void bc_match_scale(Object *ob, UnitConverter &bc_unit, bool scale_to_scene);
+extern void bc_match_scale(std::vector<Object *> *objects_done, UnitConverter &unit_converter, bool scale_to_scene);
extern void bc_triangulate_mesh(Mesh *me);
diff --git a/source/blender/compositor/CMakeLists.txt b/source/blender/compositor/CMakeLists.txt
index b3ec7c78808..c1b99274bed 100644
--- a/source/blender/compositor/CMakeLists.txt
+++ b/source/blender/compositor/CMakeLists.txt
@@ -425,14 +425,12 @@ set(SRC
operations/COM_CompositorOperation.cpp
operations/COM_OutputFileOperation.h
operations/COM_OutputFileOperation.cpp
- operations/COM_ViewerBaseOperation.h
- operations/COM_ViewerBaseOperation.cpp
operations/COM_ViewerOperation.h
operations/COM_ViewerOperation.cpp
operations/COM_PreviewOperation.h
operations/COM_PreviewOperation.cpp
- operations/COM_SplitViewerOperation.h
- operations/COM_SplitViewerOperation.cpp
+ operations/COM_SplitOperation.h
+ operations/COM_SplitOperation.cpp
operations/COM_ConvertValueToColorProg.h
operations/COM_ConvertValueToColorProg.cpp
operations/COM_ConvertColorToValueProg.h
diff --git a/source/blender/compositor/COM_compositor.h b/source/blender/compositor/COM_compositor.h
index fc546188816..204c3237e65 100644
--- a/source/blender/compositor/COM_compositor.h
+++ b/source/blender/compositor/COM_compositor.h
@@ -107,7 +107,7 @@ extern "C" {
* - [@ref ChunkExecutionState.COM_ES_EXECUTED]: Chunk is finished
*
* @see ExecutionGroup.execute
- * @see ViewerBaseOperation.getChunkOrder
+ * @see ViewerOperation.getChunkOrder
* @see OrderOfChunks
*
* @section interest Area of interest
diff --git a/source/blender/compositor/intern/COM_ExecutionGroup.cpp b/source/blender/compositor/intern/COM_ExecutionGroup.cpp
index 51eaffaa31c..827b93c350e 100644
--- a/source/blender/compositor/intern/COM_ExecutionGroup.cpp
+++ b/source/blender/compositor/intern/COM_ExecutionGroup.cpp
@@ -248,7 +248,7 @@ void ExecutionGroup::execute(ExecutionSystem *graph)
OrderOfChunks chunkorder = COM_ORDER_OF_CHUNKS_DEFAULT;
if (operation->isViewerOperation()) {
- ViewerBaseOperation *viewer = (ViewerBaseOperation *)operation;
+ ViewerOperation *viewer = (ViewerOperation *)operation;
centerX = viewer->getCenterX();
centerY = viewer->getCenterY();
chunkorder = viewer->getChunkOrder();
diff --git a/source/blender/compositor/intern/COM_ExecutionSystemHelper.cpp b/source/blender/compositor/intern/COM_ExecutionSystemHelper.cpp
index 9f0a943c8a2..9024cd33745 100644
--- a/source/blender/compositor/intern/COM_ExecutionSystemHelper.cpp
+++ b/source/blender/compositor/intern/COM_ExecutionSystemHelper.cpp
@@ -36,7 +36,7 @@
#include "COM_GroupNode.h"
#include "COM_WriteBufferOperation.h"
#include "COM_ReadBufferOperation.h"
-#include "COM_ViewerBaseOperation.h"
+#include "COM_ViewerOperation.h"
extern "C" {
#include "BKE_node.h"
@@ -212,7 +212,7 @@ void ExecutionSystemHelper::debugDump(ExecutionSystem *system)
printf("|");
}
if (operation->isViewerOperation()) {
- ViewerBaseOperation *viewer = (ViewerBaseOperation *)operation;
+ ViewerOperation *viewer = (ViewerOperation *)operation;
if (viewer->isActiveViewerOutput()) {
printf("Active viewer");
}
diff --git a/source/blender/compositor/intern/COM_SocketReader.h b/source/blender/compositor/intern/COM_SocketReader.h
index 88b018ef8ba..b7aae8b92f0 100644
--- a/source/blender/compositor/intern/COM_SocketReader.h
+++ b/source/blender/compositor/intern/COM_SocketReader.h
@@ -91,13 +91,13 @@ protected:
virtual void executePixel(float output[4], float x, float y, float dx, float dy, PixelSampler sampler) {}
public:
- inline void read(float *result, float x, float y, PixelSampler sampler) {
+ inline void read(float result[4], float x, float y, PixelSampler sampler) {
executePixel(result, x, y, sampler);
}
- inline void read(float *result, int x, int y, void *chunkData) {
+ inline void read(float result[4], int x, int y, void *chunkData) {
executePixel(result, x, y, chunkData);
}
- inline void read(float *result, float x, float y, float dx, float dy, PixelSampler sampler) {
+ inline void read(float result[4], float x, float y, float dx, float dy, PixelSampler sampler) {
executePixel(result, x, y, dx, dy, sampler);
}
diff --git a/source/blender/compositor/intern/COM_WorkScheduler.cpp b/source/blender/compositor/intern/COM_WorkScheduler.cpp
index e0ac767b628..1bac06fc4ab 100644
--- a/source/blender/compositor/intern/COM_WorkScheduler.cpp
+++ b/source/blender/compositor/intern/COM_WorkScheduler.cpp
@@ -81,6 +81,7 @@ int g_highlightIndex;
void **g_highlightedNodes;
void **g_highlightedNodesRead;
+#if COM_CURRENT_THREADING_MODEL == COM_TM_QUEUE
#define HIGHLIGHT(wp) \
{ \
ExecutionGroup *group = wp->getExecutionGroup(); \
@@ -103,6 +104,7 @@ void **g_highlightedNodesRead;
} \
} \
}
+#endif /* COM_CURRENT_THREADING_MODEL == COM_TM_QUEUE */
void COM_startReadHighlights()
{
diff --git a/source/blender/compositor/nodes/COM_RenderLayersNode.cpp b/source/blender/compositor/nodes/COM_RenderLayersNode.cpp
index 5259fbc7dc5..74e557c77ce 100644
--- a/source/blender/compositor/nodes/COM_RenderLayersNode.cpp
+++ b/source/blender/compositor/nodes/COM_RenderLayersNode.cpp
@@ -114,4 +114,7 @@ void RenderLayersNode::convertToOperations(ExecutionSystem *graph, CompositorCon
testSocketConnection(graph, context, 25, new RenderLayersCyclesOperation(SCE_PASS_TRANSM_DIRECT));
testSocketConnection(graph, context, 26, new RenderLayersCyclesOperation(SCE_PASS_TRANSM_INDIRECT));
testSocketConnection(graph, context, 27, new RenderLayersCyclesOperation(SCE_PASS_TRANSM_COLOR));
+ testSocketConnection(graph, context, 28, new RenderLayersCyclesOperation(SCE_PASS_SUBSURFACE_DIRECT));
+ testSocketConnection(graph, context, 29, new RenderLayersCyclesOperation(SCE_PASS_SUBSURFACE_INDIRECT));
+ testSocketConnection(graph, context, 30, new RenderLayersCyclesOperation(SCE_PASS_SUBSURFACE_COLOR));
}
diff --git a/source/blender/compositor/nodes/COM_SplitViewerNode.cpp b/source/blender/compositor/nodes/COM_SplitViewerNode.cpp
index 0293f4926db..81c0744564f 100644
--- a/source/blender/compositor/nodes/COM_SplitViewerNode.cpp
+++ b/source/blender/compositor/nodes/COM_SplitViewerNode.cpp
@@ -23,7 +23,8 @@
#include "COM_SplitViewerNode.h"
#include "BKE_global.h"
-#include "COM_SplitViewerOperation.h"
+#include "COM_SplitOperation.h"
+#include "COM_ViewerOperation.h"
#include "COM_ExecutionSystem.h"
SplitViewerNode::SplitViewerNode(bNode *editorNode) : Node(editorNode)
@@ -42,29 +43,31 @@ void SplitViewerNode::convertToOperations(ExecutionSystem *graph, CompositorCont
InputSocket *image2Socket = this->getInputSocket(1);
Image *image = (Image *)this->getbNode()->id;
ImageUser *imageUser = (ImageUser *) this->getbNode()->storage;
- if (image1Socket->isConnected() && image2Socket->isConnected()) {
- SplitViewerOperation *splitViewerOperation = new SplitViewerOperation();
- splitViewerOperation->setImage(image);
- splitViewerOperation->setImageUser(imageUser);
- splitViewerOperation->setActive(is_active);
- splitViewerOperation->setSplitPercentage(this->getbNode()->custom1);
- splitViewerOperation->setViewSettings(context->getViewSettings());
- splitViewerOperation->setDisplaySettings(context->getDisplaySettings());
+ SplitOperation *splitViewerOperation = new SplitOperation();
+ splitViewerOperation->setSplitPercentage(this->getbNode()->custom1);
+ splitViewerOperation->setXSplit(!this->getbNode()->custom2);
- /* defaults - the viewer node has these options but not exposed for split view
- * we could use the split to define an area of interest on one axis at least */
- splitViewerOperation->setChunkOrder(COM_ORDER_OF_CHUNKS_DEFAULT);
- splitViewerOperation->setCenterX(0.5f);
- splitViewerOperation->setCenterY(0.5f);
+ image1Socket->relinkConnections(splitViewerOperation->getInputSocket(0), 0, graph);
+ image2Socket->relinkConnections(splitViewerOperation->getInputSocket(1), 1, graph);
- splitViewerOperation->setXSplit(!this->getbNode()->custom2);
- image1Socket->relinkConnections(splitViewerOperation->getInputSocket(0), 0, graph);
- image2Socket->relinkConnections(splitViewerOperation->getInputSocket(1), 1, graph);
+ ViewerOperation *viewerOperation = new ViewerOperation();
+ viewerOperation->setImage(image);
+ viewerOperation->setImageUser(imageUser);
+ viewerOperation->setActive(is_active);
+ viewerOperation->setViewSettings(context->getViewSettings());
+ viewerOperation->setDisplaySettings(context->getDisplaySettings());
- if (is_active)
- addPreviewOperation(graph, context, splitViewerOperation->getInputSocket(0));
+ /* defaults - the viewer node has these options but not exposed for split view
+ * we could use the split to define an area of interest on one axis at least */
+ viewerOperation->setChunkOrder(COM_ORDER_OF_CHUNKS_DEFAULT);
+ viewerOperation->setCenterX(0.5f);
+ viewerOperation->setCenterY(0.5f);
- graph->addOperation(splitViewerOperation);
- }
+ addLink(graph, splitViewerOperation->getOutputSocket(), viewerOperation->getInputSocket(0));
+
+ addPreviewOperation(graph, context, viewerOperation->getInputSocket(0));
+
+ graph->addOperation(splitViewerOperation);
+ graph->addOperation(viewerOperation);
}
diff --git a/source/blender/compositor/operations/COM_ConvertColorToBWOperation.cpp b/source/blender/compositor/operations/COM_ConvertColorToBWOperation.cpp
index 9cff5e8eaa6..3b5aa8cd755 100644
--- a/source/blender/compositor/operations/COM_ConvertColorToBWOperation.cpp
+++ b/source/blender/compositor/operations/COM_ConvertColorToBWOperation.cpp
@@ -37,7 +37,7 @@ void ConvertColorToBWOperation::initExecution()
void ConvertColorToBWOperation::executePixel(float output[4], float x, float y, PixelSampler sampler)
{
float inputColor[4];
- this->m_inputOperation->read(&inputColor[0], x, y, sampler);
+ this->m_inputOperation->read(inputColor, x, y, sampler);
output[0] = rgb_to_bw(inputColor);
}
diff --git a/source/blender/compositor/operations/COM_ConvertColorToValueProg.cpp b/source/blender/compositor/operations/COM_ConvertColorToValueProg.cpp
index 3a65519864a..44e751d1cae 100644
--- a/source/blender/compositor/operations/COM_ConvertColorToValueProg.cpp
+++ b/source/blender/compositor/operations/COM_ConvertColorToValueProg.cpp
@@ -37,7 +37,7 @@ void ConvertColorToValueProg::initExecution()
void ConvertColorToValueProg::executePixel(float output[4], float x, float y, PixelSampler sampler)
{
float inputColor[4];
- this->m_inputOperation->read(&inputColor[0], x, y, sampler);
+ this->m_inputOperation->read(inputColor, x, y, sampler);
output[0] = (inputColor[0] + inputColor[1] + inputColor[2]) / 3.0f;
}
diff --git a/source/blender/compositor/operations/COM_MathBaseOperation.cpp b/source/blender/compositor/operations/COM_MathBaseOperation.cpp
index 3749bcf42d8..fa0c480eb70 100644
--- a/source/blender/compositor/operations/COM_MathBaseOperation.cpp
+++ b/source/blender/compositor/operations/COM_MathBaseOperation.cpp
@@ -77,8 +77,8 @@ void MathAddOperation::executePixel(float output[4], float x, float y, PixelSamp
float inputValue1[4];
float inputValue2[4];
- this->m_inputValue1Operation->read(&inputValue1[0], x, y, sampler);
- this->m_inputValue2Operation->read(&inputValue2[0], x, y, sampler);
+ this->m_inputValue1Operation->read(inputValue1, x, y, sampler);
+ this->m_inputValue2Operation->read(inputValue2, x, y, sampler);
output[0] = inputValue1[0] + inputValue2[0];
@@ -90,8 +90,8 @@ void MathSubtractOperation::executePixel(float output[4], float x, float y, Pixe
float inputValue1[4];
float inputValue2[4];
- this->m_inputValue1Operation->read(&inputValue1[0], x, y, sampler);
- this->m_inputValue2Operation->read(&inputValue2[0], x, y, sampler);
+ this->m_inputValue1Operation->read(inputValue1, x, y, sampler);
+ this->m_inputValue2Operation->read(inputValue2, x, y, sampler);
output[0] = inputValue1[0] - inputValue2[0];
@@ -103,8 +103,8 @@ void MathMultiplyOperation::executePixel(float output[4], float x, float y, Pixe
float inputValue1[4];
float inputValue2[4];
- this->m_inputValue1Operation->read(&inputValue1[0], x, y, sampler);
- this->m_inputValue2Operation->read(&inputValue2[0], x, y, sampler);
+ this->m_inputValue1Operation->read(inputValue1, x, y, sampler);
+ this->m_inputValue2Operation->read(inputValue2, x, y, sampler);
output[0] = inputValue1[0] * inputValue2[0];
@@ -116,8 +116,8 @@ void MathDivideOperation::executePixel(float output[4], float x, float y, PixelS
float inputValue1[4];
float inputValue2[4];
- this->m_inputValue1Operation->read(&inputValue1[0], x, y, sampler);
- this->m_inputValue2Operation->read(&inputValue2[0], x, y, sampler);
+ this->m_inputValue1Operation->read(inputValue1, x, y, sampler);
+ this->m_inputValue2Operation->read(inputValue2, x, y, sampler);
if (inputValue2[0] == 0) /* We don't want to divide by zero. */
output[0] = 0.0;
@@ -132,8 +132,8 @@ void MathSineOperation::executePixel(float output[4], float x, float y, PixelSam
float inputValue1[4];
float inputValue2[4];
- this->m_inputValue1Operation->read(&inputValue1[0], x, y, sampler);
- this->m_inputValue2Operation->read(&inputValue2[0], x, y, sampler);
+ this->m_inputValue1Operation->read(inputValue1, x, y, sampler);
+ this->m_inputValue2Operation->read(inputValue2, x, y, sampler);
output[0] = sin(inputValue1[0]);
@@ -145,8 +145,8 @@ void MathCosineOperation::executePixel(float output[4], float x, float y, PixelS
float inputValue1[4];
float inputValue2[4];
- this->m_inputValue1Operation->read(&inputValue1[0], x, y, sampler);
- this->m_inputValue2Operation->read(&inputValue2[0], x, y, sampler);
+ this->m_inputValue1Operation->read(inputValue1, x, y, sampler);
+ this->m_inputValue2Operation->read(inputValue2, x, y, sampler);
output[0] = cos(inputValue1[0]);
@@ -158,8 +158,8 @@ void MathTangentOperation::executePixel(float output[4], float x, float y, Pixel
float inputValue1[4];
float inputValue2[4];
- this->m_inputValue1Operation->read(&inputValue1[0], x, y, sampler);
- this->m_inputValue2Operation->read(&inputValue2[0], x, y, sampler);
+ this->m_inputValue1Operation->read(inputValue1, x, y, sampler);
+ this->m_inputValue2Operation->read(inputValue2, x, y, sampler);
output[0] = tan(inputValue1[0]);
@@ -171,8 +171,8 @@ void MathArcSineOperation::executePixel(float output[4], float x, float y, Pixel
float inputValue1[4];
float inputValue2[4];
- this->m_inputValue1Operation->read(&inputValue1[0], x, y, sampler);
- this->m_inputValue2Operation->read(&inputValue2[0], x, y, sampler);
+ this->m_inputValue1Operation->read(inputValue1, x, y, sampler);
+ this->m_inputValue2Operation->read(inputValue2, x, y, sampler);
if (inputValue1[0] <= 1 && inputValue1[0] >= -1)
output[0] = asin(inputValue1[0]);
@@ -187,8 +187,8 @@ void MathArcCosineOperation::executePixel(float output[4], float x, float y, Pix
float inputValue1[4];
float inputValue2[4];
- this->m_inputValue1Operation->read(&inputValue1[0], x, y, sampler);
- this->m_inputValue2Operation->read(&inputValue2[0], x, y, sampler);
+ this->m_inputValue1Operation->read(inputValue1, x, y, sampler);
+ this->m_inputValue2Operation->read(inputValue2, x, y, sampler);
if (inputValue1[0] <= 1 && inputValue1[0] >= -1)
output[0] = acos(inputValue1[0]);
@@ -203,8 +203,8 @@ void MathArcTangentOperation::executePixel(float output[4], float x, float y, Pi
float inputValue1[4];
float inputValue2[4];
- this->m_inputValue1Operation->read(&inputValue1[0], x, y, sampler);
- this->m_inputValue2Operation->read(&inputValue2[0], x, y, sampler);
+ this->m_inputValue1Operation->read(inputValue1, x, y, sampler);
+ this->m_inputValue2Operation->read(inputValue2, x, y, sampler);
output[0] = atan(inputValue1[0]);
@@ -216,8 +216,8 @@ void MathPowerOperation::executePixel(float output[4], float x, float y, PixelSa
float inputValue1[4];
float inputValue2[4];
- this->m_inputValue1Operation->read(&inputValue1[0], x, y, sampler);
- this->m_inputValue2Operation->read(&inputValue2[0], x, y, sampler);
+ this->m_inputValue1Operation->read(inputValue1, x, y, sampler);
+ this->m_inputValue2Operation->read(inputValue2, x, y, sampler);
if (inputValue1[0] >= 0) {
output[0] = pow(inputValue1[0], inputValue2[0]);
@@ -241,8 +241,8 @@ void MathLogarithmOperation::executePixel(float output[4], float x, float y, Pix
float inputValue1[4];
float inputValue2[4];
- this->m_inputValue1Operation->read(&inputValue1[0], x, y, sampler);
- this->m_inputValue2Operation->read(&inputValue2[0], x, y, sampler);
+ this->m_inputValue1Operation->read(inputValue1, x, y, sampler);
+ this->m_inputValue2Operation->read(inputValue2, x, y, sampler);
if (inputValue1[0] > 0 && inputValue2[0] > 0)
output[0] = log(inputValue1[0]) / log(inputValue2[0]);
@@ -257,8 +257,8 @@ void MathMinimumOperation::executePixel(float output[4], float x, float y, Pixel
float inputValue1[4];
float inputValue2[4];
- this->m_inputValue1Operation->read(&inputValue1[0], x, y, sampler);
- this->m_inputValue2Operation->read(&inputValue2[0], x, y, sampler);
+ this->m_inputValue1Operation->read(inputValue1, x, y, sampler);
+ this->m_inputValue2Operation->read(inputValue2, x, y, sampler);
output[0] = min(inputValue1[0], inputValue2[0]);
@@ -270,8 +270,8 @@ void MathMaximumOperation::executePixel(float output[4], float x, float y, Pixel
float inputValue1[4];
float inputValue2[4];
- this->m_inputValue1Operation->read(&inputValue1[0], x, y, sampler);
- this->m_inputValue2Operation->read(&inputValue2[0], x, y, sampler);
+ this->m_inputValue1Operation->read(inputValue1, x, y, sampler);
+ this->m_inputValue2Operation->read(inputValue2, x, y, sampler);
output[0] = max(inputValue1[0], inputValue2[0]);
@@ -283,8 +283,8 @@ void MathRoundOperation::executePixel(float output[4], float x, float y, PixelSa
float inputValue1[4];
float inputValue2[4];
- this->m_inputValue1Operation->read(&inputValue1[0], x, y, sampler);
- this->m_inputValue2Operation->read(&inputValue2[0], x, y, sampler);
+ this->m_inputValue1Operation->read(inputValue1, x, y, sampler);
+ this->m_inputValue2Operation->read(inputValue2, x, y, sampler);
output[0] = round(inputValue1[0]);
@@ -296,8 +296,8 @@ void MathLessThanOperation::executePixel(float output[4], float x, float y, Pixe
float inputValue1[4];
float inputValue2[4];
- this->m_inputValue1Operation->read(&inputValue1[0], x, y, sampler);
- this->m_inputValue2Operation->read(&inputValue2[0], x, y, sampler);
+ this->m_inputValue1Operation->read(inputValue1, x, y, sampler);
+ this->m_inputValue2Operation->read(inputValue2, x, y, sampler);
output[0] = inputValue1[0] < inputValue2[0] ? 1.0f : 0.0f;
@@ -309,8 +309,8 @@ void MathGreaterThanOperation::executePixel(float output[4], float x, float y, P
float inputValue1[4];
float inputValue2[4];
- this->m_inputValue1Operation->read(&inputValue1[0], x, y, sampler);
- this->m_inputValue2Operation->read(&inputValue2[0], x, y, sampler);
+ this->m_inputValue1Operation->read(inputValue1, x, y, sampler);
+ this->m_inputValue2Operation->read(inputValue2, x, y, sampler);
output[0] = inputValue1[0] > inputValue2[0] ? 1.0f : 0.0f;
@@ -322,8 +322,8 @@ void MathModuloOperation::executePixel(float output[4], float x, float y, PixelS
float inputValue1[4];
float inputValue2[4];
- this->m_inputValue1Operation->read(&inputValue1[0], x, y, sampler);
- this->m_inputValue2Operation->read(&inputValue2[0], x, y, sampler);
+ this->m_inputValue1Operation->read(inputValue1, x, y, sampler);
+ this->m_inputValue2Operation->read(inputValue2, x, y, sampler);
if (inputValue2[0] == 0)
output[0] = 0.0;
diff --git a/source/blender/compositor/operations/COM_MixAddOperation.cpp b/source/blender/compositor/operations/COM_MixAddOperation.cpp
index be737f22280..4e0876439c0 100644
--- a/source/blender/compositor/operations/COM_MixAddOperation.cpp
+++ b/source/blender/compositor/operations/COM_MixAddOperation.cpp
@@ -37,7 +37,6 @@ void MixAddOperation::executePixel(float output[4], float x, float y, PixelSampl
this->m_inputColor1Operation->read(inputColor1, x, y, sampler);
this->m_inputColor2Operation->read(inputColor2, x, y, sampler);
-
float value = inputValue[0];
if (this->useValueAlphaMultiply()) {
value *= inputColor2[3];
diff --git a/source/blender/compositor/operations/COM_MixBurnOperation.cpp b/source/blender/compositor/operations/COM_MixBurnOperation.cpp
index 5cfe38766bc..d4422c6cc6a 100644
--- a/source/blender/compositor/operations/COM_MixBurnOperation.cpp
+++ b/source/blender/compositor/operations/COM_MixBurnOperation.cpp
@@ -31,13 +31,14 @@ void MixBurnOperation::executePixel(float output[4], float x, float y, PixelSamp
{
float inputColor1[4];
float inputColor2[4];
- float value;
+ float inputValue[4];
float tmp;
- this->m_inputValueOperation->read(&value, x, y, sampler);
- this->m_inputColor1Operation->read(&inputColor1[0], x, y, sampler);
- this->m_inputColor2Operation->read(&inputColor2[0], x, y, sampler);
+ this->m_inputValueOperation->read(inputValue, x, y, sampler);
+ this->m_inputColor1Operation->read(inputColor1, x, y, sampler);
+ this->m_inputColor2Operation->read(inputColor2, x, y, sampler);
+ float value = inputValue[0];
if (this->useValueAlphaMultiply()) {
value *= inputColor2[3];
}
diff --git a/source/blender/compositor/operations/COM_MixColorOperation.cpp b/source/blender/compositor/operations/COM_MixColorOperation.cpp
index 56aca27eaef..6919a636aeb 100644
--- a/source/blender/compositor/operations/COM_MixColorOperation.cpp
+++ b/source/blender/compositor/operations/COM_MixColorOperation.cpp
@@ -35,12 +35,13 @@ void MixColorOperation::executePixel(float output[4], float x, float y, PixelSam
{
float inputColor1[4];
float inputColor2[4];
- float value;
+ float inputValue[4];
- this->m_inputValueOperation->read(&value, x, y, sampler);
- this->m_inputColor1Operation->read(&inputColor1[0], x, y, sampler);
- this->m_inputColor2Operation->read(&inputColor2[0], x, y, sampler);
+ this->m_inputValueOperation->read(inputValue, x, y, sampler);
+ this->m_inputColor1Operation->read(inputColor1, x, y, sampler);
+ this->m_inputColor2Operation->read(inputColor2, x, y, sampler);
+ float value = inputValue[0];
if (this->useValueAlphaMultiply()) {
value *= inputColor2[3];
}
diff --git a/source/blender/compositor/operations/COM_MixDarkenOperation.cpp b/source/blender/compositor/operations/COM_MixDarkenOperation.cpp
index 5b79f4c95ac..d56d9fdf122 100644
--- a/source/blender/compositor/operations/COM_MixDarkenOperation.cpp
+++ b/source/blender/compositor/operations/COM_MixDarkenOperation.cpp
@@ -31,12 +31,13 @@ void MixDarkenOperation::executePixel(float output[4], float x, float y, PixelSa
{
float inputColor1[4];
float inputColor2[4];
- float value;
+ float inputValue[4];
- this->m_inputValueOperation->read(&value, x, y, sampler);
- this->m_inputColor1Operation->read(&inputColor1[0], x, y, sampler);
- this->m_inputColor2Operation->read(&inputColor2[0], x, y, sampler);
+ this->m_inputValueOperation->read(inputValue, x, y, sampler);
+ this->m_inputColor1Operation->read(inputColor1, x, y, sampler);
+ this->m_inputColor2Operation->read(inputColor2, x, y, sampler);
+ float value = inputValue[0];
if (this->useValueAlphaMultiply()) {
value *= inputColor2[3];
}
diff --git a/source/blender/compositor/operations/COM_MixDifferenceOperation.cpp b/source/blender/compositor/operations/COM_MixDifferenceOperation.cpp
index d2c1e5e428f..13494401c60 100644
--- a/source/blender/compositor/operations/COM_MixDifferenceOperation.cpp
+++ b/source/blender/compositor/operations/COM_MixDifferenceOperation.cpp
@@ -32,12 +32,13 @@ void MixDifferenceOperation::executePixel(float output[4], float x, float y, Pix
{
float inputColor1[4];
float inputColor2[4];
- float value;
-
- this->m_inputValueOperation->read(&value, x, y, sampler);
- this->m_inputColor1Operation->read(&inputColor1[0], x, y, sampler);
- this->m_inputColor2Operation->read(&inputColor2[0], x, y, sampler);
+ float inputValue[4];
+ this->m_inputValueOperation->read(inputValue, x, y, sampler);
+ this->m_inputColor1Operation->read(inputColor1, x, y, sampler);
+ this->m_inputColor2Operation->read(inputColor2, x, y, sampler);
+
+ float value = inputValue[0];
if (this->useValueAlphaMultiply()) {
value *= inputColor2[3];
}
diff --git a/source/blender/compositor/operations/COM_MixDivideOperation.cpp b/source/blender/compositor/operations/COM_MixDivideOperation.cpp
index fdb1618b6e6..3e0eb66565c 100644
--- a/source/blender/compositor/operations/COM_MixDivideOperation.cpp
+++ b/source/blender/compositor/operations/COM_MixDivideOperation.cpp
@@ -31,12 +31,13 @@ void MixDivideOperation::executePixel(float output[4], float x, float y, PixelSa
{
float inputColor1[4];
float inputColor2[4];
- float value;
-
- this->m_inputValueOperation->read(&value, x, y, sampler);
- this->m_inputColor1Operation->read(&inputColor1[0], x, y, sampler);
- this->m_inputColor2Operation->read(&inputColor2[0], x, y, sampler);
+ float inputValue[4];
+ this->m_inputValueOperation->read(inputValue, x, y, sampler);
+ this->m_inputColor1Operation->read(inputColor1, x, y, sampler);
+ this->m_inputColor2Operation->read(inputColor2, x, y, sampler);
+
+ float value = inputValue[0];
if (this->useValueAlphaMultiply()) {
value *= inputColor2[3];
}
diff --git a/source/blender/compositor/operations/COM_MixDodgeOperation.cpp b/source/blender/compositor/operations/COM_MixDodgeOperation.cpp
index 87f60df8e1b..acb39f665ff 100644
--- a/source/blender/compositor/operations/COM_MixDodgeOperation.cpp
+++ b/source/blender/compositor/operations/COM_MixDodgeOperation.cpp
@@ -31,13 +31,14 @@ void MixDodgeOperation::executePixel(float output[4], float x, float y, PixelSam
{
float inputColor1[4];
float inputColor2[4];
- float value;
+ float inputValue[4];
float tmp;
- this->m_inputValueOperation->read(&value, x, y, sampler);
- this->m_inputColor1Operation->read(&inputColor1[0], x, y, sampler);
- this->m_inputColor2Operation->read(&inputColor2[0], x, y, sampler);
+ this->m_inputValueOperation->read(inputValue, x, y, sampler);
+ this->m_inputColor1Operation->read(inputColor1, x, y, sampler);
+ this->m_inputColor2Operation->read(inputColor2, x, y, sampler);
+ float value = inputValue[0];
if (this->useValueAlphaMultiply()) {
value *= inputColor2[3];
}
diff --git a/source/blender/compositor/operations/COM_MixHueOperation.cpp b/source/blender/compositor/operations/COM_MixHueOperation.cpp
index 12cd16bb73b..64c88592b93 100644
--- a/source/blender/compositor/operations/COM_MixHueOperation.cpp
+++ b/source/blender/compositor/operations/COM_MixHueOperation.cpp
@@ -35,12 +35,13 @@ void MixHueOperation::executePixel(float output[4], float x, float y, PixelSampl
{
float inputColor1[4];
float inputColor2[4];
- float value;
+ float inputValue[4];
- this->m_inputValueOperation->read(&value, x, y, sampler);
- this->m_inputColor1Operation->read(&inputColor1[0], x, y, sampler);
- this->m_inputColor2Operation->read(&inputColor2[0], x, y, sampler);
+ this->m_inputValueOperation->read(inputValue, x, y, sampler);
+ this->m_inputColor1Operation->read(inputColor1, x, y, sampler);
+ this->m_inputColor2Operation->read(inputColor2, x, y, sampler);
+ float value = inputValue[0];
if (this->useValueAlphaMultiply()) {
value *= inputColor2[3];
}
diff --git a/source/blender/compositor/operations/COM_MixLightenOperation.cpp b/source/blender/compositor/operations/COM_MixLightenOperation.cpp
index 9eb45a783f8..a468fb39442 100644
--- a/source/blender/compositor/operations/COM_MixLightenOperation.cpp
+++ b/source/blender/compositor/operations/COM_MixLightenOperation.cpp
@@ -31,12 +31,13 @@ void MixLightenOperation::executePixel(float output[4], float x, float y, PixelS
{
float inputColor1[4];
float inputColor2[4];
- float value;
-
- this->m_inputValueOperation->read(&value, x, y, sampler);
- this->m_inputColor1Operation->read(&inputColor1[0], x, y, sampler);
- this->m_inputColor2Operation->read(&inputColor2[0], x, y, sampler);
+ float inputValue[4];
+ this->m_inputValueOperation->read(inputValue, x, y, sampler);
+ this->m_inputColor1Operation->read(inputColor1, x, y, sampler);
+ this->m_inputColor2Operation->read(inputColor2, x, y, sampler);
+
+ float value = inputValue[0];
if (this->useValueAlphaMultiply()) {
value *= inputColor2[3];
}
diff --git a/source/blender/compositor/operations/COM_MixLinearLightOperation.cpp b/source/blender/compositor/operations/COM_MixLinearLightOperation.cpp
index ee7dcc9fe28..e1b5e040f0f 100644
--- a/source/blender/compositor/operations/COM_MixLinearLightOperation.cpp
+++ b/source/blender/compositor/operations/COM_MixLinearLightOperation.cpp
@@ -31,12 +31,13 @@ void MixLinearLightOperation::executePixel(float output[4], float x, float y, Pi
{
float inputColor1[4];
float inputColor2[4];
- float value;
-
- this->m_inputValueOperation->read(&value, x, y, sampler);
- this->m_inputColor1Operation->read(&inputColor1[0], x, y, sampler);
- this->m_inputColor2Operation->read(&inputColor2[0], x, y, sampler);
-
+ float inputValue[4];
+
+ this->m_inputValueOperation->read(inputValue, x, y, sampler);
+ this->m_inputColor1Operation->read(inputColor1, x, y, sampler);
+ this->m_inputColor2Operation->read(inputColor2, x, y, sampler);
+
+ float value = inputValue[0];
if (this->useValueAlphaMultiply()) {
value *= inputColor2[3];
}
diff --git a/source/blender/compositor/operations/COM_MixOverlayOperation.cpp b/source/blender/compositor/operations/COM_MixOverlayOperation.cpp
index 09a9d3cbc4f..d5e1c6d1167 100644
--- a/source/blender/compositor/operations/COM_MixOverlayOperation.cpp
+++ b/source/blender/compositor/operations/COM_MixOverlayOperation.cpp
@@ -31,12 +31,13 @@ void MixOverlayOperation::executePixel(float output[4], float x, float y, PixelS
{
float inputColor1[4];
float inputColor2[4];
- float value;
+ float inputValue[4];
- this->m_inputValueOperation->read(&value, x, y, sampler);
- this->m_inputColor1Operation->read(&inputColor1[0], x, y, sampler);
- this->m_inputColor2Operation->read(&inputColor2[0], x, y, sampler);
+ this->m_inputValueOperation->read(inputValue, x, y, sampler);
+ this->m_inputColor1Operation->read(inputColor1, x, y, sampler);
+ this->m_inputColor2Operation->read(inputColor2, x, y, sampler);
+ float value = inputValue[0];
if (this->useValueAlphaMultiply()) {
value *= inputColor2[3];
}
diff --git a/source/blender/compositor/operations/COM_MixSaturationOperation.cpp b/source/blender/compositor/operations/COM_MixSaturationOperation.cpp
index 3ab19748458..ca45a1c703a 100644
--- a/source/blender/compositor/operations/COM_MixSaturationOperation.cpp
+++ b/source/blender/compositor/operations/COM_MixSaturationOperation.cpp
@@ -35,12 +35,13 @@ void MixSaturationOperation::executePixel(float output[4], float x, float y, Pix
{
float inputColor1[4];
float inputColor2[4];
- float value;
+ float inputValue[4];
- this->m_inputValueOperation->read(&value, x, y, sampler);
- this->m_inputColor1Operation->read(&inputColor1[0], x, y, sampler);
- this->m_inputColor2Operation->read(&inputColor2[0], x, y, sampler);
+ this->m_inputValueOperation->read(inputValue, x, y, sampler);
+ this->m_inputColor1Operation->read(inputColor1, x, y, sampler);
+ this->m_inputColor2Operation->read(inputColor2, x, y, sampler);
+ float value = inputValue[0];
if (this->useValueAlphaMultiply()) {
value *= inputColor2[3];
}
diff --git a/source/blender/compositor/operations/COM_MixScreenOperation.cpp b/source/blender/compositor/operations/COM_MixScreenOperation.cpp
index 671ffd3303c..511768a49ad 100644
--- a/source/blender/compositor/operations/COM_MixScreenOperation.cpp
+++ b/source/blender/compositor/operations/COM_MixScreenOperation.cpp
@@ -31,13 +31,13 @@ void MixScreenOperation::executePixel(float output[4], float x, float y, PixelSa
{
float inputColor1[4];
float inputColor2[4];
- float valuev[4];
+ float inputValue[4];
- this->m_inputValueOperation->read(valuev, x, y, sampler);
- this->m_inputColor1Operation->read(&inputColor1[0], x, y, sampler);
- this->m_inputColor2Operation->read(&inputColor2[0], x, y, sampler);
+ this->m_inputValueOperation->read(inputValue, x, y, sampler);
+ this->m_inputColor1Operation->read(inputColor1, x, y, sampler);
+ this->m_inputColor2Operation->read(inputColor2, x, y, sampler);
- float value = valuev[0];
+ float value = inputValue[0];
if (this->useValueAlphaMultiply()) {
value *= inputColor2[3];
}
diff --git a/source/blender/compositor/operations/COM_MixSoftLightOperation.cpp b/source/blender/compositor/operations/COM_MixSoftLightOperation.cpp
index 604881ae47f..71d83ce54ea 100644
--- a/source/blender/compositor/operations/COM_MixSoftLightOperation.cpp
+++ b/source/blender/compositor/operations/COM_MixSoftLightOperation.cpp
@@ -31,12 +31,13 @@ void MixSoftLightOperation::executePixel(float output[4], float x, float y, Pixe
{
float inputColor1[4];
float inputColor2[4];
- float value;
+ float inputValue[4];
- this->m_inputValueOperation->read(&value, x, y, sampler);
- this->m_inputColor1Operation->read(&inputColor1[0], x, y, sampler);
- this->m_inputColor2Operation->read(&inputColor2[0], x, y, sampler);
+ this->m_inputValueOperation->read(inputValue, x, y, sampler);
+ this->m_inputColor1Operation->read(inputColor1, x, y, sampler);
+ this->m_inputColor2Operation->read(inputColor2, x, y, sampler);
+ float value = inputValue[0];
if (this->useValueAlphaMultiply()) {
value *= inputColor2[3];
}
diff --git a/source/blender/compositor/operations/COM_MixSubtractOperation.cpp b/source/blender/compositor/operations/COM_MixSubtractOperation.cpp
index a446dfe4e54..e6efe0f62f3 100644
--- a/source/blender/compositor/operations/COM_MixSubtractOperation.cpp
+++ b/source/blender/compositor/operations/COM_MixSubtractOperation.cpp
@@ -31,12 +31,13 @@ void MixSubtractOperation::executePixel(float output[4], float x, float y, Pixel
{
float inputColor1[4];
float inputColor2[4];
- float value;
+ float inputValue[4];
- this->m_inputValueOperation->read(&value, x, y, sampler);
- this->m_inputColor1Operation->read(&inputColor1[0], x, y, sampler);
- this->m_inputColor2Operation->read(&inputColor2[0], x, y, sampler);
+ this->m_inputValueOperation->read(inputValue, x, y, sampler);
+ this->m_inputColor1Operation->read(inputColor1, x, y, sampler);
+ this->m_inputColor2Operation->read(inputColor2, x, y, sampler);
+ float value = inputValue[0];
if (this->useValueAlphaMultiply()) {
value *= inputColor2[3];
}
diff --git a/source/blender/compositor/operations/COM_MixValueOperation.cpp b/source/blender/compositor/operations/COM_MixValueOperation.cpp
index caefdf024cc..553041e39bf 100644
--- a/source/blender/compositor/operations/COM_MixValueOperation.cpp
+++ b/source/blender/compositor/operations/COM_MixValueOperation.cpp
@@ -35,12 +35,13 @@ void MixValueOperation::executePixel(float output[4], float x, float y, PixelSam
{
float inputColor1[4];
float inputColor2[4];
- float value;
+ float inputValue[4];
- this->m_inputValueOperation->read(&value, x, y, sampler);
- this->m_inputColor1Operation->read(&inputColor1[0], x, y, sampler);
- this->m_inputColor2Operation->read(&inputColor2[0], x, y, sampler);
+ this->m_inputValueOperation->read(inputValue, x, y, sampler);
+ this->m_inputColor1Operation->read(inputColor1, x, y, sampler);
+ this->m_inputColor2Operation->read(inputColor2, x, y, sampler);
+ float value = inputValue[0];
if (this->useValueAlphaMultiply()) {
value *= inputColor2[3];
}
diff --git a/source/blender/compositor/operations/COM_SplitViewerOperation.cpp b/source/blender/compositor/operations/COM_SplitOperation.cpp
index 7325e32a863..a7dbccfc2f7 100644
--- a/source/blender/compositor/operations/COM_SplitViewerOperation.cpp
+++ b/source/blender/compositor/operations/COM_SplitOperation.cpp
@@ -20,7 +20,7 @@
* Monique Dewanchand
*/
-#include "COM_SplitViewerOperation.h"
+#include "COM_SplitOperation.h"
#include "COM_SocketConnection.h"
#include "BLI_listbase.h"
#include "BKE_image.h"
@@ -35,58 +35,47 @@ extern "C" {
}
-SplitViewerOperation::SplitViewerOperation() : ViewerBaseOperation()
+SplitOperation::SplitOperation() : NodeOperation()
{
this->addInputSocket(COM_DT_COLOR);
this->addInputSocket(COM_DT_COLOR);
+ this->addOutputSocket(COM_DT_COLOR);
this->m_image1Input = NULL;
this->m_image2Input = NULL;
}
-void SplitViewerOperation::initExecution()
+void SplitOperation::initExecution()
{
// When initializing the tree during initial load the width and height can be zero.
this->m_image1Input = getInputSocketReader(0);
this->m_image2Input = getInputSocketReader(1);
- ViewerBaseOperation::initExecution();
}
-void SplitViewerOperation::deinitExecution()
+void SplitOperation::deinitExecution()
{
this->m_image1Input = NULL;
this->m_image2Input = NULL;
- ViewerBaseOperation::deinitExecution();
}
-
-void SplitViewerOperation::executeRegion(rcti *rect, unsigned int tileNumber)
+void SplitOperation::executePixel(float output[4], float x, float y, PixelSampler sampler)
{
- float *buffer = this->m_outputBuffer;
-
- if (!buffer) return;
- int x1 = rect->xmin;
- int y1 = rect->ymin;
- int x2 = rect->xmax;
- int y2 = rect->ymax;
- int offset = (y1 * this->getWidth() + x1) * 4;
- int x;
- int y;
int perc = this->m_xSplit ? this->m_splitPercentage * this->getWidth() / 100.0f : this->m_splitPercentage * this->getHeight() / 100.0f;
- for (y = y1; y < y2; y++) {
- for (x = x1; x < x2; x++) {
- bool image1;
- image1 = this->m_xSplit ? x > perc : y > perc;
- if (image1) {
- this->m_image1Input->read(&(buffer[offset]), x, y, COM_PS_NEAREST);
- }
- else {
- this->m_image2Input->read(&(buffer[offset]), x, y, COM_PS_NEAREST);
- }
-
- offset += 4;
- }
- offset += (this->getWidth() - (x2 - x1)) * 4;
+ bool image1 = this->m_xSplit ? x > perc : y > perc;
+ if (image1) {
+ this->m_image1Input->read(output, x, y, COM_PS_NEAREST);
+ }
+ else {
+ this->m_image2Input->read(output, x, y, COM_PS_NEAREST);
}
- updateImage(rect);
}
+void SplitOperation::determineResolution(unsigned int resolution[2], unsigned int preferredResolution[2])
+{
+ unsigned int tempPreferredResolution[2] = {0, 0};
+ unsigned int tempResolution[2];
+
+ this->getInputSocket(0)->determineResolution(tempResolution, tempPreferredResolution);
+ this->setResolutionInputSocketIndex((tempResolution[0] && tempResolution[1]) ? 0 : 1);
+
+ NodeOperation::determineResolution(resolution, preferredResolution);
+}
diff --git a/source/blender/compositor/operations/COM_SplitViewerOperation.h b/source/blender/compositor/operations/COM_SplitOperation.h
index c759e14e1dd..5a042b789d8 100644
--- a/source/blender/compositor/operations/COM_SplitViewerOperation.h
+++ b/source/blender/compositor/operations/COM_SplitOperation.h
@@ -20,13 +20,11 @@
* Monique Dewanchand
*/
-#ifndef _COM_SplitViewerOperation_h
-#define _COM_SplitViewerOperation_h
-#include "COM_ViewerBaseOperation.h"
-#include "DNA_image_types.h"
-#include "BLI_rect.h"
+#ifndef _COM_SplitOperation_h
+#define _COM_SplitOperation_h
+#include "COM_NodeOperation.h"
-class SplitViewerOperation : public ViewerBaseOperation {
+class SplitOperation : public NodeOperation {
private:
SocketReader *m_image1Input;
SocketReader *m_image2Input;
@@ -34,10 +32,11 @@ private:
float m_splitPercentage;
bool m_xSplit;
public:
- SplitViewerOperation();
- void executeRegion(rcti *rect, unsigned int tileNumber);
+ SplitOperation();
void initExecution();
void deinitExecution();
+ void executePixel(float output[4], float x, float y, PixelSampler sampler);
+ void determineResolution(unsigned int resolution[2], unsigned int preferredResolution[2]);
void setSplitPercentage(float splitPercentage) { this->m_splitPercentage = splitPercentage; }
void setXSplit(bool xsplit) { this->m_xSplit = xsplit; }
};
diff --git a/source/blender/compositor/operations/COM_ViewerBaseOperation.cpp b/source/blender/compositor/operations/COM_ViewerBaseOperation.cpp
deleted file mode 100644
index 072246932db..00000000000
--- a/source/blender/compositor/operations/COM_ViewerBaseOperation.cpp
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
- * Copyright 2011, Blender Foundation.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * Contributor:
- * Jeroen Bakker
- * Monique Dewanchand
- */
-
-#include "COM_ViewerBaseOperation.h"
-#include "COM_SocketConnection.h"
-#include "BLI_listbase.h"
-#include "BKE_image.h"
-#include "WM_api.h"
-#include "WM_types.h"
-#include "PIL_time.h"
-#include "BLI_utildefines.h"
-#include "BLI_math_color.h"
-
-extern "C" {
- #include "MEM_guardedalloc.h"
- #include "IMB_imbuf.h"
- #include "IMB_imbuf_types.h"
- #include "IMB_colormanagement.h"
-}
-
-
-ViewerBaseOperation::ViewerBaseOperation() : NodeOperation()
-{
- this->setImage(NULL);
- this->setImageUser(NULL);
- this->m_outputBuffer = NULL;
- this->m_depthBuffer = NULL;
- this->m_active = false;
- this->m_doDepthBuffer = false;
- this->m_viewSettings = NULL;
- this->m_displaySettings = NULL;
- this->m_ignoreAlpha = false;
-}
-
-void ViewerBaseOperation::initExecution()
-{
- if (isActiveViewerOutput()) {
- initImage();
- }
-}
-
-void ViewerBaseOperation::initImage()
-{
- Image *anImage = this->m_image;
- ImBuf *ibuf = BKE_image_acquire_ibuf(anImage, this->m_imageUser, &this->m_lock);
-
- if (!ibuf) return;
- BLI_lock_thread(LOCK_DRAW_IMAGE);
- if (ibuf->x != (int)getWidth() || ibuf->y != (int)getHeight()) {
-
- imb_freerectImBuf(ibuf);
- imb_freerectfloatImBuf(ibuf);
- IMB_freezbuffloatImBuf(ibuf);
- ibuf->x = getWidth();
- ibuf->y = getHeight();
- imb_addrectfloatImBuf(ibuf);
- anImage->ok = IMA_OK_LOADED;
-
- ibuf->userflags |= IB_DISPLAY_BUFFER_INVALID;
-
- BLI_unlock_thread(LOCK_DRAW_IMAGE);
- }
-
- if (m_doDepthBuffer) {
- addzbuffloatImBuf(ibuf);
- }
- BLI_unlock_thread(LOCK_DRAW_IMAGE);
-
- /* now we combine the input with ibuf */
- this->m_outputBuffer = ibuf->rect_float;
-
- /* needed for display buffer update */
- this->m_ibuf = ibuf;
-
- if (m_doDepthBuffer) {
- this->m_depthBuffer = ibuf->zbuf_float;
- }
-
- BKE_image_release_ibuf(this->m_image, this->m_ibuf, this->m_lock);
-}
-
-void ViewerBaseOperation:: updateImage(rcti *rect)
-{
- IMB_partial_display_buffer_update(this->m_ibuf, this->m_outputBuffer, NULL, getWidth(), 0, 0,
- this->m_viewSettings, this->m_displaySettings,
- rect->xmin, rect->ymin, rect->xmax, rect->ymax, FALSE);
-
- this->updateDraw();
-}
-
-void ViewerBaseOperation::deinitExecution()
-{
- this->m_outputBuffer = NULL;
-}
-
-const CompositorPriority ViewerBaseOperation::getRenderPriority() const
-{
- if (this->isActiveViewerOutput()) {
- return COM_PRIORITY_HIGH;
- }
- else {
- return COM_PRIORITY_LOW;
- }
-}
diff --git a/source/blender/compositor/operations/COM_ViewerBaseOperation.h b/source/blender/compositor/operations/COM_ViewerBaseOperation.h
deleted file mode 100644
index 7ead96b5c29..00000000000
--- a/source/blender/compositor/operations/COM_ViewerBaseOperation.h
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * Copyright 2011, Blender Foundation.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * Contributor:
- * Jeroen Bakker
- * Monique Dewanchand
- */
-
-#ifndef _COM_ViewerBaseOperation_h
-#define _COM_ViewerBaseOperation_h
-#include "COM_NodeOperation.h"
-#include "DNA_image_types.h"
-#include "BLI_rect.h"
-#include "BKE_global.h"
-
-class ViewerBaseOperation : public NodeOperation {
-protected:
- float *m_outputBuffer;
- float *m_depthBuffer;
- Image *m_image;
- ImageUser *m_imageUser;
- void *m_lock;
- bool m_active;
- float m_centerX;
- float m_centerY;
- OrderOfChunks m_chunkOrder;
- bool m_doDepthBuffer;
- ImBuf *m_ibuf;
- bool m_ignoreAlpha;
-
- const ColorManagedViewSettings *m_viewSettings;
- const ColorManagedDisplaySettings *m_displaySettings;
-
-public:
- bool isOutputOperation(bool rendering) const { if (G.background) return false; return isActiveViewerOutput(); }
- void initExecution();
- void deinitExecution();
- void setImage(Image *image) { this->m_image = image; }
- void setImageUser(ImageUser *imageUser) { this->m_imageUser = imageUser; }
- const bool isActiveViewerOutput() const { return this->m_active; }
- void setActive(bool active) { this->m_active = active; }
- void setCenterX(float centerX) { this->m_centerX = centerX;}
- void setCenterY(float centerY) { this->m_centerY = centerY;}
- void setChunkOrder(OrderOfChunks tileOrder) { this->m_chunkOrder = tileOrder; }
- float getCenterX() { return this->m_centerX; }
- float getCenterY() { return this->m_centerY; }
- OrderOfChunks getChunkOrder() { return this->m_chunkOrder; }
- const CompositorPriority getRenderPriority() const;
- bool isViewerOperation() { return true; }
- void setIgnoreAlpha(bool value) { this->m_ignoreAlpha = value; }
-
- void setViewSettings(const ColorManagedViewSettings *viewSettings) { this->m_viewSettings = viewSettings; }
- void setDisplaySettings(const ColorManagedDisplaySettings *displaySettings) { this->m_displaySettings = displaySettings; }
-protected:
- ViewerBaseOperation();
- void updateImage(rcti *rect);
-
-private:
- void initImage();
-};
-#endif
diff --git a/source/blender/compositor/operations/COM_ViewerOperation.cpp b/source/blender/compositor/operations/COM_ViewerOperation.cpp
index 4d10e49aeeb..e9f083178e4 100644
--- a/source/blender/compositor/operations/COM_ViewerOperation.cpp
+++ b/source/blender/compositor/operations/COM_ViewerOperation.cpp
@@ -35,11 +35,22 @@ extern "C" {
#include "MEM_guardedalloc.h"
#include "IMB_imbuf.h"
#include "IMB_imbuf_types.h"
+ #include "IMB_colormanagement.h"
}
-ViewerOperation::ViewerOperation() : ViewerBaseOperation()
+ViewerOperation::ViewerOperation() : NodeOperation()
{
+ this->setImage(NULL);
+ this->setImageUser(NULL);
+ this->m_outputBuffer = NULL;
+ this->m_depthBuffer = NULL;
+ this->m_active = false;
+ this->m_doDepthBuffer = false;
+ this->m_viewSettings = NULL;
+ this->m_displaySettings = NULL;
+ this->m_ignoreAlpha = false;
+
this->addInputSocket(COM_DT_COLOR);
this->addInputSocket(COM_DT_VALUE);
this->addInputSocket(COM_DT_VALUE);
@@ -56,7 +67,10 @@ void ViewerOperation::initExecution()
this->m_alphaInput = getInputSocketReader(1);
this->m_depthInput = getInputSocketReader(2);
this->m_doDepthBuffer = (this->m_depthInput != NULL);
- ViewerBaseOperation::initExecution();
+
+ if (isActiveViewerOutput()) {
+ initImage();
+ }
}
void ViewerOperation::deinitExecution()
@@ -64,10 +78,9 @@ void ViewerOperation::deinitExecution()
this->m_imageInput = NULL;
this->m_alphaInput = NULL;
this->m_depthInput = NULL;
- ViewerBaseOperation::deinitExecution();
+ this->m_outputBuffer = NULL;
}
-
void ViewerOperation::executeRegion(rcti *rect, unsigned int tileNumber)
{
float *buffer = this->m_outputBuffer;
@@ -114,3 +127,63 @@ void ViewerOperation::executeRegion(rcti *rect, unsigned int tileNumber)
}
updateImage(rect);
}
+
+void ViewerOperation::initImage()
+{
+ Image *ima = this->m_image;
+ void *lock;
+ ImBuf *ibuf = BKE_image_acquire_ibuf(ima, this->m_imageUser, &lock);
+
+ if (!ibuf) return;
+ BLI_lock_thread(LOCK_DRAW_IMAGE);
+ if (ibuf->x != (int)getWidth() || ibuf->y != (int)getHeight()) {
+
+ imb_freerectImBuf(ibuf);
+ imb_freerectfloatImBuf(ibuf);
+ IMB_freezbuffloatImBuf(ibuf);
+ ibuf->x = getWidth();
+ ibuf->y = getHeight();
+ imb_addrectfloatImBuf(ibuf);
+ ima->ok = IMA_OK_LOADED;
+
+ ibuf->userflags |= IB_DISPLAY_BUFFER_INVALID;
+
+ BLI_unlock_thread(LOCK_DRAW_IMAGE);
+ }
+
+ if (m_doDepthBuffer) {
+ addzbuffloatImBuf(ibuf);
+ }
+ BLI_unlock_thread(LOCK_DRAW_IMAGE);
+
+ /* now we combine the input with ibuf */
+ this->m_outputBuffer = ibuf->rect_float;
+
+ /* needed for display buffer update */
+ this->m_ibuf = ibuf;
+
+ if (m_doDepthBuffer) {
+ this->m_depthBuffer = ibuf->zbuf_float;
+ }
+
+ BKE_image_release_ibuf(this->m_image, this->m_ibuf, lock);
+}
+
+void ViewerOperation::updateImage(rcti *rect)
+{
+ IMB_partial_display_buffer_update(this->m_ibuf, this->m_outputBuffer, NULL, getWidth(), 0, 0,
+ this->m_viewSettings, this->m_displaySettings,
+ rect->xmin, rect->ymin, rect->xmax, rect->ymax, FALSE);
+
+ this->updateDraw();
+}
+
+const CompositorPriority ViewerOperation::getRenderPriority() const
+{
+ if (this->isActiveViewerOutput()) {
+ return COM_PRIORITY_HIGH;
+ }
+ else {
+ return COM_PRIORITY_LOW;
+ }
+}
diff --git a/source/blender/compositor/operations/COM_ViewerOperation.h b/source/blender/compositor/operations/COM_ViewerOperation.h
index 262efd87dba..0b8d08d3974 100644
--- a/source/blender/compositor/operations/COM_ViewerOperation.h
+++ b/source/blender/compositor/operations/COM_ViewerOperation.h
@@ -25,18 +25,54 @@
#include "COM_NodeOperation.h"
#include "DNA_image_types.h"
#include "BLI_rect.h"
-#include "COM_ViewerBaseOperation.h"
+#include "BKE_global.h"
-class ViewerOperation : public ViewerBaseOperation {
+class ViewerOperation : public NodeOperation {
private:
+ float *m_outputBuffer;
+ float *m_depthBuffer;
+ Image *m_image;
+ ImageUser *m_imageUser;
+ bool m_active;
+ float m_centerX;
+ float m_centerY;
+ OrderOfChunks m_chunkOrder;
+ bool m_doDepthBuffer;
+ ImBuf *m_ibuf;
+ bool m_ignoreAlpha;
+
+ const ColorManagedViewSettings *m_viewSettings;
+ const ColorManagedDisplaySettings *m_displaySettings;
+
SocketReader *m_imageInput;
SocketReader *m_alphaInput;
SocketReader *m_depthInput;
public:
ViewerOperation();
- void executeRegion(rcti *rect, unsigned int tileNumber);
void initExecution();
void deinitExecution();
+ void executeRegion(rcti *rect, unsigned int tileNumber);
+ bool isOutputOperation(bool rendering) const { if (G.background) return false; return isActiveViewerOutput(); }
+ void setImage(Image *image) { this->m_image = image; }
+ void setImageUser(ImageUser *imageUser) { this->m_imageUser = imageUser; }
+ const bool isActiveViewerOutput() const { return this->m_active; }
+ void setActive(bool active) { this->m_active = active; }
+ void setCenterX(float centerX) { this->m_centerX = centerX;}
+ void setCenterY(float centerY) { this->m_centerY = centerY;}
+ void setChunkOrder(OrderOfChunks tileOrder) { this->m_chunkOrder = tileOrder; }
+ float getCenterX() const { return this->m_centerX; }
+ float getCenterY() const { return this->m_centerY; }
+ OrderOfChunks getChunkOrder() const { return this->m_chunkOrder; }
+ const CompositorPriority getRenderPriority() const;
+ bool isViewerOperation() { return true; }
+ void setIgnoreAlpha(bool value) { this->m_ignoreAlpha = value; }
+
+ void setViewSettings(const ColorManagedViewSettings *viewSettings) { this->m_viewSettings = viewSettings; }
+ void setDisplaySettings(const ColorManagedDisplaySettings *displaySettings) { this->m_displaySettings = displaySettings; }
+
+private:
+ void updateImage(rcti *rect);
+ void initImage();
};
#endif
diff --git a/source/blender/editors/animation/anim_intern.h b/source/blender/editors/animation/anim_intern.h
index 54c7f7ea30f..c571da1ba74 100644
--- a/source/blender/editors/animation/anim_intern.h
+++ b/source/blender/editors/animation/anim_intern.h
@@ -54,14 +54,14 @@ void ANIM_OT_keyframe_insert_menu(struct wmOperatorType *ot);
void ANIM_OT_keyframe_delete_v3d(struct wmOperatorType *ot);
void ANIM_OT_keyframe_clear_v3d(struct wmOperatorType *ot);
-/* Keyframe managment operators for UI buttons (RMB menu). */
+/* Keyframe management operators for UI buttons (RMB menu). */
void ANIM_OT_keyframe_insert_button(struct wmOperatorType *ot);
void ANIM_OT_keyframe_delete_button(struct wmOperatorType *ot);
void ANIM_OT_keyframe_clear_button(struct wmOperatorType *ot);
/* .......... */
-/* KeyingSet managment operators for UI buttons (RMB menu) */
+/* KeyingSet management operators for UI buttons (RMB menu) */
void ANIM_OT_keyingset_button_add(struct wmOperatorType *ot);
void ANIM_OT_keyingset_button_remove(struct wmOperatorType *ot);
diff --git a/source/blender/editors/animation/anim_markers.c b/source/blender/editors/animation/anim_markers.c
index fe41a037fcb..3c8576be312 100644
--- a/source/blender/editors/animation/anim_markers.c
+++ b/source/blender/editors/animation/anim_markers.c
@@ -553,7 +553,7 @@ static int ed_markers_opwrap_invoke(bContext *C, wmOperator *op, const wmEvent *
/* ************************** add markers *************************** */
/* add TimeMarker at curent frame */
-static int ed_marker_add(bContext *C, wmOperator *UNUSED(op))
+static int ed_marker_add_exec(bContext *C, wmOperator *UNUSED(op))
{
ListBase *markers = ED_context_get_markers(C);
TimeMarker *marker;
@@ -593,7 +593,7 @@ static void MARKER_OT_add(wmOperatorType *ot)
ot->idname = "MARKER_OT_add";
/* api callbacks */
- ot->exec = ed_marker_add;
+ ot->exec = ed_marker_add_exec;
ot->invoke = ed_markers_opwrap_invoke;
ot->poll = ED_operator_animview_active;
diff --git a/source/blender/editors/animation/keyframes_draw.c b/source/blender/editors/animation/keyframes_draw.c
index 4e6cc53f962..db51e3c2398 100644
--- a/source/blender/editors/animation/keyframes_draw.c
+++ b/source/blender/editors/animation/keyframes_draw.c
@@ -793,7 +793,7 @@ void draw_action_channel(View2D *v2d, AnimData *adt, bAction *act, float ypos)
{
DLRBT_Tree keys, blocks;
- short locked = (act && act->id.lib != 0);
+ short locked = (act && act->id.lib != NULL);
BLI_dlrbTree_init(&keys);
BLI_dlrbTree_init(&blocks);
@@ -887,7 +887,7 @@ void scene_to_keylist(bDopeSheet *ads, Scene *sce, DLRBT_Tree *keys, DLRBT_Tree
bAnimListElem *ale;
int filter;
- bAnimListElem dummychan = {0};
+ bAnimListElem dummychan = {NULL};
if (sce == NULL)
return;
@@ -920,8 +920,8 @@ void ob_to_keylist(bDopeSheet *ads, Object *ob, DLRBT_Tree *keys, DLRBT_Tree *bl
bAnimListElem *ale;
int filter;
- bAnimListElem dummychan = {0};
- Base dummybase = {0};
+ bAnimListElem dummychan = {NULL};
+ Base dummybase = {NULL};
if (ob == NULL)
return;
diff --git a/source/blender/editors/animation/keyframes_general.c b/source/blender/editors/animation/keyframes_general.c
index 2cb2f6683ef..cfa5f9f032c 100644
--- a/source/blender/editors/animation/keyframes_general.c
+++ b/source/blender/editors/animation/keyframes_general.c
@@ -628,9 +628,8 @@ static tAnimCopybufItem *pastebuf_match_path_property(FCurve *fcu, const short f
PropertyRNA *prop;
RNA_id_pointer_create(aci->id, &id_ptr);
- RNA_path_resolve(&id_ptr, aci->rna_path, &rptr, &prop);
- if (prop) {
+ if (RNA_path_resolve_property(&id_ptr, aci->rna_path, &rptr, &prop)) {
const char *identifier = RNA_property_identifier(prop);
int len_id = strlen(identifier);
int len_path = strlen(fcu->rna_path);
diff --git a/source/blender/editors/armature/armature_edit.c b/source/blender/editors/armature/armature_edit.c
index 12602c10955..90c1a439a19 100644
--- a/source/blender/editors/armature/armature_edit.c
+++ b/source/blender/editors/armature/armature_edit.c
@@ -78,11 +78,10 @@ void ED_armature_apply_transform(Object *ob, float mat[4][4])
/* Do the rotations */
for (ebone = arm->edbo->first; ebone; ebone = ebone->next) {
- float delta[3], tmat[3][3];
+ float tmat[3][3];
/* find the current bone's roll matrix */
- sub_v3_v3v3(delta, ebone->tail, ebone->head);
- vec_roll_to_mat3(delta, ebone->roll, tmat);
+ ED_armature_ebone_to_mat3(ebone, tmat);
/* transform the roll matrix */
mul_m3_m3m3(tmat, mat3, tmat);
@@ -282,15 +281,14 @@ static int armature_calc_roll_exec(bContext *C, wmOperator *op)
mul_m3_v3(imat, vec);
}
else if (type == CALC_ROLL_ACTIVE) {
- float mat[3][3], nor[3];
+ float mat[3][3];
ebone = (EditBone *)arm->act_edbone;
if (ebone == NULL) {
BKE_report(op->reports, RPT_ERROR, "No active bone set");
return OPERATOR_CANCELLED;
}
- sub_v3_v3v3(nor, ebone->tail, ebone->head);
- vec_roll_to_mat3(nor, ebone->roll, mat);
+ ED_armature_ebone_to_mat3(ebone, mat);
copy_v3_v3(vec, mat[2]);
}
else { /* Axis */
diff --git a/source/blender/editors/armature/armature_relations.c b/source/blender/editors/armature/armature_relations.c
index 289901076a1..79d75c9fcda 100644
--- a/source/blender/editors/armature/armature_relations.c
+++ b/source/blender/editors/armature/armature_relations.c
@@ -242,21 +242,18 @@ int join_armature_exec(bContext *C, wmOperator *op)
float difmat[4][4];
float imat[4][4];
float temp[3][3];
- float delta[3];
/* Get the premat */
- sub_v3_v3v3(delta, curbone->tail, curbone->head);
- vec_roll_to_mat3(delta, curbone->roll, temp);
+ ED_armature_ebone_to_mat3(curbone, temp);
- unit_m4(premat); /* Mat4MulMat34 only sets 3x3 part */
+ unit_m4(premat); /* mul_m4_m3m4 only sets 3x3 part */
mul_m4_m3m4(premat, temp, mat);
mul_m4_v3(mat, curbone->head);
mul_m4_v3(mat, curbone->tail);
/* Get the postmat */
- sub_v3_v3v3(delta, curbone->tail, curbone->head);
- vec_roll_to_mat3(delta, curbone->roll, temp);
+ ED_armature_ebone_to_mat3(curbone, temp);
copy_m4_m3(postmat, temp);
/* Find the roll */
diff --git a/source/blender/editors/armature/armature_select.c b/source/blender/editors/armature/armature_select.c
index d05d309b201..fe1d2fa3765 100644
--- a/source/blender/editors/armature/armature_select.c
+++ b/source/blender/editors/armature/armature_select.c
@@ -244,7 +244,7 @@ void ARMATURE_OT_select_linked(wmOperatorType *ot)
ot->description = "Select bones related to selected ones by parent/child relationships";
/* api callbacks */
- ot->exec = NULL;
+ /* leave 'exec' unset */
ot->invoke = armature_select_linked_invoke;
ot->poll = armature_select_linked_poll;
@@ -714,10 +714,10 @@ static void armature_select_less(bArmature *UNUSED(arm), EditBone *ebone)
}
}
-static void armature_select_more_less(Object* ob, bool more)
+static void armature_select_more_less(Object *ob, bool more)
{
- bArmature* arm = (bArmature *)ob->data;
- EditBone* ebone;
+ bArmature *arm = (bArmature *)ob->data;
+ EditBone *ebone;
/* XXX, eventually we shouldn't need this - campbell */
ED_armature_sync_selection(arm->edbo);
diff --git a/source/blender/editors/armature/armature_skinning.c b/source/blender/editors/armature/armature_skinning.c
index 0a9cff3dc90..22bd22c8561 100644
--- a/source/blender/editors/armature/armature_skinning.c
+++ b/source/blender/editors/armature/armature_skinning.c
@@ -362,7 +362,7 @@ static void add_verts_to_dgroups(ReportList *reports, Scene *scene, Object *ob,
DerivedMesh *dm = mesh_get_derived_final(scene, ob, CD_MASK_BAREMESH);
if (dm->foreachMappedVert) {
- dm->foreachMappedVert(dm, add_vgroups__mapFunc, (void *)verts);
+ dm->foreachMappedVert(dm, add_vgroups__mapFunc, (void *)verts, DM_FOREACH_NOP);
vertsfilled = 1;
}
diff --git a/source/blender/editors/armature/armature_utils.c b/source/blender/editors/armature/armature_utils.c
index 0e93a00b01d..4991ef63cf5 100644
--- a/source/blender/editors/armature/armature_utils.c
+++ b/source/blender/editors/armature/armature_utils.c
@@ -156,6 +156,25 @@ bool ED_armature_ebone_is_child_recursive(EditBone *ebone_parent, EditBone *ebon
return false;
}
+void ED_armature_ebone_to_mat3(EditBone *ebone, float mat[3][3])
+{
+ float delta[3];
+
+ /* Find the current bone matrix */
+ sub_v3_v3v3(delta, ebone->tail, ebone->head);
+ vec_roll_to_mat3(delta, ebone->roll, mat);
+}
+
+void ED_armature_ebone_to_mat4(EditBone *ebone, float mat[4][4])
+{
+ float m3[3][3];
+
+ ED_armature_ebone_to_mat3(ebone, m3);
+
+ copy_m4_m3(mat, m3);
+ copy_v3_v3(mat[3], ebone->head);
+}
+
/* *************************************************************** */
/* Mirroring */
@@ -389,7 +408,6 @@ static void fix_bonelist_roll(ListBase *bonelist, ListBase *editbonelist)
float postmat[3][3];
float difmat[3][3];
float imat[3][3];
- float delta[3];
for (curBone = bonelist->first; curBone; curBone = curBone->next) {
/* sets local matrix and arm_mat (restpos) */
@@ -402,8 +420,7 @@ static void fix_bonelist_roll(ListBase *bonelist, ListBase *editbonelist)
if (ebone) {
/* Get the ebone premat */
- sub_v3_v3v3(delta, ebone->tail, ebone->head);
- vec_roll_to_mat3(delta, ebone->roll, premat);
+ ED_armature_ebone_to_mat3(ebone, premat);
/* Get the bone postmat */
copy_m3_m4(postmat, curBone->arm_mat);
@@ -503,11 +520,9 @@ void ED_armature_from_edit(Object *obedit)
{
float M_parentRest[3][3];
float iM_parentRest[3][3];
- float delta[3];
/* Get the parent's matrix (rotation only) */
- sub_v3_v3v3(delta, eBone->parent->tail, eBone->parent->head);
- vec_roll_to_mat3(delta, eBone->parent->roll, M_parentRest);
+ ED_armature_ebone_to_mat3(eBone->parent, M_parentRest);
/* Invert the parent matrix */
invert_m3_m3(iM_parentRest, M_parentRest);
diff --git a/source/blender/editors/armature/pose_edit.c b/source/blender/editors/armature/pose_edit.c
index 40b96132699..e84008c3d15 100644
--- a/source/blender/editors/armature/pose_edit.c
+++ b/source/blender/editors/armature/pose_edit.c
@@ -487,6 +487,9 @@ static void pose_copy_menu(Scene *scene)
break;
case 8: /* Custom Bone Shape */
pchan->custom = pchanact->custom;
+ if (pchan->custom) {
+ id_us_plus(&pchan->custom->id);
+ }
break;
case 9: /* Visual Location */
BKE_armature_loc_pose_to_bone(pchan, pchanact->pose_mat[3], pchan->loc);
diff --git a/source/blender/editors/armature/pose_select.c b/source/blender/editors/armature/pose_select.c
index c599e978e58..9449b5a49bf 100644
--- a/source/blender/editors/armature/pose_select.c
+++ b/source/blender/editors/armature/pose_select.c
@@ -271,7 +271,7 @@ void POSE_OT_select_linked(wmOperatorType *ot)
ot->description = "Select bones related to selected ones by parent/child relationships";
/* api callbacks */
- ot->exec = NULL;
+ /* leave 'exec' unset */
ot->invoke = pose_select_connected_invoke;
ot->poll = pose_select_linked_poll;
diff --git a/source/blender/editors/armature/pose_transform.c b/source/blender/editors/armature/pose_transform.c
index c530faedd68..79ca70a6189 100644
--- a/source/blender/editors/armature/pose_transform.c
+++ b/source/blender/editors/armature/pose_transform.c
@@ -815,7 +815,7 @@ static int pose_clear_user_transforms_exec(bContext *C, wmOperator *op)
* just pose values should change, so this should be fine
*/
bPose *dummyPose = NULL;
- Object workob = {{0}};
+ Object workob = {{NULL}};
bPoseChannel *pchan;
/* execute animation step for current frame using a dummy copy of the pose */
diff --git a/source/blender/editors/armature/pose_utils.c b/source/blender/editors/armature/pose_utils.c
index a5e51ccf32a..014a64170db 100644
--- a/source/blender/editors/armature/pose_utils.c
+++ b/source/blender/editors/armature/pose_utils.c
@@ -239,7 +239,7 @@ void poseAnim_mapping_autoKeyframe(bContext *C, Scene *scene, Object *ob, ListBa
* - only do this if keyframes should have been added
* - do not calculate unless there are paths already to update...
*/
- if (C && (ob->pose->avs.path_bakeflag & MOTIONPATH_BAKE_HAS_PATHS)) {
+ if (ob->pose->avs.path_bakeflag & MOTIONPATH_BAKE_HAS_PATHS) {
//ED_pose_clear_paths(C, ob); // XXX for now, don't need to clear
ED_pose_recalculate_paths(scene, ob);
}
diff --git a/source/blender/editors/curve/curve_intern.h b/source/blender/editors/curve/curve_intern.h
index 0521297d049..d197697e60b 100644
--- a/source/blender/editors/curve/curve_intern.h
+++ b/source/blender/editors/curve/curve_intern.h
@@ -88,7 +88,9 @@ void CURVE_OT_shade_flat(struct wmOperatorType *ot);
void CURVE_OT_tilt_clear(struct wmOperatorType *ot);
void CURVE_OT_smooth(struct wmOperatorType *ot);
+void CURVE_OT_smooth_weight(struct wmOperatorType *ot);
void CURVE_OT_smooth_radius(struct wmOperatorType *ot);
+void CURVE_OT_smooth_tilt(struct wmOperatorType *ot);
void CURVE_OT_primitive_bezier_curve_add(struct wmOperatorType *ot);
void CURVE_OT_primitive_bezier_circle_add(struct wmOperatorType *ot);
diff --git a/source/blender/editors/curve/curve_ops.c b/source/blender/editors/curve/curve_ops.c
index 5b525a089b3..2452a5d1a4b 100644
--- a/source/blender/editors/curve/curve_ops.c
+++ b/source/blender/editors/curve/curve_ops.c
@@ -112,7 +112,9 @@ void ED_operatortypes_curve(void)
WM_operatortype_append(SURFACE_OT_primitive_nurbs_surface_torus_add);
WM_operatortype_append(CURVE_OT_smooth);
+ WM_operatortype_append(CURVE_OT_smooth_weight);
WM_operatortype_append(CURVE_OT_smooth_radius);
+ WM_operatortype_append(CURVE_OT_smooth_tilt);
WM_operatortype_append(CURVE_OT_de_select_first);
WM_operatortype_append(CURVE_OT_de_select_last);
diff --git a/source/blender/editors/curve/editcurve.c b/source/blender/editors/curve/editcurve.c
index 75de4e13707..660f8098a38 100644
--- a/source/blender/editors/curve/editcurve.c
+++ b/source/blender/editors/curve/editcurve.c
@@ -2260,29 +2260,33 @@ void CURVE_OT_smooth(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
-/**************** smooth curve radius operator *************/
+/* -------------------------------------------------------------------- */
+/* Smooth radius/weight/tilt
+ *
+ * TODO: make smoothing distance based
+ * TODO: support cyclic curves
+ */
-/* TODO, make smoothing distance based */
-static int smooth_radius_exec(bContext *C, wmOperator *UNUSED(op))
+static void curve_smooth_value(ListBase *editnurb,
+ const int bezt_offsetof, const int bp_offset)
{
- Object *obedit = CTX_data_edit_object(C);
- ListBase *editnurb = object_editcurve_get(obedit);
Nurb *nu;
BezTriple *bezt;
BPoint *bp;
int a;
-
+
/* use for smoothing */
int last_sel;
int start_sel, end_sel; /* selection indices, inclusive */
float start_rad, end_rad, fac, range;
-
+
for (nu = editnurb->first; nu; nu = nu->next) {
if (nu->bezt) {
-
+#define BEZT_VALUE(bezt) (*((float *)((char *)bezt + bezt_offsetof)))
+
for (last_sel = 0; last_sel < nu->pntsu; last_sel++) {
/* loop over selection segments of a curve, smooth each */
-
+
/* Start BezTriple code, this is duplicated below for points, make sure these functions stay in sync */
start_sel = -1;
for (bezt = &nu->bezt[last_sel], a = last_sel; a < nu->pntsu; a++, bezt++) {
@@ -2299,57 +2303,60 @@ static int smooth_radius_exec(bContext *C, wmOperator *UNUSED(op))
}
end_sel = a;
}
-
+
if (start_sel == -1) {
last_sel = nu->pntsu; /* next... */
}
else {
last_sel = end_sel; /* before we modify it */
-
+
/* now blend between start and end sel */
- start_rad = end_rad = -1.0;
-
+ start_rad = end_rad = FLT_MAX;
+
if (start_sel == end_sel) {
/* simple, only 1 point selected */
- if (start_sel > 0) start_rad = nu->bezt[start_sel - 1].radius;
- if (end_sel != -1 && end_sel < nu->pntsu) end_rad = nu->bezt[start_sel + 1].radius;
-
- if (start_rad >= 0.0f && end_rad >= 0.0f) nu->bezt[start_sel].radius = (start_rad + end_rad) / 2.0f;
- else if (start_rad >= 0.0f) nu->bezt[start_sel].radius = start_rad;
- else if (end_rad >= 0.0f) nu->bezt[start_sel].radius = end_rad;
+ if (start_sel > 0) start_rad = BEZT_VALUE(&nu->bezt[start_sel - 1]);
+ if (end_sel != -1 && end_sel < nu->pntsu) end_rad = BEZT_VALUE(&nu->bezt[start_sel + 1]);
+
+ if (start_rad != FLT_MAX && end_rad >= FLT_MAX) BEZT_VALUE(&nu->bezt[start_sel]) = (start_rad + end_rad) / 2.0f;
+ else if (start_rad != FLT_MAX) BEZT_VALUE(&nu->bezt[start_sel]) = start_rad;
+ else if (end_rad != FLT_MAX) BEZT_VALUE(&nu->bezt[start_sel]) = end_rad;
}
else {
/* if endpoints selected, then use them */
if (start_sel == 0) {
- start_rad = nu->bezt[start_sel].radius;
+ start_rad = BEZT_VALUE(&nu->bezt[start_sel]);
start_sel++; /* we don't want to edit the selected endpoint */
}
else {
- start_rad = nu->bezt[start_sel - 1].radius;
+ start_rad = BEZT_VALUE(&nu->bezt[start_sel - 1]);
}
if (end_sel == nu->pntsu - 1) {
- end_rad = nu->bezt[end_sel].radius;
+ end_rad = BEZT_VALUE(&nu->bezt[end_sel]);
end_sel--; /* we don't want to edit the selected endpoint */
}
else {
- end_rad = nu->bezt[end_sel + 1].radius;
+ end_rad = BEZT_VALUE(&nu->bezt[end_sel + 1]);
}
-
+
/* Now Blend between the points */
range = (float)(end_sel - start_sel) + 2.0f;
for (bezt = &nu->bezt[start_sel], a = start_sel; a <= end_sel; a++, bezt++) {
fac = (float)(1 + a - start_sel) / range;
- bezt->radius = start_rad * (1.0f - fac) + end_rad * fac;
+ BEZT_VALUE(bezt) = start_rad * (1.0f - fac) + end_rad * fac;
}
}
}
}
+#undef BEZT_VALUE
}
else if (nu->bp) {
+#define BP_VALUE(bp) (*((float *)((char *)bp + bp_offset)))
+
/* Same as above, keep these the same! */
for (last_sel = 0; last_sel < nu->pntsu; last_sel++) {
/* loop over selection segments of a curve, smooth each */
-
+
/* Start BezTriple code, this is duplicated below for points, make sure these functions stay in sync */
start_sel = -1;
for (bp = &nu->bp[last_sel], a = last_sel; a < nu->pntsu; a++, bp++) {
@@ -2366,53 +2373,90 @@ static int smooth_radius_exec(bContext *C, wmOperator *UNUSED(op))
}
end_sel = a;
}
-
+
if (start_sel == -1) {
last_sel = nu->pntsu; /* next... */
}
else {
last_sel = end_sel; /* before we modify it */
-
+
/* now blend between start and end sel */
- start_rad = end_rad = -1.0;
-
+ start_rad = end_rad = FLT_MAX;
+
if (start_sel == end_sel) {
/* simple, only 1 point selected */
- if (start_sel > 0) start_rad = nu->bp[start_sel - 1].radius;
- if (end_sel != -1 && end_sel < nu->pntsu) end_rad = nu->bp[start_sel + 1].radius;
-
- if (start_rad >= 0.0f && end_rad >= 0.0f) nu->bp[start_sel].radius = (start_rad + end_rad) / 2;
- else if (start_rad >= 0.0f) nu->bp[start_sel].radius = start_rad;
- else if (end_rad >= 0.0f) nu->bp[start_sel].radius = end_rad;
+ if (start_sel > 0) start_rad = BP_VALUE(&nu->bp[start_sel - 1]);
+ if (end_sel != -1 && end_sel < nu->pntsu) end_rad = BP_VALUE(&nu->bp[start_sel + 1]);
+
+ if (start_rad != FLT_MAX && end_rad != FLT_MAX) BP_VALUE(&nu->bp[start_sel]) = (start_rad + end_rad) / 2;
+ else if (start_rad != FLT_MAX) BP_VALUE(&nu->bp[start_sel]) = start_rad;
+ else if (end_rad != FLT_MAX) BP_VALUE(&nu->bp[start_sel]) = end_rad;
}
else {
/* if endpoints selected, then use them */
if (start_sel == 0) {
- start_rad = nu->bp[start_sel].radius;
+ start_rad = BP_VALUE(&nu->bp[start_sel]);
start_sel++; /* we don't want to edit the selected endpoint */
}
else {
- start_rad = nu->bp[start_sel - 1].radius;
+ start_rad = BP_VALUE(&nu->bp[start_sel - 1]);
}
if (end_sel == nu->pntsu - 1) {
- end_rad = nu->bp[end_sel].radius;
+ end_rad = BP_VALUE(&nu->bp[end_sel]);
end_sel--; /* we don't want to edit the selected endpoint */
}
else {
- end_rad = nu->bp[end_sel + 1].radius;
+ end_rad = BP_VALUE(&nu->bp[end_sel + 1]);
}
-
+
/* Now Blend between the points */
range = (float)(end_sel - start_sel) + 2.0f;
for (bp = &nu->bp[start_sel], a = start_sel; a <= end_sel; a++, bp++) {
fac = (float)(1 + a - start_sel) / range;
- bp->radius = start_rad * (1.0f - fac) + end_rad * fac;
+ BP_VALUE(bp) = start_rad * (1.0f - fac) + end_rad * fac;
}
}
}
}
+#undef BP_VALUE
}
}
+}
+
+static int curve_smooth_weight_exec(bContext *C, wmOperator *UNUSED(op))
+{
+ Object *obedit = CTX_data_edit_object(C);
+ ListBase *editnurb = object_editcurve_get(obedit);
+
+ curve_smooth_value(editnurb, offsetof(BezTriple, weight), offsetof(BPoint, weight));
+
+ WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data);
+ DAG_id_tag_update(obedit->data, 0);
+
+ return OPERATOR_FINISHED;
+}
+
+void CURVE_OT_smooth_weight(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Smooth Curve Weight";
+ ot->description = "Interpolate weight of selected points";
+ ot->idname = "CURVE_OT_smooth_weight";
+
+ /* api clastbacks */
+ ot->exec = curve_smooth_weight_exec;
+ ot->poll = ED_operator_editsurfcurve;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+}
+
+static int curve_smooth_radius_exec(bContext *C, wmOperator *UNUSED(op))
+{
+ Object *obedit = CTX_data_edit_object(C);
+ ListBase *editnurb = object_editcurve_get(obedit);
+
+ curve_smooth_value(editnurb, offsetof(BezTriple, radius), offsetof(BPoint, radius));
WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data);
DAG_id_tag_update(obedit->data, 0);
@@ -2424,17 +2468,45 @@ void CURVE_OT_smooth_radius(wmOperatorType *ot)
{
/* identifiers */
ot->name = "Smooth Curve Radius";
- ot->description = "Flatten radii of selected points";
+ ot->description = "Interpolate radii of selected points";
ot->idname = "CURVE_OT_smooth_radius";
/* api clastbacks */
- ot->exec = smooth_radius_exec;
+ ot->exec = curve_smooth_radius_exec;
ot->poll = ED_operator_editsurfcurve;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
+static int curve_smooth_tilt_exec(bContext *C, wmOperator *UNUSED(op))
+{
+ Object *obedit = CTX_data_edit_object(C);
+ ListBase *editnurb = object_editcurve_get(obedit);
+
+ curve_smooth_value(editnurb, offsetof(BezTriple, alfa), offsetof(BPoint, alfa));
+
+ WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data);
+ DAG_id_tag_update(obedit->data, 0);
+
+ return OPERATOR_FINISHED;
+}
+
+void CURVE_OT_smooth_tilt(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Smooth Curve Tilt";
+ ot->description = "Interpolate tilt of selected points";
+ ot->idname = "CURVE_OT_smooth_tilt";
+
+ /* api clastbacks */
+ ot->exec = curve_smooth_tilt_exec;
+ ot->poll = ED_operator_editsurfcurve;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+}
+
/***************** selection utility *************************/
/* next == 1 -> select next */
@@ -2833,44 +2905,6 @@ void CURVE_OT_reveal(wmOperatorType *ot)
/********************** subdivide operator *********************/
-static BezTriple *next_spline_bezier_point_get(Nurb *nu, BezTriple *bezt)
-{
- BezTriple *nextbezt;
-
- if (bezt == nu->bezt + nu->pntsu - 1) {
- if (nu->flagu & CU_NURB_CYCLIC) {
- nextbezt = nu->bezt;
- }
- else {
- nextbezt = NULL;
- }
- }
- else {
- nextbezt = bezt + 1;
- }
-
- return nextbezt;
-}
-
-static BPoint *next_spline_bpoint_get(Nurb *nu, BPoint *bp)
-{
- BPoint *nextbp;
-
- if (bp == nu->bp + nu->pntsu - 1) {
- if (nu->flagu & CU_NURB_CYCLIC) {
- nextbp = nu->bp;
- }
- else {
- nextbp = NULL;
- }
- }
- else {
- nextbp = bp + 1;
- }
-
- return nextbp;
-}
-
/** Divide the line segments associated with the currently selected
* curve nodes (Bezier or NURB). If there are no valid segment
* selections within the current selection, nothing happens.
@@ -2902,7 +2936,7 @@ static void subdividenurb(Object *obedit, int number_cuts)
a = nu->pntsu;
bezt = nu->bezt;
while (a--) {
- nextbezt = next_spline_bezier_point_get(nu, bezt);
+ nextbezt = BKE_nurb_bezt_get_next(nu, bezt);
if (nextbezt == NULL) {
break;
}
@@ -2924,7 +2958,7 @@ static void subdividenurb(Object *obedit, int number_cuts)
keyIndex_updateBezt(editnurb, bezt, beztn, 1);
beztn++;
- nextbezt = next_spline_bezier_point_get(nu, bezt);
+ nextbezt = BKE_nurb_bezt_get_next(nu, bezt);
if (nextbezt == NULL) {
break;
}
@@ -2988,7 +3022,7 @@ static void subdividenurb(Object *obedit, int number_cuts)
a = nu->pntsu;
bp = nu->bp;
while (a--) {
- nextbp = next_spline_bpoint_get(nu, bp);
+ nextbp = BKE_nurb_bpoint_get_next(nu, bp);
if (nextbp == NULL) {
break;
}
@@ -3013,7 +3047,7 @@ static void subdividenurb(Object *obedit, int number_cuts)
keyIndex_updateBP(editnurb, bp, bpn, 1);
bpn++;
- nextbp = next_spline_bpoint_get(nu, bp);
+ nextbp = BKE_nurb_bpoint_get_next(nu, bp);
if (nextbp == NULL) {
break;
}
@@ -5174,7 +5208,7 @@ static int select_more_exec(bContext *C, wmOperator *UNUSED(op))
/* may not be optimal always (example: end of NURBS sphere) */
if (obedit->type == OB_SURF) {
for (nu = editnurb->first; nu; nu = nu->next) {
- BLI_bitmap selbpoints;
+ BLI_bitmap *selbpoints;
a = nu->pntsu * nu->pntsv;
bp = nu->bp;
selbpoints = BLI_BITMAP_NEW(a, "selectlist");
@@ -5260,7 +5294,7 @@ static int select_less_exec(bContext *C, wmOperator *UNUSED(op))
if (obedit->type == OB_SURF) {
for (nu = editnurb->first; nu; nu = nu->next) {
- BLI_bitmap selbpoints;
+ BLI_bitmap *selbpoints;
a = nu->pntsu * nu->pntsv;
bp = nu->bp;
selbpoints = BLI_BITMAP_NEW(a, "selectlist");
diff --git a/source/blender/editors/curve/editfont.c b/source/blender/editors/curve/editfont.c
index db4e4dc8500..b9759e16f20 100644
--- a/source/blender/editors/curve/editfont.c
+++ b/source/blender/editors/curve/editfont.c
@@ -446,7 +446,9 @@ static void txt_add_object(bContext *C, TextLine *firstline, int totline, float
Object *obedit;
Base *base;
struct TextLine *tmp;
- int nchars = 0, a;
+ int nchars = 0, nbytes = 0;
+ char *s;
+ int a;
float rot[3] = {0.f, 0.f, 0.f};
obedit = BKE_object_add(bmain, scene, OB_FONT);
@@ -463,26 +465,38 @@ static void txt_add_object(bContext *C, TextLine *firstline, int totline, float
cu->vfont = BKE_vfont_builtin_get();
cu->vfont->id.us++;
- for (tmp = firstline, a = 0; cu->len < MAXTEXT && a < totline; tmp = tmp->next, a++)
- nchars += strlen(tmp->line) + 1;
+ for (tmp = firstline, a = 0; nbytes < MAXTEXT && a < totline; tmp = tmp->next, a++) {
+ size_t nchars_line, nbytes_line;
+ nchars_line = BLI_strlen_utf8_ex(tmp->line, &nbytes_line);
+ nchars += nchars_line + 1;
+ nbytes += nbytes_line + 1;
+ }
if (cu->str) MEM_freeN(cu->str);
if (cu->strinfo) MEM_freeN(cu->strinfo);
- cu->str = MEM_callocN(nchars + 4, "str");
+ cu->str = MEM_mallocN(nbytes + 4, "str");
cu->strinfo = MEM_callocN((nchars + 4) * sizeof(CharInfo), "strinfo");
- cu->str[0] = '\0';
cu->len = 0;
cu->pos = 0;
-
+
+ s = cu->str;
+ *s = '\0';
+
for (tmp = firstline, a = 0; cu->len < MAXTEXT && a < totline; tmp = tmp->next, a++) {
- strcat(cu->str, tmp->line);
- cu->len += strlen(tmp->line);
+ size_t nbytes_line;
+
+ nbytes_line = BLI_strcpy_rlen(s, tmp->line);
+
+ s += nbytes_line;
+ cu->len += nbytes_line;
if (tmp->next) {
- strcat(cu->str, "\n");
- cu->len++;
+ nbytes_line = BLI_strcpy_rlen(s, "\n");
+
+ s += nbytes_line;
+ cu->len += nbytes_line;
}
cu->pos = cu->len;
diff --git a/source/blender/editors/include/BIF_glutil.h b/source/blender/editors/include/BIF_glutil.h
index dfb02fa9c1b..352a74cf172 100644
--- a/source/blender/editors/include/BIF_glutil.h
+++ b/source/blender/editors/include/BIF_glutil.h
@@ -55,7 +55,6 @@ void fdrawXORcirc(float xofs, float yofs, float rad);
void fdrawcheckerboard(float x1, float y1, float x2, float y2);
/* OpenGL stipple defines */
-/* OpenGL stipple defines */
extern const unsigned char stipple_halftone[128];
extern const unsigned char stipple_quarttone[128];
extern const unsigned char stipple_diag_stripes_pos[128];
diff --git a/source/blender/editors/include/ED_armature.h b/source/blender/editors/include/ED_armature.h
index 9b9a4c154db..fab179da7bc 100644
--- a/source/blender/editors/include/ED_armature.h
+++ b/source/blender/editors/include/ED_armature.h
@@ -135,8 +135,12 @@ void ED_armature_validate_active(struct bArmature *arm);
void add_primitive_bone(struct Object *obedit_arm, bool view_aligned);
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 ED_armature_ebone_to_mat3(EditBone *ebone, float mat[3][3]);
+void ED_armature_ebone_to_mat4(EditBone *ebone, float mat[4][4]);
+
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_transform.h b/source/blender/editors/include/ED_transform.h
index 423613fb780..81308dd84f2 100644
--- a/source/blender/editors/include/ED_transform.h
+++ b/source/blender/editors/include/ED_transform.h
@@ -90,16 +90,14 @@ enum TfmMode {
/* TRANSFORM CONTEXTS */
#define CTX_NONE 0
-#define CTX_TEXTURE 1
-#define CTX_EDGE 2
-#define CTX_NO_PET 4
-#define CTX_TWEAK 8
-#define CTX_NO_MIRROR 16
-#define CTX_AUTOCONFIRM 32
-#define CTX_BMESH 64
-#define CTX_NDOF 128
-#define CTX_MOVIECLIP 256
-#define CTX_MASK 512
+#define CTX_TEXTURE (1 << 0)
+#define CTX_EDGE (1 << 1)
+#define CTX_NO_PET (1 << 2)
+#define CTX_NO_MIRROR (1 << 3)
+#define CTX_AUTOCONFIRM (1 << 4)
+#define CTX_NDOF (1 << 5)
+#define CTX_MOVIECLIP (1 << 6)
+#define CTX_MASK (1 << 7)
/* Standalone call to get the transformation center corresponding to the current situation
* returns 1 if successful, 0 otherwise (usually means there's no selection)
diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h
index e5cc0dd8ea7..9a9cab9b46c 100644
--- a/source/blender/editors/include/UI_interface.h
+++ b/source/blender/editors/include/UI_interface.h
@@ -327,7 +327,11 @@ typedef void (*uiMenuHandleFunc)(struct bContext *C, void *arg, int event);
typedef struct uiPopupMenu uiPopupMenu;
-struct uiPopupMenu *uiPupMenuBegin(struct bContext *C, const char *title, int icon);
+struct uiPopupMenu *uiPupMenuBegin(struct bContext *C, const char *title, int icon)
+#ifdef __GNUC__
+__attribute__((nonnull))
+#endif
+;
void uiPupMenuEnd(struct bContext *C, struct uiPopupMenu *head);
struct uiLayout *uiPupMenuLayout(uiPopupMenu *head);
@@ -546,7 +550,11 @@ typedef struct uiStringInfo {
/* Note: Expects pointers to uiStringInfo structs as parameters.
* Will fill them with translated strings, when possible.
* Strings in uiStringInfo must be MEM_freeN'ed by caller. */
-void uiButGetStrInfo(struct bContext *C, uiBut *but, ...);
+void uiButGetStrInfo(struct bContext *C, uiBut *but, ...)
+#ifdef __GNUC__
+__attribute__((sentinel))
+#endif
+;
/* Edit i18n stuff. */
/* Name of the main py op from i18n addon. */
diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c
index 042ca942722..21a63183c1a 100644
--- a/source/blender/editors/interface/interface.c
+++ b/source/blender/editors/interface/interface.c
@@ -559,19 +559,19 @@ static void ui_draw_links(uiBlock *block)
/* ************** BLOCK ENDING FUNCTION ************* */
/* NOTE: if but->poin is allocated memory for every defbut, things fail... */
-static bool ui_but_equals_old(uiBut *but, uiBut *oldbut)
+static bool ui_but_equals_old(const uiBut *but, const uiBut *oldbut)
{
/* various properties are being compared here, hopefully sufficient
* to catch all cases, but it is simple to add more checks later */
if (but->retval != oldbut->retval) return false;
if (but->rnapoin.data != oldbut->rnapoin.data) return false;
- if (but->rnaprop != oldbut->rnaprop)
- if (but->rnaindex != oldbut->rnaindex) return false;
+ if (but->rnaprop != oldbut->rnaprop && but->rnaindex != oldbut->rnaindex) return false;
if (but->func != oldbut->func) return false;
if (but->funcN != oldbut->funcN) return false;
if (oldbut->func_arg1 != oldbut && but->func_arg1 != oldbut->func_arg1) return false;
if (oldbut->func_arg2 != oldbut && but->func_arg2 != oldbut->func_arg2) return false;
- if (!but->funcN && ((but->poin != oldbut->poin && (uiBut *)oldbut->poin != oldbut) || but->pointype != oldbut->pointype)) return false;
+ if (!but->funcN && ((but->poin != oldbut->poin && (uiBut *)oldbut->poin != oldbut) ||
+ (but->pointype != oldbut->pointype))) return false;
if (but->optype != oldbut->optype) return false;
return true;
@@ -620,7 +620,7 @@ static int ui_but_update_from_old_block(const bContext *C, uiBlock *block, uiBut
return found;
for (oldbut = oldblock->buttons.first; oldbut; oldbut = oldbut->next) {
- if (ui_but_equals_old(oldbut, but)) {
+ if (ui_but_equals_old(but, oldbut)) {
if (oldbut->active) {
#if 0
// but->flag = oldbut->flag;
@@ -2426,35 +2426,37 @@ void ui_check_but(uiBut *but)
case NUM:
case NUMSLI:
- UI_GET_BUT_VALUE_INIT(but, value);
+ if (!but->editstr) {
+ UI_GET_BUT_VALUE_INIT(but, value);
- if (ui_is_but_float(but)) {
- if (value == (double) FLT_MAX) {
- BLI_snprintf(but->drawstr, sizeof(but->drawstr), "%sinf", but->str);
- }
- else if (value == (double) -FLT_MAX) {
- BLI_snprintf(but->drawstr, sizeof(but->drawstr), "%s-inf", but->str);
- }
- /* 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, -1);
- BLI_snprintf(but->drawstr, sizeof(but->drawstr), "%s%s", but->str, new_str);
+ if (ui_is_but_float(but)) {
+ if (value == (double) FLT_MAX) {
+ BLI_snprintf(but->drawstr, sizeof(but->drawstr), "%sinf", but->str);
+ }
+ else if (value == (double) -FLT_MAX) {
+ BLI_snprintf(but->drawstr, sizeof(but->drawstr), "%s-inf", but->str);
+ }
+ /* 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, -1);
+ BLI_snprintf(but->drawstr, sizeof(but->drawstr), "%s%s", but->str, new_str);
+ }
+ else {
+ const int prec = ui_but_float_precision(but, value);
+ BLI_snprintf(but->drawstr, sizeof(but->drawstr), "%s%.*f", but->str, prec, value);
+ }
}
else {
- const int prec = ui_but_float_precision(but, value);
- BLI_snprintf(but->drawstr, sizeof(but->drawstr), "%s%.*f", but->str, prec, value);
+ BLI_snprintf(but->drawstr, sizeof(but->drawstr), "%s%d", but->str, (int)value);
+ }
+
+ if (but->rnaprop) {
+ PropertySubType pstype = RNA_property_subtype(but->rnaprop);
+
+ if (pstype == PROP_PERCENTAGE)
+ strcat(but->drawstr, "%");
}
- }
- else {
- BLI_snprintf(but->drawstr, sizeof(but->drawstr), "%s%d", but->str, (int)value);
- }
-
- if (but->rnaprop) {
- PropertySubType pstype = RNA_property_subtype(but->rnaprop);
-
- if (pstype == PROP_PERCENTAGE)
- strcat(but->drawstr, "%");
}
break;
@@ -2477,29 +2479,30 @@ void ui_check_but(uiBut *but)
if (!but->editstr) {
char str[UI_MAX_DRAW_STR];
- ui_get_but_string(but, str, UI_MAX_DRAW_STR - strlen(but->str));
-
+ ui_get_but_string(but, str, UI_MAX_DRAW_STR);
BLI_snprintf(but->drawstr, sizeof(but->drawstr), "%s%s", but->str, str);
}
break;
case KEYEVT:
- BLI_strncpy(but->drawstr, but->str, UI_MAX_DRAW_STR);
+ {
+ const char *str;
if (but->flag & UI_SELECT) {
- strcat(but->drawstr, "Press a key");
+ str = "Press a key";
}
else {
UI_GET_BUT_VALUE_INIT(but, value);
- strcat(but->drawstr, WM_key_event_string((short)value));
+ str = WM_key_event_string((short)value);
}
+ BLI_snprintf(but->drawstr, UI_MAX_DRAW_STR, "%s%s", but->str, str);
break;
-
+ }
case HOTKEYEVT:
if (but->flag & UI_SELECT) {
- but->drawstr[0] = '\0';
if (but->modifier_key) {
char *str = but->drawstr;
+ but->drawstr[0] = '\0';
if (but->modifier_key & KM_SHIFT)
str += BLI_strcpy_rlen(str, "Shift ");
@@ -2512,8 +2515,9 @@ void ui_check_but(uiBut *but)
(void)str; /* UNUSED */
}
- else
- strcat(but->drawstr, "Press a key ");
+ else {
+ BLI_strncpy(but->drawstr, "Press a key", UI_MAX_DRAW_STR);
+ }
}
else
BLI_strncpy(but->drawstr, but->str, UI_MAX_DRAW_STR);
@@ -3960,7 +3964,8 @@ void uiButSetFocusOnEnter(wmWindow *win, uiBut *but)
{
wmEvent event;
- event = *(win->eventstate);
+ wm_event_init_from_window(win, &event);
+
event.type = EVT_BUT_OPEN;
event.val = KM_PRESS;
event.customdata = but;
diff --git a/source/blender/editors/interface/interface_draw.c b/source/blender/editors/interface/interface_draw.c
index cbd1f6ccaaa..cd845da10c6 100644
--- a/source/blender/editors/interface/interface_draw.c
+++ b/source/blender/editors/interface/interface_draw.c
@@ -561,7 +561,7 @@ void ui_draw_but_HISTOGRAM(ARegion *ar, uiBut *but, uiWidgetColors *UNUSED(wcol)
glColor4f(1.f, 1.f, 1.f, 0.08f);
/* draw grid lines here */
- for (i = 1; i < (HISTOGRAM_TOT_GRID_LINES + 1); i++) {
+ for (i = 1; i <= HISTOGRAM_TOT_GRID_LINES; i++) {
const float fac = (float)i / (float)HISTOGRAM_TOT_GRID_LINES;
/* so we can tell the 1.0 color point */
diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c
index ee316e13dad..f9ee2b67e6b 100644
--- a/source/blender/editors/interface/interface_handlers.c
+++ b/source/blender/editors/interface/interface_handlers.c
@@ -228,10 +228,10 @@ typedef struct uiAfterFunc {
bContextStore *context;
char undostr[BKE_UNDO_STR_MAX];
-
- int autokey;
} uiAfterFunc;
+
+
static bool ui_but_contains_pt(uiBut *but, int mx, int my);
static bool ui_mouse_inside_button(ARegion *ar, uiBut *but, int x, int y);
static void button_activate_state(bContext *C, uiBut *but, uiHandleButtonState state);
@@ -2605,7 +2605,7 @@ static int ui_do_but_KEYEVT(bContext *C, uiBut *but, uiHandleButtonData *data, c
static int ui_do_but_TEX(bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data, const wmEvent *event)
{
if (data->state == BUTTON_STATE_HIGHLIGHT) {
- if (ELEM(event->type, LEFTMOUSE, EVT_BUT_OPEN) && event->val == KM_PRESS) {
+ if (ELEM4(event->type, LEFTMOUSE, EVT_BUT_OPEN, PADENTER, RETKEY) && event->val == KM_PRESS) {
if (but->dt == UI_EMBOSSN && !event->ctrl) {
/* pass */
}
@@ -2630,7 +2630,7 @@ static int ui_do_but_TEX(bContext *C, uiBlock *block, uiBut *but, uiHandleButton
static int ui_do_but_SEARCH_UNLINK(bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data, const wmEvent *event)
{
/* unlink icon is on right */
- if (ELEM(event->type, LEFTMOUSE, EVT_BUT_OPEN) && event->val == KM_PRESS) {
+ if (ELEM4(event->type, LEFTMOUSE, EVT_BUT_OPEN, PADENTER, RETKEY) && event->val == KM_PRESS) {
ARegion *ar = data->region;
rcti rect;
int x = event->x, y = event->y;
@@ -4944,7 +4944,6 @@ static bool ui_but_menu(bContext *C, uiBut *but)
uiPopupMenu *pup;
uiLayout *layout;
bool is_array, is_array_component;
- const char *name;
uiStringInfo label = {BUT_GET_LABEL, NULL};
/* if ((but->rnapoin.data && but->rnaprop) == 0 && but->optype == NULL)*/
@@ -4957,12 +4956,11 @@ static bool ui_but_menu(bContext *C, uiBut *but)
button_timers_tooltip_remove(C, but);
+ /* highly unlikely getting the label ever fails */
uiButGetStrInfo(C, but, &label, NULL);
- name = label.strinfo;
- pup = uiPupMenuBegin(C, name, ICON_NONE);
+ pup = uiPupMenuBegin(C, label.strinfo ? label.strinfo : "", ICON_NONE);
layout = uiPupMenuLayout(pup);
-
if (label.strinfo)
MEM_freeN(label.strinfo);
@@ -6195,7 +6193,7 @@ void ui_button_activate_do(bContext *C, ARegion *ar, uiBut *but)
button_activate_init(C, ar, but, BUTTON_ACTIVATE_OVER);
- event = *(win->eventstate); /* XXX huh huh? make api call */
+ wm_event_init_from_window(win, &event);
event.type = EVT_BUT_OPEN;
event.val = KM_PRESS;
event.customdata = but;
@@ -6581,6 +6579,8 @@ static void ui_handle_button_return_submenu(bContext *C, const wmEvent *event, u
static void ui_mouse_motion_towards_init_ex(uiPopupBlockHandle *menu, const int xy[2], const bool force)
{
+ BLI_assert(((uiBlock *)menu->region->uiblocks.first)->flag & UI_BLOCK_MOVEMOUSE_QUIT);
+
if (!menu->dotowards || force) {
menu->dotowards = true;
menu->towards_xy[0] = xy[0];
@@ -6613,6 +6613,25 @@ static bool ui_mouse_motion_towards_check(uiBlock *block, uiPopupBlockHandle *me
const float margin = MENU_TOWARDS_MARGIN;
rctf rect_px;
+ BLI_assert(block->flag & UI_BLOCK_MOVEMOUSE_QUIT);
+
+
+ /* annoying fix for [#36269], this is a bit odd but in fact works quite well
+ * don't mouse-out of a menu if another menu has been created after it.
+ * if this causes problems we could remove it and check on a different fix - campbell */
+ if (menu->region->next) {
+ /* am I the last menu (test) */
+ ARegion *ar = menu->region->next;
+ do {
+ uiBlock *block_iter = ar->uiblocks.first;
+ if (block_iter && ui_block_is_menu(block_iter)) {
+ return true;
+ }
+ } while ((ar = ar->next));
+ }
+ /* annoying fix end! */
+
+
if (!menu->dotowards) {
return false;
}
@@ -6837,10 +6856,12 @@ static int ui_handle_menu_event(bContext *C, const wmEvent *event, uiPopupBlockH
but = ui_but_find_activated(ar);
if (but && button_modal_state(but->active->state)) {
- /* if a button is activated modal, always reset the start mouse
- * position of the towards mechanism to avoid loosing focus,
- * and don't handle events */
- ui_mouse_motion_towards_reinit(menu, &event->x);
+ if (block->flag & UI_BLOCK_MOVEMOUSE_QUIT) {
+ /* if a button is activated modal, always reset the start mouse
+ * position of the towards mechanism to avoid loosing focus,
+ * and don't handle events */
+ ui_mouse_motion_towards_reinit(menu, &event->x);
+ }
}
else if (event->type == TIMER) {
if (event->customdata == menu->scrolltimer)
@@ -6849,7 +6870,9 @@ static int ui_handle_menu_event(bContext *C, const wmEvent *event, uiPopupBlockH
else {
/* for ui_mouse_motion_towards_block */
if (event->type == MOUSEMOVE) {
- ui_mouse_motion_towards_init(menu, &event->x);
+ if (block->flag & UI_BLOCK_MOVEMOUSE_QUIT) {
+ ui_mouse_motion_towards_init(menu, &event->x);
+ }
/* add menu scroll timer, if needed */
if (ui_menu_scroll_test(block, my))
@@ -7154,11 +7177,12 @@ static int ui_handle_menu_event(bContext *C, const wmEvent *event, uiPopupBlockH
menu->menuretval = UI_RETURN_CANCEL | UI_RETURN_POPUP_OK;
}
else {
- ui_mouse_motion_towards_check(block, menu, &event->x, is_parent_inside == false);
/* check mouse moving outside of the menu */
if (inside == 0 && (block->flag & UI_BLOCK_MOVEMOUSE_QUIT)) {
uiSafetyRct *saferct;
+
+ ui_mouse_motion_towards_check(block, menu, &event->x, is_parent_inside == false);
/* check for all parent rects, enables arrowkeys to be used */
for (saferct = block->saferct.first; saferct; saferct = saferct->next) {
@@ -7247,9 +7271,11 @@ static int ui_handle_menu_return_submenu(bContext *C, const wmEvent *event, uiPo
submenu->menuretval = 0;
}
- /* for cases where close does not cascade, allow the user to
- * move the mouse back towards the menu without closing */
- ui_mouse_motion_towards_reinit(menu, &event->x);
+ if (block->flag & UI_BLOCK_MOVEMOUSE_QUIT) {
+ /* for cases where close does not cascade, allow the user to
+ * move the mouse back towards the menu without closing */
+ ui_mouse_motion_towards_reinit(menu, &event->x);
+ }
if (menu->menuretval)
return WM_UI_HANDLER_CONTINUE;
@@ -7304,12 +7330,16 @@ static int ui_handle_menus_recursive(bContext *C, const wmEvent *event, uiPopupB
}
if (do_but_search) {
+ uiBlock *block = menu->region->uiblocks.first;
+
retval = ui_handle_menu_button(C, event, menu);
- /* when there is a active search button and we close it,
- * we need to reinit the mouse coords [#35346] */
- if (ui_but_find_activated(menu->region) != but) {
- do_towards_reinit = true;
+ if (block->flag & UI_BLOCK_MOVEMOUSE_QUIT) {
+ /* when there is a active search button and we close it,
+ * we need to reinit the mouse coords [#35346] */
+ if (ui_but_find_activated(menu->region) != but) {
+ do_towards_reinit = true;
+ }
}
}
else {
diff --git a/source/blender/editors/interface/interface_intern.h b/source/blender/editors/interface/interface_intern.h
index 82352cee05e..d2a8c47b347 100644
--- a/source/blender/editors/interface/interface_intern.h
+++ b/source/blender/editors/interface/interface_intern.h
@@ -427,6 +427,8 @@ struct uiKeyNavLock {
struct uiPopupBlockHandle {
/* internal */
struct ARegion *region;
+
+ /* use only for 'UI_BLOCK_MOVEMOUSE_QUIT' popups */
float towards_xy[2];
double towardstime;
bool dotowards;
diff --git a/source/blender/editors/interface/interface_layout.c b/source/blender/editors/interface/interface_layout.c
index 2e80af1b3ad..079ba97aa9d 100644
--- a/source/blender/editors/interface/interface_layout.c
+++ b/source/blender/editors/interface/interface_layout.c
@@ -355,7 +355,7 @@ static void ui_item_array(uiLayout *layout, uiBlock *block, const char *name, in
PropertyType type;
PropertySubType subtype;
uiLayout *sub;
- int a, b;
+ unsigned int a, b;
/* retrieve type and subtype */
type = RNA_property_type(prop);
@@ -373,8 +373,8 @@ static void ui_item_array(uiLayout *layout, uiBlock *block, const char *name, in
/* special check for layer layout */
int butw, buth, unit;
int cols = (len >= 20) ? 2 : 1;
- int colbuts = len / (2 * cols);
- int layer_used = 0;
+ const unsigned int colbuts = len / (2 * cols);
+ unsigned int layer_used = 0;
uiBlockSetCurLayout(block, uiLayoutAbsolute(layout, FALSE));
diff --git a/source/blender/editors/interface/interface_ops.c b/source/blender/editors/interface/interface_ops.c
index 9f7d1435195..cfe6e313c58 100644
--- a/source/blender/editors/interface/interface_ops.c
+++ b/source/blender/editors/interface/interface_ops.c
@@ -148,7 +148,7 @@ static void eyedropper_color_sample_fl(bContext *C, Eyedropper *UNUSED(eye), int
if (BLI_rcti_isect_pt(&sa->totrct, mx, my)) {
if (sa->spacetype == SPACE_IMAGE) {
ARegion *ar = BKE_area_find_region_type(sa, RGN_TYPE_WINDOW);
- if (BLI_rcti_isect_pt(&ar->winrct, mx, my)) {
+ if (ar && BLI_rcti_isect_pt(&ar->winrct, mx, my)) {
SpaceImage *sima = sa->spacedata.first;
int mval[2] = {mx - ar->winrct.xmin,
my - ar->winrct.ymin};
@@ -160,7 +160,7 @@ static void eyedropper_color_sample_fl(bContext *C, Eyedropper *UNUSED(eye), int
}
else if (sa->spacetype == SPACE_NODE) {
ARegion *ar = BKE_area_find_region_type(sa, RGN_TYPE_WINDOW);
- if (BLI_rcti_isect_pt(&ar->winrct, mx, my)) {
+ if (ar && BLI_rcti_isect_pt(&ar->winrct, mx, my)) {
SpaceNode *snode = sa->spacedata.first;
int mval[2] = {mx - ar->winrct.xmin,
my - ar->winrct.ymin};
@@ -172,7 +172,7 @@ static void eyedropper_color_sample_fl(bContext *C, Eyedropper *UNUSED(eye), int
}
else if (sa->spacetype == SPACE_CLIP) {
ARegion *ar = BKE_area_find_region_type(sa, RGN_TYPE_WINDOW);
- if (BLI_rcti_isect_pt(&ar->winrct, mx, my)) {
+ if (ar && BLI_rcti_isect_pt(&ar->winrct, mx, my)) {
SpaceClip *sc = sa->spacedata.first;
int mval[2] = {mx - ar->winrct.xmin,
my - ar->winrct.ymin};
@@ -704,12 +704,12 @@ static void UI_OT_reports_to_textblock(wmOperatorType *ot)
/* EditSource Utility funcs and operator,
* note, this includes utility functions and button matching checks */
-struct uiEditSourceStore {
+typedef struct uiEditSourceStore {
uiBut but_orig;
GHash *hash;
} uiEditSourceStore;
-struct uiEditSourceButStore {
+typedef struct uiEditSourceButStore {
char py_dbg_fn[FILE_MAX];
int py_dbg_ln;
} uiEditSourceButStore;
@@ -917,7 +917,7 @@ static void edittranslation_find_po_file(const char *root, const char *uilng, ch
/* First, full lang code. */
BLI_snprintf(tstr, sizeof(tstr), "%s.po", uilng);
BLI_join_dirfile(path, maxlen, root, uilng);
- BLI_join_dirfile(path, maxlen, path, tstr);
+ BLI_path_append(path, maxlen, tstr);
if (BLI_is_file(path))
return;
@@ -941,7 +941,7 @@ static void edittranslation_find_po_file(const char *root, const char *uilng, ch
BLI_join_dirfile(path, maxlen, root, tstr);
strcat(tstr, ".po");
- BLI_join_dirfile(path, maxlen, path, tstr);
+ BLI_path_append(path, maxlen, tstr);
if (BLI_is_file(path))
return;
}
diff --git a/source/blender/editors/interface/interface_regions.c b/source/blender/editors/interface/interface_regions.c
index 9c6a606333d..95f47be0b70 100644
--- a/source/blender/editors/interface/interface_regions.c
+++ b/source/blender/editors/interface/interface_regions.c
@@ -590,7 +590,7 @@ ARegion *ui_tooltip_create(bContext *C, ARegion *butregion, uiBut *but)
/* never fails */
id_path = RNA_path_full_ID_py(id);
- if (ptr->id.data && ptr->data && prop) {
+ if (ptr->data && prop) {
data_path = RNA_path_from_ID_to_property(ptr, prop);
}
@@ -2268,10 +2268,8 @@ uiBlock *ui_block_func_COLOR(bContext *C, uiPopupBlockHandle *handle, void *arg_
block = uiBeginBlock(C, handle->region, __func__, UI_EMBOSS);
- if (but->rnaprop) {
- if (RNA_property_subtype(but->rnaprop) == PROP_COLOR_GAMMA) {
- block->color_profile = FALSE;
- }
+ if (RNA_property_subtype(but->rnaprop) == PROP_COLOR_GAMMA) {
+ block->color_profile = false;
}
if (but->block) {
@@ -2528,7 +2526,7 @@ uiPopupMenu *uiPupMenuBegin(bContext *C, const char *title, int icon)
uiStyle *style = UI_GetStyleDraw();
uiPopupMenu *pup = MEM_callocN(sizeof(uiPopupMenu), "popup menu");
uiBut *but;
-
+
pup->block = uiBeginBlock(C, NULL, __func__, UI_EMBOSSP);
pup->block->flag |= UI_BLOCK_POPUP_MEMORY;
pup->block->puphash = ui_popup_menu_hash(title);
@@ -2542,7 +2540,7 @@ uiPopupMenu *uiPupMenuBegin(bContext *C, const char *title, int icon)
pup->block->handle = MEM_callocN(sizeof(uiPopupBlockHandle), "uiPopupBlockHandle");
/* create title button */
- if (title && title[0]) {
+ if (title[0]) {
char titlestr[256];
if (icon) {
diff --git a/source/blender/editors/interface/interface_templates.c b/source/blender/editors/interface/interface_templates.c
index f45bd1c3463..61cc021800e 100644
--- a/source/blender/editors/interface/interface_templates.c
+++ b/source/blender/editors/interface/interface_templates.c
@@ -1147,7 +1147,7 @@ static uiLayout *draw_constraint(uiLayout *layout, Object *ob, bConstraint *con)
uiBlockSetEmboss(block, UI_EMBOSS);
/* name */
- uiDefBut(block, LABEL, B_CONSTRAINT_TEST, typestr, xco + 10, yco, 100, 18, NULL, 0.0, 0.0, 0.0, 0.0, "");
+ uiDefBut(block, LABEL, B_CONSTRAINT_TEST, typestr, xco + 0.5f*UI_UNIT_X, yco, 5 * UI_UNIT_X, 0.9f*UI_UNIT_Y, NULL, 0.0, 0.0, 0.0, 0.0, "");
if (con->flag & CONSTRAINT_DISABLE)
uiLayoutSetRedAlert(row, TRUE);
@@ -1165,9 +1165,9 @@ static uiLayout *draw_constraint(uiLayout *layout, Object *ob, bConstraint *con)
uiBlockSetEmboss(block, UI_EMBOSSN);
/* draw a ghost icon (for proxy) and also a lock beside it, to show that constraint is "proxy locked" */
- uiDefIconBut(block, BUT, B_CONSTRAINT_TEST, ICON_GHOST, xco + 244, yco, 19, 19,
+ uiDefIconBut(block, BUT, B_CONSTRAINT_TEST, ICON_GHOST, xco + 12.2f * UI_UNIT_X, yco, 0.95f * UI_UNIT_X, 0.95f * UI_UNIT_Y,
NULL, 0.0, 0.0, 0.0, 0.0, TIP_("Proxy Protected"));
- uiDefIconBut(block, BUT, B_CONSTRAINT_TEST, ICON_LOCKED, xco + 262, yco, 19, 19,
+ uiDefIconBut(block, BUT, B_CONSTRAINT_TEST, ICON_LOCKED, xco + 13.1f * UI_UNIT_X, yco, 0.95f * UI_UNIT_X, 0.95f * UI_UNIT_Y,
NULL, 0.0, 0.0, 0.0, 0.0, TIP_("Proxy Protected"));
uiBlockSetEmboss(block, UI_EMBOSS);
@@ -1226,7 +1226,7 @@ static uiLayout *draw_constraint(uiLayout *layout, Object *ob, bConstraint *con)
/* Draw constraint data */
if ((con->flag & CONSTRAINT_EXPAND) == 0) {
- (yco) -= 21;
+ (yco) -= 10.5f * UI_UNIT_Y;
}
else {
box = uiLayoutBox(col);
diff --git a/source/blender/editors/interface/resources.c b/source/blender/editors/interface/resources.c
index dc780d6a4f1..1ef4d43c9f3 100644
--- a/source/blender/editors/interface/resources.c
+++ b/source/blender/editors/interface/resources.c
@@ -1953,7 +1953,7 @@ void init_userdef_do_versions(void)
if (bmain->versionfile < 262 || (bmain->versionfile == 262 && bmain->subversionfile < 4)) {
bTheme *btheme;
for (btheme = U.themes.first; btheme; btheme = btheme->next) {
- if (btheme->tseq.movieclip[0] == 0) {
+ if (btheme->tseq.movieclip[3] == 0) {
rgba_char_args_set(btheme->tseq.movieclip, 32, 32, 143, 255);
}
}
@@ -2002,7 +2002,7 @@ void init_userdef_do_versions(void)
if (bmain->versionfile < 263 || (bmain->versionfile == 263 && bmain->subversionfile < 11)) {
bTheme *btheme;
for (btheme = U.themes.first; btheme; btheme = btheme->next) {
- if (btheme->tseq.movieclip[0] == 0) {
+ if (btheme->tseq.mask[3] == 0) {
rgba_char_args_set(btheme->tseq.mask, 152, 78, 62, 255);
}
}
diff --git a/source/blender/editors/interface/view2d_ops.c b/source/blender/editors/interface/view2d_ops.c
index 772bd6fe671..929b7ae2a5d 100644
--- a/source/blender/editors/interface/view2d_ops.c
+++ b/source/blender/editors/interface/view2d_ops.c
@@ -1288,7 +1288,7 @@ void UI_view2d_smooth_view(bContext *C, ARegion *ar,
fac = smooth_view_rect_to_fac(&v2d->cur, cur);
}
- if (C && U.smooth_viewtx && fac > FLT_EPSILON) {
+ if (U.smooth_viewtx && fac > FLT_EPSILON) {
int changed = FALSE;
if (BLI_rctf_compare(&sms.new_cur, &v2d->cur, FLT_EPSILON) == FALSE)
diff --git a/source/blender/editors/mask/mask_draw.c b/source/blender/editors/mask/mask_draw.c
index 924e25e4ef4..fec4ab87996 100644
--- a/source/blender/editors/mask/mask_draw.c
+++ b/source/blender/editors/mask/mask_draw.c
@@ -165,7 +165,7 @@ static void draw_spline_points(const bContext *C, MaskLayer *masklay, MaskSpline
int j;
- for (j = 0; j < point->tot_uw + 1; j++) {
+ for (j = 0; j <= point->tot_uw; j++) {
float feather_point[2];
int sel = FALSE;
diff --git a/source/blender/editors/mask/mask_ops.c b/source/blender/editors/mask/mask_ops.c
index 5c2aacf0713..c9d3bd19941 100644
--- a/source/blender/editors/mask/mask_ops.c
+++ b/source/blender/editors/mask/mask_ops.c
@@ -197,7 +197,7 @@ int ED_mask_feather_find_nearest(const bContext *C, Mask *mask, float normal_co[
int j;
MaskSplinePoint *cur_point = &spline->points[i];
- for (j = 0; j < cur_point->tot_uw + 1; j++) {
+ for (j = 0; j <= cur_point->tot_uw; j++) {
float cur_len, vec[2];
vec[0] = (*fp)[0] * scalex;
diff --git a/source/blender/editors/mask/mask_select.c b/source/blender/editors/mask/mask_select.c
index c524aeb06ee..90796e9eb93 100644
--- a/source/blender/editors/mask/mask_select.c
+++ b/source/blender/editors/mask/mask_select.c
@@ -809,8 +809,9 @@ static int mask_select_more_less(bContext *C, bool more)
}
for (spline = masklay->splines.first; spline; spline = spline->next) {
+ const bool cyclic = (spline->flag & MASK_SPLINE_CYCLIC) != 0;
+ bool start_sel, end_sel, prev_sel, cur_sel;
int i;
- bool start_sel, end_sel, prev_sel, cur_sel, cyclic = spline->flag & MASK_SPLINE_CYCLIC;
/* reselect point if any handle is selected to make the result more predictable */
for (i = 0; i < spline->tot_point; i++) {
@@ -826,6 +827,10 @@ static int mask_select_more_less(bContext *C, bool more)
start_sel = !!MASKPOINT_ISSEL_KNOT(spline->points);
end_sel = !!MASKPOINT_ISSEL_KNOT(&spline->points[spline->tot_point - 1]);
}
+ else {
+ start_sel = false;
+ end_sel = false;
+ }
for (i = 0; i < spline->tot_point; i++) {
if (i == 0 && !cyclic) {
diff --git a/source/blender/editors/mesh/editface.c b/source/blender/editors/mesh/editface.c
index 6fd198d9ae6..902906fcf8a 100644
--- a/source/blender/editors/mesh/editface.c
+++ b/source/blender/editors/mesh/editface.c
@@ -198,8 +198,8 @@ static void select_linked_tfaces_with_seams(Mesh *me, const unsigned int index,
bool do_it = true;
bool mark = false;
- BLI_bitmap edge_tag = BLI_BITMAP_NEW(me->totedge, __func__);
- BLI_bitmap poly_tag = BLI_BITMAP_NEW(me->totpoly, __func__);
+ BLI_bitmap *edge_tag = BLI_BITMAP_NEW(me->totedge, __func__);
+ BLI_bitmap *poly_tag = BLI_BITMAP_NEW(me->totpoly, __func__);
if (index != (unsigned int)-1) {
/* only put face under cursor in array */
@@ -291,49 +291,37 @@ void paintface_deselect_all_visible(Object *ob, int action, bool flush_flags)
me = BKE_mesh_from_object(ob);
if (me == NULL) return;
- if (action == SEL_INVERT) {
+ if (action == SEL_TOGGLE) {
+ action = SEL_SELECT;
+
mpoly = me->mpoly;
a = me->totpoly;
while (a--) {
- if ((mpoly->flag & ME_HIDE) == 0) {
- mpoly->flag ^= ME_FACE_SEL;
+ if ((mpoly->flag & ME_HIDE) == 0 && mpoly->flag & ME_FACE_SEL) {
+ action = SEL_DESELECT;
+ break;
}
mpoly++;
}
}
- else {
- if (action == SEL_TOGGLE) {
- action = SEL_SELECT;
-
- mpoly = me->mpoly;
- a = me->totpoly;
- while (a--) {
- if ((mpoly->flag & ME_HIDE) == 0 && mpoly->flag & ME_FACE_SEL) {
- action = SEL_DESELECT;
- break;
- }
- mpoly++;
- }
- }
- mpoly = me->mpoly;
- a = me->totpoly;
- while (a--) {
- if ((mpoly->flag & ME_HIDE) == 0) {
- switch (action) {
- case SEL_SELECT:
- mpoly->flag |= ME_FACE_SEL;
- break;
- case SEL_DESELECT:
- mpoly->flag &= ~ME_FACE_SEL;
- break;
- case SEL_INVERT:
- mpoly->flag ^= ME_FACE_SEL;
- break;
- }
+ mpoly = me->mpoly;
+ a = me->totpoly;
+ while (a--) {
+ if ((mpoly->flag & ME_HIDE) == 0) {
+ switch (action) {
+ case SEL_SELECT:
+ mpoly->flag |= ME_FACE_SEL;
+ break;
+ case SEL_DESELECT:
+ mpoly->flag &= ~ME_FACE_SEL;
+ break;
+ case SEL_INVERT:
+ mpoly->flag ^= ME_FACE_SEL;
+ break;
}
- mpoly++;
}
+ mpoly++;
}
if (flush_flags) {
@@ -557,49 +545,37 @@ void paintvert_deselect_all_visible(Object *ob, int action, bool flush_flags)
me = BKE_mesh_from_object(ob);
if (me == NULL) return;
- if (action == SEL_INVERT) {
+ if (action == SEL_TOGGLE) {
+ action = SEL_SELECT;
+
mvert = me->mvert;
a = me->totvert;
while (a--) {
- if ((mvert->flag & ME_HIDE) == 0) {
- mvert->flag ^= SELECT;
+ if ((mvert->flag & ME_HIDE) == 0 && mvert->flag & SELECT) {
+ action = SEL_DESELECT;
+ break;
}
mvert++;
}
}
- else {
- if (action == SEL_TOGGLE) {
- action = SEL_SELECT;
-
- mvert = me->mvert;
- a = me->totvert;
- while (a--) {
- if ((mvert->flag & ME_HIDE) == 0 && mvert->flag & SELECT) {
- action = SEL_DESELECT;
- break;
- }
- mvert++;
- }
- }
- mvert = me->mvert;
- a = me->totvert;
- while (a--) {
- if ((mvert->flag & ME_HIDE) == 0) {
- switch (action) {
- case SEL_SELECT:
- mvert->flag |= SELECT;
- break;
- case SEL_DESELECT:
- mvert->flag &= ~SELECT;
- break;
- case SEL_INVERT:
- mvert->flag ^= SELECT;
- break;
- }
+ mvert = me->mvert;
+ a = me->totvert;
+ while (a--) {
+ if ((mvert->flag & ME_HIDE) == 0) {
+ switch (action) {
+ case SEL_SELECT:
+ mvert->flag |= SELECT;
+ break;
+ case SEL_DESELECT:
+ mvert->flag &= ~SELECT;
+ break;
+ case SEL_INVERT:
+ mvert->flag ^= SELECT;
+ break;
}
- mvert++;
}
+ mvert++;
}
/* handle mselect */
diff --git a/source/blender/editors/mesh/editmesh_add.c b/source/blender/editors/mesh/editmesh_add.c
index e544592365d..f372053db55 100644
--- a/source/blender/editors/mesh/editmesh_add.c
+++ b/source/blender/editors/mesh/editmesh_add.c
@@ -118,9 +118,10 @@ static int add_primitive_plane_exec(bContext *C, wmOperator *op)
obedit = make_prim_init(C, CTX_DATA_(BLF_I18NCONTEXT_ID_MESH, "Plane"), &dia, mat, &was_editmode, loc, rot, layer);
em = BKE_editmesh_from_object(obedit);
- if (!EDBM_op_call_and_selectf(em, op, "verts.out",
- "create_grid x_segments=%i y_segments=%i size=%f matrix=%m4",
- 1, 1, RNA_float_get(op->ptr, "radius"), mat))
+ if (!EDBM_op_call_and_selectf(
+ em, op, "verts.out", false,
+ "create_grid x_segments=%i y_segments=%i size=%f matrix=%m4",
+ 1, 1, RNA_float_get(op->ptr, "radius"), mat))
{
return OPERATOR_CANCELLED;
}
@@ -162,8 +163,10 @@ static int add_primitive_cube_exec(bContext *C, wmOperator *op)
obedit = make_prim_init(C, CTX_DATA_(BLF_I18NCONTEXT_ID_MESH, "Cube"), &dia, mat, &was_editmode, loc, rot, layer);
em = BKE_editmesh_from_object(obedit);
- if (!EDBM_op_call_and_selectf(em, op, "verts.out", "create_cube matrix=%m4 size=%f",
- mat, RNA_float_get(op->ptr, "radius") * 2.0f))
+ if (!EDBM_op_call_and_selectf(
+ em, op, "verts.out", false,
+ "create_cube matrix=%m4 size=%f",
+ mat, RNA_float_get(op->ptr, "radius") * 2.0f))
{
return OPERATOR_CANCELLED;
}
@@ -216,10 +219,11 @@ static int add_primitive_circle_exec(bContext *C, wmOperator *op)
obedit = make_prim_init(C, CTX_DATA_(BLF_I18NCONTEXT_ID_MESH, "Circle"), &dia, mat, &was_editmode, loc, rot, layer);
em = BKE_editmesh_from_object(obedit);
- if (!EDBM_op_call_and_selectf(em, op, "verts.out",
- "create_circle segments=%i diameter=%f cap_ends=%b cap_tris=%b matrix=%m4",
- RNA_int_get(op->ptr, "vertices"), RNA_float_get(op->ptr, "radius"),
- cap_end, cap_tri, mat))
+ if (!EDBM_op_call_and_selectf(
+ em, op, "verts.out", false,
+ "create_circle segments=%i diameter=%f cap_ends=%b cap_tris=%b matrix=%m4",
+ RNA_int_get(op->ptr, "vertices"), RNA_float_get(op->ptr, "radius"),
+ cap_end, cap_tri, mat))
{
return OPERATOR_CANCELLED;
}
@@ -269,7 +273,7 @@ static int add_primitive_cylinder_exec(bContext *C, wmOperator *op)
em = BKE_editmesh_from_object(obedit);
if (!EDBM_op_call_and_selectf(
- em, op, "verts.out",
+ em, op, "verts.out", false,
"create_cone segments=%i diameter1=%f diameter2=%f cap_ends=%b cap_tris=%b depth=%f matrix=%m4",
RNA_int_get(op->ptr, "vertices"),
RNA_float_get(op->ptr, "radius"),
@@ -329,7 +333,7 @@ static int add_primitive_cone_exec(bContext *C, wmOperator *op)
em = BKE_editmesh_from_object(obedit);
if (!EDBM_op_call_and_selectf(
- em, op, "verts.out",
+ em, op, "verts.out", false,
"create_cone segments=%i diameter1=%f diameter2=%f cap_ends=%b cap_tris=%b depth=%f matrix=%m4",
RNA_int_get(op->ptr, "vertices"), RNA_float_get(op->ptr, "radius1"),
RNA_float_get(op->ptr, "radius2"), cap_end, cap_tri, RNA_float_get(op->ptr, "depth"), mat))
@@ -385,11 +389,12 @@ static int add_primitive_grid_exec(bContext *C, wmOperator *op)
obedit = make_prim_init(C, CTX_DATA_(BLF_I18NCONTEXT_ID_MESH, "Grid"), &dia, mat, &was_editmode, loc, rot, layer);
em = BKE_editmesh_from_object(obedit);
- if (!EDBM_op_call_and_selectf(em, op, "verts.out",
- "create_grid x_segments=%i y_segments=%i size=%f matrix=%m4",
- RNA_int_get(op->ptr, "x_subdivisions"),
- RNA_int_get(op->ptr, "y_subdivisions"),
- RNA_float_get(op->ptr, "radius"), mat))
+ if (!EDBM_op_call_and_selectf(
+ em, op, "verts.out", false,
+ "create_grid x_segments=%i y_segments=%i size=%f matrix=%m4",
+ RNA_int_get(op->ptr, "x_subdivisions"),
+ RNA_int_get(op->ptr, "y_subdivisions"),
+ RNA_float_get(op->ptr, "radius"), mat))
{
return OPERATOR_CANCELLED;
}
@@ -444,7 +449,10 @@ static int add_primitive_monkey_exec(bContext *C, wmOperator *op)
em = BKE_editmesh_from_object(obedit);
- if (!EDBM_op_call_and_selectf(em, op, "verts.out", "create_monkey matrix=%m4", mat)) {
+ if (!EDBM_op_call_and_selectf(
+ em, op, "verts.out", false,
+ "create_monkey matrix=%m4", mat))
+ {
return OPERATOR_CANCELLED;
}
@@ -485,10 +493,11 @@ static int add_primitive_uvsphere_exec(bContext *C, wmOperator *op)
obedit = make_prim_init(C, CTX_DATA_(BLF_I18NCONTEXT_ID_MESH, "Sphere"), &dia, mat, &was_editmode, loc, rot, layer);
em = BKE_editmesh_from_object(obedit);
- if (!EDBM_op_call_and_selectf(em, op, "verts.out",
- "create_uvsphere u_segments=%i v_segments=%i diameter=%f matrix=%m4",
- RNA_int_get(op->ptr, "segments"), RNA_int_get(op->ptr, "ring_count"),
- RNA_float_get(op->ptr, "size"), mat))
+ if (!EDBM_op_call_and_selectf(
+ em, op, "verts.out", false,
+ "create_uvsphere u_segments=%i v_segments=%i diameter=%f matrix=%m4",
+ RNA_int_get(op->ptr, "segments"), RNA_int_get(op->ptr, "ring_count"),
+ RNA_float_get(op->ptr, "size"), mat))
{
return OPERATOR_CANCELLED;
}
@@ -538,7 +547,7 @@ static int add_primitive_icosphere_exec(bContext *C, wmOperator *op)
em = BKE_editmesh_from_object(obedit);
if (!EDBM_op_call_and_selectf(
- em, op, "verts.out",
+ em, op, "verts.out", false,
"create_icosphere subdivisions=%i diameter=%f matrix=%m4",
RNA_int_get(op->ptr, "subdivisions"),
RNA_float_get(op->ptr, "size"), mat))
diff --git a/source/blender/editors/mesh/editmesh_extrude.c b/source/blender/editors/mesh/editmesh_extrude.c
index 65c528dbe03..b38f09b1dec 100644
--- a/source/blender/editors/mesh/editmesh_extrude.c
+++ b/source/blender/editors/mesh/editmesh_extrude.c
@@ -713,7 +713,7 @@ static int edbm_spin_exec(bContext *C, wmOperator *op)
BMEditMesh *em = BKE_editmesh_from_object(obedit);
BMesh *bm = em->bm;
BMOperator spinop;
- float cent[3], axis[3], imat[3][3];
+ float cent[3], axis[3];
float d[3] = {0.0f, 0.0f, 0.0f};
int steps, dupli;
float angle;
@@ -726,15 +726,10 @@ static int edbm_spin_exec(bContext *C, wmOperator *op)
angle = -angle;
dupli = RNA_boolean_get(op->ptr, "dupli");
- /* undo object transformation */
- copy_m3_m4(imat, obedit->imat);
- sub_v3_v3(cent, obedit->obmat[3]);
- mul_m3_v3(imat, cent);
- mul_m3_v3(imat, axis);
-
+ /* keep the values in worldspace since we're passing the obmat */
if (!EDBM_op_init(em, &spinop, op,
- "spin geom=%hvef cent=%v axis=%v dvec=%v steps=%i angle=%f use_duplicate=%b",
- BM_ELEM_SELECT, cent, axis, d, steps, angle, dupli))
+ "spin geom=%hvef cent=%v axis=%v dvec=%v steps=%i angle=%f space=%m4 use_duplicate=%b",
+ BM_ELEM_SELECT, cent, axis, d, steps, angle, obedit->obmat, dupli))
{
return OPERATOR_CANCELLED;
}
@@ -800,8 +795,7 @@ static int edbm_screw_exec(bContext *C, wmOperator *op)
BMVert *eve, *v1, *v2;
BMIter iter, eiter;
BMOperator spinop;
- float dvec[3], nor[3], cent[3], axis[3];
- float imat[3][3];
+ float dvec[3], nor[3], cent[3], axis[3], v1_co_global[3], v2_co_global[3];
int steps, turns;
int valence;
@@ -811,13 +805,6 @@ static int edbm_screw_exec(bContext *C, wmOperator *op)
RNA_float_get_array(op->ptr, "center", cent);
RNA_float_get_array(op->ptr, "axis", axis);
- /* undo object transformation */
- copy_m3_m4(imat, obedit->imat);
- sub_v3_v3(cent, obedit->obmat[3]);
- mul_m3_v3(imat, cent);
- mul_m3_v3(imat, axis);
-
-
/* find two vertices with valence count == 1, more or less is wrong */
v1 = NULL;
v2 = NULL;
@@ -850,15 +837,17 @@ static int edbm_screw_exec(bContext *C, wmOperator *op)
}
/* calculate dvec */
- sub_v3_v3v3(dvec, v1->co, v2->co);
+ mul_v3_m4v3(v1_co_global, obedit->obmat, v1->co);
+ mul_v3_m4v3(v2_co_global, obedit->obmat, v2->co);
+ sub_v3_v3v3(dvec, v1_co_global, v2_co_global);
mul_v3_fl(dvec, 1.0f / steps);
- if (dot_v3v3(nor, dvec) > 0.000f)
+ if (dot_v3v3(nor, dvec) > 0.0f)
negate_v3(dvec);
if (!EDBM_op_init(em, &spinop, op,
- "spin geom=%hvef cent=%v axis=%v dvec=%v steps=%i angle=%f use_duplicate=%b",
- BM_ELEM_SELECT, cent, axis, dvec, turns * steps, DEG2RADF(360.0f * turns), false))
+ "spin geom=%hvef cent=%v axis=%v dvec=%v steps=%i angle=%f space=%m4 use_duplicate=%b",
+ BM_ELEM_SELECT, cent, axis, dvec, turns * steps, DEG2RADF(360.0f * turns), obedit->obmat, false))
{
return OPERATOR_CANCELLED;
}
diff --git a/source/blender/editors/mesh/editmesh_knife.c b/source/blender/editors/mesh/editmesh_knife.c
index 50db460e5bc..e1d0a412ce7 100644
--- a/source/blender/editors/mesh/editmesh_knife.c
+++ b/source/blender/editors/mesh/editmesh_knife.c
@@ -38,6 +38,7 @@
#include "BLI_listbase.h"
#include "BLI_string.h"
#include "BLI_array.h"
+#include "BLI_alloca.h"
#include "BLI_linklist.h"
#include "BLI_math.h"
#include "BLI_smallhash.h"
@@ -2623,15 +2624,15 @@ static bool knife_edge_in_face(KnifeTool_OpData *UNUSED(kcd), KnifeEdge *kfe, BM
/* Split face f with KnifeEdges on chain. f remains as one side, the face formed is put in *newface.
* The new face will be on the left side of the chain as viewed from the normal-out side of f. */
-static void knife_make_chain_cut(KnifeTool_OpData *kcd, BMFace *f, ListBase *chain, BMFace **newface)
+static void knife_make_chain_cut(KnifeTool_OpData *kcd, BMFace *f, ListBase *chain, BMFace **r_f_new)
{
BMesh *bm = kcd->em->bm;
KnifeEdge *kfe, *kfelast;
BMVert *v1, *v2;
- BMFace *fnew;
+ BMFace *f_new;
Ref *ref;
KnifeVert *kfv, *kfvprev;
- BMLoop *lnew, *l_iter;
+ BMLoop *l_new, *l_iter;
int i;
int nco = BLI_countlist(chain) - 1;
float (*cos)[3] = BLI_array_alloca(cos, nco);
@@ -2652,23 +2653,21 @@ static void knife_make_chain_cut(KnifeTool_OpData *kcd, BMFace *f, ListBase *cha
kfvprev = kfv;
}
BLI_assert(i == nco);
- lnew = NULL;
+ l_new = NULL;
if (nco == 0) {
/* Want to prevent creating two-sided polygons */
if (BM_edge_exists(v1, v2)) {
- *newface = NULL;
+ f_new = NULL;
}
else {
- *newface = BM_face_split(bm, f, v1, v2, &lnew, NULL, true);
+ f_new = BM_face_split(bm, f, v1, v2, &l_new, NULL, true);
}
}
else {
- fnew = BM_face_split_n(bm, f, v1, v2, cos, nco, &lnew, NULL);
- *newface = fnew;
-
- if (fnew) {
+ f_new = BM_face_split_n(bm, f, v1, v2, cos, nco, &l_new, NULL);
+ if (f_new) {
/* Now go through lnew chain matching up chain kv's and assign real v's to them */
- for (l_iter = lnew->next, i = 0; i < nco; l_iter = l_iter->next, i++) {
+ for (l_iter = l_new->next, i = 0; i < nco; l_iter = l_iter->next, i++) {
BLI_assert(equals_v3v3(cos[i], l_iter->v->co));
if (kcd->select_result) {
BM_edge_select_set(bm, l_iter->e, true);
@@ -2680,10 +2679,15 @@ static void knife_make_chain_cut(KnifeTool_OpData *kcd, BMFace *f, ListBase *cha
/* the select chain above doesnt account for the first loop */
if (kcd->select_result) {
- if (lnew) {
- BM_edge_select_set(bm, lnew->e, true);
+ if (l_new) {
+ BM_edge_select_set(bm, l_new->e, true);
}
}
+ else {
+ BM_elem_select_copy(bm, bm, f_new, f);
+ }
+
+ *r_f_new = f_new;
}
static void knife_make_face_cuts(KnifeTool_OpData *kcd, BMFace *f, ListBase *kfedges)
@@ -2887,6 +2891,7 @@ static void knifetool_finish_ex(KnifeTool_OpData *kcd)
knife_make_cuts(kcd);
#endif
+ EDBM_selectmode_flush(kcd->em);
EDBM_mesh_normals_update(kcd->em);
EDBM_update_generic(kcd->em, true, true);
}
diff --git a/source/blender/editors/mesh/editmesh_loopcut.c b/source/blender/editors/mesh/editmesh_loopcut.c
index 3c1b210d171..892b773b1ba 100644
--- a/source/blender/editors/mesh/editmesh_loopcut.c
+++ b/source/blender/editors/mesh/editmesh_loopcut.c
@@ -125,9 +125,9 @@ static void edgering_find_order(BMEdge *lasteed, BMEdge *eed,
l = eed->l;
/* find correct order for v[1] */
- if (!(BM_edge_in_face(l->f, eed) && BM_edge_in_face(l->f, lasteed))) {
+ if (!(BM_edge_in_face(eed, l->f) && BM_edge_in_face(lasteed, l->f))) {
BM_ITER_ELEM (l, &liter, l, BM_LOOPS_OF_LOOP) {
- if (BM_edge_in_face(l->f, eed) && BM_edge_in_face(l->f, lasteed))
+ if (BM_edge_in_face(eed, l->f) && BM_edge_in_face(lasteed, l->f))
break;
}
}
diff --git a/source/blender/editors/mesh/editmesh_rip.c b/source/blender/editors/mesh/editmesh_rip.c
index c027c1bbcd1..1360a180b2d 100644
--- a/source/blender/editors/mesh/editmesh_rip.c
+++ b/source/blender/editors/mesh/editmesh_rip.c
@@ -510,24 +510,6 @@ static void edbm_tagged_loop_pairs_do_fill_faces(BMesh *bm, UnorderedLoopPair *u
/* --- end 'face-fill' code --- */
-
-static bool edbm_rip_call_edgesplit(BMEditMesh *em, wmOperator *op)
-{
- BMOperator bmop;
-
- if (!EDBM_op_init(em, &bmop, op, "split_edges edges=%he verts=%hv use_verts=%b",
- BM_ELEM_TAG, BM_ELEM_SELECT, true))
- {
- return false;
- }
- BMO_op_exec(em->bm, &bmop);
- if (!EDBM_op_finish(em, &bmop, op, true)) {
- return false;
- }
-
- return true;
-}
-
/**
* This is the main vert ripping function (rip when one vertex is selected)
*/
@@ -648,11 +630,9 @@ static int edbm_rip_invoke__vert(bContext *C, wmOperator *op, const wmEvent *eve
BM_vert_select_set(bm, v, false);
- if (bmesh_vert_separate(bm, v, &vout, &vout_len) == false) {
- BKE_report(op->reports, RPT_ERROR, "Error ripping vertex from faces");
- return OPERATOR_CANCELLED;
- }
- else if (vout_len < 2) {
+ bmesh_vert_separate(bm, v, &vout, &vout_len, true);
+
+ if (vout_len < 2) {
MEM_freeN(vout);
/* set selection back to avoid active-unselected vertex */
BM_vert_select_set(bm, v, true);
@@ -786,10 +766,7 @@ static int edbm_rip_invoke__vert(bContext *C, wmOperator *op, const wmEvent *eve
fill_uloop_pairs = edbm_tagged_loop_pairs_to_fill(bm);
}
- if (!edbm_rip_call_edgesplit(em, op)) {
- if (fill_uloop_pairs) MEM_freeN(fill_uloop_pairs);
- return OPERATOR_CANCELLED;
- }
+ BM_mesh_edgesplit(em->bm, true, true, true);
}
dist = FLT_MAX;
@@ -951,10 +928,7 @@ static int edbm_rip_invoke__edge(bContext *C, wmOperator *op, const wmEvent *eve
fill_uloop_pairs = edbm_tagged_loop_pairs_to_fill(bm);
}
- if (!edbm_rip_call_edgesplit(em, op)) {
- if (fill_uloop_pairs) MEM_freeN(fill_uloop_pairs);
- return OPERATOR_CANCELLED;
- }
+ BM_mesh_edgesplit(em->bm, true, true, true);
/* note: the output of the bmesh operator is ignored, since we built
* the contiguous loop pairs to split already, its possible that some
@@ -965,6 +939,9 @@ static int edbm_rip_invoke__edge(bContext *C, wmOperator *op, const wmEvent *eve
ar, projectMat, fmval);
MEM_freeN(eloop_pairs);
+ /* deselect loose verts */
+ BM_mesh_select_mode_clean_ex(bm, SCE_SELECT_EDGE);
+
if (do_fill && fill_uloop_pairs) {
edbm_tagged_loop_pairs_do_fill_faces(bm, fill_uloop_pairs);
MEM_freeN(fill_uloop_pairs);
@@ -975,7 +952,7 @@ static int edbm_rip_invoke__edge(bContext *C, wmOperator *op, const wmEvent *eve
return OPERATOR_CANCELLED;
}
- EDBM_selectmode_flush(em);
+ BM_select_history_validate(bm);
return OPERATOR_FINISHED;
}
diff --git a/source/blender/editors/mesh/editmesh_select.c b/source/blender/editors/mesh/editmesh_select.c
index f50ff45e83b..a1f1f6bd83f 100644
--- a/source/blender/editors/mesh/editmesh_select.c
+++ b/source/blender/editors/mesh/editmesh_select.c
@@ -1590,8 +1590,7 @@ void EDBM_selectmode_set(BMEditMesh *em)
}
if (em->bm->totfacesel) {
- efa = BM_iter_new(&iter, em->bm, BM_FACES_OF_MESH, NULL);
- for (; efa; efa = BM_iter_step(&iter)) {
+ BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
if (BM_elem_flag_test(efa, BM_ELEM_SELECT)) {
BM_face_select_set(em->bm, efa, true);
}
@@ -2427,9 +2426,6 @@ static void walker_deselect_nth(BMEditMesh *em, int nth, int offset, BMHeader *h
static void deselect_nth_active(BMEditMesh *em, BMVert **r_eve, BMEdge **r_eed, BMFace **r_efa)
{
- BMVert *v;
- BMEdge *e;
- BMFace *f;
BMIter iter;
BMElem *ele;
@@ -2440,7 +2436,7 @@ static void deselect_nth_active(BMEditMesh *em, BMVert **r_eve, BMEdge **r_eed,
EDBM_selectmode_flush(em);
ele = BM_mesh_active_elem_get(em->bm);
- if (ele) {
+ if (ele && BM_elem_flag_test(ele, BM_ELEM_SELECT)) {
switch (ele->head.htype) {
case BM_VERT:
*r_eve = (BMVert *)ele;
@@ -2455,6 +2451,7 @@ static void deselect_nth_active(BMEditMesh *em, BMVert **r_eve, BMEdge **r_eed,
}
if (em->selectmode & SCE_SELECT_VERTEX) {
+ BMVert *v;
BM_ITER_MESH (v, &iter, em->bm, BM_VERTS_OF_MESH) {
if (BM_elem_flag_test(v, BM_ELEM_SELECT)) {
*r_eve = v;
@@ -2463,6 +2460,7 @@ static void deselect_nth_active(BMEditMesh *em, BMVert **r_eve, BMEdge **r_eed,
}
}
else if (em->selectmode & SCE_SELECT_EDGE) {
+ BMEdge *e;
BM_ITER_MESH (e, &iter, em->bm, BM_EDGES_OF_MESH) {
if (BM_elem_flag_test(e, BM_ELEM_SELECT)) {
*r_eed = e;
@@ -2471,8 +2469,8 @@ static void deselect_nth_active(BMEditMesh *em, BMVert **r_eve, BMEdge **r_eed,
}
}
else if (em->selectmode & SCE_SELECT_FACE) {
- f = BM_mesh_active_face_get(em->bm, true, false);
- if (f) {
+ BMFace *f = BM_mesh_active_face_get(em->bm, true, false);
+ if (f && BM_elem_flag_test(f, BM_ELEM_SELECT)) {
*r_efa = f;
return;
}
@@ -2619,7 +2617,7 @@ static int edbm_select_linked_flat_faces_exec(bContext *C, wmOperator *op)
BMLoop *l, *l2;
const float angle_limit = RNA_float_get(op->ptr, "sharpness");
- BM_mesh_elem_hflag_disable_all(bm, BM_VERT, BM_ELEM_TAG, false);
+ BM_mesh_elem_hflag_disable_all(bm, BM_FACE, BM_ELEM_TAG, false);
BM_ITER_MESH (f, &iter, bm, BM_FACES_OF_MESH) {
@@ -3076,10 +3074,10 @@ void MESH_OT_region_to_loop(wmOperatorType *ot)
static int loop_find_region(BMLoop *l, int flag,
SmallHash *fhash, BMFace ***region_out)
{
- BLI_array_declare(region);
- BLI_array_declare(stack);
BMFace **region = NULL;
BMFace **stack = NULL;
+ BLI_array_declare(region);
+ BLI_array_declare(stack);
BMFace *f;
BLI_array_append(stack, l->f);
diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c
index bf9dd03f170..4610bb89ae4 100644
--- a/source/blender/editors/mesh/editmesh_tools.c
+++ b/source/blender/editors/mesh/editmesh_tools.c
@@ -428,8 +428,9 @@ static int edbm_add_edge_face__smooth_get(BMesh *bm)
* 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 *))
+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)(const BMEdge *))
{
BMIter iter;
BMEdge *e_iter;
@@ -635,7 +636,7 @@ void MESH_OT_edge_face_add(wmOperatorType *ot)
/* ************************* SEAMS AND EDGES **************** */
-static int edbm_mark_seam(bContext *C, wmOperator *op)
+static int edbm_mark_seam_exec(bContext *C, wmOperator *op)
{
Scene *scene = CTX_data_scene(C);
Object *obedit = CTX_data_edit_object(C);
@@ -681,7 +682,7 @@ void MESH_OT_mark_seam(wmOperatorType *ot)
ot->description = "(Un)mark selected edges as a seam";
/* api callbacks */
- ot->exec = edbm_mark_seam;
+ ot->exec = edbm_mark_seam_exec;
ot->poll = ED_operator_editmesh;
/* flags */
@@ -690,7 +691,7 @@ void MESH_OT_mark_seam(wmOperatorType *ot)
RNA_def_boolean(ot->srna, "clear", 0, "Clear", "");
}
-static int edbm_mark_sharp(bContext *C, wmOperator *op)
+static int edbm_mark_sharp_exec(bContext *C, wmOperator *op)
{
Object *obedit = CTX_data_edit_object(C);
Mesh *me = ((Mesh *)obedit->data);
@@ -735,7 +736,7 @@ void MESH_OT_mark_sharp(wmOperatorType *ot)
ot->description = "(Un)mark selected edges as sharp";
/* api callbacks */
- ot->exec = edbm_mark_sharp;
+ ot->exec = edbm_mark_sharp_exec;
ot->poll = ED_operator_editmesh;
/* flags */
@@ -745,7 +746,7 @@ void MESH_OT_mark_sharp(wmOperatorType *ot)
}
-static int edbm_vert_connect(bContext *C, wmOperator *op)
+static int edbm_vert_connect_exec(bContext *C, wmOperator *op)
{
Object *obedit = CTX_data_edit_object(C);
BMEditMesh *em = BKE_editmesh_from_object(obedit);
@@ -795,33 +796,79 @@ void MESH_OT_vert_connect(wmOperatorType *ot)
ot->description = "Connect 2 vertices of a face by an edge, splitting the face in two";
/* api callbacks */
- ot->exec = edbm_vert_connect;
+ ot->exec = edbm_vert_connect_exec;
ot->poll = ED_operator_editmesh;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
-static int edbm_edge_split_exec(bContext *C, wmOperator *op)
+
+static int edbm_vert_connect_nonplaner_exec(bContext *C, wmOperator *op)
{
Object *obedit = CTX_data_edit_object(C);
BMEditMesh *em = BKE_editmesh_from_object(obedit);
- BMesh *bm = em->bm;
- BMOperator bmop;
- int len = 0;
-
- if (!EDBM_op_init(em, &bmop, op, "split_edges edges=%he", BM_ELEM_SELECT)) {
+
+ const float angle_limit = RNA_float_get(op->ptr, "angle_limit");
+
+ if (!EDBM_op_call_and_selectf(
+ em, op,
+ "faces.out", true,
+ "connect_verts_nonplanar faces=%hf angle_limit=%f",
+ BM_ELEM_SELECT, angle_limit))
+ {
return OPERATOR_CANCELLED;
}
- BMO_op_exec(bm, &bmop);
- len = BMO_slot_get(bmop.slots_out, "edges.out")->len;
- if (!EDBM_op_finish(em, &bmop, op, true)) {
+
+
+ EDBM_update_generic(em, true, true);
+ return OPERATOR_FINISHED;
+}
+
+void MESH_OT_vert_connect_nonplanar(wmOperatorType *ot)
+{
+ PropertyRNA *prop;
+
+ /* identifiers */
+ ot->name = "Split Non-Planar Faces";
+ ot->idname = "MESH_OT_vert_connect_nonplanar";
+ ot->description = "Split non-planar faces that exceed the angle threshold";
+
+ /* api callbacks */
+ ot->exec = edbm_vert_connect_nonplaner_exec;
+ ot->poll = ED_operator_editmesh;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+
+ /* props */
+ prop = RNA_def_float_rotation(ot->srna, "angle_limit", 0, NULL, 0.0f, DEG2RADF(180.0f),
+ "Max Angle", "Angle limit", 0.0f, DEG2RADF(180.0f));
+ RNA_def_property_float_default(prop, DEG2RADF(5.0f));
+}
+
+
+static int edbm_edge_split_exec(bContext *C, wmOperator *op)
+{
+ Object *obedit = CTX_data_edit_object(C);
+ BMEditMesh *em = BKE_editmesh_from_object(obedit);
+
+ if (!EDBM_op_call_and_selectf(
+ em, op,
+ "edges.out", false,
+ "split_edges edges=%he",
+ BM_ELEM_SELECT))
+ {
return OPERATOR_CANCELLED;
}
+ if (em->selectmode == SCE_SELECT_FACE) {
+ EDBM_select_flush(em);
+ }
+
EDBM_update_generic(em, true, true);
- return len ? OPERATOR_FINISHED : OPERATOR_CANCELLED;
+ return OPERATOR_FINISHED;
}
void MESH_OT_edge_split(wmOperatorType *ot)
@@ -2277,7 +2324,7 @@ static int edbm_knife_cut_exec(bContext *C, wmOperator *op)
/* store percentage of edge cut for KNIFE_EXACT here.*/
slot_edge_percents = BMO_slot_get(bmop.slots_in, "edge_percents");
- for (be = BM_iter_new(&iter, bm, BM_EDGES_OF_MESH, NULL); be; be = BM_iter_step(&iter)) {
+ BM_ITER_MESH (be, &iter, bm, BM_EDGES_OF_MESH) {
bool is_cut = false;
if (BM_elem_flag_test(be, BM_ELEM_SELECT)) {
const float *sco_a = screen_vert_coords[BM_elem_index_get(be->v1)];
@@ -2752,15 +2799,56 @@ void MESH_OT_fill_grid(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
+static int edbm_fill_holes_exec(bContext *C, wmOperator *op)
+{
+ Object *obedit = CTX_data_edit_object(C);
+ BMEditMesh *em = BKE_editmesh_from_object(obedit);
+ const int sides = RNA_int_get(op->ptr, "sides");
+
+ if (!EDBM_op_call_and_selectf(
+ em, op,
+ "faces.out", true,
+ "holes_fill edges=%he sides=%i",
+ BM_ELEM_SELECT, sides))
+ {
+ return OPERATOR_CANCELLED;
+ }
+
+ EDBM_update_generic(em, true, true);
+
+ return OPERATOR_FINISHED;
+
+}
+
+void MESH_OT_fill_holes(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Fill Holes";
+ ot->idname = "MESH_OT_fill_holes";
+ ot->description = "Fill in holes (boundary edge loops)";
+ /* api callbacks */
+ ot->exec = edbm_fill_holes_exec;
+ ot->poll = ED_operator_editmesh;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+
+ RNA_def_int(ot->srna, "sides", 4, 0, INT_MAX, "Sides", "Number of sides (zero disables)", 0, 100);
+}
static int edbm_beautify_fill_exec(bContext *C, wmOperator *op)
{
Object *obedit = CTX_data_edit_object(C);
BMEditMesh *em = BKE_editmesh_from_object(obedit);
- if (!EDBM_op_callf(em, op, "beautify_fill faces=%hf edges=ae", BM_ELEM_SELECT))
+ if (!EDBM_op_call_and_selectf(
+ em, op, "geom.out", true,
+ "beautify_fill faces=%hf edges=ae",
+ BM_ELEM_SELECT))
+ {
return OPERATOR_CANCELLED;
+ }
EDBM_update_generic(em, true, true);
@@ -2855,11 +2943,14 @@ static int edbm_quads_convert_to_tris_exec(bContext *C, wmOperator *op)
EDBM_op_init(em, &bmop, op, "triangulate faces=%hf use_beauty=%b", BM_ELEM_SELECT, use_beauty);
BMO_op_exec(em->bm, &bmop);
+ BMO_slot_buffer_hflag_enable(em->bm, bmop.slots_out, "faces.out", BM_FACE, BM_ELEM_SELECT, true);
+
/* now call beauty fill */
if (use_beauty) {
- EDBM_op_callf(em, op,
- "beautify_fill faces=%S edges=%S",
- &bmop, "faces.out", &bmop, "edges.out");
+ EDBM_op_call_and_selectf(
+ em, op, "geom.out", true,
+ "beautify_fill faces=%S edges=%S",
+ &bmop, "faces.out", &bmop, "edges.out");
}
if (!EDBM_op_finish(em, &bmop, op, true)) {
@@ -2901,9 +2992,11 @@ static int edbm_tris_convert_to_quads_exec(bContext *C, wmOperator *op)
dovcols = RNA_boolean_get(op->ptr, "vcols");
domaterials = RNA_boolean_get(op->ptr, "materials");
- if (!EDBM_op_callf(em, op,
- "join_triangles faces=%hf limit=%f cmp_sharp=%b cmp_uvs=%b cmp_vcols=%b cmp_materials=%b",
- BM_ELEM_SELECT, limit, dosharp, douvs, dovcols, domaterials))
+ if (!EDBM_op_call_and_selectf(
+ em, op,
+ "faces.out", true,
+ "join_triangles faces=%hf limit=%f cmp_sharp=%b cmp_uvs=%b cmp_vcols=%b cmp_materials=%b",
+ BM_ELEM_SELECT, limit, dosharp, douvs, dovcols, domaterials))
{
return OPERATOR_CANCELLED;
}
@@ -2947,6 +3040,17 @@ void MESH_OT_tris_convert_to_quads(wmOperatorType *ot)
/* -------------------------------------------------------------------- */
/* Dissolve */
+static void edbm_dissolve_prop__use_verts(wmOperatorType *ot)
+{
+ RNA_def_boolean(ot->srna, "use_verts", 0, "Dissolve Verts",
+ "Dissolve remaining vertices");
+}
+static void edbm_dissolve_prop__use_face_split(wmOperatorType *ot)
+{
+ RNA_def_boolean(ot->srna, "use_face_split", 0, "Face Split",
+ "Split off face corners to maintain surrounding geometry");
+}
+
static int edbm_dissolve_verts_exec(bContext *C, wmOperator *op)
{
Object *obedit = CTX_data_edit_object(C);
@@ -2976,8 +3080,7 @@ void MESH_OT_dissolve_verts(wmOperatorType *ot)
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
- RNA_def_boolean(ot->srna, "use_face_split", 0, "Face Split",
- "Split off face corners to maintain surrounding geometry");
+ edbm_dissolve_prop__use_face_split(ot);
}
static int edbm_dissolve_edges_exec(bContext *C, wmOperator *op)
@@ -3014,9 +3117,8 @@ void MESH_OT_dissolve_edges(wmOperatorType *ot)
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
- RNA_def_boolean(ot->srna, "use_verts", 0, "Dissolve Verts", "Dissolve remaining vertices");
- RNA_def_boolean(ot->srna, "use_face_split", 0, "Face Split",
- "Split off face corners to maintain surrounding geometry");
+ edbm_dissolve_prop__use_verts(ot);
+ edbm_dissolve_prop__use_face_split(ot);
}
static int edbm_dissolve_faces_exec(bContext *C, wmOperator *op)
@@ -3026,8 +3128,14 @@ static int edbm_dissolve_faces_exec(bContext *C, wmOperator *op)
const bool use_verts = RNA_boolean_get(op->ptr, "use_verts");
- if (!EDBM_op_callf(em, op, "dissolve_faces faces=%hf use_verts=%b", BM_ELEM_SELECT, use_verts))
+ if (!EDBM_op_call_and_selectf(
+ em, op,
+ "region.out", true,
+ "dissolve_faces faces=%hf use_verts=%b",
+ BM_ELEM_SELECT, use_verts))
+ {
return OPERATOR_CANCELLED;
+ }
EDBM_update_generic(em, true, true);
@@ -3048,10 +3156,44 @@ void MESH_OT_dissolve_faces(wmOperatorType *ot)
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
- RNA_def_boolean(ot->srna, "use_verts", 0, "Dissolve Verts", "Dissolve remaining vertices");
+ edbm_dissolve_prop__use_verts(ot);
}
+static int edbm_dissolve_mode_exec(bContext *C, wmOperator *op)
+{
+ Object *obedit = CTX_data_edit_object(C);
+ BMEditMesh *em = BKE_editmesh_from_object(obedit);
+
+ if (em->selectmode & SCE_SELECT_VERTEX) {
+ return edbm_dissolve_verts_exec(C, op);
+ }
+ else if (em->selectmode & SCE_SELECT_EDGE) {
+ return edbm_dissolve_edges_exec(C, op);
+ }
+ else {
+ return edbm_dissolve_faces_exec(C, op);
+ }
+}
+
+void MESH_OT_dissolve_mode(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Dissolve Selection";
+ ot->description = "Dissolve geometry based on the selection mode";
+ ot->idname = "MESH_OT_dissolve_mode";
+
+ /* api callbacks */
+ ot->exec = edbm_dissolve_mode_exec;
+ ot->poll = ED_operator_editmesh;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+
+ edbm_dissolve_prop__use_verts(ot);
+ edbm_dissolve_prop__use_face_split(ot);
+}
+
static int edbm_dissolve_limited_exec(bContext *C, wmOperator *op)
{
Object *obedit = CTX_data_edit_object(C);
@@ -3094,12 +3236,10 @@ static int edbm_dissolve_limited_exec(bContext *C, wmOperator *op)
dissolve_flag = BM_ELEM_SELECT;
}
- if (!EDBM_op_callf(em, op,
- "dissolve_limit edges=%he verts=%hv angle_limit=%f use_dissolve_boundaries=%b delimit=%i",
- dissolve_flag, dissolve_flag, angle_limit, use_dissolve_boundaries, delimit))
- {
- return OPERATOR_CANCELLED;
- }
+ EDBM_op_call_and_selectf(
+ em, op, "region.out", true,
+ "dissolve_limit edges=%he verts=%hv angle_limit=%f use_dissolve_boundaries=%b delimit=%i",
+ dissolve_flag, dissolve_flag, angle_limit, use_dissolve_boundaries, delimit);
EDBM_update_generic(em, true, true);
@@ -3147,7 +3287,7 @@ static int edbm_delete_edgeloop_exec(bContext *C, wmOperator *op)
BM_mesh_elem_hflag_disable_all(em->bm, BM_FACE, BM_ELEM_TAG, false);
BM_ITER_MESH (e, &iter, em->bm, BM_EDGES_OF_MESH) {
- if (BM_elem_flag_test(e, BM_ELEM_SELECT)) {
+ if (BM_elem_flag_test(e, BM_ELEM_SELECT) && e->l) {
BMLoop *l_iter = e->l;
do {
BM_elem_flag_enable(l_iter->f, BM_ELEM_TAG);
@@ -3936,6 +4076,7 @@ static int edbm_bridge_edge_loops_exec(bContext *C, wmOperator *op)
const bool use_cyclic = (type == 1);
const bool use_merge = RNA_boolean_get(op->ptr, "use_merge");
const float merge_factor = RNA_float_get(op->ptr, "merge_factor");
+ const int twist_offset = RNA_int_get(op->ptr, "twist_offset");
const bool use_faces = (em->bm->totfacesel != 0);
char edge_hflag;
@@ -3963,8 +4104,8 @@ static int edbm_bridge_edge_loops_exec(bContext *C, wmOperator *op)
}
EDBM_op_init(em, &bmop, op,
- "bridge_loops edges=%he use_pairs=%b use_cyclic=%b use_merge=%b merge_factor=%f",
- edge_hflag, use_pairs, use_cyclic, use_merge, merge_factor);
+ "bridge_loops edges=%he use_pairs=%b use_cyclic=%b use_merge=%b merge_factor=%f twist_offset=%i",
+ edge_hflag, use_pairs, use_cyclic, use_merge, merge_factor, twist_offset);
BMO_op_exec(em->bm, &bmop);
@@ -3991,14 +4132,23 @@ static int edbm_bridge_edge_loops_exec(bContext *C, wmOperator *op)
mesh_operator_edgering_props_get(op, &op_props);
if (op_props.cuts) {
+ BMOperator bmop_subd;
/* we only need face normals updated */
EDBM_mesh_normals_update(em);
- BMO_op_callf(em->bm, BMO_FLAG_DEFAULTS,
- "subdivide_edgering edges=%S interp_mode=%i cuts=%i smooth=%f "
- "profile_shape=%i profile_shape_factor=%f",
- &bmop, "edges.out", op_props.interp_mode, op_props.cuts, op_props.smooth,
- op_props.profile_shape, op_props.profile_shape_factor);
+ BMO_op_initf(
+ em->bm, &bmop_subd, op->flag,
+ "subdivide_edgering edges=%S interp_mode=%i cuts=%i smooth=%f "
+ "profile_shape=%i profile_shape_factor=%f",
+ &bmop, "edges.out", op_props.interp_mode, op_props.cuts, op_props.smooth,
+ op_props.profile_shape, op_props.profile_shape_factor
+ );
+ BMO_op_exec(em->bm, &bmop_subd);
+
+ BMO_slot_buffer_hflag_enable(em->bm, bmop_subd.slots_out, "faces.out", BM_FACE, BM_ELEM_SELECT, true);
+
+ BMO_op_finish(em->bm, &bmop_subd);
+
}
}
}
@@ -4044,6 +4194,7 @@ void MESH_OT_bridge_edge_loops(wmOperatorType *ot)
RNA_def_boolean(ot->srna, "use_merge", false, "Merge", "Merge rather than creating faces");
RNA_def_float(ot->srna, "merge_factor", 0.5f, 0.0f, 1.0f, "Merge Factor", "", 0.0f, 1.0f);
+ RNA_def_int(ot->srna, "twist_offset", 0, -1000, 1000, "Twist", "Twist offset for closed loops", -1000, 1000);
mesh_operator_edgering_props(ot, 0);
}
@@ -4382,7 +4533,7 @@ void MESH_OT_symmetry_snap(struct wmOperatorType *ot)
#ifdef WITH_FREESTYLE
-static int edbm_mark_freestyle_edge(bContext *C, wmOperator *op)
+static int edbm_mark_freestyle_edge_exec(bContext *C, wmOperator *op)
{
Object *obedit = CTX_data_edit_object(C);
Mesh *me = (Mesh *)obedit->data;
@@ -4435,7 +4586,7 @@ void MESH_OT_mark_freestyle_edge(wmOperatorType *ot)
ot->idname = "MESH_OT_mark_freestyle_edge";
/* api callbacks */
- ot->exec = edbm_mark_freestyle_edge;
+ ot->exec = edbm_mark_freestyle_edge_exec;
ot->poll = ED_operator_editmesh;
/* flags */
diff --git a/source/blender/editors/mesh/editmesh_utils.c b/source/blender/editors/mesh/editmesh_utils.c
index f64ea569100..46cab3b4416 100644
--- a/source/blender/editors/mesh/editmesh_utils.c
+++ b/source/blender/editors/mesh/editmesh_utils.c
@@ -35,7 +35,7 @@
#include "DNA_object_types.h"
#include "BLI_math.h"
-#include "BLI_array.h"
+#include "BLI_alloca.h"
#include "BKE_DerivedMesh.h"
#include "BKE_context.h"
@@ -270,7 +270,9 @@ bool EDBM_op_callf(BMEditMesh *em, wmOperator *op, const char *fmt, ...)
return EDBM_op_finish(em, &bmop, op, true);
}
-bool EDBM_op_call_and_selectf(BMEditMesh *em, wmOperator *op, const char *select_slot_out, const char *fmt, ...)
+bool EDBM_op_call_and_selectf(BMEditMesh *em, wmOperator *op,
+ const char *select_slot_out, const bool select_extend,
+ const char *fmt, ...)
{
BMOpSlot *slot_select_out;
BMesh *bm = em->bm;
@@ -294,8 +296,11 @@ bool EDBM_op_call_and_selectf(BMEditMesh *em, wmOperator *op, const char *select
slot_select_out = BMO_slot_get(bmop.slots_out, select_slot_out);
hflag = slot_select_out->slot_subtype.elem & BM_ALL_NOLOOP;
+ BLI_assert(hflag != 0);
- BM_mesh_elem_hflag_disable_all(em->bm, BM_VERT | BM_EDGE | BM_FACE, BM_ELEM_SELECT, false);
+ if (select_extend == false) {
+ BM_mesh_elem_hflag_disable_all(em->bm, BM_VERT | BM_EDGE | BM_FACE, BM_ELEM_SELECT, false);
+ }
BMO_slot_buffer_hflag_enable(em->bm, bmop.slots_out, select_slot_out, hflag, BM_ELEM_SELECT, true);
@@ -1478,7 +1483,7 @@ static BMFace *edge_ray_cast(struct BMBVHTree *tree, const float co[3], const fl
{
BMFace *f = BKE_bmbvh_ray_cast(tree, co, dir, NULL, r_hitout, NULL);
- if (f && BM_edge_in_face(f, e))
+ if (f && BM_edge_in_face(e, f))
return NULL;
return f;
diff --git a/source/blender/editors/mesh/mesh_data.c b/source/blender/editors/mesh/mesh_data.c
index 52a8ccc4aab..e8cbf0926d4 100644
--- a/source/blender/editors/mesh/mesh_data.c
+++ b/source/blender/editors/mesh/mesh_data.c
@@ -37,8 +37,8 @@
#include "DNA_view3d_types.h"
#include "BLI_utildefines.h"
+#include "BLI_alloca.h"
#include "BLI_path_util.h"
-#include "BLI_array.h"
#include "BLI_math.h"
#include "BKE_context.h"
diff --git a/source/blender/editors/mesh/mesh_intern.h b/source/blender/editors/mesh/mesh_intern.h
index a4706618765..9dcb38b9f87 100644
--- a/source/blender/editors/mesh/mesh_intern.h
+++ b/source/blender/editors/mesh/mesh_intern.h
@@ -59,7 +59,8 @@ struct LinkNode;
/* Calls a bmesh op, reporting errors to the user, etc */
bool EDBM_op_callf(struct BMEditMesh *em, struct wmOperator *op, const char *fmt, ...);
bool EDBM_op_call_and_selectf(struct BMEditMesh *em, struct wmOperator *op,
- const char *selectslot, const char *fmt, ...);
+ const char *select_slot, const bool select_replace,
+ const char *fmt, ...);
/* Same as above, but doesn't report errors.*/
bool EDBM_op_call_silentf(struct BMEditMesh *em, const char *fmt, ...);
@@ -168,6 +169,7 @@ void MESH_OT_normals_make_consistent(struct wmOperatorType *ot);
void MESH_OT_vertices_smooth(struct wmOperatorType *ot);
void MESH_OT_vertices_smooth_laplacian(struct wmOperatorType *ot);
void MESH_OT_vert_connect(struct wmOperatorType *ot);
+void MESH_OT_vert_connect_nonplanar(struct wmOperatorType *ot);
void MESH_OT_edge_split(struct wmOperatorType *ot);
void MESH_OT_bridge_edge_loops(struct wmOperatorType *ot);
void MESH_OT_wireframe(struct wmOperatorType *ot);
@@ -198,12 +200,14 @@ void MESH_OT_knife_cut(struct wmOperatorType *ot);
void MESH_OT_separate(struct wmOperatorType *ot);
void MESH_OT_fill(struct wmOperatorType *ot);
void MESH_OT_fill_grid(struct wmOperatorType *ot);
+void MESH_OT_fill_holes(struct wmOperatorType *ot);
void MESH_OT_beautify_fill(struct wmOperatorType *ot);
void MESH_OT_quads_convert_to_tris(struct wmOperatorType *ot);
void MESH_OT_tris_convert_to_quads(struct wmOperatorType *ot);
void MESH_OT_dissolve_verts(struct wmOperatorType *ot);
void MESH_OT_dissolve_edges(struct wmOperatorType *ot);
void MESH_OT_dissolve_faces(struct wmOperatorType *ot);
+void MESH_OT_dissolve_mode(struct wmOperatorType *ot);
void MESH_OT_dissolve_limited(struct wmOperatorType *ot);
void MESH_OT_delete_edgeloop(struct wmOperatorType *ot);
void MESH_OT_edge_face_add(struct wmOperatorType *ot);
diff --git a/source/blender/editors/mesh/mesh_navmesh.c b/source/blender/editors/mesh/mesh_navmesh.c
index 3d8718ef887..66e577975b6 100644
--- a/source/blender/editors/mesh/mesh_navmesh.c
+++ b/source/blender/editors/mesh/mesh_navmesh.c
@@ -461,7 +461,7 @@ static int navmesh_create_exec(bContext *C, wmOperator *op)
unsigned int lay = 0;
int nverts = 0, ntris = 0;
- int *tris = 0;
+ int *tris = NULL;
float *verts = NULL;
createVertsTrisData(C, obs, &nverts, &verts, &ntris, &tris, &lay);
diff --git a/source/blender/editors/mesh/mesh_ops.c b/source/blender/editors/mesh/mesh_ops.c
index d6dff32f097..fb0ec4e5768 100644
--- a/source/blender/editors/mesh/mesh_ops.c
+++ b/source/blender/editors/mesh/mesh_ops.c
@@ -102,12 +102,14 @@ void ED_operatortypes_mesh(void)
WM_operatortype_append(MESH_OT_fill);
WM_operatortype_append(MESH_OT_fill_grid);
+ WM_operatortype_append(MESH_OT_fill_holes);
WM_operatortype_append(MESH_OT_beautify_fill);
WM_operatortype_append(MESH_OT_quads_convert_to_tris);
WM_operatortype_append(MESH_OT_tris_convert_to_quads);
WM_operatortype_append(MESH_OT_dissolve_verts);
WM_operatortype_append(MESH_OT_dissolve_edges);
WM_operatortype_append(MESH_OT_dissolve_faces);
+ WM_operatortype_append(MESH_OT_dissolve_mode);
WM_operatortype_append(MESH_OT_dissolve_limited);
WM_operatortype_append(MESH_OT_delete_edgeloop);
WM_operatortype_append(MESH_OT_faces_shade_smooth);
@@ -156,6 +158,7 @@ void ED_operatortypes_mesh(void)
WM_operatortype_append(MESH_OT_solidify);
WM_operatortype_append(MESH_OT_select_nth);
WM_operatortype_append(MESH_OT_vert_connect);
+ WM_operatortype_append(MESH_OT_vert_connect_nonplanar);
WM_operatortype_append(MESH_OT_knife_tool);
WM_operatortype_append(MESH_OT_knife_project);
@@ -383,6 +386,9 @@ void ED_keymap_mesh(wmKeyConfig *keyconf)
WM_keymap_add_menu(keymap, "VIEW3D_MT_edit_mesh_delete", XKEY, KM_PRESS, 0, 0);
WM_keymap_add_menu(keymap, "VIEW3D_MT_edit_mesh_delete", DELKEY, KM_PRESS, 0, 0);
+
+ WM_keymap_add_item(keymap, "MESH_OT_dissolve_mode", XKEY, KM_PRESS, KM_CTRL, 0);
+ WM_keymap_add_item(keymap, "MESH_OT_dissolve_mode", DELKEY, KM_PRESS, KM_CTRL, 0);
kmi = WM_keymap_add_item(keymap, "MESH_OT_knife_tool", KKEY, KM_PRESS, 0, 0);
RNA_boolean_set(kmi->ptr, "use_occlude_geometry", true);
diff --git a/source/blender/editors/mesh/meshtools.c b/source/blender/editors/mesh/meshtools.c
index ed05d2a01a5..d012a8ac656 100644
--- a/source/blender/editors/mesh/meshtools.c
+++ b/source/blender/editors/mesh/meshtools.c
@@ -1336,7 +1336,7 @@ bool ED_mesh_pick_vert(bContext *C, Object *ob, const int mval[2], unsigned int
const float mval_f[2] = {(float)mval[0],
(float)mval[1]};
- VertPickData data = {0};
+ VertPickData data = {NULL};
ED_view3d_init_mats_rv3d(ob, rv3d);
@@ -1351,7 +1351,7 @@ bool ED_mesh_pick_vert(bContext *C, Object *ob, const int mval[2], unsigned int
data.len_best = FLT_MAX;
data.v_idx_best = -1;
- dm->foreachMappedVert(dm, ed_mesh_pick_vert__mapFunc, &data);
+ dm->foreachMappedVert(dm, ed_mesh_pick_vert__mapFunc, &data, DM_FOREACH_NOP);
dm->release(dm);
diff --git a/source/blender/editors/object/object_add.c b/source/blender/editors/object/object_add.c
index 5b100d7b6c2..ce61b4fce50 100644
--- a/source/blender/editors/object/object_add.c
+++ b/source/blender/editors/object/object_add.c
@@ -1431,7 +1431,7 @@ static int convert_exec(bContext *C, wmOperator *op)
{
Main *bmain = CTX_data_main(C);
Scene *scene = CTX_data_scene(C);
- Base *basen = NULL, *basact = NULL, *basedel = NULL;
+ Base *basen = NULL, *basact = NULL;
Object *ob, *ob1, *newob, *obact = CTX_data_active_object(C);
DerivedMesh *dm;
Curve *cu;
@@ -1687,14 +1687,6 @@ static int convert_exec(bContext *C, wmOperator *op)
DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
((ID *)ob->data)->flag &= ~LIB_DOIT; /* flag not to convert this datablock again */
}
-
- /* delete original if needed */
- if (basedel) {
- if (!keep_original)
- ED_base_object_free_and_unlink(bmain, scene, basedel);
-
- basedel = NULL;
- }
}
CTX_DATA_END;
diff --git a/source/blender/editors/object/object_bake.c b/source/blender/editors/object/object_bake.c
index 3f1ceb7327c..8b674cf1e50 100644
--- a/source/blender/editors/object/object_bake.c
+++ b/source/blender/editors/object/object_bake.c
@@ -107,13 +107,14 @@ typedef struct {
int threads;
} MultiresBakeJob;
-static int multiresbake_check(bContext *C, wmOperator *op)
+static bool multiresbake_check(bContext *C, wmOperator *op)
{
Scene *scene = CTX_data_scene(C);
Object *ob;
Mesh *me;
MultiresModifierData *mmd;
- int ok = 1, a;
+ bool ok = true;
+ int a;
CTX_DATA_BEGIN (C, Base *, base, selected_editable_bases)
{
@@ -122,7 +123,7 @@ static int multiresbake_check(bContext *C, wmOperator *op)
if (ob->type != OB_MESH) {
BKE_report(op->reports, RPT_ERROR, "Baking of multires data only works with an active mesh object");
- ok = 0;
+ ok = false;
break;
}
@@ -137,12 +138,12 @@ static int multiresbake_check(bContext *C, wmOperator *op)
for (md = (ModifierData *)mmd->modifier.next; md && ok; md = md->next) {
if (modifier_isEnabled(scene, md, eModifierMode_Realtime)) {
- ok = 0;
+ ok = false;
}
}
}
else {
- ok = 0;
+ ok = false;
}
if (!ok) {
@@ -153,14 +154,14 @@ static int multiresbake_check(bContext *C, wmOperator *op)
if (mmd->lvl == 0) {
BKE_report(op->reports, RPT_ERROR, "Multires data baking is not supported for preview subdivision level 0");
-
+ ok = false;
break;
}
if (!me->mtpoly) {
BKE_report(op->reports, RPT_ERROR, "Mesh should be unwrapped before multires data baking");
- ok = 0;
+ ok = false;
}
else {
a = me->totpoly;
@@ -170,7 +171,7 @@ static int multiresbake_check(bContext *C, wmOperator *op)
if (!ima) {
BKE_report(op->reports, RPT_ERROR, "You should have active texture to use multires baker");
- ok = 0;
+ ok = false;
}
else {
ImBuf *ibuf = BKE_image_acquire_ibuf(ima, NULL, NULL);
@@ -178,14 +179,14 @@ static int multiresbake_check(bContext *C, wmOperator *op)
if (!ibuf) {
BKE_report(op->reports, RPT_ERROR, "Baking should happen to image with image buffer");
- ok = 0;
+ ok = false;
}
else {
if (ibuf->rect == NULL && ibuf->rect_float == NULL)
- ok = 0;
+ ok = false;
if (ibuf->rect_float && !(ibuf->channels == 0 || ibuf->channels == 4))
- ok = 0;
+ ok = false;
if (!ok)
BKE_report(op->reports, RPT_ERROR, "Baking to unsupported image type");
diff --git a/source/blender/editors/object/object_edit.c b/source/blender/editors/object/object_edit.c
index 9eaaf8fe1db..7f7a0777bbf 100644
--- a/source/blender/editors/object/object_edit.c
+++ b/source/blender/editors/object/object_edit.c
@@ -1347,7 +1347,7 @@ static int shade_smooth_exec(bContext *C, wmOperator *op)
static int shade_poll(bContext *C)
{
- return (ED_operator_object_active_editable(C) && !ED_operator_editmesh(C));
+ return (CTX_data_edit_object(C) == NULL);
}
void OBJECT_OT_shade_flat(wmOperatorType *ot)
@@ -1610,7 +1610,7 @@ void ED_object_toggle_modes(bContext *C, int mode)
/************************ Game Properties ***********************/
-static int game_property_new(bContext *C, wmOperator *op)
+static int game_property_new_exec(bContext *C, wmOperator *op)
{
Object *ob = CTX_data_active_object(C);
bProperty *prop;
@@ -1640,7 +1640,7 @@ void OBJECT_OT_game_property_new(wmOperatorType *ot)
ot->idname = "OBJECT_OT_game_property_new";
/* api callbacks */
- ot->exec = game_property_new;
+ ot->exec = game_property_new_exec;
ot->poll = ED_operator_object_active_editable;
/* flags */
@@ -1650,7 +1650,7 @@ void OBJECT_OT_game_property_new(wmOperatorType *ot)
RNA_def_string(ot->srna, "name", "", MAX_NAME, "Name", "Name of the game property to add");
}
-static int game_property_remove(bContext *C, wmOperator *op)
+static int game_property_remove_exec(bContext *C, wmOperator *op)
{
Object *ob = CTX_data_active_object(C);
bProperty *prop;
@@ -1681,7 +1681,7 @@ void OBJECT_OT_game_property_remove(wmOperatorType *ot)
ot->idname = "OBJECT_OT_game_property_remove";
/* api callbacks */
- ot->exec = game_property_remove;
+ ot->exec = game_property_remove_exec;
ot->poll = ED_operator_object_active_editable;
/* flags */
diff --git a/source/blender/editors/object/object_group.c b/source/blender/editors/object/object_group.c
index f48e4ff5056..1f52346222c 100644
--- a/source/blender/editors/object/object_group.c
+++ b/source/blender/editors/object/object_group.c
@@ -61,6 +61,49 @@
/********************* 3d view operators ***********************/
+static bool group_link_early_exit_check(Group *group, Object *object)
+{
+ GroupObject *group_object;
+
+ for (group_object = group->gobject.first; group_object; group_object = group_object->next) {
+ if (group_object->ob == object) {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+static bool check_group_contains_object_recursive(Group *group, Object *object)
+{
+ GroupObject *group_object;
+
+ if ((group->id.flag & LIB_DOIT) == 0) {
+ /* Cycle already exists in groups, let's prevent further crappyness */
+ return true;
+ }
+
+ group->id.flag &= ~LIB_DOIT;
+
+ for (group_object = group->gobject.first; group_object; group_object = group_object->next) {
+ Object *current_object = group_object->ob;
+
+ if (current_object == object) {
+ return true;
+ }
+
+ if (current_object->dup_group) {
+ if (check_group_contains_object_recursive(current_object->dup_group, object)) {
+ return true;
+ }
+ }
+ }
+
+ group->id.flag |= LIB_DOIT;
+
+ return false;
+}
+
/* can be called with C == NULL */
static EnumPropertyItem *group_object_active_itemf(bContext *C, PointerRNA *UNUSED(ptr), PropertyRNA *UNUSED(prop), int *free)
{
@@ -123,9 +166,15 @@ static int objects_add_active_exec(bContext *C, wmOperator *op)
/* now add all selected objects from the group */
if (group) {
+ /* for recursive check */
+ tag_main_lb(&bmain->group, TRUE);
+
CTX_DATA_BEGIN (C, Base *, base, selected_editable_bases)
{
- if (base->object->dup_group != group) {
+ if (group_link_early_exit_check(group, base->object))
+ continue;
+
+ if (base->object->dup_group != group && !check_group_contains_object_recursive(group, base->object)) {
BKE_group_object_add(group, base->object, scene, base);
}
else {
@@ -378,47 +427,6 @@ void OBJECT_OT_group_add(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
-static bool group_link_early_exit_check(Group *group, Object *object)
-{
- GroupObject *group_object;
-
- for (group_object = group->gobject.first; group_object; group_object = group_object->next) {
- if (group_object->ob == object) {
- return true;
- }
- }
-
- return false;
-}
-
-static bool check_group_contains_object_recursive(Group *group, Object *object)
-{
- GroupObject *group_object;
-
- if ((group->id.flag & LIB_DOIT) == 0) {
- /* Cycle already exists in groups, let's prevent further crappyness */
- return true;
- }
-
- group->id.flag &= ~LIB_DOIT;
-
- for (group_object = group->gobject.first; group_object; group_object = group_object->next) {
- Object *current_object = group_object->ob;
-
- if (current_object == object) {
- return true;
- }
-
- if (current_object->dup_group) {
- if (check_group_contains_object_recursive(current_object->dup_group, object)) {
- return true;
- }
- }
- }
-
- return false;
-}
-
static int group_link_exec(bContext *C, wmOperator *op)
{
Main *bmain = CTX_data_main(C);
diff --git a/source/blender/editors/object/object_hook.c b/source/blender/editors/object/object_hook.c
index c8baa0d84dc..5b20489c9cb 100644
--- a/source/blender/editors/object/object_hook.c
+++ b/source/blender/editors/object/object_hook.c
@@ -713,11 +713,11 @@ static int object_hook_reset_exec(bContext *C, wmOperator *op)
mul_m4_m4m4(mat, hmd->object->obmat, pchan->pose_mat);
invert_m4_m4(imat, mat);
- mul_serie_m4(hmd->parentinv, imat, ob->obmat, NULL, NULL, NULL, NULL, NULL, NULL);
+ mul_m4_m4m4(hmd->parentinv, imat, ob->obmat);
}
else {
invert_m4_m4(hmd->object->imat, hmd->object->obmat);
- mul_serie_m4(hmd->parentinv, hmd->object->imat, ob->obmat, NULL, NULL, NULL, NULL, NULL, NULL);
+ mul_m4_m4m4(hmd->parentinv, hmd->object->imat, ob->obmat);
}
}
diff --git a/source/blender/editors/object/object_lattice.c b/source/blender/editors/object/object_lattice.c
index 54e8d8e6599..a79b0607421 100644
--- a/source/blender/editors/object/object_lattice.c
+++ b/source/blender/editors/object/object_lattice.c
@@ -228,7 +228,7 @@ void LATTICE_OT_select_random(wmOperatorType *ot)
/************************** Select More/Less Operator *************************/
-static bool lattice_test_bitmap_uvw(Lattice *lt, BLI_bitmap selpoints, int u, int v, int w, const bool selected)
+static bool lattice_test_bitmap_uvw(Lattice *lt, BLI_bitmap *selpoints, int u, int v, int w, const bool selected)
{
if ((u < 0 || u >= lt->pntsu) ||
(v < 0 || v >= lt->pntsv) ||
@@ -252,7 +252,7 @@ static int lattice_select_more_less(bContext *C, const bool select)
BPoint *bp;
const int tot = lt->pntsu * lt->pntsv * lt->pntsw;
int i, w, u, v;
- BLI_bitmap selpoints;
+ BLI_bitmap *selpoints;
lt->actbp = LT_ACTBP_NONE;
diff --git a/source/blender/editors/object/object_modifier.c b/source/blender/editors/object/object_modifier.c
index b1f1f73f493..03d51fcbe82 100644
--- a/source/blender/editors/object/object_modifier.c
+++ b/source/blender/editors/object/object_modifier.c
@@ -873,9 +873,9 @@ static int modifier_remove_exec(bContext *C, wmOperator *op)
Scene *scene = CTX_data_scene(C);
Object *ob = ED_object_active_context(C);
ModifierData *md = edit_modifier_property_get(op, ob, 0);
- int mode_orig = ob ? ob->mode : 0;
+ int mode_orig = ob->mode;
- if (!ob || !md || !ED_object_modifier_remove(op->reports, bmain, ob, md))
+ if (!md || !ED_object_modifier_remove(op->reports, bmain, ob, md))
return OPERATOR_CANCELLED;
WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob);
@@ -919,7 +919,7 @@ static int modifier_move_up_exec(bContext *C, wmOperator *op)
Object *ob = ED_object_active_context(C);
ModifierData *md = edit_modifier_property_get(op, ob, 0);
- if (!ob || !md || !ED_object_modifier_move_up(op->reports, ob, md))
+ if (!md || !ED_object_modifier_move_up(op->reports, ob, md))
return OPERATOR_CANCELLED;
DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
@@ -958,7 +958,7 @@ static int modifier_move_down_exec(bContext *C, wmOperator *op)
Object *ob = ED_object_active_context(C);
ModifierData *md = edit_modifier_property_get(op, ob, 0);
- if (!ob || !md || !ED_object_modifier_move_down(op->reports, ob, md))
+ if (!md || !ED_object_modifier_move_down(op->reports, ob, md))
return OPERATOR_CANCELLED;
DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
@@ -999,7 +999,7 @@ static int modifier_apply_exec(bContext *C, wmOperator *op)
ModifierData *md = edit_modifier_property_get(op, ob, 0);
int apply_as = RNA_enum_get(op->ptr, "apply_as");
- if (!ob || !md || !ED_object_modifier_apply(op->reports, scene, ob, md, apply_as)) {
+ if (!md || !ED_object_modifier_apply(op->reports, scene, ob, md, apply_as)) {
return OPERATOR_CANCELLED;
}
@@ -1049,7 +1049,7 @@ static int modifier_convert_exec(bContext *C, wmOperator *op)
Object *ob = ED_object_active_context(C);
ModifierData *md = edit_modifier_property_get(op, ob, 0);
- if (!ob || !md || !ED_object_modifier_convert(op->reports, bmain, scene, ob, md))
+ if (!md || !ED_object_modifier_convert(op->reports, bmain, scene, ob, md))
return OPERATOR_CANCELLED;
DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
@@ -1088,7 +1088,7 @@ static int modifier_copy_exec(bContext *C, wmOperator *op)
Object *ob = ED_object_active_context(C);
ModifierData *md = edit_modifier_property_get(op, ob, 0);
- if (!ob || !md || !ED_object_modifier_copy(op->reports, ob, md))
+ if (!md || !ED_object_modifier_copy(op->reports, ob, md))
return OPERATOR_CANCELLED;
DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
@@ -1671,7 +1671,7 @@ void OBJECT_OT_skin_radii_equalize(wmOperatorType *ot)
static void skin_armature_bone_create(Object *skin_ob,
MVert *mvert, MEdge *medge,
bArmature *arm,
- BLI_bitmap edges_visited,
+ BLI_bitmap *edges_visited,
const MeshElemMap *emap,
EditBone *parent_bone,
int parent_v)
@@ -1720,7 +1720,7 @@ static void skin_armature_bone_create(Object *skin_ob,
static Object *modifier_skin_armature_create(Main *bmain, Scene *scene, Object *skin_ob)
{
- BLI_bitmap edges_visited;
+ BLI_bitmap *edges_visited;
DerivedMesh *deform_dm;
MVert *mvert;
Mesh *me = skin_ob->data;
diff --git a/source/blender/editors/object/object_relations.c b/source/blender/editors/object/object_relations.c
index 13fb46e35de..52f51cfcf48 100644
--- a/source/blender/editors/object/object_relations.c
+++ b/source/blender/editors/object/object_relations.c
@@ -2049,7 +2049,7 @@ static int make_local_exec(bContext *C, wmOperator *op)
if (adt) BKE_animdata_make_local(adt);
/* tag indirect data direct */
- matarar = (Material ***)give_matarar(ob);
+ matarar = give_matarar(ob);
if (matarar) {
for (a = 0; a < ob->totcol; a++) {
ma = (*matarar)[a];
diff --git a/source/blender/editors/object/object_vgroup.c b/source/blender/editors/object/object_vgroup.c
index 9b3f1a4f3ac..294b0632015 100644
--- a/source/blender/editors/object/object_vgroup.c
+++ b/source/blender/editors/object/object_vgroup.c
@@ -547,7 +547,6 @@ static void vgroup_normalize_active(Object *ob, eVGroupSelect subset_type)
ED_mesh_defvert_mirror_update_em(ob, eve_act, -1, -1, cd_dvert_offset);
}
else {
- int v_act = BKE_mesh_mselect_active_get(me, ME_VSEL);
ED_mesh_defvert_mirror_update_ob(ob, -1, v_act);
}
}
diff --git a/source/blender/editors/render/render_internal.c b/source/blender/editors/render/render_internal.c
index bc4ca82392f..3a6bd05df0b 100644
--- a/source/blender/editors/render/render_internal.c
+++ b/source/blender/editors/render/render_internal.c
@@ -1120,7 +1120,7 @@ void render_view3d_draw(RenderEngine *engine, const bContext *C)
glEnable(GL_BLEND);
glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
glaDrawPixelsTex(rres.xof, rres.yof, rres.rectx, rres.recty, GL_RGBA, GL_FLOAT,
- GL_LINEAR, rres.rectf);
+ GL_NEAREST, rres.rectf);
glDisable(GL_BLEND);
IMB_colormanagement_finish_glsl_draw();
@@ -1139,7 +1139,7 @@ void render_view3d_draw(RenderEngine *engine, const bContext *C)
glEnable(GL_BLEND);
glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
glaDrawPixelsAuto(rres.xof, rres.yof, rres.rectx, rres.recty, GL_RGBA, GL_UNSIGNED_BYTE,
- GL_LINEAR, display_buffer);
+ GL_NEAREST, display_buffer);
glDisable(GL_BLEND);
MEM_freeN(display_buffer);
diff --git a/source/blender/editors/render/render_opengl.c b/source/blender/editors/render/render_opengl.c
index 93ae913cee0..e21e889d99d 100644
--- a/source/blender/editors/render/render_opengl.c
+++ b/source/blender/editors/render/render_opengl.c
@@ -469,9 +469,7 @@ static void screen_opengl_render_end(bContext *C, OGLRender *oglrender)
WM_event_remove_timer(oglrender->wm, oglrender->win, oglrender->timer);
}
- if (oglrender->win) {
- WM_cursor_restore(oglrender->win);
- }
+ WM_cursor_restore(oglrender->win);
WM_event_add_notifier(C, NC_SCENE | ND_RENDER_RESULT, oglrender->scene);
@@ -560,9 +558,7 @@ static int screen_opengl_render_anim_step(bContext *C, wmOperator *op)
}
}
- if (oglrender->win) {
- WM_cursor_time(oglrender->win, scene->r.cfra);
- }
+ WM_cursor_time(oglrender->win, scene->r.cfra);
BKE_scene_update_for_newframe(bmain, scene, screen_opengl_layers(oglrender));
@@ -688,6 +684,7 @@ static int screen_opengl_render_modal(bContext *C, wmOperator *op, const wmEvent
/* render frame? */
if (oglrender->timer == event->customdata)
break;
+ /* fall-through */
default:
/* nothing to do */
return OPERATOR_RUNNING_MODAL;
@@ -728,6 +725,9 @@ static int screen_opengl_render_invoke(bContext *C, wmOperator *op, const wmEven
oglrender = op->customdata;
render_view_open(C, event->x, event->y);
+ /* view may be changed above (R_OUTPUT_WINDOW) */
+ oglrender->win = CTX_wm_window(C);
+
WM_event_add_modal_handler(C, op);
oglrender->timer = WM_event_add_timer(oglrender->wm, oglrender->win, TIMER, 0.01f);
diff --git a/source/blender/editors/render/render_preview.c b/source/blender/editors/render/render_preview.c
index 8da66c114d5..4bd8a7d426a 100644
--- a/source/blender/editors/render/render_preview.c
+++ b/source/blender/editors/render/render_preview.c
@@ -964,7 +964,7 @@ static void icon_preview_startjob(void *customdata, short *stop, short *do_updat
br->icon_imbuf = get_brush_icon(br);
- memset(sp->pr_rect, 0x888888, sp->sizex * sp->sizey * sizeof(unsigned int));
+ memset(sp->pr_rect, 0x88, sp->sizex * sp->sizey * sizeof(unsigned int));
if (!(br->icon_imbuf) || !(br->icon_imbuf->rect))
return;
diff --git a/source/blender/editors/render/render_shading.c b/source/blender/editors/render/render_shading.c
index 49ecfe2940e..58c244228ed 100644
--- a/source/blender/editors/render/render_shading.c
+++ b/source/blender/editors/render/render_shading.c
@@ -1214,7 +1214,7 @@ void SCENE_OT_freestyle_modifier_move(wmOperatorType *ot)
#endif /* WITH_FREESTYLE */
-static int texture_slot_move(bContext *C, wmOperator *op)
+static int texture_slot_move_exec(bContext *C, wmOperator *op)
{
ID *id = CTX_data_pointer_get_type(C, "texture_slot", &RNA_TextureSlot).id.data;
@@ -1292,7 +1292,7 @@ void TEXTURE_OT_slot_move(wmOperatorType *ot)
ot->description = "Move texture slots up and down";
/* api callbacks */
- ot->exec = texture_slot_move;
+ ot->exec = texture_slot_move_exec;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
diff --git a/source/blender/editors/screen/area.c b/source/blender/editors/screen/area.c
index 6c0d5ccd844..e805b3f30fc 100644
--- a/source/blender/editors/screen/area.c
+++ b/source/blender/editors/screen/area.c
@@ -387,7 +387,7 @@ void ED_region_set(const bContext *C, ARegion *ar)
ar->drawrct = ar->winrct;
/* note; this sets state, so we can use wmOrtho and friends */
- wmSubWindowScissorSet(win, ar->swinid, &ar->drawrct);
+ wmSubWindowScissorSet(win, ar->swinid, &ar->drawrct, true);
UI_SetTheme(sa ? sa->spacetype : 0, ar->type ? ar->type->regionid : 0);
@@ -401,26 +401,27 @@ void ED_region_do_draw(bContext *C, ARegion *ar)
wmWindow *win = CTX_wm_window(C);
ScrArea *sa = CTX_wm_area(C);
ARegionType *at = ar->type;
-
+ bool scissor_pad;
+
/* see BKE_spacedata_draw_locks() */
if (at->do_lock)
return;
/* if no partial draw rect set, full rect */
- if (ar->drawrct.xmin == ar->drawrct.xmax)
+ if (ar->drawrct.xmin == ar->drawrct.xmax) {
ar->drawrct = ar->winrct;
+ scissor_pad = true;
+ }
else {
- /* extra clip for safety (intersect the rects, could use API func) */
- ar->drawrct.xmin = max_ii(ar->winrct.xmin, ar->drawrct.xmin);
- ar->drawrct.ymin = max_ii(ar->winrct.ymin, ar->drawrct.ymin);
- ar->drawrct.xmax = min_ii(ar->winrct.xmax, ar->drawrct.xmax);
- ar->drawrct.ymax = min_ii(ar->winrct.ymax, ar->drawrct.ymax);
+ /* extra clip for safety */
+ BLI_rcti_isect(&ar->winrct, &ar->drawrct, &ar->drawrct);
+ scissor_pad = false;
}
/* note; this sets state, so we can use wmOrtho and friends */
- wmSubWindowScissorSet(win, ar->swinid, &ar->drawrct);
+ wmSubWindowScissorSet(win, ar->swinid, &ar->drawrct, scissor_pad);
- UI_SetTheme(sa ? sa->spacetype : 0, ar->type ? ar->type->regionid : 0);
+ UI_SetTheme(sa ? sa->spacetype : 0, at->regionid);
/* optional header info instead? */
if (ar->headerstr) {
diff --git a/source/blender/editors/screen/screen_edit.c b/source/blender/editors/screen/screen_edit.c
index d9dc5648ae3..498762f1603 100644
--- a/source/blender/editors/screen/screen_edit.c
+++ b/source/blender/editors/screen/screen_edit.c
@@ -1378,10 +1378,7 @@ void ED_screen_set(bContext *C, bScreen *sc)
if (id == NULL)
return;
- /* check for valid winid */
- if (sc->winid != 0 && sc->winid != win->winid)
- return;
-
+
if (sc->full) { /* find associated full */
bScreen *sc1;
for (sc1 = bmain->screen.first; sc1; sc1 = sc1->id.next) {
@@ -1392,6 +1389,10 @@ void ED_screen_set(bContext *C, bScreen *sc)
}
}
}
+
+ /* check for valid winid */
+ if (sc->winid != 0 && sc->winid != win->winid)
+ return;
if (oldscreen != sc) {
wmTimer *wt = oldscreen->animtimer;
diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c
index ff2561dc66f..3066b733fc5 100644
--- a/source/blender/editors/screen/screen_ops.c
+++ b/source/blender/editors/screen/screen_ops.c
@@ -649,7 +649,8 @@ static void actionzone_apply(bContext *C, wmOperator *op, int type)
sad->modifier = RNA_int_get(op->ptr, "modifier");
- event = *(win->eventstate); /* XXX huh huh? make api call */
+ wm_event_init_from_window(win, &event);
+
if (type == AZONE_AREA)
event.type = EVT_ACTIONZONE_AREA;
else
@@ -2564,7 +2565,7 @@ static void SCREEN_OT_area_options(wmOperatorType *ot)
/* ******************************* */
-static int spacedata_cleanup(bContext *C, wmOperator *op)
+static int spacedata_cleanup_exec(bContext *C, wmOperator *op)
{
Main *bmain = CTX_data_main(C);
bScreen *screen;
@@ -2596,7 +2597,7 @@ static void SCREEN_OT_spacedata_cleanup(wmOperatorType *ot)
ot->idname = "SCREEN_OT_spacedata_cleanup";
/* api callbacks */
- ot->exec = spacedata_cleanup;
+ ot->exec = spacedata_cleanup_exec;
ot->poll = WM_operator_winactive;
}
@@ -3184,7 +3185,7 @@ static int screen_animation_step(bContext *C, wmOperator *UNUSED(op), const wmEv
sound_seek_scene(bmain, scene);
/* since we follow drawflags, we can't send notifier but tag regions ourselves */
- ED_update_for_newframe(CTX_data_main(C), scene, 1);
+ ED_update_for_newframe(bmain, scene, 1);
for (window = wm->windows.first; window; window = window->next) {
for (sa = window->screen->areabase.first; sa; sa = sa->next) {
@@ -3369,7 +3370,7 @@ static void SCREEN_OT_animation_cancel(wmOperatorType *ot)
* poll() has to be filled in by user for context
*/
#if 0
-static int border_select_do(bContext *C, wmOperator *op)
+static int border_select_exec(bContext *C, wmOperator *op)
{
int event_type = RNA_int_get(op->ptr, "event_type");
@@ -3390,7 +3391,7 @@ static void SCREEN_OT_border_select(wmOperatorType *ot)
ot->idname = "SCREEN_OT_border_select";
/* api callbacks */
- ot->exec = border_select_do;
+ ot->exec = border_select_exec;
ot->invoke = WM_border_select_invoke;
ot->modal = WM_border_select_modal;
ot->cancel = WM_border_select_cancel;
diff --git a/source/blender/editors/sculpt_paint/paint_hide.c b/source/blender/editors/sculpt_paint/paint_hide.c
index 3db0bd61f03..db6380e920f 100644
--- a/source/blender/editors/sculpt_paint/paint_hide.c
+++ b/source/blender/editors/sculpt_paint/paint_hide.c
@@ -154,7 +154,7 @@ static void partialvis_update_grids(Object *ob,
{
CCGElem **grids;
CCGKey key;
- BLI_bitmap *grid_hidden;
+ BLI_bitmap **grid_hidden;
int any_visible = 0;
int *grid_indices, totgrid, any_changed, i;
@@ -171,7 +171,7 @@ static void partialvis_update_grids(Object *ob,
for (i = 0; i < totgrid; i++) {
int any_hidden = 0;
int g = grid_indices[i], x, y;
- BLI_bitmap gh = grid_hidden[g];
+ BLI_bitmap *gh = grid_hidden[g];
if (!gh) {
switch (action) {
diff --git a/source/blender/editors/sculpt_paint/paint_image_proj.c b/source/blender/editors/sculpt_paint/paint_image_proj.c
index 017232d1856..db55dc271f1 100644
--- a/source/blender/editors/sculpt_paint/paint_image_proj.c
+++ b/source/blender/editors/sculpt_paint/paint_image_proj.c
@@ -2816,7 +2816,11 @@ static void project_paint_begin(ProjPaintState *ps)
int a, i; /* generic looping vars */
int image_index = -1, face_index;
- int *mpoly_origindex;
+
+ /* double lookup */
+ const int *index_mf_to_mpoly = NULL;
+ const int *index_mp_to_orig = NULL;
+
MVert *mv;
MemArena *arena; /* at the moment this is just ps->arena_mt[0], but use this to show were not multithreading */
@@ -2871,12 +2875,17 @@ static void project_paint_begin(ProjPaintState *ps)
ps->dm_totface = ps->dm->getNumTessFaces(ps->dm);
if (ps->do_face_sel) {
- mpoly_orig = ((Mesh *)ps->ob->data)->mpoly;
- mpoly_origindex = ps->dm->getPolyDataArray(ps->dm, CD_ORIGINDEX);
+ index_mf_to_mpoly = ps->dm->getTessFaceDataArray(ps->dm, CD_ORIGINDEX);
+ index_mp_to_orig = ps->dm->getPolyDataArray(ps->dm, CD_ORIGINDEX);
+ if (index_mf_to_mpoly == NULL) {
+ index_mp_to_orig = NULL;
+ }
+ else {
+ mpoly_orig = ((Mesh *)ps->ob->data)->mpoly;
+ }
}
else {
mpoly_orig = NULL;
- mpoly_origindex = NULL;
}
/* use clone mtface? */
@@ -3166,8 +3175,10 @@ static void project_paint_begin(ProjPaintState *ps)
if (ps->do_face_sel) {
int orig_index;
- if (mpoly_origindex && ((orig_index = mpoly_origindex[face_index])) != ORIGINDEX_NONE) {
- MPoly *mp = mpoly_orig + orig_index;
+ if (index_mp_to_orig && ((orig_index = DM_origindex_mface_mpoly(index_mf_to_mpoly, index_mp_to_orig,
+ face_index))) != ORIGINDEX_NONE)
+ {
+ MPoly *mp = &mpoly_orig[orig_index];
is_face_sel = ((mp->flag & ME_FACE_SEL) != 0);
}
else {
diff --git a/source/blender/editors/sculpt_paint/paint_ops.c b/source/blender/editors/sculpt_paint/paint_ops.c
index cef624463c2..bdf542526ee 100644
--- a/source/blender/editors/sculpt_paint/paint_ops.c
+++ b/source/blender/editors/sculpt_paint/paint_ops.c
@@ -847,7 +847,7 @@ static void BRUSH_OT_stencil_fit_image_aspect(wmOperatorType *ot)
}
-static int stencil_reset_transform(bContext *C, wmOperator *op)
+static int stencil_reset_transform_exec(bContext *C, wmOperator *op)
{
Paint *paint = BKE_paint_get_active_from_context(C);
Brush *br = BKE_paint_brush(paint);
@@ -889,7 +889,7 @@ static void BRUSH_OT_stencil_reset_transform(wmOperatorType *ot)
ot->idname = "BRUSH_OT_stencil_reset_transform";
/* api callbacks */
- ot->exec = stencil_reset_transform;
+ ot->exec = stencil_reset_transform_exec;
ot->poll = stencil_control_poll;
/* flags */
diff --git a/source/blender/editors/sculpt_paint/paint_stroke.c b/source/blender/editors/sculpt_paint/paint_stroke.c
index 576bbecb561..36e1b1feb38 100644
--- a/source/blender/editors/sculpt_paint/paint_stroke.c
+++ b/source/blender/editors/sculpt_paint/paint_stroke.c
@@ -375,13 +375,13 @@ static float paint_space_stroke_spacing(const Scene *scene, PaintStroke *stroke,
/* apply spacing pressure */
if (stroke->brush->flag & BRUSH_SPACING_PRESSURE)
- spacing = max_ff(1.0f, spacing * (1.5f - spacing_pressure));
+ spacing = spacing * (1.5f - spacing_pressure);
/* stroke system is used for 2d paint too, so we need to account for
* the fact that brush can be scaled there. */
spacing *= stroke->zoom_2d;
- return (size_clamp * spacing / 50.0f);
+ return max_ff(1.0, size_clamp * spacing / 50.0f);
}
static float paint_space_stroke_spacing_variable(const Scene *scene, PaintStroke *stroke, float pressure, float dpressure, float length)
diff --git a/source/blender/editors/sculpt_paint/paint_utils.c b/source/blender/editors/sculpt_paint/paint_utils.c
index 3ecde56b5d0..d376bd3180f 100644
--- a/source/blender/editors/sculpt_paint/paint_utils.c
+++ b/source/blender/editors/sculpt_paint/paint_utils.c
@@ -412,7 +412,7 @@ void BRUSH_OT_curve_preset(wmOperatorType *ot)
/* face-select ops */
static int paint_select_linked_exec(bContext *C, wmOperator *UNUSED(op))
{
- paintface_select_linked(C, CTX_data_active_object(C), NULL, 2);
+ paintface_select_linked(C, CTX_data_active_object(C), NULL, true);
ED_region_tag_redraw(CTX_wm_region(C));
return OPERATOR_FINISHED;
}
diff --git a/source/blender/editors/sculpt_paint/paint_vertex.c b/source/blender/editors/sculpt_paint/paint_vertex.c
index b7bd061d14a..2c654507015 100644
--- a/source/blender/editors/sculpt_paint/paint_vertex.c
+++ b/source/blender/editors/sculpt_paint/paint_vertex.c
@@ -2025,7 +2025,7 @@ static void do_weight_paint_vertex(
/* *************** set wpaint operator ****************** */
-static int set_wpaint(bContext *C, wmOperator *UNUSED(op)) /* toggle */
+static int wpaint_mode_toggle_exec(bContext *C, wmOperator *UNUSED(op)) /* toggle */
{
Object *ob = CTX_data_active_object(C);
Scene *scene = CTX_data_scene(C);
@@ -2096,7 +2096,7 @@ void PAINT_OT_weight_paint_toggle(wmOperatorType *ot)
ot->description = "Toggle weight paint mode in 3D view";
/* api callbacks */
- ot->exec = set_wpaint;
+ ot->exec = wpaint_mode_toggle_exec;
ot->poll = paint_poll_test;
/* flags */
@@ -2642,7 +2642,7 @@ void PAINT_OT_weight_set(wmOperatorType *ot)
/* ************ set / clear vertex paint mode ********** */
-static int set_vpaint(bContext *C, wmOperator *op) /* toggle */
+static int vpaint_mode_toggle_exec(bContext *C, wmOperator *op) /* toggle */
{
Object *ob = CTX_data_active_object(C);
Scene *scene = CTX_data_scene(C);
@@ -2673,7 +2673,7 @@ static int set_vpaint(bContext *C, wmOperator *op) /* toggle */
ob->mode |= OB_MODE_VERTEX_PAINT;
/* Turn off weight painting */
if (ob->mode & OB_MODE_WEIGHT_PAINT)
- set_wpaint(C, op);
+ wpaint_mode_toggle_exec(C, op);
if (vp == NULL)
vp = scene->toolsettings->vpaint = new_vpaint(0);
@@ -2700,7 +2700,7 @@ void PAINT_OT_vertex_paint_toggle(wmOperatorType *ot)
ot->description = "Toggle the vertex paint mode in 3D view";
/* api callbacks */
- ot->exec = set_vpaint;
+ ot->exec = vpaint_mode_toggle_exec;
ot->poll = paint_poll_test;
/* flags */
@@ -3364,7 +3364,7 @@ static int paint_weight_gradient_exec(bContext *C, wmOperator *op)
const bool is_interactive = (gesture != NULL);
DerivedMesh *dm = mesh_get_derived_final(scene, ob, scene->customdata_mask);
- DMGradient_userData data = {0};
+ DMGradient_userData data = {NULL};
if (is_interactive) {
if (gesture->userdata == NULL) {
@@ -3413,7 +3413,7 @@ static int paint_weight_gradient_exec(bContext *C, wmOperator *op)
ED_view3d_init_mats_rv3d(ob, ar->regiondata);
- dm->foreachMappedVert(dm, gradientVert__mapFunc, &data);
+ dm->foreachMappedVert(dm, gradientVert__mapFunc, &data, DM_FOREACH_NOP);
DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob);
diff --git a/source/blender/editors/sculpt_paint/paint_vertex_proj.c b/source/blender/editors/sculpt_paint/paint_vertex_proj.c
index 2d5de80efeb..4c06cb8ea0d 100644
--- a/source/blender/editors/sculpt_paint/paint_vertex_proj.c
+++ b/source/blender/editors/sculpt_paint/paint_vertex_proj.c
@@ -107,7 +107,7 @@ static void vpaint_proj_dm_map_cosnos_init(Scene *scene, Object *ob,
if (dm->foreachMappedVert) {
memset(vp_handle->vcosnos, 0, sizeof(DMCoNo) * me->totvert);
- dm->foreachMappedVert(dm, vpaint_proj_dm_map_cosnos_init__map_cb, vp_handle);
+ dm->foreachMappedVert(dm, vpaint_proj_dm_map_cosnos_init__map_cb, vp_handle, DM_FOREACH_USE_NORMAL);
}
else {
DMCoNo *v_co_no = vp_handle->vcosnos;
@@ -183,7 +183,7 @@ static void vpaint_proj_dm_map_cosnos_update(struct VertProjHandle *vp_handle,
if (LIKELY(dm->foreachMappedVert)) {
fill_vn_fl(vp_handle->dists, me->totvert, FLT_MAX);
- dm->foreachMappedVert(dm, vpaint_proj_dm_map_cosnos_update__map_cb, &vp_update);
+ dm->foreachMappedVert(dm, vpaint_proj_dm_map_cosnos_update__map_cb, &vp_update, DM_FOREACH_USE_NORMAL);
}
dm->release(dm);
diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c
index 3aeb2f1597b..2edd00c015d 100644
--- a/source/blender/editors/sculpt_paint/sculpt.c
+++ b/source/blender/editors/sculpt_paint/sculpt.c
@@ -306,6 +306,7 @@ typedef struct StrokeCache {
char saved_active_brush_name[MAX_ID_NAME];
char saved_mask_brush_tool;
+ int saved_smooth_size; /* smooth tool copies the size of the current tool */
int alt_smooth;
float plane_trim_squared;
@@ -1529,7 +1530,7 @@ static void do_multires_smooth_brush(Sculpt *sd, SculptSession *ss, PBVHNode *no
float *tmpgrid_mask, *tmprow_mask;
int v1, v2, v3, v4;
int thread_num;
- BLI_bitmap *grid_hidden;
+ BLI_bitmap **grid_hidden;
int *grid_indices, totgrid, gridsize, i, x, y;
sculpt_brush_test_init(ss, &test);
@@ -1554,7 +1555,7 @@ static void do_multires_smooth_brush(Sculpt *sd, SculptSession *ss, PBVHNode *no
for (i = 0; i < totgrid; ++i) {
int gi = grid_indices[i];
- BLI_bitmap gh = grid_hidden[gi];
+ BLI_bitmap *gh = grid_hidden[gi];
data = griddata[gi];
adj = &gridadj[gi];
@@ -3710,6 +3711,7 @@ static void sculpt_omp_done(SculptSession *ss)
static void sculpt_update_cache_invariants(bContext *C, Sculpt *sd, SculptSession *ss, wmOperator *op, const float mouse[2])
{
StrokeCache *cache = MEM_callocN(sizeof(StrokeCache), "stroke cache");
+ Scene *scene = CTX_data_scene(C);
UnifiedPaintSettings *ups = &CTX_data_tool_settings(C)->unified_paint_settings;
Brush *brush = BKE_paint_brush(&sd->paint);
ViewContext *vc = paint_stroke_view_context(op->customdata);
@@ -3755,6 +3757,7 @@ static void sculpt_update_cache_invariants(bContext *C, Sculpt *sd, SculptSessio
else {
Paint *p = &sd->paint;
Brush *br;
+ int size = BKE_brush_size_get(scene, brush);
BLI_strncpy(cache->saved_active_brush_name, brush->id.name + 2,
sizeof(cache->saved_active_brush_name));
@@ -3763,6 +3766,8 @@ static void sculpt_update_cache_invariants(bContext *C, Sculpt *sd, SculptSessio
if (br) {
BKE_paint_brush_set(p, br);
brush = br;
+ cache->saved_smooth_size = BKE_brush_size_get(scene, brush);
+ BKE_brush_size_set(scene, brush, size);
}
}
}
@@ -4352,6 +4357,7 @@ static void sculpt_stroke_done(const bContext *C, struct PaintStroke *UNUSED(str
{
UnifiedPaintSettings *ups = &CTX_data_tool_settings(C)->unified_paint_settings;
Object *ob = CTX_data_active_object(C);
+ Scene *scene = CTX_data_scene(C);
SculptSession *ss = ob->sculpt;
Sculpt *sd = CTX_data_tool_settings(C)->sculpt;
@@ -4375,6 +4381,7 @@ static void sculpt_stroke_done(const bContext *C, struct PaintStroke *UNUSED(str
}
else {
Paint *p = &sd->paint;
+ BKE_brush_size_set(scene, ss->cache->brush, ss->cache->saved_smooth_size);
brush = (Brush *)BKE_libblock_find_name(ID_BR, ss->cache->saved_active_brush_name);
if (brush) {
BKE_paint_brush_set(p, brush);
@@ -4523,7 +4530,7 @@ static void SCULPT_OT_brush_stroke(wmOperatorType *ot)
/**** Reset the copy of the mesh that is being sculpted on (currently just for the layer brush) ****/
-static int sculpt_set_persistent_base(bContext *C, wmOperator *UNUSED(op))
+static int sculpt_set_persistent_base_exec(bContext *C, wmOperator *UNUSED(op))
{
SculptSession *ss = CTX_data_active_object(C)->sculpt;
@@ -4544,7 +4551,7 @@ static void SCULPT_OT_set_persistent_base(wmOperatorType *ot)
ot->description = "Reset the copy of the mesh that is being sculpted on";
/* api callbacks */
- ot->exec = sculpt_set_persistent_base;
+ ot->exec = sculpt_set_persistent_base_exec;
ot->poll = sculpt_mode_poll;
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
@@ -4588,14 +4595,21 @@ void sculpt_dynamic_topology_enable(bContext *C)
Object *ob = CTX_data_active_object(C);
SculptSession *ss = ob->sculpt;
Mesh *me = ob->data;
+ const BMAllocTemplate allocsize = {me->totvert,
+ me->totedge,
+ me->totloop,
+ me->totpoly};
sculpt_pbvh_clear(ob);
ss->bm_smooth_shading = (scene->toolsettings->sculpt->flags &
SCULPT_DYNTOPO_SMOOTH_SHADING);
+ /* Dynamic topology doesn't ensure selection state is valid, so remove [#36280] */
+ BKE_mesh_mselect_clear(me);
+
/* Create triangles-only BMesh */
- ss->bm = BM_mesh_create(&bm_mesh_allocsize_default);
+ ss->bm = BM_mesh_create(&allocsize);
BM_mesh_bm_from_me(ss->bm, me, true, true, ob->shapenr);
sculpt_dynamic_topology_triangulate(ss->bm);
@@ -4893,7 +4907,7 @@ int ED_sculpt_mask_layers_ensure(Object *ob, MultiresModifierData *mmd)
return ret;
}
-static int sculpt_toggle_mode(bContext *C, wmOperator *UNUSED(op))
+static int sculpt_mode_toggle_exec(bContext *C, wmOperator *UNUSED(op))
{
Scene *scene = CTX_data_scene(C);
ToolSettings *ts = CTX_data_tool_settings(C);
@@ -4981,7 +4995,7 @@ static void SCULPT_OT_sculptmode_toggle(wmOperatorType *ot)
ot->description = "Toggle sculpt mode in 3D view";
/* api callbacks */
- ot->exec = sculpt_toggle_mode;
+ ot->exec = sculpt_mode_toggle_exec;
ot->poll = ED_operator_object_active_editable_mesh;
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
diff --git a/source/blender/editors/sculpt_paint/sculpt_intern.h b/source/blender/editors/sculpt_paint/sculpt_intern.h
index 13f97c50dc7..d904ec3bc96 100644
--- a/source/blender/editors/sculpt_paint/sculpt_intern.h
+++ b/source/blender/editors/sculpt_paint/sculpt_intern.h
@@ -100,14 +100,14 @@ typedef struct SculptUndoNode {
/* non-multires */
int maxvert; /* to verify if totvert it still the same */
int *index; /* to restore into right location */
- BLI_bitmap vert_hidden;
+ BLI_bitmap *vert_hidden;
/* multires */
int maxgrid; /* same for grid */
int gridsize; /* same for grid */
int totgrid; /* to restore into right location */
int *grids; /* to restore into right location */
- BLI_bitmap *grid_hidden;
+ BLI_bitmap **grid_hidden;
/* bmesh */
struct BMLogEntry *bm_entry;
diff --git a/source/blender/editors/sculpt_paint/sculpt_undo.c b/source/blender/editors/sculpt_paint/sculpt_undo.c
index 2cc09ea2aa9..8861777f326 100644
--- a/source/blender/editors/sculpt_paint/sculpt_undo.c
+++ b/source/blender/editors/sculpt_paint/sculpt_undo.c
@@ -210,10 +210,10 @@ static int sculpt_undo_restore_hidden(bContext *C, DerivedMesh *dm,
}
}
else if (unode->maxgrid && dm->getGridData) {
- BLI_bitmap *grid_hidden = dm->getGridHidden(dm);
+ BLI_bitmap **grid_hidden = dm->getGridHidden(dm);
for (i = 0; i < unode->totgrid; i++) {
- SWAP(BLI_bitmap,
+ SWAP(BLI_bitmap *,
unode->grid_hidden[i],
grid_hidden[unode->grids[i]]);
@@ -531,7 +531,7 @@ static void sculpt_undo_alloc_and_store_hidden(PBVH *pbvh,
SculptUndoNode *unode)
{
PBVHNode *node = unode->node;
- BLI_bitmap *grid_hidden;
+ BLI_bitmap **grid_hidden;
int i, *grid_indices, totgrid;
grid_hidden = BKE_pbvh_grid_hidden(pbvh);
@@ -539,7 +539,7 @@ static void sculpt_undo_alloc_and_store_hidden(PBVH *pbvh,
BKE_pbvh_node_get_grids(pbvh, node, &grid_indices, &totgrid,
NULL, NULL, NULL, NULL);
- unode->grid_hidden = MEM_mapallocN(sizeof(BLI_bitmap) * totgrid,
+ unode->grid_hidden = MEM_mapallocN(sizeof(*unode->grid_hidden) * totgrid,
"unode->grid_hidden");
for (i = 0; i < totgrid; i++) {
diff --git a/source/blender/editors/space_buttons/space_buttons.c b/source/blender/editors/space_buttons/space_buttons.c
index 72d7bcd43ce..d32be692558 100644
--- a/source/blender/editors/space_buttons/space_buttons.c
+++ b/source/blender/editors/space_buttons/space_buttons.c
@@ -266,6 +266,7 @@ static void buttons_area_listener(bScreen *UNUSED(sc), ScrArea *sa, wmNotifier *
break;
case ND_POSE:
buttons_area_redraw(sa, BCONTEXT_DATA);
+ break;
case ND_BONE_ACTIVE:
case ND_BONE_SELECT:
buttons_area_redraw(sa, BCONTEXT_BONE);
diff --git a/source/blender/editors/space_clip/tracking_ops.c b/source/blender/editors/space_clip/tracking_ops.c
index 9afca413836..f3d070452a5 100644
--- a/source/blender/editors/space_clip/tracking_ops.c
+++ b/source/blender/editors/space_clip/tracking_ops.c
@@ -1226,9 +1226,9 @@ static void track_markers_freejob(void *tmv)
BKE_tracking_context_sync(tmj->context);
BKE_tracking_context_free(tmj->context);
- MEM_freeN(tmj);
-
WM_main_add_notifier(NC_SCENE | ND_FRAME, tmj->scene);
+
+ MEM_freeN(tmj);
}
static int track_markers_exec(bContext *C, wmOperator *op)
@@ -1711,7 +1711,9 @@ static int clear_track_path_exec(bContext *C, wmOperator *op)
if (clear_active) {
track = BKE_tracking_track_get_active(tracking);
- BKE_tracking_track_path_clear(track, framenr, action);
+ if (track) {
+ BKE_tracking_track_path_clear(track, framenr, action);
+ }
}
else {
track = tracksbase->first;
@@ -3476,6 +3478,8 @@ static int clean_tracks_exec(bContext *C, wmOperator *op)
track = next;
}
+ BKE_tracking_dopesheet_tag_update(tracking);
+
WM_event_add_notifier(C, NC_MOVIECLIP | ND_SELECT, clip);
return OPERATOR_FINISHED;
diff --git a/source/blender/editors/space_file/space_file.c b/source/blender/editors/space_file/space_file.c
index 8b1df0f0d8f..6f3d0367574 100644
--- a/source/blender/editors/space_file/space_file.c
+++ b/source/blender/editors/space_file/space_file.c
@@ -500,12 +500,14 @@ static void file_channel_area_draw(const bContext *C, ARegion *ar)
ED_region_panels(C, ar, 1, NULL, -1);
}
-static void file_channel_area_listener(bScreen *UNUSED(sc), ScrArea *UNUSED(sa), ARegion *UNUSED(ar), wmNotifier *wmn)
+static void file_channel_area_listener(bScreen *UNUSED(sc), ScrArea *UNUSED(sa), ARegion *UNUSED(ar), wmNotifier *UNUSED(wmn))
{
+#if 0
/* context changes */
switch (wmn->category) {
}
+#endif
}
/* add handlers, stuff you only do once or on area/region changes */
diff --git a/source/blender/editors/space_graph/graph_buttons.c b/source/blender/editors/space_graph/graph_buttons.c
index a81c0d6dfd6..295f8bd9ff2 100644
--- a/source/blender/editors/space_graph/graph_buttons.c
+++ b/source/blender/editors/space_graph/graph_buttons.c
@@ -50,6 +50,7 @@
#include "BKE_depsgraph.h"
#include "BKE_fcurve.h"
#include "BKE_main.h"
+#include "BKE_global.h"
#include "BKE_screen.h"
#include "BKE_unit.h"
@@ -74,20 +75,6 @@
/* -------------- */
-static void do_graph_region_buttons(bContext *UNUSED(C), void *UNUSED(arg), int event)
-{
- //Scene *scene = CTX_data_scene(C);
-
- switch (event) {
-
- }
-
- /* default for now */
- //WM_event_add_notifier(C, NC_OBJECT|ND_TRANSFORM, ob);
-}
-
-/* -------------- */
-
static int graph_panel_context(const bContext *C, bAnimListElem **ale, FCurve **fcu)
{
bAnimContext ac;
@@ -162,15 +149,16 @@ static void graph_panel_properties(const bContext *C, Panel *pa)
PointerRNA fcu_ptr;
uiLayout *layout = pa->layout;
uiLayout *col, *row, *sub;
- uiBlock *block;
+ // uiBlock *block; // UNUSED
char name[256];
int icon = 0;
if (!graph_panel_context(C, &ale, &fcu))
return;
- block = uiLayoutGetBlock(layout);
- uiBlockSetHandleFunc(block, do_graph_region_buttons, NULL);
+ // UNUSED
+ // block = uiLayoutGetBlock(layout);
+ // uiBlockSetHandleFunc(block, do_graph_region_buttons, NULL);
/* F-Curve pointer */
RNA_pointer_create(ale->id, &RNA_FCurve, fcu, &fcu_ptr);
@@ -281,7 +269,7 @@ static void graph_panel_key_properties(const bContext *C, Panel *pa)
return;
block = uiLayoutGetBlock(layout);
- uiBlockSetHandleFunc(block, do_graph_region_buttons, NULL);
+ /* uiBlockSetHandleFunc(block, do_graph_region_buttons, NULL); */
/* only show this info if there are keyframes to edit */
if (get_active_fcurve_keyframe_edit(fcu, &bezt, &prevbezt)) {
@@ -633,8 +621,12 @@ static void graph_panel_drivers(const bContext *C, Panel *pa)
uiItemR(col, &driver_ptr, "expression", 0, IFACE_("Expr"), ICON_NONE);
/* errors? */
- if (driver->flag & DRIVER_FLAG_INVALID)
+ if ((G.f & G_SCRIPT_AUTOEXEC) == 0) {
+ uiItemL(col, IFACE_("ERROR: Python auto-execution disabled"), ICON_ERROR);
+ }
+ else if (driver->flag & DRIVER_FLAG_INVALID) {
uiItemL(col, IFACE_("ERROR: Invalid Python expression"), ICON_ERROR);
+ }
}
else {
/* errors? */
@@ -841,7 +833,7 @@ void graph_buttons_register(ARegionType *art)
BLI_addtail(&art->paneltypes, pt);
}
-static int graph_properties(bContext *C, wmOperator *UNUSED(op))
+static int graph_properties_toggle_exec(bContext *C, wmOperator *UNUSED(op))
{
ScrArea *sa = CTX_wm_area(C);
ARegion *ar = graph_has_buttons_region(sa);
@@ -858,7 +850,7 @@ void GRAPH_OT_properties(wmOperatorType *ot)
ot->idname = "GRAPH_OT_properties";
ot->description = "Toggle display properties panel";
- ot->exec = graph_properties;
+ ot->exec = graph_properties_toggle_exec;
ot->poll = ED_operator_graphedit_active;
/* flags */
diff --git a/source/blender/editors/space_image/image_buttons.c b/source/blender/editors/space_image/image_buttons.c
index 4b1975bc058..144d2c14e9f 100644
--- a/source/blender/editors/space_image/image_buttons.c
+++ b/source/blender/editors/space_image/image_buttons.c
@@ -886,7 +886,7 @@ void image_buttons_register(ARegionType *art)
BLI_addtail(&art->paneltypes, pt);
}
-static int image_properties(bContext *C, wmOperator *UNUSED(op))
+static int image_properties_toggle_exec(bContext *C, wmOperator *UNUSED(op))
{
ScrArea *sa = CTX_wm_area(C);
ARegion *ar = image_has_buttons_region(sa);
@@ -903,14 +903,14 @@ void IMAGE_OT_properties(wmOperatorType *ot)
ot->idname = "IMAGE_OT_properties";
ot->description = "Toggle display properties panel";
- ot->exec = image_properties;
+ ot->exec = image_properties_toggle_exec;
ot->poll = ED_operator_image_active;
/* flags */
ot->flag = 0;
}
-static int image_scopes(bContext *C, wmOperator *UNUSED(op))
+static int image_scopes_toggle_exec(bContext *C, wmOperator *UNUSED(op))
{
ScrArea *sa = CTX_wm_area(C);
ARegion *ar = image_has_scope_region(sa);
@@ -927,7 +927,7 @@ void IMAGE_OT_scopes(wmOperatorType *ot)
ot->idname = "IMAGE_OT_scopes";
ot->description = "Toggle display scopes panel";
- ot->exec = image_scopes;
+ ot->exec = image_scopes_toggle_exec;
ot->poll = ED_operator_image_active;
/* flags */
diff --git a/source/blender/editors/space_logic/logic_buttons.c b/source/blender/editors/space_logic/logic_buttons.c
index a55da0e3b2c..2c521532484 100644
--- a/source/blender/editors/space_logic/logic_buttons.c
+++ b/source/blender/editors/space_logic/logic_buttons.c
@@ -50,7 +50,7 @@
#include "interface_intern.h"
#include "logic_intern.h"
-static int logic_properties(bContext *C, wmOperator *UNUSED(op))
+static int logic_properties_toggle_exec(bContext *C, wmOperator *UNUSED(op))
{
ScrArea *sa = CTX_wm_area(C);
ARegion *ar = logic_has_buttons_region(sa);
@@ -67,7 +67,7 @@ void LOGIC_OT_properties(wmOperatorType *ot)
ot->description = "Toggle display properties panel";
ot->idname = "LOGIC_OT_properties";
- ot->exec = logic_properties;
+ ot->exec = logic_properties_toggle_exec;
ot->poll = ED_operator_logic_active;
/* flags */
diff --git a/source/blender/editors/space_logic/logic_window.c b/source/blender/editors/space_logic/logic_window.c
index ce8ee25eef0..2957edd941b 100644
--- a/source/blender/editors/space_logic/logic_window.c
+++ b/source/blender/editors/space_logic/logic_window.c
@@ -1009,8 +1009,6 @@ static void draw_sensor_armature(uiLayout *layout, PointerRNA *ptr)
bSensor *sens = (bSensor *)ptr->data;
bArmatureSensor *as = (bArmatureSensor *) sens->data;
Object *ob = (Object *)ptr->id.data;
- PointerRNA pose_ptr, pchan_ptr;
- PropertyRNA *bones_prop= NULL;
uiLayout *row;
if (ob->type != OB_ARMATURE) {
@@ -1019,11 +1017,12 @@ static void draw_sensor_armature(uiLayout *layout, PointerRNA *ptr)
}
if (ob->pose) {
+ PointerRNA pose_ptr, pchan_ptr;
+ PropertyRNA *bones_prop;
+
RNA_pointer_create((ID *)ob, &RNA_Pose, ob->pose, &pose_ptr);
bones_prop = RNA_struct_find_property(&pose_ptr, "bones");
- }
- if (&pose_ptr.data) {
uiItemPointerR(layout, ptr, "bone", &pose_ptr, "bones", NULL, ICON_BONE_DATA);
if (RNA_property_collection_lookup_string(&pose_ptr, bones_prop, as->posechannel, &pchan_ptr))
diff --git a/source/blender/editors/space_nla/nla_buttons.c b/source/blender/editors/space_nla/nla_buttons.c
index 4cda92fbe07..ce7d537a518 100644
--- a/source/blender/editors/space_nla/nla_buttons.c
+++ b/source/blender/editors/space_nla/nla_buttons.c
@@ -68,14 +68,14 @@
/* -------------- */
-static void do_nla_region_buttons(bContext *C, void *UNUSED(arg), int event)
+static void do_nla_region_buttons(bContext *C, void *UNUSED(arg), int UNUSED(event))
{
//Scene *scene = CTX_data_scene(C);
-
+#if 0
switch (event) {
}
-
+#endif
/* default for now */
WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, NULL);
WM_event_add_notifier(C, NC_SCENE | ND_TRANSFORM, NULL);
@@ -552,7 +552,7 @@ void nla_buttons_register(ARegionType *art)
BLI_addtail(&art->paneltypes, pt);
}
-static int nla_properties(bContext *C, wmOperator *UNUSED(op))
+static int nla_properties_toggle_exec(bContext *C, wmOperator *UNUSED(op))
{
ScrArea *sa = CTX_wm_area(C);
ARegion *ar = nla_has_buttons_region(sa);
@@ -569,7 +569,7 @@ void NLA_OT_properties(wmOperatorType *ot)
ot->idname = "NLA_OT_properties";
ot->description = "Toggle display properties panel";
- ot->exec = nla_properties;
+ ot->exec = nla_properties_toggle_exec;
ot->poll = ED_operator_nla_active;
/* flags */
diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c
index 0dcae29bf7f..cf3c0454e6b 100644
--- a/source/blender/editors/space_node/drawnode.c
+++ b/source/blender/editors/space_node/drawnode.c
@@ -735,6 +735,13 @@ static void node_shader_buts_vect_math(uiLayout *layout, bContext *UNUSED(C), Po
uiItemR(layout, ptr, "operation", 0, "", ICON_NONE);
}
+static void node_shader_buts_vect_transform(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+{
+ uiItemR(layout, ptr, "type", UI_ITEM_R_EXPAND, NULL, ICON_NONE);
+ uiItemR(layout, ptr, "convert_from", 0, "", ICON_NONE);
+ uiItemR(layout, ptr, "convert_to", 0, "", ICON_NONE);
+}
+
static void node_shader_buts_geometry(uiLayout *layout, bContext *C, PointerRNA *ptr)
{
PointerRNA obptr = CTX_data_pointer_get(C, "active_object");
@@ -975,6 +982,9 @@ static void node_shader_set_butfunc(bNodeType *ntype)
case SH_NODE_VECT_MATH:
ntype->uifunc = node_shader_buts_vect_math;
break;
+ case SH_NODE_VECT_TRANSFORM:
+ ntype->uifunc = node_shader_buts_vect_transform;
+ break;
case SH_NODE_GEOMETRY:
ntype->uifunc = node_shader_buts_geometry;
break;
diff --git a/source/blender/editors/space_node/node_add.c b/source/blender/editors/space_node/node_add.c
index d5224a37358..c9618daa7c5 100644
--- a/source/blender/editors/space_node/node_add.c
+++ b/source/blender/editors/space_node/node_add.c
@@ -339,8 +339,6 @@ static int node_add_file_exec(bContext *C, wmOperator *op)
}
}
- node_deselect_all(snode);
-
switch (snode->nodetree->type) {
case NTREE_SHADER:
type = SH_NODE_TEX_IMAGE;
@@ -410,6 +408,69 @@ void NODE_OT_add_file(wmOperatorType *ot)
RNA_def_string(ot->srna, "name", "Image", MAX_ID_NAME - 2, "Name", "Datablock name to assign");
}
+/* ****************** Add Mask Node Operator ******************* */
+
+static int node_add_mask_poll(bContext *C)
+{
+ SpaceNode *snode = CTX_wm_space_node(C);
+
+ return ED_operator_node_editable(C) && snode->nodetree->type == NTREE_COMPOSIT;
+}
+
+static int node_add_mask_invoke(bContext *C, wmOperator *op, const wmEvent *event)
+{
+ ARegion *ar = CTX_wm_region(C);
+ SpaceNode *snode = CTX_wm_space_node(C);
+ bNode *node;
+ ID *mask = NULL;
+
+ /* check input variables */
+ char name[MAX_ID_NAME - 2];
+ RNA_string_get(op->ptr, "name", name);
+ mask = BKE_libblock_find_name(ID_MSK, name);
+ if (!mask) {
+ BKE_reportf(op->reports, RPT_ERROR, "Mask '%s' not found", name);
+ return OPERATOR_CANCELLED;
+ }
+
+ ED_preview_kill_jobs(C);
+
+ /* convert mouse coordinates to v2d space */
+ UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1],
+ &snode->cursor[0], &snode->cursor[1]);
+ node = node_add_node(C, NULL, CMP_NODE_MASK, snode->cursor[0], snode->cursor[1]);
+
+ if (!node) {
+ BKE_report(op->reports, RPT_WARNING, "Could not add a mask node");
+ return OPERATOR_CANCELLED;
+ }
+
+ node->id = mask;
+ id_us_plus(mask);
+
+ snode_notify(C, snode);
+ snode_dag_update(C, snode);
+
+ return OPERATOR_FINISHED;
+}
+
+void NODE_OT_add_mask(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Add Mask Node";
+ ot->description = "Add a mask node to the current node editor";
+ ot->idname = "NODE_OT_add_mask";
+
+ /* callbacks */
+ ot->invoke = node_add_mask_invoke;
+ ot->poll = node_add_mask_poll;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+
+ RNA_def_string(ot->srna, "name", "Mask", MAX_ID_NAME - 2, "Name", "Datablock name to assign");
+}
+
/********************** New node tree operator *********************/
static int new_node_tree_exec(bContext *C, wmOperator *op)
diff --git a/source/blender/editors/space_node/node_buttons.c b/source/blender/editors/space_node/node_buttons.c
index 7068973b2bf..f95e895bef2 100644
--- a/source/blender/editors/space_node/node_buttons.c
+++ b/source/blender/editors/space_node/node_buttons.c
@@ -206,7 +206,7 @@ void node_buttons_register(ARegionType *art)
BLI_addtail(&art->paneltypes, pt);
}
-static int node_properties(bContext *C, wmOperator *UNUSED(op))
+static int node_properties_toggle_exec(bContext *C, wmOperator *UNUSED(op))
{
ScrArea *sa = CTX_wm_area(C);
ARegion *ar = node_has_buttons_region(sa);
@@ -230,7 +230,7 @@ void NODE_OT_properties(wmOperatorType *ot)
ot->description = "Toggles the properties panel display";
ot->idname = "NODE_OT_properties";
- ot->exec = node_properties;
+ ot->exec = node_properties_toggle_exec;
ot->poll = node_properties_poll;
/* flags */
diff --git a/source/blender/editors/space_node/node_edit.c b/source/blender/editors/space_node/node_edit.c
index 9b48774588d..b7e9cb0268f 100644
--- a/source/blender/editors/space_node/node_edit.c
+++ b/source/blender/editors/space_node/node_edit.c
@@ -510,13 +510,9 @@ void ED_node_composit_default(const bContext *C, struct Scene *sce)
out = nodeAddStaticNode(C, sce->nodetree, CMP_NODE_COMPOSITE);
out->locx = 300.0f; out->locy = 400.0f;
- out->id = &sce->id;
- id_us_plus(out->id);
in = nodeAddStaticNode(C, sce->nodetree, CMP_NODE_R_LAYERS);
in->locx = 10.0f; in->locy = 400.0f;
- in->id = &sce->id;
- id_us_plus(in->id);
nodeSetActive(sce->nodetree, in);
/* links from color to color */
diff --git a/source/blender/editors/space_node/node_intern.h b/source/blender/editors/space_node/node_intern.h
index a9a17b182a4..1a2e90e5522 100644
--- a/source/blender/editors/space_node/node_intern.h
+++ b/source/blender/editors/space_node/node_intern.h
@@ -143,6 +143,7 @@ void draw_nodespace_back_pix(const struct bContext *C, struct ARegion *ar, struc
bNode *node_add_node(const struct bContext *C, const char *idname, int type, float locx, float locy);
void NODE_OT_add_reroute(struct wmOperatorType *ot);
void NODE_OT_add_file(struct wmOperatorType *ot);
+void NODE_OT_add_mask(struct wmOperatorType *ot);
void NODE_OT_new_node_tree(struct wmOperatorType *ot);
diff --git a/source/blender/editors/space_node/node_ops.c b/source/blender/editors/space_node/node_ops.c
index 2476a9b8b99..566bb1600cc 100644
--- a/source/blender/editors/space_node/node_ops.c
+++ b/source/blender/editors/space_node/node_ops.c
@@ -101,6 +101,7 @@ void node_operatortypes(void)
WM_operatortype_append(NODE_OT_backimage_sample);
WM_operatortype_append(NODE_OT_add_file);
+ WM_operatortype_append(NODE_OT_add_mask);
WM_operatortype_append(NODE_OT_new_node_tree);
diff --git a/source/blender/editors/space_node/node_relationships.c b/source/blender/editors/space_node/node_relationships.c
index beea4dc3183..244b222811e 100644
--- a/source/blender/editors/space_node/node_relationships.c
+++ b/source/blender/editors/space_node/node_relationships.c
@@ -356,7 +356,7 @@ static int node_link_viewer(const bContext *C, bNode *tonode)
}
-static int node_active_link_viewer(bContext *C, wmOperator *UNUSED(op))
+static int node_active_link_viewer_exec(bContext *C, wmOperator *UNUSED(op))
{
SpaceNode *snode = CTX_wm_space_node(C);
bNode *node;
@@ -385,7 +385,7 @@ void NODE_OT_link_viewer(wmOperatorType *ot)
ot->idname = "NODE_OT_link_viewer";
/* api callbacks */
- ot->exec = node_active_link_viewer;
+ ot->exec = node_active_link_viewer_exec;
ot->poll = composite_node_editable;
/* flags */
diff --git a/source/blender/editors/space_node/node_select.c b/source/blender/editors/space_node/node_select.c
index bd0c9848b23..e17699309ef 100644
--- a/source/blender/editors/space_node/node_select.c
+++ b/source/blender/editors/space_node/node_select.c
@@ -926,7 +926,7 @@ static uiBlock *node_find_menu(bContext *C, ARegion *ar, void *arg_op)
uiEndBlock(C, block);
// uiButActiveOnly(C, ar, block, but); XXX using this here makes Blender hang - investigate
- event = *(win->eventstate); /* XXX huh huh? make api call */
+ wm_event_init_from_window(win, &event);
event.type = EVT_BUT_OPEN;
event.val = KM_PRESS;
event.customdata = but;
diff --git a/source/blender/editors/space_node/node_toolbar.c b/source/blender/editors/space_node/node_toolbar.c
index 86da4009b17..dd5bad3f8ad 100644
--- a/source/blender/editors/space_node/node_toolbar.c
+++ b/source/blender/editors/space_node/node_toolbar.c
@@ -60,7 +60,7 @@ void node_toolbar_register(ARegionType *UNUSED(art))
/* ********** operator to open/close toolshelf region */
-static int node_toolbar(bContext *C, wmOperator *UNUSED(op))
+static int node_toolbar_toggle_exec(bContext *C, wmOperator *UNUSED(op))
{
ScrArea *sa = CTX_wm_area(C);
ARegion *ar = node_has_tools_region(sa);
@@ -84,7 +84,7 @@ void NODE_OT_toolbar(wmOperatorType *ot)
ot->description = "Toggles tool shelf display";
ot->idname = "NODE_OT_toolbar";
- ot->exec = node_toolbar;
+ ot->exec = node_toolbar_toggle_exec;
ot->poll = node_toolbar_poll;
/* flags */
diff --git a/source/blender/editors/space_node/node_view.c b/source/blender/editors/space_node/node_view.c
index eed8a10a1db..9e6e1e628f6 100644
--- a/source/blender/editors/space_node/node_view.c
+++ b/source/blender/editors/space_node/node_view.c
@@ -295,7 +295,7 @@ void NODE_OT_backimage_move(wmOperatorType *ot)
ot->flag = OPTYPE_BLOCKING | OPTYPE_GRAB_POINTER;
}
-static int backimage_zoom(bContext *C, wmOperator *op)
+static int backimage_zoom_exec(bContext *C, wmOperator *op)
{
SpaceNode *snode = CTX_wm_space_node(C);
ARegion *ar = CTX_wm_region(C);
@@ -317,7 +317,7 @@ void NODE_OT_backimage_zoom(wmOperatorType *ot)
ot->description = "Zoom in/out the background image";
/* api callbacks */
- ot->exec = backimage_zoom;
+ ot->exec = backimage_zoom_exec;
ot->poll = composite_node_active;
/* flags */
diff --git a/source/blender/editors/space_node/space_node.c b/source/blender/editors/space_node/space_node.c
index f12f7743429..922912fa540 100644
--- a/source/blender/editors/space_node/space_node.c
+++ b/source/blender/editors/space_node/space_node.c
@@ -635,7 +635,7 @@ static void node_main_area_draw(const bContext *C, ARegion *ar)
/* ************* dropboxes ************* */
-static int node_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUSED(event))
+static int node_ima_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUSED(event))
{
if (drag->type == WM_DRAG_ID) {
ID *id = (ID *)drag->poin;
@@ -649,6 +649,23 @@ static int node_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUS
return 0;
}
+static int node_mask_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUSED(event))
+{
+ if (drag->type == WM_DRAG_ID) {
+ ID *id = (ID *)drag->poin;
+ if (GS(id->name) == ID_MSK)
+ return 1;
+ }
+ return 0;
+}
+
+static void node_id_drop_copy(wmDrag *drag, wmDropBox *drop)
+{
+ ID *id = (ID *)drag->poin;
+
+ RNA_string_set(drop->ptr, "name", id->name + 2);
+}
+
static void node_id_path_drop_copy(wmDrag *drag, wmDropBox *drop)
{
ID *id = (ID *)drag->poin;
@@ -666,7 +683,8 @@ static void node_dropboxes(void)
{
ListBase *lb = WM_dropboxmap_find("Node Editor", SPACE_NODE, RGN_TYPE_WINDOW);
- WM_dropbox_add(lb, "NODE_OT_add_file", node_drop_poll, node_id_path_drop_copy);
+ WM_dropbox_add(lb, "NODE_OT_add_file", node_ima_drop_poll, node_id_path_drop_copy);
+ WM_dropbox_add(lb, "NODE_OT_add_mask", node_mask_drop_poll, node_id_drop_copy);
}
diff --git a/source/blender/editors/space_outliner/outliner_draw.c b/source/blender/editors/space_outliner/outliner_draw.c
index 81207deea01..44d5672e7da 100644
--- a/source/blender/editors/space_outliner/outliner_draw.c
+++ b/source/blender/editors/space_outliner/outliner_draw.c
@@ -40,6 +40,7 @@
#include "BLI_blenlib.h"
#include "BLI_utildefines.h"
#include "BLI_ghash.h"
+#include "BLI_mempool.h"
#include "BLF_translation.h"
@@ -263,7 +264,7 @@ static void restrictbutton_bone_visibility_cb(bContext *C, void *poin, void *poi
{
bArmature *arm = (bArmature *)poin;
Bone *bone = (Bone *)poin2;
- if (bone && (bone->flag & BONE_HIDDEN_P))
+ if (bone->flag & BONE_HIDDEN_P)
bone->flag &= ~(BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL);
if (CTX_wm_window(C)->eventstate->ctrl) {
@@ -277,7 +278,7 @@ 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))
+ if (bone->flag & BONE_UNSELECTABLE)
bone->flag &= ~(BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL);
if (CTX_wm_window(C)->eventstate->ctrl) {
@@ -407,7 +408,7 @@ static void namebutton_cb(bContext *C, void *tsep, char *oldname)
SpaceOops *soops = CTX_wm_space_outliner(C);
Scene *scene = CTX_data_scene(C);
Object *obedit = CTX_data_edit_object(C);
- TreeStore *ts = soops->treestore;
+ BLI_mempool *ts = soops->treestore;
TreeStoreElem *tselem = tsep;
if (ts && tselem) {
@@ -539,21 +540,21 @@ 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,
+ (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_VIEWX), te->ys, UI_UNIT_X, UI_UNIT_Y,
&ptr, "hide", -1, 0, 0, -1, -1,
TIP_("Restrict viewport visibility (Ctrl - Recursive)"));
uiButSetFunc(bt, restrictbutton_view_cb, scene, ob);
uiButSetFlag(bt, UI_BUT_DRAG_LOCK);
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,
+ (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_SELECTX), te->ys, UI_UNIT_X, UI_UNIT_Y,
&ptr, "hide_select", -1, 0, 0, -1, -1,
TIP_("Restrict viewport selection (Ctrl - Recursive)"));
uiButSetFunc(bt, restrictbutton_sel_cb, scene, ob);
uiButSetFlag(bt, UI_BUT_DRAG_LOCK);
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,
+ (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_RENDERX), te->ys, UI_UNIT_X, UI_UNIT_Y,
&ptr, "hide_render", -1, 0, 0, -1, -1,
TIP_("Restrict rendering (Ctrl - Recursive)"));
uiButSetFunc(bt, restrictbutton_rend_cb, scene, ob);
@@ -570,21 +571,21 @@ 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,
+ (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_VIEWX), te->ys, UI_UNIT_X, UI_UNIT_Y,
NULL, 0, 0, 0, 0, TIP_("Restrict/Allow visibility in the 3D View"));
uiButSetFunc(bt, restrictbutton_gr_restrict_view, scene, gr);
uiButSetFlag(bt, UI_BUT_DRAG_LOCK);
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,
+ (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_SELECTX), te->ys, UI_UNIT_X, UI_UNIT_Y,
NULL, 0, 0, 0, 0, TIP_("Restrict/Allow selection in the 3D View"));
uiButSetFunc(bt, restrictbutton_gr_restrict_select, scene, gr);
uiButSetFlag(bt, UI_BUT_DRAG_LOCK);
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,
+ (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_RENDERX), te->ys, UI_UNIT_X, UI_UNIT_Y,
NULL, 0, 0, 0, 0, TIP_("Restrict/Allow renderability"));
uiButSetFunc(bt, restrictbutton_gr_restrict_render, scene, gr);
uiButSetFlag(bt, UI_BUT_DRAG_LOCK);
@@ -596,7 +597,7 @@ 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,
+ (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_VIEWX), 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);
uiButSetFlag(bt, UI_BUT_DRAG_LOCK);
@@ -611,7 +612,7 @@ 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,
+ (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_VIEWX), 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);
uiButSetFlag(bt, UI_BUT_DRAG_LOCK);
@@ -621,7 +622,7 @@ 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,
+ (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_SELECTX), 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);
uiButSetFlag(bt, UI_BUT_DRAG_LOCK);
@@ -635,14 +636,14 @@ 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,
+ (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_VIEWX), 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);
uiButSetFlag(bt, UI_BUT_DRAG_LOCK);
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,
+ (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_RENDERX), 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);
uiButSetFlag(bt, UI_BUT_DRAG_LOCK);
@@ -656,14 +657,14 @@ static void outliner_draw_restrictbuts(uiBlock *block, Scene *scene, ARegion *ar
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,
+ (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_VIEWX), 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);
uiButSetFlag(bt, UI_BUT_DRAG_LOCK);
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,
+ (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_SELECTX), 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);
@@ -676,14 +677,14 @@ static void outliner_draw_restrictbuts(uiBlock *block, Scene *scene, ARegion *ar
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,
+ (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_VIEWX), 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);
uiButSetFlag(bt, UI_BUT_DRAG_LOCK);
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,
+ (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_SELECTX), 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);
@@ -735,7 +736,7 @@ static void outliner_draw_rnabuts(uiBlock *block, Scene *scene, ARegion *ar, Spa
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,
+ uiDefAutoButR(block, ptr, prop, -1, "", ICON_NONE, sizex, te->ys, OL_RNA_COL_SIZEX,
UI_UNIT_Y - 1);
}
}
@@ -743,7 +744,7 @@ static void outliner_draw_rnabuts(uiBlock *block, Scene *scene, ARegion *ar, Spa
ptr = &te->rnaptr;
prop = te->directdata;
- uiDefAutoButR(block, ptr, prop, te->index, "", ICON_NONE, sizex, (int)te->ys, OL_RNA_COL_SIZEX,
+ uiDefAutoButR(block, ptr, prop, te->index, "", ICON_NONE, sizex, te->ys, OL_RNA_COL_SIZEX,
UI_UNIT_Y - 1);
}
}
@@ -811,7 +812,7 @@ static uiBlock *operator_search_menu(bContext *C, ARegion *ar, void *arg_kmi)
uiBlockSetDirection(block, UI_DOWN);
uiEndBlock(C, block);
- event = *(win->eventstate); /* XXX huh huh? make api call */
+ wm_event_init_from_window(win, &event);
event.type = EVT_BUT_OPEN;
event.val = KM_PRESS;
event.customdata = but;
@@ -960,7 +961,7 @@ 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,
+ uiDefBlockBut(block, operator_search_menu, kmi, "", xstart, te->ys + 1, butw1, UI_UNIT_Y - 1,
TIP_("Assign new Operator"));
}
xstart += butw1 + 10;
@@ -969,7 +970,7 @@ 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,
+ but = uiDefButS(block, MENU, 0, str, xstart, 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;
@@ -977,48 +978,48 @@ static void outliner_draw_keymapbuts(uiBlock *block, ARegion *ar, SpaceOops *soo
/* 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,
+ uiDefKeyevtButS(block, 0, "", xstart, 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,
+ uiDefButS(block, MENU, 0, str, xstart, 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,
+ uiDefButS(block, MENU, 0, str, xstart, 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,
+ uiDefButS(block, MENU, 0, str, xstart, 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, IFACE_("Shift"), xstart, (int)te->ys + 1, butw3 + 5, UI_UNIT_Y - 1,
+ uiDefButS(block, OPTION, 0, IFACE_("Shift"), xstart, 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,
+ uiDefButS(block, OPTION, 0, IFACE_("Ctrl"), xstart, 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,
+ uiDefButS(block, OPTION, 0, IFACE_("Alt"), xstart, 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,
+ uiDefButS(block, OPTION, 0, IFACE_("OS"), xstart, 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,
+ uiDefKeyevtButS(block, 0, "", xstart, 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, IFACE_("(RNA property)"), xstart, (int)te->ys + 1, butw2, UI_UNIT_Y - 1,
+ uiDefBut(block, LABEL, 0, IFACE_("(RNA property)"), xstart, te->ys + 1, butw2, UI_UNIT_Y - 1,
NULL, 0, 0, 0, 0, "");
xstart += butw2;
}
@@ -1064,7 +1065,7 @@ static void outliner_buttons(const bContext *C, uiBlock *block, ARegion *ar, Spa
spx = te->xs + 1.8f * UI_UNIT_X;
if (spx + dx + 0.5f * UI_UNIT_X > ar->v2d.cur.xmax) dx = ar->v2d.cur.xmax - spx - 0.5f * UI_UNIT_X;
- bt = uiDefBut(block, TEX, OL_NAMEBUTTON, "", spx, (int)te->ys, dx + UI_UNIT_X, UI_UNIT_Y - 1, (void *)te->name,
+ bt = uiDefBut(block, TEX, OL_NAMEBUTTON, "", spx, te->ys, dx + UI_UNIT_X, UI_UNIT_Y - 1, (void *)te->name,
1.0, (float)len, 0, 0, "");
uiButSetRenameFunc(bt, namebutton_cb, tselem);
@@ -1440,8 +1441,8 @@ static void outliner_draw_iconrow(bContext *C, uiBlock *block, Scene *scene, Spa
}
tselem_draw_icon(block, xmax, (float)*offsx, (float)ys, tselem, te, 0.5f);
- te->xs = (float)*offsx;
- te->ys = (float)ys;
+ te->xs = *offsx;
+ te->ys = ys;
te->xend = (short)*offsx + UI_UNIT_X;
te->flag |= TE_ICONROW; // for click
@@ -1456,13 +1457,13 @@ static void outliner_draw_iconrow(bContext *C, uiBlock *block, Scene *scene, Spa
}
/* closed tree element */
-static void outliner_set_coord_tree_element(SpaceOops *soops, TreeElement *te, int startx, int *starty)
+static void outliner_set_coord_tree_element(SpaceOops *soops, TreeElement *te, int startx, int starty)
{
TreeElement *ten;
/* store coord and continue, we need coordinates for elements outside view too */
- te->xs = (float)startx;
- te->ys = (float)(*starty);
+ te->xs = startx;
+ te->ys = starty;
for (ten = te->subtree.first; ten; ten = ten->next) {
outliner_set_coord_tree_element(soops, ten, startx + UI_UNIT_X, starty);
@@ -1656,8 +1657,8 @@ static void outliner_draw_tree_element(bContext *C, uiBlock *block, Scene *scene
}
}
/* store coord and continue, we need coordinates for elements outside view too */
- te->xs = (float)startx;
- te->ys = (float)*starty;
+ te->xs = startx;
+ te->ys = *starty;
te->xend = startx + offsx;
if (TSELEM_OPEN(tselem, soops)) {
@@ -1668,7 +1669,7 @@ static void outliner_draw_tree_element(bContext *C, uiBlock *block, Scene *scene
}
else {
for (ten = te->subtree.first; ten; ten = ten->next)
- outliner_set_coord_tree_element(soops, te, startx, starty);
+ outliner_set_coord_tree_element(soops, ten, startx, *starty);
*starty -= UI_UNIT_Y;
}
diff --git a/source/blender/editors/space_outliner/outliner_edit.c b/source/blender/editors/space_outliner/outliner_edit.c
index 0161f53e690..1e9b681197c 100644
--- a/source/blender/editors/space_outliner/outliner_edit.c
+++ b/source/blender/editors/space_outliner/outliner_edit.c
@@ -618,7 +618,7 @@ static int outliner_show_active_exec(bContext *C, wmOperator *UNUSED(op))
te = outliner_find_id(so, &so->tree, (ID *)OBACT);
if (te) {
/* make te->ys center of view */
- ytop = (int)(te->ys + BLI_rcti_size_y(&v2d->mask) / 2);
+ ytop = te->ys + BLI_rcti_size_y(&v2d->mask) / 2;
if (ytop > 0) ytop = 0;
v2d->cur.ymax = (float)ytop;
@@ -984,7 +984,7 @@ static int ed_operator_outliner_datablocks_active(bContext *C)
* NOTE: the caller must zero-out all values of the pointers that it passes here first, as
* this function does not do that yet
*/
-static void tree_element_to_path(SpaceOops *soops, TreeElement *te, TreeStoreElem *tselem,
+static void tree_element_to_path(TreeElement *te, TreeStoreElem *tselem,
ID **id, char **path, int *array_index, short *flag, short *UNUSED(groupmode))
{
ListBase hierarchy = {NULL, NULL};
@@ -1152,7 +1152,7 @@ static void do_outliner_drivers_editop(SpaceOops *soops, ListBase *tree, ReportL
RNA_property_animateable(&te->rnaptr, te->directdata))
{
/* get id + path + index info from the selected element */
- tree_element_to_path(soops, te, tselem,
+ tree_element_to_path(te, tselem,
&id, &path, &array_index, &flag, &groupmode);
}
@@ -1333,7 +1333,7 @@ static void do_outliner_keyingset_editop(SpaceOops *soops, KeyingSet *ks, ListBa
RNA_property_animateable(&te->rnaptr, te->directdata))
{
/* get id + path + index info from the selected element */
- tree_element_to_path(soops, te, tselem,
+ tree_element_to_path(te, tselem,
&id, &path, &array_index, &flag, &groupmode);
}
@@ -1648,26 +1648,29 @@ void OUTLINER_OT_parent_drop(wmOperatorType *ot)
RNA_def_enum(ot->srna, "type", prop_make_parent_types, 0, "Type", "");
}
+static int outliner_parenting_poll(bContext *C)
+{
+ SpaceOops *soops = CTX_wm_space_outliner(C);
+
+ if (soops) {
+ return ELEM4(soops->outlinevis, SO_ALL_SCENES, SO_CUR_SCENE, SO_VISIBLE, SO_GROUPS);
+ }
+
+ return FALSE;
+}
+
static int parent_clear_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
Main *bmain = CTX_data_main(C);
- Scene *scene = NULL;
Object *ob = NULL;
SpaceOops *soops = CTX_wm_space_outliner(C);
- TreeElement *te;
char obname[MAX_ID_NAME];
RNA_string_get(op->ptr, "dragged_obj", obname);
ob = (Object *)BKE_libblock_find_name(ID_OB, obname);
/* search forwards to find the object */
- te = outliner_find_id(soops, &soops->tree, (ID *)ob);
- /* then search backwards to get the scene */
- scene = (Scene *)outliner_search_back(soops, te, ID_SCE);
-
- if (scene == NULL) {
- return OPERATOR_CANCELLED;
- }
+ outliner_find_id(soops, &soops->tree, (ID *)ob);
ED_object_parent_clear(ob, RNA_enum_get(op->ptr, "type"));
@@ -1687,7 +1690,7 @@ void OUTLINER_OT_parent_clear(wmOperatorType *ot)
/* api callbacks */
ot->invoke = parent_clear_invoke;
- ot->poll = ED_operator_outliner_active;
+ ot->poll = outliner_parenting_poll;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
diff --git a/source/blender/editors/space_outliner/outliner_intern.h b/source/blender/editors/space_outliner/outliner_intern.h
index fe07a7dae9f..5aaf8b5430b 100644
--- a/source/blender/editors/space_outliner/outliner_intern.h
+++ b/source/blender/editors/space_outliner/outliner_intern.h
@@ -48,15 +48,15 @@ struct Object;
typedef struct TreeElement {
struct TreeElement *next, *prev, *parent;
ListBase subtree;
- float xs, ys; // do selection
- int store_index; // offset in tree store
- short flag; // flag for non-saved stuff
- short index; // index for data arrays
- short idcode; // from TreeStore id
- short xend; // width of item display, for select
+ int xs, ys; // do selection
+ TreeStoreElem *store_elem; // element in tree store
+ short flag; // flag for non-saved stuff
+ short index; // index for data arrays
+ short idcode; // from TreeStore id
+ short xend; // width of item display, for select
const char *name;
- void *directdata; // Armature Bones, Base, Sequence, Strip...
- PointerRNA rnaptr; // RNA Pointer
+ void *directdata; // Armature Bones, Base, Sequence, Strip...
+ PointerRNA rnaptr; // RNA Pointer
} TreeElement;
/* TreeElement->flag */
@@ -111,7 +111,7 @@ typedef struct TreeElement {
/* get TreeStoreElem associated with a TreeElement
* < a: (TreeElement) tree element to find stored element for
*/
-#define TREESTORE(a) (soops->treestore->data + (a)->store_index)
+#define TREESTORE(a) ((a)->store_elem)
/* size constants */
#define OL_Y_OFFSET 2
@@ -150,6 +150,7 @@ typedef struct TreeElement {
/* outliner_tree.c ----------------------------------------------- */
+void outliner_rebuild_treehash(struct SpaceOops *soops);
void outliner_free_tree(ListBase *lb);
void outliner_cleanup_tree(struct SpaceOops *soops);
diff --git a/source/blender/editors/space_outliner/outliner_select.c b/source/blender/editors/space_outliner/outliner_select.c
index 9720d981e85..41ad75bb14f 100644
--- a/source/blender/editors/space_outliner/outliner_select.c
+++ b/source/blender/editors/space_outliner/outliner_select.c
@@ -282,7 +282,7 @@ static int tree_element_active_material(bContext *C, Scene *scene, SpaceOops *so
return 0;
}
-static int tree_element_active_texture(bContext *C, Scene *scene, SpaceOops *soops, TreeElement *te, int set)
+static int tree_element_active_texture(bContext *C, Scene *scene, SpaceOops *UNUSED(soops), TreeElement *te, int set)
{
TreeElement *tep;
TreeStoreElem /* *tselem,*/ *tselemp;
@@ -384,7 +384,7 @@ static int tree_element_active_camera(bContext *UNUSED(C), Scene *scene, SpaceOo
return scene->camera == ob;
}
-static int tree_element_active_world(bContext *C, Scene *scene, SpaceOops *soops, TreeElement *te, int set)
+static int tree_element_active_world(bContext *C, Scene *scene, SpaceOops *UNUSED(soops), TreeElement *te, int set)
{
TreeElement *tep;
TreeStoreElem *tselem = NULL;
diff --git a/source/blender/editors/space_outliner/outliner_tools.c b/source/blender/editors/space_outliner/outliner_tools.c
index fb56c5c6dfe..c1950e62817 100644
--- a/source/blender/editors/space_outliner/outliner_tools.c
+++ b/source/blender/editors/space_outliner/outliner_tools.c
@@ -45,6 +45,7 @@
#include "BLI_blenlib.h"
#include "BLI_utildefines.h"
+#include "BLI_ghash.h"
#include "BKE_animsys.h"
#include "BKE_context.h"
@@ -298,13 +299,17 @@ static void object_delete_cb(bContext *C, Scene *scene, TreeElement *te,
if (base == NULL)
base = BKE_scene_base_find(scene, (Object *)tselem->id);
if (base) {
+ SpaceOops *soops = CTX_wm_space_outliner(C);
+
// check also library later
if (scene->obedit == base->object)
ED_object_editmode_exit(C, EM_FREEDATA | EM_FREEUNDO | EM_WAITCURSOR | EM_DO_UNDO);
ED_base_object_free_and_unlink(CTX_data_main(C), scene, base);
te->directdata = NULL;
+ BLI_ghash_remove(soops->treehash, tselem, NULL, NULL);
tselem->id = NULL;
+ BLI_ghash_insert(soops->treehash, tselem, tselem);
}
}
@@ -683,6 +688,10 @@ static int outliner_object_operation_exec(bContext *C, wmOperator *op)
outliner_do_object_operation(C, scene, soops, &soops->tree, item_rename_cb);
str = "Rename Object";
}
+ else {
+ BLI_assert(0);
+ return OPERATOR_CANCELLED;
+ }
ED_undo_push(C, str);
diff --git a/source/blender/editors/space_outliner/outliner_tree.c b/source/blender/editors/space_outliner/outliner_tree.c
index 7d3ec148662..514bfc43ac7 100644
--- a/source/blender/editors/space_outliner/outliner_tree.c
+++ b/source/blender/editors/space_outliner/outliner_tree.c
@@ -63,6 +63,8 @@
#include "BLI_blenlib.h"
#include "BLI_utildefines.h"
#include "BLI_math.h"
+#include "BLI_ghash.h"
+#include "BLI_mempool.h"
#include "BLF_translation.h"
@@ -84,114 +86,131 @@
#include "outliner_intern.h"
/* ********************************************************* */
-/* Defines */
-
-#define TS_CHUNK 128
-
-/* ********************************************************* */
/* Persistent Data */
static void outliner_storage_cleanup(SpaceOops *soops)
{
- TreeStore *ts = soops->treestore;
+ BLI_mempool *ts = soops->treestore;
if (ts) {
TreeStoreElem *tselem;
- int a, unused = 0;
+ int unused = 0;
/* each element used once, for ID blocks with more users to have each a treestore */
- for (a = 0, tselem = ts->data; a < ts->usedelem; a++, tselem++) tselem->used = 0;
+ BLI_mempool_iter iter;
+
+ BLI_mempool_iternew(ts, &iter);
+ while ((tselem = BLI_mempool_iterstep(&iter))) {
+ tselem->used = 0;
+ }
/* cleanup only after reading file or undo step, and always for
* RNA datablocks view in order to save memory */
if (soops->storeflag & SO_TREESTORE_CLEANUP) {
-
- for (a = 0, tselem = ts->data; a < ts->usedelem; a++, tselem++) {
+ BLI_mempool_iternew(ts, &iter);
+ while ((tselem = BLI_mempool_iterstep(&iter))) {
if (tselem->id == NULL) unused++;
}
if (unused) {
- if (ts->usedelem == unused) {
- MEM_freeN(ts->data);
- ts->data = NULL;
- ts->usedelem = ts->totelem = 0;
+ if (BLI_mempool_count(ts) == unused) {
+ BLI_mempool_destroy(ts);
+ soops->treestore = NULL;
+
+ if (soops->treehash) {
+ BLI_ghash_free(soops->treehash, NULL, NULL);
+ soops->treehash = NULL;
+ }
}
else {
- TreeStoreElem *tsnewar, *tsnew;
-
- tsnew = tsnewar = MEM_mallocN((ts->usedelem - unused) * sizeof(TreeStoreElem), "new tselem");
- for (a = 0, tselem = ts->data; a < ts->usedelem; a++, tselem++) {
+ TreeStoreElem *tsenew;
+ BLI_mempool *new_ts = BLI_mempool_create(sizeof(TreeStoreElem), BLI_mempool_count(ts) - unused,
+ 512, BLI_MEMPOOL_ALLOW_ITER);
+ BLI_mempool_iternew(ts, &iter);
+ while ((tselem = BLI_mempool_iterstep(&iter))) {
if (tselem->id) {
- *tsnew = *tselem;
- tsnew++;
+ tsenew = BLI_mempool_alloc(new_ts);
+ *tsenew = *tselem;
+ }
+ }
+ BLI_mempool_destroy(ts);
+ soops->treestore = new_ts;
+
+ if (soops->treehash) {
+ /* update hash table to fix broken pointers */
+ BLI_ghash_clear(soops->treehash, NULL, NULL);
+ BLI_mempool_iternew(soops->treestore, &iter);
+ while ((tselem = BLI_mempool_iterstep(&iter))) {
+ BLI_ghash_insert(soops->treehash, tselem, tselem);
}
}
- MEM_freeN(ts->data);
- ts->data = tsnewar;
- ts->usedelem -= unused;
- ts->totelem = ts->usedelem;
}
}
}
}
}
-/* XXX - THIS FUNCTION IS INCREDIBLY SLOW
- * ... it can bring blenders tools and viewport to a grinding halt because of searching
- * for duplicate items every times they are added.
- *
- * TODO (possible speedups)
- * - use a hash for duplicate (could even store a hash per type)
- * - use mempool for TreeElements
- * */
+static unsigned int tse_hash(const void *ptr)
+{
+ const TreeStoreElem *tse = (const TreeStoreElem *)ptr;
+ unsigned int hash;
+ BLI_assert(tse->type || !tse->nr);
+ hash = BLI_ghashutil_inthash(SET_INT_IN_POINTER((tse->nr << 16) + tse->type));
+ hash ^= BLI_ghashutil_inthash(tse->id);
+ return hash;
+}
+
+static int tse_cmp(const void *a, const void *b)
+{
+ const TreeStoreElem *tse_a = (const TreeStoreElem *)a;
+ const TreeStoreElem *tse_b = (const TreeStoreElem *)b;
+ return tse_a->type != tse_b->type || tse_a->nr != tse_b->nr || tse_a->id != tse_b->id;
+}
+
static void check_persistent(SpaceOops *soops, TreeElement *te, ID *id, short type, short nr)
{
- TreeStore *ts;
- TreeStoreElem *tselem;
- int a;
+ /* When treestore comes directly from readfile.c, treehash is empty;
+ * In this case we don't want to get TSE_CLOSED while adding elements one by one,
+ * that is why this function restores treehash */
+ bool restore_treehash = (soops->treestore && !soops->treehash);
+ TreeStoreElem *tselem, elem_template;
- /* case 1; no TreeStore */
if (soops->treestore == NULL) {
- soops->treestore = MEM_callocN(sizeof(TreeStore), "treestore");
+ /* if treestore was not created in readfile.c, create it here */
+ soops->treestore = BLI_mempool_create(sizeof(TreeStoreElem), 1, 512, BLI_MEMPOOL_ALLOW_ITER);
}
- ts = soops->treestore;
-
- /* check if 'te' is in treestore */
- tselem = ts->data;
- for (a = 0; a < ts->usedelem; a++, tselem++) {
- if ((tselem->used == 0) && (tselem->type == type) && (tselem->id == id)) {
- if ((type == 0) || (tselem->nr == nr)) {
- te->store_index = a;
- tselem->used = 1;
- return;
- }
- }
+ if (soops->treehash == NULL) {
+ soops->treehash = BLI_ghash_new(tse_hash, tse_cmp, "treehash");
}
- /* add 1 element to treestore */
- if (ts->usedelem == ts->totelem) {
- TreeStoreElem *tsnew;
-
- tsnew = MEM_mallocN((ts->totelem + TS_CHUNK) * sizeof(TreeStoreElem), "treestore data");
- if (ts->data) {
- memcpy(tsnew, ts->data, ts->totelem * sizeof(TreeStoreElem));
- MEM_freeN(ts->data);
+ if (restore_treehash) {
+ BLI_mempool_iter iter;
+ BLI_mempool_iternew(soops->treestore, &iter);
+ while ((tselem = BLI_mempool_iterstep(&iter))) {
+ BLI_ghash_insert(soops->treehash, tselem, tselem);
}
- ts->data = tsnew;
- ts->totelem += TS_CHUNK;
}
-
- tselem = ts->data + ts->usedelem;
-
+
+ /* check if 'te' is in treestore */
+ elem_template.type = type;
+ elem_template.nr = type ? nr : 0; // we're picky! :)
+ elem_template.id = id;
+ tselem = BLI_ghash_lookup(soops->treehash, &elem_template);
+ if (tselem && !tselem->used) {
+ te->store_elem = tselem;
+ tselem->used = 1;
+ return;
+ }
+
+ /* add 1 element to treestore */
+ tselem = BLI_mempool_alloc(soops->treestore);
tselem->type = type;
- if (type) tselem->nr = nr; // we're picky! :)
- else tselem->nr = 0;
+ tselem->nr = type ? nr : 0;
tselem->id = id;
tselem->used = 0;
tselem->flag = TSE_CLOSED;
- te->store_index = ts->usedelem;
-
- ts->usedelem++;
+ te->store_elem = tselem;
+ BLI_ghash_insert(soops->treehash, tselem, tselem);
}
/* ********************************************************* */
@@ -216,15 +235,14 @@ void outliner_cleanup_tree(SpaceOops *soops)
outliner_storage_cleanup(soops);
}
-/* Find ith item from the treestore */
-static TreeElement *outliner_find_tree_element(ListBase *lb, int store_index)
+/* Find specific item from the treestore */
+static TreeElement *outliner_find_tree_element(ListBase *lb, TreeStoreElem *store_elem)
{
- TreeElement *te = lb->first, *tes;
- while (te) {
- if (te->store_index == store_index) return te;
- tes = outliner_find_tree_element(&te->subtree, store_index);
+ TreeElement *te, *tes;
+ for (te = lb->first; te; te = te->next) {
+ if (te->store_elem == store_elem) return te;
+ tes = outliner_find_tree_element(&te->subtree, store_elem);
if (tes) return tes;
- te = te->next;
}
return NULL;
}
@@ -232,23 +250,18 @@ static TreeElement *outliner_find_tree_element(ListBase *lb, int store_index)
/* tse is not in the treestore, we use its contents to find a match */
TreeElement *outliner_find_tse(SpaceOops *soops, TreeStoreElem *tse)
{
- TreeStore *ts = soops->treestore;
- TreeStoreElem *tselem;
- int a;
-
+ GHash *th = soops->treehash;
+ TreeStoreElem *tselem, tselem_template;
+
if (tse->id == NULL) return NULL;
/* check if 'tse' is in treestore */
- tselem = ts->data;
- for (a = 0; a < ts->usedelem; a++, tselem++) {
- if ((tse->type == 0 && tselem->type == 0) || (tselem->type == tse->type && tselem->nr == tse->nr)) {
- if (tselem->id == tse->id) {
- break;
- }
- }
- }
+ tselem_template.id = tse->id;
+ tselem_template.type = tse->type;
+ tselem_template.nr = tse->type ? tse->nr : 0;
+ tselem = BLI_ghash_lookup(th, &tselem_template);
if (tselem)
- return outliner_find_tree_element(&soops->tree, a);
+ return outliner_find_tree_element(&soops->tree, tselem);
return NULL;
}
@@ -274,7 +287,7 @@ TreeElement *outliner_find_id(SpaceOops *soops, ListBase *lb, ID *id)
}
-ID *outliner_search_back(SpaceOops *soops, TreeElement *te, short idcode)
+ID *outliner_search_back(SpaceOops *UNUSED(soops), TreeElement *te, short idcode)
{
TreeStoreElem *tselem;
te = te->parent;
@@ -420,7 +433,7 @@ static void outliner_add_scene_contents(SpaceOops *soops, ListBase *lb, Scene *s
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;
- tenlay->directdata = &srl->passflag;
+ tenlay->directdata = &srl->layflag;
if (srl->light_override)
outliner_add_element(soops, &tenlay->subtree, srl->light_override, tenlay, TSE_LINKED_LAMP, 0);
@@ -804,7 +817,6 @@ static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *i
TreeElement *te;
TreeStoreElem *tselem;
ID *id = idv;
- int a = 0;
if (ELEM3(type, TSE_RNA_STRUCT, TSE_RNA_PROPERTY, TSE_RNA_ARRAY_ELEM)) {
id = ((PointerRNA *)idv)->id.data;
@@ -1084,7 +1096,7 @@ static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *i
te->name = km->idname;
if (TSELEM_OPEN(tselem, soops)) {
- a = 0;
+ int a = 0;
for (kmi = km->items.first; kmi; kmi = kmi->next, a++) {
const char *key = WM_key_event_string(kmi->type);
@@ -1131,7 +1143,7 @@ static int need_add_seq_dup(Sequence *seq)
{
Sequence *p;
- if ((!seq->strip) || (!seq->strip->stripdata) || (!seq->strip->stripdata->name))
+ if ((!seq->strip) || (!seq->strip->stripdata))
return(1);
/*
@@ -1140,7 +1152,7 @@ static int need_add_seq_dup(Sequence *seq)
*/
p = seq->prev;
while (p) {
- if ((!p->strip) || (!p->strip->stripdata) || (!p->strip->stripdata->name)) {
+ if ((!p->strip) || (!p->strip->stripdata)) {
p = p->prev;
continue;
}
@@ -1152,7 +1164,7 @@ static int need_add_seq_dup(Sequence *seq)
p = seq->next;
while (p) {
- if ((!p->strip) || (!p->strip->stripdata) || (!p->strip->stripdata->name)) {
+ if ((!p->strip) || (!p->strip->stripdata)) {
p = p->next;
continue;
}
@@ -1188,7 +1200,7 @@ static void outliner_add_seq_dup(SpaceOops *soops, Sequence *seq, TreeElement *t
/* Hierarchy --------------------------------------------- */
/* make sure elements are correctly nested */
-static void outliner_make_hierarchy(SpaceOops *soops, ListBase *lb)
+static void outliner_make_hierarchy(ListBase *lb)
{
TreeElement *te, *ten, *tep;
TreeStoreElem *tselem;
@@ -1490,7 +1502,7 @@ void outliner_build_tree(Main *mainvar, Scene *scene, SpaceOops *soops)
Object *ob;
TreeElement *te = NULL, *ten;
TreeStoreElem *tselem;
- int show_opened = (soops->treestore == NULL); /* on first view, we open scenes */
+ int show_opened = !soops->treestore || !BLI_mempool_count(soops->treestore); /* on first view, we open scenes */
/* Are we looking for something - we want to tag parents to filter child matches
* - NOT in datablocks view - searching all datablocks takes way too long to be useful
@@ -1562,7 +1574,7 @@ void outliner_build_tree(Main *mainvar, Scene *scene, SpaceOops *soops)
ten = outliner_add_element(soops, &te->subtree, base->object, te, 0, 0);
ten->directdata = base;
}
- outliner_make_hierarchy(soops, &te->subtree);
+ outliner_make_hierarchy(&te->subtree);
/* clear id.newid, to prevent objects be inserted in wrong scenes (parent in other scene) */
for (base = sce->base.first; base; base = base->next) base->object->id.newid = NULL;
}
@@ -1575,14 +1587,14 @@ void outliner_build_tree(Main *mainvar, Scene *scene, SpaceOops *soops)
ten = outliner_add_element(soops, &soops->tree, base->object, NULL, 0, 0);
ten->directdata = base;
}
- outliner_make_hierarchy(soops, &soops->tree);
+ outliner_make_hierarchy(&soops->tree);
}
else if (soops->outlinevis == SO_VISIBLE) {
for (base = scene->base.first; base; base = base->next) {
if (base->lay & scene->lay)
outliner_add_element(soops, &soops->tree, base->object, NULL, 0, 0);
}
- outliner_make_hierarchy(soops, &soops->tree);
+ outliner_make_hierarchy(&soops->tree);
}
else if (soops->outlinevis == SO_GROUPS) {
Group *group;
@@ -1596,7 +1608,7 @@ void outliner_build_tree(Main *mainvar, Scene *scene, SpaceOops *soops)
ten = outliner_add_element(soops, &te->subtree, go->ob, te, 0, 0);
ten->directdata = NULL; /* eh, why? */
}
- outliner_make_hierarchy(soops, &te->subtree);
+ outliner_make_hierarchy(&te->subtree);
/* clear id.newid, to prevent objects be inserted in wrong scenes (parent in other scene) */
for (go = group->gobject.first; go; go = go->next) go->ob->id.newid = NULL;
}
@@ -1611,7 +1623,7 @@ void outliner_build_tree(Main *mainvar, Scene *scene, SpaceOops *soops)
ten->directdata = base;
}
}
- outliner_make_hierarchy(soops, &soops->tree);
+ outliner_make_hierarchy(&soops->tree);
}
}
else if (soops->outlinevis == SO_SELECTED) {
@@ -1623,7 +1635,7 @@ void outliner_build_tree(Main *mainvar, Scene *scene, SpaceOops *soops)
}
}
}
- outliner_make_hierarchy(soops, &soops->tree);
+ outliner_make_hierarchy(&soops->tree);
}
else if (soops->outlinevis == SO_SEQUENCE) {
Sequence *seq;
diff --git a/source/blender/editors/space_outliner/space_outliner.c b/source/blender/editors/space_outliner/space_outliner.c
index 8da244b1db1..874852ee320 100644
--- a/source/blender/editors/space_outliner/space_outliner.c
+++ b/source/blender/editors/space_outliner/space_outliner.c
@@ -37,6 +37,8 @@
#include "BLI_blenlib.h"
#include "BLI_math.h"
#include "BLI_utildefines.h"
+#include "BLI_mempool.h"
+#include "BLI_ghash.h"
#include "BKE_context.h"
#include "BKE_screen.h"
@@ -142,6 +144,10 @@ static int outliner_parent_clear_poll(bContext *C, wmDrag *drag, const wmEvent *
UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &fmval[0], &fmval[1]);
+ if (!ELEM4(soops->outlinevis, SO_ALL_SCENES, SO_CUR_SCENE, SO_VISIBLE, SO_GROUPS)) {
+ return FALSE;
+ }
+
if (drag->type == WM_DRAG_ID) {
ID *id = (ID *)drag->poin;
if (GS(id->name) == ID_OB) {
@@ -426,10 +432,11 @@ static void outliner_free(SpaceLink *sl)
outliner_free_tree(&soutliner->tree);
if (soutliner->treestore) {
- if (soutliner->treestore->data) MEM_freeN(soutliner->treestore->data);
- MEM_freeN(soutliner->treestore);
+ BLI_mempool_destroy(soutliner->treestore);
+ }
+ if (soutliner->treehash) {
+ BLI_ghash_free(soutliner->treehash, NULL, NULL);
}
-
}
/* spacetype; init callback */
@@ -445,6 +452,7 @@ static SpaceLink *outliner_duplicate(SpaceLink *sl)
soutlinern->tree.first = soutlinern->tree.last = NULL;
soutlinern->treestore = NULL;
+ soutlinern->treehash = NULL;
return (SpaceLink *)soutlinern;
}
diff --git a/source/blender/editors/space_sequencer/sequencer_buttons.c b/source/blender/editors/space_sequencer/sequencer_buttons.c
index 197cc64dea4..36589984c78 100644
--- a/source/blender/editors/space_sequencer/sequencer_buttons.c
+++ b/source/blender/editors/space_sequencer/sequencer_buttons.c
@@ -76,7 +76,7 @@ void sequencer_buttons_register(ARegionType *art)
/* **************** operator to open/close properties view ************* */
-static int sequencer_properties(bContext *C, wmOperator *UNUSED(op))
+static int sequencer_properties_toggle_exec(bContext *C, wmOperator *UNUSED(op))
{
ScrArea *sa = CTX_wm_area(C);
ARegion *ar = sequencer_has_buttons_region(sa);
@@ -93,7 +93,7 @@ void SEQUENCER_OT_properties(wmOperatorType *ot)
ot->idname = "SEQUENCER_OT_properties";
ot->description = "Open sequencer properties panel";
- ot->exec = sequencer_properties;
+ ot->exec = sequencer_properties_toggle_exec;
ot->poll = ED_operator_sequencer_active;
/* flags */
diff --git a/source/blender/editors/space_sequencer/sequencer_edit.c b/source/blender/editors/space_sequencer/sequencer_edit.c
index c13dc118de5..955a9c78c56 100644
--- a/source/blender/editors/space_sequencer/sequencer_edit.c
+++ b/source/blender/editors/space_sequencer/sequencer_edit.c
@@ -2721,7 +2721,6 @@ static void seq_copy_del_sound(Scene *scene, Sequence *seq)
}
}
-/* TODO, validate scenes */
static int sequencer_copy_exec(bContext *C, wmOperator *op)
{
Scene *scene = CTX_data_scene(C);
@@ -2766,6 +2765,11 @@ static int sequencer_copy_exec(bContext *C, wmOperator *op)
for (seq = seqbase_clipboard.first; seq; seq = seq->next) {
seq_copy_del_sound(scene, seq);
}
+
+ /* duplicate pointers */
+ for (seq = seqbase_clipboard.first; seq; seq = seq->next) {
+ BKE_sequence_clipboard_pointers_store(seq);
+ }
}
return OPERATOR_FINISHED;
@@ -2790,11 +2794,12 @@ void SEQUENCER_OT_copy(wmOperatorType *ot)
static int sequencer_paste_exec(bContext *C, wmOperator *UNUSED(op))
{
+ Main *bmain = CTX_data_main(C);
Scene *scene = CTX_data_scene(C);
Editing *ed = BKE_sequencer_editing_get(scene, TRUE); /* create if needed */
ListBase nseqbase = {NULL, NULL};
int ofs;
- Sequence *iseq;
+ Sequence *iseq, *iseq_first;
ED_sequencer_deselect_all(scene);
ofs = scene->r.cfra - seqbase_clipboard_frame;
@@ -2805,19 +2810,33 @@ static int sequencer_paste_exec(bContext *C, wmOperator *UNUSED(op))
if (ofs) {
for (iseq = nseqbase.first; iseq; iseq = iseq->next) {
BKE_sequence_translate(scene, iseq, ofs);
- BKE_sequence_sound_init(scene, iseq);
}
}
- iseq = nseqbase.first;
+ for (iseq = nseqbase.first; iseq; iseq = iseq->next) {
+ BKE_sequence_clipboard_pointers_restore(iseq, bmain);
+ }
+
+ for (iseq = nseqbase.first; iseq; iseq = iseq->next) {
+ BKE_sequence_sound_init(scene, iseq);
+ }
+
+ iseq_first = nseqbase.first;
BLI_movelisttolist(ed->seqbasep, &nseqbase);
/* make sure the pasted strips have unique names between them */
- for (; iseq; iseq = iseq->next) {
+ for (iseq = iseq_first; iseq; iseq = iseq->next) {
BKE_sequencer_recursive_apply(iseq, apply_unique_name_cb, scene);
}
+ /* ensure pasted strips don't overlap */
+ for (iseq = iseq_first; iseq; iseq = iseq->next) {
+ if (BKE_sequence_test_overlap(ed->seqbasep, iseq)) {
+ BKE_sequence_base_shuffle(ed->seqbasep, iseq, scene);
+ }
+ }
+
WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
return OPERATOR_FINISHED;
diff --git a/source/blender/editors/space_time/space_time.c b/source/blender/editors/space_time/space_time.c
index f7116c01a72..ad761971200 100644
--- a/source/blender/editors/space_time/space_time.c
+++ b/source/blender/editors/space_time/space_time.c
@@ -420,6 +420,9 @@ static void time_listener(bScreen *UNUSED(sc), ScrArea *sa, wmNotifier *wmn)
case NC_SCENE:
{
switch (wmn->data) {
+ case ND_RENDER_RESULT:
+ ED_area_tag_redraw(sa);
+ break;
case ND_OB_ACTIVE:
case ND_FRAME:
ED_area_tag_refresh(sa);
@@ -559,6 +562,7 @@ static void time_main_area_listener(bScreen *UNUSED(sc), ScrArea *UNUSED(sa), AR
ED_region_tag_redraw(ar);
break;
}
+ break;
}
}
@@ -588,6 +592,7 @@ static void time_header_area_listener(bScreen *UNUSED(sc), ScrArea *UNUSED(sa),
case NC_SCENE:
{
switch (wmn->data) {
+ case ND_RENDER_RESULT:
case ND_OB_SELECT:
case ND_FRAME:
case ND_FRAME_RANGE:
diff --git a/source/blender/editors/space_view3d/drawarmature.c b/source/blender/editors/space_view3d/drawarmature.c
index fb20f082085..d3d8868520d 100644
--- a/source/blender/editors/space_view3d/drawarmature.c
+++ b/source/blender/editors/space_view3d/drawarmature.c
@@ -1485,7 +1485,7 @@ static void draw_dof_ellipse(float ax, float az)
z = staticSine[i];
px = 0.0f;
- for (j = 1; j < n - i + 1; j++) {
+ for (j = 1; j <= (n - i); j++) {
x = staticSine[j];
if (j == n - i) {
@@ -2060,20 +2060,10 @@ static void draw_pose_bones(Scene *scene, View3D *v3d, ARegion *ar, Base *base,
}
/* in editmode, we don't store the bone matrix... */
-static void get_matrix_editbone(EditBone *eBone, float bmat[4][4])
+static void get_matrix_editbone(EditBone *ebone, float bmat[4][4])
{
- float delta[3];
- float mat[3][3];
-
- /* Compose the parent transforms (i.e. their translations) */
- sub_v3_v3v3(delta, eBone->tail, eBone->head);
-
- eBone->length = (float)sqrt(delta[0] * delta[0] + delta[1] * delta[1] + delta[2] * delta[2]);
-
- vec_roll_to_mat3(delta, eBone->roll, mat);
- copy_m4_m3(bmat, mat);
-
- add_v3_v3(bmat[3], eBone->head);
+ ebone->length = len_v3v3(ebone->tail, ebone->head);
+ ED_armature_ebone_to_mat4(ebone, bmat);
}
static void draw_ebones(View3D *v3d, ARegion *ar, Object *ob, const short dt)
diff --git a/source/blender/editors/space_view3d/drawmesh.c b/source/blender/editors/space_view3d/drawmesh.c
index 767d4aca3a8..16423c60cac 100644
--- a/source/blender/editors/space_view3d/drawmesh.c
+++ b/source/blender/editors/space_view3d/drawmesh.c
@@ -77,7 +77,7 @@
/* user data structures for derived mesh callbacks */
typedef struct drawMeshFaceSelect_userData {
Mesh *me;
- BLI_bitmap edge_flags; /* pairs of edge options (visible, select) */
+ BLI_bitmap *edge_flags; /* pairs of edge options (visible, select) */
} drawMeshFaceSelect_userData;
typedef struct drawEMTFMapped_userData {
@@ -100,9 +100,9 @@ typedef struct drawTFace_userData {
BLI_INLINE int edge_vis_index(const int index) { return index * 2; }
BLI_INLINE int edge_sel_index(const int index) { return index * 2 + 1; }
-static BLI_bitmap get_tface_mesh_marked_edge_info(Mesh *me)
+static BLI_bitmap *get_tface_mesh_marked_edge_info(Mesh *me)
{
- BLI_bitmap bitmap_edge_flags = BLI_BITMAP_NEW(me->totedge * 2, __func__);
+ BLI_bitmap *bitmap_edge_flags = BLI_BITMAP_NEW(me->totedge * 2, __func__);
MPoly *mp;
MLoop *ml;
int i, j;
diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c
index dca1160b194..62e3f8471a3 100644
--- a/source/blender/editors/space_view3d/drawobject.c
+++ b/source/blender/editors/space_view3d/drawobject.c
@@ -2002,7 +2002,7 @@ static void drawSelectedVertices(DerivedMesh *dm, Mesh *me)
data.col[2] = act_col;
glBegin(GL_POINTS);
- dm->foreachMappedVert(dm, drawSelectedVertices__mapFunc, &data);
+ dm->foreachMappedVert(dm, drawSelectedVertices__mapFunc, &data, DM_FOREACH_NOP);
glEnd();
}
@@ -2068,7 +2068,7 @@ static void draw_dm_face_normals(BMEditMesh *em, Scene *scene, Object *ob, Deriv
calcDrawDMNormalScale(ob, &data);
glBegin(GL_LINES);
- dm->foreachMappedFaceCenter(dm, draw_dm_face_normals__mapFunc, &data);
+ dm->foreachMappedFaceCenter(dm, draw_dm_face_normals__mapFunc, &data, DM_FOREACH_USE_NORMAL);
glEnd();
}
@@ -2088,7 +2088,7 @@ static void draw_dm_face_centers(BMEditMesh *em, DerivedMesh *dm, char sel)
void *ptrs[2] = {em, &sel};
bglBegin(GL_POINTS);
- dm->foreachMappedFaceCenter(dm, draw_dm_face_centers__mapFunc, ptrs);
+ dm->foreachMappedFaceCenter(dm, draw_dm_face_centers__mapFunc, ptrs, DM_FOREACH_NOP);
bglEnd();
}
@@ -2133,7 +2133,7 @@ static void draw_dm_vert_normals(BMEditMesh *em, Scene *scene, Object *ob, Deriv
calcDrawDMNormalScale(ob, &data);
glBegin(GL_LINES);
- dm->foreachMappedVert(dm, draw_dm_vert_normals__mapFunc, &data);
+ dm->foreachMappedVert(dm, draw_dm_vert_normals__mapFunc, &data, DM_FOREACH_USE_NORMAL);
glEnd();
}
@@ -2204,7 +2204,7 @@ static void draw_dm_verts(BMEditMesh *em, DerivedMesh *dm, const char sel, BMVer
invert_m4(data.imat);
bglBegin(GL_POINTS);
- dm->foreachMappedVert(dm, draw_dm_verts__mapFunc, &data);
+ dm->foreachMappedVert(dm, draw_dm_verts__mapFunc, &data, DM_FOREACH_NOP);
bglEnd();
}
@@ -2534,7 +2534,7 @@ static void draw_dm_bweights(BMEditMesh *em, Scene *scene, DerivedMesh *dm)
if (data.cd_layer_offset != -1) {
glPointSize(UI_GetThemeValuef(TH_VERTEX_SIZE) + 2);
bglBegin(GL_POINTS);
- dm->foreachMappedVert(dm, draw_dm_bweights__mapFunc, &data);
+ dm->foreachMappedVert(dm, draw_dm_bweights__mapFunc, &data, DM_FOREACH_NOP);
bglEnd();
}
}
@@ -3094,8 +3094,8 @@ static void draw_em_fancy(Scene *scene, ARegion *ar, View3D *v3d,
BMVert *eve_act = NULL;
bool use_occlude_wire = (v3d->flag2 & V3D_OCCLUDE_WIRE) && (dt > OB_WIRE);
- // if (cageDM) BLI_assert(!(cageDM->dirty & DM_DIRTY_NORMALS));
- if (finalDM) BLI_assert(!(finalDM->dirty & DM_DIRTY_NORMALS));
+ // BLI_assert(!cageDM || !(cageDM->dirty & DM_DIRTY_NORMALS));
+ BLI_assert(!finalDM || !(finalDM->dirty & DM_DIRTY_NORMALS));
if (em->bm->selected.last) {
BMEditSelection *ese = em->bm->selected.last;
@@ -3132,9 +3132,10 @@ static void draw_em_fancy(Scene *scene, ARegion *ar, View3D *v3d,
}
else if (dt > OB_WIRE) {
if (use_occlude_wire) {
+ /* use the cageDM since it always overlaps the editmesh faces */
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
- finalDM->drawMappedFaces(finalDM, draw_em_fancy__setFaceOpts,
- GPU_enable_material, NULL, me->edit_btmesh, 0);
+ cageDM->drawMappedFaces(cageDM, draw_em_fancy__setFaceOpts,
+ GPU_enable_material, NULL, me->edit_btmesh, 0);
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
}
else if (check_object_draw_texture(scene, v3d, dt)) {
@@ -3851,8 +3852,8 @@ static void drawDispListsolid(ListBase *lb, Object *ob, const short dflag,
glEnd();
glEnable(GL_LIGHTING);
- break;
}
+ break;
case DL_SURF:
if (dl->index) {
@@ -6779,7 +6780,7 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, const short
cpack(0xffffff);
set_inverted_drawing(1);
- for (i = 0; i < (selend - selstart + 1); i++) {
+ for (i = 0; i <= (selend - selstart); i++) {
SelBox *sb = &(cu->selboxes[i]);
if (i < (selend - selstart)) {
@@ -7052,18 +7053,15 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, const short
mul_mat3_m4_v3(ob->imat, viewnormal);
normalize_v3(viewnormal);
- /* set dynamic boundaries to draw the volume */
- p0[0] = sds->p0[0] + sds->cell_size[0] * sds->res_min[0] + sds->obj_shift_f[0];
- p0[1] = sds->p0[1] + sds->cell_size[1] * sds->res_min[1] + sds->obj_shift_f[1];
- p0[2] = sds->p0[2] + sds->cell_size[2] * sds->res_min[2] + sds->obj_shift_f[2];
- p1[0] = sds->p0[0] + sds->cell_size[0] * sds->res_max[0] + sds->obj_shift_f[0];
- p1[1] = sds->p0[1] + sds->cell_size[1] * sds->res_max[1] + sds->obj_shift_f[1];
- p1[2] = sds->p0[2] + sds->cell_size[2] * sds->res_max[2] + sds->obj_shift_f[2];
-
- /* scale cube to global space to equalize volume slicing on all axises
+ /* set dynamic boundaries to draw the volume
+ * also scale cube to global space to equalize volume slicing on all axises
* (its scaled back before drawing) */
- mul_v3_v3(p0, ob->size);
- mul_v3_v3(p1, ob->size);
+ p0[0] = (sds->p0[0] + sds->cell_size[0] * sds->res_min[0] + sds->obj_shift_f[0]) * fabsf(ob->size[0]);
+ p0[1] = (sds->p0[1] + sds->cell_size[1] * sds->res_min[1] + sds->obj_shift_f[1]) * fabsf(ob->size[1]);
+ p0[2] = (sds->p0[2] + sds->cell_size[2] * sds->res_min[2] + sds->obj_shift_f[2]) * fabsf(ob->size[2]);
+ p1[0] = (sds->p0[0] + sds->cell_size[0] * sds->res_max[0] + sds->obj_shift_f[0]) * fabsf(ob->size[0]);
+ p1[1] = (sds->p0[1] + sds->cell_size[1] * sds->res_max[1] + sds->obj_shift_f[1]) * fabsf(ob->size[1]);
+ p1[2] = (sds->p0[2] + sds->cell_size[2] * sds->res_max[2] + sds->obj_shift_f[2]) * fabsf(ob->size[2]);
if (!sds->wt || !(sds->viewsettings & MOD_SMOKE_VIEW_SHOWBIG)) {
smd->domain->tex = NULL;
@@ -7255,23 +7253,19 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, const short
cob = BKE_constraints_make_evalob(scene, ob, NULL, CONSTRAINT_OBTYPE_OBJECT);
for (curcon = list->first; curcon; curcon = curcon->next) {
- bConstraintTypeInfo *cti = BKE_constraint_get_typeinfo(curcon);
- ListBase targets = {NULL, NULL};
- bConstraintTarget *ct;
-
- if (ELEM(cti->type, CONSTRAINT_TYPE_FOLLOWTRACK, CONSTRAINT_TYPE_OBJECTSOLVER)) {
+ if (ELEM(curcon->type, CONSTRAINT_TYPE_FOLLOWTRACK, CONSTRAINT_TYPE_OBJECTSOLVER)) {
/* special case for object solver and follow track constraints because they don't fill
* constraint targets properly (design limitation -- scene is needed for their target
* but it can't be accessed from get_targets callvack) */
Object *camob = NULL;
- if (cti->type == CONSTRAINT_TYPE_FOLLOWTRACK) {
+ if (curcon->type == CONSTRAINT_TYPE_FOLLOWTRACK) {
bFollowTrackConstraint *data = (bFollowTrackConstraint *)curcon->data;
camob = data->camera ? data->camera : scene->camera;
}
- else if (cti->type == CONSTRAINT_TYPE_OBJECTSOLVER) {
+ else if (curcon->type == CONSTRAINT_TYPE_OBJECTSOLVER) {
bObjectSolverConstraint *data = (bObjectSolverConstraint *)curcon->data;
camob = data->camera ? data->camera : scene->camera;
@@ -7286,26 +7280,33 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, const short
setlinestyle(0);
}
}
- else if ((curcon->flag & CONSTRAINT_EXPAND) && (cti->get_constraint_targets)) {
- cti->get_constraint_targets(curcon, &targets);
-
- for (ct = targets.first; ct; ct = ct->next) {
- /* calculate target's matrix */
- if (cti->get_target_matrix)
- cti->get_target_matrix(curcon, cob, ct, BKE_scene_frame_get(scene));
- else
- unit_m4(ct->matrix);
-
- setlinestyle(3);
- glBegin(GL_LINES);
- glVertex3fv(ct->matrix[3]);
- glVertex3fv(ob->obmat[3]);
- glEnd();
- setlinestyle(0);
+ else {
+ bConstraintTypeInfo *cti = BKE_constraint_get_typeinfo(curcon);
+
+ if ((cti && cti->get_constraint_targets) && (curcon->flag & CONSTRAINT_EXPAND)) {
+ ListBase targets = {NULL, NULL};
+ bConstraintTarget *ct;
+
+ cti->get_constraint_targets(curcon, &targets);
+
+ for (ct = targets.first; ct; ct = ct->next) {
+ /* calculate target's matrix */
+ if (cti->get_target_matrix)
+ cti->get_target_matrix(curcon, cob, ct, BKE_scene_frame_get(scene));
+ else
+ unit_m4(ct->matrix);
+
+ setlinestyle(3);
+ glBegin(GL_LINES);
+ glVertex3fv(ct->matrix[3]);
+ glVertex3fv(ob->obmat[3]);
+ glEnd();
+ setlinestyle(0);
+ }
+
+ if (cti->flush_constraint_targets)
+ cti->flush_constraint_targets(curcon, &targets, 1);
}
-
- if (cti->flush_constraint_targets)
- cti->flush_constraint_targets(curcon, &targets, 1);
}
}
@@ -7358,7 +7359,7 @@ static void bbs_obmode_mesh_verts(Object *ob, DerivedMesh *dm, int offset)
data.offset = (void *)(intptr_t) offset;
glPointSize(UI_GetThemeValuef(TH_VERTEX_SIZE));
bglBegin(GL_POINTS);
- dm->foreachMappedVert(dm, bbs_obmode_mesh_verts__mapFunc, &data);
+ dm->foreachMappedVert(dm, bbs_obmode_mesh_verts__mapFunc, &data, DM_FOREACH_NOP);
bglEnd();
glPointSize(1.0);
}
@@ -7381,7 +7382,7 @@ static void bbs_mesh_verts(BMEditMesh *em, DerivedMesh *dm, int offset)
glPointSize(UI_GetThemeValuef(TH_VERTEX_SIZE));
bglBegin(GL_POINTS);
- dm->foreachMappedVert(dm, bbs_mesh_verts__mapFunc, ptrs);
+ dm->foreachMappedVert(dm, bbs_mesh_verts__mapFunc, ptrs, DM_FOREACH_NOP);
bglEnd();
glPointSize(1.0);
}
@@ -7447,7 +7448,7 @@ static void bbs_mesh_solid_EM(BMEditMesh *em, Scene *scene, View3D *v3d,
glPointSize(UI_GetThemeValuef(TH_FACEDOT_SIZE));
bglBegin(GL_POINTS);
- dm->foreachMappedFaceCenter(dm, bbs_mesh_solid__drawCenter, ptrs);
+ dm->foreachMappedFaceCenter(dm, bbs_mesh_solid__drawCenter, ptrs, DM_FOREACH_NOP);
bglEnd();
}
diff --git a/source/blender/editors/space_view3d/drawvolume.c b/source/blender/editors/space_view3d/drawvolume.c
index 8323e7de9a4..542ed7af0e6 100644
--- a/source/blender/editors/space_view3d/drawvolume.c
+++ b/source/blender/editors/space_view3d/drawvolume.c
@@ -461,7 +461,9 @@ void draw_smoke_volume(SmokeDomainSettings *sds, Object *ob,
glTexCoord3d((points[i * 3 + 0] - min[0]) * cor[0] / size[0],
(points[i * 3 + 1] - min[1]) * cor[1] / size[1],
(points[i * 3 + 2] - min[2]) * cor[2] / size[2]);
- glVertex3f(points[i * 3 + 0] / ob->size[0], points[i * 3 + 1] / ob->size[1], points[i * 3 + 2] / ob->size[2]);
+ glVertex3f(points[i * 3 + 0] / fabsf(ob->size[0]),
+ points[i * 3 + 1] / fabsf(ob->size[1]),
+ points[i * 3 + 2] / fabsf(ob->size[2]));
}
glEnd();
@@ -474,7 +476,9 @@ void draw_smoke_volume(SmokeDomainSettings *sds, Object *ob,
glTexCoord3d((points[i * 3 + 0] - min[0]) * cor[0] / size[0],
(points[i * 3 + 1] - min[1]) * cor[1] / size[1],
(points[i * 3 + 2] - min[2]) * cor[2] / size[2]);
- glVertex3f(points[i * 3 + 0] / ob->size[0], points[i * 3 + 1] / ob->size[1], points[i * 3 + 2] / ob->size[2]);
+ glVertex3f(points[i * 3 + 0] / fabsf(ob->size[0]),
+ points[i * 3 + 1] / fabsf(ob->size[1]),
+ points[i * 3 + 2] / fabsf(ob->size[2]));
}
glEnd();
}
diff --git a/source/blender/editors/space_view3d/space_view3d.c b/source/blender/editors/space_view3d/space_view3d.c
index 92bf8214336..6c61c2af816 100644
--- a/source/blender/editors/space_view3d/space_view3d.c
+++ b/source/blender/editors/space_view3d/space_view3d.c
@@ -826,6 +826,7 @@ static void view3d_main_area_listener(bScreen *sc, ScrArea *sa, ARegion *ar, wmN
if (rv3d->persp == RV3D_CAMOB) {
ED_region_tag_redraw(ar);
}
+ break;
}
}
break;
@@ -881,8 +882,8 @@ static void view3d_main_area_listener(bScreen *sc, ScrArea *sa, ARegion *ar, wmN
/* screen was changed, need to update used layers due to NC_SCENE|ND_LAYER_CONTENT */
/* updates used layers only for View3D in active screen */
if (wmn->reference) {
- bScreen *sc = wmn->reference;
- view3d_recalc_used_layers(ar, wmn, sc->scene);
+ bScreen *sc_ref = wmn->reference;
+ view3d_recalc_used_layers(ar, wmn, sc_ref->scene);
}
ED_region_tag_redraw(ar);
break;
@@ -1141,17 +1142,17 @@ const char *view3d_context_dir[] = {
static int view3d_context(const bContext *C, const char *member, bContextDataResult *result)
{
- View3D *v3d = CTX_wm_view3d(C);
- Scene *scene = CTX_data_scene(C);
- Base *base;
/* fallback to the scene layer, allows duplicate and other object operators to run outside the 3d view */
- unsigned int lay = v3d ? v3d->lay : scene->lay;
if (CTX_data_dir(member)) {
CTX_data_dir_set(result, view3d_context_dir);
}
else if (CTX_data_equals(member, "selected_objects") || CTX_data_equals(member, "selected_bases")) {
- int selected_objects = CTX_data_equals(member, "selected_objects");
+ View3D *v3d = CTX_wm_view3d(C);
+ Scene *scene = CTX_data_scene(C);
+ const unsigned int lay = v3d ? v3d->lay : scene->lay;
+ Base *base;
+ const bool selected_objects = CTX_data_equals(member, "selected_objects");
for (base = scene->base.first; base; base = base->next) {
if ((base->flag & SELECT) && (base->lay & lay)) {
@@ -1167,7 +1168,11 @@ static int view3d_context(const bContext *C, const char *member, bContextDataRes
return 1;
}
else if (CTX_data_equals(member, "selected_editable_objects") || CTX_data_equals(member, "selected_editable_bases")) {
- int selected_editable_objects = CTX_data_equals(member, "selected_editable_objects");
+ View3D *v3d = CTX_wm_view3d(C);
+ Scene *scene = CTX_data_scene(C);
+ const unsigned int lay = v3d ? v3d->lay : scene->lay;
+ Base *base;
+ const bool selected_editable_objects = CTX_data_equals(member, "selected_editable_objects");
for (base = scene->base.first; base; base = base->next) {
if ((base->flag & SELECT) && (base->lay & lay)) {
@@ -1185,7 +1190,11 @@ static int view3d_context(const bContext *C, const char *member, bContextDataRes
return 1;
}
else if (CTX_data_equals(member, "visible_objects") || CTX_data_equals(member, "visible_bases")) {
- int visible_objects = CTX_data_equals(member, "visible_objects");
+ View3D *v3d = CTX_wm_view3d(C);
+ Scene *scene = CTX_data_scene(C);
+ const unsigned int lay = v3d ? v3d->lay : scene->lay;
+ Base *base;
+ const bool visible_objects = CTX_data_equals(member, "visible_objects");
for (base = scene->base.first; base; base = base->next) {
if (base->lay & lay) {
@@ -1201,7 +1210,11 @@ static int view3d_context(const bContext *C, const char *member, bContextDataRes
return 1;
}
else if (CTX_data_equals(member, "selectable_objects") || CTX_data_equals(member, "selectable_bases")) {
- int selectable_objects = CTX_data_equals(member, "selectable_objects");
+ View3D *v3d = CTX_wm_view3d(C);
+ Scene *scene = CTX_data_scene(C);
+ const unsigned int lay = v3d ? v3d->lay : scene->lay;
+ Base *base;
+ const bool selectable_objects = CTX_data_equals(member, "selectable_objects");
for (base = scene->base.first; base; base = base->next) {
if (base->lay & lay) {
@@ -1217,6 +1230,9 @@ static int view3d_context(const bContext *C, const char *member, bContextDataRes
return 1;
}
else if (CTX_data_equals(member, "active_base")) {
+ View3D *v3d = CTX_wm_view3d(C);
+ Scene *scene = CTX_data_scene(C);
+ const unsigned int lay = v3d ? v3d->lay : scene->lay;
if (scene->basact && (scene->basact->lay & lay)) {
Object *ob = scene->basact->object;
/* if hidden but in edit mode, we still display, can happen with animation */
@@ -1227,6 +1243,9 @@ static int view3d_context(const bContext *C, const char *member, bContextDataRes
return 1;
}
else if (CTX_data_equals(member, "active_object")) {
+ View3D *v3d = CTX_wm_view3d(C);
+ Scene *scene = CTX_data_scene(C);
+ const unsigned int lay = v3d ? v3d->lay : scene->lay;
if (scene->basact && (scene->basact->lay & lay)) {
Object *ob = scene->basact->object;
if ((ob->restrictflag & OB_RESTRICT_VIEW) == 0 || (ob->mode & OB_MODE_EDIT))
diff --git a/source/blender/editors/space_view3d/view3d_buttons.c b/source/blender/editors/space_view3d/view3d_buttons.c
index 536bccfbe7a..75e7605df6b 100644
--- a/source/blender/editors/space_view3d/view3d_buttons.c
+++ b/source/blender/editors/space_view3d/view3d_buttons.c
@@ -95,8 +95,6 @@ typedef struct {
float ob_dims[3];
short link_scale;
float ve_median[NBR_TRANSFORM_PROPERTIES];
- int curdef;
- float *defweightp;
} TransformProperties;
/* Helper function to compute a median changed value,
@@ -154,17 +152,14 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float
#define L_WEIGHT 4
uiBlock *block = (layout) ? uiLayoutAbsoluteBlock(layout) : NULL;
- MDeformVert *dvert = NULL;
TransformProperties *tfp;
float median[NBR_TRANSFORM_PROPERTIES], ve_median[NBR_TRANSFORM_PROPERTIES];
int tot, totedgedata, totcurvedata, totlattdata, totskinradius, totcurvebweight;
bool has_meshdata = false;
- char defstr[320];
PointerRNA data_ptr;
fill_vn_fl(median, NBR_TRANSFORM_PROPERTIES, 0.0f);
tot = totedgedata = totcurvedata = totlattdata = totskinradius = totcurvebweight = 0;
- defstr[0] = '\0';
/* make sure we got storage */
if (v3d->properties_storage == NULL)
@@ -175,7 +170,7 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float
Mesh *me = ob->data;
BMEditMesh *em = me->edit_btmesh;
BMesh *bm = em->bm;
- BMVert *eve, *evedef = NULL;
+ BMVert *eve;
BMEdge *eed;
BMIter iter;
@@ -187,7 +182,6 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float
if (bm->totvertsel) {
BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) {
if (BM_elem_flag_test(eve, BM_ELEM_SELECT)) {
- evedef = eve;
tot++;
add_v3_v3(&median[LOC_X], eve->co);
@@ -226,33 +220,6 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float
totedgedata = bm->totedgesel;
}
- /* check for defgroups */
- if (evedef)
- dvert = CustomData_bmesh_get(&bm->vdata, evedef->head.data, CD_MDEFORMVERT);
- if (tot == 1 && dvert && dvert->totweight) {
- bDeformGroup *dg;
- int i, max = 1, init = 1;
- char str[320];
-
- for (i = 0; i < dvert->totweight; i++) {
- dg = BLI_findlink(&ob->defbase, dvert->dw[i].def_nr);
- if (dg) {
- max += BLI_snprintf(str, sizeof(str), "%s %%x%d|", dg->name, dvert->dw[i].def_nr);
- if (max < sizeof(str)) strcat(defstr, str);
- }
-
- if (tfp->curdef == dvert->dw[i].def_nr) {
- init = 0;
- tfp->defweightp = &dvert->dw[i].weight;
- }
- }
-
- if (init) { /* needs new initialized */
- tfp->curdef = dvert->dw[0].def_nr;
- tfp->defweightp = &dvert->dw[0].weight;
- }
- }
-
has_meshdata = (totedgedata || totskinradius);
}
else if (ob->type == OB_CURVE || ob->type == OB_SURF) {
@@ -1204,7 +1171,7 @@ void view3d_buttons_register(ARegionType *art)
BLI_addtail(&art->paneltypes, pt);
}
-static int view3d_properties(bContext *C, wmOperator *UNUSED(op))
+static int view3d_properties_toggle_exec(bContext *C, wmOperator *UNUSED(op))
{
ScrArea *sa = CTX_wm_area(C);
ARegion *ar = view3d_has_buttons_region(sa);
@@ -1221,7 +1188,7 @@ void VIEW3D_OT_properties(wmOperatorType *ot)
ot->description = "Toggles the properties panel display";
ot->idname = "VIEW3D_OT_properties";
- ot->exec = view3d_properties;
+ ot->exec = view3d_properties_toggle_exec;
ot->poll = ED_operator_view3d_active;
/* flags */
diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c
index 61532e75ee9..fa8d43b1756 100644
--- a/source/blender/editors/space_view3d/view3d_draw.c
+++ b/source/blender/editors/space_view3d/view3d_draw.c
@@ -350,18 +350,19 @@ static void drawgrid(UnitSettings *unit, ARegion *ar, View3D *v3d, const char **
}
}
else {
- short sublines = v3d->gridsubdiv;
+ const double sublines = v3d->gridsubdiv;
+ const float sublines_fl = v3d->gridsubdiv;
if (dx < GRID_MIN_PX_D) {
- rv3d->gridview *= sublines;
+ rv3d->gridview *= sublines_fl;
dx *= sublines;
if (dx < GRID_MIN_PX_D) {
- rv3d->gridview *= sublines;
+ rv3d->gridview *= sublines_fl;
dx *= sublines;
if (dx < GRID_MIN_PX_D) {
- rv3d->gridview *= sublines;
+ rv3d->gridview *= sublines_fl;
dx *= sublines;
if (dx < GRID_MIN_PX_D) {
/* pass */
@@ -389,10 +390,10 @@ static void drawgrid(UnitSettings *unit, ARegion *ar, View3D *v3d, const char **
}
else {
if (dx > (GRID_MIN_PX_D * 10.0)) { /* start blending in */
- rv3d->gridview /= sublines;
+ rv3d->gridview /= sublines_fl;
dx /= sublines;
if (dx > (GRID_MIN_PX_D * 10.0)) { /* start blending in */
- rv3d->gridview /= sublines;
+ rv3d->gridview /= sublines_fl;
dx /= sublines;
if (dx > (GRID_MIN_PX_D * 10.0)) {
UI_ThemeColor(TH_GRID);
@@ -494,6 +495,7 @@ static void drawfloor(Scene *scene, View3D *v3d, const char **grid_unit)
/* draw the Y axis and/or grid lines */
if (v3d->gridflag & V3D_SHOW_FLOOR) {
+ const int sublines = v3d->gridsubdiv;
float vert[4][3] = {{0.0f}};
unsigned char col_bg[3];
unsigned char col_grid_emphasise[3], col_grid_light[3];
@@ -517,7 +519,7 @@ static void drawfloor(Scene *scene, View3D *v3d, const char **grid_unit)
for (a = -gridlines; a <= gridlines; a++) {
const float line = a * grid_scale;
- const int is_emphasise = (a % 10) == 0;
+ const int is_emphasise = (a % sublines) == 0;
if (is_emphasise != prev_emphasise) {
glColor3ubv(is_emphasise ? col_grid_emphasise : col_grid_light);
@@ -531,8 +533,6 @@ static void drawfloor(Scene *scene, View3D *v3d, const char **grid_unit)
}
glDisableClientState(GL_VERTEX_ARRAY);
-
- GPU_print_error("sdsd");
}
/* draw the Z axis line */
@@ -1189,7 +1189,7 @@ static void drawviewborder(Scene *scene, ARegion *ar, View3D *v3d)
y4 = y1 + scene->r.border.ymax * (y2 - y1);
cpack(0x4040FF);
- glRectf(x3, y3, x4, y4);
+ glRecti(x3, y3, x4, y4);
}
/* safety border */
@@ -2953,10 +2953,8 @@ bool ED_view3d_calc_render_border(Scene *scene, View3D *v3d, ARegion *ar, rcti *
rect->ymax = v3d->render_border.ymax * ar->winy;
}
- rect->xmin = CLAMPIS(ar->winrct.xmin + rect->xmin, ar->winrct.xmin, ar->winrct.xmax);
- rect->ymin = CLAMPIS(ar->winrct.ymin + rect->ymin, ar->winrct.ymin, ar->winrct.ymax);
- rect->xmax = CLAMPIS(ar->winrct.xmin + rect->xmax, ar->winrct.xmin, ar->winrct.xmax);
- rect->ymax = CLAMPIS(ar->winrct.ymin + rect->ymax, ar->winrct.ymin, ar->winrct.ymax);
+ BLI_rcti_translate(rect, ar->winrct.xmin, ar->winrct.ymin);
+ BLI_rcti_isect(&ar->winrct, rect, rect);
return true;
}
@@ -3422,7 +3420,7 @@ static void view3d_main_area_draw_info(const bContext *C, ARegion *ar, const cha
setlinestyle(3);
cpack(0x4040FF);
- glRectf(v3d->render_border.xmin * ar->winx, v3d->render_border.ymin * ar->winy,
+ glRecti(v3d->render_border.xmin * ar->winx, v3d->render_border.ymin * ar->winy,
v3d->render_border.xmax * ar->winx, v3d->render_border.ymax * ar->winy);
setlinestyle(0);
diff --git a/source/blender/editors/space_view3d/view3d_edit.c b/source/blender/editors/space_view3d/view3d_edit.c
index bfc64d1d37a..7b8c197f3e6 100644
--- a/source/blender/editors/space_view3d/view3d_edit.c
+++ b/source/blender/editors/space_view3d/view3d_edit.c
@@ -3241,16 +3241,11 @@ static void axis_set_view(bContext *C, View3D *v3d, ARegion *ar,
align_active = false;
}
else {
- const float z_flip_quat[4] = {0.0f, 0.0f, 0.0f, 1.0f};
float obact_quat[4];
float twmat[3][3];
- /* flip the input, the end result being that an object
- * with no rotation behaves as if 'align_active' is off */
- mul_qt_qtqt(new_quat, new_quat, z_flip_quat);
-
/* same as transform manipulator when normal is set */
- ED_getTransformOrientationMatrix(C, twmat, false);
+ ED_getTransformOrientationMatrix(C, twmat, true);
mat3_to_quat(obact_quat, twmat);
invert_qt(obact_quat);
@@ -4205,28 +4200,27 @@ float ED_view3d_offset_distance(float mat[4][4], const float ofs[3], const float
*/
void ED_view3d_from_m4(float mat[4][4], float ofs[3], float quat[4], float *dist)
{
+ float nmat[3][3];
+
+ /* dist depends on offset */
+ BLI_assert(dist == NULL || ofs != NULL);
+
+ copy_m3_m4(nmat, mat);
+ normalize_m3(nmat);
+
/* Offset */
if (ofs)
negate_v3_v3(ofs, mat[3]);
/* Quat */
if (quat) {
- float imat[4][4];
- normalize_m4_m4(imat, mat);
- invert_m4(imat);
- mat4_to_quat(quat, imat);
+ float imat[3][3];
+ invert_m3_m3(imat, nmat);
+ mat3_to_quat(quat, imat);
}
- if (dist) {
- float nmat[3][3];
- float vec[3];
-
- vec[0] = 0.0f;
- vec[1] = 0.0f;
- vec[2] = -(*dist);
-
- copy_m3_m4(nmat, mat);
- normalize_m3(nmat);
+ if (ofs && dist) {
+ float vec[3] = {0.0f, 0.0f, -(*dist)};
mul_m3_v3(nmat, vec);
sub_v3_v3(ofs, vec);
diff --git a/source/blender/editors/space_view3d/view3d_iterators.c b/source/blender/editors/space_view3d/view3d_iterators.c
index 0490d8763d8..d13ab15d837 100644
--- a/source/blender/editors/space_view3d/view3d_iterators.c
+++ b/source/blender/editors/space_view3d/view3d_iterators.c
@@ -124,7 +124,7 @@ void meshobject_foreachScreenVert(
ED_view3d_clipping_local(vc->rv3d, vc->obedit->obmat); /* for local clipping lookups */
}
- dm->foreachMappedVert(dm, meshobject_foreachScreenVert__mapFunc, &data);
+ dm->foreachMappedVert(dm, meshobject_foreachScreenVert__mapFunc, &data, DM_FOREACH_NOP);
dm->release(dm);
}
@@ -166,7 +166,7 @@ void mesh_foreachScreenVert(
}
EDBM_index_arrays_ensure(vc->em, BM_VERT);
- dm->foreachMappedVert(dm, mesh_foreachScreenVert__mapFunc, &data);
+ dm->foreachMappedVert(dm, mesh_foreachScreenVert__mapFunc, &data, DM_FOREACH_NOP);
dm->release(dm);
}
@@ -262,7 +262,7 @@ void mesh_foreachScreenFace(
data.clip_flag = clip_flag;
EDBM_index_arrays_ensure(vc->em, BM_FACE);
- dm->foreachMappedFaceCenter(dm, mesh_foreachScreenFace__mapFunc, &data);
+ dm->foreachMappedFaceCenter(dm, mesh_foreachScreenFace__mapFunc, &data, DM_FOREACH_NOP);
dm->release(dm);
}
diff --git a/source/blender/editors/space_view3d/view3d_select.c b/source/blender/editors/space_view3d/view3d_select.c
index 16282b0d49c..19426ab2dfa 100644
--- a/source/blender/editors/space_view3d/view3d_select.c
+++ b/source/blender/editors/space_view3d/view3d_select.c
@@ -146,12 +146,13 @@ static void edbm_backbuf_check_and_select_verts(BMEditMesh *em, const bool selec
BMIter iter;
unsigned int index = bm_wireoffs;
- for (eve = BM_iter_new(&iter, em->bm, BM_VERTS_OF_MESH, NULL); eve; eve = BM_iter_step(&iter), index++) {
+ BM_ITER_MESH (eve, &iter, em->bm, BM_VERTS_OF_MESH) {
if (!BM_elem_flag_test(eve, BM_ELEM_HIDDEN)) {
if (EDBM_backbuf_check(index)) {
BM_vert_select_set(em->bm, eve, select);
}
}
+ index++;
}
}
@@ -161,13 +162,13 @@ static void edbm_backbuf_check_and_select_edges(BMEditMesh *em, const bool selec
BMIter iter;
int index = bm_solidoffs;
- eed = BM_iter_new(&iter, em->bm, BM_EDGES_OF_MESH, NULL);
- for (; eed; eed = BM_iter_step(&iter), index++) {
+ BM_ITER_MESH (eed, &iter, em->bm, BM_EDGES_OF_MESH) {
if (!BM_elem_flag_test(eed, BM_ELEM_HIDDEN)) {
if (EDBM_backbuf_check(index)) {
BM_edge_select_set(em->bm, eed, select);
}
}
+ index++;
}
}
@@ -177,13 +178,13 @@ static void edbm_backbuf_check_and_select_faces(BMEditMesh *em, const bool selec
BMIter iter;
unsigned int index = 1;
- efa = BM_iter_new(&iter, em->bm, BM_FACES_OF_MESH, NULL);
- for (; efa; efa = BM_iter_step(&iter), index++) {
+ BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
if (!BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) {
if (EDBM_backbuf_check(index)) {
BM_face_select_set(em->bm, efa, select);
}
}
+ index++;
}
}
@@ -2553,7 +2554,7 @@ static void do_circle_select_pose__doSelectBone(void *userData, struct bPoseChan
/* project tail location to screenspace */
if (screen_co_b[0] != IS_CLIPPED) {
points_proj_tot++;
- if (pchan_circle_doSelectJoint(data, pchan, screen_co_a)) {
+ if (pchan_circle_doSelectJoint(data, pchan, screen_co_b)) {
is_point_done = true;
}
}
diff --git a/source/blender/editors/space_view3d/view3d_snap.c b/source/blender/editors/space_view3d/view3d_snap.c
index fb7bbdaa178..0f2f07a1053 100644
--- a/source/blender/editors/space_view3d/view3d_snap.c
+++ b/source/blender/editors/space_view3d/view3d_snap.c
@@ -343,7 +343,7 @@ static void make_trans_verts(Object *obedit, float min[3], float max[3], int mod
if (transvmain && em->derivedCage) {
EDBM_index_arrays_ensure(em, BM_VERT);
- em->derivedCage->foreachMappedVert(em->derivedCage, set_mapped_co, userdata);
+ em->derivedCage->foreachMappedVert(em->derivedCage, set_mapped_co, userdata, DM_FOREACH_NOP);
}
}
else if (obedit->type == OB_ARMATURE) {
@@ -532,7 +532,7 @@ static void make_trans_verts(Object *obedit, float min[3], float max[3], int mod
/* *********************** operators ******************** */
-static int snap_sel_to_grid(bContext *C, wmOperator *UNUSED(op))
+static int snap_sel_to_grid_exec(bContext *C, wmOperator *UNUSED(op))
{
Object *obedit = CTX_data_edit_object(C);
Scene *scene = CTX_data_scene(C);
@@ -660,11 +660,11 @@ void VIEW3D_OT_snap_selected_to_grid(wmOperatorType *ot)
{
/* identifiers */
ot->name = "Snap Selection to Grid";
- ot->description = "Snap selected item(s) to nearest grid node";
+ ot->description = "Snap selected item(s) to nearest grid division";
ot->idname = "VIEW3D_OT_snap_selected_to_grid";
/* api callbacks */
- ot->exec = snap_sel_to_grid;
+ ot->exec = snap_sel_to_grid_exec;
ot->poll = ED_operator_region_view3d_active;
/* flags */
@@ -673,7 +673,7 @@ void VIEW3D_OT_snap_selected_to_grid(wmOperatorType *ot)
/* *************************************************** */
-static int snap_sel_to_curs(bContext *C, wmOperator *op)
+static int snap_sel_to_curs_exec(bContext *C, wmOperator *op)
{
Object *obedit = CTX_data_edit_object(C);
Scene *scene = CTX_data_scene(C);
@@ -832,7 +832,7 @@ void VIEW3D_OT_snap_selected_to_cursor(wmOperatorType *ot)
ot->idname = "VIEW3D_OT_snap_selected_to_cursor";
/* api callbacks */
- ot->exec = snap_sel_to_curs;
+ ot->exec = snap_sel_to_curs_exec;
ot->poll = ED_operator_view3d_active;
/* flags */
@@ -844,7 +844,7 @@ void VIEW3D_OT_snap_selected_to_cursor(wmOperatorType *ot)
/* *************************************************** */
-static int snap_curs_to_grid(bContext *C, wmOperator *UNUSED(op))
+static int snap_curs_to_grid_exec(bContext *C, wmOperator *UNUSED(op))
{
Scene *scene = CTX_data_scene(C);
RegionView3D *rv3d = CTX_wm_region_data(C);
@@ -867,11 +867,11 @@ void VIEW3D_OT_snap_cursor_to_grid(wmOperatorType *ot)
{
/* identifiers */
ot->name = "Snap Cursor to Grid";
- ot->description = "Snap cursor to nearest grid node";
+ ot->description = "Snap cursor to nearest grid division";
ot->idname = "VIEW3D_OT_snap_cursor_to_grid";
/* api callbacks */
- ot->exec = snap_curs_to_grid;
+ ot->exec = snap_curs_to_grid_exec;
ot->poll = ED_operator_region_view3d_active;
/* flags */
@@ -1029,7 +1029,7 @@ static bool snap_curs_to_sel_ex(bContext *C, float cursor[3])
return true;
}
-static int snap_curs_to_sel(bContext *C, wmOperator *UNUSED(op))
+static int snap_curs_to_sel_exec(bContext *C, wmOperator *UNUSED(op))
{
Scene *scene = CTX_data_scene(C);
View3D *v3d = CTX_wm_view3d(C);
@@ -1055,7 +1055,7 @@ void VIEW3D_OT_snap_cursor_to_selected(wmOperatorType *ot)
ot->idname = "VIEW3D_OT_snap_cursor_to_selected";
/* api callbacks */
- ot->exec = snap_curs_to_sel;
+ ot->exec = snap_curs_to_sel_exec;
ot->poll = ED_operator_view3d_active;
/* flags */
@@ -1064,7 +1064,7 @@ void VIEW3D_OT_snap_cursor_to_selected(wmOperatorType *ot)
/* ********************************************** */
-static int snap_curs_to_active(bContext *C, wmOperator *UNUSED(op))
+static int snap_curs_to_active_exec(bContext *C, wmOperator *UNUSED(op))
{
Object *obedit = CTX_data_edit_object(C);
Object *obact = CTX_data_active_object(C);
@@ -1113,7 +1113,7 @@ void VIEW3D_OT_snap_cursor_to_active(wmOperatorType *ot)
ot->idname = "VIEW3D_OT_snap_cursor_to_active";
/* api callbacks */
- ot->exec = snap_curs_to_active;
+ ot->exec = snap_curs_to_active_exec;
ot->poll = ED_operator_view3d_active;
/* flags */
@@ -1122,7 +1122,7 @@ void VIEW3D_OT_snap_cursor_to_active(wmOperatorType *ot)
/* **************************************************** */
/*New Code - Snap Cursor to Center -*/
-static int snap_curs_to_center(bContext *C, wmOperator *UNUSED(op))
+static int snap_curs_to_center_exec(bContext *C, wmOperator *UNUSED(op))
{
Scene *scene = CTX_data_scene(C);
View3D *v3d = CTX_wm_view3d(C);
@@ -1144,7 +1144,7 @@ void VIEW3D_OT_snap_cursor_to_center(wmOperatorType *ot)
ot->idname = "VIEW3D_OT_snap_cursor_to_center";
/* api callbacks */
- ot->exec = snap_curs_to_center;
+ ot->exec = snap_curs_to_center_exec;
ot->poll = ED_operator_view3d_active;
/* flags */
diff --git a/source/blender/editors/space_view3d/view3d_toolbar.c b/source/blender/editors/space_view3d/view3d_toolbar.c
index ebb9a7b8c81..bdb203ab003 100644
--- a/source/blender/editors/space_view3d/view3d_toolbar.c
+++ b/source/blender/editors/space_view3d/view3d_toolbar.c
@@ -195,7 +195,7 @@ static uiBlock *tool_search_menu(bContext *C, ARegion *ar, void *arg_listbase)
uiBlockSetDirection(block, UI_DOWN);
uiEndBlock(C, block);
- event = *(win->eventstate); /* XXX huh huh? make api call */
+ wm_event_init_from_window(win, &event);
event.type = EVT_BUT_OPEN;
event.val = KM_PRESS;
event.customdata = but;
@@ -258,7 +258,7 @@ void view3d_tool_props_register(ARegionType *art)
/* ********** operator to open/close toolshelf region */
-static int view3d_toolshelf(bContext *C, wmOperator *UNUSED(op))
+static int view3d_toolshelf_toggle_exec(bContext *C, wmOperator *UNUSED(op))
{
ScrArea *sa = CTX_wm_area(C);
ARegion *ar = view3d_has_tools_region(sa);
@@ -275,7 +275,7 @@ void VIEW3D_OT_toolshelf(wmOperatorType *ot)
ot->description = "Toggles tool shelf display";
ot->idname = "VIEW3D_OT_toolshelf";
- ot->exec = view3d_toolshelf;
+ ot->exec = view3d_toolshelf_toggle_exec;
ot->poll = ED_operator_view3d_active;
/* flags */
diff --git a/source/blender/editors/space_view3d/view3d_view.c b/source/blender/editors/space_view3d/view3d_view.c
index 3638690a0a5..44c338d22b9 100644
--- a/source/blender/editors/space_view3d/view3d_view.c
+++ b/source/blender/editors/space_view3d/view3d_view.c
@@ -202,7 +202,7 @@ void view3d_smooth_view(bContext *C, View3D *v3d, ARegion *ar, Object *oldcamera
}
/* skip smooth viewing for render engine draw */
- if (C && U.smooth_viewtx && v3d->drawtype != OB_RENDER) {
+ if (U.smooth_viewtx && v3d->drawtype != OB_RENDER) {
bool changed = false; /* zero means no difference */
if (oldcamera != camera)
@@ -444,14 +444,27 @@ void VIEW3D_OT_camera_to_view(wmOperatorType *ot)
/* unlike VIEW3D_OT_view_selected this is for framing a render and not
* meant to take into account vertex/bone selection for eg. */
-static int view3d_camera_to_view_selected_exec(bContext *C, wmOperator *UNUSED(op))
+static int view3d_camera_to_view_selected_exec(bContext *C, wmOperator *op)
{
Scene *scene = CTX_data_scene(C);
- View3D *v3d = CTX_wm_view3d(C);
- Object *camera_ob = v3d->camera;
+ View3D *v3d = CTX_wm_view3d(C); /* can be NULL */
+ Object *camera_ob = v3d ? v3d->camera : scene->camera;
float r_co[3]; /* the new location to apply */
+ if (camera_ob == NULL) {
+ BKE_report(op->reports, RPT_ERROR, "No active camera");
+ return OPERATOR_CANCELLED;
+ }
+ else if (camera_ob->type != OB_CAMERA) {
+ BKE_report(op->reports, RPT_ERROR, "Object not a camera");
+ return OPERATOR_CANCELLED;
+ }
+ else if (((Camera *)camera_ob->data)->type == R_ORTHO) {
+ BKE_report(op->reports, RPT_ERROR, "Orthographic cameras not supported");
+ return OPERATOR_CANCELLED;
+ }
+
/* this function does all the important stuff */
if (BKE_camera_view_frame_fit_to_scene(scene, v3d, camera_ob, r_co)) {
@@ -476,24 +489,6 @@ static int view3d_camera_to_view_selected_exec(bContext *C, wmOperator *UNUSED(o
}
}
-static int view3d_camera_to_view_selected_poll(bContext *C)
-{
- View3D *v3d = CTX_wm_view3d(C);
- if (v3d && v3d->camera && v3d->camera->id.lib == NULL) {
- RegionView3D *rv3d = CTX_wm_region_view3d(C);
- if (rv3d) {
- if (rv3d->is_persp == false) {
- CTX_wm_operator_poll_msg_set(C, "Only valid for a perspective camera view");
- }
- else if (!rv3d->viewlock) {
- return 1;
- }
- }
- }
-
- return 0;
-}
-
void VIEW3D_OT_camera_to_view_selected(wmOperatorType *ot)
{
/* identifiers */
@@ -503,7 +498,7 @@ void VIEW3D_OT_camera_to_view_selected(wmOperatorType *ot)
/* api callbacks */
ot->exec = view3d_camera_to_view_selected_exec;
- ot->poll = view3d_camera_to_view_selected_poll;
+ ot->poll = ED_operator_scene_editable;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
@@ -753,7 +748,7 @@ void setwinmatrixview3d(ARegion *ar, View3D *v3d, rctf *rect)
glGetFloatv(GL_PROJECTION_MATRIX, (float *)rv3d->winmat);
}
-static void obmat_to_viewmat(View3D *v3d, RegionView3D *rv3d, Object *ob, short smooth)
+static void obmat_to_viewmat(RegionView3D *rv3d, Object *ob)
{
float bmat[4][4];
float tmat[3][3];
@@ -766,36 +761,7 @@ static void obmat_to_viewmat(View3D *v3d, RegionView3D *rv3d, Object *ob, short
/* view quat calculation, needed for add object */
copy_m3_m4(tmat, rv3d->viewmat);
- if (smooth) {
- float new_quat[4];
- if (rv3d->persp == RV3D_CAMOB && v3d->camera) {
- /* were from a camera view */
-
- float orig_ofs[3];
- float orig_dist = rv3d->dist;
- float orig_lens = v3d->lens;
- copy_v3_v3(orig_ofs, rv3d->ofs);
-
- /* Switch from camera view */
- mat3_to_quat(new_quat, tmat);
-
- rv3d->persp = RV3D_PERSP;
- rv3d->dist = 0.0;
-
- ED_view3d_from_object(v3d->camera, rv3d->ofs, NULL, NULL, &v3d->lens);
- view3d_smooth_view(NULL, NULL, NULL, NULL, NULL, orig_ofs, new_quat, &orig_dist, &orig_lens); /* XXX */
-
- rv3d->persp = RV3D_CAMOB; /* just to be polite, not needed */
-
- }
- else {
- mat3_to_quat(new_quat, tmat);
- view3d_smooth_view(NULL, NULL, NULL, NULL, NULL, NULL, new_quat, NULL, NULL); /* XXX */
- }
- }
- else {
- mat3_to_quat(rv3d->viewquat, tmat);
- }
+ mat3_to_quat(rv3d->viewquat, tmat);
}
#define QUATSET(a, b, c, d, e) { a[0] = b; a[1] = c; a[2] = d; a[3] = e; } (void)0
@@ -839,7 +805,7 @@ void setviewmatrixview3d(Scene *scene, View3D *v3d, RegionView3D *rv3d)
if (rv3d->persp == RV3D_CAMOB) { /* obs/camera */
if (v3d->camera) {
BKE_object_where_is_calc(scene, v3d->camera);
- obmat_to_viewmat(v3d, rv3d, v3d->camera, 0);
+ obmat_to_viewmat(rv3d, v3d->camera);
}
else {
quat_to_mat4(rv3d->viewmat, rv3d->viewquat);
@@ -1562,40 +1528,6 @@ void VIEW3D_OT_game_start(wmOperatorType *ot)
/* ************************************** */
-static void UNUSED_FUNCTION(view3d_align_axis_to_vector)(View3D *v3d, RegionView3D *rv3d, int axisidx, float vec[3])
-{
- float alignaxis[3] = {0.0, 0.0, 0.0};
- float norm[3], axis[3], angle, new_quat[4];
-
- if (axisidx > 0) alignaxis[axisidx - 1] = 1.0;
- else alignaxis[-axisidx - 1] = -1.0;
-
- normalize_v3_v3(norm, vec);
-
- angle = (float)acos(dot_v3v3(alignaxis, norm));
- cross_v3_v3v3(axis, alignaxis, norm);
- axis_angle_to_quat(new_quat, axis, -angle);
-
- rv3d->view = RV3D_VIEW_USER;
-
- if (rv3d->persp == RV3D_CAMOB && v3d->camera) {
- /* switch out of camera view */
- float orig_ofs[3];
- float orig_dist = rv3d->dist;
- float orig_lens = v3d->lens;
-
- copy_v3_v3(orig_ofs, rv3d->ofs);
- rv3d->persp = RV3D_PERSP;
- rv3d->dist = 0.0;
- ED_view3d_from_object(v3d->camera, rv3d->ofs, NULL, NULL, &v3d->lens);
- view3d_smooth_view(NULL, NULL, NULL, NULL, NULL, orig_ofs, new_quat, &orig_dist, &orig_lens); /* XXX */
- }
- else {
- if (rv3d->persp == RV3D_CAMOB) rv3d->persp = RV3D_PERSP; /* switch out of camera mode */
- view3d_smooth_view(NULL, NULL, NULL, NULL, NULL, NULL, new_quat, NULL, NULL); /* XXX */
- }
-}
-
float ED_view3d_pixel_size(RegionView3D *rv3d, const float co[3])
{
return mul_project_m4_v3_zfac(rv3d->persmat, co) * rv3d->pixsize * U.pixelsize;
diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c
index a565213f031..d5a9d0f9f93 100644
--- a/source/blender/editors/transform/transform.c
+++ b/source/blender/editors/transform/transform.c
@@ -61,7 +61,6 @@
#include "BLI_linklist.h"
#include "BKE_nla.h"
-#include "BKE_bmesh.h"
#include "BKE_editmesh_bvh.h"
#include "BKE_context.h"
#include "BKE_constraint.h"
@@ -111,9 +110,7 @@ static bool transdata_check_local_center(TransInfo *t)
{
return ((t->around == V3D_LOCAL) && (
(t->flag & (T_OBJECT | T_POSE)) ||
- (t->obedit && t->obedit->type == OB_MESH && (t->settings->selectmode & (SCE_SELECT_EDGE | SCE_SELECT_FACE))) ||
- (t->obedit && t->obedit->type == OB_MBALL) ||
- (t->obedit && t->obedit->type == OB_ARMATURE) ||
+ (t->obedit && ELEM4(t->obedit->type, OB_MESH, OB_CURVE, OB_MBALL, OB_ARMATURE)) ||
(t->spacetype == SPACE_IPO))
);
}
@@ -1327,12 +1324,6 @@ int transformEvent(TransInfo *t, const wmEvent *event)
t->redraw |= TREDRAW_HARD;
}
break;
-// case LEFTMOUSE:
-// case RIGHTMOUSE:
-// if (WM_modal_tweak_exit(event, t->event_type))
-//// if (t->options & CTX_TWEAK)
-// t->state = TRANS_CONFIRM;
-// break;
case LEFTALTKEY:
case RIGHTALTKEY:
if (ELEM(t->spacetype, SPACE_SEQ, SPACE_VIEW3D)) {
@@ -1377,7 +1368,7 @@ int calculateTransformCenter(bContext *C, int centerMode, float cent3d[3], int c
t->state = TRANS_RUNNING;
/* avoid calculating PET */
- t->options = CTX_NONE | CTX_NO_PET;
+ t->options = CTX_NO_PET;
t->mode = TFM_DUMMY;
@@ -5709,7 +5700,7 @@ int handleEventEdgeSlide(struct TransInfo *t, const struct wmEvent *event)
return 0;
}
-void drawEdgeSlide(const struct bContext *C, TransInfo *t)
+static void drawEdgeSlide(const struct bContext *C, TransInfo *t)
{
if (t->mode == TFM_EDGE_SLIDE) {
EdgeSlideData *sld = (EdgeSlideData *)t->customData;
@@ -5883,14 +5874,8 @@ int EdgeSlide(TransInfo *t, const int UNUSED(mval[2]))
t->values[0] = final;
- /*do stuff here*/
- if (t->customData) {
- doEdgeSlide(t, final);
- }
- else {
- BLI_strncpy(str, IFACE_("Invalid Edge Selection"), MAX_INFO_LEN);
- t->state = TRANS_CANCEL;
- }
+ /* do stuff here */
+ doEdgeSlide(t, final);
recalcData(t);
@@ -6397,14 +6382,8 @@ int VertSlide(TransInfo *t, const int UNUSED(mval[2]))
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*/
- if (t->customData) {
- doVertSlide(t, final);
- }
- else {
- BLI_strncpy(str, IFACE_("Invalid Vert Selection"), MAX_INFO_LEN);
- t->state = TRANS_CANCEL;
- }
+ /* do stuff here */
+ doVertSlide(t, final);
recalcData(t);
@@ -7358,7 +7337,7 @@ bool checkUseAxisMatrix(TransInfo *t)
{
/* currenly only checks for editmode */
if (t->flag & T_EDIT) {
- if ((t->around == V3D_LOCAL) && (ELEM3(t->obedit->type, OB_MESH, OB_MBALL, OB_ARMATURE))) {
+ if ((t->around == V3D_LOCAL) && (ELEM4(t->obedit->type, OB_MESH, OB_CURVE, OB_MBALL, OB_ARMATURE))) {
/* not all editmode supports axis-matrix */
return true;
}
diff --git a/source/blender/editors/transform/transform.h b/source/blender/editors/transform/transform.h
index 911d4b0a623..4a1c4203a43 100644
--- a/source/blender/editors/transform/transform.h
+++ b/source/blender/editors/transform/transform.h
@@ -725,7 +725,7 @@ void initTransformOrientation(struct bContext *C, TransInfo *t);
/* Those two fill in mat and return non-zero on success */
bool createSpaceNormal(float mat[3][3], const float normal[3]);
-bool createSpaceNormalTangent(float mat[3][3], float normal[3], float tangent[3]);
+bool createSpaceNormalTangent(float mat[3][3], const float normal[3], const float tangent[3]);
struct TransformOrientation *addMatrixSpace(struct bContext *C, float mat[3][3], char name[], int overwrite);
void applyTransformOrientation(const struct bContext *C, float mat[3][3], char *name);
diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c
index 93e01d84eaf..95ec20a0c2b 100644
--- a/source/blender/editors/transform/transform_conversions.c
+++ b/source/blender/editors/transform/transform_conversions.c
@@ -59,14 +59,12 @@
#include "BLI_math.h"
#include "BLI_blenlib.h"
-#include "BLI_array.h"
#include "BLI_utildefines.h"
#include "BLI_smallhash.h"
#include "BKE_DerivedMesh.h"
#include "BKE_action.h"
#include "BKE_armature.h"
-#include "BKE_bmesh.h"
#include "BKE_constraint.h"
#include "BKE_context.h"
#include "BKE_curve.h"
@@ -124,6 +122,11 @@
#include "BLI_sys_types.h" // for intptr_t support
+/* when transforming islands */
+struct TransIslandData {
+ float co[3];
+ float axismtx[3][3];
+};
/* local function prototype - for Object/Bone Constraints */
static bool constraints_list_needinv(TransInfo *t, ListBase *list);
@@ -1043,7 +1046,7 @@ static void createTransArmatureVerts(TransInfo *t)
bArmature *arm = t->obedit->data;
ListBase *edbo = arm->edbo;
TransData *td;
- float mtx[3][3], smtx[3][3], delta[3], bonemat[3][3];
+ float mtx[3][3], smtx[3][3], bonemat[3][3];
/* special hack for envelope drawmode and scaling:
* to allow scaling the size of the envelope around single points,
@@ -1135,8 +1138,7 @@ static void createTransArmatureVerts(TransInfo *t)
td->flag = TD_SELECTED;
/* use local bone matrix */
- sub_v3_v3v3(delta, ebo->tail, ebo->head);
- vec_roll_to_mat3(delta, ebo->roll, bonemat);
+ ED_armature_ebone_to_mat3(ebo, bonemat);
mul_m3_m3m3(td->mtx, mtx, bonemat);
invert_m3_m3(td->smtx, td->mtx);
@@ -1176,8 +1178,7 @@ static void createTransArmatureVerts(TransInfo *t)
copy_m3_m3(td->smtx, smtx);
copy_m3_m3(td->mtx, mtx);
- sub_v3_v3v3(delta, ebo->tail, ebo->head);
- vec_roll_to_mat3(delta, ebo->roll, td->axismtx);
+ ED_armature_ebone_to_mat3(ebo, td->axismtx);
if ((ebo->flag & BONE_ROOTSEL) == 0) {
td->extra = ebo;
@@ -1200,8 +1201,7 @@ static void createTransArmatureVerts(TransInfo *t)
copy_m3_m3(td->smtx, smtx);
copy_m3_m3(td->mtx, mtx);
- sub_v3_v3v3(delta, ebo->tail, ebo->head);
- vec_roll_to_mat3(delta, ebo->roll, td->axismtx);
+ ED_armature_ebone_to_mat3(ebo, td->axismtx);
td->extra = ebo; /* to fix roll */
@@ -1413,6 +1413,23 @@ static void createTransCurveVerts(TransInfo *t)
for (a = 0, bezt = nu->bezt; a < nu->pntsu; a++, bezt++) {
if (bezt->hide == 0) {
TransDataCurveHandleFlags *hdata = NULL;
+ float axismtx[3][3];
+
+ if (t->around == V3D_LOCAL) {
+ float normal[3], plane[3];
+
+ BKE_nurb_bezt_calc_normal(nu, bezt, normal);
+ BKE_nurb_bezt_calc_plane(nu, bezt, plane);
+
+ if (createSpaceNormalTangent(axismtx, normal, plane)) {
+ /* pass */
+ }
+ else {
+ normalize_v3(normal);
+ axis_dominant_v3_to_m3(axismtx, normal);
+ invert_m3(axismtx);
+ }
+ }
if (propmode ||
((bezt->f2 & SELECT) && hide_handles) ||
@@ -1436,6 +1453,9 @@ static void createTransCurveVerts(TransInfo *t)
copy_m3_m3(td->smtx, smtx);
copy_m3_m3(td->mtx, mtx);
+ if (t->around == V3D_LOCAL) {
+ copy_m3_m3(td->axismtx, axismtx);
+ }
td++;
count++;
@@ -1465,6 +1485,9 @@ static void createTransCurveVerts(TransInfo *t)
copy_m3_m3(td->smtx, smtx);
copy_m3_m3(td->mtx, mtx);
+ if (t->around == V3D_LOCAL) {
+ copy_m3_m3(td->axismtx, axismtx);
+ }
if ((bezt->f1 & SELECT) == 0 && (bezt->f3 & SELECT) == 0)
/* If the middle is selected but the sides arnt, this is needed */
@@ -1500,6 +1523,9 @@ static void createTransCurveVerts(TransInfo *t)
copy_m3_m3(td->smtx, smtx);
copy_m3_m3(td->mtx, mtx);
+ if (t->around == V3D_LOCAL) {
+ copy_m3_m3(td->axismtx, axismtx);
+ }
td++;
count++;
@@ -1914,34 +1940,124 @@ static void editmesh_set_connectivity_distance(BMesh *bm, float mtx[3][3], float
MEM_freeN(dists_prev);
}
-static BMElem *bm_vert_single_select_face(BMVert *eve)
+static struct TransIslandData *editmesh_islands_info_calc(BMEditMesh *em, int *r_island_tot, int **r_island_vert_map)
{
- BMElem *ele;
- BMIter iter;
+ BMesh *bm = em->bm;
+ struct TransIslandData *trans_islands;
+ char htype;
+ char itype;
+ int i;
+
+ /* group vars */
+ int *groups_array;
+ int (*group_index)[2];
+ int group_tot;
+ void **ele_array;
+
+ int *vert_map;
+
+ if (em->selectmode & (SCE_SELECT_VERTEX | SCE_SELECT_EDGE)) {
+ groups_array = MEM_mallocN(sizeof(*groups_array) * bm->totedgesel, __func__);
+ group_tot = BM_mesh_calc_edge_groups(bm, groups_array, &group_index,
+ NULL, NULL,
+ BM_ELEM_SELECT);
+
+ htype = BM_EDGE;
+ itype = BM_VERTS_OF_EDGE;
- BM_ITER_ELEM (ele, &iter, eve, BM_FACES_OF_VERT) {
- if (BM_elem_flag_test(ele, BM_ELEM_SELECT)) {
- return ele;
- }
}
- return NULL;
-}
-static BMElem *bm_vert_single_select_edge(BMVert *eve)
-{
- BMElem *ele;
- BMIter iter;
+ else { /* (bm->selectmode & SCE_SELECT_FACE) */
+ groups_array = MEM_mallocN(sizeof(*groups_array) * bm->totfacesel, __func__);
+ group_tot = BM_mesh_calc_face_groups(bm, groups_array, &group_index,
+ NULL, NULL,
+ BM_ELEM_SELECT, BM_VERT);
+
+ htype = BM_FACE;
+ itype = BM_VERTS_OF_FACE;
+ }
+
+
+ trans_islands = MEM_mallocN(sizeof(*trans_islands) * group_tot, __func__);
+
+ vert_map = MEM_mallocN(sizeof(*vert_map) * bm->totvert, __func__);
+ /* we shouldn't need this, but with incorrect selection flushing
+ * its possible we have a selected vertex thats not in a face, for now best not crash in that case. */
+ fill_vn_i(vert_map, bm->totvert, -1);
+
+ EDBM_index_arrays_ensure(em, htype);
+ ele_array = (htype == BM_FACE) ? (void **)em->face_index : (void **)em->edge_index;
+
+ BM_mesh_elem_index_ensure(bm, BM_VERT);
+
+ /* may be an edge OR a face array */
+ for (i = 0; i < group_tot; i++) {
+ BMEditSelection ese = {NULL};
+
+ const int fg_sta = group_index[i][0];
+ const int fg_len = group_index[i][1];
+ float co[3], no[3], tangent[3];
+ int j;
+
+ zero_v3(co);
+ zero_v3(no);
+ zero_v3(tangent);
- BM_ITER_ELEM (ele, &iter, eve, BM_EDGES_OF_VERT) {
- if (BM_elem_flag_test(ele, BM_ELEM_SELECT)) {
- return ele;
+ ese.htype = htype;
+
+ /* loop on each face in this group:
+ * - assign r_vert_map
+ * - calculate (co, no)
+ */
+ for (j = 0; j < fg_len; j++) {
+ float tmp_co[3], tmp_no[3], tmp_tangent[3];
+
+ ese.ele = ele_array[groups_array[fg_sta + j]];
+
+ BM_editselection_center(&ese, tmp_co);
+ BM_editselection_normal(&ese, tmp_no);
+ BM_editselection_plane(&ese, tmp_tangent);
+
+ add_v3_v3(co, tmp_co);
+ add_v3_v3(no, tmp_no);
+ add_v3_v3(tangent, tmp_tangent);
+
+ {
+ /* setup vertex map */
+ BMIter iter;
+ BMVert *v;
+
+ /* connected edge-verts */
+ BM_ITER_ELEM (v, &iter, ese.ele, itype) {
+ vert_map[BM_elem_index_get(v)] = i;
+ }
+ }
+ }
+
+ mul_v3_v3fl(trans_islands[i].co, co, 1.0f / (float)fg_len);
+
+ if (createSpaceNormalTangent(trans_islands[i].axismtx, no, tangent)) {
+ /* pass */
+ }
+ else {
+ normalize_v3(no);
+ axis_dominant_v3_to_m3(trans_islands[i].axismtx, no);
+ invert_m3(trans_islands[i].axismtx);
}
}
- return NULL;
+
+ MEM_freeN(groups_array);
+ MEM_freeN(group_index);
+
+ *r_island_tot = group_tot;
+ *r_island_vert_map = vert_map;
+
+ return trans_islands;
}
/* way to overwrite what data is edited with transform */
static void VertsToTransData(TransInfo *t, TransData *td, TransDataExtension *tx,
- BMEditMesh *em, BMVert *eve, float *bweight)
+ BMEditMesh *em, BMVert *eve, float *bweight,
+ struct TransIslandData *v_island)
{
BLI_assert(BM_elem_flag_test(eve, BM_ELEM_HIDDEN) == 0);
@@ -1951,40 +2067,20 @@ static void VertsToTransData(TransInfo *t, TransData *td, TransDataExtension *tx
//else
td->loc = eve->co;
copy_v3_v3(td->iloc, td->loc);
- copy_v3_v3(td->center, td->loc);
-
- if (t->around == V3D_LOCAL) {
- BMElem *ele;
- bool is_axismat_set = false;
- if (em->selectmode & (SCE_SELECT_FACE | SCE_SELECT_EDGE) &&
- (ele = ((em->selectmode & SCE_SELECT_FACE) ?
- bm_vert_single_select_face(eve) :
- bm_vert_single_select_edge(eve))))
- {
- float normal[3], tangent[3];
-
- BMEditSelection ese;
- ese.next = ese.prev = NULL;
- ese.ele = ele;
- ese.htype = ele->head.htype;
-
- BM_editselection_center(&ese, td->center);
- BM_editselection_normal(&ese, normal);
- BM_editselection_plane(&ese, tangent);
-
- if (createSpaceNormalTangent(td->axismtx, normal, tangent)) {
- is_axismat_set = true;
- }
- }
+ if (v_island) {
+ copy_v3_v3(td->center, v_island->co);
+ copy_m3_m3(td->axismtx, v_island->axismtx);
+ }
+ else if (t->around == V3D_LOCAL) {
+ copy_v3_v3(td->center, td->loc);
- /* for verts or fallback when createSpaceNormalTangent fails */
- if (is_axismat_set == false) {
- axis_dominant_v3_to_m3(td->axismtx, eve->no);
- invert_m3(td->axismtx);
- }
+ axis_dominant_v3_to_m3(td->axismtx, eve->no);
+ invert_m3(td->axismtx);
}
else {
+ copy_v3_v3(td->center, td->loc);
+
/* Setting normals */
copy_v3_v3(td->axismtx[2], eve->no);
td->axismtx[0][0] =
@@ -2021,7 +2117,6 @@ static void VertsToTransData(TransInfo *t, TransData *td, TransDataExtension *tx
static void createTransEditVerts(TransInfo *t)
{
- ToolSettings *ts = t->scene->toolsettings;
TransData *tob = NULL;
TransDataExtension *tx = NULL;
BMEditMesh *em = BKE_editmesh_from_object(t->obedit);
@@ -2033,15 +2128,15 @@ static void createTransEditVerts(TransInfo *t)
float *mappedcos = NULL, *quats = NULL;
float mtx[3][3], smtx[3][3], (*defmats)[3][3] = NULL, (*defcos)[3] = NULL;
float *dists = NULL;
- int count = 0, countsel = 0, a, totleft;
+ int a;
int propmode = (t->flag & T_PROP_EDIT) ? (t->flag & T_PROP_EDIT_ALL) : 0;
int mirror = 0;
- short selectmode = ts->selectmode;
int cd_vert_bweight_offset = -1;
bool use_topology = (me->editflag & ME_EDIT_MIRROR_TOPO) != 0;
- /* BMESH_TODO, writing into the index values is BAD!, means we cant
- * use the values for vertex mirror - campbell */
+ struct TransIslandData *island_info = NULL;
+ int island_info_tot;
+ int *island_vert_map = NULL;
if (t->flag & T_MIRROR) {
EDBM_verts_mirror_cache_begin(em, 0, false, (t->flag & T_PROP_EDIT) == 0, use_topology);
@@ -2050,17 +2145,17 @@ static void createTransEditVerts(TransInfo *t)
/* quick check if we can transform */
/* note: in prop mode we need at least 1 selected */
- if (selectmode & SCE_SELECT_VERTEX) {
+ if (em->selectmode & SCE_SELECT_VERTEX) {
if (bm->totvertsel == 0) {
goto cleanup;
}
}
- else if (selectmode & SCE_SELECT_EDGE) {
+ else if (em->selectmode & SCE_SELECT_EDGE) {
if (bm->totvertsel == 0 || bm->totedgesel == 0) {
goto cleanup;
}
}
- else if (selectmode & SCE_SELECT_FACE) {
+ else if (em->selectmode & SCE_SELECT_FACE) {
if (bm->totvertsel == 0 || bm->totfacesel == 0) {
goto cleanup;
}
@@ -2069,10 +2164,6 @@ static void createTransEditVerts(TransInfo *t)
BLI_assert(0);
}
- countsel = bm->totvertsel;
- if (propmode) {
- count = bm->totvert;
- }
/* check active */
eve_act = BM_mesh_active_vert_get(bm);
@@ -2083,6 +2174,13 @@ static void createTransEditVerts(TransInfo *t)
}
if (propmode) {
+ unsigned int count = 0;
+ BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) {
+ if (!BM_elem_flag_test(eve, BM_ELEM_HIDDEN)) {
+ count++;
+ }
+ }
+
t->total = count;
/* allocating scratch arrays */
@@ -2090,7 +2188,7 @@ static void createTransEditVerts(TransInfo *t)
dists = MEM_mallocN(em->bm->totvert * sizeof(float), "scratch nears");
}
else {
- t->total = countsel;
+ t->total = bm->totvertsel;
}
tob = t->data = MEM_callocN(t->total * sizeof(TransData), "TransObData(Mesh EditMode)");
@@ -2112,9 +2210,17 @@ static void createTransEditVerts(TransInfo *t)
editmesh_set_connectivity_distance(em->bm, mtx, dists);
}
+ if (t->around == V3D_LOCAL) {
+ island_info = editmesh_islands_info_calc(em, &island_info_tot, &island_vert_map);
+ }
+
+ /* BMESH_TODO, crazy-space writing into the index values is BAD!, means we cant
+ * use the values for vertex mirror - campbell */
+
/* detect CrazySpace [tm] */
if (modifiers_getCageIndex(t->scene, t->obedit, NULL, 1) >= 0) {
if (modifiers_isCorrectableDeformed(t->obedit)) {
+ int totleft;
/* check if we can use deform matrices for modifier from the
* start up to stack, they are more accurate than quats */
totleft = editbmesh_get_first_deform_matrices(t->scene, t->obedit, em, &defmats, &defcos);
@@ -2151,9 +2257,11 @@ static void createTransEditVerts(TransInfo *t)
BM_ITER_MESH_INDEX (eve, &iter, bm, BM_VERTS_OF_MESH, a) {
if (!BM_elem_flag_test(eve, BM_ELEM_HIDDEN)) {
if (propmode || BM_elem_flag_test(eve, BM_ELEM_SELECT)) {
+ struct TransIslandData *v_island = (island_info && island_vert_map[a] != -1) ?
+ &island_info[island_vert_map[a]] : NULL;
float *bweight = (cd_vert_bweight_offset != -1) ? BM_ELEM_CD_GET_VOID_P(eve, cd_vert_bweight_offset) : NULL;
-
- VertsToTransData(t, tob, tx, em, eve, bweight);
+
+ VertsToTransData(t, tob, tx, em, eve, bweight, v_island);
if (tx)
tx++;
@@ -2213,6 +2321,11 @@ static void createTransEditVerts(TransInfo *t)
}
}
+ if (island_info) {
+ MEM_freeN(island_info);
+ MEM_freeN(island_vert_map);
+ }
+
if (mirror != 0) {
tob = t->data;
for (a = 0; a < t->total; a++, tob++) {
@@ -2233,7 +2346,6 @@ cleanup:
if (t->flag & T_MIRROR) {
EDBM_verts_mirror_cache_end(em);
- mirror = 1;
}
}
@@ -6309,7 +6421,7 @@ void flushTransTracking(TransInfo *t)
}
}
- if (tdt->area != TRACK_AREA_POINT || tdt->relative == 0) {
+ if (tdt->area != TRACK_AREA_POINT || tdt->relative == NULL) {
td2d->loc2d[0] = loc2d[0];
td2d->loc2d[1] = loc2d[1];
@@ -6556,10 +6668,6 @@ void createTransData(bContext *C, TransInfo *t)
sort_trans_data_dist(t);
}
}
- else if (t->options == CTX_BMESH) {
- // TRANSFORM_FIX_ME
- //createTransBMeshVerts(t, G.editBMesh->bm, G.editBMesh->td);
- }
else if (t->spacetype == SPACE_IMAGE) {
t->flag |= T_POINTS | T_2D_EDIT;
if (t->options & CTX_MASK) {
diff --git a/source/blender/editors/transform/transform_orientations.c b/source/blender/editors/transform/transform_orientations.c
index 2be4a072d49..55d80d63234 100644
--- a/source/blender/editors/transform/transform_orientations.c
+++ b/source/blender/editors/transform/transform_orientations.c
@@ -166,6 +166,26 @@ static TransformOrientation *createBoneSpace(bContext *C, ReportList *reports, c
return addMatrixSpace(C, mat, name, overwrite);
}
+static TransformOrientation *createCurveSpace(bContext *C, ReportList *reports, char *name, int overwrite)
+{
+ float mat[3][3];
+ float normal[3], plane[3];
+
+ getTransformOrientation(C, normal, plane, 0);
+
+ if (createSpaceNormalTangent(mat, normal, plane) == 0) {
+ BKE_reports_prepend(reports, "Cannot use zero-length curve");
+ return NULL;
+ }
+
+ if (name[0] == 0) {
+ strcpy(name, "Curve");
+ }
+
+ return addMatrixSpace(C, mat, name, overwrite);
+}
+
+
static TransformOrientation *createMeshSpace(bContext *C, ReportList *reports, char *name, int overwrite)
{
float mat[3][3];
@@ -236,26 +256,34 @@ bool createSpaceNormal(float mat[3][3], const float normal[3])
return true;
}
-bool createSpaceNormalTangent(float mat[3][3], float normal[3], float tangent[3])
+/**
+ * \note To recreate an orientation from the matrix:
+ * - (plane == mat[1])
+ * - (normal == mat[2])
+ */
+bool createSpaceNormalTangent(float mat[3][3], const float normal[3], const float tangent[3])
{
- copy_v3_v3(mat[2], normal);
- if (normalize_v3(mat[2]) == 0.0f) {
+ if (normalize_v3_v3(mat[2], normal) == 0.0f) {
return false; /* error return */
}
-
+
+ /* negate so we can use values from the matrix as input */
+ negate_v3_v3(mat[1], tangent);
/* preempt zero length tangent from causing trouble */
- if (tangent[0] == 0 && tangent[1] == 0 && tangent[2] == 0) {
- tangent[2] = 1;
+ if (is_zero_v3(mat[1])) {
+ mat[1][2] = 1.0f;
}
- cross_v3_v3v3(mat[0], mat[2], tangent);
+ cross_v3_v3v3(mat[0], mat[2], mat[1]);
if (normalize_v3(mat[0]) == 0.0f) {
return false; /* error return */
}
cross_v3_v3v3(mat[1], mat[2], mat[0]);
+ normalize_v3(mat[1]);
- normalize_m3(mat);
+ /* final matrix must be normalized, do inline */
+ // normalize_m3(mat);
return true;
}
@@ -276,6 +304,8 @@ void BIF_createTransformOrientation(bContext *C, ReportList *reports, char *name
ts = createMeshSpace(C, reports, name, overwrite);
else if (obedit->type == OB_ARMATURE)
ts = createBoneSpace(C, reports, name, overwrite);
+ else if (obedit->type == OB_CURVE)
+ ts = createCurveSpace(C, reports, name, overwrite);
}
else if (ob && (ob->mode & OB_MODE_POSE)) {
ts = createBoneSpace(C, reports, name, overwrite);
@@ -667,6 +697,10 @@ int getTransformOrientation(const bContext *C, float normal[3], float plane[3],
result = ORIENTATION_VERT;
}
}
+
+ /* not needed but this matches 2.68 and older behavior */
+ negate_v3(plane);
+
} /* end editmesh */
else if (ELEM(obedit->type, OB_CURVE, OB_SURF)) {
Curve *cu = obedit->data;
@@ -675,34 +709,67 @@ int getTransformOrientation(const bContext *C, float normal[3], float plane[3],
int a;
ListBase *nurbs = BKE_curve_editNurbs_get(cu);
- for (nu = nurbs->first; nu; nu = nu->next) {
- /* only bezier has a normal */
- if (nu->type == CU_BEZIER) {
- bezt = nu->bezt;
- a = nu->pntsu;
- while (a--) {
- /* exception */
- if ((bezt->f1 & SELECT) + (bezt->f2 & SELECT) + (bezt->f3 & SELECT) > SELECT) {
- sub_v3_v3v3(normal, bezt->vec[0], bezt->vec[2]);
+ if (activeOnly && cu->lastsel) {
+ for (nu = nurbs->first; nu; nu = nu->next) {
+ if (nu->type == CU_BEZIER) {
+ if (ARRAY_HAS_ITEM((BezTriple *)cu->lastsel, nu->bezt, nu->pntsu)) {
+ bezt = cu->lastsel;
+ BKE_nurb_bezt_calc_normal(nu, bezt, normal);
+ BKE_nurb_bezt_calc_plane(nu, bezt, plane);
+ break;
}
- else {
- if (bezt->f1) {
- sub_v3_v3v3(normal, bezt->vec[0], bezt->vec[1]);
- }
- if (bezt->f2) {
- sub_v3_v3v3(normal, bezt->vec[0], bezt->vec[2]);
- }
- if (bezt->f3) {
- sub_v3_v3v3(normal, bezt->vec[1], bezt->vec[2]);
+ }
+ else {
+ if (ARRAY_HAS_ITEM((BPoint *)cu->lastsel, nu->bp, nu->pntsu)) {
+ /* do nothing */
+ break;
+ }
+ }
+ }
+ }
+ else {
+ for (nu = nurbs->first; nu; nu = nu->next) {
+ /* only bezier has a normal */
+ if (nu->type == CU_BEZIER) {
+ bezt = nu->bezt;
+ a = nu->pntsu;
+ while (a--) {
+ /* exception */
+ if ((bezt->f1 | bezt->f2 | bezt->f3) & SELECT) {
+ float tvec[3];
+ if ((bezt->f1 & SELECT) + (bezt->f2 & SELECT) + (bezt->f3 & SELECT) > SELECT) {
+ BKE_nurb_bezt_calc_normal(nu, bezt, tvec);
+ add_v3_v3(normal, tvec);
+ }
+ else {
+ if (bezt->f1 & SELECT) {
+ sub_v3_v3v3(tvec, bezt->vec[0], bezt->vec[1]);
+ normalize_v3(tvec);
+ add_v3_v3(normal, tvec);
+ }
+ if (bezt->f2 & SELECT) {
+ sub_v3_v3v3(tvec, bezt->vec[0], bezt->vec[2]);
+ normalize_v3(tvec);
+ add_v3_v3(normal, tvec);
+ }
+ if (bezt->f3 & SELECT) {
+ sub_v3_v3v3(tvec, bezt->vec[1], bezt->vec[2]);
+ normalize_v3(tvec);
+ add_v3_v3(normal, tvec);
+ }
+ }
+
+ BKE_nurb_bezt_calc_plane(nu, bezt, tvec);
+ add_v3_v3(plane, tvec);
}
+ bezt++;
}
- bezt++;
}
}
}
if (!is_zero_v3(normal)) {
- result = ORIENTATION_NORMAL;
+ result = ORIENTATION_FACE;
}
}
else if (obedit->type == OB_MBALL) {
@@ -716,7 +783,7 @@ int getTransformOrientation(const bContext *C, float normal[3], float plane[3],
copy_v3_v3(normal, qmat[2]);
- negate_v3_v3(plane, qmat[1]);
+ copy_v3_v3(plane, qmat[1]);
result = ORIENTATION_FACE;
}
@@ -724,45 +791,33 @@ int getTransformOrientation(const bContext *C, float normal[3], float plane[3],
else if (obedit->type == OB_ARMATURE) {
bArmature *arm = obedit->data;
EditBone *ebone;
- int ok = FALSE;
-
- /* grr. but better then duplicate code */
-#define EBONE_CALC_NORMAL_PLANE { \
- float tmat[3][3]; \
- float vec[3]; \
- sub_v3_v3v3(vec, ebone->tail, ebone->head); \
- normalize_v3(vec); \
- add_v3_v3(normal, vec); \
- \
- vec_roll_to_mat3(vec, ebone->roll, tmat); \
- add_v3_v3(plane, tmat[2]); \
- } (void)0
-
+ bool ok = false;
+ float tmat[3][3];
if (activeOnly && (ebone = arm->act_edbone)) {
- EBONE_CALC_NORMAL_PLANE;
- ok = TRUE;
+ ED_armature_ebone_to_mat3(ebone, tmat);
+ add_v3_v3(normal, tmat[2]);
+ add_v3_v3(plane, tmat[1]);
+ ok = true;
}
else {
for (ebone = arm->edbo->first; ebone; ebone = ebone->next) {
if (arm->layer & ebone->layer) {
if (ebone->flag & BONE_SELECTED) {
- EBONE_CALC_NORMAL_PLANE;
- ok = TRUE;
+ ED_armature_ebone_to_mat3(ebone, tmat);
+ add_v3_v3(normal, tmat[2]);
+ add_v3_v3(plane, tmat[1]);
+ ok = true;
}
}
}
}
if (ok) {
- normalize_v3(normal);
- normalize_v3(plane);
-
if (!is_zero_v3(plane)) {
result = ORIENTATION_EDGE;
}
}
-#undef EBONE_CALC_NORMAL_PLANE
}
/* Vectors from edges don't need the special transpose inverse multiplication */
@@ -804,8 +859,6 @@ int getTransformOrientation(const bContext *C, float normal[3], float plane[3],
/* use for both active & all */
if (ok) {
- negate_v3(plane);
-
/* we need the transpose of the inverse for a normal... */
copy_m3_m4(imat, ob->obmat);
@@ -823,11 +876,14 @@ int getTransformOrientation(const bContext *C, float normal[3], float plane[3],
else {
/* we need the one selected object, if its not active */
ob = OBACT;
- if (ob && !(ob->flag & SELECT)) ob = NULL;
-
- for (base = scene->base.first; base; base = base->next) {
- if (TESTBASELIB(v3d, base)) {
- if (ob == NULL) {
+ if (ob && (ob->flag & SELECT)) {
+ /* pass */
+ }
+ else {
+ /* first selected */
+ ob = NULL;
+ for (base = scene->base.first; base; base = base->next) {
+ if (TESTBASELIB(v3d, base)) {
ob = base->object;
break;
}
diff --git a/source/blender/editors/util/crazyspace.c b/source/blender/editors/util/crazyspace.c
index ea3687ad715..bed8aaaddf2 100644
--- a/source/blender/editors/util/crazyspace.c
+++ b/source/blender/editors/util/crazyspace.c
@@ -40,6 +40,7 @@
#include "BLI_utildefines.h"
#include "BLI_math.h"
+#include "BLI_bitmap.h"
#include "BKE_DerivedMesh.h"
#include "BKE_modifier.h"
@@ -51,7 +52,7 @@
typedef struct {
float *vertexcos;
- short *flags;
+ BLI_bitmap *vertex_visit;
} MappedUserData;
#define TAN_MAKE_VEC(a, b, c) a[0] = b[0] + 0.2f * (b[0] - c[0]); a[1] = b[1] + 0.2f * (b[1] - c[1]); a[2] = b[2] + 0.2f * (b[2] - c[2])
@@ -79,11 +80,11 @@ static void make_vertexcos__mapFunc(void *userData, int index, const float co[3]
float *vec = mappedData->vertexcos;
vec += 3 * index;
- if (!mappedData->flags[index]) {
+ if (BLI_BITMAP_GET(mappedData->vertex_visit, index) == 0) {
/* we need coord from prototype vertex, not it clones or images,
* suppose they stored in the beginning of vertex array stored in DM */
copy_v3_v3(vec, co);
- mappedData->flags[index] = 1;
+ BLI_BITMAP_SET(mappedData->vertex_visit, index);
}
}
@@ -109,7 +110,7 @@ float *crazyspace_get_mapped_editverts(Scene *scene, Object *obedit)
DerivedMesh *dm;
float *vertexcos;
int nverts = me->edit_btmesh->bm->totvert;
- short *flags;
+ BLI_bitmap *vertex_visit;
MappedUserData userData;
/* disable subsurf temporal, get mapped cos, and enable it */
@@ -122,18 +123,18 @@ float *crazyspace_get_mapped_editverts(Scene *scene, Object *obedit)
dm = editbmesh_get_derived_cage(scene, obedit, me->edit_btmesh, CD_MASK_BAREMESH);
vertexcos = MEM_callocN(3 * sizeof(float) * nverts, "vertexcos map");
- flags = MEM_callocN(sizeof(short) * nverts, "vertexcos flags");
+ vertex_visit = BLI_BITMAP_NEW(nverts, "vertexcos flags");
userData.vertexcos = vertexcos;
- userData.flags = flags;
- dm->foreachMappedVert(dm, make_vertexcos__mapFunc, &userData);
+ userData.vertex_visit = vertex_visit;
+ dm->foreachMappedVert(dm, make_vertexcos__mapFunc, &userData, DM_FOREACH_NOP);
dm->release(dm);
/* set back the flag, no new cage needs to be built, transform does it */
modifiers_disable_subsurf_temporary(obedit);
- MEM_freeN(flags);
+ MEM_freeN(vertex_visit);
return vertexcos;
}
@@ -278,7 +279,7 @@ int editbmesh_get_first_deform_matrices(Scene *scene, Object *ob, BMEditMesh *em
if (!defmats) {
dm = getEditDerivedBMesh(em, ob, NULL);
deformedVerts = editbmesh_get_vertex_cos(em, &numVerts);
- defmats = MEM_callocN(sizeof(*defmats) * numVerts, "defmats");
+ defmats = MEM_mallocN(sizeof(*defmats) * numVerts, "defmats");
for (a = 0; a < numVerts; a++)
unit_m3(defmats[a]);
diff --git a/source/blender/editors/uvedit/uvedit_draw.c b/source/blender/editors/uvedit/uvedit_draw.c
index 438f6bbdb9c..a873702b5b8 100644
--- a/source/blender/editors/uvedit/uvedit_draw.c
+++ b/source/blender/editors/uvedit/uvedit_draw.c
@@ -49,7 +49,6 @@
#include "BKE_mesh.h"
#include "BKE_editmesh.h"
-#include "BLI_array.h"
#include "BLI_buffer.h"
#include "BIF_gl.h"
@@ -66,6 +65,10 @@
#include "uvedit_intern.h"
+/* use editmesh tessface */
+#define USE_EDBM_LOOPTRIS
+
+
void draw_image_cursor(SpaceImage *sima, ARegion *ar)
{
float zoom[2], x_fac, y_fac;
@@ -257,6 +260,7 @@ static void draw_uvs_stretch(SpaceImage *sima, Scene *scene, BMEditMesh *em, MTe
weight_to_rgb(col, areadiff);
glColor3fv(col);
+ /* TODO: USE_EDBM_LOOPTRIS */
glBegin(GL_POLYGON);
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
@@ -321,6 +325,7 @@ static void draw_uvs_stretch(SpaceImage *sima, Scene *scene, BMEditMesh *em, MTe
ang[i] = angle_normalized_v3v3(av[i], av[(i + 1) % efa_len]);
}
+ /* TODO: USE_EDBM_LOOPTRIS */
glBegin(GL_POLYGON);
BM_ITER_ELEM_INDEX (l, &liter, efa, BM_LOOPS_OF_FACE, i) {
luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
@@ -421,6 +426,23 @@ static void draw_uvs_texpaint(SpaceImage *sima, Scene *scene, Object *ob)
}
}
+#ifdef USE_EDBM_LOOPTRIS
+static void draw_uvs_looptri(BMEditMesh *em, unsigned int *r_loop_index, const int cd_loop_uv_offset)
+{
+ unsigned int i = *r_loop_index;
+ BMFace *f = em->looptris[i][0]->f;
+ do {
+ unsigned int j;
+ for (j = 0; j < 3; j++) {
+ MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(em->looptris[i][j], cd_loop_uv_offset);
+ glVertex2fv(luv->uv);
+ }
+ i++;
+ } while (i != em->tottri && (f == em->looptris[i][0]->f));
+ *r_loop_index = i - 1;
+}
+#endif
+
/* draws uv's in the image space */
static void draw_uvs(SpaceImage *sima, Scene *scene, Object *obedit)
{
@@ -428,7 +450,10 @@ static void draw_uvs(SpaceImage *sima, Scene *scene, Object *obedit)
Mesh *me = obedit->data;
BMEditMesh *em = me->edit_btmesh;
BMesh *bm = em->bm;
- BMFace *efa, *efa_act, *activef;
+ BMFace *efa, *efa_act;
+#ifndef USE_EDBM_LOOPTRIS
+ BMFace *activef;
+#endif
BMLoop *l;
BMIter iter, liter;
MTexPoly *tf, *activetf = NULL;
@@ -443,7 +468,9 @@ static void draw_uvs(SpaceImage *sima, Scene *scene, Object *obedit)
const int cd_poly_tex_offset = CustomData_get_offset(&bm->pdata, CD_MTEXPOLY);
activetf = EDBM_mtexpoly_active_get(em, &efa_act, FALSE, FALSE); /* will be set to NULL if hidden */
+#ifndef USE_EDBM_LOOPTRIS
activef = BM_mesh_active_face_get(bm, FALSE, FALSE);
+#endif
ts = scene->toolsettings;
drawfaces = draw_uvs_face_check(scene);
@@ -490,9 +517,42 @@ static void draw_uvs(SpaceImage *sima, Scene *scene, Object *obedit)
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_BLEND);
+#ifdef USE_EDBM_LOOPTRIS
+ {
+ unsigned int i;
+ for (i = 0; i < em->tottri; i++) {
+ efa = em->looptris[i][0]->f;
+ tf = BM_ELEM_CD_GET_VOID_P(efa, cd_poly_tex_offset);
+ if (uvedit_face_visible_test(scene, ima, efa, tf)) {
+ const bool is_select = uvedit_face_select_test(scene, efa, cd_loop_uv_offset);
+ BM_elem_flag_enable(efa, BM_ELEM_TAG);
+
+ if (tf == activetf) {
+ /* only once */
+ glEnable(GL_POLYGON_STIPPLE);
+ glPolygonStipple(stipple_quarttone);
+ UI_ThemeColor4(TH_EDITMESH_ACTIVE);
+ }
+ else {
+ glColor4ubv((GLubyte *)(is_select ? col2 : col1));
+ }
+
+ glBegin(GL_TRIANGLES);
+ draw_uvs_looptri(em, &i, cd_loop_uv_offset);
+ glEnd();
+
+ if (tf == activetf) {
+ glDisable(GL_POLYGON_STIPPLE);
+ }
+ }
+ else {
+ BM_elem_flag_disable(efa, BM_ELEM_TAG);
+ }
+ }
+ }
+#else
BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) {
tf = BM_ELEM_CD_GET_VOID_P(efa, cd_poly_tex_offset);
-
if (uvedit_face_visible_test(scene, ima, efa, tf)) {
BM_elem_flag_enable(efa, BM_ELEM_TAG);
if (tf == activetf) continue; /* important the temp boolean is set above */
@@ -515,6 +575,7 @@ static void draw_uvs(SpaceImage *sima, Scene *scene, Object *obedit)
BM_elem_flag_disable(efa, BM_ELEM_TAG);
}
}
+#endif
glDisable(GL_BLEND);
}
else {
@@ -536,7 +597,7 @@ static void draw_uvs(SpaceImage *sima, Scene *scene, Object *obedit)
}
/* 3. draw active face stippled */
-
+#ifndef USE_EDBM_LOOPTRIS
if (activef) {
tf = BM_ELEM_CD_GET_VOID_P(activef, cd_poly_tex_offset);
if (uvedit_face_visible_test(scene, ima, activef, tf)) {
@@ -558,6 +619,7 @@ static void draw_uvs(SpaceImage *sima, Scene *scene, Object *obedit)
glDisable(GL_BLEND);
}
}
+#endif
/* 4. draw edges */
diff --git a/source/blender/editors/uvedit/uvedit_ops.c b/source/blender/editors/uvedit/uvedit_ops.c
index 0f7caf126d3..0b514e3f6fd 100644
--- a/source/blender/editors/uvedit/uvedit_ops.c
+++ b/source/blender/editors/uvedit/uvedit_ops.c
@@ -46,11 +46,12 @@
#include "DNA_space_types.h"
#include "DNA_scene_types.h"
+#include "BLI_utildefines.h"
+#include "BLI_alloca.h"
#include "BLI_math.h"
#include "BLI_lasso.h"
#include "BLI_blenlib.h"
#include "BLI_array.h"
-#include "BLI_utildefines.h"
#include "BKE_context.h"
#include "BKE_customdata.h"
diff --git a/source/blender/editors/uvedit/uvedit_parametrizer.c b/source/blender/editors/uvedit/uvedit_parametrizer.c
index 18f4e8cafaf..7851eebe269 100644
--- a/source/blender/editors/uvedit/uvedit_parametrizer.c
+++ b/source/blender/editors/uvedit/uvedit_parametrizer.c
@@ -26,15 +26,13 @@
#include "MEM_guardedalloc.h"
-#include "BLI_array.h"
+#include "BLI_utildefines.h"
+#include "BLI_alloca.h"
#include "BLI_memarena.h"
#include "BLI_math.h"
#include "BLI_rand.h"
#include "BLI_heap.h"
#include "BLI_boxpack2d.h"
-#include "BLI_utildefines.h"
-
-
#include "ONL_opennl.h"
diff --git a/source/blender/editors/uvedit/uvedit_unwrap_ops.c b/source/blender/editors/uvedit/uvedit_unwrap_ops.c
index a100757980c..49505b03a19 100644
--- a/source/blender/editors/uvedit/uvedit_unwrap_ops.c
+++ b/source/blender/editors/uvedit/uvedit_unwrap_ops.c
@@ -44,6 +44,7 @@
#include "DNA_modifier_types.h"
#include "BLI_utildefines.h"
+#include "BLI_alloca.h"
#include "BLI_math.h"
#include "BLI_edgehash.h"
#include "BLI_uvproject.h"
@@ -65,7 +66,6 @@
#include "BLI_math.h"
#include "BLI_edgehash.h"
#include "BLI_scanfill.h"
-#include "BLI_array.h"
#include "BLI_uvproject.h"
#include "PIL_time.h"
@@ -362,7 +362,7 @@ static ParamHandle *construct_param_handle_subsurfed(Scene *scene, Object *ob, B
ModifierData *md;
SubsurfModifierData *smd_real;
/* modifier initialization data, will control what type of subdivision will happen*/
- SubsurfModifierData smd = {{0}};
+ SubsurfModifierData smd = {{NULL}};
/* Used to hold subsurfed Mesh */
DerivedMesh *derivedMesh, *initialDerived;
/* holds original indices for subsurfed mesh */
diff --git a/source/blender/freestyle/intern/application/AppView.h b/source/blender/freestyle/intern/application/AppView.h
index ca250f89850..3f6d0b8e93e 100644
--- a/source/blender/freestyle/intern/application/AppView.h
+++ b/source/blender/freestyle/intern/application/AppView.h
@@ -234,7 +234,6 @@ protected:
NodeDrawingStyle *_p2DSelectionNode;
#ifdef WITH_CXX_GUARDEDALLOC
-public:
MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:AppView")
#endif
};
diff --git a/source/blender/freestyle/intern/application/Controller.h b/source/blender/freestyle/intern/application/Controller.h
index c8eaaf5486b..d4537f5f987 100644
--- a/source/blender/freestyle/intern/application/Controller.h
+++ b/source/blender/freestyle/intern/application/Controller.h
@@ -244,7 +244,6 @@ private:
FEdgeXDetector edgeDetector;
#ifdef WITH_CXX_GUARDEDALLOC
-public:
MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:Controller")
#endif
};
diff --git a/source/blender/freestyle/intern/blender_interface/BlenderFileLoader.h b/source/blender/freestyle/intern/blender_interface/BlenderFileLoader.h
index c505eab40f1..17c0dd0c6db 100644
--- a/source/blender/freestyle/intern/blender_interface/BlenderFileLoader.h
+++ b/source/blender/freestyle/intern/blender_interface/BlenderFileLoader.h
@@ -127,7 +127,6 @@ protected:
RenderMonitor *_pRenderMonitor;
#ifdef WITH_CXX_GUARDEDALLOC
-public:
MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:BlenderFileLoader")
#endif
};
diff --git a/source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.h b/source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.h
index ae0e6bed3b2..96ce8c1be7e 100644
--- a/source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.h
+++ b/source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.h
@@ -64,6 +64,11 @@ protected:
float get_stroke_vertex_z(void) const;
unsigned int get_stroke_mesh_id(void) const;
+
+#ifdef WITH_CXX_GUARDEDALLOC
+ MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:BlenderStrokeRenderer")
+#endif
+
};
} /* namespace Freestyle */
diff --git a/source/blender/freestyle/intern/blender_interface/BlenderStyleModule.h b/source/blender/freestyle/intern/blender_interface/BlenderStyleModule.h
index 7419d49ba4d..8a16a2b5c2a 100644
--- a/source/blender/freestyle/intern/blender_interface/BlenderStyleModule.h
+++ b/source/blender/freestyle/intern/blender_interface/BlenderStyleModule.h
@@ -58,6 +58,11 @@ protected:
private:
struct Text *_text;
+
+#ifdef WITH_CXX_GUARDEDALLOC
+ MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:BlenderStyleModule")
+#endif
+
};
} /* namespace Freestyle */
diff --git a/source/blender/freestyle/intern/blender_interface/BlenderTextureManager.h b/source/blender/freestyle/intern/blender_interface/BlenderTextureManager.h
index 1484188851d..b6cb303942a 100644
--- a/source/blender/freestyle/intern/blender_interface/BlenderTextureManager.h
+++ b/source/blender/freestyle/intern/blender_interface/BlenderTextureManager.h
@@ -43,6 +43,11 @@ protected:
protected:
virtual void loadStandardBrushes();
+
+#ifdef WITH_CXX_GUARDEDALLOC
+ MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:BlenderTextureManager")
+#endif
+
};
} /* namespace Freestyle */
diff --git a/source/blender/freestyle/intern/geometry/BBox.h b/source/blender/freestyle/intern/geometry/BBox.h
index 04fe6118815..794ceba48e7 100644
--- a/source/blender/freestyle/intern/geometry/BBox.h
+++ b/source/blender/freestyle/intern/geometry/BBox.h
@@ -136,7 +136,6 @@ private:
bool _empty;
#ifdef WITH_CXX_GUARDEDALLOC
-public:
MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:BBox")
#endif
};
diff --git a/source/blender/freestyle/intern/geometry/FastGrid.h b/source/blender/freestyle/intern/geometry/FastGrid.h
index 510a2b94225..e292589b7cf 100644
--- a/source/blender/freestyle/intern/geometry/FastGrid.h
+++ b/source/blender/freestyle/intern/geometry/FastGrid.h
@@ -76,6 +76,11 @@ public:
protected:
Cell **_cells;
unsigned _cells_size;
+
+#ifdef WITH_CXX_GUARDEDALLOC
+ MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:FastGrid")
+#endif
+
};
} /* namespace Freestyle */
diff --git a/source/blender/freestyle/intern/geometry/FitCurve.cpp b/source/blender/freestyle/intern/geometry/FitCurve.cpp
index a5701ea05e5..e517bf4f196 100644
--- a/source/blender/freestyle/intern/geometry/FitCurve.cpp
+++ b/source/blender/freestyle/intern/geometry/FitCurve.cpp
@@ -478,7 +478,7 @@ FitCurveWrapper::~FitCurveWrapper()
void FitCurveWrapper::DrawBezierCurve(int n, Vector2 *curve)
{
- for (int i = 0; i < n + 1; ++i)
+ for (int i = 0; i <= n; ++i)
_vertices.push_back(curve[i]);
}
diff --git a/source/blender/freestyle/intern/geometry/Grid.h b/source/blender/freestyle/intern/geometry/Grid.h
index 08b614faa95..a1368f1ea21 100644
--- a/source/blender/freestyle/intern/geometry/Grid.h
+++ b/source/blender/freestyle/intern/geometry/Grid.h
@@ -89,7 +89,6 @@ private:
OccludersSet _occluders;
#ifdef WITH_CXX_GUARDEDALLOC
-public:
MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:Cell")
#endif
};
@@ -372,7 +371,6 @@ protected:
OccludersSet _occluders; // List of all occluders inserted in the grid
#ifdef WITH_CXX_GUARDEDALLOC
-public:
MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:Grid")
#endif
};
@@ -395,7 +393,6 @@ private:
OccludersSet::iterator it, end;
#ifdef WITH_CXX_GUARDEDALLOC
-public:
MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:VirtualOccludersSet")
#endif
};
diff --git a/source/blender/freestyle/intern/geometry/Noise.h b/source/blender/freestyle/intern/geometry/Noise.h
index cd1be53a5aa..8798bc45a93 100644
--- a/source/blender/freestyle/intern/geometry/Noise.h
+++ b/source/blender/freestyle/intern/geometry/Noise.h
@@ -81,7 +81,6 @@ private:
// int start;
#ifdef WITH_CXX_GUARDEDALLOC
-public:
MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:Noise")
#endif
};
diff --git a/source/blender/freestyle/intern/geometry/Polygon.h b/source/blender/freestyle/intern/geometry/Polygon.h
index cfeae8fd632..d8b891c77cc 100644
--- a/source/blender/freestyle/intern/geometry/Polygon.h
+++ b/source/blender/freestyle/intern/geometry/Polygon.h
@@ -171,7 +171,6 @@ protected:
unsigned _id;
#ifdef WITH_CXX_GUARDEDALLOC
-public:
MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:Geometry:Polygon")
#endif
};
diff --git a/source/blender/freestyle/intern/geometry/SweepLine.h b/source/blender/freestyle/intern/geometry/SweepLine.h
index 86058a434bf..039ecd7ebf4 100644
--- a/source/blender/freestyle/intern/geometry/SweepLine.h
+++ b/source/blender/freestyle/intern/geometry/SweepLine.h
@@ -190,7 +190,6 @@ private:
bool _order; // true if A and B are in the same order than _edge.A and _edge.B. false otherwise.
#ifdef WITH_CXX_GUARDEDALLOC
-public:
MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:Segment")
#endif
};
@@ -337,7 +336,6 @@ private:
std::vector<Intersection<Segment<T, Point> > *> _Intersections; // the list of all intersections.
#ifdef WITH_CXX_GUARDEDALLOC
-public:
MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:SweepLine")
#endif
};
diff --git a/source/blender/freestyle/intern/geometry/VecMat.h b/source/blender/freestyle/intern/geometry/VecMat.h
index 1948dadb207..c3aae0601fe 100644
--- a/source/blender/freestyle/intern/geometry/VecMat.h
+++ b/source/blender/freestyle/intern/geometry/VecMat.h
@@ -278,7 +278,6 @@ protected:
};
#ifdef WITH_CXX_GUARDEDALLOC
-public:
MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:VecMat:Vec")
#endif
};
@@ -766,7 +765,6 @@ protected:
value_type _coord[_SIZE];
#ifdef WITH_CXX_GUARDEDALLOC
-public:
MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:VecMat:Matrix")
#endif
};
diff --git a/source/blender/freestyle/intern/geometry/normal_cycle.h b/source/blender/freestyle/intern/geometry/normal_cycle.h
index 441fca7ac5f..7a63acdf52a 100644
--- a/source/blender/freestyle/intern/geometry/normal_cycle.h
+++ b/source/blender/freestyle/intern/geometry/normal_cycle.h
@@ -129,7 +129,6 @@ private:
int i_[3];
#ifdef WITH_CXX_GUARDEDALLOC
-public:
MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:OGF:NormalCycle")
#endif
};
diff --git a/source/blender/freestyle/intern/image/GaussianFilter.h b/source/blender/freestyle/intern/image/GaussianFilter.h
index 313441a07d3..d3175e86382 100644
--- a/source/blender/freestyle/intern/image/GaussianFilter.h
+++ b/source/blender/freestyle/intern/image/GaussianFilter.h
@@ -115,7 +115,6 @@ protected:
void computeMask();
#ifdef WITH_CXX_GUARDEDALLOC
-public:
MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:GaussianFilter")
#endif
};
diff --git a/source/blender/freestyle/intern/image/Image.h b/source/blender/freestyle/intern/image/Image.h
index 12be1816c1a..577dc0fb866 100644
--- a/source/blender/freestyle/intern/image/Image.h
+++ b/source/blender/freestyle/intern/image/Image.h
@@ -173,7 +173,6 @@ protected:
unsigned _Oy; // origin of the stored part
#ifdef WITH_CXX_GUARDEDALLOC
-public:
MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:FrsImage")
#endif
};
diff --git a/source/blender/freestyle/intern/python/Interface0D/BPy_CurvePoint.cpp b/source/blender/freestyle/intern/python/Interface0D/BPy_CurvePoint.cpp
index 4fa46b62185..69d0adadc00 100644
--- a/source/blender/freestyle/intern/python/Interface0D/BPy_CurvePoint.cpp
+++ b/source/blender/freestyle/intern/python/Interface0D/BPy_CurvePoint.cpp
@@ -135,7 +135,7 @@ static int CurvePoint_init(BPy_CurvePoint *self, PyObject *args, PyObject *kwds)
PyDoc_STRVAR(CurvePoint_first_svertex_doc,
"The first SVertex upon which the CurvePoint is built.\n"
"\n"
-":type: int");
+":type: :class:`SVertex`");
static PyObject *CurvePoint_first_svertex_get(BPy_CurvePoint *self, void *UNUSED(closure))
{
@@ -158,7 +158,7 @@ static int CurvePoint_first_svertex_set(BPy_CurvePoint *self, PyObject *value, v
PyDoc_STRVAR(CurvePoint_second_svertex_doc,
"The second SVertex upon which the CurvePoint is built.\n"
"\n"
-":type: int");
+":type: :class:`SVertex`");
static PyObject *CurvePoint_second_svertex_get(BPy_CurvePoint *self, void *UNUSED(closure))
{
diff --git a/source/blender/freestyle/intern/python/Interface0D/BPy_SVertex.cpp b/source/blender/freestyle/intern/python/Interface0D/BPy_SVertex.cpp
index 37c25760bd7..3205a3a3d7e 100644
--- a/source/blender/freestyle/intern/python/Interface0D/BPy_SVertex.cpp
+++ b/source/blender/freestyle/intern/python/Interface0D/BPy_SVertex.cpp
@@ -371,6 +371,7 @@ static PyObject *SVertex_normals_size_get(BPy_SVertex *self, void *UNUSED(closur
PyDoc_STRVAR(SVertex_viewvertex_doc,
"If this SVertex is also a ViewVertex, this property refers to the\n"
"ViewVertex, and None otherwise.\n"
+"\n"
":type: :class:`ViewVertex`");
static PyObject *SVertex_viewvertex_get(BPy_SVertex *self, void *UNUSED(closure))
diff --git a/source/blender/freestyle/intern/scene_graph/DrawingStyle.h b/source/blender/freestyle/intern/scene_graph/DrawingStyle.h
index 9fbdd0e0fad..192fa76c497 100644
--- a/source/blender/freestyle/intern/scene_graph/DrawingStyle.h
+++ b/source/blender/freestyle/intern/scene_graph/DrawingStyle.h
@@ -106,7 +106,6 @@ private:
bool LightingEnabled;
#ifdef WITH_CXX_GUARDEDALLOC
-public:
MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:DrawingStyle")
#endif
};
diff --git a/source/blender/freestyle/intern/scene_graph/FrsMaterial.h b/source/blender/freestyle/intern/scene_graph/FrsMaterial.h
index 7e9eeda26d5..4d1fc4e69c9 100644
--- a/source/blender/freestyle/intern/scene_graph/FrsMaterial.h
+++ b/source/blender/freestyle/intern/scene_graph/FrsMaterial.h
@@ -259,7 +259,6 @@ private:
float Shininess;
#ifdef WITH_CXX_GUARDEDALLOC
-public:
MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:FrsMaterial")
#endif
};
diff --git a/source/blender/freestyle/intern/scene_graph/IndexedFaceSet.h b/source/blender/freestyle/intern/scene_graph/IndexedFaceSet.h
index 2995360fb24..1ffddc9b24d 100644
--- a/source/blender/freestyle/intern/scene_graph/IndexedFaceSet.h
+++ b/source/blender/freestyle/intern/scene_graph/IndexedFaceSet.h
@@ -312,6 +312,11 @@ protected:
unsigned _TISize;
unsigned int _displayList;
+
+#ifdef WITH_CXX_GUARDEDALLOC
+ MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:IndexedFaceSet")
+#endif
+
};
} /* namespace Freestyle */
diff --git a/source/blender/freestyle/intern/scene_graph/LineRep.h b/source/blender/freestyle/intern/scene_graph/LineRep.h
index c5de30309f6..6452e1260ad 100644
--- a/source/blender/freestyle/intern/scene_graph/LineRep.h
+++ b/source/blender/freestyle/intern/scene_graph/LineRep.h
@@ -148,6 +148,11 @@ private:
LINES_STYLE _Style;
vector<Vec3r> _vertices;
float _width;
+
+#ifdef WITH_CXX_GUARDEDALLOC
+ MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:LineRep")
+#endif
+
};
} /* namespace Freestyle */
diff --git a/source/blender/freestyle/intern/scene_graph/Node.h b/source/blender/freestyle/intern/scene_graph/Node.h
index 47ce6aaf8e6..ba8549f5128 100644
--- a/source/blender/freestyle/intern/scene_graph/Node.h
+++ b/source/blender/freestyle/intern/scene_graph/Node.h
@@ -106,6 +106,11 @@ protected:
private:
BBox<Vec3r> _BBox;
+
+#ifdef WITH_CXX_GUARDEDALLOC
+ MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:Node")
+#endif
+
};
} /* namespace Freestyle */
diff --git a/source/blender/freestyle/intern/scene_graph/NodeCamera.h b/source/blender/freestyle/intern/scene_graph/NodeCamera.h
index 8e5cf9be52d..ee630e91884 100644
--- a/source/blender/freestyle/intern/scene_graph/NodeCamera.h
+++ b/source/blender/freestyle/intern/scene_graph/NodeCamera.h
@@ -83,6 +83,11 @@ protected:
double projection_matrix_[16];
CameraType camera_type_;
+
+#ifdef WITH_CXX_GUARDEDALLOC
+ MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:NodeCamera")
+#endif
+
};
class LIB_SCENE_GRAPH_EXPORT NodeOrthographicCamera : public NodeCamera
@@ -145,6 +150,11 @@ private:
double top_;
double zNear_;
double zFar_;
+
+#ifdef WITH_CXX_GUARDEDALLOC
+ MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:NodeOrthographicCamera")
+#endif
+
};
class LIB_SCENE_GRAPH_EXPORT NodePerspectiveCamera : public NodeCamera
@@ -205,6 +215,11 @@ public:
* zFar-zNear
*/
NodePerspectiveCamera(double left, double right, double bottom, double top, double zNear, double zFar);
+
+#ifdef WITH_CXX_GUARDEDALLOC
+ MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:NodePerspectiveCamera")
+#endif
+
};
} /* namespace Freestyle */
diff --git a/source/blender/freestyle/intern/scene_graph/NodeDrawingStyle.h b/source/blender/freestyle/intern/scene_graph/NodeDrawingStyle.h
index a846b050db1..7e8c6635953 100644
--- a/source/blender/freestyle/intern/scene_graph/NodeDrawingStyle.h
+++ b/source/blender/freestyle/intern/scene_graph/NodeDrawingStyle.h
@@ -101,6 +101,11 @@ public:
private:
DrawingStyle _DrawingStyle;
+
+#ifdef WITH_CXX_GUARDEDALLOC
+ MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:NodeDrawingStyle")
+#endif
+
};
} /* namespace Freestyle */
diff --git a/source/blender/freestyle/intern/stroke/Module.h b/source/blender/freestyle/intern/stroke/Module.h
index b43c2d6247e..64b6f34afa4 100644
--- a/source/blender/freestyle/intern/stroke/Module.h
+++ b/source/blender/freestyle/intern/stroke/Module.h
@@ -78,7 +78,6 @@ private:
}
#ifdef WITH_CXX_GUARDEDALLOC
-public:
MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:Module")
#endif
};
diff --git a/source/blender/freestyle/intern/stroke/Operators.h b/source/blender/freestyle/intern/stroke/Operators.h
index 61b20f556b5..dcd61b8ce84 100644
--- a/source/blender/freestyle/intern/stroke/Operators.h
+++ b/source/blender/freestyle/intern/stroke/Operators.h
@@ -270,7 +270,6 @@ private:
static StrokesContainer _current_strokes_set;
#ifdef WITH_CXX_GUARDEDALLOC
-public:
MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:Operators")
#endif
};
diff --git a/source/blender/freestyle/intern/stroke/Predicates0D.h b/source/blender/freestyle/intern/stroke/Predicates0D.h
index 0f04c0827c3..a6e7cbee042 100644
--- a/source/blender/freestyle/intern/stroke/Predicates0D.h
+++ b/source/blender/freestyle/intern/stroke/Predicates0D.h
@@ -82,7 +82,6 @@ public:
}
#ifdef WITH_CXX_GUARDEDALLOC
-public:
MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:UnaryPredicate0D")
#endif
};
@@ -133,7 +132,6 @@ public:
}
#ifdef WITH_CXX_GUARDEDALLOC
-public:
MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:BinaryPredicate0D")
#endif
};
diff --git a/source/blender/freestyle/intern/stroke/Stroke.h b/source/blender/freestyle/intern/stroke/Stroke.h
index 5415d003c5e..e7a75728985 100644
--- a/source/blender/freestyle/intern/stroke/Stroke.h
+++ b/source/blender/freestyle/intern/stroke/Stroke.h
@@ -303,7 +303,6 @@ private:
Vec3fMap *_userAttributesVec3f;
#ifdef WITH_CXX_GUARDEDALLOC
-public:
MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:StrokeAttribute")
#endif
};
diff --git a/source/blender/freestyle/intern/stroke/StrokeRenderer.h b/source/blender/freestyle/intern/stroke/StrokeRenderer.h
index e38b7107efd..e5478c81b40 100644
--- a/source/blender/freestyle/intern/stroke/StrokeRenderer.h
+++ b/source/blender/freestyle/intern/stroke/StrokeRenderer.h
@@ -113,7 +113,6 @@ protected:
unsigned int _defaultTextureId;
#ifdef WITH_CXX_GUARDEDALLOC
-public:
MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:TextureManager")
#endif
};
diff --git a/source/blender/freestyle/intern/stroke/StrokeRep.cpp b/source/blender/freestyle/intern/stroke/StrokeRep.cpp
index c2811895147..2615df0a124 100644
--- a/source/blender/freestyle/intern/stroke/StrokeRep.cpp
+++ b/source/blender/freestyle/intern/stroke/StrokeRep.cpp
@@ -414,10 +414,10 @@ void Strip::cleanUpSingularities (const vector<StrokeVertex*>& iStrokeVertices)
cerr << "Stephane dit \"Toto\"" << endl;
//traverse all the vertices of the singularity and average them
Vec2r avP(0.0, 0.0);
- for (j = i - timeSinceSingu1; j < i + 1; j++)
+ for (j = i - timeSinceSingu1; j <= i; j++)
avP = Vec2r(avP + _vertices[2 * j]->point2d());
avP = Vec2r( 1.0 / float(timeSinceSingu1 + 1) * avP);
- for (j = i - timeSinceSingu1; j < i + 1; j++)
+ for (j = i - timeSinceSingu1; j <= i; j++)
_vertices[2 * j]->setPoint2d(avP);
//_vertex[2 * j] = _vertex[2 * i];
singu1 = false;
@@ -435,10 +435,10 @@ void Strip::cleanUpSingularities (const vector<StrokeVertex*>& iStrokeVertices)
cerr << "Stephane dit \"Toto\"" << endl;
//traverse all the vertices of the singularity and average them
Vec2r avP(0.0, 0.0);
- for (j = i - timeSinceSingu2; j < i + 1; j++)
+ for (j = i - timeSinceSingu2; j <= i; j++)
avP = Vec2r(avP + _vertices[2 * j + 1]->point2d());
avP = Vec2r(1.0 / float(timeSinceSingu2 + 1) * avP);
- for (j = i - timeSinceSingu2; j < i + 1; j++)
+ for (j = i - timeSinceSingu2; j <= i; j++)
_vertices[2 * j + 1]->setPoint2d(avP);
//_vertex[2 * j + 1] = _vertex[2 * i + 1];
singu2 = false;
diff --git a/source/blender/freestyle/intern/stroke/StrokeRep.h b/source/blender/freestyle/intern/stroke/StrokeRep.h
index 38d6716584d..d01b27215fe 100644
--- a/source/blender/freestyle/intern/stroke/StrokeRep.h
+++ b/source/blender/freestyle/intern/stroke/StrokeRep.h
@@ -120,7 +120,6 @@ protected:
float _alpha;
#ifdef WITH_CXX_GUARDEDALLOC
-public:
MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:StrokeVertexRep")
#endif
};
diff --git a/source/blender/freestyle/intern/stroke/StrokeTesselator.h b/source/blender/freestyle/intern/stroke/StrokeTesselator.h
index e8ff75f7a96..661c871a4d5 100644
--- a/source/blender/freestyle/intern/stroke/StrokeTesselator.h
+++ b/source/blender/freestyle/intern/stroke/StrokeTesselator.h
@@ -74,7 +74,6 @@ private:
bool _overloadFrsMaterial;
#ifdef WITH_CXX_GUARDEDALLOC
-public:
MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:StrokeTesselator")
#endif
};
diff --git a/source/blender/freestyle/intern/stroke/StyleModule.h b/source/blender/freestyle/intern/stroke/StyleModule.h
index c34a288c5d6..f1d96283f90 100644
--- a/source/blender/freestyle/intern/stroke/StyleModule.h
+++ b/source/blender/freestyle/intern/stroke/StyleModule.h
@@ -180,7 +180,6 @@ protected:
Interpreter *_inter;
#ifdef WITH_CXX_GUARDEDALLOC
-public:
MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:StyleModule")
#endif
};
diff --git a/source/blender/freestyle/intern/system/BaseIterator.h b/source/blender/freestyle/intern/system/BaseIterator.h
index f27bfb68b9f..9eb06744095 100644
--- a/source/blender/freestyle/intern/system/BaseIterator.h
+++ b/source/blender/freestyle/intern/system/BaseIterator.h
@@ -109,7 +109,6 @@ protected:
IteratorBase() {}
#ifdef WITH_CXX_GUARDEDALLOC
-public:
MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:IteratorBase")
#endif
};
diff --git a/source/blender/freestyle/intern/system/BaseObject.h b/source/blender/freestyle/intern/system/BaseObject.h
index a9e501be38f..56f52a5fb80 100644
--- a/source/blender/freestyle/intern/system/BaseObject.h
+++ b/source/blender/freestyle/intern/system/BaseObject.h
@@ -73,7 +73,6 @@ private:
unsigned _ref_counter;
#ifdef WITH_CXX_GUARDEDALLOC
-public:
MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:BaseObject")
#endif
};
diff --git a/source/blender/freestyle/intern/system/Exception.h b/source/blender/freestyle/intern/system/Exception.h
index d69de7b10dd..dedc4152ae9 100644
--- a/source/blender/freestyle/intern/system/Exception.h
+++ b/source/blender/freestyle/intern/system/Exception.h
@@ -66,7 +66,6 @@ private:
static exception_type _exception;
#ifdef WITH_CXX_GUARDEDALLOC
-public:
MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:Exception")
#endif
};
diff --git a/source/blender/freestyle/intern/system/Id.h b/source/blender/freestyle/intern/system/Id.h
index 5260a38c709..9cd45646f1c 100644
--- a/source/blender/freestyle/intern/system/Id.h
+++ b/source/blender/freestyle/intern/system/Id.h
@@ -131,7 +131,6 @@ private:
id_type _second;
#ifdef WITH_CXX_GUARDEDALLOC
-public:
MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:Id")
#endif
};
diff --git a/source/blender/freestyle/intern/system/Interpreter.h b/source/blender/freestyle/intern/system/Interpreter.h
index 9b7acc1cf46..e1269f40468 100644
--- a/source/blender/freestyle/intern/system/Interpreter.h
+++ b/source/blender/freestyle/intern/system/Interpreter.h
@@ -61,7 +61,6 @@ protected:
string _language;
#ifdef WITH_CXX_GUARDEDALLOC
-public:
MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:Interpreter")
#endif
};
diff --git a/source/blender/freestyle/intern/system/ProgressBar.h b/source/blender/freestyle/intern/system/ProgressBar.h
index 754004d7f81..56dbef59b0e 100644
--- a/source/blender/freestyle/intern/system/ProgressBar.h
+++ b/source/blender/freestyle/intern/system/ProgressBar.h
@@ -92,7 +92,6 @@ protected:
string _label;
#ifdef WITH_CXX_GUARDEDALLOC
-public:
MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:ProgressBar")
#endif
};
diff --git a/source/blender/freestyle/intern/system/PseudoNoise.h b/source/blender/freestyle/intern/system/PseudoNoise.h
index ce725723b59..e53d8ed7a7a 100644
--- a/source/blender/freestyle/intern/system/PseudoNoise.h
+++ b/source/blender/freestyle/intern/system/PseudoNoise.h
@@ -57,7 +57,6 @@ protected:
static real _values[NB_VALUE_NOISE];
#ifdef WITH_CXX_GUARDEDALLOC
-public:
MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:PseudoNoise")
#endif
};
diff --git a/source/blender/freestyle/intern/system/RandGen.h b/source/blender/freestyle/intern/system/RandGen.h
index c3e2b3d99f7..3c8724bcbee 100644
--- a/source/blender/freestyle/intern/system/RandGen.h
+++ b/source/blender/freestyle/intern/system/RandGen.h
@@ -50,7 +50,6 @@ private:
static void next();
#ifdef WITH_CXX_GUARDEDALLOC
-public:
MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:RandGen")
#endif
};
diff --git a/source/blender/freestyle/intern/system/RenderMonitor.h b/source/blender/freestyle/intern/system/RenderMonitor.h
index 0453f81e5b5..7910bf13c63 100644
--- a/source/blender/freestyle/intern/system/RenderMonitor.h
+++ b/source/blender/freestyle/intern/system/RenderMonitor.h
@@ -72,7 +72,6 @@ protected:
Render *_re;
#ifdef WITH_CXX_GUARDEDALLOC
-public:
MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:RenderMonitor")
#endif
};
diff --git a/source/blender/freestyle/intern/system/TimeStamp.h b/source/blender/freestyle/intern/system/TimeStamp.h
index 052816c5a85..e809aa71575 100644
--- a/source/blender/freestyle/intern/system/TimeStamp.h
+++ b/source/blender/freestyle/intern/system/TimeStamp.h
@@ -72,7 +72,6 @@ private:
unsigned _time_stamp;
#ifdef WITH_CXX_GUARDEDALLOC
-public:
MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:TimeStamp")
#endif
};
diff --git a/source/blender/freestyle/intern/system/TimeUtils.h b/source/blender/freestyle/intern/system/TimeUtils.h
index 1bdcf2d7d38..bbf4c5a1edb 100644
--- a/source/blender/freestyle/intern/system/TimeUtils.h
+++ b/source/blender/freestyle/intern/system/TimeUtils.h
@@ -60,7 +60,6 @@ private:
clock_t _start;
#ifdef WITH_CXX_GUARDEDALLOC
-public:
MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:Chronometer")
#endif
};
diff --git a/source/blender/freestyle/intern/view_map/BoxGrid.h b/source/blender/freestyle/intern/view_map/BoxGrid.h
index 8aa5167732d..92f886ef429 100644
--- a/source/blender/freestyle/intern/view_map/BoxGrid.h
+++ b/source/blender/freestyle/intern/view_map/BoxGrid.h
@@ -72,7 +72,6 @@ public:
WFace *face;
#ifdef WITH_CXX_GUARDEDALLOC
- public:
MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:BoxGrid:OccluderData")
#endif
};
@@ -137,7 +136,6 @@ public:
vector<OccluderData*>::iterator _current, _occludeeCandidate;
#ifdef WITH_CXX_GUARDEDALLOC
- public:
MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:BoxGrid:Iterator")
#endif
};
@@ -192,7 +190,6 @@ private:
bool _enableQI;
#ifdef WITH_CXX_GUARDEDALLOC
-public:
MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:BoxGrid")
#endif
};
diff --git a/source/blender/freestyle/intern/view_map/FEdgeXDetector.h b/source/blender/freestyle/intern/view_map/FEdgeXDetector.h
index 59d6e23312f..2bc0cd13e88 100644
--- a/source/blender/freestyle/intern/view_map/FEdgeXDetector.h
+++ b/source/blender/freestyle/intern/view_map/FEdgeXDetector.h
@@ -237,7 +237,6 @@ protected:
RenderMonitor *_pRenderMonitor;
#ifdef WITH_CXX_GUARDEDALLOC
-public:
MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:FEdgeXDetector")
#endif
};
diff --git a/source/blender/freestyle/intern/view_map/Functions1D.h b/source/blender/freestyle/intern/view_map/Functions1D.h
index a4dd1cd5e03..2d3da151d13 100644
--- a/source/blender/freestyle/intern/view_map/Functions1D.h
+++ b/source/blender/freestyle/intern/view_map/Functions1D.h
@@ -125,7 +125,6 @@ protected:
IntegrationType _integration;
#ifdef WITH_CXX_GUARDEDALLOC
-public:
MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:UnaryFunction1D")
#endif
};
@@ -172,7 +171,6 @@ protected:
IntegrationType _integration;
#ifdef WITH_CXX_GUARDEDALLOC
-public:
MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:UnaryFunction1D_void")
#endif
};
diff --git a/source/blender/freestyle/intern/view_map/GridDensityProvider.h b/source/blender/freestyle/intern/view_map/GridDensityProvider.h
index fe14efbe20f..f14362e3deb 100644
--- a/source/blender/freestyle/intern/view_map/GridDensityProvider.h
+++ b/source/blender/freestyle/intern/view_map/GridDensityProvider.h
@@ -134,7 +134,6 @@ protected:
float _cellOrigin[2];
#ifdef WITH_CXX_GUARDEDALLOC
-public:
MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:GridDensityProvider")
#endif
};
diff --git a/source/blender/freestyle/intern/view_map/Interface1D.h b/source/blender/freestyle/intern/view_map/Interface1D.h
index 2c1f4956e96..c7beafaf14d 100644
--- a/source/blender/freestyle/intern/view_map/Interface1D.h
+++ b/source/blender/freestyle/intern/view_map/Interface1D.h
@@ -226,7 +226,6 @@ protected:
unsigned _timeStamp;
#ifdef WITH_CXX_GUARDEDALLOC
-public:
MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:Interface1D")
#endif
};
diff --git a/source/blender/freestyle/intern/view_map/OccluderSource.h b/source/blender/freestyle/intern/view_map/OccluderSource.h
index b6f30ce9e3a..b916661e04c 100644
--- a/source/blender/freestyle/intern/view_map/OccluderSource.h
+++ b/source/blender/freestyle/intern/view_map/OccluderSource.h
@@ -72,7 +72,6 @@ protected:
void buildCachedPolygon();
#ifdef WITH_CXX_GUARDEDALLOC
-public:
MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:OccluderSource")
#endif
};
diff --git a/source/blender/freestyle/intern/view_map/SphericalGrid.h b/source/blender/freestyle/intern/view_map/SphericalGrid.h
index 56d2ae3cf5e..050dcc4c882 100644
--- a/source/blender/freestyle/intern/view_map/SphericalGrid.h
+++ b/source/blender/freestyle/intern/view_map/SphericalGrid.h
@@ -135,7 +135,6 @@ public:
vector<OccluderData*>::iterator _current, _occludeeCandidate;
#ifdef WITH_CXX_GUARDEDALLOC
- public:
MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:SphericalGrid:Iterator")
#endif
@@ -191,7 +190,6 @@ private:
bool _enableQI;
#ifdef WITH_CXX_GUARDEDALLOC
-public:
MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:SphericalGrid")
#endif
};
diff --git a/source/blender/freestyle/intern/view_map/SteerableViewMap.cpp b/source/blender/freestyle/intern/view_map/SteerableViewMap.cpp
index 7693afdce07..c777db6249f 100644
--- a/source/blender/freestyle/intern/view_map/SteerableViewMap.cpp
+++ b/source/blender/freestyle/intern/view_map/SteerableViewMap.cpp
@@ -74,7 +74,7 @@ SteerableViewMap::SteerableViewMap(const SteerableViewMap& iBrother)
_directions = iBrother._directions;
_mapping = iBrother._mapping;
_imagesPyramids = new ImagePyramid *[_nbOrientations + 1]; // one more map to store the complete visible VM
- for (i = 0; i < _nbOrientations + 1; ++i)
+ for (i = 0; i <= _nbOrientations; ++i)
_imagesPyramids[i] = new GaussianPyramid(*(dynamic_cast<GaussianPyramid*>(iBrother._imagesPyramids[i])));
}
diff --git a/source/blender/freestyle/intern/view_map/SteerableViewMap.h b/source/blender/freestyle/intern/view_map/SteerableViewMap.h
index 9af65765fcd..23681b43c48 100644
--- a/source/blender/freestyle/intern/view_map/SteerableViewMap.h
+++ b/source/blender/freestyle/intern/view_map/SteerableViewMap.h
@@ -150,7 +150,6 @@ protected:
void Build();
#ifdef WITH_CXX_GUARDEDALLOC
-public:
MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:SteerableViewMap")
#endif
};
diff --git a/source/blender/freestyle/intern/view_map/ViewEdgeXBuilder.h b/source/blender/freestyle/intern/view_map/ViewEdgeXBuilder.h
index b036410a9fe..6efc81efbaf 100644
--- a/source/blender/freestyle/intern/view_map/ViewEdgeXBuilder.h
+++ b/source/blender/freestyle/intern/view_map/ViewEdgeXBuilder.h
@@ -293,7 +293,6 @@ protected:
ViewShape *_pCurrentVShape;
#ifdef WITH_CXX_GUARDEDALLOC
-public:
MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:ViewEdgeXBuilder")
#endif
};
diff --git a/source/blender/freestyle/intern/view_map/ViewMap.h b/source/blender/freestyle/intern/view_map/ViewMap.h
index f684f2b919d..987a5bda9b3 100644
--- a/source/blender/freestyle/intern/view_map/ViewMap.h
+++ b/source/blender/freestyle/intern/view_map/ViewMap.h
@@ -365,6 +365,11 @@ public:
/*! Returns an orientedViewEdgeIterator pointing to the ViewEdge given as argument. */
virtual ViewVertexInternal::orientedViewEdgeIterator edgesIterator(ViewEdge *iEdge) = 0;
+
+#ifdef WITH_CXX_GUARDEDALLOC
+ MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:ViewVertex")
+#endif
+
};
/**********************************/
@@ -633,6 +638,11 @@ public:
/*! Returns an orientedViewEdgeIterator pointing to the ViewEdge given as argument. */
virtual ViewVertexInternal::orientedViewEdgeIterator edgesIterator(ViewEdge *iEdge);
+
+#ifdef WITH_CXX_GUARDEDALLOC
+ MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:TVertex")
+#endif
+
};
@@ -845,6 +855,11 @@ public:
/*! Returns an orientedViewEdgeIterator pointing to the ViewEdge given as argument. */
virtual ViewVertexInternal::orientedViewEdgeIterator edgesIterator(ViewEdge *iEdge);
+
+#ifdef WITH_CXX_GUARDEDALLOC
+ MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:NonTVertex")
+#endif
+
};
/**********************************/
@@ -1360,6 +1375,11 @@ public:
* the sampling value.
*/
virtual Interface0DIterator pointsEnd(float t = 0.0f);
+
+#ifdef WITH_CXX_GUARDEDALLOC
+ MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:ViewEdge")
+#endif
+
};
diff --git a/source/blender/freestyle/intern/view_map/ViewMapBuilder.h b/source/blender/freestyle/intern/view_map/ViewMapBuilder.h
index 05596daa85b..29e393052a3 100644
--- a/source/blender/freestyle/intern/view_map/ViewMapBuilder.h
+++ b/source/blender/freestyle/intern/view_map/ViewMapBuilder.h
@@ -253,7 +253,6 @@ protected:
Vec3r& u, Vec3r& A, Vec3r& origin, Vec3r& edge, vector<WVertex*>& faceVertices);
#ifdef WITH_CXX_GUARDEDALLOC
-public:
MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:ViewMapBuilder")
#endif
};
diff --git a/source/blender/freestyle/intern/view_map/ViewMapIO.cpp b/source/blender/freestyle/intern/view_map/ViewMapIO.cpp
index 5df3e4e0d8f..e78fb894be0 100644
--- a/source/blender/freestyle/intern/view_map/ViewMapIO.cpp
+++ b/source/blender/freestyle/intern/view_map/ViewMapIO.cpp
@@ -982,7 +982,7 @@ int load(istream& in, ViewMap *vm, ProgressBar *pb)
if (fe_s) {
bool b;
READ(b);
- for (READ(fe_rle1), fe_rle2 = 0; fe_rle1 < fe_s + 1; fe_rle2 = fe_rle1, READ(fe_rle1)) {
+ for (READ(fe_rle1), fe_rle2 = 0; fe_rle1 <= fe_s; fe_rle2 = fe_rle1, READ(fe_rle1)) {
if (b) {
for (unsigned int i = fe_rle2; i < fe_rle1; i++) {
FEdgeSmooth *fes = new FEdgeSmooth;
@@ -1007,7 +1007,7 @@ int load(istream& in, ViewMap *vm, ProgressBar *pb)
if (vv_s) {
Nature::VertexNature nature;
READ(nature);
- for (READ(vv_rle1), vv_rle2 = 0; vv_rle1 < vv_s + 1; vv_rle2 = vv_rle1, READ(vv_rle1)) {
+ for (READ(vv_rle1), vv_rle2 = 0; vv_rle1 <= vv_s; vv_rle2 = vv_rle1, READ(vv_rle1)) {
if (nature & Nature::T_VERTEX) {
for (unsigned int i = vv_rle2; i < vv_rle1; i++) {
TVertex *tv = new TVertex();
diff --git a/source/blender/freestyle/intern/view_map/ViewMapIterators.h b/source/blender/freestyle/intern/view_map/ViewMapIterators.h
index 72d439da8bd..2794d9028d2 100644
--- a/source/blender/freestyle/intern/view_map/ViewMapIterators.h
+++ b/source/blender/freestyle/intern/view_map/ViewMapIterators.h
@@ -219,6 +219,11 @@ public:
}
return 0;
}
+
+#ifdef WITH_CXX_GUARDEDALLOC
+ MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:orientedViewEdgeIterator")
+#endif
+
};
} // ViewVertexInternal namespace
@@ -390,6 +395,11 @@ private:
FEdge *_previous_edge;
FEdge *_next_edge;
float _t; // curvilinear abscissa
+
+#ifdef WITH_CXX_GUARDEDALLOC
+ MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:SVertexIterator")
+#endif
+
};
@@ -561,6 +571,11 @@ protected:
bool _orientation;
ViewEdge *_edge;
ViewEdge *_begin;
+
+#ifdef WITH_CXX_GUARDEDALLOC
+ MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:ViewEdgeIterator")
+#endif
+
};
} // end of namespace ViewEdgeInternal
diff --git a/source/blender/freestyle/intern/view_map/ViewMapTesselator.h b/source/blender/freestyle/intern/view_map/ViewMapTesselator.h
index d37d0b6e5a5..9c4d214d931 100644
--- a/source/blender/freestyle/intern/view_map/ViewMapTesselator.h
+++ b/source/blender/freestyle/intern/view_map/ViewMapTesselator.h
@@ -104,7 +104,6 @@ private:
bool _overloadFrsMaterial;
#ifdef WITH_CXX_GUARDEDALLOC
-public:
MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:ViewMapTesselator")
#endif
};
@@ -121,6 +120,11 @@ protected:
{
iLine->AddVertex(v->point2D());
}
+
+#ifdef WITH_CXX_GUARDEDALLOC
+ MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:ViewMapTesselator2D")
+#endif
+
};
/*! Class to tesselate the 3D silhouette */
@@ -135,6 +139,11 @@ protected:
{
iLine->AddVertex(v->point3D());
}
+
+#ifdef WITH_CXX_GUARDEDALLOC
+ MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:ViewMapTesselator3D")
+#endif
+
};
//
diff --git a/source/blender/freestyle/intern/winged_edge/WEdge.h b/source/blender/freestyle/intern/winged_edge/WEdge.h
index e5020f2a7fa..f0692aecd5b 100644
--- a/source/blender/freestyle/intern/winged_edge/WEdge.h
+++ b/source/blender/freestyle/intern/winged_edge/WEdge.h
@@ -245,7 +245,6 @@ public:
virtual void increment();
#ifdef WITH_CXX_GUARDEDALLOC
- public:
MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:WVertex:incoming_edge_iterator")
#endif
};
@@ -330,7 +329,6 @@ public:
}
#ifdef WITH_CXX_GUARDEDALLOC
- public:
MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:WVertex:face_iterator")
#endif
};
@@ -1282,7 +1280,6 @@ protected:
WFace *face);
#ifdef WITH_CXX_GUARDEDALLOC
-public:
MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:WShape")
#endif
};
@@ -1327,7 +1324,6 @@ private:
vector<WShape *> _wshapes;
#ifdef WITH_CXX_GUARDEDALLOC
-public:
MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:WingedEdge")
#endif
};
diff --git a/source/blender/freestyle/intern/winged_edge/WFillGrid.h b/source/blender/freestyle/intern/winged_edge/WFillGrid.h
index ca52f75847c..819bb24ffc2 100644
--- a/source/blender/freestyle/intern/winged_edge/WFillGrid.h
+++ b/source/blender/freestyle/intern/winged_edge/WFillGrid.h
@@ -84,7 +84,6 @@ private:
unsigned _polygon_id;
#ifdef WITH_CXX_GUARDEDALLOC
-public:
MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:WFillGrid")
#endif
};
diff --git a/source/blender/freestyle/intern/winged_edge/WSFillGrid.h b/source/blender/freestyle/intern/winged_edge/WSFillGrid.h
index ee693de9ba1..5b33df906a6 100644
--- a/source/blender/freestyle/intern/winged_edge/WSFillGrid.h
+++ b/source/blender/freestyle/intern/winged_edge/WSFillGrid.h
@@ -77,8 +77,13 @@ private:
Grid *_grid;
WingedEdge *_winged_edge;
unsigned _polygon_id;
+
+#ifdef WITH_CXX_GUARDEDALLOC
+ MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:WSFillGrid")
+#endif
+
};
} /* namespace Freestyle */
-#endif // __FREESTYLE_WS_FILL_GRID_H__ \ No newline at end of file
+#endif // __FREESTYLE_WS_FILL_GRID_H__
diff --git a/source/blender/freestyle/intern/winged_edge/WXEdge.h b/source/blender/freestyle/intern/winged_edge/WXEdge.h
index f696e279ad0..364183bbc84 100644
--- a/source/blender/freestyle/intern/winged_edge/WXEdge.h
+++ b/source/blender/freestyle/intern/winged_edge/WXEdge.h
@@ -95,6 +95,11 @@ public:
{
return _curvatures;
}
+
+#ifdef WITH_CXX_GUARDEDALLOC
+ MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:WXVertex")
+#endif
+
};
@@ -197,6 +202,11 @@ public:
{
_order = i;
}
+
+#ifdef WITH_CXX_GUARDEDALLOC
+ MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:WXEdge")
+#endif
+
};
/**********************************
@@ -686,6 +696,11 @@ public:
(*wxf)->userdata = NULL;
}
}
+
+#ifdef WITH_CXX_GUARDEDALLOC
+ MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:WXFace")
+#endif
+
};
@@ -782,6 +797,11 @@ public:
}
}
/*! accessors */
+
+#ifdef WITH_CXX_GUARDEDALLOC
+ MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:WXShape")
+#endif
+
};
/*
diff --git a/source/blender/freestyle/intern/winged_edge/WXEdgeBuilder.h b/source/blender/freestyle/intern/winged_edge/WXEdgeBuilder.h
index 0c3e97f7806..5579989072a 100644
--- a/source/blender/freestyle/intern/winged_edge/WXEdgeBuilder.h
+++ b/source/blender/freestyle/intern/winged_edge/WXEdgeBuilder.h
@@ -44,6 +44,11 @@ public:
protected:
virtual void buildWVertices(WShape& shape, const real *vertices, unsigned vsize);
+
+#ifdef WITH_CXX_GUARDEDALLOC
+ MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:WXEdgeBuilder")
+#endif
+
};
} /* namespace Freestyle */
diff --git a/source/blender/freestyle/intern/winged_edge/WingedEdgeBuilder.h b/source/blender/freestyle/intern/winged_edge/WingedEdgeBuilder.h
index d8a045adfa3..d68acaf29c1 100644
--- a/source/blender/freestyle/intern/winged_edge/WingedEdgeBuilder.h
+++ b/source/blender/freestyle/intern/winged_edge/WingedEdgeBuilder.h
@@ -147,8 +147,13 @@ private:
WingedEdge *_winged_edge;
Matrix44r *_current_matrix;
vector<Matrix44r *> _matrices_stack;
+
+#ifdef WITH_CXX_GUARDEDALLOC
+ MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:WingedEdgeBuilder")
+#endif
+
};
} /* namespace Freestyle */
-#endif // __FREESTYLE_WINGED_EDGE_BUILDER_H__ \ No newline at end of file
+#endif // __FREESTYLE_WINGED_EDGE_BUILDER_H__
diff --git a/source/blender/gpu/GPU_buffers.h b/source/blender/gpu/GPU_buffers.h
index 9f6f80585ab..fca8dcc3392 100644
--- a/source/blender/gpu/GPU_buffers.h
+++ b/source/blender/gpu/GPU_buffers.h
@@ -122,6 +122,7 @@ typedef struct GPUAttrib {
} GPUAttrib;
void GPU_global_buffer_pool_free(void);
+void GPU_global_buffer_pool_free_unused(void);
GPUBuffer *GPU_buffer_alloc(int size);
void GPU_buffer_free(GPUBuffer *buffer);
diff --git a/source/blender/gpu/intern/gpu_buffers.c b/source/blender/gpu/intern/gpu_buffers.c
index 4d52afbde93..c54f937f4a9 100644
--- a/source/blender/gpu/intern/gpu_buffers.c
+++ b/source/blender/gpu/intern/gpu_buffers.c
@@ -172,6 +172,15 @@ static void gpu_buffer_pool_free(GPUBufferPool *pool)
MEM_freeN(pool);
}
+static void gpu_buffer_pool_free_unused(GPUBufferPool *pool)
+{
+ if (!pool)
+ return;
+
+ while (pool->totbuf)
+ gpu_buffer_pool_delete_last(pool);
+}
+
static GPUBufferPool *gpu_buffer_pool = NULL;
static GPUBufferPool *gpu_get_global_buffer_pool(void)
{
@@ -188,6 +197,11 @@ void GPU_global_buffer_pool_free(void)
gpu_buffer_pool = NULL;
}
+void GPU_global_buffer_pool_free_unused(void)
+{
+ gpu_buffer_pool_free_unused(gpu_buffer_pool);
+}
+
/* get a GPUBuffer of at least `size' bytes; uses one from the buffer
* pool if possible, otherwise creates a new one */
GPUBuffer *GPU_buffer_alloc(int size)
@@ -1266,7 +1280,7 @@ struct GPU_Buffers {
CCGKey gridkey;
CCGElem **grids;
const DMFlagMat *grid_flag_mats;
- const BLI_bitmap *grid_hidden;
+ BLI_bitmap * const *grid_hidden;
int *grid_indices;
int totgrid;
int has_hidden;
@@ -1686,7 +1700,7 @@ void GPU_update_grid_buffers(GPU_Buffers *buffers, CCGElem **grids,
}
/* Returns the number of visible quads in the nodes' grids. */
-static int gpu_count_grid_quads(BLI_bitmap *grid_hidden,
+static int gpu_count_grid_quads(BLI_bitmap **grid_hidden,
int *grid_indices, int totgrid,
int gridsize)
{
@@ -1697,7 +1711,7 @@ static int gpu_count_grid_quads(BLI_bitmap *grid_hidden,
* visibility */
for (i = 0, totquad = 0; i < totgrid; i++) {
- const BLI_bitmap gh = grid_hidden[grid_indices[i]];
+ const BLI_bitmap *gh = grid_hidden[grid_indices[i]];
if (gh) {
/* grid hidden are present, have to check each element */
@@ -1732,7 +1746,7 @@ static int gpu_count_grid_quads(BLI_bitmap *grid_hidden,
GL_WRITE_ONLY_ARB); \
if (quad_data) { \
for (i = 0; i < totgrid; ++i) { \
- BLI_bitmap gh = NULL; \
+ BLI_bitmap *gh = NULL; \
if (grid_hidden) \
gh = grid_hidden[(grid_indices)[i]]; \
\
@@ -1770,7 +1784,7 @@ static GLuint gpu_get_grid_buffer(int gridsize, GLenum *index_type, unsigned *to
static unsigned prev_totquad;
/* used in the FILL_QUAD_BUFFER macro */
- const BLI_bitmap *grid_hidden = NULL;
+ BLI_bitmap * const *grid_hidden = NULL;
int *grid_indices = NULL;
int totgrid = 1;
@@ -1815,7 +1829,7 @@ static GLuint gpu_get_grid_buffer(int gridsize, GLenum *index_type, unsigned *to
}
GPU_Buffers *GPU_build_grid_buffers(int *grid_indices, int totgrid,
- BLI_bitmap *grid_hidden, int gridsize)
+ BLI_bitmap **grid_hidden, int gridsize)
{
GPU_Buffers *buffers;
int totquad;
@@ -2200,7 +2214,7 @@ static void gpu_draw_buffers_legacy_grids(GPU_Buffers *buffers)
for (i = 0; i < buffers->totgrid; ++i) {
int g = buffers->grid_indices[i];
CCGElem *grid = buffers->grids[g];
- BLI_bitmap gh = buffers->grid_hidden[g];
+ BLI_bitmap *gh = buffers->grid_hidden[g];
/* TODO: could use strips with hiding as well */
diff --git a/source/blender/gpu/intern/gpu_draw.c b/source/blender/gpu/intern/gpu_draw.c
index 9dc98e59c42..e9f9d4a3379 100644
--- a/source/blender/gpu/intern/gpu_draw.c
+++ b/source/blender/gpu/intern/gpu_draw.c
@@ -1243,8 +1243,7 @@ void GPU_free_unused_buffers(void)
image_free_queue = NULL;
/* vbo buffers */
- /* it's probably not necessary to free all buffers every frame */
- /* GPU_buffer_pool_free_unused(0); */
+ GPU_global_buffer_pool_free_unused();
BLI_unlock_thread(LOCK_OPENGL);
}
diff --git a/source/blender/gpu/intern/gpu_extensions.c b/source/blender/gpu/intern/gpu_extensions.c
index ffd3bba5493..ea7b169a882 100644
--- a/source/blender/gpu/intern/gpu_extensions.c
+++ b/source/blender/gpu/intern/gpu_extensions.c
@@ -989,6 +989,8 @@ void GPU_framebuffer_blur(GPUFrameBuffer *fb, GPUTexture *tex, GPUFrameBuffer *b
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
+ glDisable(GL_DEPTH_TEST);
+
GPU_texture_bind(tex, 0);
/* Drawing quad */
diff --git a/source/blender/imbuf/intern/bmp.c b/source/blender/imbuf/intern/bmp.c
index 856124ab5cb..eb3cfc3ade3 100644
--- a/source/blender/imbuf/intern/bmp.c
+++ b/source/blender/imbuf/intern/bmp.c
@@ -100,11 +100,11 @@ static int checkbmp(unsigned char *mem)
memcpy(&bmi, mem, sizeof(bmi));
u = LITTLE_LONG(bmi.biSize);
- /* we only support uncompressed 24 or 32 bits images for now */
+ /* we only support uncompressed images for now. */
if (u >= sizeof(BMPINFOHEADER)) {
- if ((bmi.biCompression == 0) && (bmi.biClrUsed == 0)) {
+ if (bmi.biCompression == 0) {
u = LITTLE_SHORT(bmi.biBitCount);
- if (u >= 16) {
+ if (u >= 8) {
ret_val = 1;
}
}
@@ -125,7 +125,7 @@ struct ImBuf *imb_bmp_decode(unsigned char *mem, size_t size, int flags, char co
{
struct ImBuf *ibuf = NULL;
BMPINFOHEADER bmi;
- int x, y, depth, skip, i;
+ int x, y, depth, ibuf_depth, skip, i;
unsigned char *bmp, *rect;
unsigned short col;
double xppm, yppm;
@@ -151,6 +151,13 @@ struct ImBuf *imb_bmp_decode(unsigned char *mem, size_t size, int flags, char co
xppm = LITTLE_LONG(bmi.biXPelsPerMeter);
yppm = LITTLE_LONG(bmi.biYPelsPerMeter);
+ if (depth <= 8) {
+ ibuf_depth = 24;
+ }
+ else {
+ ibuf_depth = depth;
+ }
+
#if 0
printf("skip: %d, x: %d y: %d, depth: %d (%x)\n", skip, x, y,
depth, bmi.biBitCount);
@@ -159,14 +166,33 @@ struct ImBuf *imb_bmp_decode(unsigned char *mem, size_t size, int flags, char co
#endif
if (flags & IB_test) {
- ibuf = IMB_allocImBuf(x, y, depth, 0);
+ ibuf = IMB_allocImBuf(x, y, ibuf_depth, 0);
}
else {
- ibuf = IMB_allocImBuf(x, y, depth, IB_rect);
+ ibuf = IMB_allocImBuf(x, y, ibuf_depth, IB_rect);
bmp = mem + skip;
rect = (unsigned char *) ibuf->rect;
- if (depth == 16) {
+ if (depth == 8) {
+ const int x_pad = (4 - (x % 4)) % 4;
+ const char (*palette)[4] = (void *)bmp;
+ bmp += bmi.biClrUsed * 4;
+ for (i = y; i > 0; i--) {
+ int j;
+ for (j = x; j > 0; j--) {
+ const char *pcol = palette[bmp[0]];
+ rect[0] = pcol[0];
+ rect[1] = pcol[1];
+ rect[2] = pcol[2];
+
+ rect[3] = 255;
+ rect += 4; bmp += 1;
+ }
+ /* rows are padded to multiples of 4 */
+ bmp += x_pad;
+ }
+ }
+ else if (depth == 16) {
for (i = x * y; i > 0; i--) {
col = bmp[0] + (bmp[1] << 8);
rect[0] = ((col >> 10) & 0x1f) << 3;
@@ -179,6 +205,7 @@ struct ImBuf *imb_bmp_decode(unsigned char *mem, size_t size, int flags, char co
}
else if (depth == 24) {
+ const int x_pad = x % 4;
for (i = y; i > 0; i--) {
int j;
for (j = x; j > 0; j--) {
@@ -190,7 +217,7 @@ struct ImBuf *imb_bmp_decode(unsigned char *mem, size_t size, int flags, char co
rect += 4; bmp += 3;
}
/* for 24-bit images, rows are padded to multiples of 4 */
- bmp += x % 4;
+ bmp += x_pad;
}
}
else if (depth == 32) {
diff --git a/source/blender/imbuf/intern/colormanagement.c b/source/blender/imbuf/intern/colormanagement.c
index 238e68b141c..0167eaccef0 100644
--- a/source/blender/imbuf/intern/colormanagement.c
+++ b/source/blender/imbuf/intern/colormanagement.c
@@ -2787,9 +2787,9 @@ static void update_glsl_display_processor(const ColorManagedViewSettings *view_s
check_glsl_display_processor_changed(view_settings, display_settings, from_colorspace))
{
/* Store settings of processor for further comparison. */
- strcpy(global_glsl_state.view, view_settings->view_transform);
- strcpy(global_glsl_state.display, display_settings->display_device);
- strcpy(global_glsl_state.input, from_colorspace);
+ BLI_strncpy(global_glsl_state.view, view_settings->view_transform, MAX_COLORSPACE_NAME);
+ BLI_strncpy(global_glsl_state.display, display_settings->display_device, MAX_COLORSPACE_NAME);
+ BLI_strncpy(global_glsl_state.input, from_colorspace, MAX_COLORSPACE_NAME);
global_glsl_state.exposure = view_settings->exposure;
global_glsl_state.gamma = view_settings->gamma;
diff --git a/source/blender/imbuf/intern/indexer.c b/source/blender/imbuf/intern/indexer.c
index c66f2d62db2..7acfe8a9dd1 100644
--- a/source/blender/imbuf/intern/indexer.c
+++ b/source/blender/imbuf/intern/indexer.c
@@ -366,8 +366,8 @@ static void get_index_dir(struct anim *anim, char *index_dir, size_t index_dir_l
if (!anim->index_dir[0]) {
char fname[FILE_MAXFILE];
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);
+ BLI_path_append(index_dir, index_dir_len, "BL_proxy");
+ BLI_path_append(index_dir, index_dir_len, fname);
}
else {
BLI_strncpy(index_dir, anim->index_dir, index_dir_len);
diff --git a/source/blender/imbuf/intern/thumbs.c b/source/blender/imbuf/intern/thumbs.c
index 59b78109aaf..18268043a04 100644
--- a/source/blender/imbuf/intern/thumbs.c
+++ b/source/blender/imbuf/intern/thumbs.c
@@ -67,35 +67,40 @@
# include <unistd.h>
#endif
-#define URI_MAX FILE_MAX * 3 + 8
+#define URI_MAX (FILE_MAX * 3 + 8)
static int get_thumb_dir(char *dir, ThumbSize size)
{
+ char *s = dir;
+ const char *subdir;
#ifdef WIN32
wchar_t dir_16[MAX_PATH];
/* yes, applications shouldn't store data there, but so does GIMP :)*/
SHGetSpecialFolderPathW(0, dir_16, CSIDL_PROFILE, 0);
conv_utf_16_to_8(dir_16, dir, FILE_MAX);
-
-
+ s += strlen(dir);
#else
const char *home = getenv("HOME");
if (!home) return 0;
- BLI_strncpy(dir, home, FILE_MAX);
+ s += BLI_strncpy_rlen(s, home, FILE_MAX);
#endif
switch (size) {
case THB_NORMAL:
- strcat(dir, "/.thumbnails/normal/");
+ subdir = "/.thumbnails/normal/";
break;
case THB_LARGE:
- strcat(dir, "/.thumbnails/large/");
+ subdir = "/.thumbnails/large/";
break;
case THB_FAIL:
- strcat(dir, "/.thumbnails/fail/blender/");
+ subdir = "/.thumbnails/fail/blender/";
break;
default:
return 0; /* unknown size */
}
+
+ s += BLI_strncpy_rlen(s, subdir, FILE_MAX - (s - dir));
+ (void)s;
+
return 1;
}
@@ -195,20 +200,20 @@ static int uri_from_filename(const char *path, char *uri)
strcat(orig_uri, vol);
dirstart += 2;
}
-#else
- BLI_strncpy(orig_uri, "file://", FILE_MAX);
-#endif
strcat(orig_uri, dirstart);
BLI_char_switch(orig_uri, '\\', '/');
+#else
+ BLI_snprintf(orig_uri, URI_MAX, "file://%s", dirstart);
+#endif
#ifdef WITH_ICONV
{
- char uri_utf8[FILE_MAX * 3 + 8];
- escape_uri_string(orig_uri, uri_utf8, FILE_MAX * 3 + 8, UNSAFE_PATH);
+ char uri_utf8[URI_MAX];
+ escape_uri_string(orig_uri, uri_utf8, URI_MAX, UNSAFE_PATH);
BLI_string_to_utf8(uri_utf8, uri, NULL);
}
#else
- escape_uri_string(orig_uri, uri, FILE_MAX * 3 + 8, UNSAFE_PATH);
+ escape_uri_string(orig_uri, uri, URI_MAX, UNSAFE_PATH);
#endif
return 1;
}
@@ -396,7 +401,7 @@ ImBuf *IMB_thumb_create(const char *path, ThumbSize size, ThumbSource source, Im
ImBuf *IMB_thumb_read(const char *path, ThumbSize size)
{
char thumb[FILE_MAX];
- char uri[FILE_MAX * 3 + 8];
+ char uri[URI_MAX];
ImBuf *img = NULL;
if (!uri_from_filename(path, uri)) {
@@ -413,7 +418,7 @@ ImBuf *IMB_thumb_read(const char *path, ThumbSize size)
void IMB_thumb_delete(const char *path, ThumbSize size)
{
char thumb[FILE_MAX];
- char uri[FILE_MAX * 3 + 8];
+ char uri[URI_MAX];
if (!uri_from_filename(path, uri)) {
return;
@@ -433,7 +438,7 @@ void IMB_thumb_delete(const char *path, ThumbSize size)
ImBuf *IMB_thumb_manage(const char *path, ThumbSize size, ThumbSource source)
{
char thumb[FILE_MAX];
- char uri[FILE_MAX * 3 + 8];
+ char uri[URI_MAX];
struct stat st;
ImBuf *img = NULL;
diff --git a/source/blender/imbuf/intern/util.c b/source/blender/imbuf/intern/util.c
index 4ec5879cfac..a4b0e61d544 100644
--- a/source/blender/imbuf/intern/util.c
+++ b/source/blender/imbuf/intern/util.c
@@ -253,11 +253,11 @@ static void ffmpeg_log_callback(void *ptr, int level, const char *format, va_lis
{
if (ELEM(level, AV_LOG_FATAL, AV_LOG_ERROR)) {
size_t n;
- va_list arg2;
+ va_list args_cpy;
- va_copy(arg2, arg);
-
- n = BLI_vsnprintf(ffmpeg_last_error, sizeof(ffmpeg_last_error), format, arg2);
+ va_copy(args_cpy, arg);
+ n = BLI_vsnprintf(ffmpeg_last_error, sizeof(ffmpeg_last_error), format, args_cpy);
+ va_end(args_cpy);
/* strip trailing \n */
ffmpeg_last_error[n - 1] = '\0';
diff --git a/source/blender/makesdna/DNA_dynamicpaint_types.h b/source/blender/makesdna/DNA_dynamicpaint_types.h
index 1f2a589dc27..d2b95c959b3 100644
--- a/source/blender/makesdna/DNA_dynamicpaint_types.h
+++ b/source/blender/makesdna/DNA_dynamicpaint_types.h
@@ -125,7 +125,8 @@ typedef struct DynamicPaintSurface {
float influence_scale, radius_scale;
/* wave settings */
- float wave_damping, wave_speed, wave_timescale, wave_spring;
+ float wave_damping, wave_speed, wave_timescale, wave_spring, wave_smoothness;
+ int pad2;
char uvlayer_name[64]; /* MAX_CUSTOMDATA_LAYER_NAME */
char image_output_path[1024]; /* 1024 = FILE_MAX */
diff --git a/source/blender/makesdna/DNA_image_types.h b/source/blender/makesdna/DNA_image_types.h
index 456196771a6..dae520f458d 100644
--- a/source/blender/makesdna/DNA_image_types.h
+++ b/source/blender/makesdna/DNA_image_types.h
@@ -106,7 +106,7 @@ typedef struct Image {
/* for generated images */
int gen_x, gen_y;
char gen_type, gen_flag;
- char gen_pad[2];
+ short gen_depth;
/* display aspect - for UV editing images resized for faster openGL display */
float aspx, aspy;
diff --git a/source/blender/makesdna/DNA_mesh_types.h b/source/blender/makesdna/DNA_mesh_types.h
index 947bf593310..e37d1368892 100644
--- a/source/blender/makesdna/DNA_mesh_types.h
+++ b/source/blender/makesdna/DNA_mesh_types.h
@@ -33,7 +33,6 @@
#define __DNA_MESH_TYPES_H__
#include "DNA_defs.h"
-#include "DNA_listBase.h"
#include "DNA_ID.h"
#include "DNA_customdata_types.h"
diff --git a/source/blender/makesdna/DNA_modifier_types.h b/source/blender/makesdna/DNA_modifier_types.h
index a76f57a3e7c..5e65369b32d 100644
--- a/source/blender/makesdna/DNA_modifier_types.h
+++ b/source/blender/makesdna/DNA_modifier_types.h
@@ -282,16 +282,23 @@ typedef struct BevelModifierData {
short val_flags; /* flags used to interpret the bevel value */
short lim_flags; /* flags to tell the tool how to limit the bevel */
short e_flags; /* flags to direct how edge weights are applied to verts */
- float bevel_angle; /* if the BME_BEVEL_ANGLE is set, this will be how "sharp" an edge must be before it gets beveled */
- char defgrp_name[64]; /* if the BME_BEVEL_VWEIGHT option is set, this will be the name of the vert group, MAX_VGROUP_NAME */
+ float bevel_angle; /* if the MOD_BEVEL_ANGLE is set, this will be how "sharp" an edge must be before it gets beveled */
+ char defgrp_name[64]; /* if the MOD_BEVEL_VWEIGHT option is set, this will be the name of the vert group, MAX_VGROUP_NAME */
} BevelModifierData;
-typedef struct BMeshModifierData {
- ModifierData modifier;
-
- float pad;
- int type;
-} BMeshModifierData;
+#define MOD_BEVEL_VERT (1 << 1)
+// #define MOD_BEVEL_RADIUS (1 << 2)
+#define MOD_BEVEL_ANGLE (1 << 3)
+#define MOD_BEVEL_WEIGHT (1 << 4)
+#define MOD_BEVEL_VGROUP (1 << 5)
+#define MOD_BEVEL_EMIN (1 << 7)
+#define MOD_BEVEL_EMAX (1 << 8)
+// #define MOD_BEVEL_RUNNING (1 << 9)
+// #define MOD_BEVEL_RES (1 << 10)
+// #define MOD_BEVEL_EVEN (1 << 11) /* this is a new setting not related to old (trunk bmesh bevel code) but adding
+// * here because they are mixed - campbell */
+// #define MOD_BEVEL_DIST (1 << 12) /* same as above */
+#define MOD_BEVEL_OVERLAP_OK (1 << 13)
/* Smoke modifier flags */
@@ -714,8 +721,7 @@ typedef struct SimpleDeformModifierData {
char mode; /* deform function */
char axis; /* lock axis (for taper and strech) */
- char originOpts; /* originOptions */
- char pad;
+ char pad[2];
} SimpleDeformModifierData;
@@ -727,12 +733,6 @@ typedef struct SimpleDeformModifierData {
#define MOD_SIMPLEDEFORM_LOCK_AXIS_X (1<<0)
#define MOD_SIMPLEDEFORM_LOCK_AXIS_Y (1<<1)
-/* indicates whether simple deform should use the local
- * coordinates or global coordinates of origin */
-/* XXX, this should have never been an option, all other modifiers work relatively
- * (so moving both objects makes no change!) - Campbell */
-#define MOD_SIMPLEDEFORM_ORIGIN_LOCAL (1<<0)
-
#define MOD_UVPROJECT_MAX 10
typedef struct ShapeKeyModifierData {
diff --git a/source/blender/makesdna/DNA_node_types.h b/source/blender/makesdna/DNA_node_types.h
index 8a9a95a9935..9ff4392242e 100644
--- a/source/blender/makesdna/DNA_node_types.h
+++ b/source/blender/makesdna/DNA_node_types.h
@@ -788,6 +788,12 @@ typedef struct NodeShaderAttribute {
char name[64];
} NodeShaderAttribute;
+typedef struct NodeShaderVectTransform {
+ int type;
+ int convert_from, convert_to;
+ int pad;
+} NodeShaderVectTransform;
+
/* TEX_output */
typedef struct TexNodeOutput {
char name[64];
@@ -869,6 +875,15 @@ typedef struct NodeShaderNormalMap {
#define SHD_GLOSSY_SHARP 1
#define SHD_GLOSSY_GGX 2
+/* vector transform */
+#define SHD_VECT_TRANSFORM_TYPE_VECTOR 0
+#define SHD_VECT_TRANSFORM_TYPE_POINT 1
+#define SHD_VECT_TRANSFORM_TYPE_NORMAL 2
+
+#define SHD_VECT_TRANSFORM_SPACE_WORLD 0
+#define SHD_VECT_TRANSFORM_SPACE_OBJECT 1
+#define SHD_VECT_TRANSFORM_SPACE_CAMERA 2
+
/* toon modes */
#define SHD_TOON_DIFFUSE 0
#define SHD_TOON_GLOSSY 1
diff --git a/source/blender/makesdna/DNA_outliner_types.h b/source/blender/makesdna/DNA_outliner_types.h
index 17124a724fe..53061b55e2d 100644
--- a/source/blender/makesdna/DNA_outliner_types.h
+++ b/source/blender/makesdna/DNA_outliner_types.h
@@ -32,7 +32,7 @@
#ifndef __DNA_OUTLINER_TYPES_H__
#define __DNA_OUTLINER_TYPES_H__
-#include "DNA_listBase.h"
+#include "DNA_defs.h"
struct ID;
@@ -41,9 +41,12 @@ typedef struct TreeStoreElem {
struct ID *id;
} TreeStoreElem;
+/* used only to store data in in blend files */
typedef struct TreeStore {
- int totelem, usedelem;
- TreeStoreElem *data;
+ int totelem DNA_DEPRECATED; /* was previously used for memory preallocation */
+ int usedelem; /* number of elements in data array */
+ TreeStoreElem *data; /* elements to be packed from mempool in writefile.c
+ * or extracted to mempool in readfile.c */
} TreeStore;
/* TreeStoreElem->flag */
diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h
index 5e877ed697b..ceb745cf90a 100644
--- a/source/blender/makesdna/DNA_scene_types.h
+++ b/source/blender/makesdna/DNA_scene_types.h
@@ -209,34 +209,37 @@ typedef struct SceneRenderLayer {
#define SCE_LAY_NEG_ZMASK 0x80000
/* srl->passflag */
-#define SCE_PASS_COMBINED (1<<0)
-#define SCE_PASS_Z (1<<1)
-#define SCE_PASS_RGBA (1<<2)
-#define SCE_PASS_DIFFUSE (1<<3)
-#define SCE_PASS_SPEC (1<<4)
-#define SCE_PASS_SHADOW (1<<5)
-#define SCE_PASS_AO (1<<6)
-#define SCE_PASS_REFLECT (1<<7)
-#define SCE_PASS_NORMAL (1<<8)
-#define SCE_PASS_VECTOR (1<<9)
-#define SCE_PASS_REFRACT (1<<10)
-#define SCE_PASS_INDEXOB (1<<11)
-#define SCE_PASS_UV (1<<12)
-#define SCE_PASS_INDIRECT (1<<13)
-#define SCE_PASS_MIST (1<<14)
-#define SCE_PASS_RAYHITS (1<<15)
-#define SCE_PASS_EMIT (1<<16)
-#define SCE_PASS_ENVIRONMENT (1<<17)
-#define SCE_PASS_INDEXMA (1<<18)
-#define SCE_PASS_DIFFUSE_DIRECT (1<<19)
-#define SCE_PASS_DIFFUSE_INDIRECT (1<<20)
-#define SCE_PASS_DIFFUSE_COLOR (1<<21)
-#define SCE_PASS_GLOSSY_DIRECT (1<<22)
-#define SCE_PASS_GLOSSY_INDIRECT (1<<23)
-#define SCE_PASS_GLOSSY_COLOR (1<<24)
-#define SCE_PASS_TRANSM_DIRECT (1<<25)
-#define SCE_PASS_TRANSM_INDIRECT (1<<26)
-#define SCE_PASS_TRANSM_COLOR (1<<27)
+#define SCE_PASS_COMBINED (1<<0)
+#define SCE_PASS_Z (1<<1)
+#define SCE_PASS_RGBA (1<<2)
+#define SCE_PASS_DIFFUSE (1<<3)
+#define SCE_PASS_SPEC (1<<4)
+#define SCE_PASS_SHADOW (1<<5)
+#define SCE_PASS_AO (1<<6)
+#define SCE_PASS_REFLECT (1<<7)
+#define SCE_PASS_NORMAL (1<<8)
+#define SCE_PASS_VECTOR (1<<9)
+#define SCE_PASS_REFRACT (1<<10)
+#define SCE_PASS_INDEXOB (1<<11)
+#define SCE_PASS_UV (1<<12)
+#define SCE_PASS_INDIRECT (1<<13)
+#define SCE_PASS_MIST (1<<14)
+#define SCE_PASS_RAYHITS (1<<15)
+#define SCE_PASS_EMIT (1<<16)
+#define SCE_PASS_ENVIRONMENT (1<<17)
+#define SCE_PASS_INDEXMA (1<<18)
+#define SCE_PASS_DIFFUSE_DIRECT (1<<19)
+#define SCE_PASS_DIFFUSE_INDIRECT (1<<20)
+#define SCE_PASS_DIFFUSE_COLOR (1<<21)
+#define SCE_PASS_GLOSSY_DIRECT (1<<22)
+#define SCE_PASS_GLOSSY_INDIRECT (1<<23)
+#define SCE_PASS_GLOSSY_COLOR (1<<24)
+#define SCE_PASS_TRANSM_DIRECT (1<<25)
+#define SCE_PASS_TRANSM_INDIRECT (1<<26)
+#define SCE_PASS_TRANSM_COLOR (1<<27)
+#define SCE_PASS_SUBSURFACE_DIRECT (1<<28)
+#define SCE_PASS_SUBSURFACE_INDIRECT (1<<29)
+#define SCE_PASS_SUBSURFACE_COLOR (1<<30)
/* note, srl->passflag is treestore element 'nr' in outliner, short still... */
@@ -652,7 +655,8 @@ typedef struct GameData {
short mode, matmode;
short occlusionRes; /* resolution of occlusion Z buffer in pixel */
short physicsEngine;
- short exitkey, pad;
+ short exitkey;
+ short vsync; /* Controls vsync: off, on, or adaptive (if supported) */
short ticrate, maxlogicstep, physubstep, maxphystep;
short obstacleSimulation;
short raster_storage;
@@ -688,6 +692,11 @@ typedef struct GameData {
#define RAS_STORE_VA 2
#define RAS_STORE_VBO 3
+/* vsync */
+#define VSYNC_OFF 0
+#define VSYNC_ON 1
+#define VSYNC_ADAPTIVE 2
+
/* GameData.flag */
#define GAME_RESTRICT_ANIM_UPDATES (1 << 0)
#define GAME_ENABLE_ALL_FRAMES (1 << 1)
diff --git a/source/blender/makesdna/DNA_sound_types.h b/source/blender/makesdna/DNA_sound_types.h
index 6dc45e4a6de..040942d6cea 100644
--- a/source/blender/makesdna/DNA_sound_types.h
+++ b/source/blender/makesdna/DNA_sound_types.h
@@ -33,7 +33,6 @@
#ifndef __DNA_SOUND_TYPES_H__
#define __DNA_SOUND_TYPES_H__
-#include "DNA_listBase.h"
#include "DNA_ID.h"
/* stupid... could easily be solved */
diff --git a/source/blender/makesdna/DNA_space_types.h b/source/blender/makesdna/DNA_space_types.h
index 2d87cb1d890..c562a1fefae 100644
--- a/source/blender/makesdna/DNA_space_types.h
+++ b/source/blender/makesdna/DNA_space_types.h
@@ -72,6 +72,8 @@ struct wmTimer;
struct MovieClip;
struct MovieClipScopes;
struct Mask;
+struct GHash;
+struct BLI_mempool;
/* SpaceLink (Base) ==================================== */
@@ -244,13 +246,14 @@ typedef struct SpaceOops {
View2D v2d DNA_DEPRECATED; /* deprecated, copied to region */
ListBase tree;
- struct TreeStore *treestore;
+ struct BLI_mempool *treestore;
/* search stuff */
char search_string[32];
struct TreeStoreElem search_tse;
short flag, outlinevis, storeflag, search_flags;
+ struct GHash *treehash;
} SpaceOops;
diff --git a/source/blender/makesrna/SConscript b/source/blender/makesrna/SConscript
index 3b322491559..2d0c4260c97 100644
--- a/source/blender/makesrna/SConscript
+++ b/source/blender/makesrna/SConscript
@@ -130,10 +130,6 @@ if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'linuxcross', 'win64-vc', '
if env['WITH_BF_INTERNATIONAL']:
defs.append('WITH_INTERNATIONAL')
-if env['WITH_BF_FREESTYLE']:
- incs += ' ../freestyle'
- defs.append('WITH_FREESTYLE')
-
rnalib = env.BlenderLib ( 'bf_rna', objs, Split(incs), defines=defs, libtype=['core','player'], priority = [165,20] )
Return ('rnalib')
diff --git a/source/blender/makesrna/intern/CMakeLists.txt b/source/blender/makesrna/intern/CMakeLists.txt
index af14e959c11..592c518e9c0 100644
--- a/source/blender/makesrna/intern/CMakeLists.txt
+++ b/source/blender/makesrna/intern/CMakeLists.txt
@@ -280,11 +280,6 @@ blender_include_dirs(
../../../../intern/smoke/extern
)
-if(WITH_FREESTYLE)
- # TO BE REMOVED when the trunk merger is done
- add_definitions(-DWITH_FREESTYLE)
-endif()
-
blender_include_dirs_sys(
${GLEW_INCLUDE_PATH}
)
diff --git a/source/blender/makesrna/intern/SConscript b/source/blender/makesrna/intern/SConscript
index 49528db0022..10b6a8c8d10 100644
--- a/source/blender/makesrna/intern/SConscript
+++ b/source/blender/makesrna/intern/SConscript
@@ -38,8 +38,6 @@ root_build_dir=normpath(env['BF_BUILDDIR'])
source_files = env.Glob('*.c')
source_files.remove('rna_access.c')
-if not env['WITH_BF_FREESTYLE']:
- source_files.remove('rna_linestyle.c')
generated_files = source_files[:]
generated_files.remove('rna_define.c')
@@ -149,10 +147,6 @@ if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'linuxcross', 'win64-vc', '
if env['WITH_BF_INTERNATIONAL']:
defs.append('WITH_INTERNATIONAL')
-if env['WITH_BF_FREESTYLE']:
- # TO BE REMOVED when the trunk merger is done
- defs.append('WITH_FREESTYLE')
-
if not env['BF_DEBUG']:
defs.append('NDEBUG')
diff --git a/source/blender/makesrna/intern/makesrna.c b/source/blender/makesrna/intern/makesrna.c
index faf348302e4..c158facca7c 100644
--- a/source/blender/makesrna/intern/makesrna.c
+++ b/source/blender/makesrna/intern/makesrna.c
@@ -177,8 +177,8 @@ static int replace_if_different(char *tmpfile, const char *dep_files[])
if (len_new != len_org) {
- fclose(fp_new);
- fclose(fp_org);
+ fclose(fp_new); fp_new = NULL;
+ fclose(fp_org); fp_org = NULL;
REN_IF_DIFF;
}
@@ -191,8 +191,8 @@ static int replace_if_different(char *tmpfile, const char *dep_files[])
if (fread(arr_org, sizeof(char), len_org, fp_org) != len_org)
fprintf(stderr, "%s:%d, error reading file %s for comparison.\n", __FILE__, __LINE__, orgfile);
- fclose(fp_new);
- fclose(fp_org);
+ fclose(fp_new); fp_new = NULL;
+ fclose(fp_org); fp_org = NULL;
cmp = memcmp(arr_new, arr_org, len_new);
@@ -319,15 +319,15 @@ static void rna_print_c_string(FILE *f, const char *str)
static void rna_print_data_get(FILE *f, PropertyDefRNA *dp)
{
if (dp->dnastructfromname && dp->dnastructfromprop)
- fprintf(f, " %s *data= (%s*)(((%s*)ptr->data)->%s);\n", dp->dnastructname, dp->dnastructname,
+ fprintf(f, " %s *data = (%s *)(((%s *)ptr->data)->%s);\n", dp->dnastructname, dp->dnastructname,
dp->dnastructfromname, dp->dnastructfromprop);
else
- fprintf(f, " %s *data= (%s*)(ptr->data);\n", dp->dnastructname, dp->dnastructname);
+ fprintf(f, " %s *data = (%s *)(ptr->data);\n", dp->dnastructname, dp->dnastructname);
}
static void rna_print_id_get(FILE *f, PropertyDefRNA *UNUSED(dp))
{
- fprintf(f, " ID *id= ptr->id.data;\n");
+ fprintf(f, " ID *id = ptr->id.data;\n");
}
static void rna_construct_function_name(char *buffer, int size, const char *structname, const char *propname, const char *type)
@@ -646,14 +646,15 @@ static char *rna_def_property_get_func(FILE *f, StructRNA *srna, PropertyRNA *pr
if (prop->flag & PROP_DYNAMIC) {
char *lenfunc = rna_alloc_function_name(srna->identifier, rna_safe_id(prop->identifier),
"get_length");
- fprintf(f, " int i, arraylen[RNA_MAX_ARRAY_DIMENSION];\n");
- fprintf(f, " int len= %s(ptr, arraylen);\n\n", lenfunc);
- fprintf(f, " for (i=0; i < len; i++) {\n");
+ fprintf(f, " unsigned int arraylen[RNA_MAX_ARRAY_DIMENSION];\n");
+ fprintf(f, " unsigned int i;\n");
+ fprintf(f, " unsigned int len = %s(ptr, arraylen);\n\n", lenfunc);
+ fprintf(f, " for (i = 0; i < len; i++) {\n");
MEM_freeN(lenfunc);
}
else {
- fprintf(f, " int i;\n\n");
- fprintf(f, " for (i=0; i < %u; i++) {\n", prop->totarraylength);
+ fprintf(f, " unsigned int i;\n\n");
+ fprintf(f, " for (i = 0; i < %u; i++) {\n", prop->totarraylength);
}
if (dp->dnaarraylength == 1) {
@@ -674,11 +675,11 @@ static char *rna_def_property_get_func(FILE *f, StructRNA *srna, PropertyRNA *pr
fprintf(f, ") != 0);\n");
}
else if (rna_color_quantize(prop, dp)) {
- fprintf(f, " values[i] = (%s)(data->%s[i]*(1.0f / 255.0f));\n",
+ fprintf(f, " values[i] = (%s)(data->%s[i] * (1.0f / 255.0f));\n",
rna_type_type(prop), dp->dnaname);
}
else if (dp->dnatype) {
- fprintf(f, " values[i] = (%s)%s(((%s*)data->%s)[i]);\n",
+ fprintf(f, " values[i] = (%s)%s(((%s *)data->%s)[i]);\n",
rna_type_type(prop), (dp->booleannegative) ? "!" : "", dp->dnatype, dp->dnaname);
}
else {
@@ -897,15 +898,15 @@ static char *rna_def_property_set_func(FILE *f, StructRNA *srna, PropertyRNA *pr
char *lenfunc = rna_alloc_function_name(srna->identifier, rna_safe_id(prop->identifier),
"set_length");
fprintf(f, " int i, arraylen[RNA_MAX_ARRAY_DIMENSION];\n");
- fprintf(f, " int len= %s(ptr, arraylen);\n\n", lenfunc);
+ fprintf(f, " int len = %s(ptr, arraylen);\n\n", lenfunc);
rna_clamp_value_range(f, prop);
- fprintf(f, " for (i=0; i < len; i++) {\n");
+ fprintf(f, " for (i = 0; i < len; i++) {\n");
MEM_freeN(lenfunc);
}
else {
fprintf(f, " int i;\n\n");
rna_clamp_value_range(f, prop);
- fprintf(f, " for (i=0; i < %u; i++) {\n", prop->totarraylength);
+ fprintf(f, " for (i = 0; i < %u; i++) {\n", prop->totarraylength);
}
if (dp->dnaarraylength == 1) {
@@ -934,7 +935,7 @@ static char *rna_def_property_set_func(FILE *f, StructRNA *srna, PropertyRNA *pr
}
else {
if (dp->dnatype)
- fprintf(f, " ((%s*)data->%s)[i] = %s", dp->dnatype, dp->dnaname,
+ fprintf(f, " ((%s *)data->%s)[i] = %s", dp->dnatype, dp->dnaname,
(dp->booleannegative) ? "!" : "");
else
fprintf(f, " (data->%s)[i] = %s", dp->dnaname, (dp->booleannegative) ? "!" : "");
@@ -1072,8 +1073,8 @@ static char *rna_def_property_begin_func(FILE *f, StructRNA *srna, PropertyRNA *
rna_print_data_get(f, dp);
fprintf(f, "\n memset(iter, 0, sizeof(*iter));\n");
- fprintf(f, " iter->parent= *ptr;\n");
- fprintf(f, " iter->prop= (PropertyRNA *)&rna_%s_%s;\n", srna->identifier, prop->identifier);
+ fprintf(f, " iter->parent = *ptr;\n");
+ fprintf(f, " iter->prop = (PropertyRNA *)&rna_%s_%s;\n", srna->identifier, prop->identifier);
if (dp->dnalengthname || dp->dnalengthfixed) {
if (manualfunc) {
@@ -1100,7 +1101,7 @@ static char *rna_def_property_begin_func(FILE *f, StructRNA *srna, PropertyRNA *
getfunc = rna_alloc_function_name(srna->identifier, rna_safe_id(prop->identifier), "get");
fprintf(f, "\n if (iter->valid)\n");
- fprintf(f, " iter->ptr= %s(iter);\n", getfunc);
+ fprintf(f, " iter->ptr = %s(iter);\n", getfunc);
fprintf(f, "}\n\n");
@@ -1139,14 +1140,14 @@ static char *rna_def_property_lookup_int_func(FILE *f, StructRNA *srna, Property
return func;
}
- fprintf(f, " int found= 0;\n");
+ fprintf(f, " int found = 0;\n");
fprintf(f, " CollectionPropertyIterator iter;\n\n");
fprintf(f, " %s_%s_begin(&iter, ptr);\n\n", srna->identifier, rna_safe_id(prop->identifier));
fprintf(f, " if (iter.valid) {\n");
if (strcmp(nextfunc, "rna_iterator_array_next") == 0) {
- fprintf(f, " ArrayIterator *internal= iter.internal;\n");
+ fprintf(f, " ArrayIterator *internal = iter.internal;\n");
fprintf(f, " if (index < 0 || index >= internal->length) {\n");
fprintf(f, "#ifdef __GNUC__\n");
fprintf(f, " printf(\"Array iterator out of range: %%s (index %%d)\\n\", __func__, index);\n");
@@ -1158,25 +1159,25 @@ static char *rna_def_property_lookup_int_func(FILE *f, StructRNA *srna, Property
fprintf(f, " while (index-- > 0 && iter.valid) {\n");
fprintf(f, " rna_iterator_array_next(&iter);\n");
fprintf(f, " }\n");
- fprintf(f, " found= (index == -1 && iter.valid);\n");
+ fprintf(f, " found = (index == -1 && iter.valid);\n");
fprintf(f, " }\n");
fprintf(f, " else {\n");
- fprintf(f, " internal->ptr += internal->itemsize*index;\n");
- fprintf(f, " found= 1;\n");
+ fprintf(f, " internal->ptr += internal->itemsize * index;\n");
+ fprintf(f, " found = 1;\n");
fprintf(f, " }\n");
}
else if (strcmp(nextfunc, "rna_iterator_listbase_next") == 0) {
- fprintf(f, " ListBaseIterator *internal= iter.internal;\n");
+ fprintf(f, " ListBaseIterator *internal = iter.internal;\n");
fprintf(f, " if (internal->skip) {\n");
fprintf(f, " while (index-- > 0 && iter.valid) {\n");
fprintf(f, " rna_iterator_listbase_next(&iter);\n");
fprintf(f, " }\n");
- fprintf(f, " found= (index == -1 && iter.valid);\n");
+ fprintf(f, " found = (index == -1 && iter.valid);\n");
fprintf(f, " }\n");
fprintf(f, " else {\n");
fprintf(f, " while (index-- > 0 && internal->link)\n");
- fprintf(f, " internal->link= internal->link->next;\n");
- fprintf(f, " found= (index == -1 && internal->link);\n");
+ fprintf(f, " internal->link = internal->link->next;\n");
+ fprintf(f, " found = (index == -1 && internal->link);\n");
fprintf(f, " }\n");
}
@@ -1318,7 +1319,7 @@ static char *rna_def_property_next_func(FILE *f, StructRNA *srna, PropertyRNA *p
getfunc = rna_alloc_function_name(srna->identifier, rna_safe_id(prop->identifier), "get");
fprintf(f, "\n if (iter->valid)\n");
- fprintf(f, " iter->ptr= %s(iter);\n", getfunc);
+ fprintf(f, " iter->ptr = %s(iter);\n", getfunc);
fprintf(f, "}\n\n");
@@ -2202,7 +2203,7 @@ static void rna_def_function_funcs(FILE *f, StructDefRNA *dsrna, FunctionDefRNA
else if ((type == PROP_POINTER) && (flag & PROP_RNAPTR) && !(flag & PROP_THICK_WRAP))
ptrstr = "*";
/* PROP_THICK_WRAP strings are pre-allocated on the ParameterList stack,
- * but type name for string props is already char*, so leave empty */
+ * but type name for string props is already (char *), so leave empty */
else if (type == PROP_STRING && (flag & PROP_THICK_WRAP))
ptrstr = "";
else
@@ -2225,19 +2226,19 @@ static void rna_def_function_funcs(FILE *f, StructDefRNA *dsrna, FunctionDefRNA
/* assign self */
if (func->flag & FUNC_USE_SELF_ID) {
- fprintf(f, "\t_selfid= (struct ID*)_ptr->id.data;\n");
+ fprintf(f, "\t_selfid = (struct ID *)_ptr->id.data;\n");
}
if ((func->flag & FUNC_NO_SELF) == 0) {
- if (dsrna->dnaname) fprintf(f, "\t_self= (struct %s *)_ptr->data;\n", dsrna->dnaname);
- else fprintf(f, "\t_self= (struct %s *)_ptr->data;\n", srna->identifier);
+ if (dsrna->dnaname) fprintf(f, "\t_self = (struct %s *)_ptr->data;\n", dsrna->dnaname);
+ else fprintf(f, "\t_self = (struct %s *)_ptr->data;\n", srna->identifier);
}
else if (func->flag & FUNC_USE_SELF_TYPE) {
- fprintf(f, "\t_type= _ptr->type;\n");
+ fprintf(f, "\t_type = _ptr->type;\n");
}
if (has_data) {
- fprintf(f, "\t_data= (char *)_parms->data;\n");
+ fprintf(f, "\t_data = (char *)_parms->data;\n");
}
dparm = dfunc->cont.properties.first;
@@ -2248,7 +2249,7 @@ static void rna_def_function_funcs(FILE *f, StructDefRNA *dsrna, FunctionDefRNA
cptr = ((type == PROP_POINTER) && !(flag & PROP_RNAPTR));
if (dparm->prop == func->c_ret)
- fprintf(f, "\t_retdata= _data;\n");
+ fprintf(f, "\t_retdata = _data;\n");
else {
const char *data_str;
if (cptr || (flag & PROP_DYNAMIC)) {
@@ -2275,7 +2276,7 @@ static void rna_def_function_funcs(FILE *f, StructDefRNA *dsrna, FunctionDefRNA
/* this must be kept in sync with RNA_parameter_length_get_data,
* we could just call the function directly, but this is faster */
if (flag & PROP_DYNAMIC) {
- fprintf(f, "\t%s_len= %s((int *)_data);\n", dparm->prop->identifier, pout ? "" : "*");
+ fprintf(f, "\t%s_len = %s((int *)_data);\n", dparm->prop->identifier, pout ? "" : "*");
data_str = "(&(((char *)_data)[sizeof(void *)]))";
}
else {
@@ -2286,12 +2287,12 @@ static void rna_def_function_funcs(FILE *f, StructDefRNA *dsrna, FunctionDefRNA
if (!pout)
fprintf(f, "%s", valstr);
- fprintf(f, "((%s%s%s)%s);\n", rna_type_struct(dparm->prop), rna_parameter_type_name(dparm->prop),
+ fprintf(f, "((%s%s %s)%s);\n", rna_type_struct(dparm->prop), rna_parameter_type_name(dparm->prop),
ptrstr, data_str);
}
if (dparm->next)
- fprintf(f, "\t_data += %d;\n", rna_parameter_size_alloc(dparm->prop));
+ fprintf(f, "\t_data += %d;\n", rna_parameter_size(dparm->prop));
}
if (dfunc->call) {
@@ -2356,7 +2357,7 @@ static void rna_def_function_funcs(FILE *f, StructDefRNA *dsrna, FunctionDefRNA
dparm = rna_find_parameter_def(func->c_ret);
ptrstr = (((dparm->prop->type == PROP_POINTER) && !(dparm->prop->flag & PROP_RNAPTR)) ||
(dparm->prop->arraydimension)) ? "*" : "";
- fprintf(f, "\t*((%s%s%s*)_retdata) = %s;\n", rna_type_struct(dparm->prop),
+ fprintf(f, "\t*((%s%s %s*)_retdata) = %s;\n", rna_type_struct(dparm->prop),
rna_parameter_type_name(dparm->prop), ptrstr, func->c_ret->identifier);
}
}
@@ -2915,9 +2916,9 @@ static void rna_generate_property(FILE *f, StructRNA *srna, const char *nest, Pr
fprintf(f, ", %d, ", prop->flag);
rna_print_c_string(f, prop->name); fprintf(f, ",\n\t");
rna_print_c_string(f, prop->description); fprintf(f, ",\n\t");
- fprintf(f, "%d,\n", prop->icon);
- rna_print_c_string(f, prop->translation_context); fprintf(f, ",\n\t");
- fprintf(f, "\t%s, %s|%s, %s, %u, {%u, %u, %u}, %u,\n",
+ fprintf(f, "%d, ", prop->icon);
+ rna_print_c_string(f, prop->translation_context); fprintf(f, ",\n");
+ fprintf(f, "\t%s, %s | %s, %s, %u, {%u, %u, %u}, %u,\n",
RNA_property_typename(prop->type),
rna_property_subtypename(prop->subtype),
rna_property_subtype_unit(prop->subtype),
@@ -3155,14 +3156,14 @@ static void rna_generate_struct(BlenderRNA *UNUSED(brna), StructRNA *srna, FILE
else fprintf(f, "NULL}},\n");
fprintf(f, "\t");
rna_print_c_string(f, srna->identifier);
- fprintf(f, "\t, NULL,NULL\n"); /* PyType - Cant initialize here */
+ fprintf(f, ", NULL, NULL"); /* PyType - Cant initialize here */
fprintf(f, ", %d, ", srna->flag);
rna_print_c_string(f, srna->name);
- fprintf(f, ", ");
+ fprintf(f, ",\n\t");
rna_print_c_string(f, srna->description);
- fprintf(f, ", ");
+ fprintf(f, ",\n\t");
rna_print_c_string(f, srna->translation_context);
- fprintf(f, ",\n\t%d,\n", srna->icon);
+ fprintf(f, ", %d,\n", srna->icon);
prop = srna->nameproperty;
if (prop) {
@@ -3392,7 +3393,7 @@ static void rna_generate_header(BlenderRNA *UNUSED(brna), FILE *f)
fprintf(f, " CollectionPropertyIterator rna_macro_iter; \\\n");
fprintf(f, " for (property##_begin(&rna_macro_iter, sptr); rna_macro_iter.valid; "
"property##_next(&rna_macro_iter)) { \\\n");
- fprintf(f, " itemptr= rna_macro_iter.ptr;\n\n");
+ fprintf(f, " itemptr = rna_macro_iter.ptr;\n\n");
fprintf(f, "#define FOREACH_END(property) \\\n");
fprintf(f, " } \\\n");
@@ -3495,7 +3496,7 @@ static const char *cpp_classes = ""
"\n"
"#define STRING_PROPERTY(sname, identifier) \\\n"
" inline std::string sname::identifier(void) { \\\n"
-" int len= sname##_##identifier##_length(&ptr); \\\n"
+" int len = sname##_##identifier##_length(&ptr); \\\n"
" std::string str; str.resize(len); \\\n"
" sname##_##identifier##_get(&ptr, &str[0]); return str; } \\\n"
" inline void sname::identifier(const std::string& value) { \\\n"
@@ -3604,7 +3605,7 @@ static const char *cpp_classes = ""
"\n"
" Array() {}\n"
" Array(const Array<T, Tsize>& other) { memcpy(data, other.data, sizeof(T) * Tsize); }\n"
-" const Array<T, Tsize>& operator=(const Array<T, Tsize>& other) { memcpy(data, other.data, sizeof(T) * Tsize); "
+" const Array<T, Tsize>& operator = (const Array<T, Tsize>& other) { memcpy(data, other.data, sizeof(T) * Tsize); "
"return *this; }\n"
"\n"
" operator T*() { return data; }\n"
@@ -3619,7 +3620,7 @@ static const char *cpp_classes = ""
" DynamicArray() : data(NULL), length(0) {}\n"
" DynamicArray(int new_length) : data(NULL), length(new_length) { data = (float *)malloc(sizeof(T) * new_length); }\n"
" DynamicArray(const DynamicArray<T>& other) { copy_from(other); }\n"
-" const DynamicArray<T>& operator=(const DynamicArray<T>& other) { copy_from(other); return *this; }\n"
+" const DynamicArray<T>& operator = (const DynamicArray<T>& other) { copy_from(other); return *this; }\n"
"\n"
" ~DynamicArray() { if (data) free(data); }\n"
"\n"
@@ -3644,7 +3645,7 @@ static const char *cpp_classes = ""
"template<typename T, TBeginFunc Tbegin, TNextFunc Tnext, TEndFunc Tend>\n"
"class CollectionIterator {\n"
"public:\n"
-" CollectionIterator() : t(iter.ptr), init(false) { iter.valid= false; }\n"
+" CollectionIterator() : t(iter.ptr), init(false) { iter.valid = false; }\n"
" ~CollectionIterator(void) { if (init) Tend(&iter); };\n"
"\n"
" operator bool(void)\n"
@@ -3653,7 +3654,7 @@ static const char *cpp_classes = ""
"\n"
" T& operator*(void) { return t; }\n"
" T* operator->(void) { return &t; }\n"
-" bool operator==(const CollectionIterator<T, Tbegin, Tnext, Tend>& other) "
+" bool operator == (const CollectionIterator<T, Tbegin, Tnext, Tend>& other) "
"{ return iter.valid == other.iter.valid; }\n"
" bool operator!=(const CollectionIterator<T, Tbegin, Tnext, Tend>& other) "
"{ return iter.valid != other.iter.valid; }\n"
@@ -3662,7 +3663,7 @@ static const char *cpp_classes = ""
" { if (init) Tend(&iter); Tbegin(&iter, (PointerRNA *)&ptr.ptr); t = T(iter.ptr); init = true; }\n"
"\n"
"private:\n"
-" const CollectionIterator<T, Tbegin, Tnext, Tend>& operator="
+" const CollectionIterator<T, Tbegin, Tnext, Tend>& operator = "
"(const CollectionIterator<T, Tbegin, Tnext, Tend>& copy) {}\n"
""
" CollectionPropertyIterator iter;\n"
diff --git a/source/blender/makesrna/intern/rna_ID.c b/source/blender/makesrna/intern/rna_ID.c
index 0489f85a37f..26febf217a6 100644
--- a/source/blender/makesrna/intern/rna_ID.c
+++ b/source/blender/makesrna/intern/rna_ID.c
@@ -347,15 +347,32 @@ int rna_IDMaterials_assign_int(PointerRNA *ptr, int key, const PointerRNA *assig
static void rna_IDMaterials_append_id(ID *id, Material *ma)
{
- material_append_id(id, ma);
+ BKE_material_append_id(id, ma);
WM_main_add_notifier(NC_OBJECT | ND_DRAW, id);
WM_main_add_notifier(NC_OBJECT | ND_OB_SHADING, id);
}
-static Material *rna_IDMaterials_pop_id(ID *id, int index_i, int remove_material_slot)
+static Material *rna_IDMaterials_pop_id(ID *id, ReportList *reports, int index_i, int remove_material_slot)
{
- Material *ma = material_pop_id(id, index_i, remove_material_slot);
+ Material *ma;
+ short *totcol = give_totcolp_id(id);
+ const short totcol_orig = *totcol;
+ if (index_i < 0) {
+ index_i += (*totcol);
+ }
+
+ if ((index_i < 0) || (index_i >= (*totcol))) {
+ BKE_report(reports, RPT_ERROR, "Index out of range");
+ return NULL;
+ }
+
+ ma = BKE_material_pop_id(id, index_i, remove_material_slot);
+
+ if (*totcol == totcol_orig) {
+ BKE_report(reports, RPT_ERROR, "No material to removed");
+ return NULL;
+ }
DAG_id_tag_update(id, OB_RECALC_DATA);
WM_main_add_notifier(NC_OBJECT | ND_DRAW, id);
@@ -364,6 +381,15 @@ static Material *rna_IDMaterials_pop_id(ID *id, int index_i, int remove_material
return ma;
}
+static void rna_IDMaterials_clear_id(ID *id, int remove_material_slot)
+{
+ BKE_material_clear_id(id, remove_material_slot);
+
+ DAG_id_tag_update(id, OB_RECALC_DATA);
+ WM_main_add_notifier(NC_OBJECT | ND_DRAW, id);
+ WM_main_add_notifier(NC_OBJECT | ND_OB_SHADING, id);
+}
+
static void rna_Library_filepath_set(PointerRNA *ptr, const char *value)
{
Library *lib = (Library *)ptr->data;
@@ -476,12 +502,16 @@ static void rna_def_ID_materials(BlenderRNA *brna)
RNA_def_property_flag(parm, PROP_REQUIRED);
func = RNA_def_function(srna, "pop", "rna_IDMaterials_pop_id");
+ RNA_def_function_flag(func, FUNC_USE_REPORTS);
RNA_def_function_ui_description(func, "Remove a material from the data block");
- parm = RNA_def_int(func, "index", 0, 0, MAXMAT, "", "Index of material to remove", 0, MAXMAT);
- RNA_def_property_flag(parm, PROP_REQUIRED);
+ parm = RNA_def_int(func, "index", -1, -MAXMAT, MAXMAT, "", "Index of material to remove", 0, MAXMAT);
RNA_def_boolean(func, "update_data", 0, "", "Update data by re-adjusting the material slots assigned");
parm = RNA_def_pointer(func, "material", "Material", "", "Material to remove");
RNA_def_function_return(func, parm);
+
+ func = RNA_def_function(srna, "clear", "rna_IDMaterials_clear_id");
+ RNA_def_function_ui_description(func, "Remove all materials from the data block");
+ RNA_def_boolean(func, "update_data", 0, "", "Update data by re-adjusting the material slots assigned");
}
static void rna_def_ID(BlenderRNA *brna)
diff --git a/source/blender/makesrna/intern/rna_access.c b/source/blender/makesrna/intern/rna_access.c
index 5499386dcf1..f3e561cde0a 100644
--- a/source/blender/makesrna/intern/rna_access.c
+++ b/source/blender/makesrna/intern/rna_access.c
@@ -5378,7 +5378,7 @@ ParameterList *RNA_parameter_list_create(ParameterList *parms, PointerRNA *UNUSE
/* allocate data */
for (parm = func->cont.properties.first; parm; parm = parm->next) {
- alloc_size += rna_parameter_size_alloc(parm);
+ alloc_size += rna_parameter_size(parm);
if (parm->flag & PROP_OUTPUT)
parms->ret_count++;
@@ -5440,7 +5440,7 @@ ParameterList *RNA_parameter_list_create(ParameterList *parms, PointerRNA *UNUSE
}
}
- data = ((char *)data) + rna_parameter_size_alloc(parm);
+ data = ((char *)data) + rna_parameter_size(parm);
}
return parms;
@@ -5462,7 +5462,7 @@ void RNA_parameter_list_free(ParameterList *parms)
MEM_freeN(data_alloc->array);
}
- tot += rna_parameter_size_alloc(parm);
+ tot += rna_parameter_size(parm);
}
MEM_freeN(parms->data);
@@ -5497,7 +5497,7 @@ void RNA_parameter_list_begin(ParameterList *parms, ParameterIterator *iter)
iter->offset = 0;
if (iter->valid) {
- iter->size = rna_parameter_size_alloc(iter->parm);
+ iter->size = rna_parameter_size(iter->parm);
iter->data = (((char *)iter->parms->data)); /* +iter->offset, always 0 */
}
}
@@ -5509,7 +5509,7 @@ void RNA_parameter_list_next(ParameterIterator *iter)
iter->valid = iter->parm != NULL;
if (iter->valid) {
- iter->size = rna_parameter_size_alloc(iter->parm);
+ iter->size = rna_parameter_size(iter->parm);
iter->data = (((char *)iter->parms->data) + iter->offset);
}
}
@@ -6392,6 +6392,7 @@ bool RNA_property_equals(PointerRNA *a, PointerRNA *b, PropertyRNA *prop, bool i
PointerRNA propptr_b = RNA_property_pointer_get(b, prop);
return RNA_struct_equals(&propptr_a, &propptr_b, is_strict);
}
+ break;
}
default:
diff --git a/source/blender/makesrna/intern/rna_armature.c b/source/blender/makesrna/intern/rna_armature.c
index fd151ccebb9..a832a8cdf96 100644
--- a/source/blender/makesrna/intern/rna_armature.c
+++ b/source/blender/makesrna/intern/rna_armature.c
@@ -398,16 +398,7 @@ static void rna_EditBone_parent_set(PointerRNA *ptr, PointerRNA value)
static void rna_EditBone_matrix_get(PointerRNA *ptr, float *values)
{
EditBone *ebone = (EditBone *)(ptr->data);
-
- float delta[3], tmat[3][3], mat[4][4];
-
- /* Find the current bone matrix */
- sub_v3_v3v3(delta, ebone->tail, ebone->head);
- vec_roll_to_mat3(delta, ebone->roll, tmat);
- copy_m4_m3(mat, tmat);
- copy_v3_v3(mat[3], ebone->head);
-
- memcpy(values, mat, 16 * sizeof(float));
+ ED_armature_ebone_to_mat4(ebone, (float(*)[4])values);
}
static void rna_Armature_editbone_transform_update(Main *bmain, Scene *scene, PointerRNA *ptr)
diff --git a/source/blender/makesrna/intern/rna_brush.c b/source/blender/makesrna/intern/rna_brush.c
index c1707048612..5d68a6905a3 100644
--- a/source/blender/makesrna/intern/rna_brush.c
+++ b/source/blender/makesrna/intern/rna_brush.c
@@ -1086,19 +1086,19 @@ static void rna_def_brush(BlenderRNA *brna)
prop = RNA_def_property(srna, "texture_overlay_alpha", PROP_INT, PROP_PERCENTAGE);
RNA_def_property_int_sdna(prop, NULL, "texture_overlay_alpha");
- RNA_def_property_range(prop, 1, 100);
+ RNA_def_property_range(prop, 0, 100);
RNA_def_property_ui_text(prop, "Texture Overlay Alpha", "");
RNA_def_property_update(prop, 0, "rna_Brush_update");
prop = RNA_def_property(srna, "mask_overlay_alpha", PROP_INT, PROP_PERCENTAGE);
RNA_def_property_int_sdna(prop, NULL, "mask_overlay_alpha");
- RNA_def_property_range(prop, 1, 100);
+ RNA_def_property_range(prop, 0, 100);
RNA_def_property_ui_text(prop, "Mask Texture Overlay Alpha", "");
RNA_def_property_update(prop, 0, "rna_Brush_update");
prop = RNA_def_property(srna, "cursor_overlay_alpha", PROP_INT, PROP_PERCENTAGE);
RNA_def_property_int_sdna(prop, NULL, "cursor_overlay_alpha");
- RNA_def_property_range(prop, 1, 100);
+ RNA_def_property_range(prop, 0, 100);
RNA_def_property_ui_text(prop, "Mask Texture Overlay Alpha", "");
RNA_def_property_update(prop, 0, "rna_Brush_update");
diff --git a/source/blender/makesrna/intern/rna_color.c b/source/blender/makesrna/intern/rna_color.c
index ec61c543a9f..ebd06475c79 100644
--- a/source/blender/makesrna/intern/rna_color.c
+++ b/source/blender/makesrna/intern/rna_color.c
@@ -288,6 +288,7 @@ static char *rna_ColorRampElement_path(PointerRNA *ptr)
if (RNA_path_resolve(&ramp_ptr, "color_ramp", &ramp_ptr, &prop)) {
COLRAMP_GETPATH;
}
+ break;
}
}
}
diff --git a/source/blender/makesrna/intern/rna_define.c b/source/blender/makesrna/intern/rna_define.c
index 969e715bebf..723f158bb50 100644
--- a/source/blender/makesrna/intern/rna_define.c
+++ b/source/blender/makesrna/intern/rna_define.c
@@ -3039,13 +3039,13 @@ void RNA_def_function_ui_description(FunctionRNA *func, const char *description)
int rna_parameter_size(PropertyRNA *parm)
{
PropertyType ptype = parm->type;
- int len = parm->totarraylength; /* only supports fixed length at the moment */
+ int len = parm->totarraylength;
- if (len > 0) {
- /* XXX in other parts is mentioned that strings can be dynamic as well */
- if (parm->flag & PROP_DYNAMIC)
- return sizeof(void *);
+ /* XXX in other parts is mentioned that strings can be dynamic as well */
+ if (parm->flag & PROP_DYNAMIC)
+ return sizeof(ParameterDynAlloc);
+ if (len > 0) {
switch (ptype) {
case PROP_BOOLEAN:
case PROP_INT:
@@ -3106,18 +3106,6 @@ int rna_parameter_size(PropertyRNA *parm)
return sizeof(void *);
}
-/* this function returns the size of the memory allocated for the parameter,
- * useful for instance for memory alignment or for storing additional information */
-int rna_parameter_size_alloc(PropertyRNA *parm)
-{
- int size = rna_parameter_size(parm);
-
- if (parm->flag & PROP_DYNAMIC)
- size += sizeof(((ParameterDynAlloc *)NULL)->array_tot);
-
- return size;
-}
-
/* Dynamic Enums */
void RNA_enum_item_add(EnumPropertyItem **items, int *totitem, const EnumPropertyItem *item)
diff --git a/source/blender/makesrna/intern/rna_dynamicpaint.c b/source/blender/makesrna/intern/rna_dynamicpaint.c
index fb16dd0c5a1..c716c3263d1 100644
--- a/source/blender/makesrna/intern/rna_dynamicpaint.c
+++ b/source/blender/makesrna/intern/rna_dynamicpaint.c
@@ -710,6 +710,12 @@ static void rna_def_canvas_surface(BlenderRNA *brna)
RNA_def_property_ui_range(prop, 0.01, 1.0, 1, 2);
RNA_def_property_ui_text(prop, "Spring", "Spring force that pulls water level back to zero");
+ prop = RNA_def_property(srna, "wave_smoothness", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_range(prop, 0.0, 10.0);
+ RNA_def_property_ui_range(prop, 0.1, 5.0, 1, 2);
+ RNA_def_property_ui_text(prop, "Smoothness", "Limit maximum steepness of wave slope between simulation points "
+ "(use higher values for smoother waves at expense of reduced detail)");
+
prop = RNA_def_property(srna, "use_wave_open_border", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flags", MOD_DPAINT_WAVE_OPEN_BORDERS);
RNA_def_property_ui_text(prop, "Open Borders", "Pass waves through mesh edges");
diff --git a/source/blender/makesrna/intern/rna_gpencil.c b/source/blender/makesrna/intern/rna_gpencil.c
index efe6c08cafe..439bc51896f 100644
--- a/source/blender/makesrna/intern/rna_gpencil.c
+++ b/source/blender/makesrna/intern/rna_gpencil.c
@@ -118,11 +118,9 @@ static void rna_GPencilLayer_info_set(PointerRNA *ptr, const char *value)
static void rna_GPencil_stroke_point_add(bGPDstroke *stroke, int count)
{
if (count > 0) {
- if (stroke->points == NULL)
- stroke->points = MEM_callocN(sizeof(bGPDspoint) * count, "gp_stroke_points");
- else
- stroke->points = MEM_recallocN(stroke->points, sizeof(bGPDspoint) * (stroke->totpoints + count));
-
+ stroke->points = MEM_recallocN_id(stroke->points,
+ sizeof(bGPDspoint) * (stroke->totpoints + count),
+ "gp_stroke_points");
stroke->totpoints += count;
}
}
diff --git a/source/blender/makesrna/intern/rna_internal.h b/source/blender/makesrna/intern/rna_internal.h
index d1cfb01abfb..72985f7b6e6 100644
--- a/source/blender/makesrna/intern/rna_internal.h
+++ b/source/blender/makesrna/intern/rna_internal.h
@@ -402,7 +402,6 @@ PointerRNA rna_pointer_inherit_refine(struct PointerRNA *ptr, struct StructRNA *
/* Functions */
int rna_parameter_size(struct PropertyRNA *parm);
-int rna_parameter_size_alloc(struct PropertyRNA *parm);
struct Mesh *rna_Main_meshes_new_from_object(
struct Main *bmain, struct ReportList *reports, struct Scene *sce,
diff --git a/source/blender/makesrna/intern/rna_mesh.c b/source/blender/makesrna/intern/rna_mesh.c
index 51aad755e77..35d8a0fb433 100644
--- a/source/blender/makesrna/intern/rna_mesh.c
+++ b/source/blender/makesrna/intern/rna_mesh.c
@@ -37,7 +37,6 @@
#include "DNA_meshdata_types.h"
#include "DNA_object_types.h"
-#include "BLI_array.h"
#include "BLI_math_base.h"
#include "BLI_math_rotation.h"
#include "BLI_utildefines.h"
diff --git a/source/blender/makesrna/intern/rna_meta.c b/source/blender/makesrna/intern/rna_meta.c
index 898825820ac..11f0e48012b 100644
--- a/source/blender/makesrna/intern/rna_meta.c
+++ b/source/blender/makesrna/intern/rna_meta.c
@@ -164,6 +164,22 @@ static int rna_Meta_is_editmode_get(PointerRNA *ptr)
return (mb->editelems != NULL);
}
+static char *rna_MetaElement_path(PointerRNA *ptr)
+{
+ MetaBall *mb = ptr->id.data;
+ MetaElem *ml = ptr->data;
+ int index = -1;
+
+ if (mb->editelems)
+ index = BLI_findindex(mb->editelems, ml);
+ if (index == -1)
+ index = BLI_findindex(&mb->elems, ml);
+ if (index == -1)
+ return NULL;
+
+ return BLI_sprintfN("elements[%d]", index);
+}
+
#else
static void rna_def_metaelement(BlenderRNA *brna)
@@ -174,6 +190,7 @@ static void rna_def_metaelement(BlenderRNA *brna)
srna = RNA_def_struct(brna, "MetaElement", NULL);
RNA_def_struct_sdna(srna, "MetaElem");
RNA_def_struct_ui_text(srna, "Meta Element", "Blobby element in a Metaball datablock");
+ RNA_def_struct_path_func(srna, "rna_MetaElement_path");
RNA_def_struct_ui_icon(srna, ICON_OUTLINER_DATA_META);
/* enums */
diff --git a/source/blender/makesrna/intern/rna_modifier.c b/source/blender/makesrna/intern/rna_modifier.c
index f4f557e1985..1c764d396f7 100644
--- a/source/blender/makesrna/intern/rna_modifier.c
+++ b/source/blender/makesrna/intern/rna_modifier.c
@@ -43,7 +43,6 @@
#include "BLF_translation.h"
#include "BKE_animsys.h"
-#include "BKE_bmesh.h" /* For BevelModifierData */
#include "BKE_dynamicpaint.h"
#include "BKE_multires.h"
#include "BKE_smoke.h" /* For smokeModifier_free & smokeModifier_createType */
@@ -2315,10 +2314,10 @@ static void rna_def_modifier_bevel(BlenderRNA *brna)
static EnumPropertyItem prop_limit_method_items[] = {
{0, "NONE", 0, "None", "Bevel the entire mesh by a constant amount"},
- {BME_BEVEL_ANGLE, "ANGLE", 0, "Angle", "Only bevel edges with sharp enough angles between faces"},
- {BME_BEVEL_WEIGHT, "WEIGHT", 0, "Weight",
+ {MOD_BEVEL_ANGLE, "ANGLE", 0, "Angle", "Only bevel edges with sharp enough angles between faces"},
+ {MOD_BEVEL_WEIGHT, "WEIGHT", 0, "Weight",
"Use bevel weights to determine how much bevel is applied in edge mode"},
- {BME_BEVEL_VGROUP, "VGROUP", 0, "Vertex Group",
+ {MOD_BEVEL_VGROUP, "VGROUP", 0, "Vertex Group",
"Use vertex group weights to determine how much bevel is applied in vertex mode"},
{0, NULL, 0, NULL, NULL}
};
@@ -2326,8 +2325,8 @@ static void rna_def_modifier_bevel(BlenderRNA *brna)
/* TO BE DEPRECATED */
static EnumPropertyItem prop_edge_weight_method_items[] = {
{0, "AVERAGE", 0, "Average", ""},
- {BME_BEVEL_EMIN, "SHARPEST", 0, "Sharpest", ""},
- {BME_BEVEL_EMAX, "LARGEST", 0, "Largest", ""},
+ {MOD_BEVEL_EMIN, "SHARPEST", 0, "Sharpest", ""},
+ {MOD_BEVEL_EMAX, "LARGEST", 0, "Largest", ""},
{0, NULL, 0, NULL, NULL}
};
@@ -2350,7 +2349,7 @@ static void rna_def_modifier_bevel(BlenderRNA *brna)
RNA_def_property_update(prop, 0, "rna_Modifier_update");
prop = RNA_def_property(srna, "use_only_vertices", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_sdna(prop, NULL, "flags", BME_BEVEL_VERT);
+ RNA_def_property_boolean_sdna(prop, NULL, "flags", MOD_BEVEL_VERT);
RNA_def_property_ui_text(prop, "Only Vertices", "Bevel verts/corners, not edges");
RNA_def_property_update(prop, 0, "rna_Modifier_update");
@@ -2367,22 +2366,14 @@ static void rna_def_modifier_bevel(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Edge Weight Method", "What edge weight to use for weighting a vertex");
RNA_def_property_update(prop, 0, "rna_Modifier_update");
-#if 1 /* expose as radians */
prop = RNA_def_property(srna, "angle_limit", PROP_FLOAT, PROP_ANGLE);
RNA_def_property_float_funcs(prop, "rna_BevelModifier_angle_limit_get",
"rna_BevelModifier_angle_limit_set", NULL);
RNA_def_property_range(prop, 0, DEG2RAD(180));
RNA_def_property_ui_range(prop, 0, DEG2RAD(180), 100, 2);
-#else
- prop = RNA_def_property(srna, "angle_limit", PROP_FLOAT, PROP_NONE);
- RNA_def_property_float_sdna(prop, NULL, "bevel_angle");
- RNA_def_property_range(prop, 0, 180);
- RNA_def_property_ui_range(prop, 0, 180, 100, 2);
-#endif
RNA_def_property_ui_text(prop, "Angle", "Angle above which to bevel edges");
RNA_def_property_update(prop, 0, "rna_Modifier_update");
-#ifdef USE_BM_BEVEL_OP_AS_MOD
prop = RNA_def_property(srna, "vertex_group", PROP_STRING, PROP_NONE);
RNA_def_property_string_sdna(prop, NULL, "defgrp_name");
RNA_def_property_ui_text(prop, "Vertex Group", "Vertex group name");
@@ -2390,11 +2381,9 @@ static void rna_def_modifier_bevel(BlenderRNA *brna)
RNA_def_property_update(prop, 0, "rna_Modifier_update");
prop = RNA_def_property(srna, "use_clamp_overlap", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_negative_sdna(prop, NULL, "flags", BME_BEVEL_OVERLAP_OK);
+ RNA_def_property_boolean_negative_sdna(prop, NULL, "flags", MOD_BEVEL_OVERLAP_OK);
RNA_def_property_ui_text(prop, "Clamp Overlap", "Clamp the width to avoid overlap");
RNA_def_property_update(prop, 0, "rna_Modifier_update");
-#endif
-
}
static void rna_def_modifier_shrinkwrap(BlenderRNA *brna)
@@ -2607,11 +2596,6 @@ static void rna_def_modifier_simpledeform(BlenderRNA *brna)
RNA_def_property_flag(prop, PROP_EDITABLE | PROP_ID_SELF_CHECK);
RNA_def_property_update(prop, 0, "rna_Modifier_dependency_update");
- prop = RNA_def_property(srna, "use_relative", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_sdna(prop, NULL, "originOpts", MOD_SIMPLEDEFORM_ORIGIN_LOCAL);
- RNA_def_property_ui_text(prop, "Relative", "Set the origin of deform space to be relative to the object");
- RNA_def_property_update(prop, 0, "rna_Modifier_update");
-
prop = RNA_def_property(srna, "factor", PROP_FLOAT, PROP_NONE);
RNA_def_property_range(prop, -FLT_MAX, FLT_MAX);
RNA_def_property_ui_range(prop, -10, 10, 1, 3);
diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c
index 0c31f042f93..535c279c02f 100644
--- a/source/blender/makesrna/intern/rna_nodetree.c
+++ b/source/blender/makesrna/intern/rna_nodetree.c
@@ -3509,6 +3509,42 @@ static void def_sh_tex_coord(StructRNA *srna)
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
}
+static void def_sh_vect_transform(StructRNA *srna)
+{
+ static EnumPropertyItem prop_vect_type_items[] = {
+ {SHD_VECT_TRANSFORM_TYPE_VECTOR, "VECTOR", 0, "Vector", ""},
+ {SHD_VECT_TRANSFORM_TYPE_POINT, "POINT", 0, "Point", ""},
+ {SHD_VECT_TRANSFORM_TYPE_NORMAL, "NORMAL", 0, "Normal", ""},
+ {0, NULL, 0, NULL, NULL}
+ };
+
+ static EnumPropertyItem prop_vect_space_items[] = {
+ {SHD_VECT_TRANSFORM_SPACE_WORLD, "WORLD", 0, "World", ""},
+ {SHD_VECT_TRANSFORM_SPACE_OBJECT, "OBJECT", 0, "Object", ""},
+ {SHD_VECT_TRANSFORM_SPACE_CAMERA, "CAMERA", 0, "Camera", ""},
+ {0, NULL, 0, NULL, NULL}
+ };
+
+ PropertyRNA *prop;
+
+ RNA_def_struct_sdna_from(srna, "NodeShaderVectTransform", "storage");
+
+ prop = RNA_def_property(srna, "type", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_items(prop, prop_vect_type_items);
+ RNA_def_property_ui_text(prop, "Type", "");
+ RNA_def_property_update(prop, 0, "rna_Node_update");
+
+ prop = RNA_def_property(srna, "convert_from", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_items(prop, prop_vect_space_items);
+ RNA_def_property_ui_text(prop, "Convert From", "Space to convert from");
+ RNA_def_property_update(prop, 0, "rna_Node_update");
+
+ prop = RNA_def_property(srna, "convert_to", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_items(prop, prop_vect_space_items);
+ RNA_def_property_ui_text(prop, "Convert To", "Space to convert to");
+ RNA_def_property_update(prop, 0, "rna_Node_update");
+}
+
static void def_sh_tex_wireframe(StructRNA *srna)
{
PropertyRNA *prop;
@@ -4032,7 +4068,7 @@ static void def_cmp_render_layers(StructRNA *srna)
RNA_def_property_pointer_sdna(prop, NULL, "id");
RNA_def_property_pointer_funcs(prop, NULL, "rna_Node_scene_set", NULL, NULL);
RNA_def_property_struct_type(prop, "Scene");
- RNA_def_property_flag(prop, PROP_EDITABLE | PROP_ID_SELF_CHECK);
+ RNA_def_property_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "Scene", "");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
diff --git a/source/blender/makesrna/intern/rna_object_api.c b/source/blender/makesrna/intern/rna_object_api.c
index a4e532660f1..25ca231e58d 100644
--- a/source/blender/makesrna/intern/rna_object_api.c
+++ b/source/blender/makesrna/intern/rna_object_api.c
@@ -259,6 +259,21 @@ static void rna_Mesh_assign_verts_to_group(Object *ob, bDeformGroup *group, int
}
#endif
+/* don't call inside a loop */
+static int dm_tessface_to_poly_index(DerivedMesh *dm, int tessface_index)
+{
+ if (tessface_index != ORIGINDEX_NONE) {
+ /* double lookup */
+ const int *index_mf_to_mpoly;
+ if ((index_mf_to_mpoly = dm->getTessFaceDataArray(dm, CD_ORIGINDEX))) {
+ const int *index_mp_to_orig = dm->getPolyDataArray(dm, CD_ORIGINDEX);
+ return DM_origindex_mface_mpoly(index_mf_to_mpoly, index_mp_to_orig, tessface_index);
+ }
+ }
+
+ return ORIGINDEX_NONE;
+}
+
/* BMESH_TODO, return polygon index, not tessface */
static void rna_Object_ray_cast(Object *ob, ReportList *reports, float ray_start[3], float ray_end[3],
float r_location[3], float r_normal[3], int *index)
@@ -291,7 +306,7 @@ static void rna_Object_ray_cast(Object *ob, ReportList *reports, float ray_start
if (hit.dist <= dist) {
copy_v3_v3(r_location, hit.co);
copy_v3_v3(r_normal, hit.no);
- *index = hit.index;
+ *index = dm_tessface_to_poly_index(ob->derivedFinal, hit.index);
return;
}
}
@@ -330,7 +345,7 @@ static void rna_Object_closest_point_on_mesh(Object *ob, ReportList *reports, fl
if (BLI_bvhtree_find_nearest(treeData.tree, point_co, &nearest, treeData.nearest_callback, &treeData) != -1) {
copy_v3_v3(n_location, nearest.co);
copy_v3_v3(n_normal, nearest.no);
- *index = nearest.index;
+ *index = dm_tessface_to_poly_index(ob->derivedFinal, nearest.index);
return;
}
}
diff --git a/source/blender/makesrna/intern/rna_object_force.c b/source/blender/makesrna/intern/rna_object_force.c
index 06d8f4faf04..1d2aa08e7cd 100644
--- a/source/blender/makesrna/intern/rna_object_force.c
+++ b/source/blender/makesrna/intern/rna_object_force.c
@@ -184,6 +184,7 @@ static void rna_Cache_idname_change(Main *UNUSED(bmain), Scene *UNUSED(scene), P
BKE_ptcache_load_external(pid);
DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
+ WM_main_add_notifier(NC_OBJECT | ND_POINTCACHE, ob);
}
else {
for (pid = pidlist.first; pid; pid = pid->next) {
diff --git a/source/blender/makesrna/intern/rna_render.c b/source/blender/makesrna/intern/rna_render.c
index 64b4e019c27..82cdfcdd631 100644
--- a/source/blender/makesrna/intern/rna_render.c
+++ b/source/blender/makesrna/intern/rna_render.c
@@ -570,6 +570,9 @@ static void rna_def_render_pass(BlenderRNA *brna)
{SCE_PASS_TRANSM_DIRECT, "TRANSMISSION_DIRECT", 0, "Transmission Direct", ""},
{SCE_PASS_TRANSM_INDIRECT, "TRANSMISSION_INDIRECT", 0, "Transmission Indirect", ""},
{SCE_PASS_TRANSM_COLOR, "TRANSMISSION_COLOR", 0, "Transmission Color", ""},
+ {SCE_PASS_SUBSURFACE_DIRECT, "SUBSURFACE_DIRECT", 0, "Subsurface Direct", ""},
+ {SCE_PASS_SUBSURFACE_INDIRECT, "SUBSURFACE_INDIRECT", 0, "Subsurface Indirect", ""},
+ {SCE_PASS_SUBSURFACE_COLOR, "SUBSURFACE_COLOR", 0, "Subsurface Color", ""},
{0, NULL, 0, NULL, NULL}
};
diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c
index d6dc2162720..83dbd79024e 100644
--- a/source/blender/makesrna/intern/rna_scene.c
+++ b/source/blender/makesrna/intern/rna_scene.c
@@ -2555,6 +2555,24 @@ void rna_def_render_layer_common(StructRNA *srna, int scene)
RNA_def_property_ui_text(prop, "Transmission Color", "Deliver transmission color pass");
if (scene) RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, "rna_SceneRenderLayer_pass_update");
else RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+
+ prop = RNA_def_property(srna, "use_pass_subsurface_direct", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "passflag", SCE_PASS_SUBSURFACE_DIRECT);
+ RNA_def_property_ui_text(prop, "Subsurface Direct", "Deliver subsurface direct pass");
+ if (scene) RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, "rna_SceneRenderLayer_pass_update");
+ else RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+
+ prop = RNA_def_property(srna, "use_pass_subsurface_indirect", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "passflag", SCE_PASS_SUBSURFACE_INDIRECT);
+ RNA_def_property_ui_text(prop, "Subsurface Indirect", "Deliver subsurface indirect pass");
+ if (scene) RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, "rna_SceneRenderLayer_pass_update");
+ else RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+
+ prop = RNA_def_property(srna, "use_pass_subsurface_color", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "passflag", SCE_PASS_SUBSURFACE_COLOR);
+ RNA_def_property_ui_text(prop, "Subsurface Color", "Deliver subsurface color pass");
+ if (scene) RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, "rna_SceneRenderLayer_pass_update");
+ else RNA_def_property_clear_flag(prop, PROP_EDITABLE);
}
static void rna_def_freestyle_linesets(BlenderRNA *brna, PropertyRNA *cprop)
@@ -3126,8 +3144,15 @@ static void rna_def_scene_game_data(BlenderRNA *brna)
{0, NULL, 0, NULL, NULL}
};
+ static EnumPropertyItem vsync_items[] = {
+ {VSYNC_OFF, "OFF", 0, "Off", "Disable vsync"},
+ {VSYNC_ON, "ON", 0, "On", "Enable vsync"},
+ {VSYNC_ADAPTIVE, "ADAPTIVE", 0, "Adaptive", "Enable adaptive vsync (if supported)"},
+ {0, NULL, 0, NULL, NULL}
+ };
+
static EnumPropertyItem storage_items[] = {
- {RAS_STORE_AUTO, "AUTO", 0, "Auto Select", "Chooses the best supported mode"},
+ {RAS_STORE_AUTO, "AUTO", 0, "Auto Select", "Choose the best supported mode"},
{RAS_STORE_IMMEDIATE, "IMMEDIATE", 0, "Immediate Mode", "Slowest performance, requires OpenGL (any version)"},
{RAS_STORE_VA, "VERTEX_ARRAY", 0, "Vertex Arrays", "Better performance, requires at least OpenGL 1.1"},
#if 0 /* XXX VBOS are currently disabled since they cannot beat vertex array with display lists in performance. */
@@ -3152,6 +3177,11 @@ static void rna_def_scene_game_data(BlenderRNA *brna)
RNA_def_property_range(prop, 4, 10000);
RNA_def_property_ui_text(prop, "Resolution Y", "Number of vertical pixels in the screen");
RNA_def_property_update(prop, NC_SCENE, NULL);
+
+ prop = RNA_def_property(srna, "vsync", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_sdna(prop, NULL, "vsync");
+ RNA_def_property_enum_items(prop, vsync_items);
+ RNA_def_property_ui_text(prop, "Vsync", "Change vsync settings");
prop = RNA_def_property(srna, "samples", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "aasamples");
diff --git a/source/blender/modifiers/intern/MOD_bevel.c b/source/blender/modifiers/intern/MOD_bevel.c
index 3713cb817f5..b48f434abe9 100644
--- a/source/blender/modifiers/intern/MOD_bevel.c
+++ b/source/blender/modifiers/intern/MOD_bevel.c
@@ -42,7 +42,6 @@
#include "BKE_deform.h"
#include "BKE_modifier.h"
#include "BKE_mesh.h"
-#include "BKE_bmesh.h" /* only for defines */
#include "MOD_util.h"
@@ -91,8 +90,6 @@ static CustomDataMask requiredDataMask(Object *UNUSED(ob), ModifierData *md)
return dataMask;
}
-#ifdef USE_BM_BEVEL_OP_AS_MOD
-
/*
* This calls the new bevel code (added since 2.64)
*/
@@ -110,13 +107,13 @@ static DerivedMesh *applyModifier(ModifierData *md, struct Object *ob,
MDeformVert *dvert = NULL;
BevelModifierData *bmd = (BevelModifierData *) md;
const float threshold = cosf((bmd->bevel_angle + 0.00001f) * (float)M_PI / 180.0f);
- const bool vertex_only = (bmd->flags & BME_BEVEL_VERT) != 0;
- const bool do_clamp = !(bmd->flags & BME_BEVEL_OVERLAP_OK);
+ const bool vertex_only = (bmd->flags & MOD_BEVEL_VERT) != 0;
+ const bool do_clamp = !(bmd->flags & MOD_BEVEL_OVERLAP_OK);
bm = DM_to_bmesh(dm, true);
if (vertex_only) {
- if ((bmd->lim_flags & BME_BEVEL_VGROUP) && bmd->defgrp_name[0]) {
+ if ((bmd->lim_flags & MOD_BEVEL_VGROUP) && bmd->defgrp_name[0]) {
modifier_get_vgroup(ob, dm, bmd->defgrp_name, &dvert, &vgroup);
}
BM_ITER_MESH(v, &iter, bm, BM_VERTS_OF_MESH) {
@@ -131,7 +128,7 @@ static DerivedMesh *applyModifier(ModifierData *md, struct Object *ob,
BM_elem_flag_enable(v, BM_ELEM_TAG);
}
}
- else if (bmd->lim_flags & BME_BEVEL_ANGLE) {
+ else if (bmd->lim_flags & MOD_BEVEL_ANGLE) {
BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) {
/* check for 1 edge having 2 face users */
BMLoop *l_a, *l_b;
@@ -148,7 +145,7 @@ static DerivedMesh *applyModifier(ModifierData *md, struct Object *ob,
/* crummy, is there a way just to operator on all? - campbell */
BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) {
if (BM_edge_is_manifold(e)) {
- if (bmd->lim_flags & BME_BEVEL_WEIGHT) {
+ if (bmd->lim_flags & MOD_BEVEL_WEIGHT) {
weight = BM_elem_float_data_get(&bm->edata, e, CD_BWEIGHT);
if (weight == 0.0f)
continue;
@@ -161,7 +158,7 @@ static DerivedMesh *applyModifier(ModifierData *md, struct Object *ob,
}
BM_mesh_bevel(bm, bmd->value, bmd->res,
- vertex_only, bmd->lim_flags & BME_BEVEL_WEIGHT, do_clamp,
+ vertex_only, bmd->lim_flags & MOD_BEVEL_WEIGHT, do_clamp,
dvert, vgroup);
result = CDDM_from_bmesh(bm, TRUE);
@@ -176,46 +173,6 @@ static DerivedMesh *applyModifier(ModifierData *md, struct Object *ob,
return result;
}
-
-#else /* from trunk, see note above */
-
-static DerivedMesh *applyModifier(ModifierData *md, Object *UNUSED(ob),
- DerivedMesh *derivedData,
- ModifierApplyFlag UNUSED(flag))
-{
- DerivedMesh *result;
- BMesh *bm;
-
- /*bDeformGroup *def;*/
- int /*i,*/ options, defgrp_index = -1;
- BevelModifierData *bmd = (BevelModifierData *) md;
-
- options = bmd->flags | bmd->val_flags | bmd->lim_flags | bmd->e_flags;
-
-#if 0
- if ((options & BME_BEVEL_VWEIGHT) && bmd->defgrp_name[0]) {
- defgrp_index = defgroup_name_index(ob, bmd->defgrp_name);
- if (defgrp_index == -1) {
- options &= ~BME_BEVEL_VWEIGHT;
- }
- }
-#endif
-
- bm = DM_to_bmesh(derivedData);
- BME_bevel(bm, bmd->value, bmd->res, options, defgrp_index, DEG2RADF(bmd->bevel_angle), NULL);
- result = CDDM_from_bmesh(bm, TRUE);
- BM_mesh_free(bm);
-
- /* until we allow for dirty normal flag, always calc,
- * note: calculating on the CDDM is faster then the BMesh equivalent */
- result->dirty |= DM_DIRTY_NORMALS;
-
- return result;
-}
-
-#endif
-
-
ModifierTypeInfo modifierType_Bevel = {
/* name */ "Bevel",
/* structName */ "BevelModifierData",
diff --git a/source/blender/modifiers/intern/MOD_boolean_util.c b/source/blender/modifiers/intern/MOD_boolean_util.c
index 02ec6108733..98fab9c06ff 100644
--- a/source/blender/modifiers/intern/MOD_boolean_util.c
+++ b/source/blender/modifiers/intern/MOD_boolean_util.c
@@ -519,8 +519,8 @@ static DerivedMesh *NewBooleanDerivedMesh_intern(
DerivedMesh *result = NULL;
- if (dm == NULL || dm_select == NULL) return 0;
- if (!dm->getNumTessFaces(dm) || !dm_select->getNumTessFaces(dm_select)) return 0;
+ if (dm == NULL || dm_select == NULL) return NULL;
+ if (!dm->getNumTessFaces(dm) || !dm_select->getNumTessFaces(dm_select)) return NULL;
/* we map the final object back into ob's local coordinate space. For this
* we need to compute the inverse transform from global to ob (inv_mat),
diff --git a/source/blender/modifiers/intern/MOD_cloth.c b/source/blender/modifiers/intern/MOD_cloth.c
index ec3212d4cbb..81f139e48ce 100644
--- a/source/blender/modifiers/intern/MOD_cloth.c
+++ b/source/blender/modifiers/intern/MOD_cloth.c
@@ -72,7 +72,6 @@ static void deformVerts(ModifierData *md, Object *ob, DerivedMesh *derivedData,
{
DerivedMesh *dm;
ClothModifierData *clmd = (ClothModifierData *) md;
- DerivedMesh *result = NULL;
/* check for alloc failing */
if (!clmd->sim_parms || !clmd->coll_parms) {
@@ -92,11 +91,6 @@ static void deformVerts(ModifierData *md, Object *ob, DerivedMesh *derivedData,
clothModifier_do(clmd, md->scene, ob, dm, vertexCos);
- if (result) {
- result->getVertCos(result, vertexCos);
- result->release(result);
- }
-
dm->release(dm);
}
diff --git a/source/blender/modifiers/intern/MOD_decimate.c b/source/blender/modifiers/intern/MOD_decimate.c
index 6c75f1d4be9..9fdb40e71dc 100644
--- a/source/blender/modifiers/intern/MOD_decimate.c
+++ b/source/blender/modifiers/intern/MOD_decimate.c
@@ -127,6 +127,8 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob,
}
calc_face_normal = true;
break;
+ default:
+ return dm;
}
if (dmd->face_count <= 3) {
diff --git a/source/blender/modifiers/intern/MOD_edgesplit.c b/source/blender/modifiers/intern/MOD_edgesplit.c
index e37fc56d08c..b3d3e65e120 100644
--- a/source/blender/modifiers/intern/MOD_edgesplit.c
+++ b/source/blender/modifiers/intern/MOD_edgesplit.c
@@ -44,7 +44,6 @@
#include "BKE_modifier.h"
#include "bmesh.h"
-#include "tools/bmesh_edgesplit.h"
#include "DNA_object_types.h"
@@ -91,7 +90,7 @@ static DerivedMesh *doEdgeSplit(DerivedMesh *dm, EdgeSplitModifierData *emd)
}
}
- BM_mesh_edgesplit(bm, FALSE, TRUE);
+ BM_mesh_edgesplit(bm, false, true, false);
/* BM_mesh_validate(bm); */ /* for troubleshooting */
diff --git a/source/blender/modifiers/intern/MOD_laplaciansmooth.c b/source/blender/modifiers/intern/MOD_laplaciansmooth.c
index 1abe1e97a23..3843ee6f535 100644
--- a/source/blender/modifiers/intern/MOD_laplaciansmooth.c
+++ b/source/blender/modifiers/intern/MOD_laplaciansmooth.c
@@ -366,7 +366,7 @@ static void init_laplacian_matrix(LaplacianSystem *sys)
v1 = sys->vertexCos[idv1];
v2 = sys->vertexCos[idv2];
v3 = sys->vertexCos[idv3];
- v4 = has_4_vert ? sys->vertexCos[idv4] : 0;
+ v4 = has_4_vert ? sys->vertexCos[idv4] : NULL;
if (has_4_vert) {
areaf = area_quad_v3(v1, v2, v3, sys->vertexCos[sys->mfaces[i].v4]);
diff --git a/source/blender/modifiers/intern/MOD_mirror.c b/source/blender/modifiers/intern/MOD_mirror.c
index d50e69217f6..1b9fcd9f34e 100644
--- a/source/blender/modifiers/intern/MOD_mirror.c
+++ b/source/blender/modifiers/intern/MOD_mirror.c
@@ -37,7 +37,6 @@
#include "DNA_object_types.h"
#include "BLI_math.h"
-#include "BLI_array.h"
#include "BKE_cdderivedmesh.h"
#include "BKE_mesh.h"
diff --git a/source/blender/modifiers/intern/MOD_ocean.c b/source/blender/modifiers/intern/MOD_ocean.c
index 7c9a88622ed..40a4d5e0986 100644
--- a/source/blender/modifiers/intern/MOD_ocean.c
+++ b/source/blender/modifiers/intern/MOD_ocean.c
@@ -318,8 +318,8 @@ static DerivedMesh *generate_ocean_geometry(OceanModifierData *omd)
/* create vertices */
#pragma omp parallel for private(x, y) if (rx > OMP_MIN_RES)
- for (y = 0; y < res_y + 1; y++) {
- for (x = 0; x < res_x + 1; x++) {
+ for (y = 0; y <= res_y; y++) {
+ for (x = 0; x <= res_x; x++) {
const int i = y * (res_x + 1) + x;
float *co = mverts[i].co;
co[0] = ox + (x * sx);
@@ -426,6 +426,11 @@ static DerivedMesh *doOcean(ModifierData *md, Object *ob,
const float size_co_inv = 1.0f / (omd->size * omd->spatial_size);
+ /* can happen in when size is small, avoid bad array lookups later and quit now */
+ if (!finite(size_co_inv)) {
+ return derivedData;
+ }
+
/* update modifier */
if (omd->refresh & MOD_OCEAN_REFRESH_ADD)
omd->ocean = BKE_add_ocean();
@@ -531,7 +536,7 @@ static DerivedMesh *doOcean(ModifierData *md, Object *ob,
}
}
- #undef OCEAN_CO
+#undef OCEAN_CO
return dm;
}
@@ -552,8 +557,6 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob,
{
DerivedMesh *result;
- CDDM_calc_normals(derivedData);
-
result = doOcean(md, ob, derivedData, 0);
if (result != derivedData)
diff --git a/source/blender/modifiers/intern/MOD_simpledeform.c b/source/blender/modifiers/intern/MOD_simpledeform.c
index 588c98c9827..d260312fe3d 100644
--- a/source/blender/modifiers/intern/MOD_simpledeform.c
+++ b/source/blender/modifiers/intern/MOD_simpledeform.c
@@ -166,14 +166,7 @@ static void SimpleDeformModifier_do(SimpleDeformModifierData *smd, struct Object
/* Calculate matrixs do convert between coordinate spaces */
if (smd->origin) {
transf = &tmp_transf;
-
- if (smd->originOpts & MOD_SIMPLEDEFORM_ORIGIN_LOCAL) {
- space_transform_from_matrixs(transf, ob->obmat, smd->origin->obmat);
- }
- else {
- copy_m4_m4(transf->local2target, smd->origin->obmat);
- invert_m4_m4(transf->target2local, transf->local2target);
- }
+ space_transform_from_matrixs(transf, ob->obmat, smd->origin->obmat);
}
/* Setup vars,
@@ -252,7 +245,6 @@ static void initData(ModifierData *md)
SimpleDeformModifierData *smd = (SimpleDeformModifierData *) md;
smd->mode = MOD_SIMPLEDEFORM_MODE_TWIST;
- smd->originOpts = MOD_SIMPLEDEFORM_ORIGIN_LOCAL;
smd->axis = 0;
smd->origin = NULL;
@@ -269,9 +261,8 @@ static void copyData(ModifierData *md, ModifierData *target)
tsmd->mode = smd->mode;
tsmd->axis = smd->axis;
tsmd->origin = smd->origin;
- tsmd->originOpts = smd->originOpts;
tsmd->factor = smd->factor;
- memcpy(tsmd->limit, smd->limit, sizeof(tsmd->limit));
+ copy_v2_v2(tsmd->limit, smd->limit);
BLI_strncpy(tsmd->vgroup_name, smd->vgroup_name, sizeof(tsmd->vgroup_name));
}
diff --git a/source/blender/modifiers/intern/MOD_skin.c b/source/blender/modifiers/intern/MOD_skin.c
index daf0e5c9dc3..83ac9f34df3 100644
--- a/source/blender/modifiers/intern/MOD_skin.c
+++ b/source/blender/modifiers/intern/MOD_skin.c
@@ -411,7 +411,7 @@ static Frame **collect_hull_frames(int v, SkinNode *frames,
int nbr, i;
(*tothullframe) = emap[v].count;
- hull_frames = MEM_callocN(sizeof(Frame * *) * (*tothullframe),
+ hull_frames = MEM_callocN(sizeof(Frame *) * (*tothullframe),
"hull_from_frames.hull_frames");
i = 0;
for (nbr = 0; nbr < emap[v].count; nbr++) {
@@ -690,7 +690,7 @@ static void build_emats_stack(BLI_Stack *stack, int *visited_e, EMat *emat,
/* Add neighbors to stack */
for (i = 0; i < emap[v].count; i++) {
/* Add neighbors to stack */
- memcpy(stack_elem.mat, emat[e].mat, sizeof(float) * 3 * 3);
+ copy_m3_m3(stack_elem.mat, emat[e].mat);
stack_elem.e = emap[v].indices[i];
stack_elem.parent_v = v;
BLI_stack_push(stack, &stack_elem);
@@ -1039,7 +1039,7 @@ static int isect_ray_poly(const float ray_start[3],
v_first = v;
else if (v_prev != v_first) {
float dist;
- int curhit;
+ bool curhit;
curhit = isect_ray_tri_v3(ray_start, ray_dir,
v_first->co, v_prev->co, v->co,
@@ -1751,7 +1751,7 @@ static void skin_set_orig_indices(DerivedMesh *dm)
totpoly = dm->getNumPolys(dm);
orig = CustomData_add_layer(&dm->polyData, CD_ORIGINDEX,
- CD_CALLOC, 0, totpoly);
+ CD_CALLOC, NULL, totpoly);
for (i = 0; i < totpoly; i++)
orig[i] = ORIGINDEX_NONE;
}
diff --git a/source/blender/modifiers/intern/MOD_warp.c b/source/blender/modifiers/intern/MOD_warp.c
index 3429acdcea4..4fac201377a 100644
--- a/source/blender/modifiers/intern/MOD_warp.c
+++ b/source/blender/modifiers/intern/MOD_warp.c
@@ -368,8 +368,8 @@ ModifierTypeInfo modifierType_Warp = {
/* deformMatrices */ NULL,
/* deformVertsEM */ deformVertsEM,
/* deformMatricesEM */ NULL,
- /* applyModifier */ 0,
- /* applyModifierEM */ 0,
+ /* applyModifier */ NULL,
+ /* applyModifierEM */ NULL,
/* initData */ initData,
/* requiredDataMask */ requiredDataMask,
/* freeData */ freeData,
diff --git a/source/blender/modifiers/intern/MOD_weightvg_util.c b/source/blender/modifiers/intern/MOD_weightvg_util.c
index 8ad9e26f788..e2267addd53 100644
--- a/source/blender/modifiers/intern/MOD_weightvg_util.c
+++ b/source/blender/modifiers/intern/MOD_weightvg_util.c
@@ -135,6 +135,7 @@ void weightvg_do_mask(int num, const int *indices, float *org_w, const float *ne
/* See mapping note below... */
MappingInfoModifierData t_map;
float (*v_co)[3];
+ int numVerts = dm->getNumVerts(dm);
/* Use new generic get_texture_coords, but do not modify our DNA struct for it...
* XXX Why use a ModifierData stuff here ? Why not a simple, generic struct for parameters ?
@@ -145,9 +146,9 @@ void weightvg_do_mask(int num, const int *indices, float *org_w, const float *ne
t_map.map_object = tex_map_object;
BLI_strncpy(t_map.uvlayer_name, tex_uvlayer_name, sizeof(t_map.uvlayer_name));
t_map.texmapping = tex_mapping;
- v_co = MEM_mallocN(sizeof(*v_co) * num, "WeightVG Modifier, TEX mode, v_co");
+ v_co = MEM_mallocN(sizeof(*v_co) * numVerts, "WeightVG Modifier, TEX mode, v_co");
dm->getVertCos(dm, v_co);
- tex_co = MEM_callocN(sizeof(*tex_co) * num, "WeightVG Modifier, TEX mode, tex_co");
+ tex_co = MEM_callocN(sizeof(*tex_co) * numVerts, "WeightVG Modifier, TEX mode, tex_co");
get_texture_coords(&t_map, ob, dm, v_co, tex_co, num);
MEM_freeN(v_co);
diff --git a/source/blender/modifiers/intern/MOD_weightvgedit.c b/source/blender/modifiers/intern/MOD_weightvgedit.c
index 959e4d4f59d..c8da0eb6de7 100644
--- a/source/blender/modifiers/intern/MOD_weightvgedit.c
+++ b/source/blender/modifiers/intern/MOD_weightvgedit.c
@@ -253,7 +253,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, DerivedMesh *der
RNG *rng = NULL;
if (wmd->falloff_type == MOD_WVG_MAPPING_RANDOM)
- rng = BLI_rng_new_srandom(BLI_ghashutil_strhash(ob->id.name));
+ rng = BLI_rng_new_srandom(BLI_ghashutil_strhash(ob->id.name + 2));
weightvg_do_map(numVerts, new_w, wmd->falloff_type, wmd->cmap_curve, rng);
diff --git a/source/blender/modifiers/intern/MOD_weightvgproximity.c b/source/blender/modifiers/intern/MOD_weightvgproximity.c
index f0e9a26f10a..63267538528 100644
--- a/source/blender/modifiers/intern/MOD_weightvgproximity.c
+++ b/source/blender/modifiers/intern/MOD_weightvgproximity.c
@@ -216,7 +216,7 @@ static void do_map(Object *ob, float *weights, const int nidx, const float min_d
RNG *rng = NULL;
if (mode == MOD_WVG_MAPPING_RANDOM)
- rng = BLI_rng_new_srandom(BLI_ghashutil_strhash(ob->id.name));
+ rng = BLI_rng_new_srandom(BLI_ghashutil_strhash(ob->id.name + 2));
weightvg_do_map(nidx, weights, mode, NULL, rng);
diff --git a/source/blender/nodes/CMakeLists.txt b/source/blender/nodes/CMakeLists.txt
index cc1a5f8cee9..64261246e3d 100644
--- a/source/blender/nodes/CMakeLists.txt
+++ b/source/blender/nodes/CMakeLists.txt
@@ -140,13 +140,16 @@ set(SRC
shader/nodes/node_shader_output.c
shader/nodes/node_shader_rgb.c
shader/nodes/node_shader_sepcombRGB.c
+ shader/nodes/node_shader_sepcombHSV.c
shader/nodes/node_shader_squeeze.c
shader/nodes/node_shader_texture.c
shader/nodes/node_shader_valToRgb.c
shader/nodes/node_shader_value.c
shader/nodes/node_shader_wireframe.c
shader/nodes/node_shader_wavelength.c
+ shader/nodes/node_shader_blackbody.c
shader/nodes/node_shader_vectMath.c
+ shader/nodes/node_shader_vectTransform.c
shader/nodes/node_shader_add_shader.c
shader/nodes/node_shader_ambient_occlusion.c
shader/nodes/node_shader_attribute.c
diff --git a/source/blender/nodes/NOD_shader.h b/source/blender/nodes/NOD_shader.h
index edb0ba6f475..ec39d81618d 100644
--- a/source/blender/nodes/NOD_shader.h
+++ b/source/blender/nodes/NOD_shader.h
@@ -70,6 +70,8 @@ void register_node_type_sh_material_ext(void);
void register_node_type_sh_invert(void);
void register_node_type_sh_seprgb(void);
void register_node_type_sh_combrgb(void);
+void register_node_type_sh_sephsv(void);
+void register_node_type_sh_combhsv(void);
void register_node_type_sh_hue_sat(void);
void register_node_type_sh_tex_brick(void);
@@ -81,6 +83,7 @@ void register_node_type_sh_object_info(void);
void register_node_type_sh_fresnel(void);
void register_node_type_sh_wireframe(void);
void register_node_type_sh_wavelength(void);
+void register_node_type_sh_blackbody(void);
void register_node_type_sh_layer_weight(void);
void register_node_type_sh_tex_coord(void);
void register_node_type_sh_particle_info(void);
@@ -88,6 +91,7 @@ void register_node_type_sh_hair_info(void);
void register_node_type_sh_script(void);
void register_node_type_sh_normal_map(void);
void register_node_type_sh_tangent(void);
+void register_node_type_sh_vect_transform(void);
void register_node_type_sh_ambient_occlusion(void);
void register_node_type_sh_background(void);
diff --git a/source/blender/nodes/NOD_static_types.h b/source/blender/nodes/NOD_static_types.h
index 69f2a0ae955..0b526fcde0e 100644
--- a/source/blender/nodes/NOD_static_types.h
+++ b/source/blender/nodes/NOD_static_types.h
@@ -97,6 +97,7 @@ DefNode( ShaderNode, SH_NODE_PARTICLE_INFO, 0, "PA
DefNode( ShaderNode, SH_NODE_HAIR_INFO, 0, "HAIR_INFO", HairInfo, "Hair Info", "" )
DefNode( ShaderNode, SH_NODE_WIREFRAME, def_sh_tex_wireframe, "WIREFRAME", Wireframe, "Wireframe", "" )
DefNode( ShaderNode, SH_NODE_WAVELENGTH, 0, "WAVELENGTH", Wavelength, "Wavelength", "" )
+DefNode( ShaderNode, SH_NODE_BLACKBODY, 0, "BLACKBODY", Blackbody, "Blackbody", "" )
DefNode( ShaderNode, SH_NODE_BUMP, def_sh_bump, "BUMP", Bump, "Bump", "" )
DefNode( ShaderNode, SH_NODE_NORMAL_MAP, def_sh_normal_map, "NORMAL_MAP", NormalMap, "Normal Map", "" )
DefNode( ShaderNode, SH_NODE_TANGENT, def_sh_tangent, "TANGENT", Tangent, "Tangent", "" )
@@ -113,6 +114,9 @@ DefNode( ShaderNode, SH_NODE_TEX_VORONOI, def_sh_tex_voronoi, "TE
DefNode( ShaderNode, SH_NODE_TEX_CHECKER, def_sh_tex_checker, "TEX_CHECKER", TexChecker, "Checker Texture", "" )
DefNode( ShaderNode, SH_NODE_TEX_BRICK, def_sh_tex_brick, "TEX_BRICK", TexBrick, "Brick Texture", "" )
DefNode( ShaderNode, SH_NODE_TEX_COORD, def_sh_tex_coord, "TEX_COORD", TexCoord, "Texture Coordinate","" )
+DefNode( ShaderNode, SH_NODE_VECT_TRANSFORM, def_sh_vect_transform, "VECT_TRANSFORM", VectorTransform, "Vector Transform", "" )
+DefNode( ShaderNode, SH_NODE_SEPHSV, 0, "SEPHSV", SeparateHSV, "Separate HSV", "" )
+DefNode( ShaderNode, SH_NODE_COMBHSV, 0, "COMBHSV", CombineHSV, "Combine HSV", "" )
DefNode( CompositorNode, CMP_NODE_VIEWER, def_cmp_viewer, "VIEWER", Viewer, "Viewer", "" )
DefNode( CompositorNode, CMP_NODE_RGB, 0, "RGB", RGB, "RGB", "" )
diff --git a/source/blender/nodes/composite/nodes/node_composite_image.c b/source/blender/nodes/composite/nodes/node_composite_image.c
index 41f1f81e048..d073abf112a 100644
--- a/source/blender/nodes/composite/nodes/node_composite_image.c
+++ b/source/blender/nodes/composite/nodes/node_composite_image.c
@@ -72,6 +72,9 @@ static bNodeSocketTemplate cmp_node_rlayers_out[] = {
{ SOCK_RGBA, 0, N_("Transmission Direct"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
{ SOCK_RGBA, 0, N_("Transmission Indirect"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
{ SOCK_RGBA, 0, N_("Transmission Color"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
+ { SOCK_RGBA, 0, N_("Subsurface Direct"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
+ { SOCK_RGBA, 0, N_("Subsurface Indirect"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
+ { SOCK_RGBA, 0, N_("Subsurface Color"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
{ -1, 0, "" }
};
@@ -152,6 +155,13 @@ static void cmp_node_image_add_render_pass_outputs(bNodeTree *ntree, bNode *node
cmp_node_image_add_render_pass_output(ntree, node, SCE_PASS_TRANSM_INDIRECT, RRES_OUT_TRANSM_INDIRECT);
if (passflag & SCE_PASS_TRANSM_COLOR)
cmp_node_image_add_render_pass_output(ntree, node, SCE_PASS_TRANSM_COLOR, RRES_OUT_TRANSM_COLOR);
+
+ if (passflag & SCE_PASS_SUBSURFACE_DIRECT)
+ cmp_node_image_add_render_pass_output(ntree, node, SCE_PASS_SUBSURFACE_DIRECT, RRES_OUT_SUBSURFACE_DIRECT);
+ if (passflag & SCE_PASS_SUBSURFACE_INDIRECT)
+ cmp_node_image_add_render_pass_output(ntree, node, SCE_PASS_SUBSURFACE_INDIRECT, RRES_OUT_SUBSURFACE_INDIRECT);
+ if (passflag & SCE_PASS_SUBSURFACE_COLOR)
+ cmp_node_image_add_render_pass_output(ntree, node, SCE_PASS_SUBSURFACE_COLOR, RRES_OUT_SUBSURFACE_COLOR);
}
static void cmp_node_image_add_multilayer_outputs(bNodeTree *ntree, bNode *node, RenderLayer *rl)
@@ -373,7 +383,8 @@ void node_cmp_rlayers_force_hidden_passes(bNode *node)
bNodeSocket *sock;
/* must always have valid scene pointer */
- BLI_assert(scene != NULL);
+ if (!scene)
+ return;
srl = BLI_findlink(&scene->r.layers, node->custom1);
if (!srl)
@@ -384,35 +395,38 @@ void node_cmp_rlayers_force_hidden_passes(bNode *node)
for (sock = node->outputs.first; sock; sock = sock->next)
sock->flag &= ~SOCK_UNAVAIL;
- set_output_visible(node, passflag, RRES_OUT_IMAGE, SCE_PASS_COMBINED);
- set_output_visible(node, passflag, RRES_OUT_ALPHA, SCE_PASS_COMBINED);
-
- set_output_visible(node, passflag, RRES_OUT_Z, SCE_PASS_Z);
- set_output_visible(node, passflag, RRES_OUT_NORMAL, SCE_PASS_NORMAL);
- set_output_visible(node, passflag, RRES_OUT_VEC, SCE_PASS_VECTOR);
- set_output_visible(node, passflag, RRES_OUT_UV, SCE_PASS_UV);
- set_output_visible(node, passflag, RRES_OUT_RGBA, SCE_PASS_RGBA);
- set_output_visible(node, passflag, RRES_OUT_DIFF, SCE_PASS_DIFFUSE);
- set_output_visible(node, passflag, RRES_OUT_SPEC, SCE_PASS_SPEC);
- set_output_visible(node, passflag, RRES_OUT_SHADOW, SCE_PASS_SHADOW);
- set_output_visible(node, passflag, RRES_OUT_AO, SCE_PASS_AO);
- set_output_visible(node, passflag, RRES_OUT_REFLECT, SCE_PASS_REFLECT);
- set_output_visible(node, passflag, RRES_OUT_REFRACT, SCE_PASS_REFRACT);
- set_output_visible(node, passflag, RRES_OUT_INDIRECT, SCE_PASS_INDIRECT);
- set_output_visible(node, passflag, RRES_OUT_INDEXOB, SCE_PASS_INDEXOB);
- set_output_visible(node, passflag, RRES_OUT_INDEXMA, SCE_PASS_INDEXMA);
- set_output_visible(node, passflag, RRES_OUT_MIST, SCE_PASS_MIST);
- set_output_visible(node, passflag, RRES_OUT_EMIT, SCE_PASS_EMIT);
- set_output_visible(node, passflag, RRES_OUT_ENV, SCE_PASS_ENVIRONMENT);
- set_output_visible(node, passflag, RRES_OUT_DIFF_DIRECT, SCE_PASS_DIFFUSE_DIRECT);
- set_output_visible(node, passflag, RRES_OUT_DIFF_INDIRECT, SCE_PASS_DIFFUSE_INDIRECT);
- set_output_visible(node, passflag, RRES_OUT_DIFF_COLOR, SCE_PASS_DIFFUSE_COLOR);
- set_output_visible(node, passflag, RRES_OUT_GLOSSY_DIRECT, SCE_PASS_GLOSSY_DIRECT);
- set_output_visible(node, passflag, RRES_OUT_GLOSSY_INDIRECT, SCE_PASS_GLOSSY_INDIRECT);
- set_output_visible(node, passflag, RRES_OUT_GLOSSY_COLOR, SCE_PASS_GLOSSY_COLOR);
- set_output_visible(node, passflag, RRES_OUT_TRANSM_DIRECT, SCE_PASS_TRANSM_DIRECT);
- set_output_visible(node, passflag, RRES_OUT_TRANSM_INDIRECT, SCE_PASS_TRANSM_INDIRECT);
- set_output_visible(node, passflag, RRES_OUT_TRANSM_COLOR, SCE_PASS_TRANSM_COLOR);
+ set_output_visible(node, passflag, RRES_OUT_IMAGE, SCE_PASS_COMBINED);
+ set_output_visible(node, passflag, RRES_OUT_ALPHA, SCE_PASS_COMBINED);
+
+ set_output_visible(node, passflag, RRES_OUT_Z, SCE_PASS_Z);
+ set_output_visible(node, passflag, RRES_OUT_NORMAL, SCE_PASS_NORMAL);
+ set_output_visible(node, passflag, RRES_OUT_VEC, SCE_PASS_VECTOR);
+ set_output_visible(node, passflag, RRES_OUT_UV, SCE_PASS_UV);
+ set_output_visible(node, passflag, RRES_OUT_RGBA, SCE_PASS_RGBA);
+ set_output_visible(node, passflag, RRES_OUT_DIFF, SCE_PASS_DIFFUSE);
+ set_output_visible(node, passflag, RRES_OUT_SPEC, SCE_PASS_SPEC);
+ set_output_visible(node, passflag, RRES_OUT_SHADOW, SCE_PASS_SHADOW);
+ set_output_visible(node, passflag, RRES_OUT_AO, SCE_PASS_AO);
+ set_output_visible(node, passflag, RRES_OUT_REFLECT, SCE_PASS_REFLECT);
+ set_output_visible(node, passflag, RRES_OUT_REFRACT, SCE_PASS_REFRACT);
+ set_output_visible(node, passflag, RRES_OUT_INDIRECT, SCE_PASS_INDIRECT);
+ set_output_visible(node, passflag, RRES_OUT_INDEXOB, SCE_PASS_INDEXOB);
+ set_output_visible(node, passflag, RRES_OUT_INDEXMA, SCE_PASS_INDEXMA);
+ set_output_visible(node, passflag, RRES_OUT_MIST, SCE_PASS_MIST);
+ set_output_visible(node, passflag, RRES_OUT_EMIT, SCE_PASS_EMIT);
+ set_output_visible(node, passflag, RRES_OUT_ENV, SCE_PASS_ENVIRONMENT);
+ set_output_visible(node, passflag, RRES_OUT_DIFF_DIRECT, SCE_PASS_DIFFUSE_DIRECT);
+ set_output_visible(node, passflag, RRES_OUT_DIFF_INDIRECT, SCE_PASS_DIFFUSE_INDIRECT);
+ set_output_visible(node, passflag, RRES_OUT_DIFF_COLOR, SCE_PASS_DIFFUSE_COLOR);
+ set_output_visible(node, passflag, RRES_OUT_GLOSSY_DIRECT, SCE_PASS_GLOSSY_DIRECT);
+ set_output_visible(node, passflag, RRES_OUT_GLOSSY_INDIRECT, SCE_PASS_GLOSSY_INDIRECT);
+ set_output_visible(node, passflag, RRES_OUT_GLOSSY_COLOR, SCE_PASS_GLOSSY_COLOR);
+ set_output_visible(node, passflag, RRES_OUT_TRANSM_DIRECT, SCE_PASS_TRANSM_DIRECT);
+ set_output_visible(node, passflag, RRES_OUT_TRANSM_INDIRECT, SCE_PASS_TRANSM_INDIRECT);
+ set_output_visible(node, passflag, RRES_OUT_TRANSM_COLOR, SCE_PASS_TRANSM_COLOR);
+ set_output_visible(node, passflag, RRES_OUT_SUBSURFACE_DIRECT, SCE_PASS_SUBSURFACE_DIRECT);
+ set_output_visible(node, passflag, RRES_OUT_SUBSURFACE_INDIRECT, SCE_PASS_SUBSURFACE_INDIRECT);
+ set_output_visible(node, passflag, RRES_OUT_SUBSURFACE_COLOR, SCE_PASS_SUBSURFACE_COLOR);
}
static void node_composit_init_rlayers(const bContext *C, PointerRNA *ptr)
diff --git a/source/blender/nodes/intern/node_common.c b/source/blender/nodes/intern/node_common.c
index 36b27094cc4..a8133460628 100644
--- a/source/blender/nodes/intern/node_common.c
+++ b/source/blender/nodes/intern/node_common.c
@@ -267,6 +267,7 @@ static void node_reroute_inherit_type_recursive(bNodeTree *ntree, bNode *node)
bNodeSocket *output = node->outputs.first;
bNodeLink *link;
int type = SOCK_FLOAT;
+ const char *type_idname = nodeStaticSocketType(type, PROP_NONE);
/* XXX it would be a little bit more efficient to restrict actual updates
* to rerout nodes connected to an updated node, but there's no reliable flag
@@ -292,21 +293,37 @@ static void node_reroute_inherit_type_recursive(bNodeTree *ntree, bNode *node)
}
/* determine socket type from unambiguous input/output connection if possible */
- if (input->limit == 1 && input->link)
+ if (input->limit == 1 && input->link) {
type = input->link->fromsock->type;
- else if (output->limit == 1 && output->link)
+ type_idname = nodeStaticSocketType(type, PROP_NONE);
+ }
+ else if (output->limit == 1 && output->link) {
type = output->link->tosock->type;
+ type_idname = nodeStaticSocketType(type, PROP_NONE);
+ }
- /* arbitrary, could also test output->type, both are the same */
if (input->type != type) {
- PointerRNA input_ptr, output_ptr;
- /* same type for input/output */
- RNA_pointer_create((ID *)ntree, &RNA_NodeSocket, input, &input_ptr);
- RNA_pointer_create((ID *)ntree, &RNA_NodeSocket, output, &output_ptr);
-
- RNA_enum_set(&input_ptr, "type", type);
- RNA_enum_set(&output_ptr, "type", type);
+ bNodeSocket *ninput = nodeAddSocket(ntree, node, SOCK_IN, type_idname, "input", "Input");
+ for (link = ntree->links.first; link; link = link->next) {
+ if (link->tosock == input) {
+ link->tosock = ninput;
+ ninput->link = link;
+ }
+ }
+ nodeRemoveSocket(ntree, node, input);
}
+
+ if (output->type != type) {
+ bNodeSocket *noutput = nodeAddSocket(ntree, node, SOCK_OUT, type_idname, "output", "Output");
+ for (link = ntree->links.first; link; link = link->next) {
+ if (link->fromsock == output) {
+ link->fromsock = noutput;
+ }
+ }
+ nodeRemoveSocket(ntree, node, output);
+ }
+
+ nodeUpdateInternalLinks(ntree, node);
}
/* Global update function for Reroute node types.
diff --git a/source/blender/nodes/intern/node_exec.c b/source/blender/nodes/intern/node_exec.c
index d18dddd4ff4..2b6318679e0 100644
--- a/source/blender/nodes/intern/node_exec.c
+++ b/source/blender/nodes/intern/node_exec.c
@@ -98,6 +98,10 @@ static void node_init_output_index(bNodeSocket *sock, int *index, ListBase *inte
for (link = internal_links->first; link; link = link->next) {
if (link->tosock == sock) {
sock->stack_index = link->fromsock->stack_index;
+ /* set the link pointer to indicate that this socket
+ * should not overwrite the stack value!
+ */
+ sock->link = link;
break;
}
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_blackbody.c b/source/blender/nodes/shader/nodes/node_shader_blackbody.c
new file mode 100644
index 00000000000..af89a959554
--- /dev/null
+++ b/source/blender/nodes/shader/nodes/node_shader_blackbody.c
@@ -0,0 +1,54 @@
+/*
+ * ***** 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): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#include "../node_shader_util.h"
+
+/* **************** Blackbody ******************** */
+static bNodeSocketTemplate sh_node_blackbody_in[] = {
+ { SOCK_FLOAT, 1, N_("Temperature"), 1500.0f, 0.0f, 0.0f, 0.0f, 800.0f, 12000.0f},
+ { -1, 0, "" }
+};
+
+static bNodeSocketTemplate sh_node_blackbody_out[] = {
+ { SOCK_RGBA, 0, N_("Color")},
+ { -1, 0, "" }
+};
+
+/* node type definition */
+void register_node_type_sh_blackbody(void)
+{
+ static bNodeType ntype;
+
+ sh_node_type_base(&ntype, SH_NODE_BLACKBODY, "Blackbody", NODE_CLASS_CONVERTOR, 0);
+ node_type_compatibility(&ntype, NODE_NEW_SHADING);
+ node_type_size_preset(&ntype, NODE_SIZE_MIDDLE);
+ node_type_socket_templates(&ntype, sh_node_blackbody_in, sh_node_blackbody_out);
+ node_type_init(&ntype, NULL);
+ node_type_storage(&ntype, "", NULL, NULL);
+
+ nodeRegisterType(&ntype);
+}
diff --git a/source/blender/nodes/shader/nodes/node_shader_light_path.c b/source/blender/nodes/shader/nodes/node_shader_light_path.c
index 63713eb1e02..9d769b284b1 100644
--- a/source/blender/nodes/shader/nodes/node_shader_light_path.c
+++ b/source/blender/nodes/shader/nodes/node_shader_light_path.c
@@ -38,6 +38,7 @@ static bNodeSocketTemplate sh_node_light_path_out[] = {
{ SOCK_FLOAT, 0, N_("Is Reflection Ray"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
{ SOCK_FLOAT, 0, N_("Is Transmission Ray"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
{ SOCK_FLOAT, 0, N_("Ray Length"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
+ { SOCK_FLOAT, 0, N_("Ray Depth"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
{ -1, 0, "" }
};
diff --git a/source/blender/nodes/shader/nodes/node_shader_math.c b/source/blender/nodes/shader/nodes/node_shader_math.c
index b0570a7d673..49a7de47fc3 100644
--- a/source/blender/nodes/shader/nodes/node_shader_math.c
+++ b/source/blender/nodes/shader/nodes/node_shader_math.c
@@ -232,6 +232,7 @@ static int gpu_shader_math(GPUMaterial *mat, bNode *node, bNodeExecData *UNUSED(
case 13:
case 15:
case 16:
+ case 17:
GPU_stack_link(mat, names[node->custom1], in, out);
break;
case 4:
diff --git a/source/blender/nodes/shader/nodes/node_shader_sepcombHSV.c b/source/blender/nodes/shader/nodes/node_shader_sepcombHSV.c
new file mode 100644
index 00000000000..707e295241a
--- /dev/null
+++ b/source/blender/nodes/shader/nodes/node_shader_sepcombHSV.c
@@ -0,0 +1,80 @@
+/*
+ * ***** 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): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/nodes/shader/nodes/node_shader_sepcombHSV.c
+ * \ingroup shdnodes
+ */
+
+
+#include "node_shader_util.h"
+
+/* **************** SEPARATE HSV ******************** */
+static bNodeSocketTemplate sh_node_sephsv_in[] = {
+ { SOCK_RGBA, 1, N_("Color"), 0.8f, 0.8f, 0.8f, 1.0f},
+ { -1, 0, "" }
+};
+static bNodeSocketTemplate sh_node_sephsv_out[] = {
+ { SOCK_FLOAT, 0, N_("H")},
+ { SOCK_FLOAT, 0, N_("S")},
+ { SOCK_FLOAT, 0, N_("V")},
+ { -1, 0, "" }
+};
+
+void register_node_type_sh_sephsv(void)
+{
+ static bNodeType ntype;
+
+ sh_node_type_base(&ntype, SH_NODE_SEPHSV, "Separate HSV", NODE_CLASS_CONVERTOR, 0);
+ node_type_compatibility(&ntype, NODE_NEW_SHADING);
+ node_type_socket_templates(&ntype, sh_node_sephsv_in, sh_node_sephsv_out);
+
+ nodeRegisterType(&ntype);
+}
+
+
+/* **************** COMBINE HSV ******************** */
+static bNodeSocketTemplate sh_node_combhsv_in[] = {
+ { SOCK_FLOAT, 1, N_("H"), 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, PROP_UNSIGNED},
+ { SOCK_FLOAT, 1, N_("S"), 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, PROP_UNSIGNED},
+ { SOCK_FLOAT, 1, N_("V"), 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, PROP_UNSIGNED},
+ { -1, 0, "" }
+};
+static bNodeSocketTemplate sh_node_combhsv_out[] = {
+ { SOCK_RGBA, 0, N_("Color")},
+ { -1, 0, "" }
+};
+
+void register_node_type_sh_combhsv(void)
+{
+ static bNodeType ntype;
+
+ sh_node_type_base(&ntype, SH_NODE_COMBHSV, "Combine HSV", NODE_CLASS_CONVERTOR, 0);
+ node_type_compatibility(&ntype, NODE_NEW_SHADING);
+ node_type_socket_templates(&ntype, sh_node_combhsv_in, sh_node_combhsv_out);
+
+ nodeRegisterType(&ntype);
+}
diff --git a/source/blender/nodes/shader/nodes/node_shader_subsurface_scattering.c b/source/blender/nodes/shader/nodes/node_shader_subsurface_scattering.c
index 6a77b0d3eb1..3bdc3813fd7 100644
--- a/source/blender/nodes/shader/nodes/node_shader_subsurface_scattering.c
+++ b/source/blender/nodes/shader/nodes/node_shader_subsurface_scattering.c
@@ -31,7 +31,7 @@
static bNodeSocketTemplate sh_node_subsurface_scattering_in[] = {
{ SOCK_RGBA, 1, N_("Color"), 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f},
- { SOCK_FLOAT, 1, N_("Scale"), 1.0, 0.0f, 0.0f, 0.0f, 0.0f, 1000000.0f},
+ { SOCK_FLOAT, 1, N_("Scale"), 1.0, 0.0f, 0.0f, 0.0f, 0.0f, 1000.0f},
{ SOCK_VECTOR, 1, N_("Radius"), 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 100.0f},
//{ SOCK_FLOAT, 1, N_("IOR"), 1.3f, 0.0f, 0.0f, 0.0f, 1.0f, 1000.0f},
{ SOCK_VECTOR, 1, N_("Normal"), 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f, PROP_NONE, SOCK_HIDE_VALUE},
diff --git a/source/blender/nodes/shader/nodes/node_shader_vectTransform.c b/source/blender/nodes/shader/nodes/node_shader_vectTransform.c
new file mode 100644
index 00000000000..40c70b9e23d
--- /dev/null
+++ b/source/blender/nodes/shader/nodes/node_shader_vectTransform.c
@@ -0,0 +1,66 @@
+/*
+ * ***** 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): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/nodes/shader/nodes/node_shader_vectTransform.c
+ * \ingroup shdnodes
+ */
+
+ #include "../node_shader_util.h"
+
+/* **************** Vector Transform ******************** */
+static bNodeSocketTemplate sh_node_vect_transform_in[] = {
+ { SOCK_VECTOR, 1, N_("Vector"), 0.5f, 0.5f, 0.5f, 1.0f, -10000.0f, 10000.0f, PROP_NONE},
+ { -1, 0, "" }
+};
+
+static bNodeSocketTemplate sh_node_vect_transform_out[] = {
+ { SOCK_VECTOR, 0, N_("Vector")},
+ { -1, 0, "" }
+};
+
+static void node_shader_init_vect_transform(bNodeTree *UNUSED(ntree), bNode *node)
+{
+ NodeShaderVectTransform *vect = MEM_callocN(sizeof(NodeShaderVectTransform), "NodeShaderVectTransform");
+
+ /* Convert World into Object Space per default */
+ vect->convert_to = 1;
+
+ node->storage = vect;
+}
+
+void register_node_type_sh_vect_transform(void)
+{
+ static bNodeType ntype;
+
+ sh_node_type_base(&ntype, SH_NODE_VECT_TRANSFORM, "Vector Transform", NODE_CLASS_CONVERTOR, 0);
+ node_type_compatibility(&ntype, NODE_NEW_SHADING);
+ node_type_init(&ntype, node_shader_init_vect_transform);
+ node_type_socket_templates(&ntype, sh_node_vect_transform_in, sh_node_vect_transform_out);
+ node_type_storage(&ntype, "NodeShaderVectTransform", node_free_standard_storage, node_copy_standard_storage);
+
+ nodeRegisterType(&ntype);
+}
diff --git a/source/blender/nodes/texture/node_texture_tree.c b/source/blender/nodes/texture/node_texture_tree.c
index 859636ed4e5..5e863da9635 100644
--- a/source/blender/nodes/texture/node_texture_tree.c
+++ b/source/blender/nodes/texture/node_texture_tree.c
@@ -283,10 +283,12 @@ void ntreeTexEndExecTree_internal(bNodeTreeExec *exec)
void ntreeTexEndExecTree(bNodeTreeExec *exec)
{
if (exec) {
+ /* exec may get freed, so assign ntree */
+ bNodeTree *ntree = exec->nodetree;
ntreeTexEndExecTree_internal(exec);
/* XXX clear nodetree backpointer to exec data, same problem as noted in ntreeBeginExecTree */
- exec->nodetree->execdata = NULL;
+ ntree->execdata = NULL;
}
}
diff --git a/source/blender/nodes/texture/nodes/node_texture_output.c b/source/blender/nodes/texture/nodes/node_texture_output.c
index 235cb560a99..37e527f611a 100644
--- a/source/blender/nodes/texture/nodes/node_texture_output.c
+++ b/source/blender/nodes/texture/nodes/node_texture_output.c
@@ -80,12 +80,13 @@ static void exec(void *data, int UNUSED(thread), bNode *node, bNodeExecData *exe
static void unique_name(bNode *node)
{
TexNodeOutput *tno = (TexNodeOutput *)node->storage;
- char *new_name = NULL;
+ char new_name[sizeof(tno->name)];
int new_len = 0;
int suffix;
bNode *i;
char *name = tno->name;
+ new_name[0] = '\0';
i = node;
while (i->prev) i = i->prev;
for (; i; i = i->next) {
@@ -96,7 +97,7 @@ static void unique_name(bNode *node)
continue;
}
- if (!new_name) {
+ if (new_name[0] == '\0') {
int len = strlen(name);
if (len >= 4 && sscanf(name + len - 4, ".%03d", &suffix) == 1) {
new_len = len;
@@ -107,17 +108,15 @@ static void unique_name(bNode *node)
if (new_len > (sizeof(tno->name) - 1))
new_len = (sizeof(tno->name) - 1);
}
-
- new_name = MEM_mallocN(new_len + 1, "new_name");
- strcpy(new_name, name);
+
+ BLI_strncpy(new_name, name, sizeof(tno->name));
name = new_name;
}
sprintf(new_name + new_len - 4, ".%03d", ++suffix);
}
- if (new_name) {
- strcpy(tno->name, new_name);
- MEM_freeN(new_name);
+ if (new_name[0] != '\0') {
+ BLI_strncpy(tno->name, new_name, sizeof(tno->name));
}
}
diff --git a/source/blender/python/bmesh/bmesh_py_ops.c b/source/blender/python/bmesh/bmesh_py_ops.c
index 8826baf81b7..4fc0160bbd6 100644
--- a/source/blender/python/bmesh/bmesh_py_ops.c
+++ b/source/blender/python/bmesh/bmesh_py_ops.c
@@ -50,7 +50,7 @@
/* bmesh operator 'bmesh.ops.*' callable types
* ******************************************* */
-PyTypeObject bmesh_op_Type;
+static PyTypeObject bmesh_op_Type;
static PyObject *bpy_bmesh_op_CreatePyObject(const char *opname)
{
@@ -140,7 +140,7 @@ static PyGetSetDef bpy_bmesh_op_getseters[] = {
/* Types
* ===== */
-PyTypeObject bmesh_op_Type = {
+static PyTypeObject bmesh_op_Type = {
PyVarObject_HEAD_INIT(NULL, 0)
"BMeshOpFunc", /* tp_name */
sizeof(BPy_BMeshOpFunc), /* tp_basicsize */
diff --git a/source/blender/python/bmesh/bmesh_py_types_meshdata.c b/source/blender/python/bmesh/bmesh_py_types_meshdata.c
index b8572baa7f9..06b11f02b2a 100644
--- a/source/blender/python/bmesh/bmesh_py_types_meshdata.c
+++ b/source/blender/python/bmesh/bmesh_py_types_meshdata.c
@@ -310,7 +310,7 @@ static int mathutils_bmloopcol_set_index(BaseMathObject *bmo, int subtype, int i
return mathutils_bmloopcol_set(bmo, subtype);
}
-Mathutils_Callback mathutils_bmloopcol_cb = {
+static Mathutils_Callback mathutils_bmloopcol_cb = {
mathutils_bmloopcol_check,
mathutils_bmloopcol_get,
mathutils_bmloopcol_set,
diff --git a/source/blender/python/bmesh/bmesh_py_utils.c b/source/blender/python/bmesh/bmesh_py_utils.c
index 55c97b66ffb..d228e1a0646 100644
--- a/source/blender/python/bmesh/bmesh_py_utils.c
+++ b/source/blender/python/bmesh/bmesh_py_utils.c
@@ -245,14 +245,10 @@ static PyObject *bpy_bm_utils_vert_separate(PyObject *UNUSED(self), PyObject *ar
return NULL;
}
- if (BM_vert_separate(bm, py_vert->v, &elem, &elem_len, edge_array, edge_array_len)) {
- /* return collected verts */
- ret = BPy_BMElem_Array_As_Tuple(bm, (BMHeader **)elem, elem_len);
- MEM_freeN(elem);
- }
- else {
- ret = PyTuple_New(0);
- }
+ BM_vert_separate(bm, py_vert->v, &elem, &elem_len, edge_array, edge_array_len);
+ /* return collected verts */
+ ret = BPy_BMElem_Array_As_Tuple(bm, (BMHeader **)elem, elem_len);
+ MEM_freeN(elem);
PyMem_FREE(edge_array);
diff --git a/source/blender/python/intern/bpy_rna.c b/source/blender/python/intern/bpy_rna.c
index 9f7c589630a..3cd030e9b08 100644
--- a/source/blender/python/intern/bpy_rna.c
+++ b/source/blender/python/intern/bpy_rna.c
@@ -5948,7 +5948,7 @@ PyTypeObject pyrna_func_Type = {
static void pyrna_prop_collection_iter_dealloc(BPy_PropertyCollectionIterRNA *self);
static PyObject *pyrna_prop_collection_iter_next(BPy_PropertyCollectionIterRNA *self);
-PyTypeObject pyrna_prop_collection_iter_Type = {
+static PyTypeObject pyrna_prop_collection_iter_Type = {
PyVarObject_HEAD_INIT(NULL, 0)
"bpy_prop_collection_iter", /* tp_name */
sizeof(BPy_PropertyCollectionIterRNA), /* tp_basicsize */
diff --git a/source/blender/quicktime/apple/quicktime_export.c b/source/blender/quicktime/apple/quicktime_export.c
index ce4f3063082..52ef21e4f39 100644
--- a/source/blender/quicktime/apple/quicktime_export.c
+++ b/source/blender/quicktime/apple/quicktime_export.c
@@ -768,7 +768,7 @@ int get_qtcodec_settings(RenderData *rd, ReportList *reports)
return err;
}
-static int request_qtcodec_settings(bContext *C, wmOperator *op)
+static int request_qtcodec_settings_exec(bContext *C, wmOperator *op)
{
OSErr err = noErr;
Scene *scene = CTX_data_scene(C);
@@ -893,11 +893,11 @@ static int ED_operator_setqtcodec(bContext *C)
#if defined(__APPLE__) && defined(GHOST_COCOA)
/* Need to set up a Cocoa NSAutoReleasePool to avoid memory leak
* And it must be done in an objC file, so use a GHOST_SystemCocoa.mm function for that */
-extern int cocoa_request_qtcodec_settings(bContext *C, wmOperator *op);
+extern int cocoa_request_qtcodec_settings_exec(bContext *C, wmOperator *op);
int fromcocoa_request_qtcodec_settings(bContext *C, wmOperator *op)
{
- return request_qtcodec_settings(C, op);
+ return request_qtcodec_settings_exec(C, op);
}
#endif
@@ -911,9 +911,9 @@ void SCENE_OT_render_data_set_quicktime_codec(wmOperatorType *ot)
/* api callbacks */
#if defined(__APPLE__) && defined(GHOST_COCOA)
- ot->exec = cocoa_request_qtcodec_settings;
+ ot->exec = cocoa_request_qtcodec_settings_exec;
#else
- ot->exec = request_qtcodec_settings;
+ ot->exec = request_qtcodec_settings_exec;
#endif
ot->poll = ED_operator_setqtcodec;
diff --git a/source/blender/render/intern/include/zbuf.h b/source/blender/render/intern/include/zbuf.h
index ca9897b652c..ec30c3241ab 100644
--- a/source/blender/render/intern/include/zbuf.h
+++ b/source/blender/render/intern/include/zbuf.h
@@ -120,8 +120,9 @@ typedef struct ZSpan {
} ZSpan;
/* exported to shadbuf.c */
-void zbufclip4(struct ZSpan *zspan, int obi, int zvlnr, float *f1, float *f2, float *f3, float *f4,
- int c1, int c2, int c3, int c4);
+void zbufclip4(struct ZSpan *zspan, int obi, int zvlnr,
+ const float f1[4], const float f2[4], const float f3[4], const float f4[4],
+ const int c1, const int c2, const int c3, const int c4);
void zbuf_free_span(struct ZSpan *zspan);
void freepsA(struct ListBase *lb);
@@ -130,10 +131,13 @@ void zspan_scanconvert(struct ZSpan *zpan, void *handle, float *v1, float *v2, f
void (*func)(void *, int, int, float, float) );
/* exported to edge render... */
-void zbufclip(struct ZSpan *zspan, int obi, int zvlnr, float *f1, float *f2, float *f3, int c1, int c2, int c3);
+void zbufclip(struct ZSpan *zspan, int obi, int zvlnr,
+ const float f1[4], const float f2[4], const float f3[4],
+ const int c1, const int c2, const int c3);
void zbuf_alloc_span(struct ZSpan *zspan, int rectx, int recty, float clipcrop);
void zbufclipwire(struct ZSpan *zspan, int obi, int zvlnr, int ec,
- float *ho1, float *ho2, float *ho3, float *ho4, int c1, int c2, int c3, int c4);
+ const float ho1[4], const float ho2[4], const float ho3[4], const float ho4[4],
+ const int c1, const int c2, const int c3, const int c4);
/* exported to shadeinput.c */
void zbuf_make_winmat(Render *re, float winmat[4][4]);
diff --git a/source/blender/render/intern/raytrace/rayobject_octree.cpp b/source/blender/render/intern/raytrace/rayobject_octree.cpp
index e4fd5a6d41e..2f668ba62d0 100644
--- a/source/blender/render/intern/raytrace/rayobject_octree.cpp
+++ b/source/blender/render/intern/raytrace/rayobject_octree.cpp
@@ -521,7 +521,7 @@ static void octree_fill_rayface(Octree *oc, RayFace *face)
copy_v3_v3(co1, face->v1);
copy_v3_v3(co2, face->v2);
copy_v3_v3(co3, face->v3);
- if (face->v4)
+ if (RE_rayface_isQuad(face))
copy_v3_v3(co4, face->v4);
for (c = 0; c < 3; c++) {
diff --git a/source/blender/render/intern/source/bake.c b/source/blender/render/intern/source/bake.c
index a15d24ebe42..564cca09834 100644
--- a/source/blender/render/intern/source/bake.c
+++ b/source/blender/render/intern/source/bake.c
@@ -577,7 +577,7 @@ static void do_bake_shade(void *handle, int x, int y, float u, float v)
if (bs->type == RE_BAKE_NORMALS && R.r.bake_normal_space == R_BAKE_SPACE_TANGENT)
bake_shade(handle, ob, shi, quad, x, y, u, v, tvn, ttang);
else
- bake_shade(handle, ob, shi, quad, x, y, u, v, 0, 0);
+ bake_shade(handle, ob, shi, quad, x, y, u, v, NULL, NULL);
}
static int get_next_bake_face(BakeShade *bs)
diff --git a/source/blender/render/intern/source/convertblender.c b/source/blender/render/intern/source/convertblender.c
index 7d842c1026b..ab888ba198b 100644
--- a/source/blender/render/intern/source/convertblender.c
+++ b/source/blender/render/intern/source/convertblender.c
@@ -726,7 +726,7 @@ static int as_testvertex(VlakRen *vlr, VertRen *UNUSED(ver), ASvert *asv, float
float inp;
int a;
- if (vlr==0) return 0;
+ if (vlr == NULL) return 0;
asf= asv->faces.first;
while (asf) {
@@ -803,7 +803,7 @@ static void autosmooth(Render *UNUSED(re), ObjectRen *obr, float mat[4][4], int
totvert= obr->totvert;
/* we now test all vertices, when faces have a normal too much different: they get a new vertex */
for (a=0, asv=asverts; a<totvert; a++, asv++) {
- if (asv && asv->totface>1) {
+ if (asv->totface > 1) {
ver= RE_findOrAddVert(obr, a);
asf= asv->faces.first;
@@ -1289,7 +1289,7 @@ static void static_particle_wire(ObjectRen *obr, Material *ma, const float vec[3
static void particle_curve(Render *re, ObjectRen *obr, DerivedMesh *dm, Material *ma, ParticleStrandData *sd,
const float loc[3], const float loc1[3], int seed, float *pa_co)
{
- HaloRen *har=0;
+ HaloRen *har = NULL;
if (ma->material_type == MA_TYPE_WIRE)
static_particle_wire(obr, ma, loc, loc1, sd->first, sd->line);
@@ -1466,7 +1466,7 @@ static void particle_normal_ren(short ren_as, ParticleSettings *part, Render *re
default:
{
- HaloRen *har=0;
+ HaloRen *har = NULL;
har = RE_inithalo_particle(re, obr, dm, ma, loc, NULL, sd->orco, sd->uvco, hasize, 0.0, seed, pa_co);
@@ -1516,22 +1516,22 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem
{
Object *ob= obr->ob;
// Object *tob=0;
- Material *ma=0;
+ Material *ma = NULL;
ParticleSystemModifierData *psmd;
- ParticleSystem *tpsys=0;
- ParticleSettings *part, *tpart=0;
- ParticleData *pars, *pa=0, *tpa=0;
- ParticleKey *states=0;
+ ParticleSystem *tpsys = NULL;
+ ParticleSettings *part, *tpart = NULL;
+ ParticleData *pars, *pa = NULL, *tpa = NULL;
+ ParticleKey *states = NULL;
ParticleKey state;
- ParticleCacheKey *cache=0;
+ ParticleCacheKey *cache = NULL;
ParticleBillboardData bb;
- ParticleSimulationData sim = {0};
+ ParticleSimulationData sim = {NULL};
ParticleStrandData sd;
- StrandBuffer *strandbuf=0;
- StrandVert *svert=0;
- StrandBound *sbound= 0;
- StrandRen *strand=0;
- RNG *rng= 0;
+ StrandBuffer *strandbuf = NULL;
+ StrandVert *svert = NULL;
+ StrandBound *sbound = NULL;
+ StrandRen *strand = NULL;
+ RNG *rng = NULL;
float loc[3], loc1[3], loc0[3], mat[4][4], nmat[3][3], co[3], nor[3], duplimat[4][4];
float strandlen=0.0f, curlen=0.0f;
float hasize, pa_size, r_tilt, r_length;
@@ -1542,7 +1542,7 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem
int totchild=0, step_nbr;
int seed, path_nbr=0, orco1=0, num;
int totface;
- char **uv_name=0;
+ char **uv_name = NULL;
const int *index_mf_to_mpoly = NULL;
const int *index_mp_to_orig = NULL;
@@ -1735,7 +1735,7 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem
}
}
- if (sd.orco == 0) {
+ if (sd.orco == NULL) {
sd.orco = MEM_mallocN(3 * sizeof(float), "particle orco");
orco1 = 1;
}
@@ -1760,10 +1760,17 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem
/* get orco */
if (tpsys && part->phystype == PART_PHYS_NO) {
tpa = tpsys->particles + pa->num;
- psys_particle_on_emitter(psmd, tpart->from, tpa->num, pa->num_dmcache, tpa->fuv, tpa->foffset, co, nor, 0, 0, sd.orco, 0);
+ psys_particle_on_emitter(
+ psmd,
+ tpart->from, tpa->num, pa->num_dmcache, tpa->fuv,
+ tpa->foffset, co, nor, NULL, NULL, sd.orco, NULL);
+ }
+ else {
+ psys_particle_on_emitter(
+ psmd,
+ part->from, pa->num, pa->num_dmcache,
+ pa->fuv, pa->foffset, co, nor, NULL, NULL, sd.orco, NULL);
}
- else
- psys_particle_on_emitter(psmd, part->from, pa->num, pa->num_dmcache, pa->fuv, pa->foffset, co, nor, 0, 0, sd.orco, 0);
/* get uvco & mcol */
num= pa->num_dmcache;
@@ -1808,15 +1815,17 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem
/* get orco */
if (part->childtype == PART_CHILD_FACES) {
- psys_particle_on_emitter(psmd,
- PART_FROM_FACE, cpa->num, DMCACHE_ISCHILD,
- cpa->fuv, cpa->foffset, co, nor, 0, 0, sd.orco, 0);
+ psys_particle_on_emitter(
+ psmd,
+ PART_FROM_FACE, cpa->num, DMCACHE_ISCHILD,
+ cpa->fuv, cpa->foffset, co, nor, NULL, NULL, sd.orco, NULL);
}
else {
ParticleData *par = psys->particles + cpa->parent;
- psys_particle_on_emitter(psmd, part->from,
- par->num, DMCACHE_ISCHILD, par->fuv,
- par->foffset, co, nor, 0, 0, sd.orco, 0);
+ psys_particle_on_emitter(
+ psmd,
+ part->from, par->num, DMCACHE_ISCHILD, par->fuv,
+ par->foffset, co, nor, NULL, NULL, sd.orco, NULL);
}
/* get uvco & mcol */
@@ -2419,7 +2428,7 @@ static void init_render_mball(Render *re, ObjectRen *obr)
BKE_displist_make_mball_forRender(re->scene, ob, &dispbase);
dl= dispbase.first;
- if (dl==0) return;
+ if (dl == NULL) return;
data= dl->verts;
nors= dl->nors;
@@ -2464,7 +2473,7 @@ static void init_render_mball(Render *re, ObjectRen *obr)
vlr->v1= RE_findOrAddVert(obr, index[0]);
vlr->v2= RE_findOrAddVert(obr, index[1]);
vlr->v3= RE_findOrAddVert(obr, index[2]);
- vlr->v4= 0;
+ vlr->v4 = NULL;
if (negative_scale)
normal_tri_v3(vlr->n, vlr->v1->co, vlr->v2->co, vlr->v3->co);
@@ -2729,7 +2738,7 @@ static void init_render_dm(DerivedMesh *dm, Render *re, ObjectRen *obr,
vlr->v2= RE_findOrAddVert(obr, vertofs+v2);
vlr->v3= RE_findOrAddVert(obr, vertofs+v3);
if (v4) vlr->v4= RE_findOrAddVert(obr, vertofs+v4);
- else vlr->v4= 0;
+ else vlr->v4 = NULL;
/* render normals are inverted in render */
if (vlr->v4)
@@ -2787,7 +2796,7 @@ static void init_render_dm(DerivedMesh *dm, Render *re, ObjectRen *obr,
static void init_render_surf(Render *re, ObjectRen *obr, int timeoffset)
{
Object *ob= obr->ob;
- Nurb *nu=0;
+ Nurb *nu = NULL;
Curve *cu;
ListBase displist= {NULL, NULL};
DispList *dl;
@@ -2798,7 +2807,7 @@ static void init_render_surf(Render *re, ObjectRen *obr, int timeoffset)
cu= ob->data;
nu= cu->nurb.first;
- if (nu==0) return;
+ if (nu == NULL) return;
mul_m4_m4m4(mat, re->viewmat, ob->obmat);
invert_m4_m4(ob->imat, mat);
@@ -3311,7 +3320,7 @@ static void init_render_mesh(Render *re, ObjectRen *obr, int timeoffset)
DerivedMesh *dm;
CustomDataMask mask;
float xn, yn, zn, imat[3][3], mat[4][4]; //nor[3],
- float *orco=0;
+ float *orco = NULL;
int need_orco=0, need_stress=0, need_nmap_tangent=0, need_tangent=0, need_origindex=0;
int a, a1, ok, vertofs;
int end, do_autosmooth = FALSE, totvert = 0;
@@ -3526,8 +3535,8 @@ static void init_render_mesh(Render *re, ObjectRen *obr, int timeoffset)
vlr->v1= RE_findOrAddVert(obr, vertofs+v1);
vlr->v2= RE_findOrAddVert(obr, vertofs+v2);
vlr->v3= RE_findOrAddVert(obr, vertofs+v3);
- if (v4) vlr->v4= RE_findOrAddVert(obr, vertofs+v4);
- else vlr->v4= 0;
+ if (v4) vlr->v4 = RE_findOrAddVert(obr, vertofs+v4);
+ else vlr->v4 = NULL;
#ifdef WITH_FREESTYLE
/* Freestyle edge/face marks */
@@ -4706,14 +4715,12 @@ static void set_dupli_tex_mat(Render *re, ObjectInstanceRen *obi, DupliObject *d
obi->duplitexmat= BLI_memarena_alloc(re->memArena, sizeof(float)*4*4);
invert_m4_m4(imat, dob->mat);
- mul_serie_m4(obi->duplitexmat, re->viewmat, dob->omat, imat, re->viewinv, 0, 0, 0, 0);
+ mul_serie_m4(obi->duplitexmat, re->viewmat, dob->omat, imat, re->viewinv,
+ NULL, NULL, NULL, NULL);
}
- if (dob) {
- copy_v3_v3(obi->dupliorco, dob->orco);
- obi->dupliuv[0]= dob->uv[0];
- obi->dupliuv[1]= dob->uv[1];
- }
+ copy_v3_v3(obi->dupliorco, dob->orco);
+ copy_v2_v2(obi->dupliuv, dob->uv);
}
static void init_render_object_data(Render *re, ObjectRen *obr, int timeoffset)
@@ -4810,6 +4817,9 @@ static void add_render_object(Render *re, Object *ob, Object *par, DupliObject *
if (ob->particlesystem.first) {
psysindex= 1;
for (psys=ob->particlesystem.first; psys; psys=psys->next, psysindex++) {
+ if (!psys_check_enabled(ob, psys))
+ continue;
+
obr= RE_addRenderObject(re, ob, par, index, psysindex, ob->lay);
if ((dob && !dob->animated) || (ob->transflag & OB_RENDER_DUPLI)) {
obr->flag |= R_INSTANCEABLE;
@@ -5068,7 +5078,7 @@ static void add_group_render_dupli_obs(Render *re, Group *group, int nolamps, in
if (ob->flag & OB_DONE) {
if (ob->transflag & OB_RENDER_DUPLI) {
if (allow_render_object(re, ob, nolamps, onlyselected, actob)) {
- init_render_object(re, ob, NULL, 0, timeoffset);
+ init_render_object(re, ob, NULL, NULL, timeoffset);
ob->transflag &= ~OB_RENDER_DUPLI;
if (ob->dup_group)
@@ -5128,7 +5138,7 @@ static void database_init_objects(Render *re, unsigned int renderlay, int nolamp
* it still needs to create the ObjectRen containing the data */
if (ob->transflag & OB_RENDER_DUPLI) {
if (allow_render_object(re, ob, nolamps, onlyselected, actob)) {
- init_render_object(re, ob, NULL, 0, timeoffset);
+ init_render_object(re, ob, NULL, NULL, timeoffset);
ob->transflag &= ~OB_RENDER_DUPLI;
}
}
@@ -5236,10 +5246,10 @@ static void database_init_objects(Render *re, unsigned int renderlay, int nolamp
free_object_duplilist(lb);
if (allow_render_object(re, ob, nolamps, onlyselected, actob))
- init_render_object(re, ob, NULL, 0, timeoffset);
+ init_render_object(re, ob, NULL, NULL, timeoffset);
}
else if (allow_render_object(re, ob, nolamps, onlyselected, actob))
- init_render_object(re, ob, NULL, 0, timeoffset);
+ init_render_object(re, ob, NULL, NULL, timeoffset);
}
if (re->test_break(re->tbh)) break;
@@ -5327,7 +5337,7 @@ void RE_Database_FromScene(Render *re, Main *bmain, Scene *scene, unsigned int l
set_node_shader_lamp_loop(shade_material_loop);
/* MAKE RENDER DATA */
- database_init_objects(re, lay, 0, 0, 0, 0);
+ database_init_objects(re, lay, 0, 0, NULL, 0);
if (!re->test_break(re->tbh)) {
set_material_lightgroups(re);
@@ -5486,7 +5496,7 @@ static void database_fromscene_vectors(Render *re, Scene *scene, unsigned int la
}
/* MAKE RENDER DATA */
- database_init_objects(re, lay, 0, 0, 0, timeoffset);
+ database_init_objects(re, lay, 0, 0, NULL, timeoffset);
if (!re->test_break(re->tbh))
project_renderdata(re, projectverto, re->r.mode & R_PANORAMA, 0, 1);
diff --git a/source/blender/render/intern/source/envmap.c b/source/blender/render/intern/source/envmap.c
index 3cd9020fb89..b5bc5ea768b 100644
--- a/source/blender/render/intern/source/envmap.c
+++ b/source/blender/render/intern/source/envmap.c
@@ -245,9 +245,7 @@ static void envmap_transmatrix(float mat[4][4], int part)
copy_m4_m4(tmat, mat);
eul_to_mat4(rotmat, eul);
- mul_serie_m4(mat, tmat, rotmat,
- NULL, NULL, NULL,
- NULL, NULL, NULL);
+ mul_m4_m4m4(mat, tmat, rotmat);
}
/* ------------------------------------------------------------------------- */
diff --git a/source/blender/render/intern/source/external_engine.c b/source/blender/render/intern/source/external_engine.c
index 616dd623b94..ea22423985b 100644
--- a/source/blender/render/intern/source/external_engine.c
+++ b/source/blender/render/intern/source/external_engine.c
@@ -311,7 +311,7 @@ void RE_engine_update_stats(RenderEngine *engine, const char *stats, const char
else if (info && info[0])
BLI_strncpy(engine->text, info, sizeof(engine->text));
else if (stats && stats[0])
- BLI_strncpy(engine->text, info, sizeof(engine->text));
+ BLI_strncpy(engine->text, stats, sizeof(engine->text));
}
void RE_engine_update_progress(RenderEngine *engine, float progress)
diff --git a/source/blender/render/intern/source/initrender.c b/source/blender/render/intern/source/initrender.c
index d4d4a703d6c..6cac2fa3fa6 100644
--- a/source/blender/render/intern/source/initrender.c
+++ b/source/blender/render/intern/source/initrender.c
@@ -541,8 +541,8 @@ void RE_parts_free(Render *re)
void RE_parts_clamp(Render *re)
{
/* part size */
- re->partx = min_ii(re->r.tilex, re->rectx);
- re->party = min_ii(re->r.tiley, re->recty);
+ re->partx = max_ii(1, min_ii(re->r.tilex, re->rectx));
+ re->party = max_ii(1, min_ii(re->r.tiley, re->recty));
}
void RE_parts_init(Render *re, int do_crop)
diff --git a/source/blender/render/intern/source/multires_bake.c b/source/blender/render/intern/source/multires_bake.c
index e81359e8fca..a2fa37fd7ea 100644
--- a/source/blender/render/intern/source/multires_bake.c
+++ b/source/blender/render/intern/source/multires_bake.c
@@ -776,7 +776,7 @@ static void apply_heights_callback(DerivedMesh *lores_dm, DerivedMesh *hires_dm,
get_ccgdm_data(lores_dm, hires_dm,
height_data->orig_index_mf_to_mpoly, height_data->orig_index_mp_to_orig,
- lvl, face_index, uv[0], uv[1], p1, 0);
+ lvl, face_index, uv[0], uv[1], p1, NULL);
if (height_data->ssdm) {
get_ccgdm_data(lores_dm, height_data->ssdm,
diff --git a/source/blender/render/intern/source/occlusion.c b/source/blender/render/intern/source/occlusion.c
index 50f9d6caff6..a16c4b24682 100644
--- a/source/blender/render/intern/source/occlusion.c
+++ b/source/blender/render/intern/source/occlusion.c
@@ -371,7 +371,7 @@ static void occ_sum_occlusion(OcclusionTree *tree, OccNode *node)
for (b = 0; b < TOTCHILD; b++) {
if (node->childflag & (1 << b)) {
a = node->child[b].face;
- occ_face(&tree->face[a], 0, 0, &area);
+ occ_face(&tree->face[a], NULL, NULL, &area);
occ += area * tree->occlusion[a];
if (indirect) madd_v3_v3fl(rad, tree->rad[a], area);
totarea += area;
@@ -521,7 +521,7 @@ static void *exec_occ_build(void *data)
occ_build_recursive(othread->tree, othread->node, othread->begin, othread->end, othread->depth);
- return 0;
+ return NULL;
}
static void occ_build_recursive(OcclusionTree *tree, OccNode *node, int begin, int end, int depth)
@@ -567,7 +567,7 @@ static void occ_build_recursive(OcclusionTree *tree, OccNode *node, int begin, i
node->child[b].node = child;
/* keep track of maximum depth for stack */
- if (depth + 1 > tree->maxdepth)
+ if (depth >= tree->maxdepth)
tree->maxdepth = depth + 1;
if (tree->dothreadedbuild)
@@ -1244,7 +1244,7 @@ static void *exec_strandsurface_sample(void *data)
copy_v3_v3(othread->faceindirect[a], indirect);
}
- return 0;
+ return NULL;
}
void make_occ_tree(Render *re)
diff --git a/source/blender/render/intern/source/pipeline.c b/source/blender/render/intern/source/pipeline.c
index 848e94c8d4b..899c9b335be 100644
--- a/source/blender/render/intern/source/pipeline.c
+++ b/source/blender/render/intern/source/pipeline.c
@@ -1927,6 +1927,8 @@ static void do_render_composite_fields_blur_3d(Render *re)
do_render_fields_blur_3d(re);
}
else {
+ re->i.cfra = re->r.cfra;
+
/* ensure new result gets added, like for regular renders */
BLI_rw_mutex_lock(&re->resultmutex, THREAD_LOCK_WRITE);
diff --git a/source/blender/render/intern/source/pointdensity.c b/source/blender/render/intern/source/pointdensity.c
index e86ae7ea063..d4d6bfa5b7f 100644
--- a/source/blender/render/intern/source/pointdensity.c
+++ b/source/blender/render/intern/source/pointdensity.c
@@ -107,6 +107,7 @@ static void pointdensity_cache_psys(Render *re, PointDensity *pd, Object *ob, Pa
{
DerivedMesh* dm;
ParticleKey state;
+ ParticleCacheKey *cache;
ParticleSimulationData sim= {NULL};
ParticleData *pa=NULL;
float cfra = BKE_scene_frame_get(re->scene);
@@ -153,44 +154,62 @@ static void pointdensity_cache_psys(Render *re, PointDensity *pd, Object *ob, Pa
for (i=0, pa=psys->particles; i < total_particles; i++, pa++) {
- state.time = cfra;
- if (psys_get_particle_state(&sim, i, &state, 0)) {
-
- copy_v3_v3(partco, state.co);
-
- if (pd->psys_cache_space == TEX_PD_OBJECTSPACE)
- mul_m4_v3(ob->imat, partco);
- else if (pd->psys_cache_space == TEX_PD_OBJECTLOC) {
- sub_v3_v3(partco, ob->loc);
- }
- else {
- /* TEX_PD_WORLDSPACE */
- }
-
- BLI_bvhtree_insert(pd->point_tree, i, partco, 1);
-
- if (data_used & POINT_DATA_VEL) {
- pd->point_data[i*3 + 0] = state.vel[0];
- pd->point_data[i*3 + 1] = state.vel[1];
- pd->point_data[i*3 + 2] = state.vel[2];
- }
+ if (psys->part->type == PART_HAIR) {
+ /* hair particles */
+ if (i < psys->totpart && psys->pathcache)
+ cache = psys->pathcache[i];
+ else if (i >= psys->totpart && psys->childcache)
+ cache = psys->childcache[i - psys->totpart];
+ else
+ continue;
+
+ cache += cache->steps; /* use endpoint */
+
+ copy_v3_v3(state.co, cache->co);
+ zero_v3(state.vel);
+ state.time = 0.0f;
+ }
+ else {
+ /* emitter particles */
+ state.time = cfra;
+
+ if (!psys_get_particle_state(&sim, i, &state, 0))
+ continue;
+
if (data_used & POINT_DATA_LIFE) {
- float pa_time;
-
if (i < psys->totpart) {
- pa_time = (cfra - pa->time)/pa->lifetime;
+ state.time = (cfra - pa->time)/pa->lifetime;
}
else {
ChildParticle *cpa= (psys->child + i) - psys->totpart;
float pa_birthtime, pa_dietime;
- pa_time = psys_get_child_time(psys, cpa, cfra, &pa_birthtime, &pa_dietime);
+ state.time = psys_get_child_time(psys, cpa, cfra, &pa_birthtime, &pa_dietime);
}
-
- pd->point_data[offset + i] = pa_time;
-
}
}
+
+ copy_v3_v3(partco, state.co);
+
+ if (pd->psys_cache_space == TEX_PD_OBJECTSPACE)
+ mul_m4_v3(ob->imat, partco);
+ else if (pd->psys_cache_space == TEX_PD_OBJECTLOC) {
+ sub_v3_v3(partco, ob->loc);
+ }
+ else {
+ /* TEX_PD_WORLDSPACE */
+ }
+
+ BLI_bvhtree_insert(pd->point_tree, i, partco, 1);
+
+ if (data_used & POINT_DATA_VEL) {
+ pd->point_data[i*3 + 0] = state.vel[0];
+ pd->point_data[i*3 + 1] = state.vel[1];
+ pd->point_data[i*3 + 2] = state.vel[2];
+ }
+ if (data_used & POINT_DATA_LIFE) {
+ pd->point_data[offset + i] = state.time;
+ }
}
BLI_bvhtree_balance(pd->point_tree);
@@ -198,7 +217,7 @@ static void pointdensity_cache_psys(Render *re, PointDensity *pd, Object *ob, Pa
if (psys->lattice) {
end_latt_deform(psys->lattice);
- psys->lattice=0;
+ psys->lattice = NULL;
}
psys_render_restore(ob, psys);
diff --git a/source/blender/render/intern/source/rayshade.c b/source/blender/render/intern/source/rayshade.c
index e77920dde26..7ae64d499fa 100644
--- a/source/blender/render/intern/source/rayshade.c
+++ b/source/blender/render/intern/source/rayshade.c
@@ -731,7 +731,7 @@ static void ray_fadeout(Isect *is, ShadeInput *shi, float col[3], const float bl
* note: 'col' must be initialized */
static void traceray(ShadeInput *origshi, ShadeResult *origshr, short depth, const float start[3], const float dir[3], float col[4], ObjectInstanceRen *obi, VlakRen *vlr, int traflag)
{
- ShadeInput shi= {0};
+ ShadeInput shi = {NULL};
Isect isec;
float dist_mir = origshi->mat->dist_mir;
@@ -741,7 +741,7 @@ static void traceray(ShadeInput *origshi, ShadeResult *origshr, short depth, con
isec.mode= RE_RAY_MIRROR;
isec.check = RE_CHECK_VLR_RENDER;
isec.skip = RE_SKIP_VLR_NEIGHBOUR;
- isec.hint = 0;
+ isec.hint = NULL;
isec.orig.ob = obi;
isec.orig.face = vlr;
@@ -1866,10 +1866,10 @@ static void ray_ao_qmc(ShadeInput *shi, float ao[3], float env[3])
isec.orig.face = shi->vlr;
isec.check = RE_CHECK_VLR_NON_SOLID_MATERIAL;
isec.skip = RE_SKIP_VLR_NEIGHBOUR;
- isec.hint = 0;
+ isec.hint = NULL;
- isec.hit.ob = 0;
- isec.hit.face = 0;
+ isec.hit.ob = NULL;
+ isec.hit.face = NULL;
isec.last_hit = NULL;
@@ -2013,10 +2013,10 @@ static void ray_ao_spheresamp(ShadeInput *shi, float ao[3], float env[3])
isec.orig.face = shi->vlr;
isec.check = RE_CHECK_VLR_RENDER;
isec.skip = RE_SKIP_VLR_NEIGHBOUR;
- isec.hint = 0;
+ isec.hint = NULL;
- isec.hit.ob = 0;
- isec.hit.face = 0;
+ isec.hit.ob = NULL;
+ isec.hit.face = NULL;
isec.last_hit = NULL;
@@ -2468,7 +2468,7 @@ void ray_shadow(ShadeInput *shi, LampRen *lar, float shadfac[4])
RE_RC_INIT(isec, *shi);
if (shi->mat->mode & MA_SHADOW_TRA) isec.mode= RE_RAY_SHADOW_TRA;
else isec.mode= RE_RAY_SHADOW;
- isec.hint = 0;
+ isec.hint = NULL;
if (lar->mode & (LA_LAYER|LA_LAYER_SHADOW))
isec.lay= lar->lay;
diff --git a/source/blender/render/intern/source/render_result.c b/source/blender/render/intern/source/render_result.c
index f719e09769d..1f740e3f483 100644
--- a/source/blender/render/intern/source/render_result.c
+++ b/source/blender/render/intern/source/render_result.c
@@ -279,6 +279,24 @@ static const char *get_pass_name(int passtype, int channel)
if (channel == 1) return "TransCol.G";
return "TransCol.B";
}
+ if (passtype == SCE_PASS_SUBSURFACE_DIRECT) {
+ if (channel == -1) return "SubsurfaceDir";
+ if (channel == 0) return "SubsurfaceDir.R";
+ if (channel == 1) return "SubsurfaceDir.G";
+ return "SubsurfaceDir.B";
+ }
+ if (passtype == SCE_PASS_SUBSURFACE_INDIRECT) {
+ if (channel == -1) return "SubsurfaceInd";
+ if (channel == 0) return "SubsurfaceInd.R";
+ if (channel == 1) return "SubsurfaceInd.G";
+ return "SubsurfaceInd.B";
+ }
+ if (passtype == SCE_PASS_SUBSURFACE_COLOR) {
+ if (channel == -1) return "SubsurfaceCol";
+ if (channel == 0) return "SubsurfaceCol.R";
+ if (channel == 1) return "SubsurfaceCol.G";
+ return "SubsurfaceCol.B";
+ }
return "Unknown";
}
@@ -368,6 +386,15 @@ static int passtype_from_name(const char *str)
if (strcmp(str, "TransCol") == 0)
return SCE_PASS_TRANSM_COLOR;
+
+ if (strcmp(str, "SubsurfaceDir") == 0)
+ return SCE_PASS_SUBSURFACE_DIRECT;
+
+ if (strcmp(str, "SubsurfaceInd") == 0)
+ return SCE_PASS_SUBSURFACE_INDIRECT;
+
+ if (strcmp(str, "SubsurfaceCol") == 0)
+ return SCE_PASS_SUBSURFACE_COLOR;
return 0;
}
@@ -538,6 +565,12 @@ RenderResult *render_result_new(Render *re, rcti *partrct, int crop, int savebuf
render_layer_add_pass(rr, rl, 3, SCE_PASS_TRANSM_INDIRECT);
if (srl->passflag & SCE_PASS_TRANSM_COLOR)
render_layer_add_pass(rr, rl, 3, SCE_PASS_TRANSM_COLOR);
+ if (srl->passflag & SCE_PASS_SUBSURFACE_DIRECT)
+ render_layer_add_pass(rr, rl, 3, SCE_PASS_SUBSURFACE_DIRECT);
+ if (srl->passflag & SCE_PASS_SUBSURFACE_INDIRECT)
+ render_layer_add_pass(rr, rl, 3, SCE_PASS_SUBSURFACE_INDIRECT);
+ if (srl->passflag & SCE_PASS_SUBSURFACE_COLOR)
+ render_layer_add_pass(rr, rl, 3, SCE_PASS_SUBSURFACE_COLOR);
}
/* sss, previewrender and envmap don't do layers, so we make a default one */
if (rr->layers.first == NULL && !(layername && layername[0])) {
diff --git a/source/blender/render/intern/source/render_texture.c b/source/blender/render/intern/source/render_texture.c
index ad923a4172c..49052150fe3 100644
--- a/source/blender/render/intern/source/render_texture.c
+++ b/source/blender/render/intern/source/render_texture.c
@@ -2163,7 +2163,7 @@ void do_material_tex(ShadeInput *shi, Render *re)
mtex= shi->mat->mtex[tex_nr];
tex= mtex->tex;
- if (tex==0) continue;
+ if (tex == NULL) continue;
found_deriv_map = (tex->type==TEX_IMAGE) && (tex->imaflag & TEX_DERIVATIVEMAP);
use_compat_bump= (mtex->texflag & MTEX_COMPAT_BUMP);
@@ -2686,7 +2686,7 @@ void do_volume_tex(ShadeInput *shi, const float *xyz, int mapto_flag, float col_
if (shi->mat->mtex[tex_nr]) {
mtex= shi->mat->mtex[tex_nr];
tex= mtex->tex;
- if (tex==0) continue;
+ if (tex == NULL) continue;
/* only process if this texture is mapped
* to one that we're interested in */
@@ -3028,7 +3028,7 @@ void do_sky_tex(const float rco[3], float lo[3], const float dxyview[2], float h
mtex= R.wrld.mtex[tex_nr];
tex= mtex->tex;
- if (tex==0) continue;
+ if (tex == NULL) continue;
/* if (mtex->mapto==0) continue; */
/* which coords */
@@ -3609,7 +3609,7 @@ Material *RE_init_sample_material(Material *orig_mat, Scene *scene)
}
if (tex->type==TEX_POINTDENSITY) {
/* set dummy values for render and do cache */
- Render dummy_re = {0};
+ Render dummy_re = {NULL};
dummy_re.scene = scene;
unit_m4(dummy_re.viewinv);
unit_m4(dummy_re.viewmat);
@@ -3668,8 +3668,8 @@ void RE_sample_material_color(Material *mat, float color[3], float *alpha, const
int v1, v2, v3;
MVert *mvert;
float uv[3], normal[3];
- ShadeInput shi = {0};
- Render re = {0};
+ ShadeInput shi = {NULL};
+ Render re = {NULL};
/* Get face data */
mvert = orcoDm->getVertArray(orcoDm);
@@ -3752,7 +3752,7 @@ void RE_sample_material_color(Material *mat, float color[3], float *alpha, const
*alpha = shi.alpha;
}
else if (mat->material_type == MA_TYPE_VOLUME) {
- ObjectInstanceRen obi = {0};
+ ObjectInstanceRen obi = {NULL};
obi.ob = ob;
shi.obi = &obi;
unit_m4(re.viewinv);
diff --git a/source/blender/render/intern/source/shadbuf.c b/source/blender/render/intern/source/shadbuf.c
index 6453c03c596..0d85cfe78b7 100644
--- a/source/blender/render/intern/source/shadbuf.c
+++ b/source/blender/render/intern/source/shadbuf.c
@@ -1026,7 +1026,7 @@ static float readdeepshadowbuf(ShadBuf *shb, ShadSampleBuf *shsample, int bias,
if (biast != 0.0f) {
/* in soft bias area */
- biasv= readdeepvisibility(shsample->deepbuf[ofs], tot, zs, 0, 0);
+ biasv = readdeepvisibility(shsample->deepbuf[ofs], tot, zs, 0, NULL);
biast= biast*biast;
return (1.0f-biast)*v + biast*biasv;
@@ -2045,7 +2045,7 @@ static void isb_bsp_fillfaces(Render *re, LampRen *lar, ISBBranch *root)
if (vlr->v4)
zbufclipwire(&zspan, i, a+1, vlr->ec, hoco[0], hoco[1], hoco[2], hoco[3], c1, c2, c3, c4);
else
- zbufclipwire(&zspan, i, a+1, vlr->ec, hoco[0], hoco[1], hoco[2], 0, c1, c2, c3, 0);
+ zbufclipwire(&zspan, i, a+1, vlr->ec, hoco[0], hoco[1], hoco[2], NULL, c1, c2, c3, 0);
}
else if (vlr->v4) {
if (vlr->flag & R_STRAND)
diff --git a/source/blender/render/intern/source/strand.c b/source/blender/render/intern/source/strand.c
index 0a9c1fa666e..f2d4a7afd94 100644
--- a/source/blender/render/intern/source/strand.c
+++ b/source/blender/render/intern/source/strand.c
@@ -783,7 +783,7 @@ int zbuffer_strands_abuf(Render *re, RenderPart *pa, APixstrand *apixbuf, ListBa
ObjectRen *obr;
ObjectInstanceRen *obi;
ZSpan zspan;
- StrandRen *strand=0;
+ StrandRen *strand = NULL;
StrandVert *svert;
StrandBound *sbound;
StrandPart spart;
diff --git a/source/blender/render/intern/source/voxeldata.c b/source/blender/render/intern/source/voxeldata.c
index 0aa1bcfef34..3f19e77946c 100644
--- a/source/blender/render/intern/source/voxeldata.c
+++ b/source/blender/render/intern/source/voxeldata.c
@@ -156,7 +156,7 @@ static void load_frame_image_sequence(VoxelData *vd, Tex *tex)
int x = 0, y = 0, z = 0;
float *rf;
- if (!ima || !tiuser) return;
+ if (!ima) return;
if (iuser.frames == 0) return;
ima->source = IMA_SRC_SEQUENCE;
diff --git a/source/blender/render/intern/source/zbuf.c b/source/blender/render/intern/source/zbuf.c
index 2f45ad756d3..d65db9d47f8 100644
--- a/source/blender/render/intern/source/zbuf.c
+++ b/source/blender/render/intern/source/zbuf.c
@@ -121,7 +121,7 @@ static void zbuf_init_span(ZSpan *zspan)
zspan->minp1= zspan->maxp1= zspan->minp2= zspan->maxp2= NULL;
}
-static void zbuf_add_to_span(ZSpan *zspan, const float *v1, const float *v2)
+static void zbuf_add_to_span(ZSpan *zspan, const float v1[2], const float v2[2])
{
const float *minv, *maxv;
float *span;
@@ -504,7 +504,7 @@ static void zbuflineAc(ZSpan *zspan, int obi, int zvlnr, const float vec1[3], co
if (apn->p[2]==zvlnr && apn->obi[2]==obi) {apn->mask[2]|= mask; break; }
if (apn->p[3]==0) {apn->obi[3]= obi; apn->p[3]= zvlnr; apn->z[3]= vergz; apn->mask[3]= mask; break; }
if (apn->p[3]==zvlnr && apn->obi[3]==obi) {apn->mask[3]|= mask; break; }
- if (apn->next==0) apn->next= addpsA(zspan);
+ if (apn->next == NULL) apn->next = addpsA(zspan);
apn= apn->next;
}
}
@@ -575,7 +575,7 @@ static void zbuflineAc(ZSpan *zspan, int obi, int zvlnr, const float vec1[3], co
if (apn->p[2]==zvlnr) {apn->mask[2]|= mask; break; }
if (apn->p[3]==0) {apn->obi[3]= obi; apn->p[3]= zvlnr; apn->z[3]= vergz; apn->mask[3]= mask; break; }
if (apn->p[3]==zvlnr) {apn->mask[3]|= mask; break; }
- if (apn->next==0) apn->next= addpsA(zspan);
+ if (apn->next == NULL) apn->next = addpsA(zspan);
apn= apn->next;
}
}
@@ -909,7 +909,9 @@ void hoco_to_zco(ZSpan *zspan, float zco[3], const float hoco[4])
zco[2]= 0x7FFFFFFF *(hoco[2]*div);
}
-void zbufclipwire(ZSpan *zspan, int obi, int zvlnr, int ec, float *ho1, float *ho2, float *ho3, float *ho4, int c1, int c2, int c3, int c4)
+void zbufclipwire(ZSpan *zspan, int obi, int zvlnr, int ec,
+ const float ho1[4], const float ho2[4], const float ho3[4], const float ho4[4],
+ int c1, int c2, int c3, int c4)
{
float vez[20];
int and, or;
@@ -1845,7 +1847,9 @@ void zbuf_make_winmat(Render *re, float winmat[4][4])
/* do zbuffering and clip, f1 f2 f3 are hocos, c1 c2 c3 are clipping flags */
-void zbufclip(ZSpan *zspan, int obi, int zvlnr, float *f1, float *f2, float *f3, int c1, int c2, int c3)
+void zbufclip(ZSpan *zspan, int obi, int zvlnr,
+ const float f1[4], const float f2[4], const float f3[4],
+ const int c1, const int c2, const int c3)
{
float *vlzp[32][3], lambda[3][2];
float vez[400], *trias[40];
@@ -1856,6 +1860,7 @@ void zbufclip(ZSpan *zspan, int obi, int zvlnr, float *f1, float *f2, float *f3,
}
else { /* clipping */
int arg, v, b, clipflag[3], b1, b2, b3, c4, clve=3, clvlo, clvl=1;
+ float *fp;
vez[0]= f1[0]; vez[1]= f1[1]; vez[2]= f1[2]; vez[3]= f1[3];
vez[4]= f2[0]; vez[5]= f2[1]; vez[6]= f2[2]; vez[7]= f2[3];
@@ -1936,16 +1941,16 @@ void zbufclip(ZSpan *zspan, int obi, int zvlnr, float *f1, float *f2, float *f3,
}
}
- /* warning, this should never happen! */
- if (clve>38 || clvl>31) printf("clip overflow: clve clvl %d %d\n", clve, clvl);
+ /* warning, clip overflow, this should never happen! */
+ BLI_assert(!(clve > 38 || clvl > 31));
/* perspective division */
- f1=vez;
- for (c1=0;c1<clve;c1++) {
- hoco_to_zco(zspan, f1, f1);
- f1+=4;
+ fp = vez;
+ for (b = 0; b < clve; b++) {
+ hoco_to_zco(zspan, fp, fp);
+ fp += 4;
}
- for (b=1;b<clvl;b++) {
+ for (b = 1; b < clvl; b++) {
if (vlzp[b][0]) {
zspan->zbuffunc(zspan, obi, zvlnr, vlzp[b][0], vlzp[b][1], vlzp[b][2], NULL);
}
@@ -1961,7 +1966,9 @@ void zbufclip(ZSpan *zspan, int obi, int zvlnr, float *f1, float *f2, float *f3,
zspan->zbuffunc(zspan, obi, zvlnr, vez, vez+4, vez+8, NULL);
}
-void zbufclip4(ZSpan *zspan, int obi, int zvlnr, float *f1, float *f2, float *f3, float *f4, int c1, int c2, int c3, int c4)
+void zbufclip4(ZSpan *zspan, int obi, int zvlnr,
+ const float f1[4], const float f2[4], const float f3[4], const float f4[4],
+ const int c1, const int c2, const int c3, const int c4)
{
float vez[16];
@@ -2068,7 +2075,7 @@ void zbuffer_solid(RenderPart *pa, RenderLayer *rl, void(*fillfunc)(RenderPart *
ZSpan zspans[16], *zspan; /* 16 = RE_MAX_OSA */
VlakRen *vlr= NULL;
VertRen *v1, *v2, *v3, *v4;
- Material *ma=0;
+ Material *ma = NULL;
ObjectInstanceRen *obi;
ObjectRen *obr;
float obwinmat[4][4], winmat[4][4], bounds[4];
@@ -2238,7 +2245,7 @@ void zbuffer_solid(RenderPart *pa, RenderLayer *rl, void(*fillfunc)(RenderPart *
if (v4)
zbufclipwire(zspan, i, zvlnr, vlr->ec, ho1, ho2, ho3, ho4, c1, c2, c3, c4);
else
- zbufclipwire(zspan, i, zvlnr, vlr->ec, ho1, ho2, ho3, 0, c1, c2, c3, 0);
+ zbufclipwire(zspan, i, zvlnr, vlr->ec, ho1, ho2, ho3, NULL, c1, c2, c3, 0);
}
else {
/* strands allow to be filled in as quad */
@@ -2375,7 +2382,7 @@ void zbuffer_shadow(Render *re, float winmat[4][4], LampRen *lar, int *rectz, in
zbufclipwire(&zspan, 0, a+1, vlr->ec, ho1, ho2, ho3, ho4, c1, c2, c3, c4);
}
else
- zbufclipwire(&zspan, 0, a+1, vlr->ec, ho1, ho2, ho3, 0, c1, c2, c3, 0);
+ zbufclipwire(&zspan, 0, a+1, vlr->ec, ho1, ho2, ho3, NULL, c1, c2, c3, 0);
}
else {
if (vlr->v4) {
@@ -2539,7 +2546,7 @@ void zbuffer_sss(RenderPart *pa, unsigned int lay, void *handle, void (*func)(vo
ObjectRen *obr;
VlakRen *vlr= NULL;
VertRen *v1, *v2, *v3, *v4;
- Material *ma=0, *sss_ma= R.sss_mat;
+ Material *ma = NULL, *sss_ma = R.sss_mat;
float obwinmat[4][4], winmat[4][4], bounds[4];
float ho1[4], ho2[4], ho3[4], ho4[4]={0};
int i, v, zvlnr, c1, c2, c3, c4=0;
@@ -3399,7 +3406,7 @@ static int zbuffer_abuf(Render *re, RenderPart *pa, APixstr *APixbuf, ListBase *
if (v4)
zbufclipwire(zspan, i, zvlnr, vlr->ec, ho1, ho2, ho3, ho4, c1, c2, c3, c4);
else
- zbufclipwire(zspan, i, zvlnr, vlr->ec, ho1, ho2, ho3, 0, c1, c2, c3, 0);
+ zbufclipwire(zspan, i, zvlnr, vlr->ec, ho1, ho2, ho3, NULL, c1, c2, c3, 0);
}
else {
if (v4 && (vlr->flag & R_STRAND)) {
diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h
index 7cb24daaaef..8894be111e7 100644
--- a/source/blender/windowmanager/WM_api.h
+++ b/source/blender/windowmanager/WM_api.h
@@ -187,6 +187,8 @@ __attribute__ ((format(printf, 3, 4)))
;
void wm_event_add(struct wmWindow *win, const struct wmEvent *event_to_add);
+void wm_event_init_from_window(struct wmWindow *win, struct wmEvent *event);
+
/* at maximum, every timestep seconds it triggers event_type events */
struct wmTimer *WM_event_add_timer(struct wmWindowManager *wm, struct wmWindow *win, int event_type, double timestep);
@@ -340,7 +342,7 @@ ListBase *WM_dropboxmap_find(const char *idname, int spaceid, int regionid);
/* Set a subwindow active in pixelspace view, with optional scissor subset */
void wmSubWindowSet (struct wmWindow *win, int swinid);
-void wmSubWindowScissorSet (struct wmWindow *win, int swinid, struct rcti *srct);
+void wmSubWindowScissorSet (struct wmWindow *win, int swinid, const struct rcti *srct, bool srct_pad);
/* OpenGL utilities with safety check + working in modelview matrix mode */
void wmFrustum (float x1, float x2, float y1, float y2, float n, float f);
diff --git a/source/blender/windowmanager/intern/wm_draw.c b/source/blender/windowmanager/intern/wm_draw.c
index 3e9dc0f10c8..dac62d624b5 100644
--- a/source/blender/windowmanager/intern/wm_draw.c
+++ b/source/blender/windowmanager/intern/wm_draw.c
@@ -569,7 +569,7 @@ static void wm_draw_region_blend(wmWindow *win, ARegion *ar)
/* region blend always is 1, except when blend timer is running */
if (fac < 1.0f) {
- wmSubWindowScissorSet(win, win->screen->mainwin, &ar->winrct);
+ wmSubWindowScissorSet(win, win->screen->mainwin, &ar->winrct, true);
glEnable(GL_BLEND);
wm_triple_draw_textures(win, win->drawdata, 1.0f - fac);
diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c
index f8546ad441a..b4f193bdbe6 100644
--- a/source/blender/windowmanager/intern/wm_event_system.c
+++ b/source/blender/windowmanager/intern/wm_event_system.c
@@ -132,6 +132,14 @@ void wm_event_free_all(wmWindow *win)
}
}
+void wm_event_init_from_window(wmWindow *win, wmEvent *event)
+{
+ /* make sure we don't copy any owned pointers */
+ BLI_assert(win->eventstate->tablet_data == NULL);
+
+ *event = *(win->eventstate);
+}
+
/* ********************* notifiers, listeners *************** */
static int wm_test_duplicate_notifier(wmWindowManager *wm, unsigned int type, void *reference)
@@ -274,7 +282,7 @@ void wm_event_do_notifiers(bContext *C)
}
if (note->window == win ||
- (note->window == NULL && (note->reference == NULL || note->reference == CTX_data_scene(C))))
+ (note->window == NULL && (note->reference == NULL || note->reference == win->screen->scene)))
{
if (note->category == NC_SCENE) {
if (note->data == ND_FRAME)
@@ -282,7 +290,7 @@ void wm_event_do_notifiers(bContext *C)
}
}
if (ELEM5(note->category, NC_SCENE, NC_OBJECT, NC_GEOM, NC_SCENE, NC_WM)) {
- ED_info_stats_clear(CTX_data_scene(C));
+ ED_info_stats_clear(win->screen->scene);
WM_event_add_notifier(C, NC_SPACE | ND_SPACE_INFO, NULL);
}
}
@@ -445,7 +453,9 @@ static void wm_handler_ui_cancel(bContext *C)
nexthandler = handler->next;
if (handler->ui_handle) {
- wmEvent event = *(win->eventstate);
+ wmEvent event;
+
+ wm_event_init_from_window(win, &event);
event.type = EVT_BUT_CANCEL;
handler->ui_handle(C, &event, handler->ui_userdata);
}
@@ -972,7 +982,7 @@ static int wm_operator_invoke(bContext *C, wmOperatorType *ot, wmEvent *event,
WM_operator_last_properties_init(op);
}
- if ((G.debug & G_DEBUG_HANDLERS) && event && event->type != MOUSEMOVE) {
+ if ((G.debug & G_DEBUG_HANDLERS) && ((event == NULL) || (event->type != MOUSEMOVE))) {
printf("%s: handle evt %d win %d op %s\n",
__func__, event ? event->type : 0, CTX_wm_screen(C)->subwinactive, ot->idname);
}
diff --git a/source/blender/windowmanager/intern/wm_keymap.c b/source/blender/windowmanager/intern/wm_keymap.c
index 13230f48a15..ff805579b44 100644
--- a/source/blender/windowmanager/intern/wm_keymap.c
+++ b/source/blender/windowmanager/intern/wm_keymap.c
@@ -795,6 +795,7 @@ const char *WM_key_event_string(short type)
int WM_keymap_item_to_string(wmKeyMapItem *kmi, char *str, const int len)
{
char buf[128];
+ char *p = buf;
buf[0] = 0;
@@ -803,28 +804,28 @@ int WM_keymap_item_to_string(wmKeyMapItem *kmi, char *str, const int len)
kmi->alt == KM_ANY &&
kmi->oskey == KM_ANY)
{
- strcat(buf, "Any ");
+ p += BLI_strcpy_rlen(p, "Any ");
}
else {
if (kmi->shift)
- strcat(buf, "Shift ");
+ p += BLI_strcpy_rlen(p, "Shift ");
if (kmi->ctrl)
- strcat(buf, "Ctrl ");
+ p += BLI_strcpy_rlen(p, "Ctrl ");
if (kmi->alt)
- strcat(buf, "Alt ");
+ p += BLI_strcpy_rlen(p, "Alt ");
if (kmi->oskey)
- strcat(buf, "Cmd ");
+ p += BLI_strcpy_rlen(p, "Cmd ");
}
if (kmi->keymodifier) {
- strcat(buf, WM_key_event_string(kmi->keymodifier));
- strcat(buf, " ");
+ p += BLI_strcpy_rlen(p, WM_key_event_string(kmi->keymodifier));
+ p += BLI_strcpy_rlen(p, " ");
}
- strcat(buf, WM_key_event_string(kmi->type));
+ p += BLI_strcpy_rlen(p, WM_key_event_string(kmi->type));
return BLI_strncpy_rlen(str, buf, len);
}
diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c
index ddc48ce6332..f1a9f6dc007 100644
--- a/source/blender/windowmanager/intern/wm_operators.c
+++ b/source/blender/windowmanager/intern/wm_operators.c
@@ -978,7 +978,7 @@ static uiBlock *wm_enum_search_menu(bContext *C, ARegion *ar, void *arg_op)
uiPopupBoundsBlock(block, 6, 0, -UI_UNIT_Y); /* move it downwards, mouse over button */
uiEndBlock(C, block);
- event = *(win->eventstate); /* XXX huh huh? make api call */
+ wm_event_init_from_window(win, &event);
event.type = EVT_BUT_OPEN;
event.val = KM_PRESS;
event.customdata = but;
@@ -1751,7 +1751,7 @@ static uiBlock *wm_block_search_menu(bContext *C, ARegion *ar, void *UNUSED(arg_
uiPopupBoundsBlock(block, 6, 0, -UI_UNIT_Y); /* move it downwards, mouse over button */
uiEndBlock(C, block);
- event = *(win->eventstate); /* XXX huh huh? make api call */
+ wm_event_init_from_window(win, &event);
event.type = EVT_BUT_OPEN;
event.val = KM_PRESS;
event.customdata = but;
@@ -2614,7 +2614,7 @@ static void WM_OT_window_fullscreen_toggle(wmOperatorType *ot)
ot->poll = WM_operator_winactive;
}
-static int wm_exit_blender_op(bContext *C, wmOperator *op)
+static int wm_exit_blender_exec(bContext *C, wmOperator *op)
{
WM_operator_free(op);
@@ -2630,7 +2630,7 @@ static void WM_OT_quit_blender(wmOperatorType *ot)
ot->description = "Quit Blender";
ot->invoke = WM_operator_confirm;
- ot->exec = wm_exit_blender_op;
+ ot->exec = wm_exit_blender_exec;
ot->poll = WM_operator_winactive;
}
@@ -2638,7 +2638,7 @@ static void WM_OT_quit_blender(wmOperatorType *ot)
#if defined(WIN32)
-static int wm_console_toggle_op(bContext *UNUSED(C), wmOperator *UNUSED(op))
+static int wm_console_toggle_exec(bContext *UNUSED(C), wmOperator *UNUSED(op))
{
GHOST_toggleConsole(2);
return OPERATOR_FINISHED;
@@ -2651,7 +2651,7 @@ static void WM_OT_console_toggle(wmOperatorType *ot)
ot->idname = "WM_OT_console_toggle";
ot->description = N_("Toggle System Console");
- ot->exec = wm_console_toggle_op;
+ ot->exec = wm_console_toggle_exec;
ot->poll = WM_operator_winactive;
}
@@ -2988,7 +2988,7 @@ static void tweak_gesture_modal(bContext *C, const wmEvent *event)
if ((val = wm_gesture_evaluate(gesture))) {
wmEvent tevent;
- tevent = *(window->eventstate);
+ wm_event_init_from_window(window, &tevent);
if (gesture->event_type == LEFTMOUSE)
tevent.type = EVT_TWEAK_L;
else if (gesture->event_type == RIGHTMOUSE)
diff --git a/source/blender/windowmanager/intern/wm_subwindow.c b/source/blender/windowmanager/intern/wm_subwindow.c
index 01bebe8a1b8..4ad4286b657 100644
--- a/source/blender/windowmanager/intern/wm_subwindow.c
+++ b/source/blender/windowmanager/intern/wm_subwindow.c
@@ -239,7 +239,7 @@ void wm_subwindow_position(wmWindow *win, int swinid, rcti *winrct)
static wmWindow *_curwindow = NULL;
static wmSubWindow *_curswin = NULL;
-void wmSubWindowScissorSet(wmWindow *win, int swinid, rcti *srct)
+void wmSubWindowScissorSet(wmWindow *win, int swinid, const rcti *srct, bool srct_pad)
{
int width, height;
_curswin = swin_from_swinid(win, swinid);
@@ -257,8 +257,16 @@ void wmSubWindowScissorSet(wmWindow *win, int swinid, rcti *srct)
glViewport(_curswin->winrct.xmin, _curswin->winrct.ymin, width, height);
if (srct) {
- int scissor_width = BLI_rcti_size_x(srct) + 1; /* only here */
- int scissor_height = BLI_rcti_size_y(srct) + 1;
+ int scissor_width = BLI_rcti_size_x(srct);
+ int scissor_height = BLI_rcti_size_y(srct);
+
+ /* typically a single pixel doesn't matter,
+ * but one pixel offset is noticable with viewport border render */
+ if (srct_pad) {
+ scissor_width += 1;
+ scissor_height += 1;
+ }
+
glScissor(srct->xmin, srct->ymin, scissor_width, scissor_height);
}
else
@@ -273,7 +281,7 @@ void wmSubWindowScissorSet(wmWindow *win, int swinid, rcti *srct)
/* enable the WM versions of opengl calls */
void wmSubWindowSet(wmWindow *win, int swinid)
{
- wmSubWindowScissorSet(win, swinid, NULL);
+ wmSubWindowScissorSet(win, swinid, NULL, true);
}
void wmFrustum(float x1, float x2, float y1, float y2, float n, float f)
diff --git a/source/blender/windowmanager/intern/wm_window.c b/source/blender/windowmanager/intern/wm_window.c
index e0595e3c8ab..062107f834e 100644
--- a/source/blender/windowmanager/intern/wm_window.c
+++ b/source/blender/windowmanager/intern/wm_window.c
@@ -808,7 +808,7 @@ static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr C_void_ptr
* currently it seems to be common practice to generate new event for, but probably
* we'll need utility function for this? (sergey)
*/
- event = *(win->eventstate);
+ wm_event_init_from_window(win, &event);
event.type = MOUSEMOVE;
event.prevx = event.x;
event.prevy = event.y;
@@ -957,7 +957,7 @@ static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr C_void_ptr
win->eventstate->x = wx;
win->eventstate->y = wy;
- event = *(win->eventstate); /* copy last state, like mouse coords */
+ wm_event_init_from_window(win, &event); /* copy last state, like mouse coords */
/* activate region */
event.type = MOUSEMOVE;
@@ -1065,7 +1065,8 @@ static int wm_window_timer(const bContext *C)
else if (wt->event_type == TIMERAUTOSAVE)
wm_autosave_timer(C, wm, wt);
else if (win) {
- wmEvent event = *(win->eventstate);
+ wmEvent event;
+ wm_event_init_from_window(win, &event);
event.type = wt->event_type;
event.val = 0;
@@ -1323,6 +1324,16 @@ void wm_window_swap_buffers(wmWindow *win)
#endif
}
+void wm_window_set_swap_interval (wmWindow *win, int interval)
+{
+ GHOST_SetSwapInterval(win->ghostwin, interval);
+}
+
+int wm_window_get_swap_interval (wmWindow *win)
+{
+ return GHOST_GetSwapInterval(win->ghostwin);
+}
+
/* ******************* exported api ***************** */
diff --git a/source/blender/windowmanager/wm_window.h b/source/blender/windowmanager/wm_window.h
index 22fa2423f61..d7e938fec7c 100644
--- a/source/blender/windowmanager/wm_window.h
+++ b/source/blender/windowmanager/wm_window.h
@@ -58,6 +58,8 @@ void wm_window_lower (wmWindow *win);
void wm_window_set_size (wmWindow *win, int width, int height);
void wm_window_get_position (wmWindow *win, int *posx_r, int *posy_r);
void wm_window_swap_buffers (wmWindow *win);
+void wm_window_set_swap_interval (wmWindow *win, int interval);
+int wm_window_get_swap_interval (wmWindow *win);
void wm_get_cursor_position (wmWindow *win, int *x, int *y);
diff --git a/source/blenderplayer/bad_level_call_stubs/stubs.c b/source/blenderplayer/bad_level_call_stubs/stubs.c
index ca57299fe1e..21502492c05 100644
--- a/source/blenderplayer/bad_level_call_stubs/stubs.c
+++ b/source/blenderplayer/bad_level_call_stubs/stubs.c
@@ -226,6 +226,7 @@ struct wmTimer *WM_event_add_timer(struct wmWindowManager *wm, struct wmWindow *
void WM_event_remove_timer(struct wmWindowManager *wm, struct wmWindow *win, struct wmTimer *timer) {STUB_ASSERT(0);}
void ED_armature_edit_bone_remove(struct bArmature *arm, struct EditBone *exBone) {STUB_ASSERT(0);}
void object_test_constraints(struct Object *owner) {STUB_ASSERT(0);}
+void ED_armature_ebone_to_mat4(struct EditBone *ebone, float mat[4][4]) {STUB_ASSERT(0);}
void ED_object_parent(struct Object *ob, struct Object *par, int type, const char *substr) {STUB_ASSERT(0);}
void ED_object_constraint_set_active(struct Object *ob, struct bConstraint *con) {STUB_ASSERT(0);}
void ED_node_composit_default(struct bContext *C, struct Scene *scene) {STUB_ASSERT(0);}
diff --git a/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp b/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp
index dbb7cbc1816..7b5f5a7096a 100644
--- a/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp
+++ b/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp
@@ -284,6 +284,14 @@ extern "C" void StartKetsjiShell(struct bContext *C, struct ARegion *ar, rcti *c
canvas->SetMouseState(RAS_ICanvas::MOUSE_NORMAL);
else
canvas->SetMouseState(RAS_ICanvas::MOUSE_INVISIBLE);
+
+ // Setup vsync
+ int previous_vsync = canvas->GetSwapInterval();
+ if (startscene->gm.vsync == VSYNC_ADAPTIVE)
+ canvas->SetSwapInterval(-1);
+ else
+ canvas->SetSwapInterval(startscene->gm.vsync); // VSYNC_OFF == 0, VSYNC_ON == 1, so this works
+
RAS_IRenderTools* rendertools = new KX_BlenderRenderTools();
RAS_IRasterizer* rasterizer = NULL;
//Don't use displaylists with VBOs
@@ -371,7 +379,7 @@ extern "C" void StartKetsjiShell(struct bContext *C, struct ARegion *ar, rcti *c
// to the original file working directory
if (exitstring != "")
- strcpy(basedpath, exitstring.Ptr());
+ BLI_strncpy(basedpath, exitstring.ReadPtr(), sizeof(basedpath));
// load relative to the last loaded file, this used to be relative
// to the first file but that makes no sense, relative paths in
@@ -384,9 +392,8 @@ extern "C" void StartKetsjiShell(struct bContext *C, struct ARegion *ar, rcti *c
if (!bfd)
{
// just add "//" in front of it
- char temppath[242];
- strcpy(temppath, "//");
- strcat(temppath, basedpath);
+ char temppath[FILE_MAX] = "//";
+ BLI_strncpy(temppath + 2, basedpath, FILE_MAX - 2);
BLI_path_abs(temppath, pathname);
bfd = load_game_data(temppath);
@@ -664,6 +671,7 @@ extern "C" void StartKetsjiShell(struct bContext *C, struct ARegion *ar, rcti *c
}
if (canvas)
{
+ canvas->SetSwapInterval(previous_vsync); // Set the swap interval back
delete canvas;
canvas = NULL;
}
diff --git a/source/gameengine/BlenderRoutines/KX_BlenderCanvas.cpp b/source/gameengine/BlenderRoutines/KX_BlenderCanvas.cpp
index 3bd1c02f12e..3089b3fd44d 100644
--- a/source/gameengine/BlenderRoutines/KX_BlenderCanvas.cpp
+++ b/source/gameengine/BlenderRoutines/KX_BlenderCanvas.cpp
@@ -66,6 +66,16 @@ void KX_BlenderCanvas::SwapBuffers()
BL_SwapBuffers(m_win);
}
+void KX_BlenderCanvas::SetSwapInterval(int interval)
+{
+ BL_SetSwapInterval(m_win, interval);
+}
+
+int KX_BlenderCanvas::GetSwapInterval()
+{
+ return BL_GetSwapInterval(m_win);
+}
+
void KX_BlenderCanvas::ResizeWindow(int width, int height)
{
// Not implemented for the embedded player
diff --git a/source/gameengine/BlenderRoutines/KX_BlenderCanvas.h b/source/gameengine/BlenderRoutines/KX_BlenderCanvas.h
index c201d866efe..c5318b882fa 100644
--- a/source/gameengine/BlenderRoutines/KX_BlenderCanvas.h
+++ b/source/gameengine/BlenderRoutines/KX_BlenderCanvas.h
@@ -80,6 +80,16 @@ public:
void
SwapBuffers(
);
+
+ void
+ SetSwapInterval(
+ int interval
+ );
+
+ int
+ GetSwapInterval(
+ );
+
void
ResizeWindow(
int width,
diff --git a/source/gameengine/BlenderRoutines/KX_BlenderGL.cpp b/source/gameengine/BlenderRoutines/KX_BlenderGL.cpp
index 61598995040..6ed4866579c 100644
--- a/source/gameengine/BlenderRoutines/KX_BlenderGL.cpp
+++ b/source/gameengine/BlenderRoutines/KX_BlenderGL.cpp
@@ -98,6 +98,16 @@ void BL_MakeDrawable(wmWindowManager *wm, wmWindow *win)
wm_window_make_drawable(wm, win);
}
+void BL_SetSwapInterval(struct wmWindow *win, int interval)
+{
+ wm_window_set_swap_interval(win, interval);
+}
+
+int BL_GetSwapInterval(struct wmWindow *win)
+{
+ return wm_window_get_swap_interval(win);
+}
+
static void DisableForText()
{
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); /* needed for texture fonts otherwise they render as wireframe */
diff --git a/source/gameengine/BlenderRoutines/KX_BlenderGL.h b/source/gameengine/BlenderRoutines/KX_BlenderGL.h
index 54e76ff6489..8032d9a594a 100644
--- a/source/gameengine/BlenderRoutines/KX_BlenderGL.h
+++ b/source/gameengine/BlenderRoutines/KX_BlenderGL.h
@@ -43,6 +43,8 @@ struct wmWindowManager;
// special swapbuffers, that takes care of which area (viewport) needs to be swapped
void BL_SwapBuffers(struct wmWindow *win);
+void BL_SetSwapInterval(struct wmWindow *win, int interval);
+int BL_GetSwapInterval(struct wmWindow *win);
void BL_MakeDrawable(struct wmWindowManager *wm, struct wmWindow *win);
diff --git a/source/gameengine/BlenderRoutines/KX_BlenderRenderTools.cpp b/source/gameengine/BlenderRoutines/KX_BlenderRenderTools.cpp
index db9445b728d..a6b71e0bc43 100644
--- a/source/gameengine/BlenderRoutines/KX_BlenderRenderTools.cpp
+++ b/source/gameengine/BlenderRoutines/KX_BlenderRenderTools.cpp
@@ -37,6 +37,7 @@
#include "RAS_LightObject.h"
#include "RAS_ICanvas.h"
#include "RAS_GLExtensionManager.h"
+#include "RAS_MeshObject.h"
#include "KX_GameObject.h"
#include "KX_PolygonMaterial.h"
@@ -157,6 +158,11 @@ void KX_BlenderRenderTools::SetClientObject(RAS_IRasterizer *rasty, void* obj)
bool KX_BlenderRenderTools::RayHit(KX_ClientObjectInfo *client, KX_RayCast *result, void * const data)
{
double* const oglmatrix = (double* const) data;
+
+ RAS_Polygon* poly = result->m_hitMesh->GetPolygon(result->m_hitPolygon);
+ if (!poly->IsVisible())
+ return false;
+
MT_Point3 resultpoint(result->m_hitPoint);
MT_Vector3 resultnormal(result->m_hitNormal);
MT_Vector3 left(oglmatrix[0],oglmatrix[1],oglmatrix[2]);
@@ -219,7 +225,7 @@ void KX_BlenderRenderTools::applyTransform(RAS_IRasterizer* rasty,double* oglmat
}
MT_Vector3 left = dir.normalized();
- dir = (left.cross(up)).normalized();
+ dir = (up.cross(left)).normalized();
// we have calculated the row vectors, now we keep
// local scaling into account:
diff --git a/source/gameengine/Converter/BL_ArmatureConstraint.cpp b/source/gameengine/Converter/BL_ArmatureConstraint.cpp
index 131fdaed3ec..1e6e3557aa4 100644
--- a/source/gameengine/Converter/BL_ArmatureConstraint.cpp
+++ b/source/gameengine/Converter/BL_ArmatureConstraint.cpp
@@ -189,7 +189,7 @@ void BL_ArmatureConstraint::UpdateTarget()
if (m_blendsubtarget && m_subtarget) {
m_subtarget->UpdateBlenderObjectMatrix(m_blendsubtarget);
if (m_subpose && m_subtarget->GetGameObjectType() == SCA_IObject::OBJ_ARMATURE)
- m_blendsubtarget->pose = ((BL_ArmatureObject*)m_target)->GetOrigPose();
+ m_blendsubtarget->pose = ((BL_ArmatureObject*)m_subtarget)->GetOrigPose();
}
}
}
diff --git a/source/gameengine/Converter/KX_BlenderSceneConverter.cpp b/source/gameengine/Converter/KX_BlenderSceneConverter.cpp
index 7a53144657d..98af99825e1 100644
--- a/source/gameengine/Converter/KX_BlenderSceneConverter.cpp
+++ b/source/gameengine/Converter/KX_BlenderSceneConverter.cpp
@@ -1143,7 +1143,7 @@ KX_LibLoadStatus *KX_BlenderSceneConverter::LinkBlendFile(BlendHandle *bpy_openl
/* needed for lookups*/
GetMainDynamic().push_back(main_newlib);
- strncpy(main_newlib->name, path, sizeof(main_newlib->name));
+ BLI_strncpy(main_newlib->name, path, sizeof(main_newlib->name));
status = new KX_LibLoadStatus(this, m_ketsjiEngine, scene_merge, path);
diff --git a/source/gameengine/Converter/KX_ConvertActuators.cpp b/source/gameengine/Converter/KX_ConvertActuators.cpp
index 05da38dd1af..5b528972e00 100644
--- a/source/gameengine/Converter/KX_ConvertActuators.cpp
+++ b/source/gameengine/Converter/KX_ConvertActuators.cpp
@@ -319,26 +319,20 @@ void BL_ConvertActuators(const char* maggiename,
/* Get the name of the properties that objects must own that
* we're sending to, if present
*/
- STR_String toPropName = (msgAct->toPropName
- ? (char*) msgAct->toPropName
- : "");
+ STR_String toPropName = msgAct->toPropName;
/* Get the Message Subject to send.
*/
- STR_String subject = (msgAct->subject
- ? (char*) msgAct->subject
- : "");
+ STR_String subject = msgAct->subject;
/* Get the bodyType
*/
int bodyType = msgAct->bodyType;
-
+
/* Get the body (text message or property name whose value
* we'll be sending, might be empty
*/
- STR_String body = (msgAct->body
- ? (char*) msgAct->body
- : "");
+ const STR_String body = msgAct->body;
KX_NetworkMessageActuator *tmpmsgact = new KX_NetworkMessageActuator(
gameobj, // actuator controlling object
diff --git a/source/gameengine/Converter/KX_ConvertSensors.cpp b/source/gameengine/Converter/KX_ConvertSensors.cpp
index acaf911c26e..1aae2738311 100644
--- a/source/gameengine/Converter/KX_ConvertSensors.cpp
+++ b/source/gameengine/Converter/KX_ConvertSensors.cpp
@@ -177,9 +177,8 @@ void BL_ConvertSensors(struct Object* blenderobject,
bTouchPulse = (blendertouchsensor->mode & SENS_COLLISION_PULSE);
- STR_String touchPropOrMatName = ( bFindMaterial ?
- blendertouchsensor->materialName:
- (blendertouchsensor->name ? blendertouchsensor->name: ""));
+ const STR_String touchPropOrMatName = bFindMaterial ?
+ blendertouchsensor->materialName : blendertouchsensor->name;
if (gameobj->GetPhysicsController())
@@ -229,9 +228,7 @@ void BL_ConvertSensors(struct Object* blenderobject,
/* Get our NetworkScene */
NG_NetworkScene *NetworkScene = kxscene->GetNetworkScene();
/* filter on the incoming subjects, might be empty */
- STR_String subject = (msgSens->subject
- ? (char*)msgSens->subject
- : "");
+ const STR_String subject = msgSens->subject;
gamesensor = new KX_NetworkMessageSensor(
eventmgr, // our eventmanager
@@ -247,14 +244,9 @@ void BL_ConvertSensors(struct Object* blenderobject,
SCA_EventManager* eventmgr = logicmgr->FindEventManager(SCA_EventManager::TOUCH_EVENTMGR);
if (eventmgr)
{
- STR_String nearpropertyname;
bNearSensor* blendernearsensor = (bNearSensor*)sens->data;
- if (blendernearsensor->name)
- {
- // only objects that own this property will be taken into account
- nearpropertyname = (char*) blendernearsensor->name;
- }
-
+ const STR_String nearpropertyname = (char *)blendernearsensor->name;
+
//DT_ShapeHandle shape = DT_Sphere(0.0);
// this sumoObject is not deleted by a gameobj, so delete it ourself
@@ -453,18 +445,11 @@ void BL_ConvertSensors(struct Object* blenderobject,
SCA_EventManager* eventmgr = logicmgr->FindEventManager(SCA_EventManager::TOUCH_EVENTMGR);
if (eventmgr)
{
- STR_String radarpropertyname;
- STR_String touchpropertyname;
bRadarSensor* blenderradarsensor = (bRadarSensor*) sens->data;
+ const STR_String radarpropertyname = blenderradarsensor->name;
int radaraxis = blenderradarsensor->axis;
- if (blenderradarsensor->name)
- {
- // only objects that own this property will be taken into account
- radarpropertyname = (char*) blenderradarsensor->name;
- }
-
MT_Scalar coneheight = blenderradarsensor->range;
// janco: the angle was doubled, so should I divide the factor in 2
diff --git a/source/gameengine/Expressions/FloatValue.cpp b/source/gameengine/Expressions/FloatValue.cpp
index b7d7f528155..0f468e328ed 100644
--- a/source/gameengine/Expressions/FloatValue.cpp
+++ b/source/gameengine/Expressions/FloatValue.cpp
@@ -97,7 +97,7 @@ ret: a new object containing the result of applying operator op to this
return new CFloatValue (-m_float);
break;
case VALUE_NOT_OPERATOR:
- return new CErrorValue (op2str(op) + "only allowed on booleans");
+ return new CBoolValue (m_float == 0.f);
break;
case VALUE_AND_OPERATOR:
case VALUE_OR_OPERATOR:
@@ -160,6 +160,9 @@ ret: a new object containing the result of applying operator op to val and
case VALUE_LEQ_OPERATOR:
ret = new CBoolValue(((CIntValue *) val)->GetInt() <= m_float);
break;
+ case VALUE_NOT_OPERATOR:
+ ret = new CBoolValue(m_float == 0);
+ break;
default:
ret = new CErrorValue("illegal operator. please send a bug report.");
break;
@@ -212,7 +215,9 @@ ret: a new object containing the result of applying operator op to val and
case VALUE_POS_OPERATOR:
ret = new CFloatValue (m_float);
break;
-
+ case VALUE_NOT_OPERATOR:
+ ret = new CBoolValue(m_float == 0);
+ break;
default:
ret = new CErrorValue("illegal operator. please send a bug report.");
break;
diff --git a/source/gameengine/Expressions/IntValue.cpp b/source/gameengine/Expressions/IntValue.cpp
index 2cacea98467..fa4c9ad8ac9 100644
--- a/source/gameengine/Expressions/IntValue.cpp
+++ b/source/gameengine/Expressions/IntValue.cpp
@@ -96,7 +96,7 @@ object and val
return new CIntValue (-m_int);
break;
case VALUE_NOT_OPERATOR:
- return new CErrorValue (op2str(op) + "only allowed on booleans");
+ return new CBoolValue (m_int == 0);
break;
case VALUE_AND_OPERATOR:
case VALUE_OR_OPERATOR:
@@ -170,7 +170,11 @@ CValue* CIntValue::CalcFinal(VALUE_DATA_TYPE dtype, VALUE_OPERATOR op, CValue *v
case VALUE_POS_OPERATOR:
ret = new CIntValue (m_int);
break;
+ case VALUE_NOT_OPERATOR:
+ ret = new CBoolValue(m_int == 0);
+ break;
default:
+ printf("Found op: %d\n", op);
ret = new CErrorValue("illegal operator. please send a bug report.");
break;
}
@@ -215,6 +219,9 @@ CValue* CIntValue::CalcFinal(VALUE_DATA_TYPE dtype, VALUE_OPERATOR op, CValue *v
case VALUE_LEQ_OPERATOR:
ret = new CBoolValue(((CFloatValue *) val)->GetFloat() <= m_int);
break;
+ case VALUE_NOT_OPERATOR:
+ ret = new CBoolValue(m_int == 0);
+ break;
default:
ret = new CErrorValue("illegal operator. please send a bug report.");
break;
diff --git a/source/gameengine/GamePlayer/common/GPC_RenderTools.cpp b/source/gameengine/GamePlayer/common/GPC_RenderTools.cpp
index 70a05f7425b..e8c29d5aa4f 100644
--- a/source/gameengine/GamePlayer/common/GPC_RenderTools.cpp
+++ b/source/gameengine/GamePlayer/common/GPC_RenderTools.cpp
@@ -37,6 +37,7 @@
#include "RAS_LightObject.h"
#include "RAS_ICanvas.h"
#include "RAS_GLExtensionManager.h"
+#include "RAS_MeshObject.h"
#include "KX_GameObject.h"
#include "KX_PolygonMaterial.h"
@@ -166,6 +167,11 @@ void GPC_RenderTools::SetClientObject(RAS_IRasterizer *rasty, void* obj)
bool GPC_RenderTools::RayHit(KX_ClientObjectInfo *client, KX_RayCast *result, void * const data)
{
double* const oglmatrix = (double* const) data;
+
+ RAS_Polygon* poly = result->m_hitMesh->GetPolygon(result->m_hitPolygon);
+ if (!poly->IsVisible())
+ return false;
+
MT_Point3 resultpoint(result->m_hitPoint);
MT_Vector3 resultnormal(result->m_hitNormal);
MT_Vector3 left(oglmatrix[0],oglmatrix[1],oglmatrix[2]);
diff --git a/source/gameengine/GamePlayer/ghost/GPG_Application.cpp b/source/gameengine/GamePlayer/ghost/GPG_Application.cpp
index bedee5d9a47..c3cbf381af4 100644
--- a/source/gameengine/GamePlayer/ghost/GPG_Application.cpp
+++ b/source/gameengine/GamePlayer/ghost/GPG_Application.cpp
@@ -582,7 +582,12 @@ bool GPG_Application::initEngine(GHOST_IWindow* window, const int stereoMode)
m_canvas = new GPG_Canvas(window);
if (!m_canvas)
return false;
-
+
+ if (gm->vsync == VSYNC_ADAPTIVE)
+ m_canvas->SetSwapInterval(-1);
+ else
+ m_canvas->SetSwapInterval(gm->vsync); // VSYNC_OFF == 0, VSYNC_ON == 1, so this works
+
m_canvas->Init();
if (gm->flag & GAME_SHOW_MOUSE)
m_canvas->SetMouseState(RAS_ICanvas::MOUSE_NORMAL);
@@ -787,9 +792,6 @@ void GPG_Application::stopEngine()
}
m_pyGlobalDictString_Length = saveGamePythonConfig(&m_pyGlobalDictString);
-
- // when exiting the mainloop
- exitGamePythonScripting();
#endif
m_ketsjiengine->StopEngine();
@@ -803,6 +805,7 @@ void GPG_Application::stopEngine()
m_system->removeTimer(m_frameTimer);
m_frameTimer = 0;
}
+
m_engineRunning = false;
}
@@ -880,6 +883,11 @@ void GPG_Application::exitEngine()
GPU_extensions_exit();
+#ifdef WITH_PYTHON
+ // Call this after we're sure nothing needs Python anymore (e.g., destructors)
+ exitGamePlayerPythonScripting();
+#endif
+
m_exitRequested = 0;
m_engineInitialized = false;
}
diff --git a/source/gameengine/GamePlayer/ghost/GPG_Canvas.cpp b/source/gameengine/GamePlayer/ghost/GPG_Canvas.cpp
index a1d00dad0e1..e0559385ee6 100644
--- a/source/gameengine/GamePlayer/ghost/GPG_Canvas.cpp
+++ b/source/gameengine/GamePlayer/ghost/GPG_Canvas.cpp
@@ -107,6 +107,20 @@ void GPG_Canvas::SwapBuffers()
}
}
+void GPG_Canvas::SetSwapInterval(int interval)
+{
+ if (m_window)
+ m_window->setSwapInterval(interval);
+}
+
+int GPG_Canvas::GetSwapInterval()
+{
+ if (m_window)
+ return m_window->getSwapInterval();
+
+ return 0;
+}
+
void GPG_Canvas::ResizeWindow(int width, int height)
{
if (m_window->getState() == GHOST_kWindowStateFullScreen)
diff --git a/source/gameengine/GamePlayer/ghost/GPG_Canvas.h b/source/gameengine/GamePlayer/ghost/GPG_Canvas.h
index 6168d96b337..6e1f86cac0e 100644
--- a/source/gameengine/GamePlayer/ghost/GPG_Canvas.h
+++ b/source/gameengine/GamePlayer/ghost/GPG_Canvas.h
@@ -55,6 +55,9 @@ public:
virtual void SetMousePosition(int x, int y);
virtual void SetMouseState(RAS_MouseState mousestate);
virtual void SwapBuffers();
+ virtual void SetSwapInterval(int interval);
+ virtual int GetSwapInterval();
+
virtual int GetMouseX(int x) { return x; }
virtual int GetMouseY(int y) { return y; }
virtual float GetMouseNormalizedX(int x);
diff --git a/source/gameengine/GamePlayer/ghost/GPG_ghost.cpp b/source/gameengine/GamePlayer/ghost/GPG_ghost.cpp
index f1edb71f4fe..ccbcdd25639 100644
--- a/source/gameengine/GamePlayer/ghost/GPG_ghost.cpp
+++ b/source/gameengine/GamePlayer/ghost/GPG_ghost.cpp
@@ -118,6 +118,14 @@ static void mem_error_cb(const char *errorStr)
fflush(stderr);
}
+// library.c will only free window managers with a callback function.
+// We don't actually use a wmWindowManager, but loading a blendfile
+// loads wmWindows, so we need to free those.
+static void wm_free(bContext *C, wmWindowManager *wm)
+{
+ BLI_freelistN(&wm->windows);
+}
+
#ifdef WIN32
typedef enum {
SCREEN_SAVER_MODE_NONE = 0,
@@ -501,6 +509,8 @@ int main(int argc, char** argv)
sound_init_once();
+ set_free_windowmanager_cb(wm_free);
+
/* if running blenderplayer the last argument can't be parsed since it has to be the filename. */
isBlenderPlayer = !BLO_is_a_runtime(argv[0]);
if (isBlenderPlayer)
@@ -813,9 +823,8 @@ int main(int argc, char** argv)
if (!bfd) {
// just add "//" in front of it
- char temppath[242];
- strcpy(temppath, "//");
- strcat(temppath, basedpath);
+ char temppath[FILE_MAX] = "//";
+ BLI_strncpy(temppath + 2, basedpath, FILE_MAX - 2);
BLI_path_abs(temppath, pathname);
bfd = load_game_data(temppath);
diff --git a/source/gameengine/Ketsji/BL_ActionManager.cpp b/source/gameengine/Ketsji/BL_ActionManager.cpp
index f3620a7b4ba..e3402972ca6 100644
--- a/source/gameengine/Ketsji/BL_ActionManager.cpp
+++ b/source/gameengine/Ketsji/BL_ActionManager.cpp
@@ -41,8 +41,6 @@ BL_ActionManager::~BL_ActionManager()
float BL_ActionManager::GetActionFrame(short layer)
{
return m_layers[layer]->GetFrame();
-
- return 0.f;
}
void BL_ActionManager::SetActionFrame(short layer, float frame)
@@ -53,8 +51,6 @@ void BL_ActionManager::SetActionFrame(short layer, float frame)
struct bAction *BL_ActionManager::GetCurrentAction(short layer)
{
return m_layers[layer]->GetAction();
-
- return 0;
}
void BL_ActionManager::SetPlayMode(short layer, short mode)
@@ -92,8 +88,6 @@ void BL_ActionManager::StopAction(short layer)
bool BL_ActionManager::IsActionDone(short layer)
{
return m_layers[layer]->IsDone();
-
- return true;
}
void BL_ActionManager::Update(float curtime)
diff --git a/source/gameengine/Ketsji/KX_BlenderMaterial.cpp b/source/gameengine/Ketsji/KX_BlenderMaterial.cpp
index 630b2f0b32a..28abdc898ae 100644
--- a/source/gameengine/Ketsji/KX_BlenderMaterial.cpp
+++ b/source/gameengine/Ketsji/KX_BlenderMaterial.cpp
@@ -157,6 +157,11 @@ Material *KX_BlenderMaterial::GetBlenderMaterial() const
return mMaterial->material;
}
+Image *KX_BlenderMaterial::GetBlenderImage() const
+{
+ return mMaterial->tface.tpage;
+}
+
Scene* KX_BlenderMaterial::GetBlenderScene() const
{
return mScene->GetBlenderScene();
diff --git a/source/gameengine/Ketsji/KX_BlenderMaterial.h b/source/gameengine/Ketsji/KX_BlenderMaterial.h
index c34a49e1bde..0a2675f04a8 100644
--- a/source/gameengine/Ketsji/KX_BlenderMaterial.h
+++ b/source/gameengine/Ketsji/KX_BlenderMaterial.h
@@ -78,6 +78,7 @@ public:
)const;
Material* GetBlenderMaterial() const;
+ Image* GetBlenderImage() const;
MTFace* GetMTFace(void) const;
unsigned int* GetMCol(void) const;
BL_Texture * getTex (unsigned int idx) {
diff --git a/source/gameengine/Ketsji/KX_Camera.cpp b/source/gameengine/Ketsji/KX_Camera.cpp
index 0cd06a7b6eb..73ebf89bea3 100644
--- a/source/gameengine/Ketsji/KX_Camera.cpp
+++ b/source/gameengine/Ketsji/KX_Camera.cpp
@@ -521,6 +521,7 @@ PyAttributeDef KX_Camera::Attributes[] = {
KX_PYATTRIBUTE_RW_FUNCTION("perspective", KX_Camera, pyattr_get_perspective, pyattr_set_perspective),
KX_PYATTRIBUTE_RW_FUNCTION("lens", KX_Camera, pyattr_get_lens, pyattr_set_lens),
+ KX_PYATTRIBUTE_RW_FUNCTION("fov", KX_Camera, pyattr_get_fov, pyattr_set_fov),
KX_PYATTRIBUTE_RW_FUNCTION("ortho_scale", KX_Camera, pyattr_get_ortho_scale, pyattr_set_ortho_scale),
KX_PYATTRIBUTE_RW_FUNCTION("near", KX_Camera, pyattr_get_near, pyattr_set_near),
KX_PYATTRIBUTE_RW_FUNCTION("far", KX_Camera, pyattr_get_far, pyattr_set_far),
@@ -752,6 +753,35 @@ int KX_Camera::pyattr_set_lens(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef,
return PY_SET_ATTR_SUCCESS;
}
+PyObject *KX_Camera::pyattr_get_fov(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
+{
+ KX_Camera* self = static_cast<KX_Camera*>(self_v);
+
+ float lens = self->m_camdata.m_lens;
+ float width = self->m_camdata.m_sensor_x;
+ float fov = 2.0 * atan(0.5 * width / lens);
+
+ return PyFloat_FromDouble(fov * MT_DEGS_PER_RAD);
+}
+
+int KX_Camera::pyattr_set_fov(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value)
+{
+ KX_Camera* self = static_cast<KX_Camera*>(self_v);
+ float fov = PyFloat_AsDouble(value);
+ if (fov <= 0.0) {
+ PyErr_SetString(PyExc_AttributeError, "camera.fov = float: KX_Camera, expected a float greater then zero");
+ return PY_SET_ATTR_FAIL;
+ }
+
+ fov *= MT_RADS_PER_DEG;
+ float width = self->m_camdata.m_sensor_x;
+ float lens = width / (2.0 * tan(0.5 * fov));
+
+ self->m_camdata.m_lens= lens;
+ self->m_set_projection_matrix = false;
+ return PY_SET_ATTR_SUCCESS;
+}
+
PyObject *KX_Camera::pyattr_get_ortho_scale(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
{
KX_Camera* self = static_cast<KX_Camera*>(self_v);
diff --git a/source/gameengine/Ketsji/KX_Camera.h b/source/gameengine/Ketsji/KX_Camera.h
index f615fefc223..454c4a54ec1 100644
--- a/source/gameengine/Ketsji/KX_Camera.h
+++ b/source/gameengine/Ketsji/KX_Camera.h
@@ -298,6 +298,8 @@ public:
static PyObject* pyattr_get_lens(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
static int pyattr_set_lens(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
+ static PyObject* pyattr_get_fov(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
+ static int pyattr_set_fov(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
static PyObject* pyattr_get_ortho_scale(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
static int pyattr_set_ortho_scale(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
static PyObject* pyattr_get_near(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
diff --git a/source/gameengine/Ketsji/KX_Dome.cpp b/source/gameengine/Ketsji/KX_Dome.cpp
index aa082c7ef19..85fa0b2b3ce 100644
--- a/source/gameengine/Ketsji/KX_Dome.cpp
+++ b/source/gameengine/Ketsji/KX_Dome.cpp
@@ -401,21 +401,21 @@ void KX_Dome::GLDrawWarpQuads(void)
if (warp.nodes[i][j].i < 0 || warp.nodes[i+1][j].i < 0 || warp.nodes[i+1][j+1].i < 0 || warp.nodes[i][j+1].i < 0)
continue;
- glColor3f(warp.nodes[i][j].i, warp.nodes[i][j].i, warp.nodes[i][j].i);
- glTexCoord2f((warp.nodes[i][j].u * uv_width), (warp.nodes[i][j].v * uv_height));
- glVertex3f(warp.nodes[i][j].x, warp.nodes[i][j].y,0.0);
-
- glColor3f(warp.nodes[i+1][j].i, warp.nodes[i+1][j].i, warp.nodes[i+1][j].i);
- glTexCoord2f((warp.nodes[i+1][j].u * uv_width), (warp.nodes[i+1][j].v * uv_height));
- glVertex3f(warp.nodes[i+1][j].x, warp.nodes[i+1][j].y,0.0);
+ glColor3f(warp.nodes[i][j+1].i, warp.nodes[i][j+1].i, warp.nodes[i][j+1].i);
+ glTexCoord2f((warp.nodes[i][j+1].u * uv_width), (warp.nodes[i][j+1].v * uv_height));
+ glVertex3f(warp.nodes[i][j+1].x, warp.nodes[i][j+1].y,0.0);
glColor3f(warp.nodes[i+1][j+1].i, warp.nodes[i+1][j+1].i, warp.nodes[i+1][j+1].i);
glTexCoord2f((warp.nodes[i+1][j+1].u * uv_width), (warp.nodes[i+1][j+1].v * uv_height));
glVertex3f(warp.nodes[i+1][j+1].x, warp.nodes[i+1][j+1].y,0.0);
- glColor3f(warp.nodes[i][j+1].i, warp.nodes[i][j+1].i, warp.nodes[i][j+1].i);
- glTexCoord2f((warp.nodes[i][j+1].u * uv_width), (warp.nodes[i][j+1].v * uv_height));
- glVertex3f(warp.nodes[i][j+1].x, warp.nodes[i][j+1].y,0.0);
+ glColor3f(warp.nodes[i+1][j].i, warp.nodes[i+1][j].i, warp.nodes[i+1][j].i);
+ glTexCoord2f((warp.nodes[i+1][j].u * uv_width), (warp.nodes[i+1][j].v * uv_height));
+ glVertex3f(warp.nodes[i+1][j].x, warp.nodes[i+1][j].y,0.0);
+
+ glColor3f(warp.nodes[i][j].i, warp.nodes[i][j].i, warp.nodes[i][j].i);
+ glTexCoord2f((warp.nodes[i][j].u * uv_width), (warp.nodes[i][j].v * uv_height));
+ glVertex3f(warp.nodes[i][j].x, warp.nodes[i][j].y,0.0);
}
}
glEnd();
diff --git a/source/gameengine/Ketsji/KX_KetsjiEngine.cpp b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp
index 360a337f852..32666ec0792 100644
--- a/source/gameengine/Ketsji/KX_KetsjiEngine.cpp
+++ b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp
@@ -99,7 +99,8 @@ const char KX_KetsjiEngine::m_profileLabels[tc_numCategories][15] = {
"Rasterizer:", // tc_rasterizer
"Services:", // tc_services
"Overhead:", // tc_overhead
- "Outside:" // tc_outside
+ "Outside:", // tc_outside
+ "GPU Latency:" // tc_latency
};
double KX_KetsjiEngine::m_ticrate = DEFAULT_LOGIC_TIC_RATE;
@@ -542,7 +543,10 @@ void KX_KetsjiEngine::EndFrame()
m_logger->StartLog(tc_rasterizer, m_kxsystem->GetTimeInSeconds(), true);
m_rasterizer->EndFrame();
// swap backbuffer (drawing into this buffer) <-> front/visible buffer
+ m_logger->StartLog(tc_latency, m_kxsystem->GetTimeInSeconds(), true);
m_rasterizer->SwapBuffers();
+ m_logger->StartLog(tc_rasterizer, m_kxsystem->GetTimeInSeconds(), true);
+
m_rendertools->EndFrame(m_rasterizer);
diff --git a/source/gameengine/Ketsji/KX_KetsjiEngine.h b/source/gameengine/Ketsji/KX_KetsjiEngine.h
index 4dd8ea10e62..d5d7262a418 100644
--- a/source/gameengine/Ketsji/KX_KetsjiEngine.h
+++ b/source/gameengine/Ketsji/KX_KetsjiEngine.h
@@ -158,9 +158,10 @@ private:
tc_network,
tc_scenegraph,
tc_rasterizer,
- tc_services, // time spend in miscelaneous activities
+ tc_services, // time spent in miscelaneous activities
tc_overhead, // profile info drawing overhead
- tc_outside, // time spend outside main loop
+ tc_outside, // time spent outside main loop
+ tc_latency, // time spent waiting on the gpu
tc_numCategories
} KX_TimeCategory;
diff --git a/source/gameengine/Ketsji/KX_MeshProxy.cpp b/source/gameengine/Ketsji/KX_MeshProxy.cpp
index 8e803c46358..2a9d59e8b7b 100644
--- a/source/gameengine/Ketsji/KX_MeshProxy.cpp
+++ b/source/gameengine/Ketsji/KX_MeshProxy.cpp
@@ -303,7 +303,7 @@ PyObject *KX_MeshProxy::PyTransformUV(PyObject *args, PyObject *kwds)
"mesh.transformUV(...): invalid uv_index %d", uvindex);
return NULL;
}
- if (uvindex_from < -1 || uvindex_from > 1 || uvindex == -1) {
+ if (uvindex_from < -1 || uvindex_from > 1) {
PyErr_Format(PyExc_ValueError,
"mesh.transformUV(...): invalid uv_index_from %d", uvindex);
return NULL;
@@ -387,16 +387,13 @@ PyObject *KX_MeshProxy::pyattr_get_materials(void *self_v, const KX_PYATTRIBUTE_
for (i=0; i<tot; mit++, i++) {
- RAS_IPolyMaterial *polymat = mit->m_bucket->GetPolyMaterial();
-
- /* Why do we need to check for RAS_BLENDERMAT if both are cast to a (PyObject *)? - Campbell */
- if (polymat->GetFlag() & RAS_BLENDERMAT)
- {
- KX_BlenderMaterial *mat = static_cast<KX_BlenderMaterial*>(polymat);
+ RAS_IPolyMaterial *polymat = mit->m_bucket->GetPolyMaterial();
+ if (polymat->GetFlag() & RAS_BLENDERMAT) {
+ KX_BlenderMaterial *mat = static_cast<KX_BlenderMaterial *>(polymat);
PyList_SET_ITEM(materials, i, mat->GetProxy());
}
else {
- KX_PolygonMaterial *mat = static_cast<KX_PolygonMaterial*>(polymat);
+ KX_PolygonMaterial *mat = static_cast<KX_PolygonMaterial *>(polymat);
PyList_SET_ITEM(materials, i, mat->GetProxy());
}
}
diff --git a/source/gameengine/Ketsji/KX_NavMeshObject.cpp b/source/gameengine/Ketsji/KX_NavMeshObject.cpp
index 24400398f03..e45346db9c7 100644
--- a/source/gameengine/Ketsji/KX_NavMeshObject.cpp
+++ b/source/gameengine/Ketsji/KX_NavMeshObject.cpp
@@ -49,7 +49,7 @@ extern "C" {
#include "DetourStatNavMeshBuilder.h"
#include "KX_ObstacleSimulation.h"
-static const int MAX_PATH_LEN = 256;
+#define MAX_PATH_LEN 256
static const float polyPickExt[3] = {2, 4, 2};
static void calcMeshBounds(const float* vert, int nverts, float* bmin, float* bmax)
@@ -120,14 +120,14 @@ bool KX_NavMeshObject::BuildVertIndArrays(float *&vertices, int& nverts,
int nAllVerts = 0;
float *allVerts = NULL;
buildNavMeshDataByDerivedMesh(dm, &vertsPerPoly, &nAllVerts, &allVerts, &ndtris, &dtris,
- &npolys, &dmeshes, &polys, &dtrisToPolysMap, &dtrisToTrisMap, &trisToFacesMap);
+ &npolys, &dmeshes, &polys, &dtrisToPolysMap, &dtrisToTrisMap, &trisToFacesMap);
- MEM_freeN(dtrisToPolysMap);
- MEM_freeN(dtrisToTrisMap);
- MEM_freeN(trisToFacesMap);
+ MEM_SAFE_FREE(dtrisToPolysMap);
+ MEM_SAFE_FREE(dtrisToTrisMap);
+ MEM_SAFE_FREE(trisToFacesMap);
unsigned short *verticesMap = new unsigned short[nAllVerts];
- memset(verticesMap, 0xffff, sizeof(unsigned short)*nAllVerts);
+ memset(verticesMap, 0xff, sizeof(*verticesMap) * nAllVerts);
int curIdx = 0;
//vertices - mesh verts
//iterate over all polys and create map for their vertices first...
@@ -214,7 +214,7 @@ bool KX_NavMeshObject::BuildVertIndArrays(float *&vertices, int& nverts,
}
}
- MEM_freeN(allVerts);
+ MEM_SAFE_FREE(allVerts);
}
else
{
diff --git a/source/gameengine/Ketsji/KX_ObstacleSimulation.cpp b/source/gameengine/Ketsji/KX_ObstacleSimulation.cpp
index 8798f42fa07..456f5f8af3b 100644
--- a/source/gameengine/Ketsji/KX_ObstacleSimulation.cpp
+++ b/source/gameengine/Ketsji/KX_ObstacleSimulation.cpp
@@ -36,65 +36,19 @@ namespace
{
inline float perp(const MT_Vector2& a, const MT_Vector2& b) { return a.x()*b.y() - a.y()*b.x(); }
- inline float sqr(float x) { return x*x; }
- inline float lerp(float a, float b, float t) { return a + (b-a)*t; }
+ inline float sqr(float x) { return x * x; }
+ inline float lerp(float a, float b, float t) { return a + (b - a) * t; }
inline float clamp(float a, float mn, float mx) { return a < mn ? mn : (a > mx ? mx : a); }
-
- inline float vdistsqr(const float* a, const float* b) { return sqr(b[0]-a[0]) + sqr(b[1]-a[1]); }
- inline float vdist(const float* a, const float* b) { return sqrtf(vdistsqr(a,b)); }
- inline void vcpy(float* a, const float* b) { a[0]=b[0]; a[1]=b[1]; }
- inline float vdot(const float* a, const float* b) { return a[0]*b[0] + a[1]*b[1]; }
-/* inline float vperp(const float* a, const float* b) { return a[0]*b[1] - a[1]*b[0]; } */ /* UNUSED */
- inline void vsub(float* v, const float* a, const float* b) { v[0] = a[0]-b[0]; v[1] = a[1]-b[1]; }
- inline void vadd(float* v, const float* a, const float* b) { v[0] = a[0]+b[0]; v[1] = a[1]+b[1]; }
- inline void vscale(float* v, const float* a, const float s) { v[0] = a[0]*s; v[1] = a[1]*s; }
- inline void vset(float* v, float x, float y) { v[0]=x; v[1]=y; }
- inline float vlensqr(const float* v) { return vdot(v,v); }
- inline float vlen(const float* v) { return sqrtf(vlensqr(v)); }
- inline void vlerp(float* v, const float* a, const float* b, float t) { v[0] = lerp(a[0], b[0], t); v[1] = lerp(a[1], b[1], t); }
-/* inline void vmad(float* v, const float* a, const float* b, float s) { v[0] = a[0] + b[0]*s; v[1] = a[1] + b[1]*s; } */ /* UNUSED */
- inline void vnorm(float* v)
- {
- float d = vlen(v);
- if (d > 0.0001f)
- {
- d = 1.0f/d;
- v[0] *= d;
- v[1] *= d;
- }
- }
-}
-inline float triarea(const float* a, const float* b, const float* c)
-{
- return (b[0]*a[1] - a[0]*b[1]) + (c[0]*b[1] - b[0]*c[1]) + (a[0]*c[1] - c[0]*a[1]);
-}
-
-static void closestPtPtSeg(const float* pt,
- const float* sp, const float* sq,
- float& t)
-{
- float dir[2],diff[3];
- vsub(dir,sq,sp);
- vsub(diff,pt,sp);
- t = vdot(diff,dir);
- if (t <= 0.0f) { t = 0; return; }
- float d = vdot(dir,dir);
- if (t >= d) { t = 1; return; }
- t /= d;
+ inline void vset(float v[2], float x, float y) { v[0] = x; v[1] = y; }
}
-static float distPtSegSqr(const float* pt, const float* sp, const float* sq)
-{
- float t;
- closestPtPtSeg(pt, sp,sq, t);
- float np[2];
- vlerp(np, sp,sq, t);
- return vdistsqr(pt,np);
-}
+/* grr, seems moto provides no nice way to do this */
+#define MT_3D_AS_2D(v) MT_Vector2((v)[0], (v)[1])
-static int sweepCircleCircle(const MT_Vector3& pos0, const MT_Scalar r0, const MT_Vector2& v,
- const MT_Vector3& pos1, const MT_Scalar r1,
- float& tmin, float& tmax)
+static int sweepCircleCircle(
+ const MT_Vector2 &pos0, const MT_Scalar r0, const MT_Vector2 &v,
+ const MT_Vector2 &pos1, const MT_Scalar r1,
+ float& tmin, float& tmax)
{
static const float EPS = 0.0001f;
MT_Vector2 c0(pos0.x(), pos0.y());
@@ -114,9 +68,10 @@ static int sweepCircleCircle(const MT_Vector3& pos0, const MT_Scalar r0, const M
return 1;
}
-static int sweepCircleSegment(const MT_Vector3& pos0, const MT_Scalar r0, const MT_Vector2& v,
- const MT_Vector3& pa, const MT_Vector3& pb, const MT_Scalar sr,
- float& tmin, float &tmax)
+static int sweepCircleSegment(
+ const MT_Vector2 &pos0, const MT_Scalar r0, const MT_Vector2 &v,
+ const MT_Vector2& pa, const MT_Vector2 &pb, const MT_Scalar sr,
+ float& tmin, float &tmax)
{
// equation parameters
MT_Vector2 c0(pos0.x(), pos0.y());
@@ -317,12 +272,12 @@ void KX_ObstacleSimulation::UpdateObstacles()
obs->vel[1] = obs->m_gameObj->GetLinearVelocity().y();
// Update velocity history and calculate perceived (average) velocity.
- vcpy(&obs->hvel[obs->hhead*2], obs->vel);
+ copy_v2_v2(&obs->hvel[obs->hhead * 2], obs->vel);
obs->hhead = (obs->hhead+1) % VEL_HIST_SIZE;
vset(obs->pvel,0,0);
for (int j = 0; j < VEL_HIST_SIZE; ++j)
- vadd(obs->pvel, obs->pvel, &obs->hvel[j*2]);
- vscale(obs->pvel, obs->pvel, 1.0f/VEL_HIST_SIZE);
+ add_v2_v2v2(obs->pvel, obs->pvel, &obs->hvel[j * 2]);
+ mul_v2_fl(obs->pvel, 1.0f / VEL_HIST_SIZE);
}
}
@@ -443,11 +398,11 @@ void KX_ObstacleSimulationTOI::AdjustObstacleVelocity(KX_Obstacle* activeObst, K
// Fake dynamic constraint.
float dv[2];
float vel[2];
- vsub(dv, activeObst->nvel, activeObst->vel);
- float ds = vlen(dv);
+ sub_v2_v2v2(dv, activeObst->nvel, activeObst->vel);
+ float ds = len_v2(dv);
if (ds > maxDeltaSpeed || ds<-maxDeltaSpeed)
- vscale(dv, dv, fabs(maxDeltaSpeed/ds));
- vadd(vel, activeObst->vel, dv);
+ mul_v2_fl(dv, fabs(maxDeltaSpeed / ds));
+ add_v2_v2v2(vel, activeObst->vel, dv);
velocity.x() = vel[0];
velocity.y() = vel[1];
@@ -524,8 +479,7 @@ void KX_ObstacleSimulationTOI_rays::sampleRVO(KX_Obstacle* activeObst, KX_NavMes
if (ob->m_shape == KX_OBSTACLE_CIRCLE)
{
MT_Vector2 vab;
- if (vlen(ob->vel) < 0.01f*0.01f)
- {
+ if (len_v2(ob->vel) < 0.01f * 0.01f) {
// Stationary, use VO
vab = svel;
}
@@ -535,9 +489,11 @@ void KX_ObstacleSimulationTOI_rays::sampleRVO(KX_Obstacle* activeObst, KX_NavMes
vab = 2*svel - vel - ob->vel;
}
- if (!sweepCircleCircle(activeObst->m_pos, activeObst->m_rad,
- vab, ob->m_pos, ob->m_rad, htmin, htmax))
+ if (!sweepCircleCircle(MT_3D_AS_2D(activeObst->m_pos), activeObst->m_rad,
+ vab, MT_3D_AS_2D(ob->m_pos), ob->m_rad, htmin, htmax))
+ {
continue;
+ }
}
else if (ob->m_shape == KX_OBSTACLE_SEGMENT)
{
@@ -550,9 +506,12 @@ void KX_ObstacleSimulationTOI_rays::sampleRVO(KX_Obstacle* activeObst, KX_NavMes
p1 = navmeshobj->TransformToWorldCoords(p1);
p2 = navmeshobj->TransformToWorldCoords(p2);
}
- if (!sweepCircleSegment(activeObst->m_pos, activeObst->m_rad, svel,
- p1, p2, ob->m_rad, htmin, htmax))
+
+ if (!sweepCircleSegment(MT_3D_AS_2D(activeObst->m_pos), activeObst->m_rad, svel,
+ MT_3D_AS_2D(p1), MT_3D_AS_2D(p2), ob->m_rad, htmin, htmax))
+ {
continue;
+ }
}
else {
continue;
@@ -591,8 +550,7 @@ void KX_ObstacleSimulationTOI_rays::sampleRVO(KX_Obstacle* activeObst, KX_NavMes
tc.toie[iter] = tmine;
}
- if (vlen(activeObst->vel) > 0.1)
- {
+ if (len_v2(activeObst->vel) > 0.1f) {
// Constrain max turn rate.
float cura = atan2(activeObst->vel[1],activeObst->vel[0]);
float da = bestDir - cura;
@@ -622,21 +580,20 @@ void KX_ObstacleSimulationTOI_rays::sampleRVO(KX_Obstacle* activeObst, KX_NavMes
///////////********* TOI_cells**********/////////////////
static void processSamples(KX_Obstacle* activeObst, KX_NavMeshObject* activeNavMeshObj,
- KX_Obstacles& obstacles, float levelHeight, const float vmax,
- const float* spos, const float cs, const int nspos, float* res,
- float maxToi, float velWeight, float curVelWeight, float sideWeight,
- float toiWeight)
+ KX_Obstacles& obstacles, float levelHeight, const float vmax,
+ const float* spos, const float cs, const int nspos, float* res,
+ float maxToi, float velWeight, float curVelWeight, float sideWeight,
+ float toiWeight)
{
vset(res, 0,0);
const float ivmax = 1.0f / vmax;
float adir[2] /*, adist */;
- vcpy(adir, activeObst->pvel);
- if (vlen(adir) > 0.01f)
- vnorm(adir);
- else
- vset(adir,0,0);
+ if (normalize_v2_v2(adir, activeObst->pvel) <= 0.01f) {
+ zero_v2(adir);
+ }
+
float activeObstPos[2];
vset(activeObstPos, activeObst->m_pos.x(), activeObst->m_pos.y());
/* adist = vdot(adir, activeObstPos); */
@@ -646,7 +603,7 @@ static void processSamples(KX_Obstacle* activeObst, KX_NavMeshObject* activeNavM
for (int n = 0; n < nspos; ++n)
{
float vcand[2];
- vcpy(vcand, &spos[n*2]);
+ copy_v2_v2(vcand, &spos[n * 2]);
// Find min time of impact and exit amongst all obstacles.
float tmin = maxToi;
@@ -666,9 +623,9 @@ static void processSamples(KX_Obstacle* activeObst, KX_NavMeshObject* activeNavM
float vab[2];
// Moving, use RVO
- vscale(vab, vcand, 2);
- vsub(vab, vab, activeObst->vel);
- vsub(vab, vab, ob->vel);
+ mul_v2_v2fl(vab, vcand, 2);
+ sub_v2_v2v2(vab, vab, activeObst->vel);
+ sub_v2_v2v2(vab, vab, ob->vel);
// Side
// NOTE: dp, and dv are constant over the whole calculation,
@@ -677,30 +634,31 @@ static void processSamples(KX_Obstacle* activeObst, KX_NavMeshObject* activeNavM
float pb[2];
vset(pb, ob->m_pos.x(), ob->m_pos.y());
- const float orig[2] = {0,0};
- float dp[2],dv[2],np[2];
- vsub(dp,pb,pa);
- vnorm(dp);
- vsub(dv,ob->dvel, activeObst->dvel);
+ const float orig[2] = {0, 0};
+ float dp[2], dv[2], np[2];
+ sub_v2_v2v2(dp, pb, pa);
+ normalize_v2(dp);
+ sub_v2_v2v2(dv, ob->dvel, activeObst->dvel);
- const float a = triarea(orig, dp,dv);
- if (a < 0.01f)
- {
+ /* TODO: use line_point_side_v2 */
+ if (area_tri_signed_v2(orig, dp, dv) < 0.01f) {
np[0] = -dp[1];
np[1] = dp[0];
}
- else
- {
+ else {
np[0] = dp[1];
np[1] = -dp[0];
}
- side += clamp(min(vdot(dp,vab)*2,vdot(np,vab)*2), 0.0f, 1.0f);
+ side += clamp(min(dot_v2v2(dp, vab),
+ dot_v2v2(np, vab)) * 2.0f, 0.0f, 1.0f);
nside++;
- if (!sweepCircleCircle(activeObst->m_pos, activeObst->m_rad, vab, ob->m_pos, ob->m_rad,
- htmin, htmax))
+ if (!sweepCircleCircle(MT_3D_AS_2D(activeObst->m_pos), activeObst->m_rad,
+ vab, MT_3D_AS_2D(ob->m_pos), ob->m_rad, htmin, htmax))
+ {
continue;
+ }
// Handle overlapping obstacles.
if (htmin < 0.0f && htmax > 0.0f)
@@ -729,14 +687,13 @@ static void processSamples(KX_Obstacle* activeObst, KX_NavMeshObject* activeNavM
// This can be handle more efficiently by using seg-seg test instead.
// If the whole segment is to be treated as obstacle, use agent->rad instead of 0.01f!
const float r = 0.01f; // agent->rad
- if (distPtSegSqr(activeObstPos, p, q) < sqr(r+ob->m_rad))
- {
+ if (dist_squared_to_line_segment_v2(activeObstPos, p, q) < sqr(r + ob->m_rad)) {
float sdir[2], snorm[2];
- vsub(sdir, q, p);
+ sub_v2_v2v2(sdir, q, p);
snorm[0] = sdir[1];
snorm[1] = -sdir[0];
// If the velocity is pointing towards the segment, no collision.
- if (vdot(snorm, vcand) < 0.0f)
+ if (dot_v2v2(snorm, vcand) < 0.0f)
continue;
// Else immediate collision.
htmin = 0.0f;
@@ -767,17 +724,16 @@ static void processSamples(KX_Obstacle* activeObst, KX_NavMeshObject* activeNavM
if (nside)
side /= nside;
- const float vpen = velWeight * (vdist(vcand, activeObst->dvel) * ivmax);
- const float vcpen = curVelWeight * (vdist(vcand, activeObst->vel) * ivmax);
+ const float vpen = velWeight * (len_v2v2(vcand, activeObst->dvel) * ivmax);
+ const float vcpen = curVelWeight * (len_v2v2(vcand, activeObst->vel) * ivmax);
const float spen = sideWeight * side;
const float tpen = toiWeight * (1.0f/(0.1f+tmin/maxToi));
const float penalty = vpen + vcpen + spen + tpen;
- if (penalty < minPenalty)
- {
+ if (penalty < minPenalty) {
minPenalty = penalty;
- vcpy(res, vcand);
+ copy_v2_v2(res, vcand);
}
}
}
@@ -786,7 +742,7 @@ void KX_ObstacleSimulationTOI_cells::sampleRVO(KX_Obstacle* activeObst, KX_NavMe
const float maxDeltaAngle)
{
vset(activeObst->nvel, 0.f, 0.f);
- float vmax = vlen(activeObst->dvel);
+ float vmax = len_v2(activeObst->dvel);
float* spos = new float[2*m_maxSamples];
int nspos = 0;
@@ -795,7 +751,7 @@ void KX_ObstacleSimulationTOI_cells::sampleRVO(KX_Obstacle* activeObst, KX_NavMe
{
const float cvx = activeObst->dvel[0]*m_bias;
const float cvy = activeObst->dvel[1]*m_bias;
- float vmax = vlen(activeObst->dvel);
+ float vmax = len_v2(activeObst->dvel);
const float vrange = vmax*(1-m_bias);
const float cs = 1.0f / (float)m_sampleRadius*vrange;
@@ -837,22 +793,27 @@ void KX_ObstacleSimulationTOI_cells::sampleRVO(KX_Obstacle* activeObst, KX_NavMe
{
for (int x = 0; x < rad; ++x)
{
- const float vx = res[0] + x*cs - half;
- const float vy = res[1] + y*cs - half;
- if (vx*vx+vy*vy > sqr(vmax+cs/2)) continue;
- spos[nspos*2+0] = vx;
- spos[nspos*2+1] = vy;
+ const float v_xy[2] = {
+ res[0] + x * cs - half,
+ res[1] + y * cs - half};
+
+ if (len_squared_v2(v_xy) > sqr(vmax + cs / 2))
+ continue;
+
+ copy_v2_v2(&spos[nspos * 2 + 0], v_xy);
nspos++;
}
}
- processSamples(activeObst, activeNavMeshObj, m_obstacles, m_levelHeight, vmax, spos, cs/2,
- nspos, res, m_maxToi, m_velWeight, m_curVelWeight, m_collisionWeight, m_toiWeight);
+ processSamples(activeObst, activeNavMeshObj, m_obstacles, m_levelHeight, vmax, spos, cs/2,
+ nspos, res, m_maxToi, m_velWeight, m_curVelWeight, m_collisionWeight, m_toiWeight);
cs *= 0.5f;
}
- vcpy(activeObst->nvel, res);
+ copy_v2_v2(activeObst->nvel, res);
}
+
+ delete [] spos;
}
KX_ObstacleSimulationTOI_cells::KX_ObstacleSimulationTOI_cells(MT_Scalar levelHeight, bool enableVisualization)
diff --git a/source/gameengine/Ketsji/KX_PolyProxy.h b/source/gameengine/Ketsji/KX_PolyProxy.h
index f02aa90998e..837e7f8354c 100644
--- a/source/gameengine/Ketsji/KX_PolyProxy.h
+++ b/source/gameengine/Ketsji/KX_PolyProxy.h
@@ -29,8 +29,8 @@
* \ingroup ketsji
*/
-#ifndef __KX_POLYROXY
-#define __KX_POLYPROXY
+#ifndef __KX_POLYPROXY_H__
+#define __KX_POLYPROXY_H__
#ifdef WITH_PYTHON
@@ -82,4 +82,4 @@ public:
#endif /* WITH_PYTHON */
-#endif /* __KX_POLYPROXY */
+#endif /* __KX_POLYPROXY_H__ */
diff --git a/source/gameengine/Ketsji/KX_PythonInit.cpp b/source/gameengine/Ketsji/KX_PythonInit.cpp
index 58996f7b86f..d8b4bf9e8bd 100644
--- a/source/gameengine/Ketsji/KX_PythonInit.cpp
+++ b/source/gameengine/Ketsji/KX_PythonInit.cpp
@@ -233,9 +233,8 @@ static char gPyExpandPath_doc[] =
path - the string path to convert.\n\n\
Use / as directory separator in path\n\
You can use '//' at the start of the string to define a relative path;\n\
-Blender replaces that string by the directory of the startup .blend or runtime\n\
-file to make a full path name (doesn't change during the game, even if you load\n\
-other .blend).\n\
+Blender replaces that string by the directory of the current .blend or runtime\n\
+file to make a full path name.\n\
The function also converts the directory separator to the local file system format.";
static PyObject *gPyExpandPath(PyObject *, PyObject *args)
@@ -1372,6 +1371,29 @@ static PyObject *gPyGetMipmapping(PyObject *)
return PyLong_FromLong(gp_Rasterizer->GetMipmapping());
}
+static PyObject *gPySetVsync(PyObject *, PyObject *args)
+{
+ int interval;
+
+ if (!PyArg_ParseTuple(args, "i:setVsync", &interval))
+ return NULL;
+
+ if (interval < VSYNC_OFF || interval > VSYNC_ADAPTIVE) {
+ PyErr_SetString(PyExc_ValueError, "Rasterizer.setVsync(value): value must be VSYNC_OFF, VSYNC_ON, or VSYNC_ADAPTIVE");
+ return NULL;
+ }
+
+ if (interval == VSYNC_ADAPTIVE)
+ interval = -1;
+ gp_Canvas->SetSwapInterval(interval);
+ Py_RETURN_NONE;
+}
+
+static PyObject *gPyGetVsync(PyObject *)
+{
+ return PyLong_FromLong(gp_Canvas->GetSwapInterval());
+}
+
static struct PyMethodDef rasterizer_methods[] = {
{"getWindowWidth",(PyCFunction) gPyGetWindowWidth,
METH_VARARGS, "getWindowWidth doc"},
@@ -1417,6 +1439,8 @@ static struct PyMethodDef rasterizer_methods[] = {
{"getFullScreen", (PyCFunction) gPyGetFullScreen, METH_NOARGS, ""},
{"setMipmapping", (PyCFunction) gPySetMipmapping, METH_VARARGS, ""},
{"getMipmapping", (PyCFunction) gPyGetMipmapping, METH_NOARGS, ""},
+ {"setVsync", (PyCFunction) gPySetVsync, METH_VARARGS, ""},
+ {"getVsync", (PyCFunction) gPyGetVsync, METH_NOARGS, ""},
{ NULL, (PyCFunction) NULL, 0, NULL }
};
@@ -2122,6 +2146,7 @@ void setupGamePython(KX_KetsjiEngine* ketsjiengine, KX_Scene *startscene, Main *
"'render':__import__('Rasterizer'), "
"'events':__import__('GameKeys'), "
"'constraints':__import__('PhysicsConstraints'), "
+ "'physics':__import__('PhysicsConstraints'),"
"'types':__import__('GameTypes'), "
"'texture':__import__('VideoTexture')});"
/* so we can do 'import bge.foo as bar' */
@@ -2130,6 +2155,7 @@ void setupGamePython(KX_KetsjiEngine* ketsjiengine, KX_Scene *startscene, Main *
"'bge.render':bge.render, "
"'bge.events':bge.events, "
"'bge.constraints':bge.constraints, "
+ "'bge.physics':bge.physics,"
"'bge.types':bge.types, "
"'bge.texture':bge.texture})"
);
@@ -2187,6 +2213,11 @@ PyObject *initRasterizer(RAS_IRasterizer* rasty,RAS_ICanvas* canvas)
KX_MACRO_addTypesToDict(d, RAS_MIPMAP_NEAREST, RAS_IRasterizer::RAS_MIPMAP_NEAREST);
KX_MACRO_addTypesToDict(d, RAS_MIPMAP_LINEAR, RAS_IRasterizer::RAS_MIPMAP_LINEAR);
+ /* for get/setVsync */
+ KX_MACRO_addTypesToDict(d, VSYNC_OFF, VSYNC_OFF);
+ KX_MACRO_addTypesToDict(d, VSYNC_ON, VSYNC_ON);
+ KX_MACRO_addTypesToDict(d, VSYNC_ADAPTIVE, VSYNC_ADAPTIVE);
+
// XXXX Add constants here
// Check for errors
diff --git a/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp b/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp
index 0604157a420..1a8fda0749a 100644
--- a/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp
+++ b/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp
@@ -1146,7 +1146,7 @@ void CcdPhysicsController::ApplyTorque(float torqueX,float torqueY,float torque
{
//workaround for incompatibility between 'DYNAMIC' game object, and angular factor
//a DYNAMIC object has some inconsistency: it has no angular effect due to collisions, but still has torque
- const btVector3& angFac = body->getAngularFactor();
+ const btVector3 angFac = body->getAngularFactor();
btVector3 tmpFac(1,1,1);
body->setAngularFactor(tmpFac);
body->applyTorque(torque);
@@ -1590,17 +1590,7 @@ bool CcdShapeConstructionInfo::SetMesh(RAS_MeshObject* meshobj, DerivedMesh* dm,
/* Can happen with ngons */
if (!tot_bt_verts) {
- m_shapeType = PHY_SHAPE_NONE;
- m_meshObject = NULL;
- m_vertexArray.clear();
- m_polygonIndexArray.clear();
- m_triFaceArray.clear();
- m_triFaceUVcoArray.clear();
- if (free_dm) {
- dm->release(dm);
- dm = NULL;
- }
- return false;
+ goto cleanup_empty_mesh;
}
m_vertexArray.resize(tot_bt_verts*3);
@@ -1679,17 +1669,7 @@ bool CcdShapeConstructionInfo::SetMesh(RAS_MeshObject* meshobj, DerivedMesh* dm,
/* Can happen with ngons */
if (!tot_bt_verts) {
- m_shapeType = PHY_SHAPE_NONE;
- m_meshObject = NULL;
- m_vertexArray.clear();
- m_polygonIndexArray.clear();
- m_triFaceArray.clear();
- m_triFaceUVcoArray.clear();
- if (free_dm) {
- dm->release(dm);
- dm = NULL;
- }
- return false;
+ goto cleanup_empty_mesh;
}
m_vertexArray.resize(tot_bt_verts*3);
@@ -1834,6 +1814,19 @@ bool CcdShapeConstructionInfo::SetMesh(RAS_MeshObject* meshobj, DerivedMesh* dm,
m_meshShapeMap.insert(std::pair<RAS_MeshObject*,CcdShapeConstructionInfo*>(meshobj,this));
}
return true;
+
+
+cleanup_empty_mesh:
+ m_shapeType = PHY_SHAPE_NONE;
+ m_meshObject = NULL;
+ m_vertexArray.clear();
+ m_polygonIndexArray.clear();
+ m_triFaceArray.clear();
+ m_triFaceUVcoArray.clear();
+ if (free_dm) {
+ dm->release(dm);
+ }
+ return false;
}
#include <cstdio>
diff --git a/source/gameengine/Rasterizer/RAS_2DFilterManager.cpp b/source/gameengine/Rasterizer/RAS_2DFilterManager.cpp
index bfe29a48c69..e85b57f1769 100644
--- a/source/gameengine/Rasterizer/RAS_2DFilterManager.cpp
+++ b/source/gameengine/Rasterizer/RAS_2DFilterManager.cpp
@@ -352,7 +352,7 @@ void RAS_2DFilterManager::UpdateOffsetMatrix(RAS_ICanvas* canvas)
}
}
-void RAS_2DFilterManager::UpdateCanvasTextureCoord(unsigned int * viewport)
+void RAS_2DFilterManager::UpdateCanvasTextureCoord(const int viewport[4])
{
/*
* This function update canvascoord[].
@@ -360,12 +360,10 @@ void RAS_2DFilterManager::UpdateCanvasTextureCoord(unsigned int * viewport)
* That way we can access the texcoord relative to the canvas:
* (0.0,0.0) bottom left, (1.0,1.0) top right, (0.5,0.5) center
*/
- canvascoord[0] = (GLfloat) viewport[0] / viewport[2];
- canvascoord[0] *= -1;
+ canvascoord[0] = (GLfloat) viewport[0] / -viewport[2];
canvascoord[1] = (GLfloat) (texturewidth - viewport[0]) / viewport[2];
- canvascoord[2] = (GLfloat) viewport[1] / viewport[3];
- canvascoord[2] *= -1;
+ canvascoord[2] = (GLfloat) viewport[1] / -viewport[3];
canvascoord[3] = (GLfloat)(textureheight - viewport[1]) / viewport[3];
}
@@ -396,14 +394,14 @@ void RAS_2DFilterManager::RenderFilters(RAS_ICanvas* canvas)
if (num_filters <= 0)
return;
- const GLint *viewport = canvas->GetViewPort();
+ const int *viewport = canvas->GetViewPort();
RAS_Rect rect = canvas->GetWindowArea();
int rect_width = rect.GetWidth()+1, rect_height = rect.GetHeight()+1;
if (texturewidth != rect_width || textureheight != rect_height)
{
UpdateOffsetMatrix(canvas);
- UpdateCanvasTextureCoord((unsigned int*)viewport);
+ UpdateCanvasTextureCoord(viewport);
need_tex_update = true;
}
@@ -432,7 +430,10 @@ void RAS_2DFilterManager::RenderFilters(RAS_ICanvas* canvas)
// We do this to make side-by-side stereo rendering work correctly with 2D filters. It would probably be nicer to just set the viewport,
// but it can be easier for writing shaders to have the coordinates for the whole screen instead of just part of the screen.
RAS_Rect scissor_rect = canvas->GetDisplayArea();
- glScissor(scissor_rect.GetLeft()+viewport[0], scissor_rect.GetBottom()+viewport[1], scissor_rect.GetWidth()+1, scissor_rect.GetHeight()+1);
+ glScissor(scissor_rect.GetLeft() + viewport[0],
+ scissor_rect.GetBottom() + viewport[1],
+ scissor_rect.GetWidth() + 1,
+ scissor_rect.GetHeight() + 1);
glDisable(GL_DEPTH_TEST);
// in case the previous material was wire
diff --git a/source/gameengine/Rasterizer/RAS_2DFilterManager.h b/source/gameengine/Rasterizer/RAS_2DFilterManager.h
index ba74018d36b..a637baa3d09 100644
--- a/source/gameengine/Rasterizer/RAS_2DFilterManager.h
+++ b/source/gameengine/Rasterizer/RAS_2DFilterManager.h
@@ -53,7 +53,7 @@ private:
void FreeTextures();
void UpdateOffsetMatrix(RAS_ICanvas* canvas);
- void UpdateCanvasTextureCoord(unsigned int * viewport);
+ void UpdateCanvasTextureCoord(const int viewport[4]);
float canvascoord[4];
float textureoffsets[18];
diff --git a/source/gameengine/Rasterizer/RAS_ICanvas.h b/source/gameengine/Rasterizer/RAS_ICanvas.h
index 1b1e43a5257..9e8a6e8ccf6 100644
--- a/source/gameengine/Rasterizer/RAS_ICanvas.h
+++ b/source/gameengine/Rasterizer/RAS_ICanvas.h
@@ -105,6 +105,17 @@ public:
void
SwapBuffers(
)=0;
+
+ virtual
+ void
+ SetSwapInterval(
+ int interval
+ )=0;
+
+ virtual
+ int
+ GetSwapInterval(
+ )=0;
virtual
void
diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageIM.cpp b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageIM.cpp
index 900d6f387ff..77bd540a039 100644
--- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageIM.cpp
+++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageIM.cpp
@@ -40,6 +40,7 @@ extern "C"{
}
RAS_StorageIM::RAS_StorageIM(int *texco_num, RAS_IRasterizer::TexCoGen *texco, int *attrib_num, RAS_IRasterizer::TexCoGen *attrib, int *attrib_layer) :
+ m_drawingmode(RAS_IRasterizer::KX_TEXTURED),
m_texco_num(texco_num),
m_attrib_num(attrib_num),
m_texco(texco),
diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageVA.cpp b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageVA.cpp
index 72af3852cf6..006c07b0491 100644
--- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageVA.cpp
+++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageVA.cpp
@@ -30,6 +30,7 @@
#include "GL/glew.h"
RAS_StorageVA::RAS_StorageVA(int *texco_num, RAS_IRasterizer::TexCoGen *texco, int *attrib_num, RAS_IRasterizer::TexCoGen *attrib, int *attrib_layer) :
+ m_drawingmode(RAS_IRasterizer::KX_TEXTURED),
m_texco_num(texco_num),
m_attrib_num(attrib_num),
m_last_texco_num(0),
diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageVBO.cpp b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageVBO.cpp
index c7779c209ba..06f85b143d2 100644
--- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageVBO.cpp
+++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageVBO.cpp
@@ -182,6 +182,7 @@ void VBO::Draw(int texco_num, RAS_IRasterizer::TexCoGen* texco, int attrib_num,
}
RAS_StorageVBO::RAS_StorageVBO(int *texco_num, RAS_IRasterizer::TexCoGen *texco, int *attrib_num, RAS_IRasterizer::TexCoGen *attrib, int *attrib_layer):
+ m_drawingmode(RAS_IRasterizer::KX_TEXTURED),
m_texco_num(texco_num),
m_attrib_num(attrib_num),
m_texco(texco),
diff --git a/source/gameengine/SceneGraph/SG_Tree.cpp b/source/gameengine/SceneGraph/SG_Tree.cpp
index 99f68ef625a..bef246533a6 100644
--- a/source/gameengine/SceneGraph/SG_Tree.cpp
+++ b/source/gameengine/SceneGraph/SG_Tree.cpp
@@ -37,13 +37,19 @@
#include "SG_Tree.h"
#include "SG_Node.h"
-SG_Tree::SG_Tree()
+SG_Tree::SG_Tree() :
+ m_left(NULL),
+ m_right(NULL),
+ m_parent(NULL),
+ m_radius(0.0),
+ m_client_object(NULL)
{
}
SG_Tree::SG_Tree(SG_Tree* left, SG_Tree* right) :
m_left(left),
m_right(right),
+ m_parent(NULL),
m_client_object(NULL)
{
if (m_left)
@@ -63,6 +69,7 @@ SG_Tree::SG_Tree(SG_Tree* left, SG_Tree* right) :
SG_Tree::SG_Tree(SG_Node* client) :
m_left(NULL),
m_right(NULL),
+ m_parent(NULL),
m_client_object(client)
{
m_bbox = SG_BBox(client->BBox(), client->GetWorldTransform());
diff --git a/source/gameengine/VideoTexture/BlendType.h b/source/gameengine/VideoTexture/BlendType.h
index 28eebe07789..561c6e8768f 100644
--- a/source/gameengine/VideoTexture/BlendType.h
+++ b/source/gameengine/VideoTexture/BlendType.h
@@ -38,7 +38,7 @@ template <class PyObj> class BlendType
{
public:
/// constructor
- BlendType (const char * name) : m_name(name) {}
+ BlendType (const char * name) : m_name(name), m_objType(NULL) {}
/// check blender type and return pointer to contained object or NULL (if type is not valid)
PyObj *checkType(PyObject *obj)
diff --git a/source/gameengine/VideoTexture/Exception.cpp b/source/gameengine/VideoTexture/Exception.cpp
index 0f571550205..804834af4cd 100644
--- a/source/gameengine/VideoTexture/Exception.cpp
+++ b/source/gameengine/VideoTexture/Exception.cpp
@@ -111,6 +111,8 @@ Exception::Exception (ExceptionID & expID, RESULT rslt, const char *fil, int lin
// set file and line
if (fil[0] != '\0' || lin > 0)
setFileLine (fil, lin);
+ else
+ m_line = -1;
}
diff --git a/source/gameengine/VideoTexture/FilterSource.h b/source/gameengine/VideoTexture/FilterSource.h
index 0289c88f056..bc80b2b36cc 100644
--- a/source/gameengine/VideoTexture/FilterSource.h
+++ b/source/gameengine/VideoTexture/FilterSource.h
@@ -164,7 +164,7 @@ class FilterYV12 : public FilterBase
{
public:
/// constructor
- FilterYV12 (void) {}
+ FilterYV12 (void): m_buffV(NULL), m_buffU(NULL), m_pitchUV(0) {}
/// destructor
virtual ~FilterYV12 (void) {}
diff --git a/source/gameengine/VideoTexture/ImageMix.h b/source/gameengine/VideoTexture/ImageMix.h
index e55b95834fa..161a8b375ea 100644
--- a/source/gameengine/VideoTexture/ImageMix.h
+++ b/source/gameengine/VideoTexture/ImageMix.h
@@ -43,7 +43,7 @@ class ImageSourceMix : public ImageSource
{
public:
/// constructor
- ImageSourceMix (const char *id) : ImageSource(id), m_weight(0x100) {}
+ ImageSourceMix (const char *id) : ImageSource(id), m_offset(0), m_weight(0x100) {}
/// destructor
virtual ~ImageSourceMix (void) {}
diff --git a/source/gameengine/VideoTexture/ImageRender.cpp b/source/gameengine/VideoTexture/ImageRender.cpp
index f184ab9bd1d..d83cd2dc6fd 100644
--- a/source/gameengine/VideoTexture/ImageRender.cpp
+++ b/source/gameengine/VideoTexture/ImageRender.cpp
@@ -70,7 +70,9 @@ ImageRender::ImageRender (KX_Scene *scene, KX_Camera * camera) :
m_owncamera(false),
m_observer(NULL),
m_mirror(NULL),
- m_clip(100.f)
+ m_clip(100.f),
+ m_mirrorHalfWidth(0.f),
+ m_mirrorHalfHeight(0.f)
{
// initialize background color
setBackground(0, 0, 255, 255);