Skip to content

Commit 5ff75c3

Browse files
committed
Added S, but still need to make the free motion not crash
1 parent 1cd8917 commit 5ff75c3

File tree

8 files changed

+123
-33
lines changed

8 files changed

+123
-33
lines changed

examples/stlib/SofaScene.py

Lines changed: 83 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,27 @@
11
from stlib.geometries.plane import PlaneParameters
2-
from stlib.collision import CollisionParameters
3-
from stlib.collision import Collision
4-
from stlib.visual import Visual
5-
from splib.core.enum_types import CollisionPrimitive
6-
from splib.simulation.headers import setupLagrangianCollision
2+
from stlib.geometries.file import FileParameters
3+
from stlib.geometries.extract import ExtractParameters
4+
from stlib.materials.deformable import DeformableBehaviorParameters
5+
from stlib.collision import Collision, CollisionParameters
6+
from stlib.entities import Entity, EntityParameters
7+
from stlib.visual import Visual, VisualParameters
8+
from splib.core.enum_types import CollisionPrimitive, ElementType, ConstitutiveLaw
9+
from splib.simulation.headers import setupLagrangianCollision, setupDefaultHeader
10+
from splib.simulation.ode_solvers import addImplicitODE
11+
from splib.simulation.linear_solvers import addLinearSolver
712
import dataclasses
813
import numpy as np
914

1015

1116

1217
def createScene(root):
18+
root.gravity=[0,0,9.81]
1319
##Solvers
14-
setupLagrangianCollision(root, displayFlags = "showVisualModels",backgroundColor=[0.8, 0.8, 0.8, 1],
15-
parallelComputing = True,alarmDistance=0.3, contactDistance=0.02,
16-
frictionCoef=0.5, tolerance=1.0e-4, maxIterations=20)
20+
setupDefaultHeader(root, displayFlags = "showVisualModels",backgroundColor=[0.8, 0.8, 0.8, 1],
21+
parallelComputing = True)
22+
# setupLagrangianCollision(root, displayFlags = "showVisualModels",backgroundColor=[0.8, 0.8, 0.8, 1],
23+
# parallelComputing = True,alarmDistance=0.3, contactDistance=0.02,
24+
# frictionCoef=0.5, tolerance=1.0e-4, maxIterations=20)
1725

1826
##Environement
1927
planes_lengthNormal = np.array([0, 1, 0])
@@ -29,7 +37,8 @@ def createScene(root):
2937
plane1_collisionParams.geometry = PlaneParameters(np.array([15,0,1]), np.array([0,0,-1]),
3038
planes_lengthNormal, planes_lengthNbEdge, planes_widthNbEdge, planes_lengthSize, planes_widthSize)
3139
plane1 = root.add(Collision, parameters = plane1_collisionParams)
32-
#TODO being able to reuse already loaded geometry of current prefab to add any new sub prefab
40+
# TODO being able to reuse already loaded geometry of current prefab to add any new sub prefab
41+
# We need to enable to directly pass a link to an already existing prefab in place of a prefab parameter object
3342
plane1_visu = plane1.addChild("Visu")
3443
plane1_visu.addObject("OglModel", name="VisualModel", src="@../Geometry/container")
3544

@@ -46,3 +55,68 @@ def createScene(root):
4655

4756

4857
## Real models
58+
Beam = root.addChild("Beam")
59+
60+
VolumetricObjects = root.addChild("VolumetricObjects")
61+
addImplicitODE(VolumetricObjects)
62+
addLinearSolver(VolumetricObjects, constantSparsity=True)
63+
64+
### Logo
65+
LogoParams = EntityParameters()
66+
LogoParams.name = "Logo"
67+
LogoParams.geometry = FileParameters(filename="mesh/SofaScene/Logo.vtk")
68+
LogoParams.geometry.elementType = ElementType.TETRAHEDRA
69+
LogoParams.material = DeformableBehaviorParameters()
70+
LogoParams.material.constitutiveLawType = ConstitutiveLaw.ELASTIC
71+
LogoParams.material.parameters = [200, 0.4]
72+
73+
def logoAddMaterial(node):
74+
DeformableBehaviorParameters.addDeformableMaterial(node)
75+
node.addObject("ConstantForceField", name="ConstantForceUpwards", totalForce=[0, 0, -5.0])
76+
#TODO deal with that is a more smooth way in the material directly
77+
node.addObject("LinearSolverConstraintCorrection", name="ConstraintCorrection", linearSolver=VolumetricObjects.LinearSolver.linkpath, ODESolver=VolumetricObjects.ODESolver.linkpath)
78+
79+
80+
LogoParams.material.addMaterial = logoAddMaterial
81+
LogoParams.material.massDensity = 0.003261
82+
LogoParams.collision = CollisionParameters()
83+
LogoParams.collision.primitives = [CollisionPrimitive.SPHERES]
84+
LogoParams.collision.geometry = FileParameters(filename="mesh/SofaScene/LogoColli.sph")
85+
#TODO make this flawless with spheres. Here collisions elements are not in the topology and a link is to be made between the loader and the collision object
86+
LogoParams.collision.kwargs = {"SphereCollision" : {"radius" : "@Geometry/loader.listRadius"}}
87+
LogoParams.visual = VisualParameters()
88+
LogoParams.visual.geometry = FileParameters(filename="mesh/SofaScene/LogoVisu.obj")
89+
LogoParams.visual.color = [0.7, .35, 0, 0.8]
90+
91+
Logo = VolumetricObjects.add(Entity, parameters = LogoParams)
92+
93+
### S
94+
SParams = EntityParameters()
95+
SParams.name = "S"
96+
SParams.geometry = FileParameters(filename="mesh/SofaScene/S.vtk")
97+
SParams.geometry.elementType = ElementType.TETRAHEDRA
98+
SParams.material = DeformableBehaviorParameters()
99+
SParams.material.constitutiveLawType = ConstitutiveLaw.ELASTIC
100+
SParams.material.parameters = [200, 0.45]
101+
102+
def SAddMaterial(node):
103+
DeformableBehaviorParameters.addDeformableMaterial(node)
104+
#TODO deal with that is a more smooth way in the material directly
105+
node.addObject("LinearSolverConstraintCorrection", name="ConstraintCorrection", linearSolver=VolumetricObjects.LinearSolver.linkpath, ODESolver=VolumetricObjects.ODESolver.linkpath)
106+
107+
SParams.material.addMaterial = SAddMaterial
108+
SParams.material.massDensity = 0.011021
109+
SParams.collision = CollisionParameters()
110+
SParams.collision.primitives = [CollisionPrimitive.TRIANGLES]
111+
# #TODO: to fix link issues for extracted geometry, it might be better to give source geometry relative link + parameters
112+
SParams.collision.geometry = ExtractParameters(destinationType=ElementType.TRIANGLES, sourceParameters=SParams.geometry )
113+
SParams.visual = VisualParameters()
114+
SParams.visual.geometry = FileParameters(filename="mesh/SofaScene/SVisu.obj")
115+
SParams.visual.color = [0.7, .7, 0.7, 0.8]
116+
117+
S = VolumetricObjects.add(Entity, parameters = SParams)
118+
119+
120+
SDensity = 0.011021
121+
ODensity = SDensity
122+
ADensity = 0.00693695

splib/core/node_wrapper.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,9 @@ def addObject(self,*args, **kwargs):
2525
parameters["name"] = kwargs["name"]
2626
if kwargs["name"] in kwargs:
2727
if isinstance(kwargs[kwargs["name"]], dict):
28-
parameters = {**parameters, **kwargs[kwargs["name"]]}
28+
for param in kwargs[kwargs["name"]]:
29+
if not(isinstance(kwargs[kwargs["name"]][param],defaultValueType)):
30+
parameters = {**parameters, param : kwargs[kwargs["name"]][param]}
2931
else:
3032
print("[Warning] You are passing a keyword arg with the same name as one obj without it being a Dict, it will not be used. ")
3133

splib/mechanics/collision_model.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ def addCollisionModels(node, primitive : CollisionPrimitive,
2424
node.addObject("TriangleCollisionModel", name="TriangleCollision", topology=topology, selfCollision=selfCollision, proximity=proximity, contactStiffness=contactStiffness, contactFriction=contactFriction, group=group,**kwargs)
2525
return
2626
case CollisionPrimitive.SPHERES:
27-
node.addObject("SphereCollisionModel", name="SphereCollision", topology=topology, selfCollision=selfCollision, proximity=proximity, contactStiffness=contactStiffness, contactFriction=contactFriction, group=group, radius=spheresRadius, **kwargs)
27+
node.addObject("SphereCollisionModel", name="SphereCollision", selfCollision=selfCollision, proximity=proximity, contactStiffness=contactStiffness, contactFriction=contactFriction, group=group, radius=spheresRadius, **kwargs)
2828
return
2929
case _:
3030
return

stlib/entities/__entity__.py

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -65,16 +65,17 @@ def init(self):
6565
def addMapping(self, destinationPrefab):
6666

6767
template = f'{self.parameters.stateType},Vec3' # TODO: check that it is always true
68-
68+
69+
#TODO: all paths are expecting Geometry to be called Geomtry and so on. We need to robustify this by using the name parameter somehow
6970
if( self.parameters.stateType == StateType.VEC3):
7071
destinationPrefab.addObject("BarycentricMapping",
7172
output=destinationPrefab.linkpath,
72-
output_topology=destinationPrefab.geometry.container.linkpath,
73-
input=self.material.linkpath,
74-
input_topology=self.geometry.container.linkpath,
73+
output_topology=destinationPrefab.Geometry.container.linkpath,
74+
input=self.Material.linkpath,
75+
input_topology=self.Geometry.container.linkpath,
7576
template=template)
7677
else:
7778
destinationPrefab.addObject("RigidMapping",
7879
output=destinationPrefab.linkpath,
79-
input=self.material.linkpath,
80+
input=self.Material.linkpath,
8081
template=template)

stlib/geometries/__geometry__.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,9 +56,17 @@ def init(self):
5656
# Generate attribute (positions, edges, triangles, quads, tetrahedra, hexahedra) from the internal data provider
5757
if isinstance(self.parameters.data, InternalDataProvider) :
5858
self.parameters.data.generateAttribute(self)
59+
5960
if self.parameters.dynamicTopology :
6061
if self.parameters.elementType is not None :
61-
addDynamicTopology(self, container = dataclasses.asdict(self.parameters.data))
62+
addDynamicTopology(self, elementType=self.parameters.elementType, container = {
63+
"position": self.parameters.data.position,
64+
"edges": self.parameters.data.edges,
65+
"triangles": self.parameters.data.triangles,
66+
"quads": self.parameters.data.quads,
67+
"tetrahedra": self.parameters.data.tetrahedra,
68+
"hexahedra": self.parameters.data.hexahedra
69+
})
6270
else:
6371
raise ValueError
6472
else:

stlib/geometries/extract.py

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ def __post_init__(self):
2525

2626
InternalDataProvider.__init__(self)
2727

28-
def generateAttribute(self, parent : Geometry):
28+
def generateAttribute(self, parent : Geometry):
2929
node = parent.addChild("ExtractedGeometry")
3030

3131
#TODO: Specify somewhere in the doc that this should only be used for mapped topologies that extract parent topology surface
@@ -34,8 +34,8 @@ def generateAttribute(self, parent : Geometry):
3434
# !!! also, on a fail, nothing is added to the graph, which makes things harder to debug
3535
# !!! also, does not work because of the function canCreate(), which checks the input (not yet created?)
3636
# this is all related
37-
fromLink = "@../../Geometry.container" # TODO: can we do better than this?
38-
addDynamicTopology(node, elementType=self.sourceType)
37+
fromLink = "@../../../Geometry/container" # TODO: can we do better than this?
38+
addDynamicTopology(node, elementType=self.destinationType)
3939
if self.sourceType == ElementType.TETRAHEDRA:
4040
node.addObject("Tetra2TriangleTopologicalMapping", input=fromLink, output=node.container.linkpath)
4141
elif self.sourceType == ElementType.HEXAHEDRA:
@@ -60,12 +60,11 @@ def generateAttribute(self, parent : Geometry):
6060
class ExtractParameters(GeometryParameters):
6161
def __init__(self,
6262
sourceParameters : GeometryParameters,
63-
destinationType : ElementType,
64-
dynamicTopology : bool = False, ):
63+
destinationType : ElementType,):
6564
GeometryParameters.__init__(self,
6665
data = ExtractInternalDataProvider(destinationType = destinationType,
6766
sourceType = sourceParameters.elementType,
6867
sourceName = sourceParameters.name),
69-
dynamicTopology = dynamicTopology,
68+
dynamicTopology = True,
7069
elementType = destinationType)
7170

stlib/geometries/file.py

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,20 @@ def __post_init__(self, **kwargs):
1313
InternalDataProvider.__init__(self,**kwargs)
1414

1515
def generateAttribute(self, parent : Geometry):
16-
loadMesh(parent, self.filename)
17-
18-
self.position = str(parent.loader.position.linkpath)
19-
self.edges = str(parent.loader.edges.linkpath)
20-
self.triangles = str(parent.loader.triangles.linkpath)
21-
self.quads = str(parent.loader.quads.linkpath)
22-
self.hexahedra = str(parent.loader.hexahedra.linkpath)
23-
self.tetrahedra = str(parent.loader.tetras.linkpath)
16+
loadMesh(parent, self.filename)
17+
18+
if hasattr(parent.loader, 'position'):
19+
self.position = str(parent.loader.position.linkpath)
20+
if hasattr(parent.loader, 'edges'):
21+
self.edges = str(parent.loader.edges.linkpath)
22+
if hasattr(parent.loader, 'triangles'):
23+
self.triangles = str(parent.loader.triangles.linkpath)
24+
if hasattr(parent.loader, 'quads'):
25+
self.quads = str(parent.loader.quads.linkpath)
26+
if hasattr(parent.loader, 'hexahedra'):
27+
self.hexahedra = str(parent.loader.hexahedra.linkpath)
28+
if hasattr(parent.loader, 'tetrahedra'):
29+
self.tetrahedra = str(parent.loader.tetrahedra.linkpath)
2430

2531

2632

stlib/materials/deformable.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ class DeformableBehaviorParameters(MaterialParameters):
1313
elementType : ElementType = ElementType.TETRAHEDRA
1414
parameters : list[float] = dataclasses.field(default_factory=lambda: [1000, 0.45]) # young modulus, poisson ratio
1515

16-
def __addDeformableMaterial(node):
16+
def addDeformableMaterial(node):
1717

1818
massKwargs = {}
1919
if node.parameters.elementType != ElementType.EDGES: #If we use the MeshMatrixMass, then the mass will need us to specify the mstate to use
@@ -26,7 +26,7 @@ def __addDeformableMaterial(node):
2626
else:
2727
addLinearElasticity(node, node.parameters.elementType, node.parameters.parameters[0], node.parameters.parameters[1], topology="@../Geometry/container")
2828

29-
addMaterial : Optional[Callable] = __addDeformableMaterial
29+
addMaterial : Optional[Callable] = addDeformableMaterial
3030

3131

3232
def createScene(root) :

0 commit comments

Comments
 (0)