Path: blob/devel/ElmerGUI/netgen/libsrc/meshing/meshing3.cpp
3206 views
#include <mystdlib.h>1#include "meshing.hpp"23namespace netgen4{56double minother;7double minwithoutother;8910111213MeshingStat3d :: MeshingStat3d ()14{15cntsucc = cnttrials = cntelem = qualclass = 0;16vol0 = h = 1;17problemindex = 1;18}192021Meshing3 :: Meshing3 (const string & rulefilename)22{23tolfak = 1;2425LoadRules (rulefilename.c_str(), NULL);26adfront = new AdFront3;2728problems.SetSize (rules.Size());29foundmap.SetSize (rules.Size());30canuse.SetSize (rules.Size());31ruleused.SetSize (rules.Size());3233for (int i = 1; i <= rules.Size(); i++)34{35problems.Elem(i) = new char[255];36foundmap.Elem(i) = 0;37canuse.Elem(i) = 0;38ruleused.Elem(i) = 0;39}40}414243Meshing3 :: Meshing3 (const char ** rulep)44{45tolfak = 1;4647LoadRules (NULL, rulep);48adfront = new AdFront3;4950problems.SetSize (rules.Size());51foundmap.SetSize (rules.Size());52canuse.SetSize (rules.Size());53ruleused.SetSize (rules.Size());5455for (int i = 0; i < rules.Size(); i++)56{57problems[i] = new char[255];58foundmap[i] = 0;59canuse[i] = 0;60ruleused[i] = 0;61}62}6364Meshing3 :: ~Meshing3 ()65{66delete adfront;67for (int i = 0; i < rules.Size(); i++)68{69delete [] problems[i];70delete rules[i];71}72}73747576static double CalcLocH (const ARRAY<Point3d> & locpoints,77const ARRAY<MiniElement2d> & locfaces,78double h)79{80return h;8182// was war das ????8384int i, j;85double hi, h1, d, dn, sum, weight, wi;86Point3d p0, pc;87Vec3d n, v1, v2;8889p0.X() = p0.Y() = p0.Z() = 0;90for (j = 1; j <= 3; j++)91{92p0.X() += locpoints.Get(locfaces.Get(1).PNum(j)).X();93p0.Y() += locpoints.Get(locfaces.Get(1).PNum(j)).Y();94p0.Z() += locpoints.Get(locfaces.Get(1).PNum(j)).Z();95}96p0.X() /= 3; p0.Y() /= 3; p0.Z() /= 3;9798v1 = locpoints.Get(locfaces.Get(1).PNum(2)) -99locpoints.Get(locfaces.Get(1).PNum(1));100v2 = locpoints.Get(locfaces.Get(1).PNum(3)) -101locpoints.Get(locfaces.Get(1).PNum(1));102103h1 = v1.Length();104n = Cross (v2, v1);105n /= n.Length();106107sum = 0;108weight = 0;109110for (i = 1; i <= locfaces.Size(); i++)111{112pc.X() = pc.Y() = pc.Z() = 0;113for (j = 1; j <= 3; j++)114{115pc.X() += locpoints.Get(locfaces.Get(i).PNum(j)).X();116pc.Y() += locpoints.Get(locfaces.Get(i).PNum(j)).Y();117pc.Z() += locpoints.Get(locfaces.Get(i).PNum(j)).Z();118}119pc.X() /= 3; pc.Y() /= 3; pc.Z() /= 3;120121d = Dist (p0, pc);122dn = n * (pc - p0);123hi = Dist (locpoints.Get(locfaces.Get(i).PNum(1)),124locpoints.Get(locfaces.Get(i).PNum(2)));125126if (dn > -0.2 * h1)127{128wi = 1 / (h1 + d);129wi *= wi;130}131else132wi = 0;133134sum += hi * wi;135weight += wi;136}137138return sum/weight;139}140141142PointIndex Meshing3 :: AddPoint (const Point3d & p, PointIndex globind)143{144return adfront -> AddPoint (p, globind);145}146147void Meshing3 :: AddBoundaryElement (const Element2d & elem)148{149MiniElement2d mini(elem.GetNP());150for (int j = 0; j < elem.GetNP(); j++)151mini[j] = elem[j];152adfront -> AddFace(mini);153}154155156void Meshing3 :: AddBoundaryElement (const MiniElement2d & elem)157{158adfront -> AddFace(elem);159}160161int Meshing3 :: AddConnectedPair (const INDEX_2 & apair)162{163return adfront -> AddConnectedPair (apair);164}165166MESHING3_RESULT Meshing3 ::167GenerateMesh (Mesh & mesh, const MeshingParameters & mp)168{169static int meshing3_timer = NgProfiler::CreateTimer ("Meshing3::GenerateMesh");170static int meshing3_timer_a = NgProfiler::CreateTimer ("Meshing3::GenerateMesh a");171static int meshing3_timer_b = NgProfiler::CreateTimer ("Meshing3::GenerateMesh b");172static int meshing3_timer_c = NgProfiler::CreateTimer ("Meshing3::GenerateMesh c");173static int meshing3_timer_d = NgProfiler::CreateTimer ("Meshing3::GenerateMesh d");174NgProfiler::RegionTimer reg (meshing3_timer);175176177ARRAY<Point3d > locpoints; // local points178ARRAY<MiniElement2d> locfaces; // local faces179ARRAY<PointIndex> pindex; // mapping from local to front point numbering180ARRAY<int> allowpoint; // point is allowd ?181ARRAY<INDEX> findex; // mapping from local to front face numbering182//INDEX_2_HASHTABLE<int> connectedpairs(100); // connecgted pairs for prism meshing183184ARRAY<Point3d > plainpoints; // points in reference coordinates185ARRAY<int> delpoints, delfaces; // points and lines to be deleted186ARRAY<Element> locelements; // new generated elements187188int i, j, oldnp, oldnf;189int found;190referencetransform trans;191int rotind;192INDEX globind;193Point3d inp;194float err;195196INDEX locfacesplit; //index for faces in outer area197198bool loktestmode = false;199200int uselocalh = mp.uselocalh;201202// int giveuptol = mp.giveuptol; //203MeshingStat3d stat; // statistics204int plotstat_oldne = -1;205206207// for star-shaped domain meshing208ARRAY<MeshPoint> grouppoints;209ARRAY<MiniElement2d> groupfaces;210ARRAY<PointIndex> grouppindex;211ARRAY<INDEX> groupfindex;212213214float minerr;215int hasfound;216double tetvol;217// int giveup = 0;218219220ARRAY<Point3d> tempnewpoints;221ARRAY<MiniElement2d> tempnewfaces;222ARRAY<int> tempdelfaces;223ARRAY<Element> templocelements;224225226stat.h = mp.maxh;227228adfront->SetStartFront (mp.baseelnp);229230231found = 0;232stat.vol0 = adfront -> Volume();233tetvol = 0;234235stat.qualclass = 1;236237while (1)238{239if (multithread.terminate)240throw NgException ("Meshing stopped");241242// break if advancing front is empty243if (!mp.baseelnp && adfront->Empty())244break;245246// break, if advancing front has no elements with247// mp.baseelnp nodes248if (mp.baseelnp && adfront->Empty (mp.baseelnp))249break;250251locpoints.SetSize(0);252locfaces.SetSize(0);253locelements.SetSize(0);254pindex.SetSize(0);255findex.SetSize(0);256257INDEX_2_HASHTABLE<int> connectedpairs(100); // connected pairs for prism meshing258259// select base-element (will be locface[1])260// and get local environment of radius (safety * h)261262263int baseelem = adfront -> SelectBaseElement ();264if (mp.baseelnp && adfront->GetFace (baseelem).GetNP() != mp.baseelnp)265{266adfront->IncrementClass (baseelem);267continue;268}269270const MiniElement2d & bel = adfront->GetFace (baseelem);271const Point3d & p1 = adfront->GetPoint (bel.PNum(1));272const Point3d & p2 = adfront->GetPoint (bel.PNum(2));273const Point3d & p3 = adfront->GetPoint (bel.PNum(3));274275// (*testout) << endl << "base = " << bel << endl;276277278Point3d pmid = Center (p1, p2, p3);279280double his = (Dist (p1, p2) + Dist(p1, p3) + Dist(p2, p3)) / 3;281double hshould;282283hshould = mesh.GetH (pmid);284285if (adfront->GetFace (baseelem).GetNP() == 4)286hshould = max2 (his, hshould);287288double hmax = (his > hshould) ? his : hshould;289290// qualclass should come from baseelem !!!!!291double hinner = hmax * (1 + stat.qualclass);292double houter = hmax * (1 + 2 * stat.qualclass);293294NgProfiler::StartTimer (meshing3_timer_a);295stat.qualclass =296adfront -> GetLocals (baseelem, locpoints, locfaces,297pindex, findex, connectedpairs,298houter, hinner,299locfacesplit);300NgProfiler::StopTimer (meshing3_timer_a);301302// (*testout) << "locfaces = " << endl << locfaces << endl;303304int pi1 = pindex.Get(locfaces[0].PNum(1));305int pi2 = pindex.Get(locfaces[0].PNum(2));306int pi3 = pindex.Get(locfaces[0].PNum(3));307308//loktestmode = 1;309testmode = loktestmode; //changed310// loktestmode = testmode = (adfront->GetFace (baseelem).GetNP() == 4) && (rules.Size() == 5);311312loktestmode = stat.qualclass > 5;313314315if (loktestmode)316{317(*testout) << "baseel = " << baseelem << ", ind = " << findex.Get(1) << endl;318(*testout) << "pi = " << pi1 << ", " << pi2 << ", " << pi3 << endl;319}320321322323324325if (testmode)326{327(*testout) << "baseelem = " << baseelem << " qualclass = " << stat.qualclass << endl;328(*testout) << "locpoints = " << endl << locpoints << endl;329(*testout) << "connected = " << endl << connectedpairs << endl;330}331332333334// loch = CalcLocH (locpoints, locfaces, h);335336stat.nff = adfront->GetNF();337stat.vol = adfront->Volume();338if (stat.vol < 0) break;339340oldnp = locpoints.Size();341oldnf = locfaces.Size();342343344allowpoint.SetSize(locpoints.Size());345if (uselocalh && stat.qualclass <= 3)346for (i = 1; i <= allowpoint.Size(); i++)347{348allowpoint.Elem(i) =349(mesh.GetH (locpoints.Get(i)) > 0.4 * hshould / mp.sloppy) ? 2 : 1;350}351else352allowpoint = 2;353354355356if (stat.qualclass >= mp.starshapeclass &&357mp.baseelnp != 4)358{359NgProfiler::RegionTimer reg1 (meshing3_timer_b);360// star-shaped domain removing361362grouppoints.SetSize (0);363groupfaces.SetSize (0);364grouppindex.SetSize (0);365groupfindex.SetSize (0);366367adfront -> GetGroup (findex[0], grouppoints, groupfaces,368grouppindex, groupfindex);369370bool onlytri = 1;371for (i = 0; i < groupfaces.Size(); i++)372if (groupfaces[i].GetNP() != 3)373onlytri = 0;374375if (onlytri && groupfaces.Size() <= 20 + 2*stat.qualclass &&376FindInnerPoint (grouppoints, groupfaces, inp))377{378(*testout) << "inner point found" << endl;379380for (i = 1; i <= groupfaces.Size(); i++)381adfront -> DeleteFace (groupfindex.Get(i));382383for (i = 1; i <= groupfaces.Size(); i++)384for (j = 1; j <= locfaces.Size(); j++)385if (findex.Get(j) == groupfindex.Get(i))386delfaces.Append (j);387388389delfaces.SetSize (0);390391INDEX npi;392Element newel;393394npi = mesh.AddPoint (inp);395newel.SetNP(4);396newel.PNum(4) = npi;397398for (i = 1; i <= groupfaces.Size(); i++)399{400for (j = 1; j <= 3; j++)401{402newel.PNum(j) =403adfront->GetGlobalIndex404(grouppindex.Get(groupfaces.Get(i).PNum(j)));405}406mesh.AddVolumeElement (newel);407}408continue;409}410}411412found = 0;413hasfound = 0;414minerr = 1e6;415416// int optother = 0;417418/*419for (i = 1; i <= locfaces.Size(); i++)420{421(*testout) << "Face " << i << ": ";422for (j = 1; j <= locfaces.Get(i).GetNP(); j++)423(*testout) << pindex.Get(locfaces.Get(i).PNum(j)) << " ";424(*testout) << endl;425}426for (i = 1; i <= locpoints.Size(); i++)427{428(*testout) << "p" << i429<< ", gi = " << pindex.Get(i)430<< " = " << locpoints.Get(i) << endl;431}432*/433434minother = 1e10;435minwithoutother = 1e10;436437bool impossible = 1;438439for (rotind = 1; rotind <= locfaces[0].GetNP(); rotind++)440{441// set transformatino to reference coordinates442443if (locfaces.Get(1).GetNP() == 3)444{445trans.Set (locpoints.Get(locfaces.Get(1).PNumMod(1+rotind)),446locpoints.Get(locfaces.Get(1).PNumMod(2+rotind)),447locpoints.Get(locfaces.Get(1).PNumMod(3+rotind)), hshould);448}449else450{451trans.Set (locpoints.Get(locfaces.Get(1).PNumMod(1+rotind)),452locpoints.Get(locfaces.Get(1).PNumMod(2+rotind)),453locpoints.Get(locfaces.Get(1).PNumMod(4+rotind)), hshould);454}455456trans.ToPlain (locpoints, plainpoints);457458459for (i = 1; i <= allowpoint.Size(); i++)460{461if (plainpoints.Get(i).Z() > 0)462{463//if(loktestmode)464// (*testout) << "plainpoints.Get(i).Z() = " << plainpoints.Get(i).Z() << " > 0" << endl;465allowpoint.Elem(i) = 0;466}467}468469stat.cnttrials++;470471472if (stat.cnttrials % 100 == 0)473{474(*testout) << "\n";475for (i = 1; i <= canuse.Size(); i++)476{477(*testout) << foundmap.Get(i) << "/"478<< canuse.Get(i) << "/"479<< ruleused.Get(i) << " map/can/use rule " << rules.Get(i)->Name() << "\n";480}481(*testout) << endl;482}483484NgProfiler::StartTimer (meshing3_timer_c);485486found = ApplyRules (plainpoints, allowpoint,487locfaces, locfacesplit, connectedpairs,488locelements, delfaces,489stat.qualclass, mp.sloppy, rotind, err);490491if (found >= 0) impossible = 0;492if (found < 0) found = 0;493494495NgProfiler::StopTimer (meshing3_timer_c);496497if (!found) loktestmode = 0;498499NgProfiler::RegionTimer reg2 (meshing3_timer_d);500501if (loktestmode)502{503(*testout) << "plainpoints = " << endl << plainpoints << endl;504(*testout) << "Applyrules found " << found << endl;505}506507if (found) stat.cntsucc++;508509locpoints.SetSize (plainpoints.Size());510for (i = oldnp+1; i <= plainpoints.Size(); i++)511trans.FromPlain (plainpoints.Elem(i), locpoints.Elem(i));512513514515// avoid meshing from large to small mesh-size516if (uselocalh && found && stat.qualclass <= 3)517{518for (i = 1; i <= locelements.Size(); i++)519{520Point3d pmin = locpoints.Get(locelements.Get(i).PNum(1));521Point3d pmax = pmin;522for (j = 2; j <= 4; j++)523{524const Point3d & hp = locpoints.Get(locelements.Get(i).PNum(j));525pmin.SetToMin (hp);526pmax.SetToMax (hp);527}528529if (mesh.GetMinH (pmin, pmax) < 0.4 * hshould / mp.sloppy)530found = 0;531}532}533if (found)534{535for (i = 1; i <= locelements.Size(); i++)536for (j = 1; j <= 4; j++)537{538const Point3d & hp = locpoints.Get(locelements.Get(i).PNum(j));539if (Dist (hp, pmid) > hinner)540found = 0;541}542}543544545if (found)546ruleused.Elem(found)++;547548549// plotstat->Plot(stat);550551if (stat.cntelem != plotstat_oldne)552{553plotstat_oldne = stat.cntelem;554555PrintMessageCR (5, "El: ", stat.cntelem,556// << " trials: " << stat.cnttrials557" faces: ", stat.nff,558" vol = ", float(100 * stat.vol / stat.vol0));559560multithread.percent = 100 - 100.0 * stat.vol / stat.vol0;561}562563564if (found && (!hasfound || err < minerr) )565{566567if (testmode)568{569(*testout) << "found is active, 3" << endl;570for (i = 1; i <= plainpoints.Size(); i++)571{572(*testout) << "p";573if (i <= pindex.Size())574(*testout) << pindex.Get(i) << ": ";575else576(*testout) << "new: ";577(*testout) << plainpoints.Get(i) << endl;578}579}580581582583hasfound = found;584minerr = err;585586tempnewpoints.SetSize (0);587for (i = oldnp+1; i <= locpoints.Size(); i++)588tempnewpoints.Append (locpoints.Get(i));589590tempnewfaces.SetSize (0);591for (i = oldnf+1; i <= locfaces.Size(); i++)592tempnewfaces.Append (locfaces.Get(i));593594tempdelfaces.SetSize (0);595for (i = 1; i <= delfaces.Size(); i++)596tempdelfaces.Append (delfaces.Get(i));597598templocelements.SetSize (0);599for (i = 1; i <= locelements.Size(); i++)600templocelements.Append (locelements.Get(i));601602/*603optother =604strcmp (problems[found], "other") == 0;605*/606}607608locpoints.SetSize (oldnp);609locfaces.SetSize (oldnf);610delfaces.SetSize (0);611locelements.SetSize (0);612}613614615616if (hasfound)617{618619/*620if (optother)621(*testout) << "Other is optimal" << endl;622623if (minother < minwithoutother)624{625(*testout) << "Other is better, " << minother << " less " << minwithoutother << endl;626}627*/628629for (i = 1; i <= tempnewpoints.Size(); i++)630locpoints.Append (tempnewpoints.Get(i));631for (i = 1; i <= tempnewfaces.Size(); i++)632locfaces.Append (tempnewfaces.Get(i));633for (i = 1; i <= tempdelfaces.Size(); i++)634delfaces.Append (tempdelfaces.Get(i));635for (i = 1; i <= templocelements.Size(); i++)636locelements.Append (templocelements.Get(i));637638639if (loktestmode)640{641(*testout) << "apply rule" << endl;642for (i = 1; i <= locpoints.Size(); i++)643{644(*testout) << "p";645if (i <= pindex.Size())646(*testout) << pindex.Get(i) << ": ";647else648(*testout) << "new: ";649(*testout) << locpoints.Get(i) << endl;650}651}652653654655pindex.SetSize(locpoints.Size());656657for (i = oldnp+1; i <= locpoints.Size(); i++)658{659globind = mesh.AddPoint (locpoints.Get(i));660pindex.Elem(i) = adfront -> AddPoint (locpoints.Get(i), globind);661}662663for (i = 1; i <= locelements.Size(); i++)664{665Point3d * hp1, * hp2, * hp3, * hp4;666hp1 = &locpoints.Elem(locelements.Get(i).PNum(1));667hp2 = &locpoints.Elem(locelements.Get(i).PNum(2));668hp3 = &locpoints.Elem(locelements.Get(i).PNum(3));669hp4 = &locpoints.Elem(locelements.Get(i).PNum(4));670671tetvol += (1.0 / 6.0) * ( Cross ( *hp2 - *hp1, *hp3 - *hp1) * (*hp4 - *hp1) );672673for (j = 1; j <= locelements.Get(i).NP(); j++)674locelements.Elem(i).PNum(j) =675adfront -> GetGlobalIndex (pindex.Get(locelements.Get(i).PNum(j)));676677mesh.AddVolumeElement (locelements.Get(i));678stat.cntelem++;679}680681for (i = oldnf+1; i <= locfaces.Size(); i++)682{683for (j = 1; j <= locfaces.Get(i).GetNP(); j++)684locfaces.Elem(i).PNum(j) =685pindex.Get(locfaces.Get(i).PNum(j));686// (*testout) << "add face " << locfaces.Get(i) << endl;687adfront->AddFace (locfaces.Get(i));688}689690for (i = 1; i <= delfaces.Size(); i++)691adfront->DeleteFace (findex.Get(delfaces.Get(i)));692}693else694{695adfront->IncrementClass (findex.Get(1));696if (impossible && mp.check_impossible)697{698(*testout) << "skip face since it is impossible" << endl;699for (j = 0; j < 100; j++)700adfront->IncrementClass (findex.Get(1));701}702}703704locelements.SetSize (0);705delpoints.SetSize(0);706delfaces.SetSize(0);707708if (stat.qualclass >= mp.giveuptol)709break;710}711712PrintMessage (5, ""); // line feed after statistics713714for (i = 1; i <= ruleused.Size(); i++)715(*testout) << setw(4) << ruleused.Get(i)716<< " times used rule " << rules.Get(i) -> Name() << endl;717718719if (!mp.baseelnp && adfront->Empty())720return MESHING3_OK;721722if (mp.baseelnp && adfront->Empty (mp.baseelnp))723return MESHING3_OK;724725if (stat.vol < -1e-15)726return MESHING3_NEGVOL;727728return MESHING3_NEGVOL;729}730731732733734enum blocktyp { BLOCKUNDEF, BLOCKINNER, BLOCKBOUND, BLOCKOUTER };735736void Meshing3 :: BlockFill (Mesh & mesh, double gh)737{738PrintMessage (3, "Block-filling called (obsolete) ");739740int i, j(0), i1, i2, i3, j1, j2, j3;741int n1, n2, n3, n, min1, min2, min3, max1, max2, max3;742int changed, filled;743double xmin(0), xmax(0), ymin(0), ymax(0), zmin(0), zmax(0);744double xminb, xmaxb, yminb, ymaxb, zminb, zmaxb;745//double rad = 0.7 * gh;746747for (i = 1; i <= adfront->GetNP(); i++)748{749const Point3d & p = adfront->GetPoint(i);750if (i == 1)751{752xmin = xmax = p.X();753ymin = ymax = p.Y();754zmin = zmax = p.Z();755}756else757{758if (p.X() < xmin) xmin = p.X();759if (p.X() > xmax) xmax = p.X();760if (p.Y() < ymin) ymin = p.Y();761if (p.Y() > ymax) ymax = p.Y();762if (p.Z() < zmin) zmin = p.Z();763if (p.Z() > zmax) zmax = p.Z();764}765}766767xmin -= 5 * gh;768ymin -= 5 * gh;769zmin -= 5 * gh;770771n1 = int ((xmax-xmin) / gh + 5);772n2 = int ((ymax-ymin) / gh + 5);773n3 = int ((zmax-zmin) / gh + 5);774n = n1 * n2 * n3;775776PrintMessage (5, "n1 = ", n1, " n2 = ", n2, " n3 = ", n3);777778ARRAY<blocktyp> inner(n);779ARRAY<int> pointnr(n), frontpointnr(n);780781782// initialize inner to 1783784for (i = 1; i <= n; i++)785inner.Elem(i) = BLOCKUNDEF;786787788// set blocks cutting surfaces to 0789790for (i = 1; i <= adfront->GetNF(); i++)791{792const MiniElement2d & el = adfront->GetFace(i);793xminb = xmax; xmaxb = xmin;794yminb = ymax; ymaxb = ymin;795zminb = zmax; zmaxb = zmin;796797for (j = 1; j <= 3; j++)798{799const Point3d & p = adfront->GetPoint (el.PNum(j));800if (p.X() < xminb) xminb = p.X();801if (p.X() > xmaxb) xmaxb = p.X();802if (p.Y() < yminb) yminb = p.Y();803if (p.Y() > ymaxb) ymaxb = p.Y();804if (p.Z() < zminb) zminb = p.Z();805if (p.Z() > zmaxb) zmaxb = p.Z();806}807808809810double filldist = 0.2; // globflags.GetNumFlag ("filldist", 0.4);811xminb -= filldist * gh;812xmaxb += filldist * gh;813yminb -= filldist * gh;814ymaxb += filldist * gh;815zminb -= filldist * gh;816zmaxb += filldist * gh;817818min1 = int ((xminb - xmin) / gh) + 1;819max1 = int ((xmaxb - xmin) / gh) + 1;820min2 = int ((yminb - ymin) / gh) + 1;821max2 = int ((ymaxb - ymin) / gh) + 1;822min3 = int ((zminb - zmin) / gh) + 1;823max3 = int ((zmaxb - zmin) / gh) + 1;824825826for (i1 = min1; i1 <= max1; i1++)827for (i2 = min2; i2 <= max2; i2++)828for (i3 = min3; i3 <= max3; i3++)829inner.Elem(i3 + (i2-1) * n3 + (i1-1) * n2 * n3) = BLOCKBOUND;830}831832833834835while (1)836{837int undefi = 0;838Point3d undefp;839840for (i1 = 1; i1 <= n1 && !undefi; i1++)841for (i2 = 1; i2 <= n2 && !undefi; i2++)842for (i3 = 1; i3 <= n3 && !undefi; i3++)843{844i = i3 + (i2-1) * n3 + (i1-1) * n2 * n3;845if (inner.Elem(i) == BLOCKUNDEF)846{847undefi = i;848undefp.X() = xmin + (i1-0.5) * gh;849undefp.Y() = ymin + (i2-0.5) * gh;850undefp.Z() = zmin + (i3-0.5) * gh;851}852}853854if (!undefi)855break;856857// PrintMessage (5, "Test point: ", undefp);858859if (adfront -> Inside (undefp))860{861// (*mycout) << "inner" << endl;862inner.Elem(undefi) = BLOCKINNER;863}864else865{866// (*mycout) << "outer" << endl;867inner.Elem(undefi) = BLOCKOUTER;868}869870do871{872changed = 0;873for (i1 = 1; i1 <= n1; i1++)874for (i2 = 1; i2 <= n2; i2++)875for (i3 = 1; i3 <= n3; i3++)876{877i = i3 + (i2-1) * n3 + (i1-1) * n2 * n3;878879for (int k = 1; k <= 3; k++)880{881switch (k)882{883case 1: j = i + n2 * n3; break;884case 2: j = i + n3; break;885case 3: j = i + 1; break;886}887888if (j > n1 * n2 * n3) continue;889890if (inner.Elem(i) == BLOCKOUTER && inner.Elem(j) == BLOCKUNDEF)891{892changed = 1;893inner.Elem(j) = BLOCKOUTER;894}895if (inner.Elem(j) == BLOCKOUTER && inner.Elem(i) == BLOCKUNDEF)896{897changed = 1;898inner.Elem(i) = BLOCKOUTER;899}900if (inner.Elem(i) == BLOCKINNER && inner.Elem(j) == BLOCKUNDEF)901{902changed = 1;903inner.Elem(j) = BLOCKINNER;904}905if (inner.Elem(j) == BLOCKINNER && inner.Elem(i) == BLOCKUNDEF)906{907changed = 1;908inner.Elem(i) = BLOCKINNER;909}910}911}912}913while (changed);914915}916917918919filled = 0;920for (i = 1; i <= n; i++)921if (inner.Elem(i) == BLOCKINNER)922{923filled++;924}925PrintMessage (5, "Filled blocks: ", filled);926927for (i = 1; i <= n; i++)928{929pointnr.Elem(i) = 0;930frontpointnr.Elem(i) = 0;931}932933for (i1 = 1; i1 <= n1-1; i1++)934for (i2 = 1; i2 <= n2-1; i2++)935for (i3 = 1; i3 <= n3-1; i3++)936{937i = i3 + (i2-1) * n3 + (i1-1) * n2 * n3;938if (inner.Elem(i) == BLOCKINNER)939{940for (j1 = i1; j1 <= i1+1; j1++)941for (j2 = i2; j2 <= i2+1; j2++)942for (j3 = i3; j3 <= i3+1; j3++)943{944j = j3 + (j2-1) * n3 + (j1-1) * n2 * n3;945if (pointnr.Get(j) == 0)946{947Point3d hp(xmin + (j1-1) * gh,948ymin + (j2-1) * gh,949zmin + (j3-1) * gh);950pointnr.Elem(j) = mesh.AddPoint (hp);951frontpointnr.Elem(j) =952AddPoint (hp, pointnr.Elem(j));953954}955}956}957}958959960for (i1 = 2; i1 <= n1-1; i1++)961for (i2 = 2; i2 <= n2-1; i2++)962for (i3 = 2; i3 <= n3-1; i3++)963{964i = i3 + (i2-1) * n3 + (i1-1) * n2 * n3;965if (inner.Elem(i) == BLOCKINNER)966{967int pn[9];968pn[1] = pointnr.Get(i);969pn[2] = pointnr.Get(i+1);970pn[3] = pointnr.Get(i+n3);971pn[4] = pointnr.Get(i+n3+1);972pn[5] = pointnr.Get(i+n2*n3);973pn[6] = pointnr.Get(i+n2*n3+1);974pn[7] = pointnr.Get(i+n2*n3+n3);975pn[8] = pointnr.Get(i+n2*n3+n3+1);976static int elind[][4] =977{978{ 1, 8, 2, 4 },979{ 1, 8, 4, 3 },980{ 1, 8, 3, 7 },981{ 1, 8, 7, 5 },982{ 1, 8, 5, 6 },983{ 1, 8, 6, 2 }984};985for (j = 1; j <= 6; j++)986{987Element el(4);988for (int k = 1; k <= 4; k++)989el.PNum(k) = pn[elind[j-1][k-1]];990991mesh.AddVolumeElement (el);992}993}994}995996997998for (i1 = 2; i1 <= n1-1; i1++)999for (i2 = 2; i2 <= n2-1; i2++)1000for (i3 = 2; i3 <= n3-1; i3++)1001{1002i = i3 + (i2-1) * n3 + (i1-1) * n2 * n3;1003if (inner.Elem(i) == BLOCKINNER)1004{1005int pi1(0), pi2(0), pi3(0), pi4(0);10061007int pn1 = frontpointnr.Get(i);1008int pn2 = frontpointnr.Get(i+1);1009int pn3 = frontpointnr.Get(i+n3);1010int pn4 = frontpointnr.Get(i+n3+1);1011int pn5 = frontpointnr.Get(i+n2*n3);1012int pn6 = frontpointnr.Get(i+n2*n3+1);1013int pn7 = frontpointnr.Get(i+n2*n3+n3);1014int pn8 = frontpointnr.Get(i+n2*n3+n3+1);10151016for (int k = 1; k <= 6; k++)1017{1018switch (k)1019{1020case 1: // j3 = i3+11021j = i + 1;1022pi1 = pn2;1023pi2 = pn6;1024pi3 = pn4;1025pi4 = pn8;1026break;1027case 2: // j3 = i3-11028j = i - 1;1029pi1 = pn1;1030pi2 = pn3;1031pi3 = pn5;1032pi4 = pn7;1033break;1034case 3: // j2 = i2+11035j = i + n3;1036pi1 = pn3;1037pi2 = pn4;1038pi3 = pn7;1039pi4 = pn8;1040break;1041case 4: // j2 = i2-11042j = i - n3;1043pi1 = pn1;1044pi2 = pn5;1045pi3 = pn2;1046pi4 = pn6;1047break;1048case 5: // j1 = i1+11049j = i + n3*n2;1050pi1 = pn5;1051pi2 = pn7;1052pi3 = pn6;1053pi4 = pn8;1054break;1055case 6: // j1 = i1-11056j = i - n3*n2;1057pi1 = pn1;1058pi2 = pn2;1059pi3 = pn3;1060pi4 = pn4;1061break;1062}10631064if (inner.Get(j) == BLOCKBOUND)1065{1066MiniElement2d face;1067face.PNum(1) = pi4;1068face.PNum(2) = pi1;1069face.PNum(3) = pi3;1070AddBoundaryElement (face);10711072face.PNum(1) = pi1;1073face.PNum(2) = pi4;1074face.PNum(3) = pi2;1075AddBoundaryElement (face);10761077}1078}1079}1080}1081}1082108310841085static const AdFront3 * locadfront;1086static int TestInner (const Point3d & p)1087{1088return locadfront->Inside (p);1089}1090static int TestSameSide (const Point3d & p1, const Point3d & p2)1091{1092return locadfront->SameSide (p1, p2);1093}10941095109610971098void Meshing3 :: BlockFillLocalH (Mesh & mesh,1099const MeshingParameters & mp)1100{1101int i, j;11021103double filldist = mp.filldist;11041105(*testout) << "blockfill local h" << endl;1106(*testout) << "rel filldist = " << filldist << endl;1107PrintMessage (3, "blockfill local h");11081109/*1110(*mycout) << "boxes: " << mesh.LocalHFunction().GetNBoxes() << endl1111<< "filldist = " << filldist << endl;1112*/1113ARRAY<Point3d> npoints;11141115adfront -> CreateTrees();11161117Point3d mpmin, mpmax;1118// mesh.GetBox (mpmin, mpmax);1119bool firstp = 1;11201121double maxh = 0;1122for (i = 1; i <= adfront->GetNF(); i++)1123{1124const MiniElement2d & el = adfront->GetFace(i);1125for (j = 1; j <= 3; j++)1126{1127const Point3d & p1 = adfront->GetPoint (el.PNumMod(j));1128const Point3d & p2 = adfront->GetPoint (el.PNumMod(j+1));1129double hi = Dist (p1, p2);1130if (hi > maxh)1131{1132maxh = hi;1133//(*testout) << "reducing maxh to " << maxh << " because of " << p1 << " and " << p2 << endl;1134}11351136if (firstp)1137{1138mpmin = p1;1139mpmax = p1;1140firstp = 0;1141}1142else1143{1144mpmin.SetToMin (p1);1145mpmax.SetToMax (p1);1146}1147}1148}11491150Point3d mpc = Center (mpmin, mpmax);1151double d = max3(mpmax.X()-mpmin.X(),1152mpmax.Y()-mpmin.Y(),1153mpmax.Z()-mpmin.Z()) / 2;1154mpmin = mpc - Vec3d (d, d, d);1155mpmax = mpc + Vec3d (d, d, d);1156Box3d meshbox (mpmin, mpmax);11571158LocalH loch2 (mpmin, mpmax, 1);115911601161if (mp.maxh < maxh)1162{1163maxh = mp.maxh;1164//(*testout) << "reducing maxh to " << maxh << " because of mp.maxh" << endl;1165}11661167int changed;1168do1169{1170mesh.LocalHFunction().ClearFlags();11711172for (i = 1; i <= adfront->GetNF(); i++)1173{1174const MiniElement2d & el = adfront->GetFace(i);1175Point3d pmin = adfront->GetPoint (el.PNum(1));1176Point3d pmax = pmin;11771178for (j = 2; j <= 3; j++)1179{1180const Point3d & p = adfront->GetPoint (el.PNum(j));1181pmin.SetToMin (p);1182pmax.SetToMax (p);1183}118411851186double filld = filldist * Dist (pmin, pmax);11871188pmin = pmin - Vec3d (filld, filld, filld);1189pmax = pmax + Vec3d (filld, filld, filld);1190// (*testout) << "cut : " << pmin << " - " << pmax << endl;1191mesh.LocalHFunction().CutBoundary (pmin, pmax);1192}11931194locadfront = adfront;1195mesh.LocalHFunction().FindInnerBoxes (adfront, NULL);11961197npoints.SetSize(0);1198mesh.LocalHFunction().GetInnerPoints (npoints);11991200changed = 0;1201for (i = 1; i <= npoints.Size(); i++)1202{1203if (mesh.LocalHFunction().GetH(npoints.Get(i)) > 1.5 * maxh)1204{1205mesh.LocalHFunction().SetH (npoints.Get(i), maxh);1206changed = 1;1207}1208}1209}1210while (changed);12111212if (debugparam.slowchecks)1213(*testout) << "Blockfill with points: " << endl;1214for (i = 1; i <= npoints.Size(); i++)1215{1216if (meshbox.IsIn (npoints.Get(i)))1217{1218int gpnum = mesh.AddPoint (npoints.Get(i));1219adfront->AddPoint (npoints.Get(i), gpnum);12201221if (debugparam.slowchecks)1222{1223(*testout) << npoints.Get(i) << endl;1224if (!adfront->Inside(npoints.Get(i)))1225{1226cout << "add outside point" << endl;1227(*testout) << "outside" << endl;1228}1229}12301231}1232}1233123412351236// find outer points12371238loch2.ClearFlags();12391240for (i = 1; i <= adfront->GetNF(); i++)1241{1242const MiniElement2d & el = adfront->GetFace(i);1243Point3d pmin = adfront->GetPoint (el.PNum(1));1244Point3d pmax = pmin;12451246for (j = 2; j <= 3; j++)1247{1248const Point3d & p = adfront->GetPoint (el.PNum(j));1249pmin.SetToMin (p);1250pmax.SetToMax (p);1251}12521253loch2.SetH (Center (pmin, pmax), Dist (pmin, pmax));1254}12551256for (i = 1; i <= adfront->GetNF(); i++)1257{1258const MiniElement2d & el = adfront->GetFace(i);1259Point3d pmin = adfront->GetPoint (el.PNum(1));1260Point3d pmax = pmin;12611262for (j = 2; j <= 3; j++)1263{1264const Point3d & p = adfront->GetPoint (el.PNum(j));1265pmin.SetToMin (p);1266pmax.SetToMax (p);1267}12681269double filld = filldist * Dist (pmin, pmax);1270pmin = pmin - Vec3d (filld, filld, filld);1271pmax = pmax + Vec3d (filld, filld, filld);1272loch2.CutBoundary (pmin, pmax);1273}12741275locadfront = adfront;1276loch2.FindInnerBoxes (adfront, NULL);12771278npoints.SetSize(0);1279loch2.GetOuterPoints (npoints);12801281for (i = 1; i <= npoints.Size(); i++)1282{1283if (meshbox.IsIn (npoints.Get(i)))1284{1285int gpnum = mesh.AddPoint (npoints.Get(i));1286adfront->AddPoint (npoints.Get(i), gpnum);1287}1288}1289}12901291}129212931294