VTK-vtkPolyDataNormals

Предисловие: В этом сообщении в блоге в основном описываются цель, метод использования и принцип реализации vtkPolyDataNormals, чтобы помочь большему количеству друзей понять и лучше применять vtk.

Оглавление

1. vtkPolyDataNormals

2. Пример использования

3. Принцип реализации


1. vtkPolyDataNormals

vtkPolyDataNormals может рассчитать точку данных полигональной сетки или направление ячейки (можно рассчитать только полигоны и треугольники, линии и вершины рассчитать нельзя).

Фильтры могут переупорядочивать полигоны, чтобы обеспечить согласованную ориентацию соседних полигонов. Острые кромки можно разделить и воспроизвести точки с отдельными нормалями, чтобы обеспечить резкое (визуализированное) определение поверхности.

Также возможно глобальное изменение направления нормали.

Задача алгоритма состоит в том, чтобы определить нормали для каждого полигона, а затем усреднить их по общим точкам. Когда появляются острые края, они сегментируются и создаются новые точки, чтобы предотвратить размытие краев (из-за затенения по Гуро).

*Цель 1: Направление ячейки может быть определено заново, чтобы гарантировать, что данные не имеют плохих контуров и плохих краев.

Примечание. Если SetComputePointNormals имеет значение True, графика будет повторно визуализирована с более гладкой поверхностью. Но после сохранения и повторного открытия его не существует. Чтобы инвертировать нормали глобально, SetComputePointNormals имеет значение True.

2. Пример использования

    vtkPolyData* pd;    
    vtkSmartPointer<vtkPolyDataNormals> pdNormals =
            vtkSmartPointer<vtkPolyDataNormals>::New();
    pdNormals->SetInputData(pd);
    pdNormals->ComputeCellNormalsOn();//ComputePointNormalsOn默认为on
    pdNormals->Update();

    vtkPointData* ptData = pdNormals->GetOutput()->GetPointData();
    vtkDataArray* ptNormals = pdNormals->GetOutput()->GetPointData()->GetNormals();

    //获取每个Cell中每个点的方向
    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] );
    }

    //获取每个Cell的方向
    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] );
        }
    }

3. Принцип реализации

1) Автоматически настроить нормали (AutoOrientNormals)

        Вот основная идея: у «крайнего левого» многоугольника нормаль, направленная наружу, должна быть обращена влево. Если нет, измените порядок вершин. Затем используйте его как начальное значение для других связанных полигонов. Чтобы найти самый левый многоугольник, сначала найдите самую левую точку и проверьте соседние многоугольники, чтобы увидеть, нормаль какого многоугольника «наиболее выровнена» с осью x. Этот процесс необходимо повторить для всех подключенных компонентов сетки.

А. Поместите все точки в очередь приоритетов, основываясь на координате x, чтобы мы могли найти самую левую точку.

б) Продолжайте повторять крайнюю левую точку и ячейки, связанные с этими точками, пока не будет обнаружено, что вектор нормали ячейки, связанной с определенной точкой, является ячейкой, ближайшей к оси x и не посещаемой. Используйте ячейку как исходную ячейку, чтобы пройти и найти связанного соседа в порядке точек.

Supongo que te gusta

Origin blog.csdn.net/qq_40041064/article/details/129665380
Recomendado
Clasificación