This commit is contained in:
T.Alderighi 2018-07-12 14:02:58 +02:00
parent 22311c5340
commit d5831911d2
3 changed files with 774 additions and 774 deletions

View File

@ -108,7 +108,7 @@ public:
return minmax;
}
static void ComputerPerTetraQualityMinMax(MeshType & m, ScalarType & minQ, ScalarType & maxQ)
static void ComputePerTetraQualityMinMax(MeshType & m, ScalarType & minQ, ScalarType & maxQ)
{
std::pair<ScalarType, ScalarType> minmax = ComputerPerTetraQualityMinMax(m);
@ -116,10 +116,10 @@ public:
maxQ = minmax.second;
}
static std::pair<ScalarType, ScalarType> ComputerPerTetraQualityMinMax(MeshType & m)
static std::pair<ScalarType, ScalarType> ComputePerTetraQualityMinMax(MeshType & m)
{
tri::RequirePerTetraQuality(m);
std::pair<ScalarType, ScalarType> minmax = std::make_pair(std::numeric_limits<ScalarType>::max(), -std::numeric_limits<ScalarType>::max());
std::pair<ScalarType, ScalarType> minmax = std::make_pair(std::numeric_limits<ScalarType>::max(), std::numeric_limits<ScalarType>::min());
ForEachTetra(m, [&minmax] (TetraType & t) {
if (t.Q() < minmax.first) minmax.first = t.Q();
@ -329,7 +329,7 @@ public:
static void ComputePerTetraQualityHistogram(MeshType & m, Histogram<ScalarType> & h, bool selectionOnly = false, int HistSize = 10000)
{
tri::RequirePerTetraQuality(m);
std::pair<ScalarType, ScalarType> minmax = tri::Stat<MeshType>::ComputePerFaceQualityMinMax(m);
std::pair<ScalarType, ScalarType> minmax = tri::Stat<MeshType>::ComputePerTetraQualityMinMax(m);
h.Clear();
h.SetRange(minmax.first, minmax.second, HistSize);

View File

@ -268,7 +268,7 @@ public:
if(minq == maxq)
{
std::pair<ScalarType, ScalarType> minmax = Stat<MeshType>::ComputerPerTetraQualityMinMax(m);
std::pair<ScalarType, ScalarType> minmax = Stat<MeshType>::ComputePerTetraQualityMinMax(m);
minq=minmax.first;
maxq=minmax.second;
}
@ -441,14 +441,14 @@ Note: The faux bit is used to color polygonal faces uniformly
}
}
/*! \brief Perlin Noise.
/*! \brief Perlin Noise.
Simple Perlin noise. To make things weirder each color band can have its own offset and frequency.
Period is expressed in absolute terms.
So as period it is meaningful could be to use something in the range of 1/10 of the bbox diag.
*/
static void PerVertexPerlinNoise(MeshType& m, CoordType period, CoordType offset = CoordType(0, 0, 0), bool onSelected = false)
{
static void PerVertexPerlinNoise(MeshType& m, CoordType period, CoordType offset = CoordType(0, 0, 0), bool onSelected = false)
{
RequirePerVertexColor(m);
CoordType p[3];
@ -467,15 +467,15 @@ static void PerVertexPerlinNoise(MeshType& m, CoordType period, CoordType offset
255 );
}
}
}
/*! \brief Perlin Color mixing.
/*! \brief Perlin Color mixing.
Simple Perlin color mixing. Color 1 and 2 are mixed according the perlin noise function, with period and offset.
*/
static void PerVertexPerlinColoring(MeshType& m, ScalarType period, CoordType offset = CoordType(0, 0, 0), Color4b color1 = Color4b::Black, Color4b color2 = Color4b::White, bool onSelected = false)
{
static void PerVertexPerlinColoring(MeshType& m, ScalarType period, CoordType offset = CoordType(0, 0, 0), Color4b color1 = Color4b::Black, Color4b color2 = Color4b::White, bool onSelected = false)
{
RequirePerVertexColor(m);
CoordType p;
@ -495,13 +495,13 @@ static void PerVertexPerlinColoring(MeshType& m, ScalarType period, CoordType of
(*vi).C() = Color4b(rr, gg, bb, aa);
}
}
}
/*! \brief Simple Noise adding function.
/*! \brief Simple Noise adding function.
It simply add signed noise to the color of the mesh. The noise has uniform distribution and the amplitude is +/-2^(noisebits-1).
*/
static void PerVertexAddNoise(MeshType& m, int noiseBits, bool onSelected=false)
{
static void PerVertexAddNoise(MeshType& m, int noiseBits, bool onSelected=false)
{
RequirePerVertexColor(m);
if(noiseBits>8) noiseBits = 8;
@ -517,13 +517,13 @@ static void PerVertexAddNoise(MeshType& m, int noiseBits, bool onSelected=false)
(*vi).C()[2] = math::Clamp<int>((*vi).C()[2] + randomGen.generate(int(2*pow(2.0f,noiseBits))) - int(pow(2.0f,noiseBits)),0,255);
}
}
}
/*! \brief Reduces vertex color the mesh to two colors according to a threshold.
/*! \brief Reduces vertex color the mesh to two colors according to a threshold.
*/
static int PerVertexThresholding(MeshType &m, float threshold, const Color4b c1 = Color4<unsigned char>::Black, const Color4b c2 = Color4<unsigned char>::White, const bool ProcessSelected=false)
{
static int PerVertexThresholding(MeshType &m, float threshold, const Color4b c1 = Color4<unsigned char>::Black, const Color4b c2 = Color4<unsigned char>::White, const bool ProcessSelected=false)
{
RequirePerVertexColor(m);
int counter=0;
@ -543,20 +543,20 @@ static int PerVertexThresholding(MeshType &m, float threshold, const Color4b c1
}
}
return counter;
}
}
// Computes the lightness value for a specified color. lightness = 0.5*(Max(R,G,B)+Min(R,G,B))
static float ComputeLightness(Color4b c)
{
// Computes the lightness value for a specified color. lightness = 0.5*(Max(R,G,B)+Min(R,G,B))
static float ComputeLightness(Color4b c)
{
float min_rgb = (float)math::Min(c[0],c[1],c[2]);
float max_rgb = (float)math::Max(c[0],c[1],c[2]);
return (max_rgb + min_rgb)/2;
}
}
/*! \brief Apply the brightness filter, with the given amount, to the mesh.
/*! \brief Apply the brightness filter, with the given amount, to the mesh.
*/
static int PerVertexBrightness(MeshType &m, float amount, const bool ProcessSelected=false)
{
static int PerVertexBrightness(MeshType &m, float amount, const bool ProcessSelected=false)
{
RequirePerVertexColor(m);
int counter=0;
@ -577,12 +577,12 @@ static int PerVertexBrightness(MeshType &m, float amount, const bool ProcessSele
}
}
return counter;
}
}
/*! \brief Apply Contrast filter to the mesh with the given contrast factor.
/*! \brief Apply Contrast filter to the mesh with the given contrast factor.
*/
static int PerVertexContrast(MeshType &m, float factor, const bool ProcessSelected=false)
{
static int PerVertexContrast(MeshType &m, float factor, const bool ProcessSelected=false)
{
RequirePerVertexColor(m);
int counter=0;
@ -599,21 +599,21 @@ static int PerVertexContrast(MeshType &m, float factor, const bool ProcessSelect
}
}
return counter;
}
}
//Performs contrast operations on color, i.e expands or compress the histogram around
//the midpoint value. NewValue = (OldValue - 128) ◊ factor + 128
static Color4b ColorMul(Color4b c, float factor)
{
//Performs contrast operations on color, i.e expands or compress the histogram around
//the midpoint value. NewValue = (OldValue - 128) ◊ factor + 128
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)
{
static int ValueMul(int value, float factor)
{
return math::Clamp<int>((int)((value - 128)*factor + 128), 0, 255);
}
}
/*! \brief Apply Brightness and Contrast filter to the mesh, with the given contrast factor and brightness amount.
/*! \brief Apply Brightness and Contrast filter to the mesh, with the given contrast factor and brightness amount.
Performs contrast and brightness operations on color, i.e NewValue = (OldValue - 128) * contrast + 128 + amount
The result is clamped just one time after all computations; this get a more accurate result.
@ -621,8 +621,8 @@ The result is clamped just one time after all computations; this get a more accu
The formula used here is the one of GIMP.
*/
static int PerVertexBrightnessContrast(MeshType &m, float brightness, float contrast, const bool ProcessSelected=false)
{
static int PerVertexBrightnessContrast(MeshType &m, float brightness, float contrast, const bool ProcessSelected=false)
{
RequirePerVertexColor(m);
int counter=0;
@ -639,30 +639,30 @@ static int PerVertexBrightnessContrast(MeshType &m, float brightness, float cont
}
}
return counter;
}
}
static Color4b ColorBrightnessContrast(Color4b c, float brightness, float contrast)
{
static Color4b ColorBrightnessContrast(Color4b c, float brightness, float contrast)
{
return Color4b( ValueBrightnessContrast(c[0], brightness, contrast),
ValueBrightnessContrast(c[1], brightness, contrast),
ValueBrightnessContrast(c[2], brightness, contrast), 1 );
}
}
static int ValueBrightnessContrast(unsigned char ivalue, float brightness, float contrast)
{
static int ValueBrightnessContrast(unsigned char ivalue, float brightness, float contrast)
{
float value = float(ivalue)/255.0f;
if (brightness < 0.0) value = value * ( 1.0 + brightness);
else value = value + ((1.0 - value) * brightness);
value = (value - 0.5) * (tan ((contrast + 1) * M_PI/4) ) + 0.5;
return math::Clamp<int>(255.0*value, 0, 255);
}
}
/*! \brief Invert the colors of the mesh.
/*! \brief Invert the colors of the mesh.
\return the number of changed vertexes (the selected ones)
*/
static int PerVertexInvert(MeshType &m, const bool ProcessSelected=false)
{
static int PerVertexInvert(MeshType &m, const bool ProcessSelected=false)
{
RequirePerVertexColor(m);
int counter=0;
@ -679,13 +679,13 @@ static int PerVertexInvert(MeshType &m, const bool ProcessSelected=false)
}
}
return counter;
}
}
/*! \brief Apply the gamma correction filter, with the given gamma exponet, to the mesh.
/*! \brief Apply the gamma correction filter, with the given gamma exponet, to the mesh.
\return the number of changed vertexes (the selected ones)
*/
static int PerVertexGamma(MeshType &m, float gamma, const bool ProcessSelected=false)
{
static int PerVertexGamma(MeshType &m, float gamma, const bool ProcessSelected=false)
{
RequirePerVertexColor(m);
int counter=0;
@ -703,27 +703,27 @@ static int PerVertexGamma(MeshType &m, float gamma, const bool ProcessSelected=f
}
}
return counter;
}
}
//computes the standard gamma transformation on a given color, according to NewVal = OldVal^(1/gamma)
static Color4b ColorPow(Color4b c, float exponent)
{
//computes the standard gamma transformation on a given color, according to NewVal = OldVal^(1/gamma)
static Color4b ColorPow(Color4b c, float exponent)
{
return vcg::Color4b(
math::Clamp((int)( ValuePow(float(c[0])/255, exponent)*255), 0, 255),
math::Clamp((int)( ValuePow(float(c[1])/255, exponent)*255), 0, 255),
math::Clamp((int)( ValuePow(float(c[2])/255, exponent)*255), 0, 255),
255);
}
}
static float ValuePow(float value, float exponent)
{
static float ValuePow(float value, float exponent)
{
return powf(value, exponent);
}
}
//useful bit masks for RGB channels, used for Levels filter.
enum rgbChMask {ALL_CHANNELS = 7, RED_CHANNEL = 4, GREEN_CHANNEL = 2, BLUE_CHANNEL = 1, NO_CHANNELS = 0 };
//useful bit masks for RGB channels, used for Levels filter.
enum rgbChMask {ALL_CHANNELS = 7, RED_CHANNEL = 4, GREEN_CHANNEL = 2, BLUE_CHANNEL = 1, NO_CHANNELS = 0 };
/*! \brief Adjusts color levels of the mesh
/*! \brief Adjusts color levels of the mesh
\return the number of changed vertexes (the selected ones)
@ -731,8 +731,8 @@ Adjusts color levels of the mesh. Filter can be applied to all RGB channels or t
in_min, gamma and in_max are respectively the black point, the gray point and the white point.
out_min and out_max are the output level for black and white respectively.
*/
static int PerVertexLevels(MeshType &m, float gamma, float in_min, float in_max, float out_min, float out_max, unsigned char rgbMask, const bool ProcessSelected=false)
{
static int PerVertexLevels(MeshType &m, float gamma, float in_min, float in_max, float out_min, float out_max, unsigned char rgbMask, const bool ProcessSelected=false)
{
RequirePerVertexColor(m);
int counter=0;
@ -749,21 +749,21 @@ static int PerVertexLevels(MeshType &m, float gamma, float in_min, float in_max,
}
}
return counter;
}
}
//Performs levels transformation on each channel set to 1 in the rgbMask.
static Color4b ColorLevels(Color4b c, float gamma, float in_min, float in_max, float out_min, float out_max, unsigned char rgbMask)
{
//Performs levels transformation on each channel set to 1 in the rgbMask.
static Color4b ColorLevels(Color4b c, float gamma, float in_min, float in_max, float out_min, float out_max, unsigned char rgbMask)
{
unsigned char r = c[0], g = c[1], b = c[2];
if(rgbMask & RED_CHANNEL) r = ValueLevels(c[0], gamma, in_min, in_max, out_min, out_max);
if(rgbMask & GREEN_CHANNEL) g = ValueLevels(c[1], gamma, in_min, in_max, out_min, out_max);
if(rgbMask & BLUE_CHANNEL) b = ValueLevels(c[2], gamma, in_min, in_max, out_min, out_max);
return Color4b(r, g, b, 255);
}
}
//Transform on levels
static int ValueLevels(int value, float gamma, float in_min, float in_max, float out_min, float out_max)
{
//Transform on levels
static int ValueLevels(int value, float gamma, float in_min, float in_max, float out_min, float out_max)
{
float fvalue = value/255.0f;
// normalize
fvalue = math::Clamp<float>(fvalue - in_min, 0.0f, 1.0f) / math::Clamp<float>(in_max - in_min, 1.0f/255.0f, 1.0f);
@ -773,15 +773,15 @@ static int ValueLevels(int value, float gamma, float in_min, float in_max, float
fvalue = fvalue * (out_max - out_min) + out_min;
//back in interval [0,255] and clamp
return math::Clamp<int>((int)(fvalue * 255), 0, 255);
}
}
/*! \brief Colorize the mesh toward a given color.
/*! \brief Colorize the mesh toward a given color.
\return the number of changed vertexes (the selected ones)
Colors the mesh. Color is blended to the mesh with the given intensity (0..1 ranged).
*/
static int PerVertexColourisation(MeshType &m, Color4b c, float intensity, const bool ProcessSelected=false)
{
static int PerVertexColourisation(MeshType &m, Color4b c, float intensity, const bool ProcessSelected=false)
{
RequirePerVertexColor(m);
int counter=0;
@ -798,27 +798,27 @@ static int PerVertexColourisation(MeshType &m, Color4b c, float intensity, const
}
}
return counter;
}
}
// Perform colourisation operation.
// For each channel C:
// newC = origC + intensity * (newC - origC)
static Color4b ColorApplyDiff(Color4b old_color, Color4b new_color, float intensity)
{
// Perform colourisation operation.
// For each channel C:
// newC = origC + intensity * (newC - origC)
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), 255);
}
}
static int ValueApplyDiff(int old_value, int new_value, float intensity)
{
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);
}
}
//An useful ENUM to hold all desaturation methods.
enum DesaturationMethods {M_LIGHTNESS = 0, M_LUMINOSITY = 1, M_AVERAGE = 2};
//An useful ENUM to hold all desaturation methods.
enum DesaturationMethods {M_LIGHTNESS = 0, M_LUMINOSITY = 1, M_AVERAGE = 2};
/*! \brief Desaturates the mesh according the a chosen desaturation method
/*! \brief Desaturates the mesh according the a chosen desaturation method
\return the number of changed vertexes (the selected ones)
@ -827,8 +827,8 @@ There are three possibilities
- \c M_LUMINOSITY where luminosity = 0.21*R+0.71*G+0.7*B
- \c M_AVERAGE Plain Average
*/
static int PerVertexDesaturation(MeshType &m, int method, const bool ProcessSelected=false)
{
static int PerVertexDesaturation(MeshType &m, int method, const bool ProcessSelected=false)
{
RequirePerVertexColor(m);
int counter=0;
@ -845,11 +845,11 @@ static int PerVertexDesaturation(MeshType &m, int method, const bool ProcessSele
}
}
return counter;
}
}
//Desature the color. Ausiliary functions to calculate lightness/luminosity/average.
static Color4b ColorDesaturate(Color4b c, int method)
{
//Desature the color. Ausiliary functions to calculate lightness/luminosity/average.
static Color4b ColorDesaturate(Color4b c, int method)
{
switch(method){
case M_LIGHTNESS:{
int val = (int)ComputeLightness(c);
@ -866,27 +866,27 @@ static Color4b ColorDesaturate(Color4b c, int method)
default: assert(0);
}
return Color4b(255, 255, 255, 255);
}
}
//ausiliary function to compute average lightness. value = (R+G+B)/3
static float ComputeAvgLightness(Color4b c)
{
//ausiliary function to compute average lightness. value = (R+G+B)/3
static float ComputeAvgLightness(Color4b c)
{
return float(c[0]+c[1]+c[2])/3.0f;
}
}
//ausiliary function to compute luminosity. value = 0.21*R+0.71*G+0.7*B
static float ComputeLuminosity(Color4b c)
{
//ausiliary function to compute luminosity. value = 0.21*R+0.71*G+0.7*B
static float ComputeLuminosity(Color4b c)
{
return float(0.2126f*c[0]+0.7152f*c[1]+0.0722f*c[2]);
}
}
/*! \brief Histogram Color Equalization.
/*! \brief Histogram Color Equalization.
\return the number of changed vertexes (the selected ones)
Equalize the histogram of colors. It can equalize any combination of rgb channels or it can work on lightness.
*/
static int PerVertexEqualize(MeshType &m, unsigned int rgbMask, const bool ProcessSelected=false)
{
static int PerVertexEqualize(MeshType &m, unsigned int rgbMask, const bool ProcessSelected=false)
{
RequirePerVertexColor(m);
//declares , resets and set up 4 histograms, for Red, Green, Blue and Lightness
@ -933,11 +933,11 @@ static int PerVertexEqualize(MeshType &m, unsigned int rgbMask, const bool Proce
}
}
return counter;
}
}
//Applies equalization to the components of the color according to rgbmask
static Color4b ColorEqualize(Color4b c, int cdf_l[256], int cdf_r[256], int cdf_g[256], int cdf_b[256], unsigned int rgbMask)
{
//Applies equalization to the components of the color according to rgbmask
static Color4b ColorEqualize(Color4b c, int cdf_l[256], int cdf_r[256], int cdf_g[256], int cdf_b[256], unsigned int rgbMask)
{
unsigned char r = c[0], g = c[1], b = c[2];
if(rgbMask == NO_CHANNELS) //in this case, equalization is done on lightness
{
@ -948,21 +948,21 @@ static Color4b ColorEqualize(Color4b c, int cdf_l[256], int cdf_r[256], int cdf_
if(rgbMask & GREEN_CHANNEL) g = ValueEqualize(cdf_g[c[1]], cdf_g[0], cdf_g[255]); //Equalizes green
if(rgbMask & BLUE_CHANNEL) b = ValueEqualize(cdf_b[c[2]], cdf_b[0], cdf_b[255]); //Equalizes blue
return Color4b(r, g, b, 255); //return the equalized color
}
}
//Compute the equalized value
static int ValueEqualize(int cdfValue, int cdfMin, int cdfMax)
{
//Compute the equalized value
static int ValueEqualize(int cdfValue, int cdfMin, int cdfMax)
{
return int(float((cdfValue - cdfMin)/float(cdfMax - cdfMin)) * 255.0f);
}
}
/*! \brief Simple white balancing filter.
/*! \brief Simple white balancing filter.
\return the number of changed vertexes (the selected ones)
It applies a simple white balancing filter. It may works on a provided user color that is supposed to be white.
*/
static int PerVertexWhiteBalance(MeshType &m, Color4b userColor, const bool ProcessSelected=false)
{
static int PerVertexWhiteBalance(MeshType &m, Color4b userColor, const bool ProcessSelected=false)
{
RequirePerVertexColor(m);
Color4b unbalancedWhite= userColor;
@ -982,11 +982,11 @@ static int PerVertexWhiteBalance(MeshType &m, Color4b userColor, const bool Proc
}
}
return counter;
}
}
//Balnce the white of the color, applying a correction factor based on the unbalancedWhite color.
static Color4b ColorWhiteBalance(Color4b c, Color4b unbalancedWhite)
{
//Balnce the white of the color, applying a correction factor based on the unbalancedWhite color.
static Color4b ColorWhiteBalance(Color4b c, Color4b unbalancedWhite)
{
//sanity check to avoid division by zero...
if(unbalancedWhite[0]==0) unbalancedWhite[0]=1;
if(unbalancedWhite[1]==0) unbalancedWhite[1]=1;
@ -997,7 +997,7 @@ static Color4b ColorWhiteBalance(Color4b c, Color4b unbalancedWhite)
math::Clamp<int>((int)(c[1]*(255.0f/unbalancedWhite[1])), 0, 255),
math::Clamp<int>((int)(c[2]*(255.0f/unbalancedWhite[2])), 0, 255),
255);
}
}
};

View File

@ -102,11 +102,11 @@ public:
enum {
DELETED = 0x00000001, // Face is deleted from the mesh
NOTREAD = 0x00000002, // Face of the mesh is not readable
NOTWRITE = 0x00000004, // Face of the mesh is not writable
VISITED = 0x00000010, // Face has been visited. Usualy this is a per-algorithm used bit.
SELECTED = 0x00000020, // Face is selected. Algorithms should try to work only on selected face (if explicitly requested)
DELETED = 0x00000001, // Tet is deleted from the mesh
NOTREAD = 0x00000002, // Tet of the mesh is not readable
NOTWRITE = 0x00000004, // Tet of the mesh is not writable
VISITED = 0x00000010, // Tet has been visited. Usualy this is a per-algorithm used bit.
SELECTED = 0x00000020, // Tet is selected. Algorithms should try to work only on selected face (if explicitly requested)
// Border _flags, it is assumed that BORDERi = BORDER0<<i
BORDER0 = 0x00000040,
BORDER1 = 0x00000080,
@ -119,17 +119,17 @@ public:
};
/// checks if the Face is deleted
/// checks if the Tet is deleted
bool IsD() const {return (this->cFlags() & DELETED) != 0;}
/// checks if the Face is readable
/// checks if the Tet is readable
bool IsR() const {return (this->cFlags() & NOTREAD) == 0;}
/// checks if the Face is modifiable
/// checks if the Tet is modifiable
bool IsW() const {return (this->cFlags() & NOTWRITE)== 0;}
/// This funcion checks whether the Face is both readable and modifiable
/// This funcion checks whether the Tet is both readable and modifiable
bool IsRW() const {return (this->cFlags() & (NOTREAD | NOTWRITE)) == 0;}
/// checks if the Face is Modified
/// checks if the Tet is Modified
bool IsS() const {return (this->cFlags() & SELECTED) != 0;}
/// checks if the Face is Modified
/// checks if the Tet is Modified
bool IsV() const {return (this->cFlags() & VISITED) != 0;}
/** Set the flag value
@ -142,25 +142,25 @@ public:
*/
void ClearFlags() {this->Flags()=0;}
/// deletes the Face from the mesh
/// deletes the Tet from the mesh
void SetD() {this->Flags() |=DELETED;}
/// un-delete a Face
/// un-delete a Tet
void ClearD() {this->Flags() &=(~DELETED);}
/// marks the Face as readable
/// marks the Tet as readable
void SetR() {this->Flags() &=(~NOTREAD);}
/// marks the Face as not readable
/// marks the Tet as not readable
void ClearR() {this->Flags() |=NOTREAD;}
/// marks the Face as writable
/// marks the Tet as writable
void SetW() {this->Flags() &=(~NOTWRITE);}
/// marks the Face as notwritable
/// marks the Tet as notwritable
void ClearW() {this->Flags() |=NOTWRITE;}
/// select the Face
/// select the Tet
void SetS() {this->Flags() |=SELECTED;}
/// Un-select a Face
/// Un-select a Tet
void ClearS() {this->Flags() &= ~SELECTED;}
/// select the Face
/// select the Tet
void SetV() {this->Flags() |=VISITED;}
/// Un-select a Face
/// Un-select a Tet
void ClearV() {this->Flags() &= ~VISITED;}
/// This function checks if the face is border