Skip to content

Commit

Permalink
#5382: Expand PatchControl iterators, plus some WIP algorithm code
Browse files Browse the repository at this point in the history
  • Loading branch information
codereader committed Dec 6, 2020
1 parent 6d1f3a5 commit 48a5d01
Show file tree
Hide file tree
Showing 2 changed files with 116 additions and 6 deletions.
39 changes: 39 additions & 0 deletions radiantcore/patch/algorithm/General.cpp
Expand Up @@ -12,6 +12,7 @@
#include "string/convert.h"
#include "scenelib.h"
#include "command/ExecutionFailure.h"
#include "PatchIterators.h"

namespace patch
{
Expand Down Expand Up @@ -419,6 +420,31 @@ PatchNodePtr createdMergedPatch(const PatchNodePtr& patchNode1, const PatchNodeP
return newPatchNode;
}

namespace
{

// Returns true if all the elements in the given sequences are equal
inline bool isEqual(const PatchControlIterator& sequence1, const PatchControlIterator& sequence2)
{
// If the iterators are invalid from the start, return false
if (!sequence1.isValid() || !sequence2.isValid())
{
return false;
}

for (auto p1 = sequence1, p2 = sequence2; p1.isValid() && p2.isValid(); ++p1, ++p2)
{
if (p1->vertex != p2->vertex)
{
return false;
}
}

return true;
}

}

PatchNodePtr createdMergedPatch(const PatchNodePtr& patchNode1, const PatchNodePtr& patchNode2)
{
constexpr double WELD_EPSILON = 0.001;
Expand All @@ -439,6 +465,19 @@ PatchNodePtr createdMergedPatch(const PatchNodePtr& patchNode1, const PatchNodeP

if (patch1.getWidth() == patch2.getWidth())
{
// Row dimensions match, compare the first and last row of this patch to the
// first and last row of the other patch
SinglePatchRowIterator patch1FirstRow(patch1, 0);
SinglePatchRowIterator patch1LastRow(patch1, patch1.getWidth() - 1);

SinglePatchRowIterator patch2FirstRow(patch2, 0);
SinglePatchRowIterator patch2LastRow(patch2, patch2.getWidth() - 1);

if (isEqual(patch1FirstRow, patch2FirstRow))
{

}

row1 = 0;
row2 = 0;

Expand Down
83 changes: 77 additions & 6 deletions radiantcore/patch/algorithm/PatchIterators.h
Expand Up @@ -34,7 +34,7 @@ class PatchControlIterator
// Moves this iterator forward by one step
Forwarder _forward;

protected:
public:
PatchControlIterator(IPatch& patch, int row, int col, Forwarder forward) :
_patch(patch),
_row(row),
Expand All @@ -45,7 +45,6 @@ class PatchControlIterator
PatchControlIterator(const PatchControlIterator& other) = default;
PatchControlIterator& operator=(const PatchControlIterator& other) = default;

public:
// Post-increment i++
PatchControlIterator operator++(int)
{
Expand Down Expand Up @@ -121,11 +120,11 @@ class PatchControlIterator
};

// An iterator traversing a single row of a patch
class PatchRowIterator :
class SinglePatchRowIterator :
public PatchControlIterator
{
public:
PatchRowIterator(IPatch& patch, std::size_t row) :
SinglePatchRowIterator(IPatch& patch, std::size_t row) :
PatchControlIterator(patch, static_cast<int>(row), 0, moveToNextCol)
{}

Expand All @@ -137,11 +136,11 @@ class PatchRowIterator :
};

// An iterator traversing a single column of a patch
class PatchColumnIterator :
class SinglePatchColumnIterator :
public PatchControlIterator
{
public:
PatchColumnIterator(IPatch& patch, std::size_t col) :
SinglePatchColumnIterator(IPatch& patch, std::size_t col) :
PatchControlIterator(patch, 0, static_cast<int>(col), moveToNextRow)
{}

Expand All @@ -152,4 +151,76 @@ class PatchColumnIterator :
}
};

// An iterator traversing a the given patch column-wise, iterating over
// one row after the other (which are optionally constrained to [startRow..endRow])
class ColumnWisePatchIterator :
public PatchControlIterator
{
public:
ColumnWisePatchIterator(IPatch& patch) :
ColumnWisePatchIterator(patch, 0, patch.getHeight() - 1)
{
assert(patch.getHeight() > 0);
}

ColumnWisePatchIterator(IPatch& patch, std::size_t startRow, std::size_t endRow) :
PatchControlIterator(patch, startRow, 0, std::bind(ColumnWisePatchIterator::moveNext, std::placeholders::_1, patch, endRow))
{}

private:
static void moveNext(PatchControlIterator& it, const IPatch& patch, std::size_t endRow)
{
auto nextColumn = it.getColumn() + 1;
auto nextRow = it.getRow();

if (nextColumn >= patch.getWidth())
{
// Advance to the next row
// If that doesn't succeed, just leave the indices out of bounds
if (++nextRow <= endRow)
{
nextColumn = 0;
}
}

it.set(nextRow, nextColumn);
}
};

// An iterator traversing a the given patch row-wise, iterating over
// one column after the other (which are optionally constrained to [startColumn..endColumn])
class RowWisePatchIterator :
public PatchControlIterator
{
public:
RowWisePatchIterator(IPatch& patch) :
RowWisePatchIterator(patch, 0, patch.getWidth() - 1)
{
assert(patch.getWidth() > 0);
}

RowWisePatchIterator(IPatch& patch, std::size_t startColumn, std::size_t endColumn) :
PatchControlIterator(patch, startColumn, 0, std::bind(RowWisePatchIterator::moveNext, std::placeholders::_1, patch, endColumn))
{}

private:
static void moveNext(PatchControlIterator& it, const IPatch& patch, std::size_t endColumn)
{
auto nextRow = it.getRow() + 1;
auto nextColumn = it.getColumn();

if (nextRow >= patch.getHeight())
{
// Advance to the next column
// If that doesn't succeed, just leave the indices out of bounds
if (++nextColumn <= endColumn)
{
nextRow = 0;
}
}

it.set(nextRow, nextColumn);
}
};

}

0 comments on commit 48a5d01

Please sign in to comment.