Blender V4.3
BoxGrid.cpp
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2011-2023 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
10#include <algorithm>
11#include <stdexcept>
12
13#include "BoxGrid.h"
14
15#include "BLI_sys_types.h"
16
17#include "BKE_global.hh"
18
19using namespace std;
20
21namespace Freestyle {
22
23// Helper Classes
24
25// OccluderData
27
28// Cell
30
31void BoxGrid::Cell::setDimensions(real x, real y, real sizeX, real sizeY)
32{
33 const real epsilon = 1.0e-06;
34 boundary[0] = x - epsilon;
35 boundary[1] = x + sizeX + epsilon;
36 boundary[2] = y - epsilon;
37 boundary[3] = y + sizeY + epsilon;
38}
39
40bool BoxGrid::Cell::compareOccludersByShallowestPoint(const BoxGrid::OccluderData *a,
41 const BoxGrid::OccluderData *b)
42{
43 return a->shallowest < b->shallowest;
44}
45
46void BoxGrid::Cell::indexPolygons()
47{
48 // Sort occluders by their shallowest points.
49 sort(faces.begin(), faces.end(), compareOccludersByShallowestPoint);
50}
51
52// Iterator
54
55BoxGrid::Iterator::Iterator(BoxGrid &grid, Vec3r &center, real /*epsilon*/)
56 : _target(grid.transform(center)), _foundOccludee(false)
57{
58 // Find target cell
59 _cell = grid.findCell(_target);
60#if BOX_GRID_LOGGING
61 if (G.debug & G_DEBUG_FREESTYLE) {
62 cout << "Searching for occluders of edge centered at " << _target << " in cell ["
63 << 1_cell->boundary[0] << ", " << _cell->boundary[1] << ", " << _cell->boundary[2] << ", "
64 << _cell->boundary[3] << "] (" << _cell->faces.size() << " occluders)" << endl;
65 }
66#endif
67
68 // Set iterator
69 _current = _cell->faces.begin();
70}
71
72// BoxGrid
74
75BoxGrid::BoxGrid(OccluderSource &source,
76 GridDensityProvider &density,
77 ViewMap *viewMap,
79 bool enableQI)
80 : _viewpoint(viewpoint), _enableQI(enableQI)
81{
82 // Generate Cell structure
83 if (G.debug & G_DEBUG_FREESTYLE) {
84 cout << "Generate Cell structure" << endl;
85 }
86 assignCells(source, density, viewMap);
87
88 // Fill Cells
89 if (G.debug & G_DEBUG_FREESTYLE) {
90 cout << "Distribute occluders" << endl;
91 }
92 distributePolygons(source);
93
94 // Reorganize Cells
95 if (G.debug & G_DEBUG_FREESTYLE) {
96 cout << "Reorganize cells" << endl;
97 }
99
100 if (G.debug & G_DEBUG_FREESTYLE) {
101 cout << "Ready to use BoxGrid" << endl;
102 }
103}
104
105BoxGrid::~BoxGrid() = default;
106
108 GridDensityProvider &density,
109 ViewMap *viewMap)
110{
111 _cellSize = density.cellSize();
112 _cellsX = density.cellsX();
113 _cellsY = density.cellsY();
114 _cellOrigin[0] = density.cellOrigin(0);
115 _cellOrigin[1] = density.cellOrigin(1);
116 if (G.debug & G_DEBUG_FREESTYLE) {
117 cout << "Using " << _cellsX << "x" << _cellsY << " cells of size " << _cellSize << " square."
118 << endl;
119 cout << "Cell origin: " << _cellOrigin[0] << ", " << _cellOrigin[1] << endl;
120 }
121
122 // Now allocate the cell table and fill it with default (empty) cells
123 _cells.resize(_cellsX * _cellsY);
124 for (cellContainer::iterator i = _cells.begin(), end = _cells.end(); i != end; ++i) {
125 (*i) = nullptr;
126 }
127
128 // Identify cells that will be used, and set the dimensions for each
129 ViewMap::fedges_container &fedges = viewMap->FEdges();
130 for (ViewMap::fedges_container::iterator f = fedges.begin(), fend = fedges.end(); f != fend; ++f)
131 {
132 if ((*f)->isInImage()) {
133 Vec3r point = transform((*f)->center3d());
134 uint i, j;
135 getCellCoordinates(point, i, j);
136 if (_cells[i * _cellsY + j] == nullptr) {
137 // This is an uninitialized cell
138 real x, y, width, height;
139
140 x = _cellOrigin[0] + _cellSize * i;
141 width = _cellSize;
142
143 y = _cellOrigin[1] + _cellSize * j;
144 height = _cellSize;
145
146 // Initialize cell
147 Cell *b = _cells[i * _cellsY + j] = new Cell();
148 b->setDimensions(x, y, width, height);
149 }
150 }
151 }
152}
153
155{
156 ulong nFaces = 0;
157 ulong nKeptFaces = 0;
158
159 for (source.begin(); source.isValid(); source.next()) {
160 OccluderData *occluder = nullptr;
161
162 try {
163 if (insertOccluder(source, occluder)) {
164 _faces.push_back(occluder);
165 ++nKeptFaces;
166 }
167 }
168 catch (...) {
169 // If an exception was thrown, _faces.push_back() cannot have succeeded.
170 // occluder is not owned by anyone, and must be deleted.
171 // If the exception was thrown before or during new OccluderData(), then
172 // occluder is nullptr, and this delete is harmless.
173 delete occluder;
174 throw;
175 }
176 ++nFaces;
177 }
178 if (G.debug & G_DEBUG_FREESTYLE) {
179 cout << "Distributed " << nFaces << " occluders. Retained " << nKeptFaces << "." << endl;
180 }
181}
182
184{
185 // Sort the occluders by shallowest point
186 for (vector<Cell *>::iterator i = _cells.begin(), end = _cells.end(); i != end; ++i) {
187 if (*i != nullptr) {
188 (*i)->indexPolygons();
189 }
190 }
191}
192
193void BoxGrid::getCellCoordinates(const Vec3r &point, uint &x, uint &y)
194{
195 x = min(_cellsX - 1, uint(floor(max(double(0.0f), point[0] - _cellOrigin[0]) / _cellSize)));
196 y = min(_cellsY - 1, uint(floor(max(double(0.0f), point[1] - _cellOrigin[1]) / _cellSize)));
197}
198
199BoxGrid::Cell *BoxGrid::findCell(const Vec3r &point)
200{
201 uint x, y;
202 getCellCoordinates(point, x, y);
203 return _cells[x * _cellsY + y];
204}
205
207{
208 return true;
209}
210
212{
213 return _viewpoint;
214}
215
217{
218 return _enableQI;
219}
220
221Vec3r BoxGrid::Transform::operator()(const Vec3r &point) const
222{
223 return Vec3r(point[0], point[1], -point[2]);
224}
225
226} /* namespace Freestyle */
@ G_DEBUG_FREESTYLE
unsigned long ulong
unsigned int uint
Class to define a cell grid surrounding the projected image of a scene.
static DBVT_INLINE btDbvtNode * sort(btDbvtNode *n, btDbvtNode *&r)
Definition btDbvt.cpp:418
Iterator(BoxGrid &grid, Vec3r &center, real epsilon=1.0e-06)
Definition BoxGrid.cpp:55
Transform transform
Definition BoxGrid.h:156
void assignCells(OccluderSource &source, GridDensityProvider &density, ViewMap *viewMap)
Definition BoxGrid.cpp:107
const Vec3r & viewpoint() const
Definition BoxGrid.cpp:211
Cell * findCell(const Vec3r &point)
Definition BoxGrid.cpp:199
bool enableQI() const
Definition BoxGrid.cpp:216
void distributePolygons(OccluderSource &source)
Definition BoxGrid.cpp:154
bool insertOccluder(OccluderSource &source, OccluderData *&occluder)
Definition BoxGrid.h:387
bool orthographicProjection() const
Definition BoxGrid.cpp:206
vector< FEdge * > fedges_container
Definition ViewMap.h:53
fedges_container & FEdges()
Definition ViewMap.h:116
local_group_size(16, 16) .push_constant(Type b
ccl_device_inline float2 floor(const float2 a)
#define G(x, y, z)
VecMat::Vec3< real > Vec3r
Definition Geom.h:30
inherits from class Rep
Definition AppCanvas.cpp:20
static uint x[3]
Definition RandGen.cpp:77
double real
Definition Precision.h:14
double epsilon
default precision while comparing with Equal(..,..) functions. Initialized at 0.0000001.
Definition utility.cpp:22
#define min(a, b)
Definition sort.c:32
float max