SAPIEN calls a component’s scene-entry hook when three conditions become true together: the component is enabled, it is attached to an entity, and that entity belongs to a scene. Creating the component or attaching it to an off-scene entity establishes only part of that relationship.
The Component Lifecycle documentation defines the entry hook as on_add_to_scene() and the removal hook as on_remove_from_scene(). The first runs when the three conditions become true; the second runs when they cease to be true together. The component’s implementations should register and unregister it with the appropriate system.
This article follows the official lifecycle and architecture pages checked on October 16, 2026. No component was created or simulation stepped for the explanation.
An entity supplies a pose; components supply its functions
The Scene, Entity, Component, and System overview describes a scene as holding entities and systems. An entity has a position, orientation and attached components. Its components determine whether it participates in physics, has a rendered appearance or acts as a camera.
The overview’s concrete examples give those roles substance. A PhysxRigidDynamicComponent connects an entity to rigid-body simulation. A render-body component gives it an appearance, while a RenderCameraComponent makes an entity a camera. PhysxSystem updates physics-related components, and RenderSystem manages render bodies and cameras.
These responsibilities explain why an allocated component needs a system connection. A Python reference to an entity identifies an object in the application; registration makes the relevant system aware of the component it should process. The documentation uses Entity, Component and System terminology while explicitly distinguishing SAPIEN’s design from an ECS architecture.
The last missing condition triggers entry
The lifecycle page expresses the entry condition as this conjunction:
component.enabled
and component.entity is not None
and component.entity.scene is not None
The order in which those conditions are established can vary. The page describes three ways to complete them:
| Final change | Conditions already established | Entry event |
|---|---|---|
| Add an entity to a scene | Its component is attached and enabled | on_add_to_scene() runs |
| Attach a component to an entity already in a scene | The component is enabled | on_add_to_scene() runs |
| Enable a component | It is already attached to an entity in a scene | on_add_to_scene() runs |
In each case, the final change completes the same relationship. That is more precise than associating registration only with an add_entity call. An entity can already be in the scene when a newly attached or newly enabled component becomes eligible to enter its system.
Disabling and re-enabling changes participation
Consider an illustrative sequence in which a component starts enabled. It is first unattached, then attached to an entity outside the scene, and finally brought into the scene with that entity.
| Step | Enabled? | Attached to an entity? | Entity in scene? | Lifecycle effect |
|---|---|---|---|---|
| Create the example component | Yes, by assumption | No | No | Entry condition incomplete |
| Attach it to an off-scene entity | Yes | Yes | No | Entry condition still incomplete |
| Add the entity to the scene | Yes | Yes | Yes | Entry hook runs; its implementation registers with the system |
| Disable the component | No | Yes | Yes | Removal hook runs; its implementation unregisters it |
| Enable it again | Yes | Yes | Yes | Entry hook runs again to register it |
The table explicitly assumes the initial enabled value; it does not infer a constructor default. More importantly, it shows that membership can change while the entity remains in the scene. Disabling the component breaks the conjunction even though the entity attachment and scene membership still exist.
Removing the parent entity from the scene is another documented removal event. In that case, the scene condition becomes false. The hook is tied to losing the complete relationship, not only to deleting the component object from application code.
Registration determines which system processes the component
For the dynamic rigid-body example, the architecture overview describes querying the scene for its PhysxSystem and registering a PhysX rigid dynamic actor in that system’s simulation scene. When the physics system steps, it synchronizes updated poses to the component, which updates the SAPIEN entity’s pose.
This gives the entry hook a concrete purpose: it establishes the connection through which a system processes the component. The removal hook performs the corresponding unregistration. For custom behavior, the lifecycle page assigns those responsibilities to the hook implementations; having the entry condition become true is the occasion to perform that work.
The two official pages use slightly different names in their descriptions. The architecture overview says add_to_scene and remove_from_scene, while the dedicated lifecycle page names on_add_to_scene() and on_remove_from_scene(). This explanation uses the latter hook names from the lifecycle specification and does not turn the overview’s shortened names into a runnable custom-component implementation.
When an object exists in application code but its expected physics or rendering behavior is absent, the three conditions localize the question. Is the component enabled, is it attached, and is its entity in the scene? Once all three hold, the relevant hook and system registration explain how the component becomes part of simulation or rendering.
For a related testing question, the Gazebo TestFixture explanation describes observing a named component condition at a chosen update phase. SAPIEN’s lifecycle supplies its own concrete condition to examine: whether the three membership requirements hold and the corresponding system registration has occurred.