#include "jsfile.h" #include "settings.h" #include "glrender.h" #include "drawelement.h" using namespace settings; namespace camp { const string s="document.asy."; #ifndef HAVE_LIBGLM size_t materialIndex=0; #endif jsfile::jsfile() : finished(false), fileName("") { } jsfile::jsfile(string name) : finished(false), fileName(name) { open(name); } jsfile::~jsfile() { if (!finished) { finish(fileName); } } void jsfile::close() { if (!finished) { finish(fileName); } } void jsfile::copy(string name, bool header) { std::ifstream fin(locateFile(name).c_str()); string s; if(header) getline(fin,s); while(getline(fin,s)) out << s << newl; } void jsfile::header(string name) { out.open(name); out << "" << newl << newl; } void jsfile::meta(string name, bool svg) { out << "" << newl << newl << "" << newl << "" << stripExt(name) << "" << newl << newl << "" << newl; if(svg) out << ""; else out << ""; out << newl << "" << newl; if(svg) out << "" << newl; out << newl; } void jsfile::footer(string name) { out << newl << "" << newl << newl << "" << newl; out.flush(); if(verbose > 0) cout << "Wrote " << name << endl; } void jsfile::svgtohtml(string prefix) { string name=buildname(prefix,"html"); header(name); meta(name); out << "" << newl << newl; copy(locateFile(auxname(prefix,"svg")),true); footer(name); finished=true; } void jsfile::comment(string name) { #ifdef HAVE_LIBGLM out << "" << newl << newl; #endif } void jsfile::open(string name) { header(name); comment(name); meta(name,false); #ifdef HAVE_LIBGLM out.precision(getSetting("digits")); bool ibl=getSetting("ibl"); bool webgl2=ibl || getSetting("webgl2"); if(ibl) out << "" << newl; if(getSetting("offline")) { out << "" << newl; } else out << "("asygl") << "\">" << newl << "" << newl; out << newl << "" << newl << "" << newl << newl << "" << newl << "" << newl << ""; footer(name); #endif } void jsfile::addColor(const prc::RGBAColour& c) { out << "[" << c.R << "," << c.G << "," << c.B << "," << c.A << "]"; } void jsfile::addIndices(const uint32_t *I) { out << "[" << I[0] << "," << I[1] << "," << I[2] << "]"; } void jsfile::addRawPatch(triple const* controls, size_t n, const prc::RGBAColour *c, size_t nc) { out << "patch([" << newl; size_t last=n-1; for(size_t i=0; i < last; ++i) out << controls[i] << "," << newl; out << controls[last] << newl << "]," << drawElement::centerIndex << "," << materialIndex; if(c) { out << ",[" << newl; for(size_t i=0; i < nc; ++i) { addColor(c[i]); out << "," << newl; } out << "]"; } out << ");" << newl << newl; } void jsfile::addCurve(const triple& z0, const triple& c0, const triple& c1, const triple& z1) { out << "curve([" << newl; out << z0 << "," << newl << c0 << "," << newl << c1 << "," << newl << z1 << newl << "]," << drawElement::centerIndex << "," << materialIndex << ");" << newl << newl; } void jsfile::addCurve(const triple& z0, const triple& z1) { out << "curve([" << newl; out << z0 << "," << newl << z1 << newl << "]," << drawElement::centerIndex << "," << materialIndex << ");" << newl << newl; } void jsfile::addPixel(const triple& z0, double width) { out << "pixel(" << newl; out << z0 << "," << width << "," << newl << materialIndex << ");" << newl << newl; } #ifdef HAVE_LIBGLM void jsfile::addMaterial(Material const& material) { out << "material(" << newl << material << ");" << newl << newl; } #endif void jsfile::addTriangles(size_t nP, const triple* P, size_t nN, const triple* N, size_t nC, const prc::RGBAColour* C, size_t nI, const uint32_t (*PI)[3], const uint32_t (*NI)[3], const uint32_t (*CI)[3]) { for(size_t i=0; i < nP; ++i) out << "Positions.push(" << P[i] << ");" << newl; for(size_t i=0; i < nN; ++i) out << "Normals.push(" << N[i] << ");" << newl; for(size_t i=0; i < nC; ++i) { out << "Colors.push("; addColor(C[i]); out << ");" << newl; } for(size_t i=0; i < nI; ++i) { out << "Indices.push(["; const uint32_t *PIi=PI[i]; const uint32_t *NIi=NI[i]; bool keepNI=distinct(NIi,PIi); bool keepCI=nC && distinct(CI[i],PIi); addIndices(PIi); if(keepNI || keepCI) { out << ","; if(keepNI) addIndices(NIi); } if(keepCI) { out << ","; addIndices(CI[i]); } out << "]);" << newl; } out << "triangles(" << drawElement::centerIndex << "," << materialIndex << ");" << newl << newl; } void jsfile::addSphere(const triple& center, double radius) { out << "sphere(" << center << "," << radius << "," << drawElement::centerIndex << "," << materialIndex << ");" << newl << newl; } void jsfile::addHemisphere(const triple& center, double radius, const double& polar, const double& azimuth) { out << "sphere(" << center << "," << radius << "," << drawElement::centerIndex << "," << materialIndex << "," << newl << "[" << polar << "," << azimuth << "]"; out << ");" << newl << newl; } // core signifies whether to also draw a central line for better small-scale // rendering. void jsfile::addCylinder(const triple& center, double radius, double height, const double& polar, const double& azimuth, bool core) { out << "cylinder(" << center << "," << radius << "," << height << "," << drawElement::centerIndex << "," << materialIndex << "," << newl << "[" << polar << "," << azimuth << "]," << core << ");" << newl << newl; } void jsfile::addDisk(const triple& center, double radius, const double& polar, const double& azimuth) { out << "disk(" << center << "," << radius << "," << drawElement::centerIndex << "," << materialIndex << "," << newl << "[" << polar << "," << azimuth << "]" << ");" << newl << newl; } void jsfile::addTube(const triple *g, double width, bool core) { out << "tube([" << g[0] << "," << newl << g[1] << "," << newl << g[2] << "," << newl << g[3] << newl << "]," << width << "," << drawElement::centerIndex << "," << materialIndex << "," << core << ");" << newl << newl; } void jsfile::addPatch(triple const* controls, prc::RGBAColour const* c) { addRawPatch(controls,16,c,4); } void jsfile::addStraightPatch(triple const* controls, prc::RGBAColour const* c) { addRawPatch(controls,4,c,4); } void jsfile::addBezierTriangle(triple const* controls, prc::RGBAColour const* c) { addRawPatch(controls,10,c,3); } void jsfile::addStraightBezierTriangle(triple const* controls, prc::RGBAColour const* c) { addRawPatch(controls,3,c,3); } }