Visual Computing Library  devel
Loading...
Searching...
No Matches
index_container_component.h
1/*****************************************************************************
2 * VCLib *
3 * Visual Computing Library *
4 * *
5 * Copyright(C) 2021-2025 *
6 * Visual Computing Lab *
7 * ISTI - Italian National Research Council *
8 * *
9 * All rights reserved. *
10 * *
11 * This program is free software; you can redistribute it and/or modify *
12 * it under the terms of the Mozilla Public License Version 2.0 as published *
13 * by the Mozilla Foundation; either version 2 of the License, or *
14 * (at your option) any later version. *
15 * *
16 * This program is distributed in the hope that it will be useful, *
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
19 * Mozilla Public License Version 2.0 *
20 * (https://www.mozilla.org/en-US/MPL/2.0/) for more details. *
21 ****************************************************************************/
22
23#ifndef VCL_MESH_COMPONENTS_BASE_INDEX_CONTAINER_COMPONENT_H
24#define VCL_MESH_COMPONENTS_BASE_INDEX_CONTAINER_COMPONENT_H
25
26#include "container_component.h"
27
28#include <vclib/mesh/iterators/components/pointer_from_index_iterator.h>
29
30#include <vclib/space/core.h>
31
32namespace vcl::comp {
33
35
77template<
78 typename DerivedComponent, // CRTP pattern, derived class
79 uint COMP_ID, // component id
80 typename Elem, // element type for which the indices are stored
81 int N, // container size
82 typename ParentElemType, // parent element type
83 bool VERT, // true if component vertical
84 bool OPT, // true if component vertical and optional
85 bool TTVN> // true if container size tied to vertex number
86class IndexContainerComponent :
87 public ContainerComponent<
88 DerivedComponent,
89 COMP_ID,
90 uint,
91 N,
92 void,
93 ParentElemType,
94 VERT,
95 OPT,
96 TTVN,
97 Elem>
98{
99 using Base = ContainerComponent<
100 DerivedComponent,
101 COMP_ID,
102 uint,
103 N,
104 void,
105 ParentElemType,
106 VERT,
107 OPT,
108 TTVN,
109 Elem>;
110
111public:
112 IndexContainerComponent()
113 {
114 if constexpr (!Base::IS_VERTICAL) {
115 init();
116 }
117 }
118
119 void init()
120 {
121 if constexpr (N >= 0) {
122 container().fill(UINT_NULL);
123 }
124 }
125
134 template<typename T>
135 const auto& indices() const requires std::is_same_v<T, Elem>
136 {
137 return container();
138 }
139
140protected:
141 using Base::container;
142
143 using ConstIndexIterator = typename Base::ConstIterator;
144 using Iterator =
145 PointerFromIndexIterator<ConstIndexIterator, Elem, ParentElemType>;
146 using ConstIterator =
147 ConstPointerFromIndexIterator<ConstIndexIterator, Elem, ParentElemType>;
148
149 /*
150 * This member function is called when we need to update the indices in
151 * this container after a reallocation (the pointer of the first element of
152 * the container of Elem is changed).
153 *
154 * With respect to the updateReferences function of the
155 * PointerContainerComponent, we need to do something only when offset is
156 * different from 0, because in this case the indices of the elements have
157 * changed (append case).
158 *
159 * When we append elements, this function is called only on the elements
160 * that have been appended, and the offset is the number of referenced
161 * elements that were in the container before the append operation.
162 */
163 void updateReferences(const Elem*, std::size_t offset = 0)
164 {
165 if (offset != 0) {
166 auto& baseContainer = Base::container();
167
168 for (uint j = 0; j < baseContainer.size(); ++j) {
169 if (baseContainer.at(j) != UINT_NULL) {
170 baseContainer.at(j) += offset;
171 }
172 }
173 }
174 }
175
176 /*
177 * This member function is called when we need to update the pointers or
178 * indices in this containers, usually after a compaction of the container
179 * (but not always).
180 *
181 * In this case, indices must be updated, because the indices of the
182 * elements have changed.
183 */
184 void updateReferences(const std::vector<uint>& newIndices)
185 {
186 auto& baseContainer = Base::container();
187
188 for (uint j = 0; j < baseContainer.size(); ++j) {
189 if (baseContainer.at(j) != UINT_NULL) {
190 baseContainer.at(j) = newIndices.at(baseContainer.at(j));
191 }
192 }
193 }
194};
195
197
198} // namespace vcl::comp
199
200#endif // VCL_MESH_COMPONENTS_BASE_INDEX_CONTAINER_COMPONENT_H