bindings: backport generator from OpenCV 4.x
- better handling of enum arguments - less merge conflicts
This commit is contained in:
committed by
Alexander Alekhin
parent
d034ef6f27
commit
f5b58e5fc9
+155
-68
@@ -10,19 +10,23 @@ if sys.version_info[0] >= 3:
|
||||
else:
|
||||
from cStringIO import StringIO
|
||||
|
||||
forbidden_arg_types = ["void*"]
|
||||
|
||||
ignored_arg_types = ["RNG*"]
|
||||
|
||||
pass_by_val_types = ["Point*", "Point2f*", "Rect*", "String*", "double*", "float*", "int*"]
|
||||
|
||||
gen_template_check_self = Template(""" $cname* _self_ = NULL;
|
||||
if(PyObject_TypeCheck(self, &pyopencv_${name}_Type))
|
||||
_self_ = ${amp}((pyopencv_${name}_t*)self)->v${get};
|
||||
if (_self_ == NULL)
|
||||
if (!_self_)
|
||||
return failmsgp("Incorrect type of self (must be '${name}' or its derivative)");
|
||||
""")
|
||||
|
||||
gen_template_check_self_algo = Template(""" $cname* _self_ = NULL;
|
||||
if(PyObject_TypeCheck(self, &pyopencv_${name}_Type))
|
||||
_self_ = dynamic_cast<$cname*>(${amp}((pyopencv_${name}_t*)self)->v.get());
|
||||
if (_self_ == NULL)
|
||||
if (!_self_)
|
||||
return failmsgp("Incorrect type of self (must be '${name}' or its derivative)");
|
||||
""")
|
||||
|
||||
@@ -68,27 +72,40 @@ static void pyopencv_${name}_dealloc(PyObject* self)
|
||||
PyObject_Del(self);
|
||||
}
|
||||
|
||||
template<> PyObject* pyopencv_from(const ${cname}& r)
|
||||
template<>
|
||||
struct PyOpenCV_Converter< ${cname} >
|
||||
{
|
||||
pyopencv_${name}_t *m = PyObject_NEW(pyopencv_${name}_t, &pyopencv_${name}_Type);
|
||||
new (&m->v) ${cname}(r); //Copy constructor
|
||||
return (PyObject*)m;
|
||||
}
|
||||
|
||||
template<> bool pyopencv_to(PyObject* src, ${cname}& dst, const char* name)
|
||||
{
|
||||
if( src == NULL || src == Py_None )
|
||||
return true;
|
||||
if(!PyObject_TypeCheck(src, &pyopencv_${name}_Type))
|
||||
static PyObject* from(const ${cname}& r)
|
||||
{
|
||||
pyopencv_${name}_t *m = PyObject_NEW(pyopencv_${name}_t, &pyopencv_${name}_Type);
|
||||
new (&m->v) ${cname}(r); //Copy constructor
|
||||
return (PyObject*)m;
|
||||
}
|
||||
|
||||
static bool to(PyObject* src, ${cname}& dst, const char* name)
|
||||
{
|
||||
if(!src || src == Py_None)
|
||||
return true;
|
||||
if(PyObject_TypeCheck(src, &pyopencv_${name}_Type))
|
||||
{
|
||||
dst = ((pyopencv_${name}_t*)src)->v;
|
||||
return true;
|
||||
}
|
||||
failmsg("Expected ${cname} for argument '%%s'", name);
|
||||
return false;
|
||||
}
|
||||
dst = ((pyopencv_${name}_t*)src)->v;
|
||||
return true;
|
||||
}
|
||||
};
|
||||
""" % head_init_str)
|
||||
|
||||
gen_template_mappable = Template("""
|
||||
{
|
||||
${mappable} _src;
|
||||
if (pyopencv_to(src, _src, name))
|
||||
{
|
||||
return cv_mappable_to(_src, dst);
|
||||
}
|
||||
}
|
||||
""")
|
||||
|
||||
gen_template_type_decl = Template("""
|
||||
struct pyopencv_${name}_t
|
||||
@@ -110,26 +127,31 @@ static void pyopencv_${name}_dealloc(PyObject* self)
|
||||
PyObject_Del(self);
|
||||
}
|
||||
|
||||
template<> PyObject* pyopencv_from(const Ptr<${cname}>& r)
|
||||
template<>
|
||||
struct PyOpenCV_Converter< Ptr<${cname}> >
|
||||
{
|
||||
pyopencv_${name}_t *m = PyObject_NEW(pyopencv_${name}_t, &pyopencv_${name}_Type);
|
||||
new (&(m->v)) Ptr<$cname1>(); // init Ptr with placement new
|
||||
m->v = r;
|
||||
return (PyObject*)m;
|
||||
}
|
||||
|
||||
template<> bool pyopencv_to(PyObject* src, Ptr<${cname}>& dst, const char* name)
|
||||
{
|
||||
if( src == NULL || src == Py_None )
|
||||
return true;
|
||||
if(!PyObject_TypeCheck(src, &pyopencv_${name}_Type))
|
||||
static PyObject* from(const Ptr<${cname}>& r)
|
||||
{
|
||||
pyopencv_${name}_t *m = PyObject_NEW(pyopencv_${name}_t, &pyopencv_${name}_Type);
|
||||
new (&(m->v)) Ptr<$cname1>(); // init Ptr with placement new
|
||||
m->v = r;
|
||||
return (PyObject*)m;
|
||||
}
|
||||
|
||||
static bool to(PyObject* src, Ptr<${cname}>& dst, const char* name)
|
||||
{
|
||||
if(!src || src == Py_None)
|
||||
return true;
|
||||
if(PyObject_TypeCheck(src, &pyopencv_${name}_Type))
|
||||
{
|
||||
dst = ((pyopencv_${name}_t*)src)->v.dynamicCast<${cname}>();
|
||||
return true;
|
||||
}
|
||||
${mappable_code}
|
||||
failmsg("Expected ${cname} for argument '%%s'", name);
|
||||
return false;
|
||||
}
|
||||
dst = ((pyopencv_${name}_t*)src)->v.dynamicCast<${cname}>();
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
""" % head_init_str)
|
||||
|
||||
@@ -192,7 +214,7 @@ gen_template_get_prop_algo = Template("""
|
||||
static PyObject* pyopencv_${name}_get_${member}(pyopencv_${name}_t* p, void *closure)
|
||||
{
|
||||
$cname* _self_ = dynamic_cast<$cname*>(p->v.get());
|
||||
if (_self_ == NULL)
|
||||
if (!_self_)
|
||||
return failmsgp("Incorrect type of object (must be '${name}' or its derivative)");
|
||||
return pyopencv_from(_self_${access}${member});
|
||||
}
|
||||
@@ -201,7 +223,7 @@ static PyObject* pyopencv_${name}_get_${member}(pyopencv_${name}_t* p, void *clo
|
||||
gen_template_set_prop = Template("""
|
||||
static int pyopencv_${name}_set_${member}(pyopencv_${name}_t* p, PyObject *value, void *closure)
|
||||
{
|
||||
if (value == NULL)
|
||||
if (!value)
|
||||
{
|
||||
PyErr_SetString(PyExc_TypeError, "Cannot delete the ${member} attribute");
|
||||
return -1;
|
||||
@@ -213,13 +235,13 @@ static int pyopencv_${name}_set_${member}(pyopencv_${name}_t* p, PyObject *value
|
||||
gen_template_set_prop_algo = Template("""
|
||||
static int pyopencv_${name}_set_${member}(pyopencv_${name}_t* p, PyObject *value, void *closure)
|
||||
{
|
||||
if (value == NULL)
|
||||
if (!value)
|
||||
{
|
||||
PyErr_SetString(PyExc_TypeError, "Cannot delete the ${member} attribute");
|
||||
return -1;
|
||||
}
|
||||
$cname* _self_ = dynamic_cast<$cname*>(p->v.get());
|
||||
if (_self_ == NULL)
|
||||
if (!_self_)
|
||||
{
|
||||
failmsgp("Incorrect type of object (must be '${name}' or its derivative)");
|
||||
return -1;
|
||||
@@ -265,6 +287,7 @@ class ClassInfo(object):
|
||||
self.isalgorithm = False
|
||||
self.methods = {}
|
||||
self.props = []
|
||||
self.mappables = []
|
||||
self.consts = {}
|
||||
self.base = None
|
||||
self.constructor = None
|
||||
@@ -402,7 +425,7 @@ class ArgInfo(object):
|
||||
self.py_outputarg = False
|
||||
|
||||
def isbig(self):
|
||||
return self.tp == "Mat" or self.tp == "vector_Mat"\
|
||||
return self.tp == "Mat" or self.tp == "vector_Mat" or self.tp == "cuda::GpuMat"\
|
||||
or self.tp == "UMat" or self.tp == "vector_UMat" # or self.tp.startswith("vector")
|
||||
|
||||
def crepr(self):
|
||||
@@ -410,10 +433,11 @@ class ArgInfo(object):
|
||||
|
||||
|
||||
class FuncVariant(object):
|
||||
def __init__(self, classname, name, decl, isconstructor):
|
||||
def __init__(self, classname, name, decl, isconstructor, isphantom=False):
|
||||
self.classname = classname
|
||||
self.name = self.wname = name
|
||||
self.isconstructor = isconstructor
|
||||
self.isphantom = isphantom
|
||||
|
||||
self.docstring = decl[5]
|
||||
|
||||
@@ -461,6 +485,7 @@ class FuncVariant(object):
|
||||
argno += 1
|
||||
if a.name in self.array_counters:
|
||||
continue
|
||||
assert not a.tp in forbidden_arg_types, 'Forbidden type "{}" for argument "{}" in "{}" ("{}")'.format(a.tp, a.name, self.name, self.classname)
|
||||
if a.tp in ignored_arg_types:
|
||||
continue
|
||||
if a.returnarg:
|
||||
@@ -520,17 +545,17 @@ class FuncVariant(object):
|
||||
|
||||
|
||||
class FuncInfo(object):
|
||||
def __init__(self, classname, name, cname, isconstructor, namespace, isclassmethod):
|
||||
def __init__(self, classname, name, cname, isconstructor, namespace, is_static):
|
||||
self.classname = classname
|
||||
self.name = name
|
||||
self.cname = cname
|
||||
self.isconstructor = isconstructor
|
||||
self.namespace = namespace
|
||||
self.isclassmethod = isclassmethod
|
||||
self.is_static = is_static
|
||||
self.variants = []
|
||||
|
||||
def add_variant(self, decl):
|
||||
self.variants.append(FuncVariant(self.classname, self.name, decl, self.isconstructor))
|
||||
def add_variant(self, decl, isphantom=False):
|
||||
self.variants.append(FuncVariant(self.classname, self.name, decl, self.isconstructor, isphantom))
|
||||
|
||||
def get_wrapper_name(self):
|
||||
name = self.name
|
||||
@@ -541,8 +566,8 @@ class FuncInfo(object):
|
||||
else:
|
||||
classname = ""
|
||||
|
||||
if self.isclassmethod:
|
||||
name += "_cls"
|
||||
if self.is_static:
|
||||
name += "_static"
|
||||
|
||||
return "pyopencv_" + self.namespace.replace('.','_') + '_' + classname + name
|
||||
|
||||
@@ -601,7 +626,7 @@ class FuncInfo(object):
|
||||
|
||||
return Template(' {"$py_funcname", CV_PY_FN_WITH_KW_($wrap_funcname, $flags), "$py_docstring"},\n'
|
||||
).substitute(py_funcname = self.variants[0].wname, wrap_funcname=self.get_wrapper_name(),
|
||||
flags = 'METH_CLASS' if self.isclassmethod else '0', py_docstring = full_docstring)
|
||||
flags = 'METH_STATIC' if self.is_static else '0', py_docstring = full_docstring)
|
||||
|
||||
def gen_code(self, codegen):
|
||||
all_classes = codegen.classes
|
||||
@@ -618,7 +643,7 @@ class FuncInfo(object):
|
||||
selfinfo = all_classes[self.classname]
|
||||
if not self.isconstructor:
|
||||
amp = "&" if selfinfo.issimple else ""
|
||||
if self.isclassmethod:
|
||||
if self.is_static:
|
||||
pass
|
||||
elif selfinfo.isalgorithm:
|
||||
code += gen_template_check_self_algo.substitute(name=selfinfo.name, cname=selfinfo.cname, amp=amp)
|
||||
@@ -638,6 +663,9 @@ class FuncInfo(object):
|
||||
all_cargs = []
|
||||
parse_arglist = []
|
||||
|
||||
if v.isphantom and ismethod and not self.is_static:
|
||||
code_args += "_self_"
|
||||
|
||||
# declare all the C function arguments,
|
||||
# add necessary conversions from Python objects to code_cvt_list,
|
||||
# form the function/method call,
|
||||
@@ -646,7 +674,7 @@ class FuncInfo(object):
|
||||
if a.tp in ignored_arg_types:
|
||||
defval = a.defval
|
||||
if not defval and a.tp.endswith("*"):
|
||||
defval = 0
|
||||
defval = "0"
|
||||
assert defval
|
||||
if not code_args.endswith("("):
|
||||
code_args += ", "
|
||||
@@ -656,15 +684,15 @@ class FuncInfo(object):
|
||||
tp1 = tp = a.tp
|
||||
amp = ""
|
||||
defval0 = ""
|
||||
if tp.endswith("*"):
|
||||
if tp in pass_by_val_types:
|
||||
tp = tp1 = tp[:-1]
|
||||
amp = "&"
|
||||
if tp.endswith("*"):
|
||||
defval0 = "0"
|
||||
tp1 = tp.replace("*", "_ptr")
|
||||
if tp1.endswith("*"):
|
||||
print("Error: type with star: a.tp=%s, tp=%s, tp1=%s" % (a.tp, tp, tp1))
|
||||
sys.exit(-1)
|
||||
tp_candidates = [a.tp, normalize_class_name(self.namespace + "." + a.tp)]
|
||||
if any(tp in codegen.enums.keys() for tp in tp_candidates):
|
||||
defval0 = "static_cast<%s>(%d)" % (a.tp, 0)
|
||||
|
||||
amapping = simple_argtype_mapping.get(tp, (tp, "O", defval0))
|
||||
parse_name = a.name
|
||||
@@ -686,6 +714,9 @@ class FuncInfo(object):
|
||||
if "UMat" in tp:
|
||||
if "Mat" in defval and "UMat" not in defval:
|
||||
defval = defval.replace("Mat", "UMat")
|
||||
if "cuda::GpuMat" in tp:
|
||||
if "Mat" in defval and "GpuMat" not in defval:
|
||||
defval = defval.replace("Mat", "cuda::GpuMat")
|
||||
# "tp arg = tp();" is equivalent to "tp arg;" in the case of complex types
|
||||
if defval == tp + "()" and amapping[1] == "O":
|
||||
defval = ""
|
||||
@@ -712,13 +743,15 @@ class FuncInfo(object):
|
||||
|
||||
code_prelude = templ_prelude.substitute(name=selfinfo.name, cname=selfinfo.cname)
|
||||
code_fcall = templ.substitute(name=selfinfo.name, cname=selfinfo.cname, args=code_args)
|
||||
if v.isphantom:
|
||||
code_fcall = code_fcall.replace("new " + selfinfo.cname, self.cname.replace("::", "_"))
|
||||
else:
|
||||
code_prelude = ""
|
||||
code_fcall = ""
|
||||
if v.rettype:
|
||||
code_decl += " " + v.rettype + " retval;\n"
|
||||
code_fcall += "retval = "
|
||||
if ismethod and not self.isclassmethod:
|
||||
if not v.isphantom and ismethod and not self.is_static:
|
||||
code_fcall += "_self_->" + self.cname
|
||||
else:
|
||||
code_fcall += self.cname
|
||||
@@ -754,7 +787,7 @@ class FuncInfo(object):
|
||||
parse_arglist = ", ".join(["&" + all_cargs[argno][1] for aname, argno in v.py_arglist]),
|
||||
code_cvt = " &&\n ".join(code_cvt_list))
|
||||
else:
|
||||
code_parse = "if(PyObject_Size(args) == 0 && (kw == NULL || PyObject_Size(kw) == 0))"
|
||||
code_parse = "if(PyObject_Size(args) == 0 && (!kw || PyObject_Size(kw) == 0))"
|
||||
|
||||
if len(v.py_outlist) == 0:
|
||||
code_ret = "Py_RETURN_NONE"
|
||||
@@ -799,7 +832,7 @@ class FuncInfo(object):
|
||||
#if dump: pprint(vars(classinfo))
|
||||
if self.isconstructor:
|
||||
py_name = 'cv.' + classinfo.wname
|
||||
elif self.isclassmethod:
|
||||
elif self.is_static:
|
||||
py_name = '.'.join([self.namespace, classinfo.sname + '_' + self.variants[0].wname])
|
||||
else:
|
||||
cname = classinfo.cname + '::' + cname
|
||||
@@ -833,7 +866,9 @@ class PythonWrapperGenerator(object):
|
||||
self.classes = {}
|
||||
self.namespaces = {}
|
||||
self.consts = {}
|
||||
self.enums = {}
|
||||
self.code_include = StringIO()
|
||||
self.code_enums = StringIO()
|
||||
self.code_types = StringIO()
|
||||
self.code_funcs = StringIO()
|
||||
self.code_type_reg = StringIO()
|
||||
@@ -890,6 +925,18 @@ class PythonWrapperGenerator(object):
|
||||
py_signatures.append(dict(name=py_name, value=value))
|
||||
#print(cname + ' => ' + str(py_name) + ' (value=' + value + ')')
|
||||
|
||||
def add_enum(self, name, decl):
|
||||
wname = normalize_class_name(name)
|
||||
if wname.endswith("<unnamed>"):
|
||||
wname = None
|
||||
else:
|
||||
self.enums[wname] = name
|
||||
const_decls = decl[3]
|
||||
|
||||
for decl in const_decls:
|
||||
name = decl[0]
|
||||
self.add_const(name.replace("const ", "").strip(), decl)
|
||||
|
||||
def add_func(self, decl):
|
||||
namespace, classes, barename = self.split_decl_name(decl[0])
|
||||
cname = "::".join(namespace+classes+[barename])
|
||||
@@ -902,35 +949,46 @@ class PythonWrapperGenerator(object):
|
||||
namespace = '.'.join(namespace)
|
||||
|
||||
isconstructor = name == bareclassname
|
||||
isclassmethod = False
|
||||
is_static = False
|
||||
isphantom = False
|
||||
mappable = None
|
||||
for m in decl[2]:
|
||||
if m == "/S":
|
||||
isclassmethod = True
|
||||
is_static = True
|
||||
elif m == "/phantom":
|
||||
isphantom = True
|
||||
cname = cname.replace("::", "_")
|
||||
elif m.startswith("="):
|
||||
name = m[1:]
|
||||
elif m.startswith("/mappable="):
|
||||
mappable = m[10:]
|
||||
self.classes[classname].mappables.append(mappable)
|
||||
return
|
||||
|
||||
if isconstructor:
|
||||
name = "_".join(classes[:-1]+[name])
|
||||
|
||||
if isclassmethod:
|
||||
if is_static:
|
||||
# Add it as a method to the class
|
||||
func_map = self.classes[classname].methods
|
||||
func = func_map.setdefault(name, FuncInfo(classname, name, cname, isconstructor, namespace, isclassmethod))
|
||||
func.add_variant(decl)
|
||||
func = func_map.setdefault(name, FuncInfo(classname, name, cname, isconstructor, namespace, is_static))
|
||||
func.add_variant(decl, isphantom)
|
||||
|
||||
# Add it as global function
|
||||
g_name = "_".join(classes+[name])
|
||||
func_map = self.namespaces.setdefault(namespace, Namespace()).funcs
|
||||
func = func_map.setdefault(g_name, FuncInfo("", g_name, cname, isconstructor, namespace, False))
|
||||
func.add_variant(decl)
|
||||
func.add_variant(decl, isphantom)
|
||||
else:
|
||||
if classname and not isconstructor:
|
||||
cname = barename
|
||||
if not isphantom:
|
||||
cname = barename
|
||||
func_map = self.classes[classname].methods
|
||||
else:
|
||||
func_map = self.namespaces.setdefault(namespace, Namespace()).funcs
|
||||
|
||||
func = func_map.setdefault(name, FuncInfo(classname, name, cname, isconstructor, namespace, isclassmethod))
|
||||
func.add_variant(decl)
|
||||
func = func_map.setdefault(name, FuncInfo(classname, name, cname, isconstructor, namespace, is_static))
|
||||
func.add_variant(decl, isphantom)
|
||||
|
||||
if classname and isconstructor:
|
||||
self.classes[classname].constructor = func
|
||||
@@ -949,10 +1007,10 @@ class PythonWrapperGenerator(object):
|
||||
|
||||
self.code_ns_reg.write('static ConstDef consts_%s[] = {\n'%wname)
|
||||
for name, cname in sorted(ns.consts.items()):
|
||||
self.code_ns_reg.write(' {"%s", %s},\n'%(name, cname))
|
||||
self.code_ns_reg.write(' {"%s", static_cast<long>(%s)},\n'%(name, cname))
|
||||
compat_name = re.sub(r"([a-z])([A-Z])", r"\1_\2", name).upper()
|
||||
if name != compat_name:
|
||||
self.code_ns_reg.write(' {"%s", %s},\n'%(compat_name, cname))
|
||||
self.code_ns_reg.write(' {"%s", static_cast<long>(%s)},\n'%(compat_name, cname))
|
||||
self.code_ns_reg.write(' {NULL, 0}\n};\n\n')
|
||||
|
||||
def gen_namespaces_reg(self):
|
||||
@@ -963,6 +1021,21 @@ class PythonWrapperGenerator(object):
|
||||
self.code_ns_reg.write(' init_submodule(root, MODULESTR"%s", methods_%s, consts_%s);\n' % (ns_name[2:], wname, wname))
|
||||
self.code_ns_reg.write('};\n')
|
||||
|
||||
def gen_enum_reg(self, enum_name):
|
||||
name_seg = enum_name.split(".")
|
||||
is_enum_class = False
|
||||
if len(name_seg) >= 2 and name_seg[-1] == name_seg[-2]:
|
||||
enum_name = ".".join(name_seg[:-1])
|
||||
is_enum_class = True
|
||||
|
||||
wname = normalize_class_name(enum_name)
|
||||
cname = enum_name.replace(".", "::")
|
||||
|
||||
code = ""
|
||||
if re.sub(r"^cv\.", "", enum_name) != wname:
|
||||
code += "typedef enum {0} {1};\n".format(cname, wname)
|
||||
code += "CV_PY_FROM_ENUM({0});\nCV_PY_TO_ENUM({0});\n\n".format(wname)
|
||||
self.code_enums.write(code)
|
||||
|
||||
def save(self, path, name, buf):
|
||||
with open(path + "/" + name, "wt") as f:
|
||||
@@ -975,14 +1048,15 @@ class PythonWrapperGenerator(object):
|
||||
|
||||
def gen(self, srcfiles, output_path):
|
||||
self.clear()
|
||||
self.parser = hdr_parser.CppHeaderParser(generate_umat_decls=True)
|
||||
self.parser = hdr_parser.CppHeaderParser(generate_umat_decls=True, generate_gpumat_decls=False)
|
||||
|
||||
# step 1: scan the headers and build more descriptive maps of classes, consts, functions
|
||||
for hdr in srcfiles:
|
||||
decls = self.parser.parse(hdr)
|
||||
if len(decls) == 0:
|
||||
continue
|
||||
self.code_include.write( '#include "{0}"\n'.format(hdr[hdr.rindex('opencv2/'):]) )
|
||||
if hdr.find('opencv2/') >= 0: #Avoid including the shadow files
|
||||
self.code_include.write( '#include "{0}"\n'.format(hdr[hdr.rindex('opencv2/'):]) )
|
||||
for decl in decls:
|
||||
name = decl[0]
|
||||
if name.startswith("struct") or name.startswith("class"):
|
||||
@@ -994,6 +1068,9 @@ class PythonWrapperGenerator(object):
|
||||
elif name.startswith("const"):
|
||||
# constant
|
||||
self.add_const(name.replace("const ", "").strip(), decl)
|
||||
elif name.startswith("enum"):
|
||||
# enum
|
||||
self.add_enum(name.rsplit(" ", 1)[1], decl)
|
||||
else:
|
||||
# function
|
||||
self.add_func(decl)
|
||||
@@ -1043,8 +1120,11 @@ class PythonWrapperGenerator(object):
|
||||
templ = gen_template_simple_type_decl
|
||||
else:
|
||||
templ = gen_template_type_decl
|
||||
mappable_code = "\n".join([
|
||||
gen_template_mappable.substitute(cname=classinfo.cname, mappable=mappable)
|
||||
for mappable in classinfo.mappables])
|
||||
self.code_types.write(templ.substitute(name=name, wname=classinfo.wname, cname=classinfo.cname, sname=classinfo.sname,
|
||||
cname1=("cv::Algorithm" if classinfo.isalgorithm else classinfo.cname)))
|
||||
cname1=("cv::Algorithm" if classinfo.isalgorithm else classinfo.cname), mappable_code=mappable_code))
|
||||
|
||||
# register classes in the same order as they have been declared.
|
||||
# this way, base classes will be registered in Python before their derivatives.
|
||||
@@ -1070,7 +1150,13 @@ class PythonWrapperGenerator(object):
|
||||
self.gen_namespace(ns_name)
|
||||
self.gen_namespaces_reg()
|
||||
|
||||
# step 4: generate the code for constants
|
||||
# step 4: generate the code for enum types
|
||||
enumlist = list(self.enums.values())
|
||||
enumlist.sort()
|
||||
for name in enumlist:
|
||||
self.gen_enum_reg(name)
|
||||
|
||||
# step 5: generate the code for constants
|
||||
constlist = list(self.consts.items())
|
||||
constlist.sort()
|
||||
for name, constinfo in constlist:
|
||||
@@ -1079,6 +1165,7 @@ class PythonWrapperGenerator(object):
|
||||
# That's it. Now save all the files
|
||||
self.save(output_path, "pyopencv_generated_include.h", self.code_include)
|
||||
self.save(output_path, "pyopencv_generated_funcs.h", self.code_funcs)
|
||||
self.save(output_path, "pyopencv_generated_enums.h", self.code_enums)
|
||||
self.save(output_path, "pyopencv_generated_types.h", self.code_types)
|
||||
self.save(output_path, "pyopencv_generated_type_reg.h", self.code_type_reg)
|
||||
self.save(output_path, "pyopencv_generated_ns_reg.h", self.code_ns_reg)
|
||||
|
||||
Reference in New Issue
Block a user