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
arguments()
{
}
arguments(const arguments& args) : _map(args._map) {}
arguments(std::initializer_list<pair_type> lst)
: _map(lst)
{
......@@ -517,7 +518,7 @@ class arguments
}
private: // data
protected: // data
std::map<std::string, std::string> _map ;
......
......@@ -506,12 +506,19 @@ ptr<data> plugins_manager::load_data(const std::string& file,
{
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
// placate Windows.
stream.exceptions(std::ios::failbit);
stream.open(file.c_str(), std::ifstream::binary);
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
return result;
......
......@@ -169,7 +169,7 @@ class t_EXR_IO
header.requested_pixel_types = (int *)malloc(sizeof(int) * header.num_channels);
for (int i = 0; i < header.num_channels; i++) {
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;
......@@ -187,4 +187,4 @@ class t_EXR_IO
}
};
typedef t_EXR_IO<float> EXR_IO ;
\ No newline at end of file
typedef t_EXR_IO<float> EXR_IO ;
......@@ -151,7 +151,7 @@ public: // methods
}
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 iG = iR + _nSlice;
int iB = iG + _nSlice;
......
......@@ -43,21 +43,42 @@ ALTA_DLL_EXPORT data* load_data(std::istream& input, const arguments& args);
/*! \ingroup datas
* \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
*
* \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
* 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
* azimuth slices for various elevation angles.
* or a binary format. The data is stored as an array of azimuth slices for
* various elevation angles.
*
* 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
*/
class UTIA : public data {
......@@ -84,10 +105,12 @@ public:
this->nPerPlane = N_PER_PLANE;
this->Bd = new double[planes*nti*npi*ntv*npv];
_min = vec(4);
_min[0] = 0.0;
_min[1] = 0.0;
_min[2] = 0.0;
_min[3] = 0.0;
_max = vec(4);
_max[0] = 0.5*M_PI;
_max[1] = 2.0*M_PI;
_max[2] = 0.5*M_PI;
......@@ -108,7 +131,7 @@ public:
for(int i=0; i<H; ++i)
for(int j=0; j<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 + 1] = Bd[indexUTIA + 1*nPerPlane];
temp[3*indexEXR + 2] = Bd[indexUTIA + 2*nPerPlane];
......@@ -254,9 +277,9 @@ public:
wpv[0] /= sum;
wpv[1] /= sum;
if(ipi[1]==npi)
if(ipi[1]==npi)
ipi[1] = 0;
if(ipv[1]==npv)
if(ipv[1]==npv)
ipv[1] = 0;
int nc = npv*ntv;
......@@ -268,15 +291,15 @@ public:
for(int k=0;k<2;k++)
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] *= cos(theta_i/d2r);
}
return RGB;
}
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) {
Bd[isp*nPerPlane + i] = x[isp];
Bd[isp*nPerPlane + i] = y[isp];
}
}
......@@ -286,51 +309,43 @@ public:
ALTA_DLL_EXPORT data* provide_data(size_t size, const parameters& params,
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)
{
#if 0 // FIXME: backport this
/* If the file is an OpenEXR image */
if(filename.substr(filename.find_last_of(".") + 1) == "exr") {
double* temp;
int W, H;
if(!t_EXR_IO<double>::LoadEXR(input, W, H, temp, 3) || W != npi*nti || H != ntv*npv) {
std::cerr << "<<ERROR>> Unable to open file '" << filename << "'" << std::endl;
throw;
} else {
/* Data copy */
for(int i=0; i<H; ++i)
for(int j=0; j<W; ++j){
int indexUTIA = i*W+j;
int indexEXR = (H-i-1)*W+j;
Bd[indexUTIA + 0*nPerPlane] = temp[3*indexEXR + 0];
Bd[indexUTIA + 1*nPerPlane] = temp[3*indexEXR + 1];
Bd[indexUTIA + 2*nPerPlane] = temp[3*indexEXR + 2];
}
delete[] temp;
}
/* If the file is a binary */
} else
#endif
UTIA* result = new UTIA(alta::parameters(0, 0,
params::UNKNOWN_INPUT,
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;
UTIA* result = new UTIA(alta::parameters(4, 3,
params::SPHERICAL_TL_PL_TV_PV,
params::RGB_COLOR));
// Check the filename extension and perform the adequate loading depending
// if it is an EXR file or a binary file.
std::string filename = args["filename"];
if(filename.substr(filename.find_last_of(".") + 1) == "exr") {
// EXR data reading
double *temp; int W, H;
t_EXR_IO<double>::LoadEXR(input, W, H, temp);
// Data copy
for(int i=0; i<H; ++i)
for(int j=0; j<W; ++j){
int indexUTIA = i*W+j;
int indexEXR = i*W+j;
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;
std::cout << "<<INFO>> Successfully read EXR BRDF file" << std::endl;
} else {
int count = result->planes * result->nti * result->npi
* result->ntv * result->npv;
input.read((char*)result->Bd, count*sizeof(double));
std::cout << "<<INFO>> Successfully read binary BRDF file" << std::endl;
}
return result;
}
......@@ -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
// converted to cartesian coordinates. Note that this prevent from
// 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,
d_in->parametrization().input_parametrization(),
&temp[0]);
......
......@@ -455,6 +455,80 @@ if have_openexr:
AlwaysBuild(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:
cmd10 = make_command_test('data2brdf',
['--input',
......@@ -478,11 +552,16 @@ if have_openexr:
'--data', 'vertical_segment'],
'compound-function-to-vs')
env.Depends(cmd11, cmd10)
env.Depends(cmd11, cmd9)
# DO NOT SEE WHY cmd11 should depend cmd9
#env.Depends(cmd11, cmd9)
env.Depends(cmd11, cmd6)
AlwaysBuild(cmd11)
env.Alias('tests', cmd11)
#end_of_if_have_exr
cmd20 = make_command_test('data2data',
['--input',
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