/* This file is part of the Neper software package. */
/* Copyright (C) 2003-2014, Romain Quey. */
/* See the COPYING file in the top-level directory. */

#include"net_seed_reg_.h"

void
net_seed_reg_square (struct TESS Dom, struct SEEDSET *pGSet)
{
  int x, y, nb;
  double *coo = ut_alloc_1d (3);

  /* IniSeedCoo initializes the variable: SeedCoo */
  (*pGSet).SeedCoo = ut_alloc_2d ((*pGSet).N1d * (*pGSet).N1d
				  * (*pGSet).N1d + 1, 3);

  (*pGSet).Size = ut_alloc_2d (3, 2);
  neut_tess_bbox (Dom, (*pGSet).Size);

  /* SeedCoo is filled line by line. */
  nb = 0;
  coo[2] = 0.5 * ((*pGSet).Size[2][1] - (*pGSet).Size[2][0]) / (*pGSet).N1d;
  for (y = 1; y <= (*pGSet).N1d; y++)
  {
    coo[1] = (*pGSet).Size[1][0] + (y - 0.5) / (*pGSet).N1d *
      ((*pGSet).Size[1][1] - (*pGSet).Size[1][0]);
    for (x = 1; x <= (*pGSet).N1d; x++)
    {
      coo[0] = (*pGSet).Size[0][0] + (x - 0.5) / (*pGSet).N1d *
	((*pGSet).Size[0][1] - (*pGSet).Size[0][0]);

      ut_array_1d_memcpy ((*pGSet).SeedCoo[++nb], 3, coo);
    }
  }

  (*pGSet).N = pow ((*pGSet).N1d, 2);

  ut_free_1d (coo);

  return;
}

void
net_seed_reg_cube (struct TESS Dom, struct SEEDSET *pGSet)
{
  int x, y, z, nb;
  double *coo = NULL;

  /* IniSeedCoo initializes the variable: SeedCoo */
  (*pGSet).SeedCoo = ut_alloc_2d ((*pGSet).N1d * (*pGSet).N1d
				  * (*pGSet).N1d + 1, 3);

  (*pGSet).Size = ut_alloc_2d (3, 2);
  neut_tess_bbox (Dom, (*pGSet).Size);

  coo = ut_alloc_1d (3);

  /* SeedCoo is filled line by line. */
  nb = 0;
  for (z = 1; z <= (*pGSet).N1d; z++)
  {
    coo[2] = (*pGSet).Size[2][0] + (z - 0.5) / (*pGSet).N1d *
      ((*pGSet).Size[2][1] - (*pGSet).Size[2][0]);
    for (y = 1; y <= (*pGSet).N1d; y++)
    {
      coo[1] = (*pGSet).Size[1][0] + (y - 0.5) / (*pGSet).N1d *
	((*pGSet).Size[1][1] - (*pGSet).Size[1][0]);
      for (x = 1; x <= (*pGSet).N1d; x++)
      {
	coo[0] = (*pGSet).Size[0][0] + (x - 0.5) / (*pGSet).N1d *
	  ((*pGSet).Size[0][1] - (*pGSet).Size[0][0]);

	ut_array_1d_memcpy ((*pGSet).SeedCoo[++nb], 3, coo);
      }
    }
  }

  (*pGSet).N = pow ((*pGSet).N1d, 3);

  ut_free_1d (coo);

  return;
}

void
net_seed_reg_tocta (struct TESS Dom, struct SEEDSET *pGSet)
{
  int x, y, z, i, j, nb;
  int n = 1 + ut_num_d2ri ((*pGSet).N1d);
  double *coo = ut_alloc_1d (3);

  (*pGSet).Size = ut_alloc_2d (3, 2);
  neut_tess_bbox (Dom, (*pGSet).Size);

  double **bbox = (*pGSet).Size;

  /* IniSeedCoo initializes the variable: SeedCoo */
  (*pGSet).SeedCoo = ut_alloc_1d_pdouble (1);

  /* SeedCoo is filled line by line. */
  nb = 0;
  for (x = 1; x < n; x++)
  {
    coo[0] = bbox[0][0] + (x - 0.5) / (n - 1) * (bbox[0][1] - bbox[0][0]);
    for (y = 1; y < n; y++)
    {
      coo[1] = bbox[1][0] + (y - 0.5) / (n - 1) * (bbox[1][1] - bbox[1][0]);
      for (z = 1; z < n; z++)
      {
	coo[2] = bbox[2][0] + (z - 0.5) / (n - 1) * (bbox[2][1] - bbox[2][0]);

	(*pGSet).SeedCoo
	  = ut_realloc_2d_addline ((*pGSet).SeedCoo, ++nb + 1, 3);

	ut_array_1d_memcpy ((*pGSet).SeedCoo[nb], 3, coo);
      }
    }
  }

  for (x = 0; x < n; x++)
  {
    coo[0] = bbox[0][0] + (double) x / (n - 1) * (bbox[0][1] - bbox[0][0]);
    for (y = 0; y < n; y++)
    {
      coo[1] = bbox[1][0] + (double) y / (n - 1) * (bbox[1][1] - bbox[1][0]);
      for (z = 0; z < n; z++)
      {
	coo[2] = bbox[2][0] + (double) z / (n - 1) * (bbox[2][1] - bbox[2][0]);

	(*pGSet).SeedCoo
	  = ut_realloc_2d_addline ((*pGSet).SeedCoo, ++nb + 1, 3);

	ut_array_1d_memcpy ((*pGSet).SeedCoo[nb], 3, coo);
      }
    }
  }

  (*pGSet).N = nb;

  for (i = 1; i <= (*pGSet).N; i++)
    for (j = 0; j < 3; j++)
      (*pGSet).SeedCoo[i][j]
	= ut_num_bound ((*pGSet).SeedCoo[i][j],
			bbox[j][0] + 1e-8, bbox[j][1] - 1e-8);

  ut_free_1d (coo);

  return;
}
