Simple Mayavi CutPlane

classic Classic list List threaded Threaded
6 messages Options
Reply | Threaded
Open this post in threaded view
|

Simple Mayavi CutPlane

Nick Smith
I'm trying to use a cut plane to show a cross-sectional cut of a fiber
visualization (essentially a bunch of cylinders at different angles, the
cut should show ellipses). I've searched for all the examples of cut
planes that I could, but none of them seem to actually cut my model,
could someone post a simple example of an angled cylinder (or cube or
whatever) with a cross-sectional cut? Thanks!

-Nick
_______________________________________________
Enthought-Dev mailing list
[hidden email]
https://mail.enthought.com/mailman/listinfo/enthought-dev
Reply | Threaded
Open this post in threaded view
|

Re: Simple Mayavi CutPlane

Gael Varoquaux
Hi Nick,

I guess that the data representation that you currently have is made of
lines and surfaces, and not volumetric data. Cut plane of such data (that
has no volume) does not exist.

If you can generate the data as a volumetric data, eg sampling on a fine
grid and putting ones inside the fiber and zeros outside, you can use
the standard cut planes.

Sorry, Mayavi is not a solid geometry engine like CAD modelling software
:).

HTH,

Gaƫl

On Fri, Aug 24, 2012 at 12:49:08PM -0400, Nick Smith wrote:
> I'm trying to use a cut plane to show a cross-sectional cut of a fiber
> visualization (essentially a bunch of cylinders at different angles, the
> cut should show ellipses). I've searched for all the examples of cut
> planes that I could, but none of them seem to actually cut my model,
> could someone post a simple example of an angled cylinder (or cube or
> whatever) with a cross-sectional cut? Thanks!

_______________________________________________
Enthought-Dev mailing list
[hidden email]
https://mail.enthought.com/mailman/listinfo/enthought-dev
Reply | Threaded
Open this post in threaded view
|

Re: Simple Mayavi CutPlane

Eric Carlson
In reply to this post by Nick Smith
Hello Nick,
You can do what you want to do, but it requires digging down deeper into vtk. The appropriate vtk example is clipcows.py, and shows how to intersect an arbitrary surface object (which may be many different surfaces) with an implicit function. I have an example that works great under an older version of  vtk and mayavi, but does not work on a later version for some reason. I don't have time to track down the error.

In any case, below is the version that worked in times past as a starting point for you. I have left as comments  some of the original vtk example pieces for reference. In my case, I have a special environment that lets me keep an active name space so that the Cut function defined at the bottom allows me to select an arbitrary slice point. I have attached an example output. Under mayavi (but not vtk) I have the option to hide any of the resulting pieces as shown in the diamond_cut_adjusted

Cheers,
Eric


import vtk
from vtk.util import colors
from vtk.util.colors import peacock, tomato
from enthought.tvtk.api import tvtk
from enthought.mayavi import mlab as p3d
from enthought.mayavi.sources.vtk_data_source import VTKDataSource

e1=p3d.get_engine()
# First start by reading a cow model. We also generate surface normals for
# prettier rendering.

#cow = tvtk.BYUReader()
#cow.file_name=r"C:\Downloads\cow.g"

#cow = tvtk.STLReader()
#cow.file_name=r"C:\Downloads\junk_adjusted11.stl"
cow=tvtk.OBJReader()
cow.file_name=r"C:\SciPylot2\diamlrge.obj"

cowNormals = tvtk.PolyDataNormals()
cowNormals.set_input(cow.get_output())

# We clip with an implicit function. Here we use a plane positioned near
# the center of the cow model and oriented at an arbitrary angle.
plane = tvtk.Plane()
plane.origin=[0.0, 0.0, 0.0]
plane.normal=[0.0, 0.0, 1.0]

clip_value=20.0
# vtkClipPolyData requires an implicit function to define what it is to
# clip with. Any implicit function, including complex boolean combinations
# can be used. Notice that we can specify the value of the implicit function
# with the SetValue method.
clipper = tvtk.ClipPolyData()
clipper.set_input(cowNormals.get_output())
clipper.clip_function=plane
clipper.generate_clip_scalars=1
clipper.generate_clipped_output=1
clipper.value=clip_value
#clipM.apper = tvtk.PolyDataMapper()
#clipMapper.set_input_connection(clipper.output_port)
#clipMapper.scalar_visibility=0
backProp = tvtk.Property()
backProp.diffuse_color=tomato
#clipActor = tvtk.Actor()
#clipActor.mapper=clipMapper
#clipActor.property.color=peacock
#clipActor.backface_property=backProp

my_scene=e1.new_scene()
#my_scene.scene.add_actor(clipActor)

src1 = VTKDataSource(data = clipper.get_output())
e1.add_source(src1)
asurf=p3d.pipeline.surface(src1,opacity=1.0, name="main_cow",color=colors.white)
asurf.actor.actor.backface_property=backProp
#asurf.actor.actor.texture=my_texture

# Here we are cutting the cow. Cutting creates lines where the cut
# function intersects the model. (Clipping removes a portion of the
# model but the dimension of the data does not change.)
#
# The reason we are cutting is to generate a closed polygon at the
# boundary of the clipping process. The cutter generates line
# segments, the stripper then puts them together into polylines. We
# then pull a trick and define polygons using the closed line
# segements that the stripper created.
cutEdges = tvtk.Cutter()
cutEdges.set_input(cowNormals.get_output())
cutEdges.cut_function=plane
cutEdges.generate_cut_scalars=1
cutEdges.set_value(0,clip_value)
cutStrips = tvtk.Stripper()
cutStrips.set_input_connection(cutEdges.output_port)
cutStrips.update()
cutPoly = tvtk.PolyData()
cutPoly.points=cutStrips.get_output().points
cutPoly.polys=cutStrips.get_output().lines

# Triangle filter is robust enough to ignore the duplicate point at
# the beginning and end of the polygons and triangulate them.
cutTriangles = tvtk.TriangleFilter()
cutTriangles.input=cutPoly
cutMapper = tvtk.PolyDataMapper()
cutMapper.input=cutPoly
cutMapper.set_input_connection(cutTriangles.output_port)
cutActor = tvtk.Actor()
cutActor.mapper=cutMapper
cutActor.property.color=peacock

src2 = VTKDataSource(data = cutTriangles.get_output())
e1.add_source(src2)
asurf=p3d.pipeline.surface(src2,opacity=.50, name="cutting_plane",color=colors.peacock)


##my_scene.scene.add_actor(cutActor)
##
# The clipped part of the cow is rendered wireframe.
##restMapper = tvtk.PolyDataMapper()
##restMapper.set_input_connection(clipper.clipped_output_port)
##restMapper.scalar_visibility=0
##restActor = tvtk.Actor()
##restActor.mapper=restMapper
##restActor.property.representation='wireframe'
##my_scene.scene.add_actor(restActor)

src3 = VTKDataSource(data = clipper._get_clipped_output())
e1.add_source(src3)
asurf=p3d.pipeline.surface(src3,opacity=.50, name="clipped_output",color=colors.peacock)

##
### Create graphics stuff
##ren = vtk.vtkRenderer()
##renWin = vtk.vtkRenderWindow()
##renWin.AddRenderer(ren)
##iren = vtk.vtkRenderWindowInteractor()
##iren.SetRenderWindow(renWin)
##
### Add the actors to the renderer, set the background and size
##ren.AddActor(clipActor)
##ren.AddActor(cutActor)
##ren.AddActor(restActor)
##ren.SetBackground(1, 1, 1)
##ren.ResetCamera()
##ren.GetActiveCamera().Azimuth(30)
##ren.GetActiveCamera().Elevation(30)
##ren.GetActiveCamera().Dolly(1.5)
##ren.ResetCameraClippingRange()
##
##renWin.SetSize(300, 300)
##iren.Initialize()
##
### Lets you move the cut plane back and forth by invoking the function
### Cut with the appropriate plane value (essentially a distance from
### the original plane).  This is not used in this code but should give
### you an idea of how to define a function to do this.
def Cut(v):
    clipper.value=v
    cutEdges.set_value(0,v)
    cutStrips.update()
    cutPoly.points=cutStrips.get_output().points
    cutPoly.polys=cutStrips.get_output().lines
    cutMapper.update()
    my_scene.scene.render()
##
##renWin.Render()
##iren.Start()



_______________________________________________
Enthought-Dev mailing list
[hidden email]
https://mail.enthought.com/mailman/listinfo/enthought-dev

diamond_cut.png (161K) Download Attachment
diamond_cut_adjusted.png (66K) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: Simple Mayavi CutPlane

Gael Varoquaux
Thanks Eric for helping out on the mailing list!

Gael

On Sun, Aug 26, 2012 at 08:59:27AM -0500, Carlson, Eric wrote:
> Hello Nick,
> You can do what you want to do, but it requires digging down deeper into vtk. The appropriate vtk example is clipcows.py, and shows how to intersect an arbitrary surface object (which may be many different surfaces) with an implicit function. I have an example that works great under an older version of  vtk and mayavi, but does not work on a later version for some reason. I don't have time to track down the error.

> In any case, below is the version that worked in times past as a starting point for you. I have left as comments  some of the original vtk example pieces for reference. In my case, I have a special environment that lets me keep an active name space so that the Cut function defined at the bottom allows me to select an arbitrary slice point. I have attached an example output. Under mayavi (but not vtk) I have the option to hide any of the resulting pieces as shown in the diamond_cut_adjusted

> Cheers,
> Eric


> import vtk
> from vtk.util import colors
> from vtk.util.colors import peacock, tomato
> from enthought.tvtk.api import tvtk
> from enthought.mayavi import mlab as p3d
> from enthought.mayavi.sources.vtk_data_source import VTKDataSource

> e1=p3d.get_engine()
> # First start by reading a cow model. We also generate surface normals for
> # prettier rendering.

> #cow = tvtk.BYUReader()
> #cow.file_name=r"C:\Downloads\cow.g"

> #cow = tvtk.STLReader()
> #cow.file_name=r"C:\Downloads\junk_adjusted11.stl"
> cow=tvtk.OBJReader()
> cow.file_name=r"C:\SciPylot2\diamlrge.obj"

> cowNormals = tvtk.PolyDataNormals()
> cowNormals.set_input(cow.get_output())

> # We clip with an implicit function. Here we use a plane positioned near
> # the center of the cow model and oriented at an arbitrary angle.
> plane = tvtk.Plane()
> plane.origin=[0.0, 0.0, 0.0]
> plane.normal=[0.0, 0.0, 1.0]

> clip_value=20.0
> # vtkClipPolyData requires an implicit function to define what it is to
> # clip with. Any implicit function, including complex boolean combinations
> # can be used. Notice that we can specify the value of the implicit function
> # with the SetValue method.
> clipper = tvtk.ClipPolyData()
> clipper.set_input(cowNormals.get_output())
> clipper.clip_function=plane
> clipper.generate_clip_scalars=1
> clipper.generate_clipped_output=1
> clipper.value=clip_value
> #clipM.apper = tvtk.PolyDataMapper()
> #clipMapper.set_input_connection(clipper.output_port)
> #clipMapper.scalar_visibility=0
> backProp = tvtk.Property()
> backProp.diffuse_color=tomato
> #clipActor = tvtk.Actor()
> #clipActor.mapper=clipMapper
> #clipActor.property.color=peacock
> #clipActor.backface_property=backProp

> my_scene=e1.new_scene()
> #my_scene.scene.add_actor(clipActor)

> src1 = VTKDataSource(data = clipper.get_output())
> e1.add_source(src1)
> asurf=p3d.pipeline.surface(src1,opacity=1.0, name="main_cow",color=colors.white)
> asurf.actor.actor.backface_property=backProp
> #asurf.actor.actor.texture=my_texture

> # Here we are cutting the cow. Cutting creates lines where the cut
> # function intersects the model. (Clipping removes a portion of the
> # model but the dimension of the data does not change.)

> # The reason we are cutting is to generate a closed polygon at the
> # boundary of the clipping process. The cutter generates line
> # segments, the stripper then puts them together into polylines. We
> # then pull a trick and define polygons using the closed line
> # segements that the stripper created.
> cutEdges = tvtk.Cutter()
> cutEdges.set_input(cowNormals.get_output())
> cutEdges.cut_function=plane
> cutEdges.generate_cut_scalars=1
> cutEdges.set_value(0,clip_value)
> cutStrips = tvtk.Stripper()
> cutStrips.set_input_connection(cutEdges.output_port)
> cutStrips.update()
> cutPoly = tvtk.PolyData()
> cutPoly.points=cutStrips.get_output().points
> cutPoly.polys=cutStrips.get_output().lines

> # Triangle filter is robust enough to ignore the duplicate point at
> # the beginning and end of the polygons and triangulate them.
> cutTriangles = tvtk.TriangleFilter()
> cutTriangles.input=cutPoly
> cutMapper = tvtk.PolyDataMapper()
> cutMapper.input=cutPoly
> cutMapper.set_input_connection(cutTriangles.output_port)
> cutActor = tvtk.Actor()
> cutActor.mapper=cutMapper
> cutActor.property.color=peacock

> src2 = VTKDataSource(data = cutTriangles.get_output())
> e1.add_source(src2)
> asurf=p3d.pipeline.surface(src2,opacity=.50, name="cutting_plane",color=colors.peacock)


> ##my_scene.scene.add_actor(cutActor)

> # The clipped part of the cow is rendered wireframe.
> ##restMapper = tvtk.PolyDataMapper()
> ##restMapper.set_input_connection(clipper.clipped_output_port)
> ##restMapper.scalar_visibility=0
> ##restActor = tvtk.Actor()
> ##restActor.mapper=restMapper
> ##restActor.property.representation='wireframe'
> ##my_scene.scene.add_actor(restActor)

> src3 = VTKDataSource(data = clipper._get_clipped_output())
> e1.add_source(src3)
> asurf=p3d.pipeline.surface(src3,opacity=.50, name="clipped_output",color=colors.peacock)


> ### Create graphics stuff
> ##ren = vtk.vtkRenderer()
> ##renWin = vtk.vtkRenderWindow()
> ##renWin.AddRenderer(ren)
> ##iren = vtk.vtkRenderWindowInteractor()
> ##iren.SetRenderWindow(renWin)

> ### Add the actors to the renderer, set the background and size
> ##ren.AddActor(clipActor)
> ##ren.AddActor(cutActor)
> ##ren.AddActor(restActor)
> ##ren.SetBackground(1, 1, 1)
> ##ren.ResetCamera()
> ##ren.GetActiveCamera().Azimuth(30)
> ##ren.GetActiveCamera().Elevation(30)
> ##ren.GetActiveCamera().Dolly(1.5)
> ##ren.ResetCameraClippingRange()

> ##renWin.SetSize(300, 300)
> ##iren.Initialize()

> ### Lets you move the cut plane back and forth by invoking the function
> ### Cut with the appropriate plane value (essentially a distance from
> ### the original plane).  This is not used in this code but should give
> ### you an idea of how to define a function to do this.
> def Cut(v):
>     clipper.value=v
>     cutEdges.set_value(0,v)
>     cutStrips.update()
>     cutPoly.points=cutStrips.get_output().points
>     cutPoly.polys=cutStrips.get_output().lines
>     cutMapper.update()
>     my_scene.scene.render()

> ##renWin.Render()
> ##iren.Start()




--
    Gael Varoquaux
    Researcher, INRIA Parietal
    Laboratoire de Neuro-Imagerie Assistee par Ordinateur
    NeuroSpin/CEA Saclay , Bat 145, 91191 Gif-sur-Yvette France
    Phone:  ++ 33-1-69-08-79-68
    http://gael-varoquaux.info            http://twitter.com/GaelVaroquaux
_______________________________________________
Enthought-Dev mailing list
[hidden email]
https://mail.enthought.com/mailman/listinfo/enthought-dev
Reply | Threaded
Open this post in threaded view
|

Re: Simple Mayavi CutPlane

Eric Carlson
Quick follow up.

The example I gave does work if you give the correct path. The original clipcows.py example used the file cows.g, which is under \VTKData\Data\Viewpoint\cow.g in the VTK data set directory. To get something decent for the cow.g data set, you might want to change the values in the following lines to:

plane.origin=[ 0.25, 0, 0]
plane.normal=[ 1.0, 1.0, 0]

clip_value=.5


I have attached a functioning example for the cow.g file. The path to the file needs to be corrected for each machine, and it needs to be run in environment where the mlab windows stays open.

Should you run the file in an environment that maintains the objects and name space, you can try to change the location of the cut plane by using Cut(v) for -5<= v <=7.0.


_______________________________________________
Enthought-Dev mailing list
[hidden email]
https://mail.enthought.com/mailman/listinfo/enthought-dev

clipcow_tvtk_for_mayavi.py (7K) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: Simple Mayavi CutPlane

Nick Smith
Thanks so much for all the great help. I've been digging through the vtk examples and documentation and I think I've got it all figured out. Thanks so much for the great help!

-Nick

On 8/27/2012 6:05 PM, Carlson, Eric wrote:
Quick follow up.

The example I gave does work if you give the correct path. The original clipcows.py example used the file cows.g, which is under \VTKData\Data\Viewpoint\cow.g in the VTK data set directory. To get something decent for the cow.g data set, you might want to change the values in the following lines to:

plane.origin=[ 0.25, 0, 0]
plane.normal=[ 1.0, 1.0, 0]

clip_value=.5


I have attached a functioning example for the cow.g file. The path to the file needs to be corrected for each machine, and it needs to be run in environment where the mlab windows stays open.

Should you run the file in an environment that maintains the objects and name space, you can try to change the location of the cut plane by using Cut(v) for -5<= v <=7.0.



_______________________________________________
Enthought-Dev mailing list
[hidden email]
https://mail.enthought.com/mailman/listinfo/enthought-dev


_______________________________________________
Enthought-Dev mailing list
[hidden email]
https://mail.enthought.com/mailman/listinfo/enthought-dev