home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
AmigActive 6
/
AACD06.ISO
/
AACD
/
System
/
Mesa-3.1
/
src-glu
/
tess_heap.c
< prev
next >
Wrap
C/C++ Source or Header
|
1999-12-06
|
7KB
|
314 lines
/* $Id: tess_heap.c,v 1.9.2.4 1999/12/05 02:04:31 gareth Exp $ */
/*
* Mesa 3-D graphics library
* Version: 3.1
*
* Copyright (C) 1999 Brian Paul All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
/*****************************************************************************
*
* GLU 1.3 Polygon Tessellation - Implementation of priority queue
*
* Gareth Hughes <garethh@bell-labs.com>, April 1999
*
*****************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "gluP.h"
#include "tess.h"
#include "tess_macros.h"
#include "tess_heap.h"
/*****************************************************************************
* Internal definitions:
*****************************************************************************/
#define PARENT(i) (((i+1)>>1)-1)
#define LEFT(i) (((i+1)<<1)-1)
#define RIGHT(i) ((i+1)<<1)
/*****************************************************************************
*
* HEAP FUNCTIONS
*
*****************************************************************************/
/*****************************************************************************
* heapify
*
* Heapify the heap :)
*****************************************************************************/
static void heapify( heap_t *heap, GLint n )
{
GLint left = LEFT( n );
GLint right = RIGHT( n );
GLint largest;
if ( ( left < heap->size ) &&
( heap->elements[left]->value > heap->elements[n]->value ) )
{
largest = left;
}
else
{
largest = n;
}
if ( ( right < heap->size ) &&
( heap->elements[right]->value >
heap->elements[largest]->value ) )
{
largest = right;
}
if ( largest != n )
{
heap_elt_t *element;
element = heap->elements[n];
heap->elements[n] = heap->elements[largest];
heap->elements[n]->index = n;
heap->elements[largest] = element;
heap->elements[largest]->index = largest;
heapify( heap, largest );
}
}
/*****************************************************************************
* heap_init
*
* Allocate and initialize a new heap.
*****************************************************************************/
heap_t *heap_init()
{
heap_t *heap;
GLint i;
heap = (heap_t *) malloc( sizeof(heap_t) );
if ( heap == NULL ) {
return NULL;
}
heap->elements = (heap_elt_t **)
malloc( HEAP_ALLOC * sizeof(heap_elt_t *) );
if ( heap->elements == NULL ) {
free( heap );
return NULL;
}
heap->length = HEAP_ALLOC;
heap->size = 0;
heap->flags = 0;
for ( i = 0 ; i < heap->length ; i++ ) {
heap->elements[i] = NULL;
}
return heap;
}
/*****************************************************************************
* heap_build
*
* Build a heap from an unordered array.
*****************************************************************************/
void heap_build( heap_t *heap )
{
GLint i;
heap->size = heap->length;
for ( i = PARENT( heap->length ) ; i >= 0 ; i-- ) {
heapify( heap, i );
}
}
/*****************************************************************************
* heap_extract_max
*
* Remove and return the maximum element in the heap.
*****************************************************************************/
heap_elt_t *heap_extract_max( heap_t *heap )
{
heap_elt_t *max;
if ( heap->size < 1 ) {
return NULL;
}
max = heap->elements[0];
heap->elements[0] = heap->elements[heap->size-1];
heap->elements[0]->index = 0;
heap->size--;
heapify( heap, 0 );
return max;
}
/*****************************************************************************
* heap_insert
*
* Insert a new element into the heap.
*****************************************************************************/
GLboolean heap_insert( heap_t *heap, heap_elt_t *element )
{
GLint i;
heap->size++;
if ( heap->size > heap->length )
{
/* Allocate some more space for the heap. */
if ( ( heap->elements =
realloc( heap->elements, ( heap->length + HEAP_ALLOC )
* sizeof(heap_elt_t *) ) ) == NULL )
{
return GL_FALSE;
}
heap->length += HEAP_ALLOC;
}
i = heap->size - 1;
while ( ( i > 0 ) &&
( heap->elements[PARENT( i )]->value < element->value ) )
{
heap->elements[i] = heap->elements[PARENT( i )];
heap->elements[i]->index = i;
i = PARENT( i );
}
heap->elements[i] = element;
heap->elements[i]->index = i;
return GL_TRUE;
}
/*****************************************************************************
* heap_delete
*
* Delete element n from the heap.
*****************************************************************************/
heap_elt_t *heap_delete( heap_t *heap, GLint n )
{
heap_elt_t *element;
if ( ( heap->size < 1 ) || ( n >= heap->size ) ) {
return NULL;
}
element = heap->elements[n];
heap->elements[n] = heap->elements[heap->size-1];
heap->elements[n]->index = n;
heap->size--;
heapify( heap, n );
return element;
}
/*****************************************************************************
* heap_delete_ptr
*
* Delete the element with the given data pointer from the heap.
*****************************************************************************/
heap_elt_t *heap_delete_ptr( heap_t *heap, void *ptr )
{
heap_elt_t *element = NULL;
GLint i;
if ( ( heap->size < 1 ) || ( ptr == NULL ) ) {
return NULL;
}
for ( i = 0 ; i < heap->size ; i++ )
{
if ( heap->elements[i]->ptr == ptr ) {
element = heap->elements[i];
break;
}
}
if ( element != NULL )
{
heap->elements[i] = heap->elements[heap->size-1];
heap->elements[i]->index = i;
heap->size--;
heapify( heap, i );
}
return element;
}
/*****************************************************************************
* heap_cleanup
*
* Deallocate all memory associated with the heap.
*****************************************************************************/
void heap_cleanup( heap_t **heap )
{
GLint i;
if ( *heap )
{
if ( (*heap)->elements )
{
for ( i = 0; i < (*heap)->size; i++ )
{
if ( (*heap)->elements[i] ) {
free( (*heap)->elements[i] );
}
}
free( (*heap)->elements );
}
free( *heap );
*heap = NULL;
}
}