aboutsummaryrefslogtreecommitdiffstats
path: root/Software/Visual_Studio
diff options
context:
space:
mode:
authorRoy Ben Shabat <Roy.mail.net@gmail.com>2020-08-03 12:36:24 +0300
committerRoy Ben Shabat <Roy.mail.net@gmail.com>2020-08-03 12:36:24 +0300
commitf2a27972ca652ef568e5eede22d86f9698a08cca (patch)
tree6c55d21cba6bfa8587d95fd27e17a5ec423b3b0d /Software/Visual_Studio
parentbd1221e36ee3e493dc25bd32559f846519fe60d0 (diff)
parent05fc7b1f37ecc809acf65422a799a4d761b78acb (diff)
downloadTango-f2a27972ca652ef568e5eede22d86f9698a08cca.tar.gz
Tango-f2a27972ca652ef568e5eede22d86f9698a08cca.zip
Merge branch 'master' of https://twinetfs.visualstudio.com/Tango/_git/Tango
Diffstat (limited to 'Software/Visual_Studio')
-rw-r--r--Software/Visual_Studio/ColorLib/Tango.ColorLib_v4/ColorConverter.cpp1201
-rw-r--r--Software/Visual_Studio/ColorLib/Tango.ColorLib_v4/ColorConverter.h64
-rw-r--r--Software/Visual_Studio/ColorLib/Tango.ColorLib_v4/Utils/ColorConvert.cpp7
-rw-r--r--Software/Visual_Studio/ColorLib/Tango.ColorLib_v4/Utils/ColorConvert.h1
-rw-r--r--Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.RML/ViewModels/MainViewVM.cs47
-rw-r--r--Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.RML/Views/RmlsView.xaml4
-rw-r--r--Software/Visual_Studio/Tango.ColorLib.GradientTest.CLI/Program.cs36
-rw-r--r--Software/Visual_Studio/Utilities/Tango.DispenserAnalyzer.UI/Analyzers/FlowAnalyser.cs64
-rw-r--r--Software/Visual_Studio/Utilities/Tango.DispenserAnalyzer.UI/Analyzers/PressureBuildUpAnalyser.cs2
-rw-r--r--Software/Visual_Studio/Utilities/Tango.DispenserAnalyzer.UI/App.xaml2
-rw-r--r--Software/Visual_Studio/Utilities/Tango.DispenserAnalyzer.UI/App.xaml.cs7
-rw-r--r--Software/Visual_Studio/Utilities/Tango.DispenserAnalyzer.UI/FileHelper.cs44
-rw-r--r--Software/Visual_Studio/Utilities/Tango.DispenserAnalyzer.UI/MainWindow.xaml.cs9
-rw-r--r--Software/Visual_Studio/Utilities/Tango.DispenserAnalyzer.UI/Models/FlowRangeToTimeResults.xlsxbin0 -> 15762 bytes
-rw-r--r--Software/Visual_Studio/Utilities/Tango.DispenserAnalyzer.UI/Models/SettingsModel.cs107
-rw-r--r--Software/Visual_Studio/Utilities/Tango.DispenserAnalyzer.UI/Settings.cs87
-rw-r--r--Software/Visual_Studio/Utilities/Tango.DispenserAnalyzer.UI/Tango.DispenserAnalyzer.UI.csproj11
-rw-r--r--Software/Visual_Studio/Utilities/Tango.DispenserAnalyzer.UI/View/SettingsWnd.xaml78
-rw-r--r--Software/Visual_Studio/Utilities/Tango.DispenserAnalyzer.UI/View/SettingsWnd.xaml.cs18
-rw-r--r--Software/Visual_Studio/Utilities/Tango.DispenserAnalyzer.UI/ViewModels/MainWindowVM.cs27
-rw-r--r--Software/Visual_Studio/Utilities/Tango.DispenserAnalyzer.UI/ViewModels/SettingsVM.cs51
21 files changed, 1515 insertions, 352 deletions
diff --git a/Software/Visual_Studio/ColorLib/Tango.ColorLib_v4/ColorConverter.cpp b/Software/Visual_Studio/ColorLib/Tango.ColorLib_v4/ColorConverter.cpp
index 8f4b55db9..930980726 100644
--- a/Software/Visual_Studio/ColorLib/Tango.ColorLib_v4/ColorConverter.cpp
+++ b/Software/Visual_Studio/ColorLib/Tango.ColorLib_v4/ColorConverter.cpp
@@ -1,4 +1,5 @@
#include "ColorConverter.h"
+#include "ColorConvert.h"
#include "CalibrationPoint.pb-c.h"
#include "CalibrationData.pb-c.h"
#include "ColorSpace.pb-c.h"
@@ -53,22 +54,23 @@
#define dETol 2.0
# define ROUNDINGDigits 2.0
#define maxPerRegion 100.0
-#define LowVolumeThreshold 2.0
+#define LowVolumeThreshold 0.0
#define LowVolHalf LowVolumeThreshold/2
+#define GradientEndThr 0.95
Tango::ColorLib::ColorConverter::ColorConverter() : m_A2BTransform(NULL), m_B2ATransform(NULL),
m_GBD(NULL), m_CalibCurves(NULL), m_Conv02(NULL), m_GamutRegionMaxLim(NULL),
m_maxNlPerCM(NULL), m_nA2BnSepIn(0), m_nA2BnSepOut(0), m_nB2AnSepIn(0), m_nB2AnSepOut(0),
-m_nInks(0), m_nVolumes(0), m_AdaptWP(false), m_nGamutRegions(0), m_LinCurves(NULL),
-m_nProcessRanges(0), m_ProcessRangesMaxP(NULL)
+m_nInks(0), m_nVolumes(0), m_nGamutRegions(0), m_LinCurves(NULL),
+m_nProcessRanges(0), m_ProcessRangesMaxP(NULL), m_GradStops(NULL), m_nGradStops(0), m_NormFactor(-1.0),
+m_InvNormFactor(-1.0)
//m_ProcessRangesMinInkUptake(NULL),m_ProcessRangesMinP(NULL),
//m_ProcessRangesMaxInkUptake(NULL)
{
m_whitepointLab.Set(-1, -1, -1);
m_whitepointXYZ_Strip.Set(-1, -1, -1);
m_whitepointXYZ_CT.Set(-1, -1, -1);
-
}
Tango::ColorLib::ColorConverter::~ColorConverter()
@@ -113,6 +115,11 @@ Tango::ColorLib::ColorConverter::~ColorConverter()
delete[] m_ProcessRangesMaxP;
m_ProcessRangesMaxP = NULL;
}
+ if (m_GradStops != NULL)
+ {
+ delete[] m_GradStops;
+ m_GradStops = NULL;
+ }
/* if (m_ProcessRangesMinP != NULL)
{
delete[] m_ProcessRangesMinP;
@@ -217,6 +224,7 @@ void Tango::ColorLib::ColorConverter::ProcessHiveNeighbors(ConversionInput *conv
//double * LabInFinal1 = DBG_NEW double[3];
double * LabInFinal2 = new double[3];
double * LabOnGamut = new double[3];
+ double *InkOutP = new double[m_nB2AnSepOut];
bool InGamut = true;
for (int i = 0; i < nHive; ++i)
{
@@ -224,30 +232,51 @@ void Tango::ColorLib::ColorConverter::ProcessHiveNeighbors(ConversionInput *conv
for (j = 0; j < 3; ++j)
Lab1P[j] = Lab1(i, j);
//Check if whitepoints match
- if (m_AdaptWP)
+/* if (m_AdaptWP)
{
//Convert to CT whitepoint
m_Conv02->ChangeWP(Lab1P, Lab1P, m_whitepointXYZ_CT, m_whitepointXYZ_Strip);
LimitLab(LabInFinal1);
}
- ColConv.ChangeWP(Lab1P, Lab1P, m_WP, m_whitepointXYZ_CT); //to Relative
-
+ */
+// ColConv.ChangeWP(Lab1P, Lab1P, m_WP, m_whitepointXYZ_CT); //to Relative
+ ColConv.ChangeWP(Lab1P, Lab1P, m_WP, m_whitepointXYZ_Strip); //to Relative
m_B2ATransform->evalLab2InkP(Lab1P, InkOut, GamutRegion[i]); //InkOut is in units of 16 bits
+ for (int i = 0; i < m_nB2AnSepOut; ++i)
+ {
+ InkOut[i] *= m_NormFactor;
+ if (InkOut[i] <= m_GamutRegionMaxLim[0])
+ {
+ m_LinCurves->m_InterpCurves[i].Eval(InkOut[i] * 655.35, InkOut[i]);
+ InkOut[i] /= 655.35;
+ }
+ }
InGamut = IsInGamut(Lab1P, sur, CS, LabOnGamut);
LimitLab(LabOnGamut);
+ VectorXd NLInkOut(m_nB2AnSepOut);
+ ConvertToNLInks(DoubleToVector(InkOut, m_nInks), NLInkOut);
+
+ //Limit inks based on m_maxNlpercm
+ //Inks are limited in their nonlinear form
+ //Output Volume is in %
+ LimitInks(NLInkOut, InkOutP);
+ NLInkPToVolume(DoubleToVector(InkOutP, m_nInks), Vol);
+ GamutRegion[i] = GetGamutRegion(Vol, m_ProcessRangesMaxP);
+ NLcmtoPercentage(Vol, Vol);
//m_A2BTransform->evalInkP2Lab(InkOut, Lab1P, GamutRegion[i]);
//Convert to CT WP
- m_Conv02->ChangeWP(LabOnGamut, LabInFinal1, m_whitepointXYZ_CT, m_WP); //convert back to Absolute
+// m_Conv02->ChangeWP(LabOnGamut, LabInFinal1, m_whitepointXYZ_CT, m_WP); //convert back to Absolute
+ m_Conv02->ChangeWP(LabOnGamut, LabInFinal1, m_whitepointXYZ_Strip, m_WP); //convert back to Absolute
LimitLab(LabInFinal1); //Absolute
//Check if whitepoints match
- if (m_AdaptWP)
+/* if (m_AdaptWP)
{
//Convert to Strip whitepoint
m_Conv02->ChangeWP(LabInFinal1, LabInFinal1, m_whitepointXYZ_Strip, m_whitepointXYZ_CT);
LimitLab(LabInFinal1);
- }
+ }*/
m_Conv02->SetReferenceWhite(D65);
for (int j = 0; j < 3; ++j)
LabHive(i, j) = LabInFinal1[j];
@@ -257,32 +286,7 @@ void Tango::ColorLib::ColorConverter::ProcessHiveNeighbors(ConversionInput *conv
//m_Conv02->LabtoRGB(Lab1P, tmpRGB);
for (int j = 0; j < 3; ++j)
RGBTmpVec(i, j) = std::min(std::max(tmpRGB[j], 0.0), 255.0);
-
- double NormFactor = m_ProcessRangesMaxP[m_nProcessRanges - 1] / 100.0;
- for (int j = 0; j < m_nB2AnSepOut; ++j)
- {
- InkOut[j] *= NormFactor;
- if (InkOut[j] <= m_ProcessRangesMaxP[0])
- {
- m_LinCurves->m_InterpCurves[j].Eval(InkOut[j] * 655.35, InkOut[j]);
- InkOut[j] /= 655.35;
- }
- }
-
- VectorXd InkOutV = DoubleToVector(InkOut, m_nInks);
-
- ConvertToNLInks(InkOutV, InkOutV);
- double maxNLInk = NegValue;
- for (int j = 0; j < m_nInks; ++j)
- maxNLInk = std::max(InkOutV(j), maxNLInk);
-
- for (int j = 0; j < (int)(conversionInput->n_processranges - 1); ++j)
- {
- if (maxNLInk > m_ProcessRangesMaxP[j])
- GamutRegion[i]++;
- }
-
- NLInkPToVolume(InkOutV, Vol);
+
//make sure the rounded sum does not exceed the limit in the gamut region
for (int j = 0; j < m_nInks; ++j)
VolumeHive(i, j) = Vol(j);
@@ -348,6 +352,11 @@ void Tango::ColorLib::ColorConverter::ProcessHiveNeighbors(ConversionInput *conv
delete[]LabInFinal1;
LabInFinal1 = NULL;
}
+ if (InkOutP != NULL)
+ {
+ delete[] InkOutP;
+ InkOutP = NULL;
+ }
return;
}
@@ -443,6 +452,10 @@ void Tango::ColorLib::ColorConverter::ArrangeHiveData(MatrixXd LabHive, MatrixX
}
}
+
+
+
+
void Tango::ColorLib::ColorConverter::fillVolume(OutputCoordinates *&outputCoords, VectorXd Volume)
{
int i = 0;
@@ -493,29 +506,39 @@ void Tango::ColorLib::ColorConverter::fillLab(OutputCoordinates *outputCoords, V
outputCoords->has_b = true;
outputCoords->b = LabOut(2);
}
-
void Tango::ColorLib::ColorConverter::readColorTransformations(ConversionInput* conversionInput)
{
+ SetStripWhitepoint(conversionInput->threadl, conversionInput->threada, conversionInput->threadb);
+ bool has_forwarddata = conversionInput->has_forwarddata;
+ uint8_t *data = conversionInput->forwarddata.data;
+ int nprocessranges = conversionInput->n_processranges;
+ readColorTables(has_forwarddata, data, nprocessranges);
+
+}
+
+void Tango::ColorLib::ColorConverter::SetStripWhitepoint(double threadl, double threada, double threadb)
+{
//Read thread white. Thread White is given in CIELab Space
- m_whitepointLab.Set(conversionInput->threadl, conversionInput->threada, conversionInput->threadb);
+ m_whitepointLab.Set(threadl, threada, threadb);
//White point in XYZ Color Space
ColorConvert CConvert(D65, D65);
C_RGB_XYZ_Lab tmpW;
tmpW = CConvert.LabToXYZ(m_whitepointLab);
m_whitepointXYZ_Strip.Set(tmpW.Get_x(), tmpW.Get_y(), tmpW.Get_z());
+}
-
-
+void Tango::ColorLib::ColorConverter::readColorTables(bool has_data, uint8_t * data, int nprocessranges)
+{
//parse Color Tansformations, placed in forward data
int bytesread = 0;
NumConversions conv;
int tag_count = 0;
- if (conversionInput->has_forwarddata)
+ if (has_data)
{
//Read Header
- CT_Header header = read_header(conversionInput, bytesread);
+ CT_Header header = read_header(data, bytesread);
SetnGamutRegions((int)header.nGamutRegions);
- if (m_nGamutRegions != conversionInput->n_processranges)
+ if (m_nGamutRegions != nprocessranges)
{
throw std::exception("Number of gamut regions in table does not match STRIP\0");
return;
@@ -523,7 +546,7 @@ void Tango::ColorLib::ColorConverter::readColorTransformations(ConversionInput*
m_GamutRegionMaxLim = new double[m_nGamutRegions];
for (int i = 0; i < m_nGamutRegions; ++i)
m_GamutRegionMaxLim[i] = header.GRegMaxLim[i];
- m_nProcessRanges = (int)(conversionInput->n_processranges);
+ m_nProcessRanges = (int)(nprocessranges);
/* for (int i = 0; i < m_nGamutRegions; ++i)
{
@@ -539,7 +562,7 @@ void Tango::ColorLib::ColorConverter::readColorTransformations(ConversionInput*
uint32_t tmp;
- uint8_t *buff = conversionInput->forwarddata.data;
+ uint8_t *buff =data;
tmp = conv.ByteToInt(buff, bytesread);
tag_count = (int)tmp;
bytesread += 4;
@@ -602,7 +625,7 @@ void Tango::ColorLib::ColorConverter::readColorTransformations(ConversionInput*
{
case A2B:
{
- uint8_t *A2BLUT = &(conversionInput->forwarddata.data[TagSize[k][0]]);
+ uint8_t *A2BLUT = &(data[TagSize[k][0]]);
int A2BLutsize = TagSize[k][1];
m_A2BTransform = new ColorTransf();
//m_A2BTransform = DBG_NEW ColorTransf();
@@ -611,7 +634,7 @@ void Tango::ColorLib::ColorConverter::readColorTransformations(ConversionInput*
}
case B2A:
{
- uint8_t *B2ALUT = &(conversionInput->forwarddata.data[TagSize[k][0]]);
+ uint8_t *B2ALUT = &(data[TagSize[k][0]]);
int B2ALutsize = TagSize[k][1];
m_B2ATransform = new ColorTransf();
//m_B2ATransform = DBG_NEW ColorTransf();
@@ -629,7 +652,7 @@ void Tango::ColorLib::ColorConverter::readColorTransformations(ConversionInput*
} */
case gbd:
{
- uint8_t *GBDList = &(conversionInput->forwarddata.data[TagSize[k][0]]);
+ uint8_t *GBDList = &(data[TagSize[k][0]]);
m_GBD = new GBD();
//m_GBD = DBG_NEW GBD();
int GBDSize = TagSize[k][1];
@@ -638,7 +661,7 @@ void Tango::ColorLib::ColorConverter::readColorTransformations(ConversionInput*
}
case lcrv:
{
- uint8_t *CurvesData = &(conversionInput->forwarddata.data[TagSize[k][0]]);
+ uint8_t *CurvesData = &(data[TagSize[k][0]]);
m_LinCurves = new Curves();
int CurvesSize = TagSize[k][1];
m_LinCurves->InitData(CurvesData, CurvesSize);
@@ -646,20 +669,20 @@ void Tango::ColorLib::ColorConverter::readColorTransformations(ConversionInput*
}
case wtpt:
{
- read_xyz_type(TagSize[k][0], TagSize[k][1], &m_whitepointXYZ_CT, conversionInput);
+ read_xyz_type(TagSize[k][0], TagSize[k][1], &m_whitepointXYZ_CT, data);
break;
}
case cprt:
{
std::string textstr;
- read_text_type(TagSize[k][0], TagSize[k][1], &textstr, conversionInput);
+ read_text_type(TagSize[k][0], TagSize[k][1], &textstr, data);
break;
}
case desc:
{
std::string textdescstr;
- read_text_description_type(TagSize[k][0], TagSize[k][1], textdescstr, conversionInput);
+ read_text_description_type(TagSize[k][0], TagSize[k][1], textdescstr, data);
break;
}
default:
@@ -744,19 +767,19 @@ void Tango::ColorLib::ColorConverter::readColorTransformations(ConversionInput*
}
-void Tango::ColorLib::ColorConverter::readCalibrationTables(ConversionInput* conversionInput)
+void Tango::ColorLib::ColorConverter::readCalibrationTables(InputLiquid **inputliquid, int n_inputliquid)
{
- SetNumberofInks((int)(conversionInput->inputcoordinates->n_inputliquids));
+ SetNumberofInks((int)(n_inputliquid));
//CalibData *CalibCurves = new CalibData[m_nInks];
m_CalibCurves = new CalibData[m_nInks];
//m_CalibCurves = DBG_NEW CalibData[m_nInks];
for (int i = 0; i < m_nInks; ++i)
{
- InputLiquid* InkType = conversionInput->inputcoordinates->inputliquids[i];
+ InputLiquid* InkType = inputliquid[i];
m_CalibCurves[i].SetCalibName((int)(InkType->calibrationdata->liquidtype));
- m_CalibCurves[i].SetMaxNlPerCM(conversionInput->inputcoordinates->inputliquids[i]->maxnanoliterpercentimeter);
+ m_CalibCurves[i].SetMaxNlPerCM(inputliquid[i]->maxnanoliterpercentimeter);
switch (InkType->calibrationdata->liquidtype)
{
case LIQUID_TYPE__Cyan:
@@ -821,7 +844,8 @@ void Tango::ColorLib::ColorConverter::SetCalibData(CalibrationData *calibrationD
return;
}
-void Tango::ColorLib::ColorConverter::ConvertColorToLinearInks(ConversionInput* conversionInput, VectorXd &InkOut, VectorXd &RGBOut,
+void Tango::ColorLib::ColorConverter::ConvertColorToLinearInks(InputCoordinates* inputcoordinates, ColorSpace colorspace,
+ VectorXd &InkOut, VectorXd &RGBOut,
VectorXd &LabOut, int &GamutRegion, bool &InGamut)
{
size_t nInks = 0;
@@ -829,7 +853,7 @@ void Tango::ColorLib::ColorConverter::ConvertColorToLinearInks(ConversionInput*
C_RGB_XYZ_Lab DataLab;
SURROUND sur = m_Conv02->getSurround();
CAM02CS CS = m_Conv02->getCAM02CS();
- switch (conversionInput->colorspace)
+ switch (colorspace)
{
case (COLOR_SPACE__RGB):
{
@@ -843,9 +867,9 @@ void Tango::ColorLib::ColorConverter::ConvertColorToLinearInks(ConversionInput*
//4. Convert Lab to Absolute colorimetric taking into account the Strip and Color Table whitepoints
//5. Use the Relative Colorimetric Lab to obtain RGB
- RGBOut(0) = conversionInput->inputcoordinates->red;
- RGBOut(1) = conversionInput->inputcoordinates->green;
- RGBOut(2) = conversionInput->inputcoordinates->blue;
+ RGBOut(0) = inputcoordinates->red;
+ RGBOut(1) = inputcoordinates->green;
+ RGBOut(2) = inputcoordinates->blue;
//convert to Lab
ColorConvert CConvertD65(D65, D65); //Destination, source
double *LabIn = new double[3];
@@ -867,19 +891,18 @@ void Tango::ColorLib::ColorConverter::ConvertColorToLinearInks(ConversionInput*
double *InkOutP = new double[m_nB2AnSepOut];
//double *InkOutP = DBG_NEW double[m_nB2AnSepOut];
//LabInFinal is in Relative Colorimetric, just like the Color Tables
- m_B2ATransform->evalLab2InkP(LabOnGamut, InkOutP, GamutRegion); //InkOut is in units of 16 bits
+ m_B2ATransform->evalLab2InkP(LabOnGamut, InkOutP, GamutRegion); //InkOut is inthe [0-100] interval
//Convert to Lab to get the actual in Gamut Lab
//double *LabInP = new double[3];
//double *LabInP = DBG_NEW double[3];
//m_A2BTransform->evalInkP2Lab(InkOutP, LabInP, GamutRegion); //Lab is in Relative Colorimetric
- double NormFactor = m_ProcessRangesMaxP[m_nProcessRanges - 1] / 100.0;
//Convert InkOut to Linear via initial calibration Tables
//Initial calibration tables are the ones that were included in the color table
for (int i = 0; i < m_nB2AnSepOut; ++i)
{
- InkOutP[i] *= NormFactor;
- if (InkOutP[i] <= m_ProcessRangesMaxP[0])
+ InkOutP[i] *= m_NormFactor;
+ if (InkOutP[i] <= m_GamutRegionMaxLim[0])
{
m_LinCurves->m_InterpCurves[i].Eval(InkOutP[i] * 655.35, InkOutP[i]);
InkOutP[i] /= 655.35;
@@ -888,13 +911,16 @@ void Tango::ColorLib::ColorConverter::ConvertColorToLinearInks(ConversionInput*
InkOut = DoubleToVector(InkOutP, m_nInks);
//Convert to CT thread, LabOnGamut is in Relative Colorimetric Space
- CConvertD65.ChangeWP(LabOnGamut, LabInFinal, m_whitepointXYZ_CT, m_WP);
+ //CConvertD65.ChangeWP(LabOnGamut, LabInFinal, m_whitepointXYZ_CT, m_WP);
+ CConvertD65.ChangeWP(LabOnGamut, LabInFinal, m_whitepointXYZ_Strip, m_WP);
//check if the thread to be used is the same as the one in the color tables
+ /*
if (m_AdaptWP)
{
//Convert to Strip White Point
CConvertD65.ChangeWP(LabInFinal, LabInFinal, m_whitepointXYZ_Strip, m_whitepointXYZ_CT);
}
+ */
LabOut = DoubleToVector(LabInFinal, 3);
CConvertD65.SetReferenceWhite(D65);
double *RGBOutP1 = new double[3];
@@ -945,28 +971,31 @@ void Tango::ColorLib::ColorConverter::ConvertColorToLinearInks(ConversionInput*
//5. Use the Relative Colorimetric Lab to obtain RGB
double *LabIn = new double[3];
//double *LabIn = DBG_NEW double[3];
- LabIn[0] = conversionInput->inputcoordinates->l; //Absolute Colorimetric
- LabIn[1] = conversionInput->inputcoordinates->a;
- LabIn[2] = conversionInput->inputcoordinates->b;
+ LabIn[0] = inputcoordinates->l; //Absolute Colorimetric
+ LabIn[1] = inputcoordinates->a;
+ LabIn[2] = inputcoordinates->b;
//the assumption is that the color space has illumination that matches the whitepoint of the Strip
ColorConvert CConvertD65(D65, D65); //Destination, source
- double *LabInFinal1 = new double[3];
+ // double *LabInFinal1 = new double[3];
//double *LabInFinal1 = DBG_NEW double[3];
- for (int i = 0; i < 3; ++i)
- LabInFinal1[i] = LabIn[i];
+ // for (int i = 0; i < 3; ++i)
+ // LabInFinal1[i] = LabIn[i];
//LabInFinal1 = LabIn;
// Lab is assumed to match the color of the STRIP, however the tables could have a different WP
//Check if Color Tables and Strip whitepoints are the same, otherwise convert
- if (m_AdaptWP)
+ /*
+ if (m_AdaptWP)
{
CConvertD65.ChangeWP(LabInFinal1, LabInFinal1, m_whitepointXYZ_CT, m_whitepointXYZ_Strip); //to Color Tables
for (int i = 0; i < 3; ++i)
LabIn[i] = LabInFinal1[i];
}
+ */
double *LabInFinal2 = new double[3];
double *LabOnGamut = new double[3];
//double *LabInFinal2 = DBG_NEW double[3];
- CConvertD65.ChangeWP(LabIn, LabInFinal2, m_WP, m_whitepointXYZ_CT); //LabInFinal2 is in Relative Colorimetric Space
+// CConvertD65.ChangeWP(LabIn, LabInFinal2, m_WP, m_whitepointXYZ_CT); //LabInFinal2 is in Relative Colorimetric Space
+ CConvertD65.ChangeWP(LabIn, LabInFinal2, m_WP, m_whitepointXYZ_Strip); //LabInFinal2 is in Relative Colorimetric Space
InGamut = IsInGamut(LabInFinal2, sur, CS, LabOnGamut);
LimitLab(LabOnGamut);
@@ -978,12 +1007,11 @@ void Tango::ColorLib::ColorConverter::ConvertColorToLinearInks(ConversionInput*
//Convert Inks to Lab to get the Gamut Mapped Lab
//m_A2BTransform->evalInkP2Lab(InkOutP, LabIn, GamutRegion);
//LabOut = DoubleToVector(LabIn, 3);
- //Convert InkOutP to linear in the m_ProcessRangesMaxP[0] range
- double NormFactor = m_ProcessRangesMaxP[m_nProcessRanges - 1] / 100.0;
+ //Convert InkOutP to linear in the m_GamutRegionMaxLim[0] range
for (int i = 0; i < m_nB2AnSepOut; ++i)
{
- InkOutP[i] *= NormFactor;
- if (InkOutP[i] <= m_ProcessRangesMaxP[0])
+ InkOutP[i] *= m_NormFactor;
+ if (InkOutP[i] <= m_GamutRegionMaxLim[0])
{
m_LinCurves->m_InterpCurves[i].Eval(InkOutP[i] * 655.35, InkOutP[i]);
InkOutP[i] /= 655.35;
@@ -996,11 +1024,14 @@ void Tango::ColorLib::ColorConverter::ConvertColorToLinearInks(ConversionInput*
LabOutFinal[i] = LabOnGamut[i];
//LabOutFinal is in Relative Colorimetric
//Reverse the conversion process to bring back Lab to STRIP white point
- CConvertD65.ChangeWP(LabOutFinal, LabOutFinal, m_whitepointXYZ_CT, m_WP);
+// CConvertD65.ChangeWP(LabOutFinal, LabOutFinal, m_whitepointXYZ_CT, m_WP);
+ CConvertD65.ChangeWP(LabOutFinal, LabOutFinal, m_whitepointXYZ_Strip, m_WP);
+/*
if (m_AdaptWP)
{
CConvertD65.ChangeWP(LabOutFinal, LabOutFinal, m_whitepointXYZ_Strip, m_whitepointXYZ_CT);
}
+ */
LabOut = DoubleToVector(LabOutFinal, 3);
CConvertD65.SetReferenceWhite(D65);
//Convert to RGB
@@ -1025,11 +1056,12 @@ void Tango::ColorLib::ColorConverter::ConvertColorToLinearInks(ConversionInput*
delete[] LabIn;
LabIn = NULL;
}
- if (LabInFinal1 != NULL)
+/* if (LabInFinal1 != NULL)
{
delete[]LabInFinal1;
LabInFinal1 = NULL;
}
+ */
if (LabInFinal2 != NULL)
{
delete[]LabInFinal2;
@@ -1056,10 +1088,10 @@ void Tango::ColorLib::ColorConverter::ConvertColorToLinearInks(ConversionInput*
double *outData = new double[m_nA2BnSepIn];
//double *outData = DBG_NEW double[m_nA2BnSepIn];
size_t CountSep = 0;
- outData[0] = (double)(conversionInput->inputcoordinates->cyan);
- outData[1] = (double)(conversionInput->inputcoordinates->magenta);
- outData[2] = (double)(conversionInput->inputcoordinates->yellow);
- outData[3] = conversionInput->inputcoordinates->key;
+ outData[0] = (double)(inputcoordinates->cyan);
+ outData[1] = (double)(inputcoordinates->magenta);
+ outData[2] = (double)(inputcoordinates->yellow);
+ outData[3] = (double)(inputcoordinates->key);
CountSep = 4;
if (CountSep != m_nA2BnSepIn)
@@ -1090,13 +1122,15 @@ void Tango::ColorLib::ColorConverter::ConvertColorToLinearInks(ConversionInput*
LabOutFinal2[i] = LabOutP[i];
InGamut = true;
//Check if white points match
- CConvertD65.ChangeWP(LabOutFinal1, LabOutFinal1, m_whitepointXYZ_CT, m_WP); //To Absolute
- if (m_AdaptWP)
+// CConvertD65.ChangeWP(LabOutFinal1, LabOutFinal1, m_whitepointXYZ_CT, m_WP); //To Absolute
+ CConvertD65.ChangeWP(LabOutFinal1, LabOutFinal1, m_whitepointXYZ_Strip, m_WP); //To Absolute
+/* if (m_AdaptWP)
{
CConvertD65.ChangeWP(LabOutFinal1, LabOutFinal2, m_whitepointXYZ_Strip, m_whitepointXYZ_CT);
for (int i = 0; i < 3; ++i)
LabOutFinal1[i] = LabOutFinal2[i];
}
+ */
LabOut = DoubleToVector(LabOutFinal1, 3);
CConvertD65.SetReferenceWhite(D65);
//Get RGB
@@ -1141,8 +1175,8 @@ void Tango::ColorLib::ColorConverter::ConvertColorToLinearInks(ConversionInput*
case(COLOR_SPACE__Catalog):
{
int32_t inData;
- if (conversionInput->inputcoordinates->has_pantoncode)
- inData = conversionInput->inputcoordinates->pantoncode;
+ if (inputcoordinates->has_pantoncode)
+ inData = inputcoordinates->pantoncode;
else
{
//mismatch between color space and data
@@ -1156,7 +1190,7 @@ void Tango::ColorLib::ColorConverter::ConvertColorToLinearInks(ConversionInput*
default:
{
throw std::exception(" Unsupported Color Space");
- return;
+ break;
}
}
//all data is now in linear ink format
@@ -1168,7 +1202,7 @@ void Tango::ColorLib::ColorConverter::ConvertToNLInks(VectorXd InkIn, VectorXd
{
for (int i = 0; i < m_nVolumes; ++i)
{
- if (InkIn(i) <= m_ProcessRangesMaxP[0])
+ if (InkIn(i) <= m_GamutRegionMaxLim[0])
m_CalibCurves[i].m_InvLinearInterp->Eval(InkIn(i), InkOut(i));
else
InkOut(i) = InkIn(i);
@@ -1188,13 +1222,14 @@ void Tango::ColorLib::ColorConverter::ConvertToLinearInks(VectorXd InkIn, Vecto
void Tango::ColorLib::ColorConverter::VolumeToNLInkP(VectorXd Volume, VectorXd &NLInkP)
{
+ //Volume is in %. In order to be compatible with NL to volume it has to be tranlated to nl/cm
VectorXd InkP(m_nVolumes);
int MaxInd = -1;
double InkMax = -1.;
double InkSum = 0.;
for (int i = 0; i < m_nVolumes; ++i)
{
- InkP(i) = Volume(i); /// 100 * Volume(i) / m_maxNlPerCM(i); //Volume is in %
+ InkP(i) = Volume(i)* m_maxNlPerCM(i)/100; //Volume is in %, InkP is in [nl/cm]
if (InkMax < InkP(i))
{
InkMax = InkP(i);
@@ -1202,7 +1237,7 @@ void Tango::ColorLib::ColorConverter::VolumeToNLInkP(VectorXd Volume, VectorXd &
}
InkSum += InkP(i);
}
- NLInkP(MaxInd) = InkSum;
+ NLInkP(MaxInd) =100* InkSum/ m_maxNlPerCM(MaxInd); //Back to %
if (InkSum == 0.0)
{
for (int i = 0; i < m_nVolumes; ++i)
@@ -1245,7 +1280,7 @@ void Tango::ColorLib::ColorConverter::VolumeToNLInkP(VectorXd Volume, VectorXd &
if (i != MaxInd)
{
ind += 1;
- NLInkP(i) = Result(ind);
+ NLInkP(i) =100* Result(ind)/m_maxNlPerCM(i); //Back to %
}
}
return;
@@ -1286,7 +1321,7 @@ void Tango::ColorLib::ColorConverter::NLInkPToVolume(VectorXd NLInk, VectorXd &V
RVolNorm(i) = round(Volume(i)*ROUNDINGTol) / ROUNDINGTol;
RsumNorm += RVolNorm(i);
}
- if (RsumNorm > m_ProcessRangesMaxP[m_nProcessRanges - 1] || abs(sumNorm - RsumNorm) >= 1 / ROUNDINGTol)
+ if (RsumNorm > m_GamutRegionMaxLim[m_nProcessRanges - 1] || abs(sumNorm - RsumNorm) >= 1 / ROUNDINGTol)
{
VectorXd dd(m_nInks);
double maxdd = -1;
@@ -1379,9 +1414,10 @@ void Tango::ColorLib::ColorConverter::SetMaxNLperCM(double maxNlPerCM, int i)
m_maxNlPerCM(i) = maxNlPerCM;
}
-void Tango::ColorLib::ColorConverter::ConvertVolumeToRGBDisplay(ConversionInput* conversionInput, VectorXd &Volume, VectorXd &RGBOut, VectorXd &LabOut, int &GamutRegion)
+void Tango::ColorLib::ColorConverter::ConvertVolumeToRGBDisplay(InputCoordinates *inputcoordinates, int n_processRanges,
+ int colorspace, VectorXd &Volume, VectorXd &RGBOut, VectorXd &LabOut, int &GamutRegion)
{
- SetNumberOfVolumes((int)(conversionInput->inputcoordinates->n_inputliquids));
+ SetNumberOfVolumes((int)(inputcoordinates->n_inputliquids));
// Set Calibration Data
LiquidType LQ;
if (m_CalibCurves == NULL)
@@ -1390,46 +1426,45 @@ void Tango::ColorLib::ColorConverter::ConvertVolumeToRGBDisplay(ConversionInput*
//m_CalibCurves = DBG_NEW CalibData[m_nInks];
for (int i = 0; i < m_nVolumes; ++i)
{
- LQ = conversionInput->inputcoordinates->inputliquids[i]->calibrationdata->liquidtype;
+ LQ =inputcoordinates->inputliquids[i]->calibrationdata->liquidtype;
if (LQ == LIQUID_TYPE__Cyan || LQ == LIQUID_TYPE__Magenta || LQ == LIQUID_TYPE__Yellow || LQ == LIQUID_TYPE__Black)
{
//Get calibration data.
- CalibrationData* calibrationData = conversionInput->inputcoordinates->inputliquids[i]->calibrationdata;
+ CalibrationData* calibrationData = inputcoordinates->inputliquids[i]->calibrationdata;
SetCalibData(calibrationData, i, &m_CalibCurves[i]);
- SetMaxNLperCM(conversionInput->inputcoordinates->inputliquids[i]->maxnanoliterpercentimeter, i);
- m_CalibCurves[i].SetCalibName((int)(conversionInput->inputcoordinates->inputliquids[i]->calibrationdata->liquidtype));
+ SetMaxNLperCM(inputcoordinates->inputliquids[i]->maxnanoliterpercentimeter, i);
+ m_CalibCurves[i].SetCalibName((int)(inputcoordinates->inputliquids[i]->calibrationdata->liquidtype));
}
else
std::exception("unsupported volume");
}
}
+
+ //July 29 2020
+ //Limit inks based on m_maxNlpercm
+ //Inks are limited in their nonlinear form
VectorXd NLInkP((int)(m_nVolumes));
VectorXd InkOut((int)(m_nVolumes));
//Convert to Nonlinear Inks
double SumVol_Ink = 0.0;
+ //Get Gamut Region
for (int i = 0; i < m_nVolumes; ++i)
- {
- Volume(i) = conversionInput->inputcoordinates->inputliquids[i]->volume; //volume is given in %
- SumVol_Ink += Volume(i);
- }
- for (int i = 0; i < int(conversionInput->n_processranges - 1); ++i)
- {
- if (SumVol_Ink > m_ProcessRangesMaxP[i])
- GamutRegion++;
- }
+ Volume(i) = inputcoordinates->inputliquids[i]->volume; //volume is given in %
+
+ GamutRegion = GetGamutRegion(Volume, m_GamutRegionMaxLim);
VolumeToNLInkP(Volume, NLInkP);
+ //Limit Inks
double *InkOutP = new double[m_nA2BnSepIn];
VectorToDouble(NLInkP, InkOutP);
//for (int i = 0; i < m_nA2BnSepIn; ++i)
// InkOutP[i] = NLInkP(i);
double *LinInkP = new double[m_nA2BnSepIn];
- double NormFactor = 100 / m_ProcessRangesMaxP[m_nProcessRanges - 1];
-
- if (conversionInput->colorspace == COLOR_SPACE__Catalog)
+//Reflect the Calibration Curves of the thread in Catalog Items
+ if (colorspace == COLOR_SPACE__Catalog)
{
for (int i = 0; i < m_nB2AnSepOut; ++i)
{
- if (NLInkP(i) <= m_ProcessRangesMaxP[0])
+ if (NLInkP(i) <= m_GamutRegionMaxLim[0])
{
m_LinCurves->m_InterpCurves[i].Eval(InkOutP[i] * 655.35, InkOutP[i]);
InkOutP[i] /= 655.35;
@@ -1439,15 +1474,24 @@ void Tango::ColorLib::ColorConverter::ConvertVolumeToRGBDisplay(ConversionInput*
}
for (int i = 0; i < (int)(m_nVolumes); ++i)
{
- if (NLInkP(i) <= m_ProcessRangesMaxP[0])
+ if (NLInkP(i) <= m_GamutRegionMaxLim[0])
{
m_CalibCurves[i].m_InvLinearInterp->Eval(InkOutP[i], InkOutP[i]);
NLInkP(i) = InkOutP[i];
}
}
- NLInkPToVolume(NLInkP, Volume);
+ //NLInkPToVolume(NLInkP, Volume);
}
+ //July 29 2020
+ //Limit inks based on m_maxNlpercm
+ //Inks are limited in their nonlinear form
+ //Output Volume is in %
+ LimitInks(NLInkP, InkOutP);
+ NLInkPToVolume(DoubleToVector(InkOutP, m_nInks), Volume);
+ GamutRegion = GetGamutRegion(Volume, m_ProcessRangesMaxP);
+ NLcmtoPercentage(Volume, Volume);
+
//Convert to RGB
//GamutRegion = 0;
//Convert to Lab
@@ -1457,7 +1501,7 @@ void Tango::ColorLib::ColorConverter::ConvertVolumeToRGBDisplay(ConversionInput*
//double *LabOutP = DBG_NEW double[m_nA2BnSepOut];
//InkOutP has to be normalized to match the transform units
for (int i = 0; i < m_nB2AnSepOut; ++i)
- InkOutP[i] *= NormFactor;
+ InkOutP[i] *= m_InvNormFactor;
m_A2BTransform->evalInkP2Lab(InkOutP, LabOutP, GamutRegion);
@@ -1467,14 +1511,17 @@ void Tango::ColorLib::ColorConverter::ConvertVolumeToRGBDisplay(ConversionInput*
//double *LabOutFinal1 = DBG_NEW double[3];
double *LabOutFinal = new double[3];
- CConvertD65.ChangeWP(LabOutP, LabOutFinal1, m_whitepointXYZ_CT, m_WP); //To Absolute
+ //CConvertD65.ChangeWP(LabOutP, LabOutFinal1, m_whitepointXYZ_CT, m_WP); //To Absolute
+ CConvertD65.ChangeWP(LabOutP, LabOutFinal1, m_whitepointXYZ_Strip, m_WP); //To Absolute
for (int i = 0; i < 3; ++i)
LabOutFinal[i] = LabOutFinal1[i];
+/*
if (m_AdaptWP)
{
CConvertD65.ChangeWP(LabOutFinal, LabOutFinal, m_whitepointXYZ_Strip, m_whitepointXYZ_CT);
}
+ */
LabOut = DoubleToVector(LabOutFinal, 3);
CConvertD65.SetReferenceWhite(D65);
@@ -1605,10 +1652,10 @@ size_t Tango::ColorLib::ColorConverter::Convert(uint8_t * input_buffer, size_t i
//count number if inks
// int numofInks = CountNumberofInks(conversionInput);
readColorTransformations(conversionInput);
-
//read calibration tables and store them in m_CalibCurves
-
- readCalibrationTables(conversionInput);
+ InputLiquid **inputliquids = conversionInput->inputcoordinates->inputliquids;
+ int n_inputliquids = conversionInput->inputcoordinates->n_inputliquids;
+ readCalibrationTables(inputliquids, n_inputliquids);
//Initialize CIECAM02 transformation
Illum IL = D65;
@@ -1623,27 +1670,24 @@ size_t Tango::ColorLib::ColorConverter::Convert(uint8_t * input_buffer, size_t i
SetNumberOfInks(m_nB2AnSepOut);
// Compare Strip White point to Color Table White Point
- CompareWhitePoints();
+ //CompareWhitePoints();
if (numofInks != m_nB2AnSepOut)
throw std::exception("Number of available inks does not match ink tables\0");
//Tables have been filled
-
- //Convert maxInkUptake to percentages
-
- //m_ProcessRangesMinP = new double[m_nProcessRanges];
+ //Set Process Ranges
m_ProcessRangesMaxP = new double[m_nProcessRanges];
- //m_ProcessRangesMinInkUptake = new double[m_nProcessRanges];
- //m_ProcessRangesMaxInkUptake = new double[m_nProcessRanges];
for (int i = 0; i < m_nProcessRanges; ++i)
{
- // m_ProcessRangesMinP[i] = 100*(conversionInput->processranges[i]->mininkuptake)/ (conversionInput->processranges[0]->mininkuptake);
- m_ProcessRangesMaxP[i] = 100 * (conversionInput->processranges[i]->maxinkuptake) / (conversionInput->processranges[0]->maxinkuptake);
- //m_ProcessRangesMinInkUptake[i] = conversionInput->processranges[i]->mininkuptake;
- //m_ProcessRangesMaxInkUptake[i] = conversionInput->processranges[i]->maxinkuptake;
+ m_ProcessRangesMaxP[i] = conversionInput->processranges[i]->maxinkuptake;
+ }
+ NormGamutRegionMaxLim();
+ if (m_NormFactor <= 0.0)
+ {
+ SetNormFactor();
+ SetInverseNormFactor();
}
-
VectorXd InkOut(m_nB2AnSepOut);
VectorXd RGBOut(3);
VectorXd LabOut(3);
@@ -1661,28 +1705,34 @@ size_t Tango::ColorLib::ColorConverter::Convert(uint8_t * input_buffer, size_t i
//Convert input data to linear inks
if (conversionInput->colorspace == COLOR_SPACE__Volume || conversionInput->colorspace == COLOR_SPACE__Catalog)
{
- ConvertVolumeToRGBDisplay(conversionInput, Volume, RGBOut, LabOut, GamutRegion);
+ InputCoordinates *IC = conversionInput->inputcoordinates;
+ int colorspace = conversionInput->colorspace;
+ ConvertVolumeToRGBDisplay(IC, conversionInput->n_processranges, colorspace, Volume, RGBOut, LabOut, GamutRegion);
InGamut = true;
}
else
{
- ConvertColorToLinearInks(conversionInput, InkOut, RGBOut, LabOut, GamutRegion, InGamut);
+ ConvertColorToLinearInks(conversionInput->inputcoordinates, conversionInput->colorspace, InkOut, RGBOut,
+ LabOut, GamutRegion, InGamut);
//Inks are in Linear Space , convert to nonlinear by using Calibration Tables,
// Right now calibration is in the [0-100] range, values exceeding [0-100] are not transformed
ConvertToNLInks(InkOut, NLInkOut);
- //Determine Gamut Region
- double maxNLInk = NegValue;
- for (int i = 0; i < m_nInks; ++i)
- maxNLInk = std::max(NLInkOut[i], maxNLInk);
-
- for (int i = 0; i < int(conversionInput->n_processranges - 1); ++i)
+
+ //Limit inks based on m_maxNlpercm
+ //Inks are limited in their nonlinear form
+ //Output Volume is in %
+ double *InkOutP = new double[m_nB2AnSepOut];
+ LimitInks(NLInkOut, InkOutP);
+ NLInkPToVolume(DoubleToVector(InkOutP, m_nInks), Volume);
+ GamutRegion = GetGamutRegion(Volume, m_ProcessRangesMaxP);
+ NLcmtoPercentage(Volume, Volume);
+ //OutputCoordinates outputCoords = OUTPUT_COORDINATES__INIT;
+ if (InkOutP != NULL)
{
- if (maxNLInk > m_ProcessRangesMaxP[i])
- GamutRegion++;
+ delete[] InkOutP;
+ InkOutP = NULL;
}
- //Convert to [nl/cm]
- NLInkPToVolume(NLInkOut, Volume);
- //OutputCoordinates outputCoords = OUTPUT_COORDINATES__INIT;
+
}
OutputCoordinates *outputCoords = (OutputCoordinates*)malloc(sizeof(OutputCoordinates));
output_coordinates__init(outputCoords);
@@ -1975,14 +2025,14 @@ bool Tango::ColorLib::ColorConverter::IsInGamut(double *InLab, SURROUND sur, CA
}
-Tango::CT_Header Tango::ColorLib::ColorConverter::read_header(ConversionInput* conversionInput, int &bytesread)
+Tango::CT_Header Tango::ColorLib::ColorConverter::read_header(uint8_t *data, int &bytesread)
{
//CT_Header *Header = new CT_Header;
//CT_Header *Header = DBG_NEW CT_Header;
CT_Header Header;
// unsigned int tmp = (buffer[2 * i + 1] << 8) | buffer[2 * i];
- uint8_t *ColorTable = conversionInput->forwarddata.data;
+ uint8_t *ColorTable =data;
//File Size
NumConversions Conv;
Header.TblSIze = Conv.ByteToInt(ColorTable, bytesread);
@@ -2088,7 +2138,7 @@ void Tango::ColorLib::ColorConverter::read_lut_type(int offset, int data_size, C
return;
}
-void Tango::ColorLib::ColorConverter::read_xyz_type(int offset, int data_size, C_RGB_XYZ_Lab *XYZ, ConversionInput* conversionInput)
+void Tango::ColorLib::ColorConverter::read_xyz_type(int offset, int data_size, C_RGB_XYZ_Lab *XYZ, uint8_t *data)
{
// 0 - 3 'XYZ '
//4 - 7 reserved, must be 0
@@ -2098,7 +2148,7 @@ void Tango::ColorLib::ColorConverter::read_xyz_type(int offset, int data_size, C
{
throw std::exception("not enough data to read xyz");
}
- uint8_t *buff = &(conversionInput->forwarddata.data[offset]);
+ uint8_t *buff = &(data[offset]);
NumConversions Conv;
int bytesread = 0;
int tmpxyz = Conv.ByteToInt(buff, bytesread);
@@ -2145,8 +2195,7 @@ void Tango::ColorLib::ColorConverter::read_xyz_type(int offset, int data_size, C
return;
}
-void Tango::ColorLib::ColorConverter::read_text_type(int offset, int data_size, std::string *textstr,
- ConversionInput* conversionInput)
+void Tango::ColorLib::ColorConverter::read_text_type(int offset, int data_size, std::string *textstr, uint8_t *data)
{
// 0 - 3 'text'
//4 - 7 reserved, must be 0
@@ -2161,7 +2210,7 @@ void Tango::ColorLib::ColorConverter::read_text_type(int offset, int data_size,
return;
}
- uint8_t *buff = &(conversionInput->forwarddata.data[offset]);
+ uint8_t *buff = &(data[offset]);
int bytesread = 0;
NumConversions Conv;
int tmp = Conv.ByteToInt(buff, bytesread);
@@ -2201,15 +2250,14 @@ void Tango::ColorLib::ColorConverter::read_text_type(int offset, int data_size,
}
-void Tango::ColorLib::ColorConverter::read_text_description_type(int offset, int data_size, std::string textdescstr,
- ConversionInput* conversionInput)
+void Tango::ColorLib::ColorConverter::read_text_description_type(int offset, int data_size, std::string textdescstr, uint8_t *data)
{
// 0 - 3 'desc'
// 4 - 7 reserved, must be 0
// 8 - 11 ASCII invariant description count, including terminating NULL
// 12 - ASCII invariant description
- uint8_t *buff = &(conversionInput->forwarddata.data[offset]);
+ uint8_t *buff = &(data[offset]);
int bytesread = 0;
NumConversions Conv;
int tmp = Conv.ByteToInt(buff, bytesread);
@@ -2251,7 +2299,7 @@ void Tango::ColorLib::ColorConverter::read_text_description_type(int offset, int
return;
}
-void Tango::ColorLib::ColorConverter::CompareWhitePoints()
+/*void Tango::ColorLib::ColorConverter::CompareWhitePoints()
{
ColorConvert ColConv(D65, D65);
C_RGB_XYZ_Lab Lab_CT;
@@ -2270,10 +2318,10 @@ void Tango::ColorLib::ColorConverter::CompareWhitePoints()
ColConv.SymmetricaldECMC(VLab_CT, VLab_Strip, dECMC);
if (dECMC > WPTol)
m_AdaptWP = true;
- if (m_whitepointXYZ_Strip.Get_x() <= 0 || m_whitepointXYZ_Strip.Get_y() > 0 || m_whitepointXYZ_Strip.Get_z())
+ if (m_whitepointXYZ_Strip.Get_x() <= 0 || m_whitepointXYZ_Strip.Get_y() <= 0 || m_whitepointXYZ_Strip.Get_z()<=0)
m_AdaptWP = false;
return;
-}
+} */ /* not used*/
//size_t Tango::ColorLib::ColorConverter::Convert(uint8_t * input_buffer, size_t input_buffer_size, uint8_t *& output_buffer)
//{
@@ -2479,8 +2527,9 @@ size_t Tango::ColorLib::ColorConverter::P_IsInGamut(uint8_t * input_buffer, size
readColorTransformations(conversionInput);
//read calibration tables and store them in m_CalibCurves
-
- readCalibrationTables(conversionInput);
+ int n_inputliquids = conversionInput->inputcoordinates->n_inputliquids;
+ InputLiquid **inputliquid = conversionInput->inputcoordinates->inputliquids;
+ readCalibrationTables(inputliquid, n_inputliquids);
//Initialize CIECAM02 transformation
Illum IL = D65;
@@ -2495,7 +2544,7 @@ size_t Tango::ColorLib::ColorConverter::P_IsInGamut(uint8_t * input_buffer, size
SetNumberOfInks(m_nB2AnSepOut);
// Compare Strip White point to Color Table White Point
- CompareWhitePoints();
+ //CompareWhitePoints();
if (numofInks != m_nB2AnSepOut)
throw std::exception("Number of available inks does not match ink tables");
@@ -2561,19 +2610,22 @@ size_t Tango::ColorLib::ColorConverter::P_IsInGamut(uint8_t * input_buffer, size
LabIn[2] = conversionInput->inputcoordinates->b;
//the assumption is that the color space has illumination that matches the whitepoint of the Strip
ColorConvert CConvertD65(D65, D65); //Destination, source
- double *LabInFinal1 = new double[3];
+// double *LabInFinal1 = new double[3];
//double *LabInFinal1 = DBG_NEW double[3];
- for (int i = 0; i < 3; ++i)
- LabInFinal1[i] = LabIn[i];
+// for (int i = 0; i < 3; ++i)
+// LabInFinal1[i] = LabIn[i];
// Lab is assumed to match the color of the STRIP, however the tables could have a different WP
- //Check if Color Tables and Strip whitepoints are the same, otherwise convert
+ //We relate to the color table as a generic one in Relative Colorimetric Space
+ /*
if (m_AdaptWP)
{
CConvertD65.ChangeWP(LabInFinal1, LabInFinal1, m_whitepointXYZ_CT, m_whitepointXYZ_Strip); //to Color Tables
}
+ */
double *LabInFinal2 = new double[3];
//double *LabInFinal2 = DBG_NEW double[3];
- CConvertD65.ChangeWP(LabIn, LabInFinal2, m_WP, m_whitepointXYZ_CT); //to Relative
+ // CConvertD65.ChangeWP(LabIn, LabInFinal2, m_WP, m_whitepointXYZ_CT); //to Relative
+ CConvertD65.ChangeWP(LabIn, LabInFinal2, m_WP, m_whitepointXYZ_Strip); //to Relative
InGamut = IsInGamut(LabInFinal2, sur, CS, LabInFinal2);
LimitLab(LabInFinal2);
@@ -2582,11 +2634,11 @@ size_t Tango::ColorLib::ColorConverter::P_IsInGamut(uint8_t * input_buffer, size
delete[] LabIn;
LabIn = NULL;
}
- if (LabInFinal1 != NULL)
+ /* if (LabInFinal1 != NULL)
{
delete[]LabInFinal1;
LabInFinal1 = NULL;
- }
+ } */
if (LabInFinal2 != NULL)
{
delete[]LabInFinal2;
@@ -2651,16 +2703,20 @@ size_t Tango::ColorLib::ColorConverter::P_IsInGamut(uint8_t * input_buffer, size
size_t Tango::ColorLib::ColorConverter::GenerateGradient(uint8_t * input_buffer, size_t input_buffer_size, uint8_t *& output_buffer)
{
-
//Get Input...
GradientConversionInput* conversionInput = (GradientConversionInput*)malloc(sizeof(GradientConversionInput));
conversionInput = gradient_conversion_input__unpack(NULL, input_buffer_size, input_buffer);
+ //Initialize Output...
+ GradientConversionOutput *conversionOutput = (GradientConversionOutput*)malloc(sizeof(GradientConversionOutput));
+ gradient_conversion_output__init(conversionOutput);
+ conversionOutput->haserror = false;
+ conversionOutput->has_haserror = false;
//Get segment length...
double segmentLength = conversionInput->segmentlength;
-
+ PrepareGradient(conversionInput, conversionOutput);
//Get liquid types info...
- InputLiquid* cyan = NULL;
+/* InputLiquid* cyan = NULL;
InputLiquid* magenta = NULL;
InputLiquid* yellow = NULL;
InputLiquid* black = NULL;
@@ -2682,137 +2738,762 @@ size_t Tango::ColorLib::ColorConverter::GenerateGradient(uint8_t * input_buffer,
black = conversionInput->inputliquids[i];
break;
}
- }
+ }*/
- //Iterate over input stops...
- for (size_t i = 0; i < conversionInput->n_stops; i++)
- {
- GradientInputStop* stop = conversionInput->stops[i];
- stop->colorspace; //Stop color space.
- stop->offset; // Stop offset within the segment length (0-1)
+ //Pack output...
+ output_buffer = (uint8_t*)malloc(gradient_conversion_output__get_packed_size(conversionOutput));
+ int size = gradient_conversion_output__pack(conversionOutput, output_buffer);
+
+ //RELEASE MEMORY HERE !!!
+#pragma region Free Conversion Input & Output
+
+ gradient_conversion_input__free_unpacked(conversionInput, NULL);
+
+ gradient_conversion_output__free_unpacked(conversionOutput, NULL);
- switch (stop->colorspace)
+#pragma endregion
+
+ return size;
+}
+
+void Tango::ColorLib::ColorConverter::fillGradientStops(GradientConversionInput *conversionInput)
+{
+ for (int i = 0; i < m_nGradStops; ++i)
+ {
+ switch (conversionInput->stops[i]->colorspace)
{
case COLOR_SPACE__RGB: //Case RGB
- stop->red;
- stop->green;
- stop->blue;
+ m_GradStops[i].RGB.Set(conversionInput->stops[i]->red, conversionInput->stops[i]->green, conversionInput->stops[i]->blue);
+ m_GradStops[i].colorspace = COLOR_SPACE__RGB;
+ m_GradStops[i].offset = conversionInput->stops[i]->offset;
break;
case COLOR_SPACE__LAB: //Case LAB
- stop->l;
- stop->a;
- stop->b;
+ m_GradStops[i].Lab.Set(conversionInput->stops[i]->l, conversionInput->stops[i]->a, conversionInput->stops[i]->b);
+ m_GradStops[i].colorspace = COLOR_SPACE__LAB;
+ m_GradStops[i].offset = conversionInput->stops[i]->offset;
break;
case COLOR_SPACE__Volume: //Case Volume
-
- double cyanVolume = 0;
- double magentaVolume = 0;
- double yellowVolume = 0;
- double blackVolume = 0;
-
- for (size_t j = 0; j < stop->n_liquidvolumes; j++)
+ m_GradStops[i].colorspace = COLOR_SPACE__Volume;
+ m_GradStops[i].offset = conversionInput->stops[i]->offset;
+ for (int j = 0; j < (int)conversionInput->stops[i]->n_liquidvolumes; j++)
{
- LiquidVolume* liquidVolume = stop->liquidvolumes[j];
+ LiquidVolume* liquidVolume = conversionInput->stops[i]->liquidvolumes[j];
switch (liquidVolume->liquidtype)
{
case LIQUID_TYPE__Cyan:
- cyanVolume = liquidVolume->volume;
+ m_GradStops[i].Volume[0] = liquidVolume->volume;
+ break;
case LIQUID_TYPE__Magenta:
- magentaVolume = liquidVolume->volume;
+ m_GradStops[i].Volume[1] = liquidVolume->volume;
+ break;
case LIQUID_TYPE__Yellow:
- yellowVolume = liquidVolume->volume;
+ m_GradStops[i].Volume[2] = liquidVolume->volume;
+ break;
case LIQUID_TYPE__Black:
- blackVolume = liquidVolume->volume;
+ m_GradStops[i].Volume[3] = liquidVolume->volume;
+ break;
+ default:
+ throw std::exception("could not fill all volumes");
}
}
-
break;
}
}
+}
- //Initialize Output...
- GradientConversionOutput *conversionOutput = (GradientConversionOutput*)malloc(sizeof(GradientConversionOutput));
- gradient_conversion_output__init(conversionOutput);
- int stops_count = 100;
+void Tango::ColorLib::ColorConverter::findStops(GradStruct m_GradStop1, GradStruct m_GradStop2, double dEThr, int ninterstops,
+ int &nOut, double **VecRGBOut, double **VecLabOut, double *posOut)
+{
+ ColorConvert CConvertD65(D65, D65);
+ C_RGB_XYZ_Lab RGBStart = m_GradStop1.RGB;
+ C_RGB_XYZ_Lab RGBEnd = m_GradStop2.RGB;
+ C_RGB_XYZ_Lab LowLab(0, -128, -128);
+ C_RGB_XYZ_Lab HighLab(100, 127, 127);
+ C_RGB_XYZ_Lab LowRGB(0, 0, 0);
+ C_RGB_XYZ_Lab HighRGB(255, 255, 255);
+
+ int nsubdiv = 100;
+ C_RGB_XYZ_Lab dRGB((RGBEnd.Get_x() - RGBStart.Get_x()) / nsubdiv, (RGBEnd.Get_y() - RGBStart.Get_y()) / nsubdiv,
+ (RGBEnd.Get_z() - RGBStart.Get_z()) / nsubdiv);
+
+
+ C_RGB_XYZ_Lab *VecLabOut_tmp = new C_RGB_XYZ_Lab[ninterstops];
+ C_RGB_XYZ_Lab *VecRGBOut_tmp = new C_RGB_XYZ_Lab[ninterstops];
+ C_RGB_XYZ_Lab *VecLabOut_fin = new C_RGB_XYZ_Lab[ninterstops];
+ C_RGB_XYZ_Lab *VecRGBOut_fin = new C_RGB_XYZ_Lab[ninterstops];
+ C_RGB_XYZ_Lab RGBTmp;
+ C_RGB_XYZ_Lab LabTmp;
+ // make a vector of RGB values with 100 subdivisions
+ // make a matching Lab vector;
+
+ VecRGBOut_tmp[0] = C_RGB_XYZ_Lab(RGBStart);
+ VecLabOut_tmp[0] = C_RGB_XYZ_Lab(m_GradStop1.Lab);
+
+ for (int i = 1; i <= nsubdiv; ++i)
+ {
+ VecRGBOut_tmp[i].Set(VecRGBOut_tmp[i - 1].Get_x() + dRGB.Get_x(),
+ VecRGBOut_tmp[i - 1].Get_y() + dRGB.Get_y(),
+ VecRGBOut_tmp[i - 1].Get_z() + dRGB.Get_z());
+ VecLabOut_tmp[i] = CConvertD65.RGBtoLab(VecRGBOut_tmp[i]);
+ VecLabOut_tmp[i].Clamp(LowLab, HighLab);
+ }
+
+ int indGrad = 0;
+ int *pos = new int[ninterstops];
+ int i1 = 1;
+ int j1 = 1;
+ VecLabOut_fin[indGrad] = VecLabOut_tmp[0];
+ VecRGBOut_fin[indGrad] = VecRGBOut_tmp[0];
+ pos[indGrad] = 0;
+ double dE = 0.0;
+ double dEOld = 0.0;
+ while (i1 <= nsubdiv)
+ {
+ dEOld = dE;
+ CConvertD65.dEcmc(VecLabOut_fin[indGrad], VecLabOut_tmp[i1], dE);
+ j1 = i1;
+ while (dE < dEThr && i1 < nsubdiv && j1 < nsubdiv)
+ {
+ j1++;
+ dEOld = dE;
+ CConvertD65.dEcmc(VecLabOut_fin[indGrad], VecLabOut_tmp[j1], dE);
+ }
+ if (j1 > i1)
+ {
+ j1--;
+ indGrad++;
+ VecRGBOut_fin[indGrad] = VecRGBOut_tmp[j1];
+ VecLabOut_fin[indGrad] = VecLabOut_tmp[j1];
+ pos[indGrad] = j1;
+ dE = dEOld;
+ i1 = j1 + 1;
+ }
+ else
+ {
+ dEOld = dE;
+ while (dE >= dEThr && i1 <= nsubdiv)
+ {
+ //get intermediate point
+ RGBTmp = VecRGBOut_tmp[i1];
+ LabTmp = CConvertD65.RGBtoLab(RGBTmp);
+ LabTmp.Clamp(LowLab, HighLab);
+ //move vectors down by one
+ for (int i = i1; i < nsubdiv; ++i)
+ {
+ VecRGBOut_tmp[i + 1] = VecRGBOut_tmp[i + 1];
+ VecLabOut_tmp[i + 1] = VecLabOut_tmp[i + 1];
+ }
+ VecRGBOut_tmp[i1] = RGBTmp;
+ VecLabOut_tmp[i1] = LabTmp;
+ CConvertD65.dEcmc(VecLabOut_fin[indGrad], VecLabOut_tmp[i1], dE);
+ nsubdiv++;
+ }
+ indGrad++;
+ VecRGBOut_fin[indGrad] = VecRGBOut_tmp[j1];
+ VecLabOut_fin[indGrad] = VecLabOut_tmp[j1];
+ pos[indGrad] = j1;
+ i1 = j1 + 1;
+ }
+ }
+ nOut = indGrad;
+
+ for (int i = 0; i < nOut; ++i)
+ {
+ VecLabOut[i][0] = VecLabOut_fin[i].Get_x();
+ VecLabOut[i][1] = VecLabOut_fin[i].Get_y();
+ VecLabOut[i][2] = VecLabOut_fin[i].Get_z();
+ VecRGBOut[i][0] = VecRGBOut_fin[i].Get_x();
+ VecRGBOut[i][1] = VecRGBOut_fin[i].Get_y();
+ VecRGBOut[i][2] = VecRGBOut_fin[i].Get_z();
+ posOut[i] = pos[i];
+ }
+ //free allocs
+ if(VecLabOut_tmp != NULL)
+ {
+ delete[] VecLabOut_tmp;
+ VecLabOut_tmp = NULL;
+ }
+ if (VecRGBOut_tmp != NULL)
+ {
+ delete[] VecRGBOut_tmp;
+ VecRGBOut_tmp = NULL;
+ }
+ if (VecLabOut_fin != NULL)
+ {
+ delete[] VecLabOut_fin;
+ VecLabOut_fin = NULL;
+ }
+ if (VecRGBOut_fin != NULL)
+ {
+ delete[] VecRGBOut_fin;
+ VecRGBOut_fin = NULL;
+ }
+ if (pos != NULL)
+ {
+ delete[] pos;
+ pos = NULL;
+ }
+}
+
+void Tango::ColorLib::ColorConverter::ConvertGradStoptoVolume(InputCoordinates* inputcoordinates, ColorSpace colorspace,
+ VectorXd &Volume, int &GamutRegion)
+{
+ size_t nInks = 0;
+
+ C_RGB_XYZ_Lab DataLab;
+ VectorXd InkOut(m_nB2AnSepOut);
+ if (colorspace ==COLOR_SPACE__RGB)
+ {
+ //Convert RGB to Volume, no nee to calculate RGBOut and LabOut
+ // Basic assumption: if data is given in RGB space, conversion should be in relative colorimetric,
+ //We expect that [255,255,255](white) will be mapped to the thread white, meaning all inks should be zero
+ // and the coverted RGB will refect the color of the thread, but will be shown in Relative Colorimetric to the user
+
+ //convert to Lab
+ ColorConvert CConvertD65(D65, D65); //Destination, source
+ double *LabIn = new double[3];
+ double *RGBOutP = new double[3];
+ RGBOutP[0] = inputcoordinates->red;
+ RGBOutP[1] = inputcoordinates->green;
+ RGBOutP[2] = inputcoordinates->blue;
+ //RGB to Lab
+ CConvertD65.RGBtoLab(RGBOutP, LabIn); //Values are in Relative Colorimetric, D65
+ LimitLab(LabIn);
+
+ //convert to inks
+ int GamutRegion;
+ double *InkOutP = new double[m_nB2AnSepOut];
+ m_B2ATransform->evalLab2InkP(LabIn, InkOutP, GamutRegion); //InkOut is in units of 16 bits
+
+ //Convert InkOut to Linear via initial calibration Tables
+ //Initial calibration tables are the ones that were included in the color table
+ for (int i = 0; i < m_nB2AnSepOut; ++i)
+ {
+ InkOutP[i] *= m_NormFactor;
+ if (InkOutP[i] <= m_GamutRegionMaxLim[0])
+ {
+ m_LinCurves->m_InterpCurves[i].Eval(InkOutP[i] * 655.35, InkOutP[i]);
+ InkOutP[i] /= 655.35;
+ }
+ }
+ InkOut = DoubleToVector(InkOutP, m_nInks);
+
+ if (InkOutP != NULL)
+ {
+ delete[] InkOutP;
+ InkOutP = NULL;
+ }
+ if (LabIn != NULL)
+ {
+ delete[] LabIn;
+ LabIn = NULL;
+ }
+ if (RGBOutP != NULL)
+ {
+ delete[] RGBOutP;
+ RGBOutP = NULL;
+ }
+ }
+ else if(colorspace ==COLOR_SPACE__LAB)
+ {
+ // Basic assumption: Lab data is in relative colorimetric. No Need to convert
+
+ double *LabIn = new double[3];
+ LabIn[0] = inputcoordinates->l; //Relative Colorimetric
+ LabIn[1] = inputcoordinates->a;
+ LabIn[2] = inputcoordinates->b;
- //Init output stops array...
- GradientOutputStop** outputStops = (GradientOutputStop**)malloc(sizeof(GradientOutputStop*) * stops_count);
+ //convert to Inks
+ int GamutRegion;
+ double *InkOutP = new double[m_nB2AnSepOut];
+ m_B2ATransform->evalLab2InkP(LabIn, InkOutP, GamutRegion); //InkOut is in the [0-100] interval
+ for (int i = 0; i < m_nB2AnSepOut; ++i)
+ {
+ InkOutP[i] *= m_NormFactor;
+ if (InkOutP[i] <= m_GamutRegionMaxLim[0])
+ {
+ m_LinCurves->m_InterpCurves[i].Eval(InkOutP[i] * 655.35, InkOutP[i]);
+ InkOutP[i] /= 655.35;
+ }
+ }
+ InkOut = DoubleToVector(InkOutP, m_nInks);
- conversionOutput->stops = outputStops;
- conversionOutput->n_stops = stops_count;
+ if (InkOutP != NULL)
+ {
+ delete[] InkOutP;
+ InkOutP = NULL;
+ }
+ if (LabIn != NULL)
+ {
+ delete[] LabIn;
+ LabIn = NULL;
+ }
+ }
+ else
+ {
+ throw std::exception("Unsupported Color Space");
+ return;
+ }
+ VectorXd NLInkOut(m_nB2AnSepOut);
+ VectorXd VolumeOut(m_nB2AnSepOut);
+ double *InkOutL = new double[m_nB2AnSepOut];
+ ConvertToNLInks(InkOut, NLInkOut);
+ LimitInks(NLInkOut, InkOutL);
+ NLInkPToVolume(DoubleToVector(InkOutL, m_nInks), Volume);
+ GamutRegion = GetGamutRegion(Volume, m_ProcessRangesMaxP);
+ NLcmtoPercentage(Volume, Volume);
+ if (InkOutL != NULL)
+ {
+ delete[] InkOutL;
+ InkOutL = NULL;
+ }
- double fake_volume = 1;
+ return;
+}
+
+void Tango::ColorLib::ColorConverter::SetNormFactor()
+{
+ m_NormFactor = m_GamutRegionMaxLim[m_nProcessRanges - 1] / m_GamutRegionMaxLim[0];
+}
- //Put Demo Stops...
- for (size_t i = 0; i < stops_count; i++)
+void Tango::ColorLib::ColorConverter::SetInverseNormFactor()
+{
+ if (m_NormFactor <= 0)
+ m_InvNormFactor = -1;
+ else
+ m_InvNormFactor = 1.0 / m_NormFactor;
+}
+
+void Tango::ColorLib::ColorConverter::PrepareGradient(GradientConversionInput* conversionInput, GradientConversionOutput *conversionOutput)
+{
+ //fill input stops...
+ m_nGradStops = conversionInput->n_stops;
+ m_GradStops = new GradStruct[m_nGradStops];
+ InputCoordinates **inputcoordinates = (InputCoordinates**)malloc(sizeof(InputCoordinates*)*m_nGradStops);
+ double *InkOutL = new double[m_nB2AnSepOut];
+ for (int i = 0; i < m_nGradStops; ++i)
{
- GradientOutputStop *stop = (GradientOutputStop*)malloc(sizeof(GradientOutputStop));
- gradient_output_stop__init(stop);
+ inputcoordinates[i] = (InputCoordinates*)malloc(sizeof(InputCoordinates));
+ input_coordinates__init(inputcoordinates[i]);
+ }
+ m_nVolumes = conversionInput->stops[0]->n_liquidvolumes;
+ fillGradientStops(conversionInput);
+ GradInput2InputCoords(conversionInput, inputcoordinates);
- stop->processparameterstableindex = 0; //Set process parameters table index (0,1).
- stop->offset = (double)i / (double)stops_count;
+ //Global Parameters of gradient
+ SetStripWhitepoint(conversionInput->threadl, conversionInput->threada, conversionInput->threadb);
+ bool has_forwarddata = conversionInput->has_forwarddata;
+ uint8_t *data = conversionInput->forwarddata.data;
+ int nprocessranges = conversionInput->n_processranges;
+ readColorTables(has_forwarddata, data, nprocessranges);
- //Init stop output liquids
- OutputLiquid** outputLiquids = (OutputLiquid**)malloc(sizeof(OutputLiquid*) * 4);
+ int n_inputliquids = conversionInput->n_inputliquids;
+ InputLiquid **inputliquid = conversionInput->inputliquids;
+ readCalibrationTables(inputliquid, n_inputliquids);
- //Init cyan.
- OutputLiquid* c = (OutputLiquid*)malloc(sizeof(OutputLiquid));
- output_liquid__init(c);
- c->has_liquidtype = true;
- c->has_volume = true;
- c->liquidtype = LIQUID_TYPE__Cyan;
- c->volume = fake_volume++;
- outputLiquids[0] = c;
+ //finished reading tables and data
+ //prepare data to construct the gradient
+ //gradient is calculated in RGB space, thinned out or expanded based on dE criteria
+ // returns a vector of volumes and offsets
+ //gradient stops in different gamut region will use regular transformation
+ //if all stops in gamut region 0 the color Table will be suited to this gamut region
- //Init magenta.
- OutputLiquid* m = (OutputLiquid*)malloc(sizeof(OutputLiquid));
- output_liquid__init(m);
- m->has_liquidtype = true;
- m->has_volume = true;
- m->liquidtype = LIQUID_TYPE__Magenta;
- m->volume = fake_volume++;
- outputLiquids[1] = m;
+ //prepare input
+ //if Color Space = lab, fill rgb and calculate volume + volume region
+ //if color space = rgb, fill lab and calculate volue + volume region
+ //if color space = Volume, fill lab and RGB, calculate volume region
- //Init yellow.
- OutputLiquid* y = (OutputLiquid*)malloc(sizeof(OutputLiquid));
- output_liquid__init(y);
- y->has_liquidtype = true;
- y->has_volume = true;
- y->liquidtype = LIQUID_TYPE__Yellow;
- y->volume = fake_volume++;
- outputLiquids[2] = y;
+ bool InGamut = false;
+ m_WP.Set(0.9505, 1.00, 1.0888); //D65
+ //Initialize CIECAM02 transformation
+ Illum IL = D65;
+ SURROUND sur = average;
+ CAM02CS CS = UCS;
+ m_Conv02 = new ColorConvert(IL, IL, Y_b, L_A, sur, CS);
+ SetnA2BnSepIn(m_A2BTransform->GetSeparationsIn());
+ SetnA2BnSepOut(m_A2BTransform->GetSeparationsOut());
+ SetnB2AnSepIn(m_B2ATransform->GetSeparationsIn());
+ SetnB2AnSepOut(m_B2ATransform->GetSeparationsOut());
+ SetNumberOfInks(m_nB2AnSepOut);
+ // Compare Strip White point to Color Table White Point
+ //CompareWhitePoints();
+ ColorConvert CConvertD65(D65, D65); //Destination, source
+ if (n_inputliquids != m_nInks)
+ throw std::exception("Number of available inks does not match ink tables\0");
- //Init black.
- OutputLiquid* k = (OutputLiquid*)malloc(sizeof(OutputLiquid));
- output_liquid__init(k);
- k->has_liquidtype = true;
- k->has_volume = true;
- k->liquidtype = LIQUID_TYPE__Black;
- k->volume = fake_volume++;
- outputLiquids[3] = k;
+ //Convert maxInkUptake to percentages
+ NormGamutRegionMaxLim();
+ if (m_NormFactor <= 0.0)
+ {
+ SetNormFactor();
+ SetInverseNormFactor();
+ }
+ VectorXd InkOut(m_nB2AnSepOut);
+ VectorXd RGBOut(3);
+ VectorXd LabOut(3);
+ VectorXd NLInkOut(m_nB2AnSepOut);
+ VectorXd Volume(m_nB2AnSepOut);
+ VectorXd VolumeOut(m_nB2AnSepOut);
+ //set maxNlPerCM
+ VectorXd NlperCM(m_nB2AnSepOut);
+ double *LabOutV = new double[3];
+ double *LabOutFinal = new double[3];
+ NlperCM.setZero();
+ m_maxNlPerCM = NlperCM;
+ for (int i = 0; i < m_nB2AnSepOut; ++i)
+ SetMaxNLperCM(conversionInput->inputliquids[i]->maxnanoliterpercentimeter, i);
+ m_nVolumes = m_nB2AnSepOut;
+ int GamutRegion = 0;
+ for (int i = 0; i < m_nGradStops; ++i)
+ {
+ if (m_GradStops[i].colorspace == COLOR_SPACE__Volume || m_GradStops[i].colorspace == COLOR_SPACE__Catalog)
+ { //Convert volume to Lab
+ //Convert lab to rgb
+ ConvertVolumeToRGBDisplay(inputcoordinates[i], m_nProcessRanges, m_GradStops[i].colorspace, Volume, RGBOut, LabOut, GamutRegion);
+ //store data
+ m_GradStops[i].Lab.Set(LabOut(0), LabOut(1), LabOut(2));
+ m_GradStops[i].RGB.Set(RGBOut(0), RGBOut(1), RGBOut(2));
+ m_GradStops[i].GamutRegion = GamutRegion;
+ m_GradStops[i].InGamut = true;
+ }
+ else
+ {
+ ConvertColorToLinearInks(inputcoordinates[i], m_GradStops[i].colorspace, InkOut, RGBOut, LabOut, GamutRegion, InGamut);
+ //Inks are in Linear Space , convert to nonlinear by using Calibration Tables,
+ // Right now calibration is in the [0-100] range, values exceeding [0-100] are not transformed
- stop->outputliquids = outputLiquids;
- stop->n_outputliquids = 4;
+ ConvertToNLInks(InkOut, NLInkOut);
+ LimitInks(NLInkOut, InkOutL);
+ NLInkPToVolume(DoubleToVector(InkOutL, m_nInks), Volume);
+ GamutRegion = GetGamutRegion(Volume, m_ProcessRangesMaxP);
+ NLcmtoPercentage(Volume, Volume);
+
+ //fill data
+ //fill volume
+ //allocate m_GradStops[i].Volume
+ m_GradStops[i].Volume = new double[m_nB2AnSepOut];
+ for (int j = 0; j < m_nB2AnSepOut; ++j)
+ m_GradStops[i].Volume[j] = Volume[j];
+ m_GradStops[i].GamutRegion = GamutRegion;
+ m_GradStops[i].InGamut = InGamut;
+ //LabOut and RGBOut might be different if the input was out of gamut
+ m_GradStops[i].Lab.Set(LabOut(0), LabOut(1), LabOut(2));
+ m_GradStops[i].RGB.Set(RGBOut(0), RGBOut(1), RGBOut(2));
+ }
+ //Convert Lab Values to Relative Colorimetric. These values will be used in the Gradient Volume calculation.
+ VectorToDouble(LabOut, LabOutV);
+/* if (m_AdaptWP)
+ {
+ CConvertD65.ChangeWP(LabOutV, LabOutV, m_whitepointXYZ_CT, m_whitepointXYZ_Strip); //to Color Tables
+ }
+ */
+ //double *LabInFinal2 = DBG_NEW double[3];
+// CConvertD65.ChangeWP(LabOutV, LabOutFinal, m_WP, m_whitepointXYZ_CT); //LabInFinal is in Relative Colorimetric Space
+ CConvertD65.ChangeWP(LabOutV, LabOutFinal, m_WP, m_whitepointXYZ_Strip); //LabInFinal is in Relative Colorimetric Space
+ m_GradStops[i].Lab.Set(LabOutFinal[0], LabOutFinal[1], LabOutFinal[2]);
+ }
+ //free vectors
+ if (LabOutV == NULL)
+ {
+ delete[] LabOutV;
+ LabOutV = NULL;
+ }
+ if (LabOutFinal == NULL)
+ {
+ delete[] LabOutFinal;
+ LabOutFinal = NULL;
+ }
+ if (InkOutL == NULL)
+ {
+ delete[] InkOutL;
+ InkOutL = NULL;
+ }
- outputStops[i] = stop;
+ //are all stops in the same region?
+ int maxreg = -10;
+ int minreg = 10;
+ for (int i = 0; i < m_nGradStops; ++i)
+ {
+ maxreg = std::max(maxreg, m_GradStops[i].GamutRegion);
+ minreg = std::min(minreg, m_GradStops[i].GamutRegion);
+ }
+ bool same_regions = true;
+ if (maxreg != minreg)
+ same_regions = false;
+ double dEThr = 0.8;
+ //find intermediate points
+ int ninterstops = 300;
+ double **VecRGBOut = new double*[ninterstops];
+ double **VecLabOut = new double*[ninterstops];
+ double *posOut = new double[ninterstops];
+ for (int i = 0; i < ninterstops; ++i)
+ {
+ VecLabOut[i] = new double[3];
+ VecRGBOut[i] = new double[3];
}
+ int nOut = 0;
+ int nmaxstops = ninterstops * m_nGradStops;
- //Pack output...
- output_buffer = (uint8_t*)malloc(gradient_conversion_output__get_packed_size(conversionOutput));
- int size = gradient_conversion_output__pack(conversionOutput, output_buffer);
+ //Allocate temporary storage for all stops and positions
+ double **AllRGBOut_tmp = new double*[nmaxstops];
+ double **AllLabOut_tmp = new double*[nmaxstops];
+ double *AllPos_tmp = new double[nmaxstops];
+ for (int i = 0; i < nmaxstops; ++i)
+ {
+ AllRGBOut_tmp[i] = new double[3];
+ AllLabOut_tmp[i] = new double[3];
+ }
+ AllRGBOut_tmp[0][0] = m_GradStops[0].RGB.Get_x();
+ AllRGBOut_tmp[0][1] = m_GradStops[0].RGB.Get_y();
+ AllRGBOut_tmp[0][2] = m_GradStops[0].RGB.Get_z();
+ AllLabOut_tmp[0][0] = m_GradStops[0].Lab.Get_x();
+ AllLabOut_tmp[0][1] = m_GradStops[0].Lab.Get_y();
+ AllLabOut_tmp[0][2] = m_GradStops[0].Lab.Get_z();
+ AllPos_tmp[0] = m_GradStops[0].offset;
+ int ncountStops = 0;
+ int nPosStops = 0;
+ double dOffset = 0;
+ GradOffset OffsetType = EqSpaced;
+ for (int i = 0; i < m_nGradStops - 1; ++i)
+ {
+ findStops(m_GradStops[i], m_GradStops[i + 1], dEThr, ninterstops, nOut, VecRGBOut, VecLabOut, posOut);
+ if (i == m_nGradStops - 2)
+ dOffset = (m_GradStops[i + 1].offset - m_GradStops[i].offset)*GradientEndThr / (nOut - 1);
+ else
+ dOffset = (m_GradStops[i + 1].offset - m_GradStops[i].offset) / (nOut - 1);
- //RELEASE MEMORY HERE !!!
+ switch (OffsetType)
+ {
+ case EqSpaced:
+ for (int j = 1; j < nOut; ++j)
+ {
+ nPosStops++;
+ AllPos_tmp[nPosStops] = m_GradStops[i].offset + dOffset * posOut[j];
+ }
+ break;
+ case dESpaced:
+ for (int j = 0; j < nOut; ++j)
+ {
+ nPosStops++;
+ AllPos_tmp[nPosStops] = m_GradStops[i].offset + dOffset * j;
+ }
+ break;
+ }
+ //store the stops in temporary vector
+ for (int i = 1; i < nOut; ++i)
+ {
+ ncountStops++;
+ for (int j = 0; j < 3; ++j)
+ {
+ AllRGBOut_tmp[ncountStops][j] = VecRGBOut[i][j];
+ AllLabOut_tmp[ncountStops][j] = VecLabOut[i][j];
+ }
+ }
+ }
-#pragma region Free Conversion Input & Output
-
- gradient_conversion_input__free_unpacked(conversionInput, NULL);
+ if (VecRGBOut != NULL)
+ {
+ for (int i = 0; i < nOut; ++i)
+ delete[]VecRGBOut[i];
+ delete[]VecRGBOut;
+ }
+ if (VecLabOut != NULL)
+ {
+ for (int i = 0; i < nOut; ++i)
+ delete[]VecLabOut[i];
+ delete[]VecLabOut;
+ VecLabOut = NULL;
+ }
+ if (VecLabOut != NULL)
+ {
+ delete[]posOut;
+ posOut = NULL;
+ }
- gradient_conversion_output__free_unpacked(conversionOutput, NULL);
+ //Store Gradient intermediate data in Input Coordinates type structure.
+ //Simplify calculations, we only need the ink values, input values are in RGB color space
+ // Use table according to Gamut Regions, all stops in region 0, use 100%table otherwise use regular table, decrease dyeing speed.
-#pragma endregion
+ int nTotalStops = ncountStops;
+ InputCoordinates **SubStops = (InputCoordinates**)malloc(sizeof(InputCoordinates*)*nTotalStops);
- return size;
+ //Calculate and store
+ for (int i = 0; i < nTotalStops; ++i)
+ {
+ SubStops[i] = (InputCoordinates*)malloc(sizeof(InputCoordinates));
+ input_coordinates__init(SubStops[i]);
+ SubStops[i]->l = AllLabOut_tmp[i][0];
+ SubStops[i]->a = AllLabOut_tmp[i][1];
+ SubStops[i]->b = AllLabOut_tmp[i][2];
+ SubStops[i]->red = (int)round(AllRGBOut_tmp[i][0]);
+ SubStops[i]->green = (int)round(AllRGBOut_tmp[i][1]);
+ SubStops[i]->blue = (int)round(AllRGBOut_tmp[i][2]);
+ }
+
+GradientOutputStop** outputStops = (GradientOutputStop**)malloc(sizeof(GradientOutputStop*) * nTotalStops);
+conversionOutput->stops = outputStops;
+conversionOutput->n_stops = nTotalStops;
+
+ColorSpace SubStopsCS = COLOR_SPACE__LAB;
+//double NormFactor = m_ProcessRangesMaxP[m_nProcessRanges - 1] / 100.0;
+VectorXd VolumeStop(m_nB2AnSepOut);
+for (int i = 0; i < ncountStops; ++i)
+{
+ GradientOutputStop *stop = (GradientOutputStop*)malloc(sizeof(GradientOutputStop));
+ gradient_output_stop__init(stop);
+ ConvertGradStoptoVolume(SubStops[i], SubStopsCS,
+ VolumeStop, GamutRegion);
+ //start filling Output
+ fillStop(stop, VolumeStop, GamutRegion, AllPos_tmp[i]);
+ outputStops[i] = stop;
}
+//release memory
+if(AllLabOut_tmp != NULL)
+{
+ for (int i = 0; i < nmaxstops; ++i)
+ delete[] AllLabOut_tmp[i];
+ delete[] AllLabOut_tmp;
+ AllLabOut_tmp = NULL;
+}
+if (AllRGBOut_tmp != NULL)
+{
+ for (int i = 0; i < nmaxstops; ++i)
+ delete[] AllRGBOut_tmp[i];
+ delete[] AllRGBOut_tmp;
+ AllRGBOut_tmp = NULL;
+}
+if (AllPos_tmp != NULL)
+{
+ delete[] AllPos_tmp;
+ AllPos_tmp = NULL;
+}
+
+
+for (int i=0; i< m_nGradStops; ++i)
+ input_coordinates__free_unpacked(inputcoordinates[i], NULL);
+free(inputcoordinates);
+inputcoordinates = NULL;
+for (int i = 0; i < nTotalStops; ++i)
+ input_coordinates__free_unpacked(SubStops[i], NULL);
+free(SubStops);
+SubStops = NULL;
+
+}
+
+void Tango::ColorLib::ColorConverter::NormGamutRegionMaxLim()
+{
+ double GamutRegionMaxLim0 = m_GamutRegionMaxLim[0];
+ for (int i = 0; i < m_nProcessRanges; ++i)
+ m_GamutRegionMaxLim[i] = 100 * m_GamutRegionMaxLim[i] / GamutRegionMaxLim0;
+}
+
+void Tango::ColorLib::ColorConverter::fillStop(GradientOutputStop *&stop, VectorXd Volume, int GamutRegion, double Position)
+{
+ OutputLiquid** outputLiquids = (OutputLiquid**)malloc(sizeof(OutputLiquid*) * m_nVolumes);
+ for (int i = 0; i < m_nVolumes; ++i)
+ {
+ outputLiquids[i] = (OutputLiquid*)malloc(sizeof(OutputLiquid));
+ output_liquid__init(outputLiquids[i]);
+ switch (m_CalibCurves[i].getInkName())
+ {
+ case LIQUID_TYPE__Cyan:
+ case LIQUID_TYPE__Magenta:
+ case LIQUID_TYPE__Yellow:
+ case LIQUID_TYPE__Black:
+ {
+ outputLiquids[i]->has_volume = true;
+ outputLiquids[i]->has_liquidtype = true;
+ outputLiquids[i]->liquidtype = (LiquidType)(m_CalibCurves[i].getInkName());
+ outputLiquids[i]->volume = Volume(i);
+ break;
+ }
+ default:
+ throw std::exception("could not fill all volumes");
+ }
+ }
+ stop->outputliquids = outputLiquids;
+ stop->n_outputliquids = m_nVolumes;
+ stop->has_processparameterstableindex = true;
+ stop->processparameterstableindex = GamutRegion;
+ stop->has_offset = true;
+ stop->offset = Position;
+}
+
+void Tango::ColorLib::ColorConverter::GradInput2InputCoords(GradientConversionInput *conversionInput, InputCoordinates **inputcoordinates)
+{
+ for (size_t i = 0; i < conversionInput->n_stops; i++)
+ {
+ switch (conversionInput->stops[i]->colorspace)
+ {
+ case COLOR_SPACE__RGB: //Case RGB
+ inputcoordinates[i]->red = conversionInput->stops[i]->red;
+ inputcoordinates[i]->green = conversionInput->stops[i]->green;
+ inputcoordinates[i]->blue = conversionInput->stops[i]->blue;
+ inputcoordinates[i]->has_red = true;
+ inputcoordinates[i]->has_green = true;
+ inputcoordinates[i]->has_blue = true;
+ break;
+ case COLOR_SPACE__LAB: //Case LAB
+ inputcoordinates[i]->l = conversionInput->stops[i]->l;
+ inputcoordinates[i]->a = conversionInput->stops[i]->a;
+ inputcoordinates[i]->b = conversionInput->stops[i]->b;
+ inputcoordinates[i]->has_l = true;
+ inputcoordinates[i]->has_a = true;
+ inputcoordinates[i]->has_b = true;
+ break;
+ case COLOR_SPACE__Volume: //Case Volume
+ for (int j = 0; j < (int)conversionInput->stops[i]->n_liquidvolumes; j++)
+ {
+ LiquidVolume* liquidVolume = conversionInput->stops[i]->liquidvolumes[j];
+
+ switch (liquidVolume->liquidtype)
+ {
+ case LIQUID_TYPE__Cyan:
+ inputcoordinates[i]->inputliquids[0]->liquidtype = LIQUID_TYPE__Cyan;
+ inputcoordinates[i]->inputliquids[0]->volume = liquidVolume->volume;
+ case LIQUID_TYPE__Magenta:
+ inputcoordinates[i]->inputliquids[1]->liquidtype = LIQUID_TYPE__Magenta;
+ inputcoordinates[i]->inputliquids[1]->volume = liquidVolume->volume;
+ case LIQUID_TYPE__Yellow:
+ inputcoordinates[i]->inputliquids[2]->liquidtype = LIQUID_TYPE__Yellow;
+ inputcoordinates[i]->inputliquids[2]->volume = liquidVolume->volume;
+ case LIQUID_TYPE__Black:
+ inputcoordinates[i]->inputliquids[3]->liquidtype = LIQUID_TYPE__Black;
+ inputcoordinates[i]->inputliquids[3]->volume = liquidVolume->volume;
+ }
+ }
+ break;
+ }
+ }
+}
+
+void Tango::ColorLib::ColorConverter::LimitInks(VectorXd inInks, double *BoundedInks)
+{
+ //convert Ink % to [nl/cm]
+ //Bound Ink
+ for (int i = 0; i < m_nInks; ++i)
+ BoundedInks[i] = std::min(inInks(i)*m_maxNlPerCM(i)/100.0, m_ProcessRangesMaxP[m_nProcessRanges - 1]);
+}
+
+void Tango::ColorLib::ColorConverter::NLcmtoPercentage(VectorXd InVolume, VectorXd &OutVolume)
+{
+ for (int i = 0; i < m_nInks; ++i)
+ OutVolume(i) =100* InVolume(i) / m_maxNlPerCM(i);
+}
+
+int Tango::ColorLib::ColorConverter::GetGamutRegion(VectorXd Volume, double *GamutLimits)
+{
+ double TotalVolume = 0.0;
+ int GamutRegion = 0;
+ for (int i = 0; i < m_nInks; ++i)
+ TotalVolume += Volume(i);
+ for (int i=0; i<m_nGamutRegions; ++i)
+ {
+ if (TotalVolume > GamutLimits[i])
+ GamutRegion++;
+ }
+ return(GamutRegion);
+} \ No newline at end of file
diff --git a/Software/Visual_Studio/ColorLib/Tango.ColorLib_v4/ColorConverter.h b/Software/Visual_Studio/ColorLib/Tango.ColorLib_v4/ColorConverter.h
index 96eeac0f9..15e8f2d04 100644
--- a/Software/Visual_Studio/ColorLib/Tango.ColorLib_v4/ColorConverter.h
+++ b/Software/Visual_Studio/ColorLib/Tango.ColorLib_v4/ColorConverter.h
@@ -11,6 +11,10 @@
#include "ConversionOutput.pb-c.h"
#include "CalibrationData.pb-c.h"
#include "ConversionInput.pb-c.h"
+#include "GradientInputStop.pb-c.h"
+#include "GradientOutputStop.pb-c.h"
+#include "GradientConversionInput.pb-c.h"
+#include "GradientConversionOutput.pb-c.h"
#include "Interp.h"
#include "Curves.h"
@@ -29,12 +33,28 @@ namespace Tango
double *GRegMaxLim;
} CT_Header;
- typedef enum {
+ typedef struct
+ {
+ C_RGB_XYZ_Lab Lab;
+ C_RGB_XYZ_Lab RGB;
+ double *Volume;
+ bool InGamut;
+ int GamutRegion;
+ double offset;
+ ColorSpace colorspace;
+ }GradStruct;
+
+ /*typedef enum {
XYZ,
Lab,
CMY,
CMYK
- }ColorSpace;
+ }ColorSpaceH;*/
+
+ typedef enum {
+ EqSpaced,
+ dESpaced
+ }GradOffset;
typedef enum {
A2B,
@@ -49,17 +69,19 @@ namespace Tango
namespace ColorLib
{
-
-
class ColorConverter
{
public:
ColorConverter();
~ColorConverter();
// size_t Convert(uint8_t * input_buffer, size_t input_buffer_size, uint8_t *& output_buffer);
- void ConvertColorToLinearInks(ConversionInput* conversionInput, VectorXd &InkOut, VectorXd &RGBOut, VectorXd &LabOut,
+ void ConvertColorToLinearInks( InputCoordinates* inputcoordinates, ColorSpace colorspace,
+ VectorXd &InkOut, VectorXd &RGBOut, VectorXd &LabOut,
int &GamutRegion, bool &InGamut);
- void ConvertVolumeToRGBDisplay(ConversionInput* conversionInput, VectorXd &InkOut, VectorXd &RGBOut,
+ void ConvertGradStoptoVolume(InputCoordinates* inputcoordinates, ColorSpace colorspace,
+ VectorXd &InkOut, int &GamutRegion);
+ void ConvertVolumeToRGBDisplay(InputCoordinates *IC, int n_processRanges,int colorspace,
+ VectorXd &InkOut, VectorXd &RGBOut,
VectorXd &LabOut, int &GamutRegion);
size_t Tango::ColorLib::ColorConverter::Convert(uint8_t * input_buffer, size_t input_buffer_size, uint8_t *& output_buffer);
size_t Tango::ColorLib::ColorConverter::GenerateGradient(uint8_t * input_buffer, size_t input_buffer_size, uint8_t *& output_buffer);
@@ -83,18 +105,22 @@ namespace Tango
C_RGB_XYZ_Lab m_whitepointXYZ_CT;
void LimitLab(double* LabIn);
int m_nGamutRegions;
+ int m_nGradStops;
+ GradStruct *m_GradStops;
double *m_GamutRegionMaxLim;
int m_nB2AnSepIn;
int m_nB2AnSepOut;
int m_nA2BnSepIn;
int m_nA2BnSepOut;
- bool m_AdaptWP;
+// bool m_AdaptWP;
CalibData *m_CalibCurves;
int m_nInks;
int m_nVolumes;
int m_nProcessRanges;
//double *m_ProcessRangesMinP;
double *m_ProcessRangesMaxP;
+ double m_NormFactor;
+ double m_InvNormFactor;
//double *m_ProcessRangesMaxInkUptake;
//double *m_ProcessRangesMinInkUptake;
C_RGB_XYZ_Lab m_WP;
@@ -105,7 +131,8 @@ namespace Tango
void SetnA2BnSepOut(int nA2BnSepOut) { m_nA2BnSepOut = nA2BnSepOut; };
void SetnGamutRegions(int nGamutRegions) { m_nGamutRegions = nGamutRegions; };
void readColorTransformations(ConversionInput* conversionInput);
- void readCalibrationTables(ConversionInput* conversionInput);
+ void readColorTables(bool has_rddata, uint8_t *data, int nprocessranges);
+ void readCalibrationTables(InputLiquid **inputliquids, int n_inputliquids);
void SetCalibData(CalibrationData* calibrationData, int i, CalibData *tmpCurve);
void SetNumberofInks(int nInks) { m_nInks = nInks; };
void SetNumberOfVolumes(int nVol) { m_nVolumes = nVol; };
@@ -114,6 +141,8 @@ namespace Tango
void fillRGB(OutputCoordinates *outputCoords, VectorXd RGBOut);
void fillLab(OutputCoordinates *outputCoords, VectorXd LabOut);
void fillVolume(OutputCoordinates *&outputCoords, VectorXd Volume);
+ void fillStop(GradientOutputStop *&stop, VectorXd Volume, int GamutRegion, double Position);
+ void fillGradientStops(GradientConversionInput *conversionInput);
void ProcessHiveNeighbors(ConversionInput *conversionInput, VectorXd LabC, VectorXd RGBC, VectorXd VolumeC,
int InGamutRegion, MatrixXd &RGBOut, MatrixXd & LabOut, MatrixXd &VolumeOut,
int nHive, int *&GamutRegion, int *indDataMax);
@@ -122,17 +151,28 @@ namespace Tango
MatrixXd &ORGBHive, MatrixXd &OVolumeHive, int *&OGamutRegion);
void FindTriplet(VectorXd Lab, MatrixXd Lab1, int nHive, int*indDataMax);
int CountNumberofInks(ConversionInput* conversionInput);
+ void SetStripWhitepoint(double threadl, double threada, double threadb);
void VectorToDouble(VectorXd Vec, double *doub);
VectorXd DoubleToVector(double *doub, int nSize);
void CompareWhitePoints();
bool IsInGamut(double *InLab, SURROUND sur, CAM02CS CS, double *LabCoord);
- CT_Header read_header(ConversionInput* conversionInput, int &bytesread);
+ CT_Header read_header(uint8_t* data, int &bytesread);
void read_lut_type(int offset, int data_size, ColorTransf *Transf, ConversionInput* conversionInput);
- void read_xyz_type(int offset, int data_size, C_RGB_XYZ_Lab *xyz, ConversionInput* conversionInput);
+ void read_xyz_type(int offset, int data_size, C_RGB_XYZ_Lab *xyz, uint8_t *data);
void read_text_type(int offset, int data_size, std::string *textstr,
- ConversionInput* conversionInput);
+ uint8_t *data);
void read_text_description_type(int offset, int data_size, std::string textdescstr,
- ConversionInput* conversionInput);
+ uint8_t *data);
+ void findStops(GradStruct m_GradStops1, GradStruct m_GradStops2, double dEThr, int ninterstops, int &nOut,
+ double **VecRGBOut, double **VecLabOut, double *posOut);
+ void SetNormFactor();
+ void SetInverseNormFactor();
+ void NormGamutRegionMaxLim();
+ void GradInput2InputCoords(GradientConversionInput *conversionInput, InputCoordinates **inputcoordinates);
+ void PrepareGradient(GradientConversionInput* conversionInput, GradientConversionOutput *conversionOutput);
+ void LimitInks(VectorXd inInks, double *BoundedInks);
+ void NLcmtoPercentage(VectorXd InVolume, VectorXd &OutVolume);
+ int GetGamutRegion(VectorXd Volume, double *GamutLimits);
};
}
}
diff --git a/Software/Visual_Studio/ColorLib/Tango.ColorLib_v4/Utils/ColorConvert.cpp b/Software/Visual_Studio/ColorLib/Tango.ColorLib_v4/Utils/ColorConvert.cpp
index a0d773aee..19ffdf4b5 100644
--- a/Software/Visual_Studio/ColorLib/Tango.ColorLib_v4/Utils/ColorConvert.cpp
+++ b/Software/Visual_Studio/ColorLib/Tango.ColorLib_v4/Utils/ColorConvert.cpp
@@ -1078,6 +1078,13 @@ void ColorConvert::Jab_parameters(CAM02CS CS)
dECMCVal = (dECMC1 + dECMC2) / 2;
}
+ void ColorConvert::dEcmc(C_RGB_XYZ_Lab &refX, C_RGB_XYZ_Lab &samX, double &dECMC)
+ {
+ VectorXd refX1 = refX.Get();
+ VectorXd samX1 = samX.Get();
+ dEcmc(samX1, refX1, dECMC);
+ }
+
void ColorConvert::dEcmc(VectorXd refX, VectorXd samX, double &dECMC)
{
//dEcmc(refX, samX) calculates color difference CMC(2:1) in
diff --git a/Software/Visual_Studio/ColorLib/Tango.ColorLib_v4/Utils/ColorConvert.h b/Software/Visual_Studio/ColorLib/Tango.ColorLib_v4/Utils/ColorConvert.h
index aa1b323b1..e9bec9331 100644
--- a/Software/Visual_Studio/ColorLib/Tango.ColorLib_v4/Utils/ColorConvert.h
+++ b/Software/Visual_Studio/ColorLib/Tango.ColorLib_v4/Utils/ColorConvert.h
@@ -90,6 +90,7 @@ class ColorConvert
double *LabToJab(double* pColor, SURROUND sur);
void InitCiecamParams(double Y_b, double L_A, SURROUND sur, CAM02CS CS);
void dEcmc(VectorXd refX, VectorXd samX, double &dE);
+ void dEcmc(C_RGB_XYZ_Lab &refX, C_RGB_XYZ_Lab &samX, double &dE);
void SymmetricaldECMC(VectorXd refX, VectorXd samX, double &dECMC);
CAM02CS getCAM02CS() { return(m_CS); };
SURROUND getSurround() { return(m_sur); };
diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.RML/ViewModels/MainViewVM.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.RML/ViewModels/MainViewVM.cs
index d4bb07a9b..c31c95800 100644
--- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.RML/ViewModels/MainViewVM.cs
+++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.RML/ViewModels/MainViewVM.cs
@@ -34,6 +34,7 @@ namespace Tango.MachineStudio.RML.ViewModels
private IAuthenticationProvider _authentication;
private IActionLogManager _actionLogManager;
private RmlDTO _rmlBeforeSave;
+ private static object _syncLock = new object();
private ObservablesContext _rmls_context;
private ObservablesContext _active_context;
@@ -45,6 +46,22 @@ namespace Tango.MachineStudio.RML.ViewModels
set { _rmls = value; RaisePropertyChangedAuto(); }
}
+ private ICollectionView _rmlssCollectionView;
+ /// <summary>
+ /// Gets or sets the RML collection view.
+ /// </summary>
+ public ICollectionView RmlsCollectionView
+ {
+ get { return _rmlssCollectionView; }
+ set
+ {
+ _rmlssCollectionView = value;
+ BindingOperations.EnableCollectionSynchronization(_rmlssCollectionView, _syncLock);
+
+ RaisePropertyChangedAuto();
+ }
+ }
+
private ObservableCollection<MediaMaterial> _materials;
public ObservableCollection<MediaMaterial> Materials
{
@@ -171,6 +188,16 @@ namespace Tango.MachineStudio.RML.ViewModels
set { _colorCalibrationVM = value; RaisePropertyChangedAuto(); }
}
+ private String _RMLFilter;
+ /// <summary>
+ /// Gets or sets the job filter.
+ /// </summary>
+ public String RMLFilter
+ {
+ get { return _RMLFilter; }
+ set { _RMLFilter = value; RaisePropertyChangedAuto(); OnRMLFilterChanged(); }
+ }
+
/// <summary>
/// Gets or sets the manage RML command.
/// </summary>
@@ -262,7 +289,6 @@ namespace Tango.MachineStudio.RML.ViewModels
_rmls_context = ObservablesContext.CreateDefault();
Rmls = await new RmlsCollectionBuilder(_rmls_context).SetAll().WithLiquidFactors().WithMediaProperties().BuildAsync();
-
//Load CCT file names...
var ccts = await _rmls_context.Ccts.Select(x => new
{
@@ -283,6 +309,8 @@ namespace Tango.MachineStudio.RML.ViewModels
};
}
}
+ RmlsCollectionView = CollectionViewSource.GetDefaultView(Rmls);
+ RmlsCollectionView.SortDescriptions.Add(new SortDescription(nameof(Rml.LastUpdated), ListSortDirection.Descending));
}
private async void LoadActiveRML(String guid)
@@ -653,6 +681,23 @@ namespace Tango.MachineStudio.RML.ViewModels
ActiveProcessParametersTableView.Refresh();
}
+ private void OnRMLFilterChanged()
+ {
+ String filter = RMLFilter.ToLower();
+
+ RmlsCollectionView.Filter = (rml) =>
+ {
+ Rml r = rml as Rml;
+ return String.IsNullOrWhiteSpace(filter)
+ ||
+ r.Name.ToLower().Contains(filter) //Rml name
+ ||
+ (r.MediaMaterial != null && r.MediaMaterial.Name.ToLower().Contains(filter)) // Material name
+ ||
+ (r.Cct != null && r.Cct.FileName != null && r.Cct.FileName.ToString().Contains(filter)); //Cct.FileName
+ };
+ }
+
private void RemoveLiquidFactor(LiquidTypesRml liquidFactor)
{
if (_notification.ShowQuestion("Removing this liquid factor will remove the liquid type association with the RML and will drop the calibration data. Are you sure?"))
diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.RML/Views/RmlsView.xaml b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.RML/Views/RmlsView.xaml
index 288f00a3d..18af6bed5 100644
--- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.RML/Views/RmlsView.xaml
+++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.RML/Views/RmlsView.xaml
@@ -22,6 +22,10 @@
<DockPanel Margin="100 100 100 50" MaxWidth="1200">
<Grid DockPanel.Dock="Top">
<Image Source="../Images/threads.png" Width="300" Margin="10" />
+ <StackPanel Orientation="Horizontal" HorizontalAlignment="Right" VerticalAlignment="Bottom" Margin="0 0 10 30">
+ <materialDesign:PackIcon Kind="Magnify" Width="26" Height="26"/>
+ <TextBox Width="300" materialDesign:HintAssist.Hint="Search name, material,..." Text="{Binding RMLFilter,UpdateSourceTrigger=PropertyChanged}"></TextBox>
+ </StackPanel>
</Grid>
<Grid DockPanel.Dock="Bottom">
<StackPanel>
diff --git a/Software/Visual_Studio/Tango.ColorLib.GradientTest.CLI/Program.cs b/Software/Visual_Studio/Tango.ColorLib.GradientTest.CLI/Program.cs
index 811f53841..37d219757 100644
--- a/Software/Visual_Studio/Tango.ColorLib.GradientTest.CLI/Program.cs
+++ b/Software/Visual_Studio/Tango.ColorLib.GradientTest.CLI/Program.cs
@@ -20,54 +20,54 @@ namespace Tango.ColorLib.GradientTest.CLI
GradientConversionInput input = new GradientConversionInput();
//CCT
- input.ForwardData = ByteString.CopyFrom(File.ReadAllBytes(@"C:\Test\CMYKSylko.cct")); //TODO: Load CCT file from local drive.
+ input.ForwardData = ByteString.CopyFrom(File.ReadAllBytes(@"C:\Mirta\Matlab\Sylko_HV_IL350.cct")); //TODO: Load CCT file from local drive.
//RML Liquid Factors
input.InputLiquids.Add(new InputLiquid()
{
LiquidType = LiquidType.Cyan,
CalibrationData = BL.Entities.Cat.CreateDemoCalibrationData(LiquidType.Cyan),
- MaxNanoliterPerCentimeter = 2.34,
+ MaxNanoliterPerCentimeter = 175,
});
input.InputLiquids.Add(new InputLiquid()
{
LiquidType = LiquidType.Magenta,
CalibrationData = BL.Entities.Cat.CreateDemoCalibrationData(LiquidType.Magenta),
- MaxNanoliterPerCentimeter = 2.34,
+ MaxNanoliterPerCentimeter = 175,
});
input.InputLiquids.Add(new InputLiquid()
{
LiquidType = LiquidType.Yellow,
CalibrationData = BL.Entities.Cat.CreateDemoCalibrationData(LiquidType.Yellow),
- MaxNanoliterPerCentimeter = 2.34,
+ MaxNanoliterPerCentimeter = 175,
});
input.InputLiquids.Add(new InputLiquid()
{
LiquidType = LiquidType.Black,
CalibrationData = BL.Entities.Cat.CreateDemoCalibrationData(LiquidType.Black),
- MaxNanoliterPerCentimeter = 2.34,
+ MaxNanoliterPerCentimeter =175,
});
//Process Ranges
input.ProcessRanges.Add(new ProcessRange()
{
- MinInkUptake = 200,
- MaxInkUptake = 200,
+ MinInkUptake = 175,
+ MaxInkUptake = 175,
});
input.ProcessRanges.Add(new ProcessRange()
{
- MinInkUptake = 200,
- MaxInkUptake = 400,
+ MinInkUptake = 175,
+ MaxInkUptake = 350,
});
//White Point
- input.ThreadL = 1;
- input.ThreadA = 2;
- input.ThreadB = 3;
+ input.ThreadL = 92.7867 ;
+ input.ThreadA = -0.2519;
+ input.ThreadB = 0.6968;
//Segment length
input.SegmentLength = 1000;
@@ -77,9 +77,9 @@ namespace Tango.ColorLib.GradientTest.CLI
{
ColorSpace = ColorSpace.Rgb,
Offset = 0,
- Red = 255,
- Green = 0,
- Blue = 0,
+ Red = 25,
+ Green = 139,
+ Blue = 246,
});
//RGB Stop 2
@@ -87,9 +87,9 @@ namespace Tango.ColorLib.GradientTest.CLI
{
ColorSpace = ColorSpace.Rgb,
Offset = 1,
- Red = 0,
- Green = 0,
- Blue = 255,
+ Red = 71,
+ Green = 244,
+ Blue = 40,
});
Console.WriteLine($"Testing input:\n{input.ToJsonString(nameof(input.ForwardData),nameof(CalibrationData))}");
diff --git a/Software/Visual_Studio/Utilities/Tango.DispenserAnalyzer.UI/Analyzers/FlowAnalyser.cs b/Software/Visual_Studio/Utilities/Tango.DispenserAnalyzer.UI/Analyzers/FlowAnalyser.cs
index 2d4775a37..58c5dfedf 100644
--- a/Software/Visual_Studio/Utilities/Tango.DispenserAnalyzer.UI/Analyzers/FlowAnalyser.cs
+++ b/Software/Visual_Studio/Utilities/Tango.DispenserAnalyzer.UI/Analyzers/FlowAnalyser.cs
@@ -11,6 +11,9 @@ using System.Linq.Expressions;
using System.Diagnostics;
using OxyPlot;
using System.Collections.ObjectModel;
+using Tango.Documents;
+using System.IO;
+using Tango.Core.Helpers;
namespace Tango.DispenserAnalyzer.UI.Analyzers
{
@@ -38,7 +41,7 @@ namespace Tango.DispenserAnalyzer.UI.Analyzers
if (index % 2 == 1)//testing Flow-error
{
- List<DispenserSample> filteredValues = rangeTestValues.Skip(1800).ToList();
+ List<DispenserSample> filteredValues = rangeTestValues.Skip((int)Settings.GetValueByName(AnalyzerSettingsEnum.ExcludeAnalysis)).ToList();
//Move Average data
List<Task> tasks = new List<Task>();
@@ -57,11 +60,12 @@ namespace Tango.DispenserAnalyzer.UI.Analyzers
Task.WaitAll(tasks.ToArray());
//calculate difference Max Min values for each 300 values
- int periodCalcMaxMin = 500;
+ int periodCalcMaxMin = (int)Settings.GetValueByName(AnalyzerSettingsEnum.MaxMinRange);
+ int intervalCalcMaxMin = (int)Settings.GetValueByName(AnalyzerSettingsEnum.MaxMinIntervals);
List<int> differenceMaxMin = new List<int>();
List<int> differenceMaxMinToLocationArr = new List<int>();
int location_index = 0;
- for (int i = 0; i < (filteredValues.Count - periodCalcMaxMin); i+= 300)
+ for (int i = 0; i < (filteredValues.Count - periodCalcMaxMin); i+= intervalCalcMaxMin)
{
var rangeItems =(filteredValues.Skip(i).Take(periodCalcMaxMin).ToList());
int range = (int)(rangeItems.Max(t => t.Pressure) - rangeItems.Min(t => t.Pressure));
@@ -71,7 +75,7 @@ namespace Tango.DispenserAnalyzer.UI.Analyzers
}
FlowAverageAnalyzerResult averageResult = new FlowAverageAnalyzerResult();
averageResult.AverageValue = filteredValues.Average(t => t.Pressure);
- averageResult.Result = (averageResult.AverageValue <= 1850 && averageResult.AverageValue >= 1400) ? AnalyzerResultValue.Passed : AnalyzerResultValue.Failed;
+ averageResult.Result = (averageResult.AverageValue <= Settings.GetValueByName(AnalyzerSettingsEnum.AvgMaxValue) && averageResult.AverageValue >= Settings.GetValueByName(AnalyzerSettingsEnum.AvgMinValue)) ? AnalyzerResultValue.Passed : AnalyzerResultValue.Failed;
results.Add(averageResult);
FlowAnalyzerResult result = new FlowAnalyzerResult(++flowtestNumber);
@@ -85,8 +89,8 @@ namespace Tango.DispenserAnalyzer.UI.Analyzers
int avgMinIndex = rangeTestValues.Select(x => x.Index).Min();
int avgMaxIndex = rangeTestValues.Select(x => x.Index).Max();
double totalsec = TimeSpan.FromMilliseconds((avgMaxIndex - avgMinIndex) * 100).TotalSeconds;
- result.Time = totalsec.ToString() + " sec (succeed for period < 4.5)"; ;
- result.Result = (totalsec < 4.5) ? AnalyzerResultValue.Passed : AnalyzerResultValue.Failed;
+ result.Time = totalsec.ToString() + $" sec (succeed for period < {AnalyzerSettingsEnum.FlowPBUPassFail})"; ;
+ result.Result = (totalsec < Settings.GetValueByName(AnalyzerSettingsEnum.FlowPBUPassFail)) ? AnalyzerResultValue.Passed : AnalyzerResultValue.Failed;
results.Add(result);
}
}
@@ -155,12 +159,17 @@ namespace Tango.DispenserAnalyzer.UI.Analyzers
}
RangeToTimeChart.Title = $"Flow Time Location To Range {TestNumber}";
RangeToTimeChart.UpdateData();
+ string filename = FileHelper.GetFileToSaveFlowRangeToTimeData(TestNumber);
+ if(filename.IsNotNullOrEmpty() && rangeToTimePoints.Count > 0)
+ {
+ ExportnDataToExcel(rangeToTimePoints.ToList(), filename);
+ }
}
private double BuildMeasurementError(List<int> range_values)
{
int count = range_values.Count();
- return (count - (count * 0.99));
+ return (count - (int)Settings.GetValueByName(AnalyzerSettingsEnum.TakeOffMaxMin));
}
/// <summary>
@@ -187,11 +196,48 @@ namespace Tango.DispenserAnalyzer.UI.Analyzers
break;
}
}
- //Result = (range <= 25 && range >= 20) ? AnalyzerResultValue.Passed : AnalyzerResultValue.Failed;
+
var res = range / AverageValue * 100;
- Result = res <= 1.5 ? AnalyzerResultValue.Passed : AnalyzerResultValue.Failed;
+ Result = res <= Settings.GetValueByName(AnalyzerSettingsEnum.MaxError) ? AnalyzerResultValue.Passed : AnalyzerResultValue.Failed;
return max_key;
}
+
+ /// <summary>
+ /// Exports the calibration data to excel.
+ /// </summary>
+ /// <param name="calibrationPoints">The calibration points.</param>
+ /// <param name="fileName">Name of the file.</param>
+ public static void ExportnDataToExcel(List<DataPoint> dataPoints, String fileName)
+ {
+ try
+ {
+ CreateDataExcelTemplate(fileName);
+
+ using (ExcelWriter writer = new ExcelWriter(fileName))
+ {
+ writer.WriteData(dataPoints, "RangeToTimeData");
+ }
+ }
+ catch (Exception ex)
+ {
+ Debug.WriteLine("Error: ", ex.Message);
+ }
+ }
+
+ /// <summary>
+ /// Creates the calibration data excel template.
+ /// </summary>
+ /// <param name="fileName">Name of the file.</param>
+ public static void CreateDataExcelTemplate(String fileName)
+ {
+ var stream = EmbeddedResourceHelper.GetEmbeddedResourceStream("Tango.DispenserAnalyzer.UI.Models.FlowRangeToTimeResults.xlsx");
+
+ using (FileStream fs = new FileStream(fileName, FileMode.Create))
+ {
+ stream.Seek(0, SeekOrigin.Begin);
+ stream.CopyTo(fs);
+ }
+ }
}
public class MovingAverageFilter
diff --git a/Software/Visual_Studio/Utilities/Tango.DispenserAnalyzer.UI/Analyzers/PressureBuildUpAnalyser.cs b/Software/Visual_Studio/Utilities/Tango.DispenserAnalyzer.UI/Analyzers/PressureBuildUpAnalyser.cs
index edc89f030..c4c5f6c65 100644
--- a/Software/Visual_Studio/Utilities/Tango.DispenserAnalyzer.UI/Analyzers/PressureBuildUpAnalyser.cs
+++ b/Software/Visual_Studio/Utilities/Tango.DispenserAnalyzer.UI/Analyzers/PressureBuildUpAnalyser.cs
@@ -29,7 +29,7 @@ namespace Tango.DispenserAnalyzer.UI.Analyzers
int avgMaxIndex = rangeTestValues.Select(x => x.Index).Max();
double totalsec = TimeSpan.FromMilliseconds((avgMaxIndex - avgMinIndex) * 100).TotalSeconds;
result.Time = totalsec.ToString() + " sec";
- result.Result = (totalsec <= 12 && totalsec >= 7) ? AnalyzerResultValue.Passed : AnalyzerResultValue.Failed;
+ result.Result = (totalsec < Settings.GetValueByName(AnalyzerSettingsEnum.PBUPassFail)) ? AnalyzerResultValue.Passed : AnalyzerResultValue.Failed;
results.Add(result);
}
}
diff --git a/Software/Visual_Studio/Utilities/Tango.DispenserAnalyzer.UI/App.xaml b/Software/Visual_Studio/Utilities/Tango.DispenserAnalyzer.UI/App.xaml
index 73d8ea48c..8969f50af 100644
--- a/Software/Visual_Studio/Utilities/Tango.DispenserAnalyzer.UI/App.xaml
+++ b/Software/Visual_Studio/Utilities/Tango.DispenserAnalyzer.UI/App.xaml
@@ -3,7 +3,7 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
xmlns:local="clr-namespace:Tango.DispenserAnalyzer.UI"
- StartupUri="MainWindow.xaml">
+ Startup="Application_Startup">
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
diff --git a/Software/Visual_Studio/Utilities/Tango.DispenserAnalyzer.UI/App.xaml.cs b/Software/Visual_Studio/Utilities/Tango.DispenserAnalyzer.UI/App.xaml.cs
index 6250d17a1..c1876d806 100644
--- a/Software/Visual_Studio/Utilities/Tango.DispenserAnalyzer.UI/App.xaml.cs
+++ b/Software/Visual_Studio/Utilities/Tango.DispenserAnalyzer.UI/App.xaml.cs
@@ -13,5 +13,12 @@ namespace Tango.DispenserAnalyzer.UI
/// </summary>
public partial class App : Application
{
+ private void Application_Startup(object sender, StartupEventArgs e)
+ {
+ MainWindow wnd = new MainWindow();
+ if (e.Args.Length >= 1)
+ wnd.SetOpenFileFromArgument(e.Args[0]);
+ wnd.Show();
+ }
}
}
diff --git a/Software/Visual_Studio/Utilities/Tango.DispenserAnalyzer.UI/FileHelper.cs b/Software/Visual_Studio/Utilities/Tango.DispenserAnalyzer.UI/FileHelper.cs
new file mode 100644
index 000000000..7172a4ff1
--- /dev/null
+++ b/Software/Visual_Studio/Utilities/Tango.DispenserAnalyzer.UI/FileHelper.cs
@@ -0,0 +1,44 @@
+
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Tango.DispenserAnalyzer.UI
+{
+ public static class FileHelper
+ {
+ private const string FILE_EXTENSION = ".pdf";
+ private const string FILE_EXEL_EXTENSION = ".xlsx";
+
+ public static string OpenFilePath{ get; set; }
+
+ public static string GetResultFilePath()
+ {
+ if (File.Exists(OpenFilePath))
+ {
+ var ext = Path.GetExtension(OpenFilePath);
+ var dir = Path.GetDirectoryName(OpenFilePath);
+ var resultFile = Path.Combine(dir, string.Format("{0}-result{1}", Path.GetFileNameWithoutExtension(OpenFilePath), FILE_EXTENSION));
+ return resultFile;
+ }
+ return "";
+ }
+
+ public static string GetFileToSaveFlowRangeToTimeData( int extNumber)
+ {
+ if (File.Exists(OpenFilePath))
+ {
+ var ext = Path.GetExtension(OpenFilePath);
+ var dir = Path.GetDirectoryName(OpenFilePath);
+ var resultFile = Path.Combine(dir, string.Format("{0}_rangeToTime{1}{2}", Path.GetFileNameWithoutExtension(OpenFilePath), extNumber.ToString(), FILE_EXEL_EXTENSION));
+ return resultFile;
+ }
+ return "";
+ }
+
+
+ }
+}
diff --git a/Software/Visual_Studio/Utilities/Tango.DispenserAnalyzer.UI/MainWindow.xaml.cs b/Software/Visual_Studio/Utilities/Tango.DispenserAnalyzer.UI/MainWindow.xaml.cs
index 9797d203b..43a573a7d 100644
--- a/Software/Visual_Studio/Utilities/Tango.DispenserAnalyzer.UI/MainWindow.xaml.cs
+++ b/Software/Visual_Studio/Utilities/Tango.DispenserAnalyzer.UI/MainWindow.xaml.cs
@@ -48,6 +48,15 @@ namespace Tango.DispenserAnalyzer.UI
ax.Maximum = ax.Minimum = Double.NaN;
}
+ public void SetOpenFileFromArgument( string openFilePath)
+ {
+ if(_vm != null)
+ {
+ _vm.OpenFilePath = openFilePath;
+ _vm.Generate();
+ }
+ }
+
private void TextBlock_PreviewDrop(object sender, DragEventArgs e)
{
string[] files = (string[])e.Data.GetData(DataFormats.FileDrop);
diff --git a/Software/Visual_Studio/Utilities/Tango.DispenserAnalyzer.UI/Models/FlowRangeToTimeResults.xlsx b/Software/Visual_Studio/Utilities/Tango.DispenserAnalyzer.UI/Models/FlowRangeToTimeResults.xlsx
new file mode 100644
index 000000000..5f0e4b651
--- /dev/null
+++ b/Software/Visual_Studio/Utilities/Tango.DispenserAnalyzer.UI/Models/FlowRangeToTimeResults.xlsx
Binary files differ
diff --git a/Software/Visual_Studio/Utilities/Tango.DispenserAnalyzer.UI/Models/SettingsModel.cs b/Software/Visual_Studio/Utilities/Tango.DispenserAnalyzer.UI/Models/SettingsModel.cs
index 0d9e20288..5540e4b25 100644
--- a/Software/Visual_Studio/Utilities/Tango.DispenserAnalyzer.UI/Models/SettingsModel.cs
+++ b/Software/Visual_Studio/Utilities/Tango.DispenserAnalyzer.UI/Models/SettingsModel.cs
@@ -4,11 +4,24 @@ using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Tango.Core;
+using Tango.Core.Commands;
namespace Tango.DispenserAnalyzer.UI.Models
-{
- public class SettingsModel: ExtendedObject
+{
+ public interface ISettingsModel
{
+ string PropertyName { get; set; }
+ double PropertyValue { get; set; }
+ double DefaultValue { get; set; }
+ string DefaultValueDisplay { get; set; }
+ double MinRangeValue { get; set; }
+ double MaxRangeValue { get; set; }
+ bool IsRangeVisible { get; set; }
+ }
+
+ public class SettingsModel: ExtendedObject, ISettingsModel
+ {
+ public AnalyzerSettingsEnum _enumName;
private string _propertyName;
public string PropertyName
@@ -22,7 +35,23 @@ namespace Tango.DispenserAnalyzer.UI.Models
public double PropertyValue
{
get { return _propertyvalue; }
- set { _propertyvalue = value; RaisePropertyChangedAuto(); }
+ set {
+ if( _propertyvalue != value)
+ {
+ _propertyvalue = value;
+ RaisePropertyChangedAuto();
+ OnPropertyvalueChanged();
+ }
+ }
+ }
+
+ private void OnPropertyvalueChanged()
+ {
+ if(SettingValueEvent != null)
+ {
+ SettingValueEvent?.Invoke(this, new EventArgs());
+ }
+
}
private double _defaultValue;
@@ -41,12 +70,78 @@ namespace Tango.DispenserAnalyzer.UI.Models
set { _defaultValueDisplay = value; }
}
+ private double _minDefaultRangeValue;
+ public double MinDefaultRangeValue
+ {
+ get { return _minDefaultRangeValue; }
+ set { _minDefaultRangeValue = value; RaisePropertyChangedAuto(); }
+ }
+
+ private double _maxDefaultRangeValue;
+ public double MaxDefaultRangeValue
+ {
+ get { return _maxDefaultRangeValue; }
+ set { _maxDefaultRangeValue = value; RaisePropertyChangedAuto(); }
+ }
+
+ private double _minRangeValue;
+ public double MinRangeValue
+ {
+ get { return _minRangeValue; }
+ set {
+ if (_minRangeValue != value)
+ {
+ _minRangeValue = value;
+ RaisePropertyChangedAuto();
+ OnPropertyvalueChanged();
+ }
+ }
+ }
- public SettingsModel( string propertyName, string defaultValueDisplay, double defaultValue)
+ private double _maxRangeValue;
+ public double MaxRangeValue
{
- PropertyName = propertyName;
+ get { return _maxRangeValue; }
+ set {
+ if (_maxRangeValue != value)
+ {
+ _maxRangeValue = value;
+ RaisePropertyChangedAuto();
+ OnPropertyvalueChanged();
+ }
+ }
+ }
+ public bool IsRangeVisible { get; set; }
+
+ public event EventHandler SettingValueEvent;
+
+ public RelayCommand SetDefaultCommand { get; set; }
+
+
+ public SettingsModel(AnalyzerSettingsEnum enumName, string defaultValueDisplay, bool isrange = false)
+ {
+ _enumName = enumName;
+ PropertyName = _enumName.ToDescription();
DefaultValueDisplay = defaultValueDisplay;
- DefaultValue = defaultValue;
+ DefaultValue = Settings.GetDefaultValueByName(enumName);
+ PropertyValue = Settings.GetValueByName(enumName);
+ IsRangeVisible = isrange;
+ MinDefaultRangeValue = IsRangeVisible ? Settings.GetDefaultValueByName(AnalyzerSettingsEnum.AvgMinValue) : 0.0;
+ MaxDefaultRangeValue = IsRangeVisible ? Settings.GetDefaultValueByName(AnalyzerSettingsEnum.AvgMaxValue) : 0.0;
+ MinRangeValue = IsRangeVisible? Settings.GetValueByName(AnalyzerSettingsEnum.AvgMinValue) : 0.0;
+ MaxRangeValue = IsRangeVisible? Settings.GetValueByName(AnalyzerSettingsEnum.AvgMaxValue) : 0.0;
+ SetDefaultCommand = new RelayCommand(SetDefault);
+ }
+
+ private void SetDefault()
+ {
+ if(IsRangeVisible)
+ {
+ MinRangeValue = MinDefaultRangeValue;
+ MaxRangeValue = MaxDefaultRangeValue;
+ return;
+ }
+ PropertyValue = DefaultValue;
}
}
}
diff --git a/Software/Visual_Studio/Utilities/Tango.DispenserAnalyzer.UI/Settings.cs b/Software/Visual_Studio/Utilities/Tango.DispenserAnalyzer.UI/Settings.cs
new file mode 100644
index 000000000..9a1f10aed
--- /dev/null
+++ b/Software/Visual_Studio/Utilities/Tango.DispenserAnalyzer.UI/Settings.cs
@@ -0,0 +1,87 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Tango.DispenserAnalyzer.UI
+{
+ public enum AnalyzerSettingsEnum
+ {
+ //Undetermined
+ [Description("PBU Pass fail")]
+ PBUPassFail,
+ [Description("PBU Pass fail")]
+ FlowPBUPassFail,
+ [Description("Exclude from analysis")]
+ ExcludeAnalysis,
+ [Description("Avg value")]
+ AvgMaxValue,
+ [Description("Avg value")]
+ AvgMinValue,
+ [Description("Max-Min range")]
+ MaxMinRange,
+ [Description("Max Min intervals")]
+ MaxMinIntervals,
+ [Description("Max error")]
+ MaxError,
+ [Description("Take off 'Max-min' values(out of highest results)")]
+ TakeOffMaxMin,
+
+ }
+
+ public static class Settings
+ {
+ public static Dictionary<AnalyzerSettingsEnum, double> DefaultValues { get; set; }
+ public static Dictionary<AnalyzerSettingsEnum, double> CurrentValues { get; set; }
+
+ static Settings()
+ {
+ DefaultValues = new Dictionary<AnalyzerSettingsEnum, double>();
+
+ DefaultValues[AnalyzerSettingsEnum.PBUPassFail] = 4.5;
+ DefaultValues[AnalyzerSettingsEnum.FlowPBUPassFail] = 4.5;
+ DefaultValues[AnalyzerSettingsEnum.ExcludeAnalysis] = 1800;
+ DefaultValues[AnalyzerSettingsEnum.AvgMinValue] = 1400;
+ DefaultValues[AnalyzerSettingsEnum.AvgMaxValue] = 1850;
+ DefaultValues[AnalyzerSettingsEnum.MaxMinRange] = 500;
+ DefaultValues[AnalyzerSettingsEnum.MaxMinIntervals] = 300;
+ DefaultValues[AnalyzerSettingsEnum.MaxError] = 1.5;
+ DefaultValues[AnalyzerSettingsEnum.TakeOffMaxMin] = 3;
+
+ CurrentValues = new Dictionary<AnalyzerSettingsEnum, double>();
+ CurrentValues[AnalyzerSettingsEnum.PBUPassFail] = 4.5;
+ CurrentValues[AnalyzerSettingsEnum.FlowPBUPassFail] = 4.5;
+ CurrentValues[AnalyzerSettingsEnum.ExcludeAnalysis] = 1800;
+ CurrentValues[AnalyzerSettingsEnum.AvgMinValue] = 1400;
+ CurrentValues[AnalyzerSettingsEnum.AvgMaxValue] = 1850;
+ CurrentValues[AnalyzerSettingsEnum.MaxMinRange] = 500;
+ CurrentValues[AnalyzerSettingsEnum.MaxMinIntervals] = 300;
+ CurrentValues[AnalyzerSettingsEnum.MaxError] = 1.5;
+ CurrentValues[AnalyzerSettingsEnum.TakeOffMaxMin] = 3;
+ }
+ public static double GetValueByName(AnalyzerSettingsEnum name)
+ {
+ double value;
+ if (CurrentValues.TryGetValue(name, out value))
+ {
+ return value;
+ }
+ return 0.0;
+ }
+ public static void SetValueByName(AnalyzerSettingsEnum name, double value)
+ {
+ CurrentValues[name] = value;
+ }
+ public static double GetDefaultValueByName(AnalyzerSettingsEnum name)
+ {
+ double value;
+ if (DefaultValues.TryGetValue(name, out value))
+ {
+ return value;
+ }
+ return 0.0;
+ }
+ }
+}
diff --git a/Software/Visual_Studio/Utilities/Tango.DispenserAnalyzer.UI/Tango.DispenserAnalyzer.UI.csproj b/Software/Visual_Studio/Utilities/Tango.DispenserAnalyzer.UI/Tango.DispenserAnalyzer.UI.csproj
index 7efcaa58d..01a5a7122 100644
--- a/Software/Visual_Studio/Utilities/Tango.DispenserAnalyzer.UI/Tango.DispenserAnalyzer.UI.csproj
+++ b/Software/Visual_Studio/Utilities/Tango.DispenserAnalyzer.UI/Tango.DispenserAnalyzer.UI.csproj
@@ -29,8 +29,8 @@
<ProductName>Dispenser Analyser</ProductName>
<PublisherName>Twine</PublisherName>
<OpenBrowserOnPublish>false</OpenBrowserOnPublish>
- <ApplicationRevision>4</ApplicationRevision>
- <ApplicationVersion>1.2.1.%2a</ApplicationVersion>
+ <ApplicationRevision>2</ApplicationRevision>
+ <ApplicationVersion>2.1.1.%2a</ApplicationVersion>
<UseApplicationTrust>true</UseApplicationTrust>
<CreateDesktopShortcut>true</CreateDesktopShortcut>
<PublishWizardCompleted>true</PublishWizardCompleted>
@@ -140,10 +140,12 @@
<Compile Include="Analyzers\ReliabilityTestAnalyser.cs" />
<Compile Include="Analyzers\SealingAnalyzer.cs" />
<Compile Include="Analysis\AnalyzerAttribute.cs" />
+ <Compile Include="FileHelper.cs" />
<Compile Include="Models\DispenserCsvRow.cs" />
<Compile Include="Models\DispenserSample.cs" />
<Compile Include="Models\DispenserSampleCommand.cs" />
<Compile Include="Models\SettingsModel.cs" />
+ <Compile Include="Settings.cs" />
<Compile Include="ViewModels\MainWindowVM.cs" />
<Compile Include="ViewModels\SettingsVM.cs" />
<Compile Include="View\SettingsWnd.xaml.cs">
@@ -184,6 +186,7 @@
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
</EmbeddedResource>
+ <EmbeddedResource Include="Models\FlowRangeToTimeResults.xlsx" />
<None Include="packages.config" />
<None Include="Properties\Settings.settings">
<Generator>SettingsSingleFileGenerator</Generator>
@@ -203,6 +206,10 @@
<Project>{58e8825f-0c96-449c-b320-1e82b0aa876b}</Project>
<Name>Tango.CSV</Name>
</ProjectReference>
+ <ProjectReference Include="..\..\Tango.Documents\Tango.Documents.csproj">
+ <Project>{ca87a608-7b17-4c98-88f2-42abee10f4c1}</Project>
+ <Name>Tango.Documents</Name>
+ </ProjectReference>
<ProjectReference Include="..\..\Tango.SharedUI\Tango.SharedUI.csproj">
<Project>{8491d07b-c1f6-4b62-a412-41b9fd2d6538}</Project>
<Name>Tango.SharedUI</Name>
diff --git a/Software/Visual_Studio/Utilities/Tango.DispenserAnalyzer.UI/View/SettingsWnd.xaml b/Software/Visual_Studio/Utilities/Tango.DispenserAnalyzer.UI/View/SettingsWnd.xaml
index 9d818a05b..2bfa2bba1 100644
--- a/Software/Visual_Studio/Utilities/Tango.DispenserAnalyzer.UI/View/SettingsWnd.xaml
+++ b/Software/Visual_Studio/Utilities/Tango.DispenserAnalyzer.UI/View/SettingsWnd.xaml
@@ -6,7 +6,7 @@
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
xmlns:local="clr-namespace:Tango.DispenserAnalyzer.UI.View"
mc:Ignorable="d"
- Title="Settings" Height="630" Width="800" FontSize="22" ResizeMode="NoResize" WindowStyle="ToolWindow">
+ Title="Settings" Height="630" Width="800" FontSize="22" ResizeMode="NoResize" WindowStyle="ToolWindow" Closing="Window_Closing">
<Window.Resources>
<Style TargetType="{x:Type TextBlock}" x:Key="WrapText">
<Setter Property="TextWrapping" Value="Wrap"/>
@@ -71,11 +71,44 @@
<Setter Property="VerticalScrollBarVisibility" Value="Auto"/>
</Style>
- <DataGrid x:Key="PropertyDataGrid" HorizontalAlignment="Left" VerticalScrollBarVisibility ="Auto" SelectionUnit="FullRow" AutoGenerateColumns="False" CanUserAddRows="False" CanUserDeleteRows="False"
+ <DataGrid x:Key="PropertyDataGrid" x:Shared="False" HorizontalAlignment="Left" VerticalScrollBarVisibility ="Auto" SelectionUnit="FullRow" AutoGenerateColumns="False" CanUserAddRows="False" CanUserDeleteRows="False"
ItemsSource="{Binding .}" GridLinesVisibility="None" SelectionMode="Single" AlternatingRowBackground="#F6F6F6" FontSize="12" >
<DataGrid.Columns>
<DataGridTextColumn Header="Property Name" Binding="{Binding PropertyName}" Width="150" ElementStyle="{StaticResource WrapText}"/>
- <DataGridTextColumn Header="Property Value" Binding="{Binding PropertyValue}" Width="150" IsReadOnly="False"></DataGridTextColumn>
+ <DataGridTemplateColumn Header="Property Value" Width="150">
+ <DataGridTemplateColumn.CellTemplate>
+ <DataTemplate>
+ <StackPanel Orientation="Horizontal">
+ <TextBox Text="{Binding PropertyValue, Mode=TwoWay, UpdateSourceTrigger=LostFocus}" Width="50" VerticalAlignment="Top">
+ <TextBox.Style>
+ <Style TargetType="{x:Type TextBox}" BasedOn="{StaticResource MaterialDesignTextBox}">
+ <Setter Property="Visibility" Value="Visible"/>
+ <Style.Triggers>
+ <DataTrigger Binding="{Binding IsRangeVisible}" Value="true">
+ <Setter Property="Visibility" Value="Collapsed"/>
+ </DataTrigger>
+ </Style.Triggers>
+ </Style>
+ </TextBox.Style>
+ </TextBox>
+ <DockPanel HorizontalAlignment="Stretch" Width="150">
+ <DockPanel.Style>
+ <Style TargetType="{x:Type DockPanel}">
+ <Setter Property="Visibility" Value="Collapsed"/>
+ <Style.Triggers>
+ <DataTrigger Binding="{Binding IsRangeVisible}" Value="true">
+ <Setter Property="Visibility" Value="Visible"/>
+ </DataTrigger>
+ </Style.Triggers>
+ </Style>
+ </DockPanel.Style>
+ <TextBox DockPanel.Dock="Left" Name="MinRangeValue" Width="50" Text="{Binding MinRangeValue, Mode=TwoWay, UpdateSourceTrigger=LostFocus}"/>
+ <TextBox DockPanel.Dock="Right" Name="MaxRangeValue" Width="50" Text="{Binding MaxRangeValue, Mode=TwoWay, UpdateSourceTrigger=LostFocus}"/>
+ </DockPanel>
+ </StackPanel>
+ </DataTemplate>
+ </DataGridTemplateColumn.CellTemplate>
+ </DataGridTemplateColumn>
<DataGridTextColumn Header="Default Value" Binding="{Binding DefaultValueDisplay}" Width="150" ElementStyle="{StaticResource WrapText}" />
<DataGridTemplateColumn Header="" Width="1*">
<DataGridTemplateColumn.CellStyle>
@@ -104,13 +137,14 @@
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Grid HorizontalAlignment="Stretch" VerticalAlignment="Center">
- <Button Width="80" Padding="2" Height="26" FontSize="12" Margin="0 8">Set Default</Button>
+ <Button Width="80" Padding="2" Height="26" FontSize="12" Margin="0 8" Command="{Binding SetDefaultCommand}">Set Default</Button>
</Grid>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
+
</Window.Resources>
@@ -124,27 +158,29 @@
</Grid.ColumnDefinitions>
<Grid Grid.Row="0">
- <Grid.RowDefinitions>
- <RowDefinition Height="Auto"/>
- <RowDefinition/>
- </Grid.RowDefinitions>
- <Grid Grid.Row="0" VerticalAlignment="Top">
- <Border Margin="20 20 20 0" BorderBrush="LightGray" BorderThickness="0.6" CornerRadius="4" Height="36">
- <Border.Effect>
- <DropShadowEffect/>
- </Border.Effect>
- </Border>
- <Border Margin="20 20 20 0" BorderBrush="LightGray" BorderThickness="0.6" CornerRadius="4" Height="34" Background="#C4EEFC">
- <TextBlock FontSize="22" Padding="2">Pressure build up test</TextBlock>
- </Border>
+ <Grid>
+ <Grid.RowDefinitions>
+ <RowDefinition Height="Auto"/>
+ <RowDefinition Height="Auto"/>
+ </Grid.RowDefinitions>
+ <Grid Grid.Row="0" VerticalAlignment="Top">
+ <Border Margin="20 20 20 0" BorderBrush="LightGray" BorderThickness="0.6" CornerRadius="4" Height="36">
+ <Border.Effect>
+ <DropShadowEffect/>
+ </Border.Effect>
+ </Border>
+ <Border Margin="20 20 20 0" BorderBrush="LightGray" BorderThickness="0.6" CornerRadius="4" Height="34" Background="#C4EEFC">
+ <TextBlock FontSize="22" Padding="2">Pressure build up test</TextBlock>
+ </Border>
+ </Grid>
+ <ContentControl x:Name="PBUTestControl" Grid.Row="1" Content="{StaticResource PropertyDataGrid}" DataContext="{Binding Path=PBUTestSettings}" Margin="20 0 20 0"></ContentControl>
</Grid>
- <ContentControl Grid.Row="1" Margin="20 3 20 0" Content="{StaticResource PropertyDataGrid}" DataContext="{Binding Path=PBUTestSettings}"></ContentControl>
</Grid>
<Grid Grid.Row="1" HorizontalAlignment="Left" VerticalAlignment="Stretch">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
- <RowDefinition Height="1*"/>
+ <RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid Grid.Row="0" VerticalAlignment="Top">
<Border Margin="20 20 20 0" BorderBrush="LightGray" BorderThickness="0.6" CornerRadius="4" Height="36">
@@ -156,11 +192,11 @@
<TextBlock FontSize="22" Padding="2">Flow test</TextBlock>
</Border>
</Grid>
- <ContentControl Grid.Row="1" Content="{StaticResource PropertyDataGrid}" DataContext="{Binding Path=FlowTestSettings}" Margin="20 0 20 0"></ContentControl>
+ <ContentControl x:Name="FlowTestControl" Grid.Row="1" Content="{StaticResource PropertyDataGrid}" DataContext="{Binding Path=FlowTestSettings}" Margin="20 0 20 0"></ContentControl>
</Grid>
</Grid>
<Grid Grid.Row="2" >
- <Button Width="80" HorizontalAlignment="Right" Margin="20">Save</Button>
+ <Button Width="80" HorizontalAlignment="Right" Margin="20" Click="SaveButton_Click" IsDefault="True">Save</Button>
</Grid>
</Grid>
</Window>
diff --git a/Software/Visual_Studio/Utilities/Tango.DispenserAnalyzer.UI/View/SettingsWnd.xaml.cs b/Software/Visual_Studio/Utilities/Tango.DispenserAnalyzer.UI/View/SettingsWnd.xaml.cs
index f0e35726e..9879d8f7a 100644
--- a/Software/Visual_Studio/Utilities/Tango.DispenserAnalyzer.UI/View/SettingsWnd.xaml.cs
+++ b/Software/Visual_Studio/Utilities/Tango.DispenserAnalyzer.UI/View/SettingsWnd.xaml.cs
@@ -20,13 +20,20 @@ namespace Tango.DispenserAnalyzer.UI.View
/// </summary>
public partial class SettingsWnd : Window
{
+ private SettingsVM vm;
public SettingsWnd()
{
InitializeComponent();
- DataContext = new SettingsVM();
+ vm = new SettingsVM();
+ DataContext = vm;
Loaded += Window_loaded;
}
+ public Dictionary<AnalyzerSettingsEnum, double> GetChanges()
+ {
+ return vm.GetChanges();
+ }
+
private void Window_loaded(object sender, RoutedEventArgs e)
{
Application curApp = Application.Current;
@@ -34,5 +41,14 @@ namespace Tango.DispenserAnalyzer.UI.View
this.Left = mainWindow.Left + (mainWindow.Width - this.ActualWidth) / 2;
this.Top = mainWindow.Top + (mainWindow.Height - this.ActualHeight) / 2;
}
+
+ private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
+ {
+ vm.Dispose();
+ }
+ public void SaveButton_Click(object sender, RoutedEventArgs e)
+ {
+ this.DialogResult = true;
+ }
}
}
diff --git a/Software/Visual_Studio/Utilities/Tango.DispenserAnalyzer.UI/ViewModels/MainWindowVM.cs b/Software/Visual_Studio/Utilities/Tango.DispenserAnalyzer.UI/ViewModels/MainWindowVM.cs
index ab571ec43..70034b6e7 100644
--- a/Software/Visual_Studio/Utilities/Tango.DispenserAnalyzer.UI/ViewModels/MainWindowVM.cs
+++ b/Software/Visual_Studio/Utilities/Tango.DispenserAnalyzer.UI/ViewModels/MainWindowVM.cs
@@ -161,16 +161,22 @@ namespace Tango.DispenserAnalyzer.UI.ViewModels
_isRunning = false;
this.Points = new List<DataPoint>();
-
}
#region Settings
-
+
public void OpenSettingWnd()
{
SettingsWnd settings = new SettingsWnd();
settings.Owner = System.Windows.Application.Current.MainWindow;
- settings.ShowDialog();
+ if(true == settings.ShowDialog())
+ {
+ Dictionary<AnalyzerSettingsEnum, double> changes = settings.GetChanges();
+ foreach (KeyValuePair<AnalyzerSettingsEnum, double> entry in changes)
+ {
+ Settings.SetValueByName(entry.Key, entry.Value);
+ }
+ }
}
#endregion
@@ -220,6 +226,7 @@ namespace Tango.DispenserAnalyzer.UI.ViewModels
ResetSettings();
if(File.Exists(OpenFilePath))
{
+ FileHelper.OpenFilePath = OpenFilePath;
FileName = Path.GetFileName(OpenFilePath);
}
}
@@ -230,9 +237,9 @@ namespace Tango.DispenserAnalyzer.UI.ViewModels
{
return (OpenFilePath!= null && OpenFilePath.Length != 0 && File.Exists(OpenFilePath));
}
- private async void Generate()
+ public async void Generate()
{
- if (IsFileLocked(OpenFilePath))
+ if (false == File.Exists(OpenFilePath) || IsFileLocked(OpenFilePath) )
return;
ResetSettings();
@@ -328,13 +335,9 @@ namespace Tango.DispenserAnalyzer.UI.ViewModels
await Task.Delay(200);
try
{
- if (File.Exists(OpenFilePath))
+ var resultFile = FileHelper.GetResultFilePath();
+ if (resultFile.IsNotNullOrEmpty())
{
- var fileName = Path.GetFileNameWithoutExtension(OpenFilePath);
- fileName += "_result";
- var ext = Path.GetExtension(OpenFilePath);
- var dir = Path.GetDirectoryName(OpenFilePath);
- var resultFile = Path.Combine(dir, string.Format("{0}-result{1}", Path.GetFileNameWithoutExtension(OpenFilePath), FILE_EXTENSION));
SaveResultsAsXps(resultFile);
}
}
@@ -359,6 +362,8 @@ namespace Tango.DispenserAnalyzer.UI.ViewModels
int index = 0;
foreach (var item in all_plots)
{
+ var seriesdata = item.Series[0].ItemsSource;
+
item.RaiseEvent(new System.Windows.RoutedEventArgs(OxyPlot.Wpf.PlotView.LoadedEvent));
item.InvalidatePlot(true);
if (item.IsMeasureValid && item.ActualHeight > 0)
diff --git a/Software/Visual_Studio/Utilities/Tango.DispenserAnalyzer.UI/ViewModels/SettingsVM.cs b/Software/Visual_Studio/Utilities/Tango.DispenserAnalyzer.UI/ViewModels/SettingsVM.cs
index 99b6e948a..d5c54ab08 100644
--- a/Software/Visual_Studio/Utilities/Tango.DispenserAnalyzer.UI/ViewModels/SettingsVM.cs
+++ b/Software/Visual_Studio/Utilities/Tango.DispenserAnalyzer.UI/ViewModels/SettingsVM.cs
@@ -9,7 +9,7 @@ using Tango.SharedUI;
namespace Tango.DispenserAnalyzer.UI.ViewModels
{
- public class SettingsVM : ViewModel
+ public class SettingsVM : ViewModel, IDisposable
{
private ObservableCollection<SettingsModel> _PBUSettings;
@@ -27,28 +27,61 @@ namespace Tango.DispenserAnalyzer.UI.ViewModels
set { _flowTestSettings = value; RaisePropertyChangedAuto(); }
}
+ private Dictionary<AnalyzerSettingsEnum, double> changedValues;
+
public SettingsVM()
{
_PBUSettings = new ObservableCollection<SettingsModel>();
InitPBUTestSettings();
_flowTestSettings = new ObservableCollection<SettingsModel>();
+ changedValues = new Dictionary<AnalyzerSettingsEnum, double>();
InitFlowTestSettings();
}
private void InitPBUTestSettings()
{
- _PBUSettings.Add(new SettingsModel("PBU Pass fail", "4.5 sec", 4.5));
+ var setting = new SettingsModel(AnalyzerSettingsEnum.PBUPassFail, "4.5 sec");
+ setting.SettingValueEvent += new EventHandler(OnSettingValueChanged);
+ _PBUSettings.Add(setting);
}
private void InitFlowTestSettings()
{
- _flowTestSettings.Add(new SettingsModel("PBU Pass fail", "4.5 sec", 4.5));
- _flowTestSettings.Add(new SettingsModel("Exclude from analysis", "1800 reads", 1800));
- _flowTestSettings.Add(new SettingsModel("Avg value", "1400-1850 [mbar]", 1400));
- _flowTestSettings.Add(new SettingsModel("Max-Min range", "500 reads", 500));
- _flowTestSettings.Add(new SettingsModel("Max Min intervals", "300 reads", 300));
- _flowTestSettings.Add(new SettingsModel("Max error", "1.5%", 1.5));
- _flowTestSettings.Add(new SettingsModel("Take off 'Max-min' values (out of highest results)", "3", 3));
+ _flowTestSettings.Add(new SettingsModel(AnalyzerSettingsEnum.FlowPBUPassFail, "4.5 sec"));
+ _flowTestSettings.Add(new SettingsModel(AnalyzerSettingsEnum.ExcludeAnalysis, "1800 reads"));
+ _flowTestSettings.Add(new SettingsModel(AnalyzerSettingsEnum.AvgMinValue, "1400-1850 [mbar]", true));
+ _flowTestSettings.Add(new SettingsModel(AnalyzerSettingsEnum.MaxMinRange, "500 reads"));
+ _flowTestSettings.Add(new SettingsModel(AnalyzerSettingsEnum.MaxMinIntervals, "300 reads"));
+ _flowTestSettings.Add(new SettingsModel(AnalyzerSettingsEnum.MaxError, "1.5%"));
+ _flowTestSettings.Add(new SettingsModel(AnalyzerSettingsEnum.TakeOffMaxMin, "3"));
+
+ _flowTestSettings.ToList().ForEach(x => x.SettingValueEvent += new EventHandler(OnSettingValueChanged));
+ }
+
+ private void OnSettingValueChanged(object sender, EventArgs e)
+ {
+ if(sender is SettingsModel)
+ {
+ SettingsModel settingModel = sender as SettingsModel;
+ if(settingModel.IsRangeVisible)
+ {
+ changedValues[AnalyzerSettingsEnum.AvgMinValue] = settingModel.MinRangeValue;
+ changedValues[AnalyzerSettingsEnum.AvgMaxValue] = settingModel.MaxRangeValue;
+ }
+ else
+ changedValues[settingModel._enumName] = settingModel.PropertyValue;
+ }
+ }
+
+ public Dictionary<AnalyzerSettingsEnum, double> GetChanges()
+ {
+ return changedValues;
+ }
+
+ public void Dispose()
+ {
+ _PBUSettings.ToList().ForEach(x => x.SettingValueEvent -= OnSettingValueChanged);
+ _flowTestSettings.ToList().ForEach(x => x.SettingValueEvent -= OnSettingValueChanged);
}
}
}