Skip to content

Commit

Permalink
#5717: Add unit tests ensuring that vertex colours get preserved when…
Browse files Browse the repository at this point in the history
… added to the exporter
  • Loading branch information
codereader committed Aug 20, 2021
1 parent 96892ef commit 9c6e853
Showing 1 changed file with 180 additions and 0 deletions.
180 changes: 180 additions & 0 deletions test/ModelExport.cpp
Expand Up @@ -3,6 +3,8 @@
#include "imodel.h"
#include "imodelcache.h"
#include "imap.h"
#include "ieclass.h"
#include "ientity.h"
#include "algorithm/Scene.h"
#include "scenelib.h"
#include "os/path.h"
Expand Down Expand Up @@ -85,4 +87,182 @@ TEST_F(ModelExportTest, ExportFolderNotExisting)
EXPECT_TRUE(fs::exists(outputPath)) << "Exporter didn't create the file " << outputPath;
}

inline bool surfaceHasVertex(const model::IModelSurface& surface, const std::function<bool(const ArbitraryMeshVertex&)>& functor)
{
for (int i = 0; i < surface.getNumVertices(); ++i)
{
if (functor(surface.getVertex(i)))
{
return true;
}
}

return false;
}

const std::string CustomMaterialName = "custom_surface_name";
const Vector3 VertexColour1(0.1, 0.2, 0.3);
const Vector3 VertexColour2(0.4, 0.5, 0.6);
const Vector3 VertexColour3(0.7, 0.8, 0.9);

inline void checkVertexColoursOfExportedModel(const model::IModelExporterPtr& exporter, const std::string& outputPath_)
{
fs::path outputPath = outputPath_;
outputPath /= "models/";
fs::path filename = "dummy.lwo";

EXPECT_FALSE(fs::exists(outputPath / filename)) << filename << " already exists in " << outputPath.string();

exporter->exportToPath(outputPath.string(), filename.string());

EXPECT_TRUE(fs::exists(outputPath / filename)) << filename << " should exists in " << outputPath.string();

try
{
// Create a func_static using this new model
auto eclass = GlobalEntityClassManager().findClass("func_static");
auto entity = GlobalEntityModule().createEntity(eclass);

scene::addNodeToContainer(entity, GlobalMapModule().getRoot());

// This should assign the model node to the entity
Node_getEntity(entity)->setKeyValue("model", "models/" + filename.string());

// Locate the IModel node among the entity's children
model::ModelNodePtr model;
entity->foreachNode([&](const scene::INodePtr& node)
{
if (Node_isModel(node))
{
model = Node_getModel(node);
}
return true;
});

EXPECT_TRUE(model) << "Could not locate the model node of the entity";

EXPECT_EQ(model->getIModel().getSurfaceCount(), 1);

const auto& surface = model->getIModel().getSurface(0);
EXPECT_EQ(surface.getDefaultMaterial(), CustomMaterialName);

EXPECT_EQ(surface.getNumVertices(), 3);

// The three colours we exported need to be present in the mesh
EXPECT_TRUE(surfaceHasVertex(surface, [&](const ArbitraryMeshVertex& vertex)
{
return math::isNear(vertex.colour, VertexColour1, 0.01);
}));
EXPECT_TRUE(surfaceHasVertex(surface, [&](const ArbitraryMeshVertex& vertex)
{
return math::isNear(vertex.colour, VertexColour2, 0.01);
}));
EXPECT_TRUE(surfaceHasVertex(surface, [&](const ArbitraryMeshVertex& vertex)
{
return math::isNear(vertex.colour, VertexColour3, 0.01);
}));

fs::remove(outputPath / filename);
}
catch (const std::exception&)
{
fs::remove(outputPath / filename);
throw;
}
}

// #5717: LWO Model exporter didn't write any vertex colours
TEST_F(ModelExportTest, LwoVertexColoursAddedByPolygon)
{
auto exporter = GlobalModelFormatManager().getExporter("lwo");
EXPECT_TRUE(exporter);

// Create a few vertices with custom colours
std::vector<model::ModelPolygon> polys;

polys.emplace_back(model::ModelPolygon
{
ArbitraryMeshVertex(Vertex3f(1,0,0), Normal3f(1,0,0), TexCoord2f(1,0), VertexColour1),
ArbitraryMeshVertex(Vertex3f(0,1,0), Normal3f(1,0,0), TexCoord2f(0,0), VertexColour2),
ArbitraryMeshVertex(Vertex3f(1,1,0), Normal3f(1,0,0), TexCoord2f(1,0), VertexColour3)
});

exporter->addPolygons(CustomMaterialName, polys, Matrix4::getIdentity());

checkVertexColoursOfExportedModel(exporter, _context.getTestProjectPath());
}

class TestModelSurface :
public model::IIndexedModelSurface
{
public:
std::vector<ArbitraryMeshVertex> vertices;
std::vector<unsigned int> indices;

int getNumVertices() const override
{
return static_cast<int>(vertices.size());
}

int getNumTriangles() const override
{
return static_cast<int>(indices.size() / 3);
}

const ArbitraryMeshVertex& getVertex(int vertexNum) const override
{
return vertices[vertexNum];
}

model::ModelPolygon getPolygon(int polygonNum) const override
{
return model::ModelPolygon
{
vertices[polygonNum * 3 + 0],
vertices[polygonNum * 3 + 1],
vertices[polygonNum * 3 + 2]
};
}

const std::string& getDefaultMaterial() const override
{
return CustomMaterialName;
}

const std::string& getActiveMaterial() const override
{
return getDefaultMaterial();
}

const std::vector<ArbitraryMeshVertex>& getVertexArray() const override
{
return vertices;
}

const std::vector<unsigned int>& getIndexArray() const override
{
return indices;
}
};

TEST_F(ModelExportTest, LwoVertexColoursAddedBySurface)
{
auto exporter = GlobalModelFormatManager().getExporter("lwo");
EXPECT_TRUE(exporter);

// Create a few vertices with custom colours
TestModelSurface surface;

surface.vertices.emplace_back(Vertex3f(1, 0, 0), Normal3f(1, 0, 0), TexCoord2f(1, 0), VertexColour1);
surface.vertices.emplace_back(Vertex3f(0, 1, 0), Normal3f(1, 0, 0), TexCoord2f(0, 0), VertexColour2);
surface.vertices.emplace_back(Vertex3f(1, 1, 0), Normal3f(1, 0, 0), TexCoord2f(1, 0), VertexColour3);
surface.indices.push_back(0);
surface.indices.push_back(1);
surface.indices.push_back(2);

exporter->addSurface(surface, Matrix4::getIdentity());

checkVertexColoursOfExportedModel(exporter, _context.getTestProjectPath());
}

}

0 comments on commit 9c6e853

Please sign in to comment.