in src/esp/geo/VoxelUtils.cpp [9:88]
void generateInteriorExteriorVoxelGrid(
std::shared_ptr<esp::geo::VoxelWrapper>& voxelWrapper) {
// create 6 bool grids
auto v_grid = voxelWrapper->getVoxelGrid();
auto boundaryGrid = v_grid->getGrid<bool>("Boundary");
auto m_voxelGridDimensions = v_grid->getVoxelGridDimensions();
// Create a temporary grid (unregistered) to hold 6 booleans for each cell -
// each for a specified direction of raycasts
std::size_t dims[3]{static_cast<std::size_t>(m_voxelGridDimensions[0]),
static_cast<std::size_t>(m_voxelGridDimensions[1]),
static_cast<std::size_t>(m_voxelGridDimensions[2])};
Corrade::Containers::Array<char> cr_grid{
Corrade::ValueInit, v_grid->gridSize() * sizeof(Mn::Math::BoolVector<6>)};
auto shadowGrid_ =
Cr::Containers::StridedArrayView<3, Mn::Math::BoolVector<6>>{
Cr::Containers::arrayCast<Mn::Math::BoolVector<6>>(cr_grid), dims};
// fill each grid with ray cast
bool hit = false;
int ind = 0;
int increment = 0;
Mn::Vector3i indices;
for (int castAxis = 0; castAxis < 3; ++castAxis) {
int a1 = castAxis != 0 ? 0 : 1;
int a2 = castAxis == 2 ? 1 : 2;
for (int j = 0; j < m_voxelGridDimensions[a1]; j++) {
for (int k = 0; k < m_voxelGridDimensions[a2]; k++) {
indices[a1] = j;
indices[a2] = k;
// fill from front and back of each 1D slice
for (int direction = -1; direction < 2; direction += 2) { //-1 and 1
hit = false;
ind = (direction > 0 ? 0 : m_voxelGridDimensions[castAxis] - 1);
while (ind >= 0 && ind < m_voxelGridDimensions[castAxis]) {
indices[castAxis] = ind;
hit = (hit || boundaryGrid[indices[0]][indices[1]][indices[2]]);
if (hit)
shadowGrid_[indices[0]][indices[1]][indices[2]].set(
castAxis * 2 + (direction < 0 ? 0 : 1), true);
ind += direction;
}
}
}
}
}
// create int grid
std::string gridName = "InteriorExterior";
v_grid->addGrid<int>(gridName);
auto intExtGrid = v_grid->getGrid<int>(gridName);
bool nX = false, pX = false, nY = false, pY = false, nZ = false, pZ = false;
// fill in int grid with voting approach
for (int i = 0; i < m_voxelGridDimensions[0]; i++) {
for (int j = 0; j < m_voxelGridDimensions[1]; j++) {
for (int k = 0; k < m_voxelGridDimensions[2]; k++) {
Mn::Vector3i index = Mn::Vector3i(i, j, k);
if (boundaryGrid[i][j][k]) {
intExtGrid[i][j][k] = 0;
continue;
}
nX = !shadowGrid_[i][j][k][0];
pX = !shadowGrid_[i][j][k][1];
nY = !shadowGrid_[i][j][k][2];
pY = !shadowGrid_[i][j][k][3];
nZ = !shadowGrid_[i][j][k][4];
pZ = !shadowGrid_[i][j][k][5];
// || ((nX || pX) && (nY || pY) && (nZ || pZ))
if (((nX && pX) || (nY && pY) || (nZ && pZ)) ||
((nX || pX) && (nY || pY) && (nZ || pZ))) {
// Exterior (+inf)
intExtGrid[i][j][k] = INT_MAX;
} else {
// Interior (-inf)
intExtGrid[i][j][k] = INT_MIN;
}
}
}
}
}