Base: apply clang format
This commit is contained in:
@@ -27,10 +27,9 @@
|
||||
using namespace Base;
|
||||
|
||||
Axis::Axis(const Vector3d& Orig, const Vector3d& Dir)
|
||||
: _base{Orig}
|
||||
, _dir{Dir}
|
||||
{
|
||||
}
|
||||
: _base {Orig}
|
||||
, _dir {Dir}
|
||||
{}
|
||||
|
||||
void Axis::reverse()
|
||||
{
|
||||
@@ -49,24 +48,24 @@ void Axis::move(const Vector3d& MovVec)
|
||||
_base += MovVec;
|
||||
}
|
||||
|
||||
bool Axis::operator ==(const Axis& that) const
|
||||
bool Axis::operator==(const Axis& that) const
|
||||
{
|
||||
return (this->_base == that._base) && (this->_dir == that._dir);
|
||||
}
|
||||
|
||||
bool Axis::operator !=(const Axis& that) const
|
||||
bool Axis::operator!=(const Axis& that) const
|
||||
{
|
||||
return !(*this == that);
|
||||
}
|
||||
|
||||
Axis& Axis::operator *=(const Placement &p)
|
||||
Axis& Axis::operator*=(const Placement& p)
|
||||
{
|
||||
p.multVec(this->_base, this->_base);
|
||||
p.getRotation().multVec(this->_dir, this->_dir);
|
||||
return *this;
|
||||
}
|
||||
|
||||
Axis Axis::operator *(const Placement &p) const
|
||||
Axis Axis::operator*(const Placement& p) const
|
||||
{
|
||||
Axis a(*this);
|
||||
a *= p;
|
||||
|
||||
@@ -27,7 +27,8 @@
|
||||
#include "Placement.h"
|
||||
#include "Vector3D.h"
|
||||
|
||||
namespace Base {
|
||||
namespace Base
|
||||
{
|
||||
|
||||
/**
|
||||
* The Axis class.
|
||||
@@ -41,12 +42,24 @@ public:
|
||||
Axis(Axis&&) = default;
|
||||
Axis(const Vector3d& Orig, const Vector3d& Dir);
|
||||
/// Destruction
|
||||
~Axis () = default;
|
||||
~Axis() = default;
|
||||
|
||||
const Vector3d& getBase() const {return _base;}
|
||||
const Vector3d& getDirection() const {return _dir;}
|
||||
void setBase(const Vector3d& Orig) {_base=Orig;}
|
||||
void setDirection(const Vector3d& Dir) {_dir=Dir;}
|
||||
const Vector3d& getBase() const
|
||||
{
|
||||
return _base;
|
||||
}
|
||||
const Vector3d& getDirection() const
|
||||
{
|
||||
return _dir;
|
||||
}
|
||||
void setBase(const Vector3d& Orig)
|
||||
{
|
||||
_base = Orig;
|
||||
}
|
||||
void setDirection(const Vector3d& Dir)
|
||||
{
|
||||
_dir = Dir;
|
||||
}
|
||||
|
||||
void reverse();
|
||||
Axis reversed() const;
|
||||
@@ -54,12 +67,12 @@ public:
|
||||
|
||||
/** Operators. */
|
||||
//@{
|
||||
Axis& operator *=(const Placement &p);
|
||||
Axis operator *(const Placement &p) const;
|
||||
bool operator ==(const Axis&) const;
|
||||
bool operator !=(const Axis&) const;
|
||||
Axis& operator =(const Axis&) = default;
|
||||
Axis& operator =(Axis&&) = default;
|
||||
Axis& operator*=(const Placement& p);
|
||||
Axis operator*(const Placement& p) const;
|
||||
bool operator==(const Axis&) const;
|
||||
bool operator!=(const Axis&) const;
|
||||
Axis& operator=(const Axis&) = default;
|
||||
Axis& operator=(Axis&&) = default;
|
||||
//@}
|
||||
|
||||
private:
|
||||
@@ -67,6 +80,6 @@ private:
|
||||
Vector3d _dir;
|
||||
};
|
||||
|
||||
} // namespace Base
|
||||
} // namespace Base
|
||||
|
||||
#endif // BASE_AXIS_H
|
||||
#endif // BASE_AXIS_H
|
||||
|
||||
@@ -13,18 +13,18 @@
|
||||
FatherNamespace="Base">
|
||||
<Documentation>
|
||||
<Author Licence="LGPL" Name="Juergen Riegel" EMail="FreeCAD@juergen-riegel.net" />
|
||||
<UserDocu>Base.Axis class.
|
||||
<UserDocu>Base.Axis class.
|
||||
|
||||
An Axis defines a direction and a position (base) in 3D space.
|
||||
An Axis defines a direction and a position (base) in 3D space.
|
||||
|
||||
The following constructors are supported:
|
||||
The following constructors are supported:
|
||||
|
||||
Axis()
|
||||
Empty constructor.
|
||||
Empty constructor.
|
||||
|
||||
Axis(axis)
|
||||
Copy constructor.
|
||||
axis : Base.Axis
|
||||
axis : Base.Axis
|
||||
|
||||
Axis(base, direction)
|
||||
Define from a position and a direction.
|
||||
@@ -34,34 +34,34 @@ direction : Base.Vector</UserDocu>
|
||||
</Documentation>
|
||||
<Methode Name="copy">>
|
||||
<Documentation>
|
||||
<UserDocu>copy() -> Base.Axis
|
||||
<UserDocu>copy() -> Base.Axis
|
||||
|
||||
Returns a copy of this Axis.</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Methode Name="move">
|
||||
<Documentation>
|
||||
<UserDocu>move(vector) -> None
|
||||
<UserDocu>move(vector) -> None
|
||||
|
||||
Move the axis base along the given vector.
|
||||
Move the axis base along the given vector.
|
||||
|
||||
vector : Base.Vector
|
||||
vector : Base.Vector
|
||||
Vector by which to move the axis.</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Methode Name="multiply">
|
||||
<Documentation>
|
||||
<UserDocu>multiply(placement) -> Base.Axis
|
||||
<UserDocu>multiply(placement) -> Base.Axis
|
||||
|
||||
Multiply this axis by a placement.
|
||||
Multiply this axis by a placement.
|
||||
|
||||
placement : Base.Placement
|
||||
placement : Base.Placement
|
||||
Placement by which to multiply the axis.</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Methode Name="reversed">
|
||||
<Documentation>
|
||||
<UserDocu>reversed() -> Base.Axis
|
||||
<UserDocu>reversed() -> Base.Axis
|
||||
|
||||
Compute the reversed axis. This returns a new Base.Axis with
|
||||
the original direction reversed.</UserDocu>
|
||||
|
||||
@@ -39,14 +39,15 @@ std::string AxisPy::representation() const
|
||||
AxisPy::PointerType ptr = getAxisPtr();
|
||||
std::stringstream str;
|
||||
str << "Axis [Base=(";
|
||||
str << ptr->getBase().x << ","<< ptr->getBase().y << "," << ptr->getBase().z;
|
||||
str << ptr->getBase().x << "," << ptr->getBase().y << "," << ptr->getBase().z;
|
||||
str << "), Direction=(";
|
||||
str << ptr->getDirection().x << ","<< ptr->getDirection().y << "," << ptr->getDirection().z << ")]";
|
||||
str << ptr->getDirection().x << "," << ptr->getDirection().y << "," << ptr->getDirection().z
|
||||
<< ")]";
|
||||
|
||||
return str.str();
|
||||
}
|
||||
|
||||
PyObject *AxisPy::PyMake(struct _typeobject *, PyObject *, PyObject *) // Python wrapper
|
||||
PyObject* AxisPy::PyMake(struct _typeobject*, PyObject*, PyObject*) // Python wrapper
|
||||
{
|
||||
// create a new instance of AxisPy and the Twin object
|
||||
return new AxisPy(new Axis);
|
||||
@@ -55,22 +56,21 @@ PyObject *AxisPy::PyMake(struct _typeobject *, PyObject *, PyObject *) // Pytho
|
||||
// constructor method
|
||||
int AxisPy::PyInit(PyObject* args, PyObject* /*kwd*/)
|
||||
{
|
||||
PyObject* o{};
|
||||
PyObject* o {};
|
||||
if (PyArg_ParseTuple(args, "")) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
PyErr_Clear();
|
||||
if (PyArg_ParseTuple(args, "O!", &(Base::AxisPy::Type), &o)) {
|
||||
Base::Axis *a = static_cast<Base::AxisPy*>(o)->getAxisPtr();
|
||||
Base::Axis* a = static_cast<Base::AxisPy*>(o)->getAxisPtr();
|
||||
*(getAxisPtr()) = *a;
|
||||
return 0;
|
||||
}
|
||||
|
||||
PyErr_Clear();
|
||||
PyObject* d{};
|
||||
if (PyArg_ParseTuple(args, "O!O!", &(Base::VectorPy::Type), &o,
|
||||
&(Base::VectorPy::Type), &d)) {
|
||||
PyObject* d {};
|
||||
if (PyArg_ParseTuple(args, "O!O!", &(Base::VectorPy::Type), &o, &(Base::VectorPy::Type), &d)) {
|
||||
// NOTE: The first parameter defines the base (origin) and the second the direction.
|
||||
*getAxisPtr() = Base::Axis(static_cast<Base::VectorPy*>(o)->value(),
|
||||
static_cast<Base::VectorPy*>(d)->value());
|
||||
@@ -81,42 +81,46 @@ int AxisPy::PyInit(PyObject* args, PyObject* /*kwd*/)
|
||||
return -1;
|
||||
}
|
||||
|
||||
PyObject* AxisPy::move(PyObject * args)
|
||||
PyObject* AxisPy::move(PyObject* args)
|
||||
{
|
||||
PyObject *vec{};
|
||||
if (!PyArg_ParseTuple(args, "O!", &(VectorPy::Type), &vec))
|
||||
PyObject* vec {};
|
||||
if (!PyArg_ParseTuple(args, "O!", &(VectorPy::Type), &vec)) {
|
||||
return nullptr;
|
||||
}
|
||||
getAxisPtr()->move(static_cast<VectorPy*>(vec)->value());
|
||||
Py_Return;
|
||||
}
|
||||
|
||||
PyObject* AxisPy::multiply(PyObject * args)
|
||||
PyObject* AxisPy::multiply(PyObject* args)
|
||||
{
|
||||
PyObject *plm{};
|
||||
if (!PyArg_ParseTuple(args, "O!", &(PlacementPy::Type), &plm))
|
||||
PyObject* plm {};
|
||||
if (!PyArg_ParseTuple(args, "O!", &(PlacementPy::Type), &plm)) {
|
||||
return nullptr;
|
||||
}
|
||||
Axis mult = (*getAxisPtr()) * (*static_cast<PlacementPy*>(plm)->getPlacementPtr());
|
||||
return new AxisPy(new Axis(mult));
|
||||
}
|
||||
|
||||
PyObject* AxisPy::copy(PyObject * args)
|
||||
PyObject* AxisPy::copy(PyObject* args)
|
||||
{
|
||||
if (!PyArg_ParseTuple(args, ""))
|
||||
if (!PyArg_ParseTuple(args, "")) {
|
||||
return nullptr;
|
||||
}
|
||||
return new AxisPy(new Axis(*getAxisPtr()));
|
||||
}
|
||||
|
||||
PyObject* AxisPy::reversed(PyObject * args)
|
||||
PyObject* AxisPy::reversed(PyObject* args)
|
||||
{
|
||||
if (!PyArg_ParseTuple(args, ""))
|
||||
if (!PyArg_ParseTuple(args, "")) {
|
||||
return nullptr;
|
||||
}
|
||||
Base::Axis a = getAxisPtr()->reversed();
|
||||
return new AxisPy(new Axis(a));
|
||||
}
|
||||
|
||||
Py::Object AxisPy::getBase() const
|
||||
{
|
||||
return Py::Vector(getAxisPtr()->getBase()); // NOLINT
|
||||
return Py::Vector(getAxisPtr()->getBase()); // NOLINT
|
||||
}
|
||||
|
||||
void AxisPy::setBase(Py::Object arg)
|
||||
@@ -126,7 +130,7 @@ void AxisPy::setBase(Py::Object arg)
|
||||
|
||||
Py::Object AxisPy::getDirection() const
|
||||
{
|
||||
return Py::Vector(getAxisPtr()->getDirection()); // NOLINT
|
||||
return Py::Vector(getAxisPtr()->getDirection()); // NOLINT
|
||||
}
|
||||
|
||||
void AxisPy::setDirection(Py::Object arg)
|
||||
@@ -134,7 +138,7 @@ void AxisPy::setDirection(Py::Object arg)
|
||||
getAxisPtr()->setDirection(Py::Vector(arg).toVector());
|
||||
}
|
||||
|
||||
PyObject *AxisPy::getCustomAttributes(const char* /*attr*/) const
|
||||
PyObject* AxisPy::getCustomAttributes(const char* /*attr*/) const
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
@@ -143,4 +147,3 @@ int AxisPy::setCustomAttributes(const char* /*attr*/, PyObject* /*obj*/)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
#include "PreCompiled.h"
|
||||
|
||||
#ifndef _PreComp_
|
||||
# include <cassert>
|
||||
#include <cassert>
|
||||
#endif
|
||||
|
||||
#include "BaseClass.h"
|
||||
@@ -32,7 +32,7 @@
|
||||
|
||||
using namespace Base;
|
||||
|
||||
Type BaseClass::classTypeId = Base::Type::badType();
|
||||
Type BaseClass::classTypeId = Base::Type::badType(); // NOLINT
|
||||
|
||||
|
||||
//**************************************************************************
|
||||
@@ -64,9 +64,7 @@ void BaseClass::init()
|
||||
|
||||
/* Set up entry in the type system. */
|
||||
BaseClass::classTypeId =
|
||||
Type::createType(Type::badType(),
|
||||
"Base::BaseClass",
|
||||
BaseClass::create);
|
||||
Type::createType(Type::badType(), "Base::BaseClass", BaseClass::create);
|
||||
}
|
||||
|
||||
Type BaseClass::getClassTypeId()
|
||||
@@ -80,7 +78,9 @@ Type BaseClass::getTypeId() const
|
||||
}
|
||||
|
||||
|
||||
void BaseClass::initSubclass(Base::Type &toInit,const char* ClassName, const char *ParentName,
|
||||
void BaseClass::initSubclass(Base::Type& toInit,
|
||||
const char* ClassName,
|
||||
const char* ParentName,
|
||||
Type::instantiationMethod method)
|
||||
{
|
||||
// don't init twice!
|
||||
@@ -88,7 +88,7 @@ void BaseClass::initSubclass(Base::Type &toInit,const char* ClassName, const cha
|
||||
// get the parent class
|
||||
Base::Type parentType(Base::Type::fromName(ParentName));
|
||||
// forgot init parent!
|
||||
assert(parentType != Base::Type::badType() );
|
||||
assert(parentType != Base::Type::badType());
|
||||
|
||||
// create the new type
|
||||
toInit = Base::Type::createType(parentType, ClassName, method);
|
||||
@@ -104,13 +104,13 @@ void BaseClass::initSubclass(Base::Type &toInit,const char* ClassName, const cha
|
||||
*
|
||||
* The default implementation returns 'None'.
|
||||
*/
|
||||
PyObject *BaseClass::getPyObject()
|
||||
PyObject* BaseClass::getPyObject()
|
||||
{
|
||||
assert(0);
|
||||
Py_Return;
|
||||
}
|
||||
|
||||
void BaseClass::setPyObject(PyObject *)
|
||||
void BaseClass::setPyObject(PyObject*)
|
||||
{
|
||||
assert(0);
|
||||
}
|
||||
|
||||
@@ -31,72 +31,104 @@ using PyObject = struct _object;
|
||||
|
||||
|
||||
/// define for subclassing Base::BaseClass
|
||||
#define TYPESYSTEM_HEADER() \
|
||||
public: \
|
||||
static Base::Type getClassTypeId(void); \
|
||||
virtual Base::Type getTypeId(void) const; \
|
||||
static void init(void);\
|
||||
static void *create(void);\
|
||||
private: \
|
||||
static Base::Type classTypeId
|
||||
#define TYPESYSTEM_HEADER() \
|
||||
public: \
|
||||
static Base::Type getClassTypeId(void); \
|
||||
virtual Base::Type getTypeId(void) const; \
|
||||
static void init(void); \
|
||||
static void* create(void); \
|
||||
\
|
||||
private: \
|
||||
static Base::Type classTypeId
|
||||
|
||||
|
||||
/// Like TYPESYSTEM_HEADER, but declare getTypeId as 'override'
|
||||
#define TYPESYSTEM_HEADER_WITH_OVERRIDE() \
|
||||
public: \
|
||||
static Base::Type getClassTypeId(void); \
|
||||
virtual Base::Type getTypeId(void) const override; \
|
||||
static void init(void);\
|
||||
static void *create(void);\
|
||||
private: \
|
||||
static Base::Type classTypeId
|
||||
#define TYPESYSTEM_HEADER_WITH_OVERRIDE() \
|
||||
public: \
|
||||
static Base::Type getClassTypeId(void); \
|
||||
virtual Base::Type getTypeId(void) const override; \
|
||||
static void init(void); \
|
||||
static void* create(void); \
|
||||
\
|
||||
private: \
|
||||
static Base::Type classTypeId
|
||||
|
||||
|
||||
/// define to implement a subclass of Base::BaseClass
|
||||
#define TYPESYSTEM_SOURCE_P(_class_) \
|
||||
Base::Type _class_::getClassTypeId(void) { return _class_::classTypeId; } \
|
||||
Base::Type _class_::getTypeId(void) const { return _class_::classTypeId; } \
|
||||
Base::Type _class_::classTypeId = Base::Type::badType(); \
|
||||
void * _class_::create(void){\
|
||||
return new _class_ ();\
|
||||
}
|
||||
#define TYPESYSTEM_SOURCE_P(_class_) \
|
||||
Base::Type _class_::getClassTypeId(void) \
|
||||
{ \
|
||||
return _class_::classTypeId; \
|
||||
} \
|
||||
Base::Type _class_::getTypeId(void) const \
|
||||
{ \
|
||||
return _class_::classTypeId; \
|
||||
} \
|
||||
Base::Type _class_::classTypeId = Base::Type::badType(); \
|
||||
void* _class_::create(void) \
|
||||
{ \
|
||||
return new _class_(); \
|
||||
}
|
||||
|
||||
/// define to implement a subclass of Base::BaseClass
|
||||
#define TYPESYSTEM_SOURCE_TEMPLATE_P(_class_) \
|
||||
template<> Base::Type _class_::getClassTypeId(void) { return _class_::classTypeId; } \
|
||||
template<> Base::Type _class_::getTypeId(void) const { return _class_::classTypeId; } \
|
||||
template<> void * _class_::create(void){\
|
||||
return new _class_ ();\
|
||||
}
|
||||
#define TYPESYSTEM_SOURCE_TEMPLATE_P(_class_) \
|
||||
template<> \
|
||||
Base::Type _class_::getClassTypeId(void) \
|
||||
{ \
|
||||
return _class_::classTypeId; \
|
||||
} \
|
||||
template<> \
|
||||
Base::Type _class_::getTypeId(void) const \
|
||||
{ \
|
||||
return _class_::classTypeId; \
|
||||
} \
|
||||
template<> \
|
||||
void* _class_::create(void) \
|
||||
{ \
|
||||
return new _class_(); \
|
||||
}
|
||||
|
||||
/// define to implement a subclass of Base::BaseClass
|
||||
#define TYPESYSTEM_SOURCE_ABSTRACT_P(_class_) \
|
||||
Base::Type _class_::getClassTypeId(void) { return _class_::classTypeId; } \
|
||||
Base::Type _class_::getTypeId(void) const { return _class_::classTypeId; } \
|
||||
Base::Type _class_::classTypeId = Base::Type::badType(); \
|
||||
void * _class_::create(void){return 0;}
|
||||
#define TYPESYSTEM_SOURCE_ABSTRACT_P(_class_) \
|
||||
Base::Type _class_::getClassTypeId(void) \
|
||||
{ \
|
||||
return _class_::classTypeId; \
|
||||
} \
|
||||
Base::Type _class_::getTypeId(void) const \
|
||||
{ \
|
||||
return _class_::classTypeId; \
|
||||
} \
|
||||
Base::Type _class_::classTypeId = Base::Type::badType(); \
|
||||
void* _class_::create(void) \
|
||||
{ \
|
||||
return 0; \
|
||||
}
|
||||
|
||||
|
||||
/// define to implement a subclass of Base::BaseClass
|
||||
#define TYPESYSTEM_SOURCE(_class_, _parentclass_) \
|
||||
TYPESYSTEM_SOURCE_P(_class_)\
|
||||
void _class_::init(void){\
|
||||
initSubclass(_class_::classTypeId, #_class_ , #_parentclass_, &(_class_::create) ); \
|
||||
}
|
||||
#define TYPESYSTEM_SOURCE(_class_, _parentclass_) \
|
||||
TYPESYSTEM_SOURCE_P(_class_) \
|
||||
void _class_::init(void) \
|
||||
{ \
|
||||
initSubclass(_class_::classTypeId, #_class_, #_parentclass_, &(_class_::create)); \
|
||||
}
|
||||
|
||||
/// define to implement a subclass of Base::BaseClass
|
||||
#define TYPESYSTEM_SOURCE_TEMPLATE_T(_class_, _parentclass_) \
|
||||
TYPESYSTEM_SOURCE_TEMPLATE_P(_class_)\
|
||||
template<> void _class_::init(void){\
|
||||
initSubclass(_class_::classTypeId, #_class_ , #_parentclass_, &(_class_::create) ); \
|
||||
}
|
||||
#define TYPESYSTEM_SOURCE_TEMPLATE_T(_class_, _parentclass_) \
|
||||
TYPESYSTEM_SOURCE_TEMPLATE_P(_class_) \
|
||||
template<> \
|
||||
void _class_::init(void) \
|
||||
{ \
|
||||
initSubclass(_class_::classTypeId, #_class_, #_parentclass_, &(_class_::create)); \
|
||||
}
|
||||
|
||||
/// define to implement a subclass of Base::BaseClass
|
||||
#define TYPESYSTEM_SOURCE_ABSTRACT(_class_, _parentclass_) \
|
||||
TYPESYSTEM_SOURCE_ABSTRACT_P(_class_)\
|
||||
void _class_::init(void){\
|
||||
initSubclass(_class_::classTypeId, #_class_ , #_parentclass_, &(_class_::create) ); \
|
||||
}
|
||||
#define TYPESYSTEM_SOURCE_ABSTRACT(_class_, _parentclass_) \
|
||||
TYPESYSTEM_SOURCE_ABSTRACT_P(_class_) \
|
||||
void _class_::init(void) \
|
||||
{ \
|
||||
initSubclass(_class_::classTypeId, #_class_, #_parentclass_, &(_class_::create)); \
|
||||
}
|
||||
|
||||
namespace Base
|
||||
{
|
||||
@@ -104,54 +136,69 @@ namespace Base
|
||||
class BaseExport BaseClass
|
||||
{
|
||||
public:
|
||||
static Type getClassTypeId();
|
||||
virtual Type getTypeId() const;
|
||||
bool isDerivedFrom(const Type type) const {return getTypeId().isDerivedFrom(type);}
|
||||
static Type getClassTypeId();
|
||||
virtual Type getTypeId() const;
|
||||
bool isDerivedFrom(const Type type) const
|
||||
{
|
||||
return getTypeId().isDerivedFrom(type);
|
||||
}
|
||||
|
||||
static void init();
|
||||
static void init();
|
||||
|
||||
virtual PyObject *getPyObject();
|
||||
virtual void setPyObject(PyObject *);
|
||||
virtual PyObject* getPyObject();
|
||||
virtual void setPyObject(PyObject*);
|
||||
|
||||
static void *create(){return nullptr;}
|
||||
static void* create()
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool is() const
|
||||
{
|
||||
return getTypeId() == T::getClassTypeId();
|
||||
}
|
||||
template<typename T>
|
||||
bool is() const
|
||||
{
|
||||
return getTypeId() == T::getClassTypeId();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool isDerivedFrom() const
|
||||
{
|
||||
return getTypeId().isDerivedFrom(T::getClassTypeId());
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool isDerivedFrom() const
|
||||
{
|
||||
return getTypeId().isDerivedFrom(T::getClassTypeId());
|
||||
}
|
||||
private:
|
||||
static Type classTypeId;
|
||||
static Type classTypeId; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables)
|
||||
|
||||
protected:
|
||||
static void initSubclass(Base::Type &toInit,const char* ClassName, const char *ParentName, Type::instantiationMethod method=nullptr);
|
||||
static void initSubclass(Base::Type& toInit,
|
||||
const char* ClassName,
|
||||
const char* ParentName,
|
||||
Type::instantiationMethod method = nullptr);
|
||||
|
||||
public:
|
||||
/// Construction
|
||||
BaseClass();
|
||||
BaseClass(const BaseClass&) = default;
|
||||
BaseClass& operator=(const BaseClass&) = default;
|
||||
/// Destruction
|
||||
virtual ~BaseClass();
|
||||
|
||||
/// Construction
|
||||
BaseClass();
|
||||
BaseClass(const BaseClass&) = default;
|
||||
BaseClass& operator=(const BaseClass&) = default;
|
||||
BaseClass(BaseClass&&) = default;
|
||||
BaseClass& operator=(BaseClass&&) = default;
|
||||
/// Destruction
|
||||
virtual ~BaseClass();
|
||||
};
|
||||
|
||||
/**
|
||||
* Template that works just like dynamic_cast, but expects the argument to
|
||||
* inherit from Base::BaseClass.
|
||||
*
|
||||
*/
|
||||
template<typename T> T * freecad_dynamic_cast(Base::BaseClass * t)
|
||||
* Template that works just like dynamic_cast, but expects the argument to
|
||||
* inherit from Base::BaseClass.
|
||||
*
|
||||
*/
|
||||
template<typename T>
|
||||
T* freecad_dynamic_cast(Base::BaseClass* t)
|
||||
{
|
||||
if (t && t->isDerivedFrom(T::getClassTypeId()))
|
||||
if (t && t->isDerivedFrom(T::getClassTypeId())) {
|
||||
return static_cast<T*>(t);
|
||||
else
|
||||
}
|
||||
else {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -159,16 +206,18 @@ template<typename T> T * freecad_dynamic_cast(Base::BaseClass * t)
|
||||
* inherit from a const Base::BaseClass.
|
||||
*
|
||||
*/
|
||||
template<typename T> const T * freecad_dynamic_cast(const Base::BaseClass * t)
|
||||
template<typename T>
|
||||
const T* freecad_dynamic_cast(const Base::BaseClass* t)
|
||||
{
|
||||
if (t && t->isDerivedFrom(T::getClassTypeId()))
|
||||
if (t && t->isDerivedFrom(T::getClassTypeId())) {
|
||||
return static_cast<const T*>(t);
|
||||
else
|
||||
}
|
||||
else {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
} //namespace Base
|
||||
|
||||
#endif // BASE_BASECLASS_H
|
||||
} // namespace Base
|
||||
|
||||
#endif // BASE_BASECLASS_H
|
||||
|
||||
@@ -36,27 +36,32 @@ std::string BaseClassPy::representation() const
|
||||
}
|
||||
|
||||
|
||||
PyObject* BaseClassPy::isDerivedFrom(PyObject *args)
|
||||
PyObject* BaseClassPy::isDerivedFrom(PyObject* args)
|
||||
{
|
||||
char *name{};
|
||||
if (!PyArg_ParseTuple(args, "s", &name))
|
||||
char* name {};
|
||||
if (!PyArg_ParseTuple(args, "s", &name)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// clang-format off
|
||||
Base::Type type = Base::Type::fromName(name);
|
||||
bool valid = (type != Base::Type::badType() && getBaseClassPtr()->getTypeId().isDerivedFrom(type));
|
||||
return PyBool_FromLong(valid ? 1 : 0);
|
||||
// clang-format on
|
||||
}
|
||||
|
||||
PyObject* BaseClassPy::getAllDerivedFrom(PyObject *args)
|
||||
PyObject* BaseClassPy::getAllDerivedFrom(PyObject* args)
|
||||
{
|
||||
if (!PyArg_ParseTuple(args, ""))
|
||||
if (!PyArg_ParseTuple(args, "")) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::vector<Base::Type> ary;
|
||||
Base::Type::getAllDerivedFrom(getBaseClassPtr()->getTypeId(), ary);
|
||||
Py::List res;
|
||||
for (const auto & it : ary)
|
||||
for (const auto& it : ary) {
|
||||
res.append(Py::String(it.getName()));
|
||||
}
|
||||
return Py::new_reference_to(res);
|
||||
}
|
||||
|
||||
@@ -70,15 +75,17 @@ Py::String BaseClassPy::getModule() const
|
||||
std::string module(getBaseClassPtr()->getTypeId().getName());
|
||||
std::string::size_type pos = module.find_first_of("::");
|
||||
|
||||
if (pos != std::string::npos)
|
||||
if (pos != std::string::npos) {
|
||||
module = std::string(module, 0, pos);
|
||||
else
|
||||
}
|
||||
else {
|
||||
module.clear();
|
||||
}
|
||||
|
||||
return {module};
|
||||
}
|
||||
|
||||
PyObject *BaseClassPy::getCustomAttributes(const char* /*attr*/) const
|
||||
PyObject* BaseClassPy::getCustomAttributes(const char* /*attr*/) const
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
@@ -87,5 +94,3 @@ int BaseClassPy::setCustomAttributes(const char* /*attr*/, PyObject* /*obj*/)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -30,10 +30,11 @@
|
||||
|
||||
using namespace Base;
|
||||
|
||||
struct BindingManager::BindingManagerPrivate {
|
||||
struct BindingManager::BindingManagerPrivate
|
||||
{
|
||||
std::unordered_map<const void*, PyObject*> wrapperMapper;
|
||||
|
||||
bool hasWrapper(const void *cptr)
|
||||
bool hasWrapper(const void* cptr)
|
||||
{
|
||||
auto it = wrapperMapper.find(cptr);
|
||||
return it != wrapperMapper.end();
|
||||
@@ -71,12 +72,11 @@ BindingManager& BindingManager::instance()
|
||||
|
||||
BindingManager::BindingManager()
|
||||
: p(new BindingManagerPrivate)
|
||||
{
|
||||
}
|
||||
{}
|
||||
|
||||
BindingManager::~BindingManager() = default;
|
||||
|
||||
bool BindingManager::hasWrapper(const void *cptr)
|
||||
bool BindingManager::hasWrapper(const void* cptr)
|
||||
{
|
||||
return p->hasWrapper(cptr);
|
||||
}
|
||||
|
||||
@@ -37,13 +37,18 @@ class BaseExport BindingManager
|
||||
public:
|
||||
static BindingManager& instance();
|
||||
|
||||
bool hasWrapper(const void *cptr);
|
||||
bool hasWrapper(const void* cptr);
|
||||
|
||||
void registerWrapper(const void* cptr, PyObject* pyObj);
|
||||
void releaseWrapper(const void* cptr, PyObject* pyObj);
|
||||
|
||||
PyObject* retrieveWrapper(const void* cptr);
|
||||
|
||||
BindingManager(const BindingManager&) = delete;
|
||||
BindingManager(BindingManager&&) = delete;
|
||||
BindingManager& operator=(const BindingManager&) = delete;
|
||||
BindingManager& operator=(BindingManager&&) = delete;
|
||||
|
||||
private:
|
||||
BindingManager();
|
||||
~BindingManager();
|
||||
@@ -52,6 +57,6 @@ private:
|
||||
std::unique_ptr<BindingManagerPrivate> p;
|
||||
};
|
||||
|
||||
}
|
||||
} // namespace Base
|
||||
|
||||
#endif // BASE_BINDINGMANAGER_H
|
||||
#endif // BASE_BINDINGMANAGER_H
|
||||
|
||||
@@ -44,6 +44,7 @@
|
||||
@endcode
|
||||
*/
|
||||
|
||||
// clang-format off
|
||||
// Based on https://stackoverflow.com/questions/1448396/how-to-use-enums-as-flags-in-c
|
||||
template<class T = void> struct enum_traits {};
|
||||
|
||||
@@ -128,5 +129,6 @@ public:
|
||||
}
|
||||
};
|
||||
}
|
||||
// clang-format on
|
||||
|
||||
#endif
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,20 +1,20 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<GenerateModel xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="generateMetaModel_Module.xsd">
|
||||
<PythonExport
|
||||
Father="PyObjectBase"
|
||||
Name="BoundBoxPy"
|
||||
Twin="BoundBox"
|
||||
TwinPointer="BoundBox3d"
|
||||
Include="Base/BoundBox.h"
|
||||
FatherInclude="Base/PyObjectBase.h"
|
||||
Namespace="Base"
|
||||
<PythonExport
|
||||
Father="PyObjectBase"
|
||||
Name="BoundBoxPy"
|
||||
Twin="BoundBox"
|
||||
TwinPointer="BoundBox3d"
|
||||
Include="Base/BoundBox.h"
|
||||
FatherInclude="Base/PyObjectBase.h"
|
||||
Namespace="Base"
|
||||
Constructor="true"
|
||||
Delete="true"
|
||||
Delete="true"
|
||||
FatherNamespace="Base">
|
||||
<Documentation>
|
||||
<Author Licence="LGPL" Name="Juergen Riegel" EMail="FreeCAD@juergen-riegel.net" />
|
||||
<DeveloperDocu>This is the BoundBox export class</DeveloperDocu>
|
||||
<UserDocu>Base.BoundBox class.
|
||||
<UserDocu>Base.BoundBox class.
|
||||
|
||||
This class represents a bounding box.
|
||||
A bounding box is a rectangular cuboid which is a way to describe outer
|
||||
@@ -23,50 +23,50 @@ It is often used to check if a 3D entity lies in the range of another object.
|
||||
Checking for bounding interference first can save a lot of computing time!
|
||||
An invalid BoundBox is represented by inconsistent values at each direction:
|
||||
The maximum float value of the system at the minimum coordinates, and the
|
||||
opposite value at the maximum coordinates.
|
||||
opposite value at the maximum coordinates.
|
||||
|
||||
The following constructors are supported:
|
||||
The following constructors are supported:
|
||||
|
||||
BoundBox()
|
||||
Empty constructor. Returns an invalid BoundBox.
|
||||
Empty constructor. Returns an invalid BoundBox.
|
||||
|
||||
BoundBox(boundBox)
|
||||
Copy constructor.
|
||||
boundBox : Base.BoundBox
|
||||
boundBox : Base.BoundBox
|
||||
|
||||
BoundBox(xMin, yMin=0, zMin=0, xMax=0, yMax=0, zMax=0)
|
||||
Define from the minimum and maximum values at each direction.
|
||||
xMin : float
|
||||
xMin : float
|
||||
Minimum value at x-coordinate.
|
||||
yMin : float
|
||||
yMin : float
|
||||
Minimum value at y-coordinate.
|
||||
zMin : float
|
||||
zMin : float
|
||||
Minimum value at z-coordinate.
|
||||
xMax : float
|
||||
xMax : float
|
||||
Maximum value at x-coordinate.
|
||||
yMax : float
|
||||
yMax : float
|
||||
Maximum value at y-coordinate.
|
||||
zMax : float
|
||||
Maximum value at z-coordinate.
|
||||
zMax : float
|
||||
Maximum value at z-coordinate.
|
||||
|
||||
App.BoundBox(min, max)
|
||||
Define from two containers representing the minimum and maximum values of the
|
||||
coordinates in each direction.
|
||||
min : Base.Vector, tuple
|
||||
min : Base.Vector, tuple
|
||||
Minimum values of the coordinates.
|
||||
max : Base.Vector, tuple
|
||||
max : Base.Vector, tuple
|
||||
Maximum values of the coordinates.</UserDocu>
|
||||
</Documentation>
|
||||
<Methode Name="setVoid">
|
||||
<Documentation>
|
||||
<UserDocu>setVoid() -> None
|
||||
<UserDocu>setVoid() -> None
|
||||
|
||||
Invalidate the bounding box.</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Methode Name="isValid">
|
||||
<Documentation>
|
||||
<UserDocu>isValid() -> bool
|
||||
<UserDocu>isValid() -> bool
|
||||
|
||||
Checks if the bounding box is valid.</UserDocu>
|
||||
</Documentation>
|
||||
@@ -74,38 +74,38 @@ Checks if the bounding box is valid.</UserDocu>
|
||||
<Methode Name="add">
|
||||
<Documentation>
|
||||
<UserDocu>add(minMax) -> None
|
||||
add(x, y, z) -> None
|
||||
add(x, y, z) -> None
|
||||
|
||||
Increase the maximum values or decrease the minimum values of this BoundBox by
|
||||
replacing the current values with the given values, so the bounding box can grow
|
||||
but not shrink.
|
||||
but not shrink.
|
||||
|
||||
minMax : Base.Vector, tuple
|
||||
minMax : Base.Vector, tuple
|
||||
Values to enlarge at each direction.
|
||||
x : float
|
||||
x : float
|
||||
Value to enlarge at x-direction.
|
||||
y : float
|
||||
y : float
|
||||
Value to enlarge at y-direction.
|
||||
z : float
|
||||
z : float
|
||||
Value to enlarge at z-direction.</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Methode Name="getPoint">
|
||||
<Documentation>
|
||||
<UserDocu>getPoint(index) ->Base.Vector
|
||||
<UserDocu>getPoint(index) ->Base.Vector
|
||||
|
||||
Get the point of the given index.
|
||||
The index must be in the range of [0, 7].
|
||||
The index must be in the range of [0, 7].
|
||||
|
||||
index : int</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Methode Name="getEdge">
|
||||
<Documentation>
|
||||
<UserDocu>getEdge(index) -> tuple of Base.Vector
|
||||
<UserDocu>getEdge(index) -> tuple of Base.Vector
|
||||
|
||||
Get the edge points of the given index.
|
||||
The index must be in the range of [0, 11].
|
||||
The index must be in the range of [0, 11].
|
||||
|
||||
index : int</UserDocu>
|
||||
</Documentation>
|
||||
@@ -113,27 +113,27 @@ index : int</UserDocu>
|
||||
<Methode Name="closestPoint">
|
||||
<Documentation>
|
||||
<UserDocu>closestPoint(point) -> Base.Vector
|
||||
closestPoint(x, y, z) -> Base.Vector
|
||||
closestPoint(x, y, z) -> Base.Vector
|
||||
|
||||
Get the closest point of the bounding box to the given point.
|
||||
Get the closest point of the bounding box to the given point.
|
||||
|
||||
point : Base.Vector, tuple
|
||||
point : Base.Vector, tuple
|
||||
Coordinates of the given point.
|
||||
x : float
|
||||
x : float
|
||||
X-coordinate of the given point.
|
||||
y : float
|
||||
y : float
|
||||
Y-coordinate of the given point.
|
||||
z : float
|
||||
z : float
|
||||
Z-coordinate of the given point.</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Methode Name="intersect">
|
||||
<Documentation>
|
||||
<UserDocu>intersect(boundBox2) -> bool
|
||||
intersect(base, dir) -> bool
|
||||
intersect(base, dir) -> bool
|
||||
|
||||
Checks if the given object intersects with this bounding box. That can be
|
||||
another bounding box or a line specified by base and direction.
|
||||
another bounding box or a line specified by base and direction.
|
||||
|
||||
boundBox2 : Base.BoundBox
|
||||
base : Base.Vector, tuple
|
||||
@@ -142,28 +142,28 @@ dir : Base.Vector, tuple</UserDocu>
|
||||
</Methode>
|
||||
<Methode Name="intersected">
|
||||
<Documentation>
|
||||
<UserDocu>intersected(boundBox2) -> Base.BoundBox
|
||||
<UserDocu>intersected(boundBox2) -> Base.BoundBox
|
||||
|
||||
Returns the intersection of this and the given bounding box.
|
||||
Returns the intersection of this and the given bounding box.
|
||||
|
||||
boundBox2 : Base.BoundBox</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Methode Name="united">
|
||||
<Documentation>
|
||||
<UserDocu>united(boundBox2) -> Base.BoundBox
|
||||
<UserDocu>united(boundBox2) -> Base.BoundBox
|
||||
|
||||
Returns the union of this and the given bounding box.
|
||||
Returns the union of this and the given bounding box.
|
||||
|
||||
boundBox2 : Base.BoundBox</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Methode Name="enlarge">
|
||||
<Documentation>
|
||||
<UserDocu>enlarge(variation) -> None
|
||||
<UserDocu>enlarge(variation) -> None
|
||||
|
||||
Decrease the minimum values and increase the maximum values by the given value.
|
||||
A negative value shrinks the bounding box.
|
||||
A negative value shrinks the bounding box.
|
||||
|
||||
variation : float</UserDocu>
|
||||
</Documentation>
|
||||
@@ -171,70 +171,70 @@ variation : float</UserDocu>
|
||||
|
||||
<Methode Name="getIntersectionPoint">
|
||||
<Documentation>
|
||||
<UserDocu>getIntersectionPoint(base, dir, epsilon=0.0001) -> Base.Vector
|
||||
<UserDocu>getIntersectionPoint(base, dir, epsilon=0.0001) -> Base.Vector
|
||||
|
||||
Calculate the intersection point of a line with the bounding box.
|
||||
The base point must lie inside the bounding box, if not an exception is thrown.
|
||||
The base point must lie inside the bounding box, if not an exception is thrown.
|
||||
|
||||
base : Base.Vector
|
||||
base : Base.Vector
|
||||
Base point of the line.
|
||||
dir : Base.Vector
|
||||
dir : Base.Vector
|
||||
Direction of the line.
|
||||
epsilon : float
|
||||
epsilon : float
|
||||
Bounding box size tolerance.</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Methode Name="move">
|
||||
<Documentation>
|
||||
<UserDocu>move(displacement) -> None
|
||||
move(x, y, z) -> None
|
||||
move(x, y, z) -> None
|
||||
|
||||
Move the bounding box by the given values.
|
||||
Move the bounding box by the given values.
|
||||
|
||||
displacement : Base.Vector, tuple
|
||||
displacement : Base.Vector, tuple
|
||||
Displacement at each direction.
|
||||
x : float
|
||||
x : float
|
||||
Displacement at x-direction.
|
||||
y : float
|
||||
y : float
|
||||
Displacement at y-direction.
|
||||
z : float
|
||||
z : float
|
||||
Displacement at z-direction.</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Methode Name="scale">
|
||||
<Documentation>
|
||||
<UserDocu>scale(factor) -> None
|
||||
scale(x, y, z) -> None
|
||||
scale(x, y, z) -> None
|
||||
|
||||
Scale the bounding box by the given values.
|
||||
Scale the bounding box by the given values.
|
||||
|
||||
factor : Base.Vector, tuple
|
||||
factor : Base.Vector, tuple
|
||||
Factor scale at each direction.
|
||||
x : float
|
||||
x : float
|
||||
Scale at x-direction.
|
||||
y : float
|
||||
y : float
|
||||
Scale at y-direction.
|
||||
z : float
|
||||
z : float
|
||||
Scale at z-direction.</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Methode Name="transformed">
|
||||
<Documentation>
|
||||
<UserDocu>transformed(matrix) -> Base.BoundBox
|
||||
<UserDocu>transformed(matrix) -> Base.BoundBox
|
||||
|
||||
Returns a new BoundBox containing the transformed rectangular cuboid
|
||||
represented by this BoundBox.
|
||||
represented by this BoundBox.
|
||||
|
||||
matrix : Base.Matrix
|
||||
matrix : Base.Matrix
|
||||
Transformation matrix.</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Methode Name="isCutPlane">
|
||||
<Documentation>
|
||||
<UserDocu>isCutPlane(base, normal) -> bool
|
||||
<UserDocu>isCutPlane(base, normal) -> bool
|
||||
|
||||
Check if the plane specified by base and normal intersects (cuts) this bounding
|
||||
box.
|
||||
box.
|
||||
|
||||
base : Base.Vector
|
||||
normal : Base.Vector</UserDocu>
|
||||
@@ -243,17 +243,17 @@ normal : Base.Vector</UserDocu>
|
||||
<Methode Name="isInside">
|
||||
<Documentation>
|
||||
<UserDocu>isInside(object) -> bool
|
||||
isInside(x, y, z) -> bool
|
||||
isInside(x, y, z) -> bool
|
||||
|
||||
Check if a point or a bounding box is inside this bounding box.
|
||||
Check if a point or a bounding box is inside this bounding box.
|
||||
|
||||
object : Base.Vector, Base.BoundBox
|
||||
object : Base.Vector, Base.BoundBox
|
||||
Object to check if it is inside this bounding box.
|
||||
x : float
|
||||
x : float
|
||||
X-coordinate of the point to check.
|
||||
y : float
|
||||
y : float
|
||||
Y-coordinate of the point to check.
|
||||
z : float
|
||||
z : float
|
||||
Z-coordinate of the point to check.</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
|
||||
@@ -37,18 +37,15 @@ std::string BoundBoxPy::representation() const
|
||||
{
|
||||
std::stringstream str;
|
||||
str << "BoundBox (";
|
||||
str << getBoundBoxPtr()->MinX << ", "
|
||||
<< getBoundBoxPtr()->MinY << ", "
|
||||
<< getBoundBoxPtr()->MinZ << ", "
|
||||
<< getBoundBoxPtr()->MaxX << ", "
|
||||
<< getBoundBoxPtr()->MaxY << ", "
|
||||
<< getBoundBoxPtr()->MaxZ ;
|
||||
str << getBoundBoxPtr()->MinX << ", " << getBoundBoxPtr()->MinY << ", "
|
||||
<< getBoundBoxPtr()->MinZ << ", " << getBoundBoxPtr()->MaxX << ", "
|
||||
<< getBoundBoxPtr()->MaxY << ", " << getBoundBoxPtr()->MaxZ;
|
||||
str << ")";
|
||||
|
||||
return str.str();
|
||||
}
|
||||
|
||||
PyObject *BoundBoxPy::PyMake(struct _typeobject *, PyObject *, PyObject *) // Python wrapper
|
||||
PyObject* BoundBoxPy::PyMake(struct _typeobject*, PyObject*, PyObject*) // Python wrapper
|
||||
{
|
||||
// create a new instance of BoundBoxPy and the Twin object
|
||||
return new BoundBoxPy(new BoundBox3d);
|
||||
@@ -60,10 +57,10 @@ int BoundBoxPy::PyInit(PyObject* args, PyObject* /*kwd*/)
|
||||
if (PyArg_ParseTuple(args, "")) {
|
||||
return 0;
|
||||
}
|
||||
PyErr_Clear(); // set by PyArg_ParseTuple()
|
||||
PyErr_Clear(); // set by PyArg_ParseTuple()
|
||||
|
||||
double xMin=0.0,yMin=0.0,zMin=0.0,xMax=0.0,yMax=0.0,zMax=0.0;
|
||||
PyObject *object1{}, *object2{};
|
||||
double xMin = 0.0, yMin = 0.0, zMin = 0.0, xMax = 0.0, yMax = 0.0, zMax = 0.0;
|
||||
PyObject *object1 {}, *object2 {};
|
||||
BoundBoxPy::PointerType ptr = getBoundBoxPtr();
|
||||
if (PyArg_ParseTuple(args, "d|ddddd", &xMin, &yMin, &zMin, &xMax, &yMax, &zMax)) {
|
||||
ptr->MaxX = xMax;
|
||||
@@ -74,9 +71,8 @@ int BoundBoxPy::PyInit(PyObject* args, PyObject* /*kwd*/)
|
||||
ptr->MinZ = zMin;
|
||||
return 0;
|
||||
}
|
||||
PyErr_Clear(); // set by PyArg_ParseTuple()
|
||||
if (PyArg_ParseTuple(args,"O!O!",&PyTuple_Type, &object1,
|
||||
&PyTuple_Type, &object2)) {
|
||||
PyErr_Clear(); // set by PyArg_ParseTuple()
|
||||
if (PyArg_ParseTuple(args, "O!O!", &PyTuple_Type, &object1, &PyTuple_Type, &object2)) {
|
||||
try {
|
||||
Vector3d v1 = getVectorFromTuple<double>(object1);
|
||||
Vector3d v2 = getVectorFromTuple<double>(object2);
|
||||
@@ -88,80 +84,92 @@ int BoundBoxPy::PyInit(PyObject* args, PyObject* /*kwd*/)
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
PyErr_Clear(); // set by PyArg_ParseTuple()
|
||||
if (PyArg_ParseTuple(args,"O!O!",&(Base::VectorPy::Type), &object1,
|
||||
&(Base::VectorPy::Type), &object2)) {
|
||||
PyErr_Clear(); // set by PyArg_ParseTuple()
|
||||
if (PyArg_ParseTuple(args,
|
||||
"O!O!",
|
||||
&(Base::VectorPy::Type),
|
||||
&object1,
|
||||
&(Base::VectorPy::Type),
|
||||
&object2)) {
|
||||
ptr->Add(*(static_cast<Base::VectorPy*>(object1)->getVectorPtr()));
|
||||
ptr->Add(*(static_cast<Base::VectorPy*>(object2)->getVectorPtr()));
|
||||
return 0;
|
||||
}
|
||||
PyErr_Clear(); // set by PyArg_ParseTuple()
|
||||
if (PyArg_ParseTuple(args,"O!",&(Base::BoundBoxPy::Type), &object1)) {
|
||||
PyErr_Clear(); // set by PyArg_ParseTuple()
|
||||
if (PyArg_ParseTuple(args, "O!", &(Base::BoundBoxPy::Type), &object1)) {
|
||||
*ptr = *(static_cast<Base::BoundBoxPy*>(object1)->getBoundBoxPtr());
|
||||
return 0;
|
||||
}
|
||||
|
||||
PyErr_SetString(PyExc_TypeError, "Either six floats, two instances of "
|
||||
"Vector/Tuple or instance of BoundBox expected");
|
||||
PyErr_SetString(PyExc_TypeError,
|
||||
"Either six floats, two instances of "
|
||||
"Vector/Tuple or instance of BoundBox expected");
|
||||
return -1;
|
||||
}
|
||||
|
||||
PyObject* BoundBoxPy::setVoid(PyObject *args)
|
||||
PyObject* BoundBoxPy::setVoid(PyObject* args)
|
||||
{
|
||||
if (!PyArg_ParseTuple(args,""))
|
||||
if (!PyArg_ParseTuple(args, "")) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
getBoundBoxPtr()->SetVoid();
|
||||
Py_Return;
|
||||
}
|
||||
|
||||
PyObject* BoundBoxPy::isValid(PyObject *args)
|
||||
PyObject* BoundBoxPy::isValid(PyObject* args)
|
||||
{
|
||||
if (!PyArg_ParseTuple(args,""))
|
||||
if (!PyArg_ParseTuple(args, "")) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return PyBool_FromLong(getBoundBoxPtr()->IsValid() ? 1 : 0);
|
||||
}
|
||||
|
||||
PyObject* BoundBoxPy::add(PyObject *args)
|
||||
PyObject* BoundBoxPy::add(PyObject* args)
|
||||
{
|
||||
double x{},y{},z{};
|
||||
PyObject *object{};
|
||||
if (PyArg_ParseTuple(args, "ddd", &x,&y,&z)) {
|
||||
getBoundBoxPtr()->Add(Vector3d(x,y,z));
|
||||
double x {}, y {}, z {};
|
||||
PyObject* object {};
|
||||
if (PyArg_ParseTuple(args, "ddd", &x, &y, &z)) {
|
||||
getBoundBoxPtr()->Add(Vector3d(x, y, z));
|
||||
Py_Return;
|
||||
}
|
||||
|
||||
PyErr_Clear();
|
||||
if (PyArg_ParseTuple(args,"O!",&PyTuple_Type, &object)) {
|
||||
if (PyArg_ParseTuple(args, "O!", &PyTuple_Type, &object)) {
|
||||
getBoundBoxPtr()->Add(getVectorFromTuple<double>(object));
|
||||
Py_Return;
|
||||
}
|
||||
|
||||
PyErr_Clear();
|
||||
if (PyArg_ParseTuple(args,"O!",&(Base::VectorPy::Type), &object)) {
|
||||
if (PyArg_ParseTuple(args, "O!", &(Base::VectorPy::Type), &object)) {
|
||||
getBoundBoxPtr()->Add(*(static_cast<Base::VectorPy*>(object)->getVectorPtr()));
|
||||
Py_Return;
|
||||
}
|
||||
|
||||
PyErr_Clear();
|
||||
if (PyArg_ParseTuple(args,"O!;Need a Vector, BoundBox or three floats as argument",&(Base::BoundBoxPy::Type), &object)) {
|
||||
if (PyArg_ParseTuple(args,
|
||||
"O!;Need a Vector, BoundBox or three floats as argument",
|
||||
&(Base::BoundBoxPy::Type),
|
||||
&object)) {
|
||||
getBoundBoxPtr()->Add(*(static_cast<Base::BoundBoxPy*>(object)->getBoundBoxPtr()));
|
||||
Py_Return;
|
||||
}
|
||||
|
||||
PyErr_SetString(PyExc_TypeError, "Either three floats, instance of Vector or instance of BoundBox expected");
|
||||
PyErr_SetString(PyExc_TypeError,
|
||||
"Either three floats, instance of Vector or instance of BoundBox expected");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
PyObject* BoundBoxPy::getPoint(PyObject *args)
|
||||
PyObject* BoundBoxPy::getPoint(PyObject* args)
|
||||
{
|
||||
unsigned short index{};
|
||||
if (!PyArg_ParseTuple(args,"H",&index))
|
||||
unsigned short index {};
|
||||
if (!PyArg_ParseTuple(args, "H", &index)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (index > 7) {
|
||||
PyErr_SetString (PyExc_IndexError, "Invalid point index");
|
||||
PyErr_SetString(PyExc_IndexError, "Invalid point index");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@@ -169,14 +177,15 @@ PyObject* BoundBoxPy::getPoint(PyObject *args)
|
||||
return new Base::VectorPy(new Base::Vector3d(pnt));
|
||||
}
|
||||
|
||||
PyObject* BoundBoxPy::getEdge(PyObject *args)
|
||||
PyObject* BoundBoxPy::getEdge(PyObject* args)
|
||||
{
|
||||
unsigned short index{};
|
||||
if (!PyArg_ParseTuple(args,"H",&index))
|
||||
unsigned short index {};
|
||||
if (!PyArg_ParseTuple(args, "H", &index)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (index > 11) {
|
||||
PyErr_SetString (PyExc_IndexError, "Invalid edge index");
|
||||
PyErr_SetString(PyExc_IndexError, "Invalid edge index");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@@ -188,27 +197,27 @@ PyObject* BoundBoxPy::getEdge(PyObject *args)
|
||||
return Py::new_reference_to(tuple);
|
||||
}
|
||||
|
||||
PyObject* BoundBoxPy::closestPoint(PyObject *args)
|
||||
PyObject* BoundBoxPy::closestPoint(PyObject* args)
|
||||
{
|
||||
double x{},y{},z{};
|
||||
PyObject *object{};
|
||||
double x {}, y {}, z {};
|
||||
PyObject* object {};
|
||||
|
||||
Base::Vector3d vec;
|
||||
|
||||
do {
|
||||
if (PyArg_ParseTuple(args, "ddd", &x,&y,&z)) {
|
||||
vec = Vector3d(x,y,z);
|
||||
if (PyArg_ParseTuple(args, "ddd", &x, &y, &z)) {
|
||||
vec = Vector3d(x, y, z);
|
||||
break;
|
||||
}
|
||||
|
||||
PyErr_Clear();
|
||||
if (PyArg_ParseTuple(args,"O!",&PyTuple_Type, &object)) {
|
||||
if (PyArg_ParseTuple(args, "O!", &PyTuple_Type, &object)) {
|
||||
vec = getVectorFromTuple<double>(object);
|
||||
break;
|
||||
}
|
||||
|
||||
PyErr_Clear();
|
||||
if (PyArg_ParseTuple(args,"O!",&(Base::VectorPy::Type), &object)) {
|
||||
if (PyArg_ParseTuple(args, "O!", &(Base::VectorPy::Type), &object)) {
|
||||
vec = *(static_cast<Base::VectorPy*>(object)->getVectorPtr());
|
||||
break;
|
||||
}
|
||||
@@ -216,110 +225,125 @@ PyObject* BoundBoxPy::closestPoint(PyObject *args)
|
||||
PyErr_SetString(PyExc_TypeError, "Either three floats or vector expected");
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
while(false);
|
||||
} while (false);
|
||||
|
||||
Base::Vector3d point = getBoundBoxPtr()->ClosestPoint(vec);
|
||||
return new Base::VectorPy(new Base::Vector3d(point));
|
||||
}
|
||||
|
||||
PyObject* BoundBoxPy::intersect(PyObject *args)
|
||||
PyObject* BoundBoxPy::intersect(PyObject* args)
|
||||
{
|
||||
PyObject *object{},*object2{};
|
||||
PyObject *object {}, *object2 {};
|
||||
Py::Boolean retVal;
|
||||
|
||||
if (!getBoundBoxPtr()->IsValid()) {
|
||||
PyErr_SetString (PyExc_FloatingPointError, "Invalid bounding box");
|
||||
PyErr_SetString(PyExc_FloatingPointError, "Invalid bounding box");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
do {
|
||||
if (PyArg_ParseTuple(args,"O!O!",&(Base::VectorPy::Type), &object,
|
||||
&(Base::VectorPy::Type), &object2)) {
|
||||
if (PyArg_ParseTuple(args,
|
||||
"O!O!",
|
||||
&(Base::VectorPy::Type),
|
||||
&object,
|
||||
&(Base::VectorPy::Type),
|
||||
&object2)) {
|
||||
retVal = getBoundBoxPtr()->IsCutLine(
|
||||
*(static_cast<Base::VectorPy*>(object )->getVectorPtr()),
|
||||
*(static_cast<Base::VectorPy*>(object)->getVectorPtr()),
|
||||
*(static_cast<Base::VectorPy*>(object2)->getVectorPtr()));
|
||||
break;
|
||||
}
|
||||
|
||||
PyErr_Clear();
|
||||
if (PyArg_ParseTuple(args,"O!",&(Base::BoundBoxPy::Type), &object)) {
|
||||
if (PyArg_ParseTuple(args, "O!", &(Base::BoundBoxPy::Type), &object)) {
|
||||
if (!static_cast<Base::BoundBoxPy*>(object)->getBoundBoxPtr()->IsValid()) {
|
||||
PyErr_SetString (PyExc_FloatingPointError, "Invalid bounding box argument");
|
||||
PyErr_SetString(PyExc_FloatingPointError, "Invalid bounding box argument");
|
||||
return nullptr;
|
||||
}
|
||||
retVal = getBoundBoxPtr()->Intersect(*(static_cast<Base::BoundBoxPy*>(object)->getBoundBoxPtr()));
|
||||
retVal = getBoundBoxPtr()->Intersect(
|
||||
*(static_cast<Base::BoundBoxPy*>(object)->getBoundBoxPtr()));
|
||||
break;
|
||||
}
|
||||
|
||||
PyErr_SetString(PyExc_TypeError, "Either BoundBox or two Vectors expected");
|
||||
return nullptr;
|
||||
}
|
||||
while(false);
|
||||
} while (false);
|
||||
|
||||
return Py::new_reference_to(retVal);
|
||||
}
|
||||
|
||||
PyObject* BoundBoxPy::intersected(PyObject *args)
|
||||
PyObject* BoundBoxPy::intersected(PyObject* args)
|
||||
{
|
||||
if (!getBoundBoxPtr()->IsValid()) {
|
||||
PyErr_SetString (PyExc_FloatingPointError, "Invalid bounding box");
|
||||
PyErr_SetString(PyExc_FloatingPointError, "Invalid bounding box");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
PyObject *object{};
|
||||
if (!PyArg_ParseTuple(args,"O!",&(Base::BoundBoxPy::Type), &object))
|
||||
PyObject* object {};
|
||||
if (!PyArg_ParseTuple(args, "O!", &(Base::BoundBoxPy::Type), &object)) {
|
||||
return nullptr;
|
||||
}
|
||||
if (!static_cast<Base::BoundBoxPy*>(object)->getBoundBoxPtr()->IsValid()) {
|
||||
PyErr_SetString (PyExc_FloatingPointError, "Invalid bounding box argument");
|
||||
PyErr_SetString(PyExc_FloatingPointError, "Invalid bounding box argument");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Base::BoundBox3d bbox = getBoundBoxPtr()->Intersected(*static_cast<Base::BoundBoxPy*>(object)->getBoundBoxPtr());
|
||||
Base::BoundBox3d bbox =
|
||||
getBoundBoxPtr()->Intersected(*static_cast<Base::BoundBoxPy*>(object)->getBoundBoxPtr());
|
||||
return new Base::BoundBoxPy(new Base::BoundBox3d(bbox));
|
||||
}
|
||||
|
||||
PyObject* BoundBoxPy::united(PyObject *args)
|
||||
PyObject* BoundBoxPy::united(PyObject* args)
|
||||
{
|
||||
if (!getBoundBoxPtr()->IsValid()) {
|
||||
PyErr_SetString (PyExc_FloatingPointError, "Invalid bounding box");
|
||||
PyErr_SetString(PyExc_FloatingPointError, "Invalid bounding box");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
PyObject *object{};
|
||||
if (!PyArg_ParseTuple(args,"O!",&(Base::BoundBoxPy::Type), &object))
|
||||
PyObject* object {};
|
||||
if (!PyArg_ParseTuple(args, "O!", &(Base::BoundBoxPy::Type), &object)) {
|
||||
return nullptr;
|
||||
}
|
||||
if (!static_cast<Base::BoundBoxPy*>(object)->getBoundBoxPtr()->IsValid()) {
|
||||
PyErr_SetString (PyExc_FloatingPointError, "Invalid bounding box argument");
|
||||
PyErr_SetString(PyExc_FloatingPointError, "Invalid bounding box argument");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Base::BoundBox3d bbox = getBoundBoxPtr()->United(*static_cast<Base::BoundBoxPy*>(object)->getBoundBoxPtr());
|
||||
Base::BoundBox3d bbox =
|
||||
getBoundBoxPtr()->United(*static_cast<Base::BoundBoxPy*>(object)->getBoundBoxPtr());
|
||||
return new Base::BoundBoxPy(new Base::BoundBox3d(bbox));
|
||||
}
|
||||
|
||||
PyObject* BoundBoxPy::enlarge(PyObject *args)
|
||||
PyObject* BoundBoxPy::enlarge(PyObject* args)
|
||||
{
|
||||
double s{};
|
||||
if (!PyArg_ParseTuple(args, "d;Need float parameter to enlarge", &s))
|
||||
double s {};
|
||||
if (!PyArg_ParseTuple(args, "d;Need float parameter to enlarge", &s)) {
|
||||
return nullptr;
|
||||
}
|
||||
getBoundBoxPtr()->Enlarge(s);
|
||||
Py_Return;
|
||||
}
|
||||
|
||||
PyObject* BoundBoxPy::getIntersectionPoint(PyObject *args)
|
||||
PyObject* BoundBoxPy::getIntersectionPoint(PyObject* args)
|
||||
{
|
||||
PyObject *object{},*object2{};
|
||||
double epsilon=0.0001;
|
||||
if (!PyArg_ParseTuple(args,"O!O!|d;Need base and direction vector",
|
||||
&(Base::VectorPy::Type), &object,&(Base::VectorPy::Type), &object2, &epsilon))
|
||||
PyObject *object {}, *object2 {};
|
||||
double epsilon = 0.0001;
|
||||
if (!PyArg_ParseTuple(args,
|
||||
"O!O!|d;Need base and direction vector",
|
||||
&(Base::VectorPy::Type),
|
||||
&object,
|
||||
&(Base::VectorPy::Type),
|
||||
&object2,
|
||||
&epsilon)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Base::Vector3d point;
|
||||
bool ok = getBoundBoxPtr()->IntersectionPoint(
|
||||
*(static_cast<Base::VectorPy*>(object)->getVectorPtr()),
|
||||
*(static_cast<Base::VectorPy*>(object2)->getVectorPtr()),
|
||||
point, epsilon);
|
||||
point,
|
||||
epsilon);
|
||||
if (ok) {
|
||||
return new VectorPy(point);
|
||||
}
|
||||
@@ -329,27 +353,27 @@ PyObject* BoundBoxPy::getIntersectionPoint(PyObject *args)
|
||||
}
|
||||
}
|
||||
|
||||
PyObject* BoundBoxPy::move(PyObject *args)
|
||||
PyObject* BoundBoxPy::move(PyObject* args)
|
||||
{
|
||||
double x{},y{},z{};
|
||||
PyObject *object{};
|
||||
double x {}, y {}, z {};
|
||||
PyObject* object {};
|
||||
|
||||
Base::Vector3d vec;
|
||||
|
||||
do {
|
||||
if (PyArg_ParseTuple(args, "ddd", &x,&y,&z)) {
|
||||
vec = Vector3d(x,y,z);
|
||||
if (PyArg_ParseTuple(args, "ddd", &x, &y, &z)) {
|
||||
vec = Vector3d(x, y, z);
|
||||
break;
|
||||
}
|
||||
|
||||
PyErr_Clear();
|
||||
if (PyArg_ParseTuple(args,"O!",&PyTuple_Type, &object)) {
|
||||
if (PyArg_ParseTuple(args, "O!", &PyTuple_Type, &object)) {
|
||||
vec = getVectorFromTuple<double>(object);
|
||||
break;
|
||||
}
|
||||
|
||||
PyErr_Clear();
|
||||
if (PyArg_ParseTuple(args,"O!",&(Base::VectorPy::Type), &object)) {
|
||||
if (PyArg_ParseTuple(args, "O!", &(Base::VectorPy::Type), &object)) {
|
||||
vec = *(static_cast<Base::VectorPy*>(object)->getVectorPtr());
|
||||
break;
|
||||
}
|
||||
@@ -357,8 +381,7 @@ PyObject* BoundBoxPy::move(PyObject *args)
|
||||
PyErr_SetString(PyExc_TypeError, "Either three floats or vector expected");
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
while(false);
|
||||
} while (false);
|
||||
|
||||
getBoundBoxPtr()->MoveX(vec.x);
|
||||
getBoundBoxPtr()->MoveY(vec.y);
|
||||
@@ -367,27 +390,27 @@ PyObject* BoundBoxPy::move(PyObject *args)
|
||||
Py_Return;
|
||||
}
|
||||
|
||||
PyObject* BoundBoxPy::scale(PyObject *args)
|
||||
PyObject* BoundBoxPy::scale(PyObject* args)
|
||||
{
|
||||
double x{},y{},z{};
|
||||
PyObject *object{};
|
||||
double x {}, y {}, z {};
|
||||
PyObject* object {};
|
||||
|
||||
Base::Vector3d vec;
|
||||
|
||||
do {
|
||||
if (PyArg_ParseTuple(args, "ddd", &x,&y,&z)) {
|
||||
vec = Vector3d(x,y,z);
|
||||
if (PyArg_ParseTuple(args, "ddd", &x, &y, &z)) {
|
||||
vec = Vector3d(x, y, z);
|
||||
break;
|
||||
}
|
||||
|
||||
PyErr_Clear();
|
||||
if (PyArg_ParseTuple(args,"O!",&PyTuple_Type, &object)) {
|
||||
if (PyArg_ParseTuple(args, "O!", &PyTuple_Type, &object)) {
|
||||
vec = getVectorFromTuple<double>(object);
|
||||
break;
|
||||
}
|
||||
|
||||
PyErr_Clear();
|
||||
if (PyArg_ParseTuple(args,"O!",&(Base::VectorPy::Type), &object)) {
|
||||
if (PyArg_ParseTuple(args, "O!", &(Base::VectorPy::Type), &object)) {
|
||||
vec = *(static_cast<Base::VectorPy*>(object)->getVectorPtr());
|
||||
break;
|
||||
}
|
||||
@@ -395,8 +418,7 @@ PyObject* BoundBoxPy::scale(PyObject *args)
|
||||
PyErr_SetString(PyExc_TypeError, "Either three floats or vector expected");
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
while(false);
|
||||
} while (false);
|
||||
|
||||
getBoundBoxPtr()->ScaleX(vec.x);
|
||||
getBoundBoxPtr()->ScaleY(vec.y);
|
||||
@@ -405,90 +427,98 @@ PyObject* BoundBoxPy::scale(PyObject *args)
|
||||
Py_Return;
|
||||
}
|
||||
|
||||
PyObject* BoundBoxPy::transformed(PyObject *args)
|
||||
PyObject* BoundBoxPy::transformed(PyObject* args)
|
||||
{
|
||||
PyObject *mat{};
|
||||
PyObject* mat {};
|
||||
|
||||
if (!PyArg_ParseTuple(args,"O!", &(Base::MatrixPy::Type), &mat))
|
||||
return nullptr;
|
||||
|
||||
if (!getBoundBoxPtr()->IsValid())
|
||||
throw Py::FloatingPointError("Cannot transform invalid bounding box");
|
||||
Base::BoundBox3d bbox = getBoundBoxPtr()->Transformed(*static_cast<Base::MatrixPy*>(mat)->getMatrixPtr());
|
||||
return new Base::BoundBoxPy(new Base::BoundBox3d(bbox));
|
||||
}
|
||||
|
||||
PyObject* BoundBoxPy::isCutPlane(PyObject *args)
|
||||
{
|
||||
PyObject *object{},*object2{};
|
||||
Py::Boolean retVal;
|
||||
|
||||
if (!getBoundBoxPtr()->IsValid()) {
|
||||
PyErr_SetString (PyExc_FloatingPointError, "Invalid bounding box");
|
||||
if (!PyArg_ParseTuple(args, "O!", &(Base::MatrixPy::Type), &mat)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (!PyArg_ParseTuple(args,"O!O!;Need base and normal vector of a plane",
|
||||
&(Base::VectorPy::Type), &object,&(Base::VectorPy::Type), &object2))
|
||||
return nullptr;
|
||||
if (!getBoundBoxPtr()->IsValid()) {
|
||||
throw Py::FloatingPointError("Cannot transform invalid bounding box");
|
||||
}
|
||||
Base::BoundBox3d bbox =
|
||||
getBoundBoxPtr()->Transformed(*static_cast<Base::MatrixPy*>(mat)->getMatrixPtr());
|
||||
return new Base::BoundBoxPy(new Base::BoundBox3d(bbox));
|
||||
}
|
||||
|
||||
retVal = getBoundBoxPtr()->IsCutPlane(
|
||||
*(static_cast<Base::VectorPy*>(object)->getVectorPtr()),
|
||||
*(static_cast<Base::VectorPy*>(object2)->getVectorPtr()));
|
||||
PyObject* BoundBoxPy::isCutPlane(PyObject* args)
|
||||
{
|
||||
PyObject *object {}, *object2 {};
|
||||
Py::Boolean retVal;
|
||||
|
||||
if (!getBoundBoxPtr()->IsValid()) {
|
||||
PyErr_SetString(PyExc_FloatingPointError, "Invalid bounding box");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (!PyArg_ParseTuple(args,
|
||||
"O!O!;Need base and normal vector of a plane",
|
||||
&(Base::VectorPy::Type),
|
||||
&object,
|
||||
&(Base::VectorPy::Type),
|
||||
&object2)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
retVal = getBoundBoxPtr()->IsCutPlane(*(static_cast<Base::VectorPy*>(object)->getVectorPtr()),
|
||||
*(static_cast<Base::VectorPy*>(object2)->getVectorPtr()));
|
||||
|
||||
return Py::new_reference_to(retVal);
|
||||
}
|
||||
|
||||
PyObject* BoundBoxPy::isInside(PyObject *args)
|
||||
PyObject* BoundBoxPy::isInside(PyObject* args)
|
||||
{
|
||||
double x{},y{},z{};
|
||||
PyObject *object{};
|
||||
double x {}, y {}, z {};
|
||||
PyObject* object {};
|
||||
Py::Boolean retVal;
|
||||
|
||||
if (!getBoundBoxPtr()->IsValid()) {
|
||||
PyErr_SetString (PyExc_FloatingPointError, "Invalid bounding box");
|
||||
PyErr_SetString(PyExc_FloatingPointError, "Invalid bounding box");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
do {
|
||||
if (PyArg_ParseTuple(args, "ddd", &x,&y,&z)) {
|
||||
retVal = getBoundBoxPtr()->IsInBox(Vector3d(x,y,z));
|
||||
if (PyArg_ParseTuple(args, "ddd", &x, &y, &z)) {
|
||||
retVal = getBoundBoxPtr()->IsInBox(Vector3d(x, y, z));
|
||||
break;
|
||||
}
|
||||
|
||||
PyErr_Clear();
|
||||
if (PyArg_ParseTuple(args,"O!",&PyTuple_Type, &object)) {
|
||||
if (PyArg_ParseTuple(args, "O!", &PyTuple_Type, &object)) {
|
||||
retVal = getBoundBoxPtr()->IsInBox(getVectorFromTuple<double>(object));
|
||||
break;
|
||||
}
|
||||
|
||||
PyErr_Clear();
|
||||
if (PyArg_ParseTuple(args,"O!",&(Base::VectorPy::Type), &object)) {
|
||||
retVal = getBoundBoxPtr()->IsInBox(*(static_cast<Base::VectorPy*>(object)->getVectorPtr()));
|
||||
if (PyArg_ParseTuple(args, "O!", &(Base::VectorPy::Type), &object)) {
|
||||
retVal =
|
||||
getBoundBoxPtr()->IsInBox(*(static_cast<Base::VectorPy*>(object)->getVectorPtr()));
|
||||
break;
|
||||
}
|
||||
|
||||
PyErr_Clear();
|
||||
if (PyArg_ParseTuple(args,"O!",&(Base::BoundBoxPy::Type), &object)) {
|
||||
if (PyArg_ParseTuple(args, "O!", &(Base::BoundBoxPy::Type), &object)) {
|
||||
if (!static_cast<Base::BoundBoxPy*>(object)->getBoundBoxPtr()->IsValid()) {
|
||||
PyErr_SetString (PyExc_FloatingPointError, "Invalid bounding box argument");
|
||||
PyErr_SetString(PyExc_FloatingPointError, "Invalid bounding box argument");
|
||||
return nullptr;
|
||||
}
|
||||
retVal = getBoundBoxPtr()->IsInBox(*(static_cast<Base::BoundBoxPy*>(object)->getBoundBoxPtr()));
|
||||
retVal = getBoundBoxPtr()->IsInBox(
|
||||
*(static_cast<Base::BoundBoxPy*>(object)->getBoundBoxPtr()));
|
||||
break;
|
||||
}
|
||||
|
||||
PyErr_SetString(PyExc_TypeError, "Either three floats, Vector(s) or BoundBox expected");
|
||||
return nullptr;
|
||||
}
|
||||
while(false);
|
||||
} while (false);
|
||||
|
||||
return Py::new_reference_to(retVal);
|
||||
}
|
||||
|
||||
Py::Object BoundBoxPy::getCenter() const
|
||||
{
|
||||
return Py::Vector(getBoundBoxPtr()->GetCenter()); // NOLINT
|
||||
return Py::Vector(getBoundBoxPtr()->GetCenter()); // NOLINT
|
||||
}
|
||||
|
||||
Py::Float BoundBoxPy::getXMax() const
|
||||
@@ -496,7 +526,7 @@ Py::Float BoundBoxPy::getXMax() const
|
||||
return Py::Float(getBoundBoxPtr()->MaxX);
|
||||
}
|
||||
|
||||
void BoundBoxPy::setXMax(Py::Float arg)
|
||||
void BoundBoxPy::setXMax(Py::Float arg)
|
||||
{
|
||||
getBoundBoxPtr()->MaxX = arg;
|
||||
}
|
||||
@@ -506,7 +536,7 @@ Py::Float BoundBoxPy::getYMax() const
|
||||
return Py::Float(getBoundBoxPtr()->MaxY);
|
||||
}
|
||||
|
||||
void BoundBoxPy::setYMax(Py::Float arg)
|
||||
void BoundBoxPy::setYMax(Py::Float arg)
|
||||
{
|
||||
getBoundBoxPtr()->MaxY = arg;
|
||||
}
|
||||
@@ -516,7 +546,7 @@ Py::Float BoundBoxPy::getZMax() const
|
||||
return Py::Float(getBoundBoxPtr()->MaxZ);
|
||||
}
|
||||
|
||||
void BoundBoxPy::setZMax(Py::Float arg)
|
||||
void BoundBoxPy::setZMax(Py::Float arg)
|
||||
{
|
||||
getBoundBoxPtr()->MaxZ = arg;
|
||||
}
|
||||
@@ -526,7 +556,7 @@ Py::Float BoundBoxPy::getXMin() const
|
||||
return Py::Float(getBoundBoxPtr()->MinX);
|
||||
}
|
||||
|
||||
void BoundBoxPy::setXMin(Py::Float arg)
|
||||
void BoundBoxPy::setXMin(Py::Float arg)
|
||||
{
|
||||
getBoundBoxPtr()->MinX = arg;
|
||||
}
|
||||
@@ -536,7 +566,7 @@ Py::Float BoundBoxPy::getYMin() const
|
||||
return Py::Float(getBoundBoxPtr()->MinY);
|
||||
}
|
||||
|
||||
void BoundBoxPy::setYMin(Py::Float arg)
|
||||
void BoundBoxPy::setYMin(Py::Float arg)
|
||||
{
|
||||
getBoundBoxPtr()->MinY = arg;
|
||||
}
|
||||
@@ -546,7 +576,7 @@ Py::Float BoundBoxPy::getZMin() const
|
||||
return Py::Float(getBoundBoxPtr()->MinZ);
|
||||
}
|
||||
|
||||
void BoundBoxPy::setZMin(Py::Float arg)
|
||||
void BoundBoxPy::setZMin(Py::Float arg)
|
||||
{
|
||||
getBoundBoxPtr()->MinZ = arg;
|
||||
}
|
||||
@@ -568,12 +598,13 @@ Py::Float BoundBoxPy::getZLength() const
|
||||
|
||||
Py::Float BoundBoxPy::getDiagonalLength() const
|
||||
{
|
||||
if (!getBoundBoxPtr()->IsValid())
|
||||
if (!getBoundBoxPtr()->IsValid()) {
|
||||
throw Py::FloatingPointError("Cannot determine diagonal length of invalid bounding box");
|
||||
}
|
||||
return Py::Float(getBoundBoxPtr()->CalcDiagonalLength());
|
||||
}
|
||||
|
||||
PyObject *BoundBoxPy::getCustomAttributes(const char* /*attr*/) const
|
||||
PyObject* BoundBoxPy::getCustomAttributes(const char* /*attr*/) const
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
@@ -582,5 +613,3 @@ int BoundBoxPy::setCustomAttributes(const char* /*attr*/, PyObject* /*obj*/)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -24,16 +24,16 @@
|
||||
#include "PreCompiled.h"
|
||||
|
||||
#ifndef _PreComp_
|
||||
# include <algorithm>
|
||||
# include <cassert>
|
||||
# include <exception>
|
||||
# include <string>
|
||||
# include <string_view>
|
||||
# include <fstream>
|
||||
# include <boost/algorithm/string.hpp>
|
||||
# include <boost/algorithm/string/predicate.hpp>
|
||||
# include <boost/lexical_cast.hpp>
|
||||
# include <boost/tokenizer.hpp>
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#include <exception>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <fstream>
|
||||
#include <boost/algorithm/string.hpp>
|
||||
#include <boost/algorithm/string/predicate.hpp>
|
||||
#include <boost/lexical_cast.hpp>
|
||||
#include <boost/tokenizer.hpp>
|
||||
#endif
|
||||
|
||||
#include "Builder3D.h"
|
||||
@@ -51,16 +51,13 @@ using namespace Base;
|
||||
constexpr float valueMinLegal {-1.0F};
|
||||
constexpr float valueMaxLegal {1.0F};
|
||||
|
||||
ColorRGB::ColorRGB() : Rgb{1.0F, 1.0F, 1.0F}
|
||||
{
|
||||
}
|
||||
ColorRGB::ColorRGB()
|
||||
: Rgb {1.0F, 1.0F, 1.0F}
|
||||
{}
|
||||
|
||||
ColorRGB::ColorRGB(float red, float green, float blue)
|
||||
: Rgb{valueInRange(red),
|
||||
valueInRange(green),
|
||||
valueInRange(blue)}
|
||||
{
|
||||
}
|
||||
: Rgb {valueInRange(red), valueInRange(green), valueInRange(blue)}
|
||||
{}
|
||||
|
||||
float ColorRGB::valueInRange(float value)
|
||||
{
|
||||
@@ -70,14 +67,14 @@ float ColorRGB::valueInRange(float value)
|
||||
const char* DrawStyle::styleAsString() const
|
||||
{
|
||||
switch (style) {
|
||||
case Style::Filled:
|
||||
return "FILLED";
|
||||
case Style::Lines:
|
||||
return "LINES";
|
||||
case Style::Points:
|
||||
return "POINTS";
|
||||
case Style::Invisible:
|
||||
return "INVISIBLE";
|
||||
case Style::Filled:
|
||||
return "FILLED";
|
||||
case Style::Lines:
|
||||
return "LINES";
|
||||
case Style::Points:
|
||||
return "POINTS";
|
||||
case Style::Invisible:
|
||||
return "INVISIBLE";
|
||||
}
|
||||
return "FILLED";
|
||||
}
|
||||
@@ -92,12 +89,12 @@ std::string DrawStyle::patternAsString() const
|
||||
const char* VertexOrdering::toString() const
|
||||
{
|
||||
switch (ordering) {
|
||||
case Ordering::UnknownOrdering:
|
||||
return "UNKNOWN_ORDERING";
|
||||
case Ordering::Clockwise:
|
||||
return "CLOCKWISE";
|
||||
case Ordering::CounterClockwise:
|
||||
return "COUNTERCLOCKWISE";
|
||||
case Ordering::UnknownOrdering:
|
||||
return "UNKNOWN_ORDERING";
|
||||
case Ordering::Clockwise:
|
||||
return "CLOCKWISE";
|
||||
case Ordering::CounterClockwise:
|
||||
return "COUNTERCLOCKWISE";
|
||||
}
|
||||
return "UNKNOWN_ORDERING";
|
||||
}
|
||||
@@ -105,10 +102,10 @@ const char* VertexOrdering::toString() const
|
||||
const char* ShapeType::toString() const
|
||||
{
|
||||
switch (type) {
|
||||
case Type::UnknownShapeType:
|
||||
return "UNKNOWN_SHAPE_TYPE";
|
||||
case Type::Convex:
|
||||
return "SOLID";
|
||||
case Type::UnknownShapeType:
|
||||
return "UNKNOWN_SHAPE_TYPE";
|
||||
case Type::Convex:
|
||||
return "SOLID";
|
||||
}
|
||||
return "UNKNOWN_SHAPE_TYPE";
|
||||
}
|
||||
@@ -116,32 +113,32 @@ const char* ShapeType::toString() const
|
||||
const char* BindingElement::bindingAsString() const
|
||||
{
|
||||
switch (value) {
|
||||
case Binding::PerPart:
|
||||
return "PER_PART";
|
||||
case Binding::PerPartIndexed:
|
||||
return "PER_PART_INDEXED";
|
||||
case Binding::PerFace:
|
||||
return "PER_FACE";
|
||||
case Binding::PerFaceIndexed:
|
||||
return "PER_FACE_INDEXED";
|
||||
case Binding::PerVertex:
|
||||
return "PER_VERTEX";
|
||||
case Binding::PerVertexIndexed:
|
||||
return "PER_VERTEX_INDEXED";
|
||||
default:
|
||||
return "OVERALL";
|
||||
case Binding::PerPart:
|
||||
return "PER_PART";
|
||||
case Binding::PerPartIndexed:
|
||||
return "PER_PART_INDEXED";
|
||||
case Binding::PerFace:
|
||||
return "PER_FACE";
|
||||
case Binding::PerFaceIndexed:
|
||||
return "PER_FACE_INDEXED";
|
||||
case Binding::PerVertex:
|
||||
return "PER_VERTEX";
|
||||
case Binding::PerVertexIndexed:
|
||||
return "PER_VERTEX_INDEXED";
|
||||
default:
|
||||
return "OVERALL";
|
||||
}
|
||||
}
|
||||
|
||||
const char* PolygonOffset::styleAsString() const
|
||||
{
|
||||
switch (style) {
|
||||
case Style::Filled:
|
||||
return "FILLED";
|
||||
case Style::Lines:
|
||||
return "LINES";
|
||||
case Style::Points:
|
||||
return "POINTS";
|
||||
case Style::Filled:
|
||||
return "FILLED";
|
||||
case Style::Lines:
|
||||
return "LINES";
|
||||
case Style::Points:
|
||||
return "POINTS";
|
||||
}
|
||||
return "FILLED";
|
||||
}
|
||||
@@ -149,10 +146,9 @@ const char* PolygonOffset::styleAsString() const
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
InventorOutput::InventorOutput(std::ostream& result, Indentation& indent)
|
||||
: result(result)
|
||||
, indent(indent)
|
||||
{
|
||||
}
|
||||
: result(result)
|
||||
, indent(indent)
|
||||
{}
|
||||
|
||||
std::ostream& InventorOutput::stream()
|
||||
{
|
||||
@@ -207,32 +203,41 @@ void InventorOutput::decreaseIndent()
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
namespace Base {
|
||||
template <class type>
|
||||
struct field_traits { };
|
||||
namespace Base
|
||||
{
|
||||
template<class type>
|
||||
struct field_traits
|
||||
{
|
||||
};
|
||||
|
||||
template <>
|
||||
struct field_traits<float> {
|
||||
template<>
|
||||
struct field_traits<float>
|
||||
{
|
||||
using field_type = float;
|
||||
static std::ostream& write(std::ostream& out, const field_type& item) {
|
||||
static std::ostream& write(std::ostream& out, const field_type& item)
|
||||
{
|
||||
out << item;
|
||||
return out;
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct field_traits<Vector3f> {
|
||||
template<>
|
||||
struct field_traits<Vector3f>
|
||||
{
|
||||
using field_type = Vector3f;
|
||||
static std::ostream& write(std::ostream& out, const field_type& item) {
|
||||
static std::ostream& write(std::ostream& out, const field_type& item)
|
||||
{
|
||||
out << item.x << " " << item.y << " " << item.z;
|
||||
return out;
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct field_traits<ColorRGB> {
|
||||
template<>
|
||||
struct field_traits<ColorRGB>
|
||||
{
|
||||
using field_type = ColorRGB;
|
||||
static std::ostream& write(std::ostream& out, const field_type& item) {
|
||||
static std::ostream& write(std::ostream& out, const field_type& item)
|
||||
{
|
||||
out << item.red() << " " << item.green() << " " << item.blue();
|
||||
return out;
|
||||
}
|
||||
@@ -242,17 +247,21 @@ struct field_traits<ColorRGB> {
|
||||
* Writes a field type to a stream.
|
||||
* @author Werner Mayer
|
||||
*/
|
||||
class InventorFieldWriter {
|
||||
class InventorFieldWriter
|
||||
{
|
||||
public:
|
||||
template<typename T>
|
||||
void write(const char* fieldName, const std::vector<T>& fieldData, InventorOutput& out) const;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
void InventorFieldWriter::write(const char* fieldName, const std::vector<T>& fieldData, InventorOutput& out) const
|
||||
void InventorFieldWriter::write(const char* fieldName,
|
||||
const std::vector<T>& fieldData,
|
||||
InventorOutput& out) const
|
||||
{
|
||||
if (fieldData.empty())
|
||||
if (fieldData.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (fieldData.size() == 1) {
|
||||
out.write() << fieldName << " ";
|
||||
@@ -271,36 +280,42 @@ void InventorFieldWriter::write(const char* fieldName, const std::vector<T>& fie
|
||||
}
|
||||
|
||||
template<>
|
||||
void InventorFieldWriter::write<int>(const char* fieldName, const std::vector<int>& fieldData, InventorOutput& out) const
|
||||
void InventorFieldWriter::write<int>(const char* fieldName,
|
||||
const std::vector<int>& fieldData,
|
||||
InventorOutput& out) const
|
||||
{
|
||||
if (fieldData.empty())
|
||||
if (fieldData.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
out.write() << fieldName << " [\n";
|
||||
out.increaseIndent();
|
||||
std::size_t last_index{fieldData.size()};
|
||||
std::size_t index{};
|
||||
std::size_t last_index {fieldData.size()};
|
||||
std::size_t index {};
|
||||
for (auto it : fieldData) {
|
||||
if (index % 8 == 0)
|
||||
if (index % 8 == 0) {
|
||||
out.write();
|
||||
if (index < last_index)
|
||||
}
|
||||
if (index < last_index) {
|
||||
out.stream() << it << ", ";
|
||||
else
|
||||
}
|
||||
else {
|
||||
out.stream() << it << " ] \n";
|
||||
if (++index % 8 == 0)
|
||||
}
|
||||
if (++index % 8 == 0) {
|
||||
out.stream() << '\n';
|
||||
}
|
||||
}
|
||||
out.decreaseIndent();
|
||||
out.write() << "]\n";
|
||||
}
|
||||
}
|
||||
} // namespace Base
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
LabelItem::LabelItem(const std::string& text) : text(text)
|
||||
{
|
||||
|
||||
}
|
||||
LabelItem::LabelItem(const std::string& text)
|
||||
: text(text)
|
||||
{}
|
||||
|
||||
void LabelItem::write(InventorOutput& out) const
|
||||
{
|
||||
@@ -311,10 +326,9 @@ void LabelItem::write(InventorOutput& out) const
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
InfoItem::InfoItem(const std::string& text) : text(text)
|
||||
{
|
||||
|
||||
}
|
||||
InfoItem::InfoItem(const std::string& text)
|
||||
: text(text)
|
||||
{}
|
||||
|
||||
void InfoItem::write(InventorOutput& out) const
|
||||
{
|
||||
@@ -325,10 +339,9 @@ void InfoItem::write(InventorOutput& out) const
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
BaseColorItem::BaseColorItem(const ColorRGB& rgb) : rgb(rgb)
|
||||
{
|
||||
|
||||
}
|
||||
BaseColorItem::BaseColorItem(const ColorRGB& rgb)
|
||||
: rgb(rgb)
|
||||
{}
|
||||
|
||||
void BaseColorItem::write(InventorOutput& out) const
|
||||
{
|
||||
@@ -343,15 +356,14 @@ PointItem::PointItem(const Base::Vector3f& point, DrawStyle drawStyle, const Col
|
||||
: point(point)
|
||||
, drawStyle(drawStyle)
|
||||
, rgb(rgb)
|
||||
{
|
||||
|
||||
}
|
||||
{}
|
||||
|
||||
void PointItem::write(InventorOutput& out) const
|
||||
{
|
||||
out.write() << "Separator { \n";
|
||||
out.write() << " Material { \n";
|
||||
out.write() << " diffuseColor " << rgb.red() << " "<< rgb.green() << " "<< rgb.blue() << '\n';
|
||||
out.write() << " diffuseColor " << rgb.red() << " " << rgb.green() << " " << rgb.blue()
|
||||
<< '\n';
|
||||
out.write() << " }\n";
|
||||
out.write() << " MaterialBinding { value PER_PART }\n";
|
||||
out.write() << " DrawStyle { pointSize " << drawStyle.pointSize << "}\n";
|
||||
@@ -359,7 +371,7 @@ void PointItem::write(InventorOutput& out) const
|
||||
out.write() << " point [ " << point.x << " " << point.y << " " << point.z << "]\n";
|
||||
out.write() << " }\n";
|
||||
out.write() << " PointSet { }\n";
|
||||
out.write() <<"}\n";
|
||||
out.write() << "}\n";
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
@@ -368,21 +380,21 @@ LineItem::LineItem(const Base::Line3f& line, DrawStyle drawStyle, const ColorRGB
|
||||
: line(line)
|
||||
, drawStyle(drawStyle)
|
||||
, rgb(rgb)
|
||||
{
|
||||
|
||||
}
|
||||
{}
|
||||
|
||||
void LineItem::write(InventorOutput& out) const
|
||||
{
|
||||
std::string pattern = drawStyle.patternAsString();
|
||||
|
||||
out.write(" Separator { \n");
|
||||
out.write() << " Material { diffuseColor " << rgb.red() << " "<< rgb.green() << " "<< rgb.blue() << "} \n";
|
||||
out.write() << " DrawStyle { lineWidth " << drawStyle.lineWidth << " linePattern " << pattern << " } \n";
|
||||
out.write() << " Material { diffuseColor " << rgb.red() << " " << rgb.green() << " "
|
||||
<< rgb.blue() << "} \n";
|
||||
out.write() << " DrawStyle { lineWidth " << drawStyle.lineWidth << " linePattern " << pattern
|
||||
<< " } \n";
|
||||
out.write() << " Coordinate3 { \n";
|
||||
out.write() << " point [ ";
|
||||
out.write() << line.p1.x << " " << line.p1.y << " " << line.p1.z << ",";
|
||||
out.write() << line.p2.x << " " << line.p2.y << " " << line.p2.z;
|
||||
out.write() << line.p1.x << " " << line.p1.y << " " << line.p1.z << ",";
|
||||
out.write() << line.p2.x << " " << line.p2.y << " " << line.p2.z;
|
||||
out.write() << " ] \n";
|
||||
out.write() << " } \n";
|
||||
out.write() << " LineSet { } \n";
|
||||
@@ -391,21 +403,23 @@ void LineItem::write(InventorOutput& out) const
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
MultiLineItem::MultiLineItem(const std::vector<Vector3f>& points, DrawStyle drawStyle, const ColorRGB& rgb)
|
||||
: points{points}
|
||||
, drawStyle{drawStyle}
|
||||
, rgb{rgb}
|
||||
{
|
||||
|
||||
}
|
||||
MultiLineItem::MultiLineItem(const std::vector<Vector3f>& points,
|
||||
DrawStyle drawStyle,
|
||||
const ColorRGB& rgb)
|
||||
: points {points}
|
||||
, drawStyle {drawStyle}
|
||||
, rgb {rgb}
|
||||
{}
|
||||
|
||||
void MultiLineItem::write(InventorOutput& out) const
|
||||
{
|
||||
std::string pattern = drawStyle.patternAsString();
|
||||
|
||||
out.write() << "Separator {\n";
|
||||
out.write() << " Material { diffuseColor " << rgb.red() << " "<< rgb.green() << " "<< rgb.blue() << "}\n";
|
||||
out.write() << " DrawStyle { lineWidth " << drawStyle.lineWidth << " linePattern " << pattern << " }\n";
|
||||
out.write() << " Material { diffuseColor " << rgb.red() << " " << rgb.green() << " "
|
||||
<< rgb.blue() << "}\n";
|
||||
out.write() << " DrawStyle { lineWidth " << drawStyle.lineWidth << " linePattern " << pattern
|
||||
<< " }\n";
|
||||
out.write() << " Coordinate3 {\n";
|
||||
|
||||
InventorFieldWriter writer;
|
||||
@@ -424,9 +438,7 @@ ArrowItem::ArrowItem(const Base::Line3f& line, DrawStyle drawStyle, const ColorR
|
||||
: line(line)
|
||||
, drawStyle(drawStyle)
|
||||
, rgb(rgb)
|
||||
{
|
||||
|
||||
}
|
||||
{}
|
||||
|
||||
void ArrowItem::write(InventorOutput& out) const
|
||||
{
|
||||
@@ -434,7 +446,7 @@ void ArrowItem::write(InventorOutput& out) const
|
||||
float coneLength = length / 10.0F;
|
||||
float coneRadius = coneLength / 2.0F;
|
||||
float sf1 = length - coneLength;
|
||||
float sf2 = length - coneLength/2.0F;
|
||||
float sf2 = length - coneLength / 2.0F;
|
||||
|
||||
Vector3f dir = line.GetDirection();
|
||||
dir.Normalize();
|
||||
@@ -449,20 +461,19 @@ void ArrowItem::write(InventorOutput& out) const
|
||||
float angle = Vector3f(0.0f, 1.0f, 0.0f).GetAngle(dir);
|
||||
|
||||
out.write() << "Separator {\n";
|
||||
out.write() << " Material { diffuseColor " << rgb.red() << " "<< rgb.green() << " "<< rgb.blue() << "}\n";
|
||||
out.write() << " Material { diffuseColor " << rgb.red() << " " << rgb.green() << " "
|
||||
<< rgb.blue() << "}\n";
|
||||
out.write() << " DrawStyle { lineWidth " << drawStyle.lineWidth << " }\n";
|
||||
out.write() << " Coordinate3 {\n";
|
||||
out.write() << " point [ ";
|
||||
out.write() << line.p1.x << " " << line.p1.y << " " << line.p1.z << ", ";
|
||||
out.write() << pt2s.x << " " << pt2s.y << " " << pt2s.z;
|
||||
out.write() << line.p1.x << " " << line.p1.y << " " << line.p1.z << ", ";
|
||||
out.write() << pt2s.x << " " << pt2s.y << " " << pt2s.z;
|
||||
out.write() << " ]\n";
|
||||
out.write() << " }\n";
|
||||
out.write() << " LineSet { }\n";
|
||||
out.write() << " Transform { \n";
|
||||
out.write() << " translation "
|
||||
<< cpt.x << " " << cpt.y << " " << cpt.z << '\n';
|
||||
out.write() << " rotation "
|
||||
<< rot.x << " " << rot.y << " " << rot.z << " " << angle << '\n';
|
||||
out.write() << " translation " << cpt.x << " " << cpt.y << " " << cpt.z << '\n';
|
||||
out.write() << " rotation " << rot.x << " " << rot.y << " " << rot.z << " " << angle << '\n';
|
||||
out.write() << " }\n";
|
||||
out.write() << " Cone { bottomRadius " << coneRadius << " height " << coneLength << "} \n";
|
||||
out.write() << "}\n";
|
||||
@@ -470,14 +481,15 @@ void ArrowItem::write(InventorOutput& out) const
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
BoundingBoxItem::BoundingBoxItem(const Vector3f& pt1, const Vector3f& pt2, DrawStyle drawStyle, const ColorRGB& rgb)
|
||||
: pt1{pt1}
|
||||
, pt2{pt2}
|
||||
, drawStyle{drawStyle}
|
||||
, rgb{rgb}
|
||||
{
|
||||
|
||||
}
|
||||
BoundingBoxItem::BoundingBoxItem(const Vector3f& pt1,
|
||||
const Vector3f& pt2,
|
||||
DrawStyle drawStyle,
|
||||
const ColorRGB& rgb)
|
||||
: pt1 {pt1}
|
||||
, pt2 {pt2}
|
||||
, drawStyle {drawStyle}
|
||||
, rgb {rgb}
|
||||
{}
|
||||
|
||||
void BoundingBoxItem::write(InventorOutput& out) const
|
||||
{
|
||||
@@ -491,24 +503,20 @@ void BoundingBoxItem::write(InventorOutput& out) const
|
||||
points[6].Set(pt2.x, pt2.y, pt1.z);
|
||||
points[7].Set(pt2.x, pt2.y, pt2.z);
|
||||
|
||||
std::vector<int> lineset = {
|
||||
0, 2, 6, 4, 0, -1,
|
||||
1, 5, 7, 3, 1, -1,
|
||||
7, 6, 2, 3, 7, -1,
|
||||
3, 2, 0, 1, 3, -1,
|
||||
5, 1, 0, 4, 5, -1
|
||||
};
|
||||
std::vector<int> lineset = {0, 2, 6, 4, 0, -1, 1, 5, 7, 3, 1, -1, 7, 6, 2,
|
||||
3, 7, -1, 3, 2, 0, 1, 3, -1, 5, 1, 0, 4, 5, -1};
|
||||
|
||||
out.write() << "Separator {\n";
|
||||
out.write() << " Material { diffuseColor " << rgb.red() << " "<< rgb.green() << " "<< rgb.blue() << "}\n";
|
||||
out.write() << " Material { diffuseColor " << rgb.red() << " " << rgb.green() << " "
|
||||
<< rgb.blue() << "}\n";
|
||||
out.write() << " DrawStyle { lineWidth " << drawStyle.lineWidth << "}\n";
|
||||
|
||||
Coordinate3Item coords{points};
|
||||
Coordinate3Item coords {points};
|
||||
out.increaseIndent();
|
||||
coords.write(out);
|
||||
out.decreaseIndent();
|
||||
|
||||
IndexedLineSetItem indexed{lineset};
|
||||
IndexedLineSetItem indexed {lineset};
|
||||
out.increaseIndent();
|
||||
indexed.write(out);
|
||||
out.decreaseIndent();
|
||||
@@ -622,16 +630,14 @@ void MaterialBindingItem::setValue(BindingElement::Binding bind)
|
||||
|
||||
void MaterialBindingItem::write(InventorOutput& out) const
|
||||
{
|
||||
out.write() << "MaterialBinding { value "
|
||||
<< value.bindingAsString() << " } \n";
|
||||
out.write() << "MaterialBinding { value " << value.bindingAsString() << " } \n";
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
DrawStyleItem::DrawStyleItem(DrawStyle value)
|
||||
: style{value}
|
||||
{
|
||||
}
|
||||
: style {value}
|
||||
{}
|
||||
|
||||
void DrawStyleItem::setValue(DrawStyle value)
|
||||
{
|
||||
@@ -650,10 +656,9 @@ void DrawStyleItem::write(InventorOutput& out) const
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
ShapeHintsItem::ShapeHintsItem(float creaseAngle) : creaseAngle(creaseAngle)
|
||||
{
|
||||
|
||||
}
|
||||
ShapeHintsItem::ShapeHintsItem(float creaseAngle)
|
||||
: creaseAngle(creaseAngle)
|
||||
{}
|
||||
|
||||
void ShapeHintsItem::setVertexOrdering(VertexOrdering::Ordering value)
|
||||
{
|
||||
@@ -696,8 +701,7 @@ void PolygonOffsetItem::write(InventorOutput& out) const
|
||||
|
||||
Coordinate3Item::Coordinate3Item(const std::vector<Vector3f>& points)
|
||||
: points(points)
|
||||
{
|
||||
}
|
||||
{}
|
||||
|
||||
void Coordinate3Item::write(InventorOutput& out) const
|
||||
{
|
||||
@@ -737,11 +741,9 @@ void LineSetItem::write(InventorOutput& out) const
|
||||
|
||||
FaceSetItem::FaceSetItem(const std::vector<int>& indices)
|
||||
: indices(indices)
|
||||
{
|
||||
{}
|
||||
|
||||
}
|
||||
|
||||
void FaceSetItem::write(InventorOutput &out) const
|
||||
void FaceSetItem::write(InventorOutput& out) const
|
||||
{
|
||||
out.write() << "FaceSet {\n";
|
||||
out.increaseIndent();
|
||||
@@ -755,11 +757,9 @@ void FaceSetItem::write(InventorOutput &out) const
|
||||
|
||||
IndexedLineSetItem::IndexedLineSetItem(const std::vector<int>& indices)
|
||||
: indices(indices)
|
||||
{
|
||||
{}
|
||||
|
||||
}
|
||||
|
||||
void IndexedLineSetItem::write(InventorOutput &out) const
|
||||
void IndexedLineSetItem::write(InventorOutput& out) const
|
||||
{
|
||||
out.write() << "IndexedLineSet {\n";
|
||||
out.increaseIndent();
|
||||
@@ -773,11 +773,9 @@ void IndexedLineSetItem::write(InventorOutput &out) const
|
||||
|
||||
IndexedFaceSetItem::IndexedFaceSetItem(const std::vector<int>& indices)
|
||||
: indices(indices)
|
||||
{
|
||||
{}
|
||||
|
||||
}
|
||||
|
||||
void IndexedFaceSetItem::write(InventorOutput &out) const
|
||||
void IndexedFaceSetItem::write(InventorOutput& out) const
|
||||
{
|
||||
out.write() << "IndexedFaceSet {\n";
|
||||
out.increaseIndent();
|
||||
@@ -791,8 +789,7 @@ void IndexedFaceSetItem::write(InventorOutput &out) const
|
||||
|
||||
NormalItem::NormalItem(const std::vector<Base::Vector3f>& vec)
|
||||
: vector(vec)
|
||||
{
|
||||
}
|
||||
{}
|
||||
|
||||
void NormalItem::write(InventorOutput& out) const
|
||||
{
|
||||
@@ -823,8 +820,7 @@ void NormalBindingItem::setValue(BindingElement::Binding bind)
|
||||
|
||||
void NormalBindingItem::write(InventorOutput& out) const
|
||||
{
|
||||
out.write() << "NormalBinding { value "
|
||||
<< value.bindingAsString() << " }\n";
|
||||
out.write() << "NormalBinding { value " << value.bindingAsString() << " }\n";
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
@@ -909,22 +905,19 @@ void NurbsSurfaceItem::write(InventorOutput& out) const
|
||||
|
||||
Text2Item::Text2Item(const std::string& string)
|
||||
: string(string)
|
||||
{
|
||||
|
||||
}
|
||||
{}
|
||||
|
||||
void Text2Item::write(InventorOutput& out) const
|
||||
{
|
||||
out.write() << "Text2 { string \"" << string << "\" " << "}\n";
|
||||
out.write() << "Text2 { string \"" << string << "\" "
|
||||
<< "}\n";
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
TransformItem::TransformItem(const Base::Placement& placement)
|
||||
: placement(placement)
|
||||
{
|
||||
|
||||
}
|
||||
{}
|
||||
|
||||
TransformItem::TransformItem(const Matrix4D& transform)
|
||||
{
|
||||
@@ -935,27 +928,26 @@ void TransformItem::write(InventorOutput& out) const
|
||||
{
|
||||
Base::Vector3d translation = placement.getPosition();
|
||||
Base::Vector3d rotationaxis;
|
||||
double angle{};
|
||||
double angle {};
|
||||
placement.getRotation().getValue(rotationaxis, angle);
|
||||
|
||||
out.write() << "Transform {\n";
|
||||
out.write() << " translation "
|
||||
<< translation.x << " " << translation.y << " " << translation.z << '\n';
|
||||
out.write() << " rotation "
|
||||
<< rotationaxis.x << " " << rotationaxis.y << " " << rotationaxis.z
|
||||
<< " " << angle << '\n';
|
||||
out.write() << "}" << '\n';
|
||||
out.write() << " translation " << translation.x << " " << translation.y << " " << translation.z
|
||||
<< '\n';
|
||||
out.write() << " rotation " << rotationaxis.x << " " << rotationaxis.y << " " << rotationaxis.z
|
||||
<< " " << angle << '\n';
|
||||
out.write() << "}" << '\n';
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
InventorBuilder::InventorBuilder(std::ostream& output)
|
||||
: result(output)
|
||||
: result(output)
|
||||
{
|
||||
addHeader();
|
||||
}
|
||||
|
||||
InventorBuilder:: ~InventorBuilder() = default;
|
||||
InventorBuilder::~InventorBuilder() = default;
|
||||
|
||||
void InventorBuilder::addHeader()
|
||||
{
|
||||
@@ -997,10 +989,9 @@ void InventorBuilder::endSeparator()
|
||||
* A more elaborate description of the constructor.
|
||||
*/
|
||||
Builder3D::Builder3D()
|
||||
: result{}
|
||||
, builder{result}
|
||||
{
|
||||
}
|
||||
: result {}
|
||||
, builder {result}
|
||||
{}
|
||||
|
||||
/**
|
||||
* A destructor.
|
||||
@@ -1008,7 +999,7 @@ Builder3D::Builder3D()
|
||||
*/
|
||||
Builder3D::~Builder3D() = default;
|
||||
|
||||
void Builder3D::clear ()
|
||||
void Builder3D::clear()
|
||||
{
|
||||
// under gcc stringstream::str() returns a copy not a reference
|
||||
#if defined(_MSC_VER)
|
||||
@@ -1027,8 +1018,12 @@ void Builder3D::clear ()
|
||||
void Builder3D::saveToLog()
|
||||
{
|
||||
ILogger* obs = Base::Console().Get("StatusBar");
|
||||
if (obs){
|
||||
obs->SendLog("Builder3D",result.str().c_str(), Base::LogStyle::Log, Base::IntendedRecipient::Developer, Base::ContentType::Untranslatable);
|
||||
if (obs) {
|
||||
obs->SendLog("Builder3D",
|
||||
result.str().c_str(),
|
||||
Base::LogStyle::Log,
|
||||
Base::IntendedRecipient::Developer,
|
||||
Base::ContentType::Untranslatable);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1043,7 +1038,7 @@ void Builder3D::saveToLog()
|
||||
void Builder3D::saveToFile(const char* FileName)
|
||||
{
|
||||
Base::FileInfo fi(FileName);
|
||||
Base::ofstream file(fi);
|
||||
Base::ofstream file(fi);
|
||||
if (!file) {
|
||||
throw FileException("Cannot open file");
|
||||
}
|
||||
@@ -1086,14 +1081,15 @@ std::vector<T> InventorLoader::readData(const char* fieldName) const
|
||||
}
|
||||
}
|
||||
|
||||
if (!found)
|
||||
if (!found) {
|
||||
return {};
|
||||
}
|
||||
|
||||
do {
|
||||
boost::char_separator<char> sep(" ,");
|
||||
boost::tokenizer<boost::char_separator<char> > tokens(str, sep);
|
||||
boost::tokenizer<boost::char_separator<char>> tokens(str, sep);
|
||||
std::vector<std::string> token_results;
|
||||
token_results.assign(tokens.begin(),tokens.end());
|
||||
token_results.assign(tokens.begin(), tokens.end());
|
||||
|
||||
for (const auto& it : token_results) {
|
||||
try {
|
||||
@@ -1105,18 +1101,19 @@ std::vector<T> InventorLoader::readData(const char* fieldName) const
|
||||
}
|
||||
|
||||
// search for ']' to finish the reading
|
||||
if (str.find("]") != std::string::npos)
|
||||
if (str.find("]") != std::string::npos) {
|
||||
break;
|
||||
}
|
||||
while (std::getline(inp, str));
|
||||
}
|
||||
} while (std::getline(inp, str));
|
||||
|
||||
return fieldValues;
|
||||
}
|
||||
|
||||
std::vector<Vector3f> InventorLoader::convert(const std::vector<float>& data) const
|
||||
{
|
||||
if (data.size() % 3 != 0)
|
||||
if (data.size() % 3 != 0) {
|
||||
throw std::string("Reading failed");
|
||||
}
|
||||
|
||||
std::size_t len = data.size() / 3;
|
||||
std::vector<Vector3f> points;
|
||||
@@ -1139,11 +1136,11 @@ std::vector<InventorLoader::Face> InventorLoader::convert(const std::vector<int3
|
||||
int32_t coordIndex = 0;
|
||||
for (const auto it : data) {
|
||||
if (it == 3) {
|
||||
faces.emplace_back(coordIndex, coordIndex+1, coordIndex+2);
|
||||
faces.emplace_back(coordIndex, coordIndex + 1, coordIndex + 2);
|
||||
}
|
||||
else if (it == 4) {
|
||||
faces.emplace_back(coordIndex, coordIndex+1, coordIndex+2);
|
||||
faces.emplace_back(coordIndex, coordIndex+2, coordIndex+3);
|
||||
faces.emplace_back(coordIndex, coordIndex + 1, coordIndex + 2);
|
||||
faces.emplace_back(coordIndex, coordIndex + 2, coordIndex + 3);
|
||||
}
|
||||
coordIndex += it;
|
||||
}
|
||||
@@ -1164,7 +1161,8 @@ std::vector<std::vector<int32_t>> InventorLoader::split(const std::vector<int32_
|
||||
return splitdata;
|
||||
}
|
||||
|
||||
std::vector<InventorLoader::Face> InventorLoader::convert(const std::vector<std::vector<int32_t>>& coordIndex) const
|
||||
std::vector<InventorLoader::Face>
|
||||
InventorLoader::convert(const std::vector<std::vector<int32_t>>& coordIndex) const
|
||||
{
|
||||
std::vector<Face> faces;
|
||||
faces.reserve(coordIndex.size());
|
||||
@@ -1207,15 +1205,17 @@ void InventorLoader::readFaceSet()
|
||||
|
||||
bool InventorLoader::read()
|
||||
{
|
||||
if (!inp || inp.bad())
|
||||
if (!inp || inp.bad()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string line;
|
||||
|
||||
// Verify it's an Inventor 2.1 file
|
||||
std::getline(inp, line);
|
||||
if (line.find("#Inventor V2.1 ascii") == std::string::npos)
|
||||
if (line.find("#Inventor V2.1 ascii") == std::string::npos) {
|
||||
return false;
|
||||
}
|
||||
|
||||
while (std::getline(inp, line)) {
|
||||
// read the normals if they are defined
|
||||
@@ -1239,30 +1239,36 @@ bool InventorLoader::read()
|
||||
|
||||
bool InventorLoader::isValid() const
|
||||
{
|
||||
int32_t value{static_cast<int32_t>(points.size())};
|
||||
int32_t value {static_cast<int32_t>(points.size())};
|
||||
auto inRange = [value](const Face& f) {
|
||||
if (f.p1 < 0 || f.p1 >= value)
|
||||
if (f.p1 < 0 || f.p1 >= value) {
|
||||
return false;
|
||||
if (f.p2 < 0 || f.p2 >= value)
|
||||
}
|
||||
if (f.p2 < 0 || f.p2 >= value) {
|
||||
return false;
|
||||
if (f.p3 < 0 || f.p3 >= value)
|
||||
}
|
||||
if (f.p3 < 0 || f.p3 >= value) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
};
|
||||
for (auto it : faces) {
|
||||
if (!inRange(it))
|
||||
if (!inRange(it)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
namespace Base {
|
||||
namespace Base
|
||||
{
|
||||
BaseExport Vector3f to_vector(std::string str)
|
||||
{
|
||||
std::string_view view = str;
|
||||
if (!boost::starts_with(view, "(") || !boost::ends_with(str, ")"))
|
||||
if (!boost::starts_with(view, "(") || !boost::ends_with(str, ")")) {
|
||||
throw std::runtime_error("string is not a tuple");
|
||||
}
|
||||
|
||||
view.remove_prefix(1);
|
||||
view.remove_suffix(1);
|
||||
@@ -1270,12 +1276,13 @@ BaseExport Vector3f to_vector(std::string str)
|
||||
str = view;
|
||||
|
||||
boost::char_separator<char> sep(" ,");
|
||||
boost::tokenizer<boost::char_separator<char> > tokens(str, sep);
|
||||
boost::tokenizer<boost::char_separator<char>> tokens(str, sep);
|
||||
std::vector<std::string> token_results;
|
||||
token_results.assign(tokens.begin(), tokens.end());
|
||||
|
||||
if (token_results.size() != 3)
|
||||
if (token_results.size() != 3) {
|
||||
throw std::runtime_error("not a tuple of three floats");
|
||||
}
|
||||
|
||||
Base::Vector3f vec;
|
||||
vec.x = boost::lexical_cast<float>(token_results.at(0));
|
||||
@@ -1285,4 +1292,4 @@ BaseExport Vector3f to_vector(std::string str)
|
||||
return vec;
|
||||
}
|
||||
|
||||
}
|
||||
} // namespace Base
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
// Std. configurations
|
||||
|
||||
#ifdef __GNUC__
|
||||
# include <cstdint>
|
||||
#include <cstdint>
|
||||
#endif
|
||||
|
||||
#include <sstream>
|
||||
@@ -45,25 +45,33 @@ class BaseExport ColorRGB
|
||||
{
|
||||
public:
|
||||
ColorRGB();
|
||||
ColorRGB(const ColorRGB&) = default;
|
||||
ColorRGB(ColorRGB&&) = default;
|
||||
explicit ColorRGB(float red, float green, float blue);
|
||||
~ColorRGB() = default;
|
||||
ColorRGB& operator=(const ColorRGB&) = default;
|
||||
ColorRGB& operator=(ColorRGB&&) = default;
|
||||
|
||||
float red() const {
|
||||
float red() const
|
||||
{
|
||||
return Rgb.red;
|
||||
}
|
||||
|
||||
float green() const {
|
||||
float green() const
|
||||
{
|
||||
return Rgb.green;
|
||||
}
|
||||
|
||||
float blue() const {
|
||||
float blue() const
|
||||
{
|
||||
return Rgb.blue;
|
||||
}
|
||||
|
||||
protected:
|
||||
private:
|
||||
/*! Returns the clamped value in range [-1, +1] */
|
||||
static float valueInRange(float value);
|
||||
struct {
|
||||
struct
|
||||
{
|
||||
float red;
|
||||
float green;
|
||||
float blue;
|
||||
@@ -73,7 +81,8 @@ protected:
|
||||
class BaseExport DrawStyle
|
||||
{
|
||||
public:
|
||||
enum class Style {
|
||||
enum class Style
|
||||
{
|
||||
Filled,
|
||||
Lines,
|
||||
Points,
|
||||
@@ -91,7 +100,8 @@ public:
|
||||
class BaseExport VertexOrdering
|
||||
{
|
||||
public:
|
||||
enum class Ordering {
|
||||
enum class Ordering
|
||||
{
|
||||
UnknownOrdering,
|
||||
Clockwise,
|
||||
CounterClockwise
|
||||
@@ -105,7 +115,8 @@ public:
|
||||
class BaseExport ShapeType
|
||||
{
|
||||
public:
|
||||
enum class Type {
|
||||
enum class Type
|
||||
{
|
||||
UnknownShapeType,
|
||||
Convex
|
||||
};
|
||||
@@ -118,7 +129,8 @@ public:
|
||||
class BaseExport BindingElement
|
||||
{
|
||||
public:
|
||||
enum class Binding {
|
||||
enum class Binding
|
||||
{
|
||||
Overall = 2,
|
||||
PerPart = 3,
|
||||
PerPartIndexed = 4,
|
||||
@@ -137,7 +149,8 @@ public:
|
||||
class BaseExport PolygonOffset
|
||||
{
|
||||
public:
|
||||
enum class Style {
|
||||
enum class Style
|
||||
{
|
||||
Filled,
|
||||
Lines,
|
||||
Points
|
||||
@@ -156,19 +169,23 @@ public:
|
||||
explicit Triangle(const Base::Vector3f& pt1,
|
||||
const Base::Vector3f& pt2,
|
||||
const Base::Vector3f& pt3)
|
||||
: pt1(pt1), pt2(pt2), pt3(pt3)
|
||||
{
|
||||
}
|
||||
: pt1(pt1)
|
||||
, pt2(pt2)
|
||||
, pt3(pt3)
|
||||
{}
|
||||
|
||||
const Base::Vector3f& getPoint1() const {
|
||||
const Base::Vector3f& getPoint1() const
|
||||
{
|
||||
return pt1;
|
||||
}
|
||||
|
||||
const Base::Vector3f& getPoint2() const {
|
||||
const Base::Vector3f& getPoint2() const
|
||||
{
|
||||
return pt2;
|
||||
}
|
||||
|
||||
const Base::Vector3f& getPoint3() const {
|
||||
const Base::Vector3f& getPoint3() const
|
||||
{
|
||||
return pt3;
|
||||
}
|
||||
|
||||
@@ -178,22 +195,28 @@ private:
|
||||
Base::Vector3f pt3;
|
||||
};
|
||||
|
||||
class Indentation {
|
||||
class Indentation
|
||||
{
|
||||
int spaces = 0;
|
||||
|
||||
public:
|
||||
void increaseIndent() {
|
||||
void increaseIndent()
|
||||
{
|
||||
spaces += 2;
|
||||
}
|
||||
void decreaseIndent() {
|
||||
void decreaseIndent()
|
||||
{
|
||||
spaces -= 2;
|
||||
}
|
||||
int count() {
|
||||
int count()
|
||||
{
|
||||
return spaces;
|
||||
}
|
||||
friend std::ostream& operator<<( std::ostream& os, Indentation m)
|
||||
friend std::ostream& operator<<(std::ostream& os, Indentation m)
|
||||
{
|
||||
for (int i = 0; i < m.count(); i++)
|
||||
for (int i = 0; i < m.count(); i++) {
|
||||
os << " ";
|
||||
}
|
||||
return os;
|
||||
}
|
||||
};
|
||||
@@ -222,12 +245,19 @@ class BaseExport NodeItem
|
||||
public:
|
||||
virtual ~NodeItem() = default;
|
||||
virtual void write(InventorOutput& out) const = 0;
|
||||
|
||||
protected:
|
||||
NodeItem() = default;
|
||||
NodeItem(const NodeItem&) = default;
|
||||
NodeItem(NodeItem&&) = default;
|
||||
NodeItem& operator=(const NodeItem&) = default;
|
||||
NodeItem& operator=(NodeItem&&) = default;
|
||||
};
|
||||
|
||||
/*!
|
||||
* \brief The LabelItem class supports the SoLabel node.
|
||||
*/
|
||||
class BaseExport LabelItem : public NodeItem
|
||||
class BaseExport LabelItem: public NodeItem
|
||||
{
|
||||
public:
|
||||
explicit LabelItem(const std::string& text);
|
||||
@@ -240,7 +270,7 @@ private:
|
||||
/*!
|
||||
* \brief The InfoItem class supports the SoInfo node.
|
||||
*/
|
||||
class BaseExport InfoItem : public NodeItem
|
||||
class BaseExport InfoItem: public NodeItem
|
||||
{
|
||||
public:
|
||||
explicit InfoItem(const std::string& text);
|
||||
@@ -253,7 +283,7 @@ private:
|
||||
/*!
|
||||
* \brief The BaseColorItem class supports the SoBaseColor node.
|
||||
*/
|
||||
class BaseExport BaseColorItem : public NodeItem
|
||||
class BaseExport BaseColorItem: public NodeItem
|
||||
{
|
||||
public:
|
||||
explicit BaseColorItem(const ColorRGB& rgb);
|
||||
@@ -263,10 +293,12 @@ private:
|
||||
ColorRGB rgb;
|
||||
};
|
||||
|
||||
class BaseExport PointItem : public NodeItem
|
||||
class BaseExport PointItem: public NodeItem
|
||||
{
|
||||
public:
|
||||
explicit PointItem(const Base::Vector3f& point, DrawStyle drawStyle, const ColorRGB& rgb = ColorRGB{1.0F, 1.0F, 1.0F});
|
||||
explicit PointItem(const Base::Vector3f& point,
|
||||
DrawStyle drawStyle,
|
||||
const ColorRGB& rgb = ColorRGB {1.0F, 1.0F, 1.0F});
|
||||
void write(InventorOutput& out) const override;
|
||||
|
||||
private:
|
||||
@@ -275,10 +307,12 @@ private:
|
||||
ColorRGB rgb;
|
||||
};
|
||||
|
||||
class BaseExport LineItem : public NodeItem
|
||||
class BaseExport LineItem: public NodeItem
|
||||
{
|
||||
public:
|
||||
explicit LineItem(const Base::Line3f& line, DrawStyle drawStyle, const ColorRGB& rgb = ColorRGB{1.0F, 1.0F, 1.0F});
|
||||
explicit LineItem(const Base::Line3f& line,
|
||||
DrawStyle drawStyle,
|
||||
const ColorRGB& rgb = ColorRGB {1.0F, 1.0F, 1.0F});
|
||||
void write(InventorOutput& out) const override;
|
||||
|
||||
private:
|
||||
@@ -287,11 +321,14 @@ private:
|
||||
ColorRGB rgb;
|
||||
};
|
||||
|
||||
class BaseExport MultiLineItem : public NodeItem
|
||||
class BaseExport MultiLineItem: public NodeItem
|
||||
{
|
||||
public:
|
||||
/// add a line defined by a list of points whereat always a pair (i.e. a point and the following point) builds a line.
|
||||
explicit MultiLineItem(const std::vector<Vector3f>& points, DrawStyle drawStyle, const ColorRGB& rgb = ColorRGB{1.0F, 1.0F, 1.0F});
|
||||
/// add a line defined by a list of points whereat always a pair (i.e. a point and the following
|
||||
/// point) builds a line.
|
||||
explicit MultiLineItem(const std::vector<Vector3f>& points,
|
||||
DrawStyle drawStyle,
|
||||
const ColorRGB& rgb = ColorRGB {1.0F, 1.0F, 1.0F});
|
||||
void write(InventorOutput& out) const override;
|
||||
|
||||
private:
|
||||
@@ -300,10 +337,12 @@ private:
|
||||
ColorRGB rgb;
|
||||
};
|
||||
|
||||
class BaseExport ArrowItem : public NodeItem
|
||||
class BaseExport ArrowItem: public NodeItem
|
||||
{
|
||||
public:
|
||||
explicit ArrowItem(const Base::Line3f& line, DrawStyle drawStyle, const ColorRGB& rgb = ColorRGB{1.0F, 1.0F, 1.0F});
|
||||
explicit ArrowItem(const Base::Line3f& line,
|
||||
DrawStyle drawStyle,
|
||||
const ColorRGB& rgb = ColorRGB {1.0F, 1.0F, 1.0F});
|
||||
void write(InventorOutput& out) const override;
|
||||
|
||||
private:
|
||||
@@ -312,10 +351,13 @@ private:
|
||||
ColorRGB rgb;
|
||||
};
|
||||
|
||||
class BaseExport BoundingBoxItem : public NodeItem
|
||||
class BaseExport BoundingBoxItem: public NodeItem
|
||||
{
|
||||
public:
|
||||
explicit BoundingBoxItem(const Vector3f& pt1, const Vector3f& pt2, DrawStyle drawStyle, const ColorRGB& rgb = ColorRGB{1.0F, 1.0F, 1.0F});
|
||||
explicit BoundingBoxItem(const Vector3f& pt1,
|
||||
const Vector3f& pt2,
|
||||
DrawStyle drawStyle,
|
||||
const ColorRGB& rgb = ColorRGB {1.0F, 1.0F, 1.0F});
|
||||
void write(InventorOutput& out) const override;
|
||||
|
||||
private:
|
||||
@@ -328,7 +370,7 @@ private:
|
||||
/*!
|
||||
* \brief The MaterialItem class supports the SoMaterial node.
|
||||
*/
|
||||
class BaseExport MaterialItem : public NodeItem
|
||||
class BaseExport MaterialItem: public NodeItem
|
||||
{
|
||||
public:
|
||||
void setAmbientColor(const std::vector<ColorRGB>& rgb);
|
||||
@@ -361,7 +403,7 @@ private:
|
||||
/*!
|
||||
* \brief The MaterialBindingItem class supports the SoMaterialBinding node.
|
||||
*/
|
||||
class BaseExport MaterialBindingItem : public NodeItem
|
||||
class BaseExport MaterialBindingItem: public NodeItem
|
||||
{
|
||||
public:
|
||||
MaterialBindingItem() = default;
|
||||
@@ -376,7 +418,7 @@ private:
|
||||
/*!
|
||||
* \brief The DrawStyleItem class supports the SoDrawStyle node.
|
||||
*/
|
||||
class BaseExport DrawStyleItem : public NodeItem
|
||||
class BaseExport DrawStyleItem: public NodeItem
|
||||
{
|
||||
public:
|
||||
DrawStyleItem() = default;
|
||||
@@ -391,7 +433,7 @@ private:
|
||||
/*!
|
||||
* \brief The ShapeHintsItem class supports the SoShapeHints node.
|
||||
*/
|
||||
class BaseExport ShapeHintsItem : public NodeItem
|
||||
class BaseExport ShapeHintsItem: public NodeItem
|
||||
{
|
||||
public:
|
||||
explicit ShapeHintsItem(float creaseAngle = 0.0F);
|
||||
@@ -408,7 +450,7 @@ private:
|
||||
/*!
|
||||
* \brief The PolygonOffsetItem class supports the SoPolygonOffset node.
|
||||
*/
|
||||
class BaseExport PolygonOffsetItem : public NodeItem
|
||||
class BaseExport PolygonOffsetItem: public NodeItem
|
||||
{
|
||||
public:
|
||||
void setValue(PolygonOffset value);
|
||||
@@ -421,7 +463,7 @@ private:
|
||||
/*!
|
||||
* \brief The Coordinate3Item class supports the SoCoordinate3 node.
|
||||
*/
|
||||
class BaseExport Coordinate3Item : public NodeItem
|
||||
class BaseExport Coordinate3Item: public NodeItem
|
||||
{
|
||||
public:
|
||||
Coordinate3Item(const std::vector<Vector3f>& points);
|
||||
@@ -436,7 +478,7 @@ private:
|
||||
/*!
|
||||
* \brief The PointSetItem class supports the SoPointSet node.
|
||||
*/
|
||||
class BaseExport PointSetItem : public NodeItem
|
||||
class BaseExport PointSetItem: public NodeItem
|
||||
{
|
||||
public:
|
||||
void write(InventorOutput& out) const override;
|
||||
@@ -445,7 +487,7 @@ public:
|
||||
/*!
|
||||
* \brief The LineSetItem class supports the SoLineSet node.
|
||||
*/
|
||||
class BaseExport LineSetItem : public NodeItem
|
||||
class BaseExport LineSetItem: public NodeItem
|
||||
{
|
||||
public:
|
||||
void write(InventorOutput& out) const override;
|
||||
@@ -454,7 +496,7 @@ public:
|
||||
/*!
|
||||
* \brief The FaceSetItem class supports the SoFaceSet node.
|
||||
*/
|
||||
class BaseExport FaceSetItem : public NodeItem
|
||||
class BaseExport FaceSetItem: public NodeItem
|
||||
{
|
||||
public:
|
||||
FaceSetItem(const std::vector<int>&);
|
||||
@@ -467,7 +509,7 @@ private:
|
||||
/*!
|
||||
* \brief The IndexedLineSetItem class supports the SoIndexedLineSet node.
|
||||
*/
|
||||
class BaseExport IndexedLineSetItem : public NodeItem
|
||||
class BaseExport IndexedLineSetItem: public NodeItem
|
||||
{
|
||||
public:
|
||||
IndexedLineSetItem(const std::vector<int>&);
|
||||
@@ -480,7 +522,7 @@ private:
|
||||
/*!
|
||||
* \brief The IndexedFaceSetItem class supports the SoIndexedFaceSet node.
|
||||
*/
|
||||
class BaseExport IndexedFaceSetItem : public NodeItem
|
||||
class BaseExport IndexedFaceSetItem: public NodeItem
|
||||
{
|
||||
public:
|
||||
IndexedFaceSetItem(const std::vector<int>&);
|
||||
@@ -493,7 +535,7 @@ private:
|
||||
/*!
|
||||
* \brief The NormalItem class supports the SoNormal node.
|
||||
*/
|
||||
class BaseExport NormalItem : public NodeItem
|
||||
class BaseExport NormalItem: public NodeItem
|
||||
{
|
||||
public:
|
||||
explicit NormalItem(const std::vector<Base::Vector3f>& vec);
|
||||
@@ -508,7 +550,7 @@ private:
|
||||
/*!
|
||||
* \brief The MaterialBindingItem class supports the SoMaterialBinding node.
|
||||
*/
|
||||
class BaseExport NormalBindingItem : public NodeItem
|
||||
class BaseExport NormalBindingItem: public NodeItem
|
||||
{
|
||||
public:
|
||||
NormalBindingItem() = default;
|
||||
@@ -522,7 +564,7 @@ private:
|
||||
/*!
|
||||
* \brief The CylinderItem class supports the SoCylinder node.
|
||||
*/
|
||||
class BaseExport CylinderItem : public NodeItem
|
||||
class BaseExport CylinderItem: public NodeItem
|
||||
{
|
||||
public:
|
||||
void setRadius(float);
|
||||
@@ -537,7 +579,7 @@ private:
|
||||
/*!
|
||||
* \brief The ConeItem class supports the SoCone node.
|
||||
*/
|
||||
class BaseExport ConeItem : public NodeItem
|
||||
class BaseExport ConeItem: public NodeItem
|
||||
{
|
||||
public:
|
||||
void setBottomRadius(float);
|
||||
@@ -552,7 +594,7 @@ private:
|
||||
/*!
|
||||
* \brief The SphereItem class supports the SoSphere node.
|
||||
*/
|
||||
class BaseExport SphereItem : public NodeItem
|
||||
class BaseExport SphereItem: public NodeItem
|
||||
{
|
||||
public:
|
||||
void setRadius(float);
|
||||
@@ -565,7 +607,7 @@ private:
|
||||
/*!
|
||||
* \brief The NurbsSurfaceItem class supports the SoNurbsSurface node.
|
||||
*/
|
||||
class BaseExport NurbsSurfaceItem : public NodeItem
|
||||
class BaseExport NurbsSurfaceItem: public NodeItem
|
||||
{
|
||||
public:
|
||||
void setControlPoints(int numU, int numV);
|
||||
@@ -582,7 +624,7 @@ private:
|
||||
/*!
|
||||
* \brief The Text2Item class supports the SoText2 node.
|
||||
*/
|
||||
class BaseExport Text2Item : public NodeItem
|
||||
class BaseExport Text2Item: public NodeItem
|
||||
{
|
||||
public:
|
||||
Text2Item(const std::string&);
|
||||
@@ -595,7 +637,7 @@ private:
|
||||
/*!
|
||||
* \brief The TransformItem class supports the SoTransform node.
|
||||
*/
|
||||
class BaseExport TransformItem : public NodeItem
|
||||
class BaseExport TransformItem: public NodeItem
|
||||
{
|
||||
public:
|
||||
explicit TransformItem(const Base::Placement&);
|
||||
@@ -649,8 +691,10 @@ private:
|
||||
void decreaseIndent();
|
||||
|
||||
public:
|
||||
InventorBuilder (const InventorBuilder&) = delete;
|
||||
void operator = (const InventorBuilder&) = delete;
|
||||
InventorBuilder(const InventorBuilder&) = delete;
|
||||
InventorBuilder(InventorBuilder&&) = delete;
|
||||
void operator=(const InventorBuilder&) = delete;
|
||||
void operator=(InventorBuilder&&) = delete;
|
||||
|
||||
private:
|
||||
std::ostream& result;
|
||||
@@ -713,6 +757,11 @@ public:
|
||||
*/
|
||||
void endSeparator();
|
||||
|
||||
Builder3D(const Builder3D&) = delete;
|
||||
Builder3D(Builder3D&&) = delete;
|
||||
Builder3D& operator=(const Builder3D&) = delete;
|
||||
Builder3D& operator=(Builder3D&&) = delete;
|
||||
|
||||
private:
|
||||
/// the result string
|
||||
std::stringstream result;
|
||||
@@ -723,16 +772,22 @@ private:
|
||||
* Loads an OpenInventor file.
|
||||
* @author Werner Mayer
|
||||
*/
|
||||
class BaseExport InventorLoader {
|
||||
class BaseExport InventorLoader
|
||||
{
|
||||
public:
|
||||
struct Face {
|
||||
struct Face
|
||||
{
|
||||
Face(int32_t p1, int32_t p2, int32_t p3)
|
||||
: p1(p1), p2(p2), p3(p3) {}
|
||||
: p1(p1)
|
||||
, p2(p2)
|
||||
, p3(p3)
|
||||
{}
|
||||
int32_t p1, p2, p3;
|
||||
};
|
||||
|
||||
explicit InventorLoader(std::istream &inp) : inp(inp) {
|
||||
}
|
||||
explicit InventorLoader(std::istream& inp)
|
||||
: inp(inp)
|
||||
{}
|
||||
|
||||
/// Start the read process. Returns true if successful and false otherwise.
|
||||
/// The obtained data can be accessed with the appropriate getter functions.
|
||||
@@ -743,22 +798,26 @@ public:
|
||||
|
||||
/// Returns true if the data come from a non-indexed node as SoFaceSet.
|
||||
/// This means that the read points contain duplicates.
|
||||
bool isNonIndexed() const {
|
||||
bool isNonIndexed() const
|
||||
{
|
||||
return isnonindexed;
|
||||
}
|
||||
|
||||
/// Return the vectors of an SoNormal node
|
||||
const std::vector<Vector3f>& getVector() const {
|
||||
const std::vector<Vector3f>& getVector() const
|
||||
{
|
||||
return vector;
|
||||
}
|
||||
|
||||
/// Return the points of an SoCoordinate3 node
|
||||
const std::vector<Vector3f>& getPoints() const {
|
||||
const std::vector<Vector3f>& getPoints() const
|
||||
{
|
||||
return points;
|
||||
}
|
||||
|
||||
/// Return the faces of an SoIndexedFaceSet node
|
||||
const std::vector<Face>& getFaces() const {
|
||||
const std::vector<Face>& getFaces() const
|
||||
{
|
||||
return faces;
|
||||
}
|
||||
|
||||
@@ -779,7 +838,7 @@ private:
|
||||
std::vector<Vector3f> vector;
|
||||
std::vector<Vector3f> points;
|
||||
std::vector<Face> faces;
|
||||
std::istream &inp;
|
||||
std::istream& inp;
|
||||
};
|
||||
|
||||
/*!
|
||||
@@ -789,6 +848,6 @@ private:
|
||||
*/
|
||||
BaseExport Base::Vector3f to_vector(std::string);
|
||||
|
||||
} //namespace Base
|
||||
} // namespace Base
|
||||
|
||||
#endif // BASE_BUILDER3D_H
|
||||
#endif // BASE_BUILDER3D_H
|
||||
|
||||
@@ -24,13 +24,13 @@
|
||||
#include "PreCompiled.h"
|
||||
|
||||
#ifndef _PreComp_
|
||||
# if defined(FC_OS_WIN32)
|
||||
# include <windows.h>
|
||||
# elif defined(FC_OS_LINUX) || defined(FC_OS_MACOSX)
|
||||
# include <unistd.h>
|
||||
# endif
|
||||
# include <cstring>
|
||||
# include <functional>
|
||||
#if defined(FC_OS_WIN32)
|
||||
#include <windows.h>
|
||||
#elif defined(FC_OS_LINUX) || defined(FC_OS_MACOSX)
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#include <cstring>
|
||||
#include <functional>
|
||||
#endif
|
||||
|
||||
#include "Console.h"
|
||||
@@ -44,9 +44,11 @@ using namespace Base;
|
||||
|
||||
//=========================================================================
|
||||
|
||||
namespace Base {
|
||||
namespace Base
|
||||
{
|
||||
|
||||
class ConsoleEvent : public QEvent {
|
||||
class ConsoleEvent: public QEvent
|
||||
{
|
||||
public:
|
||||
ConsoleSingleton::FreeCAD_ConsoleMsgType msgtype;
|
||||
IntendedRecipient recipient;
|
||||
@@ -54,48 +56,83 @@ public:
|
||||
std::string notifier;
|
||||
std::string msg;
|
||||
|
||||
ConsoleEvent(ConsoleSingleton::FreeCAD_ConsoleMsgType type, IntendedRecipient recipient,
|
||||
ContentType content, const std::string& notifier, const std::string& msg)
|
||||
: QEvent(QEvent::User), msgtype(type), recipient(recipient), content(content), notifier(notifier), msg(msg)
|
||||
{
|
||||
}
|
||||
ConsoleEvent(ConsoleSingleton::FreeCAD_ConsoleMsgType type,
|
||||
IntendedRecipient recipient,
|
||||
ContentType content,
|
||||
const std::string& notifier,
|
||||
const std::string& msg)
|
||||
: QEvent(QEvent::User)
|
||||
, msgtype(type)
|
||||
, recipient(recipient)
|
||||
, content(content)
|
||||
, notifier(notifier)
|
||||
, msg(msg)
|
||||
{}
|
||||
~ConsoleEvent() override = default;
|
||||
};
|
||||
|
||||
class ConsoleOutput : public QObject // clazy:exclude=missing-qobject-macro
|
||||
class ConsoleOutput: public QObject // clazy:exclude=missing-qobject-macro
|
||||
{
|
||||
public:
|
||||
static ConsoleOutput* getInstance() {
|
||||
if (!instance)
|
||||
static ConsoleOutput* getInstance()
|
||||
{
|
||||
if (!instance) {
|
||||
instance = new ConsoleOutput;
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
static void destruct() {
|
||||
static void destruct()
|
||||
{
|
||||
delete instance;
|
||||
instance = nullptr;
|
||||
}
|
||||
|
||||
void customEvent(QEvent* ev) override {
|
||||
void customEvent(QEvent* ev) override
|
||||
{
|
||||
if (ev->type() == QEvent::User) {
|
||||
ConsoleEvent* ce = static_cast<ConsoleEvent*>(ev);
|
||||
switch (ce->msgtype) {
|
||||
case ConsoleSingleton::MsgType_Txt:
|
||||
Console().notifyPrivate(LogStyle::Message, ce->recipient, ce->content, ce->notifier, ce->msg);
|
||||
Console().notifyPrivate(LogStyle::Message,
|
||||
ce->recipient,
|
||||
ce->content,
|
||||
ce->notifier,
|
||||
ce->msg);
|
||||
break;
|
||||
case ConsoleSingleton::MsgType_Log:
|
||||
Console().notifyPrivate(LogStyle::Log, ce->recipient, ce->content, ce->notifier, ce->msg);
|
||||
Console().notifyPrivate(LogStyle::Log,
|
||||
ce->recipient,
|
||||
ce->content,
|
||||
ce->notifier,
|
||||
ce->msg);
|
||||
break;
|
||||
case ConsoleSingleton::MsgType_Wrn:
|
||||
Console().notifyPrivate(LogStyle::Warning, ce->recipient, ce->content, ce->notifier, ce->msg);
|
||||
Console().notifyPrivate(LogStyle::Warning,
|
||||
ce->recipient,
|
||||
ce->content,
|
||||
ce->notifier,
|
||||
ce->msg);
|
||||
break;
|
||||
case ConsoleSingleton::MsgType_Err:
|
||||
Console().notifyPrivate(LogStyle::Error, ce->recipient, ce->content, ce->notifier, ce->msg);
|
||||
Console().notifyPrivate(LogStyle::Error,
|
||||
ce->recipient,
|
||||
ce->content,
|
||||
ce->notifier,
|
||||
ce->msg);
|
||||
break;
|
||||
case ConsoleSingleton::MsgType_Critical:
|
||||
Console().notifyPrivate(LogStyle::Critical, ce->recipient, ce->content, ce->notifier, ce->msg);
|
||||
Console().notifyPrivate(LogStyle::Critical,
|
||||
ce->recipient,
|
||||
ce->content,
|
||||
ce->notifier,
|
||||
ce->msg);
|
||||
break;
|
||||
case ConsoleSingleton::MsgType_Notification:
|
||||
Console().notifyPrivate(LogStyle::Notification, ce->recipient, ce->content, ce->notifier, ce->msg);
|
||||
Console().notifyPrivate(LogStyle::Notification,
|
||||
ce->recipient,
|
||||
ce->content,
|
||||
ce->notifier,
|
||||
ce->msg);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -110,7 +147,7 @@ private:
|
||||
|
||||
ConsoleOutput* ConsoleOutput::instance = nullptr;
|
||||
|
||||
}
|
||||
} // namespace Base
|
||||
|
||||
//**************************************************************************
|
||||
// Construction destruction
|
||||
@@ -118,18 +155,18 @@ ConsoleOutput* ConsoleOutput::instance = nullptr;
|
||||
|
||||
ConsoleSingleton::ConsoleSingleton()
|
||||
#ifdef FC_DEBUG
|
||||
: _defaultLogLevel(FC_LOGLEVEL_LOG)
|
||||
: _defaultLogLevel(FC_LOGLEVEL_LOG)
|
||||
#else
|
||||
: _defaultLogLevel(FC_LOGLEVEL_MSG)
|
||||
: _defaultLogLevel(FC_LOGLEVEL_MSG)
|
||||
#endif
|
||||
{
|
||||
}
|
||||
{}
|
||||
|
||||
ConsoleSingleton::~ConsoleSingleton()
|
||||
{
|
||||
ConsoleOutput::destruct();
|
||||
for (ILogger* Iter : _aclObservers)
|
||||
for (ILogger* Iter : _aclObservers) {
|
||||
delete Iter;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -141,8 +178,9 @@ ConsoleSingleton::~ConsoleSingleton()
|
||||
*/
|
||||
void ConsoleSingleton::SetConsoleMode(ConsoleMode m)
|
||||
{
|
||||
if (m & Verbose)
|
||||
if (m & Verbose) {
|
||||
_bVerbose = true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -150,18 +188,21 @@ void ConsoleSingleton::SetConsoleMode(ConsoleMode m)
|
||||
*/
|
||||
void ConsoleSingleton::UnsetConsoleMode(ConsoleMode m)
|
||||
{
|
||||
if (m & Verbose)
|
||||
if (m & Verbose) {
|
||||
_bVerbose = false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* \a type can be OR'ed with any of the FreeCAD_ConsoleMsgType flags to enable -- if \a b is true --
|
||||
* or to disable -- if \a b is false -- a console observer with name \a sObs.
|
||||
* The return value is an OR'ed value of all message types that have changed their state. For example
|
||||
* The return value is an OR'ed value of all message types that have changed their state. For
|
||||
* example
|
||||
* @code
|
||||
* // switch off warnings and error messages
|
||||
* ConsoleMsgFlags ret = Base::Console().SetEnabledMsgType("myObs",
|
||||
* Base:ConsoleSingleton::MsgType_Wrn|Base::ConsoleSingleton::MsgType_Err, false);
|
||||
* Base:ConsoleSingleton::MsgType_Wrn|Base::ConsoleSingleton::MsgType_Err,
|
||||
* false);
|
||||
* // do something without notifying observer myObs
|
||||
* ...
|
||||
* // restore the former configuration again
|
||||
@@ -173,37 +214,43 @@ void ConsoleSingleton::UnsetConsoleMode(ConsoleMode m)
|
||||
ConsoleMsgFlags ConsoleSingleton::SetEnabledMsgType(const char* sObs, ConsoleMsgFlags type, bool b)
|
||||
{
|
||||
ILogger* pObs = Get(sObs);
|
||||
if ( pObs ){
|
||||
ConsoleMsgFlags flags=0;
|
||||
if (pObs) {
|
||||
ConsoleMsgFlags flags = 0;
|
||||
|
||||
if ( type&MsgType_Err ){
|
||||
if ( pObs->bErr != b )
|
||||
if (type & MsgType_Err) {
|
||||
if (pObs->bErr != b) {
|
||||
flags |= MsgType_Err;
|
||||
}
|
||||
pObs->bErr = b;
|
||||
}
|
||||
if ( type&MsgType_Wrn ){
|
||||
if ( pObs->bWrn != b )
|
||||
if (type & MsgType_Wrn) {
|
||||
if (pObs->bWrn != b) {
|
||||
flags |= MsgType_Wrn;
|
||||
}
|
||||
pObs->bWrn = b;
|
||||
}
|
||||
if ( type&MsgType_Txt ){
|
||||
if ( pObs->bMsg != b )
|
||||
if (type & MsgType_Txt) {
|
||||
if (pObs->bMsg != b) {
|
||||
flags |= MsgType_Txt;
|
||||
}
|
||||
pObs->bMsg = b;
|
||||
}
|
||||
if ( type&MsgType_Log ){
|
||||
if ( pObs->bLog != b )
|
||||
if (type & MsgType_Log) {
|
||||
if (pObs->bLog != b) {
|
||||
flags |= MsgType_Log;
|
||||
}
|
||||
pObs->bLog = b;
|
||||
}
|
||||
if ( type&MsgType_Critical ){
|
||||
if ( pObs->bCritical != b )
|
||||
if (type & MsgType_Critical) {
|
||||
if (pObs->bCritical != b) {
|
||||
flags |= MsgType_Critical;
|
||||
}
|
||||
pObs->bCritical = b;
|
||||
}
|
||||
if ( type&MsgType_Notification ){
|
||||
if ( pObs->bNotification != b )
|
||||
if (type & MsgType_Notification) {
|
||||
if (pObs->bNotification != b) {
|
||||
flags |= MsgType_Notification;
|
||||
}
|
||||
pObs->bNotification = b;
|
||||
}
|
||||
|
||||
@@ -219,20 +266,20 @@ bool ConsoleSingleton::IsMsgTypeEnabled(const char* sObs, FreeCAD_ConsoleMsgType
|
||||
ILogger* pObs = Get(sObs);
|
||||
if (pObs) {
|
||||
switch (type) {
|
||||
case MsgType_Txt:
|
||||
return pObs->bMsg;
|
||||
case MsgType_Log:
|
||||
return pObs->bLog;
|
||||
case MsgType_Wrn:
|
||||
return pObs->bWrn;
|
||||
case MsgType_Err:
|
||||
return pObs->bErr;
|
||||
case MsgType_Critical:
|
||||
return pObs->bCritical;
|
||||
case MsgType_Notification:
|
||||
return pObs->bNotification;
|
||||
default:
|
||||
return false;
|
||||
case MsgType_Txt:
|
||||
return pObs->bMsg;
|
||||
case MsgType_Log:
|
||||
return pObs->bLog;
|
||||
case MsgType_Wrn:
|
||||
return pObs->bWrn;
|
||||
case MsgType_Err:
|
||||
return pObs->bErr;
|
||||
case MsgType_Critical:
|
||||
return pObs->bCritical;
|
||||
case MsgType_Notification:
|
||||
return pObs->bNotification;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -258,10 +305,10 @@ void ConsoleSingleton::SetConnectionMode(ConnectionMode mode)
|
||||
* be forwarded to it.
|
||||
* @see ILogger
|
||||
*/
|
||||
void ConsoleSingleton::AttachObserver(ILogger *pcObserver)
|
||||
void ConsoleSingleton::AttachObserver(ILogger* pcObserver)
|
||||
{
|
||||
// double insert !!
|
||||
assert(_aclObservers.find(pcObserver) == _aclObservers.end() );
|
||||
assert(_aclObservers.find(pcObserver) == _aclObservers.end());
|
||||
|
||||
_aclObservers.insert(pcObserver);
|
||||
}
|
||||
@@ -271,76 +318,95 @@ void ConsoleSingleton::AttachObserver(ILogger *pcObserver)
|
||||
* After detaching you can destruct the Observer or reinsert it later.
|
||||
* @see ILogger
|
||||
*/
|
||||
void ConsoleSingleton::DetachObserver(ILogger *pcObserver)
|
||||
void ConsoleSingleton::DetachObserver(ILogger* pcObserver)
|
||||
{
|
||||
_aclObservers.erase(pcObserver);
|
||||
}
|
||||
|
||||
void Base::ConsoleSingleton::notifyPrivate(LogStyle category, IntendedRecipient recipient,
|
||||
ContentType content, const std::string& notifiername, const std::string& msg)
|
||||
void Base::ConsoleSingleton::notifyPrivate(LogStyle category,
|
||||
IntendedRecipient recipient,
|
||||
ContentType content,
|
||||
const std::string& notifiername,
|
||||
const std::string& msg)
|
||||
{
|
||||
for (ILogger* Iter : _aclObservers) {
|
||||
if (Iter->isActive(category)) {
|
||||
Iter->SendLog(notifiername, msg, category, recipient, content); // send string to the listener
|
||||
Iter->SendLog(notifiername,
|
||||
msg,
|
||||
category,
|
||||
recipient,
|
||||
content); // send string to the listener
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ConsoleSingleton::postEvent(ConsoleSingleton::FreeCAD_ConsoleMsgType type, IntendedRecipient recipient,
|
||||
ContentType content, const std::string& notifiername, const std::string& msg)
|
||||
void ConsoleSingleton::postEvent(ConsoleSingleton::FreeCAD_ConsoleMsgType type,
|
||||
IntendedRecipient recipient,
|
||||
ContentType content,
|
||||
const std::string& notifiername,
|
||||
const std::string& msg)
|
||||
{
|
||||
QCoreApplication::postEvent(ConsoleOutput::getInstance(), new ConsoleEvent(type, recipient, content, notifiername, msg));
|
||||
QCoreApplication::postEvent(ConsoleOutput::getInstance(),
|
||||
new ConsoleEvent(type, recipient, content, notifiername, msg));
|
||||
}
|
||||
|
||||
ILogger *ConsoleSingleton::Get(const char *Name) const
|
||||
ILogger* ConsoleSingleton::Get(const char* Name) const
|
||||
{
|
||||
const char* OName{};
|
||||
const char* OName {};
|
||||
for (ILogger* Iter : _aclObservers) {
|
||||
OName = Iter->Name(); // get the name
|
||||
if (OName && strcmp(OName,Name) == 0)
|
||||
OName = Iter->Name(); // get the name
|
||||
if (OName && strcmp(OName, Name) == 0) {
|
||||
return Iter;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
int *ConsoleSingleton::GetLogLevel(const char *tag, bool create) {
|
||||
if (!tag) tag = "";
|
||||
if (_logLevels.find(tag) != _logLevels.end())
|
||||
int* ConsoleSingleton::GetLogLevel(const char* tag, bool create)
|
||||
{
|
||||
if (!tag) {
|
||||
tag = "";
|
||||
}
|
||||
if (_logLevels.find(tag) != _logLevels.end()) {
|
||||
return &_logLevels[tag];
|
||||
if (!create)
|
||||
}
|
||||
if (!create) {
|
||||
return nullptr;
|
||||
int &ret = _logLevels[tag];
|
||||
}
|
||||
int& ret = _logLevels[tag];
|
||||
ret = -1;
|
||||
return &ret;
|
||||
}
|
||||
|
||||
void ConsoleSingleton::Refresh() {
|
||||
if (_bCanRefresh)
|
||||
void ConsoleSingleton::Refresh()
|
||||
{
|
||||
if (_bCanRefresh) {
|
||||
qApp->processEvents(QEventLoop::ExcludeUserInputEvents);
|
||||
}
|
||||
}
|
||||
|
||||
void ConsoleSingleton::EnableRefresh(bool enable) {
|
||||
void ConsoleSingleton::EnableRefresh(bool enable)
|
||||
{
|
||||
_bCanRefresh = enable;
|
||||
}
|
||||
|
||||
//**************************************************************************
|
||||
// Singleton stuff
|
||||
|
||||
ConsoleSingleton * ConsoleSingleton::_pcSingleton = nullptr;
|
||||
ConsoleSingleton* ConsoleSingleton::_pcSingleton = nullptr;
|
||||
|
||||
void ConsoleSingleton::Destruct()
|
||||
{
|
||||
// not initialized or double destructed!
|
||||
assert(_pcSingleton);
|
||||
delete _pcSingleton;
|
||||
_pcSingleton=nullptr;
|
||||
_pcSingleton = nullptr;
|
||||
}
|
||||
|
||||
ConsoleSingleton & ConsoleSingleton::Instance()
|
||||
ConsoleSingleton& ConsoleSingleton::Instance()
|
||||
{
|
||||
// not initialized?
|
||||
if (!_pcSingleton)
|
||||
{
|
||||
if (!_pcSingleton) {
|
||||
_pcSingleton = new ConsoleSingleton();
|
||||
}
|
||||
return *_pcSingleton;
|
||||
@@ -351,85 +417,118 @@ ConsoleSingleton & ConsoleSingleton::Instance()
|
||||
|
||||
// ConsoleSingleton Methods structure
|
||||
PyMethodDef ConsoleSingleton::Methods[] = {
|
||||
{"PrintMessage", ConsoleSingleton::sPyMessage, METH_VARARGS,
|
||||
{"PrintMessage",
|
||||
ConsoleSingleton::sPyMessage,
|
||||
METH_VARARGS,
|
||||
"PrintMessage(obj) -> None\n\n"
|
||||
"Print a message to the output.\n\n"
|
||||
"obj : object\n The string representation is printed."},
|
||||
{"PrintLog", ConsoleSingleton::sPyLog, METH_VARARGS,
|
||||
{"PrintLog",
|
||||
ConsoleSingleton::sPyLog,
|
||||
METH_VARARGS,
|
||||
"PrintLog(obj) -> None\n\n"
|
||||
"Print a log message to the output.\n\n"
|
||||
"obj : object\n The string representation is printed."},
|
||||
{"PrintError", ConsoleSingleton::sPyError, METH_VARARGS,
|
||||
{"PrintError",
|
||||
ConsoleSingleton::sPyError,
|
||||
METH_VARARGS,
|
||||
"PrintError(obj) -> None\n\n"
|
||||
"Print an error message to the output.\n\n"
|
||||
"obj : object\n The string representation is printed."},
|
||||
{"PrintDeveloperError", ConsoleSingleton::sPyDeveloperError, METH_VARARGS,
|
||||
{"PrintDeveloperError",
|
||||
ConsoleSingleton::sPyDeveloperError,
|
||||
METH_VARARGS,
|
||||
"PrintDeveloperError(obj) -> None\n\n"
|
||||
"Print an error message intended only for Developers to the output.\n\n"
|
||||
"obj : object\n The string representation is printed."},
|
||||
{"PrintUserError", ConsoleSingleton::sPyUserError, METH_VARARGS,
|
||||
{"PrintUserError",
|
||||
ConsoleSingleton::sPyUserError,
|
||||
METH_VARARGS,
|
||||
"PrintUserError(obj) -> None\n\n"
|
||||
"Print an error message intended only for the User to the output.\n\n"
|
||||
"obj : object\n The string representation is printed."},
|
||||
{"PrintTranslatedUserError", ConsoleSingleton::sPyTranslatedUserError, METH_VARARGS,
|
||||
{"PrintTranslatedUserError",
|
||||
ConsoleSingleton::sPyTranslatedUserError,
|
||||
METH_VARARGS,
|
||||
"PrintTranslatedUserError(obj) -> None\n\n"
|
||||
"Print an already translated error message intended only for the User to the output.\n\n"
|
||||
"obj : object\n The string representation is printed."},
|
||||
{"PrintWarning", ConsoleSingleton::sPyWarning, METH_VARARGS,
|
||||
{"PrintWarning",
|
||||
ConsoleSingleton::sPyWarning,
|
||||
METH_VARARGS,
|
||||
"PrintWarning(obj) -> None\n\n"
|
||||
"Print a warning message to the output.\n\n"
|
||||
"obj : object\n The string representation is printed."},
|
||||
{"PrintDeveloperWarning", ConsoleSingleton::sPyDeveloperWarning, METH_VARARGS,
|
||||
{"PrintDeveloperWarning",
|
||||
ConsoleSingleton::sPyDeveloperWarning,
|
||||
METH_VARARGS,
|
||||
"PrintDeveloperWarning(obj) -> None\n\n"
|
||||
"Print an warning message intended only for Developers to the output.\n\n"
|
||||
"obj : object\n The string representation is printed."},
|
||||
{"PrintUserWarning", ConsoleSingleton::sPyUserWarning, METH_VARARGS,
|
||||
{"PrintUserWarning",
|
||||
ConsoleSingleton::sPyUserWarning,
|
||||
METH_VARARGS,
|
||||
"PrintUserWarning(obj) -> None\n\n"
|
||||
"Print a warning message intended only for the User to the output.\n\n"
|
||||
"obj : object\n The string representation is printed."},
|
||||
{"PrintTranslatedUserWarning", ConsoleSingleton::sPyTranslatedUserWarning, METH_VARARGS,
|
||||
{"PrintTranslatedUserWarning",
|
||||
ConsoleSingleton::sPyTranslatedUserWarning,
|
||||
METH_VARARGS,
|
||||
"PrintTranslatedUserWarning(obj) -> None\n\n"
|
||||
"Print an already translated warning message intended only for the User to the output.\n\n"
|
||||
"obj : object\n The string representation is printed."},
|
||||
{"PrintCritical",ConsoleSingleton::sPyCritical, METH_VARARGS,
|
||||
{"PrintCritical",
|
||||
ConsoleSingleton::sPyCritical,
|
||||
METH_VARARGS,
|
||||
"PrintCritical(obj) -> None\n\n"
|
||||
"Print a critical message to the output.\n\n"
|
||||
"obj : object\n The string representation is printed."},
|
||||
{"PrintNotification", ConsoleSingleton::sPyNotification, METH_VARARGS,
|
||||
{"PrintNotification",
|
||||
ConsoleSingleton::sPyNotification,
|
||||
METH_VARARGS,
|
||||
"PrintNotification(obj) -> None\n\n"
|
||||
"Print a user notification to the output.\n\n"
|
||||
"obj : object\n The string representation is printed."},
|
||||
{"PrintTranslatedNotification", ConsoleSingleton::sPyTranslatedNotification, METH_VARARGS,
|
||||
{"PrintTranslatedNotification",
|
||||
ConsoleSingleton::sPyTranslatedNotification,
|
||||
METH_VARARGS,
|
||||
"PrintTranslatedNotification(obj) -> None\n\n"
|
||||
"Print an already translated notification to the output.\n\n"
|
||||
"obj : object\n The string representation is printed."},
|
||||
{"SetStatus", ConsoleSingleton::sPySetStatus, METH_VARARGS,
|
||||
{"SetStatus",
|
||||
ConsoleSingleton::sPySetStatus,
|
||||
METH_VARARGS,
|
||||
"SetStatus(observer, type, status) -> None\n\n"
|
||||
"Set the status for either 'Log', 'Msg', 'Wrn' or 'Error' for an observer.\n\n"
|
||||
"observer : str\n Logging interface name.\n"
|
||||
"type : str\n Message type.\n"
|
||||
"status : bool"},
|
||||
{"GetStatus", ConsoleSingleton::sPyGetStatus, METH_VARARGS,
|
||||
{"GetStatus",
|
||||
ConsoleSingleton::sPyGetStatus,
|
||||
METH_VARARGS,
|
||||
"GetStatus(observer, type) -> bool or None\n\n"
|
||||
"Get the status for either 'Log', 'Msg', 'Wrn' or 'Error' for an observer.\n"
|
||||
"Returns None if the specified observer doesn't exist.\n\n"
|
||||
"observer : str\n Logging interface name.\n"
|
||||
"type : str\n Message type."},
|
||||
{"GetObservers", ConsoleSingleton::sPyGetObservers, METH_VARARGS,
|
||||
{"GetObservers",
|
||||
ConsoleSingleton::sPyGetObservers,
|
||||
METH_VARARGS,
|
||||
"GetObservers() -> list of str\n\n"
|
||||
"Get the names of the current logging interfaces."},
|
||||
{nullptr, nullptr, 0, nullptr} /* Sentinel */
|
||||
{nullptr, nullptr, 0, nullptr} /* Sentinel */
|
||||
};
|
||||
|
||||
namespace {
|
||||
PyObject* FC_PYCONSOLE_MSG(std::function<void(const char*, const char *)> func, PyObject* args)
|
||||
namespace
|
||||
{
|
||||
PyObject *output{};
|
||||
PyObject *notifier{};
|
||||
PyObject* FC_PYCONSOLE_MSG(std::function<void(const char*, const char*)> func, PyObject* args)
|
||||
{
|
||||
PyObject* output {};
|
||||
PyObject* notifier {};
|
||||
|
||||
const char* notifierStr = "";
|
||||
|
||||
auto retrieveString = [] (PyObject* pystr) {
|
||||
auto retrieveString = [](PyObject* pystr) {
|
||||
PyObject* unicode = nullptr;
|
||||
|
||||
const char* outstr = nullptr;
|
||||
@@ -439,8 +538,9 @@ PyObject* FC_PYCONSOLE_MSG(std::function<void(const char*, const char *)> func,
|
||||
}
|
||||
else {
|
||||
unicode = PyObject_Str(pystr);
|
||||
if (unicode)
|
||||
if (unicode) {
|
||||
outstr = PyUnicode_AsUTF8(unicode);
|
||||
}
|
||||
}
|
||||
|
||||
Py_XDECREF(unicode);
|
||||
@@ -454,221 +554,285 @@ PyObject* FC_PYCONSOLE_MSG(std::function<void(const char*, const char *)> func,
|
||||
if (!PyArg_ParseTuple(args, "O", &output)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
}
|
||||
else { // retrieve notifier
|
||||
PY_TRY {
|
||||
else { // retrieve notifier
|
||||
PY_TRY
|
||||
{
|
||||
notifierStr = retrieveString(notifier);
|
||||
}
|
||||
PY_CATCH
|
||||
}
|
||||
|
||||
PY_TRY {
|
||||
PY_TRY
|
||||
{
|
||||
const char* string = retrieveString(output);
|
||||
|
||||
if (string)
|
||||
func(notifierStr, string); /*process message*/
|
||||
|
||||
if (string) {
|
||||
func(notifierStr, string); /*process message*/
|
||||
}
|
||||
}
|
||||
PY_CATCH
|
||||
Py_Return;
|
||||
}
|
||||
} // namespace
|
||||
|
||||
PyObject* ConsoleSingleton::sPyMessage(PyObject* /*self*/, PyObject* args)
|
||||
{
|
||||
return FC_PYCONSOLE_MSG(
|
||||
[](const std::string& notifier, const char* msg) {
|
||||
Instance()
|
||||
.Send<Base::LogStyle::Message,
|
||||
Base::IntendedRecipient::Developer,
|
||||
Base::ContentType::Untranslatable>(notifier, "%s", msg);
|
||||
},
|
||||
args);
|
||||
}
|
||||
|
||||
PyObject *ConsoleSingleton::sPyMessage(PyObject * /*self*/, PyObject *args)
|
||||
PyObject* ConsoleSingleton::sPyWarning(PyObject* /*self*/, PyObject* args)
|
||||
{
|
||||
return FC_PYCONSOLE_MSG([](const std::string & notifier, const char* msg) {
|
||||
Instance().Send<Base::LogStyle::Message,
|
||||
Base::IntendedRecipient::Developer,
|
||||
Base::ContentType::Untranslatable>(notifier, "%s", msg);
|
||||
}, args);
|
||||
return FC_PYCONSOLE_MSG(
|
||||
[](const std::string& notifier, const char* msg) {
|
||||
Instance().Warning(notifier, "%s", msg);
|
||||
},
|
||||
args);
|
||||
}
|
||||
|
||||
PyObject *ConsoleSingleton::sPyWarning(PyObject * /*self*/, PyObject *args)
|
||||
PyObject* ConsoleSingleton::sPyDeveloperWarning(PyObject* /*self*/, PyObject* args)
|
||||
{
|
||||
return FC_PYCONSOLE_MSG([](const std::string & notifier, const char* msg) {
|
||||
Instance().Warning(notifier, "%s", msg);
|
||||
}, args);
|
||||
return FC_PYCONSOLE_MSG(
|
||||
[](const std::string& notifier, const char* msg) {
|
||||
Instance()
|
||||
.Send<Base::LogStyle::Warning,
|
||||
Base::IntendedRecipient::Developer,
|
||||
Base::ContentType::Untranslatable>(notifier, "%s", msg);
|
||||
},
|
||||
args);
|
||||
}
|
||||
|
||||
PyObject *ConsoleSingleton::sPyDeveloperWarning(PyObject * /*self*/, PyObject *args)
|
||||
PyObject* ConsoleSingleton::sPyUserWarning(PyObject* /*self*/, PyObject* args)
|
||||
{
|
||||
return FC_PYCONSOLE_MSG([](const std::string & notifier, const char* msg) {
|
||||
Instance().Send<Base::LogStyle::Warning,
|
||||
Base::IntendedRecipient::Developer,
|
||||
Base::ContentType::Untranslatable>(notifier, "%s", msg);
|
||||
}, args);
|
||||
return FC_PYCONSOLE_MSG(
|
||||
[](const std::string& notifier, const char* msg) {
|
||||
Instance()
|
||||
.Send<Base::LogStyle::Warning,
|
||||
Base::IntendedRecipient::User,
|
||||
Base::ContentType::Untranslated>(notifier, "%s", msg);
|
||||
},
|
||||
args);
|
||||
}
|
||||
|
||||
PyObject *ConsoleSingleton::sPyUserWarning(PyObject * /*self*/, PyObject *args)
|
||||
PyObject* ConsoleSingleton::sPyTranslatedUserWarning(PyObject* /*self*/, PyObject* args)
|
||||
{
|
||||
return FC_PYCONSOLE_MSG([](const std::string & notifier, const char* msg) {
|
||||
Instance().Send<Base::LogStyle::Warning,
|
||||
Base::IntendedRecipient::User,
|
||||
Base::ContentType::Untranslated>(notifier, "%s", msg);
|
||||
}, args);
|
||||
return FC_PYCONSOLE_MSG(
|
||||
[](const std::string& notifier, const char* msg) {
|
||||
Instance()
|
||||
.Send<Base::LogStyle::Warning,
|
||||
Base::IntendedRecipient::User,
|
||||
Base::ContentType::Translated>(notifier, "%s", msg);
|
||||
},
|
||||
args);
|
||||
}
|
||||
|
||||
PyObject *ConsoleSingleton::sPyTranslatedUserWarning(PyObject * /*self*/, PyObject *args)
|
||||
PyObject* ConsoleSingleton::sPyError(PyObject* /*self*/, PyObject* args)
|
||||
{
|
||||
return FC_PYCONSOLE_MSG([](const std::string & notifier, const char* msg) {
|
||||
Instance().Send<Base::LogStyle::Warning,
|
||||
Base::IntendedRecipient::User,
|
||||
Base::ContentType::Translated>(notifier, "%s", msg);
|
||||
}, args);
|
||||
return FC_PYCONSOLE_MSG(
|
||||
[](const std::string& notifier, const char* msg) {
|
||||
Instance()
|
||||
.Send<Base::LogStyle::Error,
|
||||
Base::IntendedRecipient::All,
|
||||
Base::ContentType::Untranslated>(notifier, "%s", msg);
|
||||
},
|
||||
args);
|
||||
}
|
||||
|
||||
PyObject *ConsoleSingleton::sPyError(PyObject * /*self*/, PyObject *args)
|
||||
PyObject* ConsoleSingleton::sPyDeveloperError(PyObject* /*self*/, PyObject* args)
|
||||
{
|
||||
return FC_PYCONSOLE_MSG([](const std::string & notifier, const char* msg) {
|
||||
Instance().Send<Base::LogStyle::Error,
|
||||
Base::IntendedRecipient::All,
|
||||
Base::ContentType::Untranslated>(notifier, "%s", msg);
|
||||
}, args);
|
||||
return FC_PYCONSOLE_MSG(
|
||||
[](const std::string& notifier, const char* msg) {
|
||||
Instance()
|
||||
.Send<Base::LogStyle::Error,
|
||||
Base::IntendedRecipient::Developer,
|
||||
Base::ContentType::Untranslatable>(notifier, "%s", msg);
|
||||
},
|
||||
args);
|
||||
}
|
||||
|
||||
PyObject *ConsoleSingleton::sPyDeveloperError(PyObject * /*self*/, PyObject *args)
|
||||
PyObject* ConsoleSingleton::sPyUserError(PyObject* /*self*/, PyObject* args)
|
||||
{
|
||||
return FC_PYCONSOLE_MSG([](const std::string & notifier, const char* msg) {
|
||||
Instance().Send<Base::LogStyle::Error,
|
||||
Base::IntendedRecipient::Developer,
|
||||
Base::ContentType::Untranslatable>(notifier, "%s", msg);
|
||||
}, args);
|
||||
return FC_PYCONSOLE_MSG(
|
||||
[](const std::string& notifier, const char* msg) {
|
||||
Instance()
|
||||
.Send<Base::LogStyle::Error,
|
||||
Base::IntendedRecipient::User,
|
||||
Base::ContentType::Untranslated>(notifier, "%s", msg);
|
||||
},
|
||||
args);
|
||||
}
|
||||
|
||||
PyObject *ConsoleSingleton::sPyUserError(PyObject * /*self*/, PyObject *args)
|
||||
PyObject* ConsoleSingleton::sPyTranslatedUserError(PyObject* /*self*/, PyObject* args)
|
||||
{
|
||||
return FC_PYCONSOLE_MSG([](const std::string & notifier, const char* msg) {
|
||||
Instance().Send<Base::LogStyle::Error,
|
||||
Base::IntendedRecipient::User,
|
||||
Base::ContentType::Untranslated>(notifier, "%s", msg);
|
||||
}, args);
|
||||
return FC_PYCONSOLE_MSG(
|
||||
[](const std::string& notifier, const char* msg) {
|
||||
Instance()
|
||||
.Send<Base::LogStyle::Error,
|
||||
Base::IntendedRecipient::User,
|
||||
Base::ContentType::Translated>(notifier, "%s", msg);
|
||||
},
|
||||
args);
|
||||
}
|
||||
|
||||
PyObject *ConsoleSingleton::sPyTranslatedUserError(PyObject * /*self*/, PyObject *args)
|
||||
PyObject* ConsoleSingleton::sPyLog(PyObject* /*self*/, PyObject* args)
|
||||
{
|
||||
return FC_PYCONSOLE_MSG([](const std::string & notifier, const char* msg) {
|
||||
Instance().Send<Base::LogStyle::Error,
|
||||
Base::IntendedRecipient::User,
|
||||
Base::ContentType::Translated>(notifier, "%s", msg);
|
||||
}, args);
|
||||
return FC_PYCONSOLE_MSG(
|
||||
[](const std::string& notifier, const char* msg) {
|
||||
Instance()
|
||||
.Send<Base::LogStyle::Log,
|
||||
Base::IntendedRecipient::Developer,
|
||||
Base::ContentType::Untranslatable>(notifier, "%s", msg);
|
||||
},
|
||||
args);
|
||||
}
|
||||
|
||||
PyObject *ConsoleSingleton::sPyLog(PyObject * /*self*/, PyObject *args)
|
||||
PyObject* ConsoleSingleton::sPyCritical(PyObject* /*self*/, PyObject* args)
|
||||
{
|
||||
return FC_PYCONSOLE_MSG([](const std::string & notifier, const char* msg) {
|
||||
Instance().Send<Base::LogStyle::Log,
|
||||
Base::IntendedRecipient::Developer,
|
||||
Base::ContentType::Untranslatable>(notifier, "%s", msg);
|
||||
}, args);
|
||||
return FC_PYCONSOLE_MSG(
|
||||
[](const std::string& notifier, const char* msg) {
|
||||
Instance()
|
||||
.Send<Base::LogStyle::Critical,
|
||||
Base::IntendedRecipient::All,
|
||||
Base::ContentType::Untranslated>(notifier, "%s", msg);
|
||||
},
|
||||
args);
|
||||
}
|
||||
|
||||
PyObject *ConsoleSingleton::sPyCritical(PyObject * /*self*/, PyObject *args)
|
||||
PyObject* ConsoleSingleton::sPyNotification(PyObject* /*self*/, PyObject* args)
|
||||
{
|
||||
return FC_PYCONSOLE_MSG([](const std::string & notifier, const char* msg) {
|
||||
Instance().Send<Base::LogStyle::Critical,
|
||||
Base::IntendedRecipient::All,
|
||||
Base::ContentType::Untranslated>(notifier, "%s", msg);
|
||||
}, args);
|
||||
return FC_PYCONSOLE_MSG(
|
||||
[](const std::string& notifier, const char* msg) {
|
||||
Instance()
|
||||
.Send<Base::LogStyle::Notification,
|
||||
Base::IntendedRecipient::User,
|
||||
Base::ContentType::Untranslated>(notifier, "%s", msg);
|
||||
},
|
||||
args);
|
||||
}
|
||||
|
||||
PyObject *ConsoleSingleton::sPyNotification(PyObject * /*self*/, PyObject *args)
|
||||
PyObject* ConsoleSingleton::sPyTranslatedNotification(PyObject* /*self*/, PyObject* args)
|
||||
{
|
||||
return FC_PYCONSOLE_MSG([](const std::string & notifier, const char* msg) {
|
||||
Instance().Send<Base::LogStyle::Notification,
|
||||
Base::IntendedRecipient::User,
|
||||
Base::ContentType::Untranslated>(notifier, "%s", msg);
|
||||
}, args);
|
||||
return FC_PYCONSOLE_MSG(
|
||||
[](const std::string& notifier, const char* msg) {
|
||||
Instance()
|
||||
.Send<Base::LogStyle::Notification,
|
||||
Base::IntendedRecipient::User,
|
||||
Base::ContentType::Translated>(notifier, "%s", msg);
|
||||
},
|
||||
args);
|
||||
}
|
||||
|
||||
PyObject *ConsoleSingleton::sPyTranslatedNotification(PyObject * /*self*/, PyObject *args)
|
||||
PyObject* ConsoleSingleton::sPyGetStatus(PyObject* /*self*/, PyObject* args)
|
||||
{
|
||||
return FC_PYCONSOLE_MSG([](const std::string & notifier, const char* msg) {
|
||||
Instance().Send<Base::LogStyle::Notification,
|
||||
Base::IntendedRecipient::User,
|
||||
Base::ContentType::Translated>(notifier, "%s", msg);
|
||||
}, args);
|
||||
}
|
||||
|
||||
PyObject *ConsoleSingleton::sPyGetStatus(PyObject * /*self*/, PyObject *args)
|
||||
{
|
||||
char *pstr1{};
|
||||
char *pstr2{};
|
||||
if (!PyArg_ParseTuple(args, "ss", &pstr1, &pstr2))
|
||||
char* pstr1 {};
|
||||
char* pstr2 {};
|
||||
if (!PyArg_ParseTuple(args, "ss", &pstr1, &pstr2)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
PY_TRY{
|
||||
bool b=false;
|
||||
ILogger *pObs = Instance().Get(pstr1);
|
||||
if (!pObs)
|
||||
PY_TRY
|
||||
{
|
||||
bool b = false;
|
||||
ILogger* pObs = Instance().Get(pstr1);
|
||||
if (!pObs) {
|
||||
Py_Return;
|
||||
}
|
||||
|
||||
if (strcmp(pstr2,"Log") == 0)
|
||||
if (strcmp(pstr2, "Log") == 0) {
|
||||
b = pObs->bLog;
|
||||
else if (strcmp(pstr2,"Wrn") == 0)
|
||||
}
|
||||
else if (strcmp(pstr2, "Wrn") == 0) {
|
||||
b = pObs->bWrn;
|
||||
else if (strcmp(pstr2,"Msg") == 0)
|
||||
}
|
||||
else if (strcmp(pstr2, "Msg") == 0) {
|
||||
b = pObs->bMsg;
|
||||
else if (strcmp(pstr2,"Err") == 0)
|
||||
}
|
||||
else if (strcmp(pstr2, "Err") == 0) {
|
||||
b = pObs->bErr;
|
||||
else if (strcmp(pstr2,"Critical") == 0)
|
||||
}
|
||||
else if (strcmp(pstr2, "Critical") == 0) {
|
||||
b = pObs->bCritical;
|
||||
else if (strcmp(pstr2,"Notification") == 0)
|
||||
}
|
||||
else if (strcmp(pstr2, "Notification") == 0) {
|
||||
b = pObs->bNotification;
|
||||
else
|
||||
Py_Error(Base::PyExc_FC_GeneralError,"Unknown message type (use 'Log', 'Err', 'Wrn', 'Msg', 'Critical' or 'Notification')");
|
||||
}
|
||||
else {
|
||||
Py_Error(Base::PyExc_FC_GeneralError,
|
||||
"Unknown message type (use 'Log', 'Err', 'Wrn', 'Msg', 'Critical' or "
|
||||
"'Notification')");
|
||||
}
|
||||
|
||||
return PyBool_FromLong(b ? 1 : 0);
|
||||
}
|
||||
PY_CATCH;
|
||||
}
|
||||
|
||||
PyObject *ConsoleSingleton::sPySetStatus(PyObject * /*self*/, PyObject *args)
|
||||
PyObject* ConsoleSingleton::sPySetStatus(PyObject* /*self*/, PyObject* args)
|
||||
{
|
||||
char *pstr1{};
|
||||
char *pstr2{};
|
||||
PyObject* pyStatus{};
|
||||
if (!PyArg_ParseTuple(args, "ssO!", &pstr1, &pstr2, &PyBool_Type, &pyStatus))
|
||||
char* pstr1 {};
|
||||
char* pstr2 {};
|
||||
PyObject* pyStatus {};
|
||||
if (!PyArg_ParseTuple(args, "ssO!", &pstr1, &pstr2, &PyBool_Type, &pyStatus)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
PY_TRY{
|
||||
PY_TRY
|
||||
{
|
||||
bool status = asBoolean(pyStatus);
|
||||
ILogger *pObs = Instance().Get(pstr1);
|
||||
ILogger* pObs = Instance().Get(pstr1);
|
||||
if (pObs) {
|
||||
if (strcmp(pstr2,"Log") == 0)
|
||||
if (strcmp(pstr2, "Log") == 0) {
|
||||
pObs->bLog = status;
|
||||
else if (strcmp(pstr2,"Wrn") == 0)
|
||||
}
|
||||
else if (strcmp(pstr2, "Wrn") == 0) {
|
||||
pObs->bWrn = status;
|
||||
else if (strcmp(pstr2,"Msg") == 0)
|
||||
}
|
||||
else if (strcmp(pstr2, "Msg") == 0) {
|
||||
pObs->bMsg = status;
|
||||
else if (strcmp(pstr2,"Err") == 0)
|
||||
}
|
||||
else if (strcmp(pstr2, "Err") == 0) {
|
||||
pObs->bErr = status;
|
||||
else if (strcmp(pstr2,"Critical") == 0)
|
||||
}
|
||||
else if (strcmp(pstr2, "Critical") == 0) {
|
||||
pObs->bCritical = status;
|
||||
else if (strcmp(pstr2,"Notification") == 0)
|
||||
}
|
||||
else if (strcmp(pstr2, "Notification") == 0) {
|
||||
pObs->bNotification = status;
|
||||
else
|
||||
Py_Error(Base::PyExc_FC_GeneralError,"Unknown message type (use 'Log', 'Err', 'Wrn', 'Msg', 'Critical' or 'Notification')");
|
||||
}
|
||||
else {
|
||||
Py_Error(Base::PyExc_FC_GeneralError,
|
||||
"Unknown message type (use 'Log', 'Err', 'Wrn', 'Msg', 'Critical' or "
|
||||
"'Notification')");
|
||||
}
|
||||
|
||||
Py_Return;
|
||||
}
|
||||
else {
|
||||
Py_Error(Base::PyExc_FC_GeneralError,"Unknown logger type");
|
||||
Py_Error(Base::PyExc_FC_GeneralError, "Unknown logger type");
|
||||
}
|
||||
|
||||
}
|
||||
PY_CATCH;
|
||||
}
|
||||
|
||||
PyObject *ConsoleSingleton::sPyGetObservers(PyObject * /*self*/, PyObject *args)
|
||||
PyObject* ConsoleSingleton::sPyGetObservers(PyObject* /*self*/, PyObject* args)
|
||||
{
|
||||
if (!PyArg_ParseTuple(args, ""))
|
||||
if (!PyArg_ParseTuple(args, "")) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
PY_TRY {
|
||||
PY_TRY
|
||||
{
|
||||
Py::List list;
|
||||
for (auto i : Instance()._aclObservers)
|
||||
for (auto i : Instance()._aclObservers) {
|
||||
list.append(Py::String(i->Name() ? i->Name() : ""));
|
||||
}
|
||||
|
||||
return Py::new_reference_to(list);
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -24,11 +24,11 @@
|
||||
#include "PreCompiled.h"
|
||||
|
||||
#ifndef _PreComp_
|
||||
# ifdef FC_OS_WIN32
|
||||
# include <windows.h>
|
||||
# endif
|
||||
# include <cstring>
|
||||
# include <Python.h>
|
||||
#ifdef FC_OS_WIN32
|
||||
#include <windows.h>
|
||||
#endif
|
||||
#include <cstring>
|
||||
#include <Python.h>
|
||||
#endif
|
||||
|
||||
#include <frameobject.h>
|
||||
@@ -43,14 +43,15 @@ using namespace Base;
|
||||
//=========================================================================
|
||||
// some special observers
|
||||
|
||||
ConsoleObserverFile::ConsoleObserverFile(const char *sFileName)
|
||||
: cFileStream(Base::FileInfo(sFileName)) // can be in UTF8
|
||||
ConsoleObserverFile::ConsoleObserverFile(const char* sFileName)
|
||||
: cFileStream(Base::FileInfo(sFileName)) // can be in UTF8
|
||||
{
|
||||
if (!cFileStream.is_open())
|
||||
if (!cFileStream.is_open()) {
|
||||
Console().Warning("Cannot open log file '%s'.\n", sFileName);
|
||||
}
|
||||
// mark the file as a UTF-8 encoded file
|
||||
unsigned char bom[3] = {0xef, 0xbb, 0xbf};
|
||||
cFileStream.write(reinterpret_cast<const char*>(bom), 3*sizeof(char));
|
||||
cFileStream.write(reinterpret_cast<const char*>(bom), 3 * sizeof(char));
|
||||
}
|
||||
|
||||
ConsoleObserverFile::~ConsoleObserverFile()
|
||||
@@ -58,17 +59,21 @@ ConsoleObserverFile::~ConsoleObserverFile()
|
||||
cFileStream.close();
|
||||
}
|
||||
|
||||
void ConsoleObserverFile::SendLog(const std::string& notifiername, const std::string& msg, LogStyle level,
|
||||
IntendedRecipient recipient, ContentType content)
|
||||
void ConsoleObserverFile::SendLog(const std::string& notifiername,
|
||||
const std::string& msg,
|
||||
LogStyle level,
|
||||
IntendedRecipient recipient,
|
||||
ContentType content)
|
||||
{
|
||||
(void) notifiername;
|
||||
(void)notifiername;
|
||||
|
||||
// Do not log translated messages, or messages intended only to the user to log file
|
||||
if(recipient == IntendedRecipient::User || content == ContentType::Translated)
|
||||
if (recipient == IntendedRecipient::User || content == ContentType::Translated) {
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
std::string prefix;
|
||||
switch(level){
|
||||
switch (level) {
|
||||
case LogStyle::Warning:
|
||||
prefix = "Wrn: ";
|
||||
break;
|
||||
@@ -92,30 +97,35 @@ void ConsoleObserverFile::SendLog(const std::string& notifiername, const std::st
|
||||
cFileStream.flush();
|
||||
}
|
||||
|
||||
ConsoleObserverStd::ConsoleObserverStd() :
|
||||
# if defined(FC_OS_WIN32)
|
||||
ConsoleObserverStd::ConsoleObserverStd()
|
||||
:
|
||||
#if defined(FC_OS_WIN32)
|
||||
useColorStderr(true)
|
||||
# elif defined(FC_OS_LINUX) || defined(FC_OS_MACOSX) || defined(FC_OS_BSD)
|
||||
useColorStderr( isatty(STDERR_FILENO) )
|
||||
# else
|
||||
#elif defined(FC_OS_LINUX) || defined(FC_OS_MACOSX) || defined(FC_OS_BSD)
|
||||
useColorStderr(isatty(STDERR_FILENO))
|
||||
#else
|
||||
useColorStderr(false)
|
||||
# endif
|
||||
#endif
|
||||
{
|
||||
bLog = false;
|
||||
}
|
||||
|
||||
ConsoleObserverStd::~ConsoleObserverStd() = default;
|
||||
|
||||
void ConsoleObserverStd::SendLog(const std::string& notifiername, const std::string& msg, LogStyle level,
|
||||
IntendedRecipient recipient, ContentType content)
|
||||
void ConsoleObserverStd::SendLog(const std::string& notifiername,
|
||||
const std::string& msg,
|
||||
LogStyle level,
|
||||
IntendedRecipient recipient,
|
||||
ContentType content)
|
||||
{
|
||||
(void) notifiername;
|
||||
(void)notifiername;
|
||||
|
||||
// Do not log translated messages, or messages intended only to the user to std log
|
||||
if(recipient == IntendedRecipient::User || content == ContentType::Translated)
|
||||
if (recipient == IntendedRecipient::User || content == ContentType::Translated) {
|
||||
return;
|
||||
|
||||
switch(level){
|
||||
}
|
||||
|
||||
switch (level) {
|
||||
case LogStyle::Warning:
|
||||
this->Warning(msg.c_str());
|
||||
break;
|
||||
@@ -136,92 +146,100 @@ void ConsoleObserverStd::SendLog(const std::string& notifiername, const std::str
|
||||
}
|
||||
}
|
||||
|
||||
void ConsoleObserverStd::Message(const char *sMsg)
|
||||
void ConsoleObserverStd::Message(const char* sMsg)
|
||||
{
|
||||
printf("%s",sMsg);
|
||||
printf("%s", sMsg);
|
||||
}
|
||||
|
||||
void ConsoleObserverStd::Warning(const char *sWarn)
|
||||
void ConsoleObserverStd::Warning(const char* sWarn)
|
||||
{
|
||||
if (useColorStderr) {
|
||||
# if defined(FC_OS_WIN32)
|
||||
::SetConsoleTextAttribute(::GetStdHandle(STD_ERROR_HANDLE), FOREGROUND_GREEN| FOREGROUND_BLUE);
|
||||
# elif defined(FC_OS_LINUX) || defined(FC_OS_MACOSX) || defined(FC_OS_BSD)
|
||||
#if defined(FC_OS_WIN32)
|
||||
::SetConsoleTextAttribute(::GetStdHandle(STD_ERROR_HANDLE),
|
||||
FOREGROUND_GREEN | FOREGROUND_BLUE);
|
||||
#elif defined(FC_OS_LINUX) || defined(FC_OS_MACOSX) || defined(FC_OS_BSD)
|
||||
fprintf(stderr, "\033[1;33m");
|
||||
# endif
|
||||
#endif
|
||||
}
|
||||
|
||||
fprintf(stderr, "%s", sWarn);
|
||||
|
||||
if (useColorStderr) {
|
||||
# if defined(FC_OS_WIN32)
|
||||
::SetConsoleTextAttribute(::GetStdHandle(STD_ERROR_HANDLE),FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE );
|
||||
# elif defined(FC_OS_LINUX) || defined(FC_OS_MACOSX) || defined(FC_OS_BSD)
|
||||
#if defined(FC_OS_WIN32)
|
||||
::SetConsoleTextAttribute(::GetStdHandle(STD_ERROR_HANDLE),
|
||||
FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);
|
||||
#elif defined(FC_OS_LINUX) || defined(FC_OS_MACOSX) || defined(FC_OS_BSD)
|
||||
fprintf(stderr, "\033[0m");
|
||||
# endif
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void ConsoleObserverStd::Error (const char *sErr)
|
||||
void ConsoleObserverStd::Error(const char* sErr)
|
||||
{
|
||||
if (useColorStderr) {
|
||||
# if defined(FC_OS_WIN32)
|
||||
::SetConsoleTextAttribute(::GetStdHandle(STD_ERROR_HANDLE), FOREGROUND_RED|FOREGROUND_INTENSITY );
|
||||
# elif defined(FC_OS_LINUX) || defined(FC_OS_MACOSX) || defined(FC_OS_BSD)
|
||||
#if defined(FC_OS_WIN32)
|
||||
::SetConsoleTextAttribute(::GetStdHandle(STD_ERROR_HANDLE),
|
||||
FOREGROUND_RED | FOREGROUND_INTENSITY);
|
||||
#elif defined(FC_OS_LINUX) || defined(FC_OS_MACOSX) || defined(FC_OS_BSD)
|
||||
fprintf(stderr, "\033[1;31m");
|
||||
# endif
|
||||
#endif
|
||||
}
|
||||
|
||||
fprintf(stderr, "%s", sErr);
|
||||
|
||||
if (useColorStderr) {
|
||||
# if defined(FC_OS_WIN32)
|
||||
::SetConsoleTextAttribute(::GetStdHandle(STD_ERROR_HANDLE),FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE );
|
||||
# elif defined(FC_OS_LINUX) || defined(FC_OS_MACOSX) || defined(FC_OS_BSD)
|
||||
#if defined(FC_OS_WIN32)
|
||||
::SetConsoleTextAttribute(::GetStdHandle(STD_ERROR_HANDLE),
|
||||
FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);
|
||||
#elif defined(FC_OS_LINUX) || defined(FC_OS_MACOSX) || defined(FC_OS_BSD)
|
||||
fprintf(stderr, "\033[0m");
|
||||
# endif
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void ConsoleObserverStd::Log (const char *sErr)
|
||||
void ConsoleObserverStd::Log(const char* sErr)
|
||||
{
|
||||
if (useColorStderr) {
|
||||
# if defined(FC_OS_WIN32)
|
||||
::SetConsoleTextAttribute(::GetStdHandle(STD_ERROR_HANDLE), FOREGROUND_RED |FOREGROUND_GREEN);
|
||||
# elif defined(FC_OS_LINUX) || defined(FC_OS_MACOSX) || defined(FC_OS_BSD)
|
||||
#if defined(FC_OS_WIN32)
|
||||
::SetConsoleTextAttribute(::GetStdHandle(STD_ERROR_HANDLE),
|
||||
FOREGROUND_RED | FOREGROUND_GREEN);
|
||||
#elif defined(FC_OS_LINUX) || defined(FC_OS_MACOSX) || defined(FC_OS_BSD)
|
||||
fprintf(stderr, "\033[1;36m");
|
||||
# endif
|
||||
#endif
|
||||
}
|
||||
|
||||
fprintf(stderr, "%s", sErr);
|
||||
|
||||
if (useColorStderr) {
|
||||
# if defined(FC_OS_WIN32)
|
||||
::SetConsoleTextAttribute(::GetStdHandle(STD_ERROR_HANDLE),FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE );
|
||||
# elif defined(FC_OS_LINUX) || defined(FC_OS_MACOSX) || defined(FC_OS_BSD)
|
||||
#if defined(FC_OS_WIN32)
|
||||
::SetConsoleTextAttribute(::GetStdHandle(STD_ERROR_HANDLE),
|
||||
FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);
|
||||
#elif defined(FC_OS_LINUX) || defined(FC_OS_MACOSX) || defined(FC_OS_BSD)
|
||||
fprintf(stderr, "\033[0m");
|
||||
# endif
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void ConsoleObserverStd::Critical(const char *sCritical)
|
||||
void ConsoleObserverStd::Critical(const char* sCritical)
|
||||
{
|
||||
if (useColorStderr) {
|
||||
# if defined(FC_OS_WIN32)
|
||||
::SetConsoleTextAttribute(::GetStdHandle(STD_ERROR_HANDLE), FOREGROUND_GREEN | FOREGROUND_BLUE);
|
||||
# elif defined(FC_OS_LINUX) || defined(FC_OS_MACOSX) || defined(FC_OS_BSD)
|
||||
#if defined(FC_OS_WIN32)
|
||||
::SetConsoleTextAttribute(::GetStdHandle(STD_ERROR_HANDLE),
|
||||
FOREGROUND_GREEN | FOREGROUND_BLUE);
|
||||
#elif defined(FC_OS_LINUX) || defined(FC_OS_MACOSX) || defined(FC_OS_BSD)
|
||||
fprintf(stderr, "\033[1;33m");
|
||||
# endif
|
||||
#endif
|
||||
}
|
||||
|
||||
fprintf(stderr, "%s", sCritical);
|
||||
|
||||
if (useColorStderr) {
|
||||
# if defined(FC_OS_WIN32)
|
||||
::SetConsoleTextAttribute(::GetStdHandle(STD_ERROR_HANDLE),FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE );
|
||||
# elif defined(FC_OS_LINUX) || defined(FC_OS_MACOSX) || defined(FC_OS_BSD)
|
||||
#if defined(FC_OS_WIN32)
|
||||
::SetConsoleTextAttribute(::GetStdHandle(STD_ERROR_HANDLE),
|
||||
FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);
|
||||
#elif defined(FC_OS_LINUX) || defined(FC_OS_MACOSX) || defined(FC_OS_BSD)
|
||||
fprintf(stderr, "\033[0m");
|
||||
# endif
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@@ -232,8 +250,9 @@ RedirectStdOutput::RedirectStdOutput()
|
||||
|
||||
int RedirectStdOutput::overflow(int c)
|
||||
{
|
||||
if (c != EOF)
|
||||
if (c != EOF) {
|
||||
buffer.push_back(static_cast<char>(c));
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
@@ -254,8 +273,9 @@ RedirectStdLog::RedirectStdLog()
|
||||
|
||||
int RedirectStdLog::overflow(int c)
|
||||
{
|
||||
if (c != EOF)
|
||||
if (c != EOF) {
|
||||
buffer.push_back(static_cast<char>(c));
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
@@ -276,8 +296,9 @@ RedirectStdError::RedirectStdError()
|
||||
|
||||
int RedirectStdError::overflow(int c)
|
||||
{
|
||||
if (c != EOF)
|
||||
if (c != EOF) {
|
||||
buffer.push_back(static_cast<char>(c));
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
@@ -292,7 +313,7 @@ int RedirectStdError::sync()
|
||||
|
||||
//---------------------------------------------------------
|
||||
|
||||
std::stringstream &LogLevel::prefix(std::stringstream &str, const char *src, int line)
|
||||
std::stringstream& LogLevel::prefix(std::stringstream& str, const char* src, int line)
|
||||
{
|
||||
static FC_TIME_POINT s_tstart;
|
||||
static bool s_timing = false;
|
||||
@@ -302,11 +323,13 @@ std::stringstream &LogLevel::prefix(std::stringstream &str, const char *src, int
|
||||
_FC_TIME_INIT(s_tstart);
|
||||
}
|
||||
auto tnow = std::chrono::FC_TIME_CLOCK::now();
|
||||
auto d = std::chrono::duration_cast<FC_DURATION>(tnow-s_tstart);
|
||||
auto d = std::chrono::duration_cast<FC_DURATION>(tnow - s_tstart);
|
||||
str << d.count() << ' ';
|
||||
}
|
||||
if (print_tag) str << '<' << tag << "> ";
|
||||
if (print_src==2) {
|
||||
if (print_tag) {
|
||||
str << '<' << tag << "> ";
|
||||
}
|
||||
if (print_src == 2) {
|
||||
Base::PyGILStateLocker lock;
|
||||
PyFrameObject* frame = PyEval_GetFrame();
|
||||
if (frame) {
|
||||
@@ -322,11 +345,11 @@ std::stringstream &LogLevel::prefix(std::stringstream &str, const char *src, int
|
||||
}
|
||||
if (print_src && src && src[0]) {
|
||||
#ifdef FC_OS_WIN32
|
||||
const char *_f = std::strrchr(src, '\\');
|
||||
const char* _f = std::strrchr(src, '\\');
|
||||
#else
|
||||
const char *_f = std::strrchr(src, '/');
|
||||
const char* _f = std::strrchr(src, '/');
|
||||
#endif
|
||||
str << (_f?_f+1:src)<<"("<<line<<"): ";
|
||||
str << (_f ? _f + 1 : src) << "(" << line << "): ";
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
@@ -28,7 +28,8 @@
|
||||
#include <Base/Stream.h>
|
||||
|
||||
|
||||
namespace Base {
|
||||
namespace Base
|
||||
{
|
||||
|
||||
//=========================================================================
|
||||
// some special observers
|
||||
@@ -36,17 +37,28 @@ namespace Base {
|
||||
/** The LoggingConsoleObserver class
|
||||
* This class is used by the main modules to write Console messages and logs to a file
|
||||
*/
|
||||
class BaseExport ConsoleObserverFile : public ILogger
|
||||
class BaseExport ConsoleObserverFile: public ILogger
|
||||
{
|
||||
public:
|
||||
explicit ConsoleObserverFile(const char *sFileName);
|
||||
explicit ConsoleObserverFile(const char* sFileName);
|
||||
~ConsoleObserverFile() override;
|
||||
|
||||
void SendLog(const std::string& notifiername, const std::string& msg, LogStyle level,
|
||||
IntendedRecipient recipient, ContentType content) override;
|
||||
const char* Name() override {return "File";}
|
||||
void SendLog(const std::string& notifiername,
|
||||
const std::string& msg,
|
||||
LogStyle level,
|
||||
IntendedRecipient recipient,
|
||||
ContentType content) override;
|
||||
const char* Name() override
|
||||
{
|
||||
return "File";
|
||||
}
|
||||
|
||||
protected:
|
||||
ConsoleObserverFile(const ConsoleObserverFile&) = delete;
|
||||
ConsoleObserverFile(ConsoleObserverFile&&) = delete;
|
||||
ConsoleObserverFile& operator=(const ConsoleObserverFile&) = delete;
|
||||
ConsoleObserverFile& operator=(ConsoleObserverFile&&) = delete;
|
||||
|
||||
private:
|
||||
Base::ofstream cFileStream;
|
||||
};
|
||||
|
||||
@@ -58,17 +70,28 @@ class BaseExport ConsoleObserverStd: public ILogger
|
||||
public:
|
||||
ConsoleObserverStd();
|
||||
~ConsoleObserverStd() override;
|
||||
void SendLog(const std::string& notifiername, const std::string& msg, LogStyle level,
|
||||
IntendedRecipient recipient, ContentType content) override;
|
||||
const char* Name() override {return "Console";}
|
||||
protected:
|
||||
bool useColorStderr;
|
||||
void SendLog(const std::string& notifiername,
|
||||
const std::string& msg,
|
||||
LogStyle level,
|
||||
IntendedRecipient recipient,
|
||||
ContentType content) override;
|
||||
const char* Name() override
|
||||
{
|
||||
return "Console";
|
||||
}
|
||||
|
||||
ConsoleObserverStd(const ConsoleObserverStd&) = delete;
|
||||
ConsoleObserverStd(ConsoleObserverStd&&) = delete;
|
||||
ConsoleObserverStd& operator=(const ConsoleObserverStd&) = delete;
|
||||
ConsoleObserverStd& operator=(ConsoleObserverStd&&) = delete;
|
||||
|
||||
private:
|
||||
void Warning (const char *sWarn);
|
||||
void Message (const char *sMsg);
|
||||
void Error (const char *sErr);
|
||||
void Log (const char *sLog);
|
||||
void Critical(const char *sCritical);
|
||||
bool useColorStderr;
|
||||
void Warning(const char* sWarn);
|
||||
void Message(const char* sMsg);
|
||||
void Error(const char* sErr);
|
||||
void Log(const char* sLog);
|
||||
void Critical(const char* sCritical);
|
||||
};
|
||||
|
||||
/** The ILoggerBlocker class
|
||||
@@ -78,24 +101,31 @@ private:
|
||||
class BaseExport ILoggerBlocker
|
||||
{
|
||||
public:
|
||||
// Constructor that will block message types passed as parameter. By default, all types are blocked.
|
||||
inline explicit ILoggerBlocker(const char* co, ConsoleMsgFlags msgTypes =
|
||||
ConsoleSingleton::MsgType_Txt | ConsoleSingleton::MsgType_Log | ConsoleSingleton::MsgType_Wrn | ConsoleSingleton::MsgType_Err |
|
||||
ConsoleSingleton::MsgType_Critical | ConsoleSingleton::MsgType_Notification);
|
||||
// Constructor that will block message types passed as parameter. By default, all types are
|
||||
// blocked.
|
||||
inline explicit ILoggerBlocker(const char* co,
|
||||
ConsoleMsgFlags msgTypes = ConsoleSingleton::MsgType_Txt
|
||||
| ConsoleSingleton::MsgType_Log
|
||||
| ConsoleSingleton::MsgType_Wrn
|
||||
| ConsoleSingleton::MsgType_Err
|
||||
| ConsoleSingleton::MsgType_Critical
|
||||
| ConsoleSingleton::MsgType_Notification);
|
||||
// Disable copy & move constructors
|
||||
ILoggerBlocker(ILoggerBlocker const&) = delete;
|
||||
ILoggerBlocker(ILoggerBlocker const &&) = delete;
|
||||
ILoggerBlocker(ILoggerBlocker const&&) = delete;
|
||||
// Disable assignment & move-assignment operator
|
||||
ILoggerBlocker& operator=(ILoggerBlocker const&) = delete;
|
||||
ILoggerBlocker& operator=(ILoggerBlocker const&&) = delete;
|
||||
// Destructor that will restore message type settings.
|
||||
inline ~ILoggerBlocker();
|
||||
|
||||
private:
|
||||
ConsoleMsgFlags msgTypesBlocked = 0; // Stores message types blocked by the blocker
|
||||
const char* conObs; // Stores console observer name that blocker acts on
|
||||
ConsoleMsgFlags msgTypesBlocked = 0; // Stores message types blocked by the blocker
|
||||
const char* conObs; // Stores console observer name that blocker acts on
|
||||
};
|
||||
|
||||
ILoggerBlocker::ILoggerBlocker(const char* co, ConsoleMsgFlags msgTypes) : conObs(co)
|
||||
ILoggerBlocker::ILoggerBlocker(const char* co, ConsoleMsgFlags msgTypes)
|
||||
: conObs(co)
|
||||
{
|
||||
msgTypesBlocked = Console().SetEnabledMsgType(conObs, msgTypes, false);
|
||||
}
|
||||
@@ -104,14 +134,15 @@ ILoggerBlocker::~ILoggerBlocker()
|
||||
{
|
||||
#ifdef FC_DEBUG
|
||||
auto debug = Console().SetEnabledMsgType(conObs, msgTypesBlocked, true);
|
||||
if (debug != msgTypesBlocked)
|
||||
if (debug != msgTypesBlocked) {
|
||||
Console().Warning("Enabled message types have been changed while ILoggerBlocker was set\n");
|
||||
}
|
||||
#else
|
||||
Console().SetEnabledMsgType(conObs, msgTypesBlocked, true);
|
||||
#endif
|
||||
}
|
||||
|
||||
class BaseExport RedirectStdOutput : public std::streambuf
|
||||
class BaseExport RedirectStdOutput: public std::streambuf
|
||||
{
|
||||
public:
|
||||
RedirectStdOutput();
|
||||
@@ -124,7 +155,7 @@ private:
|
||||
std::string buffer;
|
||||
};
|
||||
|
||||
class BaseExport RedirectStdError : public std::streambuf
|
||||
class BaseExport RedirectStdError: public std::streambuf
|
||||
{
|
||||
public:
|
||||
RedirectStdError();
|
||||
@@ -137,7 +168,7 @@ private:
|
||||
std::string buffer;
|
||||
};
|
||||
|
||||
class BaseExport RedirectStdLog : public std::streambuf
|
||||
class BaseExport RedirectStdLog: public std::streambuf
|
||||
{
|
||||
public:
|
||||
RedirectStdLog();
|
||||
@@ -151,6 +182,6 @@ private:
|
||||
};
|
||||
|
||||
|
||||
} // namespace Base
|
||||
} // namespace Base
|
||||
|
||||
#endif // BASE_CONSOLEOBSERVER_H
|
||||
#endif // BASE_CONSOLEOBSERVER_H
|
||||
|
||||
@@ -29,52 +29,71 @@
|
||||
#include "Vector3D.h"
|
||||
|
||||
|
||||
namespace Base {
|
||||
namespace Base
|
||||
{
|
||||
|
||||
template <class vecT>
|
||||
struct vec_traits { };
|
||||
template<class vecT>
|
||||
struct vec_traits
|
||||
{
|
||||
};
|
||||
|
||||
template <>
|
||||
struct vec_traits<Vector3f> {
|
||||
template<>
|
||||
struct vec_traits<Vector3f>
|
||||
{
|
||||
using vec_type = Vector3f;
|
||||
using float_type = float;
|
||||
vec_traits(const vec_type& v) : v(v){}
|
||||
inline std::tuple<float_type,float_type,float_type> get() const {
|
||||
vec_traits(const vec_type& v)
|
||||
: v(v)
|
||||
{}
|
||||
inline std::tuple<float_type, float_type, float_type> get() const
|
||||
{
|
||||
return std::make_tuple(v.x, v.y, v.z);
|
||||
}
|
||||
|
||||
private:
|
||||
const vec_type& v;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct vec_traits<Vector3d> {
|
||||
template<>
|
||||
struct vec_traits<Vector3d>
|
||||
{
|
||||
using vec_type = Vector3d;
|
||||
using float_type = double;
|
||||
vec_traits(const vec_type& v) : v(v){}
|
||||
inline std::tuple<float_type,float_type,float_type> get() const {
|
||||
vec_traits(const vec_type& v)
|
||||
: v(v)
|
||||
{}
|
||||
inline std::tuple<float_type, float_type, float_type> get() const
|
||||
{
|
||||
return std::make_tuple(v.x, v.y, v.z);
|
||||
}
|
||||
|
||||
private:
|
||||
const vec_type& v;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct vec_traits<Rotation> {
|
||||
template<>
|
||||
struct vec_traits<Rotation>
|
||||
{
|
||||
using vec_type = Rotation;
|
||||
using float_type = double;
|
||||
vec_traits(const vec_type& v) : v(v){}
|
||||
inline std::tuple<float_type,float_type,float_type,float_type> get() const {
|
||||
float_type q1{},q2{},q3{},q4{};
|
||||
v.getValue(q1,q2,q3,q4);
|
||||
vec_traits(const vec_type& v)
|
||||
: v(v)
|
||||
{}
|
||||
inline std::tuple<float_type, float_type, float_type, float_type> get() const
|
||||
{
|
||||
float_type q1 {}, q2 {}, q3 {}, q4 {};
|
||||
v.getValue(q1, q2, q3, q4);
|
||||
return std::make_tuple(q1, q2, q3, q4);
|
||||
}
|
||||
|
||||
private:
|
||||
const vec_type& v;
|
||||
};
|
||||
|
||||
// type with three floats
|
||||
template <class _Vec, typename float_type>
|
||||
_Vec make_vec(const std::tuple<float_type, float_type, float_type>&& t) {
|
||||
template<class _Vec, typename float_type>
|
||||
_Vec make_vec(const std::tuple<float_type, float_type, float_type>&& t)
|
||||
{
|
||||
using traits_type = vec_traits<_Vec>;
|
||||
using float_traits_type = typename traits_type::float_type;
|
||||
return _Vec(float_traits_type(std::get<0>(t)),
|
||||
@@ -83,8 +102,9 @@ _Vec make_vec(const std::tuple<float_type, float_type, float_type>&& t) {
|
||||
}
|
||||
|
||||
// type with four floats
|
||||
template <class _Vec, typename float_type>
|
||||
_Vec make_vec(const std::tuple<float_type, float_type, float_type, float_type>&& t) {
|
||||
template<class _Vec, typename float_type>
|
||||
_Vec make_vec(const std::tuple<float_type, float_type, float_type, float_type>&& t)
|
||||
{
|
||||
using traits_type = vec_traits<_Vec>;
|
||||
using float_traits_type = typename traits_type::float_type;
|
||||
return _Vec(float_traits_type(std::get<0>(t)),
|
||||
@@ -93,7 +113,7 @@ _Vec make_vec(const std::tuple<float_type, float_type, float_type, float_type>&&
|
||||
float_traits_type(std::get<3>(t)));
|
||||
}
|
||||
|
||||
template <class _Vec1, class _Vec2>
|
||||
template<class _Vec1, class _Vec2>
|
||||
inline _Vec1 convertTo(const _Vec2& v)
|
||||
{
|
||||
using traits_type = vec_traits<_Vec2>;
|
||||
@@ -103,6 +123,6 @@ inline _Vec1 convertTo(const _Vec2& v)
|
||||
return make_vec<_Vec1, float_type>(std::move(tuple));
|
||||
}
|
||||
|
||||
}
|
||||
} // namespace Base
|
||||
|
||||
#endif // BASE_CONVERTER_H
|
||||
#endif // BASE_CONVERTER_H
|
||||
|
||||
@@ -31,19 +31,22 @@
|
||||
using namespace Base;
|
||||
|
||||
CoordinateSystem::CoordinateSystem()
|
||||
: axis(Vector3d(), Vector3d(0,0,1)), xdir(1,0,0), ydir(0,1,0)
|
||||
{
|
||||
}
|
||||
: axis(Vector3d(), Vector3d(0, 0, 1))
|
||||
, xdir(1, 0, 0)
|
||||
, ydir(0, 1, 0)
|
||||
{}
|
||||
|
||||
CoordinateSystem::~CoordinateSystem() = default;
|
||||
|
||||
void CoordinateSystem::setAxes(const Axis& v, const Vector3d& xd)
|
||||
{
|
||||
if (xd.Sqr() < Base::Vector3d::epsilon())
|
||||
if (xd.Sqr() < Base::Vector3d::epsilon()) {
|
||||
throw Base::ValueError("Direction is null vector");
|
||||
}
|
||||
Vector3d yd = v.getDirection() % xd;
|
||||
if (yd.Sqr() < Base::Vector3d::epsilon())
|
||||
if (yd.Sqr() < Base::Vector3d::epsilon()) {
|
||||
throw Base::ValueError("Direction is parallel to Z direction");
|
||||
}
|
||||
ydir = yd;
|
||||
ydir.Normalize();
|
||||
xdir = ydir % v.getDirection();
|
||||
@@ -56,11 +59,13 @@ void CoordinateSystem::setAxes(const Axis& v, const Vector3d& xd)
|
||||
|
||||
void CoordinateSystem::setAxes(const Vector3d& n, const Vector3d& xd)
|
||||
{
|
||||
if (xd.Sqr() < Base::Vector3d::epsilon())
|
||||
if (xd.Sqr() < Base::Vector3d::epsilon()) {
|
||||
throw Base::ValueError("Direction is null vector");
|
||||
}
|
||||
Vector3d yd = n % xd;
|
||||
if (yd.Sqr() < Base::Vector3d::epsilon())
|
||||
if (yd.Sqr() < Base::Vector3d::epsilon()) {
|
||||
throw Base::ValueError("Direction is parallel to Z direction");
|
||||
}
|
||||
ydir = yd;
|
||||
ydir.Normalize();
|
||||
xdir = ydir % n;
|
||||
@@ -78,8 +83,9 @@ void CoordinateSystem::setAxis(const Axis& v)
|
||||
void CoordinateSystem::setXDirection(const Vector3d& dir)
|
||||
{
|
||||
Vector3d yd = axis.getDirection() % dir;
|
||||
if (yd.Sqr() < Base::Vector3d::epsilon())
|
||||
if (yd.Sqr() < Base::Vector3d::epsilon()) {
|
||||
throw Base::ValueError("Direction is parallel to Z direction");
|
||||
}
|
||||
ydir = yd;
|
||||
ydir.Normalize();
|
||||
xdir = ydir % axis.getDirection();
|
||||
@@ -89,8 +95,9 @@ void CoordinateSystem::setXDirection(const Vector3d& dir)
|
||||
void CoordinateSystem::setYDirection(const Vector3d& dir)
|
||||
{
|
||||
Vector3d xd = dir % axis.getDirection();
|
||||
if (xd.Sqr() < Base::Vector3d::epsilon())
|
||||
if (xd.Sqr() < Base::Vector3d::epsilon()) {
|
||||
throw Base::ValueError("Direction is parallel to Z direction");
|
||||
}
|
||||
xdir = xd;
|
||||
xdir.Normalize();
|
||||
ydir = axis.getDirection() % xdir;
|
||||
@@ -107,18 +114,35 @@ Placement CoordinateSystem::displacement(const CoordinateSystem& cs) const
|
||||
const Base::Vector3d& a = axis.getBase();
|
||||
const Base::Vector3d& zdir = axis.getDirection();
|
||||
Base::Matrix4D At;
|
||||
At[0][0] = xdir.x; At[1][0] = ydir.x; At[2][0] = zdir.x;
|
||||
At[0][1] = xdir.y; At[1][1] = ydir.y; At[2][1] = zdir.y;
|
||||
At[0][2] = xdir.z; At[1][2] = ydir.z; At[2][2] = zdir.z;
|
||||
At[0][0] = xdir.x;
|
||||
At[1][0] = ydir.x;
|
||||
At[2][0] = zdir.x;
|
||||
At[0][1] = xdir.y;
|
||||
At[1][1] = ydir.y;
|
||||
At[2][1] = zdir.y;
|
||||
At[0][2] = xdir.z;
|
||||
At[1][2] = ydir.z;
|
||||
At[2][2] = zdir.z;
|
||||
Base::Vector3d at = At * a;
|
||||
At[0][3] = -at.x; At[1][3] = -at.y; At[2][3] = -at.z;
|
||||
At[0][3] = -at.x;
|
||||
At[1][3] = -at.y;
|
||||
At[2][3] = -at.z;
|
||||
|
||||
const Base::Vector3d& b = cs.axis.getBase();
|
||||
const Base::Vector3d& cszdir = cs.axis.getDirection();
|
||||
Base::Matrix4D B;
|
||||
B[0][0] = cs.xdir.x; B[0][1] = cs.ydir.x; B[0][2] = cszdir.x; B[0][3] = b.x;
|
||||
B[1][0] = cs.xdir.y; B[1][1] = cs.ydir.y; B[1][2] = cszdir.y; B[1][3] = b.y;
|
||||
B[2][0] = cs.xdir.z; B[2][1] = cs.ydir.z; B[2][2] = cszdir.z; B[2][3] = b.z;
|
||||
B[0][0] = cs.xdir.x;
|
||||
B[0][1] = cs.ydir.x;
|
||||
B[0][2] = cszdir.x;
|
||||
B[0][3] = b.x;
|
||||
B[1][0] = cs.xdir.y;
|
||||
B[1][1] = cs.ydir.y;
|
||||
B[1][2] = cszdir.y;
|
||||
B[1][3] = b.y;
|
||||
B[2][0] = cs.xdir.z;
|
||||
B[2][1] = cs.ydir.z;
|
||||
B[2][2] = cszdir.z;
|
||||
B[2][3] = b.z;
|
||||
|
||||
Placement PAt(At);
|
||||
Placement PB(B);
|
||||
@@ -149,11 +173,11 @@ void CoordinateSystem::transform(const Rotation& r)
|
||||
|
||||
void CoordinateSystem::setPlacement(const Placement& p)
|
||||
{
|
||||
Vector3d zdir(0,0,1);
|
||||
Vector3d zdir(0, 0, 1);
|
||||
p.getRotation().multVec(zdir, zdir);
|
||||
axis.setBase(p.getPosition());
|
||||
axis.setDirection(zdir);
|
||||
|
||||
p.getRotation().multVec(Vector3d(1,0,0), this->xdir);
|
||||
p.getRotation().multVec(Vector3d(0,1,0), this->ydir);
|
||||
p.getRotation().multVec(Vector3d(1, 0, 0), this->xdir);
|
||||
p.getRotation().multVec(Vector3d(0, 1, 0), this->ydir);
|
||||
}
|
||||
|
||||
@@ -26,7 +26,8 @@
|
||||
|
||||
#include "Axis.h"
|
||||
|
||||
namespace Base {
|
||||
namespace Base
|
||||
{
|
||||
/**
|
||||
* Describes a right-handed coordinate system in 3D space.
|
||||
\author Werner Mayer
|
||||
@@ -38,8 +39,13 @@ public:
|
||||
* with X axis (1,0,0), with Y axis (0,1,0) and Z axis (0,0,1)
|
||||
*/
|
||||
CoordinateSystem();
|
||||
CoordinateSystem(const CoordinateSystem&) = default;
|
||||
CoordinateSystem(CoordinateSystem&&) = default;
|
||||
~CoordinateSystem();
|
||||
|
||||
CoordinateSystem& operator=(const CoordinateSystem&) = default;
|
||||
CoordinateSystem& operator=(CoordinateSystem&&) = default;
|
||||
|
||||
/** Sets the main axis. X and Y dir are adjusted accordingly.
|
||||
* The main axis \a v must not be parallel to the X axis
|
||||
*/
|
||||
@@ -53,28 +59,40 @@ public:
|
||||
*/
|
||||
void setAxes(const Vector3d& n, const Vector3d& xd);
|
||||
inline const Axis& getAxis() const
|
||||
{ return axis; }
|
||||
{
|
||||
return axis;
|
||||
}
|
||||
|
||||
/** The passed vector must not be parallel to the main axis */
|
||||
void setXDirection(const Vector3d&);
|
||||
inline const Vector3d& getXDirection() const
|
||||
{ return xdir; }
|
||||
{
|
||||
return xdir;
|
||||
}
|
||||
|
||||
/** The passed vector must not be parallel to the main axis */
|
||||
void setYDirection(const Vector3d&);
|
||||
inline const Vector3d& getYDirection() const
|
||||
{ return ydir; }
|
||||
{
|
||||
return ydir;
|
||||
}
|
||||
|
||||
/** Sets the main axis. X and Y dir are adjusted accordingly.
|
||||
* The main axis must not be parallel to the X axis
|
||||
*/
|
||||
void setZDirection(const Vector3d&);
|
||||
inline const Vector3d& getZDirection() const
|
||||
{ return axis.getDirection(); }
|
||||
{
|
||||
return axis.getDirection();
|
||||
}
|
||||
inline void setPosition(const Vector3d& p)
|
||||
{ axis.setBase(p); }
|
||||
{
|
||||
axis.setBase(p);
|
||||
}
|
||||
inline const Vector3d& getPosition() const
|
||||
{ return axis.getBase(); }
|
||||
{
|
||||
return axis.getBase();
|
||||
}
|
||||
|
||||
/** This computes the displacement from this coordinate system to the
|
||||
* given coordinate system \a cs
|
||||
@@ -99,6 +117,6 @@ private:
|
||||
Vector3d ydir;
|
||||
};
|
||||
|
||||
}
|
||||
} // namespace Base
|
||||
|
||||
#endif // BASE_COORDINATESYSTEM_H
|
||||
#endif // BASE_COORDINATESYSTEM_H
|
||||
|
||||
@@ -38,7 +38,7 @@ std::string CoordinateSystemPy::representation() const
|
||||
return {"<CoordinateSystem object>"};
|
||||
}
|
||||
|
||||
PyObject *CoordinateSystemPy::PyMake(struct _typeobject *, PyObject *, PyObject *) // Python wrapper
|
||||
PyObject* CoordinateSystemPy::PyMake(struct _typeobject*, PyObject*, PyObject*) // Python wrapper
|
||||
{
|
||||
// create a new instance of CoordinateSystemPy and the Twin object
|
||||
return new CoordinateSystemPy(new CoordinateSystem);
|
||||
@@ -50,9 +50,9 @@ int CoordinateSystemPy::PyInit(PyObject* /*args*/, PyObject* /*kwd*/)
|
||||
return 0;
|
||||
}
|
||||
|
||||
PyObject* CoordinateSystemPy::setAxes(PyObject * args)
|
||||
PyObject* CoordinateSystemPy::setAxes(PyObject* args)
|
||||
{
|
||||
PyObject *axis{}, *xdir{};
|
||||
PyObject *axis {}, *xdir {};
|
||||
if (PyArg_ParseTuple(args, "O!O!", &(AxisPy::Type), &axis, &(VectorPy::Type), &xdir)) {
|
||||
getCoordinateSystemPtr()->setAxes(*static_cast<AxisPy*>(axis)->getAxisPtr(),
|
||||
*static_cast<VectorPy*>(xdir)->getVectorPtr());
|
||||
@@ -70,29 +70,31 @@ PyObject* CoordinateSystemPy::setAxes(PyObject * args)
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
PyObject* CoordinateSystemPy::displacement(PyObject * args)
|
||||
PyObject* CoordinateSystemPy::displacement(PyObject* args)
|
||||
{
|
||||
PyObject *cs{};
|
||||
if (!PyArg_ParseTuple(args, "O!", &(CoordinateSystemPy::Type), &cs))
|
||||
PyObject* cs {};
|
||||
if (!PyArg_ParseTuple(args, "O!", &(CoordinateSystemPy::Type), &cs)) {
|
||||
return nullptr;
|
||||
}
|
||||
Placement p = getCoordinateSystemPtr()->displacement(
|
||||
*static_cast<CoordinateSystemPy*>(cs)->getCoordinateSystemPtr());
|
||||
return new PlacementPy(new Placement(p));
|
||||
}
|
||||
|
||||
PyObject* CoordinateSystemPy::transformTo(PyObject * args)
|
||||
PyObject* CoordinateSystemPy::transformTo(PyObject* args)
|
||||
{
|
||||
PyObject *vec{};
|
||||
if (!PyArg_ParseTuple(args, "O!", &(VectorPy::Type), &vec))
|
||||
PyObject* vec {};
|
||||
if (!PyArg_ParseTuple(args, "O!", &(VectorPy::Type), &vec)) {
|
||||
return nullptr;
|
||||
}
|
||||
Vector3d v = static_cast<VectorPy*>(vec)->value();
|
||||
getCoordinateSystemPtr()->transformTo(v);
|
||||
return new VectorPy(new Vector3d(v));
|
||||
}
|
||||
|
||||
PyObject* CoordinateSystemPy::transform(PyObject * args)
|
||||
PyObject* CoordinateSystemPy::transform(PyObject* args)
|
||||
{
|
||||
PyObject *plm{};
|
||||
PyObject* plm {};
|
||||
if (PyArg_ParseTuple(args, "O!", &(PlacementPy::Type), &plm)) {
|
||||
getCoordinateSystemPtr()->transform(*static_cast<PlacementPy*>(plm)->getPlacementPtr());
|
||||
Py_Return;
|
||||
@@ -108,11 +110,12 @@ PyObject* CoordinateSystemPy::transform(PyObject * args)
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
PyObject* CoordinateSystemPy::setPlacement(PyObject * args)
|
||||
PyObject* CoordinateSystemPy::setPlacement(PyObject* args)
|
||||
{
|
||||
PyObject *plm{};
|
||||
if (!PyArg_ParseTuple(args, "O!", &(PlacementPy::Type), &plm))
|
||||
PyObject* plm {};
|
||||
if (!PyArg_ParseTuple(args, "O!", &(PlacementPy::Type), &plm)) {
|
||||
return nullptr;
|
||||
}
|
||||
getCoordinateSystemPtr()->setPlacement(*static_cast<PlacementPy*>(plm)->getPlacementPtr());
|
||||
Py_Return;
|
||||
}
|
||||
@@ -126,7 +129,7 @@ Py::Object CoordinateSystemPy::getAxis() const
|
||||
void CoordinateSystemPy::setAxis(Py::Object arg)
|
||||
{
|
||||
if (PyObject_TypeCheck(arg.ptr(), &(Base::AxisPy::Type))) {
|
||||
AxisPy *axis = static_cast<AxisPy*>(arg.ptr());
|
||||
AxisPy* axis = static_cast<AxisPy*>(arg.ptr());
|
||||
getCoordinateSystemPtr()->setAxis(*axis->getAxisPtr());
|
||||
return;
|
||||
}
|
||||
@@ -136,7 +139,7 @@ void CoordinateSystemPy::setAxis(Py::Object arg)
|
||||
|
||||
Py::Object CoordinateSystemPy::getXDirection() const
|
||||
{
|
||||
return Py::Vector(getCoordinateSystemPtr()->getXDirection()); // NOLINT
|
||||
return Py::Vector(getCoordinateSystemPtr()->getXDirection()); // NOLINT
|
||||
}
|
||||
|
||||
void CoordinateSystemPy::setXDirection(Py::Object arg)
|
||||
@@ -146,7 +149,7 @@ void CoordinateSystemPy::setXDirection(Py::Object arg)
|
||||
|
||||
Py::Object CoordinateSystemPy::getYDirection() const
|
||||
{
|
||||
return Py::Vector(getCoordinateSystemPtr()->getYDirection()); // NOLINT
|
||||
return Py::Vector(getCoordinateSystemPtr()->getYDirection()); // NOLINT
|
||||
}
|
||||
|
||||
void CoordinateSystemPy::setYDirection(Py::Object arg)
|
||||
@@ -156,7 +159,7 @@ void CoordinateSystemPy::setYDirection(Py::Object arg)
|
||||
|
||||
Py::Object CoordinateSystemPy::getZDirection() const
|
||||
{
|
||||
return Py::Vector(getCoordinateSystemPtr()->getZDirection()); // NOLINT
|
||||
return Py::Vector(getCoordinateSystemPtr()->getZDirection()); // NOLINT
|
||||
}
|
||||
|
||||
void CoordinateSystemPy::setZDirection(Py::Object arg)
|
||||
@@ -166,7 +169,7 @@ void CoordinateSystemPy::setZDirection(Py::Object arg)
|
||||
|
||||
Py::Object CoordinateSystemPy::getPosition() const
|
||||
{
|
||||
return Py::Vector(getCoordinateSystemPtr()->getPosition()); // NOLINT
|
||||
return Py::Vector(getCoordinateSystemPtr()->getPosition()); // NOLINT
|
||||
}
|
||||
|
||||
void CoordinateSystemPy::setPosition(Py::Object arg)
|
||||
@@ -174,7 +177,7 @@ void CoordinateSystemPy::setPosition(Py::Object arg)
|
||||
getCoordinateSystemPtr()->setPosition(Py::Vector(arg).toVector());
|
||||
}
|
||||
|
||||
PyObject *CoordinateSystemPy::getCustomAttributes(const char* /*attr*/) const
|
||||
PyObject* CoordinateSystemPy::getCustomAttributes(const char* /*attr*/) const
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@@ -23,8 +23,8 @@
|
||||
|
||||
#include "PreCompiled.h"
|
||||
#ifndef _PreComp_
|
||||
# include <QCoreApplication>
|
||||
# include <QEvent>
|
||||
#include <QCoreApplication>
|
||||
#include <QEvent>
|
||||
#endif
|
||||
|
||||
#include "Debugger.h"
|
||||
@@ -34,9 +34,8 @@
|
||||
using namespace Base;
|
||||
|
||||
Debugger::Debugger(QObject* parent)
|
||||
: QObject(parent), isAttached(false)
|
||||
{
|
||||
}
|
||||
: QObject(parent)
|
||||
{}
|
||||
|
||||
Debugger::~Debugger() = default;
|
||||
|
||||
@@ -66,8 +65,9 @@ bool Debugger::eventFilter(QObject*, QEvent* event)
|
||||
|
||||
int Debugger::exec()
|
||||
{
|
||||
if (isAttached)
|
||||
if (isAttached) {
|
||||
Base::Console().Message("TO CONTINUE PRESS ANY KEY...\n");
|
||||
}
|
||||
return loop.exec();
|
||||
}
|
||||
|
||||
|
||||
@@ -30,7 +30,8 @@
|
||||
#include <FCGlobal.h>
|
||||
#endif
|
||||
|
||||
namespace Base {
|
||||
namespace Base
|
||||
{
|
||||
/**
|
||||
This is a utility class to break the application at a point to inspect e.g. the result of
|
||||
an algorithm.
|
||||
@@ -53,18 +54,18 @@ namespace Base {
|
||||
\endcode
|
||||
\author Werner Mayer
|
||||
*/
|
||||
class BaseExport Debugger : public QObject
|
||||
class BaseExport Debugger: public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
Debugger(QObject* parent=nullptr);
|
||||
Debugger(QObject* parent = nullptr);
|
||||
~Debugger() override;
|
||||
|
||||
Debugger(const Debugger&) = delete;
|
||||
Debugger(Debugger&&) = delete;
|
||||
Debugger& operator= (const Debugger&) = delete;
|
||||
Debugger& operator= (Debugger&&) = delete;
|
||||
Debugger& operator=(const Debugger&) = delete;
|
||||
Debugger& operator=(Debugger&&) = delete;
|
||||
|
||||
void attach();
|
||||
void detach();
|
||||
@@ -75,10 +76,10 @@ public Q_SLOTS:
|
||||
void quit();
|
||||
|
||||
private:
|
||||
bool isAttached;
|
||||
bool isAttached {false};
|
||||
QEventLoop loop;
|
||||
};
|
||||
|
||||
}
|
||||
} // namespace Base
|
||||
|
||||
#endif // BASE_DEBUGGER_H
|
||||
#endif // BASE_DEBUGGER_H
|
||||
|
||||
@@ -25,7 +25,8 @@
|
||||
|
||||
#include <cmath>
|
||||
|
||||
namespace Base {
|
||||
namespace Base
|
||||
{
|
||||
|
||||
|
||||
/**
|
||||
@@ -40,55 +41,72 @@ class DualNumber
|
||||
public:
|
||||
double re = 0.0;
|
||||
double du = 0.0;
|
||||
|
||||
public:
|
||||
DualNumber() = default;
|
||||
DualNumber(double re, double du = 0.0)
|
||||
: re(re), du(du)
|
||||
: re(re)
|
||||
, du(du)
|
||||
{}
|
||||
DualNumber operator-() const {return {-re,-du};}
|
||||
DualNumber operator-() const
|
||||
{
|
||||
return {-re, -du};
|
||||
}
|
||||
};
|
||||
|
||||
inline DualNumber operator+(DualNumber a, DualNumber b){
|
||||
inline DualNumber operator+(DualNumber a, DualNumber b)
|
||||
{
|
||||
return {a.re + b.re, a.du + b.du};
|
||||
}
|
||||
inline DualNumber operator+(DualNumber a, double b){
|
||||
inline DualNumber operator+(DualNumber a, double b)
|
||||
{
|
||||
return {a.re + b, a.du};
|
||||
}
|
||||
inline DualNumber operator+(double a, DualNumber b){
|
||||
inline DualNumber operator+(double a, DualNumber b)
|
||||
{
|
||||
return {a + b.re, b.du};
|
||||
}
|
||||
|
||||
inline DualNumber operator-(DualNumber a, DualNumber b){
|
||||
inline DualNumber operator-(DualNumber a, DualNumber b)
|
||||
{
|
||||
return {a.re - b.re, a.du - b.du};
|
||||
}
|
||||
inline DualNumber operator-(DualNumber a, double b){
|
||||
inline DualNumber operator-(DualNumber a, double b)
|
||||
{
|
||||
return {a.re - b, a.du};
|
||||
}
|
||||
inline DualNumber operator-(double a, DualNumber b){
|
||||
inline DualNumber operator-(double a, DualNumber b)
|
||||
{
|
||||
return {a - b.re, -b.du};
|
||||
}
|
||||
|
||||
inline DualNumber operator*(DualNumber a, DualNumber b){
|
||||
inline DualNumber operator*(DualNumber a, DualNumber b)
|
||||
{
|
||||
return {a.re * b.re, a.re * b.du + a.du * b.re};
|
||||
}
|
||||
inline DualNumber operator*(double a, DualNumber b){
|
||||
inline DualNumber operator*(double a, DualNumber b)
|
||||
{
|
||||
return {a * b.re, a * b.du};
|
||||
}
|
||||
inline DualNumber operator*(DualNumber a, double b){
|
||||
inline DualNumber operator*(DualNumber a, double b)
|
||||
{
|
||||
return {a.re * b, a.du * b};
|
||||
}
|
||||
|
||||
inline DualNumber operator/(DualNumber a, DualNumber b){
|
||||
inline DualNumber operator/(DualNumber a, DualNumber b)
|
||||
{
|
||||
return {a.re / b.re, (a.du * b.re - a.re * b.du) / (b.re * b.re)};
|
||||
}
|
||||
inline DualNumber operator/(DualNumber a, double b){
|
||||
inline DualNumber operator/(DualNumber a, double b)
|
||||
{
|
||||
return {a.re / b, a.du / b};
|
||||
}
|
||||
|
||||
inline DualNumber pow(DualNumber a, double pw){
|
||||
inline DualNumber pow(DualNumber a, double pw)
|
||||
{
|
||||
return {std::pow(a.re, pw), pw * std::pow(a.re, pw - 1.0) * a.du};
|
||||
}
|
||||
} //namespace
|
||||
} // namespace Base
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@@ -28,79 +28,47 @@
|
||||
|
||||
Base::DualQuat Base::operator+(Base::DualQuat a, Base::DualQuat b)
|
||||
{
|
||||
return {
|
||||
a.x + b.x,
|
||||
a.y + b.y,
|
||||
a.z + b.z,
|
||||
a.w + b.w
|
||||
};
|
||||
return {a.x + b.x, a.y + b.y, a.z + b.z, a.w + b.w};
|
||||
}
|
||||
|
||||
Base::DualQuat Base::operator-(Base::DualQuat a, Base::DualQuat b)
|
||||
{
|
||||
return {
|
||||
a.x - b.x,
|
||||
a.y - b.y,
|
||||
a.z - b.z,
|
||||
a.w - b.w
|
||||
};
|
||||
return {a.x - b.x, a.y - b.y, a.z - b.z, a.w - b.w};
|
||||
}
|
||||
|
||||
Base::DualQuat Base::operator*(Base::DualQuat a, Base::DualQuat b)
|
||||
{
|
||||
return {
|
||||
a.w * b.x + a.x * b.w + a.y * b.z - a.z * b.y,
|
||||
a.w * b.y + a.y * b.w + a.z * b.x - a.x * b.z,
|
||||
a.w * b.z + a.z * b.w + a.x * b.y - a.y * b.x,
|
||||
a.w * b.w - a.x * b.x - a.y * b.y - a.z * b.z
|
||||
};
|
||||
return {a.w * b.x + a.x * b.w + a.y * b.z - a.z * b.y,
|
||||
a.w * b.y + a.y * b.w + a.z * b.x - a.x * b.z,
|
||||
a.w * b.z + a.z * b.w + a.x * b.y - a.y * b.x,
|
||||
a.w * b.w - a.x * b.x - a.y * b.y - a.z * b.z};
|
||||
}
|
||||
|
||||
Base::DualQuat Base::operator*(Base::DualQuat a, double b)
|
||||
{
|
||||
return {
|
||||
a.x * b,
|
||||
a.y * b,
|
||||
a.z * b,
|
||||
a.w * b
|
||||
};
|
||||
return {a.x * b, a.y * b, a.z * b, a.w * b};
|
||||
}
|
||||
|
||||
Base::DualQuat Base::operator*(double a, Base::DualQuat b)
|
||||
{
|
||||
return {
|
||||
b.x * a,
|
||||
b.y * a,
|
||||
b.z * a,
|
||||
b.w * a
|
||||
};
|
||||
return {b.x * a, b.y * a, b.z * a, b.w * a};
|
||||
}
|
||||
|
||||
Base::DualQuat Base::operator*(Base::DualQuat a, Base::DualNumber b)
|
||||
{
|
||||
return {
|
||||
a.x * b,
|
||||
a.y * b,
|
||||
a.z * b,
|
||||
a.w * b
|
||||
};
|
||||
return {a.x * b, a.y * b, a.z * b, a.w * b};
|
||||
}
|
||||
|
||||
Base::DualQuat Base::operator*(Base::DualNumber a, Base::DualQuat b)
|
||||
{
|
||||
return {
|
||||
b.x * a,
|
||||
b.y * a,
|
||||
b.z * a,
|
||||
b.w * a
|
||||
};
|
||||
return {b.x * a, b.y * a, b.z * a, b.w * a};
|
||||
}
|
||||
|
||||
Base::DualQuat::DualQuat(Base::DualQuat re, Base::DualQuat du)
|
||||
: x(re.x.re, du.x.re),
|
||||
y(re.y.re, du.y.re),
|
||||
z(re.z.re, du.z.re),
|
||||
w(re.w.re, du.w.re)
|
||||
: x(re.x.re, du.x.re)
|
||||
, y(re.y.re, du.y.re)
|
||||
, z(re.z.re, du.z.re)
|
||||
, w(re.w.re, du.w.re)
|
||||
{
|
||||
assert(re.dual().length() < 1e-12);
|
||||
assert(du.dual().length() < 1e-12);
|
||||
@@ -108,10 +76,7 @@ Base::DualQuat::DualQuat(Base::DualQuat re, Base::DualQuat du)
|
||||
|
||||
double Base::DualQuat::dot(Base::DualQuat a, Base::DualQuat b)
|
||||
{
|
||||
return a.x.re * b.x.re +
|
||||
a.y.re * b.y.re +
|
||||
a.z.re * b.z.re +
|
||||
a.w.re * b.w.re ;
|
||||
return a.x.re * b.x.re + a.y.re * b.y.re + a.z.re * b.z.re + a.w.re * b.w.re;
|
||||
}
|
||||
|
||||
Base::DualQuat Base::DualQuat::pow(double t, bool shorten) const
|
||||
@@ -135,32 +100,34 @@ Base::DualQuat Base::DualQuat::pow(double t, bool shorten) const
|
||||
* */
|
||||
double le = this->vec().length();
|
||||
if (le < 1e-12) {
|
||||
//special case of no rotation. Interpolate position
|
||||
return {this->real(), this->dual()*t};
|
||||
// special case of no rotation. Interpolate position
|
||||
return {this->real(), this->dual() * t};
|
||||
}
|
||||
|
||||
double normmult = 1.0/le;
|
||||
double normmult = 1.0 / le;
|
||||
|
||||
DualQuat self = *this;
|
||||
if (shorten){
|
||||
if (dot(self, identity()) < -1e-12){ //using negative tolerance instead of zero, for stability in situations the choice is ambiguous (180-degree rotations)
|
||||
if (shorten) {
|
||||
if (dot(self, identity())
|
||||
< -1e-12) { // using negative tolerance instead of zero, for stability in situations
|
||||
// the choice is ambiguous (180-degree rotations)
|
||||
self = -self;
|
||||
}
|
||||
}
|
||||
|
||||
//to screw coordinates
|
||||
// to screw coordinates
|
||||
double theta = self.theta();
|
||||
double pitch = -2.0 * self.w.du * normmult;
|
||||
DualQuat l = self.real().vec() * normmult; //abusing DualQuat to store vectors. Very handy in this case.
|
||||
DualQuat m = (self.dual().vec() - pitch/2*cos(theta/2)*l)*normmult;
|
||||
DualQuat l = self.real().vec()
|
||||
* normmult; // abusing DualQuat to store vectors. Very handy in this case.
|
||||
DualQuat m = (self.dual().vec() - pitch / 2 * cos(theta / 2) * l) * normmult;
|
||||
|
||||
//interpolate
|
||||
// interpolate
|
||||
theta *= t;
|
||||
pitch *= t;
|
||||
|
||||
//back to quaternion
|
||||
return {
|
||||
l * sin(theta/2) + DualQuat(0,0,0,cos(theta/2)),
|
||||
m * sin(theta/2) + pitch / 2 * cos(theta/2) * l + DualQuat(0,0,0,-pitch/2*sin(theta/2))
|
||||
};
|
||||
// back to quaternion
|
||||
return {l * sin(theta / 2) + DualQuat(0, 0, 0, cos(theta / 2)),
|
||||
m * sin(theta / 2) + pitch / 2 * cos(theta / 2) * l
|
||||
+ DualQuat(0, 0, 0, -pitch / 2 * sin(theta / 2))};
|
||||
}
|
||||
|
||||
@@ -27,7 +27,8 @@
|
||||
#include <FCGlobal.h>
|
||||
|
||||
|
||||
namespace Base {
|
||||
namespace Base
|
||||
{
|
||||
|
||||
/**
|
||||
* @brief The DualQuat class represents a dual quaternion, as a quaternion of
|
||||
@@ -40,58 +41,98 @@ namespace Base {
|
||||
* where t is quaternion with x,y,z of translation and w of 0, and r is the
|
||||
* rotation quaternion.
|
||||
*/
|
||||
class BaseExport DualQuat {
|
||||
class BaseExport DualQuat
|
||||
{
|
||||
public:
|
||||
DualNumber x;
|
||||
DualNumber y;
|
||||
DualNumber z;
|
||||
DualNumber w;
|
||||
|
||||
public:
|
||||
///default constructor: init with zeros
|
||||
/// default constructor: init with zeros
|
||||
DualQuat() = default;
|
||||
DualQuat(DualNumber x, DualNumber y, DualNumber z, DualNumber w)
|
||||
: x(x), y(y), z(z), w(w) {}
|
||||
DualQuat(double x,double y,double z,double w,double dx,double dy,double dz,double dw)
|
||||
: x(x, dx), y(y, dy), z(z, dz), w(w, dw) {}
|
||||
DualQuat(double x,double y,double z,double w)
|
||||
: x(x), y(y), z(z), w(w) {}
|
||||
: x(x)
|
||||
, y(y)
|
||||
, z(z)
|
||||
, w(w)
|
||||
{}
|
||||
DualQuat(double x, double y, double z, double w, double dx, double dy, double dz, double dw)
|
||||
: x(x, dx)
|
||||
, y(y, dy)
|
||||
, z(z, dz)
|
||||
, w(w, dw)
|
||||
{}
|
||||
DualQuat(double x, double y, double z, double w)
|
||||
: x(x)
|
||||
, y(y)
|
||||
, z(z)
|
||||
, w(w)
|
||||
{}
|
||||
|
||||
///Builds a dual quaternion from real and dual parts provided as pure real quaternions
|
||||
/// Builds a dual quaternion from real and dual parts provided as pure real quaternions
|
||||
DualQuat(DualQuat re, DualQuat du);
|
||||
|
||||
///returns dual quaternion for identity placement
|
||||
static DualQuat identity() {return {0.0, 0.0, 0.0, 1.0};}
|
||||
/// returns dual quaternion for identity placement
|
||||
static DualQuat identity()
|
||||
{
|
||||
return {0.0, 0.0, 0.0, 1.0};
|
||||
}
|
||||
|
||||
///return a copy with dual part zeroed out
|
||||
DualQuat real() const {return {x.re, y.re, z.re, w.re};}
|
||||
/// return a copy with dual part zeroed out
|
||||
DualQuat real() const
|
||||
{
|
||||
return {x.re, y.re, z.re, w.re};
|
||||
}
|
||||
|
||||
///return a real-only quaternion made from dual part of this quaternion.
|
||||
DualQuat dual() const {return {x.du, y.du, z.du, w.du};}
|
||||
/// return a real-only quaternion made from dual part of this quaternion.
|
||||
DualQuat dual() const
|
||||
{
|
||||
return {x.du, y.du, z.du, w.du};
|
||||
}
|
||||
|
||||
///conjugate
|
||||
DualQuat conj() const {return {-x, -y, -z, w};}
|
||||
/// conjugate
|
||||
DualQuat conj() const
|
||||
{
|
||||
return {-x, -y, -z, w};
|
||||
}
|
||||
|
||||
///return vector part (with scalar part zeroed out)
|
||||
DualQuat vec() const {return {x,y,z,0.0};}
|
||||
/// return vector part (with scalar part zeroed out)
|
||||
DualQuat vec() const
|
||||
{
|
||||
return {x, y, z, 0.0};
|
||||
}
|
||||
|
||||
///magnitude of the quaternion
|
||||
double length() const {return sqrt(x.re*x.re + y.re*y.re + z.re*z.re + w.re*w.re);}
|
||||
/// magnitude of the quaternion
|
||||
double length() const
|
||||
{
|
||||
return sqrt(x.re * x.re + y.re * y.re + z.re * z.re + w.re * w.re);
|
||||
}
|
||||
|
||||
///angle of rotation represented by this quaternion, in radians
|
||||
double theta() const {return 2.0 * atan2(vec().length(), w.re);}
|
||||
/// angle of rotation represented by this quaternion, in radians
|
||||
double theta() const
|
||||
{
|
||||
return 2.0 * atan2(vec().length(), w.re);
|
||||
}
|
||||
|
||||
///dot product between real (rotation) parts of two dual quaternions (to determine if one of them should be negated for shortest interpolation)
|
||||
/// dot product between real (rotation) parts of two dual quaternions (to determine if one of
|
||||
/// them should be negated for shortest interpolation)
|
||||
static double dot(DualQuat a, DualQuat b);
|
||||
|
||||
///ScLERP. t=0.0 returns identity, t=1.0 returns this. t can also be outside of 0..1 bounds.
|
||||
/// ScLERP. t=0.0 returns identity, t=1.0 returns this. t can also be outside of 0..1 bounds.
|
||||
DualQuat pow(double t, bool shorten = true) const;
|
||||
|
||||
DualQuat operator-() const {return {-x, -y, -z, -w};}
|
||||
DualQuat operator-() const
|
||||
{
|
||||
return {-x, -y, -z, -w};
|
||||
}
|
||||
|
||||
//DEBUG
|
||||
//void print() const {
|
||||
// Console().Log("%f, %f, %f, %f; %f, %f, %f, %f", x.re,y.re,z.re,w.re, x.du,y.du,z.du, w.du);
|
||||
//}
|
||||
// DEBUG
|
||||
// void print() const {
|
||||
// Console().Log("%f, %f, %f, %f; %f, %f, %f, %f", x.re,y.re,z.re,w.re, x.du,y.du,z.du,
|
||||
// w.du);
|
||||
// }
|
||||
};
|
||||
|
||||
BaseExport DualQuat operator+(DualQuat a, DualQuat b);
|
||||
@@ -104,6 +145,6 @@ BaseExport DualQuat operator*(DualQuat a, DualNumber b);
|
||||
BaseExport DualQuat operator*(DualNumber a, DualQuat b);
|
||||
|
||||
|
||||
} //namespace
|
||||
} // namespace Base
|
||||
|
||||
#endif
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -28,23 +28,25 @@
|
||||
|
||||
using namespace Base;
|
||||
|
||||
ExceptionFactory* ExceptionFactory::_pcSingleton = nullptr;
|
||||
ExceptionFactory* ExceptionFactory::_pcSingleton = nullptr; // NOLINT
|
||||
|
||||
ExceptionFactory& ExceptionFactory::Instance()
|
||||
{
|
||||
if (!_pcSingleton)
|
||||
if (!_pcSingleton) {
|
||||
_pcSingleton = new ExceptionFactory;
|
||||
}
|
||||
return *_pcSingleton;
|
||||
}
|
||||
|
||||
void ExceptionFactory::Destruct ()
|
||||
void ExceptionFactory::Destruct()
|
||||
{
|
||||
if (_pcSingleton)
|
||||
if (_pcSingleton) {
|
||||
delete _pcSingleton;
|
||||
}
|
||||
_pcSingleton = nullptr;
|
||||
}
|
||||
|
||||
void ExceptionFactory::raiseException (PyObject * pydict) const
|
||||
void ExceptionFactory::raiseException(PyObject* pydict) const
|
||||
{
|
||||
std::string classname;
|
||||
|
||||
@@ -55,9 +57,8 @@ void ExceptionFactory::raiseException (PyObject * pydict) const
|
||||
std::map<const std::string, AbstractProducer*>::const_iterator pProd;
|
||||
|
||||
pProd = _mpcProducers.find(classname.c_str());
|
||||
if (pProd != _mpcProducers.end())
|
||||
static_cast<AbstractExceptionProducer *>(pProd->second)->raiseException(pydict);
|
||||
if (pProd != _mpcProducers.end()) {
|
||||
static_cast<AbstractExceptionProducer*>(pProd->second)->raiseException(pydict);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -35,48 +35,49 @@ namespace Base
|
||||
{
|
||||
|
||||
/// Abstract base class of all exception producers
|
||||
class BaseExport AbstractExceptionProducer : public AbstractProducer
|
||||
class BaseExport AbstractExceptionProducer: public AbstractProducer
|
||||
{
|
||||
public:
|
||||
AbstractExceptionProducer () = default;
|
||||
AbstractExceptionProducer() = default;
|
||||
// just implement it
|
||||
void* Produce () const override {
|
||||
void* Produce() const override
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
virtual void raiseException(PyObject * pydict) const = 0;
|
||||
virtual void raiseException(PyObject* pydict) const = 0;
|
||||
};
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
/** The ExceptionFactory */
|
||||
class BaseExport ExceptionFactory : public Factory
|
||||
class BaseExport ExceptionFactory: public Factory
|
||||
{
|
||||
public:
|
||||
static ExceptionFactory& Instance();
|
||||
static void Destruct ();
|
||||
static void Destruct();
|
||||
|
||||
void raiseException(PyObject * pydict) const;
|
||||
void raiseException(PyObject* pydict) const;
|
||||
|
||||
private:
|
||||
static ExceptionFactory* _pcSingleton;
|
||||
static ExceptionFactory* _pcSingleton; // NOLINT
|
||||
|
||||
ExceptionFactory() = default;
|
||||
};
|
||||
|
||||
/* Producers */
|
||||
|
||||
template <class CLASS>
|
||||
class ExceptionProducer : public AbstractExceptionProducer
|
||||
template<class CLASS>
|
||||
class ExceptionProducer: public AbstractExceptionProducer
|
||||
{
|
||||
public:
|
||||
ExceptionProducer ()
|
||||
ExceptionProducer()
|
||||
{
|
||||
ExceptionFactory::Instance().AddProducer(typeid(CLASS).name(), this);
|
||||
}
|
||||
|
||||
~ExceptionProducer () override = default;
|
||||
~ExceptionProducer() override = default;
|
||||
|
||||
void raiseException(PyObject * pydict) const override
|
||||
void raiseException(PyObject* pydict) const override
|
||||
{
|
||||
CLASS c;
|
||||
c.setPyObject(pydict);
|
||||
@@ -85,8 +86,7 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
} //namespace Base
|
||||
} // namespace Base
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
#include "PreCompiled.h"
|
||||
|
||||
#ifndef _PreComp_
|
||||
# include <list>
|
||||
#include <list>
|
||||
#endif
|
||||
|
||||
#include "Factory.h"
|
||||
@@ -35,76 +35,78 @@
|
||||
using namespace Base;
|
||||
|
||||
|
||||
Factory::~Factory ()
|
||||
Factory::~Factory()
|
||||
{
|
||||
for (auto & it : _mpcProducers)
|
||||
delete it.second;
|
||||
for (auto& it : _mpcProducers) {
|
||||
delete it.second;
|
||||
}
|
||||
}
|
||||
|
||||
void* Factory::Produce (const char *sClassName) const
|
||||
void* Factory::Produce(const char* sClassName) const
|
||||
{
|
||||
std::map<const std::string, AbstractProducer*>::const_iterator pProd;
|
||||
std::map<const std::string, AbstractProducer*>::const_iterator pProd;
|
||||
|
||||
pProd = _mpcProducers.find(sClassName);
|
||||
if (pProd != _mpcProducers.end())
|
||||
return pProd->second->Produce();
|
||||
else
|
||||
return nullptr;
|
||||
pProd = _mpcProducers.find(sClassName);
|
||||
if (pProd != _mpcProducers.end()) {
|
||||
return pProd->second->Produce();
|
||||
}
|
||||
else {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void Factory::AddProducer (const char *sClassName, AbstractProducer *pcProducer)
|
||||
void Factory::AddProducer(const char* sClassName, AbstractProducer* pcProducer)
|
||||
{
|
||||
_mpcProducers[sClassName] = pcProducer;
|
||||
_mpcProducers[sClassName] = pcProducer;
|
||||
}
|
||||
|
||||
bool Factory::CanProduce(const char* sClassName) const
|
||||
{
|
||||
return (_mpcProducers.find(sClassName) != _mpcProducers.end());
|
||||
return (_mpcProducers.find(sClassName) != _mpcProducers.end());
|
||||
}
|
||||
|
||||
std::list<std::string> Factory::CanProduce() const
|
||||
{
|
||||
std::list<std::string> lObjects;
|
||||
std::list<std::string> lObjects;
|
||||
|
||||
for (const auto & it : _mpcProducers)
|
||||
{
|
||||
lObjects.push_back(it.first);
|
||||
}
|
||||
for (const auto& it : _mpcProducers) {
|
||||
lObjects.push_back(it.first);
|
||||
}
|
||||
|
||||
return lObjects;
|
||||
return lObjects;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------
|
||||
|
||||
ScriptFactorySingleton* ScriptFactorySingleton::_pcSingleton = nullptr;
|
||||
|
||||
ScriptFactorySingleton* ScriptFactorySingleton::_pcSingleton = nullptr; // NOLINT
|
||||
|
||||
|
||||
ScriptFactorySingleton& ScriptFactorySingleton::Instance()
|
||||
{
|
||||
if (!_pcSingleton)
|
||||
_pcSingleton = new ScriptFactorySingleton;
|
||||
return *_pcSingleton;
|
||||
if (!_pcSingleton) {
|
||||
_pcSingleton = new ScriptFactorySingleton;
|
||||
}
|
||||
return *_pcSingleton;
|
||||
}
|
||||
|
||||
void ScriptFactorySingleton::Destruct ()
|
||||
void ScriptFactorySingleton::Destruct()
|
||||
{
|
||||
if (_pcSingleton)
|
||||
delete _pcSingleton;
|
||||
_pcSingleton = nullptr;
|
||||
if (_pcSingleton) {
|
||||
delete _pcSingleton;
|
||||
}
|
||||
_pcSingleton = nullptr;
|
||||
}
|
||||
|
||||
const char* ScriptFactorySingleton::ProduceScript (const char* sScriptName) const
|
||||
const char* ScriptFactorySingleton::ProduceScript(const char* sScriptName) const
|
||||
{
|
||||
const char* script = static_cast<const char*>(Produce(sScriptName));
|
||||
const char* script = static_cast<const char*>(Produce(sScriptName));
|
||||
|
||||
if ( !script )
|
||||
{
|
||||
if (!script) {
|
||||
#ifdef FC_DEBUG
|
||||
Console().Warning("\"%s\" is not registered\n", sScriptName);
|
||||
Console().Warning("\"%s\" is not registered\n", sScriptName);
|
||||
#endif
|
||||
return ""; // no data
|
||||
}
|
||||
return ""; // no data
|
||||
}
|
||||
|
||||
return script;
|
||||
return script;
|
||||
}
|
||||
|
||||
@@ -43,22 +43,21 @@ public:
|
||||
AbstractProducer() = default;
|
||||
virtual ~AbstractProducer() = default;
|
||||
/// overwritten by a concrete producer to produce the needed object
|
||||
virtual void* Produce () const = 0;
|
||||
virtual void* Produce() const = 0;
|
||||
};
|
||||
|
||||
|
||||
|
||||
/** Base class of all factories
|
||||
* This class has the purpose to produce instances of classes at runtime
|
||||
* that are unknown at compile time. It holds a map of so called
|
||||
* producers which are able to produce an instance of a special class.
|
||||
* Producer can be registered at runtime through e.g. application modules
|
||||
*/
|
||||
* This class has the purpose to produce instances of classes at runtime
|
||||
* that are unknown at compile time. It holds a map of so called
|
||||
* producers which are able to produce an instance of a special class.
|
||||
* Producer can be registered at runtime through e.g. application modules
|
||||
*/
|
||||
class BaseExport Factory
|
||||
{
|
||||
public:
|
||||
/// Adds a new prducer instance
|
||||
void AddProducer (const char* sClassName, AbstractProducer *pcProducer);
|
||||
void AddProducer(const char* sClassName, AbstractProducer* pcProducer);
|
||||
/// returns true if there is a producer for this class registered
|
||||
bool CanProduce(const char* sClassName) const;
|
||||
/// returns a list of all registered producer
|
||||
@@ -66,25 +65,25 @@ public:
|
||||
|
||||
protected:
|
||||
/// produce a class with the given name
|
||||
void* Produce (const char* sClassName) const;
|
||||
void* Produce(const char* sClassName) const;
|
||||
std::map<const std::string, AbstractProducer*> _mpcProducers;
|
||||
/// construction
|
||||
Factory () = default;
|
||||
Factory() = default;
|
||||
/// destruction
|
||||
virtual ~Factory ();
|
||||
virtual ~Factory();
|
||||
};
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
/** The ScriptFactorySingleton singleton
|
||||
*/
|
||||
class BaseExport ScriptFactorySingleton : public Factory
|
||||
*/
|
||||
class BaseExport ScriptFactorySingleton: public Factory
|
||||
{
|
||||
public:
|
||||
static ScriptFactorySingleton& Instance();
|
||||
static void Destruct ();
|
||||
static void Destruct();
|
||||
|
||||
const char* ProduceScript (const char* sScriptName) const;
|
||||
const char* ProduceScript(const char* sScriptName) const;
|
||||
|
||||
private:
|
||||
static ScriptFactorySingleton* _pcSingleton;
|
||||
@@ -101,22 +100,23 @@ inline ScriptFactorySingleton& ScriptFactory()
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
/** Script Factory
|
||||
* This class produce Scripts.
|
||||
* @see Factory
|
||||
*/
|
||||
* This class produce Scripts.
|
||||
* @see Factory
|
||||
*/
|
||||
class BaseExport ScriptProducer: public AbstractProducer
|
||||
{
|
||||
public:
|
||||
/// Constructor
|
||||
ScriptProducer (const char* name, const char* script) : mScript(script)
|
||||
ScriptProducer(const char* name, const char* script)
|
||||
: mScript(script)
|
||||
{
|
||||
ScriptFactorySingleton::Instance().AddProducer(name, this);
|
||||
}
|
||||
|
||||
~ScriptProducer () override = default;
|
||||
~ScriptProducer() override = default;
|
||||
|
||||
/// Produce an instance
|
||||
void* Produce () const override
|
||||
void* Produce() const override
|
||||
{
|
||||
return const_cast<char*>(mScript);
|
||||
}
|
||||
@@ -125,8 +125,7 @@ private:
|
||||
const char* mScript;
|
||||
};
|
||||
|
||||
} //namespace Base
|
||||
} // namespace Base
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -25,18 +25,18 @@
|
||||
#include "PreCompiled.h"
|
||||
|
||||
#ifndef _PreComp_
|
||||
# include <algorithm>
|
||||
# include <cassert>
|
||||
# include <codecvt>
|
||||
# include <cstring>
|
||||
# include <locale>
|
||||
# if defined (FC_OS_LINUX) || defined(FC_OS_CYGWIN) || defined(FC_OS_MACOSX) || defined(FC_OS_BSD)
|
||||
# include <dirent.h>
|
||||
# include <unistd.h>
|
||||
# elif defined (FC_OS_WIN32)
|
||||
# include <io.h>
|
||||
# include <Windows.h>
|
||||
# endif
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#include <codecvt>
|
||||
#include <cstring>
|
||||
#include <locale>
|
||||
#if defined(FC_OS_LINUX) || defined(FC_OS_CYGWIN) || defined(FC_OS_MACOSX) || defined(FC_OS_BSD)
|
||||
#include <dirent.h>
|
||||
#include <unistd.h>
|
||||
#elif defined(FC_OS_WIN32)
|
||||
#include <io.h>
|
||||
#include <Windows.h>
|
||||
#endif
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
@@ -49,16 +49,16 @@
|
||||
using namespace Base;
|
||||
|
||||
#ifndef R_OK
|
||||
#define R_OK 4 /* Test for read permission */
|
||||
#define R_OK 4 /* Test for read permission */
|
||||
#endif
|
||||
#ifndef W_OK
|
||||
#define W_OK 2 /* Test for write permission */
|
||||
#define W_OK 2 /* Test for write permission */
|
||||
#endif
|
||||
#ifndef X_OK
|
||||
#define X_OK 1 /* Test for execute permission */
|
||||
#define X_OK 1 /* Test for execute permission */
|
||||
#endif
|
||||
#ifndef F_OK
|
||||
#define F_OK 0 /* Test for existence */
|
||||
#define F_OK 0 /* Test for existence */
|
||||
#endif
|
||||
|
||||
//**********************************************************************************
|
||||
@@ -67,11 +67,11 @@ using namespace Base;
|
||||
#ifdef FC_OS_WIN32
|
||||
std::string ConvertFromWideString(const std::wstring& string)
|
||||
{
|
||||
int neededSize = WideCharToMultiByte(CP_UTF8, 0, string.c_str(), -1, 0, 0,0,0);
|
||||
char * CharString = new char[static_cast<size_t>(neededSize)];
|
||||
WideCharToMultiByte(CP_UTF8, 0, string.c_str(), -1, CharString, neededSize,0,0);
|
||||
int neededSize = WideCharToMultiByte(CP_UTF8, 0, string.c_str(), -1, 0, 0, 0, 0);
|
||||
char* CharString = new char[static_cast<size_t>(neededSize)];
|
||||
WideCharToMultiByte(CP_UTF8, 0, string.c_str(), -1, CharString, neededSize, 0, 0);
|
||||
std::string String(CharString);
|
||||
delete [] CharString;
|
||||
delete[] CharString;
|
||||
CharString = NULL;
|
||||
return String;
|
||||
}
|
||||
@@ -82,7 +82,7 @@ std::wstring ConvertToWideString(const std::string& string)
|
||||
wchar_t* wideCharString = new wchar_t[static_cast<size_t>(neededSize)];
|
||||
MultiByteToWideChar(CP_UTF8, 0, string.c_str(), -1, wideCharString, neededSize);
|
||||
std::wstring wideString(wideCharString);
|
||||
delete [] wideCharString;
|
||||
delete[] wideCharString;
|
||||
wideCharString = NULL;
|
||||
return wideString;
|
||||
}
|
||||
@@ -93,38 +93,40 @@ std::wstring ConvertToWideString(const std::string& string)
|
||||
// FileInfo
|
||||
|
||||
|
||||
FileInfo::FileInfo (const char* _FileName)
|
||||
FileInfo::FileInfo(const char* _FileName)
|
||||
{
|
||||
setFile(_FileName);
|
||||
}
|
||||
|
||||
FileInfo::FileInfo (const std::string &_FileName)
|
||||
FileInfo::FileInfo(const std::string& _FileName)
|
||||
{
|
||||
setFile(_FileName.c_str());
|
||||
}
|
||||
|
||||
const std::string &FileInfo::getTempPath()
|
||||
const std::string& FileInfo::getTempPath()
|
||||
{
|
||||
static std::string tempPath;
|
||||
|
||||
if (tempPath == "") {
|
||||
#ifdef FC_OS_WIN32
|
||||
wchar_t buf[MAX_PATH + 2];
|
||||
GetTempPathW(MAX_PATH + 1,buf);
|
||||
GetTempPathW(MAX_PATH + 1, buf);
|
||||
int neededSize = WideCharToMultiByte(CP_UTF8, 0, buf, -1, 0, 0, 0, 0);
|
||||
char* dest = new char[static_cast<size_t>(neededSize)];
|
||||
WideCharToMultiByte(CP_UTF8, 0, buf, -1,dest, neededSize, 0, 0);
|
||||
WideCharToMultiByte(CP_UTF8, 0, buf, -1, dest, neededSize, 0, 0);
|
||||
tempPath = dest;
|
||||
delete [] dest;
|
||||
delete[] dest;
|
||||
#else
|
||||
const char* tmp = getenv("TMPDIR");
|
||||
if (tmp && tmp[0] != '\0') {
|
||||
tempPath = tmp;
|
||||
FileInfo fi(tempPath);
|
||||
if (tempPath.empty() || !fi.isDir()) // still empty or non-existent
|
||||
if (tempPath.empty() || !fi.isDir()) { // still empty or non-existent
|
||||
tempPath = "/tmp/";
|
||||
else if (tempPath.at(tempPath.size()-1)!='/')
|
||||
}
|
||||
else if (tempPath.at(tempPath.size() - 1) != '/') {
|
||||
tempPath.append("/");
|
||||
}
|
||||
}
|
||||
else {
|
||||
tempPath = "/tmp/";
|
||||
@@ -137,28 +139,32 @@ const std::string &FileInfo::getTempPath()
|
||||
|
||||
std::string FileInfo::getTempFileName(const char* FileName, const char* Path)
|
||||
{
|
||||
//FIXME: To avoid race conditions we should rather return a file pointer
|
||||
//than a file name.
|
||||
// FIXME: To avoid race conditions we should rather return a file pointer
|
||||
// than a file name.
|
||||
#ifdef FC_OS_WIN32
|
||||
wchar_t buf[MAX_PATH + 2];
|
||||
|
||||
// Path where the file is located
|
||||
std::wstring path;
|
||||
if (Path)
|
||||
if (Path) {
|
||||
path = ConvertToWideString(std::string(Path));
|
||||
else
|
||||
}
|
||||
else {
|
||||
path = ConvertToWideString(getTempPath());
|
||||
}
|
||||
|
||||
// File name in the path
|
||||
std::wstring file;
|
||||
if (FileName)
|
||||
if (FileName) {
|
||||
file = ConvertToWideString(std::string(FileName));
|
||||
else
|
||||
}
|
||||
else {
|
||||
file = L"FCTempFile";
|
||||
}
|
||||
|
||||
|
||||
// this already creates the file
|
||||
GetTempFileNameW(path.c_str(),file.c_str(),0,buf);
|
||||
GetTempFileNameW(path.c_str(), file.c_str(), 0, buf);
|
||||
DeleteFileW(buf);
|
||||
|
||||
return std::string(ConvertFromWideString(std::wstring(buf)));
|
||||
@@ -166,10 +172,12 @@ std::string FileInfo::getTempFileName(const char* FileName, const char* Path)
|
||||
std::string buf;
|
||||
|
||||
// Path where the file is located
|
||||
if (Path)
|
||||
if (Path) {
|
||||
buf = Path;
|
||||
else
|
||||
}
|
||||
else {
|
||||
buf = getTempPath();
|
||||
}
|
||||
|
||||
// File name in the path
|
||||
if (FileName) {
|
||||
@@ -190,7 +198,7 @@ std::string FileInfo::getTempFileName(const char* FileName, const char* Path)
|
||||
if (id > -1) {
|
||||
FILE* file = fdopen(id, "w");
|
||||
fclose(file);
|
||||
vec.pop_back(); // remove '\0'
|
||||
vec.pop_back(); // remove '\0'
|
||||
std::string str(vec.begin(), vec.end());
|
||||
buf.swap(str);
|
||||
unlink(buf.c_str());
|
||||
@@ -230,25 +238,27 @@ void FileInfo::setFile(const char* name)
|
||||
FileName = name;
|
||||
|
||||
// keep the UNC paths intact
|
||||
if (FileName.substr(0,2) == std::string("\\\\"))
|
||||
std::replace(FileName.begin()+2, FileName.end(), '\\', '/');
|
||||
else
|
||||
if (FileName.substr(0, 2) == std::string("\\\\")) {
|
||||
std::replace(FileName.begin() + 2, FileName.end(), '\\', '/');
|
||||
}
|
||||
else {
|
||||
std::replace(FileName.begin(), FileName.end(), '\\', '/');
|
||||
}
|
||||
}
|
||||
|
||||
std::string FileInfo::filePath () const
|
||||
std::string FileInfo::filePath() const
|
||||
{
|
||||
return FileName;
|
||||
}
|
||||
|
||||
std::string FileInfo::fileName() const
|
||||
{
|
||||
return FileName.substr(FileName.find_last_of('/')+1);
|
||||
return FileName.substr(FileName.find_last_of('/') + 1);
|
||||
}
|
||||
|
||||
std::string FileInfo::dirPath() const
|
||||
{
|
||||
std::size_t last_pos{};
|
||||
std::size_t last_pos {};
|
||||
std::string retval;
|
||||
last_pos = FileName.find_last_of('/');
|
||||
if (last_pos != std::string::npos) {
|
||||
@@ -260,7 +270,7 @@ std::string FileInfo::dirPath() const
|
||||
GetCurrentDirectoryW(MAX_PATH, buf);
|
||||
retval = std::string(ConvertFromWideString(std::wstring(buf)));
|
||||
#else
|
||||
char buf[PATH_MAX+1];
|
||||
char buf[PATH_MAX + 1];
|
||||
const char* cwd = getcwd(buf, PATH_MAX);
|
||||
retval = std::string(cwd ? cwd : ".");
|
||||
#endif
|
||||
@@ -273,10 +283,12 @@ std::string FileInfo::fileNamePure() const
|
||||
std::string temp = fileName();
|
||||
std::string::size_type pos = temp.find_last_of('.');
|
||||
|
||||
if (pos != std::string::npos)
|
||||
return temp.substr(0,pos);
|
||||
else
|
||||
if (pos != std::string::npos) {
|
||||
return temp.substr(0, pos);
|
||||
}
|
||||
else {
|
||||
return temp;
|
||||
}
|
||||
}
|
||||
|
||||
std::wstring FileInfo::toStdWString() const
|
||||
@@ -294,25 +306,27 @@ std::wstring FileInfo::toStdWString() const
|
||||
std::string FileInfo::extension() const
|
||||
{
|
||||
std::string::size_type pos = FileName.find_last_of('.');
|
||||
if (pos == std::string::npos)
|
||||
if (pos == std::string::npos) {
|
||||
return {};
|
||||
return FileName.substr(pos+1);
|
||||
}
|
||||
return FileName.substr(pos + 1);
|
||||
}
|
||||
|
||||
std::string FileInfo::completeExtension() const
|
||||
{
|
||||
std::string::size_type pos = FileName.find_first_of('.');
|
||||
if (pos == std::string::npos)
|
||||
if (pos == std::string::npos) {
|
||||
return {};
|
||||
return FileName.substr(pos+1);
|
||||
}
|
||||
return FileName.substr(pos + 1);
|
||||
}
|
||||
|
||||
bool FileInfo::hasExtension(const char* Ext) const
|
||||
{
|
||||
#if defined (FC_OS_WIN32)
|
||||
#if defined(FC_OS_WIN32)
|
||||
return _stricmp(Ext, extension().c_str()) == 0;
|
||||
#elif defined (FC_OS_LINUX) || defined(FC_OS_CYGWIN) || defined(FC_OS_MACOSX) || defined(FC_OS_BSD)
|
||||
return strcasecmp(Ext,extension().c_str()) == 0;
|
||||
#elif defined(FC_OS_LINUX) || defined(FC_OS_CYGWIN) || defined(FC_OS_MACOSX) || defined(FC_OS_BSD)
|
||||
return strcasecmp(Ext, extension().c_str()) == 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -328,30 +342,30 @@ bool FileInfo::hasExtension(std::initializer_list<const char*> Exts) const
|
||||
|
||||
bool FileInfo::exists() const
|
||||
{
|
||||
#if defined (FC_OS_WIN32)
|
||||
#if defined(FC_OS_WIN32)
|
||||
std::wstring wstr = toStdWString();
|
||||
return _waccess(wstr.c_str(), F_OK) == 0;
|
||||
#elif defined (FC_OS_LINUX) || defined(FC_OS_CYGWIN) || defined(FC_OS_MACOSX) || defined(FC_OS_BSD)
|
||||
#elif defined(FC_OS_LINUX) || defined(FC_OS_CYGWIN) || defined(FC_OS_MACOSX) || defined(FC_OS_BSD)
|
||||
return access(FileName.c_str(), F_OK) == 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool FileInfo::isReadable() const
|
||||
{
|
||||
#if defined (FC_OS_WIN32)
|
||||
#if defined(FC_OS_WIN32)
|
||||
std::wstring wstr = toStdWString();
|
||||
return _waccess(wstr.c_str(), R_OK) == 0;
|
||||
#elif defined (FC_OS_LINUX) || defined(FC_OS_CYGWIN) || defined(FC_OS_MACOSX) || defined(FC_OS_BSD)
|
||||
#elif defined(FC_OS_LINUX) || defined(FC_OS_CYGWIN) || defined(FC_OS_MACOSX) || defined(FC_OS_BSD)
|
||||
return access(FileName.c_str(), R_OK) == 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool FileInfo::isWritable() const
|
||||
{
|
||||
#if defined (FC_OS_WIN32)
|
||||
#if defined(FC_OS_WIN32)
|
||||
std::wstring wstr = toStdWString();
|
||||
return _waccess(wstr.c_str(), W_OK) == 0;
|
||||
#elif defined (FC_OS_LINUX) || defined(FC_OS_CYGWIN) || defined(FC_OS_MACOSX) || defined(FC_OS_BSD)
|
||||
#elif defined(FC_OS_LINUX) || defined(FC_OS_CYGWIN) || defined(FC_OS_MACOSX) || defined(FC_OS_BSD)
|
||||
return access(FileName.c_str(), W_OK) == 0;
|
||||
#endif
|
||||
}
|
||||
@@ -360,17 +374,20 @@ bool FileInfo::setPermissions(Permissions perms)
|
||||
{
|
||||
int mode = 0;
|
||||
|
||||
if (perms & FileInfo::ReadOnly)
|
||||
if (perms & FileInfo::ReadOnly) {
|
||||
mode |= S_IREAD;
|
||||
if (perms & FileInfo::WriteOnly)
|
||||
}
|
||||
if (perms & FileInfo::WriteOnly) {
|
||||
mode |= S_IWRITE;
|
||||
}
|
||||
|
||||
if (mode == 0) // bad argument
|
||||
if (mode == 0) { // bad argument
|
||||
return false;
|
||||
#if defined (FC_OS_WIN32)
|
||||
}
|
||||
#if defined(FC_OS_WIN32)
|
||||
std::wstring wstr = toStdWString();
|
||||
return _wchmod(wstr.c_str(), mode) == 0;
|
||||
#elif defined (FC_OS_LINUX) || defined(FC_OS_CYGWIN) || defined(FC_OS_MACOSX) || defined(FC_OS_BSD)
|
||||
#elif defined(FC_OS_LINUX) || defined(FC_OS_CYGWIN) || defined(FC_OS_MACOSX) || defined(FC_OS_BSD)
|
||||
return chmod(FileName.c_str(), mode) == 0;
|
||||
#endif
|
||||
}
|
||||
@@ -383,12 +400,15 @@ bool FileInfo::isFile() const
|
||||
std::wstring wstr = toStdWString();
|
||||
FILE* fd = _wfopen(wstr.c_str(), L"rb");
|
||||
bool ok = (fd != 0);
|
||||
if (fd) fclose(fd);
|
||||
if (fd) {
|
||||
fclose(fd);
|
||||
}
|
||||
return ok;
|
||||
#else
|
||||
struct stat st;
|
||||
if(stat(FileName.c_str(), &st) != 0)
|
||||
if (stat(FileName.c_str(), &st) != 0) {
|
||||
return false;
|
||||
}
|
||||
return S_ISREG(st.st_mode);
|
||||
#endif
|
||||
}
|
||||
@@ -402,16 +422,19 @@ bool FileInfo::isDir() const
|
||||
if (exists()) {
|
||||
// if we can chdir then it must be a directory, otherwise we assume it
|
||||
// is a file (which doesn't need to be true for any cases)
|
||||
#if defined (FC_OS_WIN32)
|
||||
#if defined(FC_OS_WIN32)
|
||||
std::wstring wstr = toStdWString();
|
||||
struct _stat st;
|
||||
|
||||
if (_wstat(wstr.c_str(), &st) != 0)
|
||||
if (_wstat(wstr.c_str(), &st) != 0) {
|
||||
return false;
|
||||
}
|
||||
return ((st.st_mode & _S_IFDIR) != 0);
|
||||
|
||||
#elif defined (FC_OS_LINUX) || defined(FC_OS_CYGWIN) || defined(FC_OS_MACOSX) || defined(FC_OS_BSD)
|
||||
struct stat st{};
|
||||
#elif defined(FC_OS_LINUX) || defined(FC_OS_CYGWIN) || defined(FC_OS_MACOSX) || defined(FC_OS_BSD)
|
||||
struct stat st
|
||||
{
|
||||
};
|
||||
if (stat(FileName.c_str(), &st) != 0) {
|
||||
return false;
|
||||
}
|
||||
@@ -420,14 +443,15 @@ bool FileInfo::isDir() const
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
else
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
|
||||
// TODO: Check for valid path name
|
||||
//return true;
|
||||
// return true;
|
||||
}
|
||||
|
||||
unsigned int FileInfo::size () const
|
||||
unsigned int FileInfo::size() const
|
||||
{
|
||||
// not implemented
|
||||
assert(0);
|
||||
@@ -439,20 +463,21 @@ TimeInfo FileInfo::lastModified() const
|
||||
TimeInfo ti = TimeInfo::null();
|
||||
if (exists()) {
|
||||
|
||||
#if defined (FC_OS_WIN32)
|
||||
#if defined(FC_OS_WIN32)
|
||||
std::wstring wstr = toStdWString();
|
||||
struct _stat st;
|
||||
if (_wstat(wstr.c_str(), &st) == 0) {
|
||||
ti.setTime_t(st.st_mtime);
|
||||
}
|
||||
|
||||
#elif defined (FC_OS_LINUX) || defined(FC_OS_CYGWIN) || defined(FC_OS_MACOSX) || defined(FC_OS_BSD)
|
||||
struct stat st{};
|
||||
#elif defined(FC_OS_LINUX) || defined(FC_OS_CYGWIN) || defined(FC_OS_MACOSX) || defined(FC_OS_BSD)
|
||||
struct stat st
|
||||
{
|
||||
};
|
||||
if (stat(FileName.c_str(), &st) == 0) {
|
||||
ti.setTime_t(st.st_mtime);
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
return ti;
|
||||
}
|
||||
@@ -462,47 +487,48 @@ TimeInfo FileInfo::lastRead() const
|
||||
TimeInfo ti = TimeInfo::null();
|
||||
if (exists()) {
|
||||
|
||||
#if defined (FC_OS_WIN32)
|
||||
#if defined(FC_OS_WIN32)
|
||||
std::wstring wstr = toStdWString();
|
||||
struct _stat st;
|
||||
if (_wstat(wstr.c_str(), &st) == 0) {
|
||||
ti.setTime_t(st.st_atime);
|
||||
}
|
||||
|
||||
#elif defined (FC_OS_LINUX) || defined(FC_OS_CYGWIN) || defined(FC_OS_MACOSX) || defined(FC_OS_BSD)
|
||||
struct stat st{};
|
||||
#elif defined(FC_OS_LINUX) || defined(FC_OS_CYGWIN) || defined(FC_OS_MACOSX) || defined(FC_OS_BSD)
|
||||
struct stat st
|
||||
{
|
||||
};
|
||||
if (stat(FileName.c_str(), &st) == 0) {
|
||||
ti.setTime_t(st.st_atime);
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
return ti;
|
||||
}
|
||||
|
||||
bool FileInfo::deleteFile() const
|
||||
{
|
||||
#if defined (FC_OS_WIN32)
|
||||
#if defined(FC_OS_WIN32)
|
||||
std::wstring wstr = toStdWString();
|
||||
return ::_wremove(wstr.c_str()) == 0;
|
||||
#elif defined (FC_OS_LINUX) || defined(FC_OS_CYGWIN) || defined(FC_OS_MACOSX) || defined(FC_OS_BSD)
|
||||
return (::remove(FileName.c_str())==0);
|
||||
#elif defined(FC_OS_LINUX) || defined(FC_OS_CYGWIN) || defined(FC_OS_MACOSX) || defined(FC_OS_BSD)
|
||||
return (::remove(FileName.c_str()) == 0);
|
||||
#else
|
||||
# error "FileInfo::deleteFile() not implemented for this platform!"
|
||||
#error "FileInfo::deleteFile() not implemented for this platform!"
|
||||
#endif
|
||||
}
|
||||
|
||||
bool FileInfo::renameFile(const char* NewName)
|
||||
{
|
||||
bool res{};
|
||||
#if defined (FC_OS_WIN32)
|
||||
bool res {};
|
||||
#if defined(FC_OS_WIN32)
|
||||
std::wstring oldname = toStdWString();
|
||||
std::wstring newname = ConvertToWideString(NewName);
|
||||
res = ::_wrename(oldname.c_str(),newname.c_str()) == 0;
|
||||
#elif defined (FC_OS_LINUX) || defined(FC_OS_CYGWIN) || defined(FC_OS_MACOSX) || defined(FC_OS_BSD)
|
||||
res = ::rename(FileName.c_str(),NewName) == 0;
|
||||
res = ::_wrename(oldname.c_str(), newname.c_str()) == 0;
|
||||
#elif defined(FC_OS_LINUX) || defined(FC_OS_CYGWIN) || defined(FC_OS_MACOSX) || defined(FC_OS_BSD)
|
||||
res = ::rename(FileName.c_str(), NewName) == 0;
|
||||
#else
|
||||
# error "FileInfo::renameFile() not implemented for this platform!"
|
||||
#error "FileInfo::renameFile() not implemented for this platform!"
|
||||
#endif
|
||||
if (!res) {
|
||||
int code = errno;
|
||||
@@ -517,11 +543,11 @@ bool FileInfo::renameFile(const char* NewName)
|
||||
|
||||
bool FileInfo::copyTo(const char* NewName) const
|
||||
{
|
||||
#if defined (FC_OS_WIN32)
|
||||
#if defined(FC_OS_WIN32)
|
||||
std::wstring oldname = toStdWString();
|
||||
std::wstring newname = ConvertToWideString(NewName);
|
||||
return CopyFileW(oldname.c_str(),newname.c_str(),true) != 0;
|
||||
#elif defined (FC_OS_LINUX) || defined(FC_OS_CYGWIN) || defined(FC_OS_MACOSX) || defined(FC_OS_BSD)
|
||||
return CopyFileW(oldname.c_str(), newname.c_str(), true) != 0;
|
||||
#elif defined(FC_OS_LINUX) || defined(FC_OS_CYGWIN) || defined(FC_OS_MACOSX) || defined(FC_OS_BSD)
|
||||
FileInfo fi1(FileName);
|
||||
FileInfo fi2(NewName);
|
||||
Base::ifstream file(fi1, std::ios::in | std::ios::binary);
|
||||
@@ -530,19 +556,19 @@ bool FileInfo::copyTo(const char* NewName) const
|
||||
file >> copy.rdbuf();
|
||||
return file.is_open() && copy.is_open();
|
||||
#else
|
||||
# error "FileInfo::copyTo() not implemented for this platform!"
|
||||
#error "FileInfo::copyTo() not implemented for this platform!"
|
||||
#endif
|
||||
}
|
||||
|
||||
bool FileInfo::createDirectory() const
|
||||
{
|
||||
#if defined (FC_OS_WIN32)
|
||||
#if defined(FC_OS_WIN32)
|
||||
std::wstring wstr = toStdWString();
|
||||
return _wmkdir(wstr.c_str()) == 0;
|
||||
#elif defined (FC_OS_LINUX) || defined(FC_OS_CYGWIN) || defined(FC_OS_MACOSX) || defined(FC_OS_BSD)
|
||||
#elif defined(FC_OS_LINUX) || defined(FC_OS_CYGWIN) || defined(FC_OS_MACOSX) || defined(FC_OS_BSD)
|
||||
return mkdir(FileName.c_str(), 0777) == 0;
|
||||
#else
|
||||
# error "FileInfo::createDirectory() not implemented for this platform!"
|
||||
#error "FileInfo::createDirectory() not implemented for this platform!"
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -550,8 +576,9 @@ bool FileInfo::createDirectories() const
|
||||
{
|
||||
try {
|
||||
boost::filesystem::path path(stringToPath(FileName));
|
||||
if (boost::filesystem::exists(path))
|
||||
if (boost::filesystem::exists(path)) {
|
||||
return true;
|
||||
}
|
||||
boost::filesystem::create_directories(path);
|
||||
return true;
|
||||
}
|
||||
@@ -562,22 +589,24 @@ bool FileInfo::createDirectories() const
|
||||
|
||||
bool FileInfo::deleteDirectory() const
|
||||
{
|
||||
if (!isDir())
|
||||
if (!isDir()) {
|
||||
return false;
|
||||
#if defined (FC_OS_WIN32)
|
||||
}
|
||||
#if defined(FC_OS_WIN32)
|
||||
std::wstring wstr = toStdWString();
|
||||
return _wrmdir(wstr.c_str()) == 0;
|
||||
#elif defined (FC_OS_LINUX) || defined(FC_OS_CYGWIN) || defined(FC_OS_MACOSX) || defined(FC_OS_BSD)
|
||||
#elif defined(FC_OS_LINUX) || defined(FC_OS_CYGWIN) || defined(FC_OS_MACOSX) || defined(FC_OS_BSD)
|
||||
return rmdir(FileName.c_str()) == 0;
|
||||
#else
|
||||
# error "FileInfo::rmdir() not implemented for this platform!"
|
||||
#error "FileInfo::rmdir() not implemented for this platform!"
|
||||
#endif
|
||||
}
|
||||
|
||||
bool FileInfo::deleteDirectoryRecursive() const
|
||||
{
|
||||
if (!isDir())
|
||||
if (!isDir()) {
|
||||
return false;
|
||||
}
|
||||
std::vector<Base::FileInfo> List = getDirectoryContent();
|
||||
|
||||
for (Base::FileInfo& fi : List) {
|
||||
@@ -595,7 +624,8 @@ bool FileInfo::deleteDirectoryRecursive() const
|
||||
fi.deleteFile();
|
||||
}
|
||||
else {
|
||||
throw Base::FileException("FileInfo::deleteDirectoryRecursive(): Unknown object Type in directory!");
|
||||
throw Base::FileException(
|
||||
"FileInfo::deleteDirectoryRecursive(): Unknown object Type in directory!");
|
||||
}
|
||||
}
|
||||
return deleteDirectory();
|
||||
@@ -604,7 +634,7 @@ bool FileInfo::deleteDirectoryRecursive() const
|
||||
std::vector<Base::FileInfo> FileInfo::getDirectoryContent() const
|
||||
{
|
||||
std::vector<Base::FileInfo> List;
|
||||
#if defined (FC_OS_WIN32)
|
||||
#if defined(FC_OS_WIN32)
|
||||
struct _wfinddata_t dentry;
|
||||
|
||||
intptr_t hFile;
|
||||
@@ -613,32 +643,35 @@ std::vector<Base::FileInfo> FileInfo::getDirectoryContent() const
|
||||
std::wstring wstr = toStdWString();
|
||||
wstr += L"/*";
|
||||
|
||||
if ((hFile = _wfindfirst( wstr.c_str(), &dentry)) == -1L)
|
||||
if ((hFile = _wfindfirst(wstr.c_str(), &dentry)) == -1L) {
|
||||
return List;
|
||||
}
|
||||
|
||||
while (_wfindnext(hFile, &dentry) == 0)
|
||||
if (wcscmp(dentry.name,L"..") != 0)
|
||||
List.push_back(FileInfo(FileName + "/" +ConvertFromWideString(std::wstring(dentry.name))));
|
||||
while (_wfindnext(hFile, &dentry) == 0) {
|
||||
if (wcscmp(dentry.name, L"..") != 0) {
|
||||
List.push_back(
|
||||
FileInfo(FileName + "/" + ConvertFromWideString(std::wstring(dentry.name))));
|
||||
}
|
||||
}
|
||||
|
||||
_findclose(hFile);
|
||||
|
||||
#elif defined (FC_OS_LINUX) || defined(FC_OS_CYGWIN) || defined(FC_OS_MACOSX) || defined(FC_OS_BSD)
|
||||
#elif defined(FC_OS_LINUX) || defined(FC_OS_CYGWIN) || defined(FC_OS_MACOSX) || defined(FC_OS_BSD)
|
||||
DIR* dp(nullptr);
|
||||
struct dirent* dentry(nullptr);
|
||||
if (!(dp = opendir(FileName.c_str())))
|
||||
{
|
||||
if (!(dp = opendir(FileName.c_str()))) {
|
||||
return List;
|
||||
}
|
||||
|
||||
while ((dentry = readdir(dp)))
|
||||
{
|
||||
while ((dentry = readdir(dp))) {
|
||||
std::string dir = dentry->d_name;
|
||||
if (dir != "." && dir != "..")
|
||||
if (dir != "." && dir != "..") {
|
||||
List.emplace_back(FileName + "/" + dir);
|
||||
}
|
||||
}
|
||||
closedir(dp);
|
||||
#else
|
||||
# error "FileInfo::getDirectoryContent() not implemented for this platform!"
|
||||
#error "FileInfo::getDirectoryContent() not implemented for this platform!"
|
||||
#endif
|
||||
return List;
|
||||
}
|
||||
|
||||
@@ -37,44 +37,49 @@ namespace Base
|
||||
/// When reading and writing a character stream, the incoming data can be dumped into the stream
|
||||
/// unaltered (if it contains only data that is valid in the current XML character set), or it can
|
||||
/// be Base64-encoded. This enum is used by Reader and Writer to distinguish the two cases.
|
||||
enum class CharStreamFormat {
|
||||
enum class CharStreamFormat
|
||||
{
|
||||
Raw,
|
||||
Base64Encoded
|
||||
};
|
||||
|
||||
/** File name unification
|
||||
* This class handles everything related to file names
|
||||
* the file names are internal generally UTF-8 encoded on
|
||||
* all platforms.
|
||||
*/
|
||||
* This class handles everything related to file names
|
||||
* the file names are internal generally UTF-8 encoded on
|
||||
* all platforms.
|
||||
*/
|
||||
class BaseExport FileInfo
|
||||
{
|
||||
public:
|
||||
enum Permissions {
|
||||
enum Permissions
|
||||
{
|
||||
WriteOnly = 0x01,
|
||||
ReadOnly = 0x02,
|
||||
ReadWrite = 0x03,
|
||||
};
|
||||
|
||||
/// Construction
|
||||
FileInfo (const char* _FileName="");
|
||||
FileInfo (const std::string &_FileName);
|
||||
FileInfo(const char* _FileName = "");
|
||||
FileInfo(const std::string& _FileName);
|
||||
/// Set a new file name
|
||||
void setFile(const char* name);
|
||||
/// Set a new file name
|
||||
void setFile(const std::string &name){setFile(name.c_str());}
|
||||
void setFile(const std::string& name)
|
||||
{
|
||||
setFile(name.c_str());
|
||||
}
|
||||
|
||||
|
||||
/** @name extraction of information */
|
||||
//@{
|
||||
/// Returns the file name, including the path (which may be absolute or relative).
|
||||
std::string filePath () const;
|
||||
std::string filePath() const;
|
||||
/// Returns the dir path name (which may be absolute or relative).
|
||||
std::string dirPath () const;
|
||||
std::string dirPath() const;
|
||||
/// Returns the name of the file, excluding the path, including the extension.
|
||||
std::string fileName () const;
|
||||
std::string fileName() const;
|
||||
/// Returns the name of the file, excluding the path and the extension.
|
||||
std::string fileNamePure () const;
|
||||
std::string fileNamePure() const;
|
||||
/// Convert the path name into a UTF-16 encoded wide string format.
|
||||
/// @note: Use this function on Windows only.
|
||||
std::wstring toStdWString() const;
|
||||
@@ -86,7 +91,7 @@ public:
|
||||
* ext = fi.extension(); // ext = "gz"
|
||||
*@endcode
|
||||
*/
|
||||
std::string extension () const;
|
||||
std::string extension() const;
|
||||
/** Returns the complete extension of the file.
|
||||
* The complete extension consists of all characters in the file after (but not including)
|
||||
* the first '.' character.
|
||||
@@ -95,29 +100,29 @@ public:
|
||||
* ext = fi.completeExtension(); // ext = "tar.gz"
|
||||
*@endcode
|
||||
*/
|
||||
std::string completeExtension () const;
|
||||
std::string completeExtension() const;
|
||||
/// Checks for a special extension, NOT case sensitive
|
||||
bool hasExtension (const char* Ext) const;
|
||||
/// Checks for any of the special extensions, NOT case sensitive
|
||||
bool hasExtension (std::initializer_list<const char*> Exts) const;
|
||||
bool hasExtension(const char* Ext) const;
|
||||
/// Checks for any of the special extensions, NOT case sensitive
|
||||
bool hasExtension(std::initializer_list<const char*> Exts) const;
|
||||
//@}
|
||||
|
||||
/** @name methods to test the status of the file or dir */
|
||||
//@{
|
||||
/// Does the file exist?
|
||||
bool exists () const;
|
||||
bool exists() const;
|
||||
/// Checks if the file exist and is readable
|
||||
bool isReadable () const;
|
||||
bool isReadable() const;
|
||||
/// Checks if the file exist and is writable
|
||||
bool isWritable () const;
|
||||
bool isWritable() const;
|
||||
/// Tries to set the file permission
|
||||
bool setPermissions (Permissions);
|
||||
bool setPermissions(Permissions);
|
||||
/// Checks if it is a file (not a directory)
|
||||
bool isFile () const;
|
||||
bool isFile() const;
|
||||
/// Checks if it is a directory (not a file)
|
||||
bool isDir () const;
|
||||
bool isDir() const;
|
||||
/// The size of the file
|
||||
unsigned int size () const;
|
||||
unsigned int size() const;
|
||||
/// Returns the time when the file was last modified.
|
||||
TimeInfo lastModified() const;
|
||||
/// Returns the time when the file was last read (accessed).
|
||||
@@ -127,8 +132,9 @@ public:
|
||||
/** @name Directory management*/
|
||||
//@{
|
||||
/// Creates a directory. Returns true if successful; otherwise returns false.
|
||||
bool createDirectory( ) const;
|
||||
/// Creates a directory and all its parent directories. Returns true if successful; otherwise returns false.
|
||||
bool createDirectory() const;
|
||||
/// Creates a directory and all its parent directories. Returns true if successful; otherwise
|
||||
/// returns false.
|
||||
bool createDirectories() const;
|
||||
/// Get a list of the directory content
|
||||
std::vector<Base::FileInfo> getDirectoryContent() const;
|
||||
@@ -148,20 +154,20 @@ public:
|
||||
/** @name Tools */
|
||||
//@{
|
||||
/// Get a unique File Name in the given or (if 0) in the temp path
|
||||
static std::string getTempFileName(const char* FileName=nullptr, const char* path=nullptr);
|
||||
static std::string getTempFileName(const char* FileName = nullptr, const char* path = nullptr);
|
||||
/// Get the path to the dir which is considered to temp files
|
||||
static const std::string &getTempPath();
|
||||
static const std::string& getTempPath();
|
||||
/// Convert from filesystem path to string
|
||||
static std::string pathToString(const boost::filesystem::path& p);
|
||||
/// Convert from string to filesystem path
|
||||
static boost::filesystem::path stringToPath(const std::string& str);
|
||||
//@}
|
||||
|
||||
protected:
|
||||
private:
|
||||
std::string FileName;
|
||||
};
|
||||
|
||||
} //namespace Base
|
||||
} // namespace Base
|
||||
|
||||
|
||||
#endif // BASE_FILEINFO_H
|
||||
#endif // BASE_FILEINFO_H
|
||||
|
||||
@@ -63,7 +63,7 @@ ClassTemplate::~ClassTemplate() = default;
|
||||
* @see publicVar()
|
||||
* @return The test results
|
||||
*/
|
||||
int ClassTemplate::testMe(int /*a*/,const char* /*s*/)
|
||||
int ClassTemplate::testMe(int /*a*/, const char* /*s*/)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
@@ -73,6 +73,3 @@ int ClassTemplate::testMe(int /*a*/,const char* /*s*/)
|
||||
//**************************************************************************
|
||||
// Separator for additional classes
|
||||
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -89,20 +89,21 @@ public:
|
||||
/// Destruction
|
||||
virtual ~ClassTemplate();
|
||||
|
||||
int testMe(int a,const char *s);
|
||||
int testMe(int a, const char* s);
|
||||
|
||||
/**
|
||||
* An enum.
|
||||
* More detailed enum description.
|
||||
*/
|
||||
|
||||
enum TEnum {
|
||||
enum TEnum
|
||||
{
|
||||
TVal1, /**< enum value TVal1. */
|
||||
TVal2, /**< enum value TVal2. */
|
||||
TVal3 /**< enum value TVal3. */
|
||||
}
|
||||
*enumPtr{nullptr}, /**< enum pointer. Details. */
|
||||
enumVar{TVal1}; /**< enum variable. Details. */
|
||||
* enumPtr {nullptr}, /**< enum pointer. Details. */
|
||||
enumVar {TVal1}; /**< enum variable. Details. */
|
||||
|
||||
/**
|
||||
* A pure virtual member.
|
||||
@@ -110,35 +111,34 @@ public:
|
||||
* @param c1 the first argument.
|
||||
* @param c2 the second argument.
|
||||
*/
|
||||
virtual void testMeToo(char c1,char c2) = 0;
|
||||
virtual void testMeToo(char c1, char c2) = 0;
|
||||
|
||||
/** @name a group of methods */
|
||||
//@{
|
||||
/// I am method one
|
||||
virtual void one()=0;
|
||||
virtual void one() = 0;
|
||||
/// I am method two
|
||||
virtual void two()=0;
|
||||
virtual void two() = 0;
|
||||
/// I am method three
|
||||
virtual void three()=0;
|
||||
virtual void three() = 0;
|
||||
//@}
|
||||
|
||||
|
||||
/**
|
||||
* a public variable.
|
||||
* Details.
|
||||
*/
|
||||
int publicVar{0};
|
||||
* a public variable.
|
||||
* Details.
|
||||
*/
|
||||
int publicVar {0};
|
||||
|
||||
/**
|
||||
* a function variable.
|
||||
* Details.
|
||||
*/
|
||||
int (*handler)(int a,int b){nullptr};
|
||||
int (*handler)(int a, int b) {nullptr};
|
||||
|
||||
std::string something;
|
||||
};
|
||||
|
||||
} //namespace Base
|
||||
|
||||
#endif // BASE_FILETEMPLATE_H
|
||||
} // namespace Base
|
||||
|
||||
#endif // BASE_FILETEMPLATE_H
|
||||
|
||||
@@ -28,16 +28,18 @@
|
||||
using namespace Base;
|
||||
|
||||
FutureWatcherProgress::FutureWatcherProgress(const char* text, unsigned int steps)
|
||||
: seq(text, 100), steps(steps), current(0)
|
||||
{
|
||||
}
|
||||
: seq(text, 100)
|
||||
, steps(steps)
|
||||
, current(0)
|
||||
{}
|
||||
|
||||
FutureWatcherProgress::~FutureWatcherProgress() = default;
|
||||
|
||||
void FutureWatcherProgress::progressValueChanged(int v)
|
||||
{
|
||||
if (steps == 0)
|
||||
if (steps == 0) {
|
||||
return;
|
||||
}
|
||||
unsigned int step = (100 * static_cast<unsigned int>(v)) / steps;
|
||||
if (step > current) {
|
||||
current = step;
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
namespace Base
|
||||
{
|
||||
|
||||
class BaseExport FutureWatcherProgress : public QObject
|
||||
class BaseExport FutureWatcherProgress: public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
@@ -41,8 +41,8 @@ public:
|
||||
|
||||
FutureWatcherProgress(const FutureWatcherProgress&) = delete;
|
||||
FutureWatcherProgress(FutureWatcherProgress&&) = delete;
|
||||
FutureWatcherProgress& operator= (const FutureWatcherProgress&) = delete;
|
||||
FutureWatcherProgress& operator= (FutureWatcherProgress&&) = delete;
|
||||
FutureWatcherProgress& operator=(const FutureWatcherProgress&) = delete;
|
||||
FutureWatcherProgress& operator=(FutureWatcherProgress&&) = delete;
|
||||
|
||||
public Q_SLOTS:
|
||||
void progressValueChanged(int value);
|
||||
@@ -51,6 +51,6 @@ private:
|
||||
Base::SequencerLauncher seq;
|
||||
unsigned int steps, current;
|
||||
};
|
||||
}
|
||||
} // namespace Base
|
||||
|
||||
#endif // BASE_FUTUREWATCHER_H
|
||||
#endif // BASE_FUTUREWATCHER_H
|
||||
|
||||
@@ -23,21 +23,21 @@
|
||||
|
||||
#include "PreCompiled.h"
|
||||
#ifndef _PreComp_
|
||||
# include <sstream>
|
||||
#include <sstream>
|
||||
#endif
|
||||
|
||||
#include "GeometryPyCXX.h"
|
||||
#include "VectorPy.h"
|
||||
|
||||
|
||||
int Py::Vector::Vector_TypeCheck(PyObject * obj)
|
||||
int Py::Vector::Vector_TypeCheck(PyObject* obj)
|
||||
{
|
||||
return PyObject_TypeCheck(obj, &(Base::VectorPy::Type));
|
||||
}
|
||||
|
||||
bool Py::Vector::accepts (PyObject *obj) const
|
||||
bool Py::Vector::accepts(PyObject* obj) const
|
||||
{
|
||||
if (obj && Vector_TypeCheck (obj)) {
|
||||
if (obj && Vector_TypeCheck(obj)) {
|
||||
return true;
|
||||
}
|
||||
else if (obj && PySequence_Check(obj)) {
|
||||
@@ -47,41 +47,42 @@ bool Py::Vector::accepts (PyObject *obj) const
|
||||
return false;
|
||||
}
|
||||
|
||||
Py::Vector::Vector (const Base::Vector3d& v)
|
||||
Py::Vector::Vector(const Base::Vector3d& v)
|
||||
{
|
||||
set(new Base::VectorPy(v), true);
|
||||
validate();
|
||||
}
|
||||
|
||||
Py::Vector::Vector (const Base::Vector3f& v)
|
||||
Py::Vector::Vector(const Base::Vector3f& v)
|
||||
{
|
||||
set(new Base::VectorPy(v), true);
|
||||
validate();
|
||||
}
|
||||
|
||||
Py::Vector& Py::Vector::operator= (PyObject* rhsp)
|
||||
Py::Vector& Py::Vector::operator=(PyObject* rhsp)
|
||||
{
|
||||
if(ptr() == rhsp)
|
||||
if (ptr() == rhsp) {
|
||||
return *this;
|
||||
set (rhsp, false);
|
||||
}
|
||||
set(rhsp, false);
|
||||
return *this;
|
||||
}
|
||||
|
||||
Py::Vector& Py::Vector::operator= (const Base::Vector3d& v)
|
||||
Py::Vector& Py::Vector::operator=(const Base::Vector3d& v)
|
||||
{
|
||||
set (new Base::VectorPy(v), true);
|
||||
set(new Base::VectorPy(v), true);
|
||||
return *this;
|
||||
}
|
||||
|
||||
Py::Vector& Py::Vector::operator= (const Base::Vector3f& v)
|
||||
Py::Vector& Py::Vector::operator=(const Base::Vector3f& v)
|
||||
{
|
||||
set (new Base::VectorPy(v), true);
|
||||
set(new Base::VectorPy(v), true);
|
||||
return *this;
|
||||
}
|
||||
|
||||
Base::Vector3d Py::Vector::toVector() const
|
||||
{
|
||||
if (Vector_TypeCheck (ptr())) {
|
||||
if (Vector_TypeCheck(ptr())) {
|
||||
return static_cast<Base::VectorPy*>(ptr())->value();
|
||||
}
|
||||
else {
|
||||
@@ -89,7 +90,8 @@ Base::Vector3d Py::Vector::toVector() const
|
||||
}
|
||||
}
|
||||
|
||||
namespace Base {
|
||||
namespace Base
|
||||
{
|
||||
|
||||
Py::PythonType& Vector2dPy::behaviors()
|
||||
{
|
||||
@@ -101,7 +103,7 @@ PyTypeObject* Vector2dPy::type_object()
|
||||
return Py::PythonClass<Vector2dPy>::type_object();
|
||||
}
|
||||
|
||||
bool Vector2dPy::check( PyObject *p )
|
||||
bool Vector2dPy::check(PyObject* p)
|
||||
{
|
||||
return Py::PythonClass<Vector2dPy>::check(p);
|
||||
}
|
||||
@@ -117,14 +119,15 @@ Py::PythonClassObject<Vector2dPy> Vector2dPy::create(double x, double y)
|
||||
Py::Tuple arg(2);
|
||||
arg.setItem(0, Py::Float(x));
|
||||
arg.setItem(1, Py::Float(y));
|
||||
Py::PythonClassObject<Vector2dPy> o = Py::PythonClassObject<Vector2dPy>(class_type.apply(arg, Py::Dict()));
|
||||
Py::PythonClassObject<Vector2dPy> o =
|
||||
Py::PythonClassObject<Vector2dPy>(class_type.apply(arg, Py::Dict()));
|
||||
return o;
|
||||
}
|
||||
|
||||
Vector2dPy::Vector2dPy(Py::PythonClassInstance *self, Py::Tuple &args, Py::Dict &kwds)
|
||||
Vector2dPy::Vector2dPy(Py::PythonClassInstance* self, Py::Tuple& args, Py::Dict& kwds)
|
||||
: Py::PythonClass<Vector2dPy>::PythonClass(self, args, kwds)
|
||||
{
|
||||
double x=0,y=0;
|
||||
double x = 0, y = 0;
|
||||
if (!PyArg_ParseTuple(args.ptr(), "|dd", &x, &y)) {
|
||||
throw Py::Exception();
|
||||
}
|
||||
@@ -141,19 +144,18 @@ Py::Object Vector2dPy::repr()
|
||||
Py::Float y(v.y);
|
||||
std::stringstream str;
|
||||
str << "Vector2 (";
|
||||
str << static_cast<std::string>(x.repr()) << ", "
|
||||
<< static_cast<std::string>(y.repr());
|
||||
str << static_cast<std::string>(x.repr()) << ", " << static_cast<std::string>(y.repr());
|
||||
str << ")";
|
||||
|
||||
return Py::String(str.str());
|
||||
}
|
||||
|
||||
Py::Object Vector2dPy::getattro(const Py::String &name_)
|
||||
Py::Object Vector2dPy::getattro(const Py::String& name_)
|
||||
{
|
||||
// For Py3 either handle __dict__ or implement __dir__ as shown here:
|
||||
// https://stackoverflow.com/questions/48609111/how-is-dir-implemented-exactly-and-how-should-i-know-it
|
||||
//
|
||||
std::string name( name_.as_std_string( "utf-8" ) );
|
||||
std::string name(name_.as_std_string("utf-8"));
|
||||
|
||||
if (name == "__dict__") {
|
||||
Py::Dict attr;
|
||||
@@ -168,13 +170,13 @@ Py::Object Vector2dPy::getattro(const Py::String &name_)
|
||||
return Py::Float(v.y);
|
||||
}
|
||||
else {
|
||||
return genericGetAttro( name_ );
|
||||
return genericGetAttro(name_);
|
||||
}
|
||||
}
|
||||
|
||||
int Vector2dPy::setattro(const Py::String &name_, const Py::Object &value)
|
||||
int Vector2dPy::setattro(const Py::String& name_, const Py::Object& value)
|
||||
{
|
||||
std::string name( name_.as_std_string( "utf-8" ) );
|
||||
std::string name(name_.as_std_string("utf-8"));
|
||||
|
||||
if (name == "x" && !value.isNull()) {
|
||||
v.x = static_cast<double>(Py::Float(value));
|
||||
@@ -185,7 +187,7 @@ int Vector2dPy::setattro(const Py::String &name_, const Py::Object &value)
|
||||
return 0;
|
||||
}
|
||||
else {
|
||||
return genericSetAttro( name_, value );
|
||||
return genericSetAttro(name_, value);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -219,21 +221,21 @@ Py::Object Vector2dPy::number_float()
|
||||
throw Py::TypeError("Not defined");
|
||||
}
|
||||
|
||||
Py::Object Vector2dPy::number_add( const Py::Object & py)
|
||||
Py::Object Vector2dPy::number_add(const Py::Object& py)
|
||||
{
|
||||
Vector2d u(Py::toVector2d(py));
|
||||
u = v + u;
|
||||
return create(u);
|
||||
}
|
||||
|
||||
Py::Object Vector2dPy::number_subtract( const Py::Object & py)
|
||||
Py::Object Vector2dPy::number_subtract(const Py::Object& py)
|
||||
{
|
||||
Vector2d u(Py::toVector2d(py));
|
||||
u = v - u;
|
||||
return create(u);
|
||||
}
|
||||
|
||||
Py::Object Vector2dPy::number_multiply( const Py::Object & py)
|
||||
Py::Object Vector2dPy::number_multiply(const Py::Object& py)
|
||||
{
|
||||
if (PyObject_TypeCheck(py.ptr(), Vector2dPy::type_object())) {
|
||||
Vector2d u(Py::toVector2d(py));
|
||||
@@ -249,42 +251,42 @@ Py::Object Vector2dPy::number_multiply( const Py::Object & py)
|
||||
}
|
||||
}
|
||||
|
||||
Py::Object Vector2dPy::number_remainder( const Py::Object & )
|
||||
Py::Object Vector2dPy::number_remainder(const Py::Object&)
|
||||
{
|
||||
throw Py::TypeError("Not defined");
|
||||
}
|
||||
|
||||
Py::Object Vector2dPy::number_divmod( const Py::Object & )
|
||||
Py::Object Vector2dPy::number_divmod(const Py::Object&)
|
||||
{
|
||||
throw Py::TypeError("Not defined");
|
||||
}
|
||||
|
||||
Py::Object Vector2dPy::number_lshift( const Py::Object & )
|
||||
Py::Object Vector2dPy::number_lshift(const Py::Object&)
|
||||
{
|
||||
throw Py::TypeError("Not defined");
|
||||
}
|
||||
|
||||
Py::Object Vector2dPy::number_rshift( const Py::Object & )
|
||||
Py::Object Vector2dPy::number_rshift(const Py::Object&)
|
||||
{
|
||||
throw Py::TypeError("Not defined");
|
||||
}
|
||||
|
||||
Py::Object Vector2dPy::number_and( const Py::Object & )
|
||||
Py::Object Vector2dPy::number_and(const Py::Object&)
|
||||
{
|
||||
throw Py::TypeError("Not defined");
|
||||
}
|
||||
|
||||
Py::Object Vector2dPy::number_xor( const Py::Object & )
|
||||
Py::Object Vector2dPy::number_xor(const Py::Object&)
|
||||
{
|
||||
throw Py::TypeError("Not defined");
|
||||
}
|
||||
|
||||
Py::Object Vector2dPy::number_or( const Py::Object & )
|
||||
Py::Object Vector2dPy::number_or(const Py::Object&)
|
||||
{
|
||||
throw Py::TypeError("Not defined");
|
||||
}
|
||||
|
||||
Py::Object Vector2dPy::number_power( const Py::Object &, const Py::Object & )
|
||||
Py::Object Vector2dPy::number_power(const Py::Object&, const Py::Object&)
|
||||
{
|
||||
throw Py::TypeError("Not defined");
|
||||
}
|
||||
@@ -381,8 +383,8 @@ PYCXX_VARARGS_METHOD_DECL(Vector2dPy, projectToLine)
|
||||
|
||||
void Vector2dPy::init_type()
|
||||
{
|
||||
behaviors().name( "Vector2d" );
|
||||
behaviors().doc( "Vector2d class" );
|
||||
behaviors().name("Vector2d");
|
||||
behaviors().doc("Vector2d class");
|
||||
behaviors().supportGetattro();
|
||||
behaviors().supportSetattro();
|
||||
behaviors().supportRepr();
|
||||
@@ -405,4 +407,4 @@ void Vector2dPy::init_type()
|
||||
behaviors().readyType();
|
||||
}
|
||||
|
||||
}
|
||||
} // namespace Base
|
||||
|
||||
@@ -37,8 +37,9 @@
|
||||
#include <Base/Vector3D.h>
|
||||
|
||||
|
||||
namespace Base {
|
||||
template <typename T>
|
||||
namespace Base
|
||||
{
|
||||
template<typename T>
|
||||
inline Vector3<T> getVectorFromTuple(PyObject* o)
|
||||
{
|
||||
Py::Sequence tuple(o);
|
||||
@@ -50,32 +51,35 @@ inline Vector3<T> getVectorFromTuple(PyObject* o)
|
||||
T y = static_cast<T>(Py::Float(tuple[1]));
|
||||
T z = static_cast<T>(Py::Float(tuple[2]));
|
||||
|
||||
return Vector3<T>(x,y,z);
|
||||
return Vector3<T>(x, y, z);
|
||||
}
|
||||
|
||||
class BaseExport Vector2dPy : public Py::PythonClass<Vector2dPy>
|
||||
class BaseExport Vector2dPy: public Py::PythonClass<Vector2dPy> // NOLINT
|
||||
{
|
||||
public:
|
||||
static Py::PythonType &behaviors();
|
||||
static PyTypeObject *type_object();
|
||||
static bool check( PyObject *p );
|
||||
static Py::PythonType& behaviors();
|
||||
static PyTypeObject* type_object();
|
||||
static bool check(PyObject* p);
|
||||
|
||||
static Py::PythonClassObject<Vector2dPy> create(const Vector2d&);
|
||||
static Py::PythonClassObject<Vector2dPy> create(double x, double y);
|
||||
Vector2dPy(Py::PythonClassInstance *self, Py::Tuple &args, Py::Dict &kwds);
|
||||
Vector2dPy(Py::PythonClassInstance* self, Py::Tuple& args, Py::Dict& kwds);
|
||||
~Vector2dPy() override;
|
||||
|
||||
static void init_type();
|
||||
Py::Object getattro(const Py::String &name_) override;
|
||||
int setattro(const Py::String &name_, const Py::Object &value) override;
|
||||
Py::Object getattro(const Py::String& name_) override;
|
||||
int setattro(const Py::String& name_, const Py::Object& value) override;
|
||||
Py::Object repr() override;
|
||||
inline const Vector2d& value() const {
|
||||
inline const Vector2d& value() const
|
||||
{
|
||||
return v;
|
||||
}
|
||||
inline void setValue(const Vector2d& n) {
|
||||
inline void setValue(const Vector2d& n)
|
||||
{
|
||||
v = n;
|
||||
}
|
||||
inline void setValue(double x, double y) {
|
||||
inline void setValue(double x, double y)
|
||||
{
|
||||
v.x = x;
|
||||
v.y = y;
|
||||
}
|
||||
@@ -88,17 +92,17 @@ public:
|
||||
Py::Object number_invert() override;
|
||||
Py::Object number_int() override;
|
||||
Py::Object number_float() override;
|
||||
Py::Object number_add( const Py::Object & ) override;
|
||||
Py::Object number_subtract( const Py::Object & ) override;
|
||||
Py::Object number_multiply( const Py::Object & ) override;
|
||||
Py::Object number_remainder( const Py::Object & ) override;
|
||||
Py::Object number_divmod( const Py::Object & ) override;
|
||||
Py::Object number_lshift( const Py::Object & ) override;
|
||||
Py::Object number_rshift( const Py::Object & ) override;
|
||||
Py::Object number_and( const Py::Object & ) override;
|
||||
Py::Object number_xor( const Py::Object & ) override;
|
||||
Py::Object number_or( const Py::Object & ) override;
|
||||
Py::Object number_power( const Py::Object &, const Py::Object & ) override;
|
||||
Py::Object number_add(const Py::Object&) override;
|
||||
Py::Object number_subtract(const Py::Object&) override;
|
||||
Py::Object number_multiply(const Py::Object&) override;
|
||||
Py::Object number_remainder(const Py::Object&) override;
|
||||
Py::Object number_divmod(const Py::Object&) override;
|
||||
Py::Object number_lshift(const Py::Object&) override;
|
||||
Py::Object number_rshift(const Py::Object&) override;
|
||||
Py::Object number_and(const Py::Object&) override;
|
||||
Py::Object number_xor(const Py::Object&) override;
|
||||
Py::Object number_or(const Py::Object&) override;
|
||||
Py::Object number_power(const Py::Object&, const Py::Object&) override;
|
||||
//@}
|
||||
|
||||
Py::Object isNull(const Py::Tuple&);
|
||||
@@ -118,53 +122,62 @@ private:
|
||||
Vector2d v;
|
||||
};
|
||||
|
||||
}
|
||||
} // namespace Base
|
||||
|
||||
namespace Py {
|
||||
namespace Py
|
||||
{
|
||||
|
||||
using Vector2d = PythonClassObject<Base::Vector2dPy>;
|
||||
|
||||
inline Base::Vector2d toVector2d(PyObject *py) {
|
||||
inline Base::Vector2d toVector2d(PyObject* py)
|
||||
{
|
||||
Base::Vector2dPy* py2d = Py::Vector2d(py).getCxxObject();
|
||||
return py2d ? py2d->value() : Base::Vector2d();
|
||||
}
|
||||
|
||||
inline Base::Vector2d toVector2d(const Object& py) {
|
||||
inline Base::Vector2d toVector2d(const Object& py)
|
||||
{
|
||||
Base::Vector2dPy* py2d = Py::Vector2d(py).getCxxObject();
|
||||
return py2d ? py2d->value() : Base::Vector2d();
|
||||
}
|
||||
|
||||
// Implementing the vector class in the fashion of the PyCXX library.
|
||||
class BaseExport Vector : public Object
|
||||
class BaseExport Vector: public Object // NOLINT
|
||||
{
|
||||
public:
|
||||
explicit Vector (PyObject *pyob, bool owned): Object(pyob, owned) {
|
||||
explicit Vector(PyObject* pyob, bool owned)
|
||||
: Object(pyob, owned)
|
||||
{
|
||||
validate();
|
||||
}
|
||||
|
||||
Vector (const Vector& ob): Object(*ob) {
|
||||
Vector(const Vector& ob)
|
||||
: Object(*ob)
|
||||
{
|
||||
validate();
|
||||
}
|
||||
|
||||
explicit Vector (const Base::Vector3d&);
|
||||
explicit Vector (const Base::Vector3f&);
|
||||
bool accepts (PyObject *pyob) const override;
|
||||
explicit Vector(const Base::Vector3d&);
|
||||
explicit Vector(const Base::Vector3f&);
|
||||
bool accepts(PyObject* pyob) const override;
|
||||
|
||||
Vector(const Object& other): Object(other.ptr()) {
|
||||
Vector(const Object& other)
|
||||
: Object(other.ptr())
|
||||
{
|
||||
validate();
|
||||
}
|
||||
Vector& operator= (const Object& rhs)
|
||||
Vector& operator=(const Object& rhs)
|
||||
{
|
||||
return (*this = *rhs);
|
||||
}
|
||||
Vector& operator= (const Vector& rhs)
|
||||
Vector& operator=(const Vector& rhs)
|
||||
{
|
||||
return (*this = *rhs);
|
||||
}
|
||||
|
||||
Vector& operator= (PyObject* rhsp);
|
||||
Vector& operator= (const Base::Vector3d&);
|
||||
Vector& operator= (const Base::Vector3f&);
|
||||
Vector& operator=(PyObject* rhsp);
|
||||
Vector& operator=(const Base::Vector3d&);
|
||||
Vector& operator=(const Base::Vector3f&);
|
||||
operator Base::Vector3d() const
|
||||
{
|
||||
return toVector();
|
||||
@@ -173,7 +186,7 @@ public:
|
||||
Base::Vector3d toVector() const;
|
||||
|
||||
private:
|
||||
static int Vector_TypeCheck(PyObject *);
|
||||
static int Vector_TypeCheck(PyObject*);
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -188,45 +201,54 @@ private:
|
||||
// The third template parameter is the definition of a pointer to the method
|
||||
// of the Python binding class to return the managed geometric instance. In our
|
||||
// example this is the method RotationPy::getRotationPtr.
|
||||
template <class T, class PyT, T* (PyT::*valuePtr)() const>
|
||||
class GeometryT : public Object
|
||||
template<class T, class PyT, T* (PyT::*valuePtr)() const>
|
||||
class GeometryT: public Object // NOLINT
|
||||
{
|
||||
public:
|
||||
explicit GeometryT (PyObject *pyob, bool owned): Object(pyob, owned) {
|
||||
explicit GeometryT(PyObject* pyob, bool owned)
|
||||
: Object(pyob, owned)
|
||||
{
|
||||
validate();
|
||||
}
|
||||
GeometryT (const GeometryT& ob): Object(*ob) {
|
||||
GeometryT(const GeometryT& ob)
|
||||
: Object(*ob)
|
||||
{
|
||||
validate();
|
||||
}
|
||||
explicit GeometryT ()
|
||||
explicit GeometryT()
|
||||
{
|
||||
set(new PyT(new T()), true);
|
||||
validate();
|
||||
}
|
||||
explicit GeometryT (const T& v)
|
||||
explicit GeometryT(const T& v)
|
||||
{
|
||||
set(new PyT(new T(v)), true);
|
||||
validate();
|
||||
}
|
||||
GeometryT(const Object& other): Object(other.ptr()) {
|
||||
GeometryT(const Object& other)
|
||||
: Object(other.ptr())
|
||||
{
|
||||
validate();
|
||||
}
|
||||
bool accepts (PyObject *pyob) const override {
|
||||
return pyob && Geometry_TypeCheck (pyob);
|
||||
bool accepts(PyObject* pyob) const override
|
||||
{
|
||||
return pyob && Geometry_TypeCheck(pyob);
|
||||
}
|
||||
GeometryT& operator= (const Object& rhs)
|
||||
GeometryT& operator=(const Object& rhs)
|
||||
{
|
||||
return (*this = *rhs);
|
||||
}
|
||||
GeometryT& operator= (PyObject* rhsp)
|
||||
GeometryT& operator=(PyObject* rhsp)
|
||||
{
|
||||
if(ptr() == rhsp) return *this;
|
||||
set (rhsp, false);
|
||||
if (ptr() == rhsp) {
|
||||
return *this;
|
||||
}
|
||||
set(rhsp, false);
|
||||
return *this;
|
||||
}
|
||||
GeometryT& operator= (const T& v)
|
||||
GeometryT& operator=(const T& v)
|
||||
{
|
||||
set (new PyT(v), true);
|
||||
set(new PyT(v), true);
|
||||
return *this;
|
||||
}
|
||||
const T& getValue() const
|
||||
@@ -248,22 +270,20 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
static int Geometry_TypeCheck(PyObject * obj)
|
||||
static int Geometry_TypeCheck(PyObject* obj)
|
||||
{
|
||||
return PyObject_TypeCheck(obj, &(PyT::Type));
|
||||
}
|
||||
};
|
||||
|
||||
// PyCXX wrapper classes Py::Matrix, Py::Rotation, Py::Placement, ...
|
||||
using BoundingBox = GeometryT<Base::BoundBox3d, Base::BoundBoxPy,
|
||||
&Base::BoundBoxPy::getBoundBoxPtr>;
|
||||
using Matrix = GeometryT<Base::Matrix4D, Base::MatrixPy,
|
||||
&Base::MatrixPy::getMatrixPtr>;
|
||||
using Rotation = GeometryT<Base::Rotation, Base::RotationPy,
|
||||
&Base::RotationPy::getRotationPtr>;
|
||||
using Placement = GeometryT<Base::Placement, Base::PlacementPy,
|
||||
&Base::PlacementPy::getPlacementPtr>;
|
||||
using BoundingBox =
|
||||
GeometryT<Base::BoundBox3d, Base::BoundBoxPy, &Base::BoundBoxPy::getBoundBoxPtr>;
|
||||
using Matrix = GeometryT<Base::Matrix4D, Base::MatrixPy, &Base::MatrixPy::getMatrixPtr>;
|
||||
using Rotation = GeometryT<Base::Rotation, Base::RotationPy, &Base::RotationPy::getRotationPtr>;
|
||||
using Placement =
|
||||
GeometryT<Base::Placement, Base::PlacementPy, &Base::PlacementPy::getPlacementPtr>;
|
||||
|
||||
}
|
||||
} // namespace Py
|
||||
|
||||
#endif // PY_GEOMETRYPY_H
|
||||
#endif // PY_GEOMETRYPY_H
|
||||
|
||||
@@ -25,8 +25,8 @@
|
||||
#include "PreCompiled.h"
|
||||
|
||||
#ifndef _PreComp_
|
||||
# include <cassert>
|
||||
# include <iostream>
|
||||
#include <cassert>
|
||||
#include <iostream>
|
||||
#endif
|
||||
|
||||
#include <QAtomicInt>
|
||||
@@ -40,14 +40,14 @@ using namespace Base;
|
||||
// Construction/Destruction
|
||||
|
||||
Handled::Handled()
|
||||
: _lRefCount(new QAtomicInt(0))
|
||||
{
|
||||
}
|
||||
: _lRefCount(new QAtomicInt(0))
|
||||
{}
|
||||
|
||||
Handled::~Handled()
|
||||
{
|
||||
if (static_cast<int>(*_lRefCount) != 0)
|
||||
if (static_cast<int>(*_lRefCount) != 0) {
|
||||
std::cerr << "Reference counter of deleted object is not zero!!!!!" << std::endl;
|
||||
}
|
||||
delete _lRefCount;
|
||||
}
|
||||
|
||||
@@ -67,7 +67,7 @@ void Handled::unref() const
|
||||
int Handled::unrefNoDelete() const
|
||||
{
|
||||
int res = _lRefCount->deref();
|
||||
assert(res>=0);
|
||||
assert(res >= 0);
|
||||
return res;
|
||||
}
|
||||
|
||||
@@ -76,7 +76,7 @@ int Handled::getRefCount() const
|
||||
return static_cast<int>(*_lRefCount);
|
||||
}
|
||||
|
||||
Handled& Handled::operator = (const Handled&)
|
||||
Handled& Handled::operator=(const Handled&)
|
||||
{
|
||||
// we must not assign _lRefCount
|
||||
return *this;
|
||||
|
||||
@@ -40,7 +40,7 @@ namespace Base
|
||||
* Only able to instantiate with a class inheriting
|
||||
* Base::Handled.
|
||||
*/
|
||||
template <class T>
|
||||
template<class T>
|
||||
class Reference
|
||||
{
|
||||
public:
|
||||
@@ -48,18 +48,25 @@ public:
|
||||
// construction & destruction
|
||||
|
||||
/** Pointer and default constructor */
|
||||
Reference() : _toHandle(nullptr) {
|
||||
}
|
||||
Reference()
|
||||
: _toHandle(nullptr)
|
||||
{}
|
||||
|
||||
Reference(T* p) : _toHandle(p) {
|
||||
if (_toHandle)
|
||||
Reference(T* p)
|
||||
: _toHandle(p)
|
||||
{
|
||||
if (_toHandle) {
|
||||
_toHandle->ref();
|
||||
}
|
||||
}
|
||||
|
||||
/** Copy constructor */
|
||||
Reference(const Reference<T>& p) : _toHandle(p._toHandle) {
|
||||
if (_toHandle)
|
||||
Reference(const Reference<T>& p)
|
||||
: _toHandle(p._toHandle)
|
||||
{
|
||||
if (_toHandle) {
|
||||
_toHandle->ref();
|
||||
}
|
||||
}
|
||||
|
||||
/** destructor
|
||||
@@ -67,51 +74,64 @@ public:
|
||||
* in case of the last one, the referenced object to
|
||||
* be destructed!
|
||||
*/
|
||||
~Reference() {
|
||||
if (_toHandle)
|
||||
~Reference()
|
||||
{
|
||||
if (_toHandle) {
|
||||
_toHandle->unref();
|
||||
}
|
||||
}
|
||||
|
||||
//**************************************************************************
|
||||
// operator implementation
|
||||
|
||||
/** Assign operator from a pointer */
|
||||
Reference <T>& operator=(T* p) {
|
||||
Reference<T>& operator=(T* p)
|
||||
{
|
||||
// check if we want to reassign the same object
|
||||
if (_toHandle == p)
|
||||
if (_toHandle == p) {
|
||||
return *this;
|
||||
if (_toHandle)
|
||||
}
|
||||
if (_toHandle) {
|
||||
_toHandle->unref();
|
||||
}
|
||||
_toHandle = p;
|
||||
if (_toHandle)
|
||||
if (_toHandle) {
|
||||
_toHandle->ref();
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
/** Assign operator from a handle */
|
||||
Reference <T>& operator=(const Reference<T>& p) {
|
||||
Reference<T>& operator=(const Reference<T>& p)
|
||||
{
|
||||
// check if we want to reassign the same object
|
||||
if (_toHandle == p._toHandle)
|
||||
if (_toHandle == p._toHandle) {
|
||||
return *this;
|
||||
if (_toHandle)
|
||||
}
|
||||
if (_toHandle) {
|
||||
_toHandle->unref();
|
||||
}
|
||||
_toHandle = p._toHandle;
|
||||
if (_toHandle)
|
||||
if (_toHandle) {
|
||||
_toHandle->ref();
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
/** Dereference operator */
|
||||
T& operator*() const {
|
||||
T& operator*() const
|
||||
{
|
||||
return *_toHandle;
|
||||
}
|
||||
|
||||
/** Dereference operator */
|
||||
T* operator->() const {
|
||||
T* operator->() const
|
||||
{
|
||||
return _toHandle;
|
||||
}
|
||||
|
||||
operator T*() const {
|
||||
operator T*() const
|
||||
{
|
||||
return _toHandle;
|
||||
}
|
||||
|
||||
@@ -119,24 +139,28 @@ public:
|
||||
// checking on the state
|
||||
|
||||
/// Test if it handles something
|
||||
bool isValid() const {
|
||||
bool isValid() const
|
||||
{
|
||||
return _toHandle != nullptr;
|
||||
}
|
||||
|
||||
/// Test if it does not handle anything
|
||||
bool isNull() const {
|
||||
bool isNull() const
|
||||
{
|
||||
return _toHandle == nullptr;
|
||||
}
|
||||
|
||||
/// Get number of references on the object, including this one
|
||||
int getRefCount() const {
|
||||
if (_toHandle)
|
||||
int getRefCount() const
|
||||
{
|
||||
if (_toHandle) {
|
||||
return _toHandle->getRefCount();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
private:
|
||||
T *_toHandle; /** the pointer to the handled object */
|
||||
T* _toHandle; /** the pointer to the handled object */
|
||||
};
|
||||
|
||||
/** Handled class
|
||||
@@ -153,16 +177,16 @@ public:
|
||||
int unrefNoDelete() const;
|
||||
|
||||
int getRefCount() const;
|
||||
Handled& operator = (const Handled&);
|
||||
Handled& operator=(const Handled&);
|
||||
|
||||
Handled(const Handled&) = delete;
|
||||
Handled(Handled&&) = delete;
|
||||
Handled& operator = (Handled&&) = delete;
|
||||
Handled& operator=(Handled&&) = delete;
|
||||
|
||||
private:
|
||||
QAtomicInt* _lRefCount;
|
||||
};
|
||||
|
||||
} // namespace Base
|
||||
} // namespace Base
|
||||
|
||||
#endif // BASE_HANDLE_H
|
||||
#endif // BASE_HANDLE_H
|
||||
|
||||
@@ -50,15 +50,19 @@ using namespace std;
|
||||
struct StdInputStream::TextCodec
|
||||
{
|
||||
QTextCodec::ConverterState state;
|
||||
TextCodec() {
|
||||
TextCodec()
|
||||
{
|
||||
state.flags |= QTextCodec::IgnoreHeader;
|
||||
state.flags |= QTextCodec::ConvertInvalidToNull;
|
||||
}
|
||||
|
||||
void validateBytes(XMLByte* const toFill, std::streamsize len) {
|
||||
QTextCodec *textCodec = QTextCodec::codecForName("UTF-8");
|
||||
void validateBytes(XMLByte* const toFill, std::streamsize len)
|
||||
{
|
||||
QTextCodec* textCodec = QTextCodec::codecForName("UTF-8");
|
||||
if (textCodec) {
|
||||
const QString text = textCodec->toUnicode(reinterpret_cast<char *>(toFill), static_cast<int>(len), &state);
|
||||
const QString text = textCodec->toUnicode(reinterpret_cast<char*>(toFill),
|
||||
static_cast<int>(len),
|
||||
&state);
|
||||
if (state.invalidChars > 0) {
|
||||
// In case invalid characters were found decode back to 'utf-8' and replace
|
||||
// them with '?'
|
||||
@@ -67,7 +71,7 @@ struct StdInputStream::TextCodec
|
||||
// we have to go through the array and replace '\0' with '?'.
|
||||
std::streamsize pos = 0;
|
||||
QByteArray ba = textCodec->fromUnicode(text);
|
||||
for (int i=0; i<ba.length(); i++, pos++) {
|
||||
for (int i = 0; i < ba.length(); i++, pos++) {
|
||||
if (pos < len && ba[i] == '\0') {
|
||||
toFill[i] = '?';
|
||||
}
|
||||
@@ -79,8 +83,9 @@ struct StdInputStream::TextCodec
|
||||
#else
|
||||
struct StdInputStream::TextCodec
|
||||
{
|
||||
void validateBytes(XMLByte* const toFill, std::streamsize len) {
|
||||
QByteArray encodedString(reinterpret_cast<char *>(toFill), static_cast<int>(len));
|
||||
void validateBytes(XMLByte* const toFill, std::streamsize len)
|
||||
{
|
||||
QByteArray encodedString(reinterpret_cast<char*>(toFill), static_cast<int>(len));
|
||||
auto toUtf16 = QStringDecoder(QStringDecoder::Utf8);
|
||||
QString text = toUtf16(encodedString);
|
||||
if (toUtf16.hasError()) {
|
||||
@@ -92,7 +97,7 @@ struct StdInputStream::TextCodec
|
||||
std::streamsize pos = 0;
|
||||
auto fromUtf16 = QStringEncoder(QStringEncoder::Utf8);
|
||||
QByteArray ba = fromUtf16(text);
|
||||
for (int i=0; i<ba.length(); i++, pos++) {
|
||||
for (int i = 0; i < ba.length(); i++, pos++) {
|
||||
if (pos < len && ba[i] == '\0') {
|
||||
toFill[i] = '?';
|
||||
}
|
||||
@@ -102,9 +107,10 @@ struct StdInputStream::TextCodec
|
||||
};
|
||||
#endif
|
||||
|
||||
StdInputStream::StdInputStream( std::istream& Stream, XERCES_CPP_NAMESPACE_QUALIFIER MemoryManager* const manager )
|
||||
: stream(Stream)
|
||||
, codec(new TextCodec)
|
||||
StdInputStream::StdInputStream(std::istream& Stream,
|
||||
XERCES_CPP_NAMESPACE_QUALIFIER MemoryManager* const manager)
|
||||
: stream(Stream)
|
||||
, codec(new TextCodec)
|
||||
{
|
||||
(void)manager;
|
||||
}
|
||||
@@ -118,34 +124,37 @@ StdInputStream::~StdInputStream() = default;
|
||||
// ---------------------------------------------------------------------------
|
||||
XMLFilePos StdInputStream::curPos() const
|
||||
{
|
||||
return static_cast<XMLFilePos>(stream.tellg());
|
||||
return static_cast<XMLFilePos>(stream.tellg());
|
||||
}
|
||||
|
||||
XMLSize_t StdInputStream::readBytes(XMLByte* const toFill, const XMLSize_t maxToRead)
|
||||
XMLSize_t StdInputStream::readBytes(XMLByte* const toFill, const XMLSize_t maxToRead)
|
||||
{
|
||||
//
|
||||
// Read up to the maximum bytes requested. We return the number
|
||||
// actually read.
|
||||
//
|
||||
//
|
||||
// Read up to the maximum bytes requested. We return the number
|
||||
// actually read.
|
||||
//
|
||||
|
||||
stream.read(reinterpret_cast<char *>(toFill), static_cast<std::streamsize>(maxToRead));
|
||||
std::streamsize len = stream.gcount();
|
||||
stream.read(reinterpret_cast<char*>(toFill), static_cast<std::streamsize>(maxToRead));
|
||||
std::streamsize len = stream.gcount();
|
||||
|
||||
codec->validateBytes(toFill, len);
|
||||
codec->validateBytes(toFill, len);
|
||||
|
||||
return static_cast<XMLSize_t>(len);
|
||||
return static_cast<XMLSize_t>(len);
|
||||
}
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// StdInputSource: Constructors and Destructor
|
||||
// ---------------------------------------------------------------------------
|
||||
StdInputSource::StdInputSource ( std::istream& Stream, const char* filePath, XERCES_CPP_NAMESPACE_QUALIFIER MemoryManager* const manager )
|
||||
: InputSource(manager),stream(Stream)
|
||||
StdInputSource::StdInputSource(std::istream& Stream,
|
||||
const char* filePath,
|
||||
XERCES_CPP_NAMESPACE_QUALIFIER MemoryManager* const manager)
|
||||
: InputSource(manager)
|
||||
, stream(Stream)
|
||||
{
|
||||
// we have to set the file name in case an error occurs
|
||||
XStr tmpBuf(filePath);
|
||||
setSystemId(tmpBuf.unicodeForm());
|
||||
// we have to set the file name in case an error occurs
|
||||
XStr tmpBuf(filePath);
|
||||
setSystemId(tmpBuf.unicodeForm());
|
||||
}
|
||||
|
||||
|
||||
@@ -157,7 +166,6 @@ StdInputSource::~StdInputSource() = default;
|
||||
// ---------------------------------------------------------------------------
|
||||
BinInputStream* StdInputSource::makeStream() const
|
||||
{
|
||||
StdInputStream* retStrm = new StdInputStream(stream /*, getMemoryManager()*/);
|
||||
return retStrm;
|
||||
StdInputStream* retStrm = new StdInputStream(stream /*, getMemoryManager()*/);
|
||||
return retStrm;
|
||||
}
|
||||
|
||||
|
||||
@@ -34,61 +34,69 @@
|
||||
|
||||
|
||||
XERCES_CPP_NAMESPACE_BEGIN
|
||||
class BinInputStream;
|
||||
class BinInputStream;
|
||||
XERCES_CPP_NAMESPACE_END
|
||||
|
||||
namespace Base
|
||||
{
|
||||
|
||||
|
||||
class BaseExport StdInputStream : public XERCES_CPP_NAMESPACE_QUALIFIER BinInputStream
|
||||
class BaseExport StdInputStream: public XERCES_CPP_NAMESPACE_QUALIFIER BinInputStream
|
||||
{
|
||||
public :
|
||||
StdInputStream ( std::istream& Stream, XERCES_CPP_NAMESPACE_QUALIFIER MemoryManager* const manager = XERCES_CPP_NAMESPACE_QUALIFIER XMLPlatformUtils::fgMemoryManager );
|
||||
~StdInputStream() override;
|
||||
public:
|
||||
StdInputStream(std::istream& Stream,
|
||||
XERCES_CPP_NAMESPACE_QUALIFIER MemoryManager* const manager =
|
||||
XERCES_CPP_NAMESPACE_QUALIFIER XMLPlatformUtils::fgMemoryManager);
|
||||
~StdInputStream() override;
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Implementation of the input stream interface
|
||||
// -----------------------------------------------------------------------
|
||||
XMLFilePos curPos() const override;
|
||||
XMLSize_t readBytes( XMLByte* const toFill, const XMLSize_t maxToRead ) override;
|
||||
const XMLCh* getContentType() const override {return nullptr;}
|
||||
// -----------------------------------------------------------------------
|
||||
// Implementation of the input stream interface
|
||||
// -----------------------------------------------------------------------
|
||||
XMLFilePos curPos() const override;
|
||||
XMLSize_t readBytes(XMLByte* const toFill, const XMLSize_t maxToRead) override;
|
||||
const XMLCh* getContentType() const override
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Unimplemented constructors and operators
|
||||
// -----------------------------------------------------------------------
|
||||
StdInputStream(const StdInputStream&) = delete;
|
||||
StdInputStream& operator=(const StdInputStream&) = delete;
|
||||
|
||||
private :
|
||||
// -----------------------------------------------------------------------
|
||||
// Private data members
|
||||
//
|
||||
// fSource
|
||||
// The source file that we represent. The FileHandle type is defined
|
||||
// per platform.
|
||||
// -----------------------------------------------------------------------
|
||||
std::istream &stream;
|
||||
struct TextCodec;
|
||||
std::unique_ptr<TextCodec> codec;
|
||||
};
|
||||
|
||||
|
||||
class BaseExport StdInputSource : public XERCES_CPP_NAMESPACE_QUALIFIER InputSource
|
||||
{
|
||||
public :
|
||||
StdInputSource ( std::istream& Stream, const char* filePath, XERCES_CPP_NAMESPACE_QUALIFIER MemoryManager* const manager = XERCES_CPP_NAMESPACE_QUALIFIER XMLPlatformUtils::fgMemoryManager );
|
||||
~StdInputSource() override;
|
||||
|
||||
XERCES_CPP_NAMESPACE_QUALIFIER BinInputStream* makeStream() const override;
|
||||
|
||||
StdInputSource(const StdInputSource&) = delete;
|
||||
StdInputSource& operator=(const StdInputSource&) = delete;
|
||||
// -----------------------------------------------------------------------
|
||||
// Unimplemented constructors and operators
|
||||
// -----------------------------------------------------------------------
|
||||
StdInputStream(const StdInputStream&) = delete;
|
||||
StdInputStream& operator=(const StdInputStream&) = delete;
|
||||
|
||||
private:
|
||||
std::istream &stream;
|
||||
// -----------------------------------------------------------------------
|
||||
// Private data members
|
||||
//
|
||||
// fSource
|
||||
// The source file that we represent. The FileHandle type is defined
|
||||
// per platform.
|
||||
// -----------------------------------------------------------------------
|
||||
std::istream& stream;
|
||||
struct TextCodec;
|
||||
std::unique_ptr<TextCodec> codec;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // BASE_IINPUTSOURCE_H
|
||||
class BaseExport StdInputSource: public XERCES_CPP_NAMESPACE_QUALIFIER InputSource
|
||||
{
|
||||
public:
|
||||
StdInputSource(std::istream& Stream,
|
||||
const char* filePath,
|
||||
XERCES_CPP_NAMESPACE_QUALIFIER MemoryManager* const manager =
|
||||
XERCES_CPP_NAMESPACE_QUALIFIER XMLPlatformUtils::fgMemoryManager);
|
||||
~StdInputSource() override;
|
||||
|
||||
XERCES_CPP_NAMESPACE_QUALIFIER BinInputStream* makeStream() const override;
|
||||
|
||||
StdInputSource(const StdInputSource&) = delete;
|
||||
StdInputSource& operator=(const StdInputSource&) = delete;
|
||||
|
||||
private:
|
||||
std::istream& stream;
|
||||
};
|
||||
|
||||
} // namespace Base
|
||||
|
||||
#endif // BASE_IINPUTSOURCE_H
|
||||
|
||||
@@ -25,8 +25,8 @@
|
||||
#include "PreCompiled.h"
|
||||
|
||||
#ifndef _PreComp_
|
||||
# include <sstream>
|
||||
# include <boost/regex.hpp>
|
||||
#include <sstream>
|
||||
#include <boost/regex.hpp>
|
||||
#endif
|
||||
|
||||
#include "Interpreter.h"
|
||||
@@ -38,12 +38,13 @@
|
||||
#include "Stream.h"
|
||||
|
||||
|
||||
char format2[1024]; //Warning! Can't go over 512 characters!!!
|
||||
char format2[1024]; // Warning! Can't go over 512 characters!!!
|
||||
unsigned int format2_len = 1024;
|
||||
|
||||
using namespace Base;
|
||||
|
||||
PyException::PyException(const Py::Object &obj) {
|
||||
PyException::PyException(const Py::Object& obj)
|
||||
{
|
||||
_sErrMsg = obj.as_string();
|
||||
// WARNING: we are assuming that python type object will never be
|
||||
// destroyed, so we don't keep reference here to save book-keeping in
|
||||
@@ -56,12 +57,12 @@ PyException::PyException(const Py::Object &obj) {
|
||||
|
||||
PyException::PyException()
|
||||
{
|
||||
PP_Fetch_Error_Text(); /* fetch (and clear) exception */
|
||||
PP_Fetch_Error_Text(); /* fetch (and clear) exception */
|
||||
|
||||
setPyObject(PP_PyDict_Object);
|
||||
|
||||
std::string prefix = PP_last_error_type; /* exception name text */
|
||||
std::string error = PP_last_error_info; /* exception data text */
|
||||
std::string error = PP_last_error_info; /* exception data text */
|
||||
|
||||
_sErrMsg = error;
|
||||
_errorType = prefix;
|
||||
@@ -75,16 +76,15 @@ PyException::PyException()
|
||||
// our copy constructor and destructor
|
||||
Py_DECREF(PP_last_exception_type);
|
||||
PP_last_exception_type = nullptr;
|
||||
|
||||
}
|
||||
|
||||
_stackTrace = PP_last_error_trace; /* exception traceback text */
|
||||
_stackTrace = PP_last_error_trace; /* exception traceback text */
|
||||
|
||||
// This should be done in the constructor because when doing
|
||||
// in the destructor it's not always clear when it is called
|
||||
// and thus may clear a Python exception when it should not.
|
||||
PyGILStateLocker locker;
|
||||
PyErr_Clear(); // must be called to keep Python interpreter in a valid state (Werner)
|
||||
PyErr_Clear(); // must be called to keep Python interpreter in a valid state (Werner)
|
||||
}
|
||||
|
||||
PyException::~PyException() noexcept = default;
|
||||
@@ -96,7 +96,8 @@ void PyException::ThrowException()
|
||||
myexcp.raiseException();
|
||||
}
|
||||
|
||||
void PyException::raiseException() {
|
||||
void PyException::raiseException()
|
||||
{
|
||||
PyGILStateLocker locker;
|
||||
if (PP_PyDict_Object) {
|
||||
// delete the Python dict upon destruction of edict
|
||||
@@ -104,11 +105,12 @@ void PyException::raiseException() {
|
||||
PP_PyDict_Object = nullptr;
|
||||
|
||||
std::string exceptionname;
|
||||
if (_exceptionType == Base::PyExc_FC_FreeCADAbort)
|
||||
edict.setItem("sclassname",
|
||||
Py::String(typeid(Base::AbortException).name()));
|
||||
if (_isReported)
|
||||
if (_exceptionType == Base::PyExc_FC_FreeCADAbort) {
|
||||
edict.setItem("sclassname", Py::String(typeid(Base::AbortException).name()));
|
||||
}
|
||||
if (_isReported) {
|
||||
edict.setItem("breported", Py::True());
|
||||
}
|
||||
Base::ExceptionFactory::Instance().raiseException(edict.ptr());
|
||||
}
|
||||
|
||||
@@ -121,24 +123,25 @@ void PyException::raiseException() {
|
||||
throw *this;
|
||||
}
|
||||
|
||||
void PyException::ReportException () const
|
||||
void PyException::ReportException() const
|
||||
{
|
||||
if (!_isReported) {
|
||||
_isReported = true;
|
||||
// set sys.last_vars to make post-mortem debugging work
|
||||
PyGILStateLocker locker;
|
||||
PySys_SetObject("last_traceback", PP_last_traceback);
|
||||
Base::Console().DeveloperError("pyException","%s%s: %s\n",
|
||||
_stackTrace.c_str(), _errorType.c_str(), what());
|
||||
Base::Console().DeveloperError("pyException",
|
||||
"%s%s: %s\n",
|
||||
_stackTrace.c_str(),
|
||||
_errorType.c_str(),
|
||||
what());
|
||||
}
|
||||
}
|
||||
|
||||
void PyException::setPyException() const
|
||||
{
|
||||
std::stringstream str;
|
||||
str << getStackTrace()
|
||||
<< getErrorType()
|
||||
<< ": " << what();
|
||||
str << getStackTrace() << getErrorType() << ": " << what();
|
||||
PyErr_SetString(getPyExceptionType(), str.str().c_str());
|
||||
}
|
||||
|
||||
@@ -156,8 +159,8 @@ SystemExitException::SystemExitException()
|
||||
// sys.exit() | 1 | "System Exit"
|
||||
|
||||
long int errCode = 1;
|
||||
std::string errMsg = "System exit";
|
||||
PyObject *type{}, *value{}, *traceback{}, *code{};
|
||||
std::string errMsg = "System exit";
|
||||
PyObject *type {}, *value {}, *traceback {}, *code {};
|
||||
|
||||
PyGILStateLocker locker;
|
||||
PyErr_Fetch(&type, &value, &traceback);
|
||||
@@ -166,21 +169,22 @@ SystemExitException::SystemExitException()
|
||||
if (value) {
|
||||
code = PyObject_GetAttrString(value, "code");
|
||||
if (code && value != Py_None) {
|
||||
Py_DECREF(value);
|
||||
value = code;
|
||||
Py_DECREF(value);
|
||||
value = code;
|
||||
}
|
||||
|
||||
if (PyLong_Check(value)) {
|
||||
errCode = PyLong_AsLong(value);
|
||||
}
|
||||
else {
|
||||
const char *str = PyUnicode_AsUTF8(value);
|
||||
if (str)
|
||||
const char* str = PyUnicode_AsUTF8(value);
|
||||
if (str) {
|
||||
errMsg = errMsg + ": " + str;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_sErrMsg = errMsg;
|
||||
_sErrMsg = errMsg;
|
||||
_exitCode = errCode;
|
||||
}
|
||||
|
||||
@@ -188,15 +192,15 @@ SystemExitException::SystemExitException()
|
||||
|
||||
// Fixes #0000831: python print causes File descriptor error on windows
|
||||
// NOLINTNEXTLINE
|
||||
class PythonStdOutput : public Py::PythonExtension<PythonStdOutput>
|
||||
class PythonStdOutput: public Py::PythonExtension<PythonStdOutput>
|
||||
{
|
||||
public:
|
||||
static void init_type()
|
||||
{
|
||||
behaviors().name("PythonStdOutput");
|
||||
behaviors().doc("Python standard output");
|
||||
add_varargs_method("write",&PythonStdOutput::write,"write()");
|
||||
add_varargs_method("flush",&PythonStdOutput::flush,"flush()");
|
||||
add_varargs_method("write", &PythonStdOutput::write, "write()");
|
||||
add_varargs_method("flush", &PythonStdOutput::flush, "flush()");
|
||||
}
|
||||
|
||||
PythonStdOutput() = default;
|
||||
@@ -222,26 +226,29 @@ InterpreterSingleton::InterpreterSingleton()
|
||||
InterpreterSingleton::~InterpreterSingleton() = default;
|
||||
|
||||
|
||||
std::string InterpreterSingleton::runString(const char *sCmd)
|
||||
std::string InterpreterSingleton::runString(const char* sCmd)
|
||||
{
|
||||
PyObject *module{}, *dict{}, *presult{}; /* "exec code in d, d" */
|
||||
PyObject *module {}, *dict {}, *presult {}; /* "exec code in d, d" */
|
||||
|
||||
PyGILStateLocker locker;
|
||||
module = PP_Load_Module("__main__"); /* get module, init python */
|
||||
if (!module)
|
||||
throw PyException(); /* not incref'd */
|
||||
dict = PyModule_GetDict(module); /* get dict namespace */
|
||||
if (!dict)
|
||||
throw PyException(); /* not incref'd */
|
||||
module = PP_Load_Module("__main__"); /* get module, init python */
|
||||
if (!module) {
|
||||
throw PyException(); /* not incref'd */
|
||||
}
|
||||
dict = PyModule_GetDict(module); /* get dict namespace */
|
||||
if (!dict) {
|
||||
throw PyException(); /* not incref'd */
|
||||
}
|
||||
|
||||
|
||||
presult = PyRun_String(sCmd, Py_file_input, dict, dict); /* eval direct */
|
||||
if (!presult) {
|
||||
if (PyErr_ExceptionMatches(PyExc_SystemExit))
|
||||
if (PyErr_ExceptionMatches(PyExc_SystemExit)) {
|
||||
throw SystemExitException();
|
||||
}
|
||||
else {
|
||||
PyException::ThrowException();
|
||||
return {}; // just to quieten code analyzers
|
||||
return {}; // just to quieten code analyzers
|
||||
}
|
||||
}
|
||||
|
||||
@@ -268,7 +275,9 @@ std::string InterpreterSingleton::runString(const char *sCmd)
|
||||
* if the error occurs after changing it inside the script.
|
||||
*/
|
||||
|
||||
std::string InterpreterSingleton::runStringWithKey(const char *psCmd, const char *key, const char *key_initial_value)
|
||||
std::string InterpreterSingleton::runStringWithKey(const char* psCmd,
|
||||
const char* key,
|
||||
const char* key_initial_value)
|
||||
{
|
||||
PyGILStateLocker locker;
|
||||
Py::Module module("__main__");
|
||||
@@ -277,46 +286,52 @@ std::string InterpreterSingleton::runStringWithKey(const char *psCmd, const char
|
||||
Py::String initial_value(key_initial_value);
|
||||
localDictionary.setItem(key, initial_value);
|
||||
|
||||
PyObject* presult = PyRun_String(psCmd, Py_file_input, globalDictionary.ptr(), localDictionary.ptr());
|
||||
PyObject* presult =
|
||||
PyRun_String(psCmd, Py_file_input, globalDictionary.ptr(), localDictionary.ptr());
|
||||
if (!presult) {
|
||||
if (PyErr_ExceptionMatches(PyExc_SystemExit)) {
|
||||
throw SystemExitException();
|
||||
}
|
||||
else {
|
||||
PyException::ThrowException();
|
||||
return {}; // just to quieten code analyzers
|
||||
return {}; // just to quieten code analyzers
|
||||
}
|
||||
}
|
||||
Py_DECREF(presult);
|
||||
|
||||
Py::Object key_return_value = localDictionary.getItem(key);
|
||||
if (!key_return_value.isString())
|
||||
if (!key_return_value.isString()) {
|
||||
key_return_value = key_return_value.str();
|
||||
}
|
||||
|
||||
Py::Bytes str = Py::String(key_return_value).encode("utf-8", "~E~");
|
||||
std::string result = static_cast<std::string>(str);
|
||||
return result;
|
||||
}
|
||||
|
||||
Py::Object InterpreterSingleton::runStringObject(const char *sCmd)
|
||||
Py::Object InterpreterSingleton::runStringObject(const char* sCmd)
|
||||
{
|
||||
PyObject *module{}, *dict{}, *presult{}; /* "exec code in d, d" */
|
||||
PyObject *module {}, *dict {}, *presult {}; /* "exec code in d, d" */
|
||||
|
||||
PyGILStateLocker locker;
|
||||
module = PP_Load_Module("__main__"); /* get module, init python */
|
||||
if (!module)
|
||||
throw PyException(); /* not incref'd */
|
||||
dict = PyModule_GetDict(module); /* get dict namespace */
|
||||
if (!dict)
|
||||
throw PyException(); /* not incref'd */
|
||||
module = PP_Load_Module("__main__"); /* get module, init python */
|
||||
if (!module) {
|
||||
throw PyException(); /* not incref'd */
|
||||
}
|
||||
dict = PyModule_GetDict(module); /* get dict namespace */
|
||||
if (!dict) {
|
||||
throw PyException(); /* not incref'd */
|
||||
}
|
||||
|
||||
|
||||
presult = PyRun_String(sCmd, Py_eval_input, dict, dict); /* eval direct */
|
||||
if (!presult) {
|
||||
if (PyErr_ExceptionMatches(PyExc_SystemExit))
|
||||
if (PyErr_ExceptionMatches(PyExc_SystemExit)) {
|
||||
throw SystemExitException();
|
||||
else
|
||||
}
|
||||
else {
|
||||
throw PyException();
|
||||
}
|
||||
}
|
||||
|
||||
return Py::asObject(presult);
|
||||
@@ -325,21 +340,23 @@ Py::Object InterpreterSingleton::runStringObject(const char *sCmd)
|
||||
void InterpreterSingleton::systemExit()
|
||||
{
|
||||
/* This code is taken from the original Python code */
|
||||
PyObject *exception{}, *value{}, *tb{};
|
||||
PyObject *exception {}, *value {}, *tb {};
|
||||
int exitcode = 0;
|
||||
|
||||
PyErr_Fetch(&exception, &value, &tb);
|
||||
fflush(stdout);
|
||||
if (!value || value == Py_None)
|
||||
goto done; // NOLINT
|
||||
if (!value || value == Py_None) {
|
||||
goto done; // NOLINT
|
||||
}
|
||||
if (PyExceptionInstance_Check(value)) {
|
||||
/* The error code should be in the `code' attribute. */
|
||||
PyObject *code = PyObject_GetAttrString(value, "code");
|
||||
PyObject* code = PyObject_GetAttrString(value, "code");
|
||||
if (code) {
|
||||
Py_DECREF(value);
|
||||
value = code;
|
||||
if (value == Py_None)
|
||||
goto done; // NOLINT
|
||||
if (value == Py_None) {
|
||||
goto done; // NOLINT
|
||||
}
|
||||
}
|
||||
/* If we failed to dig out the 'code' attribute,
|
||||
just let the else clause below print the error. */
|
||||
@@ -364,17 +381,19 @@ done:
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
void InterpreterSingleton::runInteractiveString(const char *sCmd)
|
||||
void InterpreterSingleton::runInteractiveString(const char* sCmd)
|
||||
{
|
||||
PyObject *module{}, *dict{}, *presult{}; /* "exec code in d, d" */
|
||||
PyObject *module {}, *dict {}, *presult {}; /* "exec code in d, d" */
|
||||
|
||||
PyGILStateLocker locker;
|
||||
module = PP_Load_Module("__main__"); /* get module, init python */
|
||||
if (!module)
|
||||
throw PyException(); /* not incref'd */
|
||||
dict = PyModule_GetDict(module); /* get dict namespace */
|
||||
if (!dict)
|
||||
throw PyException(); /* not incref'd */
|
||||
module = PP_Load_Module("__main__"); /* get module, init python */
|
||||
if (!module) {
|
||||
throw PyException(); /* not incref'd */
|
||||
}
|
||||
dict = PyModule_GetDict(module); /* get dict namespace */
|
||||
if (!dict) {
|
||||
throw PyException(); /* not incref'd */
|
||||
}
|
||||
|
||||
presult = PyRun_String(sCmd, Py_single_input, dict, dict); /* eval direct */
|
||||
if (!presult) {
|
||||
@@ -383,45 +402,48 @@ void InterpreterSingleton::runInteractiveString(const char *sCmd)
|
||||
}
|
||||
/* get latest python exception information */
|
||||
/* and print the error to the error output */
|
||||
PyObject *errobj{}, *errdata{}, *errtraceback{};
|
||||
PyObject *errobj {}, *errdata {}, *errtraceback {};
|
||||
PyErr_Fetch(&errobj, &errdata, &errtraceback);
|
||||
|
||||
RuntimeError exc(""); // do not use PyException since this clears the error indicator
|
||||
RuntimeError exc(""); // do not use PyException since this clears the error indicator
|
||||
if (errdata) {
|
||||
if (PyUnicode_Check(errdata))
|
||||
if (PyUnicode_Check(errdata)) {
|
||||
exc.setMessage(PyUnicode_AsUTF8(errdata));
|
||||
}
|
||||
}
|
||||
PyErr_Restore(errobj, errdata, errtraceback);
|
||||
if (PyErr_Occurred())
|
||||
if (PyErr_Occurred()) {
|
||||
PyErr_Print();
|
||||
}
|
||||
throw exc;
|
||||
}
|
||||
else
|
||||
else {
|
||||
Py_DECREF(presult);
|
||||
}
|
||||
}
|
||||
|
||||
void InterpreterSingleton::runFile(const char*pxFileName, bool local)
|
||||
void InterpreterSingleton::runFile(const char* pxFileName, bool local)
|
||||
{
|
||||
#ifdef FC_OS_WIN32
|
||||
FileInfo fi(pxFileName);
|
||||
FILE *fp = _wfopen(fi.toStdWString().c_str(),L"r");
|
||||
FILE* fp = _wfopen(fi.toStdWString().c_str(), L"r");
|
||||
#else
|
||||
FILE *fp = fopen(pxFileName,"r");
|
||||
FILE* fp = fopen(pxFileName, "r");
|
||||
#endif
|
||||
if (fp) {
|
||||
PyGILStateLocker locker;
|
||||
PyObject *module{}, *dict{};
|
||||
PyObject *module {}, *dict {};
|
||||
module = PyImport_AddModule("__main__");
|
||||
dict = PyModule_GetDict(module);
|
||||
if (local) {
|
||||
dict = PyDict_Copy(dict);
|
||||
}
|
||||
else {
|
||||
Py_INCREF(dict); // avoid to further distinguish between local and global dict
|
||||
Py_INCREF(dict); // avoid to further distinguish between local and global dict
|
||||
}
|
||||
|
||||
if (!PyDict_GetItemString(dict, "__file__")) {
|
||||
PyObject *pyObj = PyUnicode_FromString(pxFileName);
|
||||
PyObject* pyObj = PyUnicode_FromString(pxFileName);
|
||||
if (!pyObj) {
|
||||
fclose(fp);
|
||||
Py_DECREF(dict);
|
||||
@@ -436,15 +458,17 @@ void InterpreterSingleton::runFile(const char*pxFileName, bool local)
|
||||
Py_DECREF(pyObj);
|
||||
}
|
||||
|
||||
PyObject *result = PyRun_File(fp, pxFileName, Py_file_input, dict, dict);
|
||||
PyObject* result = PyRun_File(fp, pxFileName, Py_file_input, dict, dict);
|
||||
fclose(fp);
|
||||
Py_DECREF(dict);
|
||||
|
||||
if (!result) {
|
||||
if (PyErr_ExceptionMatches(PyExc_SystemExit))
|
||||
if (PyErr_ExceptionMatches(PyExc_SystemExit)) {
|
||||
throw SystemExitException();
|
||||
else
|
||||
}
|
||||
else {
|
||||
throw PyException();
|
||||
}
|
||||
}
|
||||
Py_DECREF(result);
|
||||
}
|
||||
@@ -456,17 +480,19 @@ void InterpreterSingleton::runFile(const char*pxFileName, bool local)
|
||||
bool InterpreterSingleton::loadModule(const char* psModName)
|
||||
{
|
||||
// buffer acrobatics
|
||||
//PyBuf ModName(psModName);
|
||||
PyObject *module{};
|
||||
// PyBuf ModName(psModName);
|
||||
PyObject* module {};
|
||||
|
||||
PyGILStateLocker locker;
|
||||
module = PP_Load_Module(psModName);
|
||||
|
||||
if (!module) {
|
||||
if (PyErr_ExceptionMatches(PyExc_SystemExit))
|
||||
if (PyErr_ExceptionMatches(PyExc_SystemExit)) {
|
||||
throw SystemExitException();
|
||||
else
|
||||
}
|
||||
else {
|
||||
throw PyException();
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -482,22 +508,23 @@ void InterpreterSingleton::cleanupModules()
|
||||
{
|
||||
// This is only needed to make the address sanitizer happy
|
||||
#if defined(__has_feature)
|
||||
# if __has_feature(address_sanitizer)
|
||||
#if __has_feature(address_sanitizer)
|
||||
for (auto it : _modules) {
|
||||
delete it;
|
||||
}
|
||||
_modules.clear();
|
||||
# endif
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
void InterpreterSingleton::addType(PyTypeObject* Type,PyObject* Module, const char * Name)
|
||||
void InterpreterSingleton::addType(PyTypeObject* Type, PyObject* Module, const char* Name)
|
||||
{
|
||||
// NOTE: To finish the initialization of our own type objects we must
|
||||
// call PyType_Ready, otherwise we run into a segmentation fault, later on.
|
||||
// This function is responsible for adding inherited slots from a type's base class.
|
||||
if (PyType_Ready(Type) < 0)
|
||||
if (PyType_Ready(Type) < 0) {
|
||||
return;
|
||||
}
|
||||
PyModule_AddObject(Module, Name, Base::getTypeAsObject(Type));
|
||||
}
|
||||
|
||||
@@ -509,14 +536,14 @@ void InterpreterSingleton::addPythonPath(const char* Path)
|
||||
}
|
||||
|
||||
#if PY_VERSION_HEX < 0x030b0000
|
||||
const char* InterpreterSingleton::init(int argc,char *argv[])
|
||||
const char* InterpreterSingleton::init(int argc, char* argv[])
|
||||
{
|
||||
if (!Py_IsInitialized()) {
|
||||
Py_SetProgramName(Py_DecodeLocale(argv[0],nullptr));
|
||||
// There is a serious bug in VS from 2010 until 2013 where the file descriptor for stdin, stdout or stderr
|
||||
// returns a valid value for GUI applications (i.e. subsystem = Windows) where it shouldn't.
|
||||
// This causes Python to fail during initialization.
|
||||
// A workaround is to use freopen on stdin, stdout and stderr. See the class Redirection inside main()
|
||||
Py_SetProgramName(Py_DecodeLocale(argv[0], nullptr));
|
||||
// There is a serious bug in VS from 2010 until 2013 where the file descriptor for stdin,
|
||||
// stdout or stderr returns a valid value for GUI applications (i.e. subsystem = Windows)
|
||||
// where it shouldn't. This causes Python to fail during initialization. A workaround is to
|
||||
// use freopen on stdin, stdout and stderr. See the class Redirection inside main()
|
||||
// https://bugs.python.org/issue17797#msg197474
|
||||
//
|
||||
Py_Initialize();
|
||||
@@ -524,14 +551,15 @@ const char* InterpreterSingleton::init(int argc,char *argv[])
|
||||
if (virtualenv) {
|
||||
PyRun_SimpleString(
|
||||
"# Check for virtualenv, and activate if present.\n"
|
||||
"# See https://virtualenv.pypa.io/en/latest/userguide/#using-virtualenv-without-bin-python\n"
|
||||
"# See "
|
||||
"https://virtualenv.pypa.io/en/latest/userguide/"
|
||||
"#using-virtualenv-without-bin-python\n"
|
||||
"import os\n"
|
||||
"import sys\n"
|
||||
"base_path = os.getenv(\"VIRTUAL_ENV\")\n"
|
||||
"if not base_path is None:\n"
|
||||
" activate_this = os.path.join(base_path, \"bin\", \"activate_this.py\")\n"
|
||||
" exec(open(activate_this).read(), {'__file__':activate_this})\n"
|
||||
);
|
||||
" exec(open(activate_this).read(), {'__file__':activate_this})\n");
|
||||
}
|
||||
|
||||
#if PY_VERSION_HEX < 0x03090000
|
||||
@@ -539,9 +567,9 @@ const char* InterpreterSingleton::init(int argc,char *argv[])
|
||||
#endif
|
||||
|
||||
size_t size = argc;
|
||||
static std::vector<wchar_t *> _argv(size);
|
||||
static std::vector<wchar_t*> _argv(size);
|
||||
for (int i = 0; i < argc; i++) {
|
||||
_argv[i] = Py_DecodeLocale(argv[i],nullptr);
|
||||
_argv[i] = Py_DecodeLocale(argv[i], nullptr);
|
||||
}
|
||||
PySys_SetArgv(argc, _argv.data());
|
||||
PythonStdOutput::init_type();
|
||||
@@ -549,11 +577,12 @@ const char* InterpreterSingleton::init(int argc,char *argv[])
|
||||
}
|
||||
|
||||
PyGILStateLocker lock;
|
||||
return Py_EncodeLocale(Py_GetPath(),nullptr);
|
||||
return Py_EncodeLocale(Py_GetPath(), nullptr);
|
||||
}
|
||||
#else
|
||||
namespace {
|
||||
void initInterpreter(int argc,char *argv[])
|
||||
namespace
|
||||
{
|
||||
void initInterpreter(int argc, char* argv[])
|
||||
{
|
||||
PyStatus status;
|
||||
PyConfig config;
|
||||
@@ -576,18 +605,18 @@ void initInterpreter(int argc,char *argv[])
|
||||
if (virtualenv) {
|
||||
PyRun_SimpleString(
|
||||
"# Check for virtualenv, and activate if present.\n"
|
||||
"# See https://virtualenv.pypa.io/en/latest/userguide/#using-virtualenv-without-bin-python\n"
|
||||
"# See "
|
||||
"https://virtualenv.pypa.io/en/latest/userguide/#using-virtualenv-without-bin-python\n"
|
||||
"import os\n"
|
||||
"import sys\n"
|
||||
"base_path = os.getenv(\"VIRTUAL_ENV\")\n"
|
||||
"if not base_path is None:\n"
|
||||
" activate_this = os.path.join(base_path, \"bin\", \"activate_this.py\")\n"
|
||||
" exec(open(activate_this).read(), {'__file__':activate_this})\n"
|
||||
);
|
||||
" exec(open(activate_this).read(), {'__file__':activate_this})\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
const char* InterpreterSingleton::init(int argc,char *argv[])
|
||||
} // namespace
|
||||
const char* InterpreterSingleton::init(int argc, char* argv[])
|
||||
{
|
||||
try {
|
||||
if (!Py_IsInitialized()) {
|
||||
@@ -598,7 +627,7 @@ const char* InterpreterSingleton::init(int argc,char *argv[])
|
||||
}
|
||||
|
||||
PyGILStateLocker lock;
|
||||
return Py_EncodeLocale(Py_GetPath(),nullptr);
|
||||
return Py_EncodeLocale(Py_GetPath(), nullptr);
|
||||
}
|
||||
catch (const Base::Exception& e) {
|
||||
e.ReportException();
|
||||
@@ -617,7 +646,7 @@ void InterpreterSingleton::replaceStdOutput()
|
||||
|
||||
int InterpreterSingleton::cleanup(void (*func)())
|
||||
{
|
||||
return Py_AtExit( func );
|
||||
return Py_AtExit(func);
|
||||
}
|
||||
|
||||
void InterpreterSingleton::finalize()
|
||||
@@ -631,14 +660,14 @@ void InterpreterSingleton::finalize()
|
||||
}
|
||||
}
|
||||
|
||||
void InterpreterSingleton::runStringArg(const char * psCom,...)
|
||||
void InterpreterSingleton::runStringArg(const char* psCom, ...)
|
||||
{
|
||||
// va stuff
|
||||
va_list namelessVars;
|
||||
va_start(namelessVars, psCom); // Get the "..." vars
|
||||
int len = vsnprintf(format2, format2_len, psCom, namelessVars);
|
||||
va_end(namelessVars);
|
||||
if ( len == -1 ) {
|
||||
if (len == -1) {
|
||||
// argument too long
|
||||
assert(false);
|
||||
}
|
||||
@@ -649,13 +678,14 @@ void InterpreterSingleton::runStringArg(const char * psCom,...)
|
||||
|
||||
// Singleton:
|
||||
|
||||
InterpreterSingleton * InterpreterSingleton::_pcSingleton = nullptr;
|
||||
InterpreterSingleton* InterpreterSingleton::_pcSingleton = nullptr;
|
||||
|
||||
InterpreterSingleton & InterpreterSingleton::Instance()
|
||||
InterpreterSingleton& InterpreterSingleton::Instance()
|
||||
{
|
||||
// not initialized!
|
||||
if (!_pcSingleton)
|
||||
if (!_pcSingleton) {
|
||||
_pcSingleton = new InterpreterSingleton();
|
||||
}
|
||||
return *_pcSingleton;
|
||||
}
|
||||
|
||||
@@ -667,7 +697,7 @@ void InterpreterSingleton::Destruct()
|
||||
_pcSingleton = nullptr;
|
||||
}
|
||||
|
||||
int InterpreterSingleton::runCommandLine(const char *prompt)
|
||||
int InterpreterSingleton::runCommandLine(const char* prompt)
|
||||
{
|
||||
PyGILStateLocker locker;
|
||||
return PP_Run_Command_Line(prompt);
|
||||
@@ -677,51 +707,57 @@ int InterpreterSingleton::runCommandLine(const char *prompt)
|
||||
* Runs a member method of an object with no parameter and no return value
|
||||
* void (void). There are other methods to run with returns
|
||||
*/
|
||||
void InterpreterSingleton::runMethodVoid(PyObject *pobject, const char *method)
|
||||
void InterpreterSingleton::runMethodVoid(PyObject* pobject, const char* method)
|
||||
{
|
||||
PyGILStateLocker locker;
|
||||
if (PP_Run_Method(pobject , // object
|
||||
method, // run method
|
||||
nullptr, // no return type
|
||||
nullptr, // so no return object
|
||||
"()") // no arguments
|
||||
!= 0)
|
||||
if (PP_Run_Method(pobject, // object
|
||||
method, // run method
|
||||
nullptr, // no return type
|
||||
nullptr, // so no return object
|
||||
"()") // no arguments
|
||||
!= 0) {
|
||||
throw PyException(/*"Error running InterpreterSingleton::RunMethodVoid()"*/);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
PyObject* InterpreterSingleton::runMethodObject(PyObject *pobject, const char *method)
|
||||
PyObject* InterpreterSingleton::runMethodObject(PyObject* pobject, const char* method)
|
||||
{
|
||||
PyObject *pcO{};
|
||||
PyObject* pcO {};
|
||||
|
||||
PyGILStateLocker locker;
|
||||
if (PP_Run_Method(pobject , // object
|
||||
method, // run method
|
||||
"O", // return type
|
||||
&pcO, // return object
|
||||
"()") // no arguments
|
||||
!= 0)
|
||||
if (PP_Run_Method(pobject, // object
|
||||
method, // run method
|
||||
"O", // return type
|
||||
&pcO, // return object
|
||||
"()") // no arguments
|
||||
!= 0) {
|
||||
throw PyException();
|
||||
}
|
||||
|
||||
return pcO;
|
||||
}
|
||||
|
||||
void InterpreterSingleton::runMethod(PyObject *pobject, const char *method,
|
||||
const char *resfmt, void *cresult, /* convert to c/c++ */
|
||||
const char *argfmt, ... ) /* convert to python */
|
||||
void InterpreterSingleton::runMethod(PyObject* pobject,
|
||||
const char* method,
|
||||
const char* resfmt,
|
||||
void* cresult, /* convert to c/c++ */
|
||||
const char* argfmt,
|
||||
...) /* convert to python */
|
||||
{
|
||||
PyObject *pmeth{}, *pargs{}, *presult{};
|
||||
va_list argslist; /* "pobject.method(args)" */
|
||||
PyObject *pmeth {}, *pargs {}, *presult {};
|
||||
va_list argslist; /* "pobject.method(args)" */
|
||||
va_start(argslist, argfmt);
|
||||
|
||||
PyGILStateLocker locker;
|
||||
pmeth = PyObject_GetAttrString(pobject, method);
|
||||
if (!pmeth) { /* get callable object */
|
||||
if (!pmeth) { /* get callable object */
|
||||
va_end(argslist);
|
||||
throw AttributeError("Error running InterpreterSingleton::RunMethod() method not defined"); /* bound method? has self */
|
||||
throw AttributeError(
|
||||
"Error running InterpreterSingleton::RunMethod() method not defined"); /* bound method?
|
||||
has self */
|
||||
}
|
||||
|
||||
pargs = Py_VaBuildValue(argfmt, argslist); /* args: c->python */
|
||||
pargs = Py_VaBuildValue(argfmt, argslist); /* args: c->python */
|
||||
va_end(argslist);
|
||||
|
||||
if (!pargs) {
|
||||
@@ -730,31 +766,35 @@ void InterpreterSingleton::runMethod(PyObject *pobject, const char *method,
|
||||
}
|
||||
|
||||
#if PY_VERSION_HEX < 0x03090000
|
||||
presult = PyEval_CallObject(pmeth, pargs); /* run interpreter */
|
||||
presult = PyEval_CallObject(pmeth, pargs); /* run interpreter */
|
||||
#else
|
||||
presult = PyObject_CallObject(pmeth, pargs); /* run interpreter */
|
||||
presult = PyObject_CallObject(pmeth, pargs); /* run interpreter */
|
||||
#endif
|
||||
|
||||
Py_DECREF(pmeth);
|
||||
Py_DECREF(pargs);
|
||||
if (PP_Convert_Result(presult, resfmt, cresult)!= 0) {
|
||||
if ( PyErr_Occurred() )
|
||||
if (PP_Convert_Result(presult, resfmt, cresult) != 0) {
|
||||
if (PyErr_Occurred()) {
|
||||
PyErr_Print();
|
||||
throw RuntimeError("Error running InterpreterSingleton::RunMethod() exception in called method");
|
||||
}
|
||||
throw RuntimeError(
|
||||
"Error running InterpreterSingleton::RunMethod() exception in called method");
|
||||
}
|
||||
}
|
||||
|
||||
PyObject * InterpreterSingleton::getValue(const char * key, const char * result_var)
|
||||
PyObject* InterpreterSingleton::getValue(const char* key, const char* result_var)
|
||||
{
|
||||
PyObject *module{}, *dict{}, *presult{}; /* "exec code in d, d" */
|
||||
PyObject *module {}, *dict {}, *presult {}; /* "exec code in d, d" */
|
||||
|
||||
PyGILStateLocker locker;
|
||||
module = PP_Load_Module("__main__"); /* get module, init python */
|
||||
if (!module)
|
||||
throw PyException(); /* not incref'd */
|
||||
dict = PyModule_GetDict(module); /* get dict namespace */
|
||||
if (!dict)
|
||||
throw PyException(); /* not incref'd */
|
||||
module = PP_Load_Module("__main__"); /* get module, init python */
|
||||
if (!module) {
|
||||
throw PyException(); /* not incref'd */
|
||||
}
|
||||
dict = PyModule_GetDict(module); /* get dict namespace */
|
||||
if (!dict) {
|
||||
throw PyException(); /* not incref'd */
|
||||
}
|
||||
|
||||
|
||||
presult = PyRun_String(key, Py_file_input, dict, dict); /* eval direct */
|
||||
@@ -768,45 +808,41 @@ PyObject * InterpreterSingleton::getValue(const char * key, const char * result_
|
||||
|
||||
void InterpreterSingleton::dbgObserveFile(const char* sFileName)
|
||||
{
|
||||
if (sFileName)
|
||||
if (sFileName) {
|
||||
_cDebugFileName = sFileName;
|
||||
else
|
||||
}
|
||||
else {
|
||||
_cDebugFileName = "";
|
||||
}
|
||||
}
|
||||
|
||||
void InterpreterSingleton::dbgSetBreakPoint(unsigned int /*uiLineNumber*/)
|
||||
{
|
||||
|
||||
}
|
||||
{}
|
||||
|
||||
void InterpreterSingleton::dbgUnsetBreakPoint(unsigned int /*uiLineNumber*/)
|
||||
{
|
||||
|
||||
}
|
||||
{}
|
||||
|
||||
void InterpreterSingleton::dbgStep()
|
||||
{
|
||||
|
||||
}
|
||||
{}
|
||||
|
||||
const std::string InterpreterSingleton::strToPython(const char* Str)
|
||||
{
|
||||
std::string result;
|
||||
const char *It=Str;
|
||||
const char* It = Str;
|
||||
|
||||
while (*It != '\0') {
|
||||
switch (*It) {
|
||||
case '\\':
|
||||
result += "\\\\";
|
||||
break;
|
||||
case '\"':
|
||||
result += "\\\"";
|
||||
break;
|
||||
case '\'':
|
||||
result += "\\\'";
|
||||
break;
|
||||
default:
|
||||
result += *It;
|
||||
case '\\':
|
||||
result += "\\\\";
|
||||
break;
|
||||
case '\"':
|
||||
result += "\\\"";
|
||||
break;
|
||||
case '\'':
|
||||
result += "\\\'";
|
||||
break;
|
||||
default:
|
||||
result += *It;
|
||||
}
|
||||
It++;
|
||||
}
|
||||
@@ -827,8 +863,9 @@ int getSWIGVersionFromModule(const std::string& module)
|
||||
try {
|
||||
// Get the module and check its __file__ attribute
|
||||
Py::Dict dict(PyImport_GetModuleDict());
|
||||
if (!dict.hasKey(module))
|
||||
if (!dict.hasKey(module)) {
|
||||
return 0;
|
||||
}
|
||||
Py::Module mod(module);
|
||||
Py::String file(mod.getAttr("__file__"));
|
||||
std::string filename = (std::string)file;
|
||||
@@ -847,7 +884,7 @@ int getSWIGVersionFromModule(const std::string& module)
|
||||
int major = std::atoi(what[1].first);
|
||||
int minor = std::atoi(what[2].first);
|
||||
int micro = std::atoi(what[3].first);
|
||||
int version = (major<<16)+(minor<<8)+micro;
|
||||
int version = (major << 16) + (minor << 8) + micro;
|
||||
moduleMap[module] = version;
|
||||
return version;
|
||||
}
|
||||
@@ -865,18 +902,22 @@ int getSWIGVersionFromModule(const std::string& module)
|
||||
}
|
||||
|
||||
#if (defined(HAVE_SWIG) && (HAVE_SWIG == 1))
|
||||
namespace Swig_python {
|
||||
namespace Swig_python
|
||||
{
|
||||
extern int createSWIGPointerObj_T(const char* TypeName, void* obj, PyObject** ptr, int own);
|
||||
extern int convertSWIGPointerObj_T(const char* TypeName, PyObject* obj, void** ptr, int flags);
|
||||
extern void cleanupSWIG_T(const char* TypeName);
|
||||
extern int getSWIGPointerTypeObj_T(const char* TypeName, PyTypeObject** ptr);
|
||||
}
|
||||
} // namespace Swig_python
|
||||
#endif
|
||||
|
||||
PyObject* InterpreterSingleton::createSWIGPointerObj(const char* Module, const char* TypeName, void* Pointer, int own)
|
||||
PyObject* InterpreterSingleton::createSWIGPointerObj(const char* Module,
|
||||
const char* TypeName,
|
||||
void* Pointer,
|
||||
int own)
|
||||
{
|
||||
int result = 0;
|
||||
PyObject* proxy=nullptr;
|
||||
PyObject* proxy = nullptr;
|
||||
PyGILStateLocker locker;
|
||||
(void)Module;
|
||||
#if (defined(HAVE_SWIG) && (HAVE_SWIG == 1))
|
||||
@@ -885,17 +926,22 @@ PyObject* InterpreterSingleton::createSWIGPointerObj(const char* Module, const c
|
||||
(void)TypeName;
|
||||
(void)Pointer;
|
||||
(void)own;
|
||||
result = -1; // indicates error
|
||||
result = -1; // indicates error
|
||||
#endif
|
||||
|
||||
if (result == 0)
|
||||
if (result == 0) {
|
||||
return proxy;
|
||||
}
|
||||
|
||||
// none of the SWIG's succeeded
|
||||
throw Base::RuntimeError("No SWIG wrapped library loaded");
|
||||
}
|
||||
|
||||
bool InterpreterSingleton::convertSWIGPointerObj(const char* Module, const char* TypeName, PyObject* obj, void** ptr, int flags)
|
||||
bool InterpreterSingleton::convertSWIGPointerObj(const char* Module,
|
||||
const char* TypeName,
|
||||
PyObject* obj,
|
||||
void** ptr,
|
||||
int flags)
|
||||
{
|
||||
int result = 0;
|
||||
PyGILStateLocker locker;
|
||||
@@ -907,11 +953,12 @@ bool InterpreterSingleton::convertSWIGPointerObj(const char* Module, const char*
|
||||
(void)obj;
|
||||
(void)ptr;
|
||||
(void)flags;
|
||||
result = -1; // indicates error
|
||||
result = -1; // indicates error
|
||||
#endif
|
||||
|
||||
if (result == 0)
|
||||
if (result == 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// none of the SWIG's succeeded
|
||||
throw Base::RuntimeError("No SWIG wrapped library loaded");
|
||||
@@ -937,11 +984,12 @@ PyTypeObject* InterpreterSingleton::getSWIGPointerTypeObj(const char* Module, co
|
||||
result = Swig_python::getSWIGPointerTypeObj_T(TypeName, &proxy);
|
||||
#else
|
||||
(void)TypeName;
|
||||
result = -1; // indicates error
|
||||
result = -1; // indicates error
|
||||
#endif
|
||||
|
||||
if (result == 0)
|
||||
if (result == 0) {
|
||||
return proxy;
|
||||
}
|
||||
|
||||
// none of the SWIG's succeeded
|
||||
throw Base::RuntimeError("No SWIG wrapped library loaded");
|
||||
|
||||
@@ -24,12 +24,12 @@
|
||||
#ifndef BASE_INTERPRETER_H
|
||||
#define BASE_INTERPRETER_H
|
||||
|
||||
#if defined (_POSIX_C_SOURCE)
|
||||
# undef _POSIX_C_SOURCE
|
||||
#endif // (re-)defined in pyconfig.h
|
||||
#if defined (_XOPEN_SOURCE)
|
||||
# undef _XOPEN_SOURCE
|
||||
#endif // (re-)defined in pyconfig.h
|
||||
#if defined(_POSIX_C_SOURCE)
|
||||
#undef _POSIX_C_SOURCE
|
||||
#endif // (re-)defined in pyconfig.h
|
||||
#if defined(_XOPEN_SOURCE)
|
||||
#undef _XOPEN_SOURCE
|
||||
#endif // (re-)defined in pyconfig.h
|
||||
|
||||
#ifdef FC_OS_MACOSX
|
||||
#undef toupper
|
||||
@@ -55,15 +55,15 @@
|
||||
*
|
||||
* See FeaturePythonImp::init() for example usage
|
||||
*/
|
||||
#define FC_PY_GetCallable(_pyobj,_name,_var) \
|
||||
do {\
|
||||
_var = Py::Object();\
|
||||
if(PyObject_HasAttrString(_pyobj, _name)) {\
|
||||
Py::Object _obj(PyObject_GetAttrString (_pyobj, _name), true);\
|
||||
if(_obj.isCallable())\
|
||||
_var = _obj;\
|
||||
}\
|
||||
}while(0)
|
||||
#define FC_PY_GetCallable(_pyobj, _name, _var) \
|
||||
do { \
|
||||
_var = Py::Object(); \
|
||||
if (PyObject_HasAttrString(_pyobj, _name)) { \
|
||||
Py::Object _obj(PyObject_GetAttrString(_pyobj, _name), true); \
|
||||
if (_obj.isCallable()) \
|
||||
_var = _obj; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
/** Helper macro to obtain attribute from an object
|
||||
*
|
||||
@@ -73,26 +73,27 @@
|
||||
*
|
||||
* See FeaturePythonImp::init() for example usage
|
||||
*/
|
||||
#define FC_PY_GetObject(_pyobj,_name,_var) \
|
||||
do {\
|
||||
_var = Py::Object();\
|
||||
if(PyObject_HasAttrString(_pyobj, _name))\
|
||||
_var = Py::asObject(PyObject_GetAttrString (_pyobj, _name));\
|
||||
}while(0)
|
||||
#define FC_PY_GetObject(_pyobj, _name, _var) \
|
||||
do { \
|
||||
_var = Py::Object(); \
|
||||
if (PyObject_HasAttrString(_pyobj, _name)) \
|
||||
_var = Py::asObject(PyObject_GetAttrString(_pyobj, _name)); \
|
||||
} while (0)
|
||||
|
||||
|
||||
namespace Base {
|
||||
namespace Base
|
||||
{
|
||||
|
||||
using std::string;
|
||||
using std::vector;
|
||||
using std::string;
|
||||
using std::vector;
|
||||
|
||||
|
||||
class BaseExport PyException : public Exception
|
||||
class BaseExport PyException: public Exception
|
||||
{
|
||||
public:
|
||||
/// constructor does the whole job
|
||||
PyException();
|
||||
PyException(const Py::Object &obj);
|
||||
PyException(const Py::Object& obj);
|
||||
~PyException() noexcept override;
|
||||
|
||||
void raiseException();
|
||||
@@ -103,30 +104,43 @@ public:
|
||||
static void ThrowException();
|
||||
|
||||
/// this function returns the stack trace
|
||||
const std::string &getStackTrace() const {return _stackTrace;}
|
||||
const std::string &getErrorType() const {return _errorType;}
|
||||
PyObject *getPyExceptionType() const override {return _exceptionType;}
|
||||
void ReportException () const override;
|
||||
const std::string& getStackTrace() const
|
||||
{
|
||||
return _stackTrace;
|
||||
}
|
||||
const std::string& getErrorType() const
|
||||
{
|
||||
return _errorType;
|
||||
}
|
||||
PyObject* getPyExceptionType() const override
|
||||
{
|
||||
return _exceptionType;
|
||||
}
|
||||
void ReportException() const override;
|
||||
/// Sets the Python error indicator and an error message
|
||||
void setPyException() const override;
|
||||
|
||||
protected:
|
||||
std::string _stackTrace;
|
||||
std::string _errorType;
|
||||
PyObject *_exceptionType;
|
||||
PyObject* _exceptionType;
|
||||
};
|
||||
|
||||
inline Py::Object pyCall(PyObject *callable, PyObject *args=nullptr) {
|
||||
PyObject *result = PyObject_CallObject(callable, args);
|
||||
if(!result)
|
||||
inline Py::Object pyCall(PyObject* callable, PyObject* args = nullptr)
|
||||
{
|
||||
PyObject* result = PyObject_CallObject(callable, args);
|
||||
if (!result) {
|
||||
throw Py::Exception();
|
||||
}
|
||||
return Py::asObject(result);
|
||||
}
|
||||
|
||||
inline Py::Object pyCallWithKeywords(PyObject *callable, PyObject *args, PyObject *kwds=nullptr) {
|
||||
PyObject *result = PyObject_Call(callable, args, kwds);
|
||||
if(!result)
|
||||
inline Py::Object pyCallWithKeywords(PyObject* callable, PyObject* args, PyObject* kwds = nullptr)
|
||||
{
|
||||
PyObject* result = PyObject_Call(callable, args, kwds);
|
||||
if (!result) {
|
||||
throw Py::Exception();
|
||||
}
|
||||
return Py::asObject(result);
|
||||
}
|
||||
|
||||
@@ -135,12 +149,15 @@ inline Py::Object pyCallWithKeywords(PyObject *callable, PyObject *args, PyObjec
|
||||
* was thrown.
|
||||
* @author Werner Mayer
|
||||
*/
|
||||
class BaseExport SystemExitException : public Exception
|
||||
class BaseExport SystemExitException: public Exception
|
||||
{
|
||||
public:
|
||||
SystemExitException();
|
||||
~SystemExitException() noexcept override = default;
|
||||
long getExitCode() const { return _exitCode;}
|
||||
long getExitCode() const
|
||||
{
|
||||
return _exitCode;
|
||||
}
|
||||
|
||||
protected:
|
||||
long _exitCode;
|
||||
@@ -210,26 +227,32 @@ public:
|
||||
/** @name execution methods
|
||||
*/
|
||||
//@{
|
||||
/// Run a statement on the python interpreter and gives back a string with the representation of the result.
|
||||
std::string runString(const char *psCmd);
|
||||
/// Run a statement on the python interpreter and gives back a string with the representation of
|
||||
/// the result.
|
||||
std::string runString(const char* psCmd);
|
||||
/// Run a statement on the python interpreter with a key for exchanging strings
|
||||
std::string runStringWithKey(const char *psCmd, const char *key, const char *key_initial_value="");
|
||||
std::string
|
||||
runStringWithKey(const char* psCmd, const char* key, const char* key_initial_value = "");
|
||||
/// Run a statement on the python interpreter and return back the result object.
|
||||
Py::Object runStringObject(const char *sCmd);
|
||||
/// Run a statement on the python interpreter and gives back a string with the representation of the result.
|
||||
void runInteractiveString(const char *psCmd);
|
||||
Py::Object runStringObject(const char* sCmd);
|
||||
/// Run a statement on the python interpreter and gives back a string with the representation of
|
||||
/// the result.
|
||||
void runInteractiveString(const char* psCmd);
|
||||
/// Run file (script) on the python interpreter
|
||||
void runFile(const char*pxFileName, bool local);
|
||||
void runFile(const char* pxFileName, bool local);
|
||||
/// Run a statement with arguments on the python interpreter
|
||||
void runStringArg(const char * psCom,...);
|
||||
void runStringArg(const char* psCom, ...);
|
||||
/// runs a python object method with no return value and no arguments
|
||||
void runMethodVoid(PyObject *pobject, const char *method);
|
||||
void runMethodVoid(PyObject* pobject, const char* method);
|
||||
/// runs a python object method which returns a arbitrary object
|
||||
PyObject* runMethodObject(PyObject *pobject, const char *method);
|
||||
PyObject* runMethodObject(PyObject* pobject, const char* method);
|
||||
/// runs a python method with arbitrary params
|
||||
void runMethod(PyObject *pobject, const char *method,
|
||||
const char *resfmt=nullptr, void *cresult=nullptr,
|
||||
const char *argfmt="()", ... );
|
||||
void runMethod(PyObject* pobject,
|
||||
const char* method,
|
||||
const char* resfmt = nullptr,
|
||||
void* cresult = nullptr,
|
||||
const char* argfmt = "()",
|
||||
...);
|
||||
//@}
|
||||
|
||||
/** @name Module handling
|
||||
@@ -240,7 +263,7 @@ public:
|
||||
bool loadModule(const char* psModName);
|
||||
/// Add an additional python path
|
||||
void addPythonPath(const char* Path);
|
||||
static void addType(PyTypeObject* Type,PyObject* Module, const char * Name);
|
||||
static void addType(PyTypeObject* Type, PyObject* Module, const char* Name);
|
||||
/// Add a module and return a PyObject to it
|
||||
PyObject* addModule(Py::ExtensionModuleBase*);
|
||||
/// Clean-up registered modules
|
||||
@@ -250,11 +273,12 @@ public:
|
||||
/** @name Cleanup
|
||||
*/
|
||||
//@{
|
||||
/** Register a cleanup function to be called by finalize(). The cleanup function will be called with no
|
||||
* arguments and should return no value. At most 32 cleanup functions can be registered. When the registration
|
||||
* is successful 0 is returned; on failure -1 is returned. The cleanup function registered last is called
|
||||
* first. Each cleanup function will be called at most once. Since Python's internal finalization will have
|
||||
* completed before the cleanup function, no Python APIs should be called by \a func.
|
||||
/** Register a cleanup function to be called by finalize(). The cleanup function will be called
|
||||
* with no arguments and should return no value. At most 32 cleanup functions can be registered.
|
||||
* When the registration is successful 0 is returned; on failure -1 is returned. The cleanup
|
||||
* function registered last is called first. Each cleanup function will be called at most once.
|
||||
* Since Python's internal finalization will have completed before the cleanup function, no
|
||||
* Python APIs should be called by \a func.
|
||||
*/
|
||||
int cleanup(void (*func)());
|
||||
/** This calls the registered cleanup functions. @see cleanup() for more details. */
|
||||
@@ -267,10 +291,10 @@ public:
|
||||
*/
|
||||
//@{
|
||||
/// init the interpreter and returns the module search path
|
||||
const char* init(int argc,char *argv[]);
|
||||
int runCommandLine(const char *prompt);
|
||||
const char* init(int argc, char* argv[]);
|
||||
int runCommandLine(const char* prompt);
|
||||
void replaceStdOutput();
|
||||
static InterpreterSingleton &Instance();
|
||||
static InterpreterSingleton& Instance();
|
||||
static void Destruct();
|
||||
//@}
|
||||
|
||||
@@ -280,8 +304,13 @@ public:
|
||||
*/
|
||||
//@{
|
||||
/// generate a SWIG object
|
||||
PyObject* createSWIGPointerObj(const char* Modole, const char* TypeName, void* Pointer, int own);
|
||||
bool convertSWIGPointerObj(const char* Module, const char* TypeName, PyObject* obj, void** ptr, int flags);
|
||||
PyObject*
|
||||
createSWIGPointerObj(const char* Modole, const char* TypeName, void* Pointer, int own);
|
||||
bool convertSWIGPointerObj(const char* Module,
|
||||
const char* TypeName,
|
||||
PyObject* obj,
|
||||
void** ptr,
|
||||
int flags);
|
||||
void cleanupSWIG(const char* TypeName);
|
||||
PyTypeObject* getSWIGPointerTypeObj(const char* Module, const char* TypeName);
|
||||
//@}
|
||||
@@ -290,7 +319,7 @@ public:
|
||||
*/
|
||||
//@{
|
||||
/// sets the file name which should be debugged
|
||||
void dbgObserveFile(const char* sFileName="");
|
||||
void dbgObserveFile(const char* sFileName = "");
|
||||
/// sets a break point to a special line number in the current file
|
||||
void dbgSetBreakPoint(unsigned int uiLineNumber);
|
||||
/// unsets a break point to a special line number in the current file
|
||||
@@ -305,14 +334,17 @@ public:
|
||||
//@{
|
||||
/// replaces all char with escapes for usage in python console
|
||||
static const std::string strToPython(const char* Str);
|
||||
static const std::string strToPython(const std::string &Str){return strToPython(Str.c_str());}
|
||||
static const std::string strToPython(const std::string& Str)
|
||||
{
|
||||
return strToPython(Str.c_str());
|
||||
}
|
||||
//@}
|
||||
|
||||
PyObject *getValue(const char *key, const char *result_var);
|
||||
PyObject* getValue(const char* key, const char* result_var);
|
||||
|
||||
protected:
|
||||
// singleton
|
||||
static InterpreterSingleton *_pcSingleton;
|
||||
static InterpreterSingleton* _pcSingleton;
|
||||
|
||||
private:
|
||||
std::string _cDebugFileName;
|
||||
@@ -325,11 +357,11 @@ private:
|
||||
* This method is used to gain access to the one and only instance of
|
||||
* the InterpreterSingleton class.
|
||||
*/
|
||||
inline InterpreterSingleton &Interpreter()
|
||||
inline InterpreterSingleton& Interpreter()
|
||||
{
|
||||
return InterpreterSingleton::Instance();
|
||||
}
|
||||
|
||||
} //namespace Base
|
||||
} // namespace Base
|
||||
|
||||
#endif // BASE_INTERPRETER_H
|
||||
#endif // BASE_INTERPRETER_H
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -33,9 +33,11 @@
|
||||
#endif
|
||||
|
||||
|
||||
namespace Base {
|
||||
namespace Base
|
||||
{
|
||||
|
||||
enum class ScaleType {
|
||||
enum class ScaleType
|
||||
{
|
||||
Other = -1,
|
||||
NoScaling = 0,
|
||||
NonUniformRight = 1,
|
||||
@@ -46,7 +48,7 @@ enum class ScaleType {
|
||||
/**
|
||||
* The Matrix4D class.
|
||||
*/
|
||||
class BaseExport Matrix4D //NOLINT(cppcoreguidelines-special-member-functions)
|
||||
class BaseExport Matrix4D // NOLINT(cppcoreguidelines-special-member-functions)
|
||||
{
|
||||
using traits_type = float_traits<double>;
|
||||
|
||||
@@ -57,53 +59,55 @@ public:
|
||||
*/
|
||||
Matrix4D();
|
||||
|
||||
// clang-format off
|
||||
/// Construction
|
||||
Matrix4D (float a11, float a12, float a13, float a14,
|
||||
float a21, float a22, float a23, float a24,
|
||||
float a31, float a32, float a33, float a34,
|
||||
float a41, float a42, float a43, float a44 );
|
||||
Matrix4D(float a11, float a12, float a13, float a14,
|
||||
float a21, float a22, float a23, float a24,
|
||||
float a31, float a32, float a33, float a34,
|
||||
float a41, float a42, float a43, float a44);
|
||||
/// Construction
|
||||
Matrix4D (double a11, double a12, double a13, double a14,
|
||||
double a21, double a22, double a23, double a24,
|
||||
double a31, double a32, double a33, double a34,
|
||||
double a41, double a42, double a43, double a44 );
|
||||
Matrix4D(double a11, double a12, double a13, double a14,
|
||||
double a21, double a22, double a23, double a24,
|
||||
double a31, double a32, double a33, double a34,
|
||||
double a41, double a42, double a43, double a44);
|
||||
// clang-format on
|
||||
/// Construction
|
||||
Matrix4D (const Matrix4D& mat);
|
||||
Matrix4D(const Matrix4D& mat);
|
||||
/// Construction with an Axis
|
||||
Matrix4D (const Vector3f& rclBase, const Vector3f& rclDir, float fAngle);
|
||||
Matrix4D (const Vector3d& rclBase, const Vector3d& rclDir, double fAngle);
|
||||
Matrix4D(const Vector3f& rclBase, const Vector3f& rclDir, float fAngle);
|
||||
Matrix4D(const Vector3d& rclBase, const Vector3d& rclDir, double fAngle);
|
||||
/// Destruction
|
||||
~Matrix4D () = default;
|
||||
~Matrix4D() = default;
|
||||
|
||||
/** @name Operators */
|
||||
//@{
|
||||
/// Matrix addition
|
||||
inline Matrix4D operator + (const Matrix4D& mat) const;
|
||||
inline Matrix4D& operator += (const Matrix4D& mat);
|
||||
inline Matrix4D operator+(const Matrix4D& mat) const;
|
||||
inline Matrix4D& operator+=(const Matrix4D& mat);
|
||||
/// Matrix subtraction
|
||||
inline Matrix4D operator - (const Matrix4D& mat) const;
|
||||
inline Matrix4D& operator -= (const Matrix4D& mat);
|
||||
inline Matrix4D operator-(const Matrix4D& mat) const;
|
||||
inline Matrix4D& operator-=(const Matrix4D& mat);
|
||||
/// Matrix multiplication
|
||||
inline Matrix4D& operator *= (const Matrix4D& mat);
|
||||
inline Matrix4D& operator*=(const Matrix4D& mat);
|
||||
/// Assignment
|
||||
inline Matrix4D& operator = (const Matrix4D& mat);
|
||||
inline Matrix4D& operator=(const Matrix4D& mat);
|
||||
/// Matrix multiplication
|
||||
inline Matrix4D operator * (const Matrix4D& mat) const;
|
||||
inline Matrix4D operator*(const Matrix4D& mat) const;
|
||||
/// Multiplication matrix with vector
|
||||
inline Vector3f operator * (const Vector3f& vec) const;
|
||||
inline Vector3d operator * (const Vector3d& vec) const;
|
||||
inline void multVec(const Vector3d & src, Vector3d & dst) const;
|
||||
inline void multVec(const Vector3f & src, Vector3f & dst) const;
|
||||
inline Matrix4D operator * (double) const;
|
||||
inline Matrix4D& operator *= (double);
|
||||
inline Vector3f operator*(const Vector3f& vec) const;
|
||||
inline Vector3d operator*(const Vector3d& vec) const;
|
||||
inline void multVec(const Vector3d& src, Vector3d& dst) const;
|
||||
inline void multVec(const Vector3f& src, Vector3f& dst) const;
|
||||
inline Matrix4D operator*(double) const;
|
||||
inline Matrix4D& operator*=(double);
|
||||
/// Comparison
|
||||
inline bool operator != (const Matrix4D& mat) const;
|
||||
inline bool operator!=(const Matrix4D& mat) const;
|
||||
/// Comparison
|
||||
inline bool operator == (const Matrix4D& mat) const;
|
||||
inline bool operator==(const Matrix4D& mat) const;
|
||||
/// Index operator
|
||||
inline double* operator [] (unsigned short usNdx);
|
||||
inline double* operator[](unsigned short usNdx);
|
||||
/// Index operator
|
||||
inline const double* operator[] (unsigned short usNdx) const;
|
||||
inline const double* operator[](unsigned short usNdx) const;
|
||||
/// Get vector of row
|
||||
inline Vector3d getRow(unsigned short usNdx) const;
|
||||
/// Get vector of column
|
||||
@@ -134,14 +138,14 @@ public:
|
||||
Matrix4D& Hat(const Vector3d& rV);
|
||||
//@}
|
||||
|
||||
void getMatrix (double dMtrx[16]) const;
|
||||
void setMatrix (const double dMtrx[16]);
|
||||
void getMatrix(double dMtrx[16]) const;
|
||||
void setMatrix(const double dMtrx[16]);
|
||||
/// get the matrix in OpenGL style
|
||||
void getGLMatrix (double dMtrx[16]) const;
|
||||
void getGLMatrix(double dMtrx[16]) const;
|
||||
/// set the matrix in OpenGL style
|
||||
void setGLMatrix (const double dMtrx[16]);
|
||||
void setGLMatrix(const double dMtrx[16]);
|
||||
|
||||
unsigned long getMemSpace ();
|
||||
unsigned long getMemSpace();
|
||||
|
||||
/** @name Manipulation */
|
||||
//@{
|
||||
@@ -156,72 +160,85 @@ public:
|
||||
/// Checks if this is the null matrix
|
||||
bool isNull() const;
|
||||
/// moves the coordinatesystem for the x,y,z value
|
||||
void move (float x, float y, float z)
|
||||
{ move(Vector3f(x,y,z)); }
|
||||
void move (double x, double y, double z)
|
||||
{ move(Vector3d(x,y,z)); }
|
||||
void move(float x, float y, float z)
|
||||
{
|
||||
move(Vector3f(x, y, z));
|
||||
}
|
||||
void move(double x, double y, double z)
|
||||
{
|
||||
move(Vector3d(x, y, z));
|
||||
}
|
||||
/// moves the coordinatesystem for the vector
|
||||
void move (const Vector3f& vec);
|
||||
void move (const Vector3d& vec);
|
||||
void move(const Vector3f& vec);
|
||||
void move(const Vector3d& vec);
|
||||
/// scale for the vector
|
||||
void scale (float x, float y, float z)
|
||||
{ scale(Vector3f(x,y,z)); }
|
||||
void scale (double x, double y, double z)
|
||||
{ scale(Vector3d(x,y,z)); }
|
||||
void scale(float x, float y, float z)
|
||||
{
|
||||
scale(Vector3f(x, y, z));
|
||||
}
|
||||
void scale(double x, double y, double z)
|
||||
{
|
||||
scale(Vector3d(x, y, z));
|
||||
}
|
||||
/// scale for the x,y,z value
|
||||
void scale (const Vector3f& vec);
|
||||
void scale (const Vector3d& vec);
|
||||
void scale(const Vector3f& vec);
|
||||
void scale(const Vector3d& vec);
|
||||
/// uniform scale
|
||||
void scale (float scalexyz)
|
||||
{ scale(Vector3f(scalexyz, scalexyz, scalexyz)); }
|
||||
void scale (double scalexyz)
|
||||
{ scale(Vector3d(scalexyz, scalexyz, scalexyz)); }
|
||||
void scale(float scalexyz)
|
||||
{
|
||||
scale(Vector3f(scalexyz, scalexyz, scalexyz));
|
||||
}
|
||||
void scale(double scalexyz)
|
||||
{
|
||||
scale(Vector3d(scalexyz, scalexyz, scalexyz));
|
||||
}
|
||||
/// Check for scaling factor
|
||||
ScaleType hasScale(double tol=0.0) const;
|
||||
ScaleType hasScale(double tol = 0.0) const;
|
||||
/// Decompose matrix into pure shear, scale, rotation and move
|
||||
std::array<Matrix4D, 4> decompose() const;
|
||||
/// Rotate around the X axis (in transformed space) for the given value in radians
|
||||
void rotX (double fAngle);
|
||||
void rotX(double fAngle);
|
||||
/// Rotate around the Y axis (in transformed space) for the given value in radians
|
||||
void rotY (double fAngle);
|
||||
void rotY(double fAngle);
|
||||
/// Rotate around the Z axis (in transformed space) for the given value in radians
|
||||
void rotZ (double fAngle);
|
||||
void rotZ(double fAngle);
|
||||
/// Rotate around an arbitrary axis passing the origin in radians
|
||||
void rotLine (const Vector3f& vec, float fAngle);
|
||||
void rotLine(const Vector3f& vec, float fAngle);
|
||||
/// Rotate around an arbitrary axis passing the origin in radians
|
||||
void rotLine (const Vector3d& vec, double fAngle);
|
||||
void rotLine(const Vector3d& vec, double fAngle);
|
||||
/// Rotate around an arbitrary axis that needn't necessarily pass the origin in radians
|
||||
void rotLine (const Vector3f& rclBase, const Vector3f& rclDir, float fAngle);
|
||||
void rotLine(const Vector3f& rclBase, const Vector3f& rclDir, float fAngle);
|
||||
/// Rotate around an arbitrary axis that needn't necessarily pass the origin in radians
|
||||
void rotLine (const Vector3d& rclBase, const Vector3d& rclDir, double fAngle);
|
||||
void rotLine(const Vector3d& rclBase, const Vector3d& rclDir, double fAngle);
|
||||
/// Extract the rotation axis and angle. Therefore the 3x3 submatrix must be orthogonal.
|
||||
bool toAxisAngle (Vector3f& rclBase, Vector3f& rclDir, float& fAngle, float& fTranslation) const;
|
||||
bool toAxisAngle (Vector3d& rclBase, Vector3d& rclDir, double& fAngle, double& fTranslation) const;
|
||||
bool toAxisAngle(Vector3f& rclBase, Vector3f& rclDir, float& fAngle, float& fTranslation) const;
|
||||
bool
|
||||
toAxisAngle(Vector3d& rclBase, Vector3d& rclDir, double& fAngle, double& fTranslation) const;
|
||||
/// transform (move,scale,rotate) around a point
|
||||
void transform (const Vector3f& vec, const Matrix4D& mat);
|
||||
void transform (const Vector3d& vec, const Matrix4D& mat);
|
||||
void transform(const Vector3f& vec, const Matrix4D& mat);
|
||||
void transform(const Vector3d& vec, const Matrix4D& mat);
|
||||
/// Matrix is expected to have a 3x3 rotation submatrix.
|
||||
void inverse ();
|
||||
void inverse();
|
||||
/// Matrix is expected to have a 3x3 rotation submatrix.
|
||||
void inverseOrthogonal();
|
||||
/// Arbitrary, non-singular matrix
|
||||
void inverseGauss ();
|
||||
void transpose ();
|
||||
void inverseGauss();
|
||||
void transpose();
|
||||
//@}
|
||||
|
||||
void Print () const;
|
||||
void Print() const;
|
||||
/// write the 16 double of the matrix into a string
|
||||
std::string toString() const;
|
||||
/// read the 16 double of the matrix from a string
|
||||
void fromString (const std::string &str);
|
||||
void fromString(const std::string& str);
|
||||
|
||||
private:
|
||||
double dMtrx4D[4][4];
|
||||
double dMtrx4D[4][4];
|
||||
};
|
||||
|
||||
inline Matrix4D Matrix4D::operator + (const Matrix4D& mat) const
|
||||
inline Matrix4D Matrix4D::operator+(const Matrix4D& mat) const
|
||||
{
|
||||
Matrix4D clMat;
|
||||
Matrix4D clMat;
|
||||
|
||||
for (int iz = 0; iz < 4; iz++) {
|
||||
for (int is = 0; is < 4; is++) {
|
||||
@@ -232,7 +249,7 @@ inline Matrix4D Matrix4D::operator + (const Matrix4D& mat) const
|
||||
return clMat;
|
||||
}
|
||||
|
||||
inline Matrix4D& Matrix4D::operator += (const Matrix4D& mat)
|
||||
inline Matrix4D& Matrix4D::operator+=(const Matrix4D& mat)
|
||||
{
|
||||
for (int iz = 0; iz < 4; iz++) {
|
||||
for (int is = 0; is < 4; is++) {
|
||||
@@ -243,9 +260,9 @@ inline Matrix4D& Matrix4D::operator += (const Matrix4D& mat)
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline Matrix4D Matrix4D::operator - (const Matrix4D& mat) const
|
||||
inline Matrix4D Matrix4D::operator-(const Matrix4D& mat) const
|
||||
{
|
||||
Matrix4D clMat;
|
||||
Matrix4D clMat;
|
||||
|
||||
for (int iz = 0; iz < 4; iz++) {
|
||||
for (int is = 0; is < 4; is++) {
|
||||
@@ -256,7 +273,7 @@ inline Matrix4D Matrix4D::operator - (const Matrix4D& mat) const
|
||||
return clMat;
|
||||
}
|
||||
|
||||
inline Matrix4D& Matrix4D::operator -= (const Matrix4D& mat)
|
||||
inline Matrix4D& Matrix4D::operator-=(const Matrix4D& mat)
|
||||
{
|
||||
for (int iz = 0; iz < 4; iz++) {
|
||||
for (int is = 0; is < 4; is++) {
|
||||
@@ -267,9 +284,9 @@ inline Matrix4D& Matrix4D::operator -= (const Matrix4D& mat)
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline Matrix4D& Matrix4D::operator *= (const Matrix4D& mat)
|
||||
inline Matrix4D& Matrix4D::operator*=(const Matrix4D& mat)
|
||||
{
|
||||
Matrix4D clMat;
|
||||
Matrix4D clMat;
|
||||
|
||||
for (int iz = 0; iz < 4; iz++) {
|
||||
for (int is = 0; is < 4; is++) {
|
||||
@@ -285,9 +302,9 @@ inline Matrix4D& Matrix4D::operator *= (const Matrix4D& mat)
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline Matrix4D Matrix4D::operator * (const Matrix4D& mat) const
|
||||
inline Matrix4D Matrix4D::operator*(const Matrix4D& mat) const
|
||||
{
|
||||
Matrix4D clMat;
|
||||
Matrix4D clMat;
|
||||
|
||||
for (int iz = 0; iz < 4; iz++) {
|
||||
for (int is = 0; is < 4; is++) {
|
||||
@@ -301,7 +318,7 @@ inline Matrix4D Matrix4D::operator * (const Matrix4D& mat) const
|
||||
return clMat;
|
||||
}
|
||||
|
||||
inline Matrix4D& Matrix4D::operator= (const Matrix4D& mat)
|
||||
inline Matrix4D& Matrix4D::operator=(const Matrix4D& mat)
|
||||
{
|
||||
for (int iz = 0; iz < 4; iz++) {
|
||||
for (int is = 0; is < 4; is++) {
|
||||
@@ -312,62 +329,52 @@ inline Matrix4D& Matrix4D::operator= (const Matrix4D& mat)
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline Vector3f Matrix4D::operator* (const Vector3f& vec) const
|
||||
inline Vector3f Matrix4D::operator*(const Vector3f& vec) const
|
||||
{
|
||||
// clang-format off
|
||||
double sx = static_cast<double>(vec.x);
|
||||
double sy = static_cast<double>(vec.y);
|
||||
double sz = static_cast<double>(vec.z);
|
||||
return Vector3f(
|
||||
static_cast<float>(dMtrx4D[0][0]*sx + dMtrx4D[0][1]*sy +
|
||||
dMtrx4D[0][2]*sz + dMtrx4D[0][3]),
|
||||
static_cast<float>(dMtrx4D[1][0]*sx + dMtrx4D[1][1]*sy +
|
||||
dMtrx4D[1][2]*sz + dMtrx4D[1][3]),
|
||||
static_cast<float>(dMtrx4D[2][0]*sx + dMtrx4D[2][1]*sy +
|
||||
dMtrx4D[2][2]*sz + dMtrx4D[2][3])
|
||||
);
|
||||
return Vector3f(static_cast<float>(dMtrx4D[0][0] * sx + dMtrx4D[0][1] * sy + dMtrx4D[0][2] * sz + dMtrx4D[0][3]),
|
||||
static_cast<float>(dMtrx4D[1][0] * sx + dMtrx4D[1][1] * sy + dMtrx4D[1][2] * sz + dMtrx4D[1][3]),
|
||||
static_cast<float>(dMtrx4D[2][0] * sx + dMtrx4D[2][1] * sy + dMtrx4D[2][2] * sz + dMtrx4D[2][3]));
|
||||
// clang-format on
|
||||
}
|
||||
|
||||
inline Vector3d Matrix4D::operator* (const Vector3d& vec) const
|
||||
inline Vector3d Matrix4D::operator*(const Vector3d& vec) const
|
||||
{
|
||||
return Vector3d((dMtrx4D[0][0]*vec.x + dMtrx4D[0][1]*vec.y +
|
||||
dMtrx4D[0][2]*vec.z + dMtrx4D[0][3]),
|
||||
(dMtrx4D[1][0]*vec.x + dMtrx4D[1][1]*vec.y +
|
||||
dMtrx4D[1][2]*vec.z + dMtrx4D[1][3]),
|
||||
(dMtrx4D[2][0]*vec.x + dMtrx4D[2][1]*vec.y +
|
||||
dMtrx4D[2][2]*vec.z + dMtrx4D[2][3]));
|
||||
// clang-format off
|
||||
return Vector3d((dMtrx4D[0][0] * vec.x + dMtrx4D[0][1] * vec.y + dMtrx4D[0][2] * vec.z + dMtrx4D[0][3]),
|
||||
(dMtrx4D[1][0] * vec.x + dMtrx4D[1][1] * vec.y + dMtrx4D[1][2] * vec.z + dMtrx4D[1][3]),
|
||||
(dMtrx4D[2][0] * vec.x + dMtrx4D[2][1] * vec.y + dMtrx4D[2][2] * vec.z + dMtrx4D[2][3]));
|
||||
// clang-format on
|
||||
}
|
||||
|
||||
inline void Matrix4D::multVec(const Vector3d & src, Vector3d & dst) const
|
||||
inline void Matrix4D::multVec(const Vector3d& src, Vector3d& dst) const
|
||||
{
|
||||
double dx = (dMtrx4D[0][0]*src.x + dMtrx4D[0][1]*src.y +
|
||||
dMtrx4D[0][2]*src.z + dMtrx4D[0][3]);
|
||||
double dy = (dMtrx4D[1][0]*src.x + dMtrx4D[1][1]*src.y +
|
||||
dMtrx4D[1][2]*src.z + dMtrx4D[1][3]);
|
||||
double dz = (dMtrx4D[2][0]*src.x + dMtrx4D[2][1]*src.y +
|
||||
dMtrx4D[2][2]*src.z + dMtrx4D[2][3]);
|
||||
dst.Set(dx,dy,dz);
|
||||
// clang-format off
|
||||
double dx = (dMtrx4D[0][0] * src.x + dMtrx4D[0][1] * src.y + dMtrx4D[0][2] * src.z + dMtrx4D[0][3]);
|
||||
double dy = (dMtrx4D[1][0] * src.x + dMtrx4D[1][1] * src.y + dMtrx4D[1][2] * src.z + dMtrx4D[1][3]);
|
||||
double dz = (dMtrx4D[2][0] * src.x + dMtrx4D[2][1] * src.y + dMtrx4D[2][2] * src.z + dMtrx4D[2][3]);
|
||||
dst.Set(dx, dy, dz);
|
||||
// clang-format on
|
||||
}
|
||||
|
||||
inline void Matrix4D::multVec(const Vector3f & src, Vector3f & dst) const
|
||||
inline void Matrix4D::multVec(const Vector3f& src, Vector3f& dst) const
|
||||
{
|
||||
double sx = static_cast<double>(src.x);
|
||||
double sy = static_cast<double>(src.y);
|
||||
double sz = static_cast<double>(src.z);
|
||||
|
||||
double dx = (dMtrx4D[0][0]*sx + dMtrx4D[0][1]*sy +
|
||||
dMtrx4D[0][2]*sz + dMtrx4D[0][3]);
|
||||
double dy = (dMtrx4D[1][0]*sx + dMtrx4D[1][1]*sy +
|
||||
dMtrx4D[1][2]*sz + dMtrx4D[1][3]);
|
||||
double dz = (dMtrx4D[2][0]*sx + dMtrx4D[2][1]*sy +
|
||||
dMtrx4D[2][2]*sz + dMtrx4D[2][3]);
|
||||
dst.Set(static_cast<float>(dx),
|
||||
static_cast<float>(dy),
|
||||
static_cast<float>(dz));
|
||||
double dx = (dMtrx4D[0][0] * sx + dMtrx4D[0][1] * sy + dMtrx4D[0][2] * sz + dMtrx4D[0][3]);
|
||||
double dy = (dMtrx4D[1][0] * sx + dMtrx4D[1][1] * sy + dMtrx4D[1][2] * sz + dMtrx4D[1][3]);
|
||||
double dz = (dMtrx4D[2][0] * sx + dMtrx4D[2][1] * sy + dMtrx4D[2][2] * sz + dMtrx4D[2][3]);
|
||||
dst.Set(static_cast<float>(dx), static_cast<float>(dy), static_cast<float>(dz));
|
||||
}
|
||||
|
||||
inline Matrix4D Matrix4D::operator * (double scalar) const
|
||||
inline Matrix4D Matrix4D::operator*(double scalar) const
|
||||
{
|
||||
Matrix4D matrix;
|
||||
Matrix4D matrix;
|
||||
for (unsigned short i = 0; i < 4; i++) {
|
||||
for (unsigned short j = 0; j < 4; j++) {
|
||||
matrix.dMtrx4D[i][j] = dMtrx4D[i][j] * scalar;
|
||||
@@ -377,47 +384,48 @@ inline Matrix4D Matrix4D::operator * (double scalar) const
|
||||
return matrix;
|
||||
}
|
||||
|
||||
inline Matrix4D& Matrix4D::operator *= (double scalar)
|
||||
inline Matrix4D& Matrix4D::operator*=(double scalar)
|
||||
{
|
||||
//NOLINTBEGIN
|
||||
// NOLINTBEGIN
|
||||
for (unsigned short i = 0; i < 4; i++) {
|
||||
for (unsigned short j = 0; j < 4; j++) {
|
||||
dMtrx4D[i][j] *= scalar;
|
||||
}
|
||||
}
|
||||
//NOLINTEND
|
||||
// NOLINTEND
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline bool Matrix4D::operator== (const Matrix4D& mat) const
|
||||
inline bool Matrix4D::operator==(const Matrix4D& mat) const
|
||||
{
|
||||
for (int iz = 0; iz < 4; iz++) {
|
||||
for (int is = 0; is < 4; is++) {
|
||||
if (fabs(dMtrx4D[iz][is] - mat.dMtrx4D[iz][is]) > traits_type::epsilon())
|
||||
if (fabs(dMtrx4D[iz][is] - mat.dMtrx4D[iz][is]) > traits_type::epsilon()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
inline bool Matrix4D::operator!= (const Matrix4D& mat) const
|
||||
inline bool Matrix4D::operator!=(const Matrix4D& mat) const
|
||||
{
|
||||
return !((*this) == mat);
|
||||
}
|
||||
|
||||
inline Vector3f& operator*= (Vector3f& vec, const Matrix4D& mat)
|
||||
inline Vector3f& operator*=(Vector3f& vec, const Matrix4D& mat)
|
||||
{
|
||||
vec = mat * vec;
|
||||
return vec;
|
||||
}
|
||||
|
||||
inline double* Matrix4D::operator[] (unsigned short usNdx)
|
||||
inline double* Matrix4D::operator[](unsigned short usNdx)
|
||||
{
|
||||
return dMtrx4D[usNdx];
|
||||
}
|
||||
|
||||
inline const double* Matrix4D::operator[] (unsigned short usNdx) const
|
||||
inline const double* Matrix4D::operator[](unsigned short usNdx) const
|
||||
{
|
||||
return dMtrx4D[usNdx];
|
||||
}
|
||||
@@ -468,9 +476,7 @@ inline void Matrix4D::setDiagonal(const Vector3d& vec)
|
||||
dMtrx4D[2][2] = vec.z;
|
||||
}
|
||||
|
||||
} // namespace Base
|
||||
|
||||
|
||||
#endif // BASE_MATRIX_H
|
||||
} // namespace Base
|
||||
|
||||
|
||||
#endif // BASE_MATRIX_H
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -40,10 +40,10 @@
|
||||
#include "PreCompiled.h"
|
||||
|
||||
#ifndef _PreComp_
|
||||
# ifdef _MSC_VER
|
||||
# include <ctime>
|
||||
# include <crtdbg.h>
|
||||
# endif
|
||||
#ifdef _MSC_VER
|
||||
#include <ctime>
|
||||
#include <crtdbg.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/// Here the FreeCAD includes sorted by Base,App,Gui......
|
||||
@@ -70,20 +70,26 @@ using namespace Base;
|
||||
class MemDebug
|
||||
{
|
||||
public:
|
||||
/// Construction
|
||||
MemDebug();
|
||||
/// Destruction
|
||||
virtual ~MemDebug();
|
||||
/// Construction
|
||||
MemDebug();
|
||||
/// Destruction
|
||||
virtual ~MemDebug();
|
||||
|
||||
protected:
|
||||
static FILE *logFile;
|
||||
static FILE* logFile;
|
||||
|
||||
/** @name static callbacks for the Crt */
|
||||
//@{
|
||||
static void __cdecl sDumpClientHook(void * pUserData, size_t nBytes);
|
||||
static int __cdecl sAllocHook(int nAllocType, void* pvData, size_t nSize,int nBlockUse,long lRequest,const unsigned char * szFileName,int nLine);
|
||||
static int sReportHook(int nRptType,char *szMsg,int *retVal);
|
||||
//@}
|
||||
/** @name static callbacks for the Crt */
|
||||
//@{
|
||||
static void __cdecl sDumpClientHook(void* pUserData, size_t nBytes);
|
||||
static int __cdecl sAllocHook(int nAllocType,
|
||||
void* pvData,
|
||||
size_t nSize,
|
||||
int nBlockUse,
|
||||
long lRequest,
|
||||
const unsigned char* szFileName,
|
||||
int nLine);
|
||||
static int sReportHook(int nRptType, char* szMsg, int* retVal);
|
||||
//@}
|
||||
};
|
||||
|
||||
// the one and only MemDebug instance.
|
||||
@@ -92,10 +98,10 @@ MemDebug cSingelton;
|
||||
#endif
|
||||
|
||||
|
||||
#define SET_CRT_DEBUG_FIELD(a) _CrtSetDbgFlag((a) | _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG))
|
||||
#define CLEAR_CRT_DEBUG_FIELD(a) _CrtSetDbgFlag(~(a) & _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG))
|
||||
#define SET_CRT_DEBUG_FIELD(a) _CrtSetDbgFlag((a) | _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG))
|
||||
#define CLEAR_CRT_DEBUG_FIELD(a) _CrtSetDbgFlag(~(a)&_CrtSetDbgFlag(_CRTDBG_REPORT_FLAG))
|
||||
|
||||
FILE *MemDebug::logFile = NULL;
|
||||
FILE* MemDebug::logFile = NULL;
|
||||
|
||||
//**************************************************************************
|
||||
// Construction/Destruction
|
||||
@@ -103,52 +109,56 @@ FILE *MemDebug::logFile = NULL;
|
||||
|
||||
MemDebug::MemDebug()
|
||||
{
|
||||
//_CrtMemState checkPt1;
|
||||
char timeStr[15], dateStr[15]; // Used to set up log file
|
||||
//_CrtMemState checkPt1;
|
||||
char timeStr[15], dateStr[15]; // Used to set up log file
|
||||
|
||||
|
||||
// Send all reports to STDOUT, since this example is a console app
|
||||
_CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE );
|
||||
_CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDERR );
|
||||
_CrtSetReportMode(_CRT_ERROR, _CRTDBG_MODE_FILE );
|
||||
_CrtSetReportFile(_CRT_ERROR, _CRTDBG_FILE_STDERR );
|
||||
_CrtSetReportMode(_CRT_ASSERT, _CRTDBG_MODE_FILE );
|
||||
_CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR );
|
||||
// Send all reports to STDOUT, since this example is a console app
|
||||
_CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE);
|
||||
_CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDERR);
|
||||
_CrtSetReportMode(_CRT_ERROR, _CRTDBG_MODE_FILE);
|
||||
_CrtSetReportFile(_CRT_ERROR, _CRTDBG_FILE_STDERR);
|
||||
_CrtSetReportMode(_CRT_ASSERT, _CRTDBG_MODE_FILE);
|
||||
_CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR);
|
||||
|
||||
// Set the debug heap to report memory leaks when the process terminates,
|
||||
// and to keep freed blocks in the linked list.
|
||||
SET_CRT_DEBUG_FIELD( _CRTDBG_LEAK_CHECK_DF | _CRTDBG_DELAY_FREE_MEM_DF );
|
||||
// Set the debug heap to report memory leaks when the process terminates,
|
||||
// and to keep freed blocks in the linked list.
|
||||
SET_CRT_DEBUG_FIELD(_CRTDBG_LEAK_CHECK_DF | _CRTDBG_DELAY_FREE_MEM_DF);
|
||||
|
||||
// Open a log file for the hook functions to use
|
||||
if ( logFile != NULL )
|
||||
throw std::runtime_error("Base::MemDebug::MemDebug():38: Don't call the constructor by your self!");
|
||||
// Open a log file for the hook functions to use
|
||||
if (logFile != NULL) {
|
||||
throw std::runtime_error(
|
||||
"Base::MemDebug::MemDebug():38: Don't call the constructor by your self!");
|
||||
}
|
||||
|
||||
fopen_s( &logFile, "MemLog.txt", "w" );
|
||||
if ( logFile == NULL )
|
||||
throw std::runtime_error("Base::MemDebug::MemDebug():41: File IO Error. Can't open log file...");
|
||||
_strtime_s( timeStr, 15 );
|
||||
_strdate_s( dateStr, 15 );
|
||||
fopen_s(&logFile, "MemLog.txt", "w");
|
||||
if (logFile == NULL) {
|
||||
throw std::runtime_error(
|
||||
"Base::MemDebug::MemDebug():41: File IO Error. Can't open log file...");
|
||||
}
|
||||
_strtime_s(timeStr, 15);
|
||||
_strdate_s(dateStr, 15);
|
||||
|
||||
fprintf( logFile,
|
||||
fprintf(logFile,
|
||||
"Memory Allocation Log File for FreeCAD, run at %s on %s.\n",
|
||||
timeStr, dateStr );
|
||||
fputs( "-------------------------------------------------------------------\n", logFile );
|
||||
|
||||
// Install the hook functions
|
||||
_CrtSetDumpClient( sDumpClientHook );
|
||||
_CrtSetAllocHook( sAllocHook );
|
||||
_CrtSetReportHook( sReportHook );
|
||||
timeStr,
|
||||
dateStr);
|
||||
fputs("-------------------------------------------------------------------\n", logFile);
|
||||
|
||||
// Install the hook functions
|
||||
_CrtSetDumpClient(sDumpClientHook);
|
||||
_CrtSetAllocHook(sAllocHook);
|
||||
_CrtSetReportHook(sReportHook);
|
||||
}
|
||||
|
||||
MemDebug::~MemDebug()
|
||||
{
|
||||
_CrtMemDumpAllObjectsSince( NULL );
|
||||
//_CrtCheckMemory( );
|
||||
_CrtMemDumpAllObjectsSince(NULL);
|
||||
//_CrtCheckMemory( );
|
||||
|
||||
// This fflush needs to be removed...
|
||||
fflush( logFile );
|
||||
fclose( logFile );
|
||||
// This fflush needs to be removed...
|
||||
fflush(logFile);
|
||||
fclose(logFile);
|
||||
}
|
||||
|
||||
|
||||
@@ -166,16 +176,17 @@ MemDebug::~MemDebug()
|
||||
to return zero, which causes execution to continue. If we want the function
|
||||
to start the debugger, we should have _CrtDbgReport return one.
|
||||
*/
|
||||
int MemDebug::sReportHook(int nRptType,char *szMsg,int *retVal)
|
||||
int MemDebug::sReportHook(int nRptType, char* szMsg, int* retVal)
|
||||
{
|
||||
const char *RptTypes[] = { "Warning", "Error", "Assert" };
|
||||
const char* RptTypes[] = {"Warning", "Error", "Assert"};
|
||||
|
||||
if ( ( nRptType > 0 ) || ( strstr( szMsg, "HEAP CORRUPTION DETECTED" ) ) )
|
||||
fprintf( logFile, "%s: %s", RptTypes[nRptType], szMsg );
|
||||
if ((nRptType > 0) || (strstr(szMsg, "HEAP CORRUPTION DETECTED"))) {
|
||||
fprintf(logFile, "%s: %s", RptTypes[nRptType], szMsg);
|
||||
}
|
||||
|
||||
retVal = 0;
|
||||
retVal = 0;
|
||||
|
||||
return( 7 ); // Allow the report to be made as usual (True = 7, False = 0)
|
||||
return (7); // Allow the report to be made as usual (True = 7, False = 0)
|
||||
}
|
||||
|
||||
/* ALLOCATION HOOK FUNCTION
|
||||
@@ -183,37 +194,44 @@ int MemDebug::sReportHook(int nRptType,char *szMsg,int *retVal)
|
||||
An allocation hook function can have many, many different
|
||||
uses. This one simply logs each allocation operation in a file.
|
||||
*/
|
||||
int __cdecl MemDebug::sAllocHook(
|
||||
int nAllocType,
|
||||
void * pvData,
|
||||
size_t nSize,
|
||||
int nBlockUse,
|
||||
long lRequest,
|
||||
const unsigned char * szFileName,
|
||||
int nLine
|
||||
)
|
||||
int __cdecl MemDebug::sAllocHook(int nAllocType,
|
||||
void* pvData,
|
||||
size_t nSize,
|
||||
int nBlockUse,
|
||||
long lRequest,
|
||||
const unsigned char* szFileName,
|
||||
int nLine)
|
||||
{
|
||||
const char *operation[] = { " :", "Alloc :", "Realloc:", "Free :" };
|
||||
const char *blockType[] = { "Free", "Normal", "CRT", "Ignore", "Client" };
|
||||
const char* operation[] = {" :", "Alloc :", "Realloc:", "Free :"};
|
||||
const char* blockType[] = {"Free", "Normal", "CRT", "Ignore", "Client"};
|
||||
|
||||
if ( nBlockUse == _CRT_BLOCK ) // Ignore internal C runtime library allocations
|
||||
return( 7 ); // (True = 7, False = 0)
|
||||
if (nBlockUse == _CRT_BLOCK) { // Ignore internal C runtime library allocations
|
||||
return (7); // (True = 7, False = 0)
|
||||
}
|
||||
|
||||
_ASSERT( ( nAllocType > 0 ) && ( nAllocType < 4 ) );
|
||||
_ASSERT( ( nBlockUse >= 0 ) && ( nBlockUse < 5 ) );
|
||||
_ASSERT((nAllocType > 0) && (nAllocType < 4));
|
||||
_ASSERT((nBlockUse >= 0) && (nBlockUse < 5));
|
||||
|
||||
if( nBlockUse !=4 )
|
||||
return(7);
|
||||
if (nBlockUse != 4) {
|
||||
return (7);
|
||||
}
|
||||
|
||||
fprintf( logFile,
|
||||
fprintf(logFile,
|
||||
"%s (#%7d) %12Iu byte (%s) in %s line %d",
|
||||
operation[nAllocType],lRequest, nSize, blockType[nBlockUse],szFileName, nLine);
|
||||
if ( pvData != NULL )
|
||||
fprintf( logFile, " at %p\n", pvData );
|
||||
else
|
||||
fprintf( logFile, "\n" );
|
||||
operation[nAllocType],
|
||||
lRequest,
|
||||
nSize,
|
||||
blockType[nBlockUse],
|
||||
szFileName,
|
||||
nLine);
|
||||
if (pvData != NULL) {
|
||||
fprintf(logFile, " at %p\n", pvData);
|
||||
}
|
||||
else {
|
||||
fprintf(logFile, "\n");
|
||||
}
|
||||
|
||||
return( 7 ); // Allow the memory operation to proceed (True = 7, False = 0)
|
||||
return (7); // Allow the memory operation to proceed (True = 7, False = 0)
|
||||
}
|
||||
|
||||
|
||||
@@ -224,15 +242,11 @@ int __cdecl MemDebug::sAllocHook(
|
||||
below also checks the data in several ways, and reports corruption
|
||||
or inconsistency as an assertion failure.
|
||||
*/
|
||||
void __cdecl MemDebug::sDumpClientHook(
|
||||
void * pUserData,
|
||||
size_t nBytes
|
||||
)
|
||||
void __cdecl MemDebug::sDumpClientHook(void* pUserData, size_t nBytes)
|
||||
{
|
||||
long requestNumber=0;
|
||||
_CrtIsMemoryBlock(pUserData,(unsigned int)nBytes,&requestNumber,NULL,NULL);
|
||||
fprintf( logFile, "Leak : (#%7d) %12Iu bytes (%p) \n", requestNumber, nBytes, pUserData );
|
||||
|
||||
long requestNumber = 0;
|
||||
_CrtIsMemoryBlock(pUserData, (unsigned int)nBytes, &requestNumber, NULL, NULL);
|
||||
fprintf(logFile, "Leak : (#%7d) %12Iu bytes (%p) \n", requestNumber, nBytes, pUserData);
|
||||
}
|
||||
|
||||
// -----------------------------------------------------
|
||||
@@ -240,26 +254,28 @@ void __cdecl MemDebug::sDumpClientHook(
|
||||
MemCheck::MemCheck()
|
||||
{
|
||||
// Store a memory checkpoint in the s1 memory-state structure
|
||||
_CrtMemCheckpoint( &s1 );
|
||||
_CrtMemCheckpoint(&s1);
|
||||
}
|
||||
|
||||
MemCheck::~MemCheck()
|
||||
{
|
||||
// Store a 2nd memory checkpoint in s2
|
||||
_CrtMemCheckpoint( &s2 );
|
||||
if ( _CrtMemDifference( &s3, &s1, &s2 ) )
|
||||
_CrtMemDumpStatistics( &s3 );
|
||||
_CrtMemCheckpoint(&s2);
|
||||
if (_CrtMemDifference(&s3, &s1, &s2)) {
|
||||
_CrtMemDumpStatistics(&s3);
|
||||
}
|
||||
}
|
||||
|
||||
void MemCheck::setNextCheckpoint()
|
||||
{
|
||||
// Store a 2nd memory checkpoint in s2
|
||||
_CrtMemCheckpoint( &s2 );
|
||||
if ( _CrtMemDifference( &s3, &s1, &s2 ) )
|
||||
_CrtMemDumpStatistics( &s3 );
|
||||
_CrtMemCheckpoint(&s2);
|
||||
if (_CrtMemDifference(&s3, &s1, &s2)) {
|
||||
_CrtMemDumpStatistics(&s3);
|
||||
}
|
||||
|
||||
// Store a memory checkpoint in the s1 memory-state structure
|
||||
_CrtMemCheckpoint( &s1 );
|
||||
_CrtMemCheckpoint(&s1);
|
||||
}
|
||||
|
||||
bool MemCheck::checkMemory()
|
||||
|
||||
@@ -50,7 +50,6 @@ private:
|
||||
|
||||
#endif
|
||||
|
||||
} //namespace Base
|
||||
|
||||
#endif // BASE_MEMDEBUG_H
|
||||
} // namespace Base
|
||||
|
||||
#endif // BASE_MEMDEBUG_H
|
||||
|
||||
@@ -26,12 +26,11 @@
|
||||
#include "Mutex.h"
|
||||
|
||||
|
||||
#if QT_VERSION < QT_VERSION_CHECK(5,14,0)
|
||||
QRecursiveMutex::QRecursiveMutex() : QMutex(QMutex::Recursive)
|
||||
{
|
||||
}
|
||||
#if QT_VERSION < QT_VERSION_CHECK(5, 14, 0)
|
||||
QRecursiveMutex::QRecursiveMutex()
|
||||
: QMutex(QMutex::Recursive)
|
||||
{}
|
||||
|
||||
QRecursiveMutex::~QRecursiveMutex()
|
||||
{
|
||||
}
|
||||
{}
|
||||
#endif
|
||||
|
||||
@@ -27,8 +27,8 @@
|
||||
#include <QMutex>
|
||||
#include <FCGlobal.h>
|
||||
|
||||
#if QT_VERSION < QT_VERSION_CHECK(5,14,0)
|
||||
class BaseExport QRecursiveMutex : public QMutex
|
||||
#if QT_VERSION < QT_VERSION_CHECK(5, 14, 0)
|
||||
class BaseExport QRecursiveMutex: public QMutex
|
||||
{
|
||||
public:
|
||||
QRecursiveMutex();
|
||||
@@ -36,4 +36,4 @@ public:
|
||||
};
|
||||
#endif
|
||||
|
||||
#endif // BASE_MUTEX_H
|
||||
#endif // BASE_MUTEX_H
|
||||
|
||||
@@ -26,9 +26,10 @@
|
||||
#include "Observer.h"
|
||||
|
||||
|
||||
namespace Base {
|
||||
namespace Base
|
||||
{
|
||||
|
||||
template class BaseExport Observer<const char*>;
|
||||
template class BaseExport Subject<const char*>;
|
||||
|
||||
} //namespace Base
|
||||
} // namespace Base
|
||||
|
||||
@@ -35,7 +35,8 @@
|
||||
namespace Base
|
||||
{
|
||||
|
||||
template <class MessageType> class Subject;
|
||||
template<class MessageType>
|
||||
class Subject;
|
||||
|
||||
|
||||
/** Observer class
|
||||
@@ -45,49 +46,50 @@ template <class MessageType> class Subject;
|
||||
* Attach itself to the observed object.
|
||||
* @see FCSubject
|
||||
*/
|
||||
template <class _MessageType>
|
||||
template<class _MessageType>
|
||||
class Observer
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* A constructor.
|
||||
* No special function so far.
|
||||
*/
|
||||
Observer() = default;
|
||||
|
||||
/**
|
||||
* A constructor.
|
||||
* No special function so far.
|
||||
*/
|
||||
Observer() = default;
|
||||
/**
|
||||
* A destructor.
|
||||
* No special function so far.
|
||||
*/
|
||||
virtual ~Observer() = default;
|
||||
|
||||
/**
|
||||
* A destructor.
|
||||
* No special function so far.
|
||||
*/
|
||||
virtual ~Observer() = default;
|
||||
/**
|
||||
* This method need to be reimplemented from the concrete Observer
|
||||
* and get called by the observed class
|
||||
* @param rCaller a reference to the calling object
|
||||
* @param rcReason
|
||||
* \todo undocumented parameter 2
|
||||
*/
|
||||
virtual void OnChange(Subject<_MessageType>& rCaller, _MessageType rcReason) = 0;
|
||||
|
||||
/**
|
||||
* This method need to be reimplemented from the concrete Observer
|
||||
* and get called by the observed class
|
||||
* @param rCaller a reference to the calling object
|
||||
* @param rcReason
|
||||
* \todo undocumented parameter 2
|
||||
*/
|
||||
virtual void OnChange(Subject<_MessageType>& rCaller, _MessageType rcReason) = 0;
|
||||
/**
|
||||
* This method need to be reimplemented from the concrete Observer
|
||||
* and get called by the observed class
|
||||
* @param rCaller a reference to the calling object
|
||||
*/
|
||||
virtual void OnDestroy(Subject<_MessageType>& rCaller)
|
||||
{
|
||||
(void)rCaller;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method need to be reimplemented from the concrete Observer
|
||||
* and get called by the observed class
|
||||
* @param rCaller a reference to the calling object
|
||||
*/
|
||||
virtual void OnDestroy(Subject<_MessageType>& rCaller) {
|
||||
(void)rCaller;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method can be reimplemented from the concrete Observer
|
||||
* and returns the name of the observer. Needed to use the Get
|
||||
* Method of the Subject.
|
||||
*/
|
||||
virtual const char *Name() {
|
||||
return nullptr;
|
||||
}
|
||||
/**
|
||||
* This method can be reimplemented from the concrete Observer
|
||||
* and returns the name of the observer. Needed to use the Get
|
||||
* Method of the Subject.
|
||||
*/
|
||||
virtual const char* Name()
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
};
|
||||
|
||||
/** Subject class
|
||||
@@ -97,143 +99,150 @@ public:
|
||||
* Attach itself to the observed object.
|
||||
* @see FCObserver
|
||||
*/
|
||||
template <class _MessageType>
|
||||
template<class _MessageType>
|
||||
class Subject
|
||||
{
|
||||
public:
|
||||
using ObserverType = Observer<_MessageType>;
|
||||
using MessageType = _MessageType;
|
||||
using SubjectType = Subject<_MessageType>;
|
||||
|
||||
using ObserverType = Observer<_MessageType>;
|
||||
using MessageType = _MessageType;
|
||||
using SubjectType = Subject<_MessageType>;
|
||||
/**
|
||||
* A constructor.
|
||||
* No special function so far.
|
||||
*/
|
||||
Subject() = default;
|
||||
|
||||
/**
|
||||
* A constructor.
|
||||
* No special function so far.
|
||||
*/
|
||||
Subject() = default;
|
||||
|
||||
/**
|
||||
* A destructor.
|
||||
* No special function so far.
|
||||
*/
|
||||
virtual ~Subject()
|
||||
{
|
||||
if (_ObserverSet.size() > 0)
|
||||
/**
|
||||
* A destructor.
|
||||
* No special function so far.
|
||||
*/
|
||||
virtual ~Subject()
|
||||
{
|
||||
Base::Console().DeveloperWarning(std::string("~Subject()"),
|
||||
"Not detached all observers yet\n");
|
||||
if (_ObserverSet.size() > 0) {
|
||||
Base::Console().DeveloperWarning(std::string("~Subject()"),
|
||||
"Not detached all observers yet\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Attach an Observer
|
||||
* Attach an Observer to the list of Observers which get
|
||||
* called when Notify is called.
|
||||
* @param ToObserv A pointer to a concrete Observer
|
||||
* @see Notify
|
||||
*/
|
||||
void Attach(Observer<_MessageType> *ToObserv)
|
||||
{
|
||||
/** Attach an Observer
|
||||
* Attach an Observer to the list of Observers which get
|
||||
* called when Notify is called.
|
||||
* @param ToObserv A pointer to a concrete Observer
|
||||
* @see Notify
|
||||
*/
|
||||
void Attach(Observer<_MessageType>* ToObserv)
|
||||
{
|
||||
#ifdef FC_DEBUG
|
||||
size_t count = _ObserverSet.size();
|
||||
_ObserverSet.insert(ToObserv);
|
||||
if ( _ObserverSet.size() == count ) {
|
||||
Base::Console().DeveloperWarning(std::string("Subject::Attach"),
|
||||
"Observer %p already attached\n",
|
||||
static_cast<void*>(ToObserv));
|
||||
}
|
||||
size_t count = _ObserverSet.size();
|
||||
_ObserverSet.insert(ToObserv);
|
||||
if (_ObserverSet.size() == count) {
|
||||
Base::Console().DeveloperWarning(std::string("Subject::Attach"),
|
||||
"Observer %p already attached\n",
|
||||
static_cast<void*>(ToObserv));
|
||||
}
|
||||
#else
|
||||
_ObserverSet.insert(ToObserv);
|
||||
_ObserverSet.insert(ToObserv);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/** Detach an Observer
|
||||
* Detach an Observer from the list of Observers which get
|
||||
* called when Notify is called.
|
||||
* @param ToObserv A pointer to a concrete Observer
|
||||
* @see Notify
|
||||
*/
|
||||
void Detach(Observer<_MessageType> *ToObserv)
|
||||
{
|
||||
/** Detach an Observer
|
||||
* Detach an Observer from the list of Observers which get
|
||||
* called when Notify is called.
|
||||
* @param ToObserv A pointer to a concrete Observer
|
||||
* @see Notify
|
||||
*/
|
||||
void Detach(Observer<_MessageType>* ToObserv)
|
||||
{
|
||||
#ifdef FC_DEBUG
|
||||
size_t count = _ObserverSet.size();
|
||||
_ObserverSet.erase(ToObserv);
|
||||
if (_ObserverSet.size() == count) {
|
||||
Base::Console().DeveloperWarning(std::string("Subject::Detach"),
|
||||
"Observer %p already detached\n",
|
||||
static_cast<void*>(ToObserv));
|
||||
}
|
||||
size_t count = _ObserverSet.size();
|
||||
_ObserverSet.erase(ToObserv);
|
||||
if (_ObserverSet.size() == count) {
|
||||
Base::Console().DeveloperWarning(std::string("Subject::Detach"),
|
||||
"Observer %p already detached\n",
|
||||
static_cast<void*>(ToObserv));
|
||||
}
|
||||
#else
|
||||
_ObserverSet.erase(ToObserv);
|
||||
_ObserverSet.erase(ToObserv);
|
||||
#endif
|
||||
}
|
||||
|
||||
/** Notify all Observers
|
||||
* Send a message to all Observers attached to this subject.
|
||||
* The Message depends on the implementation of a concrete
|
||||
* Oberserver and Subject.
|
||||
* @see Notify
|
||||
*/
|
||||
void Notify(_MessageType rcReason)
|
||||
{
|
||||
for(typename std::set<Observer<_MessageType> * >::iterator Iter=_ObserverSet.begin();Iter!=_ObserverSet.end();++Iter)
|
||||
{
|
||||
try {
|
||||
(*Iter)->OnChange(*this,rcReason); // send OnChange-signal
|
||||
} catch (Base::Exception &e) {
|
||||
Base::Console().Error("Unhandled Base::Exception caught when notifying observer.\n"
|
||||
"The error message is: %s\n", e.what());
|
||||
} catch (std::exception &e) {
|
||||
Base::Console().Error("Unhandled std::exception caught when notifying observer\n"
|
||||
"The error message is: %s\n", e.what());
|
||||
} catch (...) {
|
||||
Base::Console().Error("Unhandled unknown exception caught in when notifying observer.\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Get an Observer by name
|
||||
* Get a observer by name if the observer reimplements the Name() mthode.
|
||||
* @see Observer
|
||||
*/
|
||||
Observer<_MessageType> * Get(const char *Name)
|
||||
{
|
||||
const char* OName = nullptr;
|
||||
for(typename std::set<Observer<_MessageType> * >::iterator Iter=_ObserverSet.begin();Iter!=_ObserverSet.end();++Iter)
|
||||
{
|
||||
OName = (*Iter)->Name(); // get the name
|
||||
if(OName && strcmp(OName,Name) == 0)
|
||||
return *Iter;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
/** Notify all Observers
|
||||
* Send a message to all Observers attached to this subject.
|
||||
* The Message depends on the implementation of a concrete
|
||||
* Oberserver and Subject.
|
||||
* @see Notify
|
||||
*/
|
||||
void Notify(_MessageType rcReason)
|
||||
{
|
||||
for (typename std::set<Observer<_MessageType>*>::iterator Iter = _ObserverSet.begin();
|
||||
Iter != _ObserverSet.end();
|
||||
++Iter) {
|
||||
try {
|
||||
(*Iter)->OnChange(*this, rcReason); // send OnChange-signal
|
||||
}
|
||||
catch (Base::Exception& e) {
|
||||
Base::Console().Error("Unhandled Base::Exception caught when notifying observer.\n"
|
||||
"The error message is: %s\n",
|
||||
e.what());
|
||||
}
|
||||
catch (std::exception& e) {
|
||||
Base::Console().Error("Unhandled std::exception caught when notifying observer\n"
|
||||
"The error message is: %s\n",
|
||||
e.what());
|
||||
}
|
||||
catch (...) {
|
||||
Base::Console().Error(
|
||||
"Unhandled unknown exception caught in when notifying observer.\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Clears the list of all registered observers.
|
||||
* @note Using this function in your code may be an indication of design problems.
|
||||
*/
|
||||
void ClearObserver()
|
||||
{
|
||||
_ObserverSet.clear();
|
||||
}
|
||||
/** Get an Observer by name
|
||||
* Get a observer by name if the observer reimplements the Name() mthode.
|
||||
* @see Observer
|
||||
*/
|
||||
Observer<_MessageType>* Get(const char* Name)
|
||||
{
|
||||
const char* OName = nullptr;
|
||||
for (typename std::set<Observer<_MessageType>*>::iterator Iter = _ObserverSet.begin();
|
||||
Iter != _ObserverSet.end();
|
||||
++Iter) {
|
||||
OName = (*Iter)->Name(); // get the name
|
||||
if (OName && strcmp(OName, Name) == 0) {
|
||||
return *Iter;
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/** Clears the list of all registered observers.
|
||||
* @note Using this function in your code may be an indication of design problems.
|
||||
*/
|
||||
void ClearObserver()
|
||||
{
|
||||
_ObserverSet.clear();
|
||||
}
|
||||
|
||||
|
||||
protected:
|
||||
/// Vector of attached observers
|
||||
std::set<Observer <_MessageType> *> _ObserverSet;
|
||||
/// Vector of attached observers
|
||||
std::set<Observer<_MessageType>*> _ObserverSet;
|
||||
};
|
||||
|
||||
// Workaround for MSVC
|
||||
#if defined (FreeCADBase_EXPORTS) && defined(_MSC_VER)
|
||||
# define Base_EXPORT
|
||||
#if defined(FreeCADBase_EXPORTS) && defined(_MSC_VER)
|
||||
#define Base_EXPORT
|
||||
#else
|
||||
# define Base_EXPORT BaseExport
|
||||
#define Base_EXPORT BaseExport
|
||||
#endif
|
||||
|
||||
extern template class Base_EXPORT Observer<const char*>;
|
||||
extern template class Base_EXPORT Subject<const char*>;
|
||||
|
||||
|
||||
} //namespace Base
|
||||
} // namespace Base
|
||||
|
||||
|
||||
#endif // BASE_OBSERVER_H
|
||||
#endif // BASE_OBSERVER_H
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -21,7 +21,7 @@
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
/**
|
||||
/**
|
||||
* \file Parameter.h
|
||||
* \brief The classes defined here are used to interface with the XML-based
|
||||
* FreeCAD config files: user.cfg and system.cfg files. It can parse, get,
|
||||
@@ -32,7 +32,7 @@
|
||||
#ifndef BASE__PARAMETER_H
|
||||
#define BASE__PARAMETER_H
|
||||
|
||||
// Python stuff
|
||||
// Python stuff
|
||||
using PyObject = struct _object;
|
||||
|
||||
#ifdef FC_OS_MACOSX
|
||||
@@ -58,11 +58,11 @@ using PyObject = struct _object;
|
||||
#include "Observer.h"
|
||||
|
||||
#ifdef _MSC_VER
|
||||
# pragma warning( disable : 4251 )
|
||||
# pragma warning( disable : 4503 )
|
||||
# pragma warning( disable : 4786 ) // specifier longer then 255 chars
|
||||
# pragma warning( disable : 4290 ) // not implemented throw specification
|
||||
# pragma warning( disable : 4275 )
|
||||
#pragma warning(disable : 4251)
|
||||
#pragma warning(disable : 4503)
|
||||
#pragma warning(disable : 4786) // specifier longer then 255 chars
|
||||
#pragma warning(disable : 4290) // not implemented throw specification
|
||||
#pragma warning(disable : 4275)
|
||||
#endif
|
||||
|
||||
|
||||
@@ -91,7 +91,7 @@ class ParameterManager;
|
||||
* kind of preferences and so on.
|
||||
* @see ParameterManager
|
||||
*/
|
||||
class BaseExport ParameterGrp : public Base::Handled,public Base::Subject <const char*>
|
||||
class BaseExport ParameterGrp: public Base::Handled, public Base::Subject<const char*>
|
||||
{
|
||||
public:
|
||||
/** @name copy and insertation */
|
||||
@@ -117,7 +117,7 @@ public:
|
||||
/// get a handle to a sub group or create one
|
||||
Base::Reference<ParameterGrp> GetGroup(const char* Name);
|
||||
/// get a vector of all sub groups in this group
|
||||
std::vector<Base::Reference<ParameterGrp> > GetGroups();
|
||||
std::vector<Base::Reference<ParameterGrp>> GetGroups();
|
||||
/// test if this group is empty
|
||||
bool IsEmpty() const;
|
||||
/// test if a special sub group is in this group
|
||||
@@ -135,7 +135,8 @@ public:
|
||||
|
||||
/** @name methods for generic attribute handling */
|
||||
//@{
|
||||
enum class ParamType {
|
||||
enum class ParamType
|
||||
{
|
||||
FCInvalid = 0,
|
||||
FCText = 1,
|
||||
FCBool = 2,
|
||||
@@ -144,34 +145,32 @@ public:
|
||||
FCFloat = 5,
|
||||
FCGroup = 6,
|
||||
};
|
||||
static const char *TypeName(ParamType type);
|
||||
static ParamType TypeValue(const char *);
|
||||
void SetAttribute(ParamType Type, const char *Name, const char *Value);
|
||||
void RemoveAttribute(ParamType Type, const char *Name);
|
||||
const char *GetAttribute(ParamType Type,
|
||||
const char *Name,
|
||||
std::string &Value,
|
||||
const char *Default) const;
|
||||
static const char* TypeName(ParamType type);
|
||||
static ParamType TypeValue(const char*);
|
||||
void SetAttribute(ParamType Type, const char* Name, const char* Value);
|
||||
void RemoveAttribute(ParamType Type, const char* Name);
|
||||
const char*
|
||||
GetAttribute(ParamType Type, const char* Name, std::string& Value, const char* Default) const;
|
||||
std::vector<std::pair<std::string, std::string>>
|
||||
GetAttributeMap(ParamType Type, const char * sFilter = nullptr) const;
|
||||
GetAttributeMap(ParamType Type, const char* sFilter = nullptr) const;
|
||||
/** Return the type and name of all parameters with optional filter
|
||||
* @param sFilter only strings which name includes sFilter are put in the vector
|
||||
* @return std::vector of pair(type, name)
|
||||
*/
|
||||
std::vector<std::pair<ParamType,std::string>>
|
||||
GetParameterNames(const char * sFilter = nullptr) const;
|
||||
std::vector<std::pair<ParamType, std::string>>
|
||||
GetParameterNames(const char* sFilter = nullptr) const;
|
||||
//@}
|
||||
|
||||
/** @name methods for bool handling */
|
||||
//@{
|
||||
/// read bool values or give default
|
||||
bool GetBool(const char* Name, bool bPreset=false) const;
|
||||
bool GetBool(const char* Name, bool bPreset = false) const;
|
||||
/// set a bool value
|
||||
void SetBool(const char* Name, bool bValue);
|
||||
/// get a vector of all bool values in this group
|
||||
std::vector<bool> GetBools(const char * sFilter = nullptr) const;
|
||||
std::vector<bool> GetBools(const char* sFilter = nullptr) const;
|
||||
/// get a map with all bool values and the keys of this group
|
||||
std::vector<std::pair<std::string,bool> > GetBoolMap(const char * sFilter = nullptr) const;
|
||||
std::vector<std::pair<std::string, bool>> GetBoolMap(const char* sFilter = nullptr) const;
|
||||
/// remove a bool value from this group
|
||||
void RemoveBool(const char* Name);
|
||||
//@}
|
||||
@@ -179,13 +178,13 @@ public:
|
||||
/** @name methods for Int handling */
|
||||
//@{
|
||||
/// read bool values or give default
|
||||
long GetInt(const char* Name, long lPreset=0) const;
|
||||
long GetInt(const char* Name, long lPreset = 0) const;
|
||||
/// set a int value
|
||||
void SetInt(const char* Name, long lValue);
|
||||
/// get a vector of all int values in this group
|
||||
std::vector<long> GetInts(const char * sFilter = nullptr) const;
|
||||
std::vector<long> GetInts(const char* sFilter = nullptr) const;
|
||||
/// get a map with all int values and the keys of this group
|
||||
std::vector<std::pair<std::string,long> > GetIntMap(const char * sFilter = nullptr) const;
|
||||
std::vector<std::pair<std::string, long>> GetIntMap(const char* sFilter = nullptr) const;
|
||||
/// remove a int value from this group
|
||||
void RemoveInt(const char* Name);
|
||||
//@}
|
||||
@@ -193,13 +192,14 @@ public:
|
||||
/** @name methods for Unsigned Int handling */
|
||||
//@{
|
||||
/// read uint values or give default
|
||||
unsigned long GetUnsigned(const char* Name, unsigned long lPreset=0) const;
|
||||
unsigned long GetUnsigned(const char* Name, unsigned long lPreset = 0) const;
|
||||
/// set a uint value
|
||||
void SetUnsigned(const char* Name, unsigned long lValue);
|
||||
/// get a vector of all uint values in this group
|
||||
std::vector<unsigned long> GetUnsigneds(const char * sFilter = nullptr) const;
|
||||
std::vector<unsigned long> GetUnsigneds(const char* sFilter = nullptr) const;
|
||||
/// get a map with all uint values and the keys of this group
|
||||
std::vector<std::pair<std::string,unsigned long> > GetUnsignedMap(const char * sFilter = nullptr) const;
|
||||
std::vector<std::pair<std::string, unsigned long>>
|
||||
GetUnsignedMap(const char* sFilter = nullptr) const;
|
||||
/// remove a uint value from this group
|
||||
void RemoveUnsigned(const char* Name);
|
||||
//@}
|
||||
@@ -208,28 +208,29 @@ public:
|
||||
/** @name methods for Float handling */
|
||||
//@{
|
||||
/// set a float value
|
||||
double GetFloat(const char* Name, double dPreset=0.0) const;
|
||||
double GetFloat(const char* Name, double dPreset = 0.0) const;
|
||||
/// read float values or give default
|
||||
void SetFloat(const char* Name, double dValue);
|
||||
/// get a vector of all float values in this group
|
||||
std::vector<double> GetFloats(const char * sFilter = nullptr) const;
|
||||
std::vector<double> GetFloats(const char* sFilter = nullptr) const;
|
||||
/// get a map with all float values and the keys of this group
|
||||
std::vector<std::pair<std::string,double> > GetFloatMap(const char * sFilter = nullptr) const;
|
||||
std::vector<std::pair<std::string, double>> GetFloatMap(const char* sFilter = nullptr) const;
|
||||
/// remove a float value from this group
|
||||
void RemoveFloat(const char* Name);
|
||||
//@}
|
||||
|
||||
|
||||
|
||||
|
||||
/** @name methods for String handling */
|
||||
//@{
|
||||
/// set a string value
|
||||
void SetASCII(const char* Name, const char *sValue);
|
||||
void SetASCII(const char* Name, const char* sValue);
|
||||
/// set a string value
|
||||
void SetASCII(const char* Name, const std::string &sValue) { SetASCII(Name, sValue.c_str()); }
|
||||
void SetASCII(const char* Name, const std::string& sValue)
|
||||
{
|
||||
SetASCII(Name, sValue.c_str());
|
||||
}
|
||||
/// read a string values
|
||||
std::string GetASCII(const char* Name, const char * pPreset=nullptr) const;
|
||||
std::string GetASCII(const char* Name, const char* pPreset = nullptr) const;
|
||||
/// remove a string value from this group
|
||||
void RemoveASCII(const char* Name);
|
||||
/** Return all string elements in this group as a vector of strings
|
||||
@@ -237,34 +238,42 @@ public:
|
||||
* @param sFilter only strings which name includes sFilter are put in the vector
|
||||
* @return std::vector of std::strings
|
||||
*/
|
||||
std::vector<std::string> GetASCIIs(const char * sFilter = nullptr) const;
|
||||
std::vector<std::string> GetASCIIs(const char* sFilter = nullptr) const;
|
||||
/// Same as GetASCIIs() but with key,value map
|
||||
std::vector<std::pair<std::string,std::string> > GetASCIIMap(const char * sFilter = nullptr) const;
|
||||
std::vector<std::pair<std::string, std::string>>
|
||||
GetASCIIMap(const char* sFilter = nullptr) const;
|
||||
//@}
|
||||
|
||||
friend class ParameterManager;
|
||||
|
||||
/// returns the name
|
||||
const char* GetGroupName() const {
|
||||
const char* GetGroupName() const
|
||||
{
|
||||
return _cName.c_str();
|
||||
}
|
||||
|
||||
/// return the full path of this group
|
||||
std::string GetPath() const;
|
||||
void GetPath(std::string &) const;
|
||||
void GetPath(std::string&) const;
|
||||
|
||||
/** Notifies all observers for all entries except of sub-groups.
|
||||
*/
|
||||
void NotifyAll();
|
||||
|
||||
ParameterGrp *Parent() const {return _Parent;}
|
||||
ParameterManager *Manager() const {return _Manager;}
|
||||
ParameterGrp* Parent() const
|
||||
{
|
||||
return _Parent;
|
||||
}
|
||||
ParameterManager* Manager() const
|
||||
{
|
||||
return _Manager;
|
||||
}
|
||||
|
||||
protected:
|
||||
/// constructor is protected (handle concept)
|
||||
ParameterGrp(XERCES_CPP_NAMESPACE_QUALIFIER DOMElement *GroupNode=nullptr,
|
||||
const char* sName=nullptr,
|
||||
ParameterGrp *Parent=nullptr);
|
||||
ParameterGrp(XERCES_CPP_NAMESPACE_QUALIFIER DOMElement* GroupNode = nullptr,
|
||||
const char* sName = nullptr,
|
||||
ParameterGrp* Parent = nullptr);
|
||||
/// destructor is protected (handle concept)
|
||||
~ParameterGrp() override;
|
||||
/// helper function for GetGroup
|
||||
@@ -273,10 +282,11 @@ protected:
|
||||
|
||||
void _Reset();
|
||||
|
||||
void _SetAttribute(ParamType Type, const char *Name, const char *Value);
|
||||
void _Notify(ParamType Type, const char *Name, const char *Value);
|
||||
void _SetAttribute(ParamType Type, const char* Name, const char* Value);
|
||||
void _Notify(ParamType Type, const char* Name, const char* Value);
|
||||
|
||||
XERCES_CPP_NAMESPACE_QUALIFIER DOMElement *FindNextElement(XERCES_CPP_NAMESPACE_QUALIFIER DOMNode *Prev, const char* Type) const;
|
||||
XERCES_CPP_NAMESPACE_QUALIFIER DOMElement*
|
||||
FindNextElement(XERCES_CPP_NAMESPACE_QUALIFIER DOMNode* Prev, const char* Type) const;
|
||||
|
||||
/** Find an element specified by Type and Name
|
||||
* Search in the parent element Start for the first occurrence of an
|
||||
@@ -284,29 +294,39 @@ protected:
|
||||
* the pointer to that element, otherwise NULL
|
||||
* If the names not given it returns the first occurrence of Type.
|
||||
*/
|
||||
XERCES_CPP_NAMESPACE_QUALIFIER DOMElement *FindElement(XERCES_CPP_NAMESPACE_QUALIFIER DOMElement *Start, const char* Type, const char* Name=nullptr) const;
|
||||
XERCES_CPP_NAMESPACE_QUALIFIER DOMElement*
|
||||
FindElement(XERCES_CPP_NAMESPACE_QUALIFIER DOMElement* Start,
|
||||
const char* Type,
|
||||
const char* Name = nullptr) const;
|
||||
|
||||
/** Find an element specified by Type and Name or create it if not found
|
||||
* Search in the parent element Start for the first occurrence of an
|
||||
* element of Type and with the attribute Name=Name. On success it returns
|
||||
* the pointer to that element, otherwise it creates the element and returns the pointer.
|
||||
*/
|
||||
XERCES_CPP_NAMESPACE_QUALIFIER DOMElement *FindOrCreateElement(XERCES_CPP_NAMESPACE_QUALIFIER DOMElement *Start, const char* Type, const char* Name);
|
||||
XERCES_CPP_NAMESPACE_QUALIFIER DOMElement*
|
||||
FindOrCreateElement(XERCES_CPP_NAMESPACE_QUALIFIER DOMElement* Start,
|
||||
const char* Type,
|
||||
const char* Name);
|
||||
|
||||
XERCES_CPP_NAMESPACE_QUALIFIER DOMElement *CreateElement(XERCES_CPP_NAMESPACE_QUALIFIER DOMElement *Start, const char* Type, const char* Name);
|
||||
XERCES_CPP_NAMESPACE_QUALIFIER DOMElement*
|
||||
CreateElement(XERCES_CPP_NAMESPACE_QUALIFIER DOMElement* Start,
|
||||
const char* Type,
|
||||
const char* Name);
|
||||
|
||||
/** Find an attribute specified by Name
|
||||
*/
|
||||
XERCES_CPP_NAMESPACE_QUALIFIER DOMNode *FindAttribute(XERCES_CPP_NAMESPACE_QUALIFIER DOMNode *Node, const char* Name) const;
|
||||
XERCES_CPP_NAMESPACE_QUALIFIER DOMNode*
|
||||
FindAttribute(XERCES_CPP_NAMESPACE_QUALIFIER DOMNode* Node, const char* Name) const;
|
||||
|
||||
/// DOM Node of the Base node of this group
|
||||
XERCES_CPP_NAMESPACE_QUALIFIER DOMElement *_pGroupNode;
|
||||
XERCES_CPP_NAMESPACE_QUALIFIER DOMElement* _pGroupNode;
|
||||
/// the own name
|
||||
std::string _cName;
|
||||
/// map of already exported groups
|
||||
std::map <std::string ,Base::Reference<ParameterGrp> > _GroupMap;
|
||||
ParameterGrp * _Parent = nullptr;
|
||||
ParameterManager *_Manager = nullptr;
|
||||
std::map<std::string, Base::Reference<ParameterGrp>> _GroupMap;
|
||||
ParameterGrp* _Parent = nullptr;
|
||||
ParameterManager* _Manager = nullptr;
|
||||
/// Means this group xml element has not been added to its parent yet.
|
||||
bool _Detached = false;
|
||||
/** Indicate this group is currently being cleared
|
||||
@@ -332,7 +352,10 @@ public:
|
||||
virtual void SaveDocument(const ParameterManager&);
|
||||
virtual int LoadDocument(ParameterManager&);
|
||||
virtual bool LoadOrCreateDocument(ParameterManager&);
|
||||
const std::string &GetFileName() const {return filename;}
|
||||
const std::string& GetFileName() const
|
||||
{
|
||||
return filename;
|
||||
}
|
||||
|
||||
protected:
|
||||
std::string filename;
|
||||
@@ -343,7 +366,7 @@ protected:
|
||||
* Does loading, saving and handling the DOM document.
|
||||
* @see ParameterGrp
|
||||
*/
|
||||
class BaseExport ParameterManager : public ParameterGrp
|
||||
class BaseExport ParameterManager: public ParameterGrp
|
||||
{
|
||||
public:
|
||||
/// Create a reference counted ParameterManager
|
||||
@@ -354,7 +377,7 @@ public:
|
||||
/** Signal on parameter changes
|
||||
*
|
||||
* The signal is triggered on adding, removing, renaming or modifying on
|
||||
* all individual parameters and group. The signature of the signal is
|
||||
* all individual parameters and group. The signature of the signal is
|
||||
* \code
|
||||
* void (ParameterGrp *param, ParamType type, const char *name, const char *value)
|
||||
* \endcode
|
||||
@@ -373,53 +396,53 @@ public:
|
||||
* - Group removal: both 'name' and 'value' are empty
|
||||
* - Group rename: 'name' is the new name, and 'value' is the old name
|
||||
*/
|
||||
boost::signals2::signal<void (ParameterGrp* /*param*/,
|
||||
ParamType /*type*/,
|
||||
const char * /*name*/,
|
||||
const char * /*value*/)> signalParamChanged;
|
||||
boost::signals2::signal<void(ParameterGrp* /*param*/,
|
||||
ParamType /*type*/,
|
||||
const char* /*name*/,
|
||||
const char* /*value*/)>
|
||||
signalParamChanged;
|
||||
|
||||
int LoadDocument(const char* sFileName);
|
||||
int LoadDocument(const XERCES_CPP_NAMESPACE_QUALIFIER InputSource&);
|
||||
bool LoadOrCreateDocument(const char* sFileName);
|
||||
void SaveDocument(const char* sFileName) const;
|
||||
void SaveDocument(XERCES_CPP_NAMESPACE_QUALIFIER XMLFormatTarget* pFormatTarget) const;
|
||||
void CreateDocument();
|
||||
void CheckDocument() const;
|
||||
int LoadDocument(const char* sFileName);
|
||||
int LoadDocument(const XERCES_CPP_NAMESPACE_QUALIFIER InputSource&);
|
||||
bool LoadOrCreateDocument(const char* sFileName);
|
||||
void SaveDocument(const char* sFileName) const;
|
||||
void SaveDocument(XERCES_CPP_NAMESPACE_QUALIFIER XMLFormatTarget* pFormatTarget) const;
|
||||
void CreateDocument();
|
||||
void CheckDocument() const;
|
||||
|
||||
/** @name Parameter serialization */
|
||||
//@{
|
||||
/// Sets a serializer. The ParameterManager takes ownership of the serializer.
|
||||
void SetSerializer(ParameterSerializer*);
|
||||
void SetSerializer(ParameterSerializer*);
|
||||
/// Returns true if a serializer is set, otherwise false is returned.
|
||||
bool HasSerializer() const;
|
||||
bool HasSerializer() const;
|
||||
/// Returns the filename of the serialize.
|
||||
const std::string & GetSerializeFileName() const;
|
||||
const std::string& GetSerializeFileName() const;
|
||||
/// Loads an XML document by calling the serializer's load method.
|
||||
int LoadDocument();
|
||||
int LoadDocument();
|
||||
/// Loads or creates an XML document by calling the serializer's load method.
|
||||
bool LoadOrCreateDocument();
|
||||
bool LoadOrCreateDocument();
|
||||
/// Saves an XML document by calling the serializer's save method.
|
||||
void SaveDocument() const;
|
||||
void SaveDocument() const;
|
||||
//@}
|
||||
|
||||
private:
|
||||
XERCES_CPP_NAMESPACE_QUALIFIER DOMDocument* _pDocument {nullptr};
|
||||
ParameterSerializer* paramSerializer {nullptr};
|
||||
|
||||
XERCES_CPP_NAMESPACE_QUALIFIER DOMDocument *_pDocument{nullptr};
|
||||
ParameterSerializer * paramSerializer{nullptr};
|
||||
|
||||
bool gDoNamespaces ;
|
||||
bool gDoSchema ;
|
||||
bool gSchemaFullChecking ;
|
||||
bool gDoCreate ;
|
||||
bool gDoNamespaces;
|
||||
bool gDoSchema;
|
||||
bool gSchemaFullChecking;
|
||||
bool gDoCreate;
|
||||
|
||||
|
||||
const XMLCh* gOutputEncoding ;
|
||||
const XMLCh* gMyEOLSequence ;
|
||||
const XMLCh* gOutputEncoding;
|
||||
const XMLCh* gMyEOLSequence;
|
||||
|
||||
bool gSplitCdataSections ;
|
||||
bool gDiscardDefaultContent;
|
||||
bool gUseFilter ;
|
||||
bool gFormatPrettyPrint ;
|
||||
bool gSplitCdataSections;
|
||||
bool gDiscardDefaultContent;
|
||||
bool gUseFilter;
|
||||
bool gFormatPrettyPrint;
|
||||
|
||||
private:
|
||||
ParameterManager();
|
||||
@@ -427,8 +450,8 @@ private:
|
||||
};
|
||||
|
||||
/** python wrapper function
|
||||
*/
|
||||
BaseExport PyObject* GetPyObject( const Base::Reference<ParameterGrp> &hcParamGrp);
|
||||
*/
|
||||
BaseExport PyObject* GetPyObject(const Base::Reference<ParameterGrp>& hcParamGrp);
|
||||
|
||||
|
||||
#endif // BASE__PARAMETER_H
|
||||
#endif // BASE__PARAMETER_H
|
||||
|
||||
@@ -25,17 +25,17 @@
|
||||
#include "PreCompiled.h"
|
||||
|
||||
#ifndef _PreComp_
|
||||
# ifdef FC_OS_WIN32
|
||||
# include <xercesc/sax/SAXParseException.hpp>
|
||||
# endif
|
||||
# include <list>
|
||||
# include <sstream>
|
||||
# include <string>
|
||||
# include <utility>
|
||||
#ifdef FC_OS_WIN32
|
||||
#include <xercesc/sax/SAXParseException.hpp>
|
||||
#endif
|
||||
#include <list>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#endif
|
||||
|
||||
#ifdef FC_OS_LINUX
|
||||
# include <unistd.h>
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include "Parameter.h"
|
||||
@@ -43,26 +43,28 @@
|
||||
#include "Interpreter.h"
|
||||
|
||||
|
||||
namespace Base {
|
||||
namespace Base
|
||||
{
|
||||
|
||||
class ParameterGrpObserver : public ParameterGrp::ObserverType
|
||||
class ParameterGrpObserver: public ParameterGrp::ObserverType
|
||||
{
|
||||
public:
|
||||
explicit ParameterGrpObserver(const Py::Object& obj)
|
||||
{
|
||||
inst = obj;
|
||||
}
|
||||
ParameterGrpObserver(const Py::Object& obj, const Py::Object &callable, ParameterGrp *target)
|
||||
: callable(callable), _target(target), inst(obj)
|
||||
{
|
||||
}
|
||||
ParameterGrpObserver(const Py::Object& obj, const Py::Object& callable, ParameterGrp* target)
|
||||
: callable(callable)
|
||||
, _target(target)
|
||||
, inst(obj)
|
||||
{}
|
||||
~ParameterGrpObserver() override
|
||||
{
|
||||
Base::PyGILStateLocker lock;
|
||||
inst = Py::None();
|
||||
callable = Py::None();
|
||||
}
|
||||
void OnChange(ParameterGrp::SubjectType &rCaller,ParameterGrp::MessageType Reason) override
|
||||
void OnChange(ParameterGrp::SubjectType& rCaller, ParameterGrp::MessageType Reason) override
|
||||
{
|
||||
Base::PyGILStateLocker lock;
|
||||
try {
|
||||
@@ -72,12 +74,13 @@ public:
|
||||
Py::Tuple args(2);
|
||||
args.setItem(0, Py::asObject(GetPyObject(hGrp)));
|
||||
// A Reason of null indicates to clear the parameter group
|
||||
if (Reason && Reason[0] != '\0')
|
||||
if (Reason && Reason[0] != '\0') {
|
||||
args.setItem(1, Py::String(Reason));
|
||||
}
|
||||
method.apply(args);
|
||||
}
|
||||
catch (Py::Exception&) {
|
||||
Base::PyException e; // extract the Python error text
|
||||
Base::PyException e; // extract the Python error text
|
||||
e.ReportException();
|
||||
}
|
||||
}
|
||||
@@ -89,7 +92,7 @@ public:
|
||||
public:
|
||||
Py::Object callable;
|
||||
boost::signals2::scoped_connection conn;
|
||||
ParameterGrp *_target = nullptr; // no reference counted, do not access
|
||||
ParameterGrp* _target = nullptr; // no reference counted, do not access
|
||||
|
||||
private:
|
||||
Py::Object inst;
|
||||
@@ -97,12 +100,12 @@ private:
|
||||
|
||||
using ParameterGrpObserverList = std::list<ParameterGrpObserver*>;
|
||||
|
||||
class ParameterGrpPy : public Py::PythonExtension<ParameterGrpPy>
|
||||
class ParameterGrpPy: public Py::PythonExtension<ParameterGrpPy>
|
||||
{
|
||||
public:
|
||||
static void init_type(); // announce properties and methods
|
||||
static void init_type(); // announce properties and methods
|
||||
|
||||
explicit ParameterGrpPy(const Base::Reference<ParameterGrp> &rcParamGrp);
|
||||
explicit ParameterGrpPy(const Base::Reference<ParameterGrp>& rcParamGrp);
|
||||
~ParameterGrpPy() override;
|
||||
|
||||
Py::Object repr() override;
|
||||
@@ -173,20 +176,22 @@ void ParameterGrpPy::init_type()
|
||||
behaviors().supportSetattr();
|
||||
behaviors().readyType();
|
||||
|
||||
add_varargs_method("GetGroup",&ParameterGrpPy::getGroup,"GetGroup(str)");
|
||||
add_varargs_method("GetGroupName",&ParameterGrpPy::getGroupName,"GetGroupName()");
|
||||
add_varargs_method("GetGroups",&ParameterGrpPy::getGroups,"GetGroups()");
|
||||
add_varargs_method("RemGroup",&ParameterGrpPy::remGroup,"RemGroup(str)");
|
||||
add_varargs_method("HasGroup",&ParameterGrpPy::hasGroup,"HasGroup(str)");
|
||||
add_varargs_method("GetGroup", &ParameterGrpPy::getGroup, "GetGroup(str)");
|
||||
add_varargs_method("GetGroupName", &ParameterGrpPy::getGroupName, "GetGroupName()");
|
||||
add_varargs_method("GetGroups", &ParameterGrpPy::getGroups, "GetGroups()");
|
||||
add_varargs_method("RemGroup", &ParameterGrpPy::remGroup, "RemGroup(str)");
|
||||
add_varargs_method("HasGroup", &ParameterGrpPy::hasGroup, "HasGroup(str)");
|
||||
|
||||
add_varargs_method("Manager",&ParameterGrpPy::getManager,"Manager()");
|
||||
add_varargs_method("Parent",&ParameterGrpPy::getParent,"Parent()");
|
||||
add_varargs_method("Manager", &ParameterGrpPy::getManager, "Manager()");
|
||||
add_varargs_method("Parent", &ParameterGrpPy::getParent, "Parent()");
|
||||
|
||||
add_varargs_method("IsEmpty",&ParameterGrpPy::isEmpty,"IsEmpty()");
|
||||
add_varargs_method("Clear",&ParameterGrpPy::clear,"Clear()");
|
||||
add_varargs_method("IsEmpty", &ParameterGrpPy::isEmpty, "IsEmpty()");
|
||||
add_varargs_method("Clear", &ParameterGrpPy::clear, "Clear()");
|
||||
|
||||
add_varargs_method("Attach",&ParameterGrpPy::attach,"Attach()");
|
||||
add_varargs_method("AttachManager",&ParameterGrpPy::attachManager,
|
||||
add_varargs_method("Attach", &ParameterGrpPy::attach, "Attach()");
|
||||
add_varargs_method(
|
||||
"AttachManager",
|
||||
&ParameterGrpPy::attachManager,
|
||||
"AttachManager(observer) -- attach parameter manager for notification\n\n"
|
||||
"This method attaches a user defined observer to the manager (i.e. the root)\n"
|
||||
"of the current parameter group to receive notification of all its parameters\n"
|
||||
@@ -204,52 +209,52 @@ void ParameterGrpPy::init_type()
|
||||
"* Group creation: both 'name' and 'value' contain the name of the new group\n"
|
||||
"* Group removal: both 'name' and 'value' are empty\n"
|
||||
"* Group rename: 'name' is the new name, and 'value' is the old name");
|
||||
add_varargs_method("Detach",&ParameterGrpPy::detach,"Detach()");
|
||||
add_varargs_method("Notify",&ParameterGrpPy::notify,"Notify()");
|
||||
add_varargs_method("NotifyAll",&ParameterGrpPy::notifyAll,"NotifyAll()");
|
||||
add_varargs_method("Detach", &ParameterGrpPy::detach, "Detach()");
|
||||
add_varargs_method("Notify", &ParameterGrpPy::notify, "Notify()");
|
||||
add_varargs_method("NotifyAll", &ParameterGrpPy::notifyAll, "NotifyAll()");
|
||||
|
||||
add_varargs_method("SetBool",&ParameterGrpPy::setBool,"SetBool()");
|
||||
add_varargs_method("GetBool",&ParameterGrpPy::getBool,"GetBool()");
|
||||
add_varargs_method("GetBools",&ParameterGrpPy::getBools,"GetBools()");
|
||||
add_varargs_method("RemBool",&ParameterGrpPy::remBool,"RemBool()");
|
||||
add_varargs_method("SetBool", &ParameterGrpPy::setBool, "SetBool()");
|
||||
add_varargs_method("GetBool", &ParameterGrpPy::getBool, "GetBool()");
|
||||
add_varargs_method("GetBools", &ParameterGrpPy::getBools, "GetBools()");
|
||||
add_varargs_method("RemBool", &ParameterGrpPy::remBool, "RemBool()");
|
||||
|
||||
add_varargs_method("SetInt",&ParameterGrpPy::setInt,"SetInt()");
|
||||
add_varargs_method("GetInt",&ParameterGrpPy::getInt,"GetInt()");
|
||||
add_varargs_method("GetInts",&ParameterGrpPy::getInts,"GetInts()");
|
||||
add_varargs_method("RemInt",&ParameterGrpPy::remInt,"RemInt()");
|
||||
add_varargs_method("SetInt", &ParameterGrpPy::setInt, "SetInt()");
|
||||
add_varargs_method("GetInt", &ParameterGrpPy::getInt, "GetInt()");
|
||||
add_varargs_method("GetInts", &ParameterGrpPy::getInts, "GetInts()");
|
||||
add_varargs_method("RemInt", &ParameterGrpPy::remInt, "RemInt()");
|
||||
|
||||
add_varargs_method("SetUnsigned",&ParameterGrpPy::setUnsigned,"SetUnsigned()");
|
||||
add_varargs_method("GetUnsigned",&ParameterGrpPy::getUnsigned,"GetUnsigned()");
|
||||
add_varargs_method("GetUnsigneds",&ParameterGrpPy::getUnsigneds,"GetUnsigneds()");
|
||||
add_varargs_method("RemUnsigned",&ParameterGrpPy::remUnsigned,"RemUnsigned()");
|
||||
add_varargs_method("SetUnsigned", &ParameterGrpPy::setUnsigned, "SetUnsigned()");
|
||||
add_varargs_method("GetUnsigned", &ParameterGrpPy::getUnsigned, "GetUnsigned()");
|
||||
add_varargs_method("GetUnsigneds", &ParameterGrpPy::getUnsigneds, "GetUnsigneds()");
|
||||
add_varargs_method("RemUnsigned", &ParameterGrpPy::remUnsigned, "RemUnsigned()");
|
||||
|
||||
add_varargs_method("SetFloat",&ParameterGrpPy::setFloat,"SetFloat()");
|
||||
add_varargs_method("GetFloat",&ParameterGrpPy::getFloat,"GetFloat()");
|
||||
add_varargs_method("GetFloats",&ParameterGrpPy::getFloats,"GetFloats()");
|
||||
add_varargs_method("RemFloat",&ParameterGrpPy::remFloat,"RemFloat()");
|
||||
add_varargs_method("SetFloat", &ParameterGrpPy::setFloat, "SetFloat()");
|
||||
add_varargs_method("GetFloat", &ParameterGrpPy::getFloat, "GetFloat()");
|
||||
add_varargs_method("GetFloats", &ParameterGrpPy::getFloats, "GetFloats()");
|
||||
add_varargs_method("RemFloat", &ParameterGrpPy::remFloat, "RemFloat()");
|
||||
|
||||
add_varargs_method("SetString",&ParameterGrpPy::setString,"SetString()");
|
||||
add_varargs_method("GetString",&ParameterGrpPy::getString,"GetString()");
|
||||
add_varargs_method("GetStrings",&ParameterGrpPy::getStrings,"GetStrings()");
|
||||
add_varargs_method("RemString",&ParameterGrpPy::remString,"RemString()");
|
||||
add_varargs_method("SetString", &ParameterGrpPy::setString, "SetString()");
|
||||
add_varargs_method("GetString", &ParameterGrpPy::getString, "GetString()");
|
||||
add_varargs_method("GetStrings", &ParameterGrpPy::getStrings, "GetStrings()");
|
||||
add_varargs_method("RemString", &ParameterGrpPy::remString, "RemString()");
|
||||
|
||||
add_varargs_method("Import",&ParameterGrpPy::importFrom,"Import()");
|
||||
add_varargs_method("Insert",&ParameterGrpPy::insert,"Insert()");
|
||||
add_varargs_method("Export",&ParameterGrpPy::exportTo,"Export()");
|
||||
add_varargs_method("Import", &ParameterGrpPy::importFrom, "Import()");
|
||||
add_varargs_method("Insert", &ParameterGrpPy::insert, "Insert()");
|
||||
add_varargs_method("Export", &ParameterGrpPy::exportTo, "Export()");
|
||||
|
||||
add_varargs_method("GetContents",&ParameterGrpPy::getContents,"GetContents()");
|
||||
add_varargs_method("GetContents", &ParameterGrpPy::getContents, "GetContents()");
|
||||
}
|
||||
|
||||
ParameterGrpPy::ParameterGrpPy(const Base::Reference<ParameterGrp> &rcParamGrp)
|
||||
: _cParamGrp(rcParamGrp)
|
||||
{
|
||||
}
|
||||
ParameterGrpPy::ParameterGrpPy(const Base::Reference<ParameterGrp>& rcParamGrp)
|
||||
: _cParamGrp(rcParamGrp)
|
||||
{}
|
||||
|
||||
ParameterGrpPy::~ParameterGrpPy()
|
||||
{
|
||||
for (ParameterGrpObserver* obs : _observers) {
|
||||
if (!obs->_target)
|
||||
if (!obs->_target) {
|
||||
_cParamGrp->Detach(obs);
|
||||
}
|
||||
delete obs;
|
||||
}
|
||||
}
|
||||
@@ -263,9 +268,10 @@ Py::Object ParameterGrpPy::repr()
|
||||
|
||||
Py::Object ParameterGrpPy::importFrom(const Py::Tuple& args)
|
||||
{
|
||||
char *pstr = nullptr;
|
||||
if (!PyArg_ParseTuple(args.ptr(), "s", &pstr))
|
||||
char* pstr = nullptr;
|
||||
if (!PyArg_ParseTuple(args.ptr(), "s", &pstr)) {
|
||||
throw Py::Exception();
|
||||
}
|
||||
|
||||
_cParamGrp->importFrom(pstr);
|
||||
return Py::None();
|
||||
@@ -273,9 +279,10 @@ Py::Object ParameterGrpPy::importFrom(const Py::Tuple& args)
|
||||
|
||||
Py::Object ParameterGrpPy::insert(const Py::Tuple& args)
|
||||
{
|
||||
char *pstr = nullptr;
|
||||
if (!PyArg_ParseTuple(args.ptr(), "s", &pstr))
|
||||
char* pstr = nullptr;
|
||||
if (!PyArg_ParseTuple(args.ptr(), "s", &pstr)) {
|
||||
throw Py::Exception();
|
||||
}
|
||||
|
||||
_cParamGrp->insert(pstr);
|
||||
return Py::None();
|
||||
@@ -283,9 +290,10 @@ Py::Object ParameterGrpPy::insert(const Py::Tuple& args)
|
||||
|
||||
Py::Object ParameterGrpPy::exportTo(const Py::Tuple& args)
|
||||
{
|
||||
char *pstr = nullptr;
|
||||
if (!PyArg_ParseTuple(args.ptr(), "s", &pstr))
|
||||
char* pstr = nullptr;
|
||||
if (!PyArg_ParseTuple(args.ptr(), "s", &pstr)) {
|
||||
throw Py::Exception();
|
||||
}
|
||||
|
||||
_cParamGrp->exportTo(pstr);
|
||||
return Py::None();
|
||||
@@ -293,16 +301,17 @@ Py::Object ParameterGrpPy::exportTo(const Py::Tuple& args)
|
||||
|
||||
Py::Object ParameterGrpPy::getGroup(const Py::Tuple& args)
|
||||
{
|
||||
char *pstr = nullptr;
|
||||
if (!PyArg_ParseTuple(args.ptr(), "s", &pstr))
|
||||
char* pstr = nullptr;
|
||||
if (!PyArg_ParseTuple(args.ptr(), "s", &pstr)) {
|
||||
throw Py::Exception();
|
||||
}
|
||||
|
||||
try {
|
||||
// get the Handle of the wanted group
|
||||
Base::Reference<ParameterGrp> handle = _cParamGrp->GetGroup(pstr);
|
||||
if (handle.isValid()) {
|
||||
// create a python wrapper class
|
||||
ParameterGrpPy *pcParamGrp = new ParameterGrpPy(handle);
|
||||
ParameterGrpPy* pcParamGrp = new ParameterGrpPy(handle);
|
||||
// increment the ref count
|
||||
return Py::asObject(pcParamGrp);
|
||||
}
|
||||
@@ -318,14 +327,15 @@ Py::Object ParameterGrpPy::getGroup(const Py::Tuple& args)
|
||||
|
||||
Py::Object ParameterGrpPy::getManager(const Py::Tuple& args)
|
||||
{
|
||||
if (!PyArg_ParseTuple(args.ptr(), ""))
|
||||
if (!PyArg_ParseTuple(args.ptr(), "")) {
|
||||
throw Py::Exception();
|
||||
}
|
||||
|
||||
// get the Handle of the wanted group
|
||||
Base::Reference<ParameterGrp> handle = _cParamGrp->Manager();
|
||||
if (handle.isValid()) {
|
||||
// create a python wrapper class
|
||||
ParameterGrpPy *pcParamGrp = new ParameterGrpPy(handle);
|
||||
ParameterGrpPy* pcParamGrp = new ParameterGrpPy(handle);
|
||||
// increment the ref count
|
||||
return Py::asObject(pcParamGrp);
|
||||
}
|
||||
@@ -335,14 +345,15 @@ Py::Object ParameterGrpPy::getManager(const Py::Tuple& args)
|
||||
|
||||
Py::Object ParameterGrpPy::getParent(const Py::Tuple& args)
|
||||
{
|
||||
if (!PyArg_ParseTuple(args.ptr(), ""))
|
||||
if (!PyArg_ParseTuple(args.ptr(), "")) {
|
||||
throw Py::Exception();
|
||||
}
|
||||
|
||||
// get the Handle of the wanted group
|
||||
Base::Reference<ParameterGrp> handle = _cParamGrp->Parent();
|
||||
if (handle.isValid()) {
|
||||
// create a python wrapper class
|
||||
ParameterGrpPy *pcParamGrp = new ParameterGrpPy(handle);
|
||||
ParameterGrpPy* pcParamGrp = new ParameterGrpPy(handle);
|
||||
// increment the ref count
|
||||
return Py::asObject(pcParamGrp);
|
||||
}
|
||||
@@ -352,8 +363,9 @@ Py::Object ParameterGrpPy::getParent(const Py::Tuple& args)
|
||||
|
||||
Py::Object ParameterGrpPy::getGroupName(const Py::Tuple& args)
|
||||
{
|
||||
if (!PyArg_ParseTuple(args.ptr(), ""))
|
||||
if (!PyArg_ParseTuple(args.ptr(), "")) {
|
||||
throw Py::Exception();
|
||||
}
|
||||
|
||||
// get the Handle of the wanted group
|
||||
std::string name = _cParamGrp->GetGroupName();
|
||||
@@ -362,11 +374,12 @@ Py::Object ParameterGrpPy::getGroupName(const Py::Tuple& args)
|
||||
|
||||
Py::Object ParameterGrpPy::getGroups(const Py::Tuple& args)
|
||||
{
|
||||
if (!PyArg_ParseTuple(args.ptr(), ""))
|
||||
if (!PyArg_ParseTuple(args.ptr(), "")) {
|
||||
throw Py::Exception();
|
||||
}
|
||||
|
||||
// get the Handle of the wanted group
|
||||
std::vector<Base::Reference<ParameterGrp> > handle = _cParamGrp->GetGroups();
|
||||
std::vector<Base::Reference<ParameterGrp>> handle = _cParamGrp->GetGroups();
|
||||
Py::List list;
|
||||
for (const auto& it : handle) {
|
||||
list.append(Py::String(it->GetGroupName()));
|
||||
@@ -377,32 +390,35 @@ Py::Object ParameterGrpPy::getGroups(const Py::Tuple& args)
|
||||
|
||||
Py::Object ParameterGrpPy::setBool(const Py::Tuple& args)
|
||||
{
|
||||
char *pstr = nullptr;
|
||||
int Bool = 0;
|
||||
if (!PyArg_ParseTuple(args.ptr(), "si", &pstr,&Bool))
|
||||
char* pstr = nullptr;
|
||||
int Bool = 0;
|
||||
if (!PyArg_ParseTuple(args.ptr(), "si", &pstr, &Bool)) {
|
||||
throw Py::Exception();
|
||||
}
|
||||
|
||||
_cParamGrp->SetBool(pstr,Bool!=0);
|
||||
_cParamGrp->SetBool(pstr, Bool != 0);
|
||||
return Py::None();
|
||||
}
|
||||
|
||||
Py::Object ParameterGrpPy::getBool(const Py::Tuple& args)
|
||||
{
|
||||
char *pstr = nullptr;
|
||||
int Bool=0;
|
||||
if (!PyArg_ParseTuple(args.ptr(), "s|i", &pstr,&Bool))
|
||||
char* pstr = nullptr;
|
||||
int Bool = 0;
|
||||
if (!PyArg_ParseTuple(args.ptr(), "s|i", &pstr, &Bool)) {
|
||||
throw Py::Exception();
|
||||
}
|
||||
|
||||
return Py::Boolean(_cParamGrp->GetBool(pstr,Bool!=0));
|
||||
return Py::Boolean(_cParamGrp->GetBool(pstr, Bool != 0));
|
||||
}
|
||||
|
||||
Py::Object ParameterGrpPy::getBools(const Py::Tuple& args)
|
||||
{
|
||||
char *filter=nullptr;
|
||||
if (!PyArg_ParseTuple(args.ptr(), "|s", &filter))
|
||||
char* filter = nullptr;
|
||||
if (!PyArg_ParseTuple(args.ptr(), "|s", &filter)) {
|
||||
throw Py::Exception();
|
||||
}
|
||||
|
||||
std::vector<std::pair<std::string,bool> > map = _cParamGrp->GetBoolMap(filter);
|
||||
std::vector<std::pair<std::string, bool>> map = _cParamGrp->GetBoolMap(filter);
|
||||
Py::List list;
|
||||
for (const auto& it : map) {
|
||||
list.append(Py::String(it.first));
|
||||
@@ -413,31 +429,34 @@ Py::Object ParameterGrpPy::getBools(const Py::Tuple& args)
|
||||
|
||||
Py::Object ParameterGrpPy::setInt(const Py::Tuple& args)
|
||||
{
|
||||
char *pstr = nullptr;
|
||||
int Int = 0;
|
||||
if (!PyArg_ParseTuple(args.ptr(), "si", &pstr,&Int))
|
||||
char* pstr = nullptr;
|
||||
int Int = 0;
|
||||
if (!PyArg_ParseTuple(args.ptr(), "si", &pstr, &Int)) {
|
||||
throw Py::Exception();
|
||||
}
|
||||
|
||||
_cParamGrp->SetInt(pstr,Int);
|
||||
_cParamGrp->SetInt(pstr, Int);
|
||||
return Py::None();
|
||||
}
|
||||
|
||||
Py::Object ParameterGrpPy::getInt(const Py::Tuple& args)
|
||||
{
|
||||
char *pstr = nullptr;
|
||||
int Int=0;
|
||||
if (!PyArg_ParseTuple(args.ptr(), "s|i", &pstr,&Int))
|
||||
char* pstr = nullptr;
|
||||
int Int = 0;
|
||||
if (!PyArg_ParseTuple(args.ptr(), "s|i", &pstr, &Int)) {
|
||||
throw Py::Exception();
|
||||
return Py::Long(_cParamGrp->GetInt(pstr,Int));
|
||||
}
|
||||
return Py::Long(_cParamGrp->GetInt(pstr, Int));
|
||||
}
|
||||
|
||||
Py::Object ParameterGrpPy::getInts(const Py::Tuple& args)
|
||||
{
|
||||
char *filter=nullptr;
|
||||
if (!PyArg_ParseTuple(args.ptr(), "|s", &filter))
|
||||
char* filter = nullptr;
|
||||
if (!PyArg_ParseTuple(args.ptr(), "|s", &filter)) {
|
||||
throw Py::Exception();
|
||||
}
|
||||
|
||||
std::vector<std::pair<std::string,long> > map = _cParamGrp->GetIntMap(filter);
|
||||
std::vector<std::pair<std::string, long>> map = _cParamGrp->GetIntMap(filter);
|
||||
Py::List list;
|
||||
for (const auto& it : map) {
|
||||
list.append(Py::String(it.first));
|
||||
@@ -448,31 +467,34 @@ Py::Object ParameterGrpPy::getInts(const Py::Tuple& args)
|
||||
|
||||
Py::Object ParameterGrpPy::setUnsigned(const Py::Tuple& args)
|
||||
{
|
||||
char *pstr = nullptr;
|
||||
unsigned int UInt = 0;
|
||||
if (!PyArg_ParseTuple(args.ptr(), "sI", &pstr,&UInt))
|
||||
char* pstr = nullptr;
|
||||
unsigned int UInt = 0;
|
||||
if (!PyArg_ParseTuple(args.ptr(), "sI", &pstr, &UInt)) {
|
||||
throw Py::Exception();
|
||||
}
|
||||
|
||||
_cParamGrp->SetUnsigned(pstr,UInt);
|
||||
_cParamGrp->SetUnsigned(pstr, UInt);
|
||||
return Py::None();
|
||||
}
|
||||
|
||||
Py::Object ParameterGrpPy::getUnsigned(const Py::Tuple& args)
|
||||
{
|
||||
char *pstr = nullptr;
|
||||
unsigned int UInt=0;
|
||||
if (!PyArg_ParseTuple(args.ptr(), "s|I", &pstr,&UInt))
|
||||
char* pstr = nullptr;
|
||||
unsigned int UInt = 0;
|
||||
if (!PyArg_ParseTuple(args.ptr(), "s|I", &pstr, &UInt)) {
|
||||
throw Py::Exception();
|
||||
return Py::Long(_cParamGrp->GetUnsigned(pstr,UInt));
|
||||
}
|
||||
return Py::Long(_cParamGrp->GetUnsigned(pstr, UInt));
|
||||
}
|
||||
|
||||
Py::Object ParameterGrpPy::getUnsigneds(const Py::Tuple& args)
|
||||
{
|
||||
char *filter=nullptr;
|
||||
if (!PyArg_ParseTuple(args.ptr(), "|s", &filter))
|
||||
char* filter = nullptr;
|
||||
if (!PyArg_ParseTuple(args.ptr(), "|s", &filter)) {
|
||||
throw Py::Exception();
|
||||
}
|
||||
|
||||
std::vector<std::pair<std::string,unsigned long> > map = _cParamGrp->GetUnsignedMap(filter);
|
||||
std::vector<std::pair<std::string, unsigned long>> map = _cParamGrp->GetUnsignedMap(filter);
|
||||
Py::List list;
|
||||
for (const auto& it : map) {
|
||||
list.append(Py::String(it.first));
|
||||
@@ -483,32 +505,35 @@ Py::Object ParameterGrpPy::getUnsigneds(const Py::Tuple& args)
|
||||
|
||||
Py::Object ParameterGrpPy::setFloat(const Py::Tuple& args)
|
||||
{
|
||||
char *pstr = nullptr;
|
||||
double Float{};
|
||||
if (!PyArg_ParseTuple(args.ptr(), "sd", &pstr,&Float))
|
||||
char* pstr = nullptr;
|
||||
double Float {};
|
||||
if (!PyArg_ParseTuple(args.ptr(), "sd", &pstr, &Float)) {
|
||||
throw Py::Exception();
|
||||
}
|
||||
|
||||
_cParamGrp->SetFloat(pstr,Float);
|
||||
_cParamGrp->SetFloat(pstr, Float);
|
||||
return Py::None();
|
||||
}
|
||||
|
||||
Py::Object ParameterGrpPy::getFloat(const Py::Tuple& args)
|
||||
{
|
||||
char *pstr = nullptr;
|
||||
double Float=0.0;
|
||||
if (!PyArg_ParseTuple(args.ptr(), "s|d", &pstr,&Float))
|
||||
char* pstr = nullptr;
|
||||
double Float = 0.0;
|
||||
if (!PyArg_ParseTuple(args.ptr(), "s|d", &pstr, &Float)) {
|
||||
throw Py::Exception();
|
||||
}
|
||||
|
||||
return Py::Float(_cParamGrp->GetFloat(pstr,Float));
|
||||
return Py::Float(_cParamGrp->GetFloat(pstr, Float));
|
||||
}
|
||||
|
||||
Py::Object ParameterGrpPy::getFloats(const Py::Tuple& args)
|
||||
{
|
||||
char *filter=nullptr;
|
||||
if (!PyArg_ParseTuple(args.ptr(), "|s", &filter))
|
||||
char* filter = nullptr;
|
||||
if (!PyArg_ParseTuple(args.ptr(), "|s", &filter)) {
|
||||
throw Py::Exception();
|
||||
}
|
||||
|
||||
std::vector<std::pair<std::string,double> > map = _cParamGrp->GetFloatMap(filter);
|
||||
std::vector<std::pair<std::string, double>> map = _cParamGrp->GetFloatMap(filter);
|
||||
Py::List list;
|
||||
for (const auto& it : map) {
|
||||
list.append(Py::String(it.first));
|
||||
@@ -519,32 +544,35 @@ Py::Object ParameterGrpPy::getFloats(const Py::Tuple& args)
|
||||
|
||||
Py::Object ParameterGrpPy::setString(const Py::Tuple& args)
|
||||
{
|
||||
char *pstr = nullptr;
|
||||
char * str = nullptr;
|
||||
if (!PyArg_ParseTuple(args.ptr(), "ss", &pstr,&str))
|
||||
char* pstr = nullptr;
|
||||
char* str = nullptr;
|
||||
if (!PyArg_ParseTuple(args.ptr(), "ss", &pstr, &str)) {
|
||||
throw Py::Exception();
|
||||
}
|
||||
|
||||
_cParamGrp->SetASCII(pstr,str);
|
||||
_cParamGrp->SetASCII(pstr, str);
|
||||
return Py::None();
|
||||
}
|
||||
|
||||
Py::Object ParameterGrpPy::getString(const Py::Tuple& args)
|
||||
{
|
||||
char *pstr = nullptr;
|
||||
char * str="";
|
||||
if (!PyArg_ParseTuple(args.ptr(), "s|s", &pstr,&str))
|
||||
char* pstr = nullptr;
|
||||
char* str = "";
|
||||
if (!PyArg_ParseTuple(args.ptr(), "s|s", &pstr, &str)) {
|
||||
throw Py::Exception();
|
||||
}
|
||||
|
||||
return Py::String(_cParamGrp->GetASCII(pstr,str));
|
||||
return Py::String(_cParamGrp->GetASCII(pstr, str));
|
||||
}
|
||||
|
||||
Py::Object ParameterGrpPy::getStrings(const Py::Tuple& args)
|
||||
{
|
||||
char *filter=nullptr;
|
||||
if (!PyArg_ParseTuple(args.ptr(), "|s", &filter))
|
||||
char* filter = nullptr;
|
||||
if (!PyArg_ParseTuple(args.ptr(), "|s", &filter)) {
|
||||
throw Py::Exception();
|
||||
}
|
||||
|
||||
std::vector<std::pair<std::string,std::string> > map = _cParamGrp->GetASCIIMap(filter);
|
||||
std::vector<std::pair<std::string, std::string>> map = _cParamGrp->GetASCIIMap(filter);
|
||||
Py::List list;
|
||||
for (const auto& it : map) {
|
||||
list.append(Py::String(it.first));
|
||||
@@ -555,9 +583,10 @@ Py::Object ParameterGrpPy::getStrings(const Py::Tuple& args)
|
||||
|
||||
Py::Object ParameterGrpPy::remInt(const Py::Tuple& args)
|
||||
{
|
||||
char *pstr = nullptr;
|
||||
if (!PyArg_ParseTuple(args.ptr(), "s", &pstr))
|
||||
char* pstr = nullptr;
|
||||
if (!PyArg_ParseTuple(args.ptr(), "s", &pstr)) {
|
||||
throw Py::Exception();
|
||||
}
|
||||
|
||||
_cParamGrp->RemoveInt(pstr);
|
||||
return Py::None();
|
||||
@@ -565,9 +594,10 @@ Py::Object ParameterGrpPy::remInt(const Py::Tuple& args)
|
||||
|
||||
Py::Object ParameterGrpPy::remUnsigned(const Py::Tuple& args)
|
||||
{
|
||||
char *pstr = nullptr;
|
||||
if (!PyArg_ParseTuple(args.ptr(), "s", &pstr))
|
||||
char* pstr = nullptr;
|
||||
if (!PyArg_ParseTuple(args.ptr(), "s", &pstr)) {
|
||||
throw Py::Exception();
|
||||
}
|
||||
|
||||
_cParamGrp->RemoveUnsigned(pstr);
|
||||
return Py::None();
|
||||
@@ -575,9 +605,10 @@ Py::Object ParameterGrpPy::remUnsigned(const Py::Tuple& args)
|
||||
|
||||
Py::Object ParameterGrpPy::remBool(const Py::Tuple& args)
|
||||
{
|
||||
char *pstr = nullptr;
|
||||
if (!PyArg_ParseTuple(args.ptr(), "s", &pstr))
|
||||
char* pstr = nullptr;
|
||||
if (!PyArg_ParseTuple(args.ptr(), "s", &pstr)) {
|
||||
throw Py::Exception();
|
||||
}
|
||||
|
||||
_cParamGrp->RemoveBool(pstr);
|
||||
return Py::None();
|
||||
@@ -585,9 +616,10 @@ Py::Object ParameterGrpPy::remBool(const Py::Tuple& args)
|
||||
|
||||
Py::Object ParameterGrpPy::remGroup(const Py::Tuple& args)
|
||||
{
|
||||
char *pstr = nullptr;
|
||||
if (!PyArg_ParseTuple(args.ptr(), "s", &pstr))
|
||||
char* pstr = nullptr;
|
||||
if (!PyArg_ParseTuple(args.ptr(), "s", &pstr)) {
|
||||
throw Py::Exception();
|
||||
}
|
||||
|
||||
_cParamGrp->RemoveGrp(pstr);
|
||||
return Py::None();
|
||||
@@ -595,9 +627,10 @@ Py::Object ParameterGrpPy::remGroup(const Py::Tuple& args)
|
||||
|
||||
Py::Object ParameterGrpPy::remFloat(const Py::Tuple& args)
|
||||
{
|
||||
char *pstr = nullptr;
|
||||
if (!PyArg_ParseTuple(args.ptr(), "s", &pstr))
|
||||
char* pstr = nullptr;
|
||||
if (!PyArg_ParseTuple(args.ptr(), "s", &pstr)) {
|
||||
throw Py::Exception();
|
||||
}
|
||||
|
||||
_cParamGrp->RemoveFloat(pstr);
|
||||
return Py::None();
|
||||
@@ -605,9 +638,10 @@ Py::Object ParameterGrpPy::remFloat(const Py::Tuple& args)
|
||||
|
||||
Py::Object ParameterGrpPy::remString(const Py::Tuple& args)
|
||||
{
|
||||
char *pstr = nullptr;
|
||||
if (!PyArg_ParseTuple(args.ptr(), "s", &pstr))
|
||||
char* pstr = nullptr;
|
||||
if (!PyArg_ParseTuple(args.ptr(), "s", &pstr)) {
|
||||
throw Py::Exception();
|
||||
}
|
||||
|
||||
_cParamGrp->RemoveASCII(pstr);
|
||||
return Py::None();
|
||||
@@ -615,8 +649,9 @@ Py::Object ParameterGrpPy::remString(const Py::Tuple& args)
|
||||
|
||||
Py::Object ParameterGrpPy::clear(const Py::Tuple& args)
|
||||
{
|
||||
if (!PyArg_ParseTuple(args.ptr(), ""))
|
||||
if (!PyArg_ParseTuple(args.ptr(), "")) {
|
||||
throw Py::Exception();
|
||||
}
|
||||
|
||||
_cParamGrp->Clear();
|
||||
return Py::None();
|
||||
@@ -624,17 +659,19 @@ Py::Object ParameterGrpPy::clear(const Py::Tuple& args)
|
||||
|
||||
Py::Object ParameterGrpPy::isEmpty(const Py::Tuple& args)
|
||||
{
|
||||
if (!PyArg_ParseTuple(args.ptr(), ""))
|
||||
if (!PyArg_ParseTuple(args.ptr(), "")) {
|
||||
throw Py::Exception();
|
||||
}
|
||||
|
||||
return Py::Boolean(_cParamGrp->IsEmpty());
|
||||
}
|
||||
|
||||
Py::Object ParameterGrpPy::hasGroup(const Py::Tuple& args)
|
||||
{
|
||||
char *pstr = nullptr;
|
||||
if (!PyArg_ParseTuple(args.ptr(), "s", &pstr))
|
||||
char* pstr = nullptr;
|
||||
if (!PyArg_ParseTuple(args.ptr(), "s", &pstr)) {
|
||||
throw Py::Exception();
|
||||
}
|
||||
|
||||
return Py::Boolean(_cParamGrp->HasGroup(pstr));
|
||||
}
|
||||
@@ -642,12 +679,14 @@ Py::Object ParameterGrpPy::hasGroup(const Py::Tuple& args)
|
||||
Py::Object ParameterGrpPy::attach(const Py::Tuple& args)
|
||||
{
|
||||
PyObject* obj = nullptr;
|
||||
if (!PyArg_ParseTuple(args.ptr(), "O", &obj))
|
||||
if (!PyArg_ParseTuple(args.ptr(), "O", &obj)) {
|
||||
throw Py::Exception();
|
||||
}
|
||||
|
||||
Py::Object o(obj);
|
||||
if (!o.hasAttr(std::string("onChange")))
|
||||
if (!o.hasAttr(std::string("onChange"))) {
|
||||
throw Py::TypeError("Object has no onChange attribute");
|
||||
}
|
||||
|
||||
for (ParameterGrpObserver* it : _observers) {
|
||||
if (it->isEqual(o)) {
|
||||
@@ -665,19 +704,23 @@ Py::Object ParameterGrpPy::attach(const Py::Tuple& args)
|
||||
Py::Object ParameterGrpPy::attachManager(const Py::Tuple& args)
|
||||
{
|
||||
PyObject* obj = nullptr;
|
||||
if (!PyArg_ParseTuple(args.ptr(), "O", &obj))
|
||||
if (!PyArg_ParseTuple(args.ptr(), "O", &obj)) {
|
||||
throw Py::Exception();
|
||||
}
|
||||
|
||||
if (!_cParamGrp->Manager())
|
||||
if (!_cParamGrp->Manager()) {
|
||||
throw Py::RuntimeError("Parameter has no manager");
|
||||
}
|
||||
|
||||
Py::Object o(obj);
|
||||
if (!o.hasAttr(std::string("slotParamChanged")))
|
||||
if (!o.hasAttr(std::string("slotParamChanged"))) {
|
||||
throw Py::TypeError("Object has no slotParamChanged attribute");
|
||||
}
|
||||
|
||||
Py::Object attr(o.getAttr("slotParamChanged"));
|
||||
if (!attr.isCallable())
|
||||
if (!attr.isCallable()) {
|
||||
throw Py::TypeError("Object has no slotParamChanged callable attribute");
|
||||
}
|
||||
|
||||
for (ParameterGrpObserver* it : _observers) {
|
||||
if (it->isEqual(o)) {
|
||||
@@ -686,20 +729,25 @@ Py::Object ParameterGrpPy::attachManager(const Py::Tuple& args)
|
||||
}
|
||||
|
||||
ParameterGrpObserver* obs = new ParameterGrpObserver(o, attr, _cParamGrp);
|
||||
obs->conn = _cParamGrp->Manager()->signalParamChanged.connect(
|
||||
[obs](ParameterGrp *Param, ParameterGrp::ParamType Type, const char *Name, const char *Value) {
|
||||
if (!Param) return;
|
||||
obs->conn =
|
||||
_cParamGrp->Manager()->signalParamChanged.connect([obs](ParameterGrp* Param,
|
||||
ParameterGrp::ParamType Type,
|
||||
const char* Name,
|
||||
const char* Value) {
|
||||
if (!Param) {
|
||||
return;
|
||||
}
|
||||
for (auto p = Param; p; p = p->Parent()) {
|
||||
if (p == obs->_target) {
|
||||
Base::PyGILStateLocker lock;
|
||||
Py::TupleN args(
|
||||
Py::asObject(new ParameterGrpPy(Param)),
|
||||
Py::String(ParameterGrp::TypeName(Type)),
|
||||
Py::String(Name ? Name : ""),
|
||||
Py::String(Value ? Value : ""));
|
||||
Py::TupleN args(Py::asObject(new ParameterGrpPy(Param)),
|
||||
Py::String(ParameterGrp::TypeName(Type)),
|
||||
Py::String(Name ? Name : ""),
|
||||
Py::String(Value ? Value : ""));
|
||||
try {
|
||||
Py::Callable(obs->callable).apply(args);
|
||||
} catch (Py::Exception &) {
|
||||
}
|
||||
catch (Py::Exception&) {
|
||||
Base::PyException e;
|
||||
e.ReportException();
|
||||
}
|
||||
@@ -715,12 +763,14 @@ Py::Object ParameterGrpPy::attachManager(const Py::Tuple& args)
|
||||
Py::Object ParameterGrpPy::detach(const Py::Tuple& args)
|
||||
{
|
||||
PyObject* obj = nullptr;
|
||||
if (!PyArg_ParseTuple(args.ptr(), "O", &obj))
|
||||
if (!PyArg_ParseTuple(args.ptr(), "O", &obj)) {
|
||||
throw Py::Exception();
|
||||
}
|
||||
|
||||
Py::Object o(obj);
|
||||
if (!o.hasAttr(std::string("onChange")))
|
||||
if (!o.hasAttr(std::string("onChange"))) {
|
||||
throw Py::TypeError("Object has no onChange attribute");
|
||||
}
|
||||
|
||||
for (ParameterGrpObserverList::iterator it = _observers.begin(); it != _observers.end(); ++it) {
|
||||
if ((*it)->isEqual(o)) {
|
||||
@@ -737,9 +787,10 @@ Py::Object ParameterGrpPy::detach(const Py::Tuple& args)
|
||||
|
||||
Py::Object ParameterGrpPy::notify(const Py::Tuple& args)
|
||||
{
|
||||
char *pstr = nullptr;
|
||||
if (!PyArg_ParseTuple(args.ptr(), "s", &pstr))
|
||||
char* pstr = nullptr;
|
||||
if (!PyArg_ParseTuple(args.ptr(), "s", &pstr)) {
|
||||
throw Py::Exception();
|
||||
}
|
||||
|
||||
_cParamGrp->Notify(pstr);
|
||||
return Py::None();
|
||||
@@ -747,8 +798,9 @@ Py::Object ParameterGrpPy::notify(const Py::Tuple& args)
|
||||
|
||||
Py::Object ParameterGrpPy::notifyAll(const Py::Tuple& args)
|
||||
{
|
||||
if (!PyArg_ParseTuple(args.ptr(), ""))
|
||||
if (!PyArg_ParseTuple(args.ptr(), "")) {
|
||||
throw Py::Exception();
|
||||
}
|
||||
|
||||
_cParamGrp->NotifyAll();
|
||||
return Py::None();
|
||||
@@ -756,71 +808,73 @@ Py::Object ParameterGrpPy::notifyAll(const Py::Tuple& args)
|
||||
|
||||
Py::Object ParameterGrpPy::getContents(const Py::Tuple& args)
|
||||
{
|
||||
if (!PyArg_ParseTuple(args.ptr(), ""))
|
||||
if (!PyArg_ParseTuple(args.ptr(), "")) {
|
||||
throw Py::Exception();
|
||||
}
|
||||
|
||||
if (_cParamGrp->IsEmpty())
|
||||
if (_cParamGrp->IsEmpty()) {
|
||||
return Py::None();
|
||||
}
|
||||
|
||||
Py::List list;
|
||||
// filling up Text nodes
|
||||
std::vector<std::pair<std::string,std::string> > mcTextMap = _cParamGrp->GetASCIIMap();
|
||||
for (const auto & it : mcTextMap) {
|
||||
std::vector<std::pair<std::string, std::string>> mcTextMap = _cParamGrp->GetASCIIMap();
|
||||
for (const auto& it : mcTextMap) {
|
||||
Py::Tuple t2(3);
|
||||
t2.setItem(0,Py::String("String"));
|
||||
t2.setItem(1,Py::String(it.first.c_str()));
|
||||
t2.setItem(2,Py::String(it.second.c_str()));
|
||||
t2.setItem(0, Py::String("String"));
|
||||
t2.setItem(1, Py::String(it.first.c_str()));
|
||||
t2.setItem(2, Py::String(it.second.c_str()));
|
||||
list.append(t2);
|
||||
}
|
||||
|
||||
// filling up Int nodes
|
||||
std::vector<std::pair<std::string,long> > mcIntMap = _cParamGrp->GetIntMap();
|
||||
for (const auto & it : mcIntMap) {
|
||||
std::vector<std::pair<std::string, long>> mcIntMap = _cParamGrp->GetIntMap();
|
||||
for (const auto& it : mcIntMap) {
|
||||
Py::Tuple t3(3);
|
||||
t3.setItem(0,Py::String("Integer"));
|
||||
t3.setItem(1,Py::String(it.first.c_str()));
|
||||
t3.setItem(2,Py::Long(it.second));
|
||||
t3.setItem(0, Py::String("Integer"));
|
||||
t3.setItem(1, Py::String(it.first.c_str()));
|
||||
t3.setItem(2, Py::Long(it.second));
|
||||
list.append(t3);
|
||||
}
|
||||
|
||||
// filling up Float nodes
|
||||
std::vector<std::pair<std::string,double> > mcFloatMap = _cParamGrp->GetFloatMap();
|
||||
for (const auto & it : mcFloatMap) {
|
||||
std::vector<std::pair<std::string, double>> mcFloatMap = _cParamGrp->GetFloatMap();
|
||||
for (const auto& it : mcFloatMap) {
|
||||
Py::Tuple t4(3);
|
||||
t4.setItem(0,Py::String("Float"));
|
||||
t4.setItem(1,Py::String(it.first.c_str()));
|
||||
t4.setItem(2,Py::Float(it.second));
|
||||
t4.setItem(0, Py::String("Float"));
|
||||
t4.setItem(1, Py::String(it.first.c_str()));
|
||||
t4.setItem(2, Py::Float(it.second));
|
||||
list.append(t4);
|
||||
}
|
||||
|
||||
// filling up bool nodes
|
||||
std::vector<std::pair<std::string,bool> > mcBoolMap = _cParamGrp->GetBoolMap();
|
||||
for (const auto & it : mcBoolMap) {
|
||||
std::vector<std::pair<std::string, bool>> mcBoolMap = _cParamGrp->GetBoolMap();
|
||||
for (const auto& it : mcBoolMap) {
|
||||
Py::Tuple t5(3);
|
||||
t5.setItem(0,Py::String("Boolean"));
|
||||
t5.setItem(1,Py::String(it.first.c_str()));
|
||||
t5.setItem(2,Py::Boolean(it.second));
|
||||
t5.setItem(0, Py::String("Boolean"));
|
||||
t5.setItem(1, Py::String(it.first.c_str()));
|
||||
t5.setItem(2, Py::Boolean(it.second));
|
||||
list.append(t5);
|
||||
}
|
||||
|
||||
// filling up UInt nodes
|
||||
std::vector<std::pair<std::string,unsigned long> > mcUIntMap = _cParamGrp->GetUnsignedMap();
|
||||
for (const auto & it : mcUIntMap) {
|
||||
std::vector<std::pair<std::string, unsigned long>> mcUIntMap = _cParamGrp->GetUnsignedMap();
|
||||
for (const auto& it : mcUIntMap) {
|
||||
Py::Tuple t6(3);
|
||||
t6.setItem(0,Py::String("Unsigned Long"));
|
||||
t6.setItem(1,Py::String(it.first.c_str()));
|
||||
t6.setItem(2,Py::Long(it.second));
|
||||
t6.setItem(0, Py::String("Unsigned Long"));
|
||||
t6.setItem(1, Py::String(it.first.c_str()));
|
||||
t6.setItem(2, Py::Long(it.second));
|
||||
list.append(t6);
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
} // namespace Base
|
||||
} // namespace Base
|
||||
|
||||
/** python wrapper function
|
||||
*/
|
||||
PyObject* GetPyObject(const Base::Reference<ParameterGrp> &hcParamGrp)
|
||||
*/
|
||||
PyObject* GetPyObject(const Base::Reference<ParameterGrp>& hcParamGrp)
|
||||
{
|
||||
static bool init = false;
|
||||
if (!init) {
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
C:\cygwin\bin\flex.exe -oQuantityLexer.c QuantityParser.l
|
||||
C:\cygwin\bin\bison -oQuantityParser.c QuantityParser.y
|
||||
C:\cygwin\bin\bison -oQuantityParser.c QuantityParser.y
|
||||
|
||||
@@ -37,66 +37,72 @@
|
||||
|
||||
using namespace Base;
|
||||
|
||||
TYPESYSTEM_SOURCE_ABSTRACT(Base::Persistence,Base::BaseClass)
|
||||
TYPESYSTEM_SOURCE_ABSTRACT(Base::Persistence, Base::BaseClass)
|
||||
|
||||
|
||||
//**************************************************************************
|
||||
// Construction/Destruction
|
||||
|
||||
|
||||
|
||||
//**************************************************************************
|
||||
// separator for other implementation aspects
|
||||
|
||||
unsigned int Persistence::getMemSize () const
|
||||
unsigned int Persistence::getMemSize() const
|
||||
{
|
||||
// you have to implement this method in all descending classes!
|
||||
assert(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Persistence::Save (Writer &/*writer*/) const
|
||||
void Persistence::Save(Writer& /*writer*/) const
|
||||
{
|
||||
// you have to implement this method in all descending classes!
|
||||
assert(0);
|
||||
}
|
||||
|
||||
void Persistence::Restore(XMLReader &/*reader*/)
|
||||
void Persistence::Restore(XMLReader& /*reader*/)
|
||||
{
|
||||
// you have to implement this method in all descending classes!
|
||||
assert(0);
|
||||
}
|
||||
|
||||
void Persistence::SaveDocFile (Writer &/*writer*/) const
|
||||
{
|
||||
}
|
||||
void Persistence::SaveDocFile(Writer& /*writer*/) const
|
||||
{}
|
||||
|
||||
void Persistence::RestoreDocFile(Reader &/*reader*/)
|
||||
{
|
||||
}
|
||||
void Persistence::RestoreDocFile(Reader& /*reader*/)
|
||||
{}
|
||||
|
||||
std::string Persistence::encodeAttribute(const std::string& str)
|
||||
{
|
||||
std::string tmp;
|
||||
for (char it : str) {
|
||||
if (it == '<')
|
||||
if (it == '<') {
|
||||
tmp += "<";
|
||||
else if (it == '\"')
|
||||
}
|
||||
else if (it == '\"') {
|
||||
tmp += """;
|
||||
else if (it == '\'')
|
||||
}
|
||||
else if (it == '\'') {
|
||||
tmp += "'";
|
||||
else if (it == '&')
|
||||
}
|
||||
else if (it == '&') {
|
||||
tmp += "&";
|
||||
else if (it == '>')
|
||||
}
|
||||
else if (it == '>') {
|
||||
tmp += ">";
|
||||
else if (it == '\r')
|
||||
}
|
||||
else if (it == '\r') {
|
||||
tmp += " ";
|
||||
else if (it == '\n')
|
||||
}
|
||||
else if (it == '\n') {
|
||||
tmp += " ";
|
||||
else if (it == '\t')
|
||||
}
|
||||
else if (it == '\t') {
|
||||
tmp += "	";
|
||||
else
|
||||
}
|
||||
else {
|
||||
tmp += it;
|
||||
}
|
||||
}
|
||||
|
||||
return tmp;
|
||||
@@ -104,16 +110,17 @@ std::string Persistence::encodeAttribute(const std::string& str)
|
||||
|
||||
void Persistence::dumpToStream(std::ostream& stream, int compression)
|
||||
{
|
||||
//we need to close the zipstream to get a good result, the only way to do this is to delete the ZipWriter.
|
||||
//Hence the scope...
|
||||
// we need to close the zipstream to get a good result, the only way to do this is to delete the
|
||||
// ZipWriter. Hence the scope...
|
||||
{
|
||||
//create the writer
|
||||
// create the writer
|
||||
Base::ZipWriter writer(stream);
|
||||
writer.setLevel(compression);
|
||||
writer.putNextEntry("Persistence.xml");
|
||||
writer.setMode("BinaryBrep");
|
||||
|
||||
//save the content (we need to encapsulate it with xml tags to be able to read single element xmls like happen for properties)
|
||||
// save the content (we need to encapsulate it with xml tags to be able to read single
|
||||
// element xmls like happen for properties)
|
||||
writer.Stream() << "<Content>" << std::endl;
|
||||
Save(writer);
|
||||
writer.Stream() << "</Content>";
|
||||
@@ -126,8 +133,9 @@ void Persistence::restoreFromStream(std::istream& stream)
|
||||
zipios::ZipInputStream zipstream(stream);
|
||||
Base::XMLReader reader("", zipstream);
|
||||
|
||||
if (!reader.isValid())
|
||||
if (!reader.isValid()) {
|
||||
throw Base::ValueError("Unable to construct reader");
|
||||
}
|
||||
|
||||
reader.readElement("Content");
|
||||
Restore(reader);
|
||||
|
||||
@@ -33,17 +33,17 @@ class Writer;
|
||||
class XMLReader;
|
||||
|
||||
/// Persistence class and root of the type system
|
||||
class BaseExport Persistence : public BaseClass
|
||||
class BaseExport Persistence: public BaseClass
|
||||
{
|
||||
|
||||
TYPESYSTEM_HEADER();
|
||||
TYPESYSTEM_HEADER();
|
||||
|
||||
public:
|
||||
/** This method is used to get the size of objects
|
||||
* It is not meant to have the exact size, it is more or less an estimation
|
||||
* which runs fast! Is it two bytes or a GB?
|
||||
*/
|
||||
virtual unsigned int getMemSize () const = 0;
|
||||
virtual unsigned int getMemSize() const = 0;
|
||||
/** This method is used to save properties to an XML document.
|
||||
* A good example you'll find in PropertyStandard.cpp, e.g. the vector:
|
||||
* \code
|
||||
@@ -60,7 +60,7 @@ public:
|
||||
* is written. This means closing tags and writing UTF-8.
|
||||
* @see Base::Writer
|
||||
*/
|
||||
virtual void Save (Writer &/*writer*/) const = 0;
|
||||
virtual void Save(Writer& /*writer*/) const = 0;
|
||||
/** This method is used to restore properties from an XML document.
|
||||
* It uses the XMLReader class, which bases on SAX, to read the in Save()
|
||||
* written information. Again the Vector as an example:
|
||||
@@ -76,7 +76,7 @@ public:
|
||||
* }
|
||||
* \endcode
|
||||
*/
|
||||
virtual void Restore(XMLReader &/*reader*/) = 0;
|
||||
virtual void Restore(XMLReader& /*reader*/) = 0;
|
||||
/** This method is used to save large amounts of data to a binary file.
|
||||
* Sometimes it makes no sense to write property data as XML. In case the
|
||||
* amount of data is too big or the data type has a more effective way to
|
||||
@@ -93,24 +93,25 @@ public:
|
||||
* MeshCore::MeshDocXML saver(*_pcMesh);
|
||||
* saver.Save(writer);
|
||||
* }else{
|
||||
* writer << writer.ind() << "<Mesh file=\"" << writer.addFile("MeshKernel.bms", this) << "\"/>" << std::endl;
|
||||
* writer << writer.ind() << "<Mesh file=\"" << writer.addFile("MeshKernel.bms", this) <<
|
||||
* "\"/>" << std::endl;
|
||||
* }
|
||||
* \endcode
|
||||
* The writer.isForceXML() is an indication to force you to write XML. Regardless of size and effectiveness.
|
||||
* The second part informs the Base::writer through writer.addFile("MeshKernel.bms", this) that this object
|
||||
* wants to write a file with the given name. The method addFile() returns a unique name that then is written
|
||||
* in the XML stream.
|
||||
* This allows your RestoreDocFile() method to identify and read the file again.
|
||||
* Later your SaveDocFile() method is called as many times as you issued the addFile() call:
|
||||
* \code
|
||||
* void PropertyMeshKernel::SaveDocFile (Base::Writer &writer) const
|
||||
* The writer.isForceXML() is an indication to force you to write XML. Regardless of size and
|
||||
* effectiveness. The second part informs the Base::writer through
|
||||
* writer.addFile("MeshKernel.bms", this) that this object wants to write a file with the given
|
||||
* name. The method addFile() returns a unique name that then is written in the XML stream. This
|
||||
* allows your RestoreDocFile() method to identify and read the file again. Later your
|
||||
* SaveDocFile() method is called as many times as you issued the addFile() call: \code void
|
||||
* PropertyMeshKernel::SaveDocFile (Base::Writer &writer) const
|
||||
* {
|
||||
* _pcMesh->Write( writer );
|
||||
* }
|
||||
* \endcode
|
||||
* In this method you can simply stream your content to the file (Base::Writer inheriting from ostream).
|
||||
* In this method you can simply stream your content to the file (Base::Writer inheriting from
|
||||
* ostream).
|
||||
*/
|
||||
virtual void SaveDocFile (Writer &/*writer*/) const;
|
||||
virtual void SaveDocFile(Writer& /*writer*/) const;
|
||||
/** This method is used to restore large amounts of data from a file
|
||||
* In this method you simply stream in your SaveDocFile() saved data.
|
||||
* Again you have to apply for the call of this method in the Restore() call:
|
||||
@@ -140,14 +141,14 @@ public:
|
||||
* \endcode
|
||||
* @see Base::Reader,Base::XMLReader
|
||||
*/
|
||||
virtual void RestoreDocFile(Reader &/*reader*/);
|
||||
virtual void RestoreDocFile(Reader& /*reader*/);
|
||||
/// Encodes an attribute upon saving.
|
||||
static std::string encodeAttribute(const std::string&);
|
||||
|
||||
//dump the binary persistence data into into the stream
|
||||
// dump the binary persistence data into into the stream
|
||||
void dumpToStream(std::ostream& stream, int compression);
|
||||
|
||||
//restore the binary persistence data from a stream. Must have the format used by dumpToStream
|
||||
// restore the binary persistence data from a stream. Must have the format used by dumpToStream
|
||||
void restoreFromStream(std::istream& stream);
|
||||
|
||||
private:
|
||||
@@ -156,10 +157,11 @@ private:
|
||||
* A subclass can set up some internals. The default
|
||||
* implementation does nothing.
|
||||
*/
|
||||
virtual void restoreFinished() {}
|
||||
virtual void restoreFinished()
|
||||
{}
|
||||
};
|
||||
|
||||
} //namespace Base
|
||||
} // namespace Base
|
||||
|
||||
|
||||
#endif // APP_PERSISTENCE_H
|
||||
#endif // APP_PERSISTENCE_H
|
||||
|
||||
@@ -1,18 +1,18 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<GenerateModel xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="generateMetaModel_Module.xsd">
|
||||
<PythonExport
|
||||
Father="BaseClassPy"
|
||||
Name="PersistencePy"
|
||||
Twin="Persistence"
|
||||
TwinPointer="Persistence"
|
||||
Include="Base/Persistence.h"
|
||||
FatherInclude="Base/BaseClassPy.h"
|
||||
Namespace="Base"
|
||||
<PythonExport
|
||||
Father="BaseClassPy"
|
||||
Name="PersistencePy"
|
||||
Twin="Persistence"
|
||||
TwinPointer="Persistence"
|
||||
Include="Base/Persistence.h"
|
||||
FatherInclude="Base/BaseClassPy.h"
|
||||
Namespace="Base"
|
||||
FatherNamespace="Base">
|
||||
<Documentation>
|
||||
<Author Licence="LGPL" Name="Juergen Riegel" EMail="FreeCAD@juergen-riegel.net" />
|
||||
<DeveloperDocu>This is the Persistence class</DeveloperDocu>
|
||||
<UserDocu>Base.Persistence class.
|
||||
<UserDocu>Base.Persistence class.
|
||||
|
||||
Class to dump and restore the content of an object.</UserDocu>
|
||||
</Documentation>
|
||||
@@ -30,23 +30,23 @@ Class to dump and restore the content of an object.</UserDocu>
|
||||
</Attribute>
|
||||
<Methode Name="dumpContent" Keyword="true" Const="true">
|
||||
<Documentation>
|
||||
<UserDocu>dumpContent(Compression=3) -> bytearray
|
||||
<UserDocu>dumpContent(Compression=3) -> bytearray
|
||||
|
||||
Dumps the content of the object, both the XML representation and the additional
|
||||
data files required, into a byte representation.
|
||||
data files required, into a byte representation.
|
||||
|
||||
Compression : int
|
||||
Compression : int
|
||||
Set the data compression level in the range [0,9]. Set to 0 for no compression.</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Methode Name="restoreContent">
|
||||
<Documentation>
|
||||
<UserDocu>restoreContent(obj) -> None
|
||||
<UserDocu>restoreContent(obj) -> None
|
||||
|
||||
Restore the content of the object from a byte representation as stored by `dumpContent`.
|
||||
It could be restored from any Python object implementing the buffer protocol.
|
||||
It could be restored from any Python object implementing the buffer protocol.
|
||||
|
||||
obj : buffer
|
||||
obj : buffer
|
||||
Object with buffer protocol support.</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
|
||||
@@ -49,7 +49,7 @@ Py::String PersistencePy::getContent() const
|
||||
writer.setForceXML(true);
|
||||
getPersistencePtr()->Save(writer);
|
||||
|
||||
return {writer.getString()};
|
||||
return {writer.getString()};
|
||||
}
|
||||
|
||||
Py::Int PersistencePy::getMemSize() const
|
||||
@@ -57,31 +57,33 @@ Py::Int PersistencePy::getMemSize() const
|
||||
return Py::Int((long)getPersistencePtr()->getMemSize());
|
||||
}
|
||||
|
||||
PyObject* PersistencePy::dumpContent(PyObject *args, PyObject *kwds)
|
||||
PyObject* PersistencePy::dumpContent(PyObject* args, PyObject* kwds)
|
||||
{
|
||||
int compression = 3;
|
||||
static const std::array<const char *, 2> kwds_def {"Compression", nullptr};
|
||||
static const std::array<const char*, 2> kwds_def {"Compression", nullptr};
|
||||
PyErr_Clear();
|
||||
if (!Base::Wrapped_ParseTupleAndKeywords(args, kwds, "|i", kwds_def, &compression)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
//setup the stream. the in flag is needed to make "read" work
|
||||
std::stringstream stream(std::stringstream::out | std::stringstream::in | std::stringstream::binary);
|
||||
// setup the stream. the in flag is needed to make "read" work
|
||||
std::stringstream stream(std::stringstream::out | std::stringstream::in
|
||||
| std::stringstream::binary);
|
||||
try {
|
||||
getPersistencePtr()->dumpToStream(stream, compression);
|
||||
}
|
||||
catch(Base::NotImplementedError&) {
|
||||
PyErr_SetString(PyExc_NotImplementedError, "Dumping content of this object type is not implemented");
|
||||
catch (Base::NotImplementedError&) {
|
||||
PyErr_SetString(PyExc_NotImplementedError,
|
||||
"Dumping content of this object type is not implemented");
|
||||
return nullptr;
|
||||
}
|
||||
catch (...) {
|
||||
PyErr_SetString(PyExc_IOError, "Unable to parse content into binary representation");
|
||||
return nullptr;
|
||||
PyErr_SetString(PyExc_IOError, "Unable to parse content into binary representation");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
//build the byte array with correct size
|
||||
if(!stream.seekp(0, stream.end)) {
|
||||
// build the byte array with correct size
|
||||
if (!stream.seekp(0, stream.end)) {
|
||||
PyErr_SetString(PyExc_IOError, "Unable to find end of stream");
|
||||
return nullptr;
|
||||
}
|
||||
@@ -94,17 +96,17 @@ PyObject* PersistencePy::dumpContent(PyObject *args, PyObject *kwds)
|
||||
|
||||
PyObject* ba = PyByteArray_FromStringAndSize(nullptr, offset);
|
||||
|
||||
//use the buffer protocol to access the underlying array and write into it
|
||||
// use the buffer protocol to access the underlying array and write into it
|
||||
Py_buffer buf = Py_buffer();
|
||||
PyObject_GetBuffer(ba, &buf, PyBUF_WRITABLE);
|
||||
try {
|
||||
if(!stream.read((char*)buf.buf, offset)) {
|
||||
if (!stream.read((char*)buf.buf, offset)) {
|
||||
PyErr_SetString(PyExc_IOError, "Error copying data into byte array");
|
||||
return nullptr;
|
||||
}
|
||||
PyBuffer_Release(&buf);
|
||||
}
|
||||
catch(...) {
|
||||
catch (...) {
|
||||
PyBuffer_Release(&buf);
|
||||
PyErr_SetString(PyExc_IOError, "Error copying data into byte array");
|
||||
return nullptr;
|
||||
@@ -113,28 +115,30 @@ PyObject* PersistencePy::dumpContent(PyObject *args, PyObject *kwds)
|
||||
return ba;
|
||||
}
|
||||
|
||||
PyObject* PersistencePy::restoreContent(PyObject *args)
|
||||
PyObject* PersistencePy::restoreContent(PyObject* args)
|
||||
{
|
||||
PyObject* buffer = nullptr;
|
||||
if( !PyArg_ParseTuple(args, "O", &buffer) )
|
||||
if (!PyArg_ParseTuple(args, "O", &buffer)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
//check if it really is a buffer
|
||||
if( !PyObject_CheckBuffer(buffer) ) {
|
||||
// check if it really is a buffer
|
||||
if (!PyObject_CheckBuffer(buffer)) {
|
||||
PyErr_SetString(PyExc_TypeError, "Must be a buffer object");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Py_buffer buf;
|
||||
if(PyObject_GetBuffer(buffer, &buf, PyBUF_SIMPLE) < 0)
|
||||
if (PyObject_GetBuffer(buffer, &buf, PyBUF_SIMPLE) < 0) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if(!PyBuffer_IsContiguous(&buf, 'C')) {
|
||||
if (!PyBuffer_IsContiguous(&buf, 'C')) {
|
||||
PyErr_SetString(PyExc_TypeError, "Buffer must be contiguous");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
//check if it really is a buffer
|
||||
// check if it really is a buffer
|
||||
try {
|
||||
using Device = boost::iostreams::basic_array_source<char>;
|
||||
boost::iostreams::stream<Device> stream((char*)buf.buf, buf.len);
|
||||
@@ -148,13 +152,12 @@ PyObject* PersistencePy::restoreContent(PyObject *args)
|
||||
Py_Return;
|
||||
}
|
||||
|
||||
PyObject *PersistencePy::getCustomAttributes(const char*) const
|
||||
PyObject* PersistencePy::getCustomAttributes(const char*) const
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
int PersistencePy::setCustomAttributes(const char*,PyObject*)
|
||||
int PersistencePy::setCustomAttributes(const char*, PyObject*)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -36,13 +36,12 @@ Placement::Placement(const Base::Matrix4D& matrix)
|
||||
fromMatrix(matrix);
|
||||
}
|
||||
|
||||
Placement::Placement(const Vector3d& Pos, const Rotation &Rot)
|
||||
Placement::Placement(const Vector3d& Pos, const Rotation& Rot)
|
||||
: _pos(Pos)
|
||||
, _rot(Rot)
|
||||
{
|
||||
}
|
||||
{}
|
||||
|
||||
Placement::Placement(const Vector3d& Pos, const Rotation &Rot, const Vector3d& Cnt)
|
||||
Placement::Placement(const Vector3d& Pos, const Rotation& Rot, const Vector3d& Cnt)
|
||||
: _rot(Rot)
|
||||
{
|
||||
Vector3d RotC = Cnt;
|
||||
@@ -54,7 +53,7 @@ Placement Placement::fromDualQuaternion(DualQuat qq)
|
||||
{
|
||||
Rotation rot(qq.x.re, qq.y.re, qq.z.re, qq.w.re);
|
||||
DualQuat mvq = 2 * qq.dual() * qq.real().conj();
|
||||
return {Vector3d(mvq.x.re,mvq.y.re, mvq.z.re), rot};
|
||||
return {Vector3d(mvq.x.re, mvq.y.re, mvq.z.re), rot};
|
||||
}
|
||||
|
||||
Base::Matrix4D Placement::toMatrix() const
|
||||
@@ -80,13 +79,13 @@ DualQuat Placement::toDualQuaternion() const
|
||||
DualQuat posqq(_pos.x, _pos.y, _pos.z, 0.0);
|
||||
DualQuat rotqq;
|
||||
_rot.getValue(rotqq.x.re, rotqq.y.re, rotqq.z.re, rotqq.w.re);
|
||||
DualQuat ret (rotqq, 0.5 * posqq * rotqq);
|
||||
DualQuat ret(rotqq, 0.5 * posqq * rotqq);
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool Placement::isIdentity() const
|
||||
{
|
||||
Base::Vector3d nullvec(0,0,0);
|
||||
Base::Vector3d nullvec(0, 0, 0);
|
||||
bool none = (this->_pos == nullvec) && (this->_rot.isIdentity());
|
||||
return none;
|
||||
}
|
||||
@@ -98,14 +97,12 @@ bool Placement::isIdentity(double tol) const
|
||||
|
||||
bool Placement::isSame(const Placement& p) const
|
||||
{
|
||||
return this->_rot.isSame(p._rot) &&
|
||||
this->_pos.IsEqual(p._pos, 0);
|
||||
return this->_rot.isSame(p._rot) && this->_pos.IsEqual(p._pos, 0);
|
||||
}
|
||||
|
||||
bool Placement::isSame(const Placement& p, double tol) const
|
||||
{
|
||||
return this->_rot.isSame(p._rot, tol) &&
|
||||
this->_pos.IsEqual(p._pos, tol);
|
||||
return this->_rot.isSame(p._rot, tol) && this->_pos.IsEqual(p._pos, tol);
|
||||
}
|
||||
|
||||
void Placement::invert()
|
||||
@@ -127,12 +124,12 @@ void Placement::move(const Vector3d& MovVec)
|
||||
_pos += MovVec;
|
||||
}
|
||||
|
||||
bool Placement::operator == (const Placement& that) const
|
||||
bool Placement::operator==(const Placement& that) const
|
||||
{
|
||||
return (this->_pos == that._pos) && (this->_rot == that._rot);
|
||||
}
|
||||
|
||||
bool Placement::operator != (const Placement& that) const
|
||||
bool Placement::operator!=(const Placement& that) const
|
||||
{
|
||||
return !(*this == that);
|
||||
}
|
||||
@@ -143,12 +140,12 @@ bool Placement::operator != (const Placement& that) const
|
||||
|
||||
\sa multRight()
|
||||
*/
|
||||
Placement & Placement::operator*=(const Placement & p)
|
||||
Placement& Placement::operator*=(const Placement& p)
|
||||
{
|
||||
return multRight(p);
|
||||
}
|
||||
|
||||
Placement Placement::operator*(const Placement & p) const
|
||||
Placement Placement::operator*(const Placement& p) const
|
||||
{
|
||||
Placement plm(*this);
|
||||
plm *= p;
|
||||
@@ -188,22 +185,22 @@ Placement& Placement::multLeft(const Base::Placement& p)
|
||||
return *this;
|
||||
}
|
||||
|
||||
void Placement::multVec(const Vector3d & src, Vector3d & dst) const
|
||||
void Placement::multVec(const Vector3d& src, Vector3d& dst) const
|
||||
{
|
||||
this->_rot.multVec(src, dst);
|
||||
dst += this->_pos;
|
||||
}
|
||||
|
||||
void Placement::multVec(const Vector3f & src, Vector3f & dst) const
|
||||
void Placement::multVec(const Vector3f& src, Vector3f& dst) const
|
||||
{
|
||||
this->_rot.multVec(src, dst);
|
||||
dst += Base::toVector<float>(this->_pos);
|
||||
}
|
||||
|
||||
Placement Placement::slerp(const Placement & p0, const Placement & p1, double t)
|
||||
Placement Placement::slerp(const Placement& p0, const Placement& p1, double t)
|
||||
{
|
||||
Rotation rot = Rotation::slerp(p0.getRotation(), p1.getRotation(), t);
|
||||
Vector3d pos = p0.getPosition() * (1.0-t) + p1.getPosition() * t;
|
||||
Vector3d pos = p0.getPosition() * (1.0 - t) + p1.getPosition() * t;
|
||||
return {pos, rot};
|
||||
}
|
||||
|
||||
|
||||
@@ -27,7 +27,8 @@
|
||||
#include "Vector3D.h"
|
||||
|
||||
|
||||
namespace Base {
|
||||
namespace Base
|
||||
{
|
||||
|
||||
class DualQuat;
|
||||
class Matrix4D;
|
||||
@@ -43,8 +44,8 @@ public:
|
||||
Placement(const Placement&) = default;
|
||||
Placement(Placement&&) = default;
|
||||
Placement(const Base::Matrix4D& matrix);
|
||||
Placement(const Vector3d& Pos, const Rotation &Rot);
|
||||
Placement(const Vector3d& Pos, const Rotation &Rot, const Vector3d& Cnt);
|
||||
Placement(const Vector3d& Pos, const Rotation& Rot);
|
||||
Placement(const Vector3d& Pos, const Rotation& Rot, const Vector3d& Cnt);
|
||||
|
||||
/** specialty constructors */
|
||||
//@{
|
||||
@@ -52,15 +53,27 @@ public:
|
||||
//@}
|
||||
|
||||
/// Destruction
|
||||
~Placement () = default;
|
||||
~Placement() = default;
|
||||
|
||||
Matrix4D toMatrix() const;
|
||||
void fromMatrix(const Matrix4D& m);
|
||||
DualQuat toDualQuaternion() const;
|
||||
const Vector3d& getPosition() const {return _pos;}
|
||||
const Rotation& getRotation() const {return _rot;}
|
||||
void setPosition(const Vector3d& Pos){_pos=Pos;}
|
||||
void setRotation(const Rotation& Rot) {_rot = Rot;}
|
||||
const Vector3d& getPosition() const
|
||||
{
|
||||
return _pos;
|
||||
}
|
||||
const Rotation& getRotation() const
|
||||
{
|
||||
return _rot;
|
||||
}
|
||||
void setPosition(const Vector3d& Pos)
|
||||
{
|
||||
_pos = Pos;
|
||||
}
|
||||
void setRotation(const Rotation& Rot)
|
||||
{
|
||||
_rot = Rot;
|
||||
}
|
||||
|
||||
bool isIdentity() const;
|
||||
bool isIdentity(double tol) const;
|
||||
@@ -73,32 +86,31 @@ public:
|
||||
|
||||
/** Operators. */
|
||||
//@{
|
||||
Placement & operator*=(const Placement & p);
|
||||
Placement operator *(const Placement & p) const;
|
||||
bool operator == (const Placement&) const;
|
||||
bool operator != (const Placement&) const;
|
||||
Placement& operator = (const Placement&) = default;
|
||||
Placement& operator = (Placement&&) = default;
|
||||
Placement& operator*=(const Placement& p);
|
||||
Placement operator*(const Placement& p) const;
|
||||
bool operator==(const Placement&) const;
|
||||
bool operator!=(const Placement&) const;
|
||||
Placement& operator=(const Placement&) = default;
|
||||
Placement& operator=(Placement&&) = default;
|
||||
Placement pow(double t, bool shorten = true) const;
|
||||
|
||||
Placement& multRight(const Base::Placement& p);
|
||||
Placement& multLeft(const Base::Placement& p);
|
||||
|
||||
void multVec(const Vector3d & src, Vector3d & dst) const;
|
||||
void multVec(const Vector3f & src, Vector3f & dst) const;
|
||||
void multVec(const Vector3d& src, Vector3d& dst) const;
|
||||
void multVec(const Vector3f& src, Vector3f& dst) const;
|
||||
//@}
|
||||
|
||||
static Placement slerp(const Placement & p0, const Placement & p1, double t);
|
||||
static Placement sclerp(const Placement & p0, const Placement & p1, double t, bool shorten = true);
|
||||
static Placement slerp(const Placement& p0, const Placement& p1, double t);
|
||||
static Placement
|
||||
sclerp(const Placement& p0, const Placement& p1, double t, bool shorten = true);
|
||||
|
||||
private:
|
||||
Vector3<double> _pos;
|
||||
Base::Rotation _rot;
|
||||
Base::Rotation _rot;
|
||||
};
|
||||
|
||||
} // namespace Base
|
||||
|
||||
|
||||
#endif // BASE_PLACEMENT_H
|
||||
} // namespace Base
|
||||
|
||||
|
||||
#endif // BASE_PLACEMENT_H
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<GenerateModel xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="generateMetaModel_Module.xsd">
|
||||
<PythonExport
|
||||
Father="PyObjectBase"
|
||||
Name="PlacementPy"
|
||||
Twin="Placement"
|
||||
TwinPointer="Placement"
|
||||
Include="Base/Placement.h"
|
||||
FatherInclude="Base/PyObjectBase.h"
|
||||
Namespace="Base"
|
||||
<PythonExport
|
||||
Father="PyObjectBase"
|
||||
Name="PlacementPy"
|
||||
Twin="Placement"
|
||||
TwinPointer="Placement"
|
||||
Include="Base/Placement.h"
|
||||
FatherInclude="Base/PyObjectBase.h"
|
||||
Namespace="Base"
|
||||
Constructor="true"
|
||||
Delete="true"
|
||||
NumberProtocol="true"
|
||||
@@ -15,34 +15,34 @@
|
||||
FatherNamespace="Base">
|
||||
<Documentation>
|
||||
<Author Licence="LGPL" Name="Juergen Riegel" EMail="FreeCAD@juergen-riegel.net" />
|
||||
<UserDocu>Base.Placement class.
|
||||
<UserDocu>Base.Placement class.
|
||||
|
||||
A Placement defines an orientation (rotation) and a position (base) in 3D space.
|
||||
It is used when no scaling or other distortion is needed.
|
||||
It is used when no scaling or other distortion is needed.
|
||||
|
||||
The following constructors are supported:
|
||||
The following constructors are supported:
|
||||
|
||||
Placement()
|
||||
Empty constructor.
|
||||
Empty constructor.
|
||||
|
||||
Placement(placement)
|
||||
Copy constructor.
|
||||
placement : Base.Placement
|
||||
placement : Base.Placement
|
||||
|
||||
Placement(matrix)
|
||||
Define from a 4D matrix consisting of rotation and translation.
|
||||
matrix : Base.Matrix
|
||||
matrix : Base.Matrix
|
||||
|
||||
Placement(base, rotation)
|
||||
Define from position and rotation.
|
||||
base : Base.Vector
|
||||
rotation : Base.Rotation
|
||||
rotation : Base.Rotation
|
||||
|
||||
Placement(base, rotation, center)
|
||||
Define from position and rotation with center.
|
||||
base : Base.Vector
|
||||
rotation : Base.Rotation
|
||||
center : Base.Vector
|
||||
center : Base.Vector
|
||||
|
||||
Placement(base, axis, angle)
|
||||
define position and rotation.
|
||||
@@ -53,46 +53,46 @@ angle : float</UserDocu>
|
||||
</Documentation>
|
||||
<Methode Name="copy" Const="true">
|
||||
<Documentation>
|
||||
<UserDocu>copy() -> Base.Placement
|
||||
<UserDocu>copy() -> Base.Placement
|
||||
|
||||
Returns a copy of this placement.</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Methode Name="move">
|
||||
<Documentation>
|
||||
<UserDocu>move(vector) -> None
|
||||
<UserDocu>move(vector) -> None
|
||||
|
||||
Move the placement along a vector.
|
||||
Move the placement along a vector.
|
||||
|
||||
vector : Base.Vector
|
||||
vector : Base.Vector
|
||||
Vector by which to move the placement.</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Methode Name="translate">
|
||||
<Documentation>
|
||||
<UserDocu>translate(vector) -> None
|
||||
<UserDocu>translate(vector) -> None
|
||||
|
||||
Alias to move(), to be compatible with TopoShape.translate().
|
||||
Alias to move(), to be compatible with TopoShape.translate().
|
||||
|
||||
vector : Base.Vector
|
||||
vector : Base.Vector
|
||||
Vector by which to move the placement.</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Methode Name="rotate" Keyword="true">
|
||||
<Documentation>
|
||||
<UserDocu>rotate(center, axis, angle, comp) -> None
|
||||
<UserDocu>rotate(center, axis, angle, comp) -> None
|
||||
|
||||
Rotate the current placement around center and axis with the given angle.
|
||||
This method is compatible with TopoShape.rotate() if the (optional) keyword
|
||||
argument comp is True (default=False).
|
||||
|
||||
center : Base.Vector, sequence of float
|
||||
center : Base.Vector, sequence of float
|
||||
Rotation center.
|
||||
axis : Base.Vector, sequence of float
|
||||
axis : Base.Vector, sequence of float
|
||||
Rotation axis.
|
||||
angle : float
|
||||
angle : float
|
||||
Rotation angle in degrees.
|
||||
comp : bool
|
||||
comp : bool
|
||||
optional keyword only argument, if True (default=False),
|
||||
behave like TopoShape.rotate() (i.e. the resulting placements are interchangeable).
|
||||
</UserDocu>
|
||||
@@ -100,101 +100,101 @@ behave like TopoShape.rotate() (i.e. the resulting placements are interchangeabl
|
||||
</Methode>
|
||||
<Methode Name="multiply" Const="true">
|
||||
<Documentation>
|
||||
<UserDocu>multiply(placement) -> Base.Placement
|
||||
<UserDocu>multiply(placement) -> Base.Placement
|
||||
|
||||
Right multiply this placement with another placement.
|
||||
Also available as `*` operator.
|
||||
Also available as `*` operator.
|
||||
|
||||
placement : Base.Placement
|
||||
placement : Base.Placement
|
||||
Placement by which to multiply this placement.</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Methode Name="multVec" Const="true">
|
||||
<Documentation>
|
||||
<UserDocu>multVec(vector) -> Base.Vector
|
||||
<UserDocu>multVec(vector) -> Base.Vector
|
||||
|
||||
Compute the transformed vector using the placement.
|
||||
Compute the transformed vector using the placement.
|
||||
|
||||
vector : Base.Vector
|
||||
vector : Base.Vector
|
||||
Vector to be transformed.</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Methode Name="toMatrix" Const="true">
|
||||
<Documentation>
|
||||
<UserDocu>toMatrix() -> Base.Matrix
|
||||
<UserDocu>toMatrix() -> Base.Matrix
|
||||
|
||||
Compute the matrix representation of the placement.</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Methode Name="inverse" Const="true">
|
||||
<Documentation>
|
||||
<UserDocu>inverse() -> Base.Placement
|
||||
<UserDocu>inverse() -> Base.Placement
|
||||
|
||||
Compute the inverse placement.</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Methode Name="pow" Const="true">
|
||||
<Documentation>
|
||||
<UserDocu>pow(t, shorten=True) -> Base.Placement
|
||||
<UserDocu>pow(t, shorten=True) -> Base.Placement
|
||||
|
||||
Raise this placement to real power using ScLERP interpolation.
|
||||
Also available as `**` operator.
|
||||
Also available as `**` operator.
|
||||
|
||||
t : float
|
||||
t : float
|
||||
Real power.
|
||||
shorten : bool
|
||||
shorten : bool
|
||||
If True, ensures rotation quaternion is net positive to make
|
||||
the path shorter.</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Methode Name="sclerp" Const="true">
|
||||
<Documentation>
|
||||
<UserDocu>sclerp(placement2, t, shorten=True) -> Base.Placement
|
||||
<UserDocu>sclerp(placement2, t, shorten=True) -> Base.Placement
|
||||
|
||||
Screw Linear Interpolation (ScLERP) between this placement and `placement2`.
|
||||
Interpolation is a continuous motion along a helical path parametrized by `t`
|
||||
made of equal transforms if discretized.
|
||||
If quaternions of rotations of the two placements differ in sign, the interpolation
|
||||
will take a long path.
|
||||
will take a long path.
|
||||
|
||||
placement2 : Base.Placement
|
||||
t : float
|
||||
t : float
|
||||
Parameter of helical path. t=0 returns this placement, t=1 returns
|
||||
`placement2`. t can also be outside of [0, 1] range for extrapolation.
|
||||
shorten : bool
|
||||
shorten : bool
|
||||
If True, the signs are harmonized before interpolation and the interpolation
|
||||
takes the shorter path.</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Methode Name="slerp" Const="true">
|
||||
<Documentation>
|
||||
<UserDocu>slerp(placement2, t) -> Base.Placement
|
||||
<UserDocu>slerp(placement2, t) -> Base.Placement
|
||||
|
||||
Spherical Linear Interpolation (SLERP) between this placement and `placement2`.
|
||||
This function performs independent interpolation of rotation and movement.
|
||||
Result of such interpolation might be not what application expects, thus this tool
|
||||
might be considered for simple cases or for interpolating between small intervals.
|
||||
For more complex cases you better use the advanced sclerp() function.
|
||||
For more complex cases you better use the advanced sclerp() function.
|
||||
|
||||
placement2 : Base.Placement
|
||||
t : float
|
||||
t : float
|
||||
Parameter of the path. t=0 returns this placement, t=1 returns `placement2`.</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Methode Name="isIdentity" Const="true">
|
||||
<Documentation>
|
||||
<UserDocu>isIdentity([tol=0.0]) -> bool
|
||||
<UserDocu>isIdentity([tol=0.0]) -> bool
|
||||
|
||||
Returns True if the placement has no displacement and no rotation.
|
||||
Matrix representation is the 4D identity matrix.
|
||||
tol : float
|
||||
tol : float
|
||||
Tolerance used to check for identity.
|
||||
If tol is negative or zero, no tolerance is used.</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Methode Name="isSame" Const="true">
|
||||
<Documentation>
|
||||
<UserDocu>isSame(Base.Placement, [tol=0.0]) -> bool
|
||||
<UserDocu>isSame(Base.Placement, [tol=0.0]) -> bool
|
||||
|
||||
Checks whether this and the given placement are the same.
|
||||
The default tolerance is set to 0.0</UserDocu>
|
||||
|
||||
@@ -40,28 +40,29 @@ using namespace Base;
|
||||
// returns a string which represents the object e.g. when printed in python
|
||||
std::string PlacementPy::representation() const
|
||||
{
|
||||
double yaw{}, pitch{}, roll{};
|
||||
double yaw {}, pitch {}, roll {};
|
||||
PlacementPy::PointerType ptr = getPlacementPtr();
|
||||
std::stringstream str;
|
||||
ptr->getRotation().getYawPitchRoll(yaw, pitch, roll);
|
||||
|
||||
str << "Placement [Pos=(";
|
||||
str << ptr->getPosition().x << ","<< ptr->getPosition().y << "," << ptr->getPosition().z;
|
||||
str << ptr->getPosition().x << "," << ptr->getPosition().y << "," << ptr->getPosition().z;
|
||||
str << "), Yaw-Pitch-Roll=(" << yaw << "," << pitch << "," << roll << ")]";
|
||||
|
||||
return str.str();
|
||||
}
|
||||
|
||||
PyObject *PlacementPy::PyMake(struct _typeobject *, PyObject *, PyObject *) // Python wrapper
|
||||
PyObject* PlacementPy::PyMake(struct _typeobject*, PyObject*, PyObject*) // Python wrapper
|
||||
{
|
||||
// create a new instance of PlacementPy and the Twin object
|
||||
return new PlacementPy(new Placement);
|
||||
}
|
||||
|
||||
// clang-format off
|
||||
// constructor method
|
||||
int PlacementPy::PyInit(PyObject* args, PyObject* /*kwd*/)
|
||||
{
|
||||
PyObject* o{};
|
||||
PyObject* o {};
|
||||
if (PyArg_ParseTuple(args, "")) {
|
||||
return 0;
|
||||
}
|
||||
@@ -81,61 +82,68 @@ int PlacementPy::PyInit(PyObject* args, PyObject* /*kwd*/)
|
||||
|
||||
PyErr_Clear();
|
||||
if (PyArg_ParseTuple(args, "O!", &(Base::PlacementPy::Type), &o)) {
|
||||
Base::Placement *plm = static_cast<Base::PlacementPy*>(o)->getPlacementPtr();
|
||||
Base::Placement* plm = static_cast<Base::PlacementPy*>(o)->getPlacementPtr();
|
||||
*(getPlacementPtr()) = *plm;
|
||||
return 0;
|
||||
}
|
||||
|
||||
PyErr_Clear();
|
||||
PyObject* d{};
|
||||
double angle{};
|
||||
if (PyArg_ParseTuple(args, "O!O!d", &(Base::VectorPy::Type), &o,
|
||||
&(Base::VectorPy::Type), &d, &angle)) {
|
||||
PyObject* d {};
|
||||
double angle {};
|
||||
if (PyArg_ParseTuple(args,
|
||||
"O!O!d",
|
||||
&(Base::VectorPy::Type), &o,
|
||||
&(Base::VectorPy::Type), &d,
|
||||
&angle)) {
|
||||
// NOTE: The first parameter defines the translation, the second the rotation axis
|
||||
// and the last parameter defines the rotation angle in degree.
|
||||
Base::Rotation rot(static_cast<Base::VectorPy*>(d)->value(), angle/180.0*D_PI);
|
||||
*getPlacementPtr() = Base::Placement(static_cast<Base::VectorPy*>(o)->value(),rot);
|
||||
Base::Rotation rot(static_cast<Base::VectorPy*>(d)->value(), angle / 180.0 * D_PI);
|
||||
*getPlacementPtr() = Base::Placement(static_cast<Base::VectorPy*>(o)->value(), rot);
|
||||
return 0;
|
||||
}
|
||||
|
||||
PyErr_Clear();
|
||||
if (PyArg_ParseTuple(args, "O!O!", &(Base::VectorPy::Type), &o,
|
||||
&(Base::RotationPy::Type), &d)) {
|
||||
Base::Vector3d *pos = static_cast<Base::VectorPy*>(o)->getVectorPtr();
|
||||
if (PyArg_ParseTuple(args,
|
||||
"O!O!",
|
||||
&(Base::VectorPy::Type), &o,
|
||||
&(Base::RotationPy::Type), &d)) {
|
||||
Base::Vector3d* pos = static_cast<Base::VectorPy*>(o)->getVectorPtr();
|
||||
getPlacementPtr()->setPosition(*pos);
|
||||
Base::Rotation *rot = static_cast<Base::RotationPy*>(d)->getRotationPtr();
|
||||
Base::Rotation* rot = static_cast<Base::RotationPy*>(d)->getRotationPtr();
|
||||
getPlacementPtr()->setRotation(*rot);
|
||||
return 0;
|
||||
}
|
||||
|
||||
PyErr_Clear();
|
||||
PyObject* c{};
|
||||
if (PyArg_ParseTuple(args, "O!O!O!", &(Base::VectorPy::Type), &o,
|
||||
&(Base::RotationPy::Type), &d,
|
||||
&(Base::VectorPy::Type), &c)) {
|
||||
Base::Vector3d *pos = static_cast<Base::VectorPy*>(o)->getVectorPtr();
|
||||
Base::Rotation *rot = static_cast<Base::RotationPy*>(d)->getRotationPtr();
|
||||
Base::Vector3d *cnt = static_cast<Base::VectorPy*>(c)->getVectorPtr();
|
||||
Base::Placement p(*pos,*rot,*cnt);
|
||||
getPlacementPtr()->operator = (p);
|
||||
PyObject* c {};
|
||||
if (PyArg_ParseTuple(args,
|
||||
"O!O!O!",
|
||||
&(Base::VectorPy::Type), &o,
|
||||
&(Base::RotationPy::Type), &d,
|
||||
&(Base::VectorPy::Type), &c)) {
|
||||
Base::Vector3d* pos = static_cast<Base::VectorPy*>(o)->getVectorPtr();
|
||||
Base::Rotation* rot = static_cast<Base::RotationPy*>(d)->getRotationPtr();
|
||||
Base::Vector3d* cnt = static_cast<Base::VectorPy*>(c)->getVectorPtr();
|
||||
Base::Placement p(*pos, *rot, *cnt);
|
||||
getPlacementPtr()->operator=(p);
|
||||
return 0;
|
||||
}
|
||||
|
||||
PyErr_SetString(PyExc_TypeError, "empty parameter list, matrix or placement expected");
|
||||
return -1;
|
||||
}
|
||||
// clang-format on
|
||||
|
||||
PyObject* PlacementPy::richCompare(PyObject *v, PyObject *w, int op)
|
||||
PyObject* PlacementPy::richCompare(PyObject* v, PyObject* w, int op)
|
||||
{
|
||||
if (PyObject_TypeCheck(v, &(PlacementPy::Type)) &&
|
||||
PyObject_TypeCheck(w, &(PlacementPy::Type))) {
|
||||
if (PyObject_TypeCheck(v, &(PlacementPy::Type))
|
||||
&& PyObject_TypeCheck(w, &(PlacementPy::Type))) {
|
||||
Base::Placement p1 = *static_cast<PlacementPy*>(v)->getPlacementPtr();
|
||||
Base::Placement p2 = *static_cast<PlacementPy*>(w)->getPlacementPtr();
|
||||
|
||||
PyObject *res=nullptr;
|
||||
PyObject* res = nullptr;
|
||||
if (op != Py_EQ && op != Py_NE) {
|
||||
PyErr_SetString(PyExc_TypeError,
|
||||
"no ordering relation is defined for Placement");
|
||||
PyErr_SetString(PyExc_TypeError, "no ordering relation is defined for Placement");
|
||||
return nullptr;
|
||||
}
|
||||
else if (op == Py_EQ) {
|
||||
@@ -156,46 +164,56 @@ PyObject* PlacementPy::richCompare(PyObject *v, PyObject *w, int op)
|
||||
}
|
||||
}
|
||||
|
||||
PyObject* PlacementPy::move(PyObject * args)
|
||||
PyObject* PlacementPy::move(PyObject* args)
|
||||
{
|
||||
PyObject *vec{};
|
||||
if (!PyArg_ParseTuple(args, "O!", &(VectorPy::Type), &vec))
|
||||
PyObject* vec {};
|
||||
if (!PyArg_ParseTuple(args, "O!", &(VectorPy::Type), &vec)) {
|
||||
return nullptr;
|
||||
}
|
||||
getPlacementPtr()->move(static_cast<VectorPy*>(vec)->value());
|
||||
Py_Return;
|
||||
}
|
||||
|
||||
PyObject* PlacementPy::translate(PyObject * args)
|
||||
PyObject* PlacementPy::translate(PyObject* args)
|
||||
{
|
||||
return move(args);
|
||||
}
|
||||
|
||||
PyObject* PlacementPy::rotate(PyObject *args, PyObject *kwds)
|
||||
// clang-format off
|
||||
PyObject* PlacementPy::rotate(PyObject* args, PyObject* kwds)
|
||||
{
|
||||
double angle{};
|
||||
static const std::array<const char *, 6> kwlist { "center", "axis", "angle", "comp", nullptr };
|
||||
double angle {};
|
||||
static const std::array<const char*, 6> kwlist {"center", "axis", "angle", "comp", nullptr};
|
||||
Vector3d center;
|
||||
Vector3d axis;
|
||||
PyObject* pyComp = Py_False; // NOLINT
|
||||
PyObject* pyComp = Py_False; // NOLINT
|
||||
|
||||
if (!Base::Wrapped_ParseTupleAndKeywords(args, kwds, "(ddd)(ddd)d|O!", kwlist, ¢er.x, ¢er.y, ¢er.z,
|
||||
&axis.x, &axis.y, &axis.z, &angle, &PyBool_Type, &pyComp)) {
|
||||
if (!Base::Wrapped_ParseTupleAndKeywords(args,
|
||||
kwds,
|
||||
"(ddd)(ddd)d|O!",
|
||||
kwlist,
|
||||
¢er.x, ¢er.y, ¢er.z,
|
||||
&axis.x, &axis.y, &axis.z,
|
||||
&angle, &PyBool_Type, &pyComp)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
try {
|
||||
/*
|
||||
* if comp is False, we retain the original behaviour that - contrary to the (old) documentation - generates
|
||||
* Placements different from TopoShape.rotate() to ensure compatibility for existing code
|
||||
* if comp is False, we retain the original behaviour that - contrary to the (old)
|
||||
* documentation - generates Placements different from TopoShape.rotate() to ensure
|
||||
* compatibility for existing code
|
||||
*/
|
||||
bool comp = Base::asBoolean(pyComp);
|
||||
|
||||
if (!comp) {
|
||||
getPlacementPtr()->multRight(Placement(Vector3d(), Rotation(axis, toRadians<double>(angle)), center));
|
||||
getPlacementPtr()->multRight(
|
||||
Placement(Vector3d(), Rotation(axis, toRadians<double>(angle)), center));
|
||||
}
|
||||
else {
|
||||
// multiply new Placement the same way TopoShape.rotate() does
|
||||
getPlacementPtr()->multLeft(Placement(Vector3d(), Rotation(axis, toRadians<double>(angle)), center));
|
||||
getPlacementPtr()->multLeft(
|
||||
Placement(Vector3d(), Rotation(axis, toRadians<double>(angle)), center));
|
||||
}
|
||||
|
||||
Py_Return;
|
||||
@@ -204,55 +222,62 @@ PyObject* PlacementPy::rotate(PyObject *args, PyObject *kwds)
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
// clang-format on
|
||||
|
||||
PyObject* PlacementPy::multiply(PyObject * args)
|
||||
PyObject* PlacementPy::multiply(PyObject* args)
|
||||
{
|
||||
PyObject *plm{};
|
||||
if (!PyArg_ParseTuple(args, "O!", &(PlacementPy::Type), &plm))
|
||||
PyObject* plm {};
|
||||
if (!PyArg_ParseTuple(args, "O!", &(PlacementPy::Type), &plm)) {
|
||||
return nullptr;
|
||||
}
|
||||
Placement mult = (*getPlacementPtr()) * (*static_cast<PlacementPy*>(plm)->getPlacementPtr());
|
||||
return new PlacementPy(new Placement(mult));
|
||||
}
|
||||
|
||||
PyObject* PlacementPy::multVec(PyObject * args)
|
||||
PyObject* PlacementPy::multVec(PyObject* args)
|
||||
{
|
||||
PyObject *vec{};
|
||||
if (!PyArg_ParseTuple(args, "O!", &(VectorPy::Type), &vec))
|
||||
PyObject* vec {};
|
||||
if (!PyArg_ParseTuple(args, "O!", &(VectorPy::Type), &vec)) {
|
||||
return nullptr;
|
||||
}
|
||||
Base::Vector3d pnt(static_cast<VectorPy*>(vec)->value());
|
||||
getPlacementPtr()->multVec(pnt, pnt);
|
||||
return new VectorPy(new Vector3d(pnt));
|
||||
}
|
||||
|
||||
PyObject* PlacementPy::copy(PyObject * args)
|
||||
PyObject* PlacementPy::copy(PyObject* args)
|
||||
{
|
||||
if (!PyArg_ParseTuple(args, ""))
|
||||
if (!PyArg_ParseTuple(args, "")) {
|
||||
return nullptr;
|
||||
}
|
||||
return new PlacementPy(new Placement(*getPlacementPtr()));
|
||||
}
|
||||
|
||||
PyObject* PlacementPy::toMatrix(PyObject * args)
|
||||
PyObject* PlacementPy::toMatrix(PyObject* args)
|
||||
{
|
||||
if (!PyArg_ParseTuple(args, ""))
|
||||
if (!PyArg_ParseTuple(args, "")) {
|
||||
return nullptr;
|
||||
}
|
||||
Base::Matrix4D mat = getPlacementPtr()->toMatrix();
|
||||
return new MatrixPy(new Matrix4D(mat));
|
||||
}
|
||||
|
||||
PyObject* PlacementPy::inverse(PyObject * args)
|
||||
PyObject* PlacementPy::inverse(PyObject* args)
|
||||
{
|
||||
if (!PyArg_ParseTuple(args, ""))
|
||||
if (!PyArg_ParseTuple(args, "")) {
|
||||
return nullptr;
|
||||
}
|
||||
Base::Placement p = getPlacementPtr()->inverse();
|
||||
return new PlacementPy(new Placement(p));
|
||||
}
|
||||
|
||||
PyObject* PlacementPy::pow(PyObject* args)
|
||||
{
|
||||
double t{};
|
||||
double t {};
|
||||
PyObject* shorten = Py_True;
|
||||
if (!PyArg_ParseTuple(args, "d|O!", &t, &(PyBool_Type), &shorten))
|
||||
if (!PyArg_ParseTuple(args, "d|O!", &t, &(PyBool_Type), &shorten)) {
|
||||
return nullptr;
|
||||
}
|
||||
Base::Placement ret = getPlacementPtr()->pow(t, Base::asBoolean(shorten));
|
||||
return new PlacementPy(new Placement(ret));
|
||||
}
|
||||
@@ -260,53 +285,63 @@ PyObject* PlacementPy::pow(PyObject* args)
|
||||
|
||||
PyObject* PlacementPy::sclerp(PyObject* args)
|
||||
{
|
||||
PyObject* pyplm2{};
|
||||
double t{};
|
||||
PyObject* pyplm2 {};
|
||||
double t {};
|
||||
PyObject* shorten = Py_True;
|
||||
if (!PyArg_ParseTuple(args, "O!d|O!", &(PlacementPy::Type), &pyplm2, &t, &(PyBool_Type), &shorten))
|
||||
if (!PyArg_ParseTuple(args,
|
||||
"O!d|O!",
|
||||
&(PlacementPy::Type),
|
||||
&pyplm2,
|
||||
&t,
|
||||
&(PyBool_Type),
|
||||
&shorten)) {
|
||||
return nullptr;
|
||||
}
|
||||
Base::Placement plm2 = static_cast<Base::PlacementPy*>(pyplm2)->value();
|
||||
Base::Placement ret = Base::Placement::sclerp(*getPlacementPtr(), plm2, t, Base::asBoolean(shorten));
|
||||
Base::Placement ret =
|
||||
Base::Placement::sclerp(*getPlacementPtr(), plm2, t, Base::asBoolean(shorten));
|
||||
return new PlacementPy(new Placement(ret));
|
||||
}
|
||||
|
||||
PyObject* PlacementPy::slerp(PyObject* args)
|
||||
{
|
||||
PyObject* pyplm2{};
|
||||
double t{};
|
||||
if (!PyArg_ParseTuple(args, "O!d", &(PlacementPy::Type), &pyplm2, &t))
|
||||
PyObject* pyplm2 {};
|
||||
double t {};
|
||||
if (!PyArg_ParseTuple(args, "O!d", &(PlacementPy::Type), &pyplm2, &t)) {
|
||||
return nullptr;
|
||||
}
|
||||
Base::Placement plm2 = static_cast<Base::PlacementPy*>(pyplm2)->value();
|
||||
Base::Placement ret = Base::Placement::slerp(*getPlacementPtr(), plm2, t);
|
||||
return new PlacementPy(new Placement(ret));
|
||||
}
|
||||
|
||||
PyObject* PlacementPy::isIdentity(PyObject *args)
|
||||
PyObject* PlacementPy::isIdentity(PyObject* args)
|
||||
{
|
||||
double tol = 0.0;
|
||||
if (!PyArg_ParseTuple(args, "|d", &tol))
|
||||
if (!PyArg_ParseTuple(args, "|d", &tol)) {
|
||||
return nullptr;
|
||||
bool none = tol > 0 ? getPlacementPtr()->isIdentity(tol)
|
||||
: getPlacementPtr()->isIdentity();
|
||||
}
|
||||
bool none = tol > 0 ? getPlacementPtr()->isIdentity(tol) : getPlacementPtr()->isIdentity();
|
||||
return Py_BuildValue("O", (none ? Py_True : Py_False));
|
||||
}
|
||||
|
||||
PyObject* PlacementPy::isSame(PyObject *args)
|
||||
PyObject* PlacementPy::isSame(PyObject* args)
|
||||
{
|
||||
PyObject* plm{};
|
||||
PyObject* plm {};
|
||||
double tol = 0.0;
|
||||
if (!PyArg_ParseTuple(args, "O!|d", &PlacementPy::Type, &plm, &tol))
|
||||
if (!PyArg_ParseTuple(args, "O!|d", &PlacementPy::Type, &plm, &tol)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Base::Placement plm1 = * getPlacementPtr();
|
||||
Base::Placement plm2 = * static_cast<PlacementPy*>(plm)->getPlacementPtr();
|
||||
Base::Placement plm1 = *getPlacementPtr();
|
||||
Base::Placement plm2 = *static_cast<PlacementPy*>(plm)->getPlacementPtr();
|
||||
bool same = tol > 0.0 ? plm1.isSame(plm2, tol) : plm1.isSame(plm2);
|
||||
return Py_BuildValue("O", (same ? Py_True : Py_False));
|
||||
}
|
||||
|
||||
Py::Object PlacementPy::getBase() const
|
||||
{
|
||||
return Py::Vector(getPlacementPtr()->getPosition()); // NOLINT
|
||||
return Py::Vector(getPlacementPtr()->getPosition()); // NOLINT
|
||||
}
|
||||
|
||||
void PlacementPy::setBase(Py::Object arg)
|
||||
@@ -332,8 +367,7 @@ void PlacementPy::setRotation(Py::Object arg)
|
||||
getPlacementPtr()->setRotation(Base::Rotation(static_cast<double>(Py::Float(tuple[0])),
|
||||
static_cast<double>(Py::Float(tuple[1])),
|
||||
static_cast<double>(Py::Float(tuple[2])),
|
||||
static_cast<double>(Py::Float(tuple[3]))
|
||||
));
|
||||
static_cast<double>(Py::Float(tuple[3]))));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -348,8 +382,9 @@ Py::Object PlacementPy::getMatrix() const
|
||||
void PlacementPy::setMatrix(Py::Object arg)
|
||||
{
|
||||
Py::Matrix mat;
|
||||
if (!mat.accepts(arg.ptr()))
|
||||
if (!mat.accepts(arg.ptr())) {
|
||||
throw Py::TypeError("Expect type Matrix");
|
||||
}
|
||||
try {
|
||||
mat = arg;
|
||||
getPlacementPtr()->fromMatrix(mat);
|
||||
@@ -359,14 +394,14 @@ void PlacementPy::setMatrix(Py::Object arg)
|
||||
}
|
||||
}
|
||||
|
||||
PyObject *PlacementPy::getCustomAttributes(const char* attr) const
|
||||
PyObject* PlacementPy::getCustomAttributes(const char* attr) const
|
||||
{
|
||||
// for backward compatibility
|
||||
if (strcmp(attr, "isNull") == 0) {
|
||||
PyObject *w{}, *res{};
|
||||
PyObject *w {}, *res {};
|
||||
w = PyUnicode_InternFromString("isIdentity");
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-const-cast)
|
||||
res = PyObject_GenericGetAttr(const_cast<PlacementPy *>(this), w);
|
||||
res = PyObject_GenericGetAttr(const_cast<PlacementPy*>(this), w);
|
||||
Py_XDECREF(w);
|
||||
return res;
|
||||
}
|
||||
@@ -378,30 +413,30 @@ int PlacementPy::setCustomAttributes(const char* /*attr*/, PyObject* /*obj*/)
|
||||
return 0;
|
||||
}
|
||||
|
||||
PyObject* PlacementPy::number_multiply_handler(PyObject *self, PyObject *other)
|
||||
PyObject* PlacementPy::number_multiply_handler(PyObject* self, PyObject* other)
|
||||
{
|
||||
if (PyObject_TypeCheck(self, &(PlacementPy::Type))) {
|
||||
Base::Placement a = static_cast<PlacementPy*>(self)->value();
|
||||
|
||||
if (PyObject_TypeCheck(other, &(VectorPy::Type))) {
|
||||
Vector3d res;
|
||||
a.multVec(static_cast<VectorPy*>(other)->value(),res);
|
||||
a.multVec(static_cast<VectorPy*>(other)->value(), res);
|
||||
return new VectorPy(res);
|
||||
}
|
||||
|
||||
if (PyObject_TypeCheck(other, &(RotationPy::Type))) {
|
||||
Placement b(Vector3d(),static_cast<RotationPy*>(other)->value());
|
||||
return new PlacementPy(a*b);
|
||||
Placement b(Vector3d(), static_cast<RotationPy*>(other)->value());
|
||||
return new PlacementPy(a * b);
|
||||
}
|
||||
|
||||
if (PyObject_TypeCheck(other, &(PlacementPy::Type))) {
|
||||
const auto &b = static_cast<PlacementPy*>(other)->value();
|
||||
return new PlacementPy(a*b);
|
||||
const auto& b = static_cast<PlacementPy*>(other)->value();
|
||||
return new PlacementPy(a * b);
|
||||
}
|
||||
|
||||
if (PyObject_TypeCheck(other, &(MatrixPy::Type))) {
|
||||
const auto &b = static_cast<MatrixPy*>(other)->value();
|
||||
return new MatrixPy(a.toMatrix()*b);
|
||||
const auto& b = static_cast<MatrixPy*>(other)->value();
|
||||
return new MatrixPy(a.toMatrix() * b);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -409,19 +444,17 @@ PyObject* PlacementPy::number_multiply_handler(PyObject *self, PyObject *other)
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
PyObject * PlacementPy::number_power_handler (PyObject* self, PyObject* other, PyObject* arg)
|
||||
PyObject* PlacementPy::number_power_handler(PyObject* self, PyObject* other, PyObject* arg)
|
||||
{
|
||||
Py::Object pw(other);
|
||||
Py::Tuple tup(1);
|
||||
tup[0] = pw;
|
||||
|
||||
double pw_v{};
|
||||
if (!PyArg_ParseTuple(tup.ptr(), "d", &pw_v)){
|
||||
double pw_v {};
|
||||
if (!PyArg_ParseTuple(tup.ptr(), "d", &pw_v)) {
|
||||
return nullptr;
|
||||
}
|
||||
if (!PyObject_TypeCheck(self, &(PlacementPy::Type))
|
||||
|| arg != Py_None)
|
||||
{
|
||||
if (!PyObject_TypeCheck(self, &(PlacementPy::Type)) || arg != Py_None) {
|
||||
PyErr_SetString(PyExc_NotImplementedError, "Not implemented");
|
||||
return nullptr;
|
||||
}
|
||||
@@ -430,104 +463,103 @@ PyObject * PlacementPy::number_power_handler (PyObject* self, PyObject* other, P
|
||||
return new PlacementPy(a.pow(pw_v));
|
||||
}
|
||||
|
||||
PyObject* PlacementPy::number_add_handler(PyObject * /*self*/, PyObject * /*other*/)
|
||||
PyObject* PlacementPy::number_add_handler(PyObject* /*self*/, PyObject* /*other*/)
|
||||
{
|
||||
PyErr_SetString(PyExc_NotImplementedError, "Not implemented");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
PyObject* PlacementPy::number_subtract_handler(PyObject * /*self*/, PyObject * /*other*/)
|
||||
PyObject* PlacementPy::number_subtract_handler(PyObject* /*self*/, PyObject* /*other*/)
|
||||
{
|
||||
PyErr_SetString(PyExc_NotImplementedError, "Not implemented");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
PyObject * PlacementPy::number_divide_handler (PyObject* /*self*/, PyObject* /*other*/)
|
||||
PyObject* PlacementPy::number_divide_handler(PyObject* /*self*/, PyObject* /*other*/)
|
||||
{
|
||||
PyErr_SetString(PyExc_NotImplementedError, "Not implemented");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
PyObject * PlacementPy::number_remainder_handler (PyObject* /*self*/, PyObject* /*other*/)
|
||||
PyObject* PlacementPy::number_remainder_handler(PyObject* /*self*/, PyObject* /*other*/)
|
||||
{
|
||||
PyErr_SetString(PyExc_NotImplementedError, "Not implemented");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
PyObject * PlacementPy::number_divmod_handler (PyObject* /*self*/, PyObject* /*other*/)
|
||||
PyObject* PlacementPy::number_divmod_handler(PyObject* /*self*/, PyObject* /*other*/)
|
||||
{
|
||||
PyErr_SetString(PyExc_NotImplementedError, "Not implemented");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
PyObject * PlacementPy::number_negative_handler (PyObject* /*self*/)
|
||||
PyObject* PlacementPy::number_negative_handler(PyObject* /*self*/)
|
||||
{
|
||||
PyErr_SetString(PyExc_NotImplementedError, "Not implemented");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
PyObject * PlacementPy::number_positive_handler (PyObject* /*self*/)
|
||||
PyObject* PlacementPy::number_positive_handler(PyObject* /*self*/)
|
||||
{
|
||||
PyErr_SetString(PyExc_NotImplementedError, "Not implemented");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
PyObject * PlacementPy::number_absolute_handler (PyObject* /*self*/)
|
||||
PyObject* PlacementPy::number_absolute_handler(PyObject* /*self*/)
|
||||
{
|
||||
PyErr_SetString(PyExc_NotImplementedError, "Not implemented");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
int PlacementPy::number_nonzero_handler (PyObject* /*self*/)
|
||||
int PlacementPy::number_nonzero_handler(PyObject* /*self*/)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
PyObject * PlacementPy::number_invert_handler (PyObject* /*self*/)
|
||||
PyObject* PlacementPy::number_invert_handler(PyObject* /*self*/)
|
||||
{
|
||||
PyErr_SetString(PyExc_NotImplementedError, "Not implemented");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
PyObject * PlacementPy::number_lshift_handler (PyObject* /*self*/, PyObject* /*other*/)
|
||||
PyObject* PlacementPy::number_lshift_handler(PyObject* /*self*/, PyObject* /*other*/)
|
||||
{
|
||||
PyErr_SetString(PyExc_NotImplementedError, "Not implemented");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
PyObject * PlacementPy::number_rshift_handler (PyObject* /*self*/, PyObject* /*other*/)
|
||||
PyObject* PlacementPy::number_rshift_handler(PyObject* /*self*/, PyObject* /*other*/)
|
||||
{
|
||||
PyErr_SetString(PyExc_NotImplementedError, "Not implemented");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
PyObject * PlacementPy::number_and_handler (PyObject* /*self*/, PyObject* /*other*/)
|
||||
PyObject* PlacementPy::number_and_handler(PyObject* /*self*/, PyObject* /*other*/)
|
||||
{
|
||||
PyErr_SetString(PyExc_NotImplementedError, "Not implemented");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
PyObject * PlacementPy::number_xor_handler (PyObject* /*self*/, PyObject* /*other*/)
|
||||
PyObject* PlacementPy::number_xor_handler(PyObject* /*self*/, PyObject* /*other*/)
|
||||
{
|
||||
PyErr_SetString(PyExc_NotImplementedError, "Not implemented");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
PyObject * PlacementPy::number_or_handler (PyObject* /*self*/, PyObject* /*other*/)
|
||||
PyObject* PlacementPy::number_or_handler(PyObject* /*self*/, PyObject* /*other*/)
|
||||
{
|
||||
PyErr_SetString(PyExc_NotImplementedError, "Not implemented");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
PyObject * PlacementPy::number_int_handler (PyObject * /*self*/)
|
||||
PyObject* PlacementPy::number_int_handler(PyObject* /*self*/)
|
||||
{
|
||||
PyErr_SetString(PyExc_NotImplementedError, "Not implemented");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
PyObject * PlacementPy::number_float_handler (PyObject * /*self*/)
|
||||
PyObject* PlacementPy::number_float_handler(PyObject* /*self*/)
|
||||
{
|
||||
PyErr_SetString(PyExc_NotImplementedError, "Not implemented");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
@@ -39,7 +39,7 @@
|
||||
#include <cfloat>
|
||||
#ifdef FC_OS_WIN32
|
||||
#define _USE_MATH_DEFINES
|
||||
#endif // FC_OS_WIN32
|
||||
#endif // FC_OS_WIN32
|
||||
#include <cmath>
|
||||
#include <climits>
|
||||
#include <codecvt>
|
||||
@@ -56,7 +56,7 @@
|
||||
#include <Rpc.h>
|
||||
#endif
|
||||
|
||||
#if defined (FC_OS_LINUX) || defined(FC_OS_CYGWIN) || defined(FC_OS_MACOSX) || defined(FC_OS_BSD)
|
||||
#if defined(FC_OS_LINUX) || defined(FC_OS_CYGWIN) || defined(FC_OS_MACOSX) || defined(FC_OS_BSD)
|
||||
#include <dirent.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
@@ -75,7 +75,7 @@
|
||||
#include <memory>
|
||||
#include <bitset>
|
||||
|
||||
//streams
|
||||
// streams
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
@@ -136,7 +136,6 @@
|
||||
#include <QUuid>
|
||||
|
||||
|
||||
#endif //_PreComp_
|
||||
|
||||
#endif // BASE_PRECOMPILED_H
|
||||
#endif //_PreComp_
|
||||
|
||||
#endif // BASE_PRECOMPILED_H
|
||||
|
||||
@@ -26,31 +26,42 @@
|
||||
|
||||
#include <cmath>
|
||||
|
||||
namespace Base {
|
||||
namespace Base
|
||||
{
|
||||
|
||||
// The methods are copied from OCC's Precision class
|
||||
class Precision {
|
||||
class Precision
|
||||
{
|
||||
public:
|
||||
/*!
|
||||
* \brief Angular
|
||||
* Returns the recommended precision value when checking the equality of two angles (given in radians).
|
||||
* \return
|
||||
* Returns the recommended precision value when checking the equality of two angles (given in
|
||||
* radians). \return
|
||||
*/
|
||||
static double Angular() { return 1.e-12; }
|
||||
static double Angular()
|
||||
{
|
||||
return 1.e-12;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Confusion
|
||||
* Returns the recommended precision value when checking coincidence of two points in real space.
|
||||
* \return
|
||||
* Returns the recommended precision value when checking coincidence of two points in real
|
||||
* space. \return
|
||||
*/
|
||||
static double Confusion() { return 1.e-7; }
|
||||
static double Confusion()
|
||||
{
|
||||
return 1.e-7;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief SquareConfusion
|
||||
* Returns square of \ref Confusion.
|
||||
* \return
|
||||
*/
|
||||
static double SquareConfusion() { return Confusion() * Confusion(); }
|
||||
static double SquareConfusion()
|
||||
{
|
||||
return Confusion() * Confusion();
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Intersection
|
||||
@@ -58,7 +69,10 @@ public:
|
||||
* used by intersection algorithms to decide that a solution is reached.
|
||||
* \return
|
||||
*/
|
||||
static double Intersection() { return Confusion() * 0.01; }
|
||||
static double Intersection()
|
||||
{
|
||||
return Confusion() * 0.01;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Approximation
|
||||
@@ -66,7 +80,10 @@ public:
|
||||
* by approximation algorithms.
|
||||
* \return
|
||||
*/
|
||||
static double Approximation() { return Confusion() * 10.0; }
|
||||
static double Approximation()
|
||||
{
|
||||
return Confusion() * 10.0;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Parametric
|
||||
@@ -75,7 +92,10 @@ public:
|
||||
* \param T
|
||||
* \return
|
||||
*/
|
||||
static double Parametric (const double P, const double T) { return P / T; }
|
||||
static double Parametric(const double P, const double T)
|
||||
{
|
||||
return P / T;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief PConfusion
|
||||
@@ -83,21 +103,30 @@ public:
|
||||
* \param T
|
||||
* \return
|
||||
*/
|
||||
static double PConfusion (const double T) { return Parametric (Confusion(), T); }
|
||||
static double PConfusion(const double T)
|
||||
{
|
||||
return Parametric(Confusion(), T);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief PConfusion
|
||||
* Used to test distances in parametric space on a default curve.
|
||||
* \return
|
||||
*/
|
||||
static double PConfusion() { return Parametric (Confusion()); }
|
||||
static double PConfusion()
|
||||
{
|
||||
return Parametric(Confusion());
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief SquarePConfusion
|
||||
* Returns square of \ref PConfusion.
|
||||
* \return
|
||||
*/
|
||||
static double SquarePConfusion() { return PConfusion() * PConfusion(); }
|
||||
static double SquarePConfusion()
|
||||
{
|
||||
return PConfusion() * PConfusion();
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief PIntersection
|
||||
@@ -106,15 +135,20 @@ public:
|
||||
* \param T
|
||||
* \return
|
||||
*/
|
||||
static double PIntersection (const double T) { return Parametric(Intersection(),T); }
|
||||
static double PIntersection(const double T)
|
||||
{
|
||||
return Parametric(Intersection(), T);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief PApproximation
|
||||
* Returns a precision value in parametric space, which may be used by approximation algorithms.
|
||||
* \param T
|
||||
* \return
|
||||
* Returns a precision value in parametric space, which may be used by approximation
|
||||
* algorithms. \param T \return
|
||||
*/
|
||||
static double PApproximation (const double T) { return Parametric(Approximation(),T); }
|
||||
static double PApproximation(const double T)
|
||||
{
|
||||
return Parametric(Approximation(), T);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Parametric
|
||||
@@ -122,21 +156,30 @@ public:
|
||||
* \param P
|
||||
* \return
|
||||
*/
|
||||
static double Parametric (const double P) { return Parametric (P, 100.0); }
|
||||
static double Parametric(const double P)
|
||||
{
|
||||
return Parametric(P, 100.0);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief PIntersection
|
||||
* Used for Intersections in parametric space on a default curve.
|
||||
* \return
|
||||
*/
|
||||
static double PIntersection() { return Parametric (Intersection()); }
|
||||
static double PIntersection()
|
||||
{
|
||||
return Parametric(Intersection());
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief PApproximation
|
||||
* Used for Approximations in parametric space on a default curve.
|
||||
* \return
|
||||
*/
|
||||
static double PApproximation() { return Parametric (Approximation()); }
|
||||
static double PApproximation()
|
||||
{
|
||||
return Parametric(Approximation());
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief IsInfinite
|
||||
@@ -144,7 +187,10 @@ public:
|
||||
* \param R
|
||||
* \return
|
||||
*/
|
||||
static double IsInfinite (const double R) { return std::fabs (R) >= (0.5 * Precision::Infinite()); }
|
||||
static double IsInfinite(const double R)
|
||||
{
|
||||
return std::fabs(R) >= (0.5 * Precision::Infinite());
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief IsPositiveInfinite
|
||||
@@ -152,7 +198,10 @@ public:
|
||||
* \param R
|
||||
* \return
|
||||
*/
|
||||
static double IsPositiveInfinite (const double R) { return R >= (0.5 * Precision::Infinite()); }
|
||||
static double IsPositiveInfinite(const double R)
|
||||
{
|
||||
return R >= (0.5 * Precision::Infinite());
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief IsNegativeInfinite
|
||||
@@ -160,16 +209,22 @@ public:
|
||||
* \param R
|
||||
* \return
|
||||
*/
|
||||
static bool IsNegativeInfinite (const double R) { return R <= -(0.5 * Precision::Infinite()); }
|
||||
static bool IsNegativeInfinite(const double R)
|
||||
{
|
||||
return R <= -(0.5 * Precision::Infinite());
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Infinite
|
||||
* Returns a big number that can be considered as infinite. Use -Infinite() for a negative big number.
|
||||
* \return
|
||||
* Returns a big number that can be considered as infinite. Use -Infinite() for a negative
|
||||
* big number. \return
|
||||
*/
|
||||
static double Infinite() { return 2.e+100; }
|
||||
static double Infinite()
|
||||
{
|
||||
return 2.e+100;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
} // namespace Base
|
||||
|
||||
#endif // BASE_PRECISION_H
|
||||
#endif // BASE_PRECISION_H
|
||||
|
||||
@@ -36,7 +36,7 @@ std::string PrecisionPy::representation() const
|
||||
return {"<Precision object>"};
|
||||
}
|
||||
|
||||
PyObject* PrecisionPy::angular(PyObject *args)
|
||||
PyObject* PrecisionPy::angular(PyObject* args)
|
||||
{
|
||||
if (!PyArg_ParseTuple(args, "")) {
|
||||
return nullptr;
|
||||
@@ -46,7 +46,7 @@ PyObject* PrecisionPy::angular(PyObject *args)
|
||||
return Py::new_reference_to(v);
|
||||
}
|
||||
|
||||
PyObject* PrecisionPy::confusion(PyObject *args)
|
||||
PyObject* PrecisionPy::confusion(PyObject* args)
|
||||
{
|
||||
if (!PyArg_ParseTuple(args, "")) {
|
||||
return nullptr;
|
||||
@@ -56,7 +56,7 @@ PyObject* PrecisionPy::confusion(PyObject *args)
|
||||
return Py::new_reference_to(v);
|
||||
}
|
||||
|
||||
PyObject* PrecisionPy::squareConfusion(PyObject *args)
|
||||
PyObject* PrecisionPy::squareConfusion(PyObject* args)
|
||||
{
|
||||
if (!PyArg_ParseTuple(args, "")) {
|
||||
return nullptr;
|
||||
@@ -66,7 +66,7 @@ PyObject* PrecisionPy::squareConfusion(PyObject *args)
|
||||
return Py::new_reference_to(v);
|
||||
}
|
||||
|
||||
PyObject* PrecisionPy::intersection(PyObject *args)
|
||||
PyObject* PrecisionPy::intersection(PyObject* args)
|
||||
{
|
||||
if (!PyArg_ParseTuple(args, "")) {
|
||||
return nullptr;
|
||||
@@ -76,7 +76,7 @@ PyObject* PrecisionPy::intersection(PyObject *args)
|
||||
return Py::new_reference_to(v);
|
||||
}
|
||||
|
||||
PyObject* PrecisionPy::approximation(PyObject *args)
|
||||
PyObject* PrecisionPy::approximation(PyObject* args)
|
||||
{
|
||||
if (!PyArg_ParseTuple(args, "")) {
|
||||
return nullptr;
|
||||
@@ -86,16 +86,16 @@ PyObject* PrecisionPy::approximation(PyObject *args)
|
||||
return Py::new_reference_to(v);
|
||||
}
|
||||
|
||||
PyObject* PrecisionPy::parametric(PyObject *args)
|
||||
PyObject* PrecisionPy::parametric(PyObject* args)
|
||||
{
|
||||
double p{};
|
||||
double p {};
|
||||
if (PyArg_ParseTuple(args, "d", &p)) {
|
||||
Py::Float v(Precision::Parametric(p));
|
||||
return Py::new_reference_to(v);
|
||||
}
|
||||
|
||||
PyErr_Clear();
|
||||
double t{};
|
||||
double t {};
|
||||
if (PyArg_ParseTuple(args, "dd", &p, &t)) {
|
||||
Py::Float v(Precision::Parametric(p, t));
|
||||
return Py::new_reference_to(v);
|
||||
@@ -105,9 +105,9 @@ PyObject* PrecisionPy::parametric(PyObject *args)
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
PyObject* PrecisionPy::isInfinite(PyObject *args)
|
||||
PyObject* PrecisionPy::isInfinite(PyObject* args)
|
||||
{
|
||||
double v{};
|
||||
double v {};
|
||||
if (!PyArg_ParseTuple(args, "d", &v)) {
|
||||
return nullptr;
|
||||
}
|
||||
@@ -116,9 +116,9 @@ PyObject* PrecisionPy::isInfinite(PyObject *args)
|
||||
return Py::new_reference_to(b);
|
||||
}
|
||||
|
||||
PyObject* PrecisionPy::isPositiveInfinite(PyObject *args)
|
||||
PyObject* PrecisionPy::isPositiveInfinite(PyObject* args)
|
||||
{
|
||||
double v{};
|
||||
double v {};
|
||||
if (!PyArg_ParseTuple(args, "d", &v)) {
|
||||
return nullptr;
|
||||
}
|
||||
@@ -127,9 +127,9 @@ PyObject* PrecisionPy::isPositiveInfinite(PyObject *args)
|
||||
return Py::new_reference_to(b);
|
||||
}
|
||||
|
||||
PyObject* PrecisionPy::isNegativeInfinite(PyObject *args)
|
||||
PyObject* PrecisionPy::isNegativeInfinite(PyObject* args)
|
||||
{
|
||||
double v{};
|
||||
double v {};
|
||||
if (!PyArg_ParseTuple(args, "d", &v)) {
|
||||
return nullptr;
|
||||
}
|
||||
@@ -138,7 +138,7 @@ PyObject* PrecisionPy::isNegativeInfinite(PyObject *args)
|
||||
return Py::new_reference_to(b);
|
||||
}
|
||||
|
||||
PyObject* PrecisionPy::infinite(PyObject *args)
|
||||
PyObject* PrecisionPy::infinite(PyObject* args)
|
||||
{
|
||||
if (!PyArg_ParseTuple(args, "")) {
|
||||
return nullptr;
|
||||
@@ -148,7 +148,7 @@ PyObject* PrecisionPy::infinite(PyObject *args)
|
||||
return Py::new_reference_to(v);
|
||||
}
|
||||
|
||||
PyObject *PrecisionPy::getCustomAttributes(const char* /*attr*/) const
|
||||
PyObject* PrecisionPy::getCustomAttributes(const char* /*attr*/) const
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@@ -38,9 +38,9 @@ void ProgressIndicatorPy::init_type()
|
||||
behaviors().supportSetattr();
|
||||
behaviors().set_tp_new(PyMake);
|
||||
|
||||
add_varargs_method("start",&ProgressIndicatorPy::start,"start(string,int)");
|
||||
add_varargs_method("next",&ProgressIndicatorPy::next,"next()");
|
||||
add_varargs_method("stop",&ProgressIndicatorPy::stop,"stop()");
|
||||
add_varargs_method("start", &ProgressIndicatorPy::start, "start(string,int)");
|
||||
add_varargs_method("next", &ProgressIndicatorPy::next, "next()");
|
||||
add_varargs_method("stop", &ProgressIndicatorPy::stop, "stop()");
|
||||
}
|
||||
|
||||
Py::PythonType& ProgressIndicatorPy::behaviors()
|
||||
@@ -58,7 +58,7 @@ bool ProgressIndicatorPy::check(PyObject* p)
|
||||
return Py::PythonExtension<ProgressIndicatorPy>::check(p);
|
||||
}
|
||||
|
||||
PyObject *ProgressIndicatorPy::PyMake(struct _typeobject *, PyObject *, PyObject *)
|
||||
PyObject* ProgressIndicatorPy::PyMake(struct _typeobject*, PyObject*, PyObject*)
|
||||
{
|
||||
return new ProgressIndicatorPy();
|
||||
}
|
||||
@@ -70,26 +70,28 @@ ProgressIndicatorPy::~ProgressIndicatorPy() = default;
|
||||
Py::Object ProgressIndicatorPy::repr()
|
||||
{
|
||||
std::string s = "Base.ProgressIndicator";
|
||||
return Py::String(s); // NOLINT
|
||||
return Py::String(s); // NOLINT
|
||||
}
|
||||
|
||||
Py::Object ProgressIndicatorPy::start(const Py::Tuple& args)
|
||||
{
|
||||
char* text = nullptr;
|
||||
unsigned int steps = 0;
|
||||
if (!PyArg_ParseTuple(args.ptr(), "sI",&text,&steps))
|
||||
if (!PyArg_ParseTuple(args.ptr(), "sI", &text, &steps)) {
|
||||
throw Py::Exception();
|
||||
}
|
||||
if (!_seq.get()) {
|
||||
_seq = std::make_unique<SequencerLauncher>(text,steps);
|
||||
_seq = std::make_unique<SequencerLauncher>(text, steps);
|
||||
}
|
||||
return Py::None();
|
||||
}
|
||||
|
||||
Py::Object ProgressIndicatorPy::next(const Py::Tuple& args)
|
||||
{
|
||||
int b=0;
|
||||
if (!PyArg_ParseTuple(args.ptr(), "|i",&b))
|
||||
int b = 0;
|
||||
if (!PyArg_ParseTuple(args.ptr(), "|i", &b)) {
|
||||
throw Py::Exception();
|
||||
}
|
||||
if (_seq.get()) {
|
||||
try {
|
||||
_seq->next(b ? true : false);
|
||||
@@ -104,8 +106,9 @@ Py::Object ProgressIndicatorPy::next(const Py::Tuple& args)
|
||||
|
||||
Py::Object ProgressIndicatorPy::stop(const Py::Tuple& args)
|
||||
{
|
||||
if (!PyArg_ParseTuple(args.ptr(), ""))
|
||||
if (!PyArg_ParseTuple(args.ptr(), "")) {
|
||||
throw Py::Exception();
|
||||
}
|
||||
_seq.reset();
|
||||
return Py::None();
|
||||
}
|
||||
|
||||
@@ -31,10 +31,10 @@
|
||||
namespace Base
|
||||
{
|
||||
// NOLINTNEXTLINE
|
||||
class BaseExport ProgressIndicatorPy : public Py::PythonExtension<ProgressIndicatorPy>
|
||||
class BaseExport ProgressIndicatorPy: public Py::PythonExtension<ProgressIndicatorPy>
|
||||
{
|
||||
public:
|
||||
static void init_type(); // announce properties and methods
|
||||
static void init_type(); // announce properties and methods
|
||||
static Py::PythonType& behaviors();
|
||||
static PyTypeObject* type_object();
|
||||
static bool check(PyObject* p);
|
||||
@@ -49,12 +49,12 @@ public:
|
||||
Py::Object stop(const Py::Tuple&);
|
||||
|
||||
private:
|
||||
static PyObject *PyMake(struct _typeobject *, PyObject *, PyObject *);
|
||||
static PyObject* PyMake(struct _typeobject*, PyObject*, PyObject*);
|
||||
|
||||
private:
|
||||
std::unique_ptr<SequencerLauncher> _seq;
|
||||
};
|
||||
|
||||
} // namespace Base
|
||||
} // namespace Base
|
||||
|
||||
#endif // BASE_PROGRESSINDICATORPY_H
|
||||
#endif // BASE_PROGRESSINDICATORPY_H
|
||||
|
||||
@@ -32,11 +32,11 @@
|
||||
#define BASE_PYEXPORT_H
|
||||
|
||||
// (re-)defined in pyconfig.h
|
||||
#if defined (_POSIX_C_SOURCE)
|
||||
# undef _POSIX_C_SOURCE
|
||||
#if defined(_POSIX_C_SOURCE)
|
||||
#undef _POSIX_C_SOURCE
|
||||
#endif
|
||||
#if defined (_XOPEN_SOURCE)
|
||||
# undef _XOPEN_SOURCE
|
||||
#if defined(_XOPEN_SOURCE)
|
||||
#undef _XOPEN_SOURCE
|
||||
#endif
|
||||
|
||||
#include <Python.h>
|
||||
@@ -68,34 +68,35 @@ class PyObjectBase;
|
||||
* because at construction time the reference counter is already set to 1. If the Python
|
||||
* interpreter stores this object pointer into a local variable and destroys this variable
|
||||
* then the reference counter gets decremented (to 0) and the object gets destroyed automatically.
|
||||
* In case we didn't make this specification and increment the Python object from outside once again then
|
||||
* the reference counter would be set to 2 and there would be no chance to destroy the object again.
|
||||
* In case we didn't make this specification and increment the Python object from outside once
|
||||
* again then the reference counter would be set to 2 and there would be no chance to destroy the
|
||||
* object again.
|
||||
*
|
||||
* The other case is that we have a member variable in our C++ class that holds the Python object
|
||||
* then we either can create this Python in the constructor or create it the first time when GetPyObject()
|
||||
* gets called. In the destructor then we must decrement the Python object to avoid a memory leak while
|
||||
* GetPyObject() then increments the Python object every time it gets called.
|
||||
* then we either can create this Python in the constructor or create it the first time when
|
||||
* GetPyObject() gets called. In the destructor then we must decrement the Python object to avoid a
|
||||
* memory leak while GetPyObject() then increments the Python object every time it gets called.
|
||||
*
|
||||
* @remark One big consequence of this specification is that the programmer must know whether the Python interpreter
|
||||
* gets the Python object or not. If the interpreter gets the object then it decrements the counter later on when
|
||||
* the internal variable is freed. In case the interpreter doesn't get this object then the programmer must do the
|
||||
* decrement on their own.
|
||||
* @remark One big consequence of this specification is that the programmer must know whether the
|
||||
* Python interpreter gets the Python object or not. If the interpreter gets the object then it
|
||||
* decrements the counter later on when the internal variable is freed. In case the interpreter
|
||||
* doesn't get this object then the programmer must do the decrement on their own.
|
||||
*
|
||||
* @note To not to undermine this specification the programmer must make sure to get the Python object always via
|
||||
* GetPyObject().
|
||||
* @note To not to undermine this specification the programmer must make sure to get the Python
|
||||
* object always via GetPyObject().
|
||||
*
|
||||
* @see PyHandle
|
||||
* @
|
||||
*/
|
||||
//class BaseExport PyHandler
|
||||
// class BaseExport PyHandler
|
||||
//{
|
||||
//public:
|
||||
// public:
|
||||
// void IncRef(void);
|
||||
// void DecRef(void);
|
||||
// virtual ~PyHandler();
|
||||
// virtual ~PyHandler();
|
||||
// virtual PyObjectBase *GetPyObject(void)=0;
|
||||
//
|
||||
//};
|
||||
// };
|
||||
|
||||
|
||||
/** Python Object handle class
|
||||
@@ -109,8 +110,8 @@ class PyObjectBase;
|
||||
* references on it!
|
||||
* @see PyObjectBase
|
||||
*/
|
||||
template <class HandledType>
|
||||
class PyHandle
|
||||
template<class HandledType>
|
||||
class PyHandle // NOLINT
|
||||
{
|
||||
public:
|
||||
//**************************************************************************
|
||||
@@ -121,17 +122,21 @@ public:
|
||||
* instead using a overwritten new operator in the
|
||||
* HandledType class! But is not easy to enforce!
|
||||
*/
|
||||
PyHandle(HandledType *ToHandle=0L)
|
||||
:_pHandles(ToHandle) {
|
||||
if (_pHandles)
|
||||
PyHandle(HandledType* ToHandle = 0L)
|
||||
: _pHandles(ToHandle)
|
||||
{
|
||||
if (_pHandles) {
|
||||
_pHandles->IncRef();
|
||||
}
|
||||
}
|
||||
|
||||
/// Copy constructor
|
||||
PyHandle(const PyHandle <HandledType> &ToHandle)
|
||||
:_pHandles(ToHandle._pHandles) {
|
||||
if (_pHandles)
|
||||
PyHandle(const PyHandle<HandledType>& ToHandle)
|
||||
: _pHandles(ToHandle._pHandles)
|
||||
{
|
||||
if (_pHandles) {
|
||||
_pHandles->IncRef();
|
||||
}
|
||||
}
|
||||
|
||||
/** destructor
|
||||
@@ -139,97 +144,113 @@ public:
|
||||
* if was the last one, the referenced object to
|
||||
* destruct!
|
||||
*/
|
||||
~PyHandle() {
|
||||
if (_pHandles)
|
||||
~PyHandle()
|
||||
{
|
||||
if (_pHandles) {
|
||||
_pHandles->DecRef();
|
||||
}
|
||||
}
|
||||
|
||||
//**************************************************************************
|
||||
// operator implementation
|
||||
|
||||
// assign operator from a pointer
|
||||
PyHandle <HandledType> &operator=(/*const*/ HandledType* other) {
|
||||
if (_pHandles)
|
||||
PyHandle<HandledType>& operator=(/*const*/ HandledType* other)
|
||||
{
|
||||
if (_pHandles) {
|
||||
_pHandles->DecRef();
|
||||
}
|
||||
// FIXME: Should be without "->_pHandles", shouldn't it? (Werner)
|
||||
_pHandles = other;//_pHandles = other->_pHandles;
|
||||
if (_pHandles)
|
||||
_pHandles = other; //_pHandles = other->_pHandles;
|
||||
if (_pHandles) {
|
||||
_pHandles->IncRef();
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
// assign operator from a handle
|
||||
PyHandle <HandledType> &operator=(const PyHandle <HandledType> &other) {
|
||||
if (_pHandles)
|
||||
PyHandle<HandledType>& operator=(const PyHandle<HandledType>& other)
|
||||
{
|
||||
if (_pHandles) {
|
||||
_pHandles->DecRef();
|
||||
}
|
||||
_pHandles = other._pHandles;
|
||||
if (_pHandles)
|
||||
if (_pHandles) {
|
||||
_pHandles->IncRef();
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// dereference operators
|
||||
HandledType &operator*() {
|
||||
HandledType& operator*()
|
||||
{
|
||||
return *_pHandles;
|
||||
}
|
||||
|
||||
/// dereference operators
|
||||
HandledType *operator->() {
|
||||
HandledType* operator->()
|
||||
{
|
||||
return _pHandles;
|
||||
}
|
||||
|
||||
/// dereference operators
|
||||
const HandledType &operator*() const {
|
||||
const HandledType& operator*() const
|
||||
{
|
||||
return _pHandles;
|
||||
}
|
||||
|
||||
/// dereference operators
|
||||
const HandledType *operator->() const {
|
||||
const HandledType* operator->() const
|
||||
{
|
||||
return _pHandles;
|
||||
}
|
||||
|
||||
/** lower operator
|
||||
* needed for sorting in maps and sets
|
||||
*/
|
||||
bool operator<(const PyHandle<HandledType> &other) const {
|
||||
//return _pHandles<&other;
|
||||
// FIXME: Shouldn't we compare both pointers?. (Werner)
|
||||
return _pHandles<other._pHandles;
|
||||
bool operator<(const PyHandle<HandledType>& other) const
|
||||
{
|
||||
// return _pHandles<&other;
|
||||
// FIXME: Shouldn't we compare both pointers?. (Werner)
|
||||
return _pHandles < other._pHandles;
|
||||
}
|
||||
|
||||
/// equal operator
|
||||
bool operator==(const PyHandle<HandledType> &other) const {
|
||||
//return _pHandles==&other;
|
||||
// FIXME: Shouldn't we compare both pointers?. (Werner)
|
||||
return _pHandles==other._pHandles;
|
||||
bool operator==(const PyHandle<HandledType>& other) const
|
||||
{
|
||||
// return _pHandles==&other;
|
||||
// FIXME: Shouldn't we compare both pointers?. (Werner)
|
||||
return _pHandles == other._pHandles;
|
||||
}
|
||||
|
||||
/// returns the type as PyObject
|
||||
PyObject* getPyObject() const {
|
||||
PyObject* getPyObject() const
|
||||
{
|
||||
// return (PyObject*) _pHandles;
|
||||
// FIXME: Shouldn't we return the pointer's object?. (Werner)
|
||||
return const_cast<HandledType*>(_pHandles)->getPyObject();
|
||||
return const_cast<HandledType*>(_pHandles)->getPyObject(); // NOLINT
|
||||
}
|
||||
//**************************************************************************
|
||||
// checking on the state
|
||||
|
||||
/// Test if it handles something
|
||||
bool IsValid() const {
|
||||
return _pHandles!=0;
|
||||
bool IsValid() const
|
||||
{
|
||||
return _pHandles != 0;
|
||||
}
|
||||
|
||||
/// Test if it not handles something
|
||||
bool IsNull() const {
|
||||
return _pHandles==0;
|
||||
bool IsNull() const
|
||||
{
|
||||
return _pHandles == 0;
|
||||
}
|
||||
|
||||
private:
|
||||
/// the pointer on the handled object
|
||||
HandledType *_pHandles;
|
||||
|
||||
HandledType* _pHandles;
|
||||
};
|
||||
|
||||
|
||||
} // namespace Base
|
||||
} // namespace Base
|
||||
|
||||
#endif // BASE_PYEXPORT_H
|
||||
#endif // BASE_PYEXPORT_H
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
#include "PreCompiled.h"
|
||||
|
||||
#ifndef _PreComp_
|
||||
# include <sstream>
|
||||
#include <sstream>
|
||||
#endif
|
||||
|
||||
#include "PyObjectBase.h"
|
||||
@@ -36,6 +36,7 @@
|
||||
|
||||
using namespace Base;
|
||||
|
||||
// clang-format off
|
||||
PyObject* Base::PyExc_FC_GeneralError = nullptr;
|
||||
PyObject* Base::PyExc_FC_FreeCADAbort = nullptr;
|
||||
PyObject* Base::PyExc_FC_XMLBaseException = nullptr;
|
||||
@@ -48,13 +49,13 @@ PyObject* Base::PyExc_FC_ExpressionError = nullptr;
|
||||
PyObject* Base::PyExc_FC_ParserError = nullptr;
|
||||
PyObject* Base::PyExc_FC_CADKernelError = nullptr;
|
||||
|
||||
typedef struct {
|
||||
typedef struct { //NOLINT
|
||||
PyObject_HEAD
|
||||
PyObject* baseobject;
|
||||
PyObject* weakreflist; /* List of weak references */
|
||||
} PyBaseProxy;
|
||||
|
||||
// Constructor
|
||||
// NOLINTNEXTLINE
|
||||
PyObjectBase::PyObjectBase(void* voidp, PyTypeObject *T)
|
||||
: _pcTwinPointer(voidp)
|
||||
{
|
||||
@@ -78,6 +79,7 @@ PyObjectBase::~PyObjectBase()
|
||||
#ifdef FC_LOGPYOBJECTS
|
||||
Base::Console().Log("PyO-: %s (%p)\n",Py_TYPE(this)->tp_name, this);
|
||||
#endif
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
|
||||
if (baseProxy && reinterpret_cast<PyBaseProxy*>(baseProxy)->baseobject == this)
|
||||
Py_DECREF(baseProxy);
|
||||
Py_XDECREF(attrDict);
|
||||
@@ -105,6 +107,7 @@ static void
|
||||
PyBaseProxy_dealloc(PyObject* self)
|
||||
{
|
||||
/* Clear weakrefs first before calling any destructors */
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
|
||||
if (reinterpret_cast<PyBaseProxy*>(self)->weakreflist)
|
||||
PyObject_ClearWeakRefs(self);
|
||||
Py_TYPE(self)->tp_free(self);
|
||||
@@ -164,7 +167,7 @@ static PyTypeObject PyBaseProxyType = {
|
||||
0, /*tp_version_tag */
|
||||
nullptr /*tp_finalize */
|
||||
#if PY_VERSION_HEX >= 0x03090000
|
||||
,0 /*tp_vectorcall */
|
||||
,0 //NOLINT /*tp_vectorcall */
|
||||
#elif PY_VERSION_HEX >= 0x03080000
|
||||
,0 /*tp_vectorcall */
|
||||
/* bpo-37250: kept for backwards compatibility in CPython 3.8 only */
|
||||
@@ -229,7 +232,7 @@ PyTypeObject PyObjectBase::Type = {
|
||||
0, /*tp_version_tag */
|
||||
nullptr /*tp_finalize */
|
||||
#if PY_VERSION_HEX >= 0x03090000
|
||||
,0 /*tp_vectorcall */
|
||||
,0 //NOLINT /*tp_vectorcall */
|
||||
#elif PY_VERSION_HEX >= 0x03080000
|
||||
,0 /*tp_vectorcall */
|
||||
/* bpo-37250: kept for backwards compatibility in CPython 3.8 only */
|
||||
@@ -254,6 +257,7 @@ PyObject* createWeakRef(PyObjectBase* ptr)
|
||||
if (!proxy) {
|
||||
proxy = PyType_GenericAlloc(&PyBaseProxyType, 0);
|
||||
ptr->baseProxy = proxy;
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
|
||||
reinterpret_cast<PyBaseProxy*>(proxy)->baseobject = ptr;
|
||||
}
|
||||
|
||||
@@ -266,6 +270,7 @@ PyObjectBase* getFromWeakRef(PyObject* ref)
|
||||
if (ref) {
|
||||
PyObject* proxy = PyWeakref_GetObject(ref);
|
||||
if (proxy && PyObject_TypeCheck(proxy, &PyBaseProxyType)) {
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
|
||||
return static_cast<PyObjectBase*>(reinterpret_cast<PyBaseProxy*>(proxy)->baseobject);
|
||||
}
|
||||
}
|
||||
@@ -333,6 +338,7 @@ PyObject* PyObjectBase::__getattro(PyObject * obj, PyObject *attro)
|
||||
// something is wrong with the Python types. For example, a C++ class
|
||||
// that adds an extension uses the same Python type as a wrapper than
|
||||
// another C++ class without this extension.
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
|
||||
PyCFunctionObject* cfunc = reinterpret_cast<PyCFunctionObject*>(value);
|
||||
if (!cfunc->m_self) {
|
||||
Py_DECREF(cfunc);
|
||||
@@ -391,6 +397,7 @@ PyObject *PyObjectBase::_getattr(const char *attr)
|
||||
// Note: We must return the type object here,
|
||||
// so that our own types feel as really Python objects
|
||||
Py_INCREF(Py_TYPE(this));
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
|
||||
return reinterpret_cast<PyObject *>(Py_TYPE(this));
|
||||
}
|
||||
else if (streq(attr, "__members__")) {
|
||||
@@ -565,3 +572,4 @@ void PyObjectBase::clearAttributes()
|
||||
PyDict_Clear(attrDict);
|
||||
}
|
||||
}
|
||||
// clang-format on
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
#ifndef BASE_PYOBJECTBASE_H
|
||||
#define BASE_PYOBJECTBASE_H
|
||||
|
||||
// clang-format off
|
||||
// Std. configurations
|
||||
|
||||
// (re-)defined in pyconfig.h
|
||||
@@ -553,5 +554,6 @@ inline void PyTypeCheck(PyObject** ptr, int (*method)(PyObject*), const char* ms
|
||||
|
||||
} // namespace Base
|
||||
|
||||
// clang-format on
|
||||
|
||||
#endif // BASE_PYOBJECTBASE_H
|
||||
#endif // BASE_PYOBJECTBASE_H
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
// clang-format off
|
||||
/*
|
||||
PPEMBED, VERSION 2.0
|
||||
AN ENHANCED PYTHON EMBEDDED-CALL INTERFACE
|
||||
|
||||
Copyright 1996-2000, by Mark Lutz, and O'Reilly and Associates.
|
||||
Permission to use, copy, modify, and distribute this software
|
||||
Permission to use, copy, modify, and distribute this software
|
||||
for any purpose and without fee is hereby granted. This software
|
||||
is provided on an as is basis, without warranties of any kind.
|
||||
*/
|
||||
@@ -22,8 +23,8 @@ is provided on an as is basis, without warranties of any kind.
|
||||
|
||||
//NOLINTBEGIN
|
||||
/*****************************************************************************
|
||||
* RUN EMBEDDED OBJECT METHODS, ACCESS OBJECT ATTRIBUTES
|
||||
* handles attribute fetch, debugging, input/output conversions;
|
||||
* RUN EMBEDDED OBJECT METHODS, ACCESS OBJECT ATTRIBUTES
|
||||
* handles attribute fetch, debugging, input/output conversions;
|
||||
* there is no module to reload here: assumes a known object;
|
||||
*****************************************************************************/
|
||||
|
||||
@@ -37,7 +38,7 @@ PP_Run_Method(PyObject *pobject, const char *method,
|
||||
va_start(argslist, argfmt);
|
||||
|
||||
Py_Initialize(); /* init if first time */
|
||||
pmeth = PyObject_GetAttrString(pobject, method);
|
||||
pmeth = PyObject_GetAttrString(pobject, method);
|
||||
if (pmeth == NULL) { /* get callable object */
|
||||
va_end(argslist);
|
||||
return -1; /* bound method? has self */
|
||||
@@ -50,9 +51,9 @@ PP_Run_Method(PyObject *pobject, const char *method,
|
||||
Py_DECREF(pmeth);
|
||||
return -1;
|
||||
}
|
||||
if (PP_DEBUG) /* debug it too? */
|
||||
presult = PP_Debug_Function(pmeth, pargs);
|
||||
else
|
||||
if (PP_DEBUG) /* debug it too? */
|
||||
presult = PP_Debug_Function(pmeth, pargs);
|
||||
else
|
||||
#if PY_VERSION_HEX < 0x03090000
|
||||
presult = PyEval_CallObject(pmeth, pargs); /* run interpreter */
|
||||
#else
|
||||
@@ -64,18 +65,18 @@ PP_Run_Method(PyObject *pobject, const char *method,
|
||||
|
||||
return PP_Convert_Result(presult, resfmt, cresult); /* to C format */
|
||||
}
|
||||
|
||||
|
||||
|
||||
int
|
||||
PP_Get_Member(PyObject *pobject, const char *attrname,
|
||||
const char *resfmt, void *cresult) /* convert to c/c++ */
|
||||
{
|
||||
PyObject *pmemb = NULL; /* "pobject.attrname" */
|
||||
Py_Initialize();
|
||||
Py_Initialize();
|
||||
pmemb = PyObject_GetAttrString(pobject, attrname); /* incref'd */
|
||||
return PP_Convert_Result(pmemb, resfmt, cresult); /* to C form, decrefs */
|
||||
}
|
||||
|
||||
|
||||
|
||||
int
|
||||
PP_Set_Member(PyObject *pobject, const char *attrname,
|
||||
@@ -91,15 +92,15 @@ PP_Set_Member(PyObject *pobject, const char *attrname,
|
||||
if (pval == NULL)
|
||||
return -1;
|
||||
result = PyObject_SetAttrString(pobject, attrname, pval); /* setattr */
|
||||
Py_DECREF(pval);
|
||||
Py_DECREF(pval);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
* RUN EMBEDDED MODULE FUNCTIONS
|
||||
* handles module (re)import, debugging, input/output conversions;
|
||||
* note: also useful for calling classes (and C type constructors) at the
|
||||
* RUN EMBEDDED MODULE FUNCTIONS
|
||||
* handles module (re)import, debugging, input/output conversions;
|
||||
* note: also useful for calling classes (and C type constructors) at the
|
||||
* top-level of a module to make Python instances: use class-name (or type
|
||||
* constructor function name) and 'O' result convert-code to get raw object;
|
||||
* use argfmt="()" for no args, cresult='NULL' for no result (procedure);
|
||||
@@ -151,9 +152,9 @@ PP_Debug_Function(PyObject *func, PyObject *args)
|
||||
/* expand tuple at front */
|
||||
// it seems that some versions of python want just 2 arguments; in that
|
||||
// case, remove trailing 1
|
||||
oops = _PyTuple_Resize(&args, (1 + PyTuple_Size(args)));
|
||||
oops |= PyTuple_SetItem(args, 0, func);
|
||||
if (oops)
|
||||
oops = _PyTuple_Resize(&args, (1 + PyTuple_Size(args)));
|
||||
oops |= PyTuple_SetItem(args, 0, func);
|
||||
if (oops)
|
||||
return NULL; /* "args = (funcobj,) + (arg,..)" */
|
||||
|
||||
res = PP_Run_Function( /* "pdb.runcall(funcobj, arg,..)" */
|
||||
@@ -174,7 +175,7 @@ PP_Run_Known_Callable(PyObject *object, /* func|class|method */
|
||||
va_list argslist;
|
||||
va_start(argslist, argfmt); /* "return object(args)" */
|
||||
|
||||
Py_Initialize();
|
||||
Py_Initialize();
|
||||
args = Py_VaBuildValue(argfmt, argslist); /* convert args to python */
|
||||
va_end(argslist);
|
||||
if (args == NULL) /* args incref'd */
|
||||
@@ -195,14 +196,14 @@ PP_Run_Known_Callable(PyObject *object, /* func|class|method */
|
||||
/*****************************************************************************
|
||||
* PYTHON EXCEPTION INFORMATION ACCESS
|
||||
* fetch Python-related error info (type, value);
|
||||
* after an API call returns an exception indicator, call
|
||||
* after an API call returns an exception indicator, call
|
||||
* PP_Fetch_Error_Text, then get text from the 3 char[]'s;
|
||||
* note: calling PyErr_Fetch() clears/erases the current
|
||||
* exception in the Python system, as does PyErr_Print(),
|
||||
* note: calling PyErr_Fetch() clears/erases the current
|
||||
* exception in the Python system, as does PyErr_Print(),
|
||||
* so you should call one of these, one time, per exception:
|
||||
* caveats: not thread-specific since saves data in globals,
|
||||
* and only exports traceback object (the exception type and
|
||||
* data are converted to text strings and discarded); the
|
||||
* and only exports traceback object (the exception type and
|
||||
* data are converted to text strings and discarded); the
|
||||
* PyErr_Print() built-in also does a bit more on syntax errors,
|
||||
* and sends its text to sys.stderr: in principle, we could
|
||||
* assign stderr to a StringIO object and call PyErr_Print, but
|
||||
@@ -251,7 +252,7 @@ void PP_Fetch_Error_Text()
|
||||
{
|
||||
PP_last_error_type[0] = '\0';
|
||||
}
|
||||
|
||||
|
||||
Py_XDECREF(pystring);
|
||||
|
||||
pystring = NULL;
|
||||
@@ -262,7 +263,7 @@ void PP_Fetch_Error_Text()
|
||||
// PyDict_GetItemString returns a borrowed reference
|
||||
// so we must make sure not to decrement the reference
|
||||
PyObject* value = PyDict_GetItemString(errdata,"swhat");
|
||||
|
||||
|
||||
if (value!=NULL) {
|
||||
strncpy(PP_last_error_info, PyUnicode_AsUTF8(value), MAX);
|
||||
PP_last_error_info[MAX-1] = '\0';
|
||||
@@ -278,12 +279,12 @@ void PP_Fetch_Error_Text()
|
||||
strncpy(PP_last_error_info, PyUnicode_AsUTF8(pystring), MAX); /*Py->C*/
|
||||
PP_last_error_info[MAX-1] = '\0';
|
||||
}
|
||||
else
|
||||
else
|
||||
strcpy(PP_last_error_info, "<unknown exception data>");
|
||||
|
||||
|
||||
Py_XDECREF(pystring);
|
||||
|
||||
/* convert traceback to string */
|
||||
/* convert traceback to string */
|
||||
/* print text to a StringIO.StringIO() internal file object, then */
|
||||
/* fetch by calling object's .getvalue() method (see lib manual); */
|
||||
|
||||
@@ -294,13 +295,13 @@ void PP_Fetch_Error_Text()
|
||||
(PyTraceBack_Print(errtraceback, pystring) == 0) &&
|
||||
(PP_Run_Method(pystring, "getvalue", "s", &tempstr, "()") == 0) )
|
||||
{
|
||||
strncpy(PP_last_error_trace, tempstr, MAX);
|
||||
strncpy(PP_last_error_trace, tempstr, MAX);
|
||||
PP_last_error_trace[MAX-1] = '\0';
|
||||
free(tempstr); /* it's a strdup */
|
||||
}
|
||||
else {
|
||||
PyFrameObject* frame = PyEval_GetFrame();
|
||||
if(!frame)
|
||||
if(!frame)
|
||||
return;
|
||||
int line = PyFrame_GetLineNumber(frame);
|
||||
#if PY_VERSION_HEX < 0x030b0000
|
||||
@@ -327,7 +328,7 @@ void PP_Fetch_Error_Text()
|
||||
PP_last_exception_type = 0;
|
||||
Py_XDECREF(errobj);
|
||||
Py_XDECREF(errdata); /* this function owns all 3 objects */
|
||||
Py_XDECREF(PP_last_traceback); /* they've been NULL'd out in Python */
|
||||
Py_XDECREF(PP_last_traceback); /* they've been NULL'd out in Python */
|
||||
Py_XDECREF(PP_PyDict_Object);
|
||||
PP_last_traceback = errtraceback; /* save/export raw traceback object */
|
||||
PP_PyDict_Object = pydict;
|
||||
@@ -337,9 +338,9 @@ void PP_Fetch_Error_Text()
|
||||
/*****************************************************************************
|
||||
* GET/SET MODULE-LEVEL (GLOBAL) PYTHON VARIABLES BY NAME
|
||||
* handles module (re)loading, input/output conversions;
|
||||
* useful for passing data to/from codestrings (no args or return
|
||||
* useful for passing data to/from codestrings (no args or return
|
||||
* val)--load module, set inputs, run codestring, get outputs;
|
||||
* subtle thing: Python "s" output conversion code sets a C char* to
|
||||
* subtle thing: Python "s" output conversion code sets a C char* to
|
||||
* the text in the middle of a Python string object, which may be
|
||||
* returned to the heap if decref'd--this api copies the text to a new
|
||||
* char array (with strdup) that the caller must free() when possible,
|
||||
@@ -390,7 +391,7 @@ PP_Get_Global(const char *modname, const char *varname, const char *resfmt, void
|
||||
|
||||
|
||||
int
|
||||
PP_Set_Global(const char *modname, const char *varname, const char *valfmt, ... /* cval(s) */)
|
||||
PP_Set_Global(const char *modname, const char *varname, const char *valfmt, ... /* cval(s) */)
|
||||
{
|
||||
int result = 0;
|
||||
PyObject *module = NULL, *val = NULL; /* "modname.varname = val" */
|
||||
@@ -404,20 +405,20 @@ PP_Set_Global(const char *modname, const char *varname, const char *valfmt, ...
|
||||
}
|
||||
val = Py_VaBuildValue(valfmt, cvals); /* convert input to Python */
|
||||
va_end(cvals);
|
||||
if (val == NULL)
|
||||
if (val == NULL)
|
||||
return -1;
|
||||
result = PyObject_SetAttrString(module, varname, val);
|
||||
result = PyObject_SetAttrString(module, varname, val);
|
||||
Py_DECREF(val); /* set global module var */
|
||||
return result; /* decref val: var owns it */
|
||||
} /* 0=success, varname set */
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
* MODULE INTERFACE
|
||||
* MODULE INTERFACE
|
||||
* make/import/reload a python module by name
|
||||
* Note that Make_Dummy_Module could be implemented to keep a table
|
||||
* of generated dictionaries to be used as namespaces, rather than
|
||||
* using low level tools to create and mark real modules; this
|
||||
* of generated dictionaries to be used as namespaces, rather than
|
||||
* using low level tools to create and mark real modules; this
|
||||
* approach would require extra logic to manage and use the table;
|
||||
* see basic example of using dictionaries for string namespaces;
|
||||
*****************************************************************************/
|
||||
@@ -443,10 +444,10 @@ PP_Make_Dummy_Module(const char *modname) /* namespace for strings, if no file
|
||||
Py_Initialize();
|
||||
module = PyImport_AddModule(modname); /* fetch or make, no load */
|
||||
if (module == NULL) /* module not incref'd */
|
||||
return -1;
|
||||
return -1;
|
||||
else { /* module.__dict__ */
|
||||
dict = PyModule_GetDict(module); /* ['__dummy__'] = None */
|
||||
PyDict_SetItemString(dict, "__dummy__", Py_None);
|
||||
PyDict_SetItemString(dict, "__dummy__", Py_None);
|
||||
PyDict_SetItemString(dict, "__builtins__", PyEval_GetBuiltins());
|
||||
return 0;
|
||||
}
|
||||
@@ -456,15 +457,15 @@ PP_Make_Dummy_Module(const char *modname) /* namespace for strings, if no file
|
||||
PyObject * /* returns module object named modname */
|
||||
PP_Load_Module(const char *modname) /* modname can be "package.module" form */
|
||||
{ /* reload just resets C extension mods */
|
||||
/*
|
||||
/*
|
||||
* 4 cases:
|
||||
* - module "__main__" has no file, and not prebuilt: fetch or make
|
||||
* - dummy modules have no files: don't try to reload them
|
||||
* - reload=on and already loaded (on sys.modules): "reload()" before use
|
||||
* - not loaded yet, or loaded but reload=off: "import" to fetch or load
|
||||
* - not loaded yet, or loaded but reload=off: "import" to fetch or load
|
||||
*/
|
||||
|
||||
PyObject *module = NULL, *sysmods = NULL;
|
||||
PyObject *module = NULL, *sysmods = NULL;
|
||||
modname = PP_Init(modname); /* default to __main__ */
|
||||
|
||||
if (strcmp(modname, "__main__") == 0) /* main: no file */
|
||||
@@ -472,9 +473,9 @@ PP_Load_Module(const char *modname) /* modname can be "package.module" for
|
||||
|
||||
sysmods = PyImport_GetModuleDict(); /* get sys.modules dict */
|
||||
module = PyDict_GetItemString(sysmods, modname); /* mod in sys.modules? */
|
||||
|
||||
|
||||
if (module != NULL && /* dummy: no file */
|
||||
PyModule_Check(module) &&
|
||||
PyModule_Check(module) &&
|
||||
PyDict_GetItemString(PyModule_GetDict(module), "__dummy__")) {
|
||||
return module; /* not increfd */
|
||||
}
|
||||
@@ -484,7 +485,7 @@ PP_Load_Module(const char *modname) /* modname can be "package.module" for
|
||||
Py_XDECREF(module); /* still on sys.modules */
|
||||
return module; /* not increfd */
|
||||
}
|
||||
else {
|
||||
else {
|
||||
module = PyImport_ImportModule(modname); /* fetch or load module */
|
||||
Py_XDECREF(module); /* still on sys.modules */
|
||||
return module; /* not increfd */
|
||||
@@ -521,11 +522,11 @@ PP_Run_Command_Line(const char *prompt)
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* RUN EMBEDDED CODE-STRINGS
|
||||
* RUN EMBEDDED CODE-STRINGS
|
||||
* handles debugging, module (re)loading, namespaces, output conversions;
|
||||
* pbd.runeval returns a value: "eval(expr + '\n', globals, locals)";
|
||||
* pdb.run is just a statement: "exec cmd + '\n' in globals, locals"
|
||||
* New tools: precompiling strings to bytecode, running bytecode;
|
||||
* New tools: precompiling strings to bytecode, running bytecode;
|
||||
*****************************************************************************/
|
||||
|
||||
|
||||
@@ -547,9 +548,9 @@ PP_Run_Codestr(PPStringModes mode, const char *code, /* expr or stmt string */
|
||||
return -1;
|
||||
|
||||
parse_mode = (mode == PP_EXPRESSION ? Py_eval_input : Py_file_input);
|
||||
if (PP_DEBUG)
|
||||
if (PP_DEBUG)
|
||||
presult = PP_Debug_Codestr(mode, code, dict); /* run in pdb */
|
||||
else
|
||||
else
|
||||
presult = PyRun_String(code, parse_mode, dict, dict); /* eval direct */
|
||||
/* increfs res */
|
||||
if (mode == PP_STATEMENT) {
|
||||
@@ -605,11 +606,11 @@ PP_Run_Bytecode(PyObject *codeobj, /* run compiled bytecode object */
|
||||
/**************************************************************************
|
||||
* subtle things:
|
||||
* 1) pdb.run and pdb.runeval both accept either a string or a
|
||||
* compiled code object, just because they call the built in exec and
|
||||
* compiled code object, just because they call the built in exec and
|
||||
* eval(), which allow either form; further, eval() works on code
|
||||
* objects compiled as either expressions or statements, but returns
|
||||
* None as the result of statements, so we don't need to distinguish
|
||||
* between expressions and statements here again for bytecode (we
|
||||
* None as the result of statements, so we don't need to distinguish
|
||||
* between expressions and statements here again for bytecode (we
|
||||
* did when compiling); the equivalents in Python code:
|
||||
* >>> a = 1
|
||||
* >>> s = compile('x = 1', '', 'exec')
|
||||
@@ -618,7 +619,7 @@ PP_Run_Bytecode(PyObject *codeobj, /* run compiled bytecode object */
|
||||
* 2
|
||||
* >>> print eval(s)
|
||||
* None
|
||||
* on the other hand, we can't blindly use pdb.runeval when dealing
|
||||
* on the other hand, we can't blindly use pdb.runeval when dealing
|
||||
* with uncompiled strings, because eval() fails on statement strings;
|
||||
*
|
||||
* 2) in 1.5, if you debug a string or bytecode object in a module's
|
||||
@@ -631,7 +632,7 @@ PP_Run_Bytecode(PyObject *codeobj, /* run compiled bytecode object */
|
||||
**************************************************************************/
|
||||
|
||||
|
||||
static void fixPdbRetval(PyObject *moddict)
|
||||
static void fixPdbRetval(PyObject *moddict)
|
||||
{ if (PyDict_DelItemString(moddict, "__return__")) PyErr_Clear(); }
|
||||
|
||||
|
||||
@@ -646,7 +647,7 @@ PP_Debug_Codestr(PPStringModes mode, const char *codestring, PyObject *moddict)
|
||||
res = PP_Run_Function( /* "pdb.run(stmt, gdict, ldict)" */
|
||||
"pdb", pdbname, /* "pdb.runeval(expr, gdict, ldict)" */
|
||||
"O", &presult,
|
||||
"(sOO)", codestring, moddict, moddict);
|
||||
"(sOO)", codestring, moddict, moddict);
|
||||
return (res != 0) ? NULL : presult; /* return null or increfd object */
|
||||
}
|
||||
|
||||
@@ -660,8 +661,8 @@ PP_Debug_Bytecode(PyObject *codeobject, PyObject *moddict)
|
||||
res = PP_Run_Function( /* "pdb.runeval(codeobj, gdict, ldict)" */
|
||||
"pdb", "runeval", /* accepts string|code, code=stmt|expr */
|
||||
"O", &presult,
|
||||
"(OOO)", codeobject, moddict, moddict);
|
||||
"(OOO)", codeobject, moddict, moddict);
|
||||
return (res != 0) ? NULL : presult; /* null if error in run_function */
|
||||
}
|
||||
// NOLINTEND
|
||||
|
||||
// clang-format on
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
// clang-format off
|
||||
/*************************************************************************
|
||||
* PPEMBED, VERSION 2.0
|
||||
* AN ENHANCED PYTHON EMBEDDED-CALL INTERFACE
|
||||
* AN ENHANCED PYTHON EMBEDDED-CALL INTERFACE
|
||||
*
|
||||
* Wraps Python's run-time embedding API functions for easy use.
|
||||
* Most utilities assume the call is qualified by an enclosing module
|
||||
@@ -10,43 +11,43 @@
|
||||
*
|
||||
* Python is automatically initialized when the first API call occurs.
|
||||
* Input/output conversions use the standard Python conversion format
|
||||
* codes (described in the C API manual). Errors are flagged as either
|
||||
* codes (described in the C API manual). Errors are flagged as either
|
||||
* a -1 int, or a NULL pointer result. Exported names use a PP_ prefix
|
||||
* to minimize clashes; names in the built-in Python API use Py prefixes
|
||||
* instead (alas, there is no "import" equivalent in C, just "from*").
|
||||
* instead (alas, there is no "import" equivalent in C, just "from*").
|
||||
* Also note that the varargs code here may not be portable to certain
|
||||
* C compilers; to do it portably, see the text or file 'vararg.txt'
|
||||
* C compilers; to do it portably, see the text or file 'vararg.txt'
|
||||
* here, or search for string STDARG in Python's source code files.
|
||||
*
|
||||
* New in this version/edition: names now have a PP_ prefix, files
|
||||
* renamed, compiles to a single .a file, fixed pdb retval bug for
|
||||
* strings, and char* results returned by the "s" convert code now
|
||||
* point to new char arrays which the caller should free() when no
|
||||
* longer needed (this was a potential bug in prior version). Also
|
||||
* added new API interfaces for fetching exception info after errors,
|
||||
* renamed, compiles to a single .a file, fixed pdb retval bug for
|
||||
* strings, and char* results returned by the "s" convert code now
|
||||
* point to new char arrays which the caller should free() when no
|
||||
* longer needed (this was a potential bug in prior version). Also
|
||||
* added new API interfaces for fetching exception info after errors,
|
||||
* precompiling code strings to byte code, and calling simple objects.
|
||||
*
|
||||
* Also fully supports Python 1.5 module package imports: module names
|
||||
* in this API can take the form "package.package.[...].module", where
|
||||
* Python maps the package names to a nested directories path in your
|
||||
* Also fully supports Python 1.5 module package imports: module names
|
||||
* in this API can take the form "package.package.[...].module", where
|
||||
* Python maps the package names to a nested directories path in your
|
||||
* file system hierarchy; package dirs all contain __init__.py files,
|
||||
* and the leftmost one is in a directory found on PYTHONPATH. This
|
||||
* API's dynamic reload feature also works for modules in packages;
|
||||
* Python stores the full path name in the sys.modules dictionary.
|
||||
*
|
||||
* Caveats: there is no support for advanced things like threading or
|
||||
* restricted execution mode here, but such things may be added with
|
||||
* extra Python API calls external to this API (see the Python/C API
|
||||
* manual for C-level threading calls; see modules rexec and bastion
|
||||
* Caveats: there is no support for advanced things like threading or
|
||||
* restricted execution mode here, but such things may be added with
|
||||
* extra Python API calls external to this API (see the Python/C API
|
||||
* manual for C-level threading calls; see modules rexec and bastion
|
||||
* in the library manual for restricted mode details). For threading,
|
||||
* you may also be able to get by with C threads and distinct Python
|
||||
* namespaces per Python code segments, or Python language threads
|
||||
* you may also be able to get by with C threads and distinct Python
|
||||
* namespaces per Python code segments, or Python language threads
|
||||
* started by Python code run from C (see the Python thread module).
|
||||
*
|
||||
*
|
||||
* Note that Python can only reload Python modules, not C extensions,
|
||||
* but it's okay to leave the dynamic reload flag on even if you might
|
||||
* but it's okay to leave the dynamic reload flag on even if you might
|
||||
* access dynamically-loaded C extension modules--in 1.5.2, Python
|
||||
* simply resets C extension modules to their initial attribute state
|
||||
* simply resets C extension modules to their initial attribute state
|
||||
* when reloaded, but doesn't actually reload the C extension file.
|
||||
*************************************************************************/
|
||||
|
||||
@@ -55,7 +56,7 @@ PPEMBED, VERSION 2.0
|
||||
AN ENHANCED PYTHON EMBEDDED-CALL INTERFACE
|
||||
|
||||
Copyright 1996-2000, by Mark Lutz, and O'Reilly and Associates.
|
||||
Permission to use, copy, modify, and distribute this software
|
||||
Permission to use, copy, modify, and distribute this software
|
||||
for any purpose and without fee is hereby granted. This software
|
||||
is provided on an as is basis, without warranties of any kind.
|
||||
*/
|
||||
@@ -65,9 +66,9 @@ is provided on an as is basis, without warranties of any kind.
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" { /* a C library, but callable from C++ */
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdio.h> //NOLINT
|
||||
// Python
|
||||
#if defined (_POSIX_C_SOURCE)
|
||||
# undef _POSIX_C_SOURCE
|
||||
@@ -80,7 +81,7 @@ extern "C" { /* a C library, but callable from C++ */
|
||||
extern int PP_RELOAD; /* 1=reload py modules when attributes referenced */
|
||||
extern int PP_DEBUG; /* 1=start debugger when string/function/member run */
|
||||
|
||||
typedef enum {
|
||||
typedef enum { //NOLINT
|
||||
PP_EXPRESSION, /* which kind of code-string */
|
||||
PP_STATEMENT /* expressions and statements differ */
|
||||
} PPStringModes;
|
||||
@@ -104,7 +105,7 @@ extern int PP_Run_Command_Line(const char *prompt);
|
||||
extern int
|
||||
PP_Convert_Result(PyObject *presult, const char *resFormat, void *resTarget);
|
||||
|
||||
extern int
|
||||
extern int
|
||||
PP_Get_Global(const char *modname, const char *varname, const char *resfmt, void *cresult);
|
||||
|
||||
extern int
|
||||
@@ -125,16 +126,16 @@ extern PyObject*
|
||||
const char *codestring, PyObject *moddict);
|
||||
|
||||
extern PyObject *
|
||||
PP_Compile_Codestr(PPStringModes mode,
|
||||
PP_Compile_Codestr(PPStringModes mode,
|
||||
const char *codestr); /* precompile to bytecode */
|
||||
|
||||
extern int
|
||||
PP_Run_Bytecode(PyObject *codeobj, /* run a bytecode object */
|
||||
const char *modname,
|
||||
const char *modname,
|
||||
const char *resfmt, void *restarget);
|
||||
|
||||
extern PyObject * /* run bytecode under pdb */
|
||||
PP_Debug_Bytecode(PyObject *codeobject, PyObject *moddict);
|
||||
PP_Debug_Bytecode(PyObject *codeobject, PyObject *moddict);
|
||||
|
||||
|
||||
/*******************************************************/
|
||||
@@ -159,22 +160,22 @@ extern int
|
||||
/* ppembed-attributes.c: run object methods, access members */
|
||||
/**************************************************************/
|
||||
|
||||
extern int
|
||||
extern int
|
||||
PP_Run_Method(PyObject *pobject, const char *method, /* uses Debug_Function */
|
||||
const char *resfmt, void *cresult, /* output */
|
||||
const char *argfmt, ... /* arg, arg... */ ); /* inputs */
|
||||
|
||||
extern int
|
||||
extern int
|
||||
PP_Get_Member(PyObject *pobject, const char *attrname,
|
||||
const char *resfmt, void *cresult); /* output */
|
||||
|
||||
extern int
|
||||
extern int
|
||||
PP_Set_Member(PyObject *pobject, const char *attrname,
|
||||
const char *valfmt, ... /* val, val... */ ); /* input */
|
||||
|
||||
|
||||
/**********************************************************/
|
||||
/* ppembed-errors.c: get exception data after api error */
|
||||
/* ppembed-errors.c: get exception data after api error */
|
||||
/**********************************************************/
|
||||
|
||||
extern void PP_Fetch_Error_Text(); /* fetch (and clear) exception */
|
||||
@@ -193,3 +194,4 @@ extern PyObject *PP_last_exception_type; /* saved exception type */
|
||||
#endif
|
||||
|
||||
#endif /*PREEMBED_H*/
|
||||
// clang-format on
|
||||
|
||||
@@ -28,47 +28,45 @@
|
||||
#include <array>
|
||||
#include <type_traits>
|
||||
|
||||
namespace Base {
|
||||
namespace Base
|
||||
{
|
||||
|
||||
/// A thin C++ wrapper around PyArg_ParseTupleAndKeywords providing const-correctness for the keywords argument
|
||||
/// \arg args The Python args object
|
||||
/// \arg kw The Python kw object
|
||||
/// \arg format The format string describing the expected arguments
|
||||
/// \arg keywords A std::array of keywords, terminated by a nullptr (required by CPython)
|
||||
/// \arg (variadic) Pointers to the storage locations for the parameters
|
||||
/// \returns boolean true on success, or false on failure
|
||||
template<size_t arraySize>
|
||||
bool Wrapped_ParseTupleAndKeywords(PyObject *args,
|
||||
PyObject *kw,
|
||||
const char *format,
|
||||
const std::array<const char *, arraySize> keywords,
|
||||
...)
|
||||
{
|
||||
static_assert(arraySize > 0, "keywords array must have at least a single nullptr in it");
|
||||
if (keywords.back()) {
|
||||
PyErr_SetString(PyExc_ValueError, "Last element of keywords array is not null");
|
||||
return false;
|
||||
}
|
||||
|
||||
// NOTE: This code is from getargs.c in the Python source code (modified to use the public interface at
|
||||
// PyArg_VaParseTupleAndKeywords and to return a bool).
|
||||
|
||||
if ((args == nullptr || !PyTuple_Check(args)) ||
|
||||
(kw != nullptr && !PyDict_Check(kw)) ||
|
||||
format == nullptr)
|
||||
{
|
||||
PyErr_BadInternalCall();
|
||||
return false;
|
||||
}
|
||||
|
||||
va_list va; // NOLINT
|
||||
va_start(va, keywords);
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-const-cast)
|
||||
int retval = PyArg_VaParseTupleAndKeywords(args, kw, format, const_cast<char **>(keywords.data()), va);
|
||||
va_end(va);
|
||||
return retval != 0; // Convert to a true C++ boolean
|
||||
/// A thin C++ wrapper around PyArg_ParseTupleAndKeywords providing const-correctness for the
|
||||
/// keywords argument \arg args The Python args object \arg kw The Python kw object \arg format The
|
||||
/// format string describing the expected arguments \arg keywords A std::array of keywords,
|
||||
/// terminated by a nullptr (required by CPython) \arg (variadic) Pointers to the storage locations
|
||||
/// for the parameters \returns boolean true on success, or false on failure
|
||||
template<size_t arraySize>
|
||||
bool Wrapped_ParseTupleAndKeywords(PyObject* args,
|
||||
PyObject* kw,
|
||||
const char* format,
|
||||
const std::array<const char*, arraySize> keywords,
|
||||
...)
|
||||
{
|
||||
static_assert(arraySize > 0, "keywords array must have at least a single nullptr in it");
|
||||
if (keywords.back()) {
|
||||
PyErr_SetString(PyExc_ValueError, "Last element of keywords array is not null");
|
||||
return false;
|
||||
}
|
||||
|
||||
// NOTE: This code is from getargs.c in the Python source code (modified to use the public
|
||||
// interface at PyArg_VaParseTupleAndKeywords and to return a bool).
|
||||
|
||||
if ((args == nullptr || !PyTuple_Check(args)) || (kw != nullptr && !PyDict_Check(kw))
|
||||
|| format == nullptr) {
|
||||
PyErr_BadInternalCall();
|
||||
return false;
|
||||
}
|
||||
|
||||
va_list va; // NOLINT
|
||||
va_start(va, keywords);
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-const-cast)
|
||||
int retval =
|
||||
PyArg_VaParseTupleAndKeywords(args, kw, format, const_cast<char**>(keywords.data()), va);
|
||||
va_end(va);
|
||||
return retval != 0; // Convert to a true C++ boolean
|
||||
}
|
||||
|
||||
#endif //FREECAD_PYWRAPPARSETUPLEANDKEYWORDS_H
|
||||
} // namespace Base
|
||||
|
||||
#endif // FREECAD_PYWRAPPARSETUPLEANDKEYWORDS_H
|
||||
|
||||
@@ -32,17 +32,19 @@ using namespace Base;
|
||||
|
||||
PythonTypeExt::PythonTypeExt(Py::PythonType& type)
|
||||
: pytype(type)
|
||||
{
|
||||
}
|
||||
{}
|
||||
|
||||
Py::PythonType& PythonTypeExt::set_tp_descr_get(PyObject* (*tp_descr_get)(PyObject* self, PyObject* obj, PyObject* type))
|
||||
Py::PythonType& PythonTypeExt::set_tp_descr_get(PyObject* (*tp_descr_get)(PyObject* self,
|
||||
PyObject* obj,
|
||||
PyObject* type))
|
||||
{
|
||||
pytype.type_object()->tp_descr_get = tp_descr_get;
|
||||
|
||||
return pytype;
|
||||
}
|
||||
|
||||
Py::PythonType& PythonTypeExt::set_tp_descr_set(int (*tp_descr_set)(PyObject* self, PyObject* obj, PyObject* value))
|
||||
Py::PythonType&
|
||||
PythonTypeExt::set_tp_descr_set(int (*tp_descr_set)(PyObject* self, PyObject* obj, PyObject* value))
|
||||
{
|
||||
pytype.type_object()->tp_descr_set = tp_descr_set;
|
||||
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
|
||||
namespace Py
|
||||
{
|
||||
class PythonType;
|
||||
class PythonType;
|
||||
}
|
||||
|
||||
using PyObject = struct _object;
|
||||
@@ -43,13 +43,15 @@ class BaseExport PythonTypeExt
|
||||
public:
|
||||
PythonTypeExt(Py::PythonType& type);
|
||||
|
||||
Py::PythonType& set_tp_descr_get(PyObject* (*tp_descr_get)(PyObject* self, PyObject* obj, PyObject* type));
|
||||
Py::PythonType& set_tp_descr_set(int (*tp_descr_set)(PyObject* self, PyObject* obj, PyObject* value));
|
||||
Py::PythonType&
|
||||
set_tp_descr_get(PyObject* (*tp_descr_get)(PyObject* self, PyObject* obj, PyObject* type));
|
||||
Py::PythonType&
|
||||
set_tp_descr_set(int (*tp_descr_set)(PyObject* self, PyObject* obj, PyObject* value));
|
||||
|
||||
private:
|
||||
Py::PythonType& pytype;
|
||||
};
|
||||
|
||||
} // namespace Base
|
||||
} // namespace Base
|
||||
|
||||
#endif // BASE_PYTHONTYPEEXT_H
|
||||
#endif // BASE_PYTHONTYPEEXT_H
|
||||
|
||||
@@ -26,10 +26,12 @@
|
||||
#include "QtTools.h"
|
||||
|
||||
|
||||
#if QT_VERSION < QT_VERSION_CHECK(5,14,0)
|
||||
namespace Qt {
|
||||
BaseExport QTextStream& endl(QTextStream& stream) {
|
||||
return stream << QLatin1Char('\n') << flush;
|
||||
}
|
||||
#if QT_VERSION < QT_VERSION_CHECK(5, 14, 0)
|
||||
namespace Qt
|
||||
{
|
||||
BaseExport QTextStream& endl(QTextStream& stream)
|
||||
{
|
||||
return stream << QLatin1Char('\n') << flush;
|
||||
}
|
||||
} // namespace Qt
|
||||
#endif
|
||||
|
||||
@@ -30,26 +30,26 @@
|
||||
|
||||
// Suppress warning about 'SkipEmptyParts' not being used
|
||||
#if defined(__clang__)
|
||||
# pragma clang diagnostic push
|
||||
# pragma clang diagnostic ignored "-Wunused-variable"
|
||||
#elif defined (__GNUC__)
|
||||
# pragma GCC diagnostic push
|
||||
# pragma GCC diagnostic ignored "-Wunused-variable"
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wunused-variable"
|
||||
#elif defined(__GNUC__)
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wunused-variable"
|
||||
#endif
|
||||
|
||||
#if QT_VERSION < QT_VERSION_CHECK(5, 14, 0)
|
||||
#include <QTextStream>
|
||||
namespace Qt
|
||||
{
|
||||
BaseExport QTextStream& endl(QTextStream& stream);
|
||||
static auto SkipEmptyParts = QString::SkipEmptyParts;
|
||||
}
|
||||
BaseExport QTextStream& endl(QTextStream& stream);
|
||||
static auto SkipEmptyParts = QString::SkipEmptyParts;
|
||||
} // namespace Qt
|
||||
#endif
|
||||
|
||||
#if defined(__clang__)
|
||||
# pragma clang diagnostic pop
|
||||
#elif defined (__GNUC__)
|
||||
# pragma GCC diagnostic pop
|
||||
#pragma clang diagnostic pop
|
||||
#elif defined(__GNUC__)
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
||||
#endif // BASE_QTTOOLS_H
|
||||
#endif // BASE_QTTOOLS_H
|
||||
|
||||
@@ -22,10 +22,10 @@
|
||||
|
||||
#include "PreCompiled.h"
|
||||
#ifndef _PreComp_
|
||||
# ifdef FC_OS_WIN32
|
||||
# define _USE_MATH_DEFINES
|
||||
# endif // FC_OS_WIN32
|
||||
# include <array>
|
||||
#ifdef FC_OS_WIN32
|
||||
#define _USE_MATH_DEFINES
|
||||
#endif // FC_OS_WIN32
|
||||
#include <array>
|
||||
#endif
|
||||
|
||||
#include "Quantity.h"
|
||||
@@ -35,56 +35,53 @@
|
||||
|
||||
/** \defgroup Units Units system
|
||||
\ingroup BASE
|
||||
\brief The quantities and units system enables FreeCAD to work transparently with many different units
|
||||
\brief The quantities and units system enables FreeCAD to work transparently with many different
|
||||
units
|
||||
*/
|
||||
|
||||
// suppress annoying warnings from generated source files
|
||||
#ifdef _MSC_VER
|
||||
# pragma warning(disable : 4003)
|
||||
# pragma warning(disable : 4018)
|
||||
# pragma warning(disable : 4065)
|
||||
# pragma warning( disable : 4273 )
|
||||
# pragma warning(disable : 4335) // disable MAC file format warning on VC
|
||||
#pragma warning(disable : 4003)
|
||||
#pragma warning(disable : 4018)
|
||||
#pragma warning(disable : 4065)
|
||||
#pragma warning(disable : 4273)
|
||||
#pragma warning(disable : 4335) // disable MAC file format warning on VC
|
||||
#endif
|
||||
|
||||
using namespace Base;
|
||||
|
||||
// ====== Static attributes =========================
|
||||
// NOLINTNEXTLINE
|
||||
int QuantityFormat::defaultDenominator = 8; // for 1/8"
|
||||
int QuantityFormat::defaultDenominator = 8; // for 1/8"
|
||||
|
||||
|
||||
QuantityFormat::QuantityFormat()
|
||||
: option(OmitGroupSeparator | RejectGroupSeparator)
|
||||
, format(Fixed)
|
||||
, precision(UnitsApi::getDecimals())
|
||||
, denominator(defaultDenominator)
|
||||
{
|
||||
}
|
||||
: option(OmitGroupSeparator | RejectGroupSeparator)
|
||||
, format(Fixed)
|
||||
, precision(UnitsApi::getDecimals())
|
||||
, denominator(defaultDenominator)
|
||||
{}
|
||||
|
||||
QuantityFormat::QuantityFormat(QuantityFormat::NumberFormat format, int decimals)
|
||||
: option(OmitGroupSeparator | RejectGroupSeparator)
|
||||
, format(format)
|
||||
, precision(decimals < 0 ? UnitsApi::getDecimals() : decimals)
|
||||
, denominator(defaultDenominator)
|
||||
{
|
||||
}
|
||||
: option(OmitGroupSeparator | RejectGroupSeparator)
|
||||
, format(format)
|
||||
, precision(decimals < 0 ? UnitsApi::getDecimals() : decimals)
|
||||
, denominator(defaultDenominator)
|
||||
{}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
Quantity::Quantity()
|
||||
: myValue{0.0}
|
||||
{
|
||||
}
|
||||
: myValue {0.0}
|
||||
{}
|
||||
|
||||
Quantity::Quantity(double value, const Unit& unit)
|
||||
: myValue{value}
|
||||
, myUnit{unit}
|
||||
{
|
||||
}
|
||||
: myValue {value}
|
||||
, myUnit {unit}
|
||||
{}
|
||||
|
||||
Quantity::Quantity(double value, const QString& unit)
|
||||
: myValue{0.0}
|
||||
: myValue {0.0}
|
||||
{
|
||||
if (unit.isEmpty()) {
|
||||
this->myValue = value;
|
||||
@@ -103,73 +100,77 @@ Quantity::Quantity(double value, const QString& unit)
|
||||
}
|
||||
}
|
||||
|
||||
double Quantity::getValueAs(const Quantity& other)const
|
||||
double Quantity::getValueAs(const Quantity& other) const
|
||||
{
|
||||
return myValue / other.getValue();
|
||||
}
|
||||
|
||||
bool Quantity::operator ==(const Quantity& that) const
|
||||
bool Quantity::operator==(const Quantity& that) const
|
||||
{
|
||||
return (this->myValue == that.myValue) && (this->myUnit == that.myUnit);
|
||||
}
|
||||
|
||||
bool Quantity::operator !=(const Quantity& that) const
|
||||
bool Quantity::operator!=(const Quantity& that) const
|
||||
{
|
||||
return !(*this == that);
|
||||
}
|
||||
|
||||
bool Quantity::operator <(const Quantity& that) const
|
||||
bool Quantity::operator<(const Quantity& that) const
|
||||
{
|
||||
if (this->myUnit != that.myUnit) {
|
||||
throw Base::UnitsMismatchError("Quantity::operator <(): quantities need to have same unit to compare");
|
||||
throw Base::UnitsMismatchError(
|
||||
"Quantity::operator <(): quantities need to have same unit to compare");
|
||||
}
|
||||
|
||||
return (this->myValue < that.myValue) ;
|
||||
return (this->myValue < that.myValue);
|
||||
}
|
||||
|
||||
bool Quantity::operator >(const Quantity& that) const
|
||||
bool Quantity::operator>(const Quantity& that) const
|
||||
{
|
||||
if (this->myUnit != that.myUnit) {
|
||||
throw Base::UnitsMismatchError("Quantity::operator >(): quantities need to have same unit to compare");
|
||||
throw Base::UnitsMismatchError(
|
||||
"Quantity::operator >(): quantities need to have same unit to compare");
|
||||
}
|
||||
|
||||
return (this->myValue > that.myValue) ;
|
||||
return (this->myValue > that.myValue);
|
||||
}
|
||||
|
||||
bool Quantity::operator <=(const Quantity& that) const
|
||||
bool Quantity::operator<=(const Quantity& that) const
|
||||
{
|
||||
if (this->myUnit != that.myUnit) {
|
||||
throw Base::UnitsMismatchError("Quantity::operator <=(): quantities need to have same unit to compare");
|
||||
throw Base::UnitsMismatchError(
|
||||
"Quantity::operator <=(): quantities need to have same unit to compare");
|
||||
}
|
||||
|
||||
return (this->myValue <= that.myValue) ;
|
||||
return (this->myValue <= that.myValue);
|
||||
}
|
||||
|
||||
bool Quantity::operator >=(const Quantity& that) const
|
||||
bool Quantity::operator>=(const Quantity& that) const
|
||||
{
|
||||
if (this->myUnit != that.myUnit) {
|
||||
throw Base::UnitsMismatchError("Quantity::operator >=(): quantities need to have same unit to compare");
|
||||
throw Base::UnitsMismatchError(
|
||||
"Quantity::operator >=(): quantities need to have same unit to compare");
|
||||
}
|
||||
|
||||
return (this->myValue >= that.myValue) ;
|
||||
return (this->myValue >= that.myValue);
|
||||
}
|
||||
|
||||
Quantity Quantity::operator *(const Quantity& other) const
|
||||
Quantity Quantity::operator*(const Quantity& other) const
|
||||
{
|
||||
return Quantity(this->myValue * other.myValue, this->myUnit * other.myUnit);
|
||||
}
|
||||
|
||||
Quantity Quantity::operator *(double factor) const
|
||||
Quantity Quantity::operator*(double factor) const
|
||||
{
|
||||
return Quantity(this->myValue * factor, this->myUnit);
|
||||
}
|
||||
|
||||
Quantity Quantity::operator /(const Quantity& other) const
|
||||
Quantity Quantity::operator/(const Quantity& other) const
|
||||
{
|
||||
return Quantity(this->myValue / other.myValue, this->myUnit / other.myUnit);
|
||||
}
|
||||
|
||||
Quantity Quantity::operator /(double factor) const
|
||||
Quantity Quantity::operator/(double factor) const
|
||||
{
|
||||
return Quantity(this->myValue / factor, this->myUnit);
|
||||
}
|
||||
@@ -180,21 +181,16 @@ Quantity Quantity::pow(const Quantity& other) const
|
||||
throw Base::UnitsMismatchError("Quantity::pow(): exponent must not have a unit");
|
||||
}
|
||||
|
||||
return Quantity(
|
||||
std::pow(this->myValue, other.myValue),
|
||||
this->myUnit.pow(static_cast<signed char>(other.myValue))
|
||||
);
|
||||
return Quantity(std::pow(this->myValue, other.myValue),
|
||||
this->myUnit.pow(static_cast<signed char>(other.myValue)));
|
||||
}
|
||||
|
||||
Quantity Quantity::pow(double exp) const
|
||||
{
|
||||
return Quantity(
|
||||
std::pow(this->myValue, exp),
|
||||
this->myUnit.pow(exp)
|
||||
);
|
||||
return Quantity(std::pow(this->myValue, exp), this->myUnit.pow(exp));
|
||||
}
|
||||
|
||||
Quantity Quantity::operator +(const Quantity& other) const
|
||||
Quantity Quantity::operator+(const Quantity& other) const
|
||||
{
|
||||
if (this->myUnit != other.myUnit) {
|
||||
throw Base::UnitsMismatchError("Quantity::operator +(): Unit mismatch in plus operation");
|
||||
@@ -203,7 +199,7 @@ Quantity Quantity::operator +(const Quantity& other) const
|
||||
return Quantity(this->myValue + other.myValue, this->myUnit);
|
||||
}
|
||||
|
||||
Quantity& Quantity::operator +=(const Quantity& other)
|
||||
Quantity& Quantity::operator+=(const Quantity& other)
|
||||
{
|
||||
if (this->myUnit != other.myUnit) {
|
||||
throw Base::UnitsMismatchError("Quantity::operator +=(): Unit mismatch in plus operation");
|
||||
@@ -214,16 +210,16 @@ Quantity& Quantity::operator +=(const Quantity& other)
|
||||
return *this;
|
||||
}
|
||||
|
||||
Quantity Quantity::operator -(const Quantity& other) const
|
||||
Quantity Quantity::operator-(const Quantity& other) const
|
||||
{
|
||||
if (this->myUnit != other.myUnit) {
|
||||
throw Base::UnitsMismatchError("Quantity::operator -(): Unit mismatch in minus operation");
|
||||
}
|
||||
|
||||
return Quantity(this->myValue - other.myValue,this->myUnit);
|
||||
return Quantity(this->myValue - other.myValue, this->myUnit);
|
||||
}
|
||||
|
||||
Quantity& Quantity::operator -=(const Quantity& other)
|
||||
Quantity& Quantity::operator-=(const Quantity& other)
|
||||
{
|
||||
if (this->myUnit != other.myUnit) {
|
||||
throw Base::UnitsMismatchError("Quantity::operator -=(): Unit mismatch in minus operation");
|
||||
@@ -234,7 +230,7 @@ Quantity& Quantity::operator -=(const Quantity& other)
|
||||
return *this;
|
||||
}
|
||||
|
||||
Quantity Quantity::operator -() const
|
||||
Quantity Quantity::operator-() const
|
||||
{
|
||||
return Quantity(-(this->myValue), this->myUnit);
|
||||
}
|
||||
@@ -244,7 +240,7 @@ QString Quantity::getUserString(double& factor, QString& unitString) const
|
||||
return Base::UnitsApi::schemaTranslate(*this, factor, unitString);
|
||||
}
|
||||
|
||||
QString Quantity::getUserString(UnitsSchema* schema, double &factor, QString &unitString) const
|
||||
QString Quantity::getUserString(UnitsSchema* schema, double& factor, QString& unitString) const
|
||||
{
|
||||
return schema->schemaTranslate(*this, factor, unitString);
|
||||
}
|
||||
@@ -252,14 +248,11 @@ QString Quantity::getUserString(UnitsSchema* schema, double &factor, QString &un
|
||||
QString Quantity::getSafeUserString() const
|
||||
{
|
||||
auto retString = getUserString();
|
||||
if(Q_LIKELY(this->myValue != 0))
|
||||
{
|
||||
if (Q_LIKELY(this->myValue != 0)) {
|
||||
auto feedbackQty = parse(retString);
|
||||
auto feedbackVal = feedbackQty.getValue();
|
||||
if (feedbackVal == 0) {
|
||||
retString = QStringLiteral("%1 %2")
|
||||
.arg(this->myValue)
|
||||
.arg(this->getUnit().getString());
|
||||
retString = QStringLiteral("%1 %2").arg(this->myValue).arg(this->getUnit().getString());
|
||||
}
|
||||
}
|
||||
return retString;
|
||||
@@ -296,154 +289,160 @@ void Quantity::setInvalid()
|
||||
|
||||
// === Predefined types =====================================================
|
||||
|
||||
const Quantity Quantity::NanoMetre (1.0e-6 ,Unit(1));
|
||||
const Quantity Quantity::MicroMetre (1.0e-3 ,Unit(1));
|
||||
const Quantity Quantity::MilliMetre (1.0 ,Unit(1));
|
||||
const Quantity Quantity::CentiMetre (10.0 ,Unit(1));
|
||||
const Quantity Quantity::DeciMetre (100.0 ,Unit(1));
|
||||
const Quantity Quantity::Metre (1.0e3 ,Unit(1));
|
||||
const Quantity Quantity::KiloMetre (1.0e6 ,Unit(1));
|
||||
const Quantity Quantity::NanoMetre(1.0e-6, Unit(1));
|
||||
const Quantity Quantity::MicroMetre(1.0e-3, Unit(1));
|
||||
const Quantity Quantity::MilliMetre(1.0, Unit(1));
|
||||
const Quantity Quantity::CentiMetre(10.0, Unit(1));
|
||||
const Quantity Quantity::DeciMetre(100.0, Unit(1));
|
||||
const Quantity Quantity::Metre(1.0e3, Unit(1));
|
||||
const Quantity Quantity::KiloMetre(1.0e6, Unit(1));
|
||||
|
||||
const Quantity Quantity::MilliLiter (1000.0 ,Unit(3));
|
||||
const Quantity Quantity::Liter (1.0e6 ,Unit(3));
|
||||
const Quantity Quantity::MilliLiter(1000.0, Unit(3));
|
||||
const Quantity Quantity::Liter(1.0e6, Unit(3));
|
||||
|
||||
const Quantity Quantity::Hertz (1.0 ,Unit(0,0,-1));
|
||||
const Quantity Quantity::KiloHertz (1.0e3 ,Unit(0,0,-1));
|
||||
const Quantity Quantity::MegaHertz (1.0e6 ,Unit(0,0,-1));
|
||||
const Quantity Quantity::GigaHertz (1.0e9 ,Unit(0,0,-1));
|
||||
const Quantity Quantity::TeraHertz (1.0e12 ,Unit(0,0,-1));
|
||||
const Quantity Quantity::Hertz(1.0, Unit(0, 0, -1));
|
||||
const Quantity Quantity::KiloHertz(1.0e3, Unit(0, 0, -1));
|
||||
const Quantity Quantity::MegaHertz(1.0e6, Unit(0, 0, -1));
|
||||
const Quantity Quantity::GigaHertz(1.0e9, Unit(0, 0, -1));
|
||||
const Quantity Quantity::TeraHertz(1.0e12, Unit(0, 0, -1));
|
||||
|
||||
const Quantity Quantity::MicroGram (1.0e-9 ,Unit(0,1));
|
||||
const Quantity Quantity::MilliGram (1.0e-6 ,Unit(0,1));
|
||||
const Quantity Quantity::Gram (1.0e-3 ,Unit(0,1));
|
||||
const Quantity Quantity::KiloGram (1.0 ,Unit(0,1));
|
||||
const Quantity Quantity::Ton (1.0e3 ,Unit(0,1));
|
||||
const Quantity Quantity::MicroGram(1.0e-9, Unit(0, 1));
|
||||
const Quantity Quantity::MilliGram(1.0e-6, Unit(0, 1));
|
||||
const Quantity Quantity::Gram(1.0e-3, Unit(0, 1));
|
||||
const Quantity Quantity::KiloGram(1.0, Unit(0, 1));
|
||||
const Quantity Quantity::Ton(1.0e3, Unit(0, 1));
|
||||
|
||||
const Quantity Quantity::Second (1.0 ,Unit(0,0,1));
|
||||
const Quantity Quantity::Minute (60.0 ,Unit(0,0,1));
|
||||
const Quantity Quantity::Hour (3600.0 ,Unit(0,0,1));
|
||||
const Quantity Quantity::Second(1.0, Unit(0, 0, 1));
|
||||
const Quantity Quantity::Minute(60.0, Unit(0, 0, 1));
|
||||
const Quantity Quantity::Hour(3600.0, Unit(0, 0, 1));
|
||||
|
||||
const Quantity Quantity::Ampere (1.0 ,Unit(0,0,0,1));
|
||||
const Quantity Quantity::MilliAmpere (0.001 ,Unit(0,0,0,1));
|
||||
const Quantity Quantity::KiloAmpere (1000.0 ,Unit(0,0,0,1));
|
||||
const Quantity Quantity::MegaAmpere (1.0e6 ,Unit(0,0,0,1));
|
||||
const Quantity Quantity::Ampere(1.0, Unit(0, 0, 0, 1));
|
||||
const Quantity Quantity::MilliAmpere(0.001, Unit(0, 0, 0, 1));
|
||||
const Quantity Quantity::KiloAmpere(1000.0, Unit(0, 0, 0, 1));
|
||||
const Quantity Quantity::MegaAmpere(1.0e6, Unit(0, 0, 0, 1));
|
||||
|
||||
const Quantity Quantity::Kelvin (1.0 ,Unit(0,0,0,0,1));
|
||||
const Quantity Quantity::MilliKelvin (0.001 ,Unit(0,0,0,0,1));
|
||||
const Quantity Quantity::MicroKelvin (0.000001 ,Unit(0,0,0,0,1));
|
||||
const Quantity Quantity::Kelvin(1.0, Unit(0, 0, 0, 0, 1));
|
||||
const Quantity Quantity::MilliKelvin(0.001, Unit(0, 0, 0, 0, 1));
|
||||
const Quantity Quantity::MicroKelvin(0.000001, Unit(0, 0, 0, 0, 1));
|
||||
|
||||
const Quantity Quantity::MilliMole (0.001 ,Unit(0,0,0,0,0,1));
|
||||
const Quantity Quantity::Mole (1.0 ,Unit(0,0,0,0,0,1));
|
||||
const Quantity Quantity::MilliMole(0.001, Unit(0, 0, 0, 0, 0, 1));
|
||||
const Quantity Quantity::Mole(1.0, Unit(0, 0, 0, 0, 0, 1));
|
||||
|
||||
const Quantity Quantity::Candela (1.0 ,Unit(0,0,0,0,0,0,1));
|
||||
const Quantity Quantity::Candela(1.0, Unit(0, 0, 0, 0, 0, 0, 1));
|
||||
|
||||
const Quantity Quantity::Inch (25.4 ,Unit(1));
|
||||
const Quantity Quantity::Foot (304.8 ,Unit(1));
|
||||
const Quantity Quantity::Thou (0.0254 ,Unit(1));
|
||||
const Quantity Quantity::Yard (914.4 ,Unit(1));
|
||||
const Quantity Quantity::Mile (1609344.0 ,Unit(1));
|
||||
const Quantity Quantity::Inch(25.4, Unit(1));
|
||||
const Quantity Quantity::Foot(304.8, Unit(1));
|
||||
const Quantity Quantity::Thou(0.0254, Unit(1));
|
||||
const Quantity Quantity::Yard(914.4, Unit(1));
|
||||
const Quantity Quantity::Mile(1609344.0, Unit(1));
|
||||
|
||||
const Quantity Quantity::MilePerHour (447.04 ,Unit(1,0,-1));
|
||||
const Quantity Quantity::SquareFoot (92903.04 ,Unit(2));
|
||||
const Quantity Quantity::CubicFoot (28316846.592 ,Unit(3));
|
||||
const Quantity Quantity::MilePerHour(447.04, Unit(1, 0, -1));
|
||||
const Quantity Quantity::SquareFoot(92903.04, Unit(2));
|
||||
const Quantity Quantity::CubicFoot(28316846.592, Unit(3));
|
||||
|
||||
const Quantity Quantity::Pound (0.45359237 ,Unit(0,1));
|
||||
const Quantity Quantity::Ounce (0.0283495231 ,Unit(0,1));
|
||||
const Quantity Quantity::Stone (6.35029318 ,Unit(0,1));
|
||||
const Quantity Quantity::Hundredweights (50.80234544 ,Unit(0,1));
|
||||
const Quantity Quantity::Pound(0.45359237, Unit(0, 1));
|
||||
const Quantity Quantity::Ounce(0.0283495231, Unit(0, 1));
|
||||
const Quantity Quantity::Stone(6.35029318, Unit(0, 1));
|
||||
const Quantity Quantity::Hundredweights(50.80234544, Unit(0, 1));
|
||||
|
||||
const Quantity Quantity::PoundForce (4448.22 ,Unit(1,1,-2)); // lbf are ~= 4.44822 Newton
|
||||
const Quantity Quantity::PoundForce(4448.22, Unit(1, 1, -2)); // lbf are ~= 4.44822 Newton
|
||||
|
||||
const Quantity Quantity::Newton (1000.0 ,Unit(1,1,-2)); // Newton (kg*m/s^2)
|
||||
const Quantity Quantity::MilliNewton (1.0 ,Unit(1,1,-2));
|
||||
const Quantity Quantity::KiloNewton (1e+6 ,Unit(1,1,-2));
|
||||
const Quantity Quantity::MegaNewton (1e+9 ,Unit(1,1,-2));
|
||||
const Quantity Quantity::Newton(1000.0, Unit(1, 1, -2)); // Newton (kg*m/s^2)
|
||||
const Quantity Quantity::MilliNewton(1.0, Unit(1, 1, -2));
|
||||
const Quantity Quantity::KiloNewton(1e+6, Unit(1, 1, -2));
|
||||
const Quantity Quantity::MegaNewton(1e+9, Unit(1, 1, -2));
|
||||
|
||||
const Quantity Quantity::NewtonPerMeter (1.00 ,Unit(0,1,-2)); //Newton per meter (N/m or kg/s^2)
|
||||
const Quantity Quantity::MilliNewtonPerMeter (1e-3 ,Unit(0,1,-2));
|
||||
const Quantity Quantity::KiloNewtonPerMeter (1e3 ,Unit(0,1,-2));
|
||||
const Quantity Quantity::MegaNewtonPerMeter (1e6 ,Unit(0,1,-2));
|
||||
const Quantity Quantity::NewtonPerMeter(1.00, Unit(0, 1, -2)); // Newton per meter (N/m or kg/s^2)
|
||||
const Quantity Quantity::MilliNewtonPerMeter(1e-3, Unit(0, 1, -2));
|
||||
const Quantity Quantity::KiloNewtonPerMeter(1e3, Unit(0, 1, -2));
|
||||
const Quantity Quantity::MegaNewtonPerMeter(1e6, Unit(0, 1, -2));
|
||||
|
||||
const Quantity Quantity::Pascal (0.001 ,Unit(-1,1,-2)); // Pascal (kg/m/s^2 or N/m^2)
|
||||
const Quantity Quantity::KiloPascal (1.00 ,Unit(-1,1,-2));
|
||||
const Quantity Quantity::MegaPascal (1000.0 ,Unit(-1,1,-2));
|
||||
const Quantity Quantity::GigaPascal (1e+6 ,Unit(-1,1,-2));
|
||||
const Quantity Quantity::Pascal(0.001, Unit(-1, 1, -2)); // Pascal (kg/m/s^2 or N/m^2)
|
||||
const Quantity Quantity::KiloPascal(1.00, Unit(-1, 1, -2));
|
||||
const Quantity Quantity::MegaPascal(1000.0, Unit(-1, 1, -2));
|
||||
const Quantity Quantity::GigaPascal(1e+6, Unit(-1, 1, -2));
|
||||
|
||||
const Quantity Quantity::MilliBar (0.1 ,Unit(-1,1,-2));
|
||||
const Quantity Quantity::Bar (100.0 ,Unit(-1,1,-2)); // 1 bar = 100 kPa
|
||||
const Quantity Quantity::MilliBar(0.1, Unit(-1, 1, -2));
|
||||
const Quantity Quantity::Bar(100.0, Unit(-1, 1, -2)); // 1 bar = 100 kPa
|
||||
|
||||
const Quantity Quantity::Torr (101.325/760.0 ,Unit(-1,1,-2)); // Torr is a defined fraction of Pascal (kg/m/s^2 or N/m^2)
|
||||
const Quantity Quantity::mTorr (0.101325/760.0,Unit(-1,1,-2)); // Torr is a defined fraction of Pascal (kg/m/s^2 or N/m^2)
|
||||
const Quantity Quantity::yTorr (0.000101325/760.0 ,Unit(-1,1,-2)); // Torr is a defined fraction of Pascal (kg/m/s^2 or N/m^2)
|
||||
const Quantity
|
||||
Quantity::Torr(101.325 / 760.0,
|
||||
Unit(-1, 1, -2)); // Torr is a defined fraction of Pascal (kg/m/s^2 or N/m^2)
|
||||
const Quantity
|
||||
Quantity::mTorr(0.101325 / 760.0,
|
||||
Unit(-1, 1, -2)); // Torr is a defined fraction of Pascal (kg/m/s^2 or N/m^2)
|
||||
const Quantity
|
||||
Quantity::yTorr(0.000101325 / 760.0,
|
||||
Unit(-1, 1, -2)); // Torr is a defined fraction of Pascal (kg/m/s^2 or N/m^2)
|
||||
|
||||
const Quantity Quantity::PSI (6.894744825494,Unit(-1,1,-2)); // pounds/in^2
|
||||
const Quantity Quantity::KSI (6894.744825494,Unit(-1,1,-2)); // 1000 x pounds/in^2
|
||||
const Quantity Quantity::MPSI (6894744.825494,Unit(-1,1,-2)); // 1000 ksi
|
||||
const Quantity Quantity::PSI(6.894744825494, Unit(-1, 1, -2)); // pounds/in^2
|
||||
const Quantity Quantity::KSI(6894.744825494, Unit(-1, 1, -2)); // 1000 x pounds/in^2
|
||||
const Quantity Quantity::MPSI(6894744.825494, Unit(-1, 1, -2)); // 1000 ksi
|
||||
|
||||
const Quantity Quantity::Watt (1e+6 ,Unit(2,1,-3)); // Watt (kg*m^2/s^3)
|
||||
const Quantity Quantity::MilliWatt (1e+3 ,Unit(2,1,-3));
|
||||
const Quantity Quantity::KiloWatt (1e+9 ,Unit(2,1,-3));
|
||||
const Quantity Quantity::VoltAmpere (1e+6 ,Unit(2,1,-3)); // VoltAmpere (kg*m^2/s^3)
|
||||
const Quantity Quantity::Watt(1e+6, Unit(2, 1, -3)); // Watt (kg*m^2/s^3)
|
||||
const Quantity Quantity::MilliWatt(1e+3, Unit(2, 1, -3));
|
||||
const Quantity Quantity::KiloWatt(1e+9, Unit(2, 1, -3));
|
||||
const Quantity Quantity::VoltAmpere(1e+6, Unit(2, 1, -3)); // VoltAmpere (kg*m^2/s^3)
|
||||
|
||||
const Quantity Quantity::Volt (1e+6 ,Unit(2,1,-3,-1)); // Volt (kg*m^2/A/s^3)
|
||||
const Quantity Quantity::MilliVolt (1e+3 ,Unit(2,1,-3,-1));
|
||||
const Quantity Quantity::KiloVolt (1e+9 ,Unit(2,1,-3,-1));
|
||||
const Quantity Quantity::Volt(1e+6, Unit(2, 1, -3, -1)); // Volt (kg*m^2/A/s^3)
|
||||
const Quantity Quantity::MilliVolt(1e+3, Unit(2, 1, -3, -1));
|
||||
const Quantity Quantity::KiloVolt(1e+9, Unit(2, 1, -3, -1));
|
||||
|
||||
const Quantity Quantity::MegaSiemens (1.0 ,Unit(-2,-1,3,2));
|
||||
const Quantity Quantity::KiloSiemens (1e-3 ,Unit(-2,-1,3,2));
|
||||
const Quantity Quantity::Siemens (1e-6 ,Unit(-2,-1,3,2)); // Siemens (A^2*s^3/kg/m^2)
|
||||
const Quantity Quantity::MilliSiemens (1e-9 ,Unit(-2,-1,3,2));
|
||||
const Quantity Quantity::MicroSiemens (1e-12 ,Unit(-2,-1,3,2));
|
||||
const Quantity Quantity::MegaSiemens(1.0, Unit(-2, -1, 3, 2));
|
||||
const Quantity Quantity::KiloSiemens(1e-3, Unit(-2, -1, 3, 2));
|
||||
const Quantity Quantity::Siemens(1e-6, Unit(-2, -1, 3, 2)); // Siemens (A^2*s^3/kg/m^2)
|
||||
const Quantity Quantity::MilliSiemens(1e-9, Unit(-2, -1, 3, 2));
|
||||
const Quantity Quantity::MicroSiemens(1e-12, Unit(-2, -1, 3, 2));
|
||||
|
||||
const Quantity Quantity::Ohm (1e+6 ,Unit(2,1,-3,-2)); // Ohm (kg*m^2/A^2/s^3)
|
||||
const Quantity Quantity::KiloOhm (1e+9 ,Unit(2,1,-3,-2));
|
||||
const Quantity Quantity::MegaOhm (1e+12 ,Unit(2,1,-3,-2));
|
||||
const Quantity Quantity::Ohm(1e+6, Unit(2, 1, -3, -2)); // Ohm (kg*m^2/A^2/s^3)
|
||||
const Quantity Quantity::KiloOhm(1e+9, Unit(2, 1, -3, -2));
|
||||
const Quantity Quantity::MegaOhm(1e+12, Unit(2, 1, -3, -2));
|
||||
|
||||
const Quantity Quantity::Coulomb (1.0 ,Unit(0,0,1,1)); // Coulomb (A*s)
|
||||
const Quantity Quantity::Coulomb(1.0, Unit(0, 0, 1, 1)); // Coulomb (A*s)
|
||||
|
||||
const Quantity Quantity::Tesla (1.0 ,Unit(0,1,-2,-1)); // Tesla (kg/s^2/A)
|
||||
const Quantity Quantity::Gauss (1e-4 ,Unit(0,1,-2,-1)); // 1 G = 1e-4 T
|
||||
const Quantity Quantity::Tesla(1.0, Unit(0, 1, -2, -1)); // Tesla (kg/s^2/A)
|
||||
const Quantity Quantity::Gauss(1e-4, Unit(0, 1, -2, -1)); // 1 G = 1e-4 T
|
||||
|
||||
const Quantity Quantity::Weber (1e6 ,Unit(2,1,-2,-1)); // Weber (kg*m^2/s^2/A)
|
||||
const Quantity Quantity::Weber(1e6, Unit(2, 1, -2, -1)); // Weber (kg*m^2/s^2/A)
|
||||
|
||||
// disable Oersted because people need to input e.g. a field strength of
|
||||
// 1 ampere per meter -> 1 A/m and not get the recalculation to Oersted
|
||||
//const Quantity Quantity::Oersted(0.07957747, Unit(-1, 0, 0, 1));// Oersted (A/m)
|
||||
// const Quantity Quantity::Oersted(0.07957747, Unit(-1, 0, 0, 1));// Oersted (A/m)
|
||||
|
||||
const Quantity Quantity::PicoFarad (1e-18 ,Unit(-2,-1,4,2));
|
||||
const Quantity Quantity::NanoFarad (1e-15 ,Unit(-2,-1,4,2));
|
||||
const Quantity Quantity::MicroFarad (1e-12 ,Unit(-2,-1,4,2));
|
||||
const Quantity Quantity::MilliFarad (1e-9 ,Unit(-2,-1,4,2));
|
||||
const Quantity Quantity::Farad (1e-6 ,Unit(-2,-1,4,2)); // Farad (s^4*A^2/m^2/kg)
|
||||
const Quantity Quantity::PicoFarad(1e-18, Unit(-2, -1, 4, 2));
|
||||
const Quantity Quantity::NanoFarad(1e-15, Unit(-2, -1, 4, 2));
|
||||
const Quantity Quantity::MicroFarad(1e-12, Unit(-2, -1, 4, 2));
|
||||
const Quantity Quantity::MilliFarad(1e-9, Unit(-2, -1, 4, 2));
|
||||
const Quantity Quantity::Farad(1e-6, Unit(-2, -1, 4, 2)); // Farad (s^4*A^2/m^2/kg)
|
||||
|
||||
const Quantity Quantity::NanoHenry (1e-3 ,Unit(2,1,-2,-2));
|
||||
const Quantity Quantity::MicroHenry (1.0 ,Unit(2,1,-2,-2));
|
||||
const Quantity Quantity::MilliHenry (1e+3 ,Unit(2,1,-2,-2));
|
||||
const Quantity Quantity::Henry (1e+6 ,Unit(2,1,-2,-2)); // Henry (kg*m^2/s^2/A^2)
|
||||
const Quantity Quantity::NanoHenry(1e-3, Unit(2, 1, -2, -2));
|
||||
const Quantity Quantity::MicroHenry(1.0, Unit(2, 1, -2, -2));
|
||||
const Quantity Quantity::MilliHenry(1e+3, Unit(2, 1, -2, -2));
|
||||
const Quantity Quantity::Henry(1e+6, Unit(2, 1, -2, -2)); // Henry (kg*m^2/s^2/A^2)
|
||||
|
||||
const Quantity Quantity::Joule (1e+6 ,Unit(2,1,-2)); // Joule (kg*m^2/s^2)
|
||||
const Quantity Quantity::MilliJoule (1e+3 ,Unit(2,1,-2));
|
||||
const Quantity Quantity::KiloJoule (1e+9 ,Unit(2,1,-2));
|
||||
const Quantity Quantity::NewtonMeter (1e+6 ,Unit(2,1,-2)); // Joule (kg*m^2/s^2)
|
||||
const Quantity Quantity::VoltAmpereSecond (1e+6 ,Unit(2,1,-2)); // Joule (kg*m^2/s^2)
|
||||
const Quantity Quantity::WattSecond (1e+6 ,Unit(2,1,-2)); // Joule (kg*m^2/s^2)
|
||||
const Quantity Quantity::KiloWattHour (3.6e+12 ,Unit(2,1,-2)); // 1 kWh = 3.6e6 J
|
||||
const Quantity Quantity::ElectronVolt (1.602176634e-13 ,Unit(2,1,-2)); // 1 eV = 1.602176634e-19 J
|
||||
const Quantity Quantity::KiloElectronVolt (1.602176634e-10 ,Unit(2,1,-2));
|
||||
const Quantity Quantity::MegaElectronVolt (1.602176634e-7 ,Unit(2,1,-2));
|
||||
const Quantity Quantity::Calorie (4.1868e+6 ,Unit(2,1,-2)); // 1 cal = 4.1868 J
|
||||
const Quantity Quantity::KiloCalorie (4.1868e+9 ,Unit(2,1,-2));
|
||||
|
||||
const Quantity Quantity::KMH (277.778 ,Unit(1,0,-1)); // km/h
|
||||
const Quantity Quantity::MPH (447.04 ,Unit(1,0,-1)); // Mile/h
|
||||
|
||||
const Quantity Quantity::AngMinute (1.0/60.0 ,Unit(0,0,0,0,0,0,0,1)); // angular minute
|
||||
const Quantity Quantity::AngSecond (1.0/3600.0 ,Unit(0,0,0,0,0,0,0,1)); // angular second
|
||||
const Quantity Quantity::Degree (1.0 ,Unit(0,0,0,0,0,0,0,1)); // degree (internal standard angle)
|
||||
const Quantity Quantity::Radian (180/M_PI ,Unit(0,0,0,0,0,0,0,1)); // radian
|
||||
const Quantity Quantity::Gon (360.0/400.0 ,Unit(0,0,0,0,0,0,0,1)); // gon
|
||||
const Quantity Quantity::Joule(1e+6, Unit(2, 1, -2)); // Joule (kg*m^2/s^2)
|
||||
const Quantity Quantity::MilliJoule(1e+3, Unit(2, 1, -2));
|
||||
const Quantity Quantity::KiloJoule(1e+9, Unit(2, 1, -2));
|
||||
const Quantity Quantity::NewtonMeter(1e+6, Unit(2, 1, -2)); // Joule (kg*m^2/s^2)
|
||||
const Quantity Quantity::VoltAmpereSecond(1e+6, Unit(2, 1, -2)); // Joule (kg*m^2/s^2)
|
||||
const Quantity Quantity::WattSecond(1e+6, Unit(2, 1, -2)); // Joule (kg*m^2/s^2)
|
||||
const Quantity Quantity::KiloWattHour(3.6e+12, Unit(2, 1, -2)); // 1 kWh = 3.6e6 J
|
||||
const Quantity Quantity::ElectronVolt(1.602176634e-13, Unit(2, 1, -2)); // 1 eV = 1.602176634e-19 J
|
||||
const Quantity Quantity::KiloElectronVolt(1.602176634e-10, Unit(2, 1, -2));
|
||||
const Quantity Quantity::MegaElectronVolt(1.602176634e-7, Unit(2, 1, -2));
|
||||
const Quantity Quantity::Calorie(4.1868e+6, Unit(2, 1, -2)); // 1 cal = 4.1868 J
|
||||
const Quantity Quantity::KiloCalorie(4.1868e+9, Unit(2, 1, -2));
|
||||
|
||||
const Quantity Quantity::KMH(277.778, Unit(1, 0, -1)); // km/h
|
||||
const Quantity Quantity::MPH(447.04, Unit(1, 0, -1)); // Mile/h
|
||||
|
||||
const Quantity Quantity::AngMinute(1.0 / 60.0, Unit(0, 0, 0, 0, 0, 0, 0, 1)); // angular minute
|
||||
const Quantity Quantity::AngSecond(1.0 / 3600.0, Unit(0, 0, 0, 0, 0, 0, 0, 1)); // angular second
|
||||
const Quantity
|
||||
Quantity::Degree(1.0,
|
||||
Unit(0, 0, 0, 0, 0, 0, 0, 1)); // degree (internal standard angle)
|
||||
const Quantity Quantity::Radian(180 / M_PI, Unit(0, 0, 0, 0, 0, 0, 0, 1)); // radian
|
||||
const Quantity Quantity::Gon(360.0 / 400.0, Unit(0, 0, 0, 0, 0, 0, 0, 1)); // gon
|
||||
|
||||
|
||||
// === Parser & Scanner stuff ===============================================
|
||||
@@ -457,24 +456,26 @@ Quantity QuantResult;
|
||||
// NOLINTBEGIN
|
||||
double num_change(char* yytext, char dez_delim, char grp_delim)
|
||||
{
|
||||
double ret_val{};
|
||||
double ret_val {};
|
||||
const int num = 40;
|
||||
std::array<char, num> temp{};
|
||||
std::array<char, num> temp {};
|
||||
int iter = 0;
|
||||
for (char* ch = yytext; *ch != '\0'; ch++) {
|
||||
// skip group delimiter
|
||||
if (*ch == grp_delim)
|
||||
if (*ch == grp_delim) {
|
||||
continue;
|
||||
}
|
||||
// check for a dez delimiter other then dot
|
||||
if (*ch == dez_delim && dez_delim != '.') {
|
||||
temp[iter++] = '.';
|
||||
temp[iter++] = '.';
|
||||
}
|
||||
else {
|
||||
temp[iter++] = *ch;
|
||||
}
|
||||
// check buffer overflow
|
||||
if (iter >= num)
|
||||
if (iter >= num) {
|
||||
return 0.0;
|
||||
}
|
||||
}
|
||||
|
||||
temp[iter] = '\0';
|
||||
@@ -485,32 +486,33 @@ double num_change(char* yytext, char dez_delim, char grp_delim)
|
||||
// NOLINTEND
|
||||
|
||||
#if defined(__clang__)
|
||||
# pragma clang diagnostic push
|
||||
# pragma clang diagnostic ignored "-Wmissing-noreturn"
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wmissing-noreturn"
|
||||
#endif
|
||||
|
||||
// error func
|
||||
void Quantity_yyerror(char *errorinfo)
|
||||
void Quantity_yyerror(char* errorinfo)
|
||||
{
|
||||
throw Base::ParserError(errorinfo);
|
||||
}
|
||||
|
||||
#if defined(__clang__)
|
||||
# pragma clang diagnostic pop
|
||||
#pragma clang diagnostic pop
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(__clang__)
|
||||
# pragma clang diagnostic push
|
||||
# pragma clang diagnostic ignored "-Wsign-compare"
|
||||
# pragma clang diagnostic ignored "-Wunneeded-internal-declaration"
|
||||
#elif defined (__GNUC__)
|
||||
# pragma GCC diagnostic push
|
||||
# pragma GCC diagnostic ignored "-Wsign-compare"
|
||||
# pragma GCC diagnostic ignored "-Wfree-nonheap-object"
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wsign-compare"
|
||||
#pragma clang diagnostic ignored "-Wunneeded-internal-declaration"
|
||||
#elif defined(__GNUC__)
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wsign-compare"
|
||||
#pragma GCC diagnostic ignored "-Wfree-nonheap-object"
|
||||
#endif
|
||||
|
||||
namespace QuantityParser {
|
||||
namespace QuantityParser
|
||||
{
|
||||
|
||||
// NOLINTNEXTLINE
|
||||
#define YYINITDEPTH 20
|
||||
@@ -526,25 +528,26 @@ int QuantityLexer();
|
||||
// Scanner, defined in QuantityParser.l
|
||||
// NOLINTNEXTLINE
|
||||
#include "QuantityLexer.c"
|
||||
#endif // DOXYGEN_SHOULD_SKIP_THIS
|
||||
}
|
||||
#endif // DOXYGEN_SHOULD_SKIP_THIS
|
||||
} // namespace QuantityParser
|
||||
|
||||
#if defined(__clang__)
|
||||
# pragma clang diagnostic pop
|
||||
#elif defined (__GNUC__)
|
||||
# pragma GCC diagnostic pop
|
||||
#pragma clang diagnostic pop
|
||||
#elif defined(__GNUC__)
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
||||
Quantity Quantity::parse(const QString &string)
|
||||
Quantity Quantity::parse(const QString& string)
|
||||
{
|
||||
// parse from buffer
|
||||
QuantityParser::YY_BUFFER_STATE my_string_buffer = QuantityParser::yy_scan_string (string.toUtf8().data());
|
||||
QuantityParser::YY_BUFFER_STATE my_string_buffer =
|
||||
QuantityParser::yy_scan_string(string.toUtf8().data());
|
||||
// set the global return variables
|
||||
QuantResult = Quantity(DOUBLE_MIN);
|
||||
// run the parser
|
||||
QuantityParser::yyparse ();
|
||||
QuantityParser::yyparse();
|
||||
// free the scan buffer
|
||||
QuantityParser::yy_delete_buffer (my_string_buffer);
|
||||
QuantityParser::yy_delete_buffer(my_string_buffer);
|
||||
|
||||
return QuantResult;
|
||||
}
|
||||
|
||||
@@ -28,24 +28,28 @@
|
||||
#include <QString>
|
||||
|
||||
// NOLINTBEGIN
|
||||
#ifndef DOUBLE_MAX
|
||||
# define DOUBLE_MAX 1.7976931348623157E+308 /* max decimal value of a "double"*/
|
||||
#ifndef DOUBLE_MAX
|
||||
#define DOUBLE_MAX 1.7976931348623157E+308 /* max decimal value of a "double"*/
|
||||
#endif
|
||||
#ifndef DOUBLE_MIN
|
||||
# define DOUBLE_MIN 2.2250738585072014E-308 /* min decimal value of a "double"*/
|
||||
#ifndef DOUBLE_MIN
|
||||
#define DOUBLE_MIN 2.2250738585072014E-308 /* min decimal value of a "double"*/
|
||||
#endif
|
||||
// NOLINTEND
|
||||
|
||||
namespace Base {
|
||||
namespace Base
|
||||
{
|
||||
class UnitsSchema;
|
||||
|
||||
struct BaseExport QuantityFormat {
|
||||
enum NumberOption {
|
||||
struct BaseExport QuantityFormat
|
||||
{
|
||||
enum NumberOption
|
||||
{
|
||||
None = 0x00,
|
||||
OmitGroupSeparator = 0x01,
|
||||
RejectGroupSeparator = 0x02
|
||||
};
|
||||
enum NumberFormat {
|
||||
enum NumberFormat
|
||||
{
|
||||
Default = 0,
|
||||
Fixed = 1,
|
||||
Scientific = 2
|
||||
@@ -60,51 +64,57 @@ struct BaseExport QuantityFormat {
|
||||
// Default denominator of minimum fractional inch. Only used in certain
|
||||
// schemas.
|
||||
// NOLINTNEXTLINE
|
||||
static int defaultDenominator; // i.e 8 for 1/8"
|
||||
static int defaultDenominator; // i.e 8 for 1/8"
|
||||
|
||||
static inline int getDefaultDenominator() {
|
||||
static inline int getDefaultDenominator()
|
||||
{
|
||||
return defaultDenominator;
|
||||
}
|
||||
|
||||
static inline void setDefaultDenominator(int denom) {
|
||||
static inline void setDefaultDenominator(int denom)
|
||||
{
|
||||
defaultDenominator = denom;
|
||||
}
|
||||
|
||||
inline int getDenominator() const {
|
||||
inline int getDenominator() const
|
||||
{
|
||||
return denominator;
|
||||
}
|
||||
|
||||
inline void setDenominator(int denom) {
|
||||
inline void setDenominator(int denom)
|
||||
{
|
||||
denominator = denom;
|
||||
}
|
||||
QuantityFormat();
|
||||
explicit QuantityFormat(NumberFormat format, int decimals=-1);
|
||||
inline char toFormat() const {
|
||||
explicit QuantityFormat(NumberFormat format, int decimals = -1);
|
||||
inline char toFormat() const
|
||||
{
|
||||
switch (format) {
|
||||
case Fixed:
|
||||
return 'f';
|
||||
case Scientific:
|
||||
return 'e';
|
||||
default:
|
||||
return 'g';
|
||||
case Fixed:
|
||||
return 'f';
|
||||
case Scientific:
|
||||
return 'e';
|
||||
default:
|
||||
return 'g';
|
||||
}
|
||||
}
|
||||
static inline NumberFormat toFormat(char ch, bool* ok = nullptr) {
|
||||
static inline NumberFormat toFormat(char ch, bool* ok = nullptr)
|
||||
{
|
||||
if (ok) {
|
||||
*ok = true;
|
||||
}
|
||||
switch (ch) {
|
||||
case 'f':
|
||||
return Fixed;
|
||||
case 'e':
|
||||
return Scientific;
|
||||
case 'g':
|
||||
return Default;
|
||||
default:
|
||||
if (ok) {
|
||||
*ok = false;
|
||||
}
|
||||
return Default;
|
||||
case 'f':
|
||||
return Fixed;
|
||||
case 'e':
|
||||
return Scientific;
|
||||
case 'g':
|
||||
return Default;
|
||||
default:
|
||||
if (ok) {
|
||||
*ok = false;
|
||||
}
|
||||
return Default;
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -119,74 +129,89 @@ public:
|
||||
Quantity();
|
||||
Quantity(const Quantity&) = default;
|
||||
Quantity(Quantity&&) = default;
|
||||
explicit Quantity(double value, const Unit& unit=Unit());
|
||||
explicit Quantity(double value, const Unit& unit = Unit());
|
||||
explicit Quantity(double value, const QString& unit);
|
||||
/// Destruction
|
||||
~Quantity () = default;
|
||||
~Quantity() = default;
|
||||
|
||||
/** Operators. */
|
||||
//@{
|
||||
Quantity operator *(const Quantity &other) const;
|
||||
Quantity operator *(double factor) const;
|
||||
Quantity operator +(const Quantity &other) const;
|
||||
Quantity& operator +=(const Quantity &other);
|
||||
Quantity operator -(const Quantity &other) const;
|
||||
Quantity& operator -=(const Quantity &other);
|
||||
Quantity operator -() const;
|
||||
Quantity operator /(const Quantity &other) const;
|
||||
Quantity operator /(double factor) const;
|
||||
bool operator ==(const Quantity&) const;
|
||||
bool operator !=(const Quantity&) const;
|
||||
bool operator < (const Quantity&) const;
|
||||
bool operator > (const Quantity&) const;
|
||||
bool operator <= (const Quantity&) const;
|
||||
bool operator >= (const Quantity&) const;
|
||||
Quantity& operator =(const Quantity&) = default;
|
||||
Quantity& operator =(Quantity&&) = default;
|
||||
Quantity pow(const Quantity&)const;
|
||||
Quantity pow(double)const;
|
||||
Quantity operator*(const Quantity& other) const;
|
||||
Quantity operator*(double factor) const;
|
||||
Quantity operator+(const Quantity& other) const;
|
||||
Quantity& operator+=(const Quantity& other);
|
||||
Quantity operator-(const Quantity& other) const;
|
||||
Quantity& operator-=(const Quantity& other);
|
||||
Quantity operator-() const;
|
||||
Quantity operator/(const Quantity& other) const;
|
||||
Quantity operator/(double factor) const;
|
||||
bool operator==(const Quantity&) const;
|
||||
bool operator!=(const Quantity&) const;
|
||||
bool operator<(const Quantity&) const;
|
||||
bool operator>(const Quantity&) const;
|
||||
bool operator<=(const Quantity&) const;
|
||||
bool operator>=(const Quantity&) const;
|
||||
Quantity& operator=(const Quantity&) = default;
|
||||
Quantity& operator=(Quantity&&) = default;
|
||||
Quantity pow(const Quantity&) const;
|
||||
Quantity pow(double) const;
|
||||
//@}
|
||||
|
||||
const QuantityFormat& getFormat() const {
|
||||
const QuantityFormat& getFormat() const
|
||||
{
|
||||
return myFormat;
|
||||
}
|
||||
void setFormat(const QuantityFormat& fmt) {
|
||||
void setFormat(const QuantityFormat& fmt)
|
||||
{
|
||||
myFormat = fmt;
|
||||
}
|
||||
/// transfer to user preferred unit/potence
|
||||
QString getUserString(double &factor, QString &unitString) const;
|
||||
QString getUserString() const { // to satisfy GCC
|
||||
double dummy1{};
|
||||
QString dummy2{};
|
||||
QString getUserString(double& factor, QString& unitString) const;
|
||||
QString getUserString() const
|
||||
{ // to satisfy GCC
|
||||
double dummy1 {};
|
||||
QString dummy2 {};
|
||||
return getUserString(dummy1, dummy2);
|
||||
}
|
||||
QString getUserString(UnitsSchema* schema, double &factor, QString &unitString) const;
|
||||
QString getUserString(UnitsSchema* schema, double& factor, QString& unitString) const;
|
||||
QString getSafeUserString() const;
|
||||
|
||||
static Quantity parse(const QString &string);
|
||||
static Quantity parse(const QString& string);
|
||||
|
||||
/// returns the unit of the quantity
|
||||
const Unit & getUnit() const{return myUnit;}
|
||||
const Unit& getUnit() const
|
||||
{
|
||||
return myUnit;
|
||||
}
|
||||
/// set the unit of the quantity
|
||||
void setUnit(const Unit &un){myUnit = un;}
|
||||
void setUnit(const Unit& un)
|
||||
{
|
||||
myUnit = un;
|
||||
}
|
||||
/// get the Value of the quantity
|
||||
double getValue() const{return myValue;}
|
||||
double getValue() const
|
||||
{
|
||||
return myValue;
|
||||
}
|
||||
/// set the value of the quantity
|
||||
void setValue(double val){myValue = val;}
|
||||
void setValue(double val)
|
||||
{
|
||||
myValue = val;
|
||||
}
|
||||
/** get the Value in a special unit given as quantity.
|
||||
* One can use one of the predifeined quantity units in this class
|
||||
*/
|
||||
double getValueAs(const Quantity &)const;
|
||||
* One can use one of the predifeined quantity units in this class
|
||||
*/
|
||||
double getValueAs(const Quantity&) const;
|
||||
|
||||
|
||||
/// true if it has a number without a unit
|
||||
bool isDimensionless()const;
|
||||
bool isDimensionless() const;
|
||||
/// true if it has a specific unit or no dimension.
|
||||
bool isDimensionlessOrUnit(const Unit& unit)const;
|
||||
bool isDimensionlessOrUnit(const Unit& unit) const;
|
||||
/// true if it has a number and a valid unit
|
||||
bool isQuantity()const;
|
||||
bool isQuantity() const;
|
||||
/// true if it has a number with or without a unit
|
||||
bool isValid()const;
|
||||
bool isValid() const;
|
||||
/// sets the quantity invalid
|
||||
void setInvalid();
|
||||
|
||||
@@ -303,7 +328,7 @@ public:
|
||||
|
||||
static const Quantity Weber;
|
||||
|
||||
//static const Quantity Oersted;
|
||||
// static const Quantity Oersted;
|
||||
|
||||
static const Quantity Farad;
|
||||
static const Quantity MilliFarad;
|
||||
@@ -340,12 +365,12 @@ public:
|
||||
//@}
|
||||
|
||||
|
||||
protected:
|
||||
double myValue;
|
||||
Unit myUnit;
|
||||
private:
|
||||
double myValue;
|
||||
Unit myUnit;
|
||||
QuantityFormat myFormat;
|
||||
};
|
||||
|
||||
} // namespace Base
|
||||
} // namespace Base
|
||||
|
||||
#endif // BASE_Quantity_H
|
||||
#endif // BASE_Quantity_H
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// clang-format off
|
||||
#line 1 "QuantityLexer.c"
|
||||
|
||||
#line 3 "QuantityLexer.c"
|
||||
@@ -34,7 +35,7 @@
|
||||
#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
|
||||
|
||||
/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h,
|
||||
* if you want the limit (max/min) macros for int types.
|
||||
* if you want the limit (max/min) macros for int types.
|
||||
*/
|
||||
#ifndef __STDC_LIMIT_MACROS
|
||||
#define __STDC_LIMIT_MACROS 1
|
||||
@@ -51,7 +52,7 @@ typedef uint32_t flex_uint32_t;
|
||||
typedef signed char flex_int8_t;
|
||||
typedef short int flex_int16_t;
|
||||
typedef int flex_int32_t;
|
||||
typedef unsigned char flex_uint8_t;
|
||||
typedef unsigned char flex_uint8_t;
|
||||
typedef unsigned short int flex_uint16_t;
|
||||
typedef unsigned int flex_uint32_t;
|
||||
|
||||
@@ -162,10 +163,10 @@ extern FILE *yyin, *yyout;
|
||||
#define EOB_ACT_CONTINUE_SCAN 0
|
||||
#define EOB_ACT_END_OF_FILE 1
|
||||
#define EOB_ACT_LAST_MATCH 2
|
||||
|
||||
|
||||
#define YY_LESS_LINENO(n)
|
||||
#define YY_LINENO_REWIND_TO(ptr)
|
||||
|
||||
|
||||
/* Return all but the first "n" matched characters back to the input stream. */
|
||||
#define yyless(n) \
|
||||
do \
|
||||
@@ -678,7 +679,7 @@ char *yytext;
|
||||
*/
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef YY_EXTRA_TYPE
|
||||
#define YY_EXTRA_TYPE void *
|
||||
#endif
|
||||
@@ -727,7 +728,7 @@ extern int yywrap ( void );
|
||||
#endif
|
||||
|
||||
#ifndef YY_NO_UNPUT
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef yytext_ptr
|
||||
@@ -854,7 +855,7 @@ YY_DECL
|
||||
yy_state_type yy_current_state;
|
||||
char *yy_cp, *yy_bp;
|
||||
int yy_act;
|
||||
|
||||
|
||||
if ( !(yy_init) )
|
||||
{
|
||||
(yy_init) = 1;
|
||||
@@ -1994,7 +1995,7 @@ static int yy_get_next_buffer (void)
|
||||
{
|
||||
yy_state_type yy_current_state;
|
||||
char *yy_cp;
|
||||
|
||||
|
||||
yy_current_state = (yy_start);
|
||||
|
||||
for ( yy_cp = (yytext_ptr) + YY_MORE_ADJ; yy_cp < (yy_c_buf_p); ++yy_cp )
|
||||
@@ -2058,7 +2059,7 @@ static int yy_get_next_buffer (void)
|
||||
|
||||
{
|
||||
int c;
|
||||
|
||||
|
||||
*(yy_c_buf_p) = (yy_hold_char);
|
||||
|
||||
if ( *(yy_c_buf_p) == YY_END_OF_BUFFER_CHAR )
|
||||
@@ -2125,12 +2126,12 @@ static int yy_get_next_buffer (void)
|
||||
|
||||
/** Immediately switch to a different input stream.
|
||||
* @param input_file A readable stream.
|
||||
*
|
||||
*
|
||||
* @note This function does not reset the start condition to @c INITIAL .
|
||||
*/
|
||||
void yyrestart (FILE * input_file )
|
||||
{
|
||||
|
||||
|
||||
if ( ! YY_CURRENT_BUFFER ){
|
||||
yyensure_buffer_stack ();
|
||||
YY_CURRENT_BUFFER_LVALUE =
|
||||
@@ -2143,11 +2144,11 @@ static int yy_get_next_buffer (void)
|
||||
|
||||
/** Switch to a different input buffer.
|
||||
* @param new_buffer The new input buffer.
|
||||
*
|
||||
*
|
||||
*/
|
||||
void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer )
|
||||
{
|
||||
|
||||
|
||||
/* TODO. We should be able to replace this entire function body
|
||||
* with
|
||||
* yypop_buffer_state();
|
||||
@@ -2187,13 +2188,13 @@ static void yy_load_buffer_state (void)
|
||||
/** Allocate and initialize an input buffer state.
|
||||
* @param file A readable stream.
|
||||
* @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE.
|
||||
*
|
||||
*
|
||||
* @return the allocated buffer state.
|
||||
*/
|
||||
YY_BUFFER_STATE yy_create_buffer (FILE * file, int size )
|
||||
{
|
||||
YY_BUFFER_STATE b;
|
||||
|
||||
|
||||
b = (YY_BUFFER_STATE) yyalloc( sizeof( struct yy_buffer_state ) );
|
||||
if ( ! b )
|
||||
YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
|
||||
@@ -2216,11 +2217,11 @@ static void yy_load_buffer_state (void)
|
||||
|
||||
/** Destroy the buffer.
|
||||
* @param b a buffer created with yy_create_buffer()
|
||||
*
|
||||
*
|
||||
*/
|
||||
void yy_delete_buffer (YY_BUFFER_STATE b )
|
||||
{
|
||||
|
||||
|
||||
if ( ! b )
|
||||
return;
|
||||
|
||||
@@ -2241,7 +2242,7 @@ static void yy_load_buffer_state (void)
|
||||
|
||||
{
|
||||
int oerrno = errno;
|
||||
|
||||
|
||||
yy_flush_buffer( b );
|
||||
|
||||
b->yy_input_file = file;
|
||||
@@ -2257,13 +2258,13 @@ static void yy_load_buffer_state (void)
|
||||
}
|
||||
|
||||
b->yy_is_interactive = 0;
|
||||
|
||||
|
||||
errno = oerrno;
|
||||
}
|
||||
|
||||
/** Discard all buffered characters. On the next scan, YY_INPUT will be called.
|
||||
* @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER.
|
||||
*
|
||||
*
|
||||
*/
|
||||
void yy_flush_buffer (YY_BUFFER_STATE b )
|
||||
{
|
||||
@@ -2292,7 +2293,7 @@ static void yy_load_buffer_state (void)
|
||||
* the current state. This function will allocate the stack
|
||||
* if necessary.
|
||||
* @param new_buffer The new state.
|
||||
*
|
||||
*
|
||||
*/
|
||||
void yypush_buffer_state (YY_BUFFER_STATE new_buffer )
|
||||
{
|
||||
@@ -2322,7 +2323,7 @@ void yypush_buffer_state (YY_BUFFER_STATE new_buffer )
|
||||
|
||||
/** Removes and deletes the top of the stack, if present.
|
||||
* The next element becomes the new top.
|
||||
*
|
||||
*
|
||||
*/
|
||||
void yypop_buffer_state (void)
|
||||
{
|
||||
@@ -2346,7 +2347,7 @@ void yypop_buffer_state (void)
|
||||
static void yyensure_buffer_stack (void)
|
||||
{
|
||||
yy_size_t num_to_alloc;
|
||||
|
||||
|
||||
if (!(yy_buffer_stack)) {
|
||||
|
||||
/* First allocation is just for 2 elements, since we don't know if this
|
||||
@@ -2389,13 +2390,13 @@ static void yyensure_buffer_stack (void)
|
||||
/** Setup the input buffer state to scan directly from a user-specified character buffer.
|
||||
* @param base the character buffer
|
||||
* @param size the size in bytes of the character buffer
|
||||
*
|
||||
*
|
||||
* @return the newly allocated buffer state object.
|
||||
*/
|
||||
YY_BUFFER_STATE yy_scan_buffer (char * base, yy_size_t size )
|
||||
{
|
||||
YY_BUFFER_STATE b;
|
||||
|
||||
|
||||
if ( size < 2 ||
|
||||
base[size-2] != YY_END_OF_BUFFER_CHAR ||
|
||||
base[size-1] != YY_END_OF_BUFFER_CHAR )
|
||||
@@ -2424,14 +2425,14 @@ YY_BUFFER_STATE yy_scan_buffer (char * base, yy_size_t size )
|
||||
/** Setup the input buffer state to scan a string. The next call to yylex() will
|
||||
* scan from a @e copy of @a str.
|
||||
* @param yystr a NUL-terminated string to scan
|
||||
*
|
||||
*
|
||||
* @return the newly allocated buffer state object.
|
||||
* @note If you want to scan bytes that may contain NUL values, then use
|
||||
* yy_scan_bytes() instead.
|
||||
*/
|
||||
YY_BUFFER_STATE yy_scan_string (const char * yystr )
|
||||
{
|
||||
|
||||
|
||||
return yy_scan_bytes( yystr, (int) strlen(yystr) );
|
||||
}
|
||||
|
||||
@@ -2439,7 +2440,7 @@ YY_BUFFER_STATE yy_scan_string (const char * yystr )
|
||||
* scan from a @e copy of @a bytes.
|
||||
* @param yybytes the byte buffer to scan
|
||||
* @param _yybytes_len the number of bytes in the buffer pointed to by @a bytes.
|
||||
*
|
||||
*
|
||||
* @return the newly allocated buffer state object.
|
||||
*/
|
||||
YY_BUFFER_STATE yy_scan_bytes (const char * yybytes, int _yybytes_len )
|
||||
@@ -2448,7 +2449,7 @@ YY_BUFFER_STATE yy_scan_bytes (const char * yybytes, int _yybytes_len )
|
||||
char *buf;
|
||||
yy_size_t n;
|
||||
int i;
|
||||
|
||||
|
||||
/* Get memory for full buffer, including space for trailing EOB's. */
|
||||
n = (yy_size_t) (_yybytes_len + 2);
|
||||
buf = (char *) yyalloc( n );
|
||||
@@ -2502,16 +2503,16 @@ static void yynoreturn yy_fatal_error (const char* msg )
|
||||
/* Accessor methods (get/set functions) to struct members. */
|
||||
|
||||
/** Get the current line number.
|
||||
*
|
||||
*
|
||||
*/
|
||||
int yyget_lineno (void)
|
||||
{
|
||||
|
||||
|
||||
return yylineno;
|
||||
}
|
||||
|
||||
/** Get the input stream.
|
||||
*
|
||||
*
|
||||
*/
|
||||
FILE *yyget_in (void)
|
||||
{
|
||||
@@ -2519,7 +2520,7 @@ FILE *yyget_in (void)
|
||||
}
|
||||
|
||||
/** Get the output stream.
|
||||
*
|
||||
*
|
||||
*/
|
||||
FILE *yyget_out (void)
|
||||
{
|
||||
@@ -2527,7 +2528,7 @@ FILE *yyget_out (void)
|
||||
}
|
||||
|
||||
/** Get the length of the current token.
|
||||
*
|
||||
*
|
||||
*/
|
||||
int yyget_leng (void)
|
||||
{
|
||||
@@ -2535,7 +2536,7 @@ int yyget_leng (void)
|
||||
}
|
||||
|
||||
/** Get the current token.
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
char *yyget_text (void)
|
||||
@@ -2545,18 +2546,18 @@ char *yyget_text (void)
|
||||
|
||||
/** Set the current line number.
|
||||
* @param _line_number line number
|
||||
*
|
||||
*
|
||||
*/
|
||||
void yyset_lineno (int _line_number )
|
||||
{
|
||||
|
||||
|
||||
yylineno = _line_number;
|
||||
}
|
||||
|
||||
/** Set the input stream. This does not discard the current
|
||||
* input buffer.
|
||||
* @param _in_str A readable stream.
|
||||
*
|
||||
*
|
||||
* @see yy_switch_to_buffer
|
||||
*/
|
||||
void yyset_in (FILE * _in_str )
|
||||
@@ -2610,7 +2611,7 @@ static int yy_init_globals (void)
|
||||
/* yylex_destroy is for both reentrant and non-reentrant scanners. */
|
||||
int yylex_destroy (void)
|
||||
{
|
||||
|
||||
|
||||
/* Pop the buffer stack, destroying each element. */
|
||||
while(YY_CURRENT_BUFFER){
|
||||
yy_delete_buffer( YY_CURRENT_BUFFER );
|
||||
@@ -2636,7 +2637,7 @@ int yylex_destroy (void)
|
||||
#ifndef yytext_ptr
|
||||
static void yy_flex_strncpy (char* s1, const char * s2, int n )
|
||||
{
|
||||
|
||||
|
||||
int i;
|
||||
for ( i = 0; i < n; ++i )
|
||||
s1[i] = s2[i];
|
||||
@@ -2661,7 +2662,7 @@ void *yyalloc (yy_size_t size )
|
||||
|
||||
void *yyrealloc (void * ptr, yy_size_t size )
|
||||
{
|
||||
|
||||
|
||||
/* The cast to (char *) in the following accommodates both
|
||||
* implementations that use char* generic pointers, and those
|
||||
* that use void* generic pointers. It works with the latter
|
||||
@@ -2680,3 +2681,4 @@ void yyfree (void * ptr )
|
||||
#define YYTABLES_NAME "yytables"
|
||||
|
||||
#line 249 "QuantityParser.l"
|
||||
// clang-format on
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// clang-format off
|
||||
/* A Bison parser, made by GNU Bison 3.0.4. */
|
||||
|
||||
/* Bison implementation for Yacc-like parsers in C
|
||||
@@ -1745,3 +1746,4 @@ yyreturn:
|
||||
}
|
||||
#line 77 "QuantityParser.y" /* yacc.c:1906 */
|
||||
|
||||
// clang-format on
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// clang-format off
|
||||
/* A Bison parser, made by GNU Bison 3.0.4. */
|
||||
|
||||
/* Bison interface for Yacc-like parsers in C
|
||||
@@ -81,3 +82,4 @@ extern YYSTYPE yylval;
|
||||
int yyparse (void);
|
||||
|
||||
#endif /* !YY_YY_QUANTITYPARSER_H_INCLUDED */
|
||||
// clang-format on
|
||||
|
||||
@@ -35,14 +35,15 @@ std::string QuantityPy::representation() const
|
||||
{
|
||||
std::stringstream ret;
|
||||
|
||||
double val= getQuantityPtr()->getValue();
|
||||
double val = getQuantityPtr()->getValue();
|
||||
Unit unit = getQuantityPtr()->getUnit();
|
||||
|
||||
// Use Python's implementation to repr() a float
|
||||
Py::Float flt(val);
|
||||
ret << static_cast<std::string>(flt.repr());
|
||||
if (!unit.isEmpty())
|
||||
if (!unit.isEmpty()) {
|
||||
ret << " " << unit.getString().toUtf8().constData();
|
||||
}
|
||||
|
||||
return ret.str();
|
||||
}
|
||||
@@ -50,23 +51,25 @@ std::string QuantityPy::representation() const
|
||||
PyObject* QuantityPy::toStr(PyObject* args)
|
||||
{
|
||||
int prec = getQuantityPtr()->getFormat().precision;
|
||||
if (!PyArg_ParseTuple(args,"|i", &prec))
|
||||
if (!PyArg_ParseTuple(args, "|i", &prec)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
double val= getQuantityPtr()->getValue();
|
||||
double val = getQuantityPtr()->getValue();
|
||||
Unit unit = getQuantityPtr()->getUnit();
|
||||
|
||||
std::stringstream ret;
|
||||
ret.precision(prec);
|
||||
ret.setf(std::ios::fixed, std::ios::floatfield);
|
||||
ret << val;
|
||||
if (!unit.isEmpty())
|
||||
if (!unit.isEmpty()) {
|
||||
ret << " " << unit.getString().toUtf8().constData();
|
||||
}
|
||||
|
||||
return Py_BuildValue("s", ret.str().c_str());
|
||||
}
|
||||
|
||||
PyObject *QuantityPy::PyMake(struct _typeobject *, PyObject *, PyObject *) // Python wrapper
|
||||
PyObject* QuantityPy::PyMake(struct _typeobject*, PyObject*, PyObject*) // Python wrapper
|
||||
{
|
||||
// create a new instance of QuantityPy and the Twin object
|
||||
return new QuantityPy(new Quantity);
|
||||
@@ -75,60 +78,61 @@ PyObject *QuantityPy::PyMake(struct _typeobject *, PyObject *, PyObject *) // P
|
||||
// constructor method
|
||||
int QuantityPy::PyInit(PyObject* args, PyObject* /*kwd*/)
|
||||
{
|
||||
Quantity *self = getQuantityPtr();
|
||||
Quantity* self = getQuantityPtr();
|
||||
|
||||
PyErr_Clear(); // set by PyArg_ParseTuple()
|
||||
PyObject *object{};
|
||||
if (PyArg_ParseTuple(args,"O!",&(Base::QuantityPy::Type), &object)) {
|
||||
PyErr_Clear(); // set by PyArg_ParseTuple()
|
||||
PyObject* object {};
|
||||
if (PyArg_ParseTuple(args, "O!", &(Base::QuantityPy::Type), &object)) {
|
||||
*self = *(static_cast<Base::QuantityPy*>(object)->getQuantityPtr());
|
||||
return 0;
|
||||
}
|
||||
|
||||
PyErr_Clear(); // set by PyArg_ParseTuple()
|
||||
PyErr_Clear(); // set by PyArg_ParseTuple()
|
||||
double f = DOUBLE_MAX;
|
||||
if (PyArg_ParseTuple(args,"dO!",&f,&(Base::UnitPy::Type), &object)) {
|
||||
*self = Quantity(f,*(static_cast<Base::UnitPy*>(object)->getUnitPtr()));
|
||||
if (PyArg_ParseTuple(args, "dO!", &f, &(Base::UnitPy::Type), &object)) {
|
||||
*self = Quantity(f, *(static_cast<Base::UnitPy*>(object)->getUnitPtr()));
|
||||
return 0;
|
||||
}
|
||||
|
||||
PyErr_Clear(); // set by PyArg_ParseTuple()
|
||||
if (PyArg_ParseTuple(args,"dO!",&f,&(Base::QuantityPy::Type), &object)) {
|
||||
PyErr_Clear(); // set by PyArg_ParseTuple()
|
||||
if (PyArg_ParseTuple(args, "dO!", &f, &(Base::QuantityPy::Type), &object)) {
|
||||
PyErr_SetString(PyExc_TypeError, "Second argument must be a Unit not a Quantity");
|
||||
return -1;
|
||||
}
|
||||
|
||||
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(); // set by PyArg_ParseTuple()
|
||||
if (PyArg_ParseTuple(args, "|diiiiiiii", &f,&i1,&i2,&i3,&i4,&i5,&i6,&i7,&i8)) {
|
||||
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(); // set by PyArg_ParseTuple()
|
||||
if (PyArg_ParseTuple(args, "|diiiiiiii", &f, &i1, &i2, &i3, &i4, &i5, &i6, &i7, &i8)) {
|
||||
if (f < DOUBLE_MAX) {
|
||||
*self = 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)});
|
||||
*self = 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)});
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
PyErr_Clear(); // set by PyArg_ParseTuple()
|
||||
char* string{};
|
||||
if (PyArg_ParseTuple(args,"et", "utf-8", &string)) {
|
||||
PyErr_Clear(); // set by PyArg_ParseTuple()
|
||||
char* string {};
|
||||
if (PyArg_ParseTuple(args, "et", "utf-8", &string)) {
|
||||
QString qstr = QString::fromUtf8(string);
|
||||
PyMem_Free(string);
|
||||
try {
|
||||
*self = Quantity::parse(qstr);
|
||||
}
|
||||
catch(const Base::ParserError& e) {
|
||||
catch (const Base::ParserError& e) {
|
||||
PyErr_SetString(PyExc_ValueError, e.what());
|
||||
return -1;
|
||||
}
|
||||
@@ -136,14 +140,14 @@ int QuantityPy::PyInit(PyObject* args, PyObject* /*kwd*/)
|
||||
return 0;
|
||||
}
|
||||
|
||||
PyErr_Clear(); // set by PyArg_ParseTuple()
|
||||
if (PyArg_ParseTuple(args,"det", &f, "utf-8", &string)) {
|
||||
PyErr_Clear(); // set by PyArg_ParseTuple()
|
||||
if (PyArg_ParseTuple(args, "det", &f, "utf-8", &string)) {
|
||||
QString unit = QString::fromUtf8(string);
|
||||
PyMem_Free(string);
|
||||
try {
|
||||
*self = Quantity(f, unit);
|
||||
}
|
||||
catch(const Base::ParserError& e) {
|
||||
catch (const Base::ParserError& e) {
|
||||
PyErr_SetString(PyExc_ValueError, e.what());
|
||||
return -1;
|
||||
}
|
||||
@@ -158,45 +162,45 @@ int QuantityPy::PyInit(PyObject* args, PyObject* /*kwd*/)
|
||||
PyObject* QuantityPy::getUserPreferred(PyObject* /*args*/)
|
||||
{
|
||||
QString uus;
|
||||
double factor{};
|
||||
double factor {};
|
||||
Py::Tuple res(3);
|
||||
|
||||
QString uss = getQuantityPtr()->getUserString(factor,uus);
|
||||
QString uss = getQuantityPtr()->getUserString(factor, uus);
|
||||
|
||||
res[0] = Py::String(uss.toUtf8(),"utf-8");
|
||||
res[0] = Py::String(uss.toUtf8(), "utf-8");
|
||||
res[1] = Py::Float(factor);
|
||||
res[2] = Py::String(uus.toUtf8(),"utf-8");
|
||||
res[2] = Py::String(uus.toUtf8(), "utf-8");
|
||||
|
||||
return Py::new_reference_to(res);
|
||||
}
|
||||
|
||||
PyObject* QuantityPy::getValueAs(PyObject *args)
|
||||
PyObject* QuantityPy::getValueAs(PyObject* args)
|
||||
{
|
||||
Quantity quant;
|
||||
quant.setInvalid();
|
||||
|
||||
// first try Quantity
|
||||
if (!quant.isValid()) {
|
||||
PyObject *object{};
|
||||
if (PyArg_ParseTuple(args,"O!",&(Base::QuantityPy::Type), &object)) {
|
||||
quant = * static_cast<Base::QuantityPy*>(object)->getQuantityPtr();
|
||||
PyObject* object {};
|
||||
if (PyArg_ParseTuple(args, "O!", &(Base::QuantityPy::Type), &object)) {
|
||||
quant = *static_cast<Base::QuantityPy*>(object)->getQuantityPtr();
|
||||
}
|
||||
}
|
||||
|
||||
if (!quant.isValid()) {
|
||||
PyObject *object{};
|
||||
PyObject* object {};
|
||||
PyErr_Clear();
|
||||
if (PyArg_ParseTuple(args,"O!",&(Base::UnitPy::Type), &object)) {
|
||||
if (PyArg_ParseTuple(args, "O!", &(Base::UnitPy::Type), &object)) {
|
||||
quant.setUnit(*static_cast<Base::UnitPy*>(object)->getUnitPtr());
|
||||
quant.setValue(1.0);
|
||||
}
|
||||
}
|
||||
|
||||
if (!quant.isValid()) {
|
||||
PyObject *object{};
|
||||
double value{};
|
||||
PyObject* object {};
|
||||
double value {};
|
||||
PyErr_Clear();
|
||||
if (PyArg_ParseTuple(args,"dO!",&value, &(Base::UnitPy::Type), &object)) {
|
||||
if (PyArg_ParseTuple(args, "dO!", &value, &(Base::UnitPy::Type), &object)) {
|
||||
quant.setUnit(*static_cast<Base::UnitPy*>(object)->getUnitPtr());
|
||||
quant.setValue(value);
|
||||
}
|
||||
@@ -204,33 +208,34 @@ PyObject* QuantityPy::getValueAs(PyObject *args)
|
||||
|
||||
if (!quant.isValid()) {
|
||||
double f = 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 (PyArg_ParseTuple(args, "d|iiiiiiii", &f, &i1, &i2, &i3, &i4, &i5, &i6, &i7, &i8)) {
|
||||
if (f < 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)});
|
||||
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 (!quant.isValid()) {
|
||||
PyErr_Clear();
|
||||
char* string{};
|
||||
if (PyArg_ParseTuple(args,"et", "utf-8", &string)) {
|
||||
char* string {};
|
||||
if (PyArg_ParseTuple(args, "et", "utf-8", &string)) {
|
||||
QString qstr = QString::fromUtf8(string);
|
||||
PyMem_Free(string);
|
||||
quant = Quantity::parse(qstr);
|
||||
@@ -251,9 +256,9 @@ PyObject* QuantityPy::getValueAs(PyObject *args)
|
||||
return new QuantityPy(new Quantity(quant));
|
||||
}
|
||||
|
||||
PyObject * QuantityPy::__round__ (PyObject *args)
|
||||
PyObject* QuantityPy::__round__(PyObject* args)
|
||||
{
|
||||
double val= getQuantityPtr()->getValue();
|
||||
double val = getQuantityPtr()->getValue();
|
||||
Unit unit = getQuantityPtr()->getUnit();
|
||||
Py::Float flt(val);
|
||||
Py::Callable func(flt.getAttr("__round__"));
|
||||
@@ -262,7 +267,7 @@ PyObject * QuantityPy::__round__ (PyObject *args)
|
||||
return new QuantityPy(new Quantity(rnd, unit));
|
||||
}
|
||||
|
||||
PyObject * QuantityPy::number_float_handler (PyObject *self)
|
||||
PyObject* QuantityPy::number_float_handler(PyObject* self)
|
||||
{
|
||||
if (!PyObject_TypeCheck(self, &(QuantityPy::Type))) {
|
||||
PyErr_SetString(PyExc_TypeError, "Arg must be Quantity");
|
||||
@@ -273,7 +278,7 @@ PyObject * QuantityPy::number_float_handler (PyObject *self)
|
||||
return PyFloat_FromDouble(q->getValue());
|
||||
}
|
||||
|
||||
PyObject * QuantityPy::number_int_handler (PyObject *self)
|
||||
PyObject* QuantityPy::number_int_handler(PyObject* self)
|
||||
{
|
||||
if (!PyObject_TypeCheck(self, &(QuantityPy::Type))) {
|
||||
PyErr_SetString(PyExc_TypeError, "Arg must be Quantity");
|
||||
@@ -284,139 +289,167 @@ PyObject * QuantityPy::number_int_handler (PyObject *self)
|
||||
return PyLong_FromLong(long(q->getValue()));
|
||||
}
|
||||
|
||||
PyObject * QuantityPy::number_negative_handler (PyObject *self)
|
||||
PyObject* QuantityPy::number_negative_handler(PyObject* self)
|
||||
{
|
||||
if (!PyObject_TypeCheck(self, &(QuantityPy::Type))) {
|
||||
PyErr_SetString(PyExc_TypeError, "Arg must be Quantity");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Base::Quantity *a = static_cast<QuantityPy*>(self) ->getQuantityPtr();
|
||||
Base::Quantity* a = static_cast<QuantityPy*>(self)->getQuantityPtr();
|
||||
double b = -1;
|
||||
return new QuantityPy(new Quantity(*a * b));
|
||||
}
|
||||
|
||||
PyObject * QuantityPy::number_positive_handler (PyObject *self)
|
||||
PyObject* QuantityPy::number_positive_handler(PyObject* self)
|
||||
{
|
||||
if (!PyObject_TypeCheck(self, &(QuantityPy::Type))) {
|
||||
PyErr_SetString(PyExc_TypeError, "Arg must be Quantity");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Base::Quantity *a = static_cast<QuantityPy*>(self) ->getQuantityPtr();
|
||||
Base::Quantity* a = static_cast<QuantityPy*>(self)->getQuantityPtr();
|
||||
return new QuantityPy(new Quantity(*a));
|
||||
}
|
||||
|
||||
PyObject * QuantityPy::number_absolute_handler (PyObject *self)
|
||||
PyObject* QuantityPy::number_absolute_handler(PyObject* self)
|
||||
{
|
||||
if (!PyObject_TypeCheck(self, &(QuantityPy::Type))) {
|
||||
PyErr_SetString(PyExc_TypeError, "Arg must be Quantity");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Base::Quantity *a = static_cast<QuantityPy*>(self) ->getQuantityPtr();
|
||||
Base::Quantity* a = static_cast<QuantityPy*>(self)->getQuantityPtr();
|
||||
return new QuantityPy(new Quantity(fabs(a->getValue()), a->getUnit()));
|
||||
}
|
||||
|
||||
static Quantity &pyToQuantity(Quantity &q, PyObject *pyobj) {
|
||||
if (PyObject_TypeCheck(pyobj, &Base::QuantityPy::Type))
|
||||
static Quantity& pyToQuantity(Quantity& q, PyObject* pyobj)
|
||||
{
|
||||
if (PyObject_TypeCheck(pyobj, &Base::QuantityPy::Type)) {
|
||||
q = *static_cast<Base::QuantityPy*>(pyobj)->getQuantityPtr();
|
||||
else if (PyFloat_Check(pyobj))
|
||||
}
|
||||
else if (PyFloat_Check(pyobj)) {
|
||||
q = Quantity(PyFloat_AsDouble(pyobj));
|
||||
else if (PyLong_Check(pyobj))
|
||||
}
|
||||
else if (PyLong_Check(pyobj)) {
|
||||
q = Quantity(PyLong_AsLong(pyobj));
|
||||
}
|
||||
else {
|
||||
PyErr_Format(PyExc_TypeError,"Cannot convert %s to Quantity",Py_TYPE(pyobj)->tp_name);
|
||||
PyErr_Format(PyExc_TypeError, "Cannot convert %s to Quantity", Py_TYPE(pyobj)->tp_name);
|
||||
throw Py::Exception();
|
||||
}
|
||||
return q;
|
||||
}
|
||||
|
||||
PyObject* QuantityPy::number_add_handler(PyObject *self, PyObject *other)
|
||||
PyObject* QuantityPy::number_add_handler(PyObject* self, PyObject* other)
|
||||
{
|
||||
Quantity *pa=nullptr, *pb=nullptr;
|
||||
Quantity a,b;
|
||||
PY_TRY {
|
||||
if (PyObject_TypeCheck(self, &(QuantityPy::Type)))
|
||||
Quantity *pa = nullptr, *pb = nullptr;
|
||||
Quantity a, b;
|
||||
PY_TRY
|
||||
{
|
||||
if (PyObject_TypeCheck(self, &(QuantityPy::Type))) {
|
||||
pa = static_cast<QuantityPy*>(self)->getQuantityPtr();
|
||||
else
|
||||
pa = &pyToQuantity(a,self);
|
||||
}
|
||||
else {
|
||||
pa = &pyToQuantity(a, self);
|
||||
}
|
||||
|
||||
if (PyObject_TypeCheck(other, &(QuantityPy::Type)))
|
||||
if (PyObject_TypeCheck(other, &(QuantityPy::Type))) {
|
||||
pb = static_cast<QuantityPy*>(other)->getQuantityPtr();
|
||||
else
|
||||
pb = &pyToQuantity(b,other);
|
||||
return new QuantityPy(new Quantity(*pa + *pb) );
|
||||
} PY_CATCH
|
||||
}
|
||||
else {
|
||||
pb = &pyToQuantity(b, other);
|
||||
}
|
||||
return new QuantityPy(new Quantity(*pa + *pb));
|
||||
}
|
||||
PY_CATCH
|
||||
}
|
||||
|
||||
PyObject* QuantityPy::number_subtract_handler(PyObject *self, PyObject *other)
|
||||
PyObject* QuantityPy::number_subtract_handler(PyObject* self, PyObject* other)
|
||||
{
|
||||
Quantity *pa=nullptr, *pb=nullptr;
|
||||
Quantity a,b;
|
||||
PY_TRY {
|
||||
if (PyObject_TypeCheck(self, &(QuantityPy::Type)))
|
||||
Quantity *pa = nullptr, *pb = nullptr;
|
||||
Quantity a, b;
|
||||
PY_TRY
|
||||
{
|
||||
if (PyObject_TypeCheck(self, &(QuantityPy::Type))) {
|
||||
pa = static_cast<QuantityPy*>(self)->getQuantityPtr();
|
||||
else
|
||||
pa = &pyToQuantity(a,self);
|
||||
}
|
||||
else {
|
||||
pa = &pyToQuantity(a, self);
|
||||
}
|
||||
|
||||
if (PyObject_TypeCheck(other, &(QuantityPy::Type)))
|
||||
if (PyObject_TypeCheck(other, &(QuantityPy::Type))) {
|
||||
pb = static_cast<QuantityPy*>(other)->getQuantityPtr();
|
||||
else
|
||||
pb = &pyToQuantity(b,other);
|
||||
return new QuantityPy(new Quantity(*pa - *pb) );
|
||||
} PY_CATCH
|
||||
}
|
||||
else {
|
||||
pb = &pyToQuantity(b, other);
|
||||
}
|
||||
return new QuantityPy(new Quantity(*pa - *pb));
|
||||
}
|
||||
PY_CATCH
|
||||
}
|
||||
|
||||
PyObject* QuantityPy::number_multiply_handler(PyObject *self, PyObject *other)
|
||||
PyObject* QuantityPy::number_multiply_handler(PyObject* self, PyObject* other)
|
||||
{
|
||||
Quantity *pa=nullptr, *pb=nullptr;
|
||||
Quantity a,b;
|
||||
PY_TRY {
|
||||
if (PyObject_TypeCheck(self, &(QuantityPy::Type)))
|
||||
Quantity *pa = nullptr, *pb = nullptr;
|
||||
Quantity a, b;
|
||||
PY_TRY
|
||||
{
|
||||
if (PyObject_TypeCheck(self, &(QuantityPy::Type))) {
|
||||
pa = static_cast<QuantityPy*>(self)->getQuantityPtr();
|
||||
else
|
||||
pa = &pyToQuantity(a,self);
|
||||
}
|
||||
else {
|
||||
pa = &pyToQuantity(a, self);
|
||||
}
|
||||
|
||||
if (PyObject_TypeCheck(other, &(QuantityPy::Type)))
|
||||
if (PyObject_TypeCheck(other, &(QuantityPy::Type))) {
|
||||
pb = static_cast<QuantityPy*>(other)->getQuantityPtr();
|
||||
else
|
||||
pb = &pyToQuantity(b,other);
|
||||
return new QuantityPy(new Quantity(*pa * *pb) );
|
||||
} PY_CATCH
|
||||
}
|
||||
else {
|
||||
pb = &pyToQuantity(b, other);
|
||||
}
|
||||
return new QuantityPy(new Quantity(*pa * *pb));
|
||||
}
|
||||
PY_CATCH
|
||||
}
|
||||
|
||||
PyObject * QuantityPy::number_divide_handler (PyObject *self, PyObject *other)
|
||||
PyObject* QuantityPy::number_divide_handler(PyObject* self, PyObject* other)
|
||||
{
|
||||
Quantity *pa=nullptr, *pb=nullptr;
|
||||
Quantity a,b;
|
||||
PY_TRY {
|
||||
if (PyObject_TypeCheck(self, &(QuantityPy::Type)))
|
||||
Quantity *pa = nullptr, *pb = nullptr;
|
||||
Quantity a, b;
|
||||
PY_TRY
|
||||
{
|
||||
if (PyObject_TypeCheck(self, &(QuantityPy::Type))) {
|
||||
pa = static_cast<QuantityPy*>(self)->getQuantityPtr();
|
||||
else
|
||||
pa = &pyToQuantity(a,self);
|
||||
}
|
||||
else {
|
||||
pa = &pyToQuantity(a, self);
|
||||
}
|
||||
|
||||
if (PyObject_TypeCheck(other, &(QuantityPy::Type)))
|
||||
if (PyObject_TypeCheck(other, &(QuantityPy::Type))) {
|
||||
pb = static_cast<QuantityPy*>(other)->getQuantityPtr();
|
||||
else
|
||||
pb = &pyToQuantity(b,other);
|
||||
return new QuantityPy(new Quantity(*pa / *pb) );
|
||||
} PY_CATCH
|
||||
}
|
||||
else {
|
||||
pb = &pyToQuantity(b, other);
|
||||
}
|
||||
return new QuantityPy(new Quantity(*pa / *pb));
|
||||
}
|
||||
PY_CATCH
|
||||
}
|
||||
|
||||
PyObject * QuantityPy::number_remainder_handler (PyObject *self, PyObject *other)
|
||||
PyObject* QuantityPy::number_remainder_handler(PyObject* self, PyObject* other)
|
||||
{
|
||||
if (!PyObject_TypeCheck(self, &(QuantityPy::Type))) {
|
||||
PyErr_SetString(PyExc_TypeError, "First arg must be Quantity");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
double d1{}, d2{};
|
||||
Base::Quantity *a = static_cast<QuantityPy*>(self) ->getQuantityPtr();
|
||||
double d1 {}, d2 {};
|
||||
Base::Quantity* a = static_cast<QuantityPy*>(self)->getQuantityPtr();
|
||||
d1 = a->getValue();
|
||||
|
||||
if (PyObject_TypeCheck(other, &(QuantityPy::Type))) {
|
||||
Base::Quantity *b = static_cast<QuantityPy*>(other)->getQuantityPtr();
|
||||
Base::Quantity* b = static_cast<QuantityPy*>(other)->getQuantityPtr();
|
||||
d2 = b->getValue();
|
||||
}
|
||||
else if (PyFloat_Check(other)) {
|
||||
@@ -435,42 +468,44 @@ PyObject * QuantityPy::number_remainder_handler (PyObject *self, PyObject *other
|
||||
PyObject* r = PyNumber_Remainder(p1, p2);
|
||||
Py_DECREF(p1);
|
||||
Py_DECREF(p2);
|
||||
if (!r)
|
||||
if (!r) {
|
||||
return nullptr;
|
||||
}
|
||||
double q = PyFloat_AsDouble(r);
|
||||
Py_DECREF(r);
|
||||
return new QuantityPy(new Quantity(q,a->getUnit()));
|
||||
return new QuantityPy(new Quantity(q, a->getUnit()));
|
||||
}
|
||||
|
||||
PyObject * QuantityPy::number_divmod_handler (PyObject* /*self*/, PyObject* /*other*/)
|
||||
PyObject* QuantityPy::number_divmod_handler(PyObject* /*self*/, PyObject* /*other*/)
|
||||
{
|
||||
//PyNumber_Divmod();
|
||||
// PyNumber_Divmod();
|
||||
PyErr_SetString(PyExc_NotImplementedError, "Not implemented");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
PyObject * QuantityPy::number_power_handler (PyObject *self, PyObject *other, PyObject * /*modulo*/)
|
||||
PyObject* QuantityPy::number_power_handler(PyObject* self, PyObject* other, PyObject* /*modulo*/)
|
||||
{
|
||||
if (!PyObject_TypeCheck(self, &(QuantityPy::Type))) {
|
||||
PyErr_SetString(PyExc_TypeError, "First arg must be Quantity");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
PY_TRY {
|
||||
PY_TRY
|
||||
{
|
||||
if (PyObject_TypeCheck(other, &(QuantityPy::Type))) {
|
||||
Base::Quantity *a = static_cast<QuantityPy*>(self) ->getQuantityPtr();
|
||||
Base::Quantity *b = static_cast<QuantityPy*>(other)->getQuantityPtr();
|
||||
Base::Quantity q(a->pow(*b)); // to prevent memory leak in case of exception
|
||||
Base::Quantity* a = static_cast<QuantityPy*>(self)->getQuantityPtr();
|
||||
Base::Quantity* b = static_cast<QuantityPy*>(other)->getQuantityPtr();
|
||||
Base::Quantity q(a->pow(*b)); // to prevent memory leak in case of exception
|
||||
|
||||
return new QuantityPy(new Quantity(q));
|
||||
}
|
||||
else if (PyFloat_Check(other)) {
|
||||
Base::Quantity *a = static_cast<QuantityPy*>(self) ->getQuantityPtr();
|
||||
Base::Quantity* a = static_cast<QuantityPy*>(self)->getQuantityPtr();
|
||||
double b = PyFloat_AsDouble(other);
|
||||
return new QuantityPy(new Quantity(a->pow(b)) );
|
||||
return new QuantityPy(new Quantity(a->pow(b)));
|
||||
}
|
||||
else if (PyLong_Check(other)) {
|
||||
Base::Quantity *a = static_cast<QuantityPy*>(self) ->getQuantityPtr();
|
||||
Base::Quantity* a = static_cast<QuantityPy*>(self)->getQuantityPtr();
|
||||
double b = (double)PyLong_AsLong(other);
|
||||
return new QuantityPy(new Quantity(a->pow(b)));
|
||||
}
|
||||
@@ -478,27 +513,27 @@ PyObject * QuantityPy::number_power_handler (PyObject *self, PyObject *other, Py
|
||||
PyErr_SetString(PyExc_TypeError, "Expected quantity or number");
|
||||
return nullptr;
|
||||
}
|
||||
}PY_CATCH
|
||||
}
|
||||
PY_CATCH
|
||||
}
|
||||
|
||||
int QuantityPy::number_nonzero_handler (PyObject *self)
|
||||
int QuantityPy::number_nonzero_handler(PyObject* self)
|
||||
{
|
||||
if (!PyObject_TypeCheck(self, &(QuantityPy::Type))) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
Base::Quantity *a = static_cast<QuantityPy*>(self) ->getQuantityPtr();
|
||||
Base::Quantity* a = static_cast<QuantityPy*>(self)->getQuantityPtr();
|
||||
return a->getValue() != 0.0;
|
||||
}
|
||||
|
||||
PyObject* QuantityPy::richCompare(PyObject *v, PyObject *w, int op)
|
||||
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();
|
||||
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=nullptr;
|
||||
PyObject* res = nullptr;
|
||||
if (op == Py_NE) {
|
||||
res = (!(*u1 == *u2)) ? Py_True : Py_False;
|
||||
Py_INCREF(res);
|
||||
@@ -510,12 +545,12 @@ PyObject* QuantityPy::richCompare(PyObject *v, PyObject *w, int op)
|
||||
return res;
|
||||
}
|
||||
else if (op == Py_LE) {
|
||||
res = (*u1 < *u2)||(*u1 == *u2) ? Py_True : Py_False;
|
||||
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;
|
||||
res = (!(*u1 < *u2)) && (!(*u1 == *u2)) ? Py_True : Py_False;
|
||||
Py_INCREF(res);
|
||||
return res;
|
||||
}
|
||||
@@ -534,7 +569,7 @@ PyObject* QuantityPy::richCompare(PyObject *v, PyObject *w, int op)
|
||||
// Try to get floating numbers
|
||||
double u1 = PyFloat_AsDouble(v);
|
||||
double u2 = PyFloat_AsDouble(w);
|
||||
PyObject *res=nullptr;
|
||||
PyObject* res = nullptr;
|
||||
if (op == Py_NE) {
|
||||
res = (u1 != u2) ? Py_True : Py_False;
|
||||
Py_INCREF(res);
|
||||
@@ -590,15 +625,16 @@ Py::Object QuantityPy::getUnit() const
|
||||
void QuantityPy::setUnit(Py::Object arg)
|
||||
{
|
||||
Py::Type UnitType(Base::getTypeAsObject(&Base::UnitPy::Type));
|
||||
if(!arg.isType(UnitType))
|
||||
if (!arg.isType(UnitType)) {
|
||||
throw Py::AttributeError("Not yet implemented");
|
||||
}
|
||||
|
||||
getQuantityPtr()->setUnit(*static_cast<Base::UnitPy*>((*arg))->getUnitPtr());
|
||||
}
|
||||
|
||||
Py::String QuantityPy::getUserString() const
|
||||
{
|
||||
return {getQuantityPtr()->getUserString().toUtf8(),"utf-8"};
|
||||
return {getQuantityPtr()->getUserString().toUtf8(), "utf-8"};
|
||||
}
|
||||
|
||||
Py::Dict QuantityPy::getFormat() const
|
||||
@@ -606,18 +642,18 @@ Py::Dict QuantityPy::getFormat() const
|
||||
QuantityFormat fmt = getQuantityPtr()->getFormat();
|
||||
|
||||
Py::Dict dict;
|
||||
dict.setItem("Precision", Py::Int (fmt.precision));
|
||||
dict.setItem("Precision", Py::Int(fmt.precision));
|
||||
dict.setItem("NumberFormat", Py::Char(fmt.toFormat()));
|
||||
dict.setItem("Denominator", Py::Int(fmt.denominator));
|
||||
return dict;
|
||||
}
|
||||
|
||||
void QuantityPy::setFormat(Py::Dict arg)
|
||||
void QuantityPy::setFormat(Py::Dict arg)
|
||||
{
|
||||
QuantityFormat fmt = getQuantityPtr()->getFormat();
|
||||
|
||||
if (arg.hasKey("Precision")) {
|
||||
Py::Int prec(arg.getItem("Precision"));
|
||||
Py::Int prec(arg.getItem("Precision"));
|
||||
fmt.precision = static_cast<int>(prec);
|
||||
}
|
||||
|
||||
@@ -625,39 +661,44 @@ void QuantityPy::setFormat(Py::Dict arg)
|
||||
Py::Object item = arg.getItem("NumberFormat");
|
||||
if (item.isNumeric()) {
|
||||
int format = static_cast<int>(Py::Int(item));
|
||||
if (format < 0 || format > QuantityFormat::Scientific)
|
||||
if (format < 0 || format > QuantityFormat::Scientific) {
|
||||
throw Py::ValueError("Invalid format value");
|
||||
}
|
||||
fmt.format = static_cast<QuantityFormat::NumberFormat>(format);
|
||||
}
|
||||
else {
|
||||
Py::Char form(item);
|
||||
std::string fmtstr = static_cast<std::string>(Py::String(form));
|
||||
if (fmtstr.size() != 1)
|
||||
if (fmtstr.size() != 1) {
|
||||
throw Py::ValueError("Invalid format character");
|
||||
}
|
||||
|
||||
bool ok = false;
|
||||
fmt.format = Base::QuantityFormat::toFormat(fmtstr[0], &ok);
|
||||
if (!ok)
|
||||
if (!ok) {
|
||||
throw Py::ValueError("Invalid format character");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (arg.hasKey("Denominator")) {
|
||||
Py::Int denom(arg.getItem("Denominator"));
|
||||
Py::Int denom(arg.getItem("Denominator"));
|
||||
int fracInch = static_cast<int>(denom);
|
||||
// check that the value is positive and a power of 2
|
||||
if (fracInch <= 0)
|
||||
if (fracInch <= 0) {
|
||||
throw Py::ValueError("Denominator must be higher than zero");
|
||||
}
|
||||
// bitwise check
|
||||
if (fracInch & (fracInch - 1))
|
||||
if (fracInch & (fracInch - 1)) {
|
||||
throw Py::ValueError("Denominator must be a power of two");
|
||||
}
|
||||
fmt.denominator = fracInch;
|
||||
}
|
||||
|
||||
getQuantityPtr()->setFormat(fmt);
|
||||
}
|
||||
|
||||
PyObject *QuantityPy::getCustomAttributes(const char* attr) const
|
||||
PyObject* QuantityPy::getCustomAttributes(const char* attr) const
|
||||
{
|
||||
QuantityPy* py = nullptr;
|
||||
if (strcmp(attr, "Torr") == 0) {
|
||||
@@ -691,39 +732,38 @@ int QuantityPy::setCustomAttributes(const char* /*attr*/, PyObject* /*obj*/)
|
||||
return 0;
|
||||
}
|
||||
|
||||
PyObject * QuantityPy::number_invert_handler (PyObject* /*self*/)
|
||||
PyObject* QuantityPy::number_invert_handler(PyObject* /*self*/)
|
||||
{
|
||||
PyErr_SetString(PyExc_TypeError, "bad operand type for unary ~");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
PyObject * QuantityPy::number_lshift_handler (PyObject* /*self*/, PyObject* /*other*/)
|
||||
PyObject* QuantityPy::number_lshift_handler(PyObject* /*self*/, PyObject* /*other*/)
|
||||
{
|
||||
PyErr_SetString(PyExc_TypeError, "unsupported operand type(s) for <<");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
PyObject * QuantityPy::number_rshift_handler (PyObject* /*self*/, PyObject* /*other*/)
|
||||
PyObject* QuantityPy::number_rshift_handler(PyObject* /*self*/, PyObject* /*other*/)
|
||||
{
|
||||
PyErr_SetString(PyExc_TypeError, "unsupported operand type(s) for >>");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
PyObject * QuantityPy::number_and_handler (PyObject* /*self*/, PyObject* /*other*/)
|
||||
PyObject* QuantityPy::number_and_handler(PyObject* /*self*/, PyObject* /*other*/)
|
||||
{
|
||||
PyErr_SetString(PyExc_TypeError, "unsupported operand type(s) for &");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
PyObject * QuantityPy::number_xor_handler (PyObject* /*self*/, PyObject* /*other*/)
|
||||
PyObject* QuantityPy::number_xor_handler(PyObject* /*self*/, PyObject* /*other*/)
|
||||
{
|
||||
PyErr_SetString(PyExc_TypeError, "unsupported operand type(s) for ^");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
PyObject * QuantityPy::number_or_handler (PyObject* /*self*/, PyObject* /*other*/)
|
||||
PyObject* QuantityPy::number_or_handler(PyObject* /*self*/, PyObject* /*other*/)
|
||||
{
|
||||
PyErr_SetString(PyExc_TypeError, "unsupported operand type(s) for |");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
|
||||
#ifndef _PreComp_
|
||||
#include <memory>
|
||||
# include <xercesc/sax2/XMLReaderFactory.hpp>
|
||||
#include <xercesc/sax2/XMLReaderFactory.hpp>
|
||||
#endif
|
||||
|
||||
#include <locale>
|
||||
@@ -57,7 +57,7 @@ using namespace std;
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
Base::XMLReader::XMLReader(const char* FileName, std::istream& str)
|
||||
: _File(FileName)
|
||||
: _File(FileName)
|
||||
{
|
||||
#ifdef _MSC_VER
|
||||
str.imbue(std::locale::empty());
|
||||
@@ -66,7 +66,7 @@ Base::XMLReader::XMLReader(const char* FileName, std::istream& str)
|
||||
#endif
|
||||
|
||||
// create the parser
|
||||
parser = XMLReaderFactory::createXMLReader();
|
||||
parser = XMLReaderFactory::createXMLReader(); // NOLINT
|
||||
|
||||
parser->setContentHandler(this);
|
||||
parser->setLexicalHandler(this);
|
||||
@@ -78,14 +78,12 @@ Base::XMLReader::XMLReader(const char* FileName, std::istream& str)
|
||||
}
|
||||
catch (const XMLException& toCatch) {
|
||||
char* message = XMLString::transcode(toCatch.getMessage());
|
||||
cerr << "Exception message is: \n"
|
||||
<< message << "\n";
|
||||
cerr << "Exception message is: \n" << message << "\n";
|
||||
XMLString::release(&message);
|
||||
}
|
||||
catch (const SAXParseException& toCatch) {
|
||||
char* message = XMLString::transcode(toCatch.getMessage());
|
||||
cerr << "Exception message is: \n"
|
||||
<< message << "\n";
|
||||
cerr << "Exception message is: \n" << message << "\n";
|
||||
XMLString::release(&message);
|
||||
}
|
||||
#ifndef FC_DEBUG
|
||||
@@ -131,7 +129,7 @@ unsigned long Base::XMLReader::getAttributeAsUnsigned(const char* AttrName) cons
|
||||
AttrMapType::const_iterator pos = AttrMap.find(AttrName);
|
||||
|
||||
if (pos != AttrMap.end()) {
|
||||
return strtoul(pos->second.c_str(),nullptr,10);
|
||||
return strtoul(pos->second.c_str(), nullptr, 10);
|
||||
}
|
||||
else {
|
||||
// wrong name, use hasAttribute if not sure!
|
||||
@@ -141,7 +139,7 @@ unsigned long Base::XMLReader::getAttributeAsUnsigned(const char* AttrName) cons
|
||||
}
|
||||
}
|
||||
|
||||
double Base::XMLReader::getAttributeAsFloat (const char* AttrName) const
|
||||
double Base::XMLReader::getAttributeAsFloat(const char* AttrName) const
|
||||
{
|
||||
AttrMapType::const_iterator pos = AttrMap.find(AttrName);
|
||||
|
||||
@@ -156,7 +154,7 @@ double Base::XMLReader::getAttributeAsFloat (const char* AttrName) const
|
||||
}
|
||||
}
|
||||
|
||||
const char* Base::XMLReader::getAttribute (const char* AttrName) const
|
||||
const char* Base::XMLReader::getAttribute(const char* AttrName) const
|
||||
{
|
||||
AttrMapType::const_iterator pos = AttrMap.find(AttrName);
|
||||
|
||||
@@ -171,7 +169,7 @@ const char* Base::XMLReader::getAttribute (const char* AttrName) const
|
||||
}
|
||||
}
|
||||
|
||||
bool Base::XMLReader::hasAttribute (const char* AttrName) const
|
||||
bool Base::XMLReader::hasAttribute(const char* AttrName) const
|
||||
{
|
||||
return AttrMap.find(AttrName) != AttrMap.end();
|
||||
}
|
||||
@@ -205,11 +203,14 @@ bool Base::XMLReader::read()
|
||||
|
||||
void Base::XMLReader::readElement(const char* ElementName)
|
||||
{
|
||||
bool ok{};
|
||||
bool ok {};
|
||||
int currentLevel = Level;
|
||||
std::string currentName = LocalName;
|
||||
do {
|
||||
ok = read(); if (!ok) break;
|
||||
ok = read();
|
||||
if (!ok) {
|
||||
break;
|
||||
}
|
||||
if (ReadType == EndElement && currentName == LocalName && currentLevel >= Level) {
|
||||
// we have reached the end of the element when calling this method
|
||||
// thus we must stop reading on.
|
||||
@@ -219,32 +220,37 @@ void Base::XMLReader::readElement(const char* ElementName)
|
||||
// the end of the document has been reached but we still try to continue on reading
|
||||
throw Base::XMLParseException("End of document reached");
|
||||
}
|
||||
} while ((ReadType != StartElement && ReadType != StartEndElement) ||
|
||||
(ElementName && LocalName != ElementName));
|
||||
} while ((ReadType != StartElement && ReadType != StartEndElement)
|
||||
|| (ElementName && LocalName != ElementName));
|
||||
}
|
||||
|
||||
bool Base::XMLReader::readNextElement()
|
||||
{
|
||||
bool ok{};
|
||||
bool ok {};
|
||||
while (true) {
|
||||
ok = read();
|
||||
if (!ok)
|
||||
if (!ok) {
|
||||
break;
|
||||
if (ReadType == StartElement)
|
||||
}
|
||||
if (ReadType == StartElement) {
|
||||
break;
|
||||
if (ReadType == StartEndElement)
|
||||
}
|
||||
if (ReadType == StartEndElement) {
|
||||
break;
|
||||
if (ReadType == EndElement)
|
||||
}
|
||||
if (ReadType == EndElement) {
|
||||
break;
|
||||
if (ReadType == EndDocument)
|
||||
}
|
||||
if (ReadType == EndDocument) {
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
return (ReadType == StartElement ||
|
||||
ReadType == StartEndElement);
|
||||
return (ReadType == StartElement || ReadType == StartEndElement);
|
||||
}
|
||||
|
||||
int Base::XMLReader::level() const {
|
||||
int Base::XMLReader::level() const
|
||||
{
|
||||
return Level;
|
||||
}
|
||||
|
||||
@@ -266,11 +272,8 @@ bool Base::XMLReader::isEndOfDocument() const
|
||||
void Base::XMLReader::readEndElement(const char* ElementName, int level)
|
||||
{
|
||||
// if we are already at the end of the current element
|
||||
if (ReadType == EndElement
|
||||
&& ElementName
|
||||
&& LocalName == ElementName
|
||||
&& (level<0 || level==Level))
|
||||
{
|
||||
if (ReadType == EndElement && ElementName && LocalName == ElementName
|
||||
&& (level < 0 || level == Level)) {
|
||||
return;
|
||||
}
|
||||
else if (ReadType == EndDocument) {
|
||||
@@ -278,15 +281,17 @@ void Base::XMLReader::readEndElement(const char* ElementName, int level)
|
||||
throw Base::XMLParseException("End of document reached");
|
||||
}
|
||||
|
||||
bool ok{};
|
||||
bool ok {};
|
||||
do {
|
||||
ok = read(); if (!ok) break;
|
||||
if (ReadType == EndDocument)
|
||||
ok = read();
|
||||
if (!ok) {
|
||||
break;
|
||||
}
|
||||
if (ReadType == EndDocument) {
|
||||
break;
|
||||
}
|
||||
} while (ReadType != EndElement
|
||||
|| (ElementName
|
||||
&& (LocalName != ElementName
|
||||
|| (level>=0 && level!=Level))));
|
||||
|| (ElementName && (LocalName != ElementName || (level >= 0 && level != Level))));
|
||||
}
|
||||
|
||||
void Base::XMLReader::readCharacters(const char* filename, CharStreamFormat format)
|
||||
@@ -377,8 +382,9 @@ std::istream& Base::XMLReader::beginCharStream(CharStreamFormat format)
|
||||
|
||||
CharStream = std::make_unique<boost::iostreams::filtering_istream>();
|
||||
auto* filteringStream = dynamic_cast<boost::iostreams::filtering_istream*>(CharStream.get());
|
||||
if(format == CharStreamFormat::Base64Encoded) {
|
||||
filteringStream->push(base64_decoder(Base::base64DefaultBufferSize, Base64ErrorHandling::silent));
|
||||
if (format == CharStreamFormat::Base64Encoded) {
|
||||
filteringStream->push(
|
||||
base64_decoder(Base::base64DefaultBufferSize, Base64ErrorHandling::silent));
|
||||
}
|
||||
filteringStream->push(boost::ref(*this));
|
||||
return *CharStream;
|
||||
@@ -388,19 +394,23 @@ void Base::XMLReader::readBinFile(const char* filename)
|
||||
{
|
||||
Base::FileInfo fi(filename);
|
||||
Base::ofstream to(fi, std::ios::out | std::ios::binary);
|
||||
if (!to)
|
||||
if (!to) {
|
||||
throw Base::FileException("XMLReader::readBinFile() Could not open file!");
|
||||
}
|
||||
|
||||
bool ok{};
|
||||
bool ok {};
|
||||
do {
|
||||
ok = read(); if (!ok) break;
|
||||
ok = read();
|
||||
if (!ok) {
|
||||
break;
|
||||
}
|
||||
} while (ReadType != EndCDATA);
|
||||
|
||||
to << Base::base64_decode(Characters);
|
||||
to.close();
|
||||
}
|
||||
|
||||
void Base::XMLReader::readFiles(zipios::ZipInputStream &zipstream) const
|
||||
void Base::XMLReader::readFiles(zipios::ZipInputStream& zipstream) const
|
||||
{
|
||||
// It's possible that not all objects inside the document could be created, e.g. if a module
|
||||
// is missing that would know these object types. So, there may be data files inside the zip
|
||||
@@ -423,26 +433,29 @@ void Base::XMLReader::readFiles(zipios::ZipInputStream &zipstream) const
|
||||
Base::SequencerLauncher seq("Importing project files...", FileList.size());
|
||||
while (entry->isValid() && it != FileList.end()) {
|
||||
std::vector<FileEntry>::const_iterator jt = it;
|
||||
// Check if the current entry is registered, otherwise check the next registered files as soon as
|
||||
// both file names match
|
||||
while (jt != FileList.end() && entry->getName() != jt->FileName)
|
||||
// Check if the current entry is registered, otherwise check the next registered files as
|
||||
// soon as both file names match
|
||||
while (jt != FileList.end() && entry->getName() != jt->FileName) {
|
||||
++jt;
|
||||
}
|
||||
// If this condition is true both file names match and we can read-in the data, otherwise
|
||||
// no file name for the current entry in the zip was registered.
|
||||
if (jt != FileList.end()) {
|
||||
try {
|
||||
Base::Reader reader(zipstream, jt->FileName, FileVersion);
|
||||
jt->Object->RestoreDocFile(reader);
|
||||
if (reader.getLocalReader())
|
||||
if (reader.getLocalReader()) {
|
||||
reader.getLocalReader()->readFiles(zipstream);
|
||||
}
|
||||
}
|
||||
catch(...) {
|
||||
catch (...) {
|
||||
// For any exception we just continue with the next file.
|
||||
// It doesn't matter if the last reader has read more or
|
||||
// less data than the file size would allow.
|
||||
// All what we need to do is to notify the user about the
|
||||
// failure.
|
||||
Base::Console().Error("Reading failed from embedded file: %s\n", entry->toString().c_str());
|
||||
Base::Console().Error("Reading failed from embedded file: %s\n",
|
||||
entry->toString().c_str());
|
||||
}
|
||||
// Go to the next registered file name
|
||||
it = jt + 1;
|
||||
@@ -461,14 +474,14 @@ void Base::XMLReader::readFiles(zipios::ZipInputStream &zipstream) const
|
||||
}
|
||||
}
|
||||
|
||||
const char *Base::XMLReader::addFile(const char* Name, Base::Persistence *Object)
|
||||
const char* Base::XMLReader::addFile(const char* Name, Base::Persistence* Object)
|
||||
{
|
||||
FileEntry temp;
|
||||
temp.FileName = Name;
|
||||
temp.Object = Object;
|
||||
|
||||
FileList.push_back(temp);
|
||||
FileNames.push_back( temp.FileName );
|
||||
FileNames.push_back(temp.FileName);
|
||||
|
||||
return Name;
|
||||
}
|
||||
@@ -478,12 +491,13 @@ const std::vector<std::string>& Base::XMLReader::getFilenames() const
|
||||
return FileNames;
|
||||
}
|
||||
|
||||
bool Base::XMLReader::isRegistered(Base::Persistence *Object) const
|
||||
bool Base::XMLReader::isRegistered(Base::Persistence* Object) const
|
||||
{
|
||||
if (Object) {
|
||||
for (const auto & it : FileList) {
|
||||
if (it.Object == Object)
|
||||
for (const auto& it : FileList) {
|
||||
if (it.Object == Object) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -491,8 +505,7 @@ bool Base::XMLReader::isRegistered(Base::Persistence *Object) const
|
||||
}
|
||||
|
||||
void Base::XMLReader::addName(const char*, const char*)
|
||||
{
|
||||
}
|
||||
{}
|
||||
|
||||
const char* Base::XMLReader::getName(const char* name) const
|
||||
{
|
||||
@@ -517,9 +530,12 @@ void Base::XMLReader::endDocument()
|
||||
ReadType = EndDocument;
|
||||
}
|
||||
|
||||
void Base::XMLReader::startElement(const XMLCh* const /*uri*/, const XMLCh* const localname, const XMLCh* const /*qname*/, const XERCES_CPP_NAMESPACE_QUALIFIER Attributes& attrs)
|
||||
void Base::XMLReader::startElement(const XMLCh* const /*uri*/,
|
||||
const XMLCh* const localname,
|
||||
const XMLCh* const /*qname*/,
|
||||
const XERCES_CPP_NAMESPACE_QUALIFIER Attributes& attrs)
|
||||
{
|
||||
Level++; // new scope
|
||||
Level++; // new scope
|
||||
LocalName = StrX(localname).c_str();
|
||||
|
||||
// saving attributes of the current scope, delete all previously stored ones
|
||||
@@ -531,45 +547,49 @@ void Base::XMLReader::startElement(const XMLCh* const /*uri*/, const XMLCh* cons
|
||||
ReadType = StartElement;
|
||||
}
|
||||
|
||||
void Base::XMLReader::endElement (const XMLCh* const /*uri*/, const XMLCh *const localname, const XMLCh *const /*qname*/)
|
||||
void Base::XMLReader::endElement(const XMLCh* const /*uri*/,
|
||||
const XMLCh* const localname,
|
||||
const XMLCh* const /*qname*/)
|
||||
{
|
||||
Level--; // end of scope
|
||||
Level--; // end of scope
|
||||
LocalName = StrX(localname).c_str();
|
||||
|
||||
if (ReadType == StartElement)
|
||||
if (ReadType == StartElement) {
|
||||
ReadType = StartEndElement;
|
||||
else
|
||||
}
|
||||
else {
|
||||
ReadType = EndElement;
|
||||
}
|
||||
}
|
||||
|
||||
void Base::XMLReader::startCDATA ()
|
||||
void Base::XMLReader::startCDATA()
|
||||
{
|
||||
ReadType = StartCDATA;
|
||||
}
|
||||
|
||||
void Base::XMLReader::endCDATA ()
|
||||
void Base::XMLReader::endCDATA()
|
||||
{
|
||||
ReadType = EndCDATA;
|
||||
}
|
||||
|
||||
void Base::XMLReader::characters(const XMLCh* const chars, const XMLSize_t length)
|
||||
void Base::XMLReader::characters(const XMLCh* const chars, const XMLSize_t length)
|
||||
{
|
||||
Characters = StrX(chars).c_str();
|
||||
ReadType = Chars;
|
||||
CharacterCount += length;
|
||||
}
|
||||
|
||||
void Base::XMLReader::ignorableWhitespace( const XMLCh* const /*chars*/, const XMLSize_t /*length*/)
|
||||
void Base::XMLReader::ignorableWhitespace(const XMLCh* const /*chars*/, const XMLSize_t /*length*/)
|
||||
{
|
||||
//fSpaceCount += length;
|
||||
// fSpaceCount += length;
|
||||
}
|
||||
|
||||
void Base::XMLReader::resetDocument()
|
||||
{
|
||||
//fAttrCount = 0;
|
||||
//fCharacterCount = 0;
|
||||
//fElementCount = 0;
|
||||
//fSpaceCount = 0;
|
||||
// fAttrCount = 0;
|
||||
// fCharacterCount = 0;
|
||||
// fElementCount = 0;
|
||||
// fSpaceCount = 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -580,9 +600,8 @@ void Base::XMLReader::error(const XERCES_CPP_NAMESPACE_QUALIFIER SAXParseExcepti
|
||||
{
|
||||
// print some details to error output and throw an
|
||||
// exception to abort the parsing
|
||||
cerr << "Error at file " << StrX(e.getSystemId())
|
||||
<< ", line " << e.getLineNumber()
|
||||
<< ", char " << e.getColumnNumber() << endl;
|
||||
cerr << "Error at file " << StrX(e.getSystemId()) << ", line " << e.getLineNumber() << ", char "
|
||||
<< e.getColumnNumber() << endl;
|
||||
throw e;
|
||||
}
|
||||
|
||||
@@ -590,8 +609,7 @@ void Base::XMLReader::fatalError(const XERCES_CPP_NAMESPACE_QUALIFIER SAXParseEx
|
||||
{
|
||||
// print some details to error output and throw an
|
||||
// exception to abort the parsing
|
||||
cerr << "Fatal Error at file " << StrX(e.getSystemId())
|
||||
<< ", line " << e.getLineNumber()
|
||||
cerr << "Fatal Error at file " << StrX(e.getSystemId()) << ", line " << e.getLineNumber()
|
||||
<< ", char " << e.getColumnNumber() << endl;
|
||||
throw e;
|
||||
}
|
||||
@@ -600,15 +618,13 @@ void Base::XMLReader::warning(const XERCES_CPP_NAMESPACE_QUALIFIER SAXParseExcep
|
||||
{
|
||||
// print some details to error output and throw an
|
||||
// exception to abort the parsing
|
||||
cerr << "Warning at file " << StrX(e.getSystemId())
|
||||
<< ", line " << e.getLineNumber()
|
||||
<< ", char " << e.getColumnNumber() << endl;
|
||||
throw e;
|
||||
cerr << "Warning at file " << StrX(e.getSystemId()) << ", line " << e.getLineNumber()
|
||||
<< ", char " << e.getColumnNumber() << endl;
|
||||
throw e;
|
||||
}
|
||||
|
||||
void Base::XMLReader::resetErrors()
|
||||
{
|
||||
}
|
||||
{}
|
||||
|
||||
bool Base::XMLReader::testStatus(ReaderStatus pos) const
|
||||
{
|
||||
@@ -648,10 +664,13 @@ void Base::XMLReader::clearPartialRestoreObject()
|
||||
|
||||
// ----------------------------------------------------------
|
||||
|
||||
// NOLINTNEXTLINE
|
||||
Base::Reader::Reader(std::istream& str, const std::string& name, int version)
|
||||
: std::istream(str.rdbuf()), _str(str), _name(name), fileVersion(version)
|
||||
{
|
||||
}
|
||||
: std::istream(str.rdbuf())
|
||||
, _str(str)
|
||||
, _name(name)
|
||||
, fileVersion(version)
|
||||
{}
|
||||
|
||||
std::string Base::Reader::getFileName() const
|
||||
{
|
||||
@@ -675,5 +694,5 @@ void Base::Reader::initLocalReader(std::shared_ptr<Base::XMLReader> reader)
|
||||
|
||||
std::shared_ptr<Base::XMLReader> Base::Reader::getLocalReader() const
|
||||
{
|
||||
return(this->localreader);
|
||||
return (this->localreader);
|
||||
}
|
||||
|
||||
@@ -38,13 +38,14 @@
|
||||
#include "FileInfo.h"
|
||||
|
||||
|
||||
namespace zipios {
|
||||
namespace zipios
|
||||
{
|
||||
class ZipInputStream;
|
||||
}
|
||||
|
||||
XERCES_CPP_NAMESPACE_BEGIN
|
||||
class DefaultHandler;
|
||||
class SAX2XMLReader;
|
||||
class DefaultHandler;
|
||||
class SAX2XMLReader;
|
||||
XERCES_CPP_NAMESPACE_END
|
||||
|
||||
namespace Base
|
||||
@@ -88,9 +89,9 @@ void PropertyContainer::Save (short indent,std::ostream &str)
|
||||
std::map<std::string,Property*>::iterator it;
|
||||
for(it = Map.begin(); it != Map.end(); ++it)
|
||||
{
|
||||
str << ind(indent+1) << "<Property name=\"" << it->first << "\" type=\"" << it->second->getTypeId().getName() << "\">" ;
|
||||
it->second->Save(indent+2,str);
|
||||
str << "</Property>" << endl;
|
||||
str << ind(indent+1) << "<Property name=\"" << it->first << "\" type=\"" <<
|
||||
it->second->getTypeId().getName() << "\">" ; it->second->Save(indent+2,str); str << "</Property>" <<
|
||||
endl;
|
||||
}
|
||||
str << ind(indent) << "</Properties>" << endl;
|
||||
}
|
||||
@@ -116,14 +117,17 @@ void PropertyContainer::Restore(Base::Reader &reader)
|
||||
* \see Base::Persistence
|
||||
* \author Juergen Riegel
|
||||
*/
|
||||
class BaseExport XMLReader : public XERCES_CPP_NAMESPACE_QUALIFIER DefaultHandler
|
||||
class BaseExport XMLReader: public XERCES_CPP_NAMESPACE_QUALIFIER DefaultHandler
|
||||
{
|
||||
public:
|
||||
enum ReaderStatus {
|
||||
PartialRestore = 0, // This bit indicates that a partial restore took place somewhere in this Document
|
||||
PartialRestoreInDocumentObject = 1, // This bit is local to the DocumentObject being read indicating a partial restore therein
|
||||
PartialRestoreInProperty = 2, // Local to the Property
|
||||
PartialRestoreInObject = 3 // Local to the object partially restored itself
|
||||
enum ReaderStatus
|
||||
{
|
||||
PartialRestore =
|
||||
0, // This bit indicates that a partial restore took place somewhere in this Document
|
||||
PartialRestoreInDocumentObject = 1, // This bit is local to the DocumentObject being read
|
||||
// indicating a partial restore therein
|
||||
PartialRestoreInProperty = 2, // Local to the Property
|
||||
PartialRestoreInObject = 3 // Local to the object partially restored itself
|
||||
};
|
||||
/// open the file and read the first element
|
||||
XMLReader(const char* FileName, std::istream&);
|
||||
@@ -136,9 +140,18 @@ public:
|
||||
std::streamsize read(char_type* s, std::streamsize n);
|
||||
//@}
|
||||
|
||||
bool isValid() const { return _valid; }
|
||||
bool isVerbose() const { return _verbose; }
|
||||
void setVerbose(bool on) { _verbose = on; }
|
||||
bool isValid() const
|
||||
{
|
||||
return _valid;
|
||||
}
|
||||
bool isVerbose() const
|
||||
{
|
||||
return _verbose;
|
||||
}
|
||||
void setVerbose(bool on)
|
||||
{
|
||||
_verbose = on;
|
||||
}
|
||||
|
||||
/** @name Parser handling */
|
||||
//@{
|
||||
@@ -156,8 +169,9 @@ public:
|
||||
/// return true if the end of the document is reached, false otherwise
|
||||
bool isEndOfDocument() const;
|
||||
|
||||
/// read until a start element is found (\<name\>) or start-end element (\<name/\>) (with special name if given)
|
||||
void readElement (const char* ElementName=nullptr);
|
||||
/// read until a start element is found (\<name\>) or start-end element (\<name/\>) (with
|
||||
/// special name if given)
|
||||
void readElement(const char* ElementName = nullptr);
|
||||
|
||||
/// Read in the next element. Return true if it succeeded and false otherwise
|
||||
bool readNextElement();
|
||||
@@ -176,7 +190,7 @@ public:
|
||||
* child element may have the same name as its parent, otherwise, using \c
|
||||
* ElementName is enough.
|
||||
*/
|
||||
void readEndElement(const char* ElementName=nullptr, int level=-1);
|
||||
void readEndElement(const char* ElementName = nullptr, int level = -1);
|
||||
/// read until characters are found
|
||||
void readCharacters(const char* filename, CharStreamFormat format = CharStreamFormat::Raw);
|
||||
|
||||
@@ -186,11 +200,11 @@ public:
|
||||
* auto destroyed when you call with readElement() or readEndElement(), or
|
||||
* you can end it explicitly with endCharStream().
|
||||
*/
|
||||
std::istream &beginCharStream(CharStreamFormat format = CharStreamFormat::Raw);
|
||||
std::istream& beginCharStream(CharStreamFormat format = CharStreamFormat::Raw);
|
||||
/// Manually end the current character stream
|
||||
void endCharStream();
|
||||
/// Obtain the current character stream
|
||||
std::istream &charStream();
|
||||
std::istream& charStream();
|
||||
//@}
|
||||
|
||||
/// read binary file
|
||||
@@ -215,23 +229,23 @@ public:
|
||||
/** @name additional file reading */
|
||||
//@{
|
||||
/// add a read request of a persistent object
|
||||
const char *addFile(const char* Name, Base::Persistence *Object);
|
||||
const char* addFile(const char* Name, Base::Persistence* Object);
|
||||
/// process the requested file writes
|
||||
void readFiles(zipios::ZipInputStream &zipstream) const;
|
||||
void readFiles(zipios::ZipInputStream& zipstream) const;
|
||||
/// get all registered file names
|
||||
const std::vector<std::string>& getFilenames() const;
|
||||
bool isRegistered(Base::Persistence *Object) const;
|
||||
bool isRegistered(Base::Persistence* Object) const;
|
||||
virtual void addName(const char*, const char*);
|
||||
virtual const char* getName(const char*) const;
|
||||
virtual bool doNameMapping() const;
|
||||
//@}
|
||||
|
||||
/// Schema Version of the document
|
||||
int DocumentSchema{0};
|
||||
int DocumentSchema {0};
|
||||
/// Version of FreeCAD that wrote this document
|
||||
std::string ProgramVersion;
|
||||
/// Version of the file format
|
||||
int FileVersion{0};
|
||||
int FileVersion {0};
|
||||
|
||||
/// sets simultaneously the global and local PartialRestore bits
|
||||
void setPartialRestore(bool on);
|
||||
@@ -256,16 +270,21 @@ protected:
|
||||
//@{
|
||||
void startDocument() override;
|
||||
void endDocument() override;
|
||||
void startElement(const XMLCh* const uri, const XMLCh* const localname, const XMLCh* const qname, const XERCES_CPP_NAMESPACE_QUALIFIER Attributes& attrs) override;
|
||||
void endElement (const XMLCh* const uri, const XMLCh *const localname, const XMLCh *const qname) override;
|
||||
void characters (const XMLCh* const chars, const XMLSize_t length) override;
|
||||
void startElement(const XMLCh* const uri,
|
||||
const XMLCh* const localname,
|
||||
const XMLCh* const qname,
|
||||
const XERCES_CPP_NAMESPACE_QUALIFIER Attributes& attrs) override;
|
||||
void endElement(const XMLCh* const uri,
|
||||
const XMLCh* const localname,
|
||||
const XMLCh* const qname) override;
|
||||
void characters(const XMLCh* const chars, const XMLSize_t length) override;
|
||||
void ignorableWhitespace(const XMLCh* const chars, const XMLSize_t length) override;
|
||||
//@}
|
||||
|
||||
/** @name Lexical handler */
|
||||
//@{
|
||||
void startCDATA () override;
|
||||
void endCDATA () override;
|
||||
void startCDATA() override;
|
||||
void endCDATA() override;
|
||||
//@}
|
||||
|
||||
/** @name Document handler */
|
||||
@@ -286,16 +305,17 @@ protected:
|
||||
//@}
|
||||
|
||||
private:
|
||||
int Level{0};
|
||||
int Level {0};
|
||||
std::string LocalName;
|
||||
std::string Characters;
|
||||
unsigned int CharacterCount{0};
|
||||
std::streamsize CharacterOffset{-1};
|
||||
unsigned int CharacterCount {0};
|
||||
std::streamsize CharacterOffset {-1};
|
||||
|
||||
std::map<std::string,std::string> AttrMap;
|
||||
using AttrMapType = std::map<std::string,std::string>;
|
||||
std::map<std::string, std::string> AttrMap;
|
||||
using AttrMapType = std::map<std::string, std::string>;
|
||||
|
||||
enum {
|
||||
enum
|
||||
{
|
||||
None = 0,
|
||||
Chars,
|
||||
StartDocument,
|
||||
@@ -305,18 +325,19 @@ private:
|
||||
EndElement,
|
||||
StartCDATA,
|
||||
EndCDATA
|
||||
} ReadType{None};
|
||||
} ReadType {None};
|
||||
|
||||
|
||||
FileInfo _File;
|
||||
XERCES_CPP_NAMESPACE_QUALIFIER SAX2XMLReader* parser;
|
||||
XERCES_CPP_NAMESPACE_QUALIFIER XMLPScanToken token;
|
||||
bool _valid{false};
|
||||
bool _verbose{true};
|
||||
bool _valid {false};
|
||||
bool _verbose {true};
|
||||
|
||||
struct FileEntry {
|
||||
struct FileEntry
|
||||
{
|
||||
std::string FileName;
|
||||
Base::Persistence *Object;
|
||||
Base::Persistence* Object;
|
||||
};
|
||||
std::vector<FileEntry> FileList;
|
||||
std::vector<std::string> FileNames;
|
||||
@@ -326,7 +347,7 @@ private:
|
||||
std::unique_ptr<std::istream> CharStream;
|
||||
};
|
||||
|
||||
class BaseExport Reader : public std::istream
|
||||
class BaseExport Reader: public std::istream
|
||||
{
|
||||
public:
|
||||
Reader(std::istream&, const std::string&, int version);
|
||||
@@ -343,7 +364,7 @@ private:
|
||||
std::shared_ptr<Base::XMLReader> localreader;
|
||||
};
|
||||
|
||||
}
|
||||
} // namespace Base
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -29,7 +29,8 @@
|
||||
#include <FCGlobal.h>
|
||||
#endif
|
||||
|
||||
namespace Base {
|
||||
namespace Base
|
||||
{
|
||||
|
||||
// forward declarations
|
||||
class Matrix4D;
|
||||
@@ -50,18 +51,18 @@ public:
|
||||
|
||||
/** Methods to get or set rotations. */
|
||||
//@{
|
||||
const double * getValue() const;
|
||||
void getValue(double & q0, double & q1, double & q2, double & q3) const;
|
||||
const double* getValue() const;
|
||||
void getValue(double& q0, double& q1, double& q2, double& q3) const;
|
||||
void setValue(const double q0, const double q1, const double q2, const double q3);
|
||||
/// If not a null quaternion then \a axis will be normalized
|
||||
void getValue(Vector3d & axis, double & rfAngle) const;
|
||||
void getValue(Vector3d& axis, double& rfAngle) const;
|
||||
/// Does the same as the method above unless normalizing the axis.
|
||||
void getRawValue(Vector3d & axis, double & rfAngle) const;
|
||||
void getValue(Matrix4D & matrix) const;
|
||||
void getRawValue(Vector3d& axis, double& rfAngle) const;
|
||||
void getValue(Matrix4D& matrix) const;
|
||||
void setValue(const double q[4]);
|
||||
void setValue(const Matrix4D& matrix);
|
||||
void setValue(const Vector3d & axis, const double fAngle);
|
||||
void setValue(const Vector3d & rotateFrom, const Vector3d & rotateTo);
|
||||
void setValue(const Vector3d& axis, const double fAngle);
|
||||
void setValue(const Vector3d& rotateFrom, const Vector3d& rotateTo);
|
||||
/// Euler angles in yaw,pitch,roll notation
|
||||
void setYawPitchRoll(double y, double p, double r);
|
||||
/// Euler angles in yaw,pitch,roll notation
|
||||
@@ -109,9 +110,9 @@ public:
|
||||
|
||||
EulerSequenceLast,
|
||||
};
|
||||
static const char *eulerSequenceName(EulerSequence seq);
|
||||
static EulerSequence eulerSequenceFromName(const char *name);
|
||||
void getEulerAngles(EulerSequence seq, double &alpha, double &beta, double &gamma) const;
|
||||
static const char* eulerSequenceName(EulerSequence seq);
|
||||
static EulerSequence eulerSequenceFromName(const char* name);
|
||||
void getEulerAngles(EulerSequence seq, double& alpha, double& beta, double& gamma) const;
|
||||
void setEulerAngles(EulerSequence seq, double alpha, double beta, double gamma);
|
||||
bool isIdentity() const;
|
||||
bool isIdentity(double tol) const;
|
||||
@@ -122,32 +123,38 @@ public:
|
||||
|
||||
/** Invert rotations. */
|
||||
//@{
|
||||
Rotation & invert();
|
||||
Rotation& invert();
|
||||
Rotation inverse() const;
|
||||
//@}
|
||||
|
||||
/** Operators. */
|
||||
//@{
|
||||
Rotation & operator*=(const Rotation & q);
|
||||
Rotation operator *(const Rotation & q) const;
|
||||
bool operator==(const Rotation & q) const;
|
||||
bool operator!=(const Rotation & q) const;
|
||||
double & operator [] (unsigned short usIndex){return quat[usIndex];}
|
||||
const double & operator [] (unsigned short usIndex) const{return quat[usIndex];}
|
||||
void operator = (const Rotation&);
|
||||
Rotation& operator*=(const Rotation& q);
|
||||
Rotation operator*(const Rotation& q) const;
|
||||
bool operator==(const Rotation& q) const;
|
||||
bool operator!=(const Rotation& q) const;
|
||||
double& operator[](unsigned short usIndex)
|
||||
{
|
||||
return quat[usIndex];
|
||||
}
|
||||
const double& operator[](unsigned short usIndex) const
|
||||
{
|
||||
return quat[usIndex];
|
||||
}
|
||||
void operator=(const Rotation&);
|
||||
|
||||
Rotation& multRight(const Base::Rotation& q);
|
||||
Rotation& multLeft(const Base::Rotation& q);
|
||||
|
||||
void multVec(const Vector3d & src, Vector3d & dst) const;
|
||||
Vector3d multVec(const Vector3d & src) const;
|
||||
void multVec(const Vector3f & src, Vector3f & dst) const;
|
||||
Vector3f multVec(const Vector3f & src) const;
|
||||
void multVec(const Vector3d& src, Vector3d& dst) const;
|
||||
Vector3d multVec(const Vector3d& src) const;
|
||||
void multVec(const Vector3f& src, Vector3f& dst) const;
|
||||
Vector3f multVec(const Vector3f& src) const;
|
||||
void scaleAngle(const double scaleFactor);
|
||||
//@}
|
||||
|
||||
/** Specialty constructors */
|
||||
static Rotation slerp(const Rotation & rot0, const Rotation & rot1, double t);
|
||||
static Rotation slerp(const Rotation& rot0, const Rotation& rot1, double t);
|
||||
static Rotation identity();
|
||||
|
||||
/**
|
||||
@@ -164,16 +171,19 @@ public:
|
||||
*
|
||||
* If only one vector provided is nonzero, the other two directions are picked automatically.
|
||||
*/
|
||||
static Rotation makeRotationByAxes(Vector3d xdir, Vector3d ydir, Vector3d zdir, const char* priorityOrder = "ZXY");
|
||||
static Rotation makeRotationByAxes(Vector3d xdir,
|
||||
Vector3d ydir,
|
||||
Vector3d zdir,
|
||||
const char* priorityOrder = "ZXY");
|
||||
|
||||
private:
|
||||
void normalize();
|
||||
void evaluateVector ();
|
||||
void evaluateVector();
|
||||
double quat[4];
|
||||
Vector3d _axis; // the axis kept not to lose direction when angle is 0
|
||||
double _angle; // this angle to keep the angle chosen by the user
|
||||
Vector3d _axis; // the axis kept not to lose direction when angle is 0
|
||||
double _angle; // this angle to keep the angle chosen by the user
|
||||
};
|
||||
|
||||
}
|
||||
} // namespace Base
|
||||
|
||||
#endif // BASE_ROTATION_H
|
||||
#endif // BASE_ROTATION_H
|
||||
|
||||
@@ -45,48 +45,61 @@ std::string RotationPy::representation() const
|
||||
Py::Float q3(ptr->getValue()[3]);
|
||||
std::stringstream str;
|
||||
str << "Rotation (";
|
||||
str << static_cast<std::string>(q0.repr()) << ", "
|
||||
<< static_cast<std::string>(q1.repr()) << ", "
|
||||
<< static_cast<std::string>(q2.repr()) << ", "
|
||||
str << static_cast<std::string>(q0.repr()) << ", " << static_cast<std::string>(q1.repr())
|
||||
<< ", " << static_cast<std::string>(q2.repr()) << ", "
|
||||
<< static_cast<std::string>(q3.repr());
|
||||
str << ")";
|
||||
|
||||
return str.str();
|
||||
}
|
||||
|
||||
PyObject *RotationPy::PyMake(struct _typeobject *, PyObject *, PyObject *) // Python wrapper
|
||||
PyObject* RotationPy::PyMake(struct _typeobject*, PyObject*, PyObject*) // Python wrapper
|
||||
{
|
||||
// create a new instance of RotationPy and the Twin object
|
||||
return new RotationPy(new Rotation);
|
||||
}
|
||||
|
||||
// clang-format off
|
||||
// constructor method
|
||||
int RotationPy::PyInit(PyObject* args, PyObject* kwds)
|
||||
{
|
||||
PyObject* o{};
|
||||
PyObject* o {};
|
||||
if (PyArg_ParseTuple(args, "")) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
PyErr_Clear();
|
||||
if (PyArg_ParseTuple(args, "O!", &(Base::RotationPy::Type), &o)) {
|
||||
Base::Rotation *rot = static_cast<Base::RotationPy*>(o)->getRotationPtr();
|
||||
Base::Rotation* rot = static_cast<Base::RotationPy*>(o)->getRotationPtr();
|
||||
getRotationPtr()->setValue(rot->getValue());
|
||||
return 0;
|
||||
}
|
||||
|
||||
PyErr_Clear();
|
||||
double angle{};
|
||||
static const std::array<const char *, 3> kw_deg {"Axis", "Degree", nullptr};
|
||||
if (Base::Wrapped_ParseTupleAndKeywords(args, kwds, "O!d", kw_deg, &(Base::VectorPy::Type), &o, &angle)) {
|
||||
double angle {};
|
||||
static const std::array<const char*, 3> kw_deg {"Axis", "Degree", nullptr};
|
||||
if (Base::Wrapped_ParseTupleAndKeywords(args,
|
||||
kwds,
|
||||
"O!d",
|
||||
kw_deg,
|
||||
&(Base::VectorPy::Type),
|
||||
&o,
|
||||
&angle)) {
|
||||
// NOTE: The last parameter defines the rotation angle in degree.
|
||||
getRotationPtr()->setValue(static_cast<Base::VectorPy*>(o)->value(), Base::toRadians<double>(angle));
|
||||
getRotationPtr()->setValue(static_cast<Base::VectorPy*>(o)->value(),
|
||||
Base::toRadians<double>(angle));
|
||||
return 0;
|
||||
}
|
||||
|
||||
PyErr_Clear();
|
||||
static const std::array<const char *, 3> kw_rad {"Axis", "Radian", nullptr};
|
||||
if (Base::Wrapped_ParseTupleAndKeywords(args, kwds, "O!d", kw_rad, &(Base::VectorPy::Type), &o, &angle)) {
|
||||
static const std::array<const char*, 3> kw_rad {"Axis", "Radian", nullptr};
|
||||
if (Base::Wrapped_ParseTupleAndKeywords(args,
|
||||
kwds,
|
||||
"O!d",
|
||||
kw_rad,
|
||||
&(Base::VectorPy::Type),
|
||||
&o,
|
||||
&angle)) {
|
||||
getRotationPtr()->setValue(static_cast<Base::VectorPy*>(o)->value(), angle);
|
||||
return 0;
|
||||
}
|
||||
@@ -104,28 +117,29 @@ int RotationPy::PyInit(PyObject* args, PyObject* kwds)
|
||||
}
|
||||
|
||||
PyErr_Clear();
|
||||
double q0{}, q1{}, q2{}, q3{};
|
||||
double q0 {}, q1 {}, q2 {}, q3 {};
|
||||
if (PyArg_ParseTuple(args, "dddd", &q0, &q1, &q2, &q3)) {
|
||||
getRotationPtr()->setValue(q0, q1, q2, q3);
|
||||
return 0;
|
||||
}
|
||||
|
||||
PyErr_Clear();
|
||||
double y{}, p{}, r{};
|
||||
double y {}, p {}, r {};
|
||||
if (PyArg_ParseTuple(args, "ddd", &y, &p, &r)) {
|
||||
getRotationPtr()->setYawPitchRoll(y, p, r);
|
||||
return 0;
|
||||
}
|
||||
|
||||
PyErr_Clear();
|
||||
const char *seq{};
|
||||
double a{}, b{}, c{};
|
||||
const char* seq {};
|
||||
double a {}, b {}, c {};
|
||||
if (PyArg_ParseTuple(args, "sddd", &seq, &a, &b, &c)) {
|
||||
PY_TRY {
|
||||
getRotationPtr()->setEulerAngles(
|
||||
Rotation::eulerSequenceFromName(seq), a, b, c);
|
||||
PY_TRY
|
||||
{
|
||||
getRotationPtr()->setEulerAngles(Rotation::eulerSequenceFromName(seq), a, b, c);
|
||||
return 0;
|
||||
} _PY_CATCH(return -1)
|
||||
}
|
||||
_PY_CATCH(return -1)
|
||||
}
|
||||
|
||||
double a11 = 1.0, a12 = 0.0, a13 = 0.0, a14 = 0.0;
|
||||
@@ -135,12 +149,12 @@ int RotationPy::PyInit(PyObject* args, PyObject* kwds)
|
||||
|
||||
// try read a 4x4 matrix
|
||||
PyErr_Clear();
|
||||
if (PyArg_ParseTuple(args, "dddddddddddddddd",
|
||||
&a11, &a12, &a13, &a14,
|
||||
&a21, &a22, &a23, &a24,
|
||||
&a31, &a32, &a33, &a34,
|
||||
&a41, &a42, &a43, &a44))
|
||||
{
|
||||
if (PyArg_ParseTuple(args,
|
||||
"dddddddddddddddd",
|
||||
&a11, &a12, &a13, &a14,
|
||||
&a21, &a22, &a23, &a24,
|
||||
&a31, &a32, &a33, &a34,
|
||||
&a41, &a42, &a43, &a44)) {
|
||||
try {
|
||||
Matrix4D mtx(a11, a12, a13, a14,
|
||||
a21, a22, a23, a24,
|
||||
@@ -158,10 +172,9 @@ int RotationPy::PyInit(PyObject* args, PyObject* kwds)
|
||||
// try read a 3x3 matrix
|
||||
PyErr_Clear();
|
||||
if (PyArg_ParseTuple(args, "ddddddddd",
|
||||
&a11, &a12, &a13,
|
||||
&a21, &a22, &a23,
|
||||
&a31, &a32, &a33))
|
||||
{
|
||||
&a11, &a12, &a13,
|
||||
&a21, &a22, &a23,
|
||||
&a31, &a32, &a33)) {
|
||||
try {
|
||||
Matrix4D mtx(a11, a12, a13, a14,
|
||||
a21, a22, a23, a24,
|
||||
@@ -177,9 +190,11 @@ int RotationPy::PyInit(PyObject* args, PyObject* kwds)
|
||||
}
|
||||
|
||||
PyErr_Clear();
|
||||
PyObject *v1{}, *v2{};
|
||||
if (PyArg_ParseTuple(args, "O!O!", &(Base::VectorPy::Type), &v1,
|
||||
&(Base::VectorPy::Type), &v2)) {
|
||||
PyObject *v1 {}, *v2 {};
|
||||
if (PyArg_ParseTuple(args,
|
||||
"O!O!",
|
||||
&(Base::VectorPy::Type), &v1,
|
||||
&(Base::VectorPy::Type), &v2)) {
|
||||
Py::Vector from(v1, false);
|
||||
Py::Vector to(v2, false);
|
||||
getRotationPtr()->setValue(from.toVector(), to.toVector());
|
||||
@@ -187,57 +202,63 @@ int RotationPy::PyInit(PyObject* args, PyObject* kwds)
|
||||
}
|
||||
|
||||
PyErr_Clear();
|
||||
PyObject *v3{};
|
||||
const char *priority = nullptr;
|
||||
if (PyArg_ParseTuple(args, "O!O!O!|s", &(Base::VectorPy::Type), &v1,
|
||||
&(Base::VectorPy::Type), &v2,
|
||||
&(Base::VectorPy::Type), &v3,
|
||||
&priority)) {
|
||||
PyObject* v3 {};
|
||||
const char* priority = nullptr;
|
||||
if (PyArg_ParseTuple(args,
|
||||
"O!O!O!|s",
|
||||
&(Base::VectorPy::Type), &v1,
|
||||
&(Base::VectorPy::Type), &v2,
|
||||
&(Base::VectorPy::Type), &v3,
|
||||
&priority)) {
|
||||
Py::Vector xdir(v1, false);
|
||||
Py::Vector ydir(v2, false);
|
||||
Py::Vector zdir(v3, false);
|
||||
if (!priority)
|
||||
if (!priority) {
|
||||
priority = "ZXY";
|
||||
}
|
||||
try {
|
||||
*getRotationPtr() = (Rotation::makeRotationByAxes(xdir.toVector(), ydir.toVector(), zdir.toVector(), priority));
|
||||
} catch(Base::Exception &e) {
|
||||
*getRotationPtr() = (Rotation::makeRotationByAxes(xdir.toVector(),
|
||||
ydir.toVector(),
|
||||
zdir.toVector(),
|
||||
priority));
|
||||
}
|
||||
catch (Base::Exception& e) {
|
||||
std::string str;
|
||||
str += "FreeCAD exception thrown (";
|
||||
str += e.what();
|
||||
str += ")";
|
||||
PyErr_SetString(Base::PyExc_FC_GeneralError,str.c_str());
|
||||
PyErr_SetString(Base::PyExc_FC_GeneralError, str.c_str());
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
PyErr_SetString(PyExc_TypeError, "Rotation constructor accepts:\n"
|
||||
"-- empty parameter list\n"
|
||||
"-- Rotation object"
|
||||
"-- four floats (a quaternion)\n"
|
||||
"-- three floats (yaw, pitch, roll)"
|
||||
"-- Vector (rotation axis) and float (rotation angle)\n"
|
||||
"-- two Vectors (two axes)\n"
|
||||
"-- Matrix object\n"
|
||||
"-- 16 floats (4x4 matrix)\n"
|
||||
"-- 9 floats (3x3 matrix)\n"
|
||||
"-- 3 vectors + optional string"
|
||||
);
|
||||
PyErr_SetString(PyExc_TypeError,
|
||||
"Rotation constructor accepts:\n"
|
||||
"-- empty parameter list\n"
|
||||
"-- Rotation object"
|
||||
"-- four floats (a quaternion)\n"
|
||||
"-- three floats (yaw, pitch, roll)"
|
||||
"-- Vector (rotation axis) and float (rotation angle)\n"
|
||||
"-- two Vectors (two axes)\n"
|
||||
"-- Matrix object\n"
|
||||
"-- 16 floats (4x4 matrix)\n"
|
||||
"-- 9 floats (3x3 matrix)\n"
|
||||
"-- 3 vectors + optional string");
|
||||
return -1;
|
||||
}
|
||||
// clang-format on
|
||||
|
||||
PyObject* RotationPy::richCompare(PyObject *v, PyObject *w, int op)
|
||||
PyObject* RotationPy::richCompare(PyObject* v, PyObject* w, int op)
|
||||
{
|
||||
if (PyObject_TypeCheck(v, &(RotationPy::Type)) &&
|
||||
PyObject_TypeCheck(w, &(RotationPy::Type))) {
|
||||
if (PyObject_TypeCheck(v, &(RotationPy::Type)) && PyObject_TypeCheck(w, &(RotationPy::Type))) {
|
||||
Base::Rotation r1 = *static_cast<RotationPy*>(v)->getRotationPtr();
|
||||
Base::Rotation r2 = *static_cast<RotationPy*>(w)->getRotationPtr();
|
||||
|
||||
PyObject *res=nullptr;
|
||||
PyObject* res = nullptr;
|
||||
if (op != Py_EQ && op != Py_NE) {
|
||||
PyErr_SetString(PyExc_TypeError,
|
||||
"no ordering relation is defined for Rotation");
|
||||
PyErr_SetString(PyExc_TypeError, "no ordering relation is defined for Rotation");
|
||||
return nullptr;
|
||||
}
|
||||
else if (op == Py_EQ) {
|
||||
@@ -258,68 +279,75 @@ PyObject* RotationPy::richCompare(PyObject *v, PyObject *w, int op)
|
||||
}
|
||||
}
|
||||
|
||||
PyObject* RotationPy::invert(PyObject * args)
|
||||
PyObject* RotationPy::invert(PyObject* args)
|
||||
{
|
||||
if (!PyArg_ParseTuple(args, ""))
|
||||
if (!PyArg_ParseTuple(args, "")) {
|
||||
return nullptr;
|
||||
}
|
||||
this->getRotationPtr()->invert();
|
||||
Py_Return;
|
||||
}
|
||||
|
||||
PyObject* RotationPy::inverted(PyObject * args)
|
||||
PyObject* RotationPy::inverted(PyObject* args)
|
||||
{
|
||||
if (!PyArg_ParseTuple(args, ""))
|
||||
if (!PyArg_ParseTuple(args, "")) {
|
||||
return nullptr;
|
||||
}
|
||||
Rotation mult = this->getRotationPtr()->inverse();
|
||||
return new RotationPy(new Rotation(mult));
|
||||
}
|
||||
|
||||
PyObject* RotationPy::multiply(PyObject * args)
|
||||
PyObject* RotationPy::multiply(PyObject* args)
|
||||
{
|
||||
PyObject *rot{};
|
||||
if (!PyArg_ParseTuple(args, "O!", &(RotationPy::Type), &rot))
|
||||
PyObject* rot {};
|
||||
if (!PyArg_ParseTuple(args, "O!", &(RotationPy::Type), &rot)) {
|
||||
return nullptr;
|
||||
}
|
||||
Rotation mult = (*getRotationPtr()) * (*static_cast<RotationPy*>(rot)->getRotationPtr());
|
||||
return new RotationPy(new Rotation(mult));
|
||||
}
|
||||
|
||||
PyObject* RotationPy::multVec(PyObject * args)
|
||||
PyObject* RotationPy::multVec(PyObject* args)
|
||||
{
|
||||
PyObject *obj{};
|
||||
if (!PyArg_ParseTuple(args, "O!", &(VectorPy::Type), &obj))
|
||||
PyObject* obj {};
|
||||
if (!PyArg_ParseTuple(args, "O!", &(VectorPy::Type), &obj)) {
|
||||
return nullptr;
|
||||
}
|
||||
Base::Vector3d vec(static_cast<VectorPy*>(obj)->value());
|
||||
getRotationPtr()->multVec(vec, vec);
|
||||
return new VectorPy(new Vector3d(vec));
|
||||
}
|
||||
|
||||
PyObject* RotationPy::slerp(PyObject * args)
|
||||
PyObject* RotationPy::slerp(PyObject* args)
|
||||
{
|
||||
PyObject *rot{};
|
||||
double t{};
|
||||
if (!PyArg_ParseTuple(args, "O!d", &(RotationPy::Type), &rot, &t))
|
||||
PyObject* rot {};
|
||||
double t {};
|
||||
if (!PyArg_ParseTuple(args, "O!d", &(RotationPy::Type), &rot, &t)) {
|
||||
return nullptr;
|
||||
Rotation *rot0 = this->getRotationPtr();
|
||||
Rotation *rot1 = static_cast<RotationPy*>(rot)->getRotationPtr();
|
||||
}
|
||||
Rotation* rot0 = this->getRotationPtr();
|
||||
Rotation* rot1 = static_cast<RotationPy*>(rot)->getRotationPtr();
|
||||
Rotation sl = Rotation::slerp(*rot0, *rot1, t);
|
||||
return new RotationPy(new Rotation(sl));
|
||||
}
|
||||
|
||||
PyObject* RotationPy::setYawPitchRoll(PyObject * args)
|
||||
PyObject* RotationPy::setYawPitchRoll(PyObject* args)
|
||||
{
|
||||
double A{},B{},C{};
|
||||
if (!PyArg_ParseTuple(args, "ddd", &A, &B, &C))
|
||||
double A {}, B {}, C {};
|
||||
if (!PyArg_ParseTuple(args, "ddd", &A, &B, &C)) {
|
||||
return nullptr;
|
||||
this->getRotationPtr()->setYawPitchRoll(A,B,C);
|
||||
}
|
||||
this->getRotationPtr()->setYawPitchRoll(A, B, C);
|
||||
Py_Return;
|
||||
}
|
||||
|
||||
PyObject* RotationPy::getYawPitchRoll(PyObject * args)
|
||||
PyObject* RotationPy::getYawPitchRoll(PyObject* args)
|
||||
{
|
||||
if (!PyArg_ParseTuple(args, ""))
|
||||
if (!PyArg_ParseTuple(args, "")) {
|
||||
return nullptr;
|
||||
double A{},B{},C{};
|
||||
this->getRotationPtr()->getYawPitchRoll(A,B,C);
|
||||
}
|
||||
double A {}, B {}, C {};
|
||||
this->getRotationPtr()->getYawPitchRoll(A, B, C);
|
||||
|
||||
Py::Tuple tuple(3);
|
||||
tuple.setItem(0, Py::Float(A));
|
||||
@@ -328,16 +356,16 @@ PyObject* RotationPy::getYawPitchRoll(PyObject * args)
|
||||
return Py::new_reference_to(tuple);
|
||||
}
|
||||
|
||||
PyObject* RotationPy::setEulerAngles(PyObject * args)
|
||||
PyObject* RotationPy::setEulerAngles(PyObject* args)
|
||||
{
|
||||
const char *seq{};
|
||||
double A{},B{},C{};
|
||||
if (!PyArg_ParseTuple(args, "sddd", &seq, &A, &B, &C))
|
||||
const char* seq {};
|
||||
double A {}, B {}, C {};
|
||||
if (!PyArg_ParseTuple(args, "sddd", &seq, &A, &B, &C)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
try {
|
||||
getRotationPtr()->setEulerAngles(
|
||||
Rotation::eulerSequenceFromName(seq), A, B, C);
|
||||
getRotationPtr()->setEulerAngles(Rotation::eulerSequenceFromName(seq), A, B, C);
|
||||
Py_Return;
|
||||
}
|
||||
catch (const Base::Exception& e) {
|
||||
@@ -346,75 +374,80 @@ PyObject* RotationPy::setEulerAngles(PyObject * args)
|
||||
}
|
||||
}
|
||||
|
||||
PyObject* RotationPy::toEulerAngles(PyObject * args)
|
||||
PyObject* RotationPy::toEulerAngles(PyObject* args)
|
||||
{
|
||||
const char *seq = nullptr;
|
||||
if (!PyArg_ParseTuple(args, "|s", &seq))
|
||||
const char* seq = nullptr;
|
||||
if (!PyArg_ParseTuple(args, "|s", &seq)) {
|
||||
return nullptr;
|
||||
}
|
||||
if (!seq) {
|
||||
Py::List res;
|
||||
for (int i=1; i<Rotation::EulerSequenceLast; ++i)
|
||||
for (int i = 1; i < Rotation::EulerSequenceLast; ++i) {
|
||||
res.append(Py::String(Rotation::eulerSequenceName((Rotation::EulerSequence)i)));
|
||||
}
|
||||
return Py::new_reference_to(res);
|
||||
}
|
||||
|
||||
PY_TRY {
|
||||
double A{},B{},C{};
|
||||
this->getRotationPtr()->getEulerAngles(
|
||||
Rotation::eulerSequenceFromName(seq),A,B,C);
|
||||
PY_TRY
|
||||
{
|
||||
double A {}, B {}, C {};
|
||||
this->getRotationPtr()->getEulerAngles(Rotation::eulerSequenceFromName(seq), A, B, C);
|
||||
|
||||
Py::Tuple tuple(3);
|
||||
tuple.setItem(0, Py::Float(A));
|
||||
tuple.setItem(1, Py::Float(B));
|
||||
tuple.setItem(2, Py::Float(C));
|
||||
return Py::new_reference_to(tuple);
|
||||
} PY_CATCH
|
||||
|
||||
}
|
||||
PY_CATCH
|
||||
}
|
||||
|
||||
PyObject* RotationPy::toMatrix(PyObject * args)
|
||||
PyObject* RotationPy::toMatrix(PyObject* args)
|
||||
{
|
||||
if (!PyArg_ParseTuple(args, ""))
|
||||
if (!PyArg_ParseTuple(args, "")) {
|
||||
return nullptr;
|
||||
}
|
||||
Base::Matrix4D mat;
|
||||
getRotationPtr()->getValue(mat);
|
||||
return new MatrixPy(new Matrix4D(mat));
|
||||
}
|
||||
|
||||
PyObject* RotationPy::isSame(PyObject *args)
|
||||
PyObject* RotationPy::isSame(PyObject* args)
|
||||
{
|
||||
PyObject *rot{};
|
||||
PyObject* rot {};
|
||||
double tol = 0.0;
|
||||
if (!PyArg_ParseTuple(args, "O!|d", &(RotationPy::Type), &rot, &tol))
|
||||
if (!PyArg_ParseTuple(args, "O!|d", &(RotationPy::Type), &rot, &tol)) {
|
||||
return nullptr;
|
||||
Base::Rotation rot1 = * getRotationPtr();
|
||||
Base::Rotation rot2 = * static_cast<RotationPy*>(rot)->getRotationPtr();
|
||||
}
|
||||
Base::Rotation rot1 = *getRotationPtr();
|
||||
Base::Rotation rot2 = *static_cast<RotationPy*>(rot)->getRotationPtr();
|
||||
bool same = tol > 0.0 ? rot1.isSame(rot2, tol) : rot1.isSame(rot2);
|
||||
return Py_BuildValue("O", (same ? Py_True : Py_False));
|
||||
}
|
||||
|
||||
PyObject* RotationPy::isIdentity(PyObject *args)
|
||||
PyObject* RotationPy::isIdentity(PyObject* args)
|
||||
{
|
||||
double tol = 0.0;
|
||||
if (!PyArg_ParseTuple(args, "|d", &tol))
|
||||
if (!PyArg_ParseTuple(args, "|d", &tol)) {
|
||||
return nullptr;
|
||||
bool null = tol > 0.0 ? getRotationPtr()->isIdentity(tol)
|
||||
: getRotationPtr()->isIdentity();
|
||||
}
|
||||
bool null = tol > 0.0 ? getRotationPtr()->isIdentity(tol) : getRotationPtr()->isIdentity();
|
||||
return Py_BuildValue("O", (null ? Py_True : Py_False));
|
||||
}
|
||||
|
||||
PyObject* RotationPy::isNull(PyObject *args)
|
||||
PyObject* RotationPy::isNull(PyObject* args)
|
||||
{
|
||||
if (!PyArg_ParseTuple(args, ""))
|
||||
if (!PyArg_ParseTuple(args, "")) {
|
||||
return nullptr;
|
||||
}
|
||||
bool null = getRotationPtr()->isNull();
|
||||
return Py_BuildValue("O", (null ? Py_True : Py_False));
|
||||
}
|
||||
|
||||
Py::Tuple RotationPy::getQ() const
|
||||
{
|
||||
double q0{}, q1{}, q2{}, q3{};
|
||||
this->getRotationPtr()->getValue(q0,q1,q2,q3);
|
||||
double q0 {}, q1 {}, q2 {}, q3 {};
|
||||
this->getRotationPtr()->getValue(q0, q1, q2, q3);
|
||||
|
||||
Py::Tuple tuple(4);
|
||||
tuple.setItem(0, Py::Float(q0));
|
||||
@@ -430,26 +463,29 @@ void RotationPy::setQ(Py::Tuple arg)
|
||||
double q1 = static_cast<double>(Py::Float(arg.getItem(1)));
|
||||
double q2 = static_cast<double>(Py::Float(arg.getItem(2)));
|
||||
double q3 = static_cast<double>(Py::Float(arg.getItem(3)));
|
||||
this->getRotationPtr()->setValue(q0,q1,q2,q3);
|
||||
this->getRotationPtr()->setValue(q0, q1, q2, q3);
|
||||
}
|
||||
|
||||
Py::Object RotationPy::getRawAxis() const
|
||||
{
|
||||
Base::Vector3d axis; double angle{};
|
||||
Base::Vector3d axis;
|
||||
double angle {};
|
||||
this->getRotationPtr()->getRawValue(axis, angle);
|
||||
return Py::Vector(axis); // NOLINT
|
||||
return Py::Vector(axis); // NOLINT
|
||||
}
|
||||
|
||||
Py::Object RotationPy::getAxis() const
|
||||
{
|
||||
Base::Vector3d axis; double angle{};
|
||||
Base::Vector3d axis;
|
||||
double angle {};
|
||||
this->getRotationPtr()->getValue(axis, angle);
|
||||
return Py::Vector(axis); // NOLINT
|
||||
return Py::Vector(axis); // NOLINT
|
||||
}
|
||||
|
||||
void RotationPy::setAxis(Py::Object arg)
|
||||
{
|
||||
Base::Vector3d axis; double angle{};
|
||||
Base::Vector3d axis;
|
||||
double angle {};
|
||||
this->getRotationPtr()->getValue(axis, angle);
|
||||
axis = Py::Vector(arg).toVector();
|
||||
this->getRotationPtr()->setValue(axis, angle);
|
||||
@@ -457,20 +493,22 @@ void RotationPy::setAxis(Py::Object arg)
|
||||
|
||||
Py::Float RotationPy::getAngle() const
|
||||
{
|
||||
Base::Vector3d axis; double angle{};
|
||||
Base::Vector3d axis;
|
||||
double angle {};
|
||||
this->getRotationPtr()->getValue(axis, angle);
|
||||
return Py::Float(angle);
|
||||
}
|
||||
|
||||
void RotationPy::setAngle(Py::Float arg)
|
||||
{
|
||||
Base::Vector3d axis; double angle{};
|
||||
Base::Vector3d axis;
|
||||
double angle {};
|
||||
this->getRotationPtr()->getRawValue(axis, angle);
|
||||
angle = static_cast<double>(arg);
|
||||
this->getRotationPtr()->setValue(axis, angle);
|
||||
}
|
||||
|
||||
PyObject *RotationPy::getCustomAttributes(const char* attr) const
|
||||
PyObject* RotationPy::getCustomAttributes(const char* attr) const
|
||||
{
|
||||
if (strcmp(attr, "Matrix") == 0) {
|
||||
Matrix4D mat;
|
||||
@@ -478,18 +516,18 @@ PyObject *RotationPy::getCustomAttributes(const char* attr) const
|
||||
return new MatrixPy(mat);
|
||||
}
|
||||
else if (strcmp(attr, "Yaw") == 0) {
|
||||
double A{},B{},C{};
|
||||
this->getRotationPtr()->getYawPitchRoll(A,B,C);
|
||||
double A {}, B {}, C {};
|
||||
this->getRotationPtr()->getYawPitchRoll(A, B, C);
|
||||
return PyFloat_FromDouble(A);
|
||||
}
|
||||
else if (strcmp(attr, "Pitch") == 0) {
|
||||
double A{},B{},C{};
|
||||
this->getRotationPtr()->getYawPitchRoll(A,B,C);
|
||||
double A {}, B {}, C {};
|
||||
this->getRotationPtr()->getYawPitchRoll(A, B, C);
|
||||
return PyFloat_FromDouble(B);
|
||||
}
|
||||
else if (strcmp(attr, "Roll") == 0) {
|
||||
double A{},B{},C{};
|
||||
this->getRotationPtr()->getYawPitchRoll(A,B,C);
|
||||
double A {}, B {}, C {};
|
||||
this->getRotationPtr()->getYawPitchRoll(A, B, C);
|
||||
return PyFloat_FromDouble(C);
|
||||
}
|
||||
else if (strcmp(attr, "toEuler") == 0) {
|
||||
@@ -518,11 +556,10 @@ int RotationPy::setCustomAttributes(const char* attr, PyObject* obj)
|
||||
if (PySequence_Check(obj) && PySequence_Size(obj) == 2) {
|
||||
PyObject* vec1 = PySequence_GetItem(obj, 0);
|
||||
PyObject* vec2 = PySequence_GetItem(obj, 1);
|
||||
if (PyObject_TypeCheck(vec1, &(VectorPy::Type)) &&
|
||||
PyObject_TypeCheck(vec2, &(VectorPy::Type))) {
|
||||
this->getRotationPtr()->setValue(
|
||||
*static_cast<VectorPy*>(vec1)->getVectorPtr(),
|
||||
*static_cast<VectorPy*>(vec2)->getVectorPtr());
|
||||
if (PyObject_TypeCheck(vec1, &(VectorPy::Type))
|
||||
&& PyObject_TypeCheck(vec2, &(VectorPy::Type))) {
|
||||
this->getRotationPtr()->setValue(*static_cast<VectorPy*>(vec1)->getVectorPtr(),
|
||||
*static_cast<VectorPy*>(vec2)->getVectorPtr());
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
@@ -530,59 +567,59 @@ int RotationPy::setCustomAttributes(const char* attr, PyObject* obj)
|
||||
else if (strcmp(attr, "Yaw") == 0) {
|
||||
if (PyNumber_Check(obj)) {
|
||||
double V = PyFloat_AsDouble(obj);
|
||||
double A{},B{},C{};
|
||||
this->getRotationPtr()->getYawPitchRoll(A,B,C);
|
||||
this->getRotationPtr()->setYawPitchRoll(V,B,C);
|
||||
double A {}, B {}, C {};
|
||||
this->getRotationPtr()->getYawPitchRoll(A, B, C);
|
||||
this->getRotationPtr()->setYawPitchRoll(V, B, C);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
else if (strcmp(attr, "Pitch") == 0) {
|
||||
if (PyNumber_Check(obj)) {
|
||||
double V = PyFloat_AsDouble(obj);
|
||||
double A{},B{},C{};
|
||||
this->getRotationPtr()->getYawPitchRoll(A,B,C);
|
||||
this->getRotationPtr()->setYawPitchRoll(A,V,C);
|
||||
double A {}, B {}, C {};
|
||||
this->getRotationPtr()->getYawPitchRoll(A, B, C);
|
||||
this->getRotationPtr()->setYawPitchRoll(A, V, C);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
else if (strcmp(attr, "Roll") == 0) {
|
||||
if (PyNumber_Check(obj)) {
|
||||
double V = PyFloat_AsDouble(obj);
|
||||
double A{},B{},C{};
|
||||
this->getRotationPtr()->getYawPitchRoll(A,B,C);
|
||||
this->getRotationPtr()->setYawPitchRoll(A,B,V);
|
||||
double A {}, B {}, C {};
|
||||
this->getRotationPtr()->getYawPitchRoll(A, B, C);
|
||||
this->getRotationPtr()->setYawPitchRoll(A, B, V);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
PyObject* RotationPy::number_multiply_handler(PyObject *self, PyObject *other)
|
||||
PyObject* RotationPy::number_multiply_handler(PyObject* self, PyObject* other)
|
||||
{
|
||||
if (PyObject_TypeCheck(self, &(RotationPy::Type))) {
|
||||
auto a = static_cast<RotationPy*>(self)->value();
|
||||
|
||||
if (PyObject_TypeCheck(other, &(VectorPy::Type))) {
|
||||
Vector3d res;
|
||||
a.multVec(static_cast<VectorPy*>(other)->value(),res);
|
||||
a.multVec(static_cast<VectorPy*>(other)->value(), res);
|
||||
return new VectorPy(res);
|
||||
}
|
||||
|
||||
if (PyObject_TypeCheck(other, &(PlacementPy::Type))) {
|
||||
const auto &b = static_cast<PlacementPy*>(other)->value();
|
||||
return new PlacementPy(Placement(Vector3d(),a)*b);
|
||||
const auto& b = static_cast<PlacementPy*>(other)->value();
|
||||
return new PlacementPy(Placement(Vector3d(), a) * b);
|
||||
}
|
||||
|
||||
if (PyObject_TypeCheck(other, &(RotationPy::Type))) {
|
||||
const auto &b = static_cast<RotationPy*>(other)->value();
|
||||
return new RotationPy(a*b);
|
||||
const auto& b = static_cast<RotationPy*>(other)->value();
|
||||
return new RotationPy(a * b);
|
||||
}
|
||||
|
||||
if (PyObject_TypeCheck(other, &(MatrixPy::Type))) {
|
||||
const auto &b = static_cast<MatrixPy*>(other)->value();
|
||||
const auto& b = static_cast<MatrixPy*>(other)->value();
|
||||
Matrix4D mat;
|
||||
a.getValue(mat);
|
||||
return new MatrixPy(mat*b);
|
||||
return new MatrixPy(mat * b);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -590,12 +627,9 @@ PyObject* RotationPy::number_multiply_handler(PyObject *self, PyObject *other)
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
PyObject * RotationPy::number_power_handler (PyObject* self, PyObject* other, PyObject* arg)
|
||||
PyObject* RotationPy::number_power_handler(PyObject* self, PyObject* other, PyObject* arg)
|
||||
{
|
||||
if (!PyObject_TypeCheck(self, &(RotationPy::Type)) ||
|
||||
!PyLong_Check(other) ||
|
||||
arg != Py_None)
|
||||
{
|
||||
if (!PyObject_TypeCheck(self, &(RotationPy::Type)) || !PyLong_Check(other) || arg != Py_None) {
|
||||
PyErr_SetString(PyExc_NotImplementedError, "Not implemented");
|
||||
return nullptr;
|
||||
}
|
||||
@@ -604,7 +638,7 @@ PyObject * RotationPy::number_power_handler (PyObject* self, PyObject* other, Py
|
||||
long b = Py::Int(other);
|
||||
|
||||
Vector3d axis;
|
||||
double rfAngle{};
|
||||
double rfAngle {};
|
||||
|
||||
a.getRawValue(axis, rfAngle);
|
||||
rfAngle *= b;
|
||||
@@ -613,104 +647,103 @@ PyObject * RotationPy::number_power_handler (PyObject* self, PyObject* other, Py
|
||||
return new RotationPy(a);
|
||||
}
|
||||
|
||||
PyObject* RotationPy::number_add_handler(PyObject * /*self*/, PyObject * /*other*/)
|
||||
PyObject* RotationPy::number_add_handler(PyObject* /*self*/, PyObject* /*other*/)
|
||||
{
|
||||
PyErr_SetString(PyExc_NotImplementedError, "Not implemented");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
PyObject* RotationPy::number_subtract_handler(PyObject * /*self*/, PyObject * /*other*/)
|
||||
PyObject* RotationPy::number_subtract_handler(PyObject* /*self*/, PyObject* /*other*/)
|
||||
{
|
||||
PyErr_SetString(PyExc_NotImplementedError, "Not implemented");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
PyObject * RotationPy::number_divide_handler (PyObject* /*self*/, PyObject* /*other*/)
|
||||
PyObject* RotationPy::number_divide_handler(PyObject* /*self*/, PyObject* /*other*/)
|
||||
{
|
||||
PyErr_SetString(PyExc_NotImplementedError, "Not implemented");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
PyObject * RotationPy::number_remainder_handler (PyObject* /*self*/, PyObject* /*other*/)
|
||||
PyObject* RotationPy::number_remainder_handler(PyObject* /*self*/, PyObject* /*other*/)
|
||||
{
|
||||
PyErr_SetString(PyExc_NotImplementedError, "Not implemented");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
PyObject * RotationPy::number_divmod_handler (PyObject* /*self*/, PyObject* /*other*/)
|
||||
PyObject* RotationPy::number_divmod_handler(PyObject* /*self*/, PyObject* /*other*/)
|
||||
{
|
||||
PyErr_SetString(PyExc_NotImplementedError, "Not implemented");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
PyObject * RotationPy::number_negative_handler (PyObject* /*self*/)
|
||||
PyObject* RotationPy::number_negative_handler(PyObject* /*self*/)
|
||||
{
|
||||
PyErr_SetString(PyExc_NotImplementedError, "Not implemented");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
PyObject * RotationPy::number_positive_handler (PyObject* /*self*/)
|
||||
PyObject* RotationPy::number_positive_handler(PyObject* /*self*/)
|
||||
{
|
||||
PyErr_SetString(PyExc_NotImplementedError, "Not implemented");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
PyObject * RotationPy::number_absolute_handler (PyObject* /*self*/)
|
||||
PyObject* RotationPy::number_absolute_handler(PyObject* /*self*/)
|
||||
{
|
||||
PyErr_SetString(PyExc_NotImplementedError, "Not implemented");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
int RotationPy::number_nonzero_handler (PyObject* /*self*/)
|
||||
int RotationPy::number_nonzero_handler(PyObject* /*self*/)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
PyObject * RotationPy::number_invert_handler (PyObject* /*self*/)
|
||||
PyObject* RotationPy::number_invert_handler(PyObject* /*self*/)
|
||||
{
|
||||
PyErr_SetString(PyExc_NotImplementedError, "Not implemented");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
PyObject * RotationPy::number_lshift_handler (PyObject* /*self*/, PyObject* /*other*/)
|
||||
PyObject* RotationPy::number_lshift_handler(PyObject* /*self*/, PyObject* /*other*/)
|
||||
{
|
||||
PyErr_SetString(PyExc_NotImplementedError, "Not implemented");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
PyObject * RotationPy::number_rshift_handler (PyObject* /*self*/, PyObject* /*other*/)
|
||||
PyObject* RotationPy::number_rshift_handler(PyObject* /*self*/, PyObject* /*other*/)
|
||||
{
|
||||
PyErr_SetString(PyExc_NotImplementedError, "Not implemented");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
PyObject * RotationPy::number_and_handler (PyObject* /*self*/, PyObject* /*other*/)
|
||||
PyObject* RotationPy::number_and_handler(PyObject* /*self*/, PyObject* /*other*/)
|
||||
{
|
||||
PyErr_SetString(PyExc_NotImplementedError, "Not implemented");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
PyObject * RotationPy::number_xor_handler (PyObject* /*self*/, PyObject* /*other*/)
|
||||
PyObject* RotationPy::number_xor_handler(PyObject* /*self*/, PyObject* /*other*/)
|
||||
{
|
||||
PyErr_SetString(PyExc_NotImplementedError, "Not implemented");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
PyObject * RotationPy::number_or_handler (PyObject* /*self*/, PyObject* /*other*/)
|
||||
PyObject* RotationPy::number_or_handler(PyObject* /*self*/, PyObject* /*other*/)
|
||||
{
|
||||
PyErr_SetString(PyExc_NotImplementedError, "Not implemented");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
PyObject * RotationPy::number_int_handler (PyObject * /*self*/)
|
||||
PyObject* RotationPy::number_int_handler(PyObject* /*self*/)
|
||||
{
|
||||
PyErr_SetString(PyExc_NotImplementedError, "Not implemented");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
PyObject * RotationPy::number_float_handler (PyObject * /*self*/)
|
||||
PyObject* RotationPy::number_float_handler(PyObject* /*self*/)
|
||||
{
|
||||
PyErr_SetString(PyExc_NotImplementedError, "Not implemented");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
#include "PreCompiled.h"
|
||||
|
||||
#ifndef _PreComp_
|
||||
# include <QMutexLocker>
|
||||
#include <QMutexLocker>
|
||||
#endif
|
||||
|
||||
#include "Sequencer.h"
|
||||
@@ -33,41 +33,43 @@
|
||||
|
||||
using namespace Base;
|
||||
|
||||
namespace Base {
|
||||
struct SequencerP {
|
||||
// members
|
||||
static std::vector<SequencerBase*> _instances; /**< A vector of all created instances */
|
||||
static SequencerLauncher* _topLauncher; /**< The outermost launcher */
|
||||
static QRecursiveMutex mutex; /**< A mutex-locker for the launcher */
|
||||
/** Sets a global sequencer object.
|
||||
* Access to the last registered object is performed by @see Sequencer().
|
||||
*/
|
||||
static void appendInstance (SequencerBase* s)
|
||||
{
|
||||
_instances.push_back(s);
|
||||
}
|
||||
static void removeInstance (SequencerBase* s)
|
||||
{
|
||||
std::vector<SequencerBase*>::iterator it;
|
||||
it = std::find(_instances.begin(), _instances.end(), s);
|
||||
_instances.erase(it);
|
||||
}
|
||||
static SequencerBase& getInstance ()
|
||||
{
|
||||
return *_instances.back();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* The _instances member just stores the pointer of the
|
||||
* all instantiated SequencerBase objects.
|
||||
namespace Base
|
||||
{
|
||||
struct SequencerP
|
||||
{
|
||||
// members
|
||||
static std::vector<SequencerBase*> _instances; /**< A vector of all created instances */
|
||||
static SequencerLauncher* _topLauncher; /**< The outermost launcher */
|
||||
static QRecursiveMutex mutex; /**< A mutex-locker for the launcher */
|
||||
/** Sets a global sequencer object.
|
||||
* Access to the last registered object is performed by @see Sequencer().
|
||||
*/
|
||||
std::vector<SequencerBase*> SequencerP::_instances;
|
||||
SequencerLauncher* SequencerP::_topLauncher = nullptr;
|
||||
QRecursiveMutex SequencerP::mutex;
|
||||
}
|
||||
static void appendInstance(SequencerBase* s)
|
||||
{
|
||||
_instances.push_back(s);
|
||||
}
|
||||
static void removeInstance(SequencerBase* s)
|
||||
{
|
||||
std::vector<SequencerBase*>::iterator it;
|
||||
it = std::find(_instances.begin(), _instances.end(), s);
|
||||
_instances.erase(it);
|
||||
}
|
||||
static SequencerBase& getInstance()
|
||||
{
|
||||
return *_instances.back();
|
||||
}
|
||||
};
|
||||
|
||||
SequencerBase& SequencerBase::Instance ()
|
||||
/**
|
||||
* The _instances member just stores the pointer of the
|
||||
* all instantiated SequencerBase objects.
|
||||
*/
|
||||
std::vector<SequencerBase*> SequencerP::_instances;
|
||||
SequencerLauncher* SequencerP::_topLauncher = nullptr;
|
||||
QRecursiveMutex SequencerP::mutex;
|
||||
} // namespace Base
|
||||
|
||||
SequencerBase& SequencerBase::Instance()
|
||||
{
|
||||
// not initialized?
|
||||
if (SequencerP::_instances.size() == 0) {
|
||||
@@ -99,8 +101,9 @@ bool SequencerBase::start(const char* pszStr, size_t steps)
|
||||
setText(pszStr);
|
||||
|
||||
// reimplemented in sub-classes
|
||||
if (!this->_bLocked)
|
||||
if (!this->_bLocked) {
|
||||
startStep();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -111,8 +114,7 @@ size_t SequencerBase::numberOfSteps() const
|
||||
}
|
||||
|
||||
void SequencerBase::startStep()
|
||||
{
|
||||
}
|
||||
{}
|
||||
|
||||
bool SequencerBase::next(bool canAbort)
|
||||
{
|
||||
@@ -125,20 +127,19 @@ bool SequencerBase::next(bool canAbort)
|
||||
this->_nLastPercentage = perc;
|
||||
|
||||
// if not locked
|
||||
if (!this->_bLocked)
|
||||
if (!this->_bLocked) {
|
||||
nextStep(canAbort);
|
||||
}
|
||||
}
|
||||
|
||||
return this->nProgress < this->nTotalSteps;
|
||||
}
|
||||
|
||||
void SequencerBase::nextStep( bool )
|
||||
{
|
||||
}
|
||||
void SequencerBase::nextStep(bool)
|
||||
{}
|
||||
|
||||
void SequencerBase::setProgress(size_t)
|
||||
{
|
||||
}
|
||||
{}
|
||||
|
||||
bool SequencerBase::stop()
|
||||
{
|
||||
@@ -147,12 +148,10 @@ bool SequencerBase::stop()
|
||||
}
|
||||
|
||||
void SequencerBase::pause()
|
||||
{
|
||||
}
|
||||
{}
|
||||
|
||||
void SequencerBase::resume()
|
||||
{
|
||||
}
|
||||
{}
|
||||
|
||||
bool SequencerBase::isBlocking() const
|
||||
{
|
||||
@@ -206,26 +205,25 @@ void SequencerBase::resetData()
|
||||
}
|
||||
|
||||
void SequencerBase::setText(const char*)
|
||||
{
|
||||
}
|
||||
{}
|
||||
|
||||
// ---------------------------------------------------------
|
||||
|
||||
using Base::ConsoleSequencer;
|
||||
|
||||
void ConsoleSequencer::setText (const char* pszTxt)
|
||||
void ConsoleSequencer::setText(const char* pszTxt)
|
||||
{
|
||||
printf("%s...\n", pszTxt);
|
||||
}
|
||||
|
||||
void ConsoleSequencer::startStep()
|
||||
{
|
||||
}
|
||||
{}
|
||||
|
||||
void ConsoleSequencer::nextStep( bool )
|
||||
void ConsoleSequencer::nextStep(bool)
|
||||
{
|
||||
if (this->nTotalSteps != 0)
|
||||
if (this->nTotalSteps != 0) {
|
||||
printf("\t\t\t\t\t\t(%d %%)\t\r", progressInPercent());
|
||||
}
|
||||
}
|
||||
|
||||
void ConsoleSequencer::resetData()
|
||||
@@ -249,14 +247,15 @@ SequencerLauncher::SequencerLauncher(const char* pszStr, size_t steps)
|
||||
SequencerLauncher::~SequencerLauncher()
|
||||
{
|
||||
QMutexLocker locker(&SequencerP::mutex);
|
||||
if (SequencerP::_topLauncher == this)
|
||||
if (SequencerP::_topLauncher == this) {
|
||||
SequencerBase::Instance().stop();
|
||||
}
|
||||
if (SequencerP::_topLauncher == this) {
|
||||
SequencerP::_topLauncher = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void SequencerLauncher::setText (const char* pszTxt)
|
||||
void SequencerLauncher::setText(const char* pszTxt)
|
||||
{
|
||||
QMutexLocker locker(&SequencerP::mutex);
|
||||
SequencerBase::Instance().setText(pszTxt);
|
||||
@@ -265,8 +264,9 @@ void SequencerLauncher::setText (const char* pszTxt)
|
||||
bool SequencerLauncher::next(bool canAbort)
|
||||
{
|
||||
QMutexLocker locker(&SequencerP::mutex);
|
||||
if (SequencerP::_topLauncher != this)
|
||||
return true; // ignore
|
||||
if (SequencerP::_topLauncher != this) {
|
||||
return true; // ignore
|
||||
}
|
||||
return SequencerBase::Instance().next(canAbort);
|
||||
}
|
||||
|
||||
|
||||
@@ -148,7 +148,8 @@ public:
|
||||
bool wasCanceled() const;
|
||||
|
||||
/// Check if the operation is aborted by user
|
||||
virtual void checkAbort() {}
|
||||
virtual void checkAbort()
|
||||
{}
|
||||
|
||||
protected:
|
||||
/**
|
||||
@@ -211,7 +212,7 @@ protected:
|
||||
* Sets a text what the pending operation is doing. The default implementation
|
||||
* does nothing.
|
||||
*/
|
||||
virtual void setText (const char* pszTxt);
|
||||
virtual void setText(const char* pszTxt);
|
||||
/**
|
||||
* This method can be reimplemented in sub-classes to give the user a feedback
|
||||
* when a new sequence starts. The default implementation does nothing.
|
||||
@@ -236,21 +237,21 @@ protected:
|
||||
virtual void resetData();
|
||||
|
||||
protected:
|
||||
//NOLINTBEGIN
|
||||
size_t nProgress{0}; /**< Stores the current amount of progress.*/
|
||||
size_t nTotalSteps{0}; /**< Stores the total number of steps */
|
||||
//NOLINTEND
|
||||
// NOLINTBEGIN
|
||||
size_t nProgress {0}; /**< Stores the current amount of progress.*/
|
||||
size_t nTotalSteps {0}; /**< Stores the total number of steps */
|
||||
// NOLINTEND
|
||||
|
||||
private:
|
||||
bool _bLocked{false}; /**< Lock/unlock sequencer. */
|
||||
bool _bCanceled{false}; /**< Is set to true if the last pending operation was canceled */
|
||||
int _nLastPercentage{-1}; /**< Progress in percent. */
|
||||
bool _bLocked {false}; /**< Lock/unlock sequencer. */
|
||||
bool _bCanceled {false}; /**< Is set to true if the last pending operation was canceled */
|
||||
int _nLastPercentage {-1}; /**< Progress in percent. */
|
||||
};
|
||||
|
||||
/** This special sequencer might be useful if you want to suppress any indication
|
||||
* of the progress to the user.
|
||||
*/
|
||||
class BaseExport EmptySequencer : public Base::SequencerBase
|
||||
class BaseExport EmptySequencer: public Base::SequencerBase
|
||||
{
|
||||
public:
|
||||
/** construction */
|
||||
@@ -260,11 +261,11 @@ public:
|
||||
/**
|
||||
* \brief This class writes the progress to the console window.
|
||||
*/
|
||||
class BaseExport ConsoleSequencer : public SequencerBase
|
||||
class BaseExport ConsoleSequencer: public SequencerBase
|
||||
{
|
||||
public:
|
||||
/** construction */
|
||||
ConsoleSequencer () = default;
|
||||
ConsoleSequencer() = default;
|
||||
|
||||
protected:
|
||||
/** Starts the sequencer */
|
||||
@@ -274,21 +275,21 @@ protected:
|
||||
|
||||
private:
|
||||
/** Puts text to the console window */
|
||||
void setText (const char* pszTxt) override;
|
||||
void setText(const char* pszTxt) override;
|
||||
/** Resets the sequencer */
|
||||
void resetData() override;
|
||||
};
|
||||
|
||||
/** The SequencerLauncher class is provided for convenience. It allows you to run an instance of the
|
||||
* sequencer by instantiating an object of this class -- most suitable on the stack. So this mechanism
|
||||
* can be used for try-catch-blocks to destroy the object automatically if the C++ exception mechanism
|
||||
* cleans up the stack.
|
||||
* sequencer by instantiating an object of this class -- most suitable on the stack. So this
|
||||
* mechanism can be used for try-catch-blocks to destroy the object automatically if the C++
|
||||
* exception mechanism cleans up the stack.
|
||||
*
|
||||
* This class has been introduced to simplify the use with the sequencer. In the FreeCAD Gui layer there
|
||||
* is a subclass of SequencerBase called ProgressBar that grabs the keyboard and filters most of the incoming
|
||||
* events. If the programmer uses the API of SequencerBase directly to start an instance without due diligence
|
||||
* with exceptions then a not handled exception could block the whole application -- the user has to kill the
|
||||
* application then.
|
||||
* This class has been introduced to simplify the use with the sequencer. In the FreeCAD Gui layer
|
||||
* there is a subclass of SequencerBase called ProgressBar that grabs the keyboard and filters most
|
||||
* of the incoming events. If the programmer uses the API of SequencerBase directly to start an
|
||||
* instance without due diligence with exceptions then a not handled exception could block the whole
|
||||
* application -- the user has to kill the application then.
|
||||
*
|
||||
* Below is an example of a not correctly used sequencer.
|
||||
*
|
||||
@@ -304,7 +305,8 @@ private:
|
||||
* runOperation();
|
||||
* } catch(...) {
|
||||
* // the programmer forgot to stop the sequencer here
|
||||
* // Under circumstances the sequencer never gets stopped so the keyboard never gets ungrabbed and
|
||||
* // Under circumstances the sequencer never gets stopped so the keyboard never gets
|
||||
* ungrabbed and
|
||||
* // all Gui events still gets filtered.
|
||||
* }
|
||||
* }
|
||||
@@ -367,7 +369,7 @@ public:
|
||||
SequencerLauncher(const char* pszStr, size_t steps);
|
||||
~SequencerLauncher();
|
||||
size_t numberOfSteps() const;
|
||||
void setText (const char* pszTxt);
|
||||
void setText(const char* pszTxt);
|
||||
bool next(bool canAbort = false);
|
||||
void setProgress(size_t);
|
||||
bool wasCanceled() const;
|
||||
@@ -377,11 +379,11 @@ public:
|
||||
};
|
||||
|
||||
/** Access to the only SequencerBase instance */
|
||||
inline SequencerBase& Sequencer ()
|
||||
inline SequencerBase& Sequencer()
|
||||
{
|
||||
return SequencerBase::Instance();
|
||||
}
|
||||
|
||||
} // namespace Base
|
||||
} // namespace Base
|
||||
|
||||
#endif // BASE_SEQUENCER_H
|
||||
#endif // BASE_SEQUENCER_H
|
||||
|
||||
@@ -29,97 +29,98 @@
|
||||
#include <CXX/Objects.hxx>
|
||||
|
||||
|
||||
namespace Py {
|
||||
void SmartPtr::set(PyObject *pyob, bool owned)
|
||||
{
|
||||
release();
|
||||
p = pyob;
|
||||
if( !owned )
|
||||
{
|
||||
Py::_XINCREF( p );
|
||||
}
|
||||
}
|
||||
|
||||
void SmartPtr::release()
|
||||
{
|
||||
Py::_XDECREF( p );
|
||||
p = nullptr;
|
||||
}
|
||||
|
||||
SmartPtr::SmartPtr()
|
||||
: p( Py::_None() )
|
||||
{
|
||||
Py::_XINCREF( p );
|
||||
}
|
||||
|
||||
SmartPtr::SmartPtr( PyObject *pyob, bool owned)
|
||||
: p( pyob )
|
||||
{
|
||||
if( !owned )
|
||||
{
|
||||
Py::_XINCREF( p );
|
||||
}
|
||||
}
|
||||
|
||||
SmartPtr::SmartPtr( const SmartPtr &ob )
|
||||
: p( ob.p )
|
||||
{
|
||||
Py::_XINCREF( p );
|
||||
}
|
||||
|
||||
SmartPtr &SmartPtr::operator=( const SmartPtr &rhs )
|
||||
{
|
||||
set( rhs.ptr() );
|
||||
return *this;
|
||||
}
|
||||
|
||||
SmartPtr &SmartPtr::operator=( const Object &rhs )
|
||||
{
|
||||
set( rhs.ptr() );
|
||||
return *this;
|
||||
}
|
||||
|
||||
SmartPtr &SmartPtr::operator=( PyObject *rhsp )
|
||||
{
|
||||
if( ptr() != rhsp )
|
||||
set( rhsp );
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
SmartPtr::~SmartPtr()
|
||||
{
|
||||
release();
|
||||
}
|
||||
|
||||
PyObject *SmartPtr::operator*() const
|
||||
{
|
||||
return p;
|
||||
}
|
||||
|
||||
PyObject *SmartPtr::ptr() const
|
||||
{
|
||||
return p;
|
||||
}
|
||||
|
||||
bool SmartPtr::is( PyObject *pother ) const
|
||||
{ // identity test
|
||||
return p == pother;
|
||||
}
|
||||
|
||||
bool SmartPtr::is( const SmartPtr &other ) const
|
||||
{ // identity test
|
||||
return p == other.p;
|
||||
}
|
||||
|
||||
bool SmartPtr::isNull() const
|
||||
{
|
||||
return p == nullptr;
|
||||
}
|
||||
|
||||
BaseExport PyObject* new_reference_to(const SmartPtr& g) {
|
||||
PyObject* p = g.ptr();
|
||||
namespace Py
|
||||
{
|
||||
void SmartPtr::set(PyObject* pyob, bool owned)
|
||||
{
|
||||
release();
|
||||
p = pyob;
|
||||
if (!owned) {
|
||||
Py::_XINCREF(p);
|
||||
return p;
|
||||
}
|
||||
}
|
||||
|
||||
void SmartPtr::release()
|
||||
{
|
||||
Py::_XDECREF(p);
|
||||
p = nullptr;
|
||||
}
|
||||
|
||||
SmartPtr::SmartPtr()
|
||||
: p(Py::_None())
|
||||
{
|
||||
Py::_XINCREF(p);
|
||||
}
|
||||
|
||||
SmartPtr::SmartPtr(PyObject* pyob, bool owned)
|
||||
: p(pyob)
|
||||
{
|
||||
if (!owned) {
|
||||
Py::_XINCREF(p);
|
||||
}
|
||||
}
|
||||
|
||||
SmartPtr::SmartPtr(const SmartPtr& ob)
|
||||
: p(ob.p)
|
||||
{
|
||||
Py::_XINCREF(p);
|
||||
}
|
||||
|
||||
SmartPtr& SmartPtr::operator=(const SmartPtr& rhs)
|
||||
{
|
||||
set(rhs.ptr());
|
||||
return *this;
|
||||
}
|
||||
|
||||
SmartPtr& SmartPtr::operator=(const Object& rhs)
|
||||
{
|
||||
set(rhs.ptr());
|
||||
return *this;
|
||||
}
|
||||
|
||||
SmartPtr& SmartPtr::operator=(PyObject* rhsp)
|
||||
{
|
||||
if (ptr() != rhsp) {
|
||||
set(rhsp);
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
SmartPtr::~SmartPtr()
|
||||
{
|
||||
release();
|
||||
}
|
||||
|
||||
PyObject* SmartPtr::operator*() const
|
||||
{
|
||||
return p;
|
||||
}
|
||||
|
||||
PyObject* SmartPtr::ptr() const
|
||||
{
|
||||
return p;
|
||||
}
|
||||
|
||||
bool SmartPtr::is(PyObject* pother) const
|
||||
{ // identity test
|
||||
return p == pother;
|
||||
}
|
||||
|
||||
bool SmartPtr::is(const SmartPtr& other) const
|
||||
{ // identity test
|
||||
return p == other.p;
|
||||
}
|
||||
|
||||
bool SmartPtr::isNull() const
|
||||
{
|
||||
return p == nullptr;
|
||||
}
|
||||
|
||||
BaseExport PyObject* new_reference_to(const SmartPtr& g)
|
||||
{
|
||||
PyObject* p = g.ptr();
|
||||
Py::_XINCREF(p);
|
||||
return p;
|
||||
}
|
||||
} // namespace Py
|
||||
|
||||
@@ -29,7 +29,8 @@
|
||||
// forward declarations
|
||||
using PyObject = struct _object;
|
||||
|
||||
namespace Py {
|
||||
namespace Py
|
||||
{
|
||||
class Object;
|
||||
|
||||
/**
|
||||
@@ -40,50 +41,50 @@ class Object;
|
||||
*
|
||||
* \author Werner Mayer
|
||||
*/
|
||||
class BaseExport SmartPtr
|
||||
class BaseExport SmartPtr // NOLINT
|
||||
{
|
||||
private:
|
||||
PyObject *p;
|
||||
PyObject* p;
|
||||
|
||||
protected:
|
||||
void set(PyObject *pyob, bool owned = false);
|
||||
void set(PyObject* pyob, bool owned = false);
|
||||
void release();
|
||||
|
||||
public:
|
||||
SmartPtr();
|
||||
|
||||
// Constructor acquires new ownership of pointer unless explicitly told not to.
|
||||
explicit SmartPtr(PyObject *pyob, bool owned = false);
|
||||
explicit SmartPtr(PyObject* pyob, bool owned = false);
|
||||
|
||||
// Copy constructor acquires new ownership of pointer
|
||||
SmartPtr(const SmartPtr &ob);
|
||||
SmartPtr(const SmartPtr& ob);
|
||||
|
||||
// Assignment acquires new ownership of pointer
|
||||
SmartPtr &operator=( const SmartPtr &rhs );
|
||||
SmartPtr &operator=( const Object &rhs );
|
||||
SmartPtr& operator=(const SmartPtr& rhs);
|
||||
SmartPtr& operator=(const Object& rhs);
|
||||
|
||||
SmartPtr &operator=(PyObject *rhsp);
|
||||
SmartPtr& operator=(PyObject* rhsp);
|
||||
|
||||
// Destructor
|
||||
virtual ~SmartPtr();
|
||||
|
||||
// Loaning the pointer to others, retain ownership
|
||||
PyObject *operator*() const;
|
||||
PyObject* operator*() const;
|
||||
|
||||
// Would like to call this pointer() but messes up STL in SeqBase<T>
|
||||
PyObject *ptr() const;
|
||||
PyObject* ptr() const;
|
||||
//
|
||||
// Queries
|
||||
//
|
||||
|
||||
bool is(PyObject *pother) const;
|
||||
bool is(const SmartPtr &other) const;
|
||||
bool is(PyObject* pother) const;
|
||||
bool is(const SmartPtr& other) const;
|
||||
|
||||
bool isNull() const;
|
||||
};
|
||||
|
||||
BaseExport PyObject* new_reference_to(const SmartPtr&);
|
||||
|
||||
}
|
||||
} // namespace Py
|
||||
|
||||
#endif // PY_SMARTPTRPY_H
|
||||
#endif // PY_SMARTPTRPY_H
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
// clang-format off
|
||||
/**********************************************************************
|
||||
*
|
||||
*
|
||||
* StackWalker.cpp
|
||||
* http://stackwalker.codeplex.com/
|
||||
*
|
||||
@@ -9,14 +10,14 @@
|
||||
* http://www.codeproject.com/threads/StackWalker.asp
|
||||
* 2005-07-28 v2 - Changed the params of the constructor and ShowCallstack
|
||||
* (to simplify the usage)
|
||||
* 2005-08-01 v3 - Changed to use 'CONTEXT_FULL' instead of CONTEXT_ALL
|
||||
* 2005-08-01 v3 - Changed to use 'CONTEXT_FULL' instead of CONTEXT_ALL
|
||||
* (should also be enough)
|
||||
* - Changed to compile correctly with the PSDK of VC7.0
|
||||
* (GetFileVersionInfoSizeA and GetFileVersionInfoA is wrongly defined:
|
||||
* it uses LPSTR instead of LPCSTR as first parameter)
|
||||
* - Added declarations to support VC5/6 without using 'dbghelp.h'
|
||||
* - Added a 'pUserData' member to the ShowCallstack function and the
|
||||
* PReadProcessMemoryRoutine declaration (to pass some user-defined data,
|
||||
* - Added a 'pUserData' member to the ShowCallstack function and the
|
||||
* PReadProcessMemoryRoutine declaration (to pass some user-defined data,
|
||||
* which can be used in the readMemoryFunction-callback)
|
||||
* 2005-08-02 v4 - OnSymInit now also outputs the OS-Version by default
|
||||
* - Added example for doing an exception-callstack-walking in main.cpp
|
||||
@@ -56,26 +57,26 @@
|
||||
* Copyright (c) 2005-2013, Jochen Kalmbach
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* Neither the name of Jochen Kalmbach nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software without
|
||||
* specific prior written permission.
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* Neither the name of Jochen Kalmbach nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software without
|
||||
* specific prior written permission.
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
**********************************************************************/
|
||||
@@ -102,7 +103,7 @@
|
||||
// Some missing defines (for VC5/6):
|
||||
#ifndef INVALID_FILE_ATTRIBUTES
|
||||
#define INVALID_FILE_ATTRIBUTES ((DWORD)-1)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
static void MyStrCpy(char* szDest, size_t nMaxDestSize, const char* szSrc)
|
||||
@@ -263,7 +264,7 @@ public:
|
||||
m_szSymPath = _strdup(szSymPath);
|
||||
if (!this->pSI(m_hProcess, m_szSymPath, FALSE))
|
||||
this->m_parent->OnDbgHelpErr("SymInitialize", GetLastError(), 0);
|
||||
|
||||
|
||||
DWORD symOptions = this->pSGO(); // SymGetOptions
|
||||
symOptions |= SYMOPT_LOAD_LINES;
|
||||
symOptions |= SYMOPT_FAIL_CRITICAL_ERRORS;
|
||||
@@ -378,11 +379,11 @@ typedef struct IMAGEHLP_MODULE64_V2 {
|
||||
tSSO pSSO;
|
||||
|
||||
// StackWalk64()
|
||||
typedef BOOL (__stdcall *tSW)(
|
||||
DWORD MachineType,
|
||||
typedef BOOL (__stdcall *tSW)(
|
||||
DWORD MachineType,
|
||||
HANDLE hProcess,
|
||||
HANDLE hThread,
|
||||
LPSTACKFRAME64 StackFrame,
|
||||
HANDLE hThread,
|
||||
LPSTACKFRAME64 StackFrame,
|
||||
PVOID ContextRecord,
|
||||
PREAD_PROCESS_MEMORY_ROUTINE64 ReadMemoryRoutine,
|
||||
PFUNCTION_TABLE_ACCESS_ROUTINE64 FunctionTableAccessRoutine,
|
||||
@@ -869,7 +870,7 @@ BOOL StackWalker::LoadModules()
|
||||
|
||||
// The following is used to pass the "userData"-Pointer to the user-provided readMemoryFunction
|
||||
// This has to be done due to a problem with the "hProcess"-parameter in x64...
|
||||
// Because this class is in no case multi-threading-enabled (because of the limitations
|
||||
// Because this class is in no case multi-threading-enabled (because of the limitations
|
||||
// of dbghelp.dll) it is "safe" to use a static-variable
|
||||
static StackWalker::PReadProcessMemoryRoutine s_readMemoryFunction = NULL;
|
||||
static LPVOID s_readMemoryFunction_UserData = NULL;
|
||||
@@ -1079,7 +1080,7 @@ BOOL StackWalker::ShowCallstack(HANDLE hThread, const CONTEXT *context, PReadPro
|
||||
et = firstEntry;
|
||||
bLastEntryCalled = false;
|
||||
this->OnCallstackEntry(et, csEntry);
|
||||
|
||||
|
||||
if (s.AddrReturn.Offset == 0)
|
||||
{
|
||||
bLastEntryCalled = true;
|
||||
@@ -1192,3 +1193,4 @@ void StackWalker::OnOutput(LPCSTR buffer)
|
||||
{
|
||||
OutputDebugStringA(buffer);
|
||||
}
|
||||
// clang-format on
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user