Commit a1c3df83 authored by Laurent Belcour's avatar Laurent Belcour

Debug of data2moments

Modification of the MERL importer
parent 24aee29f
......@@ -5,7 +5,9 @@ CONFIG *= static \
DESTDIR = ../build
QMAKE_CXXFLAGS += -std=c++0x -m64
unix{
QMAKE_CXXFLAGS += -std=c++0x -m64
}
HEADERS = args.h \
common.h \
......
......@@ -91,6 +91,9 @@ void params::to_cartesian(const double* invec, params::input intype,
break;
case params::RUSIN_TH_TD_PD:
half_to_cartesian(invec[0], 0.0, invec[1], invec[2], outvec);
#ifdef DEBUG
std::cout << outvec[2] << std::endl;
#endif
break;
case params::ISOTROPIC_TV_TL_DPHI:
classical_to_cartesian(invec[0], 0.0, invec[1], invec[2], outvec);
......@@ -202,6 +205,9 @@ void params::from_cartesian(const double* invec, params::input outtype,
outvec[1] = atan2(invec[0], invec[1]);
outvec[2] = acos(invec[5]);
outvec[3] = atan2(invec[3], invec[4]);
#ifdef DEBUG
std::cout << invec[2] << " - acos -> " << outvec[0] << std::endl;
#endif
break;
// 6D Parametrization
......
......@@ -201,7 +201,7 @@ class params
const double cost = cos(theta);
const double sint = sin(theta);
const double temp = cost * vec[0] + sint * vec[1];
const double temp = cost * vec[0] + sint * vec[1];
vec[1] = cost * vec[1] - sint * vec[0];
vec[0] = temp;
......@@ -214,9 +214,15 @@ class params
const double cost = cos(theta);
const double sint = sin(theta);
const double temp = cost * vec[1] + sint * vec[2];
const double temp = cost * vec[1] + sint * vec[2];
#ifdef DEBUG
std::cout << acos(vec[2]) << std::endl;
#endif
vec[2] = cost * vec[2] - sint * vec[1];
#ifdef DEBUG
std::cout << acos(vec[2]) << std::endl;
#endif
vec[1] = temp;
}
......
......@@ -207,12 +207,20 @@ void lookup_brdf_val(double* brdf, double theta_in, double fi_in,
std_coords_to_half_diff_coords(theta_in, fi_in, theta_out, fi_out,
theta_half, fi_half, theta_diff, fi_diff);
#ifdef DEBUG
std::cout << theta_in << ", " << fi_in << ", " << theta_out << ", " << fi_out << " -> ";
std::cout << theta_half << ", " << theta_diff << ", " << fi_diff << std::endl;
std::cout << std::endl;
#endif
// Testing the input domain
assert(theta_half >= 0.0); assert(theta_half <= 0.5*M_PI);
assert(theta_diff >= 0.0); assert(theta_diff <= 0.5*M_PI);
assert(fi_diff >= 0.0); assert(fi_diff <= 2.0*M_PI);
if(theta_half < 0.0 || theta_half > 0.5*M_PI ||
theta_diff < 0.0 || theta_diff > 0.5*M_PI ||
fi_diff > M_PI)
{
throw; //! \todo Add exception list
}
// Find index.
// Note that phi_half is ignored, since isotropic BRDFs are assumed
int ind = phi_diff_index(fi_diff) +
......@@ -224,10 +232,10 @@ void lookup_brdf_val(double* brdf, double theta_in, double fi_in,
green_val = brdf[ind + BRDF_SAMPLING_RES_THETA_H*BRDF_SAMPLING_RES_THETA_D*BRDF_SAMPLING_RES_PHI_D/2] * GREEN_SCALE;
blue_val = brdf[ind + BRDF_SAMPLING_RES_THETA_H*BRDF_SAMPLING_RES_THETA_D*BRDF_SAMPLING_RES_PHI_D] * BLUE_SCALE;
#ifdef DEBUG
if (red_val < 0.0 || green_val < 0.0 || blue_val < 0.0)
fprintf(stderr, "Negative value [%f, %f, %f].\n", theta_half, theta_diff, fi_diff);
#endif
}
// Read BRDF data
......@@ -350,7 +358,11 @@ vec data_merl::value(vec in) const
double r, g, b;
double t_in[4];
params::convert(&in[0], params::RUSIN_TH_TD_PD, params::SPHERICAL_TL_PL_TV_PV, t_in);
params::convert(&in[0], params::RUSIN_TH_TD_PD, params::SPHERICAL_TL_PL_TV_PV, &t_in[0]);
#ifdef DEBUG
std::cout << "[" << in[0] << ", " << in[1] << ", " << in[2] << "] -> [" << t_in[0] << ", " << t_in[1] << ", " << t_in[2] << ", " << t_in[3] << "]" << std::endl;
#endif
lookup_brdf_val(brdf, t_in[0], t_in[1], t_in[2], t_in[3], r, g, b) ;
vec res(3);
......
......@@ -55,47 +55,79 @@ int main(int argc, char** argv)
params::input data_param = d->parametrization();
int d_size = params::dimension(data_param);
int y_size = d->dimY();
double in_angle[4] = {0.0, 0.0, 0.0, 0.0} ;
// Sample every degree
double dtheta = 0.5*M_PI / 90.0;
// Moments
vec mean(d->dimY());
vec raw_mnt_0(d->dimY());
vec raw_mnt_1(d->dimY());
vec in_angle(4);
// Number of elements for the integration and reconstruction
// of the moment.
int nb_theta_in = 90;
int nb_theta_out = 90;
int nb_phi_out = 360;
int nb_phi_out = 360; // Bug here if there is a dense sampling of this domain
// Moments
vec raw_mnt_0(d->dimY());
vec raw_mnt_1(d->dimY());
vec raw_mnt_2(d->dimY());
vec raw_mnt_3(d->dimY());
double nb_elements = (double)(nb_phi_out*nb_theta_out);
double weight = M_PI*M_PI/nb_elements;
for(int theta_in=0; theta_in<nb_theta_in; theta_in++)
for(int theta_in=0; theta_in<nb_theta_in; ++theta_in)
{
in_angle[0] = theta_in * 0.5*M_PI / (double)nb_theta_in;
// Init value for mnts
for(int i=0; i<y_size; ++i)
{
raw_mnt_0[i] = 0.0;
raw_mnt_1[i] = 0.0;
raw_mnt_2[i] = 0.0;
raw_mnt_3[i] = 0.0;
}
// Integrate over the light hemisphere
for(int theta_out=0; theta_out<nb_theta_out; theta_out++)
for(int theta_out=0; theta_out<nb_theta_out; ++theta_out)
{
in_angle[2] = theta_out * 0.5*M_PI / (double)nb_theta_out;
for(int phi_out=0; phi_out<nb_phi_out; phi_out++)
{
in_angle[3] = phi_out * 2.0*M_PI / (double)nb_phi_out - M_PI;
for(int phi_out=0; phi_out<nb_phi_out; ++phi_out)
{
in_angle[3] = phi_out * 2.0*M_PI / (double)nb_phi_out;
//! \todo Do not compute like Pascal! It does not make sense to do moments
//! in the hemispherical parametrization. Use vectors instead (but they might
//! degenerate to zero).
double signed_theta_out = ((abs(in_angle[3]-M_PI) < 0.5*M_PI) ? -1.0 : 1.0) * in_angle[2];
// Change the parametrization from SPHERICAL to BRDF's param
vec in(d_size);
params::convert(&in_angle[0], params::SPHERICAL_TL_PL_TV_PV, data_param, &in[0]);
try
{
//std::cout << in_angle << std::endl;
params::convert(&in_angle[0], params::SPHERICAL_TL_PL_TV_PV, params::RUSIN_TH_TD_PD, &in[0]);
}
catch(...)
{
std::cout << "<<DEBUG>> error during conversion of " << in_angle << " to " << params::get_name(data_param) << std::endl;
return 1;
}
#ifdef DEBUG
std::cout << std::endl;
std::cout << in_angle << " -> " << in << std::endl;
#endif
// Copy the input vector
// Evaluate the BRDF
vec x = d->value(in);
double inv_pdf = 1.0 / cos(in_angle[1]);
for(int i=0; i<y_size; ++i)
{
raw_mnt_0[i] += x[i] * sin(in_angle[2]);
raw_mnt_1[i] += ((abs(in_angle[3]) < 0.5*M_PI) ? 1.0 : -1.0)*mean[i] * in_angle[2];
raw_mnt_0[i] += x[i] * cos(in_angle[1]) * weight;
raw_mnt_1[i] += raw_mnt_0[i] * signed_theta_out;
raw_mnt_2[i] += raw_mnt_1[i] * signed_theta_out;
raw_mnt_3[i] += raw_mnt_2[i] * signed_theta_out;
}
}
}
......@@ -103,8 +135,10 @@ int main(int argc, char** argv)
// Normalize and center the moments before export
for(int i=0; i<y_size; ++i)
{
raw_mnt_0[i] /= nb_elements;
raw_mnt_1[i] /= raw_mnt_0[i] * nb_elements;
raw_mnt_0[i] ;
raw_mnt_1[i] /= raw_mnt_0[i];
raw_mnt_2[i] /= raw_mnt_0[i];
raw_mnt_3[i] /= raw_mnt_0[i];
}
// Output the value into the file
......@@ -116,6 +150,12 @@ int main(int argc, char** argv)
for(int i=0; i<raw_mnt_1.size(); ++i)
file << raw_mnt_1[i] << "\t";
for(int i=0; i<raw_mnt_2.size(); ++i)
file << raw_mnt_2[i] << "\t";
for(int i=0; i<raw_mnt_3.size(); ++i)
file << raw_mnt_3[i] << "\t";
file << std::endl;
}
......
......@@ -54,9 +54,19 @@ int parametrization_tests()
// Params
int nb_tests_failed = 0;
// Test the rotation code
vec x(3);
x[0] = 0; x[1] = 0; x[2] = 1;
params::rotate_binormal(&x[0], 0.5*M_PI);
std::cout << "<<DEBUG>> x = " << x << std::endl;
params::rotate_binormal(&x[0], -0.5*M_PI);
std::cout << "<<DEBUG>> x = " << x << std::endl;
std::cout << "<<DEBUG>> acos(x[2]) = " << acos(x[2]) << std::endl;
// Test Rusinkevich parametrization
vec cart(6);
vec cart(6), spherical(4);
vec rusi(3);
// Equal directions test, when the PHI_D is ZERO
......@@ -76,5 +86,53 @@ int parametrization_tests()
}
// Pathological case when THETA_H and THETA_D are equal to
// PI/4 and PHI_D PI, the conversion seems to fail.
rusi[0] = 0.759218; rusi[1] = 0.759218; rusi[2] = 3.14159;
try
{
params::convert(&rusi[0], params::RUSIN_TH_TD_PD, params::SPHERICAL_TL_PL_TV_PV, &spherical[0]);
params::convert(&spherical[0], params::SPHERICAL_TL_PL_TV_PV, params::RUSIN_TH_TD_PD, &rusi[0]);
}
catch(...)
{
std::cout << "<<ERROR>> the conversion failed" << std::endl;
std::cout << "<<DEBUG>> rusin 3d: " << rusi << std::endl;
std::cout << "<<DEBUG>> cartesian: " << spherical << std::endl;
nb_tests_failed++;
}
std::cout << "<<DEBUG>> rusin 3d: " << rusi << std::endl;
std::cout << "<<DEBUG>> cartesian: " << spherical << std::endl;
std::cout << std::endl;
// Convert issue #1
vec cart2(6);
spherical[0] = 0; spherical[1] = 0; spherical[2] = 1.51844; spherical[3] = -2.96706;
params::convert(&spherical[0], params::SPHERICAL_TL_PL_TV_PV, params::CARTESIAN, &cart2[0]);
std::cout << "<<DEBUG>> spherical before: " << spherical << std::endl;
try
{
params::convert(&spherical[0], params::SPHERICAL_TL_PL_TV_PV, params::RUSIN_TH_TD_PD, &rusi[0]);
params::convert(&rusi[0], params::RUSIN_TH_TD_PD, params::SPHERICAL_TL_PL_TV_PV, &spherical[0]);
params::convert(&spherical[0], params::SPHERICAL_TL_PL_TV_PV, params::CARTESIAN, &cart[0]);
}
catch(...)
{
std::cout << "<<ERROR>> the conversion failed" << std::endl;
std::cout << "<<DEBUG>> rusin 3d: " << rusi << std::endl;
std::cout << "<<DEBUG>> spherical: " << spherical << std::endl;
nb_tests_failed++;
}
std::cout << "<<DEBUG>> rusin after: " << rusi << std::endl;
std::cout << "<<DEBUG>> spherical after: " << spherical << std::endl;
std::cout << "<<DEBUG>> " << cart << " / " << cart2 << std::endl;
{
double dot = cart[0]*cart[3] + cart[1]*cart[4] + cart[2]*cart[5];
double dot2 = cart2[0]*cart2[3] + cart2[1]*cart2[4] + cart2[2]*cart2[5];
std::cout << "<<DEBUG>> dot = " << dot << ", " << "dot2 = " << dot2 << std::endl;
}
std::cout << std::endl;
return nb_tests_failed;
}
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