diff options
Diffstat (limited to 'Build/source/utils/asymptote/drawpath3.h')
-rw-r--r-- | Build/source/utils/asymptote/drawpath3.h | 244 |
1 files changed, 244 insertions, 0 deletions
diff --git a/Build/source/utils/asymptote/drawpath3.h b/Build/source/utils/asymptote/drawpath3.h new file mode 100644 index 00000000000..3209493bf2a --- /dev/null +++ b/Build/source/utils/asymptote/drawpath3.h @@ -0,0 +1,244 @@ +/***** + * drawpath3.h + * + * Stores a path3 that has been added to a picture. + *****/ + +#ifndef DRAWPATH3_H +#define DRAWPATH3_H + +#include "drawelement.h" +#include "path3.h" +#include "beziercurve.h" + +namespace camp { + +class drawPath3 : public drawElement { +protected: + const path3 g; + triple center; + bool straight; + prc::RGBAColour diffuse; + prc::RGBAColour emissive; + prc::RGBAColour specular; + double opacity; + double shininess; + double metallic; + double fresnel0; + bool invisible; + Interaction interaction; + triple Min,Max; + bool billboard; + size_t centerIndex; +public: +#ifdef HAVE_GL + BezierCurve R; +#endif + void init() { +#ifdef HAVE_LIBOSMESA + billboard=false; +#else + billboard=interaction == BILLBOARD; +#endif + centerIndex=0; + } + + drawPath3(path3 g, triple center, const vm::array& p, double opacity, + double shininess, double metallic, double fresnel0, + Interaction interaction, const string& key="") : + drawElement(key), g(g), center(center), + straight(g.piecewisestraight()), opacity(opacity), + shininess(shininess), metallic(metallic), fresnel0(fresnel0), + interaction(interaction), Min(g.min()), Max(g.max()) { + init(); + + pen Pen=vm::read<camp::pen>(p,0); + invisible=Pen.invisible(); + diffuse=rgba(Pen); + emissive=rgba(vm::read<camp::pen>(p,1)); + specular=rgba(vm::read<camp::pen>(p,2)); + } + + drawPath3(const double* t, const drawPath3 *s) : + drawElement(s->KEY), g(camp::transformed(t,s->g)), straight(s->straight), + diffuse(s->diffuse), emissive(s->emissive), specular(s->specular), + opacity(s->opacity), shininess(s->shininess), + metallic(s->metallic), fresnel0(s->fresnel0), + invisible(s->invisible), interaction(s->interaction), + Min(g.min()), Max(g.max()) { + init(); + center=t*s->center; + } + + virtual ~drawPath3() {} + + bool is3D() {return true;} + + void bounds(const double* t, bbox3& B) { + if(t != NULL) { + const path3 tg(camp::transformed(t,g)); + B.add(tg.min()); + B.add(tg.max()); + } else { + B.add(Min); + B.add(Max); + } + } + + void ratio(const double* t, pair &b, double (*m)(double, double), double, + bool &first) { + pair z; + if(t != NULL) { + const path3 tg(camp::transformed(t,g)); + z=tg.ratio(m); + } else z=g.ratio(m); + + if(first) { + b=z; + first=false; + } else b=pair(m(b.getx(),z.getx()),m(b.gety(),z.gety())); + } + + void meshinit() { + if(billboard) + centerIndex=centerindex(center); + } + + bool write(prcfile *out, unsigned int *, double, groupsmap&); + bool write(jsfile *out); + + void render(double, const triple&, const triple&, double, + bool remesh); + + drawElement *transformed(const double* t); +}; + +class drawNurbsPath3 : public drawElement { +protected: + size_t degree; + size_t n; + triple *controls; + double *weights; + double *knots; + prc::RGBAColour color; + bool invisible; + triple Min,Max; + +#ifdef HAVE_LIBGLM + GLfloat *Controls; + GLfloat *Knots; +#endif + +public: + drawNurbsPath3(const vm::array& g, const vm::array* knot, + const vm::array* weight, const pen& p, const string& key="") : + drawElement(key), color(rgba(p)), invisible(p.invisible()) { + size_t weightsize=checkArray(weight); + + string wrongsize="Inconsistent NURBS data"; + n=checkArray(&g); + + if(n == 0 || (weightsize != 0 && weightsize != n)) + reportError(wrongsize); + + controls=new(UseGC) triple[n]; + + size_t k=0; + for(size_t i=0; i < n; ++i) + controls[k++]=vm::read<triple>(g,i); + + if(weightsize > 0) { + size_t k=0; + weights=new(UseGC) double[n]; + for(size_t i=0; i < n; ++i) + weights[k++]=vm::read<double>(weight,i); + } else weights=NULL; + + size_t nknots=checkArray(knot); + + if(nknots <= n+1 || nknots > 2*n) + reportError(wrongsize); + + degree=nknots-n-1; + + run::copyArrayC(knots,knot,0,NoGC); + +#ifdef HAVE_LIBGLM + Controls=NULL; +#endif + } + + drawNurbsPath3(const double* t, const drawNurbsPath3 *s) : + drawElement(s->KEY), degree(s->degree), n(s->n), weights(s->weights), + knots(s->knots), color(s->color), invisible(s->invisible) { + controls=new(UseGC) triple[n]; + for(unsigned int i=0; i < n; ++i) + controls[i]=t*s->controls[i]; + +#ifdef HAVE_LIBGLM + Controls=NULL; +#endif + } + + bool is3D() {return true;} + + void bounds(const double* t, bbox3& b); + + virtual ~drawNurbsPath3() {} + + bool write(prcfile *out, unsigned int *, double, groupsmap&); + + void displacement(); + void ratio(const double* t, pair &b, double (*m)(double, double), double fuzz, + bool &first); + + void render(double size2, const triple& Min, const triple& Max, + double perspective, bool remesh); + + drawElement *transformed(const double* t); +}; + +// Draw a pixel. +class drawPixel : public drawElement { + triple v; + pen p; + prc::RGBAColour color; + double width; + bool invisible; + triple Min,Max; +public: +#ifdef HAVE_GL + Pixel R; +#endif + drawPixel(const triple& v, const pen& p, double width, const string& key="") + : drawElement(key), v(v), p(p), color(rgba(p)), width(width), + invisible(p.invisible()) {} + + void bounds(const double* t, bbox3& B) { + Min=Max=(t != NULL) ? t*v : v; + B.add(Min); + } + + void ratio(const double* t, pair &b, double (*m)(double, double), double, + bool &first) { + triple V=(t != NULL) ? t*v : v; + pair z=pair(xratio(V),yratio(V)); + + if(first) { + b=z; + first=false; + } else b=pair(m(b.getx(),z.getx()),m(b.gety(),z.gety())); + } + + void render(double size2, const triple& b, const triple& B, + double perspective, bool remesh); + + bool write(prcfile *out, unsigned int *, double, groupsmap&); + bool write(jsfile *out); + + drawElement *transformed(const double* t); +}; + +} + +#endif |