QT通过VTK切割STL模型后并着色 Mac

1.Mac下,QT如何通过VTK读取STL模型并着色,请参考我的上一篇博客QT通过VTK读取stl模型并着色 Mac
2.VTK的切割,有很多种,我这里选择的是基于plane的切割,也就是平面切割,首先你需要导入与切割相关的包

#include <vtkPlane.h>//用于创建面
#include <vtkPlaneCollection.h>//用于将定义的多个面集成到一个组里面
#include <vtkClipClosedSurface.h>//用于创建一个裁剪器
#include <vtkProperty.h>
#include <vtkClipPolyData.h>

3.定义一个切割平面

 double *center=polydata->GetCenter();//获取模型的中心
 vtkSmartPointer<vtkPlane> plane1 = vtkSmartPointer<vtkPlane>::New();//创建一个平面
 plane1->SetOrigin(center[0],center[1],center[2]);//设置面的中心
 plane1->SetNormal(0.0,1.0,1.0);//设置面的法向量

4.如果你有多个切割平面的话,可以用下面的代码将切割面结合在一个对象组里

  vtkSmartPointer<vtkPlaneCollection> planes = vtkSmartPointer<vtkPlaneCollection>::New();//创建一个面组的对象
  planes->AddItem(plane1);

5.开始设置与你切割相关的操作,包括创建一个切割器,以及切割的输入数据,切割的函数(也就是你定义的切割面)

  vtkSmartPointer<vtkClipPolyData>clipper = vtkSmartPointer<vtkClipPolyData>::New();
  clipper->SetInputData(cube);//设置切割源
   clipper->SetClipFunction(plane1);//设置切割函数
   clipper->GenerateClippedOutputOn();//如果没有这一行,那么切割完后将不会产生polydata数据
   clipper->Update();//更新切割操作

6.对切割后的数据,进行颜色映射

  //数据映射
    vtkSmartPointer<vtkPolyDataMapper> cubeMapper = vtkSmartPointer<vtkPolyDataMapper>::New();
    cubeMapper->SetInputData(clipper->GetOutput());//获取切割后的数据,作为颜色映射的数据输入源
    cubeMapper->SetScalarRange(0,polydata->GetNumberOfPoints()-1);
    cubeMapper->SetLookupTable(pColorTable);

这里附上main.cpp的完整代码(看到我的这么多注释,就知道我踩了多少坑??)

#include "mainwindow.h"
#include <QApplication>
#include <vtkAutoInit.h>
VTK_MODULE_INIT(vtkRenderingOpenGL2);
VTK_MODULE_INIT(vtkInteractionStyle);
VTK_MODULE_INIT(vtkRenderingFreeType);
//#define vtkRenderingCore_AUTOINIT 4(vtkInteractionStyle,vtkRenderingFreeType,vtkRenderingFreeTypeOpenGL2,vtkRenderingOpenGL2)
//#define vtkRenderingVolume_AUTOINIT 1(vtkRenderingVolumeOpenGL2)

#include <QDebug>//调试用的

#include <vtkVersion.h>
#include <vtkPlaneSource.h>
#include <vtkPolyData.h>
#include <vtkSTLReader.h>
#include <vtkSmartPointer.h>
#include <vtkPolyDataMapper.h>
#include <vtkActor.h>
#include <vtkCamera.h>
#include <vtkConeSource.h>
#include <vtkCellArray.h>
#include <vtkFloatArray.h>
#include "vtkPointData.h"
#include "vtkPoints.h"
#include "vtkPolyData.h"
#include "vtkPolyDataMapper.h"
#include <vtkRenderWindow.h>
#include <vtkRenderer.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkLookupTable.h>//定义颜色映射表

#include <vtkPlane.h>//用于创建面
#include <vtkPlaneCollection.h>//用于将定义的多个面集成到一个组里面
#include <vtkClipClosedSurface.h>//用于创建一个裁剪器
#include <vtkProperty.h>
#include <vtkClipPolyData.h>
using namespace std;

int main(int, char *[])
{

    std::string inputFilename="/Users/chentingxuan/Desktop/1.stl";//stl文件路径

    //读取stl文件
    vtkSmartPointer<vtkSTLReader> reader = vtkSmartPointer<vtkSTLReader>::New();
        reader->SetFileName(inputFilename.c_str());
        reader->Update();

  //创建对象
  vtkPolyData *cube = vtkPolyData::New();//立方体
  vtkPoints *points = vtkPoints::New();//顶点坐标
  vtkCellArray *polys=vtkCellArray::New();//单元数组

  //存储标量值
  vtkFloatArray *scalars = vtkFloatArray::New();

  vtkPolyData *polydata=reader->GetOutput();

  double *center=polydata->GetCenter();//获取模型的中心
  vtkSmartPointer<vtkPlane> plane1 = vtkSmartPointer<vtkPlane>::New();//创建一个平面
  plane1->SetOrigin(center[0],center[1],center[2]);//设置面的中心
  plane1->SetNormal(0.0,1.0,1.0);//设置面的法向量

  vtkSmartPointer<vtkPlaneCollection> planes = vtkSmartPointer<vtkPlaneCollection>::New();//创建一个面组的对象
  planes->AddItem(plane1);

  //用于动态创建二维数组,用于存储顶点的索引
  vtkIdType (*y)[3] = new vtkIdType[polydata->GetNumberOfCells()][3];

  //读取细胞单元,并将坐标的索引赋值给二维数组y
  for(int i =0;i<polydata->GetNumberOfCells();i++)
  {
      //l1=polydata->GetCell(i)->GetPointIds();
      y[i][0]=polydata->GetCell(i)->GetPointIds()->GetId(0);

      y[i][1]=polydata->GetCell(i)->GetPointIds()->GetId(1);

      y[i][2]=polydata->GetCell(i)->GetPointIds()->GetId(2);

  }

  //存储顶点
  for(int i=0;i<polydata->GetNumberOfPoints();i++)
  {
      double x[]={0,0,0};
      polydata->GetPoint(i,x);//获取顶点坐标
      points->InsertPoint(i,x);//将顶点坐标插入到vtkPoints定义的points
  }

  //设定单元
  for(int i=0;i<polydata->GetNumberOfCells();i++)
  {
     polys->InsertNextCell(3,y[i]);
  }
  //存储每个顶点的标量值,也就是颜色的索引值,这里暂时是以顶点的先后顺序来设定的
  for(int i=0;i<polydata->GetNumberOfPoints();i++)
  {
      scalars->InsertTuple1(i,i);
  }

  //创建多边形数据
  cube->SetPoints(points);
  //设定单元类型为多边形
  cube->SetPolys(polys);
  //设定每个顶点的标量值
  cube->GetPointData()->SetScalars(scalars);

  points->Delete();
  polys->Delete();
  scalars->Delete();

  //定义颜色映射表
  vtkLookupTable *pColorTable = vtkLookupTable::New();

  //设置颜色表中的颜色,下列两种方式都可以
  /*
  pColorTable->SetNumberOfColors(4);
  pColorTable->SetTableValue(0,1.0,0.0,0.0,1.0);
  pColorTable->SetTableValue(0,1.0,0.0,0.0,1.0);
  pColorTable->SetTableValue(1,0.0,1.0,0.0,1.0);
  pColorTable->SetTableValue(2,1.0,1.0,0.0,1.0);
  pColorTable->SetTableValue(3,0.0,0.0,1.0,1.0);
  */
  //设置颜色表中的颜色
  pColorTable->SetNumberOfColors(256);
  pColorTable->SetHueRange(0.67, 0.0);        //色调范围从红色到蓝色

  pColorTable->Build();

//  vtkSmartPointer<vtkClipClosedSurface> clipper = vtkSmartPointer<vtkClipClosedSurface>::New();//创建一个裁剪器
//  clipper->SetInputData(polydata);//设置需要裁剪的数据
//  clipper->SetClippingPlanes(planes);//设置裁剪的面
  /*
  *设置活动平面,以便从该平面进行裁剪
  *以不同颜色显示。如果没有活动,则将其设置为-1,*默认值是-1。
  */
//  clipper->SetActivePlaneId(0);
//  clipper->SetScalarModeToColors();//设置颜色
  //如果要设置颜色,可以用下面的代码。三种状态,对应三种颜色
  /*
  clipper->SetScalarModeToColors();
   clipper->SetClipColor(0.8900, 0.8100, 0.3400); // banana
   clipper->SetBaseColor(1.0000, 0.3882, 0.2784); // tomato
   clipper->SetActivePlaneColor(0.6400, 0.5800, 0.5000); // beige
*/

  vtkSmartPointer<vtkClipPolyData>clipper = vtkSmartPointer<vtkClipPolyData>::New();
  clipper->SetInputData(cube);//设置切割源
   clipper->SetClipFunction(plane1);//设置切割函数
   clipper->GenerateClippedOutputOn();//如果没有这一行,那么切割完后将不会产生polydata数据
   clipper->Update();//更新切割操作
  //数据映射
    vtkSmartPointer<vtkPolyDataMapper> cubeMapper = vtkSmartPointer<vtkPolyDataMapper>::New();
    cubeMapper->SetInputData(clipper->GetOutput());//获取切割后的数据,作为颜色映射的数据输入源
    cubeMapper->SetScalarRange(0,polydata->GetNumberOfPoints()-1);
    cubeMapper->SetLookupTable(pColorTable);

//cubeMapper->SetInputConnection(clipper->GetOutputPort());

    //cubeMapper->SetInputConnection(clipper->GetOutputPort());//将裁剪器与mapper连接起来

    vtkActor *cubeActor = vtkActor::New();
    cubeActor->SetMapper(cubeMapper);
    //cubeActor->GetProperty()->SetInterpolationToFlat();//不会在边缘周围平滑vtkActor的像素。

  // Create a renderer(渲染器), render window and interactor(渲染窗口)
  vtkSmartPointer<vtkRenderer> renderer = vtkSmartPointer<vtkRenderer>::New();
  vtkSmartPointer<vtkRenderWindow> renderWindow = vtkSmartPointer<vtkRenderWindow>::New();
  renderWindow->AddRenderer(renderer);
  renderWindow->SetSize(1300,1300);//设置窗口大小
  vtkSmartPointer<vtkRenderWindowInteractor> renderWindowInteractor = vtkSmartPointer<vtkRenderWindowInteractor>::New();
  renderWindowInteractor->SetRenderWindow(renderWindow);

  // Add the actors to the scene
  renderer->AddActor(cubeActor);
  renderer->SetBackground(.1,.2,.3); // Background color dark blue

  // Render and interact
  renderWindow->Render();
  renderWindowInteractor->Start();

  return EXIT_SUCCESS;
}

7.运行结果如下:
在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值