| 247 | } |
| 248 | |
| 249 | scene::INodePtr createdMergedPatch(const PatchNodePtr& patchNode1, const PatchNodePtr& patchNode2) |
| 250 | { |
| 251 | auto& patch1 = patchNode1->getPatch(); |
| 252 | auto& patch2 = patchNode2->getPatch(); |
| 253 | |
| 254 | // Start with the first patch, construct some edges to compare: first row, last row, first col, last col |
| 255 | // Associate Edge to the Starting Point for copying data to new patch |
| 256 | std::vector<std::pair<PatchEdge, PatchControlIterator>> patch1Edges = |
| 257 | { |
| 258 | { PatchEdge{ SinglePatchRowIterator(patch1, 0), patch1.getWidth(), EdgeType::Row }, RowWisePatchIterator(patch1, patch1.getHeight() - 1, 1) }, |
| 259 | { PatchEdge{ SinglePatchColumnIterator(patch1, 0), patch1.getHeight(), EdgeType::Column }, ColumnWisePatchIterator(patch1, patch1.getWidth() - 1, 1) }, |
| 260 | { PatchEdge{ SinglePatchRowIterator(patch1, patch1.getHeight() - 1), patch1.getWidth(), EdgeType::Row }, RowWisePatchIterator(patch1, 0, patch1.getHeight() - 2) }, |
| 261 | { PatchEdge{ SinglePatchColumnIterator(patch1, patch1.getWidth() - 1), patch1.getHeight(), EdgeType::Column }, ColumnWisePatchIterator(patch1, 0, patch1.getWidth() - 2) } |
| 262 | }; |
| 263 | |
| 264 | // We'll be comparing each of the above edges to all other four edges of the second patch |
| 265 | // and we're doing it in forward and backwards direction: we're trying to orient patch 2 |
| 266 | // such that the edge vertices are matching up with patch 1 |
| 267 | std::vector<PatchEdge> patch2Edges = |
| 268 | { |
| 269 | { RowWisePatchIterator(patch2), patch2.getWidth(), EdgeType::Row }, |
| 270 | { ColumnWisePatchIterator(patch2), patch2.getHeight(), EdgeType::Column }, |
| 271 | { RowWisePatchIterator(patch2, patch2.getHeight() - 1, 0), patch2.getWidth(), EdgeType::Row }, |
| 272 | { ColumnWisePatchIterator(patch2, patch2.getWidth() - 1, 0), patch2.getHeight(), EdgeType::Column }, |
| 273 | |
| 274 | { RowWisePatchReverseIterator(patch2), patch2.getWidth(), EdgeType::Row }, |
| 275 | { ColumnWisePatchReverseIterator(patch2), patch2.getHeight(), EdgeType::Column }, |
| 276 | { RowWisePatchReverseIterator(patch2, patch2.getHeight() - 1, 0), patch2.getWidth(), EdgeType::Row }, |
| 277 | { ColumnWisePatchReverseIterator(patch2, patch2.getWidth() - 1, 0), patch2.getHeight(), EdgeType::Column } |
| 278 | }; |
| 279 | |
| 280 | // As soon as we've found a matching edge, we know exactly how the resulting merged patch |
| 281 | // should look like. We know the dimensions and we know whether we need to expand the |
| 282 | // patch row-wise or column-wise. |
| 283 | for (const auto& p1Iter : patch1Edges) |
| 284 | { |
| 285 | const auto& patch1Edge = p1Iter.first; |
| 286 | const auto& patch1FillData = p1Iter.second; |
| 287 | |
| 288 | for (const auto& patch2Edge : patch2Edges) |
| 289 | { |
| 290 | if (patch1Edge.edgeLength != patch2Edge.edgeLength) |
| 291 | { |
| 292 | continue; // length doesn't match |
| 293 | } |
| 294 | |
| 295 | if (!firstNItemsAreEqual(patch1Edge.iterator, patch2Edge.iterator, patch1Edge.edgeLength, WELD_EPSILON)) |
| 296 | { |
| 297 | continue; |
| 298 | } |
| 299 | |
| 300 | // Calculate the patch dimensions |
| 301 | std::size_t numNewRows = patch1.getHeight(); |
| 302 | std::size_t numNewColumns = patch1.getWidth(); |
| 303 | std::size_t numNewEdges = patch2.getWidth() * patch2.getHeight() / patch2Edge.edgeLength - 1; |
| 304 | |
| 305 | auto& dimensionToExpand = patch1Edge.edgeType == EdgeType::Row ? numNewRows : numNewColumns; |
| 306 | dimensionToExpand += numNewEdges; |
no test coverage detected