Commit 7b3a6569 authored by Laurent Belcour's avatar Laurent Belcour

Merge

parents 3e9e956e 295c7e51
......@@ -157,6 +157,8 @@ unsigned int timer::current_time() const
SYSTEMTIME res;
GetSystemTime(&res);
return (unsigned int)(res.wSecond + res.wMinute*60 + res.wHour*360);
#elif __APPLE__
return 0;
#else
struct timespec res;
clock_gettime(CLOCK_MONOTONIC, &res);
......
......@@ -145,10 +145,17 @@ double function::L2_distance(const data* d) const
{
vec dat = d->get(i);
vec x(dimX()), y(d->dimY());
params::convert(&dat[0], d->input_parametrization(), input_parametrization(), &x[0]);
for(int j=0; j<d->dimY(); ++j) { y[j] = dat[d->dimX()+j]; }
//linf_dist = std::max<double>(linf_dist, std::abs<double>(norm(y-rj->value(dat))));
if(input_parametrization() == params::UNKNOWN_INPUT)
{
memcpy(&x[0], &dat[0], dimX()*sizeof(double));
}
else
{
params::convert(&dat[0], d->input_parametrization(), input_parametrization(), &x[0]);
}
memcpy(&y[0], &dat[d->dimX()], dimY()*sizeof(double));
l2_dist += std::pow(norm(y-value(x)), 2);
}
l2_dist = std::sqrt(l2_dist / d->size());
......@@ -158,17 +165,53 @@ double function::L2_distance(const data* d) const
//! \brief Linf norm to data.
double function::Linf_distance(const data* d) const
{
vec mean(dimY()), var(dimY());
double linf_dist = 0.0;
for(int i=0; i<d->size(); ++i)
{
vec dat = d->get(i);
vec x(dimX()), y(d->dimY());
params::convert(&dat[0], d->input_parametrization(), input_parametrization(), &x[0]);
for(int j=0; j<d->dimY(); ++j) { y[j] = dat[d->dimX()+j]; }
if(input_parametrization() == params::UNKNOWN_INPUT)
{
memcpy(&x[0], &dat[0], dimX()*sizeof(double));
}
else
{
params::convert(&dat[0], d->input_parametrization(), input_parametrization(), &x[0]);
}
memcpy(&y[0], &dat[d->dimX()], dimY()*sizeof(double));
linf_dist = std::max<double>(linf_dist, std::abs(norm(y-value(x))));
mean += (y-value(x)) / double(d->size());
}
for(int i=0; i<d->size(); ++i)
{
vec dat = d->get(i);
vec x(dimX()), y(d->dimY()), val(dimY());
if(input_parametrization() == params::UNKNOWN_INPUT)
{
memcpy(&x[0], &dat[0], dimX()*sizeof(double));
}
else
{
params::convert(&dat[0], d->input_parametrization(), input_parametrization(), &x[0]);
}
memcpy(&y[0], &dat[d->dimX()], dimY()*sizeof(double));
val = value(x);
for(int j=0; j<d->dimY(); ++j)
{
y[j] = dat[d->dimX()+j];
var[j] += pow(mean[j] - (val[j]-y[j]), 2) / double(d->size());
}
}
std::cout << "<<INFO>> Mean = " << mean << ", Var = " << var << std::endl;
return linf_dist;
}
......@@ -735,7 +778,7 @@ product_function::product_function(nonlinear_function* g1, nonlinear_function* g
}
else
{
setParametrization(g1->input_parametrization());
function::setParametrization(g1->input_parametrization());
function::setDimX(g1->dimX());
}
}
......@@ -767,7 +810,7 @@ vec product_function::value(const vec& x) const
bool product_function::load(std::istream& in)
{
bool loaded_f1,loaded_f2;
bool loaded_f1 = false,loaded_f2 = false;
std::streampos pos = in.tellg();
// Load the first function
......
......@@ -140,18 +140,18 @@ void params::to_cartesian(const double* invec, params::input intype,
const double theta = sqrt(invec[1]*invec[1] + invec[2]*invec[2]);
if(theta > 0.0)
{
outvec[3] = (invec[1]/theta)*sin(theta);
outvec[4] = (invec[2]/theta)*sin(theta);
outvec[0] = (invec[1]/theta)*sin(theta);
outvec[1] = (invec[2]/theta)*sin(theta);
}
else
{
outvec[3] = 0.0;
outvec[4] = 0.0;
outvec[0] = 0.0;
outvec[1] = 0.0;
}
outvec[5] = cos(theta);
outvec[0] = sin(invec[0]);
outvec[1] = 0.0;
outvec[2] = cos(invec[0]);
outvec[2] = cos(theta);
outvec[3] = sin(invec[0]);
outvec[4] = 0.0;
outvec[5] = cos(invec[0]);
}
break;
......@@ -161,12 +161,12 @@ void params::to_cartesian(const double* invec, params::input intype,
break;
case params::SPHERICAL_TL_PL_TV_PV:
outvec[0] = cos(invec[1])*sin(invec[0]);
outvec[1] = sin(invec[1])*sin(invec[0]);
outvec[2] = cos(invec[0]);
outvec[3] = cos(invec[3])*sin(invec[2]);
outvec[4] = sin(invec[3])*sin(invec[2]);
outvec[5] = cos(invec[2]);
outvec[0] = cos(invec[3])*sin(invec[2]);
outvec[1] = sin(invec[3])*sin(invec[2]);
outvec[2] = cos(invec[2]);
outvec[3] = cos(invec[1])*sin(invec[0]);
outvec[4] = sin(invec[1])*sin(invec[0]);
outvec[5] = cos(invec[0]);
break;
case params::STEREOGRAPHIC:
......@@ -274,7 +274,7 @@ void params::from_cartesian(const double* invec, params::input outtype,
case params::ISOTROPIC_TV_TL_DPHI:
outvec[0] = acos(invec[2]);
outvec[1] = acos(invec[5]);
outvec[2] = atan2(invec[1], invec[0]) - atan2(invec[4], invec[3]);
outvec[2] = atan2(invec[4], invec[3]) - atan2(invec[1], invec[0]);
break;
case params::RUSIN_VH:
outvec[0] = half[0];
......@@ -283,9 +283,9 @@ void params::from_cartesian(const double* invec, params::input outtype,
break;
case params::SCHLICK_VK:
{
const double Kx = invec[0]-invec[3];
const double Ky = invec[1]-invec[4];
const double Kz = invec[2]-invec[5];
const double Kx = invec[3]-invec[0];
const double Ky = invec[4]-invec[1];
const double Kz = invec[5]+invec[2];
const double norm = sqrt(Kx*Kx + Ky*Ky + Kz*Kz);
if(norm > 1.0E-10)
......@@ -304,9 +304,9 @@ void params::from_cartesian(const double* invec, params::input outtype,
break;
case ISOTROPIC_TL_TV_PROJ_DPHI:
{
const double theta_l = acos(invec[2]);
const double theta_v = acos(invec[5]);
const double dphi = atan2(invec[1], invec[0]) - atan2(invec[4], invec[3]);
const double theta_l = acos(invec[5]);
const double theta_v = acos(invec[2]);
const double dphi = atan2(invec[4], invec[3]) - atan2(invec[1], invec[0]);
outvec[0] = theta_l;
outvec[1] = theta_v * cos(dphi);
outvec[2] = theta_v * sin(dphi);
......@@ -330,10 +330,10 @@ void params::from_cartesian(const double* invec, params::input outtype,
break;
case params::SPHERICAL_TL_PL_TV_PV:
outvec[0] = acos(invec[2]);
outvec[1] = atan2(invec[1], invec[0]);
outvec[2] = acos(invec[5]);
outvec[3] = atan2(invec[4], invec[3]);
outvec[0] = acos(invec[5]);
outvec[1] = atan2(invec[4], invec[3]);
outvec[2] = acos(invec[2]);
outvec[3] = atan2(invec[1], invec[0]);
#ifdef DEBUG
std::cout << invec[2] << " - acos -> " << outvec[0] << std::endl;
#endif
......@@ -362,7 +362,7 @@ void params::from_cartesian(const double* invec, params::input outtype,
break;
default:
std::cerr << "<<ERROR>> Transformation not implemented, " << get_name(outtype) << " " << __FILE__ << ":" << __LINE__ << std::endl;
std::cerr << "<<ERROR>> Transformation not implemented, n°" << outtype << ", " << __FILE__ << ":" << __LINE__ << std::endl;
assert(false);
break;
}
......@@ -390,7 +390,9 @@ std::string params::get_name(const params::input param)
return it->second.name;
}
std::cerr << "<<ERROR>> Unknown parametrization, " << get_name(param) << " " << __FILE__ << ":" << __LINE__ << std::endl;
#ifdef DEBUG
std::cerr << "<<WARNING>> Unknown parametrization, n°" << param << ", "<< __FILE__ << ":" << __LINE__ << std::endl;
#endif
return std::string("UNKNOWN_INPUT");
}
......
......@@ -57,6 +57,7 @@ class params
STEREOGRAPHIC, /*!< Stereographic projection of the Light and View vectors */
SPHERICAL_TL_PL_TV_PV, /*!< Light and View vectors represented in spherical coordinates */
ISOTROPIC_TV_TL, /*!< Light and View vectors represented in spherical coordinates, */
ISOTROPIC_TV_TL_DPHI, /*!< Light and View vectors represented in spherical coordinates,
with the difference of azimutal coordinates in the last component */
ISOTROPIC_TV_PROJ_DPHI,/*!< 2D Parametrization where the phi component is projected.
......@@ -67,7 +68,13 @@ class params
\theta_v \sin(\Delta\phi).\f$]*/
ISOTROPIC_TD_PD, /*!< Difference between two directions such as R and H */
CARTESIAN, /*!< Light and View vectors represented in cartesian coordinates */
BARYCENTRIC_ALPHA_SIGMA, /*!< Barycentric parametrization defined in Stark et alL [2004].
Coordinates are: \f$[\alpha, \sigma] = [{1\over 2}(1 - \vec{l}\vec{v}),
(1-(\vec{h}.\vec{n})^2)(1 - \alpha)]\f$ */
CARTESIAN, /*!< View and Light vectors represented in cartesian coordinates.
We always pack the view vector first: \f$\vec{c} = [v.x, v.y,
v.z, l.x, l.y, l.z] \f$*/
UNKNOWN_INPUT /*!< Default behaviour. Only use this is you do not fit BRDF data */
};
......
......@@ -478,6 +478,11 @@ size_t plugins_manager::get_system_memory()
GlobalMemoryStatusEx(&status);
return status.ullTotalPhys;
}
#elif __APPLE__
size_t plugins_manager::get_system_memory()
{
return 0;
}
#else
#include <unistd.h>
size_t plugins_manager::get_system_memory()
......
......@@ -5,6 +5,7 @@ SConscript('data_interpolant/SConscript')
# Building fitters
SConscript('nonlinear_fitter_ceres/SConscript')
SConscript('rational_fitter_eigen/SConscript')
SConscript('rational_fitter_quadprog/SConscript')
# Building functions
......
......@@ -26,12 +26,12 @@ vec retro_schlick::value(const vec& x) const
params::convert(&x[0], input_parametrization(), params::SCHLICK_VK, xp);
params::convert(&x[0], input_parametrization(), params::CARTESIAN, cart);
const double dotRK = xp[0]*cart[0] + xp[1]*cart[1] + xp[2]*cart[2];
const double dotRK = xp[2]*cart[2] - (xp[0]*cart[0] + xp[1]*cart[1]) ;
vec res(_nY);
for(int i=0; i<_nY; ++i)
{
res[i] = R[i] + (1.0 - R[i]) * pow(1.0 - clamp(dotRK, 0.0, 1.0), 5.0);
res[i] = R[i] + (1.0 - R[i]) * (pow(1.0 - dotRK, 5.0));
}
return res;
......@@ -66,7 +66,7 @@ vec retro_schlick::parametersJacobian(const vec& x) const
params::convert(&x[0], input_parametrization(), params::SCHLICK_VK, xp);
params::convert(&x[0], input_parametrization(), params::CARTESIAN, cart);
const double dotRK = xp[0]*cart[0] + xp[1]*cart[1] + xp[2]*cart[2];
const double dotRK = xp[2]*cart[2] - (xp[0]*cart[0] + xp[1]*cart[1]) ;
vec jac(nbParameters()*nY);
for(int i=0; i<nY; ++i)
......@@ -74,7 +74,7 @@ vec retro_schlick::parametersJacobian(const vec& x) const
{
if(i == j)
{
jac[i*nY + j] = 1.0 - pow(1.0 - clamp(dotRK, 0.0, 1.0), 5.0);
jac[i*nY + j] = 1.0 - (pow(1.0 - dotRK, 5.0));
}
else
{
......
......@@ -191,14 +191,16 @@ bool beckmann_function::load(std::istream& in)
if(token.compare("#FUNC") != 0)
{
std::cerr << "<<ERROR>> parsing the stream. The #FUNC is not the next line defined." << std::endl;
return false;
std::cerr << "<<ERROR>> got \"" << token << "\" instead." << std::endl;
return false;
}
in >> token;
if(token.compare("nonlinear_function_beckmann") != 0)
{
std::cerr << "<<ERROR>> parsing the stream. function name is not the next token." << std::endl;
return false;
std::cerr << "<<ERROR>> got \"" << token << "\" instead." << std::endl;
return false;
}
// Parse the lobe
......
......@@ -192,14 +192,24 @@ bool beckmann_function::load(std::istream& in)
if(token.compare("#FUNC") != 0)
{
std::cerr << "<<ERROR>> parsing the stream. The #FUNC is not the next line defined." << std::endl;
return false;
std::cerr << "<<ERROR>> got \"" << token << "\" instead." << std::endl;
return false;
}
in >> token;
if(token.compare("nonlinear_function_retrobeckmann") != 0)
{
std::cerr << "<<ERROR>> parsing the stream. function name is not the next token." << std::endl;
std::cerr << "<<ERROR>> got \"" << token << "\" instead." << std::endl;
return false;
}
in >> token;
if(token.compare("#TYPE") != 0)
{
std::cerr << "<<ERROR>> parsing the stream. The #FUNC is not the next line defined." << std::endl;
return false;
std::cerr << "<<ERROR>> parsing the stream. The #TYPE is not the next line defined." << std::endl;
std::cerr << "<<ERROR>> got \"" << token << "\" instead." << std::endl;
return false;
}
in >> token;
......@@ -213,13 +223,6 @@ bool beckmann_function::load(std::istream& in)
}
in >> token;
if(token.compare("nonlinear_function_retrobeckmann") != 0)
{
std::cerr << "<<ERROR>> parsing the stream. function name is not the next token." << std::endl;
return false;
}
// Parse the lobe
for(int i=0; i<_nY; ++i)
{
......
env = Environment()
env.Append(CPPPATH = ['../../../external/build/include', '../../'])
env.Append(LIBPATH = ['../../../external/build/lib', '../../build'])
sources = ['rational_fitter.cpp']
libs = ['-lcore']
env.SharedLibrary('../../build/rational_fitter_eigen', sources, LIBS=libs)
......@@ -68,10 +68,12 @@ def baseName():
#end
def libName(name):
if os.name == 'posix':
return 'lib' + name + '.so'
if sys.platform == 'darwin':
return 'lib' + name + '.dylib'
elif os.name == 'nt':
return name + ".dll"
return name + ".dll"
else:
return 'lib' + name + '.so'
#endif
#end
......
import os
import sys
env = Environment()
env.Append(CPPPATH = ['../../', '../../../external/build/include'])
......@@ -7,8 +7,10 @@ env.Append(CPPPATH = ['../../', '../../../external/build/include'])
sources = ['main.cpp']
libs = ['core']
if(os.name == 'posix'):
if sys.platform == 'linux2':
libs.append(['rt', 'dl'])
elif sys.platform == 'darwin':
libs.append(['dl'])
#end
env.Program('../../build/brdf2brdf', sources, LIBS=libs, LIBPATH=['../../build'])
import os
import sys
env = Environment()
env.Append(CPPPATH = ['../../', '../../../external/build/include'])
......@@ -7,8 +7,10 @@ env.Append(CPPPATH = ['../../', '../../../external/build/include'])
sources = ['main.cpp']
libs = ['core']
if(os.name == 'posix'):
if sys.platform == 'linux2':
libs.append(['rt', 'dl'])
elif sys.platform == 'darwin':
libs.append(['dl'])
#end
env.Program('../../build/brdf2data', sources, LIBS=libs, LIBPATH=['../../build'])
......@@ -18,8 +18,8 @@ int main(int argc, char** argv)
arguments args(argc, argv) ;
if(args.is_defined("help")) {
std::cout << "<<HELP>> brdf2data --input brdf.file --func importer.so --output data.file --data exporter.so" << std::endl ;
std::cout << " - input, output, func, data are mandatory parameters" << std::endl ;
std::cout << "Usage: brdf2data --input brdf.file --output data.file [--data exporter.so --data-file data.file]" << std::endl ;
std::cout << " - input, output are mandatory parameters, you need to either specify a data exporter or a data file" << std::endl ;
return 0 ;
}
......@@ -35,22 +35,18 @@ int main(int argc, char** argv)
std::cerr << "<<ERROR>> the data exporter is not defined" << std::endl ;
return 1 ;
}
/*
if(! args.is_defined("func")) {
std::cerr << "<<ERROR>> the function importer is not defined" << std::endl ;
return 1 ;
}
*/
// Import data
// Get the associated data object and load the file is any
data* d = NULL ;
d = plugins_manager::get_data(args["data"]) ;
d = plugins_manager::get_data(args["data"]) ;
if(args.is_defined("data-file"))
{
d->load(args["data-file"]);
}
// Get the function file
function* f = NULL;
f = plugins_manager::get_function(args);
// Modify function or data to provide coherent
// interfaces
// plugins_manager::check_compatibility(d, f, args);
f = plugins_manager::get_function(args);
if(d != NULL && f != NULL)
{
......
import os
import sys
env = Environment()
env.Append(CPPPATH = ['../../', '../../../external/build/include'])
......@@ -7,8 +7,10 @@ env.Append(CPPPATH = ['../../', '../../../external/build/include'])
sources = ['main.cpp']
libs = ['core']
if(os.name == 'posix'):
if sys.platform == 'linux2':
libs.append(['rt', 'dl'])
elif sys.platform == 'darwin':
libs.append(['dl'])
#end
env.Program('../../build/brdf2gnuplot', sources, LIBS=libs, LIBPATH=['../../build'])
import os
import sys
env = Environment()
env.Append(CPPPATH = ['../../', '../../../external/build/include'])
......@@ -7,8 +7,10 @@ env.Append(CPPPATH = ['../../', '../../../external/build/include'])
sources = ['main.cpp']
libs = ['core']
if(os.name == 'posix'):
if sys.platform == 'linux2':
libs.append(['rt', 'dl'])
elif sys.platform == 'darwin':
libs.append(['dl'])
#end
env.Program('../../build/data2brdf', sources, LIBS=libs, LIBPATH=['../../build'])
import os
import sys
env = Environment()
env.Append(CPPPATH = ['../../', '../../../external/build/include'])
......@@ -7,8 +7,10 @@ env.Append(CPPPATH = ['../../', '../../../external/build/include'])
sources = ['main.cpp']
libs = ['core']
if(os.name == 'posix'):
if sys.platform == 'linux2':
libs.append(['rt', 'dl'])
elif sys.platform == 'darwin':
libs.append(['dl'])
#end
env.Program('../../build/data2data', sources, LIBS=libs, LIBPATH=['../../build'])
import os
import sys
env = Environment()
env.Append(CPPPATH = ['../../', '../../../external/build/include'])
......@@ -7,8 +7,10 @@ env.Append(CPPPATH = ['../../', '../../../external/build/include'])
sources = ['main.cpp']
libs = ['core']
if(os.name == 'posix'):
if sys.platform == 'linux2':
libs.append(['rt', 'dl'])
elif sys.platform == 'darwin':
libs.append(['dl'])
#end
env.Program('../../build/data2moments', sources, LIBS=libs, LIBPATH=['../../build'])
......@@ -20,6 +20,7 @@
#include <core/function.h>
#include <core/fitter.h>
#include <core/plugins_manager.h>
#include <core/vertical_segment.h>
#include <iostream>
#include <vector>
......@@ -55,6 +56,11 @@ int main(int argc, char** argv)
// Import data
data* d = NULL ;
d = plugins_manager::get_data(args["data"]) ;
if(dynamic_cast<const vertical_segment*>(d) != NULL) {
std::cerr << "<<ERROR>> this data object is not interpolant." << std::endl;
return 1;
}
d->load(args["input"]);
// Create output file
......@@ -74,6 +80,15 @@ int main(int argc, char** argv)
vec m_xx(nY);
vec m_xy(nY);
vec m_yy(nY);
vec m_xxx(nY);
vec m_xxy(nY);
vec m_xyy(nY);
vec m_yyy(nY);
vec m_xxxx(nY);
vec m_xxxy(nY);
vec m_xxyy(nY);
vec m_xyyy(nY);
vec m_yyyy(nY);
// Cumulants
vec k_x(nY);
......@@ -81,6 +96,15 @@ int main(int argc, char** argv)
vec k_xx(nY);
vec k_xy(nY);
vec k_yy(nY);
vec k_xxx(nY);
vec k_xxy(nY);
vec k_xyy(nY);
vec k_yyy(nY);
vec k_xxxx(nY);
vec k_xxxy(nY);
vec k_xxyy(nY);
vec k_xyyy(nY);
vec k_yyyy(nY);
#ifndef OLD
// Number of elements per dimension
......@@ -116,6 +140,15 @@ int main(int argc, char** argv)
m_xx = vec::Zero(nY);
m_xy = vec::Zero(nY);