PageRenderTime 60ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 1ms

/contrib/Netgen/libsrc/stlgeom/stlgeom.cpp

https://bitbucket.org/lge/gmsh
C++ | 3506 lines | 2425 code | 564 blank | 517 comment | 608 complexity | c9efdd8c1eb92e185901b6f00e324a99 MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.1, BSD-3-Clause

Large files files are truncated, but you can click here to view the full file

  1. #include <meshing.hpp>
  2. #include "stlgeom.hpp"
  3. namespace netgen
  4. {
  5. //globalen searchtree fuer gesamte geometry aktivieren
  6. int geomsearchtreeon = 0;
  7. int usechartnormal = 1;
  8. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  9. void STLMeshing (STLGeometry & geom,
  10. Mesh & mesh)
  11. {
  12. geom.Clear();
  13. geom.BuildEdges();
  14. geom.MakeAtlas(mesh);
  15. geom.CalcFaceNums();
  16. geom.AddFaceEdges();
  17. geom.LinkEdges();
  18. mesh.ClearFaceDescriptors();
  19. for (int i = 1; i <= geom.GetNOFaces(); i++)
  20. mesh.AddFaceDescriptor (FaceDescriptor (i, 1, 0, 0));
  21. }
  22. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  23. //+++++++++++++++++++ STL GEOMETRY ++++++++++++++++++++++++++++
  24. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  25. STLGeometry :: STLGeometry()
  26. /*
  27. : edges(), edgesperpoint(),
  28. normals(), externaledges(),
  29. atlas(), chartmark(),
  30. lines(), outerchartspertrig(), vicinity(), markedtrigs(), markedsegs(),
  31. lineendpoints(), spiralpoints(), selectedmultiedge()
  32. */
  33. {
  34. edgedata = new STLEdgeDataList(*this);
  35. externaledges.SetSize(0);
  36. Clear();
  37. meshchart = 0; // initialize all ?? JS
  38. if (geomsearchtreeon)
  39. searchtree = new Box3dTree (GetBoundingBox().PMin() - Vec3d(1,1,1),
  40. GetBoundingBox().PMax() + Vec3d(1,1,1));
  41. else
  42. searchtree = NULL;
  43. status = STL_GOOD;
  44. statustext = "Good Geometry";
  45. smoothedges = NULL;
  46. }
  47. STLGeometry :: ~STLGeometry()
  48. {
  49. delete edgedata;
  50. }
  51. void STLGeometry :: Save (string filename) const
  52. {
  53. const char * cfilename = filename.c_str();
  54. if (strlen(cfilename) < 4)
  55. throw NgException ("illegal filename");
  56. if (strlen(cfilename) > 3 &&
  57. strcmp (&cfilename[strlen(cfilename)-3], "stl") == 0)
  58. {
  59. STLTopology::Save (cfilename);
  60. }
  61. else if (strlen(cfilename) > 4 &&
  62. strcmp (&cfilename[strlen(cfilename)-4], "stlb") == 0)
  63. {
  64. SaveBinary (cfilename,"Binary STL Geometry");
  65. }
  66. else if (strlen(cfilename) > 4 &&
  67. strcmp (&cfilename[strlen(cfilename)-4], "stle") == 0)
  68. {
  69. SaveSTLE (cfilename);
  70. }
  71. }
  72. int STLGeometry :: GenerateMesh (Mesh*& mesh, MeshingParameters & mparam,
  73. int perfstepsstart, int perfstepsend)
  74. {
  75. return STLMeshingDummy (this, mesh, mparam, perfstepsstart, perfstepsend);
  76. }
  77. const Refinement & STLGeometry :: GetRefinement () const
  78. {
  79. return RefinementSTLGeometry (*this);
  80. }
  81. void STLGeometry :: STLInfo(double* data)
  82. {
  83. data[0] = GetNT();
  84. Box<3> b = GetBoundingBox();
  85. data[1] = b.PMin()(0);
  86. data[2] = b.PMax()(0);
  87. data[3] = b.PMin()(1);
  88. data[4] = b.PMax()(1);
  89. data[5] = b.PMin()(2);
  90. data[6] = b.PMax()(2);
  91. int i;
  92. int cons = 1;
  93. for (i = 1; i <= GetNT(); i++)
  94. {
  95. if (NONeighbourTrigs(i) != 3) {cons = 0;}
  96. }
  97. data[7] = cons;
  98. }
  99. void STLGeometry :: MarkNonSmoothNormals()
  100. {
  101. PrintFnStart("Mark Non-Smooth Normals");
  102. int i,j;
  103. markedtrigs.SetSize(GetNT());
  104. for (i = 1; i <= GetNT(); i++)
  105. {
  106. SetMarkedTrig(i, 0);
  107. }
  108. double dirtyangle = stlparam.yangle/180.*M_PI;
  109. int cnt = 0;
  110. int lp1,lp2;
  111. for (i = 1; i <= GetNT(); i++)
  112. {
  113. for (j = 1; j <= NONeighbourTrigs(i); j++)
  114. {
  115. if (GetAngle(i, NeighbourTrig(i,j)) > dirtyangle)
  116. {
  117. GetTriangle(i).GetNeighbourPoints(GetTriangle(NeighbourTrig(i,j)), lp1, lp2);
  118. if (!IsEdge(lp1,lp2))
  119. {
  120. if (!IsMarkedTrig(i)) {SetMarkedTrig(i,1); cnt++;}
  121. }
  122. }
  123. }
  124. }
  125. PrintMessage(5,"marked ",cnt," non-smooth trig-normals");
  126. }
  127. void STLGeometry :: SmoothNormals()
  128. {
  129. multithread.terminate = 0;
  130. // UseExternalEdges();
  131. BuildEdges();
  132. DenseMatrix m(3), hm(3);
  133. Vector rhs(3), sol(3), hv(3), hv2(3);
  134. Vec<3> ri;
  135. double wnb = stldoctor.smoothnormalsweight; // neigbour normal weight
  136. double wgeom = 1-wnb; // geometry normal weight
  137. // minimize
  138. // wgeom sum_T \sum ri \| ri^T (n - n_geom) \|^2
  139. // + wnb sum_SE \| ri x (n - n_nb) \|^2
  140. int i, j, k, l;
  141. int nt = GetNT();
  142. PushStatusF("Smooth Normals");
  143. //int testmode;
  144. for (i = 1; i <= nt; i++)
  145. {
  146. SetThreadPercent( 100.0 * (double)i / (double)nt);
  147. const STLTriangle & trig = GetTriangle (i);
  148. m = 0;
  149. rhs = 0;
  150. // normal of geometry:
  151. Vec<3> ngeom = trig.GeomNormal(points);
  152. ngeom.Normalize();
  153. for (j = 1; j <= 3; j++)
  154. {
  155. int pi1 = trig.PNumMod (j);
  156. int pi2 = trig.PNumMod (j+1);
  157. // edge vector
  158. ri = GetPoint (pi2) - GetPoint (pi1);
  159. for (k = 0; k < 3; k++)
  160. for (l = 0; l < 3; l++)
  161. hm.Elem(k+1, l+1) = wgeom * ri(k) * ri(l);
  162. for (k = 0; k < 3; k++)
  163. hv(k) = ngeom(k);
  164. hm.Mult (hv, hv2);
  165. /*
  166. if (testmode)
  167. (*testout) << "add vec " << hv2 << endl
  168. << " add m " << hm << endl;
  169. */
  170. rhs.Add (1, hv2);
  171. m += hm;
  172. int nbt = 0;
  173. int fp1,fp2;
  174. for (k = 1; k <= NONeighbourTrigs(i); k++)
  175. {
  176. trig.GetNeighbourPoints(GetTriangle(NeighbourTrig(i, k)),fp1,fp2);
  177. if (fp1 == pi1 && fp2 == pi2)
  178. {
  179. nbt = NeighbourTrig(i, k);
  180. }
  181. }
  182. if (!nbt)
  183. {
  184. cerr << "ERROR: stlgeom::Smoothnormals, nbt = 0" << endl;
  185. }
  186. // smoothed normal
  187. Vec<3> nnb = GetTriangle(nbt).Normal(); // neighbour normal
  188. nnb.Normalize();
  189. if (!IsEdge(pi1,pi2))
  190. {
  191. double lr2 = ri * ri;
  192. for (k = 0; k < 3; k++)
  193. {
  194. for (l = 0; l < k; l++)
  195. {
  196. hm.Elem(k+1, l+1) = -wnb * ri(k) * ri(l);
  197. hm.Elem(l+1, k+1) = -wnb * ri(k) * ri(l);
  198. }
  199. hm.Elem(k+1, k+1) = wnb * (lr2 - ri(k) * ri(k));
  200. }
  201. for (k = 0; k < 3; k++)
  202. hv(k) = nnb(k);
  203. hm.Mult (hv, hv2);
  204. /*
  205. if (testmode)
  206. (*testout) << "add nb vec " << hv2 << endl
  207. << " add nb m " << hm << endl;
  208. */
  209. rhs.Add (1, hv2);
  210. m += hm;
  211. }
  212. }
  213. m.Solve (rhs, sol);
  214. Vec3d newn(sol(0), sol(1), sol(2));
  215. newn /= (newn.Length() + 1e-24);
  216. GetTriangle(i).SetNormal(newn);
  217. // setnormal (sol);
  218. }
  219. /*
  220. for (i = 1; i <= nt; i++)
  221. SetMarkedTrig(i, 0);
  222. int crloop;
  223. for (crloop = 1; crloop <= 3; crloop++)
  224. {
  225. // find critical:
  226. Array<INDEX_2> critpairs;
  227. for (i = 1; i <= nt; i++)
  228. {
  229. const STLTriangle & trig = GetTriangle (i);
  230. Vec3d ngeom = GetTriangleNormal (i); // trig.Normal(points);
  231. ngeom /= (ngeom.Length() + 1e-24);
  232. for (j = 1; j <= 3; j++)
  233. {
  234. int pi1 = trig.PNumMod (j);
  235. int pi2 = trig.PNumMod (j+1);
  236. int nbt = 0;
  237. int fp1,fp2;
  238. for (k = 1; k <= NONeighbourTrigs(i); k++)
  239. {
  240. trig.GetNeighbourPoints(GetTriangle(NeighbourTrig(i, k)),fp1,fp2);
  241. if (fp1 == pi1 && fp2 == pi2)
  242. {
  243. nbt = NeighbourTrig(i, k);
  244. }
  245. }
  246. if (!nbt)
  247. {
  248. cerr << "ERROR: stlgeom::Smoothnormals, nbt = 0" << endl;
  249. }
  250. Vec3d nnb = GetTriangleNormal(nbt); // neighbour normal
  251. nnb /= (nnb.Length() + 1e-24);
  252. if (!IsEdge(pi1,pi2))
  253. {
  254. if (Angle (nnb, ngeom) > 150 * M_PI/180)
  255. {
  256. SetMarkedTrig(i, 1);
  257. SetMarkedTrig(nbt, 1);
  258. critpairs.Append (INDEX_2 (i, nbt));
  259. }
  260. }
  261. }
  262. }
  263. if (!critpairs.Size())
  264. {
  265. break;
  266. }
  267. if (critpairs.Size())
  268. {
  269. Array<int> friends;
  270. double area1 = 0, area2 = 0;
  271. for (i = 1; i <= critpairs.Size(); i++)
  272. {
  273. int tnr1 = critpairs.Get(i).I1();
  274. int tnr2 = critpairs.Get(i).I2();
  275. (*testout) << "t1 = " << tnr1 << ", t2 = " << tnr2
  276. << " angle = " << Angle (GetTriangleNormal (tnr1),
  277. GetTriangleNormal (tnr2))
  278. << endl;
  279. // who has more friends ?
  280. int side;
  281. area1 = 0;
  282. area2 = 0;
  283. for (side = 1; side <= 2; side++)
  284. {
  285. friends.SetSize (0);
  286. friends.Append ( (side == 1) ? tnr1 : tnr2);
  287. for (j = 1; j <= 3; j++)
  288. {
  289. int fsize = friends.Size();
  290. for (k = 1; k <= fsize; k++)
  291. {
  292. int testtnr = friends.Get(k);
  293. Vec3d ntt = GetTriangleNormal(testtnr);
  294. ntt /= (ntt.Length() + 1e-24);
  295. for (l = 1; l <= NONeighbourTrigs(testtnr); l++)
  296. {
  297. int testnbnr = NeighbourTrig(testtnr, l);
  298. Vec3d nbt = GetTriangleNormal(testnbnr);
  299. nbt /= (nbt.Length() + 1e-24);
  300. if (Angle (nbt, ntt) < 15 * M_PI/180)
  301. {
  302. int ii;
  303. int found = 0;
  304. for (ii = 1; ii <= friends.Size(); ii++)
  305. {
  306. if (friends.Get(ii) == testnbnr)
  307. {
  308. found = 1;
  309. break;
  310. }
  311. }
  312. if (!found)
  313. friends.Append (testnbnr);
  314. }
  315. }
  316. }
  317. }
  318. // compute area:
  319. for (k = 1; k <= friends.Size(); k++)
  320. {
  321. double area =
  322. GetTriangle (friends.Get(k)).Area(points);
  323. if (side == 1)
  324. area1 += area;
  325. else
  326. area2 += area;
  327. }
  328. }
  329. (*testout) << "area1 = " << area1 << " area2 = " << area2 << endl;
  330. if (area1 < 0.1 * area2)
  331. {
  332. Vec3d n = GetTriangleNormal (tnr1);
  333. n *= -1;
  334. SetTriangleNormal(tnr1, n);
  335. }
  336. if (area2 < 0.1 * area1)
  337. {
  338. Vec3d n = GetTriangleNormal (tnr2);
  339. n *= -1;
  340. SetTriangleNormal(tnr2, n);
  341. }
  342. }
  343. }
  344. }
  345. */
  346. calcedgedataanglesnew = 1;
  347. PopStatus();
  348. }
  349. int STLGeometry :: AddEdge(int ap1, int ap2)
  350. {
  351. STLEdge e(ap1,ap2);
  352. e.SetLeftTrig(GetLeftTrig(ap1,ap2));
  353. e.SetRightTrig(GetRightTrig(ap1,ap2));
  354. return edges.Append(e);
  355. }
  356. void STLGeometry :: STLDoctorConfirmEdge()
  357. {
  358. StoreEdgeData();
  359. if (GetSelectTrig() >= 1 && GetSelectTrig() <= GetNT() && GetNodeOfSelTrig())
  360. {
  361. if (stldoctor.selectmode == 1)
  362. {
  363. int ap1 = GetTriangle(GetSelectTrig()).PNum(GetNodeOfSelTrig());
  364. int ap2 = GetTriangle(GetSelectTrig()).PNumMod(GetNodeOfSelTrig()+1);
  365. edgedata->Elem(edgedata->GetEdgeNum(ap1,ap2)).SetStatus (ED_CONFIRMED);
  366. }
  367. else if (stldoctor.selectmode == 3 || stldoctor.selectmode == 4)
  368. {
  369. int i;
  370. for (i = 1; i <= selectedmultiedge.Size(); i++)
  371. {
  372. int ap1 = selectedmultiedge.Get(i).i1;
  373. int ap2 = selectedmultiedge.Get(i).i2;
  374. edgedata->Elem(edgedata->GetEdgeNum(ap1,ap2)).SetStatus (ED_CONFIRMED);
  375. }
  376. }
  377. }
  378. }
  379. void STLGeometry :: STLDoctorCandidateEdge()
  380. {
  381. StoreEdgeData();
  382. if (GetSelectTrig() >= 1 && GetSelectTrig() <= GetNT() && GetNodeOfSelTrig())
  383. {
  384. if (stldoctor.selectmode == 1)
  385. {
  386. int ap1 = GetTriangle(GetSelectTrig()).PNum(GetNodeOfSelTrig());
  387. int ap2 = GetTriangle(GetSelectTrig()).PNumMod(GetNodeOfSelTrig()+1);
  388. edgedata->Elem(edgedata->GetEdgeNum(ap1,ap2)).SetStatus (ED_CANDIDATE);
  389. }
  390. else if (stldoctor.selectmode == 3 || stldoctor.selectmode == 4)
  391. {
  392. int i;
  393. for (i = 1; i <= selectedmultiedge.Size(); i++)
  394. {
  395. int ap1 = selectedmultiedge.Get(i).i1;
  396. int ap2 = selectedmultiedge.Get(i).i2;
  397. edgedata->Elem(edgedata->GetEdgeNum(ap1,ap2)).SetStatus (ED_CANDIDATE);
  398. }
  399. }
  400. }
  401. }
  402. void STLGeometry :: STLDoctorExcludeEdge()
  403. {
  404. StoreEdgeData();
  405. if (GetSelectTrig() >= 1 && GetSelectTrig() <= GetNT() && GetNodeOfSelTrig())
  406. {
  407. if (stldoctor.selectmode == 1)
  408. {
  409. int ap1 = GetTriangle(GetSelectTrig()).PNum(GetNodeOfSelTrig());
  410. int ap2 = GetTriangle(GetSelectTrig()).PNumMod(GetNodeOfSelTrig()+1);
  411. edgedata->Elem(edgedata->GetEdgeNum(ap1,ap2)).SetStatus(ED_EXCLUDED);
  412. }
  413. else if (stldoctor.selectmode == 3 || stldoctor.selectmode == 4)
  414. {
  415. int i;
  416. for (i = 1; i <= selectedmultiedge.Size(); i++)
  417. {
  418. int ap1 = selectedmultiedge.Get(i).i1;
  419. int ap2 = selectedmultiedge.Get(i).i2;
  420. edgedata->Elem(edgedata->GetEdgeNum(ap1,ap2)).SetStatus(ED_EXCLUDED);
  421. }
  422. }
  423. }
  424. }
  425. void STLGeometry :: STLDoctorUndefinedEdge()
  426. {
  427. StoreEdgeData();
  428. if (GetSelectTrig() >= 1 && GetSelectTrig() <= GetNT() && GetNodeOfSelTrig())
  429. {
  430. if (stldoctor.selectmode == 1)
  431. {
  432. int ap1 = GetTriangle(GetSelectTrig()).PNum(GetNodeOfSelTrig());
  433. int ap2 = GetTriangle(GetSelectTrig()).PNumMod(GetNodeOfSelTrig()+1);
  434. edgedata->Elem(edgedata->GetEdgeNum(ap1,ap2)).SetStatus(ED_UNDEFINED);
  435. }
  436. else if (stldoctor.selectmode == 3 || stldoctor.selectmode == 4)
  437. {
  438. int i;
  439. for (i = 1; i <= selectedmultiedge.Size(); i++)
  440. {
  441. int ap1 = selectedmultiedge.Get(i).i1;
  442. int ap2 = selectedmultiedge.Get(i).i2;
  443. edgedata->Elem(edgedata->GetEdgeNum(ap1,ap2)).SetStatus(ED_UNDEFINED);
  444. }
  445. }
  446. }
  447. }
  448. void STLGeometry :: STLDoctorSetAllUndefinedEdges()
  449. {
  450. edgedata->ResetAll();
  451. }
  452. void STLGeometry :: STLDoctorEraseCandidateEdges()
  453. {
  454. StoreEdgeData();
  455. edgedata->ChangeStatus(ED_CANDIDATE, ED_UNDEFINED);
  456. }
  457. void STLGeometry :: STLDoctorConfirmCandidateEdges()
  458. {
  459. StoreEdgeData();
  460. edgedata->ChangeStatus(ED_CANDIDATE, ED_CONFIRMED);
  461. }
  462. void STLGeometry :: STLDoctorConfirmedToCandidateEdges()
  463. {
  464. StoreEdgeData();
  465. edgedata->ChangeStatus(ED_CONFIRMED, ED_CANDIDATE);
  466. }
  467. void STLGeometry :: STLDoctorDirtyEdgesToCandidates()
  468. {
  469. StoreEdgeData();
  470. }
  471. void STLGeometry :: STLDoctorLongLinesToCandidates()
  472. {
  473. StoreEdgeData();
  474. }
  475. twoint STLGeometry :: GetNearestSelectedDefinedEdge()
  476. {
  477. Point<3> pestimate = Center(GetTriangle(GetSelectTrig()).center,
  478. GetPoint(GetTriangle(GetSelectTrig()).PNum(GetNodeOfSelTrig())));
  479. //Point3d pestimate = GetTriangle(GetSelectTrig()).center;
  480. int i, j, en;
  481. Array<int> vic;
  482. GetVicinity(GetSelectTrig(),4,vic);
  483. twoint fedg;
  484. fedg.i1 = 0;
  485. fedg.i2 = 0;
  486. double mindist = 1E50;
  487. double dist;
  488. Point<3> p;
  489. for (i = 1; i <= vic.Size(); i++)
  490. {
  491. const STLTriangle& t = GetTriangle(vic.Get(i));
  492. for (j = 1; j <= 3; j++)
  493. {
  494. en = edgedata->GetEdgeNum(t.PNum(j),t.PNumMod(j+1));
  495. if (edgedata->Get(en).GetStatus() != ED_UNDEFINED)
  496. {
  497. p = pestimate;
  498. dist = GetDistFromLine(GetPoint(t.PNum(j)),GetPoint(t.PNumMod(j+1)),p);
  499. if (dist < mindist)
  500. {
  501. mindist = dist;
  502. fedg.i1 = t.PNum(j);
  503. fedg.i2 = t.PNumMod(j+1);
  504. }
  505. }
  506. }
  507. }
  508. return fedg;
  509. }
  510. void STLGeometry :: BuildSelectedMultiEdge(twoint ep)
  511. {
  512. if (edgedata->Size() == 0 ||
  513. !GetEPPSize())
  514. {
  515. return;
  516. }
  517. selectedmultiedge.SetSize(0);
  518. int tenum = GetTopEdgeNum (ep.i1, ep.i2);
  519. if (edgedata->Get(tenum).GetStatus() == ED_UNDEFINED)
  520. {
  521. twoint epnew = GetNearestSelectedDefinedEdge();
  522. if (epnew.i1)
  523. {
  524. ep = epnew;
  525. tenum = GetTopEdgeNum (ep.i1, ep.i2);
  526. }
  527. }
  528. selectedmultiedge.Append(twoint(ep));
  529. if (edgedata->Get(tenum).GetStatus() == ED_UNDEFINED)
  530. {
  531. return;
  532. }
  533. edgedata->BuildLineWithEdge(ep.i1,ep.i2,selectedmultiedge);
  534. }
  535. void STLGeometry :: BuildSelectedEdge(twoint ep)
  536. {
  537. if (edgedata->Size() == 0 ||
  538. !GetEPPSize())
  539. {
  540. return;
  541. }
  542. selectedmultiedge.SetSize(0);
  543. selectedmultiedge.Append(twoint(ep));
  544. }
  545. void STLGeometry :: BuildSelectedCluster(twoint ep)
  546. {
  547. if (edgedata->Size() == 0 ||
  548. !GetEPPSize())
  549. {
  550. return;
  551. }
  552. selectedmultiedge.SetSize(0);
  553. int tenum = GetTopEdgeNum (ep.i1, ep.i2);
  554. if (edgedata->Get(tenum).GetStatus() == ED_UNDEFINED)
  555. {
  556. twoint epnew = GetNearestSelectedDefinedEdge();
  557. if (epnew.i1)
  558. {
  559. ep = epnew;
  560. tenum = GetTopEdgeNum (ep.i1, ep.i2);
  561. }
  562. }
  563. selectedmultiedge.Append(twoint(ep));
  564. if (edgedata->Get(tenum).GetStatus() == ED_UNDEFINED)
  565. {
  566. return;
  567. }
  568. edgedata->BuildClusterWithEdge(ep.i1,ep.i2,selectedmultiedge);
  569. }
  570. void STLGeometry :: ImportEdges()
  571. {
  572. StoreEdgeData();
  573. PrintMessage(5, "import edges from file 'edges.ng'");
  574. ifstream fin("edges.ng");
  575. int ne;
  576. fin >> ne;
  577. Array<Point<3> > eps;
  578. int i;
  579. Point<3> p;
  580. for (i = 1; i <= 2*ne; i++)
  581. {
  582. fin >> p(0);
  583. fin >> p(1);
  584. fin >> p(2);
  585. eps.Append(p);
  586. }
  587. AddEdges(eps);
  588. }
  589. void STLGeometry :: AddEdges(const Array<Point<3> >& eps)
  590. {
  591. int i;
  592. int ne = eps.Size()/2;
  593. Array<int> epsi;
  594. Box<3> bb = GetBoundingBox();
  595. bb.Increase(1);
  596. Point3dTree ptree (bb.PMin(),
  597. bb.PMax());
  598. Array<int> pintersect;
  599. double gtol = GetBoundingBox().Diam()/1.E10;
  600. Point<3> p;
  601. for (i = 1; i <= GetNP(); i++)
  602. {
  603. p = GetPoint(i);
  604. ptree.Insert (p, i);
  605. }
  606. int error = 0;
  607. for (i = 1; i <= 2*ne; i++)
  608. {
  609. p = eps.Get(i);
  610. Point3d pmin = p - Vec3d (gtol, gtol, gtol);
  611. Point3d pmax = p + Vec3d (gtol, gtol, gtol);
  612. ptree.GetIntersecting (pmin, pmax, pintersect);
  613. if (pintersect.Size() > 1)
  614. {
  615. PrintError("Found too much points in epsilon-dist");
  616. error = 1;
  617. }
  618. else if (pintersect.Size() == 0)
  619. {
  620. error = 1;
  621. PrintError("edgepoint does not exist!");
  622. PrintMessage(5,"p=",Point3d(eps.Get(i)));
  623. }
  624. else
  625. {
  626. epsi.Append(pintersect.Get(1));
  627. }
  628. }
  629. if (error) return;
  630. int en;
  631. for (i = 1; i <= ne; i++)
  632. {
  633. if (epsi.Get(2*i-1) == epsi.Get(2*i)) {PrintError("Edge with zero length!");}
  634. else
  635. {
  636. en = edgedata->GetEdgeNum(epsi.Get(2*i-1),epsi.Get(2*i));
  637. edgedata->Elem(en).SetStatus (ED_CONFIRMED);
  638. }
  639. }
  640. }
  641. void STLGeometry :: ImportExternalEdges(const char * filename)
  642. {
  643. //AVL edges!!!!!!
  644. ifstream inf (filename);
  645. char ch;
  646. //int cnt = 0;
  647. int records, units, i, j;
  648. PrintFnStart("Import edges from ",filename);
  649. const int flen=30;
  650. char filter[flen+1];
  651. filter[flen] = 0;
  652. char buf[20];
  653. Array<Point3d> importpoints;
  654. Array<int> importlines;
  655. Array<int> importpnums;
  656. while (inf.good())
  657. {
  658. inf.get(ch);
  659. // (*testout) << cnt << ": " << ch << endl;
  660. for (i = 0; i < flen; i++)
  661. filter[i] = filter[i+1];
  662. filter[flen-1] = ch;
  663. // (*testout) << filter << endl;
  664. if (strcmp (filter+flen-7, "RECORDS") == 0)
  665. {
  666. inf.get(ch); // '='
  667. inf >> records;
  668. }
  669. if (strcmp (filter+flen-5, "UNITS") == 0)
  670. {
  671. inf.get(ch); // '='
  672. inf >> units;
  673. }
  674. if (strcmp (filter+flen-17, "EDGE NODE NUMBERS") == 0)
  675. {
  676. int nodenr;
  677. importlines.SetSize (units);
  678. for (i = 1; i <= units; i++)
  679. {
  680. inf >> nodenr;
  681. importlines.Elem(i) = nodenr;
  682. // (*testout) << nodenr << endl;
  683. }
  684. }
  685. if (strcmp (filter+flen-23, "EDGE POINT COORD IN DIR") == 0)
  686. {
  687. int coord;
  688. inf >> coord;
  689. importpoints.SetSize (units);
  690. inf >> ch;
  691. inf.putback (ch);
  692. for (i = 1; i <= units; i++)
  693. {
  694. for (j = 0; j < 12; j++)
  695. inf.get (buf[j]);
  696. buf[12] = 0;
  697. importpoints.Elem(i).X(coord) = 1000 * atof (buf);
  698. }
  699. }
  700. }
  701. /*
  702. (*testout) << "lines: " << endl;
  703. for (i = 1; i <= importlines.Size(); i++)
  704. (*testout) << importlines.Get(i) << endl;
  705. (*testout) << "points: " << endl;
  706. for (i = 1; i <= importpoints.Size(); i++)
  707. (*testout) << importpoints.Get(i) << endl;
  708. */
  709. importpnums.SetSize (importpoints.Size());
  710. Box3d bb (GetBoundingBox().PMin() + Vec3d (-1,-1,-1),
  711. GetBoundingBox().PMax() + Vec3d (1, 1, 1));
  712. Point3dTree ptree (bb.PMin(),
  713. bb.PMax());
  714. PrintMessage(7,"stl - bb: ",bb.PMin(), " - ", bb.PMax());
  715. Box3d ebb;
  716. ebb.SetPoint (importpoints.Get(1));
  717. for (i = 1; i <= importpoints.Size(); i++)
  718. ebb.AddPoint (importpoints.Get(i));
  719. PrintMessage(7,"edgep - bb: ", ebb.PMin(), " - ", ebb.PMax());
  720. Array<int> pintersect;
  721. double gtol = GetBoundingBox().Diam()/1.E6;
  722. for (i = 1; i <= GetNP(); i++)
  723. {
  724. Point3d p = GetPoint(i);
  725. // (*testout) << "stlpt: " << p << endl;
  726. ptree.Insert (p, i);
  727. }
  728. for (i = 1; i <= importpoints.Size(); i++)
  729. {
  730. Point3d p = importpoints.Get(i);
  731. Point3d pmin = p - Vec3d (gtol, gtol, gtol);
  732. Point3d pmax = p + Vec3d (gtol, gtol, gtol);
  733. ptree.GetIntersecting (pmin, pmax, pintersect);
  734. if (pintersect.Size() > 1)
  735. {
  736. importpnums.Elem(i) = 0;
  737. PrintError("Found too many points in epsilon-dist");
  738. }
  739. else if (pintersect.Size() == 0)
  740. {
  741. importpnums.Elem(i) = 0;
  742. PrintError("Edgepoint does not exist!");
  743. }
  744. else
  745. {
  746. importpnums.Elem(i) = pintersect.Get(1);
  747. }
  748. }
  749. // if (!error)
  750. {
  751. PrintMessage(7,"found all edge points in stl file");
  752. StoreEdgeData();
  753. int oldp = 0;
  754. for (i = 1; i <= importlines.Size(); i++)
  755. {
  756. int newp = importlines.Get(i);
  757. if (!importpnums.Get(abs(newp)))
  758. newp = 0;
  759. if (oldp && newp)
  760. {
  761. int en = edgedata->GetEdgeNum(importpnums.Get(oldp),
  762. importpnums.Get(abs(newp)));
  763. edgedata->Elem(en).SetStatus (ED_CONFIRMED);
  764. }
  765. if (newp < 0)
  766. oldp = 0;
  767. else
  768. oldp = newp;
  769. }
  770. }
  771. }
  772. void STLGeometry :: ExportEdges()
  773. {
  774. PrintFnStart("Save edges to file 'edges.ng'");
  775. ofstream fout("edges.ng");
  776. fout.precision(16);
  777. int n = edgedata->GetNConfEdges();
  778. fout << n << endl;
  779. int i;
  780. for (i = 1; i <= edgedata->Size(); i++)
  781. {
  782. if (edgedata->Get(i).GetStatus() == ED_CONFIRMED)
  783. {
  784. const STLTopEdge & e = edgedata->Get(i);
  785. fout << GetPoint(e.PNum(1))(0) << " " << GetPoint(e.PNum(1))(1) << " " << GetPoint(e.PNum(1))(2) << endl;
  786. fout << GetPoint(e.PNum(2))(0) << " " << GetPoint(e.PNum(2))(1) << " " << GetPoint(e.PNum(2))(2) << endl;
  787. }
  788. }
  789. }
  790. void STLGeometry :: LoadEdgeData(const char* file)
  791. {
  792. StoreEdgeData();
  793. PrintFnStart("Load edges from file '", file, "'");
  794. ifstream fin(file);
  795. edgedata->Read(fin);
  796. // calcedgedataanglesnew = 1;
  797. }
  798. void STLGeometry :: SaveEdgeData(const char* file)
  799. {
  800. PrintFnStart("save edges to file '", file, "'");
  801. ofstream fout(file);
  802. edgedata->Write(fout);
  803. }
  804. /*
  805. void STLGeometry :: SaveExternalEdges()
  806. {
  807. ofstream fout("externaledgesp3.ng");
  808. fout.precision(16);
  809. int n = NOExternalEdges();
  810. fout << n << endl;
  811. int i;
  812. for (i = 1; i <= n; i++)
  813. {
  814. twoint e = GetExternalEdge(i);
  815. fout << GetPoint(e.i1)(0) << " " << GetPoint(e.i1)(1) << " " << GetPoint(e.i1)(2) << endl;
  816. fout << GetPoint(e.i2)(0) << " " << GetPoint(e.i2)(1) << " " << GetPoint(e.i2)(2) << endl;
  817. }
  818. }
  819. */
  820. void STLGeometry :: StoreExternalEdges()
  821. {
  822. storedexternaledges.SetSize(0);
  823. undoexternaledges = 1;
  824. int i;
  825. for (i = 1; i <= externaledges.Size(); i++)
  826. {
  827. storedexternaledges.Append(externaledges.Get(i));
  828. }
  829. }
  830. void STLGeometry :: UndoExternalEdges()
  831. {
  832. if (!undoexternaledges)
  833. {
  834. PrintMessage(1, "undo not further possible!");
  835. return;
  836. }
  837. RestoreExternalEdges();
  838. undoexternaledges = 0;
  839. }
  840. void STLGeometry :: RestoreExternalEdges()
  841. {
  842. externaledges.SetSize(0);
  843. int i;
  844. for (i = 1; i <= storedexternaledges.Size(); i++)
  845. {
  846. externaledges.Append(storedexternaledges.Get(i));
  847. }
  848. }
  849. void STLGeometry :: AddExternalEdgeAtSelected()
  850. {
  851. StoreExternalEdges();
  852. if (GetSelectTrig() >= 1 && GetSelectTrig() <= GetNT())
  853. {
  854. int ap1 = GetTriangle(GetSelectTrig()).PNum(GetNodeOfSelTrig());
  855. int ap2 = GetTriangle(GetSelectTrig()).PNumMod(GetNodeOfSelTrig()+1);
  856. if (!IsExternalEdge(ap1,ap2)) {AddExternalEdge(ap1,ap2);}
  857. }
  858. }
  859. void STLGeometry :: AddClosedLinesToExternalEdges()
  860. {
  861. StoreExternalEdges();
  862. int i, j;
  863. for (i = 1; i <= GetNLines(); i++)
  864. {
  865. STLLine* l = GetLine(i);
  866. if (l->StartP() == l->EndP())
  867. {
  868. for (j = 1; j < l->NP(); j++)
  869. {
  870. int ap1 = l->PNum(j);
  871. int ap2 = l->PNum(j+1);
  872. if (!IsExternalEdge(ap1,ap2)) {AddExternalEdge(ap1,ap2);}
  873. }
  874. }
  875. }
  876. }
  877. void STLGeometry :: AddLongLinesToExternalEdges()
  878. {
  879. StoreExternalEdges();
  880. double diamfact = stldoctor.dirtytrigfact;
  881. double diam = GetBoundingBox().Diam();
  882. int i, j;
  883. for (i = 1; i <= GetNLines(); i++)
  884. {
  885. STLLine* l = GetLine(i);
  886. if (l->GetLength(points) >= diamfact*diam)
  887. {
  888. for (j = 1; j < l->NP(); j++)
  889. {
  890. int ap1 = l->PNum(j);
  891. int ap2 = l->PNum(j+1);
  892. if (!IsExternalEdge(ap1,ap2)) {AddExternalEdge(ap1,ap2);}
  893. }
  894. }
  895. }
  896. }
  897. void STLGeometry :: AddAllNotSingleLinesToExternalEdges()
  898. {
  899. StoreExternalEdges();
  900. int i, j;
  901. for (i = 1; i <= GetNLines(); i++)
  902. {
  903. STLLine* l = GetLine(i);
  904. if (GetNEPP(l->StartP()) > 1 || GetNEPP(l->EndP()) > 1)
  905. {
  906. for (j = 1; j < l->NP(); j++)
  907. {
  908. int ap1 = l->PNum(j);
  909. int ap2 = l->PNum(j+1);
  910. if (!IsExternalEdge(ap1,ap2)) {AddExternalEdge(ap1,ap2);}
  911. }
  912. }
  913. }
  914. }
  915. void STLGeometry :: DeleteDirtyExternalEdges()
  916. {
  917. //delete single triangle edges and single edge-lines in clusters"
  918. StoreExternalEdges();
  919. int i, j;
  920. for (i = 1; i <= GetNLines(); i++)
  921. {
  922. STLLine* l = GetLine(i);
  923. if (l->NP() <= 3 || (l->StartP() == l->EndP() && l->NP() == 4))
  924. {
  925. for (j = 1; j < l->NP(); j++)
  926. {
  927. int ap1 = l->PNum(j);
  928. int ap2 = l->PNum(j+1);
  929. if (IsExternalEdge(ap1,ap2)) {DeleteExternalEdge(ap1,ap2);}
  930. }
  931. }
  932. }
  933. }
  934. void STLGeometry :: AddExternalEdgesFromGeomLine()
  935. {
  936. StoreExternalEdges();
  937. if (GetSelectTrig() >= 1 && GetSelectTrig() <= GetNT())
  938. {
  939. int ap1 = GetTriangle(GetSelectTrig()).PNum(GetNodeOfSelTrig());
  940. int ap2 = GetTriangle(GetSelectTrig()).PNumMod(GetNodeOfSelTrig()+1);
  941. if (IsEdge(ap1,ap2))
  942. {
  943. int edgenum = IsEdgeNum(ap1,ap2);
  944. if (!IsExternalEdge(ap1,ap2)) {AddExternalEdge(ap1,ap2);}
  945. int noend = 1;
  946. int startp = ap1;
  947. int laste = edgenum;
  948. int np1, np2;
  949. while (noend)
  950. {
  951. if (GetNEPP(startp) == 2)
  952. {
  953. if (GetEdgePP(startp,1) != laste) {laste = GetEdgePP(startp,1);}
  954. else {laste = GetEdgePP(startp,2);}
  955. np1 = GetEdge(laste).PNum(1);
  956. np2 = GetEdge(laste).PNum(2);
  957. if (!IsExternalEdge(np1, np2)) {AddExternalEdge(np1, np2);}
  958. else {noend = 0;}
  959. if (np1 != startp) {startp = np1;}
  960. else {startp = np2;}
  961. }
  962. else {noend = 0;}
  963. }
  964. startp = ap2;
  965. laste = edgenum;
  966. noend = 1;
  967. while (noend)
  968. {
  969. if (GetNEPP(startp) == 2)
  970. {
  971. if (GetEdgePP(startp,1) != laste) {laste = GetEdgePP(startp,1);}
  972. else {laste = GetEdgePP(startp,2);}
  973. np1 = GetEdge(laste).PNum(1);
  974. np2 = GetEdge(laste).PNum(2);
  975. if (!IsExternalEdge(np1, np2)) {AddExternalEdge(np1, np2);}
  976. else {noend = 0;}
  977. if (np1 != startp) {startp = np1;}
  978. else {startp = np2;}
  979. }
  980. else {noend = 0;}
  981. }
  982. }
  983. }
  984. }
  985. void STLGeometry :: ClearEdges()
  986. {
  987. edgesfound = 0;
  988. edges.SetSize(0);
  989. //edgedata->SetSize(0);
  990. // externaledges.SetSize(0);
  991. edgesperpoint.SetSize(0);
  992. undoexternaledges = 0;
  993. }
  994. void STLGeometry :: STLDoctorBuildEdges()
  995. {
  996. // if (!trigsconverted) {return;}
  997. ClearEdges();
  998. meshlines.SetSize(0);
  999. FindEdgesFromAngles();
  1000. }
  1001. void STLGeometry :: DeleteExternalEdgeAtSelected()
  1002. {
  1003. StoreExternalEdges();
  1004. if (GetSelectTrig() >= 1 && GetSelectTrig() <= GetNT())
  1005. {
  1006. int ap1 = GetTriangle(GetSelectTrig()).PNum(GetNodeOfSelTrig());
  1007. int ap2 = GetTriangle(GetSelectTrig()).PNumMod(GetNodeOfSelTrig()+1);
  1008. if (IsExternalEdge(ap1,ap2)) {DeleteExternalEdge(ap1,ap2);}
  1009. }
  1010. }
  1011. void STLGeometry :: DeleteExternalEdgeInVicinity()
  1012. {
  1013. StoreExternalEdges();
  1014. if (!stldoctor.showvicinity || vicinity.Size() != GetNT()) {return;}
  1015. int i, j, ap1, ap2;
  1016. for (i = 1; i <= GetNT(); i++)
  1017. {
  1018. if (vicinity.Elem(i))
  1019. {
  1020. for (j = 1; j <= 3; j++)
  1021. {
  1022. ap1 = GetTriangle(i).PNum(j);
  1023. ap2 = GetTriangle(i).PNumMod(j+1);
  1024. if (IsExternalEdge(ap1,ap2))
  1025. {
  1026. DeleteExternalEdge(ap1,ap2);
  1027. }
  1028. }
  1029. }
  1030. }
  1031. }
  1032. void STLGeometry :: BuildExternalEdgesFromEdges()
  1033. {
  1034. StoreExternalEdges();
  1035. if (GetNE() == 0) {PrintWarning("Edges possibly not generated!");}
  1036. int i;
  1037. externaledges.SetSize(0);
  1038. for (i = 1; i <= GetNE(); i++)
  1039. {
  1040. STLEdge e = GetEdge(i);
  1041. AddExternalEdge(e.PNum(1), e.PNum(2));
  1042. }
  1043. }
  1044. void STLGeometry :: AddExternalEdge(int ap1, int ap2)
  1045. {
  1046. externaledges.Append(twoint(ap1,ap2));
  1047. }
  1048. void STLGeometry :: DeleteExternalEdge(int ap1, int ap2)
  1049. {
  1050. int i;
  1051. int found = 0;
  1052. for (i = 1; i <= NOExternalEdges(); i++)
  1053. {
  1054. if ((GetExternalEdge(i).i1 == ap1 && GetExternalEdge(i).i2 == ap2) ||
  1055. (GetExternalEdge(i).i1 == ap2 && GetExternalEdge(i).i2 == ap1)) {found = 1;};
  1056. if (found && i < NOExternalEdges())
  1057. {
  1058. externaledges.Elem(i) = externaledges.Get(i+1);
  1059. }
  1060. }
  1061. if (!found) {PrintWarning("edge not found");}
  1062. else
  1063. {
  1064. externaledges.SetSize(externaledges.Size()-1);
  1065. }
  1066. }
  1067. int STLGeometry :: IsExternalEdge(int ap1, int ap2)
  1068. {
  1069. int i;
  1070. for (i = 1; i <= NOExternalEdges(); i++)
  1071. {
  1072. if ((GetExternalEdge(i).i1 == ap1 && GetExternalEdge(i).i2 == ap2) ||
  1073. (GetExternalEdge(i).i1 == ap2 && GetExternalEdge(i).i2 == ap1)) {return 1;};
  1074. }
  1075. return 0;
  1076. }
  1077. void STLGeometry :: DestroyDirtyTrigs()
  1078. {
  1079. PrintFnStart("Destroy dirty triangles");
  1080. PrintMessage(5,"original number of triangles=", GetNT());
  1081. //destroy every triangle with other than 3 neighbours;
  1082. int changed = 1;
  1083. int i, j, k;
  1084. while (changed)
  1085. {
  1086. changed = 0;
  1087. Clear();
  1088. for (i = 1; i <= GetNT(); i++)
  1089. {
  1090. int dirty = NONeighbourTrigs(i) < 3;
  1091. for (j = 1; j <= 3; j++)
  1092. {
  1093. int pnum = GetTriangle(i).PNum(j);
  1094. /*
  1095. if (pnum == 1546)
  1096. {
  1097. // for (k = 1; k <= NOTrigsPerPoint(pnum); k++)
  1098. }
  1099. */
  1100. if (NOTrigsPerPoint(pnum) <= 2)
  1101. dirty = 1;
  1102. }
  1103. int pi1 = GetTriangle(i).PNum(1);
  1104. int pi2 = GetTriangle(i).PNum(2);
  1105. int pi3 = GetTriangle(i).PNum(3);
  1106. if (pi1 == pi2 || pi1 == pi3 || pi2 == pi3)
  1107. {
  1108. PrintMessage(5,"triangle with Volume 0: ", i, " nodes: ", pi1, ", ", pi2, ", ", pi3);
  1109. dirty = 1;
  1110. }
  1111. if (dirty)
  1112. {
  1113. for (k = i+1; k <= GetNT(); k++)
  1114. {
  1115. trias.Elem(k-1) = trias.Get(k);
  1116. // readtrias: not longer permanent, JS
  1117. // readtrias.Elem(k-1) = readtrias.Get(k);
  1118. }
  1119. int size = GetNT();
  1120. trias.SetSize(size-1);
  1121. // readtrias.SetSize(size-1);
  1122. changed = 1;
  1123. break;
  1124. }
  1125. }
  1126. }
  1127. FindNeighbourTrigs();
  1128. PrintMessage(5,"final number of triangles=", GetNT());
  1129. }
  1130. void STLGeometry :: CalcNormalsFromGeometry()
  1131. {
  1132. int i;
  1133. for (i = 1; i <= GetNT(); i++)
  1134. {
  1135. const STLTriangle & tr = GetTriangle(i);
  1136. const Point3d& ap1 = GetPoint(tr.PNum(1));
  1137. const Point3d& ap2 = GetPoint(tr.PNum(2));
  1138. const Point3d& ap3 = GetPoint(tr.PNum(3));
  1139. Vec3d normal = Cross (ap2-ap1, ap3-ap1);
  1140. if (normal.Length() != 0)
  1141. {
  1142. normal /= (normal.Length());
  1143. }
  1144. GetTriangle(i).SetNormal(normal);
  1145. }
  1146. PrintMessage(5,"Normals calculated from geometry!!!");
  1147. calcedgedataanglesnew = 1;
  1148. }
  1149. void STLGeometry :: SetSelectTrig(int trig)
  1150. {
  1151. stldoctor.selecttrig = trig;
  1152. }
  1153. int STLGeometry :: GetSelectTrig() const
  1154. {
  1155. return stldoctor.selecttrig;
  1156. }
  1157. void STLGeometry :: SetNodeOfSelTrig(int n)
  1158. {
  1159. stldoctor.nodeofseltrig = n;
  1160. }
  1161. int STLGeometry :: GetNodeOfSelTrig() const
  1162. {
  1163. return stldoctor.nodeofseltrig;
  1164. }
  1165. void STLGeometry :: MoveSelectedPointToMiddle()
  1166. {
  1167. if (GetSelectTrig() >= 1 && GetSelectTrig() <= GetNT())
  1168. {
  1169. int p = GetTriangle(GetSelectTrig()).PNum(GetNodeOfSelTrig());
  1170. Point<3> pm(0.,0.,0.); //Middlevector;
  1171. Point<3> p0(0.,0.,0.);
  1172. PrintMessage(5,"original point=", Point3d(GetPoint(p)));
  1173. int i;
  1174. int cnt = 0;
  1175. for (i = 1; i <= trigsperpoint.EntrySize(p); i++)
  1176. {
  1177. const STLTriangle& tr = GetTriangle(trigsperpoint.Get(p,i));
  1178. int j;
  1179. for (j = 1; j <= 3; j++)
  1180. {
  1181. if (tr.PNum(j) != p)
  1182. {
  1183. cnt++;
  1184. pm(0) += GetPoint(tr.PNum(j))(0);
  1185. pm(1) += GetPoint(tr.PNum(j))(1);
  1186. pm(2) += GetPoint(tr.PNum(j))(2);
  1187. }
  1188. }
  1189. }
  1190. Point<3> origp = GetPoint(p);
  1191. double fact = 0.2;
  1192. SetPoint(p, p0 + fact*(1./(double)cnt)*(pm-p0)+(1.-fact)*(origp-p0));
  1193. PrintMessage(5,"middle point=", Point3d (GetPoint(p)));
  1194. PrintMessage(5,"moved point ", Point3d (p));
  1195. }
  1196. }
  1197. void STLGeometry :: PrintSelectInfo()
  1198. {
  1199. //int trig = GetSelectTrig();
  1200. //int p = GetTriangle(trig).PNum(GetNodeOfSelTrig());
  1201. PrintMessage(1,"touch triangle ", GetSelectTrig()
  1202. , ", local node ", GetNodeOfSelTrig()
  1203. , " (=", GetTriangle(GetSelectTrig()).PNum(GetNodeOfSelTrig()), ")");
  1204. if (AtlasMade() && GetSelectTrig() >= 1 && GetSelectTrig() <= GetNT())
  1205. {
  1206. PrintMessage(1," chartnum=",GetChartNr(GetSelectTrig()));
  1207. /*
  1208. PointBetween(Center(Center(GetPoint(GetTriangle(270).PNum(1)),
  1209. GetPoint(GetTriangle(270).PNum(2))),
  1210. GetPoint(GetTriangle(270).PNum(3))),270,
  1211. Center(Center(GetPoint(GetTriangle(trig).PNum(1)),
  1212. GetPoint(GetTriangle(trig).PNum(2))),
  1213. GetPoint(GetTriangle(trig).PNum(3))),trig);
  1214. */
  1215. //PointBetween(Point3d(5.7818, 7.52768, 4.14879),260,Point3d(6.80292, 6.55392, 4.70184),233);
  1216. }
  1217. }
  1218. void STLGeometry :: ShowSelectedTrigChartnum()
  1219. {
  1220. int st = GetSelectTrig();
  1221. if (st >= 1 && st <= GetNT() && AtlasMade())
  1222. PrintMessage(1,"selected trig ", st, " has chartnumber ", GetChartNr(st));
  1223. }
  1224. void STLGeometry :: ShowSelectedTrigCoords()
  1225. {
  1226. int st = GetSelectTrig();
  1227. /*
  1228. //testing!!!!
  1229. Array<int> trigs;
  1230. GetSortedTrianglesAroundPoint(GetTriangle(st).PNum(GetNodeOfSelTrig()),st,trigs);
  1231. */
  1232. if (st >= 1 && st <= GetNT())
  1233. {
  1234. PrintMessage(1, "coordinates of selected trig ", st, ":");
  1235. PrintMessage(1, " p1 = ", GetTriangle(st).PNum(1), " = ",
  1236. Point3d (GetPoint(GetTriangle(st).PNum(1))));
  1237. PrintMessage(1, " p2 = ", GetTriangle(st).PNum(2), " = ",
  1238. Point3d (GetPoint(GetTriangle(st).PNum(2))));
  1239. PrintMessage(1, " p3 = ", GetTriangle(st).PNum(3), " = ",
  1240. Point3d (GetPoint(GetTriangle(st).PNum(3))));
  1241. }
  1242. }
  1243. void STLGeometry :: LoadMarkedTrigs()
  1244. {
  1245. PrintFnStart("load marked trigs from file 'markedtrigs.ng'");
  1246. ifstream fin("markedtrigs.ng");
  1247. int n;
  1248. fin >> n;
  1249. if (n != GetNT() || n == 0) {PrintError("Not a suitable marked-trig-file!"); return;}
  1250. int i, m;
  1251. for (i = 1; i <= n; i++)
  1252. {
  1253. fin >> m;
  1254. SetMarkedTrig(i, m);
  1255. }
  1256. fin >> n;
  1257. if (n != 0)
  1258. {
  1259. Point<3> ap1, ap2;
  1260. for (i = 1; i <= n; i++)
  1261. {
  1262. fin >> ap1(0); fin >> ap1(1); fin >> ap1(2);
  1263. fin >> ap2(0); fin >> ap2(1); fin >> ap2(2);
  1264. AddMarkedSeg(ap1,ap2);
  1265. }
  1266. }
  1267. }
  1268. void STLGeometry :: SaveMarkedTrigs()
  1269. {
  1270. PrintFnStart("save marked trigs to file 'markedtrigs.ng'");
  1271. ofstream fout("markedtrigs.ng");
  1272. int n = GetNT();
  1273. fout << n << endl;
  1274. int i;
  1275. for (i = 1; i <= n; i++)
  1276. {
  1277. fout << IsMarkedTrig(i) << "\n";
  1278. }
  1279. n = GetNMarkedSegs();
  1280. fout << n << endl;
  1281. Point<3> ap1,ap2;
  1282. for (i = 1; i <= n; i++)
  1283. {
  1284. GetMarkedSeg(i,ap1,ap2);
  1285. fout << ap1(0) << " " << ap1(1) << " " << ap1(2) << " ";
  1286. fout << ap2(0) << " " << ap2(1) << " " << ap2(2) << " " << "\n";
  1287. }
  1288. }
  1289. void STLGeometry :: NeighbourAnglesOfSelectedTrig()
  1290. {
  1291. int st = GetSelectTrig();
  1292. if (st >= 1 && st <= GetNT())
  1293. {
  1294. int i;
  1295. PrintMessage(1,"Angle to triangle ", st, ":");
  1296. for (i = 1; i <= NONeighbourTrigs(st); i++)
  1297. {
  1298. PrintMessage(1," triangle ", NeighbourTrig(st,i), ": angle = ",
  1299. 180./M_PI*GetAngle(st, NeighbourTrig(st,i)), "°",
  1300. ", calculated = ", 180./M_PI*Angle(GetTriangle(st).GeomNormal(points),
  1301. GetTriangle(NeighbourTrig(st,i)).GeomNormal(points)), "°");
  1302. }
  1303. }
  1304. }
  1305. void STLGeometry :: GetVicinity(int starttrig, int size, Array<int>& vic)
  1306. {
  1307. if (starttrig == 0 || starttrig > GetNT()) {return;}
  1308. Array<int> vicarray;
  1309. vicarray.SetSize(GetNT());
  1310. int i;
  1311. for (i = 1; i <= vicarray.Size(); i++)
  1312. {
  1313. vicarray.Elem(i) = 0;
  1314. }
  1315. vicarray.Elem(starttrig) = 1;
  1316. int j = 0,k;
  1317. Array <int> list1;
  1318. list1.SetSize(0);
  1319. Array <int> list2;
  1320. list2.SetSize(0);
  1321. list1.Append(starttrig);
  1322. while (j < size)
  1323. {
  1324. j++;
  1325. for (i = 1; i <= list1.Size(); i++)
  1326. {
  1327. for (k = 1; k <= NONeighbourTrigs(i); k++)
  1328. {
  1329. int nbtrig = NeighbourTrig(list1.Get(i),k);
  1330. if (nbtrig && vicarray.Get(nbtrig) == 0)
  1331. {
  1332. list2.Append(nbtrig);
  1333. vicarray.Elem(nbtrig) = 1;
  1334. }
  1335. }
  1336. }
  1337. list1.SetSize(0);
  1338. for (i = 1; i <= list2.Size(); i++)
  1339. {
  1340. list1.Append(list2.Get(i));
  1341. }
  1342. list2.SetSize(0);
  1343. }
  1344. vic.SetSize(0);
  1345. for (i = 1; i <= vicarray.Size(); i++)
  1346. {
  1347. if (vicarray.Get(i)) {vic.Append(i);}
  1348. }
  1349. }
  1350. void STLGeometry :: CalcVicinity(int starttrig)
  1351. {
  1352. if (starttrig == 0 || starttrig > GetNT()) {return;}
  1353. vicinity.SetSize(GetNT());
  1354. if (!stldoctor.showvicinity) {return;}
  1355. int i;
  1356. for (i = 1; i <= vicinity.Size(); i++)
  1357. {
  1358. vicinity.Elem(i) = 0;
  1359. }
  1360. vicinity.Elem(starttrig) = 1;
  1361. int j = 0,k;
  1362. Array <int> list1;
  1363. list1.SetSize(0);
  1364. Array <int> list2;
  1365. list2.SetSize(0);
  1366. list1.Append(starttrig);
  1367. // int cnt = 1;
  1368. while (j < stldoctor.vicinity)
  1369. {
  1370. j++;
  1371. for (i = 1; i <= list1.Size(); i++)
  1372. {
  1373. for (k = 1; k <= NONeighbourTrigs(i); k++)
  1374. {
  1375. int nbtrig = NeighbourTrig(list1.Get(i),k);
  1376. if (nbtrig && vicinity.Get(nbtrig) == 0)
  1377. {
  1378. list2.Append(nbtrig);
  1379. vicinity.Elem(nbtrig) = 1;
  1380. //cnt++;
  1381. }
  1382. }
  1383. }
  1384. list1.SetSize(0);
  1385. for (i = 1; i <= list2.Size(); i++)
  1386. {
  1387. list1.Append(list2.Get(i));
  1388. }
  1389. list2.SetSize(0);
  1390. }
  1391. }
  1392. int STLGeometry :: Vicinity(int trig) const
  1393. {
  1394. if (trig <= vicinity.Size() && trig >=1)
  1395. {
  1396. return vicinity.Get(trig);
  1397. }
  1398. else {PrintSysError("In STLGeometry::Vicinity");}
  1399. return 0;
  1400. }
  1401. void STLGeometry :: InitMarkedTrigs()
  1402. {
  1403. markedtrigs.SetSize(GetNT());
  1404. int i;
  1405. for (i = 1; i <= GetNT(); i++)
  1406. {
  1407. SetMarkedTrig(i, 0);
  1408. }
  1409. }
  1410. void STLGeometry :: MarkDirtyTrigs()
  1411. {
  1412. PrintFnStart("mark dirty trigs");
  1413. int i,j;
  1414. markedtrigs.SetSize(GetNT());
  1415. for (i = 1; i <= GetNT(); i++)
  1416. {
  1417. SetMarkedTrig(i, 0);
  1418. }
  1419. int found;
  1420. double dirtyangle = stlparam.yangle/2./180.*M_PI;
  1421. int cnt = 0;
  1422. for (i = 1; i <= GetNT(); i++)
  1423. {
  1424. found = 0;
  1425. for (j = 1; j <= NONeighbourTrigs(i); j++)
  1426. {
  1427. if (GetAngle(i, NeighbourTrig(i,j)) > dirtyangle)
  1428. {
  1429. found++;
  1430. }
  1431. }
  1432. if (found && GetTriangle(i).MinHeight(points) <
  1433. stldoctor.dirtytrigfact*GetTriangle(i).MaxLength(points))
  1434. {
  1435. SetMarkedTrig(i, 1); cnt++;
  1436. }
  1437. /*
  1438. else if (found == 3)
  1439. {
  1440. SetMarkedTrig(i, 1); cnt++;
  1441. }
  1442. */
  1443. }
  1444. PrintMessage(1, "marked ", cnt, " dirty trigs");
  1445. }
  1446. void STLGeometry :: MarkTopErrorTrigs()
  1447. {
  1448. int cnt = 0;
  1449. markedtrigs.SetSize(GetNT());
  1450. for (int i = 1; i <= GetNT(); i++)
  1451. {
  1452. const STLTriangle & trig = GetTriangle(i);
  1453. SetMarkedTrig(i, trig.flags.toperror);
  1454. if (trig.flags.toperror) cnt++;
  1455. }
  1456. PrintMessage(1,"marked ", cnt, " inconsistent triangles");
  1457. }
  1458. double STLGeometry :: CalcTrigBadness(int i)
  1459. {
  1460. int j;
  1461. double maxbadness = 0;
  1462. int ap1, ap2;
  1463. for (j = 1; j <= NONeighbourTrigs(i); j++)
  1464. {
  1465. GetTriangle(i).GetNeighbourPoints(GetTriangle(NeighbourTrig(i,j)), ap1, ap2);
  1466. if (!IsEdge(ap1,ap2) && GetGeomAngle(i, NeighbourTrig(i,j)) > maxbadness)
  1467. {
  1468. maxbadness = GetGeomAngle(i, NeighbourTrig(i,j));
  1469. }
  1470. }
  1471. return maxbadness;
  1472. }
  1473. void STLGeometry :: GeomSmoothRevertedTrigs()
  1474. {
  1475. //double revertedangle = stldoctor.smoothangle/180.*M_PI;
  1476. double fact = stldoctor.dirtytrigfact;
  1477. MarkRevertedTrigs();
  1478. int i, j, k, l, p;
  1479. for (i = 1; i <= GetNT(); i++)
  1480. {
  1481. if (IsMarkedTrig(i))
  1482. {
  1483. for (j = 1; j <= 3; j++)
  1484. {
  1485. double origbadness = CalcTrigBadness(i);
  1486. p = GetTriangle(i).PNum(j);
  1487. Point<3> pm(0.,0.,0.); //Middlevector;
  1488. Point<3> p0(0.,0.,0.);
  1489. int cnt = 0;
  1490. for (k = 1; k <= trigsperpoint.EntrySize(p); k++)
  1491. {
  1492. const STLTriangle& tr = GetTriangle(trigsperpoint.Get(p,k));
  1493. for (l = 1; l <= 3; l++)
  1494. {
  1495. if (tr.PNum(l) != p)
  1496. {
  1497. cnt++;
  1498. pm(0) += GetPoint(tr.PNum(l))(0);
  1499. pm(1) += GetPoint(tr.PNum(l))(1);
  1500. pm(2) += GetPoint(tr.PNum(l))(2);
  1501. }
  1502. }
  1503. }
  1504. Point3d origp = GetPoint(p);
  1505. Point3d newp = p0 + fact*(1./(double)cnt)*(pm-p0)+(1.-fact)*(origp-p0);
  1506. SetPoint(p, newp);
  1507. if (CalcTrigBadness(i) > 0.9*origbadness) {SetPoint(p,origp); PrintDot('f');}
  1508. else {PrintDot('s');}
  1509. }
  1510. }
  1511. }
  1512. MarkRevertedTrigs();
  1513. }
  1514. void STLGeometry :: MarkRevertedTrigs()
  1515. {
  1516. int i,j;
  1517. if (edgesperpoint.Size() != GetNP()) {BuildEdges();}
  1518. PrintFnStart("mark reverted trigs");
  1519. InitMarkedTrigs();
  1520. int found;
  1521. double revertedangle = stldoctor.smoothangle/180.*M_PI;
  1522. int cnt = 0;
  1523. int ap1, ap2;
  1524. for (i = 1; i <= GetNT(); i++)
  1525. {
  1526. found = 0;
  1527. for (j = 1; j <= NONeighbourTrigs(i); j++)
  1528. {
  1529. GetTriangle(i).GetNeighbourPoints(GetTriangle(NeighbourTrig(i,j)), ap1, ap2);
  1530. if (!IsEdge(ap1,ap2))
  1531. {
  1532. if (GetGeomAngle(i, NeighbourTrig(i,j)) > revertedangle)
  1533. {
  1534. found = 1;
  1535. break;
  1536. }
  1537. }
  1538. }
  1539. if (found)
  1540. {
  1541. SetMarkedTrig(i, 1); cnt++;
  1542. }
  1543. }
  1544. PrintMessage(5, "found ", cnt, " reverted trigs");
  1545. }
  1546. void STLGeometry :: SmoothDirtyTrigs()
  1547. {
  1548. PrintFnStart("smooth dirty trigs");
  1549. MarkDirtyTrigs();
  1550. int i,j;
  1551. int changed = 1;
  1552. int ap1, ap2;
  1553. while (changed)
  1554. {
  1555. changed = 0;
  1556. for (i = 1; i <= GetNT(); i++)
  1557. {
  1558. if (IsMarkedTrig(i))
  1559. {
  1560. int foundtrig = 0;
  1561. double maxlen = 0;
  1562. // JS: darf normalvector nicht ueber kurze Seite erben
  1563. maxlen = GetTriangle(i).MaxLength(GetPoints()) / 2.1; //JG: bei flachem dreieck auch kurze Seite
  1564. for (j = 1; j <= NONeighbourTrigs(i); j++)
  1565. {
  1566. if (!IsMarkedTrig(NeighbourTrig(i,j)))
  1567. {
  1568. GetTriangle(i).GetNeighbourPoints(GetTriangle(NeighbourTrig(i,j)),ap1,ap2);
  1569. if (Dist(GetPoint(ap1),GetPoint(ap2)) >= maxlen)
  1570. {
  1571. foundtrig = NeighbourTrig(i,j);
  1572. maxlen = Dist(GetPoint(ap1),GetPoint(ap2));
  1573. }
  1574. }
  1575. }
  1576. if (foundtrig)
  1577. {
  1578. GetTriangle(i).SetNormal(GetTriangle(foundtrig).Normal());
  1579. changed = 1;
  1580. SetMarkedTrig(i,0);
  1581. }
  1582. }
  1583. }
  1584. }
  1585. calcedgedataanglesnew = 1;
  1586. MarkDirtyTrigs();
  1587. int cnt = 0;
  1588. for (i = 1; i <= GetNT(); i++)
  1589. {
  1590. if (IsMarkedTrig(i)) {cnt++;}
  1591. }
  1592. PrintMessage(5,"NO marked dirty trigs=", cnt);
  1593. }
  1594. int STLGeometry :: IsMarkedTrig(int trig) const
  1595. {
  1596. if (trig <= markedtrigs.Size() && trig >=1)
  1597. {
  1598. return markedtrigs.Get(trig);
  1599. }
  1600. else {PrintSysError("In STLGeometry::IsMarkedTrig");}
  1601. return 0;
  1602. }
  1603. void STLGeometry :: SetMarkedTrig(int trig, int num)
  1604. {
  1605. if (trig <= markedtrigs.Size() && trig >=1)
  1606. {
  1607. markedtrigs.Elem(trig) = num;
  1608. }
  1609. else {PrintSysError("In STLGeometry::SetMarkedTrig");}
  1610. }
  1611. void STLGeometry :: Clear()
  1612. {
  1613. PrintFnStart("Clear");
  1614. surfacemeshed = 0;
  1615. surfaceoptimized = 0;
  1616. volumemeshed = 0;
  1617. selectedmultiedge.SetSize(0);
  1618. meshlines.SetSize(0);
  1619. // neighbourtrigs.SetSize(0);
  1620. outerchartspertrig.SetSize(0);
  1621. atlas.SetSize(0);
  1622. ClearMarkedSegs();
  1623. ClearSpiralPoints();
  1624. ClearLineEndPoints();
  1625. SetSelectTrig(0);
  1626. SetNodeOfSelTrig(1);
  1627. facecnt = 0;
  1628. SetThreadPercent(100.);
  1629. ClearEdges();
  1630. }
  1631. double STLGeometry :: Area()
  1632. {
  1633. double ar = 0;
  1634. int i;
  1635. for (i = 1; i <= GetNT(); i++)
  1636. {
  1637. ar += GetTriangle(i).Area(points);
  1638. }
  1639. return ar;
  1640. }
  1641. double STLGeometry :: GetAngle(int t1, int t2)
  1642. {
  1643. return Angle(GetTriangle(t1).Normal(),GetTriangle(t2).Normal());
  1644. }
  1645. double STLGeometry :: GetGeomAngle(int t1, int t2)
  1646. {
  1647. Vec3d n1 = GetTriangle(t1).GeomNormal(points);
  1648. Vec3d n2 = GetTriangle(t2).GeomNormal(points);
  1649. return Angle(n1,n2);
  1650. }
  1651. void STLGeometry :: InitSTLGeometry(const Array<STLReadTriangle> & readtrias)
  1652. {
  1653. PrintFnStart("Init STL Geometry");
  1654. STLTopology::InitSTLGeometry(readtrias);
  1655. int i, k;
  1656. //const double geometry_tol_fact = 1E8; //distances lower than max_box_size/tol are ignored
  1657. int np = GetNP();
  1658. PrintMessage(5,"NO points= ", GetNP());
  1659. normals.SetSize(GetNP());
  1660. Array<int> normal_cnt(GetNP()); // counts number of added normals in a point
  1661. for (i = 1; i <= np; i++)
  1662. {
  1663. normal_cnt.Elem(i) = 0;
  1664. normals.Elem(i) = Vec3d (0,0,0);
  1665. }
  1666. for(i = 1; i <= GetNT(); i++)
  1667. {
  1668. // STLReadTriangle t = GetReadTriangle(i);
  1669. // STLTriangle st;
  1670. Vec<3> n = GetTriangle(i).Normal ();
  1671. for (k = 1; k <= 3; k++)
  1672. {
  1673. int pi = GetTriangle(i).PNum(k);
  1674. normal_cnt.Elem(pi)++;
  1675. SetNormal(pi, GetNormal(pi) + n);
  1676. }
  1677. }
  1678. //normalize the normals
  1679. for (i = 1; i <= GetNP(); i++)
  1680. {
  1681. SetNormal(i,1./(double)normal_cnt.Get(i)*GetNormal(i));
  1682. }
  1683. trigsconverted = 1;
  1684. vicinity.SetSize(GetNT());
  1685. markedtrigs.SetSize(GetNT());
  1686. for (i = 1; i <= GetNT(); i++)
  1687. {
  1688. markedtrigs.Elem(i) = 0;
  1689. vicinity.Elem(i) = 1;
  1690. }
  1691. ha_points.SetSize(GetNP());
  1692. for (i = 1; i <= GetNP(); i++)
  1693. ha_points.Elem(i) = 0;
  1694. calcedgedataanglesnew = 0;
  1695. edgedatastored = 0;
  1696. edgedata->Clear();
  1697. if (GetStatus() == STL_ERROR) return;
  1698. CalcEdgeData();
  1699. CalcEdgeDataAngles();
  1700. ClearLineEndPoints();
  1701. CheckGeometryOverlapping();
  1702. }
  1703. void STLGeometry :: TopologyChanged()
  1704. {
  1705. calcedgedataanglesnew = 1;
  1706. }
  1707. int STLGeometry :: CheckGeometryOverlapping()
  1708. {
  1709. int i, j, k;
  1710. Box<3> geombox = GetBoundingBox();
  1711. Point<3> pmin = geombox.PMin();
  1712. Point<3> pmax = geombox.PMax();
  1713. Box3dTree setree(pmin, pmax);
  1714. Array<int> inters;
  1715. int oltrigs = 0;
  1716. markedtrigs.SetSize(GetNT());
  1717. for (i = 1; i <= GetNT(); i++)
  1718. SetMarkedTrig(i, 0);
  1719. for (i = 1; i <= GetNT(); i++)
  1720. {
  1721. const STLTriangle & tri = GetTriangle(i);
  1722. Point<3> tpmin = tri.box.PMin();
  1723. Point<3> tpmax = tri.box.PMax();
  1724. Vec<3> diag = tpmax - tpmin;
  1725. tpmax = tpmax + 0.001 * diag;
  1726. tpmin = tpmin - 0.001 * diag;
  1727. setree.Insert (tpmin, tpmax, i);
  1728. }
  1729. for (i = 1; i <= GetNT(); i++)
  1730. {
  1731. const STLTriangle & tri = GetTriangle(i);
  1732. Point<3> tpmin = tri.box.PMin();
  1733. Point<3> tpmax = tri.box.PMax();
  1734. setree.GetIntersecting (tpmin, tpmax, inters);
  1735. for (j = 1; j <= inters.Size(); j++)
  1736. {
  1737. const STLTriangle & tri2 = GetTriangle(inters.Get(j));
  1738. const Point<3> *trip1[3], *trip2[3];
  1739. Point<3> hptri1[3], hptri2[3];
  1740. /*
  1741. for (k = 1; k <= 3; k++)
  1742. {
  1743. trip1[k-1] = &GetPoint (tri.PNum(k));
  1744. trip2[k-1] = &GetPoint (tri2.PNum(k));
  1745. }
  1746. */
  1747. for (k = 0; k < 3; k++)
  1748. {
  1749. hptri1[k] = GetPoint (tri[k]);
  1750. hptri2[k] = GetPoint (tri2[k]);
  1751. trip1[k] = &hptri1[k];
  1752. trip2[k] = &hptri2[k];
  1753. }
  1754. if (IntersectTriangleTriangle (&trip1[0], &trip2[0]))
  1755. {
  1756. oltrigs++;
  1757. PrintMessage(5,"Intersecting Triangles: trig ",i," with ",inters.Get(j),"!");
  1758. SetMarkedTrig(i, 1);
  1759. SetMarkedTrig(inters.Get(j), 1);
  1760. }
  1761. }
  1762. }
  1763. PrintMessage(3,"Check Geometry Overlapping: overlapping triangles = ",oltrigs);
  1764. return oltrigs;
  1765. }
  1766. /*
  1767. void STLGeometry :: InitSTLGeometry()
  1768. {
  1769. STLTopology::InitSTLGeometry();
  1770. int i, j, k;
  1771. const double geometry_tol_fact = 1E8; //distances lower than max_box_size/tol are ignored
  1772. trias.SetSize(0);
  1773. points.SetSize(0);
  1774. normals.SetSize(0);
  1775. Array<int> normal_cnt; // counts number of added normals in a point
  1776. Box3d bb (GetBoundingBox().PMin() + Vec3d (-1,-1,-1),
  1777. GetBoundingBox().PMax() + Vec3d (1, 1, 1));
  1778. Point3dTree pointtree (bb.PMin(),
  1779. bb.PMax());
  1780. Array<int> pintersect;
  1781. double gtol = GetBoundingBox().CalcDiam()/geometry_tol_fact;
  1782. for(i = 1; i <= GetReadNT(); i++)
  1783. {
  1784. //if (i%500==499) {(*mycout) << (double)i/(double)GetReadNT()*100. << "%" << endl;}
  1785. STLReadTriangle t = GetReadTriangle(i);
  1786. STLTriangle st;
  1787. Vec3d n = t.normal;
  1788. for (k = 0; k < 3; k++)
  1789. {
  1790. Point3d p = t.pts[k];
  1791. Point3d pmin = p - Vec3d (gtol, gtol, gtol);
  1792. Point3d pmax = p + Vec3d (gtol, gtol, gtol);
  1793. pointtree.GetIntersecting (pmin, pmax, pintersect);
  1794. if (pintersect.Size() > 1)
  1795. (*mycout) << "found too much " << char(7) << endl;
  1796. int foundpos = 0;
  1797. if (pintersect.Size())
  1798. foundpos = pintersect.Get(1);
  1799. if (foundpos)
  1800. {
  1801. normal_cnt[foundpos]++;
  1802. SetNormal(foundpos,GetNormal(foundpos)+n);
  1803. // (*testout) << "found p " << p << endl;
  1804. }
  1805. else
  1806. {
  1807. foundpos = AddPoint(p);
  1808. AddNormal(n);
  1809. normal_cnt.Append(1);
  1810. pointtree.Insert (p, foundpos);
  1811. }
  1812. //(*mycout) << "foundpos=" << foundpos << endl;
  1813. st.pts[k] = foundpos;
  1814. }
  1815. if ( (st.pts[0] == st.pts[1]) ||
  1816. (st.pts[0] == st.pts[2]) ||
  1817. (st.pts[1] == st.pts[2]) )
  1818. {
  1819. (*mycout) << "ERROR: STL Triangle degenerated" << endl;
  1820. }
  1821. else
  1822. {
  1823. // do not add ? js
  1824. AddTriangle(st);
  1825. }
  1826. //(*mycout) << "TRIG" << i << " = " << st << endl;
  1827. }
  1828. //normal the normals
  1829. for (i = 1; i <= GetNP(); i++)
  1830. {
  1831. SetNormal(i,1./(double)normal_cnt[i]*GetNormal(i));
  1832. }
  1833. trigsconverted = 1;
  1834. vicinity.SetSize(GetNT());
  1835. markedtrigs.SetSize(GetNT());
  1836. for (i = 1; i <= GetNT(); i++)
  1837. {
  1838. markedtrigs.Elem(i) = 0;
  1839. vicinity.Elem(i) = 1;
  1840. }
  1841. ha_points.SetSize(GetNP());
  1842. for (i = 1; i <= GetNP(); i++)
  1843. ha_points.Elem(i) = 0;
  1844. calcedgedataanglesnew = 0;
  1845. edgedatastored = 0;
  1846. edgedata->Clear();
  1847. CalcEdgeData();
  1848. CalcEdgeDataAngles();
  1849. ClearLineEndPoints();
  1850. (*mycout) << "done" << endl;
  1851. }
  1852. */
  1853. void STLGeometry :: SetLineEndPoint(int pn)
  1854. {
  1855. if (pn <1 || pn > lineendpoints.Size()) {PrintSysError("Illegal pnum in SetLineEndPoint!!!"); return; }
  1856. lineendpoints.Elem(pn) = 1;
  1857. }
  1858. int STLGeometry :: IsLineEndPoint(int pn)
  1859. {
  1860. // return 0;
  1861. if (pn <1 || pn > lineendpoints.Size())
  1862. {PrintSysError("Illegal pnum in IsLineEndPoint!!!"); return 0;}
  1863. return lineendpoints.Get(pn);
  1864. }
  1865. void STLGeometry :: ClearLineEndPoints()
  1866. {
  1867. lineendpoints.SetSize(GetNP());
  1868. int i;
  1869. for (i = 1; i <= GetNP(); i++)
  1870. {
  1871. lineendpoints.Elem(i) = 0;
  1872. }
  1873. }
  1874. int STLGeometry :: IsEdge(int ap1, int ap2)
  1875. {
  1876. int i,j;
  1877. for (i = 1; i <= GetNEPP(ap1); i++)
  1878. {
  1879. for (j = 1; j <= GetNEPP(ap2); j++)
  1880. {
  1881. if (GetEdgePP(ap1,i) == GetEdgePP(ap2,j)) {return 1;}
  1882. }
  1883. }
  1884. return 0;
  1885. }
  1886. int STLGeometry :: IsEdgeNum(int ap1, int ap2)
  1887. {
  1888. int i,j;
  1889. for (i = 1; i <= GetNEPP(ap1); i++)
  1890. {
  1891. for (j = 1; j <= GetNEPP(ap2); j++)
  1892. {
  1893. if (GetEdgePP(ap1,i) == GetEdgePP(ap2,j)) {return GetEdgePP(ap1,i);

Large files files are truncated, but you can click here to view the full file