#include "vtkCellLocator.h" #include "vtkSTLReader.h" #include "vtkSTLWriter.h" #include "vtkPolyData.h" #include "vtkPolyDataReader.h" #include "vtkPolyDataNormals.h" #include "vtkThinPlateSplineTransform.h" #include "vtkTransformPolyDataFilter.h" #include "vtkPointDataToCellData.h" #include "vtkMath.h" #include #include static vtkPoints *GetXYZPoints(const char* filename); const char XYZfilename; int main( int argc, char *argv[] ) { if (argc != 4) { cout << "You must specify three filenames (.vtk format)..." << endl; cout << " " << endl; cout << "Performs: for each point in XYZfile , locate closest point on Reference Surface and write modified XYZfile" << endl; return 1; // or get filename with cin >> ...; } vtkIdType cellId; int subId; float dist, clospoint[3]; vtkPoints *XYZPoints; XYZfilename = argv[2]; // Read surface that is to be deformed. //vtkSTLReader *stlReaderRef = vtkSTLReader::New(); //stlReaderRef->SetFileName(argv[2]); //"8664052_19981028_mvox.stl" //stlReaderRef->Update(); vtkPolyDataReader *PolyDataReaderRef = vtkPolyDataReader::New(); PolyDataReaderRef->SetFileName(argv[2]); PolyDataReaderRef->Update(); // Read the surface to locate cloest points on. //vtkSTLReader *stlReader = vtkSTLReader::New(); //stlReader->SetFileName(argv[1]); //stlReader->Update(); vtkPolyDataReader *PolyDataReader = vtkPolyDataReader::New(); PolyDataReader->SetFileName(argv[1]); PolyDataReader->Update(); // Read the XYZ coordinates from a simple file of x y z values (no header; e.g. an .sln file) XYZPoints = GetXYZPoints(XYZfilename); vtkCellLocator *cellLocator = vtkCellLocator::New(); //cellLocator->SetDataSet(stlReader->GetOutput()); cellLocator->SetDataSet(PolyDataReader->GetOutput()); cellLocator->BuildLocator(); // Open file for output (alters argv[1]) ofstream out; out.open(strncat(argv[1],".txt",4), ios::out); //vtkPoints *poi = stlReaderRef->GetOutput()->GetPoints(); //vtkCellArray *polys = stlReaderRef->GetOutput()->GetPolys(); vtkPoints *poi = PolyDataReaderRef->GetOutput()->GetPoints(); vtkCellArray *polys = PolyDataReaderRef->GetOutput()->GetPolys(); out << "input_x input_y input_z closest_x closest_y closest_z cellid dist" << endl; int npoints = poi->GetNumberOfPoints(); cout << "npoints= " << npoints << endl; for (int i = 0; i < poi->GetNumberOfPoints(); i++) { // Find closest point cellLocator->FindClosestPoint(poi->GetPoint(i), clospoint, cellId, subId, dist); // Modify the Surface: Replace the poi with new coordinates. poi->SetPoint(i,clospoint); // Write point, closest point on ref surface, cellid and dist to file out << poi->GetPoint(i)[0] << " " << poi->GetPoint(i)[1] << " " << poi->GetPoint(i)[2] << " "; out << clospoint[0] << " " << clospoint[1] << " " << clospoint[2] << " "; out << cellId << " "; out << sqrt(dist); if (i != poi->GetNumberOfPoints()-1) { out << endl; } } out.close(); // Write output stl file. vtkPolyData *PolyData = vtkPolyData::New(); PolyData->SetPoints(poi); PolyData->SetPolys(polys); vtkPolyDataWriter *polyWriter = vtkPolyDataWriter::New(); polyWriter->SetInput(PolyData); polyWriter->SetFileName(argv[3]); polyWriter->Write(); //vtkSTLWriter *stlWriter = vtkSTLWriter::New(); //stlWriter->SetInput(PolyData); //stlWriter->SetFileName(argv[3]); //stlWriter->Write(); return 0; static vtkPoints *GetXYZPoints(const char *filename) { int valid; int bigNum = 512; int index = 0; float d1=0, d2=0, d3=0; char buffer[bigNum]; ifstream file (filename); if (! file.is_open()) { cout << "Error opening file"; exit (1); } vtkPoints *dataPts = vtkPoints::New(); while (! file.eof() ) { file.getline (buffer,bigNum); valid = 0; sscanf(buffer, "%f %f %f %*s %d", &d1, &d2, &d3, &valid); if(valid) { dataPts->InsertPoint(index, d1, d2, d3); index++; } } return dataPts; } }