Blender  V3.3
BoxGrid.cpp
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 
8 #include <algorithm>
9 #include <stdexcept>
10 
11 #include "BoxGrid.h"
12 
13 #include "BKE_global.h"
14 
15 using namespace std;
16 
17 namespace Freestyle {
18 
19 // Helper Classes
20 
21 // OccluderData
23 
24 // Cell
26 
27 void BoxGrid::Cell::setDimensions(real x, real y, real sizeX, real sizeY)
28 {
29  const real epsilon = 1.0e-06;
30  boundary[0] = x - epsilon;
31  boundary[1] = x + sizeX + epsilon;
32  boundary[2] = y - epsilon;
33  boundary[3] = y + sizeY + epsilon;
34 }
35 
36 bool BoxGrid::Cell::compareOccludersByShallowestPoint(const BoxGrid::OccluderData *a,
37  const BoxGrid::OccluderData *b)
38 {
39  return a->shallowest < b->shallowest;
40 }
41 
42 void BoxGrid::Cell::indexPolygons()
43 {
44  // Sort occluders by their shallowest points.
45  sort(faces.begin(), faces.end(), compareOccludersByShallowestPoint);
46 }
47 
48 // Iterator
50 
51 BoxGrid::Iterator::Iterator(BoxGrid &grid, Vec3r &center, real /*epsilon*/)
52  : _target(grid.transform(center)), _foundOccludee(false)
53 {
54  // Find target cell
55  _cell = grid.findCell(_target);
56 #if BOX_GRID_LOGGING
57  if (G.debug & G_DEBUG_FREESTYLE) {
58  cout << "Searching for occluders of edge centered at " << _target << " in cell ["
59  << 1_cell->boundary[0] << ", " << _cell->boundary[1] << ", " << _cell->boundary[2] << ", "
60  << _cell->boundary[3] << "] (" << _cell->faces.size() << " occluders)" << endl;
61  }
62 #endif
63 
64  // Set iterator
65  _current = _cell->faces.begin();
66 }
67 
68 // BoxGrid
70 
71 BoxGrid::BoxGrid(OccluderSource &source,
73  ViewMap *viewMap,
75  bool enableQI)
76  : _viewpoint(viewpoint), _enableQI(enableQI)
77 {
78  // Generate Cell structure
79  if (G.debug & G_DEBUG_FREESTYLE) {
80  cout << "Generate Cell structure" << endl;
81  }
82  assignCells(source, density, viewMap);
83 
84  // Fill Cells
85  if (G.debug & G_DEBUG_FREESTYLE) {
86  cout << "Distribute occluders" << endl;
87  }
88  distributePolygons(source);
89 
90  // Reorganize Cells
91  if (G.debug & G_DEBUG_FREESTYLE) {
92  cout << "Reorganize cells" << endl;
93  }
95 
96  if (G.debug & G_DEBUG_FREESTYLE) {
97  cout << "Ready to use BoxGrid" << endl;
98  }
99 }
100 
101 BoxGrid::~BoxGrid() = default;
102 
105  ViewMap *viewMap)
106 {
107  _cellSize = density.cellSize();
108  _cellsX = density.cellsX();
109  _cellsY = density.cellsY();
110  _cellOrigin[0] = density.cellOrigin(0);
111  _cellOrigin[1] = density.cellOrigin(1);
112  if (G.debug & G_DEBUG_FREESTYLE) {
113  cout << "Using " << _cellsX << "x" << _cellsY << " cells of size " << _cellSize << " square."
114  << endl;
115  cout << "Cell origin: " << _cellOrigin[0] << ", " << _cellOrigin[1] << endl;
116  }
117 
118  // Now allocate the cell table and fill it with default (empty) cells
119  _cells.resize(_cellsX * _cellsY);
120  for (cellContainer::iterator i = _cells.begin(), end = _cells.end(); i != end; ++i) {
121  (*i) = NULL;
122  }
123 
124  // Identify cells that will be used, and set the dimensions for each
125  ViewMap::fedges_container &fedges = viewMap->FEdges();
126  for (ViewMap::fedges_container::iterator f = fedges.begin(), fend = fedges.end(); f != fend;
127  ++f) {
128  if ((*f)->isInImage()) {
129  Vec3r point = transform((*f)->center3d());
130  unsigned int i, j;
131  getCellCoordinates(point, i, j);
132  if (_cells[i * _cellsY + j] == nullptr) {
133  // This is an uninitialized cell
134  real x, y, width, height;
135 
136  x = _cellOrigin[0] + _cellSize * i;
137  width = _cellSize;
138 
139  y = _cellOrigin[1] + _cellSize * j;
140  height = _cellSize;
141 
142  // Initialize cell
143  Cell *b = _cells[i * _cellsY + j] = new Cell();
144  b->setDimensions(x, y, width, height);
145  }
146  }
147  }
148 }
149 
151 {
152  unsigned long nFaces = 0;
153  unsigned long nKeptFaces = 0;
154 
155  for (source.begin(); source.isValid(); source.next()) {
156  OccluderData *occluder = nullptr;
157 
158  try {
159  if (insertOccluder(source, occluder)) {
160  _faces.push_back(occluder);
161  ++nKeptFaces;
162  }
163  }
164  catch (...) {
165  // If an exception was thrown, _faces.push_back() cannot have succeeded.
166  // occluder is not owned by anyone, and must be deleted.
167  // If the exception was thrown before or during new OccluderData(), then
168  // occluder is NULL, and this delete is harmless.
169  delete occluder;
170  throw;
171  }
172  ++nFaces;
173  }
174  if (G.debug & G_DEBUG_FREESTYLE) {
175  cout << "Distributed " << nFaces << " occluders. Retained " << nKeptFaces << "." << endl;
176  }
177 }
178 
180 {
181  // Sort the occluders by shallowest point
182  for (vector<Cell *>::iterator i = _cells.begin(), end = _cells.end(); i != end; ++i) {
183  if (*i != NULL) {
184  (*i)->indexPolygons();
185  }
186  }
187 }
188 
189 void BoxGrid::getCellCoordinates(const Vec3r &point, unsigned &x, unsigned &y)
190 {
191  x = min(_cellsX - 1, (unsigned)floor(max((double)0.0f, point[0] - _cellOrigin[0]) / _cellSize));
192  y = min(_cellsY - 1, (unsigned)floor(max((double)0.0f, point[1] - _cellOrigin[1]) / _cellSize));
193 }
194 
195 BoxGrid::Cell *BoxGrid::findCell(const Vec3r &point)
196 {
197  unsigned int x, y;
198  getCellCoordinates(point, x, y);
199  return _cells[x * _cellsY + y];
200 }
201 
203 {
204  return true;
205 }
206 
207 const Vec3r &BoxGrid::viewpoint() const
208 {
209  return _viewpoint;
210 }
211 
212 bool BoxGrid::enableQI() const
213 {
214  return _enableQI;
215 }
216 
218 {
219  return Vec3r(point[0], point[1], -point[2]);
220 }
221 
222 } /* namespace Freestyle */
@ G_DEBUG_FREESTYLE
Definition: BKE_global.h:181
Class to define a cell grid surrounding the projected image of a scene.
NSNotificationCenter * center
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei height
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint y
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei width
in reality light always falls off quadratically Particle Retrieve the data of the particle that spawned the object for example to give variation to multiple instances of an object Point Retrieve information about points in a point cloud Retrieve the edges of an object as it appears to Cycles topology will always appear triangulated Convert a blackbody temperature to an RGB value Normal Generate a perturbed normal from an RGB normal map image Typically used for faking highly detailed surfaces Generate an OSL shader from a file or text data block Image Sample an image file as a texture Sky Generate a procedural sky texture Noise Generate fractal Perlin noise Wave Generate procedural bands or rings with noise Voronoi Generate Worley noise based on the distance to random points Typically used to generate textures such as or biological cells Brick Generate a procedural texture producing bricks Texture Retrieve multiple types of texture coordinates nTypically used as inputs for texture nodes Vector Convert a point
SIMD_FORCE_INLINE btVector3 transform(const btVector3 &point) const
void sort(btMatrix3x3 &U, btVector3 &sigma, btMatrix3x3 &V, int t)
Helper function of 3X3 SVD for sorting singular values.
Vec3r operator()(const Vec3r &point) const
Definition: BoxGrid.cpp:217
Transform transform
Definition: BoxGrid.h:154
void assignCells(OccluderSource &source, GridDensityProvider &density, ViewMap *viewMap)
Definition: BoxGrid.cpp:103
const Vec3r & viewpoint() const
Definition: BoxGrid.cpp:207
void reorganizeCells()
Definition: BoxGrid.cpp:179
Cell * findCell(const Vec3r &point)
Definition: BoxGrid.cpp:195
bool enableQI() const
Definition: BoxGrid.cpp:212
void distributePolygons(OccluderSource &source)
Definition: BoxGrid.cpp:150
bool insertOccluder(OccluderSource &source, OccluderData *&occluder)
Definition: BoxGrid.h:384
bool orthographicProjection() const
Definition: BoxGrid.cpp:202
vector< FEdge * > fedges_container
Definition: ViewMap.h:52
fedges_container & FEdges()
Definition: ViewMap.h:115
static char faces[256]
#define G(x, y, z)
VecMat::Vec3< real > Vec3r
Definition: Geom.h:28
inherits from class Rep
Definition: AppCanvas.cpp:18
static unsigned x[3]
Definition: RandGen.cpp:73
static unsigned a[3]
Definition: RandGen.cpp:78
double real
Definition: Precision.h:12
T floor(const T &a)
static double epsilon
static const pxr::TfToken b("b", pxr::TfToken::Immortal)
static const pxr::TfToken density("density", pxr::TfToken::Immortal)
#define min(a, b)
Definition: sort.c:35
float max