Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions stlib/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -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):
Expand Down
4 changes: 3 additions & 1 deletion stlib/core/basePrefab.py
Original file line number Diff line number Diff line change
Expand Up @@ -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 :)")
Expand Down
11 changes: 9 additions & 2 deletions stlib/geometries/__geometry__.py
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -35,6 +35,9 @@ class GeometryParameters(BaseParameters):

dynamicTopology : bool = False

def postInit(self, node):
pass

def Data(self):
return InternalDataProvider()

Expand Down Expand Up @@ -79,4 +82,8 @@ def init(self):
"quads": self.parameters.data.quads,
"tetrahedra": self.parameters.data.tetrahedra,
"hexahedra": self.parameters.data.hexahedra
})
})


def postInit(self):
self.parameters.postInit(self)
80 changes: 31 additions & 49 deletions stlib/geometries/extract.py
Original file line number Diff line number Diff line change
Expand Up @@ -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'")

Loading