Page 1 of 3

Sketcher: Can drawEdit(editCurve) draw several curves?

Posted: Fri Feb 11, 2022 1:26 pm
by paddle
I see that currently we can draw only one preview curve with drawEdit. Is there a reason why we can't draw several curves? Or there just wasn't a usecase before?

Re: Sketcher: Can drawEdit(editCurve) draw several curves?

Posted: Fri Mar 11, 2022 9:14 pm
by abdullah
paddle wrote: Fri Feb 11, 2022 1:26 pm I see that currently we can draw only one preview curve with drawEdit. Is there a reason why we can't draw several curves? Or there just wasn't a usecase before?
The second. No use case.

Take a look into EditModeCoinManager::drawEdit() if you want to extend it to a plurality of curves.

Re: Sketcher: Can drawEdit(editCurve) draw several curves?

Posted: Fri Mar 11, 2022 9:42 pm
by paddle
I see.
For rotate scale and offset this could be useful for preview on mouse move.

Currently what I'm doing is that I open a command on activate.
Then in mouse move it does :
Abort command
Create new command
Create géométries by docommand.
Redraw.

Then the command is commit only on release button.

I think you'll probably not like this idea very much. :D
Also it seems rather CPU intensive. For rotate for instance if you make something like 50 copies of a slot it starts to be quite slow.

But that's for later I guess. For now we can focus on tool settings.

Re: Sketcher: Can drawEdit(editCurve) draw several curves?

Posted: Sat Mar 12, 2022 7:44 am
by abdullah
paddle wrote: Fri Mar 11, 2022 9:42 pm For rotate scale and offset this could be useful for preview on mouse move.
This is not even difficult to do (you certainly have the capabilities to do it).

Internally the edit curve is just a vector of 2d coordinates and an index indicating where separate lines start and end. In the function I indicated there is a single index so it is a sequence of line segments through the coordinates.

There are two ways of doing this:
1. Extending the DrawEdit to a std::vector<std::vector<Base::Vector2d>>.
2. Creating a new overload taking a std::vector<Part::Geometry *>.

Way 1

What needs to be done is:
1. Create another function with the same signature, except that it takes a std::vector<std::vector<Base::Vector2d>>.
2. Make the functionality of converting to coin more generic, so that different indices are created for different curves (ideally one function calls the other).
3. Change all the code used for calling either of these two functions so that it takes a template parameter (so that it can take either). This will enable a leaner interface (in ViewProviderSketch and the attorney).

Then if you call it with a std::vector<Base::Vector2D>, the first function is called. If you call it with a std::vector<std::vector<Base::Vector2d>>, the second function is called. You get as many curves as you want drawn in edit mode.

This is easy. It has the advantage that you can draw random curves (even when you do not have an equivalent Part::Geometry). It has the disadvantage that you need to teach DrawSketchHandler how to draw Part::Geometry, which is not difficult nonetheless:
https://github.com/FreeCAD/FreeCAD/blob ... r.cpp#L301

and incurs in some code duplication.

Way 2

You make an overload to that function that takes a std::vector<Part::Geometry *>. Then you try to leverage EditModeCoinGeometryConverter so that fills in your geometry (reusing the same drawing code it uses for the ViewProvider geometry).

This one is neater if you are drawing existing Part::Geometry. It may need some modification to EditModeCoinGeometryConverter. It is not much of an advantage if you do not actually have the Part::Geometry created or want to draw something different from Part::Geometries.
paddle wrote: Fri Mar 11, 2022 9:42 pm Currently what I'm doing is that I open a command on activate.
Then in mouse move it does :
Abort command
Create new command
Create géométries by docommand.
Redraw.

Then the command is commit only on release button.

I think you'll probably not like this idea very much. :D
Also it seems rather CPU intensive. For rotate for instance if you make something like 50 copies of a slot it starts to be quite slow.
It sounds like some prototype code to test a concept that needs to be redone when the concept is proven ;) .

When code feels bad, it is generally bad. Aborting conveys the intention that I wanted to do something and I cannot do it anymore. It does not convey the intention that I did not know upfront that what I was doing is not what I want and I did it nevertheless, just for representation purposes.

You do not want to create a command. You do not want to insert geometry in the sketch. You just want to draw. If the current capability to draw is not enough, then just improve it. Improving things does feel so right...
paddle wrote: Fri Mar 11, 2022 9:42 pm But that's for later I guess. For now we can focus on tool settings.
I am in my little pre-release loop, so any bug/PR relating to bugs/issues with PRs merged or to be merged before release takes priority. This has taken most the scarce time I could dedicate to FreeCAD this week. Then, next in the list is your tool widget.

Re: Sketcher: Can drawEdit(editCurve) draw several curves?

Posted: Sat Mar 12, 2022 9:31 am
by paddle
The idea I had in mind is what you described as way 2.
This way the DSH can easily draw géométries based on the same code as the one that create the géométries in the end.

I'll have a look into it after finishing offset.

I meant we can focus on tool setting in our next work together. I understand you have other priorities.

Re: Sketcher: Can drawEdit(editCurve) draw several curves?

Posted: Sun Mar 13, 2022 4:24 pm
by paddle
abdullah wrote: Sat Mar 12, 2022 7:44 amThere are two ways of doing this:
1. Extending the DrawEdit to a std::vector<std::vector<Base::Vector2d>>.
2. Creating a new overload taking a std::vector<Part::Geometry *>.
So I've been thinking about it and what about that :
We make a : drawEdit(const std::vector<std::vector<Base::Vector2d>> &EditCurve) function as you describe in way1.
Then we make a toEditCurve function as :
std::vector<std::vector<Base::Vector2d>> toEditCurve(const std::vector<Part::Geometry*> vecOfGeo)
std::vector<Base::Vector2d> toEditCurve(Part::Geometry* geo)

This way we have advantages of both solutions. If we want to draw something random we can, if we want to draw Part::Geometry we do :
drawEdit(toEditCurve(listOfGeos))

What do you think ?
Where should this toEditCurve function be implemented? in DSH.cpp ?

Re: Sketcher: Can drawEdit(editCurve) draw several curves?

Posted: Sun Mar 13, 2022 5:59 pm
by abdullah
paddle wrote: Sun Mar 13, 2022 4:24 pm What do you think ?
I am good to have the two functions, because I understand they are directed to two different use cases.

I am not so happy about duplicating code already available in EditCoinManager. Let me think...

Re: Sketcher: Can drawEdit(editCurve) draw several curves?

Posted: Sun Mar 13, 2022 6:51 pm
by paddle
abdullah wrote: Sun Mar 13, 2022 5:59 pm
paddle wrote: Sun Mar 13, 2022 4:24 pm What do you think ?
I am good to have the two functions, because I understand they are directed to two different use cases.

I am not so happy about duplicating code already available in EditCoinManager. Let me think...
You mean that toEditCurve would reproduce the code in EditCoinManager ?
The coin part is new to me so it's a bit hard to read the code for now.

Re: Sketcher: Can drawEdit(editCurve) draw several curves?

Posted: Sun Mar 13, 2022 7:14 pm
by abdullah
paddle wrote: Sun Mar 13, 2022 6:51 pm
abdullah wrote: Sun Mar 13, 2022 5:59 pm
paddle wrote: Sun Mar 13, 2022 4:24 pm What do you think ?
I am good to have the two functions, because I understand they are directed to two different use cases.

I am not so happy about duplicating code already available in EditCoinManager. Let me think...
You mean that toEditCurve would reproduce the code in EditCoinManager ?
The coin part is new to me so it's a bit hard to read the code for now.
Yes. I have dedicated some time to look into it just now and I see is not straightforward. I will try to dedicate some time tomorrow to think if it makes sense to refactor that code so that it is easily reusable.

Basically, if we teach several times how to draw (repeat code), the code goes in DSH. If we manage to refactor the code and reuse it (which would be the best by far), then the code goes in EditCoinManager as a new "service" offered to ViewProviderSketch, which offers it to DrawSketchHandler...

Re: Sketcher: Can drawEdit(editCurve) draw several curves?

Posted: Mon Mar 14, 2022 3:07 pm
by abdullah
paddle wrote: Sun Mar 13, 2022 6:51 pm You mean that toEditCurve would reproduce the code in EditCoinManager ?
The coin part is new to me so it's a bit hard to read the code for now.
Ok. I have been giving it some thought.

Long story short, though both draw Part::Geometry, refactoring into a single place would be close to pointless. The EditCoinManager code produces Vector3d geometry with elevation of lines for rendering order, while the framework for edit curves uses a Vector2d geometry, as elevation is a detail of the coin manager, which is abstracted in the service offered by EditCoinManager to ViewProviderSketch. At the end, sampling a curve is a couple of lines of code. So, in the balance I opt for an independent implementation.

Because, I thought while typing, here you have the functionality. You just need to rebase your functionality in master (or cherry-pick that commit):
https://github.com/FreeCAD/FreeCAD/comm ... e98484dbf5

I pushed it to master because:
- I had been asked for this functionality before, so there is to be found for anyone interested.
- The commit only extends, does not change existing code, and actually, because no part uses it, it is effectively "unused code", which will not (negatively) affect the release.

Much fun drawing multiple curves...