Path: blob/devel/ElmerGUI/netgen/libsrc/csg/identify.cpp
3206 views
#include <mystdlib.h>1#include <myadt.hpp>23#include <linalg.hpp>4#include <csg.hpp>5#include <meshing.hpp>678namespace netgen9{10Identification :: Identification (int anr, const CSGeometry & ageom)11: geom(ageom), identfaces(10)12{13nr = anr;14}1516Identification :: ~Identification ()17{18;19}202122ostream & operator<< (ostream & ost, Identification & ident)23{24ident.Print (ost);25return ost;26}272829/*30void Identification :: IdentifySpecialPoints (ARRAY<class SpecialPoint> & points)31{32;33}34*/353637int Identification ::38Identifyable (const SpecialPoint & sp1, const SpecialPoint & sp2,39const TABLE<int> & specpoint2solid,40const TABLE<int> & specpoint2surface) const41{42cout << "Identification::Identifyable called for base-class" << endl;43return 0;44}4546int Identification ::47Identifyable (const Point<3> & p1, const Point<3> & sp2) const48{49cout << "Identification::Identifyable called for base-class" << endl;50return 0;51}525354int Identification ::55IdentifyableCandidate (const SpecialPoint & sp1) const56{57return 1;58}596061int Identification ::62ShortEdge (const SpecialPoint & sp1, const SpecialPoint & sp2) const63{64return 0;65}6667int Identification :: GetIdentifiedPoint (class Mesh & mesh, int pi)68{69cout << "Identification::GetIdentifiedPoint called for base-class" << endl;70return -1;71}7273void Identification :: IdentifyPoints (Mesh & mesh)74{75cout << "Identification::IdentifyPoints called for base-class" << endl;76;77}7879void Identification :: IdentifyFaces (class Mesh & mesh)80{81cout << "Identification::IdentifyFaces called for base-class" << endl;82;83}8485void Identification ::86BuildSurfaceElements (ARRAY<Segment> & segs,87Mesh & mesh, const Surface * surf)88{89cout << "Identification::BuildSurfaceElements called for base-class" << endl;90;91}929394void Identification ::95BuildVolumeElements (ARRAY<class Element2d> & surfels,96class Mesh & mesh)97{98;99}100101void Identification ::102GetIdentifiedFaces (ARRAY<INDEX_2> & idfaces) const103{104idfaces.SetSize(0);105for (int i = 1; i <= identfaces.GetNBags(); i++)106for (int j = 1; j <= identfaces.GetBagSize(i); j++)107{108INDEX_2 i2;109int val;110identfaces.GetData (i, j, i2, val);111idfaces.Append (i2);112}113}114115116117118PeriodicIdentification ::119PeriodicIdentification (int anr,120const CSGeometry & ageom,121const Surface * as1,122const Surface * as2)123: Identification(anr, ageom)124{125s1 = as1;126s2 = as2;127}128129PeriodicIdentification :: ~PeriodicIdentification ()130{131;132}133134/*135void PeriodicIdentification :: IdentifySpecialPoints136(ARRAY<class SpecialPoint> & points)137{138int i, j;139int bestj;140double bestval, val;141142for (i = 1; i <= points.Size(); i++)143{144Point<3> p1 = points.Get(i).p;145Point<3> hp1 = p1;146s1->Project (hp1);147if (Dist (p1, hp1) > 1e-6) continue;148149Vec<3> n1;150s1->GetNormalVector (p1, n1);151n1 /= n1.Length();152if ( fabs(n1 * points.Get(i).v) > 1e-3)153continue;154155bestval = 1e8;156bestj = 1;157for (j = 1; j <= points.Size(); j++)158{159Point<3> p2= points.Get(j).p;160Point<3> hp2 = p2;161s2->Project (hp2);162if (Dist (p2, hp2) > 1e-6) continue;163164Vec<3> n2;165s2->GetNormalVector (p2, n2);166n2 /= n2.Length();167if ( fabs(n2 * points.Get(j).v) > 1e-3)168continue;169170171Vec<3> v(p1, p2);172double vl = v.Length();173double cl = fabs (v*n1);174175val = 1 - cl*cl/(vl*vl);176177val += (points.Get(i).v - points.Get(j).v).Length();178179if (val < bestval)180{181bestj = j;182bestval = val;183}184}185186(*testout) << "Identify Periodic special points: pi = "187<< points.Get(i).p << ", vi = " << points.Get(i).v188<< " pj = " << points.Get(bestj).p189<< ", vj = " << points.Get(bestj).v190<< " bestval = " << bestval << endl;191}192}193*/194195int PeriodicIdentification ::196Identifyable (const SpecialPoint & sp1, const SpecialPoint & sp2,197const TABLE<int> & specpoint2solid,198const TABLE<int> & specpoint2surface) const199{200int i;201double val;202203SpecialPoint hsp1 = sp1;204SpecialPoint hsp2 = sp2;205206for (i = 1; i <= 1; i++)207{208// Swap (hsp1, hsp2);209210if (!s1->PointOnSurface (hsp1.p))211continue;212213Vec<3> n1;214n1 = s1->GetNormalVector (hsp1.p);215n1 /= n1.Length();216if ( fabs(n1 * hsp1.v) > 1e-3)217continue;218219220if (!s2->PointOnSurface(hsp2.p))221continue;222223Vec<3> n2;224n2 = s2->GetNormalVector (hsp2.p);225n2 /= n2.Length();226if ( fabs(n2 * hsp2.v) > 1e-3)227continue;228229230Vec<3> v = hsp2.p - hsp1.p;231double vl = v.Length();232double cl = fabs (v*n1);233234235val = 1 - cl*cl/(vl*vl);236val += (hsp1.v - hsp2.v).Length();237238if (val < 1e-6)239return 1;240}241242return 0;243}244245int PeriodicIdentification ::246Identifyable (const Point<3> & p1, const Point<3> & p2) const247{248return (s1->PointOnSurface (p1) &&249s2->PointOnSurface (p2));250}251252253254255int PeriodicIdentification ::256GetIdentifiedPoint (class Mesh & mesh, int pi)257{258const Surface * sold, *snew;259const Point<3> & p = mesh.Point (pi);260261if (s1->PointOnSurface (p))262{263snew = s2;264}265else266{267if (s2->PointOnSurface (p))268{269snew = s1;270}271else272{273cerr << "GetIdenfifiedPoint: Not possible" << endl;274exit (1);275}276}277278// project to other surface279Point<3> hp = p;280snew->Project (hp);281282int i;283int newpi = 0;284for (i = 1; i <= mesh.GetNP(); i++)285if (Dist2 (mesh.Point(i), hp) < 1e-12)286{287newpi = i;288break;289}290if (!newpi)291newpi = mesh.AddPoint (hp);292293if (snew == s2)294mesh.GetIdentifications().Add (pi, newpi, nr);295else296mesh.GetIdentifications().Add (newpi, pi, nr);297298mesh.GetIdentifications().SetType(nr,Identifications::PERIODIC);299300/*301(*testout) << "Identify points(periodic), nr = " << nr << ": " << mesh.Point(pi)302<< " and " << mesh.Point(newpi)303<< ((snew == s2) ? "" : " inverse")304<< endl;305*/306return newpi;307}308309310void PeriodicIdentification :: IdentifyPoints (class Mesh & mesh)311{312int i, j;313for (i = 1; i <= mesh.GetNP(); i++)314{315Point<3> p = mesh.Point(i);316if (s1->PointOnSurface (p))317{318Point<3> pp = p;319s2->Project (pp);320for (j = 1; j <= mesh.GetNP(); j++)321if (Dist2(mesh.Point(j), pp) < 1e-6)322{323mesh.GetIdentifications().Add (i, j, nr);324/*325(*testout) << "Identify points(periodic:), nr = " << nr << ": "326<< mesh.Point(i) << " - " << mesh.Point(j) << endl;327*/328}329}330}331332mesh.GetIdentifications().SetType(nr,Identifications::PERIODIC);333}334335336void PeriodicIdentification :: IdentifyFaces (class Mesh & mesh)337{338int i, j, k, l;339int fi1, fi2, side;340for (i = 1; i <= mesh.GetNFD(); i++)341for (j = 1; j <= mesh.GetNFD(); j++)342{343int surfi = mesh.GetFaceDescriptor(i).SurfNr();344int surfj = mesh.GetFaceDescriptor(j).SurfNr();345if (surfi == surfj)346continue;347348if (geom.GetSurface (surfi) != s1 ||349geom.GetSurface (surfj) != s2)350continue;351352int idok = 1;353354355// (*testout) << "check faces " << i << " and " << j << endl;356for (side = 1; side <= 2 && idok; side++)357{358if (side == 1)359{360fi1 = i;361fi2 = j;362}363else364{365fi1 = j;366fi2 = i;367}368369for (k = 1; k <= mesh.GetNSeg(); k++)370{371const Segment & seg1 = mesh.LineSegment(k);372if (seg1.si != fi1)373continue;374375int foundother = 0;376for (l = 1; l <= mesh.GetNSeg(); l++)377{378const Segment & seg2 = mesh.LineSegment(l);379if (seg2.si != fi2)380continue;381382// (*testout) << "seg1 = " << seg1.p1 << "-" << seg1.p2 << ", seg2 = " << seg2.p1 << "-" << seg2.p2;383384if (side == 1)385{386if (mesh.GetIdentifications().Get (seg1.p1, seg2.p1) &&387mesh.GetIdentifications().Get (seg1.p2, seg2.p2))388{389foundother = 1;390break;391}392393if (mesh.GetIdentifications().Get (seg1.p1, seg2.p2) &&394mesh.GetIdentifications().Get (seg1.p2, seg2.p1))395{396foundother = 1;397break;398}399}400else401{402if (mesh.GetIdentifications().Get (seg2.p1, seg1.p1) &&403mesh.GetIdentifications().Get (seg2.p2, seg1.p2))404{405foundother = 1;406break;407}408409if (mesh.GetIdentifications().Get (seg2.p1, seg1.p2) &&410mesh.GetIdentifications().Get (seg2.p2, seg1.p1))411{412foundother = 1;413break;414}415}416}417418if (!foundother)419{420idok = 0;421break;422}423}424}425426427if (idok)428{429// (*testout) << "Identify faces " << i << " and " << j << endl;430INDEX_2 fpair(i,j);431fpair.Sort();432identfaces.Set (fpair, 1);433}434}435}436437438439void PeriodicIdentification ::440BuildSurfaceElements (ARRAY<Segment> & segs,441Mesh & mesh, const Surface * surf)442{443int found = 0;444int fother;445446int facei = segs.Get(1).si;447int surfnr = mesh.GetFaceDescriptor(facei).SurfNr();448449if (geom.GetSurface(surfnr) == s1 ||450geom.GetSurface(surfnr) == s2)451{452ARRAY<int> copy_points;453454for (int i = 1; i <= mesh.GetNSE(); i++)455{456const Element2d & sel = mesh.SurfaceElement(i);457INDEX_2 fpair (facei, sel.GetIndex());458fpair.Sort();459if (identfaces.Used (fpair))460{461for (int k = 0; k < sel.GetNP(); k++)462if (!copy_points.Contains (sel[k]))463copy_points.Append (sel[k]);464}465}466BubbleSort (copy_points);467for (int k = 0; k < copy_points.Size(); k++)468GetIdentifiedPoint (mesh, copy_points[k]);469470471472for (int i = 1; i <= mesh.GetNSE(); i++)473{474const Element2d & sel = mesh.SurfaceElement(i);475INDEX_2 fpair (facei, sel.GetIndex());476fpair.Sort();477if (identfaces.Used (fpair))478{479found = 1;480fother = sel.GetIndex();481482// copy element483Element2d newel(sel.GetType());484newel.SetIndex (facei);485for (int k = 0; k < sel.GetNP(); k++)486newel[k] = GetIdentifiedPoint (mesh, sel[k]);487488Vec<3> nt = Cross (Point<3> (mesh[newel[1]])- Point<3> (mesh[newel[0]]),489Point<3> (mesh[newel[2]])- Point<3> (mesh[newel[0]]));490491Vec<3> nsurf = geom.GetSurface (surfnr)->GetNormalVector (mesh[newel[0]]);492if (nsurf * nt < 0)493Swap (newel[0], newel[2]);494495mesh.AddSurfaceElement (newel);496}497}498}499500if (found)501{502// (*mycout) << " copy face " << facei << " from face " << fother;503PrintMessage (4, " copy face ", facei, " from face ", fother);504505segs.SetSize(0);506}507}508509510511512513514515516void PeriodicIdentification :: Print (ostream & ost) const517{518ost << "Periodic Identifiaction, surfaces: "519<< s1->Name() << " - " << s2->Name() << endl;520s1->Print (ost);521ost << " - ";522s2->Print (ost);523ost << endl;524}525526527void PeriodicIdentification :: GetData (ostream & ost) const528{529ost << "periodic " << s1->Name() << " " << s2->Name();530}531532533534535536537538CloseSurfaceIdentification ::539CloseSurfaceIdentification (int anr,540const CSGeometry & ageom,541const Surface * as1,542const Surface * as2,543const TopLevelObject * adomain,544const Flags & flags)545: Identification(anr, ageom)546{547s1 = as1;548s2 = as2;549domain = adomain;550ref_levels = int (flags.GetNumFlag ("reflevels", 2));551ref_levels_s1 = int (flags.GetNumFlag ("reflevels1", 0));552ref_levels_s2 = int (flags.GetNumFlag ("reflevels2", 0));553slices = flags.GetNumListFlag ("slices");554for(int i=0; i<slices.Size(); i++)555if((i==0 && slices[i] <= 0) ||556(i>0 && slices[i] <= slices[i-1]) ||557(slices[i] >= 1))558throw NgException ("slices have to be in ascending order, between 0 and 1");559560// eps_n = 1e-3;561eps_n = 1e-6;562563dom_surf_valid = 0;564565if (domain)566for (int i = 0; i < geom.GetNTopLevelObjects(); i++)567if (domain == geom.GetTopLevelObject(i))568dom_nr = i;569570usedirection = flags.NumListFlagDefined("direction");571if(usedirection)572{573for(int i=0; i<3; i++)574direction(i) = flags.GetNumListFlag("direction")[i];575576direction.Normalize();577}578}579580CloseSurfaceIdentification :: ~CloseSurfaceIdentification ()581{582;583}584585void CloseSurfaceIdentification :: Print (ostream & ost) const586{587ost << "CloseSurface Identifiaction, surfaces: "588<< s1->Name() << " - " << s2->Name() << endl;589s1->Print (ost);590s2->Print (ost);591ost << endl;592}593594595void CloseSurfaceIdentification :: GetData (ostream & ost) const596{597ost << "close surface " << s1->Name() << " " << s2->Name();598}599600601/*602void CloseSurfaceIdentification :: IdentifySpecialPoints603(ARRAY<class SpecialPoint> & points)604{605int i, j;606int bestj;607double bestval, val;608609for (i = 1; i <= points.Size(); i++)610{611Point<3> p1 = points.Get(i).p;612Vec<3> n1;613614if (!s1->PointOnSurface (p1))615continue;616617s1->GetNormalVector (p1, n1);618n1 /= n1.Length();619if ( fabs(n1 * points.Get(i).v) > 1e-3)620continue;621622bestval = 1e8;623bestj = 1;624for (j = 1; j <= points.Size(); j++)625{626Point<3> p2= points.Get(j).p;627if (!s2->PointOnSurface (p2))628continue;629630Vec<3> n2;631s2->GetNormalVector (p2, n2);632n2 /= n2.Length();633if ( fabs(n2 * points.Get(j).v) > 1e-3)634continue;635636637Vec<3> v(p1, p2);638double vl = v.Length();639double cl = fabs (v*n1);640641val = 1 - cl*cl/(vl*vl);642643val += (points.Get(i).v - points.Get(j).v).Length();644645if (val < bestval)646{647bestj = j;648bestval = val;649}650}651652(*testout) << "Identify close surfaces special points: pi = "653<< points.Get(i).p << ", vi = " << points.Get(i).v654<< " pj = " << points.Get(bestj).p655<< ", vj = " << points.Get(bestj).v656<< " bestval = " << bestval << endl;657}658}659*/660661int CloseSurfaceIdentification ::662Identifyable (const SpecialPoint & sp1, const SpecialPoint & sp2,663const TABLE<int> & specpoint2solid,664const TABLE<int> & specpoint2surface) const665{666//(*testout) << "identcheck: " << sp1.p << "; " << sp2.p << endl;667668if (!dom_surf_valid)669{670const_cast<bool&> (dom_surf_valid) = 1;671ARRAY<int> & hsurf = const_cast<ARRAY<int>&> (domain_surfaces);672673if (domain)674{675BoxSphere<3> hbox (geom.BoundingBox());676geom.GetIndependentSurfaceIndices (domain->GetSolid(), hbox, hsurf);677//(*testout) << "surfs of identification " << nr << ": " << endl << hsurf << endl;678}679else680{681hsurf.SetSize (geom.GetNSurf());682for (int j = 0; j < hsurf.Size(); j++)683hsurf[j] = j;684}685}686687if (domain)688{689bool has1 = 0, has2 = 0;690for (int i = 0; i < specpoint2solid[sp1.nr].Size(); i++)691if (specpoint2solid[sp1.nr][i] == dom_nr)692{ has1 = 1; break; }693for (int i = 0; i < specpoint2solid[sp2.nr].Size(); i++)694if (specpoint2solid[sp2.nr][i] == dom_nr)695{ has2 = 1; break; }696697if (!has1 || !has2)698{699//(*testout) << "failed at pos1" << endl;700return 0;701}702}703704if (!s1->PointOnSurface (sp1.p))705{706//(*testout) << "failed at pos2" << endl;707return 0;708}709710// (*testout) << "sp1 " << sp1.p << " sp2 " << sp2.p << endl711// << "specpoint2solid[sp1.nr] " << specpoint2solid[sp1.nr] << endl712// << "specpoint2solid[sp2.nr] " << specpoint2solid[sp2.nr] << endl;713714715Vec<3> n1 = s1->GetNormalVector (sp1.p);716n1.Normalize();717if ( fabs(n1 * sp1.v) > eps_n)718{719//(*testout) << "failed at pos3" << endl;720return 0;721}722723if (!s2->PointOnSurface(sp2.p))724{725//(*testout) << "failed at pos4" << endl;726return 0;727}728729730Vec<3> n2 = s2->GetNormalVector (sp2.p);731n2.Normalize();732if ( fabs(n2 * sp2.v) > eps_n)733{734//(*testout) << "failed at pos5" << endl;735return 0;736}737738// must have joint surface739bool joint = 0;740741int j = 0, k = 0;742while (1)743{744int snr1 = specpoint2surface[sp1.nr][j];745int snr2 = specpoint2surface[sp2.nr][k];746if (snr1 < snr2)747{748j++;749if (j == specpoint2surface[sp1.nr].Size()) break;750}751else if (snr2 < snr1)752{753k++;754if (k == specpoint2surface[sp2.nr].Size()) break;755}756else757{758bool dom_surf = 0;759for (int l = 0; l < domain_surfaces.Size(); l++)760if (domain_surfaces[l] == snr1)761dom_surf = 1;762763if (dom_surf)764{765Vec<3> hn1 = geom.GetSurface(snr1)->GetNormalVector (sp1.p);766Vec<3> hn2 = geom.GetSurface(snr1)->GetNormalVector (sp2.p);767768if (hn1 * hn2 > 0)769{770joint = 1;771break;772}773}774775j++;776if (j == specpoint2surface[sp1.nr].Size()) break;777k++;778if (k == specpoint2surface[sp2.nr].Size()) break;779}780}781782if (!joint)783{784//(*testout) << "failed at pos6" << endl;785return 0;786}787788Vec<3> v = sp2.p - sp1.p;789double vl = v.Length();790double cl = (usedirection) ? fabs(v*direction) : fabs (v*n1);791792793if(cl <= (1-eps_n*eps_n) * vl)794{795//(*testout) << "failed at pos7" << endl;796return 0;797}798799double dl;800801if(usedirection)802{803Vec<3> v1 = sp1.v - (sp1.v*direction)*direction; v1.Normalize();804Vec<3> v2 = sp2.v - (sp2.v*direction)*direction; v2.Normalize();805806dl = (v1 - v2).Length();807}808else809dl = (sp1.v - sp2.v).Length();810811if (dl < 0.1)812return 1;813814815//(*testout) << "failed at pos8" << endl;816return 0;817}818819int CloseSurfaceIdentification ::820Identifyable (const Point<3> & p1, const Point<3> & p2) const821{822// if (domain)823// if (!domain->GetSolid()->IsIn (p1) || !domain->GetSolid()->IsIn (p2))824// return 0;825return (s1->PointOnSurface (p1) && s2->PointOnSurface (p2));826}827828829830831int CloseSurfaceIdentification ::832IdentifyableCandidate (const SpecialPoint & sp1) const833{834if (domain)835if (!domain->GetSolid()->IsIn (sp1.p))836return 0;837838if (s1->PointOnSurface (sp1.p))839{840Vec<3> n1;841n1 = s1->GetNormalVector (sp1.p);842n1.Normalize();843if ( fabs(n1 * sp1.v) > eps_n)844return 0;845return 1;846}847848if (s2->PointOnSurface (sp1.p))849{850Vec<3> n1;851n1 = s2->GetNormalVector (sp1.p);852n1.Normalize();853if ( fabs(n1 * sp1.v) > eps_n)854return 0;855return 1;856}857return 0;858}859860861862int CloseSurfaceIdentification ::863ShortEdge (const SpecialPoint & sp1, const SpecialPoint & sp2) const864{865if ( (s1->PointOnSurface (sp1.p) && s2->PointOnSurface (sp2.p)) ||866(s1->PointOnSurface (sp2.p) && s2->PointOnSurface (sp1.p)) )867{868return 1;869}870return 0;871}872873874875int CloseSurfaceIdentification ::876GetIdentifiedPoint (class Mesh & mesh, int pi)877{878const Surface * sold, *snew;879const Point<3> & p = mesh.Point (pi);880881ARRAY<int,PointIndex::BASE> identmap(mesh.GetNP());882mesh.GetIdentifications().GetMap (nr, identmap);883if (identmap.Get(pi))884return identmap.Get(pi);885886887if (s1->PointOnSurface (p))888snew = s2;889else if (s2->PointOnSurface (p))890snew = s1;891else892{893(*testout) << "GetIdenfifiedPoint: Not possible" << endl;894(*testout) << "p = " << p << endl;895(*testout) << "surf1: " << (*s1) << endl896<< "surf2: " << (*s2) << endl;897898cerr << "GetIdenfifiedPoint: Not possible" << endl;899throw NgException ("GetIdenfifiedPoint: Not possible");900}901902// project to other surface903Point<3> hp = p;904if(usedirection)905snew->SkewProject(hp,direction);906else907snew->Project (hp);908909//(*testout) << "projecting " << p << " to " << hp << endl;910911int newpi = 0;912for (int i = 1; i <= mesh.GetNP(); i++)913if (Dist2 (mesh.Point(i), hp) < 1e-12)914// if (Dist2 (mesh.Point(i), hp) < 1 * Dist2 (hp, p))915{916newpi = i;917break;918}919if (!newpi)920newpi = mesh.AddPoint (hp);921922if (snew == s2)923{924mesh.GetIdentifications().Add (pi, newpi, nr);925//(*testout) << "add identification(1) " << pi << " - " << newpi << ", " << nr << endl;926}927else928{929mesh.GetIdentifications().Add (newpi, pi, nr);930//(*testout) << "add identification(2) " << newpi << " - " << pi << ", " << nr << endl;931}932mesh.GetIdentifications().SetType(nr,Identifications::CLOSESURFACES);933934935/*936(*testout) << "Identify points(closesurface), nr = " << nr << ": " << mesh.Point(pi)937<< " and " << mesh.Point(newpi)938<< ((snew == s2) ? "" : " inverse")939<< endl;940*/941return newpi;942}943944945946947948void CloseSurfaceIdentification :: IdentifyPoints (Mesh & mesh)949{950int np = mesh.GetNP();951952ARRAY<int> points_on_surf2;953954for (int i2 = 1; i2 <= np; i2++)955if (s2->PointOnSurface (mesh.Point(i2)))956points_on_surf2.Append (i2);957958ARRAY<int> surfs_of_p1;959960for (int i1 = 1; i1 <= np; i1++)961{962Point<3> p1 = mesh.Point(i1);963// (*testout) << "p1 = " << i1 << " = " << p1 << endl;964if (domain && !domain->GetSolid()->IsIn (p1))965continue;966967//if(domain) (*testout) << "p1 is in " << domain->GetSolid()->Name() << endl;968969if (s1->PointOnSurface (p1))970{971int candi2 = 0;972double mindist = 1e10;973974Vec<3> n1;975n1 = s1->GetNormalVector (p1);976n1.Normalize();977978surfs_of_p1.SetSize(0);979for (int jj = 0; jj < domain_surfaces.Size(); jj++)980{981int j = domain_surfaces[jj];982if (geom.GetSurface(j) -> PointOnSurface(p1))983surfs_of_p1.Append (j);984}985//(*testout) << " surfs of p1 = " << endl << surfs_of_p1 << endl;986987for (int ii2 = 0; ii2 < points_on_surf2.Size(); ii2++)988{989int i2 = points_on_surf2[ii2];990if (i2 == i1) continue;991const Point<3> p2 = mesh.Point(i2);992993Vec<3> n = p2 - p1;994n.Normalize();995996bool joint = 0;997for (int jj = 0; jj < surfs_of_p1.Size(); jj++)998{999int j = surfs_of_p1[jj];1000if (geom.GetSurface(j) -> PointOnSurface(p2))1001{1002Vec<3> hn1 = geom.GetSurface(j)->GetNormalVector (p1);1003Vec<3> hn2 = geom.GetSurface(j)->GetNormalVector (p2);10041005if (hn1 * hn2 > 0)1006{1007joint = 1;1008break;1009}1010}1011}10121013if (!joint) continue;10141015if(usedirection)1016{1017if (fabs (n*direction) > 0.9)1018{1019Vec<3> p1p2 = p2-p1;1020double ndist = p1p2.Length2() - pow(p1p2*direction,2);1021if(ndist < mindist)1022{1023candi2 = i2;1024mindist = ndist;1025}1026}10271028}1029else1030{1031if (fabs (n * n1) > 0.9 &&1032Dist (p1, p2) < mindist)1033{1034candi2 = i2;1035mindist = Dist (p1, p2);1036}1037}10381039}10401041if (candi2)1042{1043//(*testout) << "identify points " << p1 << " - " << mesh.Point(candi2) << endl;10441045/*1046(*testout) << "Add Identification from CSI2, nr = " << nr << ", p1 = "1047<< i1 << " = "1048<< mesh[PointIndex(i1)] << ", p2 = " << candi2 << " = "1049<< mesh[PointIndex(candi2)] << endl;1050*/1051mesh.GetIdentifications().Add (i1, candi2, nr);1052mesh.GetIdentifications().SetType(nr,Identifications::CLOSESURFACES);1053//(*testout) << "add identification " << i1 << " - " << candi2 << ", " << nr << endl;1054}1055}1056}1057}1058105910601061void CloseSurfaceIdentification :: IdentifyFaces (class Mesh & mesh)1062{1063int fi1, fi2, side;1064int s1rep, s2rep;10651066for (int i = 0; i < geom.GetNSurf(); i++)1067{1068if (geom.GetSurface (i) == s1)1069s1rep = geom.GetSurfaceClassRepresentant(i);1070if (geom.GetSurface (i) == s2)1071s2rep = geom.GetSurfaceClassRepresentant(i);1072}10731074ARRAY<int> segs_on_face1, segs_on_face2;10751076identfaces.DeleteData();10771078//(*testout) << "identify faces, nr = " << nr << endl;10791080for (int i = 1; i <= mesh.GetNFD(); i++)1081{1082int surfi = mesh.GetFaceDescriptor(i).SurfNr();1083if (s1rep != surfi) continue;108410851086if (domain &&1087domain != geom.GetTopLevelObject (mesh.GetFaceDescriptor(i).DomainIn()-1) &&1088domain != geom.GetTopLevelObject (mesh.GetFaceDescriptor(i).DomainOut()-1))1089continue;10901091for (int j = 1; j <= mesh.GetNFD(); j++)1092{1093int surfj = mesh.GetFaceDescriptor(j).SurfNr();10941095if (surfi == surfj) continue;1096if (s2rep != surfj) continue;109710981099int idok = 1;11001101for (side = 1; side <= 2 && idok; side++)1102{1103if (side == 1)1104{1105fi1 = i;1106fi2 = j;1107}1108else1109{1110fi1 = j;1111fi2 = i;1112}111311141115segs_on_face1.SetSize(0);1116segs_on_face2.SetSize(0);11171118for (int k = 1; k <= mesh.GetNSeg(); k++)1119{1120if (mesh.LineSegment(k).si == fi1)1121segs_on_face1.Append (k);1122if (mesh.LineSegment(k).si == fi2)1123segs_on_face2.Append (k);1124}112511261127for (int k = 1; k <= mesh.GetNSeg(); k++)1128{1129const Segment & seg1 = mesh.LineSegment(k);1130if (seg1.si != fi1)1131continue;11321133int foundother = 0;1134/*1135for (int l = 1; l <= mesh.GetNSeg(); l++)1136{1137const Segment & seg2 = mesh.LineSegment(l);1138if (seg2.si != fi2)1139continue;1140*/1141for (int ll = 0; ll < segs_on_face2.Size(); ll++)1142{1143int l = segs_on_face2[ll];1144const Segment & seg2 = mesh.LineSegment(l);11451146if (side == 1)1147{1148if (mesh.GetIdentifications().Get (seg1.p1, seg2.p1) &&1149mesh.GetIdentifications().Get (seg1.p2, seg2.p2))1150{1151foundother = 1;1152break;1153}11541155if (mesh.GetIdentifications().Get (seg1.p1, seg2.p2) &&1156mesh.GetIdentifications().Get (seg1.p2, seg2.p1))1157{1158foundother = 1;1159break;1160}1161}1162else1163{1164if (mesh.GetIdentifications().Get (seg2.p1, seg1.p1) &&1165mesh.GetIdentifications().Get (seg2.p2, seg1.p2))1166{1167foundother = 1;1168break;1169}11701171if (mesh.GetIdentifications().Get (seg2.p1, seg1.p2) &&1172mesh.GetIdentifications().Get (seg2.p2, seg1.p1))1173{1174foundother = 1;1175break;1176}1177}1178}11791180if (!foundother)1181{1182idok = 0;1183break;1184}1185}1186}118711881189if (idok)1190{1191//(*testout) << "Identification " << nr << ", identify faces " << i << " and " << j << endl;1192INDEX_2 fpair(i,j);1193fpair.Sort();1194identfaces.Set (fpair, 1);1195}1196}1197}1198}1199120012011202void CloseSurfaceIdentification ::1203BuildSurfaceElements (ARRAY<Segment> & segs,1204Mesh & mesh, const Surface * surf)1205{1206bool found = 0;1207int cntquads = 0;12081209ARRAY<int,PointIndex::BASE> identmap;1210identmap = 0;12111212mesh.GetIdentifications().GetMap (nr, identmap);12131214for (int i = PointIndex::BASE; i < identmap.Size()+PointIndex::BASE; i++)1215if (identmap[i]) identmap[identmap[i]] = i;121612171218//(*testout) << "identification nr = " << nr << endl;1219//(*testout) << "surf = " << (*surf) << endl;1220//(*testout) << "domain = " << domain->GetSolid()->Name() << endl;1221//(*testout) << "segs = " << endl << segs << endl;1222//(*testout) << "identmap = " << endl << identmap << endl;12231224//ARRAY<bool> foundseg(segs.Size());1225//foundseg = false;12261227// insert quad layer:1228for (int i1 = 0; i1 < segs.Size(); i1++)1229{1230const Segment & s1 = segs[i1];1231if (identmap[s1.p1] && identmap[s1.p2])1232for (int i2 = 0; i2 < i1; i2++)1233{1234const Segment & s2 = segs[i2];1235//(*testout) << "checking " << s1 << " and " << s2 << " for ident." << endl;12361237if(domain && !((s1.domin == dom_nr ||1238s1.domout == dom_nr) &&1239(s2.domin == dom_nr ||1240s2.domout == dom_nr)))1241continue;12421243if ((mesh.GetIdentifications().Get (s1.p1, s2.p2, nr) &&1244mesh.GetIdentifications().Get (s1.p2, s2.p1, nr)) ||1245(mesh.GetIdentifications().Get (s2.p1, s1.p2, nr) &&1246mesh.GetIdentifications().Get (s2.p2, s1.p1, nr)))1247{1248Element2d el(s1.p1, s1.p2, s2.p1, s2.p2);12491250Vec<3> n = Cross (mesh[el[1]] - mesh[el[0]],1251mesh[el[3]] - mesh[el[0]]);12521253Vec<3> ns = surf->GetNormalVector (mesh[el[0]]);12541255if (n * ns < 0)1256{1257Swap (el.PNum(1), el.PNum(2));1258Swap (el.PNum(3), el.PNum(4));1259}12601261mesh.AddSurfaceElement (el);1262// (*testout) << "(id nr "<< nr <<") add rect element: "1263// << mesh.Point (el.PNum(1)) << " - "1264// << mesh.Point (el.PNum(2)) << " - "1265// << mesh.Point (el.PNum(3)) << " - "1266// << mesh.Point (el.PNum(4)) << endl;1267found = true;1268//foundseg[i1]=foundseg[i2] = true;1269cntquads++;1270}1271}1272}1273if (found)1274{1275PrintMessage(3, "insert quad layer of ", cntquads,1276" elements at face ", segs.Get(1).si);1277//ARRAY<Segment> aux;1278//for(int i=0; i<segs.Size();i++)1279// if(!foundseg[i])1280// aux.Append(segs[i]);1281segs.SetSize(0);1282}1283else1284{1285BuildSurfaceElements2 (segs, mesh, surf);1286}1287}1288128912901291129212931294void CloseSurfaceIdentification ::1295BuildSurfaceElements2 (ARRAY<Segment> & segs,1296Mesh & mesh, const Surface * surf)1297{1298// copy mesh129913001301// (*testout) << "copy trig face, identnr = " << nr << endl;1302// (*testout) << "identfaces = " << endl << identfaces << endl;13031304if (!segs.Size()) return;13051306bool found = 0;13071308int fother;1309int facei = segs.Get(1).si;1310int surfnr = mesh.GetFaceDescriptor(facei).SurfNr();131113121313bool foundid = 0;1314for (INDEX_2_HASHTABLE<int>::Iterator it = identfaces.Begin();1315it != identfaces.End(); it++)1316{1317INDEX_2 i2;1318int data;1319identfaces.GetData (it, i2, data);1320if (i2.I1() == facei || i2.I2() == facei)1321foundid = 1;1322}13231324/*1325for (int i = 1; i <= identfaces.GetNBags(); i++)1326for (int j = 1; j <= identfaces.GetBagSize(i); j++)1327{1328INDEX_2 i2;1329int data;1330identfaces.GetData (i, j, i2, data);1331if (i2.I1() == facei || i2.I2() == facei)1332foundid = 1;13331334(*testout) << "identface = " << i2 << endl;1335(*testout) << "face " << i2.I1() << " = " << mesh.GetFaceDescriptor(i2.I1()) << endl;1336(*testout) << "face " << i2.I2() << " = " << mesh.GetFaceDescriptor(i2.I2()) << endl;1337}1338*/13391340if (foundid)1341{1342// (*testout) << "surfaces found" << endl;1343// copy surface1344for (int i = 1; i <= mesh.GetNSE(); i++)1345{1346const Element2d & sel = mesh.SurfaceElement(i);1347INDEX_2 fpair (facei, sel.GetIndex());1348fpair.Sort();1349if (identfaces.Used (fpair))1350{1351found = 1;1352fother = sel.GetIndex();13531354// copy element1355Element2d newel(sel.GetType());1356newel.SetIndex (facei);1357for (int k = 1; k <= sel.GetNP(); k++)1358{1359newel.PNum(k) =1360GetIdentifiedPoint (mesh, sel.PNum(k));1361// cout << "id-point = " << sel.PNum(k) << ", np = " << newel.PNum(k) << endl;1362}13631364Vec<3> nt = Cross (Point<3> (mesh.Point (newel.PNum(2)))-1365Point<3> (mesh.Point (newel.PNum(1))),1366Point<3> (mesh.Point (newel.PNum(3)))-1367Point<3> (mesh.Point (newel.PNum(1))));1368Vec<3> nsurf;1369nsurf = geom.GetSurface (surfnr)->GetNormalVector (mesh.Point(newel.PNum(1)));1370if (nsurf * nt < 0)1371Swap (newel.PNum(2), newel.PNum(3));13721373mesh.AddSurfaceElement (newel);1374}1375}1376}13771378if (found)1379{1380// (*mycout) << " copy face " << facei << " from face " << fother;1381PrintMessage (4, " copy face ", facei, " from face ", fother);1382segs.SetSize(0);1383}1384}138513861387138813891390139113921393139413951396139713981399void CloseSurfaceIdentification ::1400BuildVolumeElements (ARRAY<class Element2d> & surfels,1401class Mesh & mesh)1402{1403;1404}14051406140714081409141014111412141314141415141614171418/* ***************** Close Edges Identification ********** */1419142014211422CloseEdgesIdentification ::1423CloseEdgesIdentification (int anr,1424const CSGeometry & ageom,1425const Surface * afacet,1426const Surface * as1,1427const Surface * as2)1428: Identification(anr, ageom)1429{1430facet = afacet;1431s1 = as1;1432s2 = as2;1433}14341435CloseEdgesIdentification :: ~CloseEdgesIdentification ()1436{1437;1438}14391440void CloseEdgesIdentification :: Print (ostream & ost) const1441{1442ost << "CloseEdges Identifiaction, facet = "1443<< facet->Name() << ", surfaces: "1444<< s1->Name() << " - " << s2->Name() << endl;1445facet->Print (ost);1446s1->Print (ost);1447s2->Print (ost);1448ost << endl;1449}145014511452void CloseEdgesIdentification :: GetData (ostream & ost) const1453{1454ost << "closeedges " << facet->Name() << " "1455<< s1->Name() << " " << s2->Name();1456}145714581459/*1460void CloseEdgesIdentification :: IdentifySpecialPoints1461(ARRAY<class SpecialPoint> & points)1462{1463int i, j;1464int bestj;1465double bestval, val;14661467for (i = 1; i <= points.Size(); i++)1468{1469Point<3> p1 = points.Get(i).p;1470Vec<3> n1;14711472if (!s1->PointOnSurface (p1))1473continue;14741475s1->GetNormalVector (p1, n1);1476n1 /= n1.Length();1477if ( fabs(n1 * points.Get(i).v) > 1e-3)1478continue;14791480bestval = 1e8;1481bestj = 1;1482for (j = 1; j <= points.Size(); j++)1483{1484Point<3> p2= points.Get(j).p;1485if (!s2->PointOnSurface (p2))1486continue;14871488Vec<3> n2;1489s2->GetNormalVector (p2, n2);1490n2 /= n2.Length();1491if ( fabs(n2 * points.Get(j).v) > 1e-3)1492continue;149314941495Vec<3> v(p1, p2);1496double vl = v.Length();1497double cl = fabs (v*n1);14981499val = 1 - cl*cl/(vl*vl);15001501val += (points.Get(i).v - points.Get(j).v).Length();15021503if (val < bestval)1504{1505bestj = j;1506bestval = val;1507}1508}15091510(*testout) << "Identify close surfaces special points: pi = "1511<< points.Get(i).p << ", vi = " << points.Get(i).v1512<< " pj = " << points.Get(bestj).p1513<< ", vj = " << points.Get(bestj).v1514<< " bestval = " << bestval << endl;1515}1516}1517*/15181519int CloseEdgesIdentification ::1520Identifyable (const SpecialPoint & sp1, const SpecialPoint & sp2,1521const TABLE<int> & specpoint2solid,1522const TABLE<int> & specpoint2surface) const1523{1524int i;1525double val;15261527SpecialPoint hsp1 = sp1;1528SpecialPoint hsp2 = sp2;15291530for (i = 1; i <= 1; i++)1531{1532if (!s1->PointOnSurface (hsp1.p))1533continue;15341535Vec<3> n1;1536n1 = s1->GetNormalVector (hsp1.p);1537n1 /= n1.Length();1538if ( fabs(n1 * hsp1.v) > 1e-3)1539continue;154015411542if (!s2->PointOnSurface(hsp2.p))1543continue;15441545Vec<3> n2;1546n2 = s2->GetNormalVector (hsp2.p);1547n2 /= n2.Length();1548if ( fabs(n2 * hsp2.v) > 1e-3)1549continue;155015511552Vec<3> v = hsp2.p - hsp1.p;1553double vl = v.Length();1554double cl = fabs (v*n1);155515561557val = 1 - cl*cl/(vl*vl);1558val += (hsp1.v - hsp2.v).Length();15591560if (val < 1e-3)1561{1562return 1;1563}1564}15651566return 0;1567}15681569157015711572void CloseEdgesIdentification :: IdentifyPoints (Mesh & mesh)1573{1574int i, j;1575int i1, i2;15761577int np = mesh.GetNP();1578for (i1 = 1; i1 <= np; i1++)1579for (i2 = 1; i2 <= np; i2++)1580{1581if (i2 == i1)1582continue;15831584const Point<3> p1 = mesh.Point(i1);1585const Point<3> p2 = mesh.Point(i2);1586Point<3> pp1 = p1;1587Point<3> pp2 = p2;15881589s1->Project (pp1);1590facet->Project (pp1);1591s2->Project (pp2);1592facet->Project (pp2);15931594if (Dist (p1, pp1) > 1e-6 || Dist (p2, pp2) > 1e-6)1595continue;15961597Vec<3> n1, nf, t;1598Vec<3> n = p2 - p1;1599n.Normalize();16001601n1 = s1->GetNormalVector (p1);1602nf = facet->GetNormalVector (p1);1603t = Cross (n1, nf);1604t /= t.Length();16051606if (fabs (n * t) < 0.5)1607{1608(*testout) << "close edges identify points " << p1 << " - " << p2 << endl;1609mesh.GetIdentifications().Add (i1, i2, nr);1610mesh.GetIdentifications().SetType(nr,Identifications::CLOSEEDGES);1611}1612}1613}16141615void CloseEdgesIdentification ::1616BuildSurfaceElements (ARRAY<Segment> & segs,1617Mesh & mesh, const Surface * surf)1618{1619int i1, i2;1620int found = 0;1621int i, j, k;16221623if (surf != facet)1624return;16251626for (i1 = 1; i1 <= segs.Size(); i1++)1627for (i2 = 1; i2 < i1; i2++)1628{1629const Segment & s1 = segs.Get(i1);1630const Segment & s2 = segs.Get(i2);1631if (mesh.GetIdentifications().Get (s1.p1, s2.p2) &&1632mesh.GetIdentifications().Get (s1.p2, s2.p1))1633{1634Element2d el(QUAD);1635el.PNum(1) = s1.p1;1636el.PNum(2) = s1.p2;1637el.PNum(3) = s2.p2;1638el.PNum(4) = s2.p1;16391640Vec<3> n = Cross (Point<3> (mesh.Point(el.PNum(2)))-1641Point<3> (mesh.Point(el.PNum(1))),1642Point<3> (mesh.Point(el.PNum(3)))-1643Point<3> (mesh.Point(el.PNum(1))));1644Vec<3> ns;1645ns = surf->GetNormalVector (mesh.Point(el.PNum(1)));1646//(*testout) << "n = " << n << " ns = " << ns << endl;1647if (n * ns < 0)1648{1649//(*testout) << "Swap the quad" << endl;1650Swap (el.PNum(1), el.PNum(2));1651Swap (el.PNum(3), el.PNum(4));1652}165316541655Swap (el.PNum(3), el.PNum(4));1656mesh.AddSurfaceElement (el);1657// (*testout) << "add rect element: "1658// << mesh.Point (el.PNum(1)) << " - "1659// << mesh.Point (el.PNum(2)) << " - "1660// << mesh.Point (el.PNum(3)) << " - "1661// << mesh.Point (el.PNum(4)) << endl;1662found = 1;1663}1664}16651666if (found)1667segs.SetSize(0);1668}16691670}1671167216731674