diff options
author | Michael Haberler <git@mah.priv.at> | 2013-04-21 18:23:16 +0200 |
---|---|---|
committer | Michael Haberler <git@mah.priv.at> | 2013-04-21 18:24:57 +0200 |
commit | f98134029dfde67ffdb88706dc0083746dd3f065 (patch) | |
tree | 74955c88208f6c4d3fd872cfa298bbd9820c2038 | |
parent | 6c2d6fbab64380875e8ec56de9f51ae371f9ec04 (diff) | |
download | linuxcnc-f98134029dfde67ffdb88706dc0083746dd3f065.tar.gz linuxcnc-f98134029dfde67ffdb88706dc0083746dd3f065.zip |
interp/python: reduce compilation resource requirements for interpmodule.cc
by splitting up into separate files - it was just a bit too much for some
embedded systems
see http://www.boost.org/doc/libs/1_39_0/libs/python/doc/tutorial/doc/html/python/techniques.html#python.reducing_compiling_time
-rw-r--r-- | src/emc/rs274ngc/Submakefile | 5 | ||||
-rw-r--r-- | src/emc/rs274ngc/interpmodule.cc | 366 | ||||
-rw-r--r-- | src/emc/rs274ngc/paramclass.hh | 15 | ||||
-rw-r--r-- | src/emc/rs274ngc/pyarrays.cc | 33 | ||||
-rw-r--r-- | src/emc/rs274ngc/pyblock.cc | 129 | ||||
-rw-r--r-- | src/emc/rs274ngc/pyemctypes.cc | 87 | ||||
-rw-r--r-- | src/emc/rs274ngc/pyinterp1.cc | 99 | ||||
-rw-r--r-- | src/emc/rs274ngc/pyparamclass.cc | 116 |
8 files changed, 495 insertions, 355 deletions
diff --git a/src/emc/rs274ngc/Submakefile b/src/emc/rs274ngc/Submakefile index 2145bfbde..acd1bd9de 100644 --- a/src/emc/rs274ngc/Submakefile +++ b/src/emc/rs274ngc/Submakefile @@ -23,6 +23,11 @@ LIBRS274SRCS := $(addprefix emc/rs274ngc/, \ interp_python.cc \ interp_remap.cc \ canonmodule.cc \ + pyparamclass.cc \ + pyemctypes.cc \ + pyinterp1.cc \ + pyblock.cc \ + pyarrays.cc \ interpmodule.cc \ rs274ngc_pre.cc) USERSRCS += $(LIBRS274SRCS) diff --git a/src/emc/rs274ngc/interpmodule.cc b/src/emc/rs274ngc/interpmodule.cc index f38b99350..f7f591b3d 100644 --- a/src/emc/rs274ngc/interpmodule.cc +++ b/src/emc/rs274ngc/interpmodule.cc @@ -20,6 +20,12 @@ extern int _task; // zero in gcodemodule, 1 in milltask #include "units.h" #include "array1.hh" +extern void export_Internals(); +extern void export_Arrays(); +extern void export_Block(); +extern void export_EmcTypes(); +#include "paramclass.hh" + namespace pp = pyplusplus::containers::static_sized; #include "interp_array_types.hh" @@ -53,33 +59,6 @@ static sub_context_array sub_context_wrapper ( Interp & inst) { return sub_context_array(inst._setup.sub_context); } -static g_modes_array g_modes_wrapper ( block & b) { - return g_modes_array(b.g_modes); -} - -static m_modes_array m_modes_wrapper ( block & b) { - return m_modes_array(b.m_modes); -} - -static params_array saved_params_wrapper ( context &c) { - return params_array(c.saved_params); -} - -static params_array params_wrapper ( block & b) { - return params_array(b.params); -} - -static active_g_codes_array saved_g_codes_wrapper ( context &c) { - return active_g_codes_array(c.saved_g_codes); -} - -static active_m_codes_array saved_m_codes_wrapper ( context &c) { - return active_m_codes_array(c.saved_m_codes); -} - -static active_settings_array saved_settings_wrapper ( context &c) { - return active_settings_array(c.saved_settings); -} #pragma GCC diagnostic ignored "-Wformat-security" static void setErrorMsg(Interp &interp, const char *s) @@ -118,137 +97,16 @@ static bp::object wrap_find_tool_pocket(Interp &interp, int toolno) return bp::make_tuple(status, pocket); } -// access to named and numbered parameters via a pseudo-dictionary -// either params["paramname"] or params[5400] is valid -struct ParamClass { - - Interp &interp; - - ParamClass(Interp &i) : interp(i) {}; - double getitem( bp::object sub) - { - double retval = 0; - if (IS_STRING(sub)) { - char const* varname = bp::extract < char const* > (sub); - int status; - interp.find_named_param(varname, &status, &retval); - if (!status) - throw std::runtime_error("parameter does not exist: " + std::string(varname)); - } else - if (IS_INT(sub)) { - int index = bp::extract < int > (sub); - retval = interp._setup.parameters[index]; - } else { - throw std::runtime_error("params subscript type must be integer or string"); - } - return retval; - } - - double setitem(bp::object sub, double dvalue) - { - if (IS_STRING(sub)) { - char const* varname = bp::extract < char const* > (sub); - int status = interp.add_named_param(varname, varname[0] == '_' ? PA_GLOBAL :0); - status = interp.store_named_param(&interp._setup,varname, dvalue, 0); - if (status != INTERP_OK) - throw std::runtime_error("cant assign value to parameter: " + std::string(varname)); - - } else - if (IS_INT(sub)) { - int index = bp::extract < int > (sub); - if ((index < 0) || (index > RS274NGC_MAX_PARAMETERS -1)) { - std::stringstream sstr; - sstr << "params subscript out of range : " << index << " - must be between 0 and " << RS274NGC_MAX_PARAMETERS; - throw std::runtime_error(sstr.str()); - } - interp._setup.parameters[index] = dvalue; - return dvalue; - } else - throw std::runtime_error("params subscript type must be integer or string"); - return dvalue; - } - - bp::list namelist(context &c) const { - bp::list result; - for(parameter_map::iterator it = c.named_params.begin(); it != c.named_params.end(); ++it) { - result.append( it->first); - } - return result; - } - - bp::list locals() { - return namelist(interp._setup.sub_context[interp._setup.call_level]); - } - - bp::list globals() { - return namelist(interp._setup.sub_context[0]); - } - - bp::list operator()() const - { - bp::list result = namelist(interp._setup.sub_context[interp._setup.call_level]); - result.extend(namelist(interp._setup.sub_context[0])); - return result; - }; - - int length() { return RS274NGC_MAX_PARAMETERS;} -}; // FIXME not sure if this is really needed static ParamClass param_wrapper ( Interp & inst) { return ParamClass(inst); } -static bp::object emcpose_2_obj ( EmcPose &p) { - return bp::object("x=%.4f y=%.4f z=%.4f a=%.4f b=%.4f c=%.4f u=%.4f v=%.4f w=%.4f" % - bp::make_tuple(p.tran.x,p.tran.y,p.tran.z, - p.a,p.b,p.c,p.u,p.v,p.w)); -} -static bp::object emcpose_str( EmcPose &p) { - return bp::object("EmcPose(" + emcpose_2_obj(p) + ")"); -} - -static bp::object tool_str( CANON_TOOL_TABLE &t) { - return bp::object("Tool(T%d D%.4f I%.4f J%.4f Q%d offset: " % - bp::make_tuple(t.toolno, t.diameter, - t.frontangle,t.backangle, t.orientation) + - emcpose_2_obj(t.offset) + ")"); -} - -static bp::object remap_str( remap_struct &r) { - return bp::object("Remap(%s argspec=%s modal_group=%d prolog=%s ngc=%s python=%s epilog=%s) " % - bp::make_tuple(r.name,r.argspec,r.modal_group,r.prolog_func, - r.remap_ngc, r.remap_py, r.epilog_func)); -} - -static void tool_zero( CANON_TOOL_TABLE &t) { - t.toolno = -1; - ZERO_EMC_POSE(t.offset); - t.diameter = 0.0; - t.frontangle = 0.0; - t.backangle = 0.0; - t.orientation = 0; -} - -static bp::object pmcartesian_str( PmCartesian &c) { - return bp::object("PmCartesian(x=%.4f y=%.4f z=%.4f)" % - bp::make_tuple(c.x,c.y,c.z)); -} - -static const char *get_comment(block &b) { return b.comment; }; -static const char *get_o_name(block &b) { return b.o_name; }; - static int get_task(Interp &i) { return _task; }; static const char *get_filename(Interp &i) { return i._setup.filename; }; static const char *get_linetext(Interp &i) { return i._setup.linetext; }; -static void set_x(EmcPose &p, double value) { p.tran.x = value; } -static void set_y(EmcPose &p, double value) { p.tran.y = value; } -static void set_z(EmcPose &p, double value) { p.tran.z = value; } -static double get_x(EmcPose &p) { return p.tran.x; } -static double get_y(EmcPose &p) { return p.tran.y; } -static double get_z(EmcPose &p) { return p.tran.z; } - // those are exposed here because they look useful for regression testing static bool __equal(double a, double b) { return fabs(a - b) < TOLERANCE_EQUAL; } // see interp_convert.cc @@ -387,199 +245,10 @@ BOOST_PYTHON_MODULE(interpreter) { def("is_near_int", &is_near_int); // EMC's perception of closeness to an int def("nearest_int", &nearest_int); - class_<PmCartesian, noncopyable>("PmCartesian","EMC cartesian postition",no_init) - .def_readwrite("x",&PmCartesian::x) - .def_readwrite("y",&PmCartesian::y) - .def_readwrite("z",&PmCartesian::z) - .def("__str__", &pmcartesian_str) - ; - - - // leave EmcPose copyable/assignable because it's used as a parameter value (eg emcSetToolOffset) - class_<EmcPose>("EmcPose","EMC pose",no_init) - .def_readwrite("tran",&EmcPose::tran) - .add_property("x", &get_x, &set_x) - .add_property("y", &get_y, &set_y) - .add_property("z", &get_z, &set_z) - .def_readwrite("a",&EmcPose::a) - .def_readwrite("b",&EmcPose::b) - .def_readwrite("c",&EmcPose::c) - .def_readwrite("u",&EmcPose::u) - .def_readwrite("v",&EmcPose::v) - .def_readwrite("w",&EmcPose::w) - .def("__str__", &emcpose_str) - ; - - // leave CANON_TOOL_TABLE copyable/assignable because assignment is used a lot when fiddling - // with tooltable entries - class_<CANON_TOOL_TABLE >("CANON_TOOL_TABLE","Tool description" ,no_init) - .def_readwrite("toolno", &CANON_TOOL_TABLE::toolno) - .def_readwrite("offset", &CANON_TOOL_TABLE::offset) - .def_readwrite("diameter", &CANON_TOOL_TABLE::diameter) - .def_readwrite("frontangle", &CANON_TOOL_TABLE::frontangle) - .def_readwrite("backangle", &CANON_TOOL_TABLE::backangle) - .def_readwrite("orientation", &CANON_TOOL_TABLE::orientation) - .def("__str__", &tool_str) - .def("zero", &tool_zero) - ; - - - class_<parameter_value_struct /*,noncopyable */>("ParameterValue") // ,no_init) - .def_readwrite("attr",¶meter_value_struct::attr) - .def_readwrite("value",¶meter_value_struct::value) - ; - - class_<parameter_map,noncopyable>("ParameterMap",no_init) - .def(map_indexing_suite<parameter_map>()) - ; - - - // FIXME make noncopyable: class_<ParamClass, noncopyable>("Params","Interpreter parameters",no_init) - class_<ParamClass>("Params","Interpreter parameters",no_init) - .def("__getitem__", &ParamClass::getitem) - .def("__setitem__", &ParamClass::setitem) - .def("__len__", &ParamClass::length) - .def("globals", &ParamClass::globals) - .def("locals", &ParamClass::locals) - .def("__call__", &ParamClass::operator()); - ; - - class_ <context, noncopyable>("Context",no_init) - .def_readwrite("position",&context::position) - .def_readwrite("sequence_number",&context::sequence_number) - .def_readwrite("filename", &context::filename) - .def_readwrite("subname", &context::subName) - .add_property( "saved_params", - bp::make_function( saved_params_w(&saved_params_wrapper), - bp::with_custodian_and_ward_postcall< 0, 1 >())) - .add_property( "saved_g_codes", - bp::make_function( active_g_codes_w(&saved_g_codes_wrapper), - bp::with_custodian_and_ward_postcall< 0, 1 >())) - .add_property( "saved_m_codes", - bp::make_function( active_m_codes_w(&saved_m_codes_wrapper), - bp::with_custodian_and_ward_postcall< 0, 1 >())) - .add_property( "saved_settings", - bp::make_function( active_settings_w(&saved_settings_wrapper), - bp::with_custodian_and_ward_postcall< 0, 1 >())) - .def_readwrite("context_status", &context::context_status) - .def_readwrite("named_params", &context::named_params) - - .def_readwrite("call_type", &context::call_type) - .def_readwrite("tupleargs", &context::tupleargs) - .def_readwrite("kwargs", &context::kwargs) - .def_readwrite("py_return_type", &context::py_return_type) - .def_readwrite("py_returned_double", &context::py_returned_double) - .def_readwrite("py_returned_int", &context::py_returned_int) - .def_readwrite("generator_next", &context::generator_next) - - ; - // FIXME make noncopyable: class_<ParamClass, noncopyable>("Params","Interpreter parameters",no_init) - class_ <remap_struct /*, noncopyable */>("Remap" /*, no_init*/) - .def_readwrite("name",&remap::name) - .def_readwrite("argspec",&remap::argspec) - .def_readwrite("modal_group",&remap::modal_group) - .def_readwrite("prolog_func",&remap::prolog_func) - .def_readwrite("remap_py",&remap::remap_py) - .def_readwrite("remap_ngc",&remap::remap_ngc) - .def_readwrite("epilog_func",&remap::epilog_func) - .def_readwrite("motion_code",&remap::motion_code) - .def("__str__", &remap_str) - - ; - - class_<remap_map,noncopyable>("RemapMap",no_init) - .def(map_indexing_suite<remap_map>()) - ; - - class_ <block, noncopyable>("Block",no_init) - .def_readwrite("f_flag",&block::f_flag) - .def_readwrite("p_flag",&block::p_flag) - .def_readwrite("p_number",&block::p_number) - .def_readwrite("a_flag",&block::a_flag) - .def_readwrite("a_number",&block::a_number) - .def_readwrite("b_flag",&block::b_flag) - .def_readwrite("b_number",&block::b_number) - .def_readwrite("c_flag",&block::c_flag) - .def_readwrite("c_number",&block::c_number) - .def_readwrite("d_number_float",&block::d_number_float) - .def_readwrite("d_flag",&block::d_flag) - .def_readwrite("e_flag",&block::e_flag) - .def_readwrite("e_number",&block::e_number) - .def_readwrite("f_flag",&block::f_flag) - .def_readwrite("f_number",&block::f_number) - .def_readwrite("h_flag",&block::h_flag) - .def_readwrite("h_number",&block::h_number) - .def_readwrite("i_flag",&block::i_flag) - .def_readwrite("i_number",&block::i_number) - .def_readwrite("j_flag",&block::j_flag) - .def_readwrite("j_number",&block::j_number) - .def_readwrite("k_flag",&block::k_flag) - .def_readwrite("k_number",&block::k_number) - .def_readwrite("l_number",&block::l_number) - .def_readwrite("l_flag",&block::l_flag) - .def_readwrite("line_number",&block::line_number) - .def_readwrite("saved_line_number",&block::line_number) - .def_readwrite("n_number",&block::n_number) - .def_readwrite("motion_to_be",&block::motion_to_be) - .def_readwrite("m_count",&block::m_count) - .def_readwrite("user_m",&block::user_m) - .def_readwrite("p_number",&block::p_number) - .def_readwrite("p_flag",&block::p_flag) - .def_readwrite("q_number",&block::q_number) - .def_readwrite("q_flag",&block::q_flag) - .def_readwrite("r_flag",&block::r_flag) - .def_readwrite("r_number",&block::r_number) - .def_readwrite("s_flag",&block::s_flag) - .def_readwrite("s_number",&block::s_number) - .def_readwrite("t_flag",&block::t_flag) - .def_readwrite("t_number",&block::t_number) - .def_readwrite("u_flag",&block::u_flag) - .def_readwrite("u_number",&block::u_number) - .def_readwrite("v_flag",&block::v_flag) - .def_readwrite("v_number",&block::v_number) - .def_readwrite("w_flag",&block::w_flag) - .def_readwrite("w_number",&block::w_number) - .def_readwrite("x_flag",&block::x_flag) - .def_readwrite("x_number",&block::x_number) - .def_readwrite("y_flag",&block::y_flag) - .def_readwrite("y_number",&block::y_number) - .def_readwrite("z_flag",&block::z_flag) - .def_readwrite("z_number",&block::z_number) - .def_readwrite("radius_flag",&block::radius_flag) - .def_readwrite("radius",&block::radius) - .def_readwrite("theta_flag",&block::theta_flag) - .def_readwrite("theta",&block::theta) - - .def_readwrite("offset",&block::offset) - .def_readwrite("o_type",&block::o_type) - - // I hope someday I really understand this - .add_property("executing_remap", - make_getter(&block::executing_remap,return_value_policy<reference_existing_object>()), - make_setter(&block::executing_remap,return_value_policy<reference_existing_object>())) - - .def_readwrite("call_type",&block::call_type) - .def_readwrite("breadcrumbs",&block::breadcrumbs) - .def_readwrite("phase",&block::phase) - .def_readwrite("builtin_used",&block::builtin_used) - - // read-only - .add_property("comment", &get_comment) - .add_property("o_name", &get_o_name) - - .add_property( "params", - bp::make_function( params_w(¶ms_wrapper), - bp::with_custodian_and_ward_postcall< 0, 1 >())) - // arrays - .add_property( "m_modes", - bp::make_function( m_modes_w(&m_modes_wrapper), - bp::with_custodian_and_ward_postcall< 0, 1 >())) - .add_property( "g_modes", - bp::make_function( g_modes_w(&g_modes_wrapper), - bp::with_custodian_and_ward_postcall< 0, 1 >())) - - ; - + export_EmcTypes(); + export_ParamClass(); + export_Internals(); + export_Block(); class_<InterpreterException>InterpreterExceptionClass("InterpreterException", bp::init<std::string, int, std::string>()); InterpreterExceptionClass .add_property("error_message", &InterpreterException::get_error_message) @@ -737,18 +406,5 @@ BOOST_PYTHON_MODULE(interpreter) { bp::with_custodian_and_ward_postcall< 0, 1 >())) ; - - pp::register_array_1< int, ACTIVE_G_CODES> ("ActiveGcodesArray" ); - pp::register_array_1< int, ACTIVE_M_CODES> ("ActiveMcodesArray" ); - pp::register_array_1< double, ACTIVE_SETTINGS> ("ActiveSettingsArray"); - pp::register_array_1< block, MAX_NESTED_REMAPS, - bp::return_internal_reference< 1, bp::default_call_policies > > ("BlocksArray"); - pp::register_array_1< double, RS274NGC_MAX_PARAMETERS > ("ParametersArray"); - pp::register_array_1< CANON_TOOL_TABLE, CANON_POCKETS_MAX, - bp::return_internal_reference< 1, bp::default_call_policies > > ("ToolTableArray"); - pp::register_array_1< context, INTERP_SUB_ROUTINE_LEVELS, - bp::return_internal_reference< 1, bp::default_call_policies > > ("SubcontextArray"); - pp::register_array_1< int, 16> ("GmodesArray"); - pp::register_array_1< int, 11> ("MmodesArray"); - pp::register_array_1< double, INTERP_SUB_PARAMS> ("SubroutineParamsArray"); + export_Arrays(); } diff --git a/src/emc/rs274ngc/paramclass.hh b/src/emc/rs274ngc/paramclass.hh new file mode 100644 index 000000000..39ad4566b --- /dev/null +++ b/src/emc/rs274ngc/paramclass.hh @@ -0,0 +1,15 @@ +struct ParamClass { + + Interp &interp; + + ParamClass(Interp &i); + double getitem( bp::object sub); + double setitem(bp::object sub, double dvalue); + bp::list namelist(context &c) const; + bp::list locals(); + bp::list globals(); + bp::list operator()() const; + int length(); +}; + +extern void export_ParamClass(); diff --git a/src/emc/rs274ngc/pyarrays.cc b/src/emc/rs274ngc/pyarrays.cc new file mode 100644 index 000000000..262bb2f3f --- /dev/null +++ b/src/emc/rs274ngc/pyarrays.cc @@ -0,0 +1,33 @@ +// Interpreter internals - Python bindings +// Michael Haberler 7/2011 + +#include <boost/python.hpp> +namespace bp = boost::python; + +#include "rs274ngc.hh" +#include "interp_internal.hh" +#include "array1.hh" + +namespace pp = pyplusplus::containers::static_sized; +#include "interp_array_types.hh" + + +void export_Arrays() +{ + using namespace boost::python; + using namespace boost; + + pp::register_array_1< int, ACTIVE_G_CODES> ("ActiveGcodesArray" ); + pp::register_array_1< int, ACTIVE_M_CODES> ("ActiveMcodesArray" ); + pp::register_array_1< double, ACTIVE_SETTINGS> ("ActiveSettingsArray"); + pp::register_array_1< block, MAX_NESTED_REMAPS, + bp::return_internal_reference< 1, bp::default_call_policies > > ("BlocksArray"); + pp::register_array_1< double, RS274NGC_MAX_PARAMETERS > ("ParametersArray"); + pp::register_array_1< CANON_TOOL_TABLE, CANON_POCKETS_MAX, + bp::return_internal_reference< 1, bp::default_call_policies > > ("ToolTableArray"); + pp::register_array_1< context, INTERP_SUB_ROUTINE_LEVELS, + bp::return_internal_reference< 1, bp::default_call_policies > > ("SubcontextArray"); + pp::register_array_1< int, 16> ("GmodesArray"); + pp::register_array_1< int, 11> ("MmodesArray"); + pp::register_array_1< double, INTERP_SUB_PARAMS> ("SubroutineParamsArray"); +} diff --git a/src/emc/rs274ngc/pyblock.cc b/src/emc/rs274ngc/pyblock.cc new file mode 100644 index 000000000..8204d57dd --- /dev/null +++ b/src/emc/rs274ngc/pyblock.cc @@ -0,0 +1,129 @@ +// Interpreter internals - Python bindings +// Michael Haberler 7/2011 +// + +#include <boost/python.hpp> +#include <boost/python/suite/indexing/map_indexing_suite.hpp> +#include <map> + +namespace bp = boost::python; + +#include "rs274ngc.hh" +#include "interp_internal.hh" +#include "rs274ngc_interp.hh" +#include "array1.hh" + +namespace pp = pyplusplus::containers::static_sized; +#include "interp_array_types.hh" + +static const char *get_comment(block &b) { return b.comment; }; +static const char *get_o_name(block &b) { return b.o_name; }; + +static g_modes_array g_modes_wrapper ( block & b) { + return g_modes_array(b.g_modes); +} + +static m_modes_array m_modes_wrapper ( block & b) { + return m_modes_array(b.m_modes); +} + +static params_array params_wrapper ( block & b) { + return params_array(b.params); +} + +void export_Block() +{ + using namespace boost::python; + using namespace boost; + class_ <block, noncopyable>("Block",no_init) + .def_readwrite("f_flag",&block::f_flag) + .def_readwrite("p_flag",&block::p_flag) + .def_readwrite("p_number",&block::p_number) + .def_readwrite("a_flag",&block::a_flag) + .def_readwrite("a_number",&block::a_number) + .def_readwrite("b_flag",&block::b_flag) + .def_readwrite("b_number",&block::b_number) + .def_readwrite("c_flag",&block::c_flag) + .def_readwrite("c_number",&block::c_number) + .def_readwrite("d_number_float",&block::d_number_float) + .def_readwrite("d_flag",&block::d_flag) + .def_readwrite("e_flag",&block::e_flag) + .def_readwrite("e_number",&block::e_number) + .def_readwrite("f_flag",&block::f_flag) + .def_readwrite("f_number",&block::f_number) + .def_readwrite("h_flag",&block::h_flag) + .def_readwrite("h_number",&block::h_number) + .def_readwrite("i_flag",&block::i_flag) + .def_readwrite("i_number",&block::i_number) + .def_readwrite("j_flag",&block::j_flag) + .def_readwrite("j_number",&block::j_number) + .def_readwrite("k_flag",&block::k_flag) + .def_readwrite("k_number",&block::k_number) + .def_readwrite("l_number",&block::l_number) + .def_readwrite("l_flag",&block::l_flag) + .def_readwrite("line_number",&block::line_number) + .def_readwrite("saved_line_number",&block::line_number) + .def_readwrite("n_number",&block::n_number) + .def_readwrite("motion_to_be",&block::motion_to_be) + .def_readwrite("m_count",&block::m_count) + .def_readwrite("user_m",&block::user_m) + .def_readwrite("p_number",&block::p_number) + .def_readwrite("p_flag",&block::p_flag) + .def_readwrite("q_number",&block::q_number) + .def_readwrite("q_flag",&block::q_flag) + .def_readwrite("r_flag",&block::r_flag) + .def_readwrite("r_number",&block::r_number) + .def_readwrite("s_flag",&block::s_flag) + .def_readwrite("s_number",&block::s_number) + .def_readwrite("t_flag",&block::t_flag) + .def_readwrite("t_number",&block::t_number) + .def_readwrite("u_flag",&block::u_flag) + .def_readwrite("u_number",&block::u_number) + .def_readwrite("v_flag",&block::v_flag) + .def_readwrite("v_number",&block::v_number) + .def_readwrite("w_flag",&block::w_flag) + .def_readwrite("w_number",&block::w_number) + .def_readwrite("x_flag",&block::x_flag) + .def_readwrite("x_number",&block::x_number) + .def_readwrite("y_flag",&block::y_flag) + .def_readwrite("y_number",&block::y_number) + .def_readwrite("z_flag",&block::z_flag) + .def_readwrite("z_number",&block::z_number) + .def_readwrite("radius_flag",&block::radius_flag) + .def_readwrite("radius",&block::radius) + .def_readwrite("theta_flag",&block::theta_flag) + .def_readwrite("theta",&block::theta) + + .def_readwrite("offset",&block::offset) + .def_readwrite("o_type",&block::o_type) + + // I hope someday I really understand this + .add_property("executing_remap", + make_getter(&block::executing_remap, + return_value_policy<reference_existing_object>()), + make_setter(&block::executing_remap, + return_value_policy<reference_existing_object>())) + + .def_readwrite("call_type",&block::call_type) + .def_readwrite("breadcrumbs",&block::breadcrumbs) + .def_readwrite("phase",&block::phase) + .def_readwrite("builtin_used",&block::builtin_used) + + // read-only + .add_property("comment", &get_comment) + .add_property("o_name", &get_o_name) + + .add_property( "params", + bp::make_function( params_w(¶ms_wrapper), + bp::with_custodian_and_ward_postcall< 0, 1 >())) + // arrays + .add_property( "m_modes", + bp::make_function( m_modes_w(&m_modes_wrapper), + bp::with_custodian_and_ward_postcall< 0, 1 >())) + .add_property( "g_modes", + bp::make_function( g_modes_w(&g_modes_wrapper), + bp::with_custodian_and_ward_postcall< 0, 1 >())) + + ; + +} diff --git a/src/emc/rs274ngc/pyemctypes.cc b/src/emc/rs274ngc/pyemctypes.cc new file mode 100644 index 000000000..18912574e --- /dev/null +++ b/src/emc/rs274ngc/pyemctypes.cc @@ -0,0 +1,87 @@ +// Interpreter internals - Python bindings +// Michael Haberler 7/2011 +// + +#include <boost/python.hpp> +namespace bp = boost::python; + +#include "rs274ngc.hh" + +static bp::object pmcartesian_str( PmCartesian &c) { + return bp::object("PmCartesian(x=%.4f y=%.4f z=%.4f)" % + bp::make_tuple(c.x,c.y,c.z)); +} + +static bp::object emcpose_2_obj ( EmcPose &p) { + return bp::object("x=%.4f y=%.4f z=%.4f a=%.4f b=%.4f c=%.4f u=%.4f v=%.4f w=%.4f" % + bp::make_tuple(p.tran.x,p.tran.y,p.tran.z, + p.a,p.b,p.c,p.u,p.v,p.w)); +} +static bp::object emcpose_str( EmcPose &p) { + return bp::object("EmcPose(" + emcpose_2_obj(p) + ")"); +} + +static void set_x(EmcPose &p, double value) { p.tran.x = value; } +static void set_y(EmcPose &p, double value) { p.tran.y = value; } +static void set_z(EmcPose &p, double value) { p.tran.z = value; } +static double get_x(EmcPose &p) { return p.tran.x; } +static double get_y(EmcPose &p) { return p.tran.y; } +static double get_z(EmcPose &p) { return p.tran.z; } + +static bp::object tool_str( CANON_TOOL_TABLE &t) { + return bp::object("Tool(T%d D%.4f I%.4f J%.4f Q%d offset: " % + bp::make_tuple(t.toolno, t.diameter, + t.frontangle,t.backangle, t.orientation) + + emcpose_2_obj(t.offset) + ")"); +} + +static void tool_zero( CANON_TOOL_TABLE &t) { + t.toolno = -1; + ZERO_EMC_POSE(t.offset); + t.diameter = 0.0; + t.frontangle = 0.0; + t.backangle = 0.0; + t.orientation = 0; +} + +void export_EmcTypes() +{ + using namespace boost::python; + using namespace boost; + + class_<PmCartesian, noncopyable>("PmCartesian","EMC cartesian postition",no_init) + .def_readwrite("x",&PmCartesian::x) + .def_readwrite("y",&PmCartesian::y) + .def_readwrite("z",&PmCartesian::z) + .def("__str__", &pmcartesian_str) + ; + + // leave EmcPose copyable/assignable because it's used as a parameter + // value (eg emcSetToolOffset) + class_<EmcPose>("EmcPose","EMC pose",no_init) + .def_readwrite("tran",&EmcPose::tran) + .add_property("x", &get_x, &set_x) + .add_property("y", &get_y, &set_y) + .add_property("z", &get_z, &set_z) + .def_readwrite("a",&EmcPose::a) + .def_readwrite("b",&EmcPose::b) + .def_readwrite("c",&EmcPose::c) + .def_readwrite("u",&EmcPose::u) + .def_readwrite("v",&EmcPose::v) + .def_readwrite("w",&EmcPose::w) + .def("__str__", &emcpose_str) + ; + + // leave CANON_TOOL_TABLE copyable/assignable because assignment is + // used a lot when fiddling with tooltable entries + class_<CANON_TOOL_TABLE >("CANON_TOOL_TABLE","Tool description" ,no_init) + .def_readwrite("toolno", &CANON_TOOL_TABLE::toolno) + .def_readwrite("offset", &CANON_TOOL_TABLE::offset) + .def_readwrite("diameter", &CANON_TOOL_TABLE::diameter) + .def_readwrite("frontangle", &CANON_TOOL_TABLE::frontangle) + .def_readwrite("backangle", &CANON_TOOL_TABLE::backangle) + .def_readwrite("orientation", &CANON_TOOL_TABLE::orientation) + .def("__str__", &tool_str) + .def("zero", &tool_zero) + ; +} diff --git a/src/emc/rs274ngc/pyinterp1.cc b/src/emc/rs274ngc/pyinterp1.cc new file mode 100644 index 000000000..dddb243b3 --- /dev/null +++ b/src/emc/rs274ngc/pyinterp1.cc @@ -0,0 +1,99 @@ +// Interpreter internals - Python bindings +// Michael Haberler 7/2011 +// + +#include <boost/python.hpp> +#include <boost/python/suite/indexing/map_indexing_suite.hpp> +#include <map> + +namespace bp = boost::python; + +#include "rs274ngc.hh" +#include "interp_internal.hh" +#include "rs274ngc_interp.hh" +#include "array1.hh" + +namespace pp = pyplusplus::containers::static_sized; +#include "interp_array_types.hh" + +static active_g_codes_array saved_g_codes_wrapper ( context &c) { + return active_g_codes_array(c.saved_g_codes); +} + +static active_m_codes_array saved_m_codes_wrapper ( context &c) { + return active_m_codes_array(c.saved_m_codes); +} + +static active_settings_array saved_settings_wrapper ( context &c) { + return active_settings_array(c.saved_settings); +} + +static params_array saved_params_wrapper ( context &c) { + return params_array(c.saved_params); +} +static bp::object remap_str( remap_struct &r) { + return bp::object("Remap(%s argspec=%s modal_group=%d prolog=%s ngc=%s python=%s epilog=%s) " % + bp::make_tuple(r.name,r.argspec,r.modal_group,r.prolog_func, + r.remap_ngc, r.remap_py, r.epilog_func)); +} + +void export_Internals() +{ + using namespace boost::python; + using namespace boost; + class_ <context, noncopyable>("Context",no_init) + .def_readwrite("position",&context::position) + .def_readwrite("sequence_number",&context::sequence_number) + .def_readwrite("filename", &context::filename) + .def_readwrite("subname", &context::subName) + .add_property( "saved_params", + bp::make_function( saved_params_w(&saved_params_wrapper), + bp::with_custodian_and_ward_postcall< 0, 1 >())) + .add_property( "saved_g_codes", + bp::make_function( active_g_codes_w(&saved_g_codes_wrapper), + bp::with_custodian_and_ward_postcall< 0, 1 >())) + .add_property( "saved_m_codes", + bp::make_function( active_m_codes_w(&saved_m_codes_wrapper), + bp::with_custodian_and_ward_postcall< 0, 1 >())) + .add_property( "saved_settings", + bp::make_function( active_settings_w(&saved_settings_wrapper), + bp::with_custodian_and_ward_postcall< 0, 1 >())) + .def_readwrite("context_status", &context::context_status) + .def_readwrite("named_params", &context::named_params) + + .def_readwrite("call_type", &context::call_type) + .def_readwrite("tupleargs", &context::tupleargs) + .def_readwrite("kwargs", &context::kwargs) + .def_readwrite("py_return_type", &context::py_return_type) + .def_readwrite("py_returned_double", &context::py_returned_double) + .def_readwrite("py_returned_int", &context::py_returned_int) + .def_readwrite("generator_next", &context::generator_next) + + ; + // FIXME make noncopyable: class_<ParamClass, noncopyable>("Params","Interpreter parameters",no_init) + class_ <remap_struct /*, noncopyable */>("Remap" /*, no_init*/) + .def_readwrite("name",&remap::name) + .def_readwrite("argspec",&remap::argspec) + .def_readwrite("modal_group",&remap::modal_group) + .def_readwrite("prolog_func",&remap::prolog_func) + .def_readwrite("remap_py",&remap::remap_py) + .def_readwrite("remap_ngc",&remap::remap_ngc) + .def_readwrite("epilog_func",&remap::epilog_func) + .def_readwrite("motion_code",&remap::motion_code) + .def("__str__", &remap_str) + + ; + + class_<remap_map,noncopyable>("RemapMap",no_init) + .def(map_indexing_suite<remap_map>()) + ; + + class_<parameter_value_struct /*,noncopyable */>("ParameterValue") // ,no_init) + .def_readwrite("attr",¶meter_value_struct::attr) + .def_readwrite("value",¶meter_value_struct::value) + ; + + class_<parameter_map,noncopyable>("ParameterMap",no_init) + .def(map_indexing_suite<parameter_map>()) + ; +} diff --git a/src/emc/rs274ngc/pyparamclass.cc b/src/emc/rs274ngc/pyparamclass.cc new file mode 100644 index 000000000..42a543719 --- /dev/null +++ b/src/emc/rs274ngc/pyparamclass.cc @@ -0,0 +1,116 @@ +// Interpreter internals - Python bindings +// Michael Haberler 7/2011 +// + +#include <boost/python.hpp> +#include <boost/python/suite/indexing/map_indexing_suite.hpp> +#include <map> + +namespace bp = boost::python; +extern int _task; // zero in gcodemodule, 1 in milltask + +#include <stdio.h> +#include <string.h> +#include <assert.h> + +#include "rs274ngc.hh" +#include "interp_return.hh" +#include "interp_internal.hh" +#include "rs274ngc_interp.hh" +#include "paramclass.hh" + +#define IS_STRING(x) (PyObject_IsInstance(x.ptr(), (PyObject*)&PyString_Type)) +#define IS_INT(x) (PyObject_IsInstance(x.ptr(), (PyObject*)&PyInt_Type)) + +// access to named and numbered parameters via a pseudo-dictionary +// either params["paramname"] or params[5400] is valid + +ParamClass::ParamClass(Interp &i) : interp(i) {}; + +double ParamClass::getitem( bp::object sub) +{ + double retval = 0; + if (IS_STRING(sub)) { + char const* varname = bp::extract < char const* > (sub); + int status; + interp.find_named_param(varname, &status, &retval); + if (!status) + throw std::runtime_error("parameter does not exist: " + + std::string(varname)); + } else + if (IS_INT(sub)) { + int index = bp::extract < int > (sub); + retval = interp._setup.parameters[index]; + } else { + throw std::runtime_error("params subscript type must be integer or string"); + } + return retval; +} + +double ParamClass::setitem(bp::object sub, double dvalue) +{ + if (IS_STRING(sub)) { + char const* varname = bp::extract < char const* > (sub); + int status = interp.add_named_param(varname, varname[0] == '_' ? PA_GLOBAL :0); + status = interp.store_named_param(&interp._setup,varname, dvalue, 0); + if (status != INTERP_OK) + throw std::runtime_error("cant assign value to parameter: " + + std::string(varname)); + + } else + if (IS_INT(sub)) { + int index = bp::extract < int > (sub); + if ((index < 0) || (index > RS274NGC_MAX_PARAMETERS -1)) { + std::stringstream sstr; + sstr << "params subscript out of range : " + << index << " - must be between 0 and " + << RS274NGC_MAX_PARAMETERS; + throw std::runtime_error(sstr.str()); + } + interp._setup.parameters[index] = dvalue; + return dvalue; + } else + throw std::runtime_error("params subscript type must be integer or string"); + return dvalue; +} + +bp::list ParamClass::namelist(context &c) const { + bp::list result; + for(parameter_map::iterator it = c.named_params.begin(); + it != c.named_params.end(); ++it) { + result.append( it->first); + } + return result; +} + +bp::list ParamClass::locals() { + return namelist(interp._setup.sub_context[interp._setup.call_level]); +} + +bp::list ParamClass::globals() { + return namelist(interp._setup.sub_context[0]); +} + +bp::list ParamClass::operator()() const +{ + bp::list result = namelist(interp._setup.sub_context[interp._setup.call_level]); + result.extend(namelist(interp._setup.sub_context[0])); + return result; +}; + +int ParamClass::length() { return RS274NGC_MAX_PARAMETERS;} + +void export_ParamClass() +{ + using namespace boost::python; + using namespace boost; + + class_<ParamClass>("Params","Interpreter parameters",no_init) + .def("__getitem__", &ParamClass::getitem) + .def("__setitem__", &ParamClass::setitem) + .def("__len__", &ParamClass::length) + .def("globals", &ParamClass::globals) + .def("locals", &ParamClass::locals) + .def("__call__", &ParamClass::operator()); + ; +} |