Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
ElmerCSC
GitHub Repository: ElmerCSC/elmerfem
Path: blob/devel/ElmerGUI/netgen/libsrc/stlgeom/meshstlsurface.cpp
3206 views
1
#include <mystdlib.h>
2
#include <myadt.hpp>
3
4
#include <linalg.hpp>
5
#include <gprim.hpp>
6
7
#include <meshing.hpp>
8
9
10
#include "stlgeom.hpp"
11
12
13
namespace netgen
14
{
15
16
static void STLFindEdges (STLGeometry & geom,
17
class Mesh & mesh)
18
{
19
int i, j;
20
double h;
21
22
h = mparam.maxh;
23
24
// mark edge points:
25
//int ngp = geom.GetNP();
26
27
geom.RestrictLocalH(mesh, h);
28
29
PushStatusF("Mesh Lines");
30
31
ARRAY<STLLine*> meshlines;
32
ARRAY<Point3d> meshpoints;
33
34
PrintMessage(3,"Mesh Lines");
35
36
for (i = 1; i <= geom.GetNLines(); i++)
37
{
38
meshlines.Append(geom.GetLine(i)->Mesh(geom.GetPoints(), meshpoints, h, mesh));
39
SetThreadPercent(100.0 * (double)i/(double)geom.GetNLines());
40
}
41
42
geom.meshpoints.SetSize(0); //testing
43
geom.meshlines.SetSize(0); //testing
44
int pim;
45
for (i = 1; i <= meshpoints.Size(); i++)
46
{
47
geom.meshpoints.Append(meshpoints.Get(i)); //testing
48
49
pim = mesh.AddPoint(meshpoints.Get(i));
50
}
51
//(++++++++++++++testing
52
for (i = 1; i <= geom.GetNLines(); i++)
53
{
54
geom.meshlines.Append(meshlines.Get(i));
55
}
56
//++++++++++++++testing)
57
58
PrintMessage(7,"feed with edges");
59
60
for (i = 1; i <= meshlines.Size(); i++)
61
{
62
STLLine* line = meshlines.Get(i);
63
(*testout) << "store line " << i << endl;
64
for (j = 1; j <= line->GetNS(); j++)
65
{
66
int p1, p2;
67
68
line->GetSeg(j, p1, p2);
69
int trig1, trig2, trig1b, trig2b;
70
71
if (p1 == p2)
72
cout << "Add Segment, p1 == p2 == " << p1 << endl;
73
74
// Test auf geschlossener Rand mit 2 Segmenten
75
76
if ((j == 2) && (line->GetNS() == 2))
77
{
78
int oldp1, oldp2;
79
line->GetSeg (1, oldp1, oldp2);
80
if (oldp1 == p2 && oldp2 == p1)
81
{
82
PrintMessage(7,"MESSAGE: don't use second segment");
83
continue;
84
}
85
}
86
87
88
//mesh point number
89
//p1 = geom2meshnum.Get(p1); // for unmeshed lines!!!
90
//p2 = geom2meshnum.Get(p2); // for unmeshed lines!!!
91
92
//left and right trigs
93
trig1 = line->GetLeftTrig(j);
94
trig2 = line->GetRightTrig(j);
95
trig1b = line->GetLeftTrig(j+1);
96
trig2b = line->GetRightTrig(j+1);
97
98
(*testout) << "j = " << j << ", p1 = " << p1 << ", p2 = " << p2 << endl;
99
(*testout) << "segm-trigs: "
100
<< "trig1 = " << trig1
101
<< ", trig1b = " << trig1b
102
<< ", trig2 = " << trig2
103
<< ", trig2b = " << trig2b << endl;
104
105
if (trig1 <= 0 || trig2 <= 0 || trig1b <= 0 || trig2b <= 0)
106
{
107
cout << "negative trigs, "
108
<< ", trig1 = " << trig1
109
<< ", trig1b = " << trig1b
110
<< ", trig2 = " << trig2
111
<< ", trig2b = " << trig2b << endl;
112
}
113
/*
114
(*testout) << " trigs p1: " << trig1 << " - " << trig2 << endl;
115
(*testout) << " trigs p2: " << trig1b << " - " << trig2b << endl;
116
(*testout) << " charts p1: " << geom.GetChartNr(trig1) << " - " << geom.GetChartNr(trig2) << endl;
117
(*testout) << " charts p2: " << geom.GetChartNr(trig1b) << " - " << geom.GetChartNr(trig2b) << endl;
118
*/
119
Point3d hp, hp2;
120
Segment seg;
121
seg.p1 = p1;
122
seg.p2 = p2;
123
seg.si = geom.GetTriangle(trig1).GetFaceNum();
124
seg.edgenr = i;
125
126
seg.epgeominfo[0].edgenr = i;
127
seg.epgeominfo[0].dist = line->GetDist(j);
128
seg.epgeominfo[1].edgenr = i;
129
seg.epgeominfo[1].dist = line->GetDist(j+1);
130
/*
131
(*testout) << "seg = "
132
<< "edgenr " << seg.epgeominfo[0].edgenr
133
<< " dist " << seg.epgeominfo[0].dist
134
<< " edgenr " << seg.epgeominfo[1].edgenr
135
<< " dist " << seg.epgeominfo[1].dist << endl;
136
*/
137
138
seg.geominfo[0].trignum = trig1;
139
seg.geominfo[1].trignum = trig1b;
140
141
/*
142
geom.SelectChartOfTriangle (trig1);
143
hp = hp2 = mesh.Point (seg.p1);
144
seg.geominfo[0].trignum = geom.Project (hp);
145
146
(*testout) << "hp = " << hp2 << ", hp proj = " << hp << ", trignum = " << seg.geominfo[0].trignum << endl;
147
if (Dist (hp, hp2) > 1e-5 || seg.geominfo[0].trignum == 0)
148
{
149
(*testout) << "PROBLEM" << endl;
150
}
151
152
geom.SelectChartOfTriangle (trig1b);
153
hp = hp2 = mesh.Point (seg.p2);
154
seg.geominfo[1].trignum = geom.Project (hp);
155
156
(*testout) << "hp = " << hp2 << ", hp proj = " << hp << ", trignum = " << seg.geominfo[1].trignum << endl;
157
if (Dist (hp, hp2) > 1e-5 || seg.geominfo[1].trignum == 0)
158
{
159
(*testout) << "PROBLEM" << endl;
160
}
161
*/
162
163
164
if (Dist (mesh.Point(seg.p1), mesh.Point(seg.p2)) < 1e-10)
165
{
166
(*testout) << "ERROR: Line segment of length 0" << endl;
167
(*testout) << "pi1, 2 = " << seg.p1 << ", " << seg.p2 << endl;
168
(*testout) << "p1, 2 = " << mesh.Point(seg.p1)
169
<< ", " << mesh.Point(seg.p2) << endl;
170
throw NgException ("Line segment of length 0");
171
}
172
173
mesh.AddSegment (seg);
174
175
176
Segment seg2;
177
seg2.p1 = p2;
178
seg2.p2 = p1;
179
seg2.si = geom.GetTriangle(trig2).GetFaceNum();
180
seg2.edgenr = i;
181
182
seg2.epgeominfo[0].edgenr = i;
183
seg2.epgeominfo[0].dist = line->GetDist(j+1);
184
seg2.epgeominfo[1].edgenr = i;
185
seg2.epgeominfo[1].dist = line->GetDist(j);
186
/*
187
(*testout) << "seg = "
188
<< "edgenr " << seg2.epgeominfo[0].edgenr
189
<< " dist " << seg2.epgeominfo[0].dist
190
<< " edgenr " << seg2.epgeominfo[1].edgenr
191
<< " dist " << seg2.epgeominfo[1].dist << endl;
192
*/
193
194
seg2.geominfo[0].trignum = trig2b;
195
seg2.geominfo[1].trignum = trig2;
196
197
/*
198
geom.SelectChartOfTriangle (trig2);
199
hp = hp2 = mesh.Point (seg.p1);
200
seg2.geominfo[0].trignum = geom.Project (hp);
201
202
(*testout) << "hp = " << hp2 << ", hp proj = " << hp << ", trignum = " << seg.geominfo[0].trignum << endl;
203
if (Dist (hp, hp2) > 1e-5 || seg2.geominfo[0].trignum == 0)
204
{
205
(*testout) << "Get GeomInfo PROBLEM" << endl;
206
}
207
208
209
geom.SelectChartOfTriangle (trig2b);
210
hp = hp2 = mesh.Point (seg.p2);
211
seg2.geominfo[1].trignum = geom.Project (hp);
212
(*testout) << "hp = " << hp2 << ", hp proj = " << hp << ", trignum = " << seg.geominfo[1].trignum << endl;
213
if (Dist (hp, hp2) > 1e-5 || seg2.geominfo[1].trignum == 0)
214
{
215
(*testout) << "Get GeomInfo PROBLEM" << endl;
216
}
217
*/
218
219
mesh.AddSegment (seg2);
220
221
222
/*
223
// should be start triangle and end triangle
224
int bothtrigs1[2] = { trig1, trig1 };
225
meshing.AddBoundaryElement (p1, p2, sizeof (bothtrigs1), &bothtrigs1);
226
227
int bothtrigs2[2] = { trig2, trig2 };
228
meshing.AddBoundaryElement (p2, p1, sizeof (bothtrigs2), &bothtrigs2);
229
*/
230
}
231
}
232
233
PopStatus();
234
}
235
236
237
238
239
void STLSurfaceMeshing1 (STLGeometry & geom,
240
class Mesh & mesh,
241
int retrynr);
242
243
int STLSurfaceMeshing (STLGeometry & geom,
244
class Mesh & mesh)
245
{
246
int i, j;
247
PrintFnStart("Do Surface Meshing");
248
249
geom.PrepareSurfaceMeshing();
250
251
if (mesh.GetNSeg() == 0)
252
STLFindEdges (geom, mesh);
253
254
int nopen;
255
int outercnt = 20;
256
257
// mesh.Save ("mesh.edges");
258
259
for (i = 1; i <= mesh.GetNSeg(); i++)
260
{
261
const Segment & seg = mesh.LineSegment (i);
262
if (seg.geominfo[0].trignum <= 0 || seg.geominfo[1].trignum <= 0)
263
{
264
(*testout) << "Problem with segment " << i << ": " << seg << endl;
265
}
266
}
267
268
269
do
270
{
271
outercnt--;
272
if (outercnt <= 0)
273
return MESHING3_OUTERSTEPSEXCEEDED;
274
275
if (multithread.terminate)
276
{
277
return MESHING3_TERMINATE;
278
}
279
280
mesh.FindOpenSegments();
281
nopen = mesh.GetNOpenSegments();
282
283
if (nopen)
284
{
285
int trialcnt = 0;
286
while (nopen && trialcnt <= 5)
287
{
288
if (multithread.terminate)
289
{
290
return MESHING3_TERMINATE;
291
}
292
trialcnt++;
293
STLSurfaceMeshing1 (geom, mesh, trialcnt);
294
295
mesh.FindOpenSegments();
296
nopen = mesh.GetNOpenSegments();
297
298
if (nopen)
299
{
300
geom.ClearMarkedSegs();
301
for (i = 1; i <= nopen; i++)
302
{
303
const Segment & seg = mesh.GetOpenSegment (i);
304
geom.AddMarkedSeg(mesh.Point(seg.p1),mesh.Point(seg.p2));
305
}
306
307
geom.InitMarkedTrigs();
308
for (i = 1; i <= nopen; i++)
309
{
310
const Segment & seg = mesh.GetOpenSegment (i);
311
geom.SetMarkedTrig(seg.geominfo[0].trignum,1);
312
geom.SetMarkedTrig(seg.geominfo[1].trignum,1);
313
}
314
315
MeshOptimizeSTLSurface optmesh(geom);
316
optmesh.SetFaceIndex (0);
317
optmesh.SetImproveEdges (0);
318
optmesh.SetMetricWeight (0);
319
320
mesh.CalcSurfacesOfNode();
321
optmesh.EdgeSwapping (mesh, 0);
322
mesh.CalcSurfacesOfNode();
323
optmesh.ImproveMesh (mesh);
324
}
325
326
mesh.Compress();
327
mesh.FindOpenSegments();
328
nopen = mesh.GetNOpenSegments();
329
330
if (trialcnt <= 5 && nopen)
331
{
332
mesh.RemoveOneLayerSurfaceElements();
333
334
if (trialcnt >= 4)
335
{
336
mesh.FindOpenSegments();
337
mesh.RemoveOneLayerSurfaceElements();
338
339
mesh.FindOpenSegments ();
340
nopen = mesh.GetNOpenSegments();
341
}
342
}
343
}
344
345
346
if (multithread.terminate)
347
return MESHING3_TERMINATE;
348
349
if (nopen)
350
{
351
352
PrintMessage(3,"Meshing failed, trying to refine");
353
354
mesh.FindOpenSegments ();
355
nopen = mesh.GetNOpenSegments();
356
357
mesh.FindOpenSegments ();
358
mesh.RemoveOneLayerSurfaceElements();
359
mesh.FindOpenSegments ();
360
mesh.RemoveOneLayerSurfaceElements();
361
362
// Open edge-segments will be refined !
363
INDEX_2_HASHTABLE<int> openseght (nopen+1);
364
for (i = 1; i <= mesh.GetNOpenSegments(); i++)
365
{
366
const Segment & seg = mesh.GetOpenSegment (i);
367
INDEX_2 i2(seg.p1, seg.p2);
368
i2.Sort();
369
openseght.Set (i2, 1);
370
}
371
372
373
mesh.FindOpenSegments ();
374
mesh.RemoveOneLayerSurfaceElements();
375
mesh.FindOpenSegments ();
376
mesh.RemoveOneLayerSurfaceElements();
377
378
379
INDEX_2_HASHTABLE<int> newpht(100);
380
381
int nsegold = mesh.GetNSeg();
382
for (i = 1; i <= nsegold; i++)
383
{
384
Segment seg = mesh.LineSegment(i);
385
INDEX_2 i2(seg.p1, seg.p2);
386
i2.Sort();
387
if (openseght.Used (i2))
388
{
389
// segment will be split
390
PrintMessage(7,"Split segment ", int(seg.p1), "-", int(seg.p2));
391
392
Segment nseg1, nseg2;
393
EdgePointGeomInfo newgi;
394
395
const EdgePointGeomInfo & gi1 = seg.epgeominfo[0];
396
const EdgePointGeomInfo & gi2 = seg.epgeominfo[1];
397
398
newgi.dist = 0.5 * (gi1.dist + gi2.dist);
399
newgi.edgenr = gi1.edgenr;
400
401
int hi;
402
403
Point3d newp;
404
int newpi;
405
406
if (!newpht.Used (i2))
407
{
408
newp = geom.GetLine (gi1.edgenr)->
409
GetPointInDist (geom.GetPoints(), newgi.dist, hi);
410
newpi = mesh.AddPoint (newp);
411
newpht.Set (i2, newpi);
412
}
413
else
414
{
415
newpi = newpht.Get (i2);
416
newp = mesh.Point (newpi);
417
}
418
419
nseg1 = seg;
420
nseg2 = seg;
421
nseg1.p2 = newpi;
422
nseg1.epgeominfo[1] = newgi;
423
424
nseg2.p1 = newpi;
425
nseg2.epgeominfo[0] = newgi;
426
427
mesh.LineSegment(i) = nseg1;
428
mesh.AddSegment (nseg2);
429
430
mesh.RestrictLocalH (Center (mesh.Point(nseg1.p1),
431
mesh.Point(nseg1.p2)),
432
Dist (mesh.Point(nseg1.p1),
433
mesh.Point(nseg1.p2)));
434
mesh.RestrictLocalH (Center (mesh.Point(nseg2.p1),
435
mesh.Point(nseg2.p2)),
436
Dist (mesh.Point(nseg2.p1),
437
mesh.Point(nseg2.p2)));
438
}
439
}
440
441
}
442
443
nopen = -1;
444
}
445
446
else
447
448
{
449
PrintMessage(5,"mesh is closed, verifying ...");
450
451
// no open elements, check wrong elemetns (intersecting..)
452
453
454
455
PrintMessage(5,"check overlapping");
456
// mesh.FindOpenElements(); // would leed to locked points
457
if(mesh.CheckOverlappingBoundary())
458
{
459
return MESHING3_BADSURFACEMESH;
460
}
461
462
463
geom.InitMarkedTrigs();
464
465
for (i = 1; i <= mesh.GetNSE(); i++)
466
if (mesh.SurfaceElement(i).BadElement())
467
{
468
int trig = mesh.SurfaceElement(i).PNum(1);
469
geom.SetMarkedTrig(trig,1);
470
PrintMessage(7, "overlapping element, will be removed");
471
}
472
473
474
475
ARRAY<Point3d> refpts;
476
ARRAY<double> refh;
477
478
// was commented:
479
480
for (i = 1; i <= mesh.GetNSE(); i++)
481
if (mesh.SurfaceElement(i).BadElement())
482
{
483
for (j = 1; j <= 3; j++)
484
{
485
refpts.Append (mesh.Point (mesh.SurfaceElement(i).PNum(j)));
486
refh.Append (mesh.GetH (refpts.Last()) / 2);
487
}
488
mesh.DeleteSurfaceElement(i);
489
}
490
491
// delete wrong oriented element
492
for (i = 1; i <= mesh.GetNSE(); i++)
493
{
494
const Element2d & el = mesh.SurfaceElement(i);
495
if (!el.PNum(1))
496
continue;
497
498
Vec3d n = Cross (Vec3d (mesh.Point(el.PNum(1)),
499
mesh.Point(el.PNum(2))),
500
Vec3d (mesh.Point(el.PNum(1)),
501
mesh.Point(el.PNum(3))));
502
Vec3d ng = geom.GetTriangle(el.GeomInfoPi(1).trignum).Normal();
503
if (n * ng < 0)
504
{
505
refpts.Append (mesh.Point (mesh.SurfaceElement(i).PNum(1)));
506
refh.Append (mesh.GetH (refpts.Last()) / 2);
507
mesh.DeleteSurfaceElement(i);
508
}
509
}
510
// end comments
511
512
for (i = 1; i <= refpts.Size(); i++)
513
mesh.RestrictLocalH (refpts.Get(i), refh.Get(i));
514
515
mesh.RemoveOneLayerSurfaceElements();
516
517
mesh.Compress();
518
519
mesh.FindOpenSegments ();
520
nopen = mesh.GetNOpenSegments();
521
522
/*
523
if (!nopen)
524
{
525
// mesh is still ok
526
527
void STLSurfaceOptimization (STLGeometry & geom,
528
class Mesh & mesh,
529
MeshingParameters & mparam)
530
531
}
532
*/
533
}
534
535
}
536
while (nopen);
537
538
mesh.Compress();
539
mesh.CalcSurfacesOfNode();
540
541
return MESHING3_OK;
542
}
543
544
545
546
547
548
549
void STLSurfaceMeshing1 (STLGeometry & geom,
550
class Mesh & mesh,
551
int retrynr)
552
{
553
int i, j;
554
double h;
555
556
557
h = mparam.maxh;
558
559
mesh.FindOpenSegments();
560
561
ARRAY<int> spiralps(0);
562
spiralps.SetSize(0);
563
for (i = 1; i <= geom.GetNP(); i++)
564
{
565
if (geom.GetSpiralPoint(i)) {spiralps.Append(i);}
566
}
567
568
PrintMessage(7,"NO spiralpoints = ", spiralps.Size());
569
//int spfound;
570
int sppointnum;
571
int spcnt = 0;
572
573
ARRAY<int> meshsp(mesh.GetNP());
574
for (i = 1; i <= mesh.GetNP(); i++)
575
{
576
meshsp.Elem(i) = 0;
577
for (j = 1; j <= spiralps.Size(); j++)
578
if (Dist2(geom.GetPoint(spiralps.Get(j)), mesh.Point(i)) < 1e-20)
579
meshsp.Elem(i) = spiralps.Get(j);
580
}
581
582
583
ARRAY<int> opensegsperface(mesh.GetNFD());
584
for (i = 1; i <= mesh.GetNFD(); i++)
585
opensegsperface.Elem(i) = 0;
586
for (i = 1; i <= mesh.GetNOpenSegments(); i++)
587
{
588
int si = mesh.GetOpenSegment (i).si;
589
if (si >= 1 && si <= mesh.GetNFD())
590
{
591
opensegsperface.Elem(si)++;
592
}
593
else
594
{
595
cerr << "illegal face index" << endl;
596
}
597
}
598
599
600
double starttime = GetTime ();
601
602
for (int fnr = 1; fnr <= mesh.GetNFD(); fnr++)
603
if (opensegsperface.Get(fnr))
604
{
605
if (multithread.terminate)
606
return;
607
608
PrintMessage(5,"Meshing surface ", fnr, "/", mesh.GetNFD());
609
MeshingSTLSurface meshing (geom);
610
611
meshing.SetStartTime (starttime);
612
613
for (i = 1; i <= mesh.GetNP(); i++)
614
{
615
/*
616
spfound = 0;
617
for (j = 1; j <= spiralps.Size(); j++)
618
{
619
if (Dist2(geom.GetPoint(spiralps.Get(j)),mesh.Point(i)) < 1e-20)
620
{spfound = 1; sppointnum = spiralps.Get(j);}
621
}
622
*/
623
sppointnum = 0;
624
if (i <= meshsp.Size())
625
sppointnum = meshsp.Get(i);
626
627
//spfound = 0;
628
if (sppointnum)
629
{
630
MultiPointGeomInfo mgi;
631
632
int ntrigs = geom.NOTrigsPerPoint(sppointnum);
633
spcnt++;
634
635
for (j = 0; j < ntrigs; j++)
636
{
637
PointGeomInfo gi;
638
gi.trignum = geom.TrigPerPoint(sppointnum, j+1);
639
mgi.AddPointGeomInfo (gi);
640
}
641
642
// Einfuegen von ConePoint: Point bekommt alle
643
// Dreiecke (werden dann intern kopiert)
644
// Ein Segment zum ConePoint muss vorhanden sein !!!
645
646
meshing.AddPoint (mesh.Point(i), i, &mgi);
647
648
}
649
else
650
{
651
meshing.AddPoint (mesh.Point(i), i);
652
}
653
}
654
655
656
for (i = 1; i <= mesh.GetNOpenSegments(); i++)
657
{
658
const Segment & seg = mesh.GetOpenSegment (i);
659
if (seg.si == fnr)
660
meshing.AddBoundaryElement (seg.p1, seg.p2, seg.geominfo[0], seg.geominfo[1]);
661
}
662
663
664
PrintMessage(3,"start meshing, trialcnt = ", retrynr);
665
666
/*
667
(*testout) << "start meshing with h = " << h << endl;
668
*/
669
meshing.GenerateMesh (mesh, h, fnr); // face index
670
#ifdef OPENGL
671
extern void Render();
672
Render();
673
#endif
674
}
675
676
677
mesh.CalcSurfacesOfNode();
678
}
679
680
681
682
void STLSurfaceOptimization (STLGeometry & geom,
683
class Mesh & mesh,
684
MeshingParameters & meshparam)
685
{
686
PrintFnStart("optimize STL Surface");
687
688
689
MeshOptimizeSTLSurface optmesh(geom);
690
//
691
692
int i;
693
/*
694
for (i = 1; i <= mparam.optsteps2d; i++)
695
{
696
EdgeSwapping (mesh, 1, 1);
697
CombineImprove (mesh, 1);
698
optmesh.ImproveMesh (mesh, 0, 10, 1, 1);
699
}
700
*/
701
702
optmesh.SetFaceIndex (0);
703
optmesh.SetImproveEdges (0);
704
optmesh.SetMetricWeight (meshparam.elsizeweight);
705
706
PrintMessage(5,"optimize string = ", meshparam.optimize2d, " elsizew = ", meshparam.elsizeweight);
707
708
for (i = 1; i <= meshparam.optsteps2d; i++)
709
for (size_t j = 1; j <= strlen(meshparam.optimize2d); j++)
710
{
711
if (multithread.terminate)
712
break;
713
714
//(*testout) << "optimize, before, step = " << meshparam.optimize2d[j-1] << mesh.Point (3679) << endl;
715
716
mesh.CalcSurfacesOfNode();
717
switch (meshparam.optimize2d[j-1])
718
{
719
case 's':
720
{
721
optmesh.EdgeSwapping (mesh, 0);
722
break;
723
}
724
case 'S':
725
{
726
optmesh.EdgeSwapping (mesh, 1);
727
break;
728
}
729
case 'm':
730
{
731
optmesh.ImproveMesh(mesh);
732
break;
733
}
734
case 'c':
735
{
736
optmesh.CombineImprove (mesh);
737
break;
738
}
739
}
740
//(*testout) << "optimize, after, step = " << meshparam.optimize2d[j-1] << mesh.Point (3679) << endl;
741
}
742
743
geom.surfaceoptimized = 1;
744
745
mesh.Compress();
746
mesh.CalcSurfacesOfNode();
747
748
749
}
750
751
752
753
MeshingSTLSurface :: MeshingSTLSurface (STLGeometry & ageom)
754
: Meshing2(ageom.GetBoundingBox()), geom(ageom)
755
{
756
;
757
}
758
759
void MeshingSTLSurface :: DefineTransformation (const Point3d & p1, const Point3d & p2,
760
const PointGeomInfo * geominfo,
761
const PointGeomInfo * geominfo2)
762
{
763
transformationtrig = geominfo[0].trignum;
764
765
geom.DefineTangentialPlane(p1, p2, transformationtrig);
766
}
767
768
void MeshingSTLSurface :: TransformToPlain (const Point3d & locpoint, const MultiPointGeomInfo & gi,
769
Point2d & plainpoint, double h, int & zone)
770
{
771
int trigs[10000];
772
int i;
773
774
if (gi.GetNPGI() >= 9999)
775
{
776
PrintError("In Transform to plane: increase size of trigs!!!");
777
}
778
779
for (i = 1; i <= gi.GetNPGI(); i++)
780
trigs[i-1] = gi.GetPGI(i).trignum;
781
trigs[gi.GetNPGI()] = 0;
782
783
// int trig = gi.trignum;
784
// (*testout) << "locpoint = " << locpoint;
785
786
Point<2> hp2d;
787
geom.ToPlane (locpoint, trigs, hp2d, h, zone, 1);
788
plainpoint = hp2d;
789
790
// geom.ToPlane (locpoint, NULL, plainpoint, h, zone, 1);
791
/*
792
(*testout) << " plainpoint = " << plainpoint
793
<< " h = " << h
794
<< endl;
795
*/
796
}
797
798
/*
799
int MeshingSTLSurface :: ComputeLineGeoInfo (const Point3d & p1, const Point3d & p2,
800
int & geoinfosize, void *& geoinfo)
801
{
802
static int geomtrig[2] = { 0, 0 };
803
804
Point3d hp;
805
hp = p1;
806
geomtrig[0] = geom.Project (hp);
807
808
hp = p2;
809
geomtrig[1] = geom.Project (hp);
810
811
geoinfosize = sizeof (geomtrig);
812
geoinfo = &geomtrig;
813
814
if (geomtrig[0] == 0)
815
{
816
return 1;
817
}
818
return 0;
819
}
820
*/
821
822
823
int MeshingSTLSurface :: ComputePointGeomInfo (const Point3d & p, PointGeomInfo & gi)
824
{
825
// compute triangle of point,
826
// if non-unique: 0
827
828
Point<3> hp = p;
829
gi.trignum = geom.Project (hp);
830
831
if (!gi.trignum)
832
{
833
return 1;
834
}
835
836
return 0;
837
}
838
839
840
int MeshingSTLSurface ::
841
ChooseChartPointGeomInfo (const MultiPointGeomInfo & mpgi,
842
PointGeomInfo & pgi)
843
{
844
int i;
845
846
for (i = 1; i <= mpgi.GetNPGI(); i++)
847
if (geom.TrigIsInOC (mpgi.GetPGI(i).trignum, geom.meshchart))
848
{
849
pgi = mpgi.GetPGI(i);
850
return 0;
851
}
852
/*
853
for (i = 0; i < mpgi.cnt; i++)
854
{
855
// (*testout) << "d" << endl;
856
if (geom.TrigIsInOC (mpgi.mgi[i].trignum, geom.meshchart))
857
{
858
pgi = mpgi.mgi[i];
859
return 0;
860
}
861
}
862
*/
863
PrintMessage(7,"INFORM: no gi on chart");
864
pgi.trignum = 1;
865
return 1;
866
}
867
868
869
870
int MeshingSTLSurface ::
871
IsLineVertexOnChart (const Point3d & p1, const Point3d & p2,
872
int endpoint, const PointGeomInfo & gi)
873
{
874
Vec3d baselinenormal = geom.meshtrignv;
875
876
int lineendtrig = gi.trignum;
877
878
879
return geom.TrigIsInOC (lineendtrig, geom.meshchart);
880
881
// Vec3d linenormal = geom.GetTriangleNormal (lineendtrig);
882
// return ( (baselinenormal * linenormal) > cos (30 * (M_PI/180)) );
883
}
884
885
void MeshingSTLSurface ::
886
GetChartBoundary (ARRAY<Point2d > & points,
887
ARRAY<Point3d > & points3d,
888
ARRAY<INDEX_2> & lines, double h) const
889
{
890
points.SetSize (0);
891
points3d.SetSize (0);
892
lines.SetSize (0);
893
geom.GetMeshChartBoundary (points, points3d, lines, h);
894
}
895
896
897
898
899
int MeshingSTLSurface :: TransformFromPlain (Point2d & plainpoint,
900
Point3d & locpoint,
901
PointGeomInfo & gi,
902
double h)
903
{
904
//return 0, wenn alles OK
905
Point<3> hp3d;
906
int res = geom.FromPlane (plainpoint, hp3d, h);
907
locpoint = hp3d;
908
ComputePointGeomInfo (locpoint, gi);
909
return res;
910
}
911
912
913
int MeshingSTLSurface ::
914
BelongsToActiveChart (const Point3d & p,
915
const PointGeomInfo & gi)
916
{
917
return (geom.TrigIsInOC(gi.trignum, geom.meshchart) != 0);
918
}
919
920
921
922
double MeshingSTLSurface :: CalcLocalH (const Point3d & p, double gh) const
923
{
924
return gh;
925
}
926
927
double MeshingSTLSurface :: Area () const
928
{
929
return geom.Area();
930
}
931
932
933
934
935
936
937
MeshOptimizeSTLSurface :: MeshOptimizeSTLSurface (STLGeometry & ageom)
938
: MeshOptimize2d(), geom(ageom)
939
{
940
;
941
}
942
943
944
void MeshOptimizeSTLSurface :: SelectSurfaceOfPoint (const Point<3> & p,
945
const PointGeomInfo & gi)
946
{
947
// (*testout) << "sel char: " << gi.trignum << endl;
948
949
geom.SelectChartOfTriangle (gi.trignum);
950
// geom.SelectChartOfPoint (p);
951
}
952
953
954
void MeshOptimizeSTLSurface :: ProjectPoint (INDEX surfind, Point<3> & p) const
955
{
956
if (!geom.Project (p))
957
{
958
PrintMessage(7,"project failed");
959
960
if (!geom.ProjectOnWholeSurface(p))
961
{
962
PrintMessage(7, "project on whole surface failed");
963
}
964
}
965
966
// geometry.GetSurface(surfind)->Project (p);
967
}
968
969
void MeshOptimizeSTLSurface :: ProjectPoint2 (INDEX surfind, INDEX surfind2, Point<3> & p) const
970
{
971
/*
972
ProjectToEdge ( geometry.GetSurface(surfind),
973
geometry.GetSurface(surfind2), p);
974
*/
975
}
976
977
int MeshOptimizeSTLSurface :: CalcPointGeomInfo(PointGeomInfo& gi, const Point<3> & p3) const
978
{
979
Point<3> hp = p3;
980
gi.trignum = geom.Project (hp);
981
982
if (gi.trignum)
983
{
984
return 1;
985
}
986
987
return 0;
988
989
}
990
991
void MeshOptimizeSTLSurface :: GetNormalVector(INDEX surfind, const Point<3> & p, Vec<3> & n) const
992
{
993
n = geom.GetChartNormalVector();
994
995
/*
996
geometry.GetSurface(surfind)->CalcGradient (p, n);
997
n /= n.Length();
998
if (geometry.GetSurface(surfind)->Inverse())
999
n *= -1;
1000
*/
1001
}
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
RefinementSTLGeometry :: RefinementSTLGeometry (const STLGeometry & ageom)
1013
: Refinement(), geom(ageom)
1014
{
1015
;
1016
}
1017
1018
RefinementSTLGeometry :: ~RefinementSTLGeometry ()
1019
{
1020
;
1021
}
1022
1023
void RefinementSTLGeometry ::
1024
PointBetween (const Point<3> & p1, const Point<3> & p2, double secpoint,
1025
int surfi,
1026
const PointGeomInfo & gi1,
1027
const PointGeomInfo & gi2,
1028
Point<3> & newp, PointGeomInfo & newgi)
1029
{
1030
newp = p1+secpoint*(p2-p1);
1031
1032
/*
1033
(*testout) << "surf-between: p1 = " << p1 << ", p2 = " << p2
1034
<< ", gi = " << gi1 << " - " << gi2 << endl;
1035
*/
1036
1037
if (gi1.trignum > 0)
1038
{
1039
// ((STLGeometry&)geom).SelectChartOfTriangle (gi1.trignum);
1040
1041
Point<3> np1 = newp;
1042
Point<3> np2 = newp;
1043
((STLGeometry&)geom).SelectChartOfTriangle (gi1.trignum);
1044
int tn1 = geom.Project (np1);
1045
1046
((STLGeometry&)geom).SelectChartOfTriangle (gi2.trignum);
1047
int tn2 = geom.Project (np2);
1048
1049
newgi.trignum = tn1; //urspruengliche version
1050
newp = np1; //urspruengliche version
1051
1052
if (!newgi.trignum)
1053
{ newgi.trignum = tn2; newp = np2; }
1054
if (!newgi.trignum) newgi.trignum = gi1.trignum;
1055
1056
/*
1057
if (tn1 != 0 && tn2 != 0 && ((STLGeometry&)geom).GetAngle(tn1,tn2) < M_PI*0.05) {
1058
newgi.trignum = tn1;
1059
newp = np1;
1060
}
1061
else
1062
{
1063
newp = ((STLGeometry&)geom).PointBetween(p1, gi1.trignum, p2, gi2.trignum);
1064
tn1 = ((STLGeometry&)geom).Project(newp);
1065
newgi.trignum = tn1;
1066
1067
if (!tn1)
1068
{
1069
newp = Center (p1, p2);
1070
newgi.trignum = 0;
1071
1072
}
1073
}
1074
*/
1075
}
1076
else
1077
{
1078
// (*testout) << "WARNING: PointBetween got geominfo = 0" << endl;
1079
newp = p1+secpoint*(p2-p1);
1080
newgi.trignum = 0;
1081
}
1082
1083
// (*testout) << "newp = " << newp << ", ngi = " << newgi << endl;
1084
}
1085
1086
void RefinementSTLGeometry ::
1087
PointBetween (const Point<3> & p1, const Point<3> & p2, double secpoint,
1088
int surfi1, int surfi2,
1089
const EdgePointGeomInfo & gi1,
1090
const EdgePointGeomInfo & gi2,
1091
Point<3> & newp, EdgePointGeomInfo & newgi)
1092
{
1093
/*
1094
(*testout) << "edge-between: p1 = " << p1 << ", p2 = " << p2
1095
<< ", gi1,2 = " << gi1 << ", " << gi2 << endl;
1096
*/
1097
/*
1098
newp = Center (p1, p2);
1099
((STLGeometry&)geom).SelectChartOfTriangle (gi1.trignum);
1100
newgi.trignum = geom.Project (newp);
1101
*/
1102
int hi;
1103
newgi.dist = (1.0-secpoint) * gi1.dist + secpoint*gi2.dist;
1104
newgi.edgenr = gi1.edgenr;
1105
1106
/*
1107
(*testout) << "p1 = " << p1 << ", p2 = " << p2 << endl;
1108
(*testout) << "refedge: " << gi1.edgenr
1109
<< " d1 = " << gi1.dist << ", d2 = " << gi2.dist << endl;
1110
*/
1111
newp = geom.GetLine (gi1.edgenr)->GetPointInDist (geom.GetPoints(), newgi.dist, hi);
1112
1113
// (*testout) << "newp = " << newp << endl;
1114
}
1115
1116
1117
void RefinementSTLGeometry :: ProjectToSurface (Point<3> & p, int surfi)
1118
{
1119
cout << "RefinementSTLGeometry :: ProjectToSurface not implemented!" << endl;
1120
};
1121
1122
1123
void RefinementSTLGeometry :: ProjectToSurface (Point<3> & p, int surfi,
1124
PointGeomInfo & gi)
1125
{
1126
((STLGeometry&)geom).SelectChartOfTriangle (gi.trignum);
1127
gi.trignum = geom.Project (p);
1128
// if (!gi.trignum)
1129
// cout << "projectSTL failed" << endl;
1130
};
1131
1132
1133
}
1134
1135