diff options
author | Karl Berry <karl@freefriends.org> | 2009-09-11 00:21:50 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2009-09-11 00:21:50 +0000 |
commit | f06a2c99f2a8bbd8f641712c772179e8ed9ce14f (patch) | |
tree | fcf4f2b9d0492da04d9bf3761fbce51fb316024f /Build/source/utils/asymptote/drawsurface.h | |
parent | d4c54e52fe8e42b8ce9b160c70d897bb1d06eee7 (diff) |
asymptote 1.86
git-svn-id: svn://tug.org/texlive/trunk@15218 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Build/source/utils/asymptote/drawsurface.h')
-rw-r--r-- | Build/source/utils/asymptote/drawsurface.h | 320 |
1 files changed, 264 insertions, 56 deletions
diff --git a/Build/source/utils/asymptote/drawsurface.h b/Build/source/utils/asymptote/drawsurface.h index 9c7f25342b9..16d369cb545 100644 --- a/Build/source/utils/asymptote/drawsurface.h +++ b/Build/source/utils/asymptote/drawsurface.h @@ -12,11 +12,20 @@ #include "arrayop.h" #include "path3.h" +namespace run { +extern double *copyArrayC(const array *a, size_t dim); +} + namespace camp { +#ifdef HAVE_LIBGL +void storecolor(GLfloat *colors, int i, const vm::array &pens, int j); +#endif + class drawSurface : public drawElement { protected: - Triple controls[16]; + Triple *controls; + Triple vertices[4]; bool straight; RGBAColour diffuse; RGBAColour ambient; @@ -27,47 +36,56 @@ protected: double PRCshininess; double granularity; triple normal; + bool invisible; bool lighton; + string name; - bool invisible; triple Min,Max; - static triple c3[16]; - GLfloat *colors; - bool havecolors; #ifdef HAVE_LIBGL - GLfloat c[48]; + GLfloat *colors; triple d; // Maximum deviation of surface from a quadrilateral. triple dperp; - GLfloat v1[16]; - GLfloat v2[16]; - GLfloat Normal[3]; - bool havenormal; - bool havetransparency; #endif - void storecolor(int i, const vm::array &pens, int j) { - pen p=vm::read<camp::pen>(pens,j); - p.torgb(); - colors[i]=p.red(); - colors[i+1]=p.green(); - colors[i+2]=p.blue(); - colors[i+3]=p.opacity(); - } - + static const triple zero; + public: drawSurface(const vm::array& g, bool straight, const vm::array&p, double opacity, double shininess, double PRCshininess, - double granularity, triple normal, bool lighton, - const vm::array &pens) : + double granularity, triple normal, const vm::array &pens, + bool lighton, const string& name) : straight(straight), opacity(opacity), shininess(shininess), PRCshininess(PRCshininess), granularity(granularity), normal(unit(normal)), - lighton(lighton) { + lighton(lighton), name(name) { string wrongsize= "Bezier surface patch requires 4x4 array of triples and array of 4 pens"; if(checkArray(&g) != 4 || checkArray(&p) != 4) reportError(wrongsize); + bool havenormal=normal != zero; + + vm::array *g0=vm::read<vm::array*>(g,0); + vm::array *g3=vm::read<vm::array*>(g,3); + if(checkArray(g0) != 4 || checkArray(g3) != 4) + reportError(wrongsize); + store(vertices[0],vm::read<triple>(g0,0)); + store(vertices[1],vm::read<triple>(g0,3)); + store(vertices[2],vm::read<triple>(g3,0)); + store(vertices[3],vm::read<triple>(g3,3)); + + if(!havenormal || !straight) { + size_t k=0; + controls=new Triple[16]; + for(size_t i=0; i < 4; ++i) { + vm::array *gi=vm::read<vm::array*>(g,i); + if(checkArray(gi) != 4) + reportError(wrongsize); + for(size_t j=0; j < 4; ++j) + store(controls[k++],vm::read<triple>(gi,j)); + } + } else controls=NULL; + pen surfacepen=vm::read<camp::pen>(p,0); invisible=surfacepen.invisible(); @@ -78,72 +96,262 @@ public: #ifdef HAVE_LIBGL int size=checkArray(&pens); - havecolors=size > 0; - if(havecolors) { - colors=new GLfloat[16]; + if(size > 0) { if(size != 4) reportError(wrongsize); - storecolor(0,pens,0); - storecolor(8,pens,1); - storecolor(12,pens,2); - storecolor(4,pens,3); + colors=new GLfloat[16]; + storecolor(colors,0,pens,0); + storecolor(colors,8,pens,1); + storecolor(colors,12,pens,2); + storecolor(colors,4,pens,3); + } else colors=NULL; +#endif + } + + drawSurface(const vm::array& t, const drawSurface *s) : + straight(s->straight), diffuse(s->diffuse), ambient(s->ambient), + emissive(s->emissive), specular(s->specular), opacity(s->opacity), + shininess(s->shininess), PRCshininess(s->PRCshininess), + granularity(s->granularity), invisible(s->invisible), + lighton(s->lighton), name(s->name) { + + for(size_t i=0; i < 4; ++i) { + const double *c=s->vertices[i]; + store(vertices[i],run::operator *(t,triple(c[0],c[1],c[2]))); } + + if(s->controls) { + controls=new Triple[16]; + for(size_t i=0; i < 16; ++i) { + const double *c=s->controls[i]; + store(controls[i],run::operator *(t,triple(c[0],c[1],c[2]))); + } + } else controls=NULL; + + normal=run::multshiftless(t,s->normal); + +#ifdef HAVE_LIBGL + if(s->colors) { + colors=new GLfloat[16]; + for(int i=0; i < 16; ++i) + colors[i]=s->colors[i]; + } else colors=NULL; #endif + } + + bool is3D() {return true;} + + void bounds(bbox3& b); + + void ratio(pair &b, double (*m)(double, double), bool &first); + + virtual ~drawSurface() { + if(controls) + delete[] controls; + +#ifdef HAVE_LIBGL + if(colors) + delete[] colors; +#endif + } + + bool write(prcfile *out); + + void displacement(); + void render(GLUnurbs *nurb, double, const triple& Min, const triple& Max, + double perspective, bool transparent); + + drawElement *transformed(const vm::array& t); +}; + +class drawNurbs : public drawElement { +protected: + size_t udegree,vdegree; + size_t nu,nv; + Triple *controls; + double *weights; + double *uknots, *vknots; + RGBAColour diffuse; + RGBAColour ambient; + RGBAColour emissive; + RGBAColour specular; + double opacity; + double shininess; + double PRCshininess; + double granularity; + triple normal; + bool invisible; + bool lighton; + string name; + + triple Min,Max; + +#ifdef HAVE_LIBGL + GLfloat *colors; + GLfloat *Controls; + GLfloat *uKnots; + GLfloat *vKnots; +#endif + +public: + drawNurbs(const vm::array& g, const vm::array* uknot, const vm::array* vknot, + const vm::array* weight, const vm::array&p, double opacity, + double shininess, double PRCshininess, double granularity, + const vm::array &pens, bool lighton, const string& name) : + opacity(opacity), shininess(shininess), PRCshininess(PRCshininess), + granularity(granularity), lighton(lighton), name(name) { + size_t weightsize=checkArray(weight); + + string wrongsize="Inconsistent NURBS data"; + nu=checkArray(&g); + + if(nu == 0 || (weightsize != 0 && weightsize != nu) || checkArray(&p) != 4) + reportError(wrongsize); + + vm::array *g0=vm::read<vm::array*>(g,0); + nv=checkArray(g0); + + size_t n=nu*nv; + controls=new Triple[n]; size_t k=0; - for(size_t i=0; i < 4; ++i) { + for(size_t i=0; i < nu; ++i) { vm::array *gi=vm::read<vm::array*>(g,i); - size_t gisize=checkArray(gi); - if(gisize != 4) + if(checkArray(gi) != nv) reportError(wrongsize); - for(size_t j=0; j < 4; ++j) { - triple v=vm::read<triple>(gi,j); - controls[k][0]=v.getx(); - controls[k][1]=v.gety(); - controls[k][2]=v.getz(); - ++k; - } + for(size_t j=0; j < nv; ++j) + store(controls[k++],vm::read<triple>(gi,j)); } + + if(weightsize > 0) { + size_t k=0; + weights=new double[n]; + for(size_t i=0; i < nu; ++i) { + vm::array *weighti=vm::read<vm::array*>(weight,i); + if(checkArray(weighti) != nv) + reportError(wrongsize); + for(size_t j=0; j < nv; ++j) { + weights[k]=vm::read<double>(weighti,j); + ++k; + } + } + } else weights=NULL; + + size_t nuknots=checkArray(uknot); + size_t nvknots=checkArray(vknot); + + if(nuknots <= nu+1 || nuknots > 2*nu || nvknots <= nv+1 || nvknots > 2*nv) + reportError(wrongsize); + + udegree=nuknots-nu-1; + vdegree=nvknots-nv-1; + + uknots=run::copyArrayC(uknot,0); + vknots=run::copyArrayC(vknot,0); + + pen surfacepen=vm::read<camp::pen>(p,0); + invisible=surfacepen.invisible(); + + diffuse=rgba(surfacepen); + ambient=rgba(vm::read<camp::pen>(p,1)); + emissive=rgba(vm::read<camp::pen>(p,2)); + specular=rgba(vm::read<camp::pen>(p,3)); +#ifdef HAVE_LIBGL + uKnots=new GLfloat[nuknots]; + vKnots=new GLfloat[nvknots]; + Controls=new GLfloat[(weights ? 4 : 3)*n]; + + int size=checkArray(&pens); + if(size > 0) { + colors=new GLfloat[16]; + if(size != 4) reportError(wrongsize); + storecolor(colors,0,pens,0); + storecolor(colors,8,pens,1); + storecolor(colors,12,pens,2); + storecolor(colors,4,pens,3); + } else colors=NULL; +#endif } - drawSurface(const vm::array& t, const drawSurface *s) : - straight(s->straight), diffuse(s->diffuse), ambient(s->ambient), + drawNurbs(const vm::array& t, const drawNurbs *s) : + udegree(s->udegree), vdegree(s->vdegree), nu(s->nu), nv(s->nv), + diffuse(s->diffuse), ambient(s->ambient), emissive(s->emissive), specular(s->specular), opacity(s->opacity), shininess(s->shininess), PRCshininess(s->PRCshininess), - granularity(s->granularity), lighton(s->lighton), - invisible(s->invisible), colors(s->colors), havecolors(s->havecolors) { - for(size_t i=0; i < 16; ++i) { + granularity(s->granularity), invisible(s->invisible), lighton(s->lighton), + name(s->name) { + + size_t n=nu*nv; + controls=new double[n][3]; + + for(size_t i=0; i < n; ++i) { const double *c=s->controls[i]; triple v=run::operator *(t,triple(c[0],c[1],c[2])); controls[i][0]=v.getx(); controls[i][1]=v.gety(); controls[i][2]=v.getz(); } - normal=run::multshiftless(t,s->normal); + + if(s->weights) { + weights=new double[n]; + for(size_t i=0; i < n; ++i) + weights[i]=s->weights[i]; + } else weights=NULL; + + size_t nuknots=udegree+nu+1; + size_t nvknots=vdegree+nv+1; + uknots=new double[nuknots]; + vknots=new double[nvknots]; + + for(size_t i=0; i < nuknots; ++i) + uknots[i]=s->uknots[i]; + + for(size_t i=0; i < nvknots; ++i) + vknots[i]=s->vknots[i]; + +#ifdef HAVE_LIBGL + uKnots=new GLfloat[nuknots]; + vKnots=new GLfloat[nvknots]; + Controls=new GLfloat[(weights ? 4 : 3)*n]; + + if(s->colors) { + colors=new GLfloat[16]; + for(int i=0; i < 16; ++i) + colors[i]=s->colors[i]; + } else colors=NULL; +#endif } bool is3D() {return true;} void bounds(bbox3& b); - void ratio(pair &b, double (*m)(double, double), bool &first); - - virtual ~drawSurface() { - if(havecolors) - delete[] colors; + virtual ~drawNurbs() { + delete[] vknots; + delete[] uknots; + if(weights) + delete[] weights; + delete[] controls; +#ifdef HAVE_LIBGL + if(colors) + delete[] colors; + delete[] Controls; + delete[] vKnots; + delete[] uKnots; +#endif } bool write(prcfile *out); void displacement(); - void render(GLUnurbs *nurb, double, const triple& Min, const triple& Max, + void ratio(pair &b, double (*m)(double, double), bool &first); + + void render(GLUnurbs *nurb, double size2, + const triple& Min, const triple& Max, double perspective, bool transparent); - + drawElement *transformed(const vm::array& t); }; -double norm(double *a, size_t n); -double norm(triple *a, size_t n); - } #endif |