diff options
author | Karl Berry <karl@freefriends.org> | 2021-02-25 19:22:25 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2021-02-25 19:22:25 +0000 |
commit | ad547a6b5986815fda458221149728d9d9ab1d87 (patch) | |
tree | 16296910eb3eca724371474ea9aea3994dc69614 /Build/source/utils/asymptote/runpicture.in | |
parent | 947b43de3dd21d58ccc2ffadefc4441ea1c2a813 (diff) |
restore Build,TODO from r57911
git-svn-id: svn://tug.org/texlive/trunk@57915 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Build/source/utils/asymptote/runpicture.in')
-rw-r--r-- | Build/source/utils/asymptote/runpicture.in | 738 |
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(); +} |