Home › Forum › SOFA › Using SOFA › How to VTKexport PointSetTopologyContainer points
- This topic has 10 replies, 2 voices, and was last updated 6 years, 2 months ago by mbarrow.
-
AuthorPosts
-
14 August 2018 at 04:36 #11663mbarrowBlocked
I am not sure but this may be a bug?
I have been able to assign the position and values of my data to a PointSetTopologyContainer, but I cannot write this object with VTKExporter. I am unable to assign values to “pointsDataField”, even though I see the values I want in PointSetTopologyContainer.points .
What should I do?
Here is the snippet of my .scn showing my issue<PointSetTopologyContainer name="wee" src="@youngM" points="@youngM.values" position="@LMap.restPosition"/> <VTKExporter filename="poo.vtu" edges="1" position="@wee.position" pointsDataFields="@wee.points" XMLformat="1" exportAtBegin="true" overwrite="true"/>
14 August 2018 at 13:18 #11668HugoKeymasterHi @mbarrow
I just tested this:
<Node name="root" dt="0.01" gravity="0 -9.81 0"> <Mesh name="mesh" filename="mesh/dragon.obj" /> <MeshObjLoader name="loader" filename="mesh/dragon.obj" /> <MechanicalObject src="@loader" template="Vec3f" name="mecha" showObject="1" /> <TetrahedronSetTopologyContainer src="@loader" name="topo" /> <VTKExporter filename="example.vtk" listening="true" edges="0" triangles="1" quads="0" tetras="0" pointsDataFields="topo.points" exportAtBegin="1" /> </Node>
and it exports the “points” as a dataField in the vtk format.
Are the component in the same order than in your scene (first the Container then later in the scene the exporter) ?Hugo
15 August 2018 at 01:45 #11679mbarrowBlockedHi Hugo, that didn’t work for me. The vtk exporter won’t populate if I don’t use a mesh as a source for point data.
I am trying to export the data created dynamically in an example .scn. Specifically
sofa/v17.12/src/applications/plugins/Flexible/examples/demos/steak.scn
I am trying to save the youngM points and corresponding rest positions, which are generated dynamically in that .scn file
So, I want to output a set of points in a vtk file for the “E” node. Here are my non-working lines of code in the “E” node of steak.scn. With this extra context, can you help?
... <Node name="E" > <ImageValuesFromPositions name="youngM" position="@../sampler.position" image="@../../../youngM.outputImage" transform="@../../../extruder.outputTransform" /> <MechanicalObject template="E332" name="E" /> <!-- <GreenStrainMapping template="F332,E332" /> --> <CorotationalStrainMapping template="F332,E332" geometricStiffness="false" method="svd" /> <HookeForceField template="E332" name="ff" youngModulus="@youngM.values" poissonRatio="0" viscosity="0" /> <PointSetTopologyContainer name="wee" src="@youngM" points="@youngM.values" /> <VTKExporter filename="poo.vtu" edges="1" position="@wee.position" pointsDataFields="@wee.points" XMLformat="1" exportAtBegin="true" overwrite="true"/> </Node>
16 August 2018 at 23:11 #11687mbarrowBlockedHello Hugo, I think there is indeed some kind of bug.
Position is showing the youngs modulus values in the X column of the three column position vector. Y and Z are all 0’s. This is wrong and should not be possible because I have not set position to be youngs modulus in the XML.
I need this feature to work, what are my options?
17 August 2018 at 14:20 #11693HugoKeymasterHi @mjbarrow
could you post the full node for my understanding?
this should not be hard to fix18 August 2018 at 03:17 #11698mbarrowBlockedHi Hugo, thanks for getting back to me and trying to help.
I made a modification to steak.scn but I thought it may save time to dump the steak.scn here along with the modifications.
the topology you suggested looks ok, it has position vectors and youngs modulus values which I wish to export to a vtk file if I inspect the nodes with runSofa. But the VTKExporter won’t pick up on the youngs modulus values no matter what I try and I can’t write them out.
<?xml version="1.0"?> <Node name="Root" gravity="0 -9.81 0 " dt="0.1" > <RequiredPlugin pluginName="Flexible"/> <RequiredPlugin pluginName="image"/> <VisualStyle displayFlags="showVisual showBehavior" /> <DefaultAnimationLoop /> <DefaultVisualManagerLoop /> <EulerImplicitSolver rayleighStiffness="0.1" rayleighMass="0.1" /> <CGLinearSolver template="GraphScattered" iterations="10" threshold="1e-008" /> <!-- MB demo meat params (less plausible jiggle jiggle, but do work) --> <ImageContainer name="loader" filename="data/steak-seg-highres.ppm" drawBB="false" /> <ImageFilter name="selectchannel" src="@loader" filter="21" param="0"/> <ImageFilter name="extruder" inputImage="@selectchannel.outputImage" filter="20" param="-5 -3.75 -1 64 64 15 0.15 0.15 0.15 0" inputTransform="-5 -3.75 0 0 0 0 0.025 0.025 0.8 0 1 0"/> <!--<ImageContainer name="image" image="@extruder.outputImage" transform="@extruder.outputTransform" drawBB="false"/>--> <ImageContainer name="image" image="@extruder.outputImage" transform="@extruder.outputTransform" drawBB="false"/> <TransferFunction name="youngM" template="ImageUC,ImageD" inputImage="@extruder.outputImage" param="0 0 1 20000 254 5000 255 15000000000"/> <ImageViewer template="ImageD" name="viewer" image="@youngM.outputImage" transform="@extruder.outputTransform" /> <TransferFunction name="densityTF" template="ImageUC,ImageD" inputImage="@extruder.outputImage" param="0 0 1 0.01"/> <Node name="Flexible" > <ImageSampler template="ImageUC" name="sampler" src="@../image" method="1" param="50" fixedPosition="" showSamplesScale="0"/> <MergeMeshes name="merged" nbMeshes="2" position1="@sampler.fixedPosition" position2="@sampler.position" /> <MechanicalObject template="Affine" name="dof" src="@merged" showObject="1" showObjectScale=".1"/> <VoronoiShapeFunction name="SF" template="ShapeFunctiond,ImageD" image="@../youngM.outputImage" transform="@../extruder.outputTransform" nbRef="2" method="0" bias="true" printLog="false" /> <Node name="behavior" > <ImageGaussPointSampler name="sampler" indices="@../SF.indices" weights="@../SF.weights" transform="@../SF.transform" method="2" order="1" showSamplesScale="0" printLog="1" targetNumber="200" /> <MechanicalObject template="F331" name="F" /> <!-- <MLSMapping template="Affine,F331" showDeformationGradientScale="0.1"/> --> <LinearMapping template="Affine,F331" name="Lmap" showDeformationGradientScale="0.1"/> <!-- MB swap MLS for linear --> <Node name="E" > <ImageValuesFromPositions name="youngM" position="@../sampler.position" image="@../../../youngM.outputImage" transform="@../../../extruder.outputTransform" /> <MechanicalObject template="E331" name="E" /> <CorotationalStrainMapping template="F331,E331" method="svd" geometricStiffness="1"/> <HookeForceField template="E332" name="ff" youngModulus="@youngM.values" poissonRatio="0" viscosity="0" /> <!-- MB: Broken? --> <TetrahedronSetTopologyContainer src="@youngM" name="wee" points="@youngM.values" position="@Lmap.restPosition"/> <VTKExporter filename="poo.vtu" edges="1" triangles="1" quads="1" hexas="1" tetras="1" position="@wee.position" cellsDataFields="@wee.points" pointsDataFields="@youngM.values" XMLformat="1" exportAtBegin="true" overwrite="true"/> </Node> </Node> <Node name="collision" > <MeshObjLoader name="MeshLoader" filename="data/steak.obj"/> <Mesh src="@MeshLoader" name="mesh" /> <MechanicalObject template="Vec3d" name="pts" /> <UniformMass totalMass="250" /> <BoxROI template="Vec3d" box="0 -2 0 5 2 5" position="@mesh.position" /> <RestShapeSpringsForceField template="Vec3d" points="@[-1].indices" stiffness="1E3"/> <LinearMapping template="Affine,Vec3d"/> </Node> <Node name="visual" > <OglModel template="ExtVec3f" name="Visual" fileMesh="data/steak.obj" texturename="data/steak.png" normals="0"/> <LinearMapping template="Affine,ExtVec3f"/> </Node> </Node> </Node>
22 August 2018 at 09:52 #11702HugoKeymasterHi @mjbarrow,
you are actually using Flexible which uses an API a bit different from SOFA (decoupling the numerical integration, the mechanical law etc.). This is why the VTKExporter is not very usable in your case. Moreover, the simulation is based on Frame approach, with Voronoi shape functions. There is therefore no topology assiociated (usually required by VTKExporter).
In your particular case, I would recommand to export it using python:
python script “exportPositionYoungModulus.py”import Sofa import sys class WriterController(Sofa.PythonScriptController): def bwdInitGraph(self,node): self.nodeWithYoungModulus = node.getChild('Flexible').getChild('behavior').getChild('E') self.MO = self.nodeWithYoungModulus.getObject('E') self.containerYM = self.nodeWithYoungModulus.getObject('youngM') position = self.MO.findData('position').value youngModulus = self.containerYM.findData('values').value thefile = open('exportPositionYoungModulus.txt', 'w') for i in range (0, len(position)-1) : thefile.write("%s\n" % position[i]) for i in range (0, len(position)-1) : thefile.write("%s\n" % youngModulus[i]) return 0
and add the PythonController in your scene:
<PythonScriptController name="WriterController" filename="exportPositionYoungModulus.py" classname="WriterController"/>
Let me know if it suits you.
Best,Hugo
23 August 2018 at 20:57 #11717mbarrowBlockedHi Hugo, this is promising. I have a final confusion my side.
Each entry of the ‘position’ list is 24 elements long.
Is this to be expected? If so how can I convert to x,y,z?
Thanks
27 August 2018 at 05:40 #11722mbarrowBlockedHugo, I took a quite different approach to the python using some example python code in the Flexible plugin directory. It seems to sample the modulus image using a mesh, but I’m not sure if it really does the right thing. Could you confirm I am on the right path here? I’ve supplied the code for the python container.
Thanks.
import os import Sofa import json from numpy import indices # helper functions def getNode(rootNode, path): currentNode = rootNode pathComponents = path.split('/') for c in pathComponents: if len(c)==0: # for leading '/' and in case of '//' continue if c=='..': currentNode = currentNode.getParents()[0] else: currentNode = currentNode.getChild(c) if currentNode is None: print "SofaPython.Tools.findNode: can't find node at", path return None return currentNode # variables; self.variables[0][0] = path to mesh self.variables[0][0] = path to pts class Modulus_Log(Sofa.PythonScriptController): def createGraph(self,node): meshpath = self.variables[0][0] ptspath = self.variables[1][0] self.outfile= self.variables[2][0] [path,obj]=ptspath.rsplit('/',1) #get path to 'pts' object as supplied to the script self.movingpts=getNode(node,path).getObject(obj) self.mynode = node.createChild('DataLogging') self.mesh = self.mynode.createObject('TriangleSetTopologyContainer',name='mesh', src='@../'+meshpath) self.youngsIndices=self.mynode.createObject( 'ImageValuesFromPositions', template='ImageUI', name='youngsIndices', position='@mesh.position', image='@../../sampler.region', transform='@../../sampler.transform' , interpolation='0' ) self.mynode.createObject('IdentityMapping',input='@../'+ptspath, output='@.') return 0 #Log data that you want in a decent format. you could use vtk json whatever. def cleanup(self): #get mapped youngs modulus values (mapped from an image sampler to the closest exterior points of mesh) and log them out. youngMidx = self.youngsIndices.findData('values').value allYM = self.ffield.findData('youngModulus').value YM = [allYM[int(item[0])] for index, item in enumerate(youngMidx)] #get displaced mesh point positions and log those out too ptsXYZ=self.movingpts.getData('position').value rptsXYZ=self.movingpts.getData('rest_position').value T = self.mesh.getData('triangles').value print('logging out data...') output = dict() output['rest_position']=rptsXYZ output['position']=ptsXYZ output['triangles']=T output['youngsM']=YM with open(self.outfile,'w') as file: try: json.dump(output, file) except IOError: raise if self.outfile[0] != '/': print('saved simulation results to\n: \t'+os.getcwd()+'/'+self.outfile) else: print('saved simulation results to\n: \t'+self.outfile)
28 August 2018 at 22:31 #11748HugoKeymasterHi @mjbarrow
in my case, the script does not work due to “self.variable”
what is this suppose to be? it seems undefined29 August 2018 at 15:52 #11760mbarrowBlockedHi Hugo, sorry I was tired when I posted that, the self.variables should come from the python controller node in the scn. The first is to the collision mesh and the second is just a file name for some output JSON
<PythonScriptController filename="steaklog.py" classname="Modulus_Log" variables="../../collision/mesh ../../collision/pts youngsdata.json"/>
Is this the answer to your question?
Let me know, thanks
-
AuthorPosts
- You must be logged in to reply to this topic.