/**
   * Prepare data
   */
  int VTKSegmentsFramesSource::RequestInformation(vtkInformation* request, vtkInformationVector** inputVector, vtkInformationVector* outputVector)
  {
    btkNotUsed(request);
    
    vtkInformation* inInfo = inputVector[0]->GetInformationObject(0);
    VTKDataObjectAdapter* inObject = VTKDataObjectAdapter::SafeDownCast(inInfo->Get(vtkDataObject::DATA_OBJECT()));
    if (!inObject)
      return 0;

    PointCollection::Pointer input = static_pointer_cast<PointCollection>(inObject->GetBTKDataObject());
    int  frameNumber = 0;
    if (!input->IsEmpty())
      frameNumber = input->GetItem(0)->GetFrameNumber();
    
    // Update output informations
    vtkInformation* outInfo = outputVector->GetInformationObject(0);
    // TIME_STEPS
    double* outTimes = new double [frameNumber];
    for (int i = 0; i < frameNumber; ++i)
      outTimes[i] = i;
    outInfo->Set(vtkStreamingDemandDrivenPipeline::TIME_STEPS(), outTimes, frameNumber);
    delete [] outTimes;
    // TIME_RANGE
    double outRange[2];
    outRange[0] = 0.0;
    outRange[1] = frameNumber - 1.0;
    outInfo->Set(vtkStreamingDemandDrivenPipeline::TIME_RANGE(), outRange, 2);
    
    return 1;
  };
 /**
  * Sets the type of object required for the input.
  */
 int VTKSegmentsFramesSource::FillInputPortInformation(int port, vtkInformation* info)
 {
   btkNotUsed(port);
   info->Set(vtkAlgorithm::INPUT_REQUIRED_DATA_TYPE(), "VTKDataObjectAdapter");
   return 1;
 }
  /**
   * Extract segments' frame required by a vtkStreamingDemandDrivenPipeline object.
   */
  int VTKSegmentsFramesSource::RequestData(vtkInformation* request, vtkInformationVector** inputVector, vtkInformationVector* outputVector)
  {
    btkNotUsed(request);
    
    vtkInformation* inInfo = inputVector[0]->GetInformationObject(0);
    VTKDataObjectAdapter* inObject = VTKDataObjectAdapter::SafeDownCast(inInfo->Get(vtkDataObject::DATA_OBJECT()));
    if (!inObject)
      return 0;
    
    PointCollection::Pointer input = static_pointer_cast<PointCollection>(inObject->GetBTKDataObject());
    
    vtkInformation* outInfo = outputVector->GetInformationObject(0);
    vtkPolyData* output = vtkPolyData::SafeDownCast(outInfo->Get(vtkDataObject::DATA_OBJECT()));
    
    vtkInformation* outInfoBis = outputVector->GetInformationObject(1);
    vtkPolyData* outputBis = vtkPolyData::SafeDownCast(outInfoBis->Get(vtkDataObject::DATA_OBJECT()));
    
    int frameIndex = 0;
#if (VTK_MAJOR_VERSION >= 6)
    if (outInfo->Has(vtkStreamingDemandDrivenPipeline::UPDATE_TIME_STEP()))
      frameIndex = static_cast<int>(outInfo->Get(vtkStreamingDemandDrivenPipeline::UPDATE_TIME_STEP()));
#else
    if (outInfo->Has(vtkStreamingDemandDrivenPipeline::UPDATE_TIME_STEPS()))
      frameIndex = static_cast<int>(outInfo->Get(vtkStreamingDemandDrivenPipeline::UPDATE_TIME_STEPS())[0]);
#endif
      
    int markerNumber = 0;
    int linkNumber = 0;
    int faceNumber = 0;
    int inc = 0;
    for (std::list<SegmentDefinition>::const_iterator itS = this->m_Definitions.begin() ; itS != this->m_Definitions.end() ; ++itS)
    {
      if (this->mp_VisibleSegments->GetValue(inc++) == 1)
      {
        markerNumber += static_cast<int>(itS->mesh->GetVertexNumber());
        linkNumber += static_cast<int>(itS->mesh->GetEdgeNumber());
        if (itS->surfaceEnabled)
          faceNumber += static_cast<int>(itS->mesh->GetFaceNumber());
      }
    }
    
    vtkIntArray* edgeColors = vtkIntArray::New(); edgeColors->SetName("Colors"); edgeColors->SetNumberOfValues(linkNumber);
    vtkIntArray* faceColors = vtkIntArray::New(); faceColors->SetName("Colors"); faceColors->SetNumberOfValues(faceNumber);
    vtkPoints* points = vtkPoints::New(); points->SetNumberOfPoints(markerNumber);
    vtkCellArray* lines = vtkCellArray::New(); lines->Allocate(lines->EstimateSize(linkNumber,2));
    vtkCellArray* polys = vtkCellArray::New(); polys->Allocate(lines->EstimateSize(faceNumber,3));
    int segmentIndex = 0;
    int lineIndex = 0; 
    int faceIndex = 0; 
    int pointId = 0;
    output->Initialize();
    outputBis->Initialize();
    
    for (std::list<SegmentDefinition>::const_iterator itS = this->m_Definitions.begin() ; itS != this->m_Definitions.end() ; ++itS)
    {
      if (this->mp_VisibleSegments->GetValue(segmentIndex) == 0)
      {
        ++segmentIndex;
        continue;
      }
      else if (!itS->mesh->ConnectPoints(input))
      {
        btkErrorMacro("Impossible to link the segment with the markers' data.");
        ++segmentIndex;
        continue;
      }
      itS->mesh->SetCurrentFrameIndex(frameIndex);
      int markerIndex = 0;
      // Set points
      std::vector<int> idPts = std::vector<int>(itS->mesh->GetVertexNumber(), 0);
      for (TriangleMesh::VertexConstIterator itM = itS->mesh->BeginVertex() ; itM != itS->mesh->EndVertex() ; ++itM)
      {
        if (itM->IsValid())
        {
          idPts[markerIndex] = pointId;
          points->SetPoint(pointId,
                           itM->GetCoordinateX() * this->m_Scale,
                           itM->GetCoordinateY() * this->m_Scale,
                           itM->GetCoordinateZ() * this->m_Scale);
          ++pointId;
        }
        ++markerIndex;
      }
      // Set lines
      for (TriangleMesh::EdgeConstIterator itL = itS->mesh->BeginEdge() ; itL != itS->mesh->EndEdge() ; ++itL)
      {
        if (itL->IsValid())
        {
          const vtkIdType pts[2]	= {idPts[itL->GetVertex1()->GetRelativeId()], idPts[itL->GetVertex2()->GetRelativeId()]};
          lines->InsertNextCell(2, pts);
          edgeColors->SetValue(lineIndex++, this->mp_SegmentsColorIndex->GetValue(segmentIndex));
        }
      }
      // Set polys
      if (itS->surfaceEnabled)
      {
        for (TriangleMesh::FaceConstIterator itF = itS->mesh->BeginFace() ; itF != itS->mesh->EndFace() ; ++itF)
        {
          if (itF->IsValid())
          {
            const vtkIdType pts[3]	= {idPts[itF->GetVertex1()->GetRelativeId()], idPts[itF->GetVertex2()->GetRelativeId()], idPts[itF->GetVertex3()->GetRelativeId()]};
            polys->InsertNextCell(3, pts);
            faceColors->SetValue(faceIndex++, this->mp_SegmentsColorIndex->GetValue(segmentIndex));
          }
        }
      }
      ++segmentIndex;
    }
    // Edges output
    output->SetPoints(points);
    output->SetLines(lines);
    output->GetCellData()->SetScalars(edgeColors);
    // Faces output
    outputBis->SetPoints(points);
    outputBis->SetPolys(polys);
    outputBis->GetCellData()->SetScalars(faceColors);
    // Cleanup
    points->Delete();
    lines->Delete();
    polys->Delete();
    edgeColors->Delete();
    faceColors->Delete();
    
    return 1;
  };
 /**
  * Whatever the specified index, this method creates an Acquisition object
  */
 DataObject::Pointer MultiSTLFileWriter::MakeOutput(int idx)
 {
   btkNotUsed(idx);
   throw(RuntimeError("btk::MultiSTLFileWriter has not output."));
 };