Merge branch 'master' into soc-2013-depsgraph_mt soc-2013-depsgraph_mt
authorSergey Sharybin <sergey.vfx@gmail.com>
Fri, 27 Dec 2013 11:05:49 +0000 (17:05 +0600)
committerSergey Sharybin <sergey.vfx@gmail.com>
Fri, 27 Dec 2013 11:05:49 +0000 (17:05 +0600)
Conflicts:
source/blender/blenkernel/intern/constraint.c
source/blender/blenkernel/intern/depsgraph.c
source/blender/blenkernel/intern/object.c
source/blender/blenkernel/intern/scene.c
source/blender/blenkernel/intern/shrinkwrap.c
source/blender/collada/AnimationExporter.cpp
source/blender/editors/space_image/image_ops.c
source/blender/editors/space_view3d/view3d_view.c
source/blender/makesrna/intern/rna_scene.c
source/blender/modifiers/intern/MOD_util.c
source/blender/render/intern/source/pipeline.c

25 files changed:
release/scripts/startup/bl_ui/properties_render.py
source/blender/blenkernel/BKE_DerivedMesh.h
source/blender/blenkernel/BKE_constraint.h
source/blender/blenkernel/BKE_object.h
source/blender/blenkernel/intern/DerivedMesh.c
source/blender/blenkernel/intern/armature.c
source/blender/blenkernel/intern/constraint.c
source/blender/blenkernel/intern/object.c
source/blender/blenkernel/intern/scene.c
source/blender/blenkernel/intern/shrinkwrap.c
source/blender/blenloader/intern/readfile.c
source/blender/editors/render/render_internal.c
source/blender/editors/render/render_opengl.c
source/blender/editors/space_image/image_ops.c
source/blender/editors/space_view3d/drawobject.c
source/blender/editors/space_view3d/view3d_snap.c
source/blender/makesdna/DNA_scene_types.h
source/blender/makesdna/DNA_windowmanager_types.h
source/blender/makesrna/intern/rna_scene.c
source/blender/modifiers/intern/MOD_util.c
source/blender/render/intern/source/convertblender.c
source/blender/render/intern/source/pipeline.c
source/blender/windowmanager/WM_api.h
source/blender/windowmanager/WM_types.h
source/blender/windowmanager/intern/wm_event_system.c

index 5c2e3e5d0c7035f3d83e6ca00ef6560a6529e94b..1bcf650b2b2d7ed392bf470885ac6ca5c4147fae 100644 (file)
@@ -71,6 +71,8 @@ class RENDER_PT_render(RenderButtonsPanel, Panel):
 
         layout.prop(rd, "display_mode", text="Display")
 
+        layout.prop(rd, "use_lock_interface")
+
 
 class RENDER_PT_dimensions(RenderButtonsPanel, Panel):
     bl_label = "Dimensions"
index 6ffa126713d2f26bd81d52e540c9c2410c4fe5a6..b4550584b4d26bdfcbd853c031802a8385c15d18 100644 (file)
@@ -676,6 +676,7 @@ float (*editbmesh_get_vertex_cos(struct BMEditMesh *em, int *numVerts_r))[3];
 int editbmesh_modifier_is_enabled(struct Scene *scene, struct ModifierData *md, DerivedMesh *dm);
 void makeDerivedMesh(struct Scene *scene, struct Object *ob, struct BMEditMesh *em, 
                      CustomDataMask dataMask, int build_shapekey_layers);
+void makeDerivedMeshRender(struct Scene *scene, struct Object *ob, CustomDataMask dataMask);
 
 /** returns an array of deform matrices for crazyspace correction, and the
  * number of modifiers left */
index c79dc62bb613a04ceaf9a896e6c151e4780b39dc..7459d7034b40c6b4b4afc1337c6bfe28ba3a4bd4 100644 (file)
@@ -57,6 +57,7 @@ typedef struct bConstraintOb {
        
        short type;                 /* type of owner  */
        short rotOrder;             /* rotation order for constraint owner (as defined in eEulerRotationOrders in BLI_math.h) */
+       bool for_render;            /* constraints need to be evaluated for render purposes */
 } bConstraintOb;
 
 /* ---------------------------------------------------------------------------- */
@@ -144,7 +145,7 @@ void BKE_extract_proxylocal_constraints(struct ListBase *dst, struct ListBase *s
 short BKE_proxylocked_constraints_owner(struct Object *ob, struct bPoseChannel *pchan);
 
 /* Constraint Evaluation function prototypes */
-struct bConstraintOb *BKE_constraints_make_evalob(struct Scene *scene, struct Object *ob, void *subdata, short datatype);
+struct bConstraintOb *BKE_constraints_make_evalob(struct Scene *scene, struct Object *ob, void *subdata, short datatype, bool for_render);
 void BKE_constraints_clear_evalob(struct bConstraintOb *cob);
 
 void BKE_constraint_mat_convertspace(struct Object *ob, struct bPoseChannel *pchan, float mat[4][4], short from, short to);
index 419b8de2bc3027b6a0e296183dc58e085960f0fd..6ed8406d9a4cd5edf81617d0541189ec54d30f7d 100644 (file)
@@ -115,10 +115,10 @@ 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, float r_originmat[3][3]);
+void BKE_object_where_is_calc_ex(struct Scene *scene, struct RigidBodyWorld *rbw, struct Object *ob, bool for_render, 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, float r_originmat[3][3]);
+                                      struct RigidBodyWorld *rbw, bool for_render, 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 341e8e671c7b1b66c73388182cad2d66251b0bb1..b48b7629d411482ec99ada01d7708444645abb11 100644 (file)
@@ -2356,7 +2356,7 @@ DerivedMesh *mesh_get_derived_deform(Scene *scene, Object *ob, CustomDataMask da
 DerivedMesh *mesh_create_derived_render(Scene *scene, Object *ob, CustomDataMask dataMask)
 {
        DerivedMesh *final;
-       
+    
        mesh_calc_modifiers(scene, ob, NULL, NULL, &final, 1, 1, 0, dataMask, -1, 0, 0);
 
        return final;
index 0267c9a61225b73765f8638e97031ff33bd502a2..3b8e753bf621953cf3f9aac774debcd3c560965b 100644 (file)
@@ -2430,7 +2430,8 @@ void BKE_pose_where_is_bone(Scene *scene, Object *ob, bPoseChannel *pchan, float
                        /* prepare PoseChannel for Constraint solving
                         * - makes a copy of matrix, and creates temporary struct to use
                         */
-                       cob = BKE_constraints_make_evalob(scene, ob, pchan, CONSTRAINT_OBTYPE_BONE);
+                       /* TODO(sergey): We need to use proper for_render flag here */
+                       cob = BKE_constraints_make_evalob(scene, ob, pchan, CONSTRAINT_OBTYPE_BONE, false);
 
                        /* Solve PoseChannel's Constraints */
                        BKE_solve_constraints(&pchan->constraints, cob, ctime); /* ctime doesnt alter objects */
index 50e74dfba445be240c00f516e5be0c59d9bac805..8c34aa4b3cf8e66d31c5d81ca3e5d49d54c5c761 100644 (file)
@@ -108,7 +108,7 @@ void BKE_unique_constraint_name(bConstraint *con, ListBase *list)
 
 /* package an object/bone for use in constraint evaluation */
 /* This function MEM_calloc's a bConstraintOb struct, that will need to be freed after evaluation */
-bConstraintOb *BKE_constraints_make_evalob(Scene *scene, Object *ob, void *subdata, short datatype)
+bConstraintOb *BKE_constraints_make_evalob(Scene *scene, Object *ob, void *subdata, short datatype, bool for_render)
 {
        bConstraintOb *cob;
        
@@ -167,6 +167,8 @@ bConstraintOb *BKE_constraints_make_evalob(Scene *scene, Object *ob, void *subda
                        break;
        }
 
+       cob->for_render = for_render;
+
        return cob;
 }
 
@@ -347,7 +349,7 @@ void BKE_constraint_mat_convertspace(Object *ob, bPoseChannel *pchan, float mat[
 /* ------------ General Target Matrix Tools ---------- */
 
 /* function that sets the given matrix based on given vertex group in mesh */
-static void contarget_get_mesh_mat(Object *ob, const char *substring, float mat[4][4])
+static void contarget_get_mesh_mat(Object *ob, const char *substring, float mat[4][4], bool for_render)
 {
        DerivedMesh *dm = NULL;
        BMEditMesh *em = BKE_editmesh_from_object(ob);
@@ -364,7 +366,11 @@ static void contarget_get_mesh_mat(Object *ob, const char *substring, float mat[
        if (defgroup == -1) return;
 
        /* get DerivedMesh */
-       if (em) {
+       if (for_render) {
+               /* TODO(sergey); Use proper derivedRender when known. */
+               dm = ob->derivedFinal;
+       }
+       else if (em) {
                /* target is in editmode, so get a special derived mesh */
                dm = CDDM_from_editbmesh(em, FALSE, FALSE);
                freeDM = 1;
@@ -498,7 +504,7 @@ static void contarget_get_lattice_mat(Object *ob, const char *substring, float m
 
 /* generic function to get the appropriate matrix for most target cases */
 /* The cases where the target can be object data have not been implemented */
-static void constraint_target_to_mat4(Object *ob, const char *substring, float mat[4][4], short from, short to, float headtail)
+static void constraint_target_to_mat4(Object *ob, const char *substring, float mat[4][4], short from, short to, float headtail, bool for_render)
 {
        /*      Case OBJECT */
        if (!strlen(substring)) {
@@ -515,7 +521,7 @@ static void constraint_target_to_mat4(Object *ob, const char *substring, float m
         *              way as constraints can only really affect things on object/bone level.
         */
        else if (ob->type == OB_MESH) {
-               contarget_get_mesh_mat(ob, substring, mat);
+               contarget_get_mesh_mat(ob, substring, mat, for_render);
                BKE_constraint_mat_convertspace(ob, NULL, mat, from, to);
        }
        else if (ob->type == OB_LATTICE) {
@@ -594,10 +600,10 @@ static bConstraintTypeInfo CTI_CONSTRNAME = {
 /* This function should be used for the get_target_matrix member of all 
  * constraints that are not picky about what happens to their target matrix.
  */
-static void default_get_tarmat(bConstraint *con, bConstraintOb *UNUSED(cob), bConstraintTarget *ct, float UNUSED(ctime))
+static void default_get_tarmat(bConstraint *con, bConstraintOb *cob, bConstraintTarget *ct, float UNUSED(ctime))
 {
        if (VALID_CONS_TARGET(ct))
-               constraint_target_to_mat4(ct->tar, ct->subtarget, ct->matrix, CONSTRAINT_SPACE_WORLD, ct->space, con->headtail);
+               constraint_target_to_mat4(ct->tar, ct->subtarget, ct->matrix, CONSTRAINT_SPACE_WORLD, ct->space, con->headtail, cob->for_render);
        else if (ct)
                unit_m4(ct->matrix);
 }
@@ -1065,7 +1071,7 @@ static void kinematic_get_tarmat(bConstraint *con, bConstraintOb *cob, bConstrai
        bKinematicConstraint *data = con->data;
        
        if (VALID_CONS_TARGET(ct)) 
-               constraint_target_to_mat4(ct->tar, ct->subtarget, ct->matrix, CONSTRAINT_SPACE_WORLD, ct->space, con->headtail);
+               constraint_target_to_mat4(ct->tar, ct->subtarget, ct->matrix, CONSTRAINT_SPACE_WORLD, ct->space, con->headtail, cob->for_render);
        else if (ct) {
                if (data->flag & CONSTRAINT_IK_AUTO) {
                        Object *ob = cob->ob;
@@ -1942,7 +1948,7 @@ static void pycon_get_tarmat(bConstraint *con, bConstraintOb *cob, bConstraintTa
                /* firstly calculate the matrix the normal way, then let the py-function override
                 * this matrix if it needs to do so
                 */
-               constraint_target_to_mat4(ct->tar, ct->subtarget, ct->matrix, CONSTRAINT_SPACE_WORLD, ct->space, con->headtail);
+               constraint_target_to_mat4(ct->tar, ct->subtarget, ct->matrix, CONSTRAINT_SPACE_WORLD, ct->space, con->headtail, cob->for_render);
                
                /* only execute target calculation if allowed */
 #ifdef WITH_PYTHON
@@ -2054,7 +2060,7 @@ static void actcon_get_tarmat(bConstraint *con, bConstraintOb *cob, bConstraintT
                unit_m4(ct->matrix);
                
                /* get the transform matrix of the target */
-               constraint_target_to_mat4(ct->tar, ct->subtarget, tempmat, CONSTRAINT_SPACE_WORLD, ct->space, con->headtail);
+               constraint_target_to_mat4(ct->tar, ct->subtarget, tempmat, CONSTRAINT_SPACE_WORLD, ct->space, con->headtail, cob->for_render);
                
                /* determine where in transform range target is */
                /* data->type is mapped as follows for backwards compatibility:
@@ -3351,8 +3357,7 @@ static void shrinkwrap_get_tarmat(bConstraint *con, bConstraintOb *cob, bConstra
                float co[3] = {0.0f, 0.0f, 0.0f};
                
                SpaceTransform transform;
-               /* TODO(sergey): use proper for_render flag here when known. */
-               DerivedMesh *target = object_get_derived_final(ct->tar, false);
+               DerivedMesh *target = object_get_derived_final(ct->tar, cob->for_render);
                
                BVHTreeFromMesh treeData = {NULL};
                
@@ -4015,8 +4020,7 @@ static void followtrack_evaluate(bConstraint *con, bConstraintOb *cob, ListBase
 
                        if (data->depth_ob) {
                                Object *depth_ob = data->depth_ob;
-                               /* TODO(sergey): use proper for_render flag here when known. */
-                               DerivedMesh *target = object_get_derived_final(depth_ob, false);
+                               DerivedMesh *target = object_get_derived_final(depth_ob, cob->for_render);
                                if (target) {
                                        BVHTreeFromMesh treeData = NULL_BVHTreeFromMesh;
                                        BVHTreeRayHit hit;
index c069abfaf355e70ee81a20064758a95d7840cb0c..711065b0e8b2d481b88632eb4796b42cc11206e1 100644 (file)
@@ -2335,7 +2335,8 @@ 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, float r_originmat[3][3])
+                                      RigidBodyWorld *rbw, bool for_render,
+                                      float r_originmat[3][3])
 {
        if (ob == NULL) return;
        
@@ -2369,7 +2370,15 @@ void BKE_object_where_is_calc_time_ex(Scene *scene, Object *ob, float ctime,
        /* solve constraints */
        if (ob->constraints.first && !(ob->transflag & OB_NO_CONSTRAINTS)) {
                bConstraintOb *cob;
-               cob = BKE_constraints_make_evalob(scene, ob, NULL, CONSTRAINT_OBTYPE_OBJECT);
+
+               (void) for_render;  /* Currently unused. */
+
+               /* TODO(sergey): Mixing viewport/render evaluation leads to conflicts because
+                *               of shared ob->obmat.
+                *               To preserve regressions for now don't use render evaluation
+                *               for now.
+                */
+               cob = BKE_constraints_make_evalob(scene, ob, NULL, CONSTRAINT_OBTYPE_OBJECT, false);
                BKE_solve_constraints(&ob->constraints, cob, ctime);
                BKE_constraints_clear_evalob(cob);
        }
@@ -2381,7 +2390,8 @@ 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, NULL);
+       /* TODO(sergey): We might need real for_render flag here */
+       BKE_object_where_is_calc_time_ex(scene, ob, ctime, NULL, false, NULL);
 }
 
 /* get object transformation matrix without recalculating dependencies and
@@ -2405,13 +2415,14 @@ 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, float r_originmat[3][3])
+void BKE_object_where_is_calc_ex(Scene *scene, RigidBodyWorld *rbw, Object *ob, bool for_render, float r_originmat[3][3])
 {
-       BKE_object_where_is_calc_time_ex(scene, ob, BKE_scene_frame_get(scene), rbw, r_originmat);
+       BKE_object_where_is_calc_time_ex(scene, ob, BKE_scene_frame_get(scene), rbw, for_render, 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, NULL);
+       /* TODO(sergey): We might need real for_render flag here */
+       BKE_object_where_is_calc_time_ex(scene, ob, BKE_scene_frame_get(scene), NULL, false, NULL);
 }
 
 /* was written for the old game engine (until 2.04) */
@@ -2449,7 +2460,8 @@ void BKE_object_where_is_calc_simul(Scene *scene, Object *ob)
        if (ob->constraints.first) {
                bConstraintOb *cob;
                
-               cob = BKE_constraints_make_evalob(scene, ob, NULL, CONSTRAINT_OBTYPE_OBJECT);
+               /* TODO(sergey): We need a proper for_render flag here. */
+               cob = BKE_constraints_make_evalob(scene, ob, NULL, CONSTRAINT_OBTYPE_OBJECT, false);
                BKE_solve_constraints(&ob->constraints, cob, BKE_scene_frame_get(scene));
                BKE_constraints_clear_evalob(cob);
        }
@@ -2893,7 +2905,7 @@ void BKE_object_handle_update_ex(EvaluationContext *eval_ctx,
                                        copy_m4_m4(ob->obmat, ob->proxy_from->obmat);
                        }
                        else
-                               BKE_object_where_is_calc_ex(scene, rbw, ob, NULL);
+                               BKE_object_where_is_calc_ex(scene, rbw, ob, eval_ctx->for_render, NULL);
                }
                
                if (ob->recalc & OB_RECALC_DATA) {
@@ -2950,7 +2962,9 @@ void BKE_object_handle_update_ex(EvaluationContext *eval_ctx,
                                case OB_CURVE:
                                case OB_SURF:
                                case OB_FONT:
-                                       BKE_displist_make_curveTypes(scene, ob, 0);
+                                       if (eval_ctx->for_render == false) {
+                                               BKE_displist_make_curveTypes(scene, ob, 0);
+                                       }
                                        break;
                                
                                case OB_LATTICE:
index 6de75215ae1127bb5f6aa6112e622a7fd7368718..3ca702e0068df11190c917c71931e30d81265124 100644 (file)
@@ -1184,7 +1184,7 @@ static void scene_do_rb_simulation_recursive(Scene *scene, float ctime)
 
 /* Mballs evaluation uses BKE_scene_base_iter_next which calls
  * duplilist for all objects in the scene. This leads to conflict
- * accessing and writting same data from multipl threads.
+ * accessing and writing same data from multiple threads.
  *
  * Ideally Mballs shouldn't do such an iteration and use DAG
  * queries instead. For the time being we've got new DAG
index 6a7c16d1162d6268fd7c7417f3d0fb9d340e1616..34a3cdf8d670324ccf192bbcdf2b41983927f1c5 100644 (file)
@@ -74,7 +74,7 @@ DerivedMesh *object_get_derived_final(Object *ob, bool for_render)
        BMEditMesh *em = me->edit_btmesh;
 
        if (for_render) {
-               /* TODO(sergey): use proper derived render here in the future. */
+               /* TODO(sergey): Use proper derivedRender when known. */
                return ob->derivedFinal;
        }
 
index 035a917d37f2d0ec6dcaba38dae51dba95fdcb79..8cb9853aa47bc6b01cc6dd4c12db04ff3017eeb5 100644 (file)
@@ -5547,6 +5547,7 @@ static void direct_link_windowmanager(FileData *fd, wmWindowManager *wm)
        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 091dc11f5007f4e3c100228b75058b7a3c5487cd..f9f06814d370998d26ce8ced94d7134d48ca5933 100644 (file)
 
 #include "BKE_blender.h"
 #include "BKE_context.h"
+#include "BKE_curve.h"
 #include "BKE_depsgraph.h"
+#include "BKE_displist.h"
+#include "BKE_DerivedMesh.h"
 #include "BKE_freestyle.h"
 #include "BKE_global.h"
 #include "BKE_image.h"
@@ -305,6 +308,7 @@ typedef struct RenderJob {
        int orig_layer;
        int last_layer;
        ScrArea *sa;
+       bool interface_locked;
 } RenderJob;
 
 static void render_freejob(void *rjv)
@@ -636,6 +640,29 @@ static void render_endjob(void *rjv)
 
                BKE_image_release_ibuf(ima, ibuf, lock);
        }
+
+       /* Finally unlock the user interface (if it was locked). */
+       if (rj->interface_locked) {
+               Scene *scene;
+
+               /* Interface was locked, so window manager couldn't have been changed
+                * and using one from Global will unlock exactly the same manager as
+                * was locked before running the job.
+                */
+               WM_set_locked_interface(G.main->wm.first, false);
+
+               /* We've freed all the derived caches before rendering, which is
+                * effectively the same as if we re-loaded the file.
+                *
+                * So let's not try being smart here and just reset all updated
+                * scene layers and use generic DAG_on_visible_update.
+                */
+               for (scene = G.main->scene.first; scene; scene = scene->id.next) {
+                       scene->lay_updated = 0;
+               }
+
+               DAG_on_visible_update(G.main, false);
+       }
 }
 
 /* called by render, check job 'stop' value or the global */
@@ -661,10 +688,14 @@ static int render_break(void *UNUSED(rjv))
 
 /* runs in thread, no cursor setting here works. careful with notifiers too (malloc conflicts) */
 /* maybe need a way to get job send notifer? */
-static void render_drawlock(void *UNUSED(rjv), int lock)
+static void render_drawlock(void *rjv, int lock)
 {
-       BKE_spacedata_draw_locks(lock);
-       
+       RenderJob *rj = rjv;
+
+       /* If interface is locked, renderer callback shall do nothing. */
+       if (!rj->interface_locked) {
+               BKE_spacedata_draw_locks(lock);
+       }
 }
 
 /* catch esc */
@@ -695,6 +726,35 @@ static void screen_render_cancel(bContext *C, wmOperator *op)
        WM_jobs_kill_type(wm, scene, WM_JOB_TYPE_RENDER);
 }
 
+static void clean_viewport_memory(Main *bmain)
+{
+       Object *object;
+
+       for (object = bmain->object.first; object; object = object->id.next) {
+               /* TODO(sergey): Afraid we cannot use BKE_object_free_derived_caches
+                *               because it'll free bounding box which could be needed
+                *               for texture mapping in render pipeline.
+                *
+                *               So for now just use a bit of dupicated logic.
+                */
+               /* BKE_object_free_derived_caches(); */
+
+               if (object->derivedFinal) {
+                       object->derivedFinal->needsFree = 1;
+                       object->derivedFinal->release(object->derivedFinal);
+                       object->derivedFinal = NULL;
+               }
+               if (object->derivedDeform) {
+                       object->derivedDeform->needsFree = 1;
+                       object->derivedDeform->release(object->derivedDeform);
+                       object->derivedDeform = NULL;
+               }
+               if (object->curve_cache) {
+                       BKE_displist_free(&object->curve_cache->disp);
+               }
+       }
+}
+
 /* using context, starts job */
 static int screen_render_invoke(bContext *C, wmOperator *op, const wmEvent *event)
 {
@@ -810,6 +870,24 @@ static int screen_render_invoke(bContext *C, wmOperator *op, const wmEvent *even
                        rj->lay_override |= v3d->localvd->lay;
        }
 
+       /* Lock the user interface depending on render settings. */
+       if (scene->r.use_lock_interface) {
+               WM_set_locked_interface(CTX_wm_manager(C), true);
+
+               /* Set flag interface need to be unlocked.
+                *
+                * This is so because we don't have copy of render settings
+                * accessible from render job and copy is needed in case
+                * of non-locked rendering, so we wouldn't try to unlock
+                * anything if option was initially unset but then was
+                * enabled during rendering.
+                */
+               rj->interface_locked = true;
+
+               /* Clean memory used by viewport? */
+               clean_viewport_memory(rj->main);
+       }
+
        /* setup job */
        if (RE_seq_render_active(scene, &scene->r)) name = "Sequence Render";
        else name = "Render";
index a1d09963eb7101e9be3a3bde4ba5d81ce8a0abfc..42045d158f11d5a91eeba671a0b282d57b36c352 100644 (file)
@@ -554,7 +554,7 @@ static bool screen_opengl_render_anim_step(bContext *C, wmOperator *op)
 
        if (view_context) {
                if (oglrender->rv3d->persp == RV3D_CAMOB && oglrender->v3d->camera && oglrender->v3d->scenelock) {
-                       /* since BKE_scene_update_for_newframe() is used rather
+                       /* since BKE_scene_update_for_newframe_viewport() is used rather
                         * then ED_update_for_newframe() the camera needs to be set */
                        if (BKE_scene_camera_switch_update(scene)) {
                                oglrender->v3d->camera = scene->camera;
index ea06e26fb5aad5a3a722371ae23cb3c506742d0e..173710a47314a3dadd1e5153e00f6bfc3478c7fd 100644 (file)
@@ -363,7 +363,7 @@ void IMAGE_OT_view_pan(wmOperatorType *ot)
        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,
@@ -577,7 +577,7 @@ void IMAGE_OT_view_zoom(wmOperatorType *ot)
        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,
@@ -640,6 +640,9 @@ void IMAGE_OT_view_ndof(wmOperatorType *ot)
        
        /* api callbacks */
        ot->invoke = image_view_ndof_invoke;
+
+       /* flags */
+       ot->flag = OPTYPE_ALLOW_LOCKED;
 }
 
 /********************** view all operator *********************/
@@ -817,6 +820,9 @@ void IMAGE_OT_view_zoom_in(wmOperatorType *ot)
        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);
 }
@@ -859,6 +865,9 @@ void IMAGE_OT_view_zoom_out(wmOperatorType *ot)
        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);
 }
@@ -901,6 +910,9 @@ void IMAGE_OT_view_zoom_ratio(wmOperatorType *ot)
        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);
index 9eb3fb320be4dc79ea2664894ee7e8f687e6e781..02e981f2ffd409d2e85b9c471c971719de0fff5c 100644 (file)
@@ -7340,7 +7340,7 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, const short
                        UI_make_axis_color(col1, col2, 'Z');
                        glColor3ubv(col2);
                        
-                       cob = BKE_constraints_make_evalob(scene, ob, NULL, CONSTRAINT_OBTYPE_OBJECT);
+                       cob = BKE_constraints_make_evalob(scene, ob, NULL, CONSTRAINT_OBTYPE_OBJECT, false);
                        
                        for (curcon = list->first; curcon; curcon = curcon->next) {
                                if (ELEM(curcon->type, CONSTRAINT_TYPE_FOLLOWTRACK, CONSTRAINT_TYPE_OBJECTSOLVER)) {
index 3486e930466c75d251b8ede5662775811ac41152..80e9ce38bc160b4004b5d59f3bc0c94dc27c0007 100644 (file)
@@ -160,7 +160,7 @@ static int snap_sel_to_grid_exec(bContext *C, wmOperator *UNUSED(op))
                                
                                if (ob->parent) {
                                        float originmat[3][3];
-                                       BKE_object_where_is_calc_ex(scene, NULL, ob, originmat);
+                                       BKE_object_where_is_calc_ex(scene, NULL, ob, false, originmat);
                                        
                                        invert_m3_m3(imat, originmat);
                                        mul_m3_v3(imat, vec);
@@ -326,7 +326,7 @@ static int snap_sel_to_curs_exec(bContext *C, wmOperator *op)
                                
                                if (ob->parent) {
                                        float originmat[3][3];
-                                       BKE_object_where_is_calc_ex(scene, NULL, ob, originmat);
+                                       BKE_object_where_is_calc_ex(scene, NULL, ob, false, originmat);
                                        
                                        invert_m3_m3(imat, originmat);
                                        mul_m3_v3(imat, cursor_parent);
index b0aa818d49a9462213fc3b6a096716efd63a6f58..ea016c9ee3f2b51e2265a3aaee72d58d0afd9e9f 100644 (file)
@@ -432,7 +432,8 @@ typedef struct RenderData {
         * Render to image editor, fullscreen or to new window.
         */
        short displaymode;
-       short pad7;
+       char use_lock_interface;
+       char pad7;
 
        /**
         * Flags for render settings. Use bit-masking to access the settings.
index ff43cc31b9aa162a5d0439e12f84ae6d591bf1c3..a17e416b5bdefbdd50e1382c196a078bc157006b 100644 (file)
@@ -154,6 +154,9 @@ typedef struct wmWindowManager {
 
        ListBase timers;                  /* active timers */
        struct wmTimer *autosavetimer;    /* timer for auto save */
+
+       char is_interface_locked;               /* indicates whether interface is locked for user interaction */
+       char par[7];
 } wmWindowManager;
 
 /* wmWindowManager.initialized */
index 82447c2e5b40fb6b15d09cd67b9be8d345bdb13b..dbfa1c754389f81238df23ca249dd1d24f50bda0 100644 (file)
@@ -4515,6 +4515,11 @@ static void rna_def_scene_render_data(BlenderRNA *brna)
        RNA_def_property_ui_text(prop, "Display", "Select where rendered images will be displayed");
        RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL);
 
+       prop = RNA_def_property(srna, "use_lock_interface", PROP_BOOLEAN, PROP_NONE);
+       RNA_def_property_boolean_sdna(prop, NULL, "use_lock_interface", 1);
+       RNA_def_property_ui_text(prop, "Lock Interface", "Lock interface during rendering in favor of giving more memory to the renderer");
+       RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL);
+
        prop = RNA_def_property(srna, "filepath", PROP_STRING, PROP_FILEPATH);
        RNA_def_property_string_sdna(prop, NULL, "pic");
        RNA_def_property_ui_text(prop, "Output Path",
index bde30fb23ae35ae6b09edea75c1f5ed824982770..c087a7870c0dbdfc784e68a5b307339818af903c 100644 (file)
@@ -213,7 +213,7 @@ DerivedMesh *get_dm(Object *ob, struct BMEditMesh *em, DerivedMesh *dm,
 DerivedMesh *get_dm_for_modifier(Object *ob, ModifierApplyFlag flag)
 {
        if (flag & MOD_APPLY_RENDER) {
-               /* TODO(sergey): Use proper derived render in the future. */
+               /* TODO(sergey): Use proper derivedRender when known. */
                return ob->derivedFinal;
        }
        else {
index 382229cca88958eea1f348f954cd97ca198dae11..e3a8c57de66e51afccc90ac739a83e251303b3df 100644 (file)
@@ -5139,7 +5139,7 @@ void RE_Database_FromScene(Render *re, Main *bmain, Scene *scene, unsigned int l
        /* if no camera, viewmat should have been set! */
        if (use_camera_view && camera) {
                /* called before but need to call again in case of lens animation from the
-                * above call to BKE_scene_update_for_newframe, fixes bug. [#22702].
+                * above call to BKE_scene_update_for_newframe_render, fixes bug. [#22702].
                 * following calls don't depend on 'RE_SetCamera' */
                RE_SetCamera(re, camera);
 
index 4ec7ce1c0d284fcc6f8dd5c3b3eb624147b34106..78434427b18f0c5d93cbe71017f2e512f6f01704 100644 (file)
@@ -1622,6 +1622,7 @@ static bool allow_render_mesh_object(Object *ob)
        else if ((ob->transflag & OB_DUPLI) && !(ob->transflag & OB_DUPLIFRAMES)) {
                return false;
        }
+
        return true;
 }
 
index d8f558bf2c9ac8f1bf32321ec81b0fa45d463bc7..742414e21f87b577e8b854dba7ba2cdf29bae10c 100644 (file)
@@ -424,6 +424,9 @@ void        WM_main_playanim(int argc, const char **argv);
 /* debugging only, convenience function to write on crash */
 bool write_crash_blend(void);
 
+                       /* Lock the interface for any communication */
+void        WM_set_locked_interface(struct wmWindowManager *wm, bool lock);
+
 #ifdef __cplusplus
 }
 #endif
index 83c17170f9eed90f2af3391c72382d261eb86bcc..5ca63ed8a3678404637e573c6eecbfafcdd5eeea 100644 (file)
@@ -134,6 +134,7 @@ struct ImBuf;
                                                                 * and don't make sense to be accessed from the
                                                                 * search menu, even if poll() returns TRUE.
                                                                 * currently only used for the search toolbox */
+#define OPTYPE_ALLOW_LOCKED    128     /* Allow operator to run when interface is locked */
 
 /* context to call operator in for WM_operator_name_call */
 /* rna_ui.c contains EnumPropertyItem's of these, keep in sync */
index ee8ad08ad8097e68ddb83d6182c70bd6fbf638ff..ad5a7df9ac3abe69cc123c06cd00be55621453f8 100644 (file)
@@ -1467,6 +1467,22 @@ static void wm_event_modalkeymap(const bContext *C, wmOperator *op, wmEvent *eve
        }
 }
 
+/* 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)
@@ -1493,7 +1509,12 @@ static int wm_handler_operator_call(bContext *C, ListBase *handlers, wmEventHand
                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);
@@ -1565,7 +1586,9 @@ static int wm_handler_operator_call(bContext *C, ListBase *handlers, wmEventHand
                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 */
@@ -1771,7 +1794,11 @@ static int wm_handlers_do_intern(bContext *C, wmEvent *event, ListBase *handlers
                /* comment this out to flood the console! (if you really want to test) */
                !ELEM(event->type, MOUSEMOVE, INBETWEEN_MOUSEMOVE)
                ;
+#    define PRINT if (do_debug_handler) printf
+#else
+#  define PRINT(format, ...)
 #endif
+
        wmWindowManager *wm = CTX_wm_manager(C);
        wmEventHandler *handler, *nexthandler;
        int action = WM_HANDLER_CONTINUE;
@@ -1807,28 +1834,16 @@ static int wm_handlers_do_intern(bContext *C, wmEvent *event, ListBase *handlers
                                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;
@@ -1847,32 +1862,28 @@ static int wm_handlers_do_intern(bContext *C, wmEvent *event, ListBase *handlers
                                                                        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 */
@@ -1938,6 +1949,8 @@ static int wm_handlers_do_intern(bContext *C, wmEvent *event, ListBase *handlers
        if (action == (WM_HANDLER_BREAK | WM_HANDLER_MODAL))
                wm_cursor_arrow_move(CTX_wm_window(C), event);
 
+#undef PRINT
+
        return action;
 }
 
@@ -3247,3 +3260,24 @@ void wm_event_add_ghostevent(wmWindowManager *wm, wmWindow *win, int type, int U
        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);
+}