diff options
| author | Roy Ben Shabat <Roy.mail.net@gmail.com> | 2020-08-25 17:50:22 +0300 |
|---|---|---|
| committer | Roy Ben Shabat <Roy.mail.net@gmail.com> | 2020-08-25 17:50:22 +0300 |
| commit | 9bc0807514a69d97fceab11d77bee02aff4eb3d9 (patch) | |
| tree | 2c5ad002ab84443945943adc2ab531ce6fccda22 /Software/Visual_Studio | |
| parent | 26b6bf34090634edf23ed5ed1785560c024da02c (diff) | |
| parent | 642dbff4c449d268d18ec4ca7f2ff267876dce14 (diff) | |
| download | Tango-9bc0807514a69d97fceab11d77bee02aff4eb3d9.tar.gz Tango-9bc0807514a69d97fceab11d77bee02aff4eb3d9.zip | |
Merge branch 'master' of https://twinetfs.visualstudio.com/Tango/_git/Tango
Diffstat (limited to 'Software/Visual_Studio')
44 files changed, 2170 insertions, 1613 deletions
diff --git a/Software/Visual_Studio/Azure/Tango.AzureUtils.UI/Controls/WebAppPropertiesControl.xaml.cs b/Software/Visual_Studio/Azure/Tango.AzureUtils.UI/Controls/WebAppPropertiesControl.xaml.cs index 129550d14..aab9361f8 100644 --- a/Software/Visual_Studio/Azure/Tango.AzureUtils.UI/Controls/WebAppPropertiesControl.xaml.cs +++ b/Software/Visual_Studio/Azure/Tango.AzureUtils.UI/Controls/WebAppPropertiesControl.xaml.cs @@ -1,6 +1,7 @@ using Microsoft.Azure.Management.AppService.Fluent; using System; using System.Collections.Generic; +using System.Diagnostics; using System.Linq; using System.Text; using System.Threading.Tasks; @@ -99,6 +100,11 @@ namespace Tango.AzureUtils.UI.Controls { IsBusy = true; + TangoVersion = null; + MachineStudioVersion = null; + FseVersion = null; + MachineServiceVersion = null; + HostNames = app.HostNames.Select(x => x).ToList(); Settings = await app.GetMachineServiceSettingsAsync(false); @@ -112,7 +118,10 @@ namespace Tango.AzureUtils.UI.Controls FtpManager ftpManager = new FtpManager(azure); MachineServiceVersion = await ftpManager.GetMachineServiceVersion(app); } - catch { } + catch (Exception ex) + { + Debug.WriteLine(ex); + } finally { IsBusy = false; diff --git a/Software/Visual_Studio/ColorLib/Tango.ColorLib_v4/ColorCalibrator.cpp b/Software/Visual_Studio/ColorLib/Tango.ColorLib_v4/ColorCalibrator.cpp index 2f53f4ae2..3d66f2d1e 100644 --- a/Software/Visual_Studio/ColorLib/Tango.ColorLib_v4/ColorCalibrator.cpp +++ b/Software/Visual_Studio/ColorLib/Tango.ColorLib_v4/ColorCalibrator.cpp @@ -182,7 +182,7 @@ void Tango::ColorLib::ColorCalibrator::InitData(const CalibrationMeasurement** m m_targetVal[1] = targeta; m_targetVal[2] = targetb; - int m_CalIndex = 0; + m_CalIndex = 0; if (m_inkChannel == 2) m_CalIndex = 2; } @@ -395,7 +395,7 @@ void Tango::ColorLib::ColorCalibrator::LinearizationInitData(const Linearizatio m_targetVal[1] = targeta; m_targetVal[2] = targetb; - int m_CalIndex = 0; + m_CalIndex = 0; if (m_inkChannel == 2) m_CalIndex = 2; } diff --git a/Software/Visual_Studio/ColorLib/Tango.ColorLib_v4/ColorConverter.cpp b/Software/Visual_Studio/ColorLib/Tango.ColorLib_v4/ColorConverter.cpp index 595d7f428..096d85bce 100644 --- a/Software/Visual_Studio/ColorLib/Tango.ColorLib_v4/ColorConverter.cpp +++ b/Software/Visual_Studio/ColorLib/Tango.ColorLib_v4/ColorConverter.cpp @@ -1,4 +1,3 @@ -#define _CRTDBG_MAP_ALLOC #include "ColorConverter.h" #include "ColorConvert.h" #include "CalibrationPoint.pb-c.h" @@ -29,7 +28,7 @@ #include "GradientOutputStop.pb-c.h" #include "LiquidVolume.pb-c.h" - +/*#define _CRTDBG_MAP_ALLOC #include <stdlib.h> #include <crtdbg.h> #include <cstdlib> @@ -40,7 +39,7 @@ // allocations to be of _CLIENT_BLOCK type #else #define DBG_NEW new -#endif +#endif */ #define dL 2.0 #define dC 2.0 @@ -60,53 +59,20 @@ #define GradientEndThr 0.95 -Tango::ColorLib::ColorConverter::ColorConverter() : m_A2BTransform(NULL), m_B2ATransform(NULL), -m_GBD(NULL), m_A2BRTransform(NULL), m_B2ARTransform(NULL), -m_GBDR(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_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_TableVersion(1) -//m_ProcessRangesMinInkUptake(NULL),m_ProcessRangesMinP(NULL), -//m_ProcessRangesMaxInkUptake(NULL) +Tango::ColorLib::ColorConverter::ColorConverter() : + m_CalibCurves(NULL), m_Conv02(NULL), +m_maxNlPerCM(NULL), +m_nInks(0), m_nVolumes(0), + m_GradStops(NULL), m_nGradStops(0), m_colortable(NULL), m_ProcessRangesMaxP(NULL), + m_nProcessRanges(0), m_NormGamutRegionMaxLim(NULL) { m_whitepointLab.Set(-1, -1, -1); m_whitepointXYZ_Strip.Set(-1, -1, -1); - m_whitepointXYZ_CT.Set(-1, -1, -1); + m_WP.Set(-1, -1, -1); } Tango::ColorLib::ColorConverter::~ColorConverter() { - if (m_A2BTransform != NULL) - { - delete m_A2BTransform; - m_A2BTransform = NULL; - } - if (m_B2ATransform != NULL) - { - delete m_B2ATransform; - m_B2ATransform = NULL; - } - if (m_GBD != NULL) - { - delete m_GBD; - m_GBD = NULL; - } - if (m_A2BRTransform != NULL) - { - delete m_A2BRTransform; - m_A2BRTransform = NULL; - } - if (m_B2ARTransform != NULL) - { - delete m_B2ARTransform; - m_B2ARTransform = NULL; - } - if (m_GBDR != NULL) - { - delete m_GBDR; - m_GBDR = NULL; - } if (m_Conv02 != NULL) { delete m_Conv02; @@ -117,34 +83,26 @@ Tango::ColorLib::ColorConverter::~ColorConverter() delete[] m_CalibCurves; m_CalibCurves = NULL; } - if (m_GamutRegionMaxLim != NULL) + if(m_GradStops != NULL) { - delete[] m_GamutRegionMaxLim; - m_GamutRegionMaxLim = NULL; + delete [] m_GradStops; + m_GradStops = NULL; } - if (m_LinCurves != NULL) + if (m_colortable != NULL) { - delete m_LinCurves; - m_LinCurves = NULL; + delete m_colortable; + m_colortable = NULL; + } + if (m_NormGamutRegionMaxLim != NULL) + { + delete[] m_NormGamutRegionMaxLim; + m_NormGamutRegionMaxLim = NULL; } if (m_ProcessRangesMaxP != NULL) { delete[] m_ProcessRangesMaxP; m_ProcessRangesMaxP = NULL; } - if (m_GradStops != NULL) - { - for (int i = 0; i < sizeof(m_GradStops); ++i) - { - if(m_GradStops[i].Volume != NULL) - { - delete[] m_GradStops[i].Volume; - m_GradStops[i].Volume = NULL; - } - } - delete[] m_GradStops; - m_GradStops = NULL; - } /* if (m_ProcessRangesMinP != NULL) { delete[] m_ProcessRangesMinP; @@ -160,11 +118,6 @@ Tango::ColorLib::ColorConverter::~ColorConverter() delete[] m_ProcessRangesMinInkUptake; m_ProcessRangesMinInkUptake = NULL; }*/ -#ifdef _DEBUG - _CrtSetReportMode(_CRT_ERROR, _CRTDBG_MODE_DEBUG); - _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_DEBUG); - _CrtDumpMemoryLeaks(); -#endif } void Tango::ColorLib::ColorConverter::ProcessHiveNeighbors(ConversionInput *conversionInput, VectorXd Lab, @@ -186,6 +139,7 @@ void Tango::ColorLib::ColorConverter::ProcessHiveNeighbors(ConversionInput *conv hue = 0.0; else hue = atan2(Lab(2), Lab(1)); + double d1 = dC; double de = 0; MatrixXd Lab1(nHive, 3); @@ -243,7 +197,6 @@ void Tango::ColorLib::ColorConverter::ProcessHiveNeighbors(ConversionInput *conv //double *tmpRGB = DBG_NEW double[3]; double *InkOut = new double[m_nInks]; //double *InkOut = DBG_NEW double[m_nInks]; - int *GamutRegion = new int[nHive + 1]; //int *GamutRegion = DBG_NEW int[nHive + 1]; double *Lab1P = new double[3]; @@ -254,7 +207,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]; + double *InkOutP = new double[m_nInks]; bool InGamut = true; for (int i = 0; i < nHive; ++i) { @@ -271,19 +224,19 @@ void Tango::ColorLib::ColorConverter::ProcessHiveNeighbors(ConversionInput *conv */ // 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) + m_colortable->m_B2ATransform->evalLab2InkP(Lab1P, InkOut, GamutRegion[i]); //InkOut is in units of 16 bits + for (int i = 0; i <m_nInks; ++i) { - InkOut[i] *= m_NormFactor; - if (InkOut[i] <= m_GamutRegionMaxLim[0]) + InkOut[i] *= m_colortable->GetNormFactor(); + if (InkOut[i] <= m_NormGamutRegionMaxLim[0]) { - m_LinCurves->m_InterpCurves[i].Eval(InkOut[i] * 655.35, InkOut[i]); + m_colortable->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); + VectorXd NLInkOut(m_nInks); ConvertToNLInks(DoubleToVector(InkOut, m_nInks), NLInkOut); //Limit inks based on m_maxNlpercm @@ -483,9 +436,6 @@ void Tango::ColorLib::ColorConverter::ArrangeHiveData(MatrixXd LabHive, MatrixX } - - - void Tango::ColorLib::ColorConverter::fillVolume(OutputCoordinates *&outputCoords, VectorXd Volume) { int i = 0; @@ -542,8 +492,8 @@ void Tango::ColorLib::ColorConverter::readColorTransformations(ConversionInput* bool has_forwarddata = conversionInput->has_forwarddata; uint8_t *data = conversionInput->forwarddata.data; int nprocessranges = conversionInput->n_processranges; - readColorTables(has_forwarddata, data, nprocessranges); - + m_colortable->InitColorTables(has_forwarddata, data, nprocessranges); + SetNumberofInks(m_colortable->GetnA2BnSepOut()); } void Tango::ColorLib::ColorConverter::SetStripWhitepoint(double threadl, double threada, double threadb) @@ -557,296 +507,6 @@ void Tango::ColorLib::ColorConverter::SetStripWhitepoint(double threadl, double 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 (has_data) - { - //Read Header - CT_Header header = read_header(data, bytesread); - SetnGamutRegions((int)header.nGamutRegions); - SetTableVersion((int)header.Version[0]); - if (m_nGamutRegions != nprocessranges) - { - throw std::exception("Number of gamut regions in table does not match STRIP\0"); - return; - } - m_GamutRegionMaxLim = new double[m_nGamutRegions]; - for (int i = 0; i < m_nGamutRegions; ++i) - m_GamutRegionMaxLim[i] = header.GRegMaxLim[i]; - m_nProcessRanges = (int)(nprocessranges); - - /* for (int i = 0; i < m_nGamutRegions; ++i) - { - if (abs(m_GamutRegionMaxLim[i] - conversionInput->processranges[i]->maxinkuptake)> eps) - throw std::exception(" Gamut Region Limit does not match MaxInkUptake in STRIP\0"); - } - */ - if (header.GRegMaxLim != NULL) - { - delete[]header.GRegMaxLim; - header.GRegMaxLim = NULL; - } - - - uint32_t tmp; - uint8_t *buff =data; - tmp = conv.ByteToInt(buff, bytesread); - tag_count = (int)tmp; - bytesread += 4; - //read Tag Table - char **TagNames = new char*[tag_count]; - //char **TagNames = DBG_NEW char*[tag_count]; - int **TagSize = new int*[tag_count]; - //int **TagSize = DBG_NEW int*[tag_count]; - char *tmpC = new char[20]; - int n = 0; - int i, j; - for (i = 0; i < tag_count; ++i) - { - - //TagSize[i] = DBG_NEW int[3]; - tmp = conv.ByteToInt(buff, bytesread); - n = sizeof((char*)&tmp); - //tmpC = DBG_NEW char[n]; - conv.getchar(tmp, n, tmpC); - //TagNames[i] = DBG_NEW char[n]; - TagNames[i] = new char[n]; - for (j = 0; j < n; ++j) - TagNames[i][j] = tmpC[j]; - bytesread += 4; - TagSize[i] = new int[2]; - TagSize[i][0] = conv.ByteToInt(buff, bytesread); - bytesread += 4; - TagSize[i][1] = conv.ByteToInt(buff, bytesread); - bytesread += 4; - } - if(tmpC!=NULL) - { - delete[] tmpC; - tmpC = NULL; - } - - int *TList = new int[tag_count]; - //int *TList = DBG_NEW int[tag_count]; - for (int k = 0; k < tag_count; ++k) - { - if (strncmp(TagNames[k], "A2B ", 4) == 0) - TList[k] = A2B; - else if (strncmp(TagNames[k], "A2BR", 4) == 0) - TList[k] = A2BR; - else if (strncmp(TagNames[k], "B2A ", 4) == 0) - TList[k] = B2A; - else if (strncmp(TagNames[k], "B2AR ", 4) == 0) - TList[k] = B2AR; - else if (strncmp(TagNames[k], "wtpt", 4) == 0) - TList[k] = wtpt; - else if (strncmp(TagNames[k], "desc", 4) == 0) - TList[k] = desc; - else if (strncmp(TagNames[k], "gbd ", 4) == 0) - TList[k] = gbd; - else if (strncmp(TagNames[k], "gbdR", 4) == 0) - TList[k] = gbdR; - else if (strncmp(TagNames[k], "cprt", 4) == 0) - TList[k] = cprt; - else if (strncmp(TagNames[k], "lcrv", 4) == 0) - TList[k] = lcrv; - // else if (strncmp(TagNames[k], "GReg", 2) == 0) - // TList[k] = GReg; - else - throw std::exception("Unknown Tag in Color Tables"); - } - for (int k = 0; k < tag_count; ++k) - { - switch (TList[k]) - { - case A2B: - { - uint8_t *A2BLUT = &(data[TagSize[k][0]]); - int A2BLutsize = TagSize[k][1]; - m_A2BTransform = new ColorTransf(); - //m_A2BTransform = DBG_NEW ColorTransf(); - m_A2BTransform->InitData(A2BLUT, A2BLutsize); - break; - } - case A2BR: - { - uint8_t *A2BRLUT = &(data[TagSize[k][0]]); - int A2BRLutsize = TagSize[k][1]; - m_A2BRTransform = new ColorTransf(); - //m_A2BTransform = DBG_NEW ColorTransf(); - m_A2BRTransform->InitData(A2BRLUT, A2BRLutsize); - break; - } - case B2A: - { - uint8_t *B2ALUT = &(data[TagSize[k][0]]); - int B2ALutsize = TagSize[k][1]; - m_B2ATransform = new ColorTransf(); - //m_B2ATransform = DBG_NEW ColorTransf(); - m_B2ATransform->InitData(B2ALUT, B2ALutsize); - break; - } - case B2AR: - { - uint8_t *B2ARLUT = &(data[TagSize[k][0]]); - int B2ARLutsize = TagSize[k][1]; - m_B2ARTransform = new ColorTransf(); - //m_B2ATransform = DBG_NEW ColorTransf(); - m_B2ARTransform->InitData(B2ARLUT, B2ARLutsize); - break; - } - /* case GReg: - { - uint8_t *GRegLUT = &(conversionInput->forwarddata.data[TagSize[k][0]]); - int GRegLutsize = TagSize[k][1]; - m_GRegTransform = new ColorTransf(); - //m_B2ATransform = DBG_NEW ColorTransf(); - m_GRegTransform->InitData(GRegLUT, GRegLutsize); - break; - } */ - case gbd: - { - uint8_t *GBDList = &(data[TagSize[k][0]]); - m_GBD = new GBD(); - //m_GBD = DBG_NEW GBD(); - int GBDSize = TagSize[k][1]; - m_GBD->InitData(GBDList, GBDSize); - break; - } - case gbdR: - { - uint8_t *GBDRList = &(data[TagSize[k][0]]); - m_GBDR = new GBD(); - //m_GBD = DBG_NEW GBD(); - int GBDRSize = TagSize[k][1]; - m_GBDR->InitData(GBDRList, GBDRSize); - break; - } - case lcrv: - { - uint8_t *CurvesData = &(data[TagSize[k][0]]); - m_LinCurves = new Curves(); - int CurvesSize = TagSize[k][1]; - m_LinCurves->InitData(CurvesData, CurvesSize); - break; - } - case wtpt: - { - 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, data); - break; - } - case desc: - { - std::string textdescstr; - read_text_description_type(TagSize[k][0], TagSize[k][1], textdescstr, data); - break; - } - default: - { - throw std::exception("Unresolved Tag in Color Tables"); - return; - } - - } - } - if (TagNames != NULL) - { - for (int i = 0; i < sizeof(TagNames); ++i) - { - delete[] TagNames[i]; - TagNames[i] = NULL; - } - delete[]TagNames; - TagNames = NULL; - } - if (TagSize != NULL) - { - for (int i = 0; i < sizeof(TagSize); ++i) - { - delete[] TagSize[i]; - TagSize[i] = NULL; - } - delete[]TagSize; - TagSize = NULL; - } - if (TList != NULL) - { - delete[] TList; - TList = NULL; - } - - if (header.ColorSpace != NULL) - { - delete header.ColorSpace; - header.ColorSpace = NULL; - } - if (header.ConnectionSpace != NULL) - { - delete header.ConnectionSpace; - header.ConnectionSpace = NULL; - } - if (header.DeviceManufacturer != NULL) - { - delete header.DeviceManufacturer; - header.DeviceManufacturer = NULL; - } - } - - - //Verify all relevant tags had been read - if (m_A2BTransform == NULL) - { - throw std::exception("Missing Forward Transform in Color Tables"); - return; - } - if (m_A2BRTransform == NULL) - { - throw std::exception("Missing Reduced Forward Transform in Color Tables"); - return; - } - if (m_B2ATransform == NULL) - { - throw std::exception("Missing Inverse Transform in Color Tables"); - return; - } - if (m_B2ARTransform == NULL) - { - throw std::exception("Missing Reduced Inverse Transform in Color Tables"); - return; - } - if (m_GBD == NULL) - { - throw std::exception("Missing Gamut Boundary Descriptor in Color Tables"); - return; - } - if (m_GBDR == NULL) - { - throw std::exception("Missing Reduced Gamut Boundary Descriptor in Color Tables"); - return; - } - if ((m_whitepointXYZ_CT.Get_x() == -1) && (m_whitepointXYZ_CT.Get_y() == -1) && (m_whitepointXYZ_CT.Get_z() == -1)) - { - throw std::exception("Missing Whitepoint in Color Tables"); - return; - } - if (m_LinCurves == NULL) - { - throw std::exception("Missing Linear Curves in Color Tables"); - return; - } - return; // OK -} void Tango::ColorLib::ColorConverter::readCalibrationTables(InputLiquid **inputliquid, int n_inputliquid) @@ -926,20 +586,133 @@ void Tango::ColorLib::ColorConverter::SetCalibData(CalibrationData *calibrationD return; } -void Tango::ColorLib::ColorConverter::ConvertColorToLinearInks(InputCoordinates* inputcoordinates, ColorSpace colorspace, +void Tango::ColorLib::ColorConverter:: ConvertLabColorToLinearInks(InputCoordinates* inputcoordinates, VectorXd &InkOut, VectorXd &RGBOut, - VectorXd &LabOut, int &GamutRegion, bool &InGamut) + VectorXd &LabOut, int &GamutRegion, bool &InGamut, SURROUND sur, CAM02CS CS) { - size_t nInks = 0; + // Basic assumption: Lab data has the same whitepoint as the STRIP thread. + //The workflow is a follows: + //1. Convert Lab to Relative colorimetric. check if there is a match between STRIP and Color Tables + //2. Convert Lab to Inks (B2A tables), Inks to Volume + //3. Map the Lab value onto the gamut surface, if it is out of gamut + //4. Convert Lab to Absolute colorimetric taking into account the Strip and CT whitepoints + //5. Use the Relative Colorimetric Lab to obtain RGB + double *LabIn = new double[3]; + //double *LabIn = DBG_NEW double[3]; + 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 = DBG_NEW double[3]; + // 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) + { + 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_Strip); //LabInFinal2 is in Relative Colorimetric Space + InGamut = IsInGamut(LabInFinal2, sur, CS, LabOnGamut); + LimitLab(LabOnGamut); - C_RGB_XYZ_Lab DataLab; - SURROUND sur = m_Conv02->getSurround(); - CAM02CS CS = m_Conv02->getCAM02CS(); - switch (colorspace) + //convert to Inks + double *InkOutP = new double[m_nInks]; + //double *InkOutP = DBG_NEW double[m_nB2AnSepOut]; + m_colortable->m_B2ATransform->evalLab2InkP(LabOnGamut, InkOutP, GamutRegion); //InkOut is in units of 16 bits + //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_GamutRegionMaxLim[0] range + for (int i = 0; i < m_nInks; ++i) { - case (COLOR_SPACE__RGB): + InkOutP[i] *= m_colortable->GetNormFactor(); + if (InkOutP[i] <= m_NormGamutRegionMaxLim[0]) + { + m_colortable->m_LinCurves->m_InterpCurves[i].Eval(InkOutP[i] * 655.35, InkOutP[i]); + InkOutP[i] /= 655.35; + } + } + InkOut = DoubleToVector(InkOutP, m_nInks); + double *LabOutFinal = new double[3]; + //double *LabOutFinal = DBG_NEW double[3]; + for (int i = 0; i < 3; ++i) + 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_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 + double *RGBOutP = new double[3]; + // double *RGBOutP = DBG_NEW double[3]; + //Use Relative colorimetric to get RGB + CConvertD65.LabtoRGB(LabOnGamut, RGBOutP); + //CConvertD65.LabtoRGB(LabIn, RGBOutP); + RGBOut = DoubleToVector(RGBOutP, 3); + if (LabOnGamut != NULL) { - // Basic assumption: if data is given in RGB space, conversion should be in relative colorimetric, + delete[] LabOnGamut; + LabOnGamut = NULL; + } + if (InkOutP != NULL) + { + delete[] InkOutP; + InkOutP = NULL; + } + if (LabIn != NULL) + { + delete[] LabIn; + LabIn = NULL; + } + /* if (LabInFinal1 != NULL) + { + delete[]LabInFinal1; + LabInFinal1 = NULL; + } + */ + if (LabInFinal2 != NULL) + { + delete[]LabInFinal2; + LabInFinal2 = NULL; + } + if (LabOutFinal != NULL) + { + delete[]LabOutFinal; + LabOutFinal = NULL; + } + + if (RGBOutP != NULL) + { + delete[] RGBOutP; + RGBOutP = NULL; + } +} + + +void Tango::ColorLib::ColorConverter::ConvertRGBColorToLinearInks(InputCoordinates* inputcoordinates, + VectorXd &InkOut, VectorXd &RGBOut, + VectorXd &LabOut, int &GamutRegion, bool &InGamut, SURROUND sur, CAM02CS CS) +{ + // 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 //The workflow is a follows: @@ -949,263 +722,145 @@ void Tango::ColorLib::ColorConverter::ConvertColorToLinearInks(InputCoordinates* //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) = inputcoordinates->red; - RGBOut(1) = inputcoordinates->green; - RGBOut(2) = inputcoordinates->blue; - //convert to Lab - ColorConvert CConvertD65(D65, D65); //Destination, source - double *LabIn = new double[3]; - double *RGBOutP = new double[3]; - //double *LabIn = DBG_NEW double[3]; - //double *RGBOutP = DBG_NEW double[3]; - VectorToDouble(RGBOut, RGBOutP); - //RGB to Lab - CConvertD65.RGBtoLab(RGBOutP, LabIn); //Values are in Relative Colorimetric, D65 - LimitLab(LabIn); - //Is In Gamut? - double *LabInFinal = new double[3]; - double *LabOnGamut = new double[3]; - InGamut = IsInGamut(LabIn, sur, CS, LabOnGamut); - LimitLab(LabOnGamut); + 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]; + double *RGBOutP = new double[3]; + //double *LabIn = DBG_NEW double[3]; + //double *RGBOutP = DBG_NEW double[3]; + VectorToDouble(RGBOut, RGBOutP); + //RGB to Lab + CConvertD65.RGBtoLab(RGBOutP, LabIn); //Values are in Relative Colorimetric, D65 + LimitLab(LabIn); + //Is In Gamut? + double *LabInFinal = new double[3]; + double *LabOnGamut = new double[3]; + InGamut = IsInGamut(LabIn, sur, CS, LabOnGamut); + LimitLab(LabOnGamut); - //convert to inks - int GamutRegion; - 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 inthe [0-100] interval + //convert to inks - //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 - //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); + double *InkOutP = new double[m_nInks]; + //double *InkOutP = DBG_NEW double[m_nB2AnSepOut]; + //LabInFinal is in Relative Colorimetric, just like the Color Tables + m_colortable->m_B2ATransform->evalLab2InkP(LabOnGamut, InkOutP, GamutRegion); //InkOut is inthe [0-100] interval - //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_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]; - //double *RGBOutP1 = DBG_NEW double[3]; - CConvertD65.LabtoRGB(LabOnGamut, RGBOutP1); - //CConvertD65.LabtoRGB(LabInP, RGBOutP1); - RGBOut = DoubleToVector(RGBOutP1, 3); - if (LabOnGamut != NULL) - { - delete[] LabOnGamut; - LabOnGamut = NULL; - } - if (InkOutP != NULL) - { - delete[] InkOutP; - InkOutP = NULL; - } - if (LabIn != NULL) - { - delete[] LabIn; - LabIn = NULL; - } - if (RGBOutP != NULL) - { - delete[] RGBOutP; - RGBOutP = NULL; - } - if (RGBOutP1 != NULL) - { - delete[] RGBOutP1; - RGBOutP1 = NULL; - } - if (LabInFinal != NULL) - { - delete[] LabInFinal; - LabInFinal = NULL; - } - break; - } - case (COLOR_SPACE__LAB): + //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 + //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_nInks; ++i) { - // Basic assumption: Lab data has the same whitepoint as the STRIP thread. - //The workflow is a follows: - //1. Convert Lab to Relative colorimetric. check if there is a match between STRIP and Color Tables - //2. Convert Lab to Inks (B2A tables), Inks to Volume - //3. Map the Lab value onto the gamut surface, if it is out of gamut - //4. Convert Lab to Absolute colorimetric taking into account the Strip and CT whitepoints - //5. Use the Relative Colorimetric Lab to obtain RGB - double *LabIn = new double[3]; - //double *LabIn = DBG_NEW double[3]; - 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 = DBG_NEW double[3]; - // 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) + InkOutP[i] *= m_colortable->GetNormFactor(); + if (InkOutP[i] <= m_NormGamutRegionMaxLim[0]) { - CConvertD65.ChangeWP(LabInFinal1, LabInFinal1, m_whitepointXYZ_CT, m_whitepointXYZ_Strip); //to Color Tables - for (int i = 0; i < 3; ++i) - LabIn[i] = LabInFinal1[i]; + m_colortable->m_LinCurves->m_InterpCurves[i].Eval(InkOutP[i] * 655.35, InkOutP[i]); + InkOutP[i] /= 655.35; } - */ - 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_Strip); //LabInFinal2 is in Relative Colorimetric Space - InGamut = IsInGamut(LabInFinal2, sur, CS, LabOnGamut); - LimitLab(LabOnGamut); + } + InkOut = DoubleToVector(InkOutP, m_nInks); - //convert to Inks - int GamutRegion; - double *InkOutP = new double[m_nB2AnSepOut]; - //double *InkOutP = DBG_NEW double[m_nB2AnSepOut]; - m_B2ATransform->evalLab2InkP(LabOnGamut, InkOutP, GamutRegion); //InkOut is in units of 16 bits - //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_GamutRegionMaxLim[0] range - 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); - double *LabOutFinal = new double[3]; - //double *LabOutFinal = DBG_NEW double[3]; - for (int i = 0; i < 3; ++i) - 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_Strip, m_WP); + //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_Strip, m_WP); + //check if the thread to be used is the same as the one in the color tables /* - if (m_AdaptWP) - { - CConvertD65.ChangeWP(LabOutFinal, LabOutFinal, m_whitepointXYZ_Strip, m_whitepointXYZ_CT); - } - */ - LabOut = DoubleToVector(LabOutFinal, 3); - CConvertD65.SetReferenceWhite(D65); - //Convert to RGB - double *RGBOutP = new double[3]; - // double *RGBOutP = DBG_NEW double[3]; - //Use Relative colorimetric to get RGB - CConvertD65.LabtoRGB(LabOnGamut, RGBOutP); - //CConvertD65.LabtoRGB(LabIn, RGBOutP); - RGBOut = DoubleToVector(RGBOutP, 3); - if (LabOnGamut != NULL) - { - delete[] LabOnGamut; - LabOnGamut = NULL; - } - if (InkOutP != NULL) - { - delete[] InkOutP; - InkOutP = NULL; - } - if (LabIn != NULL) - { - delete[] LabIn; - LabIn = NULL; - } -/* if (LabInFinal1 != NULL) - { - delete[]LabInFinal1; - LabInFinal1 = NULL; - } - */ - if (LabInFinal2 != NULL) - { - delete[]LabInFinal2; - LabInFinal2 = NULL; - } - if (LabOutFinal != NULL) - { - delete[]LabOutFinal; - LabOutFinal = NULL; - } - - if (RGBOutP != NULL) - { - delete[] RGBOutP; - RGBOutP = NULL; - } - break; + 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]; + //double *RGBOutP1 = DBG_NEW double[3]; + CConvertD65.LabtoRGB(LabOnGamut, RGBOutP1); + //CConvertD65.LabtoRGB(LabInP, RGBOutP1); + RGBOut = DoubleToVector(RGBOutP1, 3); + if (LabOnGamut != NULL) + { + delete[] LabOnGamut; + LabOnGamut = NULL; + } + if (InkOutP != NULL) + { + delete[] InkOutP; + InkOutP = NULL; + } + if (LabIn != NULL) + { + delete[] LabIn; + LabIn = NULL; + } + if (RGBOutP != NULL) + { + delete[] RGBOutP; + RGBOutP = NULL; + } + if (RGBOutP1 != NULL) + { + delete[] RGBOutP1; + RGBOutP1 = NULL; + } + if (LabInFinal != NULL) + { + delete[] LabInFinal; + LabInFinal = NULL; + } } - case(COLOR_SPACE__CMYK): - {//no conversion +void Tango::ColorLib::ColorConverter::ConvertCMYKColorToLinearInks(InputCoordinates* inputcoordinates, + VectorXd &InkOut, VectorXd &RGBOut, + VectorXd &LabOut, int &GamutRegion, bool &InGamut, SURROUND sur, CAM02CS CS) +{ + //no conversion //missing from structure light inks or special colors // just convert Lab for rgb display - double *outData = new double[m_nA2BnSepIn]; - //double *outData = DBG_NEW double[m_nA2BnSepIn]; - size_t CountSep = 0; - 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) - { - //mismatch between table and sent data - throw std::exception("Mismatch between table and sent data"); - return; - } - //Convert to RGB - int GamutRegion = 0; - double *InkOutP = new double[m_nA2BnSepIn]; - //double *InkOutP = DBG_NEW double[m_nA2BnSepIn]; - for (int i = 0; i < m_nA2BnSepIn; ++i) - InkOutP[i] = outData[i]; - double *LabOutP = new double[3]; - //double *LabOutP = DBG_NEW double[3]; - m_A2BTransform->evalInkP2Lab(InkOutP, LabOutP, GamutRegion); - InkOut = DoubleToVector(InkOutP, m_nInks); - //LabOut is in relative colorimetric - ColorConvert CConvertD65(D65, D65); - double *LabOutFinal1 = new double[3]; - //double *LabOutFinal1 = DBG_NEW double[3]; - for (int i = 0; i < 3; ++i) - LabOutFinal1[i] = LabOutP[i]; - double *LabOutFinal2 = new double[3]; - //double *LabOutFinal2 = DBG_NEW double[3]; - for (int i = 0; i < 3; ++i) - LabOutFinal2[i] = LabOutP[i]; - InGamut = true; - //Check if white points match + double *outData = new double[m_nInks]; + //double *outData = DBG_NEW double[m_nA2BnSepIn]; + size_t CountSep = 0; + 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_nInks) + { + //mismatch between table and sent data + throw std::exception("Mismatch between table and sent data"); + return; + } + //Convert to RGB + double *InkOutP = new double[m_nInks]; + //double *InkOutP = DBG_NEW double[m_nA2BnSepIn]; + for (int i = 0; i < m_nInks; ++i) + InkOutP[i] = outData[i]; + double *LabOutP = new double[3]; + //double *LabOutP = DBG_NEW double[3]; + m_colortable->m_A2BTransform->evalInkP2Lab(InkOutP, LabOutP, GamutRegion); + InkOut = DoubleToVector(InkOutP, m_nInks); + //LabOut is in relative colorimetric + ColorConvert CConvertD65(D65, D65); + double *LabOutFinal1 = new double[3]; + //double *LabOutFinal1 = DBG_NEW double[3]; + for (int i = 0; i < 3; ++i) + LabOutFinal1[i] = LabOutP[i]; + double *LabOutFinal2 = new double[3]; + //double *LabOutFinal2 = DBG_NEW double[3]; + for (int i = 0; i < 3; ++i) + LabOutFinal2[i] = LabOutP[i]; + InGamut = true; + //Check if white points match // CConvertD65.ChangeWP(LabOutFinal1, LabOutFinal1, m_whitepointXYZ_CT, m_WP); //To Absolute - CConvertD65.ChangeWP(LabOutFinal1, LabOutFinal1, m_whitepointXYZ_Strip, 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); @@ -1213,45 +868,75 @@ void Tango::ColorLib::ColorConverter::ConvertColorToLinearInks(InputCoordinates* LabOutFinal1[i] = LabOutFinal2[i]; } */ - LabOut = DoubleToVector(LabOutFinal1, 3); - CConvertD65.SetReferenceWhite(D65); - //Get RGB - double *RGBOutP = new double[3]; - //double *RGBOutP = DBG_NEW double[3]; - CConvertD65.LabtoRGB(LabOutP, RGBOutP); - //CConvertD65.LabtoRGB(LabOutP, RGBOutP); - RGBOut = DoubleToVector(RGBOutP, 3); + LabOut = DoubleToVector(LabOutFinal1, 3); + CConvertD65.SetReferenceWhite(D65); + //Get RGB + double *RGBOutP = new double[3]; + //double *RGBOutP = DBG_NEW double[3]; + CConvertD65.LabtoRGB(LabOutP, RGBOutP); + //CConvertD65.LabtoRGB(LabOutP, RGBOutP); + RGBOut = DoubleToVector(RGBOutP, 3); - if (outData != NULL) - { - delete[] outData; - outData = NULL; - } - if (LabOutP != NULL) - { - delete[] LabOutP; - LabOutP = NULL; - } - if (InkOutP != NULL) - { - delete[] InkOutP; - InkOutP = NULL; - } - if (RGBOutP != NULL) - { - delete[] RGBOutP; - RGBOutP = NULL; - } - if (LabOutFinal1 != NULL) - { - delete[] LabOutFinal1; - LabOutFinal1 = NULL; - } - if (LabOutFinal2 != NULL) - { - delete[] LabOutFinal2; - LabOutFinal2 = NULL; - } + if (outData != NULL) + { + delete[] outData; + outData = NULL; + } + if (LabOutP != NULL) + { + delete[] LabOutP; + LabOutP = NULL; + } + if (InkOutP != NULL) + { + delete[] InkOutP; + InkOutP = NULL; + } + if (RGBOutP != NULL) + { + delete[] RGBOutP; + RGBOutP = NULL; + } + if (LabOutFinal1 != NULL) + { + delete[] LabOutFinal1; + LabOutFinal1 = NULL; + } + if (LabOutFinal2 != NULL) + { + delete[] LabOutFinal2; + LabOutFinal2 = NULL; + } +} +void Tango::ColorLib::ColorConverter::ConvertColorToLinearInks(InputCoordinates* inputcoordinates, ColorSpace colorspace, + VectorXd &InkOut, VectorXd &RGBOut, + VectorXd &LabOut, int &GamutRegion, bool &InGamut) +{ + size_t nInks = 0; + + C_RGB_XYZ_Lab DataLab; + SURROUND sur = m_Conv02->getSurround(); + CAM02CS CS = m_Conv02->getCAM02CS(); + switch (colorspace) + { + case (COLOR_SPACE__RGB): + { + ConvertRGBColorToLinearInks(inputcoordinates, + InkOut, RGBOut, LabOut, GamutRegion, InGamut, sur, CS); + break; + } + case (COLOR_SPACE__LAB): + { + ConvertLabColorToLinearInks(inputcoordinates, + InkOut, RGBOut, LabOut, GamutRegion, InGamut, sur, CS); + break; + } + + case(COLOR_SPACE__CMYK): + { + ConvertCMYKColorToLinearInks(inputcoordinates, + InkOut, RGBOut, LabOut, GamutRegion, InGamut, sur, CS); + break; } case(COLOR_SPACE__Catalog): @@ -1284,7 +969,7 @@ void Tango::ColorLib::ColorConverter::ConvertToNLInks(VectorXd InkIn, VectorXd { for (int i = 0; i < m_nVolumes; ++i) { - if (InkIn(i) <= m_GamutRegionMaxLim[0]) + if (InkIn(i) <= m_NormGamutRegionMaxLim[0]) m_CalibCurves[i].m_InvLinearInterp->Eval(InkIn(i), InkOut(i)); else InkOut(i) = InkIn(i); @@ -1403,7 +1088,7 @@ void Tango::ColorLib::ColorConverter::NLInkPToVolume(VectorXd NLInk, VectorXd &V RVolNorm(i) = round(Volume(i)*ROUNDINGTol) / ROUNDINGTol; RsumNorm += RVolNorm(i); } - if (RsumNorm > m_GamutRegionMaxLim[m_nProcessRanges - 1] || abs(sumNorm - RsumNorm) >= 1 / ROUNDINGTol) + if (RsumNorm > m_NormGamutRegionMaxLim[m_nProcessRanges - 1] || abs(sumNorm - RsumNorm) >= 1 / ROUNDINGTol) { VectorXd dd(m_nInks); double maxdd = -1; @@ -1533,22 +1218,22 @@ void Tango::ColorLib::ColorConverter::ConvertVolumeToRGBDisplay(InputCoordinates for (int i = 0; i < m_nVolumes; ++i) Volume(i) = inputcoordinates->inputliquids[i]->volume; //volume is given in % - GamutRegion = GetGamutRegion(Volume, m_GamutRegionMaxLim); + GamutRegion = GetGamutRegion(Volume, m_NormGamutRegionMaxLim); VolumeToNLInkP(Volume, NLInkP); //Limit Inks - double *InkOutP = new double[m_nA2BnSepIn]; + double *InkOutP = new double[m_nInks]; VectorToDouble(NLInkP, InkOutP); //for (int i = 0; i < m_nA2BnSepIn; ++i) // InkOutP[i] = NLInkP(i); - double *LinInkP = new double[m_nA2BnSepIn]; + double *LinInkP = new double[m_nInks]; //Reflect the Calibration Curves of the thread in Catalog Items if (colorspace == COLOR_SPACE__Catalog) { - for (int i = 0; i < m_nB2AnSepOut; ++i) + for (int i = 0; i < m_nInks; ++i) { - if (NLInkP(i) <= m_GamutRegionMaxLim[0]) + if (NLInkP(i) <= m_NormGamutRegionMaxLim[0]) { - m_LinCurves->m_InterpCurves[i].Eval(InkOutP[i] * 655.35, InkOutP[i]); + m_colortable->m_LinCurves->m_InterpCurves[i].Eval(InkOutP[i] * 655.35, InkOutP[i]); InkOutP[i] /= 655.35; NLInkP(i) = InkOutP[i]; } @@ -1556,7 +1241,7 @@ void Tango::ColorLib::ColorConverter::ConvertVolumeToRGBDisplay(InputCoordinates } for (int i = 0; i < (int)(m_nVolumes); ++i) { - if (NLInkP(i) <= m_GamutRegionMaxLim[0]) + if (NLInkP(i) <= m_NormGamutRegionMaxLim[0]) { m_CalibCurves[i].m_InvLinearInterp->Eval(InkOutP[i], InkOutP[i]); NLInkP(i) = InkOutP[i]; @@ -1577,15 +1262,15 @@ void Tango::ColorLib::ColorConverter::ConvertVolumeToRGBDisplay(InputCoordinates //Convert to RGB //GamutRegion = 0; //Convert to Lab - - double *LabOutP = new double[m_nA2BnSepOut]; + + double *LabOutP = new double[3]; //double *InkOutP = DBG_NEW double[m_nA2BnSepIn]; //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] *= m_InvNormFactor; + for (int i = 0; i < m_nInks; ++i) + InkOutP[i] *= m_colortable->GetInverseNormFactor(); - m_A2BTransform->evalInkP2Lab(InkOutP, LabOutP, GamutRegion); + m_colortable->m_A2BTransform->evalInkP2Lab(InkOutP, LabOutP, GamutRegion); //LabOutP is in Relative Colorimetric ColorConvert CConvertD65(D65, D65); @@ -1733,7 +1418,13 @@ size_t Tango::ColorLib::ColorConverter::Convert(uint8_t * input_buffer, size_t i m_WP.Set(0.9505, 1.00, 1.0888); //D65 //count number if inks // int numofInks = CountNumberofInks(conversionInput); + m_colortable = new ColorTable(); readColorTransformations(conversionInput); + m_nProcessRanges = conversionInput->n_processranges; + m_NormGamutRegionMaxLim = new double[m_nProcessRanges]; + double *tmpVal = m_colortable->GetNormGamutRegionMaxLim(); + for (int i = 0; i < m_nProcessRanges; ++i) + m_NormGamutRegionMaxLim[i] = tmpVal[i]; //read calibration tables and store them in m_CalibCurves InputLiquid **inputliquids = conversionInput->inputcoordinates->inputliquids; int n_inputliquids = conversionInput->inputcoordinates->n_inputliquids; @@ -1746,16 +1437,11 @@ size_t Tango::ColorLib::ColorConverter::Convert(uint8_t * input_buffer, size_t i if(m_Conv02 ==NULL) m_Conv02 = new ColorConvert(IL, IL, Y_b, L_A, sur, CS); //m_Conv02 = DBG_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(); - if (numofInks != m_nB2AnSepOut) + if (numofInks != m_nInks) throw std::exception("Number of available inks does not match ink tables\0"); //Tables have been filled @@ -1766,25 +1452,20 @@ size_t Tango::ColorLib::ColorConverter::Convert(uint8_t * input_buffer, size_t i { m_ProcessRangesMaxP[i] = conversionInput->processranges[i]->maxinkuptake; } - NormGamutRegionMaxLim(); - if (m_NormFactor <= 0.0) - { - SetNormFactor(); - SetInverseNormFactor(); - } - VectorXd InkOut(m_nB2AnSepOut); + + VectorXd InkOut(m_nInks); VectorXd RGBOut(3); VectorXd LabOut(3); - VectorXd NLInkOut(m_nB2AnSepOut); - VectorXd Volume(m_nB2AnSepOut); - VectorXd VolumeOut(m_nB2AnSepOut); + VectorXd NLInkOut(m_nInks); + VectorXd Volume(m_nInks); + VectorXd VolumeOut(m_nInks); //set maxNlPerCM - VectorXd NlperCM(m_nB2AnSepOut); + VectorXd NlperCM(m_nInks); NlperCM.setZero(); m_maxNlPerCM = NlperCM; - for (int i = 0; i < m_nB2AnSepOut; ++i) + for (int i = 0; i < m_nInks; ++i) SetMaxNLperCM(conversionInput->inputcoordinates->inputliquids[i]->maxnanoliterpercentimeter, i); - m_nVolumes = m_nB2AnSepOut; + m_nVolumes = m_nInks; int GamutRegion = 0; //Convert input data to linear inks if (conversionInput->colorspace == COLOR_SPACE__Volume || conversionInput->colorspace == COLOR_SPACE__Catalog) @@ -1805,7 +1486,7 @@ size_t Tango::ColorLib::ColorConverter::Convert(uint8_t * input_buffer, size_t i //Limit inks based on m_maxNlpercm //Inks are limited in their nonlinear form //Output Volume is in % - double *InkOutP = new double[m_nB2AnSepOut]; + double *InkOutP = new double[m_nInks]; LimitInks(NLInkOut, InkOutP); NLInkPToVolume(DoubleToVector(InkOutP, m_nInks), Volume); GamutRegion = GetGamutRegion(Volume, m_ProcessRangesMaxP); @@ -2057,7 +1738,7 @@ bool Tango::ColorLib::ColorConverter::IsInGamut(double *InLab, SURROUND sur, CA } double ctr[3]; - C_RGB_XYZ_Lab center = m_GBD->getCenter(); + C_RGB_XYZ_Lab center = m_colortable->m_GBD->getCenter(); VectorXd JInLab(3); JInLab << InLab[0], InLab[1], InLab[2]; VectorXd JLab = m_Conv02->LabToJab(JInLab, sur); @@ -2068,7 +1749,7 @@ bool Tango::ColorLib::ColorConverter::IsInGamut(double *InLab, SURROUND sur, CA //double *dJLab = DBG_NEW double[3]; VectorToDouble(JLab, dJLab); bool intersect = false; - m_GBD->TriangleRayIntersection(dJLab, ctr, intersect, xCoord); + m_colortable->m_GBD->TriangleRayIntersection(dJLab, ctr, intersect, xCoord); if (intersect) { VectorXd V1(3); @@ -2109,92 +1790,7 @@ bool Tango::ColorLib::ColorConverter::IsInGamut(double *InLab, SURROUND sur, CA } -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 =data; - //File Size - NumConversions Conv; - Header.TblSIze = Conv.ByteToInt(ColorTable, bytesread); - bytesread = 4; - uint8_t versionBCT[2]; - versionBCT[0] = (unsigned int)ColorTable[bytesread]; - bytesread += 1; - versionBCT[1] = (unsigned int)ColorTable[bytesread]; - - Header.Version[0] = versionBCT[0]; - Header.Version[1] = versionBCT[1] << 4; - Header.Version[2] = versionBCT[1] & 15; - bytesread += 1; - uint32_t tmp = Conv.ByteToInt(ColorTable, bytesread); - int n = sizeof((char*)&tmp); - //char *tmpC = DBG_NEW char[n]; - char *tmpC = new char[n]; - Conv.getchar(tmp, n, tmpC); - //Header.ColorSpace = DBG_NEW char[n]; - Header.ColorSpace = new char[n]; - memcpy_s(Header.ColorSpace, n + 1, tmpC, n); - - // strncpy_s(Header->ColorSpace, n+1, tmpC, n); - //Header->ColorSpace = tmpC; - bytesread += 4; - tmp = Conv.ByteToInt(ColorTable, bytesread); - Conv.getchar(tmp, n, tmpC); - //Header.ConnectionSpace = DBG_NEW char[n]; - Header.ConnectionSpace = new char[n]; - memcpy_s(Header.ConnectionSpace, n + 1, tmpC, n); - - bytesread += 4; - bytesread += 12; - tmp = Conv.ByteToInt(ColorTable, bytesread); - Conv.getchar(tmp, n, tmpC); - //Header.DeviceManufacturer = DBG_NEW char[n]; - Header.DeviceManufacturer = new char[n]; - memcpy_s(Header.DeviceManufacturer, n + 1, tmpC, n); - // strncpy_s(Header->DeviceManufacturer, n + 1, tmpC, n); - //Header->DeviceManufacturer = tmpC; - if (tmpC != NULL) - { - delete tmpC; - tmpC = NULL; - } - - bytesread += 4; - //read illuminant - double xyz[3]; - for (int j = 0; j < 3; ++j) - { - tmp = Conv.ByteToInt(ColorTable, bytesread); - xyz[j] = (double)(tmp) / 65536; - bytesread += 4; - } - Header.Illuminant.Set(xyz[0], xyz[1], xyz[2]); - //Read Number of Gamut Regions and Max Limits per Region - Header.nGamutRegions = ColorTable[bytesread]; - bytesread++; - Header.GRegMaxLim = new double[Header.nGamutRegions]; - for (int i = 0; i < Header.nGamutRegions; ++i) - { - tmp = Conv.ByteToShort(ColorTable, bytesread); - bytesread += 2; - Header.GRegMaxLim[i] = (double)tmp; - } - - if (bytesread < 128) - { - bytesread = 128; - return(Header); - } - else - { - throw std::exception("could not read Color table Header"); - } -} void Tango::ColorLib::ColorConverter::read_lut_type(int offset, int data_size, ColorTransf *Transf, ConversionInput* conversionInput) { @@ -2222,166 +1818,11 @@ 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, uint8_t *data) -{ - // 0 - 3 'XYZ ' - //4 - 7 reserved, must be 0 - // 8 - n array of XYZ numbers - if (data_size < 8) - { - throw std::exception("not enough data to read xyz"); - } - uint8_t *buff = &(data[offset]); - NumConversions Conv; - int bytesread = 0; - int tmpxyz = Conv.ByteToInt(buff, bytesread); - int n = sizeof(tmpxyz); - //char* tmpC = DBG_NEW char[n]; - char* tmpC = new char[n]; - Conv.getchar(tmpxyz, n, tmpC); - char *xyztype = new char[n + 1]; - //char *xyztype = DBG_NEW char[n + 1]; - strncpy_s(xyztype, n + 1, tmpC, n); - if (strncmp(xyztype, "XYZ ", n) != 0) - { - throw std::exception("Wrong Tag Type"); - return; - } - if (xyztype != NULL) - { - delete[] xyztype; - xyztype = NULL; - } - if (tmpC != NULL) - { - delete[] tmpC; - tmpC = NULL; - } - bytesread = 8; - int num_values = (data_size - 8) / 4; - if (floor((double)(num_values) / 3) * 3 != num_values) - { - throw std::exception("not enough Data to read xyz"); - return; - } - double xyz[3]; - int tmp; - for (int j = 0; j < 3; ++j) - { - tmp = Conv.ByteToInt(buff, bytesread); - xyz[j] = (double)(tmp) / 65536; - bytesread += 4; - } - XYZ->Set(xyz[0], xyz[1], xyz[2]); - return; -} -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 - //8 - string of(data_size - 8) 7 - bit ASCII characters, including NULL - std::stringstream strstr; - if (data_size < 8) - { - throw std::exception("invalid Tag Name"); - strstr << ""; - *textstr = strstr.str(); - return; - } - - uint8_t *buff = &(data[offset]); - int bytesread = 0; - NumConversions Conv; - int tmp = Conv.ByteToInt(buff, bytesread); - int n = sizeof((char*)&tmp); - //char *tmpC = DBG_NEW char[n]; - char *tmpC = new char[n]; - Conv.getchar(tmp, n, tmpC); - char *tagtype = new char[n + 1]; - //char *tagtype = DBG_NEW char[n + 1]; - strncpy_s(tagtype, n + 1, tmpC, n); - if (strcmp(tagtype, "text") != 0) - { - throw std::exception("invalid Tag Name"); - strstr << ""; - *textstr = strstr.str(); - return; - } - if (tagtype != NULL) - { - delete[] tagtype; - tagtype = NULL; - } - if (tmpC != NULL) - { - delete[]tmpC; - tmpC = NULL; - } - bytesread += 8; - uint8_t tmp1; - for (int i = bytesread; i < data_size; ++i) - { - tmp1 = buff[i]; - strstr.put(tmp1); - } - *textstr = strstr.str(); - return; -} - - -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 = &(data[offset]); - int bytesread = 0; - NumConversions Conv; - int tmp = Conv.ByteToInt(buff, bytesread); - int n = sizeof((char*)&tmp); - //char *tmpC= DBG_NEW char[n]; - char *tmpC = new char[n]; - Conv.getchar(tmp, n, tmpC); - char *tagtype = new char[n + 1]; - //char *tagtype = DBG_NEW char[n + 1]; - strncpy_s(tagtype, n + 1, tmpC, n); - std::stringstream strstr; - if (strcmp(tagtype, "desc") != 0) - { - throw std::exception("invalid Tag Name"); - strstr << ""; - textdescstr = strstr.str(); - return; - } - if (tagtype != NULL) - { - delete[] tagtype; - tagtype = NULL; - } - if (tmpC != NULL) - { - delete[]tmpC; - tmpC = NULL; - } - bytesread += 8; - int count = Conv.ByteToInt(buff, bytesread); - bytesread += 4; - uint8_t tmp1; - for (int i = 0; i < count - 1; ++i) - { - tmp1 = buff[bytesread + i]; - strstr << tmp1; - } - textdescstr = strstr.str(); - return; -} /*void Tango::ColorLib::ColorConverter::CompareWhitePoints() { @@ -2621,23 +2062,18 @@ size_t Tango::ColorLib::ColorConverter::P_IsInGamut(uint8_t * input_buffer, size CAM02CS CS = UCS; m_Conv02 = new ColorConvert(IL, IL, Y_b, L_A, sur, CS); //m_Conv02 = DBG_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(); - if (numofInks != m_nB2AnSepOut) + if (numofInks != m_nInks) throw std::exception("Number of available inks does not match ink tables"); - VectorXd InkOut(m_nB2AnSepOut); + VectorXd InkOut(m_nInks); VectorXd RGBOut(3); VectorXd LabOut(3); - VectorXd NLInkOut(m_nB2AnSepOut); - VectorXd Volume(m_nB2AnSepOut); + VectorXd NLInkOut(m_nInks); + VectorXd Volume(m_nInks); C_RGB_XYZ_Lab DataLab; //SURROUND sur = m_Conv02->getSurround(); @@ -2787,18 +2223,18 @@ 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) { - GradientConversionInput* conversionInput = nullptr; -//Initialize Output... + //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); - try { - //Get Input... - conversionInput = gradient_conversion_input__unpack(NULL, input_buffer_size, input_buffer); - conversionOutput->haserror = false; - conversionOutput->has_haserror = false; + conversionOutput->haserror = false; + conversionOutput->has_haserror = false; //Get segment length... double segmentLength = conversionInput->segmentlength; + m_colortable = new ColorTable(); PrepareGradient(conversionInput, conversionOutput); //Get liquid types info... /* InputLiquid* cyan = NULL; @@ -2830,64 +2266,41 @@ size_t Tango::ColorLib::ColorConverter::GenerateGradient(uint8_t * input_buffer, int size = gradient_conversion_output__pack(conversionOutput, output_buffer); //RELEASE MEMORY HERE !!! -#pragma region Free Conversion Input & Output + #pragma region Free Conversion Input & Output gradient_conversion_input__free_unpacked(conversionInput, NULL); gradient_conversion_output__free_unpacked(conversionOutput, NULL); -#pragma endregion + #pragma endregion return size; - } - catch (const std::exception& e) - { - conversionOutput->has_haserror = true; - conversionOutput->haserror = true; - - const char* what = e.what(); - if (strlen(what) > 0) - { - conversionOutput->errormessage = strdup(what); - } - output_buffer = (uint8_t*)malloc(gradient_conversion_output__get_packed_size(conversionOutput)); - int size = gradient_conversion_output__pack(conversionOutput, output_buffer); - -#pragma region Free Conversion Input & Output - - gradient_conversion_input__free_unpacked(conversionInput, NULL); - gradient_conversion_output__free_unpacked(conversionOutput, NULL); - -#pragma endregion -#ifdef _DEBUG - _CrtSetReportMode(_CRT_ERROR, _CRTDBG_MODE_DEBUG); - _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_DEBUG); - _CrtDumpMemoryLeaks(); -#endif - return (size); - } } void Tango::ColorLib::ColorConverter::fillGradientStops(GradientConversionInput *conversionInput) { + C_RGB_XYZ_Lab RGB; + C_RGB_XYZ_Lab Lab; for (int i = 0; i < m_nGradStops; ++i) { switch (conversionInput->stops[i]->colorspace) { case COLOR_SPACE__RGB: //Case RGB - 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; + RGB = C_RGB_XYZ_Lab(conversionInput->stops[i]->red, conversionInput->stops[i]->green, conversionInput->stops[i]->blue); + m_GradStops[i].Set_RGB(RGB); + m_GradStops[i].Set_ColorSpace(COLOR_SPACE__RGB); + m_GradStops[i].Set_Offset(conversionInput->stops[i]->offset); break; case COLOR_SPACE__LAB: //Case LAB - 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; + Lab = C_RGB_XYZ_Lab(conversionInput->stops[i]->l, conversionInput->stops[i]->a, conversionInput->stops[i]->b); + m_GradStops[i].Set_Lab(Lab); + m_GradStops[i].Set_ColorSpace(COLOR_SPACE__LAB); + m_GradStops[i].Set_Offset(conversionInput->stops[i]->offset); break; case COLOR_SPACE__Volume: //Case Volume - m_GradStops[i].colorspace = COLOR_SPACE__Volume; - m_GradStops[i].offset = conversionInput->stops[i]->offset; + m_GradStops[i].Set_ColorSpace(COLOR_SPACE__Volume); + m_GradStops[i].Set_Offset(conversionInput->stops[i]->offset); for (int j = 0; j < (int)conversionInput->stops[i]->n_liquidvolumes; j++) { LiquidVolume* liquidVolume = conversionInput->stops[i]->liquidvolumes[j]; @@ -2895,16 +2308,16 @@ void Tango::ColorLib::ColorConverter::fillGradientStops(GradientConversionInput switch (liquidVolume->liquidtype) { case LIQUID_TYPE__Cyan: - m_GradStops[i].Volume[0] = liquidVolume->volume; + m_GradStops[i].SetVolumeValue(liquidVolume->volume,0); break; case LIQUID_TYPE__Magenta: - m_GradStops[i].Volume[1] = liquidVolume->volume; + m_GradStops[i].SetVolumeValue(liquidVolume->volume, 1); break; case LIQUID_TYPE__Yellow: - m_GradStops[i].Volume[2] = liquidVolume->volume; + m_GradStops[i].SetVolumeValue(liquidVolume->volume, 2); break; case LIQUID_TYPE__Black: - m_GradStops[i].Volume[3] = liquidVolume->volume; + m_GradStops[i].SetVolumeValue(liquidVolume->volume, 3); break; default: throw std::exception("could not fill all volumes"); @@ -2916,12 +2329,12 @@ void Tango::ColorLib::ColorConverter::fillGradientStops(GradientConversionInput } -void Tango::ColorLib::ColorConverter::findStops(GradStruct m_GradStop1, GradStruct m_GradStop2, double dEThr, int ninterstops, +void Tango::ColorLib::ColorConverter::findStops(Gradient &GradStop1, Gradient &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 RGBStart = GradStop1.Get_RGB(); + C_RGB_XYZ_Lab RGBEnd = GradStop2.Get_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); @@ -2942,7 +2355,7 @@ void Tango::ColorLib::ColorConverter::findStops(GradStruct m_GradStop1, GradStru // make a matching Lab vector; VecRGBOut_tmp[0] = C_RGB_XYZ_Lab(RGBStart); - VecLabOut_tmp[0] = C_RGB_XYZ_Lab(m_GradStop1.Lab); + VecLabOut_tmp[0] = C_RGB_XYZ_Lab(GradStop1.Get_Lab()); for (int i = 1; i <= nsubdiv; ++i) { @@ -3058,10 +2471,10 @@ void Tango::ColorLib::ColorConverter::ConvertGradStoptoVolume(InputCoordinates* size_t nInks = 0; C_RGB_XYZ_Lab DataLab; - VectorXd InkOut(m_nB2AnSepOut); + VectorXd InkOut(m_nInks); double normFactor = 1; if (!same_regions) - normFactor = m_NormFactor; + normFactor = m_colortable->GetNormFactor(); if (colorspace ==COLOR_SPACE__RGB) { @@ -3083,20 +2496,20 @@ void Tango::ColorLib::ColorConverter::ConvertGradStoptoVolume(InputCoordinates* //convert to inks int GamutRegion; - double *InkOutP = new double[m_nB2AnSepOut]; + double *InkOutP = new double[m_nInks]; if(same_regions) - m_B2ARTransform->evalLab2InkP(LabIn, InkOutP, GamutRegion); //InkOut is in units of 16 bits + m_colortable->m_B2ARTransform->evalLab2InkP(LabIn, InkOutP, GamutRegion); //InkOut is in units of 16 bits else - m_B2ATransform->evalLab2InkP(LabIn, InkOutP, GamutRegion); //InkOut is in units of 16 bits + m_colortable->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) + for (int i = 0; i < m_nInks; ++i) { InkOutP[i] *= normFactor; - if (InkOutP[i] <= m_GamutRegionMaxLim[0]) + if (InkOutP[i] <= m_NormGamutRegionMaxLim[0]) { - m_LinCurves->m_InterpCurves[i].Eval(InkOutP[i] * 655.35, InkOutP[i]); + m_colortable->m_LinCurves->m_InterpCurves[i].Eval(InkOutP[i] * 655.35, InkOutP[i]); InkOutP[i] /= 655.35; } } @@ -3129,18 +2542,18 @@ void Tango::ColorLib::ColorConverter::ConvertGradStoptoVolume(InputCoordinates* //convert to Inks int GamutRegion; - double *InkOutP = new double[m_nB2AnSepOut]; + double *InkOutP = new double[m_nInks]; if(same_regions) - m_B2ARTransform->evalLab2InkP(LabIn, InkOutP, GamutRegion); //InkOut is in the [0-100] interval + m_colortable->m_B2ARTransform->evalLab2InkP(LabIn, InkOutP, GamutRegion); //InkOut is in the [0-100] interval else - m_B2ATransform->evalLab2InkP(LabIn, InkOutP, GamutRegion); //InkOut is in the [0-100] interval + m_colortable->m_B2ATransform->evalLab2InkP(LabIn, InkOutP, GamutRegion); //InkOut is in the [0-100] interval - for (int i = 0; i < m_nB2AnSepOut; ++i) + for (int i = 0; i < m_nInks; ++i) { InkOutP[i] *= normFactor; - if (InkOutP[i] <= m_GamutRegionMaxLim[0]) + if (InkOutP[i] <= m_NormGamutRegionMaxLim[0]) { - m_LinCurves->m_InterpCurves[i].Eval(InkOutP[i] * 655.35, InkOutP[i]); + m_colortable->m_LinCurves->m_InterpCurves[i].Eval(InkOutP[i] * 655.35, InkOutP[i]); InkOutP[i] /= 655.35; } } @@ -3162,9 +2575,9 @@ void Tango::ColorLib::ColorConverter::ConvertGradStoptoVolume(InputCoordinates* throw std::exception("Unsupported Color Space"); return; } - VectorXd NLInkOut(m_nB2AnSepOut); - VectorXd VolumeOut(m_nB2AnSepOut); - double *InkOutL = new double[m_nB2AnSepOut]; + VectorXd NLInkOut(m_nInks); + VectorXd VolumeOut(m_nInks); + double *InkOutL = new double[m_nInks]; ConvertToNLInks(InkOut, NLInkOut); LimitInks(NLInkOut, InkOutL); NLInkPToVolume(DoubleToVector(InkOutL, m_nInks), Volume); @@ -3179,41 +2592,25 @@ void Tango::ColorLib::ColorConverter::ConvertGradStoptoVolume(InputCoordinates* return; } -void Tango::ColorLib::ColorConverter::SetNormFactor() -{ - m_NormFactor = m_GamutRegionMaxLim[m_nProcessRanges - 1] / m_GamutRegionMaxLim[0]; -} - -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]; + int nInks = conversionInput->n_inputliquids; + m_nVolumes = nInks; + m_GradStops = new Gradient[m_nGradStops]; for (int i = 0; i < m_nGradStops; ++i) - { - if (m_nB2AnSepOut == 0) - m_GradStops[i].Volume = new double[4]; - else - m_GradStops[i].Volume = new double[m_nB2AnSepOut]; - } - + m_GradStops[i].SetVolumeSize(nInks); InputCoordinates **inputcoordinates = (InputCoordinates**)malloc(sizeof(InputCoordinates*)*m_nGradStops); - double *InkOutL = new double[m_nB2AnSepOut]; for (int i = 0; i < m_nGradStops; ++i) { inputcoordinates[i] = (InputCoordinates*)malloc(sizeof(InputCoordinates)); input_coordinates__init(inputcoordinates[i]); } - m_nVolumes = conversionInput->stops[0]->n_liquidvolumes; + fillGradientStops(conversionInput); GradInput2InputCoords(conversionInput, inputcoordinates); @@ -3221,13 +2618,17 @@ void Tango::ColorLib::ColorConverter::PrepareGradient(GradientConversionInput* c 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); - + m_nProcessRanges = conversionInput->n_processranges; + m_colortable->InitColorTables(has_forwarddata, data, m_nProcessRanges); + SetNumberofInks(m_colortable->GetnA2BnSepOut()); + m_NormGamutRegionMaxLim = new double[m_nProcessRanges]; + double *tmpVal = m_colortable->GetNormGamutRegionMaxLim(); + for (int i = 0; i < m_nProcessRanges; ++i) + m_NormGamutRegionMaxLim[i] = tmpVal[i]; int n_inputliquids = conversionInput->n_inputliquids; InputLiquid **inputliquid = conversionInput->inputliquids; readCalibrationTables(inputliquid, n_inputliquids); - if (m_TableVersion <= 1) + if (m_colortable->GetTableVersion() <= 1) { throw std::exception("Color Table Version does not support gradients\0"); } @@ -3251,45 +2652,33 @@ void Tango::ColorLib::ColorConverter::PrepareGradient(GradientConversionInput* c CAM02CS CS = UCS; if (m_Conv02 == NULL) 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"); - //Convert maxInkUptake to percentages if (m_ProcessRangesMaxP == NULL) m_ProcessRangesMaxP = new double[m_nProcessRanges]; for (int i = 0; i < m_nProcessRanges; ++i) { m_ProcessRangesMaxP[i] = conversionInput->processranges[i]->maxinkuptake; } - NormGamutRegionMaxLim(); - if (m_NormFactor <= 0.0) - { - SetNormFactor(); - SetInverseNormFactor(); - } - VectorXd InkOut(m_nB2AnSepOut); + + VectorXd InkOut(m_nInks); VectorXd RGBOut(3); VectorXd LabOut(3); - VectorXd NLInkOut(m_nB2AnSepOut); - VectorXd Volume(m_nB2AnSepOut); - VectorXd VolumeOut(m_nB2AnSepOut); + VectorXd NLInkOut(m_nInks); + VectorXd Volume(m_nInks); + VectorXd VolumeOut(m_nInks); //set maxNlPerCM - VectorXd NlperCM(m_nB2AnSepOut); - double *LabOutV = new double[3]; - double *LabOutFinal = new double[3]; + VectorXd NlperCM(m_nInks); NlperCM.setZero(); m_maxNlPerCM = NlperCM; - for (int i = 0; i < m_nB2AnSepOut; ++i) + for (int i = 0; i < m_nInks; ++i) SetMaxNLperCM(conversionInput->inputliquids[i]->maxnanoliterpercentimeter, i); - m_nVolumes = m_nB2AnSepOut; + //m_nVolumes = m_nB2AnSepOut; int GamutRegion = 0; ProcessGradientStops(inputcoordinates); @@ -3298,8 +2687,9 @@ void Tango::ColorLib::ColorConverter::PrepareGradient(GradientConversionInput* c 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); + GamutRegion = m_GradStops[i].Get_GamutRegion(); + maxreg = std::max(maxreg, GamutRegion); + minreg = std::min(minreg, GamutRegion); } //Choose Gamut Region for Gradient calculation @@ -3330,17 +2720,18 @@ void Tango::ColorLib::ColorConverter::PrepareGradient(GradientConversionInput* c 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; + AllRGBOut_tmp[0][0] = m_GradStops[0].Get_RGB().Get_x(); + AllRGBOut_tmp[0][1] = m_GradStops[0].Get_RGB().Get_y(); + AllRGBOut_tmp[0][2] = m_GradStops[0].Get_RGB().Get_z(); + AllLabOut_tmp[0][0] = m_GradStops[0].Get_Lab().Get_x(); + AllLabOut_tmp[0][1] = m_GradStops[0].Get_Lab().Get_y(); + AllLabOut_tmp[0][2] = m_GradStops[0].Get_Lab().Get_z(); + AllPos_tmp[0] = m_GradStops[0].Get_Offset(); int ncountStops = 0; int nPosStops = 0; double dOffset = 0; GradOffset OffsetType = EqSpaced; + for (int iStop = 0; iStop < m_nGradStops - 1; ++iStop) { findStops(m_GradStops[iStop], m_GradStops[iStop + 1], dEThr, ninterstops, nOut, VecRGBOut, VecLabOut, posOut); @@ -3348,24 +2739,24 @@ void Tango::ColorLib::ColorConverter::PrepareGradient(GradientConversionInput* c { case EqSpaced: if (iStop == m_nGradStops - 2) - dOffset = (m_GradStops[iStop + 1].offset - m_GradStops[iStop].offset)*GradientEndThr / (nOut - 1); + dOffset = (m_GradStops[iStop + 1].Get_Offset() - m_GradStops[iStop].Get_Offset())*GradientEndThr / (nOut - 1); else - dOffset = (m_GradStops[iStop + 1].offset - m_GradStops[iStop].offset) / (nOut - 1); + dOffset = (m_GradStops[iStop + 1].Get_Offset() - m_GradStops[iStop].Get_Offset()) / (nOut - 1); for (int jPos = 1; jPos < nOut; ++jPos) { nPosStops++; - AllPos_tmp[nPosStops] = m_GradStops[iStop].offset + dOffset * jPos; + AllPos_tmp[nPosStops] = m_GradStops[iStop].Get_Offset() + dOffset * jPos; } break; case dESpaced: if (iStop == m_nGradStops - 2) - dOffset = (m_GradStops[iStop + 1].offset - m_GradStops[iStop].offset)*GradientEndThr / posOut[nOut - 1]; + dOffset = (m_GradStops[iStop + 1].Get_Offset() - m_GradStops[iStop].Get_Offset())*GradientEndThr / posOut[nOut - 1]; else - dOffset = (m_GradStops[iStop + 1].offset - m_GradStops[iStop].offset) / posOut[nOut - 1]; + dOffset = (m_GradStops[iStop + 1].Get_Offset() - m_GradStops[iStop].Get_Offset()) / posOut[nOut - 1]; for (int jPos = 0; jPos < nOut; ++jPos) { nPosStops++; - AllPos_tmp[nPosStops] = m_GradStops[iStop].offset + dOffset * posOut[jPos]; + AllPos_tmp[nPosStops] = m_GradStops[iStop].Get_Offset() + dOffset * posOut[jPos]; } break; } @@ -3426,8 +2817,8 @@ void Tango::ColorLib::ColorConverter::PrepareGradient(GradientConversionInput* c ColorSpace SubStopsCS = COLOR_SPACE__LAB; //double NormFactor = m_ProcessRangesMaxP[m_nProcessRanges - 1] / 100.0; - VectorXd VolumeStop(m_nB2AnSepOut); - MatrixXd MatVolume(ncountStops, m_nB2AnSepOut); + VectorXd VolumeStop(m_nInks); + MatrixXd MatVolume(ncountStops, m_nInks); for (int iS = 0; iS < ncountStops; ++iS) { GradientOutputStop *stop = (GradientOutputStop*)malloc(sizeof(GradientOutputStop)); @@ -3443,7 +2834,7 @@ void Tango::ColorLib::ColorConverter::PrepareGradient(GradientConversionInput* c VectorXd VIn(ncountStops); VectorXd VOut(ncountStops); int FilterWidth = 7; - for (int iSep = 0; iSep < m_nB2AnSepOut; ++iSep) + for (int iSep = 0; iSep < m_nInks; ++iSep) { for (int jStop = 0; jStop < ncountStops; ++jStop) VIn(jStop) = MatVolume(jStop, iSep); @@ -3491,12 +2882,7 @@ void Tango::ColorLib::ColorConverter::PrepareGradient(GradientConversionInput* c } -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) { @@ -3611,7 +2997,7 @@ int Tango::ColorLib::ColorConverter::GetGamutRegion(VectorXd Volume, double *Ga int GamutRegion = 0; for (int i = 0; i < m_nInks; ++i) TotalVolume += Volume(i); - for (int i=0; i<m_nGamutRegions; ++i) + for (int i=0; i< m_colortable->GetnGamutRegions(); ++i) { if (TotalVolume > GamutLimits[i]) GamutRegion++; @@ -3638,14 +3024,14 @@ void Tango::ColorLib::ColorConverter::SmoothCurveData(VectorXd VIn, VectorXd &VO void Tango::ColorLib::ColorConverter::ProcessGradientStops(InputCoordinates **inputcoordinates) { - VectorXd Volume(m_nB2AnSepOut); - VectorXd RGBOut(m_nA2BnSepOut); - VectorXd LabOut(m_nA2BnSepOut); - VectorXd InkOut(m_nB2AnSepOut); - VectorXd NLInkOut(m_nB2AnSepOut); - double * InkOutL = new double[m_nB2AnSepOut]; - double * LabOutV = new double[m_nA2BnSepOut]; - double * LabOutFinal = new double[m_nA2BnSepOut]; + VectorXd Volume(m_nInks); + VectorXd RGBOut(m_nInks); + VectorXd LabOut(m_nInks); + VectorXd InkOut(m_nInks); + VectorXd NLInkOut(m_nInks); + double * InkOutL = new double[m_nInks]; + double * LabOutV = new double[3]; + double * LabOutFinal = new double[3]; ColorConvert CConvertD65(D65, D65); @@ -3653,19 +3039,21 @@ void Tango::ColorLib::ColorConverter::ProcessGradientStops(InputCoordinates **in 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) + if (m_GradStops[i].Get_ColorSpace() == COLOR_SPACE__Volume || m_GradStops[i].Get_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); + ConvertVolumeToRGBDisplay(inputcoordinates[i], m_nProcessRanges, m_GradStops[i].Get_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; + C_RGB_XYZ_Lab Lab(LabOut); + C_RGB_XYZ_Lab RGB(RGBOut); + m_GradStops[i].Set_Lab(LabOut); + m_GradStops[i].Set_RGB(RGBOut); + m_GradStops[i].Set_GamutRegion( GamutRegion); + m_GradStops[i].SetInGamut (true); } else { - ConvertColorToLinearInks(inputcoordinates[i], m_GradStops[i].colorspace, InkOut, RGBOut, LabOut, GamutRegion, InGamut); + ConvertColorToLinearInks(inputcoordinates[i], m_GradStops[i].Get_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 @@ -3678,16 +3066,15 @@ void Tango::ColorLib::ColorConverter::ProcessGradientStops(InputCoordinates **in //fill data //fill volume //allocate m_GradStops[i].Volume - if (m_GradStops[i].Volume != NULL) - delete[] 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; + C_RGB_XYZ_Lab Lab(LabOut); + C_RGB_XYZ_Lab RGB(RGBOut); + for (int j = 0; j < m_nInks; ++j) + m_GradStops[i].SetVolumeValue(Volume[j], j); + m_GradStops[i].Set_GamutRegion(GamutRegion); + m_GradStops[i].SetInGamut(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)); + m_GradStops[i].Set_Lab(LabOut); + m_GradStops[i].Set_RGB(RGBOut); } //Convert Lab Values to Relative Colorimetric. These values will be used in the Gradient Volume calculation. VectorToDouble(LabOut, LabOutV); @@ -3699,7 +3086,8 @@ void Tango::ColorLib::ColorConverter::ProcessGradientStops(InputCoordinates **in //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]); + C_RGB_XYZ_Lab LabOut1(LabOutFinal[0], LabOutFinal[1], LabOutFinal[2]); + m_GradStops[i].Set_Lab(LabOut1); } //free vectors if (LabOutV != NULL) diff --git a/Software/Visual_Studio/ColorLib/Tango.ColorLib_v4/ColorConverter.h b/Software/Visual_Studio/ColorLib/Tango.ColorLib_v4/ColorConverter.h index 226d682b3..7aec6d993 100644 --- a/Software/Visual_Studio/ColorLib/Tango.ColorLib_v4/ColorConverter.h +++ b/Software/Visual_Studio/ColorLib/Tango.ColorLib_v4/ColorConverter.h @@ -8,6 +8,7 @@ #include "ColorTransf.h" #include "ColorConvert.h" #include "GBD.h" +#include "CT_Header.h" #include "ConversionOutput.pb-c.h" #include "CalibrationData.pb-c.h" #include "ConversionInput.pb-c.h" @@ -17,11 +18,13 @@ #include "GradientConversionOutput.pb-c.h" #include "Interp.h" #include "Curves.h" +#include "Gradient.h" +#include "ColorTable.h" #pragma once namespace Tango { - typedef struct +/* typedef struct { unsigned int TblSIze = 0; unsigned int Version[3] = { 0,0,0 }; @@ -31,9 +34,9 @@ namespace Tango C_RGB_XYZ_Lab Illuminant; unsigned char nGamutRegions=0; double *GRegMaxLim; - } CT_Header; + } CT_Header; */ - typedef struct +/* typedef struct { C_RGB_XYZ_Lab Lab; C_RGB_XYZ_Lab RGB; @@ -42,7 +45,7 @@ namespace Tango int GamutRegion; double offset; ColorSpace colorspace; - }GradStruct; + }GradStruct;*/ /*typedef enum { XYZ, @@ -56,19 +59,7 @@ namespace Tango dESpaced }GradOffset; - typedef enum { - A2B, - A2BR, - B2A, - B2AR, - cprt, - gbd, - gbdR, - wtpt, - desc, - lcrv -// GReg - }TagList; + namespace ColorLib { @@ -95,57 +86,33 @@ namespace Tango void SetMaxNLperCM(double maxNlPerCM, int i); size_t P_IsInGamut(uint8_t * input_buffer, size_t input_buffer_size, uint8_t *& output_buffer); private: - ColorTransf *m_B2ATransform; - ColorTransf *m_A2BTransform; - ColorTransf *m_B2ARTransform; - ColorTransf *m_A2BRTransform; -// ColorTransf *m_GRegTransform; - GBD *m_GBD; - GBD *m_GBDR; - Curves *m_LinCurves; + ColorTable *m_colortable; ColorConvert *m_Conv02; // Interp *m_LinInterp; // Interp *m_InvLinInterp; C_RGB_XYZ_Lab m_whitepointLab; C_RGB_XYZ_Lab m_whitepointXYZ_Strip; - C_RGB_XYZ_Lab m_whitepointXYZ_CT; + double *m_NormGamutRegionMaxLim; + double *m_ProcessRangesMaxP; + int m_nProcessRanges; 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; + Gradient *m_GradStops; bool same_regions; // bool m_AdaptWP; CalibData *m_CalibCurves; int m_nInks; int m_nVolumes; - int m_nProcessRanges; - //double *m_ProcessRangesMinP; - double *m_ProcessRangesMaxP; - double m_NormFactor; - int m_TableVersion; - double m_InvNormFactor; //double *m_ProcessRangesMaxInkUptake; //double *m_ProcessRangesMinInkUptake; C_RGB_XYZ_Lab m_WP; VectorXd m_maxNlPerCM; - void SetnB2AnSepIn(int nB2AnSepIn) { m_nB2AnSepIn = nB2AnSepIn; }; - void SetnB2AnSepOut(int nB2AnSepOut) { m_nB2AnSepOut = nB2AnSepOut; }; - void SetnA2BnSepIn(int nA2BnSepIn) { m_nA2BnSepIn = nA2BnSepIn; }; - void SetnA2BnSepOut(int nA2BnSepOut) { m_nA2BnSepOut = nA2BnSepOut; }; - void SetnGamutRegions(int nGamutRegions) { m_nGamutRegions = nGamutRegions; }; - void SetTableVersion(int TableVersion) { m_TableVersion = TableVersion; }; void readColorTransformations(ConversionInput* conversionInput); - void readColorTables(bool has_rddata, uint8_t *data, int nprocessranges); +// 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; }; - void SetNumberOfInks(int nInks) { m_nInks = nInks; }; // void InitInterpolations(int numofInks, Interp *linearInterp, Interp *InvLinearInterp); void fillRGB(OutputCoordinates *outputCoords, VectorXd RGBOut); void fillLab(OutputCoordinates *outputCoords, VectorXd LabOut); @@ -165,18 +132,10 @@ namespace Tango VectorXd DoubleToVector(double *doub, int nSize); void CompareWhitePoints(); bool IsInGamut(double *InLab, SURROUND sur, CAM02CS CS, double *LabCoord); - CT_Header read_header(uint8_t* data, 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, uint8_t *data); - void read_text_type(int offset, int data_size, std::string *textstr, - uint8_t *data); - void read_text_description_type(int offset, int data_size, std::string textdescstr, - uint8_t *data); - void findStops(GradStruct m_GradStops1, GradStruct m_GradStops2, double dEThr, int ninterstops, int &nOut, + void findStops(Gradient& m_GradStops1, Gradient& 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 ProcessGradientStops(InputCoordinates **inputcoordinates); void PrepareGradient(GradientConversionInput* conversionInput, GradientConversionOutput *conversionOutput); @@ -184,6 +143,15 @@ namespace Tango void NLcmtoPercentage(VectorXd InVolume, VectorXd &OutVolume); int GetGamutRegion(VectorXd Volume, double *GamutLimits); void SmoothCurveData(VectorXd VIn, VectorXd &VOut, int FilterWidth); + void ConvertRGBColorToLinearInks(InputCoordinates* inputcoordinates, + VectorXd &InkOut, VectorXd &RGBOut, + VectorXd &LabOut, int &GamutRegion, bool &InGamut, SURROUND sur, CAM02CS CS); + void ConvertLabColorToLinearInks(InputCoordinates* inputcoordinates, + VectorXd &InkOut, VectorXd &RGBOut, + VectorXd &LabOut, int &GamutRegion, bool &InGamut, SURROUND sur, CAM02CS CS); + void ConvertCMYKColorToLinearInks(InputCoordinates* inputcoordinates, + VectorXd &InkOut, VectorXd &RGBOut, + VectorXd &LabOut, int &GamutRegion, bool &InGamut, SURROUND sur, CAM02CS CS); }; } } diff --git a/Software/Visual_Studio/ColorLib/Tango.ColorLib_v4/Tango.ColorLib_v4.vcxproj b/Software/Visual_Studio/ColorLib/Tango.ColorLib_v4/Tango.ColorLib_v4.vcxproj index 5c9365f84..e12055f28 100644 --- a/Software/Visual_Studio/ColorLib/Tango.ColorLib_v4/Tango.ColorLib_v4.vcxproj +++ b/Software/Visual_Studio/ColorLib/Tango.ColorLib_v4/Tango.ColorLib_v4.vcxproj @@ -192,10 +192,13 @@ <ClInclude Include="targetver.h" /> <ClInclude Include="Utils\CalibData.h" /> <ClInclude Include="Utils\ColorConvert.h" /> + <ClInclude Include="Utils\ColorTable.h" /> <ClInclude Include="Utils\ColorTransf.h" /> + <ClInclude Include="Utils\CT_Header.h" /> <ClInclude Include="Utils\Curves.h" /> <ClInclude Include="Utils\C_RGB_XYZ_Lab.h" /> <ClInclude Include="Utils\GBD.h" /> + <ClInclude Include="Utils\Gradient.h" /> <ClInclude Include="Utils\Interp.h" /> <ClInclude Include="Utils\NDInterpUtils.h" /> <ClInclude Include="Utils\NumConversions.h" /> @@ -229,10 +232,13 @@ <ClCompile Include="protobuf-c\protobuf-c.c" /> <ClCompile Include="Utils\CalibData.cpp" /> <ClCompile Include="Utils\ColorConvert.cpp" /> + <ClCompile Include="Utils\ColorTable.cpp" /> <ClCompile Include="Utils\ColorTransf.cpp" /> + <ClCompile Include="Utils\CT_Header.cpp" /> <ClCompile Include="Utils\Curves.cpp" /> <ClCompile Include="Utils\C_RGB_XYZ_Lab.cpp" /> <ClCompile Include="Utils\GBD.cpp" /> + <ClCompile Include="Utils\Gradient.cpp" /> <ClCompile Include="Utils\Interp.cpp" /> <ClCompile Include="Utils\NDInterpUtils.cpp" /> <ClCompile Include="Utils\NumConversions.cpp" /> diff --git a/Software/Visual_Studio/ColorLib/Tango.ColorLib_v4/Tango.ColorLib_v4.vcxproj.filters b/Software/Visual_Studio/ColorLib/Tango.ColorLib_v4/Tango.ColorLib_v4.vcxproj.filters index 3c6c1330d..5ebaedebc 100644 --- a/Software/Visual_Studio/ColorLib/Tango.ColorLib_v4/Tango.ColorLib_v4.vcxproj.filters +++ b/Software/Visual_Studio/ColorLib/Tango.ColorLib_v4/Tango.ColorLib_v4.vcxproj.filters @@ -141,6 +141,15 @@ <ClInclude Include="PMR\ColorLab\LinearizationOutput.pb-c.h"> <Filter>PMR</Filter> </ClInclude> + <ClInclude Include="Utils\Gradient.h"> + <Filter>Utils</Filter> + </ClInclude> + <ClInclude Include="Utils\CT_Header.h"> + <Filter>Utils</Filter> + </ClInclude> + <ClInclude Include="Utils\ColorTable.h"> + <Filter>Utils</Filter> + </ClInclude> </ItemGroup> <ItemGroup> <ClCompile Include="Exports.cpp"> @@ -248,5 +257,14 @@ <ClCompile Include="PMR\ColorLab\LinearizationOutput.pb-c.c"> <Filter>PMR</Filter> </ClCompile> + <ClCompile Include="Utils\Gradient.cpp"> + <Filter>Utils</Filter> + </ClCompile> + <ClCompile Include="Utils\CT_Header.cpp"> + <Filter>Utils</Filter> + </ClCompile> + <ClCompile Include="Utils\ColorTable.cpp"> + <Filter>Utils</Filter> + </ClCompile> </ItemGroup> </Project>
\ No newline at end of file diff --git a/Software/Visual_Studio/ColorLib/Tango.ColorLib_v4/Utils/CT_Header.cpp b/Software/Visual_Studio/ColorLib/Tango.ColorLib_v4/Utils/CT_Header.cpp new file mode 100644 index 000000000..5e419f711 --- /dev/null +++ b/Software/Visual_Studio/ColorLib/Tango.ColorLib_v4/Utils/CT_Header.cpp @@ -0,0 +1,83 @@ +#ifdef _MSC_VER +#define _CRT_SECURE_NO_WARNINGS +#endif +#include "CT_Header.h" +#include <iostream> +#include <stdio.h> +#include <cstring> + +CT_Header::CT_Header() : + m_Version(NULL), m_ColorSpace(NULL), m_ConnectionSpace(NULL), m_TblSize(0), + m_DeviceManufacturer(NULL), m_Illuminant(0), m_nGamutRegions(0), m_GRegMaxLim(NULL) +{ + +} + +CT_Header::~CT_Header() +{ + if (m_Version != NULL) + { + delete[]m_Version; + m_Version = NULL; + } + if (m_ColorSpace != NULL) + { + delete m_ColorSpace; + m_ColorSpace = NULL; + } + if (m_ConnectionSpace != NULL) + { + delete m_ConnectionSpace; + m_ConnectionSpace = NULL; + } + if (m_DeviceManufacturer != NULL) + { + delete m_DeviceManufacturer; + m_DeviceManufacturer = NULL; + } + if (m_GRegMaxLim != NULL) + { + delete[]m_GRegMaxLim; + m_GRegMaxLim = NULL; + } +} + +void CT_Header::SetTableVersion(unsigned int *Version) +{ + m_Version = new unsigned int[3]; + for (int i = 0; i < 3; ++i) + m_Version[i] = Version[i]; +} + +C_RGB_XYZ_Lab CT_Header::GetIlluminant() { + return(m_Illuminant); +}; + +void CT_Header::SetColorSpace(char *ColorSPace) +{ + int nsize = sizeof(ColorSPace); + m_ColorSpace = new char[nsize]; + strcpy(m_ColorSpace, ColorSPace); +} + +void CT_Header :: SetConnectionSpace(char *ConnectionSpace) +{ + int nsize = sizeof(ConnectionSpace); + m_ConnectionSpace = new char[nsize]; + strcpy(m_ConnectionSpace, ConnectionSpace); +} + +void CT_Header::SetDeviceManufacturer(char *DeviceManufacturer) +{ + int nsize = sizeof(DeviceManufacturer); + m_DeviceManufacturer = new char[nsize]; + strcpy(m_DeviceManufacturer, DeviceManufacturer); +} + +void CT_Header::SetGamutRegionsMaxLimit(double *GRegMaxLim) +{ + if (m_GRegMaxLim == NULL) + m_GRegMaxLim = new double[m_nGamutRegions]; + for (int i = 0; i < m_nGamutRegions; ++i) + m_GRegMaxLim[i] = GRegMaxLim[i]; +} diff --git a/Software/Visual_Studio/ColorLib/Tango.ColorLib_v4/Utils/CT_Header.h b/Software/Visual_Studio/ColorLib/Tango.ColorLib_v4/Utils/CT_Header.h new file mode 100644 index 000000000..6476a82cc --- /dev/null +++ b/Software/Visual_Studio/ColorLib/Tango.ColorLib_v4/Utils/CT_Header.h @@ -0,0 +1,57 @@ +#ifndef _CT_HEADER_H_ +#define _CT_HEADER_H_ +#pragma once +#include <stdlib.h> +#include "C_RGB_XYZ_Lab.h" + +class CT_Header { +public: + CT_Header(); + ~CT_Header(); + unsigned int GetTableSize() { return(m_TblSize); }; + void SetTableSize(unsigned int TableSize) { + m_TblSize = TableSize; + }; + unsigned int *GetTableVersion() { return(m_Version); }; + void SetTableVersion(unsigned int *version); + char* GetColorSpace() { + return(m_ColorSpace); + }; + void SetColorSpace(char *ColorSPace); + char* GetConnectionSpace() { + return(m_ConnectionSpace); + }; + void SetConnectionSpace(char *ConnectionSpace); + + char* GetDeviceManufacturer() { + return(m_DeviceManufacturer); + }; + void SetDeviceManufacturer(char *DeviceManufacturer); + + C_RGB_XYZ_Lab GetIlluminant(); + + void SetIlluminant(C_RGB_XYZ_Lab Illuminant) { + m_Illuminant = Illuminant; + }; + + void SetNGamutRegions(unsigned char GamutRegions) { + m_nGamutRegions = GamutRegions; + }; + unsigned char GetNGamutRegions() { + return(m_nGamutRegions); + }; + void SetGamutRegionsMaxLimit(double *GRegMaxLim); + double *GetGamutRegionsMaxLimit() { return(m_GRegMaxLim); }; + +private: + unsigned int *m_Version; + char *m_ColorSpace; + char * m_ConnectionSpace; + char * m_DeviceManufacturer; + C_RGB_XYZ_Lab m_Illuminant; + unsigned char m_nGamutRegions ; + double *m_GRegMaxLim; + unsigned int m_TblSize; +}; + +#endif
\ No newline at end of file diff --git a/Software/Visual_Studio/ColorLib/Tango.ColorLib_v4/Utils/ColorTable.cpp b/Software/Visual_Studio/ColorLib/Tango.ColorLib_v4/Utils/ColorTable.cpp new file mode 100644 index 000000000..9bdadeb3f --- /dev/null +++ b/Software/Visual_Studio/ColorLib/Tango.ColorLib_v4/Utils/ColorTable.cpp @@ -0,0 +1,645 @@ +#include "ColorTable.h" +#include "NumConversions.h" + +using namespace std; + +//Constructor +ColorTable::ColorTable() : + m_B2ATransform(NULL), m_A2BTransform(NULL), +m_B2ARTransform(NULL), m_A2BRTransform(NULL), +m_GBD(NULL), m_GBDR(NULL), m_LinCurves(NULL), +m_nB2AnSepIn(0), m_nB2AnSepOut(0), +m_nA2BnSepIn(0), m_nA2BnSepOut(0), +m_TableVersion(0), m_NormFactor(0.0), m_InvNormFactor(1.0), +m_nGamutRegions(0), m_nProcessRanges(0), +m_GamutRegionMaxLim(NULL), m_whitepointXYZ_CT(0.0) +{ +} + +ColorTable::~ColorTable() +{ + if (m_B2ATransform != NULL) + { + delete m_B2ATransform; + m_B2ATransform = NULL; + } + if (m_B2ARTransform != NULL) + { + delete m_B2ARTransform; + m_B2ARTransform = NULL; + } + if (m_A2BTransform != NULL) + { + delete m_A2BTransform; + m_A2BTransform = NULL; + } + if (m_A2BRTransform != NULL) + { + delete m_A2BRTransform; + m_A2BRTransform = NULL; + } + if (m_GBD != NULL) + { + delete m_GBD; + m_GBD = NULL; + } + if (m_GBDR != NULL) + { + delete m_GBDR; + m_GBDR = NULL; + } + if (m_LinCurves != NULL) + { + delete m_LinCurves; + m_LinCurves = NULL; + } + if (m_GamutRegionMaxLim != NULL) + { + delete[] m_GamutRegionMaxLim; + m_GamutRegionMaxLim = NULL; + } +} +void ColorTable::InitColorTables(bool has_rddata, uint8_t *data, int nprocessranges) +{ + readColorTables(has_rddata, data, nprocessranges); + SetNormFactor(); + SetInverseNormFactor(); + NormGamutRegionMaxLim(); +} +void ColorTable::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; + int TblVer = 0; + if (has_data) + { + //Read Header + CT_Header *header = read_header(data, bytesread); + SetnGamutRegions((int)(header->GetNGamutRegions())); + TblVer = (int)header->GetTableVersion()[0]; + SetTableVersion(TblVer); + if (m_nGamutRegions != nprocessranges) + { + throw std::exception("Number of gamut regions in table does not match STRIP\0"); + return; + } + double *tmpGamutRegionsLim = header->GetGamutRegionsMaxLimit(); + m_GamutRegionMaxLim = new double[m_nGamutRegions]; + for (int i = 0; i < m_nGamutRegions; ++i) + m_GamutRegionMaxLim[i] = tmpGamutRegionsLim[i]; + + m_nProcessRanges = (int)(nprocessranges); + + uint32_t tmp; + uint8_t *buff = data; + tmp = conv.ByteToInt(buff, bytesread); + tag_count = (int)tmp; + bytesread += 4; + //read Tag Table + char **TagNames = new char*[tag_count]; + //char **TagNames = DBG_NEW char*[tag_count]; + int **TagSize = new int*[tag_count]; + //int **TagSize = DBG_NEW int*[tag_count]; + char *tmpC = new char[80]; + int n = 0; + int i, j; + for (i = 0; i < tag_count; ++i) + { + TagSize[i] = new int[2]; + //TagSize[i] = DBG_NEW int[3]; + tmp = conv.ByteToInt(buff, bytesread); + n = sizeof((char*)&tmp); + //tmpC = DBG_NEW char[n]; + conv.getchar(tmp, n, tmpC); + //TagNames[i] = DBG_NEW char[n]; + TagNames[i] = new char[n]; + for (j = 0; j < n; ++j) + TagNames[i][j] = tmpC[j]; + bytesread += 4; + TagSize[i][0] = conv.ByteToInt(buff, bytesread); + bytesread += 4; + TagSize[i][1] = conv.ByteToInt(buff, bytesread); + bytesread += 4; + } + if (tmpC != NULL) + { + delete[] tmpC; + tmpC = NULL; + } + + + int *TList = new int[tag_count]; + //int *TList = DBG_NEW int[tag_count]; + for (int k = 0; k < tag_count; ++k) + { + if (strncmp(TagNames[k], "A2B ", 4) == 0) + TList[k] = A2B; + else if (strncmp(TagNames[k], "A2BR", 4) == 0) + TList[k] = A2BR; + else if (strncmp(TagNames[k], "B2A ", 4) == 0) + TList[k] = B2A; + else if (strncmp(TagNames[k], "B2AR ", 4) == 0) + TList[k] = B2AR; + else if (strncmp(TagNames[k], "wtpt", 4) == 0) + TList[k] = wtpt; + else if (strncmp(TagNames[k], "desc", 4) == 0) + TList[k] = desc; + else if (strncmp(TagNames[k], "gbd ", 4) == 0) + TList[k] = gbd; + else if (strncmp(TagNames[k], "gbdR", 4) == 0) + TList[k] = gbdR; + else if (strncmp(TagNames[k], "cprt", 4) == 0) + TList[k] = cprt; + else if (strncmp(TagNames[k], "lcrv", 4) == 0) + TList[k] = lcrv; + // else if (strncmp(TagNames[k], "GReg", 2) == 0) + // TList[k] = GReg; + else + throw std::exception("Unknown Tag in Color Tables"); + } + + if (TagNames != NULL) + { + for (int i = 0; i < tag_count; ++i) + { + delete[] TagNames[i]; + TagNames[i] = NULL; + } + delete[]TagNames; + TagNames = NULL; + } + for (int k = 0; k < tag_count; ++k) + { + switch (TList[k]) + { + case A2B: + { + uint8_t *A2BLUT = &(data[TagSize[k][0]]); + int A2BLutsize = TagSize[k][1]; + m_A2BTransform = new ColorTransf(); + //m_A2BTransform = DBG_NEW ColorTransf(); + m_A2BTransform->InitData(A2BLUT, A2BLutsize); + m_nA2BnSepIn = m_A2BTransform->GetSeparationsIn(); + m_nA2BnSepOut = m_A2BTransform->GetSeparationsOut(); + break; + } + case A2BR: + { + uint8_t *A2BRLUT = &(data[TagSize[k][0]]); + int A2BRLutsize = TagSize[k][1]; + m_A2BRTransform = new ColorTransf(); + //m_A2BTransform = DBG_NEW ColorTransf(); + m_A2BRTransform->InitData(A2BRLUT, A2BRLutsize); + break; + } + case B2A: + { + uint8_t *B2ALUT = &(data[TagSize[k][0]]); + int B2ALutsize = TagSize[k][1]; + m_B2ATransform = new ColorTransf(); + //m_B2ATransform = DBG_NEW ColorTransf(); + m_B2ATransform->InitData(B2ALUT, B2ALutsize); + m_nB2AnSepIn = m_B2ATransform->GetSeparationsIn(); + m_nB2AnSepOut = m_B2ATransform->GetSeparationsOut(); + break; + } + case B2AR: + { + uint8_t *B2ARLUT = &(data[TagSize[k][0]]); + int B2ARLutsize = TagSize[k][1]; + m_B2ARTransform = new ColorTransf(); + //m_B2ATransform = DBG_NEW ColorTransf(); + m_B2ARTransform->InitData(B2ARLUT, B2ARLutsize); + break; + } + /* case GReg: + { + uint8_t *GRegLUT = &(conversionInput->forwarddata.data[TagSize[k][0]]); + int GRegLutsize = TagSize[k][1]; + m_GRegTransform = new ColorTransf(); + //m_B2ATransform = DBG_NEW ColorTransf(); + m_GRegTransform->InitData(GRegLUT, GRegLutsize); + break; + } */ + case gbd: + { + uint8_t *GBDList = &(data[TagSize[k][0]]); + m_GBD = new GBD(); + //m_GBD = DBG_NEW GBD(); + int GBDSize = TagSize[k][1]; + m_GBD->InitData(GBDList, GBDSize); + break; + } + case gbdR: + { + uint8_t *GBDRList = &(data[TagSize[k][0]]); + m_GBDR = new GBD(); + //m_GBD = DBG_NEW GBD(); + int GBDRSize = TagSize[k][1]; + m_GBDR->InitData(GBDRList, GBDRSize); + break; + } + case lcrv: + { + uint8_t *CurvesData = &(data[TagSize[k][0]]); + m_LinCurves = new Curves(); + int CurvesSize = TagSize[k][1]; + m_LinCurves->InitData(CurvesData, CurvesSize); + break; + } + case wtpt: + { + 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, data); + break; + } + case desc: + { + std::string textdescstr; + read_text_description_type(TagSize[k][0], TagSize[k][1], textdescstr, data); + break; + } + default: + { + throw std::exception("Unresolved Tag in Color Tables"); + return; + } + + } + } + + if (TagSize != NULL) + { + for (int i = 0; i < tag_count; ++i) + { + delete[] TagSize[i]; + TagSize[i] = NULL; + } + delete[]TagSize; + TagSize = NULL; + } + if (TList != NULL) + { + delete[] TList; + TList = NULL; + } + if (header != NULL) + { + delete header; + header = NULL; + } + } + + + //Verify all relevant tags had been read + if (m_A2BTransform == NULL) + { + throw std::exception("Missing Forward Transform in Color Tables"); + return; + } + if (m_A2BRTransform == NULL) + { + throw std::exception("Missing Reduced Forward Transform in Color Tables"); + return; + } + if (m_B2ATransform == NULL) + { + throw std::exception("Missing Inverse Transform in Color Tables"); + return; + } + if (m_B2ARTransform == NULL) + { + throw std::exception("Missing Reduced Inverse Transform in Color Tables"); + return; + } + if (m_GBD == NULL) + { + throw std::exception("Missing Gamut Boundary Descriptor in Color Tables"); + return; + } + if (m_GBDR == NULL) + { + throw std::exception("Missing Reduced Gamut Boundary Descriptor in Color Tables"); + return; + } + if ((m_whitepointXYZ_CT.Get_x() == -1) && (m_whitepointXYZ_CT.Get_y() == -1) && (m_whitepointXYZ_CT.Get_z() == -1)) + { + throw std::exception("Missing Whitepoint in Color Tables"); + return; + } + if (m_LinCurves == NULL) + { + throw std::exception("Missing Linear Curves in Color Tables"); + return; + } + return; // OK +} + +CT_Header *ColorTable::read_header(uint8_t *data, int &bytesread) +{ + //CT_Header *Header = new CT_Header; + //CT_Header *Header = DBG_NEW CT_Header; + CT_Header *Header = new CT_Header; + + // unsigned int tmp = (buffer[2 * i + 1] << 8) | buffer[2 * i]; + uint8_t *ColorTableData = data; + //File Size + NumConversions Conv; + unsigned int TblSize = Conv.ByteToInt(ColorTableData, bytesread); + Header->SetTableSize(TblSize); + bytesread = 4; + uint8_t versionBCT[2]; + versionBCT[0] = (unsigned int)ColorTableData[bytesread]; + bytesread += 1; + versionBCT[1] = (unsigned int)ColorTableData[bytesread]; + unsigned int TVersion[3]; + TVersion[0] = versionBCT[0]; + TVersion[1] = versionBCT[1] << 4; + TVersion[2] = versionBCT[1] & 15; + Header->SetTableVersion(TVersion); + + bytesread += 1; + uint32_t tmp = Conv.ByteToInt(ColorTableData, bytesread); + int n = sizeof((char*)&tmp); + //char *tmpC = DBG_NEW char[n]; + char *tmpC_CS = new char[n]; + Conv.getchar(tmp, n, tmpC_CS); + //Header.ColorSpace = DBG_NEW char[n]; + Header->SetColorSpace(tmpC_CS); + if (tmpC_CS != NULL) + { + delete [] tmpC_CS; + tmpC_CS = NULL; + } + bytesread += 4; + tmp = Conv.ByteToInt(ColorTableData, bytesread); + n = sizeof((char*)&tmp); + char *tmp_connectionspace = new char[n]; + Conv.getchar(tmp, n, tmp_connectionspace); + //Header.ConnectionSpace = DBG_NEW char[n]; + Header->SetConnectionSpace(tmp_connectionspace); + if (tmp_connectionspace != NULL) + { + delete[] tmp_connectionspace; + tmp_connectionspace = NULL; + } + + bytesread += 4; + + bytesread += 12; + tmp = Conv.ByteToInt(ColorTableData, bytesread); + n = sizeof((char*)&tmp); + char *tmp_DM = new char[n]; + Conv.getchar(tmp, n, tmp_DM); + //Header.DeviceManufacturer = DBG_NEW char[n]; + Header->SetDeviceManufacturer(tmp_DM); + // strncpy_s(Header->DeviceManufacturer, n + 1, tmpC, n); + //Header->DeviceManufacturer = tmpC; + if (tmp_DM != NULL) + { + delete [] tmp_DM; + tmp_DM = NULL; + } + + bytesread += 4; + //read illuminant + double xyz[3]; + for (int j = 0; j < 3; ++j) + { + tmp = Conv.ByteToInt(ColorTableData, bytesread); + xyz[j] = (double)(tmp) / 65536; + bytesread += 4; + } + C_RGB_XYZ_Lab XYZIllum(xyz[0], xyz[1], xyz[2]); + Header->SetIlluminant(XYZIllum); + //Read Number of Gamut Regions and Max Limits per Region + Header->SetNGamutRegions(ColorTableData[bytesread]); + bytesread++; + int nsize = Header->GetNGamutRegions(); + double *GRegMaxLim = new double[nsize]; + for (int i = 0; i < nsize; ++i) + { + tmp = Conv.ByteToShort(ColorTableData, bytesread); + bytesread += 2; + GRegMaxLim[i] = (double)tmp; + } + Header->SetGamutRegionsMaxLimit(GRegMaxLim); + if (GRegMaxLim != NULL) + { + delete[] GRegMaxLim; + GRegMaxLim = NULL; + } + + if (bytesread < 128) + { + bytesread = 128; + return(Header); + } + else + { + throw std::exception("could not read Color table Header"); + } +} + +void ColorTable::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 + // 8 - n array of XYZ numbers + + if (data_size < 8) + { + throw std::exception("not enough data to read xyz"); + } + uint8_t *buff = &(data[offset]); + NumConversions Conv; + int bytesread = 0; + int tmpxyz = Conv.ByteToInt(buff, bytesread); + + int n = sizeof(tmpxyz); + //char* tmpC = DBG_NEW char[n]; + char* tmpC = new char[n]; + Conv.getchar(tmpxyz, n, tmpC); + + char *xyztype = new char[n + 1]; + //char *xyztype = DBG_NEW char[n + 1]; + strncpy_s(xyztype, n + 1, tmpC, n); + if (strncmp(xyztype, "XYZ ", n) != 0) + { + if (xyztype != NULL) + { + delete[] xyztype; + xyztype = NULL; + } + if (tmpC != NULL) + { + delete[] tmpC; + tmpC = NULL; + } + throw std::exception("Wrong Tag Type"); + return; + } + else + { + if (xyztype != NULL) + { + delete[] xyztype; + xyztype = NULL; + } + if (tmpC != NULL) + { + delete[] tmpC; + tmpC = NULL; + } + } + bytesread = 8; + int num_values = (data_size - 8) / 4; + if (floor((double)(num_values) / 3) * 3 != num_values) + { + throw std::exception("not enough Data to read xyz"); + return; + } + double xyz[3]; + int tmp; + for (int j = 0; j < 3; ++j) + { + tmp = Conv.ByteToInt(buff, bytesread); + xyz[j] = (double)(tmp) / 65536; + bytesread += 4; + } + XYZ->Set(xyz[0], xyz[1], xyz[2]); + return; +} + +void ColorTable::read_text_type(int offset, int data_size, std::string *textstr, uint8_t *data) +{ + // 0 - 3 'text' + //4 - 7 reserved, must be 0 + //8 - string of(data_size - 8) 7 - bit ASCII characters, including NULL + + std::stringstream strstr; + if (data_size < 8) + { + throw std::exception("invalid Tag Name"); + strstr << ""; + *textstr = strstr.str(); + return; + } + + uint8_t *buff = &(data[offset]); + int bytesread = 0; + NumConversions Conv; + int tmp = Conv.ByteToInt(buff, bytesread); + int n = sizeof((char*)&tmp); + //char *tmpC = DBG_NEW char[n]; + char *tmpC = new char[n]; + Conv.getchar(tmp, n, tmpC); + char *tagtype = new char[n + 1]; + //char *tagtype = DBG_NEW char[n + 1]; + strncpy_s(tagtype, n + 1, tmpC, n); + if (strcmp(tagtype, "text") != 0) + { + throw std::exception("invalid Tag Name"); + strstr << ""; + *textstr = strstr.str(); + return; + } + if (tagtype != NULL) + { + delete[] tagtype; + tagtype = NULL; + } + if (tmpC != NULL) + { + delete[]tmpC; + tmpC = NULL; + } + bytesread += 8; + uint8_t tmp1; + for (int i = bytesread; i < data_size; ++i) + { + tmp1 = buff[i]; + strstr.put(tmp1); + } + *textstr = strstr.str(); + return; +} + +void ColorTable::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 = &(data[offset]); + int bytesread = 0; + NumConversions Conv; + int tmp = Conv.ByteToInt(buff, bytesread); + int n = sizeof((char*)&tmp); + //char *tmpC= DBG_NEW char[n]; + char *tmpC = new char[n]; + Conv.getchar(tmp, n, tmpC); + char *tagtype = new char[n + 1]; + //char *tagtype = DBG_NEW char[n + 1]; + strncpy_s(tagtype, n + 1, tmpC, n); + std::stringstream strstr; + if (strcmp(tagtype, "desc") != 0) + { + throw std::exception("invalid Tag Name"); + strstr << ""; + textdescstr = strstr.str(); + return; + } + if (tagtype != NULL) + { + delete[] tagtype; + tagtype = NULL; + } + if (tmpC != NULL) + { + delete[]tmpC; + tmpC = NULL; + } + bytesread += 8; + int count = Conv.ByteToInt(buff, bytesread); + bytesread += 4; + uint8_t tmp1; + for (int i = 0; i < count - 1; ++i) + { + tmp1 = buff[bytesread + i]; + strstr << tmp1; + } + textdescstr = strstr.str(); + return; +} + +void ColorTable::SetNormFactor() +{ + m_NormFactor = m_GamutRegionMaxLim[m_nProcessRanges - 1] / m_GamutRegionMaxLim[0]; +} + +void ColorTable::SetInverseNormFactor() +{ + if (m_NormFactor <= 0) + m_InvNormFactor = -1; + else + m_InvNormFactor = 1.0 / m_NormFactor; +} + +void ColorTable::NormGamutRegionMaxLim() +{ + double GamutRegionMaxLim0 = m_GamutRegionMaxLim[0]; + for (int i = 0; i < m_nProcessRanges; ++i) + m_GamutRegionMaxLim[i] = 100 * m_GamutRegionMaxLim[i] / GamutRegionMaxLim0; +} + + diff --git a/Software/Visual_Studio/ColorLib/Tango.ColorLib_v4/Utils/ColorTable.h b/Software/Visual_Studio/ColorLib/Tango.ColorLib_v4/Utils/ColorTable.h new file mode 100644 index 000000000..9538a4011 --- /dev/null +++ b/Software/Visual_Studio/ColorLib/Tango.ColorLib_v4/Utils/ColorTable.h @@ -0,0 +1,76 @@ +#ifndef _COLORTABLE_H_ +#define _COLORTABLE_H_ + +#include "C_RGB_XYZ_Lab.h" +#include "ColorSpace.pb-c.h" +#include "ColorTransf.h" +#include "CT_Header.h" +#include "GBD.h" +#include "Curves.h" + +typedef enum { + A2B, + A2BR, + B2A, + B2AR, + cprt, + gbd, + gbdR, + wtpt, + desc, + lcrv + // GReg +}TagList; +class ColorTable { +public: + ColorTable(); + ~ColorTable(); + void InitColorTables(bool has_rddata, uint8_t *data, int nprocessranges); + + int GetnB2AnSepIn( ){ return(m_nB2AnSepIn); }; + int GetnB2AnSepOut() { return(m_nB2AnSepOut); }; + int GetnA2BnSepIn() { return(m_nA2BnSepIn); }; + int GetnA2BnSepOut() { return(m_nA2BnSepOut); }; + int GetnGamutRegions() { return(m_nGamutRegions); }; + double GetNormFactor() { return(m_NormFactor); }; + double GetInverseNormFactor() { return(m_InvNormFactor); }; + double *GetNormGamutRegionMaxLim() { return(m_GamutRegionMaxLim); }; + int GetTableVersion() { return(m_TableVersion); }; + ColorTransf *m_B2ATransform; + ColorTransf *m_A2BTransform; + ColorTransf *m_B2ARTransform; + ColorTransf *m_A2BRTransform; + GBD *m_GBD; + GBD *m_GBDR; + Curves *m_LinCurves; +private: + void readColorTables(bool has_rddata, uint8_t *data, int nprocessranges); + void SetNormFactor(); + void SetInverseNormFactor(); + void NormGamutRegionMaxLim(); + int m_nB2AnSepIn; + int m_nB2AnSepOut; + int m_nA2BnSepIn; + int m_nA2BnSepOut; + int m_nGamutRegions; + int m_nProcessRanges; + int m_TableVersion; + double m_NormFactor; + double m_InvNormFactor; + double *m_GamutRegionMaxLim; + C_RGB_XYZ_Lab m_whitepointXYZ_CT; + void SetnB2AnSepIn(int nB2AnSepIn) { m_nB2AnSepIn = nB2AnSepIn; }; + void SetnB2AnSepOut(int nB2AnSepOut) { m_nB2AnSepOut = nB2AnSepOut; }; + void SetnA2BnSepIn(int nA2BnSepIn) { m_nA2BnSepIn = nA2BnSepIn; }; + void SetnA2BnSepOut(int nA2BnSepOut) { m_nA2BnSepOut = nA2BnSepOut; }; + void SetnGamutRegions(int nGamutRegions) { m_nGamutRegions = nGamutRegions; }; + void SetTableVersion(int TableVersion) { m_TableVersion = TableVersion; }; + CT_Header *read_header(uint8_t* data, int &bytesread); + 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, + uint8_t *data); + void read_text_description_type(int offset, int data_size, std::string textdescstr, + uint8_t *data); +}; + +#endif
\ No newline at end of file diff --git a/Software/Visual_Studio/ColorLib/Tango.ColorLib_v4/Utils/Gradient.cpp b/Software/Visual_Studio/ColorLib/Tango.ColorLib_v4/Utils/Gradient.cpp new file mode 100644 index 000000000..0066db6b3 --- /dev/null +++ b/Software/Visual_Studio/ColorLib/Tango.ColorLib_v4/Utils/Gradient.cpp @@ -0,0 +1,35 @@ +#ifdef _MSC_VER +#define _CRT_SECURE_NO_WARNINGS +#endif + +#include "Gradient.h" + +using namespace std; +Gradient::Gradient() : + m_Lab(0), m_RGB(0), + m_Volume(NULL), m_GamutRegion(0), m_Offset(0.0), m_colorspace(COLOR_SPACE__RGB), + m_InGamut(true) +{ + +} + + +Gradient::~Gradient() +{ + if (m_Volume != NULL) + { + delete[] m_Volume; + m_Volume = NULL; + } + +} + +void Gradient::SetVolumeSize(int nchannels) +{ + m_Volume = new double[nchannels]; +} + +void Gradient::SetVolumeValue(double val, int ind) +{ + m_Volume[ind] = val; +} diff --git a/Software/Visual_Studio/ColorLib/Tango.ColorLib_v4/Utils/Gradient.h b/Software/Visual_Studio/ColorLib/Tango.ColorLib_v4/Utils/Gradient.h new file mode 100644 index 000000000..278b3469d --- /dev/null +++ b/Software/Visual_Studio/ColorLib/Tango.ColorLib_v4/Utils/Gradient.h @@ -0,0 +1,37 @@ +#ifndef _GRADIENT_H_ +#define _GRADIENT_H_ + +#include "C_RGB_XYZ_Lab.h" +#include "ColorSpace.pb-c.h" +class Gradient { +public: + Gradient(); + ~Gradient(); + int Get_GamutRegion() { return(m_GamutRegion); }; + double Get_Offset() { return(m_Offset); }; + ColorSpace Get_ColorSpace() {return(m_colorspace);}; + C_RGB_XYZ_Lab Get_Lab() { return(m_Lab); }; + C_RGB_XYZ_Lab Get_RGB() { return(m_RGB); }; + bool Get_InGamut() { return(m_InGamut); }; + void Set_GamutRegion(int GamutRegion) { m_GamutRegion = GamutRegion; }; + void Set_Lab(C_RGB_XYZ_Lab Lab) { m_Lab = Lab; }; + void Set_RGB(C_RGB_XYZ_Lab RGB) { m_RGB = RGB; }; + void Set_Offset(double Offset) { m_Offset = Offset; }; + void Set_ColorSpace(ColorSpace colorspace) { m_colorspace = colorspace; }; + void SetVolumeSize(int nchannels); + void SetVolumeValue(double val, int ind); + void SetInGamut(bool InGamut) { m_InGamut = InGamut; }; + + +private: + C_RGB_XYZ_Lab m_Lab; + C_RGB_XYZ_Lab m_RGB; + double *m_Volume; + int m_GamutRegion; + double m_Offset; + ColorSpace m_colorspace; + bool m_InGamut; + +}; + +#endif
\ No newline at end of file diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ActionLogs/Views/MainView.xaml b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ActionLogs/Views/MainView.xaml index e2d65d7a3..40e282712 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ActionLogs/Views/MainView.xaml +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ActionLogs/Views/MainView.xaml @@ -4,14 +4,14 @@ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mahapps="http://metro.mahapps.com/winfx/xaml/controls" - xmlns:local="clr-namespace:Tango.MachineStudio.ActionLogs.Views" + xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes" xmlns:sharedConverters="clr-namespace:Tango.SharedUI.Converters;assembly=Tango.SharedUI" xmlns:controls="clr-namespace:Tango.SharedUI.Controls;assembly=Tango.SharedUI" xmlns:vm="clr-namespace:Tango.MachineStudio.ActionLogs.ViewModels" xmlns:global="clr-namespace:Tango.MachineStudio.ActionLogs" - xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes" xmlns:wpf="clr-namespace:MaterialDesignThemes.Wpf;assembly=MaterialDesignThemes.Wpf" xmlns:diff="clr-namespace:Tango.BL.ValueObjects;assembly=Tango.BL" + xmlns:local="clr-namespace:Tango.MachineStudio.ActionLogs.Views" mc:Ignorable="d" d:DesignHeight="1080" d:DesignWidth="1920" Background="Transparent" d:DataContext="{d:DesignInstance Type=vm:MainViewVM, IsDesignTimeCreatable=False}" DataContext="{x:Static global:ViewModelLocator.MainViewVM}"> <UserControl.Resources> @@ -60,7 +60,7 @@ </StackPanel> <DockPanel Margin="50 0 0 0" > <TextBlock DockPanel.Dock="Top" Text="Action Log Type:" VerticalAlignment="Center" FontSize="10"></TextBlock> - <ToggleButton Width="200" Margin="0 5 0 0" x:Name="selectActionsButton"> + <ToggleButton Width="200" Margin="0 5 0 0" x:Name="selectActionsButton" > <ToggleButton.Template> <ControlTemplate> <Grid> @@ -75,21 +75,16 @@ </TextBlock> </DockPanel> </Border> - <Popup StaysOpen="False" IsOpen="{Binding RelativeSource={RelativeSource AncestorType=ToggleButton},Path=IsChecked }" > - <Border Padding="5" Background="{DynamicResource ComboBox.Floating.Background}" BorderBrush="{StaticResource AutoCompleteTextBox.Popup.BorderBrush}"> - <ScrollViewer MaxHeight="600" Background="{DynamicResource ComboBox.Floating.Background}"> - <ItemsControl ItemsSource="{Binding SelectedActionLogTypes}" Foreground="{StaticResource MainWindow.Foreground}"> - <ItemsControl.ItemTemplate> - <DataTemplate> - <DockPanel Margin="2"> - <CheckBox VerticalAlignment="Center" DockPanel.Dock="Left" IsChecked="{Binding IsSelected}" > - <TextBlock Margin="5 0 0 0" VerticalAlignment="Center" Text="{Binding Data,Converter={StaticResource EnumToDescriptionConverter}}"></TextBlock> - </CheckBox> - </DockPanel> - </DataTemplate> - </ItemsControl.ItemTemplate> - </ItemsControl> - </ScrollViewer> + <Popup StaysOpen="False" IsOpen="{Binding RelativeSource={RelativeSource AncestorType=ToggleButton},Path=IsChecked }" Style="{x:Null}"> + <Border Padding="5" MaxHeight="600" Background="{DynamicResource ComboBox.Floating.Background}" BorderBrush="{StaticResource AutoCompleteTextBox.Popup.BorderBrush}" MinWidth="{Binding RelativeSource={RelativeSource AncestorType=ToggleButton},Path=ActualWidth}"> + <controls:AllSelectedCheckboxList Style="{StaticResource AllSelectedCheckBoxListStyle}" MaxHeight="600" ItemsSource="{Binding SelectedActionLogTypes}" Foreground="{StaticResource MainWindow.Foreground}" Background="{DynamicResource ComboBox.Floating.Background}" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" SelectionMode="Multiple" AllSelected="True" > + <controls:AllSelectedCheckboxList.ItemTemplate> + <DataTemplate > + <TextBlock Margin="5 0 0 0" VerticalAlignment="Center" Text="{Binding Data,Converter={StaticResource EnumToDescriptionConverter}}"/> + + </DataTemplate> + </controls:AllSelectedCheckboxList.ItemTemplate> + </controls:AllSelectedCheckboxList> </Border> </Popup> </Grid> diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Developer/Views/JobView.xaml b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Developer/Views/JobView.xaml index 5b29fd432..073ba827f 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Developer/Views/JobView.xaml +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Developer/Views/JobView.xaml @@ -756,7 +756,7 @@ <StackPanel> <TextBlock>MEDIA</TextBlock> <StackPanel Orientation="Horizontal" DockPanel.Dock="Left"> - <controls:SearchComboBox Width="250" ItemsSource="{Binding Rmls}" SelectedItem="{Binding SelectedRML}" HorizontalContentAlignment="Stretch" SearchParam="Name"> + <controls:SearchComboBox Width="250" ItemsSource="{Binding Rmls}" SelectedItem="{Binding SelectedRML}" HorizontalContentAlignment="Stretch" SearchProperty="Name"> <ComboBox.ItemTemplate> <DataTemplate> <DockPanel> diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Developer/Views/MachineJobSelectionView.xaml b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Developer/Views/MachineJobSelectionView.xaml index bf626f462..1bbcfb8fe 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Developer/Views/MachineJobSelectionView.xaml +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Developer/Views/MachineJobSelectionView.xaml @@ -190,7 +190,7 @@ </DataTemplate> </DataGridTemplateColumn.CellTemplate> </DataGridTemplateColumn> - <DataGridTemplateColumn Header="CREATED BY" Width="100" CanUserSort="True" SortMemberPath="User"> + <DataGridTemplateColumn Header="CREATED BY" Width="100" CanUserSort="True" SortMemberPath="User.Contact.FirstName"> <DataGridTemplateColumn.CellTemplate> <DataTemplate> <TextBlock Text="{Binding User.Contact.FirstName}" VerticalAlignment="Center" FontSize="14"></TextBlock> diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.HardwareDesigner/Views/MainView.xaml b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.HardwareDesigner/Views/MainView.xaml index 1c00397aa..9ee2ffee7 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.HardwareDesigner/Views/MainView.xaml +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.HardwareDesigner/Views/MainView.xaml @@ -9,6 +9,7 @@ xmlns:editors="clr-namespace:Tango.SharedUI.Editors;assembly=Tango.SharedUI" xmlns:converters="clr-namespace:Tango.SharedUI.Converters;assembly=Tango.SharedUI" xmlns:entities="clr-namespace:Tango.BL.Entities;assembly=Tango.BL" + xmlns:controls="clr-namespace:Tango.SharedUI.Controls;assembly=Tango.SharedUI" xmlns:local="clr-namespace:Tango.MachineStudio.HardwareDesigner.Views" xmlns:vm="clr-namespace:Tango.MachineStudio.HardwareDesigner.ViewModels" xmlns:observables="clr-namespace:Tango.BL.Entities;assembly=Tango.BL" @@ -57,14 +58,14 @@ <TextBlock FontSize="30" FontStyle="Italic" VerticalAlignment="Center" Margin="50 10 10 0" Foreground="Silver" FontWeight="Bold">HARDWARE DESIGNER</TextBlock> <StackPanel Orientation="Horizontal" VerticalAlignment="Center" Margin="10 10 0 0"> <materialDesign:PackIcon Kind="Pencil" Width="32" Height="32" Foreground="Silver" /> - <ComboBox IsEnabled="{Binding IsFree}" ItemsSource="{Binding HardwareVersions}" SelectedItem="{Binding SelectedVersion}" Width="300" FontSize="16" FontWeight="Bold" Margin="5 0 0 0" materialDesign:HintAssist.Hint="Hardware Version"> + <controls:SearchComboBox IsEnabled="{Binding IsFree}" ItemsSource="{Binding HardwareVersions}" SelectedItem="{Binding SelectedVersion}" Width="300" SearchProperty="FullName" FontSize="16" FontWeight="Bold" Margin="5 0 0 0" materialDesign:HintAssist.Hint="Hardware Version"> <ComboBox.ItemTemplate> <DataTemplate> <TextBlock><Run Text="{Binding Name}"></Run> <Run></Run> <Run Foreground="{StaticResource MainWindow.Foreground}" FontSize="14">v</Run><Run Foreground="{StaticResource MainWindow.Foreground}" FontSize="14" Text="{Binding Version}"></Run></TextBlock> </DataTemplate> </ComboBox.ItemTemplate> - </ComboBox> - + </controls:SearchComboBox> + </StackPanel> <Button Margin="100 10 0 0" Cursor="Hand" Height="40" FontSize="12" ToolTip="Open Comparison Wizard" Command="{Binding OpenComparisonWizardCommand}"> <StackPanel Orientation="Horizontal"> 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 229d62df7..cbb171cd6 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 @@ -314,8 +314,7 @@ namespace Tango.MachineStudio.RML.ViewModels { Rml r = rml as Rml; return String.IsNullOrWhiteSpace(RMLFilter) - || r.Name.ToLower().Contains(RMLFilter.ToLower()) //Rml name - || (r.MediaMaterial != null && r.MediaMaterial.Name.ToLower().Contains(RMLFilter.ToLower())); + || r.Name.ToLower().Contains(RMLFilter.ToLower()); }; } 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 18af6bed5..7c7194554 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 @@ -24,7 +24,7 @@ <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> + <TextBox Width="300" materialDesign:HintAssist.Hint="Search by name" Text="{Binding RMLFilter,UpdateSourceTrigger=PropertyChanged,Delay=500}"></TextBox> </StackPanel> </Grid> <Grid DockPanel.Dock="Bottom"> diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Tango.MachineStudio.Statistics.csproj b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Tango.MachineStudio.Statistics.csproj index 23b7c594c..4ce0ea87d 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Tango.MachineStudio.Statistics.csproj +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Tango.MachineStudio.Statistics.csproj @@ -78,7 +78,6 @@ <ItemGroup> <Compile Include="Converters\CollectionConverter .cs" /> <Compile Include="Converters\DateTimeToStringFormatConverter.cs" /> - <Compile Include="Converters\HeadCleaningConverter.cs" /> <Compile Include="Converters\JobLengthConverter.cs" /> <Compile Include="Converters\LiquidQuantityToFormatStringConverter.cs" /> <Compile Include="Converters\LiquidTypeToColorConverter.cs" /> diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/ViewModels/JobRunsViewVM.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/ViewModels/JobRunsViewVM.cs index 0ecb12ba7..ae1592d8d 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/ViewModels/JobRunsViewVM.cs +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/ViewModels/JobRunsViewVM.cs @@ -23,9 +23,21 @@ using Tango.BL.ValueObjects; using System.Diagnostics; using Microsoft.Win32; using Tango.CSV; +using System.ComponentModel; namespace Tango.MachineStudio.Statistics.ViewModels { + public enum HeadCleaningSelectionEnum + { + [Description("Exclude")] + Exclude = 0, + [Description("Include")] + Include = 1, + [Description("Only")] + Only = 2 + }; + + public class JobRunsViewVM : ViewModel { private INotificationProvider _notification; @@ -33,6 +45,8 @@ namespace Tango.MachineStudio.Statistics.ViewModels private List<User> _allUsers; private List<RmlModel> _rmlsModels; + + #region Properties private ObservableCollection<JobRunModel> _jobRuns; @@ -175,14 +189,14 @@ namespace Tango.MachineStudio.Statistics.ViewModels } } - private SelectedObjectCollection<bool> _isHeadCleaningSelection; + private HeadCleaningSelectionEnum _headCleaningSelected; - public SelectedObjectCollection<bool> IsHeadCleaningSelection + public HeadCleaningSelectionEnum HeadCleaningSelected { - get { return _isHeadCleaningSelection; } + get { return _headCleaningSelected; } set { - _isHeadCleaningSelection = value; + _headCleaningSelected = value; RaisePropertyChangedAuto(); } } @@ -270,17 +284,8 @@ namespace Tango.MachineStudio.Statistics.ViewModels IsGradientSelection.SelectionChanged -= (x, y) => RaisePropertyChanged(nameof(IsGradientSelection)); IsGradientSelection.SelectionChanged += (x, y) => RaisePropertyChanged(nameof(IsGradientSelection)); - IsHeadCleaningSelection = new SelectedObjectCollection<bool>(new ObservableCollection<bool>() - { - true, - false - }, new ObservableCollection<bool>() - { - true, - false - }); - IsHeadCleaningSelection.SelectionChanged -= (x, y) => RaisePropertyChanged(nameof(IsHeadCleaningSelection)); - IsHeadCleaningSelection.SelectionChanged += (x, y) => RaisePropertyChanged(nameof(IsHeadCleaningSelection)); + HeadCleaningSelected = HeadCleaningSelectionEnum.Exclude; + JobsProvider = new SuggestionProvider((filter) => { try @@ -336,8 +341,9 @@ namespace Tango.MachineStudio.Statistics.ViewModels IsFree = true; } } + } - + /// <summary> /// Loads the job runs by filters. /// </summary> @@ -407,10 +413,11 @@ namespace Tango.MachineStudio.Statistics.ViewModels { db_JobRuns = db_JobRuns.Where(x => isGradientArr.Contains(x.IsGradient)); } - bool[] isHeadCleaningArr = IsHeadCleaningSelection.SynchedSource.Select(x => (bool)x).ToArray(); - if(isHeadCleaningArr.Length > 0) + + if(HeadCleaningSelected != HeadCleaningSelectionEnum.Include) { - db_JobRuns = db_JobRuns.Where(x => isHeadCleaningArr.Contains(x.IsHeadCleaning)); + bool isHeadCleaning = HeadCleaningSelected == HeadCleaningSelectionEnum.Only; + db_JobRuns = db_JobRuns.Where(x => isHeadCleaning == x.IsHeadCleaning); } List<String> rmlGuids = SelectedThreads.SynchedSource.Select(y => y.Guid).ToList(); diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Views/JobRunsView.xaml b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Views/JobRunsView.xaml index 9e4a9603e..8724fcc2b 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Views/JobRunsView.xaml +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Views/JobRunsView.xaml @@ -13,8 +13,10 @@ xmlns:tooltips="clr-namespace:Tango.MachineStudio.Statistics.Tooltips" xmlns:sys="clr-namespace:System;assembly=mscorlib" xmlns:enumerations="clr-namespace:Tango.BL.Enumerations;assembly=Tango.BL" + xmlns:controls="clr-namespace:Tango.SharedUI.Controls;assembly=Tango.SharedUI" xmlns:local="clr-namespace:Tango.MachineStudio.Statistics.Views" xmlns:model="clr-namespace:Tango.MachineStudio.Statistics.Models" + xmlns:vs="clr-namespace:Tango.MachineStudio.Statistics.ViewModels" xmlns:wellknowntypes="clr-namespace:Google.Protobuf.WellKnownTypes;assembly=Google.Protobuf" mc:Ignorable="d" d:DesignHeight="450" d:DesignWidth="1800" Foreground="{StaticResource JobFieldForeground}"> @@ -33,7 +35,6 @@ <localConverters:NanoLiterToLiterFormatConverter x:Key="NanoLiterToLiterFormatConverter"/> <localConverters:LiquidQuantityToFormatStringConverter x:Key="LiquidQuantityToFormatStringConverter"/> <localConverters:TooltipLiquidQuantityFormatConverter x:Key="TooltipLiquidQuantityFormatConverter"/> - <localConverters:HeadCleaningConverter x:Key="HeadCleaningConverter"/> <ResourceDictionary x:Key="SelectAllTextBoxResource"> <Style TargetType="TextBox"> @@ -42,6 +43,12 @@ </Style> </ResourceDictionary> + <ObjectDataProvider x:Key="HeadCleaning" MethodName="GetValues" ObjectType="{x:Type sys:Enum}"> + <ObjectDataProvider.MethodParameters> + <x:Type TypeName="vs:HeadCleaningSelectionEnum"/> + </ObjectDataProvider.MethodParameters> + </ObjectDataProvider> + <Style TargetType="{x:Type TextBlock}" x:Key="WrapText"> <Setter Property="TextWrapping" Value="Wrap"/> </Style> @@ -55,7 +62,7 @@ <Setter Property="Background" Value="Transparent"/> <Setter Property="LegendLocation" Value="None"/> </Style> - + <DataTemplate x:Key="PopUpDataTemplate"> <CheckBox VerticalAlignment="Center" FontSize="11" DockPanel.Dock="Left" IsChecked="{Binding IsSelected}"> <CheckBox.Content> @@ -64,14 +71,6 @@ </CheckBox> </DataTemplate> - <DataTemplate x:Key="PopUpSNDataTemplate"> - <CheckBox VerticalAlignment="Center" FontSize="11" DockPanel.Dock="Left" IsChecked="{Binding IsSelected}" > - <CheckBox.Content> - <TextBlock Margin="5 0 0 0" VerticalAlignment="Center" Text="{Binding Data.SerialNumber}" ToolTip="{Binding Data.SerialNumber}" FontFamily="{StaticResource FontName}"></TextBlock> - </CheckBox.Content> - </CheckBox> - </DataTemplate> - <DataTemplate x:Key="PopupBoolDataTemplate"> <CheckBox VerticalAlignment="Center" FontSize="11" DockPanel.Dock="Left" IsChecked="{Binding IsSelected}"> <CheckBox.Content> @@ -80,22 +79,6 @@ </CheckBox> </DataTemplate> - <DataTemplate x:Key="PopupThreadDataTemplate"> - <CheckBox VerticalAlignment="Center" FontSize="11" DockPanel.Dock="Left" IsChecked="{Binding IsSelected}" > - <CheckBox.Content> - <TextBlock Margin="5 0 5 0" VerticalAlignment="Center" Text="{Binding Data.Name}" ToolTip="{Binding Data.Name}" FontFamily="{StaticResource FontName}" FontSize="11"></TextBlock> - </CheckBox.Content> - </CheckBox> - </DataTemplate> - - <DataTemplate x:Key="PopupIsHeadHeatingDataTemplate"> - <CheckBox VerticalAlignment="Center" FontSize="11" DockPanel.Dock="Left" IsChecked="{Binding IsSelected}"> - <CheckBox.Content> - <TextBlock Margin="5 0 0 0" VerticalAlignment="Center" Text="{Binding Data, Converter={StaticResource HeadCleaningConverter}}"/> - </CheckBox.Content> - </CheckBox> - </DataTemplate> - <Style x:Key="{x:Type ToolTip}" TargetType="{x:Type ToolTip}" BasedOn="{StaticResource MaterialDesignToolTip}"> <Setter Property="Background" Value="{StaticResource Logging.Background}" /> @@ -158,13 +141,18 @@ </DockPanel> </Border> <Popup AllowsTransparency="True" StaysOpen="False" IsOpen="{Binding RelativeSource={RelativeSource AncestorType=ToggleButton},Path=IsChecked }"> - <Border Padding="3" CornerRadius="0 0 3 3" MinWidth="{Binding RelativeSource={RelativeSource AncestorType=ToggleButton},Path=Width}" Margin="5" Background="{StaticResource TransparentBackgroundBrush200}" BorderBrush="{StaticResource AutoCompleteTextBox.Popup.BorderBrush}" > + <Border Padding="3" CornerRadius="0 0 3 3" MinWidth="{Binding RelativeSource={RelativeSource AncestorType=ToggleButton},Path=Width}" Margin="5" BorderBrush="{StaticResource AutoCompleteTextBox.Popup.BorderBrush}" > <Border.Effect> <DropShadowEffect Opacity="0.2" /> </Border.Effect> - <ScrollViewer MaxHeight="600" Background="{StaticResource TransparentBackgroundBrush}" > - <ItemsControl ItemsSource="{Binding SelectedMachines}" Foreground="{StaticResource MainWindow.Foreground}" ItemTemplate="{StaticResource PopUpSNDataTemplate}"/> - </ScrollViewer> + <controls:AllSelectedCheckboxList Style="{StaticResource AllSelectedCheckBoxListStyle}" MaxHeight="600" ItemsSource="{Binding SelectedMachines}" Background="{StaticResource ComboBox.Floating.Background}" Foreground="{StaticResource MainWindow.Foreground}" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" SelectionMode="Multiple" AllSelected="True" > + <controls:AllSelectedCheckboxList.ItemTemplate> + <DataTemplate > + <TextBlock Margin="5 0 0 0" VerticalAlignment="Center" Text="{Binding Data.SerialNumber}" ToolTip="{Binding Data.SerialNumber}" FontFamily="{StaticResource FontName}" Background="{DynamicResource TransparentBackgroundBrush}" FontSize="11"></TextBlock> + + </DataTemplate> + </controls:AllSelectedCheckboxList.ItemTemplate> + </controls:AllSelectedCheckboxList> </Border> </Popup> </Grid> @@ -342,10 +330,13 @@ <Border.Effect> <DropShadowEffect Opacity="0.2" /> </Border.Effect> - <ScrollViewer MaxHeight="600" Background="{StaticResource TransparentBackgroundBrush200}"> - <ItemsControl ItemsSource="{Binding SelectedThreads}" Foreground="{StaticResource MainWindow.Foreground}" ItemTemplate="{StaticResource PopupThreadDataTemplate}"/> - - </ScrollViewer> + <controls:AllSelectedCheckboxList Style="{StaticResource AllSelectedCheckBoxListStyle}" MaxHeight="600" ItemsSource="{Binding SelectedThreads}" Background="{StaticResource ComboBox.Floating.Background}" Foreground="{StaticResource MainWindow.Foreground}" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" SelectionMode="Multiple" AllSelected="True" FontSize="11"> + <controls:AllSelectedCheckboxList.ItemTemplate> + <DataTemplate > + <TextBlock Margin="5 0 0 0" VerticalAlignment="Center" Text="{Binding Data.Name}" ToolTip="{Binding Data.Name}" FontFamily="{StaticResource FontName}"></TextBlock> + </DataTemplate> + </controls:AllSelectedCheckboxList.ItemTemplate> + </controls:AllSelectedCheckboxList> </Border> </Popup> </Grid> @@ -364,18 +355,8 @@ <Button x:Name="IsHeadCleaningButton" Width="18" Padding="0" Height="16" DockPanel.Dock="Right" BorderBrush="{x:Null}" HorizontalAlignment="Left" Click="IsHeadCleaningButton_Click" Style="{StaticResource MaterialDesignFlatButton}" Foreground="{StaticResource MainWindow.Foreground}"> <materialDesign:PackIcon Width="16" Height="16" Kind="ChevronDown" VerticalAlignment="Center" Foreground="{StaticResource MainWindow.Foreground}" HorizontalAlignment="Right"/> </Button> - <TextBlock VerticalAlignment="Center" Foreground="{StaticResource MainWindow.Foreground}" FontSize="11" Margin="5 0 2 0"> - <TextBlock.Style> - <Style TargetType="{x:Type TextBlock}"> - <Setter Property="Text" Value="{Binding IsHeadCleaningSelection.SynchedSource, Converter={StaticResource CollectionConverter}, ConverterParameter='Exclude, Only'}"> - </Setter> - <Style.Triggers> - <DataTrigger Binding="{Binding IsHeadCleaningSelection.SynchedSource.Count}" Value="2"> - <Setter Property="Text" Value="Include"/> - </DataTrigger> - </Style.Triggers> - </Style> - </TextBlock.Style> + <TextBlock VerticalAlignment="Center" Foreground="{StaticResource MainWindow.Foreground}" FontSize="11" Margin="5 0 2 0" Text="{Binding HeadCleaningSelected, Converter={StaticResource EnumToDescriptionConverter}}"> + </TextBlock> </DockPanel> </Border> @@ -384,8 +365,17 @@ <Border.Effect> <DropShadowEffect Opacity="0.2" /> </Border.Effect> - <ItemsControl ItemsSource="{Binding IsHeadCleaningSelection}" Foreground="{StaticResource MainWindow.Foreground}" ItemTemplate="{StaticResource PopupIsHeadHeatingDataTemplate}"/> - + <ListBox x:Name="HeadCleaningListBoxItem" ItemsSource="{Binding Source={StaticResource HeadCleaning}}" Foreground="{StaticResource MainWindow.Foreground}" SelectedItem="{Binding HeadCleaningSelected, Mode=TwoWay}" SelectionMode="Single" > + <ListBox.ItemTemplate> + <DataTemplate> + <CheckBox x:Name="HeadCleaningCheckBox" Selector.IsSelected="True" VerticalAlignment="Center" FontSize="11" DockPanel.Dock="Left" IsChecked="{Binding IsSelected, Mode=TwoWay, RelativeSource={RelativeSource AncestorType={x:Type ListBoxItem}}, UpdateSourceTrigger=PropertyChanged}" Click="CheckBox_PreventUndoCheck"> + <CheckBox.Content> + <TextBlock Margin="5 0 0 0" VerticalAlignment="Center" Text="{Binding Converter={StaticResource EnumToDescriptionConverter}}"/> + </CheckBox.Content> + </CheckBox> + </DataTemplate> + </ListBox.ItemTemplate> + </ListBox> </Border> </Popup> </Grid> diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Views/JobRunsView.xaml.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Views/JobRunsView.xaml.cs index 9bfed23e3..226478a7d 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Views/JobRunsView.xaml.cs +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Views/JobRunsView.xaml.cs @@ -28,6 +28,8 @@ namespace Tango.MachineStudio.Statistics.Views InitializeComponent(); _lastSelectedGridItemIndex = -1; } + + private void Button_Click(object sender, RoutedEventArgs e) { selectMachineButton.IsChecked = true; @@ -127,5 +129,20 @@ namespace Tango.MachineStudio.Statistics.Views } } } + + private void CheckBox_PreventUndoCheck(object sender, RoutedEventArgs e) + { + if( sender is CheckBox) + { + CheckBox cb = sender as CheckBox; + if (cb.IsChecked == false) + { + cb.IsChecked = true; + e.Handled = true; + return; + } + } + e.Handled = false; + } } } diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Converters/HeadCleaningConverter.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.UsersAndRoles/Converters/RoleEnumToVisibleConverter.cs index 478a1deba..350257fdd 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Converters/HeadCleaningConverter.cs +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.UsersAndRoles/Converters/RoleEnumToVisibleConverter.cs @@ -4,15 +4,24 @@ using System.Globalization; using System.Linq; using System.Text; using System.Threading.Tasks; +using System.Windows; using System.Windows.Data; +using Tango.BL.Enumerations; -namespace Tango.MachineStudio.Statistics.Converters +namespace Tango.MachineStudio.UsersAndRoles.Converters { - public class HeadCleaningConverter : IValueConverter + public class RoleEnumToVisibleConverter : IValueConverter { public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { - return (bool)value ? "Only" : "Exclude"; + if(value.GetType().IsEnum && Enum.IsDefined(typeof(Roles), value)) + { + Roles roleEnum = (Roles)value; + if (roleEnum.ToString().StartsWith("FSE")) + return Visibility.Collapsed; + } + + return Visibility.Visible; } public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.UsersAndRoles/Tango.MachineStudio.UsersAndRoles.csproj b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.UsersAndRoles/Tango.MachineStudio.UsersAndRoles.csproj index 035cb2b9d..687544c1b 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.UsersAndRoles/Tango.MachineStudio.UsersAndRoles.csproj +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.UsersAndRoles/Tango.MachineStudio.UsersAndRoles.csproj @@ -75,6 +75,7 @@ <Compile Include="..\..\..\Versioning\GlobalVersionInfo.cs"> <Link>GlobalVersionInfo.cs</Link> </Compile> + <Compile Include="Converters\RoleEnumToVisibleConverter.cs" /> <Compile Include="Navigation\UsersAndRolesNavigationManager.cs" /> <Compile Include="Navigation\UsersAndRolesNavigationView.cs" /> <Compile Include="Providers\PlaceAddress.cs" /> @@ -226,10 +227,11 @@ <ItemGroup> <Resource Include="Images\login.png" /> </ItemGroup> + <ItemGroup /> <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> <ProjectExtensions> <VisualStudio> - <UserProperties BuildVersion_AssemblyInfoFilename="Properties\AssemblyInfo.cs" BuildVersion_UpdateAssemblyVersion="True" BuildVersion_BuildVersioningStyle="None.None.Increment.TimeStamp" BuildVersion_UseGlobalSettings="False" BuildVersion_StartDate="2000/1/1" /> + <UserProperties BuildVersion_StartDate="2000/1/1" BuildVersion_UseGlobalSettings="False" BuildVersion_BuildVersioningStyle="None.None.Increment.TimeStamp" BuildVersion_UpdateAssemblyVersion="True" BuildVersion_AssemblyInfoFilename="Properties\AssemblyInfo.cs" /> </VisualStudio> </ProjectExtensions> </Project>
\ No newline at end of file diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.UsersAndRoles/Views/UserManagementView.xaml b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.UsersAndRoles/Views/UserManagementView.xaml index 3964abfc8..2a8621e5c 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.UsersAndRoles/Views/UserManagementView.xaml +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.UsersAndRoles/Views/UserManagementView.xaml @@ -14,6 +14,7 @@ xmlns:entities="clr-namespace:Tango.BL.Entities;assembly=Tango.BL" xmlns:local="clr-namespace:Tango.MachineStudio.UsersAndRoles.Views" xmlns:converters="clr-namespace:Tango.SharedUI.Converters;assembly=Tango.SharedUI" + xmlns:localconverters="clr-namespace:Tango.MachineStudio.UsersAndRoles.Converters" mc:Ignorable="d" d:DesignHeight="1080" d:DesignWidth="1920" d:DataContext="{d:DesignInstance Type=vm:MainViewVM, IsDesignTimeCreatable=False}" DataContext="{x:Static global:ViewModelLocator.MainViewVM}"> @@ -21,6 +22,7 @@ <providers:PlacesProvider x:Key="PlacesProvider" /> <converters:BooleanToVisibilityConverter x:Key="BoolToVisibilityConverter"></converters:BooleanToVisibilityConverter> <converters:BooleanToVisibilityInverseConverter x:Key="BooleanToVisibilityInverseConverter"></converters:BooleanToVisibilityInverseConverter> + <localconverters:RoleEnumToVisibleConverter x:Key="RoleEnumToVisibleConverter"/> </UserControl.Resources> <Grid> @@ -103,7 +105,7 @@ </ListBox.ItemsPanel> <ListBox.ItemTemplate> <DataTemplate DataType="{x:Type entities:Role}"> - <Grid> + <Grid Visibility="{Binding RoleEnum, Converter={StaticResource RoleEnumToVisibleConverter}}"> <Grid.ToolTip> <StackPanel Background="Transparent"> <TextBlock Text="{Binding Description}" FontSize="10" Margin="0 0 0 10"></TextBlock> @@ -175,7 +177,7 @@ <ListBox ItemsSource="{Binding Roles}" ItemContainerStyle="{StaticResource basicListBoxItem}" HorizontalContentAlignment="Stretch" Background="Transparent"> <ListBox.ItemTemplate> <DataTemplate> - <Grid Background="Transparent" IsHitTestVisible="True" Style="{StaticResource draggableGrid}" dragAndDrop:DragAndDropService.DraggableBorderBrush="{StaticResource AccentColorBrush}" dragAndDrop:DragAndDropService.Draggable="True" dragAndDrop:DragAndDropService.DraggingSurface="{Binding RelativeSource={RelativeSource AncestorType=UserControl},Path=DraggingSurface}"> + <Grid Background="Transparent" IsHitTestVisible="True" Style="{StaticResource draggableGrid}" dragAndDrop:DragAndDropService.DraggableBorderBrush="{StaticResource AccentColorBrush}" dragAndDrop:DragAndDropService.Draggable="True" dragAndDrop:DragAndDropService.DraggingSurface="{Binding RelativeSource={RelativeSource AncestorType=UserControl},Path=DraggingSurface}" Visibility="{Binding RoleEnum, Converter={StaticResource RoleEnumToVisibleConverter}}"> <Grid.ToolTip> <StackPanel Background="Transparent"> <TextBlock Text="{Binding Description}" FontSize="10" Margin="0 0 0 10"></TextBlock> diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Resources/MaterialDesign.xaml b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Resources/MaterialDesign.xaml index c8e216191..007712d87 100644 --- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Resources/MaterialDesign.xaml +++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Resources/MaterialDesign.xaml @@ -772,16 +772,77 @@ <Setter Property="Background" Value="Transparent"/> <Setter Property="Template"> <Setter.Value> - <ControlTemplate TargetType="{x:Type ComboBox}" > + <ControlTemplate TargetType="{x:Type controls:SearchComboBox}"> <Grid x:Name="templateRoot" Background="Transparent" SnapsToDevicePixels="True"> <Grid x:Name="InnerRoot"> <Grid.ColumnDefinitions> <ColumnDefinition Width="*" /> <ColumnDefinition Width="0" MinWidth="{DynamicResource {x:Static SystemParameters.VerticalScrollBarWidthKey}}" /> </Grid.ColumnDefinitions> - <ToggleButton x:Name="SearchToggleButton" Grid.ColumnSpan="2" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" - BorderThickness="{TemplateBinding BorderThickness}" IsChecked="{Binding IsDropDownOpen, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}" - Style="{StaticResource MaterialDesignComboBoxToggleButton}"/> + <ToggleButton x:Name="SearchToggleButton" Grid.ColumnSpan="2" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" IsChecked="{Binding IsOpened, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}" Style="{x:Null}"> + <ToggleButton.Template> + <ControlTemplate TargetType="ToggleButton"> + <Grid> + <Border x:Name="ToggleTemplateRoot" + Background="{TemplateBinding Background}" + BorderBrush="{TemplateBinding BorderBrush}" + BorderThickness="{TemplateBinding BorderThickness}"> + <Border x:Name="splitBorder" + Margin="0" + HorizontalAlignment="Right" + VerticalAlignment="Center" + BorderBrush="Transparent" + BorderThickness="0"> + <Path x:Name="arrow" + Width="8" Height="8" + Margin="0" + Stretch="Uniform" + HorizontalAlignment="Right" + VerticalAlignment="Center" + Data="M7,10L12,15L17,10H7Z" + Fill="{TemplateBinding BorderBrush}" /> + </Border> + </Border> + </Grid> + <ControlTemplate.Triggers> + <MultiDataTrigger> + <MultiDataTrigger.Conditions> + <Condition Binding="{Binding IsMouseOver, RelativeSource={RelativeSource Self}}" Value="true" /> + <Condition Binding="{Binding IsEditable, RelativeSource={RelativeSource AncestorType={x:Type ComboBox}}}" Value="false" /> + </MultiDataTrigger.Conditions> + </MultiDataTrigger> + <MultiDataTrigger> + <MultiDataTrigger.Conditions> + <Condition Binding="{Binding IsMouseOver, RelativeSource={RelativeSource Self}}" Value="true" /> + <Condition Binding="{Binding IsEditable, RelativeSource={RelativeSource AncestorType={x:Type ComboBox}}}" Value="true" /> + </MultiDataTrigger.Conditions> + <Setter Property="BorderBrush" Value="{DynamicResource PrimaryHueMidBrush}" /> + </MultiDataTrigger> + <Trigger Property="IsPressed" Value="true"> + <Setter TargetName="arrow" Property="Fill" Value="{DynamicResource PrimaryHueDarkBrush}" /> + </Trigger> + <Trigger Property="IsEnabled" Value="false"> + <Setter TargetName="arrow" Property="Fill" Value="{DynamicResource MaterialDesignCheckBoxDisabled}" /> + </Trigger> + <MultiDataTrigger> + <MultiDataTrigger.Conditions> + <Condition Binding="{Binding IsEnabled, RelativeSource={RelativeSource Self}}" Value="false" /> + <Condition Binding="{Binding IsEditable, RelativeSource={RelativeSource AncestorType={x:Type ComboBox}}}" Value="false" /> + </MultiDataTrigger.Conditions> + <Setter TargetName="ToggleTemplateRoot" Property="BorderBrush" Value="Transparent"/> + </MultiDataTrigger> + <MultiDataTrigger> + <MultiDataTrigger.Conditions> + <Condition Binding="{Binding IsEnabled, RelativeSource={RelativeSource Self}}" Value="false" /> + <Condition Binding="{Binding IsEditable, RelativeSource={RelativeSource AncestorType={x:Type ComboBox}}}" Value="true" /> + </MultiDataTrigger.Conditions> + <Setter TargetName="ToggleTemplateRoot" Property="BorderBrush" Value="Transparent"/> + <Setter TargetName="splitBorder" Property="BorderBrush" Value="{DynamicResource MaterialDesignCheckBoxDisabled}" /> + </MultiDataTrigger> + </ControlTemplate.Triggers> + </ControlTemplate> + </ToggleButton.Template> + </ToggleButton> <Grid HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" Margin="{TemplateBinding Padding}" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" UseLayoutRounding="{TemplateBinding UseLayoutRounding}"> <Grid x:Name="InputRoot" HorizontalAlignment="Left"> <ContentPresenter x:Name="contentPresenter" Content="{TemplateBinding SelectionBoxItem}" ContentStringFormat="{TemplateBinding SelectionBoxItemStringFormat}" ContentTemplate="{TemplateBinding SelectionBoxItemTemplate}" ContentTemplateSelector="{TemplateBinding ItemTemplateSelector}" IsHitTestVisible="False" /> @@ -798,35 +859,25 @@ </Grid> </Grid> <Line x:Name="DashedLine" Grid.ColumnSpan="2" VerticalAlignment="Bottom" Visibility="{Binding Path=IsEnabled, RelativeSource={RelativeSource Self}, Converter={StaticResource InverseBoolToVisConverter}}" StrokeThickness="1.25" StrokeDashArray="1,2.5" StrokeDashCap="Round" X1="0" X2="{Binding ActualWidth, ElementName=SearchToggleButton}" Y1="0" Y2="0" Stroke="{TemplateBinding BorderBrush}" Opacity="0.56" /> - <materialDesign:Underline x:Name="Underline" Grid.ColumnSpan="2" IsActive="{Binding ElementName=PART_EditableTextBox, Path=IsKeyboardFocused}" - Visibility="{Binding Path=(materialDesign:TextFieldAssist.DecorationVisibility), RelativeSource={RelativeSource TemplatedParent}}"/> + <materialDesign:Underline x:Name="Underline" Grid.ColumnSpan="2" IsActive="{Binding ElementName=PART_EditableTextBox, Path=IsKeyboardFocused}" Visibility="{Binding Path=(materialDesign:TextFieldAssist.DecorationVisibility), RelativeSource={RelativeSource TemplatedParent}}"/> - <controls:PopupWithKeyboardFocus x:Name="PART_Popup" AllowsTransparency="true" Focusable="False" HorizontalOffset="-11.5" - Tag="{Binding RelativeSource={RelativeSource AncestorType=controls:SearchComboBox}}" IsOpen="{Binding ElementName=SearchToggleButton,Path=IsChecked}" PlacementTarget="{Binding ElementName=templateRoot}" - SnapsToDevicePixels="True" UseLayoutRounding="True" Placement="Custom" PopupAnimation="Fade" VerticalOffset="-10" DefaultVerticalOffset="5" - DownVerticalOffset="{Binding ElementName=templateRoot, Path=ActualHeight}" UpVerticalOffset="15" ClassicMode="{Binding Path=(materialDesign:ComboBoxAssist.ClassicMode), RelativeSource={RelativeSource TemplatedParent}}" - UpContentTemplate="{StaticResource PopupContentUpTemplate}" DownContentTemplate="{StaticResource TransparentPopupContentDownTemplate}" ClassicContentTemplate="{StaticResource PopupContentClassicTemplate}"> + <materialDesign:ComboBoxPopup x:Name="PART_Popup" AllowsTransparency="true" HorizontalOffset="0" Tag="{Binding RelativeSource={RelativeSource AncestorType=controls:SearchComboBox}}" IsOpen="{Binding RelativeSource={RelativeSource Mode=TemplatedParent},Path=IsOpened, Mode=TwoWay}" PlacementTarget="{Binding ElementName=templateRoot}" SnapsToDevicePixels="True" UseLayoutRounding="True" Placement="Bottom" PopupAnimation="Fade" VerticalOffset="-10" DefaultVerticalOffset="5" + MinWidth="{Binding ElementName=SearchToggleButton,Path=ActualWidth}" DownVerticalOffset="{Binding ElementName=templateRoot, Path=ActualHeight}" UpVerticalOffset="15" ClassicMode="{Binding Path=(materialDesign:ComboBoxAssist.ClassicMode), RelativeSource={RelativeSource TemplatedParent}}" + MaxHeight="{TemplateBinding MaxDropDownHeight}" UpContentTemplate="{StaticResource PopupContentUpTemplate}" DownContentTemplate="{StaticResource TransparentPopupContentDownTemplate}" ClassicContentTemplate="{StaticResource PopupContentClassicTemplate}" StaysOpen="False" Margin="10 0 0 0"> <ContentControl> <Border Opacity="1" Background="{DynamicResource ComboBox.Floating.Background}" Padding="1" BorderThickness="0" BorderBrush="{TemplateBinding BorderBrush}" MaxHeight="{TemplateBinding MaxDropDownHeight}" > - <Grid > - <Grid.RowDefinitions> - <RowDefinition Height="30"/> - <RowDefinition Height="1*"/> - </Grid.RowDefinitions> - <TextBox x:Name="Search" Grid.Row="0" HorizontalAlignment="Stretch" Text="{Binding RelativeSource={RelativeSource AncestorType=controls:SearchComboBox}, Path=SearchText}" Background="{DynamicResource ComboBox.Floating.Background}" IsReadOnly="False" FontSize="14" TextAlignment="Left" VerticalAlignment="Center" VerticalContentAlignment="Center" BorderThickness="0 0 0 2" Margin=" 1 0 1 0"> + <DockPanel> + <TextBox x:Name="Search" DockPanel.Dock="Top" Margin="10" Padding="0 5" HorizontalAlignment="Stretch" Text="{Binding RelativeSource={RelativeSource AncestorType=controls:SearchComboBox}, Path=SearchFilter, Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" Background="{DynamicResource ComboBox.Floating.Background}" IsReadOnly="False" FontSize="14" TextAlignment="Left" VerticalAlignment="Center" VerticalContentAlignment="Center" BorderThickness="0 0 0 2" > <TextBox.Style> <Style TargetType="TextBox"/> </TextBox.Style> </TextBox> - <ScrollViewer Grid.Row="1" Background="{DynamicResource ComboBox.Floating.Background}" VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Hidden"> + <ListBox x:Name="list" ItemsSource="{Binding RelativeSource={RelativeSource AncestorType=controls:SearchComboBox}, Path = ListItemsSource}" ItemTemplate="{TemplateBinding ItemTemplate}"/> - <ItemsPresenter x:Name="ItemsPresenter" KeyboardNavigation.DirectionalNavigation="Contained"/> - - </ScrollViewer> - </Grid> + </DockPanel> </Border> </ContentControl> - </controls:PopupWithKeyboardFocus> + </materialDesign:ComboBoxPopup> </Grid> </Grid> <ControlTemplate.Triggers> @@ -926,6 +977,52 @@ </Setter> </Style> + <Style x:Key="CheckBoxListBoxItem" TargetType="{x:Type ListBoxItem}"> + <Setter Property="SnapsToDevicePixels" Value="true" /> + <Setter Property="Template"> + <Setter.Value> + <ControlTemplate TargetType="ListBoxItem"> + <CheckBox Margin="5,2" IsChecked="{TemplateBinding IsSelected}" x:Name="CheckBoxItem" + Command="{Binding RelativeSource={RelativeSource AncestorType=controls:AllSelectedCheckboxList}, Path=ClickCheckBoxCommand}" CommandParameter="{Binding RelativeSource={RelativeSource TemplatedParent}}"> + <ContentPresenter /> + </CheckBox> + </ControlTemplate> + </Setter.Value> + </Setter> + </Style> + + <Style x:Key="AllSelectedCheckBoxListStyle" TargetType="{x:Type controls:AllSelectedCheckboxList}" BasedOn="{StaticResource MaterialDesignListBox}"> + <!--<Setter Property="OverridesDefaultStyle" Value="true" />--> + <Setter Property="SnapsToDevicePixels" Value="true" /> + <Setter Property="SelectionMode" Value="Multiple"/> + <Setter Property="ItemContainerStyle" Value="{StaticResource CheckBoxListBoxItem}"/> + <Setter Property="Template"> + <Setter.Value> + <ControlTemplate TargetType="{x:Type controls:AllSelectedCheckboxList}"> + <Border x:Name="Bd" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" SnapsToDevicePixels="true"> + <DockPanel> + <CheckBox x:Name="SelectAllCheckBox" DockPanel.Dock="Top" VerticalAlignment="Center" IsChecked="{Binding AllSelected, Mode=TwoWay,RelativeSource={RelativeSource AncestorType=controls:AllSelectedCheckboxList}}" Margin="5"> + <TextBlock Margin="5 0 0 0" VerticalAlignment="Center" Text="SelectAll"></TextBlock> + </CheckBox> + <ScrollViewer DockPanel.Dock="Bottom" Focusable="false" Padding="{TemplateBinding Padding}"> + <ItemsPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/> + </ScrollViewer> + </DockPanel> + </Border> + <ControlTemplate.Triggers> + <MultiTrigger> + <MultiTrigger.Conditions> + <Condition Property="IsGrouping" Value="true"/> + <Condition Property="VirtualizingPanel.IsVirtualizingWhenGrouping" Value="false"/> + </MultiTrigger.Conditions> + <Setter Property="ScrollViewer.CanContentScroll" Value="false"/> + </MultiTrigger> + </ControlTemplate.Triggers> + </ControlTemplate> + </Setter.Value> + </Setter> + </Style> + <Style TargetType="Window"> <Setter Property="FontFamily" Value="{StaticResource flexo}"></Setter> </Style> diff --git a/Software/Visual_Studio/Tango.BL/Entities/HardwareVersion.cs b/Software/Visual_Studio/Tango.BL/Entities/HardwareVersion.cs index ed8596192..590fe9e13 100644 --- a/Software/Visual_Studio/Tango.BL/Entities/HardwareVersion.cs +++ b/Software/Visual_Studio/Tango.BL/Entities/HardwareVersion.cs @@ -1,5 +1,7 @@ +using Newtonsoft.Json; using System; using System.Collections.Generic; +using System.ComponentModel.DataAnnotations.Schema; using System.Linq; using System.Text; using System.Threading.Tasks; @@ -93,6 +95,13 @@ namespace Tango.BL.Entities }); } + [NotMapped] + [JsonIgnore] + public String FullName + { + get { return $"{Name} v{Version}"; } + } + /// <summary> /// Initializes a new instance of the <see cref="HardwareVersion" /> class. /// </summary> diff --git a/Software/Visual_Studio/Tango.SharedUI/Components/SelectedObject.cs b/Software/Visual_Studio/Tango.SharedUI/Components/SelectedObject.cs index f91e93b5a..d85777292 100644 --- a/Software/Visual_Studio/Tango.SharedUI/Components/SelectedObject.cs +++ b/Software/Visual_Studio/Tango.SharedUI/Components/SelectedObject.cs @@ -7,18 +7,20 @@ using Tango.Core; namespace Tango.SharedUI.Components { - public class SelectedObject<T> : ExtendedObject + public class SelectedObject : ExtendedObject { public event EventHandler IsSelectedChanged; private bool _isSelected; - public bool IsSelected { get { return _isSelected; } set { _isSelected = value; RaisePropertyChangedAuto(); IsSelectedChanged?.Invoke(this, new EventArgs()); } } + } + public class SelectedObject<T> : SelectedObject + { private T _data; public T Data diff --git a/Software/Visual_Studio/Tango.SharedUI/Controls/AllSelectedCheckboxList.cs b/Software/Visual_Studio/Tango.SharedUI/Controls/AllSelectedCheckboxList.cs new file mode 100644 index 000000000..6e3cb862f --- /dev/null +++ b/Software/Visual_Studio/Tango.SharedUI/Controls/AllSelectedCheckboxList.cs @@ -0,0 +1,144 @@ +using System; +using System.Windows; +using System.Windows.Controls; +using Tango.Core.Commands; +//using System.Collections; +using System.Linq; +using System.Collections; + +namespace Tango.SharedUI.Controls +{ + public class AllSelectedCheckboxList : ListBox + { + #region Properties + + private ItemsControl _itemsControl; + + public ItemsControl ItemsControl + { + get { return _itemsControl; } + set { _itemsControl = value; } + } + + public bool? AllSelected + { + get { return (bool?)GetValue(AllSelectedProperty); } + set + { + SetValue(AllSelectedProperty, value); + } + } + + public static readonly DependencyProperty AllSelectedProperty = + DependencyProperty.Register("AllSelected", typeof(bool?), typeof(AllSelectedCheckboxList), new FrameworkPropertyMetadata(false, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, new PropertyChangedCallback(OnAllSelectedChanged))); + + + private static void OnAllSelectedChanged(DependencyObject o, DependencyPropertyChangedEventArgs e) + { + AllSelectedCheckboxList l = o as AllSelectedCheckboxList; + var nv = e.NewValue; + l.AllSelectedChanged((bool?)nv); + } + + public static DependencyProperty ClickCheckBoxCommandProperty = DependencyProperty.Register("ClickCheckBoxCommand", typeof(RelayCommand<object>), typeof(AllSelectedCheckboxList)); + public RelayCommand<object> ClickCheckBoxCommand + { + get { return (RelayCommand<object>)GetValue(ClickCheckBoxCommandProperty); } + private set { SetValue(ClickCheckBoxCommandProperty, value); } + } + + #endregion + + #region "Constructors" + + static AllSelectedCheckboxList() + { + DefaultStyleKeyProperty.OverrideMetadata(typeof(AllSelectedCheckboxList), new FrameworkPropertyMetadata(typeof(AllSelectedCheckboxList))); + + } + public AllSelectedCheckboxList() : base() + { + ClickCheckBoxCommand = new RelayCommand<object>(ClickCheckBox); + } + + /// <summary> + /// Clicks the CheckBox.Update Selection ListBoxitem. + /// </summary> + /// <param name="obj">The object.</param> + private void ClickCheckBox(object obj) + { + if (obj is ListBoxItem) + { + ListBoxItem lbItem = obj as ListBoxItem; + CheckBox checkBox = lbItem.FindVisualChildren<CheckBox>().FirstOrDefault(); + if (checkBox != null) + { + bool? check = checkBox.IsChecked; + if (check != null) + { + lbItem.IsSelected = (bool)check; + } + } + } + + if (SelectedItems.Count == 0) + { + AllSelected = false; + } + else if (Items.Count > 0 && SelectedItems.Count == Items.Count) + { + AllSelected = true; + } + else + { + AllSelected = null; + } + } + + #endregion + + #region Override + + /// <summary> + /// When overridden in a derived class, is invoked whenever application code or internal processes call <see cref="M:System.Windows.FrameworkElement.ApplyTemplate" />. + /// </summary> + public override void OnApplyTemplate() + { + base.OnApplyTemplate(); + AllSelectedChanged(AllSelected); + + + + } + + protected override void OnSelectionChanged(SelectionChangedEventArgs e) + { + base.OnSelectionChanged(e); + foreach(var addItem in e.AddedItems.OfType<Components.SelectedObject>()) + { + addItem.IsSelected = true; + } + foreach (var removeItem in e.RemovedItems.OfType<Components.SelectedObject>()) + { + removeItem.IsSelected = false; + } + } + + #endregion + + private void AllSelectedChanged(bool? value) + { + if (value == null) + return; + SelectionMode = SelectionMode.Multiple; + if (value == true) + { + SelectAll(); + } + else + { + UnselectAll(); + } + } + } +} diff --git a/Software/Visual_Studio/Tango.SharedUI/Controls/PopupWithKeyboardFocus.cs b/Software/Visual_Studio/Tango.SharedUI/Controls/PopupWithKeyboardFocus.cs deleted file mode 100644 index 9426b95cf..000000000 --- a/Software/Visual_Studio/Tango.SharedUI/Controls/PopupWithKeyboardFocus.cs +++ /dev/null @@ -1,42 +0,0 @@ -using MaterialDesignThemes.Wpf; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Runtime.InteropServices; -using System.Text; -using System.Threading.Tasks; -using System.Windows; -using System.Windows.Controls.Primitives; -using System.Windows.Input; -using System.Windows.Interop; - -namespace Tango.SharedUI.Controls -{ - public class PopupWithKeyboardFocus: ComboBoxPopup - { - [DllImport("user32.dll")] - static extern IntPtr SetActiveWindow(IntPtr hWnd); - - static PopupWithKeyboardFocus() - { - EventManager.RegisterClassHandler( - typeof(PopupWithKeyboardFocus), - Popup.PreviewGotKeyboardFocusEvent, - new KeyboardFocusChangedEventHandler(OnPreviewGotKeyboardFocus), - true); - } - - private static void OnPreviewGotKeyboardFocus(Object sender, KeyboardFocusChangedEventArgs e) - { - var textBox = e.NewFocus as TextBoxBase; - if (textBox != null) - { - var hwndSource = PresentationSource.FromVisual(textBox) as HwndSource; - if (hwndSource != null) - { - SetActiveWindow(hwndSource.Handle); - } - } - } - } -} diff --git a/Software/Visual_Studio/Tango.SharedUI/Controls/SearchComboBox.cs b/Software/Visual_Studio/Tango.SharedUI/Controls/SearchComboBox.cs index f9d65bd2b..8fc6483e9 100644 --- a/Software/Visual_Studio/Tango.SharedUI/Controls/SearchComboBox.cs +++ b/Software/Visual_Studio/Tango.SharedUI/Controls/SearchComboBox.cs @@ -1,104 +1,63 @@ using System; +using System.Collections; using System.Collections.ObjectModel; +using System.ComponentModel; using System.Diagnostics; +using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; using System.Windows.Controls.Primitives; using System.Windows.Data; using System.Windows.Input; +using System.Linq; using System.Windows.Media; using System.Windows.Threading; namespace Tango.SharedUI.Controls { [TemplatePart(Name = SearchComboBox.PartEditor, Type = typeof(System.Windows.Controls.TextBox))] - [TemplatePart(Name = SearchComboBox.PartPopup, Type = typeof(Popup))] public class SearchComboBox : ComboBox { public const string PartEditor = "Search"; - public const string PartPopup = "PART_Popup"; - private int _savedSelectedIndex = -1; - private bool _editorMouseLeaveFlag = false; - #region Properties - - private TextBox _editor; - - public TextBox Editor - { - get { return _editor; } - set { _editor = value; } - } - - - private Popup _popup; - - public Popup Popup - { - get { return _popup; } - set { _popup = value; } - } - - private DispatcherTimer _fetchTimer; - - public DispatcherTimer FetchTimer - { - get { return _fetchTimer; } - set { _fetchTimer = value; } - } - + private TextBox _textBox; + private ListBox _listBox; + private ICollectionView _view; - private string _searchText = ""; - /// <summary> - /// Gets or sets the search text of TextBox. - /// </summary> - public string SearchText + #region Properties + public bool IsOpened { - get { return _searchText; } - set - { - if(_searchText != value && value != null) - { - _searchText = value; - } - - } + get { return (bool)GetValue(IsOpenedProperty); } + set { SetValue(IsOpenedProperty, value); } } + public static readonly DependencyProperty IsOpenedProperty = + DependencyProperty.Register("IsOpened", typeof(bool), typeof(SearchComboBox), new PropertyMetadata(false, (d, e) => (d as SearchComboBox).OnIsOpenedChanged())); - public ListCollectionView SearchItemsList + public String SearchProperty { - get { return (ListCollectionView)GetValue(SearchItemsListProperty); } - set { SetValue(SearchItemsListProperty, value); } + get { return (String)GetValue(SearchPropertyProperty); } + set { SetValue(SearchPropertyProperty, value); } } - /// <summary> - /// The search items list property for popup items list - /// </summary> - public static readonly DependencyProperty SearchItemsListProperty = - DependencyProperty.Register("SearchItemsList", typeof(ListCollectionView), typeof(SearchComboBox), new PropertyMetadata(default(ObservableCollection<string>))); - + public static readonly DependencyProperty SearchPropertyProperty = + DependencyProperty.Register("SearchProperty", typeof(String), typeof(SearchComboBox), new PropertyMetadata(null)); - public string SearchParam + public String SearchFilter { - get { return (string)GetValue(SearchParamProperty); } - set { SetValue(SearchParamProperty, value); } + get { return (String)GetValue(SearchFilterProperty); } + set { SetValue(SearchFilterProperty, value); } } + public static readonly DependencyProperty SearchFilterProperty = + DependencyProperty.Register("SearchFilter", typeof(String), typeof(SearchComboBox), new PropertyMetadata(null, (d, e) => (d as SearchComboBox).OnFilterChanged())); - public static readonly DependencyProperty SearchParamProperty = - DependencyProperty.Register("SearchParam", typeof(string), typeof(SearchComboBox), new FrameworkPropertyMetadata("")); - - public System.Collections.IList SourceItems + public IEnumerable ListItemsSource { - get { return (System.Collections.IList)GetValue(SourceItemsProperty); } - set { SetValue(SourceItemsProperty, value); } + get { return (IEnumerable)GetValue(ListItemsSourceProperty); } + set { SetValue(ListItemsSourceProperty, value); } } - - public static readonly DependencyProperty SourceItemsProperty = - DependencyProperty.Register("SourceItems", typeof(System.Collections.IList), typeof(SearchComboBox), new PropertyMetadata(default(System.Collections.IList))); - + public static readonly DependencyProperty ListItemsSourceProperty = + DependencyProperty.Register("ListItemsSource", typeof(IEnumerable), typeof(SearchComboBox), new PropertyMetadata(null)); #endregion - - #region Constructors static SearchComboBox() @@ -106,203 +65,117 @@ namespace Tango.SharedUI.Controls DefaultStyleKeyProperty.OverrideMetadata(typeof(SearchComboBox), new FrameworkPropertyMetadata(typeof(SearchComboBox))); } - public SearchComboBox() - { - - } - #endregion //Constructors - - #region override - protected override void OnLostMouseCapture(MouseEventArgs e) - { - if (Mouse.Captured == null) - { - if (e.OriginalSource == this) - { - //SetPopupState(); - } - else if (IsDropDownOpen) - { - Mouse.Capture(this, CaptureMode.SubTree); - } - } - - base.OnLostMouseCapture(e); - } - - /// <summary> - /// Responds to a <see cref="T:System.Windows.Controls.ComboBox" /> selection change by raising a <see cref="E:System.Windows.Controls.Primitives.Selector.SelectionChanged" /> event. - /// Change selection only on click on item - /// </summary> - /// <param name="e">Provides data for <see cref="T:System.Windows.Controls.SelectionChangedEventArgs" />.</param> - protected override void OnSelectionChanged(SelectionChangedEventArgs e) - { - if (Editor == null || !Editor.IsKeyboardFocused || ( Editor.IsKeyboardFocused && _editorMouseLeaveFlag ) ) - { - base.OnSelectionChanged(e); - if (e.AddedItems.Count != 0 && SelectedIndex != this.SourceItems.IndexOf(e.AddedItems[0])) - { - SelectedValue = e.AddedItems[0]; - } - } - e.Handled = true; - } - - - #endregion - #region Initialization - - void InitSelectedList() - { - if (SearchItemsList == null) - { - SearchItemsList = new ListCollectionView(this.SourceItems); - if (String.IsNullOrEmpty(SearchParam)) - SearchItemsList.Filter = null; - else - { - SearchItemsList.Filter = (ob) => - { - var prop = ob.GetType().GetProperty(SearchParam); - if (prop == null) - { - return true; - } - string value = prop.GetValue(ob, null) as string; - return value != null && (String.IsNullOrEmpty(SearchText) || value.ToLower().Contains(SearchText.ToLower())); - }; - } - Binding mbinding = new Binding("SearchItems"); - mbinding.Mode = BindingMode.Default; - mbinding.Source = this; - mbinding.Path = new PropertyPath("SearchItemsList"); - - SetBinding(ComboBox.ItemsSourceProperty, mbinding); - } - } + /// <summary> /// When overridden in a derived class, is invoked whenever application code or internal processes call <see cref="M:System.Windows.FrameworkElement.ApplyTemplate" />. /// </summary> public override void OnApplyTemplate() { base.OnApplyTemplate(); - - var binding1 = BindingOperations.GetBinding(this, ComboBox.ItemsSourceProperty); - SetBinding(SearchComboBox.SourceItemsProperty, binding1); - Popup = Template.FindName(PartPopup, this) as Popup; - - if (Popup != null) + + _textBox = GetTemplateChild(PartEditor) as TextBox; + if(_textBox != null) { - Popup.StaysOpen = false; - Popup.Opened += OnPopupOpened; - Popup.Closed += OnPopupClosed; - + _textBox.PreviewKeyDown += _textBox_KeyDown; } - Editor = Template.FindName(PartEditor, this) as TextBox; - if(Editor != null) + _listBox = GetTemplateChild("list") as ListBox; + if(_listBox != null) { - Editor.TextChanged += OnEditorTextChanged; - Editor.MouseLeave += Editor_MouseLeave; - Editor.MouseEnter += Editor_MouseEnter; + _listBox.PreviewKeyDown += _listBox_PreviewKeyDown; + _listBox.PreviewMouseLeftButtonUp += _listBox_PreviewMouseLeftButtonUp; } } #endregion - #region EventHandlers - - private void Popup_KeyDown(object sender, KeyEventArgs e) + #region Event Handlers + private void _listBox_PreviewKeyDown(object sender, KeyEventArgs e) { - if (Editor != null ) + if (e.Key == Key.Return) { - Editor.Focus(); - Keyboard.Focus(Editor); + IsOpened = false; + SelectedItem = _listBox.SelectedItem; } } - private void OnPopupOpened(object sender, EventArgs e) + private void _textBox_KeyDown(object sender, KeyEventArgs e) { - SearchText = ""; - InitSelectedList(); - if (Editor != null ) + if (e.Key == Key.Down) { - Editor.Text = ""; - Editor.Focus(); - Editor.SelectionStart = 0; - Keyboard.Focus(Editor); + _listBox.SelectedIndex = 0; + _listBox.Focus(); + Keyboard.Focus(_listBox); } - _savedSelectedIndex = SelectedIndex; } - /// <summary> - /// Called when [popup closed]. - /// Selection Index/Value will be set according to unfiltered whole list - /// </summary> - /// <param name="sender">The sender.</param> - /// <param name="e">The <see cref="EventArgs"/> instance containing the event data.</param> - private void OnPopupClosed(object sender, EventArgs e) + private void _listBox_PreviewMouseLeftButtonUp(object sender, MouseButtonEventArgs e) { - if(SelectedIndex == -1 && _savedSelectedIndex >=0)// selection item was set to null for filtering but not selected, return to prev value - { - SearchText = ""; - SearchItemsList.Refresh(); - SelectedValue = SearchItemsList.GetItemAt(_savedSelectedIndex); - } - if(this.SourceItems.Count != SearchItemsList.Count)//selection was changed on filtered list - replace to real selection index + if (!(e.OriginalSource is Thumb)) { - var selvalue = SelectedValue; - SearchText = ""; - SearchItemsList.Refresh(); - SelectedValue = selvalue; + IsOpened = false; + SelectedItem = _listBox.SelectedItem; } - _savedSelectedIndex = -1; } - private void OnEditorTextChanged(object sender, TextChangedEventArgs e) + private async void OnIsOpenedChanged() { - if (FetchTimer == null) + if (IsOpened) { - FetchTimer = new DispatcherTimer(); - FetchTimer.Interval = TimeSpan.FromMilliseconds(100); - FetchTimer.Tick += OnFetchTimerTick; + _listBox.SelectedItem = SelectedItem; + SearchFilter = ""; + await Task.Delay(100); + _textBox.Focus(); + + Keyboard.Focus(_textBox); } - - FetchTimer.IsEnabled = true; - FetchTimer.Start(); - } - - private void Editor_MouseEnter(object sender, MouseEventArgs e) - { - _editorMouseLeaveFlag = false; } - private void Editor_MouseLeave(object sender, MouseEventArgs e) - { - _editorMouseLeaveFlag = true; - } - - private void OnFetchTimerTick(object sender, EventArgs e) + private void OnFilterChanged() { - FetchTimer.IsEnabled = false; - FetchTimer.Stop(); - SearchText = Editor.Text; - OnTextChanged(); + _view?.Refresh(); } - public virtual void OnTextChanged() + #endregion + #region Override + + protected override void OnItemsSourceChanged(IEnumerable oldValue, IEnumerable newValue) { - if (SearchItemsList != null) - { - SearchItemsList.Refresh(); - } - if(SearchItemsList.Count > 0 && SelectedIndex != -1) + base.OnItemsSourceChanged(oldValue, newValue); + + if (ItemsSource != null) { - SelectedIndex = -1;// trick: all filtered items are displayed only with SelectedIndex = -1 , otherwise it is displayed 1 less + ListItemsSource = ItemsSource.Cast<Object>().ToList(); + + _view = CollectionViewSource.GetDefaultView(ListItemsSource); + _view.Filter = (x) => + { + if (String.IsNullOrWhiteSpace(SearchFilter) || SearchFilter == null) return true; + + if (x != null) + { + var prop = x.GetType().GetProperty(SearchProperty); + + // var prop = x.GetType().GetProperty(SearchProperty, System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.DeclaredOnly); + if (prop != null) + { + String propValue = prop.GetValue(x).ToString(); + return propValue.ToLower().Contains(SearchFilter.ToLower()); + } + } + + return false; + }; } } + protected override void OnSelectionChanged(SelectionChangedEventArgs e) + { + base.OnSelectionChanged(e); + } + #endregion + } } diff --git a/Software/Visual_Studio/Tango.SharedUI/Tango.SharedUI.csproj b/Software/Visual_Studio/Tango.SharedUI/Tango.SharedUI.csproj index 0d76126ab..b9350999e 100644 --- a/Software/Visual_Studio/Tango.SharedUI/Tango.SharedUI.csproj +++ b/Software/Visual_Studio/Tango.SharedUI/Tango.SharedUI.csproj @@ -72,6 +72,7 @@ <Compile Include="Components\SelectedObjectCollection.cs" /> <Compile Include="Components\TextController.cs" /> <Compile Include="Controls\AdornerContentPresenter.cs" /> + <Compile Include="Controls\AllSelectedCheckboxList.cs" /> <Compile Include="Controls\DoubleClickDataGrid.cs" /> <Compile Include="Controls\FastTextBlock.cs" /> <Compile Include="Controls\HexagonControl.cs" /> @@ -86,7 +87,6 @@ <DependentUpon>MultiTransitionControl.xaml</DependentUpon> </Compile> <Compile Include="Controls\NavigationControl.cs" /> - <Compile Include="Controls\PopupWithKeyboardFocus.cs" /> <Compile Include="Controls\SearchComboBox.cs" /> <Compile Include="Controls\SpannedUniformGrid.cs" /> <Compile Include="Controls\TableGrid.cs" /> diff --git a/Software/Visual_Studio/Utilities/Tango.DispenserAnalyzer.UI/Analysis/AnalyzerResultBase.cs b/Software/Visual_Studio/Utilities/Tango.DispenserAnalyzer.UI/Analysis/AnalyzerResultBase.cs index fcbda73e2..d3d217409 100644 --- a/Software/Visual_Studio/Utilities/Tango.DispenserAnalyzer.UI/Analysis/AnalyzerResultBase.cs +++ b/Software/Visual_Studio/Utilities/Tango.DispenserAnalyzer.UI/Analysis/AnalyzerResultBase.cs @@ -55,6 +55,7 @@ namespace Tango.DispenserAnalyzer.UI.Analysis public bool IsShowPlotResult { get; set; } public AnalyzerResultPlotData RangeToCountChart { get; set; } public AnalyzerResultPlotData RangeToTimeChart { get; set; } + public bool BackgroundMode { get; set; } public AnalyzerResultBase() { @@ -63,6 +64,7 @@ namespace Tango.DispenserAnalyzer.UI.Analysis IsShowPlotResult = false; RangeToCountChart = new AnalyzerResultPlotData(); RangeToTimeChart = new AnalyzerResultPlotData(); + BackgroundMode = false; } } } diff --git a/Software/Visual_Studio/Utilities/Tango.DispenserAnalyzer.UI/Analysis/IAnalyzer.cs b/Software/Visual_Studio/Utilities/Tango.DispenserAnalyzer.UI/Analysis/IAnalyzer.cs index 6a07e3a42..6d522da82 100644 --- a/Software/Visual_Studio/Utilities/Tango.DispenserAnalyzer.UI/Analysis/IAnalyzer.cs +++ b/Software/Visual_Studio/Utilities/Tango.DispenserAnalyzer.UI/Analysis/IAnalyzer.cs @@ -10,6 +10,6 @@ namespace Tango.DispenserAnalyzer.UI.Analysis [Analyzer("INTERFACE")] public interface IAnalyzer { - Task<List<IAnalyzerResult>> Process(List<DispenserSample> csvRows); + Task<List<IAnalyzerResult>> Process(List<DispenserSample> csvRows, bool backgroundMode); } } diff --git a/Software/Visual_Studio/Utilities/Tango.DispenserAnalyzer.UI/Analysis/IAnalyzerResult.cs b/Software/Visual_Studio/Utilities/Tango.DispenserAnalyzer.UI/Analysis/IAnalyzerResult.cs index 6b404d2a5..60f7fcb36 100644 --- a/Software/Visual_Studio/Utilities/Tango.DispenserAnalyzer.UI/Analysis/IAnalyzerResult.cs +++ b/Software/Visual_Studio/Utilities/Tango.DispenserAnalyzer.UI/Analysis/IAnalyzerResult.cs @@ -56,8 +56,10 @@ namespace Tango.DispenserAnalyzer.UI.Analysis public interface IAnalyzerResult { AnalyzerResultValue Result { get; set; } + + bool BackgroundMode { get; set; } List<AnalysisPlotValue> PlotValues { get; set; } - // ObservableCollection<DataPoint> Points { get; set; } + AnalyzerResultPlotData RangeToCountChart { get; set; } AnalyzerResultPlotData RangeToTimeChart { get; set; } } diff --git a/Software/Visual_Studio/Utilities/Tango.DispenserAnalyzer.UI/Analyzers/DynamicSealingAnalyzer.cs b/Software/Visual_Studio/Utilities/Tango.DispenserAnalyzer.UI/Analyzers/DynamicSealingAnalyzer.cs index 2cf38fdd6..8acd1651c 100644 --- a/Software/Visual_Studio/Utilities/Tango.DispenserAnalyzer.UI/Analyzers/DynamicSealingAnalyzer.cs +++ b/Software/Visual_Studio/Utilities/Tango.DispenserAnalyzer.UI/Analyzers/DynamicSealingAnalyzer.cs @@ -12,7 +12,7 @@ namespace Tango.DispenserAnalyzer.UI.Analyzers [Analyzer("dynamic")] public class DynamicSealingAnalzyer : IAnalyzer { - public Task<List<IAnalyzerResult>> Process(List<DispenserSample> csvRows) + public Task<List<IAnalyzerResult>> Process(List<DispenserSample> csvRows, bool backgroundMode) { return Task.Factory.StartNew<List<IAnalyzerResult>>(() => { 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 41b7983a7..492fb3e6a 100644 --- a/Software/Visual_Studio/Utilities/Tango.DispenserAnalyzer.UI/Analyzers/FlowAnalyser.cs +++ b/Software/Visual_Studio/Utilities/Tango.DispenserAnalyzer.UI/Analyzers/FlowAnalyser.cs @@ -21,7 +21,7 @@ namespace Tango.DispenserAnalyzer.UI.Analyzers public class FlowAnalyser : IAnalyzer { - public Task<List<IAnalyzerResult>> Process(List<DispenserSample> csvRows) + public Task<List<IAnalyzerResult>> Process(List<DispenserSample> csvRows, bool backgroundMode) { return Task.Factory.StartNew<List<IAnalyzerResult>>(() => { @@ -74,11 +74,13 @@ namespace Tango.DispenserAnalyzer.UI.Analyzers differenceMaxMinToLocationArr.Add(++location_index); } FlowAverageAnalyzerResult averageResult = new FlowAverageAnalyzerResult(); + averageResult.BackgroundMode = backgroundMode; averageResult.AverageValue = filteredValues.Average(t => t.Pressure); 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); + result.BackgroundMode = backgroundMode; result.AverageValue = averageResult.AverageValue; result.SetLocalErrors(differenceMaxMin, differenceMaxMinToLocationArr); results.Add(result); @@ -86,6 +88,7 @@ namespace Tango.DispenserAnalyzer.UI.Analyzers else//testing PBU { PrimingAnalyzerResult result = new PrimingAnalyzerResult(); + result.BackgroundMode = backgroundMode; int avgMinIndex = rangeTestValues.Select(x => x.Index).Min(); int avgMaxIndex = rangeTestValues.Select(x => x.Index).Max(); double totalsec = TimeSpan.FromMilliseconds((avgMaxIndex - avgMinIndex) * 100).TotalSeconds; @@ -138,27 +141,34 @@ namespace Tango.DispenserAnalyzer.UI.Analyzers { // int count = differenceMaxMin.Where(x => x > 25 ).Count(); int max_key = FindMaxErrorObject(differenceMaxMin); - var points = RangeToCountChart.Points; - points.Clear(); - for (int i = 0; i <= max_key; i++) + if (!BackgroundMode) { - int val = differenceMaxMin.Count(x => x == i); - if(val > 0 || points.Count > 0) + var points = RangeToCountChart.Points; + points.Clear(); + for (int i = 0; i <= max_key; i++) { - points.Add(new DataPoint(i, val)); + int val = differenceMaxMin.Count(x => x == i); + if(val > 0 || points.Count > 0) + { + points.Add(new DataPoint(i, val)); + } } + this.IsShowPlotResult = true; + RangeToCountChart.Title = $"Flow Range To Count {TestNumber}"; + RangeToCountChart.UpdateData(); } - this.IsShowPlotResult = true; - RangeToCountChart.Title = $"Flow Range To Count {TestNumber}"; - RangeToCountChart.UpdateData(); var rangeToTimePoints = RangeToTimeChart.Points; rangeToTimePoints.Clear(); for(int y = 0; y < differenceMaxMinToLocationArr.Count && y < differenceMaxMin.Count; y++) { rangeToTimePoints.Add(new DataPoint(differenceMaxMinToLocationArr.ElementAt(y), differenceMaxMin.ElementAt(y))); } - RangeToTimeChart.Title = $"Flow Time Location To Range {TestNumber}"; - RangeToTimeChart.UpdateData(); + if (!BackgroundMode) + { + RangeToTimeChart.Title = $"Flow Time Location To Range {TestNumber}"; + RangeToTimeChart.UpdateData(); + } + string filename = FileHelper.GetFileToSaveFlowRangeToTimeData(TestNumber); if(filename.IsNotNullOrEmpty() && rangeToTimePoints.Count > 0) { 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 c4c5f6c65..79b643294 100644 --- a/Software/Visual_Studio/Utilities/Tango.DispenserAnalyzer.UI/Analyzers/PressureBuildUpAnalyser.cs +++ b/Software/Visual_Studio/Utilities/Tango.DispenserAnalyzer.UI/Analyzers/PressureBuildUpAnalyser.cs @@ -11,7 +11,7 @@ namespace Tango.DispenserAnalyzer.UI.Analyzers [Analyzer("pressure build up")] public class PressureBuildUpAnalyser : IAnalyzer { - public Task<List<IAnalyzerResult>> Process(List<DispenserSample> csvRows) + public Task<List<IAnalyzerResult>> Process(List<DispenserSample> csvRows, bool backgroundMode) { return Task.Factory.StartNew<List<IAnalyzerResult>>(() => { diff --git a/Software/Visual_Studio/Utilities/Tango.DispenserAnalyzer.UI/Analyzers/PrimingAnalyzer.cs b/Software/Visual_Studio/Utilities/Tango.DispenserAnalyzer.UI/Analyzers/PrimingAnalyzer.cs index 0a0e35371..cfd4a7b55 100644 --- a/Software/Visual_Studio/Utilities/Tango.DispenserAnalyzer.UI/Analyzers/PrimingAnalyzer.cs +++ b/Software/Visual_Studio/Utilities/Tango.DispenserAnalyzer.UI/Analyzers/PrimingAnalyzer.cs @@ -13,7 +13,7 @@ namespace Tango.DispenserAnalyzer.UI.Analyzers [Analyzer("priming")] public class PrimingAnalyzer : IAnalyzer { - public Task<List<IAnalyzerResult>> Process(List<DispenserSample> csvRows) + public Task<List<IAnalyzerResult>> Process(List<DispenserSample> csvRows, bool backgroundMode) { return Task.Factory.StartNew<List<IAnalyzerResult>>(() => { diff --git a/Software/Visual_Studio/Utilities/Tango.DispenserAnalyzer.UI/Analyzers/SealingAnalyzer.cs b/Software/Visual_Studio/Utilities/Tango.DispenserAnalyzer.UI/Analyzers/SealingAnalyzer.cs index e725ee25d..e1fe232c3 100644 --- a/Software/Visual_Studio/Utilities/Tango.DispenserAnalyzer.UI/Analyzers/SealingAnalyzer.cs +++ b/Software/Visual_Studio/Utilities/Tango.DispenserAnalyzer.UI/Analyzers/SealingAnalyzer.cs @@ -12,7 +12,7 @@ namespace Tango.DispenserAnalyzer.UI.Analyzers [Analyzer("sealtest")] public class SealingAnalyzer : IAnalyzer { - public Task<List<IAnalyzerResult>> Process(List<DispenserSample> csvRows) + public Task<List<IAnalyzerResult>> Process(List<DispenserSample> csvRows, bool backgroundMode) { return Task.Factory.StartNew<List<IAnalyzerResult>>(() => { 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 c1876d806..d70c2e7a8 100644 --- a/Software/Visual_Studio/Utilities/Tango.DispenserAnalyzer.UI/App.xaml.cs +++ b/Software/Visual_Studio/Utilities/Tango.DispenserAnalyzer.UI/App.xaml.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Configuration; using System.Data; using System.Linq; +using System.Threading; using System.Threading.Tasks; using System.Windows; @@ -16,9 +17,15 @@ namespace Tango.DispenserAnalyzer.UI private void Application_Startup(object sender, StartupEventArgs e) { MainWindow wnd = new MainWindow(); - if (e.Args.Length >= 1) - wnd.SetOpenFileFromArgument(e.Args[0]); - wnd.Show(); + if (e.Args.Length > 0) + { + wnd.GenerateResultsInBackground(e.Args); + //Current.Shutdown(); + } + else + { + wnd.Show(); + } } } } 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 43a573a7d..d328ea8a5 100644 --- a/Software/Visual_Studio/Utilities/Tango.DispenserAnalyzer.UI/MainWindow.xaml.cs +++ b/Software/Visual_Studio/Utilities/Tango.DispenserAnalyzer.UI/MainWindow.xaml.cs @@ -1,20 +1,8 @@ using OxyPlot; using OxyPlot.Axes; using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Text; using System.Threading.Tasks; using System.Windows; -using System.Windows.Controls; -using System.Windows.Data; -using System.Windows.Documents; -using System.Windows.Input; -using System.Windows.Media; -using System.Windows.Media.Imaging; -using System.Windows.Navigation; -using System.Windows.Shapes; using Tango.DispenserAnalyzer.UI.ViewModels; namespace Tango.DispenserAnalyzer.UI @@ -48,13 +36,17 @@ namespace Tango.DispenserAnalyzer.UI ax.Maximum = ax.Minimum = Double.NaN; } - public void SetOpenFileFromArgument( string openFilePath) + public async void GenerateResultsInBackground( string[] filePathArr) { if(_vm != null) { - _vm.OpenFilePath = openFilePath; - _vm.Generate(); + for (int index = 0; index < filePathArr.Length; index++) + { + await _vm.GenerateInBackground(filePathArr[index]); + } } + await Task.Delay(500); + Application.Current.Shutdown(); } private void TextBlock_PreviewDrop(object sender, DragEventArgs e) 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 3e85dc80b..b7db85ef8 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,7 +29,7 @@ <ProductName>Dispenser Analyser</ProductName> <PublisherName>Twine</PublisherName> <OpenBrowserOnPublish>false</OpenBrowserOnPublish> - <ApplicationRevision>3</ApplicationRevision> + <ApplicationRevision>4</ApplicationRevision> <ApplicationVersion>2.1.1.%2a</ApplicationVersion> <UseApplicationTrust>true</UseApplicationTrust> <CreateDesktopShortcut>true</CreateDesktopShortcut> 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 70034b6e7..38f8dee81 100644 --- a/Software/Visual_Studio/Utilities/Tango.DispenserAnalyzer.UI/ViewModels/MainWindowVM.cs +++ b/Software/Visual_Studio/Utilities/Tango.DispenserAnalyzer.UI/ViewModels/MainWindowVM.cs @@ -28,6 +28,8 @@ using PdfSharp; using OxyPlot.Reporting; using System.Threading; using Tango.DispenserAnalyzer.UI.View; +using Tango.Core.Helpers; +using Tango.Documents; namespace Tango.DispenserAnalyzer.UI.ViewModels { @@ -134,6 +136,7 @@ namespace Tango.DispenserAnalyzer.UI.ViewModels get { return _isRunning; } set { _isRunning = value; RaisePropertyChangedAuto(); } } + private ObservableCollection<IAnalyzerResult> _analyzerResults; public ObservableCollection<IAnalyzerResult> AnalyzerResults { @@ -233,13 +236,18 @@ namespace Tango.DispenserAnalyzer.UI.ViewModels #endregion #region Generate + public bool CanGenerate() { return (OpenFilePath!= null && OpenFilePath.Length != 0 && File.Exists(OpenFilePath)); } + + /// <summary> + /// Generates all results. + /// </summary> public async void Generate() { - if (false == File.Exists(OpenFilePath) || IsFileLocked(OpenFilePath) ) + if (false == File.Exists(OpenFilePath) || IsFileLocked(OpenFilePath)) return; ResetSettings(); @@ -248,17 +256,18 @@ namespace Tango.DispenserAnalyzer.UI.ViewModels return; IsRunning = true; - AnalyzerAttribute attribute = (AnalyzerAttribute)analyzer.GetType().GetCustomAttributes(typeof(AnalyzerAttribute),true).FirstOrDefault(); - + AnalyzerAttribute attribute = (AnalyzerAttribute)analyzer.GetType().GetCustomAttributes(typeof(AnalyzerAttribute), true).FirstOrDefault(); + TestName = attribute.Name; - List<DispenserCsvRow> data = CsvFile.Read<DispenserCsvRow>(new CsvSource(OpenFilePath)).ToList(); + List<DispenserCsvRow> data = CsvFile.Read<DispenserCsvRow>(new CsvSource(OpenFilePath)).ToList(); List<DispenserSample> samples = new List<DispenserSample>(); To = 0; From = 0; int index = 0; int last_labelIndex = 0; - + + foreach (var item in data) { double pressure = 0; @@ -269,6 +278,7 @@ namespace Tango.DispenserAnalyzer.UI.ViewModels if (last_labelIndex == 0 || last_labelIndex < (index + 5)) { last_labelIndex = index; + OxyPlot.Wpf.LineAnnotation _line = new OxyPlot.Wpf.LineAnnotation() { StrokeThickness = 1, @@ -278,11 +288,13 @@ namespace Tango.DispenserAnalyzer.UI.ViewModels X = index, }; PlotControl.Annotations.Add(_line); + } } if (double.TryParse(item.Pressure, out pressure) || !String.IsNullOrWhiteSpace(item.Command)) { - samples.Add(new DispenserSample(){ + samples.Add(new DispenserSample() + { Pressure = pressure, Command = String.IsNullOrWhiteSpace(item.Command) ? null : item.Command, Index = index @@ -290,27 +302,84 @@ namespace Tango.DispenserAnalyzer.UI.ViewModels index++; } } - List<IAnalyzerResult> res = await analyzer.Process(samples); + List<IAnalyzerResult> res = await analyzer.Process(samples, false); AnalyzerResults = new ObservableCollection<IAnalyzerResult>(res); - - samples.ForEach(x => { if (x.Pressure != 0.0) + + samples.ForEach(x => + { + if (x.Pressure != 0.0) { Points.Add(new DataPoint(x.Index, x.Pressure)); } }); - _to = Points.Max(x=>x.Y); - _from = TestName.Contains("sealtest") ? Points.FirstOrDefault(x=>x.X == 0).Y : Points.Min(x => x.Y); + _to = Points.Max(x => x.Y); + _from = TestName.Contains("sealtest") ? Points.FirstOrDefault(x => x.X == 0).Y : Points.Min(x => x.Y); data.Clear(); _to += 100; RaisePropertyChanged("To"); - if(_from != 0) + if (_from != 0) _from -= 100; RaisePropertyChanged("From"); XStep = (int)(Points.Count / 5); - + IsRunning = false; PlotControl.InvalidatePlot(true); - + await PrintToXpsFile(); + + } + + /// <summary> + /// Generates all results from command line and close application. + /// </summary> + public async Task GenerateInBackground(string openFilePath) + { + OpenFilePath = openFilePath; + + if (false == File.Exists(OpenFilePath) || IsFileLocked(OpenFilePath)) + return; + + IAnalyzer analyzer = AnalysisService.GetAnalyzer(OpenFilePath); + if (analyzer == null) + return; + + AnalyzerAttribute attribute = (AnalyzerAttribute)analyzer.GetType().GetCustomAttributes(typeof(AnalyzerAttribute), true).FirstOrDefault(); + + TestName = attribute.Name; + List<DispenserCsvRow> data = CsvFile.Read<DispenserCsvRow>(new CsvSource(OpenFilePath)).ToList(); + List<DispenserSample> samples = new List<DispenserSample>(); + + int index = 0; + int last_labelIndex = 0; + + + foreach (var item in data) + { + double pressure = 0; + if (item.Label == "Label") + { + item.Pressure = "0"; + item.Command = "Label"; + if (last_labelIndex == 0 || last_labelIndex < (index + 5)) + { + last_labelIndex = index; + } + } + if (double.TryParse(item.Pressure, out pressure) || !String.IsNullOrWhiteSpace(item.Command)) + { + samples.Add(new DispenserSample() + { + Pressure = pressure, + Command = String.IsNullOrWhiteSpace(item.Command) ? null : item.Command, + Index = index + }); + index++; + } + } + + List<IAnalyzerResult> res = await analyzer.Process(samples, true); + AnalyzerResults = new ObservableCollection<IAnalyzerResult>(res); + + await ExportResultsToTextFile(); } #endregion @@ -487,5 +556,54 @@ namespace Tango.DispenserAnalyzer.UI.ViewModels } #endregion + + #region ExportToExel + + public async Task ExportResultsToTextFile() + { + var resultFile = FileHelper.GetResultFilePath(); + var dir = Path.GetDirectoryName(resultFile); + var name = Path.GetFileNameWithoutExtension(resultFile); + string fileNameWithoutExtension = Path.Combine(dir, name); + String sourceFile = String.Format($"{fileNameWithoutExtension}s.txt"); + File.Delete(sourceFile); + + await Task.Factory.StartNew(() => + { + try + { + List<IAnalyzerResult> results = AnalyzerResults.ToList(); + + using (StreamWriter outputFile = new StreamWriter(sourceFile)) + { + outputFile.WriteLine(String.Format($" {TestName.ToUpper()} RESULTS: ")); + outputFile.WriteLine(""); + outputFile.WriteLine(""); + foreach (var res in results) + { + if (res.GetType().IsSubclassOf(typeof(AnalyzerResultBase))) + { + List<AnalyzerResultProperty> properties = (res as AnalyzerResultBase).Properties; + foreach (var prop in properties) + { + outputFile.WriteLine(String.Format($" {prop.Name} : {prop.Value}")); + } + string resV = String.Format($" RESULT = {res.Result.ToString()}"); + outputFile.WriteLine(resV); + outputFile.WriteLine(""); + } + } + outputFile.Flush(); + } + } + catch (Exception ex) + { + Debug.WriteLine(ex); + } + }); + + } + #endregion + } } |
