Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
ElmerCSC
GitHub Repository: ElmerCSC/elmerfem
Path: blob/devel/ElmerGUI/netgen/libsrc/interface/nglib.cpp
3206 views
1
/**************************************************************************/
2
/* File: nglib.cc */
3
/* Author: Joachim Schoeberl */
4
/* Date: 7. May. 2000 */
5
/**************************************************************************/
6
7
/*
8
9
Interface to the netgen meshing kernel
10
11
*/
12
13
14
#include <mystdlib.h>
15
#include <myadt.hpp>
16
17
#include <linalg.hpp>
18
#include <csg.hpp>
19
#include <stlgeom.hpp>
20
#include <geometry2d.hpp>
21
#include <meshing.hpp>
22
23
24
25
// #include <FlexLexer.h>
26
27
namespace netgen {
28
extern void MeshFromSpline2D (SplineGeometry2d & geometry,
29
Mesh *& mesh,
30
MeshingParameters & mp);
31
}
32
33
34
35
36
37
38
39
namespace nglib {
40
#include "nglib.h"
41
}
42
43
using namespace netgen;
44
45
// constants and types:
46
47
namespace nglib
48
{
49
// initialize, deconstruct Netgen library:
50
void Ng_Init ()
51
{
52
mycout = &cout;
53
myerr = &cerr;
54
testout = new ofstream ("test.out");
55
}
56
57
void Ng_Exit ()
58
{
59
;
60
}
61
62
63
Ng_Mesh * Ng_NewMesh ()
64
{
65
Mesh * mesh = new Mesh;
66
mesh->AddFaceDescriptor (FaceDescriptor (1, 1, 0, 1));
67
return (Ng_Mesh*)(void*)mesh;
68
}
69
70
void Ng_DeleteMesh (Ng_Mesh * mesh)
71
{
72
delete (Mesh*)mesh;
73
}
74
75
// return bc property for surface element i
76
int
77
EG_GetSurfaceElementBCProperty(Ng_Mesh * mesh, int i)
78
{
79
int j = ((Mesh*)mesh)->SurfaceElement(i).GetIndex();
80
int k = ((Mesh*)mesh)->GetFaceDescriptor(j).BCProperty();
81
return k;
82
}
83
84
// return surface and volume element in pi
85
Ng_Surface_Element_Type
86
EG_GetSurfaceElement (Ng_Mesh * mesh, int num, int * pi, int * ptrignum)
87
{
88
const Element2d & el = ((Mesh*)mesh)->SurfaceElement(num);
89
for (int i = 1; i <= el.GetNP(); i++) {
90
pi[i-1] = el.PNum(i);
91
ptrignum[i-1] = el.GeomInfoPi(i).trignum;
92
}
93
Ng_Surface_Element_Type et;
94
switch (el.GetNP())
95
{
96
case 3: et = NG_TRIG; break;
97
case 4: et = NG_QUAD; break;
98
case 6: et = NG_TRIG6; break;
99
}
100
return et;
101
}
102
103
// return segment bcnum
104
void
105
EG_GetSegmentBCProperty (Ng_Mesh *mesh, Ng_Geometry_2D * geom, int num, int * bcnum)
106
{
107
const Segment & seg = ((Mesh*)mesh)->LineSegment(num);
108
109
int edgenum = seg.edgenr;
110
111
SplineGeometry2d *geom2d = (SplineGeometry2d*)geom;
112
113
SplineSegment &spline = geom2d->GetSpline(num);
114
115
if(bcnum)
116
*bcnum = spline.bc;
117
}
118
119
// feeds points, surface elements and volume elements to the mesh
120
void Ng_AddPoint (Ng_Mesh * mesh, double * x)
121
{
122
Mesh * m = (Mesh*)mesh;
123
m->AddPoint (Point3d (x[0], x[1], x[2]));
124
}
125
126
void Ng_AddSurfaceElement (Ng_Mesh * mesh, Ng_Surface_Element_Type et,
127
int * pi)
128
{
129
Mesh * m = (Mesh*)mesh;
130
Element2d el (3);
131
el.SetIndex (1);
132
el.PNum(1) = pi[0];
133
el.PNum(2) = pi[1];
134
el.PNum(3) = pi[2];
135
m->AddSurfaceElement (el);
136
}
137
138
void Ng_AddVolumeElement (Ng_Mesh * mesh, Ng_Volume_Element_Type et,
139
int * pi)
140
{
141
Mesh * m = (Mesh*)mesh;
142
Element el (4);
143
el.SetIndex (1);
144
el.PNum(1) = pi[0];
145
el.PNum(2) = pi[1];
146
el.PNum(3) = pi[2];
147
el.PNum(4) = pi[3];
148
m->AddVolumeElement (el);
149
}
150
151
// ask for number of points, surface and volume elements
152
int Ng_GetNP (Ng_Mesh * mesh)
153
{
154
return ((Mesh*)mesh) -> GetNP();
155
}
156
157
int Ng_GetNSE (Ng_Mesh * mesh)
158
{
159
return ((Mesh*)mesh) -> GetNSE();
160
}
161
162
int Ng_GetNE (Ng_Mesh * mesh)
163
{
164
return ((Mesh*)mesh) -> GetNE();
165
}
166
167
168
// return point coordinates
169
void Ng_GetPoint (Ng_Mesh * mesh, int num, double * x)
170
{
171
const Point3d & p = ((Mesh*)mesh)->Point(num);
172
x[0] = p.X();
173
x[1] = p.Y();
174
x[2] = p.Z();
175
}
176
177
// return surface and volume element in pi
178
Ng_Surface_Element_Type
179
Ng_GetSurfaceElement (Ng_Mesh * mesh, int num, int * pi)
180
{
181
const Element2d & el = ((Mesh*)mesh)->SurfaceElement(num);
182
for (int i = 1; i <= el.GetNP(); i++)
183
pi[i-1] = el.PNum(i);
184
Ng_Surface_Element_Type et;
185
switch (el.GetNP())
186
{
187
case 3: et = NG_TRIG; break;
188
case 4: et = NG_QUAD; break;
189
case 6: et = NG_TRIG6; break;
190
}
191
return et;
192
}
193
194
Ng_Volume_Element_Type
195
Ng_GetVolumeElement (Ng_Mesh * mesh, int num, int * pi)
196
{
197
const Element & el = ((Mesh*)mesh)->VolumeElement(num);
198
for (int i = 1; i <= el.GetNP(); i++)
199
pi[i-1] = el.PNum(i);
200
Ng_Volume_Element_Type et;
201
switch (el.GetNP())
202
{
203
case 4: et = NG_TET; break;
204
case 5: et = NG_PYRAMID; break;
205
case 6: et = NG_PRISM; break;
206
case 10: et = NG_TET10; break;
207
}
208
return et;
209
}
210
211
void Ng_RestrictMeshSizeGlobal (Ng_Mesh * mesh, double h)
212
{
213
((Mesh*)mesh) -> SetGlobalH (h);
214
}
215
216
void Ng_RestrictMeshSizePoint (Ng_Mesh * mesh, double * p, double h)
217
{
218
((Mesh*)mesh) -> RestrictLocalH (Point3d (p[0], p[1], p[2]), h);
219
}
220
221
void Ng_RestrictMeshSizeBox (Ng_Mesh * mesh, double * pmin, double * pmax, double h)
222
{
223
for (double x = pmin[0]; x < pmax[0]; x += h)
224
for (double y = pmin[1]; y < pmax[1]; y += h)
225
for (double z = pmin[2]; z < pmax[2]; z += h)
226
((Mesh*)mesh) -> RestrictLocalH (Point3d (x, y, z), h);
227
}
228
229
230
// generates volume mesh from surface mesh
231
Ng_Result Ng_GenerateVolumeMesh (Ng_Mesh * mesh, Ng_Meshing_Parameters * mp)
232
{
233
Mesh * m = (Mesh*)mesh;
234
235
236
MeshingParameters mparam;
237
mparam.maxh = mp->maxh;
238
mparam.meshsizefilename = mp->meshsize_filename;
239
240
m->CalcLocalH();
241
242
MeshVolume (mparam, *m);
243
RemoveIllegalElements (*m);
244
OptimizeVolume (mparam, *m);
245
246
return NG_OK;
247
}
248
249
250
251
// 2D Meshing Functions:
252
253
254
255
void Ng_AddPoint_2D (Ng_Mesh * mesh, double * x)
256
{
257
Mesh * m = (Mesh*)mesh;
258
259
m->AddPoint (Point3d (x[0], x[1], 0));
260
}
261
262
void Ng_AddBoundarySeg_2D (Ng_Mesh * mesh, int pi1, int pi2)
263
{
264
Mesh * m = (Mesh*)mesh;
265
266
Segment seg;
267
seg.p1 = pi1;
268
seg.p2 = pi2;
269
m->AddSegment (seg);
270
}
271
272
273
int Ng_GetNP_2D (Ng_Mesh * mesh)
274
{
275
Mesh * m = (Mesh*)mesh;
276
return m->GetNP();
277
}
278
279
int Ng_GetNE_2D (Ng_Mesh * mesh)
280
{
281
Mesh * m = (Mesh*)mesh;
282
return m->GetNSE();
283
}
284
285
int Ng_GetNSeg_2D (Ng_Mesh * mesh)
286
{
287
Mesh * m = (Mesh*)mesh;
288
return m->GetNSeg();
289
}
290
291
void Ng_GetPoint_2D (Ng_Mesh * mesh, int num, double * x)
292
{
293
Mesh * m = (Mesh*)mesh;
294
295
Point<3> & p = m->Point(num);
296
x[0] = p(0);
297
x[1] = p(1);
298
}
299
300
void Ng_GetElement_2D (Ng_Mesh * mesh, int num, int * pi, int * matnum)
301
{
302
const Element2d & el = ((Mesh*)mesh)->SurfaceElement(num);
303
for (int i = 1; i <= 3; i++)
304
pi[i-1] = el.PNum(i);
305
if (matnum)
306
*matnum = el.GetIndex();
307
}
308
309
310
void Ng_GetSegment_2D (Ng_Mesh * mesh, int num, int * pi, int * matnum)
311
{
312
const Segment & seg = ((Mesh*)mesh)->LineSegment(num);
313
pi[0] = seg.p1;
314
pi[1] = seg.p2;
315
316
if (matnum)
317
*matnum = seg.edgenr;
318
}
319
320
321
322
323
Ng_Geometry_2D * Ng_LoadGeometry_2D (const char * filename)
324
{
325
SplineGeometry2d * geom = new SplineGeometry2d();
326
geom -> Load (filename);
327
return (Ng_Geometry_2D *)geom;
328
}
329
330
Ng_Result Ng_GenerateMesh_2D (Ng_Geometry_2D * geom,
331
Ng_Mesh ** mesh,
332
Ng_Meshing_Parameters * mp)
333
{
334
// use global variable mparam
335
// MeshingParameters mparam;
336
mparam.maxh = mp->maxh;
337
mparam.meshsizefilename = mp->meshsize_filename;
338
mparam.quad = mp->quad_dominated;
339
340
Mesh * m;
341
MeshFromSpline2D (*(SplineGeometry2d*)geom, m, mparam);
342
343
cout << m->GetNSE() << " elements, " << m->GetNP() << " points" << endl;
344
345
*mesh = (Ng_Mesh*)m;
346
return NG_OK;
347
}
348
349
void Ng_HP_Refinement (Ng_Geometry_2D * geom,
350
Ng_Mesh * mesh,
351
int levels)
352
{
353
Refinement2d ref(*(SplineGeometry2d*)geom);
354
HPRefinement (*(Mesh*)mesh, &ref, levels);
355
}
356
357
void Ng_HP_Refinement (Ng_Geometry_2D * geom,
358
Ng_Mesh * mesh,
359
int levels, double parameter)
360
{
361
Refinement2d ref(*(SplineGeometry2d*)geom);
362
HPRefinement (*(Mesh*)mesh, &ref, levels, parameter);
363
}
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
ARRAY<STLReadTriangle> readtrias; //only before initstlgeometry
380
ARRAY<Point<3> > readedges; //only before init stlgeometry
381
382
void Ng_SaveMesh(Ng_Mesh * mesh, const char* filename)
383
{
384
((Mesh*)mesh)->Save(filename);
385
}
386
387
Ng_Mesh * Ng_LoadMesh(const char* filename)
388
{
389
Mesh * mesh = new Mesh;
390
mesh->Load(filename);
391
return ( (Ng_Mesh*)mesh );
392
}
393
394
// loads geometry from STL file
395
Ng_STL_Geometry * Ng_STL_LoadGeometry (const char * filename, int binary)
396
{
397
int i;
398
STLGeometry geom;
399
STLGeometry* geo;
400
401
if (binary)
402
{
403
ifstream ist(filename, ios::binary);
404
geo = geom.LoadBinary(ist);
405
}
406
else
407
{
408
ifstream ist(filename);
409
geo = geom.Load(ist);
410
}
411
412
readtrias.SetSize(0);
413
readedges.SetSize(0);
414
415
Point3d p;
416
Vec3d normal;
417
double p1[3];
418
double p2[3];
419
double p3[3];
420
double n[3];
421
422
Ng_STL_Geometry * geo2 = Ng_STL_NewGeometry();
423
424
for (i = 1; i <= geo->GetNT(); i++)
425
{
426
const STLTriangle& t = geo->GetTriangle(i);
427
p = geo->GetPoint(t.PNum(1));
428
p1[0] = p.X(); p1[1] = p.Y(); p1[2] = p.Z();
429
p = geo->GetPoint(t.PNum(2));
430
p2[0] = p.X(); p2[1] = p.Y(); p2[2] = p.Z();
431
p = geo->GetPoint(t.PNum(3));
432
p3[0] = p.X(); p3[1] = p.Y(); p3[2] = p.Z();
433
normal = t.Normal();
434
n[0] = normal.X(); n[1] = normal.Y(); n[2] = normal.Z();
435
436
Ng_STL_AddTriangle(geo2, p1, p2, p3, n);
437
}
438
439
return geo2;
440
}
441
442
// generate new STL Geometry
443
Ng_STL_Geometry * Ng_STL_NewGeometry ()
444
{
445
return (Ng_STL_Geometry*)(void*)new STLGeometry;
446
}
447
448
// after adding triangles (and edges) initialize
449
Ng_Result Ng_STL_InitSTLGeometry (Ng_STL_Geometry * geom)
450
{
451
STLGeometry* geo = (STLGeometry*)geom;
452
geo->InitSTLGeometry(readtrias);
453
readtrias.SetSize(0);
454
455
if (readedges.Size() != 0)
456
{
457
int i;
458
/*
459
for (i = 1; i <= readedges.Size(); i+=2)
460
{
461
cout << "e(" << readedges.Get(i) << "," << readedges.Get(i+1) << ")" << endl;
462
}
463
*/
464
geo->AddEdges(readedges);
465
}
466
467
if (geo->GetStatus() == STLTopology::STL_GOOD || geo->GetStatus() == STLTopology::STL_WARNING) return NG_OK;
468
return NG_SURFACE_INPUT_ERROR;
469
}
470
471
// automatically generates edges:
472
Ng_Result Ng_STL_MakeEdges (Ng_STL_Geometry * geom,
473
Ng_Mesh* mesh,
474
Ng_Meshing_Parameters * mp)
475
{
476
STLGeometry* stlgeometry = (STLGeometry*)geom;
477
Mesh* me = (Mesh*)mesh;
478
479
MeshingParameters mparam;
480
481
mparam.maxh = mp->maxh;
482
mparam.meshsizefilename = mp->meshsize_filename;
483
484
me -> SetGlobalH (mparam.maxh);
485
me -> SetLocalH (stlgeometry->GetBoundingBox().PMin() - Vec3d(10, 10, 10),
486
stlgeometry->GetBoundingBox().PMax() + Vec3d(10, 10, 10),
487
0.3);
488
489
me -> LoadLocalMeshSize (mp->meshsize_filename);
490
/*
491
if (mp->meshsize_filename)
492
{
493
ifstream infile (mp->meshsize_filename);
494
if (!infile.good()) return NG_FILE_NOT_FOUND;
495
me -> LoadLocalMeshSize (infile);
496
}
497
*/
498
499
STLMeshing (*stlgeometry, *me);
500
501
stlgeometry->edgesfound = 1;
502
stlgeometry->surfacemeshed = 0;
503
stlgeometry->surfaceoptimized = 0;
504
stlgeometry->volumemeshed = 0;
505
506
return NG_OK;
507
}
508
509
510
// generates mesh, empty mesh be already created.
511
Ng_Result Ng_STL_GenerateSurfaceMesh (Ng_STL_Geometry * geom,
512
Ng_Mesh* mesh,
513
Ng_Meshing_Parameters * mp)
514
{
515
STLGeometry* stlgeometry = (STLGeometry*)geom;
516
Mesh* me = (Mesh*)mesh;
517
518
MeshingParameters mparam;
519
520
mparam.maxh = mp->maxh;
521
mparam.meshsizefilename = mp->meshsize_filename;
522
523
/*
524
me -> SetGlobalH (mparam.maxh);
525
me -> SetLocalH (stlgeometry->GetBoundingBox().PMin() - Vec3d(10, 10, 10),
526
stlgeometry->GetBoundingBox().PMax() + Vec3d(10, 10, 10),
527
0.3);
528
*/
529
/*
530
STLMeshing (*stlgeometry, *me);
531
532
stlgeometry->edgesfound = 1;
533
stlgeometry->surfacemeshed = 0;
534
stlgeometry->surfaceoptimized = 0;
535
stlgeometry->volumemeshed = 0;
536
*/
537
int retval = STLSurfaceMeshing (*stlgeometry, *me);
538
if (retval == MESHING3_OK)
539
{
540
(*mycout) << "Success !!!!" << endl;
541
stlgeometry->surfacemeshed = 1;
542
stlgeometry->surfaceoptimized = 0;
543
stlgeometry->volumemeshed = 0;
544
}
545
else if (retval == MESHING3_OUTERSTEPSEXCEEDED)
546
{
547
(*mycout) << "ERROR: Give up because of too many trials. Meshing aborted!" << endl;
548
}
549
else if (retval == MESHING3_TERMINATE)
550
{
551
(*mycout) << "Meshing Stopped!" << endl;
552
}
553
else
554
{
555
(*mycout) << "ERROR: Surface meshing not successful. Meshing aborted!" << endl;
556
}
557
558
559
STLSurfaceOptimization (*stlgeometry, *me, mparam);
560
561
return NG_OK;
562
}
563
564
565
// fills STL Geometry
566
// positive orientation
567
// normal vector may be null-pointer
568
void Ng_STL_AddTriangle (Ng_STL_Geometry * geom,
569
double * p1, double * p2, double * p3, double * nv)
570
{
571
Point<3> apts[3];
572
apts[0] = Point<3>(p1[0],p1[1],p1[2]);
573
apts[1] = Point<3>(p2[0],p2[1],p2[2]);
574
apts[2] = Point<3>(p3[0],p3[1],p3[2]);
575
576
Vec<3> n;
577
if (!nv)
578
n = Cross (apts[0]-apts[1], apts[0]-apts[2]);
579
else
580
n = Vec<3>(nv[0],nv[1],nv[2]);
581
582
readtrias.Append(STLReadTriangle(apts,n));
583
}
584
585
// add (optional) edges:
586
void Ng_STL_AddEdge (Ng_STL_Geometry * geom,
587
double * p1, double * p2)
588
{
589
readedges.Append(Point3d(p1[0],p1[1],p1[2]));
590
readedges.Append(Point3d(p2[0],p2[1],p2[2]));
591
}
592
593
594
595
Ng_Meshing_Parameters :: Ng_Meshing_Parameters()
596
{
597
maxh = 1000;
598
fineness = 0.5;
599
secondorder = 0;
600
meshsize_filename = 0;
601
quad_dominated = 0;
602
}
603
604
605
}
606
607
608
// compatibility functions:
609
610
namespace netgen
611
{
612
613
char geomfilename[255];
614
615
void MyError (const char * ch)
616
{
617
cerr << ch;
618
}
619
620
//Destination for messages, errors, ...
621
void Ng_PrintDest(const char * s)
622
{
623
(*mycout) << s << flush;
624
}
625
626
double GetTime ()
627
{
628
return 0;
629
}
630
631
void ResetTime ()
632
{
633
;
634
}
635
636
void MyBeep (int i)
637
{
638
;
639
}
640
641
}
642
643