33 template<
class Po
intList,
class IndexerOp>
37 const IndexerOp& indexer,
38 const label nSubPoints,
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);
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)
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];
311 template<
class Po
intList>
317 const scalar mergeTol,
321 const label nTotPoints =
points.size();
326 pointToUnique.clear();
327 uniquePoints.clear();
344 template<
class Po
intList>
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]; };
381 template<
class Po
intList>
385 const scalar mergeTol,
401 return (
points.size() - nChanged);
405 template<
class Po
intList>
409 const scalar mergeTol,
427 points = List<typename PointList::value_type>(
points, uniquePoints);
439 template<
class Po
intList>
444 const scalar mergeTol,
463 points = List<typename PointList::value_type>(
points, uniquePoints);
475 template<
class Po
intList>
479 const scalar mergeTol,
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);
dimensioned< typename typeOfMag< Type >::type > mag(const dimensioned< Type > &dt)
labelList sortedOrder(const UList< T > &input)
Return the (stable) sort order for the list.
Ostream & endl(Ostream &os)
Add newline and flush stream.
UList< label > labelUList
A UList of labels.
Various functions to operate on Lists.
#define forAll(list, i)
Loop across all elements in list.
label mergePoints(const PointList &points, labelList &pointToUnique, labelList &uniquePoints, const scalar mergeTol=SMALL, const bool verbose=false)
Calculate merge mapping, preserving the original point order. All points closer/equal mergeTol are to...
labelList identity(const label len, label start=0)
Return an identity map of the given length with (map[i] == i), works like std::iota() but returning a...
label inplaceMergePoints(PointList &points, const scalar mergeTol, const bool verbose, labelList &pointToUnique)
Inplace merge points, preserving the original point order. All points closer/equal mergeTol are to be...
label min(const labelHashSet &set, label minValue=labelMax)
Find the min value in labelHashSet, optionally limited by second argument.
constexpr auto end(C &c) -> decltype(c.end())
Return iterator to the end of the container c.
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.
List< label > labelList
A List of labels.
prefixOSstream Pout
OSstream wrapped stdout (std::cout) with parallel prefix.
dimensioned< typename typeOfMag< Type >::type > magSqr(const dimensioned< Type > &dt)
static constexpr const zero Zero
Global zero (0)