linked duplicate objects - issues with selection in edit mode #65778

Closed
opened 2019-06-13 11:03:25 +02:00 by Marcin Twarowski · 18 comments

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: 2404220e80

Short description of error
linked_duplicate_selection_bug.blend

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:

Desktop 2019.06.13 - 10.51.57.01.avi

**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: `2404220e80` **Short description of error** [linked_duplicate_selection_bug.blend](https://archive.blender.org/developer/F7101439/linked_duplicate_selection_bug.blend) 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: [Desktop 2019.06.13 - 10.51.57.01.avi](https://archive.blender.org/developer/F7101479/Desktop_2019.06.13_-_10.51.57.01.avi)

Added subscriber: @MarcinTwarowski

Added subscriber: @MarcinTwarowski

Added subscriber: @tomjk

Added subscriber: @tomjk

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

  2. 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 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.) 2. 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.

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

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

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

Added subscribers: @fclem, @ideasman42, @brecht, @dfelinto

Added subscribers: @fclem, @ideasman42, @brecht, @dfelinto

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 @ideasman42 @fclem @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.

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. 2) 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 @ideasman42 @fclem @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.

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.

Added subscriber: @Jeroen-Bakker

Added subscriber: @Jeroen-Bakker

@Jeroen-Bakker 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.

@Jeroen-Bakker 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.

Added subscribers: @Sergey, @mano-wii

Added subscribers: @Sergey, @mano-wii

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)) {
     error_libdata();
     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, any idea why this is happening?

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)) { error_libdata(); 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, 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 @fclem, is it team work time again? ;)

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 @fclem, is it team work time again? ;)

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

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

@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: P1020: (An Untitled Masterwork)

diff --git a/source/blender/blenkernel/BKE_object.h b/source/blender/blenkernel/BKE_object.h
index fdd61580d9e..f59bf3579be 100644
--- a/source/blender/blenkernel/BKE_object.h
+++ b/source/blender/blenkernel/BKE_object.h
@@ -295,6 +295,7 @@ void BKE_object_eval_transform_all(struct Depsgraph *depsgraph,
 
 void BKE_object_eval_update_shading(struct Depsgraph *depsgraph, struct Object *object);
 void BKE_object_data_select_update(struct Depsgraph *depsgraph, struct ID *object_data);
+void BKE_object_select_update(struct Depsgraph *depsgraph, struct Object *object);
 
 void BKE_object_eval_eval_base_flags(struct Depsgraph *depsgraph,
                                      struct Scene *scene,
diff --git a/source/blender/blenkernel/intern/object_update.c b/source/blender/blenkernel/intern/object_update.c
index 6a6adb82225..2bb06c86120 100644
--- a/source/blender/blenkernel/intern/object_update.c
+++ b/source/blender/blenkernel/intern/object_update.c
@@ -393,6 +393,12 @@ void BKE_object_data_select_update(Depsgraph *depsgraph, ID *object_data)
   }
 }
 
+void BKE_object_select_update(Depsgraph *depsgraph, Object *object)
+{
+  DEG_debug_print_eval(depsgraph, __func__, object->id.name, object);
+  BKE_object_data_select_update(depsgraph, object->data);
+}
+
 void BKE_object_eval_eval_base_flags(Depsgraph *depsgraph,
                                      Scene *scene,
                                      const int view_layer_index,
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc b/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc
index e65dd3b4560..9b02f231be4 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc
@@ -1207,6 +1207,11 @@ void DepsgraphNodeBuilder::build_object_data_geometry(Object *object, bool is_ob
   build_object_pointcache(object);
   /* Geometry. */
   build_object_data_geometry_datablock((ID *)object->data, is_object_visible);
+  /* Batch cache. */
+  add_operation_node(&object->id,
+                     NodeType::BATCH_CACHE,
+                     OperationCode::GEOMETRY_SELECT_UPDATE,
+                     function_bind(BKE_object_select_update, _1, object_cow));
 }
 
 void DepsgraphNodeBuilder::build_object_data_geometry_datablock(ID *obdata, bool is_object_visible)
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc
index c7f6116e81d..8f85640bb4d 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc
@@ -1988,10 +1988,16 @@ void DepsgraphRelationBuilder::build_object_data_geometry(Object *object)
     }
   }
   /* Syncronization back to original object. */
-  ComponentKey final_geometry_jey(&object->id, NodeType::GEOMETRY);
+  ComponentKey final_geometry_key(&object->id, NodeType::GEOMETRY);
   OperationKey synchronize_key(
       &object->id, NodeType::SYNCHRONIZATION, OperationCode::SYNCHRONIZE_TO_ORIGINAL);
-  add_relation(final_geometry_jey, synchronize_key, "Synchronize to Original");
+  add_relation(final_geometry_key, synchronize_key, "Synchronize to Original");
+  /* Batch cache. */
+  OperationKey object_data_select_key(
+      obdata, NodeType::BATCH_CACHE, OperationCode::GEOMETRY_SELECT_UPDATE);
+  OperationKey object_select_key(
+      &object->id, NodeType::BATCH_CACHE, OperationCode::GEOMETRY_SELECT_UPDATE);
+  add_relation(object_data_select_key, object_select_key, "Data Selection -> Object Selection");
 }
 
 void DepsgraphRelationBuilder::build_object_data_geometry_datablock(ID *obdata)

@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: [P1020: (An Untitled Masterwork)](https://archive.blender.org/developer/P1020.txt) ``` diff --git a/source/blender/blenkernel/BKE_object.h b/source/blender/blenkernel/BKE_object.h index fdd61580d9e..f59bf3579be 100644 --- a/source/blender/blenkernel/BKE_object.h +++ b/source/blender/blenkernel/BKE_object.h @@ -295,6 +295,7 @@ void BKE_object_eval_transform_all(struct Depsgraph *depsgraph, void BKE_object_eval_update_shading(struct Depsgraph *depsgraph, struct Object *object); void BKE_object_data_select_update(struct Depsgraph *depsgraph, struct ID *object_data); +void BKE_object_select_update(struct Depsgraph *depsgraph, struct Object *object); void BKE_object_eval_eval_base_flags(struct Depsgraph *depsgraph, struct Scene *scene, diff --git a/source/blender/blenkernel/intern/object_update.c b/source/blender/blenkernel/intern/object_update.c index 6a6adb82225..2bb06c86120 100644 --- a/source/blender/blenkernel/intern/object_update.c +++ b/source/blender/blenkernel/intern/object_update.c @@ -393,6 +393,12 @@ void BKE_object_data_select_update(Depsgraph *depsgraph, ID *object_data) } } +void BKE_object_select_update(Depsgraph *depsgraph, Object *object) +{ + DEG_debug_print_eval(depsgraph, __func__, object->id.name, object); + BKE_object_data_select_update(depsgraph, object->data); +} + void BKE_object_eval_eval_base_flags(Depsgraph *depsgraph, Scene *scene, const int view_layer_index, diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc b/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc index e65dd3b4560..9b02f231be4 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc @@ -1207,6 +1207,11 @@ void DepsgraphNodeBuilder::build_object_data_geometry(Object *object, bool is_ob build_object_pointcache(object); /* Geometry. */ build_object_data_geometry_datablock((ID *)object->data, is_object_visible); + /* Batch cache. */ + add_operation_node(&object->id, + NodeType::BATCH_CACHE, + OperationCode::GEOMETRY_SELECT_UPDATE, + function_bind(BKE_object_select_update, _1, object_cow)); } void DepsgraphNodeBuilder::build_object_data_geometry_datablock(ID *obdata, bool is_object_visible) diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc index c7f6116e81d..8f85640bb4d 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc @@ -1988,10 +1988,16 @@ void DepsgraphRelationBuilder::build_object_data_geometry(Object *object) } } /* Syncronization back to original object. */ - ComponentKey final_geometry_jey(&object->id, NodeType::GEOMETRY); + ComponentKey final_geometry_key(&object->id, NodeType::GEOMETRY); OperationKey synchronize_key( &object->id, NodeType::SYNCHRONIZATION, OperationCode::SYNCHRONIZE_TO_ORIGINAL); - add_relation(final_geometry_jey, synchronize_key, "Synchronize to Original"); + add_relation(final_geometry_key, synchronize_key, "Synchronize to Original"); + /* Batch cache. */ + OperationKey object_data_select_key( + obdata, NodeType::BATCH_CACHE, OperationCode::GEOMETRY_SELECT_UPDATE); + OperationKey object_select_key( + &object->id, NodeType::BATCH_CACHE, OperationCode::GEOMETRY_SELECT_UPDATE); + add_relation(object_data_select_key, object_select_key, "Data Selection -> Object Selection"); } void DepsgraphRelationBuilder::build_object_data_geometry_datablock(ID *obdata) ```

I can confirm your patch works.

I can confirm your patch works.

This issue was referenced by 26e6bb3fa3

This issue was referenced by 26e6bb3fa371047e6d8d6f920128af1bcd0cfe65

Changed status from 'Open' to: 'Resolved'

Changed status from 'Open' to: 'Resolved'
Sergey Sharybin self-assigned this 2019-07-02 15:18:44 +02:00
Sign in to join this conversation.
No Label
Interest
Alembic
Interest
Animation & Rigging
Interest
Asset Browser
Interest
Asset Browser Project Overview
Interest
Audio
Interest
Automated Testing
Interest
Blender Asset Bundle
Interest
BlendFile
Interest
Collada
Interest
Compatibility
Interest
Compositing
Interest
Core
Interest
Cycles
Interest
Dependency Graph
Interest
Development Management
Interest
EEVEE
Interest
EEVEE & Viewport
Interest
Freestyle
Interest
Geometry Nodes
Interest
Grease Pencil
Interest
ID Management
Interest
Images & Movies
Interest
Import Export
Interest
Line Art
Interest
Masking
Interest
Metal
Interest
Modeling
Interest
Modifiers
Interest
Motion Tracking
Interest
Nodes & Physics
Interest
OpenGL
Interest
Overlay
Interest
Overrides
Interest
Performance
Interest
Physics
Interest
Pipeline, Assets & IO
Interest
Platforms, Builds & Tests
Interest
Python API
Interest
Render & Cycles
Interest
Render Pipeline
Interest
Sculpt, Paint & Texture
Interest
Text Editor
Interest
Translations
Interest
Triaging
Interest
Undo
Interest
USD
Interest
User Interface
Interest
UV Editing
Interest
VFX & Video
Interest
Video Sequencer
Interest
Virtual Reality
Interest
Vulkan
Interest
Wayland
Interest
Workbench
Interest: X11
Legacy
Blender 2.8 Project
Legacy
Milestone 1: Basic, Local Asset Browser
Legacy
OpenGL Error
Meta
Good First Issue
Meta
Papercut
Meta
Retrospective
Meta
Security
Module
Animation & Rigging
Module
Core
Module
Development Management
Module
EEVEE & Viewport
Module
Grease Pencil
Module
Modeling
Module
Nodes & Physics
Module
Pipeline, Assets & IO
Module
Platforms, Builds & Tests
Module
Python API
Module
Render & Cycles
Module
Sculpt, Paint & Texture
Module
Triaging
Module
User Interface
Module
VFX & Video
Platform
FreeBSD
Platform
Linux
Platform
macOS
Platform
Windows
Priority
High
Priority
Low
Priority
Normal
Priority
Unbreak Now!
Status
Archived
Status
Confirmed
Status
Duplicate
Status
Needs Info from Developers
Status
Needs Information from User
Status
Needs Triage
Status
Resolved
Type
Bug
Type
Design
Type
Known Issue
Type
Patch
Type
Report
Type
To Do
No Milestone
No project
No Assignees
8 Participants
Notifications
Due Date
The due date is invalid or out of range. Please use the format 'yyyy-mm-dd'.

No due date set.

Dependencies

No dependencies set.

Reference: blender/blender#65778
No description provided.