文章目录
- 一,vtkPolyData、cell、point
- 1) 例子
- 2) vtkPolyData、vtkCell、vtkPoints
- 二,vtkNew<>与vtkSmartPointer<>的区别:
- 三,补充
一,vtkPolyData、cell、point
1) 例子
/*** vtkNew 是一个类模板* vtkNew<> 是一个简单的 RAII(Resource Acquisition Is Initialization)(资源获取即初始化)类模板,用于在堆上创建对象,并负责对象的销毁。使用 vtkNew<> 创建的对象会自动在作用域结束时被销毁,无需手动调用 delete。** 你知道什么是类模板,什么是模板类吗?* 从字面意思看,类模板是一个模板,即class template;模板类是一个类,即 template class。* 简单的来讲:类模板就是一个定义,不能直接拿来用,还需要进行实例化,然后模板类就是类模板的实例化,类中的参数被实际类型所替代;(再简单来讲:没是实例化的叫类模板,实例化后的类模板是模板类)* 即:vtkNew是一个类模板,然后vtkNew<vtkNameColors>是模板类◆ vtkColor3d GetColor3d(const vtkStdString & name ):按名称获取颜色。
该名称被视为不区分大小写。颜色作为vtkColor3d类返回。如果找不到颜色,则返回黑色。*/vtkNew<vtkNamedColors> colors;/**** vtkPoints:vtkPoints表示3D点。vtkPoints的数据模型是一个vx-vy-vz三元组数组,可通过(点或单元)id访问。◆ vtkIdType vtkPoints::InsertNextPoint ( double x,double y,double z )其实还都float的方法,但是cpp在你不指定的情况下,小数都是double类型源码:inline vtkIdType vtkPoints::InsertNextPoint(double x, double y, double z){double p[3] = { x, y, z };return this->Data->InsertNextTuple(p);}//vtkDataArray* Data; // Array which represents data//InsertNextTuple的定义:
vtkIdType vtkDataArray::InsertNextTuple ( vtkIdType srcTupleIdx,
vtkAbstractArray * source
) 然后这个方法继承自vtkAbstractArray类virtual vtkIdType vtkAbstractArray::InsertNextTuple ( vtkIdType srcTupleIdx,
vtkAbstractArray * source
) 将srcTupleIdx中的元组插入到源数组的末尾。
注意,根据需要执行存储器分配以保持数据。返回插入数据的元组索引。****/vtkNew<vtkPoints> points;//构成图形的四个点points->InsertNextPoint(0.0, 0.0, 0.0);points->InsertNextPoint(1.0, 0.0, 0.0);points->InsertNextPoint(1.0, 1.0, 0.0);points->InsertNextPoint(0.0, 1.0, 0.0);// Create the polygon
/**
*vtkPolygon:表示n边多边形的像元
vtkPolygon是vtkCell的具体实现,用于表示2D n边多边形。多边形不能有任何内部孔,也不能自相交。定义n个点按逆时针方向排列的多边形;不要重复最后一点。
* GetPointIds函数继承自vtkCell类:vtkIdList* vtkCell::GetPointIds ( )
返回定义单元格的点ID列表。
vtkIdList* GetPointIds() { return this->PointIds; }void vtkIdList::SetNumberOfIds ( vtkIdType number )
:指定此对象要保存的id数。void vtkIdList::SetId ( vtkIdType i,
vtkIdType vtkid )
:在位置i设置id。
不做范围检查,所以它比InsertId快一点。确保在使用SetId()之前使用SetNumberOfIds()分配内存。typedef long long vtkIdType;typedef long vtkIdType;typedef int vtkIdType;
void SetId(vtkIdType i, vtkIdType vtkid) VTK_EXPECTS(0 <= i && i < GetNumberOfIds())
{this->Ids[i] = vtkid;
}//解释:VTK_EXPECTS(0 <= i && i < GetNumberOfIds()): 这是一个断言宏,用于在运行时检查条件是否满足。在这里,断言确保传入的索引值 i 大于等于 0 并且小于多边形点索引数组的大小。
**/vtkNew<vtkPolygon> polygon;polygon->GetPointIds()->SetNumberOfIds(4); // make a quadpolygon->GetPointIds()->SetId(0, 0);polygon->GetPointIds()->SetId(1, 1);polygon->GetPointIds()->SetId(2, 2);polygon->GetPointIds()->SetId(3, 3);//如果你对这里有疑问:可以看一下下面的图1与图2/**************vtkCellArray : 对象来表示像元连通性
tkCellArray 用于表示数据集的拓扑结构,它通过一个显式的连接表来存储每个单元所包含的点的标识。在内部,连接表由两个数组表示:Offsets 和 Connectivity。Offsets 是一个长度为 [numCells+1] 的数组,表示每个单元的点在 Connectivity 数组中的起始索引位置。最后一个值始终是 Connectivity 数组的长度。Connectivity 数组存储每个单元的点标识列表。因此,对于包含 2 个三角形、一个四边形和一条线的数据集,内部数组将如下所示:我不太理解下面这个拓扑结构和当前状态的vtkCellArray是什么意思??????????????????????????????????拓扑结构:
单元 0: 三角形 | 点标识:{0, 1, 2}
单元 1: 三角形 | 点标识:{5, 7, 2}
单元 2: 四边形 | 点标识:{3, 4, 6, 7}
单元 3: 线 | 点标识:{5, 8}vtkCellArray(当前状态):
Offsets: {0, 3, 6, 10, 12}
Connectivity: {0, 1, 2, 5, 7, 2, 3, 4, 6, 7, 5, 8}vtkIdType vtkCellArray::InsertNextCell ( vtkCell * cell )
作用:Insert a cell object.
Return the cell id of the cell.
源码:
inline vtkIdType vtkCellArray::InsertNextCell(vtkCell* cell){vtkIdList* pts = cell->GetPointIds();return this->Visit(vtkCellArray_detail::InsertNextCellImpl{}, pts->GetNumberOfIds(), pts->GetPointer(0));}******************/vtkNew<vtkCellArray> polygons;polygons->InsertNextCell(polygon);//vtkNew<vtkPolygon> polygon;polygon是vtkNew<vtkPolygon>,但是可以作为vtkCell*类型的参数(因为vtkPolygon是vtkCell的子类)
//总结一下:这两行代码的作用是存储数据集合的拓扑结构,即单元(cell)的连接关系,polygon就是我们写好的拓扑结构// Create a PolyDatavtkNew<vtkPolyData> polygonPolyData;polygonPolyData->SetPoints(points);//将坐标点给到PolydatapolygonPolyData->SetPolys(polygons);//再将这些坐标的拓扑结构给到Polydata(我理解的是坐标的连接顺序)//既然知道了坐标,也知道了坐标怎么连接,那么这个Polydata就算封装完成了//然后就是:通过mapper得到可渲染的图元数据,再通过actor得到可渲染的图元,最后将actor加入到渲染器// Create a mapper and actorvtkNew<vtkPolyDataMapper> mapper;mapper->SetInputData(polygonPolyData);vtkNew<vtkActor> actor;actor->SetMapper(mapper);actor->GetProperty()->SetColor(colors->GetColor3d("Silver").GetData());// VisualizevtkNew<vtkRenderer> renderer;vtkNew<vtkRenderWindow> renderWindow;renderWindow->SetWindowName("Polygon");renderWindow->AddRenderer(renderer);vtkNew<vtkRenderWindowInteractor> renderWindowInteractor;renderWindowInteractor->SetRenderWindow(renderWindow);renderer->AddActor(actor);renderer->SetBackground(colors->GetColor3d("Salmon").GetData());//设置背景颜色renderWindow->Render();renderWindowInteractor->Start();
2) vtkPolyData、vtkCell、vtkPoints
https://vtk.org/doc/nightly/html/classvtkPolyData.html
https://vtk.org/doc/nightly/html/classvtkCell.html
https://vtk.org/doc/nightly/html/classvtkPoints.html
二,vtkNew<>与vtkSmartPointer<>的区别:
举个例子:同样是构造窗口交互器
vtkSmartPointer<>的写法:
vtkSmartPointer<vtkRenderWindowInteractor> renderWindowInteractor =vtkSmartPointer<vtkRenderWindowInteractor>::New();vtkNew<vtkRenderWindowInteractor>的写法:
vtkNew<vtkRenderWindowInteractor> renderWindowInteractor;
简单的来说 , vtkNew没有引用计数,而vtkSmartPointer有引用计数的机制
vtkNew和vtkSmartPointer都用于VTK(可视化工具包)中对象的创建和管理。但是,两者之间确实存在着一些主要的区别 :
-
vtkNew 用于在堆上创建一个新的 VTK 对象并保持其所有权。当 vtkNew 对象超出范围时,它将删除其相关联的 VTK 对象。但请注意,vtkNew 不支持引用计数。
-
相反,vtkSmartPointer 是一个智能指针,用于维护VTK对象的引用计数。当一个 vtkSmartPointer 指向一个 VTK 对象时,该对象的引用计数增加1。当 vtkSmartPointer 在超出范围或被重新分配到另一个对象时,原来的VTK对象的引用计数减少1。如果VTK对象的引用计数变为0,那么这个对象就会被删除。
所以,在需要使用引用计数机制进行内存管理的情况下,我们通常会选择使用 vtkSmartPointer 而不是 vtkNew。
然后 , vtk的作者 更加支持使用vtkSmartPointer<>
“ 对于 V T K 库中的对象管理,推荐使用 v t k S m a r t P o i n t e r < > 来避免内存泄漏和悬挂指针等问题。 对于VTK库中的对象管理,推荐使用vtkSmartPointer<>来避免内存泄漏和悬挂指针等问题。 对于VTK库中的对象管理,推荐使用vtkSmartPointer<>来避免内存泄漏和悬挂指针等问题。”
三,补充
这里还有一篇大佬的文章:把上面的那个搞懂了,下面这个大佬写的网格分割的例子就不那么难理解了
https://blog.csdn.net/liushao1031177/article/details/118151714#comments_29088179