Skip to content

Commit 4baad13

Browse files
committed
Add Sofa.Core.Node.add with preliminary test
1 parent 6730c85 commit 4baad13

File tree

3 files changed

+118
-27
lines changed

3 files changed

+118
-27
lines changed

stlib/__init__.py

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,55 @@
11
__all__ = ["core","entities","prefabs","shapes"]
2+
3+
import Sofa.Core
4+
def addFromTypeName(self : Sofa.Core.Node, typeName, **kwargs):
5+
def findName(cname, names):
6+
"""Compute a working unique name in the node"""
7+
rname = cname
8+
for i in range(0, len(names)):
9+
if rname not in names:
10+
return rname
11+
rname = cname + str(i+1)
12+
return rname
13+
14+
params = kwargs.copy()
15+
isNode = False
16+
if "name" not in params:
17+
if isinstance(typeName, str):
18+
params["name"] = typeName
19+
isNode=True
20+
elif isinstance(typeName, type) and issubclass(typeName, Sofa.Core.Node):
21+
params["name"] = "Node"
22+
isNode=True
23+
elif isinstance(typeName, Sofa.Core.Node):
24+
params["name"] = "Node"
25+
isNode=True
26+
elif isinstance(typeName, type) and issubclass(typeName, Sofa.Core.Object):
27+
params["name"] = typeName.name.value
28+
elif isinstance(typeName, type) and issubclass(typeName, Sofa.Core.ObjectDeclaration):
29+
params["name"] = typeName.__name__
30+
else:
31+
raise RuntimeError("Invalid argument ", typeName)
32+
33+
if params["name"] in self.children or params["name"] in self.objects:
34+
names = {node.name.value for node in self.children}
35+
names = names.union({object.name.value for object in self.objects})
36+
params["name"] = findName(params["name"], names)
37+
38+
if isinstance(typeName, type) and issubclass(typeName, Sofa.Core.Node):
39+
pref = self.addChild(typeName(params["name"]))
40+
pref.init()
41+
elif isinstance(typeName, Sofa.Core.Node):
42+
pref = self.addChild(typeName)
43+
pref.init()
44+
elif isinstance(typeName, type) and issubclass(typeName, Sofa.Core.Object):
45+
pref = self.addObject(typeName(**params))
46+
elif isinstance(typeName, type) and issubclass(typeName, Sofa.Core.ObjectDeclaration):
47+
pref = self.addObject(typeName.__name__, **params)
48+
elif isinstance(typeName, str):
49+
pref = self.addObject(typeName, **params)
50+
else:
51+
raise RuntimeError("Invalid argument", typeName)
52+
return pref
53+
54+
# Inject the method so it become available as if it was part of Sofa.Core.Node
55+
Sofa.Core.Node.add = addFromTypeName

stlib/core/basePrefab.py

Lines changed: 0 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -3,33 +3,6 @@
33
import Sofa.Core
44
from stlib.core.basePrefabParameters import BasePrefabParameters
55

6-
7-
def addFromTypeName(self : Sofa.Core.Node, typeName, params = BasePrefabParameters, **kwargs):
8-
def findName(cname, node):
9-
"""Compute a working unique name in the node"""
10-
rname = cname
11-
for i in range(0, len(node.children)):
12-
if rname not in node.children:
13-
return rname
14-
rname = cname + str(i+1)
15-
return rname
16-
17-
for k,v in kwargs.items():
18-
if hasattr(params, k):
19-
setattr(params, k, v)
20-
21-
params = copy.copy(params)
22-
if params.name in self.children:
23-
params.name = findName(params.name, self)
24-
25-
pref = self.addChild(typeName(params))
26-
pref.init()
27-
28-
return pref
29-
30-
Sofa.Core.Node.add = addFromTypeName
31-
32-
336
class BasePrefab(Sofa.Core.Node):
347
"""
358
A Prefab is a Sofa.Node that assembles a set of components and nodes

tests/test_new_add.py

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
import unittest
2+
import Sofa
3+
import SofaRuntime
4+
import Sofa.Core
5+
import stlib
6+
7+
class ObjectDeclaration(object):
8+
...
9+
10+
Sofa.Core.ObjectDeclaration = ObjectDeclaration
11+
12+
class MechanicalObject(ObjectDeclaration):
13+
pass
14+
15+
class TestNewAdd(unittest.TestCase):
16+
def test_add_node_with_node_type(self):
17+
root = Sofa.Core.Node("root")
18+
root.add(Sofa.Core.Node, name="aNodeA")
19+
self.assertEqual(len(root.children), 1)
20+
self.assertEqual(root.children[0].name.value, "aNodeA")
21+
22+
def test_add_node_with_node_instance(self):
23+
root = Sofa.Core.Node("root")
24+
root.add(Sofa.Core.Node("aNodeB"))
25+
self.assertEqual(len(root.children), 1)
26+
self.assertEqual(root.children[0].name.value, "aNodeB")
27+
28+
def test_add_object_with_string_type(self):
29+
root = Sofa.Core.Node("root")
30+
root.add("MechanicalObject", name="anObject1", position=[[1,2,3]])
31+
self.assertEqual(len(root.objects), 1)
32+
self.assertEqual(root.objects[0].name.value, "anObject1")
33+
self.assertEqual(root.objects[0].position.value.shape, (1,3))
34+
35+
def test_add_object_with_object_type(self):
36+
root = Sofa.Core.Node("root")
37+
root.add(MechanicalObject, name="anObject2", position=[[1,2,3]])
38+
self.assertEqual(len(root.objects), 1)
39+
self.assertEqual(root.objects[0].name.value, "anObject2")
40+
self.assertEqual(root.objects[0].position.value.shape, (1,3))
41+
42+
def test_automatic_name_generation(self):
43+
root = Sofa.Core.Node("root")
44+
root.add(MechanicalObject, position=[[1,2,3]])
45+
root.add(MechanicalObject, position=[[1,2,3]])
46+
root.add(MechanicalObject, position=[[1,2,3]])
47+
self.assertEqual(root.objects[0].name.value, "MechanicalObject")
48+
self.assertEqual(root.objects[1].name.value, "MechanicalObject1")
49+
self.assertEqual(root.objects[2].name.value, "MechanicalObject2")
50+
51+
root.add(Sofa.Core.Node, name="TestNode")
52+
root.add(Sofa.Core.Node, name="TestNode")
53+
self.assertEqual(root.children[0].name.value, "TestNode")
54+
self.assertEqual(root.children[1].name.value, "TestNode1")
55+
56+
root.add(Sofa.Core.Node)
57+
root.add(Sofa.Core.Node)
58+
self.assertEqual(root.children[2].name.value, "Node")
59+
self.assertEqual(root.children[3].name.value, "Node1")
60+
61+
if __name__ == '__main__':
62+
63+
SofaRuntime.importPlugin("Sofa.Component.StateContainer")
64+
unittest.main()

0 commit comments

Comments
 (0)