summaryrefslogtreecommitdiff
path: root/Build/source/utils/asymptote/drawsurface.h
diff options
context:
space:
mode:
Diffstat (limited to 'Build/source/utils/asymptote/drawsurface.h')
-rw-r--r--Build/source/utils/asymptote/drawsurface.h263
1 files changed, 184 insertions, 79 deletions
diff --git a/Build/source/utils/asymptote/drawsurface.h b/Build/source/utils/asymptote/drawsurface.h
index 15b07d857c3..a44dfaa7453 100644
--- a/Build/source/utils/asymptote/drawsurface.h
+++ b/Build/source/utils/asymptote/drawsurface.h
@@ -20,15 +20,15 @@ void storecolor(GLfloat *colors, int i, const vm::array &pens, int j);
class drawSurface : public drawElement {
protected:
- Triple *controls;
- Triple vertices[4];
+ triple *controls;
+ triple vertices[4];
triple center;
- bool straight;
- RGBAColour diffuse;
- RGBAColour ambient;
- RGBAColour emissive;
- RGBAColour specular;
- RGBAColour *colors;
+ bool straight; // True iff Bezier patch is planar and has straight edges.
+ prc::RGBAColour diffuse;
+ prc::RGBAColour ambient;
+ prc::RGBAColour emissive;
+ prc::RGBAColour specular;
+ prc::RGBAColour *colors;
double opacity;
double shininess;
double PRCshininess;
@@ -57,26 +57,24 @@ public:
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));
+ vertices[0]=vm::read<triple>(g0,0);
+ vertices[1]=vm::read<triple>(g0,3);
+ vertices[2]=vm::read<triple>(g3,0);
+ vertices[3]=vm::read<triple>(g3,3);
- if(!havenormal || !straight) {
+ if(!straight) {
size_t k=0;
- controls=new(UseGC) Triple[16];
+ controls=new(UseGC) 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));
+ controls[k++]=vm::read<triple>(gi,j);
}
} else controls=NULL;
@@ -90,8 +88,8 @@ public:
int size=checkArray(&pens);
if(size > 0) {
- if(size != 4) reportError(wrongsize);
- colors=new(UseGC) RGBAColour[4];
+ if(size != 4) reportError("4 vertex pens required");
+ colors=new(UseGC) prc::RGBAColour[4];
colors[0]=rgba(vm::read<camp::pen>(pens,0));
colors[1]=rgba(vm::read<camp::pen>(pens,3));
colors[2]=rgba(vm::read<camp::pen>(pens,1));
@@ -102,17 +100,19 @@ public:
drawSurface(const double* t, const drawSurface *s) :
straight(s->straight), diffuse(s->diffuse), ambient(s->ambient),
emissive(s->emissive), specular(s->specular), colors(s->colors),
- opacity(s->opacity), shininess(s->shininess), PRCshininess(s->PRCshininess),
- invisible(s->invisible),
+ opacity(s->opacity), shininess(s->shininess),
+ PRCshininess(s->PRCshininess), invisible(s->invisible),
interaction(s->interaction), prc(s->prc) {
- transformTriples(t,4,vertices,s->vertices);
+ for(unsigned int i=0; i < 4; ++i)
+ vertices[i]=t*s->vertices[i];
if(s->controls) {
- controls=new(UseGC) Triple[16];
- transformTriples(t,16,controls,s->controls);
+ controls=new(UseGC) triple[16];
+ for(unsigned int i=0; i < 16; ++i)
+ controls[i]=t*s->controls[i];
} else controls=NULL;
-
+
#ifdef HAVE_GL
center=t*s->center;
normal=transformNormal(t,s->normal);
@@ -123,8 +123,8 @@ public:
void bounds(const double* t, bbox3& b);
- void ratio(const double* t, pair &b, double (*m)(double, double), double fuzz,
- bool &first);
+ void ratio(const double* t, pair &b, double (*m)(double, double),
+ double fuzz, bool &first);
virtual ~drawSurface() {}
@@ -138,17 +138,117 @@ public:
drawElement *transformed(const double* t);
};
+class drawBezierTriangle : public drawElement {
+protected:
+ triple *controls;
+ triple center;
+ bool straight; // True iff Bezier triangle is planar and has straight edges.
+ prc::RGBAColour diffuse;
+ prc::RGBAColour ambient;
+ prc::RGBAColour emissive;
+ prc::RGBAColour specular;
+ prc::RGBAColour *colors;
+ double opacity;
+ double shininess;
+ double PRCshininess;
+ bool invisible;
+ Interaction interaction;
+
+ triple Min,Max;
+ bool prc;
+
+#ifdef HAVE_GL
+ triple d; // Maximum deviation of surface from a triangle.
+ triple dperp;
+#endif
+
+public:
+ drawBezierTriangle(const vm::array& g, triple center, bool straight,
+ const vm::array&p, double opacity, double shininess,
+ double PRCshininess, const vm::array &pens,
+ Interaction interaction, bool prc) :
+ center(center), straight(straight), opacity(opacity), shininess(shininess),
+ PRCshininess(PRCshininess), interaction(interaction), prc(prc) {
+ const string wrongsize=
+ "Bezier triangle requires triangular array of 10 triples and array of 4 pens";
+ if(checkArray(&g) != 4 || checkArray(&p) != 4)
+ reportError(wrongsize);
+
+ size_t k=0;
+ controls=new(UseGC) triple[10];
+ for(unsigned int i=0; i < 4; ++i) {
+ vm::array *gi=vm::read<vm::array*>(g,i);
+ for(unsigned int j=0; j <= i; ++j) {
+ controls[k++]=vm::read<triple>(gi,j);
+ }
+ }
+
+ 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));
+
+ int size=checkArray(&pens);
+ if(size > 0) {
+ if(size != 3) reportError("3 vertex pens required");
+ colors=new(UseGC) prc::RGBAColour[3];
+ colors[0]=rgba(vm::read<camp::pen>(pens,0));
+ colors[1]=rgba(vm::read<camp::pen>(pens,1));
+ colors[2]=rgba(vm::read<camp::pen>(pens,2));
+ } else colors=NULL;
+ }
+
+ drawBezierTriangle(const double* t, const drawBezierTriangle *s) :
+ straight(s->straight), diffuse(s->diffuse), ambient(s->ambient),
+ emissive(s->emissive), specular(s->specular), colors(s->colors),
+ opacity(s->opacity), shininess(s->shininess),
+ PRCshininess(s->PRCshininess), invisible(s->invisible),
+ interaction(s->interaction), prc(s->prc) {
+
+ if(s->controls) {
+ controls=new(UseGC) triple[10];
+ for(unsigned int i=0; i < 10; ++i)
+ controls[i]=t*s->controls[i];
+ } else controls=NULL;
+
+#ifdef HAVE_GL
+ center=t*s->center;
+#endif
+ }
+
+ bool is3D() {return true;}
+
+ void bounds(const double* t, bbox3& b);
+
+ void ratio(const double* t, pair &b, double (*m)(double, double),
+ double fuzz, bool &first);
+
+ virtual ~drawBezierTriangle() {}
+
+ bool write(prcfile *out, unsigned int *, double, groupsmap&);
+
+// void displacement();
+
+ void render(GLUnurbs *nurb, double, const triple& Min, const triple& Max,
+ double perspective, bool lighton, bool transparent);
+
+ drawElement *transformed(const double* t);
+};
+
class drawNurbs : public drawElement {
protected:
size_t udegree,vdegree;
size_t nu,nv;
- Triple *controls;
+ triple *controls;
double *weights;
double *uknots, *vknots;
- RGBAColour diffuse;
- RGBAColour ambient;
- RGBAColour emissive;
- RGBAColour specular;
+ prc::RGBAColour diffuse;
+ prc::RGBAColour ambient;
+ prc::RGBAColour emissive;
+ prc::RGBAColour specular;
double opacity;
double shininess;
double PRCshininess;
@@ -182,7 +282,7 @@ public:
nv=checkArray(g0);
size_t n=nu*nv;
- controls=new(UseGC) Triple[n];
+ controls=new(UseGC) triple[n];
size_t k=0;
for(size_t i=0; i < nu; ++i) {
@@ -190,7 +290,7 @@ public:
if(checkArray(gi) != nv)
reportError(wrongsize);
for(size_t j=0; j < nv; ++j)
- store(controls[k++],vm::read<triple>(gi,j));
+ controls[k++]=vm::read<triple>(gi,j);
}
if(weightsize > 0) {
@@ -248,9 +348,9 @@ public:
invisible(s->invisible) {
const size_t n=nu*nv;
- controls=new(UseGC) Triple[n];
-
- transformTriples(t,n,controls,s->controls);
+ controls=new(UseGC) triple[n];
+ for(unsigned int i=0; i < n; ++i)
+ controls[i]=t*s->controls[i];
#ifdef HAVE_GL
Controls=NULL;
@@ -270,8 +370,9 @@ public:
void ratio(const double* t, pair &b, double (*m)(double, double), double,
bool &first);
- void render(GLUnurbs *nurb, double size2, const triple& Min, const triple& Max,
- double perspective, bool lighton, bool transparent);
+ void render(GLUnurbs *nurb, double size2, const triple& Min,
+ const triple& Max, double perspective, bool lighton,
+ bool transparent);
drawElement *transformed(const double* t);
};
@@ -279,10 +380,10 @@ public:
// Draw a transformed PRC object.
class drawPRC : public drawElementLC {
protected:
- RGBAColour diffuse;
- RGBAColour ambient;
- RGBAColour emissive;
- RGBAColour specular;
+ prc::RGBAColour diffuse;
+ prc::RGBAColour ambient;
+ prc::RGBAColour emissive;
+ prc::RGBAColour specular;
double opacity;
double shininess;
bool invisible;
@@ -314,8 +415,8 @@ public:
return true;
}
virtual void transformedbounds(const double*, bbox3&) {}
- virtual void transformedratio(const double*, pair&, double (*)(double, double),
- double, bool&) {}
+ virtual void transformedratio(const double*, pair&,
+ double (*)(double, double), double, bool&) {}
};
@@ -331,7 +432,7 @@ public:
drawSphere(const double* t, const drawSphere *s) :
drawPRC(t,s), half(s->half), type(s->type) {}
- void P(Triple& t, double x, double y, double z);
+ void P(triple& t, double x, double y, double z);
bool write(prcfile *out, unsigned int *, double, groupsmap&);
@@ -379,10 +480,10 @@ class drawTube : public drawElement {
protected:
path3 center;
path3 g;
- RGBAColour diffuse;
- RGBAColour ambient;
- RGBAColour emissive;
- RGBAColour specular;
+ prc::RGBAColour diffuse;
+ prc::RGBAColour ambient;
+ prc::RGBAColour emissive;
+ prc::RGBAColour specular;
double opacity;
double shininess;
bool invisible;
@@ -419,27 +520,27 @@ public:
// Draw a PRC pixel.
class drawPixel : public drawElement {
- Triple v;
- RGBAColour c;
+ triple v;
+ prc::RGBAColour c;
double width;
bool invisible;
public:
drawPixel(const triple& v0, const pen& p, double width) :
c(rgba(p)), width(width) {
- store(v,v0);
+ v=v0;
invisible=p.invisible();
}
drawPixel(const double* t, const drawPixel *s) :
c(s->c), width(s->width), invisible(s->invisible) {
- transformTriples(t,1,&v,&(s->v));
+ v=t*s->v;
}
void bounds(const double* t, bbox3& b) {
const triple R=0.5*width*triple(1.0,1.0,1.0);
if (t != NULL) {
- Triple tv;
- transformTriples(t,1,&tv,&v);
+ triple tv;
+ tv=t*v;
b.add(tv-R);
b.add(tv+R);
} else {
@@ -448,8 +549,9 @@ public:
}
}
- void render(GLUnurbs *nurb, double size2, const triple& Min, const triple& Max,
- double perspective, bool lighton, bool transparent);
+ void render(GLUnurbs *nurb, double size2, const triple& Min,
+ const triple& Max, double perspective, bool lighton,
+ bool transparent);
bool write(prcfile *out, unsigned int *, double, groupsmap&);
@@ -461,9 +563,9 @@ public:
class drawBaseTriangles : public drawElement {
protected:
size_t nP;
- Triple* P;
+ triple* P;
size_t nN;
- Triple* N;
+ triple* N;
size_t nI;
uint32_t (*PI)[3];
uint32_t (*NI)[3];
@@ -477,9 +579,9 @@ public:
drawBaseTriangles(const vm::array& v, const vm::array& vi,
const vm::array& n, const vm::array& ni) {
nP=checkArray(&v);
- P=new(UseGC) Triple[nP];
+ P=new(UseGC) triple[nP];
for(size_t i=0; i < nP; ++i)
- store(P[i],vm::read<triple>(v,i));
+ P[i]=vm::read<triple>(v,i);
nI=checkArray(&vi);
PI=new(UseGC) uint32_t[nI][3];
@@ -496,9 +598,9 @@ public:
nN=checkArray(&n);
if(nN) {
- N=new(UseGC) Triple[nN];
+ N=new(UseGC) triple[nN];
for(size_t i=0; i < nN; ++i)
- store(N[i],vm::read<triple>(n,i));
+ N[i]=vm::read<triple>(n,i);
if(checkArray(&ni) != nI)
reportError("Index arrays have different lengths");
@@ -518,8 +620,9 @@ public:
drawBaseTriangles(const double* t, const drawBaseTriangles *s) :
nP(s->nP), nN(s->nN), nI(s->nI) {
- P=new(UseGC) Triple[nP];
- transformTriples(t,nP,P,s->P);
+ P=new(UseGC) triple[nP];
+ for(size_t i=0; i < nP; i++)
+ P[i]=t*s->P[i];
PI=new(UseGC) uint32_t[nI][3];
for(size_t i=0; i < nI; ++i) {
@@ -530,8 +633,9 @@ public:
}
if(nN) {
- N=new(UseGC) Triple[nN];
- transformNormalsTriples(t,nN,N,s->N);
+ N=new(UseGC) triple[nN];
+ for(size_t i=0; i < nN; i++)
+ N[i]=transformNormal(t,s->N[i]);
NI=new(UseGC) uint32_t[nI][3];
for(size_t i=0; i < nI; ++i) {
@@ -547,8 +651,8 @@ public:
void bounds(const double* t, bbox3& b);
- void ratio(const double* t, pair &b, double (*m)(double, double), double fuzz,
- bool &first);
+ void ratio(const double* t, pair &b, double (*m)(double, double),
+ double fuzz, bool &first);
virtual ~drawBaseTriangles() {}
@@ -559,14 +663,14 @@ public:
class drawTriangles : public drawBaseTriangles {
size_t nC;
- RGBAColour*C;
+ prc::RGBAColour*C;
uint32_t (*CI)[3];
// Asymptote material data
- RGBAColour diffuse;
- RGBAColour ambient;
- RGBAColour emissive;
- RGBAColour specular;
+ prc::RGBAColour diffuse;
+ prc::RGBAColour ambient;
+ prc::RGBAColour emissive;
+ prc::RGBAColour specular;
double opacity;
double shininess;
double PRCshininess;
@@ -590,7 +694,7 @@ public:
nC=checkArray(&c);
if(nC) {
- C=new(UseGC) RGBAColour[nC];
+ C=new(UseGC) prc::RGBAColour[nC];
for(size_t i=0; i < nC; ++i)
C[i]=rgba(vm::read<camp::pen>(c,i));
@@ -624,7 +728,7 @@ public:
invisible(s->invisible) {
if(nC) {
- C=new(UseGC) RGBAColour[nC];
+ C=new(UseGC) prc::RGBAColour[nC];
for(size_t i=0; i < nC; ++i)
C[i]=s->C[i];
@@ -640,8 +744,9 @@ public:
virtual ~drawTriangles() {}
- void render(GLUnurbs *nurb, double size2, const triple& Min, const triple& Max,
- double perspective, bool lighton, bool transparent);
+ void render(GLUnurbs *nurb, double size2, const triple& Min,
+ const triple& Max, double perspective, bool lighton,
+ bool transparent);
bool write(prcfile *out, unsigned int *, double, groupsmap&);