| |
| |
| #include "tunit.h" |
| #include "tconvert.h" |
| #include <math.h> |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| namespace UnitParameters |
| { |
| |
| std::pair<double, double> dummyCurrentDpiGetter() { return std::make_pair<double, double>(72, 72); } |
| |
| CurrentDpiGetter currentDpiGetter = &dummyCurrentDpiGetter; |
| |
| void setCurrentDpiGetter(CurrentDpiGetter f) { currentDpiGetter = f; } |
| } |
| |
| |
| |
| class VerticalFldUnitConverter : public TUnitConverter |
| { |
| double m_factor; |
| |
| public: |
| static double m_fieldGuideAspectRatio; |
| |
| VerticalFldUnitConverter(double factor) : m_factor(factor) {} |
| TUnitConverter *clone() const { return new VerticalFldUnitConverter(*this); } |
| double convertTo(double v) const { return v * m_fieldGuideAspectRatio * m_factor; } |
| double convertFrom(double v) const { return v / (m_fieldGuideAspectRatio * m_factor); } |
| }; |
| double VerticalFldUnitConverter::m_fieldGuideAspectRatio = 1.38; |
| |
| |
| |
| namespace UnitParameters |
| { |
| |
| void setFieldGuideAspectRatio(double ar) |
| { |
| assert(ar > 0); |
| VerticalFldUnitConverter::m_fieldGuideAspectRatio = ar; |
| } |
| |
| double getFieldGuideAspectRatio() |
| { |
| return VerticalFldUnitConverter::m_fieldGuideAspectRatio; |
| } |
| } |
| |
| |
| |
| class TangentConverter : public TUnitConverter |
| { |
| public: |
| TangentConverter() {} |
| TUnitConverter *clone() const { return new TangentConverter(*this); } |
| double convertTo(double v) const { return atan(v) * (M_1_PI * 180.0); } |
| double convertFrom(double v) const { return tan(v * M_PI_180); } |
| }; |
| |
| |
| |
| class TPixelUnitXConverter : public TUnitConverter |
| { |
| public: |
| TPixelUnitXConverter() {} |
| TUnitConverter *clone() const { return new TPixelUnitXConverter(*this); } |
| double convertTo(double v) const { return v * UnitParameters::currentDpiGetter().first; } |
| double convertFrom(double v) const { return v / UnitParameters::currentDpiGetter().first; } |
| }; |
| |
| class TPixelUnitYConverter : public TUnitConverter |
| { |
| public: |
| TPixelUnitYConverter() {} |
| TUnitConverter *clone() const { return new TPixelUnitYConverter(*this); } |
| double convertTo(double v) const { return v * UnitParameters::currentDpiGetter().second; } |
| double convertFrom(double v) const { return v / UnitParameters::currentDpiGetter().second; } |
| }; |
| |
| |
| |
| TUnit::TUnit(std::wstring ext, TUnitConverter *converter) |
| : m_defaultExtension(ext), m_converter(converter) |
| { |
| m_extensions.push_back(ext); |
| if (m_converter == 0) |
| m_converter = new TSimpleUnitConverter(); |
| } |
| |
| |
| |
| TUnit::TUnit(const TUnit &src) |
| : m_defaultExtension(src.m_defaultExtension), m_extensions(src.m_extensions), m_converter(src.m_converter->clone()) |
| { |
| } |
| |
| |
| |
| TUnit::~TUnit() |
| { |
| delete m_converter; |
| } |
| |
| |
| |
| void TUnit::addExtension(std::wstring ext) |
| { |
| if (std::find( |
| m_extensions.begin(), m_extensions.end(), ext) == m_extensions.end()) |
| m_extensions.push_back(ext); |
| if (m_defaultExtension.empty()) |
| m_defaultExtension = ext; |
| } |
| |
| |
| |
| bool TUnit::isExtension(std::wstring ext) const |
| { |
| return std::find( |
| m_extensions.begin(), m_extensions.end(), ext) != m_extensions.end(); |
| } |
| |
| |
| |
| void TUnit::setDefaultExtension(std::wstring ext) |
| { |
| if (!ext.empty() && std::find(m_extensions.begin(), m_extensions.end(), ext) == m_extensions.end()) |
| m_extensions.push_back(ext); |
| m_defaultExtension = ext; |
| } |
| |
| |
| |
| TMeasure::TMeasure(std::string name, TUnit *mainUnit) |
| : m_name(name), m_mainUnit(0), m_standardUnit(0), m_currentUnit(0), m_defaultValue(0) |
| { |
| add(mainUnit); |
| m_mainUnit = m_currentUnit = m_standardUnit = mainUnit; |
| } |
| |
| |
| |
| TMeasure::TMeasure(const TMeasure &src) |
| : m_name(src.m_name), m_mainUnit(src.m_mainUnit), m_currentUnit(src.m_currentUnit), m_standardUnit(src.m_standardUnit), m_defaultValue(src.m_defaultValue) |
| { |
| std::map<std::wstring, TUnit *>::const_iterator it; |
| for (it = src.m_extensions.begin(); |
| it != src.m_extensions.end(); ++it) { |
| TUnit *u = it->second; |
| assert(u); |
| const std::vector<std::wstring> &e = u->getExtensions(); |
| assert(std::find(e.begin(), e.end(), it->first) != e.end()); |
| m_extensions[it->first] = u; |
| } |
| } |
| |
| |
| |
| TMeasure::~TMeasure() |
| { |
| } |
| |
| |
| |
| void TMeasure::add(TUnit *unit) |
| { |
| const std::vector<std::wstring> &e = unit->getExtensions(); |
| for (int i = 0; i < (int)e.size(); i++) { |
| std::wstring ext = e[i]; |
| assert(m_extensions.count(ext) == 0); |
| m_extensions[ext] = unit; |
| } |
| } |
| |
| |
| |
| TUnit *TMeasure::getUnit(std::wstring ext) const |
| { |
| std::map<std::wstring, TUnit *>::const_iterator it; |
| it = m_extensions.find(ext); |
| return it == m_extensions.end() ? 0 : it->second; |
| } |
| |
| |
| |
| void TMeasure::setCurrentUnit(TUnit *unit) |
| { |
| assert(unit); |
| assert(m_extensions.count(unit->getDefaultExtension()) > 0); |
| m_currentUnit = unit; |
| } |
| |
| |
| |
| void TMeasure::setStandardUnit(TUnit *unit) |
| { |
| assert(unit); |
| assert(m_extensions.count(unit->getDefaultExtension()) > 0); |
| m_standardUnit = unit; |
| } |
| |
| |
| |
| TMeasureManager::TMeasureManager() |
| { |
| TUnit |
| inch(L"in"), |
| cm(L"cm", new TSimpleUnitConverter(2.54)), |
| mm(L"mm", new TSimpleUnitConverter(25.4)), |
| |
| xfld(L"fld", new TSimpleUnitConverter(2)), |
| cameraXFld(L"fld", new TSimpleUnitConverter(1)), |
| |
| yfld(L"fld", new VerticalFldUnitConverter(2)), |
| cameraYFld(L"fld", new VerticalFldUnitConverter(1)), |
| |
| levelXFld(L"fld", new TSimpleUnitConverter(1)), |
| levelYFld(L"fld", new VerticalFldUnitConverter(1)), |
| |
| internalZDepth(L"internal.zdepth"), |
| zdepth(L"zdepth", new TSimpleUnitConverter(1)), |
| degree(L"\u00b0"), |
| scale(L"*"), |
| percentage2(L"%"), |
| shear(L"sh"), |
| shearAngle(L"\u00b0", new TangentConverter()), |
| percentage(L"%", new TSimpleUnitConverter(100)), |
| colorChannel(L"", new TSimpleUnitConverter(255)), |
| dummy(L""), |
| xPixel(L"px", new TPixelUnitXConverter()), |
| yPixel(L"px", new TPixelUnitYConverter()); |
| |
| inch.addExtension(L"inch"); |
| inch.addExtension(L"\""); |
| inch.addExtension(L"''"); |
| inch.setDefaultExtension(L"\""); |
| |
| xPixel.addExtension(L"pixel"); |
| yPixel.addExtension(L"pixel"); |
| |
| xfld.addExtension(L"field"); |
| cameraXFld.addExtension(L"field"); |
| |
| yfld.addExtension(L"field"); |
| cameraYFld.addExtension(L"field"); |
| |
| levelXFld.addExtension(L"field"); |
| levelYFld.addExtension(L"field"); |
| |
| xfld.addExtension(L"F"); |
| yfld.addExtension(L"F"); |
| cameraXFld.addExtension(L"F"); |
| cameraYFld.addExtension(L"F"); |
| |
| levelXFld.addExtension(L"F"); |
| levelYFld.addExtension(L"F"); |
| |
| TMeasure *length, *m; |
| |
| length = m = new TMeasure("length", inch.clone()); |
| m->add(cm.clone()); |
| |
| |
| |
| |
| |
| |
| |
| |
| TUnit *mmUnit = mm.clone(); |
| m->add(mmUnit); |
| m->setCurrentUnit(mmUnit); |
| add(m); |
| |
| m = new TMeasure(*length); |
| m->setName("length.x"); |
| m->add(xfld.clone()); |
| m->add(xPixel.clone()); |
| add(m); |
| |
| m = new TMeasure(*length); |
| m->setName("length.y"); |
| m->add(yfld.clone()); |
| m->add(yPixel.clone()); |
| add(m); |
| |
| m = new TMeasure(*length); |
| m->setName("length.lx"); |
| m->add(xfld.clone()); |
| m->add(xPixel.clone()); |
| add(m); |
| |
| m = new TMeasure(*length); |
| m->setName("length.ly"); |
| m->add(yfld.clone()); |
| m->add(yPixel.clone()); |
| add(m); |
| |
| m = new TMeasure(*length); |
| m->setName("camera.lx"); |
| m->add(cameraXFld.clone()); |
| m->add(xPixel.clone()); |
| add(m); |
| |
| m = new TMeasure(*length); |
| m->setName("camera.ly"); |
| m->add(cameraYFld.clone()); |
| m->add(yPixel.clone()); |
| add(m); |
| |
| m = new TMeasure(*length); |
| m->setName("level.lx"); |
| m->add(levelXFld.clone()); |
| add(m); |
| |
| m = new TMeasure(*length); |
| m->setName("level.ly"); |
| m->add(levelYFld.clone()); |
| add(m); |
| |
| m = new TMeasure(*length); |
| m->setName("canvas.lx"); |
| m->add(cameraXFld.clone()); |
| add(m); |
| |
| m = new TMeasure(*length); |
| m->setName("canvas.ly"); |
| m->add(cameraYFld.clone()); |
| add(m); |
| |
| TUnit fxLength(L"fxLength"), |
| fxInch(L"in", new TSimpleUnitConverter(1 / 53.33333)), |
| fxCm(L"cm", new TSimpleUnitConverter(2.54 / 53.33333)), |
| fxMm(L"mm", new TSimpleUnitConverter(25.4 / 53.33333)), |
| fxXfld(L"fld", new TSimpleUnitConverter(2 / 53.33333)); |
| fxInch.addExtension(L"inch"); |
| fxInch.addExtension(L"\""); |
| fxInch.addExtension(L"''"); |
| fxInch.setDefaultExtension(L"\""); |
| fxXfld.addExtension(L"field"); |
| fxXfld.addExtension(L"F"); |
| m = new TMeasure("fxLength", fxLength.clone()); |
| m->add(fxInch.clone()); |
| m->add(fxCm.clone()); |
| m->add(fxMm.clone()); |
| m->add(fxXfld.clone()); |
| add(m); |
| |
| m = new TMeasure("angle", degree.clone()); |
| add(m); |
| |
| m = new TMeasure("scale", scale.clone()); |
| TUnit *unit = percentage.clone(); |
| m->add(unit); |
| m->setCurrentUnit(unit); |
| m->setStandardUnit(unit); |
| add(m); |
| |
| m = new TMeasure("percentage", scale.clone()); |
| unit = percentage.clone(); |
| m->add(unit); |
| m->setCurrentUnit(unit); |
| m->setStandardUnit(unit); |
| add(m); |
| |
| m = new TMeasure("percentage2", percentage2.clone()); |
| add(m); |
| |
| m = new TMeasure("shear", shear.clone()); |
| unit = shearAngle.clone(); |
| m->add(unit); |
| m->setCurrentUnit(unit); |
| m->setStandardUnit(unit); |
| add(m); |
| |
| m = new TMeasure("colorChannel", colorChannel.clone()); |
| add(m); |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| m = new TMeasure("dummy", dummy.clone()); |
| add(m); |
| } |
| |
| |
| |
| void TMeasureManager::add(TMeasure *m) |
| { |
| m_measures[m->getName()] = m; |
| } |
| |
| |
| |
| TMeasure *TMeasureManager::get(std::string name) const |
| { |
| std::map<std::string, TMeasure *>::const_iterator it; |
| it = m_measures.find(name); |
| if (it == m_measures.end()) |
| return 0; |
| else |
| return it->second; |
| } |
| |
| |
| |
| TMeasuredValue::TMeasuredValue(std::string measureName) |
| : m_measure(0), m_value(0) |
| { |
| setMeasure(measureName); |
| } |
| |
| |
| |
| TMeasuredValue::~TMeasuredValue() |
| { |
| } |
| |
| |
| |
| void TMeasuredValue::setMeasure(const TMeasure *measure) |
| { |
| assert(measure); |
| if (!measure) |
| return; |
| m_measure = measure; |
| m_value = m_measure->getDefaultValue(); |
| } |
| |
| |
| |
| void TMeasuredValue::setMeasure(std::string measureName) |
| { |
| setMeasure(TMeasureManager::instance()->get(measureName)); |
| } |
| |
| |
| |
| bool TMeasuredValue::setValue(std::wstring s, int *pErr) |
| { |
| if (s == L"") { |
| if (pErr) |
| *pErr = -1; |
| return false; |
| } |
| const TUnit *unit = m_measure->getCurrentUnit(); |
| double value = 0; |
| bool valueFlag = false; |
| int i = 0, len = s.length(); |
| |
| i = s.find_first_not_of(::to_wstring(" \t")); |
| assert(i != (int)std::wstring::npos); |
| int j = i; |
| |
| if (i < len && (s[i] == L'-' || s[i] == L'+')) |
| i++; |
| while (i < len && L'0' <= s[i] && s[i] <= L'9') |
| i++; |
| if (i < len && s[i] == L'.') { |
| i++; |
| while (i < len && L'0' <= s[i] && s[i] <= L'9') |
| i++; |
| if (i < len && (s[i] == L'E' || s[i] == L'e')) { |
| i++; |
| if (i < len && (s[i] == L'-' || s[i] == L'+')) |
| i++; |
| while (i < len && L'0' <= s[i] && s[i] <= L'9') |
| i++; |
| } |
| } |
| if (i > j) { |
| value = std::stod(s.substr(j, i - j)); |
| valueFlag = true; |
| |
| i = s.find_first_not_of(::to_wstring(" \t"), i); |
| if (i == (int)std::wstring::npos) |
| i = s.length(); |
| } |
| |
| |
| if (i < (int)s.length()) { |
| j = i; |
| i = s.find_last_not_of(::to_wstring(" \t")); |
| if (i == (int)std::wstring::npos) |
| i = len - 1; |
| if (j <= i) { |
| std::wstring unitExt = s.substr(j, i + 1 - j); |
| unit = m_measure->getUnit(unitExt); |
| if (!unit) { |
| if (pErr) |
| *pErr = -2; |
| return false; |
| } |
| } |
| } |
| |
| if (valueFlag) { |
| double newValue = unit->convertFrom(value); |
| if (m_value == newValue) { |
| if (pErr) |
| *pErr = 0; |
| return false; |
| } |
| m_value = newValue; |
| } |
| if (pErr) |
| *pErr = (valueFlag || unit != 0) ? 0 : -3; |
| return valueFlag || unit != 0; |
| } |
| |
| |
| |
| std::wstring TMeasuredValue::toWideString(int decimals) const |
| { |
| double v = getValue(CurrentUnit); |
| std::string s = ::to_string(v, decimals); |
| if (s.find('.') != std::string::npos) { |
| int i = s.length(); |
| while (i > 0 && s[i - 1] == '0') |
| i--; |
| if (i > 0 && s[i - 1] == '.') |
| i--; |
| if (i < (int)s.length()) |
| s = s.substr(0, i); |
| } |
| std::wstring measure = m_measure->getCurrentUnit()->getDefaultExtension(); |
| if (measure.empty()) |
| return ::to_wstring(s); |
| return ::to_wstring(s) + L" " + measure; |
| } |
| |
| |
| |
| namespace |
| { |
| |
| class ZDepthUnitConverter : public TUnitConverter |
| { |
| TMeasureManager::CameraSizeProvider *m_cameraSizeProvider; |
| |
| public: |
| ZDepthUnitConverter(TMeasureManager::CameraSizeProvider *cameraSizeProvider) |
| : m_cameraSizeProvider(cameraSizeProvider) |
| { |
| } |
| TUnitConverter *clone() const { return new ZDepthUnitConverter(m_cameraSizeProvider); } |
| inline double getCameraSize() const { return (*m_cameraSizeProvider)(); } |
| double convertTo(double v) const |
| { |
| return (1 - v * 0.001) * getCameraSize(); |
| } |
| double convertFrom(double v) const |
| { |
| return (1 - v / getCameraSize()) * 1000.0; |
| } |
| }; |
| |
| |
| |
| class CameraZDepthUnitConverter : public TUnitConverter |
| { |
| TMeasureManager::CameraSizeProvider *m_cameraSizeProvider; |
| |
| public: |
| CameraZDepthUnitConverter(TMeasureManager::CameraSizeProvider *cameraSizeProvider) |
| : m_cameraSizeProvider(cameraSizeProvider) |
| { |
| } |
| TUnitConverter *clone() const { return new CameraZDepthUnitConverter(m_cameraSizeProvider); } |
| inline double getCameraSize() const { return (*m_cameraSizeProvider)(); } |
| double convertTo(double v) const |
| { |
| return (1 + v * 0.001) * getCameraSize(); |
| } |
| double convertFrom(double v) const |
| { |
| return (v / getCameraSize() - 1) * 1000.0; |
| } |
| }; |
| |
| |
| |
| class ZDepthHandleUnitConverter : public TUnitConverter |
| { |
| |
| TMeasureManager::CameraSizeProvider *m_cameraSizeProvider; |
| |
| public: |
| ZDepthHandleUnitConverter(TMeasureManager::CameraSizeProvider *cameraSizeProvider) |
| : m_cameraSizeProvider(cameraSizeProvider) |
| { |
| } |
| |
| TUnitConverter *clone() const { return new ZDepthHandleUnitConverter(m_cameraSizeProvider); } |
| inline double getCameraSize() const { return (*m_cameraSizeProvider)(); } |
| double convertTo(double v) const |
| { |
| return -v * 0.001 * getCameraSize(); |
| } |
| double convertFrom(double v) const |
| { |
| return (-v / getCameraSize()) * 1000.0; |
| } |
| }; |
| |
| class CameraZDepthHandleUnitConverter : public TUnitConverter |
| { |
| |
| TMeasureManager::CameraSizeProvider *m_cameraSizeProvider; |
| |
| public: |
| CameraZDepthHandleUnitConverter(TMeasureManager::CameraSizeProvider *cameraSizeProvider) |
| : m_cameraSizeProvider(cameraSizeProvider) |
| { |
| } |
| |
| TUnitConverter *clone() const { return new CameraZDepthHandleUnitConverter(m_cameraSizeProvider); } |
| inline double getCameraSize() const { return (*m_cameraSizeProvider)(); } |
| double convertTo(double v) const |
| { |
| return v * 0.001 * getCameraSize(); |
| } |
| double convertFrom(double v) const |
| { |
| return (v / getCameraSize()) * 1000.0; |
| } |
| }; |
| |
| } |
| |
| |
| |
| void TMeasureManager::addCameraMeasures(CameraSizeProvider *cameraSizeProvider) |
| { |
| TUnit |
| u0(L"z"), |
| u1(L"fld", new ZDepthUnitConverter(cameraSizeProvider)), |
| u2(L"fld", new CameraZDepthUnitConverter(cameraSizeProvider)), |
| u3(L"fld", new ZDepthHandleUnitConverter(cameraSizeProvider)), |
| u4(L"fld", new CameraZDepthHandleUnitConverter(cameraSizeProvider)); |
| |
| TMeasure *zdepth = new TMeasure("zdepth", u0.clone()); |
| TUnit *u = u1.clone(); |
| zdepth->add(u); |
| zdepth->setCurrentUnit(u); |
| zdepth->setStandardUnit(u); |
| TMeasureManager::instance()->add(zdepth); |
| |
| zdepth = new TMeasure("zdepth.cam", u0.clone()); |
| u = u2.clone(); |
| zdepth->add(u); |
| zdepth->setCurrentUnit(u); |
| zdepth->setStandardUnit(u); |
| |
| TMeasureManager::instance()->add(zdepth); |
| |
| zdepth = new TMeasure("zdepth.handle", u0.clone()); |
| u = u3.clone(); |
| zdepth->add(u); |
| zdepth->setCurrentUnit(u); |
| zdepth->setStandardUnit(u); |
| TMeasureManager::instance()->add(zdepth); |
| |
| zdepth = new TMeasure("zdepth.cam.handle", u0.clone()); |
| u = u4.clone(); |
| zdepth->add(u); |
| zdepth->setCurrentUnit(u); |
| zdepth->setStandardUnit(u); |
| TMeasureManager::instance()->add(zdepth); |
| } |
| |