Making the creation of arrays more user friendly

A forum dedicated to the Draft, Arch and BIM workbenches development.
User avatar
alonso_jamm
Posts: 37
Joined: Mon Nov 11, 2019 11:32 pm

Making the creation of arrays more user friendly

Postby alonso_jamm » Thu Dec 19, 2019 7:25 pm

Hello, I have been working on a way to make the creation of arrays more user friendly. I used the task panel where the information of the array can be put. I made all the code inside a macro as a proof of concept since I am not sure if others would like to integrate this functionality into the Draft workbench. Here is the link for the macro. In order to use the macro, the FCMacro and the ui files should be put in the default Macro folder of FreeCAD.

I also made a video showing the functionality of the macro:
phpBB [video]


This macro is only for rectangular arrays, but I wanted to first get feedback on this macro before trying to make similar Tasks for creating the other types of arrays.
vocx
Posts: 5206
Joined: Thu Oct 18, 2018 9:18 pm

Re: Making the creation of arrays more user friendly

Postby vocx » Fri Dec 20, 2019 12:51 am

alonso_jamm wrote:
Thu Dec 19, 2019 7:25 pm
...
This macro is only for rectangular arrays, but I wanted to first get feedback on this macro before trying to make similar Tasks for creating the other types of arrays.
It's good. I have the same idea. I already created a few branches to launch the CircularArray and the PolarArray tools, but I haven't submitted a pull request.

I haven't submitted my code for the simple reason that before submitting it I wanted to structure more the code so that it is not messy. The Draft Workbench is a pretty old workbench, started around 2009; therefore it has a lot of baggage that it has accumulated over the years. So instead of just adding more code to only a few files (Draft.py, DraftGui.py, and DraftTools.py are huge!), I thought it would be good to do things in a planned way.

Please read about it here [Discussion] Splitting Draft tools into their own modules.

Basically, I want to separate the code into graphical parts (the task panel and view providers) from the implementation (the GuiCommand classes, and the underlying functions, essentially Draft.makeArray).

See my branch GuiCommand_base. This sets up the needed directories for putting new commands.

Once you have merged that, then you can merge the PolarArray and CircularArray branches, where the new commands are implemented.

I noticed that in your implementation you used some observers. I haven't investigated that, so I didn't do that in my code. Maybe you can take a look at my code so that you get some ideas. It would be good if you structured your code in a similar way to mine. Why did I do it this way? Because ideally we can split all graphical commands inside DraftTools.py into their own individual modules, so that they are easier to manage and extend.

All graphical commands in Draft (all the buttons that you see) are defined in DraftTools.py and are based on some parent classes that set up some things in the interface (DraftGui.py) this is all connected and it's not very easy to untangle, so that's why I'm proceeding slowly, trying not to break backwards compatibility. Maybe we will have to break compatibility at some point, but we should avoid that if possible at the beginning.

I'll make a few changes to my code and submit it shortly. As long as it's graphical commands (buttons) changing them is not that hard. The problem is changing the underlying commands inside Draft.py. These are more critical.
Always add the important information to your posts if you need help. Also see Tutorials and Video tutorials.
To support the documentation effort, and code development, your donation is appreciated: liberapay.com/FreeCAD.
chrisb
Posts: 28098
Joined: Tue Mar 17, 2015 9:14 am

Re: Making the creation of arrays more user friendly

Postby chrisb » Fri Dec 20, 2019 12:58 am

Thanks for sharing.

Some observations after first usage:
- If an object is selected before calling the macro it should be entered as base of the array
- before trying the Select-button it's not completely clear when it has to be clicked, before the selection or after
- the preview function is really a benefit over the conventional array handling. However, the button suggest to be switched on or off, but it cannot be switched off if it was once pressed on.
- I guess it's not possible for a macro to run on double click on an array.

The GUI would provide more added value if it would give more help what to enter. In the current state there is no more information than in the Data tab.
User avatar
alonso_jamm
Posts: 37
Joined: Mon Nov 11, 2019 11:32 pm

Re: Making the creation of arrays more user friendly

Postby alonso_jamm » Fri Dec 20, 2019 6:26 pm

chrisb wrote:
Fri Dec 20, 2019 12:58 am
Thanks for sharing.
Thanks for giving feedback. I made a couple of changes that hopefully solve these issues.

chrisb wrote:
Fri Dec 20, 2019 12:58 am
- If an object is selected before calling the macro it should be entered as base of the array
Now, if an object is selected before calling the macro, then it will be used as a base for the array.

chrisb wrote:
Fri Dec 20, 2019 12:58 am
- before trying the Select-button it's not completely clear when it has to be clicked, before the selection or after
I changed the initial value of the line edit right to the Select button that gives the indication to first click the button, then to choose the base.

chrisb wrote:
Fri Dec 20, 2019 12:58 am
- the preview function is really a benefit over the conventional array handling. However, the button suggest to be switched on or off, but it cannot be switched off if it was once pressed on.
Now the preview button deletes the array when turned off.

chrisb wrote:
Fri Dec 20, 2019 12:58 am
- I guess it's not possible for a macro to run on double click on an array.
I am not sure what you mean by that. Do you mean to double click on an object to choose it as a base?

chrisb wrote:
Fri Dec 20, 2019 12:58 am
The GUI would provide more added value if it would give more help what to enter. In the current state there is no more information than in the Data tab.
I added tooltips to the widgets. However, I am not sure exactly how to explain the x,y, and z components of the intervals.

After doing these changes I think the macro is a little bit more user friendly. However, now I also think that the "Select" and "Preview" buttons may not be as intuitive as I first thought. Maybe I need to work more on the ui.
User avatar
alonso_jamm
Posts: 37
Joined: Mon Nov 11, 2019 11:32 pm

Re: Making the creation of arrays more user friendly

Postby alonso_jamm » Fri Dec 20, 2019 6:48 pm

vocx wrote:
Fri Dec 20, 2019 12:51 am
It's good. I have the same idea. I already created a few branches to launch the CircularArray and the PolarArray tools, but I haven't submitted a pull request.

I haven't submitted my code for the simple reason that before submitting it I wanted to structure more the code so that it is not messy. The Draft Workbench is a pretty old workbench, started around 2009; therefore it has a lot of baggage that it has accumulated over the years. So instead of just adding more code to only a few files (Draft.py, DraftGui.py, and DraftTools.py are huge!), I thought it would be good to do things in a planned way.

Please read about it here [Discussion] Splitting Draft tools into their own modules.

Basically, I want to separate the code into graphical parts (the task panel and view providers) from the implementation (the GuiCommand classes, and the underlying functions, essentially Draft.makeArray).

See my branch GuiCommand_base. This sets up the needed directories for putting new commands.

Once you have merged that, then you can merge the PolarArray and CircularArray branches, where the new commands are implemented.
Thanks. I like the new structure for the Draft worbench. I based this macro similar to the way ShapeStringTaskPanel is structured and on tutorials I saw about the Task Panel and on Pyside. I think it would not be too difficult to change the code into something similar to what you did for the CircularArray and PolarArray task panels.
vocx wrote:
Fri Dec 20, 2019 12:51 am
I noticed that in your implementation you used some observers. I haven't investigated that, so I didn't do that in my code. Maybe you can take a look at my code so that you get some ideas. It would be good if you structured your code in a similar way to mine. Why did I do it this way? Because ideally we can split all graphical commands inside DraftTools.py into their own individual modules, so that they are easier to manage and extend.
I used an observer in order to detect when the user clicks on an object and to get said object as a base for the array. I like the idea of the observer because we could pass different observers that look for different types of objects to the task panel easily. An example would be Assembly4, an observer for this workbench would look for an object inside "Model." The observer I put on the macro would get "Model" instead because this observer gets the parent of the selected object. And I assume that there would be more use cases where the desired base for the array will be different than the one chosen by the current observer. I don't know much about how FreeCAD works, but using observers is a relatively simple solution I found to get the base object of the array by simply clicking on the object.

I will be looking at your code to see how I can improve my array macro and to make it similar to the PolarArray and CircularArray.
chrisb
Posts: 28098
Joined: Tue Mar 17, 2015 9:14 am

Re: Making the creation of arrays more user friendly

Postby chrisb » Fri Dec 20, 2019 6:58 pm

alonso_jamm wrote:
Fri Dec 20, 2019 6:26 pm
chrisb wrote:
Fri Dec 20, 2019 12:58 am
- I guess it's not possible for a macro to run on double click on an array.
I am not sure what you mean by that. Do you mean to double click on an object to choose it as a base?
I meant indeed double clicking on an array. I mean editing an existing array with your macro, similar to a double click on a Part->Chamfer, where you reenter the dialog. I assume that it is not or almost not possible to change the behaviour of a double click on an existng array.
User avatar
alonso_jamm
Posts: 37
Joined: Mon Nov 11, 2019 11:32 pm

Re: Making the creation of arrays more user friendly

Postby alonso_jamm » Fri Dec 20, 2019 7:15 pm

chrisb wrote:
Fri Dec 20, 2019 6:58 pm
alonso_jamm wrote:
Fri Dec 20, 2019 6:26 pm
chrisb wrote:
Fri Dec 20, 2019 12:58 am
- I guess it's not possible for a macro to run on double click on an array.
I am not sure what you mean by that. Do you mean to double click on an object to choose it as a base?
I meant indeed double clicking on an array. I mean editing an existing array with your macro, similar to a double click on a Part->Chamfer, where you reenter the dialog. I assume that it is not or almost not possible to change the behaviour of a double click on an existng array.
I think changes to the array object source code needs to be done in order to get that functionality. If I double click on an existing array I get a message that says that the array is not an editable object. I think that being able to edit the array by double clicking on it would be a nice feature. But I don't know how to accomplish that.
vocx
Posts: 5206
Joined: Thu Oct 18, 2018 9:18 pm

Re: Making the creation of arrays more user friendly

Postby vocx » Fri Dec 20, 2019 7:18 pm

chrisb wrote:
Fri Dec 20, 2019 6:58 pm
...I assume that it is not or almost possible to change the behaviour of a double click on an existng array.
It should be possible, but we would have to integrate the code of alonso into the Draft Workbench. We need to register a proper GuiComamnd for it, and not leave it as a macro.
Always add the important information to your posts if you need help. Also see Tutorials and Video tutorials.
To support the documentation effort, and code development, your donation is appreciated: liberapay.com/FreeCAD.
vocx
Posts: 5206
Joined: Thu Oct 18, 2018 9:18 pm

Re: Making the creation of arrays more user friendly

Postby vocx » Fri Dec 20, 2019 7:31 pm

alonso_jamm wrote:
Fri Dec 20, 2019 6:48 pm
...
I used an observer in order to detect when the user clicks on an object and to get said object as a base for the array.
As I said, I'm not familiar with the way this works. Off the top of my head, there is not a single Observer in Draft's code, which is why I haven't seen this functionality. What is used is the simple selection, that is, FreeCADGui.Selection.getSelection. This is used in my code as well. I presume the way you are coding uses the selection mechanism behind it.
...An example would be Assembly4, an observer for this workbench would look for an object inside "Model."
...I don't know much about how FreeCAD works, but using observers is a relatively simple solution I found to get the base object of the array by simply clicking on the object.
Unfortunately I haven't looked deeply into Assembly4 either, so I haven't seen this use of Observers. It sounds like a good idea. Although I really wonder what the difference is between the Observer and the simple selection. I'll need a few days to investigate.

There is one thing to warn you about. You seem to be calling the function directly, that is, makeArray.

Code: Select all

if self.array is None:
            self.array = Draft.makeArray(baseObject, xVector, yVector, 
                                         zVector, xNum, yNum, zNum, 
                                         name=arrayName, useLink=useLink)
The Draft tools use a class called DraftTool.todo, to create a string that is executed at a later time; it's a delayed execution. This is done because if you manipulate the 3D view directly (with Coin), and you show a preview, you may get a crash; so delaying the execution of the command is better. This is what I did in my code, so maybe you can do the same.

Something like this

Code: Select all

code = "Draft.makeArray(baseObject, xVector, yVector, zVector, xNum, yNum, zNum, name=arrayName, useLink=useLink)"
self.commit += code
Always add the important information to your posts if you need help. Also see Tutorials and Video tutorials.
To support the documentation effort, and code development, your donation is appreciated: liberapay.com/FreeCAD.
User avatar
alonso_jamm
Posts: 37
Joined: Mon Nov 11, 2019 11:32 pm

Re: Making the creation of arrays more user friendly

Postby alonso_jamm » Fri Dec 20, 2019 8:27 pm

vocx wrote:
Fri Dec 20, 2019 7:31 pm
As I said, I'm not familiar with the way this works. Off the top of my head, there is not a single Observer in Draft's code, which is why I haven't seen this functionality. What is used is the simple selection, that is, FreeCADGui.Selection.getSelection. This is used in my code as well. I presume the way you are coding uses the selection mechanism behind it.
The way I used the observer is as a callback of when the user clicks on an object in the 3D view so the line edit can be updated and the preview button can be enabled at the same time the user clicks on an object. But to get the actual object I use a similar function to the one you use; I use

Code: Select all

FreeCADGui.Selection.getSelectionEx("", 0)
It is similar to getSelection but with this function I can get the parent object of the selected object in the current file (for example if I select a body inside a part, then I get the part itself instead of the body).
vocx wrote:
Fri Dec 20, 2019 7:31 pm
The Draft tools use a class called DraftTool.todo, to create a string that is executed at a later time; it's a delayed execution. This is done because if you manipulate the 3D view directly (with Coin), and you show a preview, you may get a crash; so delaying the execution of the command is better. This is what I did in my code, so maybe you can do the same.
So this means that having some sort of preview of the array will not be possible? I personally like to see a preview of what are the changes I am doing to the array. Though the way I implemented a preview is to simple edit an existing array so it is not too different to just changing values of the array in the property editor.