//=========================================================================
//  Copyright (c) Kitware, Inc.
//  All rights reserved.
//  See LICENSE.txt 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 "vtkIdentifyNonManifoldPts.h"

#include "vtkCellArray.h"
#include "vtkCleanPolyData.h"
#include "vtkInformation.h"
#include "vtkInformationVector.h"
#include "vtkObjectFactory.h"
#include "vtkMath.h"
#include "vtkNew.h"
#include "vtkPointData.h"
#include "vtkPolyData.h"
#include "vtkSmartPointer.h"
#include "vtkStripper.h"

vtkStandardNewMacro(vtkIdentifyNonManifoldPts);

//----------------------------------------------------------------------------
int vtkIdentifyNonManifoldPts::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 output
  vtkPolyData *input = vtkPolyData::SafeDownCast(
    inInfo->Get(vtkDataObject::DATA_OBJECT()));
  vtkPolyData *output = vtkPolyData::SafeDownCast(
    outInfo->Get(vtkDataObject::DATA_OBJECT()));

  vtkSmartPointer<vtkPoints> outPts = vtkSmartPointer<vtkPoints>::New();
  output->SetPoints(outPts);
  vtkSmartPointer<vtkCellArray> outVerts = vtkSmartPointer<vtkCellArray>::New();
  output->SetVerts(outVerts);

  // get rid of any duplicated points
  vtkNew<vtkCleanPolyData> cleaner;
  cleaner->SetInputData( input );
  cleaner->Update();

  vtkSmartPointer<vtkPolyData> tmpPD = vtkSmartPointer<vtkPolyData>::New();
  tmpPD->SetLines( cleaner->GetOutput()->GetLines() );
  tmpPD->SetPoints( cleaner->GetOutput()->GetPoints() );
  tmpPD->BuildLinks();
  vtkPoints *pts = tmpPD->GetPoints();
  unsigned short ncells;
  vtkIdType* cells;
  for (vtkIdType i = 0; i < pts->GetNumberOfPoints(); i++)
    {
    tmpPD->GetPointCells(i, ncells, cells);
    if (ncells > 2)
      {
      vtkIdType nextPt = outPts->InsertNextPoint(pts->GetPoint(i));
      outVerts->InsertNextCell(1, &nextPt);
      }
    }
  return 1;
}
