Limitations of scripting and macros

Need help, or want to share a macro? Post here!
Forum rules
Be nice to others! Respect the FreeCAD code of conduct!
Post Reply
User avatar
NewJoker
Veteran
Posts: 3016
Joined: Sun Oct 11, 2020 7:49 pm

Limitations of scripting and macros

Post by NewJoker »

Hi,

recently, I became interested in the topic of FreeCAD scripting and macros. I started from macros since they are usually the easiest way to learn how to script things in a particular software. After a few tests, I wonder what the limitations of FreeCAD scripting/macros are in terms of which GUI operations can and which cannot be handled. I've noticed that with the default setting of Edit --> Preferences --> General --> Macro --> Gui commands --> Record as comment - checked, many useful GUI operations are commented out in macros. But after turning this option off, there are still several operations that aren't recorded. This applies to manual view manipulations, selections and assigning colors to faces, among the others. On the other hand, the command to start recording is also saved so each time you run a macro, it starts from a window with recording options which is unnecessary.

For what reason are some commands not recorded ? Is it intentional or simply these commands do not support the scripting interface for now, like it seems to be the case with assigning colors to individual faces ?

On a daily basis I work in Abaqus FEA software in which recorded macros include literally every single operation done in GUI and thus it's possible to script everything there and even create simple widgets for automated work. I'd like to know how it looks like in FreeCAD.
heda
Veteran
Posts: 1348
Joined: Sat Dec 12, 2015 5:49 pm

Re: Limitations of scripting and macros

Post by heda »

think it is like this...

everything you can think of is scriptable,
not everything will show up when recording macros though

why?
well, the world is not perfect, not so much bang for the buck in making everything show in recording for fc as it is a volunteer project.

you need to read wiki & other docs to figure out how squeeze the most out of scripting in fc
like starting with Scripting_and_macros (in left selector of the wiki)
or if you can't figure a specific detail out, ask for specific help here on the forum,
worst case scenario is that it is not scriptable, but then someone probably will come around and make it scriptable
User avatar
onekk
Veteran
Posts: 6144
Joined: Sat Jan 17, 2015 7:48 am
Contact:

Re: Limitations of scripting and macros

Post by onekk »

@heda as already told some "truth about FC", so this is only a little extension, to explain some things.
NewJoker wrote: Mon May 23, 2022 1:47 pm I wonder what the limitations of FreeCAD scripting/macros are in terms of which GUI operations can and which cannot be handled.

This is a common mistake, in FC you could control almost everything with scripting (some WB have no Python API so it is not possible to use what is not existent)

What you see and what you record using macro is a sort of mimic of what the GUI is doing, but not everything is a "command"

Code: Select all

>>> ### Begin command Std_DlgMacroExecuteDirect
>>> Gui.SendMsgToActiveView("Run")
>>> ### End command Std_DlgMacroExecuteDirect
>>> # Gui.Selection.clearSelection()
>>> ### Begin command Std_DlgMacroExecuteDirect
>>> Gui.SendMsgToActiveView("Run")
>>> ### End command Std_DlgMacroExecuteDirect
This is usually what is shown on the Python Console, (this is relative to a script loaded in the editor when you press the "big green arrow" to execute a "Macro")

Sadly FC will not distinguish between a script and a Macro, as a macro is simply issuing "Gui" commands, using "Python code".

Code: Select all

FreeCADGui.getDocument('template').getObject('sezione_del_solido').Transparency = 79

This is a "command" that is issued when you change a property of an object in the "View Tab"

Some translation is needed:

Code: Select all

FreeCADGui.getDocument('template')
Above is simply "the active document"

Code: Select all

.getObject('sezione_del_solido')
This is the "object" in the treeview

Code: Select all

.Transparency = 79
This is the "property" changed with the new value assigned.

NewJoker wrote: Mon May 23, 2022 1:47 pm For what reason are some commands not recorded ? Is it intentional or simply these commands do not support the scripting interface for now, like it seems to be the case with assigning colors to individual faces ?

On a daily basis I work in Abaqus FEA software in which recorded macros include literally every single operation done in GUI and thus it's possible to script everything there and even create simple widgets for automated work. I'd like to know how it looks like in FreeCAD.
@heda as already told you why.


The common mistake is that a Macro has to record everything, but what you see is not properly a "Macro" (it not record as example mouse movements), it a recording of issued commands, some "actions" that you perform with the mouse are not recorded probably because they are not "exposed" as commands, to catch what a command "is" in extremely approximation:

https://wiki.freecadweb.org/Workbench_creation

You will find a "Python command definition", you will see that it define:

Code: Select all

FreeCADGui.addCommand("My_Command", My_Command_Class())
and following this example what you see in the Python console is simply the "issuing" of "My_Command" not all the operation done by My_Command_Class.

To use the class you have not need to know what is doing, only the "address" of the "button to push".

When you "push a button" on a toolbar or chose an item in a menu, you are simply invoking "My_Command" (reusing the example above).

When you wnat to do things, in FC there are a complete API, sadly documentation is not at his best, but is improving.

You could program an entire WB so you could do everything you have in mind, simply you have to learn the "API calls" and study some code.

Some examples of complex things

https://forum.freecadweb.org/viewtopic.php?f=22&t=65308

https://forum.freecadweb.org/viewtopic.php?f=22&t=65875

Scripted Objects
https://wiki.freecadweb.org/Scripted_objects

Eventually in my signature there is a scripting guide in English I have wrote, it is under revision, but some people have found it useful.

Regards

Carlo D.
GitHub page: https://github.com/onekk/freecad-doc.
- In deep articles on FreeCAD.
- Learning how to model with scripting.
- Various other stuffs.

Blog: https://okkmkblog.wordpress.com/
User avatar
NewJoker
Veteran
Posts: 3016
Joined: Sun Oct 11, 2020 7:49 pm

Re: Limitations of scripting and macros

Post by NewJoker »

Thank you for the detailed explanations. So basically, the operations that are not recorded by macros at the moment could be made recordable. The question is if it would be hard to do so. Some of them are not so important for macros (like manual view manipulations) but others, like setting face colors could be handy. On the Polish subforum, there's an ongoing discussion about how to automate the process of changing colors of multiple faces and macros could be the first step.

On the other hand, I think that the command that starts macro recording shouldn't be recorded itself. What are your thoughts about this ? Maybe preventing it from being included in the macro would be a good idea ?
User avatar
onekk
Veteran
Posts: 6144
Joined: Sat Jan 17, 2015 7:48 am
Contact:

Re: Limitations of scripting and macros

Post by onekk »

NewJoker wrote: Tue May 24, 2022 10:01 pm Thank you for the detailed explanations. So basically, the operations that are not recorded by macros at the moment could be made recordable. The question is if it would be hard to do so. Some of them are not so important for macros (like manual view manipulations) but others, like setting face colors could be handy. On the Polish subforum, there's an ongoing discussion about how to automate the process of changing colors of multiple faces and macros could be the first step.

On the other hand, I think that the command that starts macro recording shouldn't be recorded itself. What are your thoughts about this ? Maybe preventing it from being included in the macro would be a good idea ?
Face colors is implemented, but it is not exposed, and is not so robust as it could change under some conditions, there is around a forum discussion on this matter and probably something will likely chnage in future (probably in 0.21).

Actually face color is a "list" that should be created and populate by the user (speaking of scripting), there are some operations and "menu items" in the Gui that could operate on face colors, and some developers are trying to improve the interface and the "stability" of the color assigned to a face.

Sadly I don't a have a saved link to the forum discussion, but probably it is here in the "Python sub-forum".

Regards

Carlo D.
GitHub page: https://github.com/onekk/freecad-doc.
- In deep articles on FreeCAD.
- Learning how to model with scripting.
- Various other stuffs.

Blog: https://okkmkblog.wordpress.com/
TheMarkster
Veteran
Posts: 5505
Joined: Thu Apr 05, 2018 1:53 am

Re: Limitations of scripting and macros

Post by TheMarkster »

Look at Colorize macro.
User avatar
onekk
Veteran
Posts: 6144
Joined: Sat Jan 17, 2015 7:48 am
Contact:

Re: Limitations of scripting and macros

Post by onekk »

NewJoker wrote: Tue May 24, 2022 10:01 pm On the other hand, I think that the command that starts macro recording shouldn't be recorded itself. What are your thoughts about this ? Maybe preventing it from being included in the macro would be a good idea ?
See this simple test macro recorde now on 0.19.3 on Linux:

Code: Select all

# -*- coding: utf-8 -*-

# Macro Begin: /home/carlo-arch/test_macro/test_macro.FCMacro +++++++++++++++++++++++++++++++++++++++++++++++++
import FreeCAD
import Part

# Gui.runCommand('Std_DlgMacroRecord',0)
### Begin command Std_New
App.newDocument("Senza nome")
# App.setActiveDocument("Senza_nome")
# App.ActiveDocument=App.getDocument("Senza_nome")
# Gui.ActiveDocument=Gui.getDocument("Senza_nome")
# Gui.activeDocument().activeView().viewDefaultOrientation()
### End command Std_New
# Gui.runCommand('Std_OrthographicCamera',1)
### Begin command Std_Workbench
# Gui.activateWorkbench("PartWorkbench")
### End command Std_Workbench
### Begin command Part_Cylinder
App.ActiveDocument.addObject("Part::Cylinder","Cylinder")
App.ActiveDocument.ActiveObject.Label = "Cilindro"
App.ActiveDocument.recompute()
# Gui.SendMsgToActiveView("ViewFit")
### End command Part_Cylinder
### Begin command Part_Sphere
App.ActiveDocument.addObject("Part::Sphere","Sphere")
App.ActiveDocument.ActiveObject.Label = "Sfera"
App.ActiveDocument.recompute()
# Gui.SendMsgToActiveView("ViewFit")
### End command Part_Sphere
# Gui.Selection.addSelection('Senza_nome','Sphere','Face1',3.27368,-3.50946,1.27708)
App.getDocument("Senza_nome").Sphere.Placement=App.Placement(App.Vector(0,12,0), App.Rotation(App.Vector(0,0,1),0), App.Vector(0,0,0))
App.getDocument("Senza_nome").Sphere.Placement=App.Placement(App.Vector(0,12,0), App.Rotation(App.Vector(0,0,1),0), App.Vector(0,0,0))
App.getDocument("Senza_nome").Sphere.Placement=App.Placement(App.Vector(0,12,0), App.Rotation(App.Vector(0,0,1),0), App.Vector(0,0,0))
# Macro End: /home/carlo-arch/test_macro/test_macro.FCMacro +++++++++++++++++++++++++++++++++++++++++++++++++

There is no macro command registered, you could "sanitize source" leaving all the comments:

Code: Select all

# -*- coding: utf-8 -*-
import FreeCAD
import Part

App.newDocument("Senza nome")
App.ActiveDocument.addObject("Part::Cylinder","Cylinder")
App.ActiveDocument.ActiveObject.Label = "Cilindro"
App.ActiveDocument.recompute()
App.ActiveDocument.addObject("Part::Sphere","Sphere")
App.ActiveDocument.ActiveObject.Label = "Sfera"
App.ActiveDocument.recompute()
App.getDocument("Senza_nome").Sphere.Placement=App.Placement(App.Vector(0,12,0), App.Rotation(App.Vector(0,0,1),0), App.Vector(0,0,0))

I have deleted also some duplicated commands

And the operation are all here.

From what I've said, I have activated the Part WB and created a new document, but the Macro is perfectly functional as it don't use "commands" but refers to API calls:

another way to write the above is:

Code: Select all

import FreeCAD
import Part

# it is not strictly necessary when run inside the editor window but better to be explicit.
import FreeCAD as App

FreeCAD.newDocument("Senza nome")

DOC = App.ActiveDocument

obj1 = DOC.addObject("Part::Cylinder","Cylinder")
obj1.Label = "Cilindro"

DOC.recompute()

obj2 = DOC.addObject("Part::Sphere","Sphere")
obj2.Label = "Sfera"
DOC.recompute()

# App.getDocument("Senza_nome").Sphere is our obj2
obj2.Placement = App.Placement(App.Vector(0,12,0), App.Rotation(App.Vector(0,0,1),0), App.Vector(0,0,0))

# this is not recorded but better to write again as Placement has been modified
DOC.recompute()
What it lacks are the command to set the view to fit the solid.

Code: Select all

# Gui.SendMsgToActiveView("ViewFit")
That could be added:

Code: Select all

FreeCAD.Gui.SendMsgToActiveView("ViewFit")
FreeCAD.Gui.activeDocument().activeView().viewAxometric()

Find the final code here:
20220525-macro.py
(639 Bytes) Downloaded 6 times

Resuming:

- there is no a Macro start command in the registered Macro

and there are only some "echoes" of the command issued, exposed as comments, you could decomment them or "better" translate them explicitly in API calls.

Note that the only commands that remains in the final code is:

Code: Select all

FreeCAD.Gui.SendMsgToActiveView("ViewFit")
I have not found another method to do that, but it works.

Note also:

Code: Select all

FreeCAD.Gui...
That is the Gui part roughly the same as FreeCADGui (if not the same with another alias).

Hope this explanation will help you to "reconciliate" the macro with the scripting code that you usually read in this forum.

Disclaimer: probably something is explained wrong or in a improper way, feel free to correct and extend this explanation, I will appreciate as here a part of little exceptions we are all "learners".

Regards

Carlo D.
GitHub page: https://github.com/onekk/freecad-doc.
- In deep articles on FreeCAD.
- Learning how to model with scripting.
- Various other stuffs.

Blog: https://okkmkblog.wordpress.com/
Post Reply