/*=========================================================================

Copyright (c) 1998-2012 Kitware Inc. 28 Corporate Drive,
Clifton Park, NY, 12065, USA.

All rights reserved. No part of this software may be reproduced,
distributed,
or modified, in any form or by any means, without permission in writing from
Kitware Inc.

IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY FOR
DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY DERIVATIVES THEREOF,
EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES,
INCLUDING,
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
PARTICULAR PURPOSE, AND NON-INFRINGEMENT.  THIS SOFTWARE IS PROVIDED ON AN
"AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE NO OBLIGATION TO
PROVIDE
MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
=========================================================================*/
// .NAME vtkCMBMeshContourSelector - create selection by contour on mesh
// .SECTION Description
// vtkCMBMeshContourSelector is a filter that will create a polydata and
// a point Id selection that is inside the contour (selection loop).
// The output polydata contains vertex cells for those selection points.
// Based on the selection type (surface or select through), a surface
// filter may be used or not before doing selection. The input to this
// filter is a surface or volume mesh.

// .SECTION See Also
// vtkSelectionAlgorithm, vtkImplicitSelectionLoop

#ifndef __vtkCMBMeshContourSelector_h
#define __vtkCMBMeshContourSelector_h

#include "vtkCMBFilteringModule.h" // For export macro
#include "vtkSelectionAlgorithm.h"
#include "cmbSystemConfig.h"

class vtkImplicitSelectionLoop;
class vtkPolyData;
class vtkPoints;
class vtkIdTypeArray;
class vtkCellArray;
class vtkUnstructuredGrid;
class vtkIdList;

#include <map>

class VTKCMBFILTERING_EXPORT vtkCMBMeshContourSelector : public vtkSelectionAlgorithm
{
public:
  vtkTypeMacro(vtkCMBMeshContourSelector,vtkSelectionAlgorithm);
  void PrintSelf(ostream& os, vtkIndent indent);
  static vtkCMBMeshContourSelector *New();

  // Description:
  // Specify the vtkSelection object used for selecting the
  // mesh points.
  void SetSelectionConnection(vtkAlgorithmOutput* algOutput)
  { this->SetInputConnection(1, algOutput); }

  // Description:
  // Removes all inputs from input port 1.
  void RemoveAllSelectionsInputs()
  { this->SetInputConnection(1, 0); }

  // Description:
  // Specify the vktPolyData object as mesh surface
  void SetSurfaceConnection(vtkAlgorithmOutput* algOutput)
  { this->SetInputConnection(2, algOutput); }

  // Description:
  // Removes all inputs from input port 2.
  void RemoveAllSurfaceInputs()
  { this->SetInputConnection(2, 0); }

  // Description:
  // Return the Polydata generated with contour selection
  vtkPolyData* GetSelectionPolyData();

  // Description:
  // Return the average normals of the output SelectionPolyData,
  // calculated from averaging cell normals.
  vtkGetVector3Macro(OrientationOfSelectedNodes, double);

  // Description:
  // Control whether to select through or just on surface
  // If this flag is set, the GenerateSelectedOutput is ignored,
  // so this filter will only generate a selection with cell IDs.
  vtkSetMacro(SelectCellThrough,int);
  vtkGetMacro(SelectCellThrough,int);
  vtkBooleanMacro(SelectCellThrough,int);

  // Description:
  // Control whether to invert the output selection.
  vtkSetMacro(InsideOut,int);
  vtkGetMacro(InsideOut,int);
  vtkBooleanMacro(InsideOut,int);

  //BTX
  enum enumSelectCellThroughType {
    ALL_IN = 0,
    PARTIAL_OR_ALL_IN,
    INTERSECT_ONLY };
  //ETX

  // Description:
  // Set/Get the select cell through type
  // default: 0
  vtkSetClampMacro(SelectContourType, int , 0 , 2);
  vtkGetMacro(SelectContourType,int);

  //BTX
  enum enumSelectionFieldType {
    CELL = 0,
    POINT };
  //ETX

  // Description:
  // Set/Get the output selection field type
  // default: 0
  vtkSetClampMacro(SelectionFieldType, int , 0 , 1);
  vtkGetMacro(SelectionFieldType,int);

  // Description:
  // Control whether a second output is generated. The second output
  // contains the polygonal data (only points) that's been selected.
  // This flag is just to create a polydata for the selected nodes,
  // so that it can be displayed inside the contour widget and
  // transformed with a box widget
  vtkSetMacro(GenerateSelectedOutput,int);
  vtkGetMacro(GenerateSelectedOutput,int);
  vtkBooleanMacro(GenerateSelectedOutput,int);

  // Description:
  // Flag to indicate whether the output selection is empty, which
  // will be true, if all cells are selected, but InsideOut is set;
  // or no cells are selection and InsideOut is not set.
  vtkGetMacro(IsSelectionEmpty,int);

  // Description:
  // Return the mtime also considering the contour function.
  unsigned long GetMTime();

  // Description:
  // Set contour function
  void SetContour(vtkImplicitSelectionLoop *contour);
  vtkGetObjectMacro(Contour, vtkImplicitSelectionLoop);

//BTX
protected:
  vtkCMBMeshContourSelector();
  ~vtkCMBMeshContourSelector();

  int RequestData(vtkInformation *, vtkInformationVector **, vtkInformationVector *);
  virtual int FillInputPortInformation(int port, vtkInformation* info);
  virtual int FillOutputPortInformation(int port, vtkInformation* info);

  virtual void DoSurfaceSelectionCheck(int selType, vtkIdList* tmpIds,
    bool bVolume, vtkIdType selId, vtkUnstructuredGrid* input,
    vtkIdTypeArray* meshCellIdArray, vtkIdTypeArray* meshNodeIdArray,
    vtkPoints* newPoints, vtkCellArray* outVerts, vtkIdList* outMeshCellIds,
    vtkIdList* outNodeIdList, vtkIdList* surfaceNodeList,
    vtkIdTypeArray* outSelectionList, double* totNormal, int& totNumNormals);
  virtual bool DoCellContourCheck(
    vtkIdType npts, vtkIdType* pts, vtkUnstructuredGrid* input);

  int SelectCellThrough;
  int SelectContourType;
  int SelectionFieldType;
  int InsideOut;
  int IsSelectionEmpty;

  vtkImplicitSelectionLoop* Contour;
  int GenerateSelectedOutput;
  vtkPolyData* SelectionPolyData;
  double OrientationOfSelectedNodes[3];

private:
  vtkCMBMeshContourSelector(const vtkCMBMeshContourSelector&);  // Not implemented.
  void operator=(const vtkCMBMeshContourSelector&);  // Not implemented.

  bool IsProcessing;
//ETX
};

#endif
