/**************************************************************************
  Copyright (C) 1992 Guy Moreillon
  All rights reserved.

  This software may be freely copied, modified, and redistributed
  provided that this copyright notice is preserved on all copies.

  You may not distribute this software, in whole or in part, as part of
  any commercial product without the express consent of the authors.

  There is no warranty or other guarantee of fitness of this software
  for any purpose.  It is provided solely "as is".
**************************************************************************/
/**************************************************************************

				RAD
		       (Interactive Radiosity)
		    	    Version 1.0
			       1992		    	    
		    	    
		  
		    	  Guy Moreillon
		    	  
**************************************************************************/

/**************************************************************************
  Fichier	: free.c
  Description	: Fonctions utilisees pour la liberation de la memoire
		  utilisee par une scene
**************************************************************************/

#include <stdio.h>
#include "types.h"
#include "macros.h"

void free_poly(TRIANGLEP tri)
/**************************************************************************
  But	: Desalloue la memoire employee par un polygone et ses fils
  Entree: tri	: le polygone
  Sortie: neant
**************************************************************************/
{
  if (tri != NULL)
    {
      if (tri->type == poly_type)
	{
	  free(tri->tri.poly.samples);
	  free_poly(tri->tri.poly.sons);
	}
      else	/* subdiv */
	{
	  int i;

	  for(i = 0; i < 4; i++)
	    free_poly(tri->tri.subdiv.elements[i].sons);
	}
    }
}

void free_p_list(POLY_LP list)
/**************************************************************************
  But	: Desalloue la memoire employee par une liste de ref. a des poly.
  Entree: list	: la tete de liste
  Sortie: neant
**************************************************************************/
{
  if (list != NULL)
    {
      free_p_list(list->next);
      free(list);
    }
}

void free_grid(GRID *grid)
/**************************************************************************
  But	: Desalloue la memoire employee par la grille de voxel et les
	  listes qu'elle utilise
  Entree: grid	: la grille
  Sortie: neant
**************************************************************************/
{
  if (grid != NULL)
    {
      int i;

      for(i = 0; i < grid->nb_vox[0]*grid->nb_vox[1]*grid->nb_vox[2]; i++)
        free_p_list(grid->list[i]);
      free(grid->list);
      free(grid);
    }
}

void free_obj(OBJECT_OP object)
/**************************************************************************
  But	: Desalloue la memoire employee par l'objet, ses freres et ses fils
  Entree: object    : l'objet
  Sortie: neant
**************************************************************************/
{
  int	    i;
  OBJECT_OP obj, next;

  if (object == NULL)
    return;

  switch(object->type) {
    case assembly_type:
      for(obj  = object->object.assembly.sons, next = obj ? obj->next : NULL;
	  obj != NULL;
	  obj  = next, next = obj ? obj->next : NULL)
	free_obj(obj);
      break;
    case composite_type:
      for(obj  = object->object.composite.sons, next = obj ? obj->next : NULL;
	  obj != NULL;
	  obj  = next, next = obj ? obj->next : NULL)
	free_obj(obj);
      free_grid(object->object.composite.grid);
      break;
    case pure_type:
      for(i = 0; i < object->object.pure.nb_polys; i++)
	free_poly(&(object->object.pure.polys[i]));
      free(object->object.pure.polys);      
      free_grid(object->object.pure.grid);
      break;
  }

  free(object);
}

void free_scene(SCENE_OP scene)
/**************************************************************************
  But	: Desalloue la memoire employee par la scene
  Entree: scene	: la scene
  Sortie: neant
**************************************************************************/
{
  int i;

  free_obj(scene->scene);
  
  if (scene->state.nb_tex > 1)
    for(i = 1; i < scene->state.nb_tex; i++)
      free(scene->textures[i].image);
}

