FreeCAD

Форк
0
/
UnitsApiPy.cpp 
226 строк · 7.5 Кб
1
/***************************************************************************
2
 *   Copyright (c) Jürgen Riegel <juergen.riegel@web.de>                   *
3
 *                                                                         *
4
 *   This file is part of the FreeCAD CAx development system.              *
5
 *                                                                         *
6
 *   This library is free software; you can redistribute it and/or         *
7
 *   modify it under the terms of the GNU Library General Public           *
8
 *   License as published by the Free Software Foundation; either          *
9
 *   version 2 of the License, or (at your option) any later version.      *
10
 *                                                                         *
11
 *   This library  is distributed in the hope that it will be useful,      *
12
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
13
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
14
 *   GNU Library General Public License for more details.                  *
15
 *                                                                         *
16
 *   You should have received a copy of the GNU Library General Public     *
17
 *   License along with this library; see the file COPYING.LIB. If not,    *
18
 *   write to the Free Software Foundation, Inc., 59 Temple Place,         *
19
 *   Suite 330, Boston, MA  02111-1307, USA                                *
20
 *                                                                         *
21
 ***************************************************************************/
22

23

24
#include "PreCompiled.h"
25

26
#ifndef _PreComp_
27
#include <memory>
28
#endif
29

30
#include <CXX/Objects.hxx>
31

32
#include "UnitsApi.h"
33
#include "Quantity.h"
34
#include "QuantityPy.h"
35

36

37
using namespace Base;
38

39
//**************************************************************************
40
// Python stuff of UnitsApi
41

42
// UnitsApi Methods
43
PyMethodDef UnitsApi::Methods[] = {
44
    {"parseQuantity",
45
     UnitsApi::sParseQuantity,
46
     METH_VARARGS,
47
     "parseQuantity(string) -> Base.Quantity()\n\n"
48
     "calculate a mathematical expression with units to a quantity object. \n"
49
     "can be used for simple unit translation like: \n"
50
     "parseQuantity('10m')\n"
51
     "or for more complex espressions:\n"
52
     "parseQuantity('sin(pi)/50.0 m/s^2')\n"},
53
    {"listSchemas",
54
     UnitsApi::sListSchemas,
55
     METH_VARARGS,
56
     "listSchemas() -> a tuple of schemas\n\n"
57
     "listSchemas(int) -> description of the given schema\n\n"},
58
    {"getSchema",
59
     UnitsApi::sGetSchema,
60
     METH_VARARGS,
61
     "getSchema() -> int\n\n"
62
     "The int is the position of the tuple returned by listSchemas"},
63
    {"setSchema",
64
     UnitsApi::sSetSchema,
65
     METH_VARARGS,
66
     "setSchema(int) -> None\n\n"
67
     "Sets the current schema to the given number, if possible"},
68
    {"schemaTranslate",
69
     UnitsApi::sSchemaTranslate,
70
     METH_VARARGS,
71
     "schemaTranslate(Quantity, int) -> tuple\n\n"
72
     "Translate a quantity to a given schema"},
73
    {"toNumber",
74
     UnitsApi::sToNumber,
75
     METH_VARARGS,
76
     "toNumber(Quantity or float, [format='g', decimals=-1]) -> str\n\n"
77
     "Convert a quantity or float to a string"},
78

79
    {nullptr, nullptr, 0, nullptr} /* Sentinel */
80
};
81

82
PyObject* UnitsApi::sParseQuantity(PyObject* /*self*/, PyObject* args)
83
{
84
    char* pstr {};
85
    if (!PyArg_ParseTuple(args, "et", "utf-8", &pstr)) {
86
        return nullptr;
87
    }
88

89
    Quantity rtn;
90
    QString qstr = QString::fromUtf8(pstr);
91
    PyMem_Free(pstr);
92
    try {
93
        rtn = Quantity::parse(qstr);
94
    }
95
    catch (const Base::ParserError&) {
96
        PyErr_Format(PyExc_ValueError, "invalid unit expression \n");
97
        return nullptr;
98
    }
99

100
    return new QuantityPy(new Quantity(rtn));
101
}
102

103
PyObject* UnitsApi::sListSchemas(PyObject* /*self*/, PyObject* args)
104
{
105
    if (PyArg_ParseTuple(args, "")) {
106
        int num = static_cast<int>(UnitSystem::NumUnitSystemTypes);
107
        Py::Tuple tuple(num);
108
        for (int i = 0; i < num; i++) {
109
            const auto description {
110
                UnitsApi::getDescription(static_cast<UnitSystem>(i)).toStdString()};
111
            tuple.setItem(i, Py::String(description.c_str()));
112
        }
113

114
        return Py::new_reference_to(tuple);
115
    }
116

117
    PyErr_Clear();
118
    int index {};
119
    if (PyArg_ParseTuple(args, "i", &index)) {
120
        int num = static_cast<int>(UnitSystem::NumUnitSystemTypes);
121
        if (index < 0 || index >= num) {
122
            PyErr_SetString(PyExc_ValueError, "invalid schema value");
123
            return nullptr;
124
        }
125

126
        const auto description {
127
            UnitsApi::getDescription(static_cast<UnitSystem>(index)).toStdString()};
128
        return Py_BuildValue("s", description.c_str());
129
    }
130

131
    PyErr_SetString(PyExc_TypeError, "int or empty argument list expected");
132
    return nullptr;
133
}
134

135
PyObject* UnitsApi::sGetSchema(PyObject* /*self*/, PyObject* args)
136
{
137
    if (!PyArg_ParseTuple(args, "")) {
138
        return nullptr;
139
    }
140

141
    return Py_BuildValue("i", static_cast<int>(currentSystem));
142
}
143

144
PyObject* UnitsApi::sSetSchema(PyObject* /*self*/, PyObject* args)
145
{
146
    PyErr_Clear();
147
    int index {};
148
    if (PyArg_ParseTuple(args, "i", &index)) {
149
        int num = static_cast<int>(UnitSystem::NumUnitSystemTypes);
150
        if (index < 0 || index >= num) {
151
            PyErr_SetString(PyExc_ValueError, "invalid schema value");
152
            return nullptr;
153
        }
154
        setSchema(static_cast<UnitSystem>(index));
155
    }
156
    Py_Return;
157
}
158

159
PyObject* UnitsApi::sSchemaTranslate(PyObject* /*self*/, PyObject* args)
160
{
161
    PyObject* py {};
162
    int index {};
163
    if (!PyArg_ParseTuple(args, "O!i", &(QuantityPy::Type), &py, &index)) {
164
        return nullptr;
165
    }
166

167
    Quantity quant;
168
    quant = *static_cast<Base::QuantityPy*>(py)->getQuantityPtr();
169

170
    std::unique_ptr<UnitsSchema> schema(createSchema(static_cast<UnitSystem>(index)));
171
    if (!schema) {
172
        PyErr_SetString(PyExc_ValueError, "invalid schema value");
173
        return nullptr;
174
    }
175

176
    double factor {};
177
    QString uus;
178
    QString uss = schema->schemaTranslate(quant, factor, uus);
179

180
    Py::Tuple res(3);
181
    res[0] = Py::String(uss.toUtf8(), "utf-8");
182
    res[1] = Py::Float(factor);
183
    res[2] = Py::String(uus.toUtf8(), "utf-8");
184

185
    return Py::new_reference_to(res);
186
}
187

188
PyObject* UnitsApi::sToNumber(PyObject* /*self*/, PyObject* args)
189
{
190
    double value {};
191
    const char* format = "g";
192
    int decimals {};
193
    do {
194
        PyObject* py {};
195
        if (PyArg_ParseTuple(args, "O!|si", &(QuantityPy::Type), &py, &format, &decimals)) {
196
            value = static_cast<QuantityPy*>(py)->getQuantityPtr()->getValue();
197
            break;
198
        }
199

200
        PyErr_Clear();
201
        if (PyArg_ParseTuple(args, "d|si", &value, &format, &decimals)) {
202
            break;
203
        }
204

205
        PyErr_SetString(PyExc_TypeError, "toNumber(Quantity or float, [format='g', decimals=-1])");
206
        return nullptr;
207
    } while (false);
208

209
    if (strlen(format) != 1) {
210
        PyErr_SetString(PyExc_ValueError, "Format string hasn't length of 1");
211
        return nullptr;
212
    }
213

214
    bool ok {};
215
    QuantityFormat qf;
216
    qf.format = QuantityFormat::toFormat(format[0], &ok);
217
    qf.precision = decimals;
218

219
    if (!ok) {
220
        PyErr_SetString(PyExc_ValueError, "Invalid format string");
221
        return nullptr;
222
    }
223

224
    QString string = toNumber(value, qf);
225
    return Py::new_reference_to(Py::String(string.toStdString()));
226
}
227

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.