Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Sharybin <sergey.vfx@gmail.com>2017-12-01 13:39:42 +0300
committerSergey Sharybin <sergey.vfx@gmail.com>2017-12-01 13:40:50 +0300
commit2ae709d282a9e348f198b4c7fe265e83fc125765 (patch)
treeb3f21de1c52cc7c968841d3fc07f8035a36c8683 /source/blender/editors/transform
parent0591fb17e93517d849ab6cb13f2028cff0c5a540 (diff)
Transform: Use new DEG query API to see what's being affected by a changing object
This avoids us from directly calling object update, and doing other type of update flushing. Prepares us to get rid of Object->recalc flags.
Diffstat (limited to 'source/blender/editors/transform')
-rw-r--r--source/blender/editors/transform/transform_conversions.c150
1 files changed, 71 insertions, 79 deletions
diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c
index b59c6a70475..5233bdf91e1 100644
--- a/source/blender/editors/transform/transform_conversions.c
+++ b/source/blender/editors/transform/transform_conversions.c
@@ -119,6 +119,7 @@
#include "DEG_depsgraph.h"
#include "DEG_depsgraph_build.h"
+#include "DEG_depsgraph_query.h"
#include "transform.h"
#include "bmesh.h"
@@ -5528,6 +5529,37 @@ static void ObjectToTransData(TransInfo *t, TransData *td, Object *ob)
}
}
+static void trans_object_base_deps_flag_prepare(ViewLayer *view_layer)
+{
+ for (Base *base = view_layer->object_bases.first; base; base = base->next) {
+ base->object->id.tag &= ~LIB_TAG_DOIT;
+ }
+}
+
+static void set_trans_object_base_deps_flag_cb(ID *id, void *UNUSED(user_data))
+{
+ /* Here we only handle object IDs. */
+ if (GS(id->name) != ID_OB) {
+ return;
+ }
+ id->tag |= LIB_TAG_DOIT;
+}
+
+static void flush_trans_object_base_deps_flag(Depsgraph *depsgraph, Object *object)
+{
+ object->id.tag |= LIB_TAG_DOIT;
+ DEG_foreach_dependent_ID(depsgraph, &object->id,
+ set_trans_object_base_deps_flag_cb, NULL);
+}
+
+static void trans_object_base_deps_flag_finish(ViewLayer *view_layer)
+{
+ for (Base *base = view_layer->object_bases.first; base; base = base->next) {
+ if (base->object->id.tag & LIB_TAG_DOIT) {
+ base->flag_legacy |= BA_SNAP_FIX_DEPS_FIASCO;
+ }
+ }
+}
/* sets flags in Bases to define whether they take part in transform */
/* it deselects Bases, so we have to call the clear function always after */
@@ -5538,47 +5570,30 @@ static void set_trans_object_base_flags(TransInfo *t)
ViewLayer *view_layer = t->view_layer;
Scene *scene = t->scene;
Depsgraph *depsgraph = BKE_scene_get_depsgraph(scene, view_layer, true);
-
- /*
- * if Base selected and has parent selected:
- * base->flag_legacy = BA_WAS_SEL
+ /* NOTE: if Base selected and has parent selected:
+ * base->flag_legacy = BA_WAS_SEL
*/
- Base *base;
-
- /* don't do it if we're not actually going to recalculate anything */
- if (t->mode == TFM_DUMMY)
+ /* Don't do it if we're not actually going to recalculate anything. */
+ if (t->mode == TFM_DUMMY) {
return;
-
- /* makes sure base flags and object flags are identical */
+ }
+ /* Makes sure base flags and object flags are identical. */
BKE_scene_base_flag_to_objects(t->view_layer);
-
/* Make sure depsgraph is here. */
DEG_graph_relations_update(depsgraph, bmain, scene, view_layer);
-
- /* handle pending update events, otherwise they got copied below */
- EvaluationContext eval_ctx;
- DEG_evaluation_context_init_from_scene(&eval_ctx,
- t->scene, t->view_layer, t->engine_type,
- DAG_EVAL_VIEWPORT);
- for (base = view_layer->object_bases.first; base; base = base->next) {
- if (base->object->recalc & OB_RECALC_ALL) {
- /* TODO(sergey): Ideally, it's not needed. */
- BKE_object_handle_update(&eval_ctx, t->scene, base->object);
- }
- }
-
- for (base = view_layer->object_bases.first; base; base = base->next) {
+ /* Clear all flags we need. It will be used to detect dependencies. */
+ trans_object_base_deps_flag_prepare(view_layer);
+ /* Traverse all bases and set all possible flags. */
+ for (Base *base = view_layer->object_bases.first; base; base = base->next) {
base->flag_legacy &= ~BA_WAS_SEL;
-
if (TESTBASELIB_BGMODE(base)) {
Object *ob = base->object;
Object *parsel = ob->parent;
-
- /* if parent selected, deselect */
- while (parsel) {
+ /* If parent selected, deselect. */
+ while (parsel != NULL) {
if (parsel->base_flag & BASE_SELECTED) {
Base *parbase = BKE_view_layer_base_find(view_layer, parsel);
- if (parbase) { /* in rare cases this can fail */
+ if (parbase != NULL) { /* in rare cases this can fail */
if (TESTBASELIB_BGMODE(parbase)) {
break;
}
@@ -5586,9 +5601,8 @@ static void set_trans_object_base_flags(TransInfo *t)
}
parsel = parsel->parent;
}
-
- if (parsel) {
- /* rotation around local centers are allowed to propagate */
+ if (parsel != NULL) {
+ /* Rotation around local centers are allowed to propagate. */
if ((t->around == V3D_AROUND_LOCAL_ORIGINS) &&
(t->mode == TFM_ROTATION || t->mode == TFM_TRACKBALL))
{
@@ -5599,20 +5613,13 @@ static void set_trans_object_base_flags(TransInfo *t)
base->flag_legacy |= BA_WAS_SEL;
}
}
- DEG_id_tag_update(&ob->id, OB_RECALC_OB);
- }
- }
-
- /* all recalc flags get flushed to all layers, so a layer flip later on works fine */
- DEG_graph_flush_update(bmain, depsgraph);
-
- /* and we store them temporal in base (only used for transform code) */
- /* this because after doing updates, the object->recalc is cleared */
- for (base = view_layer->object_bases.first; base; base = base->next) {
- if (base->object->recalc & (OB_RECALC_OB | OB_RECALC_DATA)) {
- base->flag_legacy |= BA_SNAP_FIX_DEPS_FIASCO;
+ flush_trans_object_base_deps_flag(depsgraph, ob);
}
}
+ /* Store temporary bits in base indicating that base is being modified
+ * (directly or indirectly) by transforming objects.
+ */
+ trans_object_base_deps_flag_finish(view_layer);
}
static bool mark_children(Object *ob)
@@ -5633,32 +5640,28 @@ static bool mark_children(Object *ob)
static int count_proportional_objects(TransInfo *t)
{
int total = 0;
- /* TODO(sergey): Get rid of global, use explicit main. */
- Main *bmain = G.main;
ViewLayer *view_layer = t->view_layer;
Scene *scene = t->scene;
Depsgraph *depsgraph = BKE_scene_get_depsgraph(scene, view_layer, true);
- Base *base;
-
- /* rotations around local centers are allowed to propagate, so we take all objects */
+ /* Clear all flags we need. It will be used to detect dependencies. */
+ trans_object_base_deps_flag_prepare(view_layer);
+ /* Rotations around local centers are allowed to propagate, so we take all objects. */
if (!((t->around == V3D_AROUND_LOCAL_ORIGINS) &&
(t->mode == TFM_ROTATION || t->mode == TFM_TRACKBALL)))
{
- /* mark all parents */
- for (base = view_layer->object_bases.first; base; base = base->next) {
+ /* Mark all parents. */
+ for (Base *base = view_layer->object_bases.first; base; base = base->next) {
if (TESTBASELIB_BGMODE(base)) {
Object *parent = base->object->parent;
-
/* flag all parents */
- while (parent) {
+ while (parent != NULL) {
parent->flag |= BA_TRANSFORM_PARENT;
parent = parent->parent;
}
}
}
-
- /* mark all children */
- for (base = view_layer->object_bases.first; base; base = base->next) {
+ /* Mark all children. */
+ for (Base *base = view_layer->object_bases.first; base; base = base->next) {
/* all base not already selected or marked that is editable */
if ((base->object->flag & (BA_TRANSFORM_CHILD | BA_TRANSFORM_PARENT)) == 0 &&
(base->flag & BASE_SELECTED) == 0 &&
@@ -5668,35 +5671,24 @@ static int count_proportional_objects(TransInfo *t)
}
}
}
-
- for (base = view_layer->object_bases.first; base; base = base->next) {
+ /* Flush changed flags to all dependencies. */
+ for (Base *base = view_layer->object_bases.first; base; base = base->next) {
Object *ob = base->object;
-
- /* if base is not selected, not a parent of selection or not a child of selection and it is editable */
+ /* If base is not selected, not a parent of selection or not a child of
+ * selection and it is editable.
+ */
if ((ob->flag & (BA_TRANSFORM_CHILD | BA_TRANSFORM_PARENT)) == 0 &&
(base->flag & BASE_SELECTED) == 0 &&
(BASE_EDITABLE_BGMODE(base)))
{
-
- DEG_id_tag_update(&ob->id, OB_RECALC_OB);
-
+ flush_trans_object_base_deps_flag(depsgraph, ob);
total += 1;
}
}
-
-
- /* all recalc flags get flushed to all layers, so a layer flip later on works fine */
- DEG_graph_relations_update(depsgraph, bmain, scene, view_layer);
- DEG_graph_flush_update(bmain, depsgraph);
-
- /* and we store them temporal in base (only used for transform code) */
- /* this because after doing updates, the object->recalc is cleared */
- for (base = view_layer->object_bases.first; base; base = base->next) {
- if (base->object->recalc & (OB_RECALC_OB | OB_RECALC_DATA)) {
- base->flag_legacy |= BA_SNAP_FIX_DEPS_FIASCO;
- }
- }
-
+ /* Store temporary bits in base indicating that base is being modified
+ * (directly or indirectly) by transforming objects.
+ */
+ trans_object_base_deps_flag_finish(view_layer);
return total;
}
@@ -8286,7 +8278,7 @@ void createTransData(bContext *C, TransInfo *t)
RegionView3D *rv3d = t->ar->regiondata;
if ((rv3d->persp == RV3D_CAMOB) && v3d->camera) {
/* we could have a flag to easily check an object is being transformed */
- if (v3d->camera->recalc) {
+ if (v3d->camera->id.tag & LIB_TAG_DOIT) {
t->flag |= T_CAMERA;
}
}