~ubuntu-branches/ubuntu/intrepid/gmsh/intrepid

« back to all changes in this revision

Viewing changes to Mesh/2D_InitMesh.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Emmet Hikory
  • Date: 2007-05-07 10:01:37 UTC
  • mfrom: (1.2.4 upstream)
  • Revision ID: james.westby@ubuntu.com-20070507100137-6j0rzz1ucbn0m2jt
Tags: 2.0.7-1ubuntu1
* Merged with Debian unstable.  Remaining Ubuntu changes:
  - Add .desktop file
  - Add icon
* Added XSBC-Original-Maintainer
* Removed Application Category from gmsh.desktop
* Link against GLU (fixes FTBFS)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
// $Id: 2D_InitMesh.cpp,v 1.22 2006/01/06 00:34:25 geuzaine Exp $
2
 
//
3
 
// Copyright (C) 1997-2006 C. Geuzaine, J.-F. Remacle
4
 
//
5
 
// This program is free software; you can redistribute it and/or modify
6
 
// it under the terms of the GNU General Public License as published by
7
 
// the Free Software Foundation; either version 2 of the License, or
8
 
// (at your option) any later version.
9
 
//
10
 
// This program is distributed in the hope that it will be useful,
11
 
// but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 
// GNU General Public License for more details.
14
 
//
15
 
// You should have received a copy of the GNU General Public License
16
 
// along with this program; if not, write to the Free Software
17
 
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
18
 
// USA.
19
 
// 
20
 
// Please report all bugs and problems to <gmsh@geuz.org>.
21
 
 
22
 
/*
23
 
 
24
 
   Generation du maillage initial 2D
25
 
 
26
 
   Dans l'algorithme de maillage, on doit creer un maillage initial a l'aide
27
 
   de contours orientes aire a doite. Deux types de problemes peuvent se presenter :
28
 
 
29
 
       1) probleme courant : un triangle se trouve a l'exterieur du contour, il faut
30
 
       que sa variable de localisation soit declaree externe.  
31
 
 
32
 
       2) probleme rare : une arete du contour n'a pas ete creee
33
 
 
34
 
       On procede comme suit :
35
 
       trouve le triangle, on procede de la facon suivante :
36
 
          - on trie les aretes de tous les triangles ;
37
 
          - Pour chaque contour on prend chaque arete orientee ;
38
 
          - Si cette arete n'existe pas (bsearch return false) alors on cherche
39
 
          les 2 triangles reliant cette arete et on les modifie
40
 
          - Si cette arete possede 2 triangles adjacents, on declare externe 
41
 
          le triangle dont le troisieme noeud se trouve a gauche de l'arete.
42
 
 
43
 
          illustration
44
 
          ------------
45
 
 
46
 
          probleme 1) + = point du contour
47
 
          
48
 
 
49
 
                                        3
50
 
                        - -  + --------+     +
51
 
                   + - -     1 \      /                +
52
 
                                \    /                       +
53
 
                                 \  /                                   +
54
 
             +                     +
55
 
                                   2       3 a gauche de 1-2 -> tr externe
56
 
 
57
 
 
58
 
           probleme 2) arete inexistante 1-2
59
 
           
60
 
                       +,*,@ contours
61
 
           
62
 
                     +1                      +            
63
 
                    / \                     /|\
64
 
                   /   \                   / | \
65
 
                  /     \                 /  |  \
66
 
                 /       \               /   |   \
67
 
                *         @   --->      *----+----@ 
68
 
                 \       /               \   |   /
69
 
                  \     /                 \  |  /
70
 
                   \   /                   \ | /
71
 
                    \ /                     \|/
72
 
                     +2                      +
73
 
 
74
 
*/
75
 
 
76
 
#include "Gmsh.h"
77
 
#include "Numeric.h"
78
 
#include "Mesh.h"
79
 
#include "2D_Mesh.h"
80
 
 
81
 
extern PointRecord *gPointArray;
82
 
 
83
 
static Tree_T *ETree = NULL, *EDToSwap = NULL;
84
 
static int pointA, pointB, Counter, Stagnant, StopNow;
85
 
static int *permut;
86
 
 
87
 
typedef struct
88
 
{
89
 
  int from;
90
 
  int to;
91
 
  int NbOccur;
92
 
  Delaunay *Liste[2];
93
 
}
94
 
ED;
95
 
 
96
 
 
97
 
void makepermut(int numpoints)
98
 
{
99
 
  int i, ip;
100
 
  permut = (int *)Malloc(numpoints * sizeof(int));      //Memory leak! this is never freed...
101
 
  for(i = 0; i < numpoints; i++) {
102
 
    ip = gPointArray[i].permu;
103
 
    permut[ip] = i;
104
 
  }
105
 
}
106
 
 
107
 
int crossED(ED * e)
108
 
{
109
 
  double Xma, Xmb, Yma, Ymb, det, t, q;
110
 
  double XMa, XMb, YMa, YMb;
111
 
  double xa1, xa2, ya1, ya2;
112
 
  double xb1, xb2, yb1, yb2;
113
 
 
114
 
  xa1 = gPointArray[pointA].where.h;
115
 
  xa2 = gPointArray[pointB].where.h;
116
 
  ya1 = gPointArray[pointA].where.v;
117
 
  ya2 = gPointArray[pointB].where.v;
118
 
 
119
 
  xb1 = gPointArray[e->from].where.h;
120
 
  xb2 = gPointArray[e->to].where.h;
121
 
  yb1 = gPointArray[e->from].where.v;
122
 
  yb2 = gPointArray[e->to].where.v;
123
 
 
124
 
  Xma = DMIN(xa1, xa2);
125
 
  Xmb = DMIN(xb1, xb2);
126
 
 
127
 
  XMa = DMAX(xa1, xa2);
128
 
  XMb = DMAX(xb1, xb2);
129
 
 
130
 
  if(XMa < Xmb || XMb < Xma)
131
 
    return (0);
132
 
 
133
 
  Yma = DMIN(ya1, ya2);
134
 
  Ymb = DMIN(yb1, yb2);
135
 
 
136
 
  YMa = DMAX(ya1, ya2);
137
 
  YMb = DMAX(yb1, yb2);
138
 
 
139
 
  if(YMa < Ymb || YMb < Yma)
140
 
    return (0);
141
 
 
142
 
  det = (xa2 - xa1) * (yb1 - yb2) - (xb1 - xb2) * (ya2 - ya1);
143
 
 
144
 
  if(det == 0.0) {
145
 
    return (0);
146
 
  }
147
 
 
148
 
  t = ((xb1 - xa1) * (yb1 - yb2) - (xb1 - xb2) * (yb1 - ya1)) / det;
149
 
  q = ((xa2 - xa1) * (yb1 - ya1) - (ya2 - ya1) * (xb1 - xa1)) / det;
150
 
 
151
 
  if(t > 1. || t < 0.)
152
 
    return (0);
153
 
  if(q > 1. || q < 0.)
154
 
    return (0);
155
 
 
156
 
  //printf("t=%g  q=%g  det=%g\n", t, q, det);
157
 
 
158
 
  return (1);
159
 
}
160
 
 
161
 
int compareED2(const void *a, const void *b)
162
 
{
163
 
  ED *q, *w;
164
 
  q = (ED *) a;
165
 
  w = (ED *) b;
166
 
  if(q->NbOccur > w->NbOccur)
167
 
    return (-1);
168
 
  if(q->NbOccur < w->NbOccur)
169
 
    return (1);
170
 
  if(q->from > w->from)
171
 
    return (1);
172
 
  if(q->from < w->from)
173
 
    return (-1);
174
 
  if(q->to > w->to)
175
 
    return (1);
176
 
  if(q->to < w->to)
177
 
    return (-1);
178
 
  return (0);
179
 
}
180
 
 
181
 
int compareED(const void *a, const void *b)
182
 
{
183
 
  ED *q, *w;
184
 
  q = (ED *) a;
185
 
  w = (ED *) b;
186
 
  if(q->from > w->from)
187
 
    return (1);
188
 
  if(q->from < w->from)
189
 
    return (-1);
190
 
  if(q->to > w->to)
191
 
    return (1);
192
 
  if(q->to < w->to)
193
 
    return (-1);
194
 
  return (0);
195
 
}
196
 
 
197
 
void DoWeSwapED(void *data, void *dummy)
198
 
{
199
 
  ED *e;
200
 
 
201
 
  e = (ED *) data;
202
 
 
203
 
  if(e->from == pointA || e->from == pointB ||
204
 
     e->to == pointA || e->to == pointB) {
205
 
    return;
206
 
  }
207
 
  else if(Tree_PQuery(EDToSwap, e)) {
208
 
  }
209
 
  else if(crossED(e)) {
210
 
    Tree_Add(EDToSwap, e);
211
 
  }
212
 
}
213
 
 
214
 
void Print(void *data, void *dummy)
215
 
{
216
 
  ED *e;
217
 
 
218
 
  e = (ED *) data;
219
 
  Msg(INFO, "%d %d", e->from, e->to);
220
 
}
221
 
 
222
 
void SwapED(void *data, void *dummy)
223
 
{
224
 
  ED *e, E;
225
 
  int from = 0, to = 0;
226
 
 
227
 
  e = (ED *) data;
228
 
 
229
 
  if(Stagnant && Counter <= StopNow)
230
 
    return;
231
 
  else if(Stagnant)
232
 
    Counter++;
233
 
 
234
 
  if(!e->Liste[0] || !e->Liste[1]) {
235
 
    Msg(GERROR, "Initial mesh is wrong. Try the new isotropic algorithm.");
236
 
    return;
237
 
  }
238
 
 
239
 
  if(e->from != e->Liste[0]->t.a && e->from != e->Liste[0]->t.b &&
240
 
     e->from != e->Liste[0]->t.c)
241
 
    return;
242
 
  if(e->from != e->Liste[1]->t.a && e->from != e->Liste[1]->t.b &&
243
 
     e->from != e->Liste[1]->t.c)
244
 
    return;
245
 
  if(e->to != e->Liste[0]->t.a && e->to != e->Liste[0]->t.b &&
246
 
     e->to != e->Liste[0]->t.c)
247
 
    return;
248
 
  if(e->to != e->Liste[1]->t.a && e->to != e->Liste[1]->t.b &&
249
 
     e->to != e->Liste[1]->t.c)
250
 
    return;
251
 
 
252
 
 
253
 
  if(e->from != e->Liste[0]->t.a && e->to != e->Liste[0]->t.a)
254
 
    from = e->Liste[0]->t.a;
255
 
  else if(e->from != e->Liste[0]->t.b && e->to != e->Liste[0]->t.b)
256
 
    from = e->Liste[0]->t.b;
257
 
  else if(e->from != e->Liste[0]->t.c && e->to != e->Liste[0]->t.c)
258
 
    from = e->Liste[0]->t.c;
259
 
 
260
 
  if(e->from != e->Liste[1]->t.a && e->to != e->Liste[1]->t.a)
261
 
    to = e->Liste[1]->t.a;
262
 
  else if(e->from != e->Liste[1]->t.b && e->to != e->Liste[1]->t.b)
263
 
    to = e->Liste[1]->t.b;
264
 
  else if(e->from != e->Liste[1]->t.c && e->to != e->Liste[1]->t.c)
265
 
    to = e->Liste[1]->t.c;
266
 
 
267
 
  pointA = e->from;
268
 
  pointB = e->to;
269
 
  E.from = from;
270
 
  E.to = to;
271
 
  if(!crossED(&E))
272
 
    return;
273
 
 
274
 
  e->Liste[0]->t.a = from;
275
 
  e->Liste[0]->t.b = to;
276
 
  e->Liste[0]->t.c = e->from;
277
 
 
278
 
  e->Liste[1]->t.a = from;
279
 
  e->Liste[1]->t.b = to;
280
 
  e->Liste[1]->t.c = e->to;
281
 
 
282
 
  e->from = IMAX(from, to);
283
 
  e->to = IMIN(from, to);
284
 
}
285
 
 
286
 
void SuppressInETree(void *data, void *dummy)
287
 
{
288
 
  if(!Tree_Suppress(ETree, data))
289
 
    Msg(WARNING, "Cannot suppress in ETree");
290
 
}
291
 
 
292
 
void AddInETree(void *data, void *dummy)
293
 
{
294
 
  Tree_Add(ETree, data);
295
 
}
296
 
 
297
 
int verifie_cas_scabreux(int pa, int pb, ContourRecord ** ListContours,
298
 
                         int Nc)
299
 
{
300
 
  ED Edge;
301
 
  int i, k, a, b;
302
 
  ContourRecord *contour;
303
 
 
304
 
 
305
 
  Edge.from = IMAX(pa, pb);
306
 
  Edge.to = IMIN(pa, pb);
307
 
  for(k = 0; k < Nc; k++) {
308
 
    contour = ListContours[k];
309
 
    for(i = -1; i < (contour->numpoints - 1); i++) {
310
 
      if(i == -1) {
311
 
        a = permut[contour->oriented_points[0].permu];
312
 
        b = permut[contour->oriented_points[contour->numpoints - 1].permu];
313
 
      }
314
 
      else {
315
 
        a = permut[contour->oriented_points[i].permu];
316
 
        b = permut[contour->oriented_points[i + 1].permu];
317
 
      }
318
 
 
319
 
      pointA = IMAX(a, b);
320
 
      pointB = IMIN(a, b);
321
 
      if(a != pa && b != pa && a != pb && b != pb)
322
 
        if(crossED(&Edge))
323
 
          return (1);
324
 
    }
325
 
  }
326
 
  return (0);
327
 
}
328
 
 
329
 
void verify_edges(List_T * ListDelaunay, ContourRecord ** ListContour,
330
 
                  int NumContours)
331
 
{
332
 
 
333
 
  ED *pEdge;
334
 
  ED Edge;
335
 
  int ok, max, i, k, c, a, b;
336
 
  ContourRecord *contour;
337
 
  Delaunay *del_P;
338
 
 
339
 
  max = 100;
340
 
 
341
 
  c = 0;
342
 
  do {
343
 
    c++;
344
 
    if(c > max)
345
 
      break;
346
 
    ETree = Tree_Create(sizeof(Edge), compareED);
347
 
    for(i = 0; i < List_Nbr(ListDelaunay); i++) {
348
 
 
349
 
      del_P = *(Delaunay **) List_Pointer(ListDelaunay, i);
350
 
 
351
 
      Edge.from = IMAX(del_P->t.a, del_P->t.b);
352
 
      Edge.to = IMIN(del_P->t.a, del_P->t.b);
353
 
      Edge.NbOccur = 1;
354
 
 
355
 
      if((pEdge = (ED *) Tree_PQuery(ETree, &Edge))) {
356
 
        pEdge->Liste[1] = del_P;
357
 
      }
358
 
      else {
359
 
        Edge.Liste[0] = del_P;
360
 
        Edge.Liste[1] = NULL;
361
 
        Tree_Add(ETree, &Edge);
362
 
      }
363
 
 
364
 
      Edge.from = IMAX(del_P->t.a, del_P->t.c);
365
 
      Edge.to = IMIN(del_P->t.a, del_P->t.c);
366
 
 
367
 
      if((pEdge = (ED *) Tree_PQuery(ETree, &Edge))) {
368
 
        pEdge->Liste[1] = del_P;
369
 
      }
370
 
      else {
371
 
        Edge.Liste[0] = del_P;
372
 
        Edge.Liste[1] = NULL;
373
 
        Tree_Add(ETree, &Edge);
374
 
      }
375
 
 
376
 
      Edge.from = IMAX(del_P->t.c, del_P->t.b);
377
 
      Edge.to = IMIN(del_P->t.c, del_P->t.b);
378
 
 
379
 
      if((pEdge = (ED *) Tree_PQuery(ETree, &Edge))) {
380
 
        pEdge->Liste[1] = del_P;
381
 
      }
382
 
      else {
383
 
        Edge.Liste[0] = del_P;
384
 
        Edge.Liste[1] = NULL;
385
 
        Tree_Add(ETree, &Edge);
386
 
      }
387
 
    }
388
 
 
389
 
    ok = 0;
390
 
    for(k = 0; k < NumContours; k++) {
391
 
      contour = ListContour[k];
392
 
      for(i = -1; i < contour->numpoints - 1; i++) {
393
 
 
394
 
        if(i == -1) {
395
 
          a = permut[contour->oriented_points[0].permu];
396
 
          b = permut[contour->oriented_points[contour->numpoints - 1].permu];
397
 
        }
398
 
        else {
399
 
          a = permut[contour->oriented_points[i].permu];
400
 
          b = permut[contour->oriented_points[i + 1].permu];
401
 
        }
402
 
 
403
 
        Edge.from = IMAX(a, b);
404
 
        Edge.to = IMIN(a, b);
405
 
 
406
 
        if(!Tree_Search(ETree, &Edge))
407
 
          ok++;;
408
 
      }
409
 
    }
410
 
 
411
 
    if(!ok) {
412
 
      return;
413
 
    }
414
 
 
415
 
    Msg(INFO, "Swapping (%d missing edges)", ok);
416
 
 
417
 
    //EDToSwap = NULL;
418
 
    if(EDToSwap)
419
 
      Tree_Delete(EDToSwap);
420
 
    EDToSwap = Tree_Create(sizeof(ED), compareED2);
421
 
    for(k = 0; k < NumContours; k++) {
422
 
      contour = ListContour[k];
423
 
      for(i = -1; i < contour->numpoints - 1; i++) {
424
 
 
425
 
        if(i == -1) {
426
 
          a = permut[contour->oriented_points[0].permu];
427
 
          b = permut[contour->oriented_points[contour->numpoints - 1].permu];
428
 
        }
429
 
        else {
430
 
          a = permut[contour->oriented_points[i].permu];
431
 
          b = permut[contour->oriented_points[i + 1].permu];
432
 
        }
433
 
 
434
 
        pointA = IMAX(a, b);
435
 
        pointB = IMIN(a, b);
436
 
 
437
 
        Tree_Action(ETree, DoWeSwapED);
438
 
 
439
 
      }
440
 
    }
441
 
    Msg(INFO, "Elimination (%d swaps)", Tree_Nbr(EDToSwap));
442
 
 
443
 
    Tree_Action(EDToSwap, SuppressInETree);
444
 
    Tree_Action(EDToSwap, SwapED);
445
 
    Tree_Action(EDToSwap, AddInETree);
446
 
  } while(Tree_Nbr(EDToSwap));
447
 
 
448
 
  Tree_Delete(EDToSwap);
449
 
  Tree_Delete(ETree);
450
 
 
451
 
}
452
 
 
453
 
 
454
 
 
455
 
int comparepermu(const void *i, const void *j)
456
 
{
457
 
  return (gPointArray[*(PointNumero *) i].permu -
458
 
          gPointArray[*(PointNumero *) j].permu);
459
 
}
460
 
 
461
 
void verify_inside(Delaunay * ListDelaunay, int NumDelaunay)
462
 
{
463
 
 
464
 
  PointNumero pt[3], compare, a, b;
465
 
  int i, inside, cont[3];
466
 
 
467
 
  for(i = 0; i < NumDelaunay; i++) {
468
 
 
469
 
    pt[0] = ListDelaunay[i].t.a;
470
 
    pt[1] = ListDelaunay[i].t.b;
471
 
    pt[2] = ListDelaunay[i].t.c;
472
 
    qsort(pt, 3, sizeof(PointNumero), comparepermu);
473
 
 
474
 
    cont[0] = gPointArray[pt[0]].numcontour;
475
 
    cont[1] = gPointArray[pt[1]].numcontour;
476
 
    cont[2] = gPointArray[pt[2]].numcontour;
477
 
 
478
 
 
479
 
    if((cont[1] != cont[2]) || (cont[0] != cont[1]) || (cont[0] != cont[2]))
480
 
      inside = 1;
481
 
    else
482
 
      inside = 0;
483
 
 
484
 
 
485
 
    a = pt[0];
486
 
    b = pt[1];
487
 
    compare = pt[2];
488
 
 
489
 
    if((Is_left_of(a, b, compare) && (inside == 0))) {
490
 
      ListDelaunay[i].t.position = EXTERN;
491
 
    }
492
 
 
493
 
  }
494
 
  return;
495
 
 
496
 
}