1
1

Compare commits

...

86 Commits

Author SHA1 Message Date
76b562237f Merge branch 'master' into soc-2013-depsgraph_mt
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
2013-12-27 17:05:49 +06:00
03e3881270 Merge branch 'master' into soc-2013-depsgraph_mt 2013-12-23 23:14:46 +06:00
f277707e27 Fix compilation error when using scons 2013-12-23 21:54:33 +06:00
40223ffe69 Rename evaluation_context to eval_ctx
Only affects on variable name, structure name stays the same.
Addresses code review from Campbell to make variable names
which are being passed all over be short.

Not entirely happy with this, but well ok. It's still verbose
enough and naming kind of consistent to what Python uses.

Discussed with Brecht and he's also fine with such a change.

Hopefully this is last change to be done before merge :)
2013-12-23 13:50:53 +06:00
bbd1068ef7 Merge branch 'master' into soc-2013-depsgraph_mt
Conflicts:
	source/blender/editors/render/render_internal.c
	source/blender/modifiers/intern/MOD_smoke.c
2013-12-23 13:46:13 +06:00
43e2b343e4 Address notes from Campbell's review
- Cleanup naming in some places.
- Get rid of _ex functions with use_threads argument
  in scene update routines.

  Using Py_BEGIN_ALLOW_THREADS from frame_set and
  update_tagged functions seems made the trick.

- Fix for possible uninitialized members of
  evaluation context when it's allocated in stack.
2013-12-17 23:10:07 +06:00
c2fe44fcc4 Merge branch 'master' into soc-2013-depsgraph_mt 2013-12-17 22:42:15 +06:00
0960d2114a Address review from Brecht
* Removed residual of derivedRender code from convertblender.c
* Added check for oldcreen->scene != screen->scene before rebuilding
  the DAG when changing the scene.
* Made blender compilable with smoke disabled.
* Typo fixes.
2013-12-13 16:17:11 +06:00
dd2e967fce Merge branch 'master' into soc-2013-depsgraph_mt
Conflicts:
	release/scripts/startup/bl_ui/properties_data_curve.py
2013-12-13 16:12:57 +06:00
83f13f0ee6 Fix typo which was already fixed in trunk actually 2013-12-12 17:37:31 +06:00
07adc11588 Code cleanup to address Lukas codereview comments 2013-12-11 22:47:17 +06:00
ec34afe8eb Workaround for render settings with mballs and cycles
Not ideal solution, but it'll work just fine for until
CoW is implemented (which is gonna to take a while anyway).
2013-12-10 18:53:40 +06:00
88cfd1a815 Pass evaluation context to BKE_scene_base_iter_next
This is needed to make dupilist being created with
proper render settings when counting mballs.

Without this change enabling particles for rendering
and disabling them for viewport would lead to situation
when mball used as dupliobject for this particle system
is never visible.

Also removed hardcoded evaluation context from some
RNA callbacks.

TODO: Cycles will use viewport render settings for
      mballs, don't ask why. It is to be solved.
2013-12-10 18:42:23 +06:00
10961faa92 Temporary remove derivedRender
Couldn't say the idea was wrong, but some nasty bugs were
discovered with the approach and to make life simpler for
now it's easier to do hacks needed for boolean modifier
from the render pipeline by tagging needed operands for
the update.
2013-12-10 17:23:35 +06:00
e4edc882ae Update metaballs in a single thread
Mballs evaluation uses BKE_scene_base_iter_next which calls
duplilist for all objects in the scene. This leads to conflict
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
let's keep it simple and update mballs in a ingle thread.
2013-12-10 16:28:55 +06:00
f98eedb86b Code cleanup
- Add some additional cases to mallocn_intern
  to cover FreeBSD and add missing include for OSX.

- Move DAG_init/DAG_exit functions to the top,
  they're kind of global and it's not so much
  logical to keep them under "Threaded Update"
  comment.
2013-12-10 14:37:46 +06:00
d547db06b6 Merge branch 'master' into soc-2013-depsgraph_mt 2013-12-10 14:30:59 +06:00
2c206febd5 Fixes for stupid mistakes from a while ago
- Render engine's evaluation context didn't set for_render to truth.
- Use G.evaluation_context for motion path instead of local one.
2013-11-21 01:50:57 +06:00
e3b849565e Address some of the codereview comments
- Call it just DAG_init/DAG_exit
- Move EvaluationContext to a better place (DAG header).
- Rename valency to num_pending_parents.
- Added a comment about why we might want to not
  use threads for the scene update/
- Update comment for screen switch.
2013-11-21 01:00:48 +06:00
f19a9d3117 Post-merge compilation error fix
Was caused by the new code in master since previous merge
by the looks of it.
2013-11-20 23:57:42 +06:00
7a3ecab74b Merge branch 'master' into soc-2013-depsgraph_mt
Conflicts:
	release/datafiles/splash.png
	release/scripts/startup/bl_ui/properties_render.py
2013-11-20 23:41:41 +06:00
0712d43310 Merging r60854 through r60868 from trunk into soc-2013-depsgraph_mt 2013-10-20 12:10:37 +00:00
e81e98f4b3 Merging r60847 through r60853 from trunk into soc-2013-depsgraph_mt 2013-10-18 23:50:29 +00:00
88a5f44120 Avoid spawning local evaluation contexts
Instead of creating local one, make sure either context
from Render or G.main is used.
2013-10-18 23:18:40 +00:00
13dc30cd5c Make evaluatio ncontext a part of render strcture
That's how it's supposed to be actually.
2013-10-18 22:15:09 +00:00
a67e5d4ca3 Merging r60471 through r60846 from trunk into soc-2013-depsgraph_mt 2013-10-18 17:57:15 +00:00
650325963d Merging r60468 through r60470 from trunk into soc-2013-depsgraph_mt 2013-10-01 08:27:02 +00:00
71c1447d6c Merging r60198 through r60467 from trunk into soc-2013-depsgraph_mt 2013-10-01 08:19:31 +00:00
a44f4a2065 Merging r60106 through r60197 from trunk into soc-2013-depsgraph_mt 2013-09-17 13:50:25 +00:00
5067501b40 Simplify code around detailed analysis in scene.c 2013-09-17 08:29:48 +00:00
3822a6f008 Merging r60069 through r60105 from trunk into soc-2013-depsgraph_mt 2013-09-13 13:25:55 +00:00
1314a68bb8 Mark some CCG funcrions as inlined
This seems to be giving speedup up to 10%
and in fact perhaps the change need to go
to the trunk.
2013-09-13 13:22:18 +00:00
9ed3afc213 Second attempt at fixing windows + guardedalloc issues in main()
Although previous fix compiled, it would crash on startup, since
the guardedalloc changes need to read from the args passed in.
Now use plain malloc for allocating the offending array, so that
we can grab the args before they're needed.
2013-09-13 02:31:15 +00:00
bf377443c9 Another windows compile fix for r.59942
Moved var declarations for unicode args array to start of main().

The fix used in the original commit won't work since the args
defined in that block won't be available for later steps.
However, they must be defined before the block of code used
to initialise the mem allocators
2013-09-13 00:01:29 +00:00
3da0eae73d scons + mingw Compile Fixes for r.59942
* SCons files for guardedalloc module requires all the source files to be listed out, like in CMake.

* mingw32 (or at least gcc 4.6.2) seems to follow the Windows convention of using _msize() instead of having a "malloc_usable_size()"
2013-09-12 13:29:07 +00:00
0850ef8f59 Merging r60012 through r60068 from trunk into soc-2013-depsgraph_mt 2013-09-12 12:07:39 +00:00
1cd8f4c36f Merging r59941 through r60011 from trunk into soc-2013-depsgraph_mt 2013-09-10 14:59:29 +00:00
adcc28eaa4 Lock-free memory allocator
Release builds will now use lock-free allocator by
default without any internal locks happening.

MemHead is also reduces to as minimum as it's possible.
It still need to be size_t stored in a MemHead in order
to make us keep track on memory we're requesting from
the system, not memory which system is allocating. This
is probably also faster than using a malloc's usable
size function.

Lock-free guarded allocator will say you whether all
the blocks were freed, but wouldn't give you a list
of unfreed blocks list. To have such a list use a
--debug or --debug-memory command line arguments.

Debug builds does have the same behavior as release
builds. This is so tools like valgrind are not
screwed up by guarded allocator as they're currently
are.
2013-09-09 09:27:25 +00:00
cefb2b2878 Merging r59874 through r59940 from trunk into soc-2013-depsgraph_mt 2013-09-09 09:14:49 +00:00
7e47f5e32f Smoke modifier is now expected to use proper render flags
Not so much up to using smoke simulations, only did quick
tests. Would be nice to have some more intense testing some
day later.
2013-09-06 11:35:59 +00:00
927e0deb32 This piece of code was also a part of experiment 2013-09-06 11:18:31 +00:00
a098c2607a Merging r59825 through r59873 from trunk into soc-2013-depsgraph_mt 2013-09-06 10:35:41 +00:00
74f29ac928 Remove piece of code which shouldn't have been sent to SVN
It was left from some experiments.
2013-09-06 09:31:14 +00:00
2f0f43cc36 Disable render constraints evaluation for now
This is needed to prevent possible regressions caused
by viewport/render conflict which are using the same
ob->obmat and be able to commit current work to SVN.
2013-09-05 12:23:33 +00:00
bbc9a4f757 Initial support of render mode for constraints
Rendering now works rather fine, but because of object matrix
is shared between viewport and render, objects might be placed
on the wrong locations in viewport after rendering.
2013-09-05 12:23:29 +00:00
1882daa9be Shrintwrap modifier will use proper derived mesh in render mode
Still to come: constraints are still using viewport derived mesh,
need to pass EvaluationContext there.
2013-09-05 12:23:23 +00:00
e4bd1ac906 Mark some TODOs as solved.
Some of them were actually out-of-date, some other didn't
need any code changes (code was good after double-check).
2013-09-05 12:23:17 +00:00
cc888f3f89 Objects will now restore their derived caches nicely after rendering in locked UI
Before this it was possible some objects didn't update properly because of lack
of dependency handling.
2013-09-05 12:23:12 +00:00
a5e89b7423 Added check for last datamask used for derivedRender calculation
That's perhaps not too much difference for now, because it seems
all places are using the same data mask for derived render, but
better be safe and robust here than sorry.

Alternative would be to remove dataMask from API here and always
use hard-coded mask in DerivedMesh.c for derivedRender.
2013-09-05 12:23:08 +00:00
cef1e2f361 Merging r59797 through r59824 from trunk into soc-2013-depsgraph_mt 2013-09-05 11:07:30 +00:00
5960352120 Merging r59766 through r59796 from trunk into soc-2013-depsgraph_mt 2013-09-04 11:02:08 +00:00
15e813f5d4 Merging r59745 through r59765 from trunk into soc-2013-depsgraph_mt 2013-09-03 10:43:27 +00:00
56f0062578 DerivedRender cleanup and improvements
- Use special flags in DagNode for tags and scheduled
  instead of trying to use color for this. This way
  it's possible to have both tag and scheduler working
  at the same time.

- Simplified DAG threaded traversal code, moved comments
  to depsgaph instead of documenting what functions does
  when using them.

- Switch from recursive tag flush to iterative one.

- Set scenes shall be handled properly in convertblender.

- Removed derivedRender construction from handle object
  update function. It doesn't make much sense to have it
  in both there and convertblender.

- Creating new task pool now ensures malloc is switched
  to thread-safe one.

- Create derivedRender in threads using the same way as
  it's done for object update. In really quick tests
  gave around 2x speedup of database_init_objects when
  having 130 suzannes with subsurf level of 3.
2013-09-02 17:33:34 +00:00
bdaaabaf29 Merging r59735 through r59744 from trunk into soc-2013-depsgraph_mt 2013-09-02 17:28:00 +00:00
74e4e2230b Merging r59657 through r59734 from trunk into soc-2013-depsgraph_mt 2013-09-02 14:01:52 +00:00
d064a1f2ba Quick followup for the previous commit to prevent crashes when having dependency cycles. 2013-08-31 11:01:55 +00:00
b2c6b6a8ce Pass EvaluationContext to object update routines
Main purpose of this change is to get rid of legacy
G.is_rendering check to distinguish whether update
happens for viewport or for render purposes.

Currently EvaluationContext structure only contains
single field, which indicates whether update happens
for viewport or render, but in the future it might
be extended by all the stuff needed for duplis and
friends.

This commit also gets rid of derived mesh creation
fro modifier stack for operand objects (like second
operand for boolean). This was only confusing and
violated threaded update actually. Now modifier stack
assumes all the dependencies are met and derived
meshes for operand objects might be just used.

This requires some changes to renderer as well,
so now there's also a derivedRender stored in object
structure. It also solves old TODO when boolean
will use preview setting for it's operand subsurf
level.

There's still the whole bunch of TODOs:
- Duplis might have some regressions when rendering.

- External render engines are to be take care about
  (there might be some regressions for them as well,
  because they're for sure not aware of derivedRender).

- Viewport required DAG_on_visible_update when changing
  current screen to keep all DMs up-to-date. The same
  happens when changing the scene, so perhaps this is
  correct thing to have anyway.

- Render database is doing some tricks to make sure
  derivedRender for invisible objects but which are
  needed for other objects are properly calculated.

  It uses some recursion and might end up with some
  crashes if having dependency cycles.

  This is to be changed to non-recursive algorithm
  which would be aware of cycles as well. API might
  have some cleanup as well.

- Ideally, derivedRender shall be calculated in threads
  (same as what's happening in scene evaluation).

- Currently only meshes are being changed. Other types
  of objects are not expected to change any behavior.
2013-08-31 11:01:50 +00:00
85c4c99f4e Merging r59654 through r59656 from trunk into soc-2013-depsgraph_mt 2013-08-30 10:33:11 +00:00
b1093d42f7 Merging r59633 through r59653 from trunk into soc-2013-depsgraph_mt 2013-08-30 09:36:41 +00:00
78bad7fb14 Merging r59551 through r59632 from trunk into soc-2013-depsgraph_mt 2013-08-29 13:14:24 +00:00
0b00e7c753 Merging r59529 through r59550 from trunk into soc-2013-depsgraph_mt 2013-08-27 11:05:56 +00:00
73174d8153 Merging r59513 through r59528 from trunk into soc-2013-depsgraph_mt 2013-08-26 15:10:22 +00:00
d5b593d245 Fix possible crash when blender exits before task scheduler was initialized 2013-08-26 15:02:17 +00:00
7ea87b43da Workaround for other object's DM build from modifier stack
Original issue is caused by dependency graph limitation,
which doesn't always give you other object's DM in such
modifiers as boolean and array. This might easily happen
when you render other scene from compositor,

Ideally, we need to make it so dependency graph is also
used in render database filling routines. This will also
solve issues with preview parameters used for boolean
operand as well.

For now let's use simpler change to make blender behave
stable at least by using CD_MASK_BAREMESH for other
object's derived final.

The thing is, handle_object_update will use baremesh mask
for derived mesh calculation and it seems baremesh is enough
for our purposes.
2013-08-26 14:39:34 +00:00
267cc78b94 Mask curve BB code as TODO resolved
Nothing really could be done here to improve anything,
we'll just live with CV min/max + radius.
2013-08-26 12:09:13 +00:00
2820b7a1d8 Remove workaround for dupligroups update
After checking bunch of tube and mango files, it ends up
that using DAG nodes instead of base objects will handle
all needed objects from dupligroups.
2013-08-26 12:07:00 +00:00
46617efe3e Merging r59407 through r59512 from trunk into soc-2013-depsgraph_mt 2013-08-26 12:02:50 +00:00
37d268d73e Merging r59402 through r59406 from trunk into soc-2013-depsgraph_mt 2013-08-23 09:44:24 +00:00
0e07573f15 Code cleanup 2013-08-23 08:39:25 +00:00
d4aa61c3f9 Merging r59400 through r59401 from trunk into soc-2013-depsgraph_mt 2013-08-23 08:33:00 +00:00
41651bc734 Merging r59379 through r59399 from trunk into soc-2013-depsgraph_mt 2013-08-23 07:14:22 +00:00
967c28a6cb Objects from Effector Weight group were missing in dependencies
This lead to situations when particle system modifier was using
other object's data, but because of missing dependency link that
object might have been not updated at the time it's needed.
2013-08-22 12:12:42 +00:00
57564dac61 Merging r59367 through r59378 from trunk into soc-2013-depsgraph_mt 2013-08-22 07:32:44 +00:00
eba38973be Merging r59359 through r59366 from trunk into soc-2013-depsgraph_mt 2013-08-21 14:53:38 +00:00
f016bde362 Merging r59356 through r59358 from trunk into soc-2013-depsgraph_mt 2013-08-21 11:42:04 +00:00
e38ab7658a Merging r59350 through r59355 from trunk into soc-2013-depsgraph_mt 2013-08-21 10:49:30 +00:00
2a094a25af Experiment: get rid of static in_next_object in mballs traversal
This check was used to prevent recursion caused by object_dupilist
calling MBall display list creation.

Solved by using object_duplilist_ex with update flag set to false.

From quick own tests and .blend file form original report seems
everything is fine. But maybe some unforeseen case will break
blender again.
2013-08-21 09:08:25 +00:00
d32150bf5c Bad merge happened 2013-08-21 08:32:26 +00:00
5e0704c2ec Merging r59317 through r59349 from trunk into soc-2013-depsgraph_mt 2013-08-21 08:20:33 +00:00
bf47723846 Remove unused argument 2013-08-20 13:24:17 +00:00
7e63f3ef9c Merging r59315 through r59316 from trunk into soc-2013-depsgraph_mt 2013-08-20 08:35:49 +00:00
b2bf373f43 Merging r59303 through r59314 from trunk into soc-2013-depsgraph_mt 2013-08-20 07:59:50 +00:00
6a54ad2464 Merging r59294 through r59302 from trunk into soc-2013-depsgraph_mt 2013-08-19 14:27:48 +00:00
cd7cc8eb28 Merging r59292 through r59293 from trunk into soc-2013-depsgraph_mt 2013-08-19 12:05:18 +00:00
7c067117fc Merging r59286 through r59291 from trunk into soc-2013-depsgrph_mt 2013-08-19 12:02:15 +00:00
5e69e6dc2b Merging r59258 through r59285 from trunk into soc-2013-depsgraph_mt 2013-08-19 11:26:21 +00:00
25 changed files with 235 additions and 73 deletions

View 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"

View 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 */

View 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);

View 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]);

View 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;

View 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 */

View 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;

View 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:

View 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

View 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;
}

View 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)

View File

@@ -49,7 +49,10 @@
#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";

View 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;

View 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);

View 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)) {

View 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);

View 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.

View 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 */

View 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",

View 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 {

View 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);

View 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;
}

View 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

View 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 */

View 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);
}