Skip to content

Commit

Permalink
#5382: Improved check for merged patches which should be facing the s…
Browse files Browse the repository at this point in the history
…ame direction
  • Loading branch information
codereader committed Dec 13, 2020
1 parent c35e419 commit 602c278
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 40 deletions.
37 changes: 17 additions & 20 deletions radiantcore/patch/algorithm/General.cpp
Expand Up @@ -217,33 +217,30 @@ struct PatchEdge
EdgeType edgeType;
};

void correctPatchOrientation(const IPatch& originalPatch, IPatch& mergedPatch)
inline bool meshesAreFacingOppositeDirections(const PatchMesh& mesh1, const PatchMesh& mesh2)
{
auto refVertex = originalPatch.getTesselatedPatchMesh().vertices[0];
auto mergedMesh = mergedPatch.getTesselatedPatchMesh();
bool vertexFound = false;

// Find a matching 3D vertex and compare its normals, they should match
for (auto h = 0; h < mergedMesh.height; ++h)
// Find the first matching 3D vertex and return it
for (const auto& v1 : mesh1.vertices)
{
for (auto w = 0; w < mergedMesh.width; ++w)
for (const auto& v2 : mesh2.vertices)
{
const auto& mergedVertex = mergedMesh.vertices[h * mergedMesh.width + w];

if (!mergedVertex.vertex.isEqual(refVertex.vertex, WELD_EPSILON))
{
continue;
}

// Found a matching vertex, its normal might have changed after merging,
// but the overall direction its facing should be ok, so assume they're equal +/-half_pi
if (std::abs(mergedVertex.normal.angle(refVertex.normal)) > c_half_pi)
if (v1.vertex.isEqual(v2.vertex, 0.01))
{
rMessage() << "Reversing patch matrix" << std::endl;
mergedPatch.invertMatrix();
return std::abs(v1.normal.angle(v2.normal)) > c_half_pi;
}
}
}

return false;
}

void correctPatchOrientation(const IPatch& originalPatch, IPatch& mergedPatch)
{
if (meshesAreFacingOppositeDirections(originalPatch.getTesselatedPatchMesh(), mergedPatch.getTesselatedPatchMesh()))
{
rMessage() << "Reversing patch matrix" << std::endl;
mergedPatch.invertMatrix();
}
}

}
Expand Down
47 changes: 27 additions & 20 deletions test/PatchWelding.cpp
Expand Up @@ -25,6 +25,24 @@ inline scene::INodePtr findPatchWithNumber(const std::string& number)
return algorithm::findFirstPatchWithMaterial(GlobalMapModule().getRoot(), "textures/numbers/" + number);
}

inline void compareNormalOfFirstSharedVertex(const PatchMesh& mesh1, const PatchMesh& mesh2)
{
// Find the first matching 3D vertex and return it
for (const auto& v1 : mesh1.vertices)
{
for (const auto& v2 : mesh2.vertices)
{
if (v1.vertex.isEqual(v2.vertex, 0.01))
{
EXPECT_LT(std::abs(v1.normal.angle(v2.normal)), c_half_pi);
return;
}
}
}

EXPECT_FALSE(true) << "Didn't find any matching mesh vertex";
}

scene::INodePtr performPatchWelding(const std::string& number1, const std::string& number2)
{
auto firstPatch = findPatchWithNumber(number1);
Expand All @@ -48,26 +66,7 @@ scene::INodePtr performPatchWelding(const std::string& number1, const std::strin
auto mergedPatchNode = GlobalSelectionSystem().ultimateSelected();
auto& mergedPatch = std::dynamic_pointer_cast<IPatchNode>(mergedPatchNode)->getPatch();

auto refVertex = refPatch.getTesselatedPatchMesh().vertices[0];
auto mergedMesh = mergedPatch.getTesselatedPatchMesh();
bool vertexFound = false;

// Find a matching 3D vertex and compare its normals, they should match
for (auto h = 0; h < mergedMesh.height; ++h)
{
for (auto w = 0; w < mergedMesh.width; ++w)
{
const auto& mergedVertex = mergedMesh.vertices[h * mergedMesh.width + w];

if (mergedVertex.vertex.isEqual(refVertex.vertex, 0.01))
{
vertexFound = true;
EXPECT_LT(std::abs(mergedVertex.normal.angle(refVertex.normal)), c_half_pi);
}
}
}

EXPECT_TRUE(vertexFound) << "Didn't find a matching vertex to compare the normals.";
compareNormalOfFirstSharedVertex(refPatch.getTesselatedPatchMesh(), mergedPatch.getTesselatedPatchMesh());

return GlobalSelectionSystem().ultimateSelected();
}
Expand Down Expand Up @@ -184,6 +183,14 @@ TEST_F(PatchWeldingTest, WeldStackedCylinders)
verifyMergedPatch(performPatchWelding("11", "12"), 5, 9);
}

TEST_F(PatchWeldingTest, WeldStackedCylindersOtherWayAround)
{
loadMap("weld_patches.mapx");

// Welding the two cylinders produce a 5rows x 9cols patch
verifyMergedPatch(performPatchWelding("12", "11"), 5, 9);
}

TEST_F(PatchWeldingTest, WeldedPatchInheritsLayers)
{
loadMap("weld_patches.mapx");
Expand Down

0 comments on commit 602c278

Please sign in to comment.