<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><div>Good morning,</div><div><br></div><div>Apologies for the repost of the question I posted yesterday - when I woke up this morning I realised I had completely mislabeled the question, referring to an STL when in fact, the object was a DICOM object I had extracted using Thresholding and MarchingCubes. Hopefully the clarified subject line and explanation will target the correct audience.</div><div><br></div><div> I have just started experimenting with VTK via the ActiViz.NET wrapper. The examples are a very useful introduction to the toolkit.</div><div><br></div><div>As an exercise, I have taken the regular BoxWidget example, and replaced the mace object with an object I have extracted from a DICOM. However I am running into a slight problem:When I move the BoxWidget to clip the object, it only seems to clip the front of the object. An example of what I mean is visible here: <<<a href="http://imgur.com/Yalu91C" target="_blank">http://imgur.com/Yalu91C</a>>>. As you can see, only the front surfaces seem to turn green (green indicates the clipped area).</div><div><br></div><div><br></div><div>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 problem with normals. Can anyone perhaps shed some light on this for me?.NET Code below for critique,thought it maps pretty closely to the C++ code:</div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div dir="ltr"><div><br></div><div><div>using Kitware.VTK;</div><div>using System;</div><div><br></div><div>/// <summary></div><div>/// Class containing main method</div><div>/// </summary></div><div>public class Demo</div><div>{</div><div><br></div><div><br></div><div>    public static void Main(String[] argv)</div><div>    {</div><div>        string path = "C:\\Data\\sandbox\\python\\dicom\\example_images\\Shoulder";<br></div><div>        var reader = new vtkDICOMImageReader();</div><div>        reader.SetDirectoryName(path);</div><div><br></div><div>        var threshold = new vtkImageThreshold();</div><div>        threshold.SetInputConnection(reader.GetOutputPort());</div><div>        threshold.ThresholdByLower(350);// remove all soft tissue</div><div>        threshold.ReplaceInOn();</div><div>        threshold.SetInValue(0);        //set all values below 400 to 0</div><div>        threshold.ReplaceOutOn();</div><div>        threshold.SetOutValue(1);       //set all values above 400 to 1</div><div><br></div><div><br></div><div>        //Discrete Marching Cubes algorithm</div><div>        var dmc = new vtkDiscreteMarchingCubes();</div><div>        dmc.SetInputConnection(threshold.GetOutputPort());</div><div>        dmc.GenerateValues(1, 1, 1);</div><div><br></div><div>        //Clean the mesh</div><div>        var connect = new vtkPolyDataConnectivityFilter();</div><div>        connect.SetInputConnection(dmc.GetOutputPort());</div><div>        connect.SetExtractionModeToLargestRegion();</div><div><br></div><div>        var clean = new vtkCleanPolyData();</div><div>        clean.SetInputConnection(connect.GetOutputPort());</div><div>        //clean.SetInputConnection(dmc.GetOutputPort());</div><div><br></div><div>        //Smooth</div><div>        var boneSTL = new vtkWindowedSincPolyDataFilter();</div><div>        boneSTL.SetNumberOfIterations(25);</div><div>        boneSTL.SetInputConnection(clean.GetOutputPort());</div><div>                     <br></div><div>        glyph = vtkGlyph3D.New();<br></div><div><br></div><div>        glyph.SetInputConnection(boneSTL.GetOutputPort());</div><div>        glyph.SetVectorModeToUseNormal();</div><div>        glyph.SetScaleModeToScaleByVector();</div><div>        glyph.SetScaleFactor(0.25);</div><div><br></div><div>        boneMapper = vtkPolyDataMapper.New();</div><div>        boneMapper.SetInputConnection(boneSTL.GetOutputPort());</div><div><br></div><div>        boneActor = vtkLODActor.New();</div><div>        boneActor.SetMapper(boneMapper);</div><div>        </div><div>        boneActor.VisibilityOn();</div><div><br></div><div>        // This portion of the code clips the mace with the vtkPlanes implicit function.</div><div>        // The clipped region is colored green.</div><div>        planes = vtkPlanes.New();</div><div>        clipper = vtkClipPolyData.New();</div><div><br></div><div>        clipper.SetInputConnection(boneSTL.GetOutputPort());        </div><div>        clipper.SetClipFunction(planes);        </div><div>        clipper.InsideOutOn();</div><div><br></div><div>        selectMapper = vtkPolyDataMapper.New();</div><div>        selectMapper.SetInputConnection(clipper.GetOutputPort());</div><div>        selectMapper.ScalarVisibilityOff();</div><div><br></div><div>        selectActor = vtkLODActor.New();</div><div>        selectActor.SetMapper(selectMapper);</div><div>        selectActor.GetProperty().SetColor(0, 1, 0);</div><div>        selectActor.VisibilityOff();</div><div>        selectActor.SetScale(1.01, 1.01, 1.01);</div><div><br></div><div>        // Create the RenderWindow, Renderer and both Actors</div><div>        ren1 = vtkRenderer.New();</div><div>        renWin = vtkRenderWindow.New();</div><div>        renWin.AddRenderer(ren1);</div><div>        iren = vtkRenderWindowInteractor.New();</div><div>        iren.SetRenderWindow(renWin);</div><div><br></div><div>        // The SetInteractor method is how 3D widgets are associated with the render</div><div>        // window interactor. Internally, SetInteractor sets up a bunch of callbacks</div><div>        // using the Command/Observer mechanism (AddObserver()).</div><div>        boxWidget = vtkBoxWidget.New();</div><div>        boxWidget.SetInteractor(iren);</div><div>        boxWidget.SetPlaceFactor(1.25);</div><div>        ren1.AddActor(boneActor);</div><div>        ren1.AddActor(selectActor);</div><div><br></div><div>        // Add the actors to the renderer, set the background and size</div><div>        ren1.SetBackground(0.1, 0.2, 0.4);</div><div>        renWin.SetSize(600, 600);</div><div><br></div><div>        // Place the interactor initially. The input to a 3D widget is used to </div><div>        // initially position and scale the widget. The EndInteractionEvent is</div><div>        // observed which invokes the SelectPolygons callback.</div><div>        boxWidget.SetInput(glyph.GetOutput());</div><div>        boxWidget.PlaceWidget();</div><div>        boxWidget.EndInteractionEvt += new vtkObject.vtkObjectEventHandler(SelectPolygons);</div><div>        </div><div>        // render the image</div><div>        iren.Initialize();</div><div>        iren.Start();</div><div>        //Clean up</div><div>        deleteAllVTKObjects();</div><div>    }</div><div><br></div><div>    static vtkPolyDataAlgorithm boneSTL;</div><div>    static vtkGlyph3D glyph;</div><div>    static vtkAppendPolyData apd;</div><div>    static vtkPolyDataMapper boneMapper;</div><div>    static vtkLODActor boneActor;</div><div>    static vtkPlanes planes;</div><div>    static vtkClipPolyData clipper;</div><div>    static vtkPolyDataMapper selectMapper;</div><div>    static vtkLODActor selectActor;</div><div>    static vtkRenderer ren1;</div><div>    static vtkRenderWindow renWin;</div><div>    static vtkRenderWindowInteractor iren;</div><div>    static vtkBoxWidget boxWidget;</div><div><br></div><div>    /// <summary></div><div>    /// Callback function for boxWidget.EndInteractionEvt</div><div>    /// </summary></div><div>    public static void SelectPolygons(vtkObject sender, vtkObjectEventArgs e)</div><div>    {</div><div>        boxWidget.GetPlanes(planes);</div><div>        selectActor.VisibilityOn();</div><div>    }</div><div><br></div><div>    ///<summary></div><div>    ///Deletes all static objects created</div><div>    ///</summary></div><div>    public static void deleteAllVTKObjects()</div><div>    {</div><div>        //clean up vtk objects</div><div>        if (boneSTL != null) { boneSTL.Dispose(); }</div><div>        //if (cone != null) { cone.Dispose(); }</div><div>        if (glyph != null) { glyph.Dispose(); }</div><div>        //if (apd != null) { apd.Dispose(); }</div><div>        if (boneMapper != null) { boneMapper.Dispose(); }</div><div>        if (boneActor != null) { boneActor.Dispose(); }</div><div>        if (planes != null) { planes.Dispose(); }</div><div>        if (clipper != null) { clipper.Dispose(); }</div><div>        if (selectMapper != null) { selectMapper.Dispose(); }</div><div>        if (selectActor != null) { selectActor.Dispose(); }</div><div>        if (ren1 != null) { ren1.Dispose(); }</div><div>        if (renWin != null) { renWin.Dispose(); }</div><div>        if (iren != null) { iren.Dispose(); }</div><div>        if (boxWidget != null) { boxWidget.Dispose(); }</div><div>    }</div><div>}</div><div><br></div></div><div><br></div><div>Thank you in advance for the help.</div><div><br></div><div>Regards,</div><div>Dieter</div></div>
</blockquote></div><br></div></div>