Commit ab4545fa authored by Sylvain Thery's avatar Sylvain Thery

Merge cgogn:~vanhoey/CGoGN

parents bac3af1b 277688bd
...@@ -196,6 +196,12 @@ void decimate( ...@@ -196,6 +196,12 @@ void decimate(
case S_hLightfieldKCL : case S_hLightfieldKCL :
selector = new HalfEdgeSelector_LightfieldKCL<PFP>(map, position, approximators) ; selector = new HalfEdgeSelector_LightfieldKCL<PFP>(map, position, approximators) ;
break ; break ;
case S_hColorExperimental:
selector = new HalfEdgeSelector_ColorExperimental<PFP>(map, position, approximators, selected) ;
break ;
case S_hLFexperimental:
selector = new HalfEdgeSelector_LFexperimental<PFP>(map, position, approximators, selected) ;
break ;
} }
for(typename std::vector<ApproximatorGen<PFP>*>::iterator it = approximators.begin(); it != approximators.end(); ++it) for(typename std::vector<ApproximatorGen<PFP>*>::iterator it = approximators.begin(); it != approximators.end(); ++it)
...@@ -213,9 +219,6 @@ void decimate( ...@@ -213,9 +219,6 @@ void decimate(
return ; return ;
} }
if (edgeErrors != NULL)
selector->getEdgeErrors(edgeErrors) ;
unsigned int nbVertices = map.template getNbOrbits<VERTEX>() ; unsigned int nbVertices = map.template getNbOrbits<VERTEX>() ;
bool finished = false ; bool finished = false ;
Dart d ; Dart d ;
...@@ -257,6 +260,9 @@ void decimate( ...@@ -257,6 +260,9 @@ void decimate(
callback_wrapper(callback_object, &nbVertices) ; callback_wrapper(callback_object, &nbVertices) ;
} }
if (edgeErrors != NULL)
selector->getEdgeErrors(edgeErrors) ;
delete selector ; delete selector ;
for(typename std::vector<ApproximatorGen<PFP>*>::iterator it = approximators.begin(); it != approximators.end(); ++it) for(typename std::vector<ApproximatorGen<PFP>*>::iterator it = approximators.begin(); it != approximators.end(); ++it)
......
...@@ -466,7 +466,7 @@ public: ...@@ -466,7 +466,7 @@ public:
(*errors)[d] = halfEdgeInfo[d].it->first ; (*errors)[d] = halfEdgeInfo[d].it->first ;
} }
Dart dd = this->m_map.phi2(d) ; Dart dd = this->m_map.phi2(d) ;
if (halfEdgeInfo[dd].valid && halfEdgeInfo[dd].it->first > (*errors)[d]) if (halfEdgeInfo[dd].valid && halfEdgeInfo[dd].it->first < (*errors)[d])
{ {
(*errors)[dd] = halfEdgeInfo[dd].it->first ; (*errors)[dd] = halfEdgeInfo[dd].it->first ;
} }
...@@ -475,10 +475,202 @@ public: ...@@ -475,10 +475,202 @@ public:
} }
} ; } ;
/*****************************************************************************************************************
* HALF-EDGE COLOR EXPERIMENTAL *
*****************************************************************************************************************/
template <typename PFP>
class HalfEdgeSelector_ColorExperimental : public EdgeSelector<PFP>
{
public:
typedef typename PFP::MAP MAP ;
typedef typename PFP::REAL REAL ;
typedef typename PFP::VEC3 VEC3 ;
private:
typedef struct
{
typename std::multimap<float,Dart>::iterator it ;
bool valid ;
static std::string CGoGNnameOfType() { return "ColorExperimentalHalfEdgeInfo" ; }
} QEMextColorHalfEdgeInfo ;
typedef NoMathIOAttribute<QEMextColorHalfEdgeInfo> HalfEdgeInfo ;
DartAttribute<HalfEdgeInfo> halfEdgeInfo ;
VertexAttribute<Utils::Quadric<REAL> > m_quadric ;
VertexAttribute<VEC3> m_pos, m_color ;
int m_approxindex_pos, m_attrindex_pos ;
int m_approxindex_color, m_attrindex_color ;
std::vector<Approximator<PFP, typename PFP::VEC3,DART>* > m_approx ;
std::multimap<float,Dart> halfEdges ;
typename std::multimap<float,Dart>::iterator cur ;
void initHalfEdgeInfo(Dart d) ;
void updateHalfEdgeInfo(Dart d) ;
void computeHalfEdgeInfo(Dart d, HalfEdgeInfo& einfo) ;
//void recomputeQuadric(const Dart d, const bool recomputeNeighbors = false) ;
void recomputeQuadric(const Dart d) ;
typename PFP::REAL computeExperimentalColorError(const Dart& v0, const Dart& v1) ;
public:
HalfEdgeSelector_ColorExperimental(MAP& m, VertexAttribute<typename PFP::VEC3>& pos, std::vector<ApproximatorGen<PFP>*>& approx, const FunctorSelect& select = allDarts) :
EdgeSelector<PFP>(m, pos, approx, select),
m_approxindex_pos(-1),
m_attrindex_pos(-1),
m_approxindex_color(-1),
m_attrindex_color(-1)
{
halfEdgeInfo = m.template addAttribute<HalfEdgeInfo, DART>("halfEdgeInfo") ;
m_quadric = m.template addAttribute<Utils::Quadric<REAL>, VERTEX>("QEMquadric") ;
}
~HalfEdgeSelector_ColorExperimental()
{
this->m_map.removeAttribute(m_quadric) ;
this->m_map.removeAttribute(halfEdgeInfo) ;
}
SelectorType getType() { return S_hColorExperimental ; }
bool init() ;
bool nextEdge(Dart& d) ;
void updateBeforeCollapse(Dart d) ;
void updateAfterCollapse(Dart d2, Dart dd2) ;
void updateWithoutCollapse() { }
void getEdgeErrors(EdgeAttribute<typename PFP::REAL> *errors)
{
assert(errors != NULL || !"EdgeSelector::setColorMap requires non null vertexattribute argument") ;
if (!errors->isValid())
std::cerr << "EdgeSelector::setColorMap requires valid edgeattribute argument" << std::endl ;
assert(halfEdgeInfo.isValid()) ;
TraversorE<typename PFP::MAP> travE(this->m_map) ;
for(Dart d = travE.begin() ; d != travE.end() ; d = travE.next())
{
(*errors)[d] = -1 ;
if (halfEdgeInfo[d].valid)
{
(*errors)[d] = halfEdgeInfo[d].it->first ;
}
Dart dd = this->m_map.phi2(d) ;
if (halfEdgeInfo[dd].valid && halfEdgeInfo[dd].it->first < (*errors)[d])
{
(*errors)[d] = halfEdgeInfo[dd].it->first ;
}
}
}
} ;
/*****************************************************************************************************************
* HALF-EDGE LF EXPERIMENTAL METRIC *
*****************************************************************************************************************/
template <typename PFP>
class HalfEdgeSelector_LFexperimental : public EdgeSelector<PFP>
{
public:
typedef typename PFP::MAP MAP ;
typedef typename PFP::REAL REAL ;
typedef typename PFP::VEC3 VEC3 ;
private:
typedef struct
{
typename std::multimap<float,Dart>::iterator it ;
bool valid ;
static std::string CGoGNnameOfType() { return "LightfieldExpHalfEdgeInfo" ; }
} LightfieldHalfEdgeInfo ;
typedef NoMathIOAttribute<LightfieldHalfEdgeInfo> HalfEdgeInfo ;
DartAttribute<HalfEdgeInfo> halfEdgeInfo ;
VertexAttribute<Utils::Quadric<REAL> > m_quadric ;
VertexAttribute<REAL> m_visualImportance ;
VertexAttribute<VEC3> m_avgColor ;
int m_approxindex_pos, m_attrindex_pos ;
int m_approxindex_FT, m_attrindex_FT ;
int m_approxindex_FB, m_attrindex_FB ;
int m_approxindex_FN, m_attrindex_FN ;
std::vector<unsigned int> m_approxindex_HF, m_attrindex_HF ;
unsigned int m_K ;
std::vector<Approximator<PFP, typename PFP::VEC3,DART>* > m_approx ;
std::multimap<float,Dart> halfEdges ;
typename std::multimap<float,Dart>::iterator cur ;
void initHalfEdgeInfo(Dart d) ;
void updateHalfEdgeInfo(Dart d) ;
void computeHalfEdgeInfo(Dart d, HalfEdgeInfo& einfo) ;
void recomputeQuadric(const Dart d) ;
REAL computeLightfieldError(const Dart& v0, const Dart& v1) ;
REAL computeSquaredLightfieldDifference(const Dart& d1, const Dart& d2) ;
public:
HalfEdgeSelector_LFexperimental(MAP& m, VertexAttribute<typename PFP::VEC3>& pos, std::vector<ApproximatorGen<PFP>*>& approx, const FunctorSelect& select = allDarts) :
EdgeSelector<PFP>(m, pos, approx, select),
m_approxindex_pos(-1),
m_attrindex_pos(-1),
m_approxindex_FT(-1),
m_attrindex_FT(-1),
m_approxindex_FB(-1),
m_attrindex_FB(-1),
m_approxindex_FN(-1),
m_attrindex_FN(-1),
m_K(0)
{
halfEdgeInfo = m.template addAttribute<HalfEdgeInfo, DART>("halfEdgeInfo") ;
m_quadric = m.template addAttribute<Utils::Quadric<REAL>, VERTEX>("QEMquadric") ;
m_avgColor = m.template getAttribute<typename PFP::VEC3, VERTEX>("color") ;
assert(m_avgColor.isValid()) ;
}
~HalfEdgeSelector_LFexperimental()
{
this->m_map.removeAttribute(m_quadric) ;
this->m_map.removeAttribute(halfEdgeInfo) ;
}
SelectorType getType() { return S_hLFexperimental ; }
bool init() ;
bool nextEdge(Dart& d) ;
void updateBeforeCollapse(Dart d) ;
void updateAfterCollapse(Dart d2, Dart dd2) ;
void updateWithoutCollapse() { }
void getEdgeErrors(EdgeAttribute<typename PFP::REAL> *errors)
{
assert(errors != NULL || !"EdgeSelector::setColorMap requires non null vertexattribute argument") ;
if (!errors->isValid())
std::cerr << "EdgeSelector::setColorMap requires valid edgeattribute argument" << std::endl ;
assert(halfEdgeInfo.isValid()) ;
TraversorE<typename PFP::MAP> travE(this->m_map) ;
for(Dart d = travE.begin() ; d != travE.end() ; d = travE.next())
{
(*errors)[d] = -1 ;
if (halfEdgeInfo[d].valid)
{
(*errors)[d] = halfEdgeInfo[d].it->first ;
}
Dart dd = this->m_map.phi2(d) ;
if (halfEdgeInfo[dd].valid && halfEdgeInfo[dd].it->first < (*errors)[d])
{
(*errors)[d] = halfEdgeInfo[dd].it->first ;
}
}
}
} ;
} // namespace Decimation } // namespace Decimation
} } // namespace Surface
} // namespace Algo } // namespace Algo
......
...@@ -56,7 +56,9 @@ enum SelectorType ...@@ -56,7 +56,9 @@ enum SelectorType
S_hQEMml, S_hQEMml,
S_hLightfield, S_hLightfield,
S_hLightfieldExp, S_hLightfieldExp,
S_hLightfieldKCL S_hLightfieldKCL,
S_hColorExperimental,
S_hLFexperimental
} ; } ;
template <typename PFP> class ApproximatorGen ; template <typename PFP> class ApproximatorGen ;
......
...@@ -25,6 +25,8 @@ ...@@ -25,6 +25,8 @@
#ifndef __PLANE_3D__ #ifndef __PLANE_3D__
#define __PLANE_3D__ #define __PLANE_3D__
#include "Geometry/vector_gen.h"
namespace CGoGN namespace CGoGN
{ {
......
...@@ -58,11 +58,12 @@ public: // types ...@@ -58,11 +58,12 @@ public: // types
*/ */
enum ColourEncoding enum ColourEncoding
{ {
C_RGB = 0, C_RGB = 0, /*!< R,G,B in [0,1] */
C_XYZ = 1, C_XYZ = 1, /*!< X,Y,Z in [0,1] */
C_Luv = 2, C_Luv = 2, /*!< L in [0,100], u in [-83,175], v in [-134,108] */
C_Lab = 3, C_Lab = 3, /*!< L in [0,100], u in [-86,98], v in [-108,95] */
C_HSV = 4 C_HSV = 4, /*!< H,S,V in [0,1] */
C_HSL = 5 /*!< H,S,L in [0,1] */
} ; } ;
typedef Geom::Vector<3,REAL> VEC3 ; /*!< Triplet for color encoding */ typedef Geom::Vector<3,REAL> VEC3 ; /*!< Triplet for color encoding */
...@@ -109,6 +110,11 @@ public: // methods ...@@ -109,6 +110,11 @@ public: // methods
* @return Lab value of provided colour * @return Lab value of provided colour
*/ */
VEC3 getHSV() ; VEC3 getHSV() ;
/**
* getR
* @return HSL value of provided colour
*/
VEC3 getHSL() ;
/** /**
* getR * getR
* @return XYZ value of provided colour * @return XYZ value of provided colour
...@@ -124,6 +130,7 @@ private: // private members ...@@ -124,6 +130,7 @@ private: // private members
VEC3 *Lab ; VEC3 *Lab ;
VEC3 *HSV ; VEC3 *HSV ;
VEC3 *XYZ ; VEC3 *XYZ ;
VEC3 *HSL ;
bool convert(enum ColourEncoding from, enum ColourEncoding to) ; bool convert(enum ColourEncoding from, enum ColourEncoding to) ;
void convertRGBtoXYZ() ; void convertRGBtoXYZ() ;
...@@ -135,9 +142,30 @@ private: // private members ...@@ -135,9 +142,30 @@ private: // private members
void convertXYZtoLab() ; void convertXYZtoLab() ;
void convertLabToXYZ() ; void convertLabToXYZ() ;
/**
* Converts RGB to HSV. All is normalized between 0 and 1.
* Conversion formula adapted from http://en.wikipedia.org/wiki/HSL_color_space.
*/
void convertRGBtoHSV() ; void convertRGBtoHSV() ;
/**
* Converts HSV to RGB. All is normalized between 0 and 1.
* Conversion formula adapted from http://en.wikipedia.org/wiki/HSL_color_space.
*/
void convertHSVtoRGB() ; void convertHSVtoRGB() ;
/**
* Converts RGB to HSL. All is normalized between 0 and 1.
* Conversion formula adapted from http://en.wikipedia.org/wiki/HSL_color_space.
*/
void convertRGBtoHSL() ;
/**
* Converts HSL to RGB. All is normalized between 0 and 1.
* Conversion formula adapted from http://en.wikipedia.org/wiki/HSL_color_space.
*/
void convertHSLtoRGB() ;
static REAL hue2rgb(const REAL& p, const REAL& q, REAL t) ;
private: // private constants private: // private constants
// D65 reference white // D65 reference white
static const REAL Xn = 0.950456 ; static const REAL Xn = 0.950456 ;
......
...@@ -32,7 +32,8 @@ ColourConverter<REAL>::ColourConverter(const VEC3& col, const enum ColourEncodin ...@@ -32,7 +32,8 @@ ColourConverter<REAL>::ColourConverter(const VEC3& col, const enum ColourEncodin
Luv(NULL), Luv(NULL),
Lab(NULL), Lab(NULL),
HSV(NULL), HSV(NULL),
XYZ(NULL) XYZ(NULL),
HSL(NULL)
{ {
originalEnc = enc ; originalEnc = enc ;
...@@ -70,12 +71,18 @@ ColourConverter<REAL>::ColourConverter(const VEC3& col, const enum ColourEncodin ...@@ -70,12 +71,18 @@ ColourConverter<REAL>::ColourConverter(const VEC3& col, const enum ColourEncodin
break ; break ;
case (C_HSV) : case (C_HSV) :
#ifdef DEBUG #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)) if (!(-0.001 < col[0] && col[0] < 1.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 ; std::cerr << "Warning : an unvalid HSV color was entered in ColourConverter constructor" << std::endl ;
#endif #endif
HSV = new VEC3(col) ; HSV = new VEC3(col) ;
break ; break ;
case (C_HSL) :
#ifdef DEBUG
if (!(-0.001 < col[0] && col[0] < 1.001 && -0.001 < col[1] && col[1] < 1.001 && -0.001 < col[2] && col[2] < 1.001))
std::cerr << "Warning : an unvalid HSL color was entered in ColourConverter constructor" << std::endl ;
#endif
HSL = new VEC3(col) ;
break ;
} }
} }
...@@ -87,6 +94,7 @@ ColourConverter<REAL>::~ColourConverter() ...@@ -87,6 +94,7 @@ ColourConverter<REAL>::~ColourConverter()
delete XYZ ; delete XYZ ;
delete Lab ; delete Lab ;
delete HSV ; delete HSV ;
delete HSL ;
} }
template<typename REAL> template<typename REAL>
...@@ -112,6 +120,10 @@ Geom::Vector<3,REAL> ColourConverter<REAL>::getColour(enum ColourEncoding enc) { ...@@ -112,6 +120,10 @@ Geom::Vector<3,REAL> ColourConverter<REAL>::getColour(enum ColourEncoding enc) {
return getHSV() ; return getHSV() ;
break ; break ;
case (C_HSL) :
return getHSL() ;
break ;
default : default :
assert(!"Should never arrive here : ColourConverter::getColour default case") ; assert(!"Should never arrive here : ColourConverter::getColour default case") ;
return getOriginal() ; return getOriginal() ;
...@@ -119,12 +131,16 @@ Geom::Vector<3,REAL> ColourConverter<REAL>::getColour(enum ColourEncoding enc) { ...@@ -119,12 +131,16 @@ Geom::Vector<3,REAL> ColourConverter<REAL>::getColour(enum ColourEncoding enc) {
} }
template<typename REAL> template<typename REAL>
Geom::Vector<3,REAL> ColourConverter<REAL>::getOriginal() { Geom::Vector<3,REAL>
ColourConverter<REAL>::getOriginal()
{
return getColour(this->originalEnc) ; return getColour(this->originalEnc) ;
} }
template<typename REAL> template<typename REAL>
Geom::Vector<3,REAL> ColourConverter<REAL>::getRGB() { Geom::Vector<3,REAL>
ColourConverter<REAL>::getRGB()
{
if (RGB == NULL) if (RGB == NULL)
convert(originalEnc,C_RGB) ; convert(originalEnc,C_RGB) ;
...@@ -132,7 +148,9 @@ Geom::Vector<3,REAL> ColourConverter<REAL>::getRGB() { ...@@ -132,7 +148,9 @@ Geom::Vector<3,REAL> ColourConverter<REAL>::getRGB() {
} }
template<typename REAL> template<typename REAL>
Geom::Vector<3,REAL> ColourConverter<REAL>::getLuv() { Geom::Vector<3,REAL>
ColourConverter<REAL>::getLuv()
{
if (Luv == NULL) if (Luv == NULL)
convert(originalEnc,C_Luv) ; convert(originalEnc,C_Luv) ;
...@@ -140,7 +158,9 @@ Geom::Vector<3,REAL> ColourConverter<REAL>::getLuv() { ...@@ -140,7 +158,9 @@ Geom::Vector<3,REAL> ColourConverter<REAL>::getLuv() {
} }
template<typename REAL> template<typename REAL>
Geom::Vector<3,REAL> ColourConverter<REAL>::getLab() { Geom::Vector<3,REAL>
ColourConverter<REAL>::getLab()
{
if (Lab == NULL) if (Lab == NULL)
convert(originalEnc,C_Lab) ; convert(originalEnc,C_Lab) ;
...@@ -148,7 +168,9 @@ Geom::Vector<3,REAL> ColourConverter<REAL>::getLab() { ...@@ -148,7 +168,9 @@ Geom::Vector<3,REAL> ColourConverter<REAL>::getLab() {
} }
template<typename REAL> template<typename REAL>
Geom::Vector<3,REAL> ColourConverter<REAL>::getXYZ() { Geom::Vector<3,REAL>
ColourConverter<REAL>::getXYZ()
{
if (XYZ == NULL) { if (XYZ == NULL) {
convert(originalEnc,C_XYZ) ; convert(originalEnc,C_XYZ) ;
} }
...@@ -157,7 +179,9 @@ Geom::Vector<3,REAL> ColourConverter<REAL>::getXYZ() { ...@@ -157,7 +179,9 @@ Geom::Vector<3,REAL> ColourConverter<REAL>::getXYZ() {
} }
template<typename REAL> template<typename REAL>
Geom::Vector<3,REAL> ColourConverter<REAL>::getHSV() { Geom::Vector<3,REAL>
ColourConverter<REAL>::getHSV()
{
if (HSV == NULL) if (HSV == NULL)
convert(originalEnc,C_HSV) ; convert(originalEnc,C_HSV) ;
...@@ -165,7 +189,20 @@ Geom::Vector<3,REAL> ColourConverter<REAL>::getHSV() { ...@@ -165,7 +189,20 @@ Geom::Vector<3,REAL> ColourConverter<REAL>::getHSV() {
} }
template<typename REAL> template<typename REAL>
void ColourConverter<REAL>::convertRGBtoXYZ() { Geom::Vector<3,REAL>
ColourConverter<REAL>::getHSL()
{
if (HSL == NULL)
convert(originalEnc,C_HSL) ;
return *HSL ;
}
template<typename REAL>
void
ColourConverter<REAL>::convertRGBtoXYZ()
{
Geom::Matrix<3,3,REAL> M ; Geom::Matrix<3,3,REAL> M ;
M(0,0) = 0.412453 ; M(0,0) = 0.412453 ;
...@@ -189,7 +226,9 @@ void ColourConverter<REAL>::convertRGBtoXYZ() { ...@@ -189,7 +226,9 @@ void ColourConverter<REAL>::convertRGBtoXYZ() {
} }
template<typename REAL> template<typename REAL>
void ColourConverter<REAL>::convertXYZtoRGB() { void
ColourConverter<REAL>::convertXYZtoRGB()
{
Geom::Matrix<3,3,REAL> M ; Geom::Matrix<3,3,REAL> M ;
M(0,0) = 3.240479 ; M(0,0) = 3.240479 ;
...@@ -213,7 +252,8 @@ void ColourConverter<REAL>::convertXYZtoRGB() { ...@@ -213,7 +252,8 @@ void ColourConverter<REAL>::convertXYZtoRGB() {
} }
template<typename REAL> template<typename REAL>
void ColourConverter<REAL>::convertRGBtoHSV() void
ColourConverter<REAL>::convertRGBtoHSV()
{ {
const REAL& r = (*RGB)[0] ; const REAL& r = (*RGB)[0] ;
const REAL& g = (*RGB)[1] ; const REAL& g = (*RGB)[1] ;
...@@ -221,27 +261,38 @@ void ColourConverter<REAL>::convertRGBtoHSV() ...@@ -221,27 +261,38 @@ void ColourConverter<REAL>::convertRGBtoHSV()
const REAL& max = std::max(std::max(r,g),b) ; const REAL& max = std::max(std::max(r,g),b) ;
const REAL& min = std::min(std::min(r,g),b) ; const REAL& min = std::min(std::min(r,g),b) ;
VEC3 c ; VEC3 c ;
REAL& H = c[0] ;
REAL& S = c[1] ;
REAL& V = c[2] ;
const REAL diff = max - min ;
V = max ;
S = max == 0. ? 0 : diff / max ;
if (max == min) if (max == min)
{ {
c[0] = 0 ; H = 0 ;
}
else if (max == r)