Commit 9b573352 authored by Pierre Kraemer's avatar Pierre Kraemer

Merge cgogn:~vanhoey/CGoGN

parents 61d2951f 8ad45a03
......@@ -453,6 +453,8 @@ public:
bool nextEdge(Dart& d) ;
void updateBeforeCollapse(Dart d) ;
void updateAfterCollapse(Dart d2, Dart dd2) ;
void updateWithoutCollapse() { }
} ;
/*****************************************************************************************************************
......@@ -514,6 +516,8 @@ public:
bool nextEdge(Dart& d) ;
void updateBeforeCollapse(Dart d) ;
void updateAfterCollapse(Dart d2, Dart dd2) ;
void updateWithoutCollapse() { }
} ;
/*****************************************************************************************************************
......@@ -580,6 +584,8 @@ public:
bool nextEdge(Dart& d) ;
void updateBeforeCollapse(Dart d) ;
void updateAfterCollapse(Dart d2, Dart dd2) ;
void updateWithoutCollapse() { }
} ;
} // namespace Decimation
......
......@@ -87,6 +87,8 @@ public:
bool nextEdge(Dart& d) ;
void updateBeforeCollapse(Dart d) ;
void updateAfterCollapse(Dart d2, Dart dd2) ;
void updateWithoutCollapse() { }
} ;
///*****************************************************************************************************************
......
/*******************************************************************************
* CGoGN: Combinatorial and Geometric modeling with Generic N-dimensional Maps *
* version 0.1 *
* Copyright (C) 2009-2012, IGG Team, LSIIT, University of Strasbourg *
* *
* This library is free software; you can redistribute it and/or modify it *
* under the terms of the GNU Lesser General Public License as published by the *
* Free Software Foundation; either version 2.1 of the License, or (at your *
* option) any later version. *
* *
* This library is distributed in the hope that it will be useful, but WITHOUT *
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or *
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License *
* for more details. *
* *
* You should have received a copy of the GNU Lesser General Public License *
* along with this library; if not, write to the Free Software Foundation, *
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
* *
* Web site: http://cgogn.unistra.fr/ *
* Contact information: cgogn@unistra.fr *
* *
*******************************************************************************/
#ifndef TENSOR_H_
#define TENSOR_H_
/*!
* \file tensor.h
*/
namespace CGoGN
{
namespace Geom
{
/*! \class Tensor tensor.h
*
* \brief Class for representing cubic tensors of static size and dynamic order.
*
* A cubic Tensor of size SIZE and order ORDER has
* SIZE x SIZE x ... x SIZE (ORDER times) = SIZE^ORDER elements.
*
* \tparam REAL the floating point arithmetics to use
* \tparam SIZE the base size of the Tensor
*/
template <unsigned int SIZE, typename REAL>
class Tensor
{
private:
unsigned int m_order ;
REAL* m_data ;
public:
/**********************************************/
/* CONSTRUCTORS */
/**********************************************/
/**
* \brief Default constructor
*
* Tensor class default constructor
*/
Tensor() ;
/**
* \brief Copy constructor
*
* Tensor class copy constructor
*
* \param T the tensor to copy
*/
Tensor(const Tensor& T) ;
/**
* \brief Constructor
*
* Tensor class order constructor
*
* \param order the desired order of the Tensor
*/
Tensor(unsigned int order) ;
/**
* \brief Destructor
*
* Tensor class destructor
*/
~Tensor() ;
/**********************************************/
/* MODIFIERS */
/**********************************************/
/**
* \brief Modifier: set all to zero
*
* sets all elements to zero
*/
void zero() ;
/**
* \brief Modifier: set identity
*
* Sets diagonal elements to one
*/
void identity() ;
/**
* \brief Modifier: set constant values
*
* Sets all values to r
*
* \param r the constant value
*/
void setConst(const REAL& r) ;
/**
* \brief Modifier: copy Tensor
*
* copies argument into current instance
*
* \param T the tensor to copy
*/
void operator=(const Tensor& T) ;
/**********************************************/
/* ACCESSORS */
/**********************************************/
/**
* \brief Accessor: get element
*
* \param p=(p0, ..., pn) the nD index to access
*
* \return const reference to the value stored at index p
*/
const REAL& operator()(std::vector<unsigned int> p) const ;
/**
* \brief Accessor: get element
*
* \param p=(p0, ..., pn) the nD index to access
*
* \return reference to the value stored at index p
*/
REAL& operator()(std::vector<unsigned int> p) ;
/**
* \brief Accessor: get element
*
* \param k the 1D array index to access
*
* \return const reference to the value stored at index k in the array
*/
const REAL& operator[](unsigned int k) const ;
/**
* \brief Accessor: get element
*
* \param k the 1D array index to access
*
* \return reference to the value stored at index k in the 1D array representing the tensor
*/
REAL& operator[](unsigned int k) ;
/**
* \brief Accessor: get amount of elements in tensor
*
* \return the amount of elements in the tensor
*/
unsigned int nbElem() const ;
/**
* \brief Accessor: get order of tensor
*
* \return const ref to the order of the tensor
*/
const unsigned int& order() const ;
/**********************************************/
/* UTILITY FUNCTIONS */
/**********************************************/
/**
* \brief Utility: increment nD index
*
* Tool for incrementing the nD index (p0,...,pn) depending on the size
*
* \return true if final index not reached
*/
static bool incremIndex(std::vector<unsigned int>& p) ;
/**********************************************/
/* STREAM OPERATORS */
/**********************************************/
/**
* \brief Stream operator: write
*
* Writes the tensor in an output text stream
*/
friend std::ostream& operator<<(std::ostream& out, const Tensor<SIZE, REAL>& T)
{
out << "Tensor of order " << T.order() << " and size " << SIZE << std::endl ;
for (unsigned int i = 0 ; i < T.nbElem() ; ++i)
{
out << T[i] << " " ;
if ((i % SIZE) == (SIZE - 1))
out << std::endl ;
}
return out ;
}
private:
/**********************************************/
/* UTILITY FUNCTIONS */
/**********************************************/
/**
* \brief Utility: convert nD to 1D index
*
* Tool for converting an nD index (p0,...,pn) to a 1d array index
*
* \return 1d index
*/
unsigned int getIndex(std::vector<unsigned int> p) const ;
} ;
/**********************************************/
/* SOME USEFUL TYPEDEFS */
/**********************************************/
typedef Tensor<2, float> Tensor2f ;
typedef Tensor<2, double> Tensor2d ;
typedef Tensor<3, float> Tensor3f ;
typedef Tensor<3, double> Tensor3d ;
} /* namespace Geom */
} /* namespace CGoGN */
#include "tensor.hpp"
#endif /* TENSOR_H_ */
/*******************************************************************************
* CGoGN: Combinatorial and Geometric modeling with Generic N-dimensional Maps *
* version 0.1 *
* Copyright (C) 2009-2012, IGG Team, LSIIT, University of Strasbourg *
* *
* This library is free software; you can redistribute it and/or modify it *
* under the terms of the GNU Lesser General Public License as published by the *
* Free Software Foundation; either version 2.1 of the License, or (at your *
* option) any later version. *
* *
* This library is distributed in the hope that it will be useful, but WITHOUT *
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or *
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License *
* for more details. *
* *
* You should have received a copy of the GNU Lesser General Public License *
* along with this library; if not, write to the Free Software Foundation, *
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
* *
* Web site: http://cgogn.unistra.fr/ *
* Contact information: cgogn@unistra.fr *
* *
*******************************************************************************/
/* \file tensor.hpp */
namespace CGoGN {
namespace Geom {
template <unsigned int SIZE, typename REAL>
Tensor<SIZE, REAL>::Tensor():
m_order(0)
{
m_data = new REAL[1] ;
}
template <unsigned int SIZE, typename REAL>
Tensor<SIZE, REAL>::Tensor(const Tensor& T):
m_order(T.m_order)
{
m_data = new REAL[T.nbElem()] ;
for (unsigned int i = 0 ; i < T.nbElem() ; ++i)
m_data[i] = T[i] ;
}
template <unsigned int SIZE, typename REAL>
Tensor<SIZE, REAL>::Tensor(unsigned int order):
m_order(order)
{
m_data = new REAL[(unsigned int)pow(SIZE,m_order)] ;
}
template <unsigned int SIZE, typename REAL>
Tensor<SIZE, REAL>::~Tensor()
{
delete[] m_data ;
}
template <unsigned int SIZE, typename REAL>
void Tensor<SIZE, REAL>::identity()
{
unsigned int offset = 0 ;
for (unsigned int i = 0 ; i < SIZE ; ++i)
m_data[SIZE*i + offset++] = 1 ;
assert(offset == SIZE) ;
}
template <unsigned int SIZE, typename REAL>
void
Tensor<SIZE, REAL>::zero()
{
for (unsigned int i = 0 ; i < (unsigned int)pow(SIZE,m_order) ; ++i)
{
m_data[i] = 0 ;
}
}
template <unsigned int SIZE, typename REAL>
void
Tensor<SIZE, REAL>::setConst(const REAL& r)
{
for (unsigned int i = 0 ; i < nbElem() ; ++i)
{
m_data[i] = r ;
}
}
template <unsigned int SIZE, typename REAL>
void
Tensor<SIZE, REAL>::operator=(const Tensor& T)
{
m_order = T.m_order ;
delete(m_data) ;
m_data = new REAL[T.nbElem()] ;
for (unsigned int i = 0 ; i < T.nbElem() ; ++i)
m_data[i] = T[i] ;
}
template <unsigned int SIZE, typename REAL>
const REAL&
Tensor<SIZE, REAL>::operator()(std::vector<unsigned int> p) const
{
assert(p.size() == m_order || !"Tensor::operator(): order does not correspond to argument") ;
return m_data[getIndex(p)] ;
}
template <unsigned int SIZE, typename REAL>
REAL&
Tensor<SIZE, REAL>::operator()(std::vector<unsigned int> p)
{
assert(p.size() == m_order || !"Tensor::operator(): order does not correspond to argument") ;
return m_data[getIndex(p)] ;
}
template <unsigned int SIZE, typename REAL>
unsigned int
Tensor<SIZE, REAL>::getIndex(std::vector<unsigned int> p) const
{
assert(p.size() == m_order || !"Tensor::getIndex: order does not correspond to argument") ;
if (p.size() != m_order)
return -1 ;
unsigned int res = 0 ;
unsigned int prod = 1 ;
for (unsigned int i = 0 ; i < m_order ; ++i)
{
assert(p[i] < SIZE || !"Tensor::getIndex: given index has out of bound values (higher then tensor SIZE)") ;
res += p[i]*prod ;
prod *= SIZE ;
}
return res ;
}
template <unsigned int SIZE, typename REAL>
const unsigned int&
Tensor<SIZE, REAL>::order() const
{
return m_order ;
}
template <unsigned int SIZE, typename REAL>
unsigned int
Tensor<SIZE, REAL>::nbElem() const
{
return pow(SIZE,m_order) ;
}
template <unsigned int SIZE, typename REAL>
REAL&
Tensor<SIZE, REAL>::operator[](unsigned int k)
{
assert(k < nbElem() || !"Tensor::operator[] out of bound value requested") ;
return m_data[k] ;
}
template <unsigned int SIZE, typename REAL>
const REAL&
Tensor<SIZE, REAL>::operator[](unsigned int k) const
{
assert(k < nbElem() || !"Tensor::operator[] out of bound value requested") ;
return m_data[k] ;
}
template <unsigned int SIZE, typename REAL>
bool
Tensor<SIZE, REAL>::incremIndex(std::vector<unsigned int>& p)
{
int i = p.size() - 1 ;
while (i >= 0)
{
p[i] = (p[i] + 1) % SIZE ;
if (p[i] != 0) // if no overflow
return true ;
--i ;
}
return false ;
}
} /* namespace Geom */
} /* namespace CGoGN */
......@@ -61,7 +61,8 @@ public: // types
C_RGB = 0,
C_XYZ = 1,
C_Luv = 2,
C_Lab = 3
C_Lab = 3,
C_HSV = 4
} ;
typedef Geom::Vector<3,REAL> VEC3 ; /*!< Triplet for color encoding */
......@@ -103,6 +104,11 @@ public: // methods
* @return Lab value of provided colour
*/
VEC3 getLab() ;
/**
* getR
* @return Lab value of provided colour
*/
VEC3 getHSV() ;
/**
* getR
* @return XYZ value of provided colour
......@@ -116,6 +122,7 @@ private: // private members
VEC3 *RGB ;
VEC3 *Luv ;
VEC3 *Lab ;
VEC3 *HSV ;
VEC3 *XYZ ;
bool convert(enum ColourEncoding from, enum ColourEncoding to) ;
......@@ -128,6 +135,9 @@ private: // private members
void convertXYZtoLab() ;
void convertLabToXYZ() ;
void convertRGBtoHSV() ;
void convertHSVtoRGB() ;
private: // private constants
// D65 reference white
static const REAL Xn = 0.950456 ;
......
......@@ -31,6 +31,7 @@ ColourConverter<REAL>::ColourConverter(const VEC3& col, const enum ColourEncodin
RGB(NULL),
Luv(NULL),
Lab(NULL),
HSV(NULL),
XYZ(NULL)
{
originalEnc = enc ;
......@@ -67,6 +68,14 @@ ColourConverter<REAL>::ColourConverter(const VEC3& col, const enum ColourEncodin
#endif
Lab = new VEC3(col) ;
break ;
case (C_HSV) :
#ifdef DEBUG
if (!(-0.001 < col[0] && col[0] < 360.001 && -0.001 < col[1] && col[1] < 1.001 && -0.001 < col[2] && col[2] < 1.001))
std::cerr << "Warning : an unvalid Lab color was entered in ColourConverter constructor" << std::endl ;
#endif
HSV = new VEC3(col) ;
break ;
}
}
......@@ -77,6 +86,7 @@ ColourConverter<REAL>::~ColourConverter()
delete Luv ;
delete XYZ ;
delete Lab ;
delete HSV ;
}
template<typename REAL>
......@@ -98,6 +108,10 @@ Geom::Vector<3,REAL> ColourConverter<REAL>::getColour(enum ColourEncoding enc) {
return getLab() ;
break ;
case (C_Lab) :
return getHSV() ;
break ;
default :
assert(!"Should never arrive here : ColourConverter::getColour default case") ;
return getOriginal() ;
......@@ -142,6 +156,14 @@ Geom::Vector<3,REAL> ColourConverter<REAL>::getXYZ() {
return *XYZ ;
}
template<typename REAL>
Geom::Vector<3,REAL> ColourConverter<REAL>::getHSV() {
if (HSV == NULL)
convert(originalEnc,C_HSV) ;
return *HSV ;
}
template<typename REAL>
void ColourConverter<REAL>::convertRGBtoXYZ() {
Geom::Matrix<3,3,REAL> M ;
......@@ -160,7 +182,10 @@ void ColourConverter<REAL>::convertRGBtoXYZ() {
VEC3 c = M * (*RGB) ;
XYZ = new VEC3(c) ;
if (XYZ != NULL)
*XYZ = c ;
else
XYZ = new VEC3(c) ;
}
template<typename REAL>
......@@ -181,11 +206,108 @@ void ColourConverter<REAL>::convertXYZtoRGB() {
VEC3 c = M * (*XYZ) ;
RGB = new VEC3(c) ;
if (RGB != NULL)
*RGB = c ;
else
RGB = new VEC3(c) ;
}
template<typename REAL>
void ColourConverter<REAL>::convertXYZtoLuv() {
void ColourConverter<REAL>::convertRGBtoHSV()
{
const REAL& r = (*RGB)[0] ;
const REAL& g = (*RGB)[1] ;
const REAL& b = (*RGB)[2] ;
const REAL& max = std::max(std::max(r,g),b) ;
const REAL& min = std::min(std::min(r,g),b) ;
VEC3 c ;
if (max == min)
{
c[0] = 0 ;
}
else if (max == r)
{
c[0] = 60 * (g - b) / (max - min) + 360 ;
c[0] = (unsigned int)(c[0]) % 360 ;
}
else if (max == g)
{
c[0] = 60 * (b - r) / (max - min) + 120 ;
}
else if (max == b)
{
c[0] = 60 * (r - g) / (max - min) + 240 ;
}
c[1] = (max == 0) ? 0 : 1 - min/max ;
c[2] = max ;
if (HSV != NULL)
*HSV = c ;
else
HSV = new VEC3(c) ;
}
template<typename REAL>
void ColourConverter<REAL>::convertHSVtoRGB()
{
const REAL& H = (*HSV)[0] ;
const REAL& s = (*HSV)[1] ;
const REAL& v = (*HSV)[2] ;
const unsigned int Hi = (unsigned int)(std::floor(H / 60)) % 6 ;
const REAL f = (H / 60) - Hi ;
const REAL l = v * (1 - s) ;
const REAL m = v * (1 - f * s) ;
const REAL n = v * (1 - (1 - f) * s) ;
VEC3 c ;
switch(Hi)
{
case(0) :
{
c = VEC3(v,n,l) ;
}
break ;
case(1):
{
c = VEC3(m,v,l) ;
}
break ;
case(2):
{
c = VEC3(l,v,n) ;