Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Python: add binding for missing ParamValue constructors #2417

Merged
merged 1 commit into from
Dec 3, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
17 changes: 7 additions & 10 deletions src/python/py_oiio.h
Original file line number Diff line number Diff line change
Expand Up @@ -290,9 +290,9 @@ C_to_tuple<TypeDesc>(cspan<TypeDesc> vals)
// Python tuple.
template<typename T>
inline py::object
C_to_val_or_tuple(const T* vals, TypeDesc type)
C_to_val_or_tuple(const T* vals, TypeDesc type, int nvalues = 1)
{
size_t n = type.numelements() * type.aggregate;
size_t n = type.numelements() * type.aggregate * nvalues;
if (n == 1 && !type.arraylen)
return typename PyTypeForCType<T>::type(vals[0]);
else
Expand Down Expand Up @@ -464,18 +464,15 @@ make_numpy_array(TypeDesc format, void* data, int dims, size_t chans,


inline py::object
ParamValue_getitem(const ParamValue& self, int n = 0)
ParamValue_getitem(const ParamValue& self, bool allitems = false)
{
if (n < 0 || n >= self.nvalues()) {
throw std::out_of_range(
Strutil::sprintf("ParamValue index out of range %d", n));
}

TypeDesc t = self.type();
int nvals = allitems ? self.nvalues() : 1;

#define ParamValue_convert_dispatch(TYPE) \
case TypeDesc::TYPE: \
return C_to_val_or_tuple((CType<TypeDesc::TYPE>::type*)self.data(), t)
return C_to_val_or_tuple((CType<TypeDesc::TYPE>::type*)self.data(), t, \
nvals)

switch (t.basetype) {
// ParamValue_convert_dispatch(UCHAR);
Expand All @@ -492,7 +489,7 @@ case TypeDesc::TYPE: \
ParamValue_convert_dispatch(FLOAT);
ParamValue_convert_dispatch(DOUBLE);
case TypeDesc::STRING:
return C_to_val_or_tuple((const char**)self.data(), t);
return C_to_val_or_tuple((const char**)self.data(), t, nvals);
default: return py::none();
}

Expand Down
50 changes: 48 additions & 2 deletions src/python/py_paramvalue.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,41 @@
namespace PyOpenImageIO {


static ParamValue
ParamValue_from_tuple(string_view name, TypeDesc type, int nvalues,
ParamValue::Interp interp, const py::tuple& obj)
{
ParamValue pv;
if (type.basetype == TypeDesc::INT) {
std::vector<int> vals;
py_to_stdvector(vals, obj);
if (vals.size() == type.numelements() * type.aggregate * nvalues)
pv.init(name, type, nvalues, interp, &vals[0]);
} else if (type.basetype == TypeDesc::UINT) {
std::vector<unsigned int> vals;
py_to_stdvector(vals, obj);
if (vals.size() == type.numelements() * type.aggregate * nvalues)
pv.init(name, type, nvalues, interp, &vals[0]);
} else if (type.basetype == TypeDesc::FLOAT) {
std::vector<float> vals;
py_to_stdvector(vals, obj);
if (vals.size() == type.numelements() * type.aggregate * nvalues)
pv.init(name, type, nvalues, interp, &vals[0]);
} else if (type.basetype == TypeDesc::STRING) {
std::vector<std::string> vals;
py_to_stdvector(vals, obj);
if (vals.size() == type.numelements() * type.aggregate * nvalues) {
std::vector<ustring> u;
for (auto& val : vals)
u.emplace_back(val);
pv.init(name, type, nvalues, interp, &u[0]);
}
}
return pv;
}



void
declare_paramvalue(py::module& m)
{
Expand All @@ -29,13 +64,24 @@ declare_paramvalue(py::module& m)
})
.def_property_readonly("value",
[](const ParamValue& p) {
return ParamValue_getitem(p, 0);
return ParamValue_getitem(p, true);
})
// .def("__getitem__", &ParamValue_getitem)
.def_property_readonly("__len__", &ParamValue::nvalues)
.def(py::init<const std::string&, int>())
.def(py::init<const std::string&, float>())
.def(py::init<const std::string&, const std::string&>());
.def(py::init<const std::string&, const std::string&>())
.def(py::init([](const std::string& name, TypeDesc type,
const py::tuple& obj) {
return ParamValue_from_tuple(name, type, 1,
ParamValue::INTERP_CONSTANT, obj);
}),
"name"_a, "type"_a, "value"_a)
.def(py::init([](const std::string& name, TypeDesc type, int nvalues,
ParamValue::Interp interp, const py::tuple& obj) {
return ParamValue_from_tuple(name, type, nvalues, interp, obj);
}),
"name"_a, "type"_a, "nvalues"_a, "interp"_a, "value"_a);

py::class_<ParamValueList>(m, "ParamValueList")
.def(py::init<>())
Expand Down
8 changes: 8 additions & 0 deletions testsuite/python-paramlist/ref/out.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
Testing individual ParamValue:
item a int 42
item b float 3.5
item c string xyzpdq
item d float[4] (3.5, 4.5, 5.5, 6.5)
item e float (1.0, 3.0, 5.0, 7.0)

Testing ParamValueList:
pl length is 6
item i int 1
item s string Bob
Expand Down
31 changes: 22 additions & 9 deletions testsuite/python-paramlist/src/test_paramlist.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,36 @@
import OpenImageIO as oiio


def print_param_value(p) :
if type(p.value) == float :
print (" item {} {} {:.6}".format(p.name, p.type, p.value))
else :
print (" item {} {} {}".format(p.name, p.type, p.value))

def print_param_list(pl) :
for p in pl :
if type(p.value) == float :
print (" item {} {} {:.6}".format(p.name, p.type, p.value))
else :
print (" item {} {} {}".format(p.name, p.type, p.value))
print_param_value(p)



######################################################################
# main test starts here

try:
print ("Testing individual ParamValue:")
pv = oiio.ParamValue("a", 42)
print_param_value(pv)
pv = oiio.ParamValue("b", 3.5)
print_param_value(pv)
pv = oiio.ParamValue("c", "xyzpdq")
print_param_value(pv)
pv = oiio.ParamValue("d", "float[4]", (3.5, 4.5, 5.5, 6.5))
print_param_value(pv)
pv = oiio.ParamValue("e", "float", 4, oiio.Interp.INTERP_LINEAR, (1, 3, 5, 7))
print_param_value(pv)
print ("")

print ("Testing ParamValueList:")
pl = oiio.ParamValueList()
pl.attribute ("i", 1)
pl.attribute ("s", "Bob")
Expand All @@ -27,11 +44,7 @@ def print_param_list(pl) :
pl["pi"] = 3.141592653589793

print ("pl length is", len(pl))
for p in pl :
if type(p.value) == float :
print (" item {} {} {:.6}".format(p.name, p.type, p.value))
else :
print (" item {} {} {}".format(p.name, p.type, p.value))
print_param_list (pl)

print ("pl.contains('e') =", pl.contains('e'))
print ("pl.contains('f') =", pl.contains('f'))
Expand Down