Base: simplify UnitsSchemas management
Fixes: Maintaining schemas is difficult and error-prone - Facilitate easy schemas add, remove, change, etc. - Remove 14 files containing approx 2,190 lines of if/else code and data - Place data in one file (UnitsSchemasData.h) using a normalized structure (including special functions) - Isolate and simplify data operations (code) - Remove schemas enum to keep data independent of code - Separate responsibilities: Specifications, data, schemas, schema - Add schema data 'isDefault' - Add schema data name - Prefer algorithms to raw loops - Add schemas unit tests - Tweak quantity unit tests
This commit is contained in:
@@ -2795,12 +2795,10 @@ void Application::initApplication()
|
||||
// set up Unit system default
|
||||
const ParameterGrp::handle hGrp = GetApplication().GetParameterGroupByPath
|
||||
("User parameter:BaseApp/Preferences/Units");
|
||||
Base::UnitsApi::setSchema(static_cast<Base::UnitSystem>(hGrp->GetInt("UserSchema", 0)));
|
||||
Base::UnitsApi::setDecimals(static_cast<int>(hGrp->GetInt("Decimals", Base::UnitsApi::getDecimals())));
|
||||
|
||||
// In case we are using fractional inches, get user setting for min unit
|
||||
const int denom = static_cast<int>(hGrp->GetInt("FracInch", Base::QuantityFormat::getDefaultDenominator()));
|
||||
Base::QuantityFormat::setDefaultDenominator(denom);
|
||||
Base::UnitsApi::setSchema(hGrp->GetInt("UserSchema", Base::UnitsApi::getDefSchemaNum()));
|
||||
Base::UnitsApi::setDecimals(hGrp->GetInt("Decimals", Base::UnitsApi::getDecimals()));
|
||||
Base::QuantityFormat::setDefaultDenominator(
|
||||
hGrp->GetInt("FracInch", Base::QuantityFormat::getDefaultDenominator()));
|
||||
|
||||
#if defined (_DEBUG)
|
||||
Base::Console().Log("Application is built with debug information\n");
|
||||
|
||||
@@ -876,13 +876,8 @@ Document::Document(const char* documentName)
|
||||
"Additional tag to save the name of the company");
|
||||
ADD_PROPERTY_TYPE(UnitSystem, (""), 0, Prop_None, "Unit system to use in this project");
|
||||
// Set up the possible enum values for the unit system
|
||||
int num = static_cast<int>(Base::UnitSystem::NumUnitSystemTypes);
|
||||
std::vector<std::string> enumValsAsVector;
|
||||
for (int i = 0; i < num; i++) {
|
||||
QString item = Base::UnitsApi::getDescription(static_cast<Base::UnitSystem>(i));
|
||||
enumValsAsVector.emplace_back(item.toStdString());
|
||||
}
|
||||
UnitSystem.setEnums(enumValsAsVector);
|
||||
|
||||
UnitSystem.setEnums(Base::UnitsApi::getDescriptions());
|
||||
// Get the preferences/General unit system as the default for a new document
|
||||
ParameterGrp::handle hGrpu =
|
||||
App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/Units");
|
||||
|
||||
@@ -150,20 +150,10 @@ SET(FreeCADBase_UNITAPI_SRCS
|
||||
UnitsApi.h
|
||||
UnitsSchema.h
|
||||
UnitsSchema.cpp
|
||||
UnitsSchemaInternal.h
|
||||
UnitsSchemaInternal.cpp
|
||||
UnitsSchemaMKS.h
|
||||
UnitsSchemaMKS.cpp
|
||||
UnitsSchemaImperial1.h
|
||||
UnitsSchemaImperial1.cpp
|
||||
UnitsSchemaCentimeters.h
|
||||
UnitsSchemaCentimeters.cpp
|
||||
UnitsSchemaMmMin.h
|
||||
UnitsSchemaMmMin.cpp
|
||||
UnitsSchemaFemMilliMeterNewton.h
|
||||
UnitsSchemaFemMilliMeterNewton.cpp
|
||||
UnitsSchemaMeterDecimal.h
|
||||
UnitsSchemaMeterDecimal.cpp
|
||||
UnitsSchemas.cpp
|
||||
UnitsSchemas.h
|
||||
UnitsSchemasData.h
|
||||
UnitsSchemasSpecs.h
|
||||
Quantity.h
|
||||
Quantity.cpp
|
||||
QuantityPyImp.cpp
|
||||
|
||||
@@ -64,7 +64,7 @@ int QuantityFormat::defaultDenominator = 8; // for 1/8"
|
||||
QuantityFormat::QuantityFormat()
|
||||
: option(OmitGroupSeparator | RejectGroupSeparator)
|
||||
, format(Fixed)
|
||||
, precision(UnitsApi::getDecimals())
|
||||
, precision(static_cast<int>(UnitsApi::getDecimals()))
|
||||
, denominator(defaultDenominator)
|
||||
{}
|
||||
|
||||
@@ -256,14 +256,15 @@ std::string Quantity::getUserString(double& factor, std::string& unitString) con
|
||||
std::string
|
||||
Quantity::getUserString(UnitsSchema* schema, double& factor, std::string& unitString) const
|
||||
{
|
||||
return schema->schemaTranslate(*this, factor, unitString);
|
||||
return schema->translate(*this, factor, unitString);
|
||||
}
|
||||
|
||||
std::string Quantity::getSafeUserString() const
|
||||
{
|
||||
auto userStr = getUserString();
|
||||
if (myValue != 0.0 && parse(userStr).getValue() == 0) {
|
||||
userStr = fmt::format("{} {}", myValue, getUnit().getString());
|
||||
auto unitStr = getUnit().getString();
|
||||
userStr = fmt::format("{}{}{}", myValue, unitStr.empty() ? "" : " ", unitStr);
|
||||
}
|
||||
|
||||
return Tools::escapeQuotesFromString(userStr);
|
||||
|
||||
@@ -20,124 +20,91 @@
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
|
||||
#include "PreCompiled.h"
|
||||
|
||||
#include <sstream>
|
||||
#ifndef _PreComp_
|
||||
#include <iomanip>
|
||||
#include <memory>
|
||||
#include <sstream>
|
||||
#endif
|
||||
|
||||
#include <CXX/WrapPython.h>
|
||||
#include <fmt/format.h>
|
||||
#include <QString>
|
||||
|
||||
#include "Exception.h"
|
||||
|
||||
#include "UnitsApi.h"
|
||||
#include "UnitsSchemaCentimeters.h"
|
||||
#include "UnitsSchemaInternal.h"
|
||||
#include "UnitsSchemaImperial1.h"
|
||||
#include "UnitsSchemaMKS.h"
|
||||
#include "UnitsSchemaMmMin.h"
|
||||
#include "UnitsSchemaFemMilliMeterNewton.h"
|
||||
#include "UnitsSchemaMeterDecimal.h"
|
||||
#include "UnitsSchema.h"
|
||||
#include "UnitsSchemas.h"
|
||||
#include "UnitsSchemasData.h"
|
||||
|
||||
using namespace Base;
|
||||
using Base::UnitsApi;
|
||||
using Base::UnitsSchema;
|
||||
using Base::UnitsSchemas;
|
||||
|
||||
// === static attributes ================================================
|
||||
|
||||
UnitsSchemaPtr UnitsApi::UserPrefSystem(new UnitsSchemaInternal());
|
||||
UnitSystem UnitsApi::currentSystem = UnitSystem::SI1;
|
||||
|
||||
int UnitsApi::UserPrefDecimals = 2;
|
||||
|
||||
QString UnitsApi::getDescription(UnitSystem system)
|
||||
void UnitsApi::init()
|
||||
{
|
||||
switch (system) {
|
||||
case UnitSystem::SI1:
|
||||
return tr("Standard (mm, kg, s, °)");
|
||||
case UnitSystem::SI2:
|
||||
return tr("MKS (m, kg, s, °)");
|
||||
case UnitSystem::Imperial1:
|
||||
return tr("US customary (in, lb)");
|
||||
case UnitSystem::ImperialDecimal:
|
||||
return tr("Imperial decimal (in, lb)");
|
||||
case UnitSystem::Centimeters:
|
||||
return tr("Building Euro (cm, m², m³)");
|
||||
case UnitSystem::ImperialBuilding:
|
||||
return tr("Building US (ft-in, sqft, cft)");
|
||||
case UnitSystem::MmMin:
|
||||
return tr("Metric small parts & CNC (mm, mm/min)");
|
||||
case UnitSystem::ImperialCivil:
|
||||
return tr("Imperial for Civil Eng (ft, ft/s)");
|
||||
case UnitSystem::FemMilliMeterNewton:
|
||||
return tr("FEM (mm, N, s)");
|
||||
case UnitSystem::MeterDecimal:
|
||||
return tr("Meter decimal (m, m², m³)");
|
||||
default:
|
||||
return tr("Unknown schema");
|
||||
}
|
||||
schemas = std::make_unique<UnitsSchemas>(UnitsSchemasData::unitSchemasDataPack);
|
||||
}
|
||||
|
||||
UnitsSchemaPtr UnitsApi::createSchema(UnitSystem system)
|
||||
std::vector<std::string> UnitsApi::getDescriptions()
|
||||
{
|
||||
switch (system) {
|
||||
case UnitSystem::SI1:
|
||||
return std::make_unique<UnitsSchemaInternal>();
|
||||
case UnitSystem::SI2:
|
||||
return std::make_unique<UnitsSchemaMKS>();
|
||||
case UnitSystem::Imperial1:
|
||||
return std::make_unique<UnitsSchemaImperial1>();
|
||||
case UnitSystem::ImperialDecimal:
|
||||
return std::make_unique<UnitsSchemaImperialDecimal>();
|
||||
case UnitSystem::Centimeters:
|
||||
return std::make_unique<UnitsSchemaCentimeters>();
|
||||
case UnitSystem::ImperialBuilding:
|
||||
return std::make_unique<UnitsSchemaImperialBuilding>();
|
||||
case UnitSystem::MmMin:
|
||||
return std::make_unique<UnitsSchemaMmMin>();
|
||||
case UnitSystem::ImperialCivil:
|
||||
return std::make_unique<UnitsSchemaImperialCivil>();
|
||||
case UnitSystem::FemMilliMeterNewton:
|
||||
return std::make_unique<UnitsSchemaFemMilliMeterNewton>();
|
||||
case UnitSystem::MeterDecimal:
|
||||
return std::make_unique<UnitsSchemaMeterDecimal>();
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
return schemas->descriptions();
|
||||
}
|
||||
|
||||
void UnitsApi::setSchema(UnitSystem system)
|
||||
std::vector<std::string> UnitsApi::getNames()
|
||||
{
|
||||
if (UserPrefSystem) {
|
||||
UserPrefSystem->resetSchemaUnits(); // for schemas changed the Quantity constants
|
||||
}
|
||||
|
||||
UserPrefSystem = createSchema(system);
|
||||
currentSystem = system;
|
||||
|
||||
// for wrong value fall back to standard schema
|
||||
if (!UserPrefSystem) {
|
||||
UserPrefSystem = std::make_unique<UnitsSchemaInternal>();
|
||||
currentSystem = UnitSystem::SI1;
|
||||
}
|
||||
|
||||
UserPrefSystem->setSchemaUnits(); // if necessary a unit schema can change the constants in
|
||||
// Quantity (e.g. mi=1.8km rather then 1.6km).
|
||||
return schemas->names();
|
||||
}
|
||||
|
||||
std::string UnitsApi::toString(const Base::Quantity& quantity, const QuantityFormat& format)
|
||||
std::size_t UnitsApi::count()
|
||||
{
|
||||
return static_cast<int>(schemas->count());
|
||||
}
|
||||
|
||||
bool UnitsApi::isMultiUnitAngle()
|
||||
{
|
||||
return schemas->currentSchema()->isMultiUnitAngle();
|
||||
}
|
||||
|
||||
bool UnitsApi::isMultiUnitLength()
|
||||
{
|
||||
return schemas->currentSchema()->isMultiUnitLength();
|
||||
}
|
||||
|
||||
std::string UnitsApi::getBasicLengthUnit()
|
||||
{
|
||||
return schemas->currentSchema()->getBasicLengthUnit();
|
||||
}
|
||||
|
||||
std::size_t UnitsApi::getFractDenominator()
|
||||
{
|
||||
return schemas->defFractDenominator();
|
||||
}
|
||||
|
||||
std::unique_ptr<UnitsSchema> UnitsApi::createSchema(const std::size_t num)
|
||||
{
|
||||
return std::make_unique<UnitsSchema>(schemas->spec(num));
|
||||
}
|
||||
|
||||
void UnitsApi::setSchema(const std::string& name)
|
||||
{
|
||||
schemas->select(name);
|
||||
}
|
||||
|
||||
void UnitsApi::setSchema(const size_t num)
|
||||
{
|
||||
schemas->select(num);
|
||||
}
|
||||
|
||||
std::string UnitsApi::toString(const Quantity& quantity, const QuantityFormat& format)
|
||||
{
|
||||
return fmt::format("'{} {}'", toNumber(quantity, format), quantity.getUnit().getString());
|
||||
}
|
||||
|
||||
std::string UnitsApi::toNumber(const Base::Quantity& quantity, const QuantityFormat& format)
|
||||
std::string UnitsApi::toNumber(const Quantity& quantity, const QuantityFormat& format)
|
||||
{
|
||||
return toNumber(quantity.getValue(), format);
|
||||
}
|
||||
|
||||
std::string UnitsApi::toNumber(double value, const QuantityFormat& format)
|
||||
std::string UnitsApi::toNumber(const double value, const QuantityFormat& format)
|
||||
{
|
||||
std::stringstream ss;
|
||||
|
||||
@@ -156,31 +123,6 @@ std::string UnitsApi::toNumber(double value, const QuantityFormat& format)
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
// return true if the current user schema uses multiple units for length (ex. Ft/In)
|
||||
bool UnitsApi::isMultiUnitLength()
|
||||
{
|
||||
return UserPrefSystem->isMultiUnitLength();
|
||||
}
|
||||
|
||||
// return true if the current user schema uses multiple units for angles (ex. DMS)
|
||||
bool UnitsApi::isMultiUnitAngle()
|
||||
{
|
||||
return UserPrefSystem->isMultiUnitAngle();
|
||||
}
|
||||
|
||||
std::string UnitsApi::getBasicLengthUnit()
|
||||
{
|
||||
return UserPrefSystem->getBasicLengthUnit();
|
||||
}
|
||||
|
||||
// === static translation methods ==========================================
|
||||
|
||||
std::string
|
||||
UnitsApi::schemaTranslate(const Base::Quantity& quant, double& factor, std::string& unitString)
|
||||
{
|
||||
return UserPrefSystem->schemaTranslate(quant, factor, unitString);
|
||||
}
|
||||
|
||||
double UnitsApi::toDouble(PyObject* args, const Base::Unit& u)
|
||||
{
|
||||
if (PyUnicode_Check(args)) {
|
||||
@@ -203,34 +145,30 @@ double UnitsApi::toDouble(PyObject* args, const Base::Unit& u)
|
||||
throw Base::UnitsMismatchError("Wrong parameter type!");
|
||||
}
|
||||
|
||||
Quantity UnitsApi::toQuantity(PyObject* args, const Base::Unit& u)
|
||||
std::string
|
||||
UnitsApi::schemaTranslate(const Quantity& quant, double& factor, std::string& unitString)
|
||||
{
|
||||
double d {};
|
||||
if (PyUnicode_Check(args)) {
|
||||
std::string str(PyUnicode_AsUTF8(args));
|
||||
// Parse the string
|
||||
Quantity q = Quantity::parse(str);
|
||||
d = q.getValue();
|
||||
}
|
||||
else if (PyFloat_Check(args)) {
|
||||
d = PyFloat_AsDouble(args);
|
||||
}
|
||||
else if (PyLong_Check(args)) {
|
||||
d = static_cast<double>(PyLong_AsLong(args));
|
||||
}
|
||||
else {
|
||||
throw Base::UnitsMismatchError("Wrong parameter type!");
|
||||
}
|
||||
|
||||
return Quantity(d, u);
|
||||
return schemas->currentSchema()->translate(quant, factor, unitString);
|
||||
}
|
||||
|
||||
void UnitsApi::setDecimals(int prec)
|
||||
std::string UnitsApi::schemaTranslate(const Quantity& quant)
|
||||
{
|
||||
UserPrefDecimals = prec;
|
||||
double dummy1 {}; // to satisfy GCC
|
||||
std::string dummy2;
|
||||
return schemas->currentSchema()->translate(quant, dummy1, dummy2);
|
||||
}
|
||||
|
||||
int UnitsApi::getDecimals()
|
||||
void UnitsApi::setDecimals(const std::size_t prec)
|
||||
{
|
||||
return UserPrefDecimals;
|
||||
decimals = prec;
|
||||
}
|
||||
|
||||
size_t UnitsApi::getDecimals()
|
||||
{
|
||||
return decimals;
|
||||
}
|
||||
|
||||
size_t UnitsApi::getDefDecimals()
|
||||
{
|
||||
return schemas->getDecimals();
|
||||
}
|
||||
|
||||
@@ -20,13 +20,12 @@
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
|
||||
#ifndef BASE_UNITSAPI_H
|
||||
#define BASE_UNITSAPI_H
|
||||
|
||||
#include <memory>
|
||||
#include <QCoreApplication>
|
||||
#include "UnitsSchema.h"
|
||||
#include "UnitsSchemas.h"
|
||||
#include "UnitsSchemasData.h"
|
||||
#include "Quantity.h"
|
||||
|
||||
|
||||
@@ -37,96 +36,71 @@ using PyMethodDef = struct PyMethodDef;
|
||||
|
||||
namespace Base
|
||||
{
|
||||
using UnitsSchemaPtr = std::unique_ptr<UnitsSchema>;
|
||||
|
||||
/**
|
||||
* The UnitsApi
|
||||
*/
|
||||
|
||||
class BaseExport UnitsApi
|
||||
{
|
||||
Q_DECLARE_TR_FUNCTIONS(UnitsApi)
|
||||
|
||||
public:
|
||||
/** set Schema
|
||||
* set the UnitsSchema of the Application
|
||||
* this a represented by a class of type UnitSchema which
|
||||
* defines a set of standard units for that schema and rules
|
||||
* for representative strings.
|
||||
*/
|
||||
static void setSchema(UnitSystem s);
|
||||
/// return the active schema
|
||||
static UnitSystem getSchema()
|
||||
{
|
||||
return currentSystem;
|
||||
}
|
||||
/// Returns a brief description of a schema
|
||||
static QString getDescription(UnitSystem);
|
||||
static void init();
|
||||
static std::unique_ptr<UnitsSchema> createSchema(std::size_t num);
|
||||
static void setSchema(const std::string& name);
|
||||
static void setSchema(std::size_t num);
|
||||
|
||||
static std::string
|
||||
schemaTranslate(const Base::Quantity& quant, double& factor, std::string& unitString);
|
||||
static std::string schemaTranslate(const Base::Quantity& quant)
|
||||
{ // to satisfy GCC
|
||||
double dummy1 {};
|
||||
std::string dummy2;
|
||||
return UnitsApi::schemaTranslate(quant, dummy1, dummy2);
|
||||
}
|
||||
schemaTranslate(const Quantity& quant, double& factor, std::string& unitString);
|
||||
|
||||
/** Get a number as string for a quantity of a given format.
|
||||
* The string is a number in C locale (i.e. the decimal separator is always a dot) and if
|
||||
* needed represented in scientific notation. The string also includes the unit of the quantity.
|
||||
*/
|
||||
static std::string toString(const Base::Quantity& q,
|
||||
const QuantityFormat& f = QuantityFormat(QuantityFormat::Default));
|
||||
/** Get a number as string for a quantity of a given format.
|
||||
* The string is a number in C locale (i.e. the decimal separator is always a dot) and if
|
||||
* needed represented in scientific notation. The string doesn't include the unit of the
|
||||
* quantity.
|
||||
*/
|
||||
static std::string toNumber(const Base::Quantity& q,
|
||||
const QuantityFormat& f = QuantityFormat(QuantityFormat::Default));
|
||||
/** Get a number as string for a double of a given format.
|
||||
* The string is a number in C locale (i.e. the decimal separator is always a dot) and if
|
||||
* needed represented in scientific notation. The string doesn't include the unit of the
|
||||
* quantity.
|
||||
*/
|
||||
static std::string toNumber(double value,
|
||||
const QuantityFormat& f = QuantityFormat(QuantityFormat::Default));
|
||||
static std::string schemaTranslate(const Quantity& quant);
|
||||
|
||||
/**
|
||||
* toString & toNumber:
|
||||
* Quantity to string. Optionally apply format
|
||||
* The string is a number in C locale (i.e. the decimal separator is always a dot)
|
||||
* Scientific notation (if needed).
|
||||
*/
|
||||
|
||||
/** INCLUDES unit */
|
||||
static std::string
|
||||
toString(const Quantity& quantity,
|
||||
const QuantityFormat& format = QuantityFormat(QuantityFormat::Default));
|
||||
|
||||
/** Does NOT include unit */
|
||||
static std::string
|
||||
toNumber(const Quantity& quantity,
|
||||
const QuantityFormat& format = QuantityFormat(QuantityFormat::Default));
|
||||
|
||||
/** Does NOT include unit */
|
||||
static std::string
|
||||
toNumber(double value, const QuantityFormat& format = QuantityFormat(QuantityFormat::Default));
|
||||
|
||||
/// generate a value for a quantity with default user preferred system
|
||||
static double toDouble(PyObject* args, const Base::Unit& u = Base::Unit());
|
||||
/// generate a value for a quantity with default user preferred system
|
||||
static Quantity toQuantity(PyObject* args, const Base::Unit& u = Base::Unit());
|
||||
|
||||
// set the number of decimals
|
||||
static void setDecimals(int);
|
||||
// get the number of decimals
|
||||
static int getDecimals();
|
||||
//@}
|
||||
static void setDecimals(std::size_t);
|
||||
static std::size_t getDecimals();
|
||||
static std::size_t getDefDecimals();
|
||||
|
||||
// double Result;
|
||||
static std::vector<std::string> getDescriptions();
|
||||
static std::vector<std::string> getNames();
|
||||
|
||||
// return true if the current user schema uses multiple units for length (ex. Ft/In)
|
||||
static bool isMultiUnitLength();
|
||||
static std::size_t count();
|
||||
|
||||
// return true if the current user schema uses multiple units for angles (ex. DMS)
|
||||
static bool isMultiUnitAngle();
|
||||
|
||||
// return the basic unit of measure for length in the current user schema.
|
||||
static bool isMultiUnitLength();
|
||||
static std::string getBasicLengthUnit();
|
||||
static std::size_t getFractDenominator();
|
||||
|
||||
static std::size_t getDefSchemaNum()
|
||||
{
|
||||
return schemas->spec().num;
|
||||
}
|
||||
// Python interface
|
||||
static PyMethodDef Methods[];
|
||||
|
||||
/// return an instance of the given enum value
|
||||
static UnitsSchemaPtr createSchema(UnitSystem s);
|
||||
|
||||
protected:
|
||||
static UnitsSchemaPtr UserPrefSystem;
|
||||
static UnitSystem currentSystem;
|
||||
/// number of decimals for floats
|
||||
static int UserPrefDecimals;
|
||||
static inline auto schemas =
|
||||
std::make_unique<UnitsSchemas>(UnitsSchemasData::unitSchemasDataPack);
|
||||
static inline std::size_t decimals {2};
|
||||
static inline std::size_t denominator {2};
|
||||
|
||||
protected:
|
||||
// the python API wrapper methods
|
||||
static PyObject* sParseQuantity(PyObject* self, PyObject* args);
|
||||
static PyObject* sListSchemas(PyObject* self, PyObject* args);
|
||||
@@ -138,5 +112,4 @@ protected:
|
||||
|
||||
} // namespace Base
|
||||
|
||||
|
||||
#endif // BASE_UNITSAPI_H
|
||||
|
||||
@@ -20,9 +20,7 @@
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
|
||||
#include "PreCompiled.h"
|
||||
|
||||
#ifndef _PreComp_
|
||||
#include <memory>
|
||||
#endif
|
||||
@@ -39,10 +37,9 @@ using namespace Base;
|
||||
//**************************************************************************
|
||||
// Python stuff of UnitsApi
|
||||
|
||||
// UnitsApi Methods
|
||||
PyMethodDef UnitsApi::Methods[] = {
|
||||
{"parseQuantity",
|
||||
UnitsApi::sParseQuantity,
|
||||
sParseQuantity,
|
||||
METH_VARARGS,
|
||||
"parseQuantity(string) -> Base.Quantity()\n\n"
|
||||
"calculate a mathematical expression with units to a quantity object. \n"
|
||||
@@ -51,27 +48,27 @@ PyMethodDef UnitsApi::Methods[] = {
|
||||
"or for more complex espressions:\n"
|
||||
"parseQuantity('sin(pi)/50.0 m/s^2')\n"},
|
||||
{"listSchemas",
|
||||
UnitsApi::sListSchemas,
|
||||
sListSchemas,
|
||||
METH_VARARGS,
|
||||
"listSchemas() -> a tuple of schemas\n\n"
|
||||
"listSchemas(int) -> description of the given schema\n\n"},
|
||||
{"getSchema",
|
||||
UnitsApi::sGetSchema,
|
||||
sGetSchema,
|
||||
METH_VARARGS,
|
||||
"getSchema() -> int\n\n"
|
||||
"The int is the position of the tuple returned by listSchemas"},
|
||||
{"setSchema",
|
||||
UnitsApi::sSetSchema,
|
||||
sSetSchema,
|
||||
METH_VARARGS,
|
||||
"setSchema(int) -> None\n\n"
|
||||
"Sets the current schema to the given number, if possible"},
|
||||
{"schemaTranslate",
|
||||
UnitsApi::sSchemaTranslate,
|
||||
sSchemaTranslate,
|
||||
METH_VARARGS,
|
||||
"schemaTranslate(Quantity, int) -> tuple\n\n"
|
||||
"Translate a quantity to a given schema"},
|
||||
{"toNumber",
|
||||
UnitsApi::sToNumber,
|
||||
sToNumber,
|
||||
METH_VARARGS,
|
||||
"toNumber(Quantity or float, [format='g', decimals=-1]) -> str\n\n"
|
||||
"Convert a quantity or float to a string"},
|
||||
@@ -86,30 +83,32 @@ PyObject* UnitsApi::sParseQuantity(PyObject* /*self*/, PyObject* args)
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Quantity rtn;
|
||||
std::string str(pstr);
|
||||
const std::string str {pstr};
|
||||
PyMem_Free(pstr);
|
||||
try {
|
||||
rtn = Quantity::parse(str);
|
||||
return new QuantityPy(new Quantity(Quantity::parse(str)));
|
||||
}
|
||||
catch (const Base::ParserError&) {
|
||||
PyErr_Format(PyExc_ValueError, "invalid unit expression \n");
|
||||
catch (const ParserError&) {
|
||||
PyErr_Format(PyExc_ValueError,
|
||||
"invalid unit expression: '%s'\n",
|
||||
std::string {pstr}.c_str());
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return new QuantityPy(new Quantity(rtn));
|
||||
}
|
||||
|
||||
PyObject* UnitsApi::sListSchemas(PyObject* /*self*/, PyObject* args)
|
||||
{
|
||||
auto names = UnitsApi::getNames();
|
||||
const int num = static_cast<int>(names.size());
|
||||
|
||||
if (PyArg_ParseTuple(args, "")) {
|
||||
int num = static_cast<int>(UnitSystem::NumUnitSystemTypes);
|
||||
Py::Tuple tuple(num);
|
||||
for (int i = 0; i < num; i++) {
|
||||
const auto description {
|
||||
UnitsApi::getDescription(static_cast<UnitSystem>(i)).toStdString()};
|
||||
tuple.setItem(i, Py::String(description.c_str()));
|
||||
}
|
||||
Py::Tuple tuple {num};
|
||||
|
||||
auto addItem = [&, i {0}](const std::string& name) mutable {
|
||||
tuple.setItem(i++, Py::String {name.c_str()});
|
||||
};
|
||||
|
||||
std::for_each(names.begin(), names.end(), addItem);
|
||||
|
||||
return Py::new_reference_to(tuple);
|
||||
}
|
||||
@@ -117,14 +116,12 @@ PyObject* UnitsApi::sListSchemas(PyObject* /*self*/, PyObject* args)
|
||||
PyErr_Clear();
|
||||
int index {};
|
||||
if (PyArg_ParseTuple(args, "i", &index)) {
|
||||
int num = static_cast<int>(UnitSystem::NumUnitSystemTypes);
|
||||
if (index < 0 || index >= num) {
|
||||
PyErr_SetString(PyExc_ValueError, "invalid schema value");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const auto description {
|
||||
UnitsApi::getDescription(static_cast<UnitSystem>(index)).toStdString()};
|
||||
const auto description = schemas->descriptions().at(index);
|
||||
return Py_BuildValue("s", description.c_str());
|
||||
}
|
||||
|
||||
@@ -138,20 +135,21 @@ PyObject* UnitsApi::sGetSchema(PyObject* /*self*/, PyObject* args)
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return Py_BuildValue("i", static_cast<int>(currentSystem));
|
||||
return Py_BuildValue("i", count());
|
||||
}
|
||||
|
||||
PyObject* UnitsApi::sSetSchema(PyObject* /*self*/, PyObject* args)
|
||||
{
|
||||
PyErr_Clear();
|
||||
int index {};
|
||||
if (PyArg_ParseTuple(args, "i", &index)) {
|
||||
int num = static_cast<int>(UnitSystem::NumUnitSystemTypes);
|
||||
if (index < 0 || index >= num) {
|
||||
if (PyArg_ParseTuple(args, "i", &index) != 0) {
|
||||
|
||||
if (index < 0 || index >= static_cast<int>(count())) {
|
||||
PyErr_SetString(PyExc_ValueError, "invalid schema value");
|
||||
return nullptr;
|
||||
}
|
||||
setSchema(static_cast<UnitSystem>(index));
|
||||
|
||||
schemas->select(index);
|
||||
}
|
||||
Py_Return;
|
||||
}
|
||||
@@ -160,27 +158,26 @@ PyObject* UnitsApi::sSchemaTranslate(PyObject* /*self*/, PyObject* args)
|
||||
{
|
||||
PyObject* py {};
|
||||
int index {};
|
||||
if (!PyArg_ParseTuple(args, "O!i", &(QuantityPy::Type), &py, &index)) {
|
||||
if (!PyArg_ParseTuple(args, "O!i", &QuantityPy::Type, &py, &index)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Quantity quant;
|
||||
quant = *static_cast<Base::QuantityPy*>(py)->getQuantityPtr();
|
||||
|
||||
std::unique_ptr<UnitsSchema> schema(createSchema(static_cast<UnitSystem>(index)));
|
||||
if (!schema) {
|
||||
PyErr_SetString(PyExc_ValueError, "invalid schema value");
|
||||
if (index < 0 || index >= static_cast<int>(count())) {
|
||||
PyErr_SetString(PyExc_ValueError,
|
||||
std::string {"invalid schema index:" + std::to_string(index)}.c_str());
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const Quantity quant {*static_cast<QuantityPy*>(py)->getQuantityPtr()};
|
||||
|
||||
double factor {};
|
||||
std::string uus;
|
||||
std::string uss = schema->schemaTranslate(quant, factor, uus);
|
||||
std::string unitStr;
|
||||
const std::string unitStrLocalised = schemaTranslate(quant, factor, unitStr);
|
||||
|
||||
Py::Tuple res(3);
|
||||
res[0] = Py::String(uss, "utf-8");
|
||||
res[1] = Py::Float(factor);
|
||||
res[2] = Py::String(uus, "utf-8");
|
||||
Py::Tuple res {3};
|
||||
res[0] = Py::String {unitStrLocalised, "utf-8"};
|
||||
res[1] = Py::Float {factor};
|
||||
res[2] = Py::String {unitStr, "utf-8"};
|
||||
|
||||
return Py::new_reference_to(res);
|
||||
}
|
||||
|
||||
@@ -1,49 +1,142 @@
|
||||
/***************************************************************************
|
||||
* Copyright (c) 2009 Jürgen Riegel <FreeCAD@juergen-riegel.net> *
|
||||
* *
|
||||
* This file is part of the FreeCAD CAx development system. *
|
||||
* *
|
||||
* This library is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU Library General Public *
|
||||
* License as published by the Free Software Foundation; either *
|
||||
* version 2 of the License, or (at your option) any later version. *
|
||||
* *
|
||||
* This library is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU Library General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU Library General Public *
|
||||
* License along with this library; see the file COPYING.LIB. If not, *
|
||||
* write to the Free Software Foundation, Inc., 59 Temple Place, *
|
||||
* Suite 330, Boston, MA 02111-1307, USA *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#include "PreCompiled.h"
|
||||
#ifdef __GNUC__
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include <QLocale>
|
||||
#include <QString>
|
||||
|
||||
#include "Quantity.h"
|
||||
#include "UnitsSchema.h"
|
||||
|
||||
using namespace Base;
|
||||
|
||||
std::string UnitsSchema::toLocale(const Base::Quantity& quant,
|
||||
double factor,
|
||||
const std::string& unitString) const
|
||||
{
|
||||
QLocale Lc;
|
||||
const QuantityFormat& format = quant.getFormat();
|
||||
if (format.option != QuantityFormat::None) {
|
||||
int opt = format.option;
|
||||
Lc.setNumberOptions(static_cast<QLocale::NumberOptions>(opt));
|
||||
}
|
||||
|
||||
QString Ln = Lc.toString((quant.getValue() / factor), format.toFormat(), format.precision);
|
||||
return QStringLiteral("%1 %2").arg(Ln, QString::fromStdString(unitString)).toStdString();
|
||||
}
|
||||
/************************************************************************
|
||||
* *
|
||||
* This file is part of the FreeCAD CAx development system. *
|
||||
* *
|
||||
* This library is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU Library General Public *
|
||||
* License as published by the Free Software Foundation; either *
|
||||
* version 2 of the License, or (at your option) any later version. *
|
||||
* *
|
||||
* This library is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU Library General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU Library General Public *
|
||||
* License along with this library; see the file COPYING.LIB. If not, *
|
||||
* write to the Free Software Foundation, Inc., 59 Temple Place, *
|
||||
* Suite 330, Boston, MA 02111-1307, USA *
|
||||
* *
|
||||
************************************************************************/
|
||||
|
||||
#include "PreCompiled.h"
|
||||
|
||||
#include <iomanip>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
|
||||
#include <QLocale>
|
||||
#include <QString>
|
||||
|
||||
#include "Quantity.h"
|
||||
#include "UnitsSchema.h"
|
||||
#include "UnitsSchemasData.h"
|
||||
#include "UnitsSchemasSpecs.h"
|
||||
#include "Exception.h"
|
||||
#include "Quantity.h"
|
||||
|
||||
using Base::UnitsSchema;
|
||||
using Base::UnitsSchemaSpec;
|
||||
|
||||
|
||||
UnitsSchema::UnitsSchema(UnitsSchemaSpec spec)
|
||||
: spec {std::move(spec)}
|
||||
{}
|
||||
|
||||
std::string UnitsSchema::translate(const Quantity& quant) const
|
||||
{ // to satisfy GCC
|
||||
double dummy1 {};
|
||||
std::string dummy2;
|
||||
return translate(quant, dummy1, dummy2);
|
||||
}
|
||||
|
||||
std::string
|
||||
UnitsSchema::translate(const Quantity& quant, double& factor, std::string& unitString) const
|
||||
{
|
||||
if (spec.translationSpecs.empty()) {
|
||||
return toLocale(quant, 1.0, unitString);
|
||||
}
|
||||
|
||||
const auto unitName = quant.getUnit().getTypeString();
|
||||
|
||||
if (spec.translationSpecs.count(unitName) == 0) {
|
||||
// no schema-level translation. Use defaults.
|
||||
factor = 1.0;
|
||||
unitString = quant.getUnit().getString();
|
||||
|
||||
return toLocale(quant, factor, unitString);
|
||||
}
|
||||
|
||||
const auto value = quant.getValue();
|
||||
|
||||
auto isSuitable = [&](const UnitTranslationSpec& row) {
|
||||
return row.threshold > value || row.threshold == 0; // zero indicates default
|
||||
};
|
||||
|
||||
auto unitSpecs = spec.translationSpecs.at(unitName);
|
||||
const auto unitSpec = std::find_if(unitSpecs.begin(), unitSpecs.end(), isSuitable);
|
||||
if (unitSpec == unitSpecs.end()) {
|
||||
throw RuntimeError("Suitable threshhold not found. Schema: " + spec.name
|
||||
+ " value: " + std::to_string(value));
|
||||
}
|
||||
|
||||
if (unitSpec->factor == 0) {
|
||||
return UnitsSchemasData::runSpecial(unitSpec->unitString, value);
|
||||
}
|
||||
|
||||
factor = unitSpec->factor;
|
||||
unitString = unitSpec->unitString;
|
||||
|
||||
return toLocale(quant, factor, unitString);
|
||||
}
|
||||
|
||||
std::string
|
||||
UnitsSchema::toLocale(const Quantity& quant, const double factor, const std::string& unitString)
|
||||
{
|
||||
QLocale Lc;
|
||||
const QuantityFormat& format = quant.getFormat();
|
||||
if (format.option != QuantityFormat::None) {
|
||||
int opt = format.option;
|
||||
Lc.setNumberOptions(static_cast<QLocale::NumberOptions>(opt));
|
||||
}
|
||||
|
||||
std::string valueString =
|
||||
Lc.toString((quant.getValue() / factor), format.toFormat(), format.precision).toStdString();
|
||||
|
||||
return fmt::format(
|
||||
"{}{}{}",
|
||||
valueString,
|
||||
unitString.empty() || unitString == "°" || unitString == "″" || unitString == "′" ? ""
|
||||
: " ",
|
||||
unitString);
|
||||
}
|
||||
|
||||
bool UnitsSchema::isMultiUnitLength() const
|
||||
{
|
||||
return spec.isMultUnitLen;
|
||||
}
|
||||
|
||||
bool UnitsSchema::isMultiUnitAngle() const
|
||||
{
|
||||
return spec.isMultUnitAngle;
|
||||
}
|
||||
|
||||
std::string UnitsSchema::getBasicLengthUnit() const
|
||||
{
|
||||
return spec.basicLengthUnitStr;
|
||||
}
|
||||
|
||||
std::string UnitsSchema::getName() const
|
||||
{
|
||||
return spec.name;
|
||||
}
|
||||
|
||||
std::string UnitsSchema::getDescription() const
|
||||
{
|
||||
return spec.description;
|
||||
}
|
||||
|
||||
int UnitsSchema::getNum() const
|
||||
{
|
||||
return static_cast<int>(spec.num);
|
||||
}
|
||||
|
||||
@@ -24,78 +24,41 @@
|
||||
#define BASE_UNITSSCHEMA_H
|
||||
|
||||
#include <string>
|
||||
#include <memory>
|
||||
|
||||
#include "UnitsSchemasSpecs.h"
|
||||
#include "Base/Quantity.h"
|
||||
|
||||
namespace Base
|
||||
{
|
||||
class Quantity;
|
||||
|
||||
/** Units systems */
|
||||
enum class UnitSystem
|
||||
{
|
||||
SI1 = 0, /** internal (mm,kg,s) SI system
|
||||
(http://en.wikipedia.org/wiki/International_System_of_Units) */
|
||||
SI2 = 1, /** MKS (m,kg,s) SI system */
|
||||
Imperial1 = 2, /** the Imperial system (http://en.wikipedia.org/wiki/Imperial_units) */
|
||||
ImperialDecimal = 3, /** Imperial with length in inch only */
|
||||
Centimeters = 4, /** All lengths in centimeters, areas and volumes in square/cubic meters */
|
||||
ImperialBuilding = 5, /** All lengths in feet + inches + fractions */
|
||||
MmMin = 6, /** Lengths in mm, Speed in mm/min. Angle in degrees. Useful for small parts & CNC */
|
||||
ImperialCivil = 7, /** Lengths in ft, Speed in ft/s. Used in Civil Eng in North America */
|
||||
FemMilliMeterNewton = 8, /** Lengths in mm, Mass in t, TimeSpan in s, thus force is in N */
|
||||
MeterDecimal = 9, /** Lengths in metres always */
|
||||
NumUnitSystemTypes // must be the last item!
|
||||
};
|
||||
|
||||
|
||||
/** The UnitSchema class
|
||||
* The subclasses of this class define the stuff for a
|
||||
* certain units schema.
|
||||
/**
|
||||
* An individual schema object
|
||||
*/
|
||||
class UnitsSchema
|
||||
{
|
||||
public:
|
||||
UnitsSchema() = default;
|
||||
UnitsSchema(const UnitsSchema&) = default;
|
||||
UnitsSchema(UnitsSchema&&) = default;
|
||||
UnitsSchema& operator=(const UnitsSchema&) = default;
|
||||
UnitsSchema& operator=(UnitsSchema&&) = default;
|
||||
virtual ~UnitsSchema() = default;
|
||||
/** Gets called if this schema gets activated.
|
||||
* Here it's theoretically possible that you can change the static factors
|
||||
* for certain units (e.g. mi = 1,8km instead of mi=1.6km).
|
||||
*/
|
||||
virtual void setSchemaUnits()
|
||||
{}
|
||||
/// If you use setSchemaUnits() you also have to impment this method to undo your changes!
|
||||
virtual void resetSchemaUnits()
|
||||
{}
|
||||
explicit UnitsSchema(UnitsSchemaSpec spec);
|
||||
UnitsSchema() = delete;
|
||||
|
||||
/// This method translates the quantity in a string as the user may expect it.
|
||||
virtual std::string
|
||||
schemaTranslate(const Base::Quantity& quant, double& factor, std::string& unitString) = 0;
|
||||
[[nodiscard]] bool isMultiUnitLength() const;
|
||||
[[nodiscard]] bool isMultiUnitAngle() const;
|
||||
[[nodiscard]] std::string getBasicLengthUnit() const;
|
||||
[[nodiscard]] std::string getName() const;
|
||||
[[nodiscard]] std::string getDescription() const;
|
||||
[[nodiscard]] int getNum() const;
|
||||
|
||||
std::string
|
||||
toLocale(const Base::Quantity& quant, double factor, const std::string& unitString) const;
|
||||
std::string translate(const Quantity& quant) const;
|
||||
std::string translate(const Quantity& quant, double& factor, std::string& unitString) const;
|
||||
|
||||
// return true if this schema uses multiple units for length (ex. Ft/In)
|
||||
virtual bool isMultiUnitLength() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
private:
|
||||
[[nodiscard]] static std::string
|
||||
toLocale(const Quantity& quant, double factor, const std::string& unitString);
|
||||
|
||||
// return true if this schema uses multiple units for angles (ex. DMS)
|
||||
virtual bool isMultiUnitAngle() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// return the basic length unit for this schema
|
||||
virtual std::string getBasicLengthUnit() const
|
||||
{
|
||||
return {"mm"};
|
||||
}
|
||||
UnitsSchemaSpec spec;
|
||||
};
|
||||
|
||||
} // namespace Base
|
||||
|
||||
} // namespace Base
|
||||
#endif // BASE_UNITSSCHEMA_H
|
||||
|
||||
@@ -1,65 +0,0 @@
|
||||
/***************************************************************************
|
||||
* Copyright (c) 2016 Yorik van Havre <yorik@uncreated.net> *
|
||||
* *
|
||||
* This file is part of the FreeCAD CAx development system. *
|
||||
* *
|
||||
* This library is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU Library General Public *
|
||||
* License as published by the Free Software Foundation; either *
|
||||
* version 2 of the License, or (at your option) any later version. *
|
||||
* *
|
||||
* This library is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU Library General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU Library General Public *
|
||||
* License along with this library; see the file COPYING.LIB. If not, *
|
||||
* write to the Free Software Foundation, Inc., 59 Temple Place, *
|
||||
* Suite 330, Boston, MA 02111-1307, USA *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
|
||||
#include "PreCompiled.h"
|
||||
#ifndef _PreComp_
|
||||
#include <algorithm>
|
||||
#include <array>
|
||||
#endif
|
||||
|
||||
#include "Quantity.h"
|
||||
#include "Unit.h"
|
||||
#include "UnitsSchemaCentimeters.h"
|
||||
|
||||
using namespace Base;
|
||||
|
||||
std::string UnitsSchemaCentimeters::schemaTranslate(const Base::Quantity& quant,
|
||||
double& factor,
|
||||
std::string& unitString)
|
||||
{
|
||||
static std::array<std::pair<Unit, std::pair<std::string, double>>, 7> unitSpecs {{
|
||||
{Unit::Length, {"cm", 10.0}},
|
||||
{Unit::Area, {"m^2", 1000000.0}},
|
||||
{Unit::Volume, {"m^3", 1000000000.0}},
|
||||
{Unit::Power, {"W", 1000000.0}},
|
||||
{Unit::ElectricPotential, {"V", 1000000.0}},
|
||||
{Unit::HeatFlux, {"W/m^2", 1.0}},
|
||||
{Unit::Velocity, {"mm/min", 1.0 / 60}},
|
||||
}};
|
||||
|
||||
const auto unit = quant.getUnit();
|
||||
const auto spec = std::find_if(unitSpecs.begin(), unitSpecs.end(), [&](const auto& pair) {
|
||||
return pair.first == unit;
|
||||
});
|
||||
|
||||
if (spec != std::end(unitSpecs)) {
|
||||
unitString = spec->second.first;
|
||||
factor = spec->second.second;
|
||||
}
|
||||
else {
|
||||
unitString = quant.getUnit().getString();
|
||||
factor = 1.0;
|
||||
}
|
||||
|
||||
return toLocale(quant, factor, unitString);
|
||||
}
|
||||
@@ -1,48 +0,0 @@
|
||||
/***************************************************************************
|
||||
* Copyright (c) 2016 Yorik van Havre <yorik@uncreated.net> *
|
||||
* *
|
||||
* This file is part of the FreeCAD CAx development system. *
|
||||
* *
|
||||
* This library is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU Library General Public *
|
||||
* License as published by the Free Software Foundation; either *
|
||||
* version 2 of the License, or (at your option) any later version. *
|
||||
* *
|
||||
* This library is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU Library General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU Library General Public *
|
||||
* License along with this library; see the file COPYING.LIB. If not, *
|
||||
* write to the Free Software Foundation, Inc., 59 Temple Place, *
|
||||
* Suite 330, Boston, MA 02111-1307, USA *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef BASE_UNITSSCHEMACENTIMETERS_H
|
||||
#define BASE_UNITSSCHEMACENTIMETERS_H
|
||||
|
||||
#include "UnitsSchema.h"
|
||||
|
||||
namespace Base
|
||||
{
|
||||
|
||||
/**
|
||||
* The UnitSchema class
|
||||
*/
|
||||
class UnitsSchemaCentimeters: public UnitsSchema
|
||||
{
|
||||
public:
|
||||
std::string
|
||||
schemaTranslate(const Base::Quantity& quant, double& factor, std::string& unitString) override;
|
||||
|
||||
std::string getBasicLengthUnit() const override
|
||||
{
|
||||
return {"cm"};
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace Base
|
||||
|
||||
#endif // BASE_UNITSSCHEMACENTIMETERS_H
|
||||
@@ -1,61 +0,0 @@
|
||||
/***************************************************************************
|
||||
* Copyright (c) 2009 Jürgen Riegel <FreeCAD@juergen-riegel.net> *
|
||||
* Copyright (c) 2020 Bernd Hahnebach <bernd@bimstatik.org> *
|
||||
* *
|
||||
* This file is part of the FreeCAD CAx development system. *
|
||||
* *
|
||||
* This library is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU Library General Public *
|
||||
* License as published by the Free Software Foundation; either *
|
||||
* version 2 of the License, or (at your option) any later version. *
|
||||
* *
|
||||
* This library is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU Library General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU Library General Public *
|
||||
* License along with this library; see the file COPYING.LIB. If not, *
|
||||
* write to the Free Software Foundation, Inc., 59 Temple Place, *
|
||||
* Suite 330, Boston, MA 02111-1307, USA *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
|
||||
#include "PreCompiled.h"
|
||||
#ifndef _PreComp_
|
||||
#include <algorithm>
|
||||
#include <array>
|
||||
#endif
|
||||
|
||||
#include "Quantity.h"
|
||||
#include "Unit.h"
|
||||
#include "UnitsSchemaFemMilliMeterNewton.h"
|
||||
|
||||
using namespace Base;
|
||||
|
||||
std::string UnitsSchemaFemMilliMeterNewton::schemaTranslate(const Quantity& quant,
|
||||
double& factor,
|
||||
std::string& unitString)
|
||||
{
|
||||
static std::array<std::pair<Unit, std::pair<std::string, double>>, 2> unitSpecs {{
|
||||
{Unit::Length, {"mm", 1.0}},
|
||||
{Unit::Mass, {"t", 1e3}},
|
||||
}};
|
||||
|
||||
const auto unit = quant.getUnit();
|
||||
const auto spec = std::find_if(unitSpecs.begin(), unitSpecs.end(), [&](const auto& pair) {
|
||||
return pair.first == unit;
|
||||
});
|
||||
|
||||
if (spec != std::end(unitSpecs)) {
|
||||
unitString = spec->second.first;
|
||||
factor = spec->second.second;
|
||||
}
|
||||
else {
|
||||
unitString = quant.getUnit().getString();
|
||||
factor = 1.0;
|
||||
}
|
||||
|
||||
return toLocale(quant, factor, unitString);
|
||||
}
|
||||
@@ -1,47 +0,0 @@
|
||||
/***************************************************************************
|
||||
* Copyright (c) 2009 Jürgen Riegel <FreeCAD@juergen-riegel.net> *
|
||||
* Copyright (c) 2020 Bernd Hahnebach <bernd@bimstatik.org> *
|
||||
* *
|
||||
* This file is part of the FreeCAD CAx development system. *
|
||||
* *
|
||||
* This library is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU Library General Public *
|
||||
* License as published by the Free Software Foundation; either *
|
||||
* version 2 of the License, or (at your option) any later version. *
|
||||
* *
|
||||
* This library is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU Library General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU Library General Public *
|
||||
* License along with this library; see the file COPYING.LIB. If not, *
|
||||
* write to the Free Software Foundation, Inc., 59 Temple Place, *
|
||||
* Suite 330, Boston, MA 02111-1307, USA *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef BASE_UNITSSCHEMAFEMMLLIMETERNEWTON_H
|
||||
#define BASE_UNITSSCHEMAFEMMLLIMETERNEWTON_H
|
||||
|
||||
#include "UnitsSchema.h"
|
||||
|
||||
namespace Base
|
||||
{
|
||||
|
||||
/* Milli metric / Newton / Seconds unit schema for use in FEM.
|
||||
* Lengths are always in mm.
|
||||
* Mass is in t.
|
||||
* TimeSpann in S.
|
||||
* Thus the Force is in Newton
|
||||
*/
|
||||
class UnitsSchemaFemMilliMeterNewton: public UnitsSchema
|
||||
{
|
||||
public:
|
||||
std::string
|
||||
schemaTranslate(const Base::Quantity& quant, double& factor, std::string& unitString) override;
|
||||
};
|
||||
|
||||
} // namespace Base
|
||||
|
||||
#endif // BASE_UNITSSCHEMAFEMMLLIMETERNEWTON_H
|
||||
@@ -1,400 +0,0 @@
|
||||
/***************************************************************************
|
||||
* Copyright (c) 2009 Jürgen Riegel <FreeCAD@juergen-riegel.net> *
|
||||
* *
|
||||
* This file is part of the FreeCAD CAx development system. *
|
||||
* *
|
||||
* This library is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU Library General Public *
|
||||
* License as published by the Free Software Foundation; either *
|
||||
* version 2 of the License, or (at your option) any later version. *
|
||||
* *
|
||||
* This library is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU Library General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU Library General Public *
|
||||
* License along with this library; see the file COPYING.LIB. If not, *
|
||||
* write to the Free Software Foundation, Inc., 59 Temple Place, *
|
||||
* Suite 330, Boston, MA 02111-1307, USA *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
|
||||
#include "PreCompiled.h"
|
||||
#ifndef _PreComp_
|
||||
#include <cmath>
|
||||
#include <sstream>
|
||||
#endif
|
||||
#ifdef __GNUC__
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include "Quantity.h"
|
||||
#include "UnitsSchemaImperial1.h"
|
||||
|
||||
using namespace Base;
|
||||
|
||||
std::string UnitsSchemaImperial1::schemaTranslate(const Quantity& quant,
|
||||
double& factor,
|
||||
std::string& unitString)
|
||||
{
|
||||
double UnitValue = std::abs(quant.getValue());
|
||||
Unit unit = quant.getUnit();
|
||||
// for imperial user/programmer mind; UnitValue is in internal system, that means
|
||||
// mm/kg/s. And all combined units have to be calculated from there!
|
||||
|
||||
// now do special treatment on all cases seems necessary:
|
||||
if (unit == Unit::Length) { // Length handling ============================
|
||||
if (UnitValue < 0.00000254) { // smaller then 0.001 thou -> inch and scientific notation
|
||||
unitString = "in";
|
||||
factor = 25.4;
|
||||
}
|
||||
else if (UnitValue < 2.54) { // smaller then 0.1 inch -> Thou (mil)
|
||||
unitString = "thou";
|
||||
factor = 0.0254;
|
||||
}
|
||||
else if (UnitValue < 304.8) {
|
||||
unitString = "\"";
|
||||
factor = 25.4;
|
||||
}
|
||||
else if (UnitValue < 914.4) {
|
||||
unitString = "\'";
|
||||
factor = 304.8;
|
||||
}
|
||||
else if (UnitValue < 1609344.0) {
|
||||
unitString = "yd";
|
||||
factor = 914.4;
|
||||
}
|
||||
else if (UnitValue < 1609344000.0) {
|
||||
unitString = "mi";
|
||||
factor = 1609344.0;
|
||||
}
|
||||
else { // bigger then 1000 mi -> scientific notation
|
||||
unitString = "in";
|
||||
factor = 25.4;
|
||||
}
|
||||
}
|
||||
else if (unit == Unit::Angle) {
|
||||
unitString = "\xC2\xB0";
|
||||
factor = 1.0;
|
||||
}
|
||||
else if (unit == Unit::Area) {
|
||||
// TODO: Cascade for the Areas
|
||||
// default action for all cases without special treatment:
|
||||
unitString = "in^2";
|
||||
factor = 645.16;
|
||||
}
|
||||
else if (unit == Unit::Volume) {
|
||||
// TODO: Cascade for the Volume
|
||||
// default action for all cases without special treatment:
|
||||
unitString = "in^3";
|
||||
factor = 16387.064;
|
||||
}
|
||||
else if (unit == Unit::Mass) {
|
||||
// TODO: Cascade for the weights
|
||||
// default action for all cases without special treatment:
|
||||
unitString = "lb";
|
||||
factor = 0.45359237;
|
||||
}
|
||||
else if (unit == Unit::Pressure) {
|
||||
if (UnitValue < 6894.744) { // psi is the smallest
|
||||
unitString = "psi";
|
||||
factor = 6.894744825494;
|
||||
}
|
||||
else if (UnitValue < 6894744.825) {
|
||||
unitString = "ksi";
|
||||
factor = 6894.744825494;
|
||||
}
|
||||
else { // bigger then 1000 ksi -> psi + scientific notation
|
||||
unitString = "psi";
|
||||
factor = 6.894744825494;
|
||||
}
|
||||
}
|
||||
else if (unit == Unit::Stiffness) { // Conversion to lbf/in
|
||||
unitString = "lbf/in";
|
||||
factor = 4.448222 / 0.0254;
|
||||
}
|
||||
else if (unit == Unit::Velocity) {
|
||||
unitString = "in/min";
|
||||
factor = 25.4 / 60;
|
||||
}
|
||||
else {
|
||||
// default action for all cases without special treatment:
|
||||
unitString = quant.getUnit().getString();
|
||||
factor = 1.0;
|
||||
}
|
||||
|
||||
return toLocale(quant, factor, unitString);
|
||||
}
|
||||
|
||||
std::string UnitsSchemaImperialDecimal::schemaTranslate(const Base::Quantity& quant,
|
||||
double& factor,
|
||||
std::string& unitString)
|
||||
{
|
||||
Unit unit = quant.getUnit();
|
||||
// for imperial user/programmer mind; UnitValue is in internal system, that means
|
||||
// mm/kg/s. And all combined units have to be calculated from there!
|
||||
|
||||
// now do special treatment on all cases seems necessary:
|
||||
if (unit == Unit::Length) { // Length handling ============================
|
||||
unitString = "in";
|
||||
factor = 25.4;
|
||||
}
|
||||
else if (unit == Unit::Angle) {
|
||||
unitString = "\xC2\xB0";
|
||||
factor = 1.0;
|
||||
}
|
||||
else if (unit == Unit::Area) {
|
||||
// TODO: Cascade for the Areas
|
||||
// default action for all cases without special treatment:
|
||||
unitString = "in^2";
|
||||
factor = 645.16;
|
||||
}
|
||||
else if (unit == Unit::Volume) {
|
||||
// TODO: Cascade for the Volume
|
||||
// default action for all cases without special treatment:
|
||||
unitString = "in^3";
|
||||
factor = 16387.064;
|
||||
}
|
||||
else if (unit == Unit::Mass) {
|
||||
// TODO: Cascade for the weights
|
||||
// default action for all cases without special treatment:
|
||||
unitString = "lb";
|
||||
factor = 0.45359237;
|
||||
}
|
||||
else if (unit == Unit::Pressure) {
|
||||
unitString = "psi";
|
||||
factor = 6.894744825494;
|
||||
}
|
||||
else if (unit == Unit::Stiffness) {
|
||||
unitString = "lbf/in";
|
||||
factor = 4.448222 / 0.0254;
|
||||
}
|
||||
else if (unit == Unit::Velocity) {
|
||||
unitString = "in/min";
|
||||
factor = 25.4 / 60;
|
||||
}
|
||||
else if (unit == Unit::Acceleration) {
|
||||
unitString = "in/min^2";
|
||||
factor = 25.4 / 3600;
|
||||
}
|
||||
else {
|
||||
// default action for all cases without special treatment:
|
||||
unitString = quant.getUnit().getString();
|
||||
factor = 1.0;
|
||||
}
|
||||
|
||||
return toLocale(quant, factor, unitString);
|
||||
}
|
||||
|
||||
std::string UnitsSchemaImperialBuilding::schemaTranslate(const Quantity& quant,
|
||||
double& factor,
|
||||
std::string& unitString)
|
||||
{
|
||||
// this schema expresses distances in feet + inches + fractions
|
||||
// ex: 3'- 4 1/4" with proper rounding
|
||||
Unit unit = quant.getUnit();
|
||||
if (unit == Unit::Length) {
|
||||
unitString = "in";
|
||||
factor = 25.4;
|
||||
|
||||
// Total number of inches to format
|
||||
double totalInches = std::abs(quant.getValue()) / factor;
|
||||
|
||||
// minimum denominator (8 for 1/8, 16 for 1/16, etc)
|
||||
int minden {};
|
||||
|
||||
// Outputs
|
||||
int feet {}; // whole feet
|
||||
int inches {}; // whole inches
|
||||
int num {}, den {}; // numerator and denominator of fractional val
|
||||
std::stringstream output; // output stream
|
||||
|
||||
// Intermediate values
|
||||
int ntot {}; // total fractional units
|
||||
int a {}, b {}, d {}; // used to compute greatest common denominator
|
||||
int tmp {}; // temporary variable for GCD
|
||||
|
||||
// Get the current user specified minimum denominator
|
||||
minden = quant.getFormat().getDenominator();
|
||||
|
||||
// Compute and round the total number of fractional units
|
||||
ntot = static_cast<int>(std::round(totalInches * static_cast<double>(minden)));
|
||||
|
||||
// If this is zero, nothing to do but return
|
||||
if (ntot == 0) {
|
||||
return "0";
|
||||
}
|
||||
|
||||
// Compute the whole number of feet and remaining units
|
||||
feet = static_cast<int>(std::floor(ntot / (12 * minden)));
|
||||
ntot = ntot - 12 * minden * feet;
|
||||
|
||||
// Compute the remaining number of whole inches
|
||||
inches = static_cast<int>(std::floor(ntot / minden));
|
||||
|
||||
// Lastly the fractional quantities
|
||||
num = ntot - inches * minden;
|
||||
den = minden;
|
||||
|
||||
// If numerator is not zero, compute greatest common divisor and reduce
|
||||
// fraction
|
||||
if (num != 0) {
|
||||
// initialize
|
||||
a = num;
|
||||
b = den;
|
||||
while (b != 0) {
|
||||
tmp = a % b;
|
||||
|
||||
a = b;
|
||||
b = tmp;
|
||||
}
|
||||
d = a;
|
||||
|
||||
num /= d;
|
||||
den /= d;
|
||||
}
|
||||
|
||||
// Process into string. Start with negative sign if quantity is less
|
||||
// than zero
|
||||
char plusOrMinus {};
|
||||
if (quant.getValue() < 0) {
|
||||
output << "-";
|
||||
plusOrMinus = '-';
|
||||
}
|
||||
else {
|
||||
plusOrMinus = '+';
|
||||
}
|
||||
|
||||
bool trailingNumber = false;
|
||||
// Print feet if we have any
|
||||
if (feet != 0) {
|
||||
output << feet << "'";
|
||||
trailingNumber = true;
|
||||
}
|
||||
// Print whole inches if we have any
|
||||
if (inches != 0) {
|
||||
if (trailingNumber) {
|
||||
output << " ";
|
||||
}
|
||||
output << inches << "\"";
|
||||
trailingNumber = true;
|
||||
}
|
||||
// Print fractional inches if we have any
|
||||
if (num != 0) {
|
||||
if (trailingNumber) {
|
||||
output << " " << plusOrMinus << " ";
|
||||
}
|
||||
output << num << "/" << den << "\"";
|
||||
}
|
||||
|
||||
// Done!
|
||||
return output.str();
|
||||
}
|
||||
else if (unit == Unit::Angle) {
|
||||
unitString = "\xC2\xB0";
|
||||
factor = 1.0;
|
||||
}
|
||||
else if (unit == Unit::Area) {
|
||||
unitString = "sqft";
|
||||
factor = 92903.04;
|
||||
}
|
||||
else if (unit == Unit::Volume) {
|
||||
unitString = "cft";
|
||||
factor = 28316846.592;
|
||||
}
|
||||
else if (unit == Unit::Velocity) {
|
||||
unitString = "in/min";
|
||||
factor = 25.4 / 60;
|
||||
}
|
||||
else {
|
||||
unitString = quant.getUnit().getString();
|
||||
factor = 1.0;
|
||||
}
|
||||
|
||||
return toLocale(quant, factor, unitString);
|
||||
}
|
||||
|
||||
std::string UnitsSchemaImperialCivil::schemaTranslate(const Base::Quantity& quant,
|
||||
double& factor,
|
||||
std::string& unitString)
|
||||
{
|
||||
Unit unit = quant.getUnit();
|
||||
// for imperial user/programmer mind; UnitValue is in internal system, that means
|
||||
// mm/kg/s. And all combined units have to be calculated from there!
|
||||
|
||||
// now do special treatment on all cases seems necessary:
|
||||
if (unit == Unit::Length) { // Length handling ============================
|
||||
unitString = "ft"; // always ft
|
||||
factor = 304.8; // 12 * 25.4
|
||||
}
|
||||
else if (unit == Unit::Area) {
|
||||
unitString = "ft^2"; // always sq.ft
|
||||
factor = 92903.04;
|
||||
}
|
||||
else if (unit == Unit::Volume) {
|
||||
unitString = "ft^3"; // always cu. ft
|
||||
factor = 28316846.592;
|
||||
}
|
||||
else if (unit == Unit::Mass) {
|
||||
unitString = "lb"; // always lbs.
|
||||
factor = 0.45359237;
|
||||
}
|
||||
else if (unit == Unit::Pressure) {
|
||||
unitString = "psi";
|
||||
factor = 6.894744825494;
|
||||
}
|
||||
else if (unit == Unit::Stiffness) {
|
||||
unitString = "lbf/in";
|
||||
factor = 4.448222 / 0.0254;
|
||||
}
|
||||
else if (unit == Unit::Velocity) {
|
||||
unitString = "mph";
|
||||
factor = 447.04; // 1mm/sec => mph
|
||||
}
|
||||
// this schema expresses angles in degrees + minutes + seconds
|
||||
else if (unit == Unit::Angle) {
|
||||
unitString = "deg";
|
||||
std::string degreeString = "\xC2\xB0"; // degree symbol
|
||||
std::string minuteString = "\xE2\x80\xB2"; // prime symbol
|
||||
std::string secondString = "\xE2\x80\xB3"; // double prime symbol
|
||||
factor = 1.0; // 1deg = 1"\xC2\xB0 "
|
||||
|
||||
double totalDegrees = quant.getValue() / factor;
|
||||
double wholeDegrees = std::floor(totalDegrees);
|
||||
double sumMinutes = totalDegrees * 60.0; // quant as minutes
|
||||
double rawMinutes = sumMinutes - wholeDegrees * 60.0;
|
||||
double wholeMinutes = std::floor(rawMinutes);
|
||||
double sumSeconds = totalDegrees * 3600.0; // quant as seconds
|
||||
double rawSeconds = sumSeconds - (wholeDegrees * 3600.0) - (wholeMinutes * 60);
|
||||
|
||||
int outDeg = static_cast<int>(wholeDegrees);
|
||||
int outMin = static_cast<int>(wholeMinutes);
|
||||
int outSec = static_cast<int>(std::round(rawSeconds));
|
||||
|
||||
std::stringstream output;
|
||||
output << outDeg << degreeString;
|
||||
if ((outMin > 0) || (outSec > 0)) {
|
||||
output << outMin << minuteString;
|
||||
}
|
||||
if (outSec > 0) {
|
||||
output << outSec << secondString;
|
||||
}
|
||||
// uncomment this for decimals on seconds
|
||||
// if (remainSeconds < (1.0 * pow(10.0,-Base::UnitsApi::getDecimals())) ) {
|
||||
// //NOP too small to display
|
||||
// } else {
|
||||
// output << std::setprecision(Base::UnitsApi::getDecimals()) << std::fixed <<
|
||||
// rawSeconds << secondString.toStdString();
|
||||
// }
|
||||
return output.str();
|
||||
}
|
||||
else {
|
||||
// default action for all cases without special treatment:
|
||||
unitString = quant.getUnit().getString();
|
||||
factor = 1.0;
|
||||
}
|
||||
|
||||
return toLocale(quant, factor, unitString);
|
||||
}
|
||||
@@ -1,105 +0,0 @@
|
||||
/***************************************************************************
|
||||
* Copyright (c) 2009 Jürgen Riegel <FreeCAD@juergen-riegel.net> *
|
||||
* *
|
||||
* This file is part of the FreeCAD CAx development system. *
|
||||
* *
|
||||
* This library is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU Library General Public *
|
||||
* License as published by the Free Software Foundation; either *
|
||||
* version 2 of the License, or (at your option) any later version. *
|
||||
* *
|
||||
* This library is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU Library General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU Library General Public *
|
||||
* License along with this library; see the file COPYING.LIB. If not, *
|
||||
* write to the Free Software Foundation, Inc., 59 Temple Place, *
|
||||
* Suite 330, Boston, MA 02111-1307, USA *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef BASE_UNITSSCHEMAIMPERIAL1_H
|
||||
#define BASE_UNITSSCHEMAIMPERIAL1_H
|
||||
|
||||
#include "UnitsSchema.h"
|
||||
|
||||
namespace Base
|
||||
{
|
||||
|
||||
/** The schema class for the imperial unit system
|
||||
* Here are the definitions for the imperial unit system.
|
||||
* It also defines how the value/units get printed.
|
||||
*/
|
||||
class UnitsSchemaImperial1: public UnitsSchema
|
||||
{
|
||||
public:
|
||||
std::string
|
||||
schemaTranslate(const Base::Quantity& quant, double& factor, std::string& unitString) override;
|
||||
std::string getBasicLengthUnit() const override
|
||||
{
|
||||
return {"in"};
|
||||
}
|
||||
};
|
||||
|
||||
/** The schema class for the imperial unit system
|
||||
* Here are the definitions for the imperial unit system.
|
||||
* It also defines how the value/units get printed.
|
||||
*/
|
||||
class UnitsSchemaImperialDecimal: public UnitsSchema
|
||||
{
|
||||
public:
|
||||
std::string
|
||||
schemaTranslate(const Base::Quantity& quant, double& factor, std::string& unitString) override;
|
||||
std::string getBasicLengthUnit() const override
|
||||
{
|
||||
return {"in"};
|
||||
}
|
||||
};
|
||||
|
||||
/** The schema class for the imperial unit system
|
||||
* Here are the definitions for the imperial unit system.
|
||||
* It also defines how the value/units get printed.
|
||||
*/
|
||||
class UnitsSchemaImperialBuilding: public UnitsSchema
|
||||
{
|
||||
public:
|
||||
std::string
|
||||
schemaTranslate(const Base::Quantity& quant, double& factor, std::string& unitString) override;
|
||||
std::string getBasicLengthUnit() const override
|
||||
{
|
||||
return {"ft"};
|
||||
}
|
||||
|
||||
// return true if this schema uses multiple units for length (ex. Ft/In)
|
||||
bool isMultiUnitLength() const override
|
||||
{
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
/** The schema class for Civil Engineering in the imperial unit system
|
||||
* All measurements in ft, ft^2, ft^3, ft/sec.
|
||||
* Pressure is in psi.
|
||||
*/
|
||||
class UnitsSchemaImperialCivil: public UnitsSchema
|
||||
{
|
||||
public:
|
||||
std::string
|
||||
schemaTranslate(const Base::Quantity& quant, double& factor, std::string& unitString) override;
|
||||
std::string getBasicLengthUnit() const override
|
||||
{
|
||||
return {"ft"};
|
||||
}
|
||||
|
||||
// return true if this schema uses multiple units for angles (ex. DMS)
|
||||
bool isMultiUnitAngle() const override
|
||||
{
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace Base
|
||||
|
||||
#endif // BASE_UNITSSCHEMAIMPERIAL1_H
|
||||
@@ -1,671 +0,0 @@
|
||||
/***************************************************************************
|
||||
* Copyright (c) 2009 Jürgen Riegel <FreeCAD@juergen-riegel.net> *
|
||||
* *
|
||||
* This file is part of the FreeCAD CAx development system. *
|
||||
* *
|
||||
* This library is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU Library General Public *
|
||||
* License as published by the Free Software Foundation; either *
|
||||
* version 2 of the License, or (at your option) any later version. *
|
||||
* *
|
||||
* This library is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU Library General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU Library General Public *
|
||||
* License along with this library; see the file COPYING.LIB. If not, *
|
||||
* write to the Free Software Foundation, Inc., 59 Temple Place, *
|
||||
* Suite 330, Boston, MA 02111-1307, USA *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
|
||||
#include "PreCompiled.h"
|
||||
#ifndef _PreComp_
|
||||
#include <cmath>
|
||||
#endif
|
||||
#ifdef __GNUC__
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
|
||||
#include "Quantity.h"
|
||||
#include "Unit.h"
|
||||
#include "UnitsSchemaInternal.h"
|
||||
|
||||
using namespace Base;
|
||||
|
||||
std::string
|
||||
UnitsSchemaInternal::schemaTranslate(const Quantity& quant, double& factor, std::string& unitString)
|
||||
{
|
||||
double UnitValue = std::abs(quant.getValue());
|
||||
Unit unit = quant.getUnit();
|
||||
|
||||
// In order to get the right factor always express the target
|
||||
// units as internal units where length is in mm and mass in kg
|
||||
// Example:
|
||||
// For W/mm/K we get the factor of 1000000.0 because
|
||||
// W/mm/K = kg*m^2/s^3/mm/K
|
||||
// = 10e6 * kg*mm^2/s^3/mm/K
|
||||
// = 10e6 * kg*mm/s^3/K
|
||||
|
||||
// now do special treatment on all cases seems necessary:
|
||||
if (unit == Unit::Length) { // Length handling ============================
|
||||
if (UnitValue < 1e-6) { // smaller than 0.001 nm -> scientific notation
|
||||
unitString = "mm";
|
||||
factor = 1.0;
|
||||
}
|
||||
else if (UnitValue < 1e-3) {
|
||||
unitString = "nm";
|
||||
factor = 1e-6;
|
||||
}
|
||||
else if (UnitValue < 0.1) {
|
||||
unitString = "\xC2\xB5m";
|
||||
factor = 1e-3;
|
||||
}
|
||||
else if (UnitValue < 1e4) {
|
||||
unitString = "mm";
|
||||
factor = 1.0;
|
||||
}
|
||||
else if (UnitValue < 1e7) {
|
||||
unitString = "m";
|
||||
factor = 1e3;
|
||||
}
|
||||
else if (UnitValue < 1e10) {
|
||||
unitString = "km";
|
||||
factor = 1e6;
|
||||
}
|
||||
else { // bigger than 1000 km -> scientific notation
|
||||
unitString = "m";
|
||||
factor = 1e3;
|
||||
}
|
||||
}
|
||||
else if (unit == Unit::Area) {
|
||||
if (UnitValue < 100) {
|
||||
unitString = "mm^2";
|
||||
factor = 1.0;
|
||||
}
|
||||
else if (UnitValue < 1e6) {
|
||||
unitString = "cm^2";
|
||||
factor = 100;
|
||||
}
|
||||
else if (UnitValue < 1e12) {
|
||||
unitString = "m^2";
|
||||
factor = 1e6;
|
||||
}
|
||||
else { // bigger than 1 square kilometer
|
||||
unitString = "km^2";
|
||||
factor = 1e12;
|
||||
}
|
||||
}
|
||||
else if (unit == Unit::Volume) {
|
||||
if (UnitValue < 1e3) { // smaller than 1 ul
|
||||
unitString = "mm^3";
|
||||
factor = 1.0;
|
||||
}
|
||||
else if (UnitValue < 1e6) {
|
||||
unitString = "ml";
|
||||
factor = 1e3;
|
||||
}
|
||||
else if (UnitValue < 1e9) {
|
||||
unitString = "l";
|
||||
factor = 1e6;
|
||||
}
|
||||
else { // bigger than 1000 l
|
||||
unitString = "m^3";
|
||||
factor = 1e9;
|
||||
}
|
||||
}
|
||||
else if (unit == Unit::Angle) {
|
||||
// TODO: Cascade for the Areas
|
||||
// default action for all cases without special treatment:
|
||||
unitString = "\xC2\xB0";
|
||||
factor = 1.0;
|
||||
}
|
||||
else if (unit == Unit::Mass) {
|
||||
if (UnitValue < 1e-6) {
|
||||
unitString = "\xC2\xB5g";
|
||||
factor = 1e-9;
|
||||
}
|
||||
else if (UnitValue < 1e-3) {
|
||||
unitString = "mg";
|
||||
factor = 1e-6;
|
||||
}
|
||||
else if (UnitValue < 1.0) {
|
||||
unitString = "g";
|
||||
factor = 1e-3;
|
||||
}
|
||||
else if (UnitValue < 1e3) {
|
||||
unitString = "kg";
|
||||
factor = 1.0;
|
||||
}
|
||||
else {
|
||||
unitString = "t";
|
||||
factor = 1e3;
|
||||
}
|
||||
}
|
||||
else if (unit == Unit::Density) {
|
||||
if (UnitValue < 0.0001) {
|
||||
unitString = "kg/m^3";
|
||||
factor = 1e-9;
|
||||
}
|
||||
else if (UnitValue < 1.0) {
|
||||
unitString = "kg/cm^3";
|
||||
factor = 0.001;
|
||||
}
|
||||
else {
|
||||
unitString = "kg/mm^3";
|
||||
factor = 1.0;
|
||||
}
|
||||
}
|
||||
else if (unit == Unit::ThermalConductivity) {
|
||||
if (UnitValue > 1e6) {
|
||||
unitString = "W/mm/K";
|
||||
factor = 1e6;
|
||||
}
|
||||
else {
|
||||
unitString = "W/m/K";
|
||||
factor = 1000.0;
|
||||
}
|
||||
}
|
||||
else if (unit == Unit::ThermalExpansionCoefficient) {
|
||||
if (UnitValue < 0.001) {
|
||||
unitString = "\xC2\xB5m/m/K"; // micro-meter/meter/K
|
||||
factor = 1e-6;
|
||||
}
|
||||
else {
|
||||
unitString = "mm/mm/K";
|
||||
factor = 1.0;
|
||||
}
|
||||
}
|
||||
else if (unit == Unit::VolumetricThermalExpansionCoefficient) {
|
||||
if (UnitValue < 0.001) {
|
||||
unitString = "mm^3/m^3/K";
|
||||
factor = 1e-9;
|
||||
}
|
||||
else {
|
||||
unitString = "m^3/m^3/K";
|
||||
factor = 1.0;
|
||||
}
|
||||
}
|
||||
else if (unit == Unit::SpecificHeat) {
|
||||
unitString = "J/kg/K";
|
||||
factor = 1e6;
|
||||
}
|
||||
else if (unit == Unit::ThermalTransferCoefficient) {
|
||||
unitString = "W/m^2/K";
|
||||
factor = 1.0;
|
||||
}
|
||||
else if ((unit == Unit::Pressure) || (unit == Unit::Stress)) {
|
||||
if (UnitValue < 10.0) { // Pa is the smallest
|
||||
unitString = "Pa";
|
||||
factor = 0.001;
|
||||
}
|
||||
else if (UnitValue < 10000.0) {
|
||||
unitString = "kPa";
|
||||
factor = 1.0;
|
||||
}
|
||||
else if (UnitValue < 10000000.0) {
|
||||
unitString = "MPa";
|
||||
factor = 1000.0;
|
||||
}
|
||||
else if (UnitValue < 10000000000.0) {
|
||||
unitString = "GPa";
|
||||
factor = 1e6;
|
||||
}
|
||||
else { // bigger -> scientific notation
|
||||
unitString = "Pa";
|
||||
factor = 0.001;
|
||||
}
|
||||
}
|
||||
else if ((unit == Unit::Stiffness)) {
|
||||
if (UnitValue < 1) { // mN/m is the smallest
|
||||
unitString = "mN/m";
|
||||
factor = 1e-3;
|
||||
}
|
||||
else if (UnitValue < 1e3) {
|
||||
unitString = "N/m";
|
||||
factor = 1.0;
|
||||
}
|
||||
else if (UnitValue < 1e6) {
|
||||
unitString = "kN/m";
|
||||
factor = 1e3;
|
||||
}
|
||||
else {
|
||||
unitString = "MN/m";
|
||||
factor = 1e6;
|
||||
}
|
||||
}
|
||||
else if ((unit == Unit::StiffnessDensity)) {
|
||||
if (UnitValue < 1e-3) {
|
||||
unitString = "Pa/m";
|
||||
factor = 1e-6;
|
||||
}
|
||||
else if (UnitValue < 1) {
|
||||
unitString = "kPa/m";
|
||||
factor = 1e-3;
|
||||
}
|
||||
else if (UnitValue < 1e3) {
|
||||
unitString = "MPa/m";
|
||||
factor = 1.0;
|
||||
}
|
||||
else {
|
||||
unitString = "GPa/m";
|
||||
factor = 1e3;
|
||||
}
|
||||
}
|
||||
else if (unit == Unit::Force) {
|
||||
if (UnitValue < 1e3) {
|
||||
unitString = "mN";
|
||||
factor = 1.0;
|
||||
}
|
||||
else if (UnitValue < 1e6) {
|
||||
unitString = "N";
|
||||
factor = 1e3;
|
||||
}
|
||||
else if (UnitValue < 1e9) {
|
||||
unitString = "kN";
|
||||
factor = 1e6;
|
||||
}
|
||||
else {
|
||||
unitString = "MN";
|
||||
factor = 1e9;
|
||||
}
|
||||
}
|
||||
// else if (unit == Unit::Moment) {
|
||||
// if (UnitValue < 1e6) {
|
||||
// unitString = "mNm";
|
||||
// factor = 1e3;
|
||||
// }
|
||||
// else if (UnitValue < 1e9) {
|
||||
// unitString = "Nm";
|
||||
// factor = 1e6;
|
||||
// }
|
||||
// else if (UnitValue < 1e12) {
|
||||
// unitString = "kNm";
|
||||
// factor = 1e9;
|
||||
// }
|
||||
// else {
|
||||
// unitString = "MNm";
|
||||
// factor = 1e12;
|
||||
// }
|
||||
// }
|
||||
else if (unit == Unit::Power) {
|
||||
if (UnitValue < 1e6) {
|
||||
unitString = "mW";
|
||||
factor = 1e3;
|
||||
}
|
||||
else if (UnitValue < 1e9) {
|
||||
unitString = "W";
|
||||
factor = 1e6;
|
||||
}
|
||||
else {
|
||||
unitString = "kW";
|
||||
factor = 1e9;
|
||||
}
|
||||
}
|
||||
else if (unit == Unit::ElectricPotential) {
|
||||
if (UnitValue < 1e6) {
|
||||
unitString = "mV";
|
||||
factor = 1e3;
|
||||
}
|
||||
else if (UnitValue < 1e9) {
|
||||
unitString = "V";
|
||||
factor = 1e6;
|
||||
}
|
||||
else if (UnitValue < 1e12) {
|
||||
unitString = "kV";
|
||||
factor = 1e9;
|
||||
}
|
||||
else { // > 1000 kV scientificc notation
|
||||
unitString = "V";
|
||||
factor = 1e6;
|
||||
}
|
||||
}
|
||||
else if (unit == Unit::Work) {
|
||||
if (UnitValue < 1.602176634e-10) {
|
||||
unitString = "eV";
|
||||
factor = 1.602176634e-13;
|
||||
}
|
||||
else if (UnitValue < 1.602176634e-7) {
|
||||
unitString = "keV";
|
||||
factor = 1.602176634e-10;
|
||||
}
|
||||
else if (UnitValue < 1.602176634e-4) {
|
||||
unitString = "MeV";
|
||||
factor = 1.602176634e-7;
|
||||
}
|
||||
else if (UnitValue < 1e6) {
|
||||
unitString = "mJ";
|
||||
factor = 1e3;
|
||||
}
|
||||
else if (UnitValue < 1e9) {
|
||||
unitString = "J";
|
||||
factor = 1e6;
|
||||
}
|
||||
else if (UnitValue < 1e12) {
|
||||
unitString = "kJ";
|
||||
factor = 1e9;
|
||||
}
|
||||
else if (UnitValue < 3.6e+15) {
|
||||
unitString = "kWh";
|
||||
factor = 3.6e+12;
|
||||
}
|
||||
else { // bigger than 1000 kWh -> scientific notation
|
||||
unitString = "J";
|
||||
factor = 1e6;
|
||||
}
|
||||
}
|
||||
else if (unit == Unit::SpecificEnergy) {
|
||||
unitString = "m^2/s^2";
|
||||
factor = 1e6;
|
||||
}
|
||||
else if (unit == Unit::HeatFlux) {
|
||||
unitString = "W/m^2";
|
||||
factor = 1; // unit signature (0,1,-3,0,0) is length independent
|
||||
}
|
||||
else if (unit == Unit::ElectricCharge) {
|
||||
unitString = "C";
|
||||
factor = 1.0;
|
||||
}
|
||||
else if (unit == Unit::SurfaceChargeDensity) {
|
||||
if (UnitValue <= 1e-4) {
|
||||
unitString = "C/m^2";
|
||||
factor = 1e-6;
|
||||
}
|
||||
else if (UnitValue <= 1e-2) {
|
||||
unitString = "C/cm^2";
|
||||
factor = 1e-2;
|
||||
}
|
||||
else {
|
||||
unitString = "C/mm^2";
|
||||
factor = 1;
|
||||
}
|
||||
}
|
||||
else if (unit == Unit::VolumeChargeDensity) {
|
||||
if (UnitValue <= 1e-4) {
|
||||
unitString = "C/m^3";
|
||||
factor = 1e-9;
|
||||
}
|
||||
else if (UnitValue <= 1e-2) {
|
||||
unitString = "C/cm^3";
|
||||
factor = 1e-3;
|
||||
}
|
||||
else {
|
||||
unitString = "C/mm^3";
|
||||
factor = 1;
|
||||
}
|
||||
}
|
||||
else if (unit == Unit::CurrentDensity) {
|
||||
if (UnitValue <= 1e-4) {
|
||||
unitString = "A/m^2";
|
||||
factor = 1e-6;
|
||||
}
|
||||
else if (UnitValue <= 1e-2) {
|
||||
unitString = "A/cm^2";
|
||||
factor = 1e-2;
|
||||
}
|
||||
else {
|
||||
unitString = "A/mm^2";
|
||||
factor = 1;
|
||||
}
|
||||
}
|
||||
else if (unit == Unit::MagneticFluxDensity) {
|
||||
if (UnitValue <= 1e-3) {
|
||||
unitString = "G";
|
||||
factor = 1e-4;
|
||||
}
|
||||
else {
|
||||
unitString = "T";
|
||||
factor = 1.0;
|
||||
}
|
||||
}
|
||||
else if (unit == Unit::MagneticFieldStrength) {
|
||||
unitString = "A/m";
|
||||
factor = 1e-3;
|
||||
}
|
||||
else if (unit == Unit::MagneticFlux) {
|
||||
unitString = "Wb";
|
||||
factor = 1e6;
|
||||
}
|
||||
else if (unit == Unit::Magnetization) {
|
||||
unitString = "A/m";
|
||||
factor = 1e-3;
|
||||
}
|
||||
else if (unit == Unit::ElectromagneticPotential) {
|
||||
unitString = "Wb/m";
|
||||
factor = 1e3;
|
||||
}
|
||||
else if (unit == Unit::ElectricalConductance) {
|
||||
if (UnitValue < 1e-9) {
|
||||
unitString = "\xC2\xB5S";
|
||||
factor = 1e-12;
|
||||
}
|
||||
else if (UnitValue < 1e-6) {
|
||||
unitString = "mS";
|
||||
factor = 1e-9;
|
||||
}
|
||||
else {
|
||||
unitString = "S";
|
||||
factor = 1e-6;
|
||||
}
|
||||
}
|
||||
else if (unit == Unit::ElectricalResistance) {
|
||||
if (UnitValue < 1e9) {
|
||||
unitString = "Ohm";
|
||||
factor = 1e6;
|
||||
}
|
||||
else if (UnitValue < 1e12) {
|
||||
unitString = "kOhm";
|
||||
factor = 1e9;
|
||||
}
|
||||
else {
|
||||
unitString = "MOhm";
|
||||
factor = 1e12;
|
||||
}
|
||||
}
|
||||
else if (unit == Unit::ElectricalConductivity) {
|
||||
if (UnitValue < 1e-3) {
|
||||
unitString = "mS/m";
|
||||
factor = 1e-12;
|
||||
}
|
||||
else if (UnitValue < 1.0) {
|
||||
unitString = "S/m";
|
||||
factor = 1e-9;
|
||||
}
|
||||
else if (UnitValue < 1e3) {
|
||||
unitString = "kS/m";
|
||||
factor = 1e-6;
|
||||
}
|
||||
else {
|
||||
unitString = "MS/m";
|
||||
factor = 1e-3;
|
||||
}
|
||||
}
|
||||
else if (unit == Unit::ElectricalCapacitance) {
|
||||
if (UnitValue < 1e-15) {
|
||||
unitString = "pF";
|
||||
factor = 1e-18;
|
||||
}
|
||||
else if (UnitValue < 1e-12) {
|
||||
unitString = "nF";
|
||||
factor = 1e-15;
|
||||
}
|
||||
else if (UnitValue < 1e-9) {
|
||||
// \x reads everything to the end, therefore split
|
||||
unitString = "\xC2\xB5"
|
||||
"F";
|
||||
factor = 1e-12;
|
||||
}
|
||||
else if (UnitValue < 1e-6) {
|
||||
unitString = "mF";
|
||||
factor = 1e-9;
|
||||
}
|
||||
else {
|
||||
unitString = "F";
|
||||
factor = 1e-6;
|
||||
}
|
||||
}
|
||||
else if (unit == Unit::ElectricalInductance) {
|
||||
if (UnitValue < 1.0) {
|
||||
unitString = "nH";
|
||||
factor = 1e-3;
|
||||
}
|
||||
else if (UnitValue < 1e3) {
|
||||
unitString = "\xC2\xB5H";
|
||||
factor = 1.0;
|
||||
}
|
||||
else if (UnitValue < 1e6) {
|
||||
unitString = "mH";
|
||||
factor = 1e3;
|
||||
}
|
||||
else {
|
||||
unitString = "H";
|
||||
factor = 1e6;
|
||||
}
|
||||
}
|
||||
else if (unit == Unit::VacuumPermittivity) {
|
||||
unitString = "F/m";
|
||||
factor = 1e-9;
|
||||
}
|
||||
else if (unit == Unit::Frequency) {
|
||||
if (UnitValue < 1e3) {
|
||||
unitString = "Hz";
|
||||
factor = 1.0;
|
||||
}
|
||||
else if (UnitValue < 1e6) {
|
||||
unitString = "kHz";
|
||||
factor = 1e3;
|
||||
}
|
||||
else if (UnitValue < 1e9) {
|
||||
unitString = "MHz";
|
||||
factor = 1e6;
|
||||
}
|
||||
else if (UnitValue < 1e12) {
|
||||
unitString = "GHz";
|
||||
factor = 1e9;
|
||||
}
|
||||
else {
|
||||
unitString = "THz";
|
||||
factor = 1e12;
|
||||
}
|
||||
}
|
||||
else if (unit == Unit::Velocity) {
|
||||
unitString = "mm/s";
|
||||
factor = 1.0;
|
||||
}
|
||||
else if (unit == Unit::DynamicViscosity) {
|
||||
unitString = "Pa*s";
|
||||
factor = 0.001;
|
||||
}
|
||||
else if (unit == Unit::KinematicViscosity) {
|
||||
if (UnitValue < 1e3) {
|
||||
unitString = "mm^2/s";
|
||||
factor = 1.0;
|
||||
}
|
||||
else {
|
||||
unitString = "m^2/s";
|
||||
factor = 1e6;
|
||||
}
|
||||
}
|
||||
else if (unit == Unit::VolumeFlowRate) {
|
||||
if (UnitValue < 1e3) {
|
||||
unitString = "mm^3/s";
|
||||
factor = 1.0;
|
||||
}
|
||||
else if (UnitValue < 1e6) {
|
||||
unitString = "ml/s";
|
||||
factor = 1e3;
|
||||
}
|
||||
else if (UnitValue < 1e9) {
|
||||
unitString = "l/s";
|
||||
factor = 1e6;
|
||||
}
|
||||
else {
|
||||
unitString = "m^3/s";
|
||||
factor = 1e9;
|
||||
}
|
||||
}
|
||||
else if (unit == Unit::DissipationRate) {
|
||||
unitString = "W/kg";
|
||||
factor = 1e6;
|
||||
}
|
||||
else if (unit == Unit::InverseLength) {
|
||||
if (UnitValue < 1e-6) { // smaller than 0.001 1/km -> scientific notation
|
||||
unitString = "1/m";
|
||||
factor = 1e-3;
|
||||
}
|
||||
else if (UnitValue < 1e-3) {
|
||||
unitString = "1/km";
|
||||
factor = 1e-6;
|
||||
}
|
||||
else if (UnitValue < 1.0) {
|
||||
unitString = "1/m";
|
||||
factor = 1e-3;
|
||||
}
|
||||
else if (UnitValue < 1e3) {
|
||||
unitString = "1/mm";
|
||||
factor = 1.0;
|
||||
}
|
||||
else if (UnitValue < 1e6) {
|
||||
unitString = "1/\xC2\xB5m";
|
||||
factor = 1e3;
|
||||
}
|
||||
else if (UnitValue < 1e9) {
|
||||
unitString = "1/nm";
|
||||
factor = 1e6;
|
||||
}
|
||||
else { // larger -> scientific notation
|
||||
unitString = "1/m";
|
||||
factor = 1e-3;
|
||||
}
|
||||
}
|
||||
else if (unit == Unit::InverseArea) {
|
||||
if (UnitValue < 1e-12) { // smaller than 0.001 1/km^2 -> scientific notation
|
||||
unitString = "1/m^2";
|
||||
factor = 1e-6;
|
||||
}
|
||||
else if (UnitValue < 1e-6) {
|
||||
unitString = "1/km^2";
|
||||
factor = 1e-12;
|
||||
}
|
||||
else if (UnitValue < 1.0) {
|
||||
unitString = "1/m^2";
|
||||
factor = 1e-6;
|
||||
}
|
||||
else if (UnitValue < 1e2) {
|
||||
unitString = "1/cm^2";
|
||||
factor = 1e-2;
|
||||
}
|
||||
else {
|
||||
unitString = "1/mm^2";
|
||||
factor = 1.0;
|
||||
}
|
||||
}
|
||||
else if (unit == Unit::InverseVolume) {
|
||||
if (UnitValue < 1e-6) {
|
||||
unitString = "1/m^3";
|
||||
factor = 1e-9;
|
||||
}
|
||||
else if (UnitValue < 1e-3) {
|
||||
unitString = "1/l";
|
||||
factor = 1e-6;
|
||||
}
|
||||
else if (UnitValue < 1.0) {
|
||||
unitString = "1/ml";
|
||||
factor = 1e-3;
|
||||
}
|
||||
else {
|
||||
unitString = "1/mm^3";
|
||||
factor = 1.0;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// default action for all cases without special treatment:
|
||||
unitString = quant.getUnit().getString();
|
||||
factor = 1.0;
|
||||
}
|
||||
|
||||
return toLocale(quant, factor, unitString);
|
||||
}
|
||||
@@ -1,45 +0,0 @@
|
||||
/***************************************************************************
|
||||
* Copyright (c) 2009 Jürgen Riegel <FreeCAD@juergen-riegel.net> *
|
||||
* *
|
||||
* This file is part of the FreeCAD CAx development system. *
|
||||
* *
|
||||
* This library is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU Library General Public *
|
||||
* License as published by the Free Software Foundation; either *
|
||||
* version 2 of the License, or (at your option) any later version. *
|
||||
* *
|
||||
* This library is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU Library General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU Library General Public *
|
||||
* License along with this library; see the file COPYING.LIB. If not, *
|
||||
* write to the Free Software Foundation, Inc., 59 Temple Place, *
|
||||
* Suite 330, Boston, MA 02111-1307, USA *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef BASE_UNITSSCHEMAINTERNAL_H
|
||||
#define BASE_UNITSSCHEMAINTERNAL_H
|
||||
|
||||
#include "UnitsSchema.h"
|
||||
|
||||
namespace Base
|
||||
{
|
||||
|
||||
/** The standard units schema
|
||||
* Here is defined what internal (base) units FreeCAD uses.
|
||||
* FreeCAD uses a mm/kg/deg scala.
|
||||
* Also it defines how the units get presented.
|
||||
*/
|
||||
class UnitsSchemaInternal: public UnitsSchema
|
||||
{
|
||||
public:
|
||||
std::string
|
||||
schemaTranslate(const Base::Quantity& quant, double& factor, std::string& unitString) override;
|
||||
};
|
||||
|
||||
} // namespace Base
|
||||
|
||||
#endif // BASE_UNITSSCHEMAINTERNAL_H
|
||||
@@ -1,634 +0,0 @@
|
||||
/***************************************************************************
|
||||
* Copyright (c) 2009 Jürgen Riegel <FreeCAD@juergen-riegel.net> *
|
||||
* *
|
||||
* This file is part of the FreeCAD CAx development system. *
|
||||
* *
|
||||
* This library is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU Library General Public *
|
||||
* License as published by the Free Software Foundation; either *
|
||||
* version 2 of the License, or (at your option) any later version. *
|
||||
* *
|
||||
* This library is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU Library General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU Library General Public *
|
||||
* License along with this library; see the file COPYING.LIB. If not, *
|
||||
* write to the Free Software Foundation, Inc., 59 Temple Place, *
|
||||
* Suite 330, Boston, MA 02111-1307, USA *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
|
||||
#include "PreCompiled.h"
|
||||
#ifndef _PreComp_
|
||||
#include <cmath>
|
||||
#endif
|
||||
#ifdef __GNUC__
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include "Quantity.h"
|
||||
#include "Unit.h"
|
||||
#include "UnitsSchemaMKS.h"
|
||||
|
||||
using namespace Base;
|
||||
|
||||
std::string
|
||||
UnitsSchemaMKS::schemaTranslate(const Quantity& quant, double& factor, std::string& unitString)
|
||||
{
|
||||
double UnitValue = std::abs(quant.getValue());
|
||||
Unit unit = quant.getUnit();
|
||||
|
||||
// now do special treatment on all cases seems necessary:
|
||||
if (unit == Unit::Length) { // Length handling ============================
|
||||
if (UnitValue < 1e-6) { // smaller than 0.001 nm -> scientific notation
|
||||
unitString = "mm";
|
||||
factor = 1.0;
|
||||
}
|
||||
else if (UnitValue < 1e-3) {
|
||||
unitString = "nm";
|
||||
factor = 1e-6;
|
||||
}
|
||||
else if (UnitValue < 0.1) {
|
||||
unitString = "\xC2\xB5m";
|
||||
factor = 1e-3;
|
||||
}
|
||||
else if (UnitValue < 1e4) {
|
||||
unitString = "mm";
|
||||
factor = 1.0;
|
||||
}
|
||||
else if (UnitValue < 1e7) {
|
||||
unitString = "m";
|
||||
factor = 1e3;
|
||||
}
|
||||
else if (UnitValue < 1e10) {
|
||||
unitString = "km";
|
||||
factor = 1e6;
|
||||
}
|
||||
else { // bigger than 1000 km -> scientific notation
|
||||
unitString = "m";
|
||||
factor = 1e3;
|
||||
}
|
||||
}
|
||||
else if (unit == Unit::Area) {
|
||||
if (UnitValue < 100) {
|
||||
unitString = "mm^2";
|
||||
factor = 1.0;
|
||||
}
|
||||
else if (UnitValue < 1e6) {
|
||||
unitString = "cm^2";
|
||||
factor = 100;
|
||||
}
|
||||
else if (UnitValue < 1e12) {
|
||||
unitString = "m^2";
|
||||
factor = 1e6;
|
||||
}
|
||||
else { // bigger than 1 square kilometer
|
||||
unitString = "km^2";
|
||||
factor = 1e12;
|
||||
}
|
||||
}
|
||||
else if (unit == Unit::Volume) {
|
||||
if (UnitValue < 1e3) { // smaller than 1 ul
|
||||
unitString = "mm^3";
|
||||
factor = 1.0;
|
||||
}
|
||||
else if (UnitValue < 1e6) {
|
||||
unitString = "ml";
|
||||
factor = 1e3;
|
||||
}
|
||||
else if (UnitValue < 1e9) {
|
||||
unitString = "l";
|
||||
factor = 1e6;
|
||||
}
|
||||
else { // bigger than 1000 l
|
||||
unitString = "m^3";
|
||||
factor = 1e9;
|
||||
}
|
||||
}
|
||||
else if (unit == Unit::Mass) {
|
||||
if (UnitValue < 1e-6) {
|
||||
unitString = "\xC2\xB5g";
|
||||
factor = 1e-9;
|
||||
}
|
||||
else if (UnitValue < 1e-3) {
|
||||
unitString = "mg";
|
||||
factor = 1e-6;
|
||||
}
|
||||
else if (UnitValue < 1.0) {
|
||||
unitString = "g";
|
||||
factor = 1e-3;
|
||||
}
|
||||
else if (UnitValue < 1e3) {
|
||||
unitString = "kg";
|
||||
factor = 1.0;
|
||||
}
|
||||
else {
|
||||
unitString = "t";
|
||||
factor = 1e3;
|
||||
}
|
||||
}
|
||||
else if (unit == Unit::Density) {
|
||||
if (UnitValue < 0.0001) {
|
||||
unitString = "kg/m^3";
|
||||
factor = 0.000000001;
|
||||
}
|
||||
else if (UnitValue < 1.0) {
|
||||
unitString = "kg/cm^3";
|
||||
factor = 0.001;
|
||||
}
|
||||
else {
|
||||
unitString = "kg/mm^3";
|
||||
factor = 1.0;
|
||||
}
|
||||
}
|
||||
else if (unit == Unit::Acceleration) {
|
||||
unitString = "m/s^2";
|
||||
factor = 1000.0;
|
||||
}
|
||||
else if ((unit == Unit::Pressure) || (unit == Unit::Stress)) {
|
||||
if (UnitValue < 10.0) { // Pa is the smallest
|
||||
unitString = "Pa";
|
||||
factor = 0.001;
|
||||
}
|
||||
else if (UnitValue < 10000.0) {
|
||||
unitString = "kPa";
|
||||
factor = 1.0;
|
||||
}
|
||||
else if (UnitValue < 10000000.0) {
|
||||
unitString = "MPa";
|
||||
factor = 1000.0;
|
||||
}
|
||||
else if (UnitValue < 10000000000.0) {
|
||||
unitString = "GPa";
|
||||
factor = 1000000.0;
|
||||
}
|
||||
else { // bigger then 1000 GPa -> scientific notation
|
||||
unitString = "Pa";
|
||||
factor = 0.001;
|
||||
}
|
||||
}
|
||||
else if ((unit == Unit::Stiffness)) {
|
||||
if (UnitValue < 1) { // mN/m is the smallest
|
||||
unitString = "mN/m";
|
||||
factor = 1e-3;
|
||||
}
|
||||
else if (UnitValue < 1e3) {
|
||||
unitString = "N/m";
|
||||
factor = 1.0;
|
||||
}
|
||||
else if (UnitValue < 1e6) {
|
||||
unitString = "kN/m";
|
||||
factor = 1e3;
|
||||
}
|
||||
else {
|
||||
unitString = "MN/m";
|
||||
factor = 1e6;
|
||||
}
|
||||
}
|
||||
else if ((unit == Unit::StiffnessDensity)) {
|
||||
if (UnitValue < 1e-3) {
|
||||
unitString = "Pa/m";
|
||||
factor = 1e-6;
|
||||
}
|
||||
else if (UnitValue < 1) {
|
||||
unitString = "kPa/m";
|
||||
factor = 1e-3;
|
||||
}
|
||||
else if (UnitValue < 1e3) {
|
||||
unitString = "MPa/m";
|
||||
factor = 1.0;
|
||||
}
|
||||
else {
|
||||
unitString = "GPa/m";
|
||||
factor = 1e3;
|
||||
}
|
||||
}
|
||||
else if (unit == Unit::ThermalConductivity) {
|
||||
if (UnitValue > 1000000) {
|
||||
unitString = "W/mm/K";
|
||||
factor = 1000000.0;
|
||||
}
|
||||
else {
|
||||
unitString = "W/m/K";
|
||||
factor = 1000.0;
|
||||
}
|
||||
}
|
||||
else if (unit == Unit::ThermalExpansionCoefficient) {
|
||||
if (UnitValue < 0.001) {
|
||||
unitString = "\xC2\xB5m/m/K";
|
||||
factor = 0.000001;
|
||||
}
|
||||
else {
|
||||
unitString = "m/m/K";
|
||||
factor = 1.0;
|
||||
}
|
||||
}
|
||||
else if (unit == Unit::VolumetricThermalExpansionCoefficient) {
|
||||
if (UnitValue < 0.001) {
|
||||
unitString = "mm^3/m^3/K";
|
||||
factor = 1e-9;
|
||||
}
|
||||
else {
|
||||
unitString = "m^3/m^3/K";
|
||||
factor = 1.0;
|
||||
}
|
||||
}
|
||||
else if (unit == Unit::SpecificHeat) {
|
||||
unitString = "J/kg/K";
|
||||
factor = 1000000.0;
|
||||
}
|
||||
else if (unit == Unit::ThermalTransferCoefficient) {
|
||||
unitString = "W/m^2/K";
|
||||
factor = 1.0;
|
||||
}
|
||||
else if (unit == Unit::Force) {
|
||||
if (UnitValue < 1e3) {
|
||||
unitString = "mN";
|
||||
factor = 1.0;
|
||||
}
|
||||
else if (UnitValue < 1e6) {
|
||||
unitString = "N";
|
||||
factor = 1e3;
|
||||
}
|
||||
else if (UnitValue < 1e9) {
|
||||
unitString = "kN";
|
||||
factor = 1e6;
|
||||
}
|
||||
else {
|
||||
unitString = "MN";
|
||||
factor = 1e9;
|
||||
}
|
||||
}
|
||||
// else if (unit == Unit::Moment) {
|
||||
// if (UnitValue < 1e6) {
|
||||
// unitString = "mNm";
|
||||
// factor = 1e3;
|
||||
// }
|
||||
// else if (UnitValue < 1e9) {
|
||||
// unitString = "Nm";
|
||||
// factor = 1e6;
|
||||
// }
|
||||
// else if (UnitValue < 1e12) {
|
||||
// unitString = "kNm";
|
||||
// factor = 1e9;
|
||||
// }
|
||||
// else {
|
||||
// unitString = "MNm";
|
||||
// factor = 1e12;
|
||||
// }
|
||||
// }
|
||||
else if (unit == Unit::Power) {
|
||||
if (UnitValue < 1e6) {
|
||||
unitString = "mW";
|
||||
factor = 1e3;
|
||||
}
|
||||
else if (UnitValue < 1e9) {
|
||||
unitString = "W";
|
||||
factor = 1e6;
|
||||
}
|
||||
else {
|
||||
unitString = "kW";
|
||||
factor = 1e9;
|
||||
}
|
||||
}
|
||||
else if (unit == Unit::ElectricPotential) {
|
||||
if (UnitValue < 1e6) {
|
||||
unitString = "mV";
|
||||
factor = 1e3;
|
||||
}
|
||||
else if (UnitValue < 1e9) {
|
||||
unitString = "V";
|
||||
factor = 1e6;
|
||||
}
|
||||
else if (UnitValue < 1e12) {
|
||||
unitString = "kV";
|
||||
factor = 1e9;
|
||||
}
|
||||
else { // > 1000 kV scientificc notation
|
||||
unitString = "V";
|
||||
factor = 1e6;
|
||||
}
|
||||
}
|
||||
else if (unit == Unit::ElectricCharge) {
|
||||
unitString = "C";
|
||||
factor = 1.0;
|
||||
}
|
||||
else if (unit == Unit::SurfaceChargeDensity) {
|
||||
unitString = "C/m^2";
|
||||
factor = 1e-6;
|
||||
}
|
||||
else if (unit == Unit::VolumeChargeDensity) {
|
||||
unitString = "C/m^3";
|
||||
factor = 1e-9;
|
||||
}
|
||||
else if (unit == Unit::CurrentDensity) {
|
||||
if (UnitValue <= 1e3) {
|
||||
unitString = "A/m^2";
|
||||
factor = 1e-6;
|
||||
}
|
||||
else {
|
||||
unitString = "A/mm^2";
|
||||
factor = 1;
|
||||
}
|
||||
}
|
||||
else if (unit == Unit::MagneticFluxDensity) {
|
||||
if (UnitValue <= 1e-3) {
|
||||
unitString = "G";
|
||||
factor = 1e-4;
|
||||
}
|
||||
else {
|
||||
unitString = "T";
|
||||
factor = 1.0;
|
||||
}
|
||||
}
|
||||
else if (unit == Unit::MagneticFieldStrength) {
|
||||
unitString = "A/m";
|
||||
factor = 1e-3;
|
||||
}
|
||||
else if (unit == Unit::MagneticFlux) {
|
||||
unitString = "Wb";
|
||||
factor = 1e6;
|
||||
}
|
||||
else if (unit == Unit::Magnetization) {
|
||||
unitString = "A/m";
|
||||
factor = 1e-3;
|
||||
}
|
||||
else if (unit == Unit::ElectromagneticPotential) {
|
||||
unitString = "Wb/m";
|
||||
factor = 1e3;
|
||||
}
|
||||
else if (unit == Unit::ElectricalConductance) {
|
||||
if (UnitValue < 1e-9) {
|
||||
unitString = "\xC2\xB5S";
|
||||
factor = 1e-12;
|
||||
}
|
||||
else if (UnitValue < 1e-6) {
|
||||
unitString = "mS";
|
||||
factor = 1e-9;
|
||||
}
|
||||
else {
|
||||
unitString = "S";
|
||||
factor = 1e-6;
|
||||
}
|
||||
}
|
||||
else if (unit == Unit::ElectricalResistance) {
|
||||
if (UnitValue < 1e9) {
|
||||
unitString = "Ohm";
|
||||
factor = 1e6;
|
||||
}
|
||||
else if (UnitValue < 1e12) {
|
||||
unitString = "kOhm";
|
||||
factor = 1e9;
|
||||
}
|
||||
else {
|
||||
unitString = "MOhm";
|
||||
factor = 1e12;
|
||||
}
|
||||
}
|
||||
else if (unit == Unit::ElectricalConductivity) {
|
||||
if (UnitValue < 1e-3) {
|
||||
unitString = "mS/m";
|
||||
factor = 1e-12;
|
||||
}
|
||||
else if (UnitValue < 1.0) {
|
||||
unitString = "S/m";
|
||||
factor = 1e-9;
|
||||
}
|
||||
else if (UnitValue < 1e3) {
|
||||
unitString = "kS/m";
|
||||
factor = 1e-6;
|
||||
}
|
||||
else {
|
||||
unitString = "MS/m";
|
||||
factor = 1e-3;
|
||||
}
|
||||
}
|
||||
else if (unit == Unit::ElectricalCapacitance) {
|
||||
if (UnitValue < 1e-15) {
|
||||
unitString = "pF";
|
||||
factor = 1e-18;
|
||||
}
|
||||
else if (UnitValue < 1e-12) {
|
||||
unitString = "nF";
|
||||
factor = 1e-15;
|
||||
}
|
||||
else if (UnitValue < 1e-9) {
|
||||
// \x reads everything to the end, therefore split
|
||||
unitString = "\xC2\xB5"
|
||||
"F";
|
||||
factor = 1e-12;
|
||||
}
|
||||
else if (UnitValue < 1e-6) {
|
||||
unitString = "mF";
|
||||
factor = 1e-9;
|
||||
}
|
||||
else {
|
||||
unitString = "F";
|
||||
factor = 1e-6;
|
||||
}
|
||||
}
|
||||
else if (unit == Unit::ElectricalInductance) {
|
||||
if (UnitValue < 1e-6) {
|
||||
unitString = "nH";
|
||||
factor = 1e-3;
|
||||
}
|
||||
else if (UnitValue < 1e-3) {
|
||||
unitString = "\xC2\xB5H";
|
||||
factor = 1.0;
|
||||
}
|
||||
else if (UnitValue < 1.0) {
|
||||
unitString = "mH";
|
||||
factor = 1e3;
|
||||
}
|
||||
else {
|
||||
unitString = "H";
|
||||
factor = 1e6;
|
||||
}
|
||||
}
|
||||
else if (unit == Unit::VacuumPermittivity) {
|
||||
unitString = "F/m";
|
||||
factor = 1e-9;
|
||||
}
|
||||
else if (unit == Unit::Work) {
|
||||
if (UnitValue < 1.602176634e-10) {
|
||||
unitString = "eV";
|
||||
factor = 1.602176634e-13;
|
||||
}
|
||||
else if (UnitValue < 1.602176634e-7) {
|
||||
unitString = "keV";
|
||||
factor = 1.602176634e-10;
|
||||
}
|
||||
else if (UnitValue < 1.602176634e-4) {
|
||||
unitString = "MeV";
|
||||
factor = 1.602176634e-7;
|
||||
}
|
||||
else if (UnitValue < 1e6) {
|
||||
unitString = "mJ";
|
||||
factor = 1e3;
|
||||
}
|
||||
else if (UnitValue < 1e9) {
|
||||
unitString = "J";
|
||||
factor = 1e6;
|
||||
}
|
||||
else if (UnitValue < 1e12) {
|
||||
unitString = "kJ";
|
||||
factor = 1e9;
|
||||
}
|
||||
else if (UnitValue < 3.6e+15) {
|
||||
unitString = "kWh";
|
||||
factor = 3.6e+12;
|
||||
}
|
||||
else { // bigger than 1000 kWh -> scientific notation
|
||||
unitString = "J";
|
||||
factor = 1e6;
|
||||
}
|
||||
}
|
||||
else if (unit == Unit::SpecificEnergy) {
|
||||
unitString = "m^2/s^2";
|
||||
factor = 1000000;
|
||||
}
|
||||
else if (unit == Unit::HeatFlux) {
|
||||
unitString = "W/m^2";
|
||||
factor = 1.0;
|
||||
}
|
||||
else if (unit == Unit::Frequency) {
|
||||
if (UnitValue < 1e3) {
|
||||
unitString = "Hz";
|
||||
factor = 1.0;
|
||||
}
|
||||
else if (UnitValue < 1e6) {
|
||||
unitString = "kHz";
|
||||
factor = 1e3;
|
||||
}
|
||||
else if (UnitValue < 1e9) {
|
||||
unitString = "MHz";
|
||||
factor = 1e6;
|
||||
}
|
||||
else if (UnitValue < 1e12) {
|
||||
unitString = "GHz";
|
||||
factor = 1e9;
|
||||
}
|
||||
else {
|
||||
unitString = "THz";
|
||||
factor = 1e12;
|
||||
}
|
||||
}
|
||||
else if (unit == Unit::Velocity) {
|
||||
unitString = "m/s";
|
||||
factor = 1000.0;
|
||||
}
|
||||
else if (unit == Unit::DynamicViscosity) {
|
||||
unitString = "Pa*s";
|
||||
factor = 0.001;
|
||||
}
|
||||
else if (unit == Unit::KinematicViscosity) {
|
||||
unitString = "m^2/s";
|
||||
factor = 1e6;
|
||||
}
|
||||
else if (unit == Unit::VolumeFlowRate) {
|
||||
if (UnitValue < 1e-3) { // smaller than 0.001 mm^3/s -> scientific notation
|
||||
unitString = "m^3/s";
|
||||
factor = 1e9;
|
||||
}
|
||||
else if (UnitValue < 1e3) {
|
||||
unitString = "mm^3/s";
|
||||
factor = 1.0;
|
||||
}
|
||||
else if (UnitValue < 1e6) {
|
||||
unitString = "ml/s";
|
||||
factor = 1e3;
|
||||
}
|
||||
else if (UnitValue < 1e9) {
|
||||
unitString = "l/s";
|
||||
factor = 1e6;
|
||||
}
|
||||
else {
|
||||
unitString = "m^3/s";
|
||||
factor = 1e9;
|
||||
}
|
||||
}
|
||||
else if (unit == Unit::DissipationRate) {
|
||||
unitString = "W/kg";
|
||||
factor = 1e6;
|
||||
}
|
||||
else if (unit == Unit::InverseLength) {
|
||||
if (UnitValue < 1e-6) { // smaller than 0.001 1/km -> scientific notation
|
||||
unitString = "1/m";
|
||||
factor = 1e-3;
|
||||
}
|
||||
else if (UnitValue < 1e-3) {
|
||||
unitString = "1/km";
|
||||
factor = 1e-6;
|
||||
}
|
||||
else if (UnitValue < 1.0) {
|
||||
unitString = "1/m";
|
||||
factor = 1e-3;
|
||||
}
|
||||
else if (UnitValue < 1e3) {
|
||||
unitString = "1/mm";
|
||||
factor = 1.0;
|
||||
}
|
||||
else if (UnitValue < 1e6) {
|
||||
unitString = "1/\xC2\xB5m";
|
||||
factor = 1e3;
|
||||
}
|
||||
else if (UnitValue < 1e9) {
|
||||
unitString = "1/nm";
|
||||
factor = 1e6;
|
||||
}
|
||||
else { // larger -> scientific notation
|
||||
unitString = "1/m";
|
||||
factor = 1e-3;
|
||||
}
|
||||
}
|
||||
else if (unit == Unit::InverseArea) {
|
||||
if (UnitValue < 1e-12) { // smaller than 0.001 1/km^2 -> scientific notation
|
||||
unitString = "1/m^2";
|
||||
factor = 1e-6;
|
||||
}
|
||||
else if (UnitValue < 1e-6) {
|
||||
unitString = "1/km^2";
|
||||
factor = 1e-12;
|
||||
}
|
||||
else if (UnitValue < 1.0) {
|
||||
unitString = "1/m^2";
|
||||
factor = 1e-6;
|
||||
}
|
||||
else if (UnitValue < 1e2) {
|
||||
unitString = "1/cm^2";
|
||||
factor = 1e-2;
|
||||
}
|
||||
else {
|
||||
unitString = "1/mm^2";
|
||||
factor = 1.0;
|
||||
}
|
||||
}
|
||||
else if (unit == Unit::InverseVolume) {
|
||||
if (UnitValue < 1e-6) {
|
||||
unitString = "1/m^3";
|
||||
factor = 1e-9;
|
||||
}
|
||||
else if (UnitValue < 1e-3) {
|
||||
unitString = "1/l";
|
||||
factor = 1e-6;
|
||||
}
|
||||
else if (UnitValue < 1.0) {
|
||||
unitString = "1/ml";
|
||||
factor = 1e-3;
|
||||
}
|
||||
else {
|
||||
unitString = "1/mm^3";
|
||||
factor = 1.0;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// default action for all cases without special treatment:
|
||||
unitString = quant.getUnit().getString();
|
||||
factor = 1.0;
|
||||
}
|
||||
|
||||
return toLocale(quant, factor, unitString);
|
||||
}
|
||||
@@ -1,43 +0,0 @@
|
||||
/***************************************************************************
|
||||
* Copyright (c) 2009 Jürgen Riegel <FreeCAD@juergen-riegel.net> *
|
||||
* *
|
||||
* This file is part of the FreeCAD CAx development system. *
|
||||
* *
|
||||
* This library is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU Library General Public *
|
||||
* License as published by the Free Software Foundation; either *
|
||||
* version 2 of the License, or (at your option) any later version. *
|
||||
* *
|
||||
* This library is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU Library General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU Library General Public *
|
||||
* License along with this library; see the file COPYING.LIB. If not, *
|
||||
* write to the Free Software Foundation, Inc., 59 Temple Place, *
|
||||
* Suite 330, Boston, MA 02111-1307, USA *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef BASE_UNITSSCHEMAMKS_H
|
||||
#define BASE_UNITSSCHEMAMKS_H
|
||||
|
||||
#include "UnitsSchema.h"
|
||||
|
||||
namespace Base
|
||||
{
|
||||
|
||||
/**
|
||||
* The UnitSchema class
|
||||
*/
|
||||
class UnitsSchemaMKS: public UnitsSchema
|
||||
{
|
||||
public:
|
||||
std::string
|
||||
schemaTranslate(const Base::Quantity& quant, double& factor, std::string& unitString) override;
|
||||
};
|
||||
|
||||
} // namespace Base
|
||||
|
||||
#endif // BASE_UNITSSCHEMAMKS_H
|
||||
@@ -1,72 +0,0 @@
|
||||
/***************************************************************************
|
||||
* Copyright (c) WandererFan <wandererfan@gmail.com> *
|
||||
* *
|
||||
* This file is part of the FreeCAD CAx development system. *
|
||||
* *
|
||||
* This library is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU Library General Public *
|
||||
* License as published by the Free Software Foundation; either *
|
||||
* version 2 of the License, or (at your option) any later version. *
|
||||
* *
|
||||
* This library is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU Library General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU Library General Public *
|
||||
* License along with this library; see the file COPYING.LIB. If not, *
|
||||
* write to the Free Software Foundation, Inc., 59 Temple Place, *
|
||||
* Suite 330, Boston, MA 02111-1307, USA *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
/* Metric units schema intended for design of large objects
|
||||
* Lengths are always in metres.
|
||||
* Areas are always in square metres
|
||||
* Volumes are always in cubic metres
|
||||
* Angles in decimal degrees (use degree symbol)
|
||||
* Velocities in m/sec
|
||||
*/
|
||||
|
||||
#include "PreCompiled.h"
|
||||
#ifndef _PreComp_
|
||||
#include <algorithm>
|
||||
#include <array>
|
||||
#endif
|
||||
|
||||
#include "Quantity.h"
|
||||
#include "Unit.h"
|
||||
#include "UnitsSchemaMeterDecimal.h"
|
||||
|
||||
using namespace Base;
|
||||
|
||||
std::string UnitsSchemaMeterDecimal::schemaTranslate(const Base::Quantity& quant,
|
||||
double& factor,
|
||||
std::string& unitString)
|
||||
{
|
||||
static std::array<std::pair<Unit, std::pair<std::string, double>>, 7> unitSpecs {{
|
||||
{Unit::Length, {"m", 1e3}},
|
||||
{Unit::Area, {"m^2", 1e6}},
|
||||
{Unit::Volume, {"m^3", 1e9}},
|
||||
{Unit::Power, {"W", 1000000}},
|
||||
{Unit::ElectricPotential, {"V", 1000000}},
|
||||
{Unit::HeatFlux, {"W/m^2", 1.0}},
|
||||
{Unit::Velocity, {"m/s", 1e3}},
|
||||
}};
|
||||
|
||||
const auto unit = quant.getUnit();
|
||||
const auto spec = std::find_if(unitSpecs.begin(), unitSpecs.end(), [&](const auto& pair) {
|
||||
return pair.first == unit;
|
||||
});
|
||||
|
||||
if (spec != std::end(unitSpecs)) {
|
||||
unitString = spec->second.first;
|
||||
factor = spec->second.second;
|
||||
}
|
||||
else {
|
||||
unitString = quant.getUnit().getString();
|
||||
factor = 1.0;
|
||||
}
|
||||
|
||||
return toLocale(quant, factor, unitString);
|
||||
}
|
||||
@@ -1,60 +0,0 @@
|
||||
/***************************************************************************
|
||||
* Copyright (c) 2009 Jürgen Riegel <FreeCAD@juergen-riegel.net> *
|
||||
* *
|
||||
* This file is part of the FreeCAD CAx development system. *
|
||||
* *
|
||||
* This library is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU Library General Public *
|
||||
* License as published by the Free Software Foundation; either *
|
||||
* version 2 of the License, or (at your option) any later version. *
|
||||
* *
|
||||
* This library is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU Library General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU Library General Public *
|
||||
* License along with this library; see the file COPYING.LIB. If not, *
|
||||
* write to the Free Software Foundation, Inc., 59 Temple Place, *
|
||||
* Suite 330, Boston, MA 02111-1307, USA *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
|
||||
#include "PreCompiled.h"
|
||||
#ifndef _PreComp_
|
||||
#include <algorithm>
|
||||
#include <array>
|
||||
#endif
|
||||
|
||||
#include "Quantity.h"
|
||||
#include "Unit.h"
|
||||
#include "UnitsSchemaMmMin.h"
|
||||
|
||||
using namespace Base;
|
||||
|
||||
std::string
|
||||
UnitsSchemaMmMin::schemaTranslate(const Quantity& quant, double& factor, std::string& unitString)
|
||||
{
|
||||
static std::array<std::pair<Unit, std::pair<std::string, double>>, 3> unitSpecs {{
|
||||
{Unit::Length, {"mm", 1.0}},
|
||||
{Unit::Angle, {"\xC2\xB0", 1.0}},
|
||||
{Unit::Velocity, {"mm/min", 1.0 / 60.0}},
|
||||
}};
|
||||
|
||||
const auto unit = quant.getUnit();
|
||||
const auto spec = std::find_if(unitSpecs.begin(), unitSpecs.end(), [&](const auto& pair) {
|
||||
return pair.first == unit;
|
||||
});
|
||||
|
||||
if (spec != std::end(unitSpecs)) {
|
||||
unitString = spec->second.first;
|
||||
factor = spec->second.second;
|
||||
}
|
||||
else {
|
||||
unitString = quant.getUnit().getString();
|
||||
factor = 1.0;
|
||||
}
|
||||
|
||||
return toLocale(quant, factor, unitString);
|
||||
}
|
||||
@@ -1,45 +0,0 @@
|
||||
/***************************************************************************
|
||||
* Copyright (c) 2009 Jürgen Riegel <FreeCAD@juergen-riegel.net> *
|
||||
* *
|
||||
* This file is part of the FreeCAD CAx development system. *
|
||||
* *
|
||||
* This library is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU Library General Public *
|
||||
* License as published by the Free Software Foundation; either *
|
||||
* version 2 of the License, or (at your option) any later version. *
|
||||
* *
|
||||
* This library is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU Library General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU Library General Public *
|
||||
* License along with this library; see the file COPYING.LIB. If not, *
|
||||
* write to the Free Software Foundation, Inc., 59 Temple Place, *
|
||||
* Suite 330, Boston, MA 02111-1307, USA *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef BASE_UNITSSCHEMAMMMIN_H
|
||||
#define BASE_UNITSSCHEMAMMMIN_H
|
||||
|
||||
#include "UnitsSchema.h"
|
||||
|
||||
namespace Base
|
||||
{
|
||||
|
||||
/* Metric units schema intended for design of small parts and for CNC
|
||||
* Lengths are always in mm.
|
||||
* Angles in degrees (use degree symbol)
|
||||
* Velocities in mm/min (as used in g-code).
|
||||
*/
|
||||
class UnitsSchemaMmMin: public UnitsSchema
|
||||
{
|
||||
public:
|
||||
std::string
|
||||
schemaTranslate(const Base::Quantity& quant, double& factor, std::string& unitString) override;
|
||||
};
|
||||
|
||||
} // namespace Base
|
||||
|
||||
#endif // BASE_UNITSSCHEMAMMMIN_H
|
||||
145
src/Base/UnitsSchemas.cpp
Normal file
145
src/Base/UnitsSchemas.cpp
Normal file
@@ -0,0 +1,145 @@
|
||||
/************************************************************************
|
||||
* *
|
||||
* This file is part of the FreeCAD CAx development system. *
|
||||
* *
|
||||
* This library is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU Library General Public *
|
||||
* License as published by the Free Software Foundation; either *
|
||||
* version 2 of the License, or (at your option) any later version. *
|
||||
* *
|
||||
* This library is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU Library General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU Library General Public *
|
||||
* License along with this library; see the file COPYING.LIB. If not, *
|
||||
* write to the Free Software Foundation, Inc., 59 Temple Place, *
|
||||
* Suite 330, Boston, MA 02111-1307, USA *
|
||||
* *
|
||||
************************************************************************/
|
||||
|
||||
#include <algorithm>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include <QCoreApplication>
|
||||
|
||||
#include "UnitsSchemas.h"
|
||||
#include "Exception.h"
|
||||
#include "Quantity.h"
|
||||
#include "UnitsApi.h"
|
||||
#include "UnitsSchema.h"
|
||||
#include "UnitsSchemasSpecs.h"
|
||||
#include "UnitsSchemasData.h"
|
||||
|
||||
using Base::Quantity;
|
||||
using Base::UnitsSchema;
|
||||
using Base::UnitsSchemas;
|
||||
using Base::UnitsSchemaSpec;
|
||||
|
||||
UnitsSchemas::UnitsSchemas(const UnitsSchemasDataPack& pack)
|
||||
: pack {pack}
|
||||
, denominator {pack.defDenominator}
|
||||
, decimals {pack.defDecimals}
|
||||
{}
|
||||
|
||||
size_t UnitsSchemas::count() const
|
||||
{
|
||||
return pack.specs.size();
|
||||
}
|
||||
|
||||
std::vector<std::string> UnitsSchemas::getVec(const std::function<std::string(UnitsSchemaSpec)>& fn)
|
||||
{
|
||||
std::vector<std::string> vec;
|
||||
std::transform(pack.specs.begin(), pack.specs.end(), std::back_inserter(vec), fn);
|
||||
|
||||
return vec;
|
||||
}
|
||||
|
||||
std::vector<std::string> UnitsSchemas::names()
|
||||
{
|
||||
return getVec([](const UnitsSchemaSpec& spec) {
|
||||
return spec.name;
|
||||
});
|
||||
}
|
||||
|
||||
std::vector<std::string> UnitsSchemas::descriptions()
|
||||
{
|
||||
return getVec([](const UnitsSchemaSpec& spec) {
|
||||
return QCoreApplication::translate("UnitsApi", spec.description).toStdString();
|
||||
});
|
||||
}
|
||||
|
||||
std::size_t UnitsSchemas::getDecimals() const
|
||||
{
|
||||
return pack.defDecimals;
|
||||
}
|
||||
|
||||
std::size_t UnitsSchemas::defFractDenominator() const
|
||||
{
|
||||
return pack.defDenominator;
|
||||
}
|
||||
|
||||
void UnitsSchemas::setdefFractDenominator(const std::size_t size)
|
||||
{
|
||||
denominator = size;
|
||||
}
|
||||
|
||||
void UnitsSchemas::select()
|
||||
{
|
||||
makeCurr(spec());
|
||||
}
|
||||
|
||||
void UnitsSchemas::select(const std::string_view& name)
|
||||
{
|
||||
makeCurr(spec(name));
|
||||
}
|
||||
|
||||
void UnitsSchemas::select(const std::size_t num)
|
||||
{
|
||||
makeCurr(spec(num));
|
||||
}
|
||||
|
||||
UnitsSchema* UnitsSchemas::currentSchema() const
|
||||
{
|
||||
return current.get();
|
||||
}
|
||||
|
||||
void UnitsSchemas::makeCurr(const UnitsSchemaSpec& spec)
|
||||
{
|
||||
current = std::make_unique<UnitsSchema>(spec);
|
||||
}
|
||||
|
||||
UnitsSchemaSpec UnitsSchemas::findSpec(const std::function<bool(UnitsSchemaSpec)>& fn)
|
||||
{
|
||||
const auto found = std::find_if(pack.specs.begin(), pack.specs.end(), fn);
|
||||
|
||||
if (found == pack.specs.end()) {
|
||||
throw RuntimeError {"UnitSchemaSpec not found"};
|
||||
}
|
||||
|
||||
return *found;
|
||||
}
|
||||
|
||||
UnitsSchemaSpec UnitsSchemas::spec()
|
||||
{
|
||||
return findSpec([](const UnitsSchemaSpec& spec) {
|
||||
return spec.isDefault;
|
||||
});
|
||||
}
|
||||
|
||||
UnitsSchemaSpec UnitsSchemas::spec(const std::string_view& name)
|
||||
{
|
||||
return findSpec([&name](const UnitsSchemaSpec& spec) {
|
||||
return spec.name == name;
|
||||
});
|
||||
}
|
||||
|
||||
UnitsSchemaSpec UnitsSchemas::spec(const std::size_t num)
|
||||
{
|
||||
return findSpec([&num](const UnitsSchemaSpec& spec) {
|
||||
return spec.num == num;
|
||||
});
|
||||
}
|
||||
77
src/Base/UnitsSchemas.h
Normal file
77
src/Base/UnitsSchemas.h
Normal file
@@ -0,0 +1,77 @@
|
||||
/************************************************************************
|
||||
* *
|
||||
* This file is part of the FreeCAD CAx development system. *
|
||||
* *
|
||||
* This library is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU Library General Public *
|
||||
* License as published by the Free Software Foundation; either *
|
||||
* version 2 of the License, or (at your option) any later version. *
|
||||
* *
|
||||
* This library is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU Library General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU Library General Public *
|
||||
* License along with this library; see the file COPYING.LIB. If not, *
|
||||
* write to the Free Software Foundation, Inc., 59 Temple Place, *
|
||||
* Suite 330, Boston, MA 02111-1307, USA *
|
||||
* *
|
||||
************************************************************************/
|
||||
|
||||
#ifndef SRC_BASE_UNITSSCHEMAS_H
|
||||
#define SRC_BASE_UNITSSCHEMAS_H
|
||||
|
||||
#include <functional>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "UnitsSchema.h"
|
||||
#include "UnitsSchemasSpecs.h"
|
||||
|
||||
namespace Base
|
||||
{
|
||||
|
||||
/**
|
||||
* The interface to schema specifications
|
||||
* Has pointer to current schema
|
||||
*/
|
||||
class UnitsSchemas
|
||||
{
|
||||
public:
|
||||
explicit UnitsSchemas(const UnitsSchemasDataPack& pack);
|
||||
|
||||
/** Make a schema and set as current*/
|
||||
void select(); // default
|
||||
void select(const std::string_view& name);
|
||||
void select(std::size_t num);
|
||||
|
||||
/** Get a schema specification*/
|
||||
UnitsSchemaSpec spec(); // default, or the first spec
|
||||
UnitsSchemaSpec spec(const std::string_view& name);
|
||||
UnitsSchemaSpec spec(std::size_t num);
|
||||
|
||||
size_t count() const;
|
||||
std::vector<std::string> names();
|
||||
std::vector<std::string> descriptions();
|
||||
std::size_t getDecimals() const;
|
||||
std::size_t defFractDenominator() const;
|
||||
void setdefFractDenominator(std::size_t size);
|
||||
|
||||
UnitsSchema* currentSchema() const;
|
||||
|
||||
private:
|
||||
/** DRY utils */
|
||||
std::vector<std::string> getVec(const std::function<std::string(UnitsSchemaSpec)>& fn);
|
||||
UnitsSchemaSpec findSpec(const std::function<bool(UnitsSchemaSpec)>& fn);
|
||||
void makeCurr(const UnitsSchemaSpec& spec);
|
||||
|
||||
UnitsSchemasDataPack pack;
|
||||
std::unique_ptr<UnitsSchema> current {std::make_unique<UnitsSchema>(spec())};
|
||||
std::size_t denominator;
|
||||
std::size_t decimals;
|
||||
};
|
||||
|
||||
|
||||
} // namespace Base
|
||||
#endif // SRC_BASE_UNITSSCHEMAS_H
|
||||
749
src/Base/UnitsSchemasData.h
Normal file
749
src/Base/UnitsSchemasData.h
Normal file
@@ -0,0 +1,749 @@
|
||||
/************************************************************************
|
||||
* *
|
||||
* This file is part of the FreeCAD CAx development system. *
|
||||
* *
|
||||
* This library is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU Library General Public *
|
||||
* License as published by the Free Software Foundation; either *
|
||||
* version 2 of the License, or (at your option) any later version. *
|
||||
* *
|
||||
* This library is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU Library General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU Library General Public *
|
||||
* License along with this library; see the file COPYING.LIB. If not, *
|
||||
* write to the Free Software Foundation, Inc., 59 Temple Place, *
|
||||
* Suite 330, Boston, MA 02111-1307, USA *
|
||||
* *
|
||||
************************************************************************/
|
||||
|
||||
#ifndef BASE_UNITSSCHEMASDATA_H
|
||||
#define BASE_UNITSSCHEMASDATA_H
|
||||
|
||||
#include <map>
|
||||
#include <vector>
|
||||
|
||||
#include <QtGlobal>
|
||||
|
||||
#include "fmt/format.h"
|
||||
#include "fmt/ranges.h"
|
||||
|
||||
#include "UnitsSchemasSpecs.h"
|
||||
|
||||
/**
|
||||
* UnitSchemas raw data
|
||||
*/
|
||||
|
||||
namespace Base::UnitsSchemasData
|
||||
{
|
||||
|
||||
constexpr std::size_t defDecimals {2};
|
||||
constexpr std::size_t defDenominator {8};
|
||||
|
||||
// NOLINTBEGIN
|
||||
// clang-format off
|
||||
inline const UnitsSchemaSpec s0
|
||||
{ 6, "MmMin", "mm" , false, false , QT_TRANSLATE_NOOP("UnitsApi", "Metric small parts & CNC (mm, mm/min)"), false,
|
||||
{
|
||||
{ "Length", {{ 0 , "mm" , 1.0 }}},
|
||||
{ "Angle", {{ 0 , "°" , 1.0 }}},
|
||||
{ "Velocity", {{ 0 , "mm/min" , 1.0 / 60.0 }}}
|
||||
}
|
||||
};
|
||||
|
||||
inline const UnitsSchemaSpec s1
|
||||
{ 9, "MeterDecimal", "m", false, false, QT_TRANSLATE_NOOP("UnitsApi", "Meter decimal (m, m², m³)"), false,
|
||||
{
|
||||
{ "Length", {{ 0 , "m" , 1e3 }}},
|
||||
{ "Area", {{ 0 , "m²" , 1e6 }}},
|
||||
{ "Volume", {{ 0 , "m³" , 1e9 }}},
|
||||
{ "Power", {{ 0 , "W" , 1e6 }}},
|
||||
{ "ElectricPotential", {{ 0 , "V" , 1e6 }}},
|
||||
{ "HeatFlux", {{ 0 , "W/m²" , 1.0 }}},
|
||||
{ "Velocity", {{ 0 , "m/s" , 1e3 }}}
|
||||
}
|
||||
};
|
||||
|
||||
inline const UnitsSchemaSpec s2
|
||||
{ 3, "ImperialDecimal", "in", false, false, QT_TRANSLATE_NOOP("UnitsApi", "Imperial decimal (in, lb)"), false,
|
||||
{
|
||||
{ "Length", {{ 0 , "in" , 25.4 }}},
|
||||
{ "Angle", {{ 0 , "°" , 1.0 }}},
|
||||
{ "Area", {{ 0 , "in²" , 645.16 }}},
|
||||
{ "Volume", {{ 0 , "in³" , 16387.064 }}},
|
||||
{ "Mass", {{ 0 , "lb" , 0.45359237 }}},
|
||||
{ "Pressure", {{ 0 , "psi" , 6.894744825494 }}},
|
||||
{ "Stiffness", {{ 0 , "lbf/in" , 4.448222 / 0.0254 }}},
|
||||
{ "Velocity", {{ 0 , "in/min" , 25.4 / 60 }}},
|
||||
{ "Acceleration", {{ 0 , "in/min²" , 25.4 / 3600 }}}
|
||||
}
|
||||
};
|
||||
|
||||
inline const UnitsSchemaSpec s3
|
||||
{ 0, "Internal", "m", false, false, QT_TRANSLATE_NOOP("UnitsApi", "Internal (m, m², m³)"), true,
|
||||
{
|
||||
{ "Length", {
|
||||
{ 1e-6 , "mm" , 1.0 },
|
||||
{ 1e-3 , "nm" , 1e-6 },
|
||||
{ 1e-1 , "μm" , 1e-3 },
|
||||
{ 1e4 , "mm" , 1.0 },
|
||||
{ 1e7 , "m" , 1e3 },
|
||||
{ 1e10 , "mm" , 1e6 },
|
||||
{ 0 , "m" , 1.0 }}
|
||||
},
|
||||
{ "Area", {
|
||||
{ 1e2 , "mm²" , 1.0 },
|
||||
{ 1e6 , "cm²" , 1e2 },
|
||||
{ 1e12 , "m²" , 1e6 },
|
||||
{ 0 , "km²" , 1e12 }}
|
||||
},
|
||||
{ "Volume", {
|
||||
{ 1e3 , "mm³" , 1.0 },
|
||||
{ 1e6 , "ml" , 1e3 },
|
||||
{ 1e9 , "l" , 1e6 },
|
||||
{ 0 , "m³" , 1e9 }}
|
||||
},
|
||||
{ "Angle", {
|
||||
{ 0 , "°" , 1.0 }}
|
||||
},
|
||||
{ "Mass", {
|
||||
{ 1e-6 , "μg" , 1.0 },
|
||||
{ 1e-3 , "mg" , 1e-6 },
|
||||
{ 1.0 , "g" , 1e-3 },
|
||||
{ 1e3 , "kg" , 1.0 },
|
||||
{ 0 , "t" , 1e3 }}
|
||||
},
|
||||
{ "Density", {
|
||||
{ 1e-4 , "kg/m³" , 1e-9 },
|
||||
{ 1.0 , "kg/cm³" , 1e-3 },
|
||||
{ 0 , "kg/mm³" , 1.0 }}
|
||||
},
|
||||
{ "ThermalConductivity", {
|
||||
{ 1e6 , "W/m/K" , 1e6 },
|
||||
{ 0 , "W/mm/K" , 1e3 }}
|
||||
},
|
||||
{ "ThermalExpansionCoefficient", {
|
||||
{ 1e-3 , "μm/m/K" , 1e-6 },
|
||||
{ 0 , "mm/mm/K" , 1.0 }}
|
||||
},
|
||||
{ "VolumetricThermalExpansionCoefficient", {
|
||||
{ 1e-3 , "mm³/m³/K" , 1e-9 },
|
||||
{ 0 , "m³/m³/K" , 1.0 }}
|
||||
},
|
||||
{ "SpecificHeat", {
|
||||
{ 0 , "J/kg/K" , 1e6 }}
|
||||
},
|
||||
{ "ThermalTransferCoefficient", {
|
||||
{ 0 , "W/m²/K" , 1.0 }}
|
||||
},
|
||||
{ "Pressure", {
|
||||
{ 10.0 , "Pa" , 1e-3 },
|
||||
{ 1e4 , "kPa" , 1.0 },
|
||||
{ 1e7 , "MPa" , 1e3 },
|
||||
{ 1e10 , "GPa" , 1e6 },
|
||||
{ 0 , "Pa" , 1e-3 }}
|
||||
},
|
||||
{ "Stress", {
|
||||
{ 10.0 , "Pa" , 1e-3 },
|
||||
{ 1e4 , "kPa" , 1.0 },
|
||||
{ 1e7 , "MPa" , 1e3 },
|
||||
{ 1e10 , "GPa" , 1e6 },
|
||||
{ 0 , "Pa" , 1e-3 }}
|
||||
},
|
||||
{ "Stiffness", {
|
||||
{ 1e-3 , "Pa/m" , 1e-6 },
|
||||
{ 1 , "mN/m" , 1e-3 },
|
||||
{ 1e3 , "N/m" , 1.0 },
|
||||
{ 1e6 , "kN/m" , 1e3 },
|
||||
{ 0 , "MN/m" , 1e6 }}
|
||||
},
|
||||
{ "StiffnessDensity", {
|
||||
{ 1 , "kPa/m" , 1e-3 },
|
||||
{ 1e3 , "MPa/m" , 1.0 },
|
||||
{ 1e3 , "mN" , 1.0 },
|
||||
{ 0 , "GPa/m" , 1e3 }}
|
||||
},
|
||||
{ "Force", {
|
||||
{ 1e6 , "N" , 1e3 },
|
||||
{ 1e9 , "kN" , 1e6 },
|
||||
{ 0 , "MN" , 1e9 }}
|
||||
},
|
||||
{ "Power", {
|
||||
{ 1e6 , "mW" , 1e3 },
|
||||
{ 1e9 , "W" , 1e6 },
|
||||
{ 0 , "kW" , 1e9 }}
|
||||
},
|
||||
{ "ElectricPotential", {
|
||||
{ 1e6 , "mV" , 1e3 },
|
||||
{ 1e9 , "V" , 1e6 },
|
||||
{ 1e12 , "kV" , 1e9 },
|
||||
{ 0 , "V" , 1e6 }}
|
||||
},
|
||||
{ "Work", {
|
||||
{ 1.602176634e-10 , "eV" , 1.602176634e-13 },
|
||||
{ 1.602176634e-7 , "keV" , 1.602176634e-10 },
|
||||
{ 1.602176634e-4 , "MeV" , 1.602176634e-7 },
|
||||
{ 1e6 , "mJ" , 1e3 },
|
||||
{ 1e9 , "J" , 1e6 },
|
||||
{ 1e12 , "kJ" , 1e9 },
|
||||
{ 3.6e+15 , "kWh" , 3.6e+12 },
|
||||
{ 0 , "J" , 1e6 }}
|
||||
},
|
||||
{ "SpecificEnergy", {
|
||||
{ 0 , "m²/s²" , 1e6 }}
|
||||
},
|
||||
{ "HeatFlux", {
|
||||
{ 0 , "W/m²" , 1.0 }}
|
||||
},
|
||||
{ "ElectricCharge", {
|
||||
{ 0 , "C" , 1.0 }}
|
||||
},
|
||||
{ "SurfaceChargeDensity", {
|
||||
{ 1e-4 , "C/m²" , 1e-6 },
|
||||
{ 1e-2 , "C/cm²" , 1e-2 },
|
||||
{ 0 , "C/mm²" , 1.0 }}
|
||||
},
|
||||
{ "VolumeChargeDensity", {
|
||||
{ 1e-4 , "C/m³" , 1e-9 },
|
||||
{ 1e-2 , "C/cm³" , 1e-3 },
|
||||
{ 0 , "C/mm³" , 1.0 }}
|
||||
},
|
||||
{ "CurrentDensity", {
|
||||
{ 1e-4 , "A/m²" , 1e-6 },
|
||||
{ 1e-2 , "A/cm²" , 1e-2 },
|
||||
{ 0 , "A/mm²" , 1 }}
|
||||
},
|
||||
{ "MagneticFluxDensity", {
|
||||
{ 1e-3 , "G" , 1e-4 },
|
||||
{ 0 , "T" , 1.0 }}
|
||||
},
|
||||
{ "MagneticFieldStrength", {
|
||||
{ 0 , "A/m" , 1e-3 }}
|
||||
},
|
||||
{ "MagneticFlux", {
|
||||
{ 0 , "Wb" , 1e6 }}
|
||||
},
|
||||
{ "Magnetization", {
|
||||
{ 0 , "A/m" , 1e-3 }}
|
||||
},
|
||||
{ "ElectricalConductance", {
|
||||
{ 1e-9 , "μS" , 1e-12 },
|
||||
{ 1e-6 , "mS" , 1e-9 },
|
||||
{ 0 , "S" , 1e-6 }}
|
||||
},
|
||||
{ "ElectricalResistance", {
|
||||
{ 1e9 , "Ohm" , 1e6 },
|
||||
{ 1e12 , "kOhm" , 1e9 },
|
||||
{ 0 , "MOhm" , 1e12 }}
|
||||
},
|
||||
{ "ElectricalConductivity", {
|
||||
{ 0 , "MS/m" , 1e-3 },
|
||||
{ 1e-3 , "mS/m" , 1e-12 },
|
||||
{ 1.0 , "S/m" , 1e-9 },
|
||||
{ 1e3 , "kS/m" , 1e-6 }}
|
||||
},
|
||||
{ "ElectricalCapacitance", {
|
||||
{ 1e-15 , "pF" , 1e-18 },
|
||||
{ 1e-12 , "nF" , 1e-15 },
|
||||
{ 1e-9 , "μF" , 1e-12 },
|
||||
{ 1e-6 , "mF" , 1e-9 },
|
||||
{ 0 , "F" , 1e-6 }}
|
||||
},
|
||||
{ "ElectricalInductance", {
|
||||
{ 1.0 , "nH" , 1e-3 },
|
||||
{ 1e3 , "μH" , 1.0 },
|
||||
{ 1e6 , "mH" , 1e3 },
|
||||
{ 0 , "H" , 1e6 }}
|
||||
},
|
||||
{ "VacuumPermittivity", {
|
||||
{ 0 , "F/m" , 1e-9 }}
|
||||
},
|
||||
{ "Frequency", {
|
||||
{ 1e3 , "Hz" , 1.0 },
|
||||
{ 1e6 , "kHz" , 1e3 },
|
||||
{ 1e9 , "MHz" , 1e6 },
|
||||
{ 1e12 , "GHz" , 1e9 },
|
||||
{ 0 , "THz" , 1e12 }}
|
||||
},
|
||||
{ "Velocity", {
|
||||
{ 0 , "mm/s" , 1.0 }}
|
||||
},
|
||||
{ "DynamicViscosity", {
|
||||
{ 0 , "Pa*s" , 1e-3 }}
|
||||
},
|
||||
{ "KinematicViscosity", {
|
||||
{ 1e3 , "mm²/s" , 1.0 },
|
||||
{ 0 , "m²/s" , 1e6 }}
|
||||
},
|
||||
{ "VolumeFlowRate", {
|
||||
{ 1e3 , "mm³/s" , 1.0 },
|
||||
{ 1e6 , "ml/s" , 1e3 },
|
||||
{ 1e9 , "l/s" , 1e6 },
|
||||
{ 0 , "m³/s" , 1e9 }}
|
||||
},
|
||||
{ "DissipationRate", {
|
||||
{ 0 , "W/kg" , 1e6 }}
|
||||
},
|
||||
{ "InverseLength", {
|
||||
{ 1e-6 , "1/m" , 1e-3 },
|
||||
{ 1e-3 , "1/km" , 1e-6 },
|
||||
{ 1.0 , "1/m" , 1e-3 },
|
||||
{ 1e3 , "1/mm" , 1.0 },
|
||||
{ 1e6 , "1/μm" , 1e3 },
|
||||
{ 1e9 , "1/nm" , 1e6 },
|
||||
{ 0 , "1/m" , 1e-3 }}
|
||||
},
|
||||
{ "InverseArea", {
|
||||
{ 1e-12 , "1/m²" , 1e-6 },
|
||||
{ 1e-6 , "1/km²" , 1e-12 },
|
||||
{ 1.0 , "1/m²" , 1e-6 },
|
||||
{ 1e2 , "1/cm²" , 1e-2 },
|
||||
{ 0 , "1/mm²" , 1.0 }}
|
||||
},
|
||||
{ "InverseVolume", {
|
||||
{ 1e-6 , "1/m³" , 1e-9 },
|
||||
{ 1e-3 , "1/l" , 1e-6 },
|
||||
{ 1.0 , "1/ml" , 1e-3 },
|
||||
{ 0 , "1/mm³" , 1.0 }}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
inline const UnitsSchemaSpec s4
|
||||
{ 1, "MKS", "m", false, false, QT_TRANSLATE_NOOP("UnitsApi", "MKS (m, kg, s, °)") , false,
|
||||
{
|
||||
{ "Length", {
|
||||
{ 1e-6 , "mm" , 1.0 },
|
||||
{ 1e-3 , "nm" , 1e-6 },
|
||||
{ 0.1 , "μm" , 1e-3 },
|
||||
{ 1e4 , "mm" , 1.0 },
|
||||
{ 1e7 , "m" , 1e3 },
|
||||
{ 1e10 , "km" , 1e6 },
|
||||
{ 0 , "m" , 1e3 }}
|
||||
},
|
||||
{ "Area", {
|
||||
{ 100 , "mm²" , 1.0 },
|
||||
{ 1e6 , "cm²" , 100 },
|
||||
{ 1e12 , "m²" , 1e6 },
|
||||
{ 0 , "km²" , 1e12 }}
|
||||
},
|
||||
{ "Volume", {
|
||||
{ 1e3 , "mm³" , 1.0 },
|
||||
{ 1e6 , "ml" , 1e3 },
|
||||
{ 1e9 , "l" , 1e6 },
|
||||
{ 0 , "m³" , 1e9 }}
|
||||
},
|
||||
{ "Mass", {
|
||||
{ 1e-6 , "μg" , 1e-9 },
|
||||
{ 1e-3 , "mg" , 1e-6 },
|
||||
{ 1.0 , "g" , 1e-3 },
|
||||
{ 1e3 , "kg" , 1.0 },
|
||||
{ 0 , "t" , 1e3 }}
|
||||
},
|
||||
{ "Density", {
|
||||
{ 0.0001 , "kg/m³" , 0.000000001 },
|
||||
{ 1.0 , "kg/cm³" , 0.001 },
|
||||
{ 0 , "kg/mm³" , 1.0 }}
|
||||
},
|
||||
{ "Acceleration", {
|
||||
{ 0 , "m/s²" , 1000.0 }}
|
||||
},
|
||||
{ "Pressure", {
|
||||
{ 10.0 , "Pa" , 0.001 },
|
||||
{ 10'000.0 , "kPa" , 1.0 },
|
||||
{ 10'000'000.0 , "MPa" , 1'000.0 },
|
||||
{ 10'000'000'000.0 , "GPa" , 1'000'000.0 },
|
||||
{ 0 , "Pa" , 1000.0 }}
|
||||
},
|
||||
{ "Stress", {
|
||||
{ 10.0 , "Pa" , 0.001 },
|
||||
{ 10'000.0 , "kPa" , 1.0 },
|
||||
{ 10'000'000.0 , "MPa" , 1'000.0 },
|
||||
{ 10'000'000'000.0 , "GPa" , 1'000'000.0 },
|
||||
{ 0 , "Pa" , 0.001 }}
|
||||
},
|
||||
{ "Stiffness", {
|
||||
{ 1 , "mN/m" , 1e-3 },
|
||||
{ 1e3 , "N/m" , 1.0 },
|
||||
{ 1e6 , "kN/m" , 1e3 },
|
||||
{ 0 , "MN/m" , 1e6 }}
|
||||
},
|
||||
{ "StiffnessDensity", {
|
||||
{ 1e-3 , "Pa/m" , 1e-6 },
|
||||
{ 1 , "kPa/m" , 1e-3 },
|
||||
{ 1e3 , "MPa/m" , 1.0 },
|
||||
{ 0 , "GPa/m" , 1e3 }}
|
||||
},
|
||||
{ "ThermalConductivity", {
|
||||
{ 1'000'000 , "W/mm/K" , 1'000'000.0 },
|
||||
{ 0 , "W/m/K" , 1'000.0 }}
|
||||
},
|
||||
{ "ThermalExpansionCoefficient", {
|
||||
{ 0.001 , "μm/m/K" , 0.000001 },
|
||||
{ 0 , "m/m/K" , 1.0 }}
|
||||
},
|
||||
{ "VolumetricThermalExpansionCoefficient", {
|
||||
{ 0.001 , "mm³/m³/K" , 1e-9 },
|
||||
{ 0 , "m³/m³/K" , 1.0 }}
|
||||
},
|
||||
{ "SpecificHeat", {
|
||||
{ 0 , "J/kg/K" , 1'000'000.0 }}
|
||||
},
|
||||
{ "ThermalTransferCoefficient", {
|
||||
{ 0 , "W/m²/K" , 1.0 }}
|
||||
},
|
||||
{ "Force", {
|
||||
{ 1e3 , "mN" , 1.0 },
|
||||
{ 1e6 , "N" , 1e3 },
|
||||
{ 1e9 , "kN" , 1e6 },
|
||||
{ 0 , "MN" , 1e9 }}
|
||||
},
|
||||
{ "Power", {
|
||||
{ 1e6 , "mW" , 1e3 },
|
||||
{ 1e9 , "W" , 1e6 },
|
||||
{ 0 , "kW" , 1e9 }}
|
||||
},
|
||||
{ "ElectricPotential", {
|
||||
{ 1e6 , "mV" , 1e3 },
|
||||
{ 1e9 , "V" , 1e6 },
|
||||
{ 1e12 , "kV" , 1e9 },
|
||||
{ 0 , "V" , 1e6 }}
|
||||
},
|
||||
{ "ElectricCharge", {
|
||||
{ 0 , "C" , 1.0 }}
|
||||
},
|
||||
{ "SurfaceChargeDensity", {
|
||||
{ 0 , "C/m²" , 1e-6 }}
|
||||
},
|
||||
{ "VolumeChargeDensity", {
|
||||
{ 0 , "C/m³" , 1e-9 }}
|
||||
},
|
||||
{ "CurrentDensity", {
|
||||
{ 1e3 , "A/m²" , 1e-6 },
|
||||
{ 0 , "A/mm²" , 1.0 }}
|
||||
},
|
||||
{ "MagneticFluxDensity", {
|
||||
{ 1e-3 , "G" , 1e-4 },
|
||||
{ 0 , "T" , 1.0 }}
|
||||
},
|
||||
{ "MagneticFieldStrength", {
|
||||
{ 0 , "A/m" , 1e-3 }}
|
||||
},
|
||||
{ "MagneticFlux", {
|
||||
{ 0 , "Wb" , 1e6 }}
|
||||
},
|
||||
{ "Magnetization", {
|
||||
{ 0 , "A/m" , 1e-3 }}
|
||||
},
|
||||
{ "ElectricalConductance", {
|
||||
{ 1e-9 , "μS" , 1e-12 },
|
||||
{ 1e-6 , "mS" , 1e-9 },
|
||||
{ 0 , "S" , 1e-6 }}
|
||||
},
|
||||
{ "ElectricalResistance", {
|
||||
{ 1e9 , "Ohm" , 1e6 },
|
||||
{ 1e12 , "kOhm" , 1e9 },
|
||||
{ 0 , "MOhm" , 1e12 }}
|
||||
},
|
||||
{ "ElectricalConductivity", {
|
||||
{ 1e-3 , "mS/m" , 1e-12 },
|
||||
{ 1.0 , "S/m" , 1e-9 },
|
||||
{ 1e3 , "kS/m" , 1e-6 },
|
||||
{ 0 , "MS/m" , 1e-3 }}
|
||||
},
|
||||
{ "ElectricalCapacitance", {
|
||||
{ 1e-15 , "pF" , 1e-18 },
|
||||
{ 1e-12 , "nF" , 1e-15 },
|
||||
{ 1e-9 , "μ" "F" , 1e-12 },
|
||||
{ 1e-6 , "mF" , 1e-9 },
|
||||
{ 0 , "F" , 1e-6 }}
|
||||
},
|
||||
{ "ElectricalInductance", {
|
||||
{ 1e-6 , "nH" , 1e-3 },
|
||||
{ 1e-3 , "μH" , 1.0 },
|
||||
{ 1.0 , "mH" , 1e3 },
|
||||
{ 0 , "H" , 1e6 }}
|
||||
},
|
||||
{ "VacuumPermittivity", {
|
||||
{ 0 , "F/m" , 1e-9 }}
|
||||
},
|
||||
{ "Work", {
|
||||
{ 1.602176634e-10 , "eV" , 1.602176634e-13 },
|
||||
{ 1.602176634e-7 , "keV" , 1.602176634e-10 },
|
||||
{ 1.602176634e-4 , "MeV" , 1.602176634e-7 },
|
||||
{ 1e6 , "mJ" , 1e3 },
|
||||
{ 1e9 , "J" , 1e6 },
|
||||
{ 1e12 , "kJ" , 1e9 },
|
||||
{ 3.6e+15 , "kWh" , 3.6e+12 },
|
||||
{ 0 , "J" , 1e6 }}
|
||||
},
|
||||
{ "SpecificEnergy", {
|
||||
{ 0 , "m²/s²" , 1000000 }}
|
||||
},
|
||||
{ "HeatFlux", {
|
||||
{ 0 , "W/m²" , 1.0 }}
|
||||
},
|
||||
{ "Frequency", {
|
||||
{ 1e3 , "Hz" , 1.0 },
|
||||
{ 1e6 , "kHz" , 1e3 },
|
||||
{ 1e9 , "MHz" , 1e6 },
|
||||
{ 1e12 , "GHz" , 1e9 },
|
||||
{ 0 , "THz" , 1e12 }}
|
||||
},
|
||||
{ "Velocity", {
|
||||
{ 0 , "m/s" , 1000.0 }}
|
||||
},
|
||||
{ "DynamicViscosity", {
|
||||
{ 0 , "Pa*s" , 0.001 }}
|
||||
},
|
||||
{ "KinematicViscosity", {
|
||||
{ 0 , "m²/s" , 1e6 }}
|
||||
},
|
||||
{ "VolumeFlowRate", {
|
||||
{ 1e-3 , "m³/s" , 1e9 },
|
||||
{ 1e3 , "mm³/s" , 1.0 },
|
||||
{ 1e6 , "ml/s" , 1e3 },
|
||||
{ 1e9 , "l/s" , 1e6 },
|
||||
{ 0 , "m³/s" , 1e9 }}
|
||||
},
|
||||
{ "DissipationRate", {
|
||||
{ 0 , "W/kg" , 1e6 }}
|
||||
},
|
||||
{ "InverseLength", {
|
||||
{ 1e-6 , "1/m" , 1e-3 },
|
||||
{ 1e-3 , "1/km" , 1e-6 },
|
||||
{ 1.0 , "1/m" , 1e-3 },
|
||||
{ 1e3 , "1/mm" , 1.0 },
|
||||
{ 1e6 , "1/μm" , 1e3 },
|
||||
{ 1e9 , "1/nm" , 1e6 },
|
||||
{ 0 , "1/m" , 1e-3 }}
|
||||
},
|
||||
{ "InverseArea", {
|
||||
{ 1e-12 , "1/m²" , 1e-6 },
|
||||
{ 1e-6 , "1/km²" , 1e-12 },
|
||||
{ 1.0 , "1/m²" , 1e-6 },
|
||||
{ 1e2 , "1/cm²" , 1e-2 },
|
||||
{ 0 , "1/mm²" , 1.0 }}
|
||||
},
|
||||
{ "InverseVolume", {
|
||||
{ 1e-6 , "1/m³" , 1e-9 },
|
||||
{ 1e-3 , "1/l" , 1e-6 },
|
||||
{ 1.0 , "1/ml" , 1e-3 },
|
||||
{ 0 , "1/mm³" , 1.0 }}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
inline const UnitsSchemaSpec s5
|
||||
{ 4, "Centimeter", "cm", false, false, QT_TRANSLATE_NOOP("UnitsApi", "Building Euro (cm, m², m³)") , false,
|
||||
{
|
||||
{ "Length", {
|
||||
{ 0 , "cm" , 10.0 }}
|
||||
},
|
||||
{ "Area", {
|
||||
{ 0 , "m²" , 1e6 }}
|
||||
},
|
||||
{ "Volume", {
|
||||
{ 0 , "m³" , 1e9 }}
|
||||
},
|
||||
{ "Power", {
|
||||
{ 0 , "W" , 1e6 }}
|
||||
},
|
||||
{ "ElectricPotential", {
|
||||
{ 0 , "V" , 1e6 }}
|
||||
},
|
||||
{ "HeatFlux", {
|
||||
{ 0 , "W/m²" , 1.0 }}
|
||||
},
|
||||
{ "Velocity", {
|
||||
{ 0 , "mm/min" , 1.0 / 60 }}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
inline const UnitsSchemaSpec s6
|
||||
{ 8, "FEM", "mm", false , false , QT_TRANSLATE_NOOP("UnitsApi", "FEM (mm, N, s)"), false,
|
||||
{
|
||||
{ "Length", {
|
||||
{ 0 , "mm" , 1.0 }}
|
||||
},
|
||||
{ "Mass", {
|
||||
{ 0 , "t" , 1e3 }}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
inline const UnitsSchemaSpec s7
|
||||
{ 2, "Imperial", "in", false, false, QT_TRANSLATE_NOOP("UnitsApi", "US customary (in, lb)"), false,
|
||||
{
|
||||
{ "Length", {
|
||||
{ 0.00000254 , "in" , 25.4 },
|
||||
{ 2.54 , "thou" , 0.0254 },
|
||||
{ 304.8 , "″" , 25.4 },
|
||||
{ 914.4 , "′" , 304.8 },
|
||||
{ 1'609'344.0 , "yd" , 914.4 },
|
||||
{ 1'609'344'000.0 , "mi" , 1'609'344.0 },
|
||||
{ 0 , "in" , 25.4 }}
|
||||
},
|
||||
{ "Angle", {
|
||||
{ 0 , "°" , 1.0 }}
|
||||
},
|
||||
{ "Area", {
|
||||
{ 0 , "in²" , 645.16 }}
|
||||
},
|
||||
{ "Volume", {
|
||||
{ 0 , "in³" , 16'387.064 }}
|
||||
},
|
||||
{ "Mass", {
|
||||
{ 0 , "lb" , 0.45359237 }}
|
||||
},
|
||||
{ "Pressure", {
|
||||
{ 6'894.744 , "psi" , 6.894744825494 },
|
||||
{ 6'894'744.825 , "ksi" , 6'894.744825494 },
|
||||
{ 0 , "psi" , 6.894744825494 }}
|
||||
},
|
||||
{ "Stiffness", {
|
||||
{ 0 , "lbf/in" , 4.448222 / 0.0254 }}
|
||||
},
|
||||
{ "Velocity", {
|
||||
{ 0 , "in/min" , 25.4 / 60 }}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
inline const UnitsSchemaSpec s8
|
||||
{ 5, "ImperialBuilding", "ft", true, false , QT_TRANSLATE_NOOP("UnitsApi", "Building US (ft-in, sqft, cft)"), false,
|
||||
{
|
||||
{ "Length" , {{ 0 , "toFractional" , 0 }}}, // <== !
|
||||
{ "Angle" , {{ 0 , "°" , 1.0 }}},
|
||||
{ "Area" , {{ 0 , "sqft" , 92'903.04 }}},
|
||||
{ "Volume" , {{ 0 , "cft" , 28'316'846.592 }}},
|
||||
{ "Velocity" , {{ 0 , "in/min" , 25.4 / 60 }}}
|
||||
}
|
||||
};
|
||||
|
||||
inline const UnitsSchemaSpec s9
|
||||
{ 7, "ImperialCivil", "ft", false, true, QT_TRANSLATE_NOOP("UnitsApi", "Imperial for Civil Eng (ft, ft/s)"), false,
|
||||
{
|
||||
{ "Angle" , {{ 0 , "toDMS" , 0 }}} // <== !
|
||||
}
|
||||
};
|
||||
|
||||
// clang-format on
|
||||
// NOLINTEND
|
||||
inline const std::vector schemaSpecs {s3, s4, s5, s6, s7, s8, s9, s0, s1, s2};
|
||||
|
||||
/**
|
||||
* Special functions
|
||||
*
|
||||
* A schema unit can have custom formatting via a special function
|
||||
* Such functions must be included here and also registered in special functions caller (below)
|
||||
*/
|
||||
|
||||
/** utility function for toFractional */
|
||||
inline std::size_t greatestCommonDenominator(const std::size_t a, const std::size_t b)
|
||||
{
|
||||
return b == 0 ? a : greatestCommonDenominator(b, a % b); // Euclid's algorithm
|
||||
}
|
||||
|
||||
/**
|
||||
* double -> [feet′][inches[-fraction]″], e.g.: 3′4-1/4″
|
||||
*/
|
||||
inline std::string toFractional(const double value)
|
||||
{
|
||||
constexpr auto inchPerFoot {12};
|
||||
constexpr auto mmPerInch {25.4};
|
||||
|
||||
auto numFractUnits =
|
||||
static_cast<std::size_t>(std::round(std::abs(value) / mmPerInch * defDenominator));
|
||||
if (numFractUnits == 0) {
|
||||
return "0";
|
||||
}
|
||||
|
||||
const auto feet =
|
||||
static_cast<std::size_t>(std::floor(numFractUnits / (inchPerFoot * defDenominator)));
|
||||
numFractUnits = numFractUnits - (inchPerFoot * defDenominator * feet);
|
||||
const auto inches = static_cast<std::size_t>(std::floor(numFractUnits / defDenominator));
|
||||
const std::size_t fractNumerator = numFractUnits - (defDenominator * inches);
|
||||
|
||||
const std::size_t common_denom = greatestCommonDenominator(fractNumerator, defDenominator);
|
||||
const std::size_t numerator = fractNumerator / common_denom;
|
||||
const std::size_t denominator = defDenominator / common_denom;
|
||||
|
||||
std::vector<std::string> resultParts {};
|
||||
if (inches > 0) {
|
||||
resultParts.push_back(fmt::format("{}", inches));
|
||||
if (numerator == 0) {
|
||||
resultParts.emplace_back("″");
|
||||
}
|
||||
}
|
||||
if (numerator > 0) {
|
||||
if (inches > 0) {
|
||||
resultParts.emplace_back("-");
|
||||
}
|
||||
resultParts.push_back(fmt::format("{}/{}″", numerator, denominator));
|
||||
}
|
||||
|
||||
return fmt::format("{}{}{}",
|
||||
value < 0 ? "-" : "",
|
||||
feet > 0 ? fmt::format("{}′", feet) : "",
|
||||
fmt::join(resultParts, ""));
|
||||
}
|
||||
|
||||
/**
|
||||
* double -> degrees°[minutes′[seconds″]]
|
||||
*/
|
||||
inline std::string toDms(const double value)
|
||||
{
|
||||
constexpr auto dmsRatio {60.0};
|
||||
|
||||
auto calc = [&](const double total) -> std::pair<int, double> {
|
||||
const double whole = std::floor(total);
|
||||
return {static_cast<int>(whole), dmsRatio * (total - whole)};
|
||||
};
|
||||
|
||||
auto [degrees, totalMinutes] = calc(value);
|
||||
std::string out = fmt::format("{}°", degrees);
|
||||
|
||||
if (totalMinutes > 0) {
|
||||
auto [minutes, totalSeconds] = calc(totalMinutes);
|
||||
out += fmt::format("{}′", minutes);
|
||||
|
||||
if (totalSeconds > 0) {
|
||||
out += fmt::format("{}″", std::round(totalSeconds));
|
||||
}
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Special functions caller
|
||||
*/
|
||||
|
||||
inline const std::map<std::string, std::function<std::string(double)>> specials // clang-format off
|
||||
{
|
||||
{
|
||||
{ "toDMS" , [](const double val) { return toDms(val); }},
|
||||
{ "toFractional" , [](const double val) { return toFractional(val); }}
|
||||
}
|
||||
}; // clang-format on
|
||||
|
||||
inline std::string runSpecial(const std::string& name, const double value)
|
||||
{
|
||||
return specials.contains(name) ? specials.at(name)(value) : "";
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Build data pack
|
||||
*/
|
||||
|
||||
inline const UnitsSchemasDataPack unitSchemasDataPack {schemaSpecs, defDecimals, defDenominator};
|
||||
|
||||
|
||||
} // namespace Base::UnitsSchemasData
|
||||
#endif // BASE_UNITSSCHEMASDATA_H
|
||||
@@ -1,54 +1,69 @@
|
||||
/***************************************************************************
|
||||
* Copyright (c) 2023 WandererFan <wandererfan@gmail.com> *
|
||||
* *
|
||||
* This file is part of the FreeCAD CAx development system. *
|
||||
* *
|
||||
* This library is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU Library General Public *
|
||||
* License as published by the Free Software Foundation; either *
|
||||
* version 2 of the License, or (at your option) any later version. *
|
||||
* *
|
||||
* This library is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU Library General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU Library General Public *
|
||||
* License along with this library; see the file COPYING.LIB. If not, *
|
||||
* write to the Free Software Foundation, Inc., 59 Temple Place, *
|
||||
* Suite 330, Boston, MA 02111-1307, USA *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
/* Metric units schema intended for design of large objects
|
||||
* Lengths are always in metres.
|
||||
* Angles in degrees (use degree symbol)
|
||||
* Velocities in m/sec
|
||||
*/
|
||||
|
||||
#ifndef BASE_UNITSSCHEMAMETERS_H
|
||||
#define BASE_UNITSSCHEMAMETERS_H
|
||||
|
||||
#include "UnitsSchema.h"
|
||||
|
||||
namespace Base
|
||||
{
|
||||
|
||||
/**
|
||||
* The UnitSchema class
|
||||
*/
|
||||
class UnitsSchemaMeterDecimal: public UnitsSchema
|
||||
{
|
||||
public:
|
||||
std::string
|
||||
schemaTranslate(const Base::Quantity& quant, double& factor, std::string& unitString) override;
|
||||
|
||||
std::string getBasicLengthUnit() const override
|
||||
{
|
||||
return {"m"};
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace Base
|
||||
|
||||
#endif // BASE_UNITSSCHEMAMETRES_H
|
||||
/************************************************************************
|
||||
* *
|
||||
* This file is part of the FreeCAD CAx development system. *
|
||||
* *
|
||||
* This library is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU Library General Public *
|
||||
* License as published by the Free Software Foundation; either *
|
||||
* version 2 of the License, or (at your option) any later version. *
|
||||
* *
|
||||
* This library is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU Library General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU Library General Public *
|
||||
* License along with this library; see the file COPYING.LIB. If not, *
|
||||
* write to the Free Software Foundation, Inc., 59 Temple Place, *
|
||||
* Suite 330, Boston, MA 02111-1307, USA *
|
||||
* *
|
||||
************************************************************************/
|
||||
|
||||
#ifndef UNITSCHEMASPECS_H
|
||||
#define UNITSCHEMASPECS_H
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <functional>
|
||||
|
||||
namespace Base
|
||||
{
|
||||
|
||||
|
||||
struct UnitTranslationSpec
|
||||
{
|
||||
double threshold {1};
|
||||
std::string unitString;
|
||||
double factor {1};
|
||||
std::function<std::string(double)> fn {nullptr};
|
||||
};
|
||||
|
||||
struct UnitsSchemaSpec
|
||||
{
|
||||
std::size_t num;
|
||||
std::string name;
|
||||
std::string basicLengthUnitStr;
|
||||
bool isMultUnitLen {false};
|
||||
bool isMultUnitAngle {false};
|
||||
const char* description;
|
||||
bool isDefault {false};
|
||||
|
||||
/**
|
||||
* Applicable spec is the first with threshold > value under test
|
||||
* Special case: Threshold = 0 : default
|
||||
* Special case: Factor = 0 : unitString contains name of special function to run
|
||||
*/
|
||||
std::map<std::string, std::vector<UnitTranslationSpec>> translationSpecs;
|
||||
};
|
||||
|
||||
struct UnitsSchemasDataPack
|
||||
{
|
||||
std::vector<UnitsSchemaSpec> specs;
|
||||
size_t defDecimals;
|
||||
size_t defDenominator;
|
||||
};
|
||||
|
||||
|
||||
} // namespace Base
|
||||
#endif // UNITSCHEMASPECS_H
|
||||
@@ -1072,12 +1072,12 @@ void Application::slotActiveDocument(const App::Document& Doc)
|
||||
"User parameter:BaseApp/Preferences/Units");
|
||||
if (!hGrp->GetBool("IgnoreProjectSchema")) {
|
||||
int userSchema = Doc.UnitSystem.getValue();
|
||||
Base::UnitsApi::setSchema(static_cast<Base::UnitSystem>(userSchema));
|
||||
Base::UnitsApi::setSchema(userSchema);
|
||||
getMainWindow()->setUserSchema(userSchema);
|
||||
Application::Instance->onUpdate();
|
||||
}
|
||||
else { // set up Unit system default
|
||||
Base::UnitsApi::setSchema((Base::UnitSystem)hGrp->GetInt("UserSchema", 0));
|
||||
Base::UnitsApi::setSchema(hGrp->GetInt("UserSchema", 0));
|
||||
Base::UnitsApi::setDecimals(hGrp->GetInt("Decimals", Base::UnitsApi::getDecimals()));
|
||||
}
|
||||
signalActiveDocument(*doc->second);
|
||||
|
||||
@@ -83,11 +83,12 @@ DlgProjectInformationImp::DlgProjectInformationImp(App::Document* doc,
|
||||
ui->lineEditCompany->setText(QString::fromUtf8(doc->Company.getValue()));
|
||||
|
||||
// Load comboBox with unit systems
|
||||
int num = static_cast<int>(Base::UnitSystem::NumUnitSystemTypes);
|
||||
for (int i = 0; i < num; i++) {
|
||||
QString item = Base::UnitsApi::getDescription(static_cast<Base::UnitSystem>(i));
|
||||
ui->comboBox_unitSystem->addItem(item, i);
|
||||
}
|
||||
auto addDesc = [&, index {0}](const std::string& item) mutable {
|
||||
ui->comboBox_unitSystem->addItem(QString::fromStdString(item), index++);
|
||||
};
|
||||
const auto descriptions = Base::UnitsApi::getDescriptions();
|
||||
std::for_each(descriptions.begin(), descriptions.end(), addDesc);
|
||||
|
||||
ui->comboBox_unitSystem->setCurrentIndex(doc->UnitSystem.getValue());
|
||||
|
||||
// load comboBox with license names
|
||||
|
||||
@@ -51,12 +51,12 @@ DlgUnitsCalculator::DlgUnitsCalculator(QWidget* parent, Qt::WindowFlags fl)
|
||||
ui->setupUi(this);
|
||||
this->setAttribute(Qt::WA_DeleteOnClose);
|
||||
|
||||
ui->comboBoxScheme->addItem(QStringLiteral("Preference system"), static_cast<int>(-1));
|
||||
int num = static_cast<int>(Base::UnitSystem::NumUnitSystemTypes);
|
||||
for (int i = 0; i < num; i++) {
|
||||
QString item = Base::UnitsApi::getDescription(static_cast<Base::UnitSystem>(i));
|
||||
ui->comboBoxScheme->addItem(item, i);
|
||||
}
|
||||
ui->comboBoxScheme->addItem(QStringLiteral("Preference system"), -1);
|
||||
auto addItem = [&, index {0}](const auto& item) mutable {
|
||||
ui->comboBoxScheme->addItem(QString::fromStdString(item), index++);
|
||||
};
|
||||
auto descriptions = Base::UnitsApi::getDescriptions();
|
||||
std::for_each(descriptions.begin(), descriptions.end(), addItem);
|
||||
|
||||
// clang-format off
|
||||
connect(ui->unitsBox, qOverload<int>(&QComboBox::activated),
|
||||
@@ -214,7 +214,7 @@ void DlgUnitsCalculator::onComboBoxSchemeActivated(int index)
|
||||
{
|
||||
int item = ui->comboBoxScheme->itemData(index).toInt();
|
||||
if (item > 0) {
|
||||
ui->quantitySpinBox->setSchema(static_cast<Base::UnitSystem>(item));
|
||||
ui->quantitySpinBox->setSchema(item);
|
||||
}
|
||||
else {
|
||||
ui->quantitySpinBox->clearSchema();
|
||||
|
||||
@@ -65,6 +65,7 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include <algorithm>
|
||||
#include <boost/algorithm/string/predicate.hpp>
|
||||
|
||||
#include <App/Application.h>
|
||||
@@ -179,13 +180,16 @@ public:
|
||||
//create the action buttons
|
||||
auto* menu = new QMenu(this);
|
||||
auto* actionGrp = new QActionGroup(menu);
|
||||
int num = static_cast<int>(Base::UnitSystem::NumUnitSystemTypes);
|
||||
for (int i = 0; i < num; i++) {
|
||||
QAction* action = menu->addAction(QStringLiteral("UnitSchema%1").arg(i));
|
||||
|
||||
auto setAction = [&, index {0}](const std::string&) mutable {
|
||||
QAction* action = menu->addAction(QStringLiteral("UnitSchema%1").arg(index));
|
||||
actionGrp->addAction(action);
|
||||
action->setCheckable(true);
|
||||
action->setData(i);
|
||||
}
|
||||
action->setData(index++);
|
||||
};
|
||||
auto descriptions = Base::UnitsApi::getDescriptions();
|
||||
std::for_each(descriptions.begin(), descriptions.end(), setAction);
|
||||
|
||||
QObject::connect(actionGrp, &QActionGroup::triggered, this, [this](QAction* action) {
|
||||
int userSchema = action->data().toInt();
|
||||
setUserSchema(userSchema);
|
||||
@@ -236,7 +240,7 @@ public:
|
||||
getWindowParameter()->SetInt("UserSchema", userSchema);
|
||||
|
||||
unitChanged();
|
||||
Base::UnitsApi::setSchema(static_cast<Base::UnitSystem>(userSchema));
|
||||
Base::UnitsApi::setSchema(userSchema);
|
||||
// Update the main window to show the unit change
|
||||
Gui::Application::Instance->onUpdate();
|
||||
}
|
||||
@@ -261,12 +265,12 @@ private:
|
||||
|
||||
void retranslateUi() {
|
||||
auto actions = menu()->actions();
|
||||
int maxSchema = static_cast<int>(Base::UnitSystem::NumUnitSystemTypes);
|
||||
assert(actions.size() <= maxSchema);
|
||||
for(int i = 0; i < maxSchema ; i++)
|
||||
{
|
||||
actions[i]->setText(Base::UnitsApi::getDescription(static_cast<Base::UnitSystem>(i)));
|
||||
}
|
||||
auto addAction = [&, index {0}](const std::string& action)mutable {
|
||||
actions[index++]->setText(QString::fromStdString(action));
|
||||
};
|
||||
auto descriptions = Base::UnitsApi::getDescriptions();
|
||||
assert(actions.size() <= static_cast<qsizetype>(descriptions.size()));
|
||||
std::for_each(descriptions.begin(), descriptions.end(), addAction);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -63,7 +63,8 @@
|
||||
using namespace Gui;
|
||||
using namespace Gui::Dialog;
|
||||
namespace fs = std::filesystem;
|
||||
using namespace Base;
|
||||
using Base::UnitsApi;
|
||||
using Base::QuantityFormat;
|
||||
|
||||
/* TRANSLATOR Gui::Dialog::DlgSettingsGeneral */
|
||||
|
||||
@@ -117,14 +118,14 @@ DlgSettingsGeneral::DlgSettingsGeneral( QWidget* parent )
|
||||
connect(ui->comboBox_UnitSystem, qOverload<int>(&QComboBox::currentIndexChanged), this, &DlgSettingsGeneral::onUnitSystemIndexChanged);
|
||||
ui->spinBoxDecimals->setMaximum(std::numeric_limits<double>::digits10 + 1);
|
||||
|
||||
int num = static_cast<int>(Base::UnitSystem::NumUnitSystemTypes);
|
||||
for (int i = 0; i < num; i++) {
|
||||
QString item = Base::UnitsApi::getDescription(static_cast<Base::UnitSystem>(i));
|
||||
ui->comboBox_UnitSystem->addItem(item, i);
|
||||
}
|
||||
auto addItem = [&, index {0}](const std::string& item) mutable {
|
||||
ui->comboBox_UnitSystem->addItem(QString::fromStdString(item), index++);
|
||||
};
|
||||
auto descriptions = UnitsApi::getDescriptions();
|
||||
std::for_each(descriptions.begin(), descriptions.end(), addItem);
|
||||
|
||||
// Enable/disable the fractional inch option depending on system
|
||||
const auto visible = (UnitsApi::getSchema() == UnitSystem::ImperialBuilding);
|
||||
const auto visible = UnitsApi::isMultiUnitLength();
|
||||
ui->comboBox_FracInch->setVisible(visible);
|
||||
ui->fractionalInchLabel->setVisible(visible);
|
||||
}
|
||||
@@ -204,7 +205,7 @@ void DlgSettingsGeneral::saveUnitSystemSettings()
|
||||
hGrpu->SetBool("IgnoreProjectSchema", ui->checkBox_projectUnitSystemIgnore->isChecked());
|
||||
|
||||
// Set actual value
|
||||
Base::UnitsApi::setDecimals(ui->spinBoxDecimals->value());
|
||||
UnitsApi::setDecimals(ui->spinBoxDecimals->value());
|
||||
|
||||
// Convert the combobox index to the its integer denominator. Currently
|
||||
// with 1/2, 1/4, through 1/128, this little equation directly computes the
|
||||
@@ -218,21 +219,21 @@ void DlgSettingsGeneral::saveUnitSystemSettings()
|
||||
hGrpu->SetInt("FracInch", FracInch);
|
||||
|
||||
// Set the actual format value
|
||||
Base::QuantityFormat::setDefaultDenominator(FracInch);
|
||||
QuantityFormat::setDefaultDenominator(FracInch);
|
||||
|
||||
// Set and save the Unit System
|
||||
if (ui->checkBox_projectUnitSystemIgnore->isChecked()) {
|
||||
// currently selected View System (unit system)
|
||||
int viewSystemIndex = ui->comboBox_UnitSystem->currentIndex();
|
||||
UnitsApi::setSchema(static_cast<UnitSystem>(viewSystemIndex));
|
||||
UnitsApi::setSchema(viewSystemIndex);
|
||||
}
|
||||
else if (App::Document* doc = App::GetApplication().getActiveDocument()) {
|
||||
UnitsApi::setSchema(static_cast<UnitSystem>(doc->UnitSystem.getValue()));
|
||||
UnitsApi::setSchema(doc->UnitSystem.getValue());
|
||||
}
|
||||
else {
|
||||
// if there is no existing document then the unit must still be set
|
||||
int viewSystemIndex = ui->comboBox_UnitSystem->currentIndex();
|
||||
UnitsApi::setSchema(static_cast<UnitSystem>(viewSystemIndex));
|
||||
UnitsApi::setSchema(viewSystemIndex);
|
||||
}
|
||||
|
||||
ui->SubstituteDecimal->onSave();
|
||||
@@ -287,11 +288,11 @@ void DlgSettingsGeneral::loadSettings()
|
||||
ParameterGrp::handle hGrpu = App::GetApplication().GetParameterGroupByPath
|
||||
("User parameter:BaseApp/Preferences/Units");
|
||||
ui->comboBox_UnitSystem->setCurrentIndex(hGrpu->GetInt("UserSchema", 0));
|
||||
ui->spinBoxDecimals->setValue(hGrpu->GetInt("Decimals", Base::UnitsApi::getDecimals()));
|
||||
ui->spinBoxDecimals->setValue(hGrpu->GetInt("Decimals", UnitsApi::getDecimals()));
|
||||
ui->checkBox_projectUnitSystemIgnore->setChecked(hGrpu->GetBool("IgnoreProjectSchema", false));
|
||||
|
||||
// Get the current user setting for the minimum fractional inch
|
||||
FracInch = hGrpu->GetInt("FracInch", Base::QuantityFormat::getDefaultDenominator());
|
||||
FracInch = hGrpu->GetInt("FracInch", QuantityFormat::getDefaultDenominator());
|
||||
|
||||
// Convert fractional inch to the corresponding combobox index using this
|
||||
// handy little equation.
|
||||
@@ -529,11 +530,11 @@ void DlgSettingsGeneral::translateIconSizes()
|
||||
|
||||
void DlgSettingsGeneral::retranslateUnits()
|
||||
{
|
||||
int num = ui->comboBox_UnitSystem->count();
|
||||
for (int i = 0; i < num; i++) {
|
||||
QString item = Base::UnitsApi::getDescription(static_cast<Base::UnitSystem>(i));
|
||||
ui->comboBox_UnitSystem->setItemText(i, item);
|
||||
}
|
||||
auto setItem = [&, index {0}](const std::string& item) mutable {
|
||||
ui->comboBox_UnitSystem->setItemText(index++, QString::fromStdString(item));
|
||||
};
|
||||
const auto descriptions = UnitsApi::getDescriptions();
|
||||
std::for_each(descriptions.begin(), descriptions.end(), setItem);
|
||||
}
|
||||
|
||||
void DlgSettingsGeneral::changeEvent(QEvent *event)
|
||||
@@ -761,13 +762,14 @@ void DlgSettingsGeneral::onLoadPreferencePackClicked(const std::string& packName
|
||||
}
|
||||
}
|
||||
|
||||
void DlgSettingsGeneral::onUnitSystemIndexChanged(int index)
|
||||
void DlgSettingsGeneral::onUnitSystemIndexChanged(const int index)
|
||||
{
|
||||
if (index < 0)
|
||||
return; // happens when clearing the combo box in retranslateUi()
|
||||
if (index < 0) {
|
||||
return; // happens when clearing the combo box in retranslateUi()
|
||||
}
|
||||
|
||||
// Enable/disable the fractional inch option depending on system
|
||||
const auto visible = (static_cast<UnitSystem>(index) == UnitSystem::ImperialBuilding);
|
||||
const auto visible = UnitsApi::isMultiUnitLength();
|
||||
ui->comboBox_FracInch->setVisible(visible);
|
||||
ui->fractionalInchLabel->setVisible(visible);
|
||||
}
|
||||
|
||||
@@ -45,6 +45,7 @@
|
||||
#include <Base/Exception.h>
|
||||
#include <Base/UnitsApi.h>
|
||||
#include <Base/Tools.h>
|
||||
#include <Base/UnitsSchema.h>
|
||||
|
||||
#include "QuantitySpinBox.h"
|
||||
#include "QuantitySpinBox_p.h"
|
||||
@@ -714,7 +715,7 @@ void QuantitySpinBox::setDecimals(int v)
|
||||
updateText(d->quantity);
|
||||
}
|
||||
|
||||
void QuantitySpinBox::setSchema(const Base::UnitSystem& s)
|
||||
void QuantitySpinBox::setSchema(const int s)
|
||||
{
|
||||
Q_D(QuantitySpinBox);
|
||||
d->scheme = Base::UnitsApi::createSchema(s);
|
||||
@@ -732,7 +733,7 @@ QString QuantitySpinBox::getUserString(const Base::Quantity& val, double& factor
|
||||
{
|
||||
Q_D(const QuantitySpinBox);
|
||||
std::string unitStr;
|
||||
std::string str = d->scheme ? val.getUserString(d->scheme.get(), factor, unitStr)
|
||||
const std::string str = d->scheme ? val.getUserString(d->scheme.get(), factor, unitStr)
|
||||
: val.getUserString(factor, unitStr);
|
||||
unitString = QString::fromStdString(unitStr);
|
||||
return QString::fromStdString(str);
|
||||
|
||||
@@ -24,7 +24,6 @@
|
||||
#ifndef GUI_QUANTITYSPINBOX_H
|
||||
#define GUI_QUANTITYSPINBOX_H
|
||||
|
||||
#include <Base/UnitsSchema.h>
|
||||
#include <Gui/MetaTypes.h>
|
||||
#include <Gui/SpinBox.h>
|
||||
|
||||
@@ -99,7 +98,7 @@ public:
|
||||
|
||||
/// Sets a specific unit schema to handle quantities.
|
||||
/// The system-wide schema won't be used any more.
|
||||
void setSchema(const Base::UnitSystem& s);
|
||||
void setSchema(int s);
|
||||
|
||||
/// Clears the schemaand again use the system-wide schema.
|
||||
void clearSchema();
|
||||
|
||||
@@ -841,7 +841,7 @@ QString getPreselectionInfo(const char* documentName,
|
||||
{
|
||||
auto pts = schemaTranslatePoint(x, y, z, precision);
|
||||
|
||||
int numberDecimals = std::min(6, Base::UnitsApi::getDecimals());
|
||||
int numberDecimals = std::min(6, static_cast<int>(Base::UnitsApi::getDecimals()));
|
||||
|
||||
QString message = QStringLiteral("Preselected: %1.%2.%3 (%4 %5, %6 %7, %8 %9)")
|
||||
.arg(QString::fromUtf8(documentName))
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
#include <QWidget>
|
||||
#endif
|
||||
|
||||
#include <algorithm>
|
||||
#include "GeneralSettingsWidget.h"
|
||||
#include <gsl/pointers>
|
||||
#include <App/Application.h>
|
||||
@@ -182,7 +183,7 @@ void GeneralSettingsWidget::onUnitSystemChanged(int index)
|
||||
if (index < 0) {
|
||||
return; // happens when clearing the combo box in retranslateUi()
|
||||
}
|
||||
Base::UnitsApi::setSchema(static_cast<Base::UnitSystem>(index));
|
||||
Base::UnitsApi::setSchema(index);
|
||||
ParameterGrp::handle hGrp =
|
||||
App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/Units");
|
||||
hGrp->SetInt("UserSchema", index);
|
||||
@@ -213,15 +214,16 @@ void GeneralSettingsWidget::retranslateUi()
|
||||
_unitSystemLabel->setText(createLabelText(tr("Unit System")));
|
||||
|
||||
_unitSystemComboBox->clear();
|
||||
ParameterGrp::handle hGrpUnits =
|
||||
|
||||
auto addItem = [&, index {0}](const std::string& item) mutable {
|
||||
_unitSystemComboBox->addItem(QString::fromStdString(item), index++);
|
||||
};
|
||||
auto descriptions = Base::UnitsApi::getDescriptions();
|
||||
std::for_each(descriptions.begin(), descriptions.end(), addItem);
|
||||
|
||||
const ParameterGrp::handle hGrpUnits =
|
||||
App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/Units");
|
||||
auto userSchema = hGrpUnits->GetInt("UserSchema", 0);
|
||||
int num = static_cast<int>(Base::UnitSystem::NumUnitSystemTypes);
|
||||
for (int i = 0; i < num; i++) {
|
||||
QString item = Base::UnitsApi::getDescription(static_cast<Base::UnitSystem>(i));
|
||||
_unitSystemComboBox->addItem(item, i);
|
||||
}
|
||||
_unitSystemComboBox->setCurrentIndex(userSchema);
|
||||
_unitSystemComboBox->setCurrentIndex(static_cast<int>(hGrpUnits->GetInt("UserSchema", 0)));
|
||||
|
||||
_navigationStyleLabel->setText(createLabelText(tr("Navigation Style")));
|
||||
_navigationStyleComboBox->clear();
|
||||
|
||||
@@ -15,6 +15,7 @@ target_sources(Tests_run PRIVATE
|
||||
Quantity.cpp
|
||||
Reader.cpp
|
||||
Rotation.cpp
|
||||
SchemaTests.cpp
|
||||
ServiceProvider.cpp
|
||||
Stream.cpp
|
||||
TimeInfo.cpp
|
||||
|
||||
@@ -1,16 +1,18 @@
|
||||
#include <gtest/gtest.h>
|
||||
#include <Base/Exception.h>
|
||||
#include <Base/Quantity.h>
|
||||
#include <Base/UnitsApi.h>
|
||||
#include <Base/UnitsSchemaImperial1.h>
|
||||
#include <QLocale>
|
||||
#include <boost/core/ignore_unused.hpp>
|
||||
|
||||
// NOLINTBEGIN
|
||||
using Base::ParserError;
|
||||
using Base::Quantity;
|
||||
using Base::Unit;
|
||||
using Base::UnitsMismatchError;
|
||||
|
||||
|
||||
TEST(BaseQuantity, TestValid)
|
||||
{
|
||||
Base::Quantity q1 {1.0, Base::Unit::Length};
|
||||
Base::Quantity q2 {1.0, Base::Unit::Area};
|
||||
const Quantity q1 {1.0, Unit::Length};
|
||||
Quantity q2 {1.0, Unit::Area};
|
||||
q2.setInvalid();
|
||||
|
||||
EXPECT_EQ(q1.isValid(), true);
|
||||
@@ -19,77 +21,87 @@ TEST(BaseQuantity, TestValid)
|
||||
|
||||
TEST(BaseQuantity, TestParse)
|
||||
{
|
||||
Base::Quantity q1 = Base::Quantity::parse("1,234 kg");
|
||||
|
||||
EXPECT_EQ(q1, Base::Quantity(1.2340, Base::Unit::Mass));
|
||||
EXPECT_THROW(boost::ignore_unused(Base::Quantity::parse("1,234,500.12 kg")), Base::ParserError);
|
||||
const Quantity q1 = Quantity::parse("1,234 kg");
|
||||
constexpr auto val {1.2340};
|
||||
EXPECT_EQ(q1, Quantity(val, Unit::Mass));
|
||||
EXPECT_THROW(auto rew [[maybe_unused]] = Quantity::parse("1,234,500.12 kg"), ParserError);
|
||||
}
|
||||
|
||||
TEST(BaseQuantity, TestDim)
|
||||
{
|
||||
Base::Quantity q1 {0, Base::Unit::Area};
|
||||
const Quantity q1 {0, Unit::Area};
|
||||
|
||||
EXPECT_EQ(q1.isQuantity(), true);
|
||||
}
|
||||
|
||||
TEST(BaseQuantity, TestNoDim)
|
||||
{
|
||||
Base::Quantity q1 {};
|
||||
const Quantity q1 {};
|
||||
|
||||
EXPECT_EQ(q1.pow(2), Base::Quantity {0});
|
||||
EXPECT_EQ(q1.pow(2), Quantity {0});
|
||||
EXPECT_EQ(q1.isDimensionless(), true);
|
||||
}
|
||||
|
||||
TEST(BaseQuantity, TestPowEQ1)
|
||||
{
|
||||
Base::Quantity q1 {2, Base::Unit::Area};
|
||||
EXPECT_EQ(q1.pow(1), Base::Quantity(2, Base::Unit::Area));
|
||||
const Quantity q1 {2, Unit::Area};
|
||||
const auto expect = Quantity {2, Unit::Area};
|
||||
EXPECT_EQ(q1.pow(1), expect);
|
||||
}
|
||||
|
||||
TEST(BaseQuantity, TestPowEQ0)
|
||||
{
|
||||
Base::Quantity q1 {2, Base::Unit::Area};
|
||||
EXPECT_EQ(q1.pow(0), Base::Quantity {1});
|
||||
const Quantity q1 {2, Unit::Area};
|
||||
EXPECT_EQ(q1.pow(0), Quantity {1});
|
||||
}
|
||||
|
||||
TEST(BaseQuantity, TestPowGT1)
|
||||
{
|
||||
Base::Quantity q1 {2, Base::Unit::Length};
|
||||
EXPECT_EQ(q1.pow(2), Base::Quantity(4, Base::Unit::Area));
|
||||
constexpr auto v2 {2};
|
||||
constexpr auto v4 {4};
|
||||
const Quantity q1 {v2, Unit::Length};
|
||||
EXPECT_EQ(q1.pow(v2), Quantity(v4, Unit::Area));
|
||||
}
|
||||
|
||||
TEST(BaseQuantity, TestPowLT1)
|
||||
{
|
||||
Base::Quantity q1 {8, Base::Unit::Volume};
|
||||
EXPECT_EQ(q1.pow(1.0 / 3.0), Base::Quantity(2, Base::Unit::Length));
|
||||
constexpr auto v8 {8};
|
||||
constexpr auto v2 {2};
|
||||
constexpr auto v3 {3.0};
|
||||
const Quantity q1 {v8, Unit::Volume};
|
||||
EXPECT_EQ(q1.pow(1.0 / v3), Quantity(v2, Unit::Length));
|
||||
}
|
||||
|
||||
TEST(BaseQuantity, TestPow3DIV2)
|
||||
{
|
||||
Base::Quantity unit {8, Base::Unit::Volume};
|
||||
EXPECT_THROW(unit.pow(3.0 / 2.0), Base::UnitsMismatchError);
|
||||
constexpr auto v2 {2.0};
|
||||
constexpr auto v3 {3.0};
|
||||
constexpr auto v8 {8};
|
||||
const Quantity unit {v8, Unit::Volume};
|
||||
EXPECT_THROW(unit.pow(v3 / v2), UnitsMismatchError);
|
||||
}
|
||||
|
||||
TEST(BaseQuantity, TestString)
|
||||
{
|
||||
Base::Quantity q1 {2, "kg*m/s^2"};
|
||||
EXPECT_EQ(q1.getUnit(), Base::Unit::Force);
|
||||
constexpr auto v2 {2};
|
||||
const Quantity q1 {v2, "kg*m/s^2"};
|
||||
EXPECT_EQ(q1.getUnit(), Unit::Force);
|
||||
|
||||
Base::Quantity q2 {2, "kg*m^2/s^2"};
|
||||
EXPECT_EQ(q2.getUnit(), Base::Unit::Work);
|
||||
const Quantity q2 {v2, "kg*m^2/s^2"};
|
||||
EXPECT_EQ(q2.getUnit(), Unit::Work);
|
||||
}
|
||||
|
||||
TEST(BaseQuantity, TestCopy)
|
||||
{
|
||||
Base::Quantity q1 {1.0, Base::Unit::Length};
|
||||
const Quantity q1 {1.0, Unit::Length};
|
||||
|
||||
EXPECT_EQ(Base::Quantity {q1}, q1);
|
||||
EXPECT_EQ(Quantity {q1}, q1);
|
||||
}
|
||||
|
||||
TEST(BaseQuantity, TestEqual)
|
||||
{
|
||||
Base::Quantity q1 {1.0, Base::Unit::Force};
|
||||
Base::Quantity q2 {1.0, "kg*mm/s^2"};
|
||||
const Quantity q1 {1.0, Unit::Force};
|
||||
const Quantity q2 {1.0, "kg*mm/s^2"};
|
||||
|
||||
EXPECT_EQ(q1 == q1, true);
|
||||
EXPECT_EQ(q1 == q2, true);
|
||||
@@ -97,9 +109,10 @@ TEST(BaseQuantity, TestEqual)
|
||||
|
||||
TEST(BaseQuantity, TestNotEqual)
|
||||
{
|
||||
Base::Quantity q1 {1.0, Base::Unit::Force};
|
||||
Base::Quantity q2 {2.0, "kg*m/s^2"};
|
||||
Base::Quantity q3 {1.0, Base::Unit::Work};
|
||||
constexpr auto v2 {2.0};
|
||||
const Quantity q1 {1.0, Unit::Force};
|
||||
const Quantity q2 {v2, "kg*m/s^2"};
|
||||
const Quantity q3 {1.0, Unit::Work};
|
||||
|
||||
EXPECT_EQ(q1 != q2, true);
|
||||
EXPECT_EQ(q1 != q3, true);
|
||||
@@ -107,73 +120,77 @@ TEST(BaseQuantity, TestNotEqual)
|
||||
|
||||
TEST(BaseQuantity, TestLessOrGreater)
|
||||
{
|
||||
Base::Quantity q1 {1.0, Base::Unit::Force};
|
||||
Base::Quantity q2 {2.0, "kg*m/s^2"};
|
||||
Base::Quantity q3 {2.0, Base::Unit::Work};
|
||||
constexpr auto v2 {2.0};
|
||||
Quantity q1 {1.0, Unit::Force};
|
||||
Quantity q2 {v2, "kg*m/s^2"};
|
||||
Quantity q3 {v2, Unit::Work};
|
||||
|
||||
EXPECT_EQ(q1 < q2, true);
|
||||
EXPECT_EQ(q1 > q2, false);
|
||||
EXPECT_EQ(q1 <= q1, true);
|
||||
EXPECT_EQ(q1 >= q1, true);
|
||||
EXPECT_THROW(boost::ignore_unused(q1 < q3), Base::UnitsMismatchError);
|
||||
EXPECT_THROW(boost::ignore_unused(q1 > q3), Base::UnitsMismatchError);
|
||||
EXPECT_THROW(boost::ignore_unused(q1 <= q3), Base::UnitsMismatchError);
|
||||
EXPECT_THROW(boost::ignore_unused(q1 >= q3), Base::UnitsMismatchError);
|
||||
EXPECT_THROW(auto res [[maybe_unused]] = (q1 < q3), UnitsMismatchError);
|
||||
EXPECT_THROW(auto res [[maybe_unused]] = (q1 > q3), UnitsMismatchError);
|
||||
EXPECT_THROW(auto res [[maybe_unused]] = (q1 <= q3), UnitsMismatchError);
|
||||
EXPECT_THROW(auto res [[maybe_unused]] = (q1 >= q3), UnitsMismatchError);
|
||||
}
|
||||
|
||||
TEST(BaseQuantity, TestAdd)
|
||||
{
|
||||
Base::Quantity q1 {1.0, Base::Unit::Length};
|
||||
Base::Quantity q2 {1.0, Base::Unit::Area};
|
||||
EXPECT_THROW(q1 + q2, Base::UnitsMismatchError);
|
||||
EXPECT_THROW(q1 += q2, Base::UnitsMismatchError);
|
||||
EXPECT_EQ(q1 + q1, Base::Quantity(2, Base::Unit::Length));
|
||||
EXPECT_EQ(q1 += q1, Base::Quantity(2, Base::Unit::Length));
|
||||
Quantity q1 {1.0, Unit::Length};
|
||||
Quantity q2 {1.0, Unit::Area};
|
||||
EXPECT_THROW(q1 + q2, UnitsMismatchError);
|
||||
EXPECT_THROW(q1 += q2, UnitsMismatchError);
|
||||
EXPECT_EQ(q1 + q1, Quantity(2, Unit::Length));
|
||||
EXPECT_EQ(q1 += q1, Quantity(2, Unit::Length));
|
||||
}
|
||||
|
||||
TEST(BaseQuantity, TestSub)
|
||||
{
|
||||
Base::Quantity q1 {1.0, Base::Unit::Length};
|
||||
Base::Quantity q2 {1.0, Base::Unit::Area};
|
||||
EXPECT_THROW(q1 - q2, Base::UnitsMismatchError);
|
||||
EXPECT_THROW(q1 -= q2, Base::UnitsMismatchError);
|
||||
EXPECT_EQ(q1 - q1, Base::Quantity(0, Base::Unit::Length));
|
||||
EXPECT_EQ(q1 -= q1, Base::Quantity(0, Base::Unit::Length));
|
||||
Quantity q1 {1.0, Unit::Length};
|
||||
Quantity q2 {1.0, Unit::Area};
|
||||
EXPECT_THROW(q1 - q2, UnitsMismatchError);
|
||||
EXPECT_THROW(q1 -= q2, UnitsMismatchError);
|
||||
EXPECT_EQ(q1 - q1, Quantity(0, Unit::Length));
|
||||
EXPECT_EQ(q1 -= q1, Quantity(0, Unit::Length));
|
||||
}
|
||||
|
||||
TEST(BaseQuantity, TestNeg)
|
||||
{
|
||||
Base::Quantity q1 {1.0, Base::Unit::Length};
|
||||
EXPECT_EQ(-q1, Base::Quantity(-1.0, Base::Unit::Length));
|
||||
const Quantity q1 {1.0, Unit::Length};
|
||||
EXPECT_EQ(-q1, Quantity(-1.0, Unit::Length));
|
||||
}
|
||||
|
||||
TEST(BaseQuantity, TestMult)
|
||||
{
|
||||
Base::Quantity q1 {1.0, Base::Unit::Length};
|
||||
Base::Quantity q2 {1.0, Base::Unit::Area};
|
||||
EXPECT_EQ(q1 * q2, Base::Quantity(1.0, Base::Unit::Volume));
|
||||
EXPECT_EQ(q1 * 2.0, Base::Quantity(2.0, Base::Unit::Length));
|
||||
const Quantity q1 {1.0, Unit::Length};
|
||||
const Quantity q2 {1.0, Unit::Area};
|
||||
EXPECT_EQ(q1 * q2, Quantity(1.0, Unit::Volume));
|
||||
EXPECT_EQ(q1 * 2.0, Quantity(2.0, Unit::Length));
|
||||
}
|
||||
|
||||
TEST(BaseQuantity, TestDiv)
|
||||
{
|
||||
Base::Quantity q1 {1.0, Base::Unit::Length};
|
||||
Base::Quantity q2 {1.0, Base::Unit::Area};
|
||||
EXPECT_EQ(q1 / q2, Base::Quantity(1.0, Base::Unit::InverseLength));
|
||||
EXPECT_EQ(q1 / 2.0, Base::Quantity(0.5, Base::Unit::Length));
|
||||
const Quantity q1 {1.0, Unit::Length};
|
||||
const Quantity q2 {1.0, Unit::Area};
|
||||
EXPECT_EQ(q1 / q2, Quantity(1.0, Unit::InverseLength));
|
||||
EXPECT_EQ(q1 / 2.0, Quantity(0.5, Unit::Length));
|
||||
}
|
||||
|
||||
TEST(BaseQuantity, TestPow)
|
||||
{
|
||||
Base::Quantity q1 {2.0, Base::Unit::Length};
|
||||
Base::Quantity q2 {2.0, Base::Unit::Area};
|
||||
Base::Quantity q3 {0.0};
|
||||
EXPECT_EQ(q1.pow(q3), Base::Quantity {1});
|
||||
EXPECT_EQ(q1.pow(2.0), Base::Quantity(4, Base::Unit::Area));
|
||||
EXPECT_THROW(q1.pow(q2), Base::UnitsMismatchError);
|
||||
constexpr auto v2 {2.0};
|
||||
constexpr auto v4 {4};
|
||||
|
||||
Quantity q1 {v2, Unit::Length};
|
||||
Quantity q2 {v2, Unit::Area};
|
||||
Quantity q3 {0.0};
|
||||
EXPECT_EQ(q1.pow(q3), Quantity {1});
|
||||
EXPECT_EQ(q1.pow(v2), Quantity(v4, Unit::Area));
|
||||
EXPECT_THROW(q1.pow(q2), UnitsMismatchError);
|
||||
}
|
||||
|
||||
class Quantity: public ::testing::Test
|
||||
class BaseQuantityLoc: public ::testing::Test
|
||||
{
|
||||
protected:
|
||||
void SetUp() override
|
||||
@@ -185,60 +202,77 @@ protected:
|
||||
{}
|
||||
};
|
||||
|
||||
TEST_F(Quantity, TestSchemeImperialTwo)
|
||||
TEST_F(BaseQuantityLoc, psi_parse_spaced)
|
||||
{
|
||||
Base::Quantity quantity {1.0, Base::Unit::Length};
|
||||
|
||||
double factor {};
|
||||
std::string unitString;
|
||||
auto scheme = Base::UnitsApi::createSchema(Base::UnitSystem::ImperialDecimal);
|
||||
std::string result = scheme->schemaTranslate(quantity, factor, unitString);
|
||||
EXPECT_EQ(result, "0.04 in");
|
||||
const auto qParsed = Quantity::parse("1 psi");
|
||||
EXPECT_EQ(qParsed.getValue(), 6.8947448254939996);
|
||||
}
|
||||
|
||||
TEST_F(Quantity, TestSchemeImperialOne)
|
||||
TEST_F(BaseQuantityLoc, psi_parse_no_space)
|
||||
{
|
||||
Base::Quantity quantity {1.0, Base::Unit::Length};
|
||||
|
||||
Base::QuantityFormat format = quantity.getFormat();
|
||||
format.precision = 1;
|
||||
quantity.setFormat(format);
|
||||
|
||||
double factor {};
|
||||
std::string unitString;
|
||||
auto scheme = Base::UnitsApi::createSchema(Base::UnitSystem::ImperialDecimal);
|
||||
std::string result = scheme->schemaTranslate(quantity, factor, unitString);
|
||||
|
||||
EXPECT_EQ(result, "0.0 in");
|
||||
const auto qParsed = Quantity::parse("1psi");
|
||||
EXPECT_EQ(qParsed.getValue(), 6.8947448254939996);
|
||||
}
|
||||
|
||||
TEST_F(Quantity, TestSafeUserString)
|
||||
TEST_F(BaseQuantityLoc, psi_parse_user_str)
|
||||
{
|
||||
Base::UnitsApi::setSchema(Base::UnitSystem::ImperialDecimal);
|
||||
|
||||
Base::Quantity quantity {1.0, Base::Unit::Length};
|
||||
Base::QuantityFormat format = quantity.getFormat();
|
||||
format.precision = 1;
|
||||
quantity.setFormat(format);
|
||||
|
||||
std::string result = quantity.getSafeUserString();
|
||||
|
||||
EXPECT_EQ(result, "1 mm");
|
||||
|
||||
Base::UnitsApi::setSchema(Base::UnitSystem::Imperial1);
|
||||
|
||||
quantity = Base::Quantity {304.8, Base::Unit::Length};
|
||||
quantity.setFormat(format);
|
||||
|
||||
result = quantity.getSafeUserString();
|
||||
|
||||
EXPECT_EQ(result, "1.0 \\'");
|
||||
|
||||
quantity = Base::Quantity {25.4, Base::Unit::Length};
|
||||
quantity.setFormat(format);
|
||||
|
||||
result = quantity.getSafeUserString();
|
||||
|
||||
EXPECT_EQ(result, "1.0 \\\"");
|
||||
const auto qParsed = Quantity::parse("1 psi");
|
||||
EXPECT_EQ(qParsed.getUserString(), "6894.74 Pa");
|
||||
}
|
||||
|
||||
TEST_F(BaseQuantityLoc, psi_parse_safe_user_str)
|
||||
{
|
||||
const auto qParsed = Quantity::parse("1 psi");
|
||||
EXPECT_EQ(qParsed.getSafeUserString(), "6894.74 Pa");
|
||||
}
|
||||
|
||||
TEST_F(BaseQuantityLoc, psi_parse_unit_type)
|
||||
{
|
||||
const auto qParsed = Quantity::parse("1 psi");
|
||||
EXPECT_EQ(qParsed.getUnit().getTypeString(), "Pressure");
|
||||
}
|
||||
|
||||
TEST_F(BaseQuantityLoc, psi_to_Pa)
|
||||
{
|
||||
const auto result = Quantity::parse("1 psi").getValueAs(Quantity::Pascal);
|
||||
const auto expect = 6894.7448254939991;
|
||||
|
||||
EXPECT_EQ(result, expect);
|
||||
}
|
||||
|
||||
TEST_F(BaseQuantityLoc, psi_to_KPa)
|
||||
{
|
||||
const auto result = Quantity::parse("1 psi").getValueAs(Quantity::KiloPascal);
|
||||
const auto expect = 6.8947448254939996;
|
||||
|
||||
EXPECT_EQ(result, expect);
|
||||
}
|
||||
|
||||
TEST_F(BaseQuantityLoc, psi_to_MPa)
|
||||
{
|
||||
const auto result = Quantity::parse("1 psi").getValueAs(Quantity::MegaPascal);
|
||||
const auto expect = 0.0068947448254939999;
|
||||
|
||||
EXPECT_EQ(result, expect);
|
||||
}
|
||||
|
||||
TEST_F(BaseQuantityLoc, voltage_unit)
|
||||
{
|
||||
const auto qq = Quantity::parse("1e20 V");
|
||||
|
||||
EXPECT_EQ(qq.getUnit(), Unit::ElectricPotential);
|
||||
}
|
||||
|
||||
TEST_F(BaseQuantityLoc, voltage_val)
|
||||
{
|
||||
const auto qq = Quantity::parse("1e20 V");
|
||||
|
||||
EXPECT_EQ(qq.getValue(), 1e+26);
|
||||
}
|
||||
|
||||
TEST_F(BaseQuantityLoc, voltage_val_smaller)
|
||||
{
|
||||
const auto qq = Quantity::parse("1e3 V");
|
||||
|
||||
EXPECT_EQ(qq.getValue(), 1e+9);
|
||||
}
|
||||
// NOLINTEND
|
||||
|
||||
373
tests/src/Base/SchemaTests.cpp
Normal file
373
tests/src/Base/SchemaTests.cpp
Normal file
@@ -0,0 +1,373 @@
|
||||
/************************************************************************
|
||||
* *
|
||||
* This file is part of the FreeCAD CAx development system. *
|
||||
* *
|
||||
* This library is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU Library General Public *
|
||||
* License as published by the Free Software Foundation; either *
|
||||
* version 2 of the License, or (at your option) any later version. *
|
||||
* *
|
||||
* This library is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU Library General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU Library General Public *
|
||||
* License along with this library; see the file COPYING.LIB. If not, *
|
||||
* write to the Free Software Foundation, Inc., 59 Temple Place, *
|
||||
* Suite 330, Boston, MA 02111-1307, USA *
|
||||
* *
|
||||
************************************************************************/
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
#include "Base/Exception.h"
|
||||
#include "Base/Unit.h"
|
||||
#include "Base/Quantity.h"
|
||||
#include "Base/UnitsApi.h"
|
||||
#include "Base/UnitsSchemasData.h"
|
||||
#include "Base/UnitsSchemas.h"
|
||||
|
||||
#include <QLocale>
|
||||
#include <string>
|
||||
|
||||
using Base::Quantity;
|
||||
using Base::QuantityFormat;
|
||||
using Base::RuntimeError;
|
||||
using Base::Unit;
|
||||
using Base::UnitsApi;
|
||||
using Base::UnitsSchema;
|
||||
using Base::UnitsSchemas;
|
||||
|
||||
class SchemaTest: public testing::Test
|
||||
{
|
||||
protected:
|
||||
void SetUp() override
|
||||
{
|
||||
const QLocale loc(QLocale::C);
|
||||
QLocale::setDefault(loc);
|
||||
}
|
||||
|
||||
void TearDown() override
|
||||
{}
|
||||
|
||||
static std::string
|
||||
set(const std::string& schemaName, const Unit unit, const double value) // NOLINT
|
||||
{
|
||||
UnitsApi::setSchema(schemaName);
|
||||
const auto quantity = Quantity {value, unit};
|
||||
return quantity.getSafeUserString();
|
||||
}
|
||||
|
||||
static std::string setWithPrecision(const std::string& name,
|
||||
const double value,
|
||||
const Unit unit,
|
||||
const int precision)
|
||||
{
|
||||
UnitsApi::setSchema(name);
|
||||
Quantity quantity {value, unit};
|
||||
QuantityFormat format = quantity.getFormat();
|
||||
format.precision = precision;
|
||||
quantity.setFormat(format);
|
||||
return quantity.getSafeUserString();
|
||||
}
|
||||
|
||||
std::unique_ptr<UnitsSchemas> schemas; // NOLINT
|
||||
};
|
||||
|
||||
TEST_F(SchemaTest, imperial_decimal_1_mm_default_precision)
|
||||
{
|
||||
const std::string result = set("ImperialDecimal", Unit::Length, 1.0);
|
||||
const auto expect {"0.04 in"};
|
||||
|
||||
EXPECT_EQ(result, expect);
|
||||
}
|
||||
|
||||
TEST_F(SchemaTest, internal_1_mm_precision_0)
|
||||
{
|
||||
const std::string result = setWithPrecision("Internal", 1.0, Unit::Length, 0);
|
||||
const auto expect {"1 mm"};
|
||||
|
||||
EXPECT_EQ(result, expect);
|
||||
}
|
||||
|
||||
TEST_F(SchemaTest, internal_100_mm_precision_0)
|
||||
{
|
||||
const std::string result = setWithPrecision("Internal", 100.0, Unit::Length, 0);
|
||||
const auto expect {"100 mm"};
|
||||
|
||||
EXPECT_EQ(result, expect);
|
||||
}
|
||||
|
||||
TEST_F(SchemaTest, internal_100_mm_precision_1)
|
||||
{
|
||||
const std::string result = setWithPrecision("Internal", 100.0, Unit::Length, 1);
|
||||
const auto expect {"100.0 mm"};
|
||||
|
||||
EXPECT_EQ(result, expect);
|
||||
}
|
||||
|
||||
TEST_F(SchemaTest, internal_20000_mm_precision_2)
|
||||
{
|
||||
const std::string result = setWithPrecision("Internal", 20000.0, Unit::Length, 2);
|
||||
const auto expect {"20.00 m"};
|
||||
|
||||
EXPECT_EQ(result, expect);
|
||||
}
|
||||
|
||||
TEST_F(SchemaTest, imperial_decimal_1_mm_precision_0)
|
||||
{
|
||||
const std::string result = setWithPrecision("ImperialDecimal", 1.0, Unit::Length, 0);
|
||||
const auto expect {"1 mm"};
|
||||
|
||||
EXPECT_EQ(result, expect);
|
||||
}
|
||||
|
||||
TEST_F(SchemaTest, imperial_decimal_10_mm_precision_0)
|
||||
{
|
||||
const std::string result = setWithPrecision("ImperialDecimal", 10.0, Unit::Length, 0);
|
||||
const auto expect {"10 mm"};
|
||||
// https://github.com/FreeCAD/FreeCAD/commit/569154b73f818c6a88b010def687d5e684ce64c2
|
||||
|
||||
EXPECT_EQ(result, expect);
|
||||
}
|
||||
|
||||
TEST_F(SchemaTest, imperial_decimal_20_mm_precision_0)
|
||||
{
|
||||
const std::string result = setWithPrecision("ImperialDecimal", 20.0, Unit::Length, 0);
|
||||
const auto expect {"1 in"};
|
||||
|
||||
EXPECT_EQ(result, expect);
|
||||
}
|
||||
|
||||
TEST_F(SchemaTest, imperial_1_mm_precision_0)
|
||||
{
|
||||
const std::string result = setWithPrecision("Imperial", 1.0, Unit::Length, 0);
|
||||
const auto expect {"39 thou"};
|
||||
|
||||
EXPECT_EQ(result, expect);
|
||||
}
|
||||
|
||||
TEST_F(SchemaTest, imperial_0_mm_precision_0)
|
||||
{
|
||||
const std::string result = setWithPrecision("Imperial", 0.0, Unit::Length, 0);
|
||||
const auto expect {"0 in"};
|
||||
|
||||
EXPECT_EQ(result, expect);
|
||||
}
|
||||
|
||||
TEST_F(SchemaTest, imperial_0_mm_precision_1)
|
||||
{
|
||||
const std::string result = setWithPrecision("Imperial", 0.0, Unit::Length, 1);
|
||||
const auto expect {"0.0 in"};
|
||||
|
||||
EXPECT_EQ(result, expect);
|
||||
}
|
||||
|
||||
TEST_F(SchemaTest, imperial_decimal_0_mm_precision_0)
|
||||
{
|
||||
const std::string result = setWithPrecision("ImperialDecimal", 0.0, Unit::Length, 0);
|
||||
const auto expect {"0 in"};
|
||||
|
||||
EXPECT_EQ(result, expect);
|
||||
}
|
||||
|
||||
TEST_F(SchemaTest, imperial_decimal_0_mm_precision_1)
|
||||
{
|
||||
const std::string result = setWithPrecision("ImperialDecimal", 0.0, Unit::Length, 1);
|
||||
const auto expect {"0.0 in"};
|
||||
|
||||
EXPECT_EQ(result, expect);
|
||||
}
|
||||
|
||||
TEST_F(SchemaTest, imperial_civil_0_mm_precision_0)
|
||||
{
|
||||
const std::string result = setWithPrecision("ImperialCivil", 0.0, Unit::Length, 0);
|
||||
const auto expect {"0 mm"};
|
||||
|
||||
EXPECT_EQ(result, expect);
|
||||
}
|
||||
|
||||
TEST_F(SchemaTest, imperial_civil_0_mm_precision_1)
|
||||
{
|
||||
const std::string result = setWithPrecision("ImperialCivil", 0.0, Unit::Length, 1);
|
||||
const auto expect {"0.0 mm"};
|
||||
|
||||
EXPECT_EQ(result, expect);
|
||||
}
|
||||
|
||||
TEST_F(SchemaTest, imperial_building_0_mm_precision_0)
|
||||
{
|
||||
const std::string result = setWithPrecision("ImperialBuilding", 0.0, Unit::Length, 0);
|
||||
const auto expect {"0"}; // don't know why
|
||||
|
||||
EXPECT_EQ(result, expect);
|
||||
}
|
||||
|
||||
TEST_F(SchemaTest, imperial_building_0_mm_precision_1)
|
||||
{
|
||||
const std::string result = setWithPrecision("ImperialBuilding", 0.0, Unit::Length, 1);
|
||||
const auto expect {"0"}; // don't know why
|
||||
|
||||
EXPECT_EQ(result, expect);
|
||||
}
|
||||
|
||||
TEST_F(SchemaTest, imperial_decimal_1_mm_precision_1)
|
||||
{
|
||||
const std::string result = setWithPrecision("ImperialDecimal", 1.0, Unit::Length, 1);
|
||||
const auto expect {"1 mm"};
|
||||
|
||||
EXPECT_EQ(result, expect);
|
||||
}
|
||||
|
||||
TEST_F(SchemaTest, imperial_decimal_100_mm_precision_0)
|
||||
{
|
||||
const std::string result = setWithPrecision("ImperialDecimal", 100.0, Unit::Length, 0);
|
||||
const auto expect {"4 in"};
|
||||
|
||||
EXPECT_EQ(result, expect);
|
||||
}
|
||||
|
||||
TEST_F(SchemaTest, imperial_decimal_100_mm_precision_1)
|
||||
{
|
||||
const std::string result = setWithPrecision("ImperialDecimal", 100.0, Unit::Length, 1);
|
||||
const auto expect {"3.9 in"};
|
||||
|
||||
EXPECT_EQ(result, expect);
|
||||
}
|
||||
|
||||
TEST_F(SchemaTest, imperial_decimal_100_mm_precision_2)
|
||||
{
|
||||
const std::string result = setWithPrecision("ImperialDecimal", 100.0, Unit::Length, 2);
|
||||
const auto expect {"3.94 in"};
|
||||
|
||||
EXPECT_EQ(result, expect);
|
||||
}
|
||||
|
||||
TEST_F(SchemaTest, imperial_decimal_1_mm_precision_2)
|
||||
{
|
||||
const std::string result = setWithPrecision("ImperialDecimal", 1.0, Unit::Length, 2);
|
||||
const auto expect {"0.04 in"};
|
||||
|
||||
EXPECT_EQ(result, expect);
|
||||
}
|
||||
|
||||
TEST_F(SchemaTest, imperial_decimal_1_mm_precision_4)
|
||||
{
|
||||
const std::string result = setWithPrecision("ImperialDecimal", 1.0, Unit::Length, 4);
|
||||
const auto expect {"0.0394 in"};
|
||||
|
||||
EXPECT_EQ(result, expect);
|
||||
}
|
||||
|
||||
TEST_F(SchemaTest, imperial_safe_user_str_same)
|
||||
{
|
||||
constexpr auto val {304.8};
|
||||
const auto result = set("Imperial", Unit::Length, val);
|
||||
const auto expect {"1.00′"};
|
||||
|
||||
EXPECT_EQ(result, expect);
|
||||
}
|
||||
|
||||
TEST_F(SchemaTest, imperial_safe_user_str_more)
|
||||
{
|
||||
constexpr auto val {310.0};
|
||||
const auto result = set("Imperial", Unit::Length, val);
|
||||
const auto expect {"1.02′"};
|
||||
|
||||
EXPECT_EQ(result, expect);
|
||||
}
|
||||
|
||||
TEST_F(SchemaTest, imperial_safe_user_str_less)
|
||||
{
|
||||
constexpr auto val {300.0};
|
||||
const auto result = set("Imperial", Unit::Length, val);
|
||||
const auto expect {"11.81″"};
|
||||
|
||||
EXPECT_EQ(result, expect);
|
||||
}
|
||||
|
||||
TEST_F(SchemaTest, imperial_safe_user_str_one_inch)
|
||||
{
|
||||
constexpr auto val {25.4};
|
||||
const auto result = set("Imperial", Unit::Length, val);
|
||||
const auto expect {"1.00″"};
|
||||
|
||||
EXPECT_EQ(result, expect);
|
||||
}
|
||||
|
||||
TEST_F(SchemaTest, imperial_building_special_function_length_inch)
|
||||
{
|
||||
constexpr auto val {25.4};
|
||||
const auto result = set("ImperialBuilding", Unit::Length, val);
|
||||
const auto expect {"1″"};
|
||||
|
||||
EXPECT_EQ(result, expect);
|
||||
}
|
||||
|
||||
TEST_F(SchemaTest, imperial_building_special_function_length_foot)
|
||||
{
|
||||
constexpr auto val {25.4 * 12};
|
||||
const auto result = set("ImperialBuilding", Unit::Length, val);
|
||||
const auto expect {"1′"};
|
||||
|
||||
EXPECT_EQ(result, expect);
|
||||
}
|
||||
|
||||
TEST_F(SchemaTest, imperial_building_special_function_length)
|
||||
{
|
||||
constexpr auto val {360.6};
|
||||
const auto result = set("ImperialBuilding", Unit::Length, val);
|
||||
const auto expect {"1′2-1/4″"};
|
||||
|
||||
EXPECT_EQ(result, expect);
|
||||
}
|
||||
|
||||
TEST_F(SchemaTest, imperial_building_special_function_length_neg)
|
||||
{
|
||||
constexpr auto val {-360.6};
|
||||
const auto result = set("ImperialBuilding", Unit::Length, val);
|
||||
const auto expect {"-1′2-1/4″"};
|
||||
|
||||
EXPECT_EQ(result, expect);
|
||||
}
|
||||
|
||||
TEST_F(SchemaTest, imperial_civil_special_function_angle_degrees)
|
||||
{
|
||||
constexpr auto val {180};
|
||||
const auto result = set("ImperialCivil", Unit::Angle, val);
|
||||
const auto expect {"180°"};
|
||||
|
||||
EXPECT_EQ(result, expect);
|
||||
}
|
||||
|
||||
TEST_F(SchemaTest, imperial_civil_special_function_angle_minutes)
|
||||
{
|
||||
constexpr auto val {180.5};
|
||||
const auto result = set("ImperialCivil", Unit::Angle, val);
|
||||
const auto expect {"180°30′"};
|
||||
|
||||
EXPECT_EQ(result, expect);
|
||||
}
|
||||
|
||||
TEST_F(SchemaTest, imperial_civil_special_function_angle_seconds)
|
||||
{
|
||||
constexpr auto val {180.11};
|
||||
const auto result = set("ImperialCivil", Unit::Angle, val);
|
||||
const auto expect {"180°6′36″"};
|
||||
|
||||
EXPECT_EQ(result, expect);
|
||||
}
|
||||
|
||||
TEST_F(SchemaTest, imperial_civil_special_function_angle_no_degrees)
|
||||
{
|
||||
constexpr auto val {0.11};
|
||||
const auto result = set("ImperialCivil", Unit::Angle, val);
|
||||
const auto expect {"0°6′36″"};
|
||||
|
||||
EXPECT_EQ(result, expect);
|
||||
}
|
||||
|
||||
TEST_F(SchemaTest, unknown_schema_name_throws)
|
||||
{
|
||||
EXPECT_THROW(UnitsApi::setSchema("Unknown"), RuntimeError);
|
||||
}
|
||||
@@ -130,7 +130,7 @@ TEST_F(TestMaterialValue, TestQuantityType)
|
||||
EXPECT_EQ(variant.toString().size(), 0);
|
||||
auto quantity = variant.value<Base::Quantity>();
|
||||
EXPECT_FALSE(quantity.isValid());
|
||||
EXPECT_EQ(quantity.getUserString(), "nan ");
|
||||
EXPECT_EQ(quantity.getUserString(), "nan");
|
||||
EXPECT_TRUE(std::isnan(quantity.getValue()));
|
||||
|
||||
// Test a copy
|
||||
@@ -146,7 +146,7 @@ TEST_F(TestMaterialValue, TestQuantityType)
|
||||
EXPECT_EQ(variant.toString().size(), 0);
|
||||
quantity = variant.value<Base::Quantity>();
|
||||
EXPECT_FALSE(quantity.isValid());
|
||||
EXPECT_EQ(quantity.getUserString(), "nan ");
|
||||
EXPECT_EQ(quantity.getUserString(), "nan");
|
||||
EXPECT_TRUE(std::isnan(quantity.getValue()));
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user