Base: apply clang format

This commit is contained in:
wmayer
2023-11-10 18:27:44 +01:00
committed by WandererFan
parent bb333d9a74
commit 985def3416
154 changed files with 11874 additions and 9872 deletions

View File

@@ -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;

View File

@@ -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

View File

@@ -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>

View File

@@ -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;
}

View File

@@ -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);
}

View File

@@ -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

View File

@@ -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;
}

View File

@@ -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);
}

View File

@@ -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

View File

@@ -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

View File

@@ -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>

View File

@@ -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;
}

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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;
}

View File

@@ -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

View File

@@ -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

View File

@@ -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);
}

View File

@@ -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

View File

@@ -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;
}

View File

@@ -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();
}

View File

@@ -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

View File

@@ -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

View File

@@ -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))};
}

View File

@@ -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

View File

@@ -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);
}
}
}

View File

@@ -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

View File

@@ -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;
}

View File

@@ -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

View File

@@ -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;
}

View File

@@ -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

View File

@@ -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
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

View File

@@ -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

View File

@@ -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;

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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;

View File

@@ -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

View File

@@ -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;
}

View File

@@ -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

View File

@@ -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");

View File

@@ -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

View File

@@ -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

View File

@@ -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()

View File

@@ -50,7 +50,6 @@ private:
#endif
} //namespace Base
#endif // BASE_MEMDEBUG_H
} // namespace Base
#endif // BASE_MEMDEBUG_H

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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) {

View File

@@ -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

View File

@@ -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 += "&lt;";
else if (it == '\"')
}
else if (it == '\"') {
tmp += "&quot;";
else if (it == '\'')
}
else if (it == '\'') {
tmp += "&apos;";
else if (it == '&')
}
else if (it == '&') {
tmp += "&amp;";
else if (it == '>')
}
else if (it == '>') {
tmp += "&gt;";
else if (it == '\r')
}
else if (it == '\r') {
tmp += "&#13;";
else if (it == '\n')
}
else if (it == '\n') {
tmp += "&#10;";
else if (it == '\t')
}
else if (it == '\t') {
tmp += "&#9;";
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);

View File

@@ -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

View File

@@ -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>

View File

@@ -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;
}

View File

@@ -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};
}

View File

@@ -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

View File

@@ -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>

View File

@@ -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, &center.x, &center.y, &center.z,
&axis.x, &axis.y, &axis.z, &angle, &PyBool_Type, &pyComp)) {
if (!Base::Wrapped_ParseTupleAndKeywords(args,
kwds,
"(ddd)(ddd)d|O!",
kwlist,
&center.x, &center.y, &center.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;
}

View File

@@ -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

View File

@@ -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

View File

@@ -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;
}

View File

@@ -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();
}

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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;

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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;
}

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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;
}

View File

@@ -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);
}

View File

@@ -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

View File

@@ -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

View File

@@ -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;
}

View File

@@ -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);
}

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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