Path: blob/devel/ElmerGUI/netgen/libsrc/meshing/adfront3.cpp
3206 views
#include <mystdlib.h>1#include "meshing.hpp"234/* ********************** FrontPoint ********************** */56namespace netgen7{89FrontPoint3 :: FrontPoint3 ()10{11globalindex = -1;12nfacetopoint = 0;13frontnr = 1000;14cluster = 0;15}161718FrontPoint3 :: FrontPoint3 (const Point<3> & ap, PointIndex agi)19{20p = ap;21globalindex = agi;22nfacetopoint = 0;23frontnr = 1000;24cluster = 0;25}26272829/* ********************** FrontFace ********************** */3031FrontFace :: FrontFace ()32{33qualclass = 1;34oldfront = 0;35hashvalue = 0;36cluster = 0;37}3839FrontFace :: FrontFace (const MiniElement2d & af)40{41f = af;42oldfront = 0;43qualclass = 1;44hashvalue = 0;45}4647void FrontFace :: Invalidate ()48{49f.Delete();50oldfront = 0;51qualclass = 1000;52}5354555657/* ********************** AddFront ********************** */585960AdFront3 :: AdFront3 ()61{62nff = 0;63nff4 = 0;64vol = 0;6566hashon = 1;67hashcreated = 0;68if (hashon)69hashtable.Init(&points, &faces);7071facetree = NULL;72connectedpairs = NULL;7374rebuildcounter = -1;75lasti = 0;76minval = -1;77}787980AdFront3 :: ~AdFront3 ()81{82delete facetree;83delete connectedpairs;84}8586void AdFront3 :: GetPoints (ARRAY<Point<3> > & apoints) const87{88for (PointIndex pi = PointIndex::BASE;89pi < points.Size()+PointIndex::BASE; pi++)9091apoints.Append (points[pi].P());92}939495PointIndex AdFront3 :: AddPoint (const Point<3> & p, PointIndex globind)96{97if (delpointl.Size())98{99PointIndex pi = delpointl.Last();100delpointl.DeleteLast ();101102points[pi] = FrontPoint3 (p, globind);103return pi;104}105else106{107points.Append (FrontPoint3 (p, globind));108return points.Size()-1+PointIndex::BASE;109}110}111112113INDEX AdFront3 :: AddFace (const MiniElement2d & aface)114{115int i, minfn;116117nff++;118119for (i = 0; i < aface.GetNP(); i++)120points[aface[i]].AddFace();121122const Point3d & p1 = points[aface[0]].P();123const Point3d & p2 = points[aface[1]].P();124const Point3d & p3 = points[aface[2]].P();125126vol += 1.0/6.0 * (p1.X() + p2.X() + p3.X()) *127( (p2.Y() - p1.Y()) * (p3.Z() - p1.Z()) -128(p2.Z() - p1.Z()) * (p3.Y() - p1.Y()) );129130if (aface.GetNP() == 4)131{132nff4++;133const Point3d & p4 = points[aface[3]].P();134vol += 1.0/6.0 * (p1.X() + p3.X() + p4.X()) *135( (p3.Y() - p1.Y()) * (p4.Z() - p1.Z()) -136(p3.Z() - p1.Z()) * (p4.Y() - p1.Y()) );137}138139140minfn = 1000;141for (i = 0; i < aface.GetNP(); i++)142{143int fpn = points[aface[i]].FrontNr();144if (i == 0 || fpn < minfn)145minfn = fpn;146}147148149int cluster = 0;150for (i = 1; i <= aface.GetNP(); i++)151{152if (points[aface.PNum(i)].cluster)153cluster = points[aface.PNum(i)].cluster;154}155for (i = 1; i <= aface.GetNP(); i++)156points[aface.PNum(i)].cluster = cluster;157158159for (i = 1; i <= aface.GetNP(); i++)160points[aface.PNum(i)].DecFrontNr (minfn+1);161162int nfn = faces.Append(FrontFace (aface));163faces.Elem(nfn).cluster = cluster;164165if (hashon && hashcreated)166hashtable.AddElem(aface, nfn);167168return nfn;169}170171172173void AdFront3 :: DeleteFace (INDEX fi)174{175nff--;176177for (int i = 1; i <= faces.Get(fi).Face().GetNP(); i++)178{179PointIndex pi = faces.Get(fi).Face().PNum(i);180points[pi].RemoveFace();181if (!points[pi].Valid())182delpointl.Append (pi);183}184185const MiniElement2d & face = faces.Get(fi).Face();186const Point3d & p1 = points[face.PNum(1)].P();187const Point3d & p2 = points[face.PNum(2)].P();188const Point3d & p3 = points[face.PNum(3)].P();189190vol -= 1.0/6.0 * (p1.X() + p2.X() + p3.X()) *191( (p2.Y() - p1.Y()) * (p3.Z() - p1.Z()) -192(p2.Z() - p1.Z()) * (p3.Y() - p1.Y()) );193194if (face.GetNP() == 4)195{196const Point3d & p4 = points[face.PNum(4)].P();197vol -= 1.0/6.0 * (p1.X() + p3.X() + p4.X()) *198( (p3.Y() - p1.Y()) * (p4.Z() - p1.Z()) -199(p3.Z() - p1.Z()) * (p4.Y() - p1.Y()) );200201nff4--;202}203204faces.Elem(fi).Invalidate();205}206207208INDEX AdFront3 :: AddConnectedPair (const INDEX_2 & apair)209{210if (!connectedpairs)211connectedpairs = new TABLE<int, PointIndex::BASE> (GetNP());212213connectedpairs->Add (apair.I1(), apair.I2());214connectedpairs->Add (apair.I2(), apair.I1());215216return 0;217}218219220void AdFront3 :: CreateTrees ()221{222int i, j;223PointIndex pi;224Point3d pmin, pmax;225226for (pi = PointIndex::BASE;227pi < GetNP()+PointIndex::BASE; pi++)228{229const Point<3> & p = GetPoint(pi);230if (pi == PointIndex::BASE)231{232pmin = p;233pmax = p;234}235else236{237pmin.SetToMin (p);238pmax.SetToMax (p);239}240}241242pmax = pmax + 0.5 * (pmax - pmin);243pmin = pmin + 0.5 * (pmin - pmax);244245delete facetree;246facetree = new Box3dTree (pmin, pmax);247248for (i = 1; i <= GetNF(); i++)249{250const MiniElement2d & el = GetFace(i);251pmin = GetPoint (el[0]);252pmax = pmin;253for (j = 1; j < 3; j++)254{255const Point<3> & p = GetPoint (el[j]);256pmin.SetToMin (p);257pmax.SetToMax (p);258}259pmax = pmax + 0.01 * (pmax - pmin);260pmin = pmin + 0.01 * (pmin - pmax);261// (*testout) << "insert " << i << ": " << pmin << " - " << pmax << "\n";262facetree -> Insert (pmin, pmax, i);263}264}265266267void AdFront3 :: GetIntersectingFaces (const Point<3> & pmin, const Point<3> & pmax,268ARRAY<int> & ifaces) const269{270facetree -> GetIntersecting (pmin, pmax, ifaces);271}272273void AdFront3 :: GetFaceBoundingBox (int i, Box3d & box) const274{275const FrontFace & face = faces.Get(i);276box.SetPoint (points[face.f[0]].p);277box.AddPoint (points[face.f[1]].p);278box.AddPoint (points[face.f[2]].p);279}280281void AdFront3 :: RebuildInternalTables ()282{283static int timer_a = NgProfiler::CreateTimer ("Adfront3::RebuildInternal A");284static int timer_b = NgProfiler::CreateTimer ("Adfront3::RebuildInternal B");285static int timer_c = NgProfiler::CreateTimer ("Adfront3::RebuildInternal C");286static int timer_d = NgProfiler::CreateTimer ("Adfront3::RebuildInternal D");287288289NgProfiler::StartTimer (timer_a);290int hi = 0;291for (int i = 1; i <= faces.Size(); i++)292if (faces.Get(i).Valid())293{294hi++;295if (hi < i)296faces.Elem(hi) = faces.Get(i);297}298299faces.SetSize (nff);300301int np = points.Size();302303for (int i = PointIndex::BASE;304i < np+PointIndex::BASE; i++)305points[i].cluster = i;306307NgProfiler::StopTimer (timer_a);308NgProfiler::StartTimer (timer_b);309310int change;311do312{313change = 0;314for (int i = 1; i <= faces.Size(); i++)315{316const MiniElement2d & el = faces.Get(i).Face();317318int mini = points[el.PNum(1)].cluster;319int maxi = mini;320321for (int j = 2; j <= 3; j++)322{323int ci = points[el.PNum(j)].cluster;324if (ci < mini) mini = ci;325if (ci > maxi) maxi = ci;326}327328if (mini < maxi)329{330change = 1;331for (int j = 1; j <= 3; j++)332points[el.PNum(j)].cluster = mini;333}334}335}336while (change);337338339NgProfiler::StopTimer (timer_b);340NgProfiler::StartTimer (timer_c);341342343344345BitArrayChar<PointIndex::BASE> usecl(np);346usecl.Clear();347for (int i = 1; i <= faces.Size(); i++)348{349usecl.Set (points[faces.Get(i).Face().PNum(1)].cluster);350faces.Elem(i).cluster =351points[faces.Get(i).Face().PNum(1)].cluster;352}353int cntcl = 0;354for (int i = PointIndex::BASE;355i < np+PointIndex::BASE; i++)356if (usecl.Test(i))357cntcl++;358359ARRAY<double, PointIndex::BASE> clvol (np);360clvol = 0.0;361362for (int i = 1; i <= faces.Size(); i++)363{364const MiniElement2d & face = faces.Get(i).Face();365366const Point3d p1 = points[face.PNum(1)].P();367const Point3d p2 = points[face.PNum(2)].P();368const Point3d p3 = points[face.PNum(3)].P();369370double vi = 1.0/6.0 * (p1.X() + p2.X() + p3.X()) *371( (p2.Y() - p1.Y()) * (p3.Z() - p1.Z()) -372(p2.Z() - p1.Z()) * (p3.Y() - p1.Y()) );373374if (face.GetNP() == 4)375{376const Point3d p4 = points[face.PNum(4)].P();377vi += 1.0/6.0 * (p1.X() + p3.X() + p4.X()) *378( (p3.Y() - p1.Y()) * (p4.Z() - p1.Z()) -379(p3.Z() - p1.Z()) * (p4.Y() - p1.Y()) );380}381382clvol[faces.Get(i).cluster] += vi;383}384385NgProfiler::StopTimer (timer_c);386NgProfiler::StartTimer (timer_d);387388389390int negvol = 0;391for (int i = PointIndex::BASE;392i < clvol.Size()+PointIndex::BASE; i++)393{394if (clvol[i] < 0)395negvol = 1;396}397398if (negvol)399{400for (int i = 1; i <= faces.Size(); i++)401faces.Elem(i).cluster = 1;402for (int i = PointIndex::BASE;403i < points.Size()+PointIndex::BASE; i++)404points[i].cluster = 1;405}406407if (hashon)408hashtable.Create();409410NgProfiler::StopTimer (timer_d);411}412413414415int AdFront3 :: SelectBaseElement ()416{417int i, hi, fstind;418419/*420static int minval = -1;421static int lasti = 0;422static int counter = 0;423*/424if (rebuildcounter <= 0)425{426RebuildInternalTables();427rebuildcounter = nff / 10 + 1;428429lasti = 0;430}431rebuildcounter--;432433/*434if (faces.Size() > 2 * nff)435{436// compress facelist437438RebuildInternalTables ();439lasti = 0;440}441*/442443fstind = 0;444445for (i = lasti+1; i <= faces.Size() && !fstind; i++)446if (faces.Elem(i).Valid())447{448hi = faces.Get(i).QualClass() +449points[faces.Get(i).Face().PNum(1)].FrontNr() +450points[faces.Get(i).Face().PNum(2)].FrontNr() +451points[faces.Get(i).Face().PNum(3)].FrontNr();452453if (hi <= minval)454{455minval = hi;456fstind = i;457lasti = fstind;458}459}460461if (!fstind)462{463minval = INT_MAX;464for (i = 1; i <= faces.Size(); i++)465if (faces.Elem(i).Valid())466{467hi = faces.Get(i).QualClass() +468points[faces.Get(i).Face().PNum(1)].FrontNr() +469points[faces.Get(i).Face().PNum(2)].FrontNr() +470points[faces.Get(i).Face().PNum(3)].FrontNr();471472if (hi <= minval)473{474minval = hi;475fstind = i;476lasti = 0;477}478}479}480481482return fstind;483}484485486487int AdFront3 :: GetLocals (int fstind,488ARRAY<Point3d > & locpoints,489ARRAY<MiniElement2d> & locfaces, // local index490ARRAY<PointIndex> & pindex,491ARRAY<INDEX> & findex,492INDEX_2_HASHTABLE<int> & getconnectedpairs,493float xh,494float relh,495INDEX& facesplit)496{497static int timer = NgProfiler::CreateTimer ("AdFront3::GetLocals");498NgProfiler::RegionTimer reg (timer);499500501if (hashon && faces.Size() < 500) { hashon=0; }502if (hashon && !hashcreated)503{504hashtable.Create();505hashcreated=1;506}507508INDEX i, j;509PointIndex pstind;510INDEX pi;511Point3d midp, p0;512513static ARRAY<int, PointIndex::BASE> invpindex;514515static ARRAY<MiniElement2d> locfaces2; //all local faces in radius xh516static ARRAY<int> locfaces3; // all faces in outer radius relh517static ARRAY<INDEX> findex2;518519locfaces2.SetSize(0);520locfaces3.SetSize(0);521findex2.SetSize(0);522523int cluster = faces.Get(fstind).cluster;524525pstind = faces.Get(fstind).Face().PNum(1);526p0 = points[pstind].P();527528locfaces2.Append(faces.Get(fstind).Face());529findex2.Append(fstind);530531532Box3d b1 (p0 - Vec3d(xh, xh, xh), p0 + Vec3d (xh, xh, xh));533534if (hashon)535{536hashtable.GetLocals(locfaces2, findex2, fstind, p0, xh);537}538else539{540for (i = 1; i <= faces.Size(); i++)541{542const MiniElement2d & face = faces.Get(i).Face();543if (faces.Get(i).cluster == cluster && faces.Get(i).Valid() && i != fstind)544{545Box3d b2;546b2.SetPoint (points[face[0]].P());547b2.AddPoint (points[face[1]].P());548b2.AddPoint (points[face[2]].P());549550if (b1.Intersect (b2))551{552locfaces2.Append(faces.Get(i).Face());553findex2.Append(i);554}555}556}557}558559//local faces for inner radius:560for (i = 1; i <= locfaces2.Size(); i++)561{562const MiniElement2d & face = locfaces2.Get(i);563const Point3d & p1 = points[face[0]].P();564const Point3d & p2 = points[face[1]].P();565const Point3d & p3 = points[face[2]].P();566567midp = Center (p1, p2, p3);568569if (Dist2 (midp, p0) <= relh * relh || i == 1)570{571locfaces.Append(locfaces2.Get(i));572findex.Append(findex2.Get(i));573}574else575locfaces3.Append (i);576}577578facesplit=locfaces.Size();579580581//local faces for outer radius:582for (i = 1; i <= locfaces3.Size(); i++)583{584locfaces.Append (locfaces2.Get(locfaces3.Get(i)));585findex.Append (findex2.Get(locfaces3.Get(i)));586}587588589invpindex.SetSize (points.Size());590for (i = 1; i <= locfaces.Size(); i++)591for (j = 1; j <= locfaces.Get(i).GetNP(); j++)592{593pi = locfaces.Get(i).PNum(j);594invpindex[pi] = -1;595}596597for (i = 1; i <= locfaces.Size(); i++)598{599for (j = 1; j <= locfaces.Get(i).GetNP(); j++)600{601pi = locfaces.Get(i).PNum(j);602if (invpindex[pi] == -1)603{604pindex.Append (pi);605invpindex[pi] = pindex.Size(); // -1+PointIndex::BASE;606locfaces.Elem(i).PNum(j) = locpoints.Append (points[pi].P());607}608else609locfaces.Elem(i).PNum(j) = invpindex[pi];610611}612}613614615616if (connectedpairs)617{618for (i = 1; i <= locpoints.Size(); i++)619{620int pind = pindex.Get(i);621if (pind >= 1 && pind <= connectedpairs->Size ())622{623for (j = 1; j <= connectedpairs->EntrySize(pind); j++)624{625int oi = connectedpairs->Get(pind, j);626int other = invpindex.Get(oi);627if (other >= 1 && other <= pindex.Size() &&628pindex.Get(other) == oi)629{630// INDEX_2 coned(i, other);631// coned.Sort();632// (*testout) << "connected: " << locpoints.Get(i) << "-" << locpoints.Get(other) << endl;633getconnectedpairs.Set (INDEX_2::Sort (i, other), 1);634}635}636}637}638}639640641/*642// add isolated points643for (i = 1; i <= points.Size(); i++)644if (points.Elem(i).Valid() && Dist (points.Elem(i).P(), p0) <= xh)645{646if (!invpindex.Get(i))647{648locpoints.Append (points.Get(i).P());649pindex.Append (i);650invpindex.Elem(i) = pindex.Size();651}652}653*/654return faces.Get(fstind).QualClass();655}656657658// returns all points connected with fi659void AdFront3 :: GetGroup (int fi,660ARRAY<MeshPoint> & grouppoints,661ARRAY<MiniElement2d> & groupelements,662ARRAY<PointIndex> & pindex,663ARRAY<INDEX> & findex) const664{665static ARRAY<char> pingroup;666int i, j, changed;667668pingroup.SetSize(points.Size());669670pingroup = 0;671for (j = 1; j <= 3; j++)672pingroup.Elem (faces.Get(fi).Face().PNum(j)) = 1;673674do675{676changed = 0;677678for (i = 1; i <= faces.Size(); i++)679if (faces.Get(i).Valid())680{681const MiniElement2d & face = faces.Get(i).Face();682683int fused = 0;684for (j = 1; j <= 3; j++)685if (pingroup.Elem(face.PNum(j)))686fused++;687688if (fused >= 2)689for (j = 1; j <= 3; j++)690if (!pingroup.Elem(face.PNum(j)))691{692pingroup.Elem(face.PNum(j)) = 1;693changed = 1;694}695}696697}698while (changed);699700701static ARRAY<int> invpindex;702invpindex.SetSize (points.Size());703704705for (i = 1; i <= points.Size(); i++)706if (points.Get(i).Valid())707{708grouppoints.Append (points.Get(i).P());709pindex.Append (i);710invpindex.Elem(i) = pindex.Size();711}712713for (i = 1; i <= faces.Size(); i++)714if (faces.Get(i).Valid())715{716int fused = 0;717for (j = 1; j <= 3; j++)718if (pingroup.Get(faces.Get(i).Face().PNum(j)))719fused++;720721if (fused >= 2)722{723groupelements.Append (faces.Get(i).Face());724findex.Append (i);725}726}727728for (i = 1; i <= groupelements.Size(); i++)729for (j = 1; j <= 3; j++)730{731groupelements.Elem(i).PNum(j) =732invpindex.Get(groupelements.Elem(i).PNum(j));733}734735/*736for (i = 1; i <= groupelements.Size(); i++)737for (j = 1; j <= 3; j++)738for (k = 1; k <= grouppoints.Size(); k++)739if (pindex.Get(k) == groupelements.Get(i).PNum(j))740{741groupelements.Elem(i).PNum(j) = k;742break;743}744*/745}746747748void AdFront3 :: SetStartFront (int /* baseelnp */)749{750INDEX i;751int j;752753for (i = 1; i <= faces.Size(); i++)754if (faces.Get(i).Valid())755{756const MiniElement2d & face = faces.Get(i).Face();757for (j = 1; j <= 3; j++)758points[face.PNum(j)].DecFrontNr(0);759}760761/*762if (baseelnp)763{764for (i = 1; i <= faces.Size(); i++)765if (faces.Get(i).Valid() && faces.Get(i).Face().GetNP() != baseelnp)766faces.Elem(i).qualclass = 1000;767}768*/769}770771772bool AdFront3 :: Inside (const Point<3> & p) const773{774int i, cnt;775Vec3d n, v1, v2;776DenseMatrix a(3), ainv(3);777Vector b(3), u(3);778779// random numbers:780n.X() = 0.123871;781n.Y() = 0.15432;782n.Z() = -0.43989;783784cnt = 0;785for (i = 1; i <= faces.Size(); i++)786if (faces.Get(i).Valid())787{788const Point<3> & p1 = points[faces.Get(i).Face().PNum(1)].P();789const Point<3> & p2 = points[faces.Get(i).Face().PNum(2)].P();790const Point<3> & p3 = points[faces.Get(i).Face().PNum(3)].P();791792v1 = p2 - p1;793v2 = p3 - p1;794795a.Elem(1, 1) = v1.X();796a.Elem(2, 1) = v1.Y();797a.Elem(3, 1) = v1.Z();798a.Elem(1, 2) = v2.X();799a.Elem(2, 2) = v2.Y();800a.Elem(3, 2) = v2.Z();801a.Elem(1, 3) = -n.X();802a.Elem(2, 3) = -n.Y();803a.Elem(3, 3) = -n.Z();804805b.Elem(1) = p(0) - p1(0);806b.Elem(2) = p(1) - p1(1);807b.Elem(3) = p(2) - p1(2);808809CalcInverse (a, ainv);810ainv.Mult (b, u);811812if (u.Elem(1) >= 0 && u.Elem(2) >= 0 && u.Elem(1)+u.Elem(2) <= 1 &&813u.Elem(3) > 0)814{815cnt++;816}817}818819return ((cnt % 2) != 0);820}821822823824825826int AdFront3 :: SameSide (const Point<3> & lp1, const Point<3> & lp2,827const ARRAY<int> * testfaces) const828{829int i, ii, cnt;830831const Point<3> *line[2];832line[0] = &lp1;833line[1] = &lp2;834835836cnt = 0;837838Point3d pmin(lp1);839Point3d pmax(lp1);840pmin.SetToMin (lp2);841pmax.SetToMax (lp2);842843static ARRAY<int> aprif;844aprif.SetSize(0);845846if (!testfaces)847facetree->GetIntersecting (pmin, pmax, aprif);848else849{850for (i = 1; i <= testfaces->Size(); i++)851aprif.Append (testfaces->Get(i));852}853854// (*testout) << "test ss, p1,p2 = " << lp1 << lp2 << ", inters = " << aprif.Size() << endl;855// for (i = 1; i <= faces.Size(); i++)856for (ii = 1; ii <= aprif.Size(); ii++)857{858i = aprif.Get(ii);859860if (faces.Get(i).Valid())861{862const Point<3> *tri[3];863tri[0] = &points[faces.Get(i).Face().PNum(1)].P();864tri[1] = &points[faces.Get(i).Face().PNum(2)].P();865tri[2] = &points[faces.Get(i).Face().PNum(3)].P();866867if (IntersectTriangleLine (&tri[0], &line[0]))868cnt++;869870}871}872873return ((cnt+1) % 2);874}875}876877878