diff options
author | Karl Berry <karl@freefriends.org> | 2013-04-02 23:03:22 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2013-04-02 23:03:22 +0000 |
commit | 324efbd652f973cd70f42fe08c665c518995bcbe (patch) | |
tree | 818ae382dfa133f3dcceec8e12e4cbd42be8bcf4 /Build/source/utils/asymptote/drawsurface.cc | |
parent | bbf699abe485e707133ff3ba502119f261f27269 (diff) |
asy 2.21 sources (no runtime update)
git-svn-id: svn://tug.org/texlive/trunk@29618 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Build/source/utils/asymptote/drawsurface.cc')
-rw-r--r-- | Build/source/utils/asymptote/drawsurface.cc | 489 |
1 files changed, 301 insertions, 188 deletions
diff --git a/Build/source/utils/asymptote/drawsurface.cc b/Build/source/utils/asymptote/drawsurface.cc index bc9705e58b0..9775db2cb5c 100644 --- a/Build/source/utils/asymptote/drawsurface.cc +++ b/Build/source/utils/asymptote/drawsurface.cc @@ -7,6 +7,10 @@ #include "drawsurface.h" #include "arrayop.h" +#include <iostream> +#include <iomanip> +#include <fstream> + namespace camp { const double pixel=1.0; // Adaptive rendering constant. @@ -32,15 +36,64 @@ void storecolor(GLfloat *colors, int i, const RGBAColour& p) colors[i+2]=p.B; colors[i+3]=p.A; } + +void setcolors(bool colors, bool lighton, + const RGBAColour& diffuse, + const RGBAColour& ambient, + const RGBAColour& emissive, + const RGBAColour& specular, double shininess) +{ + if(colors) { + glEnable(GL_COLOR_MATERIAL); + if(!lighton) + glColorMaterial(GL_FRONT_AND_BACK,GL_EMISSION); + } + + if(colors) { + GLfloat Black[]={0,0,0,(GLfloat) diffuse.A}; + glMaterialfv(GL_FRONT_AND_BACK,GL_DIFFUSE,Black); + glMaterialfv(GL_FRONT_AND_BACK,GL_AMBIENT,Black); + glMaterialfv(GL_FRONT_AND_BACK,GL_EMISSION,Black); + } else { + GLfloat Diffuse[]={(GLfloat) diffuse.R,(GLfloat) diffuse.G, + (GLfloat) diffuse.B,(GLfloat) diffuse.A}; + glMaterialfv(GL_FRONT_AND_BACK,GL_DIFFUSE,Diffuse); + + GLfloat Ambient[]={(GLfloat) ambient.R,(GLfloat) ambient.G, + (GLfloat) ambient.B,(GLfloat) ambient.A}; + glMaterialfv(GL_FRONT_AND_BACK,GL_AMBIENT,Ambient); + + GLfloat Emissive[]={(GLfloat) emissive.R,(GLfloat) emissive.G, + (GLfloat) emissive.B,(GLfloat) emissive.A}; + glMaterialfv(GL_FRONT_AND_BACK,GL_EMISSION,Emissive); + } + + if(lighton) { + GLfloat Specular[]={(GLfloat) specular.R,(GLfloat) specular.G, + (GLfloat) specular.B,(GLfloat) specular.A}; + glMaterialfv(GL_FRONT_AND_BACK,GL_SPECULAR,Specular); + + glMaterialf(GL_FRONT_AND_BACK,GL_SHININESS,128.0*shininess); + } +} + #endif -void drawSurface::bounds(bbox3& b) +void drawSurface::bounds(const double* t, bbox3& b) { double x,y,z; double X,Y,Z; if(straight) { - double *v=vertices[0]; + Triple *Vertices; + if(t == NULL) Vertices=vertices; + else { + static Triple buf[4]; + Vertices=buf; + transformTriples(t,4,Vertices,vertices); + } + + double *v=Vertices[0]; x=v[0]; y=v[1]; z=v[2]; @@ -48,7 +101,7 @@ void drawSurface::bounds(bbox3& b) Y=y; Z=z; for(size_t i=1; i < 4; ++i) { - double *v=vertices[i]; + double *v=Vertices[i]; double vx=v[0]; x=min(x,vx); X=max(X,vx); @@ -60,44 +113,62 @@ void drawSurface::bounds(bbox3& b) Z=max(Z,vz); } } else { + Triple* Controls; + if(t == NULL) Controls=controls; + else { + static Triple buf[16]; + Controls=buf; + transformTriples(t,16,Controls,controls); + } + static double c1[16]; for(int i=0; i < 16; ++i) - c1[i]=controls[i][0]; + c1[i]=Controls[i][0]; double c0=c1[0]; double fuzz=sqrtFuzz*run::norm(c1,16); x=bound(c1,min,b.empty ? c0 : min(c0,b.left),fuzz); X=bound(c1,max,b.empty ? c0 : max(c0,b.right),fuzz); for(int i=0; i < 16; ++i) - c1[i]=controls[i][1]; + c1[i]=Controls[i][1]; c0=c1[0]; fuzz=sqrtFuzz*run::norm(c1,16); y=bound(c1,min,b.empty ? c0 : min(c0,b.bottom),fuzz); Y=bound(c1,max,b.empty ? c0 : max(c0,b.top),fuzz); for(int i=0; i < 16; ++i) - c1[i]=controls[i][2]; + c1[i]=Controls[i][2]; c0=c1[0]; fuzz=sqrtFuzz*run::norm(c1,16); z=bound(c1,min,b.empty ? c0 : min(c0,b.lower),fuzz); Z=bound(c1,max,b.empty ? c0 : max(c0,b.upper),fuzz); } - Min=triple(x,y,z); - Max=triple(X,Y,Z); - - b.add(Min); - b.add(Max); + b.add(x,y,z); + b.add(X,Y,Z); + + if(t == NULL) { + Min=triple(x,y,z); + Max=triple(X,Y,Z); + } } -void drawSurface::ratio(pair &b, double (*m)(double, double), double fuzz, - bool &first) +void drawSurface::ratio(const double* t, pair &b, double (*m)(double, double), + double fuzz, bool &first) { if(straight) { + Triple *Vertices; + if(t == NULL) Vertices=vertices; + else { + static Triple buf[4]; + Vertices=buf; + transformTriples(t,4,Vertices,vertices); + } + if(first) { first=false; - double *ci=vertices[0]; + double *ci=Vertices[0]; triple v=triple(ci[0],ci[1],ci[2]); b=pair(xratio(v),yratio(v)); } @@ -105,16 +176,24 @@ void drawSurface::ratio(pair &b, double (*m)(double, double), double fuzz, double x=b.getx(); double y=b.gety(); for(size_t i=0; i < 4; ++i) { - double *ci=vertices[i]; + double *ci=Vertices[i]; triple v=triple(ci[0],ci[1],ci[2]); x=m(x,xratio(v)); y=m(y,yratio(v)); } b=pair(x,y); } else { + Triple* Controls; + if(t == NULL) Controls=controls; + else { + static Triple buf[16]; + Controls=buf; + transformTriples(t,16,Controls,controls); + } + static triple c3[16]; for(int i=0; i < 16; ++i) { - double *ci=controls[i]; + double *ci=Controls[i]; c3[i]=triple(ci[0],ci[1],ci[2]); } @@ -128,8 +207,7 @@ void drawSurface::ratio(pair &b, double (*m)(double, double), double fuzz, } } -bool drawSurface::write(prcfile *out, unsigned int *, array *, array *, double, - groupsmap&) +bool drawSurface::write(prcfile *out, unsigned int *, double, groupsmap&) { if(invisible || !prc) return true; @@ -162,7 +240,7 @@ inline triple maxabs(triple u, triple v) max(fabs(u.getz()),fabs(v.getz()))); } -inline triple displacement(const Triple& z0, const Triple& c0, +inline triple displacement1(const Triple& z0, const Triple& c0, const Triple& c1, const Triple& z1) { triple Z0(z0); @@ -179,16 +257,16 @@ void drawSurface::displacement() if(!straight) { for(size_t i=1; i < 16; ++i) - d=camp::maxabs(d,camp::displacement2(controls[i],controls[0],normal)); + d=maxabs(d,displacement2(controls[i],controls[0],normal)); dperp=d; for(size_t i=0; i < 4; ++i) - d=camp::maxabs(d,camp::displacement(controls[4*i],controls[4*i+1], - controls[4*i+2],controls[4*i+3])); + d=maxabs(d,displacement1(controls[4*i],controls[4*i+1], + controls[4*i+2],controls[4*i+3])); for(size_t i=0; i < 4; ++i) - d=camp::maxabs(d,camp::displacement(controls[i],controls[i+4], - controls[i+8],controls[i+12])); + d=maxabs(d,displacement1(controls[i],controls[i+4], + controls[i+8],controls[i+12])); } } #endif @@ -209,7 +287,7 @@ inline double fraction(const triple& d, const triple& size) void drawSurface::render(GLUnurbs *nurb, double size2, const triple& Min, const triple& Max, - double perspective, bool transparent) + double perspective, bool lighton, bool transparent) { #ifdef HAVE_GL if(invisible || @@ -219,42 +297,24 @@ void drawSurface::render(GLUnurbs *nurb, double size2, static GLfloat Normal[3]; static GLfloat v[16]; - static GLfloat v1[16]; - static GLfloat v2[16]; - bool havebillboard=interaction == BILLBOARD && + const bool havebillboard=interaction == BILLBOARD && !settings::getSetting<bool>("offscreen"); triple m,M; if(perspective || !havebillboard) { - initMatrix(v1,v2); + static double t[16]; + glGetDoublev(GL_MODELVIEW_MATRIX,t); - glPushMatrix(); - glMultMatrixf(v1); - glGetFloatv(GL_MODELVIEW_MATRIX,v); - glPopMatrix(); - - bbox3 B(v[0],v[1],v[2]); - B.addnonempty(v[4],v[5],v[6]); - B.addnonempty(v[8],v[9],v[10]); - B.addnonempty(v[12],v[13],v[14]); - - glPushMatrix(); - glMultMatrixf(v2); - glGetFloatv(GL_MODELVIEW_MATRIX,v); - glPopMatrix(); - - B.addnonempty(v[0],v[1],v[2]); - B.addnonempty(v[4],v[5],v[6]); - B.addnonempty(v[8],v[9],v[10]); - B.addnonempty(v[12],v[13],v[14]); + bbox3 B(this->Min,this->Max); + B.transform(t); m=B.Min(); M=B.Max(); } if(perspective) { - double f=m.getz()*perspective; - double F=M.getz()*perspective; + const double f=m.getz()*perspective; + const double F=M.getz()*perspective; s=max(f,F); if(!havebillboard && (M.getx() < min(f*Min.getx(),F*Min.getx()) || m.getx() > max(f*Max.getx(),F*Max.getx()) || @@ -271,40 +331,10 @@ void drawSurface::render(GLUnurbs *nurb, double size2, return; } - bool ambientdiffuse=true; - bool emission=true; - - if(colors) { - glEnable(GL_COLOR_MATERIAL); - if(lighton) { - glColorMaterial(GL_FRONT_AND_BACK,GL_AMBIENT_AND_DIFFUSE); - ambientdiffuse=false; - } else { - glColorMaterial(GL_FRONT_AND_BACK,GL_EMISSION); - emission=false; - } - } + setcolors(colors,lighton,diffuse,ambient,emissive,specular,shininess); - if(ambientdiffuse) { - GLfloat Diffuse[]={diffuse.R,diffuse.G,diffuse.B,diffuse.A}; - glMaterialfv(GL_FRONT_AND_BACK,GL_DIFFUSE,Diffuse); - - GLfloat Ambient[]={ambient.R,ambient.G,ambient.B,ambient.A}; - glMaterialfv(GL_FRONT_AND_BACK,GL_AMBIENT,Ambient); - } - - if(emission) { - GLfloat Emissive[]={emissive.R,emissive.G,emissive.B,emissive.A}; - glMaterialfv(GL_FRONT_AND_BACK,GL_EMISSION,Emissive); - } - - GLfloat Specular[]={specular.R,specular.G,specular.B,specular.A}; - glMaterialfv(GL_FRONT_AND_BACK,GL_SPECULAR,Specular); - - glMaterialf(GL_FRONT_AND_BACK,GL_SHININESS,128.0*shininess); - - triple size3=triple(s*(Max.getx()-Min.getx()),s*(Max.gety()-Min.gety()), - Max.getz()-Min.getz()); + const triple size3(s*(Max.getx()-Min.getx()),s*(Max.gety()-Min.gety()), + Max.getz()-Min.getz()); bool havenormal=normal != zero; if(havebillboard) BB.init(); @@ -383,13 +413,12 @@ void drawSurface::render(GLUnurbs *nurb, double size2, #endif } -drawElement *drawSurface::transformed(const array& t) +drawElement *drawSurface::transformed(const double* t) { return new drawSurface(t,this); } -bool drawNurbs::write(prcfile *out, unsigned int *, array *, array *, double, - groupsmap&) +bool drawNurbs::write(prcfile *out, unsigned int *, double, groupsmap&) { if(invisible) return true; @@ -401,10 +430,17 @@ bool drawNurbs::write(prcfile *out, unsigned int *, array *, array *, double, } // Approximate bounds by bounding box of control polyhedron. -void drawNurbs::bounds(bbox3& b) +void drawNurbs::bounds(const double* t, bbox3& b) { - size_t n=nu*nv; - double *v=controls[0]; + const size_t n=nu*nv; + Triple* Controls; + if(t == NULL) Controls=controls; + else { + Controls=new Triple[n]; + transformTriples(t,n,Controls,controls); + } + + double *v=Controls[0]; double x=v[0]; double y=v[1]; double z=v[2]; @@ -412,7 +448,7 @@ void drawNurbs::bounds(bbox3& b) double Y=y; double Z=z; for(size_t i=1; i < n; ++i) { - double *v=controls[i]; + double *v=Controls[i]; double vx=v[0]; x=min(x,vx); X=max(X,vx); @@ -424,23 +460,34 @@ void drawNurbs::bounds(bbox3& b) Z=max(Z,vz); } - Min=triple(x,y,z); - Max=triple(X,Y,Z); - b.add(Min); - b.add(Max); + b.add(x,y,z); + b.add(X,Y,Z); + + if(t == NULL) { + Min=triple(x,y,z); + Max=triple(X,Y,Z); + } else delete[] Controls; } -drawElement *drawNurbs::transformed(const array& t) +drawElement *drawNurbs::transformed(const double* t) { return new drawNurbs(t,this); } -void drawNurbs::ratio(pair &b, double (*m)(double, double), double, bool &first) +void drawNurbs::ratio(const double *t, pair &b, double (*m)(double, double), + double, bool &first) { - size_t n=nu*nv; + const size_t n=nu*nv; + Triple* Controls; + if(t == NULL) Controls=controls; + else { + Controls=new Triple[n]; + transformTriples(t,n,Controls,controls); + } + if(first) { first=false; - double *ci=controls[0]; + double *ci=Controls[0]; triple v=triple(ci[0],ci[1],ci[2]); b=pair(xratio(v),yratio(v)); } @@ -448,14 +495,18 @@ void drawNurbs::ratio(pair &b, double (*m)(double, double), double, bool &first) double x=b.getx(); double y=b.gety(); for(size_t i=0; i < n; ++i) { - double *ci=controls[i]; + double *ci=Controls[i]; triple v=triple(ci[0],ci[1],ci[2]); x=m(x,xratio(v)); y=m(y,yratio(v)); } b=pair(x,y); + + if(t != NULL) + delete[] Controls; } + void drawNurbs::displacement() { #ifdef HAVE_GL @@ -485,37 +536,17 @@ void drawNurbs::displacement() void drawNurbs::render(GLUnurbs *nurb, double size2, const triple& Min, const triple& Max, - double perspective, bool transparent) + double perspective, bool lighton, bool transparent) { #ifdef HAVE_GL if(invisible || ((colors ? colors[3]+colors[7]+colors[11]+colors[15] < 4.0 : diffuse.A < 1.0) ^ transparent)) return; - static GLfloat v[16]; - static GLfloat v1[16]; - static GLfloat v2[16]; - - initMatrix(v1,v2); - - glPushMatrix(); - glMultMatrixf(v1); - glGetFloatv(GL_MODELVIEW_MATRIX,v); - glPopMatrix(); - - bbox3 B(v[0],v[1],v[2]); - B.addnonempty(v[4],v[5],v[6]); - B.addnonempty(v[8],v[9],v[10]); - B.addnonempty(v[12],v[13],v[14]); - - glPushMatrix(); - glMultMatrixf(v2); - glGetFloatv(GL_MODELVIEW_MATRIX,v); - glPopMatrix(); - - B.addnonempty(v[0],v[1],v[2]); - B.addnonempty(v[4],v[5],v[6]); - B.addnonempty(v[8],v[9],v[10]); - B.addnonempty(v[12],v[13],v[14]); + static double t[16]; // current transform + glGetDoublev(GL_MODELVIEW_MATRIX,t); + + bbox3 B(this->Min,this->Max); + B.transform(t); triple m=B.Min(); triple M=B.Max(); @@ -535,39 +566,8 @@ void drawNurbs::render(GLUnurbs *nurb, double size2, M.getz() < Min.getz() || m.getz() > Max.getz()) return; } - bool ambientdiffuse=true; - bool emission=true; - - if(colors) { - glEnable(GL_COLOR_MATERIAL); - if(lighton) { - glColorMaterial(GL_FRONT_AND_BACK,GL_AMBIENT_AND_DIFFUSE); - ambientdiffuse=false; - } else { - glColorMaterial(GL_FRONT_AND_BACK,GL_EMISSION); - emission=false; - } - } + setcolors(colors,lighton,diffuse,ambient,emissive,specular,shininess); - if(ambientdiffuse) { - GLfloat Diffuse[]={diffuse.R,diffuse.G,diffuse.B,diffuse.A}; - glMaterialfv(GL_FRONT_AND_BACK,GL_DIFFUSE,Diffuse); - - GLfloat Ambient[]={ambient.R,ambient.G,ambient.B,ambient.A}; - glMaterialfv(GL_FRONT_AND_BACK,GL_AMBIENT,Ambient); - } - - if(emission) { - GLfloat Emissive[]={emissive.R,emissive.G,emissive.B,emissive.A}; - glMaterialfv(GL_FRONT_AND_BACK,GL_EMISSION,Emissive); - } - - GLfloat Specular[]={specular.R,specular.G,specular.B,specular.A}; - glMaterialfv(GL_FRONT_AND_BACK,GL_SPECULAR,Specular); - - glMaterialf(GL_FRONT_AND_BACK,GL_SHININESS,128.0*shininess); - - gluNurbsCallback(nurb,GLU_NURBS_NORMAL,(_GLUfuncptr) glNormal3fv); gluBeginSurface(nurb); int uorder=udegree+1; int vorder=vdegree+1; @@ -575,6 +575,9 @@ void drawNurbs::render(GLUnurbs *nurb, double size2, gluNurbsSurface(nurb,uorder+nu,uKnots,vorder+nv,vKnots,stride*nv,stride, Controls,uorder,vorder, weights ? GL_MAP2_VERTEX_4 : GL_MAP2_VERTEX_3); + if(lighton) + gluNurbsCallback(nurb,GLU_NURBS_NORMAL,(_GLUfuncptr) glNormal3fv); + if(colors) { static GLfloat linear[]={0.0,0.0,1.0,1.0}; gluNurbsSurface(nurb,4,linear,4,linear,8,4,colors,2,2,GL_MAP2_COLOR_4); @@ -593,25 +596,16 @@ void drawSphere::P(Triple& t, double x, double y, double z) double temp=z; z=x; x=-temp; } - double f=T[12]*x+T[13]*y+T[14]*z+T[15]; + double f=T[3]*x+T[7]*y+T[11]*z+T[15]; if(f == 0.0) run::dividebyzero(); f=1.0/f; - t[0]=(T[0]*x+T[1]*y+T[2]*z+T[3])*f; - t[1]=(T[4]*x+T[5]*y+T[6]*z+T[7])*f; - t[2]=(T[8]*x+T[9]*y+T[10]*z+T[11])*f; + t[0]=(T[0]*x+T[4]*y+T[ 8]*z+T[12])*f; + t[1]=(T[1]*x+T[5]*y+T[ 9]*z+T[13])*f; + t[2]=(T[2]*x+T[6]*y+T[10]*z+T[14])*f; } -static const Triple origin={0.0,0.0,0.0}; -static const Triple xaxis={1.0,0.0,0.0}; -static const Triple yaxis={0.0,1.0,0.0}; -static const double Identity4[4][4]={{1.0,0.0,0.0,0.0}, - {0.0,1.0,0.0,0.0}, - {0.0,0.0,1.0,0.0}, - {0.0,0.0,0.0,1.0}}; - -bool drawSphere::write(prcfile *out, unsigned int *, array *, array *, double, - groupsmap&) +bool drawSphere::write(prcfile *out, unsigned int *, double, groupsmap&) { if(invisible) return true; @@ -622,9 +616,9 @@ bool drawSphere::write(prcfile *out, unsigned int *, array *, array *, double, case 0: // PRCsphere { if(half) - out->addHemisphere(1.0,m,origin,xaxis,yaxis,1.0,(double (*)[4]) T); + out->addHemisphere(1.0,m,NULL,NULL,NULL,1.0,T); else - out->addSphere(1.0,m,origin,xaxis,yaxis,1.0,(double (*)[4]) T); + out->addSphere(1.0,m,NULL,NULL,NULL,1.0,T); break; } case 1: // NURBSsphere @@ -699,34 +693,31 @@ bool drawSphere::write(prcfile *out, unsigned int *, array *, array *, double, return true; } -bool drawCylinder::write(prcfile *out, unsigned int *, array *, array *, double, - groupsmap&) +bool drawCylinder::write(prcfile *out, unsigned int *, double, groupsmap&) { if(invisible) return true; PRCmaterial m(ambient,diffuse,emissive,specular,opacity,shininess); - out->addCylinder(1.0,1.0,m,origin,xaxis,yaxis,1.0,(double (*)[4]) T); + out->addCylinder(1.0,1.0,m,NULL,NULL,NULL,1.0,T); return true; } -bool drawDisk::write(prcfile *out, unsigned int *, array *, array *, double, - groupsmap&) +bool drawDisk::write(prcfile *out, unsigned int *, double, groupsmap&) { if(invisible) return true; PRCmaterial m(ambient,diffuse,emissive,specular,opacity,shininess); - out->addDisk(1.0,m,origin,xaxis,yaxis,1.0,(double (*)[4]) T); + out->addDisk(1.0,m,NULL,NULL,NULL,1.0,T); return true; } -bool drawTube::write(prcfile *out, unsigned int *, array *, array *, double, - groupsmap&) +bool drawTube::write(prcfile *out, unsigned int *, double, groupsmap&) { if(invisible) return true; @@ -743,8 +734,7 @@ bool drawTube::write(prcfile *out, unsigned int *, array *, array *, double, Triple *controls=new(UseGC) Triple[N]; for(Int i=0; i <= n; ++i) store(controls[i],g.point(i)); - out->addTube(N,centerControls,controls,true,m,origin,xaxis,yaxis,1.0, - Identity4); + out->addTube(N,centerControls,controls,true,m,NULL,NULL,NULL,1.0); } else { size_t N=3*n+1; Triple *centerControls=new(UseGC) Triple[N]; @@ -771,15 +761,13 @@ bool drawTube::write(prcfile *out, unsigned int *, array *, array *, double, store(controls[++k],g.precontrol(n)); store(controls[++k],g.point(n)); - out->addTube(N,centerControls,controls,false,m,origin,xaxis,yaxis,1.0, - Identity4); + out->addTube(N,centerControls,controls,false,m,NULL,NULL,NULL,1.0); } return true; } -bool drawPixel::write(prcfile *out, unsigned int *, array *, array *, double, - groupsmap&) +bool drawPixel::write(prcfile *out, unsigned int *, double, groupsmap&) { if(invisible) return true; @@ -791,7 +779,7 @@ bool drawPixel::write(prcfile *out, unsigned int *, array *, array *, double, void drawPixel::render(GLUnurbs *nurb, double size2, const triple& Min, const triple& Max, - double perspective, bool transparent) + double perspective, bool lighton, bool transparent) { #ifdef HAVE_GL if(invisible) @@ -822,4 +810,129 @@ void drawPixel::render(GLUnurbs *nurb, double size2, #endif } +const string drawBaseTriangles::wrongsize= + "triangle indices require 3 components"; +const string drawBaseTriangles::outofrange="index out of range"; + +void drawBaseTriangles::bounds(const double* t, bbox3& b) +{ + double x,y,z; + double X,Y,Z; + Triple* tP; + + if(t == NULL) tP=P; + else { + tP=new Triple[nP]; + transformTriples(t,nP,tP,P); + } + + boundsTriples(x,y,z,X,Y,Z,nP,tP); + + b.add(x,y,z); + b.add(X,Y,Z); + + if(t == NULL) { + Min=triple(x,y,z); + Max=triple(X,Y,Z); + } else delete[] tP; +} + +void drawBaseTriangles::ratio(const double* t, pair &b, + double (*m)(double, double), double fuzz, + bool &first) +{ + Triple* tP; + + if(t == NULL) tP=P; + else { + tP=new Triple[nP]; + transformTriples(t,nP,tP,P); + } + + ratioTriples(b,m,first,nP,tP); + + if(t != NULL) + delete[] tP; +} + +bool drawTriangles::write(prcfile *out, unsigned int *, double, groupsmap&) +{ + if(invisible) + return true; + + PRCmaterial m(ambient,diffuse,emissive,specular,opacity,PRCshininess); + + out->addTriangles(nP,P,nI,PI,m,nN,N,NI,0,NULL,NULL,nC,C,CI,0,NULL,NULL,30); + + return true; +} + +void drawTriangles::render(GLUnurbs *nurb, double size2, const triple& Min, + const triple& Max, double perspective, bool lighton, + bool transparent) +{ +#ifdef HAVE_GL + if(invisible) + return; + + if(invisible || ((diffuse.A < 1.0) ^ transparent)) return; + + triple m,M; + static double t[16]; // current transform + glGetDoublev(GL_MODELVIEW_MATRIX,t); + + bbox3 B(this->Min,this->Max); + B.transform(t); + + m=B.Min(); + M=B.Max(); + + if(perspective) { + const double f=m.getz()*perspective; + const double F=M.getz()*perspective; + if((M.getx() < min(f*Min.getx(),F*Min.getx()) || + m.getx() > max(f*Max.getx(),F*Max.getx()) || + M.gety() < min(f*Min.gety(),F*Min.gety()) || + m.gety() > max(f*Max.gety(),F*Max.gety()) || + M.getz() < Min.getz() || + m.getz() > Max.getz())) + return; + } else { + if((M.getx() < Min.getx() || m.getx() > Max.getx() || + M.gety() < Min.gety() || m.gety() > Max.gety() || + M.getz() < Min.getz() || m.getz() > Max.getz())) + return; + } + + setcolors(nC,!nC,diffuse,ambient,emissive,specular,shininess); + if(!nN) lighton=false; + + glBegin(GL_TRIANGLES); + for(size_t i=0; i < nI; i++) { + const uint32_t *pi=PI[i]; + const uint32_t *ni=NI[i]; + const uint32_t *ci=nC ? CI[i] : 0; + if(lighton) + glNormal3f(N[ni[0]][0],N[ni[0]][1],N[ni[0]][2]); + if(nC) + glColor4f(C[ci[0]].R,C[ci[0]].G,C[ci[0]].B,C[ci[0]].A); + glVertex3f(P[pi[0]][0],P[pi[0]][1],P[pi[0]][2]); + if(lighton) + glNormal3f(N[ni[1]][0],N[ni[1]][1],N[ni[1]][2]); + if(nC) + glColor4f(C[ci[1]].R,C[ci[1]].G,C[ci[1]].B,C[ci[1]].A); + glVertex3f(P[pi[1]][0],P[pi[1]][1],P[pi[1]][2]); + if(lighton) + glNormal3f(N[ni[2]][0],N[ni[2]][1],N[ni[2]][2]); + if(nC) + glColor4f(C[ci[2]].R,C[ci[2]].G,C[ci[2]].B,C[ci[2]].A); + glVertex3f(P[pi[2]][0],P[pi[2]][1],P[pi[2]][2]); + } + glEnd(); + + if(nC) + glDisable(GL_COLOR_MATERIAL); +#endif +} + } //namespace camp |