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.in738
1 files changed, 738 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..ac5bdbc28e6
--- /dev/null
+++ b/Build/source/utils/asymptote/runpicture.in
@@ -0,0 +1,738 @@
+/*****
+ * runpicture.in
+ *
+ * Runtime functions for picture operations.
+ *
+ *****/
+
+pen => primPen()
+pair => primPair()
+triple => primTriple()
+path => primPath()
+path3 => primPath3()
+picture* => primPicture()
+Intarray* => IntArray()
+Intarray2* => IntArray2()
+realarray* => realArray()
+realarray2* => realArray2()
+patharray* => pathArray()
+penarray* => penArray()
+penarray2* => penArray2()
+pairarray* => pairArray()
+pairarray2* => pairArray2()
+triplearray* => tripleArray()
+triplearray2* => tripleArray2()
+transform => primTransform()
+callablePen* => penFunction()
+
+#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 Intarray2;
+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 callablePen;
+
+using types::IntArray;
+using types::IntArray2;
+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;
+
+static transform ZeroTransform=transform(0.0,0.0,0.0,0.0,0.0,0.0);
+
+transform getTransform(xmap_t &xmap, picture::nodelist::iterator p)
+{
+ string s=(*p)->KEY;
+ transform t;
+ // Don't apply xmap without an explicit corresponding key
+ size_t n=s.length();
+ if(n == 0 || s.substr(n-1) != "1") return t;
+
+ xmap_t::iterator q=xmap.find(s.substr(0,n-2));
+ if(q != xmap.end()) {
+ xtransform_t& v=q->second;
+ if(!v.empty()) {
+ t=v.front();
+ v.pop_front();
+ }
+ }
+ return t;
+}
+
+
+function *transformFunction()
+{
+ return new function(primTransform());
+}
+
+function *penFunction()
+{
+ return new function(primPen(),primInt(),primInt());
+}
+
+// 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;
+}
+
+triple Zero;
+
+string defaultformat3="prc";
+
+// 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();
+}
+
+pair size(picture *f)
+{
+ bbox b=f->bounds();
+ return b.Max()-b.Min();
+}
+
+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, transform t=identity,
+ bool copy=true)
+{
+ array *(*copyarray)(array *a)=copy ? copyArray : nop;
+ f->append(new drawLatticeShade(*copyarray(g),stroke,fillrule,*copyarray(p),
+ t));
+}
+
+void axialshade(picture *f, patharray *g, bool stroke=false, pen pena, pair a,
+ bool extenda=true, pen penb, pair b, bool extendb=true,
+ bool copy=true)
+{
+ array *(*copyarray)(array *a)=copy ? copyArray : nop;
+ f->append(new drawAxialShade(*copyarray(g),stroke,pena,a,extenda,penb,b,
+ extendb));
+}
+
+void radialshade(picture *f, patharray *g, bool stroke=false, pen pena,
+ pair a, real ra, bool extenda=true, pen penb, pair b, real rb,
+ bool extendb=true, bool copy=true)
+{
+ array *(*copyarray)(array *a)=copy ? copyArray : nop;
+ f->append(new drawRadialShade(*copyarray(g),stroke,pena,a,ra,extenda,
+ penb,b,rb,extendb));
+}
+
+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;
+ size_t n=checkArrays(p,b ? b : g);
+ array& G=*copyarray(g);
+ array& B=b ? *copyarray(b) : G;
+ size_t nz=checkArray(z);
+ if(nz != 0)
+ checkEqual(nz,n);
+ f->append(new drawTensorShade(G,stroke,fillrule,*copyarray2(p),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)
+{
+ f->append(new drawBegin());
+}
+
+void endgroup(picture *f)
+{
+ f->append(new drawEnd());
+}
+
+void _begingroup3(picture *f, string name, real compression,
+ real granularity, bool closed, bool tessellate,
+ bool dobreak, bool nobreak, triple center, Int interaction)
+{
+ f->append(new drawBegin3(name,compression,granularity,
+ closed,tessellate,dobreak,nobreak,
+ center,(Interaction) intcast(interaction)));
+}
+
+void endgroup3(picture *f)
+{
+ f->append(new drawEnd3());
+}
+
+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(buildname(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 drawPaletteImage(*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 drawNoPaletteImage(*copyarray2(data),t*matrix(initial,final),
+ antialias));
+}
+
+void _image(picture *f, callablePen *F, Int width, Int height,
+ pair initial, pair final, transform t=identity, bool antialias=false)
+{
+ f->append(new drawFunctionImage(Stack,F,width,height,
+ 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,
+ transform T=identity)
+{
+ if(prefix.empty()) prefix=outname();
+
+ picture *result=new picture;
+ unsigned level=0;
+ picture::nodelist::iterator p;
+
+ xmap_t xmap=processData().xmap;
+ transform Tinv=inverse(T);
+
+ for(p = f->nodes.begin(); p != f->nodes.end(); ++p) {
+ transform t=getTransform(xmap,p);
+ bool Delete=(t == ZeroTransform);
+ if(!Delete && !t.isIdentity()) t=T*t*Tinv;
+ 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,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, pair margin, realarray2 *t,
+ realarray *background, triplearray *lights, realarray2 *diffuse,
+ realarray2 *specular, bool view=true)
+{
+ size_t n=checkArrays(lights,diffuse);
+ checkEqual(n,checkArray(specular));
+
+ real *T,*Background,*Diffuse,*Specular;
+ triple *Lights;
+
+ copyArray2C(T,t,true,4);
+ copyArrayC(Background,background);
+ copyArrayC(Lights,lights);
+ copyArray2C(Diffuse,diffuse,false,4,UseGC);
+ copyArray2C(Specular,specular,false,4,UseGC);
+
+ f->shipout3(prefix,format,width,height,angle,zoom,m,M,shift,margin,T,
+ Background,n,Lights,Diffuse,Specular,view);
+
+ delete[] Background;
+ delete[] T;
+}
+
+void shipout3(string prefix, picture *f, string format=defaultformat3)
+{
+ f->shipout3(prefix,format);
+}
+
+void xmap(string key, transform t=identity)
+{
+ xmap_t &xmap=processData().xmap;
+ xmap_t::iterator p=xmap.find(key);
+ if(p != xmap.end())
+ p->second.push_back(t);
+ else {
+ xtransform_t *v=new xtransform_t();
+ v->push_back(t);
+ xmap[key]=*v;
+ }
+}
+
+void deconstruct(picture *f, picture *preamble=NULL, transform T=identity)
+{
+ unsigned level=0;
+
+ string prefix=outname();
+ const string xformat="svg";
+
+ openpipeout();
+
+ const string Done="Done";
+ const string Error="Error";
+
+ unsigned arg=0;
+ xmap_t xmap=processData().xmap;
+ transform Tinv=inverse(T);
+
+ for(picture::nodelist::iterator p=f->nodes.begin();;) {
+ if(p == f->nodes.end()) break;
+
+ picture *group=new picture;
+ transform t=getTransform(xmap,p);
+ bool Delete=(t == ZeroTransform);
+ if(!Delete && !t.isIdentity()) t=T*t*Tinv;
+
+ assert(*p);
+ if((*p)->endgroup()) {
+ fprintf(pipeout,"%s\n",Error.c_str());
+ fflush(pipeout);
+ error(nobegin);
+ }
+ bool clip=false;
+ if((*p)->begingroup()) {
+ ++level;
+ while(p != f->nodes.end() && level) {
+ if(!Delete) {
+ drawElement *e=t.isIdentity() ? *p : (*p)->transformed(t);
+ group->append(e);
+ if((*p)->endclip()) clip=true;
+ }
+ ++p;
+ if(p == f->nodes.end()) break;
+ assert(*p);
+ if((*p)->begingroup()) ++level;
+ if((*p)->endgroup()) {
+ if(level) --level;
+ else {
+ fprintf(pipeout,"%s\n",Error.c_str());
+ fflush(pipeout);
+ error(nobegin);
+ }
+ }
+ }
+ }
+ if(p != f->nodes.end()) {
+ if(!Delete) {
+ drawElement *e=t.isIdentity() ? *p : (*p)->transformed(t);
+ group->append(e);
+ bbox b=group->bounds();
+ if(!b.empty && b.right > b.left && b.top > b.bottom) {
+ if((*p)->endclip()) clip=true;
+ ostringstream buf;
+ buf << prefix << "_" << arg;
+ string outname=buildname(buf.str(),xformat);
+ group->shipout(preamble,outname,xformat,false,false);
+ fprintf(pipeout,"KEY=%s%d\n",e->KEY.c_str(),clip || f->havepng());
+
+ const char *oldlocale=setlocale(LC_NUMERIC,NULL);
+ bool override=oldlocale && strcmp(oldlocale,"C") != 0;
+ if(override) {
+ oldlocale=StrdupNoGC(oldlocale);
+ setlocale(LC_NUMERIC,"C");
+ }
+
+ fprintf(pipeout,"%g %g %g %g\n",b.left,b.bottom,b.right,b.top);
+
+ if(override) {
+ setlocale(LC_NUMERIC,oldlocale);
+ delete[] oldlocale;
+ }
+
+ fflush(pipeout);
+ ++arg;
+ }
+ }
+ ++p;
+ }
+ }
+
+ fprintf(pipeout,"%s\n",Done.c_str());
+ fflush(pipeout);
+}
+
+
+// Three-dimensional picture and surface operations
+
+// Bezier curve
+void _draw(picture *f, path3 g, triple center=Zero, penarray *p,
+ real opacity, real shininess, real metallic, real fresnel0,
+ Int interaction=0)
+{
+ size_t n=g.size();
+ for(unsigned int i=0; i < n; ++i)
+ f->append(new drawPath3(g.subpath((Int) i,Int(i+1)),center,*p,opacity,
+ shininess,metallic,fresnel0,
+ (Interaction) intcast(interaction)));
+}
+
+// Bezier patch
+void draw(picture *f, triplearray2 *P, triple center, bool straight,
+ penarray *p, real opacity, real shininess, real metallic,
+ real fresnel0, penarray *colors, Int interaction, Int digits,
+ bool primitive=false)
+{
+ f->append(new drawBezierPatch(*P,center,straight,*p,opacity,shininess,
+ metallic,fresnel0,*colors,
+ (Interaction) intcast(interaction),
+ digits,primitive));
+}
+
+// Bezier triangle
+void drawbeziertriangle(picture *f, triplearray2 *P, triple center,
+ bool straight, penarray *p, real opacity,
+ real shininess, real metallic, real fresnel0,
+ penarray *colors, Int interaction, Int digits,
+ bool primitive=false)
+{
+ f->append(new drawBezierTriangle(*P,center,straight,*p,opacity,shininess,
+ metallic,fresnel0,*colors,
+ (Interaction) intcast(interaction),
+ digits,primitive));
+}
+
+// General NURBS curve
+void draw(picture *f, triplearray *P, realarray *knot,
+ realarray *weights=emptyarray, pen p)
+{
+ f->append(new drawNurbsPath3(*P,knot,weights,p));
+}
+
+// General NURBS surface
+void draw(picture *f, triplearray2 *P, realarray *uknot, realarray *vknot,
+ realarray2 *weights=emptyarray, penarray *p, real opacity,
+ real shininess,real metallic, real fresnel0, penarray *colors)
+{
+ f->append(new drawNurbs(*P,uknot,vknot,weights,*p,opacity,shininess,
+ metallic,fresnel0,*colors));
+}
+
+// Sphere primitive
+void drawSphere(picture *f, realarray2 *t, bool half=false, penarray *p,
+ real opacity, real shininess, real metallic, real fresnel0,
+ Int type)
+{
+ f->append(new drawSphere(*t,half,*p,opacity,shininess,metallic,fresnel0,
+ intcast(type)));
+}
+
+// Cylinder primitive
+void drawCylinder(picture *f, realarray2 *t, penarray *p, real opacity,
+ real shininess, real metallic, real fresnel0,
+ bool core=false)
+{
+ f->append(new drawCylinder(*t,*p,opacity,shininess,metallic,fresnel0,core));
+}
+
+// Disk primitive
+void drawDisk(picture *f, realarray2 *t, penarray *p, real opacity,
+ real shininess, real metallic, real fresnel0)
+{
+ f->append(new drawDisk(*t,*p,opacity,shininess,metallic,fresnel0));
+}
+
+// Tube primitive
+void drawTube(picture *f, triplearray *g, real width, penarray *p,
+ real opacity, real shininess, real metallic, real fresnel0,
+ triple min, triple max, bool core=false)
+{
+ f->append(new drawTube(*g,width,*p,opacity,shininess,metallic,fresnel0,
+ min,max,core));
+}
+
+// Draw pixel
+void drawpixel(picture *f, triple v, pen p, real width=1.0)
+{
+ f->append(new drawPixel(v,p,width));
+}
+
+// Draw triangles
+void draw(picture *f, triplearray *v, Intarray2 *vi,
+ triplearray *n, Intarray2 *ni,
+ penarray *p, real opacity, real shininess,
+ real metallic, real fresnel0,
+ penarray *c=emptyarray, Intarray2 *ci=emptyarray)
+{
+ f->append(new drawTriangles(*v,*vi,*n,*ni,*p,opacity,shininess,metallic,
+ fresnel0,*c,*ci));
+}
+
+triple min3(picture *f)
+{
+ return f->bounds3().Min();
+}
+
+triple max3(picture *f)
+{
+ return f->bounds3().Max();
+}
+
+triple size3(picture *f)
+{
+ bbox3 b=f->bounds3();
+ return b.Max()-b.Min();
+}
+
+pair minratio(picture *f)
+{
+ return f->ratio(::min);
+}
+
+pair maxratio(picture *f)
+{
+ return f->ratio(::max);
+}
+
+bool is3D(picture *f)
+{
+ return f->have3D();
+}