83 m_margin =
static_cast<int64_t
>(margin);
101 }
catch (
const std::bad_alloc&) {
114 assert(cellSize > 0);
119 static_cast<int>( (P.
x - gridMinCorner.
x) / cellSize),
120 static_cast<int>( (P.
y - gridMinCorner.
y) / cellSize),
121 static_cast<int>( (P.
z - gridMinCorner.
z) / cellSize));
140 auto setIntersectValue = [&](
const Tuple3i& cellPos,
142 this->
setValue(cellPos, intersectValue);
145 return intersectWith(mesh, cellLength, gridMinCorner, setIntersectValue,
152 std::function<void(
const Tuple3i&,
unsigned)>;
166 CCVector3 halfCellDimensions(cellLength / 2, cellLength / 2,
169 std::vector<CellToTest> cellsToTest(1);
170 unsigned cellsToTestCount = 0;
173 unsigned numberOfTriangles = mesh->
size();
178 if (progressCb->textCanBeEdited()) {
180 snprintf(buffer, 32,
"Triangles: %u", numberOfTriangles);
181 progressCb->setInfo(buffer);
182 progressCb->setMethodTitle(
"Intersect Grid/Mesh");
184 progressCb->update(0);
190 for (
unsigned n = 0; n < numberOfTriangles; ++n) {
197 CCVector3 AB = (*triPoints[1]) - (*triPoints[0]);
198 CCVector3 BC = (*triPoints[2]) - (*triPoints[1]);
199 CCVector3 CA = (*triPoints[0]) - (*triPoints[2]);
206 gridMinCorner, cellLength),
208 gridMinCorner, cellLength),
210 gridMinCorner, cellLength)};
214 for (
int k = 0; k < 3; k++) {
217 std::min(cellPos[1].u[k], cellPos[2].u[k]));
220 std::max(cellPos[1].u[k], cellPos[2].u[k]));
224 assert(cellsToTest.capacity() != 0);
225 cellsToTestCount = 1;
242 static const double LOG_2 = log(2.0);
244 (1 << (maxSize > 1 ?
static_cast<unsigned char>(
ceil(
245 log(
static_cast<double>(
252 for (
int k = 0; k < 3; k++) {
254 0, minPos.
u[k] + (delta.
u[k] -
259 _currentCell->
pos = minPos;
263 while (cellsToTestCount != 0) {
264 _currentCell = &cellsToTest[--cellsToTestCount];
281 if ((currentCellPos.
x >= 0 &&
283 static_cast<int>(
size().x)) &&
284 (currentCellPos.
y >= 0 &&
286 static_cast<int>(
size().y)) &&
287 (currentCellPos.
z >= 0 &&
289 static_cast<int>(
size().z))) {
290 action(currentCellPos, n);
294 int halfCellSize = (_currentCell->
cellSize >> 1);
299 char pointsPosition[27];
301 char* _pointsPosition = pointsPosition;
303 gridMinCorner - (*triPoints[0]);
304 for (
int i = 0; i < 3; ++i) {
305 AB.
x = distanceToMinBorder.
x +
310 for (
int j = 0; j < 3; ++j) {
311 AB.
y = distanceToMinBorder.
y +
316 for (
int k = 0; k < 3; ++k) {
317 AB.
z = distanceToMinBorder.
z +
326 = (AB.
dot(N) < 0 ? -1 : 1);
333 if (cellsToTestCount + 27 > cellsToTest.capacity()) {
336 std::max(cellsToTest.capacity() + 27,
337 2 * cellsToTest.capacity()));
338 }
catch (
const std::bad_alloc&) {
346 CellToTest* _newCell = &cellsToTest[cellsToTestCount];
351 for (
int i = 0; i < 2; ++i) {
353 currentCellPos.
x + i * halfCellSize;
356 if (
static_cast<int>(_newCell->
pos.
x) +
359 static_cast<int>(_newCell->
pos.
x) <= maxPos.
x) {
360 for (
int j = 0; j < 2; ++j) {
362 currentCellPos.
y + j * halfCellSize;
363 if (
static_cast<int>(_newCell->
pos.
y) +
366 static_cast<int>(_newCell->
pos.
y) <=
368 for (
int k = 0; k < 2; ++k) {
369 _newCell->
pos.
z = currentCellPos.
z +
371 if (
static_cast<int>(
378 const char* _pointsPosition =
381 char sum = _pointsPosition[0] +
386 _pointsPosition[10] +
387 _pointsPosition[12] +
394 if (sum > -8 && sum < 8) {
398 [++cellsToTestCount] =
434 CCVector3 halfCellDimensions(cellLength / 2, cellLength / 2,
438 unsigned numberOfPoints = cloud->
size();
443 if (progressCb->textCanBeEdited()) {
445 snprintf(buffer, 32,
"Points: %u", numberOfPoints);
446 progressCb->setInfo(buffer);
447 progressCb->setMethodTitle(
"Intersect Grid/Cloud");
449 progressCb->update(0);
455 for (
unsigned n = 0; n < numberOfPoints; ++n) {
457 gridMinCorner, cellLength);
459 if ((cellPos.
x >= 0 && cellPos.
x <
static_cast<int>(
size().x)) &&
460 (cellPos.
y >= 0 && cellPos.
y <
static_cast<int>(
size().y)) &&
461 (cellPos.
z >= 0 && cellPos.
z <
static_cast<int>(
size().z))) {
Tuple3Tpl< unsigned int > Tuple3ui
Tuple of 3 unsigned int values.
Tuple3Tpl< int > Tuple3i
Tuple of 3 int values.
float PointCoordinateType
Type of the coordinates of a (N-D) point.
Type dot(const Vector3Tpl &v) const
Dot product.
Type norm2() const
Returns vector square norm.
Vector3Tpl cross(const Vector3Tpl &v) const
Cross product.
static Vector3Tpl fromArray(const int a[3])
Constructor from an int array.
virtual void placeIteratorAtBeginning()=0
Sets the cloud iterator at the beginning.
virtual const CCVector3 * getNextPoint()=0
Returns the next point (relatively to the global iterator position)
virtual unsigned size() const =0
Returns the number of points.
A generic mesh with index-based vertex access.
virtual unsigned size() const =0
Returns the number of triangles.
virtual GenericTriangle * _getNextTriangle()=0
Returns the next triangle (relatively to the global iterator position)
virtual void placeIteratorAtBeginning()=0
Places the mesh iterator at the beginning.
A generic triangle interface.
virtual const CCVector3 * _getA() const =0
Returns the first vertex (A)
virtual const CCVector3 * _getC() const =0
Returns the third vertex (C)
virtual const CCVector3 * _getB() const =0
Returns the second vertex (B)
Simple 3D grid structure.
uint64_t totalCellCount() const
Returns the total number of cell count (with margin)
int64_t pos2index(int i, int j, int k) const
Converts a 3D position to an absolute index.
const GridElement * data() const
Gives access to the internal grid data (with margin) (const version)
int64_t m_rowSize
1D row size (with margin)
Tuple3ui m_innerSize
Dimensions of the grid (without margin)
bool intersectWith(GenericIndexedMesh *mesh, PointCoordinateType cellLength, const CCVector3 &gridMinCorner, GridElement intersectValue=0, GenericProgressCallback *progressCb=nullptr)
Intersects this grid with a mesh.
std::function< void(const Tuple3i &, unsigned)> genericCellTriIntersectionAction
const GridElement & getValue(int i, int j, int k) const
Returns the value of a given cell (const version)
Type GridElement
Cell type.
GridElement & getValue(int i, int j, int k)
Returns the value of a given cell.
Grid3D()
Default constructor.
int64_t m_sliceSize
2D slice size (with margin)
bool intersectWith(GenericIndexedMesh *mesh, PointCoordinateType cellLength, const CCVector3 &gridMinCorner, genericCellTriIntersectionAction action, GenericProgressCallback *progressCb=nullptr)
Intersects this grid with a mesh (generic form)
GridElement * data()
Gives access to the internal grid data (with margin)
std::vector< GridElement > m_grid
Grid data.
Tuple3i computeCellPos(const CCVector3 &P, const CCVector3 &gridMinCorner, PointCoordinateType cellSize) const
Computes the (grid) cell position that contains a given point.
uint64_t m_totalCellCount
3D grid size with margin
void setValue(const Tuple3i &cellPos, GridElement value)
Sets the value of a given cell.
bool isInitialized() const
Returns whether the grid has been initialized or not.
void setValue(int i, int j, int k, GridElement value)
Sets the value of a given cell.
const GridElement & getValue(Tuple3i &cellPos) const
Returns the value of a given cell const version)
int64_t m_marginShift
First index of real data (i.e. after marin)
GridElement & getValue(Tuple3i &cellPos)
Returns the value of a given cell.
uint64_t innerCellCount() const
Returns the number of cell count (whithout margin)
void clear()
Clears the grid.
const Tuple3ui & size() const
Returns the grid dimensions.
bool intersectWith(GenericCloud *cloud, PointCoordinateType cellLength, const CCVector3 &gridMinCorner, GridElement intersectValue=0, GenericProgressCallback *progressCb=nullptr)
Intersects this grid with a cloud.
uint64_t m_innerCellCount
3D grid size without margin
bool init(unsigned di, unsigned dj, unsigned dk, unsigned margin, GridElement defaultCellValue=0)
Initializes the grid.
bool oneStep()
Increments total progress value of a single unit.
MiniVec< float, N > ceil(const MiniVec< float, N > &a)
Generic file read and write utility for python interface.
bool GreaterThanSquareEpsilon(double x)
Tuple3i pos
Cell position.