mirror of
https://github.com/NGSolve/netgen.git
synced 2024-12-26 05:50:32 +05:00
Merge branch 'split_improve_2d' into 'master'
SplitImprove for triangles See merge request jschoeberl/netgen!251
This commit is contained in:
commit
b76b82b293
@ -504,6 +504,8 @@ namespace netgen
|
|||||||
for (SurfaceElementIndex sei = oldnf; sei < mesh.GetNSE(); sei++)
|
for (SurfaceElementIndex sei = oldnf; sei < mesh.GetNSE(); sei++)
|
||||||
mesh[sei].SetIndex (k);
|
mesh[sei].SetIndex (k);
|
||||||
|
|
||||||
|
auto n_illegal_trigs = mesh.FindIllegalTrigs();
|
||||||
|
PrintMessage (3, n_illegal_trigs, " illegal triangles");
|
||||||
|
|
||||||
// mesh.CalcSurfacesOfNode();
|
// mesh.CalcSurfacesOfNode();
|
||||||
|
|
||||||
|
@ -430,6 +430,7 @@ namespace netgen
|
|||||||
{
|
{
|
||||||
if (!faceindex)
|
if (!faceindex)
|
||||||
{
|
{
|
||||||
|
SplitImprove(mesh);
|
||||||
PrintMessage (3, "Combine improve");
|
PrintMessage (3, "Combine improve");
|
||||||
|
|
||||||
for (faceindex = 1; faceindex <= mesh.GetNFD(); faceindex++)
|
for (faceindex = 1; faceindex <= mesh.GetNFD(); faceindex++)
|
||||||
@ -694,7 +695,11 @@ namespace netgen
|
|||||||
if ( (normals[el[l]] * nv) < 0.5)
|
if ( (normals[el[l]] * nv) < 0.5)
|
||||||
bad2 += 1e10;
|
bad2 += 1e10;
|
||||||
|
|
||||||
illegal2 += 1-mesh.LegalTrig(el);
|
Element2d el1 = el;
|
||||||
|
for (auto i : Range(3))
|
||||||
|
if(el1[i]==pi2)
|
||||||
|
el1[i] = pi1;
|
||||||
|
illegal2 += 1-mesh.LegalTrig(el1);
|
||||||
}
|
}
|
||||||
bad2 /= hasonepi.Size();
|
bad2 /= hasonepi.Size();
|
||||||
|
|
||||||
@ -789,6 +794,142 @@ namespace netgen
|
|||||||
mesh.SetNextTimeStamp();
|
mesh.SetNextTimeStamp();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MeshOptimize2d :: SplitImprove (Mesh & mesh)
|
||||||
|
{
|
||||||
|
if (!faceindex)
|
||||||
|
{
|
||||||
|
PrintMessage (3, "Split improve");
|
||||||
|
|
||||||
|
mesh.CalcSurfacesOfNode(); // TODO: needed?
|
||||||
|
for (faceindex = 1; faceindex <= mesh.GetNFD(); faceindex++)
|
||||||
|
{
|
||||||
|
SplitImprove (mesh);
|
||||||
|
|
||||||
|
if (multithread.terminate)
|
||||||
|
throw NgException ("Meshing stopped");
|
||||||
|
}
|
||||||
|
|
||||||
|
faceindex = 0;
|
||||||
|
mesh.Compress(); // TODO: needed?
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Array<SurfaceElementIndex> elements;
|
||||||
|
mesh.GetSurfaceElementsOfFace (faceindex, elements);
|
||||||
|
|
||||||
|
// return if we have quads in this surface
|
||||||
|
for (auto & ei : elements)
|
||||||
|
if (mesh[ei].GetNP() != 3)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// maps from edges to adjacent trigs
|
||||||
|
INDEX_2_HASHTABLE<tuple<SurfaceElementIndex, SurfaceElementIndex>> els_on_edge(2*elements.Size() + 2);
|
||||||
|
|
||||||
|
// build els_on_edge table
|
||||||
|
for (SurfaceElementIndex sei : elements)
|
||||||
|
{
|
||||||
|
const Element2d & sel = mesh[sei];
|
||||||
|
|
||||||
|
for (int j = 0; j < 3; j++)
|
||||||
|
{
|
||||||
|
PointIndex pi1 = sel.PNumMod(j+2);
|
||||||
|
PointIndex pi2 = sel.PNumMod(j+3);
|
||||||
|
|
||||||
|
if (mesh.IsSegment (pi1, pi2)) continue;
|
||||||
|
|
||||||
|
INDEX_2 ii2 (pi1, pi2);
|
||||||
|
ii2.Sort();
|
||||||
|
if (els_on_edge.Used (ii2))
|
||||||
|
{
|
||||||
|
auto els = els_on_edge.Get(ii2);
|
||||||
|
get<1>(els) = sei;
|
||||||
|
els_on_edge.Set(ii2, els);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
els_on_edge.Set (ii2, make_tuple(sei, sei));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// split edges of illegal trigs
|
||||||
|
for (SurfaceElementIndex sei : elements)
|
||||||
|
{
|
||||||
|
Element2d & sel = mesh[sei];
|
||||||
|
|
||||||
|
if (sel.IsDeleted()) continue;
|
||||||
|
|
||||||
|
// TODO: split also bad trigs, nut just illegal ones
|
||||||
|
if (mesh.LegalTrig(sel)) continue;
|
||||||
|
|
||||||
|
for (int j = 0; j < 3; j++)
|
||||||
|
{
|
||||||
|
PointIndex pi1 = sel.PNumMod(j+2);
|
||||||
|
PointIndex pi2 = sel.PNumMod(j+3);
|
||||||
|
PointIndex pi3 = sel.PNumMod(j+1);
|
||||||
|
PointIndex pi4;
|
||||||
|
PointGeomInfo gi1 = sel.GeomInfoPiMod(j+2);
|
||||||
|
PointGeomInfo gi2 = sel.GeomInfoPiMod(j+3);
|
||||||
|
PointGeomInfo gi3 = sel.GeomInfoPiMod(j+1);
|
||||||
|
PointGeomInfo gi4;
|
||||||
|
|
||||||
|
if (mesh.IsSegment (pi1, pi2)) continue;
|
||||||
|
|
||||||
|
// get neighbor element
|
||||||
|
INDEX_2 ii2 (pi1, pi2);
|
||||||
|
ii2.Sort();
|
||||||
|
auto els = els_on_edge.Get(ii2);
|
||||||
|
SurfaceElementIndex other_i = get<0>(els);
|
||||||
|
if(other_i==sei) other_i = get<1>(els);
|
||||||
|
auto & other = mesh[other_i];
|
||||||
|
|
||||||
|
// find opposite point of neighbor element
|
||||||
|
for (int j = 0; j < 3; j++)
|
||||||
|
if(other[j]!=pi1 && other[j]!=pi2)
|
||||||
|
{
|
||||||
|
pi4 = other[j];
|
||||||
|
gi4 = other.GeomInfoPi(j);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// split edge pi1,pi2
|
||||||
|
Point<3> p5;
|
||||||
|
PointIndex pi5;
|
||||||
|
PointGeomInfo gi5;
|
||||||
|
|
||||||
|
mesh.GetGeometry()->GetRefinement().PointBetween (mesh[pi1], mesh[pi2], 0.5,
|
||||||
|
faceindex,
|
||||||
|
gi1, gi2, p5, gi5);
|
||||||
|
|
||||||
|
pi5 = mesh.AddPoint(p5);
|
||||||
|
|
||||||
|
Element2d e1(3);
|
||||||
|
e1.SetIndex(faceindex);
|
||||||
|
e1={ {pi1,gi1}, {pi5,gi5}, {pi3,gi3} };
|
||||||
|
mesh.AddSurfaceElement( e1 );
|
||||||
|
|
||||||
|
Element2d e2(3);
|
||||||
|
e2.SetIndex(faceindex);
|
||||||
|
e2 ={ {pi5,gi5}, {pi2,gi2}, {pi3,gi3} };
|
||||||
|
mesh.AddSurfaceElement( e2 );
|
||||||
|
|
||||||
|
Element2d e3(3);
|
||||||
|
e3.SetIndex(faceindex);
|
||||||
|
e3 ={ {pi1,gi1}, {pi4,gi4}, {pi5,gi5} };
|
||||||
|
mesh.AddSurfaceElement( e3 );
|
||||||
|
|
||||||
|
Element2d e4(3);
|
||||||
|
e4.SetIndex(faceindex);
|
||||||
|
e4 ={ {pi4,gi4}, {pi2,gi2}, {pi5,gi5} };
|
||||||
|
mesh.AddSurfaceElement( e4 );
|
||||||
|
|
||||||
|
sel.Delete();
|
||||||
|
other.Delete();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mesh.SetNextTimeStamp();
|
||||||
|
}
|
||||||
|
|
||||||
void MeshOptimize2d :: CheckMeshApproximation (Mesh & mesh)
|
void MeshOptimize2d :: CheckMeshApproximation (Mesh & mesh)
|
||||||
{
|
{
|
||||||
|
@ -24,6 +24,7 @@ public:
|
|||||||
|
|
||||||
void EdgeSwapping (Mesh & mesh, int usemetric);
|
void EdgeSwapping (Mesh & mesh, int usemetric);
|
||||||
void CombineImprove (Mesh & mesh);
|
void CombineImprove (Mesh & mesh);
|
||||||
|
void SplitImprove (Mesh & mesh);
|
||||||
|
|
||||||
void GenericImprove (Mesh & mesh);
|
void GenericImprove (Mesh & mesh);
|
||||||
|
|
||||||
|
@ -3849,9 +3849,53 @@ namespace netgen
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int Mesh :: FindIllegalTrigs ()
|
||||||
|
{
|
||||||
|
// Temporary table to store the vertex numbers of all triangles
|
||||||
|
INDEX_3_CLOSED_HASHTABLE<int> temp_tab(3*GetNSE() + 1);
|
||||||
|
size_t cnt = 0;
|
||||||
|
for (SurfaceElementIndex sei = 0; sei < GetNSE(); sei++)
|
||||||
|
{
|
||||||
|
const Element2d & sel = surfelements[sei];
|
||||||
|
if (sel.IsDeleted()) continue;
|
||||||
|
|
||||||
|
INDEX_3 i3(sel[0], sel[1], sel[2]);
|
||||||
|
i3.Sort();
|
||||||
|
if(temp_tab.Used(i3))
|
||||||
|
{
|
||||||
|
temp_tab.Set (i3, -1);
|
||||||
|
cnt++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
temp_tab.Set (i3, sei);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
illegal_trigs = make_unique<INDEX_3_CLOSED_HASHTABLE<int>> (2*cnt+1);
|
||||||
|
for (SurfaceElementIndex sei = 0; sei < GetNSE(); sei++)
|
||||||
|
{
|
||||||
|
const Element2d & sel = surfelements[sei];
|
||||||
|
if (sel.IsDeleted()) continue;
|
||||||
|
|
||||||
|
INDEX_3 i3(sel[0], sel[1], sel[2]);
|
||||||
|
i3.Sort();
|
||||||
|
if(temp_tab.Get(i3)==-1)
|
||||||
|
illegal_trigs -> Set (i3, 1);
|
||||||
|
}
|
||||||
|
return cnt;
|
||||||
|
}
|
||||||
|
|
||||||
bool Mesh :: LegalTrig (const Element2d & el) const
|
bool Mesh :: LegalTrig (const Element2d & el) const
|
||||||
{
|
{
|
||||||
|
// Search for surface trigs with same vertices ( may happen for instance with close surfaces in stl geometies )
|
||||||
|
if(!illegal_trigs)
|
||||||
|
throw Exception("In Mesh::LegalTrig() - illegal_trigs table not built");
|
||||||
|
INDEX_3 i3 (el[0], el[1], el[2]);
|
||||||
|
i3.Sort();
|
||||||
|
if(illegal_trigs->Used(i3))
|
||||||
|
return false;
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
if ( /* hp */ 1) // needed for old, simple hp-refinement
|
if ( /* hp */ 1) // needed for old, simple hp-refinement
|
||||||
{
|
{
|
||||||
|
@ -55,6 +55,7 @@ namespace netgen
|
|||||||
unique_ptr<INDEX_2_CLOSED_HASHTABLE<int>> segmentht;
|
unique_ptr<INDEX_2_CLOSED_HASHTABLE<int>> segmentht;
|
||||||
///
|
///
|
||||||
unique_ptr<INDEX_3_CLOSED_HASHTABLE<int>> surfelementht;
|
unique_ptr<INDEX_3_CLOSED_HASHTABLE<int>> surfelementht;
|
||||||
|
unique_ptr<INDEX_3_CLOSED_HASHTABLE<int>> illegal_trigs;
|
||||||
|
|
||||||
/// faces of rest-solid
|
/// faces of rest-solid
|
||||||
NgArray<Element2d> openelements;
|
NgArray<Element2d> openelements;
|
||||||
@ -570,6 +571,10 @@ namespace netgen
|
|||||||
|
|
||||||
|
|
||||||
///
|
///
|
||||||
|
// Find trigs with same vertices
|
||||||
|
// return: number of illegal trigs
|
||||||
|
int FindIllegalTrigs ();
|
||||||
|
|
||||||
bool LegalTrig (const Element2d & el) const;
|
bool LegalTrig (const Element2d & el) const;
|
||||||
/**
|
/**
|
||||||
if values non-null, return values in 4-double array:
|
if values non-null, return values in 4-double array:
|
||||||
|
@ -862,6 +862,9 @@ namespace netgen
|
|||||||
|
|
||||||
for (SurfaceElementIndex sei = oldnf; sei < mesh.GetNSE(); sei++)
|
for (SurfaceElementIndex sei = oldnf; sei < mesh.GetNSE(); sei++)
|
||||||
mesh[sei].SetIndex (k);
|
mesh[sei].SetIndex (k);
|
||||||
|
|
||||||
|
auto n_illegal_trigs = mesh.FindIllegalTrigs();
|
||||||
|
PrintMessage (3, n_illegal_trigs, " illegal triangles");
|
||||||
}
|
}
|
||||||
|
|
||||||
// ofstream problemfile("occmesh.rep");
|
// ofstream problemfile("occmesh.rep");
|
||||||
|
@ -279,6 +279,9 @@ int STLSurfaceMeshing (STLGeometry & geom, class Mesh & mesh, const MeshingParam
|
|||||||
mesh.FindOpenSegments();
|
mesh.FindOpenSegments();
|
||||||
nopen = mesh.GetNOpenSegments();
|
nopen = mesh.GetNOpenSegments();
|
||||||
|
|
||||||
|
auto n_illegal_trigs = mesh.FindIllegalTrigs();
|
||||||
|
PrintMessage (3, n_illegal_trigs, " illegal triangles");
|
||||||
|
|
||||||
if (nopen)
|
if (nopen)
|
||||||
{
|
{
|
||||||
geom.ClearMarkedSegs();
|
geom.ClearMarkedSegs();
|
||||||
|
Loading…
Reference in New Issue
Block a user