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

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

Post by matthijskooijman »

I'm running into a problem: I drew a closed draft wire, which makes a face. Then I created a structure from that wire, and it was extruded downwards instead of upwards, which was a bit unexpected.

Reading up, I think this is because of the direction I drew the wire in: One direction results in a face with the forward side up/towards me, the other direction results in a face with the backward direction up/towards me (I confirmed this by setting the lighting to oneside, which shows one grey and one black side for two wire-generated faces). And the structure tool seems to always extrude from the forward side of the face. So the behavior does make sense.

Now I wonder, what tools do I have to correct this (without redrawing the line)?
  • Easiest would be to just reverse the wire, but I can't find a tool or option for this. Does it exist?
  • Another option could be to tell the wire to invert the face, i.e. MakeFace=Reverse or so, but that doesn't seem to exist (and is IMHO not so nice).
  • Another option would be to somehow tell the structure to extrude from the back of the face, but I couldn't find this. What I *can* do, is to set an explicit normal of (0,0,1) in the structure, which makes it extrude upward, but decouples it from the orientation of the face. For a horizontal face, this has the same result, but it's conceptually not what I want.
Any other thoughts on this? If it's not currently possible, maybe adding a "reverse wire" command or tool or so would probably make the most sense (where would that live, though? Maybe in the editor interface you get when you doubleclick a wire)?

Also, I think some of this applies to walls as well as structures, and maybe other arch components as well.


Update: A "Reverse wire" option was added in PR 4811, which allows reversing a wire by editing it (doubleclick), and then hovering over one line of the wire (not the endpoints) and pressing 'e' (or alt+click also works). In the resulting menu, choose "reverse wire".
Last edited by matthijskooijman on Fri Jun 04, 2021 7:07 pm, edited 1 time in total.
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 »

Probably if you Need to add It to Draft Edit I would add It here: https://github.com/FreeCAD/FreeCAD/blob ... it.py#L795
So you can access It from the context menu when pressing "e" Key over the wire in editing mode

Edit: thinking a bit more about It, maybe the viewproviderwire context menu can be more appropriate https://github.com/FreeCAD/FreeCAD/blob ... re.py#L149
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: Fri May 14, 2021 8:32 pm Probably if you Need to add It to Draft Edit I would add It here: https://github.com/FreeCAD/FreeCAD/blob ... it.py#L795
So you can access It from the context menu when pressing "e" Key over the wire in editing mode
Ah, I had forgotten about that interface (also, it seems the "e" key only works after I used the alt+click alternative once or so, weird). Seems a bit of a weird place to edit the properties of the entire object being edited, but realizing that you could be editing multiple draft objects at the same time, I guess it makes some sense. Even more, it seems there is already an "invert arc" command there. I originally thought that this was essentially the same thing, but later I realized this did not actually reverse the direction of the arc, but the size (i.e. replace a 90° arc with a 270° one), actually *without* reversing the direction.

In the impression that invert arc was the same thing for arc, I actually started implementing this a bit, but I didn't like just adding an "invert wire" option similar to "invert arc", too much boilerplate duplication of code IMHO. Also, it seems weird to do the actual inversion in some gui class, IMHO that should be done in the Proxy class itself so it's easy to call it from other places / scripts too. I made a start adding a `canInvertDirection` and `invertDirection` method to DraftObject, to be overridden by subclasses, but then I realized that really only wires can invert their direction (arcs always run in the same direction defined by Part.makeCircle/BRepBuilder it seems), rectangles always use the same order of wires as well, etc. This means that inverting really is only possible for wires. For other shapes you might still want to be able to invert the direction of the produced Face, but other than rotating using Placement (with all the complexities for non-symmetrical objects), or adding a "InvertFace" attribute (probably a bad idea, enough attributes already) I am not sure how exactly. I got a bit demotivated by this, and stopped implementing again.
carlopav wrote: Fri May 14, 2021 8:32 pm Edit: thinking a bit more about It, maybe the viewproviderwire context menu can be more appropriate https://github.com/FreeCAD/FreeCAD/blob ... re.py#L149
Yeah, I thought about that, but it seems like a menu that quickly gets flooded with editing options, so things must be added there sparingly. It is probably the easiest place to discover, though.

I initialy the best place would be the sidebar in edit mode, i.e. here:

Image

But looking at the code, there seems to be a lot of generalization in place there, and the possibility of editing multiple objects made this a bit less obvious than I thought. Also, again a lot of boilerplate for adding a button there, so I'm not sure I'm going to bother here.

For future reference, though, to reverse the direction of a wire, the following Python code seems to work:

Code: Select all

obj.Points, obj.Start, obj.End = reversed(obj.Points), obj.End, obj.Start
I had one more thought, though: Currently, the direction that the face produced by a wire has, depends on the order in which points were drawn (CCW = up, CW = down). This in itself is actually a bit surprising, given that all other objects (circle, rectangle) seem to produce a face with the forward direction up (in the current working plane, so the positive Z direction before Placement). It would be IMHO sane if a wire behaved the same, both for consistency, and because that's usually what you want (draw a face and then extrude upward).

An obvious way to fix this is to just modify the Wire execute method to, when making a face, reverse the points if they would produce a downward face. However, this is going to break backward compatibility (where people might have added additional rotation or negative extrusion height or so to compensate for the reversed face). Also, this assumes that all points are actually in the Z=0 plane, which does not seem to be guaranteed (a wire does not need to be flat, or if it is flat, it might not be flat on another place). Note that I don't mean rotation in Placement, I mean the contents of Points that might not have Z=0.

Another fix would be to, when creating a wire, reverse the points if needed to ensure that they are always CCW, ensuring that the produced face is always upwards. This would be pragmatic, but might also surprise people when the order of their points changed (and if the order of points is ever relevant, this could also be problematic in addition to suprising). Maybe this could be solved with an extra option during wire creation ("Wire direction: As drawn / Produce upwards face"), though.
User avatar
Roy_043
Veteran
Posts: 8409
Joined: Thu Dec 27, 2018 12:28 pm

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

Post by Roy_043 »

matthijskooijman wrote: Wed May 19, 2021 3:52 pm it seems the "e" key only works after I used the alt+click alternative once or so, weird
A GUI focus issue may be causing this.

Select the wire by double clicking in the 3D view, press the Draft_Edit button, and 'e' works fine.

Select the wire in the Tree view, press the Draft_Edit button, and 'e' doesn't not work. You have to click in the 3D view first.
User avatar
Roy_043
Veteran
Posts: 8409
Joined: Thu Dec 27, 2018 12:28 pm

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

Post by Roy_043 »

matthijskooijman wrote: Wed May 19, 2021 3:52 pm For future reference, though, to reverse the direction of a wire, the following Python code seems to work:

Code: Select all

obj.Points, obj.Start, obj.End = reversed(obj.Points), obj.End, obj.Start
The Start and End property are handled automatically. So I think this can be reduced to:

Code: Select all

obj.Points = reversed(obj.Points)
Interesting question: what to do with the Placement? When you create a wire in the GUI the Placement matched the Start of the wire. After reversing this is no longer the case. There probably is no reasonable way to solve this. The Placement need not match any of the points in the wire. The Draft_Offset command 'solves' this by always using a default Placement for new wires.
User avatar
Roy_043
Veteran
Posts: 8409
Joined: Thu Dec 27, 2018 12:28 pm

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

Post by Roy_043 »

matthijskooijman wrote: Wed May 19, 2021 3:52 pm but might also surprise people when the order of their points changed (and if the order of points is ever relevant, this could also be problematic in addition to suprising). Maybe this could be solved with an extra option during wire creation ("Wire direction: As drawn / Produce upwards face"), though.
The direction of wires is relevant when they are used as a path or as the base of a wall. So manipulating the order would indeed have to be optional I think.
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 »

I still think that a viewprovider context menu could be the preferred option: to reverse the order of points of a wire is something really similar to flattening the wire... and I do not think that there could be tons of commands to add to that menu anyway... :roll:
aaaannd... do not get discouraged after looking into Draft_Edit: it was the first thing I put my hands into when experimenting with FreeCAD, so I think I messed up lots of things in that command :roll: :roll:
follow my experiments on BIM modelling for architecture design
User avatar
Roy_043
Veteran
Posts: 8409
Joined: Thu Dec 27, 2018 12:28 pm

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

Post by Roy_043 »

"invert arc" does not work...
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 5:18 pm Select the wire in the Tree view, press the Draft_Edit button, and 'e' doesn't not work. You have to click in the 3D view first.
Ah, indeed, that's it.
Roy_043 wrote: Wed May 19, 2021 5:30 pm The Start and End property are handled automatically. So I think this can be reduced to:
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.
Roy_043 wrote: Wed May 19, 2021 5:30 pm Interesting question: what to do with the Placement? When you create a wire in the GUI the Placement matched the Start of the wire. After reversing this is no longer the case. There probably is no reasonable way to solve this. The Placement need not match any of the points in the wire. The Draft_Offset command 'solves' this by always using a default Placement for new wires.
Right, another way to see this is that normally, Points[0] is always (0,0,0), which is no longer the case with this change. I guess this property could be restored by modifying placement and all points by the value of the last point. But this is probably not really required, since manually modifying a wire by dragging the points also breaks this convention.
Roy_043 wrote: Wed May 19, 2021 6:09 pm "invert arc" does not work...
It worked for me, to change a 90°-ish arc to a 270°-ish arc (last week's git master).
User avatar
Roy_043
Veteran
Posts: 8409
Joined: Thu Dec 27, 2018 12:28 pm

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

Post by Roy_043 »

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.

Roy_043 wrote: Wed May 19, 2021 6:09 pm "invert arc" does not work...
I get this:
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'

Code: Select all

OS: Windows 8.1 Version 6.3 (Build 9600)
Word size of FreeCAD: 64-bit
Version: 0.20.24893 (Git)
Build type: Release
Branch: master
Hash: 03855f793feaceeb4385c02f6520f3e1b6429c93
Python version: 3.8.6+
Qt version: 5.15.2
Coin version: 4.0.1
OCC version: 7.5.0
Locale: Dutch/Netherlands (nl_NL)
Post Reply