evalExpression as a class/static method

Need help, or want to share a macro? Post here!
Forum rules
Be nice to others! Respect the FreeCAD code of conduct!
Zoltan
Posts: 62
Joined: Wed Jul 07, 2021 10:08 am

evalExpression as a class/static method

Post by Zoltan »

I would like to evaluate an expression using FreeCAD's expression engine. The expression I have at hand is not connected to any document object, I just want to use the evaluation capability of the expression engine, something like this:

Code: Select all

App.DocumentObject.evalExpression('2+2')
It doesn't work, so I guess evalExpression cannot be called as a class method. It is a pity because creating a dummy object (and hide it) just for the sake of the evaluation capability seems an overkill to me:

Code: Select all

obj = App.ActiveDocument.addObject('App::FeaturePython')
obj.ViewObject.ShowInTree = False
obj.evalExpression('2+2')
Is there a simpler way?
openBrain
Veteran
Posts: 9041
Joined: Fri Nov 09, 2018 5:38 pm
Contact:

Re: evalExpression as a class/static method

Post by openBrain »

With a mobile now so can't test by myself, does that work?

Code: Select all

App.DocumentObject().evalExpression('2+2')
Zoltan
Posts: 62
Joined: Wed Jul 07, 2021 10:08 am

Re: evalExpression as a class/static method

Post by Zoltan »

@openBrain
Makes sense to try the evalExpression on the object and not on the class. However, it does not work either (seems to be an abstract class). Here are the tracebacks:

Code: Select all

>>> App.DocumentObject().evalExpression('2+2')
Traceback (most recent call last):
  File "<input>", line 1, in <module>
RuntimeError: You cannot create directly an instance of 'DocumentObjectPy'.

Code: Select all

>>> App.DocumentObject.evalExpression('2+2')
Traceback (most recent call last):
  File "<input>", line 1, in <module>
TypeError: descriptor 'evalExpression' for 'App.DocumentObject' objects doesn't apply to a 'str' object
chrisb
Veteran
Posts: 54192
Joined: Tue Mar 17, 2015 9:14 am

Re: evalExpression as a class/static method

Post by chrisb »

openBrain wrote: Wed Sep 22, 2021 12:50 pm

Code: Select all

App.DocumentObject().evalExpression('2+2')
Doesn't work either. Message:

Code: Select all

Traceback (most recent call last):
  File "<input>", line 1, in <module>
RuntimeError: You cannot create directly an instance of 'DocumentObjectPy'.
A Sketcher Lecture with in-depth information is available in English, auf Deutsch, en français, en español.
openBrain
Veteran
Posts: 9041
Joined: Fri Nov 09, 2018 5:38 pm
Contact:

Re: evalExpression as a class/static method

Post by openBrain »

Zoltan wrote: Wed Sep 22, 2021 12:56 pm @openBrain
Makes sense to try the evalExpression on the object and not on the class. However, it does not work either (seems to be an abstract class). Here are the tracebacks:

Code: Select all

>>> App.DocumentObject().evalExpression('2+2')
Traceback (most recent call last):
  File "<input>", line 1, in <module>
RuntimeError: You cannot create directly an instance of 'DocumentObjectPy'.
Unfortunately this is what I expected but want to give a try though...
TheMarkster
Veteran
Posts: 5513
Joined: Thu Apr 05, 2018 1:53 am

Re: evalExpression as a class/static method

Post by TheMarkster »

You could check to see if there are any objects in the document already and use one of them.

Code: Select all

if App.ActiveDocument and App.ActiveDocument.Objects:
    App.ActiveDocument.Objects[0].evalExpression("3*2")
Is there a way to make a document object that does not appear in the tree? I know there is a context menu option to hide the object, but it still appears in the tree, but with some kind of overlay added to the icon.
Snip macro screenshot-aedc86.png
Snip macro screenshot-aedc86.png (66.09 KiB) Viewed 1730 times
Zoltan
Posts: 62
Joined: Wed Jul 07, 2021 10:08 am

Re: evalExpression as a class/static method

Post by Zoltan »

TheMarkster wrote: Wed Sep 22, 2021 5:13 pm You could check to see if there are any objects in the document already and use one of them.

Code: Select all

if App.ActiveDocument and App.ActiveDocument.Objects:
    App.ActiveDocument.Objects[0].evalExpression("3*2")
Is there a way to make a document object that does not appear in the tree? I know there is a context menu option to hide the object, but it still appears in the tree, but with some kind of overlay added to the icon.

Snip macro screenshot-aedc86.png
True, but I cannot count on the fact that at least one document object exists.
The object appears only if the "Show Hidden Items" is enabled in the context menu. You can also hide an item programmatically (as I showed above) by

Code: Select all

obj.ViewObject.ShowInTree = False
A third way to hide an object: select it, click on the View tab, and then change the Boolean value of the "Show In Tree" property.
By the way, this is how I found this property programmatically: hover your mouse over the "Show In Tree" text to see that its underlying property is "ShowInTree".
TheMarkster
Veteran
Posts: 5513
Joined: Thu Apr 05, 2018 1:53 am

Re: evalExpression as a class/static method

Post by TheMarkster »

Zoltan wrote: Wed Sep 22, 2021 9:12 pm
True, but I cannot count on the fact that at least one document object exists.
You can't count on it, but by checking first you can avoid creating one unnecessarily in some instances.
The object appears only if the "Show Hidden Items" is enabled in the context menu. You can also hide an item programmatically (as I showed above) by

Code: Select all

obj.ViewObject.ShowInTree = False
A third way to hide an object: select it, click on the View tab, and then change the Boolean value of the "Show In Tree" property.
Ah, yes, thanks. I overlooked that (ShowInTree) in your post. I might be able to use this for something I have on the back burner. I experimented by entering it in the python console, but still I get the overlay icon and the object is still in the tree unless I toggle Show Hidden on/off, but I don't know how to do that in python. Maybe it works better in a macro/workbench.

What I would really like to be able to do is create a sketch in memory not in the tree with something akin to Part.makeLoft(), but it would be Sketch.makeSketch() or something along those lines.
By the way, this is how I found this property programmatically: hover your mouse over the "Show In Tree" text to see that its underlying property is "ShowInTree".
Neat trick. I can't seem to reproduce. I don't see anything when I hover the mouse over Show in Tree. Is this in a debugger?
wmayer
Founder
Posts: 20306
Joined: Thu Feb 19, 2009 10:32 am
Contact:

Re: evalExpression as a class/static method

Post by wmayer »

Here you will find the implementation of evalExpression() and as you can see the first parameter passed to Expression::parse() is getDocumentObjectPtr() that points to an instance of a DocumentObject.

As a test I have replaced getDocumentObjectPtr() with nullptr and calling

Code: Select all

obj.evalExpression("2+2+")
succeeded. So, this means it's possible that an expression can be evaluated outside the context of a DocumentObject instance and thus a class method should work, too.
Zoltan
Posts: 62
Joined: Wed Jul 07, 2021 10:08 am

Re: evalExpression as a class/static method

Post by Zoltan »

I experimented by entering it in the python console, but still I get the overlay icon
That icon indicates that the object is hidden.
and the object is still in the tree unless I toggle Show Hidden on/off
If you enable showing the hidden items, they will be shown of course.
but I don't know how to do that in python
Do this:

Code: Select all

App.ActiveDocument.ShowHidden = True
I don't see anything when I hover the mouse over Show in Tree.
Here is a GIF that demonstrates it.
6yfRUbGTWd.gif
6yfRUbGTWd.gif (175.25 KiB) Viewed 1536 times
What I would really like to be able to do is create a sketch in memory not in the tree
When you create a document object and add it to the document, it will appear in the tree view (unless you hide it). If you want to work "in-memory", do not associate your custom class object with the Proxy field of a document object.
Post Reply