Blender V4.3
SphericalGrid.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
9
10#include <algorithm>
11#include <stdexcept>
12
13#include "SphericalGrid.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 SphericalGrid::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 SphericalGrid::Cell::compareOccludersByShallowestPoint(const SphericalGrid::OccluderData *a,
41 const SphericalGrid::OccluderData *b)
42{
43 return a->shallowest < b->shallowest;
44}
45
46void SphericalGrid::Cell::indexPolygons()
47{
48 // Sort occluders by their shallowest points.
49 sort(faces.begin(), faces.end(), compareOccludersByShallowestPoint);
50}
51
52// Iterator
54
55SphericalGrid::Iterator::Iterator(SphericalGrid &grid, Vec3r &center, real /*epsilon*/)
56 : _target(SphericalGrid::Transform::sphericalProjection(center)), _foundOccludee(false)
57{
58 // Find target cell
59 _cell = grid.findCell(_target);
60#if SPHERICAL_GRID_LOGGING
61 if (G.debug & G_DEBUG_FREESTYLE) {
62 cout << "Searching for occluders of edge centered at " << _target << " in cell ["
63 << _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// SphericalGrid
74
75SphericalGrid::SphericalGrid(OccluderSource &source,
76 GridDensityProvider &density,
77 ViewMap *viewMap,
79 bool enableQI)
80 : _viewpoint(viewpoint), _enableQI(enableQI)
81{
82 if (G.debug & G_DEBUG_FREESTYLE) {
83 cout << "Generate Cell structure" << endl;
84 }
85 // Generate Cell structure
86 assignCells(source, density, viewMap);
87 if (G.debug & G_DEBUG_FREESTYLE) {
88 cout << "Distribute occluders" << endl;
89 }
90 // Fill Cells
91 distributePolygons(source);
92 if (G.debug & G_DEBUG_FREESTYLE) {
93 cout << "Reorganize cells" << endl;
94 }
95 // Reorganize Cells
97 if (G.debug & G_DEBUG_FREESTYLE) {
98 cout << "Ready to use SphericalGrid" << endl;
99 }
100}
101
103
105 GridDensityProvider &density,
106 ViewMap *viewMap)
107{
108 _cellSize = density.cellSize();
109 _cellsX = density.cellsX();
110 _cellsY = density.cellsY();
111 _cellOrigin[0] = density.cellOrigin(0);
112 _cellOrigin[1] = density.cellOrigin(1);
113 if (G.debug & G_DEBUG_FREESTYLE) {
114 cout << "Using " << _cellsX << "x" << _cellsY << " cells of size " << _cellSize << " square."
115 << endl;
116 cout << "Cell origin: " << _cellOrigin[0] << ", " << _cellOrigin[1] << endl;
117 }
118
119 // Now allocate the cell table and fill it with default (empty) cells
120 _cells.resize(_cellsX * _cellsY);
121 for (cellContainer::iterator i = _cells.begin(), end = _cells.end(); i != end; ++i) {
122 (*i) = nullptr;
123 }
124
125 // Identify cells that will be used, and set the dimensions for each
126 ViewMap::fedges_container &fedges = viewMap->FEdges();
127 for (ViewMap::fedges_container::iterator f = fedges.begin(), fend = fedges.end(); f != fend; ++f)
128 {
129 if ((*f)->isInImage()) {
130 Vec3r point = SphericalGrid::Transform::sphericalProjection((*f)->center3d());
131 uint i, j;
132 getCellCoordinates(point, i, j);
133 if (_cells[i * _cellsY + j] == nullptr) {
134 // This is an uninitialized cell
135 real x, y, width, height;
136
137 x = _cellOrigin[0] + _cellSize * i;
138 width = _cellSize;
139
140 y = _cellOrigin[1] + _cellSize * j;
141 height = _cellSize;
142
143 // Initialize cell
144 Cell *b = _cells[i * _cellsY + j] = new Cell();
145 b->setDimensions(x, y, width, height);
146 }
147 }
148 }
149}
150
152{
153 ulong nFaces = 0;
154 ulong nKeptFaces = 0;
155
156 for (source.begin(); source.isValid(); source.next()) {
157 OccluderData *occluder = nullptr;
158
159 try {
160 if (insertOccluder(source, occluder)) {
161 _faces.push_back(occluder);
162 ++nKeptFaces;
163 }
164 }
165 catch (...) {
166 // If an exception was thrown, _faces.push_back() cannot have succeeded. Occluder is not
167 // owned by anyone, and must be deleted. If the exception was thrown before or during new
168 // OccluderData(), then occluder is nullptr, 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 != nullptr) {
184 (*i)->indexPolygons();
185 }
186 }
187}
188
189void SphericalGrid::getCellCoordinates(const Vec3r &point, uint &x, uint &y)
190{
191 x = min(_cellsX - 1, uint(floor(max(double(0.0f), point[0] - _cellOrigin[0]) / _cellSize)));
192 y = min(_cellsY - 1, uint(floor(max(double(0.0f), point[1] - _cellOrigin[1]) / _cellSize)));
193}
194
195SphericalGrid::Cell *SphericalGrid::findCell(const Vec3r &point)
196{
197 uint x, y;
198 getCellCoordinates(point, x, y);
199 return _cells[x * _cellsY + y];
200}
201
203{
204 return false;
205}
206
208{
209 return _viewpoint;
210}
211
213{
214 return _enableQI;
215}
216
217Vec3r SphericalGrid::Transform::operator()(const Vec3r &point) const
218{
220}
221
222Vec3r SphericalGrid::Transform::sphericalProjection(const Vec3r &M)
223{
224 Vec3r newPoint;
225
226 newPoint[0] = ::atan(M[0] / M[2]);
227 newPoint[1] = ::atan(M[1] / M[2]);
228 newPoint[2] = ::sqrt(M[0] * M[0] + M[1] * M[1] + M[2] * M[2]);
229
230 return newPoint;
231}
232
233} /* namespace Freestyle */
@ G_DEBUG_FREESTYLE
sqrt(x)+1/max(0
unsigned long ulong
unsigned int uint
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 Gabor Generate Gabor noise Gradient Generate interpolated color and intensity values based on the input vector Magic Generate a psychedelic color texture 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
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(SphericalGrid &grid, Vec3r &center, real epsilon=1.0e-06)
static Vec3r sphericalProjection(const Vec3r &M)
void assignCells(OccluderSource &source, GridDensityProvider &density, ViewMap *viewMap)
const Vec3r & viewpoint() const
bool orthographicProjection() const
Cell * findCell(const Vec3r &point)
void distributePolygons(OccluderSource &source)
bool insertOccluder(OccluderSource &source, OccluderData *&occluder)
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 M
static char faces[256]
#define G(x, y, z)
VecMat::Vec3< real > Vec3r
Definition Geom.h:30
inherits from class Rep
Definition AppCanvas.cpp:20
static uint a[3]
Definition RandGen.cpp:82
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