Macro Animator v.0.2023.09.30c

Info about new community or project announcements, implemented features, classes, modules or APIs. Might get technical!
PLEASE DO NOT POST HELP REQUESTS OR OTHER DISCUSSIONS HERE!
Forum rules
Be nice to others! Respect the FreeCAD code of conduct!
TheMarkster
Veteran
Posts: 5505
Joined: Thu Apr 05, 2018 1:53 am

Macro Animator v.0.2023.09.30c

Post by TheMarkster »

Newest version 0.2023.09.30c (see last post for details)

Latest version has ability to run a macro script each time through the loop, giving the user some additional control over the animation. The macro can be in a file, in a string list property of the Animator object, or both, or neither. The macro is called each frame of the loop so it should do its work as quickly as possible.

Obviously, this is a security risk. A warning and a confirmation is required each time the animation begins. This is to prevent unsuspecting users from downloading file with malicious code and running the code without getting the opportunity to decline permission. Malicious code could be embedded in the MacroString property.
Snip macro screenshot-9f5b0b.png
Snip macro screenshot-9f5b0b.png (26.48 KiB) Viewed 3865 times
It's up to the user to inspect the code if this is a file shared from some untrusted source to see whether there is anything malicious in it. If in doubt, don't run it.

There are some special defines available to the scripts as local variables within the script.

* FreeCAD (or App)
* FreeCADGui (or Gui)
* doc (document containing Animator object)
* AnimatorLastFrame (boolean set to True if this is the last frame of the animation)
* Animator (or fp) (Animator object)
* con (FreeCAD.Console -example: con.PrintMessage())
* props (0-indexed list of the properties referenced in the VariableNNN properties -- example Variable001 = "Sketch.Constraints.Height", so props[0] = "Constraints.Height")
* objs (0-indexed list of the objects referenced in the VariableNNN properties -- example from above objs[0] = Sketch object)
* setExpression(idx,expr) -- setExpression(0,"12") sets Sketch.Constraints.Height to 12. (expr must be a string value)
* getValue(idx) -- getValue(0) returns 12.0 from above example. This always returns a floating point unitless value, which has been rounded to 6 digits.
* setStep(idx,val) -- setStep(0,0) sets Variable001 Step = 0. (Step = 0 means do not animate this property during this frame. Step = 4 means set the value of this property to 4 * current_frame. The current frame can be gotten as fp.CurrentFrame.


Introducing Macro Animator

Available for installing via the Addon Manager (Tools menu) in the Macros tab.
Animator.png
Animator.png (4.91 KiB) Viewed 9854 times
Animator.svg
(7.26 KiB) Downloaded 91 times
With Macro Animator you can easily animate your models by animating its various properties with this feature python object. Just select a property to animate and double click the Animator object in the tree to begin animating. Double click again to stop the animation or wait until if finishes the animation loop.

Animator_scr1.png
Animator_scr1.png (27.87 KiB) Viewed 9858 times
By default 3 variables are available, but you can easily add more by modifying the Variable Count property. Each Variable can animate a selected property. You can have as many as 100 different Variables if you like, or even more, but obviously this would bring FreeCAD to a crawl. By default, there are 100 Frames per animation loop. Properties are set at 0 to Start and incremented by Step each iteration through the loop. Some iterations may be skipped by using the Nth property.

If there is an expression set for an animated property, the expression is restored at the end of the loop. Exception: animated Spreadsheet aliases that contain expressions are not restored. Sketcher named constraints may be animated as well as standard properties. Properties not bound by expressions retain their values set in the final Frame of the animation loop, so if you want them to be restored set them as expressions.

Full documentation on github at:

https://github.com/mwganson/animator
Last edited by TheMarkster on Sat Sep 30, 2023 7:20 pm, edited 5 times in total.
chrisb
Veteran
Posts: 53930
Joined: Tue Mar 17, 2015 9:14 am

Re: Lights, Camera, Action! Macro Animator

Post by chrisb »

No time to test now, but this sounds great. Thanks!
A Sketcher Lecture with in-depth information is available in English, auf Deutsch, en français, en español.
galou_breizh
Posts: 436
Joined: Wed Sep 15, 2010 9:38 am

Re: Lights, Camera, Action! Macro Animator

Post by galou_breizh »

TheMarkster wrote: Fri Oct 29, 2021 3:58 am Introducing Macro Animator
Thanks for sharing!

I wanted to invite you to submit your macro to the official macro repository. You don't need to use the trick to create `animator.py` as the addon-manager is able to install and remove dependent files as long as they are listed in the __files__ metadata variable. Please be aware that when adding your macro to the official repository, other people might modify (improve) it.

Gaël
User avatar
Shalmeneser
Veteran
Posts: 9475
Joined: Wed Dec 23, 2020 12:04 am
Location: Fr

Re: Lights, Camera, Action! Macro Animator

Post by Shalmeneser »

TheMarkster wrote: Fri Oct 29, 2021 3:58 am ...
Seems great. 8-)

Animator variables will be created at the creation time of Animator object.
If you want to modify a dimension in a sketch, you need to give it an alias before creating Animator.

Body.Placement.Rotation.X/Y/Z doesn't seem to work.
TheMarkster
Veteran
Posts: 5505
Joined: Thu Apr 05, 2018 1:53 am

Re: Lights, Camera, Action! Macro Animator

Post by TheMarkster »

Shalmeneser wrote: Fri Oct 29, 2021 12:17 pm
TheMarkster wrote: Fri Oct 29, 2021 3:58 am ...
Seems great. 8-)

Animator variables will be created at the creation time of Animator object.
If you want to modify a dimension in a sketch, you need to give it an alias before creating Animator.
You can use the Refresh property to update the property lists if you change the document, such as adding aliases, creating new objects, etc. Toggle Refresh from False to True. It serves as a trigger for the refresh command, and sets itself back to False. Spreadsheet cells should be accessible via the cell address, too, example B5 even if there is no alias.

Spreadsheets are handled differently from other properties because the ExpressionEngine property doesn't contain any expressions used for any of the cells. That's the mechanism for restoring the expressions after the animation loop finishes, and without it, spreadsheet cells that are animated will lose their expressions. Others all get restored, even sketch constraints. Obviously, all of this is practically untested at this point.
Body.Placement.Rotation.X/Y/Z doesn't seem to work.
The rotation x/y/z values are probably being affected by the way FreeCAD converts these back and forth to different formats internally. This is why the Euler values in the placement dialog can get quirky at times. You have rotation angle / axis format, you have euler format, you have quaternions, matrices, gimbal lock workarounds, the list goes on. On top of that it's possible these values can get normalized along the way, too. It's probably not a good idea to animate the rotation axis, but I'm going to leave it as an option.

By the way, here's how the code animates a property. You can try this in python console if you want to experiment. The property string is in the format objectname.property.subproperty.subproperty for properties like Vector, Placement, Matrix, that have subproperties. The code extracts the objectname and uses it to fetch the object:

Code: Select all

objname = "Body" #except it's extracted from the property name using split('.')[0]
obj = doc.getObject(objname)
obj.setExpression("Placement.Rotation.Axis.x","23.5") #except, again, not string literals
obj.setExpression("Placement.Rotation.Axis.x",None) #to remove the expression we just set, but leave the value of 23.5 intact
sebasg84
Posts: 13
Joined: Thu Jun 10, 2021 2:12 pm

Re: Lights, Camera, Action! Macro Animator

Post by sebasg84 »

This macro nicely complements a gear workbench I just created.

link to InvGears workbench:
https://github.com/sebasg84/InvGears


Do you have any problem if I insert your macro into this workbench?

https://youtu.be/na9IrsthYN8
phpBB [video]


If you agree, I´ll update the workbench with animator, and of course I make reference to https://github.com/mwganson/animator
Last edited by sebasg84 on Sun Oct 31, 2021 8:48 pm, edited 1 time in total.
TheMarkster
Veteran
Posts: 5505
Joined: Thu Apr 05, 2018 1:53 am

Re: Lights, Camera, Action! Macro Animator

Post by TheMarkster »

You may use it if you like.
TheMarkster
Veteran
Posts: 5505
Joined: Thu Apr 05, 2018 1:53 am

Re: Macro Animator v.0.2023.09.12 (now with macro access)

Post by TheMarkster »

New version 0.2023.09.12e
TheMarkster
Veteran
Posts: 5505
Joined: Thu Apr 05, 2018 1:53 am

Re: Macro Animator v.0.2023.09.13 (now makes animated gifs)

Post by TheMarkster »

Bug fix. Latest version 0.2023.09.16.

The permission dialog wasn't returning True when the user clicked the button to allow the python code to run. I don't know how I missed that in testing.
TheMarkster
Veteran
Posts: 5505
Joined: Thu Apr 05, 2018 1:53 am

Re: Macro Animator v.0.2023.09.13 (now makes animated gifs)

Post by TheMarkster »

Newest version 0.2023.09.29

I added some cam positioning options for the macros being run as strings in the MacroString property or as macro files in the MacroFile property. The cam object is already available to the macro strings. These functions are wrapped into a Camera class, which can be also imported from the python console or other macros:

Code: Select all

from animator import Camera
cam = Camera()
dir(cam) #to see a list of available attributes
cam.setHeight(10) #sets the camera height at 10
cam.setPosition(vector) #sets the camera position at vector (also accepts 3 floats: setPosition(x,y,z)
cam.setOrientation(axis,angle)#  Axis is a vector, angle is angle in degrees.
cam.setOrientationEuler(yaw, pitch, roll)# these are floats
cam.setFocalDistance(float)
cam.setAspectRatio(float) #ratio of width to height
cam.setNearDistance(float) #sets clipping for close objects
cam.setFarDistance(float)# sets clipping for distant objects
There are corresponding cam.get functions, too.

cam.getHeader() returns the version, currently Inventor 2.1
cam.getType() returns Orthographic or Perspective

Should be a way to do a fly through with these capabilities.

I also added a Macro String editor for the Macro String, so we don't have to contend with editing with the String List property editor. The editor is just a very basic QPlainTextEdit with some syntax highlighting. The editor is available from the context menu. Right click the Animator object, select Edit Macro String from menu.

Double clicking will now animate even if no property has been selected to animate if there is a non-default macro string and run macro string is true or there is a macro file being pointed to in the Macro File property and the run macro property is true.

A Freeze Camera boolean property has been added. This will restore the camera position and orientation at the end of each frame during the animation.
Post Reply