Я пытаюсь создать треугольную сетку из облаков точек, полученных наземными лазерными сканерами. Я использую алгоритм марширующих кубов библиотеки ВТК. Когда я визуализирую сгенерированную сетку, она выглядит как толстая поверхность, как показано на рисунке ниже:
Однако я ожидал увидеть это на рисунке ниже:
Не могли бы вы помочь мне об этой проблеме? Я хочу создать сетки, как показано на втором рисунке.
Я с нетерпением жду ответа от вас
Кстати, мой код:
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;
}
Поднимите свою ценность. Вы устанавливаете его на 0,001, вместо этого используйте 0,5 для двоичного изображения, чтобы получить границу между белыми и черными пикселями на равном расстоянии.
Других решений пока нет …