Forked from
gmsh / gmsh
21629 commits behind the upstream repository.
-
Christophe Geuzaine authoredChristophe Geuzaine authored
2D_Links.cpp 6.58 KiB
/* $Id: 2D_Links.cpp,v 1.3 2000-11-23 23:20:35 geuzaine Exp $ */
#include "Gmsh.h"
#include "Const.h"
#include "Mesh.h"
#include "2D_Mesh.h"
extern PointRecord *gPointArray;
extern int LocalNewPoint;
extern DocRecord *FGMESH;
extern PointNumero First(PointNumero x);
/* compte les points sur le polygone convexe */
int CountPointsOnHull(int n, PointRecord *pPointArray){
PointNumero p,p2,temp;
int i;
if (pPointArray[0].adjacent == NULL) return 0;
i = 1;
p = 0;
p2 = First(0);
while ((p2 != 0) && (i < n)) {
i++;
temp = p2;
p2 = Successor(p2,p);
p = temp;
}
return ((i <= n) ? i : -1);
}
PointNumero *ConvertDlistToArray(DListPeek *dlist,int *n){
DListPeek p,temp;
int i,max = 0;
PointNumero *ptr;
p = *dlist;
do{
max++;
p = Pred(p);
} while (p != *dlist);
ptr = (PointNumero *) Malloc((int) ((max+1) * sizeof(PointNumero)));
if (ptr == NULL) return NULL;
p = *dlist;
for (i=0;i<max;i++){
ptr[i] = p->point_num;
temp = p;
p = Pred(p);
Free(temp);
}
ptr[max]=ptr[0];
*dlist = NULL;
*n = max;
return ptr;
}
/* Convertir les listes d'adjacence en triangles */
int Conversion(DocPeek doc ){
/* on suppose que n >= 3 gPointArray est suppose OK. */
Striangle *striangle;
int n,i,j;
int count = 0,count2 = 0;
PointNumero aa,bb,cc;
PointRecord *ptemp;
ptemp = gPointArray;
gPointArray = doc->points;
n = doc->numPoints;
striangle = (Striangle *) Malloc((int) (n * sizeof(Striangle)));
count2 = (int) CountPointsOnHull(n,doc->points);
/* nombre de triangles que l'on doit obtenir */
count2 = 2 * (n - 1) - count2;
doc->delaunay = (Delaunay *) Malloc(2*count2 * sizeof(Delaunay));
for (i=0;i<n;i++){
/* on cree une liste de points connectes au point i (t) + nombre de points (t_length) */
striangle[i].t = ConvertDlistToArray(&gPointArray[i].adjacent,&striangle[i].t_length);
striangle[i].info = NULL;
striangle[i].info_length = 0;
}
/* on balaye les noeuds de gauche a droite -> on cree les triangles */
count = 0;
for (i=0;i<n;i++){
for (j=0;j<striangle[i].t_length;j++){
if ( ( striangle[i].t[j] > i) && ( striangle[i].t[j+1] > i) &&
(Is_right_of(i,striangle[i].t[j],striangle[i].t[j+1])) ) {
aa = i;
bb = striangle[i].t[j];
cc = striangle[i].t[j+1];
filldel(&doc->delaunay[count],aa,bb,cc,gPointArray,NULL);
count++;
}
}
}
for (i=0;i<n;i++) Free(striangle[i].t);
Free(striangle);
doc->numTriangles = count2;
gPointArray = ptemp;
return(1);
}
int compareEdge(const void *e1, const void *e2){
PointNumero tmp;
if ((tmp = ((edge *)e1)->from - ((edge *)e2)->from) != 0) return(tmp);
return(((edge *)e1)->to - ((edge *)e2)->to);
}
/* pour la liste de delaunays ListDelaunay, CreateLinks cree les liens entre
triangles c.a.d determine les voisins de chaque triangle */
int CreateLinks(List_T * ListDelaunay , int NumDelaunay,
ContourRecord **ListContours , int Nc){
int i;
edge *ListEdges;
MPoint pt;
Delaunay *del_Pi, *del_Pj;
ListEdges = (edge *) Malloc((3* NumDelaunay + 2)* sizeof(edge));
ListEdges[3* NumDelaunay + 1].num=0;
for (i=0;i< NumDelaunay;i++){
del_Pi = *(Delaunay**)List_Pointer(ListDelaunay, i);
/* arete a b */
if (del_Pi->t.a > del_Pi->t.b ){
ListEdges[3*i].from = del_Pi->t.a;
ListEdges[3*i].to = del_Pi->t.b;
ListEdges[3*i].num = i;
}
else {
ListEdges[3*i].from = del_Pi->t.b;
ListEdges[3*i].to = del_Pi->t.a;
ListEdges[3*i].num = i;
}
/* arete b c */
if (del_Pi->t.b > del_Pi->t.c ){
ListEdges[3*i+1].from = del_Pi->t.b;
ListEdges[3*i+1].to = del_Pi->t.c;
ListEdges[3*i+1].num = i;
}
else {
ListEdges[3*i+1].from = del_Pi->t.c;
ListEdges[3*i+1].to = del_Pi->t.b;
ListEdges[3*i+1].num = i;
}
/* arete c a */
if (del_Pi->t.c > del_Pi->t.a ){
ListEdges[3*i+2].from = del_Pi->t.c;
ListEdges[3*i+2].to = del_Pi->t.a;
ListEdges[3*i+2].num = i;
}
else {
ListEdges[3*i+2].from = del_Pi->t.a;
ListEdges[3*i+2].to = del_Pi->t.c;
ListEdges[3*i+2].num = i;
}
}
qsort(ListEdges,3*NumDelaunay,sizeof(edge),compareEdge);
i=0;
do {
if ( (ListEdges[i].from == ListEdges[i+1].from) &&
(ListEdges[i].to == ListEdges[i+1].to)){ /* create link */
del_Pi = *(Delaunay**)List_Pointer(ListDelaunay, ListEdges[i].num);
del_Pj = *(Delaunay**)List_Pointer(ListDelaunay, ListEdges[i+1].num);
if ( ( del_Pi->t.position != EXTERN ) &&
( del_Pj->t.position != EXTERN ) &&
( (del_Pj->t.info == TOLINK ) ||
(del_Pi->t.info == TOLINK ) ) ) {
if (del_Pi->v.voisin1 == NULL)
del_Pi->v.voisin1 = del_Pj;
else if (del_Pi->v.voisin2 == NULL)
del_Pi->v.voisin2 = del_Pj;
else if (del_Pi->v.voisin3 == NULL)
del_Pi->v.voisin3 = del_Pj;
else
Msg(ERROR, "Bad Link in CreateLinks");
if (del_Pj->v.voisin1 == NULL)
del_Pj->v.voisin1 = del_Pi;
else if (del_Pj->v.voisin2 == NULL)
del_Pj->v.voisin2 = del_Pi;
else if (del_Pj->v.voisin3 == NULL)
del_Pj->v.voisin3 = del_Pi;
else
Msg(ERROR, "Bad Link in CreateLinks");
}
i+=2;
}
else
i++;
} while ( i < 3*NumDelaunay );
Free(ListEdges);
for(i=0 ; i<NumDelaunay ;i++){
del_Pi = *(Delaunay**)List_Pointer(ListDelaunay, i);
if(del_Pi->t.position != EXTERN){
pt.h = del_Pi->t.xc;
pt.v = del_Pi->t.yc;
if(!PtInTriangle(pt, del_Pi->t.a, del_Pi->t.b,
del_Pi->t.c)){
if(!Find_Triangle(pt,FGMESH,A_TOUT_PRIX)){
if(LocalNewPoint == VORONOI_INSERT) {
del_Pi->t.position = ACCEPTED;
}
del_Pi->t.quality_value /= 1000.;
}
}
}
}
if((LocalNewPoint == VORONOI_INSERT)){
for(i=0 ; i<NumDelaunay ;i++){
del_Pi = *(Delaunay**)List_Pointer(ListDelaunay, i);
if( ((del_Pi->t.position == NONACCEPTED ) || (del_Pi->t.position == INTERN )) &&
(del_Pi->t.info == TOLINK )){
if ((del_Pi->v.voisin1 == NULL) ||
(del_Pi->v.voisin2 == NULL) ||
(del_Pi->v.voisin3 == NULL)){
del_Pi->t.position = ACTIF;
}
else if ((del_Pi->v.voisin1->t.position == ACCEPTED) &&
(del_Pi->v.voisin2->t.position == ACCEPTED) &&
(del_Pi->v.voisin3->t.position == ACCEPTED)){
del_Pi->t.position = ACCEPTED;
}
else if ((del_Pi->v.voisin1->t.position == ACCEPTED) ||
(del_Pi->v.voisin2->t.position == ACCEPTED) ||
(del_Pi->v.voisin3->t.position == ACCEPTED)){
del_Pi->t.position = ACTIF;
}
else {
del_Pi->t.position = WAITING;
}
}
}
}
return(1);
}