23#ifndef VCL_MESH_CONTAINERS_ELEMENT_CONTAINER_H
24#define VCL_MESH_CONTAINERS_ELEMENT_CONTAINER_H
26#include "custom_component_vector_handle.h"
27#include "custom_components_vector_map.h"
28#include "vertical_components_vector_tuple.h"
30#include <vclib/concepts/mesh/components.h>
31#include <vclib/concepts/mesh/containers.h>
32#include <vclib/concepts/mesh/elements/element.h>
33#include <vclib/io/serialization.h>
34#include <vclib/mesh/components/bases/component.h>
35#include <vclib/mesh/iterators/element_container_iterator.h>
36#include <vclib/types/view.h>
43template<ElementConcept T>
44class ElementContainer :
public ElementContainerTriggerer
46 template<ElementConcept U>
47 friend class ElementContainer;
49 using ElementContainerType = ElementContainer<T>;
52 using vComps = FilterTypesByCondition<
53 comp::IsVerticalComponentPred,
54 typename T::Components>::type;
57 using ElementType = T;
58 using ParentMeshType = T::ParentMeshType;
61 ParentMeshType* mParentMesh =
nullptr;
75 std::vector<T> mElemVec;
82 VerticalComponentsVectorTuple<vComps> mVerticalCompVecTuple;
88 CustomComponentsVectorMap<comp::HasCustomComponents<T>> mCustomCompVecMap;
91 static const uint ELEMENT_ID = T::ELEMENT_ID;
96 ElementContainer() =
default;
100 using ElementIterator = ElementContainerIterator<std::vector, T>;
101 using ConstElementIterator = ConstElementContainerIterator<std::vector, T>;
114 const T& element(uint i)
const
116 assert(i < mElemVec.size());
133 assert(i < mElemVec.size());
146 uint elementNumber()
const {
return mElemNumber; }
157 uint elementContainerSize()
const {
return mElemVec.size(); }
165 uint deletedElementNumber()
const
167 return elementContainerSize() - elementNumber();
172 mVerticalCompVecTuple.resize(mElemVec.size() + 1);
173 if constexpr (comp::HasCustomComponents<T>)
174 mCustomCompVecMap.resize(mElemVec.size() + 1);
176 T* oldB = mElemVec.data();
177 mElemVec.emplace_back();
178 T* newB = mElemVec.data();
181 mElemVec.back().setParentMesh(mParentMesh);
182 mElemVec.back().initVerticalComponents();
185 setParentMeshPointers(mParentMesh);
186 mParentMesh->updateAllReferences(oldB);
189 return mElemVec.size() - 1;
200 uint addElements(uint size)
202 mVerticalCompVecTuple.resize(mElemVec.size() + size);
203 if constexpr (comp::HasCustomComponents<T>)
204 mCustomCompVecMap.resize(mElemVec.size() + size);
206 uint baseId = mElemVec.size();
207 T* oldB = mElemVec.data();
208 mElemVec.resize(mElemVec.size() + size);
209 T* newB = mElemVec.data();
212 for (uint i = baseId; i < mElemVec.size(); ++i) {
213 mElemVec[i].setParentMesh(mParentMesh);
214 mElemVec[i].initVerticalComponents();
218 setParentMeshPointers(mParentMesh);
219 mParentMesh->updateAllReferences(oldB);
232 mVerticalCompVecTuple.clear();
233 if constexpr (comp::HasCustomComponents<T>)
234 mCustomCompVecMap.clear();
265 void resizeElements(uint size)
267 if (size > mElemNumber) {
268 addElements(size - mElemNumber);
270 else if (size < mElemNumber) {
271 uint nToDelete = mElemNumber - size;
272 for (uint i = mElemVec.size() - 1; nToDelete > 0; --i) {
273 if (!mElemVec[i].deleted()) {
280 void reserveElements(uint size)
282 T* oldB = mElemVec.data();
283 mElemVec.reserve(size);
284 T* newB = mElemVec.data();
286 mVerticalCompVecTuple.reserve(size);
287 if constexpr (comp::HasCustomComponents<T>)
288 mCustomCompVecMap.reserve(size);
291 setParentMeshPointers(mParentMesh);
292 mParentMesh->updateAllReferences(oldB);
303 std::vector<uint> compactElements()
305 std::vector<uint> newIndices = elementCompactIndices();
306 if (elementNumber() != elementContainerSize()) {
307 compactVector(mElemVec, newIndices);
309 mVerticalCompVecTuple.compact(newIndices);
310 if constexpr (comp::HasCustomComponents<T>)
311 mCustomCompVecMap.compact(newIndices);
313 updateElementIndices(newIndices);
333 void deleteElement(uint i)
335 assert(i < mElemVec.size());
336 mElemVec[i].deletedBit() =
true;
356 void deleteElement(
const T* e) { deleteElement(index(e)); }
371 uint elementIndexIfCompact(uint i)
const
373 assert(i < mElemVec.size());
374 if (mElemVec.size() == mElemNumber)
378 for (uint ii = 0; ii < i; ii++) {
379 if (!mElemVec[ii].deleted())
397 std::vector<uint> elementCompactIndices()
const
399 std::vector<uint> newIndices(mElemVec.size());
401 for (uint i = 0; i < mElemVec.size(); ++i) {
402 if (!mElemVec[i].deleted()) {
427 void append(
const ElementContainer<T>& other)
429 using Comps = T::Components;
431 uint on = other.elementNumber();
432 uint n = elementContainerSize();
434 for (uint i = 0; i < on; ++i) {
437 element(n + i) = other.element(i);
438 element(n + i).setParentMesh(mParentMesh);
441 appendVerticalComponents(other, vComps());
442 appendCustomComponents(other);
455 void serializeOptionalComponentsAndElementsNumber(std::ostream& out)
const
457 constexpr uint N_VERT_COMPS = vComps::size();
458 std::array<bool, N_VERT_COMPS> enabledComps;
461 auto forEachVertComp = [&]<
typename Comp>() {
463 mVerticalCompVecTuple.template isComponentEnabled<Comp>();
467 ForEachType<vComps>::apply(forEachVertComp);
469 vcl::serialize(out, elementContainerSize());
470 vcl::serialize(out, enabledComps);
481 void serializeElements(std::ostream& out)
const
483 for (
const auto& e : mElemVec) {
498 void deserializeOptionalComponentsAndElementsNumber(std::istream& in)
500 constexpr uint N_VERT_COMPS = vComps::size();
501 std::array<bool, N_VERT_COMPS> enabledComps;
504 vcl::deserialize(in, size);
505 vcl::deserialize(in, enabledComps);
507 resizeElements(size);
510 auto forEachVertComp = [&]<
typename Comp>() {
512 mVerticalCompVecTuple.template enableComponent<Comp>();
514 mVerticalCompVecTuple.template disableComponent<Comp>();
518 ForEachType<vComps>::apply(forEachVertComp);
529 void deserializeElements(std::istream& in)
531 for (
auto& e : mElemVec) {
547 ElementIterator elementBegin(
bool jumpDeleted =
true)
549 auto it = mElemVec.begin();
554 while (it != mElemVec.end() && it->deleted()) {
558 return ElementIterator(
559 it, mElemVec, jumpDeleted && mElemVec.size() != mElemNumber);
566 ElementIterator elementEnd()
568 return ElementIterator(mElemVec.end(), mElemVec);
582 ConstElementIterator elementBegin(
bool jumpDeleted =
true)
const
584 auto it = mElemVec.begin();
589 while (it != mElemVec.end() && it->deleted()) {
593 return ConstElementIterator(
594 it, mElemVec, jumpDeleted && mElemVec.size() != mElemNumber);
601 ConstElementIterator elementEnd()
const
603 return ConstElementIterator(mElemVec.end(), mElemVec);
628 View<ElementIterator> elements(
bool jumpDeleted =
true)
631 elementBegin(jumpDeleted && mElemVec.size() != mElemNumber),
657 View<ConstElementIterator> elements(
bool jumpDeleted =
true)
const
660 elementBegin(jumpDeleted && mElemVec.size() != mElemNumber),
664 void enableAllOptionalComponents()
666 mVerticalCompVecTuple.enableAllOptionalComponents();
669 void disableAllOptionalComponents()
671 mVerticalCompVecTuple.disableAllOptionalComponents();
675 bool isOptionalComponentEnabled()
const
677 return mVerticalCompVecTuple.template isComponentEnabled<C>();
680 template<u
int COMP_ID>
681 bool isOptionalComponentEnabled()
const
683 return mVerticalCompVecTuple.template isComponentEnabled<COMP_ID>();
687 void enableOptionalComponent()
689 mVerticalCompVecTuple.template enableComponent<C>();
691 if constexpr (comp::HasInitMemberFunction<C>) {
692 for (
auto& e : elements()) {
697 if constexpr (comp::IsTiedToVertexNumber<C>) {
698 static const int N = T::VERTEX_NUMBER;
699 if constexpr (N < 0) {
700 for (
auto& e : elements()) {
701 e.C::resize(e.vertexNumber());
707 template<u
int COMP_ID>
708 void enableOptionalComponent()
710 using C = comp::ComponentOfType<COMP_ID, typename T::Components>;
711 enableOptionalComponent<C>();
715 void disableOptionalComponent()
717 mVerticalCompVecTuple.template disableComponent<C>();
720 template<u
int COMP_ID>
721 void disableOptionalComponent()
723 mVerticalCompVecTuple.template disableComponent<COMP_ID>();
728 bool hasElemCustomComponent(
const std::string& name)
const
729 requires comp::HasCustomComponents<T>
731 return mCustomCompVecMap.componentExists(name);
734 std::vector<std::string> elemCustomComponentNames() const
735 requires comp::HasCustomComponents<T>
737 return mCustomCompVecMap.allComponentNames();
741 bool isElemCustomComponentOfType(
const std::string& name)
const
742 requires comp::HasCustomComponents<T>
744 return mCustomCompVecMap.template isComponentOfType<K>(name);
747 std::type_index elemComponentType(
const std::string& name)
const
748 requires comp::HasCustomComponents<T>
750 return mCustomCompVecMap.componentType(name);
754 std::vector<std::string> elemCustomComponentNamesOfType() const
755 requires comp::HasCustomComponents<T>
757 return mCustomCompVecMap.template allComponentNamesOfType<K>();
761 void addElemCustomComponent(
const std::string& name)
762 requires comp::HasCustomComponents<T>
764 mCustomCompVecMap.template addNewComponent<K>(
765 name, elementContainerSize());
768 void deleteElemCustomComponent(
const std::string& name)
769 requires comp::HasCustomComponents<T>
771 mCustomCompVecMap.deleteComponent(name);
775 CustomComponentVectorHandle<K> customComponentVectorHandle(
776 const std::string& name)
requires comp::HasCustomComponents<T>
778 std::vector<std::any>& cc =
779 mCustomCompVecMap.template componentVector<K>(name);
780 CustomComponentVectorHandle<K> v(cc);
785 ConstCustomComponentVectorHandle<K> customComponentVectorHandle(
786 const std::string& name)
const requires comp::HasCustomComponents<T>
788 const std::vector<std::any>& cc =
789 mCustomCompVecMap.template componentVector<K>(name);
790 ConstCustomComponentVectorHandle<K> v(cc);
794 uint index(
const T* e)
const
797 !mElemVec.empty() && e >= mElemVec.data() && e <= &mElemVec.back());
798 return e - mElemVec.data();
801 void setParentMeshPointers(
void* pm)
803 mParentMesh =
static_cast<ParentMeshType*
>(pm);
804 for (
auto& e : elements(false)) {
809 template<
typename Element>
810 void updateReferences(
811 const Element* oldBase,
812 uint firstElementToProcess = 0,
815 using Comps = T::Components;
817 updateReferencesOnComponents(
818 oldBase, Comps(), firstElementToProcess, offset);
821 template<
typename Element>
822 void updateReferences(
const std::vector<uint>& newIndices)
824 using Comps = T::Components;
826 updateReferencesOnComponents<Element>(newIndices, Comps());
860 void updateElementIndices(
const std::vector<uint>& newIndices)
862 mParentMesh->template updateAllReferences<T>(newIndices);
865 template<
typename OtherMesh>
866 void enableOptionalComponentsOf(
const OtherMesh& m)
868 if constexpr (OtherMesh::template hasContainerOf<T>()) {
871 using OContainer = OtherMesh::template ContainerOf<T>::type;
873 const OContainer& c =
static_cast<const OContainer&
>(m);
875 enableSameOptionalComponents(
typename T::Components(), c);
879 template<
typename OtherMesh>
880 void importFrom(
const OtherMesh& m)
882 if constexpr (OtherMesh::template hasContainerOf<T>()) {
885 using Container = OtherMesh::template ContainerOf<T>::type;
887 const Container& c = (
const Container&) m;
894 addElements(c.elementContainerSize());
895 unsigned int eid = 0;
896 for (
const typename Container::ElementType& e : c.elements(false)) {
900 element(eid).importFrom(e);
904 mElemNumber = c.mElemNumber;
906 comp::HasCustomComponents<T> &&
907 comp::HasCustomComponents<typename Container::ElementType>) {
908 mCustomCompVecMap = c.mCustomCompVecMap;
914 template<
typename ElPtr,
typename... Comps>
915 void updateReferencesOnComponents(
916 const ElPtr* oldBase,
917 TypeWrapper<Comps...>,
918 uint firstElementToProcess = 0,
921 (updateReferencesOnComponent<Comps>(
922 oldBase, firstElementToProcess, offset),
926 template<
typename ElPtr,
typename... Comps>
927 void updateReferencesOnComponents(
928 const std::vector<uint>& newIndices,
929 TypeWrapper<Comps...>)
931 (updateReferencesOnComponent<Comps, ElPtr>(newIndices), ...);
947 template<
typename Comp,
typename ElPtr>
948 void updateReferencesOnComponent(
949 const ElPtr* oldBase,
950 uint firstElementToProcess = 0,
953 if constexpr (comp::HasReferencesOfType<Comp, ElPtr>) {
956 for (uint i = firstElementToProcess; i < elementContainerSize();
960 e.Comp::updateReferences(oldBase, offset);
965 if constexpr (comp::HasOptionalReferencesOfType<Comp, ElPtr>) {
966 if (isOptionalComponentEnabled<Comp>()) {
976 template<
typename Comp,
typename ElPtr>
977 void updateReferencesOnComponent(
const std::vector<uint>& newIndices)
979 if constexpr (comp::HasReferencesOfType<Comp, ElPtr>) {
980 if constexpr (comp::HasOptionalReferencesOfType<Comp, ElPtr>) {
981 if (isOptionalComponentEnabled<Comp>()) {
982 for (T& e : elements()) {
983 e.Comp::updateReferences(newIndices);
988 for (T& e : elements()) {
989 e.Comp::updateReferences(newIndices);
995 template<
typename... Comps>
996 void appendVerticalComponents(
997 const ElementContainer<T>& other,
998 TypeWrapper<Comps...>)
1000 (appendVerticalComponent<Comps>(other), ...);
1003 template<
typename Comp>
1004 void appendVerticalComponent(
const ElementContainer<T>& other)
1006 uint on = other.elementNumber();
1007 uint n = elementContainerSize() - on;
1009 if (mVerticalCompVecTuple.template isComponentEnabled<Comp>() &&
1010 other.mVerticalCompVecTuple.template isComponentEnabled<Comp>()) {
1011 auto& vc = mVerticalCompVecTuple.template vector<Comp>();
1013 other.mVerticalCompVecTuple.template vector<Comp>();
1015 for (uint i = 0; i < on; ++i) {
1021 void appendCustomComponents(
const ElementContainer<T>& other)
1023 if constexpr (comp::HasCustomComponents<T>) {
1024 uint on = other.elementNumber();
1025 uint n = elementContainerSize() - on;
1027 std::vector<std::string> ccNames =
1028 mCustomCompVecMap.allComponentNames();
1030 for (
const std::string& name : ccNames) {
1031 for (uint i = 0; i < on; ++i) {
1032 mCustomCompVecMap.importSameCustomComponentFrom(
1033 n + i, i, name, other.mCustomCompVecMap);
1039 template<
typename Cont2,
typename... Comps>
1040 void enableSameOptionalComponents(TypeWrapper<Comps...>,
const Cont2& c2)
1043 (enableSameOptionalComponent<Comps>(c2), ...);
1050 template<
typename Comp,
typename Cont2>
1051 void enableSameOptionalComponent(
const Cont2& c2)
1054 if constexpr (comp::IsOptionalComponent<Comp>) {
1056 if constexpr (comp::HasComponentOfType<
1057 typename Cont2::ElementType,
1058 Comp::COMPONENT_ID>) {
1060 if constexpr (comp::HasOptionalComponentOfType<
1061 typename Cont2::ElementType,
1062 Comp::COMPONENT_ID>) {
1065 if (c2.template isOptionalComponentEnabled<
1066 Comp::COMPONENT_ID>()) {
1067 enableOptionalComponent<Comp::COMPONENT_ID>();
1073 enableOptionalComponent<Comp::COMPONENT_ID>();
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