Path: blob/devel/ElmerGUI/netgen/libsrc/csg/edgeflw.cpp
3206 views
#include <mystdlib.h>1#include <meshing.hpp>2#include <csg.hpp>34#undef DEVELOP5// #define DEVELOP67namespace netgen8{910EdgeCalculation ::11EdgeCalculation (const CSGeometry & ageometry,12ARRAY<SpecialPoint> & aspecpoints)13: geometry(ageometry), specpoints(aspecpoints)14{15Box<3> bbox = geometry.BoundingBox();1617searchtree = new Point3dTree (bbox.PMin(), bbox.PMax());18meshpoint_tree = new Point3dTree (bbox.PMin(), bbox.PMax());1920for (int i = 0; i < specpoints.Size(); i++)21searchtree->Insert (specpoints[i].p, i);2223ideps = 1e-9;24}2526EdgeCalculation :: ~EdgeCalculation()27{28delete searchtree;29delete meshpoint_tree;30}313233void EdgeCalculation :: Calc(double h, Mesh & mesh)34{35PrintMessage (1, "Find edges");36PushStatus ("Find edges");373839for (int i = 1; i <= mesh.GetNP(); i++)40meshpoint_tree->Insert (mesh.Point(i), i);414243// add all special points before edge points (important for periodic identification)44// JS, Jan 200745const double di=1e-7*geometry.MaxSize();46ARRAY<int> locsearch;4748for (int i = 0; i < specpoints.Size(); i++)49if (specpoints[i].unconditional)50{51Point<3> p = specpoints[i].p;52meshpoint_tree -> GetIntersecting (p-Vec<3> (di,di,di),53p+Vec<3> (di,di,di), locsearch);5455if (locsearch.Size() == 0)56{57PointIndex pi = mesh.AddPoint (p, specpoints[i].GetLayer(), FIXEDPOINT);58meshpoint_tree -> Insert (p, pi);59}60}6162/*63// slow version64for (int i = 0; i < specpoints.Size(); i++)65if (specpoints[i].unconditional)66{67Point<3> p = specpoints[i].p;68bool found = false;69for (int j = 1; j <= mesh.GetNP(); j++)70if (Dist (p, mesh.Point(j)) < 1e-8)71found = true;72if (!found)73mesh.AddPoint (p, specpoints[i].GetLayer(), FIXEDPOINT);74}75*/76777879CalcEdges1 (h, mesh);80SplitEqualOneSegEdges (mesh);81FindClosedSurfaces (h, mesh);82PrintMessage (3, cntedge, " edges found");8384PopStatus ();85}868788899091void EdgeCalculation :: CalcEdges1 (double h, Mesh & mesh)92{93ARRAY<int> hsp(specpoints.Size());94ARRAY<int> glob2hsp(specpoints.Size());95ARRAY<int> startpoints, endpoints;969798int pos, ep;99int layer;100101Point<3> p, np;102int pi1, s1, s2, s1_orig, s2_orig;103104ARRAY<Point<3> > edgepoints;105ARRAY<double> curvelength;106int copyedge = 0, copyfromedge = -1, copyedgeidentification = -1;107108ARRAY<int> locsurfind, locind;109110int checkedcopy = 0;111112// double size = geometry.MaxSize();113// double epspointdist2 = sqr (size) * 1e-12;114115116// copy special points to work with117for (int i = 0; i < specpoints.Size(); i++)118{119hsp[i] = i;120glob2hsp[i] = i;121}122123//for(int i=0; i<hsp.Size(); i++)124// (*testout) << "hsp["<<i<<"] ... " << specpoints[hsp[i]].p << endl;125126127cntedge = 0;128INDEX_2_HASHTABLE<int> identification_used(100); // identification i already used for startpoint j129130mesh.GetIdentifications().Delete();131132TABLE<int> specpoint2surface(specpoints.Size());133if (geometry.identifications.Size())134{135for (int i = 0; i < specpoints.Size(); i++)136for (int j = 0; j < geometry.GetNSurf(); j++)137if (geometry.GetSurface(j)->PointOnSurface (specpoints[i].p))138specpoint2surface.Add (i, j);139}140141TABLE<int> specpoint2tlo(specpoints.Size());142if (geometry.identifications.Size())143{144for (int i = 0; i < specpoints.Size(); i++)145for (int j = 0; j < geometry.GetNTopLevelObjects(); j++)146{147const TopLevelObject * tlo = geometry.GetTopLevelObject (j);148if (tlo->GetSolid() && tlo->GetSolid()->VectorIn (specpoints[i].p,specpoints[i].v))149//if (tlo->GetSolid() && tlo->GetSolid()->IsIn (specpoints[i].p))150{151#ifdef DEVELOP152(*testout) << "point " << specpoints[i].p << " v " <<specpoints[i].v <<" is in " << tlo->GetSolid()->Name() << endl;153#endif154specpoint2tlo.Add (i, j);155}156}157}158159for (int i = 0; i < specpoints.Size(); i++)160specpoints[i].nr = i;161162while (hsp.Size())163{164SetThreadPercent(100 - 100 * double (hsp.Size()) / specpoints.Size());165166#ifdef DEVELOP167(*testout) << "hsp.Size() " << hsp.Size() << " specpoints.Size() " << specpoints.Size() << endl;168(*testout) << endl << "edge nr " << cntedge+1 << endl;169#endif170171edgepoints.SetSize (0);172curvelength.SetSize (0);173174175pi1 = 0;176copyedge = 0;177// identifyable point available ?178179180for (int i = 0; i < geometry.identifications.Size() && !pi1; i++)181for (int j = checkedcopy; j < startpoints.Size() && !pi1; j++)182{183#ifdef DEVELOP184(*testout) << "checking point " << specpoints[startpoints[j]].p185<< ", v = " << specpoints[startpoints[j]].v186<< " for copying (i,j = " << i << ", " << j << ")" << endl;187#endif188if (geometry.identifications[i]->IdentifyableCandidate (specpoints[startpoints[j]]) &&189geometry.identifications[i]->IdentifyableCandidate (specpoints[endpoints[j]]))190191192{193int pi1cand = 0;194double mindist = 1e10;195196for (int k = 0; k < hsp.Size() && !pi1; k++)197{198//(*testout) << " ? identifyable with " << specpoints[hsp[k]].p199//<< ", v = " << specpoints[hsp[k]].v200// << endl;201if (identification_used.Used (INDEX_2(i, startpoints[j])) ||202identification_used.Used (INDEX_2(i, hsp[k])))203{204//(*testout) << "failed at pos0" << endl;205continue;206}207208if (geometry.identifications[i]209->Identifyable(specpoints[startpoints[j]], specpoints[hsp[k]], specpoint2tlo, specpoint2surface) ||210geometry.identifications[i]211->Identifyable(specpoints[hsp[k]], specpoints[startpoints[j]], specpoint2tlo, specpoint2surface))212{213#ifdef DEVELOP214(*testout) << "identifyable: " << specpoints[hsp[k]].p << ", v = " << specpoints[hsp[k]].v215<< " and " << specpoints[startpoints[j]].p << ", v = " << specpoints[startpoints[j]].v216<< " (identification " << i+1 << ")" << endl;217#endif218219if (Dist (specpoints[startpoints[j]].p, specpoints[hsp[k]].p) < mindist)220{221mindist = Dist (specpoints[startpoints[j]].p, specpoints[hsp[k]].p);222pi1cand = k+1;223}224}225}226227228if (pi1cand)229{230pi1 = pi1cand;231copyedge = 1;232copyfromedge = j+1;233copyedgeidentification = i+1;234235identification_used.Set (INDEX_2(i, startpoints[j]), 1);236identification_used.Set (INDEX_2(i, hsp.Get(pi1)), 1);237}238}239}240241242// cannot copy from other ege ?243if (!pi1)244checkedcopy = startpoints.Size();245246// unconditional special point available ?247if (!pi1)248for (int i = 1; i <= hsp.Size(); i++)249if (specpoints[hsp.Get(i)].unconditional == 1)250{251pi1 = i;252break;253}254255256if (!pi1)257{258// no unconditional points available, choose first conitional259pi1 = 1;260}261262layer = specpoints[hsp.Get(pi1)].GetLayer();263264265if (!specpoints[hsp.Get(pi1)].unconditional)266{267specpoints[hsp.Elem(pi1)].unconditional = 1;268for (int i = 1; i <= hsp.Size(); i++)269if (i != pi1 &&270Dist (specpoints[hsp.Get(pi1)].p, specpoints[hsp.Get(i)].p) < 1e-8*geometry.MaxSize() &&271(specpoints[hsp.Get(pi1)].v + specpoints[hsp.Get(i)].v).Length() < 1e-4)272{273// opposite direction274specpoints[hsp.Elem(i)].unconditional = 1;275}276}277278cntedge++;279startpoints.Append (hsp.Get(pi1));280281#ifdef DEVELOP282(*testout) << "start followedge: p1 = " << specpoints[hsp.Get(pi1)].p283<< ", v = " << specpoints[hsp.Get(pi1)].v << endl;284#endif285286FollowEdge (pi1, ep, pos, hsp, h, mesh,287edgepoints, curvelength);288289290if (multithread.terminate)291return;292293if (!ep)294{295// ignore starting point296hsp.DeleteElement (pi1);297cout << "yes, this happens" << endl;298continue;299}300301302303endpoints.Append (hsp.Get(ep));304305306double elen = 0;307for (int i = 1; i <= edgepoints.Size()-1; i++)308elen += Dist (edgepoints.Get(i), edgepoints.Get(i+1));309310311int shortedge = 0;312for (int i = 1; i <= geometry.identifications.Size(); i++)313if (geometry.identifications.Get(i)->ShortEdge(specpoints[hsp.Get(pi1)], specpoints[hsp.Get(ep)]))314shortedge = 1;315// (*testout) << "shortedge = " << shortedge << endl;316317318if (!shortedge)319{320mesh.RestrictLocalHLine (Point3d (specpoints[hsp.Get(pi1)].p),321Point3d (specpoints[hsp.Get(ep)].p),322elen / mparam.segmentsperedge);323}324325s1 = specpoints[hsp.Get(pi1)].s1;326s2 = specpoints[hsp.Get(pi1)].s2;327s1_orig = specpoints[hsp.Get(pi1)].s1_orig;328s2_orig = specpoints[hsp.Get(pi1)].s2_orig;329330331// delete initial, terminal and conditional points332333#ifdef DEVELOP334(*testout) << "terminal point: p = " << specpoints[hsp.Get(ep)].p335<< ", v = " << specpoints[hsp.Get(ep)].v << endl;336#endif337338searchtree -> DeleteElement (hsp.Get(ep));339searchtree -> DeleteElement (hsp.Get(pi1));340341if (ep > pi1)342{343glob2hsp[hsp[ep-1]] = -1;344glob2hsp[hsp.Last()] = ep-1;345hsp.DeleteElement (ep);346347glob2hsp[hsp[pi1-1]] = -1;348glob2hsp[hsp.Last()] = pi1-1;349hsp.DeleteElement (pi1);350}351else352{353glob2hsp[hsp[pi1-1]] = -1;354glob2hsp[hsp.Last()] = pi1-1;355hsp.DeleteElement (pi1);356357glob2hsp[hsp[ep-1]] = -1;358glob2hsp[hsp.Last()] = ep-1;359hsp.DeleteElement (ep);360}361362363for (int j = 1; j <= edgepoints.Size()-1; j++)364{365p = edgepoints.Get(j);366np = Center (p, edgepoints.Get(j+1));367double hd = Dist (p, np);368369370Box<3> boxp (np - (1.2 * hd) * Vec<3> (1, 1, 1),371np + (1.2 * hd) * Vec<3> (1, 1, 1));372searchtree -> GetIntersecting (boxp.PMin(), boxp.PMax(), locind);373374for (int i = 0; i < locind.Size(); i++)375{376if ( specpoints[locind[i]].HasSurfaces (s1, s2) &&377specpoints[locind[i]].unconditional == 0)378{379searchtree -> DeleteElement (locind[i]);380381int li = glob2hsp[locind[i]];382glob2hsp[locind[i]] = -1;383glob2hsp[hsp.Last()] = li;384hsp.Delete (li);385}386}387388389/*390for (int i = 1; i <= hsp.Size(); i++)391if ( specpoints[hsp.Get(i)].HasSurfaces (s1, s2) &&392specpoints[hsp.Get(i)].unconditional == 0 &&393Dist2 (np, specpoints[hsp.Get(i)].p) < 1.2 * hd)394{395searchtree -> DeleteElement (hsp.Get(i)+1);396hsp.DeleteElement (i);397i--;398}399*/400}401402403ARRAY<Segment> refedges;404ARRAY<bool> refedgesinv;405406407AnalyzeEdge (s1_orig, s2_orig, s1, s2, pos, layer,408edgepoints,409refedges, refedgesinv);410411412for (int i = 0; i < refedges.Size(); i++)413refedges[i].edgenr = cntedge;414415416#ifdef DEVELOP417(*testout) << "edge " << cntedge << endl418<< "startp: " << specpoints[startpoints.Last()].p419<< ", v = " << specpoints[startpoints.Last()].v << endl420<< "copy = " << copyedge << endl421<< refedges.Size() << " refedges: ";422for (int i = 1; i <= refedges.Size(); i++)423(*testout) << " " << refedges.Get(i).si;424(*testout) << endl;425if (refedgesinv.Size())426(*testout) << "inv[1] = " << refedgesinv.Get(1) << endl;427#endif428429if (refedges.Size() == 0)430throw NgException ("Problem in edge detection");431432433if (!copyedge)434{435// (*testout) << "store edge" << endl;436// int oldnseg = mesh.GetNSeg();437438if (!shortedge)439StoreEdge (refedges, refedgesinv,440edgepoints, curvelength, layer, mesh);441else442StoreShortEdge (refedges, refedgesinv,443edgepoints, curvelength, layer, mesh);444445for(int i = 0; i < refedges.Size(); i++)446{447refedges[i].surfnr1 = geometry.GetSurfaceClassRepresentant(refedges[i].surfnr1);448refedges[i].surfnr2 = geometry.GetSurfaceClassRepresentant(refedges[i].surfnr2);449}450451452/*453for (int i = oldnseg+1; i <= mesh.GetNSeg(); i++)454for (int j = 1; j <= oldnseg; j++)455{456const Point<3> & l1p1 = mesh.Point (mesh.LineSegment(i).p1);457const Point<3> & l1p2 = mesh.Point (mesh.LineSegment(i).p2);458const Point<3> & l2p1 = mesh.Point (mesh.LineSegment(j).p1);459const Point<3> & l2p2 = mesh.Point (mesh.LineSegment(j).p2);460Vec<3> vl1(l1p1, l1p2);461for (double lamk = 0; lamk <= 1; lamk += 0.1)462{463Point<3> l2p = l1p1 + lamk * vl1;464double dist = sqrt (MinDistLP2 (l2p1, l2p2, l2p));465if (dist > 1e-12)466mesh.RestrictLocalH (l2p, 3*dist);467}468}469*/470}471else472{473CopyEdge (refedges, refedgesinv,474copyfromedge,475specpoints[startpoints.Get(copyfromedge)].p,476specpoints[endpoints.Get(copyfromedge)].p,477edgepoints.Get(1), edgepoints.Last(),478copyedgeidentification,479layer,480mesh);481}482483484// for(int i=0; i<hsp.Size(); i++)485// {486// (*testout) << "pos2 hsp["<<i<<"] ... " << specpoints[hsp[i]].p << endl;487// }488}489}490491492493494495496/*497If two or more edges share the same initial and end-points,498then they need at least two segments499*/500void EdgeCalculation ::501SplitEqualOneSegEdges (Mesh & mesh)502{503// int i, j;504SegmentIndex si;505PointIndex pi;506507ARRAY<int> osedges(cntedge);508INDEX_2_HASHTABLE<int> osedgesht (cntedge+1);509510osedges = 2;511512// count segments on edges513for (si = 0; si < mesh.GetNSeg(); si++)514{515const Segment & seg = mesh[si];516if (seg.seginfo && seg.edgenr >= 1 && seg.edgenr <= cntedge)517osedges.Elem(seg.edgenr)--;518}519520// flag one segment edges521for (int i = 0; i < cntedge; i++)522osedges[i] = (osedges[i] > 0) ? 1 : 0;523524for (si = 0; si < mesh.GetNSeg(); si++)525{526const Segment & seg = mesh[si];527if (seg.seginfo && seg.edgenr >= 1 && seg.edgenr <= cntedge)528{529if (osedges.Get(seg.edgenr))530{531INDEX_2 i2(seg.p1, seg.p2);532i2.Sort ();533if (osedgesht.Used (i2))534osedgesht.Set (i2, 2);535else536osedgesht.Set (i2, 1);537}538}539}540541542// one edge 1 segment, other 2 segments543// yes, it happens !544point_on_edge_problem = 0;545for (int i = 1; i <= osedgesht.GetNBags(); i++)546for (int j = 1; j <= osedgesht.GetBagSize(i); j++)547{548INDEX_2 i2;549int val;550osedgesht.GetData (i, j, i2, val);551552const Point<3> & p1 = mesh[PointIndex(i2.I1())];553const Point<3> & p2 = mesh[PointIndex(i2.I2())];554Vec<3> v = p2 - p1;555double vlen = v.Length();556v /= vlen;557for (pi = PointIndex::BASE;558pi < mesh.GetNP()+PointIndex::BASE; pi++)559560if (pi != i2.I1() && pi != i2.I2())561{562const Point<3> & p = mesh[pi];563Vec<3> v2 = p - p1;564double lam = (v2 * v);565if (lam > 0 && lam < vlen)566{567Point<3> hp = p1 + lam * v;568if (Dist (p, hp) < 1e-4 * vlen)569{570PrintWarning ("Point on edge !!!");571cout << "seg: " << i2 << ", p = " << pi << endl;572osedgesht.Set (i2, 2);573point_on_edge_problem = 1;574575(*testout) << "Point on edge" << endl576<< "seg = " << i2 << ", p = " << pi << endl577<< "pos = " << p << ", projected = " << hp << endl578<< "seg is = " << mesh.Point(i2.I1()) << " - " << mesh.Point(i2.I2()) << endl;579}580}581}582}583584585// insert new points586osedges = -1;587588int nseg = mesh.GetNSeg();589for (si = 0; si < nseg; si++)590{591const Segment & seg = mesh[si];592if (seg.seginfo && seg.edgenr >= 1 && seg.edgenr <= cntedge)593{594INDEX_2 i2(seg.p1, seg.p2);595i2.Sort ();596if (osedgesht.Used (i2) &&597osedgesht.Get (i2) == 2 &&598osedges.Elem(seg.edgenr) == -1)599{600Point<3> newp = Center (mesh[PointIndex(seg.p1)],601mesh[PointIndex(seg.p2)]);602603ProjectToEdge (geometry.GetSurface(seg.surfnr1),604geometry.GetSurface(seg.surfnr2),605newp);606607osedges.Elem(seg.edgenr) =608mesh.AddPoint (newp, mesh[PointIndex(seg.p1)].GetLayer(), EDGEPOINT);609meshpoint_tree -> Insert (newp, osedges.Elem(seg.edgenr));610}611}612}613614615for (int i = 1; i <= nseg; i++)616{617Segment & seg = mesh.LineSegment (i);618if (seg.edgenr >= 1 && seg.edgenr <= cntedge)619{620if (osedges.Get(seg.edgenr) != -1)621{622Segment newseg = seg;623newseg.p1 = osedges.Get(seg.edgenr);624seg.p2 = osedges.Get(seg.edgenr);625mesh.AddSegment (newseg);626}627}628}629630}631632633634void EdgeCalculation ::635FollowEdge (int pi1, int & ep, int & pos,636const ARRAY<int> & hsp,637double h, const Mesh & mesh,638ARRAY<Point<3> > & edgepoints,639ARRAY<double> & curvelength)640{641int s1, s2, s1_rep, s2_rep;642double len, steplen, cursteplen, loch;643Point<3> p, np, pnp;644Vec<3> a1, a2, t;645646ARRAY<int> locind;647648double size = geometry.MaxSize();649double epspointdist2 = size * 1e-6;650epspointdist2 = sqr (epspointdist2);651int uselocalh = mparam.uselocalh;652653654s1_rep = specpoints[hsp.Get(pi1)].s1;655s2_rep = specpoints[hsp.Get(pi1)].s2;656s1 = specpoints[hsp.Get(pi1)].s1_orig;657s2 = specpoints[hsp.Get(pi1)].s2_orig;658659p = specpoints[hsp.Get(pi1)].p;660//ProjectToEdge (geometry.GetSurface(s1),661// geometry.GetSurface(s2), p);662geometry.GetSurface(s1) -> CalcGradient (p, a1);663geometry.GetSurface(s2) -> CalcGradient (p, a2);664665t = Cross (a1, a2);666t.Normalize();667668pos = (specpoints[hsp.Get(pi1)].v * t) > 0;669if (!pos) t *= -1;670671672edgepoints.Append (p);673curvelength.Append (0);674len = 0;675676// (*testout) << "geometry.GetSurface(s1) -> LocH (p, 3, 1, h) " << geometry.GetSurface(s1) -> LocH (p, 3, 1, h)677// << " geometry.GetSurface(s2) -> LocH (p, 3, 1, h) " << geometry.GetSurface(s2) -> LocH (p, 3, 1, h) << endl;678679loch = min2 (geometry.GetSurface(s1) -> LocH (p, 3, 1, h),680geometry.GetSurface(s2) -> LocH (p, 3, 1, h));681682683684if (uselocalh)685{686double lh = mesh.GetH(p);687// (*testout) << "lh " << lh << endl;688if (lh < loch)689loch = lh;690}691692steplen = 0.1 * loch;693694do695{696if (multithread.terminate)697return;698699if (fabs (p(0)) + fabs (p(1)) + fabs (p(2)) > 100000*size)700{701ep = 0;702PrintWarning ("Give up line");703break;704}705706if (steplen > 0.1 * loch) steplen = 0.1 * loch;707708steplen *= 2;709do710{711steplen *= 0.5;712np = p + steplen * t;713pnp = np;714ProjectToEdge (geometry.GetSurface(s1),715geometry.GetSurface(s2), pnp);716}717while (Dist (np, pnp) > 0.1 * steplen);718719720cursteplen = steplen;721if (Dist (np, pnp) < 0.01 * steplen) steplen *= 2;722723724np = pnp;725ep = 0;726727double hvtmin = 1.5 * cursteplen;728729Box<3> boxp (p - (2 * cursteplen) * Vec<3> (1, 1, 1),730p + (2 * cursteplen) * Vec<3> (1, 1, 1));731732searchtree -> GetIntersecting (boxp.PMin(), boxp.PMax(), locind);733734for (int i = 0; i < locind.Size(); i++)735{736Vec<3> hv = specpoints[locind[i]].p - p;737if (hv.Length2() > 9 * cursteplen * cursteplen)738continue;739740double hvt = hv * t;741hv -= hvt * t;742743if (hv.Length() < 0.2 * cursteplen &&744hvt > 0 &&745// hvt < 1.5 * cursteplen &&746hvt < hvtmin &&747specpoints[locind[i]].unconditional == 1 &&748(specpoints[locind[i]].v + t).Length() < 0.4 )749{750Point<3> hep = specpoints[locind[i]].p;751ProjectToEdge (geometry.GetSurface(s1),752geometry.GetSurface(s2), hep);753754755if (Dist2 (hep, specpoints[locind[i]].p) < epspointdist2 )756{757geometry.GetSurface(s1) -> CalcGradient (hep, a1);758geometry.GetSurface(s2) -> CalcGradient (hep, a2);759Vec<3> ept = Cross (a1, a2);760ept /= ept.Length();761if (!pos) ept *= -1;762763if ( (specpoints[locind[i]].v + ept).Length() < 1e-4 )764{765np = specpoints[locind[i]].p;766767for (int jj = 0; jj < hsp.Size(); jj++)768if (hsp[jj] == locind[i])769ep = jj+1;770771if (!ep)772cerr << "endpoint not found" << endl;773// ep = i;774hvtmin = hvt;775// break;776}777}778}779}780781782783784/*785for (int i = 1; i <= hsp.Size(); i++)786{787if (!boxp.IsIn (specpoints[hsp.Get(i)].p))788continue;789790Vec<3> hv = specpoints[hsp.Get(i)].p - p;791if (hv.Length2() > 9 * cursteplen * cursteplen)792continue;793794double hvt = hv * t;795hv -= hvt * t;796797if (hv.Length() < 0.2 * cursteplen &&798hvt > 0 &&799// hvt < 1.5 * cursteplen &&800hvt < hvtmin &&801specpoints[hsp.Get(i)].unconditional == 1 &&802(specpoints[hsp.Get(i)].v + t).Length() < 0.4 )803{804Point<3> hep = specpoints[hsp.Get(i)].p;805ProjectToEdge (geometry.GetSurface(s1),806geometry.GetSurface(s2), hep);807808809if (Dist2 (hep, specpoints[hsp.Get(i)].p) < epspointdist2 )810{811geometry.GetSurface(s1) -> CalcGradient (hep, a1);812geometry.GetSurface(s2) -> CalcGradient (hep, a2);813Vec<3> ept = Cross (a1, a2);814ept /= ept.Length();815if (!pos) ept *= -1;816817if ( (specpoints[hsp.Get(i)].v + ept).Length() < 1e-4 )818{819np = specpoints[hsp.Get(i)].p;820ep = i;821hvtmin = hvt;822// break;823}824}825}826}827*/828829loch = min2 (geometry.GetSurface(s1_rep) -> LocH (np, 3, 1, h),830geometry.GetSurface(s2_rep) -> LocH (np, 3, 1, h));831loch = max2 (loch, mparam.minh);832833if (uselocalh)834{835double lh = mesh.GetH(np);836if (lh < loch)837loch = lh;838}839840841len += Dist (p, np) / loch;842edgepoints.Append (np);843curvelength.Append (len);844845p = np;846847geometry.GetSurface(s1) -> CalcGradient (p, a1);848geometry.GetSurface(s2) -> CalcGradient (p, a2);849t = Cross (a1, a2);850t.Normalize();851if (!pos) t *= -1;852}853while (! ep);854}855856857858859860861862void EdgeCalculation ::863AnalyzeEdge (int s1, int s2, int s1_rep, int s2_rep, int pos, int layer,864const ARRAY<Point<3> > & edgepoints,865ARRAY<Segment> & refedges,866ARRAY<bool> & refedgesinv)867{868int j, k, l;869int hi;870Point<3> hp;871Vec<3> t, a1, a2, m, n;872Segment seg;873Solid * locsol;874ARRAY<int> locsurfind, locsurfind2;875876ARRAY<int> edges_priority;877878double size = geometry.MaxSize();879bool debug = 0;880881#ifdef DEVELOP882debug = 1;883#endif884885if (debug)886{887(*testout) << "debug edge !!!" << endl;888(*testout) << "edgepoints = " << edgepoints << endl;889(*testout) << "s1, s2 = " << s1_rep << " - " << s2_rep << endl;890}891892refedges.SetSize(0);893refedgesinv.SetSize(0);894hp = Center (edgepoints[0], edgepoints[1]);895ProjectToEdge (geometry.GetSurface(s1), geometry.GetSurface(s2), hp);896897if (debug)898*testout << "hp = " << hp << endl;899900geometry.GetSurface(s1) -> CalcGradient (hp, a1);901geometry.GetSurface(s2) -> CalcGradient (hp, a2);902t = Cross (a1, a2);903t.Normalize();904if (!pos) t *= -1;905906907for (int i = 0; i < geometry.GetNTopLevelObjects(); i++)908{909if (geometry.GetTopLevelObject(i)->GetLayer() != layer)910continue;911912const Solid * sol = geometry.GetTopLevelObject(i)->GetSolid();913const Surface * surf = geometry.GetTopLevelObject(i)->GetSurface();914915sol -> TangentialSolid (hp, locsol, locsurfind, size*ideps);916917//*testout << "hp = " << hp << endl;918//(*testout) << "locsol: " << endl;919//if (locsol) locsol->Print(*testout);920//(*testout) << endl;921922923if (!locsol) continue;924925BoxSphere<3> boxp (hp, hp);926boxp.Increase (1e-8*size);927boxp.CalcDiamCenter();928929ReducePrimitiveIterator rpi(boxp);930UnReducePrimitiveIterator urpi;931932((Solid*)locsol) -> IterateSolid (rpi);933934locsol -> CalcSurfaceInverse ();935936if (!surf)937{938locsol -> GetTangentialSurfaceIndices (hp,locsurfind,ideps*size);939}940else941{942/*943if (fabs (surf->CalcFunctionValue (hp)) < 1e-6)944continue;945*/946locsurfind.SetSize(1);947locsurfind[0] = -1;948for (j = 0; j < geometry.GetNSurf(); j++)949if (geometry.GetSurface(j) == surf)950{951locsurfind[0] = j;952// geometry.GetSurfaceClassRepresentant(j);953break;954}955}956957((Solid*)locsol) -> IterateSolid (urpi);958959960if (debug)961(*testout) << "edge of tlo " << i << ", has " << locsurfind.Size() << " faces." << endl;962963964for (j = locsurfind.Size()-1; j >= 0; j--)965if (fabs (geometry.GetSurface(locsurfind[j])966->CalcFunctionValue (hp) ) > ideps*size)967locsurfind.Delete(j);968969if (debug)970(*testout) << locsurfind.Size() << " faces on hp" << endl;971972973974for (j = 0; j < locsurfind.Size(); j++)975{976int lsi = locsurfind[j];977int rlsi = geometry.GetSurfaceClassRepresentant(lsi);978979Vec<3> rn;980981// n is outer normal to solid982n = geometry.GetSurface(lsi) -> GetNormalVector (hp);983if (debug)984*testout << "n1 = " << n << endl;985if (geometry.GetSurface (lsi)->Inverse())986n *= -1;987988if (fabs (t * n) > 1e-4) continue;989if (debug)990{991(*testout) << "face " << locsurfind[j] << ", rep = " << rlsi992<< " has (t*n) = " << (t*n) << endl;993(*testout) << "n = " << n << endl;994}995996// rn is normal to class representant997rn = geometry.GetSurface(rlsi) -> GetNormalVector (hp);998if (debug)999{1000(*testout) << "rn = " << rn << endl;1001}10021003//if( n*rn < 0)1004// rn *= -1;10051006bool sameasref = ((n * rn) > 0);10071008//m = Cross (t, rn);1009m = Cross (t, n); if(!sameasref) m*=-1.;10101011m.Normalize();101210131014if (debug)1015(*testout) << "m = " << m << endl;101610171018//bool founddirection = false;1019//int k;1020double eps = 1e-8*size;10211022ARRAY<bool> pre_ok(2);10231024do1025{1026eps *= 0.5;1027pre_ok[0] = (locsol -> VectorIn2 (hp, m, n, eps) == IS_OUTSIDE &&1028locsol -> VectorIn2 (hp, m, -1. * n, eps) == IS_INSIDE);1029pre_ok[1] = (locsol -> VectorIn2 (hp, -1.*m, n, eps) == IS_OUTSIDE &&1030locsol -> VectorIn2 (hp, -1.*m, -1. * n, eps) == IS_INSIDE);1031}1032while(pre_ok[0] && pre_ok[1] && eps > 1e-16*size);10331034if (debug)1035{1036*testout << "eps = " << eps << ", size = " << size << endl;1037*testout << "pre_ok[0,1] = " << pre_ok[0] << "," << pre_ok[1] << endl;1038}10391040eps = 1e-8*size;104110421043for (k = 1; k <= 2; k ++)1044{1045bool edgeinv = (k == 2);10461047if (debug)1048{1049(*testout) << "onface(" << hp << ", " << m << ")= " << flush;1050(*testout) << locsol->OnFace (hp, m, eps) << flush;1051(*testout) << " n " << n << flush;1052(*testout) << " vec2in = "1053<< locsol -> VectorIn2 (hp, m, n, eps) << " and "1054<< locsol -> VectorIn2 (hp, m, -1 * n, eps) << endl;1055}10561057// if (locsol -> OnFace (hp, m))105810591060// one side must be inside, the other must be outside1061bool ok = (pre_ok[k-1] ||1062(locsol -> VectorIn2 (hp, m, n, eps) == IS_OUTSIDE &&1063locsol -> VectorIn2 (hp, m, -1 * n, eps) == IS_INSIDE));10641065if (debug)1066(*testout) << "ok (before) " << ok << endl;10671068// compute second order approximation1069// curve = hp + t m + t*t/2 m21070Vec<3> grad, m2;1071Mat<3> hesse;1072geometry.GetSurface(lsi) -> CalcGradient (hp, grad);1073geometry.GetSurface(lsi) -> CalcHesse (hp, hesse);1074double fac = -(m * (hesse * m)) / (grad * grad);1075m2 = fac * grad;1076// (*testout) << "hp = " << hp << ", m = " << m << ", m2 = " << m2 << endl;10771078Solid * locsol2;1079locsol -> TangentialSolid3 (hp, m, m2, locsol2, locsurfind2, ideps*size);1080if (!locsol2) ok = 0;1081delete locsol2;108210831084if (ok)1085{1086if (debug)1087(*testout) << "is true" << endl;1088hi = 0;1089for (l = 1; !hi && l <= refedges.Size(); l++)1090{1091if (refedges.Get(l).si == rlsi && // JS sept 20061092// if (refedges.Get(l).si == lsi &&1093refedgesinv.Get(l) == edgeinv)1094{1095hi = l;1096}1097}10981099if (!hi)1100{1101seg.si = rlsi; // JS Sept 20061102// seg.si = lsi;1103seg.domin = -1;1104seg.domout = -1;1105seg.tlosurf = -1;1106//seg.surfnr1 = s1_rep;1107//seg.surfnr2 = s2_rep;1108seg.surfnr1 = s1;1109seg.surfnr2 = s2;1110hi = refedges.Append (seg);1111refedgesinv.Append (edgeinv);1112edges_priority.Append((pre_ok[k-1]) ? 1 : 0);1113}1114else1115{1116if(edges_priority[hi-1] / 10 == -i-1)1117edges_priority[hi-1] = 10*(i+1);1118else1119edges_priority[hi-1] = -10*(i+1);1120}11211122if (!surf)1123{1124if (sameasref)1125refedges.Elem(hi).domin = i;1126else1127refedges.Elem(hi).domout = i;1128}1129else1130refedges.Elem(hi).tlosurf = i;11311132if(pre_ok[k-1])1133edges_priority[hi-1] = 1;113411351136if (debug)1137(*testout) << "add ref seg:"1138<< "si = " << refedges.Get(hi).si1139<< ", domin = " << refedges.Get(hi).domin1140<< ", domout = " << refedges.Get(hi).domout1141<< ", surfnr1/2 = " << refedges.Get(hi).surfnr11142<< ", " << refedges.Get(hi).surfnr21143<< ", inv = " << refedgesinv.Get(hi)1144<< ", refedgenr = " << hi1145<< ", priority = " << edges_priority[hi-1]1146<< ", hi = " << hi1147<< endl;1148}1149else1150{1151if (debug)1152(*testout) << "is false" << endl;1153}1154m *= -1;1155}1156}1157delete locsol;1158}115911601161if (debug)1162{1163*testout << "Refsegments, before delete: " << endl << refedges << endl;1164*testout << "inv: " << endl << refedgesinv << endl;1165}11661167BitArray todelete(refedges.Size());1168todelete.Clear();116911701171for(int i=0; i<refedges.Size()-1; i++)1172{1173for(j=i+1; !todelete.Test(i) && j<refedges.Size(); j++)1174{1175if(todelete.Test(j))1176continue;11771178if(refedges[i].si == refedges[j].si &&1179refedges[i].domin == refedges[j].domin &&1180refedges[i].domout == refedges[j].domout &&1181geometry.GetSurfaceClassRepresentant(refedges[i].surfnr1) == geometry.GetSurfaceClassRepresentant(refedges[j].surfnr1) &&1182geometry.GetSurfaceClassRepresentant(refedges[i].surfnr2) == geometry.GetSurfaceClassRepresentant(refedges[j].surfnr2)1183// && refedgesinv[i] == refedgesinv[j] // JS, 200608021184)1185{1186if(debug)1187(*testout) << "equal segments: " << refedges[i] << " pri " << edges_priority[i]1188<< " tlosurf " << refedges[i].tlosurf1189<< "\n and " << refedges[j] << " pri " << edges_priority[j]1190<< " tlosurf " << refedges[i].tlosurf << endl;11911192if(edges_priority[i] < 10 && edges_priority[i] < edges_priority[j])1193{1194todelete.Set(i);1195}1196else if (edges_priority[j] < 10 && edges_priority[i] > edges_priority[j])1197{1198todelete.Set(j);1199}1200}1201}12021203}12041205int num = refedges.Size();12061207for(int i=refedges.Size()-1; num>2 && i>=0; i--)1208if(todelete.Test(i))1209{1210refedges.Delete(i);1211refedgesinv.Delete(i);1212num--;1213}121412151216if (debug)1217{1218*testout << "Refsegments: " << endl << refedges << endl;1219}1220}1221122212231224void EdgeCalculation ::1225StoreEdge (const ARRAY<Segment> & refedges,1226const ARRAY<bool> & refedgesinv,1227const ARRAY<Point<3> > & edgepoints,1228const ARRAY<double> & curvelength,1229int layer,1230Mesh & mesh)1231{12321233// Calculate optimal element-length1234int i, j, k;1235PointIndex pi;1236int ne;12371238double len, corr, lam;1239PointIndex thispi, lastpi;1240Point<3> p, np;1241Segment seg;12421243const Surface * surf1 = geometry.GetSurface (refedges.Get(1).surfnr1);1244const Surface * surf2 = geometry.GetSurface (refedges.Get(1).surfnr2);12451246(*testout) << "s1 " << refedges.Get(1).surfnr1 << " s2 " << refedges.Get(1).surfnr21247<< " rs1 " << geometry.GetSurfaceClassRepresentant(refedges.Get(1).surfnr1)1248<< " rs2 " << geometry.GetSurfaceClassRepresentant(refedges.Get(1).surfnr2) << endl;12491250len = curvelength.Last();1251ne = int (len + 0.5);1252if (ne == 0) ne = 1;1253if (Dist (edgepoints.Get(1), edgepoints.Last()) < 1e-8*geometry.MaxSize() &&1254ne <= 6)1255ne = 6;1256corr = len / ne;12571258// generate initial point1259p = edgepoints.Get(1);1260lastpi = -1;12611262/*1263for (pi = PointIndex::BASE;1264pi < mesh.GetNP()+PointIndex::BASE; pi++)1265if (Dist (mesh[pi], p) < 1e-6)1266{1267lastpi = pi;1268break;1269}1270*/12711272const double di=1e-7*geometry.MaxSize();12731274ARRAY<int> locsearch;1275meshpoint_tree -> GetIntersecting (p-Vec<3> (di,di,di),1276p+Vec<3> (di,di,di), locsearch);1277if (locsearch.Size())1278lastpi = locsearch[0];1279128012811282if (lastpi == -1)1283{1284lastpi = mesh.AddPoint (p, layer, FIXEDPOINT);1285meshpoint_tree -> Insert (p, lastpi);1286// (*testout) << "test1, store point " << lastpi << ", p = " << p << endl;1287}12881289j = 1;1290for (i = 1; i <= ne; i++)1291{1292while (curvelength.Get(j) < i * corr && j < curvelength.Size()) j++;129312941295lam = (i * corr - curvelength.Get(j-1)) /1296(curvelength.Get(j) - curvelength.Get(j-1));12971298np(0) = (1-lam) * edgepoints.Get(j-1)(0) + lam * edgepoints.Get(j)(0);1299np(1) = (1-lam) * edgepoints.Get(j-1)(1) + lam * edgepoints.Get(j)(1);1300np(2) = (1-lam) * edgepoints.Get(j-1)(2) + lam * edgepoints.Get(j)(2);13011302thispi = -1;1303if (i == ne)1304{1305/*1306for (pi = PointIndex::BASE;1307pi < mesh.GetNP()+PointIndex::BASE; pi++)1308if (Dist(mesh[pi], np) < 1e-6)1309thispi = pi;1310*/13111312meshpoint_tree -> GetIntersecting (np-Vec<3> (di,di,di),1313np+Vec<3> (di,di,di), locsearch);1314if (locsearch.Size())1315thispi = locsearch[0];1316}13171318if (thispi == -1)1319{1320ProjectToEdge (surf1, surf2, np);1321thispi = mesh.AddPoint (np, layer, (i==ne) ? FIXEDPOINT : EDGEPOINT);13221323meshpoint_tree -> Insert (np, thispi);1324// (*testout) << "test2, store point " << thispi << ", p = " << np << endl;1325}13261327for (k = 1; k <= refedges.Size(); k++)1328{1329if (refedgesinv.Get(k))1330{1331seg.p1 = lastpi;1332seg.p2 = thispi;1333}1334else1335{1336seg.p1 = thispi;1337seg.p2 = lastpi;1338}1339seg.si = refedges.Get(k).si;1340seg.domin = refedges.Get(k).domin;1341seg.domout = refedges.Get(k).domout;1342seg.tlosurf = refedges.Get(k).tlosurf;1343seg.edgenr = refedges.Get(k).edgenr;1344seg.surfnr1 = refedges.Get(k).surfnr1;1345seg.surfnr2 = refedges.Get(k).surfnr2;1346seg.seginfo = 0;1347if (k == 1) seg.seginfo = (refedgesinv.Get(k)) ? 2 : 1;1348mesh.AddSegment (seg);1349//(*testout) << "add seg " << mesh[seg.p1] << "-" << mesh[seg.p2] << endl;1350//(*testout) << "refedge " << k << " surf1 " << seg.surfnr1 << " surf2 " << seg.surfnr2 << " inv " << refedgesinv.Get(k) << endl;13511352double maxh = min2 (geometry.GetSurface(seg.surfnr1)->GetMaxH(),1353geometry.GetSurface(seg.surfnr2)->GetMaxH());13541355if (seg.domin != -1)1356{1357const Solid * s1 =1358geometry.GetTopLevelObject(seg.domin) -> GetSolid();1359maxh = min2 (maxh, s1->GetMaxH());1360maxh = min2 (maxh, geometry.GetTopLevelObject(seg.domin)->GetMaxH());1361mesh.RestrictLocalH (p, maxh);1362mesh.RestrictLocalH (np, maxh);1363}1364if (seg.domout != -1)1365{1366const Solid * s1 =1367geometry.GetTopLevelObject(seg.domout) -> GetSolid();1368maxh = min2 (maxh, s1->GetMaxH());1369maxh = min2 (maxh, geometry.GetTopLevelObject(seg.domout)->GetMaxH());1370mesh.RestrictLocalH (p, maxh);1371mesh.RestrictLocalH (np, maxh);1372}1373if (seg.tlosurf != -1)1374{1375double hi = geometry.GetTopLevelObject(seg.tlosurf) -> GetMaxH();1376maxh = min2 (maxh, hi);1377mesh.RestrictLocalH (p, maxh);1378mesh.RestrictLocalH (np, maxh);1379}1380}13811382p = np;1383lastpi = thispi;1384}13851386#ifdef DEVELOP1387(*testout) << " eplast = " << lastpi << " = " << p << endl;1388#endif1389}1390139113921393139413951396void EdgeCalculation ::1397StoreShortEdge (const ARRAY<Segment> & refedges,1398const ARRAY<bool> & refedgesinv,1399const ARRAY<Point<3> > & edgepoints,1400const ARRAY<double> & curvelength,1401int layer,1402Mesh & mesh)1403{14041405// Calculate optimal element-length1406PointIndex pi;1407// int ne;1408Segment seg;14091410/*1411double len, corr, lam;1412int thispi, lastpi;1413Point<3> p, np;141414151416const Surface * surf1 = geometry.GetSurface (refedges.Get(1).surfnr1);1417const Surface * surf2 = geometry.GetSurface (refedges.Get(1).surfnr2);14181419len = curvelength.Last();1420ne = int (len + 0.5);1421if (ne == 0) ne = 1;1422if (Dist2 (edgepoints[1], edgepoints.Last()) < 1e-8 &&1423ne <= 6)1424ne = 6;1425corr = len / ne;1426*/14271428// generate initial point1429Point<3> p = edgepoints[0];1430PointIndex pi1 = -1;1431for (pi = PointIndex::BASE;1432pi < mesh.GetNP()+PointIndex::BASE; pi++)14331434if (Dist (mesh[pi], p) < 1e-6*geometry.MaxSize())1435{1436pi1 = pi;1437break;1438}14391440if (pi1 == -1)1441{1442pi1 = mesh.AddPoint (p, layer, FIXEDPOINT);1443meshpoint_tree -> Insert (p, pi1);1444// (*testout) << "test3, store point " << pi1 << ", p = " << p << endl;1445}14461447p = edgepoints.Last();1448PointIndex pi2 = -1;1449for (pi = PointIndex::BASE;1450pi < mesh.GetNP()+PointIndex::BASE; pi++)14511452if (Dist (mesh[pi], p) < 1e-6*geometry.MaxSize())1453{1454pi2 = pi;1455break;1456}1457if (pi2==-1)1458{1459pi2 = mesh.AddPoint (p, layer, FIXEDPOINT);1460meshpoint_tree -> Insert (p, pi2);1461// (*testout) << "test4, store point " << pi2 << ", p = " << p << endl;1462}14631464/*14651466j = 1;1467for (i = 1; i <= ne; i++)1468{1469while (curvelength[j] < i * corr && j < curvelength.Size()) j++;14701471lam = (i * corr - curvelength[j-1]) /1472(curvelength[j] - curvelength[j-1]);14731474np(0) = (1-lam) * edgepoints[j-1](0) + lam * edgepoints[j](0);1475np(1) = (1-lam) * edgepoints[j-1](1) + lam * edgepoints[j](1);1476np(2) = (1-lam) * edgepoints[j-1](2) + lam * edgepoints[j](2);147714781479thispi = 0;1480if (i == ne)1481for (j = 1; j <= mesh.GetNP(); j++)1482if (Dist(mesh.Point(j), np) < 1e-6)1483thispi = j;14841485if (!thispi)1486{1487ProjectToEdge (surf1, surf2, np);1488thispi = mesh.AddPoint (np);1489}1490*/14911492// (*testout) << "short edge " << pi1 << " - " << pi2 << endl;14931494for (int k = 1; k <= refedges.Size(); k++)1495{1496if (refedgesinv.Get(k))1497{1498seg.p1 = pi1;1499seg.p2 = pi2;1500}1501else1502{1503seg.p1 = pi2;1504seg.p2 = pi1;1505}15061507seg.si = refedges.Get(k).si;1508seg.domin = refedges.Get(k).domin;1509seg.domout = refedges.Get(k).domout;1510seg.tlosurf = refedges.Get(k).tlosurf;1511seg.edgenr = refedges.Get(k).edgenr;1512seg.surfnr1 = refedges.Get(k).surfnr1;1513seg.surfnr2 = refedges.Get(k).surfnr2;1514seg.seginfo = 0;1515if (k == 1) seg.seginfo = (refedgesinv.Get(k)) ? 2 : 1;1516mesh.AddSegment (seg);1517// (*testout) << "add seg " << seg.p1 << "-" << seg.p2 << endl;1518}1519}15201521152215231524152515261527void EdgeCalculation ::1528CopyEdge (const ARRAY<Segment> & refedges,1529const ARRAY<bool> & refedgesinv,1530int copyfromedge,1531const Point<3> & fromstart, const Point<3> & fromend,1532const Point<3> & tostart, const Point<3> & toend,1533int copyedgeidentification,1534int layer,1535Mesh & mesh)1536{1537int k;1538PointIndex pi;15391540double size = geometry.MaxSize();15411542// copy start and end points1543for (int i = 1; i <= 2; i++)1544{1545Point<3> fromp =1546(i == 1) ? fromstart : fromend;1547Point<3> top =1548(i == 1) ? tostart : toend;15491550PointIndex frompi = -1;1551PointIndex topi = -1;1552for (pi = PointIndex::BASE;1553pi < mesh.GetNP()+PointIndex::BASE; pi++)1554{1555if (Dist2 (mesh[pi], fromp) <= 1e-16*size)1556frompi = pi;1557if (Dist2 (mesh[pi], top) <= 1e-16*size)1558topi = pi;1559}156015611562if (topi == -1)1563{1564topi = mesh.AddPoint (top, layer, FIXEDPOINT);1565meshpoint_tree -> Insert (top, topi);1566}15671568const Identification & csi =1569(*geometry.identifications.Get(copyedgeidentification));157015711572if (csi.Identifyable (mesh[frompi], mesh[topi]))1573mesh.GetIdentifications().Add(frompi, topi, copyedgeidentification);1574else if (csi.Identifyable (mesh[topi], mesh[frompi]))1575mesh.GetIdentifications().Add(topi, frompi, copyedgeidentification);1576else1577{1578cerr << "edgeflw.cpp: should identify, but cannot";1579exit(1);1580}1581#ifdef DEVELOP1582(*testout) << "adding identification " << mesh[frompi] << "; " << mesh[topi]1583<< " (id " << copyedgeidentification <<")" << endl;1584#endif158515861587/*1588(*testout) << "Add Identification from CopyEdge, p1 = "1589<< mesh[PointIndex(frompi)] << ", p2 = "1590<< mesh[PointIndex(topi)] << endl;15911592mesh.GetIdentifications().Add(frompi, topi, copyedgeidentification);1593*/1594}15951596int oldns = mesh.GetNSeg();1597for (int i = 1; i <= oldns; i++)1598{1599// real copy, since array might be reallocated !!1600const Segment oldseg = mesh.LineSegment(i);1601if (oldseg.edgenr != copyfromedge)1602continue;1603if (oldseg.seginfo == 0)1604continue;16051606int pi1 = oldseg.p1;1607int pi2 = oldseg.p2;16081609int npi1 = geometry.identifications.Get(copyedgeidentification)1610-> GetIdentifiedPoint (mesh, pi1);1611int npi2 = geometry.identifications.Get(copyedgeidentification)1612-> GetIdentifiedPoint (mesh, pi2);16131614//(*testout) << "copy edge, pts = " << npi1 << " - " << npi2 << endl;16151616Segment seg;16171618for (k = 1; k <= refedges.Size(); k++)1619{1620bool inv = refedgesinv.Get(k);16211622// other edge is inverse1623if (oldseg.seginfo == 1)1624inv = !inv;16251626// (*testout) << "inv, now = " << inv << endl;16271628if (inv)1629{1630seg.p1 = npi1;1631seg.p2 = npi2;1632}1633else1634{1635seg.p1 = npi2;1636seg.p2 = npi1;1637}1638seg.si = refedges.Get(k).si;1639seg.domin = refedges.Get(k).domin;1640seg.domout = refedges.Get(k).domout;1641seg.tlosurf = refedges.Get(k).tlosurf;1642seg.edgenr = refedges.Get(k).edgenr;1643seg.surfnr1 = refedges.Get(k).surfnr1;1644seg.surfnr2 = refedges.Get(k).surfnr2;1645seg.seginfo = 0;1646if (k == 1) seg.seginfo = refedgesinv.Get(k) ? 2 : 1;1647mesh.AddSegment (seg);1648// (*testout) << "copy seg " << seg.p1 << "-" << seg.p2 << endl;1649#ifdef DEVELOP16501651(*testout) << "copy seg, face = " << seg.si << ": "1652<< " inv = " << inv << ", refinv = " << refedgesinv.Get(k)1653<< mesh.Point(seg.p1) << ", " << mesh.Point(seg.p2) << endl;1654#endif16551656}16571658}1659}16601661166216631664166516661667void EdgeCalculation ::1668FindClosedSurfaces (double h, Mesh & mesh)1669{1670// if there is no special point at a sphere, one has to add a segment pair16711672int i, j;1673int nsol;1674int nsurf = geometry.GetNSurf();1675int layer(0);16761677BitArray pointatsurface (nsurf);1678Point<3> p1, p2;1679Vec<3> nv, tv;1680Solid * tansol;1681ARRAY<int> tansurfind;1682// const Solid * sol;16831684double size = geometry.MaxSize();1685nsol = geometry.GetNTopLevelObjects();168616871688pointatsurface.Clear();16891690/*1691for (i = 1; i <= specpoints.Size(); i++)1692{1693int classrep;16941695classrep = geometry.GetSurfaceClassRepresentant (specpoints[i].s1);1696pointatsurface.Set (classrep);1697classrep = geometry.GetSurfaceClassRepresentant (specpoints[i].s2);1698pointatsurface.Set (classrep);1699// pointatsurface.Set (specpoints[i].s1);1700// pointatsurface.Set (specpoints[i].s2);1701}1702*/1703for (i = 1; i <= mesh.GetNSeg(); i++)1704{1705const Segment & seg = mesh.LineSegment(i);1706int classrep;17071708#ifdef DEVELOP1709(*testout) << seg.surfnr1 << ", " << seg.surfnr2 << ", si = " << seg.si << endl;1710#endif1711classrep = geometry.GetSurfaceClassRepresentant (seg.si);17121713pointatsurface.Set (classrep);1714}171517161717for (i = 0; i < nsurf; i++)1718{1719int classrep = geometry.GetSurfaceClassRepresentant (i);17201721if (!pointatsurface.Test(classrep))1722{1723const Surface * s = geometry.GetSurface(i);1724p1 = s -> GetSurfacePoint();1725nv = s -> GetNormalVector (p1);17261727double hloc =1728min2 (s->LocH (p1, 3, 1, h), mesh.GetH(p1));17291730tv = nv.GetNormal ();1731tv *= (hloc / tv.Length());1732p2 = p1 + tv;1733s->Project (p2);173417351736Segment seg1;1737seg1.si = i;1738seg1.domin = -1;1739seg1.domout = -1;17401741Segment seg2;1742seg2.si = i;1743seg2.domin = -1;1744seg2.domout = -1;17451746seg1.surfnr1 = i;1747seg2.surfnr1 = i;1748seg1.surfnr2 = i;1749seg2.surfnr2 = i;17501751for (j = 0; j < nsol; j++)1752{1753if (geometry.GetTopLevelObject(j)->GetSurface())1754continue;17551756const Solid * sol = geometry.GetTopLevelObject(j)->GetSolid();1757sol -> TangentialSolid (p1, tansol, tansurfind, ideps*size);1758layer = geometry.GetTopLevelObject(j)->GetLayer();175917601761if (tansol)1762{1763tansol -> GetSurfaceIndices (tansurfind);17641765if (tansurfind.Size() == 1 && tansurfind.Get(1) == i)1766{1767if (!tansol->VectorIn(p1, nv))1768{1769seg1.domin = j;1770seg2.domin = j;1771seg1.tlosurf = j;1772seg2.tlosurf = j;1773}1774else1775{1776seg1.domout = j;1777seg2.domout = j;1778seg1.tlosurf = j;1779seg2.tlosurf = j;1780}1781// seg.s2 = i;1782// seg.invs1 = surfaces[i] -> Inverse();1783// seg.invs2 = ! (surfaces[i] -> Inverse());1784}1785delete tansol;1786}1787}178817891790if (seg1.domin != -1 || seg1.domout != -1)1791{1792mesh.AddPoint (p1, layer, EDGEPOINT);1793mesh.AddPoint (p2, layer, EDGEPOINT);1794seg1.p1 = mesh.GetNP()-1;1795seg1.p2 = mesh.GetNP();1796seg2.p2 = mesh.GetNP()-1;1797seg2.p1 = mesh.GetNP();1798seg1.geominfo[0].trignum = 1;1799seg1.geominfo[1].trignum = 1;1800seg2.geominfo[0].trignum = 1;1801seg2.geominfo[1].trignum = 1;1802mesh.AddSegment (seg1);1803mesh.AddSegment (seg2);18041805PrintMessage (5, "Add line segment to smooth surface");18061807#ifdef DEVELOP1808(*testout) << "Add segment at smooth surface " << i;1809if (i != classrep) (*testout) << ", classrep = " << classrep;1810(*testout) << ": "1811<< mesh.Point (mesh.GetNP()-1) << " - "1812<< mesh.Point (mesh.GetNP()) << endl;1813#endif1814}1815}1816}1817}18181819}182018211822