67std::vector<View3D<T>>
split_grid(View3D<T> grid,
const SplitGridOptions& options)
69 const size_t grid_width = grid.extent(0);
70 const size_t grid_height = grid.extent(1);
71 const size_t num_channels = grid.extent(2);
72 const size_t num_cells = options.num_cells;
75 auto resolve = [&]() -> std::pair<size_t, size_t> {
76 if (options.rows != 0 && options.cols != 0) {
77 return {options.rows, options.cols};
79 if (options.rows != 0) {
81 num_cells % options.rows == 0,
83 "Number of cells ({}) is not divisible by rows ({})",
86 return {options.rows, num_cells / options.rows};
88 if (options.cols != 0) {
90 num_cells % options.cols == 0,
92 "Number of cells ({}) is not divisible by cols ({})",
95 return {num_cells / options.cols, options.cols};
99 double best_aspect_diff = std::numeric_limits<double>::max();
100 for (
size_t cols = 1; cols <= num_cells; ++cols) {
101 if (num_cells % cols != 0)
continue;
102 size_t rows = num_cells / cols;
103 if (grid_width % cols != 0 || grid_height % rows != 0)
continue;
104 size_t cell_w = grid_width / cols;
105 size_t cell_h = grid_height / rows;
106 double aspect_diff = std::abs(
static_cast<double>(cell_w) / cell_h - 1.0);
107 if (aspect_diff < best_aspect_diff) {
108 best_aspect_diff = aspect_diff;
116 "Cannot evenly divide grid image ({}x{}) into {} cells",
120 return {best_rows, best_cols};
123 auto [rows, cols] = resolve();
125 rows * cols == num_cells,
127 "Layout {}x{} does not match number of cells ({})",
132 grid_width % cols == 0 && grid_height % rows == 0,
134 "Grid image ({}x{}) is not divisible by layout ({}x{})",
140 const size_t cell_width = grid_width / cols;
141 const size_t cell_height = grid_height / rows;
143 std::vector<View3D<T>> views;
144 views.reserve(num_cells);
145 const dextents<size_t, 3> cell_shape{cell_width, cell_height, num_channels};
146 const std::array<size_t, 3> cell_strides{grid.stride(0), grid.stride(1), grid.stride(2)};
147 const layout_stride::mapping<dextents<size_t, 3>> cell_mapping{cell_shape, cell_strides};
148 for (
size_t row = 0; row < rows; ++row) {
149 for (
size_t col = 0; col < cols; ++col) {
150 T* cell_ptr = &grid(col * cell_width, row * cell_height, 0);
151 views.emplace_back(cell_ptr, cell_mapping);