【VTK】vtkPolyDataNormals 计算法向量

网友投稿 1163 2022-08-27

【VTK】vtkPolyDataNormals 计算法向量

【VTK】vtkPolyDataNormals 计算法向量

vtkPolyDataNormals可以用于计算poly data中points和cell的法向量,方便处理一些数据集。 下面的例子显示了vtkPolyDataNormals作用在正方体和球体的效果。

注:为了不影响阅读体验,此文仅展示关键代码,所有例子的完整代码和输出可以浏览:​​【VTK】vtkPolyDataNormals example ​​

正方体

人为构造6个面的正方体,每一个cell是一个正方形。使用points和polys构造polydata,之后使用vtkPolyDataNormals 处理polydata。由此我们能够得到point的在mesh上的的normal和cell的normal。

int main(int argc, char *argv[]){// ... vtkSmartPointer pd = vtkSmartPointer::New(); pd->SetPolys( polys ); pd->SetPoints( points ); vtkSmartPointer mapper = vtkSmartPointer::New(); mapper->SetInputData( pd ); vtkSmartPointer surfaceActor = vtkSmartPointer::New(); surfaceActor->SetMapper( mapper ); vtkSmartPointer pdNormals = vtkSmartPointer::New(); pdNormals->SetInputData( surfaceActor->GetMapper()->GetInput() ); pdNormals->ComputeCellNormalsOn(); pdNormals->Update(); vtkPointData* ptData = pdNormals->GetOutput()->GetPointData(); vtkDataArray* ptNormals = pdNormals->GetOutput()->GetPointData()->GetNormals(); cout << "For points in every cell: \n"; cout << ptNormals->GetNumberOfTuples() << endl; for( int i = 0; i < ptNormals->GetNumberOfTuples(); ++i ) { double value[3]; ptNormals->GetTuple( i, value ); printf( "Value: (%lf, %lf, %lf)\n", value[0], value[1], value[2] ); } cout << "For cells: \n"; if( pdNormals->GetOutput()->GetCellData() && pdNormals->GetOutput()->GetCellData()->GetNormals() ) { vtkDataArray* cellNormals = pdNormals->GetOutput()->GetCellData()->GetNormals(); cout << cellNormals->GetNumberOfTuples() << endl; for( int i = 0; i < cellNormals->GetNumberOfTuples(); ++i ) { double value[3]; cellNormals->GetTuple( i, value ); printf( "Value: (%lf, %lf, %lf)\n", value[0], value[1], value[2] ); } }//...}

output:

For points in every cell: 24Value: (0.000000, 1.000000, 0.000000)Value: (0.000000, 1.000000, 0.000000)Value: (0.000000, 1.000000, 0.000000)Value: (0.000000, 1.000000, 0.000000)Value: (0.000000, -1.000000, 0.000000)Value: (0.000000, -1.000000, 0.000000)//...Value: (-1.000000, 0.000000, 0.000000)Value: (-1.000000, 0.000000, 0.000000)Value: (0.000000, 0.000000, 1.000000)For cells:6Value: (0.000000, 1.000000, 0.000000)Value: (0.000000, -1.000000, 0.000000)Value: (1.000000, 0.000000, 0.000000)Value: (0.000000, 0.000000, -1.000000)Value: (-1.000000, 0.000000, 0.000000)Value: (0.000000, 0.000000, 1.000000)

关于计算point的normal,本例子的输出中有24条,这是因为同一个点在不同的cell上可能具有不同的normal,观察本文最后的动态图有助于理解。 后面的cell normal有6条输出就很好理解了,因为这是一个6面体。

球类

以sphere为例,进行同样的操作。

int main(int argc, char *argv[]){ vtkSmartPointer sphere = vtkSmartPointer::New(); vtkSmartPointer mapper = vtkSmartPointer::New(); mapper->SetInputConnection( sphere->GetOutputPort() ); vtkSmartPointer surfaceActor = vtkSmartPointer::New(); surfaceActor->SetMapper( mapper ); vtkSmartPointer pdNormals = vtkSmartPointer::New(); pdNormals->SetInputConnection( sphere->GetOutputPort() ); pdNormals->ComputeCellNormalsOn(); pdNormals->Update(); vtkPointData* ptData = pdNormals->GetOutput()->GetPointData(); if( ptData ) { vtkDataArray* ptNormals = pdNormals->GetOutput()->GetPointData()->GetNormals(); if( ptNormals ) { cout << "For points in every cell: \n"; cout << ptNormals->GetNumberOfTuples() << endl; for( int i = 0; i < ptNormals->GetNumberOfTuples(); ++i ) { double value[3]; ptNormals->GetTuple( i, value ); printf( "Value: (%lf, %lf, %lf)\n", value[0], value[1], value[2] ); } } } cout << "For cells: \n"; if( pdNormals->GetOutput()->GetCellData() && pdNormals->GetOutput()->GetCellData()->GetNormals() ) { vtkDataArray* cellNormals = pdNormals->GetOutput()->GetCellData()->GetNormals(); cout << cellNormals->GetNumberOfTuples() << endl; for( int i = 0; i < cellNormals->GetNumberOfTuples(); ++i ) { double value[3]; cellNormals->GetTuple( i, value ); printf( "Value: (%lf, %lf, %lf)\n", value[0], value[1], value[2] ); } }// ... return EXIT_SUCCESS;}

output:

For points in every cell:66Value: (0.000000, 0.000000, 1.000000)Value: (0.000000, 0.000000, -1.000000)Value: (0.471163, 0.052265, 0.880496)Value: (0.779360, 0.017869, 0.626322)// ...Value: (0.887900, -0.367780, -0.276354)For cells:96Value: (0.221582, 0.091782, 0.970813)Value: (0.091782, 0.221582, 0.970813)// ...Value: (0.603683, -0.250054, -0.756994)Value: (0.603683, -0.250054, -0.756994)

计算points的normal,使用圆锥显示出来。 这里需要使用到vtkGlyph3D,将cone和每一个normal进行绑定。 详细的使用如下:

int main(int argc, char *argv[]){//... vtkSmartPointer cone = vtkSmartPointer::New(); cone->SetResolution( 6 ); vtkSmartPointer transform = vtkSmartPointer::New(); transform->RotateY( 180 ); // make vertex outside vtkSmartPointer transformF = vtkSmartPointer::New(); transformF->SetInputConnection( cone->GetOutputPort() ); transformF->SetTransform( transform ); vtkSmartPointer glyph = vtkSmartPointer::New(); glyph->SetInputConnection( pdNormals->GetOutputPort() ); glyph->SetSourceConnection( transformF->GetOutputPort() ); // source => transform => graph3D glyph->SetVectorModeToUseNormal(); glyph->SetScaleModeToScaleByVector(); glyph->SetScaleFactor( 0.1 ); vtkSmartPointer spikeMapper = vtkSmartPointer::New(); spikeMapper->SetInputConnection( glyph->GetOutputPort() ); vtkSmartPointer spikeActor = vtkSmartPointer::New(); spikeActor->SetMapper( spikeMapper ); spikeActor->GetProperty()->SetColor( 0.0, 0.79, 0.34 ); // Add the actors to the renderer, set the background and size ren->AddActor( spikeActor );// ...}

(我们可以使用key W、S进行网格和平面模式的切换)

吐槽:CSDN Markdown都没法设置图片居中吗?

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:如何选择适合自己的编程语言(自学编程哪种语言好入门)
下一篇:learn vtk by Python script on mac
相关文章

 发表评论

暂时没有评论,来抢沙发吧~