Merge branch 'master' into blender2.8
authorCampbell Barton <ideasman42@gmail.com>
Wed, 15 Jun 2016 07:29:11 +0000 (17:29 +1000)
committerCampbell Barton <ideasman42@gmail.com>
Wed, 15 Jun 2016 07:29:11 +0000 (17:29 +1000)
17 files changed:
extern/curve_fit_nd/curve_fit_nd.h
extern/curve_fit_nd/intern/curve_fit_cubic.c
intern/cycles/render/nodes.cpp
release/scripts/modules/bpy_extras/keyconfig_utils.py
source/blender/blenkernel/BKE_node.h
source/blender/blenkernel/intern/library_idmap.c
source/blender/blenkernel/intern/node.c
source/blender/bmesh/tools/bmesh_decimate_collapse.c
source/blender/collada/MeshImporter.cpp
source/blender/editors/curve/editcurve_paint.c
source/blender/editors/interface/interface_handlers.c
source/blender/editors/io/io_collada.c
source/blender/editors/mesh/editmesh_bevel.c
source/blender/editors/transform/transform.c
source/blender/imbuf/intern/cineon/logImageCore.c
source/blender/makesrna/intern/rna_pose.c
source/blender/nodes/shader/node_shader_tree.c

index ff6b9513a9bcf49027ae4a4369e5604e81f5c10f..3649802a425c66dacd4d2fe9caf01894e80e2a57 100644 (file)
@@ -60,6 +60,7 @@ int curve_fit_cubic_to_points_db(
         const unsigned int  points_len,
         const unsigned int  dims,
         const double        error_threshold,
+        const unsigned int  calc_flag,
         const unsigned int *corners,
         unsigned int        corners_len,
 
@@ -72,6 +73,7 @@ int curve_fit_cubic_to_points_fl(
         const unsigned int  points_len,
         const unsigned int  dims,
         const float         error_threshold,
+        const unsigned int  calc_flag,
         const unsigned int *corners,
         const unsigned int  corners_len,
 
@@ -117,6 +119,10 @@ int curve_fit_cubic_to_points_single_fl(
         float   r_handle_r[],
         float  *r_error_sq);
 
+enum {
+       CURVE_FIT_CALC_HIGH_QUALIY          = (1 << 0),
+};
+
 /* curve_fit_corners_detect.c */
 
 /**
index 4364e8f878fb5a62648cd061a61259d1f9a51aa0..1a0f7dcfdeef5909e50a457360c70baf7ff182ad 100644 (file)
@@ -1086,11 +1086,7 @@ static bool fit_cubic_to_points(
        *r_error_max_sq = error_max_sq;
        *r_split_index  = split_index;
 
-       if (error_max_sq < error_threshold_sq) {
-               free(u);
-               return true;
-       }
-       else {
+       if (!(error_max_sq < error_threshold_sq)) {
                cubic_copy(cubic_test, r_cubic, dims);
 
                /* If error not too large, try some reparameterization and iteration */
@@ -1108,25 +1104,28 @@ static bool fit_cubic_to_points(
                                points_offset_coords_length,
 #endif
                                u_prime, tan_l, tan_r, dims, cubic_test);
-                       error_max_sq = cubic_calc_error(
+
+                       const double error_max_sq_test = cubic_calc_error(
                                cubic_test, points_offset, points_offset_len, u_prime, dims,
                                &split_index);
 
-                       if (error_max_sq < error_threshold_sq) {
-                               free(u_prime);
-                               free(u);
-
-                               cubic_copy(r_cubic, cubic_test, dims);
-                               *r_error_max_sq = error_max_sq;
-                               *r_split_index  = split_index;
-                               return true;
-                       }
-                       else if (error_max_sq < *r_error_max_sq) {
+                       if (error_max_sq > error_max_sq_test) {
+                               error_max_sq = error_max_sq_test;
                                cubic_copy(r_cubic, cubic_test, dims);
                                *r_error_max_sq = error_max_sq;
                                *r_split_index = split_index;
                        }
 
+                       if (!(error_max_sq < error_threshold_sq)) {
+                               /* continue */
+                       }
+                       else {
+                               assert((error_max_sq < error_threshold_sq));
+                               free(u_prime);
+                               free(u);
+                               return true;
+                       }
+
                        SWAP(double *, u, u_prime);
                }
                free(u_prime);
@@ -1134,6 +1133,10 @@ static bool fit_cubic_to_points(
 
                return false;
        }
+       else {
+               free(u);
+               return true;
+       }
 }
 
 static void fit_cubic_to_points_recursive(
@@ -1145,6 +1148,7 @@ static void fit_cubic_to_points_recursive(
         const double  tan_l[],
         const double  tan_r[],
         const double  error_threshold_sq,
+        const uint    calc_flag,
         const uint    dims,
         /* fill in the list */
         CubicList *clist)
@@ -1158,8 +1162,11 @@ static void fit_cubic_to_points_recursive(
 #ifdef USE_LENGTH_CACHE
                points_length_cache,
 #endif
-               tan_l, tan_r, error_threshold_sq, dims,
-               cubic, &error_max_sq, &split_index))
+               tan_l, tan_r,
+               (calc_flag & CURVE_FIT_CALC_HIGH_QUALIY) ? DBL_EPSILON : error_threshold_sq,
+               dims,
+               cubic, &error_max_sq, &split_index) ||
+           (error_max_sq < error_threshold_sq))
        {
                cubic_list_prepend(clist, cubic);
                return;
@@ -1211,13 +1218,13 @@ static void fit_cubic_to_points_recursive(
 #ifdef USE_LENGTH_CACHE
                points_length_cache,
 #endif
-               tan_l, tan_center, error_threshold_sq, dims, clist);
+               tan_l, tan_center, error_threshold_sq, calc_flag, dims, clist);
        fit_cubic_to_points_recursive(
                &points_offset[split_index * dims], points_offset_len - split_index,
 #ifdef USE_LENGTH_CACHE
                points_length_cache + split_index,
 #endif
-               tan_center, tan_r, error_threshold_sq, dims, clist);
+               tan_center, tan_r, error_threshold_sq, calc_flag, dims, clist);
 
 }
 
@@ -1240,6 +1247,7 @@ int curve_fit_cubic_to_points_db(
         const uint    points_len,
         const uint    dims,
         const double  error_threshold,
+        const uint    calc_flag,
         const uint   *corners,
         uint          corners_len,
 
@@ -1315,7 +1323,7 @@ int curve_fit_cubic_to_points_db(
 #ifdef USE_LENGTH_CACHE
                                points_length_cache,
 #endif
-                               tan_l, tan_r, error_threshold_sq, dims, &clist);
+                               tan_l, tan_r, error_threshold_sq, calc_flag, dims, &clist);
                }
                else if (points_len == 1) {
                        assert(points_offset_len == 1);
@@ -1382,6 +1390,7 @@ int curve_fit_cubic_to_points_fl(
         const uint    points_len,
         const uint    dims,
         const float   error_threshold,
+        const uint    calc_flag,
         const uint   *corners,
         const uint    corners_len,
 
@@ -1399,7 +1408,7 @@ int curve_fit_cubic_to_points_fl(
        uint    cubic_array_len = 0;
 
        int result = curve_fit_cubic_to_points_db(
-               points_db, points_len, dims, error_threshold, corners, corners_len,
+               points_db, points_len, dims, error_threshold, calc_flag, corners, corners_len,
                &cubic_array_db, &cubic_array_len,
                r_cubic_orig_index,
                r_corner_index_array, r_corner_index_len);
index 6530bff084824efd4f4fd19d2a03173dda5e19f3..1157a1297ef714e3e8dedf581ef6036d9633c91f 100644 (file)
@@ -2985,7 +2985,7 @@ NODE_DEFINE(LightPathNode)
 
        SOCKET_OUT_FLOAT(is_camera_ray, "Is Camera Ray");
        SOCKET_OUT_FLOAT(is_shadow_ray, "Is Shadow Ray");
-       SOCKET_OUT_FLOAT(is_diffus_ray, "Is Diffus Ray");
+       SOCKET_OUT_FLOAT(is_diffuse_ray, "Is Diffuse Ray");
        SOCKET_OUT_FLOAT(is_glossy_ray, "Is Glossy Ray");
        SOCKET_OUT_FLOAT(is_singular_ray, "Is Singular Ray");
        SOCKET_OUT_FLOAT(is_reflection_ray, "Is Reflection Ray");
index 6246e4489e18b93984390eb997b18a1d7c155fa7..534dabf3d431addf8899dab6475fea5cbc4b3075 100644 (file)
@@ -76,7 +76,9 @@ KM_HIERARCHY = [
     ('Graph Editor', 'GRAPH_EDITOR', 'WINDOW', [
         ('Graph Editor Generic', 'GRAPH_EDITOR', 'WINDOW', []),
         ]),
-    ('Dopesheet', 'DOPESHEET_EDITOR', 'WINDOW', []),
+    ('Dopesheet', 'DOPESHEET_EDITOR', 'WINDOW', [
+        ('Dopesheet Generic', 'DOPESHEET_EDITOR', 'WINDOW', []),
+        ]),
     ('NLA Editor', 'NLA_EDITOR', 'WINDOW', [
         ('NLA Channels', 'NLA_EDITOR', 'WINDOW', []),
         ('NLA Generic', 'NLA_EDITOR', 'WINDOW', []),
index 76e49566d1958549a379de4fa44bfe33e2cfc3c5..4b92c1f7a3ad4e097aa79181246412d34719dce9 100644 (file)
@@ -348,6 +348,7 @@ void              ntreeUserDecrefID(struct bNodeTree *ntree);
 struct bNodeTree *ntreeFromID(struct ID *id);
 
 void              ntreeMakeLocal(struct bNodeTree *ntree, bool id_in_mainlist);
+struct bNode     *ntreeFindType(const struct bNodeTree *ntree, int type);
 bool              ntreeHasType(const struct bNodeTree *ntree, int type);
 bool              ntreeHasTree(const struct bNodeTree *ntree, const struct bNodeTree *lookup);
 void              ntreeUpdateTree(struct Main *main, struct bNodeTree *ntree);
index fd78d9b23ce4ed58a2071f7bcdd31a1a33b18de6..66025c04332d058915f0f8eab8f4b6b86079c1c7 100644 (file)
@@ -88,8 +88,10 @@ struct IDNameLib_Map *BKE_main_idmap_create(struct Main *bmain)
 
        int index = 0;
        while (index < MAX_LIBARRAY) {
-               id_map->type_maps[index].map = NULL;
-               id_map->type_maps[index].id_type = BKE_idcode_iter_step(&index);
+               struct IDNameLib_TypeMap *type_map = &id_map->type_maps[index];
+               type_map->map = NULL;
+               type_map->id_type = BKE_idcode_iter_step(&index);
+               BLI_assert(type_map->id_type != 0);
        }
        BLI_assert(index == MAX_LIBARRAY);
 
index 75f899dd597d258c8a3a5feed9e4cb1680e155fd..fa0367d16566f5fbfc6af9957690bf03b4c4c5f4 100644 (file)
@@ -2418,15 +2418,20 @@ void ntreeInterfaceTypeUpdate(bNodeTree *ntree)
 
 /* ************ find stuff *************** */
 
+bNode *ntreeFindType(const bNodeTree *ntree, int type) {
+       if (ntree) {
+               for (bNode * node = ntree->nodes.first; node; node = node->next) {
+                       if (node->type == type) {
+                               return node;
+                       }
+               }
+       }
+       return NULL;
+}
+
 bool ntreeHasType(const bNodeTree *ntree, int type)
 {
-       bNode *node;
-       
-       if (ntree)
-               for (node = ntree->nodes.first; node; node = node->next)
-                       if (node->type == type)
-                               return true;
-       return false;
+       return ntreeFindType(ntree, type) != NULL;
 }
 
 bool ntreeHasTree(const bNodeTree *ntree, const bNodeTree *lookup)
index 0a5e5aba86bcdd7c2eb4ccd3ded7093a05b91fdb..589b6d4752bd0996b378550de9ca9b3f9c0f5591 100644 (file)
@@ -55,7 +55,8 @@
 /* if the cost from #BLI_quadric_evaluate is 'noise', fallback to topology */
 #define USE_TOPOLOGY_FALLBACK
 #ifdef  USE_TOPOLOGY_FALLBACK
-#  define   TOPOLOGY_FALLBACK_EPS  FLT_EPSILON
+/* cost is calculated with double precision, it's ok to use a very small epsilon, see T48154. */
+#  define   TOPOLOGY_FALLBACK_EPS  1e-12f
 #endif
 
 /* these checks are for rare cases that we can't avoid since they are valid meshes still */
index 3adddddb8e78d94941f693087f0756f8bf1a1f8d..6085b66a8b87956dfe9787b57c7ae686a754f9a0 100644 (file)
@@ -271,38 +271,41 @@ bool MeshImporter::is_nice_mesh(COLLADAFW::Mesh *mesh)  // checks if mesh has su
        COLLADAFW::MeshPrimitiveArray& prim_arr = mesh->getMeshPrimitives();
 
        const std::string &name = bc_get_dae_name(mesh);
-       int hole_count = 0;
 
        for (unsigned i = 0; i < prim_arr.getCount(); i++) {
-               
+
                COLLADAFW::MeshPrimitive *mp = prim_arr[i];
                COLLADAFW::MeshPrimitive::PrimitiveType type = mp->getPrimitiveType();
 
                const char *type_str = bc_primTypeToStr(type);
-               
+
                // OpenCollada passes POLYGONS type for <polylist>
                if (type == COLLADAFW::MeshPrimitive::POLYLIST || type == COLLADAFW::MeshPrimitive::POLYGONS) {
 
                        COLLADAFW::Polygons *mpvc = (COLLADAFW::Polygons *)mp;
                        COLLADAFW::Polygons::VertexCountArray& vca = mpvc->getGroupedVerticesVertexCountArray();
-                       
+
+                       int hole_count = 0;
+                       int nonface_count = 0;
+
                        for (unsigned int j = 0; j < vca.getCount(); j++) {
                                int count = vca[j];
                                if (abs(count) < 3) {
-                                       fprintf(stderr, "ERROR: Primitive %s in %s has at least one face with vertex count < 3\n",
-                                               type_str, name.c_str());
-                                       return false;
+                                       nonface_count++;
                                }
-                               if (count < 0)
-                               {
+
+                               if (count < 0) {
                                        hole_count ++;
                                }
                        }
 
-                       if (hole_count > 0)
-                       {
+                       if (hole_count > 0) {
                                fprintf(stderr, "WARNING: Primitive %s in %s: %d holes not imported (unsupported)\n", type_str, name.c_str(), hole_count);
                        }
+
+                       if (nonface_count > 0) {
+                               fprintf(stderr, "WARNING: Primitive %s in %s: %d faces with vertex count < 3 (rejected)\n", type_str, name.c_str(), nonface_count);
+                       }
                }
 
                else if (type == COLLADAFW::MeshPrimitive::LINES) {
index bb7cc61f580f1439b7c929f5bf7812ad35648cf1..380185419296301f6f02f8a7517bb6ab1d93b5e5 100644 (file)
@@ -911,7 +911,7 @@ static int curve_draw_exec(bContext *C, wmOperator *op)
                unsigned int  corners_index_len = 0;
 
                const int result = curve_fit_cubic_to_points_fl(
-                       coords, stroke_len, dims, error_threshold,
+                       coords, stroke_len, dims, error_threshold, CURVE_FIT_CALC_HIGH_QUALIY,
                        corners, corners_len,
                        &cubic_spline, &cubic_spline_len,
                        NULL,
index ff4e11ac58b754f61361c9ae3f486cfa20a8d898..133487e18467857e5acd163249256d9e1909c806 100644 (file)
@@ -6981,13 +6981,15 @@ static int ui_do_button(bContext *C, uiBlock *block, uiBut *but, const wmEvent *
                         !IS_EVENT_MOD(event, shift, oskey) &&
                         (event->val == KM_PRESS))
                {
-                       if (event->alt)
-                               ui_but_anim_remove_driver(C);
-                       else if (event->ctrl)
-                               ui_but_anim_add_driver(C);
-                               
-                       ED_region_tag_redraw(data->region);
-                       
+                       /* quick check to prevent this opening within the popup menu its self */
+                       if (!ELEM(NULL, but->rnapoin.data, but->rnaprop)) {
+                               if (event->alt)
+                                       ui_but_anim_remove_driver(C);
+                               else if (event->ctrl)
+                                       ui_but_anim_add_driver(C);
+
+                               ED_region_tag_redraw(data->region);
+                       }
                        return WM_UI_HANDLER_BREAK;
                }
                /* handle keyingsets */
index b1ca95efe040f340266033a60e48585f92acdc35..3803221b4967afcb7a65671702e153e2ecae9833 100644 (file)
@@ -482,7 +482,7 @@ void WM_OT_collada_import(wmOperatorType *ot)
 
        RNA_def_boolean(ot->srna,
                "auto_connect", 0, "Auto Connect",
-               "set use_connect for parent bones which have exactly one child bone");
+               "Set use_connect for parent bones which have exactly one child bone");
 
        RNA_def_int(ot->srna,
                "min_chain_length",
index 0f871cd412723dd3b9d6b85ebff7bb38e9ecdf63..302ca407add0281f79d7108adf11d8a7ea605121 100644 (file)
 /* until implement profile = 0 case, need to clamp somewhat above zero */
 #define PROFILE_HARD_MIN 0.15f
 
+#define SEGMENTS_HARD_MAX 1000
+
+/* which value is mouse movement and numeric input controlling? */
+#define OFFSET_VALUE 0
+#define OFFSET_VALUE_PERCENT 1
+#define PROFILE_VALUE 2
+#define SEGMENTS_VALUE 3
+#define NUM_VALUE_KINDS 4
+
+static const char *value_rna_name[NUM_VALUE_KINDS] = {"offset", "offset", "profile", "segments"};
+static const float value_clamp_min[NUM_VALUE_KINDS] = {0.0f, 0.0f, PROFILE_HARD_MIN, 1.0f};
+static const float value_clamp_max[NUM_VALUE_KINDS] = {1e6, 100.0f, 1.0f, SEGMENTS_HARD_MAX};
+static const float value_start[NUM_VALUE_KINDS] = {0.0f, 0.0f, 0.5f, 1.0f};
+static const float value_scale_per_inch[NUM_VALUE_KINDS] = { 0.0f, 100.0f, 1.0f, 4.0f};
+
 typedef struct {
        BMEditMesh *em;
-       float initial_length;
-       float pixel_size;  /* use when mouse input is interpreted as spatial distance */
+       float initial_length[NUM_VALUE_KINDS];
+       float scale[NUM_VALUE_KINDS];
+       NumInput num_input[NUM_VALUE_KINDS]; 
+       float shift_value[NUM_VALUE_KINDS]; /* The current value when shift is pressed. Negative when shift not active. */
        bool is_modal;
-       NumInput num_input;
-       float shift_factor; /* The current factor when shift is pressed. Negative when shift not active. */
 
        /* modal only */
        float mcenter[2];
        BMBackup mesh_backup;
        void *draw_handle_pixel;
        short twtype;
-       bool mouse_controls_profile;
+       short value_mode;  /* Which value does mouse movement and numeric input affect? */
        float segments;     /* Segments as float so smooth mouse pan works in small increments */
 } BevelData;
 
 static void edbm_bevel_update_header(bContext *C, wmOperator *op)
 {
        const char *str = IFACE_("Confirm: (Enter/LMB), Cancel: (Esc/RMB), Mode: %s (M), Clamp Overlap: %s (C), "
-                                "Vertex Only: %s (V), Profile Control: %s (P), Offset: %s, Segments: %d");
+                                "Vertex Only: %s (V), Profile Control: %s (P), Offset: %s, Segments: %d, Profile: %.3f");
 
        char msg[UI_MAX_DRAW_STR];
        ScrArea *sa = CTX_wm_area(C);
@@ -93,8 +108,8 @@ static void edbm_bevel_update_header(bContext *C, wmOperator *op)
                const char *type_str;
                PropertyRNA *prop = RNA_struct_find_property(op->ptr, "offset_type");
 
-               if (hasNumInput(&opdata->num_input)) {
-                       outputNumInput(&opdata->num_input, offset_str, &sce->unit);
+               if (hasNumInput(&opdata->num_input[OFFSET_VALUE])) {
+                       outputNumInput(&opdata->num_input[OFFSET_VALUE], offset_str, &sce->unit);
                }
                else {
                        BLI_snprintf(offset_str, NUM_STR_REP_LEN, "%f", RNA_float_get(op->ptr, "offset"));
@@ -105,8 +120,8 @@ static void edbm_bevel_update_header(bContext *C, wmOperator *op)
                BLI_snprintf(msg, sizeof(msg), str, type_str,
                             WM_bool_as_string(RNA_boolean_get(op->ptr, "clamp_overlap")),
                             WM_bool_as_string(RNA_boolean_get(op->ptr, "vertex_only")),
-                            WM_bool_as_string(opdata->mouse_controls_profile),
-                            offset_str, RNA_int_get(op->ptr, "segments"));
+                            WM_bool_as_string(opdata->value_mode == PROFILE_VALUE),
+                            offset_str, RNA_int_get(op->ptr, "segments"), RNA_float_get(op->ptr, "profile"));
 
                ED_area_headerprint(sa, msg);
        }
@@ -118,6 +133,8 @@ static bool edbm_bevel_init(bContext *C, wmOperator *op, const bool is_modal)
        Scene *scene = CTX_data_scene(C);
        BMEditMesh *em = BKE_editmesh_from_object(obedit);
        BevelData *opdata;
+       float pixels_per_inch;
+       int i;
 
        if (em->bm->totvertsel == 0) {
                return false;
@@ -127,14 +144,25 @@ static bool edbm_bevel_init(bContext *C, wmOperator *op, const bool is_modal)
 
        opdata->em = em;
        opdata->is_modal = is_modal;
-       opdata->shift_factor = -1.0f;
-       opdata->mouse_controls_profile = false;
-
-       initNumInput(&opdata->num_input);
-       opdata->num_input.idx_max = 0;
-       opdata->num_input.val_flag[0] |= NUM_NO_NEGATIVE;
-       opdata->num_input.unit_sys = scene->unit.system;
-       opdata->num_input.unit_type[0] = B_UNIT_NONE;  /* Not sure this is a factor or a unit? */
+       opdata->value_mode = OFFSET_VALUE;
+       pixels_per_inch = U.dpi * U.pixelsize;
+
+       for (i = 0; i < NUM_VALUE_KINDS; i++) {
+               opdata->shift_value[i] = -1.0f;
+               /* note: scale for OFFSET_VALUE will get overwritten in edbm_bevel_invoke */
+               opdata->scale[i] = value_scale_per_inch[i] / pixels_per_inch; 
+
+               initNumInput(&opdata->num_input[i]);
+               opdata->num_input[i].idx_max = 0;
+               opdata->num_input[i].val_flag[0] |= NUM_NO_NEGATIVE;
+               if (i == SEGMENTS_VALUE) {
+                       opdata->num_input[i].val_flag[0] |= NUM_NO_FRACTION | NUM_NO_ZERO;
+               }
+               if (i == OFFSET_VALUE) {
+                       opdata->num_input[i].unit_sys = scene->unit.system;
+               }
+               opdata->num_input[i].unit_type[0] = B_UNIT_NONE;  /* Not sure this is a factor or a unit? */
+       }
 
        /* avoid the cost of allocating a bm copy */
        if (is_modal) {
@@ -142,7 +170,8 @@ static bool edbm_bevel_init(bContext *C, wmOperator *op, const bool is_modal)
                ARegion *ar = CTX_wm_region(C);
 
                opdata->mesh_backup = EDBM_redo_state_store(em);
-               opdata->draw_handle_pixel = ED_region_draw_cb_activate(ar->type, ED_region_draw_mouse_line_cb, opdata->mcenter, REGION_DRAW_POST_PIXEL);
+               opdata->draw_handle_pixel = ED_region_draw_cb_activate(ar->type, ED_region_draw_mouse_line_cb,
+                       opdata->mcenter, REGION_DRAW_POST_PIXEL);
                G.moving = G_TRANSFORM_EDIT;
 
                if (v3d) {
@@ -173,13 +202,15 @@ static bool edbm_bevel_calc(wmOperator *op)
                EDBM_redo_state_restore(opdata->mesh_backup, em, false);
        }
 
-       if (em->ob)
+       if (em->ob) {
                material = CLAMPIS(material, -1, em->ob->totcol - 1);
+       }
 
        EDBM_op_init(em, &bmop, op,
                     "bevel geom=%hev offset=%f segments=%i vertex_only=%b offset_type=%i profile=%f clamp_overlap=%b "
                     "material=%i loop_slide=%b",
-                    BM_ELEM_SELECT, offset, segments, vertex_only, offset_type, profile, clamp_overlap, material, loop_slide);
+                    BM_ELEM_SELECT, offset, segments, vertex_only, offset_type, profile,
+                    clamp_overlap, material, loop_slide);
 
        BMO_op_exec(em->bm, &bmop);
 
@@ -191,8 +222,9 @@ static bool edbm_bevel_calc(wmOperator *op)
        }
 
        /* no need to de-select existing geometry */
-       if (!EDBM_op_finish(em, &bmop, op, true))
+       if (!EDBM_op_finish(em, &bmop, op, true)) {
                return false;
+       }
 
        EDBM_mesh_normals_update(opdata->em);
 
@@ -256,12 +288,37 @@ static int edbm_bevel_exec(bContext *C, wmOperator *op)
        return OPERATOR_FINISHED;
 }
 
+static void edbm_bevel_calc_initial_length(wmOperator *op, const wmEvent *event, bool mode_changed)
+{
+       BevelData *opdata;
+       float mlen[2], len, value, sc, st;
+       int vmode;
+
+       opdata = op->customdata;
+       mlen[0] = opdata->mcenter[0] - event->mval[0];
+       mlen[1] = opdata->mcenter[1] - event->mval[1];
+       len = len_v2(mlen);
+       vmode = opdata->value_mode;
+       if (mode_changed) {
+               /* If current value is not default start value, adjust len so that 
+                * the scaling and offset in edbm_bevel_mouse_set_value will
+                * start at current value */
+               value = (vmode == SEGMENTS_VALUE) ?
+                       opdata->segments : RNA_float_get(op->ptr, value_rna_name[vmode]);
+               sc = opdata->scale[vmode];
+               st = value_start[vmode];
+               if (value != value_start[vmode]) {
+                       len = (st + sc * (len - MVAL_PIXEL_MARGIN) - value) / sc;
+               }
+       }
+       opdata->initial_length[opdata->value_mode] = len;
+}
+
 static int edbm_bevel_invoke(bContext *C, wmOperator *op, const wmEvent *event)
 {
        /* TODO make modal keymap (see fly mode) */
        RegionView3D *rv3d = CTX_wm_region_view3d(C);
        BevelData *opdata;
-       float mlen[2];
        float center_3d[3];
 
        if (!edbm_bevel_init(C, op, true)) {
@@ -276,10 +333,10 @@ static int edbm_bevel_invoke(bContext *C, wmOperator *op, const wmEvent *event)
                 * ideally this will never happen and should be checked for above */
                opdata->mcenter[0] = opdata->mcenter[1] = 0;
        }
-       mlen[0] = opdata->mcenter[0] - event->mval[0];
-       mlen[1] = opdata->mcenter[1] - event->mval[1];
-       opdata->initial_length = len_v2(mlen);
-       opdata->pixel_size = rv3d ? ED_view3d_pixel_size(rv3d, center_3d) : 1.0f;
+       edbm_bevel_calc_initial_length(op, event, false);
+
+       /* for OFFSET_VALUE only, the scale is the size of a pixel under the mouse in 3d space */
+       opdata->scale[OFFSET_VALUE] = rv3d ? ED_view3d_pixel_size(rv3d, center_3d) : 1.0f;
 
        edbm_bevel_update_header(C, op);
 
@@ -293,69 +350,72 @@ static int edbm_bevel_invoke(bContext *C, wmOperator *op, const wmEvent *event)
        return OPERATOR_RUNNING_MODAL;
 }
 
-static float edbm_bevel_mval_factor(wmOperator *op, const wmEvent *event)
+static void edbm_bevel_mouse_set_value(wmOperator *op, const wmEvent *event)
 {
        BevelData *opdata = op->customdata;
-       bool use_dist;
-       bool is_percent, is_profile;
+       int vmode = opdata->value_mode;
        float mdiff[2];
-       float factor;
+       float value;
 
        mdiff[0] = opdata->mcenter[0] - event->mval[0];
        mdiff[1] = opdata->mcenter[1] - event->mval[1];
-       is_percent = (RNA_enum_get(op->ptr, "offset_type") == BEVEL_AMT_PERCENT);
-       use_dist = !is_percent;
-       is_profile = opdata->mouse_controls_profile;
 
-       factor = ((len_v2(mdiff) - MVAL_PIXEL_MARGIN) - opdata->initial_length) * opdata->pixel_size;
+       value = ((len_v2(mdiff) - MVAL_PIXEL_MARGIN) - opdata->initial_length[vmode]);
+
+       /* Scale according to value mode */
+       value = value_start[vmode] + value * opdata->scale[vmode];
 
        /* Fake shift-transform... */
        if (event->shift) {
-               if (opdata->shift_factor < 0.0f) {
-                       if (is_profile)
-                               opdata->shift_factor = RNA_float_get(op->ptr, "profile");
-                       else {
-                               opdata->shift_factor = RNA_float_get(op->ptr, "offset");
-                               if (is_percent) {
-                                       opdata->shift_factor /= 100.0f;
-                               }
-                       }
+               if (opdata->shift_value[vmode] < 0.0f) {
+                       opdata->shift_value[vmode] = (vmode == SEGMENTS_VALUE) ?
+                               opdata->segments : RNA_float_get(op->ptr, value_rna_name[vmode]);
                }
-               factor = (factor - opdata->shift_factor) * 0.1f + opdata->shift_factor;
+               value = (value - opdata->shift_value[vmode]) * 0.1f + opdata->shift_value[vmode];
        }
-       else if (opdata->shift_factor >= 0.0f) {
-               opdata->shift_factor = -1.0f;
+       else if (opdata->shift_value[vmode] >= 0.0f) {
+               opdata->shift_value[vmode] = -1.0f;
        }
 
-       /* clamp differently based on distance/factor/profile */
-       if (is_profile) {
-               CLAMP(factor, PROFILE_HARD_MIN, 1.0f);
+       /* clamp accordingto value mode, and store value back */
+       CLAMP(value, value_clamp_min[vmode], value_clamp_max[vmode]);
+       if (vmode == SEGMENTS_VALUE) {
+               opdata->segments = value;
+               RNA_int_set(op->ptr, "segments", (int)(value + 0.5f));
        }
        else {
-               if (use_dist) {
-                       if (factor < 0.0f) factor = 0.0f;
-               }
-               else {
-                       CLAMP(factor, 0.0f, 1.0f);
-                       if (is_percent) {
-                               factor *= 100.0f;
-                       }
-               }
+               RNA_float_set(op->ptr, value_rna_name[vmode], value);
        }
+}
 
-       return factor;
+static void edbm_bevel_numinput_set_value(wmOperator *op)
+{
+       BevelData *opdata = op->customdata;
+       float value;
+       int vmode;
+
+       vmode = opdata->value_mode;
+       value = (vmode == SEGMENTS_VALUE) ?
+               opdata->segments : RNA_float_get(op->ptr, value_rna_name[vmode]);
+       applyNumInput(&opdata->num_input[vmode], &value);
+       CLAMP(value, value_clamp_min[vmode], value_clamp_max[vmode]);
+       if (vmode == SEGMENTS_VALUE) {
+               opdata->segments = value;
+               RNA_int_set(op->ptr, "segments", (int)value);
+       }
+       else {
+               RNA_float_set(op->ptr, value_rna_name[vmode], value);
+       }
 }
 
 static int edbm_bevel_modal(bContext *C, wmOperator *op, const wmEvent *event)
 {
        BevelData *opdata = op->customdata;
-       const bool has_numinput = hasNumInput(&opdata->num_input);
+       const bool has_numinput = hasNumInput(&opdata->num_input[opdata->value_mode]);
 
        /* Modal numinput active, try to handle numeric inputs first... */
-       if (event->val == KM_PRESS && has_numinput && handleNumInput(C, &opdata->num_input, event)) {
-               float value = RNA_float_get(op->ptr, "offset");
-               applyNumInput(&opdata->num_input, &value);
-               RNA_float_set(op->ptr, "offset", value);
+       if (event->val == KM_PRESS && has_numinput && handleNumInput(C, &opdata->num_input[opdata->value_mode], event)) {
+               edbm_bevel_numinput_set_value(op);
                edbm_bevel_calc(op);
                edbm_bevel_update_header(C, op);
                return OPERATOR_RUNNING_MODAL;
@@ -370,12 +430,7 @@ static int edbm_bevel_modal(bContext *C, wmOperator *op, const wmEvent *event)
 
                        case MOUSEMOVE:
                                if (!has_numinput) {
-                                       const float factor = edbm_bevel_mval_factor(op, event);
-                                       if (opdata->mouse_controls_profile)
-                                               RNA_float_set(op->ptr, "profile", factor);
-                                       else
-                                               RNA_float_set(op->ptr, "offset", factor);
-
+                                       edbm_bevel_mouse_set_value(op, event);
                                        edbm_bevel_calc(op);
                                        edbm_bevel_update_header(C, op);
                                        handled = true;
@@ -445,12 +500,18 @@ static int edbm_bevel_modal(bContext *C, wmOperator *op, const wmEvent *event)
                                        if (type > BEVEL_AMT_PERCENT) {
                                                type = BEVEL_AMT_OFFSET;
                                        }
+                                       if (opdata->value_mode == OFFSET_VALUE && type == BEVEL_AMT_PERCENT)
+                                               opdata->value_mode = OFFSET_VALUE_PERCENT;
+                                       else if (opdata->value_mode == OFFSET_VALUE_PERCENT && type != BEVEL_AMT_PERCENT)
+                                               opdata->value_mode = OFFSET_VALUE;
                                        RNA_property_enum_set(op->ptr, prop, type);
                                }
-                               /* Update factor accordingly to new offset_type. */
-                               if (!has_numinput) {
-                                       RNA_float_set(op->ptr, "offset", edbm_bevel_mval_factor(op, event));
-                               }
+                               /* Update offset accordingly to new offset_type. */
+                               if (!has_numinput &&
+                                   (opdata->value_mode == OFFSET_VALUE || opdata->value_mode == OFFSET_VALUE_PERCENT))
+                               {
+                                       edbm_bevel_mouse_set_value(op, event);
+                               }               
                                edbm_bevel_calc(op);
                                edbm_bevel_update_header(C, op);
                                handled = true;
@@ -470,7 +531,24 @@ static int edbm_bevel_modal(bContext *C, wmOperator *op, const wmEvent *event)
                        case PKEY:
                                if (event->val == KM_RELEASE)
                                        break;
-                               opdata->mouse_controls_profile = !opdata->mouse_controls_profile;
+                               if (opdata->value_mode == PROFILE_VALUE) {
+                                       opdata->value_mode = OFFSET_VALUE;
+                               }
+                               else {
+                                       opdata->value_mode = PROFILE_VALUE;
+                               }
+                               edbm_bevel_calc_initial_length(op, event, true);
+                               break;
+                       case SKEY:
+                               if (event->val == KM_RELEASE)
+                                       break;
+                               if (opdata->value_mode == SEGMENTS_VALUE) {
+                                       opdata->value_mode = OFFSET_VALUE;
+                               }
+                               else {
+                                       opdata->value_mode = SEGMENTS_VALUE;
+                               }
+                               edbm_bevel_calc_initial_length(op, event, true);
                                break;
                        case VKEY:
                                if (event->val == KM_RELEASE)
@@ -488,10 +566,8 @@ static int edbm_bevel_modal(bContext *C, wmOperator *op, const wmEvent *event)
                }
 
                /* Modal numinput inactive, try to handle numeric inputs last... */
-               if (!handled && event->val == KM_PRESS && handleNumInput(C, &opdata->num_input, event)) {
-                       float value = RNA_float_get(op->ptr, "offset");
-                       applyNumInput(&opdata->num_input, &value);
-                       RNA_float_set(op->ptr, "offset", value);
+               if (!handled && event->val == KM_PRESS && handleNumInput(C, &opdata->num_input[opdata->value_mode], event)) {
+                       edbm_bevel_numinput_set_value(op);
                        edbm_bevel_calc(op);
                        edbm_bevel_update_header(C, op);
                        return OPERATOR_RUNNING_MODAL;
@@ -542,12 +618,13 @@ void MESH_OT_bevel(wmOperatorType *ot)
        RNA_def_enum(ot->srna, "offset_type", offset_type_items, 0, "Amount Type", "What distance Amount measures");
        prop = RNA_def_float(ot->srna, "offset", 0.0f, -1e6f, 1e6f, "Amount", "", 0.0f, 1.0f);
        RNA_def_property_float_array_funcs_runtime(prop, NULL, NULL, mesh_ot_bevel_offset_range_func);
-       RNA_def_int(ot->srna, "segments", 1, 1, 50, "Segments", "Segments for curved edge", 1, 8);
+       RNA_def_int(ot->srna, "segments", 1, 1, SEGMENTS_HARD_MAX, "Segments", "Segments for curved edge", 1, 8);
        RNA_def_float(ot->srna, "profile", 0.5f, PROFILE_HARD_MIN, 1.0f, "Profile",
-                       "Controls profile shape (0.5 = round)", PROFILE_HARD_MIN, 1.0f);
+               "Controls profile shape (0.5 = round)", PROFILE_HARD_MIN, 1.0f);
        RNA_def_boolean(ot->srna, "vertex_only", false, "Vertex Only", "Bevel only vertices");
        RNA_def_boolean(ot->srna, "clamp_overlap", false, "Clamp Overlap",
-                       "Do not allow beveled edges/vertices to overlap each other");
+               "Do not allow beveled edges/vertices to overlap each other");
        RNA_def_boolean(ot->srna, "loop_slide", true, "Loop Slide", "Prefer slide along edge to even widths");
-       RNA_def_int(ot->srna, "material", -1, -1, INT_MAX, "Material", "Material for bevel faces (-1 means use adjacent faces)", -1, 100);
+       RNA_def_int(ot->srna, "material", -1, -1, INT_MAX, "Material",
+               "Material for bevel faces (-1 means use adjacent faces)", -1, 100);
 }
index 20e159f4f51855b72a7a4e6329cbe4dc9f64e62d..943490bbc3a39b7ac3067f8ebfd36b328dc5f0b3 100644 (file)
@@ -4144,7 +4144,12 @@ static void initSnapSpatial(TransInfo *t, float r_snap[3])
                        r_snap[2] = r_snap[1] * 0.1f;
                }
        }
-       else if (ELEM(t->spacetype, SPACE_IMAGE, SPACE_CLIP)) {
+       else if (t->spacetype == SPACE_IMAGE) {
+               r_snap[0] = 0.0f;
+               r_snap[1] = 0.0625f;
+               r_snap[2] = 0.03125f;
+       }
+       else if (t->spacetype == SPACE_CLIP) {
                r_snap[0] = 0.0f;
                r_snap[1] = 0.125f;
                r_snap[2] = 0.0625f;
index 5ec0a87890c5184326f14cb1df5eef3e9a9adc37..6fb1bccf491641b8d1e5f9ea14c9eba2680895b8 100644 (file)
@@ -296,10 +296,11 @@ static int logImageSetData10(LogImageFile *logImage, LogImageElement logElement,
                        row[index] = swap_uint(pixel, logImage->isMSB);
 
                if (logimage_fwrite(row, rowLength, 1, logImage) == 0) {
-                       if (verbose) printf("DPX/Cineon: Error while writing file.\n"); {
-                               MEM_freeN(row);
-                               return 1;
+                       if (verbose) {
+                               printf("DPX/Cineon: Error while writing file.\n");
                        }
+                       MEM_freeN(row);
+                       return 1;
                }
        }
        MEM_freeN(row);
index 06823a26c7745c80158ee3a9699229977da5c570..1f34d8f23d4c8637e7f83f662c0ce2828e585c7d 100644 (file)
@@ -898,7 +898,7 @@ static void rna_def_pose_channel(BlenderRNA *brna)
        prop = RNA_def_property(srna, "use_bbone_relative_start_handle", PROP_BOOLEAN, PROP_NONE);
        RNA_def_property_boolean_sdna(prop, NULL, "bboneflag", PCHAN_BBONE_CUSTOM_START_REL);
        RNA_def_property_ui_text(prop, "Relative B-Bone Start Handle", 
-                                "Use treat custom start handle position as a relative value");
+                                "Treat custom start handle position as a relative value");
        RNA_def_property_editable_func(prop, "rna_PoseChannel_proxy_editable");
        RNA_def_property_update(prop, NC_OBJECT | ND_POSE, "rna_Pose_update");
        
@@ -914,7 +914,7 @@ static void rna_def_pose_channel(BlenderRNA *brna)
        prop = RNA_def_property(srna, "use_bbone_relative_end_handle", PROP_BOOLEAN, PROP_NONE);
        RNA_def_property_boolean_sdna(prop, NULL, "bboneflag", PCHAN_BBONE_CUSTOM_END_REL);
        RNA_def_property_ui_text(prop, "Relative B-Bone End Handle", 
-                                "Use treat custom end handle position as a relative value");
+                                "Treat custom end handle position as a relative value");
        RNA_def_property_editable_func(prop, "rna_PoseChannel_proxy_editable");
        RNA_def_property_update(prop, NC_OBJECT | ND_POSE, "rna_Pose_update");
        
index 29b1e5bc5c7de6bb510526b7c34ef9c4493d8411..afccef4617445e79ba5b51a7792bf486e9bf3d7f 100644 (file)
@@ -199,6 +199,12 @@ void register_node_tree_type_sh(void)
 
 /* GPU material from shader nodes */
 
+static void ntree_shader_link_builtin_normal(bNodeTree *ntree,
+                                             bNode *node_from,
+                                             bNodeSocket *socket_from,
+                                             bNode *displacement_node,
+                                             bNodeSocket *displacement_socket);
+
 /* Find an output node of the shader tree.
  *
  * NOTE: it will only return output which is NOT in the group, which isn't how
@@ -277,32 +283,138 @@ static bool ntree_shader_has_displacement(bNodeTree *ntree,
        return displacement->link != NULL;
 }
 
+static bool ntree_shader_relink_node_normal(bNodeTree *ntree,
+                                            bNode *node,
+                                            bNode *node_from,
+                                            bNodeSocket *socket_from)
+{
+       bNodeSocket *sock = ntree_shader_node_find_input(node, "Normal");
+       /* TODO(sergey): Can we do something smarter here than just a name-based
+        * matching?
+        */
+       if (sock == NULL) {
+               /* There's no Normal input, nothing to link. */
+               return false;
+       }
+       if (sock->link != NULL) {
+               /* Something is linked to the normal input already. can't
+                * use other input for that.
+                */
+               return false;
+       }
+       /* Create connection between specified node and the normal input. */
+       nodeAddLink(ntree, node_from, socket_from, node, sock);
+       return true;
+}
+
+static void ntree_shader_link_builtin_group_normal(
+        bNodeTree *ntree,
+        bNode *group_node,
+        bNode *node_from,
+        bNodeSocket *socket_from,
+        bNode *displacement_node,
+        bNodeSocket *displacement_socket)
+{
+       bNodeTree *group_ntree = (bNodeTree *)group_node->id;
+       /* Create input socket to plug displacement connection to. */
+       bNodeSocket *group_normal_socket =
+               ntreeAddSocketInterface(group_ntree,
+                                       SOCK_IN,
+                                       "NodeSocketVector",
+                                       "Normal");
+       /* Need to update tree so all node instances nodes gets proper sockets. */
+       ntreeUpdateTree(G.main, group_ntree);
+       /* Assumes sockets are always added at the end. */
+       bNodeSocket *group_node_normal_socket = (bNodeSocket*)group_node->inputs.last;
+       if (displacement_node == group_node) {
+               /* If displacement is coming from this node group we need to perform
+                * some internal re-linking in order to avoid cycles.
+                */
+               bNode *group_output_node = ntreeFindType(group_ntree, NODE_GROUP_OUTPUT);
+               BLI_assert(group_output_node != NULL);
+               bNodeSocket *group_output_node_displacement_socket =
+                       nodeFindSocket(group_output_node,
+                                      SOCK_IN,
+                                      displacement_socket->identifier);
+               bNodeLink *group_displacement_link = group_output_node_displacement_socket->link;
+               if (group_displacement_link == NULL) {
+                       /* Displacement output is not connected to anything, can just stop
+                        * right away.
+                        */
+                       return;
+               }
+               /* This code is similar to ntree_shader_relink_displacement() */
+               bNode *group_displacement_node = group_displacement_link->fromnode;
+               bNodeSocket *group_displacement_socket = group_displacement_link->fromsock;
+               nodeRemLink(group_ntree, group_displacement_link);
+               /* Create and link bump node.
+                * Can't re-use bump node from parent tree because it'll cause cycle.
+                */
+               bNode *bump_node = nodeAddStaticNode(NULL, group_ntree, SH_NODE_BUMP);
+               bNodeSocket *bump_input_socket = ntree_shader_node_find_input(bump_node, "Height");
+               bNodeSocket *bump_output_socket = ntree_shader_node_find_output(bump_node, "Normal");
+               BLI_assert(bump_input_socket != NULL);
+               BLI_assert(bump_output_socket != NULL);
+               nodeAddLink(group_ntree,
+                           group_displacement_node, group_displacement_socket,
+                           bump_node, bump_input_socket);
+               /* Relink normals inside of the instanced tree. */
+               ntree_shader_link_builtin_normal(group_ntree,
+                                                bump_node,
+                                                bump_output_socket,
+                                                group_displacement_node,
+                                                group_displacement_socket);
+               ntreeUpdateTree(G.main, group_ntree);
+       }
+       else {
+               /* Connect group node normal input. */
+               nodeAddLink(ntree,
+                           node_from, socket_from,
+                           group_node, group_node_normal_socket);
+               bNode *group_input_node = ntreeFindType(group_ntree, NODE_GROUP_INPUT);
+               BLI_assert(group_input_node != NULL);
+               bNodeSocket *group_input_node_normal_socket =
+                       nodeFindSocket(group_input_node,
+                                      SOCK_OUT,
+                                      group_normal_socket->identifier);
+               BLI_assert(group_input_node_normal_socket != NULL);
+               /* Relink normals inside of the instanced tree. */
+               ntree_shader_link_builtin_normal(group_ntree,
+                                                group_input_node,
+                                                group_input_node_normal_socket,
+                                                displacement_node,
+                                                displacement_socket);
+               ntreeUpdateTree(G.main, group_ntree);
+       }
+}
+
 /* Use specified node and socket as an input for unconnected normal sockets. */
 static void ntree_shader_link_builtin_normal(bNodeTree *ntree,
                                              bNode *node_from,
-                                             bNodeSocket *socket_from)
+                                             bNodeSocket *socket_from,
+                                             bNode *displacement_node,
+                                             bNodeSocket *displacement_socket)
 {
        for (bNode *node = ntree->nodes.first; node != NULL; node = node->next) {
                if (node == node_from) {
                        /* Don't connect node itself! */
                        continue;
                }
-               bNodeSocket *sock = ntree_shader_node_find_input(node, "Normal");
-               /* TODO(sergey): Can we do something smarter here than just a name-based
-                * matching?
-                */
-               if (sock == NULL) {
-                       /* There's no Normal input, nothing to link. */
+               if (node->type == NODE_GROUP && node->id) {
+                       /* Special re-linking for group nodes. */
+                       ntree_shader_link_builtin_group_normal(ntree,
+                                                              node,
+                                                              node_from,
+                                                              socket_from,
+                                                              displacement_node,
+                                                              displacement_socket);
                        continue;
                }
-               if (sock->link != NULL) {
-                       /* Something is linked to the normal input already. can't
-                        * use other input for that.
-                        */
+               if (ELEM(node->type, NODE_GROUP_INPUT, NODE_GROUP_OUTPUT)) {
+                       /* Group inputs and outputs needs nothing special. */
                        continue;
                }
-               /* Create connection between specified node and the normal input. */
-               nodeAddLink(ntree, node_from, socket_from, node, sock);
+               ntree_shader_relink_node_normal(ntree, node, node_from, socket_from);
        }
 }
 
@@ -346,7 +458,11 @@ static void ntree_shader_relink_displacement(bNodeTree *ntree,
                    displacement_node, displacement_socket,
                    bump_node, bump_input_socket);
        /* Connect all free-standing Normal inputs. */
-       ntree_shader_link_builtin_normal(ntree, bump_node, bump_output_socket);
+       ntree_shader_link_builtin_normal(ntree,
+                                        bump_node,
+                                        bump_output_socket,
+                                        displacement_node,
+                                        displacement_socket);
        /* TODO(sergey): Reconnect Geometry Info->Normal sockets to the new
         * bump node.
         */