CubeCoordSet processRegion(const Coordinate & globalFirst, const Coordinate & globalLast, Func func, Skip skip) { const auto cubeBegin = globalFirst.cube(state->cubeEdgeLength, state->magnification); const auto cubeEnd = globalLast.cube(state->cubeEdgeLength, state->magnification) + 1; CubeCoordSet cubeCoords; //traverse all remaining cubes for (int z = cubeBegin.z; z < cubeEnd.z; ++z) for (int y = cubeBegin.y; y < cubeEnd.y; ++y) for (int x = cubeBegin.x; x < cubeEnd.x; ++x) { skip(x, y, z);//skip cubes which got processed before const auto cubeCoord = CoordOfCube(x, y, z); const auto globalCubeBegin = cubeCoord.cube2Global(state->cubeEdgeLength, state->magnification); auto rawcube = getRawCube(globalCubeBegin); if (rawcube.first) { auto cubeRef = getCubeRef(rawcube.second); const auto globalCubeEnd = globalCubeBegin + state->cubeEdgeLength * state->magnification - 1; const auto localStart = globalFirst.capped(globalCubeBegin, globalCubeEnd).insideCube(state->cubeEdgeLength, state->magnification); const auto localEnd = globalLast.capped(globalCubeBegin, globalCubeEnd).insideCube(state->cubeEdgeLength, state->magnification); for (int z = localStart.z; z <= localEnd.z; ++z) for (int y = localStart.y; y <= localEnd.y; ++y) for (int x = localStart.x; x <= localEnd.x; ++x) { const Coordinate globalCoord{globalCubeBegin.x + x * state->magnification, globalCubeBegin.y + y * state->magnification, globalCubeBegin.z + z * state->magnification}; func(cubeRef[z][y][x], globalCoord); } cubeCoords.emplace(cubeCoord); } else { qCritical() << x << y << z << "cube missing for (partial) writeVoxels"; } } return cubeCoords; }
std::pair<bool, char *> getRawCube(const Coordinate & pos) { const auto posDc = pos.cube(state->cubeEdgeLength, state->magnification); state->protectCube2Pointer.lock(); auto rawcube = Coordinate2BytePtr_hash_get_or_fail(state->Oc2Pointer[int_log(state->magnification)], posDc); state->protectCube2Pointer.unlock(); return std::make_pair(rawcube != nullptr, rawcube); }
bool writeVoxel(const Coordinate & pos, const uint64_t value, bool isMarkChanged) { auto cubeIt = getRawCube(pos); if (Session::singleton().outsideMovementArea(pos) || !Segmentation::enabled || !cubeIt.first) { return false; } const auto inCube = pos.insideCube(state->cubeEdgeLength, state->magnification); getCubeRef(cubeIt.second)[inCube.z][inCube.y][inCube.x] = value; if (isMarkChanged) { Loader::Controller::singleton().markOcCubeAsModified(pos.cube(state->cubeEdgeLength, state->magnification), state->magnification); } return true; }