Volume 多边形裁剪测试

vtk自带了一个Volume剪切的例子, 可以用隐函数确定的剪切面裁剪vtkImageData.

本人对该例子代码略加修改,剪切口为一个封闭的梯形。其代码和配置文件如下。

目录

ClipVolume.cxx

CMakeLists.txt

运行结果


ClipVolume.cxx

// This program draws a checkerboard and clips it with two planes.

#include <vtkActor.h>
#include <vtkCamera.h>
#include <vtkCellData.h>
#include <vtkClipVolume.h>
#include <vtkColor.h>
#include <vtkDataSetMapper.h>
#include <vtkDoubleArray.h>
#include <vtkExecutive.h>
#include <vtkImageData.h>
#include <vtkImageMapToColors.h>
#include <vtkInteractorStyleSwitch.h>
#include <vtkLookupTable.h>
#include <vtkMapper.h>
#include <vtkNamedColors.h>
#include <vtkNew.h>
#include <vtkPlanes.h>
#include <vtkPointData.h>
#include <vtkPoints.h>
#include <vtkProperty.h>
#include <vtkRenderStepsPass.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkRenderer.h>

namespace {

constexpr auto IMAGESIZE{64};  // number of checkerboard squares on a side
constexpr auto CUBESIZE{20.0}; // physical linear dimension of entire system

// Color for the checkerboard image
constexpr auto DIM{0.5}; // amount to dim the dark squares by

// Offsets for clipping planes with normals in the X and Y directions
constexpr auto XOFFSET{8};
constexpr auto YOFFSET{8};

///

// Make the image data. A checkerboard pattern is used for
// simplicity.
vtkSmartPointer<vtkImageData> makeImage(int n, vtkColor3d fillColor,
                                        vtkColor3d checkerColor);
} // namespace

int main(int, char*[])
{

  vtkMapper::SetResolveCoincidentTopologyToPolygonOffset();

  // Define colors
  vtkNew<vtkNamedColors> colors;
  vtkColor3d backgroundColor = colors->GetColor3d("Wheat");
  vtkColor3d checkerColor = colors->GetColor3d("Tomato");
  vtkColor3d fillColor = colors->GetColor3d("Banana");

  vtkNew<vtkRenderer> renderer;
  renderer->SetBackground(backgroundColor.GetData());

  vtkNew<vtkRenderWindow> renderWindow;
  renderWindow->AddRenderer(renderer);
  renderWindow->SetSize(640, 480);

  vtkNew<vtkRenderWindowInteractor> interactor;
  vtkNew<vtkInteractorStyleSwitch> style;
  interactor->SetInteractorStyle(style);
  interactor->SetRenderWindow(renderWindow);

  auto image = makeImage(IMAGESIZE, fillColor, checkerColor);

  // Clipping planes in the X and Y direction.
  vtkNew<vtkDoubleArray> normals;
  vtkNew<vtkPoints> clipPts;
  normals->SetNumberOfComponents(3);
  double xnorm[3] = {-1., -0.3, 0.};
  double lnorm[3] = { -0.5, -0.5, 0 };
  double ynorm[3] = {-0.3, -1., 0.};
  double snorm[3] = { 0.5, 0.5, 0 };
  double xpt[3] = {XOFFSET, 0., 0.};
  double lpt[3] = {XOFFSET + 5, 0, 0 };
  double ypt[3] = {0., YOFFSET, 0.};
  double spt[3] = {XOFFSET + 12, 0, 0 };
  normals->InsertNextTuple(xnorm);
  normals->InsertNextTuple(lnorm);
  normals->InsertNextTuple(ynorm);
  normals->InsertNextTuple(snorm);
  clipPts->InsertNextPoint(xpt);
  clipPts->InsertNextPoint(lpt);
  clipPts->InsertNextPoint(ypt);
  clipPts->InsertNextPoint(spt);
  vtkNew<vtkPlanes> clipPlanes;
  clipPlanes->SetNormals(normals);
  clipPlanes->SetPoints(clipPts);

  vtkNew<vtkClipVolume> clipper;
  clipper->SetClipFunction(clipPlanes);
  clipper->SetInputData(image);

  vtkNew<vtkDataSetMapper> imageMapper;
  vtkNew<vtkActor> imageActor;
  imageActor->SetMapper(imageMapper);
  renderer->AddViewProp(imageActor);
  imageMapper->SetInputConnection(clipper->GetOutputPort());

  renderer->ResetCamera();
  renderer->GetActiveCamera()->Azimuth(120);
  renderer->GetActiveCamera()->Elevation(30);
  renderer->ResetCameraClippingRange();
  renderWindow->SetWindowName("ClipVolume");
  renderWindow->Render();

  interactor->Start();

  return EXIT_SUCCESS;
  ;
}

namespace {
// Make the image data. A checkerboard pattern is used for
// simplicity.
vtkSmartPointer<vtkImageData> makeImage(int n, vtkColor3d fillColor,
                                        vtkColor3d checkerColor)
{
  vtkNew<vtkImageData> image0;
  image0->SetDimensions(n, n, n);
  image0->AllocateScalars(VTK_UNSIGNED_CHAR, 1);
  image0->SetSpacing(CUBESIZE / n, CUBESIZE / n, CUBESIZE / n);
  int checkerSize = n / 8;
  for (int z = 0; z < n; z++)
  {
    for (int y = 0; y < n; y++)
    {
      for (int x = 0; x < n; x++)
      {
        unsigned char* ptr = (unsigned char*)image0->GetScalarPointer(x, y, z);
        *ptr = (x / checkerSize + y / checkerSize + z / checkerSize) %
            2; // checkerboard
      }
    }
  }

  vtkNew<vtkLookupTable> lut;
  lut->SetNumberOfTableValues(2);
  lut->SetTableRange(0, 1);
  lut->SetTableValue(0, fillColor.GetRed(), fillColor.GetGreen(),
                     fillColor.GetBlue(), 1.0);
  lut->SetTableValue(1, checkerColor.GetRed(), checkerColor.GetGreen(),
                     checkerColor.GetBlue(), 1.0);

  auto map = vtkSmartPointer<vtkImageMapToColors>::New();
  map->SetLookupTable(lut);
  map->SetOutputFormatToRGBA();
  map->SetInputData(image0);
  map->GetExecutive()->Update();

  return map->GetOutput();
}

} // namespace

CMakeLists.txt

cmake_minimum_required(VERSION 3.12 FATAL_ERROR)

project(ClipVolume)

find_package(VTK COMPONENTS 
  vtkCommonColor
  vtkCommonCore
  vtkCommonDataModel
  vtkCommonExecutionModel
  vtkFiltersGeneral
  vtkImagingCore
  vtkInteractionStyle
  vtkRenderingContextOpenGL2
  vtkRenderingCore
  vtkRenderingFreeType
  vtkRenderingGL2PSOpenGL2
  vtkRenderingOpenGL2
  QUIET
)

if (NOT VTK_FOUND)
  message("Skipping ClipVolume: ${VTK_NOT_FOUND_MESSAGE}")
  return()
endif()
message (STATUS "VTK_VERSION: ${VTK_VERSION}")
if (VTK_VERSION VERSION_LESS "8.90.0")
  # old system
  include(${VTK_USE_FILE})
  add_executable(ClipVolume MACOSX_BUNDLE ClipVolume.cxx )
  target_link_libraries(ClipVolume PRIVATE ${VTK_LIBRARIES})
else()
  # Prevent a "command line is too long" failure in Windows.
  set(CMAKE_NINJA_FORCE_RESPONSE_FILE "ON" CACHE BOOL "Force Ninja to use response files.")
  add_executable(ClipVolume MACOSX_BUNDLE ClipVolume.cxx )
  target_link_libraries(ClipVolume PRIVATE ${VTK_LIBRARIES})
  # vtk_module_autoinit is needed
  vtk_module_autoinit(
    TARGETS ClipVolume
    MODULES ${VTK_LIBRARIES}
    )
endif()

运行结果

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值