Page MenuHome

Loop selection corner case
Closed, ResolvedPublicBUG

Description

Blender Version
Broken: 2.93 master
Worked: never?

Short description of error

(pun almost intended)

In the left image, alt-clicking the highlighted edge only selects that edge, whereas alt-clicking any other edge along that loop selects the whole loop (including that edge). However, if faces are extruded to make the mesh in the right image, then alt-clicking that edge selects the whole loop.

Note that even though the edge does border an n-gon, there's still a clearly defined direction for the loop as the edge leads to a 4-pole.

Event Timeline

Germano Cavalcante (mano-wii) changed the task status from Needs Triage to Confirmed.Jan 21 2021, 3:37 PM
Germano Cavalcante (mano-wii) changed the subtype of this task from "Report" to "Bug".

Thanks for the report I can confirm the problem.
Although there is an n-gon, in fact the behavior seems strange.
This is related to rB01b3e9cc9fdd: loopwalker support for selecting the sides of ngons see: wiki.blender.

I looked into this and found a "fix" (I am not sure if it has any side effects):

1diff --git a/source/blender/bmesh/intern/bmesh_walkers_impl.c b/source/blender/bmesh/intern/bmesh_walkers_impl.c
2index 7d56e560275..0a9f2d60cab 100644
3--- a/source/blender/bmesh/intern/bmesh_walkers_impl.c
4+++ b/source/blender/bmesh/intern/bmesh_walkers_impl.c
5@@ -862,32 +862,7 @@ static void bmw_EdgeLoopWalker_begin(BMWalker *walker, void *data)
6 lwalk->lastv = lwalk->startv = v;
7 lwalk->is_boundary = BM_edge_is_boundary(e);
8 lwalk->is_single = (lwalk->is_boundary && bm_edge_is_single(e));
9-
10- /* could also check that vertex*/
11- if ((lwalk->is_boundary == false) && (vert_edge_count[0] == 3 || vert_edge_count[1] == 3)) {
12- BMIter iter;
13- BMFace *f_iter;
14- BMFace *f_best = NULL;
15-
16- BM_ITER_ELEM (f_iter, &iter, e, BM_FACES_OF_EDGE) {
17- if (f_best == NULL || f_best->len < f_iter->len) {
18- f_best = f_iter;
19- }
20- }
21-
22- if (f_best) {
23- /* only use hub selection for 5+ sides else this could
24- * conflict with normal edge loop selection. */
25- lwalk->f_hub = f_best->len > 4 ? f_best : NULL;
26- }
27- else {
28- /* edge doesn't have any faces connected to it */
29- lwalk->f_hub = NULL;
30- }
31- }
32- else {
33- lwalk->f_hub = NULL;
34- }
35+ lwalk->f_hub = NULL;
36
37 /* rewind */
38 while ((owalk_pt = BMW_current_state(walker))) {

That if that I removed gets executed when the lower edge with the n-gon in the example is (loop) selected. Later in the step function, we only walk along the n-gon if the next vertex has exactly 3 neighbours. when it does not, the iteration ends. This seems very strange.

To summarize: I don't know what the use of the f_hub is or what the if in the bmw_EdgeLoopWalker_begin function should do. Sadly the comment on line 10 in the diff seems to incomplete. Removing that if (and therefore the use of f_hub) seems to fix the problem.

@Campbell Barton (campbellbarton) what are your thoughts on this? Do you know what that code is for?

@Germano Cavalcante (mano-wii) & @Falk David (filedescriptor), thanks for looking into this.

The f_hub was introduced in rB01b3e9cc9fdd: loopwalker support for selecting the sides of ngons see: wiki.blender..

This is the image linked (recovered from the archive)

although the image along is still not enough to explain the behavior.

Committed more detailed description of this feature rB1e355b0992a6: Docs: add diagrams describing the purpose of BMwEdgeLoopWalker.f_hub to avoid this kind of confusion in the future.