diff --git a/Sofa/Component/Engine/Generate/CMakeLists.txt b/Sofa/Component/Engine/Generate/CMakeLists.txt
index 62df2348889..e7fecbb054b 100644
--- a/Sofa/Component/Engine/Generate/CMakeLists.txt
+++ b/Sofa/Component/Engine/Generate/CMakeLists.txt
@@ -24,6 +24,8 @@ set(HEADER_FILES
${SOFACOMPONENTENGINEGENERATE_SOURCE_DIR}/GroupFilterYoungModulus.inl
${SOFACOMPONENTENGINEGENERATE_SOURCE_DIR}/JoinPoints.h
${SOFACOMPONENTENGINEGENERATE_SOURCE_DIR}/JoinPoints.inl
+ ${SOFACOMPONENTENGINEGENERATE_SOURCE_DIR}/LinearToHigherOrderElements.h
+ ${SOFACOMPONENTENGINEGENERATE_SOURCE_DIR}/LinearToHigherOrderElements.inl
${SOFACOMPONENTENGINEGENERATE_SOURCE_DIR}/MergeMeshes.h
${SOFACOMPONENTENGINEGENERATE_SOURCE_DIR}/MergeMeshes.inl
${SOFACOMPONENTENGINEGENERATE_SOURCE_DIR}/MergePoints.h
@@ -62,6 +64,7 @@ set(SOURCE_FILES
${SOFACOMPONENTENGINEGENERATE_SOURCE_DIR}/GenerateSphere.cpp
${SOFACOMPONENTENGINEGENERATE_SOURCE_DIR}/GroupFilterYoungModulus.cpp
${SOFACOMPONENTENGINEGENERATE_SOURCE_DIR}/JoinPoints.cpp
+ ${SOFACOMPONENTENGINEGENERATE_SOURCE_DIR}/LinearToHigherOrderElements.cpp
${SOFACOMPONENTENGINEGENERATE_SOURCE_DIR}/MergeMeshes.cpp
${SOFACOMPONENTENGINEGENERATE_SOURCE_DIR}/MergePoints.cpp
${SOFACOMPONENTENGINEGENERATE_SOURCE_DIR}/MergeSets.cpp
diff --git a/Sofa/Component/Engine/Generate/src/sofa/component/engine/generate/LinearToHigherOrderElements.cpp b/Sofa/Component/Engine/Generate/src/sofa/component/engine/generate/LinearToHigherOrderElements.cpp
new file mode 100644
index 00000000000..eca84271cab
--- /dev/null
+++ b/Sofa/Component/Engine/Generate/src/sofa/component/engine/generate/LinearToHigherOrderElements.cpp
@@ -0,0 +1,35 @@
+/******************************************************************************
+* SOFA, Simulation Open-Framework Architecture *
+* (c) 2006 INRIA, USTL, UJF, CNRS, MGH *
+* *
+* This program is free software; you can redistribute it and/or modify it *
+* under the terms of the GNU Lesser General Public License as published by *
+* the Free Software Foundation; either version 2.1 of the License, or (at *
+* your option) any later version. *
+* *
+* This program is distributed in the hope that it will be useful, but WITHOUT *
+* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or *
+* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License *
+* for more details. *
+* *
+* You should have received a copy of the GNU Lesser General Public License *
+* along with this program. If not, see . *
+*******************************************************************************
+* Authors: The SOFA Team and external contributors (see Authors.txt) *
+* *
+* Contact information: contact@sofa-framework.org *
+******************************************************************************/
+#include
+#include
+
+namespace sofa::component::engine::generate
+{
+
+void registerLinearToHigherOrderElements(sofa::core::ObjectFactory* factory)
+{
+ factory->registerObjects(core::ObjectRegistrationData("Merge several meshes.")
+ .add< LinearToHigherOrderElements >(true)
+ );
+}
+
+}
diff --git a/Sofa/Component/Engine/Generate/src/sofa/component/engine/generate/LinearToHigherOrderElements.h b/Sofa/Component/Engine/Generate/src/sofa/component/engine/generate/LinearToHigherOrderElements.h
new file mode 100644
index 00000000000..a5056c2087a
--- /dev/null
+++ b/Sofa/Component/Engine/Generate/src/sofa/component/engine/generate/LinearToHigherOrderElements.h
@@ -0,0 +1,71 @@
+/******************************************************************************
+* SOFA, Simulation Open-Framework Architecture *
+* (c) 2006 INRIA, USTL, UJF, CNRS, MGH *
+* *
+* This program is free software; you can redistribute it and/or modify it *
+* under the terms of the GNU Lesser General Public License as published by *
+* the Free Software Foundation; either version 2.1 of the License, or (at *
+* your option) any later version. *
+* *
+* This program is distributed in the hope that it will be useful, but WITHOUT *
+* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or *
+* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License *
+* for more details. *
+* *
+* You should have received a copy of the GNU Lesser General Public License *
+* along with this program. If not, see . *
+*******************************************************************************
+* Authors: The SOFA Team and external contributors (see Authors.txt) *
+* *
+* Contact information: contact@sofa-framework.org *
+******************************************************************************/
+#pragma once
+#include
+#include
+#include
+#include
+
+namespace sofa::component::engine::generate
+{
+
+template
+class LinearToHigherOrderElements :
+ public sofa::core::DataEngine,
+ public sofa::core::behavior::TopologyAccessor,
+ public sofa::core::behavior::SingleStateAccessor
+{
+public:
+ SOFA_CLASS3(LinearToHigherOrderElements,
+ sofa::core::DataEngine,
+ sofa::core::behavior::TopologyAccessor,
+ sofa::core::behavior::SingleStateAccessor);
+
+ template //e.g. sofa::geometry::Edge
+ using TopologyElement = sofa::topology::Element;
+
+ template //e.g. sofa::geometry::Edge
+ using SeqElement = sofa::type::vector>;
+
+ void init() override;
+
+ sofa::DataVecCoord_t d_position;
+
+ Data> d_quadraticEdges;
+ Data> d_quadraticTriangles;
+ Data> d_quadraticQuads;
+ Data> d_quadraticTetrahedra;
+ Data> d_quadraticHexahedra;
+
+ Data d_computeFromEdges;
+ Data d_computeFromTriangles;
+ Data d_computeFromQuads;
+ Data d_computeFromTetrahedra;
+ Data d_computeFromHexahedra;
+
+protected:
+ void doUpdate() override;
+
+ LinearToHigherOrderElements();
+};
+
+} // namespace sofa::component::engine::generate
diff --git a/Sofa/Component/Engine/Generate/src/sofa/component/engine/generate/LinearToHigherOrderElements.inl b/Sofa/Component/Engine/Generate/src/sofa/component/engine/generate/LinearToHigherOrderElements.inl
new file mode 100644
index 00000000000..bc7596535dc
--- /dev/null
+++ b/Sofa/Component/Engine/Generate/src/sofa/component/engine/generate/LinearToHigherOrderElements.inl
@@ -0,0 +1,226 @@
+/******************************************************************************
+* SOFA, Simulation Open-Framework Architecture *
+* (c) 2006 INRIA, USTL, UJF, CNRS, MGH *
+* *
+* This program is free software; you can redistribute it and/or modify it *
+* under the terms of the GNU Lesser General Public License as published by *
+* the Free Software Foundation; either version 2.1 of the License, or (at *
+* your option) any later version. *
+* *
+* This program is distributed in the hope that it will be useful, but WITHOUT *
+* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or *
+* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License *
+* for more details. *
+* *
+* You should have received a copy of the GNU Lesser General Public License *
+* along with this program. If not, see . *
+*******************************************************************************
+* Authors: The SOFA Team and external contributors (see Authors.txt) *
+* *
+* Contact information: contact@sofa-framework.org *
+******************************************************************************/
+#pragma once
+#include
+#include
+
+namespace sofa::component::engine::generate
+{
+
+template
+LinearToHigherOrderElements::LinearToHigherOrderElements()
+ : d_position(initData(&d_position, sofa::VecCoord_t{}, "position", "Output position"))
+ , d_quadraticEdges(initData(&d_quadraticEdges, SeqElement{},
+ "quadratic_edges", "List of quadratic edges"))
+ , d_quadraticTriangles(initData(&d_quadraticTriangles, SeqElement{},
+ "quadratic_triangles", "List of quadratic triangles"))
+ , d_quadraticQuads(initData(&d_quadraticQuads, SeqElement{},
+ "quadratic_quads", "List of quadratic quads"))
+ , d_quadraticTetrahedra(initData(&d_quadraticTetrahedra, SeqElement{},
+ "quadratic_tetrahedra", "List of quadratic tetrahedra"))
+ , d_quadraticHexahedra(initData(&d_quadraticHexahedra, SeqElement{},
+ "quadratic_hexahedra", "List of quadratic hexahedra"))
+ , d_computeFromEdges(initData(&d_computeFromEdges, true, "computeFromEdges",
+ "Use edges from the input to generate higher-order edges"))
+ , d_computeFromTriangles(initData(&d_computeFromTriangles, true, "computeFromTriangles",
+ "Use triangles from the input to generate higher-order triangles"))
+ , d_computeFromQuads(initData(&d_computeFromQuads, true, "computeFromQuads",
+ "Use quads from the input to generate higher-order quads"))
+ , d_computeFromTetrahedra(initData(&d_computeFromTetrahedra, true, "computeFromTetrahedra",
+ "Use tetrahedra from the input to generate higher-order tetrahedra"))
+ , d_computeFromHexahedra(initData(&d_computeFromHexahedra, true, "computeFromHexahedra",
+ "Use hexahedra from the input to generate higher-order hexahedra"))
+{
+ this->addOutput(&d_position);
+ this->addOutput(&d_quadraticEdges);
+ this->addOutput(&d_quadraticTriangles);
+ this->addOutput(&d_quadraticQuads);
+ this->addOutput(&d_quadraticTetrahedra);
+ this->addOutput(&d_quadraticHexahedra);
+}
+
+template
+void LinearToHigherOrderElements::init()
+{
+ DataEngine::init();
+
+ if (!this->isComponentStateInvalid())
+ {
+ this->validateTopology();
+ }
+
+ if (!this->isComponentStateInvalid())
+ {
+ sofa::core::behavior::SingleStateAccessor::init();
+ }
+}
+
+
+struct TetrahedronEdge
+{
+ TetrahedronEdge(sofa::Index p, sofa::Index q) : a(std::min(p, q)), b(std::max(p, q)) {}
+ sofa::Index a, b;
+ bool operator==(const TetrahedronEdge& e) const
+ {
+ return a == e.a && b == e.b;
+ }
+};
+
+struct Face {
+ std::array indices;
+ Face(sofa::Index a, sofa::Index b, sofa::Index c, sofa::Index d) {
+ indices = {a, b, c, d};
+ std::sort(indices.begin(), indices.end());
+ }
+ bool operator==(const Face& other) const { return indices == other.indices; }
+};
+
+
+template
+void LinearToHigherOrderElements::doUpdate()
+{
+ if (!l_topology)
+ return;
+
+ //input elements
+ const auto& edges = l_topology->getElements();
+ const auto& triangles = l_topology->getElements();
+ const auto& quads = l_topology->getElements();
+ const auto& tetrahedra = l_topology->getElements();
+ const auto& hexahedra = l_topology->getElements();
+
+ //input position
+ const auto inPosition = this->mstate->readPositions();
+
+ //output elements
+ auto quadraticEdges = sofa::helper::getWriteOnlyAccessor(d_quadraticEdges);
+ auto quadraticTriangles = sofa::helper::getWriteOnlyAccessor(d_quadraticTriangles);
+ auto quadraticQuads = sofa::helper::getWriteOnlyAccessor(d_quadraticQuads);
+ auto quadraticTetrahedra = sofa::helper::getWriteOnlyAccessor(d_quadraticTetrahedra);
+ auto quadraticHexahedra = sofa::helper::getWriteOnlyAccessor(d_quadraticHexahedra);
+
+ //output position
+ auto outPosition = sofa::helper::getWriteOnlyAccessor(d_position);
+ outPosition.wref() = inPosition.ref();
+
+ auto edgeHash = [&inPosition](const TetrahedronEdge& edge){ return edge.a + inPosition.size() * edge.b; };
+ std::unordered_map midEdgePointsMap(10, edgeHash);
+
+ auto getOrAddMidEdgePoint = [&](sofa::Index a, sofa::Index b)
+ {
+ TetrahedronEdge edge{a, b};
+ const auto [it, success] = midEdgePointsMap.insert(std::make_pair(edge, outPosition.size()));
+ if (success)
+ {
+ outPosition.push_back(0.5 * (inPosition[a] + inPosition[b]));
+ }
+ return it->second;
+ };
+
+ auto faceHash = [](const Face& f) {
+ size_t h = 0;
+ for (auto i : f.indices) h ^= std::hash{}(i) + 0x9e3779b9 + (h << 6) + (h >> 2);
+ return h;
+ };
+ std::unordered_map midFacePointsMap(10, faceHash);
+
+ auto getOrAddMidFacePoint = [&](sofa::Index a, sofa::Index b, sofa::Index c, sofa::Index d)
+ {
+ Face face{a, b, c, d};
+ const auto [it, success] = midFacePointsMap.insert(std::make_pair(face, outPosition.size()));
+ if (success)
+ {
+ outPosition.push_back(0.25 * (inPosition[a] + inPosition[b] + inPosition[c] + inPosition[d]));
+ }
+ return it->second;
+ };
+
+ if (d_computeFromEdges.getValue())
+ for (const auto& element : edges)
+ {
+ quadraticEdges.emplace_back(element[0], element[1], getOrAddMidEdgePoint(element[0], element[1]));
+ }
+
+ if (d_computeFromTriangles.getValue())
+ for (const auto& element : triangles)
+ {
+ quadraticTriangles.emplace_back(element[0], element[1], element[2],
+ getOrAddMidEdgePoint(element[0], element[1]),
+ getOrAddMidEdgePoint(element[1], element[2]),
+ getOrAddMidEdgePoint(element[2], element[0]));
+ }
+
+ if (d_computeFromQuads.getValue())
+ for (const auto& element : quads)
+ {
+ quadraticQuads.emplace_back(element[0], element[1], element[2], element[3],
+ getOrAddMidEdgePoint(element[0], element[1]),
+ getOrAddMidEdgePoint(element[1], element[2]),
+ getOrAddMidEdgePoint(element[2], element[3]),
+ getOrAddMidEdgePoint(element[3], element[0]),
+ getOrAddMidFacePoint(element[0], element[1], element[2], element[3]));
+ }
+
+ if (d_computeFromTetrahedra.getValue())
+ for (const auto& element : tetrahedra)
+ {
+ std::array newIndices;
+ for (std::size_t i = 0; i < 6; ++i)
+ {
+ const auto [a, b] = core::topology::edgesInTetrahedronArray[i];
+ newIndices[i] = getOrAddMidEdgePoint(element[a], element[b]);
+ }
+
+ quadraticTetrahedra.emplace_back(element[0], element[1], element[2], element[3],
+ newIndices[0], newIndices[1], newIndices[2], newIndices[3],
+ newIndices[4], newIndices[5]);
+ }
+
+ if (d_computeFromHexahedra.getValue())
+ for (const auto& element : hexahedra)
+ {
+ std::array midEdges;
+ for (std::size_t i = 0; i < 12; ++i)
+ {
+ midEdges[i] =
+ getOrAddMidEdgePoint(element[core::topology::edgesInHexahedronArray[i][0]],
+ element[core::topology::edgesInHexahedronArray[i][1]]);
+ }
+
+ std::array midFaces;
+ for (std::size_t i = 0; i < 6; ++i)
+ {
+ const auto quad = core::topology::quadsOrientationInHexahedronArray[i];
+ midFaces[i] = getOrAddMidFacePoint(element[quad[0]], element[quad[1]], element[quad[2]], element[quad[3]]);
+ }
+
+ sofa::Index midVolume = outPosition.size();
+ outPosition.push_back(0.125 * (inPosition[element[0]] + inPosition[element[1]] + inPosition[element[2]] + inPosition[element[3]] +
+ inPosition[element[4]] + inPosition[element[5]] + inPosition[element[6]] + inPosition[element[7]]));
+
+ quadraticHexahedra.emplace_back(element[0], element[1], element[2], element[3], element[4], element[5], element[6], element[7],
+ midEdges[0], midEdges[1], midEdges[2], midEdges[3], midEdges[4], midEdges[5], midEdges[6], midEdges[7], midEdges[8], midEdges[9], midEdges[10], midEdges[11],
+ midFaces[0], midFaces[1], midFaces[2], midFaces[3], midFaces[4], midFaces[5], midVolume);
+ }
+}
+
+} // namespace sofa::component::engine::generate
diff --git a/Sofa/Component/Engine/Generate/src/sofa/component/engine/generate/init.cpp b/Sofa/Component/Engine/Generate/src/sofa/component/engine/generate/init.cpp
index ebdca5b8b3c..be36cc6d2c1 100644
--- a/Sofa/Component/Engine/Generate/src/sofa/component/engine/generate/init.cpp
+++ b/Sofa/Component/Engine/Generate/src/sofa/component/engine/generate/init.cpp
@@ -35,6 +35,7 @@ extern void registerGenerateRigidMass(sofa::core::ObjectFactory* factory);
extern void registerGenerateSphere(sofa::core::ObjectFactory* factory);
extern void registerGroupFilterYoungModulus(sofa::core::ObjectFactory* factory);
extern void registerJoinPoints(sofa::core::ObjectFactory* factory);
+extern void registerLinearToHigherOrderElements(sofa::core::ObjectFactory* factory);
extern void registerMergeMeshes(sofa::core::ObjectFactory* factory);
extern void registerMergePoints(sofa::core::ObjectFactory* factory);
extern void registerMergeSets(sofa::core::ObjectFactory* factory);
@@ -42,12 +43,12 @@ extern void registerMergeVectors(sofa::core::ObjectFactory* factory);
extern void registerMeshBarycentricMapperEngine(sofa::core::ObjectFactory* factory);
extern void registerMeshClosingEngine(sofa::core::ObjectFactory* factory);
extern void registerMeshTetraStuffing(sofa::core::ObjectFactory* factory);
-extern void registerNormalsFromPoints(sofa::core::ObjectFactory* factory);
extern void registerNormEngine(sofa::core::ObjectFactory* factory);
+extern void registerNormalsFromPoints(sofa::core::ObjectFactory* factory);
extern void registerRandomPointDistributionInSurface(sofa::core::ObjectFactory* factory);
extern void registerSpiral(sofa::core::ObjectFactory* factory);
-extern void registerVolumeFromTriangles(sofa::core::ObjectFactory* factory);
extern void registerVolumeFromTetrahedrons(sofa::core::ObjectFactory* factory);
+extern void registerVolumeFromTriangles(sofa::core::ObjectFactory* factory);
extern "C" {
SOFA_EXPORT_DYNAMIC_LIBRARY void initExternalModule();
@@ -82,6 +83,7 @@ void registerObjects(sofa::core::ObjectFactory* factory)
registerGenerateSphere(factory);
registerGroupFilterYoungModulus(factory);
registerJoinPoints(factory);
+ registerLinearToHigherOrderElements(factory);
registerMergeMeshes(factory);
registerMergePoints(factory);
registerMergeSets(factory);
diff --git a/Sofa/Component/Mass/src/sofa/component/mass/FEMMass.cpp b/Sofa/Component/Mass/src/sofa/component/mass/FEMMass.cpp
index fc194d76fde..9e52da4fa7f 100644
--- a/Sofa/Component/Mass/src/sofa/component/mass/FEMMass.cpp
+++ b/Sofa/Component/Mass/src/sofa/component/mass/FEMMass.cpp
@@ -40,6 +40,18 @@ template class SOFA_COMPONENT_MASS_API FEMMass;
template class SOFA_COMPONENT_MASS_API FEMMass;
+template class SOFA_COMPONENT_MASS_API FEMMass;
+template class SOFA_COMPONENT_MASS_API FEMMass;
+template class SOFA_COMPONENT_MASS_API FEMMass;
+template class SOFA_COMPONENT_MASS_API FEMMass;
+template class SOFA_COMPONENT_MASS_API FEMMass;
+template class SOFA_COMPONENT_MASS_API FEMMass;
+template class SOFA_COMPONENT_MASS_API FEMMass;
+template class SOFA_COMPONENT_MASS_API FEMMass;
+template class SOFA_COMPONENT_MASS_API FEMMass;
+template class SOFA_COMPONENT_MASS_API FEMMass;
+template class SOFA_COMPONENT_MASS_API FEMMass;
+
void registerFEMMass(sofa::core::ObjectFactory* factory)
{
factory->registerObjects(sofa::core::ObjectRegistrationData("Finite-element mass (inertia and body force)")
@@ -54,6 +66,18 @@ void registerFEMMass(sofa::core::ObjectFactory* factory)
.add< FEMMass >()
.add< FEMMass >()
.add< FEMMass >()
+
+ .add< FEMMass >()
+ .add< FEMMass >()
+ .add< FEMMass >()
+ .add< FEMMass >()
+ .add< FEMMass >()
+ .add< FEMMass >()
+ .add< FEMMass >()
+ .add< FEMMass >()
+ .add< FEMMass >()
+ .add< FEMMass >()
+ .add< FEMMass >()
);
}
diff --git a/Sofa/Component/Mass/src/sofa/component/mass/FEMMass.h b/Sofa/Component/Mass/src/sofa/component/mass/FEMMass.h
index 46eab79274a..d132c121b8d 100644
--- a/Sofa/Component/Mass/src/sofa/component/mass/FEMMass.h
+++ b/Sofa/Component/Mass/src/sofa/component/mass/FEMMass.h
@@ -261,6 +261,18 @@ template class SOFA_COMPONENT_MASS_API FEMMass;
template class SOFA_COMPONENT_MASS_API FEMMass;
template class SOFA_COMPONENT_MASS_API FEMMass;
+
+template class SOFA_COMPONENT_MASS_API FEMMass;
+template class SOFA_COMPONENT_MASS_API FEMMass;
+template class SOFA_COMPONENT_MASS_API FEMMass;
+template class SOFA_COMPONENT_MASS_API FEMMass;
+template class SOFA_COMPONENT_MASS_API FEMMass;
+template class SOFA_COMPONENT_MASS_API FEMMass;
+template class SOFA_COMPONENT_MASS_API FEMMass;
+template class SOFA_COMPONENT_MASS_API FEMMass;
+template class SOFA_COMPONENT_MASS_API FEMMass;
+template class SOFA_COMPONENT_MASS_API FEMMass;
+template class SOFA_COMPONENT_MASS_API FEMMass;
#endif
} // namespace sofa::component::mass
diff --git a/Sofa/Component/SolidMechanics/FEM/Elastic/src/sofa/component/solidmechanics/fem/elastic/CorotationalFEMForceField.cpp b/Sofa/Component/SolidMechanics/FEM/Elastic/src/sofa/component/solidmechanics/fem/elastic/CorotationalFEMForceField.cpp
index da1a5d7dcc3..4a1e84d42d8 100644
--- a/Sofa/Component/SolidMechanics/FEM/Elastic/src/sofa/component/solidmechanics/fem/elastic/CorotationalFEMForceField.cpp
+++ b/Sofa/Component/SolidMechanics/FEM/Elastic/src/sofa/component/solidmechanics/fem/elastic/CorotationalFEMForceField.cpp
@@ -43,6 +43,17 @@ void registerCorotationalFEMForceField(sofa::core::ObjectFactory* factory)
.add< CorotationalFEMForceField >()
.add< CorotationalFEMForceField >()
.add< CorotationalFEMForceField >()
+
+ .add< CorotationalFEMForceField >()
+ .add< CorotationalFEMForceField >()
+ .add< CorotationalFEMForceField >()
+ .add< CorotationalFEMForceField >()
+ .add< CorotationalFEMForceField >()
+ .add< CorotationalFEMForceField >()
+ .add< CorotationalFEMForceField >()
+ .add< CorotationalFEMForceField >()
+ .add< CorotationalFEMForceField >()
+ .add< CorotationalFEMForceField >()
);
}
@@ -58,4 +69,15 @@ template class SOFA_COMPONENT_SOLIDMECHANICS_FEM_ELASTIC_API CorotationalFEMForc
template class SOFA_COMPONENT_SOLIDMECHANICS_FEM_ELASTIC_API CorotationalFEMForceField;
template class SOFA_COMPONENT_SOLIDMECHANICS_FEM_ELASTIC_API CorotationalFEMForceField;
+template class SOFA_COMPONENT_SOLIDMECHANICS_FEM_ELASTIC_API CorotationalFEMForceField;
+template class SOFA_COMPONENT_SOLIDMECHANICS_FEM_ELASTIC_API CorotationalFEMForceField;
+template class SOFA_COMPONENT_SOLIDMECHANICS_FEM_ELASTIC_API CorotationalFEMForceField;
+template class SOFA_COMPONENT_SOLIDMECHANICS_FEM_ELASTIC_API CorotationalFEMForceField;
+template class SOFA_COMPONENT_SOLIDMECHANICS_FEM_ELASTIC_API CorotationalFEMForceField;
+template class SOFA_COMPONENT_SOLIDMECHANICS_FEM_ELASTIC_API CorotationalFEMForceField;
+template class SOFA_COMPONENT_SOLIDMECHANICS_FEM_ELASTIC_API CorotationalFEMForceField;
+template class SOFA_COMPONENT_SOLIDMECHANICS_FEM_ELASTIC_API CorotationalFEMForceField;
+template class SOFA_COMPONENT_SOLIDMECHANICS_FEM_ELASTIC_API CorotationalFEMForceField;
+template class SOFA_COMPONENT_SOLIDMECHANICS_FEM_ELASTIC_API CorotationalFEMForceField;
+
}
diff --git a/Sofa/Component/SolidMechanics/FEM/Elastic/src/sofa/component/solidmechanics/fem/elastic/CorotationalFEMForceField.h b/Sofa/Component/SolidMechanics/FEM/Elastic/src/sofa/component/solidmechanics/fem/elastic/CorotationalFEMForceField.h
index a74f6d0b002..32a553f2ac8 100644
--- a/Sofa/Component/SolidMechanics/FEM/Elastic/src/sofa/component/solidmechanics/fem/elastic/CorotationalFEMForceField.h
+++ b/Sofa/Component/SolidMechanics/FEM/Elastic/src/sofa/component/solidmechanics/fem/elastic/CorotationalFEMForceField.h
@@ -109,6 +109,21 @@ struct RotationMethods : RotationMethodsC
}
};
+//partial specialization for quadratic tetrahedron
+template
+struct RotationMethods : RotationMethodsContainer, IdentityRotation
+>
+{
+ using Inherit = RotationMethodsContainer, IdentityRotation>;
+
+ explicit RotationMethods(sofa::core::objectmodel::BaseObject* parent) : Inherit(parent)
+ {
+ this->d_rotationMethod.setValue(PolarDecomposition::getItem().key);
+ }
+};
+
template
class CorotationalFEMForceField :
@@ -186,6 +201,17 @@ extern template class SOFA_COMPONENT_SOLIDMECHANICS_FEM_ELASTIC_API Corotational
extern template class SOFA_COMPONENT_SOLIDMECHANICS_FEM_ELASTIC_API CorotationalFEMForceField;
extern template class SOFA_COMPONENT_SOLIDMECHANICS_FEM_ELASTIC_API CorotationalFEMForceField;
extern template class SOFA_COMPONENT_SOLIDMECHANICS_FEM_ELASTIC_API CorotationalFEMForceField;
+
+extern template class SOFA_COMPONENT_SOLIDMECHANICS_FEM_ELASTIC_API CorotationalFEMForceField;
+extern template class SOFA_COMPONENT_SOLIDMECHANICS_FEM_ELASTIC_API CorotationalFEMForceField;
+extern template class SOFA_COMPONENT_SOLIDMECHANICS_FEM_ELASTIC_API CorotationalFEMForceField;
+extern template class SOFA_COMPONENT_SOLIDMECHANICS_FEM_ELASTIC_API CorotationalFEMForceField;
+extern template class SOFA_COMPONENT_SOLIDMECHANICS_FEM_ELASTIC_API CorotationalFEMForceField;
+extern template class SOFA_COMPONENT_SOLIDMECHANICS_FEM_ELASTIC_API CorotationalFEMForceField;
+extern template class SOFA_COMPONENT_SOLIDMECHANICS_FEM_ELASTIC_API CorotationalFEMForceField;
+extern template class SOFA_COMPONENT_SOLIDMECHANICS_FEM_ELASTIC_API CorotationalFEMForceField;
+extern template class SOFA_COMPONENT_SOLIDMECHANICS_FEM_ELASTIC_API CorotationalFEMForceField;
+extern template class SOFA_COMPONENT_SOLIDMECHANICS_FEM_ELASTIC_API CorotationalFEMForceField;
#endif
} // namespace sofa::component::solidmechanics::fem::elastic
diff --git a/Sofa/Component/SolidMechanics/FEM/Elastic/src/sofa/component/solidmechanics/fem/elastic/LinearSmallStrainFEMForceField.cpp b/Sofa/Component/SolidMechanics/FEM/Elastic/src/sofa/component/solidmechanics/fem/elastic/LinearSmallStrainFEMForceField.cpp
index e25229b29eb..abe930ca8c6 100644
--- a/Sofa/Component/SolidMechanics/FEM/Elastic/src/sofa/component/solidmechanics/fem/elastic/LinearSmallStrainFEMForceField.cpp
+++ b/Sofa/Component/SolidMechanics/FEM/Elastic/src/sofa/component/solidmechanics/fem/elastic/LinearSmallStrainFEMForceField.cpp
@@ -43,6 +43,18 @@ void registerLinearSmallStrainFEMForceField(sofa::core::ObjectFactory* factory)
.add< LinearSmallStrainFEMForceField >()
.add< LinearSmallStrainFEMForceField >()
.add< LinearSmallStrainFEMForceField >()
+
+ .add< LinearSmallStrainFEMForceField >()
+ .add< LinearSmallStrainFEMForceField >()
+ .add< LinearSmallStrainFEMForceField >()
+ .add< LinearSmallStrainFEMForceField >()
+ .add< LinearSmallStrainFEMForceField >()
+ .add< LinearSmallStrainFEMForceField >()
+ .add< LinearSmallStrainFEMForceField >()
+ .add< LinearSmallStrainFEMForceField >()
+ .add< LinearSmallStrainFEMForceField >()
+ .add< LinearSmallStrainFEMForceField >()
+ .add< LinearSmallStrainFEMForceField >()
);
}
@@ -58,4 +70,15 @@ template class SOFA_COMPONENT_SOLIDMECHANICS_FEM_ELASTIC_API LinearSmallStrainFE
template class SOFA_COMPONENT_SOLIDMECHANICS_FEM_ELASTIC_API LinearSmallStrainFEMForceField;
template class SOFA_COMPONENT_SOLIDMECHANICS_FEM_ELASTIC_API LinearSmallStrainFEMForceField;
+template class SOFA_COMPONENT_SOLIDMECHANICS_FEM_ELASTIC_API LinearSmallStrainFEMForceField;
+template class SOFA_COMPONENT_SOLIDMECHANICS_FEM_ELASTIC_API LinearSmallStrainFEMForceField;
+template class SOFA_COMPONENT_SOLIDMECHANICS_FEM_ELASTIC_API LinearSmallStrainFEMForceField;
+template class SOFA_COMPONENT_SOLIDMECHANICS_FEM_ELASTIC_API LinearSmallStrainFEMForceField;
+template class SOFA_COMPONENT_SOLIDMECHANICS_FEM_ELASTIC_API LinearSmallStrainFEMForceField;
+template class SOFA_COMPONENT_SOLIDMECHANICS_FEM_ELASTIC_API LinearSmallStrainFEMForceField;
+template class SOFA_COMPONENT_SOLIDMECHANICS_FEM_ELASTIC_API LinearSmallStrainFEMForceField;
+template class SOFA_COMPONENT_SOLIDMECHANICS_FEM_ELASTIC_API LinearSmallStrainFEMForceField;
+template class SOFA_COMPONENT_SOLIDMECHANICS_FEM_ELASTIC_API LinearSmallStrainFEMForceField;
+template class SOFA_COMPONENT_SOLIDMECHANICS_FEM_ELASTIC_API LinearSmallStrainFEMForceField;
+template class SOFA_COMPONENT_SOLIDMECHANICS_FEM_ELASTIC_API LinearSmallStrainFEMForceField;
}
diff --git a/Sofa/Component/SolidMechanics/FEM/Elastic/src/sofa/component/solidmechanics/fem/elastic/LinearSmallStrainFEMForceField.h b/Sofa/Component/SolidMechanics/FEM/Elastic/src/sofa/component/solidmechanics/fem/elastic/LinearSmallStrainFEMForceField.h
index 899edf4c084..f4b3d37b306 100644
--- a/Sofa/Component/SolidMechanics/FEM/Elastic/src/sofa/component/solidmechanics/fem/elastic/LinearSmallStrainFEMForceField.h
+++ b/Sofa/Component/SolidMechanics/FEM/Elastic/src/sofa/component/solidmechanics/fem/elastic/LinearSmallStrainFEMForceField.h
@@ -93,6 +93,18 @@ extern template class SOFA_COMPONENT_SOLIDMECHANICS_FEM_ELASTIC_API LinearSmallS
extern template class SOFA_COMPONENT_SOLIDMECHANICS_FEM_ELASTIC_API LinearSmallStrainFEMForceField;
extern template class SOFA_COMPONENT_SOLIDMECHANICS_FEM_ELASTIC_API LinearSmallStrainFEMForceField;
extern template class SOFA_COMPONENT_SOLIDMECHANICS_FEM_ELASTIC_API LinearSmallStrainFEMForceField;
+
+extern template class SOFA_COMPONENT_SOLIDMECHANICS_FEM_ELASTIC_API LinearSmallStrainFEMForceField;
+extern template class SOFA_COMPONENT_SOLIDMECHANICS_FEM_ELASTIC_API LinearSmallStrainFEMForceField;
+extern template class SOFA_COMPONENT_SOLIDMECHANICS_FEM_ELASTIC_API LinearSmallStrainFEMForceField;
+extern template class SOFA_COMPONENT_SOLIDMECHANICS_FEM_ELASTIC_API LinearSmallStrainFEMForceField;
+extern template class SOFA_COMPONENT_SOLIDMECHANICS_FEM_ELASTIC_API LinearSmallStrainFEMForceField;
+extern template class SOFA_COMPONENT_SOLIDMECHANICS_FEM_ELASTIC_API LinearSmallStrainFEMForceField;
+extern template class SOFA_COMPONENT_SOLIDMECHANICS_FEM_ELASTIC_API LinearSmallStrainFEMForceField;
+extern template class SOFA_COMPONENT_SOLIDMECHANICS_FEM_ELASTIC_API LinearSmallStrainFEMForceField;
+extern template class SOFA_COMPONENT_SOLIDMECHANICS_FEM_ELASTIC_API LinearSmallStrainFEMForceField;
+extern template class SOFA_COMPONENT_SOLIDMECHANICS_FEM_ELASTIC_API LinearSmallStrainFEMForceField;
+extern template class SOFA_COMPONENT_SOLIDMECHANICS_FEM_ELASTIC_API LinearSmallStrainFEMForceField;
#endif
} // namespace sofa::component::solidmechanics::fem::elastic
diff --git a/Sofa/Component/SolidMechanics/FEM/Elastic/tests/TriangleFEMForceField_stepTest.cpp b/Sofa/Component/SolidMechanics/FEM/Elastic/tests/TriangleFEMForceField_stepTest.cpp
index c29bf739f08..aa0ae7e23b1 100644
--- a/Sofa/Component/SolidMechanics/FEM/Elastic/tests/TriangleFEMForceField_stepTest.cpp
+++ b/Sofa/Component/SolidMechanics/FEM/Elastic/tests/TriangleFEMForceField_stepTest.cpp
@@ -45,7 +45,7 @@ struct TriangleFEMForceField_stepTest : public ForceField_test<_TriangleFEMForce
{
auto topology = modeling::addNew(this->node);
topology->setName("topology");
- topology->d_seqTriangles.setValue({{0,1,2}});
+ topology->d_seqTriangles.toData().setValue({{0,1,2}});
topology->d_seqPoints.setParent(&this->dof->x);
//Position
diff --git a/Sofa/Component/Topology/Container/Constant/CMakeLists.txt b/Sofa/Component/Topology/Container/Constant/CMakeLists.txt
index 958c2faaa08..ebf509cff7d 100644
--- a/Sofa/Component/Topology/Container/Constant/CMakeLists.txt
+++ b/Sofa/Component/Topology/Container/Constant/CMakeLists.txt
@@ -7,6 +7,7 @@ set(HEADER_FILES
${SOFACOMPONENTTOPOLOGYCONTAINERCONSTANT_SOURCE_DIR}/config.h.in
${SOFACOMPONENTTOPOLOGYCONTAINERCONSTANT_SOURCE_DIR}/init.h
${SOFACOMPONENTTOPOLOGYCONTAINERCONSTANT_SOURCE_DIR}/MeshTopology.h
+ ${SOFACOMPONENTTOPOLOGYCONTAINERCONSTANT_SOURCE_DIR}/MeshTopologyContainer.h
${SOFACOMPONENTTOPOLOGYCONTAINERCONSTANT_SOURCE_DIR}/CubeTopology.h
${SOFACOMPONENTTOPOLOGYCONTAINERCONSTANT_SOURCE_DIR}/SphereQuadTopology.h
)
@@ -14,6 +15,7 @@ set(HEADER_FILES
set(SOURCE_FILES
${SOFACOMPONENTTOPOLOGYCONTAINERCONSTANT_SOURCE_DIR}/init.cpp
${SOFACOMPONENTTOPOLOGYCONTAINERCONSTANT_SOURCE_DIR}/MeshTopology.cpp
+ ${SOFACOMPONENTTOPOLOGYCONTAINERCONSTANT_SOURCE_DIR}/MeshTopologyContainer.cpp
${SOFACOMPONENTTOPOLOGYCONTAINERCONSTANT_SOURCE_DIR}/CubeTopology.cpp
${SOFACOMPONENTTOPOLOGYCONTAINERCONSTANT_SOURCE_DIR}/SphereQuadTopology.cpp
)
diff --git a/Sofa/Component/Topology/Container/Constant/src/sofa/component/topology/container/constant/MeshTopology.cpp b/Sofa/Component/Topology/Container/Constant/src/sofa/component/topology/container/constant/MeshTopology.cpp
index b0e14ac3a76..a4beb496ea7 100644
--- a/Sofa/Component/Topology/Container/Constant/src/sofa/component/topology/container/constant/MeshTopology.cpp
+++ b/Sofa/Component/Topology/Container/Constant/src/sofa/component/topology/container/constant/MeshTopology.cpp
@@ -39,16 +39,16 @@ MeshTopology::EdgeUpdate::EdgeUpdate(MeshTopology* t)
{
if( topology->hasVolume() )
{
- addInput(&topology->d_seqHexahedra);
- addInput(&topology->d_seqTetrahedra);
- addOutput(&topology->d_seqEdges);
+ addInput(&topology->d_seqHexahedra.toData());
+ addInput(&topology->d_seqTetrahedra.toData());
+ addOutput(&topology->d_seqEdges.toData());
setDirtyValue();
}
else if( topology->hasSurface() )
{
- addInput(&topology->d_seqTriangles);
- addInput(&topology->d_seqQuads);
- addOutput(&topology->d_seqEdges);
+ addInput(&topology->d_seqTriangles.toData());
+ addInput(&topology->d_seqQuads.toData());
+ addOutput(&topology->d_seqEdges.toData());
setDirtyValue();
}
@@ -221,8 +221,8 @@ void MeshTopology::EdgeUpdate::updateFromSurface()
MeshTopology::TriangleUpdate::TriangleUpdate(MeshTopology *t)
:PrimitiveUpdate(t)
{
- addInput(&topology->d_seqTetrahedra);
- addOutput(&topology->d_seqTriangles);
+ addInput(&topology->d_seqTetrahedra.toData());
+ addOutput(&topology->d_seqTriangles.toData());
setDirtyValue();
}
@@ -275,8 +275,8 @@ void MeshTopology::TriangleUpdate::doUpdate()
MeshTopology::QuadUpdate::QuadUpdate(MeshTopology *t)
:PrimitiveUpdate(t)
{
- addInput(&topology->d_seqHexahedra);
- addOutput(&topology->d_seqQuads);
+ addInput(&topology->d_seqHexahedra.toData());
+ addOutput(&topology->d_seqQuads.toData());
setDirtyValue();
}
@@ -486,13 +486,6 @@ void registerMeshTopology(sofa::core::ObjectFactory* factory)
MeshTopology::MeshTopology()
: d_seqPoints(initData(&d_seqPoints, "position", "List of point positions"))
- , d_seqEdges(initData(&d_seqEdges, "edges", "List of edge indices"))
- , d_seqTriangles(initData(&d_seqTriangles, "triangles", "List of triangle indices"))
- , d_seqQuads(initData(&d_seqQuads, "quads", "List of quad indices"))
- , d_seqTetrahedra(initData(&d_seqTetrahedra, "tetrahedra", "List of tetrahedron indices"))
- , d_seqHexahedra(initData(&d_seqHexahedra, "hexahedra", "List of hexahedron indices"))
- , d_seqPrisms(initData(&d_seqPrisms, "prisms", "List of prisms indices"))
- , d_seqPyramids(initData(&d_seqPyramids, "pyramids", "List of pyramids indices"))
, d_seqUVs(initData(&d_seqUVs, "uv", "List of uv coordinates"))
, d_computeAllBuffers(initData(&d_computeAllBuffers, false, "computeAllBuffers", "Option to compute all crossed topology buffers at init. False by default"))
, nbPoints(0)
@@ -506,9 +499,9 @@ MeshTopology::MeshTopology()
{
m_upperElementType = sofa::geometry::ElementType::EDGE;
addAlias(&d_seqPoints, "points");
- addAlias(&d_seqEdges, "lines");
- addAlias(&d_seqTetrahedra, "tetras");
- addAlias(&d_seqHexahedra, "hexas");
+ addAlias(&d_seqEdges.toData(), "lines");
+ addAlias(&d_seqTetrahedra.toData(), "tetras");
+ addAlias(&d_seqHexahedra.toData(), "hexas");
addAlias(&d_seqUVs, "texcoords");
}
@@ -747,51 +740,6 @@ void MeshTopology::addUV(SReal u, SReal v)
nbPoints = (int)d_seqUVs.getValue().size();
}
-const MeshTopology::SeqEdges& MeshTopology::getEdges()
-{
- return d_seqEdges.getValue();
-}
-
-const MeshTopology::SeqTriangles& MeshTopology::getTriangles()
-{
- return d_seqTriangles.getValue();
-}
-
-const MeshTopology::SeqQuads& MeshTopology::getQuads()
-{
- return d_seqQuads.getValue();
-}
-
-const MeshTopology::SeqTetrahedra& MeshTopology::getTetrahedra()
-{
- if (!validTetrahedra)
- {
- updateTetrahedra();
- validTetrahedra = true;
- }
- return d_seqTetrahedra.getValue();
-}
-
-const MeshTopology::SeqHexahedra& MeshTopology::getHexahedra()
-{
- if (!validHexahedra)
- {
- updateHexahedra();
- validHexahedra = true;
- }
- return d_seqHexahedra.getValue();
-}
-
-const BaseMeshTopology::SeqPrisms& MeshTopology::getPrisms()
-{
- return d_seqPrisms.getValue();
-}
-
-const BaseMeshTopology::SeqPyramids& MeshTopology::getPyramids()
-{
- return d_seqPyramids.getValue();
-}
-
const MeshTopology::SeqUV& MeshTopology::getUVs()
{
return d_seqUVs.getValue();
diff --git a/Sofa/Component/Topology/Container/Constant/src/sofa/component/topology/container/constant/MeshTopology.h b/Sofa/Component/Topology/Container/Constant/src/sofa/component/topology/container/constant/MeshTopology.h
index 281f5ceeca1..ed2dd459cee 100644
--- a/Sofa/Component/Topology/Container/Constant/src/sofa/component/topology/container/constant/MeshTopology.h
+++ b/Sofa/Component/Topology/Container/Constant/src/sofa/component/topology/container/constant/MeshTopology.h
@@ -23,17 +23,17 @@
#include
#include
-#include
+#include
#include
#include
namespace sofa::component::topology::container::constant
{
-class SOFA_COMPONENT_TOPOLOGY_CONTAINER_CONSTANT_API MeshTopology : public core::topology::BaseMeshTopology
+class SOFA_COMPONENT_TOPOLOGY_CONTAINER_CONSTANT_API MeshTopology : public MeshTopologyContainer
{
public:
- SOFA_CLASS(MeshTopology,core::topology::BaseMeshTopology);
+ SOFA_CLASS(MeshTopology, MeshTopologyContainer);
protected:
class PrimitiveUpdate : public sofa::core::DataEngine
@@ -91,16 +91,6 @@ class SOFA_COMPONENT_TOPOLOGY_CONTAINER_CONSTANT_API MeshTopology : public core:
void setNbPoints(Size n) override;
- // Complete sequence accessors
-
- const SeqEdges& getEdges() override;
- const SeqTriangles& getTriangles() override;
- const SeqQuads& getQuads() override;
- const SeqTetrahedra& getTetrahedra() override;
- const SeqHexahedra& getHexahedra() override;
- const SeqPrisms& getPrisms() override;
- const SeqPyramids& getPyramids() override;
-
// If using STEP loader, include also uv coordinates
typedef Index UVID;
typedef type::Vec2 UV;
@@ -297,17 +287,19 @@ class SOFA_COMPONENT_TOPOLOGY_CONTAINER_CONSTANT_API MeshTopology : public core:
typedef type::vector SeqPoints;
Data< SeqPoints > d_seqPoints; ///< List of point positions
- Data d_seqEdges; ///< List of edge indices
- Data d_seqTriangles; ///< List of triangle indices
- Data d_seqQuads; ///< List of quad indices
- Data d_seqTetrahedra; ///< List of tetrahedron indices
- Data d_seqHexahedra; ///< List of hexahedron indices
- Data d_seqPrisms;
- Data d_seqPyramids;
+ SeqElementProxy d_seqEdges { this };
+ SeqElementProxy d_seqTriangles { this };
+ SeqElementProxy d_seqQuads { this };
+ SeqElementProxy d_seqTetrahedra { this };
+ SeqElementProxy d_seqHexahedra { this };
+ SeqElementProxy d_seqPrisms { this };
+ SeqElementProxy d_seqPyramids { this };
+
Data d_seqUVs; ///< List of uv coordinates
Data d_computeAllBuffers; ///< Option to call method computeCrossElementBuffers. False by default
protected:
+
Size nbPoints;
template
diff --git a/Sofa/Component/Topology/Container/Constant/src/sofa/component/topology/container/constant/MeshTopologyContainer.cpp b/Sofa/Component/Topology/Container/Constant/src/sofa/component/topology/container/constant/MeshTopologyContainer.cpp
new file mode 100644
index 00000000000..fc62f37f5bf
--- /dev/null
+++ b/Sofa/Component/Topology/Container/Constant/src/sofa/component/topology/container/constant/MeshTopologyContainer.cpp
@@ -0,0 +1,163 @@
+/******************************************************************************
+* SOFA, Simulation Open-Framework Architecture *
+* (c) 2006 INRIA, USTL, UJF, CNRS, MGH *
+* *
+* This program is free software; you can redistribute it and/or modify it *
+* under the terms of the GNU Lesser General Public License as published by *
+* the Free Software Foundation; either version 2.1 of the License, or (at *
+* your option) any later version. *
+* *
+* This program is distributed in the hope that it will be useful, but WITHOUT *
+* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or *
+* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License *
+* for more details. *
+* *
+* You should have received a copy of the GNU Lesser General Public License *
+* along with this program. If not, see . *
+*******************************************************************************
+* Authors: The SOFA Team and external contributors (see Authors.txt) *
+* *
+* Contact information: contact@sofa-framework.org *
+******************************************************************************/
+#include
+
+namespace sofa::component::topology::container::constant
+{
+
+using sofa::geometry::ElementType;
+
+constexpr const char* elementTypeToDataName(ElementType type)
+{
+ switch (type)
+ {
+ case ElementType::POINT: { return "position"; }
+ case ElementType::EDGE: { return "edges"; }
+ case ElementType::TRIANGLE: { return "triangles"; }
+ case ElementType::QUAD: { return "quads"; }
+ case ElementType::TETRAHEDRON: { return "tetrahedra"; }
+ case ElementType::HEXAHEDRON: { return "hexahedra"; }
+ case ElementType::PRISM: { return "prisms"; }
+ case ElementType::PYRAMID: { return "pyramids"; }
+
+ case ElementType::QUADRATIC_EDGE: { return "quadratic_edges"; }
+ case ElementType::QUADRATIC_TRIANGLE: { return "quadratic_triangles"; }
+ case ElementType::QUADRATIC_QUAD: { return "quadratic_quads"; }
+ case ElementType::QUADRATIC_TETRAHEDRON: { return "quadratic_tetrahedra"; }
+ case ElementType::QUADRATIC_HEXAHEDRON: { return "quadratic_hexahedra"; }
+ case ElementType::QUADRATIC_PRISM: { return "quadratic_prisms"; }
+ case ElementType::QUADRATIC_PYRAMID: { return "quadratic_pyramids"; }
+
+ default:
+ return "Unknown";
+ }
+}
+template
+void registerSingleData(core::objectmodel::BaseComponent* meshTopology, auto& dataContainer)
+{
+ using AllElements = std::remove_cvref_t;
+ using DataSeqElementPtr = std::tuple_element_t;
+ using DataSeqElement = typename DataSeqElementPtr::element_type;
+ using SeqElement = typename DataSeqElement::value_type;
+ using TopologyElement = typename SeqElement::value_type;
+ static constexpr auto elementType = TopologyElement::Element_type;
+
+ const char* elementName = sofa::geometry::elementTypeToString(elementType);
+ auto elementNameStr = sofa::helper::downcaseString(std::string(elementName));
+
+ auto dataName = elementTypeToDataName(elementType);
+ std::string dataNameStr { dataName };
+ sofa::helper::replaceAll(dataNameStr, " ", "_");
+
+ auto& dataPtr = std::get(dataContainer);
+ dataPtr = std::make_unique("List of " + elementNameStr);
+
+ sofa::core::objectmodel::BaseData& data = *dataPtr;
+ data.setName(dataName);
+
+ meshTopology->addData(dataPtr.get(), dataName);
+}
+
+template
+void registerData(core::objectmodel::BaseComponent* meshTopology, auto& dataContainer, std::index_sequence)
+{
+ (registerSingleData(meshTopology, dataContainer), ...);
+}
+
+const void* MeshTopologyContainer::getElementsRaw(
+ const sofa::geometry::ElementType& elementType) const noexcept
+{
+ switch (elementType)
+ {
+ case ElementType::UNKNOWN:
+ case ElementType::POINT:
+ break;
+ case ElementType::EDGE:
+ return &get()->getValue();
+ case ElementType::TRIANGLE:
+ return &get()->getValue();
+ case ElementType::QUAD:
+ return &get()->getValue();
+ case ElementType::TETRAHEDRON:
+ return &get()->getValue();
+ case ElementType::HEXAHEDRON:
+ return &get()->getValue();
+ case ElementType::PRISM:
+ return &get()->getValue();
+ case ElementType::PYRAMID:
+ return &get()->getValue();
+ case ElementType::QUADRATIC_EDGE:
+ return &get()->getValue();
+ case ElementType::QUADRATIC_TRIANGLE:
+ return &get()->getValue();
+ case ElementType::QUADRATIC_QUAD:
+ return &get()->getValue();
+ case ElementType::QUADRATIC_TETRAHEDRON:
+ return &get()->getValue();
+ case ElementType::QUADRATIC_HEXAHEDRON:
+ return &get()->getValue();
+ case ElementType::QUADRATIC_PRISM:
+ return &get()->getValue();
+ case ElementType::QUADRATIC_PYRAMID:
+ return &get()->getValue();
+ case ElementType::SIZE:
+ default:
+ return nullptr;
+ }
+ return nullptr;
+}
+
+MeshTopologyContainer::MeshTopologyContainer() : Inherit1()
+{
+ registerData(this, m_container, std::make_index_sequence>{});
+}
+
+const core::topology::BaseMeshTopology::SeqEdges& MeshTopologyContainer::getEdges()
+{
+ return get()->getValue();
+}
+const core::topology::BaseMeshTopology::SeqTriangles& MeshTopologyContainer::getTriangles()
+{
+ return get()->getValue();
+}
+const core::topology::BaseMeshTopology::SeqQuads& MeshTopologyContainer::getQuads()
+{
+ return get()->getValue();
+}
+const core::topology::BaseMeshTopology::SeqTetrahedra& MeshTopologyContainer::getTetrahedra()
+{
+ return get()->getValue();
+}
+const core::topology::BaseMeshTopology::SeqHexahedra& MeshTopologyContainer::getHexahedra()
+{
+ return get()->getValue();
+}
+const core::topology::BaseMeshTopology::SeqPrisms& MeshTopologyContainer::getPrisms()
+{
+ return get()->getValue();
+}
+const core::topology::BaseMeshTopology::SeqPyramids& MeshTopologyContainer::getPyramids()
+{
+ return get()->getValue();
+}
+
+} // namespace sofa::component::topology::container::constant
diff --git a/Sofa/Component/Topology/Container/Constant/src/sofa/component/topology/container/constant/MeshTopologyContainer.h b/Sofa/Component/Topology/Container/Constant/src/sofa/component/topology/container/constant/MeshTopologyContainer.h
new file mode 100644
index 00000000000..a5e7c8f1295
--- /dev/null
+++ b/Sofa/Component/Topology/Container/Constant/src/sofa/component/topology/container/constant/MeshTopologyContainer.h
@@ -0,0 +1,184 @@
+/******************************************************************************
+* SOFA, Simulation Open-Framework Architecture *
+* (c) 2006 INRIA, USTL, UJF, CNRS, MGH *
+* *
+* This program is free software; you can redistribute it and/or modify it *
+* under the terms of the GNU Lesser General Public License as published by *
+* the Free Software Foundation; either version 2.1 of the License, or (at *
+* your option) any later version. *
+* *
+* This program is distributed in the hope that it will be useful, but WITHOUT *
+* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or *
+* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License *
+* for more details. *
+* *
+* You should have received a copy of the GNU Lesser General Public License *
+* along with this program. If not, see . *
+*******************************************************************************
+* Authors: The SOFA Team and external contributors (see Authors.txt) *
+* *
+* Contact information: contact@sofa-framework.org *
+******************************************************************************/
+#pragma once
+#include
+#include
+
+namespace sofa::component::topology::container::constant
+{
+
+class SOFA_COMPONENT_TOPOLOGY_CONTAINER_CONSTANT_API MeshTopologyContainer :
+ public sofa::core::topology::BaseMeshTopology
+{
+public:
+ SOFA_CLASS(MeshTopologyContainer, core::topology::BaseMeshTopology);
+
+ template //e.g. sofa::geometry::Edge
+ using TopologyElement = sofa::topology::Element;
+
+ template //e.g. sofa::geometry::Edge
+ using SeqElement = sofa::type::vector>;
+
+ template //e.g. sofa::geometry::Edge
+ using DataSeqElement = sofa::Data>;
+
+ template //e.g. sofa::geometry::Edge
+ using DataSeqElementPtr = std::unique_ptr>;
+
+ using AllElements = std::tuple<
+ DataSeqElementPtr,
+ DataSeqElementPtr,
+ DataSeqElementPtr,
+ DataSeqElementPtr,
+ DataSeqElementPtr,
+ DataSeqElementPtr,
+ DataSeqElementPtr,
+ DataSeqElementPtr,
+ DataSeqElementPtr