Back

FastTriangularBendingSprings

A bending force field for triangular meshes in SOFA physics engine.

abstract
The FastTriangularBendingSprings component adds springs to a triangular mesh to prevent bending by enforcing elastic forces between vertices of triangles sharing an edge, using parameters like bending stiffness and minimum distance validity.
sheet
# FastTriangularBendingSprings ## Overview FastTriangularBendingSprings is a force field that prevents bending in triangular meshes by adding springs between vertices of adjacent triangles. It inherits from the `ForceField` class and requires a topology container to define the mesh structure. ## Mathematical Model The component calculates elastic forces based on vertex positions and material properties: 1. **Normals Calculation**: Normals at each vertex are computed using cross products of adjacent edges: \[ \mathbf{N}_A = (\mathbf{p_C} - \mathbf{p_A}) \times (\mathbf{p_D} - \mathbf{p_A}) \] \[ \mathbf{N}_B = (\mathbf{p_D} - \mathbf{p_B}) \times (\mathbf{p_C} - \mathbf{p_B}) \] \[ \mathbf{N}_C = -(\mathbf{p_B} - \mathbf{p_C}) \times (\mathbf{p_A} - \mathbf{p_C}) \] \[ \mathbf{N}_D = -(\mathbf{p_A} - \mathbf{p_D}) \times (\mathbf{p_B} - \mathbf{p_D}) \] 2. **Alpha Weights**: These are used to balance contributions from different vertices: \[ \alpha_A = \frac{||\mathbf{N}_B||}{||\mathbf{N}_A|| + ||\mathbf{N}_B||} \] \[ \alpha_B = \frac{||\mathbf{N}_A||}{||\mathbf{N}_A|| + ||\mathbf{N}_B||} \] \[ \alpha_C = -\frac{||\mathbf{N}_D||}{||\mathbf{N}_C|| + ||\mathbf{N}_D||} \] \[ \alpha_D = -\frac{||\mathbf{N}_C||}{||\mathbf{N}_C|| + ||\mathbf{N}_D||} \] 3. **Stiffness Calculation**: The stiffness coefficient \(\lambda\) is calculated based on distances from vertices to the edge and material bending stiffness: \[ h_A = ||(p_C - p_A) - (p_D - p_C) * (\mathbf{e}^T(p_C-p_A))|| \] \[ h_B = ||(p_C - p_B) - (p_D - p_C) * (\mathbf{e}^T(p_C-p_B))|| \] \[ l = ||p_C - p_D|| \] \[ \lambda = \frac{2}{3} \cdot \frac{(h_A + h_B)}{h_A^2 \cdot h_B^2} \cdot l \cdot K_{material} \] 4. **Force Calculation**: The resultant force \(R\) is computed as a weighted sum of vertices, and then applied to each vertex with stiffness \(\lambda\): \[ R = p_A * \alpha_A + p_B * \alpha_B + p_C * \alpha_C + p_D * \alpha_D \] 5. **Potential Energy**: The potential energy \(U\) associated with the bending force is given by: \[ U = \frac{1}{2} R^T K R \] ## Parameters and Data - `bendingStiffness`: Bending stiffness of the material (SReal, default: not specified). - `minDistValidity`: Distance under which a spring is not valid (SReal, default: not specified). ## Dependencies and Connections This component requires a topology container (`BaseMeshTopology`) to define the mesh structure.
name
FastTriangularBendingSprings
description
A bending force field for triangular meshes in SOFA physics engine.
parameters
  • {'name': 'bendingStiffness', 'description': 'The stiffness coefficient for the bending forces, used to calculate how resistant the triangles are to bending deformation.'}
  • {'name': 'rayleighStiffness', 'description': 'Rayleigh damping factor. Used in conjunction with MechanicalParams to apply Rayleigh damping if needed.'}
inputs
  • {'name': 'Mechanical state of the system', 'description': 'The mechanical state (positions, velocities) of the object on which this force field is applied.'}
  • {'name': 'Geometry', 'description': 'The geometry of the triangular mesh, typically defined by vertices and faces/triangles.'}
outputs
  • {'name': 'Bending forces', 'description': 'Applies bending forces to resist deformation of triangles in the mesh.'}
  • {'name': 'Potential energy', 'description': 'Calculates the potential energy associated with the bending deformation of the mesh.'}
details
{
  "constraints_and_limitations": [
    "It is specifically designed for use with triangular meshes.",
    "The effectiveness depends on the quality and resolution of the mesh geometry."
  ],
  "mechanism": "It calculates and applies forces that resist the bending of each triangle based on the positions and orientations of neighboring triangles. The stiffness of these forces can be tuned with the \u0027bendingStiffness\u0027 parameter.",
  "purpose": "This component implements a bending force field for triangular meshes. It simulates how much resistance there is to bending deformations between adjacent triangles in the mesh.",
  "usage_examples": [
    {
      "example": "Simulating a deformable cloth or skin in a virtual surgery simulation, where the mesh needs to bend realistically but not excessively."
    },
    {
      "example": "Creating a flexible character model for animation, allowing for natural deformation of limbs and other body parts while maintaining structural integrity."
    }
  ]
}
maths
## Mathematical and Physical Description of the Bending Force Field for Triangular Meshes in SOFA Physics Engine ### Overview The bending force field for triangular meshes is a key component used to simulate elastic behavior in deformable objects within the Simulation Open Framework Architecture (SOFA). This particular implementation focuses on enforcing smoothness across shared edges between adjacent triangles, which helps maintain realistic physical properties during simulation. ### Mathematical Model 1. **Edge Definition**: Each edge of a triangular mesh is considered as an interaction point for bending forces. Given four vertices involved in the bending operation - A, B (vertices connected by an edge) and C, D (opposite vertices to the edge). 2. **Normal Calculation**: Normals at each vertex are computed using cross products of adjacent edges: \[ \mathbf{N}_A = \mathbf{(p_C - p_A)} \times \mathbf{(p_D - p_A)} \] \[ \mathbf{N}_B = \mathbf{(p_D - p_B)} \times \mathbf{(p_C - p_B)} \] \[ \mathbf{N}_C = -\mathbf{(p_B - p_C)} \times \mathbf{(p_A - p_C)} \] \[ \mathbf{N}_D = -\mathbf{(p_A - p_D)} \times \mathbf{(p_B - p_D)} \] 3. **Alpha Weights**: These are used to balance contributions from different vertices: \[ \alpha_A = \frac{||\mathbf{N}_B||}{||\mathbf{N}_A|| + ||\mathbf{N}_B||} \] \[ \alpha_B = \frac{||\mathbf{N}_A||}{||\mathbf{N}_A|| + ||\mathbf{N}_B||} \] \[ \alpha_C = -\frac{||\mathbf{N}_D||}{||\mathbf{N}_C|| + ||\mathbf{N}_D||} \] \[ \alpha_D = -\frac{||\mathbf{N}_C||}{||\mathbf{N}_C|| + ||\mathbf{N}_D||} \] 4. **Stiffness Calculation**: The stiffness coefficient λ is calculated based on distances from vertices to the edge and material bending stiffness: \[ h_A = ||(p_C - p_A) - (p_D - p_C) * (\mathbf{e}^T(p_C-p_A))|| \] \[ h_B = ||(p_C - p_B) - (p_D - p_C) * (\mathbf{e}^T(p_C-p_B))|| \] \[ l = ||p_C - p_D|| \] \[ \lambda = \frac{2}{3} \cdot \frac{(h_A + h_B)}{h_A^2 \cdot h_B^2} \cdot l \cdot K_{material} \] 5. **Force Calculation**: The resultant force R is computed as a weighted sum of vertices, and then applied to each vertex with stiffness λ: \[ R = p_A * \alpha_A + p_B * \alpha_B + p_C * \alpha_C + p_D * \alpha_D \] 6. **Potential Energy**: The potential energy U associated with the bending force is given by: \[ U = \frac{1}{2} R^T K R \] ### Physical Interpretation - **Bending Stiffness**: Ensures that adjacent triangles maintain a smooth transition, avoiding abrupt changes in curvature which would be physically unrealistic. - **Material Properties**: The material bending stiffness affects the overall flexibility of the mesh; higher values make the object stiffer and less prone to deformation. - **Stability**: Ensuring proper balance between forces applied at vertices helps stabilize simulations by preventing excessive oscillations or instabilities. ### Conclusion This component provides a robust method for simulating realistic bending behavior in deformable objects, contributing significantly to creating believable interactions within the SOFA framework.
{
  "name": "FastTriangularBendingSprings",
  "main": {
    "name": "FastTriangularBendingSprings",
    "namespace": "sofa::component::solidmechanics::spring",
    "module": "Sofa.Component.SolidMechanics.Spring",
    "include": "sofa/component/solidmechanics/spring/FastTriangularBendingSprings.h",
    "doc": "Springs added to a triangular mesh to prevent bending.\n\nBending elastic force added between vertices of triangles sharing a common edge.\nAdapted from: P. Volino, N. Magnenat-Thalmann. Simple Linear Bending Stiffness in Particle Systems.\nEurographics Symposium on Computer Animation (SIGGRAPH), pp. 101-105, September 2006. http://www.miralab.ch/repository/papers/165.pdf\n @author François Faure, 2012",
    "inherits": [
      "ForceField"
    ],
    "templates": [
      "sofa::defaulttype::Vec3Types"
    ],
    "data_fields": [
      {
        "name": "d_bendingStiffness",
        "type": "SReal",
        "xmlname": "bendingStiffness",
        "help": "Bending stiffness of the material"
      },
      {
        "name": "d_minDistValidity",
        "type": "SReal",
        "xmlname": "minDistValidity",
        "help": "Distance under which a spring is not valid"
      }
    ],
    "links": [
      {
        "name": "l_topology",
        "target": "BaseMeshTopology",
        "kind": "single",
        "xmlname": "topology",
        "help": "link to the topology container"
      }
    ],
    "methods": [
      {
        "name": "init",
        "return_type": "void",
        "params": [],
        "is_virtual": false,
        "is_pure_virtual": false,
        "is_static": false,
        "access": "public"
      },
      {
        "name": "reinit",
        "return_type": "void",
        "params": [],
        "is_virtual": false,
        "is_pure_virtual": false,
        "is_static": false,
        "access": "public"
      },
      {
        "name": "addForce",
        "return_type": "void",
        "params": [
          {
            "name": "mparams",
            "type": "const core::MechanicalParams *"
          },
          {
            "name": "d_f",
            "type": "DataVecDeriv &"
          },
          {
            "name": "d_x",
            "type": "const DataVecCoord &"
          },
          {
            "name": "d_v",
            "type": "const DataVecDeriv &"
          }
        ],
        "is_virtual": false,
        "is_pure_virtual": false,
        "is_static": false,
        "access": "public"
      },
      {
        "name": "addDForce",
        "return_type": "void",
        "params": [
          {
            "name": "mparams",
            "type": "const core::MechanicalParams *"
          },
          {
            "name": "d_df",
            "type": "DataVecDeriv &"
          },
          {
            "name": "d_dx",
            "type": "const DataVecDeriv &"
          }
        ],
        "is_virtual": false,
        "is_pure_virtual": false,
        "is_static": false,
        "access": "public"
      },
      {
        "name": "addKToMatrix",
        "return_type": "void",
        "params": [
          {
            "name": "mat",
            "type": "sofa::linearalgebra::BaseMatrix *"
          },
          {
            "name": "k",
            "type": "SReal"
          },
          {
            "name": "offset",
            "type": "unsigned int &"
          }
        ],
        "is_virtual": false,
        "is_pure_virtual": false,
        "is_static": false,
        "access": "public"
      },
      {
        "name": "buildStiffnessMatrix",
        "return_type": "void",
        "params": [
          {
            "name": "matrix",
            "type": "core::behavior::StiffnessMatrix *"
          }
        ],
        "is_virtual": false,
        "is_pure_virtual": false,
        "is_static": false,
        "access": "public"
      },
      {
        "name": "buildDampingMatrix",
        "return_type": "void",
        "params": [
          {
            "name": "",
            "type": "core::behavior::DampingMatrix *"
          }
        ],
        "is_virtual": false,
        "is_pure_virtual": false,
        "is_static": false,
        "access": "public"
      },
      {
        "name": "getPotentialEnergy",
        "return_type": "SReal",
        "params": [
          {
            "name": "mparams",
            "type": "const core::MechanicalParams *"
          },
          {
            "name": "d_x",
            "type": "const DataVecCoord &"
          }
        ],
        "is_virtual": false,
        "is_pure_virtual": false,
        "is_static": false,
        "access": "public"
      },
      {
        "name": "draw",
        "return_type": "void",
        "params": [
          {
            "name": "vparams",
            "type": "const core::visual::VisualParams *"
          }
        ],
        "is_virtual": false,
        "is_pure_virtual": false,
        "is_static": false,
        "access": "public"
      },
      {
        "name": "applyEdgeCreation",
        "return_type": "void",
        "params": [
          {
            "name": "edgeIndex",
            "type": "int"
          },
          {
            "name": "ei",
            "type": "EdgeSpring &"
          },
          {
            "name": "",
            "type": "const core::topology::BaseMeshTopology::Edge &"
          },
          {
            "name": "",
            "type": "const int &"
          },
          {
            "name": "",
            "type": "const int &"
          }
        ],
        "is_virtual": false,
        "is_pure_virtual": false,
        "is_static": false,
        "access": "protected"
      },
      {
        "name": "applyTriangleCreation",
        "return_type": "void",
        "params": [
          {
            "name": "triangleAdded",
            "type": "const int &"
          },
          {
            "name": "",
            "type": "const int &"
          },
          {
            "name": "",
            "type": "const int &"
          },
          {
            "name": "",
            "type": "const int &"
          }
        ],
        "is_virtual": false,
        "is_pure_virtual": false,
        "is_static": false,
        "access": "protected"
      },
      {
        "name": "applyTriangleDestruction",
        "return_type": "void",
        "params": [
          {
            "name": "triangleRemoved",
            "type": "const int &"
          }
        ],
        "is_virtual": false,
        "is_pure_virtual": false,
        "is_static": false,
        "access": "protected"
      },
      {
        "name": "applyPointDestruction",
        "return_type": "void",
        "params": [
          {
            "name": "pointIndices",
            "type": "const int &"
          }
        ],
        "is_virtual": false,
        "is_pure_virtual": false,
        "is_static": false,
        "access": "protected"
      },
      {
        "name": "applyPointRenumbering",
        "return_type": "void",
        "params": [
          {
            "name": "pointToRenumber",
            "type": "const int &"
          }
        ],
        "is_virtual": false,
        "is_pure_virtual": false,
        "is_static": false,
        "access": "protected"
      },
      {
        "name": "getEdgeInfo",
        "return_type": "int &",
        "params": [],
        "is_virtual": false,
        "is_pure_virtual": false,
        "is_static": false,
        "access": "protected"
      }
    ]
  },
  "desc": {
    "name": "FastTriangularBendingSprings",
    "description": "A bending force field for triangular meshes in SOFA physics engine.",
    "parameters": [
      {
        "name": "bendingStiffness",
        "description": "The stiffness coefficient for the bending forces, used to calculate how resistant the triangles are to bending deformation."
      },
      {
        "name": "rayleighStiffness",
        "description": "Rayleigh damping factor. Used in conjunction with MechanicalParams to apply Rayleigh damping if needed."
      }
    ],
    "inputs": [
      {
        "name": "Mechanical state of the system",
        "description": "The mechanical state (positions, velocities) of the object on which this force field is applied."
      },
      {
        "name": "Geometry",
        "description": "The geometry of the triangular mesh, typically defined by vertices and faces/triangles."
      }
    ],
    "outputs": [
      {
        "name": "Bending forces",
        "description": "Applies bending forces to resist deformation of triangles in the mesh."
      },
      {
        "name": "Potential energy",
        "description": "Calculates the potential energy associated with the bending deformation of the mesh."
      }
    ],
    "details": {
      "purpose": "This component implements a bending force field for triangular meshes. It simulates how much resistance there is to bending deformations between adjacent triangles in the mesh.",
      "mechanism": "It calculates and applies forces that resist the bending of each triangle based on the positions and orientations of neighboring triangles. The stiffness of these forces can be tuned with the 'bendingStiffness' parameter.",
      "usage_examples": [
        {
          "example": "Simulating a deformable cloth or skin in a virtual surgery simulation, where the mesh needs to bend realistically but not excessively."
        },
        {
          "example": "Creating a flexible character model for animation, allowing for natural deformation of limbs and other body parts while maintaining structural integrity."
        }
      ],
      "constraints_and_limitations": [
        "It is specifically designed for use with triangular meshes.",
        "The effectiveness depends on the quality and resolution of the mesh geometry."
      ]
    }
  },
  "maths": {
    "maths": "## Mathematical and Physical Description of the Bending Force Field for Triangular Meshes in SOFA Physics Engine\n\n### Overview\nThe bending force field for triangular meshes is a key component used to simulate elastic behavior in deformable objects within the Simulation Open Framework Architecture (SOFA). This particular implementation focuses on enforcing smoothness across shared edges between adjacent triangles, which helps maintain realistic physical properties during simulation.\n\n### Mathematical Model\n1. **Edge Definition**: Each edge of a triangular mesh is considered as an interaction point for bending forces. Given four vertices involved in the bending operation - A, B (vertices connected by an edge) and C, D (opposite vertices to the edge).\n   \n2. **Normal Calculation**: Normals at each vertex are computed using cross products of adjacent edges:\n   \\[ \\mathbf{N}_A = \\mathbf{(p_C - p_A)} \\times \\mathbf{(p_D - p_A)} \\]\n   \\[ \\mathbf{N}_B = \\mathbf{(p_D - p_B)} \\times \\mathbf{(p_C - p_B)} \\]\n   \\[ \\mathbf{N}_C = -\\mathbf{(p_B - p_C)} \\times \\mathbf{(p_A - p_C)} \\]\n   \\[ \\mathbf{N}_D = -\\mathbf{(p_A - p_D)} \\times \\mathbf{(p_B - p_D)} \\]\n\n3. **Alpha Weights**: These are used to balance contributions from different vertices:\n   \\[ \\alpha_A = \\frac{||\\mathbf{N}_B||}{||\\mathbf{N}_A|| + ||\\mathbf{N}_B||} \\]\n   \\[ \\alpha_B = \\frac{||\\mathbf{N}_A||}{||\\mathbf{N}_A|| + ||\\mathbf{N}_B||} \\]\n   \\[ \\alpha_C = -\\frac{||\\mathbf{N}_D||}{||\\mathbf{N}_C|| + ||\\mathbf{N}_D||} \\]\n   \\[ \\alpha_D = -\\frac{||\\mathbf{N}_C||}{||\\mathbf{N}_C|| + ||\\mathbf{N}_D||} \\]\n\n4. **Stiffness Calculation**: The stiffness coefficient λ is calculated based on distances from vertices to the edge and material bending stiffness:\n   \\[ h_A = ||(p_C - p_A) - (p_D - p_C) * (\\mathbf{e}^T(p_C-p_A))|| \\]\n   \\[ h_B = ||(p_C - p_B) - (p_D - p_C) * (\\mathbf{e}^T(p_C-p_B))|| \\]\n   \\[ l = ||p_C - p_D|| \\]\n   \\[ \\lambda = \\frac{2}{3} \\cdot \\frac{(h_A + h_B)}{h_A^2 \\cdot h_B^2} \\cdot l \\cdot K_{material} \\]\n\n5. **Force Calculation**: The resultant force R is computed as a weighted sum of vertices, and then applied to each vertex with stiffness λ:\n   \\[ R = p_A * \\alpha_A +  p_B * \\alpha_B +  p_C * \\alpha_C +  p_D * \\alpha_D \\]\n\n6. **Potential Energy**: The potential energy U associated with the bending force is given by:\n   \\[ U = \\frac{1}{2} R^T K R \\]\n\n### Physical Interpretation\n- **Bending Stiffness**: Ensures that adjacent triangles maintain a smooth transition, avoiding abrupt changes in curvature which would be physically unrealistic.\n- **Material Properties**: The material bending stiffness affects the overall flexibility of the mesh; higher values make the object stiffer and less prone to deformation.\n- **Stability**: Ensuring proper balance between forces applied at vertices helps stabilize simulations by preventing excessive oscillations or instabilities.\n\n### Conclusion\nThis component provides a robust method for simulating realistic bending behavior in deformable objects, contributing significantly to creating believable interactions within the SOFA framework."
  },
  "summary": {
    "abstract": "The FastTriangularBendingSprings component adds springs to a triangular mesh to prevent bending by enforcing elastic forces between vertices of triangles sharing an edge, using parameters like bending stiffness and minimum distance validity.",
    "sheet": "# FastTriangularBendingSprings\n\n## Overview\nFastTriangularBendingSprings is a force field that prevents bending in triangular meshes by adding springs between vertices of adjacent triangles. It inherits from the `ForceField` class and requires a topology container to define the mesh structure.\n\n## Mathematical Model\nThe component calculates elastic forces based on vertex positions and material properties:\n1. **Normals Calculation**: Normals at each vertex are computed using cross products of adjacent edges:\n   \\[ \\mathbf{N}_A = (\\mathbf{p_C} - \\mathbf{p_A}) \\times (\\mathbf{p_D} - \\mathbf{p_A}) \\]\n   \\[ \\mathbf{N}_B = (\\mathbf{p_D} - \\mathbf{p_B}) \\times (\\mathbf{p_C} - \\mathbf{p_B}) \\]\n   \\[ \\mathbf{N}_C = -(\\mathbf{p_B} - \\mathbf{p_C}) \\times (\\mathbf{p_A} - \\mathbf{p_C}) \\]\n   \\[ \\mathbf{N}_D = -(\\mathbf{p_A} - \\mathbf{p_D}) \\times (\\mathbf{p_B} - \\mathbf{p_D}) \\]\n2. **Alpha Weights**: These are used to balance contributions from different vertices:\n   \\[ \\alpha_A = \\frac{||\\mathbf{N}_B||}{||\\mathbf{N}_A|| + ||\\mathbf{N}_B||} \\]\n   \\[ \\alpha_B = \\frac{||\\mathbf{N}_A||}{||\\mathbf{N}_A|| + ||\\mathbf{N}_B||} \\]\n   \\[ \\alpha_C = -\\frac{||\\mathbf{N}_D||}{||\\mathbf{N}_C|| + ||\\mathbf{N}_D||} \\]\n   \\[ \\alpha_D = -\\frac{||\\mathbf{N}_C||}{||\\mathbf{N}_C|| + ||\\mathbf{N}_D||} \\]\n3. **Stiffness Calculation**: The stiffness coefficient \\(\\lambda\\) is calculated based on distances from vertices to the edge and material bending stiffness:\n   \\[ h_A = ||(p_C - p_A) - (p_D - p_C) * (\\mathbf{e}^T(p_C-p_A))|| \\]\n   \\[ h_B = ||(p_C - p_B) - (p_D - p_C) * (\\mathbf{e}^T(p_C-p_B))|| \\]\n   \\[ l = ||p_C - p_D|| \\]\n   \\[ \\lambda = \\frac{2}{3} \\cdot \\frac{(h_A + h_B)}{h_A^2 \\cdot h_B^2} \\cdot l \\cdot K_{material} \\]\n4. **Force Calculation**: The resultant force \\(R\\) is computed as a weighted sum of vertices, and then applied to each vertex with stiffness \\(\\lambda\\):\n   \\[ R = p_A * \\alpha_A +  p_B * \\alpha_B +  p_C * \\alpha_C +  p_D * \\alpha_D \\]\n5. **Potential Energy**: The potential energy \\(U\\) associated with the bending force is given by:\n   \\[ U = \\frac{1}{2} R^T K R \\]\n\n## Parameters and Data\n- `bendingStiffness`: Bending stiffness of the material (SReal, default: not specified).\n- `minDistValidity`: Distance under which a spring is not valid (SReal, default: not specified).\n\n## Dependencies and Connections\nThis component requires a topology container (`BaseMeshTopology`) to define the mesh structure.\n"
  }
}