Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/freestyle/intern/view_map/SphericalGrid.h')
-rw-r--r--source/blender/freestyle/intern/view_map/SphericalGrid.h571
1 files changed, 286 insertions, 285 deletions
diff --git a/source/blender/freestyle/intern/view_map/SphericalGrid.h b/source/blender/freestyle/intern/view_map/SphericalGrid.h
index 19c2461ce01..ae00c270c1d 100644
--- a/source/blender/freestyle/intern/view_map/SphericalGrid.h
+++ b/source/blender/freestyle/intern/view_map/SphericalGrid.h
@@ -44,388 +44,389 @@
#include "BKE_global.h"
#ifdef WITH_CXX_GUARDEDALLOC
-#include "MEM_guardedalloc.h"
+# include "MEM_guardedalloc.h"
#endif
namespace Freestyle {
-class SphericalGrid
-{
-public:
- // Helper classes
- struct OccluderData
- {
- explicit OccluderData (OccluderSource& source, Polygon3r& p);
- Polygon3r poly;
- Polygon3r cameraSpacePolygon;
- real shallowest, deepest;
- // N.B. We could, of course, store face in poly's userdata member, like the old ViewMapBuilder code does.
- // However, code comments make it clear that userdata is deprecated, so we avoid the temptation to save
- // 4 or 8 bytes.
- WFace *face;
+class SphericalGrid {
+ public:
+ // Helper classes
+ struct OccluderData {
+ explicit OccluderData(OccluderSource &source, Polygon3r &p);
+ Polygon3r poly;
+ Polygon3r cameraSpacePolygon;
+ real shallowest, deepest;
+ // N.B. We could, of course, store face in poly's userdata member, like the old ViewMapBuilder code does.
+ // However, code comments make it clear that userdata is deprecated, so we avoid the temptation to save
+ // 4 or 8 bytes.
+ WFace *face;
#ifdef WITH_CXX_GUARDEDALLOC
- MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:SphericalGrid:OccluderData")
+ MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:SphericalGrid:OccluderData")
#endif
- };
-
-private:
- struct Cell
- {
- // Can't store Cell in a vector without copy and assign
- //Cell(const Cell& other);
- //Cell& operator=(const Cell& other);
-
- explicit Cell();
- ~Cell();
-
- static bool compareOccludersByShallowestPoint(const OccluderData *a, const OccluderData *b);
-
- void setDimensions(real x, real y, real sizeX, real sizeY);
- void checkAndInsert(OccluderSource& source, Polygon3r& poly, OccluderData*& occluder);
- void indexPolygons();
-
- real boundary[4];
- //deque<OccluderData*> faces;
- vector<OccluderData*> faces;
- };
-
-public:
- /*! Iterator needs to allow the user to avoid full 3D comparison in two cases:
- *
- * (1) Where (*current)->deepest < target[2], where the occluder is unambiguously in front of the target point.
- *
- * (2) Where (*current)->shallowest > target[2], where the occluder is unambiguously in back of the target point.
- *
- * In addition, when used by OptimizedFindOccludee, Iterator should stop iterating as soon as it has an occludee
- * candidate and (*current)->shallowest > candidate[2], because at that point forward no new occluder could
- * possibly be a better occludee.
- */
-
- class Iterator
- {
- public:
- // epsilon is not used in this class, but other grids with the same interface may need an epsilon
- explicit Iterator(SphericalGrid& grid, Vec3r& center, real epsilon = 1.0e-06);
- ~Iterator();
- void initBeforeTarget();
- void initAfterTarget();
- void nextOccluder();
- void nextOccludee();
- bool validBeforeTarget();
- bool validAfterTarget();
- WFace *getWFace() const;
- Polygon3r *getCameraSpacePolygon();
- void reportDepth(Vec3r origin, Vec3r u, real t);
- private:
- bool testOccluder(bool wantOccludee);
- void markCurrentOccludeeCandidate(real depth);
-
- Cell *_cell;
- Vec3r _target;
- bool _foundOccludee;
- real _occludeeDepth;
- //deque<OccluderData*>::iterator _current, _occludeeCandidate;
- vector<OccluderData*>::iterator _current, _occludeeCandidate;
+ };
+
+ private:
+ struct Cell {
+ // Can't store Cell in a vector without copy and assign
+ //Cell(const Cell& other);
+ //Cell& operator=(const Cell& other);
+
+ explicit Cell();
+ ~Cell();
+
+ static bool compareOccludersByShallowestPoint(const OccluderData *a, const OccluderData *b);
+
+ void setDimensions(real x, real y, real sizeX, real sizeY);
+ void checkAndInsert(OccluderSource &source, Polygon3r &poly, OccluderData *&occluder);
+ void indexPolygons();
+
+ real boundary[4];
+ //deque<OccluderData*> faces;
+ vector<OccluderData *> faces;
+ };
+
+ public:
+ /*! Iterator needs to allow the user to avoid full 3D comparison in two cases:
+ *
+ * (1) Where (*current)->deepest < target[2], where the occluder is unambiguously in front of the target point.
+ *
+ * (2) Where (*current)->shallowest > target[2], where the occluder is unambiguously in back of the target point.
+ *
+ * In addition, when used by OptimizedFindOccludee, Iterator should stop iterating as soon as it has an occludee
+ * candidate and (*current)->shallowest > candidate[2], because at that point forward no new occluder could
+ * possibly be a better occludee.
+ */
+
+ class Iterator {
+ public:
+ // epsilon is not used in this class, but other grids with the same interface may need an epsilon
+ explicit Iterator(SphericalGrid &grid, Vec3r &center, real epsilon = 1.0e-06);
+ ~Iterator();
+ void initBeforeTarget();
+ void initAfterTarget();
+ void nextOccluder();
+ void nextOccludee();
+ bool validBeforeTarget();
+ bool validAfterTarget();
+ WFace *getWFace() const;
+ Polygon3r *getCameraSpacePolygon();
+ void reportDepth(Vec3r origin, Vec3r u, real t);
+
+ private:
+ bool testOccluder(bool wantOccludee);
+ void markCurrentOccludeeCandidate(real depth);
+
+ Cell *_cell;
+ Vec3r _target;
+ bool _foundOccludee;
+ real _occludeeDepth;
+ //deque<OccluderData*>::iterator _current, _occludeeCandidate;
+ vector<OccluderData *>::iterator _current, _occludeeCandidate;
#ifdef WITH_CXX_GUARDEDALLOC
- MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:SphericalGrid:Iterator")
+ MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:SphericalGrid:Iterator")
#endif
-
- };
-
- class Transform : public GridHelpers::Transform
- {
- public:
- explicit Transform();
- explicit Transform(Transform& other);
- Vec3r operator()(const Vec3r& point) const;
- static Vec3r sphericalProjection(const Vec3r& M);
- };
-
-private:
- // Prevent implicit copies and assignments.
- SphericalGrid(const SphericalGrid& other);
- SphericalGrid& operator=(const SphericalGrid& other);
-
-public:
- explicit SphericalGrid(OccluderSource& source, GridDensityProvider& density, ViewMap *viewMap,
- Vec3r& viewpoint, bool enableQI);
- virtual ~SphericalGrid();
-
- // Generate Cell structure
- void assignCells(OccluderSource& source, GridDensityProvider& density, ViewMap *viewMap);
- // Fill Cells
- void distributePolygons(OccluderSource& source);
- // Insert one polygon into each matching cell, return true if any cell consumes the polygon
- bool insertOccluder(OccluderSource& source, OccluderData*& occluder);
- // Sort occluders in each cell
- void reorganizeCells();
-
- Cell *findCell(const Vec3r& point);
-
- // Accessors:
- bool orthographicProjection() const;
- const Vec3r& viewpoint() const;
- bool enableQI() const;
-
-private:
- void getCellCoordinates(const Vec3r& point, unsigned& x, unsigned& y);
-
- typedef PointerSequence<vector<Cell*>, Cell*> cellContainer;
- //typedef PointerSequence<deque<OccluderData*>, OccluderData*> occluderContainer;
- typedef PointerSequence<vector<OccluderData*>, OccluderData*> occluderContainer;
- unsigned _cellsX, _cellsY;
- float _cellSize;
- float _cellOrigin[2];
- cellContainer _cells;
- occluderContainer _faces;
- Vec3r _viewpoint;
- bool _enableQI;
+ };
+
+ class Transform : public GridHelpers::Transform {
+ public:
+ explicit Transform();
+ explicit Transform(Transform &other);
+ Vec3r operator()(const Vec3r &point) const;
+ static Vec3r sphericalProjection(const Vec3r &M);
+ };
+
+ private:
+ // Prevent implicit copies and assignments.
+ SphericalGrid(const SphericalGrid &other);
+ SphericalGrid &operator=(const SphericalGrid &other);
+
+ public:
+ explicit SphericalGrid(OccluderSource &source,
+ GridDensityProvider &density,
+ ViewMap *viewMap,
+ Vec3r &viewpoint,
+ bool enableQI);
+ virtual ~SphericalGrid();
+
+ // Generate Cell structure
+ void assignCells(OccluderSource &source, GridDensityProvider &density, ViewMap *viewMap);
+ // Fill Cells
+ void distributePolygons(OccluderSource &source);
+ // Insert one polygon into each matching cell, return true if any cell consumes the polygon
+ bool insertOccluder(OccluderSource &source, OccluderData *&occluder);
+ // Sort occluders in each cell
+ void reorganizeCells();
+
+ Cell *findCell(const Vec3r &point);
+
+ // Accessors:
+ bool orthographicProjection() const;
+ const Vec3r &viewpoint() const;
+ bool enableQI() const;
+
+ private:
+ void getCellCoordinates(const Vec3r &point, unsigned &x, unsigned &y);
+
+ typedef PointerSequence<vector<Cell *>, Cell *> cellContainer;
+ //typedef PointerSequence<deque<OccluderData*>, OccluderData*> occluderContainer;
+ typedef PointerSequence<vector<OccluderData *>, OccluderData *> occluderContainer;
+ unsigned _cellsX, _cellsY;
+ float _cellSize;
+ float _cellOrigin[2];
+ cellContainer _cells;
+ occluderContainer _faces;
+ Vec3r _viewpoint;
+ bool _enableQI;
#ifdef WITH_CXX_GUARDEDALLOC
- MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:SphericalGrid")
+ MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:SphericalGrid")
#endif
};
inline void SphericalGrid::Iterator::initBeforeTarget()
{
- _current = _cell->faces.begin();
- while (_current != _cell->faces.end() && !testOccluder(false)) {
- ++_current;
- }
+ _current = _cell->faces.begin();
+ while (_current != _cell->faces.end() && !testOccluder(false)) {
+ ++_current;
+ }
}
inline void SphericalGrid::Iterator::initAfterTarget()
{
- if (_foundOccludee) {
+ if (_foundOccludee) {
#if SPHERICAL_GRID_LOGGING
- if (G.debug & G_DEBUG_FREESTYLE) {
- std::cout << "\tStarting occludee search from occludeeCandidate at depth " <<
- _occludeeDepth << std::endl;
- }
+ if (G.debug & G_DEBUG_FREESTYLE) {
+ std::cout << "\tStarting occludee search from occludeeCandidate at depth " << _occludeeDepth
+ << std::endl;
+ }
#endif
- _current = _occludeeCandidate;
- return;
- }
+ _current = _occludeeCandidate;
+ return;
+ }
#if SPHERICAL_GRID_LOGGING
- if (G.debug & G_DEBUG_FREESTYLE) {
- std::cout << "\tStarting occludee search from current position" << std::endl;
- }
+ if (G.debug & G_DEBUG_FREESTYLE) {
+ std::cout << "\tStarting occludee search from current position" << std::endl;
+ }
#endif
- while (_current != _cell->faces.end() && !testOccluder(true)) {
- ++_current;
- }
+ while (_current != _cell->faces.end() && !testOccluder(true)) {
+ ++_current;
+ }
}
inline bool SphericalGrid::Iterator::testOccluder(bool wantOccludee)
{
- // End-of-list is not even a valid iterator position
- if (_current == _cell->faces.end()) {
- // Returning true seems strange, but it will break us out of whatever loop is calling testOccluder, and
- // _current=_cell->face.end() will make the calling routine give up.
- return true;
- }
+ // End-of-list is not even a valid iterator position
+ if (_current == _cell->faces.end()) {
+ // Returning true seems strange, but it will break us out of whatever loop is calling testOccluder, and
+ // _current=_cell->face.end() will make the calling routine give up.
+ return true;
+ }
#if SPHERICAL_GRID_LOGGING
- if (G.debug & G_DEBUG_FREESTYLE) {
- std::cout << "\tTesting occluder " << (*_current)->poly.getVertices()[0];
- for (unsigned int i = 1; i < (*_current)->poly.getVertices().size(); ++i) {
- std::cout << ", " << (*_current)->poly.getVertices()[i];
- }
- std::cout << " from shape " << (*_current)->face->GetVertex(0)->shape()->GetId() << std::endl;
- }
+ if (G.debug & G_DEBUG_FREESTYLE) {
+ std::cout << "\tTesting occluder " << (*_current)->poly.getVertices()[0];
+ for (unsigned int i = 1; i < (*_current)->poly.getVertices().size(); ++i) {
+ std::cout << ", " << (*_current)->poly.getVertices()[i];
+ }
+ std::cout << " from shape " << (*_current)->face->GetVertex(0)->shape()->GetId() << std::endl;
+ }
#endif
- // If we have an occluder candidate and we are unambiguously after it, abort
- if (_foundOccludee && (*_current)->shallowest > _occludeeDepth) {
+ // If we have an occluder candidate and we are unambiguously after it, abort
+ if (_foundOccludee && (*_current)->shallowest > _occludeeDepth) {
#if SPHERICAL_GRID_LOGGING
- if (G.debug & G_DEBUG_FREESTYLE) {
- std::cout << "\t\tAborting: shallowest > occludeeCandidate->deepest" << std::endl;
- }
+ if (G.debug & G_DEBUG_FREESTYLE) {
+ std::cout << "\t\tAborting: shallowest > occludeeCandidate->deepest" << std::endl;
+ }
#endif
- _current = _cell->faces.end();
+ _current = _cell->faces.end();
- // See note above
- return true;
- }
+ // See note above
+ return true;
+ }
- // Specific continue or stop conditions when searching for each type
- if (wantOccludee) {
- if ((*_current)->deepest < _target[2]) {
+ // Specific continue or stop conditions when searching for each type
+ if (wantOccludee) {
+ if ((*_current)->deepest < _target[2]) {
#if SPHERICAL_GRID_LOGGING
- if (G.debug & G_DEBUG_FREESTYLE) {
- std::cout << "\t\tSkipping: shallower than target while looking for occludee" << std::endl;
- }
+ if (G.debug & G_DEBUG_FREESTYLE) {
+ std::cout << "\t\tSkipping: shallower than target while looking for occludee" << std::endl;
+ }
#endif
- return false;
- }
- }
- else {
- if ((*_current)->shallowest > _target[2]) {
+ return false;
+ }
+ }
+ else {
+ if ((*_current)->shallowest > _target[2]) {
#if SPHERICAL_GRID_LOGGING
- if (G.debug & G_DEBUG_FREESTYLE) {
- std::cout << "\t\tStopping: deeper than target while looking for occluder" << std::endl;
- }
+ if (G.debug & G_DEBUG_FREESTYLE) {
+ std::cout << "\t\tStopping: deeper than target while looking for occluder" << std::endl;
+ }
#endif
- return true;
- }
- }
+ return true;
+ }
+ }
- // Depthwise, this is a valid occluder.
+ // Depthwise, this is a valid occluder.
- // Check to see if target is in the 2D bounding box
- Vec3r bbMin, bbMax;
- (*_current)->poly.getBBox(bbMin, bbMax);
- if (_target[0] < bbMin[0] || _target[0] > bbMax[0] || _target[1] < bbMin[1] || _target[1] > bbMax[1]) {
+ // Check to see if target is in the 2D bounding box
+ Vec3r bbMin, bbMax;
+ (*_current)->poly.getBBox(bbMin, bbMax);
+ if (_target[0] < bbMin[0] || _target[0] > bbMax[0] || _target[1] < bbMin[1] ||
+ _target[1] > bbMax[1]) {
#if SPHERICAL_GRID_LOGGING
- if (G.debug & G_DEBUG_FREESTYLE) {
- std::cout << "\t\tSkipping: bounding box violation" << std::endl;
- }
+ if (G.debug & G_DEBUG_FREESTYLE) {
+ std::cout << "\t\tSkipping: bounding box violation" << std::endl;
+ }
#endif
- return false;
- }
+ return false;
+ }
- // We've done all the corner cutting we can. Let the caller work out whether or not the geometry is correct.
- return true;
+ // We've done all the corner cutting we can. Let the caller work out whether or not the geometry is correct.
+ return true;
}
inline void SphericalGrid::Iterator::reportDepth(Vec3r origin, Vec3r u, real t)
{
- // The reported depth is the length of a ray in camera space. We need to convert it into the distance from viewpoint
- // If origin is the viewpoint, depth == t. A future optimization could allow the caller to tell us if origin is
- // viewponit or target, at the cost of changing the OptimizedGrid API.
- real depth = (origin + u * t).norm();
+ // The reported depth is the length of a ray in camera space. We need to convert it into the distance from viewpoint
+ // If origin is the viewpoint, depth == t. A future optimization could allow the caller to tell us if origin is
+ // viewponit or target, at the cost of changing the OptimizedGrid API.
+ real depth = (origin + u * t).norm();
#if SPHERICAL_GRID_LOGGING
- if (G.debug & G_DEBUG_FREESTYLE) {
- std::cout << "\t\tReporting depth of occluder/ee: " << depth;
- }
+ if (G.debug & G_DEBUG_FREESTYLE) {
+ std::cout << "\t\tReporting depth of occluder/ee: " << depth;
+ }
#endif
- if (depth > _target[2]) {
+ if (depth > _target[2]) {
#if SPHERICAL_GRID_LOGGING
- if (G.debug & G_DEBUG_FREESTYLE) {
- std::cout << " is deeper than target" << std::endl;
- }
+ if (G.debug & G_DEBUG_FREESTYLE) {
+ std::cout << " is deeper than target" << std::endl;
+ }
#endif
- // If the current occluder is the best occludee so far, save it.
- if (! _foundOccludee || _occludeeDepth > depth) {
- markCurrentOccludeeCandidate(depth);
- }
- }
- else {
+ // If the current occluder is the best occludee so far, save it.
+ if (!_foundOccludee || _occludeeDepth > depth) {
+ markCurrentOccludeeCandidate(depth);
+ }
+ }
+ else {
#if SPHERICAL_GRID_LOGGING
- if (G.debug & G_DEBUG_FREESTYLE) {
- std::cout << std::endl;
- }
+ if (G.debug & G_DEBUG_FREESTYLE) {
+ std::cout << std::endl;
+ }
#endif
- }
+ }
}
inline void SphericalGrid::Iterator::nextOccluder()
{
- if (_current != _cell->faces.end()) {
- do {
- ++_current;
- } while (_current != _cell->faces.end() && !testOccluder(false));
- }
+ if (_current != _cell->faces.end()) {
+ do {
+ ++_current;
+ } while (_current != _cell->faces.end() && !testOccluder(false));
+ }
}
inline void SphericalGrid::Iterator::nextOccludee()
{
- if (_current != _cell->faces.end()) {
- do {
- ++_current;
- } while (_current != _cell->faces.end() && !testOccluder(true));
- }
+ if (_current != _cell->faces.end()) {
+ do {
+ ++_current;
+ } while (_current != _cell->faces.end() && !testOccluder(true));
+ }
}
inline bool SphericalGrid::Iterator::validBeforeTarget()
{
- return _current != _cell->faces.end() && (*_current)->shallowest <= _target[2];
+ return _current != _cell->faces.end() && (*_current)->shallowest <= _target[2];
}
inline bool SphericalGrid::Iterator::validAfterTarget()
{
- return _current != _cell->faces.end();
+ return _current != _cell->faces.end();
}
inline void SphericalGrid::Iterator::markCurrentOccludeeCandidate(real depth)
{
#if SPHERICAL_GRID_LOGGING
- if (G.debug & G_DEBUG_FREESTYLE) {
- std::cout << "\t\tFound occludeeCandidate at depth " << depth << std::endl;
- }
+ if (G.debug & G_DEBUG_FREESTYLE) {
+ std::cout << "\t\tFound occludeeCandidate at depth " << depth << std::endl;
+ }
#endif
- _occludeeCandidate = _current;
- _occludeeDepth = depth;
- _foundOccludee = true;
+ _occludeeCandidate = _current;
+ _occludeeDepth = depth;
+ _foundOccludee = true;
}
inline WFace *SphericalGrid::Iterator::getWFace() const
{
- return (*_current)->face;
+ return (*_current)->face;
}
inline Polygon3r *SphericalGrid::Iterator::getCameraSpacePolygon()
{
- return &((*_current)->cameraSpacePolygon);
+ return &((*_current)->cameraSpacePolygon);
}
-inline SphericalGrid::OccluderData::OccluderData (OccluderSource& source, Polygon3r& p)
-: poly(p), cameraSpacePolygon(source.getCameraSpacePolygon()), face(source.getWFace())
+inline SphericalGrid::OccluderData::OccluderData(OccluderSource &source, Polygon3r &p)
+ : poly(p), cameraSpacePolygon(source.getCameraSpacePolygon()), face(source.getWFace())
{
- const Vec3r viewpoint(0, 0, 0);
- // Get the point on the camera-space polygon that is closest to the viewpoint
- // shallowest is the distance from the viewpoint to that point
- shallowest = GridHelpers::distancePointToPolygon(viewpoint, cameraSpacePolygon);
-
- // Get the point on the camera-space polygon that is furthest from the viewpoint
- // deepest is the distance from the viewpoint to that point
- deepest = cameraSpacePolygon.getVertices()[2].norm();
- for (unsigned int i = 0; i < 2; ++i) {
- real t = cameraSpacePolygon.getVertices()[i].norm();
- if (t > deepest) {
- deepest = t;
- }
- }
+ const Vec3r viewpoint(0, 0, 0);
+ // Get the point on the camera-space polygon that is closest to the viewpoint
+ // shallowest is the distance from the viewpoint to that point
+ shallowest = GridHelpers::distancePointToPolygon(viewpoint, cameraSpacePolygon);
+
+ // Get the point on the camera-space polygon that is furthest from the viewpoint
+ // deepest is the distance from the viewpoint to that point
+ deepest = cameraSpacePolygon.getVertices()[2].norm();
+ for (unsigned int i = 0; i < 2; ++i) {
+ real t = cameraSpacePolygon.getVertices()[i].norm();
+ if (t > deepest) {
+ deepest = t;
+ }
+ }
}
-inline void SphericalGrid::Cell::checkAndInsert(OccluderSource& source, Polygon3r& poly, OccluderData*& occluder)
+inline void SphericalGrid::Cell::checkAndInsert(OccluderSource &source,
+ Polygon3r &poly,
+ OccluderData *&occluder)
{
- if (GridHelpers::insideProscenium (boundary, poly)) {
- if (occluder == NULL) {
- // Disposal of occluder will be handled in SphericalGrid::distributePolygons(),
- // or automatically by SphericalGrid::_faces;
- occluder = new OccluderData(source, poly);
- }
- faces.push_back(occluder);
- }
+ if (GridHelpers::insideProscenium(boundary, poly)) {
+ if (occluder == NULL) {
+ // Disposal of occluder will be handled in SphericalGrid::distributePolygons(),
+ // or automatically by SphericalGrid::_faces;
+ occluder = new OccluderData(source, poly);
+ }
+ faces.push_back(occluder);
+ }
}
-inline bool SphericalGrid::insertOccluder(OccluderSource& source, OccluderData*& occluder)
+inline bool SphericalGrid::insertOccluder(OccluderSource &source, OccluderData *&occluder)
{
- Polygon3r& poly(source.getGridSpacePolygon());
- occluder = NULL;
-
- Vec3r bbMin, bbMax;
- poly.getBBox(bbMin, bbMax);
- // Check overlapping cells
- unsigned startX, startY, endX, endY;
- getCellCoordinates(bbMin, startX, startY);
- getCellCoordinates(bbMax, endX, endY);
-
- for (unsigned int i = startX; i <= endX; ++i) {
- for (unsigned int j = startY; j <= endY; ++j) {
- if (_cells[i * _cellsY + j] != NULL) {
- _cells[i * _cellsY + j]->checkAndInsert(source, poly, occluder);
- }
- }
- }
-
- return occluder != NULL;
+ Polygon3r &poly(source.getGridSpacePolygon());
+ occluder = NULL;
+
+ Vec3r bbMin, bbMax;
+ poly.getBBox(bbMin, bbMax);
+ // Check overlapping cells
+ unsigned startX, startY, endX, endY;
+ getCellCoordinates(bbMin, startX, startY);
+ getCellCoordinates(bbMax, endX, endY);
+
+ for (unsigned int i = startX; i <= endX; ++i) {
+ for (unsigned int j = startY; j <= endY; ++j) {
+ if (_cells[i * _cellsY + j] != NULL) {
+ _cells[i * _cellsY + j]->checkAndInsert(source, poly, occluder);
+ }
+ }
+ }
+
+ return occluder != NULL;
}
} /* namespace Freestyle */
-#endif // __FREESTYLE_SPHERICAL_GRID_H__
+#endif // __FREESTYLE_SPHERICAL_GRID_H__