Merged revision(s) 58093-58225 from trunk/blender into soc-2013-dingto.
authorThomas Dinges <blender@dingto.org>
Sat, 13 Jul 2013 23:52:43 +0000 (23:52 +0000)
committerThomas Dinges <blender@dingto.org>
Sat, 13 Jul 2013 23:52:43 +0000 (23:52 +0000)
124 files changed:
build_files/cmake/Modules/FindPythonLibsUnix.cmake
intern/cycles/blender/addon/__init__.py
intern/cycles/blender/addon/ui.py
intern/cycles/kernel/kernel_camera.h
intern/cycles/render/graph.cpp
source/blender/blenfont/intern/blf_font.c
source/blender/blenkernel/BKE_DerivedMesh.h
source/blender/blenkernel/BKE_object.h
source/blender/blenkernel/BKE_scene.h
source/blender/blenkernel/intern/DerivedMesh.c
source/blender/blenkernel/intern/boids.c
source/blender/blenkernel/intern/brush.c
source/blender/blenkernel/intern/constraint.c
source/blender/blenkernel/intern/customdata.c
source/blender/blenkernel/intern/dynamicpaint.c
source/blender/blenkernel/intern/editderivedmesh.c
source/blender/blenkernel/intern/fcurve.c
source/blender/blenkernel/intern/image.c
source/blender/blenkernel/intern/lattice.c
source/blender/blenkernel/intern/linestyle.c
source/blender/blenkernel/intern/mask_rasterize.c
source/blender/blenkernel/intern/material.c
source/blender/blenkernel/intern/mball.c
source/blender/blenkernel/intern/movieclip.c
source/blender/blenkernel/intern/node.c
source/blender/blenkernel/intern/object.c
source/blender/blenkernel/intern/particle.c
source/blender/blenkernel/intern/particle_system.c
source/blender/blenkernel/intern/scene.c
source/blender/blenkernel/intern/text.c
source/blender/blenkernel/intern/tracking.c
source/blender/blenkernel/intern/unit.c
source/blender/blenlib/BLI_math_geom.h
source/blender/blenlib/BLI_math_vector.h
source/blender/blenlib/BLI_string_utf8.h
source/blender/blenlib/intern/math_geom.c
source/blender/blenlib/intern/math_matrix.c
source/blender/blenlib/intern/math_vector.c
source/blender/blenlib/intern/string_utf8.c
source/blender/blenloader/intern/versioning_legacy.c
source/blender/blenloader/intern/writefile.c
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_core.h
source/blender/bmesh/intern/bmesh_interp.c
source/blender/bmesh/intern/bmesh_mesh.c
source/blender/bmesh/intern/bmesh_mods.c
source/blender/bmesh/intern/bmesh_operators.c
source/blender/bmesh/operators/bmo_bridge.c
source/blender/bmesh/operators/bmo_connect_pair.c
source/blender/bmesh/operators/bmo_normals.c
source/blender/bmesh/tools/bmesh_bevel.c
source/blender/compositor/nodes/COM_ChromaMatteNode.cpp
source/blender/compositor/nodes/COM_ZCombineNode.cpp
source/blender/compositor/operations/COM_CalculateStandardDeviationOperation.cpp
source/blender/editors/animation/anim_markers.c
source/blender/editors/armature/armature_relations.c
source/blender/editors/armature/armature_utils.c
source/blender/editors/curve/editcurve.c
source/blender/editors/include/ED_mesh.h
source/blender/editors/include/ED_render.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_layout.c
source/blender/editors/interface/interface_regions.c
source/blender/editors/interface/interface_templates.c
source/blender/editors/mesh/editface.c
source/blender/editors/mesh/editmesh_loopcut.c
source/blender/editors/mesh/editmesh_tools.c
source/blender/editors/mesh/editmesh_utils.c
source/blender/editors/mesh/meshtools.c
source/blender/editors/object/object_add.c
source/blender/editors/object/object_vgroup.c
source/blender/editors/physics/particle_edit.c
source/blender/editors/render/render_internal.c
source/blender/editors/render/render_preview.c
source/blender/editors/sculpt_paint/paint_image_proj.c
source/blender/editors/sculpt_paint/paint_ops.c
source/blender/editors/space_buttons/space_buttons.c
source/blender/editors/space_clip/space_clip.c
source/blender/editors/space_file/filelist.c
source/blender/editors/space_node/drawnode.c
source/blender/editors/space_node/node_select.c
source/blender/editors/space_sequencer/sequencer_draw.c
source/blender/editors/space_time/space_time.c
source/blender/editors/space_view3d/drawobject.c
source/blender/editors/space_view3d/view3d_ruler.c
source/blender/editors/space_view3d/view3d_snap.c
source/blender/editors/transform/transform.c
source/blender/editors/transform/transform.h
source/blender/editors/transform/transform_manipulator.c
source/blender/editors/util/undo.c
source/blender/editors/uvedit/uvedit_parametrizer.c
source/blender/freestyle/intern/blender_interface/BlenderFileLoader.cpp
source/blender/freestyle/intern/blender_interface/BlenderFileLoader.h
source/blender/freestyle/intern/view_map/ArbitraryGridDensityProvider.cpp
source/blender/freestyle/intern/view_map/AverageAreaGridDensityProvider.cpp
source/blender/freestyle/intern/view_map/BoxGrid.cpp
source/blender/freestyle/intern/view_map/GridDensityProvider.h
source/blender/freestyle/intern/view_map/Pow23GridDensityProvider.cpp
source/blender/freestyle/intern/view_map/SphericalGrid.cpp
source/blender/freestyle/intern/view_map/ViewMap.cpp
source/blender/freestyle/intern/view_map/ViewMapBuilder.cpp
source/blender/imbuf/intern/colormanagement.c
source/blender/imbuf/intern/tiff.c
source/blender/imbuf/intern/util.c
source/blender/makesdna/DNA_curve_types.h
source/blender/makesdna/intern/makesdna.c
source/blender/makesrna/intern/rna_mesh.c
source/blender/makesrna/intern/rna_nodetree.c
source/blender/makesrna/intern/rna_object.c
source/blender/makesrna/intern/rna_render.c
source/blender/makesrna/intern/rna_space.c
source/blender/modifiers/intern/MOD_screw.c
source/blender/modifiers/intern/MOD_solidify.c
source/blender/python/bmesh/bmesh_py_types.c
source/blender/render/extern/include/RE_engine.h
source/blender/render/intern/source/convertblender.c
source/blender/render/intern/source/envmap.c
source/blender/render/intern/source/external_engine.c
source/blender/render/intern/source/render_texture.c
source/blender/windowmanager/intern/wm_playanim.c

index 1dffd54fed120421eb8c3640017e07724f1521b4..82f74373b8bc37886aa8444cc42f078f0c5122ec 100644 (file)
@@ -2,9 +2,11 @@
 # Find the native Python includes and library
 #
 # Note:, This is not _yet_ intended to be a general python module for other
-#  projects to use since its hard coded to python 3.2 as blender only supports
-#  a single python version.
-#  This is for blender/unix python only.
+#  projects to use since its hard coded to fixed Python version
+#  as Blender only supports a single Python version at the moment.
+#
+# Note:
+#  this is for Blender/Unix Python only.
 #
 # This module defines
 #  PYTHON_VERSION
index b451b8ef3bf38ea687124020952a784d0a34174d..cefdf5042069db2fc098d33dce40ae419dc4dec7 100644 (file)
@@ -41,6 +41,7 @@ class CyclesRender(bpy.types.RenderEngine):
     bl_use_shading_nodes = True
     bl_use_preview = True
     bl_use_exclude_layers = True
+    bl_use_save_buffers = True
 
     def __init__(self):
         self.session = None
index b80ab6b1c5ecdb1f1fa354e01859e4e404859710..7f6e8d591c27d441b26863dfadf901cf441ff659 100644 (file)
@@ -211,21 +211,23 @@ class CyclesRender_PT_performance(CyclesButtonsPanel, Panel):
         subsub.enabled = not rd.use_border
         subsub.prop(rd, "use_save_buffers")
 
-        col = split.column()
+        col = split.column(align=True)
 
-        sub = col.column(align=True)
-        sub.label(text="Acceleration structure:")
-        sub.prop(cscene, "debug_bvh_type", text="")
-        sub.prop(cscene, "debug_use_spatial_splits")
-        sub.prop(cscene, "use_cache")
+        col.label(text="Viewport:")
+        col.prop(cscene, "debug_bvh_type", text="")
+        col.separator()
+        col.prop(cscene, "preview_start_resolution")
 
-        sub = col.column(align=True)
-        sub.label(text="Viewport:")
-        sub.prop(cscene, "preview_start_resolution")
+        col.separator()
 
-        sub = col.column(align=True)
-        sub.label(text="Final Render:")
-        sub.prop(rd, "use_persistent_data", text="Persistent Images")
+        col.label(text="Final Render:")
+        col.prop(cscene, "use_cache")
+        col.prop(rd, "use_persistent_data", text="Persistent Images")
+
+        col.separator()
+
+        col.label(text="Acceleration structure:")   
+        col.prop(cscene, "debug_use_spatial_splits")
 
 
 class CyclesRender_PT_opengl(CyclesButtonsPanel, Panel):
index 4b9ef8893f708698c699e4f569f1e717cd794238..c3cffc15ebe2e35c3372288c405e7eb1403da1d0 100644 (file)
@@ -166,6 +166,12 @@ __device void camera_sample_panorama(KernelGlobals *kg, float raster_x, float ra
 
        ray->D = panorama_to_direction(kg, Pcamera.x, Pcamera.y);
 
+       /* indicates ray should not receive any light, outside of the lens */
+       if(is_zero(ray->D)) {   
+               ray->t = 0.0f;
+               return;
+       }
+
        /* modify ray for depth of field */
        float aperturesize = kernel_data.cam.aperturesize;
 
@@ -186,12 +192,6 @@ __device void camera_sample_panorama(KernelGlobals *kg, float raster_x, float ra
                ray->D = normalize(Pfocus - ray->P);
        }
 
-       /* indicates ray should not receive any light, outside of the lens */
-       if(is_zero(ray->D)) {   
-               ray->t = 0.0f;
-               return;
-       }
-
        /* transform ray from camera to world */
        Transform cameratoworld = kernel_data.cam.cameratoworld;
 
index 515bbe9233522e69f8a05a064c0d14a86f1dc9b8..2e8bc77b9c9ae663878679c272400b77569e8724 100644 (file)
@@ -347,8 +347,9 @@ void ShaderGraph::remove_unneeded_nodes()
 
                                        if(tonode->special_type == SHADER_SPECIAL_TYPE_AUTOCONVERT) {
                                                bool all_links_removed = true;
+                                               vector<ShaderInput*> links = tonode->outputs[0]->links;
 
-                                               foreach(ShaderInput *autoin, tonode->outputs[0]->links) {
+                                               foreach(ShaderInput *autoin, links) {
                                                        if(autoin->default_value == ShaderInput::NONE)
                                                                all_links_removed = false;
                                                        else
index 56a77d643d61e2f11e23f74d9ea4153b0451fe23..15098d505318ca2a55a2a46cce12df64d2bb2cbe 100644 (file)
@@ -87,7 +87,7 @@ void blf_font_size(FontBLF *font, unsigned int size, unsigned int dpi)
        err = FT_Set_Char_Size(font->face, 0, (FT_F26Dot6)(size * 64), dpi, dpi);
        if (err) {
                /* FIXME: here we can go through the fixed size and choice a close one */
-               printf("The current font don't support the size, %d and dpi, %d\n", size, dpi);
+               printf("The current font don't support the size, %u and dpi, %u\n", size, dpi);
                return;
        }
 
index fdb43f5467e22fc59fc66fcc40df7352533898b7..ae936a1659a6d98f77313b78014c378f9684f2c3 100644 (file)
@@ -323,6 +323,7 @@ struct DerivedMesh {
 
        /** Get smooth vertex normal, undefined if index is not valid */
        void (*getVertNo)(DerivedMesh *dm, int index, float no_r[3]);
+       void (*getPolyNo)(DerivedMesh *dm, int index, float no_r[3]);
 
        /** Get a map of vertices to faces
         */
index 463720fb8cfdd8ed25785d6b038502656ed963d3..992792dcb999b90ff256ef2e9fd8730b3ed8e833 100644 (file)
@@ -95,15 +95,16 @@ void BKE_object_mat3_to_rot(struct Object *ob, float mat[3][3], bool use_compat)
 void BKE_object_to_mat3(struct Object *ob, float mat[3][3]);
 void BKE_object_to_mat4(struct Object *ob, float mat[4][4]);
 void BKE_object_apply_mat4(struct Object *ob, float mat[4][4], const bool use_compat, const bool use_parent);
+void BKE_object_matrix_local_get(struct Object *ob, float mat[4][4]);
 
 bool BKE_object_pose_context_check(struct Object *ob);
 struct Object *BKE_object_pose_armature_get(struct Object *ob);
 
 void BKE_object_where_is_calc(struct Scene *scene, struct Object *ob);
-void BKE_object_where_is_calc_ex(struct Scene *scene, struct RigidBodyWorld *rbw, struct Object *ob);
+void BKE_object_where_is_calc_ex(struct Scene *scene, struct RigidBodyWorld *rbw, struct Object *ob, float r_originmat[3][3]);
 void BKE_object_where_is_calc_time(struct Scene *scene, struct Object *ob, float ctime);
 void BKE_object_where_is_calc_time_ex(struct Scene *scene, struct Object *ob, float ctime,
-                                      struct RigidBodyWorld *rbw);
+                                      struct RigidBodyWorld *rbw, float r_originmat[3][3]);
 void BKE_object_where_is_calc_simul(struct Scene *scene, struct Object *ob);
 void BKE_object_where_is_calc_mat4(struct Scene *scene, struct Object *ob, float obmat[4][4]);
 
index 34f34bb99518baf8765542b2e18f0bb0a990fcb9..61f665be5860a919ff66448edda356d3111ae369 100644 (file)
@@ -75,7 +75,17 @@ struct Base *BKE_scene_base_add(struct Scene *sce, struct Object *ob);
 void         BKE_scene_base_unlink(struct Scene *sce, struct Base *base);
 void         BKE_scene_base_deselect_all(struct Scene *sce);
 void         BKE_scene_base_select(struct Scene *sce, struct Base *selbase);
-int          BKE_scene_base_iter_next(struct Scene **scene, int val, struct Base **base, struct Object **ob);
+
+/* Scene base iteration function.
+ * Define struct here, so no need to bother with alloc/free it.
+ */
+typedef struct SceneBaseIter {
+       struct ListBase *duplilist;
+       struct DupliObject *dupob;
+       int fase;
+} SceneBaseIter;
+
+int          BKE_scene_base_iter_next(struct SceneBaseIter *iter, struct Scene **scene, int val, struct Base **base, struct Object **ob);
 
 void BKE_scene_base_flag_to_objects(struct Scene *scene);
 void BKE_scene_base_flag_from_objects(struct Scene *scene);
index 6bde0a501f3902d07929cd06704e925df63ad690..99104ad6b836bd416087365f2ed8ba321359fed4 100644 (file)
@@ -655,21 +655,25 @@ void DM_add_poly_layer(DerivedMesh *dm, int type, int alloctype, void *layer)
 
 void *DM_get_vert_data(DerivedMesh *dm, int index, int type)
 {
+       BLI_assert(index >= 0 && index < dm->getNumVerts(dm));
        return CustomData_get(&dm->vertData, index, type);
 }
 
 void *DM_get_edge_data(DerivedMesh *dm, int index, int type)
 {
+       BLI_assert(index >= 0 && index < dm->getNumEdges(dm));
        return CustomData_get(&dm->edgeData, index, type);
 }
 
 void *DM_get_tessface_data(DerivedMesh *dm, int index, int type)
 {
+       BLI_assert(index >= 0 && index < dm->getNumTessFaces(dm));
        return CustomData_get(&dm->faceData, index, type);
 }
 
 void *DM_get_poly_data(DerivedMesh *dm, int index, int type)
 {
+       BLI_assert(index >= 0 && index < dm->getNumPolys(dm));
        return CustomData_get(&dm->polyData, index, type);
 }
 
index dfffb7c795e3e805fd45cdfa14ea42c7a624b918..cf761bf3dab9300df73093b50a6e387f7ccac694 100644 (file)
@@ -981,6 +981,7 @@ void boid_brain(BoidBrainData *bbd, int p, ParticleData *pa)
                        rule = BLI_findlink(&state->rules, rand % BLI_countlist(&state->rules));
 
                        apply_boid_rule(bbd, rule, &val, pa, -1.0);
+                       break;
                }
                case eBoidRulesetType_Average:
                {
index 307dbc648473aff28e2a41b8c7a452bcd0892e41..8130f6e646cc693481e38174105c27fa79c811f0 100644 (file)
@@ -539,7 +539,7 @@ float BKE_brush_sample_tex_3D(const Scene *scene, Brush *br,
        else if (mtex->brush_map_mode == MTEX_MAP_MODE_STENCIL) {
                float rotation = -mtex->rot;
                float point_2d[2] = {point[0], point[1]};
-               float x = 0.0f, y = 0.0f; /* Quite warnings */
+               float x, y;
                float co[3];
 
                x = point_2d[0] - br->stencil_pos[0];
@@ -658,7 +658,7 @@ float BKE_brush_sample_masktex(const Scene *scene, Brush *br,
        if (mtex->brush_map_mode == MTEX_MAP_MODE_STENCIL) {
                float rotation = -mtex->rot;
                float point_2d[2] = {point[0], point[1]};
-               float x = 0.0f, y = 0.0f; /* Quite warnings */
+               float x, y;
                float co[3];
 
                x = point_2d[0] - br->mask_stencil_pos[0];
index 0cd13d528d559fba45a2364f33da23aadd1ede93..c78038c0f6673a7acfd92628a1fb562eea0b4510 100644 (file)
@@ -2519,7 +2519,7 @@ static void distlimit_evaluate(bConstraint *con, bConstraintOb *cob, ListBase *t
        
        /* only evaluate if there is a target */
        if (VALID_CONS_TARGET(ct)) {
-               float dvec[3], dist = 0.0f, sfac = 1.0f;
+               float dvec[3], dist, sfac = 1.0f;
                short clamp_surf = 0;
                
                /* calculate our current distance from the target */
index b6c608661cd3e648d72f59cc9a2c2e0727bebe29..83685477725d7bc0f024a53aef949821412079cf 100644 (file)
@@ -2073,6 +2073,8 @@ void *CustomData_get(const CustomData *data, int index, int type)
        int offset;
        int layer_index;
        
+       BLI_assert(index >= 0);
+
        /* get the layer index of the active layer of type */
        layer_index = CustomData_get_active_layer_index(data, type);
        if (layer_index < 0) return NULL;
@@ -2088,6 +2090,8 @@ void *CustomData_get_n(const CustomData *data, int type, int index, int n)
        int layer_index;
        int offset;
 
+       BLI_assert(index >= 0 && n >= 0);
+
        /* get the layer index of the first layer of type */
        layer_index = data->typemap[type];
        if (layer_index < 0) return NULL;
index a668c6a6d7baeeb3d343b85b09d21415b9174557..a6811af1a9459f1a224c9b92eb3ab954125cfa65 100644 (file)
@@ -1942,6 +1942,7 @@ static void dynamicPaint_frameUpdate(DynamicPaintModifierData *pmd, Scene *scene
                /* loop through surfaces */
                for (; surface; surface = surface->next) {
                        int current_frame = (int)scene->r.cfra;
+                       bool no_surface_data;
 
                        /* free bake data if not required anymore */
                        surface_freeUnusedData(surface);
@@ -1951,12 +1952,13 @@ static void dynamicPaint_frameUpdate(DynamicPaintModifierData *pmd, Scene *scene
                        if (!(surface->flags & MOD_DPAINT_ACTIVE)) continue;
 
                        /* make sure surface is valid */
+                       no_surface_data = surface->data == NULL;
                        if (!dynamicPaint_checkSurfaceData(surface)) continue;
 
                        /* limit frame range */
                        CLAMP(current_frame, surface->start_frame, surface->end_frame);
 
-                       if (current_frame != surface->current_frame || (int)scene->r.cfra == surface->start_frame) {
+                       if (no_surface_data || current_frame != surface->current_frame || (int)scene->r.cfra == surface->start_frame) {
                                PointCache *cache = surface->pointcache;
                                PTCacheID pid;
                                surface->current_frame = current_frame;
index 87f7da8a1fb2cd462b5e98616f8996e979e07bc4..46cee96a53716d0f61656ba2248a335432524c5b 100644 (file)
@@ -1109,6 +1109,66 @@ static void emDM_getVert(DerivedMesh *dm, int index, MVert *r_vert)
                copy_v3_v3(r_vert->co, bmdm->vertexCos[index]);
 }
 
+static void emDM_getVertCo(DerivedMesh *dm, int index, float r_co[3])
+{
+       EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
+       BMesh *bm = bmdm->em->bm;
+
+       if (UNLIKELY(index < 0 || index >= bm->totvert)) {
+               BLI_assert(!"error in emDM_getVertCo");
+               return;
+       }
+
+       if (bmdm->vertexCos) {
+               copy_v3_v3(r_co, bmdm->vertexCos[index]);
+       }
+       else {
+               BMVert *ev = bmdm->em->vert_index[index];  /* should be EDBM_vert_at_index() */
+               // ev = BM_vert_at_index(bm, index); /* warning, does list loop, _not_ ideal */
+               copy_v3_v3(r_co, ev->co);
+       }
+}
+
+static void emDM_getVertNo(DerivedMesh *dm, int index, float r_no[3])
+{
+       EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
+       BMesh *bm = bmdm->em->bm;
+
+       if (UNLIKELY(index < 0 || index >= bm->totvert)) {
+               BLI_assert(!"error in emDM_getVertNo");
+               return;
+       }
+
+       if (bmdm->vertexNos) {
+               copy_v3_v3(r_no, bmdm->vertexNos[index]);
+       }
+       else {
+               BMVert *ev = bmdm->em->vert_index[index];  /* should be EDBM_vert_at_index() */
+               // ev = BM_vert_at_index(bm, index); /* warning, does list loop, _not_ ideal */
+               copy_v3_v3(r_no, ev->no);
+       }
+}
+
+static void emDM_getPolyNo(DerivedMesh *dm, int index, float r_no[3])
+{
+       EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
+       BMesh *bm = bmdm->em->bm;
+
+       if (UNLIKELY(index < 0 || index >= bm->totface)) {
+               BLI_assert(!"error in emDM_getPolyNo");
+               return;
+       }
+
+       if (bmdm->polyNos) {
+               copy_v3_v3(r_no, bmdm->polyNos[index]);
+       }
+       else {
+               BMFace *efa = bmdm->em->face_index[index];  /* should be EDBM_vert_at_index() */
+               // efa = BM_face_at_index(bm, index); /* warning, does list loop, _not_ ideal */
+               copy_v3_v3(r_no, efa->no);
+       }
+}
+
 static void emDM_getEdge(DerivedMesh *dm, int index, MEdge *r_edge)
 {
        EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
@@ -1456,6 +1516,9 @@ DerivedMesh *getEditDerivedBMesh(BMEditMesh *em,
        bmdm->dm.getNumPolys = emDM_getNumPolys;
 
        bmdm->dm.getVert = emDM_getVert;
+       bmdm->dm.getVertCo = emDM_getVertCo;
+       bmdm->dm.getVertNo = emDM_getVertNo;
+       bmdm->dm.getPolyNo = emDM_getPolyNo;
        bmdm->dm.getEdge = emDM_getEdge;
        bmdm->dm.getTessFace = emDM_getTessFace;
        bmdm->dm.copyVertArray = emDM_copyVertArray;
@@ -1487,6 +1550,7 @@ DerivedMesh *getEditDerivedBMesh(BMEditMesh *em,
        bmdm->dm.release = emDM_release;
 
        bmdm->vertexCos = vertexCos;
+       bmdm->dm.deformedOnly = (vertexCos != NULL);
 
        if (cd_dvert_offset != -1) {
                BMIter iter;
index f763670baefc32b80a9d3502700cc96de58664e6..8958680d611198c6f58bef5bd71853958763f071 100644 (file)
@@ -1697,7 +1697,7 @@ static float evaluate_driver(ChannelDriver *driver, const float evaltime)
                                
                                /* perform operations on the total if appropriate */
                                if (driver->type == DRIVER_TYPE_AVERAGE)
-                                       driver->curval = (value / (float)tot);
+                                       driver->curval = tot ? (value / (float)tot) : 0.0f;
                                else
                                        driver->curval = value;
                        }
index e28b1bf3f69eddf2a8d00bfd446c855c6510c2e6..f34053816c5b7ed854703dc29dac858de9ed2ed5 100644 (file)
@@ -2718,8 +2718,8 @@ static ImBuf *image_get_render_result(Image *ima, ImageUser *iuser, void **lock_
        re = RE_GetRender(iuser->scene->id.name);
 
        channels = 4;
-       layer = (iuser) ? iuser->layer : 0;
-       pass = (iuser) ? iuser->pass : 0;
+       layer = iuser->layer;
+       pass = iuser->pass;
 
        if (from_render) {
                RE_AcquireResultImage(re, &rres);
index c9b904e76ac3bb47e7704bc64020e61826d71512..a4892253c63b2b86d16e8ebd811d7fbffb416b47 100644 (file)
@@ -681,7 +681,7 @@ void curve_deform_verts(Scene *scene, Object *cuOb, Object *target,
         * we want either a Mesh with no derived data, or derived data with
         * deformverts
         */
-       if (target && target->type == OB_MESH) {
+       if (target->type == OB_MESH) {
                /* if there's derived data without deformverts, don't use vgroups */
                if (dm) {
                        use_vgroups = (dm->getVertData(dm, 0, CD_MDEFORMVERT) != NULL);
index f47f86744afb956fc93d51d0c8110f2b773e2563..3ab1a8093bee6333a6f9bbb9288a768cf4675fa5 100644 (file)
@@ -183,7 +183,7 @@ static LineStyleModifier *new_modifier(int type, size_t size)
 
        m = (LineStyleModifier *)MEM_callocN(size, "line style modifier");
        m->type = type;
-       strcpy(m->name, modifier_name[type]);
+       BLI_strncpy(m->name, modifier_name[type], sizeof(m->name));
        m->influence = 1.0f;
        m->flags = LS_MODIFIER_ENABLED | LS_MODIFIER_EXPANDED;
 
index 82410d56c52e1ebd87d6772870999656e2e69f9e..e68f87211eb90842117e6b175ec319c084ef5551 100644 (file)
@@ -530,7 +530,7 @@ static void layer_bucket_init(MaskRasterLayer *layer, const float pixel_size)
 
                if (1) {
                        /* now convert linknodes into arrays for faster per pixel access */
-                       unsigned int  **buckets_face = MEM_mallocN(bucket_tot * sizeof(unsigned int **), __func__);
+                       unsigned int  **buckets_face = MEM_mallocN(bucket_tot * sizeof(*buckets_face), __func__);
                        unsigned int bucket_index;
 
                        for (bucket_index = 0; bucket_index < bucket_tot; bucket_index++) {
index c8cd65e94773948018984168642b4faecab4da12..a445d43da00f5aef9fe83a21bc88cf4fd5f43baf 100644 (file)
@@ -2051,8 +2051,10 @@ int do_version_tface(Main *main, int fileload)
                                printf("Warning: material \"%s\" skipped - to convert old game texface to material go to the Help menu.\n", ma->id.name + 2);
                                nowarning = 0;
                        }
-                       else
-                               convert_tfacematerial(main, ma); continue;
+                       else {
+                               convert_tfacematerial(main, ma);
+                       }
+                       continue;
                }
        
                /* no conflicts in this material - 90% of cases
index 31212c3a6b79b7fb71c0724444fdcd87db918da7..173b193b7527ff542c6e5f28fb8b11f5c2128f0c 100644 (file)
@@ -485,14 +485,15 @@ void BKE_mball_properties_copy(Scene *scene, Object *active_object)
        MetaBall *active_mball = (MetaBall *)active_object->data;
        int basisnr, obnr;
        char basisname[MAX_ID_NAME], obname[MAX_ID_NAME];
-       
+       SceneBaseIter iter;
+
        BLI_split_name_num(basisname, &basisnr, active_object->id.name + 2, '.');
 
        /* XXX recursion check, see scene.c, just too simple code this BKE_scene_base_iter_next() */
-       if (F_ERROR == BKE_scene_base_iter_next(&sce_iter, 0, NULL, NULL))
+       if (F_ERROR == BKE_scene_base_iter_next(&iter, &sce_iter, 0, NULL, NULL))
                return;
        
-       while (BKE_scene_base_iter_next(&sce_iter, 1, &base, &ob)) {
+       while (BKE_scene_base_iter_next(&iter, &sce_iter, 1, &base, &ob)) {
                if (ob->type == OB_MBALL) {
                        if (ob != active_object) {
                                BLI_split_name_num(obname, &obnr, ob->id.name + 2, '.');
@@ -529,14 +530,15 @@ Object *BKE_mball_basis_find(Scene *scene, Object *basis)
        Object *ob, *bob = basis;
        int basisnr, obnr;
        char basisname[MAX_ID_NAME], obname[MAX_ID_NAME];
+       SceneBaseIter iter;
 
        BLI_split_name_num(basisname, &basisnr, basis->id.name + 2, '.');
 
        /* XXX recursion check, see scene.c, just too simple code this BKE_scene_base_iter_next() */
-       if (F_ERROR == BKE_scene_base_iter_next(&sce_iter, 0, NULL, NULL))
+       if (F_ERROR == BKE_scene_base_iter_next(&iter, &sce_iter, 0, NULL, NULL))
                return NULL;
 
-       while (BKE_scene_base_iter_next(&sce_iter, 1, &base, &ob)) {
+       while (BKE_scene_base_iter_next(&iter, &sce_iter, 1, &base, &ob)) {
                if (ob->type == OB_MBALL) {
                        if (ob != bob) {
                                BLI_split_name_num(obname, &obnr, ob->id.name + 2, '.');
@@ -1644,6 +1646,14 @@ BLI_INLINE void copy_v3_fl3(float v[3], float x, float y, float z)
        v[2] = z;
 }
 
+/* TODO(sergey): Perhaps it could be general utility function in mathutils. */
+static bool has_zero_axis_m4(float matrix[4][4])
+{
+       return len_squared_v3(matrix[0]) < FLT_EPSILON ||
+              len_squared_v3(matrix[1]) < FLT_EPSILON ||
+              len_squared_v3(matrix[2]) < FLT_EPSILON;
+}
+
 static float init_meta(PROCESS *process, Scene *scene, Object *ob)    /* return totsize */
 {
        Scene *sce_iter = scene;
@@ -1655,7 +1665,8 @@ static float init_meta(PROCESS *process, Scene *scene, Object *ob)    /* return
        //float max = 0.0f;
        int a, obnr, zero_size = 0;
        char obname[MAX_ID_NAME];
-       
+       SceneBaseIter iter;
+
        copy_m4_m4(obmat, ob->obmat);   /* to cope with duplicators from BKE_scene_base_iter_next */
        invert_m4_m4(obinv, ob->obmat);
        a = 0;
@@ -1663,8 +1674,8 @@ static float init_meta(PROCESS *process, Scene *scene, Object *ob)    /* return
        BLI_split_name_num(obname, &obnr, ob->id.name + 2, '.');
        
        /* make main array */
-       BKE_scene_base_iter_next(&sce_iter, 0, NULL, NULL);
-       while (BKE_scene_base_iter_next(&sce_iter, 1, &base, &bob)) {
+       BKE_scene_base_iter_next(&iter, &sce_iter, 0, NULL, NULL);
+       while (BKE_scene_base_iter_next(&iter, &sce_iter, 1, &base, &bob)) {
 
                if (bob->type == OB_MBALL) {
                        zero_size = 0;
@@ -1691,13 +1702,13 @@ static float init_meta(PROCESS *process, Scene *scene, Object *ob)    /* return
 
                        /* when metaball object has zero scale, then MetaElem to this MetaBall
                         * will not be put to mainb array */
-                       if (bob->size[0] == 0.0f || bob->size[1] == 0.0f || bob->size[2] == 0.0f) {
+                       if (has_zero_axis_m4(bob->obmat)) {
                                zero_size = 1;
                        }
                        else if (bob->parent) {
                                struct Object *pob = bob->parent;
                                while (pob) {
-                                       if (pob->size[0] == 0.0f || pob->size[1] == 0.0f || pob->size[2] == 0.0f) {
+                                       if (has_zero_axis_m4(pob->obmat)) {
                                                zero_size = 1;
                                                break;
                                        }
@@ -2225,15 +2236,16 @@ static void mball_count(PROCESS *process, Scene *scene, Object *basis)
        MetaElem *ml = NULL;
        int basisnr, obnr;
        char basisname[MAX_ID_NAME], obname[MAX_ID_NAME];
+       SceneBaseIter iter;
 
        BLI_split_name_num(basisname, &basisnr, basis->id.name + 2, '.');
        process->totelem = 0;
 
        /* XXX recursion check, see scene.c, just too simple code this BKE_scene_base_iter_next() */
-       if (F_ERROR == BKE_scene_base_iter_next(&sce_iter, 0, NULL, NULL))
+       if (F_ERROR == BKE_scene_base_iter_next(&iter, &sce_iter, 0, NULL, NULL))
                return;
 
-       while (BKE_scene_base_iter_next(&sce_iter, 1, &base, &ob)) {
+       while (BKE_scene_base_iter_next(&iter, &sce_iter, 1, &base, &ob)) {
                if (ob->type == OB_MBALL) {
                        if (ob == bob) {
                                MetaBall *mb = ob->data;
@@ -2434,6 +2446,7 @@ bool BKE_mball_center_median(MetaBall *mb, float r_cent[3])
 
        for (ml = mb->elems.first; ml; ml = ml->next) {
                add_v3_v3(r_cent, &ml->x);
+               total++;
        }
 
        if (total) {
index d062f302379f4fb1e17e88d8dfb66cd035f3b7cd..ef3b7ca0bdf7fbe6e23754df8ab1b72228c006e1 100644 (file)
@@ -440,7 +440,7 @@ static void *moviecache_getprioritydata(void *key_v)
        MovieClipImBufCacheKey *key = (MovieClipImBufCacheKey *) key_v;
        MovieClipCachePriorityData *priority_data;
 
-       priority_data = MEM_callocN(sizeof(priority_data), "movie cache clip priority data");
+       priority_data = MEM_callocN(sizeof(*priority_data), "movie cache clip priority data");
        priority_data->framenr = key->framenr;
 
        return priority_data;
index 929d741282eea71ff4e663ea6e1ee875bfedc41d..3f343cedff1512b8ebb39d52cd5367fc0709b9e5 100644 (file)
@@ -349,9 +349,6 @@ static void free_dynamic_typeinfo(bNodeType *ntype)
                if (ntype->outputs) {
                        MEM_freeN(ntype->outputs);
                }
-               if (ntype->ui_name) {
-                       MEM_freeN((void *)ntype->ui_name);
-               }
        }
 }
 
index f1183868e8b3b28e06594fda4dff0c6594d76e8d..e79a759407b2544f02792aee2126e9113448c7a0 100644 (file)
 
 #include "GPU_material.h"
 
-/* Local function protos */
-float originmat[3][3];  /* after BKE_object_where_is_calc(), can be used in other functions (bad!) */
-
 void BKE_object_workob_clear(Object *workob)
 {
        memset(workob, 0, sizeof(Object));
@@ -1739,6 +1736,18 @@ void BKE_object_to_mat4(Object *ob, float mat[4][4])
        add_v3_v3v3(mat[3], ob->loc, ob->dloc);
 }
 
+void BKE_object_matrix_local_get(struct Object *ob, float mat[4][4])
+{
+       if (ob->parent) {
+               float invmat[4][4]; /* for inverse of parent's matrix */
+               invert_m4_m4(invmat, ob->parent->obmat);
+               mul_m4_m4m4(mat, invmat, ob->obmat);
+       }
+       else {
+               copy_m4_m4(mat, ob->obmat);
+       }
+}
+
 /* extern */
 int enable_cu_speed = 1;
 
@@ -1991,7 +2000,11 @@ static void ob_parvert3(Object *ob, Object *par, float mat[4][4])
        }
 }
 
-static void solve_parenting(Scene *scene, Object *ob, Object *par, float obmat[4][4], float slowmat[4][4], int simul)
+/**
+ * \param r_originmat  Optional matrix that stores the space the object is in (without its own matrix applied)
+ */
+static void solve_parenting(Scene *scene, Object *ob, Object *par, float obmat[4][4], float slowmat[4][4],
+                            float r_originmat[3][3], const bool simul)
 {
        float totmat[4][4];
        float tmat[4][4];
@@ -2056,8 +2069,10 @@ static void solve_parenting(Scene *scene, Object *ob, Object *par, float obmat[4
 
        }
        else {
-               /* external usable originmat */
-               copy_m3_m4(originmat, tmat);
+               if (r_originmat) {
+                       /* usable originmat */
+                       copy_m3_m4(r_originmat, tmat);
+               }
                
                /* origin, for help line */
                if ((ob->partype & PARTYPE) == PARSKEL) {
@@ -2091,7 +2106,7 @@ static int where_is_object_parslow(Object *ob, float obmat[4][4], float slowmat[
 
 /* note, scene is the active scene while actual_scene is the scene the object resides in */
 void BKE_object_where_is_calc_time_ex(Scene *scene, Object *ob, float ctime,
-                                      RigidBodyWorld *rbw)
+                                      RigidBodyWorld *rbw, float r_originmat[3][3])
 {
        if (ob == NULL) return;
        
@@ -2103,7 +2118,7 @@ void BKE_object_where_is_calc_time_ex(Scene *scene, Object *ob, float ctime,
                float slowmat[4][4] = MAT4_UNITY;
                
                /* calculate parent matrix */
-               solve_parenting(scene, ob, par, ob->obmat, slowmat, 0);
+               solve_parenting(scene, ob, par, ob->obmat, slowmat, r_originmat, false);
                
                /* "slow parent" is definitely not threadsafe, and may also give bad results jumping around 
                 * An old-fashioned hack which probably doesn't really cut it anymore
@@ -2138,7 +2153,7 @@ void BKE_object_where_is_calc_time_ex(Scene *scene, Object *ob, float ctime,
 
 void BKE_object_where_is_calc_time(Scene *scene, Object *ob, float ctime)
 {
-       BKE_object_where_is_calc_time_ex(scene, ob, ctime, NULL);
+       BKE_object_where_is_calc_time_ex(scene, ob, ctime, NULL, NULL);
 }
 
 /* get object transformation matrix without recalculating dependencies and
@@ -2152,7 +2167,7 @@ void BKE_object_where_is_calc_mat4(Scene *scene, Object *ob, float obmat[4][4])
        if (ob->parent) {
                Object *par = ob->parent;
                
-               solve_parenting(scene, ob, par, obmat, slowmat, 1);
+               solve_parenting(scene, ob, par, obmat, slowmat, NULL, true);
                
                if (ob->partype & PARSLOW)
                        where_is_object_parslow(ob, obmat, slowmat);
@@ -2162,13 +2177,13 @@ void BKE_object_where_is_calc_mat4(Scene *scene, Object *ob, float obmat[4][4])
        }
 }
 
-void BKE_object_where_is_calc_ex(Scene *scene, RigidBodyWorld *rbw, Object *ob)
+void BKE_object_where_is_calc_ex(Scene *scene, RigidBodyWorld *rbw, Object *ob, float r_originmat[3][3])
 {
-       BKE_object_where_is_calc_time_ex(scene, ob, BKE_scene_frame_get(scene), rbw);
+       BKE_object_where_is_calc_time_ex(scene, ob, BKE_scene_frame_get(scene), rbw, r_originmat);
 }
 void BKE_object_where_is_calc(Scene *scene, Object *ob)
 {
-       BKE_object_where_is_calc_time_ex(scene, ob, BKE_scene_frame_get(scene), NULL);
+       BKE_object_where_is_calc_time_ex(scene, ob, BKE_scene_frame_get(scene), NULL, NULL);
 }
 
 /* was written for the old game engine (until 2.04) */
@@ -2186,7 +2201,7 @@ void BKE_object_where_is_calc_simul(Scene *scene, Object *ob)
        if (ob->parent) {
                par = ob->parent;
                
-               solve_parenting(scene, ob, par, ob->obmat, slowmat, 1);
+               solve_parenting(scene, ob, par, ob->obmat, slowmat, NULL, true);
                
                if (ob->partype & PARSLOW) {
                        fac1 = (float)(1.0 / (1.0 + fabs(ob->sf)));
@@ -2658,7 +2673,7 @@ void BKE_object_handle_update_ex(Scene *scene, Object *ob,
                                        copy_m4_m4(ob->obmat, ob->proxy_from->obmat);
                        }
                        else
-                               BKE_object_where_is_calc_ex(scene, rbw, ob);
+                               BKE_object_where_is_calc_ex(scene, rbw, ob, NULL);
                }
                
                if (ob->recalc & OB_RECALC_DATA) {
index f6901c7b81b3889da9577a874c0ecaad8e2744cc..b3f29fe8ce16e552300a8772d2c2841225a327e7 100644 (file)
@@ -3414,8 +3414,7 @@ static void psys_face_mat(Object *ob, DerivedMesh *dm, ParticleData *pa, float m
        OrigSpaceFace *osface;
        float (*orcodata)[3];
 
-       int i = pa->num_dmcache == DMCACHE_NOTFOUND ? pa->num : pa->num_dmcache;
-       
+       int i = (ELEM(pa->num_dmcache, DMCACHE_ISCHILD, DMCACHE_NOTFOUND)) ? pa->num : pa->num_dmcache;
        if (i == -1 || i >= dm->getNumTessFaces(dm)) { unit_m4(mat); return; }
 
        mface = dm->getTessFaceData(dm, i, CD_MFACE);
index c9be73c4bd45fe70b0d1c3f7f88b05f4903bbf0c..c150854e293e550786f8a5e3f1d5b359d9ed2561 100644 (file)
@@ -1823,35 +1823,75 @@ void psys_get_birth_coordinates(ParticleSimulationData *sim, ParticleData *pa, P
                unit_qt(state->rot);
 
                if (part->rotmode) {
+                       bool use_global_space;
+
                        /* create vector into which rotation is aligned */
                        switch (part->rotmode) {
                                case PART_ROT_NOR:
                                        copy_v3_v3(rot_vec, nor);
+                                       use_global_space = false;
                                        break;
                                case PART_ROT_VEL:
                                        copy_v3_v3(rot_vec, vel);
+                                       use_global_space = true;
                                        break;
                                case PART_ROT_GLOB_X:
                                case PART_ROT_GLOB_Y:
                                case PART_ROT_GLOB_Z:
                                        rot_vec[part->rotmode - PART_ROT_GLOB_X] = 1.0f;
+                                       use_global_space = true;
                                        break;
                                case PART_ROT_OB_X:
                                case PART_ROT_OB_Y:
                                case PART_ROT_OB_Z:
                                        copy_v3_v3(rot_vec, ob->obmat[part->rotmode - PART_ROT_OB_X]);
+                                       use_global_space = false;
+                                       break;
+                               default:
+                                       use_global_space = true;
                                        break;
                        }
                        
                        /* create rotation quat */
                        negate_v3(rot_vec);
-                       vec_to_quat( q2,rot_vec, OB_POSX, OB_POSZ);
 
-                       /* randomize rotation quat */
-                       if (part->randrotfac!=0.0f)
-                               interp_qt_qtqt(rot, q2, r_rot, part->randrotfac);
-                       else
-                               copy_qt_qt(rot,q2);
+                       if (use_global_space) {
+                               /* calculate rotation in global-space */
+                               vec_to_quat(q2, rot_vec, OB_POSX, OB_POSZ);
+
+                               /* randomize rotation quat */
+                               if (part->randrotfac != 0.0f) {
+                                       interp_qt_qtqt(rot, q2, r_rot, part->randrotfac);
+                               }
+                               else {
+                                       copy_qt_qt(rot, q2);
+                               }
+                       }
+                       else {
+                               /* calculate rotation in local-space */
+                               float q_obmat[4];
+                               float q_imat[4];
+                               float tvec[3];
+
+                               mat4_to_quat(q_obmat, ob->obmat);
+                               invert_qt_qt(q_imat, q_obmat);
+
+                               copy_v3_v3(tvec, rot_vec);
+                               mul_qt_v3(q_imat, tvec);
+                               normalize_v3(tvec);
+                               vec_to_quat(q2, tvec, OB_POSX, OB_POSZ);
+
+                               /* randomize rotation quat */
+                               if (part->randrotfac != 0.0f) {
+                                       mul_qt_qtqt(r_rot, r_rot, q_imat);
+                                       interp_qt_qtqt(rot, q2, r_rot, part->randrotfac);
+                               }
+                               else {
+                                       copy_qt_qt(rot, q2);
+                               }
+
+                               mul_qt_qtqt(rot, q_obmat, rot);
+                       }
 
                        /* rotation phase */
                        phasefac = part->phasefac;
index 26563afa65b4441019014076409f94fa6d99266c..aa68d2ac67b35e1018e2e5e10d35436070431b28 100644 (file)
@@ -684,12 +684,9 @@ void BKE_scene_set_background(Main *bmain, Scene *scene)
                }
        }
 
-       /* sort baselist */
-       DAG_scene_relations_rebuild(bmain, scene);
-       
-       /* ensure dags are built for sets */
+       /* sort baselist for scene and sets */
        for (sce = scene; sce; sce = sce->set)
-               DAG_scene_relations_update(bmain, sce);
+               DAG_scene_relations_rebuild(bmain, sce);
 
        /* copy layers and flags from bases to objects */
        for (base = scene->base.first; base; base = base->next) {
@@ -746,17 +743,16 @@ void BKE_scene_unlink(Main *bmain, Scene *sce, Scene *newsce)
 /* used by metaballs
  * doesn't return the original duplicated object, only dupli's
  */
-int BKE_scene_base_iter_next(Scene **scene, int val, Base **base, Object **ob)
+int BKE_scene_base_iter_next(SceneBaseIter *iter, Scene **scene, int val, Base **base, Object **ob)
 {
-       static ListBase *duplilist = NULL;
-       static DupliObject *dupob;
-       static int fase = F_START, in_next_object = 0;
+       static int in_next_object = 0;
        int run_again = 1;
        
        /* init */
        if (val == 0) {
-               fase = F_START;
-               dupob = NULL;
+               iter->fase = F_START;
+               iter->dupob = NULL;
+               iter->duplilist = NULL;
                
                /* XXX particle systems with metas+dupligroups call this recursively */
                /* see bug #18725 */
@@ -774,11 +770,11 @@ int BKE_scene_base_iter_next(Scene **scene, int val, Base **base, Object **ob)
                        run_again = 0;
 
                        /* the first base */
-                       if (fase == F_START) {
+                       if (iter->fase == F_START) {
                                *base = (*scene)->base.first;
                                if (*base) {
                                        *ob = (*base)->object;
-                                       fase = F_SCENE;
+                                       iter->fase = F_SCENE;
                                }
                                else {
                                        /* exception: empty scene */
@@ -787,20 +783,20 @@ int BKE_scene_base_iter_next(Scene **scene, int val, Base **base, Object **ob)
                                                if ((*scene)->base.first) {
                                                        *base = (*scene)->base.first;
                                                        *ob = (*base)->object;
-                                                       fase = F_SCENE;
+                                                       iter->fase = F_SCENE;
                                                        break;
                                                }
                                        }
                                }
                        }
                        else {
-                               if (*base && fase != F_DUPLI) {
+                               if (*base && iter->fase != F_DUPLI) {
                                        *base = (*base)->next;
                                        if (*base) {
                                                *ob = (*base)->object;
                                        }
                                        else {
-                                               if (fase == F_SCENE) {
+                                               if (iter->fase == F_SCENE) {
                                                        /* (*scene) is finished, now do the set */
                                                        while ((*scene)->set) {
                                                                (*scene) = (*scene)->set;
@@ -816,45 +812,45 @@ int BKE_scene_base_iter_next(Scene **scene, int val, Base **base, Object **ob)
                        }
                        
                        if (*base == NULL) {
-                               fase = F_START;
+                               iter->fase = F_START;
                        }
                        else {
-                               if (fase != F_DUPLI) {
+                               if (iter->fase != F_DUPLI) {
                                        if ( (*base)->object->transflag & OB_DUPLI) {
                                                /* groups cannot be duplicated for mballs yet, 
                                                 * this enters eternal loop because of 
                                                 * makeDispListMBall getting called inside of group_duplilist */
                                                if ((*base)->object->dup_group == NULL) {
-                                                       duplilist = object_duplilist((*scene), (*base)->object, FALSE);
+                                                       iter->duplilist = object_duplilist((*scene), (*base)->object, FALSE);
                                                        
-                                                       dupob = duplilist->first;
+                                                       iter->dupob = iter->duplilist->first;
 
-                                                       if (!dupob)
-                                                               free_object_duplilist(duplilist);
+                                                       if (!iter->dupob)
+                                                               free_object_duplilist(iter->duplilist);
                                                }
                                        }
                                }
                                /* handle dupli's */
-                               if (dupob) {
+                               if (iter->dupob) {
                                        
-                                       copy_m4_m4(dupob->ob->obmat, dupob->mat);
+                                       copy_m4_m4(iter->dupob->ob->obmat, iter->dupob->mat);
                                        
                                        (*base)->flag |= OB_FROMDUPLI;
-                                       *ob = dupob->ob;
-                                       fase = F_DUPLI;
+                                       *ob = iter->dupob->ob;
+                                       iter->fase = F_DUPLI;
                                        
-                                       dupob = dupob->next;
+                                       iter->dupob = iter->dupob->next;
                                }
-                               else if (fase == F_DUPLI) {
-                                       fase = F_SCENE;
+                               else if (iter->fase == F_DUPLI) {
+                                       iter->fase = F_SCENE;
                                        (*base)->flag &= ~OB_FROMDUPLI;
                                        
-                                       for (dupob = duplilist->first; dupob; dupob = dupob->next) {
-                                               copy_m4_m4(dupob->ob->obmat, dupob->omat);
+                                       for (iter->dupob = iter->duplilist->first; iter->dupob; iter->dupob = iter->dupob->next) {
+                                               copy_m4_m4(iter->dupob->ob->obmat, iter->dupob->omat);
                                        }
                                        
-                                       free_object_duplilist(duplilist);
-                                       duplilist = NULL;
+                                       free_object_duplilist(iter->duplilist);
+                                       iter->duplilist = NULL;
                                        run_again = 1;
                                }
                        }
@@ -870,7 +866,7 @@ int BKE_scene_base_iter_next(Scene **scene, int val, Base **base, Object **ob)
        /* reset recursion test */
        in_next_object = 0;
        
-       return fase;
+       return iter->fase;
 }
 
 Object *BKE_scene_camera_find(Scene *sc)
index 296f25e303e163486a68f2100cd3e26779403a4e..aec924e15b3082667d3eb51cc22d0da814295f22 100644 (file)
@@ -847,19 +847,6 @@ int txt_utf8_column_to_offset(const char *str, int column)
        return offset;
 }
 
-/* returns the real number of characters in string */
-/* not the same as BLI_strlen_utf8, which returns length for wide characters */
-static int txt_utf8_len(const char *src)
-{
-       int len;
-
-       for (len = 0; *src; len++) {
-               src += BLI_str_utf8_size(src);
-       }
-
-       return len;
-}
-
 void txt_move_up(Text *text, short sel)
 {
        TextLine **linep;
@@ -2059,7 +2046,7 @@ void txt_do_undo(Text *text)
                                text->undo_pos--;
                        }
                        buf[i] = 0;
-                       linep = txt_utf8_len(buf);
+                       linep = BLI_strlen_utf8(buf);
                        MEM_freeN(buf);
                        
                        /* skip over the length that was stored again */
index 8141fc8aaa189e6bc35ee117be66b864538d3039..2c561dd447264ae9a9a7a4e581493b1b9cacc1ee 100644 (file)
@@ -3455,7 +3455,7 @@ static bool check_point_in_stroke(bGPDstroke *stroke, float x, float y)
                prev = i;
        }
 
-       return count % 2 ? true : false;
+       return (count % 2) ? true : false;
 }
 
 /* Check whether point is inside any stroke of grease pencil layer. */
index 097c9d076a4d0dbe9c50734df777e36938efd872..a69df62f505d3f1fbb76a47e2b34a145c8c2a40f 100644 (file)
@@ -95,6 +95,11 @@ typedef struct bUnitDef {
 #define B_UNIT_DEF_SUPPRESS 1 /* Use for units that are not used enough to be translated into for common use */
 #define B_UNIT_DEF_TENTH 2 /* Display a unit even if its value is 0.1, eg 0.1mm instead of 100um */
 
+/* workaround encoding issue with "µm", bug [#36090] */
+#define B_UNIT_CHAR_MICRO "\xb5"
+#define UM B_UNIT_CHAR_MICRO"m"
+#define US B_UNIT_CHAR_MICRO"s"
+
 /* define a single unit */
 typedef struct bUnitCollection {
        struct bUnitDef *units;
@@ -116,7 +121,7 @@ static struct bUnitDef buMetricLenDef[] = {
        {"decimeter", "decimeters",     "dm",  NULL, "10 Centimeters", UN_SC_DM, 0.0, B_UNIT_DEF_SUPPRESS},
        {"centimeter", "centimeters",   "cm",  NULL, "Centimeters", UN_SC_CM, 0.0,    B_UNIT_DEF_NONE},
        {"millimeter", "millimeters",   "mm",  NULL, "Millimeters", UN_SC_MM, 0.0,    B_UNIT_DEF_NONE | B_UNIT_DEF_TENTH},
-       {"micrometer", "micrometers",   "µm",  "um", "Micrometers", UN_SC_UM, 0.0,    B_UNIT_DEF_NONE},     // micron too?
+       {"micrometer", "micrometers",   UM,    "um", "Micrometers", UN_SC_UM, 0.0,    B_UNIT_DEF_NONE},     // micron too?
 
        /* These get displayed because of float precision problems in the transform header,
         * could work around, but for now probably people wont use these */
@@ -149,7 +154,7 @@ static struct bUnitDef buMetricAreaDef[] = {
        {"square decimeter",  "square decimetees",  "dm²", "dm2",   "Square Decimeters", UN_SC_DM * UN_SC_DM, 0.0,    B_UNIT_DEF_SUPPRESS},
        {"square centimeter", "square centimeters", "cm²", "cm2",   "Square Centimeters", UN_SC_CM * UN_SC_CM, 0.0,   B_UNIT_DEF_NONE},
        {"square millimeter", "square millimeters", "mm²", "mm2",   "Square Millimeters", UN_SC_MM * UN_SC_MM, 0.0,   B_UNIT_DEF_NONE | B_UNIT_DEF_TENTH},
-       {"square micrometer", "square micrometers", "µm²", "um2",   "Square Micrometers", UN_SC_UM * UN_SC_UM, 0.0,   B_UNIT_DEF_NONE},
+       {"square micrometer", "square micrometers", UM"²", "um2",   "Square Micrometers", UN_SC_UM * UN_SC_UM, 0.0,   B_UNIT_DEF_NONE},
        {NULL, NULL, NULL,  NULL, NULL, 0.0, 0.0}
 };
 static struct bUnitCollection buMetricAreaCollection = {buMetricAreaDef, 3, 0, sizeof(buMetricAreaDef) / sizeof(bUnitDef)};
@@ -175,7 +180,7 @@ static struct bUnitDef buMetricVolDef[] = {
        {"cubic decimeter",  "cubic decimeters",  "dm³",  "dm3",  "Cubic Decimeters", UN_SC_DM * UN_SC_DM * UN_SC_DM, 0.0,    B_UNIT_DEF_SUPPRESS},
        {"cubic centimeter", "cubic centimeters", "cm³",  "cm3",  "Cubic Centimeters", UN_SC_CM * UN_SC_CM * UN_SC_CM, 0.0,   B_UNIT_DEF_NONE},
        {"cubic millimeter", "cubic millimeters", "mm³",  "mm3",  "Cubic Millimeters", UN_SC_MM * UN_SC_MM * UN_SC_MM, 0.0,   B_UNIT_DEF_NONE | B_UNIT_DEF_TENTH},
-       {"cubic micrometer", "cubic micrometers", "µm³",  "um3",  "Cubic Micrometers", UN_SC_UM * UN_SC_UM * UN_SC_UM, 0.0,   B_UNIT_DEF_NONE},
+       {"cubic micrometer", "cubic micrometers", UM"³",  "um3",  "Cubic Micrometers", UN_SC_UM * UN_SC_UM * UN_SC_UM, 0.0,   B_UNIT_DEF_NONE},
        {NULL, NULL, NULL,  NULL, NULL, 0.0, 0.0}
 };
 static struct bUnitCollection buMetricVolCollection = {buMetricVolDef, 3, 0, sizeof(buMetricVolDef) / sizeof(bUnitDef)};
@@ -253,7 +258,7 @@ static struct bUnitDef buNaturalTimeDef[] = {
        {"minute", "minutes",           "min", "m", "Minutes",      60.0, 0.0,      B_UNIT_DEF_NONE},
        {"second", "seconds",           "sec", "s", "Seconds",      1.0, 0.0,       B_UNIT_DEF_NONE}, /* base unit */
        {"millisecond", "milliseconds", "ms", NULL, "Milliseconds", 0.001, 0.0,     B_UNIT_DEF_NONE},
-       {"microsecond", "microseconds", "µs", "us", "Microseconds", 0.000001, 0.0,  B_UNIT_DEF_NONE},
+       {"microsecond", "microseconds", US,   "us", "Microseconds", 0.000001, 0.0,  B_UNIT_DEF_NONE},
        {NULL, NULL, NULL, NULL, NULL, 0.0, 0.0}
 };
 static struct bUnitCollection buNaturalTimeCollection = {buNaturalTimeDef, 3, 0, sizeof(buNaturalTimeDef) / sizeof(bUnitDef)};
@@ -273,7 +278,7 @@ static struct bUnitDef buCameraLenDef[] = {
        {"decimeter", "decimeters",     "dm",  NULL, "10 Centimeters", UN_SC_HM, 0.0, B_UNIT_DEF_SUPPRESS},
        {"centimeter", "centimeters",   "cm",  NULL, "Centimeters", UN_SC_DAM, 0.0,    B_UNIT_DEF_SUPPRESS},
        {"millimeter", "millimeters",   "mm",  NULL, "Millimeters", UN_SC_M, 0.0,    B_UNIT_DEF_NONE},
-       {"micrometer", "micrometers",   "µm",  "um", "Micrometers", UN_SC_MM, 0.0,    B_UNIT_DEF_SUPPRESS},     // micron too?
+       {"micrometer", "micrometers",   UM,    "um", "Micrometers", UN_SC_MM, 0.0,    B_UNIT_DEF_SUPPRESS},     // micron too?
        {NULL, NULL, NULL,      NULL, NULL, 0.0, 0.0}
 };
 static struct bUnitCollection buCameraLenCollection = {buCameraLenDef, 3, 0, sizeof(buCameraLenDef) / sizeof(bUnitDef)};
index 96652c0e78d2f793f6cd365add29c068b46d50e6..f9671f57acd6616e1759cfb7927014e5a4c1d305 100644 (file)
@@ -75,7 +75,8 @@ void closest_to_line_segment_v2(float closest[2], const float p[2], const float
 
 float dist_to_plane_normalized_v3(const float p[3], const float plane_co[3], const float plane_no_unit[3]);
 float dist_to_plane_v3(const float p[3], const float plane_co[3], const float plane_no[3]);
-float dist_to_line_segment_v3(const float p[3], const float l1[3], const float l2[3]);
+float dist_squared_to_line_segment_v3(const float p[3], const float l1[3], const float l2[3]);
+float         dist_to_line_segment_v3(const float p[3], const float l1[3], const float l2[3]);
 float dist_to_line_v3(const float p[3], const float l1[3], const float l2[3]);
 float closest_to_line_v3(float r[3], const float p[3], const float l1[3], const float l2[3]);
 float closest_to_line_v2(float r[2], const float p[2], const float l1[2], const float l2[2]);
index 0df4de1f8292d1d7a4103e8fc49713906f133107..304e2ea7fde62f2f572d6f2bb9188f81d347efae 100644 (file)
@@ -240,6 +240,7 @@ void rotate_normalized_v3_v3v3fl(float v[3], const float p[3], const float axis[
 void print_v2(const char *str, const float a[2]);
 void print_v3(const char *str, const float a[3]);
 void print_v4(const char *str, const float a[4]);
+void print_vn(const char *str, const float v[], const int n);
 
 MINLINE void normal_short_to_float_v3(float r[3], const short n[3]);
 MINLINE void normal_float_to_short_v3(short r[3], const float n[3]);
index d20cbd2a91cb03b2610cc0cd71121b3c7197a81e..adef843d2cc18ff439fa5252d9637a7dc06a5bd9 100644 (file)
@@ -51,8 +51,10 @@ char        *BLI_str_prev_char_utf8(const char *p);
 
 /* 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(const char *start, const size_t maxlen);
+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);
 
index 78b1f50c2e88732726a290db431b121cfc274122..28bb97689d825072119cefd958328ae74303b7ff 100644 (file)
@@ -324,21 +324,26 @@ float dist_to_plane_v3(const float p[3], const float plane_co[3], const float pl
        return line_point_factor_v3(p, plane_co, plane_co_other);
 }
 
-/* distance v1 to line-piece v2-v3 in 3D */
-float dist_to_line_segment_v3(const float v1[3], const float v2[3], const float v3[3])
+/* distance v1 to line-piece l1-l2 in 3D */
+float dist_squared_to_line_segment_v3(const float p[3], const float l1[3], const float l2[3])
 {
        float closest[3];
 
-       closest_to_line_segment_v3(closest, v1, v2, v3);
+       closest_to_line_segment_v3(closest, p, l1, l2);
 
-       return len_v3v3(closest, v1);
+       return len_squared_v3v3(closest, p);
 }
 
-float dist_to_line_v3(const float v1[3], const float v2[3], const float v3[3])
+float dist_to_line_segment_v3(const float p[3], const float l1[3], const float l2[3])
+{
+       return sqrtf(dist_squared_to_line_segment_v3(p, l1, l2));
+}
+
+float dist_to_line_v3(const float v1[3], const float l1[3], const float l2[3])
 {
        float closest[3];
 
-       closest_to_line_v3(closest, v1, v2, v3);
+       closest_to_line_v3(closest, v1, l1, l2);
 
        return len_v3v3(closest, v1);
 }
@@ -2598,45 +2603,62 @@ static float mean_value_half_tan_v2(const float v1[2], const float v2[2], const
 
 void interp_weights_poly_v3(float *w, float v[][3], const int n, const float co[3])
 {
-       /* TODO: t1 and t2 overlap each iter, we could call this only once per iter and reuse previous value */
-       float totweight, t1, t2, len, *vmid, *vprev, *vnext;
-       int i, i_next, i_curr;
+       const float eps = 0.00001f;  /* take care, low values cause [#36105] */
+       const float eps_sq = eps * eps;
+       float *v_curr, *v_next;
+       float ht_prev, ht;  /* half tangents */
+       float totweight = 0.0f;
+       int i = 0;
+       bool vert_interp = false;
        bool edge_interp = false;
 
-       totweight = 0.0f;
+       v_curr = v[0];
+       v_next = v[1];
 
-       for (i = 0; i < n; i++) {
-               i_curr = i;
-               i_next = (i == n - 1) ? 0 : i + 1;
+       ht_prev = mean_value_half_tan_v3(co, v[n - 1], v_curr);
 
-               vmid = v[i];
-               vprev = (i == 0) ? v[n - 1] : v[i - 1];
-               vnext = v[i_next];
+       while (i < n) {
+               const float len_sq = len_squared_v3v3(co, v_curr);
 
                /* Mark Mayer et al algorithm that is used here does not operate well if vertex is close
                 * to borders of face. In that case, do simple linear interpolation between the two edge vertices */
-               if (dist_to_line_segment_v3(co, vmid, vnext) < 10 * FLT_EPSILON) {
+               if (len_sq < eps_sq) {
+                       vert_interp = true;
+                       break;
+               }
+               else if (dist_squared_to_line_segment_v3(co, v_curr, v_next) < eps_sq) {
                        edge_interp = true;
                        break;
                }
 
-               t1 = mean_value_half_tan_v3(co, vprev, vmid);
-               t2 = mean_value_half_tan_v3(co, vmid, vnext);
-
-               len = len_v3v3(co, vmid);
-               w[i] = (len != 0.0f) ? (t1 + t2) / len: 0.0f;
+               ht = mean_value_half_tan_v3(co, v_curr, v_next);
+               w[i] = (ht_prev + ht) / sqrtf(len_sq);
                totweight += w[i];
+
+               /* step */
+               i++;
+               v_curr = v_next;
+               v_next = v[(i + 1) % n];
+
+               ht_prev = ht;
        }
 
-       if (edge_interp) {
-               float len_curr = len_v3v3(co, vmid);
-               float len_next = len_v3v3(co, vnext);
+       if (vert_interp) {
+               const int i_curr = i;
+               for (i = 0; i < n; i++)
+                       w[i] = 0.0;
+               w[i_curr] = 1.0f;
+       }
+       else if (edge_interp) {
+               const int i_curr = i;
+               float len_curr = len_v3v3(co, v_curr);
+               float len_next = len_v3v3(co, v_next);
                float edge_len = len_curr + len_next;
                for (i = 0; i < n; i++)
                        w[i] = 0.0;
 
                w[i_curr] = len_next / edge_len;
-               w[i_next] = len_curr / edge_len;
+               w[(i_curr + 1) % n] = len_curr / edge_len;
        }
        else {
                if (totweight != 0.0f) {
@@ -2650,45 +2672,62 @@ void interp_weights_poly_v3(float *w, float v[][3], const int n, const float co[
 
 void interp_weights_poly_v2(float *w, float v[][2], const int n, const float co[2])
 {
-       /* TODO: t1 and t2 overlap each iter, we could call this only once per iter and reuse previous value */
-       float totweight, t1, t2, len, *vmid, *vprev, *vnext;
-       int i, i_next, i_curr;
+       const float eps = 0.00001f;  /* take care, low values cause [#36105] */
+       const float eps_sq = eps * eps;
+       float *v_curr, *v_next;
+       float ht_prev, ht;  /* half tangents */
+       float totweight = 0.0f;
+       int i = 0;
+       bool vert_interp = false;
        bool edge_interp = false;
 
-       totweight = 0.0f;
+       v_curr = v[0];
+       v_next = v[1];
 
-       for (i = 0; i < n; i++) {
-               i_curr = i;
-               i_next = (i == n - 1) ? 0 : i + 1;
+       ht_prev = mean_value_half_tan_v2(co, v[n - 1], v_curr);
 
-               vmid = v[i];
-               vprev = (i == 0) ? v[n - 1] : v[i - 1];
-               vnext = v[i_next];
+       while (i < n) {
+               const float len_sq = len_squared_v2v2(co, v_curr);
 
                /* Mark Mayer et al algorithm that is used here does not operate well if vertex is close
                 * to borders of face. In that case, do simple linear interpolation between the two edge vertices */
-               if (dist_to_line_segment_v2(co, vmid, vnext) < 10 * FLT_EPSILON) {
+               if (len_sq < eps_sq) {
+                       vert_interp = true;
+                       break;
+               }
+               else if (dist_squared_to_line_segment_v2(co, v_curr, v_next) < eps_sq) {
                        edge_interp = true;
                        break;
                }
 
-               t1 = mean_value_half_tan_v2(co, vprev, vmid);
-               t2 = mean_value_half_tan_v2(co, vmid, vnext);
-
-               len = len_v2v2(co, vmid);
-               w[i] = (len != 0.0f) ? (t1 + t2) / len: 0.0f;
+               ht = mean_value_half_tan_v2(co, v_curr, v_next);
+               w[i] = (ht_prev + ht) / sqrtf(len_sq);
                totweight += w[i];
+
+               /* step */
+               i++;
+               v_curr = v_next;
+               v_next = v[(i + 1) % n];
+
+               ht_prev = ht;
        }
 
-       if (edge_interp) {
-               float len_curr = len_v2v2(co, vmid);
-               float len_next = len_v2v2(co, vnext);
+       if (vert_interp) {
+               const int i_curr = i;
+               for (i = 0; i < n; i++)
+                       w[i] = 0.0;
+               w[i_curr] = 1.0f;
+       }
+       else if (edge_interp) {
+               const int i_curr = i;
+               float len_curr = len_v2v2(co, v_curr);
+               float len_next = len_v2v2(co, v_next);
                float edge_len = len_curr + len_next;
                for (i = 0; i < n; i++)
                        w[i] = 0.0;
 
                w[i_curr] = len_next / edge_len;
-               w[i_next] = len_curr / edge_len;
+               w[(i_curr + 1) % n] = len_curr / edge_len;
        }
        else {
                if (totweight != 0.0f) {
index 298abfa8c5e2b159ee37bb5c0f0e2234baa0ec65..5efa4e4acf35bedc7cdcf726f440f43108452580 100644 (file)
@@ -790,6 +790,7 @@ void orthogonalize_m3(float mat[3][3], int axis)
                                normalize_v3(mat[2]);
                                cross_v3_v3v3(mat[1], mat[2], mat[0]);
                        }
+                       break;
                case 1:
                        if (dot_v3v3(mat[1], mat[0]) < 1) {
                                cross_v3_v3v3(mat[2], mat[0], mat[1]);
@@ -812,6 +813,7 @@ void orthogonalize_m3(float mat[3][3], int axis)
                                normalize_v3(mat[0]);
                                cross_v3_v3v3(mat[2], mat[0], mat[1]);
                        }
+                       break;
                case 2:
                        if (dot_v3v3(mat[2], mat[0]) < 1) {
                                cross_v3_v3v3(mat[1], mat[2], mat[0]);
@@ -834,6 +836,8 @@ void orthogonalize_m3(float mat[3][3], int axis)
                                normalize_v3(mat[0]);
                                cross_v3_v3v3(mat[1], mat[2], mat[0]);
                        }
+               default:
+                       BLI_assert(0);
        }
        mul_v3_fl(mat[0], size[0]);
        mul_v3_fl(mat[1], size[1]);
@@ -868,8 +872,8 @@ void orthogonalize_m4(float mat[4][4], int axis)
                                normalize_v3(mat[2]);
                                cross_v3_v3v3(mat[1], mat[2], mat[0]);
                        }
+                       break;
                case 1:
-                       normalize_v3(mat[0]);
                        if (dot_v3v3(mat[1], mat[0]) < 1) {
                                cross_v3_v3v3(mat[2], mat[0], mat[1]);
                                normalize_v3(mat[2]);
@@ -891,6 +895,7 @@ void orthogonalize_m4(float mat[4][4], int axis)
                                normalize_v3(mat[0]);
                                cross_v3_v3v3(mat[2], mat[0], mat[1]);
                        }
+                       break;
                case 2:
                        if (dot_v3v3(mat[2], mat[0]) < 1) {
                                cross_v3_v3v3(mat[1], mat[2], mat[0]);
@@ -913,6 +918,9 @@ void orthogonalize_m4(float mat[4][4], int axis)
                                normalize_v3(mat[0]);
                                cross_v3_v3v3(mat[1], mat[2], mat[0]);
                        }
+                       break;
+               default:
+                       BLI_assert(0);
        }
        mul_v3_fl(mat[0], size[0]);
        mul_v3_fl(mat[1], size[1]);
@@ -1207,16 +1215,19 @@ void mat4_to_size(float size[3], float mat[4][4])
 float mat3_to_scale(float mat[3][3])
 {
        /* unit length vector */
-       float unit_vec[3] = {0.577350269189626f, 0.577350269189626f, 0.577350269189626f};
+       float unit_vec[3];
+       copy_v3_fl(unit_vec, 0.577350269189626f);
        mul_m3_v3(mat, unit_vec);
        return len_v3(unit_vec);
 }
 
 float mat4_to_scale(float mat[4][4])
 {
-       float tmat[3][3];
-       copy_m3_m4(tmat, mat);
-       return mat3_to_scale(tmat);
+       /* unit length vector */
+       float unit_vec[3];
+       copy_v3_fl(unit_vec, 0.577350269189626f);
+       mul_mat3_m4_v3(mat, unit_vec);
+       return len_v3(unit_vec);
 }
 
 void mat3_to_rot_size(float rot[3][3], float size[3], float mat3[3][3])
index 78266c47170886254d9ac0e03fc92d4d38dd7c6a..ba0394dbc66455ad7ee0506d824bfd4e3f0aa5e5 100644 (file)
@@ -542,6 +542,16 @@ void print_v4(const char *str, const float v[4])
        printf("%s: %.3f %.3f %.3f %.3f\n", str, v[0], v[1], v[2], v[3]);
 }
 
+void print_vn(const char *str, const float v[], const int n)
+{
+       int i = 0;
+       printf("%s[%d]:", str, n);
+       while (i < n) {
+               printf(" %.3f", v[i++]);
+       }
+       printf("\n");
+}
+
 void minmax_v3v3_v3(float min[3], float max[3], const float vec[3])
 {
        if (min[0] > vec[0]) min[0] = vec[0];
index b8dca95ae3319046568e6c149bde43619f23ffbc..ab0073a7585c00293eee8a445c394742d27554ca 100644 (file)
@@ -245,24 +245,16 @@ size_t BLI_wstrlen_utf8(const wchar_t *src)
        return len;
 }
 
-/* this is very close to 'BLI_str_utf8_size' functionality, perhaps we should de-duplicate */
-/* size of UTF-8 character in bytes */
-static size_t strlen_utf8_char(const char *strc)
+size_t BLI_strlen_utf8_ex(const char *strc, int *r_len_bytes)
 {
-       if ((*strc & 0xe0) == 0xc0) {
-               if ((strc[1] & 0x80) && (strc[1] & 0x40) == 0x00)
-                       return 2;
-       }
-       else if ((*strc & 0xf0) == 0xe0) {
-               if ((strc[1] & strc[2] & 0x80) && ((strc[1] | strc[2]) & 0x40) == 0x00)
-                       return 3;
-       }
-       else if ((*strc & 0xf8) == 0xf0) {
-               if ((strc[1] & strc[2] & strc[3] & 0x80) && ((strc[1] | strc[2] | strc[3]) & 0x40) == 0x00)
-                       return 4;
-       }
+       size_t len;
+       const char *strc_orig = strc;
 
-       return 1;
+       for (len = 0; *strc; len++)
+               strc += BLI_str_utf8_size_safe(strc);
+
+       *r_len_bytes = (strc - strc_orig);
+       return len;
 }
 
 size_t BLI_strlen_utf8(const char *strc)
@@ -270,25 +262,37 @@ size_t BLI_strlen_utf8(const char *strc)
        size_t len;
 
        for (len = 0; *strc; len++)
-               strc += strlen_utf8_char(strc);
+               strc += BLI_str_utf8_size_safe(strc);
 
        return len;
 }
 
+size_t BLI_strnlen_utf8_ex(const char *strc, const size_t maxlen, int *r_len_bytes)
+{
+       size_t len;
+       const char *strc_orig = strc;
+       const char *strc_end = strc + maxlen;
+
+       for (len = 0; *strc && strc < strc_end; len++) {
+               strc += BLI_str_utf8_size_safe(strc);
+       }
+
+       *r_len_bytes = (strc - strc_orig);
+       return len;
+}
+
 /**
  * \param start the string to measure the length.
  * \param maxlen the string length (in bytes)
  * \return the unicode length (not in bytes!)
  */
-size_t BLI_strnlen_utf8(const char *start, const size_t maxlen)
+size_t BLI_strnlen_utf8(const char *strc, const size_t maxlen)
 {
-       const char *strc = start;
-       const char *strc_end = start + maxlen;
-
        size_t len;
+       const char *strc_end = strc + maxlen;
 
        for (len = 0; *strc && strc < strc_end; len++) {
-               strc += strlen_utf8_char(strc);
+               strc += BLI_str_utf8_size_safe(strc);
        }
 
        return len;
index c6856d8b71d337d398a2e905b8de967a54fbd7fb..82040020ce44e03fc19af6bbc582053d60360f85 100644 (file)
@@ -354,7 +354,7 @@ static void alphasort_version_246(FileData *fd, Library *lib, Mesh *me)
                                ma = NULL;
 
                        for (b = 0; ma && b < MAX_MTEX; b++)
-                               if (ma->mtex && ma->mtex[b] && ma->mtex[b]->mapto & MAP_ALPHA)
+                               if (ma->mtex[b] && ma->mtex[b]->mapto & MAP_ALPHA)
                                        texalpha = 1;
                }
                else {
index 9b6699f3f215ccba1db7c0f82191d559f6763b7d..dd4361be1ff704ce64b64e5797fda502181d7756 100644 (file)
@@ -1642,13 +1642,6 @@ static void write_mballs(WriteData *wd, ListBase *idbase)
        }
 }
 
-static int amount_of_chars(char *str)
-{
-       // Since the data is saved as UTF-8 to the cu->str
-       // The cu->len is not same as the strlen(cu->str)
-       return strlen(str);
-}
-
 static void write_curves(WriteData *wd, ListBase *idbase)
 {
        Curve *cu;
@@ -1666,8 +1659,12 @@ static void write_curves(WriteData *wd, ListBase *idbase)
                        if (cu->adt) write_animdata(wd, cu->adt);
                        
                        if (cu->vfont) {
-                               writedata(wd, DATA, amount_of_chars(cu->str)+1, cu->str);
-                               writestruct(wd, DATA, "CharInfo", cu->len+1, cu->strinfo);
+                               /* 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);
+
+                               writedata(wd, DATA, len_bytes + 1, cu->str);
+                               writestruct(wd, DATA, "CharInfo", len_chars + 1, cu->strinfo);
                                writestruct(wd, DATA, "TextBox", cu->totbox, cu->tb);
                        }
                        else {
index 15030f90c65d29d863c9a0ced5583a6cb4f58829..4ec0a3699d067e5908edb102ef8dee6a22f6c185 100644 (file)
@@ -803,50 +803,65 @@ static void bm_face_attrs_copy(BMesh *source_mesh, BMesh *target_mesh,
 }
 
 /* BMESH_TODO: Special handling for hide flags? */
+/* BMESH_TODO: swap src/dst args, everywhere else in bmesh does other way round */
 
 /**
  * Copies attributes, e.g. customdata, header flags, etc, from one element
  * to another of the same type.
  */
-void BM_elem_attrs_copy(BMesh *source_mesh, BMesh *target_mesh, const void *source, void *target)
+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)
 {
-       const BMHeader *sheader = source;
-       BMHeader *theader = target;
+       const BMHeader *ele_src = ele_src_v;
+       BMHeader *ele_dst = ele_dst_v;
 
-       BLI_assert(sheader->htype == theader->htype);
+       BLI_assert(ele_src->htype == ele_dst->htype);
 
-       if (sheader->htype != theader->htype) {
+       if (ele_src->htype != ele_dst->htype) {
                BLI_assert(!"type mismatch");
                return;
        }
 
-       /* First we copy select */
-       if (BM_elem_flag_test((BMElem *)sheader, BM_ELEM_SELECT)) {
-               BM_elem_select_set(target_mesh, (BMElem *)target, true);
+       if ((hflag_mask & BM_ELEM_SELECT) == 0) {
+               /* First we copy select */
+               if (BM_elem_flag_test((BMElem *)ele_src, BM_ELEM_SELECT)) {
+                       BM_elem_select_set(bm_dst, (BMElem *)ele_dst, true);
+               }
        }
-       
+
        /* Now we copy flags */
-       theader->hflag = sheader->hflag;
-       
+       if (hflag_mask == 0) {
+               ele_dst->hflag = ele_src->hflag;
+       }
+       else {
+               ele_dst->hflag = ((ele_dst->hflag & hflag_mask) | (ele_src->hflag & ~hflag_mask));
+       }
+
        /* Copy specific attributes */
-       switch (theader->htype) {
+       switch (ele_dst->htype) {
                case BM_VERT:
-                       bm_vert_attrs_copy(source_mesh, target_mesh, (const BMVert *)source, (BMVert *)target);
+                       bm_vert_attrs_copy(bm_src, bm_dst, (const BMVert *)ele_src, (BMVert *)ele_dst);
                        break;
                case BM_EDGE:
-                       bm_edge_attrs_copy(source_mesh, target_mesh, (const BMEdge *)source, (BMEdge *)target);
+                       bm_edge_attrs_copy(bm_src, bm_dst, (const BMEdge *)ele_src, (BMEdge *)ele_dst);
                        break;
                case BM_LOOP:
-                       bm_loop_attrs_copy(source_mesh, target_mesh, (const BMLoop *)source, (BMLoop *)target);
+                       bm_loop_attrs_copy(bm_src, bm_dst, (const BMLoop *)ele_src, (BMLoop *)ele_dst);
                        break;
                case BM_FACE:
-                       bm_face_attrs_copy(source_mesh, target_mesh, (const BMFace *)source, (BMFace *)target);
+                       bm_face_attrs_copy(bm_src, bm_dst, (const BMFace *)ele_src, (BMFace *)ele_dst);
                        break;
                default:
                        BLI_assert(0);
        }
 }
 
+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);
+}
+
 /* helper function for 'BM_mesh_copy' */
 static BMFace *bm_mesh_copy_new_face(BMesh *bm_new, BMesh *bm_old,
                                      BMVert **vtable, BMEdge **etable,
@@ -890,6 +905,24 @@ static BMFace *bm_mesh_copy_new_face(BMesh *bm_new, BMesh *bm_old,
        return f_new;
 }
 
+void BM_mesh_copy_init_customdata(BMesh *bm_dst, BMesh *bm_src, const BMAllocTemplate *allocsize)
+{
+       if (allocsize == NULL) {
+               allocsize = &bm_mesh_allocsize_default;
+       }
+
+       CustomData_copy(&bm_src->vdata, &bm_dst->vdata, CD_MASK_BMESH, CD_CALLOC, 0);
+       CustomData_copy(&bm_src->edata, &bm_dst->edata, CD_MASK_BMESH, CD_CALLOC, 0);
+       CustomData_copy(&bm_src->ldata, &bm_dst->ldata, CD_MASK_BMESH, CD_CALLOC, 0);
+       CustomData_copy(&bm_src->pdata, &bm_dst->pdata, CD_MASK_BMESH, CD_CALLOC, 0);
+
+       CustomData_bmesh_init_pool(&bm_dst->vdata, allocsize->totvert, BM_VERT);
+       CustomData_bmesh_init_pool(&bm_dst->edata, allocsize->totedge, BM_EDGE);
+       CustomData_bmesh_init_pool(&bm_dst->ldata, allocsize->totloop, BM_LOOP);
+       CustomData_bmesh_init_pool(&bm_dst->pdata, allocsize->totface, BM_FACE);
+}
+
+
 BMesh *BM_mesh_copy(BMesh *bm_old)
 {
        BMesh *bm_new;
@@ -908,15 +941,7 @@ BMesh *BM_mesh_copy(BMesh *bm_old)
        /* allocate a bmesh */
        bm_new = BM_mesh_create(&allocsize);
 
-       CustomData_copy(&bm_old->vdata, &bm_new->vdata, CD_MASK_BMESH, CD_CALLOC, 0);
-       CustomData_copy(&bm_old->edata, &bm_new->edata, CD_MASK_BMESH, CD_CALLOC, 0);
-       CustomData_copy(&bm_old->ldata, &bm_new->ldata, CD_MASK_BMESH, CD_CALLOC, 0);
-       CustomData_copy(&bm_old->pdata, &bm_new->pdata, CD_MASK_BMESH, CD_CALLOC, 0);
-
-       CustomData_bmesh_init_pool(&bm_new->vdata, allocsize.totvert, BM_VERT);
-       CustomData_bmesh_init_pool(&bm_new->edata, allocsize.totedge, BM_EDGE);
-       CustomData_bmesh_init_pool(&bm_new->ldata, allocsize.totloop, BM_LOOP);
-       CustomData_bmesh_init_pool(&bm_new->pdata, allocsize.totface, BM_FACE);
+       BM_mesh_copy_init_customdata(bm_new, bm_old, &allocsize);
 
        vtable = MEM_mallocN(sizeof(BMVert *) * bm_old->totvert, "BM_mesh_copy vtable");
        etable = MEM_mallocN(sizeof(BMEdge *) * bm_old->totedge, "BM_mesh_copy etable");
index 949366309b9d2e9338c5404bc346becf74c6bae9..3dcb1eb1ccb68cf28e00b60a541a4b9804e3b788 100644 (file)
@@ -27,6 +27,8 @@
  *  \ingroup bmesh
  */
 
+struct BMAllocTemplate;
+
 BMFace *BM_face_create_quad_tri_v(BMesh *bm,
                                   BMVert **verts, int len,
                                   const BMFace *example, const bool no_double);
@@ -48,8 +50,11 @@ void BMO_remove_tagged_verts(BMesh *bm, const short oflag);
 
 void BMO_remove_tagged_context(BMesh *bm, const short oflag, const int type);
 
-void BM_elem_attrs_copy(BMesh *source_mesh, BMesh *target_mesh, const void *source, void *target);
+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_mesh_copy_init_customdata(BMesh *bm_dst, BMesh *bm_src, const struct BMAllocTemplate *allocsize);
 BMesh *BM_mesh_copy(BMesh *bm_old);
 
 char  BM_face_flag_from_mflag(const char  mflag);
index b7eeceae4947879ceb229adb5d9478875621774d..ecb776e75892a7824dcc0a07e251c88124ec46ea 100644 (file)
@@ -210,7 +210,7 @@ static BMLoop *bm_face_boundary_add(BMesh *bm, BMFace *f, BMVert *startv, BMEdge
        return l;
 }
 
-BMFace *BM_face_copy(BMesh *bm, BMFace *f,
+BMFace *BM_face_copy(BMesh *bm_dst, BMesh *bm_src, BMFace *f,
                      const bool copy_verts, const bool copy_edges)
 {
        BMVert **verts = BLI_array_alloca(verts, f->len);
@@ -221,11 +221,13 @@ BMFace *BM_face_copy(BMesh *bm, BMFace *f,
        BMFace *f_copy;
        int i;
 
+       BLI_assert((bm_dst == bm_src) || (copy_verts && copy_edges));
+
        l_iter = l_first = BM_FACE_FIRST_LOOP(f);
        i = 0;
        do {
                if (copy_verts) {
-                       verts[i] = BM_vert_create(bm, l_iter->v->co, l_iter->v, 0);
+                       verts[i] = BM_vert_create(bm_dst, l_iter->v->co, l_iter->v, 0);
                }
                else {
                        verts[i] = l_iter->v;
@@ -248,7 +250,7 @@ BMFace *BM_face_copy(BMesh *bm, BMFace *f,
                                v1 = verts[(i + 1) % f->len];
                        }
                        
-                       edges[i] = BM_edge_create(bm,  v1, v2, l_iter->e, 0);
+                       edges[i] = BM_edge_create(bm_dst,  v1, v2, l_iter->e, 0);
                }
                else {
                        edges[i] = l_iter->e;
@@ -256,14 +258,14 @@ BMFace *BM_face_copy(BMesh *bm, BMFace *f,
                i++;
        } while ((l_iter = l_iter->next) != l_first);
        
-       f_copy = BM_face_create(bm, verts, edges, f->len, BM_CREATE_SKIP_CD);
+       f_copy = BM_face_create(bm_dst, verts, edges, f->len, BM_CREATE_SKIP_CD);
        
-       BM_elem_attrs_copy(bm, bm, f, f_copy);
+       BM_elem_attrs_copy(bm_src, bm_dst, f, f_copy);
        
        l_iter = l_first = BM_FACE_FIRST_LOOP(f);
        l_copy = BM_FACE_FIRST_LOOP(f_copy);
        do {
-               BM_elem_attrs_copy(bm, bm, l_iter, l_copy);
+               BM_elem_attrs_copy(bm_src, bm_dst, l_iter, l_copy);
                l_copy = l_copy->next;
        } while ((l_iter = l_iter->next) != l_first);
 
index a1f378aaa5d49dadf565760e3982f7d8e0b8f8c2..6e691a9a0b577ae5994717d9f350799593382e90 100644 (file)
@@ -27,7 +27,7 @@
  *  \ingroup bmesh
  */
 
-BMFace *BM_face_copy(BMesh *bm, BMFace *f,
+BMFace *BM_face_copy(BMesh *bm_dst, BMesh *bm_src, BMFace *f,
                      const bool copy_verts, const bool copy_edges);
 
 typedef enum eBMCreateFlag {
index 454eb201b78ba600e24a6fd68b13005927300260..446d32de5d2805cafff575ab50691651456dc8d4 100644 (file)
@@ -429,32 +429,32 @@ static void bm_loop_flip_disp(float source_axis_x[3], float source_axis_y[3],
        disp[1] = (mat[0][0] * b[1] - b[0] * mat[1][0]) / d;
 }
 
-static void bm_loop_interp_mdisps(BMesh *bm, BMLoop *target, BMFace *source)
+static void bm_loop_interp_mdisps(BMesh *bm, BMLoop *l_dst, BMFace *f_src)
 {
-       MDisps *mdisps;
+       const int cd_loop_mdisp_offset = CustomData_get_offset(&bm->ldata, CD_MDISPS);
+       MDisps *md_dst;
        float d, v1[3], v2[3], v3[3], v4[3] = {0.0f, 0.0f, 0.0f}, e1[3], e2[3];
        int ix, res;
        float axis_x[3], axis_y[3];
-       
-       /* ignore 2-edged faces */
-       if (UNLIKELY(target->f->len < 3))
+
+       if (cd_loop_mdisp_offset == -1)
                return;
        
-       if (!CustomData_has_layer(&bm->ldata, CD_MDISPS))
+       /* ignore 2-edged faces */
+       if (UNLIKELY(l_dst->f->len < 3))
                return;
+
+       md_dst = BM_ELEM_CD_GET_VOID_P(l_dst, cd_loop_mdisp_offset);
+       compute_mdisp_quad(l_dst, v1, v2, v3, v4, e1, e2);
        
-       mdisps = CustomData_bmesh_get(&bm->ldata, target->head.data, CD_MDISPS);
-       compute_mdisp_quad(target, v1, v2, v3, v4, e1, e2);
-       
-       /* if no disps data allocate a new grid, the size of the first grid in source. */
-       if (!mdisps->totdisp) {
-               MDisps *md2 = CustomData_bmesh_get(&bm->ldata, BM_FACE_FIRST_LOOP(source)->head.data, CD_MDISPS);
+       /* if no disps data allocate a new grid, the size of the first grid in f_src. */
+       if (!md_dst->totdisp) {
+               MDisps *md_src = BM_ELEM_CD_GET_VOID_P(BM_FACE_FIRST_LOOP(f_src), cd_loop_mdisp_offset);
                
-               mdisps->totdisp = md2->totdisp;
-               mdisps->level = md2->level;
-               if (mdisps->totdisp) {
-                       mdisps->disps = MEM_callocN(sizeof(float) * 3 * mdisps->totdisp,
-                                                   "mdisp->disps in bmesh_loop_intern_mdisps");
+               md_dst->totdisp = md_src->totdisp;
+               md_dst->level = md_src->level;
+               if (md_dst->totdisp) {
+                       md_dst->disps = MEM_callocN(sizeof(float) * 3 * md_dst->totdisp, __func__);
                }
                else {
                        return;
@@ -463,7 +463,7 @@ static void bm_loop_interp_mdisps(BMesh *bm, BMLoop *target, BMFace *source)
        
        mdisp_axis_from_quad(v1, v2, v3, v4, axis_x, axis_y);
 
-       res = (int)sqrt(mdisps->totdisp);
+       res = (int)sqrt(md_dst->totdisp);
        d = 1.0f / (float)(res - 1);
 #pragma omp parallel for if (res > 3)
        for (ix = 0; ix < res; ix++) {
@@ -487,18 +487,17 @@ static void bm_loop_interp_mdisps(BMesh *bm, BMLoop *target, BMFace *source)
                        mul_v3_fl(co, x);
                        add_v3_v3(co, co1);
                        
-                       l_iter = l_first = BM_FACE_FIRST_LOOP(source);
+                       l_iter = l_first = BM_FACE_FIRST_LOOP(f_src);
                        do {
                                float x2, y2;
-                               MDisps *md1, *md2;
+                               MDisps *md_src;
                                float src_axis_x[3], src_axis_y[3];
 
-                               md1 = CustomData_bmesh_get(&bm->ldata, target->head.data, CD_MDISPS);
-                               md2 = CustomData_bmesh_get(&bm->ldata, l_iter->head.data, CD_MDISPS);
+                               md_src = BM_ELEM_CD_GET_VOID_P(l_iter, cd_loop_mdisp_offset);
                                
-                               if (mdisp_in_mdispquad(target, l_iter, co, &x2, &y2, res, src_axis_x, src_axis_y)) {
-                                       old_mdisps_bilinear(md1->disps[iy * res + ix], md2->disps, res, (float)x2, (float)y2);
-                                       bm_loop_flip_disp(src_axis_x, src_axis_y, axis_x, axis_y, md1->disps[iy * res + ix]);
+                               if (mdisp_in_mdispquad(l_dst, l_iter, co, &x2, &y2, res, src_axis_x, src_axis_y)) {
+                                       old_mdisps_bilinear(md_dst->disps[iy * res + ix], md_src->disps, res, (float)x2, (float)y2);
+                                       bm_loop_flip_disp(src_axis_x, src_axis_y, axis_x, axis_y, md_dst->disps[iy * res + ix]);
 
                                        break;
                                }
@@ -513,16 +512,17 @@ static void bm_loop_interp_mdisps(BMesh *bm, BMLoop *target, BMFace *source)
  */
 void BM_face_multires_bounds_smooth(BMesh *bm, BMFace *f)
 {
+       const int cd_loop_mdisp_offset = CustomData_get_offset(&bm->ldata, CD_MDISPS);
        BMLoop *l;
        BMIter liter;
        
-       if (!CustomData_has_layer(&bm->ldata, CD_MDISPS))
+       if (cd_loop_mdisp_offset == -1)
                return;
        
        BM_ITER_ELEM (l, &liter, f, BM_LOOPS_OF_FACE) {
-               MDisps *mdp = CustomData_bmesh_get(&bm->ldata, l->prev->head.data, CD_MDISPS);
-               MDisps *mdl = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_MDISPS);
-               MDisps *mdn = CustomData_bmesh_get(&bm->ldata, l->next->head.data, CD_MDISPS);
+               MDisps *mdp = BM_ELEM_CD_GET_VOID_P(l->prev, cd_loop_mdisp_offset);
+               MDisps *mdl = BM_ELEM_CD_GET_VOID_P(l, cd_loop_mdisp_offset);
+               MDisps *mdn = BM_ELEM_CD_GET_VOID_P(l->next, cd_loop_mdisp_offset);
                float co1[3];
                int sides;
                int y;
@@ -551,7 +551,7 @@ void BM_face_multires_bounds_smooth(BMesh *bm, BMFace *f)
        }
        
        BM_ITER_ELEM (l, &liter, f, BM_LOOPS_OF_FACE) {
-               MDisps *mdl1 = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_MDISPS);
+               MDisps *mdl1 = BM_ELEM_CD_GET_VOID_P(l, cd_loop_mdisp_offset);
                MDisps *mdl2;
                float co1[3], co2[3], co[3];
                int sides;
@@ -575,9 +575,9 @@ void BM_face_multires_bounds_smooth(BMesh *bm, BMFace *f)
                        continue;
 
                if (l->radial_next->v == l->v)
-                       mdl2 = CustomData_bmesh_get(&bm->ldata, l->radial_next->head.data, CD_MDISPS);
+                       mdl2 = BM_ELEM_CD_GET_VOID_P(l->radial_next, cd_loop_mdisp_offset);
                else
-                       mdl2 = CustomData_bmesh_get(&bm->ldata, l->radial_next->next->head.data, CD_MDISPS);
+                       mdl2 = BM_ELEM_CD_GET_VOID_P(l->radial_next->next, cd_loop_mdisp_offset);
 
                sides = (int)sqrt(mdl1->totdisp);
                for (y = 0; y < sides; y++) {
@@ -640,8 +640,6 @@ void BM_loop_interp_from_face(BMesh *bm, BMLoop *target, BMFace *source,
        /* convert the 3d coords into 2d for projection */
        axis_dominant_v3_to_m3(axis_mat, source->no);
 
-       BM_elem_attrs_copy(bm, bm, source, target->f);
-
        i = 0;
        l_iter = l_first = BM_FACE_FIRST_LOOP(source);
        do {
@@ -663,9 +661,7 @@ void BM_loop_interp_from_face(BMesh *bm, BMLoop *target, BMFace *source,
        }
 
        if (do_multires) {
-               if (CustomData_has_layer(&bm->ldata, CD_MDISPS)) {
-                       bm_loop_interp_mdisps(bm, target, source);
-               }
+               bm_loop_interp_mdisps(bm, target, source);
        }
 }
 
index 4027d4b2c19965e237708e0be2121a5eaa3d986b..64368390444ee624519286d51c1196bd22378f06 100644 (file)
@@ -240,7 +240,7 @@ void BM_mesh_clear(BMesh *bm)
        bm_mempool_init(bm, &bm_mesh_allocsize_default);
 
        bm->stackdepth = 1;
-       bm->totflags = 1;
+       bm->totflags = 0;
 
        CustomData_reset(&bm->vdata);
        CustomData_reset(&bm->edata);
index c75843f029abf90aa3c2d642493c97c16df3e291..cb8e9bd70040d9fa343781bd9f054000fb8f176b 100644 (file)
@@ -345,7 +345,7 @@ BMFace *BM_face_split(BMesh *bm, BMFace *f, BMVert *v1, BMVert *v2, BMLoop **r_l
 
        /* do we have a multires layer? */
        if (has_mdisp) {
-               f_tmp = BM_face_copy(bm, f, false, false);
+               f_tmp = BM_face_copy(bm, bm, f, false, false);
        }
        
 #ifdef USE_BMESH_HOLES
@@ -414,7 +414,7 @@ BMFace *BM_face_split_n(BMesh *bm, BMFace *f, BMVert *v1, BMVert *v2, float cos[
 
        BLI_assert(v1 != v2);
 
-       f_tmp = BM_face_copy(bm, f, true, true);
+       f_tmp = BM_face_copy(bm, bm, f, true, true);
 
        if (!r_l)
                r_l = &l_dummy;
@@ -662,7 +662,7 @@ BMVert *BM_edge_split(BMesh *bm, BMEdge *e, BMVert *v, BMEdge **r_e, float perce
                /* flag existing faces so we can differentiate oldfaces from new faces */
                for (i = 0; i < BLI_array_count(oldfaces); i++) {
                        BM_ELEM_API_FLAG_ENABLE(oldfaces[i], _FLAG_OVERLAP);
-                       oldfaces[i] = BM_face_copy(bm, oldfaces[i], true, true);
+                       oldfaces[i] = BM_face_copy(bm, bm, oldfaces[i], true, true);
                        BM_ELEM_API_FLAG_DISABLE(oldfaces[i], _FLAG_OVERLAP);
                }
        }
index 3ffdbe167d726498edb78ddc6ea8833481e69a19..7f8b40d85dc507b7b5155785d129d9f6fbd629b0 100644 (file)
@@ -1248,7 +1248,7 @@ static void bmo_flag_layer_free(BMesh *bm)
                        /* now go through and memcpy all the flag */
                        BM_ITER_MESH_INDEX (ele, &iter, bm, BM_VERTS_OF_MESH, i) {
                                void *oldflags = ele->oflags;
-                               ele->oflags = BLI_mempool_calloc(newpool);
+                               ele->oflags = BLI_mempool_alloc(newpool);
                                memcpy(ele->oflags, oldflags, new_totflags_size);
                                BM_elem_index_set(ele, i); /* set_inline */
                                BM_ELEM_API_FLAG_CLEAR((BMElemF *)ele);
@@ -1264,7 +1264,7 @@ static void bmo_flag_layer_free(BMesh *bm)
 
                        BM_ITER_MESH_INDEX (ele, &iter, bm, BM_EDGES_OF_MESH, i) {
                                void *oldflags = ele->oflags;
-                               ele->oflags = BLI_mempool_calloc(newpool);
+                               ele->oflags = BLI_mempool_alloc(newpool);
                                memcpy(ele->oflags, oldflags, new_totflags_size);
                                BM_elem_index_set(ele, i); /* set_inline */
                                BM_ELEM_API_FLAG_CLEAR((BMElemF *)ele);
@@ -1280,7 +1280,7 @@ static void bmo_flag_layer_free(BMesh *bm)
 
                        BM_ITER_MESH_INDEX (ele, &iter, bm, BM_FACES_OF_MESH, i) {
                                void *oldflags = ele->oflags;
-                               ele->oflags = BLI_mempool_calloc(newpool);
+                               ele->oflags = BLI_mempool_alloc(newpool);
                                memcpy(ele->oflags, oldflags, new_totflags_size);
                                BM_elem_index_set(ele, i); /* set_inline */
                                BM_ELEM_API_FLAG_CLEAR((BMElemF *)ele);
index 6b124a3030a037f8cd1391e030d1789d58e84cb9..61421b0bec24cc84720b882f58507787e673e20f 100644 (file)
@@ -144,11 +144,13 @@ static void bridge_loop_pair(BMesh *bm,
                              struct BMEdgeLoopStore *el_store_b,
                              const bool use_merge, const float merge_factor)
 {
+       const float eps = 0.00001f;
        LinkData *el_a_first, *el_b_first;
        const bool is_closed = BM_edgeloop_is_closed(el_store_a) && BM_edgeloop_is_closed(el_store_b);
        int el_store_a_len, el_store_b_len;
        bool el_store_b_free = false;
        float el_dir[3];
+       float dot_a, dot_b;
        const bool use_edgeout = true;
 
        el_store_a_len = BM_edgeloop_length_get((struct BMEdgeLoopStore *)el_store_a);
@@ -202,9 +204,22 @@ static void bridge_loop_pair(BMesh *bm,
                BM_edgeloop_calc_normal_aligned(bm, el_store_b, no);
        }
 
-       if ((dot_v3v3(BM_edgeloop_normal_get(el_store_a), el_dir) < 0.0f) !=
-               (dot_v3v3(BM_edgeloop_normal_get(el_store_b), el_dir) < 0.0f))
+       dot_a = dot_v3v3(BM_edgeloop_normal_get(el_store_a), el_dir);
+       dot_b = dot_v3v3(BM_edgeloop_normal_get(el_store_b), el_dir);
+
+       if (UNLIKELY((len_squared_v3(el_dir) < eps) ||
+                    ((fabsf(dot_a) < eps) && (fabsf(dot_b) < eps))))
        {
+               /* in this case there is no depth between the two loops,
+                * eg: 2x 2d circles, one scaled smaller,
+                * in this case 'el_dir' cant be used, just ensure we have matching flipping. */
+               if (dot_v3v3(BM_edgeloop_normal_get(el_store_a),
+                            BM_edgeloop_normal_get(el_store_b)) < 0.0f)
+               {
+                       BM_edgeloop_flip(bm, el_store_b);
+               }
+       }
+       else if ((dot_a < 0.0f) != (dot_b < 0.0f)) {
                BM_edgeloop_flip(bm, el_store_b);
        }
 
index a56cdeec629821391dd8cf09d0a48d976c2baaaa..872f1cea2c7a4ece0ff5cd67b1c8e28eaf3ff23e 100644 (file)
@@ -381,7 +381,7 @@ void bmo_connect_vert_pair_exec(BMesh *bm, BMOperator *op)
        pc.v_b = ((BMVert **)op_verts_slot->data.p)[1];
 
        /* fail! */
-       if (!(pc.v_a && pc.v_a)) {
+       if (!(pc.v_a && pc.v_b)) {
                return;
        }
 
index c4200a377480eb9afbb55b2fb2c97479083d4e65..4291fc22793e840d8c2820151fa9f741a20db294 100644 (file)
@@ -56,7 +56,7 @@ static bool bmo_recalc_normal_edge_filter_cb(BMEdge *e, void *UNUSED(user_data))
  */
 static void bmo_recalc_face_normals_array(BMesh *bm, BMFace **faces, const int faces_len, const short oflag)
 {
-       float cent[3];
+       float cent[3], tvec[3];
        float (*faces_center)[3] = MEM_mallocN(sizeof(*faces_center) * faces_len, __func__);
        const float cent_fac = 1.0f / (float)faces_len;
        int i, f_start_index;
@@ -91,7 +91,8 @@ static void bmo_recalc_face_normals_array(BMesh *bm, BMFace **faces, const int f
        }
 
        /* make sure the starting face has the correct winding */
-       if (dot_v3v3(faces_center[f_start_index], faces[f_start_index]->no) < 0.0f) {
+       sub_v3_v3v3(tvec, faces_center[f_start_index], cent);
+       if (dot_v3v3(tvec, faces[f_start_index]->no) < 0.0f) {
                BMO_elem_flag_enable(bm, faces[f_start_index], FACE_FLIP);
        }
 
index e0c11414e38dcca57091f59d9a4bd21f2b24a403..6431b6b7cf5f64b89bec70e21f1198791d8ae8d7 100644 (file)
@@ -1941,26 +1941,35 @@ static void bevel_vert_construct(BMesh *bm, BevelParams *bp, BMVert *v)
        int i, found_shared_face, ccw_test_sum;
        int nsel = 0;
        int ntot = 0;
+       int fcnt;
 
        /* Gather input selected edges.
         * Only bevel selected edges that have exactly two incident faces.
+        * Want edges to be ordered so that they share faces.
+        * There may be one or more chains of shared faces broken by
+        * gaps where there are no faces.
+        * TODO: make following work when more than one gap.
         */
 
-       if (bp->vertex_only)
-               first_bme = v->e;
-       else
-               first_bme = NULL;
+       first_bme = NULL;
        BM_ITER_ELEM (bme, &iter, v, BM_EDGES_OF_VERT) {
+               fcnt = BM_edge_face_count(bme);
                if (BM_elem_flag_test(bme, BM_ELEM_TAG) && !bp->vertex_only) {
-                       BLI_assert(BM_edge_is_manifold(bme));
+                       BLI_assert(fcnt == 2);
                        nsel++;
                        if (!first_bme)
                                first_bme = bme;
                }
+               if (fcnt == 1) {
+                       /* good to start face chain from this edge */
+                       first_bme = bme;
+               }
                ntot++;
 
                BM_BEVEL_EDGE_TAG_DISABLE(bme);
        }
+       if (!first_bme)
+               first_bme = v->e;
 
        if ((nsel == 0 && !bp->vertex_only) || (ntot < 3 && bp->vertex_only)) {
                /* signal this vert isn't being beveled */
index 4c4b77ba6cc5a12b028b677c1b5ebfe73c37d1da..d2598e661a96afe8da7565ba6fc7ab64c89a9527 100644 (file)
@@ -47,7 +47,7 @@ void ChromaMatteNode::convertToOperations(ExecutionSystem *graph, CompositorCont
        operation->setSettings((NodeChroma *)editorsnode->storage);
 
        inputSocketImage->relinkConnections(operationRGBToYCC_Image->getInputSocket(0), 0, graph);
-       inputSocketKey->relinkConnections(operationRGBToYCC_Key->getInputSocket(0), 0, graph);
+       inputSocketKey->relinkConnections(operationRGBToYCC_Key->getInputSocket(0), 1, graph);
 
        addLink(graph, operationRGBToYCC_Image->getOutputSocket(), operation->getInputSocket(0));
        addLink(graph, operationRGBToYCC_Key->getOutputSocket(), operation->getInputSocket(1));
index 95f06e350b10b05c3e08c6b2f5a0ae9e4bd18dad..b48d974e8932238ff9399cdbb9d756a00c665691 100644 (file)
@@ -34,7 +34,7 @@
 
 void ZCombineNode::convertToOperations(ExecutionSystem *system, CompositorContext *context)
 {
-       if (context->getRenderData()->scemode & R_FULL_SAMPLE) {
+       if ((context->getRenderData()->scemode & R_FULL_SAMPLE) || this->getbNode()->custom2) {
                if (this->getOutputSocket(0)->isConnected()) {
                        ZCombineOperation *operation = NULL;
                        if (this->getbNode()->custom1) {
index e8268adff7a0f8c781e5b12a29e9570a44c2021a..0c67da2d55222fa14f4d02214923aa8c8e8f4aad 100644 (file)
@@ -53,33 +53,34 @@ void *CalculateStandardDeviationOperation::initializeTileData(rcti *rect)
                                pixels++;
                
                                switch (this->m_setting) {
-                                       case 1:
+                                       case 1:  /* rgb combined */
                                        {
                                                float value = rgb_to_bw(&buffer[offset]);
                                                sum += (value - mean) * (value - mean);
                                                break;
                                        }
-                                       case 2:
+                                       case 2:  /* red */
                                        {
                                                float value = buffer[offset];
                                                sum += value;
                                                sum += (value - mean) * (value - mean);
                                                break;
                                        }
-                                       case 3:
+                                       case 3:  /* green */
                                        {
                                                float value = buffer[offset + 1];
                                                sum += value;
                                                sum += (value - mean) * (value - mean);
                                                break;
                                        }
-                                       case 4:
+                                       case 4:  /* blue */
                                        {
                                                float value = buffer[offset + 2];
                                                sum += value;
                                                sum += (value - mean) * (value - mean);
+                                               break;
                                        }
-                                       case 5:
+                                       case 5:  /* luminance */
                                        {
                                                float yuv[3];
                                                rgb_to_yuv(buffer[offset], buffer[offset + 1], buffer[offset + 2], &yuv[0], &yuv[1], &yuv[2]);
index f3edb61f48791e3fde54096c5de55b9ae554adca..da76ad8a832e2b03f8c2c2bfd5d211441be26fe4 100644 (file)
@@ -401,7 +401,7 @@ static void draw_marker(View2D *v2d, TimeMarker *marker, int cfra, int flag)
        glDisable(GL_BLEND);
        
        /* and the marker name too, shifted slightly to the top-right */
-       if (marker->name && marker->name[0]) {
+       if (marker->name[0]) {
                float x, y;
 
                /* minimal y coordinate which wouldn't be occluded by scroll */
index d5dbe80538ff6fae3767b8f1d825e4ab676e1734..289901076a17efb90227d526a34077822cd468e9 100644 (file)
@@ -170,7 +170,7 @@ static void joined_armature_fix_links(Object *tarArm, Object *srcArm, bPoseChann
 }
 
 /* join armature exec is exported for use in object->join objects operator... */
-int join_armature_exec(bContext *C, wmOperator *UNUSED(op))
+int join_armature_exec(bContext *C, wmOperator *op)
 {
        Main *bmain = CTX_data_main(C);
        Scene *scene = CTX_data_scene(C);
@@ -180,6 +180,7 @@ int join_armature_exec(bContext *C, wmOperator *UNUSED(op))
        bPoseChannel *pchan, *pchann;
        EditBone *curbone;
        float mat[4][4], oimat[4][4];
+       bool ok = false;
        
        /*      Ensure we're not in editmode and that the active object is an armature*/
        if (!ob || ob->type != OB_ARMATURE)
@@ -187,6 +188,21 @@ int join_armature_exec(bContext *C, wmOperator *UNUSED(op))
        if (!arm || arm->edbo)
                return OPERATOR_CANCELLED;
        
+       CTX_DATA_BEGIN(C, Base *, base, selected_editable_bases)
+       {
+               if (base->object == ob) {
+                       ok = true;
+                       break;
+               }
+       }
+       CTX_DATA_END;
+
+       /* that way the active object is always selected */
+       if (ok == false) {
+               BKE_report(op->reports, RPT_WARNING, "Active object is not a selected armature");
+               return OPERATOR_CANCELLED;
+       }
+
        /* Get editbones of active armature to add editbones to */
        ED_armature_to_edit(ob);
        
index 4120be08b46a2b7821f768883cbc4d8d12ea3948..cfee6c346000251afab6beb5950d0cfc6302acde 100644 (file)
@@ -588,6 +588,60 @@ void ED_armature_to_edit(Object *ob)
 /* *************************************************************** */
 /* Undo for Armature EditMode*/
 
+/* free's bones and their properties */
+
+static void ED_armature_ebone_listbase_free(ListBase *lb)
+{
+       EditBone *ebone, *ebone_next;
+
+       for (ebone = lb->first; ebone; ebone = ebone_next) {
+               ebone_next = ebone->next;
+
+               if (ebone->prop) {
+                       IDP_FreeProperty(ebone->prop);
+                       MEM_freeN(ebone->prop);
+               }
+
+               MEM_freeN(ebone);
+       }
+
+       lb->first = NULL;
+       lb->last = NULL;
+}
+
+static void ED_armature_ebone_listbase_copy(ListBase *lb_dst, ListBase *lb_src)
+{
+       EditBone *ebone_src;
+       EditBone *ebone_dst;
+
+       BLI_assert(lb_dst->first == NULL);
+
+       for (ebone_src = lb_src->first; ebone_src; ebone_src = ebone_src->next) {
+               ebone_dst = MEM_dupallocN(ebone_src);
+               if (ebone_dst->prop) {
+                       ebone_dst->prop = IDP_CopyProperty(ebone_dst->prop);
+               }
+               ebone_src->temp = ebone_dst;
+               BLI_addtail(lb_dst, ebone_dst);
+       }
+
+       /* set pointers */
+       for (ebone_dst = lb_dst->first; ebone_dst; ebone_dst = ebone_dst->next) {
+               if (ebone_dst->parent) {
+                       ebone_dst->parent = ebone_dst->parent->temp;
+               }
+       }
+}
+
+static void ED_armature_ebone_listbase_temp_clear(ListBase *lb)
+{
+       EditBone *ebone;
+       /* be sure they don't hang ever */
+       for (ebone = lb->first; ebone; ebone = ebone->next) {
+               ebone->temp = NULL;
+       }
+}
+
 typedef struct UndoArmature {
        EditBone *act_edbone;
        ListBase lb;
@@ -597,60 +651,40 @@ static void undoBones_to_editBones(void *uarmv, void *armv, void *UNUSED(data))
 {
        UndoArmature *uarm = uarmv;
        bArmature *arm = armv;
-       EditBone *ebo, *newebo;
+       EditBone *ebone;
        
-       BLI_freelistN(arm->edbo);
-       
-       /* copy  */
-       for (ebo = uarm->lb.first; ebo; ebo = ebo->next) {
-               newebo = MEM_dupallocN(ebo);
-               ebo->temp = newebo;
-               BLI_addtail(arm->edbo, newebo);
-       }
+       ED_armature_ebone_listbase_free(arm->edbo);
+       ED_armature_ebone_listbase_copy(arm->edbo, &uarm->lb);
        
        /* active bone */
        if (uarm->act_edbone) {
-               ebo = uarm->act_edbone;
-               arm->act_edbone = ebo->temp;
+               ebone = uarm->act_edbone;
+               arm->act_edbone = ebone->temp;
        }
-       else
+       else {
                arm->act_edbone = NULL;
-
-       /* set pointers */
-       for (newebo = arm->edbo->first; newebo; newebo = newebo->next) {
-               if (newebo->parent) newebo->parent = newebo->parent->temp;
-       }
-       /* be sure they don't hang ever */
-       for (newebo = arm->edbo->first; newebo; newebo = newebo->next) {
-               newebo->temp = NULL;
        }
+
+       ED_armature_ebone_listbase_temp_clear(arm->edbo);
 }
 
 static void *editBones_to_undoBones(void *armv, void *UNUSED(obdata))
 {
        bArmature *arm = armv;
        UndoArmature *uarm;
-       EditBone *ebo, *newebo;
+       EditBone *ebone;
        
        uarm = MEM_callocN(sizeof(UndoArmature), "listbase undo");
        
-       /* copy */
-       for (ebo = arm->edbo->first; ebo; ebo = ebo->next) {
-               newebo = MEM_dupallocN(ebo);
-               ebo->temp = newebo;
-               BLI_addtail(&uarm->lb, newebo);
-       }
+       ED_armature_ebone_listbase_copy(&uarm->lb, arm->edbo);
        
        /* active bone */
        if (arm->act_edbone) {
-               ebo = arm->act_edbone;
-               uarm->act_edbone = ebo->temp;
+               ebone = arm->act_edbone;
+               uarm->act_edbone = ebone->temp;
        }
 
-       /* set pointers */
-       for (newebo = uarm->lb.first; newebo; newebo = newebo->next) {
-               if (newebo->parent) newebo->parent = newebo->parent->temp;
-       }
+       ED_armature_ebone_listbase_temp_clear(&uarm->lb);
        
        return uarm;
 }
@@ -659,7 +693,8 @@ static void free_undoBones(void *uarmv)
 {
        UndoArmature *uarm = uarmv;
        
-       BLI_freelistN(&uarm->lb);
+       ED_armature_ebone_listbase_free(&uarm->lb);
+
        MEM_freeN(uarm);
 }
 
index 0f96e886ef3b069c85bc6cab7c667f761cee5796..75de4e137071ffa307b1057be3a64e9c17449492 100644 (file)
@@ -6100,7 +6100,7 @@ void CURVE_OT_shade_flat(wmOperatorType *ot)
 
 /************** join operator, to be used externally? ****************/
 /* TODO: shape keys - as with meshes */
-int join_curve_exec(bContext *C, wmOperator *UNUSED(op))
+int join_curve_exec(bContext *C, wmOperator *op)
 {
        Main *bmain = CTX_data_main(C);
        Scene *scene = CTX_data_scene(C);
@@ -6112,6 +6112,22 @@ int join_curve_exec(bContext *C, wmOperator *UNUSED(op))
        ListBase tempbase;
        float imat[4][4], cmat[4][4];
        int a;
+       bool ok = false;
+
+       CTX_DATA_BEGIN(C, Base *, base, selected_editable_bases)
+       {
+               if (base->object == ob) {
+                       ok = true;
+                       break;
+               }
+       }
+       CTX_DATA_END;
+
+       /* that way the active object is always selected */
+       if (ok == false) {
+               BKE_report(op->reports, RPT_WARNING, "Active object is not a selected curve");
+               return OPERATOR_CANCELLED;
+       }
 
        tempbase.first = tempbase.last = NULL;
        
index 51d5d42394cd48b8411395fc8abd51923fc61208..fd08039c24b2f71ed45faa7acf8570ab40d1254e 100644 (file)
@@ -95,6 +95,7 @@ void EDBM_selectmode_to_scene(struct bContext *C);
 void EDBM_mesh_make(struct ToolSettings *ts, struct Scene *scene, struct Object *ob);
 void EDBM_mesh_free(struct BMEditMesh *em);
 void EDBM_mesh_load(struct Object *ob);
+struct DerivedMesh *EDBM_mesh_deform_dm_get(struct BMEditMesh *em);
 
 void           EDBM_index_arrays_ensure(struct BMEditMesh *em, const char htype);
 void           EDBM_index_arrays_init(struct BMEditMesh *em, const char htype);
index e8e7643164f82215a35bc973d43e7b8cbd77c131..bdfbbbb9c7434351a535947b5ec640c1e4c8eabf 100644 (file)
@@ -52,7 +52,7 @@ void ED_render_engine_changed(struct Main *bmain);
 void ED_render_engine_area_exit(struct ScrArea *sa);
 void ED_render_scene_update(struct Main *bmain, struct Scene *scene, int updated);
 
-void ED_viewport_render_kill_jobs(const struct bContext *C);
+void ED_viewport_render_kill_jobs(const struct bContext *C, bool free_database);
 
 /* render_preview.c */
 
index b566fd360b6081e0628b54730d9232d8f6208aa0..e5cc0dd8ea726d31ddc28fd04aed3edbb4e0ba9c 100644 (file)
@@ -236,6 +236,8 @@ typedef enum {
        BUT_NORMAL    = (31 << 9),
        BUT_CURVE     = (32 << 9),
        ICONTOGN      = (34 << 9),
+       LISTBOX       = (35 << 9),
+       LISTROW       = (36 << 9),
        TOGBUT        = (37 << 9),
        OPTION        = (38 << 9),
        OPTIONN       = (39 << 9),
@@ -244,8 +246,6 @@ typedef enum {
        SEARCH_MENU   = (41 << 9),
        BUT_EXTRA     = (42 << 9),
        HSVCIRCLE     = (43 << 9),
-       LISTBOX       = (44 << 9),
-       LISTROW       = (45 << 9),
        HOTKEYEVT     = (46 << 9),
        BUT_IMAGE     = (47 << 9),
        HISTOGRAM     = (48 << 9),
index 9ac499fc94b790ad255ecf2d67cd18f201bc77f6..097f042d6c9a2dff2cb33f11711e64943c25bac1 100644 (file)
@@ -2167,6 +2167,15 @@ static void ui_set_but_soft_range(uiBut *but)
                but->softmin = softmin;
                but->softmax = softmax;
        }
+       else if (but->poin && (but->pointype & UI_BUT_POIN_TYPES)) {
+               float value = ui_get_but_val(but);
+               CLAMP(value, but->hardmin, but->hardmax);
+               but->softmin = min_ff(but->softmin, value);
+               but->softmax = max_ff(but->softmax, value);
+       }
+       else {
+               BLI_assert(0);
+       }
 }
 
 /* ******************* Free ********************/
@@ -2368,8 +2377,12 @@ void ui_check_but(uiBut *but)
        ui_check_but_select(but, &value);
        
        /* only update soft range while not editing */
-       if (but->rnaprop && !(but->editval || but->editstr || but->editvec)) {
-               ui_set_but_soft_range(but);
+       if (!(but->editval || but->editstr || but->editvec)) {
+               if ((but->rnaprop != NULL) ||
+                   (but->poin && (but->pointype & UI_BUT_POIN_TYPES)))
+               {
+                       ui_set_but_soft_range(but);
+               }
        }
 
        /* test for min and max, icon sliders, etc */
@@ -2757,13 +2770,10 @@ static uiBut *ui_def_but(uiBlock *block, int type, int retval, const char *str,
        uiBut *but;
        int slen;
 
-       BLI_assert(width >= 0);
-       BLI_assert(height >= 0);
+       BLI_assert(width >= 0 && height >= 0);
        
        /* we could do some more error checks here */
        if ((type & BUTTYPE) == LABEL) {
-               if ((poin != NULL || min != 0.0f || max != 0.0f || (a1 == 0.0f && a2 != 0.0f) || (a1 != 0.0f && a1 != 1.0f)))
-                       printf("blah\n");
                BLI_assert((poin != NULL || min != 0.0f || max != 0.0f || (a1 == 0.0f && a2 != 0.0f) || (a1 != 0.0f && a1 != 1.0f)) == FALSE);
        }
 
@@ -2851,7 +2861,7 @@ static uiBut *ui_def_but(uiBlock *block, int type, int retval, const char *str,
        }
 
        /* keep track of UI_interface.h */
-       if      (ELEM9(but->type, BLOCK, BUT, LABEL, PULLDOWN, ROUNDBOX, LISTBOX, BUTM, SCROLL, SEPR /* , FTPREVIEW */)) {}
+       if      (ELEM8(but->type, BLOCK, BUT, LABEL, PULLDOWN, ROUNDBOX, BUTM, SCROLL, SEPR)) {}
        else if (but->type >= SEARCH_MENU) {}
        else but->flag |= UI_BUT_UNDO;
 
@@ -4132,6 +4142,7 @@ void uiButGetStrInfo(bContext *C, uiBut *but, ...)
 
                si->strinfo = tmp;
        }
+       va_end(args);
 
        if (free_items && items)
                MEM_freeN(items);
index 342c0569f411080939c13a1f3f9c72b2be195b8e..68cf07f695fb6a8d165cc11269461ab8d7174b87 100644 (file)
@@ -875,6 +875,10 @@ static bool ui_but_start_drag(bContext *C, uiBut *but, uiHandleButtonData *data,
                        uiDragToggleHandle *drag_info = MEM_callocN(sizeof(*drag_info), __func__);
                        ARegion *ar_prev;
 
+                       /* call here because regular mouse-up event wont run,
+                        * typically 'button_activate_exit()' handles this */
+                       ui_apply_autokey(C, but);
+
                        drag_info->is_set = ui_is_but_push(but);
                        drag_info->but_cent_start[0] = BLI_rctf_cent_x(&but->rect);
                        drag_info->but_cent_start[1] = BLI_rctf_cent_y(&but->rect);
@@ -1297,9 +1301,14 @@ static void ui_but_drop(bContext *C, const wmEvent *event, uiBut *but, uiHandleB
                        if (ELEM3(but->type, TEX, SEARCH_MENU, SEARCH_MENU_UNLINK)) {
                                ID *id = (ID *)wmd->poin;
                                
-                               if (but->poin == NULL && but->rnapoin.data == NULL) {}
                                button_activate_state(C, but, BUTTON_STATE_TEXT_EDITING);
                                BLI_strncpy(data->str, id->name + 2, data->maxlen);
+
+                               if (ELEM(but->type, SEARCH_MENU, SEARCH_MENU_UNLINK)) {
+                                       but->changed = true;
+                                       ui_searchbox_update(C, data->searchbox, but, true);
+                               }
+
                                button_activate_state(C, but, BUTTON_STATE_EXIT);
                        }
                }
@@ -1420,6 +1429,7 @@ static void ui_but_copy_paste(bContext *C, uiBut *but, uiHandleButtonData *data,
 
                        if (ELEM(but->type, SEARCH_MENU, SEARCH_MENU_UNLINK)) {
                                /* else uiSearchboxData.active member is not updated [#26856] */
+                               but->changed = true;
                                ui_searchbox_update(C, data->searchbox, but, true);
                        }
                        button_activate_state(C, but, BUTTON_STATE_EXIT);
@@ -3711,7 +3721,7 @@ static bool ui_numedit_but_HSVCUBE(uiBut *but, uiHandleButtonData *data, int mx,
 
                        break;
                default:
-                       assert(!"invalid hsv type");
+                       BLI_assert(0);
        }
 
        hsv_to_rgb_v(hsv, rgb);
@@ -3781,6 +3791,7 @@ static void ui_ndofedit_but_HSVCUBE(uiBut *but, uiHandleButtonData *data, wmNDOF
                        hsv[2] += ndof->rx * sensitivity;
                        
                        CLAMP(hsv[2], but->softmin, but->softmax);
+                       break;
                default:
                        assert(!"invalid hsv type");
        }
@@ -6413,7 +6424,6 @@ static int ui_handle_list_event(bContext *C, const wmEvent *event, ARegion *ar)
 {
        uiBut *but = ui_list_find_mouse_over(ar, event->x, event->y);
        int retval = WM_UI_HANDLER_CONTINUE;
-       int value, min, max;
        int type = event->type, val = event->val;
 
        if (but) {
@@ -6436,8 +6446,11 @@ static int ui_handle_list_event(bContext *C, const wmEvent *event, ARegion *ar)
                                if (ELEM(type, UPARROWKEY, DOWNARROWKEY) ||
                                        ((ELEM(type, WHEELUPMOUSE, WHEELDOWNMOUSE) && event->alt)))
                                {
+                                       const int value_orig = RNA_property_int_get(&but->rnapoin, but->rnaprop);
+                                       int value, min, max;
+
                                        /* activate up/down the list */
-                                       value = RNA_property_int_get(&but->rnapoin, but->rnaprop);
+                                       value = value_orig;
 
                                        if (ELEM(type, UPARROWKEY, WHEELUPMOUSE))
                                                value--;
@@ -6454,9 +6467,13 @@ static int ui_handle_list_event(bContext *C, const wmEvent *event, ARegion *ar)
                                        RNA_property_int_range(&but->rnapoin, but->rnaprop, &min, &max);
                                        value = CLAMPIS(value, min, max);
 
-                                       RNA_property_int_set(&but->rnapoin, but->rnaprop, value);
-                                       RNA_property_update(C, &but->rnapoin, but->rnaprop);
-                                       ED_region_tag_redraw(ar);
+                                       if (value != value_orig) {
+                                               RNA_property_int_set(&but->rnapoin, but->rnaprop, value);
+                                               RNA_property_update(C, &but->rnapoin, but->rnaprop);
+
+                                               ui_apply_undo(but);
+                                               ED_region_tag_redraw(ar);
+                                       }
 
                                        retval = WM_UI_HANDLER_BREAK;
                                }
index 2a6a9600582f201b943b857cdd9109ccccbca604..2e80af1b3ad87e623aae8a45973e8104d4ea66b2 100644 (file)
@@ -2429,6 +2429,11 @@ uiLayout *uiLayoutListBox(uiLayout *layout, uiList *ui_list, PointerRNA *ptr, Pr
        but->rnapoin = *actptr;
        but->rnaprop = actprop;
 
+       /* only for the undo string */
+       if (but->flag & UI_BUT_UNDO) {
+               but->tip = RNA_property_description(actprop);
+       }
+
        return (uiLayout *)box;
 }
 
@@ -3077,12 +3082,14 @@ void uiLayoutOperatorButs(const bContext *C, uiLayout *layout, wmOperator *op,
                        /* no undo for buttons for operator redo panels */
                        uiButClearFlag(but, UI_BUT_UNDO);
                        
+#if 0          /* broken, causes freedback loop, see [#36109] */
                        /* if button is operator's default property, and a text-field, enable focus for it
                         *      - this is used for allowing operators with popups to rename stuff with fewer clicks
                         */
                        if ((but->rnaprop == op->type->prop) && (but->type == TEX)) {
                                uiButSetFocusOnEnter(CTX_wm_window(C), but);
                        }
+#endif
                }
        }
 }
index 9558baf0334a40c908a5b73a9c5b6f65a0ba42e4..9c6a606333d17efa929c94e8254c6bdf21255a89 100644 (file)
@@ -524,7 +524,7 @@ ARegion *ui_tooltip_create(bContext *C, ARegion *butregion, uiBut *but)
 
                if (but->rnapoin.id.data) {
                        ID *id = but->rnapoin.id.data;
-                       if (id->lib && id->lib->name) {
+                       if (id->lib) {
                                BLI_snprintf(data->lines[data->totline], sizeof(data->lines[0]), TIP_("Library: %s"), id->lib->name);
                                data->color_id[data->totline] = UI_TIP_LC_NORMAL;
                                data->totline++;
@@ -2116,7 +2116,7 @@ static void uiBlockPicker(uiBlock *block, float rgba[4], PointerRNA *ptr, Proper
        static char tip[50];
        static char hexcol[128];
        float rgb_gamma[3];
-       float min, max, step, precision;
+       float softmin, softmax, hardmin, hardmax, step, precision;
        float *hsv = ui_block_hsv_get(block);
        int yco;
        
@@ -2142,7 +2142,8 @@ static void uiBlockPicker(uiBlock *block, float rgba[4], PointerRNA *ptr, Proper
        /* sneaky way to check for alpha */
        rgba[3] = FLT_MAX;
 
-       RNA_property_float_ui_range(ptr, prop, &min, &max, &step, &precision);
+       RNA_property_float_ui_range(ptr, prop, &softmin, &softmax, &step, &precision);
+       RNA_property_float_range(ptr, prop, &hardmin, &hardmax);
        RNA_property_float_get_array(ptr, prop, rgba);
 
        switch (U.color_picker_type) {
@@ -2196,7 +2197,8 @@ static void uiBlockPicker(uiBlock *block, float rgba[4], PointerRNA *ptr, Proper
        uiButSetFunc(bt, do_hsv_rna_cb, bt, hsv);
        bt = uiDefButF(block, NUMSLI, 0, IFACE_("S "),   0, yco -= UI_UNIT_Y, butwidth, UI_UNIT_Y, hsv + 1, 0.0, 1.0, 10, 3, TIP_("Saturation"));
        uiButSetFunc(bt, do_hsv_rna_cb, bt, hsv);
-       bt = uiDefButF(block, NUMSLI, 0, IFACE_("V "),   0, yco -= UI_UNIT_Y, butwidth, UI_UNIT_Y, hsv + 2, 0.0, max, 10, 3, TIP_("Value"));
+       bt = uiDefButF(block, NUMSLI, 0, IFACE_("V "),   0, yco -= UI_UNIT_Y, butwidth, UI_UNIT_Y, hsv + 2, 0.0, softmax, 10, 3, TIP_("Value"));
+       bt->hardmax = hardmax;  /* not common but rgb  may be over 1.0 */
        uiButSetFunc(bt, do_hsv_rna_cb, bt, hsv);
        uiBlockEndAlign(block);
 
index e061ff3502569a66e576b13aca5dac7fde607f16..f45bd1c3463b2d48c89b8c5be6b84f4c7ef381b7 100644 (file)
@@ -2646,7 +2646,7 @@ void uiTemplateList(uiLayout *layout, bContext *C, const char *listtype_name, co
                                                sub = uiLayoutRow(overlap, FALSE);
 
                                                but = uiDefButR_prop(subblock, LISTROW, 0, "", 0, 0, UI_UNIT_X * 10, UI_UNIT_Y,
-                                                                    active_dataptr, activeprop, 0, 0, i, 0, 0, "");
+                                                                    active_dataptr, activeprop, 0, 0, i, 0, 0, NULL);
                                                uiButSetFlag(but, UI_BUT_NO_TOOLTIP);
 
                                                sub = uiLayoutRow(overlap, FALSE);
@@ -2660,6 +2660,8 @@ void uiTemplateList(uiLayout *layout, bContext *C, const char *listtype_name, co
                                                if (i == activei) {
                                                        ui_layout_list_set_labels_active(sub);
                                                }
+
+                                               uiBlockClearFlag(subblock, UI_BLOCK_LIST_ITEM);
                                        }
                                        i++;
                                }
@@ -2734,7 +2736,7 @@ void uiTemplateList(uiLayout *layout, bContext *C, const char *listtype_name, co
                                        sub = uiLayoutRow(overlap, FALSE);
 
                                        but = uiDefButR_prop(subblock, LISTROW, 0, "", 0, 0, UI_UNIT_X * 10, UI_UNIT_Y,
-                                                            active_dataptr, activeprop, 0, 0, i, 0, 0, "");
+                                                            active_dataptr, activeprop, 0, 0, i, 0, 0, NULL);
                                        uiButSetFlag(but, UI_BUT_NO_TOOLTIP);
 
                                        sub = uiLayoutRow(overlap, FALSE);
@@ -2747,6 +2749,8 @@ void uiTemplateList(uiLayout *layout, bContext *C, const char *listtype_name, co
                                                ui_layout_list_set_labels_active(sub);
                                        }
 
+                                       uiBlockClearFlag(subblock, UI_BLOCK_LIST_ITEM);
+
                                        i++;
                                }
                                RNA_PROP_END;
index b2c7846ab6c86fc969cccf975357d5f36f2e3f2d..6fd198d9ae6063c1448881f02e2d8172bbe8c3d7 100644 (file)
@@ -95,9 +95,11 @@ void paintface_flush_flags(Object *ob)
                
                /* loop over tessfaces */
                for (i = 0; i < totface; i++) {
-                       /* Copy flags onto the original tessface from its original poly */
-                       mp_orig = me->mpoly + index_array[i];
-                       faces[i].flag = mp_orig->flag;
+                       if (index_array[i] != ORIGINDEX_NONE) {
+                               /* Copy flags onto the original tessface from its original poly */
+                               mp_orig = me->mpoly + index_array[i];
+                               faces[i].flag = mp_orig->flag;
+                       }
                }
        }
 
@@ -107,9 +109,11 @@ void paintface_flush_flags(Object *ob)
 
                /* loop over final derived polys */
                for (i = 0; i < totpoly; i++) {
-                       /* Copy flags onto the final derived poly from the original mesh poly */
-                       mp_orig = me->mpoly + index_array[i];
-                       polys[i].flag = mp_orig->flag;
+                       if (index_array[i] != ORIGINDEX_NONE) {
+                               /* Copy flags onto the final derived poly from the original mesh poly */
+                               mp_orig = me->mpoly + index_array[i];
+                               polys[i].flag = mp_orig->flag;
+                       }
                }
        }
 
@@ -120,9 +124,11 @@ void paintface_flush_flags(Object *ob)
 
                /* loop over tessfaces */
                for (i = 0; i < totface; i++) {
-                       /* Copy flags onto the final tessface from its final poly */
-                       mp_orig = polys + index_array[i];
-                       faces[i].flag = mp_orig->flag;
+                       if (index_array[i] != ORIGINDEX_NONE) {
+                               /* Copy flags onto the final tessface from its final poly */
+                               mp_orig = polys + index_array[i];
+                               faces[i].flag = mp_orig->flag;
+                       }
                }
        }
 }
index 2829aed4999845816bb05f8b8ff14f36ed23d6a8..f7e983fb745649b172ce2477045a90b5f0b2f6b1 100644 (file)
@@ -42,6 +42,7 @@
 #include "BKE_modifier.h"
 #include "BKE_report.h"
 #include "BKE_editmesh.h"
+#include "BKE_DerivedMesh.h"
 
 #include "BIF_gl.h"
 
@@ -61,6 +62,7 @@
 #include "mesh_intern.h"  /* own include */
 
 #define SUBD_SMOOTH_MAX 4.0f
+#define SUBD_CUTS_MAX 500
 
 /* ringsel operator */
 
@@ -155,9 +157,30 @@ static void edgering_find_order(BMEdge *lasteed, BMEdge *eed,
        }
 }
 
+static void edgering_vcos_get(DerivedMesh *dm, BMVert *v[2][2], float r_cos[2][2][3])
+{
+       if (dm) {
+               int j, k;
+               for (j = 0; j < 2; j++) {
+                       for (k = 0; k < 2; k++) {
+                               dm->getVertCo(dm, BM_elem_index_get(v[j][k]), r_cos[j][k]);
+                       }
+               }
+       }
+       else {
+               int j, k;
+               for (j = 0; j < 2; j++) {
+                       for (k = 0; k < 2; k++) {
+                               copy_v3_v3(r_cos[j][k], v[j][k]->co);
+                       }
+               }
+       }
+}
+
 static void edgering_sel(RingSelOpData *lcd, int previewlines, bool select)
 {
        BMEditMesh *em = lcd->em;
+       DerivedMesh *dm = EDBM_mesh_deform_dm_get(em);
        BMEdge *eed_start = lcd->eed;
        BMEdge *eed, *eed_last;
        BMVert *v[2][2], *v_last;
@@ -195,6 +218,10 @@ static void edgering_sel(RingSelOpData *lcd, int previewlines, bool select)
                return;
        }
 
+       if (dm) {
+               EDBM_index_arrays_ensure(lcd->em, BM_VERT);
+       }
+
        BMW_init(&walker, em->bm, BMW_EDGERING,
                 BMW_MASK_NOP, BMW_MASK_NOP, BMW_MASK_NOP,
                 BMW_FLAG_TEST_HIDDEN,
@@ -222,8 +249,12 @@ static void edgering_sel(RingSelOpData *lcd, int previewlines, bool select)
 
                        for (i = 1; i <= previewlines; i++) {
                                const float fac = (i / ((float)previewlines + 1));
-                               interp_v3_v3v3(edges[tot][0], v[0][0]->co, v[0][1]->co, fac);
-                               interp_v3_v3v3(edges[tot][1], v[1][0]->co, v[1][1]->co, fac);
+                               float v_cos[2][2][3];
+
+                               edgering_vcos_get(dm, v, v_cos);
+
+                               interp_v3_v3v3(edges[tot][0], v_cos[0][0], v_cos[0][1], fac);
+                               interp_v3_v3v3(edges[tot][1], v_cos[1][0], v_cos[1][1], fac);
                                tot++;
                        }
                }
@@ -244,13 +275,16 @@ static void edgering_sel(RingSelOpData *lcd, int previewlines, bool select)
 
                for (i = 1; i <= previewlines; i++) {
                        const float fac = (i / ((float)previewlines + 1));
+                       float v_cos[2][2][3];
 
                        if (!v[0][0] || !v[0][1] || !v[1][0] || !v[1][1]) {
                                continue;
                        }
 
-                       interp_v3_v3v3(edges[tot][0], v[0][0]->co, v[0][1]->co, fac);
-                       interp_v3_v3v3(edges[tot][1], v[1][0]->co, v[1][1]->co, fac);
+                       edgering_vcos_get(dm, v, v_cos);
+
+                       interp_v3_v3v3(edges[tot][0], v_cos[0][0], v_cos[0][1], fac);
+                       interp_v3_v3v3(edges[tot][1], v_cos[1][0], v_cos[1][1], fac);
                        tot++;
                }
        }
@@ -545,6 +579,7 @@ static int loopcut_modal(bContext *C, wmOperator *op, const wmEvent *event)
                                break;
                        if (event->alt == 0) {
                                cuts++;
+                               cuts = CLAMPIS(cuts, 0, SUBD_CUTS_MAX);
                                RNA_int_set(op->ptr, "number_cuts", cuts);
                                ringsel_find_edge(lcd, cuts);
                                show_cuts = true;
@@ -598,7 +633,7 @@ static int loopcut_modal(bContext *C, wmOperator *op, const wmEvent *event)
                        
                        /* allow zero so you can backspace and type in a value
                         * otherwise 1 as minimum would make more sense */
-                       cuts = CLAMPIS(value, 0, 130);
+                       cuts = CLAMPIS(value, 0, SUBD_CUTS_MAX);
                        
                        RNA_int_set(op->ptr, "number_cuts", cuts);
                        ringsel_find_edge(lcd, cuts);
index 2c721a0a9dc01a62f00827e2f243b53a9dd63c11..77a79e57dbc5e026946f7bc7c5e28e66b3dfbf1e 100644 (file)
@@ -4007,8 +4007,9 @@ static int edbm_bridge_edge_loops_exec(bContext *C, wmOperator *op)
        }
 
        if (!EDBM_op_finish(em, &bmop, op, true)) {
-               return OPERATOR_CANCELLED;
-
+               /* grr, need to return finished so the user can select different options */
+               //return OPERATOR_CANCELLED;
+               return OPERATOR_FINISHED;
        }
        else {
                EDBM_update_generic(em, true, true);
index effbe3a619d7a741737d323a7873c90c118eef29..63b44fb30d4870bda3abb16be188dac8162f43f0 100644 (file)
@@ -171,6 +171,13 @@ void EDBM_stats_update(BMEditMesh *em)
        }
 }
 
+DerivedMesh *EDBM_mesh_deform_dm_get(BMEditMesh *em)
+{
+       return ((em->derivedFinal != NULL) &&
+               (em->derivedFinal->type == DM_TYPE_EDITBMESH) &&
+               (em->derivedFinal->deformedOnly != false)) ? em->derivedFinal : NULL;
+}
+
 bool EDBM_op_init(BMEditMesh *em, BMOperator *bmop, wmOperator *op, const char *fmt, ...)
 {
        BMesh *bm = em->bm;
index 51b5e30bc3fb63baaf377d97f3d28fb2177c3fc8..950482df55577cf2e83b0cfc5dfadf4508554d09 100644 (file)
@@ -88,9 +88,10 @@ int join_mesh_exec(bContext *C, wmOperator *op)
        Key *key, *nkey = NULL;
        KeyBlock *kb, *okb, *kbn;
        float imat[4][4], cmat[4][4], *fp1, *fp2;
-       int a, b, totcol, totmat = 0, totedge = 0, totvert = 0, ok = 0;
+       int a, b, totcol, totmat = 0, totedge = 0, totvert = 0;
        int totloop = 0, totpoly = 0, vertofs, *matmap = NULL;
        int i, j, index, haskey = 0, edgeofs, loopofs, polyofs;
+       bool ok = false;
        bDeformGroup *dg, *odg;
        MDeformVert *dvert;
        CustomData vdata, edata, fdata, ldata, pdata;
@@ -119,7 +120,7 @@ int join_mesh_exec(bContext *C, wmOperator *op)
                        totmat += base->object->totcol;
                        
                        if (base->object == ob)
-                               ok = 1;
+                               ok = true;
                        
                        /* check for shapekeys */
                        if (me->key)
@@ -129,7 +130,7 @@ int join_mesh_exec(bContext *C, wmOperator *op)
        CTX_DATA_END;
        
        /* that way the active object is always selected */ 
-       if (ok == 0) {
+       if (ok == false) {
                BKE_report(op->reports, RPT_WARNING, "Active object is not a selected mesh");
                return OPERATOR_CANCELLED;
        }
index 1e0a8cefb8745a2c95085d24f452b4d2909f73f8..f563451f64188cadba524e7f54c23bc0d61c60b2 100644 (file)
@@ -265,6 +265,7 @@ int ED_object_add_generic_get_opts(bContext *C, wmOperator *op, float loc[3], fl
                                    bool *enter_editmode, unsigned int *layer, bool *is_view_aligned)
 {
        View3D *v3d = CTX_wm_view3d(C);
+       unsigned int _layer;
 
        /* Switch to Edit mode? */
        if (RNA_struct_find_property(op->ptr, "enter_editmode")) { /* optional */
@@ -283,7 +284,6 @@ int ED_object_add_generic_get_opts(bContext *C, wmOperator *op, float loc[3], fl
        /* Get layers! */
        {
                int a, layer_values[20];
-               unsigned int _layer;
                if (!layer)
                        layer = &_layer;
 
@@ -342,7 +342,7 @@ int ED_object_add_generic_get_opts(bContext *C, wmOperator *op, float loc[3], fl
                else if (RNA_struct_property_is_set(op->ptr, "view_align"))
                        *is_view_aligned = RNA_boolean_get(op->ptr, "view_align");
                else {
-                       *is_view_aligned = U.flag & USER_ADD_VIEWALIGNED;
+                       *is_view_aligned = (U.flag & USER_ADD_VIEWALIGNED) != 0;
                        RNA_boolean_set(op->ptr, "view_align", *is_view_aligned);
                }
 
index 581c3d257307d69293610530f40167d389a8e56c..5c5352f1671197d0784f12fa6738a7765e9011dd 100644 (file)
@@ -3000,7 +3000,7 @@ static int vertex_group_vert_select_unlocked_poll(bContext *C)
                return 0;
        }
 
-       if (ob->actdef != -1) {
+       if (ob->actdef != 0) {
                bDeformGroup *dg = BLI_findlink(&ob->defbase, ob->actdef - 1);
                if (dg) {
                        return !(dg->flag & DG_LOCK_WEIGHT);
index f84521fabbf92e2626875f0785ca9821dfc50f34..d6bb394ff79244295ed827c54a45599240d56174 100644 (file)
@@ -1722,13 +1722,17 @@ int PE_lasso_select(bContext *C, const int mcords[][2], const short moves, bool
                                    BLI_lasso_is_point_inside(mcords, moves, screen_co[0], screen_co[1], IS_CLIPPED) &&
                                    key_test_depth(&data, co, screen_co))
                                {
-                                       if (select && !(key->flag & PEK_SELECT)) {
-                                               key->flag |= PEK_SELECT;
-                                               point->flag |= PEP_EDIT_RECALC;
+                                       if (select) {
+                                               if (!(key->flag & PEK_SELECT)) {
+                                                       key->flag |= PEK_SELECT;
+                                                       point->flag |= PEP_EDIT_RECALC;
+                                               }
                                        }
-                                       else if (key->flag & PEK_SELECT) {
-                                               key->flag &= ~PEK_SELECT;
-                                               point->flag |= PEP_EDIT_RECALC;
+                                       else {
+                                               if (key->flag & PEK_SELECT) {
+                                                       key->flag &= ~PEK_SELECT;
+                                                       point->flag |= PEP_EDIT_RECALC;
+                                               }
                                        }
                                }
                        }
@@ -1742,13 +1746,17 @@ int PE_lasso_select(bContext *C, const int mcords[][2], const short moves, bool
                            BLI_lasso_is_point_inside(mcords, moves, screen_co[0], screen_co[1], IS_CLIPPED) &&
                            key_test_depth(&data, co, screen_co))
                        {
-                               if (select && !(key->flag & PEK_SELECT)) {
-                                       key->flag |= PEK_SELECT;
-                                       point->flag |= PEP_EDIT_RECALC;
+                               if (select) {
+                                       if (!(key->flag & PEK_SELECT)) {
+                                               key->flag |= PEK_SELECT;
+                                               point->flag |= PEP_EDIT_RECALC;
+                                       }
                                }
-                               else if (key->flag & PEK_SELECT) {
-                                       key->flag &= ~PEK_SELECT;
-                                       point->flag |= PEP_EDIT_RECALC;
+                               else {
+                                       if (key->flag & PEK_SELECT) {
+                                               key->flag &= ~PEK_SELECT;
+                                               point->flag |= PEP_EDIT_RECALC;
+                                       }
                                }
                        }
                }
@@ -2963,14 +2971,20 @@ static void brush_puff(PEData *data, int point_index)
        KEY_K;
        float mat[4][4], imat[4][4];
 
-       float lastco[3], rootco[3] = {0.0f, 0.0f, 0.0f}, co[3], nor[3], kco[3], dco[3], ofs[3] = {0.0f, 0.0f, 0.0f}, fac=0.0f, length=0.0f;
-       int puff_volume = 0;
-       int change= 0;
+       float onor_prev[3];  /* previous normal (particle-space) */
+       float ofs_prev[3];  /* accumulate offset for puff_volume (particle-space) */
+       float co_root[3], no_root[3];  /* root location and normal (global-space) */
+       float co_prev[3], co[3];  /* track key coords as we loop (global-space) */
+       float fac = 0.0f, length_accum = 0.0f;
+       bool puff_volume = false;
+       bool change = false;
+
+       zero_v3(ofs_prev);
 
        {
                ParticleEditSettings *pset= PE_settings(data->scene);
                ParticleBrushData *brush= &pset->brush[pset->brushtype];
-               puff_volume = brush->flag & PE_BRUSH_DATA_PUFF_VOLUME;
+               puff_volume = (brush->flag & PE_BRUSH_DATA_PUFF_VOLUME) != 0;
        }
 
        if (psys && !(psys->flag & PSYS_GLOBAL_HAIR)) {
@@ -2983,6 +2997,8 @@ static void brush_puff(PEData *data, int point_index)
        }
 
        LOOP_KEYS {
+               float kco[3];
+
                if (k==0) {
                        /* find root coordinate and normal on emitter */
                        copy_v3_v3(co, key->co);
@@ -2992,12 +3008,16 @@ static void brush_puff(PEData *data, int point_index)
                        point_index= BLI_kdtree_find_nearest(edit->emitter_field, kco, NULL, NULL);
                        if (point_index == -1) return;
 
-                       copy_v3_v3(rootco, co);
-                       copy_v3_v3(nor, &edit->emitter_cosnos[point_index*6+3]);
-                       mul_mat3_m4_v3(data->ob->obmat, nor); /* normal into worldspace */
+                       copy_v3_v3(co_root, co);
+                       copy_v3_v3(no_root, &edit->emitter_cosnos[point_index * 6 + 3]);
+                       mul_mat3_m4_v3(data->ob->obmat, no_root);  /* normal into global-space */
+                       normalize_v3(no_root);
 
-                       normalize_v3(nor);
-                       length= 0.0f;
+                       if (puff_volume) {
+                               copy_v3_v3(onor_prev, no_root);
+                               mul_mat3_m4_v3(imat, onor_prev); /* global-space into particle space */
+                               normalize_v3(onor_prev);
+                       }
 
                        fac= (float)pow((double)(1.0f - data->dist / data->rad), (double)data->pufffac);
                        fac *= 0.025f;
@@ -3007,16 +3027,23 @@ static void brush_puff(PEData *data, int point_index)
                else {
                        /* compute position as if hair was standing up straight.
                         * */
-                       copy_v3_v3(lastco, co);
+                       float length;
+                       copy_v3_v3(co_prev, co);
                        copy_v3_v3(co, key->co);
                        mul_m4_v3(mat, co);
-                       length += len_v3v3(lastco, co);
+                       length = len_v3v3(co_prev, co);
+                       length_accum += length;
+
                        if ((data->select==0 || (key->flag & PEK_SELECT)) && !(key->flag & PEK_HIDE)) {
-                               madd_v3_v3v3fl(kco, rootco, nor, length);
+                               float dco[3];  /* delta temp var */
+
+                               madd_v3_v3v3fl(kco, co_root, no_root, length_accum);
 
                                /* blend between the current and straight position */
                                sub_v3_v3v3(dco, kco, co);
                                madd_v3_v3fl(co, dco, fac);
+                               /* keep the same distance from the root or we get glitches [#35406] */
+                               dist_ensure_v3_v3fl(co, co_root, length_accum);
 
                                /* re-use dco to compare before and after translation and add to the offset  */
                                copy_v3_v3(dco, key->co);
@@ -3026,11 +3053,9 @@ static void brush_puff(PEData *data, int point_index)
                                if (puff_volume) {
                                        /* accumulate the total distance moved to apply to unselected
                                         * keys that come after */
-                                       ofs[0] += key->co[0] - dco[0];
-                                       ofs[1] += key->co[1] - dco[1];
-                                       ofs[2] += key->co[2] - dco[2];
+                                       sub_v3_v3v3(ofs_prev, key->co, dco);
                                }
-                               change = 1;
+                               change = true;
                        }
                        else {
 
@@ -3040,7 +3065,7 @@ static void brush_puff(PEData *data, int point_index)
                                        add_v3_v3(key->co, ofs);
 #else
                                        /* translate (not rotate) the rest of the hair if its not selected  */
-                                       if (ofs[0] || ofs[1] || ofs[2]) {
+                                       {
 #if 0                                  /* kindof works but looks worse then whats below */
 
                                                /* Move the unselected point on a vector based on the
@@ -3070,11 +3095,18 @@ static void brush_puff(PEData *data, int point_index)
                                                        mul_mat3_m4_v3(data->ob->obmat, onor); /* normal into worldspace */
                                                        mul_mat3_m4_v3(imat, onor); /* worldspace into particle space */
                                                        normalize_v3(onor);
+                                               }
+                                               else {
+                                                       copy_v3_v3(onor, onor_prev);
+                                               }
 
+                                               if (!is_zero_v3(ofs_prev)) {
+                                                       mul_v3_fl(onor, len_v3(ofs_prev));
 
-                                                       mul_v3_fl(onor, len_v3(ofs));
                                                        add_v3_v3(key->co, onor);
                                                }
+
+                                               copy_v3_v3(onor_prev, onor);
 #endif
                                        }
 #endif
index 7a2ece66ba4e6d601a96f332884f2c676dc62dfa..b9653da47e6fd034584d2d29c21c0f261e051b23 100644 (file)
@@ -266,6 +266,7 @@ typedef struct RenderJob {
        SceneRenderLayer *srl;
        struct Object *camera_override;
        int lay;
+       bool v3d_override;
        short anim, write_still;
        Image *image;
        ImageUser iuser;
@@ -283,7 +284,7 @@ static void render_freejob(void *rjv)
 }
 
 /* str is IMA_MAX_RENDER_TEXT in size */
-static void make_renderinfo_string(RenderStats *rs, Scene *scene, char *str)
+static void make_renderinfo_string(RenderStats *rs, Scene *scene, bool v3d_override, char *str)
 {
        char info_time_str[32]; // used to be extern to header_info.c
        uintptr_t mem_in_use, mmap_in_use, peak_memory;
@@ -300,7 +301,9 @@ static void make_renderinfo_string(RenderStats *rs, Scene *scene, char *str)
 
        /* local view */
        if (rs->localview)
-               spos += sprintf(spos, "%s | ", IFACE_("Local View"));
+               spos += sprintf(spos, "%s | ", IFACE_("3D Local View"));
+       else if (v3d_override)
+               spos += sprintf(spos, "%s | ", IFACE_("3D View"));
 
        /* frame number */
        spos += sprintf(spos, IFACE_("Frame:%d "), (scene->r.cfra));
@@ -376,7 +379,7 @@ static void image_renderinfo_cb(void *rjv, RenderStats *rs)
                if (rr->text == NULL)
                        rr->text = MEM_callocN(IMA_MAX_RENDER_TEXT, "rendertext");
 
-               make_renderinfo_string(rs, rj->scene, rr->text);
+               make_renderinfo_string(rs, rj->scene, rj->v3d_override, rr->text);
        }
 
        RE_ReleaseResult(rj->re);
@@ -643,7 +646,12 @@ static int screen_render_invoke(bContext *C, wmOperator *op, const wmEvent *even
        rj->reports = op->reports;
 
        if (v3d) {
-               rj->lay = v3d->lay;
+               if (rj->lay != v3d->lay) {
+                       rj->lay = v3d->lay;
+                       rj->v3d_override = true;
+               }
+               else if (camera_override && camera_override != scene->camera)
+                       rj->v3d_override = true;
 
                if (v3d->localvd)
                        rj->lay |= v3d->localvd->lay;
@@ -826,7 +834,7 @@ static void render_view3d_renderinfo_cb(void *rjp, RenderStats *rs)
        if (rp->rv3d->render_engine == NULL)
                *rp->stop = 1;
        else if (rp->engine->text) {
-               make_renderinfo_string(rs, rp->scene, rp->engine->text);
+               make_renderinfo_string(rs, rp->scene, false, rp->engine->text);
        
                /* make jobs timer to send notifier */
                *(rp->do_update) = TRUE;
@@ -873,7 +881,7 @@ static void render_view3d_startjob(void *customdata, short *stop, short *do_upda
        
        rstats = RE_GetStats(re);
 
-       if ((update_flag & (PR_UPDATE_RENDERSIZE|PR_UPDATE_DATABASE)) || rstats->convertdone == 0) {
+       if ((update_flag & (PR_UPDATE_RENDERSIZE | PR_UPDATE_DATABASE)) || rstats->convertdone == 0) {
                /* no osa, blur, seq, layers, etc for preview render */
                rdata = rp->scene->r;
                rdata.mode &= ~(R_OSA | R_MBLUR | R_BORDER | R_PANORAMA);
@@ -1052,9 +1060,8 @@ static void render_view3d_do(RenderEngine *engine, const bContext *C)
        rp->bmain = CTX_data_main(C);
        copy_m4_m4(rp->viewmat, rp->rv3d->viewmat);
        
-       /* dont alloc in threads */
-       if (engine->text == NULL)
-               engine->text = MEM_callocN(IMA_MAX_RENDER_TEXT, "rendertext");
+       /* clear info text */
+       engine->text[0] = '\0';
        
        /* setup job */
        WM_jobs_customdata_set(wm_job, rp, render_view3d_free);
@@ -1141,7 +1148,7 @@ void render_view3d_draw(RenderEngine *engine, const bContext *C)
        RE_ReleaseResultImage(re);
 }
 
-void ED_viewport_render_kill_jobs(const bContext *C)
+void ED_viewport_render_kill_jobs(const bContext *C, bool free_database)
 {
        wmWindowManager *wm = CTX_wm_manager(C);
        Main *bmain = CTX_data_main(C);
@@ -1172,17 +1179,23 @@ void ED_viewport_render_kill_jobs(const bContext *C)
                                if (rv3d->render_engine) {
                                        /* free render database now before we change data, because
                                         * RE_Database_Free will also loop over blender data */
-                                       char name[32];
-                                       Render *re;
-
-                                       sprintf(name, "View3dPreview %p", (void *)ar);
-                                       re = RE_GetRender(name);
-
-                                       if (re)
-                                               RE_Database_Free(re);
-
-                                       /* tag render engine to update entire database */
-                                       rv3d->render_engine->update_flag |= RE_ENGINE_UPDATE_DATABASE;
+                                       if (free_database) {
+                                               char name[32];
+                                               Render *re;
+
+                                               sprintf(name, "View3dPreview %p", (void *)ar);
+                                               re = RE_GetRender(name);
+
+                                               if (re)
+                                                       RE_Database_Free(re);
+
+                                               /* tag render engine to update entire database */
+                                               rv3d->render_engine->update_flag |= RE_ENGINE_UPDATE_DATABASE;
+                                       }
+                                       else {
+                                               /* quick shader update */
+                                               rv3d->render_engine->update_flag |= RE_ENGINE_UPDATE_MA;
+                                       }
                                }
                        }
                }
index 76fa79029fd027074ac05ff4761857634c72733e..8da66c114d5e4b7b99505f82ef565dd7aaa91dbe 100644 (file)
@@ -1180,5 +1180,7 @@ void ED_preview_kill_jobs(const struct bContext *C)
        wmWindowManager *wm = CTX_wm_manager(C);
        if (wm)
                WM_jobs_kill(wm, NULL, common_preview_startjob);
+       
+       ED_viewport_render_kill_jobs(C, false);
 }
 
index 19953723fef9560c09385d60a99f82a0f220d5f8..017232d18569421674f76839780fbd95937a3115 100644 (file)
@@ -245,7 +245,8 @@ typedef struct ProjPaintState {
        float normal_angle_inner;
        float normal_angle_range;       /* difference between normal_angle and normal_angle_inner, for easy access */
 
-       short is_ortho;
+       bool do_face_sel;               /* quick access to (me->editflag & ME_EDIT_PAINT_FACE_SEL) */
+       bool is_ortho;
        bool do_masking;              /* use masking during painting. Some operations such as airbrush may disable */
        bool is_texbrush;              /* only to avoid running  */
        bool is_maskbrush;            /* mask brush is applied before masking */
@@ -2809,11 +2810,13 @@ static void project_paint_begin(ProjPaintState *ps)
        Image *tpage_last = NULL, *tpage;
 
        /* Face vars */
+       MPoly *mpoly_orig;
        MFace *mf;
        MTFace *tf;
 
        int a, i; /* generic looping vars */
        int image_index = -1, face_index;
+       int *mpoly_origindex;
        MVert *mv;
 
        MemArena *arena; /* at the moment this is just ps->arena_mt[0], but use this to show were not multithreading */
@@ -2827,6 +2830,8 @@ static void project_paint_begin(ProjPaintState *ps)
        if (ps->source == PROJ_SRC_VIEW)
                ED_view3d_clipping_local(ps->rv3d, ps->ob->obmat);  /* faster clipping lookups */
 
+       ps->do_face_sel = ((((Mesh *)ps->ob->data)->editflag & ME_EDIT_PAINT_FACE_SEL) != 0);
+
        /* paint onto the derived mesh */
 
        /* Workaround for subsurf selection, try the display mesh first */
@@ -2835,12 +2840,17 @@ static void project_paint_begin(ProjPaintState *ps)
                ps->dm = mesh_create_derived_render(ps->scene, ps->ob, ps->scene->customdata_mask | CD_MASK_MTFACE);
                ps->dm_release = TRUE;
        }
-       else if (ps->ob->derivedFinal && CustomData_has_layer(&ps->ob->derivedFinal->faceData, CD_MTFACE)) {
+       else if (ps->ob->derivedFinal &&
+                CustomData_has_layer(&ps->ob->derivedFinal->faceData, CD_MTFACE) &&
+                (ps->do_face_sel == false || CustomData_has_layer(&ps->ob->derivedFinal->polyData, CD_ORIGINDEX)))
+       {
                ps->dm = ps->ob->derivedFinal;
                ps->dm_release = FALSE;
        }
        else {
-               ps->dm = mesh_get_derived_final(ps->scene, ps->ob, ps->scene->customdata_mask | CD_MASK_MTFACE);
+               ps->dm = mesh_get_derived_final(
+                            ps->scene, ps->ob,
+                            ps->scene->customdata_mask | CD_MASK_MTFACE | (ps->do_face_sel ? CD_ORIGINDEX : 0));
                ps->dm_release = TRUE;
        }
 
@@ -2860,6 +2870,15 @@ static void project_paint_begin(ProjPaintState *ps)
        ps->dm_totvert = ps->dm->getNumVerts(ps->dm);
        ps->dm_totface = ps->dm->getNumTessFaces(ps->dm);
 
+       if (ps->do_face_sel) {
+               mpoly_orig = ((Mesh *)ps->ob->data)->mpoly;
+               mpoly_origindex = ps->dm->getPolyDataArray(ps->dm, CD_ORIGINDEX);
+       }
+       else {
+               mpoly_orig = NULL;
+               mpoly_origindex = NULL;
+       }
+
        /* use clone mtface? */
 
 
@@ -3129,8 +3148,8 @@ static void project_paint_begin(ProjPaintState *ps)
                }
        }
 
-
        for (face_index = 0, tf = ps->dm_mtface, mf = ps->dm_mface; face_index < ps->dm_totface; mf++, tf++, face_index++) {
+               bool is_face_sel;
 
 #ifndef PROJ_DEBUG_NOSEAMBLEED
                /* add face user if we have bleed enabled, set the UV seam flags later */
@@ -3145,10 +3164,21 @@ static void project_paint_begin(ProjPaintState *ps)
                }
 #endif
 
-               tpage = project_paint_face_image(ps, ps->dm_mtface, face_index);
-
-               if (tpage && ((((Mesh *)ps->ob->data)->editflag & ME_EDIT_PAINT_FACE_SEL) == 0 || mf->flag & ME_FACE_SEL)) {
+               if (ps->do_face_sel) {
+                       int orig_index;
+                       if (mpoly_origindex && ((orig_index = mpoly_origindex[face_index])) != ORIGINDEX_NONE) {
+                               MPoly *mp = mpoly_orig + orig_index;
+                               is_face_sel = ((mp->flag & ME_FACE_SEL) != 0);
+                       }
+                       else {
+                               is_face_sel = ((mf->flag & ME_FACE_SEL) != 0);
+                       }
+               }
+               else {
+                       is_face_sel = true;
+               }
 
+               if (is_face_sel && (tpage = project_paint_face_image(ps, ps->dm_mtface, face_index))) {
                        float *v1coSS, *v2coSS, *v3coSS, *v4coSS = NULL;
 
                        v1coSS = ps->screenCoords[mf->v1];
index 6de6734f975e36cd7f3566f9f4948bddaaf54251..cef624463c25f84bed17408a2e3e3c9f7ee46846 100644 (file)
@@ -695,6 +695,7 @@ static int stencil_control_modal(bContext *C, wmOperator *op, const wmEvent *eve
                                WM_event_add_notifier(C, NC_WINDOW, NULL);
                                return OPERATOR_CANCELLED;
                        }
+                       break;
                case XKEY:
                        if (event->val == KM_PRESS) {
 
index b01f653837cffd839fd47443f08313332fd73785..72d7bcd43ce71e8ae667703e3225b2ff38e76481 100644 (file)
@@ -292,6 +292,7 @@ static void buttons_area_listener(bScreen *UNUSED(sc), ScrArea *sa, wmNotifier *
                                        buttons_area_redraw(sa, BCONTEXT_OBJECT);
                                        buttons_area_redraw(sa, BCONTEXT_DATA);
                                        buttons_area_redraw(sa, BCONTEXT_PHYSICS);
+                                       break;
                                case ND_SHADING:
                                case ND_SHADING_DRAW:
                                case ND_SHADING_LINKS:
index 36cf9fc44c6969473446706b54956a101ecdc170..2cbb2373be8cbf94eb3cd8a3d79bb25efa3101d6 100644 (file)
@@ -1019,7 +1019,7 @@ static void clip_refresh(const bContext *C, ScrArea *sa)
                if (ar_channels && !(ar_channels->flag & RGN_FLAG_HIDDEN)) {
                        ar_channels->flag |= RGN_FLAG_HIDDEN;
                        ar_channels->v2d.flag &= ~V2D_IS_INITIALISED;
-                       WM_event_remove_handlers((bContext *)C, &ar_tools->handlers);
+                       WM_event_remove_handlers((bContext *)C, &ar_channels->handlers);
                        view_changed = TRUE;
                }
                if (ar_channels && ar_channels->alignment != RGN_ALIGN_NONE) {
index f1e707f8802e3b24896bf083ba2f42a986b38483..7d7dccdf0e69970221d76b51d229a3506f3628d8 100644 (file)
@@ -847,7 +847,7 @@ static void filelist_setfiletypes(struct FileList *filelist)
                }
                file->flags = file_extension_type(file->relname);
                
-               if (filelist->filter_glob &&
+               if (filelist->filter_glob[0] &&
                    BLI_testextensie_glob(file->relname, filelist->filter_glob))
                {
                        file->flags = OPERATORFILE;
index 82104d2c83792ee40922d1a117528eb8e51d3177..fc136458b3cde339efbbff8174ae9d7bf99943ff 100644 (file)
@@ -1389,6 +1389,7 @@ static void node_composit_buts_zcombine(uiLayout *layout, bContext *UNUSED(C), P
        
        col = uiLayoutColumn(layout, TRUE);
        uiItemR(col, ptr, "use_alpha", 0, NULL, ICON_NONE);
+       uiItemR(col, ptr, "use_antialias_z", 0, NULL, ICON_NONE);
 }
 
 
index ea745c4769000f30b7f67b474db8d37fb1ba080f..bd0c9848b239d83abdadfc34c6a3a2ca0e7e3bf0 100644 (file)
@@ -429,6 +429,7 @@ void NODE_OT_select(wmOperatorType *ot)
        
        /* api callbacks */
        ot->invoke = node_select_invoke;
+       ot->exec = node_select_exec;
        ot->poll = ED_operator_node_active;
        
        /* flags */
index af4b40551567ad49a91be3de3aadb40392f76eba..0f4a2d8b4dd7ab8be67fdb2315b7393d3f8ef123 100644 (file)
@@ -162,12 +162,7 @@ static void get_seq_color3ubv(Scene *curscene, Sequence *seq, unsigned char col[
                        break;
 
                case SEQ_TYPE_COLOR:
-                       if (colvars->col) {
-                               rgb_float_to_uchar(col, colvars->col);
-                       }
-                       else {
-                               col[0] = col[1] = col[2] = 128;
-                       }
+                       rgb_float_to_uchar(col, colvars->col);
                        break;
 
                case SEQ_TYPE_SOUND_RAM:
index 8258d7178894e0d0cb6ba0bc99bf80983a96873e..495980db4479e0d142c0d04aec9a894698dd3075 100644 (file)
@@ -403,6 +403,7 @@ static void time_listener(bScreen *UNUSED(sc), ScrArea *sa, wmNotifier *wmn)
        /* mainly for updating cache display */
        switch (wmn->category) {
                case NC_OBJECT:
+               {
                        switch (wmn->data) {
                                case ND_BONE_ACTIVE:
                                case ND_POINTCACHE:
@@ -414,7 +415,9 @@ static void time_listener(bScreen *UNUSED(sc), ScrArea *sa, wmNotifier *wmn)
                                        break;
                        }
                        break;
+               }
                case NC_SCENE:
+               {
                        switch (wmn->data) {
                                case ND_OB_ACTIVE:
                                case ND_FRAME:
@@ -435,18 +438,26 @@ static void time_listener(bScreen *UNUSED(sc), ScrArea *sa, wmNotifier *wmn)
                                }
                                break;
                        }
+                       break;
+               }
                case NC_SPACE:
+               {
                        switch (wmn->data) {
                                case ND_SPACE_CHANGED:
                                        ED_area_tag_refresh(sa);
                                        break;
                        }
+                       break;
+               }
                case NC_WM:
+               {
                        switch (wmn->data) {
                                case ND_FILEREAD:
                                        ED_area_tag_refresh(sa);
                                        break;
                        }
+                       break;
+               }
        }
 }
 
@@ -568,11 +579,13 @@ static void time_header_area_listener(bScreen *UNUSED(sc), ScrArea *UNUSED(sa),
        /* context changes */
        switch (wmn->category) {
                case NC_SCREEN:
+               {
                        if (wmn->data == ND_ANIMPLAY)
                                ED_region_tag_redraw(ar);
                        break;
-
+               }
                case NC_SCENE:
+               {
                        switch (wmn->data) {
                                case ND_OB_SELECT:
                                case ND_FRAME:
@@ -582,11 +595,14 @@ static void time_header_area_listener(bScreen *UNUSED(sc), ScrArea *UNUSED(sa),
                                        ED_region_tag_redraw(ar);
                                        break;
                        }
-
+                       break;
+               }
                case NC_SPACE:
+               {
                        if (wmn->data == ND_SPACE_TIME)
                                ED_region_tag_redraw(ar);
                        break;
+               }
        }
 }
 
index d5ecdaf0596f3a7e05e1bbbc0a4e6758d5d605b2..54a3260439e39fb90d9c2c851aec8014b2a44321 100644 (file)
@@ -2699,7 +2699,8 @@ static void draw_em_measure_stats(ARegion *ar, View3D *v3d, Object *ob, BMEditMe
        const bool do_global = (v3d->flag & V3D_GLOBAL_STATS) != 0;
        const bool do_moving = (G.moving & G_TRANSFORM_EDIT) != 0;
        float clip_planes[4][4];
-
+       /* allow for displaying shape keys and deform mods */
+       DerivedMesh *dm = EDBM_mesh_deform_dm_get(em);
        BMIter iter;
        int i;
 
@@ -2725,23 +2726,33 @@ static void draw_em_measure_stats(ARegion *ar, View3D *v3d, Object *ob, BMEditMe
 
                UI_GetThemeColor3ubv(TH_DRAWEXTRA_EDGELEN, col);
 
-               eed = BM_iter_new(&iter, em->bm, BM_EDGES_OF_MESH, NULL);
-               for (; eed; eed = BM_iter_step(&iter)) {
+               if (dm) {
+                       BM_mesh_elem_index_ensure(em->bm, BM_VERT);
+               }
+
+               BM_ITER_MESH (eed, &iter, em->bm, BM_EDGES_OF_MESH) {
                        /* draw selected edges, or edges next to selected verts while draging */
                        if (BM_elem_flag_test(eed, BM_ELEM_SELECT) ||
                            (do_moving && (BM_elem_flag_test(eed->v1, BM_ELEM_SELECT) ||
                                           BM_elem_flag_test(eed->v2, BM_ELEM_SELECT))))
                        {
+                               float v1_clip[3], v2_clip[3];
 
-                               copy_v3_v3(v1, eed->v1->co);
-                               copy_v3_v3(v2, eed->v2->co);
+                               if (dm) {
+                                       dm->getVertCo(dm, BM_elem_index_get(eed->v1), v1);
+                                       dm->getVertCo(dm, BM_elem_index_get(eed->v2), v2);
+                               }
+                               else {
+                                       copy_v3_v3(v1, eed->v1->co);
+                                       copy_v3_v3(v2, eed->v2->co);
+                               }
 
-                               if (clip_segment_v3_plane_n(v1, v2, clip_planes, 4)) {
+                               copy_v3_v3(v1_clip, v1);
+                               copy_v3_v3(v2_clip, v2);
 
-                                       mid_v3_v3v3(vmid, v1, v2);
+                               if (clip_segment_v3_plane_n(v1_clip, v2_clip, clip_planes, 4)) {
 
-                                       copy_v3_v3(v1, eed->v1->co);
-                                       copy_v3_v3(v2, eed->v2->co);
+                                       mid_v3_v3v3(vmid, v1_clip, v2_clip);
 
                                        if (do_global) {
                                                mul_mat3_m4_v3(ob->obmat, v1);
@@ -2768,10 +2779,13 @@ static void draw_em_measure_stats(ARegion *ar, View3D *v3d, Object *ob, BMEditMe
 
                UI_GetThemeColor3ubv(TH_DRAWEXTRA_EDGEANG, col);
 
+               if (dm) {
+                       BM_mesh_elem_index_ensure(em->bm, BM_VERT | BM_FACE);
+               }
+
                // invert_m4_m4(ob->imat, ob->obmat);  // this is already called
 
-               eed = BM_iter_new(&iter, em->bm, BM_EDGES_OF_MESH, NULL);
-               for (; eed; eed = BM_iter_step(&iter)) {
+               BM_ITER_MESH (eed, &iter, em->bm, BM_EDGES_OF_MESH) {
                        BMLoop *l_a, *l_b;
                        if (BM_edge_loop_pair(eed, &l_a, &l_b)) {
                                /* draw selected edges, or edges next to selected verts while draging */
@@ -2786,30 +2800,44 @@ static void draw_em_measure_stats(ARegion *ar, View3D *v3d, Object *ob, BMEditMe
                                                   BM_elem_flag_test(l_b->prev->v, BM_ELEM_SELECT)
                                                   )))
                                {
-                                       copy_v3_v3(v1, eed->v1->co);
-                                       copy_v3_v3(v2, eed->v2->co);
-
-                                       if (clip_segment_v3_plane_n(v1, v2, clip_planes, 4)) {
-                                               float angle;
-
-                                               mid_v3_v3v3(vmid, v1, v2);
+                                       float v1_clip[3], v2_clip[3];
 
+                                       if (dm) {
+                                               dm->getVertCo(dm, BM_elem_index_get(eed->v1), v1);
+                                               dm->getVertCo(dm, BM_elem_index_get(eed->v2), v2);
+                                       }
+                                       else {
                                                copy_v3_v3(v1, eed->v1->co);
                                                copy_v3_v3(v2, eed->v2->co);
+                                       }
 
-                                               if (do_global) {
-                                                       float no_a[3];
-                                                       float no_b[3];
+                                       copy_v3_v3(v1_clip, v1);
+                                       copy_v3_v3(v2_clip, v2);
+
+                                       if (clip_segment_v3_plane_n(v1_clip, v2_clip, clip_planes, 4)) {
+                                               float no_a[3], no_b[3];
+                                               float angle;
+
+                                               mid_v3_v3v3(vmid, v1_clip, v2_clip);
+
+                                               if (dm) {
+                                                       dm->getPolyNo(dm, BM_elem_index_get(l_a->f), no_a);
+                                                       dm->getPolyNo(dm, BM_elem_index_get(l_b->f), no_b);
+                                               }
+                                               else {
                                                        copy_v3_v3(no_a, l_a->f->no);
                                                        copy_v3_v3(no_b, l_b->f->no);
+                                               }
+
+                                               if (do_global) {
                                                        mul_mat3_m4_v3(ob->imat, no_a);
                                                        mul_mat3_m4_v3(ob->imat, no_b);
-                                                       angle = angle_v3v3(no_a, no_b);
-                                               }
-                                               else {
-                                                       angle = angle_normalized_v3v3(l_a->f->no, l_b->f->no);
+                                                       normalize_v3(no_a);
+                                                       normalize_v3(no_b);
                                                }
 
+                                               angle = angle_normalized_v3v3(no_a, no_b);
+
                                                BLI_snprintf(numstr, sizeof(numstr), "%.3f", is_rad ? angle : RAD2DEGF(angle));
 
                                                view3d_cached_text_draw_add(vmid, numstr, 0, txt_flag, col);
@@ -2844,6 +2872,10 @@ static void draw_em_measure_stats(ARegion *ar, View3D *v3d, Object *ob, BMEditMe
 
                UI_GetThemeColor3ubv(TH_DRAWEXTRA_FACEAREA, col);
                
+               if (dm) {
+                       BM_mesh_elem_index_ensure(em->bm, BM_VERT);
+               }
+
                f = NULL;
                area = 0.0;
                zero_v3(vmid);
@@ -2858,9 +2890,18 @@ static void draw_em_measure_stats(ARegion *ar, View3D *v3d, Object *ob, BMEditMe
                        }
 
                        f = l[0]->f;
-                       copy_v3_v3(v1, l[0]->v->co);
-                       copy_v3_v3(v2, l[1]->v->co);
-                       copy_v3_v3(v3, l[2]->v->co);
+
+                       if (dm) {
+                               dm->getVertCo(dm, BM_elem_index_get(l[0]->v), v1);
+                               dm->getVertCo(dm, BM_elem_index_get(l[1]->v), v2);
+                               dm->getVertCo(dm, BM_elem_index_get(l[2]->v), v3);
+                       }
+                       else {
+                               copy_v3_v3(v1, l[0]->v->co);
+                               copy_v3_v3(v2, l[1]->v->co);
+                               copy_v3_v3(v3, l[2]->v->co);
+                       }
+
                        add_v3_v3(vmid, v1);
                        add_v3_v3(vmid, v2);
                        add_v3_v3(vmid, v3);
@@ -2885,6 +2926,9 @@ static void draw_em_measure_stats(ARegion *ar, View3D *v3d, Object *ob, BMEditMe
 
                UI_GetThemeColor3ubv(TH_DRAWEXTRA_FACEANG, col);
 
+               if (dm) {
+                       BM_mesh_elem_index_ensure(em->bm, BM_VERT);
+               }
 
                BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
                        const int is_face_sel = BM_elem_flag_test(efa, BM_ELEM_SELECT);
@@ -2897,35 +2941,50 @@ static void draw_em_measure_stats(ARegion *ar, View3D *v3d, Object *ob, BMEditMe
                                BM_ITER_ELEM (loop, &liter, efa, BM_LOOPS_OF_FACE) {
                                        if (is_face_sel || (do_moving && BM_elem_flag_test(loop->v, BM_ELEM_SELECT))) {
                                                float angle;
+                                               float v2_local[3];
 
                                                /* lazy init center calc */
                                                if (is_first) {
-                                                       BM_face_calc_center_bounds(efa, vmid);
-                                                       /* Avoid triple matrix multiply every vertex for 'global' */
-                                                       if (do_global) {
-                                                               copy_v3_v3(v1, loop->prev->v->co);
-                                                               copy_v3_v3(v2, loop->v->co);
-                                                               mul_mat3_m4_v3(ob->obmat, v1);
-                                                               mul_mat3_m4_v3(ob->obmat, v2);
+                                                       if (dm) {
+                                                               BMLoop *l_iter, *l_first;
+                                                               float tvec[3];
+                                                               zero_v3(vmid);
+                                                               l_iter = l_first = BM_FACE_FIRST_LOOP(efa);
+                                                               do {
+                                                                       dm->getVertCo(dm, BM_elem_index_get(l_iter->v), tvec);
+                                                                       add_v3_v3(vmid, tvec);
+                                                               } while ((l_iter = l_iter->next) != l_first);
+                                                               mul_v3_fl(vmid, 1.0f / (float)efa->len);
+                                                       }
+                                                       else {
+                                                               BM_face_calc_center_bounds(efa, vmid);
                                                        }
                                                        is_first = false;
                                                }
 
-                                               if (do_global) {
+                                               if (dm) {
+                                                       dm->getVertCo(dm, BM_elem_index_get(loop->prev->v), v1);
+                                                       dm->getVertCo(dm, BM_elem_index_get(loop->v),       v2);
+                                                       dm->getVertCo(dm, BM_elem_index_get(loop->next->v), v3);
+                                               }
+                                               else {
+                                                       copy_v3_v3(v1, loop->prev->v->co);
+                                                       copy_v3_v3(v2, loop->v->co);
                                                        copy_v3_v3(v3, loop->next->v->co);
+                                               }
 
-                                                       mul_mat3_m4_v3(ob->obmat, v3);
+                                               copy_v3_v3(v2_local, v2);
 
-                                                       angle = angle_v3v3v3(v1, v2, v3);
-                                                       copy_v3_v3(v1, v2);
-                                                       copy_v3_v3(v2, v3);
-                                               }
-                                               else {
-                                                       angle = angle_v3v3v3(loop->prev->v->co, loop->v->co, loop->next->v->co);
+                                               if (do_global) {
+                                                       mul_mat3_m4_v3(ob->obmat, v1);
+                                                       mul_mat3_m4_v3(ob->obmat, v2);
+                                                       mul_mat3_m4_v3(ob->obmat, v3);
                                                }
 
+                                               angle = angle_v3v3v3(v1, v2, v3);
+
                                                BLI_snprintf(numstr, sizeof(numstr), "%.3f", is_rad ? angle : RAD2DEGF(angle));
-                                               interp_v3_v3v3(fvec, vmid, loop->v->co, 0.8f);
+                                               interp_v3_v3v3(fvec, vmid, v2_local, 0.8f);
                                                view3d_cached_text_draw_add(fvec, numstr, 0, txt_flag, col);
                                        }
                                }
index 576badf601ef8b046689070029d296eaab665f01..b2f2d5849a4d078c5e75be8c87aaeec29d9df55a 100644 (file)
@@ -967,6 +967,7 @@ static int view3d_ruler_modal(bContext *C, wmOperator *op, const wmEvent *event)
                                        WM_clipboard_text_set((void *) numstr, false);
                                }
                        }
+                       break;
                }
                case RIGHTCTRLKEY:
                case LEFTCTRLKEY:
index 1678487d8bfffc92d06b72340ed1c8ab9fdfc044..e9aca8d4640b1de40e93f0c65f8cfa7e403cf936 100644 (file)
@@ -74,8 +74,6 @@
 
 #include "view3d_intern.h"
 
-extern float originmat[3][3];   /* XXX object.c */
-
 /* ************************************************** */
 /* ********************* old transform stuff ******** */
 /* *********** will get replaced with new transform * */
@@ -628,7 +626,8 @@ static int snap_sel_to_grid(bContext *C, wmOperator *UNUSED(op))
                                vec[2] = -ob->obmat[3][2] + gridf * floorf(0.5f + ob->obmat[3][2] / gridf);
                                
                                if (ob->parent) {
-                                       BKE_object_where_is_calc(scene, ob);
+                                       float originmat[3][3];
+                                       BKE_object_where_is_calc_ex(scene, NULL, ob, originmat);
                                        
                                        invert_m3_m3(imat, originmat);
                                        mul_m3_v3(imat, vec);
@@ -751,7 +750,8 @@ static int snap_sel_to_curs(bContext *C, wmOperator *UNUSED(op))
                                vec[2] = -ob->obmat[3][2] + curs[2];
                                
                                if (ob->parent) {
-                                       BKE_object_where_is_calc(scene, ob);
+                                       float originmat[3][3];
+                                       BKE_object_where_is_calc_ex(scene, NULL, ob, originmat);
                                        
                                        invert_m3_m3(imat, originmat);
                                        mul_m3_v3(imat, vec);
index bf81e0ac766cd870f89f379b56c14c83e0f611ae..8818ad1d421eb906a1877c0468f206a73baf545f 100644 (file)
@@ -59,7 +59,6 @@
 #include "BLI_string.h"
 #include "BLI_ghash.h"
 #include "BLI_linklist.h"
-#include "BLI_smallhash.h"
 
 #include "BKE_nla.h"
 #include "BKE_bmesh.h"
@@ -4995,8 +4994,7 @@ static bool createEdgeSlideVerts(TransInfo *t)
        TransDataEdgeSlideVert *sv_array;
        int sv_tot;
        BMBVHTree *btree;
-       /* BMVert -> sv_array index */
-       SmallHash table;
+       int *sv_table;  /* BMVert -> sv_array index */
        EdgeSlideData *sld = MEM_callocN(sizeof(*sld), "sld");
        View3D *v3d = NULL;
        RegionView3D *rv3d = NULL;
@@ -5014,6 +5012,17 @@ static bool createEdgeSlideVerts(TransInfo *t)
                rv3d = t->ar ? t->ar->regiondata : NULL;
        }
 
+       if ((t->settings->uvcalc_flag & UVCALC_TRANSFORM_CORRECT) &&
+           /* don't do this at all for non-basis shape keys, too easy to
+                * accidentally break uv maps or vertex colors then */
+           (bm->shapenr <= 1))
+       {
+               sld->use_origfaces = true;
+       }
+       else {
+               sld->use_origfaces = false;
+       }
+
        sld->is_proportional = true;
        sld->curr_sv_index = 0;
        sld->flipped_vtx = FALSE;
@@ -5025,11 +5034,7 @@ static bool createEdgeSlideVerts(TransInfo *t)
        else {
                ED_view3d_ob_project_mat_get(rv3d, t->obedit, projectMat);
        }
-       
-       BLI_smallhash_init(&sld->vhash);
-       BLI_smallhash_init(&sld->origfaces);
-       BLI_smallhash_init(&table);
-       
+
        /*ensure valid selection*/
        BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) {
                if (BM_elem_flag_test(v, BM_ELEM_SELECT)) {
@@ -5063,20 +5068,26 @@ static bool createEdgeSlideVerts(TransInfo *t)
                }
        }
 
+       sv_table = MEM_mallocN(sizeof(*sv_table) * bm->totvert, __func__);
+
        j = 0;
-       BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) {
+       BM_ITER_MESH_INDEX (v, &iter, bm, BM_VERTS_OF_MESH, i) {
                if (BM_elem_flag_test(v, BM_ELEM_SELECT)) {
                        BM_elem_flag_enable(v, BM_ELEM_TAG);
-                       BLI_smallhash_insert(&table, (uintptr_t)v, SET_INT_IN_POINTER(j));
+                       sv_table[i] = j;
                        j += 1;
                }
                else {
                        BM_elem_flag_disable(v, BM_ELEM_TAG);
+                       sv_table[i] = -1;
                }
+               BM_elem_index_set(v, i); /* set_inline */
        }
+       bm->elem_index_dirty &= ~BM_VERT;
 
        if (!j) {
                MEM_freeN(sld);
+               MEM_freeN(sv_table);
                return false;
        }
 
@@ -5173,9 +5184,9 @@ static bool createEdgeSlideVerts(TransInfo *t)
                        BMEdge *e_prev;
 
                        /* XXX, 'sv' will initialize multiple times, this is suspicious. see [#34024] */
-                       BLI_assert(BLI_smallhash_haskey(&table, (uintptr_t)v) != false);
                        BLI_assert(v != NULL);
-                       sv = sv_array + GET_INT_FROM_POINTER(BLI_smallhash_lookup(&table, (uintptr_t)v));
+                       BLI_assert(sv_table[BM_elem_index_get(v)] != -1);
+                       sv = &sv_array[sv_table[BM_elem_index_get(v)]];
                        sv->v = v;
                        copy_v3_v3(sv->v_co_orig, v->co);
                        sv->loop_nr = loop_nr;
@@ -5199,9 +5210,9 @@ static bool createEdgeSlideVerts(TransInfo *t)
                        e = get_other_edge(v, e);
 
                        if (!e) {
-                               BLI_assert(BLI_smallhash_haskey(&table, (uintptr_t)v) != false);
                                BLI_assert(v != NULL);
-                               sv = sv_array + GET_INT_FROM_POINTER(BLI_smallhash_lookup(&table, (uintptr_t)v));
+                               BLI_assert(sv_table[BM_elem_index_get(v)] != -1);
+                               sv = &sv_array[sv_table[BM_elem_index_get(v)]];
                                sv->v = v;
                                copy_v3_v3(sv->v_co_orig, v->co);
                                sv->loop_nr = loop_nr;
@@ -5268,7 +5279,6 @@ static bool createEdgeSlideVerts(TransInfo *t)
                loop_nr++;
        }
 
-
        /* use for visibility checks */
        use_btree_disp = (v3d && t->obedit->dt > OB_WIRE && v3d->drawtype > OB_WIRE);
 
@@ -5316,8 +5326,8 @@ static bool createEdgeSlideVerts(TransInfo *t)
                                                continue;
                                        }
 
-                                       BLI_assert(BLI_smallhash_haskey(&table, (uintptr_t)v) != false);
-                                       j = GET_INT_FROM_POINTER(BLI_smallhash_lookup(&table, (uintptr_t)v));
+                                       BLI_assert(sv_table[BM_elem_index_get(v)] != -1);
+                                       j = sv_table[BM_elem_index_get(v)];
 
                                        if (sv_array[j].v_b) {
                                                ED_view3d_project_float_v3_m4(ar, sv_array[j].v_b->co, sco_b, projectMat);
@@ -5364,33 +5374,29 @@ static bool createEdgeSlideVerts(TransInfo *t)
 
        bmesh_edit_begin(bm, BMO_OPTYPE_FLAG_UNTAN_MULTIRES);
 
+       if (sld->use_origfaces) {
+               sld->origfaces = BLI_ghash_ptr_new(__func__);
+               sld->bm_origfaces = BM_mesh_create(&bm_mesh_allocsize_default);
+               /* we need to have matching customdata */
+               BM_mesh_copy_init_customdata(sld->bm_origfaces, bm, NULL);
+       }
+
        /*create copies of faces for customdata projection*/
        sv_array = sld->sv;
        for (i = 0; i < sld->totsv; i++, sv_array++) {
-               BMIter fiter, liter;
+               BMIter fiter;
                BMFace *f;
-               BMLoop *l;
                
-               BM_ITER_ELEM (f, &fiter, sv_array->v, BM_FACES_OF_VERT) {
-                       
-                       if (!BLI_smallhash_haskey(&sld->origfaces, (uintptr_t)f)) {
-                               BMFace *copyf = BM_face_copy(bm, f, true, true);
-                               
-                               BM_face_select_set(bm, copyf, false);
-                               BM_elem_flag_enable(copyf, BM_ELEM_HIDDEN);
-                               BM_ITER_ELEM (l, &liter, copyf, BM_LOOPS_OF_FACE) {
-                                       BM_vert_select_set(bm, l->v, false);
-                                       BM_elem_flag_enable(l->v, BM_ELEM_HIDDEN);
-                                       BM_edge_select_set(bm, l->e, false);
-                                       BM_elem_flag_enable(l->e, BM_ELEM_HIDDEN);
-                               }
 
-                               BLI_smallhash_insert(&sld->origfaces, (uintptr_t)f, copyf);
+               if (sld->use_origfaces) {
+                       BM_ITER_ELEM (f, &fiter, sv_array->v, BM_FACES_OF_VERT) {
+                               if (!BLI_ghash_haskey(sld->origfaces, f)) {
+                                       BMFace *f_copy = BM_face_copy(sld->bm_origfaces, bm, f, true, true);
+                                       BLI_ghash_insert(sld->origfaces, f, f_copy);
+                               }
                        }
                }
 
-               BLI_smallhash_insert(&sld->vhash, (uintptr_t)sv_array->v, sv_array);
-
                /* switch a/b if loop direction is different from global direction */
                l_nr = sv_array->loop_nr;
                if (dot_v3v3(loop_dir[l_nr], mval_dir) < 0.0f) {
@@ -5402,9 +5408,8 @@ static bool createEdgeSlideVerts(TransInfo *t)
        if (rv3d)
                calcNonProportionalEdgeSlide(t, sld, mval);
 
-       sld->origfaces_init = true;
        sld->em = em;
-       
+
        /*zero out start*/
        zero_v2(mval_start);
 
@@ -5422,16 +5427,13 @@ static bool createEdgeSlideVerts(TransInfo *t)
        
        t->customData = sld;
        
-       BLI_smallhash_release(&table);
+       MEM_freeN(sv_table);
        if (btree) {
                BKE_bmbvh_free(btree);
        }
        MEM_freeN(loop_dir);
        MEM_freeN(loop_maxdist);
 
-       /* arrays are dirty from copying faces: EDBM_index_arrays_free */
-       EDBM_update_generic(em, false, true);
-
        return true;
 }
 
@@ -5442,17 +5444,10 @@ void projectEdgeSlideData(TransInfo *t, bool is_final)
        BMEditMesh *em = sld->em;
        int i;
 
-       if (!em)
-               return;
-       
-       if (!(t->settings->uvcalc_flag & UVCALC_TRANSFORM_CORRECT))
+       if (sld->use_origfaces == false) {
                return;
+       }
 
-       /* don't do this at all for non-basis shape keys, too easy to
-        * accidentally break uv maps or vertex colors then */
-       if (em->bm->shapenr > 1)
-               return;
-       
        for (i = 0, sv = sld->sv; i < sld->totsv; sv++, i++) {
                BMIter fiter;
                BMLoop *l;
@@ -5460,15 +5455,8 @@ void projectEdgeSlideData(TransInfo *t, bool is_final)
                BM_ITER_ELEM (l, &fiter, sv->v, BM_LOOPS_OF_VERT) {
                        BMFace *f_copy;      /* the copy of 'f' */
                        BMFace *f_copy_flip; /* the copy of 'f' or detect if we need to flip to the shorter side. */
-                       bool is_sel, is_hide;
-                       
-                       /* the face attributes of the copied face will get
-                        * copied over, so its necessary to save the selection
-                        * and hidden state*/
-                       is_sel = BM_elem_flag_test(l->f, BM_ELEM_SELECT) != 0;
-                       is_hide = BM_elem_flag_test(l->f, BM_ELEM_HIDDEN) != 0;
                        
-                       f_copy = BLI_smallhash_lookup(&sld->origfaces, (uintptr_t)l->f);
+                       f_copy = BLI_ghash_lookup(sld->origfaces, l->f);
                        
                        /* project onto copied projection face */
                        f_copy_flip = f_copy;
@@ -5482,12 +5470,12 @@ void projectEdgeSlideData(TransInfo *t, bool is_final)
 
                                if (sld->perc < 0.0f) {
                                        if (BM_vert_in_face(l_ed_sel->radial_next->f, sv->v_b)) {
-                                               f_copy_flip = BLI_smallhash_lookup(&sld->origfaces, (uintptr_t)l_ed_sel->radial_next->f);
+                                               f_copy_flip = BLI_ghash_lookup(sld->origfaces, l_ed_sel->radial_next->f);
                                        }
                                }
                                else if (sld->perc > 0.0f) {
                                        if (BM_vert_in_face(l_ed_sel->radial_next->f, sv->v_a)) {
-                                               f_copy_flip = BLI_smallhash_lookup(&sld->origfaces, (uintptr_t)l_ed_sel->radial_next->f);
+                                               f_copy_flip = BLI_ghash_lookup(sld->origfaces, l_ed_sel->radial_next->f);
                                        }
                                }
 
@@ -5573,7 +5561,7 @@ void projectEdgeSlideData(TransInfo *t, bool is_final)
                                                        l_adj = l;
                                                }
 
-                                               f_copy_flip = BLI_smallhash_lookup(&sld->origfaces, (uintptr_t)l_adj->f);
+                                               f_copy_flip = BLI_ghash_lookup(sld->origfaces, l_adj->f);
                                        }
                                }
                        }
@@ -5590,36 +5578,23 @@ void projectEdgeSlideData(TransInfo *t, bool is_final)
                        }
                        
                        /* make sure face-attributes are correct (e.g. MTexPoly) */
-                       BM_elem_attrs_copy(em->bm, em->bm, f_copy, l->f);
-                       
-                       /* restore selection and hidden flags */
-                       BM_face_select_set(em->bm, l->f, is_sel);
-                       if (!is_hide) {
-                               /* this check is a workaround for bug, see note - [#30735],
-                                * without this edge can be hidden and selected */
-                               BM_elem_hide_set(em->bm, l->f, is_hide);
-                       }
+                       BM_elem_attrs_copy(sld->bm_origfaces, em->bm, f_copy, l->f);
                }
        }
 }
 
 void freeEdgeSlideTempFaces(EdgeSlideData *sld)
 {
-       if (sld->origfaces_init) {
-               SmallHashIter hiter;
-               BMFace *copyf;
-
-               copyf = BLI_smallhash_iternew(&sld->origfaces, &hiter, NULL);
-               for (; copyf; copyf = BLI_smallhash_iternext(&hiter, NULL)) {
-                       BM_face_verts_kill(sld->em->bm, copyf);
+       if (sld->use_origfaces) {
+               if (sld->bm_origfaces) {
+                       BM_mesh_free(sld->bm_origfaces);
+                       sld->bm_origfaces = NULL;
                }
 
-               BLI_smallhash_release(&sld->origfaces);
-
-               sld->origfaces_init = false;
-
-               /* arrays are dirty from removing faces: EDBM_index_arrays_free */
-               EDBM_update_generic(sld->em, FALSE, TRUE);
+               if (sld->origfaces) {
+                       BLI_ghash_free(sld->origfaces, NULL, NULL);
+                       sld->origfaces = NULL;
+               }
        }
 }
 
@@ -5628,30 +5603,12 @@ void freeEdgeSlideVerts(TransInfo *t)
 {
        EdgeSlideData *sld = t->customData;
        
-#if 0 /*BMESH_TODO*/
-       if (me->drawflag & ME_DRAWEXTRA_EDGELEN) {
-               TransDataEdgeSlideVert *sv;
-               LinkNode *look = sld->vertlist;
-               GHash *vertgh = sld->vhash;
-               while (look) {
-                       sv  = BLI_ghash_lookup(vertgh, (EditVert *)look->link);
-                       if (sv != NULL) {
-                               sv->v_a->f &= !SELECT;
-                               sv->v_b->f &= !SELECT;
-                       }
-                       look = look->next;
-               }
-       }
-#endif
-       
        if (!sld)
                return;
        
        freeEdgeSlideTempFaces(sld);
 
        bmesh_edit_end(sld->em->bm, BMO_OPTYPE_FLAG_UNTAN_MULTIRES);
-
-       BLI_smallhash_release(&sld->vhash);
        
        MEM_freeN(sld->sv);
        MEM_freeN(sld);
index d160e1562b00b837277b1099109e498af0c3fe7f..911d4b0a6237707f0b6e012f0e8040882f2afb05 100644 (file)
@@ -201,14 +201,14 @@ typedef struct EdgeSlideData {
        TransDataEdgeSlideVert *sv;
        int totsv;
        
-       struct SmallHash vhash;
-       struct SmallHash origfaces;
+       struct GHash *origfaces;
 
        int mval_start[2], mval_end[2];
        struct BMEditMesh *em;
 
        /* flag that is set when origfaces is initialized */
-       bool origfaces_init;
+       bool use_origfaces;
+       struct BMesh *bm_origfaces;
 
        float perc;
 
index 5059e3bcc401d874d4128f1bce9cef0ad566a4f1..fc61c94ff64cdb3b980ea1d409fe19305b750e89 100644 (file)
@@ -1641,6 +1641,11 @@ void BIF_draw_manipulator(const bContext *C)
                mul_mat3_m4_fl(rv3d->twmat, ED_view3d_pixel_size(rv3d, rv3d->twmat[3]) * U.tw_size * 5.0f);
        }
 
+       /* when looking through a selected camera, the manipulator can be at the
+        * exact same position as the view, skip so we don't break selection */
+       if (fabsf(mat4_to_scale(rv3d->twmat)) < 1e-7f)
+               return;
+
        test_manipulator_axis(C);
        drawflags = rv3d->twdrawflag;    /* set in calc_manipulator_stats */
 
@@ -1677,7 +1682,12 @@ static int manipulator_selectbuf(ScrArea *sa, ARegion *ar, const int mval[2], fl
        rctf rect;
        GLuint buffer[64];      // max 4 items per select, so large enuf
        short hits;
-       extern void setwinmatrixview3d(ARegion *ar, View3D *v3d, rctf *rect); // XXX check a bit later on this... (ton)
+       extern void setwinmatrixview3d(ARegion *, View3D *, rctf *); // XXX check a bit later on this... (ton)
+
+       /* when looking through a selected camera, the manipulator can be at the
+        * exact same position as the view, skip so we don't break selection */
+       if (fabsf(mat4_to_scale(rv3d->twmat)) < 1e-7f)
+               return 0;
 
        G.f |= G_PICKSEL;
 
index 52f87c19dc8824d81fa595b2e016c3d321b0b291..e285fd8bea440f6dd550ade7b17be68b3edbe90b 100644 (file)
@@ -143,7 +143,7 @@ static int ed_undo_step(bContext *C, int step, const char *undoname)
                if ((obact && (obact->mode & OB_MODE_TEXTURE_PAINT)) || (sima->mode == SI_MODE_PAINT)) {
                        if (!ED_undo_paint_step(C, UNDO_PAINT_IMAGE, step, undoname) && undoname) {
                                if (U.uiflag & USER_GLOBALUNDO) {
-                                       ED_viewport_render_kill_jobs(C);
+                                       ED_viewport_render_kill_jobs(C, true);
                                        BKE_undo_name(C, undoname);
                                }
                        }
@@ -196,7 +196,7 @@ static int ed_undo_step(bContext *C, int step, const char *undoname)
                        /* for example, texface stores image pointers */
                        undo_editmode_clear();
                        
-                       ED_viewport_render_kill_jobs(C);
+                       ED_viewport_render_kill_jobs(C, true);
 
                        if (undoname)
                                BKE_undo_name(C, undoname);
@@ -369,7 +369,7 @@ int ED_undo_operator_repeat(bContext *C, struct wmOperator *op)
                {
                        int retval;
 
-                       ED_viewport_render_kill_jobs(C);
+                       ED_viewport_render_kill_jobs(C, true);
 
                        if (G.debug & G_DEBUG)
                                printf("redo_cb: operator redo %s\n", op->type->name);
@@ -537,7 +537,7 @@ static int undo_history_exec(bContext *C, wmOperator *op)
                        WM_event_add_notifier(C, NC_GEOM | ND_DATA, NULL);
                }
                else {
-                       ED_viewport_render_kill_jobs(C);
+                       ED_viewport_render_kill_jobs(C, true);
                        BKE_undo_number(C, item);
                        WM_event_add_notifier(C, NC_SCENE | ND_LAYER_CONTENT, CTX_data_scene(C));
                }
index 6f92c1873d6f9f6752a9e04bcc92c91e88714702..18f4e8cafaf0ee9b10c690cdce98b0c829070dcf 100644 (file)
@@ -3682,8 +3682,8 @@ static SmoothNode *p_node_new(MemArena *arena, SmoothTriangle **tri, int ntri, f
        if (ntri <= 10 || depth >= 15)
                return node;
        
-       t1 = MEM_mallocN(sizeof(SmoothTriangle) * ntri, "PNodeTri1");
-       t2 = MEM_mallocN(sizeof(SmoothTriangle) * ntri, "PNodeTri1");
+       t1 = MEM_mallocN(sizeof(*t1) * ntri, "PNodeTri1");
+       t2 = MEM_mallocN(sizeof(*t2) * ntri, "PNodeTri1");
 
        axis = (bmax[0] - bmin[0] > bmax[1] - bmin[1]) ? 0 : 1;
        split = 0.5f * (bmin[axis] + bmax[axis]);
index 2f98a042e2736c1f9ba12a3c6952c0267600df91..cd8ce14567e03a919216cd945745fa53d3ffcdf4 100644 (file)
  *  \ingroup freestyle
  */
 
-#include <assert.h>
-
 #include "BlenderFileLoader.h"
 
+#include "BLI_utildefines.h"
+
 #include "BKE_global.h"
 
 namespace Freestyle {
@@ -60,8 +60,23 @@ NodeGroup *BlenderFileLoader::Load()
        _viewplane_right =  _re->viewplane.xmax;
        _viewplane_bottom = _re->viewplane.ymin;
        _viewplane_top =    _re->viewplane.ymax;
-       _z_near = -_re->clipsta;
-       _z_far =  -_re->clipend;
+
+       if ((_re->r.scemode & R_VIEWPORT_PREVIEW) && (_re->r.mode & R_ORTHO)) {
+               // Adjust clipping start/end and set up a Z offset when the viewport preview
+               // is used with the orthographic view.  In this case, _re->clipsta is negative,
+               // while Freestyle assumes that imported mesh data are in the camera coordinate
+               // system with the view point located at origin [bug #36009].
+               BLI_assert(_re->clipsta < 0.f);
+               _z_near = -0.001f;
+               _z_offset = _re->clipsta + _z_near;
+               _z_far = -_re->clipend + _z_offset;
+       }
+       else {
+               _z_near = -_re->clipsta;
+               _z_far = -_re->clipend;
+               _z_offset = 0.f;
+       }
+
 #if 0
        if (G.debug & G_DEBUG_FREESTYLE) {
                cout << "Frustum: l " << _viewplane_left << " r " << _viewplane_right
@@ -225,7 +240,7 @@ void BlenderFileLoader::clipTriangle(int numTris, float triCoords[][3], float v1
                        }
                }
        }
-       assert(k == 2 + numTris);
+       BLI_assert(k == 2 + numTris);
 }
 
 void BlenderFileLoader::addTriangle(struct LoaderState *ls, float v1[3], float v2[3], float v3[3],
@@ -293,6 +308,9 @@ void BlenderFileLoader::addTriangle(struct LoaderState *ls, float v1[3], float v
 // zero otherwise.
 int BlenderFileLoader::testDegenerateTriangle(float v1[3], float v2[3], float v3[3])
 {
+       const float eps = 1.0e-6;
+       const float eps_sq = eps * eps;
+
 #if 0
        float area = area_tri_v3(v1, v2, v3);
        bool verbose = (area < 1.0e-6);
@@ -306,9 +324,9 @@ int BlenderFileLoader::testDegenerateTriangle(float v1[3], float v2[3], float v3
 #endif
                return 1;
        }
-       if (dist_to_line_segment_v3(v1, v2, v3) < 1.0e-6 ||
-           dist_to_line_segment_v3(v2, v1, v3) < 1.0e-6 ||
-           dist_to_line_segment_v3(v3, v1, v2) < 1.0e-6)
+       if (dist_squared_to_line_segment_v3(v1, v2, v3) < eps_sq ||
+           dist_squared_to_line_segment_v3(v2, v1, v3) < eps_sq ||
+           dist_squared_to_line_segment_v3(v3, v1, v2) < eps_sq)
        {
 #if 0
                if (verbose && G.debug & G_DEBUG_FREESTYLE) {
@@ -378,6 +396,11 @@ void BlenderFileLoader::insertShapeNode(ObjectInstanceRen *obi, int id)
                        if (vlr->v4)
                                mul_m4_v3(obi->mat, v4);
                }
+               v1[2] += _z_offset;
+               v2[2] += _z_offset;
+               v3[2] += _z_offset;
+               if (vlr->v4)
+                       v4[2] += _z_offset;
 #if 0
                print_v3("v1", v1);
                print_v3("v2", v2);
@@ -472,6 +495,11 @@ void BlenderFileLoader::insertShapeNode(ObjectInstanceRen *obi, int id)
                        if (vlr->v4)
                                mul_m4_v3(obi->mat, v4);
                }
+               v1[2] += _z_offset;
+               v2[2] += _z_offset;
+               v3[2] += _z_offset;
+               if (vlr->v4)
+                       v4[2] += _z_offset;
                if (_smooth && (vlr->flag & R_SMOOTH)) {
                        copy_v3_v3(n1, vlr->v1->n);
                        copy_v3_v3(n2, vlr->v2->n);
index 494dd375be0b792dfcddc3dc01dc6ef93f899ea7..c505eab40f170844a6389527373ef0f97a94675e 100644 (file)
@@ -122,6 +122,7 @@ protected:
        float _viewplane_bottom;
        float _viewplane_top;
        float _z_near, _z_far;
+       float _z_offset;
 
        RenderMonitor *_pRenderMonitor;
 
index ed9932c3eef593c17d87d5e58464ec860b158b9a..8bc7c0952a8eef8e7c9fdcc18c3e6031e9556f34 100644 (file)
@@ -79,10 +79,10 @@ void ArbitraryGridDensityProvider::initialize(const real proscenium[4])
        // Make sure the grid exceeds the proscenium by a small amount
        float safetyZone = 0.1f;
        if (_cellsX * _cellSize < prosceniumWidth * (1.0 + safetyZone)) {
-               _cellsX = prosceniumWidth * (1.0 + safetyZone) / _cellSize;
+               _cellsX = ceil(prosceniumWidth * (1.0 + safetyZone) / _cellSize);
        }
        if (_cellsY * _cellSize < prosceniumHeight * (1.0 + safetyZone)) {
-               _cellsY = prosceniumHeight * (1.0 + safetyZone) / _cellSize;
+               _cellsY = ceil(prosceniumHeight * (1.0 + safetyZone) / _cellSize);
        }
        if (G.debug & G_DEBUG_FREESTYLE) {
                cout << _cellsX << "x" << _cellsY << " cells of size " << _cellSize << " square." << endl;
index 61ad78a85673534c61bbf5aa44b0fb51f3444e8a..952b9752a3efe77cd3e2f38dd9e13b728b6ff9ee 100644 (file)
@@ -100,10 +100,10 @@ void AverageAreaGridDensityProvider::initialize(const real proscenium[4], real s
        // Make sure the grid exceeds the proscenium by a small amount
        float safetyZone = 0.1f;
        if (_cellsX * _cellSize < prosceniumWidth * (1.0 + safetyZone)) {
-               _cellsX = prosceniumWidth * (1.0 + safetyZone) / _cellSize;
+               _cellsX = ceil(prosceniumWidth * (1.0 + safetyZone) / _cellSize);
        }
        if (_cellsY * _cellSize < prosceniumHeight * (1.0 + safetyZone)) {
-               _cellsY = prosceniumHeight * (1.0 + safetyZone) / _cellSize;
+               _cellsY = ceil(prosceniumHeight * (1.0 + safetyZone) / _cellSize);
        }
        if (G.debug & G_DEBUG_FREESTYLE) {
                cout << _cellsX << "x" << _cellsY << " cells of size " << _cellSize << " square." << endl;
index 2e702813fb83ad9ae07798eb699d27ca3ed7df3b..f770bf6843ff01237e5c0b02421866827784639f 100644 (file)
@@ -129,6 +129,10 @@ void BoxGrid::assignCells (OccluderSource& source, GridDensityProvider& density,
        _cellsY = density.cellsY();
        _cellOrigin[0] = density.cellOrigin(0);
        _cellOrigin[1] = density.cellOrigin(1);
+       if (G.debug & G_DEBUG_FREESTYLE) {
+               cout << "Using " << _cellsX << "x" << _cellsY << " cells of size " << _cellSize << " square." << endl;
+               cout << "Cell origin: " << _cellOrigin[0] << ", " << _cellOrigin[1] << endl;
+       }
 
        // Now allocate the cell table and fill it with default (empty) cells
        _cells.resize(_cellsX * _cellsY);
index d096fb3aacda9c3df2d9d4327ce09557a5d53ebf..fe14efbe20f559bb4b978688b9ca9b47048327d9 100644 (file)
@@ -100,24 +100,29 @@ public:
        static void calculateQuickProscenium(const GridHelpers::Transform& transform, const BBox<Vec3r>& bbox,
                                             real proscenium[4])
        {
-               real z;
-               // We want to use the z-coordinate closest to the camera to determine the proscenium face
-               if (::fabs(bbox.getMin()[2]) < ::fabs(bbox.getMax()[2])) {
-                       z = bbox.getMin()[2];
-               }
-               else {
-                       z = bbox.getMax()[2];
-               }
-               // Now calculate the proscenium according to the min and max values of the x and y coordinates
-               Vec3r minPoint = transform(Vec3r(bbox.getMin()[0], bbox.getMin()[1], z));
-               Vec3r maxPoint = transform(Vec3r(bbox.getMax()[0], bbox.getMax()[1], z));
-               proscenium[0] = std::min(minPoint[0], maxPoint[0]);
-               proscenium[1] = std::max(minPoint[0], maxPoint[0]);
-               proscenium[2] = std::min(minPoint[1], maxPoint[1]);
-               proscenium[3] = std::max(minPoint[1], maxPoint[1]);
+               // Transform the coordinates of the 8 corners of the 3D bounding box
+               real xm = bbox.getMin()[0], xM = bbox.getMax()[0];
+               real ym = bbox.getMin()[1], yM = bbox.getMax()[1];
+               real zm = bbox.getMin()[2], zM = bbox.getMax()[2];
+               Vec3r p1 = transform(Vec3r(xm, ym, zm));
+               Vec3r p2 = transform(Vec3r(xm, ym, zM));
+               Vec3r p3 = transform(Vec3r(xm, yM, zm));
+               Vec3r p4 = transform(Vec3r(xm, yM, zM));
+               Vec3r p5 = transform(Vec3r(xM, ym, zm));
+               Vec3r p6 = transform(Vec3r(xM, ym, zM));
+               Vec3r p7 = transform(Vec3r(xM, yM, zm));
+               Vec3r p8 = transform(Vec3r(xM, yM, zM));
+               // Determine the proscenium face according to the min and max values of the transformed x and y coordinates
+               proscenium[0] = std::min(std::min(std::min(p1.x(), p2.x()), std::min(p3.x(), p4.x())),
+                                        std::min(std::min(p5.x(), p6.x()), std::min(p7.x(), p8.x())));
+               proscenium[1] = std::max(std::max(std::max(p1.x(), p2.x()), std::max(p3.x(), p4.x())),
+                                        std::max(std::max(p5.x(), p6.x()), std::max(p7.x(), p8.x())));
+               proscenium[2] = std::min(std::min(std::min(p1.y(), p2.y()), std::min(p3.y(), p4.y())),
+                                        std::min(std::min(p5.y(), p6.y()), std::min(p7.y(), p8.y())));
+               proscenium[3] = std::max(std::max(std::max(p1.y(), p2.y()), std::max(p3.y(), p4.y())),
+                                        std::max(std::max(p5.y(), p6.y()), std::max(p7.y(), p8.y())));
                if (G.debug & G_DEBUG_FREESTYLE) {
-                       cout << "Bounding box: " << minPoint << " to " << maxPoint << endl;
-                       cout << "Proscenium  : " << proscenium[0] << ", " << proscenium[1] << ", " << proscenium[2] << ", " <<
+                       cout << "Proscenium: " << proscenium[0] << ", " << proscenium[1] << ", " << proscenium[2] << ", " <<
                                proscenium[3] << endl;
                }
        }
index 40a3c9f298d136cbdc4fde1ce5647c069a1bb19e..e3bb9b87ecc043f2f02712d8280f4c38c3a6294c 100644 (file)
@@ -78,10 +78,10 @@ void Pow23GridDensityProvider::initialize(const real proscenium[4])
        // Make sure the grid exceeds the proscenium by a small amount
        float safetyZone = 0.1;
        if (_cellsX * _cellSize < prosceniumWidth * (1.0 + safetyZone)) {
-               _cellsX = prosceniumWidth * (1.0 + safetyZone) / _cellSize;
+               _cellsX = ceil(prosceniumWidth * (1.0 + safetyZone) / _cellSize);
        }
        if (_cellsY * _cellSize < prosceniumHeight * (1.0 + safetyZone)) {
-               _cellsY = prosceniumHeight * (1.0 + safetyZone) / _cellSize;
+               _cellsY = ceil(prosceniumHeight * (1.0 + safetyZone) / _cellSize);
        }
        if (G.debug & G_DEBUG_FREESTYLE) {
                cout << _cellsX << "x" << _cellsY << " cells of size " << _cellSize << " square." << endl;
index 1621bd850008b109da8f8975d4d4f392d54cbc9c..60ad7daea0a5d3dba201e107005287d1a670fa71 100644 (file)
@@ -127,6 +127,10 @@ void SphericalGrid::assignCells(OccluderSource& source, GridDensityProvider& den
        _cellsY = density.cellsY();
        _cellOrigin[0] = density.cellOrigin(0);
        _cellOrigin[1] = density.cellOrigin(1);
+       if (G.debug & G_DEBUG_FREESTYLE) {
+               cout << "Using " << _cellsX << "x" << _cellsY << " cells of size " << _cellSize << " square." << endl;
+               cout << "Cell origin: " << _cellOrigin[0] << ", " << _cellOrigin[1] << endl;
+       }
 
        // Now allocate the cell table and fill it with default (empty) cells
        _cells.resize(_cellsX * _cellsY);