A SOFA component is a class or a class template that inherits, directly or not, from sofa::core::objectmodel::BaseObject
. A component must also respect some conventions:
- the declaration must begin with the
SOFA_CLASS
macro. It will expand to some code required by SOFA, that will enable some kind of reflection mechanisms; - a component must be registered in the
ObjectFactory
, using theRegisterObject
mechanism (see example below), otherwise SOFA won’t be aware of it.
Here is a minimal example, for a component that does nothing:
#include <sofa/core/objectmodel/BaseObject.h>
class MyComponent : public sofa::core::objectmodel::BaseObject
{public:
SOFA_CLASS(MyComponent, sofa::core::objectmodel::BaseObject);
MyComponent ();virtual ~MyComponent ();
};
#include "MyComponent.h"
#include <sofa/core/ObjectFactory.h>
MyComponent::MyComponent()
{
}
MyComponent::~MyComponent()
{
}
int MyComponentClass = sofa::core::RegisterObject("This component does nothing.").add<MyComponent>();
Once the plugin is compiled, this component can be used in an XML scene file. You should also add a RequiredPlugin
element in the root node in order to load MyPlugin
when the scene is loaded.
<?xml version="1.0"?>
<Node name="Root">
<RequiredPlugin pluginName="MyPlugin"/>
<MyComponent>
</Node>
This is a basic example; most components don’t inherit directly from BaseObject
, but from a subclass which represent a specific aspect of a simulation. For example, force field components inherit from sofa::core::BaseForcefield
, or one of its subclasses.
Add Data to your component
Almost every component has parameters, inputs, or outputs: they are referred to as Data; in a scene file, those are the XML attributes of the component. Each XML attribute of a component is actually a member of the class, declared in a special way: it is encapsulated in a Data. For example, in order to add a float Data named myparam
to our component, we will add this member to MyComponent
:
float> m_myparam; Data<
Then we must register and initialise it in each Constructor of MyComponent:
0.42, "myparam", "Here should be a short description of myparam."))
MyComponent::MyComponent(): d_myparam(initData(&d_myparam,
{ }
This allows us to use this Data in scene files; it can be assigned a value like so:
<?xml version="1.0"?>
<Node name="Root">
<RequiredPlugin pluginName="MyPlugin"/>
<MyComponent myparam="3.7">
</Node>
Last modified: 4 April 2023