Files
SaraP cbec90699f FIST 6.8 :
- creato il progetto in Visual Studio per compilare come libreria statica
- modifiche al codice originale per integrarlo nelle nostre librerie.
2025-03-04 16:19:35 +01:00

652 lines
16 KiB
C++

/*****************************************************************************/
/* */
/* F I S T : Fast, Industrial-Strength Triangulation */
/* */
/*****************************************************************************/
/* */
/* (C) Martin Held */
/* (C) Universitaet Salzburg, Salzburg, Austria */
/* */
/* This code is not in the public domain. All rights reserved! Please make */
/* sure to read the full copyright statement contained in api_functions.cpp. */
/* */
/*****************************************************************************/
/* get standard i/o library */
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
/* get my header file */
#include "fpkernel.h"
#include "martin.h"
#include "defs.h"
#include "list.h"
#include "header.h"
/* */
/* function prototypes of functions provided in this file */
/* */
void RemoveZeroEdges(listdef* list, list_ind *ind);
void FreeList(listdef* list);
list_ind MakeHook(listdef* list);
void DeleteHook(listdef* list, int curr_loop);
int MakeLoopHeader(listdef* list);
void DecrementLoops(listdef* list);
list_ind MakeNode(listdef* list, int index);
void InsertAfter(listdef* list, list_ind ind1, list_ind ind2);
void DeleteLinks(listdef* list, list_ind ind);
list_ind FetchNextData(listdef* list, list_ind ind1, int *index);
list_ind FetchPrevData(listdef* list, list_ind ind1, int *index);
int CountListElements(listdef* list, list_ind ind1);
void UpdateIndex(listdef* list, list_ind ind, int index);
void SwapLinks(listdef* list, list_ind ind1);
boolean InPolyList(listdef* list, list_ind ind);
boolean InLoopList(listdef* list, int loop);
//void InitAngle(listdef* list, list_ind ind, int convex);
void ResetPolyList(listdef* list, list_ind ind);
list_ind GetNode(listdef* list);
int GetOriginal(listdef* list, list_ind ind);
void SetOriginal(listdef* list, list_ind ind, int original);
#ifdef NORMALS
void SetTexNormData(listdef* list, list_ind ind, int index1, int index2);
int GetNormalIndex(listdef* list, list_ind ind);
int GetTextureIndex(listdef* list, list_ind ind);
#endif
void SplitSplice(listdef* list, list_ind ind1, list_ind ind2, list_ind ind3, list_ind ind4);
void RotateLinks(listdef* list, list_ind ind1, list_ind ind2);
void ResetListData(listdef* list);
void StoreChain(listdef* list, list_ind ind);
list_ind GetNextChain(listdef* list, boolean *done);
void InitStorageList(listdef* list, int number);
void InitStorageLoops(listdef* list, int number);
void InitFace(listdef* list, int number);
void DecrementFaces(listdef* list);
int GetNumList(listdef* list);
boolean GetBridgeNode(listdef* list, list_ind ind);
void SetBridgeNodePair(listdef* list, list_ind ind1, list_ind ind2);
#ifdef PARTITION_FIST
boolean isCorner(global_struct *all, int current_partition, list_ind ind);
#endif
#define MEGA_BLOCK_SIZE 65536
#define BLOCK_SIZE 16384
#define HALF_BLOCK_SIZE 512
#define MARK_LIST_BOUND 40
void InitListDefaults(listdef* list)
{
list->list = (list_node*)NULL;
list->num_list = 0;
list->max_num_list = 0;
list->loops = (list_ind*)NULL;
list->num_loops = 0;
list->max_num_loops = 0;
list->faces = (int*)NULL;
list->num_faces = 0;
list->max_num_faces = 0;
list->first_node = 0;
list->chains = (list_ind*)NULL;
list->num_chains = 0;
list->max_num_chains = 0;
}
int GetNumList(listdef* list)
{
return list->num_list;
}
void ResetListData(listdef* list)
{
list->num_list = 0;
list->num_chains = 0;
list->first_node = 0;
return;
}
void FreeList(listdef* list)
{
FreeMemory(list->memptr, (void**) &list->list, "list:list");
FreeMemory(list->memptr, (void**) &list->loops, "list:loops");
FreeMemory(list->memptr, (void**) &list->faces, "list:faces");
FreeMemory(list->memptr, (void**) &list->chains, "list:chains");
list->max_num_list = 0;
list->num_list = 0;
list->max_num_loops = 0;
list->num_loops = 0;
list->max_num_chains = 0;
list->num_chains = 0;
list->max_num_faces = 0;
list->num_faces = 0;
return;
}
#ifdef PARTITION_FIST
boolean isCorner(global_struct *all, int current_partition, list_ind ind) {
if (ind == all->corner_nodes[current_partition])
return true;
if (ind == all->corner_nodes[(current_partition+1) % all->number_of_heaps])
return true;
return false;
}
#endif
/* */
/* allocates storage for a dummy list node; pointers are set to itself; */
/* returns pointer to node */
/* */
list_ind MakeHook(listdef* list)
{
list_ind ind;
list_node *addr;
if (list->num_list >= list->max_num_list) {
list->max_num_list += MEGA_BLOCK_SIZE;
list->list = (list_node*) ReallocateArray(list->memptr, list->list, list->max_num_list,
sizeof(list_node), "list:list");
}
ind = list->num_list;
addr = &(list->list[list->num_list]);
addr->prev = ind;
addr->next = ind;
addr->index = NIL;
addr->bridge = false;
#ifdef PARTITION_FIST
addr->delete_reflex = false;
#endif
++list->num_list;
return ind;
}
void DeleteHook(listdef* list, int curr_loop)
{
list_ind ind1, ind2;
assert(InLoopList(list,curr_loop));
ind1 = list->loops[curr_loop];
assert(InPolyList(list,ind1));
ind2 = list->list[ind1].next;
assert(InPolyList(list,ind2));
DeleteLinks(list,ind1);
list->loops[curr_loop] = ind2;
return;
}
int MakeLoopHeader(listdef* list)
{
int i;
list_ind ind;
ind = MakeHook(list);
if (list->num_loops >= list->max_num_loops) {
list->max_num_loops += BLOCK_SIZE;
list->loops = (list_ind*) ReallocateArray(list->memptr, list->loops, list->max_num_loops,
sizeof(list_ind), "list:loops");
}
list->loops[list->num_loops] = ind;
i = list->num_loops;
++list->num_loops;
return i;
}
void DecrementLoops(listdef* list)
{
assert(list->num_loops > 0);
--list->num_loops;
return;
}
void InitStorageList(listdef* list, int number)
{
if (number >= list->max_num_list) {
list->max_num_list = number;
list->list = (list_node*) ReallocateArray(list->memptr, list->list, list->max_num_list,
sizeof(list_node), "list:list");
}
return;
}
void InitStorageLoops(listdef* list, int number)
{
if (number >= list->max_num_loops) {
list->max_num_loops = number;
list->loops = (list_ind*) ReallocateArray(list->memptr, list->loops, list->max_num_loops,
sizeof(list_ind), "list:loops");
}
return;
}
/* */
/* allocates storage for a new list node, and stores the index of the point */
/* at this node; pointers are set to NIL; returns pointer to node */
/* */
list_ind MakeNode(listdef* list, int index)
{
list_ind ind;
list_node *addr;
if (list->num_list >= list->max_num_list) {
list->max_num_list += BLOCK_SIZE;
list->list = (list_node*) ReallocateArray(list->memptr, list->list, list->max_num_list,
sizeof(list_node), "list:list");
}
ind = list->num_list;
addr = &(list->list[list->num_list]);
addr->index = index;
addr->prev = NIL;
addr->next = NIL;
addr->bridge = false;
#ifdef PARTITION_FIST
addr->delete_reflex = false;
#endif
++list->num_list;
return ind;
}
/* */
/* inserts node ind2 after node ind1 */
/* */
void InsertAfter(listdef* list, list_ind ind1, list_ind ind2)
{
list_ind ind3;
assert(InPolyList(list,ind1));
assert(InPolyList(list,ind2));
list->list[ind2].next = list->list[ind1].next;
list->list[ind2].prev = ind1;
list->list[ind1].next = ind2;
ind3 = list->list[ind2].next;
assert(InPolyList(list,ind3));
list->list[ind3].prev = ind2;
return;
}
/* */
/* deletes node ind from list (with destroying its data fields) */
/* */
void DeleteLinks(listdef* list, list_ind ind)
{
list_node *addr;
assert(InPolyList(list,ind));
addr = &(list->list[ind]);
assert(InPolyList(list,addr->prev));
assert(InPolyList(list,addr->next));
if (list->first_node == ind) list->first_node = addr->next;
list->list[addr->next].prev = addr->prev;
list->list[addr->prev].next = addr->next;
addr->prev = addr->next = ind;
return;
}
/* */
/* returns pointer to the successor ind2 of ind1, and its data */
/* */
list_ind FetchNextData(listdef* list, list_ind ind1, int *index)
{
list_ind ind2;
assert(InPolyList(list,ind1));
ind2 = list->list[ind1].next;
assert(InPolyList(list,ind2));
*index = list->list[ind2].index;
return ind2;
}
/* */
/* returns pointer to the successor ind2 of ind1, and its data */
/* */
list_ind FetchPrevData(listdef* list, list_ind ind1, int *index)
{
list_ind ind2;
assert(InPolyList(list,ind1));
ind2 = list->list[ind1].prev;
assert(InPolyList(list,ind2));
*index = list->list[ind2].index;
return ind2;
}
/* */
/* this function counts the number of elements of a circular list */
/* */
int CountListElements(listdef* list, list_ind ind1)
{
int num_ele = 1;
list_ind ind2;
assert(InPolyList(list,ind1));
ind2 = list->list[ind1].next;
while (ind2 != ind1) {
assert(InPolyList(list,ind2));
++num_ele;
ind2 = list->list[ind2].next;
}
return num_ele;
}
void UpdateIndex(listdef* list, list_ind ind, int index)
{
assert(InPolyList(list,ind));
list->list[ind].index = index;
return;
}
/* */
/* swap the list pointers in order to change the orientation */
/* */
void SwapLinks(listdef* list, list_ind ind1)
{
list_ind ind2, ind3;
assert(InPolyList(list,ind1));
ind2 = list->list[ind1].next;
assert(InPolyList(list,ind2));
list->list[ind1].next = list->list[ind1].prev;
list->list[ind1].prev = ind2;
ind3 = ind2;
while (ind2 != ind1) {
assert(InPolyList(list,ind2));
ind3 = list->list[ind2].next;
list->list[ind2].next = list->list[ind2].prev;
list->list[ind2].prev = ind3;
ind2 = ind3;
}
return;
}
boolean InPolyList(listdef* list, list_ind ind)
{
return ((ind >= 0) && (ind < list->num_list) && (list->num_list <= list->max_num_list));
}
boolean InLoopList(listdef* list, int loop)
{
return ((loop >= 0) && (loop < list->num_loops) &&
(list->num_loops <= list->max_num_loops));
}
void ResetPolyList(listdef* list, list_ind ind)
{
assert(InPolyList(list,ind));
list->first_node = ind;
return;
}
list_ind GetNode(listdef* list)
{
assert(InPolyList(list,list->first_node));
return list->first_node;
}
int GetOriginal(listdef* list, list_ind ind)
{
assert(InPolyList(list,ind));
return list->list[ind].original;
}
void SetOriginal(listdef* list, list_ind ind, int original)
{
assert(InPolyList(list,ind));
list->list[ind].original = original;
return;
}
boolean GetBridgeNode(listdef* list, list_ind ind)
{
assert(InPolyList(list,ind));
return list->list[ind].bridge;
}
void SetBridgeNodePair(listdef* list, list_ind ind1, list_ind ind2)
{
assert(InPolyList(list,ind1));
assert(InPolyList(list,ind2));
list->list[ind1].bridge = true;
list->list[ind2].bridge = true;
return;
}
#ifdef NORMALS
void SetTexNormData(listdef* list, list_ind ind, int t_index, int n_index)
{
assert(InPolyList(list,ind));
list->list[ind].t_index = t_index;
list->list[ind].n_index = n_index;
return;
}
int GetTextureIndex(listdef* list, list_ind ind)
{
assert(InPolyList(list,ind));
return list->list[ind].t_index;
}
int GetNormalIndex(listdef* list, list_ind ind)
{
assert(InPolyList(list,ind));
return list->list[ind].n_index;
}
#endif
void SplitSplice(listdef* list, list_ind ind1, list_ind ind2, list_ind ind3, list_ind ind4)
{
assert(InPolyList(list,ind1));
assert(InPolyList(list,ind2));
assert(InPolyList(list,ind3));
assert(InPolyList(list,ind4));
assert(list->list[ind1].next == ind2);
assert(list->list[ind2].prev == ind1);
assert(list->list[ind3].next == ind4);
assert(list->list[ind4].prev == ind3);
list->list[ind1].next = ind4;
list->list[ind4].prev = ind1;
list->list[ind2].prev = ind3;
list->list[ind3].next = ind2;
return;
}
void RotateLinks(listdef* list, list_ind ind1, list_ind ind2)
{
list_ind ind;
list_ind ind0, ind3;
assert(InPolyList(list,ind1));
assert(InPolyList(list,ind2));
ind0 = list->list[ind1].next;
ind3 = list->list[ind2].next;
assert(InPolyList(list,ind0));
assert(InPolyList(list,ind3));
Swap(list->list[ind1].next, list->list[ind2].next, ind);
list->list[ind0].prev = ind2;
list->list[ind3].prev = ind1;
return;
}
void StoreChain(listdef* list, list_ind ind)
{
if (list->num_chains >= list->max_num_chains) {
list->max_num_chains += HALF_BLOCK_SIZE;
list->chains = (list_ind*) ReallocateArray(list->memptr, list->chains, list->max_num_chains,
sizeof(list_ind), "list:chains");
}
list->chains[list->num_chains] = ind;
++list->num_chains;
return;
}
list_ind GetNextChain(listdef* list, boolean *done)
{
if (list->num_chains > 0) {
*done = true;
--list->num_chains;
return list->chains[list->num_chains];
}
else {
*done = false;
list->num_chains = 0;
return 0;
}
}
void InitFace(listdef* list, int number)
{
if (list->num_faces >= list->max_num_faces) {
list->max_num_faces += BLOCK_SIZE;
list->faces = (int*) ReallocateArray(list->memptr, list->faces, list->max_num_faces,
sizeof(int), "list:faces");
}
list->faces[list->num_faces] = number;
++list->num_faces;
return;
}
void DecrementFaces(listdef* list)
{
assert(list->num_faces > 0);
--list->num_faces;
return;
}
void RemoveZeroEdges(listdef* list, list_ind *ind)
{
list_ind ind1, ind2, ind3;
int i1, i2;
ind1 = *ind;
i1 = GetIndex(list,ind1);
ind2 = GetNextNode(list,ind1);
do {
i2 = GetIndex(list,ind2);
if (i1 == i2) {
ind3 = GetNextNode(list,ind2);
DeleteLinks(list,ind2);
ind2 = ind3;
}
else {
i1 = i2;
ind2 = GetNextNode(list,ind2);
}
} while (ind2 != ind1);
i2 = GetIndex(list,ind2);
if (i1 == i2) {
*ind = GetNextNode(list,ind2);
DeleteLinks(list,ind1);
}
return;
}