SEARCH
TOOLBOX
LANGUAGES
FirstSteps

FirstSteps

From SOFAWiki

Jump to: navigation, search
First Steps with SOFA

SOFA users and developers, feel free to contribute to this page, it is designed to help new comers to quickly have a global vision of SOFA, and not feel completely lost! Thanks Marie for the first draft !

Contents

Setting up the project

In the main directory there is a file, sofa-default.prf. It contains all the configuration options for SOFA. It is recommended that you make a copy and name it sofa-local.prf, and make any changes you might need. You can comment/uncomment the options you want. The default configuration is fine for getting started.

Understanding SOFA

Tutorials

We have created a set of tutorials the are accessible through the Modeler tool (See https://wiki.sofa-framework.org/wiki/Modeler for more details). The Modeler provides a GUI interface for creating and editing scenes.

You can access the tutorials by running the Modeler and selecting Tutorials from the menu at the top. Start with Step by Step for a guided, interactive introduction, and then look at the other topics for more details.

We have also created some basic scenes and progressive examples to show how SOFA works. You can find them here https://wiki.sofa-framework.org/wiki/Tutorials.

Documentation

The main concepts of SOFA are explained in http://www.sofa-framework.org/sofa/doc/sofadocumentation.pdf

Organization

The SOFA sources are split into several directories, each of them corresponding to a concept, and has a specific goal. The main directories are:

Resources
  • doc : SOFA Manual
  • examples : Scene files provided by SOFA
    • Demos : complex scenario, using combination of lots of SOFA components; for advanced use of SOFA
    • Components : examples files to test the behaviour of almost all the Sofa components
    • SandBox : we put here the testing scenes for in-development or unstable components
    • Objects : combination of objects, to be added to the scenes: dynamic topologies, preset for the Modeler, ...
    • CUDA : scenes using SOFA CUDA
    • Tutorials : scenes described at https://wiki.sofa-framework.org/wiki/Tutorials
  • extlibs : all the external libraries used by SOFA. To use them, most of the time, you have to activate an option for SOFA. To do so, you can use sofaConfiguration, or modify by hand sofa-default.cfg or the equivalent sofa-local.cfg, and touch the depending files. For both option, you have to compile SOFA afterwards
  • share : main file repository of SOFA, it contains the textures, 3d models, icons, ... used by SOFA
Sources
  • framework : WARNING you should not modify any files in this directory, this is the core of SOFA where all the base classes, and types are defined
    • sofa
      • core : principal concepts used in SOFA: it contains the base class: ForceField, Mapping, State, ... You should take a look to see the API provided by SOFA, but not modify them
      • defaulttype : types used in SOFA, from the Rigid types, Mass Types, ...
      • helper : facility classes like Quaternions, Factory, OpenGL functions, Input-Output system, FileRepository handler
  • modules : where the SOFA Component are actually coded
    • sofa
      • component : Sofa Components subdivided into categories (Mapping, ForceField, VisualModel ...)
      • simulation : how the scene graph and simulation is handled
      • gpu : gpu version of some SOFA components:

C++ Tutorials

We made 4 little projects coded in C++ to show how you can create your own scene using SOFA: $SOFA/applications/tutorials/

  • oneParticule: a particle with a mass under gravity
  • oneTetrahedron: a tetrahedron with a topology under gravity. We added two main features: a fixed constraint, and a visual model mapped to the simulated Tetrahedron
  • mixedPendulum: two mechanical objects of different nature linked together by a spring.
  • chainHybrid: a complex scene, the same as the one written in xml, available in $SOFA/examples/Demos/chainHybrid.scn. Several objects, of different nature, using complex topologies, visual and collision models, mixed together, and using collision detection and response.

Examples

We try to respect one rule in Sofa: for each component we provide a .scn file, in order to show how it can be used. This way we built the hierarchy of directories in $SOFA/examples/Components: in each subdirectory, forcefield, mapping, ... you will find a scene with the same name as the component. Don't hesitate to spend some times, experimenting the different components. There may be already one ready to do what you are thinking of.

Creating Scenes

XML format

To create a data structure and link the different components (C++ module of SOFA) together, scene graphs (simulation tree in XML format) are used to describe a simulation. In term of simulation tree, nodes are used to create hierarchical levels of modeling (e.g. behavior model, collision model, visual model, etc.), whereas the large collection of components corresponds to leaves under the nodes and covers a large set of fields (e.g. mechanical behavior, force fields, topology, mass, etc. ).

This description using a XML file allows a high flexibility in designing a simulation scene. Indeed, it is easy to replace one simple component by another. For example for the computation of forces acting on a mechanical system, one can replace a spring-mass force with a finite element force. Changing a component does not affect other components in the scene due to the library architecture.


Simple example of XML scene graph:

Image:pendulum.png

In this simple example, a whole pipeline allowing to simulate a pendulum is described. Each component (white name) is a C++ class of SOFA with parameters (explain in next paragraph). Thus, in this example, each component has a different goal. - The solver system with a ODE scheme for each time step and a linear solver to solve integrated time step. - The mechanical object to define the geometry of simulated object and play the role of mechanical position container. - Then, FixedConstraint and the mass define the rest of the mechanical model. - Finaly the spring forcefield, define the spring.


Data input-output

All parameters describing a scene are stored in specific C++ containers called "Data". Those containers are C++ components members reachable in the XML file. If we take the previous example of the pendulum. In each component, we can see parameter (in blue). Those parameters are specific containers member of the different c++ classes. For example the "Data name", which define simply the name of the component, is a container Data <string>. In SOFA there are common Data, i.e which can be access in every component. Those Data are: TODO chercher la liste. Then specific Data, like for example "indices" of FixedConstraint, which define the index of the point to be fixed, should be declare in this specific C++ class.


Moreover, dependency between Data containers of same nature can be specified in the XML scene files, indicating that the content of one container should be copied from the other, making the scene description fairly simple and above all efficient. To create this dependency, the flag "@" follow by the name of the source component should be use. Like in next example. Note that it is possible to link to a component located in an other node. Thus, the syntax: myData = "@LinkToOtherNode/SourceComponent.myData". Where LinkToOtherNode = ../ if you should go up to one node, or directly the name of a node. TODO: ajouter un example, ça sera plus clair.

Image:dataLink.png


Including Files

How to use the <include href="..."/> command, and overriding some parameters

Loading Mesh Files

Mesh files located in $SOFA_DIR/share or $SOFA_DIR/examples can be automatically found by Sofa DataRepository system, so you can write <MeshLoader filename="mesh/liver.msh" />.

Using Php+XML

Explain how to generate a scene using php+xml

Modeler

A graphic tool exists in SOFA to ease the creation of new scenes, the Modeler. You can find a description at this page : https://wiki.sofa-framework.org/wiki/Modeler

To see a video explaining how to use it and some of the basic operations you can do with the Modeler, click on that link: http://www.youtube.com/watch?v=IFzNY45z2lY

Note : the Modeler may require qt4 to work properly.

Writing C++ scenes

Scenes can be created in C++ and run from a C++ program. See examples in applications/tutorials.

The argument parser eases the parsing of the command line. See examples in applications/projects/runSofa.


Typedefs

For new comers, writing C++ scenes can be a difficult task; in Sofa, we made an intensive use of templates to achieve a good genericity and modularity. For the user, the side effect is a code more difficult to read, and the almost compulsory need to use typedef. To help people to write C++ scenes, we made a tool to generate typedef files. They are placed within the directory: $SOFA/modules/sofa/component/typedef.

You just need to add the header

#include <sofa/component/typedef/Sofa_typedef.h>

And then all the typedef for all the Sofa components using template will be available. For instance, to create a mechanical object, instead of writing:

sofa::component::container::MechanicalObject<sofa::defaulttype::StdVectorTypes<sofa::defaulttype::Vec<3, double>, sofa::defaulttype::Vec<3, double>, double> > *mstate;

you just need to write:

MechanicalObject3d *mstate;

The rules are simple: the typedef consists in the name of the component + prefix corresponding to its data type.

Prefix Generation
sofa::defaulttype::StdVectorTypes<sofa::defaulttype::Vec<3, double>, sofa::defaulttype::Vec<3, double>, double> 3d
sofa::defaulttype::StdVectorTypes<sofa::defaulttype::Vec<2, float>, sofa::defaulttype::Vec<2, float>, float> 1f
sofa::defaulttype::StdRigidTypes<3, double> Rigid3d
sofa::defaulttype::ExtVectorTypes<sofa::defaulttype::Vec<3, float>, sofa::defaulttype::Vec<3, float>, float> > > Ext3f

For instance, if you want to use the component ConstantForceField:

ConstantForceField3d *constant3d; //force field using particules in 3 dimension, using double precision
ConstantForceFieldRigid3f *constantRigid3f; //forcefield using rigid frames in 3 dimension, using simple precision

The typedef for Mappings are slightly different as they make the link between two objects of somewhat different datatypes. The BarycentricMapping is one of the most used mapping in Sofa scenes. To create a barycentric mechanical mapping in C++, you have to write:

sofa::component::mapping::BarycentricMapping<sofa::core::componentmodel::behavior::MechanicalMapping<sofa::core::componentmodel::behavior::MechanicalState<sofa::defaulttype::StdVectorTypes<sofa::defaulttype::Vec<3, double>, sofa::defaulttype::Vec<3, double>, double> >, sofa::core::componentmodel::behavior::MechanicalState<sofa::defaulttype::StdVectorTypes<sofa::defaulttype::Vec<3, double>, sofa::defaulttype::Vec<3, double>, double> > > > *mapping(mstate1,mstate2);

Using our typedef, it gives:

BarycentricMechanicalMapping3d_to_3d *mapping(mstate1,mstate2);

The rules to find the typedef for the mappings are : name of the mapping + prefix for Object1 + "_to_"prefix for Mapped Object2 See the table above to get the prefix. If the mapping is mechanical (it propagates the velocities from the DOFs to the mapped state, and the forces from the mapped state to the DOFs), you have to write MechanicalMapping. If the mapping is done just in position, like a VisualMapping, you have to write Mapping.

BarycentricMapping3d_to_Ext3f *baryMapping(mstate,visualmodel); //Visual Mapping: often used to add a visual model to a deformable simulated body
RigidMechanicalMappingRigid3d_to_3d *rigidMapping(rigidState, mappedState); //Mechanical Mapping: often used to add a collision model to a rigid simulated body

Discover SOFA Mechanisms

The main functions of the main loop are implemented in class simulation::Simulation, which acts as an interface between the external control loop(s), such as a GUI or a batch program, and SOFA. After scene loading, method init is applied once, then method animate is repeatedly applied to update the state of the simulated objects. Display is applied using methods updateVisual and draw. Each of these methods are implemented using visitors which traverse a scenegraph and apply abstract methods to each graph node.


SOFA relies intensively on the concept of Visitors. Animating a Simulation consists in launching a sequence of Visitors, each of them acting on a subset of Sofa Components, and triggering some specific operations. Now, if you manage to decode the visitor execution, you will get a global vision of the execution of one step of simulation in SOFA.
A tool has been created to do so, it helps you to trace the execution of the Visitor: https://wiki.sofa-framework.org/wiki/Tips#Trace_and_Profiling


Image:Trace.png


In SOFA, click on the option Trace Visitor and Component Execution of the Stats tabulation. Then, proceed to one step of simulation. Now you can see the sequence of calls, the nodes traversed and components used. You can even trace the evolution of the state vector with our latest version of the tools.

.inl files

Often the question is asked about what the inl files are, and what they are useful for
If you have no experience at all in template programming, I suggest you take a look at the "Useful link" section, where you can find good introductions to that area.
Historically .inl files are used to implement the definition of inline functions, so that to keep a "clean" .h with only declarations. In the same way, for template classes, the .inl files contains the definitions of the member functions of the class. The .cpp file is used to specify some instanciations of the template class, with sensible template parameter types.
Here is an example :

in the .h header file

template< typename MyType >
class MyTemplateClass
{
  void SomeMethod();
};

in the .inl header file resides definitions for the class member functions.

#include "MyTemplateClass.h"
 
template< typename MyType>
void MyTemplateClass<MyType>::SomeMethod()
{
/*
some stuff happens.
*/
}

the .cpp provides some instanciations of the class, with sensible template parameters.

/*
at this point the compiler needs to "see" both the declarations and definitions of 
MyTemplateClass members in order to generate the code for specific template 
parameters, therefore we include the .inl file
*/
#include "MyTemplateClass.inl"  
 
template class MyTemplateClass<char>;
template class MyTemplateClass<unsigned int>;
template class MytemplateClass<int>;


Useful links