// // GenerateCubesFromLabels // Usage: GenerateCubesFromLabels InputVolume Startlabel Endlabel // where // InputVolume is a meta file containing a 3 volume of // discrete labels. // StartLabel is the first label to be processed // EndLabel is the last label to be processed // NOTE: There can be gaps in the labeling. If a label does // not exist in the volume, it will be skipped. // // #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include int main(int argc, char* argv[]) { if (argc < 4) { cout << "Usage: " << argv[0] << " InputVolume StartLabel EndLabel" << endl; return EXIT_FAILURE; } // Create all of the classes we will need vtkSmartPointer reader = vtkSmartPointer::New(); vtkSmartPointer histogram = vtkSmartPointer::New(); vtkSmartPointer pad = vtkSmartPointer::New(); vtkSmartPointer scalarsOff = vtkSmartPointer::New(); vtkSmartPointer selector = vtkSmartPointer::New(); vtkSmartPointer geometry = vtkSmartPointer::New(); vtkSmartPointer transformModel = vtkSmartPointer::New(); vtkSmartPointer transform = vtkSmartPointer::New(); vtkSmartPointer writer = vtkSmartPointer::New(); // Define all of the variables unsigned int startLabel = atoi(argv[2]); if (startLabel > VTK_SHORT_MAX) { std::cout << "ERROR: startLabel is larger than " << VTK_SHORT_MAX << std::endl; return EXIT_FAILURE; } unsigned int endLabel = atoi(argv[3]); if (endLabel > VTK_SHORT_MAX) { std::cout << "ERROR: endLabel is larger than " << VTK_SHORT_MAX << std::endl; return EXIT_FAILURE; } std::string filePrefix = "Cubes"; // Generate cubes from labels // 1) Read the meta file // 2) Generate a histogram of the labels // 3) Convert point data to cell data // 4) Output each cube model into a separate file reader->SetFileName(argv[1]); histogram->SetInputConnection(reader->GetOutputPort()); histogram->SetComponentExtent(0, endLabel, 0, 0, 0, 0); histogram->SetComponentOrigin(0, 0, 0); histogram->SetComponentSpacing(1, 1, 1); histogram->Update(); // Pad the volume so that we can change the point data into cell // data. int* extent = reader->GetOutput()->GetExtent(); pad->SetInputConnection(reader->GetOutputPort()); pad->SetOutputWholeExtent( extent[0], extent[1] + 1, extent[2], extent[3] + 1, extent[4], extent[5] + 1); pad->Update(); // Copy the scalar point data of the volume into the scalar cell data pad->GetOutput()->GetCellData()->SetScalars(reader->GetOutput()->GetPointData()->GetScalars()); selector->SetInputConnection(pad->GetOutputPort()); selector->SetInputArrayToProcess( 0, 0, 0, vtkDataObject::FIELD_ASSOCIATION_CELLS, vtkDataSetAttributes::SCALARS); // Shift the geometry by 1/2 transform->Translate(-.5, -.5, -.5); transformModel->SetTransform(transform); transformModel->SetInputConnection(selector->GetOutputPort()); // Strip the scalars from the output scalarsOff->SetInputConnection(transformModel->GetOutputPort()); scalarsOff->CopyAttributeOff(vtkMaskFields::POINT_DATA, vtkDataSetAttributes::SCALARS); scalarsOff->CopyAttributeOff(vtkMaskFields::CELL_DATA, vtkDataSetAttributes::SCALARS); geometry->SetInputConnection(scalarsOff->GetOutputPort()); writer->SetInputConnection(geometry->GetOutputPort()); for (unsigned int i = startLabel; i <= endLabel; i++) { // see if the label exists, if not skip it double frequency = histogram->GetOutput()->GetPointData()->GetScalars()->GetTuple1(i); if (frequency == 0.0) { continue; } // select the cells for a given label selector->SetThresholdFunction(vtkThreshold::THRESHOLD_BETWEEN); selector->SetLowerThreshold(i); selector->SetUpperThreshold(i); // output the polydata std::stringstream ss; ss << filePrefix << i << ".vtp"; cout << argv[0] << " writing " << ss.str() << endl; writer->SetFileName(ss.str().c_str()); writer->Write(); } return EXIT_SUCCESS; }