extendedEdgeMesh.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration | Website: https://openfoam.org
5  \\ / A nd | Copyright (C) 2011-2018 OpenFOAM Foundation
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8 License
9  This file is part of OpenFOAM.
10 
11  OpenFOAM is free software: you can redistribute it and/or modify it
12  under the terms of the GNU General Public License as published by
13  the Free Software Foundation, either version 3 of the License, or
14  (at your option) any later version.
15 
16  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
17  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19  for more details.
20 
21  You should have received a copy of the GNU General Public License
22  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
23 
24 \*---------------------------------------------------------------------------*/
25 
26 #include "extendedEdgeMesh.H"
27 #include "surfaceFeatures.H"
28 #include "triSurface.H"
29 #include "Random.H"
30 #include "Time.H"
31 #include "OBJstream.H"
32 #include "DynamicField.H"
33 #include "edgeMeshFormatsCore.H"
34 #include "IOmanip.H"
35 
36 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
37 
38 namespace Foam
39 {
40  defineTypeNameAndDebug(extendedEdgeMesh, 0);
41 
42  template<>
43  const char* Foam::NamedEnum
44  <
46  4
47  >::names[] =
48  {
49  "convex",
50  "concave",
51  "mixed",
52  "nonFeature"
53  };
54 
55  template<>
56  const char* Foam::NamedEnum
57  <
59  6
60  >::names[] =
61  {
62  "external",
63  "internal",
64  "flat",
65  "open",
66  "multiple",
67  "none"
68  };
69 
70  template<>
71  const char* Foam::NamedEnum
72  <
74  4
75  >::names[] =
76  {
77  "inside",
78  "outside",
79  "both",
80  "neither"
81  };
82 }
83 
86 
89 
92 
94  Foam::cos(degToRad(0.1));
95 
96 
98 
99 
101 
102 
104 
105 
107 
108 
110 {
111  return wordHashSet(*fileExtensionConstructorTablePtr_);
112 }
113 
114 
116 {
117  return wordHashSet(*writefileExtensionMemberFunctionTablePtr_);
118 }
119 
120 
121 
122 // * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
123 
125 (
126  const word& ext,
127  const bool verbose
128 )
129 {
130  return edgeMeshFormatsCore::checkSupport
131  (
132  readTypes(),
133  ext,
134  verbose,
135  "reading"
136  );
137 }
138 
139 
141 (
142  const word& ext,
143  const bool verbose
144 )
145 {
146  return edgeMeshFormatsCore::checkSupport
147  (
148  writeTypes(),
149  ext,
150  verbose,
151  "writing"
152  );
153 }
154 
155 
157 (
158  const fileName& name,
159  const bool verbose
160 )
161 {
162  word ext = name.ext();
163  if (ext == "gz")
164  {
165  ext = name.lessExt().ext();
166  }
167  return canReadType(ext, verbose);
168 }
169 
170 
171 // * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
172 
175 (
176  label ptI
177 ) const
178 {
179  const labelList& ptEds(pointEdges()[ptI]);
180 
181  label nPtEds = ptEds.size();
182  label nExternal = 0;
183  label nInternal = 0;
184 
185  if (nPtEds == 0)
186  {
187  // There are no edges attached to the point, this is a problem
188  return NONFEATURE;
189  }
190 
191  forAll(ptEds, i)
192  {
193  edgeStatus edStat = getEdgeStatus(ptEds[i]);
194 
195  if (edStat == EXTERNAL)
196  {
197  nExternal++;
198  }
199  else if (edStat == INTERNAL)
200  {
201  nInternal++;
202  }
203  }
204 
205  if (nExternal == nPtEds)
206  {
207  return CONVEX;
208  }
209  else if (nInternal == nPtEds)
210  {
211  return CONCAVE;
212  }
213  else
214  {
215  return MIXED;
216  }
217 }
218 
219 
222 (
223  const List<vector>& norms,
224  const labelList& edNorms,
225  const vector& fC0tofC1
226 )
227 {
228  label nEdNorms = edNorms.size();
229 
230  if (nEdNorms == 1)
231  {
232  return OPEN;
233  }
234  else if (nEdNorms == 2)
235  {
236  const vector& n0(norms[edNorms[0]]);
237  const vector& n1(norms[edNorms[1]]);
238 
239  if ((n0 & n1) > cosNormalAngleTol_)
240  {
241  return FLAT;
242  }
243  else if ((fC0tofC1 & n0) > 0.0)
244  {
245  return INTERNAL;
246  }
247  else
248  {
249  return EXTERNAL;
250  }
251  }
252  else if (nEdNorms > 2)
253  {
254  return MULTIPLE;
255  }
256  else
257  {
258  // There is a problem - the edge has no normals
259  return NONE;
260  }
261 }
262 
263 
264 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
265 
267 :
268  edgeMesh(pointField(0), edgeList(0)),
269  concaveStart_(0),
270  mixedStart_(0),
271  nonFeatureStart_(0),
272  internalStart_(0),
273  flatStart_(0),
274  openStart_(0),
275  multipleStart_(0),
276  normals_(0),
277  normalVolumeTypes_(0),
278  edgeDirections_(0),
279  normalDirections_(0),
280  edgeNormals_(0),
281  featurePointNormals_(0),
282  featurePointEdges_(0),
283  regionEdges_(0),
284  pointTree_(),
285  edgeTree_(),
286  edgeTreesByType_()
287 {}
288 
289 
291 :
292  edgeMesh(fem),
293  concaveStart_(fem.concaveStart()),
294  mixedStart_(fem.mixedStart()),
295  nonFeatureStart_(fem.nonFeatureStart()),
296  internalStart_(fem.internalStart()),
297  flatStart_(fem.flatStart()),
298  openStart_(fem.openStart()),
299  multipleStart_(fem.multipleStart()),
300  normals_(fem.normals()),
301  normalVolumeTypes_(fem.normalVolumeTypes()),
302  edgeDirections_(fem.edgeDirections()),
303  normalDirections_(fem.normalDirections()),
304  edgeNormals_(fem.edgeNormals()),
305  featurePointNormals_(fem.featurePointNormals()),
306  featurePointEdges_(fem.featurePointEdges()),
307  regionEdges_(fem.regionEdges()),
308  pointTree_(),
309  edgeTree_(),
311 {}
312 
313 
315 {
316  is >> *this;
317 }
318 
319 
321 (
322  const Xfer<pointField>& pointLst,
323  const Xfer<edgeList>& edgeLst
324 )
325 :
326  edgeMesh(pointLst, edgeLst),
327  concaveStart_(0),
328  mixedStart_(0),
329  nonFeatureStart_(0),
330  internalStart_(0),
331  flatStart_(0),
332  openStart_(0),
333  multipleStart_(0),
334  normals_(0),
336  edgeDirections_(0),
338  edgeNormals_(0),
341  regionEdges_(0),
342  pointTree_(),
343  edgeTree_(),
345 {}
346 
347 
349 (
350  const surfaceFeatures& sFeat,
351  const boolList& surfBaffleRegions
352 )
353 :
354  edgeMesh(pointField(0), edgeList(0)),
355  concaveStart_(-1),
356  mixedStart_(-1),
357  nonFeatureStart_(-1),
358  internalStart_(-1),
359  flatStart_(-1),
360  openStart_(-1),
361  multipleStart_(-1),
362  normals_(0),
364  edgeDirections_(0),
366  edgeNormals_(0),
369  regionEdges_(0),
370  pointTree_(),
371  edgeTree_(),
373 {
374  // Extract and reorder the data from surfaceFeatures
375  const triSurface& surf = sFeat.surface();
376  const labelList& featureEdges = sFeat.featureEdges();
377  const labelList& featurePoints = sFeat.featurePoints();
378 
379  // Get a labelList of all the featureEdges that are region edges
380  const labelList regionFeatureEdges(identity(sFeat.nRegionEdges()));
381 
383  (
384  surf,
385  featureEdges,
386  regionFeatureEdges,
387  featurePoints
388  );
389 
390  const labelListList& edgeFaces = surf.edgeFaces();
391 
393 
394  // Noting when the normal of a face has been used so not to duplicate
395  labelList faceMap(surf.size(), -1);
396 
397  label nAdded = 0;
398 
399  forAll(featureEdges, i)
400  {
401  label sFEI = featureEdges[i];
402 
403  // Pick up the faces adjacent to the feature edge
404  const labelList& eFaces = edgeFaces[sFEI];
405 
406  forAll(eFaces, j)
407  {
408  label eFI = eFaces[j];
409 
410  // Check to see if the points have been already used
411  if (faceMap[eFI] == -1)
412  {
413  normalVolumeTypes_[nAdded++] =
414  (
415  surfBaffleRegions[surf[eFI].region()]
416  ? BOTH
417  : INSIDE
418  );
419 
420  faceMap[eFI] = nAdded - 1;
421  }
422  }
423  }
424 }
425 
426 
428 (
430  const labelList& featureEdges,
431  const labelList& regionFeatureEdges,
432  const labelList& featurePoints
433 )
434 :
435  edgeMesh(pointField(0), edgeList(0)),
436  concaveStart_(-1),
437  mixedStart_(-1),
438  nonFeatureStart_(-1),
439  internalStart_(-1),
440  flatStart_(-1),
441  openStart_(-1),
442  multipleStart_(-1),
443  normals_(0),
445  edgeDirections_(0),
447  edgeNormals_(0),
450  regionEdges_(0),
451  pointTree_(),
452  edgeTree_(),
454 {
456  (
457  surf,
458  featureEdges,
459  regionFeatureEdges,
460  featurePoints
461  );
462 }
463 
464 
466 (
467  const pointField& pts,
468  const edgeList& eds,
469  label concaveStart,
470  label mixedStart,
471  label nonFeatureStart,
472  label internalStart,
473  label flatStart,
474  label openStart,
475  label multipleStart,
476  const vectorField& normals,
477  const List<sideVolumeType>& normalVolumeTypes,
478  const vectorField& edgeDirections,
479  const labelListList& normalDirections,
480  const labelListList& edgeNormals,
481  const labelListList& featurePointNormals,
482  const labelListList& featurePointEdges,
483  const labelList& regionEdges
484 )
485 :
486  edgeMesh(pts, eds),
487  concaveStart_(concaveStart),
488  mixedStart_(mixedStart),
489  nonFeatureStart_(nonFeatureStart),
490  internalStart_(internalStart),
491  flatStart_(flatStart),
492  openStart_(openStart),
493  multipleStart_(multipleStart),
494  normals_(normals),
495  normalVolumeTypes_(normalVolumeTypes),
496  edgeDirections_(edgeDirections),
497  normalDirections_(normalDirections),
498  edgeNormals_(edgeNormals),
499  featurePointNormals_(featurePointNormals),
500  featurePointEdges_(featurePointEdges),
501  regionEdges_(regionEdges),
502  pointTree_(),
503  edgeTree_(),
505 {}
506 
507 
509 (
510  const fileName& name,
511  const word& ext
512 )
513 :
514  edgeMesh(pointField(0), edgeList(0)),
515  concaveStart_(0),
516  mixedStart_(0),
517  nonFeatureStart_(0),
518  internalStart_(0),
519  flatStart_(0),
520  openStart_(0),
521  multipleStart_(0),
522  normals_(0),
524  edgeDirections_(0),
526  edgeNormals_(0),
529  regionEdges_(0),
530  pointTree_(),
531  edgeTree_(),
533 {
534  read(name, ext);
535 }
536 
537 
539 :
540  edgeMesh(pointField(0), edgeList(0)),
541  concaveStart_(0),
542  mixedStart_(0),
543  nonFeatureStart_(0),
544  internalStart_(0),
545  flatStart_(0),
546  openStart_(0),
547  multipleStart_(0),
548  normals_(0),
550  edgeDirections_(0),
552  edgeNormals_(0),
555  regionEdges_(0),
556  pointTree_(),
557  edgeTree_(),
559 {
560  read(name);
561 }
562 
563 
564 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
565 
567 {}
568 
569 
570 // * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
571 
573 {
574  word ext = name.ext();
575  if (ext == "gz")
576  {
577  fileName unzipName = name.lessExt();
578  return read(unzipName, unzipName.ext());
579  }
580  else
581  {
582  return read(name, ext);
583  }
584 }
585 
586 
587 // Read from file in given format
589 (
590  const fileName& name,
591  const word& ext
592 )
593 {
594  // read via selector mechanism
595  transfer(New(name, ext)());
596  return true;
597 }
598 
599 
601 (
602  const point& sample,
603  scalar searchDistSqr,
604  pointIndexHit& info
605 ) const
606 {
607  info = pointTree().findNearest
608  (
609  sample,
610  searchDistSqr
611  );
612 }
613 
614 
616 (
617  const point& sample,
618  scalar searchDistSqr,
619  pointIndexHit& info
620 ) const
621 {
622  info = edgeTree().findNearest
623  (
624  sample,
625  searchDistSqr
626  );
627 }
628 
629 
631 (
632  const pointField& samples,
633  const scalarField& searchDistSqr,
634  pointIndexHitList& info
635 ) const
636 {
637  info.setSize(samples.size());
638 
639  forAll(samples, i)
640  {
642  (
643  samples[i],
644  searchDistSqr[i],
645  info[i]
646  );
647  }
648 }
649 
650 
652 (
653  const point& sample,
654  const scalarField& searchDistSqr,
655  pointIndexHitList& info
656 ) const
657 {
659 
660  info.setSize(edgeTrees.size());
661 
662  labelList sliceStarts(edgeTrees.size());
663 
664  sliceStarts[0] = externalStart_;
665  sliceStarts[1] = internalStart_;
666  sliceStarts[2] = flatStart_;
667  sliceStarts[3] = openStart_;
668  sliceStarts[4] = multipleStart_;
669 
670  forAll(edgeTrees, i)
671  {
672  info[i] = edgeTrees[i].findNearest
673  (
674  sample,
675  searchDistSqr[i]
676  );
677 
678  // The index returned by the indexedOctree is local to the slice of
679  // edges it was supplied with, return the index to the value in the
680  // complete edge list
681 
682  info[i].setIndex(info[i].index() + sliceStarts[i]);
683  }
684 }
685 
686 
688 (
689  const point& sample,
690  scalar searchRadiusSqr,
691  pointIndexHitList& info
692 ) const
693 {
694  // Pick up all the feature points that intersect the search sphere
695  labelList elems = pointTree().findSphere
696  (
697  sample,
698  searchRadiusSqr
699  );
700 
701  DynamicList<pointIndexHit> dynPointHit(elems.size());
702 
703  forAll(elems, elemI)
704  {
705  label index = elems[elemI];
706  label ptI = pointTree().shapes().pointLabels()[index];
707  const point& pt = points()[ptI];
708 
709  pointIndexHit nearHit(true, pt, index);
710 
711  dynPointHit.append(nearHit);
712  }
713 
714  info.transfer(dynPointHit);
715 }
716 
717 
719 (
720  const point& sample,
721  const scalar searchRadiusSqr,
722  pointIndexHitList& info
723 ) const
724 {
726 
727  info.setSize(edgeTrees.size());
728 
729  labelList sliceStarts(edgeTrees.size());
730 
731  sliceStarts[0] = externalStart_;
732  sliceStarts[1] = internalStart_;
733  sliceStarts[2] = flatStart_;
734  sliceStarts[3] = openStart_;
735  sliceStarts[4] = multipleStart_;
736 
737  DynamicList<pointIndexHit> dynEdgeHit(edgeTrees.size()*3);
738 
739  // Loop over all the feature edge types
740  forAll(edgeTrees, i)
741  {
742  // Pick up all the edges that intersect the search sphere
743  labelList elems = edgeTrees[i].findSphere
744  (
745  sample,
746  searchRadiusSqr
747  );
748 
749  forAll(elems, elemI)
750  {
751  label index = elems[elemI];
752  label edgeI = edgeTrees[i].shapes().edgeLabels()[index];
753  const edge& e = edges()[edgeI];
754 
755  pointHit hitPoint = e.line(points()).nearestDist(sample);
756 
757  label hitIndex = index + sliceStarts[i];
758 
759  pointIndexHit nearHit
760  (
761  hitPoint.hit(),
762  hitPoint.rawPoint(),
763  hitIndex
764  );
765 
766  dynEdgeHit.append(nearHit);
767  }
768  }
769 
770  info.transfer(dynEdgeHit);
771 }
772 
773 
775 (
776  const pointIndexHitList& hitList
777 ) const
778 {
779  scalar minDist = GREAT;
780 
781  for
782  (
783  label hi1 = 0;
784  hi1 < hitList.size() - 1;
785  ++hi1
786  )
787  {
788  const pointIndexHit& pHit1 = hitList[hi1];
789 
790  if (pHit1.hit())
791  {
792  const edge& e1 = edges()[pHit1.index()];
793 
794  for
795  (
796  label hi2 = hi1 + 1;
797  hi2 < hitList.size();
798  ++hi2
799  )
800  {
801  const pointIndexHit& pHit2 = hitList[hi2];
802 
803  if (pHit2.hit())
804  {
805  const edge& e2 = edges()[pHit2.index()];
806 
807  // Don't refine if the edges are connected to each other
808  if (!e1.connected(e2))
809  {
810  scalar curDist =
811  mag(pHit1.hitPoint() - pHit2.hitPoint());
812 
813  minDist = min(curDist, minDist);
814  }
815  }
816  }
817  }
818  }
819 
820  return minDist;
821 }
822 
823 
826 {
827  if (pointTree_.empty())
828  {
829  // Slightly extended bb. Slightly off-centred just so on symmetric
830  // geometry there are less face/edge aligned items.
831  treeBoundBox bb(treeBoundBox(points()).extend(1e-4));
832 
833  const labelList featurePointLabels = identity(nonFeatureStart_);
834 
835  pointTree_.reset
836  (
838  (
840  (
841  points(),
842  featurePointLabels
843  ),
844  bb, // bb
845  8, // maxLevel
846  10, // leafsize
847  3.0 // duplicity
848  )
849  );
850  }
851 
852  return pointTree_();
853 }
854 
855 
858 {
859  if (edgeTree_.empty())
860  {
861  // Slightly extended bb. Slightly off-centred just so on symmetric
862  // geometry there are less face/edge aligned items.
863  treeBoundBox bb(treeBoundBox(points()).extend(1e-4));
864 
865  labelList allEdges(identity(edges().size()));
866 
867  edgeTree_.reset
868  (
870  (
872  (
873  false, // cachebb
874  edges(), // edges
875  points(), // points
876  allEdges // selected edges
877  ),
878  bb, // bb
879  8, // maxLevel
880  10, // leafsize
881  3.0 // duplicity
882  )
883  );
884  }
885 
886  return edgeTree_();
887 }
888 
889 
892 {
893  if (edgeTreesByType_.size() == 0)
894  {
895  edgeTreesByType_.setSize(nEdgeTypes);
896 
897  // Slightly extended bb. Slightly off-centred just so on symmetric
898  // geometry there are less face/edge aligned items.
899  treeBoundBox bb(treeBoundBox(points()).extend(1e-4));
900 
901  labelListList sliceEdges(nEdgeTypes);
902 
903  // External edges
904  sliceEdges[0] =
906 
907  // Internal edges
908  sliceEdges[1] = identity(flatStart_ - internalStart_) + internalStart_;
909 
910  // Flat edges
911  sliceEdges[2] = identity(openStart_ - flatStart_) + flatStart_;
912 
913  // Open edges
914  sliceEdges[3] = identity(multipleStart_ - openStart_) + openStart_;
915 
916  // Multiple edges
917  sliceEdges[4] =
919 
921  {
922  edgeTreesByType_.set
923  (
924  i,
926  (
928  (
929  false, // cachebb
930  edges(), // edges
931  points(), // points
932  sliceEdges[i] // selected edges
933  ),
934  bb, // bb
935  8, // maxLevel
936  10, // leafsize
937  3.0 // duplicity
938  )
939  );
940  }
941  }
942 
943  return edgeTreesByType_;
944 }
945 
946 
948 {
949  edgeMesh::transfer(mesh);
950 
952  mixedStart_ = mesh.mixedStart_;
955  flatStart_ = mesh.flatStart_;
956  openStart_ = mesh.openStart_;
958  normals_.transfer(mesh.normals_);
966  pointTree_ = mesh.pointTree_;
967  edgeTree_ = mesh.edgeTree_;
968  edgeTreesByType_.transfer(mesh.edgeTreesByType_);
969 }
970 
971 
973 {
974  return xferMoveTo<extendedEdgeMesh, extendedEdgeMesh>(*this);
975 }
976 
977 
979 {
980  edgeMesh::clear();
981  concaveStart_ = 0;
982  mixedStart_ = 0;
983  nonFeatureStart_ = 0;
984  internalStart_ = 0;
985  flatStart_ = 0;
986  openStart_ = 0;
987  multipleStart_ = 0;
988  normals_.clear();
996  pointTree_.clear();
997  edgeTree_.clear();
998  edgeTreesByType_.clear();
999 }
1000 
1001 
1003 {
1004  // Points
1005  // ~~~~~~
1006 
1007  // From current points into combined points
1008  labelList reversePointMap(points().size());
1009  labelList reverseFemPointMap(fem.points().size());
1010 
1011  label newPointi = 0;
1012  for (label i = 0; i < concaveStart(); i++)
1013  {
1014  reversePointMap[i] = newPointi++;
1015  }
1016  for (label i = 0; i < fem.concaveStart(); i++)
1017  {
1018  reverseFemPointMap[i] = newPointi++;
1019  }
1020 
1021  // Concave
1022  label newConcaveStart = newPointi;
1023  for (label i = concaveStart(); i < mixedStart(); i++)
1024  {
1025  reversePointMap[i] = newPointi++;
1026  }
1027  for (label i = fem.concaveStart(); i < fem.mixedStart(); i++)
1028  {
1029  reverseFemPointMap[i] = newPointi++;
1030  }
1031 
1032  // Mixed
1033  label newMixedStart = newPointi;
1034  for (label i = mixedStart(); i < nonFeatureStart(); i++)
1035  {
1036  reversePointMap[i] = newPointi++;
1037  }
1038  for (label i = fem.mixedStart(); i < fem.nonFeatureStart(); i++)
1039  {
1040  reverseFemPointMap[i] = newPointi++;
1041  }
1042 
1043  // Non-feature
1044  label newNonFeatureStart = newPointi;
1045  for (label i = nonFeatureStart(); i < points().size(); i++)
1046  {
1047  reversePointMap[i] = newPointi++;
1048  }
1049  for (label i = fem.nonFeatureStart(); i < fem.points().size(); i++)
1050  {
1051  reverseFemPointMap[i] = newPointi++;
1052  }
1053 
1054  pointField newPoints(newPointi);
1055  newPoints.rmap(points(), reversePointMap);
1056  newPoints.rmap(fem.points(), reverseFemPointMap);
1057 
1058 
1059  // Edges
1060  // ~~~~~
1061 
1062  // From current edges into combined edges
1063  labelList reverseEdgeMap(edges().size());
1064  labelList reverseFemEdgeMap(fem.edges().size());
1065 
1066  // External
1067  label newEdgeI = 0;
1068  for (label i = 0; i < internalStart(); i++)
1069  {
1070  reverseEdgeMap[i] = newEdgeI++;
1071  }
1072  for (label i = 0; i < fem.internalStart(); i++)
1073  {
1074  reverseFemEdgeMap[i] = newEdgeI++;
1075  }
1076 
1077  // Internal
1078  label newInternalStart = newEdgeI;
1079  for (label i = internalStart(); i < flatStart(); i++)
1080  {
1081  reverseEdgeMap[i] = newEdgeI++;
1082  }
1083  for (label i = fem.internalStart(); i < fem.flatStart(); i++)
1084  {
1085  reverseFemEdgeMap[i] = newEdgeI++;
1086  }
1087 
1088  // Flat
1089  label newFlatStart = newEdgeI;
1090  for (label i = flatStart(); i < openStart(); i++)
1091  {
1092  reverseEdgeMap[i] = newEdgeI++;
1093  }
1094  for (label i = fem.flatStart(); i < fem.openStart(); i++)
1095  {
1096  reverseFemEdgeMap[i] = newEdgeI++;
1097  }
1098 
1099  // Open
1100  label newOpenStart = newEdgeI;
1101  for (label i = openStart(); i < multipleStart(); i++)
1102  {
1103  reverseEdgeMap[i] = newEdgeI++;
1104  }
1105  for (label i = fem.openStart(); i < fem.multipleStart(); i++)
1106  {
1107  reverseFemEdgeMap[i] = newEdgeI++;
1108  }
1109 
1110  // Multiple
1111  label newMultipleStart = newEdgeI;
1112  for (label i = multipleStart(); i < edges().size(); i++)
1113  {
1114  reverseEdgeMap[i] = newEdgeI++;
1115  }
1116  for (label i = fem.multipleStart(); i < fem.edges().size(); i++)
1117  {
1118  reverseFemEdgeMap[i] = newEdgeI++;
1119  }
1120 
1121  edgeList newEdges(newEdgeI);
1122  forAll(edges(), i)
1123  {
1124  const edge& e = edges()[i];
1125  newEdges[reverseEdgeMap[i]] = edge
1126  (
1127  reversePointMap[e[0]],
1128  reversePointMap[e[1]]
1129  );
1130  }
1131  forAll(fem.edges(), i)
1132  {
1133  const edge& e = fem.edges()[i];
1134  newEdges[reverseFemEdgeMap[i]] = edge
1135  (
1136  reverseFemPointMap[e[0]],
1137  reverseFemPointMap[e[1]]
1138  );
1139  }
1140 
1141  pointField newEdgeDirections(newEdgeI);
1142  newEdgeDirections.rmap(edgeDirections(), reverseEdgeMap);
1143  newEdgeDirections.rmap(fem.edgeDirections(), reverseFemEdgeMap);
1144 
1145 
1146 
1147 
1148  // Normals
1149  // ~~~~~~~
1150 
1151  // Combine normals
1152  DynamicField<point> newNormals(normals().size()+fem.normals().size());
1153  newNormals.append(normals());
1154  newNormals.append(fem.normals());
1155 
1156 
1157  // Combine and re-index into newNormals
1158  labelListList newEdgeNormals(edgeNormals().size()+fem.edgeNormals().size());
1159  UIndirectList<labelList>(newEdgeNormals, reverseEdgeMap) =
1160  edgeNormals();
1161  UIndirectList<labelList>(newEdgeNormals, reverseFemEdgeMap) =
1162  fem.edgeNormals();
1163  forAll(reverseFemEdgeMap, i)
1164  {
1165  label mapI = reverseFemEdgeMap[i];
1166  labelList& en = newEdgeNormals[mapI];
1167  forAll(en, j)
1168  {
1169  en[j] += normals().size();
1170  }
1171  }
1172 
1173 
1174  // Combine and re-index into newFeaturePointNormals
1175  labelListList newFeaturePointNormals
1176  (
1177  featurePointNormals().size()
1178  + fem.featurePointNormals().size()
1179  );
1180 
1181  // Note: featurePointNormals only go up to nonFeatureStart
1182  UIndirectList<labelList>
1183  (
1184  newFeaturePointNormals,
1185  SubList<label>(reversePointMap, featurePointNormals().size())
1186  ) = featurePointNormals();
1187  UIndirectList<labelList>
1188  (
1189  newFeaturePointNormals,
1190  SubList<label>(reverseFemPointMap, fem.featurePointNormals().size())
1191  ) = fem.featurePointNormals();
1192  forAll(fem.featurePointNormals(), i)
1193  {
1194  label mapI = reverseFemPointMap[i];
1195  labelList& fn = newFeaturePointNormals[mapI];
1196  forAll(fn, j)
1197  {
1198  fn[j] += normals().size();
1199  }
1200  }
1201 
1202 
1203  // Combine regionEdges
1204  DynamicList<label> newRegionEdges
1205  (
1206  regionEdges().size()
1207  + fem.regionEdges().size()
1208  );
1209  forAll(regionEdges(), i)
1210  {
1211  newRegionEdges.append(reverseEdgeMap[regionEdges()[i]]);
1212  }
1213  forAll(fem.regionEdges(), i)
1214  {
1215  newRegionEdges.append(reverseFemEdgeMap[fem.regionEdges()[i]]);
1216  }
1217 
1218 
1219  // Assign
1220  // ~~~~~~
1221 
1222  // Transfer
1223  concaveStart_ = newConcaveStart;
1224  mixedStart_ = newMixedStart;
1225  nonFeatureStart_ = newNonFeatureStart;
1226 
1227  // Reset points and edges
1228  reset(xferMove(newPoints), newEdges.xfer());
1229 
1230  // Transfer
1231  internalStart_ = newInternalStart;
1232  flatStart_ = newFlatStart;
1233  openStart_ = newOpenStart;
1234  multipleStart_ = newMultipleStart;
1235 
1236  edgeDirections_.transfer(newEdgeDirections);
1237 
1238  normals_.transfer(newNormals);
1239  edgeNormals_.transfer(newEdgeNormals);
1240  featurePointNormals_.transfer(newFeaturePointNormals);
1241 
1242  regionEdges_.transfer(newRegionEdges);
1243 
1244  pointTree_.clear();
1245  edgeTree_.clear();
1246  edgeTreesByType_.clear();
1247 }
1248 
1249 
1251 {
1252  // Points
1253  // ~~~~~~
1254 
1255  // From current points into new points
1256  labelList reversePointMap(identity(points().size()));
1257 
1258  // Flip convex and concave points
1259 
1260  label newPointi = 0;
1261  // Concave points become convex
1262  for (label i = concaveStart(); i < mixedStart(); i++)
1263  {
1264  reversePointMap[i] = newPointi++;
1265  }
1266  // Convex points become concave
1267  label newConcaveStart = newPointi;
1268  for (label i = 0; i < concaveStart(); i++)
1269  {
1270  reversePointMap[i] = newPointi++;
1271  }
1272 
1273 
1274  // Edges
1275  // ~~~~~~
1276 
1277  // From current edges into new edges
1278  labelList reverseEdgeMap(identity(edges().size()));
1279 
1280  // Flip external and internal edges
1281 
1282  label newEdgeI = 0;
1283  // Internal become external
1284  for (label i = internalStart(); i < flatStart(); i++)
1285  {
1286  reverseEdgeMap[i] = newEdgeI++;
1287  }
1288  // External become internal
1289  label newInternalStart = newEdgeI;
1290  for (label i = 0; i < internalStart(); i++)
1291  {
1292  reverseEdgeMap[i] = newEdgeI++;
1293  }
1294 
1295 
1296  pointField newPoints(points().size());
1297  newPoints.rmap(points(), reversePointMap);
1298 
1299  edgeList newEdges(edges().size());
1300  forAll(edges(), i)
1301  {
1302  const edge& e = edges()[i];
1303  newEdges[reverseEdgeMap[i]] = edge
1304  (
1305  reversePointMap[e[0]],
1306  reversePointMap[e[1]]
1307  );
1308  }
1309 
1310 
1311  // Normals are flipped
1312  // ~~~~~~~~~~~~~~~~~~~
1313 
1314  pointField newEdgeDirections(edges().size());
1315  newEdgeDirections.rmap(-1.0*edgeDirections(), reverseEdgeMap);
1316 
1317  pointField newNormals(-1.0*normals());
1318 
1319  labelListList newEdgeNormals(edgeNormals().size());
1320  UIndirectList<labelList>(newEdgeNormals, reverseEdgeMap) = edgeNormals();
1321 
1322  labelListList newFeaturePointNormals(featurePointNormals().size());
1323 
1324  // Note: featurePointNormals only go up to nonFeatureStart
1326  (
1327  newFeaturePointNormals,
1328  SubList<label>(reversePointMap, featurePointNormals().size())
1329  ) = featurePointNormals();
1330 
1331  labelList newRegionEdges(regionEdges().size());
1332  forAll(regionEdges(), i)
1333  {
1334  newRegionEdges[i] = reverseEdgeMap[regionEdges()[i]];
1335  }
1336 
1337  // Transfer
1338  concaveStart_ = newConcaveStart;
1339 
1340  // Reset points and edges
1341  reset(xferMove(newPoints), newEdges.xfer());
1342 
1343  // Transfer
1344  internalStart_ = newInternalStart;
1345 
1346  edgeDirections_.transfer(newEdgeDirections);
1347  normals_.transfer(newNormals);
1348  edgeNormals_.transfer(newEdgeNormals);
1349  featurePointNormals_.transfer(newFeaturePointNormals);
1350  regionEdges_.transfer(newRegionEdges);
1351 
1352  pointTree_.clear();
1353  edgeTree_.clear();
1354  edgeTreesByType_.clear();
1355 }
1356 
1357 
1360  const fileName& prefix,
1361  const bool verbose
1362 ) const
1363 {
1364  Info<< nl << "Writing extendedEdgeMesh components to " << prefix
1365  << endl;
1366 
1367  edgeMesh::write(prefix + "_edgeMesh.obj");
1368 
1369  if (!verbose) return;
1370 
1371  OBJstream convexFtPtStr(prefix + "_convexFeaturePts.obj");
1372  Info<< "Writing convex feature points to " << convexFtPtStr.name() << endl;
1373 
1374  for(label i = 0; i < concaveStart_; i++)
1375  {
1376  convexFtPtStr.write(points()[i]);
1377  }
1378 
1379  OBJstream concaveFtPtStr(prefix + "_concaveFeaturePts.obj");
1380  Info<< "Writing concave feature points to "
1381  << concaveFtPtStr.name() << endl;
1382 
1383  for(label i = concaveStart_; i < mixedStart_; i++)
1384  {
1385  convexFtPtStr.write(points()[i]);
1386  }
1387 
1388  OBJstream mixedFtPtStr(prefix + "_mixedFeaturePts.obj");
1389  Info<< "Writing mixed feature points to " << mixedFtPtStr.name() << endl;
1390 
1391  for(label i = mixedStart_; i < nonFeatureStart_; i++)
1392  {
1393  mixedFtPtStr.write(points()[i]);
1394  }
1395 
1396  OBJstream mixedFtPtStructureStr(prefix + "_mixedFeaturePtsStructure.obj");
1397  Info<< "Writing mixed feature point structure to "
1398  << mixedFtPtStructureStr.name() << endl;
1399 
1400  for(label i = mixedStart_; i < nonFeatureStart_; i++)
1401  {
1402  const labelList& ptEds = pointEdges()[i];
1403 
1404  forAll(ptEds, j)
1405  {
1406  const edge& e = edges()[ptEds[j]];
1407  mixedFtPtStructureStr.write
1408  (
1409  linePointRef(points()[e[0]],
1410  points()[e[1]])
1411  );
1412  }
1413  }
1414 
1415  OBJstream externalStr(prefix + "_externalEdges.obj");
1416  Info<< "Writing external edges to " << externalStr.name() << endl;
1417 
1418  for (label i = externalStart_; i < internalStart_; i++)
1419  {
1420  const edge& e = edges()[i];
1421  externalStr.write(linePointRef(points()[e[0]], points()[e[1]]));
1422  }
1423 
1424  OBJstream internalStr(prefix + "_internalEdges.obj");
1425  Info<< "Writing internal edges to " << internalStr.name() << endl;
1426 
1427  for (label i = internalStart_; i < flatStart_; i++)
1428  {
1429  const edge& e = edges()[i];
1430  internalStr.write(linePointRef(points()[e[0]], points()[e[1]]));
1431  }
1432 
1433  OBJstream flatStr(prefix + "_flatEdges.obj");
1434  Info<< "Writing flat edges to " << flatStr.name() << endl;
1435 
1436  for (label i = flatStart_; i < openStart_; i++)
1437  {
1438  const edge& e = edges()[i];
1439  flatStr.write(linePointRef(points()[e[0]], points()[e[1]]));
1440  }
1441 
1442  OBJstream openStr(prefix + "_openEdges.obj");
1443  Info<< "Writing open edges to " << openStr.name() << endl;
1444 
1445  for (label i = openStart_; i < multipleStart_; i++)
1446  {
1447  const edge& e = edges()[i];
1448  openStr.write(linePointRef(points()[e[0]], points()[e[1]]));
1449  }
1450 
1451  OBJstream multipleStr(prefix + "_multipleEdges.obj");
1452  Info<< "Writing multiple edges to " << multipleStr.name() << endl;
1453 
1454  for (label i = multipleStart_; i < edges().size(); i++)
1455  {
1456  const edge& e = edges()[i];
1457  multipleStr.write(linePointRef(points()[e[0]], points()[e[1]]));
1458  }
1459 
1460  OBJstream regionStr(prefix + "_regionEdges.obj");
1461  Info<< "Writing region edges to " << regionStr.name() << endl;
1462 
1463  forAll(regionEdges_, i)
1464  {
1465  const edge& e = edges()[regionEdges_[i]];
1466  regionStr.write(linePointRef(points()[e[0]], points()[e[1]]));
1467  }
1468 
1469  OBJstream edgeDirsStr(prefix + "_edgeDirections.obj");
1470  Info<< "Writing edge directions to " << edgeDirsStr.name() << endl;
1471 
1473  {
1474  const vector& eVec = edgeDirections_[i];
1475  const edge& e = edges()[i];
1476 
1477  edgeDirsStr.write
1478  (
1479  linePointRef(points()[e.start()], eVec + points()[e.start()])
1480  );
1481  }
1482 }
1483 
1484 
1486 {
1488 
1489  os << indent << "point classification :" << nl;
1490  os << incrIndent;
1491  os << indent << "convex feature points : "
1493  << nl;
1494  os << indent << "concave feature points : "
1495  << setw(8) << mixedStart_-concaveStart_
1496  << nl;
1497  os << indent << "mixed feature points : "
1499  << nl;
1500  os << indent << "other (non-feature) points : "
1501  << setw(8) << points().size()-nonFeatureStart_
1502  << nl;
1503  os << decrIndent;
1504 
1505  os << indent << "edge classification :" << nl;
1506  os << incrIndent;
1507  os << indent << "external (convex angle) edges : "
1509  << nl;
1510  os << indent << "internal (concave angle) edges : "
1511  << setw(8) << flatStart_-internalStart_
1512  << nl;
1513  os << indent << "flat region edges : "
1514  << setw(8) << openStart_-flatStart_
1515  << nl;
1516  os << indent << "open edges : "
1517  << setw(8) << multipleStart_-openStart_
1518  << nl;
1519  os << indent << "multiply connected edges : "
1520  << setw(8) << edges().size()-multipleStart_
1521  << nl;
1522  os << decrIndent;
1523 }
1524 
1525 
1526 // * * * * * * * * * * * * * * * IOstream Operators * * * * * * * * * * * * //
1527 
1528 Foam::Istream& Foam::operator>>
1530  Istream& is,
1532 )
1533 {
1534  label type;
1535  is >> type;
1536 
1537  vt = static_cast<Foam::extendedEdgeMesh::sideVolumeType>(type);
1538 
1539  // Check state of Istream
1540  is.check("operator>>(Istream&, sideVolumeType&)");
1541 
1542  return is;
1543 }
1544 
1545 
1546 Foam::Ostream& Foam::operator<<
1548  Ostream& os,
1550 )
1551 {
1552  os << static_cast<label>(vt);
1553 
1554  return os;
1555 }
1556 
1557 
1559 {
1560  // fileFormats::extendedEdgeMeshFormat::write(os, em.points_, em.edges_);
1561  os << "// points" << nl
1562  << em.points() << nl
1563  << "// edges" << nl
1564  << em.edges() << nl
1565  << "// concaveStart mixedStart nonFeatureStart" << nl
1566  << em.concaveStart_ << token::SPACE
1567  << em.mixedStart_ << token::SPACE
1568  << em.nonFeatureStart_ << nl
1569  << "// internalStart flatStart openStart multipleStart" << nl
1570  << em.internalStart_ << token::SPACE
1571  << em.flatStart_ << token::SPACE
1572  << em.openStart_ << token::SPACE
1573  << em.multipleStart_ << nl
1574  << "// normals" << nl
1575  << em.normals_ << nl
1576  << "// normal volume types" << nl
1577  << em.normalVolumeTypes_ << nl
1578  << "// normalDirections" << nl
1579  << em.normalDirections_ << nl
1580  << "// edgeNormals" << nl
1581  << em.edgeNormals_ << nl
1582  << "// featurePointNormals" << nl
1583  << em.featurePointNormals_ << nl
1584  << "// featurePointEdges" << nl
1585  << em.featurePointEdges_ << nl
1586  << "// regionEdges" << nl
1587  << em.regionEdges_
1588  << endl;
1589 
1590  // Check state of Ostream
1591  os.check("Ostream& operator<<(Ostream&, const extendedEdgeMesh&)");
1592 
1593  return os;
1594 }
1595 
1596 
1598 {
1599  // fileFormats::extendedEdgeMeshFormat::read(is, em.points_, em.edges_);
1600  is >> static_cast<edgeMesh&>(em)
1601  >> em.concaveStart_
1602  >> em.mixedStart_
1603  >> em.nonFeatureStart_
1604  >> em.internalStart_
1605  >> em.flatStart_
1606  >> em.openStart_
1607  >> em.multipleStart_
1608  >> em.normals_
1609  >> em.normalVolumeTypes_
1610  >> em.normalDirections_
1611  >> em.edgeNormals_
1612  >> em.featurePointNormals_
1613  >> em.featurePointEdges_
1614  >> em.regionEdges_;
1615 
1616  // Check state of Istream
1617  is.check("Istream& operator>>(Istream&, extendedEdgeMesh&)");
1618 
1619  return is;
1620 }
1621 
1622 
1623 // ************************************************************************* //
extendedEdgeMesh()
Construct null.
label nonFeatureStart() const
Return the index of the start of the non-feature points.
A simple container for copying or transferring objects of type <T>.
Definition: Xfer.H:85
static autoPtr< extendedEdgeMesh > New(const fileName &, const word &ext)
Select constructed from filename (explicit extension)
void transfer(edgeMesh &)
Transfer the contents of the argument and annul the argument.
Definition: edgeMesh.C:200
const labelListList & featurePointNormals() const
Return the indices of the normals that are adjacent to the.
A HashTable with keys but without contents.
Definition: HashSet.H:59
static const scalar GREAT
Definition: scalar.H:108
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:428
intWM_LABEL_SIZE_t label
A label is an int32_t or int64_t as specified by the pre-processor macro WM_LABEL_SIZE.
Definition: label.H:59
A class for handling file names.
Definition: fileName.H:69
Holds (reference to) pointField. Encapsulation of data needed for octree searches. Used for searching for nearest point. No bounding boxes around points. Only overlaps and calcNearest are implemented, rest makes little sense.
Definition: treeDataPoint.H:59
static wordHashSet readTypes()
Ostream & indent(Ostream &os)
Indent stream.
Definition: Ostream.H:226
vectorField normals_
Normals of the features, to be referred to by index by both feature.
label nRegionEdges() const
Return number of region edges.
const labelListList & edgeNormals() const
Return the indices of the normals that are adjacent to the.
void nearestFeaturePoint(const point &sample, scalar searchDistSqr, pointIndexHit &info) const
Find nearest surface edge for the sample point.
static bool canWriteType(const word &ext, const bool verbose=false)
Can we write this file format type?
virtual bool check(const char *operation) const
Check IOstream status for given operation.
Definition: IOstream.C:92
Xfer< List< T > > xfer()
Transfer contents to the Xfer container.
Definition: ListI.H:177
void sortPointsAndEdges(const Patch &, const labelList &featureEdges, const labelList &regionFeatureEdges, const labelList &feaurePoints)
PtrList< indexedOctree< treeDataEdge > > edgeTreesByType_
Individual search trees for each type of edge.
label mixedStart_
Index of the start of the mixed type feature points.
virtual void writeStats(Ostream &os) const
Dump some information.
An Istream is an abstract base class for all input systems (streams, files, token lists etc)...
Definition: Istream.H:57
void size(const label)
Override size to be inconsistent with allocated storage.
Definition: ListI.H:163
Description of feature edges and points.
label multipleStart() const
Return the index of the start of the multiply-connected feature.
label openStart_
Index of the start of the open feature edges.
static const Foam::NamedEnum< sideVolumeType, 4 > sideVolumeTypeNames_
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:256
Holds data for octree to work on an edges subset.
Definition: treeDataEdge.H:53
virtual void clear()
Clear all storage.
static const Foam::NamedEnum< edgeStatus, 6 > edgeStatusNames_
const vectorField & normals() const
Return the normals of the surfaces adjacent to the feature edges.
labelList identity(const label len)
Create identity map (map[i] == i) of given length.
Definition: ListOps.C:104
label concaveStart_
Index of the start of the concave feature points.
label openStart() const
Return the index of the start of the open feature edges.
This class describes the interaction of (usually) a face and a point. It carries the info of a succes...
Definition: PointIndexHit.H:53
List< sideVolumeType > normalVolumeTypes_
Type per normal: which side of normal to mesh.
void add(const extendedEdgeMesh &)
Add extendedEdgeMesh. No filtering of duplicates.
const labelList & featureEdges() const
Return feature edge list.
const labelList & regionEdges() const
Return the feature edges which are on the boundary between.
virtual Ostream & write(const char)
Write character.
Definition: OBJstream.C:82
const fileName & name() const
Return the name of the stream.
Definition: OFstream.H:120
Initialise the NamedEnum HashTable from the static list of names.
Definition: NamedEnum.H:51
scalar minDist(const List< pointIndexHit > &hitList)
word ext() const
Return file name extension (part after last .)
Definition: fileName.C:283
scalar degToRad(const scalar deg)
Conversion from degrees to radians.
Pair< int > faceMap(const label facePi, const face &faceP, const label faceNi, const face &faceN)
edgeMesh()
Construct null.
Definition: edgeMesh.C:123
label internalStart_
Index of the start of the internal feature edges.
void nearestFeatureEdgeByType(const point &sample, const scalarField &searchDistSqr, pointIndexHitList &info) const
Find the nearest point on each type of feature edge.
labelListList normalDirections_
Starting directions for the edges.
A list of faces which address into the list of points.
const Point & hitPoint() const
Return hit point.
A List obtained as a section of another List.
Definition: SubList.H:53
linePointRef line(const pointField &) const
Return edge line.
Definition: edgeI.H:187
const labelListList & pointEdges() const
Return edges.
Definition: edgeMeshI.H:65
void allNearestFeatureEdges(const point &sample, const scalar searchRadiusSqr, pointIndexHitList &info) const
Find all the feature edges within searchDistSqr of sample.
vectorField pointField
pointField is a vectorField.
Definition: pointFieldFwd.H:42
void flipNormals()
Flip normals. All concave become convex, all internal external.
dynamicFvMesh & mesh
label flatStart() const
Return the index of the start of the flat feature edges.
dimensionedScalar cos(const dimensionedScalar &ds)
line< point, const point & > linePointRef
Line using referred points.
Definition: linePointRef.H:45
labelList regionEdges_
Feature edges which are on the boundary between regions.
A 1D vector of objects of type <T> that resizes itself as necessary to accept the new objects...
Definition: DynamicList.H:56
List< edge > edgeList
Definition: edgeList.H:38
static label convexStart_
Index of the start of the convex feature points - static as 0.
An edge is a list of two point labels. The functionality it provides supports the discretisation on a...
Definition: edge.H:58
label internalStart() const
Return the index of the start of the internal feature edges.
Xfer< T > xferMove(T &)
Construct by transferring the contents of the arg.
static label nEdgeTypes
Number of possible feature edge types (i.e. number of slices)
void clear()
Clear the list, i.e. set size to zero.
Definition: ListI.H:124
A class for handling words, derived from string.
Definition: word.H:59
label flatStart_
Index of the start of the flat feature edges.
Istream & operator>>(Istream &, directionInfo &)
const edgeList & edges() const
Return edges.
Definition: edgeMeshI.H:59
const triSurface & surface() const
bool read(const fileName &, const word &ext)
Read from file. Chooses reader based on explicit extension.
~extendedEdgeMesh()
Destructor.
bool hit() const
Is there a hit.
sideVolumeType
Normals point to the outside.
static label externalStart_
Index of the start of the external feature edges - static as 0.
void transfer(extendedEdgeMesh &)
Transfer the contents of the argument and annul the argument.
const labelListList & edgeFaces() const
Return edge-face addressing.
bool hit() const
Is there a hit.
Definition: PointHit.H:120
Dynamically sized Field.
Definition: DynamicField.H:49
HashSet wordHashSet
A HashSet with word keys.
Definition: HashSet.H:207
autoPtr< indexedOctree< treeDataEdge > > edgeTree_
Search tree for all edges.
const indexedOctree< treeDataEdge > & edgeTree() const
Demand driven construction of octree for boundary edges.
static scalar cosNormalAngleTol_
Angular closeness tolerance for treating normals as the same.
label mixedStart() const
Return the index of the start of the mixed type feature points.
bool connected(const edge &a) const
Return true if connected to given edge.
Definition: edgeI.H:103
An Ostream is an abstract base class for all output systems (streams, files, token lists...
Definition: Ostream.H:53
const Point & rawPoint() const
Return point with no checking.
Definition: PointHit.H:158
Istream and Ostream manipulators taking arguments.
OFstream which keeps track of vertices.
Definition: OBJstream.H:53
static const char nl
Definition: Ostream.H:265
const labelList & featurePoints() const
Return feature point list.
const pointField & points() const
Return points.
Definition: edgeMeshI.H:53
defineTypeNameAndDebug(combustionModel, 0)
Points connected by edges.
Definition: edgeMesh.H:69
Ostream & decrIndent(Ostream &os)
Decrement the indent level.
Definition: Ostream.H:240
virtual void writeStats(Ostream &) const
Definition: edgeMeshIO.C:117
dimensioned< Type > min(const dimensioned< Type > &, const dimensioned< Type > &)
virtual void reset(const Xfer< pointField > &points, const Xfer< edgeList > &edges)
Reset primitive data (points, edges)
Definition: edgeMesh.C:178
const PtrList< indexedOctree< treeDataEdge > > & edgeTreesByType() const
Demand driven construction of octree for boundary edges by type.
fileName::Type type(const fileName &, const bool followLink=true)
Return the file type: DIRECTORY or FILE.
Definition: POSIX.C:481
static edgeStatus classifyEdge(const List< vector > &norms, const labelList &edNorms, const vector &fC0tofC1)
Classify the type of feature edge. Requires face centre 0 to face.
label size() const
Return the number of elements in the UPtrList.
Definition: UPtrListI.H:29
static bool canReadType(const word &ext, const bool verbose=false)
Can we read this file format?
virtual void clear()
Clear all storage.
Definition: edgeMesh.C:169
void setSize(const label)
Reset size of List.
Definition: List.C:281
const vectorField & edgeDirections() const
Return the edgeDirection vectors.
void rmap(const UList< Type > &mapF, const labelUList &mapAddressing)
1 to 1 reverse-map from the given field
Definition: Field.C:584
Xfer< extendedEdgeMesh > xfer()
Transfer contents to the Xfer container.
label multipleStart_
Index of the start of the multiply-connected feature edges.
static const Foam::NamedEnum< pointStatus, 4 > pointStatusNames_
label newPointi
Definition: readKivaGrid.H:501
A templated 1D list of pointers to objects of type <T>, where the size of the array is known and used...
Definition: List.H:63
A List with indirect addressing.
Definition: fvMatrix.H:106
Ostream & operator<<(Ostream &, const ensightPart &)
static bool canRead(const fileName &, const bool verbose=false)
Can we read this file format?
static void write(const fileName &, const edgeMesh &)
Write to file.
Definition: edgeMeshIO.C:87
fileName lessExt() const
Return file name without extension (part before last .)
Definition: fileName.C:268
labelListList featurePointEdges_
Indices of feature edges attached to feature points. The edges are.
void writeObj(const fileName &prefix, const bool verbose=true) const
Write all components of the extendedEdgeMesh as obj files.
Standard boundBox + extra functionality for use in octree.
Definition: treeBoundBox.H:87
messageStream Info
static label nPointTypes
Number of possible point types (i.e. number of slices)
const indexedOctree< treeDataPoint > & pointTree() const
Demand driven construction of octree for feature points.
dimensioned< scalar > mag(const dimensioned< Type > &)
static wordHashSet writeTypes()
scalar minDisconnectedDist(const pointIndexHitList &hitList) const
Return the minimum distance between disconnected edges.
const doubleScalar e
Elementary charge.
Definition: doubleScalar.H:98
Omanip< int > setw(const int i)
Definition: IOmanip.H:199
labelListList featurePointNormals_
Indices of the normals that are adjacent to the feature points.
labelListList edgeNormals_
Indices of the normals that are adjacent to the feature edges.
Triangulated surface description with patch information.
Definition: triSurface.H:66
label nonFeatureStart_
Index of the start of the non-feature points.
void nearestFeatureEdge(const point &sample, scalar searchDistSqr, pointIndexHit &info) const
Find nearest surface edge for the sample point.
Ostream & incrIndent(Ostream &os)
Increment the indent level.
Definition: Ostream.H:233
vectorField edgeDirections_
Flat and open edges require the direction of the edge.
autoPtr< indexedOctree< treeDataPoint > > pointTree_
Search tree for all feature points.
void transfer(List< T > &)
Transfer the contents of the argument List into this list.
Definition: List.C:342
label index() const
Return index.
PointHit< Point > nearestDist(const Point &p) const
Return nearest distance to line from a given point.
Definition: lineI.H:95
DynamicField< T, SizeInc, SizeMult, SizeDiv > & append(const T &)
Append an element at the end of the list.
label start() const
Return start vertex label.
Definition: edgeI.H:81
Holds feature edges/points of surface.
void allNearestFeaturePoints(const point &sample, scalar searchRadiusSqr, pointIndexHitList &info) const
Find all the feature points within searchDistSqr of sample.
Namespace for OpenFOAM.
label concaveStart() const
Return the index of the start of the concave feature points.
pointStatus classifyFeaturePoint(label ptI) const
Classify the type of feature point. Requires valid stored member.