Merging r58475 through r58700 from trunk into soc-2013-depsgraph_mt
authorSergey Sharybin <sergey.vfx@gmail.com>
Mon, 29 Jul 2013 02:49:36 +0000 (02:49 +0000)
committerSergey Sharybin <sergey.vfx@gmail.com>
Mon, 29 Jul 2013 02:49:36 +0000 (02:49 +0000)
253 files changed:
intern/cycles/app/cycles_test.cpp
intern/cycles/kernel/kernel_random.h
intern/cycles/util/util_view.cpp
release/datafiles/splash.png
release/scripts/startup/bl_ui/properties_data_modifier.py
release/scripts/startup/bl_ui/properties_object.py
release/scripts/startup/bl_ui/space_image.py
release/scripts/startup/bl_ui/space_sequencer.py
release/scripts/startup/bl_ui/space_view3d.py
release/scripts/startup/bl_ui/space_view3d_toolbar.py
source/blender/avi/intern/avi.c
source/blender/blenkernel/BKE_DerivedMesh.h
source/blender/blenkernel/BKE_blender.h
source/blender/blenkernel/BKE_bmesh.h [deleted file]
source/blender/blenkernel/BKE_context.h
source/blender/blenkernel/BKE_curve.h
source/blender/blenkernel/BKE_global.h
source/blender/blenkernel/BKE_pbvh.h
source/blender/blenkernel/BKE_sequencer.h
source/blender/blenkernel/BKE_text.h
source/blender/blenkernel/CMakeLists.txt
source/blender/blenkernel/intern/DerivedMesh.c
source/blender/blenkernel/intern/anim.c
source/blender/blenkernel/intern/anim_sys.c
source/blender/blenkernel/intern/camera.c
source/blender/blenkernel/intern/cdderivedmesh.c
source/blender/blenkernel/intern/cloth.c
source/blender/blenkernel/intern/context.c
source/blender/blenkernel/intern/curve.c
source/blender/blenkernel/intern/customdata.c
source/blender/blenkernel/intern/deform.c
source/blender/blenkernel/intern/editderivedmesh.c
source/blender/blenkernel/intern/mask.c
source/blender/blenkernel/intern/material.c
source/blender/blenkernel/intern/mesh.c
source/blender/blenkernel/intern/mesh_validate.c
source/blender/blenkernel/intern/modifiers_bmesh.c
source/blender/blenkernel/intern/movieclip.c
source/blender/blenkernel/intern/multires.c
source/blender/blenkernel/intern/object.c
source/blender/blenkernel/intern/pbvh.c
source/blender/blenkernel/intern/pbvh_bmesh.c
source/blender/blenkernel/intern/pbvh_intern.h
source/blender/blenkernel/intern/pointcache.c
source/blender/blenkernel/intern/property.c
source/blender/blenkernel/intern/sequencer.c
source/blender/blenkernel/intern/subsurf_ccg.c
source/blender/blenkernel/intern/text.c
source/blender/blenkernel/intern/texture.c
source/blender/blenlib/BLI_alloca.h [new file with mode: 0644]
source/blender/blenlib/BLI_array.h
source/blender/blenlib/BLI_bitmap.h
source/blender/blenlib/BLI_buffer.h
source/blender/blenlib/BLI_math_matrix.h
source/blender/blenlib/BLI_math_vector.h
source/blender/blenlib/BLI_path_util.h
source/blender/blenlib/BLI_string.h
source/blender/blenlib/BLI_string_utf8.h
source/blender/blenlib/CMakeLists.txt
source/blender/blenlib/intern/BLI_ghash.c
source/blender/blenlib/intern/fileops.c
source/blender/blenlib/intern/math_matrix.c
source/blender/blenlib/intern/math_vector_inline.c
source/blender/blenlib/intern/path_util.c
source/blender/blenlib/intern/storage.c
source/blender/blenlib/intern/string.c
source/blender/blenlib/intern/string_utf8.c
source/blender/blenloader/intern/readfile.c
source/blender/blenloader/intern/writefile.c
source/blender/bmesh/CMakeLists.txt
source/blender/bmesh/intern/bmesh_construct.c
source/blender/bmesh/intern/bmesh_construct.h
source/blender/bmesh/intern/bmesh_core.c
source/blender/bmesh/intern/bmesh_interp.c
source/blender/bmesh/intern/bmesh_mesh_conv.c
source/blender/bmesh/intern/bmesh_mods.c
source/blender/bmesh/intern/bmesh_opdefines.c
source/blender/bmesh/intern/bmesh_operators.c
source/blender/bmesh/intern/bmesh_operators.h
source/blender/bmesh/intern/bmesh_operators_private.h
source/blender/bmesh/intern/bmesh_polygon.c
source/blender/bmesh/intern/bmesh_polygon.h
source/blender/bmesh/intern/bmesh_queries.c
source/blender/bmesh/intern/bmesh_queries.h
source/blender/bmesh/operators/bmo_beautify.c
source/blender/bmesh/operators/bmo_bridge.c
source/blender/bmesh/operators/bmo_connect.c
source/blender/bmesh/operators/bmo_connect_nonplanar.c [new file with mode: 0644]
source/blender/bmesh/operators/bmo_connect_pair.c
source/blender/bmesh/operators/bmo_dissolve.c
source/blender/bmesh/operators/bmo_dupe.c
source/blender/bmesh/operators/bmo_fill_holes.c [new file with mode: 0644]
source/blender/bmesh/operators/bmo_join_triangles.c
source/blender/bmesh/operators/bmo_normals.c
source/blender/bmesh/operators/bmo_subdivide.c
source/blender/bmesh/operators/bmo_subdivide_edgering.c
source/blender/bmesh/operators/bmo_utils.c
source/blender/bmesh/tools/BME_bevel.c [deleted file]
source/blender/bmesh/tools/bmesh_bevel.c
source/blender/bmesh/tools/bmesh_decimate.h
source/blender/bmesh/tools/bmesh_decimate_dissolve.c
source/blender/bmesh/tools/bmesh_triangulate.c
source/blender/collada/ArmatureImporter.cpp
source/blender/compositor/intern/COM_SocketReader.h
source/blender/compositor/intern/COM_WorkScheduler.cpp
source/blender/compositor/operations/COM_ConvertColorToBWOperation.cpp
source/blender/compositor/operations/COM_ConvertColorToValueProg.cpp
source/blender/compositor/operations/COM_MathBaseOperation.cpp
source/blender/compositor/operations/COM_MixAddOperation.cpp
source/blender/compositor/operations/COM_MixBurnOperation.cpp
source/blender/compositor/operations/COM_MixColorOperation.cpp
source/blender/compositor/operations/COM_MixDarkenOperation.cpp
source/blender/compositor/operations/COM_MixDifferenceOperation.cpp
source/blender/compositor/operations/COM_MixDivideOperation.cpp
source/blender/compositor/operations/COM_MixDodgeOperation.cpp
source/blender/compositor/operations/COM_MixHueOperation.cpp
source/blender/compositor/operations/COM_MixLightenOperation.cpp
source/blender/compositor/operations/COM_MixLinearLightOperation.cpp
source/blender/compositor/operations/COM_MixOverlayOperation.cpp
source/blender/compositor/operations/COM_MixSaturationOperation.cpp
source/blender/compositor/operations/COM_MixScreenOperation.cpp
source/blender/compositor/operations/COM_MixSoftLightOperation.cpp
source/blender/compositor/operations/COM_MixSubtractOperation.cpp
source/blender/compositor/operations/COM_MixValueOperation.cpp
source/blender/editors/animation/anim_intern.h
source/blender/editors/animation/anim_markers.c
source/blender/editors/animation/keyframes_general.c
source/blender/editors/armature/armature_edit.c
source/blender/editors/armature/armature_relations.c
source/blender/editors/armature/armature_select.c
source/blender/editors/armature/armature_skinning.c
source/blender/editors/armature/armature_utils.c
source/blender/editors/armature/pose_select.c
source/blender/editors/armature/pose_utils.c
source/blender/editors/curve/curve_intern.h
source/blender/editors/curve/curve_ops.c
source/blender/editors/curve/editcurve.c
source/blender/editors/curve/editfont.c
source/blender/editors/include/BIF_glutil.h
source/blender/editors/include/ED_armature.h
source/blender/editors/include/ED_mesh.h
source/blender/editors/include/UI_interface.h
source/blender/editors/interface/interface.c
source/blender/editors/interface/interface_handlers.c
source/blender/editors/interface/interface_intern.h
source/blender/editors/interface/interface_ops.c
source/blender/editors/interface/interface_regions.c
source/blender/editors/mask/mask_add.c
source/blender/editors/mesh/editface.c
source/blender/editors/mesh/editmesh_add.c
source/blender/editors/mesh/editmesh_extrude.c
source/blender/editors/mesh/editmesh_knife.c
source/blender/editors/mesh/editmesh_select.c
source/blender/editors/mesh/editmesh_tools.c
source/blender/editors/mesh/editmesh_utils.c
source/blender/editors/mesh/mesh_data.c
source/blender/editors/mesh/mesh_intern.h
source/blender/editors/mesh/mesh_ops.c
source/blender/editors/mesh/meshtools.c
source/blender/editors/object/object_add.c
source/blender/editors/object/object_edit.c
source/blender/editors/object/object_hook.c
source/blender/editors/object/object_lattice.c
source/blender/editors/object/object_modifier.c
source/blender/editors/object/object_relations.c
source/blender/editors/render/render_opengl.c
source/blender/editors/render/render_shading.c
source/blender/editors/screen/area.c
source/blender/editors/screen/screen_ops.c
source/blender/editors/sculpt_paint/paint_hide.c
source/blender/editors/sculpt_paint/paint_image_proj.c
source/blender/editors/sculpt_paint/paint_ops.c
source/blender/editors/sculpt_paint/paint_vertex.c
source/blender/editors/sculpt_paint/paint_vertex_proj.c
source/blender/editors/sculpt_paint/sculpt.c
source/blender/editors/sculpt_paint/sculpt_intern.h
source/blender/editors/sculpt_paint/sculpt_undo.c
source/blender/editors/space_buttons/space_buttons.c
source/blender/editors/space_clip/tracking_ops.c
source/blender/editors/space_graph/graph_buttons.c
source/blender/editors/space_image/image_buttons.c
source/blender/editors/space_image/space_image.c
source/blender/editors/space_logic/logic_buttons.c
source/blender/editors/space_nla/nla_buttons.c
source/blender/editors/space_node/drawnode.c
source/blender/editors/space_node/node_add.c
source/blender/editors/space_node/node_buttons.c
source/blender/editors/space_node/node_intern.h
source/blender/editors/space_node/node_ops.c
source/blender/editors/space_node/node_relationships.c
source/blender/editors/space_node/node_toolbar.c
source/blender/editors/space_node/node_view.c
source/blender/editors/space_node/space_node.c
source/blender/editors/space_outliner/outliner_tree.c
source/blender/editors/space_sequencer/sequencer_buttons.c
source/blender/editors/space_sequencer/sequencer_edit.c
source/blender/editors/space_view3d/drawarmature.c
source/blender/editors/space_view3d/drawmesh.c
source/blender/editors/space_view3d/drawobject.c
source/blender/editors/space_view3d/space_view3d.c
source/blender/editors/space_view3d/view3d_buttons.c
source/blender/editors/space_view3d/view3d_edit.c
source/blender/editors/space_view3d/view3d_iterators.c
source/blender/editors/space_view3d/view3d_snap.c
source/blender/editors/space_view3d/view3d_toolbar.c
source/blender/editors/space_view3d/view3d_view.c
source/blender/editors/transform/transform.c
source/blender/editors/transform/transform.h
source/blender/editors/transform/transform_conversions.c
source/blender/editors/transform/transform_orientations.c
source/blender/editors/util/crazyspace.c
source/blender/editors/uvedit/uvedit_draw.c
source/blender/editors/uvedit/uvedit_ops.c
source/blender/editors/uvedit/uvedit_parametrizer.c
source/blender/editors/uvedit/uvedit_unwrap_ops.c
source/blender/gpu/intern/gpu_buffers.c
source/blender/gpu/intern/gpu_extensions.c
source/blender/imbuf/intern/indexer.c
source/blender/imbuf/intern/thumbs.c
source/blender/imbuf/intern/util.c
source/blender/makesdna/DNA_modifier_types.h
source/blender/makesrna/intern/rna_access.c
source/blender/makesrna/intern/rna_armature.c
source/blender/makesrna/intern/rna_color.c
source/blender/makesrna/intern/rna_mesh.c
source/blender/makesrna/intern/rna_modifier.c
source/blender/makesrna/intern/rna_nodetree.c
source/blender/makesrna/intern/rna_object.c
source/blender/modifiers/intern/MOD_bevel.c
source/blender/modifiers/intern/MOD_cloth.c
source/blender/modifiers/intern/MOD_mirror.c
source/blender/modifiers/intern/MOD_ocean.c
source/blender/modifiers/intern/MOD_simpledeform.c
source/blender/modifiers/intern/MOD_skin.c
source/blender/nodes/composite/nodes/node_composite_image.c
source/blender/nodes/texture/node_texture_tree.c
source/blender/python/intern/bpy_rna.c
source/blender/quicktime/apple/quicktime_export.c
source/blender/render/intern/source/external_engine.c
source/blender/windowmanager/intern/wm_event_system.c
source/blender/windowmanager/intern/wm_keymap.c
source/blender/windowmanager/intern/wm_operators.c
source/blenderplayer/bad_level_call_stubs/stubs.c
source/creator/creator.c
source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp
source/gameengine/BlenderRoutines/KX_BlenderRenderTools.cpp
source/gameengine/Expressions/FloatValue.cpp
source/gameengine/Expressions/IntValue.cpp
source/gameengine/GamePlayer/common/GPC_RenderTools.cpp
source/gameengine/GamePlayer/ghost/GPG_ghost.cpp
source/gameengine/Ketsji/KX_BlenderMaterial.cpp
source/gameengine/Ketsji/KX_BlenderMaterial.h
source/gameengine/Physics/Bullet/CcdPhysicsController.cpp

index 625e8cc1706b6aba2efb18edfc569b002cb26089..6d7c5912cb5a592fe3a1aa58f0c9ad9e62fb7760 100644 (file)
@@ -181,7 +181,7 @@ static void resize(int width, int height)
                options.session->reset(session_buffer_params(), options.session_params.samples);
 }
 
-void keyboard(unsigned char key)
+static void keyboard(unsigned char key)
 {
        if(key == 'r')
                options.session->reset(session_buffer_params(), options.session_params.samples);
index 6292adff6a5f76f6e428734857bf8680970d5181..c86ac34a057015b577bc9504af6efbaa95c9cb19 100644 (file)
@@ -141,11 +141,13 @@ __device_inline void path_rng_2D(KernelGlobals *kg, RNG *rng, int sample, int nu
                int p = *rng + dimension;
                cmj_sample_2D(sample, num_samples, p, fx, fy);
        }
+       else
 #endif
-
-       /* sobol */
-       *fx = path_rng_1D(kg, rng, sample, num_samples, dimension);
-       *fy = path_rng_1D(kg, rng, sample, num_samples, dimension + 1);
+       {
+               /* sobol */
+               *fx = path_rng_1D(kg, rng, sample, num_samples, dimension);
+               *fy = path_rng_1D(kg, rng, sample, num_samples, dimension + 1);
+       }
 }
 
 __device_inline void path_rng_init(KernelGlobals *kg, __global uint *rng_state, int sample, int num_samples, RNG *rng, int x, int y, float *fx, float *fy)
index 328c0c9739158d8791d0def85e7503d0d9df271d..d9934fa1356f2e6196c37dbe043d4e70257b3b4e 100644 (file)
@@ -136,7 +136,7 @@ static void view_keyboard(unsigned char key, int x, int y)
        }
 }
 
-void view_idle()
+static void view_idle(void)
 {
        if(V.redraw) {
                V.redraw = false;
index 3c05ba86cd32bbf6665678ecacb8e6e55c39952c..9551fad2fac3dc8888220ecd910dc0fed4b2540f 100644 (file)
Binary files a/release/datafiles/splash.png and b/release/datafiles/splash.png differ
index 89e90618383564efbcc94fba4886a77c8fdc1c7d..861d64382ef5d733821c9da38ebf28a51a3e04cd 100644 (file)
@@ -715,9 +715,11 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel):
         col = split.column()
         col.label(text="Origin:")
         col.prop(md, "origin", text="")
-        sub = col.column()
-        sub.active = (md.origin is not None)
-        sub.prop(md, "use_relative")
+
+        if md.deform_method in {'TAPER', 'STRETCH', 'TWIST'}:
+            col.label(text="Lock:")
+            col.prop(md, "lock_x")
+            col.prop(md, "lock_y")
 
         col = split.column()
         col.label(text="Deform:")
@@ -726,9 +728,6 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel):
         else:
             col.prop(md, "angle")
         col.prop(md, "limits", slider=True)
-        if md.deform_method in {'TAPER', 'STRETCH', 'TWIST'}:
-            col.prop(md, "lock_x")
-            col.prop(md, "lock_y")
 
     def SMOKE(self, layout, ob, md):
         layout.label(text="Settings can be found inside the Physics context")
index 31023d49340fd7dd8124360b36be88bea226b7c8..ec2492f73651cdb5d71de78e952c7e00e23145e0 100644 (file)
@@ -205,10 +205,20 @@ class OBJECT_PT_display(ObjectButtonsPanel, Panel):
         layout = self.layout
 
         obj = context.object
+        obj_type = obj.type
+        is_geometry = (obj_type in {'MESH', 'CURVE', 'SURFACE', 'META', 'FONT'})
+        is_empty_image = (obj_type == 'EMPTY' and obj.empty_draw_type == 'IMAGE')
 
         split = layout.split()
+
         col = split.column()
-        col.prop(obj, "draw_type", text="Type")
+        col.prop(obj, "show_name", text="Name")
+        col.prop(obj, "show_axis", text="Axis")
+        if is_geometry:
+            # Makes no sense for cameras, armatures, etc.!
+            col.prop(obj, "show_wire", text="Wire")
+        if obj_type == 'MESH':
+            col.prop(obj, "show_all_edges")
 
         col = split.column()
         row = col.row()
@@ -217,27 +227,24 @@ class OBJECT_PT_display(ObjectButtonsPanel, Panel):
         sub.active = obj.show_bounds
         sub.prop(obj, "draw_bounds_type", text="")
 
+        if is_geometry:
+            col.prop(obj, "show_texture_space", text="Texture Space")
+        col.prop(obj, "show_x_ray", text="X-Ray")
+        if obj_type == 'MESH' or is_empty_image:
+            col.prop(obj, "show_transparent", text="Transparency")
+
         split = layout.split()
 
         col = split.column()
-        col.prop(obj, "show_name", text="Name")
-        col.prop(obj, "show_axis", text="Axis")
-
-        obj_type = obj.type
-
-        if obj_type in {'MESH', 'CURVE', 'SURFACE', 'META', 'FONT'}:
-            # Makes no sense for cameras, armtures, etc.!
-            col.prop(obj, "show_wire", text="Wire")
-            # Only useful with object having faces/materials...
-            col.prop(obj, "color", text="Object Color")
+        if obj_type not in {'CAMERA', 'EMPTY'}:
+            col.label(text="Maximum draw type:")
+            col.prop(obj, "draw_type", text="")
 
         col = split.column()
-        col.prop(obj, "show_texture_space", text="Texture Space")
-        col.prop(obj, "show_x_ray", text="X-Ray")
-        if obj_type == 'MESH' or (obj_type == 'EMPTY' and obj.empty_draw_type == 'IMAGE'):
-            col.prop(obj, "show_transparent", text="Transparency")
-        if obj_type == 'MESH':
-            col.prop(obj, "show_all_edges")
+        if is_geometry or is_empty_image:
+            # Only useful with object having faces/materials...
+            col.label(text="Object Color:")
+            col.prop(obj, "color", text="")
 
 
 class OBJECT_PT_duplication(ObjectButtonsPanel, Panel):
index eb0d9c5082dfb34d075f091b01402032de09613a..22e2e6e08a2a533cbe16edbbb858cbffccc42462 100644 (file)
@@ -232,6 +232,7 @@ class IMAGE_MT_uvs_snap(Menu):
 
         layout.operator("uv.snap_selected", text="Selected to Pixels").target = 'PIXELS'
         layout.operator("uv.snap_selected", text="Selected to Cursor").target = 'CURSOR'
+        layout.operator("uv.snap_selected", text="Selected to Cursor (Offset)").target = 'CURSOR_OFFSET'
         layout.operator("uv.snap_selected", text="Selected to Adjacent Unselected").target = 'ADJACENT_UNSELECTED'
 
         layout.separator()
index 3477353ba0dc0a04e7d4838e210c30be13fd3892..791916370805667f73de27626e65a8ddddc05763 100644 (file)
@@ -671,13 +671,14 @@ class SEQUENCER_PT_sound(SequencerButtonsPanel, Panel):
         layout.separator()
         layout.prop(strip, "filepath", text="")
 
-        row = layout.row()
-        if sound.packed_file:
-            row.operator("sound.unpack", icon='PACKAGE', text="Unpack")
-        else:
-            row.operator("sound.pack", icon='UGLYPACKAGE', text="Pack")
+        if sound is not None:
+            row = layout.row()
+            if sound.packed_file:
+                row.operator("sound.unpack", icon='PACKAGE', text="Unpack")
+            else:
+                row.operator("sound.pack", icon='UGLYPACKAGE', text="Pack")
 
-        row.prop(sound, "use_memory_cache")
+            row.prop(sound, "use_memory_cache")
 
         layout.prop(strip, "show_waveform")
         layout.prop(strip, "volume")
index 19095df6a14147e4e1e416d338c7ff50adbd4d43..689b1a9c9b7290310968cc1d5e779944b376a27e 100644 (file)
@@ -1822,6 +1822,7 @@ class VIEW3D_MT_edit_mesh(Menu):
         layout.menu("VIEW3D_MT_edit_mesh_edges")
         layout.menu("VIEW3D_MT_edit_mesh_faces")
         layout.menu("VIEW3D_MT_edit_mesh_normals")
+        layout.menu("VIEW3D_MT_edit_mesh_clean")
 
         layout.separator()
 
@@ -2084,6 +2085,16 @@ class VIEW3D_MT_edit_mesh_normals(Menu):
         layout.operator("mesh.flip_normals")
 
 
+class VIEW3D_MT_edit_mesh_clean(Menu):
+    bl_label = "Clean"
+
+    def draw(self, context):
+        layout = self.layout
+
+        layout.operator("mesh.fill_holes")
+        layout.operator("mesh.vert_connect_nonplanar")
+
+
 class VIEW3D_MT_edit_mesh_delete(Menu):
     bl_label = "Delete"
 
@@ -2197,7 +2208,9 @@ class VIEW3D_MT_edit_curve_specials(Menu):
         layout.operator("curve.spline_weight_set")
         layout.operator("curve.radius_set")
         layout.operator("curve.smooth")
+        layout.operator("curve.smooth_weight")
         layout.operator("curve.smooth_radius")
+        layout.operator("curve.smooth_tilt")
 
 
 class VIEW3D_MT_edit_curve_showhide(ShowHideMenu, Menu):
index 1383775042d97532594a8c8b5f4df2447901495c..f253801f431363db8c50c3888d61a6497c6700d4 100644 (file)
@@ -277,7 +277,6 @@ class VIEW3D_PT_tools_curveedit(View3DPanel, Panel):
         col.operator("curve.switch_direction")
         col.operator("curve.spline_type_set")
         col.operator("curve.radius_set")
-        col.operator("curve.smooth_radius")
 
         col = layout.column(align=True)
         col.label(text="Handles:")
index 48e64695822965e817c1189a9d6e72bdc8c78af3..6f819d438df21f18238b36d5d070c6c5804dc5fd 100644 (file)
@@ -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;
 }
 
index 40fc71e82ca8f360791f6814e9adc8dfa4e9ceb1..8396380fd06d4aa1922c61ace0399b05227564fb 100644 (file)
@@ -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.
         *
index 8c556e00aaaf01cdf8f2c6555d89be6e353cb96a..a0c2908a646a5408c50ebf89a3c983b09ba9ebe5 100644 (file)
@@ -42,7 +42,7 @@ 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      1
 
 /* 262 was the last editmesh release but it has compatibility code for bmesh data */
 #define BLENDER_MINVERSION      262
@@ -50,7 +50,7 @@ extern "C" {
 
 /* used by packaging tools */
 /* can be left blank, otherwise a,b,c... etc with no quotes */
-#define BLENDER_VERSION_CHAR   
+#define BLENDER_VERSION_CHAR   a
 /* alpha/beta/rc/release, docs use this */
 #define BLENDER_VERSION_CYCLE   alpha
 
diff --git a/source/blender/blenkernel/BKE_bmesh.h b/source/blender/blenkernel/BKE_bmesh.h
deleted file mode 100644 (file)
index 0dfab26..0000000
+++ /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
index 285077f258c9d904888a8f10faba26a8046fccb1..c6a6b0672d1365252b82d86dccbe525b4c7cdb43 100644 (file)
@@ -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);
index 08e40c8509a69b2683abb43f2369e75c723eff69..6e78cf681e136cf6e57ff2ceed2ad6f8a95327c5 100644 (file)
@@ -140,6 +140,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);
index 0699344a8878c24d08062a936d58ad8b9d64b7af..9d33af1a0f4224816d0525184533bcbbc0fc6348 100644 (file)
@@ -46,7 +46,6 @@ extern "C" {
 /* forwards */
 struct Main;
 struct Object;
-struct BME_Glob;
 
 typedef struct Global {
 
index 48c16f8db388bd604dc74947cab165016d00a0de..7d3d8d7dcbd325394af071d44a2efdc030f00d65 100644 (file)
@@ -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;
index 4494d127082091e498b0966b19523194f0662510..78018f044582057860b95cc08248905624a550f0 100644 (file)
@@ -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);
 
index 2406fa51c8462b7fc950686e37d0eba1c35ca67c..24fd763d0784c42b96ca0b9b48f13151c202d591 100644 (file)
@@ -86,7 +86,6 @@ void  txt_sel_all                     (struct Text *text);
 void   txt_sel_line            (struct Text *text);
 char   *txt_sel_to_buf         (struct Text *text);
 void   txt_insert_buf          (struct Text *text, const char *in_buffer);
-void   txt_print_undo          (struct Text *text);
 void   txt_undo_add_op         (struct Text *text, int op);
 void   txt_do_undo                     (struct Text *text);
 void   txt_do_redo                     (struct Text *text);
@@ -106,6 +105,10 @@ int                txt_setcurr_tab_spaces(struct Text *text, int space);
 bool   txt_cursor_is_line_start(struct Text *text);
 bool   txt_cursor_is_line_end(struct Text *text);
 
+#if 0
+void   txt_print_undo          (struct Text *text);
+#endif
+
 /* utility functions, could be moved somewhere more generic but are python/text related  */
 int text_check_bracket(const char ch);
 int text_check_delim(const char ch);
index 2f51f9f17feec66a2e4fcbeff3f2192ea78394db..655e0d65133a5aaced5d1861b98658f7a8cd8e2f 100644 (file)
@@ -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
index b11f88d5260147d089a8b720161d368829644ada..5fd49542c2863d619716dfaa31dfb6dd3fa77d59 100644 (file)
@@ -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"
 #include "BLI_threads.h"
index b817236781de5479eb3710454f40ac616b0f1fa0..1b1bcffb4932ca79c830e9bc865001fe35d1da6a 100644 (file)
@@ -1034,7 +1034,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++) {
index 001964087b8ba12a0581b8f38993fd07b6fac79b..4b05b0800a50c4ec6b3446d0a6101f72514d83bf 100644 (file)
@@ -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"
index a47cab7f2361f18301df4a813f5b8d054ee1d1ed..e86561d687d200211a61a280e598adc6ef699ed1 100644 (file)
@@ -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;
index d692e8e0cf77e74e32427bfb03cdcf0bb7b8e5ca..ffb33dbf3c7b20e95ddca4de752c30f1702d6e2e 100644 (file)
@@ -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);
index a7311d5efc73bb0a77ed6eea4bd2c0b02150d11c..05ffd4a626571ea3abf1cac5ad0a0d479b05bf6c 100644 (file)
@@ -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
index bbf254cd7d12b011231a0bc02f443ad225850a44..622b4f6df5a23a2e5a9ec8d17f1bc086dac1e3ed 100644 (file)
@@ -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';
 }
index 288d8917dc89e1b48b1c5cdc0b00e1c0524451d1..838774a9d80d3de38be683b9cb6b225015e70a41 100644 (file)
@@ -721,6 +721,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 ~~~~~~~~~~~ */
 
 
index 92b3c26c91ac36290c0c963bf6e01d1a331a6a6a..d69ec6a9597803205182612f9ccf666ce209fca8 100644 (file)
@@ -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)
index 0dd9d8550bb75af1e924cb3ccbfd03d1a2ed83d4..882085aa5db125623f983c3779b4b7c95924f214 100644 (file)
@@ -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") */
index ddd5e4a1e02ebaea472c371126d91f084bebd9b8..feb18c3babeeeaab8522b4b96b755506c066d054 100644 (file)
@@ -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,9 +1060,9 @@ 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}}};
        GPUVertexAttribs gattribs;
@@ -936,6 +1070,12 @@ static void emDM_drawMappedFacesMat(DerivedMesh *dm,
 
        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);
 
index b3c5ceefb2d53bf655c8d5494ad0eb528207db68..21e7fb3116e92c3d9a7f95cd380d291b82842f12 100644 (file)
@@ -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) {
index 5f9aafa219f14d7f70e310d16d753e9beadff8e9..4abeb8389d6566cbd80516a8e7c07ac4f27e6fff 100644 (file)
@@ -1148,55 +1148,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 +1176,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) {
index 49827a5df22c74b16216c862e76a7915d2874541..f1729b8e098c65ab8f94bdfbbeb83e17fbaa0fc1 100644 (file)
@@ -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"
index 878651cdb395fc039226258bbe551305490b16ab..2eced15a147b791fbe581e41b6b83df9586c8fe0 100644 (file)
@@ -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
 
index b7257028316a6e509d3cdb157f7ee03cebcbd153..290b0684e4047ea0656df99b7782e05399ea13ed 100644 (file)
  *  \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 */
index ef3b7ca0bdf7fbe6e23754df8ab1b72228c006e1..e8550e12e4f29a129e89bd7d4c668ee3b4c92d64 100644 (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);
index cba4c9206c948d07c5a33ea1968d2ef5b280281f..95bf56d00f2969ca30122b6077015e491ecc67f2 100644 (file)
@@ -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);
 
@@ -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);
index a2a67b7c6ffaa781a3e0aaa1f1bbf86f483e5a0b..ffc79c3ac5cb5def7c076a94981daa181b14d369 100644 (file)
@@ -722,6 +722,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;
index 99e6e898685cc63b20294019f251d080b4aaa67a..a0cc37dcf3f676c2788bcb45da060512fe3f07d8 100644 (file)
@@ -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;
@@ -1253,7 +1253,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;
@@ -1469,7 +1469,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 +1664,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;
 
index c6a5552dbf78de2bfc806d2743e0a0fc77a21b30..cd21f8ad96805fa1a1a51aa4e8a4cb1d769cace3 100644 (file)
@@ -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);
index b3f7bf6e3d16f58a90af71b28bcd430dfef0a69f..4154b8e4799e4def4037729f6dec4d831c26330d 100644 (file)
@@ -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;
index 06748dfc44d63e08e87c5e8f6fd827d0dfadfbb2..41b9734315d1dde65ade0ab7cf718a7afb7f5954 100644 (file)
@@ -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;
        }
 
index ec23a7db8a1bfbb981ae70ff2a4d41e551b6c491..73f2a864e32ac296b8e056410ea89da9405be937 100644 (file)
@@ -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));
index b080cfcff2f63bdeb2d61f61e044bb303a62ed01..34b19e3f357163f8fe5ae603bedea37e6a24959a 100644 (file)
@@ -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)
index 26a5dada108e490299046d317b8ca256e433c3f9..cc33727030af0bcc7c8bf1b124273222785f55b8 100644 (file)
@@ -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;
        
index f1b4626ec734ecfc9668d9921117f8d14f2a15d5..f0c01e2559810bfae8aae2e1a7abf8707793825a 100644 (file)
@@ -1496,6 +1496,7 @@ static int max_undo_test(Text *text, int x)
        return 1;
 }
 
+#if 0  /* UNUSED */
 static void dump_buffer(Text *text) 
 {
        int i = 0;
@@ -1660,6 +1661,7 @@ void txt_print_undo(Text *text)
                i++;
        }
 }
+#endif
 
 static void txt_undo_store_uint16(char *undo_buf, int *undo_pos, unsigned short value) 
 {
@@ -2357,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;
        
@@ -2366,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);
        
@@ -2620,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;
@@ -2683,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) {
index 1d0b0deae7ed4c2d0445be8cc3e92cd4813f0233..e2b7358525ac449350c17adf070cdeec898e672e 100644 (file)
@@ -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/blenlib/BLI_alloca.h b/source/blender/blenlib/BLI_alloca.h
new file mode 100644 (file)
index 0000000..b93f5b7
--- /dev/null
@@ -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__ */
index 3fb50afdeac396dddd01fb7831d102cd929806ba..ef5cb8bde04f7660cba0d7374836feee1956eaf2 100644 (file)
 #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)                \
@@ -172,31 +173,4 @@ void _bli_array_grow_func(void **arr_p, const void *arr_static,
                MEM_freeN(arr);                                                       \
        } (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)
-
-#else
-#define BLI_array_alloca(arr, realsize) \
-       alloca(sizeof(*arr) * (realsize))
-
-#define BLI_array_alloca_and_count(arr, realsize) \
-       alloca(sizeof(*arr) * (realsize));  \
-       const int _##arr##_count = (realsize)
-#endif
-
 #endif  /* __BLI_ARRAY_H__ */
index 02e5d6bd79705df3fe5cc0d7ab88272bf2dedab6..ca98d28cc402167c50344a1f5ba0bc33c78b2ac4 100644 (file)
@@ -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' */
index fe835e7cadc85c602a2312f92397d0b0f8e72b38..879ef8696530522b132b42c5801fd7b3b41e0c40 100644 (file)
@@ -53,7 +53,7 @@ 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) ? \
index 723122d7814cfc348e950873182df860a5e8b0f4..a4b0f449dc3242a62e2298d5d8ecee33c37b3102 100644 (file)
@@ -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 pivot_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 ***********************************/
 
index 304e2ea7fde62f2f572d6f2bb9188f81d347efae..6be679a90b6200d74f53790a7c8a2810dd49b6a7 100644 (file)
@@ -116,6 +116,9 @@ 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_m3_v3_single_x(float M[3][3], const float a[3]);
+MINLINE float mul_m3_v3_single_y(float M[3][3], const float a[3]);
+MINLINE float mul_m3_v3_single_z(float M[3][3], const float a[3]);
 
 MINLINE void madd_v3_v3fl(float r[3], const float a[3], float f);
 MINLINE void madd_v3_v3v3(float r[3], const float a[3], const float b[3]);
index e0a34e35acc99db45beabbbf6312e62acde96e07..cb812fe8595e85445e00b7c633d4aecda0477882 100644 (file)
@@ -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 {
index 02eb0734f8cf6a6bcc56d232de72b2037410c351..4816ac19fce9299b0e78fb5c2bb074ed02b2ba27 100644 (file)
@@ -86,7 +86,7 @@ __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__((warn_unused_result))
 __attribute__((nonnull))
index adef843d2cc18ff439fa5252d9637a7dc06a5bd9..db32190494aa6fdf1141b77b6d4956becbb2f284 100644 (file)
 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
index 3ae6e8f96564451b539ead86155591e52a9c5a67..f5d6af107a51f6d996508755d14418a416ce83b5 100644 (file)
@@ -100,6 +100,7 @@ set(SRC
        intern/winstuff.c
 
        BLI_args.h
+       BLI_alloca.h
        BLI_array.h
        BLI_bitmap.h
        BLI_blenlib.h
index d30d3f3d256a6a04a730e8b2e512dc8031d89b20..10b3c01d2741c0ec14d140a8260d36aad3c993e1 100644 (file)
@@ -34,6 +34,7 @@
 
 #include <string.h>
 #include <stdlib.h>
+#include <limits.h>
 
 #include "MEM_guardedalloc.h"
 
@@ -255,22 +256,14 @@ void BLI_ghash_free(GHash *gh, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfreef
 GHashIterator *BLI_ghashIterator_new(GHash *gh)
 {
        GHashIterator *ghi = MEM_mallocN(sizeof(*ghi), "ghash iterator");
-       ghi->gh = gh;
-       ghi->curEntry = NULL;
-       ghi->curBucket = (unsigned int)-1;
-       while (!ghi->curEntry) {
-               ghi->curBucket++;
-               if (ghi->curBucket == ghi->gh->nbuckets)
-                       break;
-               ghi->curEntry = ghi->gh->buckets[ghi->curBucket];
-       }
+       BLI_ghashIterator_init(ghi, gh);
        return ghi;
 }
 void BLI_ghashIterator_init(GHashIterator *ghi, GHash *gh)
 {
        ghi->gh = gh;
        ghi->curEntry = NULL;
-       ghi->curBucket = (unsigned int)-1;
+       ghi->curBucket = UINT_MAX;  /* wraps to zero */
        while (!ghi->curEntry) {
                ghi->curBucket++;
                if (ghi->curBucket == ghi->gh->nbuckets)
index 26b9e08c7f66386924a5dc126323038c5c2c2e44..4809ba59aaf7c4412310ffea5fc79c7afd667bc8 100644 (file)
@@ -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);
 }
index 312805e23f64c301be5fe962fd1fa1d01f0f385c..8565698110e26fc6fe396431465ba9f9ab354d4e 100644 (file)
@@ -930,7 +930,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 +944,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 +959,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 +974,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 +989,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 +1374,21 @@ void rotate_m2(float mat[2][2], const float angle)
        mat[1][0] = -mat[0][1];
 }
 
+/* scale or rotate around a non zero pivot */
+void pivot_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 +1434,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... */
index d77b1ecf0175e90c4b66417038c1ef8481704436..eff735ef8d53770ad55aa3935c1743918deacc61 100644 (file)
@@ -418,6 +418,18 @@ MINLINE float mul_project_m4_v3_zfac(float mat[4][4], const float co[3])
               (mat[2][3] * co[2]) + mat[3][3];
 }
 
+MINLINE float mul_m3_v3_single_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 mul_m3_v3_single_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 mul_m3_v3_single_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)
 {
index c5205ed5d1885c64bdabf393bea0bb735f5c0d46..2c06a812c8a1edc04f7d2ce9fbb3a4a151e9a0e3 100644 (file)
@@ -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;
@@ -1688,6 +1690,26 @@ void BLI_split_file_part(const char *string, char *file, const size_t filelen)
        BLI_split_dirfile(string, NULL, file, 0, 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;
index aeeae000fff18e433786e5325c6dbc6bfdc2221b..34c6e6321311e4c5254df4f2ea002afb59cab4a9 100644 (file)
@@ -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);
index cb0d4ae307d1a5ea775ef7a88032c20cbbe1a272..572b142d04468570ce500c344ce0ec71ca767ffe 100644 (file)
@@ -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 
index d435ed8f6e7730c7ce1000d0eb86bd76ef65483f..225b3c5538f7d37123447e2579dbaa63c03cc224 100644 (file)
@@ -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;
 }
 
index 33bf44c9843baad69134674ae4949e9d085ec1e8..e71b3c644599f66c1f4a7e0f736b7e4f9162c713 100644 (file)
@@ -5801,21 +5801,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;
 }
 
@@ -9485,7 +9487,13 @@ 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);
+               }
+       }
+       
        {
                bScreen *sc;
                Object *ob;
index dd4361be1ff704ce64b64e5797fda502181d7756..e170107713c7836f964fd1ec4f6a4a5f08fef573 100644 (file)
@@ -1660,8 +1660,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);
index b3dd2f57523fa19941db5149aaf9b71a4d2d4a4a..228ebcb96c46398e583d3ae8efd46b1e69cc946a 100644 (file)
@@ -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
index 1af4836c225ef867e294922708a1a3925fbd8782..1f7ace1ba6dbf9aa20ae46e25f0241f200bb0f19 100644 (file)
@@ -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);
 }
 
 
@@ -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 *UNUSED(bm_src), BMesh *bm_dst, const void *ele_src_v, void *ele_dst_v)
+{
+       const BMHeader *ele_src = ele_src_v;
+       BMHeader *ele_dst = ele_dst_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);
 
index 3dcb1eb1ccb68cf28e00b60a541a4b9804e3b788..9552ef6f5a4ad5dfb31547b5c65f1720080162d4 100644 (file)
@@ -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_src, BMesh *bm_dst, const void *ele_src_v, void *ele_dst_v);
 
 void   BM_mesh_copy_init_customdata(BMesh *bm_dst, BMesh *bm_src, const struct BMAllocTemplate *allocsize);
 BMesh *BM_mesh_copy(BMesh *bm_old);
index 05c462ac672df3bac91a9663e7fb319ba8eb9005..f9e711a0dc3bf13f0fa3220e3d170111203878e3 100644 (file)
@@ -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,6 +1413,7 @@ 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;
@@ -1470,6 +1477,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 +1516,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 +1564,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 +1575,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 +1591,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 +1661,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 +1681,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) {
index 446d32de5d2805cafff575ab50691651456dc8d4..3e8a49a01fcdf4e53b27226c0cd3fd6bc97f6c42 100644 (file)
@@ -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"
index 7c4af8eaa3b745ed00782c5f96dac451904b53ce..81d4aad0fdfd58c5f2515fff14c8be3e7b610db4 100644 (file)
@@ -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;
 
index cb8e9bd70040d9fa343781bd9f054000fb8f176b..418fc16ea558cc9f8395a4a524b0fb3254838f97 100644 (file)
@@ -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) {
index 497c9e1c153d6ff80329754a71f5b124144ffa9a..4f8a851c7802aea7f2f75c9e7a61caa86d47a378 100644 (file)
@@ -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'}},
        },
@@ -839,6 +867,27 @@ static BMOpDefine bmo_connect_verts_def = {
        BMO_OPTYPE_FLAG_UNTAN_MULTIRES | BMO_OPTYPE_FLAG_NORMALS_CALC | BMO_OPTYPE_FLAG_SELECT_FLUSH,
 };
 
+/*
+ * 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.
  *
@@ -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,
index 63c00d5b5456e0cdf92b31cc061c12f8ebaf01e0..269501e1f02182cea052a7db80e4bccf87b46338 100644 (file)
@@ -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);
index 4c6129cf43fcb2cfd357af0243b0c1c5cfd37c96..56d63694d88598b2b9748400069f957590791fc5 100644 (file)
@@ -49,9 +49,9 @@ enum {
 };
 
 enum {
+       SUBDIV_SELECT_NONE,
        SUBDIV_SELECT_ORIG,
        SUBDIV_SELECT_INNER,
-       SUBDIV_SELECT_INNER_SEL,
        SUBDIV_SELECT_LOOPCUT
 };
 
index e6a4760060c2d7ced6560879829afa1f7b862f8f..33c10411c0f49684924663d36b611439f752bb33 100644 (file)
@@ -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);
index 88186df89fb7c2a298678951d708b5033fa5f936..297458eb1d698b925b51459544eb88c9a0906794 100644 (file)
@@ -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"
 
@@ -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,22 +133,40 @@ 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.
  *
@@ -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);
 }
 
 /**
@@ -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
  *
index 2f6b54b91d307425f6b19b3d916645489b32e3cf..91fe94f8e48aa184a5ca52221554f4c99dbfb324 100644 (file)
@@ -34,16 +34,18 @@ int   BM_face_calc_tessellation(BMFace *f, BMLoop **r_loops, int (*r_index)[3])
 #endif
 ;
 void  BM_face_calc_normal(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);
 
index ef5ed06b61a5f0b80fc41fc85810ddaeb48950d9..de601b1905267bf12eb8c4726bd33ce2737023fb 100644 (file)
@@ -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"
@@ -338,16 +338,16 @@ bool BM_verts_in_face(BMFace *f, BMVert **varr, int len)
  */
 bool BM_edge_in_face(BMFace *f, BMEdge *e)
 {
-       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;
 }
@@ -1758,20 +1758,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],
-                             void *user_data, bool (*filter_fn)(BMEdge *, void *user_data))
+                             BMElemFilterFunc filter_fn, void *user_data,
+                             const char hflag_test, const char htype_step)
 {
 #ifdef DEBUG
        int group_index_len = 1;
@@ -1786,11 +1793,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,28 +1805,38 @@ int BM_mesh_calc_face_groups(BMesh *bm, int *r_groups_array, int (**r_group_inde
 
        STACK_INIT(group_array);
 
+       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;
                        }
@@ -1833,36 +1850,193 @@ 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_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 == 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(stack, f_other);
+                                                       }
+                                               } while ((l_radial_iter = l_radial_iter->radial_next) != l_iter);
+                                       }
+                               } while ((l_iter = l_iter->next) != l_first);
+                       }
+
+                       if (htype_step & BM_VERT) {
+                               BMIter liter;
+                               /* search for other faces */
+                               l_iter = l_first = BM_FACE_FIRST_LOOP(f);
+                               do {
+                                       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(stack, f_other);
+                                                       }
+                                               }
+                                       }
+                               } while ((l_iter = l_iter->next) != l_first);
+                       }
+               }
+
+               group_curr++;
+       }
+
+       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_FACE;
+
+       /* 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 faces */
-                       l_iter = l_first = BM_FACE_FIRST_LOOP(f);
-                       do {
-                               BMLoop *l_other = l_iter->radial_next;
-                               if ((l_other != l_iter) && filter_fn(l_iter->e, user_data)) {
-                                       if (BM_elem_flag_test(l_other->f, BM_ELEM_TAG) == false) {
-                                               BM_elem_flag_enable(l_other->f, BM_ELEM_TAG);
-                                               STACK_PUSH(fstack, l_other->f);
+                       /* 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);
+                                               }
                                        }
                                }
-                       } while ((l_iter = l_iter->next) != l_first);
+                       }
                }
 
                group_curr++;
        }
 
-       MEM_freeN(fstack);
+       MEM_freeN(stack);
 
        /* reduce alloc to required size */
        group_index = MEM_reallocN(group_index, sizeof(*group_index) * group_curr);
index 94dae1d1d239cb28044a76bc0e8c113369316b45..23d89cf92faf41fa0f4cb33004e135aae2e8449c 100644 (file)
@@ -27,6 +27,8 @@
  *  \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);
@@ -115,8 +117,13 @@ bool BM_face_is_any_vert_flag_test(BMFace *f, const char hflag);
 bool BM_face_is_any_edge_flag_test(BMFace *f, const char hflag);
 
 float BM_mesh_calc_volume(BMesh *bm, bool is_signed);
+
 int   BM_mesh_calc_face_groups(BMesh *bm, int *r_groups_array, int (**r_group_index)[2],
-                               void *user_data, bool (*filter_fn)(BMEdge *, void *user_data));
+                               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);
index 2c0bc7f95d9bd2f44a44edbcd0dbac3bf111d3b3..22b686db64e1cf143f60253c722c0f802591cd0d 100644 (file)
@@ -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);
index 5b046524e9537a45052c3547c76cae5f2727f3a9..f63e742d8ba648f4770e9300c573c6348d922335 100644 (file)
@@ -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;
                }
index 50588ad70a921659ee7a3a38fd7f4d1444cb9e4a..c718cac4bd6f8edaa799be29c200ae6b19c1360c 100644 (file)
@@ -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 (file)
index 0000000..74f42e7
--- /dev/null
@@ -0,0 +1,228 @@
+/*
+ * ***** 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 = mul_m3_v3_single_z(axis_mat, l_last->v->co);
+       do {
+               z_curr = mul_m3_v3_single_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++) {
+                               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);
+}
index 872f1cea2c7a4ece0ff5cd67b1c8e28eaf3ff23e..fb9ebe31c627e3f7d7f731b7d6a272d04853a250 100644 (file)
@@ -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 = mul_m3_v3_single_x((float (*)[3])pc->matrix, co_a) - pc->axis_sep;
+       const float diff_b = mul_m3_v3_single_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 = mul_m3_v3_single_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(mul_m3_v3_single_x((float (*)[3])pc->matrix, co_a) - pc->axis_sep);
+       diff_b = fabsf(mul_m3_v3_single_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 = mul_m3_v3_single_x(pc.matrix, pc.v_a->co);
        }
 
        /* add first vertex */
index e4f2423ca17805d995768890bd6af663735c9429..d633182de425f9dda62ad18a2ed624d752578970 100644 (file)
@@ -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);
 }
index d65e2669a58dfd3363920139390cdbda3ce8df59..f9ff308b706d6ac3204c0b24879a3e96a6eb8975 100644 (file)
@@ -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);
        }
@@ -492,8 +489,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 +500,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 +510,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",
+