30
PointIndex & PNum(int i) { return pnums[i-1]; }
31
PointIndex PNum(int i) const { return pnums[i-1]; }
33
37
PointIndex & operator[] (int i) { return pnums[i]; }
34
38
PointIndex operator[] (int i) const { return pnums[i]; }
36
int & NB(int i) { return nb[i-1]; }
37
int NB(int i) const { return nb[i-1]; }
39
inline void GetFace (int i, INDEX_3 & face) const;
40
inline int FaceNr (INDEX_3 & face) const; // which face nr is it ?
41
inline void GetFace (int i, Element2d & face) const;
40
int & NB1(int i) { return nb[i-1]; }
41
int NB1(int i) const { return nb[i-1]; }
43
int & NB(int i) { return nb[i]; }
44
int NB(int i) const { return nb[i]; }
47
int FaceNr (INDEX_3 & face) const // which face nr is it ?
49
for (int i = 0; i < 3; i++)
50
if (pnums[i] != face.I1() &&
51
pnums[i] != face.I2() &&
52
pnums[i] != face.I3())
57
void GetFace1 (int i, INDEX_3 & face) const
59
face.I(1) = pnums[deltetfaces[i-1][0]];
60
face.I(2) = pnums[deltetfaces[i-1][1]];
61
face.I(3) = pnums[deltetfaces[i-1][2]];
64
void GetFace (int i, INDEX_3 & face) const
66
face.I(1) = pnums[deltetfaces[i][0]];
67
face.I(2) = pnums[deltetfaces[i][1]];
68
face.I(3) = pnums[deltetfaces[i][2]];
71
INDEX_3 GetFace1 (int i) const
73
return INDEX_3 (pnums[deltetfaces[i-1][0]],
74
pnums[deltetfaces[i-1][1]],
75
pnums[deltetfaces[i-1][2]]);
78
INDEX_3 GetFace (int i) const
80
return INDEX_3 (pnums[deltetfaces[i][0]],
81
pnums[deltetfaces[i][1]],
82
pnums[deltetfaces[i][2]]);
85
void GetFace1 (int i, Element2d & face) const
87
// face.SetType(TRIG);
88
face[0] = pnums[deltetfaces[i-1][0]];
89
face[1] = pnums[deltetfaces[i-1][1]];
90
face[2] = pnums[deltetfaces[i-1][2]];
46
inline int DelaunayTet :: FaceNr (INDEX_3 & face) const
48
for (int i = 0; i < 3; i++)
49
if (pnums[i] != face.I1() &&
50
pnums[i] != face.I2() &&
51
pnums[i] != face.I3())
56
static const int deltetfaces[][3] =
63
inline void DelaunayTet :: GetFace (int i, INDEX_3 & face) const
65
face.I(1) = PNum(deltetfaces[i-1][0]);
66
face.I(2) = PNum(deltetfaces[i-1][1]);
67
face.I(3) = PNum(deltetfaces[i-1][2]);
70
inline void DelaunayTet :: GetFace (int i, Element2d & face) const
73
face[0] = PNum(deltetfaces[i-1][0]);
74
face[1] = PNum(deltetfaces[i-1][1]);
75
face[2] = PNum(deltetfaces[i-1][2]);
99
117
: faces(200), tets(atets)
103
120
// add element with 4 nodes
104
121
void Add (int elnr);
106
123
// delete element with 4 nodes
107
void Delete (int elnr);
124
void Delete (int elnr)
126
DelaunayTet & el = tets.Elem(elnr);
127
for (int i = 0; i < 4; i++)
128
faces.Set (el.GetFace(i).Sort(), el.NB(i));
109
131
// get neighbour of element elnr in direction fnr
110
132
int GetNB (int elnr, int fnr)
111
{ return tets.Get(elnr).NB(fnr); }
134
return tets.Get(elnr).NB1(fnr);
114
138
void ResetFaceHT (int size)
116
140
faces.SetSize (size);
119
void PrintMemInfo (ostream & ost) const;
124
146
void MeshNB :: Add (int elnr)
128
148
DelaunayTet & el = tets.Elem(elnr);
130
for (int i = 1; i <= 4; i++)
150
for (int i = 0; i < 4; i++)
135
int bnr, posnr, othertet;
152
INDEX_3 i3 = INDEX_3::Sort (el.GetFace(i));
137
156
if (!faces.PositionCreate (i3, posnr))
139
158
// face already in use
140
faces.GetData (posnr, othertet);
159
int othertet = faces.GetData (posnr);
142
161
el.NB(i) = othertet;
146
164
int fnr = tets.Get(othertet).FaceNr (i3);
159
void MeshNB :: Delete (int elnr)
162
DelaunayTet & el = tets.Elem(elnr);
164
for (int i = 1; i <= 4; i++)
168
faces.Set (i3, el.NB(i));
173
void MeshNB :: PrintMemInfo (ostream & ost) const
177
for (int i = 1; i <= face2el.Size(); i++)
178
if (face2el.Get(i).I1())
182
<< "validels = " << validels << " totels = " << el2face.Size() << endl
183
<< "validfaces = " << uf << " totfaces = " << face2el.Size() << endl
184
<< "face2el: " << face2el.Size() * sizeof(INDEX_2) << endl
185
<< "el2face: " << el2face.Size() * sizeof(INDEX_4) << endl;
198
186
ARRAY<int> links;
201
inline void AddElement (int elnr);
202
inline void DeleteElement (int elnr);
203
inline void ConnectElement (int eli, int toi);
191
void AddElement (int elnr)
193
if (elnr > links.Size())
195
links.Elem(elnr) = elnr;
198
void DeleteElement (int elnr)
200
links.Elem(elnr) = 0;
203
void ConnectElement (int eli, int toi)
205
links.Elem (eli) = links.Get (toi);
206
links.Elem (toi) = eli;
204
209
void GetList (int eli, ARRAY<int> & linked) const;
207
inline void SphereList :: AddElement (int elnr)
209
if (elnr > links.Size())
211
links.Elem(elnr) = elnr;
214
inline void SphereList :: DeleteElement (int elnr)
216
links.Elem(elnr) = 0;
219
inline void SphereList :: ConnectElement (int eli, int toi)
221
links.Elem (eli) = links.Get (toi);
222
links.Elem (toi) = eli;
225
213
void SphereList :: GetList (int eli, ARRAY<int> & linked) const
406
391
tempels.Get(helind).GetFace (k, face);
408
393
const Point3d & p1 = mesh.Point (face.PNum(1));
409
const Point3d & p2 = mesh.Point (face.PNum(2));
410
const Point3d & p3 = mesh.Point (face.PNum(3));
394
const Point3d & p2 = mesh.Point (face[1]);
395
const Point3d & p3 = mesh.Point (face[2]);
398
INDEX_3 i3 = tempels.Get(helind).GetFace (k-1);
400
const Point3d & p1 = mesh.Point ( PointIndex (i3.I1()));
401
const Point3d & p2 = mesh.Point ( PointIndex (i3.I2()));
402
const Point3d & p3 = mesh.Point ( PointIndex (i3.I3()));
412
405
Vec3d v1(p1, p2);
413
406
Vec3d v2(p1, p3);
414
407
Vec3d n = Cross (v1, v2);
417
if (n * Vec3d (p1, mesh.Point (tempels.Get(helind).PNum(k))) > 0)
410
if (n * Vec3d (p1, mesh.Point (tempels.Get(helind)[k-1])) > 0)
420
413
double dist = n * Vec3d (p1, newp);
445
439
if (!nbind || !insphere.IsIn (nbind))
448
tempels.Get (celind).GetFace (k, face);
441
tempels.Get (celind).GetFace1 (k, face);
451
444
for (l = 1; l <= 3; l++)
452
445
newel.PNum(l) = face.PNum(l);
453
newel.PNum(4) = newpi;
455
448
newels.Append (newel);
457
Vec3d v1(mesh.Point (face.PNum(1)), mesh.Point (face.PNum(2)));
458
Vec3d v2(mesh.Point (face.PNum(1)), mesh.Point (face.PNum(3)));
450
Vec3d v1(mesh.Point (face[0]), mesh.Point (face[1]));
451
Vec3d v2(mesh.Point (face[0]), mesh.Point (face[2]));
459
452
Vec3d n = Cross (v1, v2);
461
if (n * Vec3d(mesh.Point (face.PNum(1)),
462
mesh.Point (tempels.Get(insphere.Array().Get(j)).PNum(k)))
454
if (n * Vec3d(mesh.Point (face[0]),
455
mesh.Point (tempels.Get(insphere.Array().Get(j))[k-1]))
466
double hval = n * Vec3d (mesh.Point (face.PNum(1)), newp);
459
double hval = n * Vec3d (mesh.Point (face[0]), newp);
468
461
if (hval > -1e-12)
471
464
(*testout) << "vec to outer, hval = " << hval << endl;
472
465
(*testout) << "v1 x v2 = " << Cross (v1, v2) << endl;
473
466
(*testout) << "facep: "
474
<< mesh.Point (face.PNum(1)) << " "
475
<< mesh.Point (face.PNum(2)) << " "
476
<< mesh.Point (face.PNum(3)) << endl;
467
<< mesh.Point (face[0]) << " "
468
<< mesh.Point (face[1]) << " "
469
<< mesh.Point (face[2]) << endl;
632
632
int np = mesh.GetNP();
634
startel.PNum(1) = mesh.AddPoint (cp1);
635
startel.PNum(2) = mesh.AddPoint (cp2);
636
startel.PNum(3) = mesh.AddPoint (cp3);
637
startel.PNum(4) = mesh.AddPoint (cp4);
634
startel[0] = mesh.AddPoint (cp1);
635
startel[1] = mesh.AddPoint (cp2);
636
startel[2] = mesh.AddPoint (cp3);
637
startel[3] = mesh.AddPoint (cp4);
639
639
// flag points to use for Delaunay:
640
640
BitArrayChar<PointIndex::BASE> usep(np);
674
674
ARRAY<int> connected, treesearch;
677
tpmin = tpmax = mesh.Point(startel.PNum(1));
678
for (k = 2; k <= 4; k++)
677
tpmin = tpmax = mesh.Point(startel[0]);
678
for (k = 1; k < 4; k++)
680
tpmin.SetToMin (mesh.Point (startel.PNum(k)));
681
tpmax.SetToMax (mesh.Point (startel.PNum(k)));
680
tpmin.SetToMin (mesh.Point (startel[k]));
681
tpmax.SetToMax (mesh.Point (startel[k]));
683
683
tpmax = tpmax + 0.01 * (tpmax - tpmin);
684
684
tettree.Insert (tpmin, tpmax, 1);
816
816
for (i = 1; i <= tempels.Size(); i++)
819
for (j = 1; j <= 4; j++)
820
el.PNum(j) = tempels.Elem(i).PNum(j);
819
for (j = 0; j < 4; j++)
820
el[j] = tempels.Elem(i)[j];
823
const Point3d & lp1 = mesh.Point (el.PNum(1));
824
const Point3d & lp2 = mesh.Point (el.PNum(2));
825
const Point3d & lp3 = mesh.Point (el.PNum(3));
826
const Point3d & lp4 = mesh.Point (el.PNum(4));
824
const Point3d & lp1 = mesh.Point (el[0]);
825
const Point3d & lp2 = mesh.Point (el[1]);
826
const Point3d & lp3 = mesh.Point (el[2]);
827
const Point3d & lp4 = mesh.Point (el[3]);
827
828
Vec3d v1(lp1, lp2);
828
829
Vec3d v2(lp1, lp3);
829
830
Vec3d v3(lp1, lp4);
843
845
Element2d sel = mesh.OpenElement(i);
845
847
tempmesh.AddSurfaceElement (sel);
846
Swap (sel.PNum(2), sel.PNum(3));
848
swap (sel[1], sel[2]);
847
849
tempmesh.AddSurfaceElement (sel);
851
853
for (i = 1; i <= 4; i++)
855
Element2d self(TRIG);
854
856
self.SetIndex (1);
855
startel.GetFace (i, self);
857
startel.GetFace1 (i, self);
856
858
tempmesh.AddSurfaceElement (self);
860
862
tempmesh.AddFaceDescriptor (FaceDescriptor (1, 1, 0, 0));
861
863
tempmesh.AddFaceDescriptor (FaceDescriptor (2, 1, 0, 0));
864
866
// for (i = mesh.GetNP() - 3; i <= mesh.GetNP(); i++)
865
867
// tempmesh.AddLockedPoint (i);
908
909
for (i = 1; i <= tempels.Size(); i++)
911
for (j = 1; j <= 4; j++)
912
el.PNum(j) = tempels.Elem(i).PNum(j);
912
for (j = 0; j < 4; j++)
913
el[j] = tempels.Elem(i)[j];
913
914
// Element & el = tempels.Elem(i);
914
const Point3d & lp1 = mesh.Point (el.PNum(1));
915
const Point3d & lp2 = mesh.Point (el.PNum(2));
916
const Point3d & lp3 = mesh.Point (el.PNum(3));
917
const Point3d & lp4 = mesh.Point (el.PNum(4));
915
const Point3d & lp1 = mesh.Point (el[0]);
916
const Point3d & lp2 = mesh.Point (el[1]);
917
const Point3d & lp3 = mesh.Point (el[2]);
918
const Point3d & lp4 = mesh.Point (el[3]);
918
919
Vec3d v1(lp1, lp2);
919
920
Vec3d v2(lp1, lp3);
920
921
Vec3d v3(lp1, lp4);
924
925
double h = v1.Length() + v2.Length() + v3.Length();
925
926
if (fabs (vol) < 1e-8 * (h * h * h) &&
926
(el.PNum(1) <= np && el.PNum(2) <= np &&
927
el.PNum(3) <= np && el.PNum(4) <= np) ) // old: 1e-12
927
(el[0] <= np && el[1] <= np &&
928
el[2] <= np && el[3] <= np) ) // old: 1e-12
929
badnode.Set(el.PNum(1));
930
badnode.Set(el.PNum(2));
931
badnode.Set(el.PNum(3));
932
badnode.Set(el.PNum(4));
934
935
(*testout) << "vol = " << vol << " h = " << h << endl;
938
Swap (el.PNum(3), el.PNum(4));
941
942
ne = tempels.Size();
942
943
for (i = ne; i >= 1; i--)
944
945
const DelaunayTet & el = tempels.Get(i);
945
if (badnode.Test(el.PNum(1)) ||
946
badnode.Test(el.PNum(2)) ||
947
badnode.Test(el.PNum(3)) ||
948
badnode.Test(el.PNum(4)) )
946
if (badnode.Test(el[0]) ||
947
badnode.Test(el[1]) ||
948
badnode.Test(el[2]) ||
949
badnode.Test(el[3]) )
949
950
tempels.DeleteElement(i);
959
960
for (i = 1; i <= mesh.GetNOpenElements(); i++)
961
962
const Element2d & tri = mesh.OpenElement(i);
962
INDEX_3 i3(tri.PNum(1), tri.PNum(2), tri.PNum(3));
963
INDEX_3 i3(tri[0], tri[1], tri[2]);
964
965
openeltab.Set (i3, i);
967
968
for (i = 1; i <= tempels.Size(); i++)
969
for (j = 1; j <= 4; j++)
970
for (j = 0; j < 4; j++)
972
tempels.Get(i).GetFace (j, face);
973
INDEX_3 i3(face.PNum(1), face.PNum(2), face.PNum(3));
972
INDEX_3 i3 = tempels.Get(i).GetFace (j);
975
974
if (openeltab.Used(i3))
976
975
openeltab.Set (i3, 0);
1031
case 1: i2 = INDEX_2(el.PNum(1), el.PNum(2)); break;
1032
case 2: i2 = INDEX_2(el.PNum(1), el.PNum(3)); break;
1033
case 3: i2 = INDEX_2(el.PNum(1), el.PNum(4)); break;
1034
case 4: i2 = INDEX_2(el.PNum(2), el.PNum(3)); break;
1035
case 5: i2 = INDEX_2(el.PNum(2), el.PNum(4)); break;
1036
case 6: i2 = INDEX_2(el.PNum(3), el.PNum(4)); break;
1030
case 1: i2 = INDEX_2(el[0], el[1]); break;
1031
case 2: i2 = INDEX_2(el[0], el[2]); break;
1032
case 3: i2 = INDEX_2(el[0], el[3]); break;
1033
case 4: i2 = INDEX_2(el[1], el[2]); break;
1034
case 5: i2 = INDEX_2(el[1], el[3]); break;
1035
case 6: i2 = INDEX_2(el[2], el[3]); break;
1039
1038
tetedges.Set (i2, 1);
1042
1041
// cout << "tetedges:";
1043
1042
// tetedges.PrintMemInfo (cout);
1045
for (INDEX_2_HASHTABLE<INDEX_2>::Iterator it = twotrias.Begin();
1046
it != twotrias.End(); it++)
1049
twotrias.GetData (it, hi2, hi3);
1051
if (tetedges.Used (hi3))
1053
const Point3d & p1 = mesh.Point ( PointIndex (hi2.I1()));
1054
const Point3d & p2 = mesh.Point ( PointIndex (hi2.I2()));
1055
const Point3d & p3 = mesh.Point ( PointIndex (hi3.I1()));
1056
const Point3d & p4 = mesh.Point ( PointIndex (hi3.I2()));
1060
Vec3d n = Cross (v1, v2);
1061
double vol = n * v3;
1063
double h = v1.Length() + v2.Length() + v3.Length();
1064
if (fabs (vol) < 1e-4 * (h * h * h)) // old: 1e-12
1066
badnode.Set(hi3.I1());
1067
badnode.Set(hi3.I2());
1045
1073
for (i = 1; i <= twotrias.GetNBags(); i++)
1046
1074
for (j = 1; j <= twotrias.GetBagSize (i); j++)
1073
1101
ne = tempels.Size();
1074
1102
for (i = ne; i >= 1; i--)
1076
1104
const DelaunayTet & el = tempels.Get(i);
1077
if (badnode.Test(el.PNum(1)) ||
1078
badnode.Test(el.PNum(2)) ||
1079
badnode.Test(el.PNum(3)) ||
1080
badnode.Test(el.PNum(4)) )
1105
if (badnode.Test(el[0]) ||
1106
badnode.Test(el[1]) ||
1107
badnode.Test(el[2]) ||
1108
badnode.Test(el[3]) )
1081
1109
tempels.DeleteElement(i);
1228
1257
for (i = 1; i <= mesh.GetNOpenElements(); i++)
1230
1259
const Element2d & tri = mesh.OpenElement(i);
1231
INDEX_3 i3 (tri.PNum(1), tri.PNum(2), tri.PNum(3));
1260
INDEX_3 i3 (tri[0], tri[1], tri[2]);
1233
1262
boundaryfaces.Set (i3, 1);
1236
for (i = 1; i <= tempels.Size(); i++)
1237
for (j = 1; j <= 4; j++)
1238
tempels.Elem(i).NB(j) = 0;
1265
for (i = 0; i < tempels.Size(); i++)
1266
for (j = 0; j < 4; j++)
1267
tempels[i].NB(j) = 0;
1240
1269
TABLE<int,PointIndex::BASE> elsonpoint(mesh.GetNP());
1241
1270
for (i = 0; i < tempels.Size(); i++)
1290
1319
INDEX_2 i2 = faceht.Get(i3);
1292
tempels.Elem(i).NB(j) = i2.I1();
1293
tempels.Elem(i2.I1()).NB(i2.I2()) = i;
1321
tempels.Elem(i).NB1(j) = i2.I1();
1322
tempels.Elem(i2.I1()).NB1(i2.I2()) = i;
1298
1327
hel.NormalizeNumbering();
1299
INDEX_3 i3(hel.PNum(1), hel.PNum(2), hel.PNum(3));
1328
INDEX_3 i3(hel[0], hel[1], hel[2]);
1300
1329
INDEX_2 i2(i, j);
1301
1330
faceht.Set (i3, i2);
1415
1444
if (done) break;
1417
1446
const DelaunayTet & el = tempels.Get(i);
1418
const Point3d & p1 = mesh.Point (el.PNum(1));
1419
const Point3d & p2 = mesh.Point (el.PNum(2));
1420
const Point3d & p3 = mesh.Point (el.PNum(3));
1421
const Point3d & p4 = mesh.Point (el.PNum(4));
1447
const Point3d & p1 = mesh.Point (el[0]);
1448
const Point3d & p2 = mesh.Point (el[1]);
1449
const Point3d & p3 = mesh.Point (el[2]);
1450
const Point3d & p4 = mesh.Point (el[3]);
1423
1452
Point3d ci = Center (p1, p2, p3, p4);
1450
1479
for (j = 1; j <= 4; j++)
1481
INDEX_3 i3 = tempels.Get(ei).GetFace1(j);
1453
1483
Element2d face;
1454
1484
tempels.Get(ei).GetFace(j, face);
1455
1485
for (int kk = 1; kk <= 3; kk++)
1456
1486
i3.I(kk) = face.PNum(kk);
1460
if (tempels.Get(ei).NB(j))
1461
elstack.Append (tempels.Get(ei).NB(j));
1491
if (tempels.Get(ei).NB1(j))
1492
elstack.Append (tempels.Get(ei).NB1(j));
1464
1495
if (innerfaces.Used(i3))
1492
1523
for (i = 1; i <= ne; i++)
1494
1525
const DelaunayTet & el = tempels.Get(i);
1495
const Point3d & p1 = mesh.Point (el.PNum(1));
1496
const Point3d & p2 = mesh.Point (el.PNum(2));
1497
const Point3d & p3 = mesh.Point (el.PNum(3));
1498
const Point3d & p4 = mesh.Point (el.PNum(4));
1526
const Point3d & p1 = mesh.Point (el[0]);
1527
const Point3d & p2 = mesh.Point (el[1]);
1528
const Point3d & p3 = mesh.Point (el[2]);
1529
const Point3d & p4 = mesh.Point (el[3]);
1500
1531
Point3d ci = Center (p1, p2, p3, p4);