Commit e00fba79 authored by Romain Pacanowski's avatar Romain Pacanowski

Merge branch 'fix-utia'

Remark: Some tests are still not fully automated.
parents 21c1f5ca ec7d0486
...@@ -43,6 +43,7 @@ class arguments ...@@ -43,6 +43,7 @@ class arguments
arguments() arguments()
{ {
} }
arguments(const arguments& args) : _map(args._map) {}
arguments(std::initializer_list<pair_type> lst) arguments(std::initializer_list<pair_type> lst)
: _map(lst) : _map(lst)
{ {
...@@ -517,7 +518,7 @@ class arguments ...@@ -517,7 +518,7 @@ class arguments
} }
private: // data protected: // data
std::map<std::string, std::string> _map ; std::map<std::string, std::string> _map ;
......
...@@ -506,12 +506,19 @@ ptr<data> plugins_manager::load_data(const std::string& file, ...@@ -506,12 +506,19 @@ ptr<data> plugins_manager::load_data(const std::string& file,
{ {
std::ifstream stream; std::ifstream stream;
// Create a temporary `arguments` object to pass information data
// to the newly created plugin. Some arguments are provided
// through the soft command. Here we only force the filename to
// be located at item "filename"
arguments n_args(args);
n_args.update("filename", file);
// Raise an exception when 'open' fails, and open in binary mode to // Raise an exception when 'open' fails, and open in binary mode to
// placate Windows. // placate Windows.
stream.exceptions(std::ios::failbit); stream.exceptions(std::ios::failbit);
stream.open(file.c_str(), std::ifstream::binary); stream.open(file.c_str(), std::ifstream::binary);
stream.exceptions(std::ios::goodbit); stream.exceptions(std::ios::goodbit);
ptr<data> result = load_data(type, stream, args); ptr<data> result = load_data(type, stream, n_args);
stream.close(); // FIXME: make it auto-close stream.close(); // FIXME: make it auto-close
return result; return result;
......
...@@ -169,7 +169,7 @@ class t_EXR_IO ...@@ -169,7 +169,7 @@ class t_EXR_IO
header.requested_pixel_types = (int *)malloc(sizeof(int) * header.num_channels); header.requested_pixel_types = (int *)malloc(sizeof(int) * header.num_channels);
for (int i = 0; i < header.num_channels; i++) { for (int i = 0; i < header.num_channels; i++) {
header.pixel_types[i] = TINYEXR_PIXELTYPE_FLOAT; // pixel type of input image header.pixel_types[i] = TINYEXR_PIXELTYPE_FLOAT; // pixel type of input image
header.requested_pixel_types[i] = TINYEXR_PIXELTYPE_HALF; // pixel type of output image to be stored in .EXR header.requested_pixel_types[i] = TINYEXR_PIXELTYPE_FLOAT; // pixel type of output image to be stored in .EXR
} }
const char* err; const char* err;
...@@ -187,4 +187,4 @@ class t_EXR_IO ...@@ -187,4 +187,4 @@ class t_EXR_IO
} }
}; };
typedef t_EXR_IO<float> EXR_IO ; typedef t_EXR_IO<float> EXR_IO ;
\ No newline at end of file
...@@ -151,7 +151,7 @@ public: // methods ...@@ -151,7 +151,7 @@ public: // methods
} }
void set(int i, const vec& x) { void set(int i, const vec& x) {
assert(x.size() == parametrization().dimX() + parametrization().dimY()); assert(x.size() == (parametrization().dimX() + parametrization().dimY()));
int iR = i; int iR = i;
int iG = iR + _nSlice; int iG = iR + _nSlice;
int iB = iG + _nSlice; int iB = iG + _nSlice;
......
...@@ -43,21 +43,42 @@ ALTA_DLL_EXPORT data* load_data(std::istream& input, const arguments& args); ...@@ -43,21 +43,42 @@ ALTA_DLL_EXPORT data* load_data(std::istream& input, const arguments& args);
/*! \ingroup datas /*! \ingroup datas
* \class data_utia * \class data_utia
* \brief Data interface for the [UTIA][utia] file format. * \brief Data importer/exporter for the [UTIA][utia] file format.
* [utia]: http://btf.utia.cas.cz/?brdf_dat_dwn * [utia]: http://btf.utia.cas.cz/?brdf_dat_dwn
* *
* \details * \details
* *
* This plugin enables to load any of the 150 measured anisotropic materials * This plugin enables to load any of the [150 measured anisotropic materials][utia]
* released by Filip et al. from the Czech Institute of Information Theory and * released by Filip et al. from the Czech Institute of Information Theory and
* Automation (UTIA). This format is an HDR image based format using OpenEXR * Automation (UTIA). This format is an HDR image based format using OpenEXR
* or a binary format if not available. The data is stored as an array of * or a binary format. The data is stored as an array of azimuth slices for
* azimuth slices for various elevation angles. * various elevation angles.
* *
* This format is not very dense (only 6 elevation angles per view/light * This format is not very dense (only 6 elevation angles per view/light
* direction) but is quite large. * direction) but the dataset contains many anisotropic samples.
* *
* \author Laurent Belcour <laurent.belcour@umontreal.ca> * This plugin is mostly provided to import UTIA files to the ALTA format.
* We recommend to convert this dataset to ALTA's internal format prior to
* fitting. This can be done using the following command:
*
* data2data --input [file] --in-data data_utia --output [file]
*
* Note that the plugin automatically detect if the file is EXR or binary
* using the filename extension. Do not change the extension's name in case
* of an OpenEXR file.
*
* Also, this plugin can be used to export to UTIA file format from ALTA's
* internal file format. This can be done using the following command:
*
* data2data --input [file] --in-data [interpolant] --output [file] --out-data data_utia
*
* Note that you will have to use an interpolant plugin to fill all the
* datapoints of this file format, or use splatting with a dense dataset.
* Otherwise, you will have blank data.
*
* [utia]: http://btf.utia.cas.cz/?brdf_dat_dwn
*
* \author Laurent Belcour <laurent.belcour@gmail.com>
* \author Original code from Jiri Filip * \author Original code from Jiri Filip
*/ */
class UTIA : public data { class UTIA : public data {
...@@ -84,10 +105,12 @@ public: ...@@ -84,10 +105,12 @@ public:
this->nPerPlane = N_PER_PLANE; this->nPerPlane = N_PER_PLANE;
this->Bd = new double[planes*nti*npi*ntv*npv]; this->Bd = new double[planes*nti*npi*ntv*npv];
_min = vec(4);
_min[0] = 0.0; _min[0] = 0.0;
_min[1] = 0.0; _min[1] = 0.0;
_min[2] = 0.0; _min[2] = 0.0;
_min[3] = 0.0; _min[3] = 0.0;
_max = vec(4);
_max[0] = 0.5*M_PI; _max[0] = 0.5*M_PI;
_max[1] = 2.0*M_PI; _max[1] = 2.0*M_PI;
_max[2] = 0.5*M_PI; _max[2] = 0.5*M_PI;
...@@ -108,7 +131,7 @@ public: ...@@ -108,7 +131,7 @@ public:
for(int i=0; i<H; ++i) for(int i=0; i<H; ++i)
for(int j=0; j<W; ++j){ for(int j=0; j<W; ++j){
int indexUTIA = i*W+j; int indexUTIA = i*W+j;
int indexEXR = (H-i-1)*W+j; int indexEXR = i*W+j;
temp[3*indexEXR + 0] = Bd[indexUTIA + 0*nPerPlane]; temp[3*indexEXR + 0] = Bd[indexUTIA + 0*nPerPlane];
temp[3*indexEXR + 1] = Bd[indexUTIA + 1*nPerPlane]; temp[3*indexEXR + 1] = Bd[indexUTIA + 1*nPerPlane];
temp[3*indexEXR + 2] = Bd[indexUTIA + 2*nPerPlane]; temp[3*indexEXR + 2] = Bd[indexUTIA + 2*nPerPlane];
...@@ -254,9 +277,9 @@ public: ...@@ -254,9 +277,9 @@ public:
wpv[0] /= sum; wpv[0] /= sum;
wpv[1] /= sum; wpv[1] /= sum;
if(ipi[1]==npi) if(ipi[1]==npi)
ipi[1] = 0; ipi[1] = 0;
if(ipv[1]==npv) if(ipv[1]==npv)
ipv[1] = 0; ipv[1] = 0;
int nc = npv*ntv; int nc = npv*ntv;
...@@ -268,15 +291,15 @@ public: ...@@ -268,15 +291,15 @@ public:
for(int k=0;k<2;k++) for(int k=0;k<2;k++)
for(int l=0;l<2;l++) for(int l=0;l<2;l++)
RGB[isp] += Bd[isp*nr*nc + nc*(npi*iti[i]+ipi[k]) + npv*itv[j]+ipv[l]] * wti[i] * wtv[j] * wpi[k] * wpv[l]; RGB[isp] += Bd[isp*nr*nc + nc*(npi*iti[i]+ipi[k]) + npv*itv[j]+ipv[l]] * wti[i] * wtv[j] * wpi[k] * wpv[l];
// RGB[isp] *= cos(theta_i/d2r);
} }
return RGB; return RGB;
} }
virtual void set(int i, const vec& x) { virtual void set(int i, const vec& x) {
assert(x.size() == parametrization().dimY()); assert(x.size() == (parametrization().dimX() + parametrization().dimY()));
const vec& y = x.tail(parametrization().dimY());
for(int isp=0; isp<planes; ++isp) { for(int isp=0; isp<planes; ++isp) {
Bd[isp*nPerPlane + i] = x[isp]; Bd[isp*nPerPlane + i] = y[isp];
} }
} }
...@@ -286,51 +309,43 @@ public: ...@@ -286,51 +309,43 @@ public:
ALTA_DLL_EXPORT data* provide_data(size_t size, const parameters& params, ALTA_DLL_EXPORT data* provide_data(size_t size, const parameters& params,
const arguments&) const arguments&)
{ {
return new UTIA(params); return new UTIA(alta::parameters(4, 3,
params::SPHERICAL_TL_PL_TV_PV,
params::RGB_COLOR));
} }
ALTA_DLL_EXPORT data* load_data(std::istream& input, const arguments& args) ALTA_DLL_EXPORT data* load_data(std::istream& input, const arguments& args)
{ {
#if 0 // FIXME: backport this UTIA* result = new UTIA(alta::parameters(4, 3,
/* If the file is an OpenEXR image */ params::SPHERICAL_TL_PL_TV_PV,
if(filename.substr(filename.find_last_of(".") + 1) == "exr") { params::RGB_COLOR));
double* temp;
int W, H; // Check the filename extension and perform the adequate loading depending
if(!t_EXR_IO<double>::LoadEXR(input, W, H, temp, 3) || W != npi*nti || H != ntv*npv) { // if it is an EXR file or a binary file.
std::cerr << "<<ERROR>> Unable to open file '" << filename << "'" << std::endl; std::string filename = args["filename"];
throw; if(filename.substr(filename.find_last_of(".") + 1) == "exr") {
// EXR data reading
} else { double *temp; int W, H;
/* Data copy */ t_EXR_IO<double>::LoadEXR(input, W, H, temp);
for(int i=0; i<H; ++i)
for(int j=0; j<W; ++j){ // Data copy
int indexUTIA = i*W+j; for(int i=0; i<H; ++i)
int indexEXR = (H-i-1)*W+j; for(int j=0; j<W; ++j){
Bd[indexUTIA + 0*nPerPlane] = temp[3*indexEXR + 0]; int indexUTIA = i*W+j;
Bd[indexUTIA + 1*nPerPlane] = temp[3*indexEXR + 1]; int indexEXR = i*W+j;
Bd[indexUTIA + 2*nPerPlane] = temp[3*indexEXR + 2]; result->Bd[indexUTIA + 0*N_PER_PLANE] = temp[3*indexEXR + 0];
} result->Bd[indexUTIA + 1*N_PER_PLANE] = temp[3*indexEXR + 1];
result->Bd[indexUTIA + 2*N_PER_PLANE] = temp[3*indexEXR + 2];
delete[] temp; }
} delete[] temp;
std::cout << "<<INFO>> Successfully read EXR BRDF file" << std::endl;
/* If the file is a binary */
} else } else {
#endif int count = result->planes * result->nti * result->npi
* result->ntv * result->npv;
UTIA* result = new UTIA(alta::parameters(0, 0, input.read((char*)result->Bd, count*sizeof(double));
params::UNKNOWN_INPUT, std::cout << "<<INFO>> Successfully read binary BRDF file" << std::endl;
params::UNKNOWN_OUTPUT)); }
int count = 0;
for(int isp=0; isp < result->planes; isp++) {
for(int ni=0; ni< result->nti * result->npi; ni++)
for(int nv=0; nv < result->ntv * result->npv; nv++) {
input >> result->Bd[count++];
}
}
std::cout << "<<INFO>> Successfully read BRDF" << std::endl;
return result; return result;
} }
...@@ -248,7 +248,7 @@ static void convert_with_interpolation(ptr<data> d_in, ptr<data> d_out) ...@@ -248,7 +248,7 @@ static void convert_with_interpolation(ptr<data> d_in, ptr<data> d_out)
// Check if the output configuration is below the hemisphere when // Check if the output configuration is below the hemisphere when
// converted to cartesian coordinates. Note that this prevent from // converted to cartesian coordinates. Note that this prevent from
// converting BTDF data. // converting BTDF data.
if(cart[2] >= 0.0 || cart[5] >= 0.0) { if(cart[2] >= 0.0 && cart[5] >= 0.0) {
params::convert(&cart[0], params::CARTESIAN, params::convert(&cart[0], params::CARTESIAN,
d_in->parametrization().input_parametrization(), d_in->parametrization().input_parametrization(),
&temp[0]); &temp[0]);
......
...@@ -455,6 +455,80 @@ if have_openexr: ...@@ -455,6 +455,80 @@ if have_openexr:
AlwaysBuild(cmd9) AlwaysBuild(cmd9)
env.Alias('tests', cmd9) env.Alias('tests', cmd9)
# if we have the m100_fabric140.exr we can verify that some conversions with UTIA DB are working
UTIA_TEST_FILE = test_byproduct('m100_fabric140.exr')
if os.path.isfile(UTIA_TEST_FILE):
cmd_utia_idempotence = make_command_test('data2data',
['--input',
test_byproduct('m100_fabric140.exr'),
'--in-data', 'data_utia',
'--out-data', 'data_merl',
'--output',
test_byproduct('m100_fabric140-3.exr')],
'data2data-utia-to-utia')
AlwaysBuild(cmd_utia_idempotence);
env.Alias('tests', cmd_utia_idempotence)
cmd_utia_1 = make_command_test('data2data',
['--input',
test_byproduct('m100_fabric140.exr'),
'--in-data', 'data_utia',
'--out-data', 'data_merl',
'--output',
test_byproduct('m100_fabric140.binary')],
'data2data-utia-to-merl')
AlwaysBuild(cmd_utia_1);
env.Alias('tests', cmd_utia_1)
cmd_utia_2 = make_command_test('data2data',
['--input',
test_byproduct('m100_fabric140.binary'),
'--in-data', 'data_merl',
'--out-data', 'data_utia',
'--output',
test_byproduct('m100_fabric140-2.exr')],
'data2data-merl-to-utia')
AlwaysBuild(cmd_utia_2);
env.Depends(cmd_utia_2, cmd_utia_1)
env.Alias('tests', cmd_utia_2)
cmd_utia_check = make_command_test('data2stats',
['--input',
test_byproduct('m100_fabric140-2.exr'),
'--in-data', 'data_utia',
'--ref',
test_byproduct('m100_fabric140.exr'),
'--ref-data', 'data_utia'],
'data2stats-utia-check');
AlwaysBuild(cmd_utia_check);
env.Depends(cmd_utia_check, cmd_utia_2)
env.Alias('tests', cmd_utia_check)
#TODO PARSE THE OUTPUT of cmd_utia_check to see of the Linf norm is < 1e-5 if yes test passes
# if not test fails
#
#log_output_directory = Dir('#build/sources/tests').abspath
# log_file = File(log_output_directory + os.sep + 'data2stats.data2stats-utia-check.log').abspath
# file_as_string = open(log_file, 'r').read()
# per_lines = file_as_string.split('<<INFO>>')
# index = [i for i,x in enumerate(per_lines) if x.startswith(' Linf_norm')]
# line_inf = per_lines[index[0]].split(' ')
#end_if UTIA No-Regression TEST
else:
print "<<<WARNING>>> COULD NOT FIND m100_fabric140.exr !!! "
print "<<<ERROR>>> Download and put the file in:" + test_output_directory
#end_if_else
if have_nonlinear_fitter_eigen: if have_nonlinear_fitter_eigen:
cmd10 = make_command_test('data2brdf', cmd10 = make_command_test('data2brdf',
['--input', ['--input',
...@@ -478,11 +552,16 @@ if have_openexr: ...@@ -478,11 +552,16 @@ if have_openexr:
'--data', 'vertical_segment'], '--data', 'vertical_segment'],
'compound-function-to-vs') 'compound-function-to-vs')
env.Depends(cmd11, cmd10) env.Depends(cmd11, cmd10)
env.Depends(cmd11, cmd9) # DO NOT SEE WHY cmd11 should depend cmd9
#env.Depends(cmd11, cmd9)
env.Depends(cmd11, cmd6) env.Depends(cmd11, cmd6)
AlwaysBuild(cmd11) AlwaysBuild(cmd11)
env.Alias('tests', cmd11) env.Alias('tests', cmd11)
#end_of_if_have_exr
cmd20 = make_command_test('data2data', cmd20 = make_command_test('data2data',
['--input', ['--input',
test_byproduct('krylon_blue_RGB.astm'), test_byproduct('krylon_blue_RGB.astm'),
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment