Skip to content

Commit

Permalink
#5746: Set up tests for the "Select Related" texture tool algorithm.
Browse files Browse the repository at this point in the history
  • Loading branch information
codereader committed Sep 26, 2021
1 parent 569a4cc commit 520a24c
Show file tree
Hide file tree
Showing 6 changed files with 141 additions and 2 deletions.
3 changes: 3 additions & 0 deletions include/itexturetoolmodel.h
Expand Up @@ -61,6 +61,9 @@ class IComponentSelectable
// True if this node has at least one selected component (e.g. a vertex)
virtual bool hasSelectedComponents() const = 0;

// Returns the number of selected components
virtual std::size_t getNumSelectedComponents() const = 0;

// Unselect all components of this node
virtual void clearComponentSelection() = 0;

Expand Down
1 change: 0 additions & 1 deletion radiant/textool/TexTool.cpp
Expand Up @@ -875,7 +875,6 @@ void TexTool::registerCommands()
GlobalCommandSystem().addCommand("TexToolMergeItems", TexTool::texToolMergeItems);
GlobalCommandSystem().addCommand("TexToolFlipS", TexTool::texToolFlipS);
GlobalCommandSystem().addCommand("TexToolFlipT", TexTool::texToolFlipT);
GlobalCommandSystem().addCommand("TexToolSelectRelated", TexTool::selectRelated);

GlobalEventManager().addRegistryToggle("TexToolToggleGrid", RKEY_GRID_STATE);
GlobalEventManager().addRegistryToggle("TexToolToggleFaceVertexScalePivot", RKEY_FACE_VERTEX_SCALE_PIVOT_IS_CENTROID);
Expand Down
15 changes: 15 additions & 0 deletions radiantcore/selection/textool/NodeBase.h
Expand Up @@ -49,6 +49,21 @@ class NodeBase :
return false;
}

virtual std::size_t getNumSelectedComponents() const override
{
std::size_t count = 0;

for (const auto& vertex : _vertices)
{
if (vertex.isSelected())
{
++count;
}
}

return count;
}

virtual void clearComponentSelection() override
{
for (auto& vertex : _vertices)
Expand Down
7 changes: 7 additions & 0 deletions radiantcore/selection/textool/TextureToolSelectionSystem.cpp
Expand Up @@ -43,6 +43,8 @@ void TextureToolSelectionSystem::initialiseModule(const IApplicationContext& ctx
GlobalCommandSystem().addCommand("ToggleTextureToolSelectionMode",
std::bind(&TextureToolSelectionSystem::toggleSelectionModeCmd, this, std::placeholders::_1),
{ cmd::ARGTYPE_STRING });
GlobalCommandSystem().addCommand("TexToolSelectRelated",
std::bind(&TextureToolSelectionSystem::selectRelatedCmd, this, std::placeholders::_1));

_unselectListener = GlobalRadiantCore().getMessageBus().addListener(
radiant::IMessage::Type::UnselectSelectionRequest,
Expand Down Expand Up @@ -536,6 +538,11 @@ void TextureToolSelectionSystem::onComponentSelectionChanged(ISelectable& select
_sigSelectionChanged.emit();
}

void TextureToolSelectionSystem::selectRelatedCmd(const cmd::ArgumentList& args)
{
// TODO
}

module::StaticModule<TextureToolSelectionSystem> _textureToolSelectionSystemModule;

}
1 change: 1 addition & 0 deletions radiantcore/selection/textool/TextureToolSelectionSystem.h
Expand Up @@ -87,6 +87,7 @@ class TextureToolSelectionSystem :
std::size_t getManipulatorIdForType(selection::IManipulator::Type type);

void toggleSelectionModeCmd(const cmd::ArgumentList& args);
void selectRelatedCmd(const cmd::ArgumentList& args);

void performSelectionTest(Selector& selector, SelectionTest& test);
};
Expand Down
116 changes: 115 additions & 1 deletion test/TextureTool.cpp
Expand Up @@ -681,7 +681,7 @@ TEST_F(TextureToolTest, TestSelectFaceSurfaceByPoint)
EXPECT_FALSE(textoolFace->isSelected()) << "Face should be unselected at start";

// Get the texture space bounds of this face
// Construct a view that includes the patch UV bounds
// Construct a view that includes the face UV bounds
auto bounds = getTextureSpaceBounds(*faceUp);
bounds.extents *= 1.2f;

Expand Down Expand Up @@ -1431,4 +1431,118 @@ TEST_F(TextureToolTest, CancelDragManipulationOfFaceVertices)
performFaceVertexManipulationTest(true, { 0 }, assertAllCoordsUnchanged); // cancel
}

TEST_F(TextureToolTest, SelectRelatedOfPatchVertex)
{
auto patchNode = setupPatchNodeForTextureTool();
auto patch = Node_getIPatch(patchNode);

// Get the texture space bounds of this patch
auto bounds = getTextureSpaceBounds(*patch);
bounds.extents *= 1.2f;

render::TextureToolView view;
view.constructFromTextureSpaceBounds(bounds, TEXTOOL_WIDTH, TEXTOOL_HEIGHT);

// Switch to vertex selection mode
GlobalTextureToolSelectionSystem().setSelectionMode(textool::SelectionMode::Vertex);

// Get the texcoords of the first vertex
auto firstVertex = patch->ctrlAt(2, 1).texcoord;
performPointSelection(firstVertex, view);

// Hitting a vertex will select the patch componentselectable
EXPECT_EQ(getAllSelectedComponentNodes().size(), 1) << "Only one patch should be selected";

textool::IComponentSelectable::Ptr componentSelectable;
GlobalTextureToolSelectionSystem().foreachSelectedComponentNode([&](const textool::INode::Ptr& node)
{
componentSelectable = std::dynamic_pointer_cast<textool::IComponentSelectable>(node);
return false;
});

EXPECT_EQ(componentSelectable->getNumSelectedComponents(), 1) << "1 vertex should be selected";

// Execute "Select Related"
GlobalCommandSystem().executeCommand("TexToolSelectRelated");

EXPECT_EQ(getAllSelectedComponentNodes().size(), 1) << "Only one patch should be selected";
EXPECT_EQ(componentSelectable->getNumSelectedComponents(), 9) << "all 3x3 vertices should be selected";
}

TEST_F(TextureToolTest, SelectRelatedOfFaceVertex)
{
auto worldspawn = GlobalMapModule().findOrInsertWorldspawn();
auto brush = algorithm::createCubicBrush(worldspawn, Vector3(0, 256, 256), "textures/numbers/1");
scene::addNodeToContainer(brush, worldspawn);

// Put all faces into the tex tool scene
Node_setSelected(brush, true);

auto faceUp = algorithm::findBrushFaceWithNormal(Node_getIBrush(brush), Vector3(0, 0, 1));

// Get the texture space bounds of this face
auto bounds = getTextureSpaceBounds(*faceUp);
bounds.extents *= 1.2f;

render::TextureToolView view;
view.constructFromTextureSpaceBounds(bounds, TEXTOOL_WIDTH, TEXTOOL_HEIGHT);

// Switch to vertex selection mode
GlobalTextureToolSelectionSystem().setSelectionMode(textool::SelectionMode::Vertex);

// Get the texcoords of the first vertex
auto firstVertex = faceUp->getWinding()[0].texcoord;
performPointSelection(firstVertex, view);

// Hitting a vertex will select the patch componentselectable
EXPECT_EQ(getAllSelectedComponentNodes().size(), 1) << "Only one face should be selected";

textool::IComponentSelectable::Ptr componentSelectable;
GlobalTextureToolSelectionSystem().foreachSelectedComponentNode([&](const textool::INode::Ptr& node)
{
componentSelectable = std::dynamic_pointer_cast<textool::IComponentSelectable>(node);
return false;
});

EXPECT_EQ(componentSelectable->getNumSelectedComponents(), 1) << "1 vertex should be selected";

// Execute "Select Related"
GlobalCommandSystem().executeCommand("TexToolSelectRelated");

EXPECT_EQ(getAllSelectedComponentNodes().size(), 1) << "Only one face should be selected";
EXPECT_EQ(componentSelectable->getNumSelectedComponents(), faceUp->getWinding().size()) << "All winding vertices should be selected";
}

TEST_F(TextureToolTest, SelectRelatedOfFaceNode)
{
auto worldspawn = GlobalMapModule().findOrInsertWorldspawn();
auto brush = algorithm::createCubicBrush(worldspawn, Vector3(0, 256, 256), "textures/numbers/1");
scene::addNodeToContainer(brush, worldspawn);

// Put all faces into the tex tool scene
Node_setSelected(brush, true);

auto faceUp = algorithm::findBrushFaceWithNormal(Node_getIBrush(brush), Vector3(0, 0, 1));

EXPECT_EQ(getAllSelectedTextoolNodes().size(), 0) << "No item should be selected";

// Get the texture space bounds of this face
// Construct a view that includes the face UV bounds
auto bounds = getTextureSpaceBounds(*faceUp);
bounds.extents *= 1.2f;

render::TextureToolView view;
view.constructFromTextureSpaceBounds(bounds, TEXTOOL_WIDTH, TEXTOOL_HEIGHT);

// Point-select in the middle of the face
performPointSelection(algorithm::getFaceCentroid(faceUp), view);

EXPECT_EQ(getAllSelectedTextoolNodes().size(), 1) << "Only one face should be selected";

// Execute "Select Related"
GlobalCommandSystem().executeCommand("TexToolSelectRelated");

EXPECT_EQ(getAllSelectedComponentNodes().size(), 6) << "All 6 faces should be selected";
}

}

0 comments on commit 520a24c

Please sign in to comment.