Skip to content

Commit

Permalink
Fixed bug #659, seg fault on some meshes with materials.
Browse files Browse the repository at this point in the history
Turns out rviz was assuming that submeshes were not re-used, but assimp does allow for it.
With this change, that is supported and no longer causes a seg-fault.
  • Loading branch information
hershwg committed Jul 26, 2013
1 parent 9a88d97 commit 7c36935
Show file tree
Hide file tree
Showing 12 changed files with 4,148 additions and 14 deletions.
39 changes: 25 additions & 14 deletions src/rviz/mesh_loader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,14 @@ void ResourceIOSystem::Close(Assimp::IOStream* stream)
}

// Mostly stolen from gazebo
void buildMesh(const aiScene* scene, const aiNode* node, const Ogre::MeshPtr& mesh, Ogre::AxisAlignedBox& aabb, float& radius, const float scale = 1.0)
/** @brief Recursive mesh-building function.
* @param scene is the assimp scene containing the whole mesh.
* @param node is the current assimp node, which is part of a tree of nodes being recursed over.
* @param material_table is indexed the same as scene->mMaterials[], and should have been filled out already by loadMaterials(). */
void buildMesh( const aiScene* scene, const aiNode* node,
const Ogre::MeshPtr& mesh,
Ogre::AxisAlignedBox& aabb, float& radius, const float scale,
std::vector<Ogre::MaterialPtr>& material_table )
{
if (!node)
{
Expand Down Expand Up @@ -369,11 +376,13 @@ void buildMesh(const aiScene* scene, const aiNode* node, const Ogre::MeshPtr& me
ibuf->unlock();
}
vbuf->unlock();

submesh->setMaterialName(material_table[input_mesh->mMaterialIndex]->getName());
}

for (uint32_t i=0; i < node->mNumChildren; ++i)
{
buildMesh(scene, node->mChildren[i], mesh, aabb, radius, scale);
buildMesh(scene, node->mChildren[i], mesh, aabb, radius, scale, material_table);
}
}

Expand Down Expand Up @@ -417,16 +426,22 @@ void loadTexture(const std::string& resource_path)
}

// Mostly cribbed from gazebo
void loadMaterialsForMesh(const std::string& resource_path, const aiScene* scene, const Ogre::MeshPtr& mesh)
/** @brief Load all materials needed by the given scene.
* @param resource_path the path to the resource from which this scene is being loaded.
* loadMaterials() assumes textures for this scene are relative to the same directory that this scene is in.
* @param scene the assimp scene to load materials for.
* @param material_table_out Reference to the resultant material table, filled out by this function. Is indexed the same as scene->mMaterials[].
*/
void loadMaterials(const std::string& resource_path,
const aiScene* scene,
std::vector<Ogre::MaterialPtr>& material_table_out )
{
std::vector<Ogre::MaterialPtr> material_lookup;

for (uint32_t i = 0; i < scene->mNumMaterials; i++)
{
std::stringstream ss;
ss << resource_path << "Material" << i;
Ogre::MaterialPtr mat = Ogre::MaterialManager::getSingleton().create(ss.str(), ROS_PACKAGE_NAME, true);
material_lookup.push_back(mat);
material_table_out.push_back(mat);

Ogre::Technique* tech = mat->getTechnique(0);
Ogre::Pass* pass = tech->getPass(0);
Expand Down Expand Up @@ -543,11 +558,6 @@ void loadMaterialsForMesh(const std::string& resource_path, const aiScene* scene
specular.a = diffuse.a;
mat->setSpecular(specular);
}

for (uint32_t i = 0; i < mesh->getNumSubMeshes(); ++i)
{
mesh->getSubMesh(i)->setMaterialName(material_lookup[scene->mMeshes[i]->mMaterialIndex]->getName());
}
}


Expand Down Expand Up @@ -627,19 +637,20 @@ Ogre::MeshPtr meshFromAssimpScene(const std::string& name, const aiScene* scene)
return Ogre::MeshPtr();
}

std::vector<Ogre::MaterialPtr> material_table;
loadMaterials(name, scene, material_table);

Ogre::MeshPtr mesh = Ogre::MeshManager::getSingleton().createManual(name, ROS_PACKAGE_NAME);

Ogre::AxisAlignedBox aabb(Ogre::AxisAlignedBox::EXTENT_NULL);
float radius = 0.0f;
float scale = getMeshUnitRescale(name);
buildMesh(scene, scene->mRootNode, mesh, aabb, radius, scale);
buildMesh(scene, scene->mRootNode, mesh, aabb, radius, scale, material_table);

mesh->_setBounds(aabb);
mesh->_setBoundingSphereRadius(radius);
mesh->buildEdgeList();

loadMaterialsForMesh(name, scene, mesh);

mesh->load();

return mesh;
Expand Down
13 changes: 13 additions & 0 deletions src/test/kitchen-mesh-marker.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
header: { seq: 0, stamp: { secs: 0, nsecs: 0 }, frame_id: base_link }
ns: chunk
id: 0
type: 10
action: 0
pose:
position: { x: 0, y: 0, z: 0 }
orientation: { x: 0, y: 0, z: 0, w: 1 }
color: { r: 1, g: 1, b: 1, a: 1 }
scale: { x: 1, y: 1, z: 1 }
frame_locked: False
mesh_resource: 'package://rviz/src/test/meshes/kitchen/models/dada.dae'
mesh_use_embedded_materials: True
58 changes: 58 additions & 0 deletions src/test/meshes/kitchen/doc.kml
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
<?xml version='1.0' encoding='UTF-8'?>
<kml xmlns='http://earth.google.com/kml/2.1'>
<Folder>
<name>dada</name>
<description><![CDATA[Created with <a href="http://sketchup.google.com/">Google SketchUp 6.4.112</a>]]></description>
<DocumentSource>SketchUp</DocumentSource>
<visibility>1</visibility>
<LookAt>
<heading>268.621</heading>
<tilt>81.6735</tilt>
<latitude>40.01701040206847</latitude>
<longitude>-105.2828779909634</longitude>
<range>6.259231800506925</range>
<altitude>0.9128535643034782</altitude>
</LookAt>
<Folder>
<name>Tour</name>
<Placemark>
<name>Camera</name>
<visibility>1</visibility>
<LookAt>
<heading>268.621</heading>
<tilt>81.6735</tilt>
<latitude>40.01701040206847</latitude>
<longitude>-105.2828779909634</longitude>
<range>6.259231800506925</range>
<altitude>0.9128535643034782</altitude>
</LookAt>
</Placemark>
</Folder>
<Placemark>
<name>Model</name>
<description><![CDATA[]]></description>
<Style id='default'>
</Style>
<Model>
<altitudeMode>relativeToGround</altitudeMode>
<Location>
<longitude>-105.283000000000</longitude>
<latitude>40.017000000000</latitude>
<altitude>0.000000000000</altitude>
</Location>
<Orientation>
<heading>0</heading>
<tilt>0</tilt>
<roll>0</roll>
</Orientation>
<Scale>
<x>1.0</x>
<y>1.0</y>
<z>1.0</z>
</Scale>
<Link>
<href>models/dada.dae</href>
</Link>
</Model>
</Placemark></Folder>
</kml>
Binary file added src/test/meshes/kitchen/images/texture0.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/test/meshes/kitchen/images/texture1.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/test/meshes/kitchen/images/texture2.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/test/meshes/kitchen/images/texture3.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/test/meshes/kitchen/images/texture4.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/test/meshes/kitchen/images/texture5.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/test/meshes/kitchen/images/texture6.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading

0 comments on commit 7c36935

Please sign in to comment.