AttachProjectiveConstraint
This component belongs to the category of Projective Constraint. 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. 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).
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:
- if false, the position of the object1 are projected onto the object2. Therefore, object2 only follows object1 without affecting the motion of object1Usage
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.
Attach given pair of particles, projecting the positions of the second particles to the first ones.
Rigid2d
Templates:
- Rigid2d
Target: Sofa.Component.Constraint.Projective
namespace: sofa::component::constraint::projective
parents:
- PairInteractionProjectiveConstraintSet
Data
Name | Description | Default value |
---|---|---|
name | object name | unnamed |
printLog | if true, emits extra messages at runtime. | 0 |
tags | list of the subsets the object belongs to | |
bbox | this object bounding box | |
componentState | The state of the component among (Dirty, Valid, Undefined, Loading, Invalid). | Undefined |
listening | if true, handle the events, otherwise ignore the events | 0 |
group | ID of the group containing this constraint. This ID is used to specify which constraints are solved by which solver, by specifying in each solver which groups of constraints it should handle. | 0 |
endTime | The constraint stops acting after the given value. Use a negative value for infinite constraints | -1 |
indices1 | Indices of the source points on the first model | |
indices2 | Indices of the fixed points on the second model | |
twoWay | if true, projects the constraint vertices of both object1 and object2 towards their average degrees of freedom and derivatives. If false, the position of the object1 are projected onto the object2. Therefore, object2 only follows object1 without affecting the motion of object1 | 0 |
freeRotations | true to keep rotations free (only used for Rigid DOFs) | 0 |
lastFreeRotation | true to keep rotation of the last attached point free (only used for Rigid DOFs) | 0 |
restRotations | true to use rest rotations local offsets (only used for Rigid DOFs) | 0 |
lastPos | position at which the attach constraint should become inactive | |
lastDir | direction from lastPos at which the attach coustraint should become inactive | |
clamp | true to clamp particles at lastPos instead of freeing them. | 0 |
minDistance | the constraint become inactive if the distance between the points attached is bigger than minDistance. | -1 |
positionFactor | IN: Factor applied to projection of position | 1 |
velocityFactor | IN: Factor applied to projection of velocity | 1 |
responseFactor | IN: Factor applied to projection of force/acceleration | 1 |
constraintFactor | Vector of factors adapting the application of the constraint per pair of points (0 -> the constraint is released. 1 -> the constraint is fully constrained) |
Links
Name | Description | Destination type name |
---|---|---|
context | Graph Node containing this object (or BaseContext::getDefault() if no graph is used) | BaseContext |
slaves | Sub-objects used internally by this object | BaseObject |
master | nullptr for regular objects, or master object for which this object is one sub-objects | BaseObject |
mechanicalStates | List of mechanical states to which this component is associated | BaseMechanicalState |
object1 | First object associated to this component | MechanicalState<Rigid2d> |
object2 | Second object associated to this component | MechanicalState<Rigid2d> |
Rigid3d
Templates:
- Rigid3d
Target: Sofa.Component.Constraint.Projective
namespace: sofa::component::constraint::projective
parents:
- PairInteractionProjectiveConstraintSet
Data
Name | Description | Default value |
---|---|---|
name | object name | unnamed |
printLog | if true, emits extra messages at runtime. | 0 |
tags | list of the subsets the object belongs to | |
bbox | this object bounding box | |
componentState | The state of the component among (Dirty, Valid, Undefined, Loading, Invalid). | Undefined |
listening | if true, handle the events, otherwise ignore the events | 0 |
group | ID of the group containing this constraint. This ID is used to specify which constraints are solved by which solver, by specifying in each solver which groups of constraints it should handle. | 0 |
endTime | The constraint stops acting after the given value. Use a negative value for infinite constraints | -1 |
indices1 | Indices of the source points on the first model | |
indices2 | Indices of the fixed points on the second model | |
twoWay | if true, projects the constraint vertices of both object1 and object2 towards their average degrees of freedom and derivatives. If false, the position of the object1 are projected onto the object2. Therefore, object2 only follows object1 without affecting the motion of object1 | 0 |
freeRotations | true to keep rotations free (only used for Rigid DOFs) | 0 |
lastFreeRotation | true to keep rotation of the last attached point free (only used for Rigid DOFs) | 0 |
restRotations | true to use rest rotations local offsets (only used for Rigid DOFs) | 0 |
lastPos | position at which the attach constraint should become inactive | |
lastDir | direction from lastPos at which the attach coustraint should become inactive | |
clamp | true to clamp particles at lastPos instead of freeing them. | 0 |
minDistance | the constraint become inactive if the distance between the points attached is bigger than minDistance. | -1 |
positionFactor | IN: Factor applied to projection of position | 1 |
velocityFactor | IN: Factor applied to projection of velocity | 1 |
responseFactor | IN: Factor applied to projection of force/acceleration | 1 |
constraintFactor | Vector of factors adapting the application of the constraint per pair of points (0 -> the constraint is released. 1 -> the constraint is fully constrained) |
Links
Name | Description | Destination type name |
---|---|---|
context | Graph Node containing this object (or BaseContext::getDefault() if no graph is used) | BaseContext |
slaves | Sub-objects used internally by this object | BaseObject |
master | nullptr for regular objects, or master object for which this object is one sub-objects | BaseObject |
mechanicalStates | List of mechanical states to which this component is associated | BaseMechanicalState |
object1 | First object associated to this component | MechanicalState<Rigid3d> |
object2 | Second object associated to this component | MechanicalState<Rigid3d> |
Vec1d
Templates:
- Vec1d
Target: Sofa.Component.Constraint.Projective
namespace: sofa::component::constraint::projective
parents:
- PairInteractionProjectiveConstraintSet
Data
Name | Description | Default value |
---|---|---|
name | object name | unnamed |
printLog | if true, emits extra messages at runtime. | 0 |
tags | list of the subsets the object belongs to | |
bbox | this object bounding box | |
componentState | The state of the component among (Dirty, Valid, Undefined, Loading, Invalid). | Undefined |
listening | if true, handle the events, otherwise ignore the events | 0 |
group | ID of the group containing this constraint. This ID is used to specify which constraints are solved by which solver, by specifying in each solver which groups of constraints it should handle. | 0 |
endTime | The constraint stops acting after the given value. Use a negative value for infinite constraints | -1 |
indices1 | Indices of the source points on the first model | |
indices2 | Indices of the fixed points on the second model | |
twoWay | if true, projects the constraint vertices of both object1 and object2 towards their average degrees of freedom and derivatives. If false, the position of the object1 are projected onto the object2. Therefore, object2 only follows object1 without affecting the motion of object1 | 0 |
freeRotations | true to keep rotations free (only used for Rigid DOFs) | 0 |
lastFreeRotation | true to keep rotation of the last attached point free (only used for Rigid DOFs) | 0 |
restRotations | true to use rest rotations local offsets (only used for Rigid DOFs) | 0 |
lastPos | position at which the attach constraint should become inactive | |
lastDir | direction from lastPos at which the attach coustraint should become inactive | |
clamp | true to clamp particles at lastPos instead of freeing them. | 0 |
minDistance | the constraint become inactive if the distance between the points attached is bigger than minDistance. | -1 |
positionFactor | IN: Factor applied to projection of position | 1 |
velocityFactor | IN: Factor applied to projection of velocity | 1 |
responseFactor | IN: Factor applied to projection of force/acceleration | 1 |
constraintFactor | Vector of factors adapting the application of the constraint per pair of points (0 -> the constraint is released. 1 -> the constraint is fully constrained) |
Links
Name | Description | Destination type name |
---|---|---|
context | Graph Node containing this object (or BaseContext::getDefault() if no graph is used) | BaseContext |
slaves | Sub-objects used internally by this object | BaseObject |
master | nullptr for regular objects, or master object for which this object is one sub-objects | BaseObject |
mechanicalStates | List of mechanical states to which this component is associated | BaseMechanicalState |
object1 | First object associated to this component | MechanicalState<Vec1d> |
object2 | Second object associated to this component | MechanicalState<Vec1d> |
Vec2d
Templates:
- Vec2d
Target: Sofa.Component.Constraint.Projective
namespace: sofa::component::constraint::projective
parents:
- PairInteractionProjectiveConstraintSet
Data
Name | Description | Default value |
---|---|---|
name | object name | unnamed |
printLog | if true, emits extra messages at runtime. | 0 |
tags | list of the subsets the object belongs to | |
bbox | this object bounding box | |
componentState | The state of the component among (Dirty, Valid, Undefined, Loading, Invalid). | Undefined |
listening | if true, handle the events, otherwise ignore the events | 0 |
group | ID of the group containing this constraint. This ID is used to specify which constraints are solved by which solver, by specifying in each solver which groups of constraints it should handle. | 0 |
endTime | The constraint stops acting after the given value. Use a negative value for infinite constraints | -1 |
indices1 | Indices of the source points on the first model | |
indices2 | Indices of the fixed points on the second model | |
twoWay | if true, projects the constraint vertices of both object1 and object2 towards their average degrees of freedom and derivatives. If false, the position of the object1 are projected onto the object2. Therefore, object2 only follows object1 without affecting the motion of object1 | 0 |
freeRotations | true to keep rotations free (only used for Rigid DOFs) | 0 |
lastFreeRotation | true to keep rotation of the last attached point free (only used for Rigid DOFs) | 0 |
restRotations | true to use rest rotations local offsets (only used for Rigid DOFs) | 0 |
lastPos | position at which the attach constraint should become inactive | |
lastDir | direction from lastPos at which the attach coustraint should become inactive | |
clamp | true to clamp particles at lastPos instead of freeing them. | 0 |
minDistance | the constraint become inactive if the distance between the points attached is bigger than minDistance. | -1 |
positionFactor | IN: Factor applied to projection of position | 1 |
velocityFactor | IN: Factor applied to projection of velocity | 1 |
responseFactor | IN: Factor applied to projection of force/acceleration | 1 |
constraintFactor | Vector of factors adapting the application of the constraint per pair of points (0 -> the constraint is released. 1 -> the constraint is fully constrained) |
Links
Name | Description | Destination type name |
---|---|---|
context | Graph Node containing this object (or BaseContext::getDefault() if no graph is used) | BaseContext |
slaves | Sub-objects used internally by this object | BaseObject |
master | nullptr for regular objects, or master object for which this object is one sub-objects | BaseObject |
mechanicalStates | List of mechanical states to which this component is associated | BaseMechanicalState |
object1 | First object associated to this component | MechanicalState<Vec2d> |
object2 | Second object associated to this component | MechanicalState<Vec2d> |
Vec3d
Templates:
- Vec3d
Target: Sofa.Component.Constraint.Projective
namespace: sofa::component::constraint::projective
parents:
- PairInteractionProjectiveConstraintSet
Data
Name | Description | Default value |
---|---|---|
name | object name | unnamed |
printLog | if true, emits extra messages at runtime. | 0 |
tags | list of the subsets the object belongs to | |
bbox | this object bounding box | |
componentState | The state of the component among (Dirty, Valid, Undefined, Loading, Invalid). | Undefined |
listening | if true, handle the events, otherwise ignore the events | 0 |
group | ID of the group containing this constraint. This ID is used to specify which constraints are solved by which solver, by specifying in each solver which groups of constraints it should handle. | 0 |
endTime | The constraint stops acting after the given value. Use a negative value for infinite constraints | -1 |
indices1 | Indices of the source points on the first model | |
indices2 | Indices of the fixed points on the second model | |
twoWay | if true, projects the constraint vertices of both object1 and object2 towards their average degrees of freedom and derivatives. If false, the position of the object1 are projected onto the object2. Therefore, object2 only follows object1 without affecting the motion of object1 | 0 |
freeRotations | true to keep rotations free (only used for Rigid DOFs) | 0 |
lastFreeRotation | true to keep rotation of the last attached point free (only used for Rigid DOFs) | 0 |
restRotations | true to use rest rotations local offsets (only used for Rigid DOFs) | 0 |
lastPos | position at which the attach constraint should become inactive | |
lastDir | direction from lastPos at which the attach coustraint should become inactive | |
clamp | true to clamp particles at lastPos instead of freeing them. | 0 |
minDistance | the constraint become inactive if the distance between the points attached is bigger than minDistance. | -1 |
positionFactor | IN: Factor applied to projection of position | 1 |
velocityFactor | IN: Factor applied to projection of velocity | 1 |
responseFactor | IN: Factor applied to projection of force/acceleration | 1 |
constraintFactor | Vector of factors adapting the application of the constraint per pair of points (0 -> the constraint is released. 1 -> the constraint is fully constrained) |
Links
Name | Description | Destination type name |
---|---|---|
context | Graph Node containing this object (or BaseContext::getDefault() if no graph is used) | BaseContext |
slaves | Sub-objects used internally by this object | BaseObject |
master | nullptr for regular objects, or master object for which this object is one sub-objects | BaseObject |
mechanicalStates | List of mechanical states to which this component is associated | BaseMechanicalState |
object1 | First object associated to this component | MechanicalState<Vec3d> |
object2 | Second object associated to this component | MechanicalState<Vec3d> |
Examples
AttachProjectiveConstraint.scn
<Node name="root" dt="0.02">
<RequiredPlugin name="Sofa.Component.Constraint.Projective"/> <!-- Needed to use components [AttachProjectiveConstraint FixedProjectiveConstraint] -->
<RequiredPlugin name="Sofa.Component.Engine.Select"/> <!-- Needed to use components [BoxROI] -->
<RequiredPlugin name="Sofa.Component.LinearSolver.Iterative"/> <!-- Needed to use components [CGLinearSolver] -->
<RequiredPlugin name="Sofa.Component.Mass"/> <!-- Needed to use components [UniformMass] -->
<RequiredPlugin name="Sofa.Component.ODESolver.Backward"/> <!-- Needed to use components [EulerImplicitSolver] -->
<RequiredPlugin name="Sofa.Component.SolidMechanics.FEM.Elastic"/> <!-- Needed to use components [TetrahedronFEMForceField] -->
<RequiredPlugin name="Sofa.Component.StateContainer"/> <!-- Needed to use components [MechanicalObject] -->
<RequiredPlugin name="Sofa.Component.Topology.Container.Grid"/> <!-- Needed to use components [RegularGridTopology] -->
<RequiredPlugin name="Sofa.Component.Visual"/> <!-- Needed to use components [VisualStyle] -->
<VisualStyle displayFlags="showBehaviorModels showForceFields" />
<DefaultAnimationLoop/>
<Node name="Single">
<EulerImplicitSolver name="cg_odesolver" printLog="false" rayleighStiffness="0.1" rayleighMass="0.1" />
<CGLinearSolver iterations="25" name="linear solver" tolerance="1.0e-9" threshold="1.0e-9" />
<Node name="M1">
<MechanicalObject showObject="1"/>
<UniformMass vertexMass="1" />
<RegularGridTopology nx="4" ny="4" nz="28" xmin="-9" xmax="-6" ymin="0" ymax="3" zmin="0" zmax="27" />
<BoxConstraint box="-9.1 -0.1 -0.1 -5.9 3.1 0.1" />
<!--<BoxConstraint box="-9.1 -0.1 26.9 -5.9 3.1 27.1" />-->
<TetrahedronFEMForceField name="FEM" youngModulus="4000" poissonRatio="0.3" />
</Node>
</Node>
<Node name="AttachOneWay">
<EulerImplicitSolver name="cg_odesolver" printLog="false" />
<CGLinearSolver iterations="25" name="linear solver" tolerance="1.0e-9" threshold="1.0e-9" />
<Node name="M1">
<MechanicalObject />
<UniformMass vertexMass="1" />
<RegularGridTopology nx="4" ny="4" nz="10" xmin="-4" xmax="-1" ymin="0" ymax="3" zmin="0" zmax="9" />
<BoxConstraint box="-4.1 -0.1 -0.1 -0.9 3.1 0.1" />
<TetrahedronFEMForceField name="FEM" youngModulus="4000" poissonRatio="0.3" />
</Node>
<Node name="M2">
<EulerImplicitSolver name="cg_odesolver" printLog="false" />
<CGLinearSolver iterations="25" name="linear solver" tolerance="1.0e-9" threshold="1.0e-9" />
<MechanicalObject />
<UniformMass vertexMass="1" />
<RegularGridTopology nx="4" ny="4" nz="10" xmin="-4" xmax="-1" ymin="0" ymax="3" zmin="9" zmax="18" />
<TetrahedronFEMForceField name="FEM" youngModulus="4000" poissonRatio="0.3" />
</Node>
<Node name="M3">
<EulerImplicitSolver name="cg_odesolver" printLog="false" />
<CGLinearSolver iterations="25" name="linear solver" tolerance="1.0e-9" threshold="1.0e-9" />
<MechanicalObject />
<UniformMass vertexMass="1" />
<RegularGridTopology nx="4" ny="4" nz="10" xmin="-4" xmax="-1" ymin="0" ymax="3" zmin="18" zmax="27" />
<!--<BoxConstraint box="-4.1 -0.1 26.9 -0.9 3.1 27.1" />-->
<TetrahedronFEMForceField name="FEM" youngModulus="4000" poissonRatio="0.3" />
</Node>
<AttachProjectiveConstraint object1="@M1" object2="@M2" indices1="144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159" indices2="0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15" constraintFactor="1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1"/>
<AttachProjectiveConstraint object1="@M2" object2="@M3" indices1="144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159" indices2="0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15" constraintFactor="1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1"/>
</Node>
<Node name="AttachTwoWay">
<EulerImplicitSolver name="cg_odesolver" printLog="false" />
<CGLinearSolver iterations="25" name="linear solver" tolerance="1.0e-9" threshold="1.0e-9" />
<Node name="M1">
<MechanicalObject />
<UniformMass vertexMass="1" />
<RegularGridTopology nx="4" ny="4" nz="10" xmin="1" xmax="4" ymin="0" ymax="3" zmin="0" zmax="9" />
<BoxConstraint box="0.9 -0.1 -0.1 4.1 3.1 0.1" />
<TetrahedronFEMForceField name="FEM" youngModulus="4000" poissonRatio="0.3" />
</Node>
<Node name="M2">
<EulerImplicitSolver name="cg_odesolver" printLog="false" />
<CGLinearSolver iterations="25" name="linear solver" tolerance="1.0e-9" threshold="1.0e-9" />
<MechanicalObject />
<UniformMass vertexMass="1" />
<RegularGridTopology nx="4" ny="4" nz="10" xmin="1" xmax="4" ymin="0" ymax="3" zmin="9" zmax="18" />
<TetrahedronFEMForceField name="FEM" youngModulus="4000" poissonRatio="0.3" />
</Node>
<Node name="M3">
<EulerImplicitSolver name="cg_odesolver" printLog="false" />
<CGLinearSolver iterations="25" name="linear solver" tolerance="1.0e-9" threshold="1.0e-9" />
<MechanicalObject />
<UniformMass vertexMass="1" />
<RegularGridTopology nx="4" ny="4" nz="10" xmin="1" xmax="4" ymin="0" ymax="3" zmin="18" zmax="27" />
<!--<BoxConstraint box="0.9 -0.1 26.9 4.1 3.1 27.1" />-->
<TetrahedronFEMForceField name="FEM" youngModulus="4000" poissonRatio="0.3" />
</Node>
<AttachProjectiveConstraint object1="@M1" object2="@M2" twoWay="true" indices1="144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159" indices2="0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15" constraintFactor="1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1"/>
<AttachProjectiveConstraint object1="@M2" object2="@M3" twoWay="true" indices1="144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159" indices2="0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15"/>
</Node>
</Node>
def createScene(root_node):
root = root_node.addChild('root', dt="0.02")
root.addObject('RequiredPlugin', name="Sofa.Component.Constraint.Projective")
root.addObject('RequiredPlugin', name="Sofa.Component.Engine.Select")
root.addObject('RequiredPlugin', name="Sofa.Component.LinearSolver.Iterative")
root.addObject('RequiredPlugin', name="Sofa.Component.Mass")
root.addObject('RequiredPlugin', name="Sofa.Component.ODESolver.Backward")
root.addObject('RequiredPlugin', name="Sofa.Component.SolidMechanics.FEM.Elastic")
root.addObject('RequiredPlugin', name="Sofa.Component.StateContainer")
root.addObject('RequiredPlugin', name="Sofa.Component.Topology.Container.Grid")
root.addObject('RequiredPlugin', name="Sofa.Component.Visual")
root.addObject('VisualStyle', displayFlags="showBehaviorModels showForceFields")
root.addObject('DefaultAnimationLoop', )
single = root.addChild('Single')
single.addObject('EulerImplicitSolver', name="cg_odesolver", printLog="false", rayleighStiffness="0.1", rayleighMass="0.1")
single.addObject('CGLinearSolver', iterations="25", name="linear solver", tolerance="1.0e-9", threshold="1.0e-9")
m1 = Single.addChild('M1')
m1.addObject('MechanicalObject', showObject="1")
m1.addObject('UniformMass', vertexMass="1")
m1.addObject('RegularGridTopology', nx="4", ny="4", nz="28", xmin="-9", xmax="-6", ymin="0", ymax="3", zmin="0", zmax="27")
m1.addObject('BoxConstraint', box="-9.1 -0.1 -0.1 -5.9 3.1 0.1")
m1.addObject('TetrahedronFEMForceField', name="FEM", youngModulus="4000", poissonRatio="0.3")
attach_one_way = root.addChild('AttachOneWay')
attach_one_way.addObject('EulerImplicitSolver', name="cg_odesolver", printLog="false")
attach_one_way.addObject('CGLinearSolver', iterations="25", name="linear solver", tolerance="1.0e-9", threshold="1.0e-9")
m1 = AttachOneWay.addChild('M1')
m1.addObject('MechanicalObject', )
m1.addObject('UniformMass', vertexMass="1")
m1.addObject('RegularGridTopology', nx="4", ny="4", nz="10", xmin="-4", xmax="-1", ymin="0", ymax="3", zmin="0", zmax="9")
m1.addObject('BoxConstraint', box="-4.1 -0.1 -0.1 -0.9 3.1 0.1")
m1.addObject('TetrahedronFEMForceField', name="FEM", youngModulus="4000", poissonRatio="0.3")
m2 = AttachOneWay.addChild('M2')
m2.addObject('EulerImplicitSolver', name="cg_odesolver", printLog="false")
m2.addObject('CGLinearSolver', iterations="25", name="linear solver", tolerance="1.0e-9", threshold="1.0e-9")
m2.addObject('MechanicalObject', )
m2.addObject('UniformMass', vertexMass="1")
m2.addObject('RegularGridTopology', nx="4", ny="4", nz="10", xmin="-4", xmax="-1", ymin="0", ymax="3", zmin="9", zmax="18")
m2.addObject('TetrahedronFEMForceField', name="FEM", youngModulus="4000", poissonRatio="0.3")
m3 = AttachOneWay.addChild('M3')
m3.addObject('EulerImplicitSolver', name="cg_odesolver", printLog="false")
m3.addObject('CGLinearSolver', iterations="25", name="linear solver", tolerance="1.0e-9", threshold="1.0e-9")
m3.addObject('MechanicalObject', )
m3.addObject('UniformMass', vertexMass="1")
m3.addObject('RegularGridTopology', nx="4", ny="4", nz="10", xmin="-4", xmax="-1", ymin="0", ymax="3", zmin="18", zmax="27")
m3.addObject('TetrahedronFEMForceField', name="FEM", youngModulus="4000", poissonRatio="0.3")
attach_one_way.addObject('AttachProjectiveConstraint', object1="@M1", object2="@M2", indices1="144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159", indices2="0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15", constraintFactor="1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1")
attach_one_way.addObject('AttachProjectiveConstraint', object1="@M2", object2="@M3", indices1="144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159", indices2="0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15", constraintFactor="1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1")
attach_two_way = root.addChild('AttachTwoWay')
attach_two_way.addObject('EulerImplicitSolver', name="cg_odesolver", printLog="false")
attach_two_way.addObject('CGLinearSolver', iterations="25", name="linear solver", tolerance="1.0e-9", threshold="1.0e-9")
m1 = AttachTwoWay.addChild('M1')
m1.addObject('MechanicalObject', )
m1.addObject('UniformMass', vertexMass="1")
m1.addObject('RegularGridTopology', nx="4", ny="4", nz="10", xmin="1", xmax="4", ymin="0", ymax="3", zmin="0", zmax="9")
m1.addObject('BoxConstraint', box="0.9 -0.1 -0.1 4.1 3.1 0.1")
m1.addObject('TetrahedronFEMForceField', name="FEM", youngModulus="4000", poissonRatio="0.3")
m2 = AttachTwoWay.addChild('M2')
m2.addObject('EulerImplicitSolver', name="cg_odesolver", printLog="false")
m2.addObject('CGLinearSolver', iterations="25", name="linear solver", tolerance="1.0e-9", threshold="1.0e-9")
m2.addObject('MechanicalObject', )
m2.addObject('UniformMass', vertexMass="1")
m2.addObject('RegularGridTopology', nx="4", ny="4", nz="10", xmin="1", xmax="4", ymin="0", ymax="3", zmin="9", zmax="18")
m2.addObject('TetrahedronFEMForceField', name="FEM", youngModulus="4000", poissonRatio="0.3")
m3 = AttachTwoWay.addChild('M3')
m3.addObject('EulerImplicitSolver', name="cg_odesolver", printLog="false")
m3.addObject('CGLinearSolver', iterations="25", name="linear solver", tolerance="1.0e-9", threshold="1.0e-9")
m3.addObject('MechanicalObject', )
m3.addObject('UniformMass', vertexMass="1")
m3.addObject('RegularGridTopology', nx="4", ny="4", nz="10", xmin="1", xmax="4", ymin="0", ymax="3", zmin="18", zmax="27")
m3.addObject('TetrahedronFEMForceField', name="FEM", youngModulus="4000", poissonRatio="0.3")
attach_two_way.addObject('AttachProjectiveConstraint', object1="@M1", object2="@M2", twoWay="true", indices1="144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159", indices2="0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15", constraintFactor="1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1")
attach_two_way.addObject('AttachProjectiveConstraint', object1="@M2", object2="@M3", twoWay="true", indices1="144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159", indices2="0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15")
AttachProjectiveConstraintMatrix.scn
<Node name="root" dt="0.02">
<RequiredPlugin name="Sofa.Component.Constraint.Projective"/> <!-- Needed to use components [AttachProjectiveConstraint FixedProjectiveConstraint] -->
<RequiredPlugin name="Sofa.Component.Engine.Select"/> <!-- Needed to use components [BoxROI] -->
<RequiredPlugin name="Sofa.Component.LinearSolver.Direct"/> <!-- Needed to use components [EigenSimplicialLDLT] -->
<RequiredPlugin name="Sofa.Component.LinearSolver.Iterative"/> <!-- Needed to use components [CGLinearSolver] -->
<RequiredPlugin name="Sofa.Component.Mass"/> <!-- Needed to use components [UniformMass] -->
<RequiredPlugin name="Sofa.Component.ODESolver.Backward"/> <!-- Needed to use components [EulerImplicitSolver] -->
<RequiredPlugin name="Sofa.Component.SolidMechanics.FEM.Elastic"/> <!-- Needed to use components [TetrahedronFEMForceField] -->
<RequiredPlugin name="Sofa.Component.StateContainer"/> <!-- Needed to use components [MechanicalObject] -->
<RequiredPlugin name="Sofa.Component.Topology.Container.Grid"/> <!-- Needed to use components [RegularGridTopology] -->
<RequiredPlugin name="Sofa.Component.Visual"/> <!-- Needed to use components [VisualStyle] -->
<VisualStyle displayFlags="showBehaviorModels showForceFields" />
<DefaultAnimationLoop/>
<Node name="AttachOneWay">
<EulerImplicitSolver name="cg_odesolver" printLog="false" rayleighStiffness="0.1" rayleighMass="0.1" />
<CGLinearSolver iterations="25" name="linear solver" tolerance="1.0e-9" threshold="1.0e-9" />
<Node name="M1">
<MechanicalObject showObject="1"/>
<UniformMass vertexMass="1" />
<RegularGridTopology nx="4" ny="4" nz="10" xmin="1" xmax="4" ymin="0" ymax="3" zmin="0" zmax="9" />
<BoxConstraint box="0.9 -0.1 -0.1 4.1 3.1 0.1" />
<TetrahedronFEMForceField name="FEM" youngModulus="4000" poissonRatio="0.3" />
</Node>
<Node name="M2">
<MechanicalObject />
<UniformMass vertexMass="1" />
<RegularGridTopology nx="4" ny="4" nz="10" xmin="1" xmax="4" ymin="0" ymax="3" zmin="9" zmax="18" />
<TetrahedronFEMForceField name="FEM" youngModulus="4000" poissonRatio="0.3" />
</Node>
<!--
<Node name="M3">
<EulerImplicitSolver name="cg_odesolver" printLog="false"/>
<CGLinearSolver iterations="25" name="linear solver" tolerance="1.0e-9" threshold="1.0e-9"/>
<MechanicalObject/>
<UniformMass vertexMass="1"/>
<RegularGridTopology nx="4" ny="4" nz="10" xmin="1" xmax="4" ymin="0" ymax="3" zmin="18" zmax="27"/>
<TetrahedronFEMForceField name="FEM" youngModulus="4000" poissonRatio="0.3"/>
</Node>
-->
<AttachProjectiveConstraint object1="@M1" object2="@M2" indices1="144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159" indices2="0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15"/>
<!-- <AttachProjectiveConstraint object1="@M2" object2="@M3" radius="0.1" indices1="144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159" indices2="0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15" constraintFactor="1"/> -->
</Node>
<Node name="AttachOneWay2">
<EulerImplicitSolver name="cg_odesolver" printLog="false" />
<EigenSimplicialLDLT template="CompressedRowSparseMatrixMat3x3"/>
<Node name="M1">
<MechanicalObject />
<UniformMass vertexMass="1" />
<RegularGridTopology nx="4" ny="4" nz="10" xmin="-4" xmax="-1" ymin="0" ymax="3" zmin="0" zmax="9" />
<BoxConstraint box="-4.1 -0.9 -0.1 4.1 3.1 0.1" />
<TetrahedronFEMForceField name="FEM" youngModulus="4000" poissonRatio="0.3" />
</Node>
<Node name="M2">
<MechanicalObject />
<UniformMass vertexMass="1" />
<RegularGridTopology nx="4" ny="4" nz="10" xmin="-4" xmax="-1" ymin="0" ymax="3" zmin="9" zmax="18" />
<TetrahedronFEMForceField name="FEM" youngModulus="4000" poissonRatio="0.3" />
</Node>
<!--
<Node name="M3">
<EulerImplicitSolver name="cg_odesolver" printLog="false"/>
<CGLinearSolver iterations="25" name="linear solver" tolerance="1.0e-9" threshold="1.0e-9"/>
<MechanicalObject/>
<UniformMass vertexMass="1"/>
<RegularGridTopology nx="4" ny="4" nz="10" xmin="-4" xmax="-1" ymin="0" ymax="3" zmin="18" zmax="27"/>
<TetrahedronFEMForceField name="FEM" youngModulus="4000" poissonRatio="0.3"/>
</Node>
-->
<AttachProjectiveConstraint object1="@M1" object2="@M2" indices1="144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159" indices2="0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15"/>
<!-- <AttachProjectiveConstraint object1="@M2" object2="@M3" radius="0.1" indices1="144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159" indices2="0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15" constraintFactor="1"/> -->
</Node>
</Node>
def createScene(root_node):
root = root_node.addChild('root', dt="0.02")
root.addObject('RequiredPlugin', name="Sofa.Component.Constraint.Projective")
root.addObject('RequiredPlugin', name="Sofa.Component.Engine.Select")
root.addObject('RequiredPlugin', name="Sofa.Component.LinearSolver.Direct")
root.addObject('RequiredPlugin', name="Sofa.Component.LinearSolver.Iterative")
root.addObject('RequiredPlugin', name="Sofa.Component.Mass")
root.addObject('RequiredPlugin', name="Sofa.Component.ODESolver.Backward")
root.addObject('RequiredPlugin', name="Sofa.Component.SolidMechanics.FEM.Elastic")
root.addObject('RequiredPlugin', name="Sofa.Component.StateContainer")
root.addObject('RequiredPlugin', name="Sofa.Component.Topology.Container.Grid")
root.addObject('RequiredPlugin', name="Sofa.Component.Visual")
root.addObject('VisualStyle', displayFlags="showBehaviorModels showForceFields")
root.addObject('DefaultAnimationLoop', )
attach_one_way = root.addChild('AttachOneWay')
attach_one_way.addObject('EulerImplicitSolver', name="cg_odesolver", printLog="false", rayleighStiffness="0.1", rayleighMass="0.1")
attach_one_way.addObject('CGLinearSolver', iterations="25", name="linear solver", tolerance="1.0e-9", threshold="1.0e-9")
m1 = AttachOneWay.addChild('M1')
m1.addObject('MechanicalObject', showObject="1")
m1.addObject('UniformMass', vertexMass="1")
m1.addObject('RegularGridTopology', nx="4", ny="4", nz="10", xmin="1", xmax="4", ymin="0", ymax="3", zmin="0", zmax="9")
m1.addObject('BoxConstraint', box="0.9 -0.1 -0.1 4.1 3.1 0.1")
m1.addObject('TetrahedronFEMForceField', name="FEM", youngModulus="4000", poissonRatio="0.3")
m2 = AttachOneWay.addChild('M2')
m2.addObject('MechanicalObject', )
m2.addObject('UniformMass', vertexMass="1")
m2.addObject('RegularGridTopology', nx="4", ny="4", nz="10", xmin="1", xmax="4", ymin="0", ymax="3", zmin="9", zmax="18")
m2.addObject('TetrahedronFEMForceField', name="FEM", youngModulus="4000", poissonRatio="0.3")
attach_one_way.addObject('AttachProjectiveConstraint', object1="@M1", object2="@M2", indices1="144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159", indices2="0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15")
attach_one_way2 = root.addChild('AttachOneWay2')
attach_one_way2.addObject('EulerImplicitSolver', name="cg_odesolver", printLog="false")
attach_one_way2.addObject('EigenSimplicialLDLT', template="CompressedRowSparseMatrixMat3x3")
m1 = AttachOneWay2.addChild('M1')
m1.addObject('MechanicalObject', )
m1.addObject('UniformMass', vertexMass="1")
m1.addObject('RegularGridTopology', nx="4", ny="4", nz="10", xmin="-4", xmax="-1", ymin="0", ymax="3", zmin="0", zmax="9")
m1.addObject('BoxConstraint', box="-4.1 -0.9 -0.1 4.1 3.1 0.1")
m1.addObject('TetrahedronFEMForceField', name="FEM", youngModulus="4000", poissonRatio="0.3")
m2 = AttachOneWay2.addChild('M2')
m2.addObject('MechanicalObject', )
m2.addObject('UniformMass', vertexMass="1")
m2.addObject('RegularGridTopology', nx="4", ny="4", nz="10", xmin="-4", xmax="-1", ymin="0", ymax="3", zmin="9", zmax="18")
m2.addObject('TetrahedronFEMForceField', name="FEM", youngModulus="4000", poissonRatio="0.3")
attach_one_way2.addObject('AttachProjectiveConstraint', object1="@M1", object2="@M2", indices1="144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159", indices2="0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15")