Commit 21c1f5ca authored by Romain Pacanowski's avatar Romain Pacanowski

Merge branch 'master' of https://gitlab.inria.fr/alta/alta

parents fb8df3b8 3c11d5a4
[submodule "external/tinyexr"]
path = external/tinyexr
url = https://github.com/syoyo/tinyexr.git
[submodule "external/Catch"]
path = external/Catch
url = https://github.com/philsquared/Catch.git
......@@ -190,6 +190,14 @@ def library_available(env, pkgspec='', lib='', header='',
conf.Finish()
return result
def catch_available(env):
"""Return True if Catch is available."""
env.AppendUnique(CPPPATH = '#external')
conf = Configure(env)
has_catch = conf.CheckCXXHeader('Catch/single_include/catch.hpp')
conf.Finish()
return has_catch
def openexr_available(env):
"""Return True if OpenEXR is available."""
env.AppendUnique(CPPPATH = '#external')
......@@ -277,7 +285,7 @@ int main(int argc, char* argv[]) {
return has_cxx11
# Export these for use in SConscripts.
Export('CheckPKG', 'library_available', 'openexr_available')
Export('CheckPKG', 'library_available', 'openexr_available', 'catch_available')
conf = Configure(env, custom_tests = { 'CheckOpenMP': CheckOpenMP,
'CheckCXX11' : CheckCXX11 })
......
Subproject commit 72b72ca9379e7d6fa465efcdec67994a61778046
......@@ -210,7 +210,7 @@ double solve_quadprog_with_guess(Ref<const MatrixXd> L, Ref<const VectorXd> g0,
for (int i = 0; i < n; i++)
{
d[i] = 1.0;
J.col(i) = L.triangularView<Lower>().solve(d);
J.col(i) = L.transpose().triangularView<Upper>().solve(d);
c2 += J(i,i);
d[i] = 0.0;
}
......@@ -220,7 +220,7 @@ double solve_quadprog_with_guess(Ref<const MatrixXd> L, Ref<const VectorXd> g0,
f_value = 0.5 * g0.dot(x);
TRACE_SOLVER( std::cout << "Unconstrained solution: " << f_value << std::endl );
TRACE_SOLVER( print_vector("x", x) );
TRACE_SOLVER( std::cout << "x: " << x.transpose() << std::endl );
// Add equality constraints to the working set A
iq = 0;
......@@ -284,7 +284,7 @@ double solve_quadprog_with_guess(Ref<const MatrixXd> L, Ref<const VectorXd> g0,
int nb_satisfied_chunks = 0;
while(iter<=10*m) // make sure we do not run into an infinite loop
{
TRACE_SOLVER( print_vector("x", x) );
TRACE_SOLVER( std::cout << "x: " << x.transpose() << std::endl );
// step 1: choose a violated constraint
// FIXME: should be removed:
......@@ -455,7 +455,7 @@ double solve_quadprog_with_guess(Ref<const MatrixXd> L, Ref<const VectorXd> g0,
A[iq] = ip; // add ip to the active set A
TRACE_SOLVER( std::cout << "Trying with constraint " << ip << std::endl );
TRACE_SOLVER( print_vector("np", np) );
TRACE_SOLVER( std::cout << "np: " << np.transpose() << std::endl );
// Project onto constraint ip
int count = 0;
......@@ -642,9 +642,9 @@ bool add_constraint(Ref<MatrixXd> R, Ref<MatrixXd> J, Ref<VectorXd> d, int& iq,
R.col(iq-1).head(iq) = d.head(iq);
TRACE_SOLVER( std::cout << iq << std::endl );
TRACE_SOLVER( print_matrix("R", R, iq, iq) );
TRACE_SOLVER( print_matrix("J", J) );
TRACE_SOLVER( print_vector("d", d, iq) );
TRACE_SOLVER( std::cout << "R:\n" << R.topLeftCorner(iq,iq) << std::endl );
TRACE_SOLVER( std::cout << "J:\n" << J << std::endl );
TRACE_SOLVER( std::cout << "d: " << d.head(iq).transpose() << std::endl );
if (std::abs(d[iq - 1]) <= std::numeric_limits<double>::epsilon() * R_norm)
{
......
......@@ -412,6 +412,10 @@ class arguments
}
#ifdef DEBUG_ARGS
std::cout << "]" << std::endl;
for( int i=0; i < cmd_vec.size(); i++)
{
std::cout << " cmd_vec[" << i << "]=" << cmd_vec[i] << std::endl;
}
#endif
int argc = cmd_vec.size();
......
......@@ -186,6 +186,8 @@ alta::data* alta::load_data_from_text(std::istream& input,
auto kind = ci_kind_from_number(header.get_int("VS"));
std::vector<double> content;
std::cout << "<<INFO>> Starting to load file ... " << std::endl;
// Now read the body.
while(input.good())
{
......@@ -238,10 +240,11 @@ alta::data* alta::load_data_from_text(std::istream& input,
}
std::cout << "<<INFO>> loaded input stream" << std::endl ;
std::cout << "<<INFO>> loading data input of R^"
std::cout << "<<INFO>> loaded data input of R^"
<< dim.first
<< " -> R^" << dim.second << std::endl ;
std::cout << "<<INFO>> " << content.size() << " elements to fit" << std::endl ;
std::cout << "<<DEBUG>> " << content.size() << " double loaded. " << std::endl ;
double *raw_content = new double[content.size()];
......@@ -255,6 +258,8 @@ alta::data* alta::load_data_from_text(std::istream& input,
if(args.is_defined("data-correct-cosine"))
result->save("/tmp/data-corrected.dat");
std::cout << "<<INFO>> " << element_count << " elements (rows) loaded" << std::endl ;
return result;
}
......
This diff is collapsed.
import os, sys
from subprocess import call
from subprocess import call, Popen, STDOUT
from os.path import basename, splitext
import filecmp
import obtain
Import('env', 'ALTA_LIBS', 'openexr_available')
Import('env', 'ALTA_LIBS', 'openexr_available', 'catch_available')
env = env.Clone()
have_catch = catch_available(env)
have_openexr = openexr_available(env)
conf = Configure(env)
have_cppquickcheck = conf.CheckLibWithHeader('cppqc', 'cppqc.h', 'C++')
......@@ -79,9 +81,9 @@ def run_unit_test(env, target, source):
envvars = build_environment_variables()
with open(str(target[0]),'w') as log:
log.write(str(envvars) + '\n')
if splitext(program)[1] == '.py':
command = env['PYTHON'] + ' ' + program
log.write(str(envvars) + '\n')
if call([env['PYTHON'], program], env=envvars) == 0:
log.write("PASS: " + command + "\n")
return 0
......@@ -89,7 +91,11 @@ def run_unit_test(env, target, source):
log.write("FAIL: " + command + "\n")
return 1
else:
if os.spawnle(os.P_WAIT, program, program, envvars) == 0:
pipe = Popen([program], env = envvars,
stdout = log, stderr = STDOUT)
pipe.wait()
log.write('\n' + str(envvars) + '\n')
if pipe.returncode == 0:
log.write("PASS: " + program + "\n")
return 0
else:
......@@ -102,10 +108,13 @@ def run_command(arguments):
program = str(source[0].abspath)
envvars = build_environment_variables()
status = os.spawnve(os.P_WAIT, program, [program] + arguments, envvars)
command = ' '.join([program] + arguments)
with open(str(target[0]), 'w') as log:
log.write(str(envvars) + '\n');
pipe = Popen([program] + arguments, env = envvars, \
stdout = log, stderr = STDOUT)
pipe.wait()
status = pipe.returncode
command = ' '.join([program] + arguments)
log.write('\n' + str(envvars) + '\n');
if status == 0:
log.write("PASS: '" + command + "' succeeded\n")
else:
......@@ -201,6 +210,7 @@ if 'python' in COMMAND_LINE_TARGETS:
for test in PYTHON_TESTS:
make_test_python(test)
# Make sure commands from the tutorials actually work.
cmd1 = make_command_test('data2brdf', [ '--input', test_file, '--output',
......@@ -272,6 +282,115 @@ downloadKrylon = env.Command(test_output_directory + '/krylon_blue_RGB.astm',
downloadGold.noclean = True
downloadKrylon.noclean = True
# Test Some basic conversion from MERL to ALTA ...
cmd00 = make_command_test('data2data', ['--param RUSIN_TH_TD_PD',
'--input', test_byproduct('gold-metallic-paint.binary'),
'--in-data', 'data_merl',
'--output', test_byproduct('gold-metallic-paint.alta'),
'--all-values'],
'merl-to-alta-all-values')
env.Depends(cmd00, downloadGold)
AlwaysBuild(cmd00)
env.Alias('tests',cmd00)
# ... and from ALTA to ALTA using filtering
cmd01 = make_command_test('data2data', ['--input', test_byproduct('gold-metallic-paint.alta'),
'--output', test_byproduct('gold-metallic-paint_positive_only.alta'),
'--all-values', '--param RUSIN_TH_TD_PD', '--ymin [0.0, 0.0, 0.0]'],
'alta-to-alta-positive-values-only')
env.Depends(cmd01,cmd00)
AlwaysBuild(cmd01)
env.Alias('tests',cmd01)
# Convert from ALTA's text format to ALTA's binary format and back.
cmd02 = make_command_test('data2data',
['--input',
test_byproduct('gold-metallic-paint.alta'),
'--output',
test_byproduct('gold-metallic-paint-all-values.alta-bin'),
'--out-data', 'alta-binary',
'--all-values'],
'alta-to-alta-binary')
env.Depends(cmd02, cmd00)
cmd03 = make_command_test('data2data',
['--input',
test_byproduct('gold-metallic-paint-all-values.alta-bin'),
'--output',
test_byproduct('gold-metallic-paint2.alta'),
'--all-values'],
'alta-binary-to-alta')
env.Depends(cmd03, cmd02)
def check_that_files_are_identical(file1, file2):
"""Return a function that checks whether FILE1 and FILE2 are identical."""
def compare_files(env, target, source):
identical = filecmp.cmp(file1, file2)
with open(str(target[0]), 'w') as log:
if identical:
log.write("PASS: '" + file1 + "' and '" + file2 + "' are identical\n")
else:
log.write("FAIL: '" + file1 + "' and '" + file2 + "' differ\n")
return 1
return compare_files
cmd04 = env.Command('data2data-alta-to-binary-to-alta.log',
test_byproduct('gold-metallic-paint2.alta'),
check_that_files_are_identical(test_byproduct('gold-metallic-paint.alta'),
test_byproduct('gold-metallic-paint2.alta')))
env.Depends(cmd04, cmd00)
env.Depends(cmd04, cmd03)
env.Alias('tests', cmd04)
# Convert from MERL to ALTA's binary format.
cmd05 = make_command_test('data2data', ['--param RUSIN_TH_TD_PD',
'--input', test_byproduct('gold-metallic-paint.binary'),
'--in-data', 'data_merl',
'--out-data', 'alta-binary',
'--output', test_byproduct('gold-metallic-paint2.alta-bin'),
'--all-values'],
'merl-to-alta-all-values-binary')
env.Depends(cmd05, downloadGold)
env.Alias('tests', cmd05)
cmd06 = make_command_test('data2data',
['--input',
test_byproduct('gold-metallic-paint2.alta-bin'),
'--output',
test_byproduct('gold-metallic-paint3.alta'),
'--all-values'],
'alta-binary-to-alta2')
env.Depends(cmd06, cmd05)
env.Alias('tests', cmd06)
cmd07 = env.Command('data2data-merl-to-alta-binary-to-alta.log',
test_byproduct('gold-metallic-paint3.alta'),
check_that_files_are_identical(test_byproduct('gold-metallic-paint.alta'),
test_byproduct('gold-metallic-paint3.alta')))
env.Depends(cmd07, cmd00)
env.Depends(cmd07, cmd06)
env.Alias('tests', cmd07)
# ADD C++ Test if the two previous tests have passed and if Catch submodule is available
if have_catch:
CXX_CATCH_TESTS = ['core/conversion-catch-1.cpp']
env.AppendUnique(CPPPATH = ['#external/Catch/single_include/'])
for test in CXX_CATCH_TESTS:
make_cxx_test_alias(test)
#end_for_loop
#end_if_have_catch
if have_openexr:
cmd5 = make_command_test('data2data',
['--input',
......
/* ALTA --- Analysis of Bidirectional Reflectance Distribution Functions
Copyright (C) 2017 CNRS
This file is part of ALTA.
This Source Code Form is subject to the terms of the Mozilla Public
License, v. 2.0. If a copy of the MPL was not distributed with this
file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
/*
* Initial author : Romain Pacanowski @ institutoptique.fr
*/
//Catch Framework
// CATCH SHOULD PROVIDE MAIN
#define CATCH_CONFIG_MAIN
#include "catch.hpp"
//ALTA
#include <core/args.h>
#include <core/data.h>
#include <core/params.h>
#include <core/common.h>
#include <core/plugins_manager.h>
#include <core/vertical_segment.h>
TEST_CASE( " Conversion from MERL data to ALTA with all values", "[MERL to ALTA. All Values]")
{
using namespace alta;
arguments args;
std::string const DATA_FILE1 = "./build/tests/gold-metallic-paint.binary";
//Load data from File
ptr<data> d_in;
try
{
d_in = plugins_manager::load_data(DATA_FILE1.c_str(),"data_merl", args) ;
}
catch(...)
{
//Could not load file ?
REQUIRE(false);
}
REQUIRE( d_in->size() == 90*90*180 );
REQUIRE( d_in->parametrization().dimX() == 3); // RUSINKIEWICZ PARAMETRIZATION AS INPUT
REQUIRE( d_in->parametrization().dimY() == 3); // COLOR RGB AS VALUES
}
TEST_CASE( "ALTA FILTERING TEST by keeping only positive values for Y", "[ALTA Y Filtering]")
{
using namespace alta;
arguments args;
args.update("ymin","[0.0, 0.0, 0.0]");
std::string const DATA_FILE1 = "./build/tests/gold-metallic-paint.alta";
std::cout << " ATTEMTPING TO LOAD = " << DATA_FILE1 << std::endl;
//Load data from File
ptr<data> d_in;
//Try to convert to VerticalSegment. Should work or we have a problem
ptr<vertical_segment> vs;
try
{
d_in = plugins_manager::load_data(DATA_FILE1.c_str(),"", args) ;
vs = dynamic_pointer_cast< vertical_segment >( d_in );
}
catch(...)
{
//Could not load file ?
REQUIRE(false);
}
// vec y_min = args.get_vec("ymin",3, -1);
// std::cout << " y_min = " << y_min << std::endl;
// std::cout << " is vec for ymin " << args.is_vec("ymin");
// std::cout << " d_in->parametrization().dimX() = " << d_in->parametrization().dimX() << std::endl;
// std::cout << " d_in->size() = " << d_in->size() << std::endl;
for (int i = 0; i < d_in->size(); ++i)
{
vec x_y = d_in->get(i);
for(int d=0; d < d_in->parametrization().dimY(); d++ )
{
double y = x_y( d_in->parametrization().dimX() + d );
REQUIRE( y >= 0.0 );
}
}
Eigen::Map<RowMatrixXd> data_as_matrix = vs->matrix_view();
RowMatrixXd const & y_values = data_as_matrix.block(0, d_in->parametrization().dimX(), d_in->size(), d_in->parametrization().dimY() );
REQUIRE( y_values.all() >= 0.0 );
}
TEST_CASE( "ALTA FILTERING TEST by keeping only values for phi_diff and theta_diff near zero", "[ALTA X Filtering]")
{
using namespace alta;
double const THETA_H_MAX_VALUE = 1.55;
arguments args;
args.update("ymin","[0.0, 0.0, 0.0]");
args.update("max","[1.55, 0.01, 0.01]");
//args.create_arguments( "--ymin [0.0, 0.0, 0.0] --max [1.5, 0.01, 0.01] --param RUSIN_TH_TD_PD");
std::string const DATA_FILE1 = "./build/tests/gold-metallic-paint.alta";
//Load data from File
ptr<data> d_in;
ptr<vertical_segment> vs;
try
{
d_in = plugins_manager::load_data(DATA_FILE1.c_str(),"", args) ;
vs = dynamic_pointer_cast< vertical_segment >( d_in );
}
catch(...)
{
//Could not load file ?
REQUIRE(false);
}
Eigen::Map<RowMatrixXd> data_as_matrix = vs->matrix_view();
RowMatrixXd const & x_values = data_as_matrix.block(0, 0, d_in->size(), d_in->parametrization().dimX() );
// std::cout << " d_in->parametrization().dimX() = " << d_in->parametrization().dimX() << std::endl;
// std::cout << " d_in->size() = " << d_in->size() << std::endl;
// std::cout << " Nb Rows in x_values = " << x_values.rows() << std::endl;
// std::cout << " Nb Colums in x_avlues " << x_values.cols() << std::endl;
vec x_max = args.get_vec("xmax",3, -1);
// std::cout << " xmax = " << x_max << std::endl;
// std::cout << " is vec for xmax " << args.is_vec("xmax");
// for( int i=0; i < x_values.rows(); i++)
// {
// std::cout << x_values(i,0) << " " << x_values(i,1) << " " << x_values(i,2)
// << std::endl;
// }
Eigen::ArrayXd col_0 = x_values.col( 0 ).array();
//CHECK ALL first X values are supposed to be less than 1.5
//Thats theta_h for MERL material
REQUIRE( (col_0 <= THETA_H_MAX_VALUE).all() );
//CHECK ALL Second X values are supposed to be less than 0.01
// Thats theta_diff for MERL Material
REQUIRE( (x_values.col( 1 ).array() <= 0.01).all() ) ;
//CHECK ALL Third X values are supposed to be less than 0.01
// Thats phi_diff for MERL Material
REQUIRE( (x_values.col( 2 ).array() <= 0.01).all() ) ;
}
\ No newline at end of file
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