23#ifndef VCL_MESH_CONTAINERS_BASE_ELEMENT_CONTAINER_H
24#define VCL_MESH_CONTAINERS_BASE_ELEMENT_CONTAINER_H
27#include "custom_component_vector_handle.h"
29#include "../detail/custom_components_vector_map.h"
30#include "../detail/vertical_components_vector_tuple.h"
32#include <vclib/mesh/components/base/component.h>
33#include <vclib/mesh/components/custom_components.h>
34#include <vclib/mesh/elements/base/element.h>
35#include <vclib/mesh/iterators/element_container_iterator.h>
37#include <vclib/base.h>
44template<ElementConcept T>
45class ElementContainer :
public ElementContainerTriggerer
47 template<ElementConcept U>
48 friend class ElementContainer;
50 using ElementContainerType = ElementContainer<T>;
53 using VertComps = FilterTypesByCondition<
54 comp::IsVerticalComponentPred,
55 typename T::Components>::type;
58 using ElementType = T;
59 using ParentMeshType = T::ParentMeshType;
62 ParentMeshType* mParentMesh =
nullptr;
76 std::vector<T> mElemVec;
83 detail::VerticalComponentsVectorTuple<VertComps> mVerticalCompVecTuple;
89 detail::CustomComponentsVectorMap<comp::HasCustomComponents<T>>
93 static const uint ELEMENT_ID = T::ELEMENT_ID;
98 ElementContainer() =
default;
102 using ElementIterator = ElementContainerIterator<std::vector, T>;
103 using ConstElementIterator = ConstElementContainerIterator<std::vector, T>;
116 const T& element(uint i)
const
118 assert(i < mElemVec.size());
135 assert(i < mElemVec.size());
148 uint elementNumber()
const {
return mElemNumber; }
159 uint elementContainerSize()
const {
return mElemVec.
size(); }
167 uint deletedElementNumber()
const
169 return elementContainerSize() - elementNumber();
174 mVerticalCompVecTuple.resize(mElemVec.size() + 1);
175 if constexpr (comp::HasCustomComponents<T>)
176 mCustomCompVecMap.resize(mElemVec.size() + 1);
178 T* oldB = mElemVec.data();
179 mElemVec.emplace_back();
180 T* newB = mElemVec.data();
183 mElemVec.back().setParentMesh(mParentMesh);
184 mElemVec.back().initVerticalComponents();
187 setParentMeshPointers(mParentMesh);
188 mParentMesh->updateAllReferences(oldB);
191 return mElemVec.size() - 1;
202 uint addElements(uint size)
204 mVerticalCompVecTuple.resize(mElemVec.size() + size);
205 if constexpr (comp::HasCustomComponents<T>)
206 mCustomCompVecMap.resize(mElemVec.size() + size);
208 uint baseId = mElemVec.
size();
209 T* oldB = mElemVec.data();
210 mElemVec.resize(mElemVec.size() + size);
211 T* newB = mElemVec.data();
214 for (uint i = baseId; i < mElemVec.size(); ++i) {
215 mElemVec[i].setParentMesh(mParentMesh);
216 mElemVec[i].initVerticalComponents();
220 setParentMeshPointers(mParentMesh);
221 mParentMesh->updateAllReferences(oldB);
234 mVerticalCompVecTuple.clear();
235 if constexpr (comp::HasCustomComponents<T>)
236 mCustomCompVecMap.clear();
267 void resizeElements(uint size)
269 if (size > mElemNumber) {
270 addElements(size - mElemNumber);
272 else if (size < mElemNumber) {
273 uint nToDelete = mElemNumber - size;
274 for (uint i = mElemVec.size() - 1; nToDelete > 0; --i) {
275 if (!mElemVec[i].deleted()) {
282 void reserveElements(uint size)
284 T* oldB = mElemVec.data();
285 mElemVec.reserve(size);
286 T* newB = mElemVec.data();
288 mVerticalCompVecTuple.reserve(size);
289 if constexpr (comp::HasCustomComponents<T>)
290 mCustomCompVecMap.reserve(size);
293 setParentMeshPointers(mParentMesh);
294 mParentMesh->updateAllReferences(oldB);
305 std::vector<uint> compactElements()
307 std::vector<uint> newIndices = elementCompactIndices();
308 if (elementNumber() != elementContainerSize()) {
309 compactVector(mElemVec, newIndices);
311 mVerticalCompVecTuple.compact(newIndices);
312 if constexpr (comp::HasCustomComponents<T>)
313 mCustomCompVecMap.compact(newIndices);
315 updateElementIndices(newIndices);
335 void deleteElement(uint i)
337 assert(i < mElemVec.size());
338 mElemVec[i].deletedBit() =
true;
358 void deleteElement(
const T* e) { deleteElement(index(e)); }
373 uint elementIndexIfCompact(uint i)
const
375 assert(i < mElemVec.size());
376 if (mElemVec.size() == mElemNumber)
380 for (uint ii = 0; ii < i; ii++) {
381 if (!mElemVec[ii].deleted())
399 std::vector<uint> elementCompactIndices()
const
401 std::vector<uint> newIndices(mElemVec.size());
403 for (uint i = 0; i < mElemVec.size(); ++i) {
404 if (!mElemVec[i].deleted()) {
429 void append(
const ElementContainer<T>& other)
431 using Comps = T::Components;
433 uint on = other.elementContainerSize();
434 uint n = elementContainerSize();
436 for (uint i = 0; i < on; ++i) {
439 if (other.element(i).deleted()) {
440 deleteElement(n + i);
442 element(n + i) = other.element(i);
443 element(n + i).setParentMesh(mParentMesh);
446 appendVerticalComponents(other, VertComps());
447 appendCustomComponents(other);
460 void serializeOptionalComponentsAndElementsNumber(std::ostream& out)
const
462 constexpr uint N_VERT_COMPS = VertComps::size();
463 std::array<bool, N_VERT_COMPS> enabledComps;
466 auto forEachVertComp = [&]<
typename Comp>() {
468 mVerticalCompVecTuple.template isComponentEnabled<Comp>();
472 ForEachType<VertComps>::apply(forEachVertComp);
474 vcl::serialize(out, elementContainerSize());
475 vcl::serialize(out, enabledComps);
486 void serializeElements(std::ostream& out)
const
488 for (
const auto& e : mElemVec) {
503 void deserializeOptionalComponentsAndElementsNumber(std::istream& in)
505 constexpr uint N_VERT_COMPS = VertComps::size();
506 std::array<bool, N_VERT_COMPS> enabledComps;
509 vcl::deserialize(in, size);
510 vcl::deserialize(in, enabledComps);
512 resizeElements(size);
515 auto forEachVertComp = [&]<
typename Comp>() {
517 mVerticalCompVecTuple.template enableComponent<Comp>();
519 mVerticalCompVecTuple.template disableComponent<Comp>();
523 ForEachType<VertComps>::apply(forEachVertComp);
534 void deserializeElements(std::istream& in)
536 for (
auto& e : mElemVec) {
552 ElementIterator elementBegin(
bool jumpDeleted =
true)
554 return ElementIterator(
557 jumpDeleted && mElemVec.size() != mElemNumber);
564 ElementIterator elementEnd()
566 return ElementIterator(mElemVec.end(), mElemVec);
580 ConstElementIterator elementBegin(
bool jumpDeleted =
true)
const
582 return ConstElementIterator(
585 jumpDeleted && mElemVec.size() != mElemNumber);
592 ConstElementIterator elementEnd()
const
594 return ConstElementIterator(mElemVec.end(), mElemVec);
619 View<ElementIterator> elements(
bool jumpDeleted =
true)
622 elementBegin(jumpDeleted && mElemVec.size() != mElemNumber),
650 View<ElementIterator> elements(uint begin, uint end =
UINT_NULL)
652 assert(begin <= elementContainerSize());
653 if (end ==
UINT_NULL || end > elementContainerSize())
654 end = elementContainerSize();
655 assert(begin <= end);
656 return View(elementBegin(
false) + begin, elementBegin(
false) + end);
681 View<ConstElementIterator> elements(
bool jumpDeleted =
true)
const
684 elementBegin(jumpDeleted && mElemVec.size() != mElemNumber),
712 View<ConstElementIterator> elements(uint begin, uint end =
UINT_NULL)
const
714 assert(begin <= elementContainerSize());
715 if (end ==
UINT_NULL || end > elementContainerSize())
716 end = elementContainerSize();
717 assert(begin <= end);
718 return View(elementBegin(
false) + begin, elementBegin(
false) + end);
721 void enableAllOptionalComponents()
723 mVerticalCompVecTuple.enableAllOptionalComponents();
726 void disableAllOptionalComponents()
728 mVerticalCompVecTuple.disableAllOptionalComponents();
732 bool isComponentAvailable()
const
734 if constexpr (comp::HasComponentOfType<T, C::COMPONENT_ID>) {
736 HasOptionalComponentOfType<T, C::COMPONENT_ID>) {
737 return mVerticalCompVecTuple.template isComponentEnabled<C>();
748 template<u
int COMP_ID>
749 bool isComponentAvailable()
const
751 if constexpr (comp::HasComponentOfType<T, COMP_ID>) {
752 if constexpr (comp::HasOptionalComponentOfType<T, COMP_ID>) {
753 return mVerticalCompVecTuple
754 .template isComponentEnabled<COMP_ID>();
766 bool isOptionalComponentEnabled()
const
768 return mVerticalCompVecTuple.template isComponentEnabled<C>();
771 template<u
int COMP_ID>
772 bool isOptionalComponentEnabled()
const
774 return mVerticalCompVecTuple.template isComponentEnabled<COMP_ID>();
778 void enableOptionalComponent()
780 mVerticalCompVecTuple.template enableComponent<C>();
782 if constexpr (comp::HasInitMemberFunction<C>) {
783 for (
auto& e : elements()) {
788 if constexpr (comp::IsTiedToVertexNumber<C>) {
789 static const int N = T::VERTEX_NUMBER;
790 if constexpr (N < 0) {
791 for (
auto& e : elements()) {
792 e.C::resize(e.vertexNumber());
798 template<u
int COMP_ID>
799 void enableOptionalComponent()
801 using C = comp::ComponentOfType<COMP_ID, typename T::Components>;
802 enableOptionalComponent<C>();
806 void disableOptionalComponent()
808 mVerticalCompVecTuple.template disableComponent<C>();
811 template<u
int COMP_ID>
812 void disableOptionalComponent()
814 mVerticalCompVecTuple.template disableComponent<COMP_ID>();
819 bool hasElemCustomComponent(
const std::string& name)
const
820 requires comp::HasCustomComponents<T>
822 return mCustomCompVecMap.componentExists(name);
825 std::vector<std::string> elemCustomComponentNames() const
826 requires comp::HasCustomComponents<T>
828 return mCustomCompVecMap.allComponentNames();
832 bool isElemCustomComponentOfType(
const std::string& name)
const
833 requires comp::HasCustomComponents<T>
835 return mCustomCompVecMap.template isComponentOfType<K>(name);
838 std::type_index elemComponentType(
const std::string& name)
const
839 requires comp::HasCustomComponents<T>
841 return mCustomCompVecMap.componentType(name);
845 std::vector<std::string> elemCustomComponentNamesOfType() const
846 requires comp::HasCustomComponents<T>
848 return mCustomCompVecMap.template allComponentNamesOfType<K>();
852 void addElemCustomComponent(
const std::string& name)
853 requires comp::HasCustomComponents<T>
855 mCustomCompVecMap.template addNewComponent<K>(
856 name, elementContainerSize());
859 void deleteElemCustomComponent(
const std::string& name)
860 requires comp::HasCustomComponents<T>
862 mCustomCompVecMap.deleteComponent(name);
866 CustomComponentVectorHandle<K> customComponentVectorHandle(
867 const std::string& name)
requires comp::HasCustomComponents<T>
869 std::vector<std::any>& cc =
870 mCustomCompVecMap.template componentVector<K>(name);
871 CustomComponentVectorHandle<K> v(cc);
876 ConstCustomComponentVectorHandle<K> customComponentVectorHandle(
877 const std::string& name)
const requires comp::HasCustomComponents<T>
879 const std::vector<std::any>& cc =
880 mCustomCompVecMap.template componentVector<K>(name);
881 ConstCustomComponentVectorHandle<K> v(cc);
886 void serializePerElementCustomComponentsOfType(std::ostream& os)
const
887 requires comp::HasCustomComponents<T>
889 mCustomCompVecMap.template serializeCustomComponentsOfType<K>(os);
893 void deserializePerElementCustomComponentsOfType(std::istream& is)
894 requires comp::HasCustomComponents<T>
896 mCustomCompVecMap.template deserializeCustomComponentsOfType<K>(is);
899 uint index(
const T* e)
const
902 !mElemVec.empty() && e >= mElemVec.data() && e <= &mElemVec.back());
903 return e - mElemVec.data();
906 void setParentMeshPointers(
void* pm)
908 mParentMesh =
static_cast<ParentMeshType*
>(pm);
909 for (
auto& e : elements(false)) {
914 template<
typename Element>
915 void updateReferences(
916 const Element* oldBase,
917 uint firstElementToProcess = 0,
920 using Comps = T::Components;
922 updateReferencesOnComponents(
923 oldBase, Comps(), firstElementToProcess, offset);
926 template<
typename Element>
927 void updateReferences(
const std::vector<uint>& newIndices)
929 using Comps = T::Components;
931 updateReferencesOnComponents<Element>(newIndices, Comps());
965 void updateElementIndices(
const std::vector<uint>& newIndices)
967 mParentMesh->template updateAllReferences<T>(newIndices);
970 template<
typename OtherMesh>
971 void enableOptionalComponentsOf(
const OtherMesh& m)
973 if constexpr (OtherMesh::template hasContainerOf<T>()) {
976 using OContainer = OtherMesh::template ContainerOf<T>::type;
978 const OContainer& c =
static_cast<const OContainer&
>(m);
980 enableSameOptionalComponents(
typename T::Components(), c);
984 template<
typename OtherMesh>
985 void importFrom(
const OtherMesh& m)
987 if constexpr (OtherMesh::template hasContainerOf<T>()) {
990 using Container = OtherMesh::template ContainerOf<T>::type;
992 const Container& c = (
const Container&) m;
999 addElements(c.elementContainerSize());
1000 unsigned int eid = 0;
1001 for (
const typename Container::ElementType& e : c.elements(false)) {
1005 element(eid).importFrom(e);
1009 mElemNumber = c.mElemNumber;
1011 comp::HasCustomComponents<T> &&
1012 comp::HasCustomComponents<typename Container::ElementType>) {
1013 mCustomCompVecMap = c.mCustomCompVecMap;
1019 template<
typename ElPtr,
typename... Comps>
1020 void updateReferencesOnComponents(
1021 const ElPtr* oldBase,
1022 TypeWrapper<Comps...>,
1023 uint firstElementToProcess = 0,
1026 (updateReferencesOnComponent<Comps>(
1027 oldBase, firstElementToProcess, offset),
1031 template<
typename ElPtr,
typename... Comps>
1032 void updateReferencesOnComponents(
1033 const std::vector<uint>& newIndices,
1034 TypeWrapper<Comps...>)
1036 (updateReferencesOnComponent<Comps, ElPtr>(newIndices), ...);
1052 template<
typename Comp,
typename ElPtr>
1053 void updateReferencesOnComponent(
1054 const ElPtr* oldBase,
1055 uint firstElementToProcess = 0,
1058 if constexpr (comp::HasReferencesOfType<Comp, ElPtr>) {
1061 for (uint i = firstElementToProcess; i < elementContainerSize();
1065 e.Comp::updateReferences(oldBase, offset);
1070 if constexpr (comp::HasOptionalReferencesOfType<Comp, ElPtr>) {
1071 if (isOptionalComponentEnabled<Comp>()) {
1081 template<
typename Comp,
typename ElPtr>
1082 void updateReferencesOnComponent(
const std::vector<uint>& newIndices)
1084 if constexpr (comp::HasReferencesOfType<Comp, ElPtr>) {
1085 if constexpr (comp::HasOptionalReferencesOfType<Comp, ElPtr>) {
1086 if (isOptionalComponentEnabled<Comp>()) {
1087 for (T& e : elements()) {
1088 e.Comp::updateReferences(newIndices);
1093 for (T& e : elements()) {
1094 e.Comp::updateReferences(newIndices);
1100 template<
typename... Comps>
1101 void appendVerticalComponents(
1102 const ElementContainer<T>& other,
1103 TypeWrapper<Comps...>)
1105 (appendVerticalComponent<Comps>(other), ...);
1108 template<
typename Comp>
1109 void appendVerticalComponent(
const ElementContainer<T>& other)
1111 uint on = other.elementContainerSize();
1112 uint n = elementContainerSize() - on;
1114 if (mVerticalCompVecTuple.template isComponentEnabled<Comp>() &&
1115 other.mVerticalCompVecTuple.template isComponentEnabled<Comp>()) {
1116 auto& vc = mVerticalCompVecTuple.template vector<Comp>();
1118 other.mVerticalCompVecTuple.template vector<Comp>();
1120 for (uint i = 0; i < on; ++i) {
1126 void appendCustomComponents(
const ElementContainer<T>& other)
1128 if constexpr (comp::HasCustomComponents<T>) {
1129 uint on = other.elementContainerSize();
1130 uint n = elementContainerSize() - on;
1132 std::vector<std::string> ccNames =
1133 mCustomCompVecMap.allComponentNames();
1135 for (
const std::string& name : ccNames) {
1136 for (uint i = 0; i < on; ++i) {
1137 mCustomCompVecMap.importSameCustomComponentFrom(
1138 n + i, i, name, other.mCustomCompVecMap);
1144 template<
typename Cont2,
typename... Comps>
1145 void enableSameOptionalComponents(TypeWrapper<Comps...>,
const Cont2& c2)
1148 (enableSameOptionalComponent<Comps>(c2), ...);
1155 template<
typename Comp,
typename Cont2>
1156 void enableSameOptionalComponent(
const Cont2& c2)
1159 if constexpr (comp::IsOptionalComponent<Comp>) {
1161 if constexpr (comp::HasComponentOfType<
1162 typename Cont2::ElementType,
1163 Comp::COMPONENT_ID>) {
1165 if constexpr (comp::HasOptionalComponentOfType<
1166 typename Cont2::ElementType,
1167 Comp::COMPONENT_ID>) {
1170 if (c2.template isOptionalComponentEnabled<
1171 Comp::COMPONENT_ID>()) {
1172 enableOptionalComponent<Comp::COMPONENT_ID>();
1178 enableOptionalComponent<Comp::COMPONENT_ID>();
1198concept ElementContainerConcept =
1200 std::remove_cvref_t<T>,
1201 ElementContainer<typename RemoveRef<T>::ElementType>>;
PointT size() const
Computes the size of the box.
Definition box.h:267
constexpr uint UINT_NULL
The UINT_NULL value represent a null value of uint that is the maximum value that can be represented ...
Definition base.h:48