Page MenuHome

linked duplicate objects - issues with selection in edit mode
Closed, ResolvedPublic


System Information
Operating system: Windows-10-10.0.16299 64 Bits
Graphics card: GeForce GTX 1080/PCIe/SSE2 NVIDIA Corporation 4.5.0 NVIDIA 419.67

Blender Version
Broken: version: 2.80 (sub 74), branch: blender2.7, commit date: 2019-06-12 18:00, hash: rB2404220e80a9

Short description of error

There are problems with selection when you edit two objects at the same time in edit mode: the original object and a linked duplicate. See the video:

Related Objects

Event Timeline

I see two things here:

  1. You want to edit the two linked objects at the same time, but you can only edit one the active one.

I don't think this rises to the level of a bug, but a feature request. Ideally you could select any element from the inactive object and it would instantly become the active object.
(It might also be nice to be able to work on any feature from both object, but I think the ability to perform operations such as rotate and scale on selections across multiple instances of the same mesh at the same time might introduce complexity.)

  1. The selection display falls out of sync between instances until you perform an operation.

I can confirm this. It happens either if you have one or multiple instances selected, all other instances enter edit mode then don't sync selections properly.

I really only meant that selections don't sync properly.

Ah, ok then. Yep that's a bug.

I can confirm this bug, but there are two scenarios:

  1. You are only editing one of the objects.

In this case I think we shouldn't draw the "edit mode engine" layer for the dupli objects. So the bug reported here won't even be a problem.

  1. You are editing both objects at the same time (multi-object editing):

In this case, in the ideal world, we should be able to select, snap, ... both of them, and be ready to some really unexpected effects when e.g. knife cutting across them both.
However since at the moment we iterate over "unique data" most of the time, I think it is no surprise this doesn't work well.

Any thoughts gentlemen? cc @Campbell Barton (campbellbarton) @Clément Foucault (fclem) @Brecht Van Lommel (brecht)

My short-term proposal is to disable drawing of the non-object mode engines for dupli objects. And in the future we can have (2) implemented.

Also note that the bug is real and it only happens for meshes - curves, lattice, armatures, they are all good.
That said I stick to what I said, despite what we had in 2.79 I think we should NOT draw edit data for the the dupli data of the other objects.

@Jeroen Bakker (jbakker) looked into a bug related to this, but I can't find it quickly now. Apparently it was not trivial to make it work well with modifiers.

I don't care too much about drawing the edit mode cage for other linked duplicates, it is somewhat confusing. It has just worked like that for a very long time.

I investigated this bug and realized that the problem involves two areas.
The first is with the BKE_view_layer_array_from_bases_in_edit_mode call.
It is behaving like BKE_view_layer_array_from_bases_in_edit_mode_unique_data since linked objects are not marked as being in edit mode.
This can be solved by moving these lines:

diff --git a/source/blender/editors/object/object_edit.c b/source/blender/editors/object/object_edit.c
index a390cf67cf5..4470ab5ced7 100644
--- a/source/blender/editors/object/object_edit.c
+++ b/source/blender/editors/object/object_edit.c
@@ -567,11 +567,6 @@ bool ED_object_editmode_enter_ex(Main *bmain, Scene *scene, Object *ob, int flag
     return false;
-  /* this checks actual object->data, for cases when other scenes have it in editmode context */
-  if (BKE_object_is_in_editmode(ob)) {
-    return true;
-  }
   if (BKE_object_obdata_is_libdata(ob)) {
     return false;
@@ -581,6 +576,11 @@ bool ED_object_editmode_enter_ex(Main *bmain, Scene *scene, Object *ob, int flag
   ob->mode = OB_MODE_EDIT;
+  /* this checks actual object->data, for cases when other scenes have it in editmode context */
+  if (BKE_object_is_in_editmode(ob)) {
+    return true;
+  }
   if (ob->type == OB_MESH) {
     BMEditMesh *em;
     ok = 1;

The second problem is the DEG_id_tag_update(vc.obedit->data, ID_RECALC_SELECT) call in EDBM_select_pick.
It looks like some relation is missing because only one evaluated mesh is flagged as dirty in the DRW_mesh_batch_cache_dirty_tag.
Ideally, each of the meshes of the linked objects should be flagged as dirty.

@Sergey Sharybin (sergey), any idea why this is happening?

Selection update is tagging the input mesh via BKE_object_data_select_update(). There is only one such mesh.

My speculation is that it is something in the object level which attempts to do early exit or something like this based on batch's batch_ready flags.

Can not tell any more details, because i am not sure about specifics of how edit mode batches are shared and what is supposed to happen when.
Hey @Clément Foucault (fclem), is it team work time again? ;)

@Sergey Sharybin (sergey) From my observation, in the case of linked object data, Mesh* (ob->data) are shared in object mode but are not in edit mode. Which seems strange to me. When objects use modifiers it makes sense.

As @Germano Cavalcante (mano-wii) notices It is indeed a problem of tagging as only one mesh is being tagged. Or maybe we could remove the need for another Mesh* in the first place.

@Clément Foucault (fclem), well, there is only one mesh to tag.. Anyway, design details which we can go into another time.
If my understanding is correct this patch should fix it, but i wouldn't mind if you give it an extra look/test:

1diff --git a/source/blender/blenkernel/BKE_object.h b/source/blender/blenkernel/BKE_object.h
2index fdd61580d9e..f59bf3579be 100644
3--- a/source/blender/blenkernel/BKE_object.h
4+++ b/source/blender/blenkernel/BKE_object.h
5@@ -295,6 +295,7 @@ void BKE_object_eval_transform_all(struct Depsgraph *depsgraph,
7 void BKE_object_eval_update_shading(struct Depsgraph *depsgraph, struct Object *object);
8 void BKE_object_data_select_update(struct Depsgraph *depsgraph, struct ID *object_data);
9+void BKE_object_select_update(struct Depsgraph *depsgraph, struct Object *object);
11 void BKE_object_eval_eval_base_flags(struct Depsgraph *depsgraph,
12 struct Scene *scene,
13diff --git a/source/blender/blenkernel/intern/object_update.c b/source/blender/blenkernel/intern/object_update.c
14index 6a6adb82225..2bb06c86120 100644
15--- a/source/blender/blenkernel/intern/object_update.c
16+++ b/source/blender/blenkernel/intern/object_update.c
17@@ -393,6 +393,12 @@ void BKE_object_data_select_update(Depsgraph *depsgraph, ID *object_data)
18 }
19 }
21+void BKE_object_select_update(Depsgraph *depsgraph, Object *object)
23+ DEG_debug_print_eval(depsgraph, __func__, object->, object);
24+ BKE_object_data_select_update(depsgraph, object->data);
27 void BKE_object_eval_eval_base_flags(Depsgraph *depsgraph,
28 Scene *scene,
29 const int view_layer_index,
30diff --git a/source/blender/depsgraph/intern/builder/ b/source/blender/depsgraph/intern/builder/
31index e65dd3b4560..9b02f231be4 100644
32--- a/source/blender/depsgraph/intern/builder/
33+++ b/source/blender/depsgraph/intern/builder/
34@@ -1207,6 +1207,11 @@ void DepsgraphNodeBuilder::build_object_data_geometry(Object *object, bool is_ob
35 build_object_pointcache(object);
36 /* Geometry. */
37 build_object_data_geometry_datablock((ID *)object->data, is_object_visible);
38+ /* Batch cache. */
39+ add_operation_node(&object->id,
40+ NodeType::BATCH_CACHE,
42+ function_bind(BKE_object_select_update, _1, object_cow));
43 }
45 void DepsgraphNodeBuilder::build_object_data_geometry_datablock(ID *obdata, bool is_object_visible)
46diff --git a/source/blender/depsgraph/intern/builder/ b/source/blender/depsgraph/intern/builder/
47index c7f6116e81d..8f85640bb4d 100644
48--- a/source/blender/depsgraph/intern/builder/
49+++ b/source/blender/depsgraph/intern/builder/
50@@ -1988,10 +1988,16 @@ void DepsgraphRelationBuilder::build_object_data_geometry(Object *object)
51 }
52 }
53 /* Syncronization back to original object. */
54- ComponentKey final_geometry_jey(&object->id, NodeType::GEOMETRY);
55+ ComponentKey final_geometry_key(&object->id, NodeType::GEOMETRY);
56 OperationKey synchronize_key(
57 &object->id, NodeType::SYNCHRONIZATION, OperationCode::SYNCHRONIZE_TO_ORIGINAL);
58- add_relation(final_geometry_jey, synchronize_key, "Synchronize to Original");
59+ add_relation(final_geometry_key, synchronize_key, "Synchronize to Original");
60+ /* Batch cache. */
61+ OperationKey object_data_select_key(
62+ obdata, NodeType::BATCH_CACHE, OperationCode::GEOMETRY_SELECT_UPDATE);
63+ OperationKey object_select_key(
64+ &object->id, NodeType::BATCH_CACHE, OperationCode::GEOMETRY_SELECT_UPDATE);
65+ add_relation(object_data_select_key, object_select_key, "Data Selection -> Object Selection");
66 }
68 void DepsgraphRelationBuilder::build_object_data_geometry_datablock(ID *obdata)

I can confirm your patch works.