Skip to content

Change the Prefab's parameters and implemention to make it usage clear. #267

Closed
damienmarchal wants to merge 2 commits intosofa-framework:masterfrom
CRIStAL-PADR:pr-improve-prefab
Closed

Change the Prefab's parameters and implemention to make it usage clear. #267
damienmarchal wants to merge 2 commits intosofa-framework:masterfrom
CRIStAL-PADR:pr-improve-prefab

Conversation

@damienmarchal
Copy link
Contributor

@damienmarchal damienmarchal commented Jun 10, 2022

The Prefab implementation in SofaPython3 is experimental code that has never been validated, a too complexe API and is not event fully working.

This PR fix all that and includes a basic test and a first example to demonstrate the use of Sofa.Prefab.

The general idea is that a Sofa.Prefab is a Node with extra feature to deal in a systematic way how its content change when some of its parameters changes.

Comment on lines 1 to 24
import Sofa

class MyPrefab(Sofa.Prefab):
prefabParameters = [
{"name" : "n",
"type" : "int",
"help" : "Rien"}
]

prefabData = [
{"name" : "angle", "type" : "double", "help" : "The angular velocity of the motor", "default" : 3.14151617}
]

def __init__(self, *args, **kwargs):
Sofa.Prefab.__init__(self, *args, **kwargs)

def onParameterChanged(self):
print("UPDATE...",self.n.value)
for i in range(self.n.value):
self.addChild("Child"+str(i))

def createScene(root):
root.addChild("Child1")
root.addChild(MyPrefab(name="toto", n=5)) No newline at end of file
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would clean this example a little bit. Like this for instance:

import Sofa

class MyPrefab(Sofa.Prefab):
    prefabParameters = [
        {"name" : "myParameter", "type" : "int", "help" : "my message to help the user", "default" : 0}
    ]  
    # These are special parameters, when any of them are changed the prefab is completely recreated by calling the method onParameterChanged(). 
    # So the scene graph is always kept synchronized with these parameters content.

    prefabData = [
        {"name" : "myData", "type" : "double", "help" : "my message to help the user", "default" : 0.0}
    ]  

    def __init__(self, *args, **kwargs):
        Sofa.Prefab.__init__(self, *args, **kwargs)

    def onParameterChanged(self):
        print("Called when any of the prefabParameters changed: ", self.myParameter.value)
        for i in range(self.myParameter.value):
            self.addChild("Child"+str(i))

def createScene(root):
    root.addChild("MyPrefab1")
    root.addChild(MyPrefab(name="MyPrefab2", myParameter=5))

Copy link
Contributor Author

@damienmarchal damienmarchal Jun 14, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Arg @EulalieCoevoet you rise me a furious envy to continue this work.
So now the onParameterChanged can be either use that way but also to forward to the init()

import Sofa

class MyPrefab(Sofa.Prefab):
    prefabParameters = [
        {"name" : "myParameter", "type" : "int", "help" : "my message to help the user", "default" : 0}
    ]  
    # These are special parameters, when any of them are changed the prefab is completely recreated by calling the method onParameterChanged(). 
    # So the scene graph is always kept synchronized with these parameters content.

    prefabData = [
        {"name" : "myData", "type" : "double", "help" : "my message to help the user", "default" : 0.0}
    ]  

    def __init__(self, *args, **kwargs):
        Sofa.Prefab.__init__(self, *args, **kwargs)

    def init(self):
        print("Build the prefab with: ", self.myParameter.value)
        for i in range(self.myParameter.value):
            self.addChild("Child"+str(i))
            
    #uncomment this to restrict/disable is update of the prefab on each parameter change 
    #def onParameterChanged(self):
    #    if self.myParameter.value > 2:
    #         self.init()                   
        
def createScene(root):
    root.addChild("MyPrefab1")
    root.addChild(MyPrefab(name="MyPrefab2", myParameter=5))

@damienmarchal damienmarchal force-pushed the pr-improve-prefab branch 3 times, most recently from c6ba6c5 to a6d696e Compare June 14, 2022 23:37
@damienmarchal damienmarchal changed the title Change the Prefab's parameters to make their usage clear. Change the Prefab's parameters and implemention to make it usage clear. Jun 15, 2022
if(!findData(name) && !findLink(name))
{
sofa::core::objectmodel::BaseData* data = sofapython3::addData(py::cast(this), name, py::none(), defaultValue, help, "Prefab's properties", type);
sofa::core::objectmodel::BaseData* data = sofapython3::addData(py::cast(this), name, py::none(), defaultValue, help, "Prefab's parameters", type);
Copy link
Contributor

@EulalieCoevoet EulalieCoevoet Jun 15, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ligne 114 should be "Prefab's parameters" too, right?

@EulalieCoevoet
Copy link
Contributor

EulalieCoevoet commented Jun 15, 2022

I've tried this branch with the Tripod tutorial's update from SofaDefrost/SoftRobots#151.
For instance with s90servo.py, I'm still getting a different behavior if we fill the node with the components in the method init() instead of __init__(). By different behavior I mean, warnings and errors which feel like the node is being initialized twice.

@damienmarchal
Copy link
Contributor Author

This Branch was used to make the #277

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants