Friedrich Tuttas on 11 Jul 2024 at 14:13
⋮
Commented: Friedrich Tuttas about 9 hours ago
Accepted Answer: Paul
Open in MATLAB Online
I have CAD files of 3D shapes in obj format. In this format, the shapes are made up of a number of triangles. Using a MATLAB function, I can import data of these shapes into MATLAB. The data are made up of the coordinates of the triangles' vertices, the vector of the triangles' surface normals and the triangles' area. Using the function on one of the files looks like this:
[vertices, surfaceNormals, areas] = objImport('some3dShape.obj');
Now, vertices is a double array of size 3x3xN. N is the number of triangles of this shape and there are three vertices per triangle and each vertex is described by three coordinates. Consequently, surfaceNormals is of size 3xN and areas is of size 1xN.
I want to use these data of multiple shapes in a Simulink simulation. So, I thought, that I could store the data of all shapes nicely in a struct array in the MATLAB workspace before starting the simulation.
shapes = struct();
[shapes(1).vertices, shapes(1).surfaceNormals, shapes(1).areas] = objImport('shape1.obj');
[shapes(2).vertices, shapes(2).surfaceNormals, shapes(2).areas] = objImport('shape2.obj');
[shapes(3).vertices, shapes(3).surfaceNormals, shapes(3).areas] = objImport('shape3.obj');
A MATLAB function block within the Simulink simulation could then access the shapes struct array from the MATLAB workspace as parameter data.
At least, that was the idea. MATLAB can deal with this kind of struct array. However, Simulink throws the error message "Mixed field types in structure arrays are not supported". This only works if all fields with the same name in the struct array have the same size. So, if shapes(1).vertices had size 3x3x100, then shapes(2).vertices would also have to have this size, meaning all shapes must be made up of the same number of triangles.
I am assuming that this error is the same one as described here. So, I am assuming this has to do with the compilation of the simulation into C code.
Possible Solutions I came up with
- Create a new struct for every shape (shape1, shape2, ...).
- Pad the smaller arrays with zeros and add another field that keeps track of the actual amount of triangles per shape.
Solution 1 has the drawback that I would have to adapt my simulation every time I use a different number of shapes. I wanted to use the struct array so that the MATLAB function block can simply iterate over all struct array items in order to keep the simulation as generic as possible.
Solution 2 seems inefficient. If one of the shapes has a lot of triangles, then the struct array items of the other shapes would also have use up the same amount of memory even if they actually had a lot less triangles.
Are there any other solutions? Is there maybe some pointer-based alternative to struct arrays that does not store the actual data but just a pointer to it? That way the fields would all have the same size (that of a pointer).
1 Comment Show -1 older commentsHide -1 older comments
Show -1 older commentsHide -1 older comments
Friedrich Tuttas about 11 hours ago
Direct link to this comment
https://www.mathworks.com/matlabcentral/answers/2136523-struct-array-with-differently-sized-fields-as-parameter-data-for-simulink-simulation#comment_3209593
Open in MATLAB Online
I found a solution that seems to be working for me. Instead of creating a struct array with an item for every shape, I create a single struct and append the arrays of the individual shapes into a big array. So, if I had 4 shapes, my struct shapes would have a field vertices which has a size of 3x3x(N1+N2+N3+N4). The size of the other fields surfaceNormals and areas follow the same principle. Now, I only need to additionally save the initial index for each shape so that I know that e.g. the vertices of shape 3 are located at something like:
current_body_vertices = vertices(:,:,417:529);
In my MATLAB function block within Simulink, I now need to read these indices before accessing the shape data instead of simply iterating over a struct array like I intended before. This results in a few more lines of code, which is fine. However, I am surprised that the Simulink coder is not able to do something like this under the hood itself.
Sign in to comment.