//------------------------------------------------------------ // // DictWrapper // //------------------------------------------------------------ DictWrapper::DictWrapper( Py::Dict result_wrappers, const std::string &wrapper_name ) : m_wrapper_name( wrapper_name ) , m_have_wrapper( false ) , m_wrapper() { if( result_wrappers.hasKey( wrapper_name ) ) { m_wrapper = result_wrappers[ wrapper_name ]; m_have_wrapper = true; } }
/* ------------ module methods ------------- */ Py::Object _backend_agg_module::new_renderer (const Py::Tuple &args, const Py::Dict &kws) { if (args.length() != 3 ) { throw Py::RuntimeError("Incorrect # of args to RendererAgg(width, height, dpi)."); } int debug; if ( kws.hasKey("debug") ) debug = Py::Int( kws["debug"] ); else debug=0; int width = Py::Int(args[0]); int height = Py::Int(args[1]); double dpi = Py::Float(args[2]); return Py::asObject(new RendererAgg(width, height, dpi, debug)); }
QMap<QString, CallTip> CallTipsList::extractTips(const QString& context) const { Base::PyGILStateLocker lock; QMap<QString, CallTip> tips; if (context.isEmpty()) return tips; try { Py::Module module("__main__"); Py::Dict dict = module.getDict(); #if 0 QStringList items = context.split(QLatin1Char('.')); QString modname = items.front(); items.pop_front(); if (!dict.hasKey(std::string(modname.toLatin1()))) return tips; // unknown object // get the Python object we need Py::Object obj = dict.getItem(std::string(modname.toLatin1())); while (!items.isEmpty()) { QByteArray name = items.front().toLatin1(); std::string attr = name.constData(); items.pop_front(); if (obj.hasAttr(attr)) obj = obj.getAttr(attr); else return tips; } #else // Don't use hasattr & getattr because if a property is bound to a method this will be executed twice. PyObject* code = Py_CompileString(static_cast<const char*>(context.toLatin1()), "<CallTipsList>", Py_eval_input); if (!code) { PyErr_Clear(); return tips; } PyObject* eval = 0; if (PyCode_Check(code)) { eval = PyEval_EvalCode(reinterpret_cast<PyCodeObject*>(code), dict.ptr(), dict.ptr()); } Py_DECREF(code); if (!eval) { PyErr_Clear(); return tips; } Py::Object obj(eval, true); #endif // Checks whether the type is a subclass of PyObjectBase because to get the doc string // of a member we must get it by its type instead of its instance otherwise we get the // wrong string, namely that of the type of the member. // Note: 3rd party libraries may use their own type object classes so that we cannot // reliably use Py::Type. To be on the safe side we should use Py::Object to assign // the used type object to. //Py::Object type = obj.type(); Py::Object type(PyObject_Type(obj.ptr()), true); Py::Object inst = obj; // the object instance union PyType_Object typeobj = {&Base::PyObjectBase::Type}; union PyType_Object typedoc = {&App::DocumentObjectPy::Type}; union PyType_Object basetype = {&PyBaseObject_Type}; if (PyObject_IsSubclass(type.ptr(), typedoc.o) == 1) { // From the template Python object we don't query its type object because there we keep // a list of additional methods that we won't see otherwise. But to get the correct doc // strings we query the type's dict in the class itself. // To see if we have a template Python object we check for the existence of supportedProperties if (!type.hasAttr("supportedProperties")) { obj = type; } } else if (PyObject_IsSubclass(type.ptr(), typeobj.o) == 1) { obj = type; } else if (PyInstance_Check(obj.ptr())) { // instances of old style classes PyInstanceObject* inst = reinterpret_cast<PyInstanceObject*>(obj.ptr()); PyObject* classobj = reinterpret_cast<PyObject*>(inst->in_class); obj = Py::Object(classobj); } else if (PyObject_IsInstance(obj.ptr(), basetype.o) == 1) { // New style class which can be a module, type, list, tuple, int, float, ... // Make sure it's not a type objec union PyType_Object typetype = {&PyType_Type}; if (PyObject_IsInstance(obj.ptr(), typetype.o) != 1) { // this should be now a user-defined Python class // http://stackoverflow.com/questions/12233103/in-python-at-runtime-determine-if-an-object-is-a-class-old-and-new-type-instan if (Py_TYPE(obj.ptr())->tp_flags & Py_TPFLAGS_HEAPTYPE) { obj = type; } } } // If we have an instance of PyObjectBase then determine whether it's valid or not if (PyObject_IsInstance(inst.ptr(), typeobj.o) == 1) { Base::PyObjectBase* baseobj = static_cast<Base::PyObjectBase*>(inst.ptr()); const_cast<CallTipsList*>(this)->validObject = baseobj->isValid(); } else { // PyObject_IsInstance might set an exception PyErr_Clear(); } Py::List list(obj.dir()); // If we derive from PropertyContainerPy we can search for the properties in the // C++ twin class. union PyType_Object proptypeobj = {&App::PropertyContainerPy::Type}; if (PyObject_IsSubclass(type.ptr(), proptypeobj.o) == 1) { // These are the attributes of the instance itself which are NOT accessible by // its type object extractTipsFromProperties(inst, tips); } // If we derive from App::DocumentPy we have direct access to the objects by their internal // names. So, we add these names to the list, too. union PyType_Object appdoctypeobj = {&App::DocumentPy::Type}; if (PyObject_IsSubclass(type.ptr(), appdoctypeobj.o) == 1) { App::DocumentPy* docpy = (App::DocumentPy*)(inst.ptr()); App::Document* document = docpy->getDocumentPtr(); // Make sure that the C++ object is alive if (document) { std::vector<App::DocumentObject*> objects = document->getObjects(); Py::List list; for (std::vector<App::DocumentObject*>::iterator it = objects.begin(); it != objects.end(); ++it) list.append(Py::String((*it)->getNameInDocument())); extractTipsFromObject(inst, list, tips); } } // If we derive from Gui::DocumentPy we have direct access to the objects by their internal // names. So, we add these names to the list, too. union PyType_Object guidoctypeobj = {&Gui::DocumentPy::Type}; if (PyObject_IsSubclass(type.ptr(), guidoctypeobj.o) == 1) { Gui::DocumentPy* docpy = (Gui::DocumentPy*)(inst.ptr()); if (docpy->getDocumentPtr()) { App::Document* document = docpy->getDocumentPtr()->getDocument(); // Make sure that the C++ object is alive if (document) { std::vector<App::DocumentObject*> objects = document->getObjects(); Py::List list; for (std::vector<App::DocumentObject*>::iterator it = objects.begin(); it != objects.end(); ++it) list.append(Py::String((*it)->getNameInDocument())); extractTipsFromObject(inst, list, tips); } } } // These are the attributes from the type object extractTipsFromObject(obj, list, tips); } catch (Py::Exception& e) { // Just clear the Python exception e.clear(); } return tips; }
QMap<QString, CallTip> CallTipsList::extractTips(const QString& context) const { Base::PyGILStateLocker lock; QMap<QString, CallTip> tips; if (context.isEmpty()) return tips; try { QStringList items = context.split(QLatin1Char('.')); Py::Module module("__main__"); Py::Dict dict = module.getDict(); QString modname = items.front(); items.pop_front(); if (!dict.hasKey(std::string(modname.toAscii()))) return tips; // unknown object // get the Python object we need Py::Object obj = dict.getItem(std::string(modname.toAscii())); while (!items.isEmpty()) { QByteArray name = items.front().toAscii(); std::string attr = name.constData(); items.pop_front(); if (obj.hasAttr(attr)) obj = obj.getAttr(attr); else return tips; } // Checks whether the type is a subclass of PyObjectBase because to get the doc string // of a member we must get it by its type instead of its instance otherwise we get the // wrong string, namely that of the type of the member. // Note: 3rd party libraries may use their own type object classes so that we cannot // reliably use Py::Type. To be on the safe side we should use Py::Object to assign // the used type object to. //Py::Object type = obj.type(); Py::Object type(PyObject_Type(obj.ptr()), true); Py::Object inst = obj; // the object instance union PyType_Object typeobj = {&Base::PyObjectBase::Type}; union PyType_Object typedoc = {&App::DocumentObjectPy::Type}; if (PyObject_IsSubclass(type.ptr(), typedoc.o) == 1) { // From the template Python object we don't query its type object because there we keep // a list of additional methods that we won't see otherwise. But to get the correct doc // strings we query the type's dict in the class itself. // To see if we have a template Python object we check for the existence of supportedProperties if (!type.hasAttr("supportedProperties")) { obj = type; } } else if (PyObject_IsSubclass(type.ptr(), typeobj.o) == 1) { obj = type; } // If we have an instance of PyObjectBase then determine whether it's valid or not if (PyObject_IsInstance(inst.ptr(), typeobj.o) == 1) { Base::PyObjectBase* baseobj = static_cast<Base::PyObjectBase*>(inst.ptr()); const_cast<CallTipsList*>(this)->validObject = baseobj->isValid(); } else { // PyObject_IsInstance might set an exception PyErr_Clear(); } Py::List list(PyObject_Dir(obj.ptr()), true); // If we derive from PropertyContainerPy we can search for the properties in the // C++ twin class. union PyType_Object proptypeobj = {&App::PropertyContainerPy::Type}; if (PyObject_IsSubclass(type.ptr(), proptypeobj.o) == 1) { // These are the attributes of the instance itself which are NOT accessible by // its type object extractTipsFromProperties(inst, tips); } // If we derive from App::DocumentPy we have direct access to the objects by their internal // names. So, we add these names to the list, too. union PyType_Object appdoctypeobj = {&App::DocumentPy::Type}; if (PyObject_IsSubclass(type.ptr(), appdoctypeobj.o) == 1) { App::DocumentPy* docpy = (App::DocumentPy*)(inst.ptr()); App::Document* document = docpy->getDocumentPtr(); // Make sure that the C++ object is alive if (document) { std::vector<App::DocumentObject*> objects = document->getObjects(); Py::List list; for (std::vector<App::DocumentObject*>::iterator it = objects.begin(); it != objects.end(); ++it) list.append(Py::String((*it)->getNameInDocument())); extractTipsFromObject(inst, list, tips); } } // If we derive from Gui::DocumentPy we have direct access to the objects by their internal // names. So, we add these names to the list, too. union PyType_Object guidoctypeobj = {&Gui::DocumentPy::Type}; if (PyObject_IsSubclass(type.ptr(), guidoctypeobj.o) == 1) { Gui::DocumentPy* docpy = (Gui::DocumentPy*)(inst.ptr()); if (docpy->getDocumentPtr()) { App::Document* document = docpy->getDocumentPtr()->getDocument(); // Make sure that the C++ object is alive if (document) { std::vector<App::DocumentObject*> objects = document->getObjects(); Py::List list; for (std::vector<App::DocumentObject*>::iterator it = objects.begin(); it != objects.end(); ++it) list.append(Py::String((*it)->getNameInDocument())); extractTipsFromObject(inst, list, tips); } } } // These are the attributes from the type object extractTipsFromObject(obj, list, tips); } catch (Py::Exception& e) { // Just clear the Python exception e.clear(); } return tips; }
Py::Object Image::resize(const Py::Tuple& args, const Py::Dict& kwargs) { _VERBOSE("Image::resize"); args.verify_length(2); int norm = 1; if ( kwargs.hasKey("norm") ) norm = Py::Int( kwargs["norm"] ); double radius = 4.0; if ( kwargs.hasKey("radius") ) radius = Py::Float( kwargs["radius"] ); if (bufferIn ==NULL) throw Py::RuntimeError("You must first load the image"); int numcols = Py::Int(args[0]); int numrows = Py::Int(args[1]); colsOut = numcols; rowsOut = numrows; size_t NUMBYTES(numrows * numcols * BPP); delete [] bufferOut; bufferOut = new agg::int8u[NUMBYTES]; if (bufferOut ==NULL) //todo: also handle allocation throw throw Py::MemoryError("Image::resize could not allocate memory"); delete rbufOut; rbufOut = new agg::rendering_buffer; rbufOut->attach(bufferOut, numcols, numrows, numcols * BPP); // init the output rendering/rasterizing stuff pixfmt pixf(*rbufOut); renderer_base rb(pixf); rb.clear(bg); agg::rasterizer_scanline_aa<> ras; agg::scanline_u8 sl; //srcMatrix *= resizingMatrix; //imageMatrix *= resizingMatrix; imageMatrix.invert(); interpolator_type interpolator(imageMatrix); typedef agg::span_allocator<agg::rgba8> span_alloc_type; span_alloc_type sa; agg::rgba8 background(agg::rgba8(int(255*bg.r), int(255*bg.g), int(255*bg.b), int(255*bg.a))); // the image path agg::path_storage path; agg::int8u *bufferPad = NULL; agg::rendering_buffer rbufPad; double x0, y0, x1, y1; x0 = 0.0; x1 = colsIn; y0 = 0.0; y1 = rowsIn; path.move_to(x0, y0); path.line_to(x1, y0); path.line_to(x1, y1); path.line_to(x0, y1); path.close_polygon(); agg::conv_transform<agg::path_storage> imageBox(path, srcMatrix); ras.add_path(imageBox); typedef agg::wrap_mode_reflect reflect_type; typedef agg::image_accessor_wrap<pixfmt, reflect_type, reflect_type> img_accessor_type; pixfmt pixfmtin(*rbufIn); img_accessor_type ia(pixfmtin); switch(interpolation) { case NEAREST: { typedef agg::span_image_filter_rgba_nn<img_accessor_type, interpolator_type> span_gen_type; typedef agg::renderer_scanline_aa<renderer_base, span_alloc_type, span_gen_type> renderer_type; span_gen_type sg(ia, interpolator); renderer_type ri(rb, sa, sg); agg::render_scanlines(ras, sl, ri); } break; case BILINEAR: case BICUBIC: case SPLINE16: case SPLINE36: case HANNING: case HAMMING: case HERMITE: case KAISER: case QUADRIC: case CATROM: case GAUSSIAN: case BESSEL: case MITCHELL: case SINC: case LANCZOS: case BLACKMAN: { agg::image_filter_lut filter; switch(interpolation) { case BILINEAR: filter.calculate(agg::image_filter_bilinear(), norm); break; case BICUBIC: filter.calculate(agg::image_filter_bicubic(), norm); break; case SPLINE16: filter.calculate(agg::image_filter_spline16(), norm); break; case SPLINE36: filter.calculate(agg::image_filter_spline36(), norm); break; case HANNING: filter.calculate(agg::image_filter_hanning(), norm); break; case HAMMING: filter.calculate(agg::image_filter_hamming(), norm); break; case HERMITE: filter.calculate(agg::image_filter_hermite(), norm); break; case KAISER: filter.calculate(agg::image_filter_kaiser(), norm); break; case QUADRIC: filter.calculate(agg::image_filter_quadric(), norm); break; case CATROM: filter.calculate(agg::image_filter_catrom(), norm); break; case GAUSSIAN: filter.calculate(agg::image_filter_gaussian(), norm); break; case BESSEL: filter.calculate(agg::image_filter_bessel(), norm); break; case MITCHELL: filter.calculate(agg::image_filter_mitchell(), norm); break; case SINC: filter.calculate(agg::image_filter_sinc(radius), norm); break; case LANCZOS: filter.calculate(agg::image_filter_lanczos(radius), norm); break; case BLACKMAN: filter.calculate(agg::image_filter_blackman(radius), norm); break; } typedef agg::span_image_filter_rgba_2x2<img_accessor_type, interpolator_type> span_gen_type; typedef agg::renderer_scanline_aa<renderer_base, span_alloc_type, span_gen_type> renderer_type; span_gen_type sg(ia, interpolator, filter); renderer_type ri(rb, sa, sg); agg::render_scanlines(ras, sl, ri); } break; } delete [] bufferPad; return Py::Object(); }
Py::Object Transformation::nonlinear_only_numerix(const Py::Tuple & args, const Py::Dict &kwargs) { _VERBOSE("Transformation::nonlinear_only_numerix"); args.verify_length(2); int returnMask = false; if (kwargs.hasKey("returnMask")) { returnMask = Py::Int(kwargs["returnMask"]); } Py::Object xo = args[0]; Py::Object yo = args[1]; PyArrayObject *x = (PyArrayObject *) PyArray_ContiguousFromObject(xo.ptr(), PyArray_DOUBLE, 1, 1); if (x==NULL) throw Py::TypeError("Transformation::nonlinear_only_numerix expected numerix array"); PyArrayObject *y = (PyArrayObject *) PyArray_ContiguousFromObject(yo.ptr(), PyArray_DOUBLE, 1, 1); if (y==NULL) throw Py::TypeError("Transformation::nonlinear_only_numerix expected numerix array"); size_t Nx = x->dimensions[0]; size_t Ny = y->dimensions[0]; if (Nx!=Ny) throw Py::ValueError("x and y must be equal length sequences"); int dimensions[1]; dimensions[0] = Nx; PyArrayObject *retx = (PyArrayObject *)PyArray_FromDims(1,dimensions,PyArray_DOUBLE); if (retx==NULL) { Py_XDECREF(x); Py_XDECREF(y); throw Py::RuntimeError("Could not create return x array"); } PyArrayObject *rety = (PyArrayObject *)PyArray_FromDims(1,dimensions,PyArray_DOUBLE); if (rety==NULL) { Py_XDECREF(x); Py_XDECREF(y); Py_XDECREF(retx); throw Py::RuntimeError("Could not create return x array"); } PyArrayObject *retmask = NULL; if (returnMask) { retmask = (PyArrayObject *)PyArray_FromDims(1,dimensions,PyArray_UBYTE); if (retmask==NULL) { Py_XDECREF(x); Py_XDECREF(y); Py_XDECREF(retx); Py_XDECREF(rety); throw Py::RuntimeError("Could not create return mask array"); } } for (size_t i=0; i< Nx; ++i) { double thisx = *(double *)(x->data + i*x->strides[0]); double thisy = *(double *)(y->data + i*y->strides[0]); try { this->nonlinear_only_api(&thisx, &thisy); } catch(...) { if (returnMask) { *(unsigned char *)(retmask->data + i*retmask->strides[0]) = 0; *(double *)(retx->data + i*retx->strides[0]) = 0.0; *(double *)(rety->data + i*rety->strides[0]) = 0.0; continue; } else { throw Py::ValueError("Domain error on this->nonlinear_only_api(&thisx, &thisy) in Transformation::nonlinear_only_numerix"); } } *(double *)(retx->data + i*retx->strides[0]) = thisx; *(double *)(rety->data + i*rety->strides[0]) = thisy; if (returnMask) { *(unsigned char *)(retmask->data + i*retmask->strides[0]) = 1; } } Py_XDECREF(x); Py_XDECREF(y); if (returnMask) { Py::Tuple ret(3); ret[0] = Py::Object((PyObject*)retx); ret[1] = Py::Object((PyObject*)rety); ret[2] = Py::Object((PyObject*)retmask); Py_XDECREF(retx); Py_XDECREF(rety); Py_XDECREF(retmask); return ret; } else { Py::Tuple ret(2); ret[0] = Py::Object((PyObject*)retx); ret[1] = Py::Object((PyObject*)rety); Py_XDECREF(retx); Py_XDECREF(rety); return ret; } }