/***** * 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() { billboard=interaction == BILLBOARD; 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(p,0); invisible=Pen.invisible(); diffuse=rgba(Pen); emissive=rgba(vm::read(p,1)); specular=rgba(vm::read(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(abs3Doutfile *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(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(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(abs3Doutfile *out); drawElement *transformed(const double* t); }; } #endif