Closed patrikhuber closed 7 years ago
@patrikhuber Is there any difference between glm::tvec4<float,0>
and glm::vec4<float>
?
Usually it is a matter of defining ::to
for glm::vec4<float>*
. But vec4
seems to be also a template, and because of that, template type inference might be failing in the compiler side.
Is there any difference between glm::tvec4<float,0> and glm::vec4
?
No, 0 (it's glm::precision::packed_highp
) is the default. But just to be sure, I played around more with it, simplifying it a bit: leaving out the std::vector
, and specifying all template arguments explicitly, and it still gives the same error.
However I think I got closer to the issue: I think this is an issue with how the ::to
and ::from
instantiation works in input.get<T>(arg_nb);
(from InputArguments
) versus how it works in array.at<T>(...)
(from MxArray
).
For example this works fine, and calls the ::to
method for glm::vec4*
:
const auto vec = input.get<glm::vec4>(0);
In contrast, array.at<glm::vec4>("vertices");
doesn't compile - I don't think this tries to go via the ::to
methods at all? It tries to use its own methods with a different mechanism, which use value->assign(...)
and value->resize(...)
.
I can call ::to
manually on the element of the struct, but it's really ugly and cumbersome:
const mxArray* element = mxGetField(array.get(), 0, "vertices");
MxArray vtx_sub_ele(element);
glm::vec4 vec;
mexplus::MxArray::to(vtx_sub_ele.get(), &vec);
Am I correct that these are two different overload mechanisms happening here, because it works in the first case, from InputArguments
, but not in the second case? Do you have any suggestions as to a solution?
@patrikhuber There could be a missing API in MxArray for at()
support. Just to check, does the following work?
array.at("vertices", &mesh.vertices);
array.at("vertices", &mesh.vertices);
It produces the same compile error than the other at
function overload that I used:
Error C2039 'assign': is not a member of 'glm::tvec4<float,0>' Error C2039 'resize': is not a member of 'glm::tvec4<float,0>'
@patrikhuber I see. This can be marked a bug, as the internal implementation of at
is not able to instantiate the correct function.
The temporary workaround is perhaps to use to
as you've found.
MxArray vertices(array.at("vertices"));
vertices.to(&mesh.vertices);
MxArray vertices(array.at("vertices")); vertices.to(&mesh.vertices);
Actually, this produces above compile errors too.
So we've got the following:
glm::vec4 vec;
MxArray vertices(array.at("vertices"));
vertices.to(&vec); // produces above compile errors
mexplus::MxArray::to(vertices.get(), &vec); // works
@patrikhuber Alright, this is yet another bug. Will check.
Thank you very much!
I think I know why it works in the case of InputArguments
:
InputArguments::get(...)
explicitly calls ::to
:
MxArray::to<T>(get(index), value);
While in the other case, probably some function overload "magic" happens.
@patrikhuber Yes, the thing is that at
and to
are using different internal conversion logic, and that's why the behavior is inconsistent. I am thinking about unifying some of the internal implementation. At least cell and struct access can rely on to
conversion inside.
Okay! That makes sense and explains my observation. I'm manually calling MxArray::to
right now in many places. Looking forward to the improvements! :-)
Thanks for your time and this great library!
@patrikhuber PR #21 should solve this specific issue. Good luck
I can confirm this fixes the issue, and array.at("vertices", &mesh->vertices);
now finds the correct overload!
Thanks very much for your time and effort! :-)
Hi!
I'm trying to pass a struct from Matlab to C++. The struct contains several matrices:
I'm having trouble reading this back into my C++ class.
This fails to compile with a few errors like:
Of course I have defined a template specialisation to read this:
But it doesn't seem to get used. Also, defining a
::to
method for justglm::vec4
doesn't fix it and results in the same compile error.I'm a bit confused by this as when I go the opposite way, from a C++ Mesh to a Matlab struct, everything works great - I've defined a
::from
method forMesh
which callsout_array.set("vertices", mesh.vertices);
, which in turns calls the::from
specialisation forstd::vector<glm::tvec4<float>>
that I have defined.It seems to me like the only way to read a matrix from a Matlab struct in C++ is through
vector
; if I do this inside theMesh
's::to
method, it compiles:auto vertices = array.at<std::vector<double>>("vertices");
But this is quite cumbersome and repetitive I then need to convert manually from this
vector<double>
to my types (reshape, etc.), and I think it defies the whole purpose of the very nice concept of these converters with theto
andfrom
methods.Am I missing something, or what is the best way to accomplish this?
Thanks!