/**************************************************************************
  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".
**************************************************************************/
/**************************************************************************

			     PREPRAD
		     (Scene preparation program)
		    	    Version 1.0
			       1992		    	    
		    	    
		  
		    	  Guy Moreillon
		    	  
**************************************************************************/

/**************************************************************************
  Fichier	: object.c
  Description	: routines de creation d'objet
**************************************************************************/

#include <stdio.h>
#include <assert.h>

#include <types.h>
#include <macros.h>
#include <misc.h>
#include "preprad.h"
#include "object.h"

void cleanup(OBJECT_OP object)
/**************************************************************************
  But	: Nettoie un objet: enleve tous les polygones selectionnes du
	  tableau des polygones de l'objet
  Entree: object    : l'objet
  Sortie: neant
**************************************************************************/
{
  int i, j, cur, new, old = object->object.pure.nb_polys;

  for(cur = 0, new = 0;
      (cur < object->object.pure.nb_polys) &&
      (new < object->object.pure.nb_polys)
      ;)
    {
      for(;
	  (cur < object->object.pure.nb_polys) &&
	  !object->object.pure.polys[cur].tri.poly.samples;
	  cur++);
      if (cur >= object->object.pure.nb_polys)
	break;

      for(new = cur;
	  (new < object->object.pure.nb_polys) &&
	  object->object.pure.polys[new].tri.poly.samples;
	  new++);
      if (new >= object->object.pure.nb_polys)
	{
	  object->object.pure.nb_polys -= new - cur;
	  break;
	}

      for(i = new, j = cur; i < object->object.pure.nb_polys; i++, j++)
	object->object.pure.polys[j] = object->object.pure.polys[i];

      object->object.pure.nb_polys -= new - cur;
    }

  if (old != object->object.pure.nb_polys)
    object->object.pure.polys =
	(TRIANGLEP)realloc(object->object.pure.polys,
			   sizeof(TRIANGLE)*object->object.pure.nb_polys);
}

OBJECT_OP create_object(SCENE_OP    scene,
			int	    nb_pol,
			OBJECT_OP   *tab_dad,
			int	    nb_dad)
/**************************************************************************
  But	: Cree un objet Pure a partir de tous les polygones selectionnes
  Entree: scene	    : la scene
	  nb_pol    : le nombre de polygone dont il est forme
	  tab_dad   : le tableau des objets Pures contenant eventuelement
		      des polygones selectionnes.
	  nb_dad    : le nombre des objets Pures
  Sortie: neant
**************************************************************************/
{
  int	    i, j, k, cur = 0;
  OBJECT_OP new;
  VECTOR    bboxi, bboxa;

  V_init(bboxi,  HUGE,  HUGE,  HUGE);
  V_init(bboxa, -HUGE, -HUGE, -HUGE);

  if ((new = (OBJECT_OP)malloc(sizeof(OBJECT_O))) == NULL)
    return NULL;

  new->type = pure_type;
  new->dad  = scene->scene;
  new->next = scene->scene->object.assembly.sons;

  new->object.pure.nb_polys = nb_pol;
  if ((new->object.pure.polys =
       (TRIANGLEP)malloc(sizeof(TRIANGLE)*nb_pol)) == NULL)
    {
      free(new);
      return NULL;
    }

  new->object.pure.grid = NULL;
  new->object.pure.texmap.index = 0;

  for(i = 0; i < nb_dad; i++)
    for(j = 0; j < tab_dad[i]->object.pure.nb_polys; j++)
      if (tab_dad[i]->object.pure.polys[j].tri.poly.samples)
	{
	  new->object.pure.polys[cur] = tab_dad[i]->object.pure.polys[j];

	  for(k = 0; k < 3; k++)
	    {
	      V_min(bboxi, bboxi,
		    new->object.pure.polys[cur].tri.poly.vertex[k].point);
	      V_max(bboxa, bboxa,
		    new->object.pure.polys[cur].tri.poly.vertex[k].point);
	    }

	  cur++;
	}

  V_copy(new->bbox[0], bboxi);
  V_copy(new->bbox[1], bboxa);

  for(i = 0; i < nb_dad; i++)
    cleanup(tab_dad[i]);

  scene->scene->object.assembly.sons = new;

  return new;
}
