Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
ElmerCSC
GitHub Repository: ElmerCSC/elmerfem
Path: blob/devel/ElmerGUI/netgen/libsrc/stlgeom/stlline.cpp
3206 views
1
#include <mystdlib.h>
2
3
#include <myadt.hpp>
4
#include <linalg.hpp>
5
#include <gprim.hpp>
6
7
#include <meshing.hpp>
8
9
#include "stlgeom.hpp"
10
11
namespace netgen
12
{
13
14
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
15
//++++++++++++++ EDGE DATA ++++++++++++++++++++++++++++++++++++++++++
16
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
17
18
19
/*
20
void STLEdgeData :: Write(ofstream& of) const
21
{
22
of // << angle << " "
23
<< p1 << " "
24
<< p2 << " "
25
<< lt << " "
26
<< rt << " "
27
// << status
28
<< endl;
29
}
30
31
void STLEdgeData :: Read(ifstream& ifs)
32
{
33
// ifs >> angle;
34
ifs >> p1;
35
ifs >> p2;
36
ifs >> lt;
37
ifs >> rt;
38
// ifs >> status;
39
}
40
41
42
int STLEdgeData :: GetStatus () const
43
{
44
if (topedgenr <= 0 || topedgenr > top->GetNTE()) return 0;
45
return top->GetTopEdge (topedgenr).GetStatus();
46
}
47
48
void STLEdgeData ::SetStatus (int stat)
49
{
50
if (topedgenr >= 1 && topedgenr <= top->GetNTE())
51
top->GetTopEdge (topedgenr).SetStatus(stat);
52
}
53
54
55
float STLEdgeData :: CosAngle() const
56
{
57
return top->GetTopEdge (topedgenr).CosAngle();
58
}
59
60
61
62
void STLEdgeDataList :: ResetAll()
63
{
64
int i;
65
for (i = 1; i <= edgedata.Size(); i++)
66
{
67
edgedata.Elem(i).SetUndefined();
68
}
69
}
70
71
void STLEdgeDataList :: ResetCandidates()
72
{
73
int i;
74
for (i = 1; i <= edgedata.Size(); i++)
75
{
76
if (edgedata.Get(i).Candidate())
77
{edgedata.Elem(i).SetUndefined();}
78
}
79
}
80
81
int STLEdgeDataList :: GetNConfEdges() const
82
{
83
int i;
84
int cnt = 0;
85
for (i = 1; i <= edgedata.Size(); i++)
86
{
87
if (edgedata.Get(i).Confirmed()) {cnt++;}
88
}
89
return cnt;
90
}
91
92
void STLEdgeDataList :: ConfirmCandidates()
93
{
94
int i;
95
for (i = 1; i <= edgedata.Size(); i++)
96
{
97
if (edgedata.Get(i).Candidate())
98
{edgedata.Elem(i).SetConfirmed();}
99
}
100
}
101
102
int STLEdgeDataList :: GetEdgeNum(int np1, int np2) const
103
{
104
INDEX_2 ed(np1,np2);
105
ed.Sort();
106
if (hashtab.Used(ed))
107
{
108
return hashtab.Get(ed);
109
}
110
111
// int i;
112
// for (i = 1; i <= Size(); i++)
113
// {
114
// if ((Get(i).p1 == np1 && Get(i).p2 == np2) ||
115
// (Get(i).p2 == np1 && Get(i).p1 == np2))
116
// {
117
// return i;
118
// }
119
// }
120
121
return 0;
122
}
123
124
const STLEdgeDataList& STLEdgeDataList :: operator=(const STLEdgeDataList& edl)
125
{
126
int i;
127
SetSize(edl.Size());
128
for (i = 1; i <= Size(); i++)
129
{
130
Add(edl.Get(i), i);
131
}
132
return *this;
133
}
134
135
void STLEdgeDataList :: Add(const STLEdgeData& ed, int i)
136
{
137
INDEX_2 edge(ed.p1,ed.p2);
138
edge.Sort();
139
hashtab.Set(edge, i);
140
Elem(i) = ed;
141
AddEdgePP(ed.p1,i);
142
AddEdgePP(ed.p2,i);
143
}
144
145
void STLEdgeDataList :: Write(ofstream& of) const
146
{
147
of.precision(16);
148
int i;
149
of << Size() << endl;
150
151
for (i = 1; i <= Size(); i++)
152
{
153
Get(i).Write(of);
154
}
155
}
156
157
void STLEdgeDataList :: Read(ifstream& ifs)
158
{
159
int i,n;
160
ifs >> n;
161
162
SetSize(n);
163
STLEdgeData ed;
164
for (i = 1; i <= n; i++)
165
{
166
ed.Read(ifs);
167
Add(ed,i);
168
}
169
}
170
171
int STLEdgeDataList :: GetNEPPStat(int p, int status) const
172
{
173
int i;
174
int cnt = 0;
175
for (i = 1; i <= GetNEPP(p); i++)
176
{
177
if (Get(GetEdgePP(p,i)).GetStatus() == status)
178
{
179
cnt++;
180
}
181
}
182
return cnt;
183
}
184
185
int STLEdgeDataList :: GetNConfCandEPP(int p) const
186
{
187
int i;
188
int cnt = 0;
189
for (i = 1; i <= GetNEPP(p); i++)
190
{
191
if (Get(GetEdgePP(p,i)).ConfCand())
192
{
193
cnt++;
194
}
195
}
196
return cnt;
197
}
198
199
200
void STLEdgeDataList :: BuildLineWithEdge(int ep1, int ep2, ARRAY<twoint>& line)
201
{
202
int status = Get(GetEdgeNum(ep1,ep2)).GetStatus();
203
204
int found, pstart, p, en, pnew, ennew;
205
int closed = 0;
206
int j, i;
207
for (j = 1; j <= 2; j++)
208
{
209
if (j == 1) {p = ep1;}
210
if (j == 2) {p = ep2;}
211
212
pstart = p;
213
en = GetEdgeNum(ep1,ep2);
214
215
found = 1;
216
while (found && !closed)
217
{
218
found = 0;
219
220
if (GetNEPPStat(p,status) == 2)
221
{
222
for (i = 1; i <= GetNEPP(p); i++)
223
{
224
const STLEdgeData& e = Get(GetEdgePP(p,i));
225
if (GetEdgePP(p,i) != en && e.GetStatus() == status)
226
{
227
if (e.p1 == p)
228
{pnew = e.p2;}
229
else
230
{pnew = e.p1;}
231
232
ennew = GetEdgePP(p,i);
233
}
234
}
235
if (pnew == pstart) {closed = 1;}
236
else
237
{
238
line.Append(twoint(p,pnew));
239
p = pnew;
240
en = ennew;
241
found = 1;
242
}
243
}
244
}
245
}
246
247
}
248
*/
249
250
251
252
253
STLEdgeDataList :: STLEdgeDataList (STLTopology & ageom)
254
: geom(ageom)
255
{
256
;
257
}
258
259
STLEdgeDataList :: ~STLEdgeDataList()
260
{
261
;
262
}
263
264
265
void STLEdgeDataList :: Store ()
266
{
267
int i, ne = geom.GetNTE();
268
storedstatus.SetSize(ne);
269
for (i = 1; i <= ne; i++)
270
{
271
storedstatus.Elem(i) = Get(i).GetStatus();
272
}
273
}
274
275
void STLEdgeDataList :: Restore ()
276
{
277
int i, ne = geom.GetNTE();
278
if (storedstatus.Size() == ne)
279
for (i = 1; i <= ne; i++)
280
geom.GetTopEdge(i).SetStatus (storedstatus.Elem(i));
281
}
282
283
284
void STLEdgeDataList :: ResetAll()
285
{
286
int i, ne = geom.GetNTE();
287
for (i = 1; i <= ne; i++)
288
geom.GetTopEdge (i).SetStatus (ED_UNDEFINED);
289
}
290
291
int STLEdgeDataList :: GetNConfEdges() const
292
{
293
int i, ne = geom.GetNTE();
294
int cnt = 0;
295
for (i = 1; i <= ne; i++)
296
if (geom.GetTopEdge (i).GetStatus() == ED_CONFIRMED)
297
cnt++;
298
return cnt;
299
}
300
301
void STLEdgeDataList :: ChangeStatus(int status1, int status2)
302
{
303
int i, ne = geom.GetNTE();
304
for (i = 1; i <= ne; i++)
305
if (geom.GetTopEdge (i).GetStatus() == status1)
306
geom.GetTopEdge (i).SetStatus (status2);
307
}
308
309
/*
310
void STLEdgeDataList :: Add(const STLEdgeData& ed, int i)
311
{
312
INDEX_2 edge(ed.p1,ed.p2);
313
edge.Sort();
314
hashtab.Set(edge, i);
315
Elem(i) = ed;
316
AddEdgePP(ed.p1,i);
317
AddEdgePP(ed.p2,i);
318
}
319
*/
320
321
void STLEdgeDataList :: Write(ofstream& of) const
322
{
323
324
/*
325
of.precision(16);
326
int i;
327
of << Size() << endl;
328
329
for (i = 1; i <= Size(); i++)
330
{
331
Get(i).Write(of);
332
}
333
334
*/
335
of.precision(16);
336
int i, ne = geom.GetNTE();
337
//of << GetNConfEdges() << endl;
338
of << geom.GetNTE() << endl;
339
340
for (i = 1; i <= ne; i++)
341
{
342
const STLTopEdge & edge = geom.GetTopEdge(i);
343
//if (edge.GetStatus() == ED_CONFIRMED)
344
of << edge.GetStatus() << " ";
345
346
const Point3d & p1 = geom.GetPoint (edge.PNum(1));
347
const Point3d & p2 = geom.GetPoint (edge.PNum(2));
348
of << p1.X() << " "
349
<< p1.Y() << " "
350
<< p1.Z() << " "
351
<< p2.X() << " "
352
<< p2.Y() << " "
353
<< p2.Z() << endl;
354
}
355
356
}
357
358
void STLEdgeDataList :: Read(ifstream& ifs)
359
{
360
int i, nce;
361
Point3d p1, p2;
362
int pi1, pi2;
363
int status, ednum;
364
365
ifs >> nce;
366
for (i = 1; i <= nce; i++)
367
{
368
ifs >> status;
369
ifs >> p1.X() >> p1.Y() >> p1.Z();
370
ifs >> p2.X() >> p2.Y() >> p2.Z();
371
372
pi1 = geom.GetPointNum (p1);
373
pi2 = geom.GetPointNum (p2);
374
ednum = geom.GetTopEdgeNum (pi1, pi2);
375
376
377
if (ednum)
378
{
379
geom.GetTopEdge(ednum).SetStatus (status);
380
// geom.GetTopEdge (ednum).SetStatus (ED_CONFIRMED);
381
}
382
}
383
/*
384
int i,n;
385
ifs >> n;
386
387
SetSize(n);
388
STLEdgeData ed;
389
for (i = 1; i <= n; i++)
390
{
391
ed.Read(ifs);
392
Add(ed,i);
393
}
394
*/
395
}
396
397
int STLEdgeDataList :: GetNEPPStat(int p, int status) const
398
{
399
int i;
400
int cnt = 0;
401
for (i = 1; i <= GetNEPP(p); i++)
402
{
403
if (Get(GetEdgePP(p,i)).GetStatus() == status)
404
{
405
cnt++;
406
}
407
}
408
return cnt;
409
}
410
411
int STLEdgeDataList :: GetNConfCandEPP(int p) const
412
{
413
int i;
414
int cnt = 0;
415
for (i = 1; i <= GetNEPP(p); i++)
416
{
417
if (Get(GetEdgePP(p,i)).GetStatus() == ED_CANDIDATE ||
418
Get(GetEdgePP(p,i)).GetStatus() == ED_CONFIRMED)
419
{
420
cnt++;
421
}
422
}
423
return cnt;
424
}
425
426
427
void STLEdgeDataList :: BuildLineWithEdge(int ep1, int ep2, ARRAY<twoint>& line)
428
{
429
int status = Get(GetEdgeNum(ep1,ep2)).GetStatus();
430
431
int found, pstart, p(0), en, pnew(0), ennew(0);
432
int closed = 0;
433
int j, i;
434
for (j = 1; j <= 2; j++)
435
{
436
if (j == 1) {p = ep1;}
437
if (j == 2) {p = ep2;}
438
439
pstart = p;
440
en = GetEdgeNum(ep1,ep2);
441
442
found = 1;
443
while (found && !closed)
444
{
445
found = 0;
446
447
if (GetNEPPStat(p,status) == 2)
448
{
449
for (i = 1; i <= GetNEPP(p); i++)
450
{
451
const STLTopEdge & e = Get(GetEdgePP(p,i));
452
if (GetEdgePP(p,i) != en && e.GetStatus() == status)
453
{
454
if (e.PNum(1) == p)
455
{pnew = e.PNum(2);}
456
else
457
{pnew = e.PNum(1);}
458
459
ennew = GetEdgePP(p,i);
460
}
461
}
462
if (pnew == pstart) {closed = 1;}
463
else
464
{
465
line.Append(twoint(p,pnew));
466
p = pnew;
467
en = ennew;
468
found = 1;
469
}
470
}
471
}
472
}
473
474
}
475
476
int Exists(int p1, int p2, const ARRAY<twoint>& line)
477
{
478
int i;
479
for (i = 1; i <= line.Size(); i++)
480
{
481
if (line.Get(i).i1 == p1 && line.Get(i).i2 == p2 ||
482
line.Get(i).i1 == p2 && line.Get(i).i2 == p1) {return 1;}
483
}
484
return 0;
485
}
486
487
void STLEdgeDataList :: BuildClusterWithEdge(int ep1, int ep2, ARRAY<twoint>& line)
488
{
489
int status = Get(GetEdgeNum(ep1,ep2)).GetStatus();
490
491
int p(0), en;
492
int j, i, k;
493
int oldend;
494
int newend = 1;
495
int pnew, ennew(0);
496
497
int changed = 1;
498
while (changed)
499
{
500
changed = 0;
501
for (j = 1; j <= 2; j++)
502
{
503
oldend = newend;
504
newend = line.Size();
505
for (k = oldend; k <= line.Size(); k++)
506
{
507
if (j == 1) p = line.Get(k).i1;
508
if (j == 2) p = line.Get(k).i2;
509
en = GetEdgeNum(line.Get(k).i1, line.Get(k).i2);
510
511
for (i = 1; i <= GetNEPP(p); i++)
512
{
513
pnew = 0;
514
const STLTopEdge & e = Get(GetEdgePP(p,i));
515
if (GetEdgePP(p,i) != en && e.GetStatus() == status)
516
{
517
if (e.PNum(1) == p)
518
{pnew = e.PNum(2);}
519
else
520
{pnew = e.PNum(1);}
521
522
ennew = GetEdgePP(p,i);
523
}
524
if (pnew && !Exists(p,pnew,line))
525
{
526
changed = 1;
527
line.Append(twoint(p,pnew));
528
p = pnew;
529
en = ennew;
530
}
531
}
532
533
}
534
}
535
536
}
537
538
}
539
540
541
542
543
544
545
546
547
548
549
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
550
//+++++++++++++++++++ STL LINE +++++++++++++++++++++++++++++++
551
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
552
553
STLLine :: STLLine(const STLGeometry * ageometry)
554
: pts(), lefttrigs(), righttrigs()
555
{
556
geometry = ageometry;
557
split = 0;
558
};
559
560
int STLLine :: GetNS() const
561
{
562
if (pts.Size() <= 1) {return 0;}
563
return pts.Size()-1;
564
}
565
void STLLine :: GetSeg(int nr, int& p1, int& p2) const
566
{
567
p1 = pts.Get(nr);
568
p2 = pts.Get(nr+1);
569
}
570
571
int STLLine :: GetLeftTrig(int nr) const
572
{
573
if (nr > lefttrigs.Size()) {PrintSysError("In STLLine::GetLeftTrig!!!"); return 0;}
574
return lefttrigs.Get(nr);
575
};
576
577
int STLLine :: GetRightTrig(int nr) const
578
{
579
if (nr > righttrigs.Size()) {PrintSysError("In STLLine::GetRightTrig!!!"); return 0;}
580
return righttrigs.Get(nr);
581
};
582
583
double STLLine :: GetSegLen(const ARRAY<Point<3> >& ap, int nr) const
584
{
585
return Dist(ap.Get(PNum(nr)),ap.Get(PNum(nr+1)));
586
}
587
588
double STLLine :: GetLength(const ARRAY<Point<3> >& ap) const
589
{
590
double len = 0;
591
for (int i = 2; i <= pts.Size(); i++)
592
{
593
len += (ap.Get(pts.Get(i)) - ap.Get(pts.Get(i-1))).Length();
594
}
595
return len;
596
}
597
598
void STLLine :: GetBoundingBox (const ARRAY<Point<3> > & ap, Box<3> & box) const
599
{
600
box.Set (ap.Get (pts[0]));
601
for (int i = 1; i < pts.Size(); i++)
602
box.Add (ap.Get(pts[i]));
603
}
604
605
606
607
Point<3> STLLine ::
608
GetPointInDist(const ARRAY<Point<3> >& ap, double dist, int& index) const
609
{
610
if (dist <= 0)
611
{
612
index = 1;
613
return ap.Get(StartP());
614
}
615
616
double len = 0;
617
int i;
618
for (i = 1; i < pts.Size(); i++)
619
{
620
double seglen = Dist (ap.Get(pts.Get(i)),
621
ap.Get(pts.Get(i+1)));
622
623
if (len + seglen > dist)
624
{
625
index = i;
626
double relval = (dist - len) / (seglen + 1e-16);
627
Vec3d v (ap.Get(pts.Get(i)), ap.Get(pts.Get(i+1)));
628
return ap.Get(pts.Get(i)) + relval * v;
629
}
630
631
len += seglen;
632
}
633
634
index = pts.Size() - 1;
635
return ap.Get(EndP());
636
}
637
638
639
/*
640
double stlgh;
641
double GetH(const Point3d& p, double x)
642
{
643
return stlgh;//+0.5)*(x+0.5);
644
}
645
*/
646
STLLine* STLLine :: Mesh(const ARRAY<Point<3> >& ap,
647
ARRAY<Point3d>& mp, double ghi,
648
class Mesh& mesh) const
649
{
650
STLLine* line = new STLLine(geometry);
651
652
//stlgh = ghi; //uebergangsloesung!!!!
653
654
double len = GetLength(ap);
655
double inthl = 0; //integral of 1/h
656
double dist = 0;
657
double h;
658
int ind;
659
Point3d p;
660
661
int i, j;
662
663
Box<3> bbox;
664
GetBoundingBox (ap, bbox);
665
double diam = bbox.Diam();
666
667
double minh = mesh.LocalHFunction().GetMinH (bbox.PMin(), bbox.PMax());
668
669
double maxseglen = 0;
670
for (i = 1; i <= GetNS(); i++)
671
maxseglen = max2 (maxseglen, GetSegLen (ap, i));
672
673
int nph = 10+int(maxseglen / minh); //anzahl der integralauswertungen pro segment
674
675
ARRAY<double> inthi(GetNS()*nph);
676
ARRAY<double> curvelen(GetNS()*nph);
677
678
679
for (i = 1; i <= GetNS(); i++)
680
{
681
//double seglen = GetSegLen(ap,i);
682
for (j = 1; j <= nph; j++)
683
{
684
p = GetPointInDist(ap,dist,ind);
685
//h = GetH(p,dist/len);
686
h = mesh.GetH(p);
687
688
689
dist += GetSegLen(ap,i)/(double)nph;
690
691
inthl += GetSegLen(ap,i)/nph/(h);
692
inthi.Elem((i-1)*nph+j) = GetSegLen(ap,i)/nph/h;
693
curvelen.Elem((i-1)*nph+j) = GetSegLen(ap,i)/nph;
694
}
695
}
696
697
698
int inthlint = int(inthl+1);
699
700
if ( (inthlint < 3) && (StartP() == EndP()))
701
{
702
inthlint = 3;
703
}
704
if ( (inthlint == 1) && ShouldSplit())
705
{
706
inthlint = 2;
707
}
708
709
double fact = inthl/(double)inthlint;
710
dist = 0;
711
j = 1;
712
713
714
p = ap.Get(StartP());
715
int pn = AddPointIfNotExists(mp, p, 1e-10*diam);
716
717
int segn = 1;
718
line->AddPoint(pn);
719
line->AddLeftTrig(GetLeftTrig(segn));
720
line->AddRightTrig(GetRightTrig(segn));
721
line->AddDist(dist);
722
723
inthl = 0; //restart each meshseg
724
for (i = 1; i <= inthlint; i++)
725
{
726
while (inthl < 1.000000001 && j <= inthi.Size())
727
// while (inthl-1. < 1e-9) && j <= inthi.Size())
728
{
729
inthl += inthi.Get(j)/fact;
730
dist += curvelen.Get(j);
731
j++;
732
}
733
734
//went to far:
735
j--;
736
double tofar = (inthl - 1)/inthi.Get(j);
737
inthl -= tofar*inthi.Get(j);
738
dist -= tofar*curvelen.Get(j)*fact;
739
740
if (i == inthlint && fabs(dist - len) >= 1E-8)
741
{
742
PrintSysError("meshline failed!!!");
743
}
744
745
if (i != inthlint)
746
{
747
p = GetPointInDist(ap,dist,ind);
748
pn = AddPointIfNotExists(mp, p, 1e-10*diam);
749
segn = ind;
750
line->AddPoint(pn);
751
line->AddLeftTrig(GetLeftTrig(segn));
752
line->AddRightTrig(GetRightTrig(segn));
753
line->AddDist(dist);
754
}
755
756
inthl = tofar*inthi.Get(j);
757
dist += tofar*curvelen.Get(j)*fact;
758
j++;
759
}
760
761
p = ap.Get(EndP());
762
pn = AddPointIfNotExists(mp, p, 1e-10*diam);
763
segn = GetNS();
764
line->AddPoint(pn);
765
line->AddLeftTrig(GetLeftTrig(segn));
766
line->AddRightTrig(GetRightTrig(segn));
767
line->AddDist(dist);
768
769
for (int ii = 1; ii <= line->GetNS(); ii++)
770
{
771
int p1, p2;
772
line->GetSeg(ii,p1,p2);
773
}
774
/*
775
(*testout) << "line, " << ap.Get(StartP()) << "-" << ap.Get(EndP())
776
<< " len = " << Dist (ap.Get(StartP()), ap.Get(EndP())) << endl;
777
*/
778
return line;
779
}
780
}
781
782