/* * © Copyright 2014 – Urheberrechtshinweis * Alle Rechte vorbehalten / All Rights Reserved * * Programmcode ist urheberrechtlich geschuetzt. * Das Urheberrecht liegt, soweit nicht ausdruecklich anders gekennzeichnet, bei Frank Ebner. * Keine Verwendung ohne explizite Genehmigung. * (vgl. § 106 ff UrhG / § 97 UrhG) */ #ifndef BVHDEBUG_H #define BVHDEBUG_H #include "BVH.h" #include #include #include #include #include #include #include #include #include #include "../BBox3.h" #include ///** adds some debug helpers to the BVH */ //template class BVHDebug : public BVH { //}; template class BVH3Debug : public BVH { using BVHNode = typename BVH::BVHNode; using BVHLeaf = typename BVH::BVHLeaf; public: void show(int maxPts = 1500, bool showLeafs = true) { std::stringstream out; static K::Gnuplot gp; K::GnuplotSplot plot; K::GnuplotSplotElementColorPoints pVol; plot.add(&pVol); //pVol.setColor(K::GnuplotColor::fromRGB(128,128,128)); K::GnuplotSplotElementPoints pElemPoints; plot.add(&pElemPoints); pElemPoints.setColor(K::GnuplotColor::fromRGB(0,0,255)); K::GnuplotSplotElementLines pElemLines; plot.add(&pElemLines); pElemLines.getStroke().setColor(K::GnuplotColor::fromRGB(0,0,255)); const int maxDepth = this->getDepth(); recurse(maxPts, showLeafs, 0, &this->root, pVol, pElemPoints, pElemLines); plot.getAxisCB().setRange(0, maxDepth); gp << "set view equal xyz\n"; gp.draw(plot); gp.flush(); } private: Point3 getRandomPoint(BoundingVolumeSphere3 sphere) { static std::minstd_rand gen; std::uniform_real_distribution dist(-1, +1); Point3 dir = Point3(dist(gen), dist(gen), dist(gen)).normalized() * sphere.radius; return sphere.center + dir; } void addLines(const Element& elem, K::GnuplotSplotElementLines& elemLines) { std::vector pts = Wrapper::getDebugLines(elem); for (size_t i = 0; i< pts.size(); i+=2) { const Point3 p1 = pts[i+0]; const Point3 p2 = pts[i+1]; K::GnuplotPoint3 gp1(p1.x, p1.y, p1.z); K::GnuplotPoint3 gp2(p2.x, p2.y, p2.z); elemLines.addSegment(gp1, gp2); } } int recurse(int maxPts, bool showLeafs, int curDepth, const BVHNode* node, K::GnuplotSplotElementColorPoints& vol, K::GnuplotSplotElementPoints& pElemPoints, K::GnuplotSplotElementLines& elemLines) { int resDepth = curDepth; for (BVHNode* sub : node->childNodes) { resDepth = recurse(maxPts, showLeafs, curDepth+1, sub, vol, pElemPoints, elemLines); } if (!node->isLeaf || showLeafs) { const int numPts = maxPts / (curDepth+1); for (int i = 0; i < numPts; ++i) { const Point3 p = getRandomPoint(node->boundingVolume); vol.add(K::GnuplotPoint3(p.x, p.y, p.z), curDepth); } } if (node->isLeaf) { BVHLeaf* leaf = (BVHLeaf*) node; std::vector verts = Wrapper::getVertices(leaf->element); for (const Point3 p : verts) { pElemPoints.add(K::GnuplotPoint3(p.x, p.y, p.z)); } addLines(leaf->element, elemLines); } return resDepth; } }; template class BVH2Debug : public BVH { using BVHNode = typename BVH::BVHNode; using BVHLeaf = typename BVH::BVHLeaf; public: void show(int maxPts = 1500, bool showLeafs = true) { std::stringstream out; static K::Gnuplot gp; K::GnuplotPlot plot; K::GnuplotPlotElementColorLines pVolLines; plot.add(&pVolLines); K::GnuplotPlotElementPoints pElemPoints; plot.add(&pElemPoints); pElemPoints.setColor(K::GnuplotColor::fromRGB(0,0,255)); K::GnuplotPlotElementLines pElemLines; plot.add(&pElemLines); pElemLines.getStroke().setColor(K::GnuplotColor::fromRGB(0,0,255)); const int maxDepth = this->getDepth(); recurse(maxDepth, showLeafs, 0, &this->root, plot, pVolLines, pElemPoints, pElemLines); plot.getObjects().reOrderByZIndex(); plot.getAxisCB().setRange(0, maxDepth); gp << "set size ratio -1\n"; gp.draw(plot); gp.flush(); } private: void addLines(const Element& elem, K::GnuplotPlotElementLines& elemLines) { std::vector pts = Wrapper::getDebugLines(elem); for (size_t i = 0; i< pts.size(); i+=2) { const Point2 p1 = pts[i+0]; const Point2 p2 = pts[i+1]; K::GnuplotPoint2 gp1(p1.x, p1.y); K::GnuplotPoint2 gp2(p2.x, p2.y); elemLines.addSegment(gp1, gp2); } } std::vector colors = { "#888800", "#444400", "#008888", "#004444", "#880088", "#440044", "#ee0000", "#880000", "#00ee00", "#008800", "#0000ee", "#000088", "#888800", "#444400", "#008888", "#004444", "#880088", "#440044", "#ee0000", "#880000", "#00ee00", "#008800", "#0000ee", "#000088", "#888800", "#444400", "#008888", "#004444", "#880088", "#440044", "#ee0000", "#880000", "#00ee00", "#008800", "#0000ee", "#000088" }; void showVolume(const BoundingVolumeCircle2& circle, int maxDepth, int curDepth, K::GnuplotPlot& plot, K::GnuplotPlotElementColorLines& pVolLines) { K::GnuplotObjectPolygon* poly = new K::GnuplotObjectPolygon(); for (int i = 0; i < 20; ++i) { const float f = M_PI*2 * i / 19; const Point2 p = circle.getPointAt(f); poly->add(K::GnuplotCoordinate2(p.x, p.y, K::GnuplotCoordinateSystem::FIRST)); poly->getFill().setColor(K::GnuplotColor::fromHexStr(colors[maxDepth-curDepth])); poly->getFill().setStyle(K::GnuplotFillStyle::SOLID); poly->setZIndex(curDepth); } plot.getObjects().add(poly); } void showVolume(const BoundingVolumeAABB2& _aabb, int maxDepth, int curDepth, K::GnuplotPlot& plot, K::GnuplotPlotElementColorLines& pVolLines) { BBox2 bbox2 = _aabb; bbox2.grow( (10-curDepth) / 100.0f ); // pVolLines.add(K::GnuplotPoint2(bbox2.getMin().x, bbox2.getMin().y), curDepth); // pVolLines.add(K::GnuplotPoint2(bbox2.getMax().x, bbox2.getMin().y), curDepth); // pVolLines.add(K::GnuplotPoint2(bbox2.getMax().x, bbox2.getMax().y), curDepth); // pVolLines.add(K::GnuplotPoint2(bbox2.getMin().x, bbox2.getMax().y), curDepth); // pVolLines.add(K::GnuplotPoint2(bbox2.getMin().x, bbox2.getMin().y), curDepth); // pVolLines.splitFace(); K::GnuplotObjectPolygon* poly = new K::GnuplotObjectPolygon(); poly->getStroke().setColor(K::GnuplotColor::fromHexStr(colors[maxDepth-curDepth])); //poly->getFill().setColor(K::GnuplotColor::fromHexStr(colors[maxDepth-curDepth])); //poly->getFill().setStyle(K::GnuplotFillStyle::SOLID); poly->add(K::GnuplotCoordinate2(bbox2.getMin().x, bbox2.getMin().y, K::GnuplotCoordinateSystem::FIRST)); poly->add(K::GnuplotCoordinate2(bbox2.getMax().x, bbox2.getMin().y, K::GnuplotCoordinateSystem::FIRST)); poly->add(K::GnuplotCoordinate2(bbox2.getMax().x, bbox2.getMax().y, K::GnuplotCoordinateSystem::FIRST)); poly->add(K::GnuplotCoordinate2(bbox2.getMin().x, bbox2.getMax().y, K::GnuplotCoordinateSystem::FIRST)); poly->close(); poly->setZIndex(curDepth); plot.getObjects().add(poly); } int recurse(int maxDepth, bool showLeafs, int curDepth, const BVHNode* node, K::GnuplotPlot& plot, K::GnuplotPlotElementColorLines& pVolLines, K::GnuplotPlotElementPoints& pElemPoints, K::GnuplotPlotElementLines& elemLines) { int resDepth = curDepth; for (BVHNode* sub : node->childNodes) { resDepth = recurse(maxDepth, showLeafs, curDepth+1, sub, plot, pVolLines, pElemPoints, elemLines); } if (!node->isLeaf || showLeafs) { if (node != &this->root) { //const int numPts = maxPts / (curDepth+1); showVolume(node->boundingVolume, maxDepth, curDepth, plot, pVolLines); } } if (node->isLeaf) { BVHLeaf* leaf = (BVHLeaf*) node; std::vector verts = Wrapper::getVertices(leaf->element); for (const Point2 p : verts) { pElemPoints.add(K::GnuplotPoint2(p.x, p.y)); } addLines(leaf->element, elemLines); } return resDepth; } }; #endif // BVHDEBUG_H