Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
ElmerCSC
GitHub Repository: ElmerCSC/elmerfem
Path: blob/devel/ElmerGUI/netgen/libsrc/stlgeom/stlgeommesh.cpp
3206 views
1
//20.11.1999 second part of stlgeom.cc, mainly mesh functions
2
3
#include <mystdlib.h>
4
5
#include <myadt.hpp>
6
#include <linalg.hpp>
7
#include <gprim.hpp>
8
9
#include <meshing.hpp>
10
11
#include "stlgeom.hpp"
12
13
namespace netgen
14
{
15
int EdgeUsed(int p1, int p2, ARRAY<INDEX_2>& edges, INDEX_2_HASHTABLE<int>& hashtab)
16
{
17
if (p1 > p2) {swap (p1,p2);}
18
19
if (hashtab.Used(INDEX_2(p1,p2)))
20
{return hashtab.Get(INDEX_2(p1,p2));}
21
22
return 0;
23
}
24
25
Point<3> STLGeometry :: PointBetween(const Point<3> & ap1, int t1,
26
const Point<3> & ap2, int t2)
27
{
28
//funktioniert nicht in allen F�llen!
29
30
PrintWarning("Point between");
31
32
33
ClearMarkedSegs();
34
35
InitMarkedTrigs();
36
SetMarkedTrig(t1,1);
37
SetMarkedTrig(t2,1);
38
39
TABLE<Point3d> edgepoints;
40
TABLE<double> edgepointdists;
41
TABLE<int> edgepointorigines;
42
TABLE<int> edgepointoriginps;
43
44
ARRAY<int> edgetrigs;
45
ARRAY<INDEX_2> edgepointnums;
46
ARRAY<int> edgetriglocinds;
47
48
int size = 3*GetNT();
49
INDEX_2_HASHTABLE<int> hashtab(size);
50
51
int divisions = 10;
52
53
edgepoints.SetSize(size);
54
edgepointdists.SetSize(size);
55
edgepointorigines.SetSize(size);
56
edgepointoriginps.SetSize(size);
57
58
edgetrigs.SetSize(size);
59
edgepointnums.SetSize(size);
60
edgetriglocinds.SetSize(size);
61
62
ARRAY<int> edgelist1;
63
ARRAY<int> edgelist2;
64
65
edgelist1.SetSize(0);
66
edgelist2.SetSize(0);
67
68
69
int i, j, k, l, m;
70
int edgecnt = 0;
71
72
//first triangle:
73
for (i = 1; i <= 3; i++)
74
{
75
int ptn1 = GetTriangle(t1).PNum(i);
76
int ptn2 = GetTriangle(t1).PNumMod(i+1);
77
78
if (ptn1 > ptn2) {swap(ptn1,ptn2);}
79
80
Point3d pt1 = GetPoint(ptn1);
81
Point3d pt2 = GetPoint(ptn2);
82
83
edgecnt++;
84
edgetrigs.Elem(edgecnt) = t1;
85
edgepointnums.Elem(edgecnt) = INDEX_2(ptn1,ptn2);
86
hashtab.Set(edgepointnums.Get(edgecnt),edgecnt);
87
88
edgetriglocinds.Elem(edgecnt) = i;
89
edgelist1.Append(edgecnt);
90
91
for (j = 1; j <= divisions; j++)
92
{
93
double lfact = (double)j/(double)divisions;
94
Point3d pbtw(lfact*pt1.X()+(1.-lfact)*pt2.X(),
95
lfact*pt1.Y()+(1.-lfact)*pt2.Y(),
96
lfact*pt1.Z()+(1.-lfact)*pt2.Z());
97
98
//AddMarkedSeg(ap1,pbtw);
99
100
edgepoints.Add1(edgecnt,pbtw);
101
edgepointdists.Add1(edgecnt,Dist(pbtw,ap1));
102
edgepointorigines.Add1(edgecnt,0);
103
edgepointoriginps.Add1(edgecnt,0);
104
}
105
}
106
107
int finished = 0;
108
int endpointorigine = 0;
109
int endpointoriginp = 0;
110
double endpointmindist = 1E50;
111
112
int maxsize = 0;
113
while (!finished)
114
{
115
finished = 1;
116
117
if (edgelist1.Size() > maxsize) {maxsize = edgelist1.Size();}
118
119
for (i = 1; i <= edgelist1.Size(); i++)
120
{
121
int en = edgelist1.Get(i);
122
int trig = edgetrigs.Get(en);
123
int edgenum = edgetriglocinds.Get(en);
124
int tn = NeighbourTrigSorted(trig,edgenum);
125
126
if (tn != t2)
127
{
128
for (k = 1; k <= 3; k++)
129
{
130
int pnt1 = GetTriangle(tn).PNum(k);
131
int pnt2 = GetTriangle(tn).PNumMod(k+1);
132
133
if (pnt1 > pnt2) {swap(pnt1,pnt2);}
134
135
Point3d pt1 = GetPoint(pnt1);
136
Point3d pt2 = GetPoint(pnt2);
137
138
//AddMarkedSeg(pt1,pt2);
139
140
//if (!(pnt1 == ep1 && pnt2 == ep2))
141
// {
142
int edgeused = 0;
143
edgenum = EdgeUsed(pnt1, pnt2, edgepointnums, hashtab);
144
if (edgenum != en)
145
{
146
if (edgenum != 0)
147
{edgeused = 1;}
148
else
149
{
150
edgecnt++;
151
edgenum = edgecnt;
152
153
edgetrigs.Elem(edgenum) = tn;
154
edgepointnums.Elem(edgenum) = INDEX_2(pnt1,pnt2);
155
hashtab.Set(edgepointnums.Get(edgenum),edgenum);
156
edgetriglocinds.Elem(edgenum) = k;
157
}
158
159
if (edgenum > size || edgenum == 0) {PrintSysError("edgenum = ", edgenum);}
160
161
double minofmindist = 1E50;
162
int changed = 0;
163
164
for (l = 1; l <= divisions; l++)
165
{
166
double lfact = (double)l/(double)divisions;
167
Point3d pbtw(lfact*pt1.X()+(1.-lfact)*pt2.X(),
168
lfact*pt1.Y()+(1.-lfact)*pt2.Y(),
169
lfact*pt1.Z()+(1.-lfact)*pt2.Z());
170
171
double mindist = 1E50;
172
int index=0;
173
174
for (m = 1; m <= divisions; m++)
175
{
176
const Point3d& p = edgepoints.Get(en,m);
177
if (Dist(pbtw,p) + edgepointdists.Get(en,m) < mindist)
178
{mindist = Dist(pbtw,p) + edgepointdists.Get(en,m); index = m;}
179
}
180
181
//if (mindist < endpointmindist) {finished = 0;}
182
if (mindist < minofmindist) {minofmindist = mindist;}
183
184
185
if (!edgeused)
186
{
187
//AddMarkedSeg(pbtw,edgepoints.Get(en,index));
188
189
edgepoints.Add1(edgenum,pbtw);
190
edgepointdists.Add1(edgenum,mindist);
191
edgepointorigines.Add1(edgenum,en);
192
edgepointoriginps.Add1(edgenum,index);
193
changed = 1;
194
}
195
else
196
{
197
if (mindist < edgepointdists.Get(edgenum,l))
198
{
199
edgepointdists.Set(edgenum,l,mindist);
200
edgepointorigines.Set(edgenum,l,en);
201
edgepointoriginps.Set(edgenum,l,index);
202
changed = 1;
203
}
204
}
205
}
206
if (minofmindist < endpointmindist-1E-10 && changed)
207
{
208
finished = 0;
209
edgelist2.Append(edgenum);
210
}
211
}
212
}
213
}
214
else
215
{
216
double mindist = 1E50;
217
int index(0);
218
for (m = 1; m <= divisions; m++)
219
{
220
const Point3d& p = edgepoints.Get(en,m);
221
if (Dist(ap2,p) + edgepointdists.Get(en,m) < mindist)
222
{mindist = Dist(ap2,p) + edgepointdists.Get(en,m); index = m;}
223
}
224
if (mindist < endpointmindist)
225
{
226
endpointorigine = en;
227
endpointoriginp = index;
228
endpointmindist = mindist;
229
}
230
}
231
}
232
edgelist1.SetSize(0);
233
for (i = 1; i <= edgelist2.Size(); i++)
234
{
235
edgelist1.Append(edgelist2.Get(i));
236
}
237
}
238
239
if (!endpointorigine) {PrintSysError("No connection found!");}
240
241
ARRAY<Point3d> plist;
242
243
plist.Append(ap2);
244
int laste = endpointorigine;
245
int lastp = endpointoriginp;
246
int lle, llp;
247
248
249
while (laste)
250
{
251
plist.Append(edgepoints.Get(laste,lastp));
252
253
lle = laste;
254
llp = lastp;
255
laste = edgepointorigines.Get(lle,llp);
256
lastp = edgepointoriginps.Get(lle,llp);
257
}
258
259
plist.Append(ap1);
260
261
for (i = 1; i <= plist.Size()-1; i++)
262
{
263
AddMarkedSeg(plist.Get(i),plist.Get(i+1));
264
}
265
266
PrintMessage(5,"PointBetween: complexity=", maxsize);
267
268
269
Point3d pm;
270
double dist = 0;
271
int found = 0;
272
273
for (i = 1; i <= plist.Size()-1; i++)
274
{
275
dist += Dist(plist.Get(i),plist.Get(i+1));
276
if (dist > endpointmindist*0.5)
277
{
278
double segl = Dist(plist.Get(i), plist.Get(i+1));
279
double d = dist - endpointmindist * 0.5;
280
pm = Point3d(d/segl*plist.Get(i).X() + (1.-d/segl)*plist.Get(i+1).X(),
281
d/segl*plist.Get(i).Y() + (1.-d/segl)*plist.Get(i+1).Y(),
282
d/segl*plist.Get(i).Z() + (1.-d/segl)*plist.Get(i+1).Z());
283
found = 1;
284
break;
285
}
286
}
287
if (!found) {PrintWarning("Problem in PointBetween"); pm = Center(ap1,ap2);}
288
289
AddMarkedSeg(pm, Point3d(0.,0.,0.));
290
291
return pm;
292
293
}
294
295
296
void STLGeometry :: PrepareSurfaceMeshing()
297
{
298
meshchart = -1; //clear no old chart
299
meshcharttrigs.SetSize(GetNT());
300
int i;
301
for (i = 1; i <= GetNT(); i++)
302
{meshcharttrigs.Elem(i) = 0;}
303
}
304
305
void STLGeometry::GetMeshChartBoundary (ARRAY<Point2d > & apoints,
306
ARRAY<Point3d > & points3d,
307
ARRAY<INDEX_2> & alines, double h)
308
{
309
int i, j;
310
twoint seg, newseg;
311
int zone;
312
Point<2> p2;
313
314
const STLChart& chart = GetChart(meshchart);
315
316
317
for (i = 1; i <= chart.GetNOLimit(); i++)
318
{
319
seg = chart.GetOLimit(i);
320
INDEX_2 i2;
321
for (j = 1; j <= 2; j++)
322
{
323
int pi = (j == 1) ? seg.i1 : seg.i2;
324
int lpi;
325
if (ha_points.Get(pi) == 0)
326
{
327
const Point<3> & p3d = GetPoint (pi);
328
Point<2> p2d;
329
330
points3d.Append (p3d);
331
ToPlane(p3d, 0, p2d, h, zone, 0);
332
apoints.Append (p2d);
333
334
lpi = apoints.Size();
335
ha_points.Elem(pi) = lpi;
336
}
337
else
338
lpi = ha_points.Get(pi);
339
340
i2.I(j) = lpi;
341
}
342
alines.Append (i2);
343
344
/*
345
seg = chart.GetOLimit(i);
346
psize = points.Size();
347
348
newseg.i1 = psize+1;
349
newseg.i2 = psize+2;
350
351
ToPlane(GetPoint(seg.i1), 0, p2, h, zone, 0);
352
points.Append(p2);
353
points3d.Append (GetPoint(seg.i1));
354
ToPlane(GetPoint(seg.i2), 0, p2, h, zone, 0);
355
points.Append(p2);
356
points3d.Append (GetPoint(seg.i2));
357
lines.Append (INDEX_2 (points.Size()-1, points.Size()));
358
*/
359
}
360
361
for (i = 1; i <= chart.GetNOLimit(); i++)
362
{
363
seg = chart.GetOLimit(i);
364
ha_points.Elem(seg.i1) = 0;
365
ha_points.Elem(seg.i2) = 0;
366
}
367
}
368
369
void STLGeometry :: DefineTangentialPlane (const Point<3> & ap1, const Point<3> & ap2, int trig)
370
{
371
p1 = ap1; //save for ToPlane, in data of STLGeometry class
372
Point<3> p2 = ap2; //only locally used
373
374
meshchart = GetChartNr(trig);
375
376
if (usechartnormal)
377
meshtrignv = GetChart(meshchart).GetNormal();
378
else
379
meshtrignv = GetTriangle(trig).Normal();
380
381
//meshtrignv = GetTriangle(trig).Normal(points);
382
383
meshtrignv /= meshtrignv.Length();
384
385
GetTriangle(trig).ProjectInPlain(points, meshtrignv, p2);
386
387
388
ez = meshtrignv;
389
ez /= ez.Length();
390
ex = p2 - p1;
391
ex -= (ex * ez) * ez;
392
ex /= ex.Length();
393
ey = Cross (ez, ex);
394
395
}
396
397
398
void STLGeometry :: SelectChartOfTriangle (int trignum)
399
{
400
meshchart = GetChartNr(trignum);
401
meshtrignv = GetTriangle(trignum).Normal();
402
}
403
404
405
void STLGeometry :: SelectChartOfPoint (const Point<3> & p)
406
{
407
int i, ii;
408
409
ARRAY<int> trigsinbox;
410
411
Box<3> box(p,p);
412
box.Increase (1e-6);
413
GetTrianglesInBox (box, trigsinbox);
414
415
416
// for (i = 1; i <= GetNT(); i++)
417
for (ii = 1; ii <= trigsinbox.Size(); ii++)
418
{
419
i = trigsinbox.Get(ii);
420
Point<3> hp = p;
421
if (GetTriangle(i).GetNearestPoint(points, hp) <= 1E-8)
422
{
423
SelectChartOfTriangle (i);
424
break;
425
}
426
}
427
return;
428
}
429
430
431
432
void STLGeometry :: ToPlane (const Point<3> & locpoint, int * trigs,
433
Point<2> & plainpoint, double h, int& zone,
434
int checkchart)
435
{
436
if (checkchart)
437
{
438
439
//check if locpoint lies on actual chart:
440
zone = 0;
441
442
443
// Point3d p;
444
int i = 1;
445
const STLChart& chart = GetChart(meshchart);
446
int foundinchart = 0;
447
const double range = 1e-6; //1e-4 old
448
449
450
451
452
if (trigs)
453
{
454
int * htrigs = trigs;
455
while (*htrigs)
456
{
457
if (TrigIsInOC (*htrigs, meshchart))
458
{
459
foundinchart = 1;
460
break;
461
}
462
htrigs++;
463
}
464
}
465
466
else
467
{
468
ARRAY<int> trigsinbox;
469
470
if (!geomsearchtreeon)
471
{
472
//alter chart-tree
473
Box<3> box(locpoint, locpoint);
474
box.Increase (range);
475
chart.GetTrianglesInBox (box.PMin(), box.PMax(), trigsinbox);
476
}
477
else
478
{
479
ARRAY<int> trigsinbox2;
480
Box<3> box(locpoint, locpoint);
481
box.Increase (range);
482
GetTrianglesInBox (box, trigsinbox2);
483
for (i = 1; i <= trigsinbox2.Size(); i++)
484
{
485
if (TrigIsInOC(trigsinbox2.Get(i),meshchart)) {trigsinbox.Append(trigsinbox2.Get(i));}
486
}
487
488
}
489
490
491
for (i = 1; i <= trigsinbox.Size(); i++)
492
{
493
Point<3> p = locpoint;
494
if (GetTriangle(trigsinbox.Get(i)).GetNearestPoint(points, p)
495
<= 1E-8)
496
{
497
foundinchart = 1;
498
break;
499
}
500
501
}
502
}
503
504
//do not use this point (but do correct projection (joachim)
505
if (!foundinchart)
506
{
507
zone = -1; // plainpoint.X() = 11111; plainpoint.Y() = 11111; return;
508
}
509
}
510
511
else
512
{
513
zone = 0;
514
}
515
516
//transform in plane
517
Vec<3> p1p = locpoint - p1;
518
plainpoint(0) = (p1p * ex) / h;
519
plainpoint(1) = (p1p * ey) / h;
520
521
}
522
523
int STLGeometry :: FromPlane (const Point<2> & plainpoint,
524
Point<3> & locpoint, double h)
525
{
526
Point2d plainpoint2 (plainpoint);
527
528
plainpoint2.X() *= h;
529
plainpoint2.Y() *= h;
530
Vec3d p1p = plainpoint2.X() * ex + plainpoint2.Y() * ey;
531
locpoint = p1 + p1p;
532
533
534
int rv = Project(locpoint);
535
if (!rv) {return 1;} //project nicht gegangen
536
return 0;
537
}
538
539
int lasttrig;
540
int STLGeometry :: LastTrig() const {return lasttrig;};
541
542
//project normal to tangential plane
543
int STLGeometry :: Project(Point<3> & p3d) const
544
{
545
Point<3> p, pf;
546
547
int i, j;
548
int fi = 0;
549
int cnt = 0;
550
int different = 0;
551
const double lamtol = 1e-6;
552
553
const STLChart& chart = GetChart(meshchart);
554
555
int nt = chart.GetNT();
556
557
QuadraticFunction3d quadfun(p3d, meshtrignv);
558
559
/*
560
Vec3d hv = meshtrignv;
561
hv /= hv.Length();
562
Vec3d t1, t2;
563
hv.GetNormal (t1);
564
Cross (hv, t1, t2);
565
*/
566
567
for (j = 1; j <= nt; j++)
568
{
569
i = chart.GetTrig(j);
570
571
const Point<3> & c = GetTriangle(i).center;
572
/*
573
double d1 = t1 * (c-p3d);
574
double d2 = t2 * (c-p3d);
575
*/
576
/*
577
if (d1 * d1 + d2 * d2 > sqr (GetTriangle(i).rad))
578
continue;
579
*/
580
if (quadfun.Eval(c) > sqr (GetTriangle(i).rad))
581
continue;
582
583
p = p3d;
584
Vec<3> lam;
585
int err = GetTriangle(i).ProjectInPlain(points, meshtrignv, p, lam);
586
int inside = (err == 0 && lam(0) > -lamtol &&
587
lam(1) > -lamtol && (1-lam(0)-lam(1)) > -lamtol);
588
589
590
/*
591
p = p3d;
592
GetTriangle(i).ProjectInPlain(points, meshtrignv, p);
593
if (GetTriangle(i).PointInside(points, p))
594
*/
595
if (inside)
596
{
597
if (cnt != 0)
598
{
599
if (Dist2(p,pf)>=1E-16)
600
{
601
// (*testout) << "ERROR: found two points to project which are different" << endl;
602
//(*testout) << "p=" << p << ", pf=" << pf << endl;
603
different = 1;
604
}
605
}
606
pf = p; fi = i; cnt++;
607
}
608
609
if (inside)
610
break;
611
612
}
613
614
// if (cnt == 2) {(*testout) << "WARNING: found 2 triangles to project" << endl;}
615
//if (cnt == 3) {(*testout) << "WARNING: found 3 triangles to project" << endl;}
616
//if (cnt > 3) {(*testout) << "WARNING: found more than 3 triangles to project" << endl;}
617
618
if (fi != 0) {lasttrig = fi;}
619
if (fi != 0 && !different) {p3d = pf; return fi;}
620
621
// (*testout) << "WARNING: Project failed" << endl;
622
return 0;
623
624
}
625
626
//project normal to tangential plane
627
int STLGeometry :: ProjectOnWholeSurface(Point<3> & p3d) const
628
{
629
Point<3> p, pf;
630
631
int i;
632
int fi = 0;
633
int cnt = 0;
634
int different = 0;
635
const double lamtol = 1e-6;
636
637
for (i = 1; i <= GetNT(); i++)
638
{
639
p = p3d;
640
Vec<3> lam;
641
int err =
642
GetTriangle(i).ProjectInPlain(points, meshtrignv, p, lam);
643
int inside = (err == 0 && lam(0) > -lamtol &&
644
lam(1) > -lamtol && (1-lam(0)-lam(1)) > -lamtol);
645
646
/*
647
p = p3d;
648
GetTriangle(i).ProjectInPlain(points, meshtrignv, p);
649
if (GetTriangle(i).PointInside(points, p))
650
*/
651
if (inside)
652
{
653
if (cnt != 0)
654
{
655
if (Dist2(p,pf)>=1E-16)
656
{
657
// (*testout) << "ERROR: found two points to project which are different" << endl;
658
// (*testout) << "p=" << p << ", pf=" << pf << endl;
659
different = 1;
660
}
661
}
662
pf = p; fi = i; cnt++;
663
}
664
}
665
/*
666
if (cnt == 2) {(*testout) << "WARNING: found 2 triangles to project" << endl;}
667
if (cnt == 3) {(*testout) << "WARNING: found 3 triangles to project" << endl;}
668
if (cnt > 3) {(*testout) << "WARNING: found more than 3 triangles to project" << endl;}
669
*/
670
if (fi != 0) {lasttrig = fi;}
671
if (fi != 0 && !different) {p3d = pf; return fi;}
672
673
// (*testout) << "WARNING: Project failed" << endl;
674
return 0;
675
676
}
677
678
679
int STLGeometry :: ProjectNearest(Point<3> & p3d) const
680
{
681
Point<3> p, pf;
682
683
//set new chart
684
const STLChart& chart = GetChart(meshchart);
685
int i;
686
double nearest = 1E50;
687
double dist;
688
int ft = 0;
689
690
for (i = 1; i <= chart.GetNT(); i++)
691
{
692
p = p3d;
693
dist = GetTriangle(chart.GetTrig(i)).GetNearestPoint(points, p);
694
if (dist < nearest)
695
{
696
pf = p;
697
nearest = dist;
698
ft = chart.GetTrig(i);
699
}
700
}
701
p3d = pf;
702
//if (!ft) {(*testout) << "ERROR: ProjectNearest failed" << endl;}
703
704
return ft;
705
}
706
707
708
709
710
//Restrict local h due to curvature for make atlas
711
void STLGeometry :: RestrictLocalHCurv(class Mesh & mesh, double gh)
712
{
713
PushStatusF("Restrict H due to surface curvature");
714
715
//bei jedem Dreieck alle Nachbardreiecke vergleichen, und, fallskein Kante dazwischen,
716
//die Meshsize auf ein bestimmtes Mass limitieren
717
int i,j;
718
719
int ap1,ap2,p3,p4;
720
Point<3> p1p, p2p, p3p, p4p;
721
Vec<3> n, ntn;
722
double rzyl, localh;
723
724
// double localhfact = 0.5;
725
// double geometryignorelength = 1E-4;
726
double minlocalh = stlparam.atlasminh;
727
728
Box<3> bb = GetBoundingBox();
729
// mesh.SetLocalH(bb.PMin() - Vec3d(10, 10, 10),bb.PMax() + Vec3d(10, 10, 10),
730
// mparam.grading);
731
732
// mesh.SetGlobalH(gh);
733
734
double mincalch = 1E10;
735
double maxcalch = -1E10;
736
737
double objectsize = bb.Diam();
738
double geometryignoreedgelength = objectsize * 1e-5;
739
740
741
if (stlparam.resthatlasenable)
742
{
743
ARRAY<double> minh; //minimales h pro punkt
744
minh.SetSize(GetNP());
745
for (i = 1; i <= GetNP(); i++)
746
{
747
minh.Elem(i) = gh;
748
}
749
750
for (i = 1; i <= GetNT(); i++)
751
{
752
SetThreadPercent((double)i/(double)GetNT()*100.);
753
754
if (multithread.terminate)
755
{PopStatus(); return;}
756
757
const STLTriangle& trig = GetTriangle(i);
758
n = GetTriangle(i).Normal();
759
for (j = 1; j <= 3; j++)
760
{
761
const STLTriangle& nt = GetTriangle(NeighbourTrig(i,j));
762
763
trig.GetNeighbourPointsAndOpposite(nt,ap1,ap2,p3);
764
765
//checken, ob ap1-ap2 eine Kante sind
766
if (IsEdge(ap1,ap2)) continue;
767
768
p4 = trig.PNum(1) + trig.PNum(2) + trig.PNum(3) - ap1 - ap2;
769
770
p1p = GetPoint(ap1); p2p = GetPoint(ap2);
771
p3p = GetPoint(p3); p4p = GetPoint(p4);
772
773
double h1 = GetDistFromInfiniteLine(p1p,p2p, p4p);
774
double h2 = GetDistFromInfiniteLine(p1p,p2p, p3p);
775
double diaglen = Dist (p1p, p2p);
776
777
if (diaglen < geometryignoreedgelength)
778
continue;
779
rzyl = ComputeCylinderRadius
780
(n, GetTriangle(NeighbourTrig(i,j)).Normal(),
781
h1, h2);
782
783
784
if (h1 < 1e-3 * diaglen && h2 < 1e-3 * diaglen)
785
continue;
786
if (h1 < 1e-5 * objectsize && h2 < 1e-5 * objectsize)
787
continue;
788
789
790
// rzyl = mindist/(2*sinang);
791
localh = 10.*rzyl / stlparam.resthatlasfac;
792
if (localh < mincalch) {mincalch = localh;}
793
if (localh > maxcalch) {maxcalch = localh;}
794
795
if (localh < minlocalh) {localh = minlocalh;}
796
if (localh < gh)
797
{
798
minh.Elem(ap1) = min2(minh.Elem(ap1),localh);
799
minh.Elem(ap2) = min2(minh.Elem(ap2),localh);
800
}
801
802
mesh.RestrictLocalHLine(p1p, p2p, localh);
803
}
804
805
}
806
}
807
PrintMessage(5, "done\nATLAS H: nmin local h=", mincalch);
808
PrintMessage(5, "ATLAS H: max local h=", maxcalch);
809
PrintMessage(5, "Local h tree has ", mesh.LocalHFunction().GetNBoxes(), " boxes of size ",
810
(int)sizeof(GradingBox));
811
812
PopStatus();
813
814
}
815
//restrict local h due to near edges and due to outer chart distance
816
void STLGeometry :: RestrictLocalH(class Mesh & mesh, double gh)
817
{
818
819
//bei jedem Dreieck alle Nachbardreiecke vergleichen, und, fallskein Kante dazwischen,
820
//die Meshsize auf ein bestimmtes Mass limitieren
821
int i,j;
822
823
int ap1,ap2,p3,p4;
824
Point3d p1p, p2p, p3p, p4p;
825
Vec3d n, ntn;
826
double rzyl, localh;
827
828
// double localhfact = 0.5;
829
// double geometryignorelength = 1E-4;
830
831
Box<3> bb = GetBoundingBox();
832
//mesh.SetLocalH(bb.PMin() - Vec3d(10, 10, 10),bb.PMax() + Vec3d(10, 10, 10),
833
// mparam.grading);
834
835
//mesh.SetGlobalH(gh);
836
837
double mincalch = 1E10;
838
double maxcalch = -1E10;
839
840
double objectsize = bb.Diam();
841
double geometryignoreedgelength = objectsize * 1e-5;
842
843
if (stlparam.resthsurfcurvenable)
844
{
845
PushStatusF("Restrict H due to surface curvature");
846
847
ARRAY<double> minh; //minimales h pro punkt
848
minh.SetSize(GetNP());
849
for (i = 1; i <= GetNP(); i++)
850
{
851
minh.Elem(i) = gh;
852
}
853
854
for (i = 1; i <= GetNT(); i++)
855
{
856
SetThreadPercent((double)i/(double)GetNT()*100.);
857
if (i%20000==19999) {PrintMessage(7, (double)i/(double)GetNT()*100. , "%");}
858
859
if (multithread.terminate)
860
{PopStatus(); return;}
861
862
const STLTriangle& trig = GetTriangle(i);
863
n = GetTriangle(i).Normal();
864
for (j = 1; j <= 3; j++)
865
{
866
const STLTriangle& nt = GetTriangle(NeighbourTrig(i,j));
867
868
trig.GetNeighbourPointsAndOpposite(nt,ap1,ap2,p3);
869
870
//checken, ob ap1-ap2 eine Kante sind
871
if (IsEdge(ap1,ap2)) continue;
872
873
p4 = trig.PNum(1) + trig.PNum(2) + trig.PNum(3) - ap1 - ap2;
874
875
p1p = GetPoint(ap1); p2p = GetPoint(ap2);
876
p3p = GetPoint(p3); p4p = GetPoint(p4);
877
878
double h1 = GetDistFromInfiniteLine(p1p,p2p, p4p);
879
double h2 = GetDistFromInfiniteLine(p1p,p2p, p3p);
880
double diaglen = Dist (p1p, p2p);
881
882
if (diaglen < geometryignoreedgelength)
883
continue;
884
rzyl = ComputeCylinderRadius
885
(n, GetTriangle (NeighbourTrig(i,j)).Normal(),
886
h1, h2);
887
888
889
if (h1 < 1e-3 * diaglen && h2 < 1e-3 * diaglen)
890
continue;
891
892
if (h1 < 1e-5 * objectsize && h2 < 1e-5 * objectsize)
893
continue;
894
895
896
// rzyl = mindist/(2*sinang);
897
localh = rzyl / stlparam.resthsurfcurvfac;
898
if (localh < mincalch) {mincalch = localh;}
899
if (localh > maxcalch) {maxcalch = localh;}
900
if (localh < gh)
901
{
902
minh.Elem(ap1) = min2(minh.Elem(ap1),localh);
903
minh.Elem(ap2) = min2(minh.Elem(ap2),localh);
904
}
905
906
//if (localh < 0.2) {localh = 0.2;}
907
908
if(localh < objectsize)
909
mesh.RestrictLocalHLine(p1p, p2p, localh);
910
(*testout) << "restrict h along " << p1p << " - " << p2p << " to " << localh << endl;
911
912
if (localh < 0.1)
913
{
914
localh = 0.1;
915
}
916
917
}
918
}
919
PrintMessage(7, "done\nmin local h=", mincalch, "\nmax local h=", maxcalch);
920
PopStatus();
921
}
922
923
if (stlparam.resthcloseedgeenable)
924
{
925
PushStatusF("Restrict H due to close edges");
926
//geht nicht f�r spiralen!!!!!!!!!!!!!!!!!!
927
928
double disttohfact = sqr(10.0 / stlparam.resthcloseedgefac);
929
int k,l;
930
double h1, h2, dist;
931
int rc = 0;
932
Point3d p3p1;
933
double mindist = 1E50;
934
935
PrintMessage(7,"build search tree...");
936
Box3dTree* lsearchtree = new Box3dTree (GetBoundingBox().PMin() - Vec3d(1,1,1),
937
GetBoundingBox().PMax() + Vec3d(1,1,1));
938
939
ARRAY<Point3d> pmins(GetNLines());
940
ARRAY<Point3d> pmaxs(GetNLines());
941
942
double maxhline;
943
for (i = 1; i <= GetNLines(); i++)
944
{
945
maxhline = 0;
946
STLLine* l1 = GetLine(i);
947
Point3d pmin(GetPoint(l1->StartP())), pmax(GetPoint(l1->StartP())), px;
948
949
for (j = 2; j <= l1->NP(); j++)
950
{
951
px = GetPoint(l1->PNum(j));
952
maxhline = max2(maxhline,mesh.GetH(px));
953
pmin.SetToMin (px);
954
pmax.SetToMax (px);
955
}
956
Box3d box(pmin,pmax);
957
box.Increase(maxhline);
958
959
lsearchtree->Insert (box.PMin(), box.PMax(), i);
960
pmins.Elem(i) = box.PMin();
961
pmaxs.Elem(i) = box.PMax();
962
}
963
964
ARRAY<int> linenums;
965
int k2;
966
967
for (i = 1; i <= GetNLines(); i++)
968
{
969
SetThreadPercent((double)i/(double)GetNLines()*100.);
970
if (multithread.terminate)
971
{PopStatus(); return;}
972
973
linenums.SetSize(0);
974
lsearchtree->GetIntersecting(pmins.Get(i),pmaxs.Get(i),linenums);
975
976
STLLine* l1 = GetLine(i);
977
for (j = 1; j <= l1->NP(); j++)
978
{
979
p3p1 = GetPoint(l1->PNum(j));
980
h1 = sqr(mesh.GetH(p3p1));
981
982
for (k2 = 1; k2 <= linenums.Size(); k2++)
983
{
984
k = linenums.Get(k2);
985
if (k <= i) {continue;}
986
/*
987
//old, without searchtrees
988
for (k = i+1; k <= GetNLines(); k++)
989
{
990
*/
991
STLLine* l2 = GetLine(k);
992
for (l = 1; l <= l2->NP(); l++)
993
{
994
const Point3d& p3p2 = GetPoint(l2->PNum(l));
995
h2 = sqr(mesh.GetH(p3p2));
996
dist = Dist2(p3p1,p3p2)*disttohfact;
997
if (dist > 1E-12)
998
{
999
if (dist < h1)
1000
{
1001
mesh.RestrictLocalH(p3p1,sqrt(dist));
1002
rc++;
1003
mindist = min2(mindist,sqrt(dist));
1004
}
1005
if (dist < h2)
1006
{
1007
mesh.RestrictLocalH(p3p2,sqrt(dist));
1008
rc++;
1009
mindist = min2(mindist,sqrt(dist));
1010
}
1011
}
1012
}
1013
}
1014
}
1015
}
1016
PrintMessage(5, "done\n Restricted h in ", rc, " points due to near edges!");
1017
PopStatus();
1018
}
1019
1020
if (stlparam.resthedgeangleenable)
1021
{
1022
PushStatusF("Restrict h due to close edges");
1023
1024
int lp1, lp2;
1025
Vec3d v1,v2;
1026
mincalch = 1E50;
1027
maxcalch = -1E50;
1028
1029
for (i = 1; i <= GetNP(); i++)
1030
{
1031
SetThreadPercent((double)i/(double)GetNP()*100.);
1032
if (multithread.terminate)
1033
{PopStatus(); return;}
1034
1035
if (GetNEPP(i) == 2 && !IsLineEndPoint(i))
1036
{
1037
if (GetEdge(GetEdgePP(i,1)).PNum(2) == GetEdge(GetEdgePP(i,2)).PNum(1) ||
1038
GetEdge(GetEdgePP(i,1)).PNum(1) == GetEdge(GetEdgePP(i,2)).PNum(2))
1039
{
1040
lp1 = 1; lp2 = 2;
1041
}
1042
else
1043
{
1044
lp1 = 2; lp2 = 1;
1045
}
1046
1047
v1 = Vec3d(GetPoint(GetEdge(GetEdgePP(i,1)).PNum(1)),
1048
GetPoint(GetEdge(GetEdgePP(i,1)).PNum(2)));
1049
v2 = Vec3d(GetPoint(GetEdge(GetEdgePP(i,2)).PNum(lp1)),
1050
GetPoint(GetEdge(GetEdgePP(i,2)).PNum(lp2)));
1051
1052
rzyl = ComputeCylinderRadius(v1, v2, v1.Length(), v2.Length());
1053
1054
localh = rzyl / stlparam.resthedgeanglefac;
1055
if (localh < mincalch) {mincalch = localh;}
1056
if (localh > maxcalch) {maxcalch = localh;}
1057
1058
if (localh != 0)
1059
mesh.RestrictLocalH(GetPoint(i), localh);
1060
}
1061
}
1062
PrintMessage(7,"edge-angle min local h=", mincalch, "\nedge-angle max local h=", maxcalch);
1063
PopStatus();
1064
}
1065
1066
if (stlparam.resthchartdistenable)
1067
{
1068
PushStatusF("Restrict H due to outer chart distance");
1069
1070
// mesh.LocalHFunction().Delete();
1071
1072
//berechne minimale distanz von chart zu einem nicht-outerchart-punkt in jedem randpunkt einer chart
1073
1074
ARRAY<int> acttrigs; //outercharttrigs
1075
acttrigs.SetSize(GetNT());
1076
for (i = 1; i <= GetNT(); i++)
1077
{
1078
acttrigs.Elem(i) = 0;
1079
}
1080
for (i = 1; i <= GetNOCharts(); i++)
1081
{
1082
SetThreadPercent((double)i/(double)GetNOCharts()*100.);
1083
if (multithread.terminate)
1084
{PopStatus(); return;}
1085
1086
RestrictHChartDistOneChart(i, acttrigs, mesh, gh, 1., 0.);
1087
}
1088
1089
PopStatus();
1090
}
1091
1092
if (stlparam.resthlinelengthenable)
1093
{
1094
//restrict h due to short lines
1095
PushStatusF("Restrict H due to line-length");
1096
1097
double minhl = 1E50;
1098
double linefact = 1./stlparam.resthlinelengthfac;
1099
double l;
1100
for (i = 1; i <= GetNLines(); i++)
1101
{
1102
SetThreadPercent((double)i/(double)GetNLines()*100.);
1103
if (multithread.terminate)
1104
{PopStatus(); return;}
1105
1106
l = GetLine(i)->GetLength(points);
1107
1108
const Point3d& pp1 = GetPoint(GetLine(i)->StartP());
1109
const Point3d& pp2 = GetPoint(GetLine(i)->EndP());
1110
1111
if (l != 0)
1112
{
1113
minhl = min2(minhl,l*linefact);
1114
1115
mesh.RestrictLocalH(pp1, l*linefact);
1116
mesh.RestrictLocalH(pp2, l*linefact);
1117
}
1118
}
1119
PopStatus();
1120
PrintMessage(5, "minh due to line length=", minhl);
1121
}
1122
}
1123
1124
void STLGeometry :: RestrictHChartDistOneChart(int chartnum, ARRAY<int>& acttrigs,
1125
class Mesh & mesh, double gh, double fact, double minh)
1126
{
1127
int i = chartnum;
1128
int j;
1129
1130
double limessafety = stlparam.resthchartdistfac*fact; // original: 2
1131
double localh;
1132
1133
double f1,f2;
1134
// mincalch = 1E10;
1135
//maxcalch = -1E10;
1136
ARRAY<int> limes1;
1137
ARRAY<int> limes2;
1138
1139
ARRAY<Point3d> plimes1;
1140
ARRAY<Point3d> plimes2;
1141
1142
ARRAY<int> plimes1trigs; //check from wich trig the points come
1143
ARRAY<int> plimes2trigs;
1144
1145
ARRAY<int> plimes1origin; //either the original pointnumber or zero, if new point
1146
1147
int divisions = 10;
1148
1149
int k, t, nt, np1, np2;
1150
Point3d p3p1, p3p2;
1151
STLTriangle tt;
1152
1153
limes1.SetSize(0);
1154
limes2.SetSize(0);
1155
plimes1.SetSize(0);
1156
plimes2.SetSize(0);
1157
plimes1trigs.SetSize(0);
1158
plimes2trigs.SetSize(0);
1159
plimes1origin.SetSize(0);
1160
1161
STLChart& chart = GetChart(i);
1162
chart.ClearOLimit();
1163
chart.ClearILimit();
1164
1165
for (j = 1; j <= chart.GetNChartT(); j++)
1166
{
1167
t = chart.GetChartTrig(j);
1168
tt = GetTriangle(t);
1169
for (k = 1; k <= 3; k++)
1170
{
1171
nt = NeighbourTrig(t,k);
1172
if (GetChartNr(nt) != i)
1173
{
1174
tt.GetNeighbourPoints(GetTriangle(nt),np1,np2);
1175
if (!IsEdge(np1,np2) && !GetSpiralPoint(np1) && !GetSpiralPoint(np2))
1176
{
1177
p3p1 = GetPoint(np1);
1178
p3p2 = GetPoint(np2);
1179
if (AddIfNotExists(limes1,np1))
1180
{
1181
plimes1.Append(p3p1);
1182
plimes1trigs.Append(t);
1183
plimes1origin.Append(np1);
1184
}
1185
if (AddIfNotExists(limes1,np2))
1186
{
1187
plimes1.Append(p3p2);
1188
plimes1trigs.Append(t);
1189
plimes1origin.Append(np2);
1190
}
1191
chart.AddILimit(twoint(np1,np2));
1192
1193
for (int di = 1; di <= divisions; di++)
1194
{
1195
f1 = (double)di/(double)(divisions+1.);
1196
f2 = (divisions+1.-(double)di)/(double)(divisions+1.);
1197
1198
plimes1.Append(Point3d(p3p1.X()*f1+p3p2.X()*f2,
1199
p3p1.Y()*f1+p3p2.Y()*f2,
1200
p3p1.Z()*f1+p3p2.Z()*f2));
1201
plimes1trigs.Append(t);
1202
plimes1origin.Append(0);
1203
}
1204
}
1205
}
1206
}
1207
}
1208
1209
1210
for (j = 1; j <= chart.GetNT(); j++)
1211
{
1212
acttrigs.Elem(chart.GetTrig(j)) = i;
1213
}
1214
1215
for (j = 1; j <= chart.GetNOuterT(); j++)
1216
{
1217
t = chart.GetOuterTrig(j);
1218
tt = GetTriangle(t);
1219
for (k = 1; k <= 3; k++)
1220
{
1221
nt = NeighbourTrig(t,k);
1222
1223
if (acttrigs.Get(nt) != i)
1224
{
1225
tt.GetNeighbourPoints(GetTriangle(nt),np1,np2);
1226
1227
if (!IsEdge(np1,np2))
1228
{
1229
p3p1 = GetPoint(np1);
1230
p3p2 = GetPoint(np2);
1231
1232
if (AddIfNotExists(limes2,np1)) {plimes2.Append(p3p1); plimes2trigs.Append(t);}
1233
if (AddIfNotExists(limes2,np2)) {plimes2.Append(p3p2); plimes2trigs.Append(t);}
1234
chart.AddOLimit(twoint(np1,np2));
1235
1236
for (int di = 1; di <= divisions; di++)
1237
{
1238
f1 = (double)di/(double)(divisions+1.);
1239
f2 = (divisions+1.-(double)di)/(double)(divisions+1.);
1240
1241
plimes2.Append(Point3d(p3p1.X()*f1+p3p2.X()*f2,
1242
p3p1.Y()*f1+p3p2.Y()*f2,
1243
p3p1.Z()*f1+p3p2.Z()*f2));
1244
plimes2trigs.Append(t);
1245
}
1246
}
1247
}
1248
}
1249
}
1250
1251
1252
double chartmindist = 1E50;
1253
1254
if (plimes2.Size())
1255
{
1256
Box3d bbox;
1257
bbox.SetPoint (plimes2.Get(1));
1258
for (j = 2; j <= plimes2.Size(); j++)
1259
bbox.AddPoint (plimes2.Get(j));
1260
Point3dTree stree(bbox.PMin(), bbox.PMax());
1261
for (j = 1; j <= plimes2.Size(); j++)
1262
stree.Insert (plimes2.Get(j), j);
1263
ARRAY<int> foundpts;
1264
1265
for (j = 1; j <= plimes1.Size(); j++)
1266
{
1267
double mindist = 1E50;
1268
double dist;
1269
1270
const Point3d & ap1 = plimes1.Get(j);
1271
double boxs = mesh.GetH (plimes1.Get(j)) * limessafety;
1272
1273
Point3d pmin = ap1 - Vec3d (boxs, boxs, boxs);
1274
Point3d pmax = ap1 + Vec3d (boxs, boxs, boxs);
1275
1276
stree.GetIntersecting (pmin, pmax, foundpts);
1277
1278
1279
for (int kk = 1; kk <= foundpts.Size(); kk++)
1280
{
1281
k = foundpts.Get(kk);
1282
dist = Dist2(plimes1.Get(j),plimes2.Get(k));
1283
if (dist < mindist)
1284
{
1285
mindist = dist;
1286
}
1287
}
1288
1289
/*
1290
const Point3d & ap1 = plimes1.Get(j);
1291
double his = mesh.GetH (plimes1.Get(j));
1292
1293
double xmin = ap1.X() - his * limessafety;
1294
double xmax = ap1.X() + his * limessafety;
1295
double ymin = ap1.Y() - his * limessafety;
1296
double ymax = ap1.Y() + his * limessafety;
1297
double zmin = ap1.Z() - his * limessafety;
1298
double zmax = ap1.Z() + his * limessafety;
1299
1300
for (k = 1; k <= plimes2.Size(); k++)
1301
{
1302
const Point3d & ap2 = plimes2.Get(k);
1303
if (ap2.X() >= xmin && ap2.X() <= xmax &&
1304
ap2.Y() >= ymin && ap2.Y() <= ymax &&
1305
ap2.Z() >= zmin && ap2.Z() <= zmax)
1306
{
1307
dist = Dist2(plimes1.Get(j),plimes2.Get(k));
1308
if (dist < mindist)
1309
{
1310
mindist = dist;
1311
}
1312
}
1313
}
1314
*/
1315
mindist = sqrt(mindist);
1316
localh = mindist/limessafety;
1317
1318
if (localh < minh && localh != 0) {localh = minh;} //minh is generally 0! (except make atlas)
1319
if (localh < gh && localh > 0)
1320
{
1321
mesh.RestrictLocalH(plimes1.Get(j), localh);
1322
// if (mindist < mincalch) {mincalch = mindist;}
1323
// if (mindist > maxcalch) {maxcalch = mindist;}
1324
if (mindist < chartmindist) {chartmindist = mindist;}
1325
}
1326
}
1327
}
1328
1329
}
1330
1331
1332
//void * STLMeshingDummy (void *)
1333
int STLMeshingDummy (STLGeometry* stlgeometry, Mesh*& mesh,
1334
int perfstepsstart, int perfstepsend, char* optstring)
1335
{
1336
if (perfstepsstart > perfstepsend) return 0;
1337
1338
multithread.terminate = 0;
1339
int success = 1;
1340
//int trialcntouter = 0;
1341
1342
if (perfstepsstart <= MESHCONST_MESHEDGES)
1343
{
1344
1345
mesh = new Mesh();
1346
mesh -> SetGlobalH (mparam.maxh);
1347
mesh -> SetLocalH (stlgeometry->GetBoundingBox().PMin() - Vec3d(10, 10, 10),
1348
stlgeometry->GetBoundingBox().PMax() + Vec3d(10, 10, 10),
1349
mparam.grading);
1350
mesh -> LoadLocalMeshSize (mparam.meshsizefilename);
1351
1352
success = 0;
1353
1354
//mesh->DeleteMesh();
1355
1356
STLMeshing (*stlgeometry, *mesh);
1357
1358
stlgeometry->edgesfound = 1;
1359
stlgeometry->surfacemeshed = 0;
1360
stlgeometry->surfaceoptimized = 0;
1361
stlgeometry->volumemeshed = 0;
1362
}
1363
1364
if (multithread.terminate)
1365
return 0;
1366
1367
if (perfstepsstart <= MESHCONST_MESHSURFACE &&
1368
perfstepsend >= MESHCONST_MESHSURFACE)
1369
{
1370
1371
if (!stlgeometry->edgesfound)
1372
{
1373
PrintUserError("You have to do 'analyse geometry' first!!!");
1374
return 0;
1375
}
1376
if (stlgeometry->surfacemeshed || stlgeometry->surfacemeshed)
1377
{
1378
PrintUserError("Already meshed. Please start again with 'Analyse Geometry'!!!");
1379
return 0;
1380
}
1381
1382
success = 0;
1383
int retval = STLSurfaceMeshing (*stlgeometry, *mesh);
1384
if (retval == MESHING3_OK)
1385
{
1386
PrintMessage(3,"Success !!!!");
1387
stlgeometry->surfacemeshed = 1;
1388
stlgeometry->surfaceoptimized = 0;
1389
stlgeometry->volumemeshed = 0;
1390
success = 1;
1391
}
1392
else if (retval == MESHING3_OUTERSTEPSEXCEEDED)
1393
{
1394
PrintError("Give up because of too many trials. Meshing aborted!");
1395
}
1396
else if (retval == MESHING3_TERMINATE)
1397
{
1398
PrintWarning("Meshing Stopped by user!");
1399
}
1400
else
1401
{
1402
PrintError("Surface meshing not successful. Meshing aborted!");
1403
}
1404
1405
#ifdef STAT_STREAM
1406
(*statout) << mesh->GetNSeg() << " & " << endl
1407
<< mesh->GetNSE() << " & " << endl
1408
<< GetTime() << " & ";
1409
#endif
1410
}
1411
if (multithread.terminate)
1412
return 0;
1413
1414
if (success)
1415
{
1416
if (perfstepsstart <= MESHCONST_OPTSURFACE &&
1417
perfstepsend >= MESHCONST_OPTSURFACE)
1418
{
1419
if (!stlgeometry->edgesfound)
1420
{
1421
PrintUserError("You have to do 'meshing->analyse geometry' first!!!");
1422
return 0;
1423
}
1424
if (!stlgeometry->surfacemeshed)
1425
{
1426
PrintUserError("You have to do 'meshing->mesh surface' first!!!");
1427
return 0;
1428
}
1429
if (stlgeometry->volumemeshed)
1430
{
1431
PrintWarning("Surface optimization with meshed volume is dangerous!!!");
1432
}
1433
1434
if (!optstring || strlen(optstring) == 0)
1435
{
1436
mparam.optimize2d = "smcm";
1437
}
1438
else
1439
{
1440
mparam.optimize2d = optstring;
1441
}
1442
1443
STLSurfaceOptimization (*stlgeometry, *mesh, mparam);
1444
1445
if (stlparam.recalc_h_opt)
1446
{
1447
mesh -> SetLocalH (stlgeometry->GetBoundingBox().PMin() - Vec3d(10, 10, 10),
1448
stlgeometry->GetBoundingBox().PMax() + Vec3d(10, 10, 10),
1449
mparam.grading);
1450
mesh -> LoadLocalMeshSize (mparam.meshsizefilename);
1451
mesh -> CalcLocalHFromSurfaceCurvature (stlparam.resthsurfmeshcurvfac);
1452
mparam.optimize2d = "cmsmSm";
1453
STLSurfaceOptimization (*stlgeometry, *mesh, mparam);
1454
#ifdef STAT_STREAM
1455
(*statout) << GetTime() << " & ";
1456
#endif
1457
1458
#ifdef OPENGL
1459
extern void Render();
1460
Render();
1461
#endif
1462
}
1463
stlgeometry->surfaceoptimized = 1;
1464
}
1465
if (multithread.terminate)
1466
return 0;
1467
1468
if (perfstepsstart <= MESHCONST_MESHVOLUME &&
1469
perfstepsend >= MESHCONST_MESHVOLUME)
1470
{
1471
if (stlgeometry->volumemeshed)
1472
{
1473
PrintUserError("Volume already meshed!"); return 0;
1474
}
1475
1476
if (!stlgeometry->edgesfound)
1477
{
1478
PrintUserError("You have to do 'meshing->analyse geometry' first!!!");
1479
return 0;
1480
}
1481
if (!stlgeometry->surfacemeshed)
1482
{
1483
PrintUserError("You have to do 'meshing->mesh surface' first!!!");
1484
return 0;
1485
}
1486
if (!stlgeometry->surfaceoptimized)
1487
{
1488
PrintWarning("You should do 'meshing->optimize surface' first!!!");
1489
}
1490
1491
1492
PrintMessage(5,"Check Overlapping boundary: ");
1493
mesh->FindOpenElements();
1494
mesh->CheckOverlappingBoundary();
1495
PrintMessage(5,"");
1496
1497
1498
if (stlparam.recalc_h_opt)
1499
{
1500
mesh -> SetLocalH (stlgeometry->GetBoundingBox().PMin() - Vec3d(10, 10, 10),
1501
stlgeometry->GetBoundingBox().PMax() + Vec3d(10, 10, 10),
1502
mparam.grading);
1503
mesh -> LoadLocalMeshSize (mparam.meshsizefilename);
1504
mesh -> CalcLocalH ();
1505
}
1506
1507
1508
PrintMessage(5,"Volume meshing");
1509
int retval = MeshVolume (mparam, *mesh);
1510
if (retval == MESHING3_OK)
1511
{
1512
RemoveIllegalElements(*mesh);
1513
stlgeometry->volumemeshed = 1;
1514
}
1515
else if (retval == MESHING3_OUTERSTEPSEXCEEDED)
1516
{
1517
PrintError("Give up because of too many trials. Meshing aborted!");
1518
return 0;
1519
}
1520
else if (retval == MESHING3_TERMINATE)
1521
{
1522
PrintWarning("Meshing Stopped by user!");
1523
}
1524
else
1525
{
1526
PrintError("Volume meshing not successful. Meshing aborted!");
1527
return 0;
1528
}
1529
1530
#ifdef STAT_STREAM
1531
(*statout) << GetTime() << " & " << endl;
1532
#endif
1533
MeshQuality3d (*mesh);
1534
}
1535
1536
if (multithread.terminate)
1537
return 0;
1538
1539
if (perfstepsstart <= MESHCONST_OPTVOLUME &&
1540
perfstepsend >= MESHCONST_OPTVOLUME)
1541
{
1542
if (!stlgeometry->edgesfound)
1543
{
1544
PrintUserError("You have to do 'meshing->analyse geometry' first!!!");
1545
return 0;
1546
}
1547
if (!stlgeometry->surfacemeshed)
1548
{
1549
PrintUserError("You have to do 'meshing->mesh surface' first!!!");
1550
return 0;
1551
}
1552
if (!stlgeometry->volumemeshed)
1553
{
1554
PrintUserError("You have to do 'meshing->mesh volume' first!!!");
1555
return 0;
1556
}
1557
1558
if (!optstring || strlen(optstring) == 0)
1559
{
1560
mparam.optimize3d = "cmdmstm";
1561
}
1562
else
1563
{
1564
mparam.optimize3d = optstring;
1565
}
1566
1567
1568
OptimizeVolume (mparam, *mesh);
1569
1570
#ifdef STAT_STREAM
1571
(*statout) << GetTime() << " & " << endl;
1572
(*statout) << mesh->GetNE() << " & " << endl
1573
<< mesh->GetNP() << " " << '\\' << '\\' << " \\" << "hline" << endl;
1574
#endif
1575
1576
#ifdef OPENGL
1577
extern void Render();
1578
Render();
1579
#endif
1580
1581
}
1582
}
1583
1584
1585
return 0;
1586
}
1587
1588
1589
1590
}
1591
1592