bindings/python/parsers/python/model.cpp
Go to the documentation of this file.
1 //
2 // Copyright (c) 2016-2023 CNRS INRIA
3 //
4 
5 #include "pinocchio/parsers/python.hpp"
6 
7 #include <iostream>
8 #include <Python.h>
9 #include <boost/version.hpp>
10 #include <boost/algorithm/string/predicate.hpp>
11 
12 // Boost 1.58
13 #if BOOST_VERSION / 100 % 1000 == 58
14 #include <fstream>
15 #endif
16 
17 namespace pinocchio
18 {
19  namespace python
20  {
21  namespace bp = boost::python;
22 
23  Model buildModel(const std::string & filename, const std::string & model_name)
24  {
25  Py_Initialize();
26 
27  bp::object main_module = bp::import("__main__");
28  // Get a dict for the global namespace to exec further python code with
29  bp::dict globals = bp::extract<bp::dict>(main_module.attr("__dict__"));
30 
31  // We need to link to the pinocchio PyWrap. We delegate the dynamic loading to the python interpreter.
32  bp::object cpp_module( (bp::handle<>(bp::borrowed(PyImport_AddModule("libpinocchio_pywrap")))) );
33 
34  // That's it, you can exec your python script, starting with a model you
35  // can update as you want.
36  try
37  {
38 // Boost 1.58
39 #if BOOST_VERSION / 100 % 1000 == 58
40  // Avoid a segv with exec_file
41  // See: https://github.com/boostorg/python/pull/15
42  std::ifstream t(filename.c_str());
43  std::stringstream buffer;
44  buffer << t.rdbuf();
45  bp::exec(buffer.str().c_str(), globals);
46 #else // default implementation
47  bp::exec_file((bp::str)filename, globals);
48 #endif
49  }
50  catch (bp::error_already_set & e)
51  {
52  PyErr_PrintEx(0);
53  }
54 
55  Model model;
56  try
57  {
58  bp::object obj_model = globals[model_name];
59  model = bp::extract<Model>(obj_model);
60  }
61  catch (bp::error_already_set & e)
62  {
63  PyErr_PrintEx(0);
64  }
65 
66  // close the interpreter
67  // cf. https://github.com/numpy/numpy/issues/8097
68 #if PY_MAJOR_VERSION < 3
69  Py_Finalize();
70 #else
71 
72  PyObject * poMainModule = PyImport_AddModule("__main__");
73  PyObject * poAttrList = PyObject_Dir(poMainModule);
74  PyObject * poAttrIter = PyObject_GetIter(poAttrList);
75  PyObject * poAttrName;
76 
77  while ((poAttrName = PyIter_Next(poAttrIter)) != NULL)
78  {
79  std::string oAttrName((bp::extract<char const*>(poAttrName)));
80 
81  // Make sure we don't delete any private objects.
82  if (!boost::starts_with(oAttrName, "__") || !boost::ends_with(oAttrName, "__"))
83  {
84  PyObject * poAttr = PyObject_GetAttr(poMainModule, poAttrName);
85 
86  // Make sure we don't delete any module objects.
87  if (poAttr && poAttr->ob_type != poMainModule->ob_type)
88  PyObject_SetAttr(poMainModule, poAttrName, NULL);
89  Py_DecRef(poAttr);
90  }
91  Py_DecRef(poAttrName);
92  }
93  Py_DecRef(poAttrIter);
94  Py_DecRef(poAttrList);
95 #endif
96 
97  return model;
98  }
99  } // namespace python
100 } // namespace pinocchio
Model buildModel(const std::string &filename, const std::string &model_name)
Load a model from a Python script.
Main pinocchio namespace.
Definition: timings.cpp:28
Transform3f t
JointCollectionTpl & model


pinocchio
Author(s):
autogenerated on Fri Jun 23 2023 02:38:32