Merging 'master' into 'wrap'
commit
8d2b7cd0cf
|
@ -5,12 +5,12 @@ on: [pull_request]
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
name: Tests for 🐍 ${{ matrix.python-version }}
|
name: Tests for 🐍 ${{ matrix.python-version }}
|
||||||
runs-on: ubuntu-18.04
|
runs-on: ubuntu-22.04
|
||||||
|
|
||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
python-version: [3.6, 3.7, 3.8, 3.9]
|
python-version: ["3.7", "3.8", "3.9", "3.10"]
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
|
@ -19,7 +19,7 @@ jobs:
|
||||||
- name: Install Dependencies
|
- name: Install Dependencies
|
||||||
run: |
|
run: |
|
||||||
sudo apt-get -y update
|
sudo apt-get -y update
|
||||||
sudo apt install cmake build-essential pkg-config libpython-dev python-numpy libboost-all-dev
|
sudo apt install cmake build-essential pkg-config libpython3-dev python3-numpy libboost-all-dev
|
||||||
|
|
||||||
- name: Set up Python ${{ matrix.python-version }}
|
- name: Set up Python ${{ matrix.python-version }}
|
||||||
uses: actions/setup-python@v2
|
uses: actions/setup-python@v2
|
||||||
|
|
|
@ -5,12 +5,12 @@ on: [pull_request]
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
name: Tests for 🐍 ${{ matrix.python-version }}
|
name: Tests for 🐍 ${{ matrix.python-version }}
|
||||||
runs-on: macos-10.15
|
runs-on: macos-12
|
||||||
|
|
||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
python-version: [3.6, 3.7, 3.8, 3.9]
|
python-version: ["3.7", "3.8", "3.9", "3.10"]
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
|
|
|
@ -60,6 +60,11 @@ class CheckMixin:
|
||||||
arg_type.typename.name not in self.not_ptr_type and \
|
arg_type.typename.name not in self.not_ptr_type and \
|
||||||
arg_type.is_ref
|
arg_type.is_ref
|
||||||
|
|
||||||
|
def is_class_enum(self, arg_type: parser.Type, class_: parser.Class):
|
||||||
|
"""Check if `arg_type` is an enum in the class `class_`."""
|
||||||
|
enums = (enum.name for enum in class_.enums)
|
||||||
|
return arg_type.ctype.typename.name in enums
|
||||||
|
|
||||||
|
|
||||||
class FormatMixin:
|
class FormatMixin:
|
||||||
"""Mixin to provide formatting utilities."""
|
"""Mixin to provide formatting utilities."""
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
"""Code generation templates for the Matlab wrapper."""
|
||||||
|
|
||||||
import textwrap
|
import textwrap
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -341,11 +341,26 @@ class MatlabWrapper(CheckMixin, FormatMixin):
|
||||||
|
|
||||||
return check_statement
|
return check_statement
|
||||||
|
|
||||||
def _unwrap_argument(self, arg, arg_id=0, constructor=False):
|
def _unwrap_argument(self,
|
||||||
|
arg,
|
||||||
|
arg_id=0,
|
||||||
|
constructor=False,
|
||||||
|
instantiated_class=None):
|
||||||
ctype_camel = self._format_type_name(arg.ctype.typename, separator='')
|
ctype_camel = self._format_type_name(arg.ctype.typename, separator='')
|
||||||
ctype_sep = self._format_type_name(arg.ctype.typename)
|
ctype_sep = self._format_type_name(arg.ctype.typename)
|
||||||
|
|
||||||
if self.is_ref(arg.ctype): # and not constructor:
|
if instantiated_class and \
|
||||||
|
self.is_class_enum(arg, instantiated_class):
|
||||||
|
|
||||||
|
if instantiated_class.original.template:
|
||||||
|
enum_type = f"{arg.ctype.typename}"
|
||||||
|
else:
|
||||||
|
enum_type = f"{instantiated_class.name}::{arg.ctype}"
|
||||||
|
|
||||||
|
arg_type = f"std::shared_ptr<{enum_type}>"
|
||||||
|
unwrap = f'unwrap_enum<{enum_type}>(in[{arg_id}]);'
|
||||||
|
|
||||||
|
elif self.is_ref(arg.ctype): # and not constructor:
|
||||||
arg_type = "{ctype}&".format(ctype=ctype_sep)
|
arg_type = "{ctype}&".format(ctype=ctype_sep)
|
||||||
unwrap = '*unwrap_shared_ptr< {ctype} >(in[{id}], "ptr_{ctype_camel}");'.format(
|
unwrap = '*unwrap_shared_ptr< {ctype} >(in[{id}], "ptr_{ctype_camel}");'.format(
|
||||||
ctype=ctype_sep, ctype_camel=ctype_camel, id=arg_id)
|
ctype=ctype_sep, ctype_camel=ctype_camel, id=arg_id)
|
||||||
|
@ -372,7 +387,11 @@ class MatlabWrapper(CheckMixin, FormatMixin):
|
||||||
|
|
||||||
return arg_type, unwrap
|
return arg_type, unwrap
|
||||||
|
|
||||||
def _wrapper_unwrap_arguments(self, args, arg_id=0, constructor=False):
|
def _wrapper_unwrap_arguments(self,
|
||||||
|
args,
|
||||||
|
arg_id=0,
|
||||||
|
constructor=False,
|
||||||
|
instantiated_class=None):
|
||||||
"""Format the interface_parser.Arguments.
|
"""Format the interface_parser.Arguments.
|
||||||
|
|
||||||
Examples:
|
Examples:
|
||||||
|
@ -383,7 +402,11 @@ class MatlabWrapper(CheckMixin, FormatMixin):
|
||||||
body_args = ''
|
body_args = ''
|
||||||
|
|
||||||
for arg in args.list():
|
for arg in args.list():
|
||||||
arg_type, unwrap = self._unwrap_argument(arg, arg_id, constructor)
|
arg_type, unwrap = self._unwrap_argument(
|
||||||
|
arg,
|
||||||
|
arg_id,
|
||||||
|
constructor,
|
||||||
|
instantiated_class=instantiated_class)
|
||||||
|
|
||||||
body_args += textwrap.indent(textwrap.dedent('''\
|
body_args += textwrap.indent(textwrap.dedent('''\
|
||||||
{arg_type} {name} = {unwrap}
|
{arg_type} {name} = {unwrap}
|
||||||
|
@ -535,7 +558,7 @@ class MatlabWrapper(CheckMixin, FormatMixin):
|
||||||
|
|
||||||
def wrap_methods(self, methods, global_funcs=False, global_ns=None):
|
def wrap_methods(self, methods, global_funcs=False, global_ns=None):
|
||||||
"""
|
"""
|
||||||
Wrap a sequence of methods. Groups methods with the same names
|
Wrap a sequence of methods/functions. Groups methods with the same names
|
||||||
together.
|
together.
|
||||||
If global_funcs is True then output every method into its own file.
|
If global_funcs is True then output every method into its own file.
|
||||||
"""
|
"""
|
||||||
|
@ -1027,7 +1050,7 @@ class MatlabWrapper(CheckMixin, FormatMixin):
|
||||||
if uninstantiated_name in self.ignore_classes:
|
if uninstantiated_name in self.ignore_classes:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
# Class comment
|
# Class docstring/comment
|
||||||
content_text = self.class_comment(instantiated_class)
|
content_text = self.class_comment(instantiated_class)
|
||||||
content_text += self.wrap_methods(instantiated_class.methods)
|
content_text += self.wrap_methods(instantiated_class.methods)
|
||||||
|
|
||||||
|
@ -1108,31 +1131,73 @@ class MatlabWrapper(CheckMixin, FormatMixin):
|
||||||
end
|
end
|
||||||
''')
|
''')
|
||||||
|
|
||||||
|
# Enums
|
||||||
|
# Place enums into the correct submodule so we can access them
|
||||||
|
# e.g. gtsam.Class.Enum.A
|
||||||
|
for enum in instantiated_class.enums:
|
||||||
|
enum_text = self.wrap_enum(enum)
|
||||||
|
if namespace_name != '':
|
||||||
|
submodule = f"+{namespace_name}/"
|
||||||
|
else:
|
||||||
|
submodule = ""
|
||||||
|
submodule += f"+{instantiated_class.name}"
|
||||||
|
self.content.append((submodule, [enum_text]))
|
||||||
|
|
||||||
return file_name + '.m', content_text
|
return file_name + '.m', content_text
|
||||||
|
|
||||||
def wrap_namespace(self, namespace):
|
def wrap_enum(self, enum):
|
||||||
|
"""
|
||||||
|
Wrap an enum definition.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
enum: The interface_parser.Enum instance
|
||||||
|
"""
|
||||||
|
file_name = enum.name + '.m'
|
||||||
|
enum_template = textwrap.dedent("""\
|
||||||
|
classdef {0} < uint32
|
||||||
|
enumeration
|
||||||
|
{1}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
""")
|
||||||
|
enumerators = "\n ".join([
|
||||||
|
f"{enumerator.name}({idx})"
|
||||||
|
for idx, enumerator in enumerate(enum.enumerators)
|
||||||
|
])
|
||||||
|
|
||||||
|
content = enum_template.format(enum.name, enumerators)
|
||||||
|
return file_name, content
|
||||||
|
|
||||||
|
def wrap_namespace(self, namespace, add_mex_file=True):
|
||||||
"""Wrap a namespace by wrapping all of its components.
|
"""Wrap a namespace by wrapping all of its components.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
namespace: the interface_parser.namespace instance of the namespace
|
namespace: the interface_parser.namespace instance of the namespace
|
||||||
parent: parent namespace
|
add_cpp_file: Flag indicating whether the mex file should be added
|
||||||
"""
|
"""
|
||||||
namespaces = namespace.full_namespaces()
|
namespaces = namespace.full_namespaces()
|
||||||
inner_namespace = namespace.name != ''
|
inner_namespace = namespace.name != ''
|
||||||
wrapped = []
|
wrapped = []
|
||||||
|
|
||||||
cpp_filename = self._wrapper_name() + '.cpp'
|
top_level_scope = []
|
||||||
self.content.append((cpp_filename, self.wrapper_file_headers))
|
inner_namespace_scope = []
|
||||||
|
|
||||||
current_scope = []
|
|
||||||
namespace_scope = []
|
|
||||||
|
|
||||||
for element in namespace.content:
|
for element in namespace.content:
|
||||||
if isinstance(element, parser.Include):
|
if isinstance(element, parser.Include):
|
||||||
self.includes.append(element)
|
self.includes.append(element)
|
||||||
|
|
||||||
elif isinstance(element, parser.Namespace):
|
elif isinstance(element, parser.Namespace):
|
||||||
self.wrap_namespace(element)
|
self.wrap_namespace(element, False)
|
||||||
|
|
||||||
|
elif isinstance(element, parser.Enum):
|
||||||
|
file, content = self.wrap_enum(element)
|
||||||
|
if inner_namespace:
|
||||||
|
module = "".join([
|
||||||
|
'+' + x + '/' for x in namespace.full_namespaces()[1:]
|
||||||
|
])[:-1]
|
||||||
|
inner_namespace_scope.append((module, [(file, content)]))
|
||||||
|
else:
|
||||||
|
top_level_scope.append((file, content))
|
||||||
|
|
||||||
elif isinstance(element, instantiator.InstantiatedClass):
|
elif isinstance(element, instantiator.InstantiatedClass):
|
||||||
self.add_class(element)
|
self.add_class(element)
|
||||||
|
@ -1142,18 +1207,22 @@ class MatlabWrapper(CheckMixin, FormatMixin):
|
||||||
element, "".join(namespace.full_namespaces()))
|
element, "".join(namespace.full_namespaces()))
|
||||||
|
|
||||||
if not class_text is None:
|
if not class_text is None:
|
||||||
namespace_scope.append(("".join([
|
inner_namespace_scope.append(("".join([
|
||||||
'+' + x + '/'
|
'+' + x + '/'
|
||||||
for x in namespace.full_namespaces()[1:]
|
for x in namespace.full_namespaces()[1:]
|
||||||
])[:-1], [(class_text[0], class_text[1])]))
|
])[:-1], [(class_text[0], class_text[1])]))
|
||||||
else:
|
else:
|
||||||
class_text = self.wrap_instantiated_class(element)
|
class_text = self.wrap_instantiated_class(element)
|
||||||
current_scope.append((class_text[0], class_text[1]))
|
top_level_scope.append((class_text[0], class_text[1]))
|
||||||
|
|
||||||
self.content.extend(current_scope)
|
self.content.extend(top_level_scope)
|
||||||
|
|
||||||
if inner_namespace:
|
if inner_namespace:
|
||||||
self.content.append(namespace_scope)
|
self.content.append(inner_namespace_scope)
|
||||||
|
|
||||||
|
if add_mex_file:
|
||||||
|
cpp_filename = self._wrapper_name() + '.cpp'
|
||||||
|
self.content.append((cpp_filename, self.wrapper_file_headers))
|
||||||
|
|
||||||
# Global functions
|
# Global functions
|
||||||
all_funcs = [
|
all_funcs = [
|
||||||
|
@ -1213,10 +1282,22 @@ class MatlabWrapper(CheckMixin, FormatMixin):
|
||||||
|
|
||||||
return return_type_text
|
return return_type_text
|
||||||
|
|
||||||
def _collector_return(self, obj: str, ctype: parser.Type):
|
def _collector_return(self,
|
||||||
|
obj: str,
|
||||||
|
ctype: parser.Type,
|
||||||
|
class_property: parser.Variable = None,
|
||||||
|
instantiated_class: InstantiatedClass = None):
|
||||||
"""Helper method to get the final statement before the return in the collector function."""
|
"""Helper method to get the final statement before the return in the collector function."""
|
||||||
expanded = ''
|
expanded = ''
|
||||||
if self.is_shared_ptr(ctype) or self.is_ptr(ctype) or \
|
|
||||||
|
if class_property and instantiated_class and \
|
||||||
|
self.is_class_enum(class_property, instantiated_class):
|
||||||
|
class_name = ".".join(instantiated_class.namespaces()[1:] + [instantiated_class.name])
|
||||||
|
enum_type = f"{class_name}.{ctype.typename.name}"
|
||||||
|
expanded = textwrap.indent(
|
||||||
|
f'out[0] = wrap_enum({obj},\"{enum_type}\");', prefix=' ')
|
||||||
|
|
||||||
|
elif self.is_shared_ptr(ctype) or self.is_ptr(ctype) or \
|
||||||
self.can_be_pointer(ctype):
|
self.can_be_pointer(ctype):
|
||||||
sep_method_name = partial(self._format_type_name,
|
sep_method_name = partial(self._format_type_name,
|
||||||
ctype.typename,
|
ctype.typename,
|
||||||
|
@ -1316,13 +1397,19 @@ class MatlabWrapper(CheckMixin, FormatMixin):
|
||||||
|
|
||||||
return expanded
|
return expanded
|
||||||
|
|
||||||
def wrap_collector_property_return(self, class_property: parser.Variable):
|
def wrap_collector_property_return(
|
||||||
|
self,
|
||||||
|
class_property: parser.Variable,
|
||||||
|
instantiated_class: InstantiatedClass = None):
|
||||||
"""Get the last collector function statement before return for a property."""
|
"""Get the last collector function statement before return for a property."""
|
||||||
property_name = class_property.name
|
property_name = class_property.name
|
||||||
obj = 'obj->{}'.format(property_name)
|
obj = 'obj->{}'.format(property_name)
|
||||||
property_type = class_property.ctype
|
|
||||||
|
|
||||||
return self._collector_return(obj, property_type)
|
ctype = class_property.ctype
|
||||||
|
return self._collector_return(obj,
|
||||||
|
ctype,
|
||||||
|
class_property=class_property,
|
||||||
|
instantiated_class=instantiated_class)
|
||||||
|
|
||||||
def wrap_collector_function_upcast_from_void(self, class_name, func_id,
|
def wrap_collector_function_upcast_from_void(self, class_name, func_id,
|
||||||
cpp_name):
|
cpp_name):
|
||||||
|
@ -1381,7 +1468,9 @@ class MatlabWrapper(CheckMixin, FormatMixin):
|
||||||
elif collector_func[2] == 'constructor':
|
elif collector_func[2] == 'constructor':
|
||||||
base = ''
|
base = ''
|
||||||
params, body_args = self._wrapper_unwrap_arguments(
|
params, body_args = self._wrapper_unwrap_arguments(
|
||||||
extra.args, constructor=True)
|
extra.args,
|
||||||
|
constructor=True,
|
||||||
|
instantiated_class=collector_func[1])
|
||||||
|
|
||||||
if collector_func[1].parent_class:
|
if collector_func[1].parent_class:
|
||||||
base += textwrap.indent(textwrap.dedent('''
|
base += textwrap.indent(textwrap.dedent('''
|
||||||
|
@ -1442,7 +1531,9 @@ class MatlabWrapper(CheckMixin, FormatMixin):
|
||||||
method_name += extra.name
|
method_name += extra.name
|
||||||
|
|
||||||
_, body_args = self._wrapper_unwrap_arguments(
|
_, body_args = self._wrapper_unwrap_arguments(
|
||||||
extra.args, arg_id=1 if is_method else 0)
|
extra.args,
|
||||||
|
arg_id=1 if is_method else 0,
|
||||||
|
instantiated_class=collector_func[1])
|
||||||
return_body = self.wrap_collector_function_return(extra)
|
return_body = self.wrap_collector_function_return(extra)
|
||||||
|
|
||||||
shared_obj = ''
|
shared_obj = ''
|
||||||
|
@ -1472,7 +1563,8 @@ class MatlabWrapper(CheckMixin, FormatMixin):
|
||||||
class_name=class_name)
|
class_name=class_name)
|
||||||
|
|
||||||
# Unpack the property from mxArray
|
# Unpack the property from mxArray
|
||||||
property_type, unwrap = self._unwrap_argument(extra, arg_id=1)
|
property_type, unwrap = self._unwrap_argument(
|
||||||
|
extra, arg_id=1, instantiated_class=collector_func[1])
|
||||||
unpack_property = textwrap.indent(textwrap.dedent('''\
|
unpack_property = textwrap.indent(textwrap.dedent('''\
|
||||||
{arg_type} {name} = {unwrap}
|
{arg_type} {name} = {unwrap}
|
||||||
'''.format(arg_type=property_type,
|
'''.format(arg_type=property_type,
|
||||||
|
@ -1482,7 +1574,8 @@ class MatlabWrapper(CheckMixin, FormatMixin):
|
||||||
|
|
||||||
# Getter
|
# Getter
|
||||||
if "_get_" in method_name:
|
if "_get_" in method_name:
|
||||||
return_body = self.wrap_collector_property_return(extra)
|
return_body = self.wrap_collector_property_return(
|
||||||
|
extra, instantiated_class=collector_func[1])
|
||||||
|
|
||||||
getter = ' checkArguments("{property_name}",nargout,nargin{min1},' \
|
getter = ' checkArguments("{property_name}",nargout,nargin{min1},' \
|
||||||
'{num_args});\n' \
|
'{num_args});\n' \
|
||||||
|
@ -1837,3 +1930,4 @@ class MatlabWrapper(CheckMixin, FormatMixin):
|
||||||
self.generate_content(self.content, path)
|
self.generate_content(self.content, path)
|
||||||
|
|
||||||
return self.content
|
return self.content
|
||||||
|
|
||||||
|
|
|
@ -228,8 +228,22 @@ mxArray* wrap<gtsam::Matrix >(const gtsam::Matrix& A) {
|
||||||
return wrap_Matrix(A);
|
return wrap_Matrix(A);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
mxArray* wrap_enum(const T x, const std::string& classname) {
|
||||||
|
// create double array to store value in
|
||||||
|
mxArray* a = mxCreateDoubleMatrix(1, 1, mxREAL);
|
||||||
|
double* data = mxGetPr(a);
|
||||||
|
data[0] = static_cast<double>(x);
|
||||||
|
|
||||||
|
// convert to Matlab enumeration type
|
||||||
|
mxArray* result;
|
||||||
|
mexCallMATLAB(1, &result, 1, &a, classname.c_str());
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
//*****************************************************************************
|
//*****************************************************************************
|
||||||
// unwrapping MATLAB arrays into C++ basis types
|
// unwrapping MATLAB arrays into C++ basic types
|
||||||
//*****************************************************************************
|
//*****************************************************************************
|
||||||
|
|
||||||
// default unwrapping throws an error
|
// default unwrapping throws an error
|
||||||
|
@ -240,6 +254,22 @@ T unwrap(const mxArray* array) {
|
||||||
return T();
|
return T();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
shared_ptr<T> unwrap_enum(const mxArray* array) {
|
||||||
|
// Make duplicate to remove const-ness
|
||||||
|
mxArray* a = mxDuplicateArray(array);
|
||||||
|
std::cout << "unwrap enum type: " << typeid(array).name() << std::endl;
|
||||||
|
|
||||||
|
// convert void* to int32* array
|
||||||
|
mxArray* a_int32;
|
||||||
|
mexCallMATLAB(1, &a_int32, 1, &a, "int32");
|
||||||
|
|
||||||
|
// Get the value in the input array
|
||||||
|
int32_T* value = (int32_T*)mxGetData(a_int32);
|
||||||
|
// cast int32 to enum type
|
||||||
|
return std::make_shared<T>(static_cast<T>(*value));
|
||||||
|
}
|
||||||
|
|
||||||
// specialization to string
|
// specialization to string
|
||||||
// expects a character array
|
// expects a character array
|
||||||
// Warning: relies on mxChar==char
|
// Warning: relies on mxChar==char
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
classdef Kind < uint32
|
||||||
|
enumeration
|
||||||
|
Dog(0)
|
||||||
|
Cat(1)
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,9 @@
|
||||||
|
classdef Avengers < uint32
|
||||||
|
enumeration
|
||||||
|
CaptainAmerica(0)
|
||||||
|
IronMan(1)
|
||||||
|
Hulk(2)
|
||||||
|
Hawkeye(3)
|
||||||
|
Thor(4)
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,9 @@
|
||||||
|
classdef GotG < uint32
|
||||||
|
enumeration
|
||||||
|
Starlord(0)
|
||||||
|
Gamorra(1)
|
||||||
|
Rocket(2)
|
||||||
|
Drax(3)
|
||||||
|
Groot(4)
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,7 @@
|
||||||
|
classdef Verbosity < uint32
|
||||||
|
enumeration
|
||||||
|
SILENT(0)
|
||||||
|
SUMMARY(1)
|
||||||
|
VERBOSE(2)
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,12 @@
|
||||||
|
classdef VerbosityLM < uint32
|
||||||
|
enumeration
|
||||||
|
SILENT(0)
|
||||||
|
SUMMARY(1)
|
||||||
|
TERMINATION(2)
|
||||||
|
LAMBDA(3)
|
||||||
|
TRYLAMBDA(4)
|
||||||
|
TRYCONFIG(5)
|
||||||
|
DAMPED(6)
|
||||||
|
TRYDELTA(7)
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,7 @@
|
||||||
|
classdef Color < uint32
|
||||||
|
enumeration
|
||||||
|
Red(0)
|
||||||
|
Green(1)
|
||||||
|
Blue(2)
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,266 @@
|
||||||
|
#include <gtwrap/matlab.h>
|
||||||
|
#include <map>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
typedef gtsam::Optimizer<gtsam::GaussNewtonParams> OptimizerGaussNewtonParams;
|
||||||
|
|
||||||
|
typedef std::set<std::shared_ptr<Pet>*> Collector_Pet;
|
||||||
|
static Collector_Pet collector_Pet;
|
||||||
|
typedef std::set<std::shared_ptr<gtsam::MCU>*> Collector_gtsamMCU;
|
||||||
|
static Collector_gtsamMCU collector_gtsamMCU;
|
||||||
|
typedef std::set<std::shared_ptr<OptimizerGaussNewtonParams>*> Collector_gtsamOptimizerGaussNewtonParams;
|
||||||
|
static Collector_gtsamOptimizerGaussNewtonParams collector_gtsamOptimizerGaussNewtonParams;
|
||||||
|
|
||||||
|
|
||||||
|
void _deleteAllObjects()
|
||||||
|
{
|
||||||
|
mstream mout;
|
||||||
|
std::streambuf *outbuf = std::cout.rdbuf(&mout);
|
||||||
|
|
||||||
|
bool anyDeleted = false;
|
||||||
|
{ for(Collector_Pet::iterator iter = collector_Pet.begin();
|
||||||
|
iter != collector_Pet.end(); ) {
|
||||||
|
delete *iter;
|
||||||
|
collector_Pet.erase(iter++);
|
||||||
|
anyDeleted = true;
|
||||||
|
} }
|
||||||
|
{ for(Collector_gtsamMCU::iterator iter = collector_gtsamMCU.begin();
|
||||||
|
iter != collector_gtsamMCU.end(); ) {
|
||||||
|
delete *iter;
|
||||||
|
collector_gtsamMCU.erase(iter++);
|
||||||
|
anyDeleted = true;
|
||||||
|
} }
|
||||||
|
{ for(Collector_gtsamOptimizerGaussNewtonParams::iterator iter = collector_gtsamOptimizerGaussNewtonParams.begin();
|
||||||
|
iter != collector_gtsamOptimizerGaussNewtonParams.end(); ) {
|
||||||
|
delete *iter;
|
||||||
|
collector_gtsamOptimizerGaussNewtonParams.erase(iter++);
|
||||||
|
anyDeleted = true;
|
||||||
|
} }
|
||||||
|
|
||||||
|
if(anyDeleted)
|
||||||
|
cout <<
|
||||||
|
"WARNING: Wrap modules with variables in the workspace have been reloaded due to\n"
|
||||||
|
"calling destructors, call 'clear all' again if you plan to now recompile a wrap\n"
|
||||||
|
"module, so that your recompiled module is used instead of the old one." << endl;
|
||||||
|
std::cout.rdbuf(outbuf);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _enum_RTTIRegister() {
|
||||||
|
const mxArray *alreadyCreated = mexGetVariablePtr("global", "gtsam_enum_rttiRegistry_created");
|
||||||
|
if(!alreadyCreated) {
|
||||||
|
std::map<std::string, std::string> types;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
mxArray *registry = mexGetVariable("global", "gtsamwrap_rttiRegistry");
|
||||||
|
if(!registry)
|
||||||
|
registry = mxCreateStructMatrix(1, 1, 0, NULL);
|
||||||
|
typedef std::pair<std::string, std::string> StringPair;
|
||||||
|
for(const StringPair& rtti_matlab: types) {
|
||||||
|
int fieldId = mxAddField(registry, rtti_matlab.first.c_str());
|
||||||
|
if(fieldId < 0) {
|
||||||
|
mexErrMsgTxt("gtsam wrap: Error indexing RTTI types, inheritance will not work correctly");
|
||||||
|
}
|
||||||
|
mxArray *matlabName = mxCreateString(rtti_matlab.second.c_str());
|
||||||
|
mxSetFieldByNumber(registry, 0, fieldId, matlabName);
|
||||||
|
}
|
||||||
|
if(mexPutVariable("global", "gtsamwrap_rttiRegistry", registry) != 0) {
|
||||||
|
mexErrMsgTxt("gtsam wrap: Error indexing RTTI types, inheritance will not work correctly");
|
||||||
|
}
|
||||||
|
mxDestroyArray(registry);
|
||||||
|
|
||||||
|
mxArray *newAlreadyCreated = mxCreateNumericMatrix(0, 0, mxINT8_CLASS, mxREAL);
|
||||||
|
if(mexPutVariable("global", "gtsam_enum_rttiRegistry_created", newAlreadyCreated) != 0) {
|
||||||
|
mexErrMsgTxt("gtsam wrap: Error indexing RTTI types, inheritance will not work correctly");
|
||||||
|
}
|
||||||
|
mxDestroyArray(newAlreadyCreated);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Pet_collectorInsertAndMakeBase_0(int nargout, mxArray *out[], int nargin, const mxArray *in[])
|
||||||
|
{
|
||||||
|
mexAtExit(&_deleteAllObjects);
|
||||||
|
typedef std::shared_ptr<Pet> Shared;
|
||||||
|
|
||||||
|
Shared *self = *reinterpret_cast<Shared**> (mxGetData(in[0]));
|
||||||
|
collector_Pet.insert(self);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Pet_constructor_1(int nargout, mxArray *out[], int nargin, const mxArray *in[])
|
||||||
|
{
|
||||||
|
mexAtExit(&_deleteAllObjects);
|
||||||
|
typedef std::shared_ptr<Pet> Shared;
|
||||||
|
|
||||||
|
string& name = *unwrap_shared_ptr< string >(in[0], "ptr_string");
|
||||||
|
std::shared_ptr<Pet::Kind> type = unwrap_enum<Pet::Kind>(in[1]);
|
||||||
|
Shared *self = new Shared(new Pet(name,*type));
|
||||||
|
collector_Pet.insert(self);
|
||||||
|
out[0] = mxCreateNumericMatrix(1, 1, mxUINT32OR64_CLASS, mxREAL);
|
||||||
|
*reinterpret_cast<Shared**> (mxGetData(out[0])) = self;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Pet_deconstructor_2(int nargout, mxArray *out[], int nargin, const mxArray *in[])
|
||||||
|
{
|
||||||
|
typedef std::shared_ptr<Pet> Shared;
|
||||||
|
checkArguments("delete_Pet",nargout,nargin,1);
|
||||||
|
Shared *self = *reinterpret_cast<Shared**>(mxGetData(in[0]));
|
||||||
|
Collector_Pet::iterator item;
|
||||||
|
item = collector_Pet.find(self);
|
||||||
|
if(item != collector_Pet.end()) {
|
||||||
|
collector_Pet.erase(item);
|
||||||
|
}
|
||||||
|
delete self;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Pet_get_name_3(int nargout, mxArray *out[], int nargin, const mxArray *in[])
|
||||||
|
{
|
||||||
|
checkArguments("name",nargout,nargin-1,0);
|
||||||
|
auto obj = unwrap_shared_ptr<Pet>(in[0], "ptr_Pet");
|
||||||
|
out[0] = wrap< string >(obj->name);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Pet_set_name_4(int nargout, mxArray *out[], int nargin, const mxArray *in[])
|
||||||
|
{
|
||||||
|
checkArguments("name",nargout,nargin-1,1);
|
||||||
|
auto obj = unwrap_shared_ptr<Pet>(in[0], "ptr_Pet");
|
||||||
|
string name = unwrap< string >(in[1]);
|
||||||
|
obj->name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Pet_get_type_5(int nargout, mxArray *out[], int nargin, const mxArray *in[])
|
||||||
|
{
|
||||||
|
checkArguments("type",nargout,nargin-1,0);
|
||||||
|
auto obj = unwrap_shared_ptr<Pet>(in[0], "ptr_Pet");
|
||||||
|
out[0] = wrap_enum(obj->type,"Pet.Kind");
|
||||||
|
}
|
||||||
|
|
||||||
|
void Pet_set_type_6(int nargout, mxArray *out[], int nargin, const mxArray *in[])
|
||||||
|
{
|
||||||
|
checkArguments("type",nargout,nargin-1,1);
|
||||||
|
auto obj = unwrap_shared_ptr<Pet>(in[0], "ptr_Pet");
|
||||||
|
std::shared_ptr<Pet::Kind> type = unwrap_enum<Pet::Kind>(in[1]);
|
||||||
|
obj->type = *type;
|
||||||
|
}
|
||||||
|
|
||||||
|
void gtsamMCU_collectorInsertAndMakeBase_7(int nargout, mxArray *out[], int nargin, const mxArray *in[])
|
||||||
|
{
|
||||||
|
mexAtExit(&_deleteAllObjects);
|
||||||
|
typedef std::shared_ptr<gtsam::MCU> Shared;
|
||||||
|
|
||||||
|
Shared *self = *reinterpret_cast<Shared**> (mxGetData(in[0]));
|
||||||
|
collector_gtsamMCU.insert(self);
|
||||||
|
}
|
||||||
|
|
||||||
|
void gtsamMCU_constructor_8(int nargout, mxArray *out[], int nargin, const mxArray *in[])
|
||||||
|
{
|
||||||
|
mexAtExit(&_deleteAllObjects);
|
||||||
|
typedef std::shared_ptr<gtsam::MCU> Shared;
|
||||||
|
|
||||||
|
Shared *self = new Shared(new gtsam::MCU());
|
||||||
|
collector_gtsamMCU.insert(self);
|
||||||
|
out[0] = mxCreateNumericMatrix(1, 1, mxUINT32OR64_CLASS, mxREAL);
|
||||||
|
*reinterpret_cast<Shared**> (mxGetData(out[0])) = self;
|
||||||
|
}
|
||||||
|
|
||||||
|
void gtsamMCU_deconstructor_9(int nargout, mxArray *out[], int nargin, const mxArray *in[])
|
||||||
|
{
|
||||||
|
typedef std::shared_ptr<gtsam::MCU> Shared;
|
||||||
|
checkArguments("delete_gtsamMCU",nargout,nargin,1);
|
||||||
|
Shared *self = *reinterpret_cast<Shared**>(mxGetData(in[0]));
|
||||||
|
Collector_gtsamMCU::iterator item;
|
||||||
|
item = collector_gtsamMCU.find(self);
|
||||||
|
if(item != collector_gtsamMCU.end()) {
|
||||||
|
collector_gtsamMCU.erase(item);
|
||||||
|
}
|
||||||
|
delete self;
|
||||||
|
}
|
||||||
|
|
||||||
|
void gtsamOptimizerGaussNewtonParams_collectorInsertAndMakeBase_10(int nargout, mxArray *out[], int nargin, const mxArray *in[])
|
||||||
|
{
|
||||||
|
mexAtExit(&_deleteAllObjects);
|
||||||
|
typedef std::shared_ptr<gtsam::Optimizer<gtsam::GaussNewtonParams>> Shared;
|
||||||
|
|
||||||
|
Shared *self = *reinterpret_cast<Shared**> (mxGetData(in[0]));
|
||||||
|
collector_gtsamOptimizerGaussNewtonParams.insert(self);
|
||||||
|
}
|
||||||
|
|
||||||
|
void gtsamOptimizerGaussNewtonParams_deconstructor_11(int nargout, mxArray *out[], int nargin, const mxArray *in[])
|
||||||
|
{
|
||||||
|
typedef std::shared_ptr<gtsam::Optimizer<gtsam::GaussNewtonParams>> Shared;
|
||||||
|
checkArguments("delete_gtsamOptimizerGaussNewtonParams",nargout,nargin,1);
|
||||||
|
Shared *self = *reinterpret_cast<Shared**>(mxGetData(in[0]));
|
||||||
|
Collector_gtsamOptimizerGaussNewtonParams::iterator item;
|
||||||
|
item = collector_gtsamOptimizerGaussNewtonParams.find(self);
|
||||||
|
if(item != collector_gtsamOptimizerGaussNewtonParams.end()) {
|
||||||
|
collector_gtsamOptimizerGaussNewtonParams.erase(item);
|
||||||
|
}
|
||||||
|
delete self;
|
||||||
|
}
|
||||||
|
|
||||||
|
void gtsamOptimizerGaussNewtonParams_setVerbosity_12(int nargout, mxArray *out[], int nargin, const mxArray *in[])
|
||||||
|
{
|
||||||
|
checkArguments("setVerbosity",nargout,nargin-1,1);
|
||||||
|
auto obj = unwrap_shared_ptr<gtsam::Optimizer<gtsam::GaussNewtonParams>>(in[0], "ptr_gtsamOptimizerGaussNewtonParams");
|
||||||
|
std::shared_ptr<Optimizer<gtsam::GaussNewtonParams>::Verbosity> value = unwrap_enum<Optimizer<gtsam::GaussNewtonParams>::Verbosity>(in[1]);
|
||||||
|
obj->setVerbosity(*value);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void mexFunction(int nargout, mxArray *out[], int nargin, const mxArray *in[])
|
||||||
|
{
|
||||||
|
mstream mout;
|
||||||
|
std::streambuf *outbuf = std::cout.rdbuf(&mout);
|
||||||
|
|
||||||
|
_enum_RTTIRegister();
|
||||||
|
|
||||||
|
int id = unwrap<int>(in[0]);
|
||||||
|
|
||||||
|
try {
|
||||||
|
switch(id) {
|
||||||
|
case 0:
|
||||||
|
Pet_collectorInsertAndMakeBase_0(nargout, out, nargin-1, in+1);
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
Pet_constructor_1(nargout, out, nargin-1, in+1);
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
Pet_deconstructor_2(nargout, out, nargin-1, in+1);
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
Pet_get_name_3(nargout, out, nargin-1, in+1);
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
Pet_set_name_4(nargout, out, nargin-1, in+1);
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
Pet_get_type_5(nargout, out, nargin-1, in+1);
|
||||||
|
break;
|
||||||
|
case 6:
|
||||||
|
Pet_set_type_6(nargout, out, nargin-1, in+1);
|
||||||
|
break;
|
||||||
|
case 7:
|
||||||
|
gtsamMCU_collectorInsertAndMakeBase_7(nargout, out, nargin-1, in+1);
|
||||||
|
break;
|
||||||
|
case 8:
|
||||||
|
gtsamMCU_constructor_8(nargout, out, nargin-1, in+1);
|
||||||
|
break;
|
||||||
|
case 9:
|
||||||
|
gtsamMCU_deconstructor_9(nargout, out, nargin-1, in+1);
|
||||||
|
break;
|
||||||
|
case 10:
|
||||||
|
gtsamOptimizerGaussNewtonParams_collectorInsertAndMakeBase_10(nargout, out, nargin-1, in+1);
|
||||||
|
break;
|
||||||
|
case 11:
|
||||||
|
gtsamOptimizerGaussNewtonParams_deconstructor_11(nargout, out, nargin-1, in+1);
|
||||||
|
break;
|
||||||
|
case 12:
|
||||||
|
gtsamOptimizerGaussNewtonParams_setVerbosity_12(nargout, out, nargin-1, in+1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} catch(const std::exception& e) {
|
||||||
|
mexErrMsgTxt(("Exception from gtsam:\n" + std::string(e.what()) + "\n").c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
std::cout.rdbuf(outbuf);
|
||||||
|
}
|
|
@ -204,14 +204,14 @@ void gtsamGeneralSFMFactorCal3Bundler_get_verbosity_11(int nargout, mxArray *out
|
||||||
{
|
{
|
||||||
checkArguments("verbosity",nargout,nargin-1,0);
|
checkArguments("verbosity",nargout,nargin-1,0);
|
||||||
auto obj = unwrap_shared_ptr<gtsam::GeneralSFMFactor<gtsam::PinholeCamera<gtsam::Cal3Bundler>, gtsam::Point3>>(in[0], "ptr_gtsamGeneralSFMFactorCal3Bundler");
|
auto obj = unwrap_shared_ptr<gtsam::GeneralSFMFactor<gtsam::PinholeCamera<gtsam::Cal3Bundler>, gtsam::Point3>>(in[0], "ptr_gtsamGeneralSFMFactorCal3Bundler");
|
||||||
out[0] = wrap_shared_ptr(std::make_shared<gtsam::GeneralSFMFactor<gtsam::PinholeCamera<gtsam::Cal3Bundler>, gtsam::Point3>::Verbosity>(obj->verbosity),"gtsam.GeneralSFMFactor<gtsam::PinholeCamera<gtsam::Cal3Bundler>, gtsam::Point3>.Verbosity", false);
|
out[0] = wrap_enum(obj->verbosity,"gtsam.GeneralSFMFactorCal3Bundler.Verbosity");
|
||||||
}
|
}
|
||||||
|
|
||||||
void gtsamGeneralSFMFactorCal3Bundler_set_verbosity_12(int nargout, mxArray *out[], int nargin, const mxArray *in[])
|
void gtsamGeneralSFMFactorCal3Bundler_set_verbosity_12(int nargout, mxArray *out[], int nargin, const mxArray *in[])
|
||||||
{
|
{
|
||||||
checkArguments("verbosity",nargout,nargin-1,1);
|
checkArguments("verbosity",nargout,nargin-1,1);
|
||||||
auto obj = unwrap_shared_ptr<gtsam::GeneralSFMFactor<gtsam::PinholeCamera<gtsam::Cal3Bundler>, gtsam::Point3>>(in[0], "ptr_gtsamGeneralSFMFactorCal3Bundler");
|
auto obj = unwrap_shared_ptr<gtsam::GeneralSFMFactor<gtsam::PinholeCamera<gtsam::Cal3Bundler>, gtsam::Point3>>(in[0], "ptr_gtsamGeneralSFMFactorCal3Bundler");
|
||||||
std::shared_ptr<gtsam::GeneralSFMFactor<gtsam::PinholeCamera<gtsam::Cal3Bundler>, gtsam::Point3>::Verbosity> verbosity = unwrap_shared_ptr< gtsam::GeneralSFMFactor<gtsam::PinholeCamera<gtsam::Cal3Bundler>, gtsam::Point3>::Verbosity >(in[1], "ptr_gtsamGeneralSFMFactor<gtsam::PinholeCamera<gtsam::Cal3Bundler>, gtsam::Point3>Verbosity");
|
std::shared_ptr<gtsam::GeneralSFMFactor<gtsam::PinholeCamera<gtsam::Cal3Bundler>, gtsam::Point3>::Verbosity> verbosity = unwrap_enum<gtsam::GeneralSFMFactor<gtsam::PinholeCamera<gtsam::Cal3Bundler>, gtsam::Point3>::Verbosity>(in[1]);
|
||||||
obj->verbosity = *verbosity;
|
obj->verbosity = *verbosity;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -141,6 +141,32 @@ class TestWrap(unittest.TestCase):
|
||||||
actual = osp.join(self.MATLAB_ACTUAL_DIR, file)
|
actual = osp.join(self.MATLAB_ACTUAL_DIR, file)
|
||||||
self.compare_and_diff(file, actual)
|
self.compare_and_diff(file, actual)
|
||||||
|
|
||||||
|
def test_enum(self):
|
||||||
|
"""Test interface file with only enum info."""
|
||||||
|
file = osp.join(self.INTERFACE_DIR, 'enum.i')
|
||||||
|
|
||||||
|
wrapper = MatlabWrapper(
|
||||||
|
module_name='enum',
|
||||||
|
top_module_namespace=['gtsam'],
|
||||||
|
ignore_classes=[''],
|
||||||
|
)
|
||||||
|
|
||||||
|
wrapper.wrap([file], path=self.MATLAB_ACTUAL_DIR)
|
||||||
|
|
||||||
|
files = [
|
||||||
|
'enum_wrapper.cpp',
|
||||||
|
'Color.m',
|
||||||
|
'+Pet/Kind.m',
|
||||||
|
'+gtsam/VerbosityLM.m',
|
||||||
|
'+gtsam/+MCU/Avengers.m',
|
||||||
|
'+gtsam/+MCU/GotG.m',
|
||||||
|
'+gtsam/+OptimizerGaussNewtonParams/Verbosity.m',
|
||||||
|
]
|
||||||
|
|
||||||
|
for file in files:
|
||||||
|
actual = osp.join(self.MATLAB_ACTUAL_DIR, file)
|
||||||
|
self.compare_and_diff(file, actual)
|
||||||
|
|
||||||
def test_templates(self):
|
def test_templates(self):
|
||||||
"""Test interface file with template info."""
|
"""Test interface file with template info."""
|
||||||
file = osp.join(self.INTERFACE_DIR, 'templates.i')
|
file = osp.join(self.INTERFACE_DIR, 'templates.i')
|
||||||
|
|
Loading…
Reference in New Issue