diff options
author | Norbert Preining <norbert@preining.info> | 2021-12-28 03:01:00 +0000 |
---|---|---|
committer | Norbert Preining <norbert@preining.info> | 2021-12-28 03:01:00 +0000 |
commit | ecdf859b6ce481abfd530425dcf6f0f764bd0001 (patch) | |
tree | 13bc161dc046876ac6c92fce5f9f5034ba9aa573 /graphics/asymptote/v3dfile.cc | |
parent | 790995b7e79697514364450bf9c04f1b8d500838 (diff) |
CTAN sync 202112280300
Diffstat (limited to 'graphics/asymptote/v3dfile.cc')
-rw-r--r-- | graphics/asymptote/v3dfile.cc | 353 |
1 files changed, 353 insertions, 0 deletions
diff --git a/graphics/asymptote/v3dfile.cc b/graphics/asymptote/v3dfile.cc new file mode 100644 index 0000000000..d8eebab50c --- /dev/null +++ b/graphics/asymptote/v3dfile.cc @@ -0,0 +1,353 @@ +/* + * v3dfile.cc + * V3D Export class + * + * Supakorn "Jamie" Rassameemasmuang <jamievlin@outlook.com> and + * John C. Bowman + */ + +#include "v3dfile.h" + +#ifdef HAVE_RPC_RPC_H + +#include "drawelement.h" +#include "makeUnique.h" + +namespace camp +{ + +using settings::getSetting; + +void v3dfile::writeInit() +{ + uint32_t doubleprecision = !singleprecision; + getXDRFile() << v3dVersion << doubleprecision; + addHeaders(); + + camp::clearCenters(); + camp::clearMaterials(); +} + +void v3dfile::addHeaders() +{ + getXDRFile() << v3dtypes::header; + std::vector<std::unique_ptr<AHeader>> headers; + + headers.emplace_back(make_unique<Uint32Header>(v3dheadertypes::canvasWidth, gl::fullWidth)); + headers.emplace_back(make_unique<Uint32Header>(v3dheadertypes::canvasHeight, gl::fullHeight)); + headers.emplace_back(make_unique<Uint32Header>(v3dheadertypes::absolute, getSetting<bool>("absolute"))); + headers.emplace_back(make_unique<TripleHeader>(v3dheadertypes::minBound, triple(gl::xmin, gl::ymin, gl::zmin))); + headers.emplace_back(make_unique<TripleHeader>(v3dheadertypes::maxBound, triple(gl::xmax, gl::ymax, gl::zmax))); + headers.emplace_back(make_unique<Uint32Header>(v3dheadertypes::orthographic, gl::orthographic)); + headers.emplace_back(make_unique<DoubleHeader>(v3dheadertypes::angleOfView, gl::Angle)); + headers.emplace_back(make_unique<DoubleHeader>(v3dheadertypes::initialZoom, gl::Zoom0)); + if(gl::Shift != pair(0.0,0.0)) + headers.emplace_back(make_unique<PairHeader>(v3dheadertypes::viewportShift, gl::Shift*gl::Zoom0)); + headers.emplace_back(make_unique<PairHeader>(v3dheadertypes::viewportMargin, gl::Margin)); + + for(size_t i=0; i < gl::nlights; ++i) { + size_t i4=4*i; + headers.emplace_back(make_unique<LightHeader>( + gl::Lights[i], + prc::RGBAColour(gl::Diffuse[i4], gl::Diffuse[i4+1], gl::Diffuse[i4+2], 1.0) + )); + } + + headers.emplace_back(make_unique<RGBAHeader>( + v3dheadertypes::background, + prc::RGBAColour(gl::Background[0],gl::Background[1],gl::Background[2],gl::Background[3]))); + + headers.emplace_back(make_unique<DoubleHeader>(v3dheadertypes::zoomFactor, getSetting<double>("zoomfactor"))); + headers.emplace_back(make_unique<DoubleHeader>( + v3dheadertypes::zoomPinchFactor, getSetting<double>("zoomPinchFactor"))); + headers.emplace_back(make_unique<DoubleHeader>( + v3dheadertypes::zoomPinchCap, getSetting<double>("zoomPinchCap"))); + headers.emplace_back(make_unique<DoubleHeader>(v3dheadertypes::zoomStep, getSetting<double>("zoomstep"))); + headers.emplace_back(make_unique<DoubleHeader>( + v3dheadertypes::shiftHoldDistance, getSetting<double>("shiftHoldDistance"))); + headers.emplace_back(make_unique<DoubleHeader>( + v3dheadertypes::shiftWaitTime, getSetting<double>("shiftWaitTime"))); + headers.emplace_back(make_unique<DoubleHeader>( + v3dheadertypes::vibrateTime, getSetting<double>("vibrateTime"))); + + getXDRFile() << (uint32_t) headers.size(); + for(const auto& header : headers) { + getXDRFile() << header->ty << header->getWordSize(singleprecision); + header->writeContent(getXDRFile()); + } +} + +void v3dfile::addCenters() +{ + getXDRFile() << v3dtypes::centers; + size_t nelem=drawElement::centers.size(); + getXDRFile() << (uint32_t) nelem; + if(nelem > 0) + addTriples(drawElement::centers.data(), nelem); +} + +void v3dfile::addTriples(triple const* triples, size_t n) +{ + for(size_t i=0; i < n; ++i) + getXDRFile() << triples[i]; +} + +void v3dfile::addColors(prc::RGBAColour const* col, size_t nc) +{ + for(size_t i=0; i < nc; ++i) + getXDRFile() << col[i]; +} + + +void v3dfile::addPatch(triple const* controls, triple const& Min, + triple const& Max, prc::RGBAColour const* c) +{ + getXDRFile() << (c ? v3dtypes::bezierPatchColor : v3dtypes::bezierPatch); + addTriples(controls,16); + addCenterIndexMat(); + + if(c) + addColors(c,4); +} + +void v3dfile::addStraightPatch(triple const* controls, triple const& Min, + triple const& Max, prc::RGBAColour const* c) +{ + getXDRFile() << (c ? v3dtypes::quadColor : v3dtypes::quad); + addTriples(controls,4); + addCenterIndexMat(); + + if(c) + addColors(c,4); +} + +void v3dfile::addBezierTriangle(triple const* controls, triple const& Min, + triple const& Max, prc::RGBAColour const* c) +{ + getXDRFile() << (c ? v3dtypes::bezierTriangleColor : v3dtypes::bezierTriangle); + addTriples(controls,10); + addCenterIndexMat(); + + if(c) + addColors(c,3); +} + +void v3dfile::addStraightBezierTriangle(triple const* controls, triple const& Min, + triple const& Max, prc::RGBAColour const* c) +{ + getXDRFile() << (c ? v3dtypes::triangleColor : v3dtypes::triangle); + addTriples(controls,3); + addCenterIndexMat(); + + if(c) + addColors(c,3); +} + +void v3dfile::addMaterial(Material const& mat) +{ + getXDRFile() << v3dtypes::material; + addvec4(mat.diffuse); + addvec4(mat.emissive); + addvec4(mat.specular); + glm::vec4 vec=mat.parameters; + getXDRFile() << static_cast<float>(vec.x) << static_cast<float>(vec.y) + << static_cast<float>(vec.z); +} + +void v3dfile::addCenterIndexMat() +{ + getXDRFile() << (uint32_t) drawElement::centerIndex << (uint32_t) materialIndex; +} + +void v3dfile::addvec4(glm::vec4 const& vec) +{ + getXDRFile() << static_cast<float>(vec.x) << static_cast<float>(vec.y) + << static_cast<float>(vec.z) << static_cast<float>(vec.w); +} + +void v3dfile::addHemisphere(triple const& center, double radius, double const& polar, double const& azimuth) +{ + getXDRFile() << v3dtypes::halfSphere << center << radius; + addCenterIndexMat(); + getXDRFile() << polar << azimuth; +} + +void v3dfile::addSphere(triple const& center, double radius) +{ + getXDRFile() << v3dtypes::sphere << center << radius; + addCenterIndexMat(); +} + +void +v3dfile::addCylinder(triple const& center, double radius, double height, double const& polar, double const& azimuth, + bool core) +{ + getXDRFile() << v3dtypes::cylinder << center << radius << height; + addCenterIndexMat(); + getXDRFile() << polar << azimuth << core; +} + +void v3dfile::addDisk(triple const& center, double radius, double const& polar, double const& azimuth) +{ + getXDRFile() << v3dtypes::disk << center << radius; + addCenterIndexMat(); + getXDRFile() << polar << azimuth; +} + +void v3dfile::addTube(triple const* g, double width, triple const& Min, triple const& Max, bool core) +{ + getXDRFile() << v3dtypes::tube; + for(int i=0; i < 4; ++i) + getXDRFile() << g[i]; + getXDRFile() << width; + addCenterIndexMat(); + getXDRFile() << core; +} + +void v3dfile::addTriangles(size_t nP, triple const* P, size_t nN, triple const* N, size_t nC, prc::RGBAColour const* C, + size_t nI, uint32_t const (* PI)[3], uint32_t const (* NI)[3], uint32_t const (* CI)[3], + triple const& Min, triple const& Max) +{ + getXDRFile() << v3dtypes::triangles; + getXDRFile() << (uint32_t) nI; + + getXDRFile() << (uint32_t) nP; + addTriples(P,nP); + + getXDRFile() << (uint32_t) nN; + addTriples(N,nN); + + bool explicitNI=true; + for(size_t i=0; i < nI; ++i) { + const uint32_t *PIi=PI[i]; + const uint32_t *NIi=NI[i]; + if(!distinct(NIi,PIi)) { + explicitNI=false; + break; + } + } + getXDRFile() << (uint32_t) explicitNI; + + getXDRFile() << (uint32_t) nC; + bool explicitCI=true; + if(nC) { + addColors(C,nC); + for(size_t i=0; i < nI; ++i) { + const uint32_t *PIi=PI[i]; + const uint32_t *CIi=CI[i]; + if(!distinct(CIi,PIi)) { + explicitNI=false; + break; + } + } + getXDRFile() << (uint32_t) explicitCI; + } + + for(size_t i=0; i < nI; ++i) { + const uint32_t *PIi=PI[i]; + const uint32_t *NIi=NI[i]; + addIndices(PIi); + if(explicitNI) + addIndices(NIi); + if(nC) { + const uint32_t *CIi=CI[i]; + if(explicitCI) + addIndices(CIi); + } + } + + addCenterIndexMat(); +} + +void v3dfile::addIndices(uint32_t const* v) +{ + getXDRFile() << v[0] << v[1] << v[2]; +} + +void v3dfile::addCurve(triple const& z0, triple const& c0, triple const& c1, triple const& z1, triple const& Min, + triple const& Max) +{ + getXDRFile() << v3dtypes::curve << z0 << c0 << c1 << z1; + addCenterIndexMat(); + +} + +void v3dfile::addCurve(triple const& z0, triple const& z1, triple const& Min, triple const& Max) +{ + getXDRFile() << v3dtypes::line << z0 << z1; + addCenterIndexMat(); +} + +void v3dfile::addPixel(triple const& z0, double width, triple const& Min, triple const& Max) +{ + getXDRFile() << v3dtypes::pixel << z0 << width; + getXDRFile() << (uint32_t) materialIndex; +} + +void v3dfile::finalize() +{ + if(!finalized) { + addCenters(); + finalized=true; + } +} + +// gzv3dfile + +xdr::oxstream& gzv3dfile::getXDRFile() +{ + return memxdrfile; +} + +gzv3dfile::gzv3dfile(string const& name, bool singleprecision): v3dfile(singleprecision), memxdrfile(singleprecision), name(name), destroyed(false) +{ + writeInit(); +} + +gzv3dfile::~gzv3dfile() +{ + close(); +} + +void gzv3dfile::close() +{ + if(!destroyed) { + finalize(); + memxdrfile.close(); + gzFile file=gzopen(name.c_str(), "wb9"); + gzwrite(file,data(),length()); + gzclose(file); + if(settings::verbose > 0) + cout << "Wrote " << name << endl; + destroyed=true; + } +} + +char const* gzv3dfile::data() const +{ + return memxdrfile.stream(); +} + +size_t const& gzv3dfile::length() const +{ + return memxdrfile.getLength(); +} + +uint32_t LightHeader::getWordSize(bool singleprecision) const +{ + return (singleprecision ? 1 : 2)*3+3; +} + +void LightHeader::writeContent(xdr::oxstream& ox) const +{ + ox << direction << (float) color.R << (float) color.G << (float) color.B; +} + +LightHeader::LightHeader(triple const& direction, prc::RGBAColour const& color) : + AHeader(v3dheadertypes::light), direction(direction), color(color) +{ +} + +} //namespace camp + +#endif |