summaryrefslogtreecommitdiff
path: root/Build/source/utils/asymptote/base/animation.asy
diff options
context:
space:
mode:
Diffstat (limited to 'Build/source/utils/asymptote/base/animation.asy')
-rw-r--r--Build/source/utils/asymptote/base/animation.asy179
1 files changed, 179 insertions, 0 deletions
diff --git a/Build/source/utils/asymptote/base/animation.asy b/Build/source/utils/asymptote/base/animation.asy
new file mode 100644
index 00000000000..2b7519c700a
--- /dev/null
+++ b/Build/source/utils/asymptote/base/animation.asy
@@ -0,0 +1,179 @@
+/*****
+ * animation.asy
+ * Andy Hammerlindl and John Bowman 2005/11/06
+ *
+ * Produce GIF, inline PDF, or other animations.
+ *****/
+
+// animation delay is in milliseconds
+real animationdelay=50;
+
+typedef frame fit(string prefix="",picture);
+
+frame NoBox(string prefix="", picture pic) {
+ return pic.fit(prefix);
+}
+
+fit BBox(string prefix="", real xmargin=0, real ymargin=xmargin,
+ pen p=currentpen, filltype filltype=NoFill) {
+ return new frame(string prefix, picture pic) {
+ return bbox(prefix,pic,xmargin,ymargin,p,filltype);
+ };
+}
+
+struct animation {
+ picture[] pictures;
+ string[] files;
+ int index;
+
+ string prefix;
+ bool global; // If true, use a global scaling for all frames; this requires
+ // extra memory since the actual shipout is deferred until all frames have
+ // been generated.
+
+ void operator init(string prefix="", bool global=true) {
+ prefix=replace((prefix == "") ? outprefix() : stripdirectory(prefix),
+ " ","_");
+ this.prefix=prefix;
+ this.global=global;
+ }
+
+ string basename(string prefix=prefix) {
+ return "_"+stripextension(prefix);
+ }
+
+ string name(string prefix, int index) {
+ return stripextension(prefix)+"+"+string(index);
+ }
+
+ private string nextname() {
+ string name=name(prefix,index);
+ ++index;
+ return name;
+ }
+
+ void shipout(string name=nextname(), frame f) {
+ string format=nativeformat();
+ plain.shipout(name,f,format=format,view=false);
+ files.push(name+"."+format);
+ shipped=false;
+ }
+
+ void add(picture pic=currentpicture, fit fit=NoBox) {
+ if(global) {
+ pictures.push(pic.copy());
+ } else this.shipout(nextname(),fit(prefix,pic));
+ }
+
+ void purge(bool keep=settings.keep) {
+ if(!keep) {
+ for(int i=0; i < files.length; ++i)
+ delete(files[i]);
+ }
+ }
+
+ int merge(int loops=0, real delay=animationdelay, string format="gif",
+ string options="", bool keep=settings.keep) {
+ string args="-loop " +(string) loops+" -delay "+(string)(delay/10)+
+ " -alpha Off -dispose Background "+options;
+ for(int i=0; i < files.length; ++i)
+ args += " " +files[i];
+ int rc=convert(args,prefix+"."+format,format=format);
+ this.purge(keep);
+ if(rc == 0) animate(file=prefix+"."+format,format=format);
+ else abort("merge failed");
+ return rc;
+ }
+
+ // Export all frames with the same scaling.
+ void export(string prefix=prefix, fit fit=NoBox,
+ bool multipage=false, bool view=false) {
+ if(pictures.length == 0) return;
+ rescale(pictures);
+ frame multi;
+ bool inlinetex=settings.inlinetex;
+ if(multipage)
+ settings.inlinetex=false;
+ for(int i=0; i < pictures.length; ++i) {
+ if(multipage) {
+ add(multi,fit(prefix,pictures[i]));
+ newpage(multi);
+ } else {
+ if(pictures[i].empty3() || settings.render <= 0) {
+ real render=settings.render;
+ settings.render=0;
+ this.shipout(name(prefix,i),fit(prefix,pictures[i]));
+ settings.render=render;
+ } else { // Render 3D frames
+ files.push(name(prefix,i)+"."+nativeformat());
+ fit(prefix,pictures[i]);
+ }
+ }
+ }
+ if(multipage) {
+ plain.shipout(prefix,multi,view=view);
+ settings.inlinetex=inlinetex;
+ }
+ shipped=true;
+ }
+
+ string load(int frames, real delay=animationdelay, string options="",
+ bool multipage=false) {
+ string s="\animategraphics["+options+"]{"+format("%.18f",1000/delay,"C")+
+ "}{"+basename();
+ if(!multipage) s += "+";
+ s += "}{0}{"+string(frames-1)+"}";
+ return s;
+ }
+
+ string pdf(fit fit=NoBox, real delay=animationdelay, string options="",
+ bool keep=settings.keep, bool multipage=true) {
+ if(settings.inlinetex) multipage=true;
+ if(settings.tex != "pdflatex")
+ abort("inline pdf animations require -tex pdflatex");
+ if(settings.outformat != "") settings.outformat="pdf";
+
+ string filename=basename();
+ string pdfname=filename+".pdf";
+ bool single=global && multipage;
+
+ if(global)
+ export(filename,fit,multipage=multipage);
+
+ shipped=false;
+
+ if(!keep && !settings.inlinetex) {
+ exitfcn currentexitfunction=atexit();
+ void exitfunction() {
+ if(currentexitfunction != null) currentexitfunction();
+ this.purge();
+ if(single)
+ delete(pdfname);
+ }
+ atexit(exitfunction);
+ }
+
+ if(!single)
+ delete(pdfname);
+
+ return load(pictures.length,delay,options,multipage);
+ }
+
+ int movie(fit fit=NoBox, int loops=0, real delay=animationdelay,
+ string format=settings.outformat == "" ? "gif" : settings.outformat,
+ string options="", bool keep=settings.keep) {
+ if(global && format == "pdf") {
+ export(fit,multipage=true,view=true);
+ return 0;
+ }
+
+ if(global)
+ export(fit);
+ return merge(loops,delay,format,options,keep);
+ }
+}
+
+animation operator init() {
+ animation a=animation();
+ return a;
+}