1 // Copyright 2009-2020 Intel Corporation
2 // SPDX-License-Identifier: Apache-2.0
3
4 #include "rawToAMR.h"
5
6 static const std::string description = R"description(
7 Creates an adaptive mesh refinement (AMR) representation of the provided
8 structured volume data.
9
10 The input structured volume data is used as the highest refinement level
11 (i.e. the finest resolution data). From this level, data that does not meet
12 the user-provided variance threshold is discarded. The average of the
13 discarded block is used in the next level down.
14
15 This simulates the effect that an adaptive simulation would have created
16 regions of higher refinement in the highly varying portions of the volume.
17 )description";
18
19 static const std::string usage =
20 R"usage([-h | --help] input_volume variable_type x_dim y_dim z_dim num_levels
21 block_size refinement_factor threshold output_basename
22 )usage";
23
24 static const std::string help = R"help(
25 input_volume Structured volume in binary brick-of-data format
26 (string filepath)
27 variable_type Type of structured volume, must be exactly one of:
28 float
29 (string)
30 x_dim X dimensions of the structured volume grid (int)
31 y_dim Y dimensions of the structured volume grid (int)
32 z_dim Z dimensions of the structured volume grid (int)
33 num_levels Number of refinement levels to simulate (int)
34 block_size Size of blocks at each level in terms of cells. Blocks
35 are defined as cubes with this number of cells per edge.
36 Note that refinement levels change the width of the
37 cells, NOT the width of the blocks. Blocks will always
38 be this provided size in cell extents, but the width of
39 the cells will be smaller/larger depending on level.
40 For example, a block of 4x4x4 cells at the highest
41 refinement level will be converted into a single cell
42 at the next lower level, which would be part of that
43 level's block of 4x4x4 cells. (int)
44 refinement_factor How much larger/smaller, in terms of cell extents, each
45 level's grid will be. Note that this is independent of
46 block_size above! For example, if the input data is a
47 512^3 grid, and block_size is 4^3, the highest
48 refinement level will have a 128^3 block grid. If this
49 value is 2, the next level will have a 64^3 block grid,
50 but will still be comprised of 4^3 blocks. That is, the
51 number of cells decreases from 512^3 to 256^3, and the
52 cell width increases to accommodate. (int)
53 threshold Variance threshold used to determine whether a block
54 belongs to a higher refinement level. If the variance
55 within a block is above this threshold, it remains at
56 the current level. Otherwise, if the variance is low,
57 this block would have not have been selected for mesh
58 refinement by a numerical simulation, so this block is
59 discarded at this level. (variable_type, converted to
60 float)
61 output_basename Basename for the output files. This application creates
62 three files with different extensions, with this basename
63 in common. (string)
64 )help";
65
66 using namespace rkcommon::math;
67
68 static std::string inFileName;
69 static std::string format;
70 static vec3i inDims;
71 static int numLevels;
72 static int blockSize;
73 static int refinementLevel;
74 static float threshold;
75 static std::string outFileBase;
76
parseArguments(int argc,char ** argv)77 bool parseArguments(int argc, char **argv)
78 {
79 if (argc != 11) {
80 if (argc > 1
81 && (std::string(argv[1]) == "-h" || std::string(argv[1]) == "--help")) {
82 std::cerr << description << std::endl;
83 std::cerr << "Usage: " << argv[0] << " " << usage << std::endl;
84 std::cerr << help << std::endl;
85 } else {
86 std::cerr << argc - 1 << " argument"
87 << ((argc == 1 || argc > 2) ? "s " : " ");
88 std::cerr << "provided, but 10 are needed" << std::endl;
89 std::cerr << "Usage: " << argv[0] << " " << usage << std::endl;
90 }
91 return false;
92 }
93
94 inFileName = argv[1];
95 format = argv[2];
96 inDims.x = atoi(argv[3]);
97 inDims.y = atoi(argv[4]);
98 inDims.z = atoi(argv[5]);
99 numLevels = atoi(argv[6]);
100 blockSize = atoi(argv[7]);
101 refinementLevel = atoi(argv[8]);
102 threshold = atof(argv[9]);
103 outFileBase = argv[10];
104
105 return true;
106 }
107
main(int argc,char ** argv)108 int main(int argc, char **argv)
109 {
110 bool parseSucceed = parseArguments(argc, argv);
111 if (!parseSucceed) {
112 return 1;
113 }
114
115 // ALOK: TODO:
116 // support more than float
117 std::vector<float> in;
118 if (format == "float") {
119 in = ospray::amr::mmapRAW<float>(inFileName, inDims);
120 } else {
121 throw std::runtime_error("unsupported input voxel format");
122 }
123
124 std::vector<box3i> blockBounds;
125 std::vector<int> refinementLevels;
126 std::vector<float> cellWidths;
127 std::vector<std::vector<float>> brickData;
128
129 ospray::amr::makeAMR(in,
130 inDims,
131 numLevels,
132 blockSize,
133 refinementLevel,
134 threshold,
135 blockBounds,
136 refinementLevels,
137 cellWidths,
138 brickData);
139 ospray::amr::outputAMR(outFileBase,
140 blockBounds,
141 refinementLevels,
142 cellWidths,
143 brickData,
144 blockSize);
145
146 return 0;
147 }
148