App: add class PropertyRotation

This commit is contained in:
wmayer
2021-10-29 12:40:32 +02:00
parent 09e2e7acfa
commit 16ae568549
3 changed files with 250 additions and 2 deletions

View File

@@ -1810,6 +1810,7 @@ void Application::initTypes(void)
App ::PropertyPlacement ::init();
App ::PropertyPlacementList ::init();
App ::PropertyPlacementLink ::init();
App ::PropertyRotation ::init();
App ::PropertyGeometry ::init();
App ::PropertyComplexGeoData ::init();
App ::PropertyColor ::init();

View File

@@ -40,6 +40,7 @@
#include <Base/MatrixPy.h>
#include <Base/PlacementPy.h>
#include <Base/QuantityPy.h>
#include <Base/RotationPy.h>
#include "Document.h"
#include "DocumentObject.h"
@@ -938,6 +939,183 @@ void PropertyPlacementLink::Paste(const Property &from)
hasSetValue();
}
//**************************************************************************
//**************************************************************************
// PropertyRotation
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
TYPESYSTEM_SOURCE(App::PropertyRotation , App::Property)
PropertyRotation::PropertyRotation()
{
}
PropertyRotation::~PropertyRotation()
{
}
void PropertyRotation::setValue(const Base::Rotation &rot)
{
aboutToSetValue();
_rot = rot;
hasSetValue();
}
bool PropertyRotation::setValueIfChanged(const Base::Rotation &rot, double atol)
{
if (_rot.isSame(rot, atol)) {
return false;
}
setValue(rot);
return true;
}
const Base::Rotation & PropertyRotation::getValue() const
{
return _rot;
}
void PropertyRotation::getPaths(std::vector<ObjectIdentifier> &paths) const
{
paths.push_back(ObjectIdentifier(*this)
<< ObjectIdentifier::SimpleComponent(ObjectIdentifier::String("Angle")));
paths.push_back(ObjectIdentifier(*this)
<< ObjectIdentifier::SimpleComponent(ObjectIdentifier::String("Axis"))
<< ObjectIdentifier::SimpleComponent(ObjectIdentifier::String("x")));
paths.push_back(ObjectIdentifier(*this)
<< ObjectIdentifier::SimpleComponent(ObjectIdentifier::String("Axis"))
<< ObjectIdentifier::SimpleComponent(ObjectIdentifier::String("y")));
paths.push_back(ObjectIdentifier(*this)
<< ObjectIdentifier::SimpleComponent(ObjectIdentifier::String("Axis"))
<< ObjectIdentifier::SimpleComponent(ObjectIdentifier::String("z")));
}
void PropertyRotation::setPathValue(const ObjectIdentifier &path, const boost::any &value)
{
if (path.getSubPathStr() == ".Angle") {
double avalue;
if (value.type() == typeid(Base::Quantity))
avalue = boost::any_cast<Base::Quantity>(value).getValue();
else if (value.type() == typeid(double))
avalue = boost::any_cast<double>(value);
else if (value.type() == typeid(int))
avalue = boost::any_cast<int>(value);
else if (value.type() == typeid(unsigned int))
avalue = boost::any_cast<unsigned int >(value);
else if (value.type() == typeid(short))
avalue = boost::any_cast<short>(value);
else if (value.type() == typeid(unsigned short))
avalue = boost::any_cast<unsigned short>(value);
else if (value.type() == typeid(long))
avalue = boost::any_cast<long>(value);
else if (value.type() == typeid(unsigned long))
avalue = boost::any_cast<unsigned long>(value);
else
throw std::bad_cast();
Property::setPathValue(path, Base::toRadians(avalue));
}
else {
Property::setPathValue(path, value);
}
}
const boost::any PropertyRotation::getPathValue(const ObjectIdentifier &path) const
{
std::string p = path.getSubPathStr();
if (p == ".Angle") {
// Convert angle to degrees
return Base::Quantity(Base::toDegrees(boost::any_cast<double>(Property::getPathValue(path))), Unit::Angle);
}
else {
return Property::getPathValue(path);
}
}
bool PropertyRotation::getPyPathValue(const ObjectIdentifier &path, Py::Object &res) const
{
std::string p = path.getSubPathStr();
if (p == ".Angle") {
Base::Vector3d axis; double angle;
_rot.getValue(axis,angle);
res = Py::asObject(new QuantityPy(new Quantity(Base::toDegrees(angle),Unit::Angle)));
return true;
}
return false;
}
PyObject *PropertyRotation::getPyObject()
{
return new Base::RotationPy(new Base::Rotation(_rot));
}
void PropertyRotation::setPyObject(PyObject *value)
{
if (PyObject_TypeCheck(value, &(Base::MatrixPy::Type))) {
Base::MatrixPy *object = static_cast<Base::MatrixPy*>(value);
Base::Matrix4D mat = object->value();
Base::Rotation p;
p.setValue(mat);
setValue(p);
}
else if (PyObject_TypeCheck(value, &(Base::RotationPy::Type))) {
setValue(*static_cast<Base::RotationPy*>(value)->getRotationPtr());
}
else {
std::string error = std::string("type must be 'Matrix' or 'Rotation', not ");
error += value->ob_type->tp_name;
throw Base::TypeError(error);
}
}
void PropertyRotation::Save (Base::Writer &writer) const
{
Vector3d axis;
double rfAngle;
_rot.getValue(axis, rfAngle);
writer.Stream() << writer.ind() << "<PropertyRotation";
writer.Stream() << " A=\"" << rfAngle << "\""
<< " Ox=\"" << axis.x << "\""
<< " Oy=\"" << axis.y << "\""
<< " Oz=\"" << axis.z << "\""
<< "/>\n";
}
void PropertyRotation::Restore(Base::XMLReader &reader)
{
reader.readElement("PropertyRotation");
aboutToSetValue();
_rot = Rotation(Vector3d(reader.getAttributeAsFloat("Ox"),
reader.getAttributeAsFloat("Oy"),
reader.getAttributeAsFloat("Oz")),
reader.getAttributeAsFloat("A"));
hasSetValue();
}
Property *PropertyRotation::Copy() const
{
PropertyRotation *p = new PropertyRotation();
p->_rot = _rot;
return p;
}
void PropertyRotation::Paste(const Property &from)
{
aboutToSetValue();
_rot = dynamic_cast<const PropertyRotation&>(from)._rot;
hasSetValue();
}
// ------------------------------------------------------------
TYPESYSTEM_SOURCE_ABSTRACT(App::PropertyGeometry , App::Property)

View File

@@ -35,6 +35,7 @@
#include "Property.h"
#include "PropertyLinks.h"
#include "ComplexGeoData.h"
#include <FCGlobal.h>
namespace Base {
class Writer;
@@ -281,8 +282,9 @@ private:
Base::Matrix4D _cMat;
};
/** Vector properties
* This is the father of all properties handling Integers.
/// Property representing a placement
/*!
* Encapsulates a Base::Placement in a Property
*/
class AppExport PropertyPlacement: public Property
{
@@ -408,6 +410,73 @@ protected:
};
/// Property representing a rotation
/*!
* Encapsulates a Base::Rotation in a Property
*/
class AppExport PropertyRotation : public Property
{
TYPESYSTEM_HEADER_WITH_OVERRIDE();
public:
/**
* A constructor.
* A more elaborate description of the constructor.
*/
PropertyRotation();
/**
* A destructor.
* A more elaborate description of the destructor.
*/
virtual ~PropertyRotation();
/** Sets the property
*/
void setValue(const Base::Rotation &rot);
/** Sets property only if changed
* @param pos: input placement
* @param tol: position tolerance
* @param atol: angular tolerance
*/
bool setValueIfChanged(const Base::Rotation &rot, double atol=1e-12);
/** This method returns a string representation of the property
*/
const Base::Rotation &getValue() const;
/// Get valid paths for this property; used by auto completer
void getPaths(std::vector<ObjectIdentifier> &paths) const override;
void setPathValue(const ObjectIdentifier &path, const boost::any &value) override;
virtual const boost::any getPathValue(const ObjectIdentifier &path) const override;
virtual bool getPyPathValue(const ObjectIdentifier &path, Py::Object &res) const override;
const char* getEditorName() const override {
return "Gui::PropertyEditor::PropertyRotationItem";
}
virtual PyObject *getPyObject() override;
virtual void setPyObject(PyObject *) override;
virtual void Save (Base::Writer &writer) const override;
virtual void Restore(Base::XMLReader &reader) override;
virtual Property *Copy() const override;
virtual void Paste(const Property &from) override;
virtual unsigned int getMemSize () const override {
return sizeof(Base::Placement);
}
private:
Base::Rotation _rot;
};
/** The base class for all basic geometry properties.
* @author Werner Mayer
*/