GPv3: Select Alternate #109240
|
@ -288,14 +288,8 @@ void select_alternate(bke::CurvesGeometry &curves, const bool deselect_ends)
|
|||
continue;
|
||||
Lorenzo-Carpaneto marked this conversation as resolved
Outdated
|
||||
}
|
||||
|
||||
bool prev_selected = deselect_ends;
|
||||
for (int point_i = points.first(); point_i <= points.last(); point_i++) {
|
||||
if (prev_selected) {
|
||||
selection_typed[point_i] = prev_selected = false;
|
||||
}
|
||||
else {
|
||||
selection_typed[point_i] = prev_selected = true;
|
||||
}
|
||||
for (const int offset : IndexRange(points.size())) {
|
||||
Lorenzo-Carpaneto marked this conversation as resolved
Outdated
Falk David
commented
I think this loop can now be simplified:
I think this loop can now be simplified:
```
for (const int point_i : points.index_range()) {
selection[point_i] = (point_i % 2 == 0);
}
```
Lorenzo-Carpaneto
commented
mmm, this is not entirely right I think: the select ends param makes us start or from first or from second point... So the selection is kind of "inverted" based on this params (I am basing this fact on the older version of gp, that works like this) mmm, this is not entirely right I think: the select ends param makes us start or from first or from second point... So the selection is kind of "inverted" based on this params (I am basing this fact on the older version of gp, that works like this)
Falk David
commented
Ah then you use Ah then you use `(point_i % 2 == unselect_ends)` instead.
Sietse Brouwer
commented
It's weird, but I noticed we can't use It's weird, but I noticed we can't use `points.index_range()`, because it always starts at `0`. While `points.first()` gives the correct offset.
So keeping
` for (int point_i = points.first(); point_i <= points.last(); point_i++) {`
is the right thing to do.
Iliya Katushenock
commented
Maybe something like this? ```Cpp
const int half_of_size = points.size() / 2;
const IndexRange selected = points.shift(select_ends ? 0 : 1);
const IndexRange deselected = points.shift(select_ends ? 1 : 0);
for (const int index : IndexRange(half_of_size)) {
const int selected_index = selected[index * 2];
const int deselected_index = deselected[index * 2];
selection_typed[selected_index] = true;
selection_typed[deselected_index] = false;
}
selection_typed.last() = select_ends;
```
Maybe something like this?
Lorenzo-Carpaneto
commented
@mod_moder to me this seems more difficult to read than what I had originally written though... @mod_moder to me this seems more difficult to read than what I had originally written though...
Lorenzo-Carpaneto
commented
Are we entirely sure that the first point is always 0? Because I see that index_range has a start_ init param > Ah then you use `(point_i % 2 == unselect_ends)` instead.
Are we entirely sure that the first point is always 0? Because I see that index_range has a start_ init param
Falk David
commented
@SietseB is right, the for loop can stay as is. @SietseB is right, the for loop can stay as is.
Iliya Katushenock
commented
@Lorenzo-Carpaneto The main reason for my approach is that it is:
@Lorenzo-Carpaneto The main reason for my approach is that it is:
- It doesn't require you to calculate each step of the loop in your head that you know the result.
- It can be multi-threaded. Remember, these arrays can be millions of points long.
Lorenzo-Carpaneto
commented
@mod_moder These are good motivations, but I think there might be problems with your solution. @mod_moder These are good motivations, but I think there might be problems with your solution.
@SietseB and @filedescriptor said that `points.index_range()` is not working (and that function returns: `IndexRange(size_);`. So I fear that your approach suffers from the same bug. So for now maybe better keep the loop as is, and as soon as we fix the problem with iteration on indexRange, we change the code
Iliya Katushenock
commented
IndexRange is iterator factory itself. If you use IndexRange is iterator factory itself. If you use `index_range()` method, you will create new IndexRange for iterating on something. In my case, `points` sampled directly, look at `const IndexRange selected = points.shift(select_ends ? 0 : 1);...` lines.
Lorenzo-Carpaneto
commented
I was referring to I was referring to `for (const int index : IndexRange(half_of_size))`
Iliya Katushenock
commented
`const int selected_index = selected[index * 2];`
You can sampling IndexRage to maping indices.
Lorenzo-Carpaneto
commented
@mod_moder @HooglyBoogly I looked better at the problem that @SietseB was saying about IndexRange and I am now convinced that the solution proposed should work :) I have made the change (a bit different from suggestion but basically the same) check it out :) @mod_moder @HooglyBoogly I looked better at the problem that @SietseB was saying about IndexRange and I am now convinced that the solution proposed should work :) I have made the change (a bit different from suggestion but basically the same) check it out :)
|
||||
selection_typed[points.first() + offset] = deselect_ends ? offset % 2 : !(offset % 2);
|
||||
Lorenzo-Carpaneto marked this conversation as resolved
Outdated
Hans Goudey
commented
`for (const int point : points) {`
Lorenzo-Carpaneto
commented
We are just discussing about this in the other thread, please join in the dicussion :D We are just discussing about this in the other thread, please join in the dicussion :D
Hans Goudey
commented
Ah sorry, haha Ah sorry, haha
Think I agree with Iliya in principle (whenever possible, better to write loops in a parallel way, so they have no dependence on the previous iteration)
Iliya Katushenock
commented
This one is exactly the same ```Cpp
for (const int index : points.index_range()) {
selection_typed[points[index]] = deselect_ends ? index % 2 : !(index % 2);
```
This one is exactly the same
Lorenzo-Carpaneto
commented
According to @SietseB (previous comment in the other thread)
This way should avoid this problem (cause we need to start from 0) According to @SietseB (previous comment in the other thread)
```
It's weird, but I noticed we can't use points.index_range(), because it always starts at 0. While points.first() gives the correct offset.
```
This way should avoid this problem (cause we need to start from 0)
Iliya Katushenock
commented
`IndexRange(points.size())` == `points.index_range()`
`points.first() + 0..1..2...` == `points[0...1...2...]`
Lorenzo-Carpaneto
commented
Ah, you are totally right, pushing the proposed version, it's a bit more readable and efficient :) Ah, you are totally right, pushing the proposed version, it's a bit more readable and efficient :)
|
||||
}
|
||||
|
||||
if (cyclic[curve_i]) {
|
||||
|
|
I think it make sense to avoid the indentation and continue early.