Skip to content

Commit 88abe6e

Browse files
Merge pull request sofa-framework#277 from CRIStAL-PADR/pr-add-prefabparam-to-prefab
[Sofa.Prefab] Replace Sofa.Prefab "properties"
2 parents 9be1217 + 9badb90 commit 88abe6e

File tree

1 file changed

+50
-12
lines changed

1 file changed

+50
-12
lines changed

bindings/Sofa/package/prefab.py

Lines changed: 50 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,50 @@
11
import Sofa.Core
22
import inspect
33

4+
45
class Prefab(Sofa.Core.RawPrefab):
56
"""
6-
The Prefab object is a Base class to create custom Prefab components for SOFA, implemented in python.
7-
A Prefab can have parameters defined in the "properties" list (datafields under the group "Prefab's Properties"), that trigger its doReInit() function when modified. Parameters must be in a list of dictionaries containing the 3 required fields ("name", "type", "help") and one optional field ("default").
8-
When initializing a Prefab, if a prefab property name matches a keyword argument fed to the Prefab's initializer, the property will be added to the prefab as a SOFA data of the given type.
7+
Special Node to make reusable procedural objects in Sofa.
8+
---------------------------------------------------------
9+
10+
Inherit from this class to create your own Prefab. What makes Prefab special is that they
11+
have a set of special data named prefabParameters. When any of prefabParameter is changed the prefab
12+
is completely recreated by calling the onParameterChanged method so the scene graph is always kept synchronized
13+
with the parameter's content.
914
10-
Prefabs have protected keyword arguments:
11-
- name: the name of the prefab instance
12-
- parent and parents: can't be used together, they set the context of the prefab, thus allowing paths resolution for Prefab parameters whose arguments are passed as link paths (strings). parents (with an '-s') sets multi-node contexts
13-
- All other protected keyword arguments in SOFA components
15+
To specify the prefabParameters, it is possible to provide in the class a list of dictionaries containing the 3 required fields ("name", "type", "help")
16+
and one optional field ("default").
17+
18+
The same syntax can be used to also add prefab's data.
1419
1520
Example of use:
1621
.. code-block:: python
22+
1723
import Sofa.Core
1824
1925
class Foo(Sofa.Core.Prefab):
20-
properties = [{ 'name': 'n', 'type': 'int', 'help': 'number of times this prefab prints 'message', 'default': '1'},
21-
{'name': 'message', 'type': 'string', 'help': 'message to display n times', 'default': 'Hello World!'}]
26+
prefabParameters = [{ 'name': 'n', 'type': 'int', 'help': 'number of repetition, 'default': 1},
27+
{'name': 'message', 'type': 'string', 'help': 'message to display', 'default': ''}]
28+
29+
myAttribute = 0
2230
2331
def __init__(self, *a, *k):
2432
Sofa.Core.Prefab.__init__(self, *a, **k)
2533
26-
def doReInit(self):
34+
def init(self):
35+
myAttribute += 1
2736
for i in range(0, self.n.value):
2837
print(self.message.value)
2938
3039
n = Sofa.Core.Node()
3140
n.addChild(Foo(name="aFooPrefab", n=42, message="hello universe!"))
41+
42+
Prefab has protected the following additional keywords:
43+
- "name": the name of the prefab instance
44+
- "parent" and "parents": can't be used together, they set the context of the prefab,
45+
thus allowing paths resolution for Prefab parameters whose arguments are passed as link paths (strings). parents (with an '-s') sets multi-node contexts
46+
47+
3248
"""
3349
def __init__(self, *args, **kwargs):
3450
Sofa.Core.RawPrefab.__init__(self, *args, **kwargs)
@@ -71,14 +87,36 @@ def __init__(self, *args, **kwargs):
7187
if "parent" in kwargs and "parents" in kwargs:
7288
Sofa.Helper.msg_error(self, "Cannot use both 'parent' and 'parents' keywords on a prefab. Use 'parent' to set the context of your prefab, 'parents' in the case of a multi-parent prefab")
7389

74-
# Prefab parameters are defined in a list of dictionaries named "properties".
90+
# Prefab parameters are defined in a list of dictionaries named "prefabParameters".
7591
# The dictionaries has 3 required fields (name, type, help) and an additional optional field "default"
7692
docstring = ""
93+
94+
if hasattr(self, "prefabParameters"):
95+
docstring += "Prefab's parameters:"
96+
for p in self.prefabParameters:
97+
self.addPrefabParameter(name=p['name'],
98+
type=p['type'],
99+
help=p['help'],
100+
default=kwargs.get(p['name'], p.get('default', None)))
101+
docstring += "\n:param " + p['name'] + ": " + p['help'] + ", defaults to " + str(p.get('default', '')) + '\n:type ' + p['name'] + ": " + p['type'] + "\n\n"
102+
103+
if hasattr(self, "prefabData"):
104+
docstring += "Prefab's data:"
105+
for p in self.prefabData:
106+
self.addData(name=p['name'], type=p['type'], help=p['help'],
107+
value=kwargs.get(p['name'], p.get('default', None)),
108+
default=p['default'],
109+
group=p.get('group', 'Property'))
110+
docstring += "\n:param " + p['name'] + ": " + p['help'] + ", defaults to " + str(p.get('default', '')) + '\n:type ' + p['name'] + ": " + p['type'] + "\n\n"
111+
77112
if hasattr(self, "properties"):
78-
docstring += ""
113+
Sofa.Helper.msg_deprecated(self, "'properties' has been replaced with 'prefabParameters'. Please update your code.")
114+
docstring += "Prefab's (properties):"
79115
for p in self.properties:
80116
self.addPrefabParameter(name=p['name'], type=p['type'], help=p['help'], default=kwargs.get(p['name'], p.get('default', None)))
81117
docstring += "\n:param " + p['name'] + ": " + p['help'] + ", defaults to " + str(p.get('default', '')) + '\n:type ' + p['name'] + ": " + p['type'] + "\n\n"
82118

83119
self.addData("docstring", value=('' if self.__doc__ is None else self.__doc__) + docstring, type="string", group="Infos", help="Documentation of the prefab")
120+
121+
# calls the init() method in the prefab, then do node init & traversal.
84122
self.init()

0 commit comments

Comments
 (0)