| 172 | } |
| 173 | |
| 174 | VolumeBrick makeLocalVolume(const int mpiRank, const int mpiWorldSize) |
| 175 | { |
| 176 | const vec3i grid = computeGrid(mpiWorldSize); |
| 177 | const vec3i brickId(mpiRank % grid.x, |
| 178 | (mpiRank / grid.x) % grid.y, |
| 179 | mpiRank / (grid.x * grid.y)); |
| 180 | // The bricks are 64^3 + 1 layer of ghost voxels on each axis |
| 181 | const vec3i brickVolumeDims = vec3i(32); |
| 182 | const vec3i brickGhostDims = vec3i(brickVolumeDims + 2); |
| 183 | |
| 184 | // The grid is over the [0, grid * brickVolumeDims] box |
| 185 | worldBounds = box3f(vec3f(0.f), vec3f(grid * brickVolumeDims)); |
| 186 | const vec3f brickLower = brickId * brickVolumeDims; |
| 187 | const vec3f brickUpper = brickId * brickVolumeDims + brickVolumeDims; |
| 188 | |
| 189 | VolumeBrick brick; |
| 190 | brick.bounds = box3f(brickLower, brickUpper); |
| 191 | // we just put ghost voxels on all sides here, but a real application |
| 192 | // would change which faces of each brick have ghost voxels dependent |
| 193 | // on the actual data |
| 194 | brick.ghostBounds = box3f(brickLower - vec3f(1.f), brickUpper + vec3f(1.f)); |
| 195 | |
| 196 | brick.brick = cpp::Volume("structuredRegular"); |
| 197 | |
| 198 | brick.brick.setParam("dimensions", brickGhostDims); |
| 199 | |
| 200 | // we use the grid origin to place this brick in the right position inside |
| 201 | // the global volume |
| 202 | brick.brick.setParam("gridOrigin", brick.ghostBounds.lower); |
| 203 | |
| 204 | // generate the volume data to just be filled with this rank's id |
| 205 | const size_t nVoxels = brickGhostDims.x * brickGhostDims.y * brickGhostDims.z; |
| 206 | std::vector<uint8_t> volumeData(nVoxels, static_cast<uint8_t>(mpiRank)); |
| 207 | brick.brick.setParam("data", |
| 208 | cpp::CopiedData(static_cast<const uint8_t *>(volumeData.data()), |
| 209 | vec3ul(brickVolumeDims))); |
| 210 | |
| 211 | brick.brick.commit(); |
| 212 | |
| 213 | brick.model = cpp::VolumetricModel(brick.brick); |
| 214 | cpp::TransferFunction tfn("piecewiseLinear"); |
| 215 | std::vector<vec3f> colors = {vec3f(0.f, 0.f, 1.f), vec3f(1.f, 0.f, 0.f)}; |
| 216 | std::vector<float> opacities = {0.05f, 1.f}; |
| 217 | |
| 218 | tfn.setParam("color", cpp::CopiedData(colors)); |
| 219 | tfn.setParam("opacity", cpp::CopiedData(opacities)); |
| 220 | // color the bricks by their rank, we pad the range out a bit to keep |
| 221 | // any brick from being completely transparent |
| 222 | range1f valueRange = range1f(0, mpiWorldSize); |
| 223 | tfn.setParam("value", valueRange); |
| 224 | tfn.commit(); |
| 225 | brick.model.setParam("transferFunction", tfn); |
| 226 | brick.model.setParam("samplingRate", 0.5f); |
| 227 | brick.model.commit(); |
| 228 | |
| 229 | brick.group = cpp::Group(); |
| 230 | brick.group.setParam("volume", cpp::CopiedData(brick.model)); |
| 231 | brick.group.commit(); |
no test coverage detected