[vtkusers] Fwd: [VTK] Reversed/inside out objects using vtkBoxWidget

Jon Haitz Legarreta jhlegarreta at vicomtech.org
Wed Jun 18 05:04:55 EDT 2014


Hi there,
anybody, please?

Thank you !
JON HAITZ


---------- Forwarded message ----------
From: Jon Haitz Legarreta <jhlegarreta at vicomtech.org>
Date: 17 June 2014 10:36
Subject: [VTK] Reversed/inside out objects using vtkBoxWidget
To: "vtkusers at vtk.org" <vtkusers at vtk.org>


Hi there,
I was trying to get a kind of reversed or inside out result for the
clipping operation performed by the vtkBoxWidget.

Please, find attached a screenshot of the idea, done in Paraview.

I've noticed that there is some older post asking for the same question
[1], but the conversation drifted towards volume rendering issues.

Although I want to apply the reversed box to a volume as well, I guess the
situation is just the same as applying it to an isosurface or a geometry
generated with VTK.

Calling InsideOutOn for either the vtkClipPolyData does not work for me.
Attached is also a MWE of the "usual" situation, where the part of interest
lies within the box (and the outside is displayed by another actor; hiding
the original actor does not work). So in my case, the part of interest
would be the inverse: the one lying outside the box.

I am using VTK 6.1.0

Thanks,
JON HAITZ


[1] http://www.vtk.org/pipermail/vtkusers/2013-April/079288.html
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://public.kitware.com/pipermail/vtkusers/attachments/20140618/34c5d83e/attachment-0001.html>
-------------- next part --------------
/*=======================================================================

  Program:   
  Module:    $RCSfile: $
  Language:  C++
  Date:      $Date: $
  Version:   $Revision: $
  Author:    $Author: $
  Comment:   Adapted from the VTK examples

=========================================================================*/
/* $Id:  */


#include <vtkActor.h>
#include <vtkAppendPolyData.h>
#include <vtkBoxWidget.h>
#include <vtkBoxRepresentation.h>
#include <vtkCamera.h>
#include <vtkClipPolyData.h>
#include <vtkCommand.h>
#include <vtkConeSource.h>
#include <vtkGlyph3D.h>
#include <vtkInteractorStyleTrackballCamera.h>
#include <vtkLODActor.h>
#include <vtkPlanes.h>
#include <vtkPolyDataMapper.h>
#include <vtkProperty.h>
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkSmartPointer.h>
#include <vtkSphereSource.h>

 
class vtkMyCallback : public vtkCommand
{
public:
  static vtkMyCallback *New() 
    { return new vtkMyCallback; }
  virtual void Execute(vtkObject *caller, unsigned long, void*)
    {
      vtkBoxWidget *widget = reinterpret_cast<vtkBoxWidget*>(caller);
      vtkPlanes* planes = vtkPlanes::New();
      // Get the planes of the box widget and apply them to mapper
      widget->GetPlanes(planes);
      this->MaceActor->GetMapper()->SetClippingPlanes(planes);
      this->MaceActor->VisibilityOn();
      this->SelectActor->VisibilityOn();
    }
    vtkMyCallback() : MaceActor(0), SelectActor(0) {}
    vtkActor *MaceActor;
    vtkActor *SelectActor;
};
 
int main(int, char*[])
{

  // Create a mace out of filters.
  //
  vtkSmartPointer<vtkSphereSource> sphere =
    vtkSmartPointer<vtkSphereSource>::New();
  vtkSmartPointer<vtkConeSource> cone =
    vtkSmartPointer<vtkConeSource>::New();
  vtkSmartPointer<vtkGlyph3D> glyph =
    vtkSmartPointer<vtkGlyph3D>::New();
  glyph->SetInputConnection(sphere->GetOutputPort());
  glyph->SetSourceConnection(cone->GetOutputPort());
  glyph->SetVectorModeToUseNormal();
  glyph->SetScaleModeToScaleByVector();
  glyph->SetScaleFactor(0.25);

  // The sphere and spikes are appended into a single polydata.
  // This just makes things simpler to manage.
  vtkSmartPointer<vtkAppendPolyData> apd =
    vtkSmartPointer<vtkAppendPolyData>::New();
  apd->AddInputConnection(glyph->GetOutputPort());
  apd->AddInputConnection(sphere->GetOutputPort());
  
  vtkSmartPointer<vtkPolyDataMapper> maceMapper = 
    vtkSmartPointer<vtkPolyDataMapper>::New();
  maceMapper->SetInputConnection(apd->GetOutputPort());
 
  vtkSmartPointer<vtkLODActor> maceActor = 
    vtkSmartPointer<vtkLODActor>::New();
  maceActor->SetMapper(maceMapper);
  maceActor->VisibilityOn(); 
 
  // This portion of the code clips the mace with the vtkPlanes implicit
  // function. The clipped region is colored green.
  vtkSmartPointer<vtkPlanes> planes = 
      vtkSmartPointer<vtkPlanes>::New();
  vtkSmartPointer<vtkClipPolyData> clipper = 
    vtkSmartPointer<vtkClipPolyData>::New();
  clipper->GenerateClippedOutputOn();
  clipper->SetClipFunction(planes);
  clipper->SetInputConnection(apd->GetOutputPort());
  clipper->InsideOutOn();

  vtkSmartPointer<vtkPolyDataMapper> selectMapper =
    vtkSmartPointer<vtkPolyDataMapper>::New();
  selectMapper->SetInputConnection(clipper->GetClippedOutputPort());
  
  vtkSmartPointer<vtkLODActor> selectActor = 
    vtkSmartPointer<vtkLODActor>::New();
  selectActor->SetMapper(selectMapper);
  selectActor->GetProperty()->SetColor(0.0, 1.0, 0.0);
  selectActor->VisibilityOff();
  // Dirty trick to hide selectActor under the maceActor
  // where the dataset has not been clipped. Shouldn't
  // be necessary, since the clipped part should just be 
  // the part that lies outside the boxWidget, but doesn't
  // seem to follow that rationale
  selectActor->SetScale(0.99, 0.99, 0.99);

  // Create the RenderWindow, Renderer and both Actors
  vtkSmartPointer<vtkRenderer> ren1= 
    vtkSmartPointer<vtkRenderer>::New();
  ren1->AddActor(maceActor);
  ren1->AddActor(selectActor);
  ren1->SetBackground(0.1, 0.2, 0.4);
 
  vtkSmartPointer<vtkRenderWindow> renWin = 
    vtkSmartPointer<vtkRenderWindow>::New();
  renWin->AddRenderer(ren1);
  renWin->SetSize(300, 300);
 
  vtkSmartPointer<vtkRenderWindowInteractor> iren = 
    vtkSmartPointer<vtkRenderWindowInteractor>::New();
  iren->SetRenderWindow(renWin);
 
  vtkSmartPointer<vtkInteractorStyleTrackballCamera> style = 
    vtkSmartPointer<vtkInteractorStyleTrackballCamera>::New();
  iren->SetInteractorStyle(style);
 
  //
  // Here we use a vtkBoxWidget to clip the underlying maceActor
 
  // The place factor controls the initial size of the widget with 
  // respect to the bounding box of the input to the widget.
  vtkSmartPointer<vtkBoxWidget> boxWidget = 
    vtkSmartPointer<vtkBoxWidget>::New();
  boxWidget->SetInteractor(iren);
  boxWidget->SetPlaceFactor(1.25);
  boxWidget->GetPlanes(planes);
  boxWidget->InsideOutOn();
  boxWidget->SetInputConnection(glyph->GetOutputPort());
  boxWidget->PlaceWidget();


  vtkSmartPointer<vtkMyCallback> callback =
    vtkSmartPointer<vtkMyCallback>::New();
  boxWidget->AddObserver(vtkCommand::InteractionEvent, callback);
  callback->MaceActor = maceActor;
  callback->SelectActor = selectActor;
 
  boxWidget->On();
 
  iren->Initialize();
  iren->Start();
 
  return EXIT_SUCCESS;
}
-------------- next part --------------
A non-text attachment was scrubbed...
Name: ReverseBoxWidget.jpg
Type: image/jpeg
Size: 132814 bytes
Desc: not available
URL: <http://public.kitware.com/pipermail/vtkusers/attachments/20140618/34c5d83e/attachment-0001.jpg>
-------------- next part --------------
cmake_minimum_required(VERSION 2.8)
 
PROJECT(ReverseBoxWidgetExample)

#-----------------------------------------------------------------------------
# Find and use VTK libraries
#
find_package( VTK REQUIRED )
if( VTK_FOUND )
  include( ${VTK_USE_FILE} )
else( VTK_FOUND )
  message( FATAL_ERROR "This application requires VTK. One of these components is missing. Please verify configuration")
endif( VTK_FOUND )

  
add_executable(ReverseBoxWidgetExample ReverseBoxWidgetExample.cxx)
 
if(VTK_LIBRARIES)
  target_link_libraries(ReverseBoxWidgetExample ${VTK_LIBRARIES})
else()
  target_link_libraries(ReverseBoxWidgetExample vtkHybrid vtkWidgets)
endif()


More information about the vtkusers mailing list