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 191c5ba2 authored by PACANOWSKI Romain's avatar PACANOWSKI Romain
Browse files

Merge

parents abddc9f7 35018597
......@@ -7,7 +7,7 @@ formulation, etc. It is decomposed in three components:
<li><em>\ref core</em>: a set of classes providing interfaces to BRDFs, data type
and fitting algorithms. All the code using this library should rely on this
part.</li>
<li><em>\ref plugins</em>: a set of Qt plugins providing fitting algorithms
<li><em>\ref plugins</em>: a set of plugins providing fitting algorithms
for rational BRDFs, non-linear BRDFs, etc.</li>
<li><em>\ref softs</em>: a set of tools to fit data, convert data, export fitting to
plots, etc.</li>
......
......@@ -5,116 +5,6 @@
#include <string>
#include <fstream>
#ifdef OLD
clustering::clustering(const data* d, const arguments& args)
{
// List of the indices of the clustering
std::vector<int> indices;
vec findices = args.get_vec("cluster-dim", d->dimX(), -1.0f);
for(int i=0; i<findices.size() && findices[i] != -1.0f; ++i)
{
int id = (int)findices[i];
indices.push_back(id);
assert(id >= 0 && id < d->dimX());
}
std::cout << "<<DEBUG>> the resulting data will have " << indices.size() << " dimensions" << std::endl;
// We cannot have null cluster size of full rank.
assert(indices.size() > 0 && indices.size() < d->dimX());
// Fit the slice into the domain of definition of the data
vec compressed_vec = args.get_vec("cluster-slice", d->dimX(), std::numeric_limits<float>::max());
for(int i=0; i<d->dimX(); ++i)
{
compressed_vec[i] = std::min<double>(compressed_vec[i], d->max()[i]);
compressed_vec[i] = std::max<double>(compressed_vec[i], d->min()[i]);
}
// Set the limit of the new domain and dimensions
_nX = indices.size();
_nY = d->dimY();
_min = vec(_nX);
_max = vec(_nX);
for(int i=0; i<_nX; ++i)
{
_min[i] = d->min()[indices[i]];
_max[i] = d->max()[indices[i]];
}
for(int i=0; i<d->size(); ++i)
{
vec p = d->get(i);
bool reject = false;
for(int i=0; i<d->dimX(); ++i)
{
if(is_in<int>(indices, i) == -1 && p[i] != compressed_vec[i])
{
reject = true;
}
}
if(reject)
{
continue;
}
vec e(dimX()+dimY());
for(int i=0; i<_nX; ++i)
{
e[i] = p[indices[i]];
}
for(int i=0; i<_nY; ++i)
{
e[_nX + i] = p[d->dimX() + i];
}
_data.push_back(e);
}
std::cout << "<<INFO>> clustering left " << _data.size() << " elements" << std::endl;
save("cluster.txt");
}
void clustering::save(const std::string& filename)
{
std::ofstream file(filename.c_str(), std::ios_base::trunc);
file << "#DIM " << _nX << " " << _nY << std::endl;
for(int i=0; i<size(); ++i)
{
for(int j=0; j<_nX+_nY; ++j)
{
file << _data[i][j] << "\t";
}
file << std::endl;
}
file.close();
}
vec clustering::get(int i) const
{
return _data[i];
}
vec clustering::operator[](int i) const
{
return _data[i];
}
int clustering::size() const
{
return _data.size();
}
vec clustering::min() const
{
return _min;
}
vec clustering::max() const
{
return _max;
}
#else
template<class T> void clustering(const T* in_data, int _nY, params::input in_param, params::input out_param, std::vector<vec>& out_data)
{
......@@ -127,45 +17,55 @@ template<class T> void clustering(const T* in_data, int _nY, params::input in_pa
std::cout << "out dim = " << out_nX << std::endl;
#endif
for(int i=0; i<in_data->size(); ++i)
{
vec p = in_data->get(i);
vec e (out_nX + _nY);
// Fill the input part of the vector
params::convert(&p[0], in_param, out_param, &e[0]);
// Search for duplicates
bool already_exist = false;
for(unsigned int j=0; j<out_data.size(); ++j)
{
vec test_e = out_data[j];
double dist = 0.0;
for(int k=0; k<out_nX; ++k)
{
const double temp = test_e[k]-e[k];
dist += temp*temp;
}
if(dist < 1.0E-5)
already_exist = true;
}
if(!already_exist)
{
// Fill the output part of the vector
for(int j=0; j<_nY; ++j)
e[out_nX + j] = p[in_nX + j];
for(int i=0; i<in_data->size(); ++i)
{
vec p = in_data->get(i);
vec e (out_nX + _nY);
// Fill the input part of the vector
params::convert(&p[0], in_param, out_param, &e[0]);
// Search for duplicates only when the reparametrization is compressing
// the space.
if(out_nX < in_nX)
{
bool already_exist = false;
for(unsigned int j=0; j<out_data.size(); ++j)
{
vec test_e = out_data[j];
double dist = 0.0;
for(int k=0; k<out_nX; ++k)
{
const double temp = test_e[k]-e[k];
dist += temp*temp;
}
if(dist < 1.0E-5)
already_exist = true;
}
if(!already_exist)
{
// Fill the output part of the vector
for(int j=0; j<_nY; ++j)
e[out_nX + j] = p[in_nX + j];
#ifdef DEBUG
std::cout << " in = " << p << std::endl;
std::cout << "out = " << e << std::endl;
std::cout << " in = " << p << std::endl;
std::cout << "out = " << e << std::endl;
#endif
out_data.push_back(e);
}
}
out_data.push_back(e);
}
}
else
{
// Fill the output part of the vector
for(int j=0; j<_nY; ++j)
e[out_nX + j] = p[in_nX + j];
out_data.push_back(e);
}
}
}
#endif
......@@ -5,6 +5,7 @@
#include <cassert>
#include <cmath>
#include <cstring>
#include <algorithm>
/*! \brief A core implementation of a vector of double.
* \ingroup core
......@@ -238,6 +239,11 @@ template<typename T> int is_in(std::vector<T> ve, T v)
return res;
}
template<typename T> T clamp(T x, T a, T b)
{
return std::max<T>(std::min<T>(x, b), a);
}
#define NOT_IMPLEMENTED() \
std::cerr << "<<ERROR>> not implemented " << __FILE__ \
<< ":" << __LINE__ << std::endl; \
......@@ -251,4 +257,4 @@ throw
#define ALTA_DLL_EXPORT extern "C" __declspec(dllexport)
#else
#define ALTA_DLL_EXPORT extern "C"
#endif
\ No newline at end of file
#endif
TEMPLATE = lib
CONFIG *= static \
qt \
console
DESTDIR = ../build
QMAKE_CXXFLAGS += -std=c++0x
unix{
QMAKE_CXXFLAGS += -std=c++0x -m64
}
HEADERS = args.h \
common.h \
......@@ -20,7 +21,7 @@ HEADERS = args.h \
SOURCES = plugins_manager.cpp \
vertical_segment.cpp \
rational_function.cpp \
params.cpp \
rational_function.cpp \
params.cpp \
function.cpp \
# clustering.cpp
......@@ -6,8 +6,6 @@
#include <limits>
#include <fstream>
#include <QtPlugin>
#include "common.h"
#include "args.h"
#include "params.h"
......@@ -49,10 +47,16 @@ class data : public parametrized
//!
//! \details
//! The input vector in (can have texture coordinate) and the output
//! vector out are taken to grad a value and return it. The two vectors
//! vector out are taken to grab a value and return it. The two vectors
//! should be compliant with the size and parametrization of the data.
virtual vec value(vec in, vec out) const = 0;
//! \brief Provide an evaluation in a BRDF way of the data.
//!
//! \details
//! The input vector must have the parametrization of the data.
virtual vec value(vec in) const = 0;
//! \brief Put the sample inside the data
virtual void set(vec x) = 0;
......@@ -75,8 +79,6 @@ class data : public parametrized
// Dimensions of the data
int _nX, _nY ;
} ;
Q_DECLARE_INTERFACE(data, "Fitter.Data")
/*! \brief Change the parametrization of data to fit the parametrization of the
* function to be fitted.
......@@ -109,6 +111,9 @@ class data_params : public data
data_params::clustrering method = data_params::NONE) :
_clustering_method(method)
{
setParametrization(new_param);
setParametrization(d->output_parametrization());
_nX = params::dimension(new_param);
_nY = d->dimY();
......@@ -123,6 +128,10 @@ class data_params : public data
{
NOT_IMPLEMENTED();
}
virtual vec value(vec in) const
{
NOT_IMPLEMENTED();
}
// Load data from a file
virtual void load(const std::string& filename)
......
......@@ -5,8 +5,6 @@
#include "args.h"
#include "common.h"
#include <QtPlugin>
/*! \brief Fitting interface for generic fitting algorithms
* \ingroup core
*
......@@ -14,15 +12,16 @@
class fitter
{
public:
//! \brief static function to fit a data set d with the underling
//! function class. Return the best fit (along with fitting
//! information ?)
virtual bool fit_data(const data* d, function* f, const arguments& args) = 0 ;
//! \brief static function to fit a data set d with the underling
//! function class. Return the best fit (along with fitting
//! information ?)
virtual bool fit_data(const data* d, function* f, const arguments& args) = 0 ;
//! \brief parse the command line arguments to setup some general
//! options before any fit. Those options should be resilient to
//! multiple call to the fit_data procedure
virtual void set_parameters(const arguments& args) = 0 ;
} ;
Q_DECLARE_INTERFACE(fitter, "Fitter.Fitter")
......@@ -4,8 +4,6 @@
#include <string>
#include <fstream>
#include <QtPlugin>
#include "common.h"
#include "args.h"
#include "params.h"
......@@ -210,5 +208,3 @@ class nonlinear_function: public function
virtual vec parametersJacobian(const vec& x) const = 0;
};
Q_DECLARE_INTERFACE(function, "Fitter.Function")
......@@ -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);
......@@ -116,7 +119,8 @@ void params::to_cartesian(const double* invec, params::input intype,
break;
default:
throw("Transformation not implemented, params::to_cartesian");
std::cerr << "<<ERROR>> Transformation not implemented, " << get_name(intype) << " " << __FILE__ << ":" << __LINE__ << std::endl;
throw;
break;
}
......@@ -148,24 +152,36 @@ void params::from_cartesian(const double* invec, params::input outtype,
// 2D Parametrizations
case params::COS_TH_TD:
outvec[0] = half[2];
outvec[1] = half[0]*outvec[0] + half[1]*outvec[1] + half[2]*outvec[2];
outvec[1] = half[0]*invec[0] + half[1]*invec[1] + half[2]*invec[2];
break;
case params::RUSIN_TH_TD:
outvec[0] = acos(half[2]);
outvec[2] = acos(half[0]*outvec[0] + half[1]*outvec[1] + half[2]*outvec[2]);
outvec[2] = acos(half[0]*invec[0] + half[1]*invec[1] + half[2]*invec[2]);
break;
// 3D Parametrization
case params::RUSIN_TH_PH_TD:
outvec[0] = acos(half[2]);
outvec[1] = atan2(half[0], half[1]);
outvec[2] = acos(half[0]*outvec[0] + half[1]*outvec[1] + half[2]*outvec[2]);
outvec[2] = acos(half[0]*invec[0] + half[1]*invec[1] + half[2]*invec[2]);
break;
case params::RUSIN_TH_TD_PD:
outvec[0] = acos(half[2]);
// Compute the diff vector
diff[0] = invec[0];
diff[1] = invec[1];
diff[2] = invec[2];
rotate_normal(diff, -outvec[1]);
rotate_binormal(diff, -outvec[0]);
outvec[1] = acos(diff[2]);
outvec[2] = atan2(diff[0], diff[1]);
break;
case params::ISOTROPIC_TV_TL_DPHI:
outvec[0] = acos(invec[2]);
outvec[1] = 0.0;
outvec[2] = acos(invec[5]);
outvec[3] = atan2(invec[1], invec[0]) - atan2(invec[4], invec[3]);
outvec[1] = acos(invec[5]);
outvec[2] = atan2(invec[1], invec[0]) - atan2(invec[4], invec[3]);
break;
// 4D Parametrization
......@@ -189,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
......@@ -197,6 +216,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;
assert(false);
break;
}
......
......@@ -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;
}
......@@ -234,7 +240,6 @@ class parametrized
parametrized() : _in_param(params::UNKNOWN_INPUT),
_out_param(params::UNKNOWN_OUTPUT) { }
//! \brief provide the input parametrization of the object.
virtual params::input parametrization() const
{
......@@ -283,7 +288,7 @@ class parametrized
{
return;
}
else if(_out_param == params::UNKNOWN_INPUT)
else if(_out_param == params::UNKNOWN_OUTPUT)
{
_out_param = new_param;
}
......
......@@ -2,18 +2,75 @@
#include "rational_function.h"
#include "vertical_segment.h"
/*
#include <QCoreApplication>
#include <QPluginLoader>
#include <QtPlugin>
#include <QLibrary>
#include <QDir>
*/
// Create the object, parse the argument and load
// all the plugins
//
plugins_manager::plugins_manager(const arguments& args)
#ifdef WIN32
#include <windows.h>
#else
#include <dlfcn.h>
#endif
#include <stdio.h>
//! \brief Open a dynamic library file (.so or .dll) and extract the associated
//! provide function. The template argument is used to cast the library to a
//! specific type.
template<typename T> T open_library(const std::string& filename, const char* function)
{
#ifdef WIN32
HINSTANCE handle = LoadLibrary((LPCTSTR)filename.c_str());
if(handle != NULL)
{
T res = (T)GetProcAddress(handle, function);
if(res == NULL)
{
std::cerr << "<<ERROR>> unable to load the symbol \"" << function << "\" from " << filename << std::endl;
return NULL;
}
#ifdef DEBUG_CORE
std::cout << "<<DEBUG>> will provide a " << function << " for library \"" << filename << "\"" << std::endl;
#endif
return res;
}
else
{
std::cerr << "<<ERROR>> unable to load the dynamic library file \"" << filename << "\"" << std::endl;
std::cerr << " cause: \"" << GetLastError() << "\"" << std::endl;
return NULL;
}
#else
void* handle = dlopen(filename.c_str(), RTLD_LAZY);
if(handle != NULL)
{
void* res = dlsym(handle, function);
if(dlerror() != NULL)
{
std::cerr << "<<ERROR>> unable to load the symbol \"" << function << "\" from " << filename << std::endl;
return NULL;
}
#ifdef DEBUG_CORE
std::cout << "<<DEBUG>> will provide a " << function << " for library \"" << filename << "\"" << std::endl;
#endif
return (T)res;
}
else
{
std::cerr << "<<ERROR>> unable to load the dynamic library file \"" << filename << "\"" << std::endl;
std::cerr << " cause: \"" << dlerror() << "\"" << std::endl;
return NULL;
}
#endif
}
// Create the object, parse the argument and load all the plugins
plugins_manager::plugins_manager(const arguments& args)
{
/*
QDir pluginsDir;
if(args.is_defined("plugins"))
{
......@@ -23,7 +80,9 @@ plugins_manager::plugins_manager(const arguments& args)
{
pluginsDir = QDir(QCoreApplication::instance()->applicationDirPath());
}
*/
/*
foreach (QString fileName, pluginsDir.entryList(QDir::Files))
{
QPluginLoader loader ;
......@@ -77,14 +136,9 @@ plugins_manager::plugins_manager(const arguments& args)
#endif
}
}
*/
}
#ifdef USING_STATIC
typedef function* (*FunctionPrototype)();
typedef fitter* (*FitterPrototype)();
typedef data* (*DataPrototype)();
#endif
// Get instances of the function, the data and the
// fitter
//
......@@ -140,7 +194,6 @@ fitter* plugins_manager::get_fitter()
#endif
}
// Get instances of the function, the data and the
// fitter, select one based on the name. Return null
// if no one exist.
......@@ -156,6 +209,7 @@ function* plugins_manager::get_function(const std::string& n)
}