Repository navigation
Description
I just ask Mistral AI for an analysis of the different pattern in sofa regarding the initialization of Data<> d_indices.
I put here the summary to avoid consuming token asking the same question in the future.
Analysis of indices / index Data in SOFA Components
This report analyzes all components inheriting from BaseComponent that have Data fields named "indices" or "index" (members d_indices, d_index, f_indices, etc.). The goal is to identify naming, typing, and initialization pattern inconsistencies across components, with a view toward unification.
The analysis covers:
- Data declaration (exposed name, member name, type)
- Constructor initialization patterns
- Initialization patterns in
::init()and::reinit() - Auto-fill behaviors (full or partial)
1. Summary of Types Used
| Local alias | Actual type | Family |
|---|---|---|
VecId, VecIndex, SetIndex (ROI), SetIndices |
sofa::type::vector<sofa::Index> |
Simple Data<std::vector<Index>> |
SetIndex (constraints), DataSetIndex, IndexSubsetData |
TopologySubsetIndices |
Data-derived class with topology support |
PointSubsetData<IndexArray> |
TopologySubsetData<Point, IndexArray> |
Data-derived class with topology support |
unsigned int, Index, sofa::Index |
scalar | Data<scalar> |
2. Components by Declaration Pattern
Pattern 1 — initData(&d_indices, "indices", "description") no default value
The most widespread pattern. Data named "indices", member d_indices, no explicit default value.
Projective Constraints (all use TopologySubsetIndices aliased as SetIndex or IndexSubsetData)
| Component | Member | Actual type | Init file |
|---|---|---|---|
FixedProjectiveConstraint |
SetIndex d_indices |
TopologySubsetIndices |
.inl:39 |
FixedTranslationProjectiveConstraint |
SetIndex d_indices |
TopologySubsetIndices |
.inl:36 |
FixedPlaneProjectiveConstraint |
SetIndex d_indices |
TopologySubsetIndices |
.inl:45 |
PointProjectiveConstraint |
SetIndex d_indices |
TopologySubsetIndices |
.inl:40 |
PlaneProjectiveConstraint |
IndexSubsetData d_indices |
TopologySubsetIndices |
.inl:38 |
LineProjectiveConstraint |
IndexSubsetData d_indices |
TopologySubsetIndices |
.inl:38 |
DirectionProjectiveConstraint |
IndexSubsetData d_indices |
TopologySubsetIndices |
.inl:39 |
LinearMovementProjectiveConstraint |
SetIndex d_indices |
TopologySubsetIndices |
.inl:40 |
LinearVelocityProjectiveConstraint |
SetIndex d_indices |
TopologySubsetIndices |
.inl:41 |
PartialLinearMovementProjectiveConstraint |
SetIndex d_indices |
TopologySubsetIndices |
.inl:42 |
AffineMovementProjectiveConstraint |
SetIndex d_indices |
TopologySubsetIndices |
.inl:41 |
ParabolicProjectiveConstraint |
SetIndex d_indices |
TopologySubsetIndices |
.inl:34 |
HermiteSplineProjectiveConstraint |
SetIndex d_indices |
TopologySubsetIndices |
.inl:34 |
Lagrangian Constraints
| Component | Member | Actual type | Init file |
|---|---|---|---|
FixedLagrangianConstraint |
SetIndex d_indices |
TopologySubsetIndices |
.inl:35 |
StopperLagrangianConstraint |
Data<vector<unsigned int>> d_indices |
Simple Data<vector<unsigned>> |
.inl:34 |
Mappings
| Component | Member | Actual type | Init file |
|---|---|---|---|
SubsetMapping |
SetIndex d_indices |
PointSubsetData<IndexArray> (topological) |
.inl:32 |
DistanceFromTargetMapping |
Data<vector<unsigned>> d_indices |
Simple Data<vector<unsigned>> |
.inl:39 |
ForceFields / Mass
| Component | Member | Actual type | Init file |
|---|---|---|---|
ConstantForceField |
SetIndex d_indices |
TopologySubsetIndices |
.inl:38 |
TorsionForceField |
Data<VecId> d_indices |
Simple Data<vector<PointId>> |
.inl:39 |
AngularSpringForceField |
Data<vector<Index>> d_indices |
Simple Data<vector<Index>> |
.inl:37 |
UniformMass |
DataSetIndex d_indices |
TopologySubsetIndices |
.inl:76 |
Engines (ROI / Select / Analyze / Generate)
| Component | Member | Actual type | Init file |
|---|---|---|---|
BaseROI |
Data<SetIndex> d_indices |
Simple Data<vector<Index>> |
.inl:63 |
ComplementaryROI |
Data<SetIndex> d_indices |
Simple Data<vector<Index>> |
.inl:46 |
MeshBoundaryROI |
Data<SetIndex> d_indices |
Simple Data<vector<Index>> |
.cpp:39 |
MeshSubsetEngine |
Data<SetIndices> d_indices |
Simple Data<vector<Index>> |
.inl:37 |
SelectConnectedLabelsROI |
Data<vector<Index>> d_indices |
Simple Data<vector<Index>> |
.h:58 (inline) |
SelectLabelROI |
Data<vector<Index>> d_indices |
Simple Data<vector<Index>> |
.h:69 (inline) |
AverageCoord |
Data<VecIndex> d_indices |
Simple Data<vector<Index>> |
.inl:34 |
MeshClosingEngine |
Data<VecSeqIndex> indices |
Data<vector<vector<Index>>> (no d_ prefix) |
.h:82 (inline) |
Pattern 2 — initData(&d_index, (unsigned)0, "index", "description") with default value 0
Data named "index" (singular), member d_index, scalar type, default value 0.
| Component | Member | Type | Default | Init file |
|---|---|---|---|---|
MechanicalStateController |
Data<unsigned int> d_index |
unsigned int |
(unsigned int)0 |
.inl:47 |
RigidMapping |
Data<sofa::Index> d_index |
sofa::Index |
(unsigned)0 |
.inl:121 |
DeformableOnRigidFrameMapping |
Data<unsigned int> d_index |
unsigned int |
(unsigned)0 |
.inl:34 |
Pattern 3 — INCONSISTENT: initData(&d_index, "indices", "description")
Member named d_index (singular) but Data named "indices" (plural), vector type.
| Component | Member | Actual type | Data name | Init file |
|---|---|---|---|---|
SkinningMapping |
Data<vector<SVector<unsigned int>>> d_index |
vector<vector<unsigned>> |
"indices" |
.inl:42 |
This is the only case where the member is
d_indexbut the exposed name is"indices". All other components with ad_indexmember use the name"index".
Pattern 4 — initData(&f_indices, "indices", "description") f_ prefix (engines)
Data named "indices", member f_indices (engine convention: f_ = field/input), no default value.
| Component | Member | Actual type | Init file |
|---|---|---|---|
PlaneROI |
Data<SetIndex> f_indices |
Data<vector<Index>> |
.inl:40 |
ProximityROI |
Data<SetIndex> f_indices |
Data<vector<Index>> |
.inl:41 |
PairBoxRoi |
Data<SetIndex> f_indices |
Data<vector<Index>> |
.inl:38 |
SubsetTopology |
Data<SetIndex> f_indices |
Data<vector<Index>> |
.inl:48 |
PointsFromIndices |
Data<SetIndex> f_indices |
Data<vector<Index>> |
.inl:32 |
ValuesFromIndices |
Data<VecIndex> f_indices |
Data<vector<Index>> |
.inl:32 |
IndicesFromValues |
Data<VecIndex> f_indices |
Data<vector<Index>> |
.inl:33 |
IndexValueMapper |
Data<vector<Index>> f_indices |
Data<vector<Index>> |
.inl:32 |
Indices2ValuesMapper |
Data<vector<Real>> f_indices |
Data<vector<Real>> |
.inl:36 |
MapIndices |
Data<VecIndex> f_indices |
Data<vector<Index>> |
.inl:32 |
Pattern 5 — this, "indices", "description", DataEngineInput/Output (new vectorData style)
Uses core::objectmodel::vectorData<T> with the modern constructor this, "name", "desc", DataEngineInput.
| Component | Member | Type | Data name | Init file |
|---|---|---|---|---|
ROIValueMapper |
vectorData<vector<Index>> f_indices |
vectorData<vector<Index>> |
"indices" |
.h:93 |
MergeROIs |
vectorData<vector<Index>> f_indices |
vectorData<vector<Index>> |
"indices" |
.h:65 |
MeshSplittingEngine |
vectorData<SetIndices> indices |
vectorData<vector<Index>> |
"indices" |
.inl:55 |
MeshSplittingEnginealso hasedgeIndices,triangleIndices,quadIndices,tetrahedronIndices,hexahedronIndices— all invectorData<SetIndices>.
Pattern 6 — std::array<TopologySubsetIndices, 2> initialized in the declaration
Pattern unique to SpringForceField: a std::array of TopologySubsetIndices initialized directly in the member declaration.
| Component | Member | Type | File |
|---|---|---|---|
SpringForceField |
std::array<TopologySubsetIndices, 2> d_springsIndices |
array of TopologySubsetIndices |
.h:148-151 |
// SpringForceField.h:148-151
std::array<sofa::core::topology::TopologySubsetIndices, 2> d_springsIndices
{
sofa::core::topology::TopologySubsetIndices {initData(&d_springsIndices[0], "springsIndices1", "List of indices in springs from the first mstate", true, true)},
sofa::core::topology::TopologySubsetIndices {initData(&d_springsIndices[1], "springsIndices2", "List of indices in springs from the second mstate", true, true)}
};Note: the exposed names are
"springsIndices1"and"springsIndices2", not"indices".
Pattern 7 — Data names different from "indices" / "index"
| Component | Member | Exposed Data name | Type | Init file |
|---|---|---|---|---|
SmoothMeshEngine |
Data<vector<unsigned int>> input_indices |
"input_indices" |
Data<vector<unsigned>> |
.inl:34 |
AttachProjectiveConstraint |
SetIndex f_indices1 |
"indices1" |
TopologySubsetIndices |
.inl:199 |
AttachProjectiveConstraint |
SetIndex f_indices2 |
"indices2" |
TopologySubsetIndices |
.inl:200 |
MergePoints |
f_indices1 |
"indices1" |
— | .inl:34 |
MergePoints |
f_indices2 |
"indices2" |
— | .inl:35 |
NearestPointROI |
f_indices1 |
"indices1" |
— | .inl:37 |
NearestPointROI |
f_indices2 |
"indices2" |
— | .inl:38 |
3. Initialization Patterns in ::init() / ::reinit()
Pattern A — createTopologyHandler(topology): topology linkage
Components using TopologySubsetIndices systematically call d_indices.createTopologyHandler(_topology) in init() to enable topology change tracking.
| Component | init() |
reinit() |
|---|---|---|
FixedProjectiveConstraint |
createTopologyHandler + checkIndices() |
checkIndices() |
PointProjectiveConstraint |
createTopologyHandler + validation |
std::sort(tmp) on indices |
PlaneProjectiveConstraint |
createTopologyHandler + validation |
normalizes normal vector |
LineProjectiveConstraint |
createTopologyHandler + validation |
updateJacobian() |
DirectionProjectiveConstraint |
createTopologyHandler + validation |
normalize + build matrix |
LinearMovementProjectiveConstraint |
createTopologyHandler + x0.resize(0) |
— |
LinearVelocityProjectiveConstraint |
createTopologyHandler (indices + coordinates) |
— |
PartialLinearMovementProjectiveConstraint |
createTopologyHandler + x0.resize(0) |
— |
AffineMovementProjectiveConstraint |
createTopologyHandler + validation |
— |
ParabolicProjectiveConstraint |
createTopologyHandler + projection computation |
reinit() calls init() |
HermiteSplineProjectiveConstraint |
createTopologyHandler |
reinit() calls init() |
FixedTranslationProjectiveConstraint |
createTopologyHandler (indices + coordinates) |
— |
FixedPlaneProjectiveConstraint |
createTopologyHandler + selectVerticesAlongPlane() |
— |
ConstantForceField |
createTopologyHandler + m_systemSize = topology->getNbPoints() |
— (callback updateFromIndices) |
SubsetMapping |
createTopologyHandler if d_handleTopologyChange |
— |
UniformMass |
createTopologyHandler + supportNewTopologyElements(true) + callback |
— |
Pattern B — Auto-fill if indices not set (isSet() / empty())
When the user does not provide indices, the component auto-generates them (0..N-1).
| Component | Condition | Action |
|---|---|---|
StopperLagrangianConstraint |
if(!d_indices.isSet()) |
resize(x.size()) then indices[i] = i for all i |
UniformMass |
if(indices.size()==0) after d_localRange check |
clear() then push_back(i) for i=0..N-1 |
Pattern C — Index generation from d_first/d_last or proximity search
| Component | Logic in init() |
|---|---|
SubsetMapping |
If d_indices empty and d_first != InvalidID → generates [first..last]. Else if empty → proximity search with d_radius between in/out positions |
// SubsetMapping.inl:76-90
if (d_indices.getValue().empty() && d_first.getValue() != sofa::InvalidID) {
indices.resize(last-first+1);
for (Index i=0; i<indices.size(); ++i)
indices[i] = first+i;
}
else if (d_indices.getValue().empty()) {
// proximity search with d_radius
}Pattern D — Index extension/resizing
| Component | Logic in init() |
|---|---|
DistanceFromTargetMapping |
If indices.size() < targetPositions.size() → push_back(i) to fill up to target size |
SkinningMapping |
If d_index.size() != numChildren → updateWeights() auto-recomputes |
Pattern E — Index validation (bounds)
Several ProjectiveConstraints validate that each index < mstate->getSize() and call removeConstraint(index) if invalid.
| Component | Validation function |
|---|---|
FixedProjectiveConstraint |
checkIndices() (called in both init() and reinit()) |
PointProjectiveConstraint |
inline loop in init() |
PlaneProjectiveConstraint |
inline loop in init() |
LineProjectiveConstraint |
inline loop in init() |
DirectionProjectiveConstraint |
inline loop in init() |
AffineMovementProjectiveConstraint |
inline loop in init() |
// Typical pattern (FixedProjectiveConstraint.inl:130+)
const SetIndexArray & indices = d_indices.getValue();
for (unsigned int i=0; i<indices.size(); ++i) {
const Index index = indices[i];
if (index >= maxIndex) {
msg_error() << "Index " << index << " not valid!";
removeConstraint(index);
}
}Pattern F — No index processing in init()/reinit()
| Component | Behavior |
|---|---|
FixedLagrangianConstraint |
init() → just Inherit1::init(), no reinit() |
MechanicalStateController |
d_index (scalar) used directly in applyController(), never initialized |
DeformableOnRigidFrameMapping |
d_index (scalar) used directly in mappings, never initialized |
RigidMapping |
d_index (scalar) used in getRigidIndex(), init() calls reinit() for d_points |
TorsionForceField |
No init()/reinit() functions at all |
AngularSpringForceField |
init()/reinit() exist but do not touch d_indices |
Pattern G — Engines: setDirtyValue() in init(), update() in reinit()
All engines follow this pattern. Indices are computed in doUpdate(), not directly in init()/reinit().
| Component | init() |
reinit() |
Index processing |
|---|---|---|---|
BaseROI |
auto-link d_positions |
— | in children's doUpdate() |
ComplementaryROI |
vd_setIndices.resize(d_nbSet), setDirtyValue() |
update() |
doUpdate(): indices.clear() + computation via std::set |
PlaneROI |
auto-link f_X0, edges, triangles, setDirtyValue() |
update() |
in doUpdate() |
ProximityROI |
auto-link f_X0, setDirtyValue() |
update() |
in doUpdate() |
PairBoxRoi |
auto-link f_X0, setDirtyValue() |
update() |
in doUpdate() |
SubsetTopology |
auto-link f_X0, topology, setDirtyValue() |
update() |
in doUpdate() |
PointsFromIndices |
auto-link f_X, setDirtyValue() |
update() |
doUpdate(): reads f_indices |
ValuesFromIndices |
f_outStr.setParent(&f_out), setDirtyValue() |
update() |
doUpdate(): reads f_indices |
IndicesFromValues |
setDirtyValue() |
update() |
doUpdate(): indices.clear() + search |
IndexValueMapper |
setDirtyValue() |
update() |
doUpdate(): reads f_indices |
Indices2ValuesMapper |
setDirtyValue() |
update() |
doUpdate(): reads f_indices |
MapIndices |
setDirtyValue() |
update() |
doUpdate(): reads f_indices |
SmoothMeshEngine |
link topology, setDirtyValue() |
update() |
doUpdate(): reads input_indices, if empty → all points |
AverageCoord |
SingleStateAccessor::init(), setDirtyValue() |
update() |
doUpdate(): reads d_indices, if empty → all |
MeshClosingEngine |
(inline in .h) | update() |
doUpdate(): oindices.clear() + loop generation |
MeshBoundaryROI |
auto-link triangles/quads, setDirtyValue() |
update() |
doUpdate(): indices.clear() + boundary detection |
SelectConnectedLabelsROI |
(inline in .h) | — | doUpdate(): indices.clear() + conditional push_back |
SelectLabelROI |
(inline in .h) | — | doUpdate(): indices.clear() + conditional push_back |
Pattern H — reinit() calls init() (or vice versa)
| Component | Relationship |
|---|---|
ParabolicProjectiveConstraint |
reinit() → calls init() |
HermiteSplineProjectiveConstraint |
reinit() → calls init() |
AttachProjectiveConstraint |
init() → calls reinit() |
SkinningMapping |
init() → calls reinit() at the end |
RigidMapping |
init() → calls this->reinit() |
Pattern I — Update via callback (DataTracker)
| Component | Mechanism |
|---|---|
ConstantForceField |
addUpdateCallback("updateFromIndices", {&d_indices}, ...) in constructor → updateFromIndices() checks indicesSize > m_systemSize |
Pattern J — d_index scalar: never initialized in init/reinit
| Component | Usage of d_index |
|---|---|
MechanicalStateController |
Read directly in applyController(): unsigned int i = d_index.getValue() |
DeformableOnRigidFrameMapping |
Read in apply(): (*inRigid)[d_index.getValue()] or [size-1-d_index] |
RigidMapping |
Read in getRigidIndex(): returns d_index.getValue() or size-1-d_index |
These components have no initialization logic for
d_indexininit()/reinit(). The constructor default value0is used as-is.
4. Auto-fill 0..N-1 (full or partial)
Full auto-fill 0..N-1 in init() / reinit()
| Component | Function | Condition | Code |
|---|---|---|---|
StopperLagrangianConstraint |
init() |
if(!d_indices.isSet()) |
indices.resize(x.size()); for(i=0;i<x.size();i++) indices[i]=i; |
UniformMass |
initDefaultImpl() (called by init()) |
if(indices.size()==0) (after d_localRange check) |
indices.clear(); for(i=0;i<mstate->getSize();i++) indices.push_back(i); |
Partial auto-fill (sub-sequence) in init() / reinit()
| Component | Function | Condition | Generated sequence |
|---|---|---|---|
UniformMass |
initDefaultImpl() |
d_localRange[0] >= 0 && d_localRange[1] > 0 && d_localRange[1]+1 < getSize() |
d_localRange[0] .. d_localRange[1] |
SubsetMapping |
init() |
d_indices empty AND d_first != InvalidID |
d_first .. d_last (clamped to inSize) |
DistanceFromTargetMapping |
init() |
indices.size() < targetPositions.size() |
Fills with i from indices.size() to targetPositions.size()-1 (sequential extension) |
Default value [0] in the constructor (not in init()/reinit())
These components set index 0 as the sole default value in the constructor:
| Component | Member | Code |
|---|---|---|
FixedProjectiveConstraint |
d_indices |
d_indices.beginEdit()->push_back(0); d_indices.endEdit(); |
PointProjectiveConstraint |
d_indices |
same |
PlaneProjectiveConstraint |
d_indices |
same |
LineProjectiveConstraint |
d_indices |
same |
DirectionProjectiveConstraint |
d_indices |
same |
LinearMovementProjectiveConstraint |
d_indices |
same + comment // default to indice 0 |
LinearVelocityProjectiveConstraint |
d_indices |
same |
PartialLinearMovementProjectiveConstraint |
d_indices |
same |
FixedTranslationProjectiveConstraint |
d_indices |
same |
BaseROI |
d_indices |
sofa::helper::getWriteOnlyAccessor(d_indices).push_back(0); |
BoxROI |
d_indices |
same |
PlaneROI |
f_indices |
f_indices.beginEdit()->push_back(0); |
ProximityROI |
f_indices |
same |
SubsetTopology |
f_indices |
same |
Note: this is not a 0..N-1 auto-fill, but a default value
[0](a single index).
Equivalent behavior via d_fixAll (without filling the vector)
| Component | Mechanism | Effect |
|---|---|---|
FixedProjectiveConstraint |
d_fixAll=true |
Loop for(i=0; i<mstate->getSize(); i++) in projectMatrix()/projectResponse() — ignores d_indices |
FixedLagrangianConstraint |
d_fixAll=true |
m_cid.resize(getSize()) and dofIdx = lineNumber — implicitly uses 0..N-1 |
Fallback "all indices" in doUpdate() (engines)
| Component | Member | Condition | Behavior |
|---|---|---|---|
AverageCoord |
d_indices |
indices.empty() |
n = coord.size(), iterates coord[i] for i=0..n-1 |
SmoothMeshEngine |
input_indices |
indices.size()==0 |
Processes all points (loop over out.size()) |
Auto-fill in recomputeIndices() (internal member, not a Data)
| Component | Internal member | Source Data | Function |
|---|---|---|---|
RestShapeSpringsForceField |
m_indices |
d_points |
recomputeIndices(): if m_indices.empty() → push_back(i) for i=0..N-1 |
PolynomialRestShapeSpringsForceField |
m_indices |
d_points |
same |
These two components have no
d_indicesData — the fill concerns an internal memberm_indicescomputed fromd_points.
5. Pattern Summary Table
| Pattern | Description | Components |
|---|---|---|
| A | createTopologyHandler(topology) |
13 ProjectiveConstraints + ConstantForceField + SubsetMapping + UniformMass |
| B | Auto-fill 0..N-1 if empty | StopperLagrangianConstraint, UniformMass, AverageCoord |
| C | Generation from first/last or proximity |
SubsetMapping |
| D | Extension/resizing | DistanceFromTargetMapping, SkinningMapping |
| E | Bounds validation + removeConstraint |
6 ProjectiveConstraints |
| F | No processing in init/reinit | FixedLagrangianConstraint, MechanicalStateController, DeformableOnRigidFrameMapping, RigidMapping, TorsionForceField, AngularSpringForceField |
| G | Engine: setDirtyValue() / update() |
18 engines |
| H | reinit() ↔ init() (circular call) |
Parabolic, HermiteSpline, Attach, SkinningMapping, RigidMapping |
| I | DataTracker callback | ConstantForceField |
| J | d_index scalar without init |
MechanicalStateController, DeformableOnRigidFrameMapping, RigidMapping |
6. Key Inconsistencies Identified
| Issue | Affected components | Detail |
|---|---|---|
Member d_index but Data "indices" |
SkinningMapping |
Only case where singular member = plural name |
Member d_indices but Data "index" |
None | — |
Member without d_ prefix |
MeshClosingEngine (indices) |
Data named "indices", member indices |
Member input_indices, Data "input_indices" |
SmoothMeshEngine |
Full name differs |
Two fields indices1/indices2 |
AttachProjectiveConstraint, MergePoints, NearestPointROI |
Two-index-set pattern |
| Scalar vs vector type | MechanicalStateController, RigidMapping, DeformableOnRigidFrameMapping (scalar) vs all others (vector) |
d_index = scalar, d_indices = vector |
| Topological vs simple type | Constraints + UniformMass + ConstantForceField + SubsetMapping (topological) vs StopperLagrangianConstraint + BaseROI + engines (simple Data<vector<Index>>) |
TopologySubsetIndices vs Data<vector<Index>> |
vectorData vs Data |
ROIValueMapper, MergeROIs, MeshSplittingEngine (vectorData) vs all others (Data) |
Two different APIs for engines |
Init in .h vs .inl vs .cpp |
SelectConnectedLabelsROI/SelectLabelROI/MeshClosingEngine (.h) vs MeshBoundaryROI (.cpp) vs others (.inl) |
Placement inconsistency |
| Two opposite semantics for "empty" | StopperLagrangianConstraint + UniformMass (empty = all) vs ProjectiveConstraints (empty = none, except constructor default [0]) |
Radically different behavior if user touches nothing |
Constructor default [0] vs auto-fill in init() |
ProjectiveConstraints ([0] in constructor, isSet()==true) vs StopperLagrangianConstraint (checks !isSet() in init()) |
"Not set" detection inconsistency |
UniformMass has two priority levels |
d_localRange (partial) > full auto-fill > user indices |
User indices are overwritten by d_localRange if set |
SubsetMapping has 3 sources of truth |
d_indices > d_first/d_last > proximity search |
Priority not documented in the Data |
reinit() calls init() |
ParabolicProjectiveConstraint, HermiteSplineProjectiveConstraint |
Dangerous pattern (full reinitialization on every reinit) |
init() calls reinit() |
AttachProjectiveConstraint, SkinningMapping, RigidMapping |
Unusual inverted logic |
No reinit() at all |
FixedLagrangianConstraint, StopperLagrangianConstraint, MechanicalStateController, UniformMass, TorsionForceField |
— |
d_index never validated |
MechanicalStateController, DeformableOnRigidFrameMapping, RigidMapping |
No check that index < mstate size |
Activity