Macro Animator v.0.2023.09.30c
Forum rules
Be nice to others! Respect the FreeCAD code of conduct!
Be nice to others! Respect the FreeCAD code of conduct!
-
- Veteran
- Posts: 5513
- Joined: Thu Apr 05, 2018 1:53 am
Macro Animator v.0.2023.09.30c
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.
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. 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.
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
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.
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. 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.
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.
Re: Lights, Camera, Action! Macro Animator
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.
-
- Posts: 437
- Joined: Wed Sep 15, 2010 9:38 am
Re: Lights, Camera, Action! 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
- Shalmeneser
- Veteran
- Posts: 9591
- Joined: Wed Dec 23, 2020 12:04 am
- Location: Fr
Re: Lights, Camera, Action! Macro Animator
Seems great.
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.
-
- Veteran
- Posts: 5513
- Joined: Thu Apr 05, 2018 1:53 am
Re: Lights, Camera, Action! Macro 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.Shalmeneser wrote: ↑Fri Oct 29, 2021 12:17 pmSeems great.
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.
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.
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.Body.Placement.Rotation.X/Y/Z doesn't seem to work.
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
Re: Lights, Camera, Action! Macro Animator
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
If you agree, I´ll update the workbench with animator, and of course I make reference to https://github.com/mwganson/animator
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
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.
-
- Veteran
- Posts: 5513
- Joined: Thu Apr 05, 2018 1:53 am
-
- Veteran
- Posts: 5513
- Joined: Thu Apr 05, 2018 1:53 am
-
- Veteran
- Posts: 5513
- Joined: Thu Apr 05, 2018 1:53 am
Re: Macro Animator v.0.2023.09.13 (now makes animated gifs)
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.
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.
-
- Veteran
- Posts: 5513
- Joined: Thu Apr 05, 2018 1:53 am
Re: Macro Animator v.0.2023.09.13 (now makes animated gifs)
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:
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.
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
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.