/*========================================================================= Program: Visualization Toolkit Module: vtkBoostExtractLargestComponent.cxx Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen All rights reserved. See Copyright.txt or http://www.kitware.com/Copyright.htm for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notice for more information. =========================================================================*/ #include "vtkBoostExtractLargestComponent.h" #include "vtkBoostConnectedComponents.h" #include "vtkDataSetAttributes.h" #include "vtkDirectedGraph.h" #include "vtkExecutive.h" #include "vtkExtractSelectedGraph.h" #include "vtkGraph.h" #include "vtkIdTypeArray.h" #include "vtkInformation.h" #include "vtkInformationVector.h" #include "vtkIntArray.h" #include "vtkObjectFactory.h" #include "vtkSmartPointer.h" #include "vtkSelection.h" #include "vtkSelectionNode.h" #include "vtkUndirectedGraph.h" #include vtkStandardNewMacro(vtkBoostExtractLargestComponent); vtkBoostExtractLargestComponent::vtkBoostExtractLargestComponent() { this->InvertSelection = false; } int vtkBoostExtractLargestComponent::RequestData(vtkInformation *vtkNotUsed(request), vtkInformationVector **inputVector, vtkInformationVector *outputVector) { // Get the info objects vtkInformation *inInfo = inputVector[0]->GetInformationObject(0); vtkInformation *outInfo = outputVector->GetInformationObject(0); // Get the input and ouptut vtkGraph* input = vtkGraph::SafeDownCast( inInfo->Get(vtkDataObject::DATA_OBJECT())); vtkGraph* output = vtkGraph::SafeDownCast( outInfo->Get(vtkDataObject::DATA_OBJECT())); vtkSmartPointer inputCopy; if (vtkDirectedGraph::SafeDownCast(input)) { inputCopy = vtkSmartPointer::New(); } else { inputCopy = vtkSmartPointer::New(); } inputCopy->ShallowCopy(input); // Find all of the connected components vtkSmartPointer connectedComponents = vtkSmartPointer::New(); connectedComponents->SetInputData(inputCopy); connectedComponents->Update(); vtkIntArray* components = vtkArrayDownCast( connectedComponents->GetOutput()->GetVertexData()->GetArray("component")); // Create an array to store the count of the number of vertices // in every component int componentRange[2]; components->GetValueRange(componentRange); std::vector componentCount(componentRange[1] + 1); for(vtkIdType i = 0; i < components->GetNumberOfTuples(); i++) { componentCount[components->GetValue(i)]++; } // Save the original counts std::vector originalComponentCount(componentCount.size()); std::copy(componentCount.begin(), componentCount.end(), originalComponentCount.begin()); // Sort in descending order std::sort(componentCount.rbegin(), componentCount.rend()); // Find the original component ID of the component with the highest count std::vector::iterator it = find(originalComponentCount.begin(), originalComponentCount.end(), componentCount[0]); if(it == originalComponentCount.end()) { vtkErrorMacro("Should never get to the end of the components!"); return 0; } int largestComponent = it - originalComponentCount.begin(); vtkDebugMacro("The largest component is " << largestComponent << " and it has " << componentCount[0] << " vertices."); // Put either the index of the vertices belonging to the largest connected component // or the index of the vertices NOT the largest connected component (depending on the // InververtSelection flag) into an array to be used to extract this part of the graph. vtkSmartPointer ids = vtkSmartPointer::New(); for(vtkIdType i = 0; i < components->GetNumberOfTuples(); i++) { if(!this->InvertSelection) { if(components->GetValue(i) == largestComponent) { ids->InsertNextValue(i); } } else { if(components->GetValue(i) != largestComponent) { ids->InsertNextValue(i); } } } vtkDebugMacro(<< ids->GetNumberOfTuples() << " values selected."); // Mark all of the things in the graph that should be extracted vtkSmartPointer selection = vtkSmartPointer::New(); vtkSmartPointer node = vtkSmartPointer::New(); selection->AddNode(node); node->SetSelectionList(ids); node->SetContentType(vtkSelectionNode::INDICES); node->SetFieldType(vtkSelectionNode::VERTEX); // Extract them vtkSmartPointer extractSelectedGraph = vtkSmartPointer::New(); extractSelectedGraph->SetInputData(0, inputCopy); extractSelectedGraph->SetInputData(1, selection); extractSelectedGraph->Update(); output->ShallowCopy(extractSelectedGraph->GetOutput()); return 1; } void vtkBoostExtractLargestComponent::PrintSelf(ostream& os, vtkIndent indent) { this->Superclass::PrintSelf(os,indent); os << indent << "InvertSelection: " << this->InvertSelection << "\n"; }