Path: blob/devel/ElmerGUI/netgen/libsrc/stlgeom/stltool.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{121314//add a point into a pointlist, return pointnumber15int AddPointIfNotExists(ARRAY<Point3d>& ap, const Point3d& p, double eps)16{17int i;18for (i = 1; i <= ap.Size(); i++)19{20if (Dist(ap.Get(i),p) <= eps ) {return i;}21}22return ap.Append(p);23}2425//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++2627double GetDistFromLine(const Point<3> & lp1, const Point<3> & lp2,28Point<3> & p)29{30Vec3d vn = lp2 - lp1;31Vec3d v1 = p - lp1;32Vec3d v2 = lp2 - p;3334Point3d pold = p;3536if (v2 * vn <= 0) {p = lp2; return (pold - p).Length();}37if (v1 * vn <= 0) {p = lp1; return (pold - p).Length();}3839double vnl = vn.Length();40if (vnl == 0) {return Dist(lp1,p);}4142vn /= vnl;43p = lp1 + (v1 * vn) * vn;44return (pold - p).Length();45};4647double GetDistFromInfiniteLine(const Point<3>& lp1, const Point<3>& lp2, const Point<3>& p)48{49Vec3d vn(lp1, lp2);50Vec3d v1(lp1, p);5152double vnl = vn.Length();5354if (vnl == 0)55{56return Dist (lp1, p);57}58else59{60return Cross (vn, v1).Length() / vnl;61}62};63646566//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++67//Binary IO-Manipulation68697071void FIOReadInt(istream& ios, int& i)72{73const int ilen = sizeof(int);7475char buf[ilen];76int j;77for (j = 0; j < ilen; j++)78{79ios.get(buf[j]);80}81memcpy(&i, &buf, ilen);82}8384void FIOWriteInt(ostream& ios, const int& i)85{86const int ilen = sizeof(int);8788char buf[ilen];89memcpy(&buf, &i, ilen);9091int j;92for (j = 0; j < ilen; j++)93{94ios << buf[j];95}96}9798void FIOReadDouble(istream& ios, double& i)99{100const int ilen = sizeof(double);101102char buf[ilen];103int j;104for (j = 0; j < ilen; j++)105{106ios.get(buf[j]);107}108memcpy(&i, &buf, ilen);109}110111void FIOWriteDouble(ostream& ios, const double& i)112{113const int ilen = sizeof(double);114115char buf[ilen];116memcpy(&buf, &i, ilen);117118int j;119for (j = 0; j < ilen; j++)120{121ios << buf[j];122}123}124125void FIOReadFloat(istream& ios, float& i)126{127const int ilen = sizeof(float);128129char buf[ilen];130int j;131for (j = 0; j < ilen; j++)132{133ios.get(buf[j]);134}135memcpy(&i, &buf, ilen);136}137138void FIOWriteFloat(ostream& ios, const float& i)139{140const int ilen = sizeof(float);141142char buf[ilen];143memcpy(&buf, &i, ilen);144145int j;146for (j = 0; j < ilen; j++)147{148ios << buf[j];149}150}151152void FIOReadString(istream& ios, char* str, int len)153{154int j;155for (j = 0; j < len; j++)156{157ios.get(str[j]);158}159}160161//read string and add terminating 0162void FIOReadStringE(istream& ios, char* str, int len)163{164int j;165for (j = 0; j < len; j++)166{167ios.get(str[j]);168}169str[len] = 0;170}171172void FIOWriteString(ostream& ios, char* str, int len)173{174int j;175for (j = 0; j < len; j++)176{177ios << str[j];178}179}180181182/*183void FIOReadInt(istream& ios, int& i)184{185const int ilen = sizeof(int);186187char buf[ilen];188int j;189for (j = 0; j < ilen; j++)190{191ios.get(buf[ilen-j-1]);192}193memcpy(&i, &buf, ilen);194}195196void FIOWriteInt(ostream& ios, const int& i)197{198const int ilen = sizeof(int);199200char buf[ilen];201memcpy(&buf, &i, ilen);202203int j;204for (j = 0; j < ilen; j++)205{206ios << buf[ilen-j-1];207}208}209210void FIOReadDouble(istream& ios, double& i)211{212const int ilen = sizeof(double);213214char buf[ilen];215int j;216for (j = 0; j < ilen; j++)217{218ios.get(buf[ilen-j-1]);219}220memcpy(&i, &buf, ilen);221}222223void FIOWriteDouble(ostream& ios, const double& i)224{225const int ilen = sizeof(double);226227char buf[ilen];228memcpy(&buf, &i, ilen);229230int j;231for (j = 0; j < ilen; j++)232{233ios << buf[ilen-j-1];234}235}236237void FIOReadFloat(istream& ios, float& i)238{239const int ilen = sizeof(float);240241char buf[ilen];242int j;243for (j = 0; j < ilen; j++)244{245ios.get(buf[ilen-j-1]);246}247memcpy(&i, &buf, ilen);248}249250void FIOWriteFloat(ostream& ios, const float& i)251{252const int ilen = sizeof(float);253254char buf[ilen];255memcpy(&buf, &i, ilen);256257int j;258for (j = 0; j < ilen; j++)259{260ios << buf[ilen-j-1];261}262}263264void FIOReadString(istream& ios, char* str, int len)265{266int j;267for (j = 0; j < len; j++)268{269ios.get(str[j]);270}271}272273//read string and add terminating 0274void FIOReadStringE(istream& ios, char* str, int len)275{276int j;277for (j = 0; j < len; j++)278{279ios.get(str[j]);280}281str[len] = 0;282}283284void FIOWriteString(ostream& ios, char* str, int len)285{286int j;287for (j = 0; j < len; j++)288{289ios << str[j];290}291}292*/293294//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++295296STLReadTriangle :: STLReadTriangle (const Point<3> * apts,297const Vec<3> & anormal)298{299pts[0] = apts[0];300pts[1] = apts[1];301pts[2] = apts[2];302normal = anormal;303}304305306307STLTriangle :: STLTriangle(const int * apts)308{309pts[0] = apts[0];310pts[1] = apts[1];311pts[2] = apts[2];312313facenum = 0;314}315316int STLTriangle :: IsNeighbourFrom(const STLTriangle& t) const317{318//triangles must have same orientation!!!319int i, j;320for(i = 0; i <= 2; i++)321{322for(j = 0; j <= 2; j++)323{324if (t.pts[(i+1)%3] == pts[j] &&325t.pts[i] == pts[(j+1)%3])326{return 1;}327}328}329return 0;330}331332int STLTriangle :: IsWrongNeighbourFrom(const STLTriangle& t) const333{334//triangles have not same orientation!!!335int i, j;336for(i = 0; i <= 2; i++)337{338for(j = 0; j <= 2; j++)339{340if (t.pts[(i+1)%3] == pts[(j+1)%3] &&341t.pts[i] == pts[j])342{return 1;}343}344}345return 0;346}347348void STLTriangle :: GetNeighbourPoints(const STLTriangle& t, int& p1, int& p2) const349{350int i, j;351for(i = 1; i <= 3; i++)352{353for(j = 1; j <= 3; j++)354{355if (t.PNumMod(i+1) == PNumMod(j) &&356t.PNumMod(i) == PNumMod(j+1))357{p1 = PNumMod(j); p2 = PNumMod(j+1); return;}358}359}360PrintSysError("Get neighbourpoints failed!");361}362363int STLTriangle :: GetNeighbourPointsAndOpposite(const STLTriangle& t, int& p1, int& p2, int& po) const364{365int i, j;366for(i = 1; i <= 3; i++)367{368for(j = 1; j <= 3; j++)369{370if (t.PNumMod(i+1) == PNumMod(j) &&371t.PNumMod(i) == PNumMod(j+1))372{p1 = PNumMod(j); p2 = PNumMod(j+1); po = PNumMod(j+2); return 1;}373}374}375return 0;376}377378Vec<3> STLTriangle :: GeomNormal(const ARRAY<Point<3> >& ap) const379{380const Point<3> & p1 = ap.Get(PNum(1));381const Point<3> & p2 = ap.Get(PNum(2));382const Point<3> & p3 = ap.Get(PNum(3));383384return Cross(p2-p1, p3-p1);385}386387388void STLTriangle :: SetNormal (const Vec<3> & n)389{390double len = n.Length();391if (len > 0)392{393normal = n;394normal.Normalize();395}396else397{398normal = Vec<3> (1, 0, 0);399}400}401402403void STLTriangle :: ChangeOrientation()404{405normal *= -1;406Swap(pts[0],pts[1]);407}408409410411double STLTriangle :: Area(const ARRAY<Point<3> >& ap) const412{413return 0.5 * Cross(ap.Get(PNum(2))-ap.Get(PNum(1)),414ap.Get(PNum(3))-ap.Get(PNum(1))).Length();415}416417double STLTriangle :: MinHeight(const ARRAY<Point<3> >& ap) const418{419double ml = MaxLength(ap);420if (ml != 0) {return 2.*Area(ap)/ml;}421PrintWarning("max Side Length of a triangle = 0!!!");422return 0;423}424425double STLTriangle :: MaxLength(const ARRAY<Point<3> >& ap) const426{427return max3(Dist(ap.Get(PNum(1)),ap.Get(PNum(2))),428Dist(ap.Get(PNum(2)),ap.Get(PNum(3))),429Dist(ap.Get(PNum(3)),ap.Get(PNum(1))));430}431432void STLTriangle :: ProjectInPlain(const ARRAY<Point<3> >& ap,433const Vec<3> & n, Point<3> & pp) const434{435const Point<3> & p1 = ap.Get(PNum(1));436const Point<3> & p2 = ap.Get(PNum(2));437const Point<3> & p3 = ap.Get(PNum(3));438439Vec<3> v1 = p2 - p1;440Vec<3> v2 = p3 - p1;441Vec<3> nt = Cross(v1, v2);442443double c = - (p1(0)*nt(0) + p1(1)*nt(1) + p1(2)*nt(2));444445double prod = n * nt;446447if (fabs(prod) == 0)448{449pp = Point<3>(1.E20,1.E20,1.E20);450return;451}452453double nfact = -(pp(0)*nt(0) + pp(1)*nt(1) + pp(2)*nt(2) + c) / (prod);454pp = pp + (nfact) * n;455456}457458459int STLTriangle :: ProjectInPlain (const ARRAY<Point<3> >& ap,460const Vec<3> & nproj,461Point<3> & pp, Vec<3> & lam) const462{463const Point<3> & p1 = ap.Get(PNum(1));464const Point<3> & p2 = ap.Get(PNum(2));465const Point<3> & p3 = ap.Get(PNum(3));466467Vec<3> v1 = p2-p1;468Vec<3> v2 = p3-p1;469470Mat<3> mat;471for (int i = 0; i < 3; i++)472{473mat(i,0) = v1(i);474mat(i,1) = v2(i);475mat(i,2) = nproj(i);476}477478int err = 0;479mat.Solve (pp-p1, lam);480// int err = SolveLinearSystem (v1, v2, nproj, pp-p1, lam);481482if (!err)483{484// pp = p1 + lam(0) * v1 + lam(1) * v2;485486pp(0) = p1(0) + lam(0) * v1(0) + lam(1) * v2(0);487pp(1) = p1(1) + lam(0) * v1(1) + lam(1) * v2(1);488pp(2) = p1(2) + lam(0) * v1(2) + lam(1) * v2(2);489}490return err;491}492493494495496497void STLTriangle :: ProjectInPlain(const ARRAY<Point<3> >& ap,498Point<3> & pp) const499{500const Point<3> & p1 = ap.Get(PNum(1));501const Point<3> & p2 = ap.Get(PNum(2));502const Point<3> & p3 = ap.Get(PNum(3));503504Vec<3> v1 = p2 - p1;505Vec<3> v2 = p3 - p1;506Vec<3> nt = Cross(v1, v2);507508double c = - (p1(0)*nt(0) + p1(1)*nt(1) + p1(2)*nt(2));509510double prod = nt * nt;511512double nfact = -(pp(0)*nt(0) + pp(1)*nt(1) + pp(2)*nt(2) + c) / (prod);513514pp = pp + (nfact) * nt;515}516517int STLTriangle :: PointInside(const ARRAY<Point<3> > & ap,518const Point<3> & pp) const519{520const Point<3> & p1 = ap.Get(PNum(1));521const Point<3> & p2 = ap.Get(PNum(2));522const Point<3> & p3 = ap.Get(PNum(3));523524Vec<3> v1 = p2 - p1;525Vec<3> v2 = p3 - p1;526Vec<3> v = pp - p1;527double det, l1, l2;528Vec<3> ex, ey, ez;529530531ez = GeomNormal(ap);532ez /= ez.Length();533ex = v1;534ex /= ex.Length();535ey = Cross (ez, ex);536537Vec<2> v1p(v1*ex, v1*ey);538Vec<2> v2p(v2*ex, v2*ey);539Vec<2> vp(v*ex, v*ey);540541det = v2p(1) * v1p(0) - v2p(0) * v1p(1);542543if (fabs(det) == 0) {return 0;}544545l2 = (vp(1) * v1p(0) - vp(0) * v1p(1)) / det;546547if (v1p(0) != 0.)548{549l1 = (vp(0) - l2 * v2p(0)) / v1p(0);550}551else if (v1p(1) != 0.)552{553l1 = (vp(1) - l2 * v2p(1)) / v1p(1);554}555else {return 0;}556557if (l1 >= -1E-10 && l2 >= -1E-10 && l1 + l2 <= 1.+1E-10) {return 1;}558return 0;559}560561double STLTriangle :: GetNearestPoint(const ARRAY<Point<3> >& ap,562Point<3> & p3d) const563{564Point<3> p = p3d;565ProjectInPlain(ap, p);566double dist = (p - p3d).Length();567568if (PointInside(ap, p)) {p3d = p; return dist;}569else570{571Point<3> pf;572double nearest = 1E50;573//int fi = 0;574int j;575576for (j = 1; j <= 3; j++)577{578p = p3d;579dist = GetDistFromLine(ap.Get(PNum(j)), ap.Get(PNumMod(j+1)), p);580if (dist < nearest)581{582nearest = dist;583pf = p;584}585}586p3d = pf;587return nearest;588}589}590591int STLTriangle :: HasEdge(int p1, int p2) const592{593int i;594for (i = 1; i <= 3; i++)595{596if (p1 == PNum(i) && p2 == PNumMod(i+1)) {return 1;}597}598return 0;599}600601ostream& operator<<(ostream& os, const STLTriangle& t)602{603os << "[";604os << t[0] << ",";605os << t[1] << ",";606os << t[2] << "]";607608return os;609};610611612613STLTopEdge :: STLTopEdge ()614{615pts[0] = pts[1] = 0;616trigs[0] = trigs[1] = 0;617cosangle = 1;618status = ED_UNDEFINED;619}620621STLTopEdge :: STLTopEdge (int p1, int p2, int trig1, int trig2)622{623pts[0] = p1;624pts[1] = p2;625trigs[0] = trig1;626trigs[1] = trig2;627cosangle = 1;628status = ED_UNDEFINED;629}630631632633634//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++635//+++++++++++++++++++ STL CHART +++++++++++++++++++++++++++++++636//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++637638STLChart :: STLChart(STLGeometry * ageometry)639{640charttrigs = new ARRAY<int> (0,0);641outertrigs = new ARRAY<int> (0,0);642ilimit = new ARRAY<twoint> (0,0);643olimit = new ARRAY<twoint> (0,0);644645geometry = ageometry;646647if ( (stlparam.usesearchtree == 1))648searchtree = new Box3dTree (geometry->GetBoundingBox().PMin() - Vec3d(1,1,1),649geometry->GetBoundingBox().PMax() + Vec3d(1,1,1));650else651searchtree = NULL;652}653654void STLChart :: AddChartTrig(int i)655{656charttrigs->Append(i);657658const STLTriangle & trig = geometry->GetTriangle(i);659const Point3d & p1 = geometry->GetPoint (trig.PNum(1));660const Point3d & p2 = geometry->GetPoint (trig.PNum(2));661const Point3d & p3 = geometry->GetPoint (trig.PNum(3));662663Point3d pmin(p1), pmax(p1);664pmin.SetToMin (p2);665pmin.SetToMin (p3);666pmax.SetToMax (p2);667pmax.SetToMax (p3);668669if (!geomsearchtreeon && (stlparam.usesearchtree == 1))670{searchtree->Insert (pmin, pmax, i);}671}672673void STLChart :: AddOuterTrig(int i)674{675outertrigs->Append(i);676677const STLTriangle & trig = geometry->GetTriangle(i);678const Point3d & p1 = geometry->GetPoint (trig.PNum(1));679const Point3d & p2 = geometry->GetPoint (trig.PNum(2));680const Point3d & p3 = geometry->GetPoint (trig.PNum(3));681682Point3d pmin(p1), pmax(p1);683pmin.SetToMin (p2);684pmin.SetToMin (p3);685pmax.SetToMax (p2);686pmax.SetToMax (p3);687688if (!geomsearchtreeon && (stlparam.usesearchtree==1))689{searchtree->Insert (pmin, pmax, i);}690}691692int STLChart :: IsInWholeChart(int nr) const693{694int i;695for (i = 1; i <= charttrigs->Size(); i++)696{697if (charttrigs->Get(i) == nr) {return 1;}698}699for (i = 1; i <= outertrigs->Size(); i++)700{701if (outertrigs->Get(i) == nr) {return 1;}702}703return 0;704}705706void STLChart :: GetTrianglesInBox (const Point3d & pmin,707const Point3d & pmax,708ARRAY<int> & trias) const709{710if (geomsearchtreeon) {PrintMessage(5,"geomsearchtreeon is set!!!");}711712if (searchtree)713searchtree -> GetIntersecting (pmin, pmax, trias);714else715{716int i;717Box3d box1(pmin, pmax);718box1.Increase (1e-4);719Box3d box2;720721trias.SetSize(0);722723int nt = GetNT();724for (i = 1; i <= nt; i++)725{726727int trignum = GetTrig(i);728const STLTriangle & trig = geometry->GetTriangle(trignum);729box2.SetPoint (geometry->GetPoint (trig.PNum(1)));730box2.AddPoint (geometry->GetPoint (trig.PNum(2)));731box2.AddPoint (geometry->GetPoint (trig.PNum(3)));732733if (box1.Intersect (box2))734{735trias.Append (trignum);736}737}738}739}740741//trigs may contain the same triangle double742void STLChart :: MoveToOuterChart(const ARRAY<int>& trigs)743{744if (!trigs.Size()) {return;}745int i;746for (i = 1; i <= trigs.Size(); i++)747{748if (charttrigs->Get(trigs.Get(i)) != -1)749{AddOuterTrig(charttrigs->Get(trigs.Get(i)));}750charttrigs->Elem(trigs.Get(i)) = -1;751}752DelChartTrigs(trigs);753}754755//trigs may contain the same triangle double756void STLChart :: DelChartTrigs(const ARRAY<int>& trigs)757{758if (!trigs.Size()) {return;}759760int i;761for (i = 1; i <= trigs.Size(); i++)762{763charttrigs->Elem(trigs.Get(i)) = -1;764}765766int cnt = 0;767for (i = 1; i <= charttrigs->Size(); i++)768{769if (charttrigs->Elem(i) == -1)770{771cnt++;772}773if (cnt != 0 && i < charttrigs->Size())774{775charttrigs->Elem(i-cnt+1) = charttrigs->Get(i+1);776}777}778i = charttrigs->Size() - trigs.Size();779charttrigs->SetSize(i);780781if (!geomsearchtreeon && stlparam.usesearchtree == 1)782{783PrintMessage(7, "Warning: unsecure routine due to first use of searchtrees!!!");784//bould new searchtree!!!785searchtree = new Box3dTree (geometry->GetBoundingBox().PMin() - Vec3d(1,1,1),786geometry->GetBoundingBox().PMax() + Vec3d(1,1,1));787788for (i = 1; i <= charttrigs->Size(); i++)789{790const STLTriangle & trig = geometry->GetTriangle(i);791const Point3d & p1 = geometry->GetPoint (trig.PNum(1));792const Point3d & p2 = geometry->GetPoint (trig.PNum(2));793const Point3d & p3 = geometry->GetPoint (trig.PNum(3));794795Point3d pmin(p1), pmax(p1);796pmin.SetToMin (p2);797pmin.SetToMin (p3);798pmax.SetToMax (p2);799pmax.SetToMax (p3);800801searchtree->Insert (pmin, pmax, i);802}803}804}805806807void STLChart :: SetNormal (const Point<3> & apref, const Vec<3> & anormal)808{809pref = apref;810normal = anormal;811double len = normal.Length();812if (len) normal /= len;813else normal = Vec<3> (1, 0, 0);814815t1 = normal.GetNormal ();816t2 = Cross (normal, t1);817}818819Point<2> STLChart :: Project2d (const Point<3> & p3d) const820{821Vec<3> v = p3d-pref;822return Point<2> (t1 * v, t2 * v);823}824825826827/*828Point3d p1, p2, center;829double rad;830int i1, i2;831public:832*/833STLBoundarySeg ::834STLBoundarySeg (int ai1, int ai2, const ARRAY<Point<3> > & points,835const STLChart * chart)836{837i1 = ai1;838i2 = ai2;839p1 = points.Get(i1);840p2 = points.Get(i2);841center = ::netgen::Center (p1, p2);842rad = Dist (p1, center);843844p2d1 = chart->Project2d (p1);845p2d2 = chart->Project2d (p2);846847boundingbox.Set (p2d1);848boundingbox.Add (p2d2);849}850851void STLBoundarySeg :: Swap ()852{853::netgen::Swap (i1, i2);854::netgen::Swap (p1, p2);855}856857858859STLBoundary :: STLBoundary (STLGeometry * ageometry)860: boundary(), geometry(ageometry)861{862;863}864865866void STLBoundary :: AddOrDelSegment(const STLBoundarySeg & seg)867{868int i;869int found = 0;870for (i = 1; i <= boundary.Size(); i++)871{872if (found) {boundary.Elem(i-1) = boundary.Get(i);}873if (boundary.Get(i) == seg) {found = 1;}874}875if (!found)876{877boundary.Append(seg);878}879else880{881boundary.SetSize(boundary.Size()-1);882}883}884885void STLBoundary ::AddTriangle(const STLTriangle & t)886{887int i;888int found1 = 0;889int found2 = 0;890int found3 = 0;891//int offset = 0;892893894STLBoundarySeg seg1(t[0],t[1], geometry->GetPoints(), chart);895STLBoundarySeg seg2(t[1],t[2], geometry->GetPoints(), chart);896STLBoundarySeg seg3(t[2],t[0], geometry->GetPoints(), chart);897898seg1.SetSmoothEdge (geometry->IsSmoothEdge (seg1.I1(), seg1.I2()));899seg2.SetSmoothEdge (geometry->IsSmoothEdge (seg2.I1(), seg2.I2()));900seg3.SetSmoothEdge (geometry->IsSmoothEdge (seg3.I1(), seg3.I2()));901902/*903for (i = 1; i <= boundary.Size(); i++)904{905if (offset) {boundary.Elem(i-offset) = boundary.Get(i);}906if (boundary.Get(i) == seg1) {found1 = 1; offset++;}907if (boundary.Get(i) == seg2) {found2 = 1; offset++;}908if (boundary.Get(i) == seg3) {found3 = 1; offset++;}909}910911if (offset)912{913boundary.SetSize(boundary.Size()-offset);914}915*/916for (i = boundary.Size(); i >= 1; i--)917{918if (boundary.Get(i) == seg1)919{ boundary.DeleteElement (i); found1 = 1; }920else if (boundary.Get(i) == seg2)921{ boundary.DeleteElement (i); found2 = 1; }922else if (boundary.Get(i) == seg3)923{ boundary.DeleteElement (i); found3 = 1; }924}925926if (!found1) {seg1.Swap(); boundary.Append(seg1);}927if (!found2) {seg2.Swap(); boundary.Append(seg2);}928if (!found3) {seg3.Swap(); boundary.Append(seg3);}929}930931int STLBoundary :: TestSeg(const Point<3>& p1, const Point<3> & p2, const Vec<3> & sn,932double sinchartangle, int divisions, ARRAY<Point<3> >& points, double eps)933{934935if (usechartnormal)936return TestSegChartNV (p1, p2, sn);937938// for statistics939{940int i;941static ARRAY<int> cntclass;942static int cnt = 0;943static int cnti = 0, cnto = 0;944static long int cntsegs = 0;945if (cntclass.Size() == 0)946{947cntclass.SetSize (20);948for (i = 1; i <= cntclass.Size(); i++)949cntclass.Elem(i) = 0;950}951952cntsegs += NOSegments();953int cla = int (log (double(NOSegments()+1)) / log(2.0));954if (cla < 1) cla = 1;955if (cla > cntclass.Size()) cla = cntclass.Size();956cntclass.Elem(cla)++;957cnt++;958if (divisions)959cnti++;960else961cnto++;962if (cnt > 100000)963{964cnt = 0;965/*966(*testout) << "TestSeg-calls for classes:" << endl;967(*testout) << cnti << " inner calls, " << cnto << " outercalls" << endl;968(*testout) << "total testes segments: " << cntsegs << endl;969for (i = 1; i <= cntclass.Size(); i++)970{971(*testout) << int (exp (i * log(2.0))) << " bnd segs: " << cntclass.Get(i) << endl;972}973*/974}975}976977978int i,j,k;979Point<3> seg1p/*, seg2p*/;980Point<3> sp1,sp2;981double lambda1, lambda2, vlen2;982Vec<3> vptpl;983double sinchartangle2 = sqr(sinchartangle);984double scal;985int possible;986987//double maxval = -1;988//double maxvalnew = -1;989990991992double scalp1 = p1(0) * sn(0) + p1(1) * sn(1) + p1(2) * sn(2);993double scalp2 = p2(0) * sn(0) + p2(1) * sn(1) + p2(2) * sn(2);994double minl = min2(scalp1, scalp2);995double maxl = max2(scalp1, scalp2);996Point<3> c = Center (p1, p2);997double dist1 = Dist (c, p1);998999int nseg = NOSegments();1000for (j = 1; j <= nseg; j++)1001{1002const STLBoundarySeg & seg = GetSegment(j);100310041005if (seg.IsSmoothEdge())1006continue;100710081009sp1 = seg.P1();1010sp2 = seg.P2();10111012// Test, ob Spiral Konfikt moeglich10131014possible = 1;10151016double scalsp1 = sp1(0) * sn(0) + sp1(1) * sn(1) + sp1(2) * sn(2);1017double scalsp2 = sp2(0) * sn(0) + sp2(1) * sn(1) + sp2(2) * sn(2);10181019double minsl = min2(scalsp1, scalsp2);1020double maxsl = max2(scalsp1, scalsp2);10211022double maxdiff = max2 (maxsl - minl, maxl - minsl);10231024/*1025Point3d sc = Center (sp1, sp2);1026double mindist = Dist(c, sc) - dist1 - GetSegment(j).Radius();1027if (maxdiff < sinchartangle * mindist)1028{1029possible = 0;1030}1031*/10321033double hscal = maxdiff + sinchartangle * (dist1 + seg.Radius());1034if (hscal * hscal < sinchartangle * Dist2(c, seg.center ))1035possible = 0;103610371038/*1039if (possible)1040{1041double mindist2ex = MinDistLL2 (p1, p2, sp1, sp2);1042if (maxdiff * maxdiff < sinchartangle2 * mindist2ex)1043possible = 0;1044}1045*/10461047if (possible)1048{1049LinearPolynomial2V lp (scalp1 - scalsp1,1050scalp2 - scalp1,1051-(scalsp2 - scalsp1));1052QuadraticPolynomial2V slp;1053slp.Square (lp);105410551056Vec3d v (p1, sp1);1057Vec3d vl (p1, p2);1058Vec3d vsl (sp1, sp2);10591060QuadraticPolynomial2V qp (v.Length2(),1061-2 * (v * vl),10622 * (v * vsl),1063vl.Length2(),1064-2 * (vl * vsl),1065vsl.Length2());10661067slp.Add (-sinchartangle2, qp);10681069double hv = slp.MaxUnitSquare();10701071if (hv > eps) return 0;1072/*1073if (hv > maxvalnew)1074maxvalnew = hv;1075*/1076}107710781079if (possible && 0)10801081for (i = 0; i <= divisions; i++)1082{10831084lambda1 = (double)i/(double)divisions;1085seg1p = Point3d(p1(0)*lambda1+p2(0)*(1.-lambda1),1086p1(1)*lambda1+p2(1)*(1.-lambda1),1087p1(2)*lambda1+p2(2)*(1.-lambda1));1088108910901091for (k = 0; k <= divisions; k++)1092{1093lambda2 = (double)k/(double)divisions;1094vptpl = Vec3d(sp1(0)*lambda2+sp2(0)*(1.-lambda2)-seg1p(0),1095sp1(1)*lambda2+sp2(1)*(1.-lambda2)-seg1p(1),1096sp1(2)*lambda2+sp2(2)*(1.-lambda2)-seg1p(2));10971098vlen2 = vptpl.Length2();10991100// if (vlen2 > 0)1101{1102scal = vptpl * sn;1103double hv = scal*scal - sinchartangle2*vlen2;1104110511061107/*1108if (hv > maxval)1109maxval = hv;1110*/1111if (hv > eps) return 0;1112}1113}1114}1115}11161117return 1;1118// return (maxvalnew < eps);1119}1120112111221123// checks, whether 2d projection intersects1124int STLBoundary :: TestSegChartNV(const Point3d & p1, const Point3d& p2,1125const Vec3d& sn)1126{1127int j;1128int nseg = NOSegments();11291130Point<2> p2d1 = chart->Project2d (p1);1131Point<2> p2d2 = chart->Project2d (p2);11321133Box<2> box2d;1134box2d.Set (p2d1);1135box2d.Add (p2d2);1136/*1137Point2d pmin(p2d1);1138pmin.SetToMin (p2d2);1139Point2d pmax(p2d1);1140pmax.SetToMax (p2d2);1141*/11421143Line2d l1 (p2d1, p2d2);11441145double lam1, lam2;1146double eps = 1e-3;11471148for (j = 1; j <= nseg; j++)1149{1150const STLBoundarySeg & seg = GetSegment(j);11511152if (!box2d.Intersect (seg.BoundingBox()))1153continue;1154/*1155if (seg.P2DMin()(0) > pmax(0)) continue;1156if (seg.P2DMin()(1) > pmax(1)) continue;1157if (seg.P2DMax()(0) < pmin(0)) continue;1158if (seg.P2DMax()(1) < pmin(1)) continue;1159*/11601161if (seg.IsSmoothEdge()) continue;11621163const Point<2> & sp1 = seg.P2D1();1164const Point<2> & sp2 = seg.P2D2();116511661167Line2d l2 (sp1, sp2);11681169int err =1170CrossPointBarycentric (l1, l2, lam1, lam2);1171/*1172if (chartdebug)1173{11741175(*testout) << "lam1 = " << lam1 << ", lam2 = " << lam2 << endl;1176(*testout) << "p2d = " << p2d1 << ", " << p2d2 << endl;1177(*testout) << "sp2d = " << sp1 << ", " << sp2 << endl;1178(*testout) << "i1,2 = " << seg.I1() << ", " << seg.I2() << endl;11791180}1181*/1182if (!err && lam1 > eps && lam1 < 1-eps &&1183lam2 > eps && lam2 < 1-eps)1184return 0;1185}1186return 1;1187}1188118911901191STLDoctorParams :: STLDoctorParams()1192{1193drawmeshededges = 1;1194geom_tol_fact = 1E-6;1195longlinefact = 0;1196showexcluded = 1;11971198selectmode = 0;1199edgeselectmode = 0;1200useexternaledges = 0;1201showfaces = 0;1202showtouchedtrigchart = 1;1203showedgecornerpoints = 1;1204conecheck = 1;1205spiralcheck = 1;1206selecttrig = 0;1207nodeofseltrig = 1;1208selectwithmouse = 1;1209showmarkedtrigs = 1;1210dirtytrigfact = 0.001;1211smoothangle = 90;1212smoothnormalsweight = 0.2;1213vicinity = 0;1214showvicinity = 0;1215}1216121712181219STLDoctorParams stldoctor;12201221void STLDoctorParams :: Print (ostream & ost) const1222{1223ost << "STL doctor parameters:" << endl1224<< "selecttrig = " << selecttrig << endl1225<< "selectlocalpoint = " << nodeofseltrig << endl1226<< "selectwithmouse = " << selectwithmouse << endl1227<< "showmarkedtrigs = " << showmarkedtrigs << endl1228<< "dirtytrigfact = " << dirtytrigfact << endl1229<< "smoothangle = " << smoothangle << endl;1230}123112321233STLParameters :: STLParameters()1234{1235yangle = 30;1236contyangle = 20;1237edgecornerangle = 60;1238chartangle = 15;1239outerchartangle = 70;12401241usesearchtree = 0;1242atlasminh = 1E-4;1243resthsurfcurvfac = 2;1244resthsurfcurvenable = 0;1245resthatlasfac = 2;1246resthatlasenable = 1;1247resthchartdistfac = 1.2;1248resthchartdistenable = 1;1249resthlinelengthfac = 0.5;1250resthlinelengthenable = 1;1251resthcloseedgefac = 1;1252resthcloseedgeenable = 1;1253resthedgeanglefac = 1;1254resthedgeangleenable = 0;1255resthsurfmeshcurvfac = 1;1256resthsurfmeshcurvenable = 0;1257recalc_h_opt = 1;1258}12591260void STLParameters :: Print (ostream & ost) const1261{1262ost << "STL parameters:" << endl1263<< "yellow angle = " << yangle << endl1264<< "continued yellow angle = " << contyangle << endl1265<< "edgecornerangle = " << edgecornerangle << endl1266<< "chartangle = " << chartangle << endl1267<< "outerchartangle = " << outerchartangle << endl1268<< "restrict h due to ..., enable and safety factor: " << endl1269<< "surface curvature: " << resthsurfcurvenable1270<< ", fac = " << resthsurfcurvfac << endl1271<< "atlas surface curvature: " << resthatlasenable1272<< ", fac = " << resthatlasfac << endl1273<< "chart distance: " << resthchartdistenable1274<< ", fac = " << resthchartdistfac << endl1275<< "line length: " << resthlinelengthenable1276<< ", fac = " << resthlinelengthfac << endl1277<< "close edges: " << resthcloseedgeenable1278<< ", fac = " << resthcloseedgefac << endl1279<< "edge angle: " << resthedgeangleenable1280<< ", fac = " << resthedgeanglefac << endl;1281}128212831284STLParameters stlparam;128512861287}128812891290