[vtkusers] Fwd: Clipping STL only clips part of the object
Dieter Rosch
dieter.rosch at gmail.com
Tue Nov 10 09:53:52 EST 2015
Hi all,
I have just started experimenting with VTK via the ActiViz.NET wrapper. The
examples are a very useful introduction, and I am really enjoying the
toolkit so far.
As an exercise, I have taken the regular BoxWidget example, and replaced
the mace object with an STL I have. However I am running into a slight
problem:
When I move the BoxWidget to clip the STL image, it only seems to clip the
front of the STL.
An example of what I mean is visible here: <<http://imgur.com/Yalu91C>>
I am pretty sure it is something small I am missing, it's as if the
clipping algorithm does not see the not clipped part as an outside surface,
perhaps a normal problem. Can anyone perhaps shed some light on this for me?
.NET Code below for critique:
using Kitware.VTK;
using System;
/// <summary>
/// Class containing main method
/// </summary>
public class Demo
{
public static vtkWindowedSincPolyDataFilter GetBoneSTL()
{
string path =
"C:\\Data\\sandbox\\python\\dicom\\example_images\\Shoulder";
var reader = new vtkDICOMImageReader();
reader.SetDirectoryName(path);
var threshold = new vtkImageThreshold();
threshold.SetInputConnection(reader.GetOutputPort());
threshold.ThresholdByLower(350);// remove all soft tissue
threshold.ReplaceInOn();
threshold.SetInValue(0); //set all values below 400 to 0
threshold.ReplaceOutOn();
threshold.SetOutValue(1); //set all values above 400 to 1
//Discrete Marching Cubes algorithm
var dmc = new vtkDiscreteMarchingCubes();
dmc.SetInputConnection(threshold.GetOutputPort());
dmc.GenerateValues(1, 1, 1);
//Clean the mesh
var connect = new vtkPolyDataConnectivityFilter();
connect.SetInputConnection(dmc.GetOutputPort());
connect.SetExtractionModeToLargestRegion();
var clean = new vtkCleanPolyData();
clean.SetInputConnection(connect.GetOutputPort());
//clean.SetInputConnection(dmc.GetOutputPort());
//Smooth
var smooth = new vtkWindowedSincPolyDataFilter();
smooth.SetNumberOfIterations(25);
smooth.SetInputConnection(clean.GetOutputPort());
return smooth;
}
public static void Main(String[] argv)
{
boneSTL = Demo.GetBoneSTL();
glyph = vtkGlyph3D.New();
glyph.SetInputConnection(boneSTL.GetOutputPort());
glyph.SetVectorModeToUseNormal();
glyph.SetScaleModeToScaleByVector();
glyph.SetScaleFactor(0.25);
boneMapper = vtkPolyDataMapper.New();
boneMapper.SetInputConnection(boneSTL.GetOutputPort());
boneActor = vtkLODActor.New();
boneActor.SetMapper(boneMapper);
boneActor.VisibilityOn();
// This portion of the code clips the mace with the vtkPlanes
implicit function.
// The clipped region is colored green.
planes = vtkPlanes.New();
clipper = vtkClipPolyData.New();
clipper.SetInputConnection(boneSTL.GetOutputPort());
clipper.SetClipFunction(planes);
clipper.InsideOutOn();
selectMapper = vtkPolyDataMapper.New();
selectMapper.SetInputConnection(clipper.GetOutputPort());
selectMapper.ScalarVisibilityOff();
selectActor = vtkLODActor.New();
selectActor.SetMapper(selectMapper);
selectActor.GetProperty().SetColor(0, 1, 0);
selectActor.VisibilityOff();
selectActor.SetScale(1.01, 1.01, 1.01);
// Create the RenderWindow, Renderer and both Actors
ren1 = vtkRenderer.New();
renWin = vtkRenderWindow.New();
renWin.AddRenderer(ren1);
iren = vtkRenderWindowInteractor.New();
iren.SetRenderWindow(renWin);
// The SetInteractor method is how 3D widgets are associated with
the render
// window interactor. Internally, SetInteractor sets up a bunch of
callbacks
// using the Command/Observer mechanism (AddObserver()).
boxWidget = vtkBoxWidget.New();
boxWidget.SetInteractor(iren);
boxWidget.SetPlaceFactor(1.25);
ren1.AddActor(boneActor);
ren1.AddActor(selectActor);
// Add the actors to the renderer, set the background and size
ren1.SetBackground(0.1, 0.2, 0.4);
renWin.SetSize(600, 600);
// Place the interactor initially. The input to a 3D widget is used
to
// initially position and scale the widget. The EndInteractionEvent
is
// observed which invokes the SelectPolygons callback.
boxWidget.SetInput(glyph.GetOutput());
boxWidget.PlaceWidget();
boxWidget.EndInteractionEvt += new
vtkObject.vtkObjectEventHandler(SelectPolygons);
// render the image
iren.Initialize();
iren.Start();
//Clean up
deleteAllVTKObjects();
}
static vtkPolyDataAlgorithm boneSTL;
static vtkGlyph3D glyph;
static vtkAppendPolyData apd;
static vtkPolyDataMapper boneMapper;
static vtkLODActor boneActor;
static vtkPlanes planes;
static vtkClipPolyData clipper;
static vtkPolyDataMapper selectMapper;
static vtkLODActor selectActor;
static vtkRenderer ren1;
static vtkRenderWindow renWin;
static vtkRenderWindowInteractor iren;
static vtkBoxWidget boxWidget;
/// <summary>
/// Callback function for boxWidget.EndInteractionEvt
/// </summary>
public static void SelectPolygons(vtkObject sender, vtkObjectEventArgs
e)
{
boxWidget.GetPlanes(planes);
selectActor.VisibilityOn();
}
///<summary>
///Deletes all static objects created
///</summary>
public static void deleteAllVTKObjects()
{
//clean up vtk objects
if (boneSTL != null) { boneSTL.Dispose(); }
//if (cone != null) { cone.Dispose(); }
if (glyph != null) { glyph.Dispose(); }
//if (apd != null) { apd.Dispose(); }
if (boneMapper != null) { boneMapper.Dispose(); }
if (boneActor != null) { boneActor.Dispose(); }
if (planes != null) { planes.Dispose(); }
if (clipper != null) { clipper.Dispose(); }
if (selectMapper != null) { selectMapper.Dispose(); }
if (selectActor != null) { selectActor.Dispose(); }
if (ren1 != null) { ren1.Dispose(); }
if (renWin != null) { renWin.Dispose(); }
if (iren != null) { iren.Dispose(); }
if (boxWidget != null) { boxWidget.Dispose(); }
}
}
Regards,
Dieter
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://public.kitware.com/pipermail/vtkusers/attachments/20151110/8c9cab5e/attachment.html>
More information about the vtkusers
mailing list