Skip to content

Commit 0dfe85d

Browse files
committed
+Add a gridvolume generator utility
1 parent 277326f commit 0dfe85d

File tree

2 files changed

+196
-0
lines changed

2 files changed

+196
-0
lines changed

src/utils/SConscript

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
Import('env', 'plugins')
22

33
plugins += env.SharedLibrary('addimages', ['addimages.cpp'])
4+
plugins += env.SharedLibrary('genvolume', ['genvolume.cpp'])
45
plugins += env.SharedLibrary('joinrgb', ['joinrgb.cpp'])
56
plugins += env.SharedLibrary('cylclip', ['cylclip.cpp'])
67
plugins += env.SharedLibrary('kdbench', ['kdbench.cpp'])

src/utils/genvolume.cpp

Lines changed: 195 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,195 @@
1+
/*
2+
This file is part of Mitsuba, a physically based rendering system.
3+
4+
Copyright (c) 2007-2014 by Wenzel Jakob and others.
5+
6+
Mitsuba is free software; you can redistribute it and/or modify
7+
it under the terms of the GNU General Public License Version 3
8+
as published by the Free Software Foundation.
9+
10+
Mitsuba is distributed in the hope that it will be useful,
11+
but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13+
GNU General Public License for more details.
14+
15+
You should have received a copy of the GNU General Public License
16+
along with this program. If not, see <http://www.gnu.org/licenses/>.
17+
*/
18+
19+
#include <mitsuba/core/plugin.h>
20+
#include <mitsuba/core/bitmap.h>
21+
#include <mitsuba/core/fstream.h>
22+
#include <mitsuba/core/fresolver.h>
23+
#include <mitsuba/render/util.h>
24+
#if defined(WIN32)
25+
#include <mitsuba/core/getopt.h>
26+
#endif
27+
28+
29+
MTS_NAMESPACE_BEGIN
30+
31+
class GridDataSource {
32+
public:
33+
enum EVolumeType {
34+
EFloat32 = 1,
35+
EFloat16 = 2,
36+
EUInt8 = 3,
37+
EQuantizedDirections = 4
38+
};
39+
};
40+
41+
class GenerateVolumeDataSource : public Utility {
42+
public:
43+
44+
void help(){
45+
cout<<"Generates an input file for the `gridvolume` plugin"<<endl;
46+
cout<<"mtsutil genvolume [options] <filename>"<<endl;
47+
cout<<" -f Set the output format to Float32 (Default)"<<endl;
48+
cout<<" -i Set the output format to UInt8"<<endl;
49+
cout<<" -q Set the output format to QuantizedDirections (2xUInt8), overwrites channels"<<endl;
50+
cout<<" -c <channels> Set the number of channels (1 or 3), Default: 1"<<endl;
51+
cout<<" -v <value> Set the constant value of the volume, Default: 0.0f"<<endl;
52+
cout<<endl;
53+
cout<<" -b <xmin>,<ymin>,<zmin>,<xmax>,<ymax>,<zmax>"<<endl;
54+
cout<<" Defines the integer bounding box of the filled volume, Default: [0,0,0],[1,1,1]"<<endl;
55+
}
56+
57+
int run(int argc, char **argv) {
58+
ref<FileResolver> fileResolver = Thread::getThread()->getFileResolver();
59+
int optchar;
60+
char *end_ptr = NULL;
61+
62+
//init options with defaults
63+
GridDataSource::EVolumeType type = GridDataSource::EVolumeType::EFloat32;
64+
int channels = 1;
65+
TAABB<Point3i> bounds(Point3i(0),Point3i(1));
66+
Float value = 0.0f;
67+
68+
optind = 1;
69+
70+
/* Parse command-line arguments */
71+
while ((optchar = getopt(argc, argv, "hfiqc:v:b:")) != -1) {
72+
switch (optchar) {
73+
case 'h': {
74+
help();
75+
return 0;
76+
}
77+
break;
78+
case 'f': {
79+
type = GridDataSource::EVolumeType::EFloat32;
80+
}
81+
break;
82+
case 'i': {
83+
type = GridDataSource::EVolumeType::EUInt8;
84+
}
85+
break;
86+
case 'q': {
87+
type = GridDataSource::EVolumeType::EQuantizedDirections;
88+
}
89+
break;
90+
case 'c': {
91+
channels = strtol(optarg, &end_ptr,10);
92+
if (*end_ptr != '\0')
93+
SLog(EError, "Could not parse the channels argument!");
94+
}
95+
break;
96+
case 'v': {
97+
value = (Float) strtod(optarg, &end_ptr);
98+
if (*end_ptr != '\0')
99+
SLog(EError, "Could not parse the value argument!");
100+
}
101+
break;
102+
case 'b': {
103+
std::vector<std::string> tokens = tokenize(optarg, ", ");
104+
if (tokens.size() != 6)
105+
Log(EError, "Invalid number of bounding box parameters!");
106+
for (int i=0; i<3; ++i) {
107+
bounds.min[i] = std::strtol(tokens[i].c_str(), &end_ptr, 10);
108+
if (*end_ptr != '\0')
109+
Log(EError, "Cannot parse integer number "
110+
"in bounding box parameter!");
111+
}
112+
for (int i=3; i<6; ++i) {
113+
bounds.max[i-3] = std::strtol(tokens[i].c_str(), &end_ptr, 10);
114+
if (*end_ptr != '\0')
115+
Log(EError, "Cannot parse integer number "
116+
"in bounding box parameter!");
117+
}
118+
}
119+
break;
120+
};
121+
}
122+
123+
if (optind == argc || optind+1 < argc) {
124+
help();
125+
return 0;
126+
}
127+
if(type == GridDataSource::EVolumeType::EQuantizedDirections)
128+
channels = 2;
129+
else if(channels != 1 && channels != 3)
130+
Log(EError, "Invalid number of channels specified for data type. Please specify 1 or 3.");
131+
132+
133+
assert(bounds.isValid());
134+
135+
cout << bounds.toString().c_str() << endl;
136+
fs::path outputFile = fileResolver->resolve(argv[optind]);
137+
ref<FileStream> fs = new FileStream(outputFile, FileStream::ETruncWrite);
138+
139+
char header[] = {'V','O','L'};
140+
fs->write(&header, sizeof(header));
141+
142+
fs->writeChar(3);
143+
fs->writeInt(type);
144+
145+
int xres = (bounds.max.x - bounds.min.x)+1;
146+
int yres = (bounds.max.y - bounds.min.y)+1;
147+
int zres = (bounds.max.z - bounds.min.z)+1;
148+
fs->writeInt(xres);
149+
fs->writeInt(yres);
150+
fs->writeInt(zres);
151+
152+
fs->writeInt(channels);
153+
154+
fs->writeSingle(bounds.min.x);
155+
fs->writeSingle(bounds.min.y);
156+
fs->writeSingle(bounds.min.z);
157+
fs->writeSingle(bounds.max.x);
158+
fs->writeSingle(bounds.max.y);
159+
fs->writeSingle(bounds.max.z);
160+
161+
size_t size = xres * yres * zres * channels;
162+
void * data;
163+
164+
switch((GridDataSource::EVolumeType)type) {
165+
case GridDataSource::EVolumeType::EFloat32: {
166+
std::vector<float> vector(size, value);
167+
data = vector.data();
168+
size *= sizeof(float);
169+
}
170+
break;
171+
172+
case GridDataSource::EVolumeType::EQuantizedDirections:
173+
case GridDataSource::EVolumeType::EUInt8: {
174+
std::vector<unsigned char> vector(size, value);
175+
data = vector.data();
176+
size *= sizeof(unsigned char);
177+
}
178+
break;
179+
180+
default:
181+
Log(EError, "EVolumeType not supported");
182+
break;
183+
};
184+
185+
fs->write(data, size);
186+
fs->close();
187+
188+
return 0;
189+
}
190+
191+
MTS_DECLARE_UTILITY()
192+
};
193+
194+
MTS_EXPORT_UTILITY(GenerateVolumeDataSource, "Generate a constant volume for `gridvolume` plugin")
195+
MTS_NAMESPACE_END

0 commit comments

Comments
 (0)