moveit / geometric_shapes

Representation of geometric shapes

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Assimp::Importer::ReadFileFromMemory creates a mesh with too many vertices

corot opened this issue · comments

Assimp::Importer::ReadFileFromMemory creates a mesh with way too many vertices. For example, for this simple .obj cube:

# Blender v2.74 (sub 0) OBJ File: ''
# www.blender.org
mtllib cube_2_5_red_2.mtl
o Cube.001
v 0.012500 -0.012500 -0.012500
v 0.012500 -0.012500 0.012500
v -0.012500 -0.012500 0.012500
v -0.012500 -0.012500 -0.012500
v 0.012500 0.012500 -0.012500
v -0.012500 0.012500 -0.012500
v -0.012500 0.012500 0.012500
v 0.012500 0.012500 0.012500
vn 0.000000 -1.000000 -0.000000
vn 0.000000 1.000000 0.000000
vn 1.000000 -0.000000 0.000000
vn 0.000000 -0.000000 1.000000
vn -1.000000 0.000000 0.000000
vn 0.000000 0.000000 -1.000000
usemtl Material.001
s 1
f 1//1 2//1 3//1 4//1
f 5//2 6//2 7//2 8//2
f 1//3 5//3 8//3 2//3
f 2//4 8//4 7//4 3//4
f 3//5 7//5 6//5 4//5
f 5//6 1//6 4//6 6//6

Creates 24 instead of the 8 required, 2/3 of them duplicated. The why is explained here (thanks to @gavanderhoorn to point me to this explanation).

This should not be a problem, as the resulting mesh looks fine. But for any reason, possibly related with how OpenGL handles occlusions, it doesn't work for clearing the octomap with DepthImageOctomapUpdater::excludeShape. All this is explained in this MoveIt group post.

The solution pointed by @gavanderhoorn's suggested explanation is to use the RemoveComponents post-processing step, removing all but the meshes. (I'll PR in a moment)

Do you think you could create a minimal test case in test for this issue? Automatically reading the vertices in a test case might not be easy, but it would streamline verifying and testing your PR.

mmm... not fully sure what and how I should test... what about this:

  1. I read a known STL file from geometric_shapes/test/resources, from example ORK tutorial's coke.stl
  2. I read a serialized shape_msgs/Mesh message constructed from this STL with tested code
  3. I compare both objects and they should be the same

But I suppose 2 meshes can be different but equally valid, if the vertices are ordered differently. Which properties can I compare in two meshes to determine that they are the same? Comes to my mind think like the bounding box, but this is hardly enough...

Any idea or advice?

Hi @jacquelinekay, I think these tests should fill the bill. I cannot come with a much better way to test my changes. The advantage is that this adds testing to existing code, namely mesh load and mesh generation for primitives.

What i do is, I generate a mesh from a primitive shape with createMeshFromShape. I randomly chose between SPHERE, CYLINDER, CONE and BOX so all will get tested in a few test executions. Then, I load its twin from an STL file. All the tests are intended to verify that both procedures produce equivalent meshes. I passed the tests both with and without my change.

Some caveats:

  • I skip the sphere because it takes ages for each test, around 20 seconds each. Could this be possible bug? Because same test on cylinders or cones takes around 100 times less!
  • meshes created by createMeshFromShape for cylinders and cones use a magic number to set the smoothness (now is 100). The STL meshes have been built with a more or less equivalent smoothness, but if this matching breaks, randomized tests can fail in some unlikely situations
  • I disabled rays intersection because it fails in around 1% cases, with and without my modifications. For example, the following ray will hit twice the generated mesh but once the loaded one:
 Eigen::Vector3d ray_o(0.497215,  -0.0503702, 0.15293);
 Eigen::Vector3d ray_d(0.00640291, 0.776497, -0.0711191);

So in fact the two methods provide slightly different meshes, but that's also true with current code.

The test looks like it could be a valuable general addition to the package. I have some feedback:

Why do you randomly choose between shapes rather than testing all of the shapes in succession?

The original issue is about the Assimp importer creating meshes with too many vertices. Can you make a test case that tests this issue more directly?

It seems to me that importing one of the STL files using Assimp::Importer::ReadFileFromMemory (by way of createMeshFromBinary) and then comparing the number of vertices (by checking vertex_count https://github.com/ros-planning/geometric_shapes/blob/6b52703f83e9f52bd952bfa6e60b15d0bd925731/include/geometric_shapes/shapes.h#L206) to the expected number of vertices (e.g. the simple cube has 8 vertices).

You are probably much more familiar with this package than me at this point, so please correct me if this suggestion doesn't make any sense.

Hi @jacquelinekay, thanks for the feedback. In fact, those are my first gtests, so I appreciate any comment.

I randomize the shapes to increase the test coverage without incurring in a considerable execution time. Think these tests get run with every new release upstream of geometric_shapes, so... I guess this mean quite often. But that said, you are probably right, because BOX is always very fast, and without the SPHERE, running all in sequence just increase by ~2 the test execution time (up to a couple of seconds... negligible). I'll modify the tests, if you want.

For the number of vertices... well, only make sense for the BOX, actually, because for the curved shapes it depends on the chosen smoothness (and they differ by one! I don't know why). That said, current code would not pass such a test. And neither would do a box with double sides, or one with duplicated vertices... being still valid; so I decided not to consider that test.

Hi back, @jacquelinekay. Regardless my previous comment, I have implemented all your suggestions, as you are probably right : fc05244

Hello back, @jacquelinekay. Any problem still blocking this PR merge? Actually, I'm the only person affected by this issue, afaik. But anyway it can prevents others in the future to waste time with this problem

I'll take another look today!

@jacquelinekay think you can still review this? I'm looking at it now