diff options
Diffstat (limited to 'graphics/asymptote/base/three.asy')
-rw-r--r-- | graphics/asymptote/base/three.asy | 259 |
1 files changed, 142 insertions, 117 deletions
diff --git a/graphics/asymptote/base/three.asy b/graphics/asymptote/base/three.asy index 5fc0d2f109..fbca4b3960 100644 --- a/graphics/asymptote/base/three.asy +++ b/graphics/asymptote/base/three.asy @@ -1,8 +1,5 @@ private import math; -if(settings.xasy) - settings.render=0; - if(prc0()) { if(!latex()) settings.prc=false; else { @@ -11,8 +8,9 @@ if(prc0()) { } } -// Useful lossy compression values. +// Useful lossy PRC compression values. restricted real Zero=0; +restricted real Single=0.000001; restricted real Low=0.0001; restricted real Medium=0.001; restricted real High=0.01; @@ -20,6 +18,27 @@ restricted real High=0.01; restricted int PRCsphere=0; // Renders slowly but produces smaller PRC files. restricted int NURBSsphere=1; // Renders fast but produces larger PRC files. +struct interaction +{ + int type; + triple center; // position to rotate billboard objects about + bool targetsize; + static interaction defaultinteraction; + + void operator init(interaction interaction=defaultinteraction, + int type=interaction.type, + triple center=interaction.center, bool targetsize=interaction.targetsize) { + this.type=type; + this.center=center; + this.targetsize=targetsize; + } +} + +interaction.defaultinteraction=new interaction; + +restricted interaction Embedded=interaction(); +restricted interaction Billboard=interaction(1); + struct render { // PRC parameters: @@ -41,19 +60,22 @@ struct render bool partnames; // assign part name indices to compound objects bool defaultnames; // assign default names to unnamed objects + interaction interaction; // billboard interaction mode static render defaultrender; - - void operator init(real compression=defaultrender.compression, - real granularity=defaultrender.granularity, - bool closed=defaultrender.closed, - bool tessellate=defaultrender.tessellate, - bool3 merge=defaultrender.merge, - int sphere=defaultrender.sphere, - real margin=defaultrender.margin, - bool labelfill=defaultrender.labelfill, - bool partnames=defaultrender.partnames, - bool defaultnames=defaultrender.defaultnames) + + void operator init(render render=defaultrender, + real compression=render.compression, + real granularity=render.granularity, + bool closed=render.closed, + bool tessellate=render.tessellate, + bool3 merge=render.merge, + int sphere=render.sphere, + real margin=render.margin, + bool labelfill=render.labelfill, + bool partnames=render.partnames, + bool defaultnames=render.defaultnames, + interaction interaction=render.interaction) { this.compression=compression; this.granularity=granularity; @@ -65,6 +87,7 @@ struct render this.labelfill=labelfill; this.partnames=partnames; this.defaultnames=defaultnames; + this.interaction=interaction; } } @@ -81,6 +104,7 @@ defaultrender.sphere=NURBSsphere; defaultrender.labelfill=true; defaultrender.partnames=false; defaultrender.defaultnames=true; +defaultrender.interaction=Embedded; real defaultshininess=0.7; real defaultmetallic=0.0; @@ -95,7 +119,7 @@ string defaultembed3Doptions="3Dmenu"; string defaultembed3Dscript; real defaulteyetoview=63mm/1000mm; -string partname(int i, render render=defaultrender) +string partname(int i, render render=defaultrender) { return render.partnames ? string(i+1) : ""; } @@ -158,8 +182,8 @@ transform3 scale(triple v, real s) v=unit(v); s -= 1; return new real[][] { - {1+s*v.x^2, s*v.x*v.y, s*v.x*v.z, 0}, - {s*v.x*v.y, 1+s*v.y^2, s*v.y*v.z, 0}, + {1+s*v.x^2, s*v.x*v.y, s*v.x*v.z, 0}, + {s*v.x*v.y, 1+s*v.y^2, s*v.y*v.z, 0}, {s*v.x*v.z, s*v.y*v.z, 1+s*v.z^2, 0}, {0, 0, 0, 1}}; } @@ -248,7 +272,7 @@ transform3 look(triple eye, triple up=Z, triple target=O) } // Return a matrix to do perspective distortion based on a triple v. -transform3 distort(triple v) +transform3 distort(triple v) { transform3 t=identity(4); real d=length(v); @@ -410,7 +434,7 @@ projection TopView=orthographic(Z,up=Y,showtarget=true); currentprojection=perspective(5,4,2); -projection projection() +projection projection() { projection P; real[] a=_projection(); @@ -467,8 +491,8 @@ struct control { } control nocontrol; - -control operator * (transform3 t, control c) + +control operator * (transform3 t, control c) { control C; C.post=t*c.post; @@ -485,7 +509,7 @@ void write(file file, control c) write(file," and "); write(file,c.pre); } - + struct Tension { real out,in; bool atLeast; @@ -510,7 +534,7 @@ Tension operator init() Tension noTension; noTension.active=false; - + void write(file file, Tension t) { write(file,"..tension "); @@ -519,7 +543,7 @@ void write(file file, Tension t) write(file," and "); write(file,t.in); } - + struct dir { triple dir; real gamma=1; // endpoint curl @@ -561,8 +585,8 @@ void write(file file, dir d) write(file,"{curl "); write(file,d.gamma); write(file,"}"); } } - -dir operator * (transform3 t, dir d) + +dir operator * (transform3 t, dir d) { dir D=d.copy(); D.init(unit(shiftless(t)*d.dir)); @@ -596,11 +620,11 @@ struct flatguide3 { bool cyclic() {int n=cyclic.length; return n > 0 ? cyclic[n-1] : false;} bool precyclic() {int i=find(cyclic); return i >= 0 && i < cyclic.length-1;} - + int size() { return cyclic() ? nodes.length-1 : nodes.length; } - + void node(triple v, bool b=false) { nodes.push(v); control.push(nocontrol); @@ -650,7 +674,7 @@ struct flatguide3 { if(nodes.length > 0) node(nodes[0],true); } - + // Return true if outgoing direction at node i is known. bool solved(int i) { return out[i].active() || control[i].active; @@ -705,13 +729,13 @@ guide3 operator cast(cycleToken) { }; } -guide3 operator controls(triple post, triple pre) +guide3 operator controls(triple post, triple pre) { return new void(flatguide3 f) { f.control(post,pre); }; }; - + guide3 operator controls(triple v) { return operator controls(v,v); @@ -743,7 +767,7 @@ guide3 operator spec(triple v, int side) abort("invalid direction specifier"); }; } - + guide3 operator -- (... guide3[] g) { return new void(flatguide3 f) { @@ -805,13 +829,13 @@ real asin1(real x) { return asin(min(max(x,-1),1)); } - + // A version of acos that tolerates numerical imprecision real acos1(real x) { return acos(min(max(x,-1),1)); } - + struct Controls { triple c0,c1; @@ -840,7 +864,7 @@ private triple cross(triple d0, triple d1, triple reference) triple normal=cross(d0,d1); return normal == O ? reference : normal; } - + private triple dir(real theta, triple d0, triple d1, triple reference) { triple normal=cross(d0,d1,reference); @@ -860,7 +884,7 @@ private real angle(triple d0, triple d1, triple reference) // beta[i] is the tension for segment i, and in[i] is the incoming // direction for segment i (where segment i begins at node i). -real[] theta(triple[] v, real[] alpha, real[] beta, +real[] theta(triple[] v, real[] alpha, real[] beta, triple dir0, triple dirn, real g0, real gn, triple reference) { real[] a,b,c,f,l,psi; @@ -905,7 +929,7 @@ real[] theta(triple[] v, real[] alpha, real[] beta, f[n]=angle(v[n]-v[n-1],dirn,reference); } } - + for(int i=i0; i < n; ++i) { real in=beta[i-1]^2*l[i-1]; real A=in/alpha[i-1]; @@ -917,14 +941,14 @@ real[] theta(triple[] v, real[] alpha, real[] beta, c[i]=C; f[i]=-B*psi[i-1]-C*psi[i]; } - + return tridiagonal(a,b,c,f); } triple reference(triple[] v, int n, triple d0, triple d1) { triple[] V=sequence(new triple(int i) { - return cross(v[i+1]-v[i],v[i+2]-v[i+1]); + return cross(v[i+1]-v[i],v[i+2]-v[i+1]); },n-1); if(n > 0) { V.push(cross(d0,v[1]-v[0])); @@ -952,18 +976,18 @@ triple reference(triple[] v, int n, triple d0, triple d1) } // Fill in missing directions for n cyclic nodes. -void aim(flatguide3 g, int N) +void aim(flatguide3 g, int N) { bool cyclic=true; int start=0, end=0; - + // If the cycle contains one or more direction specifiers, break the loop. for(int k=0; k < N; ++k) if(g.solved(k)) {cyclic=false; end=k; break;} for(int k=N-1; k >= 0; --k) if(g.solved(k)) {cyclic=false; start=k; break;} while(start < N && g.control[start].active) ++start; - + int n=N-(start-end); if(n <= 1 || (cyclic && n <= 2)) return; @@ -993,7 +1017,7 @@ void aim(flatguide3 g, int N) v.cyclic=true; theta.cyclic=true; - + for(int k=1; k < (cyclic ? n+1 : n); ++k) { triple w=dir(theta[k],v[k]-v[k-1],v[k+1]-v[k],reference); g.in[(start+k-1) % N].init(w); @@ -1008,7 +1032,7 @@ void aim(flatguide3 g, int N) } // Fill in missing directions for the sequence of nodes i...n. -void aim(flatguide3 g, int i, int n) +void aim(flatguide3 g, int i, int n) { int j=n-i; if(j > 1 || g.out[i].dir != O || g.in[i].dir != O) { @@ -1021,7 +1045,7 @@ void aim(flatguide3 g, int i, int n) beta[k]=g.Tension[i+k].in; } v[j]=g.nodes[n]; - + triple d0=g.out[i].dir; triple d1=g.in[n-1].dir; @@ -1029,7 +1053,7 @@ void aim(flatguide3 g, int i, int n) real[] theta=theta(v,alpha,beta,d0,d1,g.out[i].gamma,g.in[n-1].gamma, reference); - + for(int k=1; k < j; ++k) { triple w=dir(theta[k],v[k]-v[k-1],v[k+1]-v[k],reference); g.in[i+k-1].init(w); @@ -1175,7 +1199,7 @@ path path(path3 p, pair P(triple)=xypart) for(int i=1; i < n; ++i) g=straight(p,i-1) ? g--P(point(p,i)) : g..controls P(postcontrol(p,i-1)) and P(precontrol(p,i))..P(point(p,i)); - + if(straight(p,n-1)) return cyclic(p) ? g--cycle : g--P(point(p,n)); @@ -1241,16 +1265,16 @@ path3 solve(flatguide3 g) for(int i=0; i < n; ++i) { if(g.nodes[i] == g.nodes[i+1] && !g.control[i].active) g.control[i]=control(g.nodes[i],g.nodes[i],straight=true); - } - + } + // Fill in empty direction specifiers inherited from explicit control points. for(int i=0; i < n; ++i) { if(g.control[i].active) { g.out[i].init(g.control[i].post-g.nodes[i]); g.in[i].init(g.nodes[i+1]-g.control[i].pre); } - } - + } + // Propagate directions across nodes. for(int i=0; i < n; ++i) { int next=g.cyclic[i+1] ? 0 : i+1; @@ -1260,8 +1284,8 @@ path3 solve(flatguide3 g) g.out[next].default(g.in[i]); g.out[i+1].default(g.in[i]); } - } - + } + // Compute missing 3D directions. // First, resolve cycles int i=find(g.cyclic); @@ -1278,7 +1302,7 @@ path3 solve(flatguide3 g) } } } - + // Next, resolve sequences. int i=0; int start=0; @@ -1288,13 +1312,13 @@ path3 solve(flatguide3 g) if(i > n) break; // Look for the end of the sequence. while(i < n && !g.solved(i)) ++i; - + while(start < i && g.control[start].active) ++start; - - if(start < i) + + if(start < i) aim(g,start,i); } - + // Compute missing 3D control points. for(int i=0; i < n; ++i) { int next=g.cyclic[i+1] ? 0 : i+1; @@ -1344,7 +1368,7 @@ path3 solve(flatguide3 g) straight[n-1]=false; } } - + return path3(pre,point,post,straight,cyclic); } @@ -1385,7 +1409,7 @@ path project(path3 p, projection P=currentprojection, int last=length(p); if(last < 0) return g; - + transform3 t=P.t; if(ninterpolate == 1 || piecewisestraight(p)) { @@ -1401,7 +1425,7 @@ path project(path3 p, projection P=currentprojection, } } } else return nurb(p,P); - + if(cyclic(p)) g=straight(p,last-1) ? g--cycle : g..controls project(postcontrol(p,last-1),t) and @@ -1418,11 +1442,11 @@ path[] project(explicit path3[] g, projection P=currentprojection) { return sequence(new path(int i) {return project(g[i],P);},g.length); } - + guide3 operator cast(path3 p) { int last=length(p); - + bool cyclic=cyclic(p); int stop=cyclic ? last-1 : last; return new void(flatguide3 f) { @@ -1456,7 +1480,7 @@ triple normal(path3 p) real fuzz=sqrtEpsilon*abs(max(p)-min(p)); real absnormal; real theta; - + bool Cross(triple a, triple b) { if(abs(a) >= fuzz && abs(b) >= fuzz) { triple n=cross(unit(a),unit(b)); @@ -1478,7 +1502,7 @@ triple normal(path3 p) } return false; } - + int L=length(p); if(L <= 0) return O; @@ -1505,7 +1529,7 @@ triple normal(triple[] p) real fuzz=sqrtEpsilon*abs(maxbound(p)-minbound(p)); real absnormal; real theta; - + bool Cross(triple a, triple b) { if(abs(a) >= fuzz && abs(b) >= fuzz) { triple n=cross(unit(a),unit(b)); @@ -1526,7 +1550,7 @@ triple normal(triple[] p) } return false; } - + if(p.length <= 0) return O; triple zi=p[0]; @@ -1642,7 +1666,7 @@ Label project(Label L, triple u, triple v, triple O=O, projection P=currentprojection) { Label L=L.copy(); L.position=project(O,P.t); - L.transform(transform(u,v,O,P)); + L.transform(transform(u,v,O,P)); return L; } @@ -1674,7 +1698,7 @@ void write(file file, string s="", explicit guide3[] x, suffix suffix=none) write(file,s,(path3[]) x,suffix); } -void write(string s="", explicit guide3[] x, suffix suffix=endl) +void write(string s="", explicit guide3[] x, suffix suffix=endl) { write(stdout,s,(path3[]) x,suffix); } @@ -1850,7 +1874,7 @@ real relative(Label L, path3 g) } // return the linear transformation that maps X,Y,Z to u,v,w. -transform3 transform3(triple u, triple v, triple w=cross(u,v)) +transform3 transform3(triple u, triple v, triple w=cross(u,v)) { return new real[][] { {u.x,v.x,w.x,0}, @@ -1915,37 +1939,37 @@ path3[] operator cast(guide3 g) return new path3[] {(path3) g}; } -path3[] operator ^^ (path3 p, path3 q) +path3[] operator ^^ (path3 p, path3 q) { return new path3[] {p,q}; } -path3[] operator ^^ (path3 p, explicit path3[] q) +path3[] operator ^^ (path3 p, explicit path3[] q) { return concat(new path3[] {p},q); } -path3[] operator ^^ (explicit path3[] p, path3 q) +path3[] operator ^^ (explicit path3[] p, path3 q) { return concat(p,new path3[] {q}); } -path3[] operator ^^ (explicit path3[] p, explicit path3[] q) +path3[] operator ^^ (explicit path3[] p, explicit path3[] q) { return concat(p,q); } -path3[] operator * (transform3 t, explicit path3[] p) +path3[] operator * (transform3 t, explicit path3[] p) { return sequence(new path3(int i) {return t*p[i];},p.length); } -triple[] operator * (transform3 t, triple[] v) +triple[] operator * (transform3 t, triple[] v) { return sequence(new triple(int i) {return t*v[i];},v.length); } -triple[][] operator * (transform3 t, triple[][] v) +triple[][] operator * (transform3 t, triple[][] v) { triple[][] V=new triple[v.length][]; for(int i=0; i < v.length; ++i) { @@ -1979,7 +2003,7 @@ path3 randompath3(int n, bool cumulate=true, interpolate3 join=operator ..) triple w; for(int i=0; i <= n; ++i) { triple z=(unitrand()-0.5,unitrand()-0.5,unitrand()-0.5); - if(cumulate) w += z; + if(cumulate) w += z; else w=z; g=join(g,w); } @@ -2040,15 +2064,15 @@ path3 arc(triple c, triple v1, triple v2, triple normal=O, bool direction=CCW) v1=Tinv*v1; v2=Tinv*v2; } - + string invalidnormal="invalid normal vector"; real fuzz=sqrtEpsilon; if(abs(v1.z) > fuzz || abs(v2.z) > fuzz) abort(invalidnormal); - + real[] t1=intersect(unitcircle3,O--2*(v1.x,v1.y,0)); real[] t2=intersect(unitcircle3,O--2*(v2.x,v2.y,0)); - + if(t1.length == 0 || t2.length == 0) abort(invalidnormal); @@ -2102,21 +2126,19 @@ void draw(frame f, path3 g, material p=currentpen, light light=nolight, string name="", render render=defaultrender, projection P=currentprojection); -void begingroup3(frame f, string name="", render render=defaultrender, - triple center=O, int interaction=0) +void begingroup3(frame f, string name="", render render=defaultrender) { _begingroup3(f,name,render.compression,render.granularity,render.closed, render.tessellate,render.merge == false, - render.merge == true,center,interaction); + render.merge == true,render.interaction.center,render.interaction.type); } void begingroup3(picture pic=currentpicture, string name="", - render render=defaultrender, - triple center=O, int interaction=0) + render render=defaultrender) { pic.add(new void(frame f, transform3, picture pic, projection) { if(is3D()) - begingroup3(f,name,render,center,interaction); + begingroup3(f,name,render); if(pic != null) begingroup(pic); },true); @@ -2141,7 +2163,7 @@ void addPath(picture pic, path3 g, pen p) include three_surface; include three_margins; -pair min(path3 p, projection P) +pair min(path3 p, projection P) { path3 q=P.T.modelview*p; if(P.infinity) @@ -2149,7 +2171,7 @@ pair min(path3 p, projection P) return maxratio(q)/P.T.projection[3][2]; } -pair max(path3 p, projection P) +pair max(path3 p, projection P) { path3 q=P.T.modelview*p; if(P.infinity) @@ -2157,7 +2179,7 @@ pair max(path3 p, projection P) return minratio(q)/P.T.projection[3][2]; } -pair min(frame f, projection P) +pair min(frame f, projection P) { frame g=P.T.modelview*f; if(P.infinity) @@ -2165,7 +2187,7 @@ pair min(frame f, projection P) return maxratio(g)/P.T.projection[3][2]; } -pair max(frame f, projection P) +pair max(frame f, projection P) { frame g=P.T.modelview*f; if(P.infinity) @@ -2210,7 +2232,7 @@ draw=new void(frame f, path3 g, material p=currentpen, void drawthick(path3 g) { if(settings.thick && width > 0) { bool prc=prc(); - bool webgl=settings.outformat == "html"; + bool primitive=primitive(); real linecap=linecap(q); real r=0.5*width; bool open=!cyclic(g); @@ -2256,7 +2278,7 @@ draw=new void(frame f, path3 g, material p=currentpen, } } // Draw central core for better small-scale rendering. - if((!prc || piecewisestraight(g)) && !webgl && opacity(q) == 1) + if((!prc || piecewisestraight(g)) && !primitive && opacity(q) == 1) _draw(f,c,p,light); } for(surface s : T.s) @@ -2319,7 +2341,7 @@ void draw(picture pic=currentpicture, explicit path3[] g, include three_arrows; -void draw(picture pic=currentpicture, Label L="", path3 g, +void draw(picture pic=currentpicture, Label L="", path3 g, align align=NoAlign, material p=currentpen, arrowbar3 arrow, arrowbar3 bar=None, margin3 margin=NoMargin3, light light=nolight, light arrowheadlight=currentlight, string name="", @@ -2409,12 +2431,12 @@ triple min3(picture pic, projection P=currentprojection) { return pic.min3(P); } - + triple max3(picture pic, projection P=currentprojection) { return pic.max3(P); } - + triple size3(picture pic, bool user=false, projection P=currentprojection) { transform3 t=pic.calculateTransform3(P); @@ -2635,7 +2657,7 @@ struct scene transform3 T=identity4; picture pic2; bool keepAspect=true; - + void operator init(frame f, real width, real height, projection P=currentprojection) { this.f=f; @@ -2644,14 +2666,14 @@ struct scene this.width=width; this.height=height; } - + void operator init(picture pic, real xsize=pic.xsize, real ysize=pic.ysize, bool keepAspect=pic.keepAspect, bool is3D=true, projection P=currentprojection) { real xsize3=pic.xsize3, ysize3=pic.ysize3, zsize3=pic.zsize3; bool warn=true; this.keepAspect=keepAspect; - + if(xsize3 == 0 && ysize3 == 0 && zsize3 == 0) { xsize3=ysize3=zsize3=max(xsize,ysize); warn=false; @@ -2787,6 +2809,7 @@ object embed(string prefix=outprefix(), string label=prefix, triple orthoshift; modelview=P.T.modelview; transform3 inv; + bool prc=prc(format); if(P.absolute) { Q=modelview*P; inv=inverse(modelview); @@ -2798,12 +2821,13 @@ object embed(string prefix=outprefix(), string label=prefix, if(Q.t[2][3] == -1) // PRC can't handle oblique projections Q=orthographic(P.camera,P.up,P.target,P.zoom,P.viewportshift, - P.showtarget,P.center); + P.showtarget,P.center); + if(P.infinity) { triple m=min3(S.f); triple M=max3(S.f); triple lambda=M-m; - if(S.keepAspect) { + if(S.keepAspect || prc) { S.viewportmargin=viewportmargin((lambda.x,lambda.y)); S.width=ceil(lambda.x+2*S.viewportmargin.x); S.height=ceil(lambda.y+2*S.viewportmargin.y); @@ -2821,7 +2845,7 @@ object embed(string prefix=outprefix(), string label=prefix, inv=inverse(modelview); Q.angle=P.angle; if(settings.verbose > 0) { - if(S.adjusted) + if(S.adjusted) write("adjusting camera to ",tinv*inv*P.camera); target=inv*P.target; } @@ -2835,7 +2859,6 @@ object embed(string prefix=outprefix(), string label=prefix, light Light=modelview*light; if(prefix == "") prefix=outprefix(); - bool prc=prc(format); bool preview=settings.render > 0 && !prconly(); if(prc) { // The media9.sty package cannot handle spaces or dots in filenames. @@ -2868,12 +2891,12 @@ object embed(string prefix=outprefix(), string label=prefix, if(P.infinity) { triple margin=(S.viewportmargin.x,S.viewportmargin.y,0); - M += margin; + M += margin; m -= margin; } else if(M.z >= 0) abort("camera too close"); - if(settings.outformat == "html") - format="html"; + if(primitive()) + format=settings.outformat; shipout3(prefix,f,preview ? nativeformat() : format, S.width-defaultrender.margin,S.height-defaultrender.margin, @@ -2893,7 +2916,7 @@ object embed(string prefix=outprefix(), string label=prefix, transform T=S.pic2.scaling(S.width,S.height); _shipout(image,S.pic2.fit(T),newframe,nativeformat(),false,false); } - + image += "."+nativeformat(); if(!settings.inlinetex) file3.push(image); image=graphic(image,"hiresbb"); @@ -2924,7 +2947,7 @@ shift"); if(P.infinity) { triple lambda=max3(S.f)-min3(S.f); pair margin=viewportmargin((lambda.x,lambda.y)); - viewplanesize=(max(lambda.x+2*margin.x,lambda.y+2*margin.y))/(Q.zoom); + viewplanesize=(max(lambda.x+2*margin.x,lambda.y+2*margin.y))/Q.zoom; transform3 t=inv*shift(-orthoshift); Q=t*Q; S.f=t*S.f; @@ -2948,7 +2971,7 @@ object embed(string prefix=outprefix(), string label=prefix, { bool is3D=is3D(format); scene S=scene(pic,xsize,ysize,keepAspect,is3D,P); - if(is3D) + if(is3D && !(settings.xasy && format == "")) return embed(prefix,label,text,S,format,view,options,script,light); else { object F; @@ -3017,7 +3040,9 @@ currentpicture.fitter=new frame(string prefix, picture pic, string format, return embed(prefix=prefix,pic,format,xsize,ysize,keepAspect,view, options,script,light,P); },prefix,format,view,light); - if(is3D(format) || empty3) add(f,pic.fit2(xsize,ysize,keepAspect)); + + if(is3D(format) || empty3) + add(f,pic.fit2(xsize,ysize,keepAspect)); return f; }; @@ -3056,7 +3081,7 @@ void addViews(picture dest, picture src, projection[][] views=SixViewsUS, frame[][] F=array(views.length,new frame[]); pair[][] M=array(views.length,new pair[]); pair[][] m=array(views.length,new pair[]); - + for(int i=0; i < views.length; ++i) { projection[] viewsi=views[i]; frame[] Fi=F[i]; @@ -3076,17 +3101,17 @@ void addViews(picture dest, picture src, projection[][] views=SixViewsUS, } } } - + real[] my=new real[views.length]; real[] My=new real[views.length]; - + int Nj=0; for(int i=0; i < views.length; ++i) { my[i]=minbound(m[i]).y; My[i]=maxbound(M[i]).y; Nj=max(Nj,views[i].length); } - + real[] mx=array(Nj,infinity); real[] Mx=array(Nj,-infinity); for(int i=0; i < views.length; ++i) { @@ -3179,10 +3204,10 @@ frame[] fit3(string prefix="", picture[] pictures, picture all, frame f=embedder(prefix,out[i],format,S.width,S.height,view,options, script,light,S.P); if(!settings.loop) out[i]=f; - } + } if(!settings.loop) break; } - + settings.animating=false; settings.interrupt=false; settings.reverse=reverse; |