Merging r57816 through r57896 from trunk into soc-2013-depsgraph_mt
authorSergey Sharybin <sergey.vfx@gmail.com>
Mon, 1 Jul 2013 09:07:21 +0000 (09:07 +0000)
committerSergey Sharybin <sergey.vfx@gmail.com>
Mon, 1 Jul 2013 09:07:21 +0000 (09:07 +0000)
1  2 
release/datafiles/startup.blend
source/blender/blenkernel/BKE_mball.h
source/blender/blenkernel/intern/DerivedMesh.c
source/blender/blenkernel/intern/depsgraph.c
source/blender/blenkernel/intern/mball.c
source/blender/blenloader/intern/readfile.c
source/blender/editors/space_image/image_ops.c
source/blender/windowmanager/intern/wm_event_system.c
source/blender/windowmanager/intern/wm_operators.c

index 805308cf6629f2517aa45ab14d2676d204bc4a0d,c604d16829ce6a5106e895002102e33bd2a83707..8b58493fe3a4a1b8e404ee214d1610104aabbab8
Binary files differ
index 9a9b8a4da4db523ad6c42a190fda51eb32bad107,44459300c5640b8d7f6574e373b3b0e4ed97636e..7665e1b54dc6df497daf6cb9ff84889f9f329a38
@@@ -47,7 -47,7 +47,7 @@@ void BKE_mball_make_local(struct MetaBa
  
  void BKE_mball_cubeTable_free(void);
  
 -void BKE_mball_polygonize(struct Scene *scene, struct Object *ob, struct ListBase *dispbase);
 +void BKE_mball_polygonize(struct Scene *scene, struct Object *ob, struct ListBase *dispbase, bool for_render);
  bool BKE_mball_is_basis_for(struct Object *ob1, struct Object *ob2);
  bool BKE_mball_is_basis(struct Object *ob);
  struct Object *BKE_mball_basis_find(struct Scene *scene, struct Object *ob);
@@@ -57,9 -57,11 +57,11 @@@ float *BKE_mball_make_orco(struct Objec
  
  void BKE_mball_properties_copy(struct Scene *scene, struct Object *active_object);
  
- int BKE_mball_minmax(struct MetaBall *mb, float min[3], float max[3]);
- int BKE_mball_center_median(struct MetaBall *mb, float r_cent[3]);
- int BKE_mball_center_bounds(struct MetaBall *mb, float r_cent[3]);
+ bool BKE_mball_minmax(struct MetaBall *mb, float min[3], float max[3]);
+ bool BKE_mball_minmax_ex(struct MetaBall *mb, float min[3], float max[3],
+                          float obmat[4][4], const short flag);
+ bool BKE_mball_center_median(struct MetaBall *mb, float r_cent[3]);
+ bool BKE_mball_center_bounds(struct MetaBall *mb, float r_cent[3]);
  void BKE_mball_translate(struct MetaBall *mb, const float offset[3]);
  
  struct MetaElem *BKE_mball_element_add(struct MetaBall *mb, const int type);
index d1bf42183c10edb62a83df02cf77d7fa4ce969d0,6f86b0c3f887c66e11fc5c599a329d7b4be701bd..b2ba1755303b4d216e2b867934fa5f4b86aba2cd
@@@ -49,7 -49,6 +49,7 @@@
  #include "BLI_array.h"
  #include "BLI_utildefines.h"
  #include "BLI_linklist.h"
 +#include "BLI_threads.h"
  
  #include "BKE_pbvh.h"
  #include "BKE_cdderivedmesh.h"
@@@ -1947,9 -1946,9 +1947,9 @@@ static void editbmesh_calc_modifiers(Sc
                                       DerivedMesh **final_r,
                                       CustomDataMask dataMask)
  {
-       ModifierData *md;
+       ModifierData *md, *previewmd = NULL;
        float (*deformedVerts)[3] = NULL;
-       CustomDataMask mask;
+       CustomDataMask mask, previewmask = 0;
        DerivedMesh *dm, *orcodm = NULL;
        int i, numVerts = 0, cageIndex = modifiers_getCageIndex(scene, ob, NULL, 1);
        CDMaskLink *datamasks, *curr;
        const int do_final_wmcol = FALSE;
        int do_init_wmcol = ((((Mesh *)ob->data)->drawflag & ME_DRAWEIGHT) && !do_final_wmcol);
        int do_init_statvis = ((((Mesh *)ob->data)->drawflag & ME_DRAW_STATVIS) && !do_init_wmcol);
+       const int do_mod_wmcol = do_init_wmcol;
  
        modifiers_clearErrors(ob);
  
        dm = NULL;
        md = modifiers_getVirtualModifierList(ob);
  
-       datamasks = modifiers_calcDataMasks(scene, ob, md, dataMask, required_mode, NULL, 0);
+       /* copied from mesh_calc_modifiers */
+       if (do_mod_wmcol) {
+               previewmd = modifiers_getLastPreview(scene, md, required_mode);
+               /* even if the modifier doesn't need the data, to make a preview it may */
+               if (previewmd) {
+                       if (do_mod_wmcol) {
+                               previewmask = CD_MASK_MDEFORMVERT;
+                       }
+               }
+       }
+       datamasks = modifiers_calcDataMasks(scene, ob, md, dataMask, required_mode, previewmd, previewmask);
  
        curr = datamasks;
        for (i = 0; md; i++, md = md->next, curr = curr->next) {
index c2912a39b6585f26c2a2ce401d1b3e62cb336e3a,2206770dfbd7b064bf54aac0d46f211c9f62e398..d10d6b23ba4a0eb45bef01b3b8650f7258cc5e80
@@@ -1455,9 -1455,8 +1455,8 @@@ static void lib_id_recalc_data_tag(Mai
  }
  
  /* node was checked to have lasttime != curtime and is if type ID_OB */
- static void flush_update_node(DagNode *node, unsigned int layer, int curtime)
+ static void flush_update_node(Main *bmain, DagNode *node, unsigned int layer, int curtime)
  {
-       Main *bmain = G.main;
        DagAdjList *itA;
        Object *ob, *obc;
        int oldflag, changed = 0;
        /* we only go deeper if node not checked or something changed  */
        for (itA = node->child; itA; itA = itA->next) {
                if (changed || itA->node->lasttime != curtime)
-                       flush_update_node(itA->node, layer, curtime);
+                       flush_update_node(bmain, itA->node, layer, curtime);
        }
        
  }
@@@ -1571,9 -1570,8 +1570,8 @@@ static unsigned int flush_layer_node(Sc
  }
  
  /* node was checked to have lasttime != curtime, and is of type ID_OB */
- static void flush_pointcache_reset(Scene *scene, DagNode *node, int curtime, int reset)
+ static void flush_pointcache_reset(Main *bmain, Scene *scene, DagNode *node, int curtime, int reset)
  {
-       Main *bmain = G.main;
        DagAdjList *itA;
        Object *ob;
        
                                                lib_id_recalc_data_tag(bmain, &ob->id);
                                        }
  
-                                       flush_pointcache_reset(scene, itA->node, curtime, 1);
+                                       flush_pointcache_reset(bmain, scene, itA->node, curtime, 1);
                                }
                                else
-                                       flush_pointcache_reset(scene, itA->node, curtime, 0);
+                                       flush_pointcache_reset(bmain, scene, itA->node, curtime, 0);
                        }
                }
        }
@@@ -1694,7 -1692,7 +1692,7 @@@ void DAG_scene_flush_update(Main *bmain
        lasttime = sce->theDag->time;
        for (itA = firstnode->child; itA; itA = itA->next)
                if (itA->node->lasttime != lasttime && itA->node->type == ID_OB)
-                       flush_update_node(itA->node, lay, lasttime);
+                       flush_update_node(bmain, itA->node, lay, lasttime);
  
        /* if update is not due to time change, do pointcache clears */
        if (!time) {
                                                lib_id_recalc_data_tag(bmain, &ob->id);
                                        }
  
-                                       flush_pointcache_reset(sce, itA->node, lasttime, 1);
+                                       flush_pointcache_reset(bmain, sce, itA->node, lasttime, 1);
                                }
                                else
-                                       flush_pointcache_reset(sce, itA->node, lasttime, 0);
+                                       flush_pointcache_reset(bmain, sce, itA->node, lasttime, 0);
                        }
                }
        }
@@@ -1797,7 -1795,7 +1795,7 @@@ static short animdata_use_time(AnimDat
        return 0;
  }
  
- static void dag_object_time_update_flags(Scene *scene, Object *ob)
+ static void dag_object_time_update_flags(Main *bmain, Scene *scene, Object *ob)
  {
        if (ob->constraints.first) {
                bConstraint *con;
        }
  
        if (ob->recalc & OB_RECALC_OB)
-               lib_id_recalc_tag(G.main, &ob->id);
+               lib_id_recalc_tag(bmain, &ob->id);
        if (ob->recalc & OB_RECALC_DATA)
-               lib_id_recalc_data_tag(G.main, &ob->id);
+               lib_id_recalc_data_tag(bmain, &ob->id);
  
  }
  /* flag all objects that need recalc, for changes in time for example */
@@@ -1949,7 -1947,7 +1947,7 @@@ void DAG_scene_update_flags(Main *bmain
                        /* NOTE: "sce_iter" not "scene" so that rigidbodies in background scenes work 
                         * (i.e. muting + rbw availability can be checked and tagged properly) [#33970] 
                         */
-                       dag_object_time_update_flags(sce_iter, ob);
+                       dag_object_time_update_flags(bmain, sce_iter, ob);
                }
  
                /* handled in next loop */
                for (group = bmain->group.first; group; group = group->id.next) {
                        if (group->id.flag & LIB_DOIT) {
                                for (go = group->gobject.first; go; go = go->next) {
-                                       dag_object_time_update_flags(scene, go->ob);
+                                       dag_object_time_update_flags(bmain, scene, go->ob);
                                }
                        }
                }
  
                /* hrmf... an exception to look at once, for invisible camera object we do it over */
                if (scene->camera)
-                       dag_object_time_update_flags(scene, scene->camera);
+                       dag_object_time_update_flags(bmain, scene, scene->camera);
        }
  
        /* and store the info in groupobject */
@@@ -2129,9 -2127,8 +2127,8 @@@ static void dag_id_flush_update__isDepe
        }
  }
  
- static void dag_id_flush_update(Scene *sce, ID *id)
+ static void dag_id_flush_update(Main *bmain, Scene *sce, ID *id)
  {
-       Main *bmain = G.main;
        Object *obt, *ob = NULL;
        short idtype;
  
                        MovieClip *clip = BKE_object_movieclip_get(sce, sce->camera, 1);
  
                        if (clip)
-                               dag_id_flush_update(sce, &clip->id);
+                               dag_id_flush_update(bmain, sce, &clip->id);
                }
  
                /* update editors */
@@@ -2314,7 -2311,7 +2311,7 @@@ void DAG_ids_flush_tagged(Main *bmain
                                if (id->flag & (LIB_ID_RECALC | LIB_ID_RECALC_DATA)) {
                                        
                                        for (dsl = listbase.first; dsl; dsl = dsl->next)
-                                               dag_id_flush_update(dsl->scene, id);
+                                               dag_id_flush_update(bmain, dsl->scene, id);
                                        
                                        do_flush = TRUE;
                                }
@@@ -2655,172 -2652,6 +2652,172 @@@ void DAG_pose_sort(Object *ob
        ugly_hack_sorry = 1;
  }
  
 +/* ******************* DAG FOR THREADED UPDATR ***************** */
 +
 +void DAG_get_independent_groups(Scene *scene, ListBase *groups)
 +{
 +#if defined __GNUC__ || defined __sun
 +#  define PRINT(format, args ...) { if (dag_print_dependencies) printf(format, ##args); } (void)0
 +#else
 +#  define PRINT(format, ...) { if (dag_print_dependencies) printf(__VA_ARGS__); } (void)0
 +#endif
 +
 +      DagNode *node, *rootnode;
 +      DagNodeQueue *node_queue;
 +      DagAdjList *itA;
 +      bool skip = false;
 +      Base *base;
 +      ListBase *current_group = NULL;
 +      bool has_group = false;
 +      int root_count = 0;
 +
 +      PRINT("Independend groups of objects:\n");
 +      PRINT("\nACHTUNG!!! Order of objects in groups is reversed in outout!\n");
 +      PRINT("Don't ask why, just be aware of this.\n\n");
 +
 +      /* ** STEP 0: Some pre-initialization. ** */
 +
 +      rootnode = scene->theDag->DagNode.first;
 +
 +      node_queue = queue_create(DAGQUEUEALLOC);
 +
 +      /* Mark all objects as unhandled.
 +       * This flag is checked later to detect cycle dependencies.
 +       */
 +      for (base = scene->base.first; base; base = base->next) {
 +              base->object->id.flag |= LIB_DOIT;
 +      }
 +
 +      /* ** STEP 1: Find all nodes which doesn't depend on other nodes ** */
 +
 +      /* Mark all nodes as not visited. */
 +      for (node = scene->theDag->DagNode.first; node; node = node->next) {
 +              node->color = DAG_WHITE;
 +      }
 +
 +      /* Detect all the nodes which doesn't have parent. */
 +      for (node = scene->theDag->DagNode.first; node; node = node->next) {
 +              DagAdjList *itA;
 +
 +              if (node == rootnode) {
 +                      continue;
 +              }
 +
 +              for (itA = node->child; itA; itA = itA->next) {
 +                      if (itA->node != node) {
 +                              itA->node->color = DAG_BLACK;
 +                      }
 +              }
 +      }
 +
 +      /* Always put root to a traverse queue. */
 +      rootnode->color = DAG_GRAY;
 +      push_stack(node_queue, rootnode);
 +
 +      /* Put all nodes which that depend on other nodes to a traverse queue.
 +       * Also mark this nodes as gray (since they're visited but not finished)
 +       * and mark all other nodes as white (they're not viisted).
 +       */
 +      for (node = scene->theDag->DagNode.first; node; node = node->next) {
 +              if (node == rootnode) {
 +                      continue;
 +              }
 +
 +              if (node->color == DAG_WHITE) {
 +                      PRINT("Root node: %s\n", dag_node_name(node));
 +
 +                      node->color = DAG_GRAY;
 +                      push_stack(node_queue, node);
 +              }
 +              else {
 +                      node->color = DAG_WHITE;
 +              }
 +      }
 +
 +      root_count = node_queue->count;
 +
 +      /* ** STEP 2: Traverse the graph and collect all the groups. ** */
 +
 +      while (node_queue->count) {
 +              skip = false;
 +              node = get_top_node_queue(node_queue);
 +
 +              itA = node->child;
 +              while (itA != NULL) {
 +                      if (itA->node->color == DAG_WHITE) {
 +                              itA->node->color = DAG_GRAY;
 +                              push_stack(node_queue, itA->node);
 +                              skip = true;
 +                              break;
 +                      }
 +                      itA = itA->next;
 +              }
 +
 +              if (!skip) {
 +                      if (node) {
 +                              node = pop_queue(node_queue);
 +                              if (node->ob == scene) {
 +                                      /* Whatever Thom, we are done! */
 +                                      break;
 +                              }
 +
 +                              node->color = DAG_BLACK;
 +
 +                              base = scene->base.first;
 +                              while (base && base->object != node->ob) {
 +                                      base = base->next;
 +                              }
 +
 +                              if (base) {
 +                                      base->object->id.flag &= ~LIB_DOIT;
 +
 +                                      if (has_group == false) {
 +                                              PRINT("- Next group\n");
 +
 +                                              if (groups) {
 +                                                      current_group = MEM_callocN(sizeof(ListBase), "DAG independent group");
 +                                                      BLI_addhead(groups, BLI_genericNodeN(current_group));
 +                                              }
 +
 +                                              has_group = true;
 +                                      }
 +
 +                                      PRINT("  %s\n", dag_node_name(node));
 +
 +                                      if (groups) {
 +                                              BLI_addhead(current_group, BLI_genericNodeN(base));
 +                                      }
 +                              }
 +
 +                              if (node_queue->count < root_count) {
 +                                      root_count--;
 +                                      has_group = false;
 +                              }
 +                      }
 +              }
 +      }
 +
 +      /* Here we put all cyclic objects to separate groups */
 +      for (base = scene->base.first; base; base = base->next) {
 +              if (base->object->id.flag & LIB_DOIT) {
 +                      base->object->id.flag &= ~LIB_DOIT;
 +
 +                      PRINT("- Next cyclic group\n");
 +                      PRINT("  %s\n", base->object->id.name + 2);
 +
 +                      if (groups) {
 +                              current_group = MEM_callocN(sizeof(ListBase), "DAG independent group");
 +                              BLI_addtail(groups, BLI_genericNodeN(current_group));
 +                              BLI_addtail(current_group, BLI_genericNodeN(base));
 +                      }
 +              }
 +      }
 +
 +      queue_delete(node_queue);
 +
 +#undef PRINT
 +}
 +
  /* ************************ DAG DEBUGGING ********************* */
  
  void DAG_print_dependencies(Main *bmain, Scene *scene, Object *ob)
        dag_print_dependencies = 0;
  }
  
 +void DAG_print_dependency_groups(Scene *scene)
 +{
 +      dag_print_dependencies = 1;
 +
 +      DAG_get_independent_groups(scene, NULL);
 +
 +      dag_print_dependencies = 0;
 +}
index afe1c0f24df952828e5d9fcff41a61dc44fc6842,31212c3a6b79b7fb71c0724444fdcd87db918da7..f84a6088ee53e875f8a4568931fbc3547dcdf7b7
@@@ -2269,7 -2269,7 +2269,7 @@@ static void mball_count(PROCESS *proces
        }
  }
  
 -void BKE_mball_polygonize(Scene *scene, Object *ob, ListBase *dispbase)
 +void BKE_mball_polygonize(Scene *scene, Object *ob, ListBase *dispbase, bool for_render)
  {
        MetaBall *mb;
        DispList *dl;
        mball_count(&process, scene, ob);
  
        if (process.totelem == 0) return;
 -      if ((G.is_rendering == FALSE) && (mb->flag == MB_UPDATE_NEVER)) return;
 +      if ((for_render == FALSE) && (mb->flag == MB_UPDATE_NEVER)) return;
        if ((G.moving & (G_TRANSFORM_OBJ | G_TRANSFORM_EDIT)) && mb->flag == MB_UPDATE_FAST) return;
  
        process.thresh = mb->thresh;
        }
  
        /* width is size per polygonize cube */
 -      if (G.is_rendering) {
 +      if (for_render) {
                width = mb->rendersize;
        }
        else {
        freepolygonize(&process);
  }
  
+ bool BKE_mball_minmax_ex(MetaBall *mb, float min[3], float max[3],
+                          float obmat[4][4], const short flag)
+ {
+       const float scale = obmat ? mat4_to_scale(obmat) : 1.0f;
+       MetaElem *ml;
+       bool change = false;
+       float centroid[3], vec[3];
+       INIT_MINMAX(min, max);
+       for (ml = mb->elems.first; ml; ml = ml->next) {
+               if ((ml->flag & flag) == flag) {
+                       const float scale_mb = (ml->rad * 0.5f) * scale;
+                       int i;
+                       if (obmat) {
+                               mul_v3_m4v3(centroid, obmat, &ml->x);
+                       }
+                       else {
+                               copy_v3_v3(centroid, &ml->x);
+                       }
+                       /* TODO, non circle shapes cubes etc, probably nobody notices - campbell */
+                       for (i = -1; i != 3; i += 2) {
+                               copy_v3_v3(vec, centroid);
+                               add_v3_fl(vec, scale_mb * i);
+                               minmax_v3v3_v3(min, max, vec);
+                       }
+                       change = true;
+               }
+       }
+       return change;
+ }
  /* basic vertex data functions */
int BKE_mball_minmax(MetaBall *mb, float min[3], float max[3])
bool BKE_mball_minmax(MetaBall *mb, float min[3], float max[3])
  {
        MetaElem *ml;
  
        return (mb->elems.first != NULL);
  }
  
int BKE_mball_center_median(MetaBall *mb, float r_cent[3])
bool BKE_mball_center_median(MetaBall *mb, float r_cent[3])
  {
        MetaElem *ml;
        int total = 0;
        return (total != 0);
  }
  
int BKE_mball_center_bounds(MetaBall *mb, float r_cent[3])
bool BKE_mball_center_bounds(MetaBall *mb, float r_cent[3])
  {
        float min[3], max[3];
  
index 917b1e5d054eff0749418c863421ad1f99978f5f,5d30bf6ff738cfa315e7cee25ef897d6e465df15..9fa352a581768cea38de2209901c430afc5fd9f8
@@@ -4148,6 -4148,11 +4148,11 @@@ static void direct_link_mesh(FileData *
        mesh->bb = NULL;
        mesh->edit_btmesh = NULL;
        
+       /* happens with old files */
+       if (mesh->mselect == NULL) {
+               mesh->totselect = 0;
+       }
        /* Multires data */
        mesh->mr= newdataadr(fd, mesh->mr);
        if (mesh->mr) {
@@@ -5514,7 -5519,6 +5519,7 @@@ static void direct_link_windowmanager(F
        wm->winactive = NULL;
        wm->initialized = 0;
        wm->op_undo_depth = 0;
 +      wm->is_interface_locked = 0;
  }
  
  static void lib_link_windowmanager(FileData *fd, Main *main)
index 17a5dda09b09ef3b6d8315bfd9cff2350fd3d83b,20bbfbbf343b8b01d8de23a51121cb6dce71c91c..a845f8e525c33fa57ff9b992563786506c7427f7
@@@ -360,7 -360,7 +360,7 @@@ void IMAGE_OT_view_pan(wmOperatorType *
        ot->poll = space_image_main_area_poll;
  
        /* flags */
 -      ot->flag = OPTYPE_BLOCKING | OPTYPE_GRAB_POINTER;
 +      ot->flag = OPTYPE_BLOCKING | OPTYPE_GRAB_POINTER | OPTYPE_ALLOW_LOCKED;
        
        /* properties */
        RNA_def_float_vector(ot->srna, "offset", 2, NULL, -FLT_MAX, FLT_MAX,
@@@ -575,7 -575,7 +575,7 @@@ void IMAGE_OT_view_zoom(wmOperatorType 
        ot->poll = space_image_main_area_poll;
  
        /* flags */
 -      ot->flag = OPTYPE_BLOCKING;
 +      ot->flag = OPTYPE_BLOCKING | OPTYPE_ALLOW_LOCKED;
        
        /* properties */
        RNA_def_float(ot->srna, "factor", 0.0f, -FLT_MAX, FLT_MAX,
@@@ -638,9 -638,6 +638,9 @@@ void IMAGE_OT_view_ndof(wmOperatorType 
        
        /* api callbacks */
        ot->invoke = image_view_ndof_invoke;
 +
 +      /* flags */
 +      ot->flag = OPTYPE_ALLOW_LOCKED;
  }
  
  /********************** view all operator *********************/
@@@ -696,9 -693,6 +696,9 @@@ void IMAGE_OT_view_all(wmOperatorType *
        /* api callbacks */
        ot->exec = image_view_all_exec;
        ot->poll = space_image_main_area_poll;
 +
 +      /* flags */
 +      ot->flag = OPTYPE_GRAB_POINTER;
  }
  
  /********************** view selected operator *********************/
@@@ -761,9 -755,6 +761,9 @@@ void IMAGE_OT_view_selected(wmOperatorT
        /* api callbacks */
        ot->exec = image_view_selected_exec;
        ot->poll = image_view_selected_poll;
 +
 +      /* flags */
 +      ot->flag = OPTYPE_GRAB_POINTER;
  }
  
  /********************** view zoom in/out operator *********************/
@@@ -806,9 -797,6 +806,9 @@@ void IMAGE_OT_view_zoom_in(wmOperatorTy
        ot->exec = image_view_zoom_in_exec;
        ot->poll = space_image_main_area_poll;
  
 +      /* flags */
 +      ot->flag = OPTYPE_ALLOW_LOCKED;
 +
        /* properties */
        RNA_def_float_vector(ot->srna, "location", 2, NULL, -FLT_MAX, FLT_MAX, "Location", "Cursor location in screen coordinates", -10.0f, 10.0f);
  }
@@@ -851,9 -839,6 +851,9 @@@ void IMAGE_OT_view_zoom_out(wmOperatorT
        ot->exec = image_view_zoom_out_exec;
        ot->poll = space_image_main_area_poll;
  
 +      /* flags */
 +      ot->flag = OPTYPE_ALLOW_LOCKED;
 +
        /* properties */
        RNA_def_float_vector(ot->srna, "location", 2, NULL, -FLT_MAX, FLT_MAX, "Location", "Cursor location in screen coordinates", -10.0f, 10.0f);
  }
@@@ -895,10 -880,7 +895,10 @@@ void IMAGE_OT_view_zoom_ratio(wmOperato
        /* api callbacks */
        ot->exec = image_view_zoom_ratio_exec;
        ot->poll = space_image_main_area_poll;
 -      
 +
 +      /* flags */
 +      ot->flag = OPTYPE_ALLOW_LOCKED;
 +
        /* properties */
        RNA_def_float(ot->srna, "ratio", 0.0f, -FLT_MAX, FLT_MAX,
                      "Ratio", "Zoom ratio, 1.0 is 1:1, higher is zoomed in, lower is zoomed out", -FLT_MAX, FLT_MAX);
@@@ -1360,7 -1342,7 +1360,7 @@@ static void save_image_doit(bContext *C
                        Scene *scene = CTX_data_scene(C);
                        RenderResult *rr = BKE_image_acquire_renderresult(scene, ima);
                        if (rr) {
-                               RE_WriteRenderResult(op->reports, rr, simopts->filepath, simopts->im_format.quality);
+                               RE_WriteRenderResult(op->reports, rr, simopts->filepath, simopts->im_format.exr_codec);
                                ok = TRUE;
                        }
                        else {
index df5de47fb3bdb33d211b529530a0c6a619b9dd1a,5b469a6c50fdf9656e0c1c0991db5d1e9818a1b1..b9455601ede4e76db1fbbbde716f3ca8e342970e
@@@ -1441,22 -1441,6 +1441,22 @@@ static void wm_event_modalkeymap(const 
        }
  }
  
 +/* Check whether operator is allowed to run in case interface is locked,
 + * If interface is unlocked, will always return truth.
 + */
 +static bool wm_operator_check_locked_interface(bContext *C, wmOperatorType *ot)
 +{
 +      wmWindowManager *wm = CTX_wm_manager(C);
 +
 +      if (wm->is_interface_locked) {
 +              if ((ot->flag & OPTYPE_ALLOW_LOCKED) == 0) {
 +                      return false;
 +              }
 +      }
 +
 +      return true;
 +}
 +
  /* bad hacking event system... better restore event type for checking of KM_CLICK for example */
  /* XXX modal maps could use different method (ton) */
  static void wm_event_modalmap_end(wmEvent *event)
@@@ -1483,12 -1467,7 +1483,12 @@@ static int wm_handler_operator_call(bCo
                wmOperator *op = handler->op;
                wmOperatorType *ot = op->type;
  
 -              if (ot->modal) {
 +              if (!wm_operator_check_locked_interface(C, ot)) {
 +                      /* Interface is locked and pperator is not allowed to run,
 +                       * nothing to do in this case.
 +                       */
 +              }
 +              else if (ot->modal) {
                        /* we set context to where modal handler came from */
                        wmWindowManager *wm = CTX_wm_manager(C);
                        ScrArea *area = CTX_wm_area(C);
                wmOperatorType *ot = WM_operatortype_find(event->keymap_idname, 0);
  
                if (ot) {
 -                      retval = wm_operator_invoke(C, ot, event, properties, NULL, FALSE);
 +                      if (wm_operator_check_locked_interface(C, ot)) {
 +                              retval = wm_operator_invoke(C, ot, event, properties, NULL, FALSE);
 +                      }
                }
        }
        /* Finished and pass through flag as handled */
@@@ -1766,15 -1743,7 +1766,15 @@@ static int wm_handlers_do_intern(bConte
                /* comment this out to flood the console! (if you really want to test) */
                !ELEM(event->type, MOUSEMOVE, INBETWEEN_MOUSEMOVE)
                ;
 +#  if defined __GNUC__ || defined __sun
 +#    define PRINT(format, args ...) { if (do_debug_handler) printf(format, ##args); } (void)0
 +#  else
 +#    define PRINT(format, ...) { if (do_debug_handler) printf(__VA_ARGS__); } (void)0
 +#  endif
 +#else
 +#  define PRINT(format, ...)
  #endif
 +
        wmWindowManager *wm = CTX_wm_manager(C);
        wmEventHandler *handler, *nexthandler;
        int action = WM_HANDLER_CONTINUE;
                                wmKeyMap *keymap = WM_keymap_active(wm, handler->keymap);
                                wmKeyMapItem *kmi;
  
 -#ifndef NDEBUG
 -                              if (do_debug_handler) {
 -                                      printf("%s:   checking '%s' ...", __func__, keymap->idname);
 -                              }
 -#endif
 +                              PRINT("%s:   checking '%s' ...", __func__, keymap->idname);
  
                                if (!keymap->poll || keymap->poll(C)) {
  
 -#ifndef NDEBUG
 -                                      if (do_debug_handler) {
 -                                              printf("pass\n");
 -                                      }
 -#endif
 +                                      PRINT("pass\n");
  
                                        for (kmi = keymap->items.first; kmi; kmi = kmi->next) {
                                                if (wm_eventmatch(event, kmi)) {
  
 -#ifndef NDEBUG
 -                                                      if (do_debug_handler) {
 -                                                              printf("%s:     item matched '%s'\n", __func__, kmi->idname);
 -                                                      }
 -#endif
 +                                                      PRINT("%s:     item matched '%s'\n", __func__, kmi->idname);
  
                                                        /* weak, but allows interactive callback to not use rawkey */
                                                        event->keymap_idname = kmi->idname;
                                                                        if (G.debug & (G_DEBUG_EVENTS | G_DEBUG_HANDLERS))
                                                                                printf("%s:       handled - and pass on! '%s'\n", __func__, kmi->idname);
                                                                
 -#ifndef NDEBUG
 -                                                              if (do_debug_handler) {
 -                                                                      printf("%s:       un-handled '%s'...", __func__, kmi->idname);
 -                                                              }
 -#endif
 +                                                                      PRINT("%s:       un-handled '%s'...", __func__, kmi->idname);
                                                        }
                                                }
                                        }
                                }
                                else {
 -#ifndef NDEBUG
 -                                      if (do_debug_handler) {
 -                                              printf("fail\n");
 -                                      }
 -#endif
 +                                      PRINT("fail\n");
                                }
                        }
                        else if (handler->ui_handle) {
 -                              action |= wm_handler_ui_call(C, handler, event, always_pass);
 +                              if (!wm->is_interface_locked) {
 +                                      action |= wm_handler_ui_call(C, handler, event, always_pass);
 +                              }
                        }
                        else if (handler->type == WM_HANDLER_FILESELECT) {
 -                              /* screen context changes here */
 -                              action |= wm_handler_fileselect_call(C, handlers, handler, event);
 +                              if (!wm->is_interface_locked) {
 +                                      /* screen context changes here */
 +                                      action |= wm_handler_fileselect_call(C, handlers, handler, event);
 +                              }
                        }
                        else if (handler->dropboxes) {
 -                              if (event->type == EVT_DROP) {
 +                              if (!wm->is_interface_locked && event->type == EVT_DROP) {
                                        wmDropBox *drop = handler->dropboxes->first;
                                        for (; drop; drop = drop->next) {
                                                /* other drop custom types allowed */
        if (action == (WM_HANDLER_BREAK | WM_HANDLER_MODAL))
                wm_cursor_arrow_move(CTX_wm_window(C), event);
  
 +#undef PRINT
 +
        return action;
  }
  
@@@ -1939,7 -1922,7 +1939,7 @@@ static int wm_handlers_do(bContext *C, 
        if (CTX_wm_window(C) == NULL)
                return action;
  
-       if (!ELEM(event->type, MOUSEMOVE, INBETWEEN_MOUSEMOVE) && !ISTIMER(event->type)) {
+       if (!ELEM3(event->type, MOUSEMOVE, INBETWEEN_MOUSEMOVE, EVENT_NONE) && !ISTIMER(event->type)) {
  
                /* test for CLICK events */
                if (wm_action_not_handled(action)) {
@@@ -3236,24 -3219,3 +3236,24 @@@ void wm_event_add_ghostevent(wmWindowMa
        WM_event_print(&event);
  #endif
  }
 +
 +void WM_set_locked_interface(wmWindowManager *wm, bool lock)
 +{
 +      /* This will prevent events from being handled while interface is locked
 +       *
 +       * Use a "local" flag for now, because currently no other areas could
 +       * benefit of locked interface anyway (aka using G.is_interface_locked
 +       * wouldn't be useful anywhere outside of window manager, so let's not
 +       * pollute global context with such an information for now).
 +       */
 +      wm->is_interface_locked = lock ? 1 : 0;
 +
 +      /* This will prevent drawing regions which uses non-threadsafe data.
 +       * Currently it'll be just a 3D viewport.
 +       *
 +       * TODO(sergey): Make it different locked states, so different jobs
 +       *               could lock different areas of blender and allow
 +       *               interation with others?
 +       */
 +      BKE_spacedata_draw_locks(lock);
 +}
index 0771e6b8f5ae0d249a0ad60c523e23a10e6276e8,9e0cb6a1d383de3b8bee5abdad13e8f574e9417a..42e72f521371545fa47c79f9b6c8a21f6317ccb5
@@@ -1674,7 -1674,7 +1674,7 @@@ static uiBlock *wm_block_create_splash(
        uiItemStringO(col, IFACE_("Credits"), ICON_URL, "WM_OT_url_open", "url",
                      "http://www.blender.org/development/credits");
        uiItemStringO(col, IFACE_("Release Log"), ICON_URL, "WM_OT_url_open", "url",
-                     "http://www.blender.org/development/release-logs/blender-267");
+                     "http://www.blender.org/development/release-logs/blender-268");
        uiItemStringO(col, IFACE_("Manual"), ICON_URL, "WM_OT_url_open", "url",
                      "http://wiki.blender.org/index.php/Doc:2.6/Manual");
        uiItemStringO(col, IFACE_("Blender Website"), ICON_URL, "WM_OT_url_open", "url", "http://www.blender.org");
@@@ -3021,7 -3021,7 +3021,7 @@@ static void tweak_gesture_modal(bContex
                        }
                        break;
                default:
-                       if (!ISTIMER(event->type)) {
+                       if (!ISTIMER(event->type) && event->type != EVENT_NONE) {
                                WM_gesture_end(C, gesture);
                        }
                        break;
@@@ -4075,24 -4075,6 +4075,24 @@@ static void WM_OT_dependency_relations(
        ot->exec = dependency_relations_exec;
  }
  
 +static int dependency_groups_exec(bContext *C, wmOperator *UNUSED(op))
 +{
 +      Scene *scene = CTX_data_scene(C);
 +
 +      DAG_print_dependency_groups(scene);
 +
 +      return OPERATOR_FINISHED;
 +}
 +
 +static void WM_OT_dependency_groups(wmOperatorType *ot)
 +{
 +      ot->name = "Dependency Groups";
 +      ot->idname = "WM_OT_dependency_groups";
 +      ot->description = "Print dependency graph groups to the console";
 +
 +      ot->exec = dependency_groups_exec;
 +}
 +
  /* ******************************************************* */
  
  static int wm_ndof_sensitivity_exec(bContext *UNUSED(C), wmOperator *op)
@@@ -4185,7 -4167,6 +4185,7 @@@ void wm_operatortype_init(void
        WM_operatortype_append(WM_OT_redraw_timer);
        WM_operatortype_append(WM_OT_memory_statistics);
        WM_operatortype_append(WM_OT_dependency_relations);
 +      WM_operatortype_append(WM_OT_dependency_groups);
        WM_operatortype_append(WM_OT_debug_menu);
        WM_operatortype_append(WM_OT_operator_defaults);
        WM_operatortype_append(WM_OT_splash);