Started handling trivial case of return references. Removed most modules from build tree while testing (cmake/OpenCVModule)

This commit is contained in:
hbristow 2013-06-21 17:33:24 -07:00
parent d9cea3b8b0
commit 1a15ed3279
9 changed files with 127 additions and 48 deletions

View File

@ -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})

View File

@ -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()

View File

@ -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:]

View File

@ -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

View File

@ -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):

View File

@ -0,0 +1,57 @@
// 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 -%}

View File

@ -1,3 +1,4 @@
{% 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
}

View File

@ -1,3 +1,4 @@
{% 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
}

View File

@ -1,6 +1,6 @@
# 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