/*****************************************************************************/ /* */ /* 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 libraries */ /* */ #include #include #include /* */ /* get my header files */ /* */ #include "fpkernel.h" #include "martin.h" #include "defs.h" #include "list.h" #include "header.h" #include "basic.h" #include "numerics.h" /* */ /* prototypes of functions provided in this file */ /* */ void AdjustOrientation(global_struct *all, int i1, int i2); double PolygonArea(global_struct *all, list_ind ind); void DetermineOrientation(global_struct *all, list_ind ind); void FreeOrientation(global_struct *all); /* */ /* determine the outer polygon and the orientation of the polygons; the */ /* default orientation is CCW for the outer-most polygon, and CW for the */ /* inner polygons. the polygonal loops are referenced by loops[i1,..,i2-1]. */ /* */ void AdjustOrientation(global_struct *all, int i1, int i2) { listdef *list = &all->c_list; double area; int i, outer; list_ind ind; assert(i1 < i2); if (list->num_loops > all->max_num_poly_area) { all->poly_area = CORE_ReallocateArray(list->memptr, all->poly_area, all->max_num_poly_area, list->num_loops, double, "orientation:poly_area"); all->max_num_poly_area = list->num_loops; } /* */ /* for each contour, compute its signed area, i.e., its orientation. the */ /* contour with largest area is assumed to be the outer-most contour. */ /* */ #ifdef PARTITION_FIST #pragma omp parallel for #endif for (i = i1; i < i2; ++i) { ind = list->loops[i]; all->poly_area[i] = PolygonArea(all, ind); } /* */ /* determine the outer-most contour */ /* */ area = Abs(all->poly_area[i1]); outer = i1; #ifdef PARTITION_FIST #pragma omp parallel for #endif for (i = i1 + 1; i < i2; ++i) { if (area < Abs(all->poly_area[i])) { area = Abs(all->poly_area[i]); outer = i; } } /* */ /* default: the outer contour is referenced by loops[i1] */ /* */ if (outer != i1) { Swap(list->loops[i1], list->loops[outer], ind); Swap(all->poly_area[i1], all->poly_area[outer], area); } /* */ /* adjust the orientation */ /* */ if (all->poly_area[i1] < C_0_0) { SwapLinks(list, list->loops[i1]); // MODIF : nel nostro caso è l'orientamento del loop esterno a determinare l'orientamento dei triangoli, quindi // salvo il suo orientamento come viene fatto nel caso di un singolo loop in DetermineOrientation all->ccw_loop = false ; } #ifdef PARTITION_FIST #pragma omp parallel for #endif for (i = i1 + 1; i < i2; ++i) { if (all->poly_area[i] > C_0_0) SwapLinks(list, list->loops[i]); } return; } void FreeOrientation(global_struct *all) { all->max_num_poly_area = 0; CORE_FreeMemory((debug_memdef*)(&all->c_mem), &all->poly_area, "orientation:poly_area"); return; } /* */ /* this function computes twice the signed area of a simple closed polygon */ /* */ double PolygonArea(global_struct *all, list_ind ind) { listdef *list = &all->c_list; datadef *data = &all->c_data; tmp_data_def tmp_data; int hook = 0; list_ind ind1, ind2; int i1, i2; double area = C_0_0, area1 = C_0_0; ind1 = ind; i1 = GetIndex(list, ind1); ind2 = GetNextNode(list, ind1); i2 = GetIndex(list, ind2); StableDet2D(data, tmp_data, hook, i1, i2, area); ind1 = ind2; i1 = i2; while (ind1 != ind) { ind2 = GetNextNode(list, ind1); i2 = GetIndex(list, ind2); StableDet2D(data, tmp_data, hook, i1, i2, area1); area += area1; ind1 = ind2; i1 = i2; } return area; } /* */ /* determine the orientation of the polygon; the default orientation is CCW */ /* */ void DetermineOrientation(global_struct *all, list_ind ind) { double area; /* */ /* compute the polygon's signed area, i.e., its orientation. */ /* */ area = PolygonArea(all, ind); /* */ /* adjust the orientation (i.e., make it CCW) */ /* */ if (area < C_0_0) { SwapLinks(&all->c_list, ind); all->ccw_loop = false; } return; }