some fixes and comparison interface for Unit and Quantity python objects
This commit is contained in:
parent
01d69071b6
commit
272e60671b
|
@ -10,19 +10,19 @@
|
|||
#* *
|
||||
#* This file is part of the FreeCAD CAx development system. *
|
||||
#* *
|
||||
#* This program is free software; you can redistribute it and/or modify *
|
||||
#* This program is free software you can redistribute it and/or modify *
|
||||
#* it under the terms of the GNU Lesser General Public License (LGPL) *
|
||||
#* as published by the Free Software Foundation; either version 2 of *
|
||||
#* as published by the Free Software Foundation either version 2 of *
|
||||
#* the License, or (at your option) any later version. *
|
||||
#* for detail see the LICENCE text file. *
|
||||
#* *
|
||||
#* FreeCAD is distributed in the hope that it will be useful, *
|
||||
#* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
#* but WITHOUT ANY WARRANTY without even the implied warranty of *
|
||||
#* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
#* GNU Lesser General Public License for more details. *
|
||||
#* *
|
||||
#* You should have received a copy of the GNU Library General Public *
|
||||
#* License along with FreeCAD; if not, write to the Free Software *
|
||||
#* License along with FreeCAD if not, write to the Free Software *
|
||||
#* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
|
||||
#* USA *
|
||||
#* *
|
||||
|
@ -47,7 +47,7 @@ def InitApplications():
|
|||
BinDir = os.path.realpath(BinDir)
|
||||
LibDir = FreeCAD.getHomePath()+'lib'
|
||||
LibDir = os.path.realpath(LibDir)
|
||||
AddPath = FreeCAD.ConfigGet("AdditionalModulePaths").split(";")
|
||||
AddPath = FreeCAD.ConfigGet("AdditionalModulePaths").split(" ")
|
||||
HomeMod = FreeCAD.ConfigGet("UserAppData")+"Mod"
|
||||
HomeMod = os.path.realpath(HomeMod)
|
||||
MacroDir = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Macro").GetString("MacroPath")
|
||||
|
@ -118,7 +118,7 @@ def InitApplications():
|
|||
if len(platform.mac_ver()[0]) > 0:
|
||||
sys.path.append(os.path.expanduser('~/Library/Application Support/FreeCAD/Mod'))
|
||||
|
||||
# some often used shortcuts (for lazy people like me ;-)
|
||||
# some often used shortcuts (for lazy people like me -)
|
||||
App = FreeCAD
|
||||
Log = FreeCAD.Console.PrintLog
|
||||
Msg = FreeCAD.Console.PrintMessage
|
||||
|
@ -208,6 +208,27 @@ App.Units.Degree = App.Units.Quantity('deg')
|
|||
App.Units.Radian = App.Units.Quantity('rad')
|
||||
App.Units.Gon = App.Units.Quantity('gon')
|
||||
|
||||
App.Units.Length = App.Units.Unit(1)
|
||||
App.Units.Area = App.Units.Unit(2)
|
||||
App.Units.Volume = App.Units.Unit(3)
|
||||
App.Units.Mass = App.Units.Unit(0,1)
|
||||
App.Units.Angle = App.Units.Unit(0,0,0,0,0,0,0,1)
|
||||
|
||||
App.Units.TimeSpan = App.Units.Unit(0,0,1)
|
||||
App.Units.Velocity = App.Units.Unit(1,0,-1)
|
||||
App.Units.Acceleration = App.Units.Unit(1,0,-2)
|
||||
App.Units.Temperature = App.Units.Unit(0,0,0,0,1)
|
||||
|
||||
App.Units.ElectricCurrent = App.Units.Unit(0,0,0,1)
|
||||
App.Units.AmountOfSubstance = App.Units.Unit(0,0,0,0,0,1)
|
||||
App.Units.LuminoseIntensity = App.Units.Unit(0,0,0,0,0,0,1)
|
||||
|
||||
App.Units.Stress = App.Units.Unit(-1,1,-2)
|
||||
App.Units.Pressure = App.Units.Unit(-1,1,-2)
|
||||
|
||||
App.Units.Force = App.Units.Unit(1,1,-2)
|
||||
App.Units.Work = App.Units.Unit(2,1,-2)
|
||||
App.Units.Power = App.Units.Unit(2,1,-3)
|
||||
|
||||
|
||||
# clean up namespace
|
||||
|
|
|
@ -71,6 +71,14 @@ bool Quantity::operator ==(const Quantity& that) const
|
|||
return (this->_Value == that._Value) && (this->_Unit == that._Unit) ;
|
||||
}
|
||||
|
||||
bool Quantity::operator <(const Quantity& that) const
|
||||
{
|
||||
if(this->_Unit != that._Unit)
|
||||
throw Base::Exception("Quantity::operator <(): quantities need to have same unit to compare");
|
||||
|
||||
return (this->_Value < that._Value) ;
|
||||
}
|
||||
|
||||
|
||||
Quantity Quantity::operator *(const Quantity &p) const
|
||||
{
|
||||
|
|
|
@ -57,6 +57,7 @@ public:
|
|||
Quantity operator -(void) const;
|
||||
Quantity operator /(const Quantity &p) const;
|
||||
bool operator ==(const Quantity&) const;
|
||||
bool operator < (const Quantity&) const;
|
||||
Quantity& operator =(const Quantity&);
|
||||
Quantity pow(const Quantity&)const;
|
||||
//@}
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
FatherInclude="Base/PyObjectBase.h"
|
||||
Namespace="Base"
|
||||
NumberProtocol="true"
|
||||
RichCompare="true"
|
||||
Constructor="true"
|
||||
Delete="true"
|
||||
FatherNamespace="Base">
|
||||
|
|
|
@ -56,6 +56,12 @@ int QuantityPy::PyInit(PyObject* args, PyObject* kwd)
|
|||
return 0;
|
||||
}
|
||||
PyErr_Clear(); // set by PyArg_ParseTuple()
|
||||
if (PyArg_ParseTuple(args,"dO!",&f,&(Base::UnitPy::Type), &object)) {
|
||||
// Note: must be static_cast, not reinterpret_cast
|
||||
*self = Quantity(f,*(static_cast<Base::UnitPy*>(object)->getUnitPtr()));
|
||||
return 0;
|
||||
}
|
||||
PyErr_Clear(); // set by PyArg_ParseTuple()
|
||||
const char* string;
|
||||
if (PyArg_ParseTuple(args,"s", &string)) {
|
||||
|
||||
|
@ -178,6 +184,52 @@ PyObject* QuantityPy::number_multiply_handler(PyObject *self, PyObject *other)
|
|||
}
|
||||
}
|
||||
|
||||
PyObject* QuantityPy::richCompare(PyObject *v, PyObject *w, int op)
|
||||
{
|
||||
if (PyObject_TypeCheck(v, &(QuantityPy::Type)) &&
|
||||
PyObject_TypeCheck(w, &(QuantityPy::Type))) {
|
||||
const Quantity * u1 = static_cast<QuantityPy*>(v)->getQuantityPtr();
|
||||
const Quantity * u2 = static_cast<QuantityPy*>(w)->getQuantityPtr();
|
||||
|
||||
PyObject *res=0;
|
||||
if (op == Py_NE) {
|
||||
res = (!(*u1 == *u2)) ? Py_True : Py_False;
|
||||
Py_INCREF(res);
|
||||
return res;
|
||||
}
|
||||
else if (op == Py_LT) {
|
||||
res = (*u1 < *u2) ? Py_True : Py_False;
|
||||
Py_INCREF(res);
|
||||
return res;
|
||||
}
|
||||
else if (op == Py_LE) {
|
||||
res = (*u1 < *u2)||(*u1 == *u2) ? Py_True : Py_False;
|
||||
Py_INCREF(res);
|
||||
return res;
|
||||
}
|
||||
else if (op == Py_GT) {
|
||||
res = (!(*u1 < *u2))&&(!(*u1 == *u2)) ? Py_True : Py_False;
|
||||
Py_INCREF(res);
|
||||
return res;
|
||||
}
|
||||
else if (op == Py_GE) {
|
||||
res = (!(*u1 < *u2)) ? Py_True : Py_False;
|
||||
Py_INCREF(res);
|
||||
return res;
|
||||
}
|
||||
else if (op == Py_EQ) {
|
||||
res = (*u1 == *u2) ? Py_True : Py_False;
|
||||
Py_INCREF(res);
|
||||
return res;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// This always returns False
|
||||
Py_INCREF(Py_NotImplemented);
|
||||
return Py_NotImplemented;
|
||||
|
||||
}
|
||||
|
||||
Py::Float QuantityPy::getValue(void) const
|
||||
{
|
||||
|
|
|
@ -73,7 +73,6 @@ Unit::Unit(const std::string& Pars)
|
|||
|
||||
}
|
||||
|
||||
|
||||
Unit Unit::pow(char exp)const
|
||||
{
|
||||
Unit result;
|
||||
|
@ -316,6 +315,27 @@ std::string Unit::getString(void) const
|
|||
return ret.str();
|
||||
}
|
||||
|
||||
std::string Unit::getTypeString(void) const
|
||||
{
|
||||
if(*this == Unit::Length ) return "Length"; else
|
||||
if(*this == Unit::Area ) return "Area"; else
|
||||
if(*this == Unit::Volume ) return "Volume"; else
|
||||
if(*this == Unit::Mass ) return "Mass"; else
|
||||
if(*this == Unit::Angle ) return "Angle"; else
|
||||
if(*this == Unit::TimeSpan ) return "TimeSpan"; else
|
||||
if(*this == Unit::Velocity ) return "Velocity"; else
|
||||
if(*this == Unit::Acceleration ) return "Acceleration"; else
|
||||
if(*this == Unit::Temperature ) return "Temperature"; else
|
||||
if(*this == Unit::ElectricCurrent ) return "ElectricCurrent"; else
|
||||
if(*this == Unit::AmountOfSubstance ) return "AmountOfSubstance"; else
|
||||
if(*this == Unit::LuminoseIntensity ) return "LuminoseIntensity"; else
|
||||
if(*this == Unit::Pressure ) return "Pressure"; else
|
||||
if(*this == Unit::Force ) return "Force"; else
|
||||
if(*this == Unit::Work ) return "Work"; else
|
||||
if(*this == Unit::Power ) return "Power"; else
|
||||
return "";
|
||||
|
||||
}
|
||||
|
||||
Unit Unit::Length(1);
|
||||
Unit Unit::Area(2);
|
||||
|
@ -334,3 +354,7 @@ Unit Unit::LuminoseIntensity(0,0,0,0,0,0,1);
|
|||
|
||||
Unit Unit::Stress (-1,1,-2); // kg/m*s^2 or N/m^2 or PSI
|
||||
Unit Unit::Pressure(-1,1,-2); // kg/m*s^2 or N/m^2 or PSI
|
||||
|
||||
Unit Unit::Force (1,1,-2);
|
||||
Unit Unit::Work (2,1,-2);
|
||||
Unit Unit::Power (2,1,-3);
|
||||
|
|
|
@ -70,10 +70,13 @@ public:
|
|||
Unit& operator =(const Unit&);
|
||||
Unit pow(char exp)const;
|
||||
//@}
|
||||
|
||||
/// get the unit signature
|
||||
const UnitSignature & getSignature(void)const {return Sig;}
|
||||
bool isEmpty(void)const;
|
||||
char getLengthDimension(void){return Sig.Length;}
|
||||
|
||||
std::string getString(void) const;
|
||||
/// get the type as an string such as "Area", "Length" or "Pressure".
|
||||
std::string getTypeString(void) const;
|
||||
|
||||
/** Predefined Unit types. */
|
||||
//@{
|
||||
|
@ -97,6 +100,11 @@ public:
|
|||
|
||||
static Unit Stress;
|
||||
static Unit Pressure;
|
||||
static Unit Force;
|
||||
static Unit Work;
|
||||
static Unit Power;
|
||||
|
||||
|
||||
//@}
|
||||
protected:
|
||||
UnitSignature Sig;
|
||||
|
|
|
@ -9,41 +9,30 @@
|
|||
FatherInclude="Base/PyObjectBase.h"
|
||||
Namespace="Base"
|
||||
NumberProtocol="true"
|
||||
RichCompare="true"
|
||||
Constructor="true"
|
||||
Delete="true"
|
||||
FatherNamespace="Base">
|
||||
<Documentation>
|
||||
<Author Licence="LGPL" Name="Juergen Riegel" EMail="FreeCAD@juergen-riegel.net" />
|
||||
<UserDocu>Unit
|
||||
defines a unit type and calculate and compare.
|
||||
<UserDocu>
|
||||
Unit
|
||||
defines a unit type, calculate and compare.
|
||||
|
||||
The following constructors are supported:
|
||||
Unit() -- empty constructor
|
||||
Unit(Unit) -- copy constructor
|
||||
Unit(string) -- parse the string for units
|
||||
</UserDocu>
|
||||
The following constructors are supported:
|
||||
Unit() -- empty constructor
|
||||
Unit(i1,i2,i3,i4,i5,i6,i7,i8) -- unit signature
|
||||
Unit(Quantity) -- copy unit from Quantity
|
||||
Unit(Unit) -- copy constructor
|
||||
Unit(string) -- parse the string for units
|
||||
</UserDocu>
|
||||
<DeveloperDocu>Unit</DeveloperDocu>
|
||||
</Documentation>
|
||||
<Methode Name="multiply">
|
||||
<Attribute Name="Type" ReadOnly="true">
|
||||
<Documentation>
|
||||
<UserDocu>
|
||||
multiply(Placement)
|
||||
Multiply this axis with a placement
|
||||
</UserDocu>
|
||||
<UserDocu>holds the unit type as a string, e.g. 'Area'.</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Methode Name="getType">
|
||||
<Documentation>
|
||||
<UserDocu>
|
||||
get the type of the unit as string
|
||||
</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Attribute Name="Dimensions" ReadOnly="false">
|
||||
<Documentation>
|
||||
<UserDocu>get the dimension as a vector with 8 fields</UserDocu>
|
||||
</Documentation>
|
||||
<Parameter Name="Direction" Type="Object" />
|
||||
<Parameter Name="Type" Type="String" />
|
||||
</Attribute>
|
||||
</PythonExport>
|
||||
</GenerateModel>
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
|
||||
// inclusion of the generated files (generated out of UnitPy.xml)
|
||||
#include "UnitPy.h"
|
||||
#include "QuantityPy.h"
|
||||
#include "UnitPy.cpp"
|
||||
|
||||
using namespace Base;
|
||||
|
@ -12,7 +13,23 @@ using namespace Base;
|
|||
// returns a string which represents the object e.g. when printed in python
|
||||
std::string UnitPy::representation(void) const
|
||||
{
|
||||
return std::string("<Unit object>");
|
||||
const UnitSignature & Sig = getUnitPtr()->getSignature();
|
||||
std::stringstream ret;
|
||||
ret << "Unit: ";
|
||||
ret << getUnitPtr()->getString() << " (";
|
||||
ret << Sig.Length << ",";
|
||||
ret << Sig.Mass << ",";
|
||||
ret << Sig.Time << ",";
|
||||
ret << Sig.ElectricCurrent << ",";
|
||||
ret << Sig.ThermodynamicTemperature << ",";
|
||||
ret << Sig.AmountOfSubstance << ",";
|
||||
ret << Sig.LuminoseIntensity << ",";
|
||||
ret << Sig.Angle << ")";
|
||||
std::string type = getUnitPtr()->getTypeString();
|
||||
if(! type.empty())
|
||||
ret << " [" << type << "]";
|
||||
|
||||
return ret.str();
|
||||
}
|
||||
|
||||
PyObject *UnitPy::PyMake(struct _typeobject *, PyObject *, PyObject *) // Python wrapper
|
||||
|
@ -22,22 +39,48 @@ PyObject *UnitPy::PyMake(struct _typeobject *, PyObject *, PyObject *) // Pytho
|
|||
}
|
||||
|
||||
// constructor method
|
||||
int UnitPy::PyInit(PyObject* /*args*/, PyObject* /*kwd*/)
|
||||
int UnitPy::PyInit(PyObject* args, PyObject* kwd)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
Unit *self = getUnitPtr();
|
||||
|
||||
int i1=0;
|
||||
int i2=0;
|
||||
int i3=0;
|
||||
int i4=0;
|
||||
int i5=0;
|
||||
int i6=0;
|
||||
int i7=0;
|
||||
int i8=0;
|
||||
if (PyArg_ParseTuple(args, "|iiiiiiii", &i1,&i2,&i3,&i4,&i5,&i6,&i7,&i8)) {
|
||||
*self = Unit(i1,i2,i3,i4,i5,i6,i7,i8);
|
||||
return 0;
|
||||
}
|
||||
PyErr_Clear(); // set by PyArg_ParseTuple()
|
||||
|
||||
PyObject* UnitPy::multiply(PyObject * /*args*/)
|
||||
{
|
||||
PyErr_SetString(PyExc_NotImplementedError, "Not yet implemented");
|
||||
return 0;
|
||||
}
|
||||
PyObject *object;
|
||||
|
||||
PyObject* UnitPy::getType(PyObject * /*args*/)
|
||||
{
|
||||
PyErr_SetString(PyExc_NotImplementedError, "Not yet implemented");
|
||||
return 0;
|
||||
if (PyArg_ParseTuple(args,"O!",&(Base::QuantityPy::Type), &object)) {
|
||||
// Note: must be static_cast, not reinterpret_cast
|
||||
*self = static_cast<Base::QuantityPy*>(object)->getQuantityPtr()->getUnit();
|
||||
return 0;
|
||||
}
|
||||
PyErr_Clear(); // set by PyArg_ParseTuple()
|
||||
|
||||
if (PyArg_ParseTuple(args,"O!",&(Base::UnitPy::Type), &object)) {
|
||||
// Note: must be static_cast, not reinterpret_cast
|
||||
*self = *(static_cast<Base::UnitPy*>(object)->getUnitPtr());
|
||||
return 0;
|
||||
}
|
||||
PyErr_Clear(); // set by PyArg_ParseTuple()
|
||||
const char* string;
|
||||
if (PyArg_ParseTuple(args,"s", &string)) {
|
||||
|
||||
*self = Quantity::parse(string).getUnit();
|
||||
return 0;
|
||||
}
|
||||
|
||||
PyErr_SetString(PyExc_TypeError, "Either string, (float,8 ints), Unit() or Quantity()");
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
|
@ -102,18 +145,44 @@ PyObject* UnitPy::number_multiply_handler(PyObject *self, PyObject *other)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
Py::Object UnitPy::getDimensions(void) const
|
||||
PyObject* UnitPy::richCompare(PyObject *v, PyObject *w, int op)
|
||||
{
|
||||
//return Py::Object();
|
||||
throw Py::AttributeError("Not yet implemented");
|
||||
if (PyObject_TypeCheck(v, &(UnitPy::Type)) &&
|
||||
PyObject_TypeCheck(w, &(UnitPy::Type))) {
|
||||
const Unit * u1 = static_cast<UnitPy*>(v)->getUnitPtr();
|
||||
const Unit * u2 = static_cast<UnitPy*>(w)->getUnitPtr();
|
||||
|
||||
PyObject *res=0;
|
||||
if (op != Py_EQ && op != Py_NE) {
|
||||
PyErr_SetString(PyExc_TypeError,
|
||||
"no ordering relation is defined for Units");
|
||||
return 0;
|
||||
}
|
||||
else if (op == Py_EQ) {
|
||||
res = (*u1 == *u2) ? Py_True : Py_False;
|
||||
Py_INCREF(res);
|
||||
return res;
|
||||
}
|
||||
else {
|
||||
res = (*u1 != *u2) ? Py_True : Py_False;
|
||||
Py_INCREF(res);
|
||||
return res;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// This always returns False
|
||||
Py_INCREF(Py_NotImplemented);
|
||||
return Py_NotImplemented;
|
||||
}
|
||||
}
|
||||
|
||||
void UnitPy::setDimensions(Py::Object /*arg*/)
|
||||
Py::String UnitPy::getType(void) const
|
||||
{
|
||||
throw Py::AttributeError("Not yet implemented");
|
||||
return Py::String(getUnitPtr()->getTypeString());
|
||||
}
|
||||
|
||||
|
||||
|
||||
PyObject *UnitPy::getCustomAttributes(const char* /*attr*/) const
|
||||
{
|
||||
return 0;
|
||||
|
|
Loading…
Reference in New Issue
Block a user