Blender V5.0
Grid.h
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2023 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
5#pragma once
6
11
12#include <cstring> // for memset
13#include <float.h>
14#include <stdint.h> // For POINTER_FROM_UINT, i.e. uintptr_t.
15#include <vector>
16
17#include "Geom.h"
18#include "GeomUtils.h"
19#include "Polygon.h"
20
22
23#include "BLI_utildefines.h"
24
25#include "MEM_guardedalloc.h"
26
27using namespace std;
28
29namespace Freestyle {
30
31using namespace Geometry;
32
33typedef vector<Polygon3r *> OccludersSet;
34
35//
36// Class to define cells used by the regular grid
37//
39
40class Cell {
41 public:
42 Cell(Vec3r &orig)
43 {
44 _orig = orig;
45 }
46
47 virtual ~Cell() {}
48
49 inline void addOccluder(Polygon3r *o)
50 {
51 if (o) {
52 _occluders.push_back(o);
53 }
54 }
55
56 inline const Vec3r &getOrigin()
57 {
58 return _orig;
59 }
60
62 {
63 return _occluders;
64 }
65
66 private:
67 Vec3r _orig;
68 OccludersSet _occluders;
69
70 MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:Cell")
71};
72
74 public:
75 virtual ~GridVisitor() {}; // soc
76
77 virtual void discoverCell(Cell * /*cell*/) {}
78
79 virtual void examineOccluder(Polygon3r * /*occ*/) {}
80
81 virtual void finishCell(Cell * /*cell*/) {}
82
83 virtual bool stop()
84 {
85 return false;
86 }
87
88 MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:GridVisitor")
89};
90
93 public:
95
96 virtual void examineOccluder(Polygon3r *occ);
97
99 {
100 return occluders_;
101 }
102
103 void clear()
104 {
105 occluders_.clear();
106 }
107
108 private:
109 OccludersSet &occluders_;
110};
111
116 // soc - changed order to remove warnings
117 public:
118 double u_, v_, t_;
119
120 private:
121 Polygon3r *occluder_;
122 Vec3r ray_org_, ray_dir_, cell_size_;
123 Cell *current_cell_;
124
125 public:
126 firstIntersectionGridVisitor(const Vec3r &ray_org, const Vec3r &ray_dir, const Vec3r &cell_size)
127 : GridVisitor(),
128 u_(0),
129 v_(0),
130 t_(DBL_MAX),
131 occluder_(0),
132 ray_org_(ray_org),
133 ray_dir_(ray_dir),
134 cell_size_(cell_size),
135 current_cell_(0)
136 {
137 }
138
140
141 virtual void discoverCell(Cell *cell)
142 {
143 current_cell_ = cell;
144 }
145
146 virtual void examineOccluder(Polygon3r *occ);
147
148 virtual bool stop();
149
151 {
152 return occluder_;
153 }
154};
155
156//
157// Class to define a regular grid used for ray casting computations
158//
160
161class Grid {
162 public:
164 Grid() {}
165
166 virtual ~Grid()
167 {
168 clear();
169 }
170
174 virtual void clear();
175
184 virtual void configure(const Vec3r &orig, const Vec3r &size, uint nb);
185
191 inline void getCellCoordinates(const Vec3r &p, Vec3u &res)
192 {
193 int tmp;
194 for (int i = 0; i < 3; i++) {
195 tmp = (int)((p[i] - _orig[i]) / _cell_size[i]);
196 if (tmp < 0) {
197 res[i] = 0;
198 }
199 else if ((uint)tmp >= _cells_nb[i]) {
200 res[i] = _cells_nb[i] - 1;
201 }
202 else {
203 res[i] = tmp;
204 }
205 }
206 }
207
209 virtual void fillCell(const Vec3u &coord, Cell &cell) = 0;
210
212 virtual Cell *getCell(const Vec3u &coord) = 0;
213
219 inline Cell *getCell(const Vec3r &p)
220 {
221 Vec3u coord;
222 getCellCoordinates(p, coord);
223 return getCell(coord);
224 }
225
233 inline void getCellOrigin(const Vec3u &cell_coord, Vec3r &orig)
234 {
235 for (uint i = 0; i < 3; i++) {
236 orig[i] = _orig[i] + cell_coord[i] * _cell_size[i];
237 }
238 }
239
248 inline void getCellBox(const Vec3u &cell_coord, Vec3r &min_out, Vec3r &max_out)
249 {
250 getCellOrigin(cell_coord, min_out);
251 max_out = min_out + _cell_size;
252 }
253
258 void insertOccluder(Polygon3r *occluder);
259
261 void addOccluder(Polygon3r *occluder)
262 {
263 _occluders.push_back(occluder);
264 }
265
270 void castRay(const Vec3r &orig, const Vec3r &end, OccludersSet &occluders, uint timestamp);
271
272 // Prepares to cast ray without generating OccludersSet
273 void initAcceleratedRay(const Vec3r &orig, const Vec3r &end, uint timestamp);
274
279 void castInfiniteRay(const Vec3r &orig,
280 const Vec3r &dir,
281 OccludersSet &occluders,
282 uint timestamp);
283
284 // Prepares to cast ray without generating OccludersSet.
285 bool initAcceleratedInfiniteRay(const Vec3r &orig, const Vec3r &dir, uint timestamp);
286
292 const Vec3r &orig, const Vec3r &dir, double &t, double &u, double &v, uint timestamp);
293
295 void initRay(const Vec3r &orig, const Vec3r &end, uint timestamp);
296
300 bool initInfiniteRay(const Vec3r &orig, const Vec3r &dir, uint timestamp);
301
303 inline const Vec3r &getOrigin() const
304 {
305 return _orig;
306 }
307
308 inline Vec3r gridSize() const
309 {
310 return _size;
311 }
312
313 inline Vec3r getCellSize() const
314 {
315 return _cell_size;
316 }
317
318 // ARB profiling only:
320 {
321 return &_occluders;
322 }
323
325 {
326 cerr << "Cells nb : " << _cells_nb << endl;
327 cerr << "Cell size : " << _cell_size << endl;
328 cerr << "Origin : " << _orig << endl;
329 cerr << "Occluders nb : " << _occluders.size() << endl;
330 }
331
332 protected:
334 inline void castRayInternal(GridVisitor &visitor)
335 {
336 Cell *current_cell = nullptr;
337 do {
338 current_cell = getCell(_current_cell);
339 if (current_cell) {
340 visitor.discoverCell(current_cell);
341 OccludersSet &occluders =
342 current_cell->getOccluders(); // FIXME: I had forgotten the ref &
343 for (OccludersSet::iterator it = occluders.begin(); it != occluders.end(); it++) {
344 if (POINTER_AS_UINT((*it)->userdata2) != _timestamp) {
345 (*it)->userdata2 = POINTER_FROM_UINT(_timestamp);
346 visitor.examineOccluder(*it);
347 }
348 }
349 visitor.finishCell(current_cell);
350 }
351 } while ((!visitor.stop()) && (nextRayCell(_current_cell, _current_cell)));
352 }
353
355 bool nextRayCell(Vec3u &current_cell, Vec3u &next_cell);
356
358
359 Vec3u _cells_nb; // number of cells for x,y,z axis
360 Vec3r _cell_size; // cell x,y,z dimensions
361 Vec3r _size; // grid x,y,x dimensions
362 Vec3r _orig; // grid origin
363
364 Vec3r _ray_dir; // direction vector for the ray
365 Vec3u _current_cell; // The current cell being processed (designated by its 3 coordinates)
366 Vec3r _pt; // Points corresponding to the incoming and outgoing intersections of one cell with
367 // the ray
368 real _t_end; // To know when we are at the end of the ray
370
371 // OccludersSet _ray_occluders; // Set storing the occluders contained in the cells traversed by
372 // a ray
373 OccludersSet _occluders; // List of all occluders inserted in the grid
374
375 MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:Grid")
376};
377
378//
379// Class to walk through occluders in grid without building intermediate data structures
380//
382
384 public:
385 VirtualOccludersSet(Grid &_grid) : grid(_grid) {};
388 Polygon3r *next(bool stopOnNewCell);
389
390 private:
391 Polygon3r *firstOccluderFromNextCell();
392 Grid &grid;
393 OccludersSet::iterator it, end;
394
395 MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:VirtualOccludersSet")
396};
397
398} /* namespace Freestyle */
unsigned int uint
#define POINTER_AS_UINT(i)
#define POINTER_FROM_UINT(i)
Configuration definitions.
Various tools for geometry.
Vectors and Matrices (useful type definitions).
Read Guarded memory(de)allocation.
Class to define a polygon.
ATTR_WARN_UNUSED_RESULT const BMVert * v
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Definition btDbvt.cpp:52
void addOccluder(Polygon3r *o)
Definition Grid.h:49
virtual ~Cell()
Definition Grid.h:47
const Vec3r & getOrigin()
Definition Grid.h:56
Cell(Vec3r &orig)
Definition Grid.h:42
OccludersSet & getOccluders()
Definition Grid.h:61
virtual void discoverCell(Cell *)
Definition Grid.h:77
virtual void examineOccluder(Polygon3r *)
Definition Grid.h:79
virtual void finishCell(Cell *)
Definition Grid.h:81
virtual bool stop()
Definition Grid.h:83
virtual ~GridVisitor()
Definition Grid.h:75
OccludersSet _occluders
Definition Grid.h:373
OccludersSet * getOccluders()
Definition Grid.h:319
Vec3r gridSize() const
Definition Grid.h:308
void initAcceleratedRay(const Vec3r &orig, const Vec3r &end, uint timestamp)
void getCellCoordinates(const Vec3r &p, Vec3u &res)
Definition Grid.h:191
const Vec3r & getOrigin() const
Definition Grid.h:303
bool initAcceleratedInfiniteRay(const Vec3r &orig, const Vec3r &dir, uint timestamp)
void castInfiniteRay(const Vec3r &orig, const Vec3r &dir, OccludersSet &occluders, uint timestamp)
Definition Grid.cpp:295
void getCellBox(const Vec3u &cell_coord, Vec3r &min_out, Vec3r &max_out)
Definition Grid.h:248
real _t_end
Definition Grid.h:368
void addOccluder(Polygon3r *occluder)
Definition Grid.h:261
bool nextRayCell(Vec3u &current_cell, Vec3u &next_cell)
Definition Grid.cpp:229
Vec3r getCellSize() const
Definition Grid.h:313
Vec3u _current_cell
Definition Grid.h:365
virtual void configure(const Vec3r &orig, const Vec3r &size, uint nb)
Definition Grid.cpp:101
Vec3r _cell_size
Definition Grid.h:360
void getCellOrigin(const Vec3u &cell_coord, Vec3r &orig)
Definition Grid.h:233
virtual ~Grid()
Definition Grid.h:166
Vec3r _pt
Definition Grid.h:366
bool initInfiniteRay(const Vec3r &orig, const Vec3r &dir, uint timestamp)
Definition Grid.cpp:346
Vec3r _size
Definition Grid.h:361
virtual void clear()
Definition Grid.cpp:85
virtual void fillCell(const Vec3u &coord, Cell &cell)=0
Polygon3r * castRayToFindFirstIntersection(const Vec3r &orig, const Vec3r &dir, double &t, double &u, double &v, uint timestamp)
Definition Grid.cpp:309
void insertOccluder(Polygon3r *occluder)
Definition Grid.cpp:145
void castRayInternal(GridVisitor &visitor)
Definition Grid.h:334
Vec3u _cells_nb
Definition Grid.h:359
void castRay(const Vec3r &orig, const Vec3r &end, OccludersSet &occluders, uint timestamp)
Definition Grid.cpp:288
virtual Cell * getCell(const Vec3u &coord)=0
void initRay(const Vec3r &orig, const Vec3r &end, uint timestamp)
Definition Grid.cpp:330
Vec3r _orig
Definition Grid.h:362
uint _timestamp
Definition Grid.h:357
void displayDebug()
Definition Grid.h:324
Cell * getCell(const Vec3r &p)
Definition Grid.h:219
Vec3r _ray_dir
Definition Grid.h:364
Polygon3r * next(bool stopOnNewCell)
VirtualOccludersSet(Grid &_grid)
Definition Grid.h:385
OccludersSet & occluders()
Definition Grid.h:98
allOccludersGridVisitor(OccludersSet &occluders)
Definition Grid.h:94
virtual void examineOccluder(Polygon3r *occ)
Definition Grid.cpp:21
virtual void discoverCell(Cell *cell)
Definition Grid.h:141
firstIntersectionGridVisitor(const Vec3r &ray_org, const Vec3r &ray_dir, const Vec3r &cell_size)
Definition Grid.h:126
virtual void examineOccluder(Polygon3r *occ)
Definition Grid.cpp:37
VecMat::Vec3< uint > Vec3u
Definition Geom.h:26
VecMat::Vec3< real > Vec3r
Definition Geom.h:30
inherits from class Rep
Definition AppCanvas.cpp:20
vector< Polygon3r * > OccludersSet
Definition Grid.h:33
double real
Definition Precision.h:14
i
Definition text_draw.cc:230