summaryrefslogtreecommitdiff
path: root/Build/source/utils/asymptote/runpicture.in
diff options
context:
space:
mode:
Diffstat (limited to 'Build/source/utils/asymptote/runpicture.in')
-rw-r--r--Build/source/utils/asymptote/runpicture.in605
1 files changed, 605 insertions, 0 deletions
diff --git a/Build/source/utils/asymptote/runpicture.in b/Build/source/utils/asymptote/runpicture.in
new file mode 100644
index 00000000000..20686c1b6b7
--- /dev/null
+++ b/Build/source/utils/asymptote/runpicture.in
@@ -0,0 +1,605 @@
+/*****
+ * runpicture.in
+ *
+ * Runtime functions for picture operations.
+ *
+ *****/
+
+pen => primPen()
+pair => primPair()
+triple => primTriple()
+path => primPath()
+path3 => primPath3()
+picture* => primPicture()
+Intarray* => IntArray()
+realarray* => realArray()
+realarray2* => realArray2()
+patharray* => pathArray()
+penarray* => penArray()
+penarray2* => penArray2()
+pairarray* => pairArray()
+pairarray2* => pairArray2()
+triplearray* => tripleArray()
+triplearray2* => tripleArray2()
+transform => primTransform()
+callableTransform* => transformFunction()
+
+#include "picture.h"
+#include "drawelement.h"
+#include "path.h"
+#include "array.h"
+#include "arrayop.h"
+#include "drawpath.h"
+#include "drawfill.h"
+#include "drawclipbegin.h"
+#include "drawclipend.h"
+#include "drawgsave.h"
+#include "drawgrestore.h"
+#include "drawgroup.h"
+#include "drawverbatim.h"
+#include "drawlabel.h"
+#include "drawlayer.h"
+#include "drawimage.h"
+#include "drawpath3.h"
+#include "drawsurface.h"
+
+using namespace camp;
+using namespace settings;
+using namespace vm;
+
+typedef array Intarray;
+typedef array realarray;
+typedef array realarray2;
+typedef array pairarray;
+typedef array pairarray2;
+typedef array triplearray;
+typedef array triplearray2;
+typedef array patharray;
+typedef array penarray;
+typedef array penarray2;
+
+typedef callable callableTransform;
+
+using types::IntArray;
+using types::realArray;
+using types::realArray2;
+using types::pairArray;
+using types::pairArray2;
+using types::tripleArray;
+using types::tripleArray2;
+using types::pathArray;
+using types::penArray;
+using types::penArray2;
+
+function *transformFunction()
+{
+ return new function(primTransform());
+}
+
+// Ignore unclosed begingroups but not spurious endgroups.
+const char *nobegin="endgroup without matching begingroup";
+
+array *emptyarray=new array(0);
+
+array *nop(array *a)
+{
+ return a;
+}
+
+// Autogenerated routines:
+
+
+picture* :newPicture()
+{
+ return new picture();
+}
+
+bool empty(picture *f)
+{
+ return f->null();
+}
+
+void erase(picture *f)
+{
+ f->nodes.clear();
+}
+
+pair min(picture *f)
+{
+ return f->bounds().Min();
+}
+
+pair max(picture *f)
+{
+ return f->bounds().Max();
+}
+
+void _draw(picture *f, path g, pen p)
+{
+ f->append(new drawPath(g,p));
+}
+
+void fill(picture *f, patharray *g, pen p=CURRENTPEN, bool copy=true)
+{
+ array *(*copyarray)(array *a)=copy ? copyArray: nop;
+ f->append(new drawFill(*copyarray(g),false,p));
+}
+
+void latticeshade(picture *f, patharray *g, bool stroke=false,
+ pen fillrule=CURRENTPEN, penarray2 *p, bool copy=true)
+{
+ array *(*copyarray)(array *a)=copy ? copyArray: nop;
+ f->append(new drawLatticeShade(*copyarray(g),stroke,fillrule,*copyarray(p)));
+}
+
+void axialshade(picture *f, patharray *g, bool stroke=false, pen pena, pair a,
+ pen penb, pair b, bool copy=true)
+{
+ array *(*copyarray)(array *a)=copy ? copyArray: nop;
+ f->append(new drawAxialShade(*copyarray(g),stroke,pena,a,penb,b));
+}
+
+void radialshade(picture *f, patharray *g, bool stroke=false, pen pena,
+ pair a, real ra, pen penb, pair b, real rb, bool copy=true)
+{
+ array *(*copyarray)(array *a)=copy ? copyArray: nop;
+ f->append(new drawRadialShade(*copyarray(g),stroke,pena,a,ra,penb,b,rb));
+}
+
+void gouraudshade(picture *f, patharray *g, bool stroke=false,
+ pen fillrule=CURRENTPEN, penarray *p, pairarray *z,
+ Intarray *edges, bool copy=true)
+{
+ array *(*copyarray)(array *a)=copy ? copyArray: nop;
+ checkArrays(p,z);
+ checkArrays(z,edges);
+ f->append(new drawGouraudShade(*copyarray(g),stroke,fillrule,*copyarray(p),
+ *copyarray(z),*copyarray(edges)));
+}
+
+void gouraudshade(picture *f, patharray *g, bool stroke=false,
+ pen fillrule=CURRENTPEN, penarray *p, Intarray *edges,
+ bool copy=true)
+{
+ array *(*copyarray)(array *a)=copy ? copyArray: nop;
+ size_t n=checkArrays(p,edges);
+ size_t m=checkArray(g);
+ array *z=new array(n);
+ Int k=0;
+ Int in=(Int) n;
+ for(size_t j=0; j < m; ++j) {
+ path *P=read<path *>(g,j);
+ assert(P);
+ Int stop=Min(P->size(),in-k);
+ mem::vector<solvedKnot>& nodes=P->Nodes();
+ for(Int i=0; i < stop; ++i)
+ (*z)[k++]=nodes[i].point;
+ }
+ checkArrays(p,z);
+
+ f->append(new drawGouraudShade(*copyarray(g),stroke,fillrule,*copyarray(p),
+ *z,*copyarray(edges)));
+}
+
+void tensorshade(picture *f, patharray *g, bool stroke=false,
+ pen fillrule=CURRENTPEN, penarray2 *p, patharray *b=NULL,
+ pairarray2 *z=emptyarray, bool copy=true)
+{
+ array *(*copyarray)(array *a)=copy ? copyArray: nop;
+ array *(*copyarray2)(array *a)=copy ? copyArray2: nop;
+ if(b == NULL) b=g;
+ size_t n=checkArrays(p,b);
+ size_t nz=checkArray(z);
+ if(nz != 0)
+ checkEqual(nz,n);
+ f->append(new drawTensorShade(*copyarray(g),stroke,fillrule,*copyarray2(p),
+ *copyarray(b),*copyarray2(z)));
+}
+
+void functionshade(picture *f, patharray *g, bool stroke=false,
+ pen fillrule=CURRENTPEN, string shader=emptystring,
+ bool copy=true)
+{
+ array *(*copyarray)(array *a)=copy ? copyArray: nop;
+ f->append(new drawFunctionShade(*copyarray(g),stroke,fillrule,shader));
+}
+
+// Clip a picture to a superpath using the given fill rule.
+// Subsequent additions to the picture will not be affected by the clipping.
+void clip(picture *f, patharray *g, bool stroke=false,
+ pen fillrule=CURRENTPEN, bool copy=true)
+{
+ array *(*copyarray)(array *a)=copy ? copyArray: nop;
+ drawClipBegin *begin=new drawClipBegin(*copyarray(g),stroke,fillrule,true);
+ f->enclose(begin,new drawClipEnd(true,begin));
+}
+
+void beginclip(picture *f, patharray *g, bool stroke=false,
+ pen fillrule=CURRENTPEN, bool copy=true)
+{
+ array *(*copyarray)(array *a)=copy ? copyArray: nop;
+ f->append(new drawClipBegin(*copyarray(g),stroke,fillrule,false));
+}
+
+void endclip(picture *f)
+{
+ f->append(new drawClipEnd(false));
+}
+
+void gsave(picture *f)
+{
+ f->append(new drawGsave());
+}
+
+void grestore(picture *f)
+{
+ f->append(new drawGrestore());
+}
+
+void begingroup(picture *f, string name=emptystring)
+{
+ f->append(new drawBegin(name));
+}
+
+void endgroup(picture *f)
+{
+ f->append(new drawEnd());
+}
+
+void add(picture *dest, picture *src)
+{
+ dest->add(*src);
+}
+
+void prepend(picture *dest, picture *src)
+{
+ dest->prepend(*src);
+}
+
+void postscript(picture *f, string s)
+{
+ f->append(new drawVerbatim(PostScript,s));
+}
+
+void tex(picture *f, string s)
+{
+ f->append(new drawVerbatim(TeX,s));
+}
+
+void postscript(picture *f, string s, pair min, pair max)
+{
+ f->append(new drawVerbatim(PostScript,s,min,max));
+}
+
+void tex(picture *f, string s, pair min, pair max)
+{
+ f->append(new drawVerbatim(TeX,s,min,max));
+}
+
+void texpreamble(string s)
+{
+ string t=s+"\n";
+ processDataStruct &pd=processData();
+ pd.TeXpipepreamble.push_back(t);
+ pd.TeXpreamble.push_back(t);
+}
+
+void deletepreamble()
+{
+ if(getSetting<bool>("inlinetex")) {
+ unlink(auxname(outname(),"pre").c_str());
+ }
+}
+
+void _labelpath(picture *f, string s, string size, path g, string justify,
+ pair offset, pen p)
+{
+ f->append(new drawLabelPath(s,size,g,justify,offset,p));
+}
+
+void texreset()
+{
+ processDataStruct &pd=processData();
+ pd.TeXpipepreamble.clear();
+ pd.TeXpreamble.clear();
+ pd.tex.pipeclose();
+}
+
+void layer(picture *f)
+{
+ f->append(new drawLayer());
+}
+
+void newpage(picture *f)
+{
+ f->append(new drawNewPage());
+}
+
+void _image(picture *f, realarray2 *data, pair initial, pair final,
+ penarray *palette=NULL, transform t=identity, bool copy=true,
+ bool antialias=false)
+{
+ array *(*copyarray)(array *a)=copy ? copyArray: nop;
+ array *(*copyarray2)(array *a)=copy ? copyArray2: nop;
+ f->append(new drawImage(*copyarray2(data),*copyarray(palette),
+ t*matrix(initial,final),antialias));
+}
+
+void _image(picture *f, penarray2 *data, pair initial, pair final,
+ transform t=identity, bool copy=true, bool antialias=false)
+{
+ array *(*copyarray2)(array *a)=copy ? copyArray2: nop;
+ f->append(new drawImage(*copyarray2(data),t*matrix(initial,final),antialias));
+}
+
+string nativeformat()
+{
+ return nativeformat();
+}
+
+bool latex()
+{
+ return latex(getSetting<string>("tex"));
+}
+
+bool pdf()
+{
+ return pdf(getSetting<string>("tex"));
+}
+
+void shipout(string prefix=emptystring, picture *f, picture *preamble=NULL,
+ string format=emptystring, bool wait=false, bool view=true,
+ callableTransform *xform)
+{
+ if(prefix.empty()) prefix=outname();
+
+ picture *result=new picture;
+ unsigned level=0;
+ picture::nodelist::iterator p;
+ for(p = f->nodes.begin(); p != f->nodes.end(); ++p) {
+ xform->call(Stack);
+ transform t=pop<transform>(Stack);
+ static transform Zero=transform(0.0,0.0,0.0,0.0,0.0,0.0);
+ bool Delete=(t == Zero);
+ picture *group=new picture;
+ assert(*p);
+ if((*p)->endgroup()) error(nobegin);
+ if((*p)->begingroup()) {
+ ++level;
+ while(p != f->nodes.end() && level) {
+ if(!Delete) {
+ drawElement *e=t.isIdentity() ? *p : (*p)->transformed(t);
+ group->append(e);
+ }
+ ++p;
+ if(p == f->nodes.end()) break;
+ assert(*p);
+ if((*p)->begingroup()) ++level;
+ if((*p)->endgroup()) {
+ if(level) --level;
+ else error(nobegin);
+ }
+ }
+ }
+ if(p == f->nodes.end()) break;
+ assert(*p);
+ if(!Delete) {
+ drawElement *e=t.isIdentity() ? *p : (*p)->transformed(t);
+ group->append(e);
+ result->add(*group);
+ }
+ }
+
+ result->shipout(preamble,prefix,format,0.0,wait,view);
+}
+
+void shipout3(string prefix, picture *f, string format=emptystring,
+ real width, real height, real angle, real zoom,
+ triple m, triple M, pair shift, realarray2 *t,
+ realarray *background, triplearray *lights, realarray2 *diffuse,
+ realarray2 *ambient, realarray2 *specular,
+ bool viewportlighting, bool view=true)
+{
+ size_t n=checkArrays(lights,diffuse);
+ checkEqual(n,checkArray(ambient));
+ checkEqual(n,checkArray(specular));
+
+ real *T=copyArray2C(t,true,4);
+ triple *Lights=copyTripleArrayC(lights);
+ real* Background=copyArrayC(background);
+ real *Diffuse=copyArray2C(diffuse,false,4);
+ real *Ambient=copyArray2C(ambient,false,4);
+ real *Specular=copyArray2C(specular,false,4);
+
+ f->shipout3(prefix,format,width,height,angle,zoom,m,M,shift,T,Background,n,
+ Lights,Diffuse,Ambient,Specular,viewportlighting,view);
+
+ delete[] Specular;
+ delete[] Ambient;
+ delete[] Diffuse;
+ delete[] Background;
+ delete[] Lights;
+ delete[] T;
+}
+
+void shipout3(string prefix, picture *f)
+{
+ f->shipout3(prefix);
+}
+
+void deconstruct(picture *f, picture *preamble=NULL, real magnification=1,
+ callableTransform *xform)
+{
+ unsigned level=0;
+ unsigned n=0;
+
+ string prefix=outname();
+ const string xformat="png";
+
+ static long arg_max=sysconf(_SC_ARG_MAX);
+ const unsigned maxargs=::min(arg_max/(prefix.size()+xformat.size()+25ul),
+ 256ul);
+
+ cout << maxargs << newl;
+
+ string preformat=nativeformat();
+ const string Done="Done";
+ const string Error="Error";
+
+ mem::vector<string> cmd;
+
+ // Enforce ghostscript limitations.
+ magnification=::max(magnification,0.0001);
+ real res=::min(::max(magnification*72.0,2.0),8192.0);
+
+ const char *converter=NULL, *hint=NULL;
+
+ if(magnification > 0.0) {
+ mem::list<string> nameStack;
+ string outname;
+ unsigned arg=0;
+ unsigned batch=0;
+ for(picture::nodelist::iterator p=f->nodes.begin();;) {
+ if(p == f->nodes.end()) break;
+ if(arg == 0) {
+ cmd.clear();
+ ostringstream buf;
+ buf << batch << "_";
+ outname=buildname(prefix+buf.str()+"%d",xformat,"");
+ converter="gs";
+ hint="Ghostscript";
+ cmd.push_back(getSetting<string>(converter));
+ cmd.push_back("-q");
+ cmd.push_back("-dNOPAUSE");
+ cmd.push_back("-dBATCH");
+ cmd.push_back("-sDEVICE=pngalpha");
+ cmd.push_back("-dEPSCrop");
+ if(safe)
+ cmd.push_back("-dSAFER");
+ cmd.push_back("-r"+String(res)+"x"+String(res));
+ cmd.push_back("-sOutputFile="+outname);
+ }
+
+ picture *group=new picture;
+ xform->call(Stack);
+ transform t=pop<transform>(Stack);
+ assert(*p);
+ if((*p)->endgroup()) {
+ cout << Error << endl;
+ error(nobegin);
+ }
+ if((*p)->begingroup()) {
+ ++level;
+ while(p != f->nodes.end() && level) {
+ drawElement *e=t.isIdentity() ? *p : (*p)->transformed(t);
+ group->append(e);
+ ++p;
+ if(p == f->nodes.end()) break;
+ assert(*p);
+ if((*p)->begingroup()) ++level;
+ if((*p)->endgroup()) {
+ if(level) --level;
+ else {
+ cout << Error << endl;
+ error(nobegin);
+ }
+ }
+ }
+ }
+ if(p != f->nodes.end()) {
+ assert(*p);
+ drawElement *e=t.isIdentity() ? *p : (*p)->transformed(t);
+ group->append(e);
+ bbox b;
+ ostringstream buf;
+ buf << prefix << "_" << n;
+ group->shipout(preamble,buf.str(),preformat,magnification,false,false);
+ string Preformat=group->Transparency() ? "pdf" : preformat;
+ string name=buildname(buf.str(),Preformat);
+ nameStack.push_back(name);
+ cmd.push_back(name);
+ b=group->bounds();
+ b *= magnification;
+
+ cout << b << newl;
+ ++n;
+ ++p;
+ ++arg;
+ }
+
+ if(p == f->nodes.end() || arg >= maxargs) {
+ arg=0;
+ ++batch;
+ cout.flush();
+
+ int status=System(cmd,0,true,converter,hint);
+ if(status) {
+ cout << Error << endl;
+ error("deconstruct failed");
+ }
+ }
+ }
+
+ if(!getSetting<bool>("keep")) {
+ for(mem::list<string>::iterator p=nameStack.begin();
+ p != nameStack.end(); ++p)
+ unlink(p->c_str());
+ }
+
+ cout << Done << endl;
+ }
+}
+
+
+// Three-dimensional picture and surface operations
+
+// Bezier curve
+void _draw(picture *f, path3 g, pen p, string name=emptystring)
+{
+ if(g.size() > 0)
+ f->append(new drawPath3(g,p,name));
+}
+
+// Bezier patch
+void draw(picture *f, triplearray2 *P, bool straight, penarray *p, real opacity,
+ real shininess, real PRCshininess, real granularity, triple normal,
+ penarray *colors, bool lighton, string name=emptystring)
+{
+ f->append(new drawSurface(*P,straight,*p,opacity,shininess,PRCshininess,
+ granularity,normal,*colors,lighton,name));
+}
+
+// General NURBS surface
+void draw(picture *f, triplearray2 *P, realarray *uknot, realarray *vknot,
+ realarray2 *weights=emptyarray, penarray *p,
+ real opacity, real shininess, real PRCshininess, real granularity,
+ penarray *colors, bool lighton, string name=emptystring)
+{
+ f->append(new drawNurbs(*P,uknot,vknot,weights,*p,opacity,shininess,
+ PRCshininess,granularity,*colors,lighton,name));
+}
+
+triple min3(picture *f)
+{
+ return f->bounds3().Min();
+}
+
+triple max3(picture *f)
+{
+ return f->bounds3().Max();
+}
+
+pair minratio(picture *f)
+{
+ return f->ratio(::min);
+}
+
+pair maxratio(picture *f)
+{
+ return f->ratio(::max);
+}
+
+bool is3D(picture *f)
+{
+ return f->have3D();
+}