Workbench-Starterkit refactor

Have some feature requests, feedback, cool stuff to share, or want to know where FreeCAD is going? This is the place.
Forum rules
Be nice to others! Read the FreeCAD code of conduct!
User avatar
Joel_graff
Veteran
Posts: 1949
Joined: Fri Apr 28, 2017 4:23 pm
Contact:

Workbench-Starterkit refactor

Post by Joel_graff »

So I've been playing with the Workbench-Starterkit code for a few months. I really love the new design. It's cleaner and more organized and I think it's poised to be one of the nicest development tools that we can offer new FC devs / superusers.

I really want to document the workbench starter kit thoroughly on a github wiki (see my pivy_tracker wiki for an example). I'd happily document it as-is, but I really think we need to revisit the structure of the starter kit and tweak it to better aid new devs.

That said, I've been reworking the structure to incorporate features that would have helped me learn workbench design when I was just getting started. Most of my changes have really just expanded on what's already there - providing structure / organization that doesn't exist currently.

I'm also interested in seeing more uniform workbench layout across FC workbenches, both internal and external, as @vocx is attempting to do with the Draft WB. While I don't think enforcing strict uniformity is a good idea, I do think some consistency in layout is essential, as it'll help new devs contribute more to the project as a whole, while making codebases more maintainable and scalable.

As it stands, probably the only major omission in my refactor is providing support for non-gui code. That is, there's no obvious structure or definition for how a to split up code between init.py and init_gui.py, or why someone should bother, if they're only interested in a GUI-based workflow. I want to correct that, of course.

I also don't want to overlook the TemplatePyMod codebase in the wiki, though it's examples tend to be a bit arcane for the typical Python WB dev. Plus, it's only referenced in passing in the Wiki page for Scripted Objects.

Getting some changes merged will make the StarterKit even better and pave the way for documenting a clear, maintainable process for Python workbench development that a new dev can easily follow.
FreeCAD Trails workbench for transportation engineering: https://www.github.com/joelgraff/freecad.trails

pivy_trackers 2D coin3D library: https://www.github.com/joelgraff/pivy_trackers
User avatar
looo
Veteran
Posts: 3941
Joined: Mon Nov 11, 2013 5:29 pm

Re: Workbench-Starterkit refactor

Post by looo »

Joel_graff wrote: Fri Nov 08, 2019 1:32 pm As it stands, probably the only major omission in my refactor is providing support for non-gui code. That is, there's no obvious structure or definition for how a to split up code between init.py and init_gui.py, or why someone should bother, if they're only interested in a GUI-based workflow. I want to correct that, of course.
I guess the init.py is one source of confusion for python developers. While it makes sense to split gui and non-gui stuff, there is not really a need for a init.py file. Making freecadcmd behave differently from the python-interpreter by adding symbols makes it difficult for 3rd-parties to depend on freeecad-modules. One example which shows how difficult it is to import freecad from an external library is shown by cadquery: def _fc_path.

In my eyes there is no need for the freecadcmd and therefor no need for the init.py files. Simple align all modules to the structure of a normal python modules and somehow split the freecad-gui stuff (initialized by the init_gui.py) so a import of the module (when imported from python) does not import any gui-dependent stuff.

So in my eyes it's important to define the future import-structure of freecad first and afterward align the StarterKit to this structure.

But all this will rely on the python-rule to not have multiple versions of the same package in one system/environment. This would mean that we can only install one version of freecad in ubuntu/debian via apt-get. Not sure if this is possible with any other package-manager.
User avatar
Joel_graff
Veteran
Posts: 1949
Joined: Fri Apr 28, 2017 4:23 pm
Contact:

Re: Workbench-Starterkit refactor

Post by Joel_graff »

looo wrote: Fri Nov 08, 2019 2:27 pm So in my eyes it's important to define the future import-structure of freecad first and afterward align the StarterKit to this structure.

But all this will rely on the python-rule to not have multiple versions of the same package in one system/environment. This would mean that we can only install one version of freecad in ubuntu/debian via apt-get. Not sure if this is possible with any other package-manager.
I see your point. Out of curiosity, I presume you'd roll FreeCADcmd into FreeCAD and trigger it with maybe a --headless argument?

Either way, I think we can do a lot to develop a cohesive structure for workbench design, no matter what the import issues are. Maybe we should just encourage use of init_gui.py and ignore init.py as you suggest, then worry about it again if/when the freecad import process changes / freecadcmd goes away. I see no reason to postpone this effort on account of that, anyway.

Nevertheless, maybe we need to start / redouble our efforts to address the freecad import structure issue, as well? Even if it only results in a long-term plan, it would likely provide guidance for the workbench structure...
FreeCAD Trails workbench for transportation engineering: https://www.github.com/joelgraff/freecad.trails

pivy_trackers 2D coin3D library: https://www.github.com/joelgraff/pivy_trackers
vocx
Veteran
Posts: 5197
Joined: Thu Oct 18, 2018 9:18 pm

Re: Workbench-Starterkit refactor

Post by vocx »

Joel_graff wrote: Fri Nov 08, 2019 2:43 pm I see your point. Out of curiosity, I presume you'd roll FreeCADcmd into FreeCAD and trigger it with maybe a --headless argument?
...
I'm not sure I understand this point.

I believe these are equivalent.

Code: Select all

freecadcmd
freecad -c
Also, to looo's commet
looo wrote: Fri Nov 08, 2019 2:27 pm While it makes sense to split gui and non-gui stuff, there is not really a need for a init.py file. Making freecadcmd behave differently from the python-interpreter by adding symbols makes it difficult for 3rd-parties to depend on freeecad-modules.
Is this about the new style workbenches, or about all workbenches in general?

How is init.py called?

I always assumed it is called regardless of whether the GUI is used or not.

Code: Select all

freecad --> init.py --> if GUI --> init_gui.py
Is this not correct?

Code: Select all

freecadcmd --> init.py
freecad --> init.py --> init_gui.py
I'm using the new workbench names, but I assumed this is the same with old-style workbenches.

Code: Select all

freecadcmd --> Init.py
freecad --> Init.py --> InitGui.py
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
Joel_graff
Veteran
Posts: 1949
Joined: Fri Apr 28, 2017 4:23 pm
Contact:

Re: Workbench-Starterkit refactor

Post by Joel_graff »

vocx wrote: Fri Nov 08, 2019 5:08 pm I believe these are equivalent.
I didn't know about the -c parameter. That's what I meant by --headless. :lol:

As for init.py / init_gui.py, I really am not terribly familiar with the inner workings for the new style, but I had assumed they were the same.
FreeCAD Trails workbench for transportation engineering: https://www.github.com/joelgraff/freecad.trails

pivy_trackers 2D coin3D library: https://www.github.com/joelgraff/pivy_trackers
vocx
Veteran
Posts: 5197
Joined: Thu Oct 18, 2018 9:18 pm

Re: Workbench-Starterkit refactor

Post by vocx »

Joel_graff wrote: Fri Nov 08, 2019 5:49 pm ...
As for init.py / init_gui.py, I really am not terribly familiar with the inner workings for the new style, but I had assumed they were the same.
You mean init.py is called sometimes, and init_gui.py called other times? That wouldn't make sense, in my opinion. It only makes sense if it's initialized in a cascading way, first init.py, then if the GUI is available, init_gui.py.
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
looo
Veteran
Posts: 3941
Joined: Mon Nov 11, 2013 5:29 pm

Re: Workbench-Starterkit refactor

Post by looo »

Some more confusion:

Actually, I was a bit wrong. The Init.py and init.py are NOT called when launching freecadcmd. So I wonder why we need the init.py at all??? You can try by adding some print statements in any of the Init.py files.
So I guess we are save by not recomending to add any init.py file.

And what about the freecadcmd?
This seems to be a pure python-console with some nice FreeCAD-logo on top and some sys.path modifications. So if we somehow manage to make FreeCAD and it's modules a real python-package there shouldn't be any difference between a python-console where freecad is imported and the freecadcmd.

edit: But calling FreeCAD -c calls the init.py files.

As this is all a bit confusing, this is where all the magic happens (maybe the freecadcmd uses another initialization, not sure):
Init.py (traditional)
InitGui.py(traditional)
init.py (new-style)
[init_gui.py new-style

So I guess we really have to create a proposal on how the initialization of freecad-workbenches should work because this is still a big mess.

@wmayer: Do we really need the Init.py/init.py files? What if we write all the stuff done in these files into a __init__.py file of a module and call them if a special export/import is needed (referring to this file: https://github.com/FreeCAD/FreeCAD/blob ... ft/Init.py)?
Last edited by looo on Sat Nov 09, 2019 4:23 pm, edited 1 time in total.
wmayer
Founder
Posts: 20319
Joined: Thu Feb 19, 2009 10:32 am
Contact:

Re: Workbench-Starterkit refactor

Post by wmayer »

Actually, I was a bit wrong. The Init.py and init.py are NOT called when launching freecadcmd. So I wonder why we need the init.py at all???
Of course, the Init.py files are called at startup. Just make sure to add this statement to one of the Init.py files of your build directory.

Code: Select all

print ("Execute Init.py")
If you now run FreeCADCmd or python -c "import FreeCAD" you should see the above message in the console.
And the Init.py files are still important because they are used to register a file format with a module name. Although mainly used in the GUI it is helpful in headless mode, too.
Consider the case that you have a certain file name but you don't know which module handles it.

Code: Select all

filename = ...
ext=os.path.splitext(filename)[1][1:]
support = FreeCAD.getImportType(ext)
if len(support) == 1:
    import importlib
    mod=importlib.import_module(support[0])
    mod.open(filename)
In your client code you don't have to make assumptions about which modules handles which file format. Of course, if you know you have an STL file you will load the Mesh module but there are other file formats like ply that are handled by multiple modules
And what about the freecadcmd?
It's true that "freecadcmd" and "freecad -c" does the same but the key difference is the dependency to other packages. FreeCAD links against FreeCADGui and thus to a ton of GUI-specific 3rd party libraries. However, on a pure server system you usually don't have installed any GUI-stuff and thus running the FreeCAD GUI version in headless mode is not possible.
User avatar
looo
Veteran
Posts: 3941
Joined: Mon Nov 11, 2013 5:29 pm

Re: Workbench-Starterkit refactor

Post by looo »

wmayer wrote: Sat Nov 09, 2019 3:01 pm Of course, the Init.py files are called at startup. Just make sure to add this statement to one of the Init.py files of your build directory.
Ah my fault. I used the system "freecadcmd" where no modification was made. :oops:
wmayer wrote: Sat Nov 09, 2019 3:01 pm And the Init.py files are still important because they are used to register a file format with a module name. Although mainly used in the GUI it is helpful in headless mode, too.
Consider the case that you have a certain file name but you don't know which module handles it.
The problem here is that this is different to how things work if modules are directly imported from python. So someone writes a macro for FreeCAD and wants to run it with python. Ideally, this just works. But due to predefined variables and magic stuff happening in FreeCAD(Gui) all kinds of modifications have to be made.

Can you confirm that the init.py/Init.py files are not called when FreeCAD is imported from python? Or is this another wrong assumption of me?

and sorry for hijacking this topic @Joel_graff
Last edited by looo on Sat Nov 09, 2019 4:11 pm, edited 1 time in total.
User avatar
Kunda1
Veteran
Posts: 13434
Joined: Thu Jan 05, 2017 9:03 pm

Re: Workbench-Starterkit refactor

Post by Kunda1 »

This is a great thread to document the intricacies of what gets loaded and the sequences between the different way to invoke FreeCAD (with and without GUI). Can someone add this to the wiki, I'd do it but some concepts are out of my current scope
Alone you go faster. Together we go farther
Please mark thread [Solved]
Want to contribute back to FC? Checkout:
'good first issues' | Open TODOs and FIXMEs | How to Help FreeCAD | How to report Bugs
Post Reply