CAD或CAE中的常见搭配,是使用OCC创建几何对象,然后将OCC的数据导给vtk,vtk对几何数据进行解析转换为自己的数据然后进行显示。
#include <TopoDS_Shape.hxx>
#include <TopExp_Explorer.hxx>
#include <qlist.h>
#include <vtkSmartPointer.h>
#include <vtkPolyData.h>
#include <vtkAppendPolyData.h>
#include <IVtkOCC_Shape.hxx>
#include <IVtkTools_ShapeDataSource.hxx>
#include <vtkCleanPolyData.h>
#include <vtkTriangle.h>
#include <vtkPolyDataNormals.h>
//解析边或点
vtkSmartPointer<vtkPolyData> ParseGeometry::parseGeometry(const TopoDS_Shape& shape)
{
//OCC将TopoDS_Shape 转换为vtk的接口类
IVtkOCC_Shape::Handle aShapeImpl = new IVtkOCC_Shape(shape);
//vtk解析OCC的接口类
vtkSmartPointer<IVtkTools_ShapeDataSource> DS = vtkSmartPointer<IVtkTools_ShapeDataSource>::New();
DS->SetShape(aShapeImpl);
DS->Update();
vtkPolyData* p = DS->GetOutput();
const int ncell = p->GetNumberOfCells();
//进行检查,如果是边,检查单元是否小于2
if ( shape.ShapeType() == TopAbs_EDGE && ncell < 2) {
return nullptr;
}
//是点则检查是否小于1
if (shape.ShapeType() == TopAbs_VERTEX && ncell < 1) {
return nullptr;
}
vtkSmartPointer<vtkPolyData> poly = vtkSmartPointer<vtkPolyData>::New();
poly->DeepCopy(p);
return poly;
}
//解析面
vtkSmartPointer<vtkPolyData> ParseGeometry::parseGeometryFace(const TopoDS_Shape& shape)
{
//和上方一样
IVtkOCC_Shape::Handle aShapeImpl = new IVtkOCC_Shape(shape);
vtkSmartPointer<IVtkTools_ShapeDataSource> DS = vtkSmartPointer<IVtkTools_ShapeDataSource>::New();
DS->SetShape(aShapeImpl);
//进行数据清理
vtkSmartPointer<vtkCleanPolyData> cleanFilter = vtkSmartPointer<vtkCleanPolyData>::New();
cleanFilter->SetInputConnection(DS->GetOutputPort());
cleanFilter->Update();
//将数据赋予给tpolys
vtkSmartPointer<vtkPolyData> tpolys = vtkSmartPointer<vtkPolyData>::New();
vtkPolyData* tpolydata = cleanFilter->GetOutput();
const int np = tpolydata->GetNumberOfPoints();
const int nc = tpolydata->GetNumberOfCells();
//赋予点
vtkPoints* points = vtkPoints::New();
for (int i = 0; i < np; i++) {
double* coor = tpolydata->GetPoint(i);
points->InsertNextPoint(coor);
}
tpolys->SetPoints(points);
//赋予单元
vtkCellArray* cells = vtkCellArray::New();
for (int i = 0; i < nc; ++i) {
vtkCell* cell = tpolydata->GetCell(i);
vtkIdList* ceid = cell->GetPointIds();
if (ceid->GetNumberOfIds() == 3) {
vtkTriangle* triangle = vtkTriangle::New();
triangle->DeepCopy(cell);
cells->InsertNextCell(triangle);
}
}
tpolys->SetPolys(cells);
//计算法向量
vtkSmartPointer<vtkPolyDataNormals> normals = vtkSmartPointer<vtkPolyDataNormals>::New();
normals->SetInputData(tpolys);
normals->FlipNormalsOn();
normals->Update();
const int ncell = facePoly->GetNumberOfCells();
if (ncell < 1) {
return nullptr;
}
vtkPolyData* facePoly = normals->GetOutput();
vtkSmartPointer<vtkPolyData> resPoly = vtkSmartPointer<vtkPolyData>::New();
resPoly->DeepCopy(facePoly);
return resPoly;
}