Merge pull request #20540 from 3x380V/cleanup-schemas-management
Simplify UnitsSchemas management
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");
|
||||
|
||||
@@ -877,13 +877,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
|
||||
|
||||
@@ -26,14 +26,16 @@
|
||||
#include <cmath>
|
||||
#include <limits>
|
||||
#include <numbers>
|
||||
#include <string>
|
||||
#endif
|
||||
|
||||
#include <fmt/format.h>
|
||||
#include <Base/Tools.h>
|
||||
|
||||
#include "Exception.h"
|
||||
#include "Quantity.h"
|
||||
#include "Tools.h"
|
||||
#include "UnitsApi.h"
|
||||
#include "UnitsSchema.h"
|
||||
|
||||
/** \defgroup Units Units system
|
||||
\ingroup BASE
|
||||
@@ -50,7 +52,9 @@
|
||||
#pragma warning(disable : 4335) // disable MAC file format warning on VC
|
||||
#endif
|
||||
|
||||
using namespace Base;
|
||||
using Base::Quantity;
|
||||
using Base::QuantityFormat;
|
||||
using Base::UnitsSchema;
|
||||
|
||||
// ====== Static attributes =========================
|
||||
// NOLINTNEXTLINE
|
||||
@@ -60,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)
|
||||
{}
|
||||
|
||||
@@ -237,6 +241,13 @@ Quantity Quantity::operator-() const
|
||||
return Quantity(-(this->myValue), this->myUnit);
|
||||
}
|
||||
|
||||
std::string Quantity::getUserString() const
|
||||
{
|
||||
double dummy1 {}; // to satisfy GCC
|
||||
std::string dummy2 {};
|
||||
return getUserString(dummy1, dummy2);
|
||||
}
|
||||
|
||||
std::string Quantity::getUserString(double& factor, std::string& unitString) const
|
||||
{
|
||||
return Base::UnitsApi::schemaTranslate(*this, factor, unitString);
|
||||
@@ -245,20 +256,18 @@ 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 ret = getUserString();
|
||||
if (this->myValue) {
|
||||
auto feedbackQty = parse(ret);
|
||||
auto feedbackVal = feedbackQty.getValue();
|
||||
if (feedbackVal == 0) {
|
||||
ret = fmt::format("{} {}", this->myValue, this->getUnit().getString());
|
||||
}
|
||||
auto userStr = getUserString();
|
||||
if (myValue != 0.0 && parse(userStr).getValue() == 0) {
|
||||
auto unitStr = getUnit().getString();
|
||||
userStr = fmt::format("{}{}{}", myValue, unitStr.empty() ? "" : " ", unitStr);
|
||||
}
|
||||
return Base::Tools::escapeQuotesFromString(ret);
|
||||
|
||||
return Tools::escapeQuotesFromString(userStr);
|
||||
}
|
||||
|
||||
/// true if it has a number without a unit
|
||||
|
||||
@@ -156,14 +156,10 @@ public:
|
||||
{
|
||||
myFormat = fmt;
|
||||
}
|
||||
|
||||
std::string getUserString() const;
|
||||
/// transfer to user preferred unit/potence
|
||||
std::string getUserString(double& factor, std::string& unitString) const;
|
||||
std::string getUserString() const
|
||||
{ // to satisfy GCC
|
||||
double dummy1 {};
|
||||
std::string dummy2 {};
|
||||
return getUserString(dummy1, dummy2);
|
||||
}
|
||||
std::string getUserString(UnitsSchema* schema, double& factor, std::string& unitString) const;
|
||||
std::string getSafeUserString() const;
|
||||
|
||||
|
||||
@@ -22,7 +22,12 @@
|
||||
|
||||
#include "PreCompiled.h"
|
||||
#ifndef _PreComp_
|
||||
#include <cmath>
|
||||
#include <limits>
|
||||
#include <optional>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#endif
|
||||
|
||||
#include "Unit.h"
|
||||
@@ -33,7 +38,7 @@
|
||||
|
||||
#include "UnitPy.h"
|
||||
|
||||
using namespace Base;
|
||||
using Base::Quantity;
|
||||
|
||||
// returns a string which represents the object e.g. when printed in python
|
||||
std::string QuantityPy::representation() const
|
||||
@@ -181,84 +186,128 @@ PyObject* QuantityPy::getUserPreferred(PyObject* /*args*/) const
|
||||
|
||||
PyObject* QuantityPy::getValueAs(PyObject* args) const
|
||||
{
|
||||
Quantity quant;
|
||||
quant.setInvalid();
|
||||
|
||||
// first try Quantity
|
||||
if (!quant.isValid()) {
|
||||
auto tryQuantity = [&]() -> std::optional<Quantity> {
|
||||
PyObject* object {};
|
||||
if (PyArg_ParseTuple(args, "O!", &(QuantityPy::Type), &object)) {
|
||||
quant = *static_cast<QuantityPy*>(object)->getQuantityPtr();
|
||||
if (!PyArg_ParseTuple(args, "O!", &(QuantityPy::Type), &object)) {
|
||||
return std::nullopt;
|
||||
}
|
||||
}
|
||||
|
||||
if (!quant.isValid()) {
|
||||
return *getQuantityPtr();
|
||||
};
|
||||
|
||||
auto tryUnit = [&]() -> std::optional<Quantity> {
|
||||
PyObject* object {};
|
||||
PyErr_Clear();
|
||||
if (PyArg_ParseTuple(args, "O!", &(UnitPy::Type), &object)) {
|
||||
quant.setUnit(*static_cast<UnitPy*>(object)->getUnitPtr());
|
||||
quant.setValue(1.0);
|
||||
if (!PyArg_ParseTuple(args, "O!", &(UnitPy::Type), &object)) {
|
||||
return std::nullopt;
|
||||
}
|
||||
}
|
||||
|
||||
if (!quant.isValid()) {
|
||||
return Quantity {1.0, *static_cast<UnitPy*>(object)->getUnitPtr()};
|
||||
};
|
||||
|
||||
auto tryUnitAndValue = [&]() -> std::optional<Quantity> {
|
||||
PyObject* object {};
|
||||
double value {};
|
||||
PyErr_Clear();
|
||||
if (PyArg_ParseTuple(args, "dO!", &value, &(UnitPy::Type), &object)) {
|
||||
quant.setUnit(*static_cast<UnitPy*>(object)->getUnitPtr());
|
||||
quant.setValue(value);
|
||||
if (!PyArg_ParseTuple(args, "dO!", &value, &(UnitPy::Type), &object)) {
|
||||
return std::nullopt;
|
||||
}
|
||||
}
|
||||
|
||||
if (!quant.isValid()) {
|
||||
return Quantity {value, *static_cast<UnitPy*>(object)->getUnitPtr()};
|
||||
};
|
||||
|
||||
auto tryUnitPartsAndValue = [&]() -> std::optional<Quantity> {
|
||||
double f = std::numeric_limits<double>::max();
|
||||
int i1 = 0;
|
||||
int i2 = 0;
|
||||
int i3 = 0;
|
||||
int i4 = 0;
|
||||
int i5 = 0;
|
||||
int i6 = 0;
|
||||
int i7 = 0;
|
||||
int i8 = 0;
|
||||
int i1 {0};
|
||||
int i2 {0};
|
||||
int i3 {0};
|
||||
int i4 {0};
|
||||
int i5 {0};
|
||||
int i6 {0};
|
||||
int i7 {0};
|
||||
int i8 {0};
|
||||
PyErr_Clear();
|
||||
if (PyArg_ParseTuple(args, "d|iiiiiiii", &f, &i1, &i2, &i3, &i4, &i5, &i6, &i7, &i8)) {
|
||||
if (f < std::numeric_limits<double>::max()) {
|
||||
quant = Quantity(f,
|
||||
Unit {static_cast<int8_t>(i1),
|
||||
static_cast<int8_t>(i2),
|
||||
static_cast<int8_t>(i3),
|
||||
static_cast<int8_t>(i4),
|
||||
static_cast<int8_t>(i5),
|
||||
static_cast<int8_t>(i6),
|
||||
static_cast<int8_t>(i7),
|
||||
static_cast<int8_t>(i8)});
|
||||
if (!PyArg_ParseTuple(args, "d|iiiiiiii", &f, &i1, &i2, &i3, &i4, &i5, &i6, &i7, &i8)) {
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
if (f >= std::numeric_limits<double>::max()) {
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
auto re = [](auto val) {
|
||||
return static_cast<int8_t>(val);
|
||||
};
|
||||
|
||||
return Quantity {f, Unit {re(i1), re(i2), re(i3), re(i4), re(i5), re(i6), re(i7), re(i8)}};
|
||||
};
|
||||
|
||||
auto tryString = [&]() -> std::optional<Quantity> {
|
||||
char* string {};
|
||||
if (!PyArg_ParseTuple(args, "et", "utf-8", &string)) {
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
const std::string str {string};
|
||||
PyMem_Free(string);
|
||||
return Quantity::parse(str);
|
||||
};
|
||||
|
||||
const std::vector<std::function<std::optional<Quantity>()>> funcs = {tryQuantity,
|
||||
tryUnit,
|
||||
tryUnitAndValue,
|
||||
tryUnitPartsAndValue,
|
||||
tryString};
|
||||
|
||||
auto tryFuncs = [&]() -> std::optional<Quantity> {
|
||||
for (const auto& func : funcs) {
|
||||
PyErr_Clear();
|
||||
if (auto quant = func(); quant.has_value()) {
|
||||
return quant;
|
||||
}
|
||||
}
|
||||
return std::nullopt;
|
||||
};
|
||||
|
||||
auto checkQuant = [&](const Quantity& quant) -> bool {
|
||||
auto err = [&](const std::string& str) {
|
||||
PyErr_SetString(PyExc_ValueError, str.c_str());
|
||||
};
|
||||
|
||||
const auto* qPtr = getQuantityPtr();
|
||||
if (!qPtr) {
|
||||
err("QuantityPtr is null");
|
||||
return false;
|
||||
}
|
||||
|
||||
const auto qpUnit = qPtr->getUnit();
|
||||
if (qpUnit.isEmpty()) {
|
||||
err("QuantityPtr returned empty unit");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (const auto qUnit = quant.getUnit(); qUnit != qpUnit) {
|
||||
err("Unit mismatch (`" + qUnit.getString() + "` != `" + qpUnit.getString() + "`)");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
//----------------------------------------------------------------------------------------------
|
||||
|
||||
const auto optQuant = tryFuncs();
|
||||
if (!optQuant.has_value()) {
|
||||
PyErr_SetString(PyExc_TypeError, "Expected quantity, string, float or unit");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (!quant.isValid()) {
|
||||
PyErr_Clear();
|
||||
char* string {};
|
||||
if (PyArg_ParseTuple(args, "et", "utf-8", &string)) {
|
||||
std::string str(string);
|
||||
PyMem_Free(string);
|
||||
quant = Quantity::parse(str);
|
||||
const auto quant = optQuant.value();
|
||||
if (quant.isQuantity()) {
|
||||
if (!checkQuant(quant)) {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
if (!quant.isValid()) {
|
||||
PyErr_SetString(PyExc_TypeError, "Either quantity, string, float or unit expected");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (getQuantityPtr()->getUnit() != quant.getUnit() && quant.isQuantity()) {
|
||||
PyErr_SetString(PyExc_ValueError, "Unit mismatch");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
quant = Quantity(getQuantityPtr()->getValueAs(quant));
|
||||
return new QuantityPy(new Quantity(quant));
|
||||
return new QuantityPy(new Quantity(getQuantityPtr()->getValue() / quant.getValue()));
|
||||
}
|
||||
|
||||
PyObject* QuantityPy::__round__(PyObject* args) const
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
|
||||
#include "MainWindow.h"
|
||||
|
||||
#if 0 // needed for Qt's lupdate utility
|
||||
#if 0 // needed for Qt's lupdate utility
|
||||
qApp->translate("Gui::Dialog::DlgSettingsDocument", "All rights reserved");
|
||||
qApp->translate("Gui::Dialog::DlgSettingsDocument", "Creative Commons Attribution");
|
||||
qApp->translate("Gui::Dialog::DlgSettingsDocument", "Creative Commons Attribution-ShareAlike");
|
||||
@@ -64,8 +64,12 @@ using namespace Gui::Dialog;
|
||||
* The dialog will by default be modeless, unless you set 'modal' to
|
||||
* true to construct a modal dialog.
|
||||
*/
|
||||
DlgProjectInformationImp::DlgProjectInformationImp(App::Document* doc, QWidget* parent, Qt::WindowFlags fl)
|
||||
: QDialog(parent, fl), _doc(doc), ui(new Ui_DlgProjectInformation)
|
||||
DlgProjectInformationImp::DlgProjectInformationImp(App::Document* doc,
|
||||
QWidget* parent,
|
||||
Qt::WindowFlags fl)
|
||||
: QDialog(parent, fl)
|
||||
, _doc(doc)
|
||||
, ui(new Ui_DlgProjectInformation)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
ui->lineEditName->setText(QString::fromUtf8(doc->Label.getValue()));
|
||||
@@ -79,11 +83,12 @@ DlgProjectInformationImp::DlgProjectInformationImp(App::Document* doc, QWidget*
|
||||
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
|
||||
@@ -114,11 +119,15 @@ DlgProjectInformationImp::DlgProjectInformationImp(App::Document* doc, QWidget*
|
||||
QStringList lines = comment.split(QLatin1String("\\n"), Qt::KeepEmptyParts);
|
||||
|
||||
QString text = lines.join(QLatin1String("\n"));
|
||||
ui->textEditComment->setPlainText( text );
|
||||
connect(ui->pushButtonOpenURL, &QPushButton::clicked,
|
||||
this, &DlgProjectInformationImp::open_url);
|
||||
connect(ui->comboLicense, qOverload<int>(&QComboBox::currentIndexChanged),
|
||||
this, &DlgProjectInformationImp::onLicenseTypeChanged);
|
||||
ui->textEditComment->setPlainText(text);
|
||||
connect(ui->pushButtonOpenURL,
|
||||
&QPushButton::clicked,
|
||||
this,
|
||||
&DlgProjectInformationImp::open_url);
|
||||
connect(ui->comboLicense,
|
||||
qOverload<int>(&QComboBox::currentIndexChanged),
|
||||
this,
|
||||
&DlgProjectInformationImp::onLicenseTypeChanged);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -148,8 +157,8 @@ void DlgProjectInformationImp::accept()
|
||||
_doc->LicenseURL.setValue(ui->lineEditLicenseURL->text().toUtf8());
|
||||
|
||||
// Replace newline escape sequence through '\\n' string
|
||||
QStringList lines = ui->textEditComment->toPlainText().split
|
||||
(QLatin1String("\n"), Qt::KeepEmptyParts);
|
||||
QStringList lines =
|
||||
ui->textEditComment->toPlainText().split(QLatin1String("\n"), Qt::KeepEmptyParts);
|
||||
|
||||
QString text = lines.join(QLatin1String("\\n"));
|
||||
_doc->Comment.setValue(text.isEmpty() ? QByteArray() : text.toUtf8());
|
||||
@@ -159,8 +168,9 @@ void DlgProjectInformationImp::accept()
|
||||
|
||||
void DlgProjectInformationImp::onLicenseTypeChanged(int index)
|
||||
{
|
||||
const char* url {index >= 0 && index < App::countOfLicenses ? App::licenseItems.at(index).at(App::posnOfUrl)
|
||||
: _doc->LicenseURL.getValue()};
|
||||
const char* url {index >= 0 && index < App::countOfLicenses
|
||||
? App::licenseItems.at(index).at(App::posnOfUrl)
|
||||
: _doc->LicenseURL.getValue()};
|
||||
|
||||
ui->lineEditLicenseURL->setText(QString::fromLatin1(url));
|
||||
}
|
||||
|
||||
@@ -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,23 +118,16 @@ 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
|
||||
if (UnitsApi::getSchema() == UnitSystem::ImperialBuilding)
|
||||
{
|
||||
ui->comboBox_FracInch->setVisible(true);
|
||||
ui->fractionalInchLabel->setVisible(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
ui->comboBox_FracInch->setVisible(false);
|
||||
ui->fractionalInchLabel->setVisible(false);
|
||||
}
|
||||
const auto visible = UnitsApi::isMultiUnitLength();
|
||||
ui->comboBox_FracInch->setVisible(visible);
|
||||
ui->fractionalInchLabel->setVisible(visible);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -211,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
|
||||
@@ -225,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();
|
||||
@@ -294,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.
|
||||
@@ -536,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)
|
||||
@@ -768,22 +762,16 @@ 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
|
||||
if (static_cast<UnitSystem>(index) == UnitSystem::ImperialBuilding)
|
||||
{
|
||||
ui->comboBox_FracInch->setVisible(true);
|
||||
ui->fractionalInchLabel->setVisible(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
ui->comboBox_FracInch->setVisible(false);
|
||||
ui->fractionalInchLabel->setVisible(false);
|
||||
}
|
||||
const auto visible = UnitsApi::isMultiUnitLength();
|
||||
ui->comboBox_FracInch->setVisible(visible);
|
||||
ui->fractionalInchLabel->setVisible(visible);
|
||||
}
|
||||
|
||||
void DlgSettingsGeneral::onThemeChanged(int index) {
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -27,6 +27,7 @@ Test module for FreeCAD material cards and APIs
|
||||
import unittest
|
||||
import FreeCAD
|
||||
import Materials
|
||||
import sys
|
||||
|
||||
parseQuantity = FreeCAD.Units.parseQuantity
|
||||
|
||||
@@ -37,6 +38,15 @@ class MaterialTestCases(unittest.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
""" Setup function to initialize test data """
|
||||
# The test for ThermalExpansionCoefficient causes problems with some localizations
|
||||
# due to the Unicode mu ('\u03bc') character in the units. This will happen with
|
||||
# locales that don't support UTF8 such as zh_CN (It does support UTF-8)
|
||||
try:
|
||||
sys.stdout.reconfigure(errors='replace')
|
||||
except:
|
||||
# reconfigure appeared in 3.7, hope for the best...
|
||||
pass
|
||||
|
||||
self.ModelManager = Materials.ModelManager()
|
||||
self.MaterialManager = Materials.MaterialManager()
|
||||
self.uuids = Materials.UUIDs()
|
||||
@@ -145,12 +155,6 @@ class MaterialTestCases(unittest.TestCase):
|
||||
self.assertIn("SpecularColor", properties)
|
||||
self.assertIn("Transparency", properties)
|
||||
|
||||
#
|
||||
# The test for ThermalExpansionCoefficient causes problems with some localizations
|
||||
# due to the Unicode mu character in the units. This will happen with
|
||||
# locales that don't support UTF8 such as zh_CN (It does support UTF-8)
|
||||
#
|
||||
# When this is a problem simply comment the lines printing ThermalExpansionCoefficient
|
||||
print("Density " + properties["Density"])
|
||||
# print("BulkModulus " + properties["BulkModulus"])
|
||||
print("PoissonRatio " + properties["PoissonRatio"])
|
||||
|
||||
@@ -2100,100 +2100,77 @@ void EditModeConstraintCoinManager::rebuildConstraintNodes(
|
||||
|
||||
QString EditModeConstraintCoinManager::getPresentationString(const Constraint* constraint)
|
||||
{
|
||||
std::string nameStr; // name parameter string
|
||||
QString valueStr; // dimensional value string
|
||||
std::string unitStr; // the actual unit string
|
||||
std::string baseUnitStr; // the expected base unit string
|
||||
double factor; // unit scaling factor, currently not used
|
||||
Base::UnitSystem unitSys; // current unit system
|
||||
|
||||
if (!constraint->isActive) {
|
||||
return QStringLiteral(" ");
|
||||
}
|
||||
|
||||
// Get the current name parameter string of the constraint
|
||||
nameStr = constraint->Name;
|
||||
/**
|
||||
* Hide units if
|
||||
* - user has requested it,
|
||||
* - is being displayed in the base units, -and-
|
||||
* - the schema being used has a clear base unit in the first place.
|
||||
*
|
||||
* Remove unit string if expected unit string matches actual unit string
|
||||
* Example code from: Mod/TechDraw/App/DrawViewDimension.cpp:372
|
||||
*
|
||||
* Hide the default length unit
|
||||
*/
|
||||
auto fixValueStr = [&](const QString& valueStr, const auto& unitStr) -> std::optional<QString> {
|
||||
if (!constraintParameters.bHideUnits || constraint->Type == Sketcher::Angle) {
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
const auto baseUnitStr {Base::UnitsApi::getBasicLengthUnit()};
|
||||
if (baseUnitStr.empty() || baseUnitStr != unitStr) {
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
// trailing space or non-dig
|
||||
const QRegularExpression rxUnits {QString::fromUtf8(" \\D*$")};
|
||||
auto vStr = valueStr;
|
||||
vStr.remove(rxUnits);
|
||||
return {vStr};
|
||||
};
|
||||
|
||||
// Get the current value string including units
|
||||
valueStr =
|
||||
QString::fromStdString(constraint->getPresentationValue().getUserString(factor, unitStr));
|
||||
double factor {};
|
||||
std::string unitStr; // the actual unit string
|
||||
const auto constrPresValue {constraint->getPresentationValue().getUserString(factor, unitStr)};
|
||||
auto valueStr = QString::fromStdString(constrPresValue);
|
||||
|
||||
// Hide units if user has requested it, is being displayed in the base
|
||||
// units, and the schema being used has a clear base unit in the first
|
||||
// place. Otherwise, display units.
|
||||
if (constraintParameters.bHideUnits && constraint->Type != Sketcher::Angle) {
|
||||
// Only hide the default length unit. Right now there is not an easy way
|
||||
// to get that from the Unit system so we have to manually add it here.
|
||||
// Hopefully this can be added in the future so this code won't have to
|
||||
// be updated if a new units schema is added.
|
||||
unitSys = Base::UnitsApi::getSchema();
|
||||
|
||||
// If this is a supported unit system then define what the base unit is.
|
||||
switch (unitSys) {
|
||||
case Base::UnitSystem::SI1:
|
||||
case Base::UnitSystem::MmMin:
|
||||
baseUnitStr = "mm";
|
||||
break;
|
||||
|
||||
case Base::UnitSystem::SI2:
|
||||
baseUnitStr = "m";
|
||||
break;
|
||||
|
||||
case Base::UnitSystem::ImperialDecimal:
|
||||
baseUnitStr = "in";
|
||||
break;
|
||||
|
||||
case Base::UnitSystem::Centimeters:
|
||||
baseUnitStr = "cm";
|
||||
break;
|
||||
|
||||
default:
|
||||
// Nothing to do
|
||||
break;
|
||||
}
|
||||
|
||||
if (!baseUnitStr.empty()) {
|
||||
// expected unit string matches actual unit string. remove.
|
||||
if (baseUnitStr.compare(unitStr) == 0) {
|
||||
// Example code from: Mod/TechDraw/App/DrawViewDimension.cpp:372
|
||||
QRegularExpression rxUnits(
|
||||
QStringLiteral(" \\D*$")); // space + any non digits at end of string
|
||||
valueStr.remove(rxUnits); // getUserString(defaultDecimals) without units
|
||||
}
|
||||
}
|
||||
auto fixedValueStr = fixValueStr(valueStr, unitStr).value_or(valueStr);
|
||||
switch (constraint->Type) {
|
||||
case Sketcher::Diameter:
|
||||
fixedValueStr.prepend(QChar(0x2300));
|
||||
break;
|
||||
case Sketcher::Radius:
|
||||
fixedValueStr.prepend(QLatin1Char('R'));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (constraint->Type == Sketcher::Diameter) {
|
||||
valueStr.prepend(QChar(216)); // Diameter sign
|
||||
}
|
||||
else if (constraint->Type == Sketcher::Radius) {
|
||||
valueStr.prepend(QChar(82)); // Capital letter R
|
||||
if (!constraintParameters.bShowDimensionalName || constraint->Name.empty()) {
|
||||
return fixedValueStr;
|
||||
}
|
||||
|
||||
/**
|
||||
Create the representation string from the user defined format string
|
||||
Format options are:
|
||||
%N - the constraint name parameter
|
||||
%V - the value of the dimensional constraint, including any unit characters
|
||||
*/
|
||||
if (constraintParameters.bShowDimensionalName && !nameStr.empty()) {
|
||||
QString presentationStr;
|
||||
if (constraintParameters.sDimensionalStringFormat.contains(QLatin1String("%V"))
|
||||
|| constraintParameters.sDimensionalStringFormat.contains(QLatin1String("%N"))) {
|
||||
presentationStr = constraintParameters.sDimensionalStringFormat;
|
||||
presentationStr.replace(QLatin1String("%N"), QString::fromStdString(nameStr));
|
||||
presentationStr.replace(QLatin1String("%V"), valueStr);
|
||||
}
|
||||
else {
|
||||
// user defined format string does not contain any valid parameter, using default format
|
||||
// "%N = %V"
|
||||
presentationStr = QString::fromStdString(nameStr) + QStringLiteral(" = ") + valueStr;
|
||||
}
|
||||
* Create the representation string from the user defined format string
|
||||
* Format options are:
|
||||
* %N - the constraint name parameter
|
||||
* %V - the value of the dimensional constraint, including any unit characters
|
||||
*/
|
||||
auto sDimFmt {constraintParameters.sDimensionalStringFormat};
|
||||
if (!sDimFmt.contains(QLatin1String("%V"))
|
||||
&& !sDimFmt.contains(QLatin1String("%N"))) { // using default format "%N = %V"
|
||||
|
||||
return presentationStr;
|
||||
return QString::fromStdString(constraint->Name) + QString::fromLatin1(" = ") + valueStr;
|
||||
}
|
||||
|
||||
return valueStr;
|
||||
sDimFmt.replace(QLatin1String("%N"), QString::fromStdString(constraint->Name));
|
||||
sDimFmt.replace(QLatin1String("%V"), fixedValueStr);
|
||||
|
||||
return sDimFmt;
|
||||
}
|
||||
|
||||
std::set<int> EditModeConstraintCoinManager::detectPreselectionConstr(const SoPickedPoint* Point,
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -39,17 +39,11 @@ using namespace TechDraw;
|
||||
|
||||
bool DimensionFormatter::isMultiValueSchema() const
|
||||
{
|
||||
bool angularMeasure = (m_dimension->Type.isValue("Angle") ||
|
||||
m_dimension->Type.isValue("Angle3Pt"));
|
||||
const bool angularMeasure =
|
||||
(m_dimension->Type.isValue("Angle") || m_dimension->Type.isValue("Angle3Pt"));
|
||||
|
||||
if (Base::UnitsApi::isMultiUnitAngle() &&
|
||||
angularMeasure) {
|
||||
return true;
|
||||
} else if (Base::UnitsApi::isMultiUnitLength() &&
|
||||
!angularMeasure) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
return (Base::UnitsApi::isMultiUnitAngle() && angularMeasure)
|
||||
|| (Base::UnitsApi::isMultiUnitLength() && !angularMeasure);
|
||||
}
|
||||
|
||||
std::string DimensionFormatter::formatValue(const qreal value,
|
||||
@@ -57,145 +51,117 @@ std::string DimensionFormatter::formatValue(const qreal value,
|
||||
const Format partial,
|
||||
const bool isDim) const
|
||||
{
|
||||
// Base::Console().Message("DF::formatValue() - %s isRestoring: %d\n",
|
||||
// m_dimension->getNameInDocument(), m_dimension->isRestoring());
|
||||
bool angularMeasure = m_dimension->Type.isValue("Angle") || m_dimension->Type.isValue("Angle3Pt");
|
||||
bool areaMeasure = m_dimension->Type.isValue("Area");
|
||||
QLocale loc;
|
||||
const bool angularMeasure =
|
||||
m_dimension->Type.isValue("Angle") || m_dimension->Type.isValue("Angle3Pt");
|
||||
const bool areaMeasure = m_dimension->Type.isValue("Area");
|
||||
|
||||
Base::Quantity asQuantity;
|
||||
asQuantity.setValue(value);
|
||||
Base::Unit unit;
|
||||
if (angularMeasure) {
|
||||
asQuantity.setUnit(Base::Unit::Angle);
|
||||
unit = Base::Unit::Angle;
|
||||
}
|
||||
else if (areaMeasure) {
|
||||
asQuantity.setUnit(Base::Unit::Area);
|
||||
unit = Base::Unit::Area;
|
||||
}
|
||||
else {
|
||||
asQuantity.setUnit(Base::Unit::Length);
|
||||
unit = Base::Unit::Length;
|
||||
}
|
||||
|
||||
Base::Quantity asQuantity {value, unit};
|
||||
|
||||
QStringList qsl = getPrefixSuffixSpec(qFormatSpec);
|
||||
const std::string formatPrefix = qsl[0].toStdString();
|
||||
const std::string formatSuffix = qsl[1].toStdString();
|
||||
QString formatSpecifier = qsl[2];
|
||||
|
||||
// this handles mm to inch/km/parsec etc and decimal positions but
|
||||
// won't give more than Global_Decimals precision
|
||||
QString qUserString = QString::fromStdString(asQuantity.getUserString());
|
||||
std::string basicString = formatPrefix + asQuantity.getUserString() + formatSuffix;
|
||||
|
||||
//get formatSpec prefix/suffix/specifier
|
||||
QStringList qsl = getPrefixSuffixSpec(qFormatSpec);
|
||||
QString formatPrefix = qsl[0]; //FormatSpec prefix
|
||||
QString formatSuffix = qsl[1]; //FormatSpec suffix
|
||||
QString formatSpecifier = qsl[2]; //FormatSpec specifier
|
||||
|
||||
QString qMultiValueStr;
|
||||
QString qBasicUnit = QString::fromStdString(Base::UnitsApi::getBasicLengthUnit());
|
||||
|
||||
QString formattedValue;
|
||||
if (isMultiValueSchema() && partial == Format::UNALTERED) {
|
||||
//handle multi value schemes (yd/ft/in, dms, etc). don't even try to use Alt Decimals or hide units
|
||||
qMultiValueStr = formatPrefix + qUserString + formatSuffix;
|
||||
return qMultiValueStr.toStdString();
|
||||
} else {
|
||||
//not multivalue schema
|
||||
if (formatSpecifier.isEmpty()) {
|
||||
Base::Console().Warning("Warning - no numeric format in Format Spec %s - %s\n",
|
||||
qPrintable(qFormatSpec), m_dimension->getNameInDocument());
|
||||
return qFormatSpec.toStdString();
|
||||
}
|
||||
return basicString; // Don't even try to use Alt Decimals or hide units
|
||||
}
|
||||
|
||||
// for older TD drawings the formatSpecifier "%g" was used, but the number of decimals was
|
||||
// neverheless limited. To keep old drawings, we limit the number of decimals too
|
||||
// if the TD preferences option to use the global decimal number is set
|
||||
// the formatSpecifier can have a prefix and/or suffix
|
||||
if (m_dimension->useDecimals() && formatSpecifier.contains(QStringLiteral("%g"), Qt::CaseInsensitive)) {
|
||||
int globalPrecision = Base::UnitsApi::getDecimals();
|
||||
// change formatSpecifier to e.g. "%.2f"
|
||||
QString newSpecifier = QString::fromStdString("%." + std::to_string(globalPrecision) + "f");
|
||||
formatSpecifier.replace(QStringLiteral("%g"), newSpecifier, Qt::CaseInsensitive);
|
||||
}
|
||||
if (formatSpecifier.isEmpty()) {
|
||||
Base::Console().Warning("Warning - no numeric format in Format Spec %s - %s\n",
|
||||
qPrintable(qFormatSpec),
|
||||
m_dimension->getNameInDocument());
|
||||
return qFormatSpec.toStdString();
|
||||
}
|
||||
|
||||
// since we are not using a multiValueSchema, we know that angles are in '°' and for
|
||||
// lengths we can get the unit of measure from UnitsApi::getBasicLengthUnit.
|
||||
// for older TD drawings the formatSpecifier "%g" was used, but the number of decimals was
|
||||
// nevertheless limited. To keep old drawings, we limit the number of decimals too
|
||||
// if the TD preferences option to use the global decimal number is set
|
||||
// the formatSpecifier can have a prefix and/or suffix
|
||||
if (m_dimension->useDecimals()
|
||||
&& formatSpecifier.contains(QStringLiteral("%g"), Qt::CaseInsensitive)) {
|
||||
const int globalPrecision = Base::UnitsApi::getDecimals();
|
||||
// change formatSpecifier to e.g. "%.2f"
|
||||
const QString newSpecifier =
|
||||
QString::fromStdString("%." + std::to_string(globalPrecision) + "f");
|
||||
formatSpecifier.replace(QStringLiteral("%g"), newSpecifier, Qt::CaseInsensitive);
|
||||
}
|
||||
|
||||
// TODO: check the weird schemas (MKS, Imperial1)that report different UoM
|
||||
// for different values
|
||||
// since we are not using a multiValueSchema, we know that angles are in '°' and for
|
||||
// lengths we can get the unit of measure from UnitsApi::getBasicLengthUnit.
|
||||
|
||||
// get value in the base unit with default decimals
|
||||
// for the conversion we use the same method as in DlgUnitsCalculator::valueChanged
|
||||
// get the conversion factor for the unit
|
||||
// the result is now just val / convertValue because val is always in the base unit
|
||||
// don't do this for angular values since they are not in the BaseLengthUnit
|
||||
double userVal;
|
||||
if (angularMeasure) {
|
||||
userVal = asQuantity.getValue();
|
||||
qBasicUnit = QStringLiteral("°");
|
||||
}
|
||||
else {
|
||||
double convertValue = Base::Quantity::parse("1" + qBasicUnit.toStdString()).getValue();
|
||||
userVal = asQuantity.getValue() / convertValue;
|
||||
if (areaMeasure) {
|
||||
userVal = userVal / convertValue; // divide again as area is length²
|
||||
qBasicUnit = qBasicUnit + QStringLiteral("²");
|
||||
}
|
||||
}
|
||||
// TODO: check the weird schemas (MKS, Imperial1) that report different UoM for different values
|
||||
|
||||
if (isTooSmall(userVal, formatSpecifier)) {
|
||||
Base::Console().Warning("Dimension %s value %.6f is too small for format specifier: %s\n",
|
||||
m_dimension->getNameInDocument(), userVal, qPrintable(formatSpecifier));
|
||||
}
|
||||
// get value in the base unit with default decimals
|
||||
// for the conversion we use the same method as in DlgUnitsCalculator::valueChanged
|
||||
// get the conversion factor for the unit
|
||||
// the result is now just val / convertValue because val is always in the base unit
|
||||
// don't do this for angular values since they are not in the BaseLengthUnit
|
||||
std::string qBasicUnit =
|
||||
angularMeasure ? "°" : Base::UnitsApi::getBasicLengthUnit();
|
||||
double userVal = asQuantity.getValue();
|
||||
|
||||
formattedValue = formatValueToSpec(userVal, formatSpecifier);
|
||||
|
||||
// replace decimal sign if necessary
|
||||
QChar dp = QChar::fromLatin1('.');
|
||||
if (loc.decimalPoint() != dp) {
|
||||
formattedValue.replace(dp, loc.decimalPoint());
|
||||
if (!angularMeasure) {
|
||||
const double convertValue = Base::Quantity::parse("1" + qBasicUnit).getValue();
|
||||
userVal /= convertValue;
|
||||
if (areaMeasure) {
|
||||
userVal /= convertValue; // divide again as area is length²
|
||||
qBasicUnit += "²";
|
||||
}
|
||||
}
|
||||
|
||||
//formattedValue is now in formatSpec format with local decimal separator
|
||||
if (isTooSmall(userVal, formatSpecifier)) {
|
||||
Base::Console().Warning("Dimension %s value %.6f is too small for format specifier: %s\n",
|
||||
m_dimension->getNameInDocument(),
|
||||
userVal,
|
||||
qPrintable(formatSpecifier));
|
||||
}
|
||||
|
||||
QString formattedValue = formatValueToSpec(userVal, formatSpecifier);
|
||||
|
||||
// replace decimal sign if necessary
|
||||
constexpr QChar dp = QChar::fromLatin1('.');
|
||||
if (const QLocale loc; loc.decimalPoint() != dp) {
|
||||
formattedValue.replace(dp, loc.decimalPoint());
|
||||
}
|
||||
|
||||
// formattedValue is now in formatSpec format with local decimal separator
|
||||
std::string formattedValueString = formattedValue.toStdString();
|
||||
if (partial == Format::UNALTERED) { // prefix + unit subsystem string + suffix
|
||||
return formatPrefix.toStdString() +
|
||||
qUserString.toStdString() +
|
||||
formatSuffix.toStdString();
|
||||
|
||||
if (partial == Format::UNALTERED) {
|
||||
return basicString;
|
||||
}
|
||||
else if (partial == Format::FORMATTED) {
|
||||
|
||||
if (partial == Format::FORMATTED) {
|
||||
std::string unitStr {};
|
||||
|
||||
if (angularMeasure) {
|
||||
//always insert unit after value
|
||||
return formatPrefix.toStdString() + formattedValueString + "°" +
|
||||
formatSuffix.toStdString();
|
||||
unitStr = "°";
|
||||
}
|
||||
else if (m_dimension->showUnits() || areaMeasure){
|
||||
if (isDim && m_dimension->haveTolerance()) {
|
||||
//unit will be included in tolerance so don't repeat it here
|
||||
return formatPrefix.toStdString() +
|
||||
formattedValueString +
|
||||
formatSuffix.toStdString();
|
||||
}
|
||||
else {
|
||||
//no tolerance, so we need to include unit
|
||||
return formatPrefix.toStdString() +
|
||||
formattedValueString + " " +
|
||||
qBasicUnit.toStdString() +
|
||||
formatSuffix.toStdString();
|
||||
}
|
||||
}
|
||||
else {
|
||||
//showUnits is false
|
||||
return formatPrefix.toStdString() +
|
||||
formattedValueString +
|
||||
formatSuffix.toStdString();
|
||||
else if ((m_dimension->showUnits() || areaMeasure)
|
||||
&& !(isDim && m_dimension->haveTolerance())) {
|
||||
unitStr = " " + qBasicUnit;
|
||||
}
|
||||
|
||||
return formatPrefix + formattedValueString + unitStr + formatSuffix;
|
||||
}
|
||||
else if (partial == Format::UNIT) {
|
||||
if (angularMeasure) {
|
||||
return qBasicUnit.toStdString();
|
||||
}
|
||||
else if (m_dimension->showUnits() || areaMeasure) {
|
||||
return qBasicUnit.toStdString();
|
||||
}
|
||||
else {
|
||||
return "";
|
||||
}
|
||||
|
||||
if (partial == Format::UNIT) {
|
||||
return angularMeasure || m_dimension->showUnits() || areaMeasure ? qBasicUnit : "";
|
||||
}
|
||||
|
||||
return formattedValueString;
|
||||
@@ -368,13 +334,10 @@ QString DimensionFormatter::formatValueToSpec(const double value, QString format
|
||||
|
||||
bool DimensionFormatter::isNumericFormat(const QString& formatSpecifier) const
|
||||
{
|
||||
QRegularExpression rxFormat(QStringLiteral("%[+-]?[0-9]*\\.*[0-9]*[aefgwAEFGW]")); //printf double format spec
|
||||
//printf double format spec
|
||||
const QRegularExpression rxFormat(QStringLiteral("%[+-]?[0-9]*\\.*[0-9]*[aefgwAEFGW]"));
|
||||
QRegularExpressionMatch rxMatch;
|
||||
int pos = formatSpecifier.indexOf(rxFormat, 0, &rxMatch);
|
||||
if (pos != -1) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
return formatSpecifier.indexOf(rxFormat, 0, &rxMatch) != -1;
|
||||
}
|
||||
|
||||
//TODO: similar code here and above
|
||||
|
||||
@@ -41,28 +41,28 @@ public:
|
||||
UNIT // return only the unit of measure
|
||||
};
|
||||
|
||||
DimensionFormatter() {}
|
||||
DimensionFormatter(DrawViewDimension* dim) { m_dimension = dim; }
|
||||
DimensionFormatter() = default;
|
||||
explicit DimensionFormatter(DrawViewDimension* dim)
|
||||
: m_dimension {dim}
|
||||
{}
|
||||
~DimensionFormatter() = default;
|
||||
|
||||
//void setDimension(DrawViewDimension* dim) { m_dimension = dim; }
|
||||
bool isMultiValueSchema() const;
|
||||
std::string formatValue(const qreal value,
|
||||
const QString& qFormatSpec,
|
||||
const Format partial,
|
||||
const bool isDim) const;
|
||||
std::string getFormattedToleranceValue(const Format partial) const;
|
||||
std::pair<std::string, std::string> getFormattedToleranceValues(const Format partial) const;
|
||||
std::string getFormattedDimensionValue(const Format partial) const;
|
||||
std::string formatValue(qreal value, const QString& qFormatSpec, Format partial, bool isDim) const;
|
||||
std::string getFormattedToleranceValue(Format partial) const;
|
||||
std::pair<std::string, std::string> getFormattedToleranceValues(Format partial) const;
|
||||
std::string getFormattedDimensionValue(Format partial) const;
|
||||
QStringList getPrefixSuffixSpec(const QString& fSpec) const;
|
||||
std::string getDefaultFormatSpec(bool isToleranceFormat) const;
|
||||
bool isTooSmall(const double value, const QString& formatSpec) const;
|
||||
QString formatValueToSpec(const double value, QString formatSpecifier) const;
|
||||
bool isNumericFormat(const QString& formatSpecifier) const;
|
||||
|
||||
private:
|
||||
DrawViewDimension* m_dimension;
|
||||
bool isTooSmall(double value, const QString& formatSpec) const;
|
||||
QString formatValueToSpec(double value, QString formatSpecifier) const;
|
||||
bool isNumericFormat(const QString& formatSpecifier) const;
|
||||
|
||||
DrawViewDimension* m_dimension {nullptr};
|
||||
};
|
||||
|
||||
} //end namespace TechDraw
|
||||
} // end namespace TechDraw
|
||||
#endif
|
||||
|
||||
@@ -96,9 +96,9 @@ class UnitBasicCases(unittest.TestCase):
|
||||
qu2 = FreeCAD.Units.Quantity("m/s")
|
||||
self.assertTrue(qu1 / qu2, 1)
|
||||
|
||||
def testSchemes(self):
|
||||
schemes = FreeCAD.Units.listSchemas()
|
||||
num = len(schemes)
|
||||
def testSchemas(self):
|
||||
schemas = FreeCAD.Units.listSchemas()
|
||||
num = len(schemas)
|
||||
|
||||
psi = FreeCAD.Units.parseQuantity("1psi")
|
||||
for i in range(num):
|
||||
@@ -108,7 +108,7 @@ class UnitBasicCases(unittest.TestCase):
|
||||
1,
|
||||
v.Value,
|
||||
msg='Failed with "{0}" scheme: {1} != 1 (delta: {2})'.format(
|
||||
schemes[i], v.Value, self.delta
|
||||
schemas[i], v.Value, self.delta
|
||||
),
|
||||
delta=self.delta,
|
||||
)
|
||||
@@ -121,7 +121,7 @@ class UnitBasicCases(unittest.TestCase):
|
||||
1,
|
||||
v.Value,
|
||||
msg='Failed with "{0}" scheme: {1} != 1 (delta: {2})'.format(
|
||||
schemes[i], v.Value, self.delta
|
||||
schemas[i], v.Value, self.delta
|
||||
),
|
||||
delta=self.delta,
|
||||
)
|
||||
@@ -135,7 +135,7 @@ class UnitBasicCases(unittest.TestCase):
|
||||
1,
|
||||
v.Value,
|
||||
msg='Failed with "{0}" scheme: {1} != 1 (delta: {2})'.format(
|
||||
schemes[i], v.Value, self.delta
|
||||
schemas[i], v.Value, self.delta
|
||||
),
|
||||
delta=self.delta,
|
||||
)
|
||||
@@ -146,12 +146,12 @@ class UnitBasicCases(unittest.TestCase):
|
||||
if issubclass(type(getattr(FreeCAD.Units, i)), FreeCAD.Units.Quantity):
|
||||
quantities.append(i)
|
||||
|
||||
schemes = FreeCAD.Units.listSchemas()
|
||||
schemas = FreeCAD.Units.listSchemas()
|
||||
for i in quantities:
|
||||
q1 = getattr(FreeCAD.Units, i)
|
||||
q1 = FreeCAD.Units.Quantity(q1)
|
||||
q1.Format = {"Precision": 16}
|
||||
for idx, val in enumerate(schemes):
|
||||
for idx, val in enumerate(schemas):
|
||||
[t, amountPerUnit, unit] = FreeCAD.Units.schemaTranslate(q1, idx)
|
||||
try:
|
||||
q2 = FreeCAD.Units.Quantity(t)
|
||||
|
||||
Reference in New Issue
Block a user