Path: blob/devel/ElmerGUI/netgen/libsrc/stlgeom/stlline.cpp
3206 views
#include <mystdlib.h>12#include <myadt.hpp>3#include <linalg.hpp>4#include <gprim.hpp>56#include <meshing.hpp>78#include "stlgeom.hpp"910namespace netgen11{1213//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++14//++++++++++++++ EDGE DATA ++++++++++++++++++++++++++++++++++++++++++15//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++161718/*19void STLEdgeData :: Write(ofstream& of) const20{21of // << angle << " "22<< p1 << " "23<< p2 << " "24<< lt << " "25<< rt << " "26// << status27<< endl;28}2930void STLEdgeData :: Read(ifstream& ifs)31{32// ifs >> angle;33ifs >> p1;34ifs >> p2;35ifs >> lt;36ifs >> rt;37// ifs >> status;38}394041int STLEdgeData :: GetStatus () const42{43if (topedgenr <= 0 || topedgenr > top->GetNTE()) return 0;44return top->GetTopEdge (topedgenr).GetStatus();45}4647void STLEdgeData ::SetStatus (int stat)48{49if (topedgenr >= 1 && topedgenr <= top->GetNTE())50top->GetTopEdge (topedgenr).SetStatus(stat);51}525354float STLEdgeData :: CosAngle() const55{56return top->GetTopEdge (topedgenr).CosAngle();57}58596061void STLEdgeDataList :: ResetAll()62{63int i;64for (i = 1; i <= edgedata.Size(); i++)65{66edgedata.Elem(i).SetUndefined();67}68}6970void STLEdgeDataList :: ResetCandidates()71{72int i;73for (i = 1; i <= edgedata.Size(); i++)74{75if (edgedata.Get(i).Candidate())76{edgedata.Elem(i).SetUndefined();}77}78}7980int STLEdgeDataList :: GetNConfEdges() const81{82int i;83int cnt = 0;84for (i = 1; i <= edgedata.Size(); i++)85{86if (edgedata.Get(i).Confirmed()) {cnt++;}87}88return cnt;89}9091void STLEdgeDataList :: ConfirmCandidates()92{93int i;94for (i = 1; i <= edgedata.Size(); i++)95{96if (edgedata.Get(i).Candidate())97{edgedata.Elem(i).SetConfirmed();}98}99}100101int STLEdgeDataList :: GetEdgeNum(int np1, int np2) const102{103INDEX_2 ed(np1,np2);104ed.Sort();105if (hashtab.Used(ed))106{107return hashtab.Get(ed);108}109110// int i;111// for (i = 1; i <= Size(); i++)112// {113// if ((Get(i).p1 == np1 && Get(i).p2 == np2) ||114// (Get(i).p2 == np1 && Get(i).p1 == np2))115// {116// return i;117// }118// }119120return 0;121}122123const STLEdgeDataList& STLEdgeDataList :: operator=(const STLEdgeDataList& edl)124{125int i;126SetSize(edl.Size());127for (i = 1; i <= Size(); i++)128{129Add(edl.Get(i), i);130}131return *this;132}133134void STLEdgeDataList :: Add(const STLEdgeData& ed, int i)135{136INDEX_2 edge(ed.p1,ed.p2);137edge.Sort();138hashtab.Set(edge, i);139Elem(i) = ed;140AddEdgePP(ed.p1,i);141AddEdgePP(ed.p2,i);142}143144void STLEdgeDataList :: Write(ofstream& of) const145{146of.precision(16);147int i;148of << Size() << endl;149150for (i = 1; i <= Size(); i++)151{152Get(i).Write(of);153}154}155156void STLEdgeDataList :: Read(ifstream& ifs)157{158int i,n;159ifs >> n;160161SetSize(n);162STLEdgeData ed;163for (i = 1; i <= n; i++)164{165ed.Read(ifs);166Add(ed,i);167}168}169170int STLEdgeDataList :: GetNEPPStat(int p, int status) const171{172int i;173int cnt = 0;174for (i = 1; i <= GetNEPP(p); i++)175{176if (Get(GetEdgePP(p,i)).GetStatus() == status)177{178cnt++;179}180}181return cnt;182}183184int STLEdgeDataList :: GetNConfCandEPP(int p) const185{186int i;187int cnt = 0;188for (i = 1; i <= GetNEPP(p); i++)189{190if (Get(GetEdgePP(p,i)).ConfCand())191{192cnt++;193}194}195return cnt;196}197198199void STLEdgeDataList :: BuildLineWithEdge(int ep1, int ep2, ARRAY<twoint>& line)200{201int status = Get(GetEdgeNum(ep1,ep2)).GetStatus();202203int found, pstart, p, en, pnew, ennew;204int closed = 0;205int j, i;206for (j = 1; j <= 2; j++)207{208if (j == 1) {p = ep1;}209if (j == 2) {p = ep2;}210211pstart = p;212en = GetEdgeNum(ep1,ep2);213214found = 1;215while (found && !closed)216{217found = 0;218219if (GetNEPPStat(p,status) == 2)220{221for (i = 1; i <= GetNEPP(p); i++)222{223const STLEdgeData& e = Get(GetEdgePP(p,i));224if (GetEdgePP(p,i) != en && e.GetStatus() == status)225{226if (e.p1 == p)227{pnew = e.p2;}228else229{pnew = e.p1;}230231ennew = GetEdgePP(p,i);232}233}234if (pnew == pstart) {closed = 1;}235else236{237line.Append(twoint(p,pnew));238p = pnew;239en = ennew;240found = 1;241}242}243}244}245246}247*/248249250251252STLEdgeDataList :: STLEdgeDataList (STLTopology & ageom)253: geom(ageom)254{255;256}257258STLEdgeDataList :: ~STLEdgeDataList()259{260;261}262263264void STLEdgeDataList :: Store ()265{266int i, ne = geom.GetNTE();267storedstatus.SetSize(ne);268for (i = 1; i <= ne; i++)269{270storedstatus.Elem(i) = Get(i).GetStatus();271}272}273274void STLEdgeDataList :: Restore ()275{276int i, ne = geom.GetNTE();277if (storedstatus.Size() == ne)278for (i = 1; i <= ne; i++)279geom.GetTopEdge(i).SetStatus (storedstatus.Elem(i));280}281282283void STLEdgeDataList :: ResetAll()284{285int i, ne = geom.GetNTE();286for (i = 1; i <= ne; i++)287geom.GetTopEdge (i).SetStatus (ED_UNDEFINED);288}289290int STLEdgeDataList :: GetNConfEdges() const291{292int i, ne = geom.GetNTE();293int cnt = 0;294for (i = 1; i <= ne; i++)295if (geom.GetTopEdge (i).GetStatus() == ED_CONFIRMED)296cnt++;297return cnt;298}299300void STLEdgeDataList :: ChangeStatus(int status1, int status2)301{302int i, ne = geom.GetNTE();303for (i = 1; i <= ne; i++)304if (geom.GetTopEdge (i).GetStatus() == status1)305geom.GetTopEdge (i).SetStatus (status2);306}307308/*309void STLEdgeDataList :: Add(const STLEdgeData& ed, int i)310{311INDEX_2 edge(ed.p1,ed.p2);312edge.Sort();313hashtab.Set(edge, i);314Elem(i) = ed;315AddEdgePP(ed.p1,i);316AddEdgePP(ed.p2,i);317}318*/319320void STLEdgeDataList :: Write(ofstream& of) const321{322323/*324of.precision(16);325int i;326of << Size() << endl;327328for (i = 1; i <= Size(); i++)329{330Get(i).Write(of);331}332333*/334of.precision(16);335int i, ne = geom.GetNTE();336//of << GetNConfEdges() << endl;337of << geom.GetNTE() << endl;338339for (i = 1; i <= ne; i++)340{341const STLTopEdge & edge = geom.GetTopEdge(i);342//if (edge.GetStatus() == ED_CONFIRMED)343of << edge.GetStatus() << " ";344345const Point3d & p1 = geom.GetPoint (edge.PNum(1));346const Point3d & p2 = geom.GetPoint (edge.PNum(2));347of << p1.X() << " "348<< p1.Y() << " "349<< p1.Z() << " "350<< p2.X() << " "351<< p2.Y() << " "352<< p2.Z() << endl;353}354355}356357void STLEdgeDataList :: Read(ifstream& ifs)358{359int i, nce;360Point3d p1, p2;361int pi1, pi2;362int status, ednum;363364ifs >> nce;365for (i = 1; i <= nce; i++)366{367ifs >> status;368ifs >> p1.X() >> p1.Y() >> p1.Z();369ifs >> p2.X() >> p2.Y() >> p2.Z();370371pi1 = geom.GetPointNum (p1);372pi2 = geom.GetPointNum (p2);373ednum = geom.GetTopEdgeNum (pi1, pi2);374375376if (ednum)377{378geom.GetTopEdge(ednum).SetStatus (status);379// geom.GetTopEdge (ednum).SetStatus (ED_CONFIRMED);380}381}382/*383int i,n;384ifs >> n;385386SetSize(n);387STLEdgeData ed;388for (i = 1; i <= n; i++)389{390ed.Read(ifs);391Add(ed,i);392}393*/394}395396int STLEdgeDataList :: GetNEPPStat(int p, int status) const397{398int i;399int cnt = 0;400for (i = 1; i <= GetNEPP(p); i++)401{402if (Get(GetEdgePP(p,i)).GetStatus() == status)403{404cnt++;405}406}407return cnt;408}409410int STLEdgeDataList :: GetNConfCandEPP(int p) const411{412int i;413int cnt = 0;414for (i = 1; i <= GetNEPP(p); i++)415{416if (Get(GetEdgePP(p,i)).GetStatus() == ED_CANDIDATE ||417Get(GetEdgePP(p,i)).GetStatus() == ED_CONFIRMED)418{419cnt++;420}421}422return cnt;423}424425426void STLEdgeDataList :: BuildLineWithEdge(int ep1, int ep2, ARRAY<twoint>& line)427{428int status = Get(GetEdgeNum(ep1,ep2)).GetStatus();429430int found, pstart, p(0), en, pnew(0), ennew(0);431int closed = 0;432int j, i;433for (j = 1; j <= 2; j++)434{435if (j == 1) {p = ep1;}436if (j == 2) {p = ep2;}437438pstart = p;439en = GetEdgeNum(ep1,ep2);440441found = 1;442while (found && !closed)443{444found = 0;445446if (GetNEPPStat(p,status) == 2)447{448for (i = 1; i <= GetNEPP(p); i++)449{450const STLTopEdge & e = Get(GetEdgePP(p,i));451if (GetEdgePP(p,i) != en && e.GetStatus() == status)452{453if (e.PNum(1) == p)454{pnew = e.PNum(2);}455else456{pnew = e.PNum(1);}457458ennew = GetEdgePP(p,i);459}460}461if (pnew == pstart) {closed = 1;}462else463{464line.Append(twoint(p,pnew));465p = pnew;466en = ennew;467found = 1;468}469}470}471}472473}474475int Exists(int p1, int p2, const ARRAY<twoint>& line)476{477int i;478for (i = 1; i <= line.Size(); i++)479{480if (line.Get(i).i1 == p1 && line.Get(i).i2 == p2 ||481line.Get(i).i1 == p2 && line.Get(i).i2 == p1) {return 1;}482}483return 0;484}485486void STLEdgeDataList :: BuildClusterWithEdge(int ep1, int ep2, ARRAY<twoint>& line)487{488int status = Get(GetEdgeNum(ep1,ep2)).GetStatus();489490int p(0), en;491int j, i, k;492int oldend;493int newend = 1;494int pnew, ennew(0);495496int changed = 1;497while (changed)498{499changed = 0;500for (j = 1; j <= 2; j++)501{502oldend = newend;503newend = line.Size();504for (k = oldend; k <= line.Size(); k++)505{506if (j == 1) p = line.Get(k).i1;507if (j == 2) p = line.Get(k).i2;508en = GetEdgeNum(line.Get(k).i1, line.Get(k).i2);509510for (i = 1; i <= GetNEPP(p); i++)511{512pnew = 0;513const STLTopEdge & e = Get(GetEdgePP(p,i));514if (GetEdgePP(p,i) != en && e.GetStatus() == status)515{516if (e.PNum(1) == p)517{pnew = e.PNum(2);}518else519{pnew = e.PNum(1);}520521ennew = GetEdgePP(p,i);522}523if (pnew && !Exists(p,pnew,line))524{525changed = 1;526line.Append(twoint(p,pnew));527p = pnew;528en = ennew;529}530}531532}533}534535}536537}538539540541542543544545546547548//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++549//+++++++++++++++++++ STL LINE +++++++++++++++++++++++++++++++550//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++551552STLLine :: STLLine(const STLGeometry * ageometry)553: pts(), lefttrigs(), righttrigs()554{555geometry = ageometry;556split = 0;557};558559int STLLine :: GetNS() const560{561if (pts.Size() <= 1) {return 0;}562return pts.Size()-1;563}564void STLLine :: GetSeg(int nr, int& p1, int& p2) const565{566p1 = pts.Get(nr);567p2 = pts.Get(nr+1);568}569570int STLLine :: GetLeftTrig(int nr) const571{572if (nr > lefttrigs.Size()) {PrintSysError("In STLLine::GetLeftTrig!!!"); return 0;}573return lefttrigs.Get(nr);574};575576int STLLine :: GetRightTrig(int nr) const577{578if (nr > righttrigs.Size()) {PrintSysError("In STLLine::GetRightTrig!!!"); return 0;}579return righttrigs.Get(nr);580};581582double STLLine :: GetSegLen(const ARRAY<Point<3> >& ap, int nr) const583{584return Dist(ap.Get(PNum(nr)),ap.Get(PNum(nr+1)));585}586587double STLLine :: GetLength(const ARRAY<Point<3> >& ap) const588{589double len = 0;590for (int i = 2; i <= pts.Size(); i++)591{592len += (ap.Get(pts.Get(i)) - ap.Get(pts.Get(i-1))).Length();593}594return len;595}596597void STLLine :: GetBoundingBox (const ARRAY<Point<3> > & ap, Box<3> & box) const598{599box.Set (ap.Get (pts[0]));600for (int i = 1; i < pts.Size(); i++)601box.Add (ap.Get(pts[i]));602}603604605606Point<3> STLLine ::607GetPointInDist(const ARRAY<Point<3> >& ap, double dist, int& index) const608{609if (dist <= 0)610{611index = 1;612return ap.Get(StartP());613}614615double len = 0;616int i;617for (i = 1; i < pts.Size(); i++)618{619double seglen = Dist (ap.Get(pts.Get(i)),620ap.Get(pts.Get(i+1)));621622if (len + seglen > dist)623{624index = i;625double relval = (dist - len) / (seglen + 1e-16);626Vec3d v (ap.Get(pts.Get(i)), ap.Get(pts.Get(i+1)));627return ap.Get(pts.Get(i)) + relval * v;628}629630len += seglen;631}632633index = pts.Size() - 1;634return ap.Get(EndP());635}636637638/*639double stlgh;640double GetH(const Point3d& p, double x)641{642return stlgh;//+0.5)*(x+0.5);643}644*/645STLLine* STLLine :: Mesh(const ARRAY<Point<3> >& ap,646ARRAY<Point3d>& mp, double ghi,647class Mesh& mesh) const648{649STLLine* line = new STLLine(geometry);650651//stlgh = ghi; //uebergangsloesung!!!!652653double len = GetLength(ap);654double inthl = 0; //integral of 1/h655double dist = 0;656double h;657int ind;658Point3d p;659660int i, j;661662Box<3> bbox;663GetBoundingBox (ap, bbox);664double diam = bbox.Diam();665666double minh = mesh.LocalHFunction().GetMinH (bbox.PMin(), bbox.PMax());667668double maxseglen = 0;669for (i = 1; i <= GetNS(); i++)670maxseglen = max2 (maxseglen, GetSegLen (ap, i));671672int nph = 10+int(maxseglen / minh); //anzahl der integralauswertungen pro segment673674ARRAY<double> inthi(GetNS()*nph);675ARRAY<double> curvelen(GetNS()*nph);676677678for (i = 1; i <= GetNS(); i++)679{680//double seglen = GetSegLen(ap,i);681for (j = 1; j <= nph; j++)682{683p = GetPointInDist(ap,dist,ind);684//h = GetH(p,dist/len);685h = mesh.GetH(p);686687688dist += GetSegLen(ap,i)/(double)nph;689690inthl += GetSegLen(ap,i)/nph/(h);691inthi.Elem((i-1)*nph+j) = GetSegLen(ap,i)/nph/h;692curvelen.Elem((i-1)*nph+j) = GetSegLen(ap,i)/nph;693}694}695696697int inthlint = int(inthl+1);698699if ( (inthlint < 3) && (StartP() == EndP()))700{701inthlint = 3;702}703if ( (inthlint == 1) && ShouldSplit())704{705inthlint = 2;706}707708double fact = inthl/(double)inthlint;709dist = 0;710j = 1;711712713p = ap.Get(StartP());714int pn = AddPointIfNotExists(mp, p, 1e-10*diam);715716int segn = 1;717line->AddPoint(pn);718line->AddLeftTrig(GetLeftTrig(segn));719line->AddRightTrig(GetRightTrig(segn));720line->AddDist(dist);721722inthl = 0; //restart each meshseg723for (i = 1; i <= inthlint; i++)724{725while (inthl < 1.000000001 && j <= inthi.Size())726// while (inthl-1. < 1e-9) && j <= inthi.Size())727{728inthl += inthi.Get(j)/fact;729dist += curvelen.Get(j);730j++;731}732733//went to far:734j--;735double tofar = (inthl - 1)/inthi.Get(j);736inthl -= tofar*inthi.Get(j);737dist -= tofar*curvelen.Get(j)*fact;738739if (i == inthlint && fabs(dist - len) >= 1E-8)740{741PrintSysError("meshline failed!!!");742}743744if (i != inthlint)745{746p = GetPointInDist(ap,dist,ind);747pn = AddPointIfNotExists(mp, p, 1e-10*diam);748segn = ind;749line->AddPoint(pn);750line->AddLeftTrig(GetLeftTrig(segn));751line->AddRightTrig(GetRightTrig(segn));752line->AddDist(dist);753}754755inthl = tofar*inthi.Get(j);756dist += tofar*curvelen.Get(j)*fact;757j++;758}759760p = ap.Get(EndP());761pn = AddPointIfNotExists(mp, p, 1e-10*diam);762segn = GetNS();763line->AddPoint(pn);764line->AddLeftTrig(GetLeftTrig(segn));765line->AddRightTrig(GetRightTrig(segn));766line->AddDist(dist);767768for (int ii = 1; ii <= line->GetNS(); ii++)769{770int p1, p2;771line->GetSeg(ii,p1,p2);772}773/*774(*testout) << "line, " << ap.Get(StartP()) << "-" << ap.Get(EndP())775<< " len = " << Dist (ap.Get(StartP()), ap.Get(EndP())) << endl;776*/777return line;778}779}780781782