Added color processing functions.
Some changes still to be performed.
This commit is contained in:
parent
9debed15de
commit
6be78dcf70
|
@ -8,7 +8,7 @@
|
||||||
* \ *
|
* \ *
|
||||||
* All rights reserved. *
|
* All rights reserved. *
|
||||||
* *
|
* *
|
||||||
* This program is free software; you can redistribute it and/or modify *
|
* This program is free software; you can redistribute it and/or modify *
|
||||||
* it under the terms of the GNU General Public License as published by *
|
* it under the terms of the GNU General Public License as published by *
|
||||||
* the Free Software Foundation; either version 2 of the License, or *
|
* the Free Software Foundation; either version 2 of the License, or *
|
||||||
* (at your option) any later version. *
|
* (at your option) any later version. *
|
||||||
|
@ -69,12 +69,12 @@ Changed name from plural to singular (normals->normal)
|
||||||
namespace vcg {
|
namespace vcg {
|
||||||
namespace tri {
|
namespace tri {
|
||||||
|
|
||||||
/// \ingroup trimesh
|
/// \ingroup trimesh
|
||||||
|
|
||||||
/// \headerfile color.h vcg/complex/trimesh/update/color.h
|
/// \headerfile color.h vcg/complex/trimesh/update/color.h
|
||||||
|
|
||||||
/// \brief Generation of per-vertex and per-face colors according to various strategy.
|
/// \brief Generation of per-vertex and per-face colors according to various strategy.
|
||||||
/**
|
/**
|
||||||
This class is used to compute per face or per vertex color with respect to for example Border (UpdateColor::VertexBorderFlag), Selection (UpdateColor::FaceSelected), Quality .
|
This class is used to compute per face or per vertex color with respect to for example Border (UpdateColor::VertexBorderFlag), Selection (UpdateColor::FaceSelected), Quality .
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -82,7 +82,7 @@ template <class UpdateMeshType>
|
||||||
class UpdateColor
|
class UpdateColor
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
typedef UpdateMeshType MeshType;
|
typedef UpdateMeshType MeshType;
|
||||||
typedef typename UpdateMeshType::VertexType VertexType;
|
typedef typename UpdateMeshType::VertexType VertexType;
|
||||||
typedef typename UpdateMeshType::VertexPointer VertexPointer;
|
typedef typename UpdateMeshType::VertexPointer VertexPointer;
|
||||||
typedef typename UpdateMeshType::VertexIterator VertexIterator;
|
typedef typename UpdateMeshType::VertexIterator VertexIterator;
|
||||||
|
@ -93,7 +93,7 @@ typedef typename UpdateMeshType::FaceIterator FaceIterator;
|
||||||
/// \brief Color the vertexes of the mesh that are on the border
|
/// \brief Color the vertexes of the mesh that are on the border
|
||||||
|
|
||||||
/**
|
/**
|
||||||
It uses the information in the Vertex flags, and not any topology.
|
It uses the information in the Vertex flags, and not any topology.
|
||||||
So it just require that you have correctly computed the flags;
|
So it just require that you have correctly computed the flags;
|
||||||
|
|
||||||
- vcg::tri::UpdateTopology<Mesh>::FaceFace(m.cm);
|
- vcg::tri::UpdateTopology<Mesh>::FaceFace(m.cm);
|
||||||
|
@ -105,8 +105,8 @@ So it just require that you have correctly computed the flags;
|
||||||
static void VertexBorderFlag( UpdateMeshType &m, Color4b BorderColor=Color4b::Blue, Color4b InternalColor=Color4b::White, Color4b MixColor=Color4b::Cyan)
|
static void VertexBorderFlag( UpdateMeshType &m, Color4b BorderColor=Color4b::Blue, Color4b InternalColor=Color4b::White, Color4b MixColor=Color4b::Cyan)
|
||||||
{
|
{
|
||||||
Color4b BaseColor = Color4b::Green;
|
Color4b BaseColor = Color4b::Green;
|
||||||
|
|
||||||
VertexConstant(m,BaseColor);
|
VertexConstant(m,BaseColor);
|
||||||
|
|
||||||
typename UpdateMeshType::FaceIterator fi;
|
typename UpdateMeshType::FaceIterator fi;
|
||||||
for(fi=m.face.begin();fi!=m.face.end();++fi) if(!(*fi).IsD())
|
for(fi=m.face.begin();fi!=m.face.end();++fi) if(!(*fi).IsD())
|
||||||
|
@ -123,17 +123,17 @@ static void VertexBorderFlag( UpdateMeshType &m, Color4b BorderColor=Color4b::Bl
|
||||||
if( (*fi).V1(j)->C() == BaseColor) (*fi).V1(j)->C() = InternalColor;
|
if( (*fi).V1(j)->C() == BaseColor) (*fi).V1(j)->C() = InternalColor;
|
||||||
if( (*fi).V1(j)->C() == BorderColor) (*fi).V1(j)->C() = MixColor;
|
if( (*fi).V1(j)->C() == BorderColor) (*fi).V1(j)->C() = MixColor;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// This function colores the face of a mesh randomly.
|
/// This function colores the face of a mesh randomly.
|
||||||
/// The feature bit is used to color polygonal faces uniformly
|
/// The feature bit is used to color polygonal faces uniformly
|
||||||
|
|
||||||
static void MultiFaceRandom( UpdateMeshType &m)
|
static void MultiFaceRandom( UpdateMeshType &m)
|
||||||
{
|
{
|
||||||
FaceIterator fi;
|
FaceIterator fi;
|
||||||
Color4b BaseColor = Color4b::Black;
|
Color4b BaseColor = Color4b::Black;
|
||||||
FaceConstant(m,BaseColor);
|
FaceConstant(m,BaseColor);
|
||||||
int id=0;
|
int id=0;
|
||||||
for(fi=m.face.begin();fi!=m.face.end();++fi)
|
for(fi=m.face.begin();fi!=m.face.end();++fi)
|
||||||
if(!(*fi).IsD())
|
if(!(*fi).IsD())
|
||||||
|
@ -141,15 +141,15 @@ static void MultiFaceRandom( UpdateMeshType &m)
|
||||||
id++;
|
id++;
|
||||||
if((*fi).C() == BaseColor) (*fi).C() = Color4b::Scatter(50, id%50,.4f,.7f);
|
if((*fi).C() == BaseColor) (*fi).C() = Color4b::Scatter(50, id%50,.4f,.7f);
|
||||||
for(int j=0;j<3;++j)
|
for(int j=0;j<3;++j)
|
||||||
if((*fi).IsF(j))
|
if((*fi).IsF(j))
|
||||||
{
|
{
|
||||||
assert(!IsBorder((*fi),j));
|
assert(!IsBorder((*fi),j));
|
||||||
(*fi).FFp(j)->C()= (*fi).C();
|
(*fi).FFp(j)->C()= (*fi).C();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void FaceBF( UpdateMeshType &m, Color4b vn=Color4b::White, Color4b vb=Color4b::Blue,
|
static void FaceBF( UpdateMeshType &m, Color4b vn=Color4b::White, Color4b vb=Color4b::Blue,
|
||||||
Color4b vc=Color4b::Red, Color4b vs=Color4b::LightBlue)
|
Color4b vc=Color4b::Red, Color4b vs=Color4b::LightBlue)
|
||||||
{
|
{
|
||||||
typename UpdateMeshType::FaceIterator fi;
|
typename UpdateMeshType::FaceIterator fi;
|
||||||
|
@ -157,7 +157,7 @@ static void FaceBF( UpdateMeshType &m, Color4b vn=Color4b::White, Color4b vb=Col
|
||||||
if(!(*fi).IsD())
|
if(!(*fi).IsD())
|
||||||
(*fi).C() = vn;
|
(*fi).C() = vn;
|
||||||
|
|
||||||
for(fi=m.face.begin();fi!=m.face.end();++fi)
|
for(fi=m.face.begin();fi!=m.face.end();++fi)
|
||||||
if(!(*fi).IsD())
|
if(!(*fi).IsD())
|
||||||
{
|
{
|
||||||
if((*fi).IsS())
|
if((*fi).IsS())
|
||||||
|
@ -169,7 +169,7 @@ static void FaceBF( UpdateMeshType &m, Color4b vn=Color4b::White, Color4b vb=Col
|
||||||
if((*fi).IsB(j)){
|
if((*fi).IsB(j)){
|
||||||
(*fi).C() = vb;
|
(*fi).C() = vb;
|
||||||
(*fi).C() = vb;
|
(*fi).C() = vb;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -186,7 +186,7 @@ static int FaceSelected(UpdateMeshType &m, Color4b vs=Color4b::LightBlue)
|
||||||
int cnt=0;
|
int cnt=0;
|
||||||
typename UpdateMeshType::FaceIterator fi;
|
typename UpdateMeshType::FaceIterator fi;
|
||||||
for(fi=m.face.begin();fi!=m.face.end();++fi)
|
for(fi=m.face.begin();fi!=m.face.end();++fi)
|
||||||
if(!(*fi).IsD())
|
if(!(*fi).IsD())
|
||||||
if((*fi).IsS()) { (*fi).C() = vs; ++cnt; }
|
if((*fi).IsS()) { (*fi).C() = vs; ++cnt; }
|
||||||
else (*fi).C() = Color4b::White;
|
else (*fi).C() = Color4b::White;
|
||||||
return cnt;
|
return cnt;
|
||||||
|
@ -211,7 +211,7 @@ static void FaceColorStrip(UpdateMeshType &m, std::vector<FacePointer> &TStripF)
|
||||||
else cnt=(cnt+1)%16;
|
else cnt=(cnt+1)%16;
|
||||||
// if(*fi) (**fi).C()=cc[cnt];
|
// if(*fi) (**fi).C()=cc[cnt];
|
||||||
// else cnt=(cnt+1)%7;
|
// else cnt=(cnt+1)%7;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -220,42 +220,42 @@ static int VertexSelected(UpdateMeshType &m, Color4b vs=Color4b::LightBlue)
|
||||||
int cnt=0;
|
int cnt=0;
|
||||||
typename UpdateMeshType::VertexIterator vi;
|
typename UpdateMeshType::VertexIterator vi;
|
||||||
for(vi=m.vert.begin();vi!=m.vert.end();++vi)
|
for(vi=m.vert.begin();vi!=m.vert.end();++vi)
|
||||||
if(!(*vi).IsD())
|
if(!(*vi).IsD())
|
||||||
if((*vi).IsS()) {(*vi).C() = vs; ++cnt; }
|
if((*vi).IsS()) {(*vi).C() = vs; ++cnt; }
|
||||||
else (*vi).C() = Color4b::White;
|
else (*vi).C() = Color4b::White;
|
||||||
|
|
||||||
return cnt;
|
return cnt;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void VertexConstant(UpdateMeshType &m, Color4b c=Color4b::White)
|
static void VertexConstant(UpdateMeshType &m, Color4b c=Color4b::White)
|
||||||
{
|
{
|
||||||
typename UpdateMeshType::VertexIterator vi;
|
typename UpdateMeshType::VertexIterator vi;
|
||||||
for(vi=m.vert.begin();vi!=m.vert.end();++vi) if(!(*vi).IsD())
|
for(vi=m.vert.begin();vi!=m.vert.end();++vi) if(!(*vi).IsD())
|
||||||
(*vi).C()=c;
|
(*vi).C()=c;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void FaceConstant(UpdateMeshType &m, Color4b c=Color4b::White)
|
static void FaceConstant(UpdateMeshType &m, Color4b c=Color4b::White)
|
||||||
{
|
{
|
||||||
typename UpdateMeshType::FaceIterator fi;
|
typename UpdateMeshType::FaceIterator fi;
|
||||||
for(fi=m.face.begin();fi!=m.face.end();++fi)
|
for(fi=m.face.begin();fi!=m.face.end();++fi)
|
||||||
(*fi).C()=c;
|
(*fi).C()=c;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void VertexBorderManifoldFlag(UpdateMeshType &m, Color4b vn=Color4b::White, Color4b vb=Color4b::Blue, Color4b vc=Color4b::Red)
|
static void VertexBorderManifoldFlag(UpdateMeshType &m, Color4b vn=Color4b::White, Color4b vb=Color4b::Blue, Color4b vc=Color4b::Red)
|
||||||
{
|
{
|
||||||
typename UpdateMeshType::VertexIterator vi;
|
typename UpdateMeshType::VertexIterator vi;
|
||||||
for(vi=m.vert.begin();vi!=m.vert.end();++vi) if(!(*vi).IsD())
|
for(vi=m.vert.begin();vi!=m.vert.end();++vi) if(!(*vi).IsD())
|
||||||
(*vi).C()=vn;
|
(*vi).C()=vn;
|
||||||
|
|
||||||
typename UpdateMeshType::FaceIterator fi;
|
typename UpdateMeshType::FaceIterator fi;
|
||||||
for(fi=m.face.begin();fi!=m.face.end();++fi)
|
for(fi=m.face.begin();fi!=m.face.end();++fi)
|
||||||
if(!(*fi).IsD())
|
if(!(*fi).IsD())
|
||||||
for(int j=0;j<3;++j)
|
for(int j=0;j<3;++j)
|
||||||
if((*fi).IsManifold(j)){
|
if((*fi).IsManifold(j)){
|
||||||
if((*fi).IsB(j)){
|
if((*fi).IsB(j)){
|
||||||
(*fi).V(j)->C()=vb;
|
(*fi).V(j)->C()=vb;
|
||||||
(*fi).V1(j)->C()=vb;
|
(*fi).V1(j)->C()=vb;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -273,7 +273,7 @@ static void FaceQuality(UpdateMeshType &m)
|
||||||
float minq=m.face[0].Q(),
|
float minq=m.face[0].Q(),
|
||||||
maxq=m.face[0].Q();
|
maxq=m.face[0].Q();
|
||||||
for(fi=m.face.begin();fi!=m.face.end();++fi) if(!(*fi).IsD())
|
for(fi=m.face.begin();fi!=m.face.end();++fi) if(!(*fi).IsD())
|
||||||
if(!(*fi).IsD())
|
if(!(*fi).IsD())
|
||||||
{
|
{
|
||||||
minq=min(minq,(*fi).Q());
|
minq=min(minq,(*fi).Q());
|
||||||
maxq=max(maxq,(*fi).Q());
|
maxq=max(maxq,(*fi).Q());
|
||||||
|
@ -286,7 +286,7 @@ static void FaceQuality(UpdateMeshType &m, float minq, float maxq)
|
||||||
{
|
{
|
||||||
typename UpdateMeshType::FaceIterator fi;
|
typename UpdateMeshType::FaceIterator fi;
|
||||||
|
|
||||||
for(fi=m.face.begin();fi!=m.face.end();++fi) if(!(*fi).IsD())
|
for(fi=m.face.begin();fi!=m.face.end();++fi) if(!(*fi).IsD())
|
||||||
(*fi).C().ColorRamp(minq,maxq,(*fi).Q());
|
(*fi).C().ColorRamp(minq,maxq,(*fi).Q());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -294,8 +294,8 @@ static void VertexQuality(UpdateMeshType &m, float minq, float maxq)
|
||||||
{
|
{
|
||||||
typename UpdateMeshType::VertexIterator vi;
|
typename UpdateMeshType::VertexIterator vi;
|
||||||
|
|
||||||
for(vi=m.vert.begin();vi!=m.vert.end();++vi)
|
for(vi=m.vert.begin();vi!=m.vert.end();++vi)
|
||||||
if(!(*vi).IsD())
|
if(!(*vi).IsD())
|
||||||
(*vi).C().ColorRamp(minq,maxq,(*vi).Q());
|
(*vi).C().ColorRamp(minq,maxq,(*vi).Q());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -305,38 +305,206 @@ static void VertexQuality(UpdateMeshType &m)
|
||||||
typename UpdateMeshType::VertexIterator vi;
|
typename UpdateMeshType::VertexIterator vi;
|
||||||
float minq=std::numeric_limits<float>::max(),
|
float minq=std::numeric_limits<float>::max(),
|
||||||
maxq=-std::numeric_limits<float>::max();
|
maxq=-std::numeric_limits<float>::max();
|
||||||
for(vi=m.vert.begin();vi!=m.vert.end();++vi)
|
for(vi=m.vert.begin();vi!=m.vert.end();++vi)
|
||||||
if(!(*vi).IsD())
|
if(!(*vi).IsD())
|
||||||
{
|
{
|
||||||
minq=vcg::math::Min<float>(minq,(*vi).Q());
|
minq=vcg::math::Min<float>(minq,(*vi).Q());
|
||||||
maxq=vcg::math::Max<float>(maxq,(*vi).Q());
|
maxq=vcg::math::Max<float>(maxq,(*vi).Q());
|
||||||
}
|
}
|
||||||
VertexQuality(m,minq,maxq);
|
VertexQuality(m,minq,maxq);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Fill the mesh with the selected color.
|
||||||
|
static int Filling(UpdateMeshType &m, vcg::Color4b c, const bool ProcessSelected=false)
|
||||||
|
{
|
||||||
|
int counter=0;
|
||||||
|
VertexIterator vi;
|
||||||
|
for(vi=m.vert.begin();vi!=m.vert.end();++vi) //scan all the vertex...
|
||||||
|
{
|
||||||
|
if(!(*vi).IsD()) //if it has not been deleted...
|
||||||
|
{
|
||||||
|
if(!ProcessSelected || (*vi).IsS()) //if this vertex has been selected, do transormation
|
||||||
|
{
|
||||||
|
(*vi).C() = c;
|
||||||
|
++counter;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return counter;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Reduces the mesh to two colors according to a treshold.
|
||||||
|
static int Tresholding(UpdateMeshType &m, float treshold, Color4b c1 = Color4<unsigned char>::Black, Color4b c2 = Color4<unsigned char>::White, const bool ProcessSelected=false)
|
||||||
|
{
|
||||||
|
int counter=0;
|
||||||
|
VertexIterator vi;
|
||||||
|
for(vi=m.vert.begin();vi!=m.vert.end();++vi) //scan all the vertex...
|
||||||
|
{
|
||||||
|
if(!(*vi).IsD()) //if it has not been deleted...
|
||||||
|
{
|
||||||
|
if(!ProcessSelected || (*vi).IsS()) //if this vertex has been selected, do transormation
|
||||||
|
{
|
||||||
|
float value = ComputeLightness((*vi).C());
|
||||||
|
|
||||||
|
if(value<=treshold) (*vi).C() = c1;
|
||||||
|
else (*vi).C() = c2;
|
||||||
|
++counter;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return counter;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Computes the luminance value for a specified color.
|
||||||
|
static float ComputeLightness(Color4b c)
|
||||||
|
{
|
||||||
|
float min_rgb = math::Min((float)c[0],(float)c[1]);
|
||||||
|
min_rgb = math::Min(min_rgb,(float)c[2]);
|
||||||
|
float max_rgb = math::Max((float)c[0],(float)c[1]);
|
||||||
|
max_rgb = math::Max(max_rgb,(float)c[2]);
|
||||||
|
return (max_rgb + min_rgb)/2;
|
||||||
|
}
|
||||||
|
|
||||||
//Apply the brightness filter, with the given amount, to the mesh.
|
//Apply the brightness filter, with the given amount, to the mesh.
|
||||||
static int Brighting(UpdateMeshType &m, int amount, const bool ProcessSelected=false)
|
static int Brighting(UpdateMeshType &m, int amount, const bool ProcessSelected=false)
|
||||||
{
|
{
|
||||||
int counter=0;
|
int counter=0;
|
||||||
VertexIterator vi;
|
VertexIterator vi;
|
||||||
for(vi=m.vert.begin();vi!=m.vert.end();++vi) //scan all the vertex...
|
for(vi=m.vert.begin();vi!=m.vert.end();++vi) //scan all the vertex...
|
||||||
{
|
{
|
||||||
if(!(*vi).IsD()) //if it has not been deleted...
|
if(!(*vi).IsD()) //if it has not been deleted...
|
||||||
{
|
{
|
||||||
if(!ProcessSelected || (*vi).IsS()) //if this vertex has been selected, do transormation
|
if(!ProcessSelected || (*vi).IsS()) //if this vertex has been selected, do transormation
|
||||||
{
|
{
|
||||||
(*vi).C() = Color4b(
|
(*vi).C() = Color4b(
|
||||||
math::Clamp(int((*vi).C()[0])+amount,0,255),
|
math::Clamp(int((*vi).C()[0])+amount,0,255),
|
||||||
math::Clamp(int((*vi).C()[1])+amount,0,255),
|
math::Clamp(int((*vi).C()[1])+amount,0,255),
|
||||||
math::Clamp(int((*vi).C()[2])+amount,0,255),
|
math::Clamp(int((*vi).C()[2])+amount,0,255),
|
||||||
255);
|
255);
|
||||||
++counter;
|
++counter;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return counter;
|
return counter;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int Contrast(UpdateMeshType &m, float factor, const bool ProcessSelected=false)
|
||||||
|
{
|
||||||
|
int counter=0;
|
||||||
|
VertexIterator vi;
|
||||||
|
for(vi=m.vert.begin();vi!=m.vert.end();++vi) //scan all the vertex...
|
||||||
|
{
|
||||||
|
if(!(*vi).IsD()) //if it has not been deleted...
|
||||||
|
{
|
||||||
|
if(!ProcessSelected || (*vi).IsS()) //if this vertex has been selected, do transormation
|
||||||
|
{
|
||||||
|
(*vi).C() = ColorMul((*vi).C(),factor);
|
||||||
|
++counter;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return counter;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Subtracts a middle value, multiplies the rgb components of the color for a factor,
|
||||||
|
//and adds the middle value back.This is used for contrast operation.
|
||||||
|
static Color4b ColorMul(Color4b c, float factor)
|
||||||
|
{
|
||||||
|
return Color4b( ValueMul(c[0], factor), ValueMul(c[1], factor), ValueMul(c[2], factor), 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ValueMul(int value, float factor)
|
||||||
|
{
|
||||||
|
return math::Clamp<int>((int)((value - 128)*factor + 128), 0, 255);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ContrastBrightness(UpdateMeshType &m, float factor, int amount, const bool ProcessSelected=false)
|
||||||
|
{
|
||||||
|
int counter=0;
|
||||||
|
VertexIterator vi;
|
||||||
|
for(vi=m.vert.begin();vi!=m.vert.end();++vi) //scan all the vertex...
|
||||||
|
{
|
||||||
|
if(!(*vi).IsD()) //if it has not been deleted...
|
||||||
|
{
|
||||||
|
if(!ProcessSelected || (*vi).IsS()) //if this vertex has been selected, do transormation
|
||||||
|
{
|
||||||
|
(*vi).C() = ColorMulAdd((*vi).C(),factor,amount);
|
||||||
|
++counter;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return counter;
|
||||||
|
}
|
||||||
|
|
||||||
|
//This is a composition of ColorMul() and ColorAdd(), used for Contrast&Brightness operations.
|
||||||
|
//The result is clamped just one time after all computations; this get a more accurate result.
|
||||||
|
static Color4b ColorMulAdd(Color4b c, float factor, int amount)
|
||||||
|
{
|
||||||
|
return Color4b( ValueMulAdd(c[0], factor, amount), ValueMulAdd(c[1], factor, amount), ValueMulAdd(c[2], factor, amount), 1 );
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ValueMulAdd(int value, float factor, int amount)
|
||||||
|
{
|
||||||
|
return math::Clamp<int>((int)((value - 128)*factor + 128 + amount), 0, 255);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Invert the rgb components of the color.
|
||||||
|
static int Invert(UpdateMeshType &m, const bool ProcessSelected=false)
|
||||||
|
{
|
||||||
|
int counter=0;
|
||||||
|
VertexIterator vi;
|
||||||
|
for(vi=m.vert.begin();vi!=m.vert.end();++vi) //scan all the vertex...
|
||||||
|
{
|
||||||
|
if(!(*vi).IsD()) //if it has not been deleted...
|
||||||
|
{
|
||||||
|
if(!ProcessSelected || (*vi).IsS()) //if this vertex has been selected, do transormation
|
||||||
|
{
|
||||||
|
(*vi).C() = ColorInvert((*vi).C());
|
||||||
|
++counter;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return counter;
|
||||||
|
}
|
||||||
|
|
||||||
|
//invert the given color
|
||||||
|
static Color4b ColorInvert(Color4b c)
|
||||||
|
{
|
||||||
|
return Color4b( ValueInvert(c[0]), ValueInvert(c[1]), ValueInvert(c[2]), 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ValueInvert(int value)
|
||||||
|
{
|
||||||
|
return 255-value;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int Colourisation(UpdateMeshType &m, Color4b c, float intensity, const bool ProcessSelected=false)
|
||||||
|
{
|
||||||
|
int counter=0;
|
||||||
|
VertexIterator vi;
|
||||||
|
for(vi=m.vert.begin();vi!=m.vert.end();++vi) //scan all the vertex...
|
||||||
|
{
|
||||||
|
if(!(*vi).IsD()) //if it has not been deleted...
|
||||||
|
{
|
||||||
|
if(!ProcessSelected || (*vi).IsS()) //if this vertex has been selected, do transormation
|
||||||
|
{
|
||||||
|
(*vi).C() = ColorApplyDiff((*vi).C(), c, intensity);
|
||||||
|
++counter;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return counter;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Color4b ColorApplyDiff(Color4b old_color, Color4b new_color, float intensity)
|
||||||
|
{
|
||||||
|
return Color4b( ValueApplyDiff(old_color[0],new_color[0],intensity), ValueApplyDiff(old_color[1],new_color[1],intensity), ValueApplyDiff(old_color[2], new_color[2],intensity), 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ValueApplyDiff(int old_value, int new_value, float intensity)
|
||||||
|
{
|
||||||
|
return math::Clamp<int>((int)(old_value + intensity * (new_value - old_value)), 0, 255);
|
||||||
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue