12 #include <boost/pending/disjoint_sets.hpp>
14 namespace Acts::Ccl::internal {
18 template <
typename,
size_t,
typename T =
void>
24 std::void_t<decltype(getCellRow(std::declval<T>())),
25 decltype(getCellColumn(std::declval<T>())),
32 std::void_t<decltype(getCellColumn(std::declval<T>())),
36 template <
typename,
typename,
typename T =
void>
39 template <
typename T,
typename U>
42 std::void_t<decltype(clusterAddCell(std::declval<T>(), std::declval<U>()))>>
45 template <
size_t Gr
idDim>
48 GridDim == 1 || GridDim == 2,
49 "mergeClusters is only defined for grid dimensions of 1 or 2. ");
52 template <
typename T,
size_t Gr
idDim>
56 "Cell type should have the following functions: "
57 "'int getCellRow(const Cell&)', "
58 "'int getCellColumn(const Cell&)', "
59 "'Label& getCellLabel(Cell&)'");
62 template <
typename T,
typename U>
66 "Cluster type should have the following function: "
67 "'void clusterAddCell(Cluster&, const Cell&)'");
70 template <
typename Cell,
size_t Gr
idDim>
72 static_assert(GridDim != 1 && GridDim != 2,
73 "Only grid dimensions of 1 or 2 are supported");
78 template <
typename Cell>
85 return (col0 == col1) ? row0 < row1 : col0 < col1;
90 template <
typename Cell>
131 boost::disjoint_sets<size_t*, size_t*>
m_ds;
134 template <
size_t BufSize>
137 std::array<Label, BufSize>
buf;
141 template <
size_t Gr
idDim>
157 template <
typename Cell,
typename Connect,
size_t Gr
idDim>
159 std::vector<Cell>&
set, Connect connect) {
161 typename std::vector<Cell>::iterator it_2{it};
163 while (it_2 !=
set.
begin()) {
164 it_2 = std::prev(it_2);
167 if (cr == ConnectResult::eNoConnStop) {
170 if (cr == ConnectResult::eNoConn) {
173 if (cr == ConnectResult::eConn) {
176 if (seen.nconn == seen.buf.size()) {
184 template <
typename CellCollection,
typename ClusterCollection>
193 ClusterCollection outv;
196 for (
auto& cell : cells) {
213 namespace Acts::Ccl {
215 template <
typename Cell>
217 const Cell& iter)
const {
223 return ConnectResult::eNoConnStop;
228 return ConnectResult::eNoConn;
232 if ((deltaRow + deltaCol) <= (conn8 ? 2 : 1)) {
233 return ConnectResult::eConn;
235 return ConnectResult::eNoConn;
238 template <
typename Cell>
240 const Cell& iter)
const {
242 return deltaCol == 1 ? ConnectResult::eConn : ConnectResult::eNoConnStop;
245 template <
size_t Gr
idDim>
250 if (seen.nconn > 0 && seen.buf[0] ==
NO_LABEL) {
251 throw std::logic_error(
"seen.nconn > 0 but seen.buf[0] == NO_LABEL");
253 for (
size_t i = 1;
i < seen.nconn;
i++) {
258 throw std::logic_error(
"i < seen.nconn but see.buf[i] == NO_LABEL");
261 if (seen.buf[0] != seen.buf[
i]) {
267 template <
typename CellCollection,
size_t Gr
idDim,
typename Connect>
270 internal::staticCheckCellType<Cell, GridDim>();
278 for (
auto it = cells.begin();
it != cells.end(); ++
it) {
280 internal::getConnections<Cell, Connect, GridDim>(
it, cells, connect);
281 if (seen.nconn == 0) {
292 for (
auto& cell : cells) {
294 lbl = ds.findSet(lbl);
298 template <
typename CellCollection,
typename ClusterCollection,
303 internal::staticCheckGridDim<GridDim>();
304 internal::staticCheckCellType<Cell, GridDim>();
305 internal::staticCheckClusterType<Cluster&, const Cell&>();
307 if constexpr (GridDim > 1) {
315 return internal::mergeClustersImpl<CellCollection, ClusterCollection>(cells);
318 template <
typename CellCollection,
typename ClusterCollection,
size_t GridDim,
323 internal::staticCheckCellType<Cell, GridDim>();
324 internal::staticCheckClusterType<Cluster&, const Cell&>();
325 labelClusters<CellCollection, GridDim, Connect>(cells, connect);
326 return mergeClusters<CellCollection, ClusterCollection, GridDim>(cells);