Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
Sauvage
CGoGN
Commits
ab4545fa
Commit
ab4545fa
authored
Feb 15, 2013
by
Sylvain Thery
Browse files
Merge cgogn:~vanhoey/CGoGN
parents
bac3af1b
277688bd
Changes
7
Expand all
Hide whitespace changes
Inline
Side-by-side
include/Algo/Decimation/decimation.hpp
View file @
ab4545fa
...
...
@@ -196,6 +196,12 @@ void decimate(
case
S_hLightfieldKCL
:
selector
=
new
HalfEdgeSelector_LightfieldKCL
<
PFP
>
(
map
,
position
,
approximators
)
;
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
)
...
...
@@ -213,9 +219,6 @@ void decimate(
return
;
}
if
(
edgeErrors
!=
NULL
)
selector
->
getEdgeErrors
(
edgeErrors
)
;
unsigned
int
nbVertices
=
map
.
template
getNbOrbits
<
VERTEX
>()
;
bool
finished
=
false
;
Dart
d
;
...
...
@@ -257,6 +260,9 @@ void decimate(
callback_wrapper
(
callback_object
,
&
nbVertices
)
;
}
if
(
edgeErrors
!=
NULL
)
selector
->
getEdgeErrors
(
edgeErrors
)
;
delete
selector
;
for
(
typename
std
::
vector
<
ApproximatorGen
<
PFP
>*>::
iterator
it
=
approximators
.
begin
();
it
!=
approximators
.
end
();
++
it
)
...
...
include/Algo/Decimation/halfEdgeSelector.h
View file @
ab4545fa
...
...
@@ -466,7 +466,7 @@ public:
(
*
errors
)[
d
]
=
halfEdgeInfo
[
d
].
it
->
first
;
}
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
;
}
...
...
@@ -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 Surface
}
// namespace Algo
...
...
include/Algo/Decimation/halfEdgeSelector.hpp
View file @
ab4545fa
This diff is collapsed.
Click to expand it.
include/Algo/Decimation/selector.h
View file @
ab4545fa
...
...
@@ -56,7 +56,9 @@ enum SelectorType
S_hQEMml
,
S_hLightfield
,
S_hLightfieldExp
,
S_hLightfieldKCL
S_hLightfieldKCL
,
S_hColorExperimental
,
S_hLFexperimental
}
;
template
<
typename
PFP
>
class
ApproximatorGen
;
...
...
include/Geometry/plane_3d.h
View file @
ab4545fa
...
...
@@ -25,6 +25,8 @@
#ifndef __PLANE_3D__
#define __PLANE_3D__
#include
"Geometry/vector_gen.h"
namespace
CGoGN
{
...
...
include/Utils/colourConverter.h
View file @
ab4545fa
...
...
@@ -58,11 +58,12 @@ public: // types
*/
enum
ColourEncoding
{
C_RGB
=
0
,
C_XYZ
=
1
,
C_Luv
=
2
,
C_Lab
=
3
,
C_HSV
=
4
C_RGB
=
0
,
/*!< R,G,B in [0,1] */
C_XYZ
=
1
,
/*!< X,Y,Z in [0,1] */
C_Luv
=
2
,
/*!< L in [0,100], u in [-83,175], v in [-134,108] */
C_Lab
=
3
,
/*!< L in [0,100], u in [-86,98], v in [-108,95] */
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 */
...
...
@@ -109,6 +110,11 @@ public: // methods
* @return Lab value of provided colour
*/
VEC3
getHSV
()
;
/**
* getR
* @return HSL value of provided colour
*/
VEC3
getHSL
()
;
/**
* getR
* @return XYZ value of provided colour
...
...
@@ -124,6 +130,7 @@ private: // private members
VEC3
*
Lab
;
VEC3
*
HSV
;
VEC3
*
XYZ
;
VEC3
*
HSL
;
bool
convert
(
enum
ColourEncoding
from
,
enum
ColourEncoding
to
)
;
void
convertRGBtoXYZ
()
;
...
...
@@ -135,9 +142,30 @@ private: // private members
void
convertXYZtoLab
()
;
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
()
;
/**
* 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
()
;
/**
* 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
// D65 reference white
static
const
REAL
Xn
=
0.950456
;
...
...
include/Utils/colourConverter.hpp
View file @
ab4545fa
...
...
@@ -32,7 +32,8 @@ ColourConverter<REAL>::ColourConverter(const VEC3& col, const enum ColourEncodin
Luv
(
NULL
),
Lab
(
NULL
),
HSV
(
NULL
),
XYZ
(
NULL
)
XYZ
(
NULL
),
HSL
(
NULL
)
{
originalEnc
=
enc
;
...
...
@@ -70,12 +71,18 @@ ColourConverter<REAL>::ColourConverter(const VEC3& col, const enum ColourEncodin
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
;
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
HSV
color was entered in ColourConverter constructor"
<<
std
::
endl
;
#endif
HSV
=
new
VEC3
(
col
)
;
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()
delete
XYZ
;
delete
Lab
;
delete
HSV
;
delete
HSL
;
}
template
<
typename
REAL
>
...
...
@@ -112,6 +120,10 @@ Geom::Vector<3,REAL> ColourConverter<REAL>::getColour(enum ColourEncoding enc) {
return
getHSV
()
;
break
;
case
(
C_HSL
)
:
return
getHSL
()
;
break
;
default
:
assert
(
!
"Should never arrive here : ColourConverter::getColour default case"
)
;
return
getOriginal
()
;
...
...
@@ -119,12 +131,16 @@ Geom::Vector<3,REAL> ColourConverter<REAL>::getColour(enum ColourEncoding enc) {
}
template
<
typename
REAL
>
Geom
::
Vector
<
3
,
REAL
>
ColourConverter
<
REAL
>::
getOriginal
()
{
Geom
::
Vector
<
3
,
REAL
>
ColourConverter
<
REAL
>::
getOriginal
()
{
return
getColour
(
this
->
originalEnc
)
;
}
template
<
typename
REAL
>
Geom
::
Vector
<
3
,
REAL
>
ColourConverter
<
REAL
>::
getRGB
()
{
Geom
::
Vector
<
3
,
REAL
>
ColourConverter
<
REAL
>::
getRGB
()
{
if
(
RGB
==
NULL
)
convert
(
originalEnc
,
C_RGB
)
;
...
...
@@ -132,7 +148,9 @@ Geom::Vector<3,REAL> ColourConverter<REAL>::getRGB() {
}
template
<
typename
REAL
>
Geom
::
Vector
<
3
,
REAL
>
ColourConverter
<
REAL
>::
getLuv
()
{
Geom
::
Vector
<
3
,
REAL
>
ColourConverter
<
REAL
>::
getLuv
()
{
if
(
Luv
==
NULL
)
convert
(
originalEnc
,
C_Luv
)
;
...
...
@@ -140,7 +158,9 @@ Geom::Vector<3,REAL> ColourConverter<REAL>::getLuv() {
}
template
<
typename
REAL
>
Geom
::
Vector
<
3
,
REAL
>
ColourConverter
<
REAL
>::
getLab
()
{
Geom
::
Vector
<
3
,
REAL
>
ColourConverter
<
REAL
>::
getLab
()
{
if
(
Lab
==
NULL
)
convert
(
originalEnc
,
C_Lab
)
;
...
...
@@ -148,7 +168,9 @@ Geom::Vector<3,REAL> ColourConverter<REAL>::getLab() {
}
template
<
typename
REAL
>
Geom
::
Vector
<
3
,
REAL
>
ColourConverter
<
REAL
>::
getXYZ
()
{
Geom
::
Vector
<
3
,
REAL
>
ColourConverter
<
REAL
>::
getXYZ
()
{
if
(
XYZ
==
NULL
)
{
convert
(
originalEnc
,
C_XYZ
)
;
}
...
...
@@ -157,7 +179,9 @@ Geom::Vector<3,REAL> ColourConverter<REAL>::getXYZ() {
}
template
<
typename
REAL
>
Geom
::
Vector
<
3
,
REAL
>
ColourConverter
<
REAL
>::
getHSV
()
{
Geom
::
Vector
<
3
,
REAL
>
ColourConverter
<
REAL
>::
getHSV
()
{
if
(
HSV
==
NULL
)
convert
(
originalEnc
,
C_HSV
)
;
...
...
@@ -165,7 +189,20 @@ Geom::Vector<3,REAL> ColourConverter<REAL>::getHSV() {
}
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
;
M
(
0
,
0
)
=
0.412453
;
...
...
@@ -189,7 +226,9 @@ void ColourConverter<REAL>::convertRGBtoXYZ() {
}
template
<
typename
REAL
>
void
ColourConverter
<
REAL
>::
convertXYZtoRGB
()
{
void
ColourConverter
<
REAL
>::
convertXYZtoRGB
()
{
Geom
::
Matrix
<
3
,
3
,
REAL
>
M
;
M
(
0
,
0
)
=
3.240479
;
...
...
@@ -213,7 +252,8 @@ void ColourConverter<REAL>::convertXYZtoRGB() {
}
template
<
typename
REAL
>
void
ColourConverter
<
REAL
>::
convertRGBtoHSV
()
void
ColourConverter
<
REAL
>::
convertRGBtoHSV
()
{
const
REAL
&
r
=
(
*
RGB
)[
0
]
;
const
REAL
&
g
=
(
*
RGB
)[
1
]
;
...
...
@@ -221,27 +261,38 @@ void ColourConverter<REAL>::convertRGBtoHSV()
const
REAL
&
max
=
std
::
max
(
std
::
max
(
r
,
g
),
b
)
;
const
REAL
&
min
=
std
::
min
(
std
::
min
(
r
,
g
),
b
)
;
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
)
{
c
[
0
]
=
0
;
}
else
if
(
max
==
r
)
{
c
[
0
]
=
60
*
(
g
-
b
)
/
(
max
-
min
)
+
360
;
c
[
0
]
=
(
unsigned
int
)(
c
[
0
])
%
360
;
H
=
0
;
}
else
if
(
max
==
g
)
{
c
[
0
]
=
60
*
(
b
-
r
)
/
(
max
-
min
)
+
120
;
}
else
if
(
max
==
b
)
else
{
c
[
0
]
=
60
*
(
r
-
g
)
/
(
max
-
min
)
+
240
;
if
(
max
==
r
)
{
H
=
(
g
-
b
)
/
diff
+
(
g
<
b
?
6
:
0
)
;
}
else
if
(
max
==
g
)
{
H
=
(
b
-
r
)
/
diff
+
2
;
}
else
if
(
max
==
b
)
{
H
=
(
r
-
g
)
/
diff
+
4
;
}
}
c
[
1
]
=
(
max
==
0
)
?
0
:
1
-
min
/
max
;
c
[
2
]
=
max
;
H
/=
6.
;
if
(
HSV
!=
NULL
)
*
HSV
=
c
;
...
...
@@ -250,54 +301,134 @@ void ColourConverter<REAL>::convertRGBtoHSV()
}
template
<
typename
REAL
>
void
ColourConverter
<
REAL
>::
convertHSVtoRGB
()
void
ColourConverter
<
REAL
>::
convertHSVtoRGB
()
{
const
REAL
&
H
=
(
*
HSV
)[
0
]
;
const
REAL
&
s
=
(
*
HSV
)[
1
]
;
const
REAL
&
v
=
(
*
HSV
)[
2
]
;
const
REAL
&
S
=
(
*
HSV
)[
1
]
;
const
REAL
&
V
=
(
*
HSV
)[
2
]
;
const
unsigned
int
H
i
=
(
unsigned
int
)(
floor
(
H
/
6
0
))
%
6
;
const
REAL
f
=
(
H
/
6
0
)
-
Hi
;
const
REAL
l
=
v
*
(
1
-
s
)
;
const
REAL
m
=
v
*
(
1
-
f
*
s
)
;
const
REAL
n
=
v
*
(
1
-
(
1
-
f
)
*
s
)
;
const
int
i
=
std
::
floor
(
H
*
6
)
;
const
REAL
f
=
H
*
6
-
i
;
const
REAL
p
=
V
*
(
1
-
S
)
;
const
REAL
q
=
V
*
(
1
-
f
*
S
)
;
const
REAL
t
=
V
*
(
1
-
(
1
-
f
)
*
S
)
;
VEC3
c
;
switch
(
Hi
)
REAL
&
r
=
c
[
0
]
;
REAL
&
g
=
c
[
1
]
;
REAL
&
b
=
c
[
2
]
;
switch
(
i
%
6
)
{
case
(
0
)
:
{
c
=
VEC3
(
v
,
n
,
l
)
;
}
break
;
case
(
1
):
{
c
=
VEC3
(
m
,
v
,
l
)
;
}
break
;
case
(
2
):
case
0
:
r
=
V
,
g
=
t
,
b
=
p
;
break
;
case
1
:
r
=
q
,
g
=
V
,
b
=
p
;
break
;
case
2
:
r
=
p
,
g
=
V
,
b
=
t
;
break
;
case
3
:
r
=
p
,
g
=
q
,
b
=
V
;
break
;
case
4
:
r
=
t
,
g
=
p
,
b
=
V
;
break
;
case
5
:
r
=
V
,
g
=
p
,
b
=
q
;
break
;
}
if
(
RGB
!=
NULL
)
*
RGB
=
c
;
else
RGB
=
new
VEC3
(
c
)
;
}
template
<
typename
REAL
>
void