├── images ├── collision │ ├── SAP.png │ ├── IncrSAP.png │ ├── DirectSAP.png │ ├── CollisionSteps.png │ ├── CollisionVisitor.png │ ├── RayTraceDetection.png │ ├── BruteForceDetection.png │ ├── CollisionContactManager.png │ ├── LocalMinDistance-cones.png │ ├── LocalMinDistance-detection.png │ ├── MinProximityIntersection.png │ └── LocalMinDistance-degenerated.png ├── plugins │ └── SOFA_FETCH.png ├── FEM │ ├── ConstantForceField.png │ └── Tetra-ParentConfig.png ├── usingSOFA │ ├── TimerProfiler.png │ ├── lockSceneGraph.png │ ├── videorecordmenu.png │ └── CaduceusProfiling.png ├── linearsolver │ ├── CGLinearSolver.png │ ├── SparseLDLSolver.png │ ├── SparseLUSolver.png │ └── SparseCholeskySolver.png ├── integrationscheme │ ├── StaticSolver.png │ ├── EulerExplicitSolver.png │ ├── EulerImplicitSolver.png │ └── NewmarkImplicitSolver.png ├── contributingtoSOFA │ └── sofa_tests_vs.png ├── animationloop │ ├── DefaultAnimationLoop.png │ ├── MultiStepAnimationLoop.png │ └── FreeMotionAnimationLoop.png └── gettingstarted │ ├── install_qt_windows_1.png │ └── install_qt_windows_2.png ├── 35_Plugins ├── 40_Create_your_plugin_.md ├── 50_Usual_plugins │ ├── MultiThreading │ │ ├── ParallelStiffSpringForceField.md │ │ ├── ParallelMeshSpringForceField.md │ │ ├── ParallelBVHNarrowPhase.md │ │ ├── ParallelTetrahedronFEMForceField.md │ │ ├── ParallelBruteForceBroadPhase.md │ │ ├── BeamLinearMapping_mt.md │ │ └── ParallelHexahedronFEMForceField.md │ ├── 30_Python_scripting.md │ ├── 60_Xitact.md │ ├── 75_SofaCarving.md │ ├── 65_HAPI.md │ └── 80_MultiThreading.md ├── 45_Suported_Plugins_List.md ├── 30_Use_a_plugin_binaries.md ├── 10_What_is_a_plugin.md ├── 25_Fetch_plugin_code_source.md └── 20_Build_a_plugin_from_sources.md ├── 15_Using_SOFA ├── 25_Create_your_scene_in_Cpp_.md ├── 10_SceneChecking.md ├── 90_Use_SOFA_in_Matlab.md └── 10_runSofa.md ├── 50_Contributing_to_SOFA ├── 30_Writing_doc.md ├── 40_Continuous_integration.md └── 50_Add_your_paper_on_HAL.md ├── 30_Components ├── 25_Engine │ ├── 30_Transform │ │ ├── 27_TransformEngine.md │ │ └── 28_TransformPosition.md │ ├── 26_TextureInterpolation.md │ ├── 10_Generate │ │ └── 32_Vertex2Frame.md │ └── 20_Select │ │ ├── 34_SubsetTopology.md │ │ └── 10_ROI_Selection.md ├── 48_IO │ └── 10_Mesh │ │ ├── 20_MeshOBJLoader.md │ │ ├── 50_MeshVTKLoader.md │ │ ├── 30_MeshOffLoader.md │ │ ├── 40_MeshSTLLoader.md │ │ ├── 10_MeshGmshLoader.md │ │ └── 80_VTKExport.md ├── 15_Collision │ ├── 10_Detection │ │ ├── 20_Intersection │ │ │ ├── 10_IntersectionMethod.md │ │ │ ├── 50_MinProximityIntersection.md │ │ │ └── 60_LocalMinDistance.md │ │ └── 10_Algorithm │ │ │ ├── 17_BruteForceBroadPhase.md │ │ │ ├── 33_RayTraceNarrowPhase.md │ │ │ ├── 31_BVHNarrowPhase.md │ │ │ ├── 32_DirectSAPNarrowPhase.md │ │ │ ├── 10_CollisionPipeline.md │ │ │ ├── 30_NarrowPhase.md │ │ │ ├── 15_BroadPhase.md │ │ │ ├── 20_DefaultPipeline.md │ │ │ └── 20_Detection_Sweep_and_Prune.md │ ├── 20_Geometry │ │ └── 40_CollisionModels.md │ └── 60_CollisionGroupManagers │ │ └── 10_CollisionGroupManager.md ├── 35_MechanicalLoad │ ├── 20_ConstantForceField.md │ └── 10_ConicalForceField.md ├── 20_Constraint │ ├── 20_Lagrangian │ │ └── Model │ │ │ ├── FixedLagrangianConstraint.md │ │ │ ├── 50_UnilateralLagrangianConstraint.md │ │ │ └── 30_BilateralLagrangianConstraint.md │ └── 10_Projective │ │ ├── 10_AttachProjectiveConstraint.md │ │ └── 50_FixedProjectiveConstraint.md ├── 75_UI │ ├── 10_Customizing_the_UI.md │ └── 20_Recorded_Camera.md ├── 10_AnimationLoop │ ├── 20_MultiStepAnimationLoop.md │ ├── 30_FreeMotionAnimationLoop.md │ └── 10_DefaultAnimationLoop.md ├── 65_Rendering │ ├── 10_Different_Viewports.md │ ├── 40_Lighting.md │ └── 20_Shaders.md ├── 45_LinearSolver │ ├── 20_Direct │ │ ├── 40_SparseCholeskySolver.md │ │ ├── 60_SparseLUSolver.md │ │ ├── 55_AsyncSparseLDLSolver.md │ │ └── 50_SparseLDLSolver.md │ └── 10_Iterative │ │ ├── 10_CGLinearSolver.md │ │ └── 80_Preconditioned_CG.md ├── 40_ODESolver │ ├── 20_Backward │ │ ├── 60_NewmarkImplicitSolver.md │ │ ├── NewtonRaphsonSolver.md │ │ ├── BDFOdeSolver.md │ │ └── 50_StaticSolver.md │ └── 10_Forward │ │ └── 10_EulerExplicitSolver.md ├── 30_SolidMechanics │ ├── 10_FEM │ │ └── HyperElastic │ │ │ └── 30_TetrahedronHyperelasticityFEMForceField.md │ └── 20_Spring │ │ └── 80_PolynomialSpringsForceField.md ├── 50_Mapping │ ├── NonLinear │ │ ├── SquareMapping.md │ │ └── AreaMapping.md │ └── Linear │ │ └── IdentityMapping.md ├── 70_Visual │ └── 20_VisualStyle.md └── 55_Mass │ ├── 10_UniformMass.md │ └── 30_DiagonalMass.md ├── 10_Getting_Started ├── 25_Video_Tutorials │ ├── 40_Step_by_Step.md │ ├── 30_Introduction_course.md │ ├── 10_How_to_compile_SOFA.md │ └── 20_How_to_compile_a_plugin.md ├── 15_Binaries │ └── 10_Binaries_instructions.md └── 20_Build │ └── 50_Activate_Plugins.md ├── 20_Simulation_Principles ├── 50_Multi-Model_Representation │ └── 30_Visual_Model.md ├── 70_Engine.md ├── 12_Visitors.md ├── 60_Constraint │ └── 10_Projective_Constraint.md └── 11_Animation_Loop.md ├── .github └── workflows │ └── trigger-doc.yml ├── 40_Programming_with_SOFA ├── 60_API_overview │ ├── 20_Create_links.md │ ├── 45_Pause_the_animation.md │ ├── 13_DataTypes.md │ ├── 15_Forward_declaration.md │ ├── 80_Macro_for_deprecation.md │ └── 40_Events_in_SOFA.md ├── 05_SOFA_packages.md ├── 50_Create_your_binaries.md └── 30_Create_your_component.md └── README.md /images/collision/SAP.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sofa-framework/doc/HEAD/images/collision/SAP.png -------------------------------------------------------------------------------- /images/collision/IncrSAP.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sofa-framework/doc/HEAD/images/collision/IncrSAP.png -------------------------------------------------------------------------------- /images/plugins/SOFA_FETCH.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sofa-framework/doc/HEAD/images/plugins/SOFA_FETCH.png -------------------------------------------------------------------------------- /images/collision/DirectSAP.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sofa-framework/doc/HEAD/images/collision/DirectSAP.png -------------------------------------------------------------------------------- /images/FEM/ConstantForceField.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sofa-framework/doc/HEAD/images/FEM/ConstantForceField.png -------------------------------------------------------------------------------- /images/FEM/Tetra-ParentConfig.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sofa-framework/doc/HEAD/images/FEM/Tetra-ParentConfig.png -------------------------------------------------------------------------------- /images/usingSOFA/TimerProfiler.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sofa-framework/doc/HEAD/images/usingSOFA/TimerProfiler.png -------------------------------------------------------------------------------- /images/collision/CollisionSteps.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sofa-framework/doc/HEAD/images/collision/CollisionSteps.png -------------------------------------------------------------------------------- /images/collision/CollisionVisitor.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sofa-framework/doc/HEAD/images/collision/CollisionVisitor.png -------------------------------------------------------------------------------- /images/usingSOFA/lockSceneGraph.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sofa-framework/doc/HEAD/images/usingSOFA/lockSceneGraph.png -------------------------------------------------------------------------------- /images/usingSOFA/videorecordmenu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sofa-framework/doc/HEAD/images/usingSOFA/videorecordmenu.png -------------------------------------------------------------------------------- /images/collision/RayTraceDetection.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sofa-framework/doc/HEAD/images/collision/RayTraceDetection.png -------------------------------------------------------------------------------- /images/linearsolver/CGLinearSolver.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sofa-framework/doc/HEAD/images/linearsolver/CGLinearSolver.png -------------------------------------------------------------------------------- /images/linearsolver/SparseLDLSolver.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sofa-framework/doc/HEAD/images/linearsolver/SparseLDLSolver.png -------------------------------------------------------------------------------- /images/linearsolver/SparseLUSolver.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sofa-framework/doc/HEAD/images/linearsolver/SparseLUSolver.png -------------------------------------------------------------------------------- /images/usingSOFA/CaduceusProfiling.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sofa-framework/doc/HEAD/images/usingSOFA/CaduceusProfiling.png -------------------------------------------------------------------------------- /images/collision/BruteForceDetection.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sofa-framework/doc/HEAD/images/collision/BruteForceDetection.png -------------------------------------------------------------------------------- /images/integrationscheme/StaticSolver.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sofa-framework/doc/HEAD/images/integrationscheme/StaticSolver.png -------------------------------------------------------------------------------- /images/collision/CollisionContactManager.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sofa-framework/doc/HEAD/images/collision/CollisionContactManager.png -------------------------------------------------------------------------------- /images/collision/LocalMinDistance-cones.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sofa-framework/doc/HEAD/images/collision/LocalMinDistance-cones.png -------------------------------------------------------------------------------- /images/contributingtoSOFA/sofa_tests_vs.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sofa-framework/doc/HEAD/images/contributingtoSOFA/sofa_tests_vs.png -------------------------------------------------------------------------------- /images/linearsolver/SparseCholeskySolver.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sofa-framework/doc/HEAD/images/linearsolver/SparseCholeskySolver.png -------------------------------------------------------------------------------- /35_Plugins/40_Create_your_plugin_.md: -------------------------------------------------------------------------------- 1 | 2 | See [Programming with SOFA > Create your plugin](../../programming-with-sofa/create-your-plugin/). 3 | -------------------------------------------------------------------------------- /images/animationloop/DefaultAnimationLoop.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sofa-framework/doc/HEAD/images/animationloop/DefaultAnimationLoop.png -------------------------------------------------------------------------------- /images/animationloop/MultiStepAnimationLoop.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sofa-framework/doc/HEAD/images/animationloop/MultiStepAnimationLoop.png -------------------------------------------------------------------------------- /images/collision/LocalMinDistance-detection.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sofa-framework/doc/HEAD/images/collision/LocalMinDistance-detection.png -------------------------------------------------------------------------------- /images/collision/MinProximityIntersection.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sofa-framework/doc/HEAD/images/collision/MinProximityIntersection.png -------------------------------------------------------------------------------- /images/gettingstarted/install_qt_windows_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sofa-framework/doc/HEAD/images/gettingstarted/install_qt_windows_1.png -------------------------------------------------------------------------------- /images/gettingstarted/install_qt_windows_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sofa-framework/doc/HEAD/images/gettingstarted/install_qt_windows_2.png -------------------------------------------------------------------------------- /images/animationloop/FreeMotionAnimationLoop.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sofa-framework/doc/HEAD/images/animationloop/FreeMotionAnimationLoop.png -------------------------------------------------------------------------------- /images/collision/LocalMinDistance-degenerated.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sofa-framework/doc/HEAD/images/collision/LocalMinDistance-degenerated.png -------------------------------------------------------------------------------- /images/integrationscheme/EulerExplicitSolver.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sofa-framework/doc/HEAD/images/integrationscheme/EulerExplicitSolver.png -------------------------------------------------------------------------------- /images/integrationscheme/EulerImplicitSolver.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sofa-framework/doc/HEAD/images/integrationscheme/EulerImplicitSolver.png -------------------------------------------------------------------------------- /images/integrationscheme/NewmarkImplicitSolver.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sofa-framework/doc/HEAD/images/integrationscheme/NewmarkImplicitSolver.png -------------------------------------------------------------------------------- /15_Using_SOFA/25_Create_your_scene_in_Cpp_.md: -------------------------------------------------------------------------------- 1 | 2 | See [Programming with SOFA > Create your scene in C++](../../programming-with-sofa/create-your-scene-in-cpp/). 3 | -------------------------------------------------------------------------------- /35_Plugins/50_Usual_plugins/MultiThreading/ParallelStiffSpringForceField.md: -------------------------------------------------------------------------------- 1 | # ParallelSpringForceField 2 | 3 | ParallelSpringForceField is the multi-threaded equivalent of SpringForceField. 4 | -------------------------------------------------------------------------------- /35_Plugins/50_Usual_plugins/MultiThreading/ParallelMeshSpringForceField.md: -------------------------------------------------------------------------------- 1 | # ParallelMeshSpringForceField 2 | 3 | ParallelMeshSpringForceField is the multi-threaded equivalent of MeshSpringForceField. 4 | -------------------------------------------------------------------------------- /50_Contributing_to_SOFA/30_Writing_doc.md: -------------------------------------------------------------------------------- 1 | In order to allow anyone in the community to help us improve the documentation, this doc is open-source and available on GitHub. Feel free edit it [directly on GitHub](https://github.com/sofa-framework/doc/tree/master)! 2 | 3 | Any feedback is always welcome! -------------------------------------------------------------------------------- /35_Plugins/50_Usual_plugins/30_Python_scripting.md: -------------------------------------------------------------------------------- 1 | SofaPython3 2 | ----------- 3 | 4 | The SofaPython3 plugin has its own [GitHub repository](https://github.com/sofa-framework/sofapython3/). A dedicated documentation for the plugin is available online: 5 | 6 | See [SofaPython3 > readthedoc](https://sofapython3.readthedocs.io/en/latest/index.html) -------------------------------------------------------------------------------- /30_Components/25_Engine/30_Transform/27_TransformEngine.md: -------------------------------------------------------------------------------- 1 | `TransformEngine 2 | =============== 3 | 4 | This component belongs to the category of [Engines](../../../../simulation-principles/engine/). The TransformEngine transforms the positions of one DataFields into new positions after applying a transformation. This transformation can be either: translation, rotation or scale. 5 | -------------------------------------------------------------------------------- /30_Components/25_Engine/26_TextureInterpolation.md: -------------------------------------------------------------------------------- 1 | TextureInterpolation 2 | ==================== 3 | 4 | This component belongs to the category of [Engines](../../../simulation-principles/engine/). This engine creates texture coordinate in 1D according to an input state vector. Coordinate can be interpolated either from min and max value of input states (default behavior) or on a manual define scale. 5 | -------------------------------------------------------------------------------- /35_Plugins/50_Usual_plugins/MultiThreading/ParallelBVHNarrowPhase.md: -------------------------------------------------------------------------------- 1 | # ParallelBVHNarrowPhase 2 | 3 | This component is a parallel implementation of [BVHNarrowPhase](../../../../components/collision/detection/algorithm/bvhnarrowphase/) using a global thread pool. 4 | It means the result of a simulation with [BVHNarrowPhase](../../../../components/collision/detection/algorithm/bvhnarrowphase/) or with ParallelBVHNarrowPhase is expected to be equal. 5 | -------------------------------------------------------------------------------- /15_Using_SOFA/10_SceneChecking.md: -------------------------------------------------------------------------------- 1 | # Scene Checking 2 | 3 | When the `runSofa` application loads a scene, it performs several verification checks. These checks help ensure the scene follows implicit design rules. If any issues are detected during the verification process, warning messages are displayed in the console. 4 | 5 | Using a SOFA built from sources, you can activate or de-activate these checks using the CMake flag `APPLICATION_SCENECHECKING` 6 | 7 | -------------------------------------------------------------------------------- /30_Components/25_Engine/10_Generate/32_Vertex2Frame.md: -------------------------------------------------------------------------------- 1 | Vertex2Frame 2 | ============ 3 | 4 | This component belongs to the category of [Engines](../../../../simulation-principles/engine/). For each point defined in an .obj file, this engine computes a set of rigid points using the normals. Normal vector will be collinear to the Z axis and orthonormal to X and Y as showed bellow: 5 | 6 | ``` 7 | Y 8 | | 9 | | / X 10 | | / 11 | | / 12 | |/_ _ _ _ _ Z/normal 13 | ``` 14 | -------------------------------------------------------------------------------- /35_Plugins/50_Usual_plugins/MultiThreading/ParallelTetrahedronFEMForceField.md: -------------------------------------------------------------------------------- 1 | # ParallelTetrahedronFEMForceField 2 | 3 | ParallelTetrahedronFEMForceField is the multi-threaded equivalent of [TetrahedronFEMForceField](../../../../components/solidmechanics/fem/elastic/tetrahedronfemforcefield). 4 | 5 | This implementation is the most efficient when the number of tetrahedron is large (> 1000). 6 | 7 | The following methods are executed in parallel: 8 | - `addDForce` 9 | - `addKToMatrix` 10 | -------------------------------------------------------------------------------- /30_Components/48_IO/10_Mesh/20_MeshOBJLoader.md: -------------------------------------------------------------------------------- 1 | MeshOBJLoader 2 | ============= 3 | 4 | This component belongs to the category of the [MeshLoaders](../../../../simulation-principles/topology/#meshloaders). 5 | 6 | The MeshOBJLoader loads a mesh from a file under the format \*.obj. Such a mesh file **only supports surface meshes**. The \*.obj meshes can be generated using software like [Blender](https://blender.org/). 7 | 8 | Usage 9 | ----- 10 | 11 | **No pre-requisite** in your scene to use a MeshLoader. 12 | -------------------------------------------------------------------------------- /50_Contributing_to_SOFA/40_Continuous_integration.md: -------------------------------------------------------------------------------- 1 | Each commit or pull-request is built and tested using Jenkins. 2 | You can find the Jenkins platform for continuous integration here: 3 | 4 |

5 | [**Continuous Integration Platform**](https://ci.inria.fr/sofa-ci-dev/) 6 |

7 | 8 | A dashboard presents all the SOFA builds. 9 | You can find this interface here: 10 | 11 | 12 |

13 | [**Dashboard**](http://www.sofa-framework.org/dash/) 14 |

-------------------------------------------------------------------------------- /30_Components/25_Engine/30_Transform/28_TransformPosition.md: -------------------------------------------------------------------------------- 1 | TransformPosition 2 | =============== 3 | 4 | This component belongs to the category of [Engines](../../../../simulation-principles/engine/). The TransformPosition engine transforms the positions of one DataFields into new positions after applying a transformation. This transformation can be either: 5 | 6 | - Projection on a plane (plane defined by an origin and a normal vector) 7 | - Translation, rotation, scale and some combinations of translation rotation and scale 8 | -------------------------------------------------------------------------------- /30_Components/48_IO/10_Mesh/50_MeshVTKLoader.md: -------------------------------------------------------------------------------- 1 | MeshVTKLoader 2 | ============= 3 | 4 | This component belongs to the category of the [MeshLoaders](../../../../simulation-principles/topology/#meshloaders). 5 | 6 | The MeshVTKLoader loads a mesh from a file under the format \*.vtk. Such a mesh file can be either surface or volumetric meshes. The \*.vtk meshes can be generated using the [Paraview](https://www.paraview.org) software. 7 | 8 | Usage 9 | ----- 10 | 11 | **No pre-requisite** in your scene to use a MeshLoader. 12 | -------------------------------------------------------------------------------- /30_Components/48_IO/10_Mesh/30_MeshOffLoader.md: -------------------------------------------------------------------------------- 1 | MeshOffLoader 2 | ============= 3 | 4 | This component belongs to the category of the [MeshLoaders](../../../../simulation-principles/topology/#meshloaders). 5 | 6 | The MeshOffLoader loads a mesh from a file under the format \*.off. Such a mesh file can be either surface or volumetric meshes. The \*.off meshes can be generated using software like [MeshLab](https://www.meshlab.net/). 7 | 8 | Usage 9 | ----- 10 | 11 | **No pre-requisite** in your scene to use a MeshLoader. 12 | 13 | -------------------------------------------------------------------------------- /35_Plugins/45_Suported_Plugins_List.md: -------------------------------------------------------------------------------- 1 | # Officially supported plugins 2 | 3 | This page aims at summarizing all plugins that are officially supported by the SOFA consortium. 4 | This means that the SOFA consortium commits to: 5 | 6 | 1. Including them in our continuous integration pipeline, thus assessing the compilation at every push in the SOFA master branch, at each new pull-request and at each nightly build 7 | 2. Including them in the official bi-annual SOFA binaries 8 | 3. Providing technical support on these plugins 9 | 10 | -------------------------------------------------------------------------------- /30_Components/25_Engine/20_Select/34_SubsetTopology.md: -------------------------------------------------------------------------------- 1 | SubsetTopology 2 | ============== 3 | 4 | This component belongs to the category of [Engines](../../../../simulation-principles/engine/). This engine separate topology in two parts, considering a ROI, a topology inside and a topology outside the ROI which can be a sphere or a box ROI used in this engine are similar to BoxROI and SphereROI. 5 | 6 | ![SubsetTopology](https://www.sofa-framework.org/wp-content/uploads/2014/11/SubsetTopology.png){.wp-image-1612 .alignright width="40%" height="auto"} 7 | -------------------------------------------------------------------------------- /30_Components/15_Collision/10_Detection/20_Intersection/10_IntersectionMethod.md: -------------------------------------------------------------------------------- 1 | Intersection Method 2 | =================== 3 | 4 | In SOFA, a proximity method can be used to detect contact when two objects are getting closer to another. 5 | Evaluating this proximity allows for a better anticipation of the contact, i.e. more stable contact. 6 | 7 | Examples of Components 8 | ====================== 9 | 10 | The following components are all intersection methods, and can be placed in a simulation scene: 11 | 12 | - [_MinProximityIntersection_](./../minproximityintersection) 13 | - [_LocalMinDistance_](./../localmindistance) 14 | -------------------------------------------------------------------------------- /10_Getting_Started/25_Video_Tutorials/40_Step_by_Step.md: -------------------------------------------------------------------------------- 1 | This video presents how to create a simulation in SOFA. Find the associated presentation [here (PDF version)](https://www.sofa-framework.org/wp-content/uploads/2016/08/2-Tutorial.pdf "Tutorial.pdf") 2 | 3 | 4 | 5 | We hope these videos helped you understand the basis of SOFA. If you want to provide us any [feedback](https://www.sofa-framework.org/users-feedback/ "Users' feedback"), do not hesitate. 6 | 7 | -------------------------------------------------------------------------------- /30_Components/48_IO/10_Mesh/40_MeshSTLLoader.md: -------------------------------------------------------------------------------- 1 | MeshSTLLoader 2 | ============= 3 | 4 | This component belongs to the category of the [MeshLoaders](../../../../simulation-principles/topology/#meshloaders). 5 | 6 | The MeshSTLLoader loads a mesh from a file under the [format \*.stl](https://en.wikipedia.org/wiki/STL_(file_format)). Such a mesh file **only supports surface meshes**. The \*.stl format is widely spread and such meshes can be generated using software like [MeshLab](https://www.meshlab.net/) or [Paraview](https://www.paraview.org) among many other solutions. 7 | 8 | Usage 9 | ----- 10 | 11 | **No pre-requisite** in your scene to use a MeshLoader. 12 | -------------------------------------------------------------------------------- /35_Plugins/50_Usual_plugins/MultiThreading/ParallelBruteForceBroadPhase.md: -------------------------------------------------------------------------------- 1 | # ParallelBruteForceBroadPhase 2 | 3 | This component is a parallel implementation of [BruteForceBroadPhase](../../../../components/collision/detection/algorithm/bruteforcebroadphase/) using a global thread pool. 4 | It means the result of a simulation with [BruteForceBroadPhase](../../../../components/collision/detection/algorithm/bruteforcebroadphase/) or with ParallelBruteForceBroadPhase is expected to be equal. 5 | ParallelBruteForceBroadPhase is the most efficient compared to [BruteForceBroadPhase](../../../../components/collision/detection/algorithm/bruteforcebroadphase/) when there is a lot of objects in the scene. 6 | -------------------------------------------------------------------------------- /30_Components/48_IO/10_Mesh/10_MeshGmshLoader.md: -------------------------------------------------------------------------------- 1 | MeshGmshLoader 2 | ============== 3 | 4 | This component belongs to the category of the [MeshLoaders](../../../../simulation-principles/topology/#meshloaders). 5 | 6 | The MeshGmshLoader loads a mesh from a file under the format \*.msh. Such a mesh file can be either surface or volumetric meshes. The \*.msh meshes can be generated using software like [Gmsh](https://gmsh.info/). 7 | To be noted, an interesting [project couples SOFA and Gmsh in python](https://github.com/sescaida/gmsh-sofa_tutorial) for applications such as parametric design or design optimization. 8 | 9 | Usage 10 | ----- 11 | 12 | **No pre-requisite** in your scene to use a MeshLoader. 13 | 14 | -------------------------------------------------------------------------------- /35_Plugins/50_Usual_plugins/60_Xitact.md: -------------------------------------------------------------------------------- 1 | Xitact are haptic device product by the company **Mentice**. Two models are handled in SOFA: 2 | 3 | - Xitact™ IHP: a haptic device designed to track the motion of a 4 | surgical instrument and to provide realistic force feedback during 5 | the simulation of a minimally invasive surgical procedure. 6 | - Xitact™ ITP: a device designed to track the motion of an instrument 7 | during the simulation of a minimally invasive surgical procedure. 8 | 9 | Install 10 | ------- 11 | 12 | Here is a walkthrough on how to install, compile and use in SOFA: 13 | 14 | - Activate the plugin Xitact: **SOFA-PLUGIN\_XITACT**, 15 | - Compile Sofa again, 16 | - This is it. 17 | 18 | -------------------------------------------------------------------------------- /10_Getting_Started/25_Video_Tutorials/30_Introduction_course.md: -------------------------------------------------------------------------------- 1 | In order to help you starting with SOFA, we recorded a video of the SOFA days. This first video presents an generic introduction to the main principles of SOFA. Find the associated presentation [here (PDF version)](https://www.sofa-framework.org/wp-content/uploads/2016/08/1-Presentation-SOFA-VRIPHYS2015.pdf "Presentation-SOFA-VRIPHYS2015.pdf"). 2 | 3 | 2023 Tutorial (using SOFA v23.06): 4 | 5 | 6 | 7 | 8 | All SOFA tutorials are available here on our YouTube channel: [Tutorial playlist](https://www.youtube.com/playlist?list=PLL2-UDGHPj0iLCieVkrv3OvAme0jsWl91). 9 | -------------------------------------------------------------------------------- /20_Simulation_Principles/50_Multi-Model_Representation/30_Visual_Model.md: -------------------------------------------------------------------------------- 1 | Visualization 2 | ============= 3 | 4 | To visualize an object in SOFA, the main component to use is the _OglModel_. 5 | Using OpenGL, this class will display the topology of its context. To display a mesh loaded with any MeshLoader, all you need to do is to connect the OglModel with the MeshLoader by writing (in case if an XML scene): 6 | 7 | ```xml 8 | 9 | 10 | ``` 11 | 12 | You can also specify some Data like _color_ or _scale_. 13 | 14 | Note that since the approach of SOFA separate the different representations, the visual model can use a different topology (a different mesh) than the physical or the collision model. -------------------------------------------------------------------------------- /35_Plugins/50_Usual_plugins/MultiThreading/BeamLinearMapping_mt.md: -------------------------------------------------------------------------------- 1 | ## BeamLinearMapping_mt 2 | 3 | This component inherits all the functionality from the BeamLinearMapping component and overrides three virtual functions that contain a `for` loop: `apply()`, `applyJ()` and `applyJT()`. 4 | It adds only one data attribute, the granularity. This attribute sets the number of iterations of the `for` loop, corresponding to the number of points along the beam elements that must be assigned and executed for each task. 5 | If this number is lower than the number of iterations the loop won't be parallelized, and the corresponding BeamLinearMapping function is called. 6 | If this number is greater than the number of iterations of the loop the tasks are created, and each task executes the granularity value of iterations of the loop. 7 | -------------------------------------------------------------------------------- /35_Plugins/30_Use_a_plugin_binaries.md: -------------------------------------------------------------------------------- 1 | # Use plugin binaries 2 | 3 | SOFA is regularly released along with several officially-supported plugins. However, many more plugins do exist. It may occur that someone shares with you the binaries of a plugin (pre-compiled plugin) which are not distributed in the SOFA releases. Make sure this third-party plugin is trustworthy. 4 | 5 | ## Compatibility check 6 | 7 | In such a case, one must firstly check that the compilation environment of the plugin should be compatible with yours: 8 | - check the operating system 9 | - check the SOFA version 10 | - check the version of the dependencies (libraries like Python, pybind11, Qt, Boost, Eigen, TinyXML2, Glew, Zlib, libPNG, libJPEG, libTIFF) 11 | 12 | 13 | ## Load in SOFA 14 | 15 | See [What is a plugin > Plugin loading](./../what-is-a-plugin/#plugin_loading). 16 | -------------------------------------------------------------------------------- /10_Getting_Started/25_Video_Tutorials/10_How_to_compile_SOFA.md: -------------------------------------------------------------------------------- 1 | In order to assist you in the compilation of SOFA, we recorded a video detailing the steps to follow to download, but most importantly install SOFA sources. 2 | 3 | Linux 4 | ----- 5 | 6 | In this video, the sources correspond to the master branch of SOFA. The operating system is a fresh XUbuntu (18.04). 7 | 8 | 9 | 10 | 11 | Windows 12 | ------- 13 | 14 | Developers of the community also created a video to assist you to compile SOFA on Windows 10: 15 | -------------------------------------------------------------------------------- /15_Using_SOFA/90_Use_SOFA_in_Matlab.md: -------------------------------------------------------------------------------- 1 | This was done for Ubuntu. 2 | 3 | Launch Matlab preloading libraries that SOFA uses 4 | ------------------------------------------------- 5 | In command line, write: 6 | 7 | ``` 8 | LD_PRELOAD=”/usr/lib/x86_64-linux-gnu/libstdc++.so.6:/usr/lib/x86_64-linux-gnu/libQt5OpenGLusr/lib/x86_64-linux-gnu/libQt5Widgets.so.5:/usr/lib/x86_64-linux-gnu/libQt5Gui.so.5:/usr/lib/x86_64-linux-gnu/libQt5Core.so.5″ matlab 9 | ``` 10 | 11 | From a Matlab script launch sofa 12 | -------------------------------- 13 | In Matlab, define: 14 | 15 | ``` 16 | pathToSofaScene = fullfile(PATH_TO_SOFA_SCENES, ‘sofaScene.scn’) 17 | [status, result] = system([‘PATH_TO_SOFA_BIN/runSofa -g batch -n 10’ pathToSofaScene]); 18 | ``` 19 | 20 | It reads in result the SOFA terminal output. 21 | 22 | 23 | __Note__: Matlab plots, and other Qt related functions (write png images) will be a bit broken 24 | -------------------------------------------------------------------------------- /10_Getting_Started/25_Video_Tutorials/20_How_to_compile_a_plugin.md: -------------------------------------------------------------------------------- 1 | In order to develop your own codes, SOFA allows to develop plugins separately from the SOFA open-source core. This tutorial shows how to organize and compile one or several plugins outside from SOFA. 2 | 3 | Linux (with SOFA sources) 4 | ------------------------- 5 | 6 | This video shows how to download and compile a plugin ( [MyAwesomeComponents](https://github.com/sofa-framework/MyAwesomeComponents) ) when you have a compiled version of SOFA. The operating system is a fresh XUbuntu (18.04). The plugin sources are located out from the SOFA sources, but compiled with SOFA. 7 | 8 | 9 | 10 | 11 | Linux (with SOFA binaries) 12 | -------------------------- 13 | 14 | Coming soon. -------------------------------------------------------------------------------- /30_Components/35_MechanicalLoad/20_ConstantForceField.md: -------------------------------------------------------------------------------- 1 | ConstantForceField 2 | ================== 3 | 4 | This component belongs to the category of [ForceField](../../../simulation-principles/multi-model-representation/forcefield/). The ConstantForceField is a simple force field applying the same constant force on each node. This force field is not integrated over the domain of our object, but simply distributed over the number of nodes. 5 | 6 | 7 | 8 | 9 | 10 | 11 | Usage 12 | ----- 13 | 14 | As a Forcefield, the ConstantForceField requires a **MechanicalObject** and the associated **solvers** (integration scheme and linear solver), as well as a **PointSetTopologyContainer**. 15 | -------------------------------------------------------------------------------- /30_Components/20_Constraint/20_Lagrangian/Model/FixedLagrangianConstraint.md: -------------------------------------------------------------------------------- 1 | FixedLagrangianConstraint 2 | ========================= 3 | 4 | This component belongs to the category of [Constraint Laws](../../../../../simulation-principles/constraint/lagrange-constraint/#constraint-laws) used for the Lagrange constraint resolution. 5 | The FixedLagrangianConstraint defines a [holonomic constraint](https://en.wikipedia.org/wiki/Holonomic_constraints) law applied on some degrees on freedom to fix them in space. 6 | 7 | The constraint equation can be written as: 8 | 9 | $$ 10 | \Phi(q) = q - q_0 11 | $$ 12 | 13 | where $q$ is the position and $q_0$ is the initial position. 14 | 15 | The constraint matrix $\mathbf{H}$ (derivative of the constraint law) is then filled with blocks of the identity matrix (of the dimension of the number of degrees of freedom per point) under each considered fixed index. If `fixAll` is selected, then this Jacobian is the identity matrix. 16 | 17 | $$ 18 | \mathbf{H} = \mathbf{I} 19 | $$ 20 | -------------------------------------------------------------------------------- /30_Components/75_UI/10_Customizing_the_UI.md: -------------------------------------------------------------------------------- 1 | #### AttachBodyButtonSetting 2 | 3 | Tune the attachBody mouse operation, like which button is used for the 4 | operation and the stiffness of the spring. 5 | 6 | #### FixPickedParticleButtonSetting 7 | 8 | Specify the mouse button used for this particular operation. 9 | 10 | #### ViewerSetting 11 | 12 | Customize things like the resolution of the viewer, the camera 13 | projection, and the picking method. The picking can be done through ray 14 | casting (default) or can be imaged based by using a selection buffer. If 15 | you use the picking with the selection buffer you can only pick the 16 | surface primitives like triangles and spheres which belong to the 17 | collision layer of your models. 18 | 19 | #### BackgroundSetting 20 | 21 | Tune the color or the image used for the background of the viewer. 22 | 23 | #### SofaDefaultPathSetting 24 | 25 | Tell Sofa where to put your simulation records and gnuplot files. 26 | 27 | #### StatsSettings 28 | 29 | Give access to various logging options. 30 | -------------------------------------------------------------------------------- /.github/workflows/trigger-doc.yml: -------------------------------------------------------------------------------- 1 | name: Trigger DocGenerateAndPublish Workflow 2 | 3 | on: 4 | workflow_dispatch: 5 | inputs: 6 | script-branch: 7 | description: 'Specify the branch on which the DocGenerateAndPublish action should run' 8 | default: 'gen' 9 | type: string 10 | schedule: 11 | - cron: '0 6 * * 1' # Every Monday morning 12 | push: 13 | branches: 14 | - master 15 | 16 | jobs: 17 | trigger_workflow: 18 | runs-on: ubuntu-latest 19 | steps: 20 | - uses: actions/checkout@v3 21 | - name: Run on dispatch 22 | if: ${{ github.event_name == 'workflow_dispatch' }} 23 | run: gh workflow run DocGenerateAndPublish --ref ${{ inputs.script-branch }} 24 | env: 25 | GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} 26 | - name: Run on push and nightly 27 | if: ${{ github.event_name != 'workflow_dispatch' }} 28 | run: gh workflow run DocGenerateAndPublish --ref gen 29 | env: 30 | GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} 31 | -------------------------------------------------------------------------------- /35_Plugins/50_Usual_plugins/75_SofaCarving.md: -------------------------------------------------------------------------------- 1 | The SofaCarving plugin provides basic functionality for removing 2 | tetrahedra from a mesh. This can be used to simulate tissue destruction 3 | in medical simulations. []() 4 | 5 | Loading the Plugin 6 | --------------------------------------------------- 7 | 8 | To load the SofaCarving plugin, select **SOFA-PLUGIN\_SOFACARVING** in 9 | your Cmake configuration. Reconfigure, generate and build. []() 10 | 11 | CarvingManager 12 | ----------------------------------------------- 13 | 14 | The plugin provides one component, the CarvingManager. When added to a 15 | scene, it automatically looks for a collision model that will act as 16 | the tool from removing tetrahedra, and a surface model that will have 17 | its tetrahedra removed by the tool. If your scene has many possible 18 | collision or surface models, you can specify the ones that the 19 | CarvingManager will use by giving those components the tags 20 | **CarvingTool** and **CarvingSurface**. See the example scene 21 | **SofaCarving/SimpleCarving.scn**. 22 | -------------------------------------------------------------------------------- /30_Components/10_AnimationLoop/20_MultiStepAnimationLoop.md: -------------------------------------------------------------------------------- 1 | MultiStepAnimationLoop 2 | ====================== 3 | 4 | This component belongs to the category of [AnimationLoop](../../../simulation-principles/animation-loop/). 5 | 6 | The MultiStepAnimationLoop derives from the [DefaultAnimationLoop](../../../components/animationloop/defaultanimationloop/). This animation loop is different due to the fact that it allows - at each iteration - for running several collision (_collisionSteps_), and within each of these collision steps, several integration sub-steps can be computed (_integrationSteps_). 7 | 8 | 9 | 10 | 11 | Usage 12 | ----- 13 | 14 | The MultiStepAnimationLoop has **no pre-requisite**. 15 | 16 | Note that this MultiStepAnimationLoop does not handle constraints solved using [Lagrange multipliers](../../../simulation-principles/constraint/lagrange-constraint/). 17 | -------------------------------------------------------------------------------- /30_Components/65_Rendering/10_Different_Viewports.md: -------------------------------------------------------------------------------- 1 | Using different views in OpenGL 2 | ------------------------------- 3 | 4 | You can get different points of view of your scene. It can be useful if 5 | you want to watch something for example. In order to get those 6 | viewports, you have to add : 7 | 8 | ```xml 9 | 10 | ``` 11 | 12 | where : 13 | 14 | - screenPosition = : position on the viewer 15 | - screenSize = : size of the viewport 16 | - cameraPosition = : position of the camera in eye's space 17 | - cameraOrientation = : camera's orientation (direction and 18 | up vectors) 19 | 20 | **cameraPosition** and **cameraOrientation** can be easily retrieved, 21 | using viewer's view file: get the view you want to add with the main 22 | viewer, save the view, open the resulting yourscene.scn.view file and 23 | copy-paste the 2 vectors into the corresponding fields. 24 | 25 | #### Example 26 | 27 | - [example/Component/visualmodel/OglViewport.scn](https://github.com/sofa-framework/sofa/blob/master/examples/Component/Visual/OglViewport.scn) 28 | 29 | -------------------------------------------------------------------------------- /35_Plugins/50_Usual_plugins/MultiThreading/ParallelHexahedronFEMForceField.md: -------------------------------------------------------------------------------- 1 | # ParallelHexahedronFEMForceField 2 | 3 | ParallelHexahedronFEMForceField is the multi-threaded equivalent of [HexahedronFEMForceField](../../../../components/solidmechanics/fem/elastic/hexahedronfemforcefield). 4 | 5 | This implementation is the most efficient when: 6 | 7 | 1) the number of hexahedron is large (> 1000) 8 | 2) the global system matrix is not assembled. It is usually the case with a [CGLinearSolver](../../../../components/linearsolver/iterative/cglinearsolver/) templated with GraphScattered types. 9 | 3) the method is 'large'. If the method is 'polar' or 'small', `addForce` is executed sequentially, but `addDForce` in parallel. 10 | 11 | The following methods are executed in parallel: 12 | 13 | - `addForce` for method 'large'. 14 | - `addDForce` 15 | 16 | The method `addKToMatrix` is not executed in parallel. 17 | This method is called with an assembled system, usually with a direct solver or a [CGLinearSolver](../../../../components/linearsolver/iterative/cglinearsolver/) templated with types different from GraphScattered. 18 | In this case, the most time-consuming step is to invert the matrix. This is where efforts should be put to accelerate the simulation. 19 | -------------------------------------------------------------------------------- /30_Components/65_Rendering/40_Lighting.md: -------------------------------------------------------------------------------- 1 | Adding Lights 2 | ------------- 3 | 4 | One white global light illuminates the scene by default. This can be 5 | changed through a light manager object and a certain number of lights 6 | (limited by OpenGL). The first step is to add the object called 7 | LightManager, preferably at the top of the scene file. 8 | 9 | ```xml 10 | 11 | ``` 12 | 13 | After that, we can add 3 different kinds of lights : 14 | 15 | - a positional light (parameters : color, position) ; 16 | 17 | ```xml 18 | 19 | ``` 20 | 21 | - a directional light (parameters : color, direction) ; 22 | 23 | ```xml 24 | 25 | ``` 26 | 27 | - a spotlight (parameters : color, position, direction, cut off, 28 | exponent, attenuation) 29 | 30 | ```xml 31 | 32 | ``` 33 | 34 | #### Example 35 | 36 | - [example/Component/visualmodel/LightManager.scn](https://github.com/sofa-framework/sofa/blob/master/examples/Component/Visual/LightManager.scn) 37 | 38 | 39 | -------------------------------------------------------------------------------- /30_Components/15_Collision/10_Detection/10_Algorithm/17_BruteForceBroadPhase.md: -------------------------------------------------------------------------------- 1 | Broad Phase: Brute Force Broad Phase 2 | ==================================== 3 | 4 | BruteForceBroadPhase is a [broad phase component](./../broadphase), which is used in a [Collision Detection](../../collisionpipeline/#collision-detection) pipeline. 5 | 6 | The method is based on the comparison of the overall [bounding volumes](https://en.wikipedia.org/wiki/Bounding_volume) of objects to determine if they are in collision or not. 7 | This test is very exhaustive because of its $n^2/2$ pairwise checks. 8 | In SOFA, the proposed bounding volumes are commonly Axis-Aligned-Bounding-Box (AABB). 9 | 10 | Since, the bounding volumes are very simple (AABB), the tests are very fast for a few collision models. 11 | A more advanced method must be selected for simulations involving a high number of objects. 12 | 13 | A parallel implementation (_ParallelBruteForceBroadPhase_) can be found in the plugin MultiThreading. 14 | 15 | Example of Usage 16 | ================ 17 | 18 | This component is used as follows in XML format: 19 | 20 | ```xml 21 | 22 | 23 | 24 | 25 | 26 | 27 | ``` -------------------------------------------------------------------------------- /40_Programming_with_SOFA/60_API_overview/20_Create_links.md: -------------------------------------------------------------------------------- 1 | A [Link](../../../using-sofa/lexicography/#link) allow you to access a SOFA component from another one anywhere 2 | in the simulation graph. In your scene creation file, it usually appears 3 | as : input=@../component. In this page we explain how to use it. In your 4 | .h, declare your link : 5 | 6 | ``` cpp 7 | //Where it comes from (usually you do not need to include it, it is already included) 8 | #include 9 | //Use a typedef to make it readable 10 | typedef sofa::core::objectmodel::SingleLink< FROM_CLASS, TO_CLASS, LINK_FLAG> MyLink; 11 | MyLink mylink; 12 | ``` 13 | 14 | In your constructor use : 15 | 16 | ``` cpp 17 | MyConstructor::MyConstructor():mylink(initLink('name', 'help')){} 18 | ``` 19 | 20 | The list of flags you can use is available in the [SOFA API](https://www.sofa-framework.org/api/ "SOFA API") in the [LinkFlags enumeration](https://www.sofa-framework.org/api/master/sofa/html/classsofa_1_1core_1_1objectmodel_1_1_base_link.html#a5e9e323c0eca40c08a8020da6631c1bd) "SofaAPIBaseLink. 21 | Here is a link to the [BaseLink 22 | API](https://www.sofa-framework.org/api/master/sofa/html/classsofa_1_1core_1_1objectmodel_1_1_base_link.html). Here 23 | is an example from [mapping.h]([https://www.sofa-framework.org/api/SOFA/_mapping_8h_source.html](https://www.sofa-framework.org/api/master/sofa/html/classsofa_1_1core_1_1_mapping.html#aae1ae4761c3febd5116b71ba53f6a42c)). 24 | See the Mapping.inl for implementation also. 25 | -------------------------------------------------------------------------------- /30_Components/65_Rendering/20_Shaders.md: -------------------------------------------------------------------------------- 1 | General use of Shaders 2 | ---------------------- 3 | 4 | A complete set of tools about using shaders is implemented into SOFA. 5 | The three kinds of shaders (vertex and fragments (mandatory), geometry 6 | (optional)) are available. Shader is used only for Visual Model as 7 | **OglModel**. The effects of the shader is spread to the associated 8 | subtree. Finally, there is only one shader activated for each visual 9 | model : if two shaders are present in the same node, only the second 10 | will be effective. To simply include a shader, add this into your node : 11 | 12 | ```xml 13 | ``` 14 | 15 | vertFilename and fragFilename are the only mandatory parameters. Other 16 | optional parameters are about geometry shader : geoFilename, 17 | geometryInputType, geometryOutputType and geometryVerticesOut. A last 18 | parameter, turnOn, is for debugging purpose, when you want to disable 19 | shader without restarting the scene. If you want to send values to 20 | uniform variables defined into the shader, a certain number of objects 21 | is available : 22 | 23 | - OglIntVariable,OglInt{2,3,4}Variable : for int and ivec{2,3,4} 24 | - OglFloatVariable,OglFloat{2,3,4}Variable : for float and vec{2,3,4} 25 | - OglIntVectorVariable, OglIntVector{2,3,4}Variable : for arrays of 26 | int and ivec{2,3,4} 27 | - OglFloatVectorVariable, OglFloatVector{2,3,4}Variable : for arrays 28 | of float and vec{2,3,4} 29 | - OglMatrix{2,3,4}x{2,3,4} : for matrix n\*m where n and m = {2,3,4} 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /30_Components/20_Constraint/10_Projective/10_AttachProjectiveConstraint.md: -------------------------------------------------------------------------------- 1 | AttachProjectiveConstraint 2 | ================ 3 | 4 | This component belongs to the category of [Projective Constraint](../../../../simulation-principles/constraint/projective-constraint/). 5 | The AttachProjectiveConstraint works with a pair of objects, and it projects the degrees of freedom (e.g. position) and their derivatives (e.g. velocity), so that both objects are attached. 6 | As being a projective constraint, this projective constraints ensures a geometrical connection between both objects at the end of the time step, but it does not integrate the physics of both object (contrary to Lagrange based constraints). 7 | 8 | 9 | Note that constraining objects using the data **twoWay** will project the constraint vertices of both _object1_ and _object2_ towards their average degrees of freedom and derivatives: 10 | ```cpp 11 | Deriv corr = (dx2-dx1)*0.5*responseFactor*getConstraintFactor(index); 12 | dx1 += corr; 13 | dx2 -= corr; 14 | ``` 15 | - if false, the position of the _object1_ are projected onto the _object2_. Therefore, _object2_ only follows _object1_ without affecting the motion of _object1_ 16 | ```cpp 17 | dx2 = Deriv(); 18 | ``` 19 | 20 | 21 | Usage 22 | ----- 23 | 24 | The AttachProjectiveConstraint **requires** two MechanicalObjects so that both degrees of freedom can be accessed and projected to the attached configuration. An integration scheme and a solver are also necessary to solve the linear system at each time step. 25 | -------------------------------------------------------------------------------- /30_Components/15_Collision/20_Geometry/40_CollisionModels.md: -------------------------------------------------------------------------------- 1 | Collision Models 2 | ================ 3 | 4 | SOFA implements a series of collision primitives called CollisionModel. A CollisionModel contains a list of same-type elements. It can be part of a list of CollisionModels or a hierarchy. Here is a list of them: 5 | 6 | - [pointcollisionmodel](./../pointcollisionmodel) 7 | - [linecollisionmodel](./../linecollisionmodel) 8 | - [trianglecollisionmodel](./../trianglecollisionmodel) 9 | - [spherecollisionmodel](./../spherecollisionmodel) 10 | - [cylindercollisionmodel](./../cylindercollisionmodel) 11 | - [cubecollisionmodel](./../cubecollisionmodel) 12 | - [raycollisionmodel](./../raycollisionmodel) 13 | 14 | See the detailed description of the [CollisionModel class](https://www.sofa-framework.org/api/master/sofa/html/classsofa_1_1core_1_1_collision_model.html). 15 | 16 | Note that the data **contactStiffness** is only taken into account in the case you are using a collision response using the [Penalty method](../../../../simulation-principles/multi-model-representation/collision/#collision-response). 17 | 18 | 19 | 20 | Usage 21 | ----- 22 | 23 | To use a CollisionModel, you must first make sure that the collision node in which the CollisionModel is defined does contain the associated topology (e.g. TriangleSetTopologyContainer if you want to use the TriangleCollisionModel). 24 | 25 | Moreover, the collision model is usually mapped to a node containing the mechanical representation of the object. The collision node should therefore include a mapping. 26 | 27 | -------------------------------------------------------------------------------- /30_Components/45_LinearSolver/20_Direct/40_SparseCholeskySolver.md: -------------------------------------------------------------------------------- 1 | SparseCholeskySolver 2 | ==================== 3 | 4 | This component belongs to the category of [LinearSolver](../../../../simulation-principles/system-resolution/linear-solver/). The role of the SparseLUSolver is to solve the linear system $\mathbf{A}x=b$ assuming that the matrix $\mathbf{A}$ is symmetric and sparse. 5 | 6 | The Cholesky decomposition (https://en.wikipedia.org/wiki/Cholesky_decomposition) is a numerical method that solves a linear system $mathbf{A}x=b$ by factorizing the matrix of the system as $\mathbf{LL^T}$. By doing so, we only need to solve two triangular systems to compute the solution. It is only applyable on **symetric** matrices but is roughtly twice as efficient as the LU solver. The $\mathbf{LDL^T}$ decomposition is heavily related to the Cholesky decomposition. 7 | 8 | $$ 9 | \begin{cases}\mathbf{A}x=b \\ \mathbf{A}=\mathbf{LL^T}\end{cases}\Longleftrightarrow\begin{cases} \mathbf{L} y = b \\ \mathbf{L}^T x = y \\ \end{cases} 10 | $$ 11 | 12 | 13 | Sequence diagram 14 | ---------------- 15 | 16 | 17 | 18 | 19 | 20 | The SparseCholeskySolver **requires** the use (above in the scene graph) of an integration scheme, and (below in the scene graph) of a MechanicalObject storing the state information that the SparseCholeskySolver will access. 21 | -------------------------------------------------------------------------------- /50_Contributing_to_SOFA/50_Add_your_paper_on_HAL.md: -------------------------------------------------------------------------------- 1 | You want your papers, which rely on SOFA, to be listed on our website? Just follow the following explanations for HAL. 2 | 3 | ![](https://www.sofa-framework.org/wp-content/uploads/2016/06/tampon-hal.jpg) 4 | 5 | ## Case 1 - add a new paper on HAL 6 | 7 | First, go on the [HAL portal](https://hal.archives-ouvertes.fr/) and log in. Follow carefully the following steps: The upload process starts by clicking on "Submit": 8 | 9 | * choose the type of paper (poster, conference or journal ..) 10 | * upload the compulsory documents: 11 | * the PDF document, 12 | * videos, or others supplementary data, if any, 13 | * one or several images: do not forget to define one image as primary as shown in the following image. 14 | 15 | ![](https://www.sofa-framework.org/wp-content/uploads/2016/06/AjoutVignettes.png) 16 | 17 |
_Specify one image as "Primary"_
18 | 19 | * check the automatic formatting (title, summary of the work, keywords, information about the conference/journal, etc.), 20 | * **add "SOFA" in the field "Collaboration/Project"**, 21 | * add the authors, 22 | * check the overall information and validate it. 23 | 24 | It's done ! Your paper will automatically appear in our publication list! 25 | 26 | ## Case 2 - list a former paper 27 | 28 | If you already uploaded your paper on HAL, but you want to refer this paper in our publication list, follow the instruction: 29 | 30 | * [Log in](https://hal.archives-ouvertes.fr/) with your HAL account, 31 | * Edit the metadata of the paper, 32 | * **add "SOFA" in the field "Collaboration/Project"**. -------------------------------------------------------------------------------- /30_Components/10_AnimationLoop/30_FreeMotionAnimationLoop.md: -------------------------------------------------------------------------------- 1 | FreeMotionAnimationLoop 2 | ======================= 3 | 4 | This component belongs to the category of [AnimationLoop](../../../simulation-principles/animation-loop/). 5 | 6 | The FreeMotionAnimationLoop is the component that rules the simulation in two main steps: a free motion, then a correction step. First, the free motion computes the projective constraints, the physics, solving the resulting free linear system. Second, the correction step solves the constraints based on the Lagrange multipliers. More information on the constraint resolution can be found [here](../../../simulation-principles/constraint/lagrange-constraint/). 7 | 8 | 9 | 10 | 11 | Usage 12 | ----- 13 | 14 | The FreeMotionAnimationLoop must be used specifically for constraint resolution based on the Lagrange multiplier. It therefore **requires**: 15 | 16 | - a [ConstraintSolver](../../../simulation-principles/constraint/lagrange-constraint/#constraintsolver-in-sofa). If no constraint solver can be found, a LCPConstraintSolver is automatically created by default. 17 | 18 | Note that one or multiple [ConstraintCorrection](../../../simulation-principles/constraint/lagrange-constraint/#constraintcorrection) may be required by the [ConstraintSolver](../../../simulation-principles/constraint/lagrange-constraint/#constraintsolver-in-sofa). 19 | 20 | -------------------------------------------------------------------------------- /40_Programming_with_SOFA/60_API_overview/45_Pause_the_animation.md: -------------------------------------------------------------------------------- 1 | Pause the Animation 2 | ------------------- 3 | 4 | Sometimes, you would like the animation to be paused without pressing 5 | any button but from the **Simulation** itself. For example if solver 6 | does not converge, you might want to stop the animation to look 7 | at it carefully, or because the interesting part is over. This is now 8 | possible, using a **PauseAnimation** component. This component has a 9 | method *pause()* that tells the Simulation it should be paused using 10 | *setPaused()* a WriteAccessor on the Simulation field paused. The 11 | RealGUI step() we check the state of the Simulation to know if we should 12 | stop the Animation, pressing back the Animate button. 13 | 14 | #### PauseAnimationOnEvent 15 | 16 | **PauseAnimationOnEvent** is derived from **PauseAnimation** and handles 17 | *PauseEvent* event. When it receives this event, it calls the *pause()* 18 | method. Add the following component on your scene description: 19 | 20 | ```xml 21 | listening="true" 22 | ``` 23 | 24 | Then launch the PauseEvent where you want to in your code. For example, 25 | when your solver does not succeed to converge, or when the simulated end 26 | time has been reached... (To learn how to launch a visitor). 27 | 28 | #### Quick component hierarchy overview 29 | 30 | \[caption id="attachment\_1551" align="aligncenter" 31 | width="350"\][![PauseAnimation 32 | architecture](https://www.sofa-framework.org/wp-content/uploads/2014/11/350px-PauseAnimation1.png){.size-full 33 | .wp-image-1551 width="350" 34 | height="239"}](https://www.sofa-framework.org/wp-content/uploads/2014/11/350px-PauseAnimation1.png) 35 | PauseAnimation architecture\[/caption\] 36 | -------------------------------------------------------------------------------- /35_Plugins/10_What_is_a_plugin.md: -------------------------------------------------------------------------------- 1 | # What is a Plugin? 2 | 3 | SOFA allows to extend its feature with a plugin mechanism. A plugin is a shared library that can be loaded dynamically at run-time by SOFA. More features become available, such as new components or alternative scene loaders. 4 | 5 | # Online plugin list 6 | 7 | The [Online plugin list](https://www.sofa-framework.org/applications/plugins/) highlights some of the SOFA plugins. Never hesitate to request, inquire for one or to [submit your own plugin](https://www.sofa-framework.org/applications/submit/). 8 | 9 | # Plugin Loading 10 | 11 | In order to use the features of a plugin, it must be loaded first. SOFA offers multiple ways to load a plugin. 12 | 13 | ## Command-line Argument 14 | 15 | The application `runSofa` accepts an optional argument `-l,--load` to specify a list of plugins to load. A plugin can be provided as a full path, or as a name. In the latter case, the plugin library will be searched in known folders for a match. 16 | 17 | ## Automatic Loading 18 | 19 | By default, the application `runSofa` reads the content of a configuration file to load automatically a list of plugins. This list can be edited to add the plugin you need. The file is either `plugin_list.conf` or `plugin_list.conf.default`. `plugin_list.conf.default` is generated automatically at compile-time and is not meant to be edited. To edit a list of plugins, `plugin_list.conf` must be used. If the file does not exist, it must be created based on `plugin_list.conf.default`. 20 | 21 | ## GUI: Plugin Manager 22 | 23 | The GUI allows to load a plugin through a graphical user interface. Go to `Edit > Plugin Manager ...`. You will see the list of already loaded plugins. Click on `Add...` to load another plugin. 24 | -------------------------------------------------------------------------------- /30_Components/15_Collision/10_Detection/10_Algorithm/33_RayTraceNarrowPhase.md: -------------------------------------------------------------------------------- 1 | Narrow Phase: Ray Trace Narrow Phase 2 | ==================================== 3 | 4 | The RayTraceNarrowPhase component is a [narrow phase component](./../narrowphase), which is used in the detection phase of a [CollisionPipeline](../../collisionpipeline/#collision-detection). 5 | This method traces a ray for each point in one object following the opposite of the point's normal up to find a triangle in the other object. 6 | Both triangles are tested to evaluate if they are in a colliding state. 7 | 8 | It **must be used with a TriangleOctreeModel**, as an octree is used to traverse the object. 9 | 10 | The Algorithm 11 | ============= 12 | 13 | The CollisionModel at the lowest level is saved, in this case it must be a TriangleOctreeModel. If the octree would not be constructed already, build it. Then, rays are traced against the TriangleOctreeModel. Distances computed with the ray indicates if a collision occurs between the pair of TriangleOctreeModels. Finally, the DetectionOutput vector containing elements of TriangleOctreeModels in collision is returned, as well as the contact points on the triangle of each model. 14 | 15 | Example of Usage 16 | ================ 17 | 18 | This component can be used as follows in XML format: 19 | 20 | ```xml 21 | 22 | 23 | 24 | 25 | 26 | 27 | ``` 28 | 29 | Colliding objects must have a TriangleOctreeModel: 30 | 31 | ```xml 32 | 33 | ``` -------------------------------------------------------------------------------- /30_Components/15_Collision/10_Detection/10_Algorithm/31_BVHNarrowPhase.md: -------------------------------------------------------------------------------- 1 | Narrow Phase: BVH Narrow Phase 2 | ============================== 3 | 4 | BVHNarrowPhase is [narrow phase component](./../narrowphase), which is used in the detection phase of a [CollisionPipeline](../../collisionpipeline/#collision-detection). 5 | The algorithm is based on a Bounding Volume Hierarchy (BVH). 6 | 7 | 8 | Bounding Volume Hierarchy 9 | ========================= 10 | 11 | The data structure is built or updated by the collision pipeline before the actual collision detection. 12 | The hierarchy is contained internally into the collision models, through linked collision models and lists of elements (see CollisionModel). 13 | 14 | The Algorithm 15 | ============= 16 | 17 | The algorithm examines a potential collision between a pair of collision models, which has been detected in the broad phase. 18 | This test is time-consuming, this is why it is necessary to have a broad phase which eliminates a maximum number of pairs. 19 | For a pair of collision models, the algorithm traverses the hierarchy of collision elements to rapidly eliminate pairs of elements which are not in intersection. 20 | Finally, the intersection method is called on the remaining pairs of elements. 21 | 22 | Note that the algorithm is written in its iterative form, instead of a recursive form. 23 | 24 | A parallel implementation (ParallelBVHNarrowPhase) can be found in the plugin MultiThreading. 25 | 26 | Example of Usage 27 | ================ 28 | 29 | This component is used as follows in XML format: 30 | 31 | ```xml 32 | 33 | 34 | 35 | 36 | 37 | 38 | ``` -------------------------------------------------------------------------------- /30_Components/45_LinearSolver/20_Direct/60_SparseLUSolver.md: -------------------------------------------------------------------------------- 1 | SparseLUSolver 2 | ============== 3 | 4 | This component belongs to the category of [LinearSolver](../../../../simulation-principles/system-resolution/linear-solver/). The role of the SparseLUSolver is to solve the linear system $\mathbf{A}x=b$ assuming that the matrix $\mathbf{A}$ is invertible and sparse. 5 | 6 | In order to solve this system, this solver will factorize the matrix $\mathbf{A}$ into the product $\mathbf{A=LU}$ where $\mathbf{L}$ is a lower triangular matrix with ones on its diagonal and $\mathbf{U}$ is an upper triangular matrix (for more, see [LU decomposition article](https://en.wikipedia.org/wiki/LU_decomposition)). 7 | 8 | As this method relies on the Gaussian elimination, a partial pivot is applied on the lines of $\mathbf{A}$ hence its factorization will be written as $\mathbf{PA=LU}$ . 9 | The LU solver is a direct solver which will compute the exact solution of the linear system by successively solving two triangular systems. 10 | 11 | $$ 12 | \begin{cases} \mathbf{A}x = b\\ 13 | \mathbf{PA}=\mathbf{LU} 14 | \end{case} \Longleftrightarrow 15 | \begin{cases} \mathbf{L}y=\mathbf{P}b\\ 16 | \mathbf{U} x = y \\ 17 | \end{case} 18 | $$ 19 | 20 | 21 | Usage 22 | ----- 23 | 24 | 25 | The SparseLUSolver **requires** the use (above in the scene graph) of an integration scheme, and (below in the scene graph) of a MechanicalObject storing the state information that the SparseLUSolver will access. 26 | 27 | The SparseLUSolver is the most generic direct solver. It may be time consuming but it will be able compute the exact solution as soon as $$\mathbf{A}"> is invertible. 28 | -------------------------------------------------------------------------------- /30_Components/10_AnimationLoop/10_DefaultAnimationLoop.md: -------------------------------------------------------------------------------- 1 | DefaultAnimationLoop 2 | ==================== 3 | 4 | This component belongs to the category of [AnimationLoop](../../../simulation-principles/animation-loop/). 5 | 6 | The DefaultAnimationLoop is the component that rules the steps of the simulation in the default order. It consists in computing the collision (if any), the projective constraints, the physics, solving the resulting linear system and finally updating all data before another step begins. 7 | 8 | 9 | 10 | 11 | Data 12 | ---- 13 | 14 | The DefaultAnimationLoop has one data: 15 | 16 | - **parallelODESolving**: if true, solves all the ODEs in parallel 17 | - **computeBoundingBox**: a boolean defining whether the global bounding box of the scene is computed at each time step. Used mostly for rendering. 18 | 19 | 20 | Usage 21 | ----- 22 | 23 | The DefaultAnimationLoop has **no pre-requisite**. If no AnimationLoop is specified in the scene, this animation loop is included by default at the root node of the graph. 24 | 25 | Note that this AnimationLoop does not support constraints solved using [Lagrange multipliers](../../../simulation-principles/constraint/lagrange-constraint/). 26 | 27 | 28 | Example 29 | ------- 30 | 31 | This component is used as follows in XML format: 32 | 33 | ``` xml 34 | 35 | ``` 36 | 37 | or using SofaPython3: 38 | 39 | ``` python 40 | node.addObject('DefaultAnimationLoop') 41 | ``` 42 | 43 | An example scene involving a DefaultAnimationLoop is available in [*examples/Component/AnimationLoop/DefaultAnimationLoop.scn*](https://github.com/sofa-framework/sofa/blob/master/examples/Component/AnimationLoop/DefaultAnimationLoop.scn) 44 | -------------------------------------------------------------------------------- /30_Components/40_ODESolver/20_Backward/60_NewmarkImplicitSolver.md: -------------------------------------------------------------------------------- 1 | NewmarkImplicitSolver 2 | ===================== 3 | 4 | This component belongs to the category of [integration schemes or ODE Solver](../../../../simulation-principles/system-resolution/integration-scheme/). 5 | 6 | This scheme is an implicit time integrator for dynamic system using the Newmark scheme. To compute the new position or new velocity, the NewmarkImplicitSolver is based on the following equations: 7 | 8 | $$ 9 | x_{t+h}=x_t+h v_t+\frac{h^2}{2}((1-2\beta)a_t+2\beta a_{t+h}) 10 | $$ 11 | 12 | $$ 13 | v_{t+h}=v_t+h((1-\gamma)a_t+\gamma a_{t+h}) 14 | $$ 15 | 16 | 17 | Applied to a mechanical system where $\small Ma_t+(r_MM+r_KK)v_t+Kx_t=f_{ext}$, we need to solve the following system: 18 | 19 | 20 | $$ 21 | \tiny Ma_{t+h}+(r_MM+r_KK)v_{t+h}+Kx_{t+h}=f_{ext} 22 | $$ 23 | 24 | $$ 25 | \tiny Ma_{t+h}+(r_MM+r_KK)(v_t+h((1-\gamma)a_t+\gamma a_{t+h}))+K(x_t+hv_t+\frac{h^2}{2}((1-2\beta)a_t+2\beta a_{t+h}))=f_{ext} 26 | $$ 27 | 28 | $$ 29 | \tiny (M+h\gamma(r_MM+r_KK)+h^2\beta K)a_{t+h}=f_{ext}-(r_MM+r_KK)(v_t+h(1-\gamma)a_t)-K(x_t+hv_t+\frac{h^2(1-2\beta)}{2}a_t) 30 | $$ 31 | 32 | $$ 33 | \tiny ((1+h\gamma r_M)M+(h^2\beta +h\gamma r_K)K)a_{t+h}=f_{ext}-(r_MM+r_KK)v_t-Kx_t-(r_MM+r_KK)(h(1-\gamma)a_t)-K(hv_t+\frac{h^2(1-2\beta)}{2}a_t) 34 | $$ 35 | 36 | $$ 37 | \tiny ((1+h\gamma r_M)M+(h^2\beta+h\gamma r_K)K)a_{t+h}=a_t-(r_MM+r_KK)(h(1-\gamma)a_t)-K(hv_t+\frac{h^2(1-2\beta)}{2}a_t) 38 | $$ 39 | 40 | 41 | 42 | Sequence diagram 43 | ---------------- 44 | 45 | 46 | 47 | 48 | Usage 49 | ----- 50 | 51 | At each simulation step and each Newton Raphson iteration, the NewmarkImplicitSolver **requires**: 52 | 53 | - a [LinearSolver](../../../../simulation-principles/system-resolution/linear-solver/) to solve the linear system 54 | - and a MechanicalObject to store the state vectors. 55 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | SOFA Documentation 2 | ================== 3 | 4 | This section provides articles to help the community starting using SOFA and developing interactive applications. 5 | 6 | 7 | ### Content 8 | - **Getting Started**: instructions about building and installing SOFA. 9 | - **Main Principles**: everything you need to know about what is SOFA and how it works. 10 | - **Video Tutorials**: list videos helping new users starting with SOFA. 11 | - **Using SOFA**: how to use SOFA to build and run simulation scenes (user documentation). 12 | - **Programming with SOFA**: how to write your own code and then contribute it to SOFA (developer documentation). 13 | 14 | 15 | ### Support forum 16 | 17 | Feel free to leverage the [SOFA Discussions forum](http://github.com/sofa-framework/sofa/discussions/) to elaborate on your queries. The supportive SOFA community is eager to offer assistance and guidance. 18 | 19 | ### List of plugins 20 | 21 | Before crafting your own code, explore the [SOFA plugin list](https://www.sofa-framework.org/applications/plugins/). You might just find exactly what you are searching for! 22 | 23 | ### Cite SOFA 24 | 25 | Detailed introductions about SOFA and SOFA in soft-robotics were written: 26 | 27 | - SOFA Framework: **SOFA: A Multi-Model Framework for Interactive Physical Simulation**. F. Faure et al. _Soft Tissue Biomechanical Modeling for Computer Assisted Surgery_, 2012 \[[BibTex](https://hal.inria.fr/hal-00681539v1/bibtex)\] 28 | - SoftRobot: **Software toolkit for modeling, simulation and control of soft robots**. E. Coevoet et al. _Advanced Robotics_, 2017 \[[BibTex](https://hal.inria.fr/hal-01649355v1/bibtex)\] 29 | 30 | ### Contribution 31 | Everyone is very welcome to contribute to this documentation. This can be done by pull-requesting changes on the [documentation GitHub repository](https://github.com/sofa-framework/doc/) or by [reporting any missing information](https://github.com/sofa-framework/doc/issues/new) so that this documentation may constantly improve! 32 | 33 | Files are written in Markdown. If you don't understand the syntax, you can refer to [this useful cheatsheet](https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet). 34 | -------------------------------------------------------------------------------- /30_Components/30_SolidMechanics/10_FEM/HyperElastic/30_TetrahedronHyperelasticityFEMForceField.md: -------------------------------------------------------------------------------- 1 | TetrahedronHyperelasticityFEMForceField 2 | ======================================= 3 | 4 | This component belongs to the category of [ForceField](../../../../../simulation-principles/multi-model-representation/forcefield/). The TetrahedronHyperelasticityFEMForceField implements - for tetrahedral topology only - several non-linear mechanical constitutive laws, also named as hyperelastic constitutive laws. The available models are: 5 | 6 | - [Arruda-Boyce model](https://en.wikipedia.org/wiki/Arruda%E2%80%93Boyce_model) 7 | - [Costa model](https://www.jstor.org/stable/pdf/3066567.pdf) 8 | - [Mooney-Rivlin model](https://en.wikipedia.org/wiki/Mooney%E2%80%93Rivlin_solid) 9 | - [Neo-Hookean model](https://en.wikipedia.org/wiki/Neo-Hookean_solid) 10 | - [Stable Neo-Hookean model](https://dl.acm.org/doi/10.1145/3180491) 11 | - [Ogden model](https://en.wikipedia.org/wiki/Ogden_hyperelastic_model) (order 1) 12 | - [St Venant-Kirchhoff model](https://en.wikipedia.org/wiki/Hyperelastic_material#Saint_Venant%E2%80%93Kirchhoff_model) 13 | - [Veronda-Westmann model](https://www.sciencedirect.com/science/article/pii/0021929070900552) 14 | 15 | 16 | 17 | Note that the **ParameterSet** data changes depending on the chosen material. It corresponds to: 18 | 19 | - for "ArrudaBoyce", two parameters are required: $\left[ \mu ,k_0\right]$ 20 | - for "Costa", eight parameters are required: $\left[ a,k_{0},b_{ff},b_{fs},b_{ss},b_{fn},b_{sn},b_{nn}\right]$ 21 | - for "MooneyRivlin", three parameters are required: $\left[ C_{01},C_{10},k_{0}\right]$ 22 | - for "NeoHookean", two parameters are required: $\left[ \mu,\lambda \right]$ 23 | - for "Ogden", three parameters are required: $\left[ k,\mu_1,\alpha_1\right]$ 24 | - for "StVenantKirchhoff", two parameters are required: $\left[ \mu,\lambda \right]$ 25 | - for "VerondaWestman", parameters are required: $\left[ C_{1},C_{2},k_0\right]$ 26 | 27 | 28 | Usage 29 | ----- 30 | 31 | As a Forcefield, the TetrahedronHyperelasticityFEMForceField requires a **MechanicalObject** and the associated **solvers** (integration scheme and linear solver), as well as a **TetrahedronSetTopologyContainer**. 32 | 33 | -------------------------------------------------------------------------------- /30_Components/45_LinearSolver/10_Iterative/10_CGLinearSolver.md: -------------------------------------------------------------------------------- 1 | CGLinearSolver 2 | ============== 3 | 4 | This component belongs to the category of [LinearSolver](../../../../simulation-principles/system-resolution/linear-solver/). The role of the CGLinearSolver is to solve the linear system $\mathbf{A}x=b$ without any _a priori_ on this system. 5 | 6 | In SOFA, the CGLinearSolver follows the well-known [conjugate gradient method](https://en.wikipedia.org/wiki/Conjugate_gradient_method), which consists in iteratively solving $r=b-\mathbf{A}x^k$ where *r* is known as the residual. This residual will be used to compute mutually conjugate vectors *p* (see the sequence diagram below) which will be used as a basis to find a new approximated solution $x^{k+1}$. 7 | 8 | **Note**: the CGLinearSolver in SOFA assumes that the right hand side (RHS) vector *b* is already computed. The computation of *b* is usually called in the [integration scheme](../../../../simulation-principles/system-resolution/integration-scheme/) through the function `computeForce()`. 9 | 10 | 11 | 12 | Sequence diagram 13 | ---------------- 14 | 15 | 16 | 17 | 18 | Usage 19 | ----- 20 | 21 | The CGLinearSolver **requires** the use (above in the scene graph) of an integration scheme, and (below in the scene graph) of a MechanicalObject storing the state information that the CGLinearSolver will access. 22 | 23 | When using a CGLinearSolver, make sure you carefully chose the value of the free data field iterations, tolerance and threshold. Both tolerance and threshold data must be chosen in accordance with the dimension of the degrees of freedom (DOFs). Usually, the value of these two data is close to the square of the expected error on the DOFs. 24 | 25 | Remember that when using an iterative linear solver like the CGLinearSolver, no exact solution can be found. The accuracy of your solution will always depend on the conditioning of your system and your input data (iterations, tolerance and threshold). 26 | 27 | -------------------------------------------------------------------------------- /30_Components/45_LinearSolver/20_Direct/55_AsyncSparseLDLSolver.md: -------------------------------------------------------------------------------- 1 | AsyncSparseLDLSolver 2 | ==================== 3 | 4 | AsyncSparseLDLSolver is based on [SparseLDLSolver](./../sparseldlsolver/). 5 | It follows some ideas presented in: 6 | 7 | > Courtecuisse, Hadrien, et al. "Asynchronous preconditioners for efficient solving of non-linear deformations." VRIPHYS-Virtual Reality Interaction and Physical Simulation. Eurographics Association, 2010. 8 | https://hal.inria.fr/hal-00688865/document 9 | 10 | ## Asynchronous Factorization 11 | 12 | The difference compared to SparseLDLSolver resides in the fact that the factorization of the matrix is performed in a different thread in order to speed up the simulation. 13 | 14 | The synchronous version performs the following operations (synchronously): 15 | 1) Build the matrix 16 | 2) Factorize the matrix 17 | 3) Solve the system based on the factorization 18 | 19 | In the asynchronous version, the factorization is performed asynchronously. 20 | A consequence is that the solving process uses a factorization which may not be up-to-date. 21 | In practice, the factorization is at least one time step old, but it can be an older factorization depending on the duration of the asynchronous factorization step. 22 | Because of this, the solver computes an approximation of the solution, based on an old factorization. 23 | It is therefore important to understand that using AsyncSparseLDLSolver changes the behavior of your simulation compared to a synchronous version. 24 | It may also introduce instabilities. 25 | 26 | ## A Preconditioner 27 | 28 | AsyncSparseLDLSolver can be used as a preconditioner of [ShewchukPCGLinearSolver](../../iterative/preconditioned-cg/). 29 | 30 | ## Performances 31 | 32 | The idea to have the factorization of the matrix in a different thread is to reduce the time taken to solve a linear system. 33 | However, building the matrix and solving a system based on a factorization will not be reduced. 34 | Since the factorization of a matrix is a time-consuming step of the simulation, this strategy greatly improves the performances. 35 | This speed up is at the price of an approximation of the solution, because solving the linear system relies on a factorization of a matrix from a previous time step. 36 | -------------------------------------------------------------------------------- /40_Programming_with_SOFA/60_API_overview/13_DataTypes.md: -------------------------------------------------------------------------------- 1 | DataTypes 2 | ========= 3 | 4 | As you may know, many SOFA C++ classes are templated, mostly on the type of DOF you want to simulate. Examples of templates can be found in the [MechanicalObject page](../../../simulation-principles/mechanicalobject/), in the [templates section](../../../simulation-principles/mechanicalobject/#templates). In the code, the use of templates can be confusing, especially when the type used in place of the template has itself many types. This page provides a short introduction to all these DOF types. 5 | 6 | All DOF Types must implement (or define) all the following types: 7 | 8 | - **Real**: corresponds to a double or float value, depending on the DataTypes used: a class templated in Vec3d will return a double, whereas a a class templated in Vec3f will return a float 9 | 10 | - **Coord**: standing for "coordinate", corresponds to a vector of _Real_ with a size given by the number of degrees of freedom: a class templated in Vec6d will return a vector of 6 doubles. This vector is homogeneous to your degrees of freedom. 11 | 12 | - **Deriv** standing for "derivative", corresponds to a vector of _Real_ with a size given by the number of degrees of freedom: a class templated in Vec6d will return a vector of 6 doubles 13 | 14 | - **VecCoord** or **VecDeriv**: correspond to a vector of respectively _Coord_ or _Deriv_ 15 | 16 | - **DataVecCoord or DataVecDeriv**: correspond to a [Data](../../../simulation-principles/scene-graph/#data) containing a vector of respectively _Coord_ or _Deriv_. As noted in the associated article, the Data are variable of the class exposed to the user and other components in the scene 17 | 18 | - **MatrixCoord or MatrixDeriv**: correspond to a matrix of respectively _Coord_ or _Deriv_, this is more especially used by solvers and constraint algorithms 19 | 20 | - **VecCoordId, VecDerivId, MatrixCoordId or MatrixDerivId**: correspond to an identifiant value (int) pointing to a vector or matrix of respectively _Coord_ or _Deriv_. This is very useful to access specific vectors or matrix in the simulation. [State vectors](../../../simulation-principles/mechanicalobject/#state-vectors) for instance are managed with specific protected Ids by the solvers. 21 | -------------------------------------------------------------------------------- /30_Components/40_ODESolver/20_Backward/NewtonRaphsonSolver.md: -------------------------------------------------------------------------------- 1 | NewtonRaphsonSolver 2 | =================== 3 | 4 | NewtonRaphsonSolver is a component able to solve nonlinear equations using [Newton-Raphson method](https://en.wikipedia.org/wiki/Newton%27s_method). 5 | From an initial guess, the algorithm successively computes better approximations of the root of the nonlinear function. 6 | At every iteration, multiple criteria are evaluated to decide to stop the algorithm (because it converged or the maximum number of iterations has been reached), or to continue. 7 | 8 | The algorithm relies on the derivative of the function and a linear system to solve. 9 | For a function $F : \mathbb{R}^k \rightarrow \mathbb{R}^k$, the new approximation of the root $x_{n+1}$ is computed as: 10 | 11 | $$ 12 | \nabla_F(x_n) (x_{n+1} - x_n) = -F(x_n) 13 | $$ 14 | 15 | where: 16 | 17 | - $x_i$ is the $i$-th approximation of the root 18 | - $x_0$ is the initial guess 19 | - $\nabla_F$ is the Jacobian matrix of the function 20 | 21 | If $dx$ is the solution of the previous linear system, then 22 | 23 | $$ 24 | x_{n+1} = dx + x_n 25 | $$ 26 | 27 | Example 28 | ------- 29 | 30 | To solve a static equilibrium (see [StaticSolver](StaticSolver.md)), the nonlinear equation to solve is the sum of forces must be equal to zero ($\sum F = 0$). At each iteration, the linear system $K dx = -\sum F$ must be solved to compute the next approximation of the root. Here K is the derivative of the forces, also called the stiffness matrix. 31 | 32 | Usage 33 | ----- 34 | 35 | This component must be linked by another component requiring to solve a nonlinear equation, such as an implicit ODE solver or a static solver. 36 | 37 | In XML format, the link may look like: 38 | 39 | ```xml 40 | 46 | 47 | ``` 48 | -------------------------------------------------------------------------------- /40_Programming_with_SOFA/05_SOFA_packages.md: -------------------------------------------------------------------------------- 1 | Intro 2 | ===== 3 | 4 | In order to allow building plugins separately from SOFA and building an 5 | external application or library which depends on SOFA, we provide cmake 6 | package configurations files. Those files are what cmake looks for when 7 | you call find_package(Something), which is now how you find the 8 | dependencies for your plugins. 9 | 10 | The repository is divided in multiple packages: *SofaFramework* for 11 | framework/, *SofaSimulation* for sofa/simulation, five packages for 12 | modules (divided according to the *SofaComponent\** meta-libraries), and 13 | *SofaGui* for GUI-related libraries. 14 | 15 | Also, there is a package for each plugin that is expected to be used as 16 | a library. (E.g. SofaPython, Compliant, Flexible...) 17 | 18 | The following section lists the libraries is each package. 19 | 20 | Packages 21 | ======== 22 | 23 | Sofa.Framework 24 | -------------- 25 | 26 | - Sofa.Type 27 | - Sofa.LinearAlgebra 28 | - Sofa.Core 29 | - Sofa.Config 30 | - Sofa.Topology 31 | - Sofa.Testing 32 | - Sofa.Simulation 33 | - Sofa.SimpleApi 34 | - Sofa.Helper 35 | - Sofa.Geometry 36 | - Sofa.DefaultType 37 | 38 | 39 | Sofa.Component 40 | -------------- 41 | 42 | - Sofa.Component.AnimationLoop 43 | - Sofa.Component.Collision 44 | - Sofa.Component.Constraint 45 | - Sofa.Component.Controller 46 | - Sofa.Component.Diffusion 47 | - Sofa.Component.Engine 48 | - Sofa.Component.Haptics 49 | - Sofa.Component.IO 50 | - Sofa.Component.LinearSolver 51 | - Sofa.Component.LinearSystem 52 | - Sofa.Component.Mapping 53 | - Sofa.Component.Mass 54 | - Sofa.Component.MechanicalLoad 55 | - Sofa.Component.ODESolver 56 | - Sofa.Component.Playback 57 | - Sofa.Component.SceneUtility 58 | - Sofa.Component.Setting 59 | - Sofa.Component.SolidMechanics 60 | - Sofa.Component.StateContainer 61 | - Sofa.Component.Topology 62 | - Sofa.Component.Visual 63 | 64 | 65 | Sofa.GL 66 | -------------- 67 | 68 | - Sofa.GL 69 | - Sofa.GL.Component.Engine 70 | - Sofa.GL.Component.Rendering2D 71 | - Sofa.GL.Component.Rendering3D 72 | - Sofa.GL.Component.Shader 73 | 74 | 75 | Sofa.GUI 76 | -------------- 77 | 78 | - Sofa.GUI 79 | - Sofa.GUI.Batch 80 | - Sofa.GUI.Common 81 | - Sofa.GUI.Component 82 | - Sofa.GUI.HeadlessRecorder 83 | - Sofa.GUI.Qt 84 | -------------------------------------------------------------------------------- /30_Components/50_Mapping/NonLinear/SquareMapping.md: -------------------------------------------------------------------------------- 1 | # SquareMapping 2 | 3 | This component is classified under the category of [Mappings](../../../../simulation-principles/multi-model-representation/mapping/). 4 | 5 | In this particular mapping, we designate the input as the parent state and the output as the child state. 6 | 7 | ## Mapping Function 8 | 9 | The transformation function employed in this mapping is the square function. 10 | Formally, if $f$ denotes the mapping function, then for any input $x$, the output $f(x)$ is $x^2$. 11 | 12 | Mathematically, this can be expressed as: 13 | 14 | $$ 15 | f(x)=x^2 16 | $$ 17 | 18 | for all $x$ in the domain. 19 | 20 | ## Jacobian Matrix 21 | 22 | The Jacobian matrix of this mapping, which represents the first-order partial derivatives of the output with respect to the input, is not constant, and depends on the input. 23 | 24 | The elements of the Jacobian matrix are given by: 25 | $$ 26 | J_{ij} = \frac{\partial f_i}{\partial x_j} = \delta_{ij} 2 x_j 27 | $$ 28 | 29 | This can be written in matrix form as: 30 | 31 | $$ 32 | J(x) = 2\: \text{diag} (x) 33 | $$ 34 | 35 | Here, $\text{diag}(x)$ denotes a diagonal matrix with the elements of $x$ on the diagonal. 36 | 37 | Since the Jacobian matrix is diagonal, its transpose is equal to itself: 38 | 39 | $$ 40 | J(x)^T = J(x) 41 | $$ 42 | 43 | ## Hessian Tensor 44 | 45 | The Hessian tensor represents the second-order partial derivatives of the output with respect to the input. For the `SquareMapping` component, the Hessian tensor is non-zero because the Jacobian matrix depends on the input $x$. 46 | 47 | The elements of the Hessian tensor are given by: 48 | 49 | $$ 50 | H_{ijk} = \frac{\partial J_{ij}(x)}{\partial x_k} = \frac{\partial (\delta_{ij} 2 x_j)}{\partial x_k} = 2 \delta_{ij} \frac{\partial x_j}{\partial x_k} = 2 \delta_{ij} \delta_{jk} 51 | $$ 52 | 53 | Then, for any vector $v$ 54 | 55 | $$ 56 | (H \cdot v)_{ij} = \sum_k H_{ijk} v_k = 2 \delta_{ij} \sum_k \delta_{jk} v_k = 2 \delta_{ij} v_j 57 | $$ 58 | 59 | In matrix notation, this can be written as: 60 | 61 | $$ 62 | H \cdot v = 2 \: \text{diag}(v) 63 | $$ 64 | 65 | ## Implementation Details 66 | 67 | Given the nature of the mapping function, the mapping is defined only if the input and output are scalar DoFs. 68 | It means, the only available template for this mapping is `Vec1`. 69 | 70 | -------------------------------------------------------------------------------- /30_Components/50_Mapping/Linear/IdentityMapping.md: -------------------------------------------------------------------------------- 1 | # IdentityMapping 2 | 3 | This component is classified under the category of Mappings. 4 | 5 | In this particular mapping, we designate the input as the parent state and the output as the child state. 6 | The transformation function employed in this mapping is the identity function. 7 | Formally, if $f$ denotes the mapping function, then for any input $x$, the output $f(x)$ is exactly $x$. 8 | In other words, the identity function directly maps each element to itself without any modification. 9 | 10 | Mathematically, this can be expressed as: 11 | 12 | $$ 13 | f(x)=x 14 | $$ 15 | 16 | for all $x$ in the domain. 17 | 18 | The Jacobian matrix of this mapping, which represents the first-order partial derivatives of the output with respect to the input, is the identity matrix. 19 | This means that the rate of change of each output variable with respect to the corresponding input variable is 1, while the rate of change with respect to all other variables is 0. 20 | The identity matrix $I$ in this context can be defined as: 21 | 22 | $$ 23 | J=I 24 | $$ 25 | 26 | where $J$ is the Jacobian matrix, and $I$ is the identity matrix. 27 | 28 | Furthermore, the transpose of the Jacobian matrix, denoted as $J^T$, is also the identity matrix. 29 | 30 | Given that the Jacobian matrix is constant and does not vary with the input, the second-order partial derivatives of the mapping are zero. 31 | Hence, the Hessian matrix, which contains these second-order derivatives, is a null matrix (a matrix where all elements are zero). 32 | 33 | ## Implementation Details 34 | 35 | Given the fact that the mapping function is the identity, the `apply` method effectively performs a direct copy of the input state into the output state. 36 | Since the Jacobian matrix is the identity matrix, the `applyJ` method also operates as a simple copy. 37 | Similarly, for the `applyJT` method, which applies the transpose of the Jacobian matrix, the operation remains a straightforward copy. 38 | 39 | The Hessian matrix being null means that the second-order derivatives of the mapping function are zero. 40 | Consequently, methods that depend on the Hessian matrix, such as `applyDJT` and `buildGeometricStiffnessMatrix`, will be effectively empty or trivial. 41 | These methods do not need to perform any computations because there are no second-order effects to account for in the mapping. 42 | 43 | -------------------------------------------------------------------------------- /30_Components/35_MechanicalLoad/10_ConicalForceField.md: -------------------------------------------------------------------------------- 1 | # ConicalForceField 2 | 3 | Repulsion applied by a cone toward the exterior 4 | 5 | 6 | __Templates__: 7 | - Vec3d 8 | 9 | __Target__: Sofa.Component.MechanicalLoad 10 | 11 | __namespace__: sofa::component::mechanicalload 12 | 13 | __parents__: 14 | - ForceField 15 | 16 | Data: 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 32 | 33 | 34 | 35 | 36 | 39 | 40 | 41 | 42 | 43 | 46 | 47 | 48 | 49 | 50 | 53 | 54 | 55 | 56 | 57 | 60 | 61 | 62 | 63 | 64 | 67 | 68 | 69 | 70 | 71 | 74 | 75 | 76 | 77 | 78 | 81 | 82 | 83 | 84 | 85 | 88 | 89 | 90 | 91 | 92 | 95 | 96 | 97 | 98 | 99 | 102 | 103 | 104 | 105 | 106 | 109 | 110 | 111 | 112 | 113 | 116 | 117 | 118 | 119 | 120 | 123 | 124 | 125 | 126 | 127 |
NameDescriptionDefault value
name 30 | object name 31 | unnamed
printLog 37 | if true, emits extra messages at runtime. 38 | 0
tags 44 | list of the subsets the objet belongs to 45 |
bbox 51 | this object bounding box 52 |
componentState 58 | The state of the component among (Dirty, Valid, Undefined, Loading, Invalid). 59 | Undefined
listening 65 | if true, handle the events, otherwise ignore the events 66 | 0
isCompliance 72 | Consider the component as a compliance, else as a stiffness 73 | 0
rayleighStiffness 79 | Rayleigh damping - stiffness matrix coefficient 80 | 0
coneCenter 86 | cone center 87 |
coneHeight 93 | cone height 94 |
coneAngle 100 | cone angle 101 | 10
stiffness 107 | force stiffness 108 | 500
damping 114 | force damping 115 | 5
color 121 | cone color. (default=0.0,0.0,0.0,1.0,1.0) 122 | 0 0 1 1
128 | 129 | -------------------------------------------------------------------------------- /30_Components/15_Collision/10_Detection/10_Algorithm/32_DirectSAPNarrowPhase.md: -------------------------------------------------------------------------------- 1 | Narrow Phase: Direct SAP Narrow Phase 2 | ===================================== 3 | 4 | _DirectSAPNarrowPhase_ is a [narrow phase component](./../narrowphase), which is used in the detection phase of a [CollisionPipeline](../../collisionpipeline/#collision-detection). 5 | The algorithm is based on the "[Sweep and Prune](https://en.wikipedia.org/wiki/Sweep_and_prune)" algorithm, noted SAP. 6 | 7 | The Algorithm 8 | ============= 9 | 10 | As mentioned in [Narrow Phase](./../narrowphase), _DirectSAPNarrowPhase_ input is a list of pairs of [collision models](../../../../geometry/collisionmodels/). 11 | Among this list, if it is the first time that a [collision model](../../../../geometry/collisionmodels/) is provided to _DirectSAPNarrowPhase_, a list of Axis-Aligned Bounding Box (AABB) is created. 12 | Each associated to a collision element of the new [collision model](../../../../geometry/collisionmodels/). 13 | This list is saved from a time step to the next. 14 | 15 | In the second step, all the AABB are updated according to the geometry of the collision elements in the current time step. 16 | The size of the AABB takes into account the alarm distance defined in the intersection method. 17 | 18 | Then, the boxes end points are sorted, according to their position projected on the axis of the greatest variance. 19 | 20 | Finally, the sorted end points are processed. 21 | A list of active end points is used. 22 | If an end point corresponds to the beginning of an AABB, it is added to the active list. 23 | If an end point corresponds to the end of an AABB, it is removed from the active list. 24 | For each end point, it is tested against the active list. 25 | 26 | Direct vs Inc. 27 | -------------- 28 | 29 | _DirectSAPNarrowPhase_ corresponds to the implementation of SAP in its "direct" version, i.e. at each step it sorts all the primitives along an axis (**not checking the moving ones**) and computes overlapping pairs without saving it. 30 | But the memory used to save these primitives is created just once, the first time CollisionModels are added. 31 | 32 | Example of Usage 33 | ================ 34 | 35 | This component is used as follows in XML format: 36 | 37 | ```xml 38 | 39 | 40 | 41 | 42 | 43 | 44 | ``` -------------------------------------------------------------------------------- /30_Components/70_Visual/20_VisualStyle.md: -------------------------------------------------------------------------------- 1 | Customize what to render on screen 2 | ---------------------------------- 3 | 4 | #### Description 5 | 6 | **VisualStyle** component controls the *DisplayFlags* state embedded in 7 | the **VisualParams** for the current subgraph. It merges the 8 | **DisplayFlags** conveyed by the **VisualParams** with its own 9 | DisplayFlags. Example Taken from 10 | [*examples/Component/Visual/VisualStyle.scn*](https://github.com/sofa-framework/sofa/blob/master/examples/Component/Visual/VisualStyle.scn) 11 | 12 | 13 | 14 | \[caption id="attachment\_1566" align="aligncenter" 15 | width="533"\][![Resulting View from the previous XML 16 | scene](https://www.sofa-framework.org/wp-content/uploads/2014/11/VisualStyle.jpg){.size-full 17 | .wp-image-1566 width="533" 18 | height="400"}](https://www.sofa-framework.org/wp-content/uploads/2014/11/VisualStyle.jpg) 19 | Resulting View from the previous XML scene\[/caption\] 20 | 21 | #### XML Usage 22 | 23 | ```xml 24 | 25 | ``` 26 | 27 | allowed values for displayFlags data are a combination of the following: 28 | 29 | ```xml 30 | showAll, hideAll, 31 | showVisual, hideVisual, 32 | showVisualModels, hideVisualModels, 33 | showBehavior, hideBehavior, 34 | showBehaviorModels, hideBehaviorModels, 35 | showForceFields, hideForceFields, 36 | showInteractionForceFields, hideInteractionForceFields 37 | showMapping, hideMapping 38 | showMappings, hideMappings 39 | showMechanicalMappings, hideMechanicalMappings 40 | showCollision, hideCollision 41 | showCollisionModels, hideCollisionModels 42 | showBoundingCollisionModels, hideBoundingCollisionModels 43 | showOptions hideOptions 44 | showNormals hideNormals 45 | showWireframe hideWireframe 46 | ``` 47 | 48 | #### C++ Usage 49 | 50 | In C++, to set the visual style in a node, you have to create a 51 | VisualStyle component, attach it to the node, create and tune a 52 | !DisplayFlags object and set the !VisualStyle with it, as shown in the 53 | following example: 54 | 55 | ``` 56 | VisualStyle::SPtr visualStyle = New(); 57 | root->addObject(visualStyle); 58 | VisualStyle::DisplayFlags displayFlags; 59 | displayFlags.setShowAll(); 60 | visualStyle->displayFlags.setValue(displayFlags); 61 | ``` 62 | 63 | You can also use method component::visualmodel::addVisualStyle( 64 | simulation::Node::SPtr ) to insert a VisualStyle component at the given 65 | node and return a WriteAccessor on the display flags: 66 | 67 | ``` 68 | addVisualStyle(root)->setShowVisual().setShowBehavior().setShowMapping(false); 69 | ``` 70 | -------------------------------------------------------------------------------- /35_Plugins/25_Fetch_plugin_code_source.md: -------------------------------------------------------------------------------- 1 | # Fetch Plugin Code Source 2 | 3 | A few number of plugins are directly embedded in SOFA repository, under `applications/plugins`. 4 | Most of them are deactivated by default, and it is up to the developer to activate the compilation in CMake through a corresponding CMake variable. 5 | 6 | However, some plugins can also be found in other repositories. 7 | For example, here is a list of important plugins with their corresponding repository: 8 | 9 | | Plugin | Repository | 10 | |---------------------|----------------------------------------------------------------------------------------------------------| 11 | | SofaPython3 | [https://github.com/sofa-framework/SofaPython3](https://github.com/sofa-framework/SofaPython3) | 12 | | SofaGLFW | [https://github.com/sofa-framework/SofaGLFW](https://github.com/sofa-framework/SofaGLFW) | 13 | | CGALPlugin | [https://github.com/sofa-framework/CGALPlugin](https://github.com/sofa-framework/CGALPlugin) | 14 | | SoftRobots | [https://github.com/SofaDefrost/SoftRobots](https://github.com/SofaDefrost/SoftRobots) | 15 | | ModelOrderReduction | [https://github.com/SofaDefrost/ModelOrderReduction](https://github.com/SofaDefrost/ModelOrderReduction) | 16 | | Caribou | [https://github.com/mimesis-inria/caribou](https://github.com/mimesis-inria/caribou) | 17 | 18 | Some of those external plugins (from other repositories) can be directly fetched and downloaded in SOFA sources at the configuration stage with CMake. 19 | To fetch the source code of a plugin, follow these steps: 20 | 1) In CMake, activate the variable `SOFA_FETCH_{PLUGINNAME}`. 21 | 2) Configure. After the configuration, the variable `SOFA_FETCH_{PLUGINNAME}` is automatically unchecked. The log output should confirm that. 22 | 3) A new CMake variable `PLUGIN_{PLUGINNAME}` becomes available. Activate it. 23 | 4) Configure and generate. The plugin will be compiled along with SOFA. 24 | 25 | ![](https://raw.githubusercontent.com/sofa-framework/doc/master/images/plugins/SOFA_FETCH.png) 26 | 27 | Fetching the source code of a plugin uses git to clone a repository (usually the master branch) in the SOFA build directory. 28 | It is done one time, and it is then up to the developer to update and manage the git directory. 29 | For developing on a plugin repository, it is advised to follow [these steps](./../build-a-plugin-from-sources/) rather than fetching the code source. 30 | -------------------------------------------------------------------------------- /30_Components/48_IO/10_Mesh/80_VTKExport.md: -------------------------------------------------------------------------------- 1 | Exporting in VTK format 2 | ======================= 3 | 4 | In this section, we will explain how to export a 3D object in a VTK format file. 5 | 6 | How to use it 7 | ------------- 8 | 9 | Put : 10 | 11 | into a node where a BaseMeshTopology exists. 12 | 13 | - filename = : where to save exported VTK file 14 | - edges/triangles/quads/tetras/hexas= : which primitive you want to 15 | export (at least one type is required) 16 | - pointsDataFields= where string= : indicates where the exporter will 17 | get its values to put on the points. Obviously, the number of values 18 | has to be the same as the number of points. Several data can be 19 | listed, just separate them with a space. 20 | - cellsDataFields= where string= : the same as the points. You must 21 | notice that, for now, the mapping between a primitive and a value is 22 | not possible. Consequently, only one primitive can get values (as 23 | the number of values must equal the number of cells) 24 | 25 | 26 | 27 | Limitations 28 | ----------- 29 | 30 | For now, this class supports only , for the data, Vec{1,2}{f/d} as an 31 | array of values and Vec3{f/d} as an array of vectors ('real' vector with 32 | arrow and so on ...) The export is processed when Control+E keys are 33 | pressed.Don't forget to set listening to true. 34 | 35 | 36 | [![Example\_vtkexporter\_paraview](https://www.sofa-framework.org/wp-content/uploads/2014/11/Example_vtkexporter_paraview.jpg){.size-full 37 | .wp-image-1624 .aligncenter width="600" 38 | height="357"}](https://www.sofa-framework.org/wp-content/uploads/2014/11/Example_vtkexporter_paraview.jpg) 39 | 40 | 41 | Reconstruct VTK mesh in ParaView 42 | -------------------------------- 43 | 44 | The **VTKExporter** component will export the mesh as a "*VTK 45 | Unstructured Grid*". This part will explain how to get back a "*VTK 46 | Polygonal Mesh*" which could be reload in SOFA. This pipeline has been 47 | realised using ParaView release 3.6.2. 48 | 49 | - Step 1: Open your export file: example.vtk0.vtu (File -> Open). 50 | - Step 2: unselect "position" and then apply. 51 | - Step 3: Extract Surface (Filters-> Extract Surface), and apply. 52 | - Step 4: Save Data as VTK file, either in ascii or binary (File -> 53 | Save Data). 54 | 55 | You can now use the component **MeshVTKLoader** to load this mesh in 56 | SOFA. Additionally, if you want to save only the principal component of 57 | the mesh (remove small elements) Between step 2 and 3 do: 58 | 59 | - Step 2.1: Filter -> Connectivity, and apply. 60 | - Step 2.2: Filter -> Threshold, and change the boundary to keep 61 | region between 0 and 1 62 | 63 | -------------------------------------------------------------------------------- /30_Components/45_LinearSolver/10_Iterative/80_Preconditioned_CG.md: -------------------------------------------------------------------------------- 1 | ShewchukPCGLinearSolver 2 | ======================= 3 | 4 | This component belongs to the category of [LinearSolver](../../../../simulation-principles/system-resolution/linear-solver/), it therefore aims at solving the linear system $\mathbf{A}x=b$. The ShewchukPCGLinearSolver is an iterative solver using the [conjugate gradient method](https://en.wikipedia.org/wiki/Conjugate_gradient_method) as implemented in the [CGLinearSolver](./../cglinearsolver/) in SOFA but it adds the possibility to define a [preconditioner](https://en.wikipedia.org/wiki/Preconditioner). It must be reminded that the ShewchukPCGLinearSolver relies on the conjugate gradient method, meaning that as all iterative approaches, no exact solution can be found. The accuracy of your solution will always depend on the conditioning of your system and your input data (iterations, tolerance and threshold). 5 | 6 | 7 | Preconditioners are used in cases where the convergence of the system is slow, which is usually due to a ill-conditioned system (high [condition number](https://en.wikipedia.org/wiki/Condition_number)). In order to preserve accuracy, while improving performance, preconditioning methods aims at projecting a matrix $\mathbf{P}$ (preconditioner) on the linear system $\mathbf{A}x=b$, in order to get closer to the solution. The efficiency of the preconditioner will depend on the choice of the preconditioner $\mathbf{P}$. 8 | 9 | The ShewchukPCGLinearSolver allows to choose the preconditioner of our choice based on an external direct linear solver: LULinearSolver, [SparseLDLSolver](../../direct/sparseldlsolver/), etc. These solvers will allow to compute $\mathbf{P} \approx \mathbf{A}$ and use it to compute at each iteration _k_ of the conjugate gradient: 10 | 11 | $$ 12 | \mathbf{P}^{-1}(\mathbf{A}x_k-b)=0 13 | $$ 14 | 15 | Using an appropriate preconditioner $\mathbf{P}$ of a matrix $\mathbf{A}$ means that $\mathbf{P}^{-1}\mathbf{A}$ has a smaller condition number than $\mathbf{A}$. 16 | 17 | 18 | Usage 19 | ----- 20 | 21 | The ShewchukPCGLinearSolver **requires**: 22 | 23 | - the use (above in the scene graph) of an integration scheme 24 | - (below in the scene graph) of a MechanicalObject storing the state information that the ShewchukPCGLinearSolver will access 25 | - and, if a preconditioning is desired, a linear solver to compute the $$\mathbf{P}^{-1}$$ 26 | 27 | As for the CGLinearSolver, when using a ShewchukPCGLinearSolver, make sure you carefully chose the value of the free data field iterations, tolerance and threshold. Both tolerance and threshold data must be chosen in accordance with the dimension of the degrees of freedom (DOFs). Usually, the value of these two data is close to the square of the expected error on the DOFs. 28 | -------------------------------------------------------------------------------- /40_Programming_with_SOFA/50_Create_your_binaries.md: -------------------------------------------------------------------------------- 1 | ## SOFA binaries 2 | 3 | ### Prepare the sources 4 | 5 | - Update SOFA version in CMakeLists.txt 6 | ```cmake 7 | # Manually define VERSION 8 | set(SOFA_VERSION_MAJOR ) 9 | set(SOFA_VERSION_MINOR ) 10 | set(SOFA_VERSION_PATCH ) 11 | ``` 12 | - Update External Projects versions 13 | For each ExternalProject.cmake.in file in the sources, edit the line `GIT_TAG origin/` 14 | - Set the CMake variables 15 | ```cmake 16 | SOFA_BUILD_RELEASE_PACKAGE=ON 17 | CPACK_GENERATOR=ZIP 18 | CPACK_BINARY_ZIP=ON 19 | ``` 20 | - If you want to generate an installer: 21 | - Install the latest [Qt Installer Framework (Qt IFW)](https://download.qt.io/official_releases/qt-installer-framework/) 22 | - Set the CMake variables 23 | ```cmake 24 | CPACK_IFW_ROOT= 25 | CPACK_GENERATOR=ZIP;IFW 26 | CPACK_BINARY_ZIP=ON 27 | CPACK_BINARY_IFW=ON 28 | ``` 29 | - [MacOS] Set CMake variable for OSX compatibility version: 30 | ``` 31 | CMAKE_OSX_DEPLOYMENT_TARGET=10.15 32 | ``` 33 | - [MacOS] If you want to generate a bundle (.app), set the CMake variables: 34 | ```cmake 35 | CPACK_GENERATOR=ZIP;DragNDrop 36 | CPACK_BINARY_ZIP=ON 37 | CPACK_BINARY_DRAGNDROP=ON 38 | ``` 39 | 40 | ### Generate the binaries 41 | 42 | - Configure + Generate + Build 43 | - Install: `make install` or `ninja install` 44 | - Make sure that `linux-postinstall-fixup.sh` or `windows-postinstall-fixup.sh` or `macos-postinstall-fixup.sh` was triggered and its output is OK 45 | - Your binaries should be in your build directory 46 | 47 | 48 | ## Plugin binaries 49 | 50 | 51 | 52 | 53 | ## Troubleshooting 54 | 55 | - To show how Qt plugins are loaded and used: `export QT_DEBUG_PLUGINS=1` 56 | - [Linux][MacOS] To fix library dependency resolution: `export LD_LIBRARY_PATH=/path/to/sofa/bin:/path/to/sofa/lib:$LD_LIBRARY_PATH` 57 | - [MacOS] To show when dylibs are loaded: `export DYLD_PRINT_LIBRARIES=1` 58 | 59 | 60 | ## Publishing a SOFA release 61 | 62 | Once the binaries are generated: 63 | 64 | - Create a [release](https://github.com/sofa-framework/sofa/releases) on GitHub. 65 | - Update the link on the [download](https://www.sofa-framework.org/download/) page for the binaries (add changes in dependencies). 66 | - Update the doc for building SOFA: 67 | - on [Linux](../../getting-started/build/linux/) 68 | - on [MacOS](../../getting-started/build/mac-os-x/) 69 | - on [Windows](../../getting-started/build/windows/) 70 | - Update the flags on the forum. 71 | - Create a post on the forum, on Twitter, on LinkedIn. 72 | -------------------------------------------------------------------------------- /30_Components/15_Collision/10_Detection/20_Intersection/50_MinProximityIntersection.md: -------------------------------------------------------------------------------- 1 | MinProximityIntersection 2 | ======================== 3 | 4 | This proximity method for [intersection detection](../../../../../simulation-principles/multi-model-representation/collision/#narrow-phase-detect-intersection): 5 | 6 | - detects a possible contact as soon as pair of collision elements are close to each other (distance smaller than the alarmDistance) 7 | - and creates contact (aka DetectionOutput) when the distance is lower than contactDistance. 8 | 9 | This method is optimized for meshes. The intersection is implemented for the following primitives: Triangle/Point, Line/Point, Line/Line, so that it covers all Triangle/Triangle intersections. To get a proper detection, the TriangleModel, LineModel and PointModel must be simultaneously used in the scene. 10 | 11 | In the figure below, we describe the detection of the contacts for Object 1 due to an Object 2. It assumes here that a PointCollisionModel and a LineCollisionModel are defined. The detection gives: 12 | - 2 Point-Point contacts (yellow) 13 | - 1 Point-Line contact (blue) 14 | - 1 Line-Line contact (pink) 15 | 16 | 17 | 18 | 19 | Although the method is working properly, the intersection might result in a high number of contacts. This works just fine for Penalty method (many springs will be generated). However, using a response method based on Lagrange multipliers, many constraints will be generated which might rapidly become computationally-demanding. 20 | 21 | Moreover, the contacts can be a bit degenerated: many contacts with different orientations. Again, using Penalty, it might only create some numerical friction but, using the Lagrange multiplier resolution, this can lead to contradictory constraints (worsening the convergence). 22 | 23 | 24 | 25 | Usage 26 | ----- 27 | 28 | The MinProximityIntersection must be placed right after the CollisionPipeline and the associated Detection methods (usually [BruteForceBroadPhase](../../algorithm/bruteforcebroadphase/) and [BVHNarrowPhase](../../algorithm/bvhnarrowphase/)) on top the scene graph. 29 | 30 | 31 | Additional information 32 | ---------------------- 33 | 34 | - collision models in the scene will have the data **proximity** corresponding to an enlargement of the collision model, i.e., value added to the alarmDistance and the contactDistance and also when building AABBs in the broad phase 35 | - a different alarmDistance and contactDistance can be specified for each CollisionModel by setting alarmDistance and contactDistance to zero and changing the proximity parameter 36 | 37 | -------------------------------------------------------------------------------- /30_Components/20_Constraint/10_Projective/50_FixedProjectiveConstraint.md: -------------------------------------------------------------------------------- 1 | FixedProjectiveConstraint 2 | ========================= 3 | 4 | This component belongs to the category of [Projective Constraint](../../../../simulation-principles/constraint/projective-constraint/). 5 | The FixedProjectiveConstraint projects a constant velocity. If the fixed points have a zero velocity at the simulation start, they will keep a zero velocity i.e. be fixed. 6 | 7 | As introduced in the page about the Projective Constraint, the FixedProjectiveConstraint corresponds to a projection matrix noted $\mathbf{P}$ which will multiply the system matrix $\mathbf{A}$ so that: $\mathbf{P}^T\mathbf{A}\mathbf{P}\Deltav=\mathbf{P}^Tb$. This projection matrix $\mathbf{P}$ is the identity matrix in which the diagonal value corresponding to the indices of the fixed points equals zero. These lines and columns equals 0. As a consequence, when the integration scheme (ODESolver) will call the ```projectResponse()``` or ```projectVelocity()``` the constraint will be applied, ensuring that the desired degrees of freedom remain fixed. 8 | 9 | Example of a system of size 6, with a fixed constraint at the index 5: 10 | 11 | $$ 12 | \mathbf{P}=\begin{bmatrix}1&0&0&0&0&0\\0&1&0&0&0&0\\0&0&1&0&0&0\\0&0&0&1&0&0\\0&0&0&0&\mathbf{0}&0\\0&0&0&0&0&1\end{bmatrix} 13 | $$ 14 | 15 | By projecting this $\mathbf{P}$ matrix on the right hand side vector we have $\mathbf{P}^Tb$. This ensures to have the projection $b[5]=0$, thus preventing any time evolution of the fifth degree of freedom. In such case, we function _projectResponse()_: 16 | 17 | ```cpp 18 | template 19 | void FixedProjectiveConstraint::projectResponse(const core::MechanicalParams* mparams, DataVecDeriv& resData) 20 | { 21 | SOFA_UNUSED(mparams); 22 | 23 | helper::WriteAccessor res (resData ); 24 | const SetIndexArray & indices = d_indices.getValue(); 25 | 26 | if( d_fixAll.getValue() ) 27 | { 28 | // fix everything 29 | typename VecDeriv::iterator it; 30 | for( it = res.begin(); it != res.end(); ++it ) 31 | { 32 | *it = Deriv(); 33 | } 34 | } 35 | else 36 | { 37 | for (SetIndexArray::const_iterator it = indices.begin(); it != indices.end(); ++it) 38 | { 39 | res[*it] = Deriv(); 40 | } 41 | } 42 | } 43 | ``` 44 | 45 | 46 | 47 | Usage 48 | ----- 49 | 50 | The FixedProjectiveConstraint **requires** a MechanicalObject to store the degrees of freedom associated to the nodes, as well as a Mass so that the system matrix is not null. An integration scheme and a solver are also necessary to solve the linear system at each time step. 51 | 52 | Note that if only a part of the degrees of freedom must be constraint, you can use the PartialFixedProjectiveConstraint working in the same way as the FixedProjectiveConstraint. 53 | 54 | -------------------------------------------------------------------------------- /30_Components/20_Constraint/20_Lagrangian/Model/50_UnilateralLagrangianConstraint.md: -------------------------------------------------------------------------------- 1 | UnilateralLagrangianConstraint 2 | =============================== 3 | 4 | 5 | This component belongs to the category of [Constraint Laws](../../../../../simulation-principles/constraint/lagrange-constraint/#constraint-laws) used for the Lagrange constraint resolution and inherits from the PairInteractionConstraint. The UnilateralLagrangianConstraint defines an [non-holonomic constraint](https://en.wikipedia.org/wiki/Nonholonomic_system) law between a pair of simulated body, i.e. the constraint defined between the pair of objects must have an inequality form: 6 | 7 | $$ 8 | \Psi(x_1,x_2...)~\geq~0 9 | $$ 10 | 11 | Such a constraint are used for friction-less and friction contact modeling (it can even be used as a starting point for puncture modeling). For a UnilateralLagrangianConstraint, the constraint matrix $\mathbf{H}$ (derivative of the constraint law) corresponds to: 12 | 13 | - $\mathbf{H}_1 = \begin{bmatrix} \begin{bmatrix} 0 & 0 & 0\\\end{bmatrix}_0 & ... & \vec{n}_i & ... & \begin{bmatrix} 0 & 0 & 0\\\end{bmatrix}_{N_1}\\ \end{bmatrix}$ for object 1 14 | - $\mathbf{H}_1 = \begin{bmatrix} \begin{bmatrix} 0 & 0 & 0\\\end{bmatrix}_0 & ... & \vec{n}_j & ... & \begin{bmatrix} 0 & 0 & 0\\\end{bmatrix}_{N_2} \\ \end{bmatrix}$ for object 2 15 | 16 | We can see from these matrices that the UnilateralLagrangianConstraint is a transformation towards the constraint space, by building a projection of any field against the contact direction (normal here, and possibly tangential directions as well if friction is defined). 17 | 18 | 19 | As all constraint laws, the UnilateralLagrangianConstraint will be called in the following functions and for the following steps: 20 | 21 | - `getConstraintViolation()`: project the free velocity in the constraint space and compute the free interpenetration $\dot{\delta}_1^{free}=\mathbf{H}_1v_1^{free}$ 22 | - `buildConstraintMatrix()`: build the compliance made up of $dt\mathbf{H}_1\mathbf{A}_1^{-1}\mathbf{H}_1^T$ and $dt\mathbf{H}_2\mathbf{A}_2^{-1}\mathbf{H}_2^T$ 23 | 24 | 25 | 26 | Usage 27 | ----- 28 | 29 | The UnilateralLagrangianConstraint can only be used in the context of [Lagrange constraint](../../../../../simulation-principles/constraint/lagrange-constraint/) resolution. The scene must therefore contain: 30 | 31 | - a FreeMotionAnimationLoop 32 | - a ConstraintSolver 33 | 34 | Moreover, each constrained object must define in its node a ConstraintCorrection so that the corrective motion can be applied. Unlike other constraints, the UnilateralLagrangianConstraint is mostly used in SOFA for contact modeling. UnilateralLagrangianConstraint are therefore dynamically and automatically created within the scene graph when two objects are colliding: when the CollisionPipeline defines new DetectionOutput with ContactResponse using Lagrange multipliers, each DetectionOutput generates a new UnilateralLagrangianConstraint. 35 | 36 | -------------------------------------------------------------------------------- /30_Components/15_Collision/10_Detection/10_Algorithm/10_CollisionPipeline.md: -------------------------------------------------------------------------------- 1 | Collision Pipelines 2 | =================== 3 | 4 | Collision between objects is split in several phases, each implemented in a different component. 5 | Each phase is scheduled by a collision pipeline. 6 | The collision pipelines are executed in an [animation loop](../../../../../simulation-principles/animation-loop/). 7 | 8 | The Steps 9 | ========= 10 | 11 | The collision pipeline follows three steps: 12 | 13 | 1. reset of the collision 14 | 2. a collision detection 15 | 3. a collision response 16 | 17 | Implementation 18 | ============== 19 | 20 | A collision pipeline is called from an [animation loop](../../../../../simulation-principles/animation-loop/) through a CollisionVisitor executing the 3 steps of the pipeline in `CollisionVisitor::processCollisionPipeline`. 21 | 22 | The visitor executes the following functions, each corresponding to a step of the pipeline: 23 | ```cpp 24 | /// Remove collision response from last step 25 | void Pipeline::computeCollisionReset() 26 | ``` 27 | 28 | ```cpp 29 | /// Detect new collisions. Note that this step must not modify the simulation graph 30 | void Pipeline::computeCollisionDetection() 31 | ``` 32 | 33 | ```cpp 34 | /// Add collision response in the simulation graph 35 | void Pipeline::computeCollisionResponse() 36 | ``` 37 | 38 | Each of these functions will call a delegate, available in the Pipeline: 39 | ``` cpp 40 | /// Remove collision response from last step 41 | void doCollisionReset() override; 42 | ``` 43 | 44 | ``` cpp 45 | /// Detect new collisions. Note that this step must not modify the simulation graph 46 | void doCollisionDetection(const sofa::helper::vector& collisionModels) override; 47 | ``` 48 | 49 | ``` cpp 50 | /// Add collision response in the simulation graph 51 | void doCollisionResponse() override; 52 | ``` 53 | 54 | The 3 delegate functions describe the 3 different steps, and are usually overriden in derived classes. 55 | See an example in [_DefaultPipeline_](./../defaultpipeline). 56 | 57 | Notes: 58 | In some cases, the 3 steps are called manually by the animation loop through 3 dedicated visitors ([CollisionResetVisitor](https://www.sofa-framework.org/api/master/sofa/html/classsofa_1_1simulation_1_1_collision_reset_visitor.html), [CollisionDetectionVisitor](https://www.sofa-framework.org/api/master/sofa/html/classsofa_1_1simulation_1_1_collision_detection_visitor.html) and [CollisionResponseVisitor](https://www.sofa-framework.org/api/master/sofa/html/classsofa_1_1simulation_1_1_collision_response_visitor.html)). 59 | Each of these visitors executes only one step (instead of the 3). 60 | This is to avoid race conditions in a multithreaded environment. 61 | 62 | Examples of Components 63 | ====================== 64 | 65 | The following components are all collision pipelines, and can be placed in a simulation scene: 66 | 67 | - [_DefaultPipeline_](./../defaultpipeline) 68 | -------------------------------------------------------------------------------- /40_Programming_with_SOFA/60_API_overview/15_Forward_declaration.md: -------------------------------------------------------------------------------- 1 | Forward declaration 2 | =============== 3 | To reduce the amount of file inclusion in SOFA and thus compilation time it is possible to use forward declaration. 4 | A forward declaration is an incomplete type which complete definition is not provided. 5 | ```cpp 6 | class AClass; ///< this is a forward declaration of a type 7 | 8 | /// This is the full declaration + definition of a type 9 | class AClass 10 | { 11 | public: 12 | } 13 | ``` 14 | 15 | Forward declaration can be used in place of the complete type (declaration+definition) when the "inner" details of the type are not needed. A classical scenario is the following 16 | ```cpp 17 | #include 18 | bool myFunction1(BaseObject* a) 19 | { 20 | return doSomethingWith(a); 21 | } 22 | ``` 23 | 24 | As we are manipulating the 'a' object via a pointer and passing it to the doSomethingWith function there is no need to know any details of the BaseObject to compile that properly. Using a forward declaration for BaseObject would save us from the inclusion of the file ```#include ``` 25 | 26 | Where to put forward declaration 27 | -------------------------------- 28 | 29 | Forward declaration must be in a file called ```fwd.h```. The fwd.h can be located at the module root directory. 30 | Eg: 31 | ``` 32 | sofa/core/fwd.h 33 | ``` 34 | 35 | If there is a lot of forward declaration it is allowed to have a per sub-module ```fwd.h``` file. 36 | Eg: 37 | ``` 38 | sofa/core/objectmodel/fwd.h 39 | sofa/core/behavior/fwd.h 40 | ``` 41 | 42 | In that case it is mandatory that the module file contains them all. In our example 43 | ```cpp 44 | sofa/core/fwd.h 45 | #include 46 | #include 47 | ``` 48 | 49 | 50 | Opaque API 51 | ========= 52 | When it is not desirable to have access the full type definition it is possible to make or use what is called an opaque API. The Opaque API mimmics the methods provided by a class but relying only on forward declaration. 53 | Example of the "transparent" API: 54 | ```cpp 55 | #include 56 | #include 57 | namespace sofa::simulation 58 | { 59 | class Node : public Context, public BaseNode 60 | { 61 | public: 62 | double getDt(); 63 | ///.... 64 | }; 65 | } 66 | ``` 67 | 68 | Example of the corresponding "opaque" API: 69 | ```cpp 70 | namespace sofa::simulation::node 71 | { 72 | double getDt(Node*); 73 | } 74 | ``` 75 | 76 | Opaque API for a given type can be located at the same location where the type is forward declared or if very long in their own dedicated file close to the one where the type definition is. 77 | ``` 78 | sofa/simulation/node.h 79 | sofa/simulation/node.cpp 80 | sofa/simulation/node-fwd.h 81 | ``` 82 | 83 | If the second solution is chosen, the ``node-fwd.h` file must be included by the per-module fwd.h. -------------------------------------------------------------------------------- /30_Components/20_Constraint/20_Lagrangian/Model/30_BilateralLagrangianConstraint.md: -------------------------------------------------------------------------------- 1 | BilateralLagrangianConstraint 2 | ============================== 3 | 4 | This component belongs to the category of [Constraint Laws](../../../../../simulation-principles/constraint/lagrange-constraint/#constraint-laws) used for the Lagrange constraint resolution and inherits from the PairInteractionConstraint. The BilateralLagrangianConstraint defines an [holonomic constraint](https://en.wikipedia.org/wiki/Holonomic_constraints) law between a pair of simulated body, i.e. the constraint defined between the pair of objects must have an equality form: 5 | 6 | $$ 7 | \Phi(x_1,x_2...)~=~0 8 | $$ 9 | 10 | Such a constraint is suited for attachment cases or sliding joints. For an attachment case, if the vertex _i_ of object 1 and the vertex _j_ of object 2 are attached, the holonomic constraint law can be written as $x_1(i)-x_2(j)~=~0$. 11 | 12 | For a BilateralLagrangianConstraint, the constraint matrix $\mathbf{H}$ (derivative of the constraint law) corresponds to: 13 | 14 | - $\mathbf{H}_1 = \begin{bmatrix} \begin{bmatrix} 0 & 0 & 0\\\end{bmatrix}_0 & ... & \begin{bmatrix} 1 & 0 & 0\\\end{bmatrix}_i & ... & \begin{bmatrix} 0 & 0 & 0\\\end{bmatrix}_{N_1}\\ \begin{bmatrix} 0 & 0 & 0\\\end{bmatrix}_0 & ... & \begin{bmatrix} 0 & 1 & 0\\\end{bmatrix}_i & ... & \begin{bmatrix} 0 & 0 & 0\\\end{bmatrix}_{N_1}\\ \begin{bmatrix} 0 & 0 & 0\\\end{bmatrix}_0 & ... & \begin{bmatrix} 0 & 0 & 1\\\end{bmatrix}_i & ... & \begin{bmatrix} 0 & 0 & 0\\\end{bmatrix}_{N_1}\\ \end{bmatrix}$ for object 1 15 | - $\mathbf{H}_2 = \begin{bmatrix} \begin{bmatrix} 0 & 0 & 0\\\end{bmatrix}_0 & ... & \begin{bmatrix} -1 & 0 & 0\\\end{bmatrix}_j & ... & \begin{bmatrix} 0 & 0 & 0\\\end{bmatrix}_{N_2}\\ \begin{bmatrix} 0 & 0 & 0\\\end{bmatrix}_0 & ... & \begin{bmatrix} 0 & -1 & 0\\\end{bmatrix}_j & ... & \begin{bmatrix} 0 & 0 & 0\\\end{bmatrix}_{N_2}\\ \begin{bmatrix} 0 & 0 & 0\\\end{bmatrix}_0 & ... & \begin{bmatrix} 0 & 0 & -1\\\end{bmatrix}_j & ... & \begin{bmatrix} 0 & 0 & 0\\\end{bmatrix}_{N_2}\\ \end{bmatrix}$ for object 2 16 | 17 | 18 | As all constraint laws, the BilateralLagrangianConstraint will be called in the following functions and for the following steps: 19 | 20 | - `getConstraintViolation()`: project the free velocity in the constraint space and compute the free interpenetration $\dot{\delta}_1^{free}=\mathbf{H}_1v_1^{free}$ 21 | - `buildConstraintMatrix()`: build the compliance made up of $dt\mathbf{H}_1\mathbf{A}_1^{-1}\mathbf{H}_1^T$ and $dt\mathbf{H}_2\mathbf{A}_2^{-1}\mathbf{H}_2^T$ 22 | 23 | 24 | 25 | Usage 26 | ----- 27 | 28 | The BilateralLagrangianConstraint can only be used in the context of [Lagrange constraint](../../../../../simulation-principles/constraint/lagrange-constraint/) resolution. The scene must therefore contain: 29 | 30 | - a FreeMotionAnimationLoop 31 | - a ConstraintSolver 32 | 33 | Moreover, each constrained object must define in its node a ConstraintCorrection so that the corrective motion can be applied. 34 | -------------------------------------------------------------------------------- /10_Getting_Started/15_Binaries/10_Binaries_instructions.md: -------------------------------------------------------------------------------- 1 | SOFA provides pre-compiled binaries, eliminating the need to compile the software from its source code. This simplifies the process for users to get started with SOFA. Below are detailed instructions on how to download, install, and execute SOFA: 2 | 3 | 4 | ## Download 5 | 6 | To download SOFA, visit the official SOFA website at [https://www.sofa-framework.org/download/](https://www.sofa-framework.org/download/). On this page, you will find the latest version of SOFA. There are two types of files available, download one or the other: 7 | 8 | - Installer Files: these files are designed for easy installation of SOFA, including all the necessary binaries, on your operating system. 9 | - Zip Files: these files contain a folder with the SOFA application and its associated binaries. 10 | 11 | If you choose the zip file option, extract its contents to access the SOFA application and binaries. 12 | 13 | If you require a specific version of SOFA, you can also find previous releases on the official SOFA GitHub repository at [https://github.com/sofa-framework/sofa/releases](https://github.com/sofa-framework/sofa/releases). 14 | 15 | 16 | ## Install 17 | 18 | If you downloaded an installer file, simply run the file, and follow the installation process as you would for any other software application. This will ensure that SOFA is properly installed on your system. 19 | 20 | 21 | ## Run SOFA 22 | 23 | ### with the SOFA GUI 24 | To run SOFA, locate and execute the application called `runSofa`. For more detailed information on how to use the application, you can refer to the [page dedicated to runsofa](../../../using-sofa/runsofa/). This documentation will provide you with further guidance on using SOFA effectively. 25 | 26 | 27 | ### within a Python environment 28 | 29 | To use the binary release of SOFA within a Python3 environment, the section "using Python3" details how to [set up your environment on various operating systems](https://sofapython3.readthedocs.io/en/latest/content/Installation.html#using-python3). 30 | 31 | Note that the latest SOFA release has been compiled using Python3.12. Make sure to check your Python version before going any further. 32 | 33 | 34 | ### Notes for macOS Users 35 | 36 | Unfortunately, macOS binaries of SOFA are not code-signed. It means that macOS adds a quarantine flag to the binaries when a user downloads them. The result is a warning window with the message "runSofa cannot be opened because the developer cannot be verified.", preventing to open the application. 37 | 38 | There are several solutions to run SOFA anyway: 39 | 40 | - Build SOFA by yourself. MacOS does not add the quarantine flags on the local builds. See the instructions [here](../../build/macos/). 41 | - Run the following command: 42 | 43 | ```bash 44 | xattr -dr com.apple.quarantine path/to/sofa/folder 45 | ``` 46 | 47 | with path/to/sofa/folder is the folder where the binaries of SOFA are located. This command removes the quarantine flags on the binary files. 48 | -------------------------------------------------------------------------------- /10_Getting_Started/20_Build/50_Activate_Plugins.md: -------------------------------------------------------------------------------- 1 | # Activable plugins for in-tree compilation 2 | 3 | Multiple extensions can be activated when building the project. They fall into three categories: 4 | 5 | 1. Applications: extensions that offer SOFA-based executable applications (e.g. a main for launching SOFA) 6 | 2. Plugins: extensions that enriche the SOFA API by adding new components or providing more support for external libraries (e.g. new constitutive laws, alternative GUIs) 7 | 3. Directories: extensions that contain multiple CMake projects that cannot be described by only one of the above type 8 | Moreover, these projects are either present in the SOFA sources or they need to be fetched (meaning that they have their own external repository). 9 | 10 | This page aims at summarizing those extensions in tables containing: 11 | 12 | - the name + hyperlink to the extension sources either in the SOFA repository or in its own repository 13 | - a short description 14 | - activation directives 15 | 16 | The activation directives propose two ways of activating those plugins in the build tree: 17 | 18 | 1. Through custom CMake flags that [can be added during the CMake call](https://cmake.org/cmake/help/latest/manual/cmake.1.html#cmdoption-cmake-D). All of those plugins can be activated with one or two CMake flags named using their type and name. For example, the plugin SofaPython3 can be activated by activating both flags `SOFA_FETCH_SOFAPYTHON3=ON` and `PLUGIN_SOFAPYTHON3=ON` (because its sources are in a separate repository, see bellow). 19 | 2. Through preset that can be [specified during the CMake call](https://cmake.org/cmake/help/latest/manual/cmake-presets.7.html#introduction) 20 | 21 | ### Note on fetched plugins 22 | 23 | As stated before, some plugins have their own repository and thus need to be fetched to be compiled in-tree. To do so, you will need to activate the associated flag `SOFA_FETCH_XXX=ON` (while replacing `XXX` by the capitalized name of your plugin). Note that all '.' in the plugin name should be replaced by a '_', e.g. to fetch Sofa.Qt, one need to set the CMake flag `SOFA_FETCH_SOFA_QT=ON`. 24 | 25 | The repository from which to fetch and the tag to checkout can be changed by using the respective flags `XXX_GIT_REPOSITORY` and `XXX_GIT_TAG`. The tag can be either a tag, a branch name or a commit hash. 26 | 27 | It should be noted that you can use a local clone of the repository, instead of relying on the fetching mechanism. This can be useful when you have a version of the plugin on your disk on which you are currently working. To do this, you will need to specify the flag `XXX_LOCAL_DIRECTORY` with an absolute path to the local clone of the plugin. If this flag is set, it will be used in priority over the fetching mechanism (`SOFA_FETCH_XXX`). 28 | 29 | No matter what mechanism you use (fetch or local clone), you will still need to activate it by setting to ON the following CMake flag `{TYPE}_XXX` where TYPE corresponds to one of the following keywords: `{"APPLICATION", "PLUGIN", "DIRECTORY"}`. 30 | 31 | 32 | -------------------------------------------------------------------------------- /20_Simulation_Principles/70_Engine.md: -------------------------------------------------------------------------------- 1 | Engine 2 | ====== 3 | 4 | As explained the documentation page on Data, SOFA allows to connect Data instances (Data link) to keep their value synchronized. An Engine (or DataEngine) is a component which relies on this concept to compute one or several output Data based on one or several input Data. 5 | 6 | The specifity of the Engines resides in their update mechanism: output Data are updated based on the input Data through a mechanism of lazy evaluation. Data values which are not up-to-date are recursively flagged as "dirty", but they are recomputed only when necessary. The update (recomputation) only occurs when the Data itself or a Data depending on this Data is accessed. 7 | 8 | For instance: 9 | 10 | - the TransformEngine computes a geometric transformation (rotation, translation,scaling) on input positions (e.g. coming from a MeshLoader) and outputs the transformed position 11 | - based on a bounding box and a vector of coordinates, a BoxROI engine computes the list of indices of the coordinates inside the box. These indices can then be used as input of a FixedConstraint to define a fixed boundary condition. With this design, the simulation can transparently be setup either from data stored in static files, or generated automatically with engines. 12 | 13 | Engines are meant to perform relatively simple computations, but can easily be created in a series. The network of interconnected Data objects defines a Data dependency graph, superimposed on the scene graph. This Data dependency graph is not visible within the runSofa GUI. 14 | 15 | 16 | API of Engines 17 | -------------- 18 | 19 | The API of engines is pretty simple since only one function is to be implemented (on top of the `init()` function common to all SOFA components): 20 | 21 | ``` cpp 22 | 23 | // Update function in Engines computing the new values of outputs from inputs 24 | void doUpdate() 25 | 26 | ``` 27 | 28 | This function is in charge of the computation of the ouput Data based on the input Data. It is the delegate function from the `update()` function implemented in DataEngine which updates all inputs before calling the `doUpdate()` function. 29 | 30 | 31 | 32 | Example of use 33 | -------------- 34 | 35 | Here is an example with the [TransformEngine](../../components/engine/transform/transformengine/) with an input data ("input_position") and an output data ("output_position") resulting from a transformation defined by the user (here translation): 36 | 37 | ``` xml 38 | 39 | 40 | ``` 41 | 42 | or in python: 43 | 44 | ``` python 45 | node.addObject("TransformEngine", name="translationEngine", template="Vec3d", translation="10 0 0", input_position="@meshLoader.position") 46 | node.addObject("MechanicalObject", name="transform", template="Vec3d", position="@translationEngine.output_position") 47 | ``` 48 | -------------------------------------------------------------------------------- /35_Plugins/50_Usual_plugins/65_HAPI.md: -------------------------------------------------------------------------------- 1 | Configuring 2 | ----------- 3 | 4 | - Install 5 | [HAPI](http://www.h3dapi.org/modules/PDdownloads/viewcat.php?cid=15 "http://www.h3dapi.org/modules/PDdownloads/viewcat.php?cid=15"){.external 6 | .text}, using either an installer or with the source code (For 7 | VS2010, see below). If you use the installer and keep it in the 8 | default directory, it should install to C:/HAPI. If you use the 9 | source, it will be in the directory that you specify. From this 10 | point forward, we will refer to this directory 11 | as MyHAPIInstallation. 12 | - Turn on the option **SOFA-PLUGIN\_SOFAHAPI** in CMake, 13 | and configure. 14 | - Likely, CMake will report that HAPI was not found. You can manually 15 | set: 16 | 17 | `HAPI_INCLUDE_DIR = MyHAPIInstallation/HAPI/include` 18 | `HAPI_LIBRARY = MyHAPIInstallation/lib/HAPI_vc9.lib` If you are not 19 | compiling in Visual Studio 2008, change the \_vc9.lib suffix to whatever 20 | version is appropriate. HAPI\_DEBUG\_LIBRARY is optional. Configure 21 | again. 22 | 23 | - Next, you will probably get an error that H3DUTIL was not found. You 24 | can manually set: 25 | 26 | `H3DUTIL_INCLUDE_DIR = MyHAPIInstallation/H3DUtil/include` 27 | `H3DUTIL_LIBRARY = MyHAPIInstallation/lib/H3DUtil_vc9.lib` Again, 28 | changing the library suffix if needed. H3DUTIL\_DEBUG\_LIBRARY is 29 | optional. Configure again. 30 | 31 | - Finally, you will probably get an error that PTHREAD was not found. 32 | You can manually set: 33 | 34 | `PTHREAD_INCLUDE_DIR = MyHAPIInstallation/External/include/pthread` 35 | `PTHREAD_LIBRARY = MyHAPIInstallation/External/lib/pthreadVC2.lib` Note 36 | that pthreadVC2.lib is not in the same directory as the previous two 37 | libraries. Configure again. 38 | 39 | - You should now be able to Generate and compile without problems. 40 | 41 | HAPI for VS2010 42 | --------------- 43 | 44 | The HAPI installer doesn't include libraries for VS2010, so you will 45 | have to build them yourself. 46 | 47 | - Start by using the installer, as it will get you the source code and 48 | Pthread, a required library. 49 | - Using CMake, set the **Source Code** to 50 | **MyHAPIInstallation/HAPI/build**. 51 | - Set the **Build** to where you want to source to be built. 52 | - Press Configure, and choose Visual Studio 10 as the 53 | desired compiler. 54 | - Press Configure until all the red highlighted things are gone. 55 | - Press Generate. 56 | - Open the resulting Solution file in Visual Studio 2010, and compile. 57 | - Once everything finishes compiling, you can find 58 | **H3DUtil\_vc10.lib** in 59 | **MyHAPIInstallation/H3DUtil/build/Release** and **HAPI\_vc10.lib** 60 | in **MyHAPIInstallation/HAPI/build/Release**. You can either leave 61 | them where they are and point CMake to them when configuring, or 62 | copy them to**MyHAPIInstallation/lib** with the libraries for the 63 | other versions of Visual Studio. 64 | - Repeat the compilation is debug mode if desired. 65 | 66 | -------------------------------------------------------------------------------- /20_Simulation_Principles/12_Visitors.md: -------------------------------------------------------------------------------- 1 | Visitors 2 | ======== 3 | 4 | During the different steps of the simulation (initialization, system assembly, solving, visualization), information needs to be recovered from all graph nodes. SOFA relies on an implicit mechanism: the _Visitors_. You can find the abstract _Visitor_ class in the SofaSimulation package. 5 | 6 | _Visitors_ traverse the scene top-down and bottom-up and call the corresponding virtual functions at each graph node traversal. _Visitors_ are therefore used to trigger actions by calling the associated virtual functions (e.g. animating the simulation, accumulating forces). Algorithmic operations on the simulated objects are implemented by deriving the _Visitor_ class and overloading its virtual functions _processNodeTopDown( )_ and _processNodeBottomUp( )_. 7 | 8 | This approach hides the scene structure (parent, children) from the components, for more implementation flexibility and a better control of the execution model. Moreover, various parallelism strategies can be applied independently of the mechanical computations performed at each node. The data structure is actually extended from strict hierarchies to directed acyclic graphs to handle more general kinematic dependencies. The top-down node traversals are pruned unless all the parents of the current node have been traversed already, so that nodes with multiple parents are traversed only once all their parents have been traversed. The bottom-up traversals are made in the reverse order. 9 | 10 | 11 | Examples: 12 | 13 | - at the level of an [AnimationLoop](../../simulation-principles/animation-loop/), visitors are used for instance to trigger the simulation step (_AnimateVisitor_), update the context (_UpdateSimulationContextVisitor_) and update the mappings (_UpdateMappingVisitor_). 14 | 15 | - at the level of the [ODESolver](../../simulation-principles/system-resolution/integration-scheme/), visitors allow to build the linear matrix system by abstract functions. For instance, the computation of the right hand side vector *b* is triggered by the _MechanicalComputeForceVisitor_, accumulating forces is used to compute all the forces (internal or external) applied on our object. The solver then triggers the associate _Visitor_ and the action is propagated through the graph and calls the appropriate (bottom-up) methods at each force and mapping node. All components able to compute forces will accumulate their contributions. This information is finally gathered in the MechanicalObject and the solver will use this "force" vector to solve the mathematical system. 16 | 17 |
18 | 19 |
20 | 21 | 22 | 23 | Sequence diagram 24 | ---------------- 25 | 26 | Here is the usual sequence diagram of a SOFA simulation. 27 | 28 |
29 | 30 |
-------------------------------------------------------------------------------- /40_Programming_with_SOFA/30_Create_your_component.md: -------------------------------------------------------------------------------- 1 | A **SOFA component** is a class or a class template that inherits, 2 | directly or not, from `sofa::core::objectmodel::BaseObject`. A component 3 | must also respect some conventions: 4 | 5 | - the declaration *must* begin with the `SOFA_CLASS` macro. It will 6 | expand to some code required by SOFA, that will enable some kind of 7 | reflection mechanisms; 8 | - a component must be registered in the `ObjectFactory`, using the 9 | `RegisterObject` mechanism (see example below), otherwise SOFA won't 10 | be aware of it. 11 | 12 | Here is a minimal example, for a component that does nothing: 13 | 14 | ``` cpp 15 | #include 16 | 17 | class MyComponent : public sofa::core::objectmodel::BaseObject 18 | { 19 | public: 20 | SOFA_CLASS(MyComponent, sofa::core::objectmodel::BaseObject); 21 | 22 | MyComponent (); 23 | virtual ~MyComponent (); 24 | }; 25 | ``` 26 | 27 | ``` cpp 28 | #include "MyComponent.h" 29 | #include 30 | 31 | MyComponent::MyComponent() 32 | { 33 | } 34 | 35 | MyComponent::~MyComponent() 36 | { 37 | } 38 | 39 | int MyComponentClass = sofa::core::RegisterObject("This component does nothing.").add(); 40 | ``` 41 | 42 | Once the plugin is compiled, this component can be used in an XML scene 43 | file. You should also add a `RequiredPlugin` element in the root node in 44 | order to load `MyPlugin` when the scene is loaded. 45 | 46 | ``` xml 47 | 48 | 49 | 50 | 51 | 52 | ``` 53 | 54 | This is a basic example; most components don't inherit directly from 55 | `BaseObject`, but from a subclass which represent a specific aspect of a 56 | simulation. For example, force field components inherit from 57 | `sofa::core::BaseForcefield`, or one of its subclasses. 58 | 59 | Add Data to your component 60 | -------------------------- 61 | 62 | Almost every component has parameters, inputs, or outputs: they are 63 | referred to as *Data*; in a scene file, those are the XML attributes of 64 | the component. Each XML attribute of a component is actually a member of 65 | the class, declared in a special way: it is encapsulated in a 66 | [Data](https://www.sofa-framework.org/api/SOFA/classsofa_1_1core_1_1objectmodel_1_1_data.html "Data"). 67 | For example, in order to add a float Data named `myparam` to our 68 | component, we will add this member to `MyComponent`: 69 | 70 | ``` cpp 71 | Data m_myparam; 72 | ``` 73 | 74 | Then we must register and initialise it in **each** Constructor of 75 | MyComponent: 76 | 77 | ``` cpp 78 | MyComponent::MyComponent(): d_myparam(initData(&d_myparam, 0.42, "myparam", "Here should be a short description of myparam.")) 79 | { 80 | } 81 | ``` 82 | 83 | This allows us to use this Data in scene files; it can be assigned a 84 | value like so: 85 | 86 | ``` xml 87 | 88 | 89 | 90 | 91 | 92 | ``` 93 | -------------------------------------------------------------------------------- /30_Components/75_UI/20_Recorded_Camera.md: -------------------------------------------------------------------------------- 1 | How to manage the recorded camera 2 | --------------------------------- 3 | 4 | In this page, we explain how to manage the recorded camera. The recorded 5 | camera is available on componentSofaBaseVisual. You have three modes to 6 | manipulate the camera: rotation mode, translation mode and navigation 7 | mode. 8 | 9 | #### The rotation mode 10 | 11 | The camera can rotate, if you define the rotation center, the rotation 12 | axis and the rotation start point. The rotation path is visible if you 13 | check the option "if true, draw the rotation path". 14 | 15 | #### The translation mode 16 | 17 | This mode enables to move the camera between intermediate camera 18 | positions. The camera path is then defined with a linear spline linking 19 | these intermediate positions.You can select the intermediate positions 20 | on the orthogonal views of the plugin image by double-clicking on the 21 | point. Each time you double-click on a point you have to update the 22 | ImageViewer component. Image:Example.jpg The camera can navigate along 23 | the path with a default view up, if you check the option "if true, 24 | translation will be performed". To draw the translation path check the 25 | option "if true, translation path will be performed". An example 26 | navigationInVolume.scn is available in the plugin image. 27 | 28 | - How is camera orientation defined ? To define the camera 29 | orientation, you have to determine the look-at vector and the 30 | view-up vector. The camera looks at the next point of the 31 | linear spline. To define the up vector, we initialize it with a 32 | default value. Then in order to guarantee a stability during the 33 | navigation, the up vector is oriented almost in the 34 | same orientation. Indeed for each step n, the right vector is 35 | defined as the cross product between the previous up vector and the 36 | current focal vector. \[caption id="attachment\_1558" 37 | align="aligncenter" width="302"\][![Axes of the 38 | Camera](https://www.sofa-framework.org/wp-content/uploads/2014/11/AxesCamera.jpg){.size-full 39 | .wp-image-1558 width="302" 40 | height="214"}](https://www.sofa-framework.org/wp-content/uploads/2014/11/AxesCamera.jpg) 41 | Axes of the Camera\[/caption\] 42 | 43 | #### The navigation mode 44 | 45 | The navigation mode enables to move between selected intermediate camera 46 | view points. A view point corresponds to a camera position and a camera 47 | orientation. Therefore, the main difference between navigation mode and 48 | translation mode is that the camera orientation is defined in the 49 | navigation mode by interpolation between intermediate orientations. To 50 | save an intermediate camera view point select in the mouse manager 51 | (*edit->Mouse manager*) the operation "**Save camera's view point for 52 | navigation**". To navigate select the operation "**Start navigation if 53 | camera's view points have been saved**", which works if at least 2 view 54 | points have been saved. An example navigationRecordedCamera.scn is 55 | available in *examplesComponentsvisualmodel*. 56 | -------------------------------------------------------------------------------- /40_Programming_with_SOFA/60_API_overview/80_Macro_for_deprecation.md: -------------------------------------------------------------------------------- 1 | # Deprecation macros 2 | 3 | ## The 2 base macros 4 | 5 | ### SOFA_ATTRIBUTE_DEPRECATED(deprecateDate, disableDate, toFixMsg) 6 | 7 | To be used to trigger a deprecation warning. It is a simple `[[deprecated]]` interface. 8 | 9 | This macro warns that something 10 | 11 | - is DEPRECATED (still usable) since `deprecateDate` 12 | - will be disabled on `disableDate` 13 | 14 | and gives the `toFixMsg` instructions to fix the deprecation warning. 15 | 16 | ### SOFA_ATTRIBUTE_DISABLED(deprecateDate, disableDate, toFixMsg) 17 | 18 | To be used jointly with `= delete` to trigger an error. It is a flavored `[[deprecated]]` interface. 19 | 20 | This macro warns that something 21 | 22 | - is DISABLED (not usable anymore) since `disabledDate` 23 | - was firstly deprecated on `deprecateDate` 24 | 25 | and gives the `toFixMsg` instructions to fix the compilation error. 26 | 27 | 28 | ## How to use them 29 | 30 | Create a new deprecation macro specifying the deprecation topic you are tackling. 31 | This way, you won't have dates everywhere in your code. 32 | 33 | ## Example 34 | 35 | ### Deprecate 36 | 37 | I want to rename something that will break my API. 38 | To ease the transition for my users, I will propose a deprecation period with a fine message by using a deprecation macro. 39 | Latest release is v20.06, next release (currently under development) is v20.12, after that will come the v21.06. 40 | 41 | In my config.h.in 42 | ```cpp 43 | #define SOFA_ATTRIBUTE_DEPRECATED__MYDEPRECATIONTOPIC() \ 44 | SOFA_ATTRIBUTE_DEPRECATED( \ 45 | "v20.12 (PR#12345)", "v21.06", \ 46 | "XXX must be renamed into YYY.") 47 | ``` 48 | 49 | In my code 50 | ```cpp 51 | SOFA_ATTRIBUTE_DEPRECATED__MYDEPRECATIONTOPIC() 52 | void myDeprecatedMethod(); 53 | ``` 54 | 55 | Anyone using myDeprecatedMethod will get this **warning**: 56 | ```text 57 | warning: 'myDeprecatedMethod' is deprecated: It is still usable but has been DEPRECATED since v20.12 (PR#12345). You have until v21.06 to fix your code. XXX must be renamed into YYY. 58 | ``` 59 | 60 | ### Disable 61 | 62 | Now forward in time ... 63 | Latest release is v20.12, next release (currently under development) is v21.06, after that will come the v21.12. 64 | It is time to stop the deprecation period. To provide a clear message to my users, I will not remove my deprecated method but instead, I will disable it with `= delete` and use a deprecation macro. 65 | 66 | In my config.h.in 67 | ```cpp 68 | #define SOFA_ATTRIBUTE_DISABLED__MYDEPRECATIONTOPIC() \ 69 | SOFA_ATTRIBUTE_DISABLED( \ 70 | "v20.12 (PR#12345)", "v21.06 (PR#45678)", \ 71 | "XXX must be renamed into YYY.") 72 | ``` 73 | 74 | In my code 75 | ```cpp 76 | SOFA_ATTRIBUTE_DISABLED__MYDEPRECATIONTOPIC() 77 | void myDeprecatedMethod() = delete; 78 | ``` 79 | 80 | Anyone using myDeprecatedMethod will get an **error** right after this warning: 81 | ```text 82 | warning: 'myDeprecatedMethod' is deprecated: It is not usable anymore because it has been DISABLED since v21.06 (PR#45678) after being deprecated on v20.12 (PR#12345). XXX must be renamed into YYY. 83 | ``` 84 | 85 | 86 | -------------------------------------------------------------------------------- /30_Components/40_ODESolver/10_Forward/10_EulerExplicitSolver.md: -------------------------------------------------------------------------------- 1 | EulerExplicitSolver 2 | =================== 3 | 4 | The EulerExplicitSolver component belongs to the category of [integration schemes or ODE Solver](../../../../simulation-principles/system-resolution/integration-scheme/). This scheme allows to solve dynamic systems explicitly: all forces will be computed based on the state information at the current time step $x(t)$. 5 | 6 | Looking at continuum mechanics, the linear system $\mathbf{A}x=b$ arises from the dynamic equation. This dynamic is written as follows but other physics (like heat transfer) result in a similar equation: 7 | 8 | $$ 9 | \mathbf{M}\Delta v=dt\left(f(x,t)\right) 10 | $$ 11 | 12 | where $x$ is the degrees of freedom, $\mathbf{M}$ the mass matrix and $f(x,t)$ a function of $x$ (and possibly its derivatives) acting on our system. In the case of the EulerExplicitSolver, this equation can be written: 13 | 14 | $$ 15 | \mathbf{M}\Delta v=dt\left(f(x(t))\right) 16 | $$ 17 | 18 | since forces only depend on known state (at our current time step). These forces are computed by the ForceField in the `addForce()` function. The system matrix $\mathbf{A}$ is only equal to the mass matrix $\mathbf{M}$. 19 | 20 | Depending on whether the mass matrix is diagonal or not, SOFA supports two cases: 21 | 22 | 1) The mass matrix is diagonal. It makes the resolution of the linear system trivial (best performances). In this case, the system matrix $\mathbf{A}$ equals a diagonal mass matrix $\mathbf{M}$ which is diagonal, and it can be stored as a vector $|m|$ . Moreover, its inverse can directly be obtained as: $\mathbf{M}^{-1}=|m|^{-1}=\frac{1}{|m|}$. 23 | The solution $\Delta v_{sol}=dt\cdot \mathbf{M}^{-1}f(x(t))$ finally corresponds to a division operation of $f(x(t))$ by the mass. This computation is actually performed by the Mass component in the `accFromF()` function. Therefore, no LinearSolver is needed to compute directly or iteratively a solution. 24 | 2) The mass matrix is not diagonal. Solving the system requires a linear solver. 25 | 26 | Note that the **symplectic** data allows to modify the scheme to make it [symplectic](https://en.wikipedia.org/wiki/Semi-implicit_Euler_method), i.e. velocities are updated before the positions. 27 | It allows to update the positions from the newly computed velocities, instead of velocities from the previous time step. 28 | This option makes the scheme more robust in time. 29 | EulerExplicitSolver is symplectic by default. 30 | 31 | Sequence diagram 32 | ---------------- 33 | 34 | 35 | 36 | 37 | 38 | Usage 39 | ----- 40 | 41 | The EulerExplicitSolver **requires** a MechanicalObject to store the state vectors. However, as explained above, no LinearSolver is needed and the EulerExplicitSolver is **only working using a [UniformMass](../../../mass/uniformmass/) or [DiagonalMass](../../../mass/diagonalmass/)**, which ensures to have a diagonal system matrix. 42 | -------------------------------------------------------------------------------- /30_Components/45_LinearSolver/20_Direct/50_SparseLDLSolver.md: -------------------------------------------------------------------------------- 1 | SparseLDLSolver 2 | =============== 3 | 4 | This component belongs to the category of [LinearSolver](../../../../simulation-principles/system-resolution/linear-solver/). The role of the SparseLDLSolver is to solve the linear system $\mathbf{A}x=b$ assuming that the matrix $\mathbf{A}$ is symmetric and sparse. 5 | 6 | 7 | To do so, the SparseLDLSolver relies on the method of [LDL decomposition](https://en.wikipedia.org/wiki/Cholesky_decomposition#LDL_decomposition_2). The system matrix will be decomposed $\mathbf{A}=\mathbf{L}\mathbf{D}\mathbf{L}^T$, where $\mathbf{L}$ is a lower triangular matrix $\mathbf{A}$ and $\mathbf{D}$ is a diagonal matrix. This decomposition is an extension of the Cholesky decomposition which reduces its numerical inaccuracy. 8 | 9 | As a direct solver, the SparseLDLSolver computes at each simulation time step an exact solution as follows: 10 | 11 | $$ 12 | \mathbf{L}\mathbf{D}\mathbf{L}^Tx=b 13 | $$ 14 | 15 | Using a block forward substitution, we successively solve two triangular systems. Between those two resolutions, we need to inverse $\mathbf{D}$, which is trivial as it is a diagonal matrix that has no null value on its diagonal. 16 | 17 | $$ 18 | \begin{cases} 19 | \mathbf{A}x=b \\ 20 | \mathbf{A}=\mathbf{LDL^T} 21 | \end{cases} 22 | \Longleftrightarrow 23 | \begin{cases} 24 | \mathbf{L} z = b \\ 25 | \mathbf{D} y = z \\ 26 | \mathbf{L}^T x = y \\ 27 | \end{cases} 28 | $$ 29 | 30 | It is important to note that this decomposition considers that the system matrix $\mathbf{A}$ is symmetric. 31 | 32 | Note that using permutation, the SparseLDLSolver will apply fill reducing permutation on the rows and the columns of $\mathbf{A}$ in order to minimize the number of non null values in $\mathbf{L}$ . Instead of solving $\mathbf{A}x=b$, we will solve $\mathbf{(PAQ) (Q^{-1}}x) = Pb$. Moreover, $\mathbf{A}$ is symmetric, so we will use the same permutation on the rows and on the columns with $\mathbf{Q}=\mathbf{P}^T=\mathbf{P}^{-1}$. We will factorize $\tilde{\mathbf{A}} =\mathbf{PAP^T} $ and then we will solve 33 | 34 | $$ 35 | \begin{cases} 36 | \tilde{\mathbf{A}} y = Pb \\ 37 | \mathbf{Q}^{-1} x = y 38 | \end{cases} 39 | $$ 40 | 41 | As the impact of the use of fill reducing permutations on the performances is highly influenced by the repartition of the nodes used to model an object, we advise the users to test which type of permutation is the best suited for their simulations. 42 | 43 | 44 | 45 | Sequence diagram 46 | ---------------- 47 | 48 | 49 | 50 | 51 | Usage 52 | ----- 53 | 54 | The SparseLDLSolver **requires** the use (above in the scene graph) of an integration scheme, and (below in the scene graph) of a MechanicalObject storing the state information that the SparseLDLSolver will access. 55 | 56 | As a direct solver, the SparseLDLSolver might be extremely time consuming for large system. However, it will always give you an exact solution, **making the assumption that the system matrix $\mathbf{A}$ is symmetric**. 57 | 58 | -------------------------------------------------------------------------------- /30_Components/15_Collision/10_Detection/10_Algorithm/30_NarrowPhase.md: -------------------------------------------------------------------------------- 1 | Narrow Phase Components 2 | ====================== 3 | 4 | The narrow phase collision detection components are executed in a [collision pipeline](../../collisionpipeline). 5 | 6 | Introduction 7 | ============ 8 | 9 | In SOFA, collision detection usually involves complex meshes (e.g. a set of triangles). 10 | For an accurate collision response, the collision detection detects which pairs of collision elements are in intersection. 11 | 12 | The naive approach would be to test every pair of collision elements. 13 | The number of tests depends on the number of objects, and the number of collision elements in each object. 14 | For performances reasons, this approach is never selected because of its quadratic complexity. 15 | 16 | Instead, the collision detection will be divided in two parts: 17 | 1. The [broad phase collision detection](../../broadphase) 18 | 2. The narrow phase collision detection 19 | 20 | The Narrow Phase 21 | ================ 22 | 23 | The narrow phase is executed after the broad phase. 24 | The broad phase output is a list of collision models potentially in collision. 25 | The goal of the narrow phase is to examine the list more closely and determine if they are actually in intersection. 26 | If it is the case, it detects which elements are in intersection. 27 | 28 | Following the [DefaultPipeline](../../defaultpipeline), the output of the narrow phase is provided to the contact manager. 29 | 30 | The Implementation 31 | ------------------ 32 | 33 | The narrow phase is executed in 3 functions: 34 | 35 | ```cpp 36 | /// Clear all the potentially colliding pairs detected in the previous simulation step 37 | void NarrowPhaseDetection::beginNarrowPhase() 38 | ``` 39 | 40 | ```cpp 41 | /// Add a new list of potentially colliding pairs of models 42 | void NarrowPhaseDetection::addCollisionPairs(const sofa::helper::vector< std::pair >& v) 43 | ``` 44 | 45 | ```cpp 46 | void NarrowPhaseDetection::endNarrowPhase() 47 | ``` 48 | 49 | The function `addCollisionPairs` is called on the list of pairs of collision models provided by the broad phase. 50 | Internally, this function is just a loop calling the following function: 51 | ```cpp 52 | void NarrowPhaseDetection::addCollisionPair (const std::pair& cmPair) 53 | ``` 54 | 55 | The implementation of these 3 functions (`beginNarrowPhase`, `addCollisionPair` and `endNarrowPhase`) defines the behavior of the narrow phase. 56 | It is where the algorithm is implemented. 57 | To implement a new narrow phase algorithm, a developer will probably derive a class from `NarrowPhaseDetection` and override the 3 mentioned functions. 58 | 59 | After the execution of the narrow phase, the list of contact is stored in 60 | ```cpp 61 | DetectionOutputMap NarrowPhaseDetection::m_outputsMap; 62 | ``` 63 | 64 | Finally, the collision pipeline provides this list to the contact manager. 65 | 66 | Examples of Components 67 | ====================== 68 | 69 | The following components are all narrow phase collision detections, and can be placed in a simulation scene: 70 | 71 | - [BVHNarrowPhase](../../bvhnarrowphase) 72 | - ParallelBVHNarrowPhase (plugin MultiThreading) 73 | - DirectSAPNarrowPhase 74 | 75 | -------------------------------------------------------------------------------- /20_Simulation_Principles/60_Constraint/10_Projective_Constraint.md: -------------------------------------------------------------------------------- 1 | Projective constraint 2 | ===================== 3 | 4 | Different types of constraint exist in SOFA. The projective constraint are method allowing to project the velocity of the constraint points of an object to a desired value. 5 | 6 | 7 | Matrix approach 8 | --------------- 9 | 10 | A projection matrix noted $\mathbf{P}$ multiplies the matrix $\mathbf{A}$ of the linear system $\mathbf{A}x=b$ (where our unknown $x$ is actually $\Delta{v}$) to enforce the so-called project constraint. The system thus becomes: $\mathbf{P}^T\mathbf{A}\mathbf{P} \Delta v=\mathbf{P}^Tb$. Implicit integration has the advantage of being more stable for stiff forces or large time steps. The solution of these equation systems requires [linear solvers](../../system-resolution/linear-solver/). Due to the superlinear time complexity of equation solvers, it is generally more efficient to process independent interaction groups using separated solvers rather than a unique solver. 11 | 12 | Another type of constraints is available in SOFA focusing on constraint-based interactions which requires the computation of Lagrange multipliers based on interaction Jacobians. This will be discussed in the next article about [Lagrange constraint](./../lagrange-constraint/). 13 | 14 | 15 | 16 | API of projective constraint 17 | ---------------------------- 18 | 19 | In SOFA, you can find several of these projective constraints in the SofaBoundaryConditions module, among them: 20 | 21 | - the [_FixedProjectiveConstraint_](../../../components/constraint/projective/fixedprojectiveconstraint/): projecting a constant velocity, if the vertex is initially fixed, then it is attached to its initial position 22 | - the [_PartialFixedProjectiveConstraint_](../../../components/constraint/projective/partialfixedprojectiveconstraint/): inheriting from _FixedProjectiveConstraint_, this constraint is projected only along certain degrees of freedom (e.g. only in x direction) 23 | 24 | Classes considering on single object inherit from the class _ProjectiveConstraintSet_. The usual API functions associated to projective constraints are: 25 | 26 | ``` cpp 27 | /// Project dx to constrained space (dx models an acceleration): 28 | void projectResponse(const core::MechanicalParams* mparams, DataVecDeriv& resData); 29 | 30 | /// Project v to constrained space (v models a velocity): 31 | void projectVelocity(const core::MechanicalParams* mparams, DataVecDeriv& vData); 32 | 33 | /// Project x to constrained space (x models a position): 34 | void projectPosition(const core::MechanicalParams* mparams, DataVecCoord& xData); 35 | 36 | /// Project c to constrained space (c models a constraint): 37 | /// this method must be implemented by the component to handle Lagrange Multiplier based constraint 38 | void projectJacobianMatrix(const core::MechanicalParams* mparams, DataMatrixDeriv& cData); 39 | 40 | /// Project the global Mechanical Matrix to constrained space using offset parameter 41 | void applyConstraint(const MechanicalParams*, const sofa::core::behavior::MultiMatrixAccessor*); 42 | 43 | /// Project the global Mechanical Vector to constrained space using offset parameter 44 | void applyConstraint(const MechanicalParams* , defaulttype::BaseVector*, const sofa::core::behavior::MultiMatrixAccessor*); 45 | 46 | ``` -------------------------------------------------------------------------------- /40_Programming_with_SOFA/60_API_overview/40_Events_in_SOFA.md: -------------------------------------------------------------------------------- 1 | Recovering the events from the keyboard or the mouse can be very useful 2 | for interactive simulation (ex: controlling surgical instruments) There 3 | is already implemented in SOFA a very easy way to access these so-called 4 | events during the simulation. To access the event within a SOFA 5 | component, you need: 6 | 7 | - **handleEvent()** function: you need to define the inherited 8 | function handleEvent. A nice example is available in the component: 9 | BaseController.cpp (see at line 71). 10 | - **f\_listening** parameter: activate the boolean f\_listening by the 11 | function handleEvent in order to listen to the events. This boolean 12 | is not activated by default.The best way to activate it is to 13 | specify it in the scene file that while writing "listening=1". You 14 | can otherwise "hard" code it in your C++ component as 15 | follows "myComponent.f\_listening.setValue(true)". 16 | 17 | Now, you will be able to recover the events and therefore to interact 18 | with your simulation. Have fun ! 19 | 20 | If you still don't receive events, it may be possible than you will need to press Ctrl key. 21 | 22 | Mouse or Keyboard Events 23 | ------------------------ 24 | 25 | ``` cpp 26 | template< class DataTypes> 27 | void myComponent< datatypes >::handleEvent(core::objectmodel::Event *event) 28 | { 29 | // Key pressed event 30 | if(KeypressedEvent* ev = dynamic_cast< keypressedevent *>(event)) 31 | { 32 | switch(ev->getKey()) 33 | { 34 | // The key M is pressed 35 | case 'M': 36 | case 'm': 37 | { 38 | .... 39 | } 40 | } 41 | } 42 | 43 | 44 | // Mouse Events 45 | if(MouseEvent* ev = dynamic_cast< mouseevent *>(event)) 46 | { 47 | switch(ev->getState()) 48 | { 49 | // The left key of the mouse is pressed 50 | case MouseEvent::LeftPressed: 51 | { 52 | .... 53 | } 54 | } 55 | } 56 | } 57 | ``` 58 | 59 | Specific integration events 60 | --------------------------- 61 | 62 | Similarly to Mouse or Keyboard events, you can detect 63 | specific events during the time integration. These events are managed 64 | and sent by the AnimationLoop you are using. 65 | 66 | Events related to the mechanics/solving are: 67 | 68 | - BeginAnimationStep: start of a time step 69 | - EndAnimationStep: end of a time step 70 | - IntegrationBeginEvent: start of the integration phase 71 | - IntegrationEndEvent: end of the integration phase 72 | - CollisionBeginEvent: start of the collision phase 73 | - CollisionEndEvent: end of the collision phase 74 | 75 | Interaction-related events are: 76 | 77 | - KeypressedEvent 78 | - KeyreleasedEvent 79 | - MouseEvent 80 | - HapticDeviceEvent 81 | - PauseEvent 82 | - IdleEvent 83 | 84 | ``` cpp 85 | template< class DataTypes> 86 | void myComponent< datatypes >::handleEvent(core::objectmodel::Event *event) 87 | { 88 | // Begin of the animation step 89 | if (dynamic_cast< sofa::simulation::AnimateBeginEvent *>(event)) 90 | { 91 | ... 92 | } 93 | 94 | 95 | // End of the animation step 96 | if (dynamic_cast< sofa::simulation::AnimateEndEvent *>(event)) 97 | { 98 | ... 99 | } 100 | } 101 | ``` 102 | -------------------------------------------------------------------------------- /30_Components/15_Collision/10_Detection/20_Intersection/60_LocalMinDistance.md: -------------------------------------------------------------------------------- 1 | LocalMinDistance 2 | ================ 3 | 4 | This proximity method is an [intersection detection](../../../../../simulation-principles/multi-model-representation/collision/#narrow-phase-detect-intersection) close to the previous [MinProximityIntersection](./../minproximityintersection/) but in addition, it filters the list of DetectionOutput to keep only the contacts with the local minimal distance. 5 | 6 | To find an optimal number of contact points, the LocalMinDistance computes cones on all nodes of the collision model. A cone is the combination of the orthogonal directions/planes of the neighboring lines/surfaces. 7 | 8 | 9 | 10 | 11 | All contact outputs which are outside these cones will be invalidated (even if they are below the contactDistance). Thus, only the geometrically closest contacts remain: for convex surfaces, this method even ensures to find one and only one contact point. 12 | 13 | 14 | 15 | Degenerated cases can occur when, for instance, surfaces are perfectly parallel. If we think about configuration described below: 16 | 17 | The cones on the sides (no 1 and 3) are open with an 90 degree angle, while the middle cone (2) is closed. No contact will therefore be detected from the cone 2. 18 | 19 | 20 | 21 | 22 | - In case our object is rigid, having the two cones exactly equal to 90 degrees may lead to instabilities: a small rotation would lead to the invalidation of one of the two corner contacts, and the object would start to oscillate. To prevent such cases, a data is available to open the cone: "coneFactor" 23 | - In case of a soft body, the LocalMinDistance would not detect the middle point as a contact since the cone is closed. The method would therefore fail to keep the object over the surface. To solve such a generated case, a data aiming at opening all existing cones is defined: "angleCone" 24 | 25 | 26 | 27 | 28 | Usage 29 | ----- 30 | 31 | The MinProximityIntersection must be placed right after the CollisionPipeline and the associated Detection method (usually [BruteForce](../../algorithm/bruteforcebroadphase/)) on top the scene graph. 32 | 33 | 34 | Additional information 35 | ---------------------- 36 | 37 | - collision models in the scene will have the data **proximity** corresponding to an enlargement of the collision model, i.e., value added to the alarmDistance and the contactDistance and also when building AABBs in the broad phase 38 | - a different alarmDistance and contactDistance can be specified for each CollisionModel by setting alarmDistance and contactDistance to zero and changing the proximity parameter 39 | 40 | -------------------------------------------------------------------------------- /30_Components/55_Mass/10_UniformMass.md: -------------------------------------------------------------------------------- 1 | UniformMass 2 | =========== 3 | 4 | 5 | This component belongs to the category of [Masses](../../../simulation-principles/multi-model-representation/mass/). The UniformMass is a very **simplistic mass** component since it does not compute the volume integration of a density term. The mass is equally spread over the number of points, thus resulting in the following diagonal mass matrix: 6 | 7 | $$\mathbf{M}=\begin{bmatrix}m&0&\cdots&0\\&m&\cdots&0\\ \vdots&\vdots&\ddots&\vdots\\&0&\cdots&m\end{bmatrix}$$ 8 | 9 | Each diagonal term equals the nodal mass $m=\frac{m_{\textnormal{total}}}{N}$ where $m_{\textnormal{total}}$ is the total mass of the objet and $N$ is the number of nodes of the object. Spreading the mass over the nodes without considering their connectivity results in this diagonal mass matrix $\mathbf{M}$. 10 | 11 | 12 | As all mass components, the UniformMass $\mathbf{M}$ will contribute to the main matrix $\mathbf{A}$ in the system $\mathbf{A}x=b$. Depending on the type of [LinearSolver](../../../simulation-principles/system-resolution/linear-solver/) used: 13 | 14 | - for iterative solvers, the result of the multiplication between the mass matrix $\mathbf{M}$ and an approximated solution is computed by the function: 15 | 16 | ``` cpp 17 | template 18 | void UniformMass::addMDx ( const core::MechanicalParams*, DataVecDeriv& vres, const DataVecDeriv& vdx, SReal factor) 19 | { 20 | helper::WriteAccessor res = vres; 21 | helper::ReadAccessor dx = vdx; 22 | 23 | WriteAccessor > > indices = d_indices; 24 | 25 | MassType m = d_vertexMass.getValue(); 26 | if ( factor != 1.0 ) 27 | m *= ( typename DataTypes::Real ) factor; 28 | 29 | for ( unsigned int i=0; i 39 | void UniformMass::addMToMatrix (const MechanicalParams *mparams, const MultiMatrixAccessor* matrix) 40 | { 41 | const MassType& m = d_vertexMass.getValue(); 42 | 43 | const size_t N = DataTypeInfo::size(); 44 | 45 | AddMToMatrixFunctor calc; 46 | MultiMatrixAccessor::MatrixRef r = matrix->getMatrix(mstate); 47 | 48 | Real mFactor = (Real)mparams->mFactorIncludingRayleighDamping(this->rayleighMass.getValue()); 49 | 50 | ReadAccessor > > indices = d_indices; 51 | for ( unsigned int i=0; i& contacts) 46 | ``` 47 | 48 | Contacts are provided through the contact manager: 49 | ```cpp 50 | const helper::vector& contacts = contactManager->getContacts(); 51 | ``` 52 | 53 | Examples of Components 54 | ====================== 55 | 56 | The following components are collision group managers, and can be placed in a simulation scene: 57 | 58 | - DefaultCollisionGroupManager (plugin SofaMiscCollision) 59 | -------------------------------------------------------------------------------- /35_Plugins/20_Build_a_plugin_from_sources.md: -------------------------------------------------------------------------------- 1 | # Build a plugin 2 | 3 | 4 | This page presents how to build an external plugin, 5 | i.e. a plugin which is not provided in the source code of SOFA. 6 | 7 | > ⚠️ **WARNING**: In most cases, the version of a plugin follows the version of SOFA. For compatibility reasons, it is preferable to compile the version of the plugin corresponding to your SOFA version. For example, if you have the SOFA v23.06 binaries, you will need to compile plugins using their v23.06 version (i.e. their v23.06 branch). 8 | 9 | > Note: Some plugins are switched off by default. To switch them on, make sure to have the following CMake variable defined `-DPLUGIN_{PLUGIN_NAME}=ON`. 10 | 11 | Two ways of building a plugin are possible: 12 | 13 | - you are compiling SOFA and you integrate your plugin project along SOFA (aka [_in-tree build_](#in-tree-build)). 14 | - you have an install of SOFA (either you downloaded a [pre-built configuration](https://www.sofa-framework.org/download/), or you installed by yourself from a [SOFA build](../../getting-started/build/build-options/)), and you want to use this installation to build your plugin (aka [_out-of-tree build_](#out-of-tree-build)) 15 | 16 | ## In-tree build 17 | 18 | #### Preferred file architecture 19 | 20 | If you use the source code of SOFA, you want compile and use one or more 21 | external plugins it is preferred to create one specific repository 22 | outside SOFA where you can checkout all these external plugins. 23 | This structure is preferred since it will allow a clean organization 24 | of external plugins in one single repository. 25 | Let's note the path to this repository */ext_plugin_repo/*. 26 | 27 | In this directory, the structure is: 28 | 29 | - ext_plugin_repo/ 30 | - plugin1/ 31 | - plugin2/ 32 | - ... 33 | 34 | 35 | #### CMakeLists.txt of the repository 36 | 37 | In order to handle this repository as one single set of external plugins, 38 | you need to write a short CMakeLists.txt file as follows: 39 | 40 | ``` 41 | cmake_minimum_required(VERSION 3.22) 42 | 43 | find_package(SofaFramework) 44 | 45 | sofa_add_subdirectory(plugin path_to_plugin1/ name_of_project_plugin1) 46 | sofa_add_subdirectory(plugin path_to_plugin2/ name_of_project_plugin2) 47 | ``` 48 | 49 | #### CMake option in SOFA 50 | 51 | To compile all the external plugins located in this repository, 52 | all you need to do is to set the path to this repository (*/ext_plugin_repo/*) 53 | in the CMake variable: **SOFA\_EXTERNAL\_DIRECTORIES**. 54 | 55 | This will directly configure and allow to compile all specified plugins from SOFA. 56 | 57 | ## Out-of-tree build 58 | 59 | Your plugin will be considered as a standalone project, and SOFA will be simply a dependency for your CMake project. 60 | 61 | #### CMake configuration 62 | 63 | The main CMakeFile.txt of the plugin will not be different from the _in-tree_ way. 64 | 65 | Afterwards, in CMake (cmake, ccmake, cmake-gui), you just set the source to the root of your plugin, as any project based on CMake. 66 | 67 | The only mandatory requirement for your project to find SOFA is to edit the CMake variable **CMAKE\_PREFIX\_PATH** and set the value to the path of the _lib/cmake_ directory of your SOFA installation: 68 | 69 | ![](https://user-images.githubusercontent.com/11028016/135097125-996b2ed5-29cf-4383-a98c-572621bad8d2.PNG) 70 | 71 | In some cases, having the `SOFA_ROOT` environment variable properly defined (to the build or install directory of SOFA) might also help in the configuration step. 72 | 73 | After setting the eventual third-party libraries (Qt, Eigen, etc), you will be able to generate and build your plugin. 74 | 75 | Finally, you are advised to install directly your plugin into the SOFA installation, essentially to load it more easily with runSofa. 76 | This is possible by setting the CMake variable **CMAKE\_INSTALL\_PREFIX** in your plugin configuration. 77 | -------------------------------------------------------------------------------- /30_Components/15_Collision/10_Detection/10_Algorithm/15_BroadPhase.md: -------------------------------------------------------------------------------- 1 | Broad Phase Components 2 | ====================== 3 | 4 | The broad phase collision detection components are executed in a [collision pipeline](../../collisionpipeline). 5 | 6 | Introduction 7 | ============ 8 | 9 | In SOFA, collision detection usually involves complex meshes (e.g. a set of triangles). 10 | For an accurate collision response, the collision detection detects which pairs of collision elements are in intersection. 11 | 12 | The naive approach would be to test every pair of collision elements. 13 | The number of tests depends on the number of objects, and the number of collision elements in each object. 14 | For performances reasons, this approach is never selected because of its quadratic complexity. 15 | 16 | Instead, the collision detection will be divided in two parts: 17 | 18 | 1. The broad phase collision detection 19 | 2. The [narrow phase collision detection](../../narrowphase) 20 | 21 | The Broad Phase 22 | =============== 23 | 24 | In SOFA, the role of the broad phase is usually to prune a maximum number of pairs of collision models which are not in intersection. 25 | Considering $n$ collision models (usually there are more than one collision model per object), there are between $n*(n-1)/2$(no self collision) and $n^2/2$(if all collision models can self collide) pairs of collision models. 26 | 27 | The output of the broad phase is a collection of pairs of collision models which are potentially in intersection. 28 | At this stage, it is not known if those pairs are actually in intersection or not. 29 | It is not known which collision elements (i.e. point/line/triangle) are in intersection with which collision elements. 30 | The list of pairs is provided as an input to the narrow phase collision detection. 31 | 32 | The Implementation 33 | ------------------ 34 | 35 | Before starting the broad phase, all collision models in the scene must be listed. This is done in the function ```void PipelineImpl::computeCollisionDetection()``` with: 36 | ```cpp 37 | std::vector collisionModels; 38 | root->getTreeObjects (&collisionModels); 39 | ``` 40 | 41 | Then, the broad phase collision detection is executed in 3 functions: 42 | 43 | ```cpp 44 | void BroadPhaseDetection::beginBroadPhase() 45 | ``` 46 | 47 | ```cpp 48 | void BroadPhaseDetection::addCollisionModels(const sofa::helper::vector& v) 49 | ``` 50 | 51 | ```cpp 52 | void BroadPhaseDetection::endBroadPhase() 53 | ``` 54 | 55 | The function `addCollisionModels` is called on the list of all collision models in the scene. 56 | Internally, this function is just a loop calling the following function: 57 | ```cpp 58 | void BroadPhaseDetection::addCollisionModel(core::CollisionModel *cm) 59 | ``` 60 | 61 | The implementation of these 3 functions (`beginBroadPhase`, `addCollisionModel` and `endBroadPhase`) defines the behavior of the broad phase. 62 | It is where the algorithm is implemented. 63 | To implement a new broad phase algorithm, a developer will probably derive a class from `BroadPhaseDetection` and override the 3 mentioned functions. 64 | 65 | After the execution of the broad phase, the list of potential colliding pairs is stored in 66 | ```cpp 67 | sofa::helper::vector< CollisionModelPair > BroadPhaseDetection::cmPairs; 68 | ``` 69 | Finally, the [collision pipeline](../../collisionpipeline) provides this list to a [narrow phase collision detection](../../narrowphase). 70 | 71 | Examples of Components 72 | ====================== 73 | 74 | The following components are all broad phase collision detections, and can be placed in a simulation scene: 75 | 76 | - [BruteForceBroadPhase](./../bruteforcebroadphase) 77 | - ParallelBruteForceBroadPhase (plugin MultiThreading) 78 | - BruteForceDetection 79 | - THMPGSpatialHashing (plugin THMPGSpatialHashing) 80 | - BulletCollisionDetection (plugin BulletCollisionDetection) 81 | 82 | -------------------------------------------------------------------------------- /30_Components/15_Collision/10_Detection/10_Algorithm/20_DefaultPipeline.md: -------------------------------------------------------------------------------- 1 | Collision Pipelines: DefaultPipeline 2 | ============================================== 3 | 4 | The DefaultPipeline is a [Collision Pipeline](./../collisionpipeline). 5 | It performs steps related to the collision, mainly collision detection and collision response. 6 | 7 | The [animation loop](../../../../../simulation-principles/animation-loop/) executes the 3 steps of the pipeline (see documentation on [Collision Pipeline](./../collisionpipeline)). 8 | 9 | Interaction with Other Components 10 | ================================= 11 | 12 | _DefaultPipeline_ requires other components defined in the same context: 13 | 14 | - An intersection method (e.g. MinProximityIntersection, LocalMinDistance) 15 | - A broad phase detection (e.g. [_BruteForceBroadPhase_](./../bruteforcebroadphase)) 16 | - A narrow phase detection (e.g. [_BVHNarrowPhase_](./../bvhnarrowphase)) 17 | - A contact manager (e.g. DefaultContactManager) 18 | - [optional] A group manager (e.g. [_DefaultCollisionGroupManager_](../../../collisiongroupmanagers/collisiongroupmanager)) 19 | 20 | If no intersection method is provided, a default _DiscreteIntersection_ component is created and added to the scene graph, with a warning to the user, and used as the intersection method. 21 | 22 | Pipeline 23 | ======== 24 | 25 | Here is a description of the 3 steps of the pipeline: 26 | 27 | Collision Reset 28 | --------------- 29 | 30 | This step mainly clears data computed from the previous time step. 31 | It is implemented in the function 32 | ```cpp 33 | void DefaultPipeline::doCollisionReset() 34 | ``` 35 | 36 | 1. All the contacts provided by the contact manager are cleared. 37 | 2. The group manager clears its groups 38 | 39 | Collision Detection 40 | ------------------- 41 | 42 | 1. For all collision models, computes its bounding tree. The depth of the tree is defined by a Data in DefaultPipeline. If the broad phase or the narrow phase does not require a deep tree (`needsDeepBoundingTree()`), the tree is minimal. In any case, a CubeCollisionModel is created and linked to each collision model, to be used as a Axis-Aligned Bounding Box in the broad phase. Building the tree takes into account whether the collision detection is continuous or not. This is defined in the intersection method. 43 | 2. Executes the broad phase collision detection 44 | 3. Executes the narrow phase collision detection 45 | 46 | Collision detection is implemented in the following function 47 | ```cpp 48 | void DefaultPipeline::doCollisionDetection() 49 | ``` 50 | 51 | Collision Response 52 | ------------------ 53 | 54 | 1. Create contacts in the contact manager, based on the result of the collision detection 55 | 2. Create response for all pairs of intersecting collision models, which one is not simulated 56 | 3. Create response for the rest of the pairs of intersecting collision models (the ones which are simulated). This step can be performed by the group manager if any. 57 | 58 | Creation of the response depends on the type of contact defined in the contact manager. 59 | 60 | Collision response is implemented in the following function 61 | ```cpp 62 | void DefaultPipeline::doCollisionResponse(const helper::vector& collisionModels) 63 | ``` 64 | 65 | Example of Usage 66 | ================ 67 | 68 | This component is used as follows in XML format: 69 | 70 | ```xml 71 | 72 | 73 | 74 | 75 | 76 | 77 | ``` 78 | 79 | Note [DefaultPipeline](https://www.sofa-framework.org/api/master/sofa/html/classsofa_1_1component_1_1collision_1_1_default_pipeline.html) is defined alongside other required components. 80 | 81 | 82 | -------------------------------------------------------------------------------- /30_Components/40_ODESolver/20_Backward/50_StaticSolver.md: -------------------------------------------------------------------------------- 1 | StaticSolver 2 | ============ 3 | 4 | This component belongs to the category of [integration schemes or ODE Solver](../../../../simulation-principles/system-resolution/integration-scheme/). 5 | 6 | In the field of mechanics, statics consists in finding the equilibrium taking into account the loads (internal forces, external forces and torques) acting on the physical system, that do not experience an acceleration ( $a=0$ ). Finding a static equilibrium means finding a solution to: $\textstyle \sum F=0$ where $F$ is the sum of all loads, one of which might be unknown. 7 | 8 | In a static analysis, the inertia and damping effects are ignored, i.e. the dynamic effect of the mass is ignored. It can thus be written: $M=I \alpha=0$. In the same way, when running a static simulation, time is not elapsing and time steps should rather be considered as convergence steps. 9 | 10 | In a static simulation involving elasticity, the linear system that we solve corresponds to $K \Delta u=f$ where $K$ is the stiffness matrix (derivative of elastic forces), $\Delta u$ is a vector describing the total increment of displacement and $f$ are all explicit forces. We realize here that the static solver is in fact an implicit scheme, since the $K$ matrix is present in the left-hand side of the equation. The solution $\Delta u$ is obtained iteratively. At each iteration _i_, the displacement is incremented $\Delta u_{i+1}=\Delta u_{i}+\delta u_i$, thus resulting in the following system to solve: $K_i \delta u_i=f$. 11 | 12 | In case of non-linear elasticity, $K_i$ is a linearization which must be updated with regards to the increment of displacement $\delta u_i$. In such cases, several iterations of Newton Raphson are required to find an appropriate approximate solution. In one step of the StaticSolver, the number of Newton Raphson iterations is ruled by the data field **newton_iterations**. 13 | 14 | _Reminder_: the [Newton Raphson method](https://en.wikipedia.org/wiki/Newton%27s_method) is an iterative algorithm aiming at finding the solution of the system $f(x)=0$ where $f(x)$ is non-linear. At each iteration of Newton Raphson algorithm, we find a new approximate solution: 15 | 16 | $x^{n+1}=x^n-\frac{f(x^n)}{f'(x^n)}$ where $f'(x^n) = \frac{df}{dx}(x^n)$ 17 | 18 | In our elasticity case, the system to solve is $K_i \delta u_i-f=0$. At each iteration of Newton Raphson algorithm $n$ at simulation step $i$, we therefore find: 19 | 20 | $$ 21 | \delta u_i^{n+1}=\delta u_i^{n}-\frac{(K_i^n \delta u_i^n-f)}{K_i^n} 22 | $$ 23 | 24 | 25 | Sequence diagram 26 | ---------------- 27 | 28 | 29 | 30 | 31 | Usage 32 | ----- 33 | 34 | At each simulation step and each Newton Raphson iteration, the StaticSolver **requires**: 35 | 36 | - a [LinearSolver](../../../../simulation-principles/system-resolution/linear-solver/) to solve the linear system 37 | - and a MechanicalObject to store the state vectors. 38 | 39 | A StaticSolver must be used in simulations where the dynamics has no or a negligible effect on the system. A StaticSolver would also be relevant for systems with low mass. In such case, we fall into the quasi-static analysis. 40 | 41 | In some loading configuration, applying the full forces and torques might not lead to any converging simulation. It is then relevant to go for an incremental loading, i.e. loads are applied incrementally at each simulation step $i$. This incremental loading has to be done in the associated ForceField. If you want to use this solver with Newton Raphson iterations, it is in the user's hand to make sure the external forces used in the scene (pressure, traction, etc.) only get incremented at each time step, and not at each calls to addForce (which is currently the case for most force fields). 42 | -------------------------------------------------------------------------------- /30_Components/55_Mass/30_DiagonalMass.md: -------------------------------------------------------------------------------- 1 | DiagonalMass 2 | ============ 3 | 4 | This component belongs to the category of [Masses](../../../simulation-principles/multi-model-representation/mass/). In the dynamic equation (see [Physics integration](../../../simulation-principles/multi-model-representation/physics-integration/) page), the mass density results from the first derivative in time of the momentum term. Like the MeshMatrixMass, the DiagonalMass computes the integral of this mass density over the volume of the object geometry. To do so and for any given topology (edges, triangles, quads, tetrahedra or hexahedra), the DiagonalMass integrates the mass density inside each elements and sums the mass matrix $\mathbf{M}$ in the system matrix $\mathbf{A}$. 5 | 6 | However, the DiagonalMass makes a strong simplification: it considers the mass matrix $\mathbf{M}$ as being diagonal. To build this diagonal mass matrix, the DiagonalMass relies on a numerical method called the mass lumping. It consists in summing all mass values of a line on the diagonal. This approach is already implemented in the MeshMatrixMass but the DiagonalMass proposes an optimized version of the mass lumping and extend it to edge topology. 7 | 8 | For details on the volume integration, please report to the [MeshMatrixMass](./../meshmatrixmass/) page. As demonstrated in the [MeshMatrixMass](./../meshmatrixmass/#case-of-a-linear-tetrahedron) page, in case of a topology using linear tetrahedra, the diagonal mass matrix corresponds to: 9 | 10 | 11 | $$ 12 | \mathbf{M}\dot{v}=\sum_{e=0}^E \frac{\rho V_e}{4}\begin{bmatrix}1&0&0&0\\&1&0&0\\&0&1&0\\&0&0&1\\ \end{bmatrix}\begin{bmatrix}\dot{v}_1\\ \dot{v}_2\\ \dot{v}_3\\ \dot{v}_4\\ \end{bmatrix} 13 | $$ 14 | 15 | 16 | By making the matrix diagonal (i.e. removing extra-diagonal terms), the lumping method removes the connectivity (neighborhood) information from the matrix. Due to this numerical approximation, the accuracy of the integration is decreased compared to the MeshMatrixMass integration. It is therefore advised to use the DiagonalMass carefully. 17 | 18 | 19 | 20 | 21 | ### API 22 | 23 | Depending on the type of [LinearSolver](../../../simulation-principles/system-resolution/linear-solver/) used: 24 | 25 | - for iterative solvers, the result of the multiplication between the mass matrix $\mathbf{M}$ and an approximated solution is computed by the function: 26 | 27 | ``` cpp 28 | template 29 | void DiagonalMass::addMDx(const core::MechanicalParams* /*mparams*/, DataVecDeriv& res, const DataVecDeriv& dx, SReal factor) 30 | { 31 | const MassVector &masses= d_vertexMass.getValue(); 32 | helper::WriteAccessor< DataVecDeriv > _res = res; 33 | helper::ReadAccessor< DataVecDeriv > _dx = dx; 34 | 35 | size_t n = masses.size(); 36 | 37 | for (size_t i=0; i 48 | void DiagonalMass::addMToMatrix(const core::MechanicalParams *mparams, const sofa::core::behavior::MultiMatrixAccessor* matrix) 49 | { 50 | const MassVector &masses= d_vertexMass.getValue(); 51 | const int N = defaulttype::DataTypeInfo::size(); 52 | AddMToMatrixFunctor calc; 53 | sofa::core::behavior::MultiMatrixAccessor::MatrixRef r = matrix->getMatrix(this->mstate); 54 | Real mFactor = (Real)mparams->mFactorIncludingRayleighDamping(this->rayleighMass.getValue()); 55 | for (unsigned int i=0; i PluginManager` and browse the plugin list. If the plugin SofaPython3 is not present, make sure to add the associated dynamic library using the button `Add`. 62 | 63 | More about SOFA & Python can be found on the [SofaPython3 documentation](https://sofapython3.readthedocs.io/en/latest). -------------------------------------------------------------------------------- /30_Components/15_Collision/10_Detection/10_Algorithm/20_Detection_Sweep_and_Prune.md: -------------------------------------------------------------------------------- 1 | Collisions Detection: DirectSAP 2 | =============================== 3 | 4 | The DirectSAP component belongs to the category of [Collision Detection](../../../../../simulation-principles/multi-model-representation/collision/#collision-detection). 5 | In this section, we describe the two collision detection methods based on the "[Sweep and Prune](https://en.wikipedia.org/wiki/Sweep_and_prune)" algorithm, noted SAP. The SAP method belongs to the topological methods for broad phase, based on the positions of objects in relation to others. 6 | 7 | 8 | 9 | 10 | DirectSAP corresponds to the implementation of SAP in its "direct" version, i.e. at each step it sorts all the primitives along an axis (**not checking the moving ones**) and computes overlapping pairs without saving it. But the memory used to save these primitives is created just once, the first time we add CollisionModels. 11 | 12 | 13 | ### Preliminary phase 14 | 15 | Before starting the broad phase, two steps are therefore required before the brute force detection starts: 16 | 17 | - all present collision models in the scene must be listed. This is done in the function ```void PipelineImpl::computeCollisionDetection()``` with: 18 | ```cpp 19 | root->getTreeObjects (&collisionModels); 20 | ``` 21 | - from the collision, Axis-Aligned-Bounding-Box (AABB, i.e. CubeModel) will be computed without needing a deep bounding tree (depth level = 1). This is done by each CollisionModel in the scene in the function: 22 | ```cpp 23 | computeBoundingTree(used_depth); 24 | ``` 25 | 26 | 27 | ### Broad phase 28 | 29 | It is one of the most used methods in the broad-phase algorithms because it provides an efficient and quick pairs removal (two objects too far one to the other is deleted) and it does not depend on the objects complexity. The sequential algorithm of SAP takes in input the overall objects of the environment and feeds in output a collided objects pairs list. The algorithm is divided in two principal parts: 30 | 31 | - the first one is in charge of the bounding volume update of each active virtual objects. In SOFA, these bounding volume are defined in DSAPBoxes which are simple bounding boxes. Each DSAPBox contains a Cube which contains only one final CollisionElement and pointers to min and max EndPoints. 32 | - the second part is in charge of the detection of overlapping between objects. To do that a projection of higher and upper bounds on the three axis of coordinates (x, y and z) of each 33 | AABBs is made. 34 | 35 | Only the pairs of objects whose projected bounding volumes overlap on all axes will be saved in the set of active boxes to be considered for the narrow phase. We can notice two related but different concepts on the way the SAP operates internally: the **DirectSAP** starts from scratch each time even though internal structures could be updated as performed in the [IncrSAP](./../incrsap/). 36 | 37 | 38 | ### Narrow phase 39 | 40 | The narrow phase browses all boxes considered as active by the broad phase. From this information, it is possible to recover the finest CollisionModel (which is not a CubeModel) corresponding to each box. An intersection check will then be done between these pairs. This check also depends on the [intersection method](../../../../../simulation-principles/multi-model-representation/collision/#intersection-methods) used. This last phase returns the DetectionOutput vector containing elements of CollisionModels in collision and the contact points on the surface of each model. 41 | 42 | 43 | 44 | 45 | Sequence diagram 46 | ---------------- 47 | 48 | --------------------------------------------------------------------------------