diff --git a/stlib/__init__.py b/stlib/__init__.py index 0ad659858..c6eb6d67a 100644 --- a/stlib/__init__.py +++ b/stlib/__init__.py @@ -52,6 +52,7 @@ def checkName(context : Sofa.Core.Node, name): if isinstance(typeName, type) and issubclass(typeName, BasePrefab): pref = self.addChild(typeName(**params)) pref.init() + pref.postInit() elif isinstance(typeName, Sofa.Core.Node): pref = self.addChild(typeName(**params)) elif isinstance(typeName, type) and issubclass(typeName, Sofa.Core.Object): diff --git a/stlib/core/basePrefab.py b/stlib/core/basePrefab.py index 83d29f55d..94b4772b4 100644 --- a/stlib/core/basePrefab.py +++ b/stlib/core/basePrefab.py @@ -14,7 +14,9 @@ def __init__(self, parameters: BasePrefabParameters): def init(self): raise NotImplemented("To be overridden by child class") - + + def postInit(self): + pass def localToGlobalCoordinates(pointCloudInput, pointCloudOutput): raise NotImplemented("Send an email to Damien, he will help you. Guaranteed :)") diff --git a/stlib/geometries/__geometry__.py b/stlib/geometries/__geometry__.py index 57d0e5c76..5355c009c 100644 --- a/stlib/geometries/__geometry__.py +++ b/stlib/geometries/__geometry__.py @@ -1,5 +1,5 @@ from stlib.core.basePrefab import BasePrefab -from stlib.core.baseParameters import BaseParameters, Optional, dataclasses, Any +from stlib.core.baseParameters import BaseParameters, Optional, dataclasses, Any, Callable from splib.topology.dynamic import addDynamicTopology from splib.topology.static import addStaticTopology from splib.core.enum_types import ElementType @@ -35,6 +35,9 @@ class GeometryParameters(BaseParameters): dynamicTopology : bool = False + def postInit(self, node): + pass + def Data(self): return InternalDataProvider() @@ -79,4 +82,8 @@ def init(self): "quads": self.parameters.data.quads, "tetrahedra": self.parameters.data.tetrahedra, "hexahedra": self.parameters.data.hexahedra - }) \ No newline at end of file + }) + + + def postInit(self): + self.parameters.postInit(self) diff --git a/stlib/geometries/extract.py b/stlib/geometries/extract.py index 5ee1b3762..138c0e7e7 100644 --- a/stlib/geometries/extract.py +++ b/stlib/geometries/extract.py @@ -6,66 +6,48 @@ import Sofa from Sofa.Core import Node +from functools import partial class ExtractInternalDataProvider(InternalDataProvider): - destinationType : ElementType - sourceType : ElementType - sourceName : str - def __init__(self, destinationType : ElementType, sourceType : ElementType, sourceName : str): - self.destinationType = destinationType - self.sourceType = sourceType - self.sourceName = sourceName - - def __post_init__(self): - if(not (self.sourceType == ElementType.TETRAHEDRA and self.destinationType == ElementType.TRIANGLES) - and not (self.sourceType == ElementType.HEXAHEDRA and self.destinationType == ElementType.QUADS) ): - raise ValueError("Only configuration possible are 'Tetrahedra to Triangles' and 'Hexahedra to Quads'") - - InternalDataProvider.__init__(self) + def __init__(self): + super().__init__() def generateAttribute(self, parent : Geometry): - node = parent.addChild("ExtractedGeometry") + self.position = parent.parents[0].parents[0].getChild("Geometry").container.position.linkpath + - #TODO: Specify somewhere in the doc that this should only be used for mapped topologies that extract parent topology surface - # fromLink = parent.parents[0].parents[0].getChild(self.SourceName).container.linkpath - # TODO: the line above cannot work if the nodes and objects are not added to the graph prior the end of __init__() call - # !!! also, on a fail, nothing is added to the graph, which makes things harder to debug - # !!! also, does not work because of the function canCreate(), which checks the input (not yet created?) - # this is all related - fromLink = "@../../../Geometry/container" # TODO: can we do better than this? - addDynamicTopology(node, elementType=self.destinationType, container={"position" : fromLink + ".position"}) - if self.sourceType == ElementType.TETRAHEDRA: - node.addObject("Tetra2TriangleTopologicalMapping", input=fromLink, output=node.container.linkpath) - elif self.sourceType == ElementType.HEXAHEDRA: - node.addObject("Hexa2QuadTopologicalMapping", input=fromLink, output=node.container.linkpath) - else: - Sofa.msg_error("[stlib/geometry/exctrat.py]", "Element type: " + str(self.sourceType) + " not supported.") +def extractGeometry(sourceType : ElementType, parent : Geometry): + #TODO: Specify somewhere in the doc that this should only be used for mapped topologies that extract parent topology surface + # fromLink = parent.parents[0].parents[0].getChild(self.SourceName).container.linkpath + # TODO: the line above cannot work if the nodes and objects are not added to the graph prior the end of __init__() call + # !!! also, on a fail, nothing is added to the graph, which makes things harder to debug + # !!! also, does not work because of the function canCreate(), which checks the input (not yet created?) + # this is all related + fromLink = parent.parents[0].parents[0].getChild("Geometry").container.linkpath # TODO: can we do better than this? + if sourceType == ElementType.TETRAHEDRA: + parent.addObject("Tetra2TriangleTopologicalMapping", input=fromLink, output=parent.container.linkpath) + elif sourceType == ElementType.HEXAHEDRA: + parent.addObject("Hexa2QuadTopologicalMapping", input=fromLink, output=parent.container.linkpath) + else: + Sofa.msg_error("[stlib/geometry/exctrat.py]", "Element type: " + str(sourceType) + " not supported.") - self.position = node.container.position.linkpath - if node.container.findData("edges") is not None: - self.edges = node.container.edges.linkpath - if node.container.findData("triangles") is not None: - self.triangles = node.container.triangles.linkpath - if node.container.findData("quads") is not None: - self.quads = node.container.quads.linkpath - if node.container.findData("hexahedra") is not None: - self.hexahedra = node.container.hexahedra.linkpath - if node.container.findData("tetras") is not None: - self.tetrahedra = node.container.tetras.linkpath class ExtractParameters(GeometryParameters): - def __init__(self, - sourceParameters : GeometryParameters, - destinationType : ElementType, - dynamicTopology : bool = False): + def __init__(self, + sourceParameters : GeometryParameters, + destinationType : ElementType): GeometryParameters.__init__(self, - data = ExtractInternalDataProvider(destinationType = destinationType, - sourceType = sourceParameters.elementType, - sourceName = sourceParameters.name), - dynamicTopology = dynamicTopology, + data = ExtractInternalDataProvider(), + dynamicTopology = True, elementType = destinationType) - + + self.postInit = partial(extractGeometry, sourceParameters.elementType) + + if(not (sourceParameters.elementType == ElementType.TETRAHEDRA and destinationType == ElementType.TRIANGLES) + and not (sourceParameters.elementType == ElementType.HEXAHEDRA and destinationType == ElementType.QUADS) ): + raise ValueError("Only configuration possible are 'Tetrahedra to Triangles' and 'Hexahedra to Quads'") +