Can I reverse a wire, or extrude a structure on the back of face

A forum dedicated to the Draft, Arch and BIM workbenches development.
Forum rules
Be nice to others! Respect the FreeCAD code of conduct!
matthijskooijman
Posts: 72
Joined: Thu Mar 25, 2021 10:59 am

Re: Can I reverse a wire, or extrude a structure on the back of face

Post by matthijskooijman »

Roy_043 wrote: Wed May 19, 2021 7:27 pm
matthijskooijman wrote: Wed May 19, 2021 6:41 pm This is what I tried first, but then my wire got moved (to double coordinates, I think, or double applying placement maybe). From the code, I also think I saw that updating Start and End updates Points, but not the other way around.
Strange. Note that after obj.Points = reversed(obj.Points) you do have to recompute.
I just tried again, and I cannot reproduce the earlier problem, not even with the same wire in the same file not sure why. Oh well, it seems to behave as you said indeed: Just updating Points and then recomputing, which updates Start and End. Looking at the code, execute() runs onChanged(obj, "Placement"), which then updates Start and End, so the code is indeed there.

Roy_043 wrote: Wed May 19, 2021 6:09 pm 21:26:11 Traceback (most recent call last):
21:26:11 File "D:\BKG_Tmp\FreeCAD_0.20_Last\Mod\Draft\draftguitools\gui_edit.py", line 839, in evaluate_menu_action
21:26:11 obj_gui_tools.arcInvert(obj)
21:26:11 AttributeError: 'NoneType' object has no attribute 'arcInvert'
Heh, I now get the same. I'm pretty sure it worked before, but looking at the code, I can't see how. I see that:
  1. this code fails to set obj because the mouse is over the object, not a node.
  2. this code will not be able to find obj_gui_tools
  3. then this code will find the right obj, but not search for obj_gui_tools again, so this fails.
Probably easy to fix, but I'm not entirely sure what the best way is (this code seems to make some assumptions about its global state, i.e. can you assume that e.g. self.overNode or self.event still has the same value as when the menu was shown? And why do this menu title checking and using all this state in self, rather than just using callback functions that capture all the data they need (so you can be *sure* that the object the action is executed on is the same as the one considered when populating the menu)?
carlopav
Veteran
Posts: 2062
Joined: Mon Dec 31, 2018 1:49 pm
Location: Venice, Italy

Re: Can I reverse a wire, or extrude a structure on the back of face

Post by carlopav »

matthijskooijman wrote: Wed May 19, 2021 9:13 pm Probably easy to fix, but I'm not entirely sure what the best way is (this code seems to make some assumptions about its global state, i.e. can you assume that e.g. self.overNode or self.event still has the same value as when the menu was shown? And why do this menu title checking and using all this state in self, rather than just using callback functions that capture all the data they need (so you can be *sure* that the object the action is executed on is the same as the one considered when populating the menu)?
hmmm, this was something I wish to address, but didn't have the time to: it's a result of a generalization attempt that was not carried on till the end.
I was quite satisfied with the nodes interaction part, but I still couldn't find an elegant way to deal with the object interaction.
Also I had a lot of attempts to add the menu actions in the "right click context menu", but I really couldn't find a way...
:oops: so that tool is more of a sum of workarounds than something planned... :oops: :oops:
I will support any improvement you wish to contribute :)
follow my experiments on BIM modelling for architecture design
matthijskooijman
Posts: 72
Joined: Thu Mar 25, 2021 10:59 am

Re: Can I reverse a wire, or extrude a structure on the back of face

Post by matthijskooijman »

carlopav wrote: Thu May 20, 2021 7:54 am hmmm, this was something I wish to address, but didn't have the time to: it's a result of a generalization attempt that was not carried on till the end.
I was quite satisfied with the nodes interaction part, but I still couldn't find an elegant way to deal with the object interaction.

Yeah, the nodes part is indeed nicer, since each object can define its own commands nicely rather than hardcoding them in a single place. But even there, the action itself is identified by its label, and actions are executed by string matching against its label (i.e. obj_gui_tools.get_edit_point_context_menu returns strings, and obj_gui_tools.evaluate_context_menu_action matches against these strings). A nicer way to handle this would, IMHO, be to have obj_gui_tools.get_edit_point_context_menu return e.g. tuples of (label, action), where the label is shown in the menu, and if it is selected, the function/lambda inside action is called (removing the need for a separate evoluate_context_menuj_action).

Also, the fact that display_tracker_menu() and evaluate_menu_action() both have to figure out the object to modify etc. is some boilerplate and fragility that I would rather not have. Better to have display_tracker_menu just figure out what needs to happen and then maybe even just capture all the needed information inside a lambda/closure, so that evaluate_menu_action does not have to do anything else than just look up the right closure and call it (and even nicer if Qt can do that, but I'm not sure if it supports this).
carlopav wrote: Thu May 20, 2021 7:54 am Also I had a lot of attempts to add the menu actions in the "right click context menu", but I really couldn't find a way...
:oops: so that tool is more of a sum of workarounds than something planned... :oops: :oops:
I will support any improvement you wish to contribute :)
You mean that you could right click the points and line instead of alt-leftclick or pressing "e"? I would agree that that would be even nicer, since it is a lot easier to discover the actions then (and even nicer if they would work outside of draft edit mode too, but that probably requires core changes).
carlopav
Veteran
Posts: 2062
Joined: Mon Dec 31, 2018 1:49 pm
Location: Venice, Italy

Re: Can I reverse a wire, or extrude a structure on the back of face

Post by carlopav »

matthijskooijman wrote: Thu May 20, 2021 3:20 pm Yeah, the nodes part is indeed nicer, since each object can define its own commands nicely rather than hardcoding them in a single place.
Yup, @vanuan provider the pattern to do that and i applied It.
A nicer way to handle this would, IMHO, be to have obj_gui_tools.get_edit_point_context_menu return e.g. tuples of (label, action), where the label is shown in the menu, and if it is selected, the function/lambda inside action is called (removing the need for a separate evoluate_context_menuj_action).
Can you provider a code example for that? I'm in favour of improving It if possibile.
You mean that you could right click the points and line instead of alt-leftclick or pressing "e"? I would agree that that would be even nicer, since it is a lot easier to discover the actions then (and even nicer if they would work outside of draft edit mode too, but that probably requires core changes).
Yes that was what i meant. I think that a core change that would incorporate the possibility to handle user interaction better could be higly desirable, but i do not think It Is likely to happen cause Draft wb workflow Is quite peculiar in FC.

edit: by the way, i really appreciate the way you write your posts, I find them written with care. May I ask you what is your background? It looks like you are interested in Arch, but it also looks like you are quite comfortable with software development :)
follow my experiments on BIM modelling for architecture design
matthijskooijman
Posts: 72
Joined: Thu Mar 25, 2021 10:59 am

Re: Can I reverse a wire, or extrude a structure on the back of face

Post by matthijskooijman »

carlopav wrote: Thu May 20, 2021 8:11 pm
A nicer way to handle this would, IMHO, be to have obj_gui_tools.get_edit_point_context_menu return e.g. tuples of (label, action), where the label is shown in the menu, and if it is selected, the function/lambda inside action is called (removing the need for a separate evoluate_context_menuj_action).
Can you provider a code example for that? I'm in favour of improving It if possibile.
Sure, here's some quick code: https://github.com/matthijskooijman/Fre ... 353e7347e2

It still works for wire delete point, add point and invert arc, other draft editing will raise exceptions now. I changed get_edit_point_context_menu to return a dictionary of label: callback, so that when get_edit_point_context_menu defines which actions there are, it immediately also defines how to handle them (note that my previous proposal of returning a list of tuples might actually be better, since that is ordered and a dict is not in earlier version of Python).


Note that I used a lambda as the callback in get_edit_point_context_menu, which *captures* the value of any variables that are referenced by the lambda body at the time the lambda is created (i.e. when get_edit_point_context_menu is executed and returns the dict). An alternative to a lambda is to define a local function, which I did for add point and invert arc. Like the lambda, it captures any variables it uses. I'm not sure which of these are the best approach, depends a bit on the context I guess. Also, the handle_delete_point I added now is a bit messy, maybe it should be a local function (like add_point/invert_arc) or maybe the resetTrackers should move elsewhere (so the callback could just call self.delete_point directly).

Note that this means that the pos, obj, etc. is no longer recomputed when the action is executed (but the values are captures inside the callback), and also there is no longer a need to store the event in self.event (I just realized I removed the "del self.event" line, but I'm not sure if this explicit deletion is still needed maybe in display_tracker_menu now?)

Furthermore, I also changed the way the QMenu is handled: Instead of matching using the selected item's label, it now attaches the callback directly to the menu action using setData, meaning that handling the menu action is now just a matter of getting the callback out and calling it.

Let me know how this looks to you :-)
carlopav wrote: Thu May 20, 2021 8:11 pm edit: by the way, i really appreciate the way you write your posts, I find them written with care. May I ask you what is your background? It looks like you are interested in Arch, but it also looks like you are quite comfortable with software development :)
Thanks, I do my best :-) My background is embedded software engineering (by education and by trade), but I've also done a *lot* of more high level programming (mostly on open-source projects, somehow I almost never manage to use a bit of software without ending up submitting patches :-p). Since open-source communication is often text-based, I've had quite some practice with technical writing to make a point clear. Also, I've experienced that writing down observations in a clear way is helpful, if not for others, than at least for my future self :-p And my experience with a lot of different open-source projects has made me proficient in understanding code written by others quickly (though admittedly, FreeCAD is offering a whole new level of challenge in this area :-p).

As for Arch: I have no background or experience in that at all, but I am involved with a volunteer organization that has recently acquired ownership of a building for their activities, and now there is a lot of stuff going on there that need us to draw proper annotated floorplans for various purposes (construction work, fire safety, documenting piping and wiring, etc.).
carlopav
Veteran
Posts: 2062
Joined: Mon Dec 31, 2018 1:49 pm
Location: Venice, Italy

Re: Can I reverse a wire, or extrude a structure on the back of face

Post by carlopav »

matthijskooijman wrote: Sat May 22, 2021 2:17 pm Sure, here's some quick code: https://github.com/matthijskooijman/Fre ... 353e7347e2
Let me know how this looks to you :-)
Cool! you encouraged me to do something that was long overdue: to move all the addPoint stuff to the object's gui_tools :)

Here is a quick attempt:
https://github.com/carlopav/FreeCAD/com ... b091cd3831

I really do like the dictionary-lambda function approach ;)

Edit: I ended up preparing a PR
Last edited by carlopav on Sat May 22, 2021 10:10 pm, edited 1 time in total.
follow my experiments on BIM modelling for architecture design
carlopav
Veteran
Posts: 2062
Joined: Mon Dec 31, 2018 1:49 pm
Location: Venice, Italy

Re: Can I reverse a wire, or extrude a structure on the back of face

Post by carlopav »

matthijskooijman wrote: Sat May 22, 2021 2:17 pm Thanks, I do my best :-) My background is embedded software engineering (by education and by trade), but I've also done a *lot* of more high level programming (mostly on open-source projects, somehow I almost never manage to use a bit of software without ending up submitting patches :-p).
It's always interesting to know the stories of people around the forum :) And yes, that's really a good point to take some time to write carefully the posts :)
And my experience with a lot of different open-source projects has made me proficient in understanding code written by others quickly (though admittedly, FreeCAD is offering a whole new level of challenge in this area :-p).
:oops: yes, what we have it's a real bazar! I suspect that it's because many like me - without any education to software development - were allowed to contribute :) but, hey, i'm grateful for that :D and really happy when someone come and have a more professional view over things so we can improve!
As for Arch: I have no background or experience in that at all, but I am involved with a volunteer organization that has recently acquired ownership of a building for their activities, and now there is a lot of stuff going on there that need us to draw proper annotated floorplans for various purposes (construction work, fire safety, documenting piping and wiring, etc.).
Let us know if you could use FC for some of that stuff, it would be cool.
follow my experiments on BIM modelling for architecture design
matthijskooijman
Posts: 72
Joined: Thu Mar 25, 2021 10:59 am

Re: Can I reverse a wire, or extrude a structure on the back of face

Post by matthijskooijman »

carlopav wrote: Sat May 22, 2021 5:03 pm Edit: I ended up preparing a PR
Nice! I did a thorough review of it, looking good already :-) Good to see that I've provided some motivation for you to pick this up: I suspect that these kinds of generalizations and cleanups can help make the code more accessible, but lacking time to attack all of this myself, it's nice that we can attack this together in this way :-)
carlopav wrote: Sat May 22, 2021 9:18 pm Let us know if you could use FC for some of that stuff, it would be cool.
Yeah, once we have a setup that works (and the pressure of getting the building ready is a bit lower), I will certainly publish our results and do a nice writeup of our approach :-)
carlopav
Veteran
Posts: 2062
Joined: Mon Dec 31, 2018 1:49 pm
Location: Venice, Italy

Re: Can I reverse a wire, or extrude a structure on the back of face

Post by carlopav »

matthijskooijman wrote: Sun May 23, 2021 8:58 am Good to see that I've provided some motivation for you to pick this up: I suspect that these kinds of generalizations and cleanups can help make the code more accessible, but lacking time to attack all of this myself, it's nice that we can attack this together in this way :-)
I like this way to go!
by the way I took the chance to change another couple of things that hurted my aestethic sense :)
Still some cleanup work to do, but indeed it's already a lot better!
follow my experiments on BIM modelling for architecture design
matthijskooijman
Posts: 72
Joined: Thu Mar 25, 2021 10:59 am

Re: Can I reverse a wire, or extrude a structure on the back of face

Post by matthijskooijman »

Yay, the PR was merged. Thanks @carlopav, for all your effort. Now I can reverse my wires nicely ;-D

So, anything else you want to attack in this co-op mode? :-)
Post Reply