/** \brief Create a structured cube grid
      \param lowerLeft Lower left corner of the grid
      \param upperRight Upper right corner of the grid
      \param elements Number of elements in each coordinate direction
  */
  static std::unique_ptr<GridType>
  createCubeGrid(const FieldVector<ctype, dim> &lowerLeft,
                 const FieldVector<ctype, dim> &upperRight,
                 const array<int, dim> &elements) {
    // The grid factory
    GridFactory<GridType> factory;

    if (MPIHelper::getCollectiveCommunication().rank() == 0) {
      // Insert uniformly spaced vertices
      array<int, dim> vertices = elements;
      for (int i = 0; i < vertices.size(); ++i)
        vertices[i]++;

      // Insert vertices for structured grid into the factory
      insertVertices(factory, lowerLeft, upperRight, vertices);

      // Compute the index offsets needed to move to the adjacent
      // vertices in the different coordinate directions
      array<int, dim> unitOffsets = computeUnitOffsets(vertices);

      // Compute an element template (the cube at (0,...,0).  All
      // other cubes are constructed by moving this template around
      int nCorners = 1 << dim;

      std::vector<int> cornersTemplate(nCorners, 0);

      for (int i = 0; i < nCorners; i++)
        for (int j = 0; j < dim; j++)
          if (i & (1 << j))
            cornersTemplate[i] += unitOffsets[j];

      // Insert elements
      MultiIndex index(elements);

      // Compute the total number of elementss to be created
      int numElements = index.cycle();

      for (int i = 0; i < numElements; i++, ++index) {

        // 'base' is the index of the lower left element corner
        int base = 0;
        for (int j = 0; j < dim; j++)
          base += index[j] * unitOffsets[j];

        // insert new element
        std::vector<int> corners = cornersTemplate;
        for (size_t j = 0; j < corners.size(); j++)
          corners[j] += base;

        factory.insertElement(GeometryType(GeometryType::cube, dim), corners);
      }

    } // if(rank == 0)

    // Create the grid and hand it to the calling method
    return std::unique_ptr<GridType>(factory.createGrid());
  }
bool ITR3DMImport::import(const char* file, ITRGeometry* geometry,
	Vector<UInt32>* volumeMasks)
{
   TPlaneF::DistancePrecision = distancePrecision;
   TPlaneF::NormalPrecision   = normalPrecision;
   char buff[256];

   //
   printf("Thred.3DM Import\n");

   PolyList polyList;
   printf("   Importing...");
   import(file,&polyList);

#if 0
	// This is now down by Zed.
   // Texture mapping
   printf("Texturing...");
   for (int i = 0; i < polyList.size(); i++)
      boxMap(polyList[i]);
#endif

   // Split polys whose textures are larger than 256x256
   printf("Splitting...");
   for (int i = 0; i < polyList.size(); i++) {
      Poly* poly = polyList[i];
      if (poly->textureSize.x > splitDist)
         splitX(poly,&polyList);
      if (poly->textureSize.y > splitDist)
         splitY(poly,&polyList);
   }

   printf("Material Sorting...");
   sortByMaterial(polyList);

   if (lowDetailInterior == false) {
      // Insert colinear vertices into polygons
      printf("SharedVertices...");
      insertVertices(polyList);
   } else {
      printf("LowDetail (Shared Vertices not inserted)...");
      geometry->setFlag(ITRGeometry::LowDetailInterior);
   }

   //
   printf("Export...");
   exportToGeometry(polyList, geometry, volumeMasks);
   geometry->highestMipLevel = maxMipLevel;
   printf("\n");

   //
   printf("   Vertices: %d\n", geometry->point3List.size());
   printf("   Surfaces: %d\n", geometry->surfaceList.size());
   printf("   Planes: %d\n",   geometry->planeList.size());
   return true;
}
  /** \brief Create a structured simplex grid

      This works in all dimensions.  The Coxeter-Freudenthal-Kuhn triangulation
     is
      used, which splits each cube into dim! simplices.  See Allgower and Georg,
      'Numerical Path Following' for a description.
  */
  static std::unique_ptr<GridType>
  createSimplexGrid(const FieldVector<ctype, dim> &lowerLeft,
                    const FieldVector<ctype, dim> &upperRight,
                    const array<int, dim> &elements) {
    // The grid factory
    GridFactory<GridType> factory;

    if (MPIHelper::getCollectiveCommunication().rank() == 0) {
      // Insert uniformly spaced vertices
      array<int, dim> vertices = elements;
      for (std::size_t i = 0; i < vertices.size(); i++)
        vertices[i]++;

      insertVertices(factory, lowerLeft, upperRight, vertices);

      // Compute the index offsets needed to move to the adjacent
      // vertices in the different coordinate directions
      array<int, dim> unitOffsets = computeUnitOffsets(vertices);

      // Insert the elements
      std::vector<int> corners(dim + 1);

      // Loop over all "cubes", and split up each cube into dim!
      // (factorial) simplices
      MultiIndex elementsIndex(elements);
      int cycle = elementsIndex.cycle();

      for (int i = 0; i < cycle; ++elementsIndex, i++) {

        // 'base' is the index of the lower left element corner
        int base = 0;
        for (int j = 0; j < dim; j++)
          base += elementsIndex[j] * unitOffsets[j];

        // each permutation of the unit vectors gives a simplex.
        std::vector<unsigned int> permutation(dim);
        for (int j = 0; j < dim; j++)
          permutation[j] = j;

        // A hack for triangular lattices: swap the two last
        // vertices of every second triangle to uniformize orientation
        // of their normals
        int triangle = 0;
        do {

          // Make a simplex
          std::vector<unsigned int> corners(dim + 1);
          corners[0] = base;

          for (int j = 0; j < dim; j++)
            corners[j + 1] = corners[j] + unitOffsets[permutation[j]];
          if (dim == 2 && triangle == 1)
            std::swap(corners[1], corners[2]);
          ++triangle;

          factory.insertElement(GeometryType(GeometryType::simplex, dim),
                                corners);

        } while (std::next_permutation(permutation.begin(), permutation.end()));
      }

    } // if(rank == 0)

    // Create the grid and hand it to the calling method
    return std::unique_ptr<GridType>(factory.createGrid());
  }