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

« back to all changes in this revision

Viewing changes to Mesh/2D_Mesh_Triangle.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_Mesh_Triangle.cpp,v 1.15 2006/01/29 22:53:41 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
 
#include "Gmsh.h"
23
 
#include "Mesh.h"
24
 
#include "Numeric.h"
25
 
#include "Context.h"
26
 
 
27
 
#if !defined(HAVE_TRIANGLE)
28
 
 
29
 
int Mesh_Triangle(Surface * s)
30
 
{
31
 
  Msg(GERROR, "Triangle is not compiled in this version of Gmsh");
32
 
  return 1;
33
 
}
34
 
 
35
 
#else
36
 
 
37
 
#define ANSI_DECLARATORS
38
 
#define REAL double
39
 
#define VOID void
40
 
 
41
 
extern "C"
42
 
{
43
 
#include "triangle.h"
44
 
}
45
 
 
46
 
extern Context_T CTX;
47
 
extern Mesh *THEM;
48
 
 
49
 
void AddInMesh(Surface * sur, int nbbound, Vertex ** vertexbound,
50
 
               struct triangulateio *out)
51
 
{
52
 
  int i;
53
 
  Vertex **vtable;
54
 
  Simplex *s;
55
 
 
56
 
  //Msg(INFO, "Add in database...");
57
 
 
58
 
  vtable = (Vertex **) Malloc(out->numberofpoints * sizeof(Vertex *));
59
 
 
60
 
  for(i = 0; i < nbbound; i++)
61
 
    vtable[i] = vertexbound[i];
62
 
  Free(vertexbound);
63
 
 
64
 
  for(i = nbbound; i < out->numberofpoints; i++) {
65
 
    vtable[i] = Create_Vertex(++(THEM->MaxPointNum),
66
 
                              out->pointlist[i * 2],
67
 
                              out->pointlist[i * 2 + 1], 0.0,
68
 
                              out->pointattributelist[i], 0.0);
69
 
    Tree_Add(sur->Vertices, &vtable[i]);
70
 
  }
71
 
 
72
 
  Free(out->pointlist);
73
 
  Free(out->pointattributelist);
74
 
 
75
 
  for(i = 0; i < out->numberoftriangles; i++) {
76
 
    s = Create_Simplex(vtable[out->trianglelist[i * out->numberofcorners + 0]],
77
 
                       vtable[out->trianglelist[i * out->numberofcorners + 1]],
78
 
                       vtable[out->trianglelist[i * out->numberofcorners + 2]],
79
 
                       NULL);
80
 
    s->iEnt = sur->Num;
81
 
    Tree_Add(sur->Simplexes, &s);
82
 
  }
83
 
 
84
 
  Free(vtable);
85
 
  Free(out->trianglelist);
86
 
  Free(out->triangleattributelist);
87
 
 
88
 
  //Msg(INFO, "...done");
89
 
}
90
 
 
91
 
// This is horrible...
92
 
 
93
 
void FindPointInHole(List_T * verts, REAL * x, REAL * y)
94
 
{
95
 
  Vertex *v1, *v2;
96
 
  double a[3], b[3], c[3];
97
 
  List_Read(verts, 0, &v1);
98
 
  List_Read(verts, 1, &v2);
99
 
  a[0] = v2->Pos.X - v1->Pos.X;
100
 
  a[1] = v2->Pos.Y - v1->Pos.Y;
101
 
  a[2] = 0.;
102
 
  b[0] = 0.;
103
 
  b[1] = 0.;
104
 
  b[2] = 1.;
105
 
  prodve(b, a, c);
106
 
  norme(c);
107
 
  *x = 0.5 * (v1->Pos.X + v2->Pos.X) + 1.e-12 * CTX.lc * c[0];
108
 
  *y = 0.5 * (v1->Pos.Y + v2->Pos.Y) + 1.e-12 * CTX.lc * c[1];
109
 
}
110
 
 
111
 
int Mesh_Triangle(Surface * s)
112
 
{
113
 
  char opts[128];
114
 
  int i, j, k, l, NbPts = 0, first;
115
 
  double val;
116
 
  List_T *list;
117
 
  Vertex *v, **vtable;
118
 
  struct triangulateio in, mid, out;
119
 
 
120
 
  for(i = 0; i < List_Nbr(s->Contours); i++) {
121
 
    List_Read(s->Contours, i, &list);
122
 
    NbPts += List_Nbr(list);
123
 
  }
124
 
 
125
 
  in.numberofpoints = NbPts;
126
 
  in.pointlist = (REAL *) Malloc(in.numberofpoints * 2 * sizeof(REAL));
127
 
  vtable = (Vertex **) Malloc(in.numberofpoints * sizeof(Vertex *));
128
 
  in.numberofpointattributes = 1;
129
 
  in.pointattributelist = (REAL *) Malloc(in.numberofpoints *
130
 
                                          in.numberofpointattributes *
131
 
                                          sizeof(REAL));
132
 
  in.pointmarkerlist = NULL;
133
 
  in.numberofsegments = NbPts;
134
 
  in.segmentlist = (int *)Malloc(in.numberofsegments * 2 * sizeof(int));
135
 
  in.segmentmarkerlist = (int *)Malloc(in.numberofsegments * sizeof(int));
136
 
  in.numberofregions = 0;
137
 
  in.regionlist = NULL;
138
 
 
139
 
  k = 0;
140
 
  l = 0;
141
 
  double lc_max = -1.0;
142
 
  for(i = 0; i < List_Nbr(s->Contours); i++) {
143
 
    List_Read(s->Contours, i, &list);
144
 
    first = l;
145
 
    for(j = 0; j < List_Nbr(list); j++) {
146
 
      List_Read(list, j, &v);
147
 
      in.pointlist[k] = v->Pos.X;
148
 
      in.pointlist[k + 1] = v->Pos.Y;
149
 
      in.pointattributelist[l] = v->lc;
150
 
      if(v->lc > lc_max) lc_max = v->lc;
151
 
      vtable[l] = v;
152
 
      in.segmentlist[k] = l;
153
 
      in.segmentlist[k + 1] = (j == List_Nbr(list) - 1) ? (first) : (l + 1);
154
 
      in.segmentmarkerlist[l] = i;
155
 
      k += 2;
156
 
      l++;
157
 
    }
158
 
  }
159
 
 
160
 
  if(List_Nbr(s->Contours) > 1) {
161
 
    in.numberofholes = List_Nbr(s->Contours) - 1;
162
 
    in.holelist = (REAL *) Malloc(in.numberofholes * 2 * sizeof(REAL));
163
 
    for(i = 1; i < List_Nbr(s->Contours); i++) {
164
 
      List_Read(s->Contours, i, &list);
165
 
      FindPointInHole(list, &in.holelist[(i - 1) * 2],
166
 
                      &in.holelist[(i - 1) * 2 + 1]);
167
 
    }
168
 
  }
169
 
  else {
170
 
    in.numberofholes = 0;
171
 
    in.holelist = NULL;
172
 
  }
173
 
 
174
 
  mid.pointlist = NULL;
175
 
  mid.pointattributelist = NULL;
176
 
  mid.pointmarkerlist = NULL;
177
 
  mid.trianglelist = NULL;
178
 
  mid.triangleattributelist = NULL;
179
 
  mid.neighborlist = NULL;
180
 
  mid.segmentlist = NULL;
181
 
  mid.segmentmarkerlist = NULL;
182
 
  mid.edgelist = NULL;
183
 
  mid.edgemarkerlist = NULL;
184
 
 
185
 
  // triangulate the points with minimum angle > 20 deg, with no
186
 
  // boundary breaking, and with an area constraint related to the
187
 
  // maximum char. length allowed (this last constraint is to avoid an
188
 
  // extremely coarse initial grid, on which the interpolation of the
189
 
  // final char. lengths would be awful).
190
 
 
191
 
  double a = lc_max*lc_max / 1.2; // FIXME: bof
192
 
  if(a > 1.e-6)
193
 
    sprintf(opts, "pqzYa%f", a);
194
 
  else
195
 
    strcpy(opts, "pqzY");
196
 
  if(CTX.verbosity < 4)
197
 
    strcat(opts, "Q");
198
 
  triangulate(opts, &in, &mid, NULL);
199
 
 
200
 
  Free(in.pointlist);
201
 
  Free(in.pointattributelist);
202
 
  Free(in.pointmarkerlist);
203
 
  Free(in.regionlist);
204
 
  Free(in.segmentlist);
205
 
  Free(in.segmentmarkerlist);
206
 
  Free(in.holelist);
207
 
 
208
 
  if(CTX.mesh.initial_only == 2) {
209
 
    AddInMesh(s, NbPts, vtable, &mid);
210
 
    return 0;
211
 
  }
212
 
 
213
 
  mid.trianglearealist =
214
 
    (REAL *) Malloc(mid.numberoftriangles * sizeof(REAL));
215
 
  for(i = 0; i < mid.numberoftriangles; i++) {
216
 
    if(THEM->BackgroundMeshType == ONFILE) {
217
 
      double xx = 0.0, yy = 0.0;
218
 
      for(j = 0; j < mid.numberofcorners; j++) {
219
 
        k = mid.trianglelist[i * mid.numberofcorners + j];
220
 
        xx += mid.pointlist[2 * k];
221
 
        yy += mid.pointlist[2 * k + 1];
222
 
      }
223
 
      xx /= mid.numberofcorners;
224
 
      yy /= mid.numberofcorners;
225
 
      Vertex *v, *dum;
226
 
      v = Create_Vertex(-1, xx, yy, 0.0, 0.0, 0.0);
227
 
      Calcule_Z_Plan(&v, &dum);
228
 
      Projette_Inverse(&v, &dum);
229
 
      val = BGMXYZ(v->Pos.X, v->Pos.Y, v->Pos.Z);
230
 
      val = val * val / 1.2;  // FIXME: bof
231
 
      Free_Vertex(&v, 0);
232
 
    }
233
 
    else {
234
 
      val = 0;
235
 
      for(j = 0; j < mid.numberofcorners; j++) {
236
 
        k = mid.trianglelist[i * mid.numberofcorners + j];
237
 
        val += mid.pointattributelist[k];
238
 
      }
239
 
      val /= mid.numberofcorners;
240
 
      val = val * val / 1.5;  // FIXME: bof
241
 
    }
242
 
    mid.trianglearealist[i] = val;
243
 
  }
244
 
 
245
 
  out.pointlist = NULL;
246
 
  out.pointattributelist = NULL;
247
 
  out.trianglelist = NULL;
248
 
  out.triangleattributelist = NULL;
249
 
 
250
 
  // refine the triangulation according to the triangle area
251
 
  // constraints
252
 
 
253
 
  //strcpy(opts, "praqzBPY");
254
 
  strcpy(opts, CTX.mesh.triangle_options);
255
 
  if(CTX.verbosity < 4)
256
 
    strcat(opts, "Q");
257
 
  triangulate(opts, &mid, &out, NULL);
258
 
 
259
 
  // free all allocated arrays + those allocated by Triangle
260
 
 
261
 
  Free(mid.pointlist);
262
 
  Free(mid.pointattributelist);
263
 
  Free(mid.pointmarkerlist);
264
 
  Free(mid.trianglelist);
265
 
  Free(mid.triangleattributelist);
266
 
  Free(mid.trianglearealist);
267
 
  Free(mid.segmentlist);
268
 
  Free(mid.segmentmarkerlist);
269
 
 
270
 
  AddInMesh(s, NbPts, vtable, &out);
271
 
 
272
 
  return 0;
273
 
 
274
 
}
275
 
 
276
 
#endif // !HAVE_TRIANGLE