Commit 1a15ed32 authored by hbristow's avatar hbristow

Started handling trivial case of return references. Removed most modules from…

Started handling trivial case of return references. Removed most modules from build tree while testing (cmake/OpenCVModule)
parent d9cea3b8
...@@ -311,7 +311,9 @@ macro(ocv_glob_modules) ...@@ -311,7 +311,9 @@ macro(ocv_glob_modules)
endif() endif()
list(APPEND __directories_observed "${__path}") list(APPEND __directories_observed "${__path}")
file(GLOB __ocvmodules RELATIVE "${__path}" "${__path}/*") # TODO: Undo this change to build all modules
#file(GLOB __ocvmodules RELATIVE "${__path}" "${__path}/*")
file(GLOB __ocvmodules RELATIVE "${__path}" "${__path}/core" "${__path}/matlab")
if(__ocvmodules) if(__ocvmodules)
list(SORT __ocvmodules) list(SORT __ocvmodules)
foreach(mod ${__ocvmodules}) foreach(mod ${__ocvmodules})
......
...@@ -40,13 +40,16 @@ if (IOS OR ANDROID OR NOT MATLAB_FOUND OR NOT PYTHONLIBS_FOUND) ...@@ -40,13 +40,16 @@ if (IOS OR ANDROID OR NOT MATLAB_FOUND OR NOT PYTHONLIBS_FOUND)
return() return()
endif() endif()
# TODO: matlab bindings should depend on python (maybe)
set(the_description "The Matlab/Octave bindings") set(the_description "The Matlab/Octave bindings")
ocv_add_module(matlab BINDINGS opencv_core opencv_imgproc ocv_add_module(matlab BINDINGS opencv_core #TODO: does it actually NEED to depend on core?
OPTIONAL opencv_objdetect opencv_features2d opencv_video OPTIONAL opencv_objdetect opencv_features2d opencv_video
opencv_highgui opencv_ml opencv_calib3d opencv_photo opencv_highgui opencv_ml opencv_calib3d opencv_photo
opencv_nonfree opencv_calib) opencv_nonfree opencv_calib opencv_imgproc)
set(HDR_PARSER_PATH ${OPENCV_MODULE_opencv_python_LOCATION}/src2) # TODO: Undo this when building all modules to find python properly
#set(HDR_PARSER_PATH ${OPENCV_MODULE_opencv_python_LOCATION}/src2)
set(HDR_PARSER_PATH ${CMAKE_CURRENT_SOURCE_DIR}/../python/src2)
prepend("-I" MEX_INCLUDES ${CMAKE_CURRENT_SOURCE_DIR}/include) prepend("-I" MEX_INCLUDES ${CMAKE_CURRENT_SOURCE_DIR}/include)
if (BUILD_TESTS) if (BUILD_TESTS)
...@@ -106,14 +109,14 @@ foreach(module ${OPENCV_MATLAB_MODULES}) ...@@ -106,14 +109,14 @@ foreach(module ${OPENCV_MATLAB_MODULES})
endforeach() endforeach()
# synthesise the matlab sources # synthesise the matlab sources
add_custom_target(opencv_matlab_sources ALL add_custom_target(opencv_matlab_sources
COMMAND ${PYTHON_EXECUTABLE} COMMAND ${PYTHON_EXECUTABLE}
${CMAKE_CURRENT_SOURCE_DIR}/generator/gen_matlab_caller.py ${HDR_PARSER_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/generator/gen_matlab_caller.py ${HDR_PARSER_PATH}
${opencv_hdrs} ${CMAKE_CURRENT_BINARY_DIR} ${opencv_hdrs} ${CMAKE_CURRENT_BINARY_DIR}
) )
# compile the matlab sources to mex # compile the matlab sources to mex
add_custom_target(opencv_matlab ALL) add_custom_target(opencv_matlab ALL DEPENDS opencv_matlab_sources)
file(GLOB SOURCE_FILES "${CMAKE_CURRENT_BINARY_DIR}/src/*.cpp") file(GLOB SOURCE_FILES "${CMAKE_CURRENT_BINARY_DIR}/src/*.cpp")
foreach(SOURCE_FILE ${SOURCE_FILES}) foreach(SOURCE_FILE ${SOURCE_FILES})
get_filename_component(FILENAME ${SOURCE_FILE} NAME_WE) get_filename_component(FILENAME ${SOURCE_FILE} NAME_WE)
...@@ -122,7 +125,6 @@ foreach(SOURCE_FILE ${SOURCE_FILES}) ...@@ -122,7 +125,6 @@ foreach(SOURCE_FILE ${SOURCE_FILES})
COMMAND echo ${MATLAB_MEX_SCRIPT} ${MEX_INCLUDES} COMMAND echo ${MATLAB_MEX_SCRIPT} ${MEX_INCLUDES}
${SOURCE_FILE} ${SOURCE_FILE}
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/src WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/src
DEPENDS opencv_matlab_sources
) )
endforeach() endforeach()
......
...@@ -2,6 +2,40 @@ from textwrap import TextWrapper ...@@ -2,6 +2,40 @@ from textwrap import TextWrapper
from string import split, join from string import split, join
import re import re
def inputs(args):
'''Keeps only the input arguments in a list of elements.
In OpenCV input arguments are all arguments with names
not beginning with 'dst'
'''
out = []
for arg in args:
if not arg.name.startswith('dst'):
out.append(arg)
return out
def ninputs(args):
'''Counts the number of input arguments in the input list'''
return len(inputs(args))
def outputs(args):
'''Determines whether any of the given arguments is an output
reference, and returns a list of only those elements.
In OpenCV, output references are preceeded by 'dst'
'''
out = []
for arg in args:
if arg.name.startswith('dst'):
out.append(arg)
return out
def output(arg):
return True if arg.name.startswith('dst') else False
def noutputs(args):
'''Counts the number of output arguments in the input list'''
return len(outputs(args))
def toUpperCamelCase(text): def toUpperCamelCase(text):
return text[0].upper() + text[1:] return text[0].upper() + text[1:]
......
...@@ -31,6 +31,11 @@ class MatlabWrapperGenerator(object): ...@@ -31,6 +31,11 @@ class MatlabWrapperGenerator(object):
jtemplate.filters['toLowerCamelCase'] = toLowerCamelCase jtemplate.filters['toLowerCamelCase'] = toLowerCamelCase
jtemplate.filters['toUnderCase'] = toUnderCase jtemplate.filters['toUnderCase'] = toUnderCase
jtemplate.filters['comment'] = comment jtemplate.filters['comment'] = comment
jtemplate.filters['inputs'] = inputs
jtemplate.filters['outputs'] = outputs
jtemplate.filters['output'] = output
jtemplate.filters['noutputs'] = noutputs
jtemplate.filters['ninputs'] = ninputs
# load the templates # load the templates
tfunction = jtemplate.get_template('template_function_base.cpp') tfunction = jtemplate.get_template('template_function_base.cpp')
...@@ -53,7 +58,7 @@ class MatlabWrapperGenerator(object): ...@@ -53,7 +58,7 @@ class MatlabWrapperGenerator(object):
for namespace in parse_tree.namespaces: for namespace in parse_tree.namespaces:
# functions # functions
for function in namespace.functions: for function in namespace.functions:
populated = tfunction.render(fun=function, time=time) populated = tfunction.render(fun=function, time=time, includes=namespace.name)
with open(output_source_dir+'/'+function.name+'.cpp', 'wb') as f: with open(output_source_dir+'/'+function.name+'.cpp', 'wb') as f:
f.write(populated) f.write(populated)
# classes # classes
......
...@@ -85,7 +85,7 @@ class Translator(object): ...@@ -85,7 +85,7 @@ class Translator(object):
def translateArgument(self, defn): def translateArgument(self, defn):
tp = defn[0] tp = defn[0]
name = defn[1] name = defn[1]
default = tp+'()' if defn[2] else '' default = defn[2] if defn[2] else ''
return Argument(name, tp, False, '', default) return Argument(name, tp, False, '', default)
def translateName(self, name): def translateName(self, name):
......
// compose a function
{% macro compose(fun, retname="ret") %}
{%- if not fun.rtp == "void" -%} {{fun.rtp}} retname = {% endif -%}
{{fun.name}}(
{%- for arg in fun.req -%}
{{arg.name}}
{%- if not loop.last %}, {% endif %}
{% endfor %}
{% if fun.req and fun.opt %}, {% endif %}
{%- for opt in fun.opt -%}
{{opt.name}}
{%- if not loop.last -%}, {% endif %}
{%- endfor -%}
);
{%- endmacro %}
// create a full function invocation
{%- macro generate(fun) -%}
// unpack the arguments
// inputs
{% for arg in fun.req|inputs %}
{{arg.tp}} {{arg.name}} = inputs[{{ loop.index0 }}];
{% endfor %}
{% for opt in fun.opt|inputs %}
{{opt.tp}} {{opt.name}} = (nrhs > {{loop.index0 + fun.req|ninputs}}) ? inputs[{{loop.index0 + fun.req|ninputs}}] : {{opt.default}};
{% endfor %}
// outputs
{% for arg in fun.req|outputs %}
{{arg.tp}} {{arg.name}};
{% endfor %}
{% for opt in fun.opt|outputs %}
{{opt.tp}} {{opt.name}};
{% endfor %}
// call the opencv function
// [out =] namespace.fun(src1, ..., srcn, dst1, ..., dstn, opt1, ..., optn);
try {
{{ compose(fun) }}
} catch(cv::Exception& e) {
mexErrMsgTxt(std::string("cv::exception caught: ").append(e.what()).c_str());
} catch(std::exception& e) {
mexErrMsgTxt(std::string("std::exception caught: ").append(e.what()).c_str());
} catch(...) {
mexErrMsgTxt("Uncaught exception occurred in {{fun.name}}");
}
// assign the outputs into the bridge
{% for arg in fun.req|outputs %}
outputs[{{loop.index0}}] = {{arg.name}};
{% endfor %}
{% for opt in fun.opt|outputs %}
outputs[{{loop.index0 + fun.req|noutputs}}] = {{opt.name}};
{% endfor %}
{%- endmacro -%}
{% import 'functional.cpp' as functional %}
/* /*
* file: {{clss.name}}Bridge.cpp * file: {{clss.name}}Bridge.cpp
* author: A trusty code generator * author: A trusty code generator
...@@ -27,16 +28,7 @@ std::vector<Bridge> {{function.name}}({{clss.name}}& inst, const std::vector<Bri ...@@ -27,16 +28,7 @@ std::vector<Bridge> {{function.name}}({{clss.name}}& inst, const std::vector<Bri
// setup // setup
// invoke // invoke
try { {{ functional.generate(function) }}
// invoke
} catch(cv::Exception& e) {
mexErrMsgTxt(std::string("cv::exception caught: ").append(e.what()).c_str());
} catch(std::exception& e) {
mexErrMsgTxt(std::string("std::exception caught: ").append(e.what()).c_str());
} catch(...) {
mexErrMsgTxt("Uncaught exception occurred in {{function.name}}");
}
// setdown // setdown
} }
......
{% import 'functional.cpp' as functional %}
/* /*
* file: {{fun.name}}.cpp * file: {{fun.name}}.cpp
* author: A trusty code generator * author: A trusty code generator
...@@ -12,9 +13,11 @@ ...@@ -12,9 +13,11 @@
#include <string> #include <string>
#include <vector> #include <vector>
#include <exception> #include <exception>
#include <opencv2/core.hpp> #include <opencv2/{{ns}}.hpp>
{% block includes %} {% block includes %}
{% endblock %} {% endblock %}
using namespace std;
using namespace cv;
/* /*
* {{ fun.name }} * {{ fun.name }}
...@@ -27,34 +30,18 @@ ...@@ -27,34 +30,18 @@
void mexFunction(int nlhs, mxArray* plhs[], void mexFunction(int nlhs, mxArray* plhs[],
int nrhs, const mxArray* prhs[]) { int nrhs, const mxArray* prhs[]) {
{% block argcheck %} // assertions
{% endblock %} mxAssert(nrhs >= {{fun.req|length - fun.req|noutputs}}, "Too few required input arguments specified");
mxAssert(nrhs <= {{fun.req|length + fun.opt|length - fun.req|noutputs - fun.opt|noutputs}}, "Too many input arguments specified");
mxAssert(nlhs <= {{fun.ret|length + fun.req|noutputs + fun.opt|noutputs}}, "Too many output arguments specified");
{% block prebridge %} // setup
{% endblock %} vector<Bridge> inputs(plhs, plhs+nrhs);
vector<Bridge> outputs(nlhs);
// parse the inputs and outputs {{ fun }}
{% block postbridge %} {{ functional.generate(fun) }}
{% endblock %}
// call the opencv function // setdown
// [out =] namespace.fun(src1, ..., srcn, dst1, ..., dstn, opt1, ..., optn);
try {
{{fun.name}}();
} catch(cv::Exception& e) {
mexErrMsgTxt(std::string("cv::exception caught: ").append(e.what()).c_str());
} catch(std::exception& e) {
mexErrMsgTxt(std::string("std::exception caught: ").append(e.what()).c_str());
} catch(...) {
mexErrMsgTxt("Uncaught exception occurred in {{fun.name}}");
}
{% block fcall %}
{% endblock %}
{% block postfun %}
{% endblock %}
{% block cleanup %}
{% endblock %}
} }
# compile the test sources # compile the test sources
file(GLOB SOURCE_FILES "*.cpp") file(GLOB SOURCE_FILES "*.cpp")
add_custom_target(opencv_test_matlab_sources ALL) add_custom_target(opencv_test_matlab_sources)
foreach(SOURCE_FILE ${SOURCE_FILES}) foreach(SOURCE_FILE ${SOURCE_FILES})
get_filename_component(FILENAME ${SOURCE_FILE} NAME_WE) get_filename_component(FILENAME ${SOURCE_FILE} NAME_WE)
# compile the source file using mex # compile the source file using mex
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment