厚表面有VTK

时间:2017-04-28 14:16:06

标签: c++ mesh vtk marching-cubes

我正在尝试从地面激光扫描仪获得的点云生成三角形网格。我使用VTK库的行进立方体算法。当我想象生成的网格时,它看起来像一个厚的表面,如下图所示:

enter image description here

然而,我期待看到它如下图所示:

enter image description here

你能帮我解决一下这个问题吗?我想生成网格,如第二张图所示。 我期待着您的回复

顺便说一句,我的代码是:

int main(int argc, char* argv[])
{    
    //nokta bulutu
    vtkSmartPointer<vtkSimplePointsReader> reader =
        vtkSmartPointer<vtkSimplePointsReader>::New();
    reader->SetFileName("SIL_ARKA_ENTIRE.xyz");
    reader->Update();
    vtkPolyData* polydata = reader->GetOutput();    

    FILE *Normaloku = fopen("SIL_ARKA_ENTIRE_NORMALS.xyz", "r");
    int sirasi;
    vtkSmartPointer<vtkDoubleArray> pointNormalsArray =
        vtkSmartPointer<vtkDoubleArray>::New();
    pointNormalsArray->SetNumberOfComponents(3); //3d normals (ie x,y,z)
    pointNormalsArray->SetNumberOfTuples(polydata->GetNumberOfPoints());
    double nokta_normali[3];
    for (sirasi = 0; sirasi < 652802; sirasi++)
    {
        fscanf(Normaloku, "%lf  %lf &lf", &nokta_normali[0], &nokta_normali[1], &nokta_normali[2]);
        pointNormalsArray->SetTuple(sirasi, nokta_normali);
    }
    polydata->GetPointData()->SetNormals(pointNormalsArray);
    fclose(Normaloku);
    std::cout << "eklenen işlem bitti" << std::endl;

    double isoValue;
    double bounds[6];    
    polydata->GetBounds(bounds);
    for (unsigned int i = 0; i < 6; i += 2)
    {    
        double range = bounds[i + 1] - bounds[i];
        bounds[i] = bounds[i] - .1 * range;
        bounds[i + 1] = bounds[i + 1] + .1 * range;
    }

    vtkSmartPointer<vtkImageData> volume = vtkSmartPointer<vtkImageData>::New();
    vtkSmartPointer<vtkVoxelModeller> voxelModeller = vtkSmartPointer<vtkVoxelModeller>::New();
    voxelModeller->SetSampleDimensions(20, 20, 20);
    voxelModeller->SetModelBounds(bounds);
    voxelModeller->SetScalarTypeToFloat();
    voxelModeller->SetMaximumDistance(.1);

    //voxelModeller->SetInputConnection(reader->GetOutputPort());
    voxelModeller->SetInputData(polydata);
    voxelModeller->Update();
    isoValue = 0.0001;
    volume->DeepCopy(voxelModeller->GetOutput());
    vtkSmartPointer<vtkMarchingCubes> surface = vtkSmartPointer<vtkMarchingCubes>::New();    
#if VTK_MAJOR_VERSION <= 5
    surface->SetInput(volume);
#else
    surface->SetInputData(volume);
#endif
    surface->ComputeNormalsOff();
    surface->SetValue(1, isoValue);

    vtkSmartPointer<vtkRenderer> renderer = vtkSmartPointer<vtkRenderer>::New();
    renderer->SetBackground(.1, .2, .3);
    vtkSmartPointer<vtkRenderWindow> renderWindow = vtkSmartPointer<vtkRenderWindow>::New();
    renderWindow->AddRenderer(renderer);
    vtkSmartPointer<vtkRenderWindowInteractor> interactor = vtkSmartPointer<vtkRenderWindowInteractor>::New();
    interactor->SetRenderWindow(renderWindow);
    vtkSmartPointer<vtkPolyDataMapper> mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
    mapper->SetInputConnection(surface->GetOutputPort());
    mapper->ScalarVisibilityOff();    
    std::string filename = "VTK_mesh_deneme.ply";
    vtkSmartPointer<vtkPLYWriter> plyWriter = vtkSmartPointer<vtkPLYWriter>::New();
    plyWriter->SetInputConnection(surface->GetOutputPort());
    plyWriter->SetFileName(filename.c_str());
    plyWriter->Write();    
    //volume->DeepCopy(voxelModeller->GetOutput());    
    vtkSmartPointer<vtkActor> actor = vtkSmartPointer<vtkActor>::New();
    actor->SetMapper(mapper);    
    renderer->AddActor(actor);    
    renderWindow->Render();
    interactor->Start();    
    return EXIT_SUCCESS;
}

1 个答案:

答案 0 :(得分:0)

提高你的等值。您将其设置为0.001,而不是使用0.5作为二进制图像,以使白色和黑色像素之间的边界等距。