text: /*=========================================================================
  
    Program:   Visualization Toolkit
    Module:    vtkHyperTreeGridSource.h
  
    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.
  
  =========================================================================*/
  /**
   * @class   vtkHyperTreeGridSource
   * @brief   Create a synthetic grid of hypertrees.
   *
   *
   * This class uses input parameters, most notably a string descriptor,
   * to generate a vtkHyperTreeGrid instance representing the corresponding
   * tree-based AMR grid. This descriptor uses the following conventions,
   * e.g., to describe a 1-D ternary subdivision with 2 root cells
   * L0    L1        L2
   * RR  | .R. ... | ...
   * For this tree:
   *  HTG:       .
   *           /   \
   *  L0:     .     .
   *         /|\   /|\
   *  L1:   c . c c c c
   *         /|\
   *  L2:   c c c
   * The top level of the tree is not considered a grid level
   * NB: For ease of legibility, white spaces are allowed and ignored.
   *
   * @par Thanks:
   * This class was written by Philippe Pebay, Joachim Pouderoux, and Charles Law, Kitware 2013
   * This class was modified by Guenole Harel and Jacques-Bernard Lekien 2014
   * This class was modified by Philippe Pebay, 2016
   * This work was supported by Commissariat a l'Energie Atomique (CEA/DIF)
   * CEA, DAM, DIF, F-91297 Arpajon, France.
   */
  
  #ifndef vtkHyperTreeGridSource_h
  #define vtkHyperTreeGridSource_h
  
  #include "vtkFiltersSourcesModule.h" // For export macro
  #include "vtkHyperTreeGridAlgorithm.h"
  #include "vtkLegacy.h" // For VTK_LEGACY
  
  #include <map>    // STL Header
  #include <string> // STL Header
  #include <vector> // STL Header
  
  class vtkBitArray;
  class vtkDataArray;
  class vtkHyperTreeGridNonOrientedCursor;
  class vtkIdTypeArray;
  class vtkImplicitFunction;
  class vtkHyperTreeGrid;
  class vtkQuadric;
  
  class VTKFILTERSSOURCES_EXPORT vtkHyperTreeGridSource : public vtkHyperTreeGridAlgorithm
  {
  public:
    vtkTypeMacro(vtkHyperTreeGridSource, vtkHyperTreeGridAlgorithm);
    void PrintSelf(ostream& os, vtkIndent indent) override;
  
    static vtkHyperTreeGridSource* New();
  
    // @deprecated Replaced by GetMaxDepth() as of VTK 9
    VTK_LEGACY(unsigned int GetMaximumLevel());
  
    // @deprecated Replaced by SetMaxDepth() as of VTK 9
    VTK_LEGACY(void SetMaximumLevel(unsigned int levels));
  
    /**
     * Return the maximum number of levels of the hypertree.
     * \post positive_result: result>=1
     */
    unsigned int GetMaxDepth();
  
    /**
     * Set the maximum number of levels of the hypertrees.
     * \pre positive_levels: levels>=1
     * \post is_set: this->GetLevels()==levels
     * \post min_is_valid: this->GetMinLevels()<this->GetLevels()
     */
    void SetMaxDepth(unsigned int levels);
  
    //@{
    /**
     * Set/Get the origin of the grid
     */
    vtkSetVector3Macro(Origin, double);
    vtkGetVector3Macro(Origin, double);
    //@}
  
    //@{
    /**
     * Set/Get the scale to be applied to root cells in each dimension of the grid
     */
    vtkSetVector3Macro(GridScale, double);
    vtkGetVector3Macro(GridScale, double);
    void SetGridScale(double scale) { this->SetGridScale(scale, scale, scale); }
    //@}
  
    //@{
    /**
     * Set/Get the number of root cells + 1 in each dimension of the grid
     */
    void SetDimensions(const unsigned int* dims);
    void SetDimensions(unsigned int, unsigned int, unsigned int);
    vtkGetVector3Macro(Dimensions, unsigned int);
    //@}
  
    //@{
    /**
     * Specify whether indexing mode of grid root cells must be transposed to
     * x-axis first, z-axis last, instead of the default z-axis first, k-axis last
     */
    vtkSetMacro(TransposedRootIndexing, bool);
    vtkGetMacro(TransposedRootIndexing, bool);
    void SetIndexingModeToKJI();
    void SetIndexingModeToIJK();
    //@}
  
    //@{
    /**
     * Set/Get the orientation of the grid (in 1D and 2D)
     */
    vtkGetMacro(Orientation, unsigned int);
    //@}
  
    //@{
    /**
     * Set/Get the subdivision factor in the grid refinement scheme
     */
    vtkSetClampMacro(BranchFactor, unsigned int, 2, 3);
    vtkGetMacro(BranchFactor, unsigned int);
    //@}
  
    //@{
    /**
     * Set/get whether the descriptor string should be used.
     * NB: Otherwise a quadric definition is expected.
     * Default: true
     */
    vtkSetMacro(UseDescriptor, bool);
    vtkGetMacro(UseDescriptor, bool);
    vtkBooleanMacro(UseDescriptor, bool);
    //@}
  
    //@{
    /**
     * Set/get whether the material mask should be used.
     * NB: This is only used when UseDescriptor is ON
     * Default: false
     */
    vtkSetMacro(UseMask, bool);
    vtkGetMacro(UseMask, bool);
    vtkBooleanMacro(UseMask, bool);
    //@}
  
    //@{
    /**
     * Set/get whether cell-centered interface fields
     * should be generated.
     * Default: false
     */
    vtkSetMacro(GenerateInterfaceFields, bool);
    vtkGetMacro(GenerateInterfaceFields, bool);
    vtkBooleanMacro(GenerateInterfaceFields, bool);
    //@}
  
    //@{
    /**
     * Set/Get the string used to describe the grid.
     */
    vtkSetStringMacro(Descriptor);
    vtkGetStringMacro(Descriptor);
    //@}
  
    //@{
    /**
     * Set/Get the string used to as a material mask.
     */
    vtkSetStringMacro(Mask);
    vtkGetStringMacro(Mask);
    //@}
  
    //@{
    /**
     * Set/Get the bitarray used to describe the grid.
     */
    virtual void SetDescriptorBits(vtkBitArray*);
    vtkGetObjectMacro(DescriptorBits, vtkBitArray);
    //@}
  
    /**
     * Set the index array used to as a material mask.
     */
    virtual void SetLevelZeroMaterialIndex(vtkIdTypeArray*);
  
    //@{
    /**
     * Set/Get the bitarray used as a material mask.
     */
    virtual void SetMaskBits(vtkBitArray*);
    vtkGetObjectMacro(MaskBits, vtkBitArray);
    //@}
  
    //@{
    /**
     * Set/Get the quadric function.
     */
    virtual void SetQuadric(vtkQuadric*);
    vtkGetObjectMacro(Quadric, vtkQuadric);
    //@}
  
    //@{
    /**
     * Helpers to set/get the 10 coefficients of the quadric function
     */
    void SetQuadricCoefficients(double[10]);
    void GetQuadricCoefficients(double[10]);
    double* GetQuadricCoefficients();
    //@}
  
    /**
     * Override GetMTime because we delegate to a vtkQuadric.
     */
    vtkMTimeType GetMTime() override;
  
    //@{
    /**
     * Helpers to convert string descriptors & mask to bit arrays
     */
    vtkBitArray* ConvertDescriptorStringToBitArray(const std::string&);
    vtkBitArray* ConvertMaskStringToBitArray(const std::string&);
    //@}
  
  protected:
    vtkHyperTreeGridSource();
    ~vtkHyperTreeGridSource() override;
  
    int RequestInformation(vtkInformation*, vtkInformationVector**, vtkInformationVector*) override;
  
    int RequestData(vtkInformation*, vtkInformationVector**, vtkInformationVector*) override;
  
    int FillOutputPortInformation(int, vtkInformation*) override;
  
    /**
     * Main routine to process individual trees in the grid
     */
    int ProcessTrees(vtkHyperTreeGrid*, vtkDataObject*) override;
  
    /**
     * Initialize grid from descriptor string when it is to be used
     */
    int InitializeFromStringDescriptor();
  
    /**
     * Initialize grid from bit array descriptors when it is to be used
     */
    int InitializeFromBitsDescriptor();
  
    /**
     * Initialize tree grid from descriptor and call subdivide if needed
     */
    void InitTreeFromDescriptor(
      vtkHyperTreeGrid* output, vtkHyperTreeGridNonOrientedCursor* cursor, int treeIdx, int idx[3]);
  
    /**
     * Subdivide grid from descriptor string when it is to be used
     */
    void SubdivideFromStringDescriptor(vtkHyperTreeGrid* output,
      vtkHyperTreeGridNonOrientedCursor* cursor, unsigned int level, int treeIdx, int childIdx,
      int idx[3], int parentPos);
  
    /**
     * Subdivide grid from descriptor string when it is to be used
     */
    void SubdivideFromBitsDescriptor(vtkHyperTreeGrid* output,
      vtkHyperTreeGridNonOrientedCursor* cursor, unsigned int level, int treeIdx, int childIdx,
      int idx[3], int parentPos);
  
    /**
     * Subdivide grid from quadric when descriptor is not used
     */
    void SubdivideFromQuadric(vtkHyperTreeGrid* output, vtkHyperTreeGridNonOrientedCursor* cursor,
      unsigned int level, int treeIdx, const int idx[3], double origin[3], double size[3]);
  
    /**
     * Evaluate quadric at given point coordinates
     */
    double EvaluateQuadric(double[3]);
  
    double Origin[3];
    double GridScale[3];
    unsigned int Dimension;
  
  protected:
    unsigned int Dimensions[3];
    bool TransposedRootIndexing;
    unsigned int MaxDepth;
  
    unsigned int Orientation;
    unsigned int BranchFactor;
    unsigned int BlockSize;
    bool UseDescriptor;
    bool UseMask;
    bool GenerateInterfaceFields;
  
    vtkDataArray* XCoordinates;
    vtkDataArray* YCoordinates;
    vtkDataArray* ZCoordinates;
  
    char* Descriptor;
    char* Mask;
    std::vector<std::string> LevelDescriptors;
    std::vector<std::string> LevelMasks;
  
    vtkBitArray* DescriptorBits;
    vtkBitArray* MaskBits;
    std::vector<vtkIdType> LevelBitsIndex;
    std::vector<vtkIdType> LevelBitsIndexCnt;
  
    vtkIdTypeArray* LevelZeroMaterialIndex;
    std::map<vtkIdType, vtkIdType> LevelZeroMaterialMap;
  
    std::vector<int> LevelCounters;
  
    vtkQuadric* Quadric;
  
    vtkHyperTreeGrid* OutputHTG;
  
  private:
    vtkHyperTreeGridSource(const vtkHyperTreeGridSource&) = delete;
    void operator=(const vtkHyperTreeGridSource&) = delete;
  };
  
  #endif
  