Skip to content

Commit

Permalink
Addressed review comments. Added tests
Browse files Browse the repository at this point in the history
Signed-off-by: Gonzalo de Pedro <[email protected]>
  • Loading branch information
Gonzalo de Pedro committed Oct 19, 2020
1 parent 91d5338 commit df095ab
Show file tree
Hide file tree
Showing 3 changed files with 141 additions and 18 deletions.
2 changes: 1 addition & 1 deletion graphics/include/ignition/common/ColladaExporter.hh
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ namespace ignition

public: virtual void Export(const Mesh *_mesh,
const std::string &_filename, bool _exportTextures,
std::vector<math::Matrix4d> &_submeshToMatrix);
const std::vector<math::Matrix4d> &_submeshToMatrix);

IGN_COMMON_WARN_IGNORE__DLL_INTERFACE_MISSING
/// \internal
Expand Down
43 changes: 26 additions & 17 deletions graphics/src/ColladaExporter.cc
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ class ignition::common::ColladaExporterPrivate
/// scenes XML instance
public: void ExportVisualScenes(
tinyxml2::XMLElement *_libraryVisualScenesXml,
std::vector<math::Matrix4d> &_submeshToMatrix);
const std::vector<math::Matrix4d> &_submeshToMatrix);

/// \brief Export scene element
/// \param[in] _sceneXml Pointer to the scene XML instance
Expand Down Expand Up @@ -155,13 +155,23 @@ void ColladaExporter::Export(const Mesh *_mesh, const std::string &_filename,
bool _exportTextures)
{
std::vector<math::Matrix4d> empty;
this->ColladaExporter::Export(_mesh, _filename, _exportTextures, empty);
this->Export(_mesh, _filename, _exportTextures, empty);
}

//////////////////////////////////////////////////
void ColladaExporter::Export(const Mesh *_mesh, const std::string &_filename,
bool _exportTextures, std::vector<math::Matrix4d> &_submeshToMatrix)
bool _exportTextures, const std::vector<math::Matrix4d> &_submeshToMatrix)
{

if ( _submeshToMatrix.size() > 0 &&
(_mesh->SubMeshCount() != _submeshToMatrix.size()) )
{
ignerr << "_submeshToMatrix.size() : " << _mesh->SubMeshCount()
<< " , must be equal to SubMeshCount() : " << _mesh->SubMeshCount()
<< std::endl;
return;
}

this->dataPtr->mesh = _mesh;
this->dataPtr->materialCount = this->dataPtr->mesh->MaterialCount();
this->dataPtr->subMeshCount = this->dataPtr->mesh->SubMeshCount();
Expand All @@ -174,14 +184,6 @@ void ColladaExporter::Export(const Mesh *_mesh, const std::string &_filename,
this->dataPtr->path = unix_filename.substr(0, beginFilename);
this->dataPtr->filename = unix_filename.substr(beginFilename);

if (this->dataPtr->materialCount != 0 &&
this->dataPtr->materialCount != this->dataPtr->subMeshCount)
{
ignwarn << "Material count [" << this->dataPtr->materialCount <<
"] different from submesh count [" <<
this->dataPtr->subMeshCount << "]\n";
}

// Collada file
tinyxml2::XMLDocument xmlDoc;

Expand Down Expand Up @@ -399,9 +401,12 @@ void ColladaExporterPrivate::ExportGeometries(
{
for (unsigned int i = 0; i < this->subMeshCount; ++i)
{

int materialIndex = this->mesh->SubMeshByIndex(i).lock()->MaterialIndex();

char meshId[100], materialId[100];
snprintf(meshId, sizeof(meshId), "mesh_%u", i);
snprintf(materialId, sizeof(materialId), "material_%u", i);
snprintf(materialId, sizeof(materialId), "material_%u", materialIndex);

tinyxml2::XMLElement *geometryXml =
_libraryGeometriesXml->GetDocument()->NewElement("geometry");
Expand Down Expand Up @@ -745,7 +750,7 @@ void ColladaExporterPrivate::ExportEffects(
//////////////////////////////////////////////////
void ColladaExporterPrivate::ExportVisualScenes(
tinyxml2::XMLElement *_libraryVisualScenesXml,
std::vector<math::Matrix4d> &_submeshToMatrix)
const std::vector<math::Matrix4d> &_submeshToMatrix)
{
tinyxml2::XMLElement *visualSceneXml =
_libraryVisualScenesXml->GetDocument()->NewElement("visual_scene");
Expand All @@ -761,7 +766,6 @@ void ColladaExporterPrivate::ExportVisualScenes(

snprintf(meshId, sizeof(meshId), "mesh_%u", i);
snprintf(nodeId, sizeof(nodeId), "node_%u", i);
snprintf(materialId, sizeof(materialId), "material_%u", i);

nodeXml =
_libraryVisualScenesXml->GetDocument()->NewElement("node");
Expand Down Expand Up @@ -790,11 +794,16 @@ void ColladaExporterPrivate::ExportVisualScenes(
snprintf(attributeValue, sizeof(attributeValue), "#%s", meshId);
instanceGeometryXml->SetAttribute("url", attributeValue);

const ignition::common::MaterialPtr material =
this->mesh->MaterialByIndex(i);
int materialIndex = this->mesh->SubMeshByIndex(i).lock()->MaterialIndex();

if (material)
if (materialIndex != -1 )
{

const ignition::common::MaterialPtr material =
this->mesh->MaterialByIndex(materialIndex);

snprintf(materialId, sizeof(materialId), "material_%u", materialIndex);

tinyxml2::XMLElement *bindMaterialXml =
_libraryVisualScenesXml->GetDocument()->NewElement("bind_material");
instanceGeometryXml->LinkEndChild(bindMaterialXml);
Expand Down
114 changes: 114 additions & 0 deletions graphics/src/ColladaExporter_TEST.cc
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,120 @@ TEST_F(ColladaExporter, ExportCordlessDrill)
common::removeAll(pathOut + "/tmp");
}

/////////////////////////////////////////////////
TEST_F(ColladaExporter, ExportMeshWithSubmeshes)
{

std::string boxFilenameIn = std::string(PROJECT_SOURCE_PATH) +
"/test/data/box.dae";

common::ColladaLoader loader;
const common::Mesh *boxMesh = loader.Load(
boxFilenameIn);

const common::Mesh *drillMesh = loader.Load(
std::string(PROJECT_SOURCE_PATH) +
"/test/data/cordless_drill/meshes/cordless_drill.dae");

common::Mesh outMesh;
std::weak_ptr<common::SubMesh> subm;
std::vector<math::Matrix4d> subMeshMatrix;
math::Pose3d localPose = math::Pose3d::Zero;

int i = outMesh.AddMaterial(boxMesh->MaterialByIndex(boxMesh->SubMeshByIndex(0).lock()->MaterialIndex()));
subm = outMesh.AddSubMesh(*boxMesh->SubMeshByIndex(0).lock().get());
subm.lock()->SetMaterialIndex(i);

localPose.SetX(10);
math::Matrix4d matrix(localPose);
subMeshMatrix.push_back(matrix);

i = outMesh.AddMaterial(drillMesh->MaterialByIndex(drillMesh->SubMeshByIndex(0).lock()->MaterialIndex()));
subm = outMesh.AddSubMesh(*drillMesh->SubMeshByIndex(0).lock().get());
subm.lock()->SetMaterialIndex(i);

localPose.SetX(-10);
matrix = math::Matrix4d(localPose);
subMeshMatrix.push_back(matrix);

std::string pathOut = common::cwd();
common::createDirectories(pathOut + "/" + "tmp");

common::ColladaExporter exporter;
exporter.Export(&outMesh, pathOut + "/tmp/mesh_with_submeshes", true, subMeshMatrix);

// Check .dae file
tinyxml2::XMLDocument xmlDoc;
std::string filename = pathOut +
"/tmp/mesh_with_submeshes/meshes/mesh_with_submeshes.dae";

EXPECT_EQ(xmlDoc.LoadFile(filename.c_str()), tinyxml2::XML_SUCCESS);

ASSERT_TRUE(xmlDoc.FirstChildElement("COLLADA") != nullptr);
ASSERT_TRUE(xmlDoc.FirstChildElement(
"COLLADA")->FirstChildElement("library_geometries") != nullptr);

tinyxml2::XMLElement *geometryXml = xmlDoc.FirstChildElement("COLLADA")
->FirstChildElement("library_geometries")
->FirstChildElement("geometry");
ASSERT_TRUE(geometryXml != nullptr);

for (unsigned int j = 0; j < outMesh.SubMeshCount(); ++j)
{
unsigned int countMeshInt =
outMesh.SubMeshByIndex(j).lock()->VertexCount()*3;
char countMesh[100];
snprintf(countMesh, sizeof(countMesh), "%u", countMeshInt);

const char *countDae = geometryXml
->FirstChildElement("mesh")
->FirstChildElement("source")
->FirstChildElement("float_array")
->Attribute("count");

EXPECT_STREQ(countDae, countMesh);

geometryXml = geometryXml->NextSiblingElement("geometry");
}

tinyxml2::XMLElement *nodeXml = xmlDoc.FirstChildElement("COLLADA")
->FirstChildElement("library_visual_scenes")
->FirstChildElement("visual_scene")
->FirstChildElement("node");
ASSERT_TRUE(nodeXml != nullptr);

for (unsigned int j = 0; j < outMesh.SubMeshCount(); ++j)
{

std::ostringstream fillData;
fillData.precision(8);
fillData << std::fixed;
fillData << subMeshMatrix.at(j);

std::string matrixStr = nodeXml->FirstChildElement("matrix")->GetText();
EXPECT_EQ(matrixStr, fillData.str());

nodeXml = nodeXml->NextSiblingElement("node");
}

// Reload mesh and compare
const common::Mesh *meshReloaded = loader.Load(pathOut +
"/tmp/mesh_with_submeshes/meshes/mesh_with_submeshes.dae");

EXPECT_EQ(outMesh.Name(), meshReloaded->Name());
EXPECT_EQ(outMesh.SubMeshCount(), meshReloaded->SubMeshCount());
EXPECT_EQ(outMesh.MaterialCount(),
meshReloaded->MaterialCount());
EXPECT_EQ(outMesh.IndexCount(), meshReloaded->IndexCount());
EXPECT_EQ(outMesh.VertexCount(), meshReloaded->VertexCount());
EXPECT_EQ(outMesh.NormalCount(), meshReloaded->NormalCount());
EXPECT_EQ(outMesh.TexCoordCount(),
meshReloaded->TexCoordCount());

// Remove temp directory
common::removeAll(pathOut + "/tmp");
}

/////////////////////////////////////////////////
int main(int argc, char **argv)
{
Expand Down

0 comments on commit df095ab

Please sign in to comment.