Maj terminée. Pour consulter la release notes associée voici le lien :
https://about.gitlab.com/releases/2021/07/07/critical-security-release-gitlab-14-0-4-released/

Commit 4b70bd2f authored by Laurent Belcour's avatar Laurent Belcour
Browse files

Updating the documentation

parents 01d2ca89 9f0b06a1
/*!
\page format Format
\todo Describe here the file format
<h2>Common notations</h2>
<h2>Input file format</h2>
For a text data file with <em>n</em> data entries where the input domain has <em>N</em> dimensions and a <em>input_param</em> parametrization and the output domain has <em>P</em> dimensions and a <em>output_param</em> parametrization, our file format is the following:
\verbatim
#DIM N P
#PARAM_IN %input_param%
#PARAM_OUT %output_param%
#VS [0|1|2] (P times)
x_{1,1} ... x_{1,N} y_{1,1} ... y_{1,P}
...
x_{i,1} ... x_{i,N} y_{i,1} ... y_{i,P}
...
x_{n,1} ... x_{n,N} y_{n,1} ... y_{n,P}
\endverbatim
Vertical segments are not defined if VS is 0. For a VS of 1, each sample as a radius associated for the associated dimension. If VS is 2, each sample has a min and max segment value for the associated dimension.
Data and function files have the same format. They are text file very close to dump.
Each file starts with a header containing :
<h3> Parametrization format </h3>
New Tokens
<ul>
<li> \verbatim #PARAM_IN input_parametrization_name \endverbatim </li>
<li> \verbatim #PARAM_OUT output_parametrization_name \endverbatim </li>
</ul>
<h3>Input Parametrization</h3>
Param toujours de la forme NOMDUTYPE_PARAM1_PARAM2_..._PARAMN ou N est le nombre
......@@ -60,32 +42,97 @@ enum{
ENERGY ( as specified by the International Unit System i.e., Joule)
LUMINANCE
<h2>Input file format</h2>
For a text data file with <em>n</em> data entries where the input domain has <em>N</em> dimensions and a <em>input_param</em> parametrization and the output domain has <em>P</em> dimensions and a <em>output_param</em> parametrization, our file format is the following:
\verbatim
#DIM N P
#PARAM_IN %input_param%
#PARAM_OUT %output_param%
#VS [0|1|2] (P times)
x_{1,1} ... x_{1,N} y_{1,1} ... y_{1,P}
...
x_{i,1} ... x_{i,N} y_{i,1} ... y_{i,P}
...
x_{n,1} ... x_{n,N} y_{n,1} ... y_{n,P}
\endverbatim
Vertical segments are not defined if VS is 0. For a VS of 1, each sample as a radius associated for the associated dimension. If VS is 2, each sample has a min and max segment value for the associated dimension.
<h2>Rational function file format (.rational)</h2>
We advise to output all rational function into .rational file for consistency.
ALTA library assumes that all rational polynomials are exported using the
following convention:
<h2>Function file format (.function_name)</h2>
We advise to output function file into <em>.function</em> file for consistency.
ALTA library assumes that all functions are exported using the following convention:
<ul>
<li>The .rational file is outputed in plain text and not in binary.</li>
<li>The .rational file starts with a header. Each line of the header
<li>The .function file is outputed in plain text and not in binary.</li>
<li>The .function file starts with a header. Each line of the header
starts with the character '#'.</li>
<li>If there are multiple color channels to the rational function, they
<li>The header contains the command line used to create the function
in a <em>#CMD ...</em> line.
<li>If there are multiple color channels to the function, they
are enumerated in the file, one color channel by one.</li>
</ul>
Example of a .rational file:
Example of a .function file for a single Lafortune lobe without any diffuse:
\verbatim
#ALTA_HEADER_START
#CMD lafortune --nb_lobes 1 --isotrope
#DIM 2 1
#PARAM_IN ROMEIRO_TH_TD
#PARAM_OUT ENERGY
#ALTA_HEADER_END
#FUNC lafortune
Cx 1.0
Cz 1.0
N 10.0
\endverbatim
For multiple BRDFs lobes (when you want to add a diffuse for example), you need to
specify it into the command line. The different parameters are outputed sequentially
into the file:
\verbatim
#DIM N P
#NP (nombre de coeffs ou degré max au numerateur )
#NQ (nombre de coeffs ou degré min au denominateur )
#BASIS "chaine_caract_decrivant_le_type_de_fonction_de_base"
Coeff_numerateur deg_1_fct_base deg_2_fct_base ... coeff_associe
Coeff denominateur
#NP
#NQ
#ALTA_HEADER_START
#CMD [diffuse, lafortune --nb_lobes 1 --isotrope, phong --fresnel schlick]
#DIM 2 3
#PARAM_IN ROMEIRO_TH_TD
#PARAM_OUT RGB_COLOR
#ALTA_HEADER_END
#FUNC diffuse
kd 1.0
kd 0.02
kd 0.1
#FUNC lafortune
Cx 1.0
Cz 1.0
N 10.0
Cx 1.0
Cz 1.0
N 10.0
Cx 1.0
Cz 1.0
N 10.0
#FUNC phong
ks 1.0
N 10.0
ks 1.0
N 10.0
ks 1.0
N 10.0
#FUNC schlick
R 1.0
R 1.0
R 1.0
\endverbatim
\todo Right now the different color channels have the same length !
......
......@@ -14,7 +14,7 @@
+ Format texte d'entrée et de sortie
+ Format en Entrée
<h2>Data file format</h2>
#DIM N P
# COMMENTAIRE
......@@ -24,7 +24,7 @@
x1 .... xN y1.....yP
+ Format en Sortie
<h2>Function file format</h2>
#DIM N P
#NP (nombre de coeffs ou degré max au numerateur )
......
......@@ -245,7 +245,7 @@ template<typename T> T clamp(T x, T a, T b)
}
#define NOT_IMPLEMENTED() \
std::cerr << "<<ERROR>> not implemented " << __FILE__ \
std::cerr << "<<ERROR>> not implemented " << __PRETTY_FUNCTION__ << " in file " << __FILE__ \
<< ":" << __LINE__ << std::endl; \
throw
......
......@@ -5,7 +5,7 @@ CONFIG *= static \
DESTDIR = ../build
unix{
QMAKE_CXXFLAGS += -std=c++0x -m64
QMAKE_CXXFLAGS += -std=c++0x
}
HEADERS = args.h \
......
......@@ -288,6 +288,13 @@ class fresnel : public nonlinear_function
}
}
//! \brief Provide a first rough fit of the function.
virtual void bootstrap(const data* d, const arguments& args)
{
fresnelBootstrap(d, args);
f->bootstrap(d, args);
}
//! Save the Fresnel part along with the function
virtual void save(const std::string& filename, const arguments& args) const
{
......@@ -456,6 +463,9 @@ class fresnel : public nonlinear_function
//! parameters.
virtual vec getFresnelParametersJacobian(const vec& x) const = 0;
//! \brief Boostrap the function by defining the diffuse term
virtual void fresnelBootstrap(const data* d, const arguments& args) = 0;
protected: //data
//! the base object
......
......@@ -23,10 +23,13 @@ void schlick::load(const std::string& filename)
vec schlick::fresnelValue(const vec& x) const
{
double xp[2];
params::convert(&x[0], input_parametrization(), params::COS_TH_TD, xp);
vec res(_nY);
for(int i=0; i<_nY; ++i)
{
res[i] = R + (1.0 - R) * pow(1.0 - clamp(x[0], 0.0, 1.0), 5.0);
res[i] = R + (1.0 - R) * pow(1.0 - clamp(xp[1], 0.0, 1.0), 5.0);
}
return res;
......@@ -35,7 +38,7 @@ vec schlick::fresnelValue(const vec& x) const
//! \brief Number of parameters to this non-linear function
int schlick::nbFresnelParameters() const
{
return dimY();
return 1;
}
//! \brief Get the vector of parameters for the function
......@@ -57,18 +60,20 @@ void schlick::setFresnelParameters(const vec& p)
vec schlick::getFresnelParametersJacobian(const vec& x) const
{
const int nY = dimY();
double xp[2];
params::convert(&x[0], input_parametrization(), params::COS_TH_TD, xp);
vec jac(nY);
for(int i=0; i<nY; ++i)
{
jac[i] = 1.0 - pow(1.0 - clamp(x[0], 0.0, 1.0), 5.0);
jac[i] = 1.0 - pow(1.0 - clamp(xp[1], 0.0, 1.0), 5.0);
}
return jac;
}
void schlick::bootstrap(const data* d, const arguments& args)
void schlick::fresnelBootstrap(const data* d, const arguments& args)
{
R = 1.0;
}
......@@ -17,9 +17,6 @@ class schlick : public fresnel
public: // methods
//! \brief Boostrap the function by defining the diffuse term
virtual void bootstrap(const data* d, const arguments& args);
//! \brief Load function specific files
virtual void load(const std::string& filename) ;
......@@ -41,6 +38,10 @@ class schlick : public fresnel
//! \brief Obtain the derivatives of the function with respect to the
//! parameters.
virtual vec getFresnelParametersJacobian(const vec& x) const ;
//! \brief Boostrap the function by defining the diffuse term
virtual void fresnelBootstrap(const data* d, const arguments& args);
private: // data
......
#include "function.h"
#include <string>
#include <iostream>
#include <fstream>
#include <limits>
#include <algorithm>
#include <cmath>
#include <core/common.h>
ALTA_DLL_EXPORT function* provide_function()
{
return new diffuse_function();
}
// Overload the function operator
vec diffuse_function::operator()(const vec& x) const
{
return value(x);
}
vec diffuse_function::value(const vec& x) const
{
vec res(dimY());
for(int i=0; i<dimY(); ++i)
{
res[i] = _kd[i];
}
return res;
}
//! Load function specific files
void diffuse_function::load(const std::string& filename)
{
NOT_IMPLEMENTED();
}
void diffuse_function::save_alta(const std::string& filename, const arguments& args) const
{
NOT_IMPLEMENTED();
}
//! Number of parameters to this non-linear function
int diffuse_function::nbParameters() const
{
#ifdef FIT_DIFFUSE
return dimY();
#else
return 0;
#endif
}
//! Get the vector of parameters for the function
vec diffuse_function::parameters() const
{
#ifdef FIT_DIFFUSE
vec res(dimY());
for(int i=0; i<dimY(); ++i)
{
res[i*3 + 0] = _kd[i];
}
#else
vec res(0);
#endif
return res;
}
//! Update the vector of parameters for the function
void diffuse_function::setParameters(const vec& p)
{
#ifdef FIT_DIFFUSE
for(int i=0; i<dimY(); ++i)
{
_kd[i] = p[i];
}
#endif
}
//! Obtain the derivatives of the function with respect to the
//! parameters.
vec diffuse_function::parametersJacobian(const vec& x) const
{
#ifdef FIT_DIFFUSE
vec jac(dimY());
for(int i=0; i<dimY(); ++i)
for(int j=0; j<dimY(); ++j)
{
if(i == j)
{
// df / dk_d
jac[i*dimY() + j] = 1.0;
}
else
{
jac[i*dimY() + j] = 0.0;
}
}
#else
vec jac(0);
#endif
return jac;
}
void diffuse_function::bootstrap(const data* d, const arguments& args)
{
// Set the diffuse component
vec x0 = d->get(0);
for(int i=0; i<d->dimY(); ++i)
_kd[i] = x0[d->dimX() + i];
for(int i=1; i<d->size(); ++i)
{
vec xi = d->get(i);
for(int j=0; j<d->dimY(); ++j)
_kd[j] = std::min(xi[d->dimX() + j], _kd[j]);
}
std::cout << "<<INFO>> found diffuse: " << _kd << std::endl;
}
#pragma once
// Include STL
#include <vector>
#include <string>
// Interface
#include <core/function.h>
#include <core/data.h>
#include <core/args.h>
#include <core/common.h>
/*! \brief A diffuse component class.
*/
class diffuse_function : public nonlinear_function
{
public: // methods
// Overload the function operator
virtual vec operator()(const vec& x) const ;
virtual vec value(const vec& x) const ;
//! \brief Boostrap the function by defining the diffuse term
virtual void bootstrap(const data* d, const arguments& args);
//! \brief Load function specific files
virtual void load(const std::string& filename) ;
//! \brief Number of parameters to this non-linear function
virtual int nbParameters() const ;
//! \brief Get the vector of parameters for the function
virtual vec parameters() const ;
//! \brief Update the vector of parameters for the function
virtual void setParameters(const vec& p) ;
//! \brief Obtain the derivatives of the function with respect to the
//! parameters.
virtual vec parametersJacobian(const vec& x) const ;
virtual void setDimY(int nY)
{
_nY = nY;
_kd.resize(nY);
}
protected: // methods
virtual void save_alta(const std::string& filename, const arguments& args) const;
private: // data
vec _kd;
} ;
TEMPLATE = lib
CONFIG *= qt \
plugin
DESTDIR = ../../build
INCLUDEPATH += ../..
HEADERS = function.h
SOURCES = function.cpp
LIBS += -L../../build \
-lcore
......@@ -138,9 +138,14 @@ bool nonlinear_fitter_eigen::fit_data(const data* d, function* fit, const argume
#ifndef DEBUG
std::cout << "<<DEBUG>> number of parameters: " << nf->nbParameters() << std::endl;
#endif
if(nf->nbParameters() == 0)
{
return true;
}
/* the following starting values provide a rough fit. */
vec nf_x = nf->parameters();
int info;
Eigen::VectorXd x(nf->nbParameters());
for(int i=0; i<nf->nbParameters(); ++i)
......
......@@ -11,6 +11,7 @@ SUBDIRS = \
# rational_fitter_dca \
nonlinear_levenberg_eigen \
nonlinear_fresnel_schlick \
nonlinear_function_diffuse \
nonlinear_function_phong \
nonlinear_function_lafortune \
nonlinear_function_isotropic_lafortune \
......
CONFIG += console \
qt
INCLUDEPATH += ../../
DESTDIR = ../../build
SOURCES += main.cpp
LIBS += -L../../build -lcore
unix{
PRE_TARGETDEPS += ../../build/libcore.a
}
#include <core/args.h>
#include <core/data.h>
#include <core/params.h>
#include <core/function.h>
#include <core/fitter.h>
#include <core/plugins_manager.h>
#include <QApplication>
#include <iostream>
#include <vector>
#include <iostream>
#include <fstream>
#include <limits>
#include <cstdlib>
#include <cmath>
int main(int argc, char** argv)
{
QApplication app(argc, argv, false);
arguments args(argc, argv) ;
plugins_manager manager(args) ;
if(args.is_defined("help")) {
std::cout << "<<HELP>> data2moments --input data.file --output gnuplot.file --function loader.so" << std::endl ;
std::cout << " - input, output and data are mandatory parameters" << std::endl ;
return 0 ;
}
if(! args.is_defined("input")) {
std::cerr << "<<ERROR>> the input filename is not defined" << std::endl ;
return 1 ;
}
if(! args.is_defined("output")) {
std::cerr << "<<ERROR>> the output filename is not defined" << std::endl ;
return 1 ;
}
if(! args.is_defined("func")) {
std::cerr << "<<ERROR>> the data loader is not defined" << std::endl ;
return 1 ;
}
// Import data
function* f = NULL ;
f = manager.get_function(args) ;
f->load(args["input"]);
// Create output file
std::ofstream file(args["output"].c_str(), std::ios_base::trunc);
if(f != NULL)
{
// Data parametrization
params::input func_param = f->parametrization();
int d_size = params::dimension(func_param);
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 rawm0(f->dimY());
vec rawm1(f->dimY());
for(int theta_in=0; theta_in<90; theta_in++)
{
in_angle[0] = theta_in * 0.5*M_PI / 90.0;
// Integrate over the light hemisphere
for(int theta_out=0; theta_out<90; theta_out++)
{
in_angle[2] = theta_out * 0.5*M_PI / 90.0;
for(int phi_out=0; phi_out<180; phi_out++)
{
in_angle[3] = phi_out * 0.5*M_PI / 180.0;
vec in(d_size);
params::convert(in_angle, params::SPHERICAL_TL_PL_TV_PV, func_param, &in[0]);
// Copy the input vector
vec x = f->value(in);
for(int i=0; i<f->dimY(); ++i)
{
double val = x[i] * cos(in_angle[2]);