// Copyright (c) Lawrence Livermore National Security, LLC and other VisIt
// Project developers.  See the top-level LICENSE file for dates and other
// details.  No copyright assignment is required to contribute to VisIt.

#include <avtMeshMetaData.h>
#include <DataNode.h>
#include <algorithm>

// ****************************************************************************
// Method: avtMeshMetaData::avtMeshMetaData
//
// Purpose:
//   Init utility for the avtMeshMetaData class.
//
// Note:       Autogenerated by xml2atts.
//
// Programmer: xml2atts
// Creation:   omitted
//
// Modifications:
//
// ****************************************************************************

void avtMeshMetaData::Init()
{
    name = "mesh";
    validVariable = true;
    meshType = AVT_UNKNOWN_MESH;
    meshCoordType = AVT_XY;
    cellOrigin = 0;
    spatialDimension = 3;
    hasLogicalBounds = false;
    logicalBounds[0] = 0;
    logicalBounds[1] = 0;
    logicalBounds[2] = 0;
    hasNumberCells = false;
    numberCells = 0;
    topologicalDimension = 3;
    xLabel = "X-Axis";
    yLabel = "Y-Axis";
    zLabel = "Z-Axis";
    hasSpatialExtents = false;
    minSpatialExtents[0] = 0;
    minSpatialExtents[1] = 0;
    minSpatialExtents[2] = 0;
    maxSpatialExtents[0] = 0;
    maxSpatialExtents[1] = 0;
    maxSpatialExtents[2] = 0;
    numBlocks = 1;
    blockOrigin = 0;
    blockPieceName = "domain";
    blockTitle = "domains";
    numGroups = 0;
    groupOrigin = 0;
    groupPieceName = "group";
    groupTitle = "groups";
    disjointElements = false;
    containsGhostZones = AVT_MAYBE_GHOSTS;
    containsOriginalCells = false;
    containsOriginalNodes = false;
    containsGlobalNodeIds = false;
    containsGlobalZoneIds = false;
    loadBalanceScheme = LOAD_BALANCE_UNKNOWN;
    nodesAreCritical = false;
    unitCellVectors[0] = 1;
    unitCellVectors[1] = 0;
    unitCellVectors[2] = 0;
    unitCellVectors[3] = 0;
    unitCellVectors[4] = 1;
    unitCellVectors[5] = 0;
    unitCellVectors[6] = 0;
    unitCellVectors[7] = 0;
    unitCellVectors[8] = 1;
    unitCellOrigin[0] = 0;
    unitCellOrigin[1] = 0;
    unitCellOrigin[2] = 0;
    rectilinearGridHasTransform = false;
    rectilinearGridTransform[0] = 1;
    rectilinearGridTransform[1] = 0;
    rectilinearGridTransform[2] = 0;
    rectilinearGridTransform[3] = 0;
    rectilinearGridTransform[4] = 0;
    rectilinearGridTransform[5] = 1;
    rectilinearGridTransform[6] = 0;
    rectilinearGridTransform[7] = 0;
    rectilinearGridTransform[8] = 0;
    rectilinearGridTransform[9] = 0;
    rectilinearGridTransform[10] = 1;
    rectilinearGridTransform[11] = 0;
    rectilinearGridTransform[12] = 0;
    rectilinearGridTransform[13] = 0;
    rectilinearGridTransform[14] = 0;
    rectilinearGridTransform[15] = 1;
    nodeOrigin = 0;
    containsExteriorBoundaryGhosts = false;
    hideFromGUI = false;
    LODs = 1;
    presentGhostZoneTypes = 0;
    zonesWereSplit = false;

    avtMeshMetaData::SelectAll();
}

// ****************************************************************************
// Method: avtMeshMetaData::avtMeshMetaData
//
// Purpose:
//   Copy utility for the avtMeshMetaData class.
//
// Note:       Autogenerated by xml2atts.
//
// Programmer: xml2atts
// Creation:   omitted
//
// Modifications:
//
// ****************************************************************************

void avtMeshMetaData::Copy(const avtMeshMetaData &obj)
{

    name = obj.name;
    originalName = obj.originalName;
    validVariable = obj.validVariable;
    meshType = obj.meshType;
    meshCoordType = obj.meshCoordType;
    cellOrigin = obj.cellOrigin;
    spatialDimension = obj.spatialDimension;
    hasLogicalBounds = obj.hasLogicalBounds;
    logicalBounds[0] = obj.logicalBounds[0];
    logicalBounds[1] = obj.logicalBounds[1];
    logicalBounds[2] = obj.logicalBounds[2];

    hasNumberCells = obj.hasNumberCells;
    numberCells = obj.numberCells;
    topologicalDimension = obj.topologicalDimension;
    xUnits = obj.xUnits;
    yUnits = obj.yUnits;
    zUnits = obj.zUnits;
    xLabel = obj.xLabel;
    yLabel = obj.yLabel;
    zLabel = obj.zLabel;
    hasSpatialExtents = obj.hasSpatialExtents;
    minSpatialExtents[0] = obj.minSpatialExtents[0];
    minSpatialExtents[1] = obj.minSpatialExtents[1];
    minSpatialExtents[2] = obj.minSpatialExtents[2];

    maxSpatialExtents[0] = obj.maxSpatialExtents[0];
    maxSpatialExtents[1] = obj.maxSpatialExtents[1];
    maxSpatialExtents[2] = obj.maxSpatialExtents[2];

    numBlocks = obj.numBlocks;
    blockOrigin = obj.blockOrigin;
    blockPieceName = obj.blockPieceName;
    blockTitle = obj.blockTitle;
    blockNames = obj.blockNames;
    blockNameScheme = obj.blockNameScheme;
    numGroups = obj.numGroups;
    groupOrigin = obj.groupOrigin;
    groupPieceName = obj.groupPieceName;
    groupTitle = obj.groupTitle;
    groupNames = obj.groupNames;
    groupIds = obj.groupIds;
    groupIdsBasedOnRange = obj.groupIdsBasedOnRange;
    disjointElements = obj.disjointElements;
    containsGhostZones = obj.containsGhostZones;
    containsOriginalCells = obj.containsOriginalCells;
    containsOriginalNodes = obj.containsOriginalNodes;
    containsGlobalNodeIds = obj.containsGlobalNodeIds;
    containsGlobalZoneIds = obj.containsGlobalZoneIds;
    loadBalanceScheme = obj.loadBalanceScheme;
    nodesAreCritical = obj.nodesAreCritical;
    for(int i = 0; i < 9; ++i)
        unitCellVectors[i] = obj.unitCellVectors[i];

    unitCellOrigin[0] = obj.unitCellOrigin[0];
    unitCellOrigin[1] = obj.unitCellOrigin[1];
    unitCellOrigin[2] = obj.unitCellOrigin[2];

    rectilinearGridHasTransform = obj.rectilinearGridHasTransform;
    for(int i = 0; i < 16; ++i)
        rectilinearGridTransform[i] = obj.rectilinearGridTransform[i];

    nodeOrigin = obj.nodeOrigin;
    containsExteriorBoundaryGhosts = obj.containsExteriorBoundaryGhosts;
    hideFromGUI = obj.hideFromGUI;
    LODs = obj.LODs;
    presentGhostZoneTypes = obj.presentGhostZoneTypes;
    zonesWereSplit = obj.zonesWereSplit;

    avtMeshMetaData::SelectAll();
}

// Type map format string
const char *avtMeshMetaData::TypeMapFormatString = AVTMESHMETADATA_TMFS;
const AttributeGroup::private_tmfs_t avtMeshMetaData::TmfsStruct = {AVTMESHMETADATA_TMFS};


// ****************************************************************************
// Method: avtMeshMetaData::avtMeshMetaData
//
// Purpose:
//   Default constructor for the avtMeshMetaData class.
//
// Note:       Autogenerated by xml2atts.
//
// Programmer: xml2atts
// Creation:   omitted
//
// Modifications:
//
// ****************************************************************************

avtMeshMetaData::avtMeshMetaData() :
    AttributeSubject(avtMeshMetaData::TypeMapFormatString)
{
    avtMeshMetaData::Init();
}

// ****************************************************************************
// Method: avtMeshMetaData::avtMeshMetaData
//
// Purpose:
//   Constructor for the derived classes of avtMeshMetaData class.
//
// Note:       Autogenerated by xml2atts.
//
// Programmer: xml2atts
// Creation:   omitted
//
// Modifications:
//
// ****************************************************************************

avtMeshMetaData::avtMeshMetaData(private_tmfs_t tmfs) :
    AttributeSubject(tmfs.tmfs)
{
    avtMeshMetaData::Init();
}

// ****************************************************************************
// Method: avtMeshMetaData::avtMeshMetaData
//
// Purpose:
//   Copy constructor for the avtMeshMetaData class.
//
// Note:       Autogenerated by xml2atts.
//
// Programmer: xml2atts
// Creation:   omitted
//
// Modifications:
//
// ****************************************************************************

avtMeshMetaData::avtMeshMetaData(const avtMeshMetaData &obj) :
    AttributeSubject(avtMeshMetaData::TypeMapFormatString)
{
    avtMeshMetaData::Copy(obj);
}

// ****************************************************************************
// Method: avtMeshMetaData::avtMeshMetaData
//
// Purpose:
//   Copy constructor for derived classes of the avtMeshMetaData class.
//
// Note:       Autogenerated by xml2atts.
//
// Programmer: xml2atts
// Creation:   omitted
//
// Modifications:
//
// ****************************************************************************

avtMeshMetaData::avtMeshMetaData(const avtMeshMetaData &obj, private_tmfs_t tmfs) :
    AttributeSubject(tmfs.tmfs)
{
    avtMeshMetaData::Copy(obj);
}

// ****************************************************************************
// Method: avtMeshMetaData::~avtMeshMetaData
//
// Purpose:
//   Destructor for the avtMeshMetaData class.
//
// Note:       Autogenerated by xml2atts.
//
// Programmer: xml2atts
// Creation:   omitted
//
// Modifications:
//
// ****************************************************************************

avtMeshMetaData::~avtMeshMetaData()
{
    // nothing here
}

// ****************************************************************************
// Method: avtMeshMetaData::operator =
//
// Purpose:
//   Assignment operator for the avtMeshMetaData class.
//
// Note:       Autogenerated by xml2atts.
//
// Programmer: xml2atts
// Creation:   omitted
//
// Modifications:
//
// ****************************************************************************

avtMeshMetaData&
avtMeshMetaData::operator = (const avtMeshMetaData &obj)
{
    if (this == &obj) return *this;

    avtMeshMetaData::Copy(obj);

    return *this;
}

// ****************************************************************************
// Method: avtMeshMetaData::operator ==
//
// Purpose:
//   Comparison operator == for the avtMeshMetaData class.
//
// Note:       Autogenerated by xml2atts.
//
// Programmer: xml2atts
// Creation:   omitted
//
// Modifications:
//
// ****************************************************************************

bool
avtMeshMetaData::operator == (const avtMeshMetaData &obj) const
{
    // Compare the logicalBounds arrays.
    bool logicalBounds_equal = true;
    for(int i = 0; i < 3 && logicalBounds_equal; ++i)
        logicalBounds_equal = (logicalBounds[i] == obj.logicalBounds[i]);

    // Compare the minSpatialExtents arrays.
    bool minSpatialExtents_equal = true;
    for(int i = 0; i < 3 && minSpatialExtents_equal; ++i)
        minSpatialExtents_equal = (minSpatialExtents[i] == obj.minSpatialExtents[i]);

    // Compare the maxSpatialExtents arrays.
    bool maxSpatialExtents_equal = true;
    for(int i = 0; i < 3 && maxSpatialExtents_equal; ++i)
        maxSpatialExtents_equal = (maxSpatialExtents[i] == obj.maxSpatialExtents[i]);

    // Compare the unitCellVectors arrays.
    bool unitCellVectors_equal = true;
    for(int i = 0; i < 9 && unitCellVectors_equal; ++i)
        unitCellVectors_equal = (unitCellVectors[i] == obj.unitCellVectors[i]);

    // Compare the unitCellOrigin arrays.
    bool unitCellOrigin_equal = true;
    for(int i = 0; i < 3 && unitCellOrigin_equal; ++i)
        unitCellOrigin_equal = (unitCellOrigin[i] == obj.unitCellOrigin[i]);

    // Compare the rectilinearGridTransform arrays.
    bool rectilinearGridTransform_equal = true;
    for(int i = 0; i < 16 && rectilinearGridTransform_equal; ++i)
        rectilinearGridTransform_equal = (rectilinearGridTransform[i] == obj.rectilinearGridTransform[i]);

    // Create the return value
    return ((name == obj.name) &&
            (originalName == obj.originalName) &&
            (validVariable == obj.validVariable) &&
            (meshType == obj.meshType) &&
            (meshCoordType == obj.meshCoordType) &&
            (cellOrigin == obj.cellOrigin) &&
            (spatialDimension == obj.spatialDimension) &&
            (hasLogicalBounds == obj.hasLogicalBounds) &&
            logicalBounds_equal &&
            (hasNumberCells == obj.hasNumberCells) &&
            (numberCells == obj.numberCells) &&
            (topologicalDimension == obj.topologicalDimension) &&
            (xUnits == obj.xUnits) &&
            (yUnits == obj.yUnits) &&
            (zUnits == obj.zUnits) &&
            (xLabel == obj.xLabel) &&
            (yLabel == obj.yLabel) &&
            (zLabel == obj.zLabel) &&
            (hasSpatialExtents == obj.hasSpatialExtents) &&
            minSpatialExtents_equal &&
            maxSpatialExtents_equal &&
            (numBlocks == obj.numBlocks) &&
            (blockOrigin == obj.blockOrigin) &&
            (blockPieceName == obj.blockPieceName) &&
            (blockTitle == obj.blockTitle) &&
            (blockNames == obj.blockNames) &&
            (blockNameScheme == obj.blockNameScheme) &&
            (numGroups == obj.numGroups) &&
            (groupOrigin == obj.groupOrigin) &&
            (groupPieceName == obj.groupPieceName) &&
            (groupTitle == obj.groupTitle) &&
            (groupNames == obj.groupNames) &&
            (groupIds == obj.groupIds) &&
            (groupIdsBasedOnRange == obj.groupIdsBasedOnRange) &&
            (disjointElements == obj.disjointElements) &&
            (containsGhostZones == obj.containsGhostZones) &&
            (containsOriginalCells == obj.containsOriginalCells) &&
            (containsOriginalNodes == obj.containsOriginalNodes) &&
            (containsGlobalNodeIds == obj.containsGlobalNodeIds) &&
            (containsGlobalZoneIds == obj.containsGlobalZoneIds) &&
            (loadBalanceScheme == obj.loadBalanceScheme) &&
            (nodesAreCritical == obj.nodesAreCritical) &&
            unitCellVectors_equal &&
            unitCellOrigin_equal &&
            (rectilinearGridHasTransform == obj.rectilinearGridHasTransform) &&
            rectilinearGridTransform_equal &&
            (nodeOrigin == obj.nodeOrigin) &&
            (containsExteriorBoundaryGhosts == obj.containsExteriorBoundaryGhosts) &&
            (hideFromGUI == obj.hideFromGUI) &&
            (LODs == obj.LODs) &&
            (presentGhostZoneTypes == obj.presentGhostZoneTypes) &&
            (zonesWereSplit == obj.zonesWereSplit));
}

// ****************************************************************************
// Method: avtMeshMetaData::operator !=
//
// Purpose:
//   Comparison operator != for the avtMeshMetaData class.
//
// Note:       Autogenerated by xml2atts.
//
// Programmer: xml2atts
// Creation:   omitted
//
// Modifications:
//
// ****************************************************************************

bool
avtMeshMetaData::operator != (const avtMeshMetaData &obj) const
{
    return !(this->operator == (obj));
}

// ****************************************************************************
// Method: avtMeshMetaData::TypeName
//
// Purpose:
//   Type name method for the avtMeshMetaData class.
//
// Note:       Autogenerated by xml2atts.
//
// Programmer: xml2atts
// Creation:   omitted
//
// Modifications:
//
// ****************************************************************************

const std::string
avtMeshMetaData::TypeName() const
{
    return "avtMeshMetaData";
}

// ****************************************************************************
// Method: avtMeshMetaData::CopyAttributes
//
// Purpose:
//   CopyAttributes method for the avtMeshMetaData class.
//
// Note:       Autogenerated by xml2atts.
//
// Programmer: xml2atts
// Creation:   omitted
//
// Modifications:
//
// ****************************************************************************

bool
avtMeshMetaData::CopyAttributes(const AttributeGroup *atts)
{
    if(TypeName() != atts->TypeName())
        return false;

    // Call assignment operator.
    const avtMeshMetaData *tmp = (const avtMeshMetaData *)atts;
    *this = *tmp;

    return true;
}

// ****************************************************************************
// Method: avtMeshMetaData::CreateCompatible
//
// Purpose:
//   CreateCompatible method for the avtMeshMetaData class.
//
// Note:       Autogenerated by xml2atts.
//
// Programmer: xml2atts
// Creation:   omitted
//
// Modifications:
//
// ****************************************************************************

AttributeSubject *
avtMeshMetaData::CreateCompatible(const std::string &tname) const
{
    AttributeSubject *retval = 0;
    if(TypeName() == tname)
        retval = new avtMeshMetaData(*this);
    // Other cases could go here too.

    return retval;
}

// ****************************************************************************
// Method: avtMeshMetaData::NewInstance
//
// Purpose:
//   NewInstance method for the avtMeshMetaData class.
//
// Note:       Autogenerated by xml2atts.
//
// Programmer: xml2atts
// Creation:   omitted
//
// Modifications:
//
// ****************************************************************************

AttributeSubject *
avtMeshMetaData::NewInstance(bool copy) const
{
    AttributeSubject *retval = 0;
    if(copy)
        retval = new avtMeshMetaData(*this);
    else
        retval = new avtMeshMetaData;

    return retval;
}

// ****************************************************************************
// Method: avtMeshMetaData::SelectAll
//
// Purpose:
//   Selects all attributes.
//
// Note:       Autogenerated by xml2atts.
//
// Programmer: xml2atts
// Creation:   omitted
//
// Modifications:
//
// ****************************************************************************

void
avtMeshMetaData::SelectAll()
{
    Select(ID_name,                           (void *)&name);
    Select(ID_originalName,                   (void *)&originalName);
    Select(ID_validVariable,                  (void *)&validVariable);
    Select(ID_meshType,                       (void *)&meshType);
    Select(ID_meshCoordType,                  (void *)&meshCoordType);
    Select(ID_cellOrigin,                     (void *)&cellOrigin);
    Select(ID_spatialDimension,               (void *)&spatialDimension);
    Select(ID_hasLogicalBounds,               (void *)&hasLogicalBounds);
    Select(ID_logicalBounds,                  (void *)logicalBounds, 3);
    Select(ID_hasNumberCells,                 (void *)&hasNumberCells);
    Select(ID_numberCells,                    (void *)&numberCells);
    Select(ID_topologicalDimension,           (void *)&topologicalDimension);
    Select(ID_xUnits,                         (void *)&xUnits);
    Select(ID_yUnits,                         (void *)&yUnits);
    Select(ID_zUnits,                         (void *)&zUnits);
    Select(ID_xLabel,                         (void *)&xLabel);
    Select(ID_yLabel,                         (void *)&yLabel);
    Select(ID_zLabel,                         (void *)&zLabel);
    Select(ID_hasSpatialExtents,              (void *)&hasSpatialExtents);
    Select(ID_minSpatialExtents,              (void *)minSpatialExtents, 3);
    Select(ID_maxSpatialExtents,              (void *)maxSpatialExtents, 3);
    Select(ID_numBlocks,                      (void *)&numBlocks);
    Select(ID_blockOrigin,                    (void *)&blockOrigin);
    Select(ID_blockPieceName,                 (void *)&blockPieceName);
    Select(ID_blockTitle,                     (void *)&blockTitle);
    Select(ID_blockNames,                     (void *)&blockNames);
    Select(ID_blockNameScheme,                (void *)&blockNameScheme);
    Select(ID_numGroups,                      (void *)&numGroups);
    Select(ID_groupOrigin,                    (void *)&groupOrigin);
    Select(ID_groupPieceName,                 (void *)&groupPieceName);
    Select(ID_groupTitle,                     (void *)&groupTitle);
    Select(ID_groupNames,                     (void *)&groupNames);
    Select(ID_groupIds,                       (void *)&groupIds);
    Select(ID_groupIdsBasedOnRange,           (void *)&groupIdsBasedOnRange);
    Select(ID_disjointElements,               (void *)&disjointElements);
    Select(ID_containsGhostZones,             (void *)&containsGhostZones);
    Select(ID_containsOriginalCells,          (void *)&containsOriginalCells);
    Select(ID_containsOriginalNodes,          (void *)&containsOriginalNodes);
    Select(ID_containsGlobalNodeIds,          (void *)&containsGlobalNodeIds);
    Select(ID_containsGlobalZoneIds,          (void *)&containsGlobalZoneIds);
    Select(ID_loadBalanceScheme,              (void *)&loadBalanceScheme);
    Select(ID_nodesAreCritical,               (void *)&nodesAreCritical);
    Select(ID_unitCellVectors,                (void *)unitCellVectors, 9);
    Select(ID_unitCellOrigin,                 (void *)unitCellOrigin, 3);
    Select(ID_rectilinearGridHasTransform,    (void *)&rectilinearGridHasTransform);
    Select(ID_rectilinearGridTransform,       (void *)rectilinearGridTransform, 16);
    Select(ID_nodeOrigin,                     (void *)&nodeOrigin);
    Select(ID_containsExteriorBoundaryGhosts, (void *)&containsExteriorBoundaryGhosts);
    Select(ID_hideFromGUI,                    (void *)&hideFromGUI);
    Select(ID_LODs,                           (void *)&LODs);
    Select(ID_presentGhostZoneTypes,          (void *)&presentGhostZoneTypes);
    Select(ID_zonesWereSplit,                 (void *)&zonesWereSplit);
}

///////////////////////////////////////////////////////////////////////////////
// Set property methods
///////////////////////////////////////////////////////////////////////////////

///////////////////////////////////////////////////////////////////////////////
// Get property methods
///////////////////////////////////////////////////////////////////////////////

///////////////////////////////////////////////////////////////////////////////
// Keyframing methods
///////////////////////////////////////////////////////////////////////////////

// ****************************************************************************
// Method: avtMeshMetaData::GetFieldName
//
// Purpose:
//   This method returns the name of a field given its index.
//
// Note:       Autogenerated by xml2atts.
//
// Programmer: xml2atts
// Creation:   omitted
//
// Modifications:
//
// ****************************************************************************

std::string
avtMeshMetaData::GetFieldName(int index) const
{
    switch (index)
    {
    case ID_name:                           return "name";
    case ID_originalName:                   return "originalName";
    case ID_validVariable:                  return "validVariable";
    case ID_meshType:                       return "meshType";
    case ID_meshCoordType:                  return "meshCoordType";
    case ID_cellOrigin:                     return "cellOrigin";
    case ID_spatialDimension:               return "spatialDimension";
    case ID_hasLogicalBounds:               return "hasLogicalBounds";
    case ID_logicalBounds:                  return "logicalBounds";
    case ID_hasNumberCells:                 return "hasNumberCells";
    case ID_numberCells:                    return "numberCells";
    case ID_topologicalDimension:           return "topologicalDimension";
    case ID_xUnits:                         return "xUnits";
    case ID_yUnits:                         return "yUnits";
    case ID_zUnits:                         return "zUnits";
    case ID_xLabel:                         return "xLabel";
    case ID_yLabel:                         return "yLabel";
    case ID_zLabel:                         return "zLabel";
    case ID_hasSpatialExtents:              return "hasSpatialExtents";
    case ID_minSpatialExtents:              return "minSpatialExtents";
    case ID_maxSpatialExtents:              return "maxSpatialExtents";
    case ID_numBlocks:                      return "numBlocks";
    case ID_blockOrigin:                    return "blockOrigin";
    case ID_blockPieceName:                 return "blockPieceName";
    case ID_blockTitle:                     return "blockTitle";
    case ID_blockNames:                     return "blockNames";
    case ID_blockNameScheme:                return "blockNameScheme";
    case ID_numGroups:                      return "numGroups";
    case ID_groupOrigin:                    return "groupOrigin";
    case ID_groupPieceName:                 return "groupPieceName";
    case ID_groupTitle:                     return "groupTitle";
    case ID_groupNames:                     return "groupNames";
    case ID_groupIds:                       return "groupIds";
    case ID_groupIdsBasedOnRange:           return "groupIdsBasedOnRange";
    case ID_disjointElements:               return "disjointElements";
    case ID_containsGhostZones:             return "containsGhostZones";
    case ID_containsOriginalCells:          return "containsOriginalCells";
    case ID_containsOriginalNodes:          return "containsOriginalNodes";
    case ID_containsGlobalNodeIds:          return "containsGlobalNodeIds";
    case ID_containsGlobalZoneIds:          return "containsGlobalZoneIds";
    case ID_loadBalanceScheme:              return "loadBalanceScheme";
    case ID_nodesAreCritical:               return "nodesAreCritical";
    case ID_unitCellVectors:                return "unitCellVectors";
    case ID_unitCellOrigin:                 return "unitCellOrigin";
    case ID_rectilinearGridHasTransform:    return "rectilinearGridHasTransform";
    case ID_rectilinearGridTransform:       return "rectilinearGridTransform";
    case ID_nodeOrigin:                     return "nodeOrigin";
    case ID_containsExteriorBoundaryGhosts: return "containsExteriorBoundaryGhosts";
    case ID_hideFromGUI:                    return "hideFromGUI";
    case ID_LODs:                           return "LODs";
    case ID_presentGhostZoneTypes:          return "presentGhostZoneTypes";
    case ID_zonesWereSplit:                 return "zonesWereSplit";
    default:  return "invalid index";
    }
}

// ****************************************************************************
// Method: avtMeshMetaData::GetFieldType
//
// Purpose:
//   This method returns the type of a field given its index.
//
// Note:       Autogenerated by xml2atts.
//
// Programmer: xml2atts
// Creation:   omitted
//
// Modifications:
//
// ****************************************************************************

AttributeGroup::FieldType
avtMeshMetaData::GetFieldType(int index) const
{
    switch (index)
    {
    case ID_name:                           return FieldType_string;
    case ID_originalName:                   return FieldType_string;
    case ID_validVariable:                  return FieldType_bool;
    case ID_meshType:                       return FieldType_int;
    case ID_meshCoordType:                  return FieldType_int;
    case ID_cellOrigin:                     return FieldType_int;
    case ID_spatialDimension:               return FieldType_int;
    case ID_hasLogicalBounds:               return FieldType_bool;
    case ID_logicalBounds:                  return FieldType_intArray;
    case ID_hasNumberCells:                 return FieldType_bool;
    case ID_numberCells:                    return FieldType_int;
    case ID_topologicalDimension:           return FieldType_int;
    case ID_xUnits:                         return FieldType_string;
    case ID_yUnits:                         return FieldType_string;
    case ID_zUnits:                         return FieldType_string;
    case ID_xLabel:                         return FieldType_string;
    case ID_yLabel:                         return FieldType_string;
    case ID_zLabel:                         return FieldType_string;
    case ID_hasSpatialExtents:              return FieldType_bool;
    case ID_minSpatialExtents:              return FieldType_doubleArray;
    case ID_maxSpatialExtents:              return FieldType_doubleArray;
    case ID_numBlocks:                      return FieldType_int;
    case ID_blockOrigin:                    return FieldType_int;
    case ID_blockPieceName:                 return FieldType_string;
    case ID_blockTitle:                     return FieldType_string;
    case ID_blockNames:                     return FieldType_stringVector;
    case ID_blockNameScheme:                return FieldType_att;
    case ID_numGroups:                      return FieldType_int;
    case ID_groupOrigin:                    return FieldType_int;
    case ID_groupPieceName:                 return FieldType_string;
    case ID_groupTitle:                     return FieldType_string;
    case ID_groupNames:                     return FieldType_stringVector;
    case ID_groupIds:                       return FieldType_intVector;
    case ID_groupIdsBasedOnRange:           return FieldType_intVector;
    case ID_disjointElements:               return FieldType_bool;
    case ID_containsGhostZones:             return FieldType_int;
    case ID_containsOriginalCells:          return FieldType_bool;
    case ID_containsOriginalNodes:          return FieldType_bool;
    case ID_containsGlobalNodeIds:          return FieldType_bool;
    case ID_containsGlobalZoneIds:          return FieldType_bool;
    case ID_loadBalanceScheme:              return FieldType_int;
    case ID_nodesAreCritical:               return FieldType_bool;
    case ID_unitCellVectors:                return FieldType_floatArray;
    case ID_unitCellOrigin:                 return FieldType_floatArray;
    case ID_rectilinearGridHasTransform:    return FieldType_bool;
    case ID_rectilinearGridTransform:       return FieldType_doubleArray;
    case ID_nodeOrigin:                     return FieldType_int;
    case ID_containsExteriorBoundaryGhosts: return FieldType_bool;
    case ID_hideFromGUI:                    return FieldType_bool;
    case ID_LODs:                           return FieldType_int;
    case ID_presentGhostZoneTypes:          return FieldType_int;
    case ID_zonesWereSplit:                 return FieldType_bool;
    default:  return FieldType_unknown;
    }
}

// ****************************************************************************
// Method: avtMeshMetaData::GetFieldTypeName
//
// Purpose:
//   This method returns the name of a field type given its index.
//
// Note:       Autogenerated by xml2atts.
//
// Programmer: xml2atts
// Creation:   omitted
//
// Modifications:
//
// ****************************************************************************

std::string
avtMeshMetaData::GetFieldTypeName(int index) const
{
    switch (index)
    {
    case ID_name:                           return "string";
    case ID_originalName:                   return "string";
    case ID_validVariable:                  return "bool";
    case ID_meshType:                       return "avtMeshTypeField";
    case ID_meshCoordType:                  return "avtMeshCoordType";
    case ID_cellOrigin:                     return "int";
    case ID_spatialDimension:               return "int";
    case ID_hasLogicalBounds:               return "bool";
    case ID_logicalBounds:                  return "intArray";
    case ID_hasNumberCells:                 return "bool";
    case ID_numberCells:                    return "int";
    case ID_topologicalDimension:           return "int";
    case ID_xUnits:                         return "string";
    case ID_yUnits:                         return "string";
    case ID_zUnits:                         return "string";
    case ID_xLabel:                         return "string";
    case ID_yLabel:                         return "string";
    case ID_zLabel:                         return "string";
    case ID_hasSpatialExtents:              return "bool";
    case ID_minSpatialExtents:              return "doubleArray";
    case ID_maxSpatialExtents:              return "doubleArray";
    case ID_numBlocks:                      return "int";
    case ID_blockOrigin:                    return "int";
    case ID_blockPieceName:                 return "string";
    case ID_blockTitle:                     return "string";
    case ID_blockNames:                     return "stringVector";
    case ID_blockNameScheme:                return "att";
    case ID_numGroups:                      return "int";
    case ID_groupOrigin:                    return "int";
    case ID_groupPieceName:                 return "string";
    case ID_groupTitle:                     return "string";
    case ID_groupNames:                     return "stringVector";
    case ID_groupIds:                       return "intVector";
    case ID_groupIdsBasedOnRange:           return "intVector";
    case ID_disjointElements:               return "bool";
    case ID_containsGhostZones:             return "avtGhostType";
    case ID_containsOriginalCells:          return "bool";
    case ID_containsOriginalNodes:          return "bool";
    case ID_containsGlobalNodeIds:          return "bool";
    case ID_containsGlobalZoneIds:          return "bool";
    case ID_loadBalanceScheme:              return "LoadBalanceScheme";
    case ID_nodesAreCritical:               return "bool";
    case ID_unitCellVectors:                return "floatArray";
    case ID_unitCellOrigin:                 return "floatArray";
    case ID_rectilinearGridHasTransform:    return "bool";
    case ID_rectilinearGridTransform:       return "doubleArray";
    case ID_nodeOrigin:                     return "int";
    case ID_containsExteriorBoundaryGhosts: return "bool";
    case ID_hideFromGUI:                    return "bool";
    case ID_LODs:                           return "int";
    case ID_presentGhostZoneTypes:          return "int";
    case ID_zonesWereSplit:                 return "bool";
    default:  return "invalid index";
    }
}

// ****************************************************************************
// Method: avtMeshMetaData::FieldsEqual
//
// Purpose:
//   This method compares two fields and return true if they are equal.
//
// Note:       Autogenerated by xml2atts.
//
// Programmer: xml2atts
// Creation:   omitted
//
// Modifications:
//
// ****************************************************************************

bool
avtMeshMetaData::FieldsEqual(int index_, const AttributeGroup *rhs) const
{
    const avtMeshMetaData &obj = *((const avtMeshMetaData*)rhs);
    bool retval = false;
    switch (index_)
    {
    case ID_name:
        {  // new scope
        retval = (name == obj.name);
        }
        break;
    case ID_originalName:
        {  // new scope
        retval = (originalName == obj.originalName);
        }
        break;
    case ID_validVariable:
        {  // new scope
        retval = (validVariable == obj.validVariable);
        }
        break;
    case ID_meshType:
        {  // new scope
        retval = (meshType == obj.meshType);
        }
        break;
    case ID_meshCoordType:
        {  // new scope
        retval = (meshCoordType == obj.meshCoordType);
        }
        break;
    case ID_cellOrigin:
        {  // new scope
        retval = (cellOrigin == obj.cellOrigin);
        }
        break;
    case ID_spatialDimension:
        {  // new scope
        retval = (spatialDimension == obj.spatialDimension);
        }
        break;
    case ID_hasLogicalBounds:
        {  // new scope
        retval = (hasLogicalBounds == obj.hasLogicalBounds);
        }
        break;
    case ID_logicalBounds:
        {  // new scope
        // Compare the logicalBounds arrays.
        bool logicalBounds_equal = true;
        for(int i = 0; i < 3 && logicalBounds_equal; ++i)
            logicalBounds_equal = (logicalBounds[i] == obj.logicalBounds[i]);

        retval = logicalBounds_equal;
        }
        break;
    case ID_hasNumberCells:
        {  // new scope
        retval = (hasNumberCells == obj.hasNumberCells);
        }
        break;
    case ID_numberCells:
        {  // new scope
        retval = (numberCells == obj.numberCells);
        }
        break;
    case ID_topologicalDimension:
        {  // new scope
        retval = (topologicalDimension == obj.topologicalDimension);
        }
        break;
    case ID_xUnits:
        {  // new scope
        retval = (xUnits == obj.xUnits);
        }
        break;
    case ID_yUnits:
        {  // new scope
        retval = (yUnits == obj.yUnits);
        }
        break;
    case ID_zUnits:
        {  // new scope
        retval = (zUnits == obj.zUnits);
        }
        break;
    case ID_xLabel:
        {  // new scope
        retval = (xLabel == obj.xLabel);
        }
        break;
    case ID_yLabel:
        {  // new scope
        retval = (yLabel == obj.yLabel);
        }
        break;
    case ID_zLabel:
        {  // new scope
        retval = (zLabel == obj.zLabel);
        }
        break;
    case ID_hasSpatialExtents:
        {  // new scope
        retval = (hasSpatialExtents == obj.hasSpatialExtents);
        }
        break;
    case ID_minSpatialExtents:
        {  // new scope
        // Compare the minSpatialExtents arrays.
        bool minSpatialExtents_equal = true;
        for(int i = 0; i < 3 && minSpatialExtents_equal; ++i)
            minSpatialExtents_equal = (minSpatialExtents[i] == obj.minSpatialExtents[i]);

        retval = minSpatialExtents_equal;
        }
        break;
    case ID_maxSpatialExtents:
        {  // new scope
        // Compare the maxSpatialExtents arrays.
        bool maxSpatialExtents_equal = true;
        for(int i = 0; i < 3 && maxSpatialExtents_equal; ++i)
            maxSpatialExtents_equal = (maxSpatialExtents[i] == obj.maxSpatialExtents[i]);

        retval = maxSpatialExtents_equal;
        }
        break;
    case ID_numBlocks:
        {  // new scope
        retval = (numBlocks == obj.numBlocks);
        }
        break;
    case ID_blockOrigin:
        {  // new scope
        retval = (blockOrigin == obj.blockOrigin);
        }
        break;
    case ID_blockPieceName:
        {  // new scope
        retval = (blockPieceName == obj.blockPieceName);
        }
        break;
    case ID_blockTitle:
        {  // new scope
        retval = (blockTitle == obj.blockTitle);
        }
        break;
    case ID_blockNames:
        {  // new scope
        retval = (blockNames == obj.blockNames);
        }
        break;
    case ID_blockNameScheme:
        {  // new scope
        retval = (blockNameScheme == obj.blockNameScheme);
        }
        break;
    case ID_numGroups:
        {  // new scope
        retval = (numGroups == obj.numGroups);
        }
        break;
    case ID_groupOrigin:
        {  // new scope
        retval = (groupOrigin == obj.groupOrigin);
        }
        break;
    case ID_groupPieceName:
        {  // new scope
        retval = (groupPieceName == obj.groupPieceName);
        }
        break;
    case ID_groupTitle:
        {  // new scope
        retval = (groupTitle == obj.groupTitle);
        }
        break;
    case ID_groupNames:
        {  // new scope
        retval = (groupNames == obj.groupNames);
        }
        break;
    case ID_groupIds:
        {  // new scope
        retval = (groupIds == obj.groupIds);
        }
        break;
    case ID_groupIdsBasedOnRange:
        {  // new scope
        retval = (groupIdsBasedOnRange == obj.groupIdsBasedOnRange);
        }
        break;
    case ID_disjointElements:
        {  // new scope
        retval = (disjointElements == obj.disjointElements);
        }
        break;
    case ID_containsGhostZones:
        {  // new scope
        retval = (containsGhostZones == obj.containsGhostZones);
        }
        break;
    case ID_containsOriginalCells:
        {  // new scope
        retval = (containsOriginalCells == obj.containsOriginalCells);
        }
        break;
    case ID_containsOriginalNodes:
        {  // new scope
        retval = (containsOriginalNodes == obj.containsOriginalNodes);
        }
        break;
    case ID_containsGlobalNodeIds:
        {  // new scope
        retval = (containsGlobalNodeIds == obj.containsGlobalNodeIds);
        }
        break;
    case ID_containsGlobalZoneIds:
        {  // new scope
        retval = (containsGlobalZoneIds == obj.containsGlobalZoneIds);
        }
        break;
    case ID_loadBalanceScheme:
        {  // new scope
        retval = (loadBalanceScheme == obj.loadBalanceScheme);
        }
        break;
    case ID_nodesAreCritical:
        {  // new scope
        retval = (nodesAreCritical == obj.nodesAreCritical);
        }
        break;
    case ID_unitCellVectors:
        {  // new scope
        // Compare the unitCellVectors arrays.
        bool unitCellVectors_equal = true;
        for(int i = 0; i < 9 && unitCellVectors_equal; ++i)
            unitCellVectors_equal = (unitCellVectors[i] == obj.unitCellVectors[i]);

        retval = unitCellVectors_equal;
        }
        break;
    case ID_unitCellOrigin:
        {  // new scope
        // Compare the unitCellOrigin arrays.
        bool unitCellOrigin_equal = true;
        for(int i = 0; i < 3 && unitCellOrigin_equal; ++i)
            unitCellOrigin_equal = (unitCellOrigin[i] == obj.unitCellOrigin[i]);

        retval = unitCellOrigin_equal;
        }
        break;
    case ID_rectilinearGridHasTransform:
        {  // new scope
        retval = (rectilinearGridHasTransform == obj.rectilinearGridHasTransform);
        }
        break;
    case ID_rectilinearGridTransform:
        {  // new scope
        // Compare the rectilinearGridTransform arrays.
        bool rectilinearGridTransform_equal = true;
        for(int i = 0; i < 16 && rectilinearGridTransform_equal; ++i)
            rectilinearGridTransform_equal = (rectilinearGridTransform[i] == obj.rectilinearGridTransform[i]);

        retval = rectilinearGridTransform_equal;
        }
        break;
    case ID_nodeOrigin:
        {  // new scope
        retval = (nodeOrigin == obj.nodeOrigin);
        }
        break;
    case ID_containsExteriorBoundaryGhosts:
        {  // new scope
        retval = (containsExteriorBoundaryGhosts == obj.containsExteriorBoundaryGhosts);
        }
        break;
    case ID_hideFromGUI:
        {  // new scope
        retval = (hideFromGUI == obj.hideFromGUI);
        }
        break;
    case ID_LODs:
        {  // new scope
        retval = (LODs == obj.LODs);
        }
        break;
    case ID_presentGhostZoneTypes:
        {  // new scope
        retval = (presentGhostZoneTypes == obj.presentGhostZoneTypes);
        }
        break;
    case ID_zonesWereSplit:
        {  // new scope
        retval = (zonesWereSplit == obj.zonesWereSplit);
        }
        break;
    default: retval = false;
    }

    return retval;
}

///////////////////////////////////////////////////////////////////////////////
// User-defined methods.
///////////////////////////////////////////////////////////////////////////////

// ****************************************************************************
//  Method: avtMeshMetaData constructor
//
//  Arguments:
//      bounds      Strunctured mesh bounds as < max_i, max_j, max_k>.
//      extents     Mesh extents as <min_x, max_x, min_y, max_y, min_z, max_z>.
//      s           The name of the mesh.
//      nb          The number of blocks.
//      bo          The block origin.
//      sd          The spacial dimensionality.
//      td          The topological dimensionality.
//      mt          The type of mesh.
//
//  Programmer: Hank Childs
//  Creation:   August 25, 2000
//
//  Modifications:
//
//    Hank Childs, Tue May 28 13:57:49 PDT 2002
//    Initialized blockPieceName and blockTitle.
//
//    Hank Childs, Sun Jun 16 19:31:03 PDT 2002
//    Added argument for cell origin.
//
//    Hank Childs, Mon Jun 24 12:21:15 PDT 2002
//    Initialize numGroups.
//
//    Hank Childs, Sun Aug 18 10:54:26 PDT 2002
//    Initialized disjointElements.
//
//    Hank Childs, Mon Sep 30 08:57:30 PDT 2002
//    Initialized containsGhostZones.
//
//    Hank Childs, Mon Dec  9 17:04:39 PST 2002
//    Initialized validVariable.
//
//    Kathleen Bonnell, Wed Mar 26 13:03:54 PST 2003
//    Initialized containsOriginalCells.
//
//    Kathleen Bonnell, Fri May 28 18:16:48 PDT 2004
//    Initialized containsOriginalNodes.
//
//    Hank Childs, Sun Jun 27 11:50:34 PDT 2004
//    Initialized containsGlobalNodeIds.
//
//    Brad Whitlock, Fri Jul 23 12:25:03 PDT 2004
//    Added xLabel, yLabel, zLabel.
//
//    Mark C. Miller, August 9, 2004
//    Added containsGlobalZoneIds data member
//
//    Hank Childs, Mon Feb 14 14:16:49 PST 2005
//    Added original name.
//
//    Jeremy Meredith, Thu Aug 25 09:42:33 PDT 2005
//    Added group origin.
//
//    Mark C. Miller, Wed Nov 16 10:46:36 PST 2005
//    Added loadBalanceScheme
//
//    Kathleen Bonnell, Fri Feb  3 10:23:36 PST 2006
//    Added meshCoordType.
//
//    Jeremy Meredith, Fri Aug 25 17:14:58 EDT 2006
//    Added nodesAreCritical and unitCellVectors.
//
//    Jeremy Meredith, Thu Feb 15 11:42:44 EST 2007
//    Added support for rectilinear grids with an inherent transform.
//
//    Brad Whitlock, Thu Mar 1 16:36:37 PST 2007
//    Rewrote.
//
//    Hank Childs, Sun Oct 28 09:17:48 PST 2007
//    Added containsExteriorBoundaryGhosts
//
// ****************************************************************************

avtMeshMetaData::avtMeshMetaData(const int *bounds, const double *extents,
                                 std::string s, int nb,
                                 int bo, int co, int go, int sd, int td,
                                 avtMeshType mt)
    : AttributeSubject(avtMeshMetaData::TypeMapFormatString)
{
    // Initialize all values.
    *this = avtMeshMetaData();

    // Override some initialization with the passed arguments.
    name                 = s;
    originalName         = name;
    numBlocks            = nb;
    blockOrigin          = bo;
    cellOrigin           = co;
    groupOrigin          = go;
    topologicalDimension = td;
    spatialDimension     = sd;
    meshType             = mt;
    numGroups            = 0;
    containsExteriorBoundaryGhosts = false;
    SetExtents(extents);
    SetBounds(bounds);
}

// ****************************************************************************
//  Method: avtMeshMetaData constructor
//
//  Arguments:
//      s           The name of the mesh.
//      nb          The number of blocks.
//      bo          The block origin.
//      sd          The spacial dimensionality.
//      td          The topological dimensionality.
//      mt          The type of mesh.
//
//  Programmer: Hank Childs
//  Creation:   August 25, 2000
//
//  Modifications:
//
//    Hank Childs, Tue May 28 13:57:49 PDT 2002
//    Initialized blockPieceName and blockTitle.
//
//    Hank Childs, Sun Jun 16 19:31:03 PDT 2002
//    Added argument for cell origin.
//
//    Hank Childs, Mon Jun 24 12:21:15 PDT 2002
//    Initialize numGroups.
//
//    Hank Childs, Sun Aug 18 10:54:26 PDT 2002
//    Initialized disjointElements.
//
//    Hank Childs, Mon Sep 30 08:57:30 PDT 2002
//    Initialized containsGhostZones.
//
//    Hank Childs, Mon Dec  9 17:04:39 PST 2002
//    Initialized validVariable.
//
//    Kathleen Bonnell, Wed Mar 26 13:03:54 PST 2003
//    Initialized containsOriginalCells.
//
//    Kathleen Bonnell, Fri May 28 18:16:48 PDT 2004
//    Initialized containsOriginalNodes.
//
//    Hank Childs, Sun Jun 27 11:50:34 PDT 2004
//    Initialized containsGlobalNodeIds.
//
//    Brad Whitlock, Fri Jul 23 12:25:22 PDT 2004
//    Added xLabel, yLabel, zLabel.
//
//    Mark C. Miller, August 9, 2004
//    Added containsGlobalZoneIds data member
//
//    Hank Childs, Mon Feb 14 14:16:49 PST 2005
//    Added original name.
//
//    Jeremy Meredith, Thu Aug 25 09:42:37 PDT 2005
//    Added group origin.
//
//    Mark C. Miller, Wed Nov 16 10:46:36 PST 2005
//    Added loadBalanceScheme
//
//    Kathleen Bonnell, Fri Feb  3 10:23:36 PST 2006
//    Added meshCoordType.
//
//    Mark C. Miller, Tue Aug 15 21:48:46 PDT 2006
//    Called SetExtents to initialize extents. Keeps purify happy.
//
//    Jeremy Meredith, Fri Aug 25 17:14:58 EDT 2006
//    Added nodesAreCritical and unitCellVectors.
//
//    Jeremy Meredith, Thu Feb 15 11:42:44 EST 2007
//    Added support for rectilinear grids with an inherent transform.
//
//    Brad Whitlock, Thu Mar 1 16:37:16 PST 2007
//    Rewrote.
//
//    Hank Childs, Sun Oct 28 09:17:48 PST 2007
//    Added containsExteriorBoundaryGhosts
//
// ****************************************************************************

avtMeshMetaData::avtMeshMetaData(std::string s, int nb, int bo, int co, int go,
                                 int sd, int td, avtMeshType mt)
    : AttributeSubject(avtMeshMetaData::TypeMapFormatString)
{
    // Initialize all values.
    *this = avtMeshMetaData();

    // Override some initialization with the passed arguments.
    name                 = s;
    originalName         = name;
    numBlocks            = nb;
    blockOrigin          = bo;
    cellOrigin           = co;
    groupOrigin          = go;
    topologicalDimension = td;
    spatialDimension     = sd;
    meshType             = mt;
    containsExteriorBoundaryGhosts = false;
    SetExtents(0);
    SetBounds(0);
}

// ****************************************************************************
//  Method: avtMeshMetaData::SetExtents
//
//  Purpose:
//      Sets the extents of the mesh.
//
//  Arguments:
//      extents     Mesh extents as <min_x, max_x, min_y, max_y, min_z, max_z>.
//
//  Programmer: Hank Childs
//  Creation:   August 30, 2000
//
//  Modifications:
//
//    Hank Childs, Tue May  1 12:53:10 PDT 2001
//    Check for NULL extents.
//
//    Mark C. Miller, Tue Aug 15 21:45:50 PDT 2006
//    Added code to initialize extents to [0,1] if null was passed in. Keeps
//    purify happy.
//
//    Dave Pugmire, Tue Jan 11 16:26:35 EST 2011
//    Protect against spatialDims > 3.
// ****************************************************************************

void
avtMeshMetaData::SetExtents(const double *extents)
{
    if (extents == NULL)
    {
        hasSpatialExtents = false;
        for (int i = 0 ; i < std::min(spatialDimension, 3) ; i++)
        {
            minSpatialExtents[i] = 0.0;
            maxSpatialExtents[i] = 1.0;
        }
    }
    else
    {
        hasSpatialExtents = true;
        for (int i = 0 ; i < std::min(spatialDimension, 3) ; i++)
        {
            minSpatialExtents[i] = extents[2*i];
            maxSpatialExtents[i] = extents[2*i + 1];
        }
    }
}

void
avtMeshMetaData::UnsetExtents()
{
    hasSpatialExtents = false;
}

// ****************************************************************************
//  Method: avtMeshMetaData::SetBounds
//
//  Purpose:
//      Sets the logical bounds of a structured mesh.
//
//  Arguments:
//      bounds     Mesh bounds as < i_max, j_max, k_max>.
//
//  Creationist: Allen Sanderson
//  Creation:    March 3, 2011
//
//  Modifications:
//    Mark C. Miller, Tue Apr 19 14:46:23 PDT 2011
//    Set logical bounds to integer value '0' and not '0.0'.
// ****************************************************************************

void
avtMeshMetaData::SetBounds(const int *bounds)
{
    if (bounds == NULL)
    {
        hasLogicalBounds = false;
        for (int i = 0 ; i < std::min(topologicalDimension, 3) ; i++)
        {
            logicalBounds[i] = 0;
        }
    }
    else
    {
        hasLogicalBounds = true;
        for (int i = 0 ; i < std::min(topologicalDimension, 3) ; i++)
        {
            logicalBounds[i] = bounds[i];
        }
    }
}

void
avtMeshMetaData::UnsetBounds()
{
    hasLogicalBounds = false;
}

// ****************************************************************************
//  Method: avtMeshMetaData::SetNumberCells
//
//  Purpose:
//      Sets the number of cells for a mesh.
//
//  Arguments:
//      numberCells     Number if mesh cells as < nCells >.
//
//  Creationist: Allen Sanderson
//  Creation:    July 27, 2011
//
// ****************************************************************************

void
avtMeshMetaData::SetNumberCells(const int nCells)
{
    hasNumberCells = (nCells > 0);

    numberCells = (nCells > 0 ? nCells : 0 );
}

void
avtMeshMetaData::UnsetNumberCells()
{
    hasNumberCells = false;
}

// ****************************************************************************
//  Method: avtMeshMetaData::Print
//
//  Purpose:
//      Print statement for debugging.
//
//  Arguments:
//      out      The stream to output to.
//      indent   The number of tabs to indent each line with.
//
//  Programmer:  Hank Childs
//  Creation:    August 28, 2000
//
//  Modifications:
//
//    Hank Childs, Tue Aug 28 10:16:24 PDT 2001
//    Added block names.
//
//    Hank Childs, Tue May 28 13:57:49 PDT 2002
//    Added blockPieceName and blockTitle.
//
//    Hank Childs, Sun Jun 16 19:31:03 PDT 2002
//    Added cell origin.
//
//    Hank Childs, Mon Jun 24 12:21:15 PDT 2002
//    Added numGroups.
//
//    Hank Childs, Sun Aug 18 10:54:26 PDT 2002
//    Added disjointElements.
//
//    Brad Whitlock, Tue Aug 20 15:11:14 PST 2002
//    Changed printing a little.
//
//    Hank Childs, Thu Sep 26 22:01:55 PDT 2002
//    Added units.
//
//    Hank Childs, Mon Sep 30 08:57:30 PDT 2002
//    Added containsGhostZones.
//
//    Hank Childs, Mon Dec  9 17:04:39 PST 2002
//    Added validVariable.
//
//    Kathleen Bonnell, Wed Mar 26 13:03:54 PST 2003
//    Added containsOriginalCells.
//
//    Kathleen Bonnell, Fri May 28 18:16:48 PDT 2004
//    Added containsOriginalNodes.
//
//    Brad Whitlock, Fri Jul 23 12:28:21 PDT 2004
//    Added xLabel, yLabel, and zLabel.
//
//    Hank Childs, Mon Feb 14 14:16:49 PST 2005
//    Added original name.
//
//    Jeremy Meredith, Thu Aug 25 09:42:47 PDT 2005
//    Added group origin.
//
//    Mark C. Miller, Wed Nov 16 10:46:36 PST 2005
//    Added loadBalanceScheme
//
//    Hank Childs, Wed Jan 11 09:36:13 PST 2006
//    Added new mesh types.
//
//    Kathleen Bonnell, Fri Feb  3 10:23:36 PST 2006
//    Added meshCoordType.
//
//    Jeremy Meredith, Fri Aug 25 17:14:58 EDT 2006
//    Added nodesAreCritical and unitCellVectors.
//
//    Jeremy Meredith, Thu Feb 15 11:42:44 EST 2007
//    Added support for rectilinear grids with an inherent transform.
//
//    Mark C. Miller, Tue Mar 27 08:39:55 PDT 2007
//    Added support for node origin
//
//    Hank Childs, Sun Oct 28 09:17:48 PST 2007
//    Added containsExteriorBoundaryGhosts
//
//    Hank Childs, Fri Dec 11 14:17:12 PST 2009
//    Add support for new SIL-efficiency data members.
//
// ****************************************************************************
inline void
Indent(ostream &out, int indent)
{
    for (int i = 0 ; i < indent ; i++)
    {
        out << "\t";
    }
}

void
avtMeshMetaData::Print(ostream &out, int indent) const
{
    Indent(out, indent);
    out << "Name = " << name.c_str() << std::endl;
    if (name != originalName)
    {
        Indent(out, indent);
        out << "Original Name = " << originalName.c_str() << std::endl;
    }
    Indent(out, indent);
    out << "Number of blocks = " << numBlocks << std::endl;
    Indent(out, indent);
    out << "Block origin = " << blockOrigin << std::endl;
    Indent(out, indent);
    out << "Cell origin = " << cellOrigin
        << " (origin within one block of the cells)." << std::endl;
    Indent(out, indent);
    out << "Node origin = " << nodeOrigin
        << " (origin within one block of the nodes)." << std::endl;
    Indent(out, indent);
    out << "Group origin = " << groupOrigin << std::endl;
    Indent(out, indent);
    out << "Title for domain hierarchy is " << blockTitle.c_str() << std::endl;
    Indent(out, indent);
    out << "Title for individual piece in domain hierarchy is "
        << blockPieceName.c_str() << std::endl;
    if (blockNameScheme.GetNamescheme() != "")
    {
        Indent(out, indent);
        out << "The name scheme is: " << blockNameScheme.GetNamescheme() << std::endl;
    }

    Indent(out, indent);
    out << "Number of groups = " << numGroups << std::endl;
    if(numGroups > 0)
    {
        Indent(out, indent);
        out << "Group ids are: ";
        if (groupIdsBasedOnRange.size() > 0)
        {
            for (size_t i = 0 ; i < groupIdsBasedOnRange.size()-1 ; i++)
            {
                out << i << ": " << groupIdsBasedOnRange[i] << "-"
                    << groupIdsBasedOnRange[i+1]-1;
                if (i < groupIdsBasedOnRange.size()-1)
                    out << ", ";
            }
        }
        else
        {
            for (size_t i = 0 ; i < groupIds.size() ; i++)
            {
                out << groupIds[i];
                if(i < groupIds.size() - 1)
                    out << ", ";
            }
        }
        out << std::endl;
    }
    Indent(out, indent);
    out << "Title for group hierarchy is " << groupTitle.c_str() << std::endl;
    Indent(out, indent);
    out << "Title for individual piece in group hierarchy is "
        << groupPieceName.c_str() << std::endl;

    Indent(out, indent);
    out << "Mesh type is ";
    switch (meshType)
    {
      case AVT_RECTILINEAR_MESH:
        out << "Rectilinear Mesh";
        break;

      case AVT_CURVILINEAR_MESH:
        out << "Curvilinear Mesh";
        break;

      case AVT_UNSTRUCTURED_MESH:
        out << "Unstructured Mesh";
        break;

      case AVT_POINT_MESH:
        out << "Point Mesh";
        break;

      case AVT_SURFACE_MESH:
        out << "Surface Mesh";
        break;

      case AVT_CSG_MESH:
        out << "CSG Mesh";
        break;

      case AVT_AMR_MESH:
        out << "AMR Mesh";
        break;

      case AVT_UNKNOWN_MESH:
      default:
        out << "Unknown";
        break;
    }
    out << "." << std::endl;

    Indent(out, indent);
    out << "Spatial Dimension = " << spatialDimension << std::endl;

    if (hasSpatialExtents)
    {
        Indent(out, indent);
        out << "Spatial extents are: (";
        for (int j = 0 ; j < std::min(spatialDimension, 3) ; j++)
        {
            out << "(" << minSpatialExtents[j] << ", " << maxSpatialExtents[j]
                << ")";
            if(j < spatialDimension-1)
                out << ", ";
        }
        out << ")" << std::endl;
    }
    else
    {
        Indent(out, indent);
        out << "The spatial extents are not set." << std::endl;
    }

    Indent(out, indent);
    out << "Topological Dimension = " << topologicalDimension << std::endl;

    if (hasLogicalBounds || hasNumberCells )
    {
        switch (meshType)
        {
          case AVT_RECTILINEAR_MESH:
          case AVT_CURVILINEAR_MESH:
            Indent(out, indent);
            out << "Logical nodal bounds are (";
            for (int j = 0 ; j < std::min(topologicalDimension, 3) ; j++)
            {
              out << logicalBounds[j];
              if(j < topologicalDimension-1)
                  out << ", ";
            }
            out << ")" << std::endl;
            break;
          case AVT_POINT_MESH:
          case AVT_UNSTRUCTURED_MESH:
            Indent(out, indent);
            out << "Logical cell bound is (" << numberCells << ")"
                << std::endl;
            break;

//        Report nothing as the logical bounds are not applicable
          default:
            out << "The logical nodal bounds or number of cells are set but not applicable."
                << std::endl;
            break;
        }
    }
    else
    {
        switch (meshType)
        {
          case AVT_RECTILINEAR_MESH:
          case AVT_CURVILINEAR_MESH:
            Indent(out, indent);
            out << "The logical nodal bounds are not set." << std::endl;
            break;
          case AVT_POINT_MESH:
          case AVT_UNSTRUCTURED_MESH:
            Indent(out, indent);
            out << "The logical cell bound are not set." << std::endl;
            break;

          // Report nothing as the logical bounds are not applicable
          default:
            // out << "The logical bounds are not applicable." << std::endl;
            break;
        }
    }

    if (hasNumberCells)
    {
        Indent(out, indent);
        out << "Number of cells is " << numberCells << std::endl;
    }
    else
    {
        switch (meshType)
        {
          case AVT_UNSTRUCTURED_MESH:
          case AVT_RECTILINEAR_MESH:
          case AVT_CURVILINEAR_MESH:
          case AVT_POINT_MESH:
            Indent(out, indent);
            out << "The number of cells is not set." << std::endl;
            break;

          // Report nothing as the number of cells is not applicable
          default:
            // out << "The number of cells is not applicable." << std::endl;
            break;
        }
    }


    if (blockNames.size() == (size_t)numBlocks)
    {
        Indent(out, indent);
        out << "Block names: " << std::endl;
        for (int i = 0 ; i < numBlocks ; i++)
        {
            Indent(out, indent);
            out << "\t" << blockNames[i].c_str() << std::endl;
        }
    }
    else
    {
        Indent(out, indent);
        out << "There are no names set with the blocks." << std::endl;
    }

    Indent(out, indent);
    out << "Disjoint elements " << (disjointElements ? "Yes" : "No")
        << std::endl;

    if( containsGhostZones )
    {
      Indent(out, indent);
      if( containsGhostZones == AVT_HAS_GHOSTS )
        out << "Contains ghost zones " << "Yes" << std::endl;

      else if( containsGhostZones == AVT_CREATED_GHOSTS )
        out << "Contains ghost zones " << "Created" << std::endl;

      else if( containsGhostZones == AVT_MAYBE_GHOSTS )
        out << "Contains ghost zones " << "Maybe" << std::endl;

      if (containsExteriorBoundaryGhosts)
      {
        Indent(out, indent);
        out << "Contains ghost zones on the exterior boundary" << std::endl;
      }
    }

    Indent(out, indent);
    out << "Contains original cells " << (containsOriginalCells ? "Yes" : "No")
        << std::endl;

    Indent(out, indent);
    out << "Contains original nodes " << (containsOriginalNodes ? "Yes" : "No")
        << std::endl;

    Indent(out, indent);
    out << "Units =  x: \"" << xUnits.c_str()
        << "\", y: \"" << yUnits.c_str()
        << "\", z: \"" << zUnits.c_str() << "\"." << std::endl;

    Indent(out, indent);
    out << "Labels =  x: \"" << xLabel.c_str()
        << "\", y: \"" << yLabel.c_str()
        << "\", z: \"" << zLabel.c_str() << "\"." << std::endl;

    if (!validVariable)
    {
        Indent(out, indent);
        out << "THIS IS NOT A VALID VARIABLE." << std::endl;
    }

    if (loadBalanceScheme != LOAD_BALANCE_UNKNOWN)
    {
        Indent(out, indent);
        out << "HAS A SPECIFIC LOAD BALANCE SCHEME = "
            << loadBalanceScheme << std::endl;
    }
    if (meshCoordType == AVT_XY)
    {
        Indent(out, indent);
        out << "Mesh coord type is XY" << std::endl;
    }
    else if (meshCoordType == AVT_RZ)
    {
        Indent(out, indent);
        out << "Mesh coord type is RZ" << std::endl;
    }
    else if (meshCoordType == AVT_ZR)
    {
        Indent(out, indent);
        out << "Mesh coord type is ZR" << std::endl;
    }

    Indent(out, indent);
    out << "Mesh is primarily "
        << (nodesAreCritical ? "point" : "cell") << "-based" << std::endl;

    for (int i=0; i<3; i++)
    {
        Indent(out, indent);
        out << "Unit cell vector #"<<i<<" is "
            << unitCellVectors[i*3+0] << " "
            << unitCellVectors[i*3+1] << " "
            << unitCellVectors[i*3+2] << std::endl;
    }

    Indent(out, indent);
    out << "Rectilinear grids "
        << (rectilinearGridHasTransform ? "do " : "do not ")
        << "have an implicit transform." << std::endl;
    if (rectilinearGridHasTransform)
    {
        for (int i=0; i<4; i++)
        {
            Indent(out, indent);
            out << "   [ "
                << rectilinearGridTransform[i*4+0] << " "
                << rectilinearGridTransform[i*4+1] << " "
                << rectilinearGridTransform[i*4+2] << " "
                << rectilinearGridTransform[i*4+3] << " "
                << "]" << std::endl;
        }
    }
}

// ****************************************************************************
//  Method: avtMeshMetaData::SetAMRInfo
//
//  Purpose:
//      Sets meta data for AMR meshes.  Specifically, it sets up the names
//      for the levels/patches and the information between the levels and
//      the patches.
//
//  Programmer: Hank Childs
//  Creation:   December 11, 2009
//
//  Modifications:
//
//    Hank Childs, Mon Jun 14 14:27:16 PDT 2010
//    Fix crash for nlevels == 1 && patchs -> patches.
//
// ****************************************************************************

void
avtMeshMetaData::SetAMRInfo(const std::string &levelName,
                            const std::string &patchName, int origin,
                            const std::vector<int> &patchesPerLevel)
{
    int  i;
    int  nlevels = (int)patchesPerLevel.size();

    // Basic setup stuff
    int  numBlocks = 0;
    for (i = 0 ; i < nlevels ; i++)
        numBlocks += patchesPerLevel[i];
    this->numBlocks = numBlocks;
    this->blockTitle = patchName + "s";
    if (patchName == "patch" || patchName == "Patch")
        this->blockTitle = patchName + "es";
    this->blockPieceName = patchName;
    this->numGroups = nlevels;
    this->groupTitle = levelName + "s";
    this->groupPieceName = levelName;
    this->blockOrigin = origin;
    this->groupOrigin = origin;

    std::vector<int> groupIds(nlevels+1);
    groupIds[0] = 0;
    for (i = 1 ; i < nlevels+1 ; i++)
    {
        groupIds[i] = groupIds[i-1] + patchesPerLevel[i-1];
    }
    this->groupIdsBasedOnRange = groupIds;
    std::vector<int> numbelow(nlevels);
    numbelow[0] = 0;
    for (i = 1 ; i < nlevels ; i++)
        numbelow[i] = numbelow[i-1]+patchesPerLevel[i-1];
    char str[128];
    sprintf(str, "@%s%%d,%s%%d@", levelName.c_str(), patchName.c_str());
    std::string base_string = str;
    for (i = 1 ; i < nlevels ; i++)
    {
        sprintf(str, "(n/%d)", numbelow[i]);
        base_string += str;
        if (i != (nlevels-1))
            base_string += "?(";
    }
    for (i = nlevels-1 ; i >= 0 ; i--)
    {
        if (i == (nlevels-1))
            sprintf(str, "?%d", i+origin);
        else if (i > 0)
            sprintf(str, ":%d:)", i+origin);
        else
            sprintf(str, ":%d:@", i+origin);
        base_string += str;
    }
    for (i = 1 ; i < nlevels ; i++)
    {
        sprintf(str, "(n/%d)", numbelow[i]);
        base_string += str;
        if (i != (nlevels-1))
            base_string += "?(";
        else
            base_string += "?";
    }
    for (i = nlevels-1 ; i >= 0 ; i--)
    {
        if (i == (nlevels-1))
            sprintf(str, "n+%d-%d", origin, numbelow[i]);
        else if (i > 0)
            sprintf(str, ":n+%d-%d:)", origin, numbelow[i]);
        else
            sprintf(str, ":n+%d:", origin);
        base_string += str;
    }
    if (nlevels <= 1)
    {
        // logic above doesn't work for nlevels == 1, just override
        sprintf(str, "@%s%d,%s%%d@n+%d:", levelName.c_str(), origin,
                                          patchName.c_str(), origin);
        base_string = str;
    }

    NameschemeAttributes atts;
    atts.SetNamescheme(base_string);
    this->blockNameScheme = atts;
}

