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)
endif()
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)
list(SORT __ocvmodules)
foreach(mod ${__ocvmodules})
......
......@@ -40,13 +40,16 @@ if (IOS OR ANDROID OR NOT MATLAB_FOUND OR NOT PYTHONLIBS_FOUND)
return()
endif()
# TODO: matlab bindings should depend on python (maybe)
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
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)
if (BUILD_TESTS)
......@@ -106,14 +109,14 @@ foreach(module ${OPENCV_MATLAB_MODULES})
endforeach()
# synthesise the matlab sources
add_custom_target(opencv_matlab_sources ALL
add_custom_target(opencv_matlab_sources
COMMAND ${PYTHON_EXECUTABLE}
${CMAKE_CURRENT_SOURCE_DIR}/generator/gen_matlab_caller.py ${HDR_PARSER_PATH}
${opencv_hdrs} ${CMAKE_CURRENT_BINARY_DIR}
)
# 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")
foreach(SOURCE_FILE ${SOURCE_FILES})
get_filename_component(FILENAME ${SOURCE_FILE} NAME_WE)
......@@ -122,7 +125,6 @@ foreach(SOURCE_FILE ${SOURCE_FILES})
COMMAND echo ${MATLAB_MEX_SCRIPT} ${MEX_INCLUDES}
${SOURCE_FILE}
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/src
DEPENDS opencv_matlab_sources
)
endforeach()
......
......@@ -2,6 +2,40 @@ from textwrap import TextWrapper
from string import split, join
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):
return text[0].upper() + text[1:]
......
......@@ -30,7 +30,12 @@ class MatlabWrapperGenerator(object):
jtemplate.filters['toUpperCamelCase'] = toUpperCamelCase
jtemplate.filters['toLowerCamelCase'] = toLowerCamelCase
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
tfunction = jtemplate.get_template('template_function_base.cpp')
......@@ -53,7 +58,7 @@ class MatlabWrapperGenerator(object):
for namespace in parse_tree.namespaces:
# 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:
f.write(populated)
# classes
......
......@@ -85,7 +85,7 @@ class Translator(object):
def translateArgument(self, defn):
tp = defn[0]
name = defn[1]
default = tp+'()' if defn[2] else ''
default = defn[2] if defn[2] else ''
return Argument(name, tp, False, '', default)
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
* author: A trusty code generator
......@@ -27,16 +28,7 @@ std::vector<Bridge> {{function.name}}({{clss.name}}& inst, const std::vector<Bri
// setup
// invoke
try {
// 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}}");
}
{{ functional.generate(function) }}
// setdown
}
......
{% import 'functional.cpp' as functional %}
/*
* file: {{fun.name}}.cpp
* author: A trusty code generator
......@@ -12,9 +13,11 @@
#include <string>
#include <vector>
#include <exception>
#include <opencv2/core.hpp>
#include <opencv2/{{ns}}.hpp>
{% block includes %}
{% endblock %}
using namespace std;
using namespace cv;
/*
* {{ fun.name }}
......@@ -27,34 +30,18 @@
void mexFunction(int nlhs, mxArray* plhs[],
int nrhs, const mxArray* prhs[]) {
{% block argcheck %}
{% endblock %}
// assertions
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 %}
{% endblock %}
// setup
vector<Bridge> inputs(plhs, plhs+nrhs);
vector<Bridge> outputs(nlhs);
// parse the inputs and outputs
{{ fun }}
{% block postbridge %}
{% endblock %}
{{ functional.generate(fun) }}
// call the opencv function
// [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 %}
// setdown
}
# compile the test sources
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})
get_filename_component(FILENAME ${SOURCE_FILE} NAME_WE)
# 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