33template<
class Po
intList,
class IndexerOp>
37 const IndexerOp& indexer,
38 const label nSubPoints,
39 labelList& pointToUnique,
40 labelList& uniquePoints,
41 const scalar mergeTol,
45 const label nTotPoints =
points.size();
47 if (!nTotPoints || !nSubPoints)
50 pointToUnique =
identity(nTotPoints);
51 uniquePoints = pointToUnique;
56 pointToUnique.resize_nocopy(nTotPoints);
63 auto comparePoint(
points[indexer(0)]);
64 for (label pointi = 1; pointi < nSubPoints; ++pointi)
66 comparePoint =
min(comparePoint,
points[indexer(pointi)]);
78 const scalar mergeTolSqr(
magSqr(mergeTol));
81 List<scalar> sqrDist(nSubPoints);
82 for (label pointi = 0; pointi < nSubPoints; ++pointi)
84 const auto&
p =
points[indexer(pointi)];
89 magSqr(scalar(
p.x() - comparePoint.x()))
90 +
magSqr(scalar(
p.y() - comparePoint.y()))
91 +
magSqr(scalar(
p.z() - comparePoint.z()))
96 List<scalar> sortedTol(nSubPoints);
99 const auto&
p =
points[indexer(order[sorti])];
106 mag(scalar(
p.x() - comparePoint.x()))
107 +
mag(scalar(
p.y() - comparePoint.y()))
108 +
mag(scalar(
p.z() - comparePoint.z()))
119 SubList<label> subPointMap(pointToUnique, nSubPoints);
122 labelList newPointCounts(nSubPoints, Zero);
124 label nNewPoints = 0;
125 for (label sorti = 0; sorti < order.size(); ++sorti)
128 const label pointi = order[sorti];
129 const scalar currDist = sqrDist[order[sorti]];
130 const auto& currPoint =
points[indexer(pointi)];
135 bool matched =
false;
139 label prevSorti = sorti - 1;
142 && (
mag(sqrDist[order[prevSorti]] - currDist) <= sortedTol[sorti])
147 const label prevPointi = order[prevSorti];
148 const auto& prevPoint =
points[indexer(prevPointi)];
155 magSqr(scalar(currPoint.x() - prevPoint.x()))
156 +
magSqr(scalar(currPoint.y() - prevPoint.y()))
157 +
magSqr(scalar(currPoint.z() - prevPoint.z()))
165 subPointMap[pointi] = subPointMap[prevPointi];
169 Pout<<
"Foam::mergePoints : [" << subPointMap[pointi]
170 <<
"] Point " << pointi <<
" duplicate of "
171 << prevPointi <<
" : coordinates:" << currPoint
172 <<
" and " << prevPoint <<
endl;
181 subPointMap[pointi] = nNewPoints++;
190 ++newPointCounts[subPointMap[pointi]];
193 const label nDupPoints(nSubPoints - nNewPoints);
194 const label nUniqPoints(nTotPoints - nDupPoints);
198 Pout<<
"Foam::mergePoints : "
199 <<
"Merging removed " << nDupPoints <<
'/'
200 << nTotPoints <<
" points" <<
endl;
206 pointToUnique =
identity(nTotPoints);
207 uniquePoints = pointToUnique;
219 labelList lookupMerged(std::move(order));
223 for (label& idx : lookupMerged)
233 ListOps::identity(pointToUnique, 1);
240 for (
const label len : newPointCounts)
244 const label
end = (beg + len);
249 label masterPointi = lookupMerged[beg];
251 for (label iter = beg + 1; iter <
end; ++iter)
253 const label origPointi = lookupMerged[iter];
255 if (masterPointi > origPointi)
257 masterPointi = origPointi;
263 for (label iter = beg; iter <
end; ++iter)
265 const label origPointi = lookupMerged[iter];
267 if (masterPointi != origPointi)
270 pointToUnique[origPointi] = (-masterPointi-1);
280 uniquePoints.resize_nocopy(nUniqPoints);
284 forAll(pointToUnique, pointi)
286 const label origPointi = pointToUnique[pointi];
291 uniquePoints[uniquei] = (origPointi - 1);
292 pointToUnique[pointi] = uniquei;
299 const label masterPointi =
mag(origPointi) - 1;
300 pointToUnique[pointi] = pointToUnique[masterPointi];
311template<
class Po
intList>
315 labelList& pointToUnique,
316 labelList& uniquePoints,
317 const scalar mergeTol,
321 const label nTotPoints =
points.size();
326 pointToUnique.clear();
327 uniquePoints.clear();
344template<
class Po
intList>
348 const labelUList& selection,
349 labelList& pointToUnique,
350 labelList& uniquePoints,
351 const scalar mergeTol,
355 const label nTotPoints =
points.size();
356 const label nSubPoints = selection.size();
358 if (!nTotPoints || !nSubPoints)
361 pointToUnique.clear();
362 uniquePoints.clear();
366 const auto indexer = [&](
const label i) -> label {
return selection[i]; };
381template<
class Po
intList>
385 const scalar mergeTol,
387 labelList& pointToUnique
401 return (
points.size() - nChanged);
405template<
class Po
intList>
409 const scalar mergeTol,
411 labelList& pointToUnique
427 points = List<typename PointList::value_type>(
points, uniquePoints);
439template<
class Po
intList>
443 const labelUList& selection,
444 const scalar mergeTol,
446 labelList& pointToUnique
463 points = List<typename PointList::value_type>(
points, uniquePoints);
475template<
class Po
intList>
479 const scalar mergeTol,
481 labelList& pointToUnique,
482 List<typename PointList::value_type>& newPoints
485 const label nTotPoints =
points.size();
490 pointToUnique.clear();
507 newPoints = List<typename PointList::value_type>(
points, uniquePoints);
Various functions to operate on Lists.
label mergePoints(const PointList &points, const IndexerOp &indexer, const label nSubPoints, labelList &pointToUnique, labelList &uniquePoints, const scalar mergeTol, const bool verbose)
Implementation detail for Foam::mergePoints.
labelList identity(const label len, label start=0)
Return an identity map of the given length with (map[i] == i)
List< label > labelList
A List of labels.
label mergePoints(const PointList &points, labelList &pointToUnique, labelList &uniquePoints, const scalar mergeTol=SMALL, const bool verbose=false)
Ostream & endl(Ostream &os)
Add newline and flush stream.
dimensioned< typename typeOfMag< Type >::type > mag(const dimensioned< Type > &dt)
labelList sortedOrder(const UList< T > &input)
Return the (stable) sort order for the list.
label min(const labelHashSet &set, label minValue=labelMax)
Find the min value in labelHashSet, optionally limited by second argument.
label inplaceMergePoints(PointList &points, const scalar mergeTol, const bool verbose, labelList &pointToUnique)
prefixOSstream Pout
OSstream wrapped stdout (std::cout) with parallel prefix.
dimensioned< typename typeOfMag< Type >::type > magSqr(const dimensioned< Type > &dt)
constexpr auto end(C &c) -> decltype(c.end())
Return iterator to the end of the container c.
#define forAll(list, i)
Loop across all elements in list.