NearestPointROI
Attach given pair of particles, projecting the positions of the second particles to the first ones.
Rigid2d
Templates:
- Rigid2d
Target: Sofa.Component.Engine.Select
namespace: sofa::component::engine::select
parents:
- DataEngine
- PairStateAccessor
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 |
inputIndices1 | Indices of the points to consider on the first model | |
inputIndices2 | Indices of the points to consider on the first model | |
radius | Radius to search corresponding fixed point | 1 |
useRestPosition | If true will use restPosition only at init | 1 |
Outputs | ||
indices1 | Indices from the first model associated to a dof from the second model | |
indices2 | Indices from the second model associated to a dof from the first model | |
edges | List of edge indices | |
indexPairs | list of couples (parent index + index in the parent) | |
distances | List of distances between pairs of points | |
Visualization | ||
drawPairs | Option to draw the positions pairs computed | 0 |
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.Engine.Select
namespace: sofa::component::engine::select
parents:
- DataEngine
- PairStateAccessor
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 |
inputIndices1 | Indices of the points to consider on the first model | |
inputIndices2 | Indices of the points to consider on the first model | |
radius | Radius to search corresponding fixed point | 1 |
useRestPosition | If true will use restPosition only at init | 1 |
Outputs | ||
indices1 | Indices from the first model associated to a dof from the second model | |
indices2 | Indices from the second model associated to a dof from the first model | |
edges | List of edge indices | |
indexPairs | list of couples (parent index + index in the parent) | |
distances | List of distances between pairs of points | |
Visualization | ||
drawPairs | Option to draw the positions pairs computed | 0 |
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.Engine.Select
namespace: sofa::component::engine::select
parents:
- DataEngine
- PairStateAccessor
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 |
inputIndices1 | Indices of the points to consider on the first model | |
inputIndices2 | Indices of the points to consider on the first model | |
radius | Radius to search corresponding fixed point | 1 |
useRestPosition | If true will use restPosition only at init | 1 |
Outputs | ||
indices1 | Indices from the first model associated to a dof from the second model | |
indices2 | Indices from the second model associated to a dof from the first model | |
edges | List of edge indices | |
indexPairs | list of couples (parent index + index in the parent) | |
distances | List of distances between pairs of points | |
Visualization | ||
drawPairs | Option to draw the positions pairs computed | 0 |
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.Engine.Select
namespace: sofa::component::engine::select
parents:
- DataEngine
- PairStateAccessor
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 |
inputIndices1 | Indices of the points to consider on the first model | |
inputIndices2 | Indices of the points to consider on the first model | |
radius | Radius to search corresponding fixed point | 1 |
useRestPosition | If true will use restPosition only at init | 1 |
Outputs | ||
indices1 | Indices from the first model associated to a dof from the second model | |
indices2 | Indices from the second model associated to a dof from the first model | |
edges | List of edge indices | |
indexPairs | list of couples (parent index + index in the parent) | |
distances | List of distances between pairs of points | |
Visualization | ||
drawPairs | Option to draw the positions pairs computed | 0 |
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.Engine.Select
namespace: sofa::component::engine::select
parents:
- DataEngine
- PairStateAccessor
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 |
inputIndices1 | Indices of the points to consider on the first model | |
inputIndices2 | Indices of the points to consider on the first model | |
radius | Radius to search corresponding fixed point | 1 |
useRestPosition | If true will use restPosition only at init | 1 |
Outputs | ||
indices1 | Indices from the first model associated to a dof from the second model | |
indices2 | Indices from the second model associated to a dof from the first model | |
edges | List of edge indices | |
indexPairs | list of couples (parent index + index in the parent) | |
distances | List of distances between pairs of points | |
Visualization | ||
drawPairs | Option to draw the positions pairs computed | 0 |
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> |
Vec6d
Templates:
- Vec6d
Target: Sofa.Component.Engine.Select
namespace: sofa::component::engine::select
parents:
- DataEngine
- PairStateAccessor
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 |
inputIndices1 | Indices of the points to consider on the first model | |
inputIndices2 | Indices of the points to consider on the first model | |
radius | Radius to search corresponding fixed point | 1 |
useRestPosition | If true will use restPosition only at init | 1 |
Outputs | ||
indices1 | Indices from the first model associated to a dof from the second model | |
indices2 | Indices from the second model associated to a dof from the first model | |
edges | List of edge indices | |
indexPairs | list of couples (parent index + index in the parent) | |
distances | List of distances between pairs of points | |
Visualization | ||
drawPairs | Option to draw the positions pairs computed | 0 |
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<Vec6d> |
object2 | Second object associated to this component | MechanicalState<Vec6d> |
Examples
NearestPointROI.scn
<Node name="root" dt="0.02">
<Node name="requiredPlugins">
<RequiredPlugin name="Sofa.Component.AnimationLoop"/> <!-- Needed to use components [FreeMotionAnimationLoop] -->
<RequiredPlugin name="Sofa.Component.Constraint.Lagrangian.Correction"/> <!-- Needed to use components [UncoupledConstraintCorrection] -->
<RequiredPlugin name="Sofa.Component.Constraint.Lagrangian.Model"/> <!-- Needed to use components [BilateralLagrangianConstraint] -->
<RequiredPlugin name="Sofa.Component.Constraint.Lagrangian.Solver"/> <!-- Needed to use components [GenericConstraintSolver] -->
<RequiredPlugin name="Sofa.Component.Constraint.Projective"/> <!-- Needed to use components [FixedProjectiveConstraint] -->
<RequiredPlugin name="Sofa.Component.Engine.Select"/> <!-- Needed to use components [BoxROI NearestPointROI] -->
<RequiredPlugin name="Sofa.Component.LinearSolver.Iterative"/> <!-- Needed to use components [CGLinearSolver] -->
<RequiredPlugin name="Sofa.Component.Mapping.Linear"/> <!-- Needed to use components [SubsetMultiMapping] -->
<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.SolidMechanics.Spring"/> <!-- Needed to use components [MeshSpringForceField] -->
<RequiredPlugin name="Sofa.Component.StateContainer"/> <!-- Needed to use components [MechanicalObject] -->
<RequiredPlugin name="Sofa.Component.Topology.Container.Dynamic"/> <!-- Needed to use components [EdgeSetTopologyContainer] -->
<RequiredPlugin name="Sofa.Component.Topology.Container.Grid"/> <!-- Needed to use components [RegularGridTopology] -->
<RequiredPlugin name="Sofa.Component.Visual"/> <!-- Needed to use components [VisualStyle] -->
</Node>
<VisualStyle displayFlags="showBehaviorModels showForceFields showInteractionForceFields" />
<FreeMotionAnimationLoop parallelODESolving="true"/>
<GenericConstraintSolver tolerance="0.001" maxIterations="1000" resolutionMethod="UnbuildGaussSeidel" multithreading="true"/>
<!--
This Node shows how NearestPointROI is used to create constraints to link close vertices
-->
<Node name="ObjectsAttachedWithConstraints">
<EulerImplicitSolver name="cg_odesolver" rayleighStiffness="0.1" rayleighMass="0.1"/>
<CGLinearSolver iterations="25" name="linear solver" tolerance="1.0e-9" threshold="1.0e-9" />
<Node name="M1">
<MechanicalObject name="mo"/>
<UniformMass totalMass="160" />
<RegularGridTopology nx="4" ny="4" nz="10" xmin="0" xmax="3" ymin="0" ymax="3" zmin="0" zmax="9" />
<BoxROI box="-0.1 -0.1 -0.1 3.1 3.1 0.1" name="box"/>
<FixedProjectiveConstraint indices="@box.indices"/>
<TetrahedronFEMForceField name="FEM" youngModulus="4000" poissonRatio="0.3" computeVonMisesStress="1" showVonMisesStressPerElement="true"/>
<UncoupledConstraintCorrection useOdeSolverIntegrationFactors="0"/>
</Node>
<Node name="M2">
<MechanicalObject name="mo"/>
<UniformMass totalMass="160" />
<RegularGridTopology nx="4" ny="4" nz="10" xmin="0" xmax="3" ymin="0" ymax="3" zmin="9" zmax="18" />
<TetrahedronFEMForceField name="FEM" youngModulus="20000" poissonRatio="0.3" computeVonMisesStress="1" showVonMisesStressPerElement="true"/>
<UncoupledConstraintCorrection useOdeSolverIntegrationFactors="0"/>
</Node>
<Node name="M3">
<MechanicalObject name="mo"/>
<UniformMass totalMass="160" />
<RegularGridTopology nx="4" ny="4" nz="10" xmin="0" xmax="3" ymin="0" ymax="3" zmin="18" zmax="27" />
<BoxROI box="-0.1 -0.1 26.99 3.1 3.1 27.1" name="box"/>
<FixedProjectiveConstraint indices="@box.indices"/>
<TetrahedronFEMForceField name="FEM" youngModulus="4000" poissonRatio="0.3" computeVonMisesStress="1" showVonMisesStressPerElement="true"/>
<UncoupledConstraintCorrection useOdeSolverIntegrationFactors="0"/>
</Node>
<NearestPointROI template="Vec3" name="np1" object1="@./M1/mo" object2="@./M2/mo" radius="0.1"/>
<NearestPointROI template="Vec3" name="np2" object1="@./M2/mo" object2="@./M3/mo" radius="0.1"/>
<BilateralLagrangianConstraint template="Vec3" object1="@M1" object2="@M2" first_point="@np1.indices1" second_point="@np1.indices2" />
<BilateralLagrangianConstraint template="Vec3" object1="@M2" object2="@M3" first_point="@np2.indices1" second_point="@np2.indices2" />
</Node>
<!--
This Node shows how NearestPointROI is used to create SubsetMultiMapping and EdgeSetTopologyContainer.
-->
<Node name="Springs">
<EulerImplicitSolver name="cg_odesolver" rayleighStiffness="0.1" rayleighMass="0.1"/>
<CGLinearSolver iterations="25" name="linear solver" tolerance="1.0e-9" threshold="1.0e-9" />
<Node name="M1">
<MechanicalObject name="mo"/>
<UniformMass totalMass="160" />
<RegularGridTopology nx="4" ny="4" nz="10" xmin="4" xmax="7" ymin="0" ymax="3" zmin="0" zmax="9" />
<BoxROI box="3.9 -0.1 -0.1 7.1 3.1 0.1" name="box"/>
<FixedProjectiveConstraint indices="@box.indices"/>
<TetrahedronFEMForceField name="FEM" youngModulus="4000" poissonRatio="0.3" computeVonMisesStress="1" showVonMisesStressPerElement="true"/>
<UncoupledConstraintCorrection useOdeSolverIntegrationFactors="0"/>
</Node>
<Node name="M2"> <!-- This object has a higher resolution than the others -->
<MechanicalObject name="mo"/>
<UniformMass totalMass="160" />
<RegularGridTopology nx="8" ny="8" nz="20" xmin="4" xmax="7" ymin="0" ymax="3" zmin="9" zmax="18" />
<TetrahedronFEMForceField name="FEM" youngModulus="20000" poissonRatio="0.3" computeVonMisesStress="1" showVonMisesStressPerElement="true"/>
<UncoupledConstraintCorrection useOdeSolverIntegrationFactors="0"/>
</Node>
<Node name="M3">
<MechanicalObject name="mo"/>
<UniformMass totalMass="160" />
<RegularGridTopology nx="4" ny="4" nz="10" xmin="4" xmax="7" ymin="0" ymax="3" zmin="18" zmax="27" />
<BoxROI box="3.9 -0.1 26.99 7.1 3.1 27.1" name="box"/>
<FixedProjectiveConstraint indices="@box.indices"/>
<TetrahedronFEMForceField name="FEM" youngModulus="4000" poissonRatio="0.3" computeVonMisesStress="1" showVonMisesStressPerElement="true"/>
<UncoupledConstraintCorrection useOdeSolverIntegrationFactors="0"/>
</Node>
<!--
In the following Nodes, dofs from 2 mechanical objects are fused into a new mechanical object, based on the
minimal distance between points.
A mapping links the three objects. An edge topology is created.
Springs are created based on the topology.
-->
<Node name="merge1">
<BoxROI name="box1" position="@../M1/mo.position" box="3.9 -0.1 8.9 7.1 3.1 9.1"/>
<BoxROI name="box2" position="@../M2/mo.position" box="3.9 -0.1 8.9 7.1 3.1 9.1"/>
<NearestPointROI template="Vec3" name="np" object1="@../M1/mo" object2="@../M2/mo" radius="1e5" inputIndices1="@box1.indices" inputIndices2="@box2.indices"/>
<MechanicalObject name="dofs"/>
<SubsetMultiMapping input="@../M1/mo @../M2/mo" output="@dofs" indexPairs="@np.indexPairs"/>
<EdgeSetTopologyContainer edges="@np.edges"/>
<MeshSpringForceField stiffness="10000" damping="1" linesStiffness="10000" linesDamping="1" drawMode="1" drawSpringSize="1"/>
</Node>
<Node name="merge2">
<BoxROI name="box1" position="@../M2/mo.position" box="3.9 -0.1 17.9 7.1 3.1 18.1"/>
<BoxROI name="box2" position="@../M3/mo.position" box="3.9 -0.1 17.9 7.1 3.1 18.1"/>
<NearestPointROI template="Vec3" name="np" object1="@../M2/mo" object2="@../M3/mo" radius="1e5" inputIndices1="@box1.indices" inputIndices2="@box2.indices"/>
<MechanicalObject name="dofs"/>
<SubsetMultiMapping input="@../M2/mo @../M3/mo" output="@dofs" indexPairs="@np.indexPairs"/>
<EdgeSetTopologyContainer edges="@np.edges"/>
<MeshSpringForceField stiffness="10000" damping="1" linesStiffness="10000" linesDamping="1" drawMode="1" drawSpringSize="1"/>
</Node>
</Node>
</Node>
def createScene(root_node):
root = root_node.addChild('root', dt="0.02")
required_plugins = root.addChild('requiredPlugins')
required_plugins.addObject('RequiredPlugin', name="Sofa.Component.AnimationLoop")
required_plugins.addObject('RequiredPlugin', name="Sofa.Component.Constraint.Lagrangian.Correction")
required_plugins.addObject('RequiredPlugin', name="Sofa.Component.Constraint.Lagrangian.Model")
required_plugins.addObject('RequiredPlugin', name="Sofa.Component.Constraint.Lagrangian.Solver")
required_plugins.addObject('RequiredPlugin', name="Sofa.Component.Constraint.Projective")
required_plugins.addObject('RequiredPlugin', name="Sofa.Component.Engine.Select")
required_plugins.addObject('RequiredPlugin', name="Sofa.Component.LinearSolver.Iterative")
required_plugins.addObject('RequiredPlugin', name="Sofa.Component.Mapping.Linear")
required_plugins.addObject('RequiredPlugin', name="Sofa.Component.Mass")
required_plugins.addObject('RequiredPlugin', name="Sofa.Component.ODESolver.Backward")
required_plugins.addObject('RequiredPlugin', name="Sofa.Component.SolidMechanics.FEM.Elastic")
required_plugins.addObject('RequiredPlugin', name="Sofa.Component.SolidMechanics.Spring")
required_plugins.addObject('RequiredPlugin', name="Sofa.Component.StateContainer")
required_plugins.addObject('RequiredPlugin', name="Sofa.Component.Topology.Container.Dynamic")
required_plugins.addObject('RequiredPlugin', name="Sofa.Component.Topology.Container.Grid")
required_plugins.addObject('RequiredPlugin', name="Sofa.Component.Visual")
root.addObject('VisualStyle', displayFlags="showBehaviorModels showForceFields showInteractionForceFields")
root.addObject('FreeMotionAnimationLoop', parallelODESolving="true")
root.addObject('GenericConstraintSolver', tolerance="0.001", maxIterations="1000", resolutionMethod="UnbuildGaussSeidel", multithreading="true")
objects_attached_with_constraints = root.addChild('ObjectsAttachedWithConstraints')
objects_attached_with_constraints.addObject('EulerImplicitSolver', name="cg_odesolver", rayleighStiffness="0.1", rayleighMass="0.1")
objects_attached_with_constraints.addObject('CGLinearSolver', iterations="25", name="linear solver", tolerance="1.0e-9", threshold="1.0e-9")
m1 = ObjectsAttachedWithConstraints.addChild('M1')
m1.addObject('MechanicalObject', name="mo")
m1.addObject('UniformMass', totalMass="160")
m1.addObject('RegularGridTopology', nx="4", ny="4", nz="10", xmin="0", xmax="3", ymin="0", ymax="3", zmin="0", zmax="9")
m1.addObject('BoxROI', box="-0.1 -0.1 -0.1 3.1 3.1 0.1", name="box")
m1.addObject('FixedProjectiveConstraint', indices="@box.indices")
m1.addObject('TetrahedronFEMForceField', name="FEM", youngModulus="4000", poissonRatio="0.3", computeVonMisesStress="1", showVonMisesStressPerElement="true")
m1.addObject('UncoupledConstraintCorrection', useOdeSolverIntegrationFactors="0")
m2 = ObjectsAttachedWithConstraints.addChild('M2')
m2.addObject('MechanicalObject', name="mo")
m2.addObject('UniformMass', totalMass="160")
m2.addObject('RegularGridTopology', nx="4", ny="4", nz="10", xmin="0", xmax="3", ymin="0", ymax="3", zmin="9", zmax="18")
m2.addObject('TetrahedronFEMForceField', name="FEM", youngModulus="20000", poissonRatio="0.3", computeVonMisesStress="1", showVonMisesStressPerElement="true")
m2.addObject('UncoupledConstraintCorrection', useOdeSolverIntegrationFactors="0")
m3 = ObjectsAttachedWithConstraints.addChild('M3')
m3.addObject('MechanicalObject', name="mo")
m3.addObject('UniformMass', totalMass="160")
m3.addObject('RegularGridTopology', nx="4", ny="4", nz="10", xmin="0", xmax="3", ymin="0", ymax="3", zmin="18", zmax="27")
m3.addObject('BoxROI', box="-0.1 -0.1 26.99 3.1 3.1 27.1", name="box")
m3.addObject('FixedProjectiveConstraint', indices="@box.indices")
m3.addObject('TetrahedronFEMForceField', name="FEM", youngModulus="4000", poissonRatio="0.3", computeVonMisesStress="1", showVonMisesStressPerElement="true")
m3.addObject('UncoupledConstraintCorrection', useOdeSolverIntegrationFactors="0")
objects_attached_with_constraints.addObject('NearestPointROI', template="Vec3", name="np1", object1="@./M1/mo", object2="@./M2/mo", radius="0.1")
objects_attached_with_constraints.addObject('NearestPointROI', template="Vec3", name="np2", object1="@./M2/mo", object2="@./M3/mo", radius="0.1")
objects_attached_with_constraints.addObject('BilateralLagrangianConstraint', template="Vec3", object1="@M1", object2="@M2", first_point="@np1.indices1", second_point="@np1.indices2")
objects_attached_with_constraints.addObject('BilateralLagrangianConstraint', template="Vec3", object1="@M2", object2="@M3", first_point="@np2.indices1", second_point="@np2.indices2")
springs = root.addChild('Springs')
springs.addObject('EulerImplicitSolver', name="cg_odesolver", rayleighStiffness="0.1", rayleighMass="0.1")
springs.addObject('CGLinearSolver', iterations="25", name="linear solver", tolerance="1.0e-9", threshold="1.0e-9")
m1 = Springs.addChild('M1')
m1.addObject('MechanicalObject', name="mo")
m1.addObject('UniformMass', totalMass="160")
m1.addObject('RegularGridTopology', nx="4", ny="4", nz="10", xmin="4", xmax="7", ymin="0", ymax="3", zmin="0", zmax="9")
m1.addObject('BoxROI', box="3.9 -0.1 -0.1 7.1 3.1 0.1", name="box")
m1.addObject('FixedProjectiveConstraint', indices="@box.indices")
m1.addObject('TetrahedronFEMForceField', name="FEM", youngModulus="4000", poissonRatio="0.3", computeVonMisesStress="1", showVonMisesStressPerElement="true")
m1.addObject('UncoupledConstraintCorrection', useOdeSolverIntegrationFactors="0")
m2 = Springs.addChild('M2')
m2.addObject('MechanicalObject', name="mo")
m2.addObject('UniformMass', totalMass="160")
m2.addObject('RegularGridTopology', nx="8", ny="8", nz="20", xmin="4", xmax="7", ymin="0", ymax="3", zmin="9", zmax="18")
m2.addObject('TetrahedronFEMForceField', name="FEM", youngModulus="20000", poissonRatio="0.3", computeVonMisesStress="1", showVonMisesStressPerElement="true")
m2.addObject('UncoupledConstraintCorrection', useOdeSolverIntegrationFactors="0")
m3 = Springs.addChild('M3')
m3.addObject('MechanicalObject', name="mo")
m3.addObject('UniformMass', totalMass="160")
m3.addObject('RegularGridTopology', nx="4", ny="4", nz="10", xmin="4", xmax="7", ymin="0", ymax="3", zmin="18", zmax="27")
m3.addObject('BoxROI', box="3.9 -0.1 26.99 7.1 3.1 27.1", name="box")
m3.addObject('FixedProjectiveConstraint', indices="@box.indices")
m3.addObject('TetrahedronFEMForceField', name="FEM", youngModulus="4000", poissonRatio="0.3", computeVonMisesStress="1", showVonMisesStressPerElement="true")
m3.addObject('UncoupledConstraintCorrection', useOdeSolverIntegrationFactors="0")
merge1 = Springs.addChild('merge1')
merge1.addObject('BoxROI', name="box1", position="@../M1/mo.position", box="3.9 -0.1 8.9 7.1 3.1 9.1")
merge1.addObject('BoxROI', name="box2", position="@../M2/mo.position", box="3.9 -0.1 8.9 7.1 3.1 9.1")
merge1.addObject('NearestPointROI', template="Vec3", name="np", object1="@../M1/mo", object2="@../M2/mo", radius="1e5", inputIndices1="@box1.indices", inputIndices2="@box2.indices")
merge1.addObject('MechanicalObject', name="dofs")
merge1.addObject('SubsetMultiMapping', input="@../M1/mo @../M2/mo", output="@dofs", indexPairs="@np.indexPairs")
merge1.addObject('EdgeSetTopologyContainer', edges="@np.edges")
merge1.addObject('MeshSpringForceField', stiffness="10000", damping="1", linesStiffness="10000", linesDamping="1", drawMode="1", drawSpringSize="1")
merge2 = Springs.addChild('merge2')
merge2.addObject('BoxROI', name="box1", position="@../M2/mo.position", box="3.9 -0.1 17.9 7.1 3.1 18.1")
merge2.addObject('BoxROI', name="box2", position="@../M3/mo.position", box="3.9 -0.1 17.9 7.1 3.1 18.1")
merge2.addObject('NearestPointROI', template="Vec3", name="np", object1="@../M2/mo", object2="@../M3/mo", radius="1e5", inputIndices1="@box1.indices", inputIndices2="@box2.indices")
merge2.addObject('MechanicalObject', name="dofs")
merge2.addObject('SubsetMultiMapping', input="@../M2/mo @../M3/mo", output="@dofs", indexPairs="@np.indexPairs")
merge2.addObject('EdgeSetTopologyContainer', edges="@np.edges")
merge2.addObject('MeshSpringForceField', stiffness="10000", damping="1", linesStiffness="10000", linesDamping="1", drawMode="1", drawSpringSize="1")