This commit is contained in:
Keith Sloan
2017-05-12 14:28:25 +01:00
19 changed files with 547 additions and 42 deletions

View File

@@ -184,7 +184,7 @@ before_install:
export INSTALLED_APP_PATH="/usr/local/MacOS/FreeCAD"
fi
export CMAKE_ARGS="${CMAKE_OPTS} -DFREECAD_USE_EXTERNAL_KDL=ON"
export CMAKE_ARGS="${CMAKE_OPTS} -DFREECAD_USE_EXTERNAL_KDL=ON -DEIGEN3_INCLUDE_DIR=$(brew --prefix eigen@3.2)/include/eigen3"
;;
*)

View File

@@ -267,13 +267,21 @@ PyObject* DocumentObjectPy::setExpression(PyObject * args)
if (Py::Object(expr).isNone())
getDocumentObjectPtr()->setExpression(p, boost::shared_ptr<Expression>());
#if PY_MAJOR_VERSION >= 3
else if (PyUnicode_Check(expr)) {
const char * exprStr = PyUnicode_AsUTF8(expr);
#else
else if (PyString_Check(expr)) {
const char * exprStr = PyString_AsString(expr);
#endif
boost::shared_ptr<Expression> shared_expr(ExpressionParser::parse(getDocumentObjectPtr(), exprStr));
getDocumentObjectPtr()->setExpression(p, shared_expr, comment);
}
else if (PyUnicode_Check(expr)) {
#if PY_MAJOR_VERSION >= 3
std::string exprStr = PyUnicode_AsUTF8(expr);
#else
PyObject* unicode = PyUnicode_AsEncodedString(expr, "utf-8", 0);
if (unicode) {
std::string exprStr = PyString_AsString(unicode);
@@ -286,6 +294,7 @@ PyObject* DocumentObjectPy::setExpression(PyObject * args)
// utf-8 encoding failed
return 0;
}
#endif
}
else
throw Py::TypeError("String or None expected.");

View File

@@ -211,7 +211,11 @@ PyObject* DocumentPy::exportGraphviz(PyObject * args)
else {
std::stringstream str;
getDocumentPtr()->exportGraphviz(str);
#if PY_MAJOR_VERSION >= 3
return PyUnicode_FromString(str.str().c_str());
#else
return PyString_FromString(str.str().c_str());
#endif
}
}
@@ -326,6 +330,13 @@ PyObject* DocumentPy::openTransaction(PyObject *args)
if (!PyArg_ParseTuple(args, "|O",&value))
return NULL; // NULL triggers exception
std::string cmd;
#if PY_MAJOR_VERSION >= 3
if (PyUnicode_Check(value)) {
cmd = PyUnicode_AsUTF8(value);
}
#else
if (PyUnicode_Check(value)) {
PyObject* unicode = PyUnicode_AsLatin1String(value);
cmd = PyString_AsString(unicode);
@@ -334,6 +345,12 @@ PyObject* DocumentPy::openTransaction(PyObject *args)
else if (PyString_Check(value)) {
cmd = PyString_AsString(value);
}
#endif
else {
PyErr_SetString(PyExc_TypeError, "string or unicode expected");
return NULL;
}
getDocumentPtr()->openTransaction(cmd.c_str());
Py_Return;
}
@@ -521,9 +538,10 @@ Py::Int DocumentPy::getUndoMode(void) const
void DocumentPy::setUndoMode(Py::Int arg)
{
getDocumentPtr()->setUndoMode(arg);
getDocumentPtr()->setUndoMode(arg);
}
Py::Int DocumentPy::getUndoRedoMemSize(void) const
{
return Py::Int((long)getDocumentPtr()->getUndoMemSize());
@@ -591,12 +609,16 @@ PyObject* DocumentPy::getTempFileName(PyObject *args)
std::string string;
if (PyUnicode_Check(value)) {
#if PY_MAJOR_VERSION >= 3
string = PyUnicode_AsUTF8(value);
#else
PyObject* unicode = PyUnicode_AsUTF8String(value);
string = PyString_AsString(unicode);
Py_DECREF(unicode);
}
else if (PyString_Check(value)) {
string = PyString_AsString(value);
#endif
}
else {
std::string error = std::string("type must be a string!");

View File

@@ -37,6 +37,29 @@
virtual ~_class_(); \
};
#if PY_MAJOR_VERSION >= 3
#define PYTHON_TYPE_IMP(_class_, _subclass_) \
PyTypeObject _class_::Type = { \
PyVarObject_HEAD_INIT(&PyType_Type, 0) \
""#_class_"", \
sizeof(_class_), \
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
Py_TPFLAGS_BASETYPE|Py_TPFLAGS_DEFAULT, \
""#_class_"", \
0, 0, 0, 0, 0, 0, 0, 0, 0, \
&_subclass_::Type, \
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 \
}; \
_class_::_class_(Base::BaseClass *pcObject, PyTypeObject *T) \
: _subclass_(reinterpret_cast<_subclass_::PointerType>(pcObject), T) \
{ \
} \
_class_::~_class_() \
{ \
}
#else
#define PYTHON_TYPE_IMP(_class_, _subclass_) \
PyTypeObject _class_::Type = { \
PyObject_HEAD_INIT(&PyType_Type) \
@@ -58,6 +81,8 @@
{ \
}
#endif
namespace App
{

View File

@@ -1035,18 +1035,28 @@ boost::any ObjectIdentifier::getValue() const
if (!pyvalue)
throw Base::RuntimeError("Failed to get property value.");
#if PY_MAJOR_VERSION < 3
if (PyInt_Check(pyvalue))
return boost::any(PyInt_AsLong(pyvalue));
#else
if (PyLong_Check(pyvalue))
return boost::any(PyLong_AsLong(pyvalue));
#endif
else if (PyFloat_Check(pyvalue))
return boost::any(PyFloat_AsDouble(pyvalue));
#if PY_MAJOR_VERSION < 3
else if (PyString_Check(pyvalue))
return boost::any(PyString_AsString(pyvalue));
#endif
else if (PyUnicode_Check(pyvalue)) {
PyObject * s = PyUnicode_AsUTF8String(pyvalue);
destructor d2(s);
#if PY_MAJOR_VERSION >= 3
return boost::any(PyUnicode_AsUTF8(s));
#else
return boost::any(PyString_AsString(s));
#endif
}
else if (PyObject_TypeCheck(pyvalue, &Base::QuantityPy::Type)) {
Base::QuantityPy * qp = static_cast<Base::QuantityPy*>(pyvalue);

View File

@@ -244,7 +244,11 @@ PyObject *PropertyContainerPy::getCustomAttributes(const char* attr) const
PyObject *dict = PyDict_New();
if (dict) {
for ( std::map<std::string,App::Property*>::iterator it = Map.begin(); it != Map.end(); ++it )
#if PY_MAJOR_VERSION >= 3
PyDict_SetItem(dict, PyUnicode_FromString(it->first.c_str()), PyUnicode_FromString(""));
#else
PyDict_SetItem(dict, PyString_FromString(it->first.c_str()), PyString_FromString(""));
#endif
if (PyErr_Occurred()) {
Py_DECREF(dict);
dict = NULL;

View File

@@ -253,8 +253,55 @@ PyObject *PropertyFileIncluded::getPyObject(void)
return p;
}
#if PY_MAJOR_VERSION >= 3
namespace App {
const char* getNameFromFile(PyObject* value)
{
const char* string = 0;
PyObject *oname = PyObject_GetAttrString (value, "name");
if (oname) {
if (PyUnicode_Check (oname)) {
string = PyUnicode_AsUTF8 (oname);
}
else if (PyBytes_Check (oname)) {
string = PyBytes_AsString (oname);
}
Py_DECREF (oname);
}
if (!string)
throw Base::TypeError("Unable to get filename");
return string;
}
bool isIOFile(PyObject* file)
{
PyObject* io = PyImport_ImportModule("io");
PyObject* IOBase_Class = PyObject_GetAttrString(io, "IOBase");
bool isFile = PyObject_IsInstance(file, IOBase_Class);
Py_DECREF(IOBase_Class);
Py_DECREF(io);
return isFile;
}
}
#endif
void PropertyFileIncluded::setPyObject(PyObject *value)
{
#if PY_MAJOR_VERSION >= 3
std::string string;
if (PyUnicode_Check(value)) {
string = PyUnicode_AsUTF8(value);
}
else if (PyBytes_Check(value)) {
string = PyBytes_AsString(value);
}
else if (isIOFile(value)){
string = getNameFromFile(value);
}
#else
std::string string;
if (PyUnicode_Check(value)) {
PyObject* unicode = PyUnicode_AsUTF8String(value);
@@ -268,6 +315,7 @@ void PropertyFileIncluded::setPyObject(PyObject *value)
PyObject* FileName = PyFile_Name(value);
string = PyString_AsString(FileName);
}
#endif
else if (PyTuple_Check(value)) {
if (PyTuple_Size(value) != 2)
throw Base::TypeError("Tuple needs size of (filePath,newFileName)");
@@ -276,6 +324,17 @@ void PropertyFileIncluded::setPyObject(PyObject *value)
// decoding file
std::string fileStr;
#if PY_MAJOR_VERSION >= 3
if (PyUnicode_Check(file)) {
fileStr = PyUnicode_AsUTF8(file);
}
else if (PyBytes_Check(file)) {
fileStr = PyBytes_AsString(file);
}
else if (isIOFile(value)) {
fileStr = getNameFromFile(file);
}
#else
if (PyUnicode_Check(file)) {
PyObject* unicode = PyUnicode_AsUTF8String(file);
fileStr = PyString_AsString(unicode);
@@ -288,6 +347,7 @@ void PropertyFileIncluded::setPyObject(PyObject *value)
PyObject* FileName = PyFile_Name(file);
fileStr = PyString_AsString(FileName);
}
#endif
else {
std::string error = std::string("First item in tuple must be a file or string, not ");
error += file->ob_type->tp_name;
@@ -296,6 +356,17 @@ void PropertyFileIncluded::setPyObject(PyObject *value)
// decoding name
std::string nameStr;
#if PY_MAJOR_VERSION >= 3
if (PyUnicode_Check(name)) {
nameStr = PyUnicode_AsUTF8(name);
}
else if (PyBytes_Check(name)) {
nameStr = PyBytes_AsString(name);
}
else if (isIOFile(value)) {
nameStr = getNameFromFile(name);
}
#else
if (PyString_Check(name)) {
nameStr = PyString_AsString(name);
}
@@ -303,6 +374,7 @@ void PropertyFileIncluded::setPyObject(PyObject *value)
PyObject* FileName = PyFile_Name(name);
nameStr = PyString_AsString(FileName);
}
#endif
else {
std::string error = std::string("Second item in tuple must be a string, not ");
error += name->ob_type->tp_name;

View File

@@ -115,24 +115,39 @@ void PropertyVector::setPyObject(PyObject *value)
item = PyTuple_GetItem(value,0);
if (PyFloat_Check(item))
cVec.x = PyFloat_AsDouble(item);
#if PY_MAJOR_VERSION < 3
else if (PyInt_Check(item))
cVec.x = (double)PyInt_AsLong(item);
#else
else if (PyLong_Check(item))
cVec.x = (double)PyLong_AsLong(item);
#endif
else
throw Base::TypeError("Not allowed type used in tuple (float expected)...");
// y
item = PyTuple_GetItem(value,1);
if (PyFloat_Check(item))
cVec.y = PyFloat_AsDouble(item);
#if PY_MAJOR_VERSION < 3
else if (PyInt_Check(item))
cVec.y = (double)PyInt_AsLong(item);
#else
else if (PyLong_Check(item))
cVec.y = (double)PyLong_AsLong(item);
#endif
else
throw Base::TypeError("Not allowed type used in tuple (float expected)...");
// z
item = PyTuple_GetItem(value,2);
if (PyFloat_Check(item))
cVec.z = PyFloat_AsDouble(item);
#if PY_MAJOR_VERSION < 3
else if (PyInt_Check(item))
cVec.z = (double)PyInt_AsLong(item);
#else
else if (PyLong_Check(item))
cVec.z = (double)PyLong_AsLong(item);
#endif
else
throw Base::TypeError("Not allowed type used in tuple (float expected)...");
setValue( cVec );
@@ -433,8 +448,13 @@ void PropertyMatrix::setPyObject(PyObject *value)
item = PyTuple_GetItem(value,x+y*4);
if (PyFloat_Check(item))
cMatrix[x][y] = PyFloat_AsDouble(item);
#if PY_MAJOR_VERSION < 3
else if (PyInt_Check(item))
cMatrix[x][y] = (double)PyInt_AsLong(item);
#else
else if (PyLong_Check(item))
cMatrix[x][y] = (double)PyLong_AsLong(item);
#endif
else
throw Base::TypeError("Not allowed type used in matrix tuple (a number expected)...");
}

View File

@@ -325,10 +325,14 @@ void PropertyPythonObject::Restore(Base::XMLReader &reader)
if (reader.hasAttribute("module") && reader.hasAttribute("class")) {
Py::Module mod(PyImport_ImportModule(reader.getAttribute("module")),true);
PyObject* cls = mod.getAttr(reader.getAttribute("class")).ptr();
#if PY_MAJOR_VERSION >= 3
if (PyType_Check(cls)) {
#else
if (PyClass_Check(cls)) {
this->object = PyInstance_NewRaw(cls, 0);
}
else if (PyType_Check(cls)) {
#endif
this->object = PyType_GenericAlloc((PyTypeObject*)cls, 0);
}
else {
@@ -340,7 +344,11 @@ void PropertyPythonObject::Restore(Base::XMLReader &reader)
std::string nam = std::string(what[1].first, what[1].second);
std::string cls = std::string(what[2].first, what[2].second);
Py::Module mod(PyImport_ImportModule(nam.c_str()),true);
#if PY_MAJOR_VERSION >= 3
this->object = PyObject_CallObject(mod.getAttr(cls).ptr(), NULL);
#else
this->object = PyInstance_NewRaw(mod.getAttr(cls).ptr(), 0);
#endif
load_pickle = true;
buffer = std::string(what[2].second, end);
}

View File

@@ -94,9 +94,15 @@ PyObject *PropertyInteger::getPyObject(void)
void PropertyInteger::setPyObject(PyObject *value)
{
#if PY_MAJOR_VERSION < 3
if (PyInt_Check(value)) {
aboutToSetValue();
_lValue = PyInt_AsLong(value);
#else
if (PyLong_Check(value)) {
aboutToSetValue();
_lValue = PyLong_AsLong(value);
#endif
hasSetValue();
}
else {
@@ -221,12 +227,16 @@ void PropertyPath::setPyObject(PyObject *value)
{
std::string path;
if (PyUnicode_Check(value)) {
#if PY_MAJOR_VERSION >= 3
path = PyUnicode_AsUTF8(value);
#else
PyObject* unicode = PyUnicode_AsUTF8String(value);
path = PyString_AsString(unicode);
Py_DECREF(unicode);
}
else if (PyString_Check(value)) {
path = PyString_AsString(value);
#endif
}
else {
std::string error = std::string("type must be str or unicode, not ");
@@ -419,15 +429,48 @@ PyObject * PropertyEnumeration::getPyObject(void)
}
void PropertyEnumeration::setPyObject(PyObject *value)
{
{
#if PY_MAJOR_VERSION < 3
if (PyInt_Check(value)) {
long val = PyInt_AsLong(value);
#else
if (PyLong_Check(value)) {
long val = PyLong_AsLong(value);
#endif
if (_enum.isValid()) {
aboutToSetValue();
_enum.setValue(val, true);
hasSetValue();
}
}
else if (PyUnicode_Check(value)) {
#if PY_MAJOR_VERSION >= 3
const char* str = PyUnicode_AsUTF8 (value);
if (_enum.contains(str)) {
aboutToSetValue();
_enum.setValue(PyUnicode_AsUTF8 (value));
hasSetValue();
}
else {
std::stringstream out;
out << "'" << str << "' is not part of the enumeration";
throw Base::ValueError(out.str());
}
#else
PyObject* unicode = PyUnicode_AsUTF8String(value);
const char* str = PyString_AsString (unicode);
if (_enum.contains(str)) {
aboutToSetValue();
_enum.setValue(PyString_AsString (unicode));
hasSetValue();
}
else {
std::stringstream out;
out << "'" << str << "' is not part of the enumeration";
throw Base::ValueError(out.str());
}
Py_DECREF(unicode);
}
else if (PyString_Check(value)) {
const char* str = PyString_AsString (value);
if (_enum.contains(str)) {
@@ -440,11 +483,16 @@ void PropertyEnumeration::setPyObject(PyObject *value)
out << "'" << str << "' is not part of the enumeration";
throw Base::ValueError(out.str());
}
#endif
}
else if (PyUnicode_Check(value)) {
#if PY_MAJOR_VERSION >=3
std::string str = PyUnicode_AsUTF8(value);
#else
PyObject* unicode = PyUnicode_AsUTF8String(value);
std::string str = PyString_AsString(unicode);
Py_DECREF(unicode);
#endif
if (_enum.contains(str.c_str())) {
aboutToSetValue();
_enum.setValue(str);
@@ -464,20 +512,25 @@ void PropertyEnumeration::setPyObject(PyObject *value)
for (Py_ssize_t i = 0; i < nSize; ++i) {
PyObject *item = PySequence_GetItem(value, i);
if (PyString_Check(item)) {
values[i] = PyString_AsString(item);
}
else if (PyUnicode_Check(item)) {
if (PyUnicode_Check(item)) {
#if PY_MAJOR_VERSION >= 3
values[i] = PyUnicode_AsUTF8(item);
#else
PyObject* unicode = PyUnicode_AsUTF8String(item);
values[i] = PyString_AsString(unicode);
Py_DECREF(unicode);
#endif
}
#if PY_MAJOR_VERSION < 3
if (PyString_Check(item)) {
values[i] = PyString_AsString(item);
}
#endif
else {
std::string error = std::string("type in list must be str or unicode, not ");
throw Base::TypeError(error + item->ob_type->tp_name);
}
}
_enum.setEnums(values);
setValue((long)0);
}
@@ -556,9 +609,14 @@ const PropertyIntegerConstraint::Constraints* PropertyIntegerConstraint::getCon
}
void PropertyIntegerConstraint::setPyObject(PyObject *value)
{
{
#if PY_MAJOR_VERSION < 3
if (PyInt_Check(value)) {
long temp = PyInt_AsLong(value);
#else
if (PyLong_Check(value)) {
long temp = PyLong_AsLong(value);
#endif
if (_ConstStruct) {
if (temp > _ConstStruct->UpperBound)
temp = _ConstStruct->UpperBound;
@@ -575,8 +633,13 @@ void PropertyIntegerConstraint::setPyObject(PyObject *value)
for (int i=0; i<4; i++) {
PyObject* item;
item = PyTuple_GetItem(value,i);
#if PY_MAJOR_VERSION < 3
if (PyInt_Check(item))
values[i] = PyInt_AsLong(item);
#else
if (PyLong_Check(item))
values[i] = PyLong_AsLong(item);
#endif
else
throw Base::TypeError("Type in tuple must be int");
}
@@ -682,7 +745,11 @@ PyObject *PropertyIntegerList::getPyObject(void)
{
PyObject* list = PyList_New(getSize());
for(int i = 0;i<getSize(); i++)
#if PY_MAJOR_VERSION < 3
PyList_SetItem( list, i, PyInt_FromLong(_lValueList[i]));
#else
PyList_SetItem( list, i, PyLong_FromLong(_lValueList[i]));
#endif
return list;
}
@@ -695,18 +762,32 @@ void PropertyIntegerList::setPyObject(PyObject *value)
for (Py_ssize_t i=0; i<nSize;++i) {
PyObject* item = PySequence_GetItem(value, i);
#if PY_MAJOR_VERSION < 3
if (!PyInt_Check(item)) {
std::string error = std::string("type in list must be int, not ");
error += item->ob_type->tp_name;
throw Base::TypeError(error);
}
values[i] = PyInt_AsLong(item);
#else
if (!PyLong_Check(item)) {
std::string error = std::string("type in list must be int, not ");
error += item->ob_type->tp_name;
throw Base::TypeError(error);
}
values[i] = PyLong_AsLong(item);
#endif
}
setValues(values);
}
#if PY_MAJOR_VERSION < 3
else if (PyInt_Check(value)) {
setValue(PyInt_AsLong(value));
#else
else if (PyLong_Check(value)) {
setValue(PyLong_AsLong(value));
#endif
}
else {
std::string error = std::string("type must be int or a sequence of int, not ");
@@ -810,7 +891,11 @@ PyObject *PropertyIntegerSet::getPyObject(void)
{
PyObject* set = PySet_New(NULL);
for(std::set<long>::const_iterator it=_lValueSet.begin();it!=_lValueSet.end();++it)
#if PY_MAJOR_VERSION < 3
PySet_Add(set,PyInt_FromLong(*it));
#else
PySet_Add(set,PyLong_FromLong(*it));
#endif
return set;
}
@@ -823,18 +908,32 @@ void PropertyIntegerSet::setPyObject(PyObject *value)
for (Py_ssize_t i=0; i<nSize;++i) {
PyObject* item = PySequence_GetItem(value, i);
#if PY_MAJOR_VERSION < 3
if (!PyInt_Check(item)) {
std::string error = std::string("type in list must be int, not ");
error += item->ob_type->tp_name;
throw Base::TypeError(error);
}
values.insert(PyInt_AsLong(item));
#else
if (!PyLong_Check(item)) {
std::string error = std::string("type in list must be int, not ");
error += item->ob_type->tp_name;
throw Base::TypeError(error);
}
values.insert(PyLong_AsLong(item));
#endif
}
setValues(values);
}
#if PY_MAJOR_VERSION < 3
else if (PyInt_Check(value)) {
setValue(PyInt_AsLong(value));
#else
else if (PyLong_Check(value)) {
setValue(PyLong_AsLong(value));
#endif
}
else {
std::string error = std::string("type must be int or list of int, not ");
@@ -941,9 +1040,15 @@ void PropertyFloat::setPyObject(PyObject *value)
_dValue = PyFloat_AsDouble(value);
hasSetValue();
}
#if PY_MAJOR_VERSION < 3
else if(PyInt_Check(value)) {
aboutToSetValue();
_dValue = PyInt_AsLong(value);
#else
else if(PyLong_Check(value)) {
aboutToSetValue();
_dValue = PyLong_AsLong(value);
#endif
hasSetValue();
}
else {
@@ -1045,8 +1150,13 @@ void PropertyFloatConstraint::setPyObject(PyObject *value)
_dValue = temp;
hasSetValue();
}
#if PY_MAJOR_VERSION < 3
else if (PyInt_Check(value)) {
double temp = (double)PyInt_AsLong(value);
#else
else if (PyLong_Check(value)) {
double temp = (double)PyLong_AsLong(value);
#endif
if (_ConstStruct) {
if (temp > _ConstStruct->UpperBound)
temp = _ConstStruct->UpperBound;
@@ -1065,8 +1175,13 @@ void PropertyFloatConstraint::setPyObject(PyObject *value)
item = PyTuple_GetItem(value,i);
if (PyFloat_Check(item))
values[i] = PyFloat_AsDouble(item);
#if PY_MAJOR_VERSION < 3
else if (PyInt_Check(item))
values[i] = PyInt_AsLong(item);
#else
else if (PyLong_Check(item))
values[i] = PyLong_AsLong(item);
#endif
else
throw Base::TypeError("Type in tuple must be float or int");
}
@@ -1186,7 +1301,7 @@ void PropertyFloatList::setPyObject(PyObject *value)
PyObject* item = PyList_GetItem(value, i);
if (PyFloat_Check(item)) {
values[i] = PyFloat_AsDouble(item);
#if PYTHON_VERSION_MAJOR >= 3
#if PY_MAJOR_VERSION >= 3
} else if (PyLong_Check(item)) {
values[i] = static_cast<double>(PyLong_AsLong(item));
#else
@@ -1346,12 +1461,16 @@ void PropertyString::setPyObject(PyObject *value)
{
std::string string;
if (PyUnicode_Check(value)) {
#if PY_MAJOR_VERSION >= 3
string = PyUnicode_AsUTF8(value);
#else
PyObject* unicode = PyUnicode_AsUTF8String(value);
string = PyString_AsString(unicode);
Py_DECREF(unicode);
}
else if (PyString_Check(value)) {
string = PyString_AsString(value);
#endif
}
else {
std::string error = std::string("type must be str or unicode, not ");
@@ -1459,18 +1578,31 @@ const Base::Uuid& PropertyUUID::getValue(void) const
PyObject *PropertyUUID::getPyObject(void)
{
#if PY_MAJOR_VERSION >= 3
PyObject *p = PyUnicode_FromString(_uuid.getValue().c_str());
#else
PyObject *p = PyString_FromString(_uuid.getValue().c_str());
#endif
return p;
}
void PropertyUUID::setPyObject(PyObject *value)
{
std::string string;
if (PyString_Check(value)) {
if (PyUnicode_Check(value)) {
#if PY_MAJOR_VERSION >= 3
string = PyUnicode_AsUTF8(value);
#else
PyObject* unicode = PyUnicode_AsUTF8String(value);
string = PyString_AsString(unicode);
Py_DECREF(unicode);
}
else if (PyString_Check(value)) {
string = PyString_AsString(value);
#endif
}
else {
std::string error = std::string("type must be a str, not ");
std::string error = std::string("type must be unicode or str, not ");
error += value->ob_type->tp_name;
throw Base::TypeError(error);
}
@@ -1604,9 +1736,15 @@ PyObject *PropertyStringList::getPyObject(void)
void PropertyStringList::setPyObject(PyObject *value)
{
#if PY_MAJOR_VERSION >=3
if (PyBytes_Check(value)) {
setValue(PyBytes_AsString(value));
}
#else
if (PyString_Check(value)) {
setValue(PyString_AsString(value));
}
#endif
else if (PySequence_Check(value)) {
Py_ssize_t nSize = PySequence_Size(value);
std::vector<std::string> values;
@@ -1615,12 +1753,16 @@ void PropertyStringList::setPyObject(PyObject *value)
for (Py_ssize_t i=0; i<nSize;++i) {
PyObject* item = PySequence_GetItem(value, i);
if (PyUnicode_Check(item)) {
#if PY_MAJOR_VERSION >= 3
values[i] = PyUnicode_AsUTF8(item);
#else
PyObject* unicode = PyUnicode_AsUTF8String(item);
values[i] = PyString_AsString(unicode);
Py_DECREF(unicode);
}
else if (PyString_Check(item)) {
values[i] = PyString_AsString(item);
#endif
}
else {
std::string error = std::string("type in list must be str or unicode, not ");
@@ -1631,8 +1773,18 @@ void PropertyStringList::setPyObject(PyObject *value)
setValues(values);
}
else if (PyUnicode_Check(value)) {
#if PY_MAJOR_VERSION >= 3
setValue(PyUnicode_AsUTF8(value));
}
#else
PyObject* unicode = PyUnicode_AsUTF8String(value);
setValue(PyString_AsString(unicode));
Py_DECREF(unicode);
}
#endif
else {
std::string error = std::string("type must be str or list of str, not ");
std::string error = std::string("type must be str or unicode or list of str or list of unicodes, not ");
error += value->ob_type->tp_name;
throw Base::TypeError(error);
}
@@ -1776,11 +1928,20 @@ void PropertyMap::setPyObject(PyObject *value)
// check on the key:
std::string keyStr;
PyObject* key = PyList_GetItem(keyList, i);
if (PyUnicode_Check(key)) {
#if PY_MAJOR_VERSION >= 3
keyStr = PyUnicode_AsUTF8(key);
#else
PyObject* unicode = PyUnicode_AsUTF8String(key);
keyStr = PyString_AsString(unicode);
Py_DECREF(unicode);
}
if (PyString_Check(key)) {
keyStr = PyString_AsString(key);
#endif
}
else {
std::string error = std::string("type of the key need to be a string, not");
std::string error = std::string("type of the key need to be unicode or string, not");
error += key->ob_type->tp_name;
throw Base::TypeError(error);
}
@@ -1788,12 +1949,16 @@ void PropertyMap::setPyObject(PyObject *value)
// check on the item:
PyObject* item = PyList_GetItem(itemList, i);
if (PyUnicode_Check(item)) {
#if PY_MAJOR_VERSION >= 3
values[keyStr] = PyUnicode_AsUTF8(item);
#else
PyObject* unicode = PyUnicode_AsUTF8String(item);
values[keyStr] = PyString_AsString(unicode);
Py_DECREF(unicode);
}
else if (PyString_Check(item)) {
values[keyStr] = PyString_AsString(item);
#endif
}
else {
std::string error = std::string("type in list must be string or unicode, not ");
@@ -1912,8 +2077,13 @@ void PropertyBool::setPyObject(PyObject *value)
{
if (PyBool_Check(value))
setValue(PyObject_IsTrue(value)!=0);
#if PY_MAJOR_VERSION < 3
else if(PyInt_Check(value))
setValue(PyInt_AsLong(value)!=0);
#else
else if(PyLong_Check(value))
setValue(PyLong_AsLong(value)!=0);
#endif
else {
std::string error = std::string("type must be bool, not ");
error += value->ob_type->tp_name;
@@ -2052,8 +2222,20 @@ PyObject *PropertyBoolList::getPyObject(void)
void PropertyBoolList::setPyObject(PyObject *value)
{
// string is also a sequence and must be be treated differently
std::string str;
if (PyUnicode_Check(value)) {
#if PY_MAJOR_VERSION >= 3
str = PyUnicode_AsUTF8(value);
#else
PyObject* unicode = PyUnicode_AsUTF8String(value);
str = PyString_AsString(unicode);
Py_DECREF(unicode);
boost::dynamic_bitset<> values(str);
setValues(values);
}
if (PyString_Check(value)) {
std::string str = PyString_AsString(value);
str = PyString_AsString(value);
#endif
boost::dynamic_bitset<> values(str);
setValues(values);
}
@@ -2066,8 +2248,13 @@ void PropertyBoolList::setPyObject(PyObject *value)
if (PyBool_Check(item)) {
values[i] = (PyObject_IsTrue(item) ? true : false);
}
#if PY_MAJOR_VERSION < 3
else if (PyInt_Check(item)) {
values[i] = (PyInt_AsLong(item) ? true : false);
#else
else if (PyLong_Check(item)) {
values[i] = (PyLong_AsLong(item) ? true : false);
#endif
}
else {
std::string error = std::string("type in list must be bool or int, not ");
@@ -2081,8 +2268,13 @@ void PropertyBoolList::setPyObject(PyObject *value)
else if (PyBool_Check(value)) {
setValue(PyObject_IsTrue(value) ? true : false);
}
#if PY_MAJOR_VERSION < 3
else if (PyInt_Check(value)) {
setValue(PyInt_AsLong(value) ? true : false);
#else
else if (PyLong_Check(value)) {
setValue(PyLong_AsLong(value) ? true : false);
#endif
}
else {
std::string error = std::string("type must be bool or a sequence of bool, not ");

View File

@@ -75,19 +75,29 @@ Base::Quantity PropertyQuantity::createQuantityFromPy(PyObject *value)
{
Base::Quantity quant;
if (PyString_Check(value))
quant = Quantity::parse(QString::fromLatin1(PyString_AsString(value)));
else if (PyUnicode_Check(value)){
if (PyUnicode_Check(value)){
#if PY_MAJOR_VERSION >= 3
quant = Quantity::parse(QString::fromUtf8(PyUnicode_AsUTF8(value)));
}
#else
PyObject* unicode = PyUnicode_AsUTF8String(value);
std::string Str;
Str = PyString_AsString(unicode);
quant = Quantity::parse(QString::fromUtf8(Str.c_str()));
Py_DECREF(unicode);
}
else if (PyString_Check(value))
quant = Quantity::parse(QString::fromLatin1(PyString_AsString(value)));
#endif
else if (PyFloat_Check(value))
quant = Quantity(PyFloat_AsDouble(value),_Unit);
#if PY_MAJOR_VERSION < 3
else if (PyInt_Check(value))
quant = Quantity((double)PyInt_AsLong(value),_Unit);
#else
else if (PyLong_Check(value))
quant = Quantity((double)PyLong_AsLong(value),_Unit);
#endif
else if (PyObject_TypeCheck(value, &(QuantityPy::Type))) {
Base::QuantityPy *pcObject = static_cast<Base::QuantityPy*>(value);
quant = *(pcObject->getQuantityPtr());

View File

@@ -38,7 +38,12 @@ installed.
'''
from PySide import QtCore, QtGui
import FreeCAD,urllib2,re,os,shutil
import sys, os, re, shutil
import FreeCAD
if sys.version_info.major < 3:
import urllib2
else:
import urllib.request as urllib2
NOGIT = False # for debugging purposes, set this to True to always use http downloads
@@ -304,6 +309,8 @@ class UpdateWorker(QtCore.QThread):
self.progressbar_show.emit(True)
u = urllib2.urlopen("https://github.com/FreeCAD/FreeCAD-addons")
p = u.read()
if isinstance(p, bytes):
p = p.decode("utf-8")
u.close()
p = p.replace("\n"," ")
p = re.findall("octicon-file-submodule(.*?)message",p)
@@ -346,6 +353,8 @@ class InfoWorker(QtCore.QThread):
url = repo[1]
u = urllib2.urlopen(url)
p = u.read()
if isinstance(p, bytes):
p = p.decode("utf-8")
u.close()
desc = re.findall("<meta name=\"description\" content=\"(.*?)\">",p)
if desc:
@@ -374,6 +383,8 @@ class MacroWorker(QtCore.QThread):
macropath = FreeCAD.ParamGet('User parameter:BaseApp/Preferences/Macro').GetString("MacroPath",os.path.join(FreeCAD.ConfigGet("UserAppData"),"Macro"))
u = urllib2.urlopen("http://www.freecadweb.org/wiki/Macros_recipes")
p = u.read()
if isinstance(p, bytes):
p = p.decode("utf-8")
u.close()
macros = re.findall("title=\"(Macro.*?)\"",p)
macros = [mac for mac in macros if (not("translated" in mac))]
@@ -414,6 +425,8 @@ class ShowWorker(QtCore.QThread):
self.info_label.emit(translate("AddonsInstaller", "Retrieving info from ") + str(url))
u = urllib2.urlopen(url)
p = u.read()
if isinstance(p, bytes):
p = p.decode("utf-8")
u.close()
desc = re.findall("<meta name=\"description\" content=\"(.*?)\">",p)
if desc:
@@ -456,6 +469,8 @@ class ShowMacroWorker(QtCore.QThread):
self.info_label.emit("Retrieving info from " + str(url))
u = urllib2.urlopen(url)
p = u.read()
if isinstance(p, bytes):
p = p.decode("utf-8")
u.close()
code = re.findall("<pre>(.*?)<\/pre>",p.replace("\n","--endl--"))
if code:
@@ -559,7 +574,8 @@ class InstallWorker(QtCore.QThread):
def download(self,giturl,clonedir):
"downloads and unzip from github"
import StringIO,zipfile
import zipfile
import io
bakdir = None
if os.path.exists(clonedir):
bakdir = clonedir+".bak"
@@ -573,7 +589,7 @@ class InstallWorker(QtCore.QThread):
u = urllib2.urlopen(zipurl)
except:
return translate("AddonsInstaller", "Error: Unable to download") + " " + zipurl
zfile = StringIO.StringIO()
zfile = io.StringIO()
zfile.write(u.read())
zfile = zipfile.ZipFile(zfile)
master = zfile.namelist()[0] # github will put everything in a subfolder

View File

@@ -382,7 +382,9 @@ class Twist:
facetransform.rotateZ(math.radians(fp.Angle.Value))
facetransform.move(FreeCAD.Vector(0,0,fp.Height.Value))
faceu.transformShape(facetransform)
step = 2 + int(fp.Angle.Value // 90) #resolution in z direction
step = 2 + abs(int(fp.Angle.Value // 90)) #resolution in z direction
# print abs(int(fp.Angle.Value // 90)) #resolution in z direction
# print step
zinc = fp.Height.Value/(step-1.0)
angleinc = math.radians(fp.Angle.Value)/(step-1.0)
spine = Part.makePolygon([(0,0,i*zinc) \
@@ -395,7 +397,9 @@ class Twist:
pipeshell=Part.BRepOffsetAPI.MakePipeShell(spine)
pipeshell.setSpineSupport(spine)
pipeshell.add(wire)
pipeshell.setAuxiliarySpine(auxspine,True,False)
# Was before function change
# pipeshell.setAuxiliarySpine(auxspine,True,False)
pipeshell.setAuxiliarySpine(auxspine,True,long(0))
print(pipeshell.getStatus())
assert(pipeshell.isReady())
#fp.Shape=pipeshell.makeSolid()

View File

@@ -653,6 +653,10 @@ def p_linear_extrude_with_twist(p):
t = float(p[3]['twist'])
else:
t = 0
# Test if null object like from null text
if (len(p[6]) == 0) :
p[0] = []
return
if (len(p[6]) > 1) :
obj = fuse(p[6],"Linear Extrude Union")
else :

View File

@@ -286,10 +286,30 @@ public:
"By default pnt=Vector(0,0,0) and dir=Vector(0,0,1)"
);
add_varargs_method("makeLine",&Module::makeLine,
"makeLine((x1,y1,z1),(x2,y2,z2)) -- Make a line of two points"
"makeLine(startpnt,endpnt) -- Make a line between two points\n"
"\n"
"Args:\n"
" startpnt (Vector or tuple): Vector or 3 element tuple \n"
" containing the x,y and z coordinates of the start point,\n"
" i.e. (x1,y1,z1).\n"
" endpnt (Vector or tuple): Vector or 3 element tuple \n"
" containing the x,y and z coordinates of the start point,\n"
" i.e. (x1,y1,z1).\n"
"\n"
"Returns:\n"
" Edge: Part.Edge object\n"
);
add_varargs_method("makePolygon",&Module::makePolygon,
"makePolygon(list) -- Make a polygon of a list of points"
"makePolygon(pntslist) -- Make a polygon from a list of points\n"
"\n"
"Args:\n"
" pntslist (list(Vector)): list of Vectors representing the \n"
" points of the polygon.\n"
"\n"
"Returns:\n"
" Wire: Part.Wire object. If the last point in the list is \n"
" not the same as the first point, the Wire will not be \n"
" closed and cannot be used to create a face.\n"
);
add_varargs_method("makeCircle",&Module::makeCircle,
"makeCircle(radius,[pnt,dir,angle1,angle2]) -- Make a circle with a given radius\n"

View File

@@ -283,6 +283,13 @@ Return a list of sub-shapes that are direct children of this shape.
</UserDocu>
</Documentation>
</Methode>
<Methode Name="ancestorsOfType">
<Documentation>
<UserDocu>ancestorsOfType(shape, shape type) -> list
For a sub-shape of this shape get its ancestors of a type.
</UserDocu>
</Documentation>
</Methode>
<Methode Name="removeInternalWires">
<Documentation>
<UserDocu>Removes internal wires (also holes) from the shape.</UserDocu>

View File

@@ -1218,6 +1218,75 @@ PyObject* TopoShapePy::childShapes(PyObject *args)
}
}
namespace Part {
std::vector<PyTypeObject*> buildShapeEnumTypeMap()
{
std::vector<PyTypeObject*> typeMap;
typeMap.push_back(&TopoShapeCompoundPy::Type); //TopAbs_COMPOUND
typeMap.push_back(&TopoShapeCompSolidPy::Type); //TopAbs_COMPSOLID
typeMap.push_back(&TopoShapeSolidPy::Type); //TopAbs_SOLID
typeMap.push_back(&TopoShapeShellPy::Type); //TopAbs_SHELL
typeMap.push_back(&TopoShapeFacePy::Type); //TopAbs_FACE
typeMap.push_back(&TopoShapeWirePy::Type); //TopAbs_WIRE
typeMap.push_back(&TopoShapeEdgePy::Type); //TopAbs_EDGE
typeMap.push_back(&TopoShapeVertexPy::Type); //TopAbs_VERTEX
typeMap.push_back(&TopoShapePy::Type); //TopAbs_SHAPE
return typeMap;
}
}
PyObject* TopoShapePy::ancestorsOfType(PyObject *args)
{
PyObject *pcObj;
PyObject *type;
if (!PyArg_ParseTuple(args, "O!O!", &(TopoShapePy::Type), &pcObj, &PyType_Type, &type))
return NULL;
try {
const TopoDS_Shape& model = getTopoShapePtr()->getShape();
const TopoDS_Shape& shape = static_cast<TopoShapePy*>(pcObj)->
getTopoShapePtr()->getShape();
if (model.IsNull() || shape.IsNull()) {
PyErr_SetString(PyExc_ValueError, "Shape is null");
return NULL;
}
static std::vector<PyTypeObject*> typeMap = buildShapeEnumTypeMap();
PyTypeObject* pyType = reinterpret_cast<PyTypeObject*>(type);
TopAbs_ShapeEnum shapetype = TopAbs_SHAPE;
for (auto it = typeMap.begin(); it != typeMap.end(); ++it) {
if (PyType_IsSubtype(pyType, *it)) {
auto index = std::distance(typeMap.begin(), it);
shapetype = static_cast<TopAbs_ShapeEnum>(index);
break;
}
}
TopTools_IndexedDataMapOfShapeListOfShape mapOfShapeShape;
TopExp::MapShapesAndAncestors(model, shape.ShapeType(), shapetype, mapOfShapeShape);
const TopTools_ListOfShape& ancestors = mapOfShapeShape.FindFromKey(shape);
Py::List list;
std::set<Standard_Integer> hashes;
TopTools_ListIteratorOfListOfShape it(ancestors);
for (; it.More(); it.Next()) {
// make sure to avoid duplicates
Standard_Integer code = it.Value().HashCode(INT_MAX);
if (hashes.find(code) == hashes.end()) {
list.append(shape2pyshape(it.Value()));
hashes.insert(code);
}
}
return Py::new_reference_to(list);
}
catch (Standard_Failure) {
Handle(Standard_Failure) e = Standard_Failure::Caught();
PyErr_SetString(PartExceptionOCCError, e->GetMessageString());
return NULL;
}
}
PyObject* TopoShapePy::removeInternalWires(PyObject *args)
{
double minArea;

View File

@@ -101,14 +101,20 @@ SoSeparator* ViewProvider2DObject::createGrid(void)
MaY = MaxY + (MaxY-MinY)*0.2f;
}
else {
MiX = -exp(ceil(log(std::abs(MinX))));
MiX = std::min<float>(MiX,(float)-exp(ceil(log(std::abs(0.1f*MaxX)))));
MaX = exp(ceil(log(std::abs(MaxX))));
MaX = std::max<float>(MaX,(float)exp(ceil(log(std::abs(0.1f*MinX)))));
MiY = -exp(ceil(log(std::abs(MinY))));
MiY = std::min<float>(MiY,(float)-exp(ceil(log(std::abs(0.1f*MaxY)))));
MaY = exp(ceil(log(std::abs(MaxY))));
MaY = std::max<float>(MaY,(float)exp(ceil(log(std::abs(0.1f*MinY)))));
// make sure that nine of the numbers are exactly zero because log(0)
// is not defined
float xMin = std::abs(MinX) < FLT_EPSILON ? 0.01f : MinX;
float xMax = std::abs(MaxX) < FLT_EPSILON ? 0.01f : MaxX;
float yMin = std::abs(MinY) < FLT_EPSILON ? 0.01f : MinY;
float yMax = std::abs(MaxY) < FLT_EPSILON ? 0.01f : MaxY;
MiX = -exp(ceil(log(std::abs(xMin))));
MiX = std::min<float>(MiX,(float)-exp(ceil(log(std::abs(0.1f*xMax)))));
MaX = exp(ceil(log(std::abs(xMax))));
MaX = std::max<float>(MaX,(float)exp(ceil(log(std::abs(0.1f*xMin)))));
MiY = -exp(ceil(log(std::abs(yMin))));
MiY = std::min<float>(MiY,(float)-exp(ceil(log(std::abs(0.1f*yMax)))));
MaY = exp(ceil(log(std::abs(yMax))));
MaY = std::max<float>(MaY,(float)exp(ceil(log(std::abs(0.1f*yMin)))));
}
//Round the values otherwise grid is not aligned with center
MiX = floor(MiX / Step) * Step;

View File

@@ -3922,14 +3922,21 @@ void ViewProviderSketch::draw(bool temp /*=false*/, bool rebuildinformationlayer
edit->RootCrossSet->numVertices.set1Value(0,2);
edit->RootCrossSet->numVertices.set1Value(1,2);
float MiX = -exp(ceil(log(std::abs(MinX))));
MiX = std::min(MiX,(float)-exp(ceil(log(std::abs(0.1f*MaxX)))));
float MaX = exp(ceil(log(std::abs(MaxX))));
MaX = std::max(MaX,(float)exp(ceil(log(std::abs(0.1f*MinX)))));
float MiY = -exp(ceil(log(std::abs(MinY))));
MiY = std::min(MiY,(float)-exp(ceil(log(std::abs(0.1f*MaxY)))));
float MaY = exp(ceil(log(std::abs(MaxY))));
MaY = std::max(MaY,(float)exp(ceil(log(std::abs(0.1f*MinY)))));
// make sure that nine of the numbers are exactly zero because log(0)
// is not defined
float xMin = std::abs(MinX) < FLT_EPSILON ? 0.01f : MinX;
float xMax = std::abs(MaxX) < FLT_EPSILON ? 0.01f : MaxX;
float yMin = std::abs(MinY) < FLT_EPSILON ? 0.01f : MinY;
float yMax = std::abs(MaxY) < FLT_EPSILON ? 0.01f : MaxY;
float MiX = -exp(ceil(log(std::abs(xMin))));
MiX = std::min(MiX,(float)-exp(ceil(log(std::abs(0.1f*xMax)))));
float MaX = exp(ceil(log(std::abs(xMax))));
MaX = std::max(MaX,(float)exp(ceil(log(std::abs(0.1f*xMin)))));
float MiY = -exp(ceil(log(std::abs(yMin))));
MiY = std::min(MiY,(float)-exp(ceil(log(std::abs(0.1f*yMax)))));
float MaY = exp(ceil(log(std::abs(yMax))));
MaY = std::max(MaY,(float)exp(ceil(log(std::abs(0.1f*yMin)))));
edit->RootCrossCoordinate->point.set1Value(0,SbVec3f(MiX, 0.0f, zCross));
edit->RootCrossCoordinate->point.set1Value(1,SbVec3f(MaX, 0.0f, zCross));