extendedEdgeMesh.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration |
5  \\ / A nd | Copyright (C) 2011-2017 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  List<pointIndexHit>& 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  List<pointIndexHit>& 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  List<pointIndexHit>& 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  List<pointIndexHit>& 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 
776 {
777  if (pointTree_.empty())
778  {
779  Random rndGen(17301893);
780 
781  // Slightly extended bb. Slightly off-centred just so on symmetric
782  // geometry there are less face/edge aligned items.
783  treeBoundBox bb
784  (
785  treeBoundBox(points()).extend(rndGen, 1e-4)
786  );
787 
788  bb.min() -= point(ROOTVSMALL, ROOTVSMALL, ROOTVSMALL);
789  bb.max() += point(ROOTVSMALL, ROOTVSMALL, ROOTVSMALL);
790 
791  const labelList featurePointLabels = identity(nonFeatureStart_);
792 
793  pointTree_.reset
794  (
796  (
798  (
799  points(),
800  featurePointLabels
801  ),
802  bb, // bb
803  8, // maxLevel
804  10, // leafsize
805  3.0 // duplicity
806  )
807  );
808  }
809 
810  return pointTree_();
811 }
812 
813 
816 {
817  if (edgeTree_.empty())
818  {
819  Random rndGen(17301893);
820 
821  // Slightly extended bb. Slightly off-centred just so on symmetric
822  // geometry there are less face/edge aligned items.
823  treeBoundBox bb
824  (
825  treeBoundBox(points()).extend(rndGen, 1e-4)
826  );
827 
828  bb.min() -= point(ROOTVSMALL, ROOTVSMALL, ROOTVSMALL);
829  bb.max() += point(ROOTVSMALL, ROOTVSMALL, ROOTVSMALL);
830 
831  labelList allEdges(identity(edges().size()));
832 
833  edgeTree_.reset
834  (
836  (
838  (
839  false, // cachebb
840  edges(), // edges
841  points(), // points
842  allEdges // selected edges
843  ),
844  bb, // bb
845  8, // maxLevel
846  10, // leafsize
847  3.0 // duplicity
848  )
849  );
850  }
851 
852  return edgeTree_();
853 }
854 
855 
858 {
859  if (edgeTreesByType_.size() == 0)
860  {
861  edgeTreesByType_.setSize(nEdgeTypes);
862 
863  Random rndGen(872141);
864 
865  // Slightly extended bb. Slightly off-centred just so on symmetric
866  // geometry there are less face/edge aligned items.
867  treeBoundBox bb
868  (
869  treeBoundBox(points()).extend(rndGen, 1e-4)
870  );
871 
872  bb.min() -= point(ROOTVSMALL, ROOTVSMALL, ROOTVSMALL);
873  bb.max() += point(ROOTVSMALL, ROOTVSMALL, ROOTVSMALL);
874 
875  labelListList sliceEdges(nEdgeTypes);
876 
877  // External edges
878  sliceEdges[0] =
880 
881  // Internal edges
882  sliceEdges[1] = identity(flatStart_ - internalStart_) + internalStart_;
883 
884  // Flat edges
885  sliceEdges[2] = identity(openStart_ - flatStart_) + flatStart_;
886 
887  // Open edges
888  sliceEdges[3] = identity(multipleStart_ - openStart_) + openStart_;
889 
890  // Multiple edges
891  sliceEdges[4] =
893 
895  {
896  edgeTreesByType_.set
897  (
898  i,
900  (
902  (
903  false, // cachebb
904  edges(), // edges
905  points(), // points
906  sliceEdges[i] // selected edges
907  ),
908  bb, // bb
909  8, // maxLevel
910  10, // leafsize
911  3.0 // duplicity
912  )
913  );
914  }
915  }
916 
917  return edgeTreesByType_;
918 }
919 
920 
922 {
923  edgeMesh::transfer(mesh);
924 
926  mixedStart_ = mesh.mixedStart_;
929  flatStart_ = mesh.flatStart_;
930  openStart_ = mesh.openStart_;
932  normals_.transfer(mesh.normals_);
940  pointTree_ = mesh.pointTree_;
941  edgeTree_ = mesh.edgeTree_;
942  edgeTreesByType_.transfer(mesh.edgeTreesByType_);
943 }
944 
945 
947 {
948  return xferMoveTo<extendedEdgeMesh, extendedEdgeMesh>(*this);
949 }
950 
951 
953 {
954  edgeMesh::clear();
955  concaveStart_ = 0;
956  mixedStart_ = 0;
957  nonFeatureStart_ = 0;
958  internalStart_ = 0;
959  flatStart_ = 0;
960  openStart_ = 0;
961  multipleStart_ = 0;
962  normals_.clear();
970  pointTree_.clear();
971  edgeTree_.clear();
972  edgeTreesByType_.clear();
973 }
974 
975 
977 {
978  // Points
979  // ~~~~~~
980 
981  // From current points into combined points
982  labelList reversePointMap(points().size());
983  labelList reverseFemPointMap(fem.points().size());
984 
985  label newPointi = 0;
986  for (label i = 0; i < concaveStart(); i++)
987  {
988  reversePointMap[i] = newPointi++;
989  }
990  for (label i = 0; i < fem.concaveStart(); i++)
991  {
992  reverseFemPointMap[i] = newPointi++;
993  }
994 
995  // Concave
996  label newConcaveStart = newPointi;
997  for (label i = concaveStart(); i < mixedStart(); i++)
998  {
999  reversePointMap[i] = newPointi++;
1000  }
1001  for (label i = fem.concaveStart(); i < fem.mixedStart(); i++)
1002  {
1003  reverseFemPointMap[i] = newPointi++;
1004  }
1005 
1006  // Mixed
1007  label newMixedStart = newPointi;
1008  for (label i = mixedStart(); i < nonFeatureStart(); i++)
1009  {
1010  reversePointMap[i] = newPointi++;
1011  }
1012  for (label i = fem.mixedStart(); i < fem.nonFeatureStart(); i++)
1013  {
1014  reverseFemPointMap[i] = newPointi++;
1015  }
1016 
1017  // Non-feature
1018  label newNonFeatureStart = newPointi;
1019  for (label i = nonFeatureStart(); i < points().size(); i++)
1020  {
1021  reversePointMap[i] = newPointi++;
1022  }
1023  for (label i = fem.nonFeatureStart(); i < fem.points().size(); i++)
1024  {
1025  reverseFemPointMap[i] = newPointi++;
1026  }
1027 
1028  pointField newPoints(newPointi);
1029  newPoints.rmap(points(), reversePointMap);
1030  newPoints.rmap(fem.points(), reverseFemPointMap);
1031 
1032 
1033  // Edges
1034  // ~~~~~
1035 
1036  // From current edges into combined edges
1037  labelList reverseEdgeMap(edges().size());
1038  labelList reverseFemEdgeMap(fem.edges().size());
1039 
1040  // External
1041  label newEdgeI = 0;
1042  for (label i = 0; i < internalStart(); i++)
1043  {
1044  reverseEdgeMap[i] = newEdgeI++;
1045  }
1046  for (label i = 0; i < fem.internalStart(); i++)
1047  {
1048  reverseFemEdgeMap[i] = newEdgeI++;
1049  }
1050 
1051  // Internal
1052  label newInternalStart = newEdgeI;
1053  for (label i = internalStart(); i < flatStart(); i++)
1054  {
1055  reverseEdgeMap[i] = newEdgeI++;
1056  }
1057  for (label i = fem.internalStart(); i < fem.flatStart(); i++)
1058  {
1059  reverseFemEdgeMap[i] = newEdgeI++;
1060  }
1061 
1062  // Flat
1063  label newFlatStart = newEdgeI;
1064  for (label i = flatStart(); i < openStart(); i++)
1065  {
1066  reverseEdgeMap[i] = newEdgeI++;
1067  }
1068  for (label i = fem.flatStart(); i < fem.openStart(); i++)
1069  {
1070  reverseFemEdgeMap[i] = newEdgeI++;
1071  }
1072 
1073  // Open
1074  label newOpenStart = newEdgeI;
1075  for (label i = openStart(); i < multipleStart(); i++)
1076  {
1077  reverseEdgeMap[i] = newEdgeI++;
1078  }
1079  for (label i = fem.openStart(); i < fem.multipleStart(); i++)
1080  {
1081  reverseFemEdgeMap[i] = newEdgeI++;
1082  }
1083 
1084  // Multiple
1085  label newMultipleStart = newEdgeI;
1086  for (label i = multipleStart(); i < edges().size(); i++)
1087  {
1088  reverseEdgeMap[i] = newEdgeI++;
1089  }
1090  for (label i = fem.multipleStart(); i < fem.edges().size(); i++)
1091  {
1092  reverseFemEdgeMap[i] = newEdgeI++;
1093  }
1094 
1095  edgeList newEdges(newEdgeI);
1096  forAll(edges(), i)
1097  {
1098  const edge& e = edges()[i];
1099  newEdges[reverseEdgeMap[i]] = edge
1100  (
1101  reversePointMap[e[0]],
1102  reversePointMap[e[1]]
1103  );
1104  }
1105  forAll(fem.edges(), i)
1106  {
1107  const edge& e = fem.edges()[i];
1108  newEdges[reverseFemEdgeMap[i]] = edge
1109  (
1110  reverseFemPointMap[e[0]],
1111  reverseFemPointMap[e[1]]
1112  );
1113  }
1114 
1115  pointField newEdgeDirections(newEdgeI);
1116  newEdgeDirections.rmap(edgeDirections(), reverseEdgeMap);
1117  newEdgeDirections.rmap(fem.edgeDirections(), reverseFemEdgeMap);
1118 
1119 
1120 
1121 
1122  // Normals
1123  // ~~~~~~~
1124 
1125  // Combine normals
1126  DynamicField<point> newNormals(normals().size()+fem.normals().size());
1127  newNormals.append(normals());
1128  newNormals.append(fem.normals());
1129 
1130 
1131  // Combine and re-index into newNormals
1132  labelListList newEdgeNormals(edgeNormals().size()+fem.edgeNormals().size());
1133  UIndirectList<labelList>(newEdgeNormals, reverseEdgeMap) =
1134  edgeNormals();
1135  UIndirectList<labelList>(newEdgeNormals, reverseFemEdgeMap) =
1136  fem.edgeNormals();
1137  forAll(reverseFemEdgeMap, i)
1138  {
1139  label mapI = reverseFemEdgeMap[i];
1140  labelList& en = newEdgeNormals[mapI];
1141  forAll(en, j)
1142  {
1143  en[j] += normals().size();
1144  }
1145  }
1146 
1147 
1148  // Combine and re-index into newFeaturePointNormals
1149  labelListList newFeaturePointNormals
1150  (
1151  featurePointNormals().size()
1152  + fem.featurePointNormals().size()
1153  );
1154 
1155  // Note: featurePointNormals only go up to nonFeatureStart
1156  UIndirectList<labelList>
1157  (
1158  newFeaturePointNormals,
1159  SubList<label>(reversePointMap, featurePointNormals().size())
1160  ) = featurePointNormals();
1161  UIndirectList<labelList>
1162  (
1163  newFeaturePointNormals,
1164  SubList<label>(reverseFemPointMap, fem.featurePointNormals().size())
1165  ) = fem.featurePointNormals();
1166  forAll(fem.featurePointNormals(), i)
1167  {
1168  label mapI = reverseFemPointMap[i];
1169  labelList& fn = newFeaturePointNormals[mapI];
1170  forAll(fn, j)
1171  {
1172  fn[j] += normals().size();
1173  }
1174  }
1175 
1176 
1177  // Combine regionEdges
1178  DynamicList<label> newRegionEdges
1179  (
1180  regionEdges().size()
1181  + fem.regionEdges().size()
1182  );
1183  forAll(regionEdges(), i)
1184  {
1185  newRegionEdges.append(reverseEdgeMap[regionEdges()[i]]);
1186  }
1187  forAll(fem.regionEdges(), i)
1188  {
1189  newRegionEdges.append(reverseFemEdgeMap[fem.regionEdges()[i]]);
1190  }
1191 
1192 
1193  // Assign
1194  // ~~~~~~
1195 
1196  // Transfer
1197  concaveStart_ = newConcaveStart;
1198  mixedStart_ = newMixedStart;
1199  nonFeatureStart_ = newNonFeatureStart;
1200 
1201  // Reset points and edges
1202  reset(xferMove(newPoints), newEdges.xfer());
1203 
1204  // Transfer
1205  internalStart_ = newInternalStart;
1206  flatStart_ = newFlatStart;
1207  openStart_ = newOpenStart;
1208  multipleStart_ = newMultipleStart;
1209 
1210  edgeDirections_.transfer(newEdgeDirections);
1211 
1212  normals_.transfer(newNormals);
1213  edgeNormals_.transfer(newEdgeNormals);
1214  featurePointNormals_.transfer(newFeaturePointNormals);
1215 
1216  regionEdges_.transfer(newRegionEdges);
1217 
1218  pointTree_.clear();
1219  edgeTree_.clear();
1220  edgeTreesByType_.clear();
1221 }
1222 
1223 
1225 {
1226  // Points
1227  // ~~~~~~
1228 
1229  // From current points into new points
1230  labelList reversePointMap(identity(points().size()));
1231 
1232  // Flip convex and concave points
1233 
1234  label newPointi = 0;
1235  // Concave points become convex
1236  for (label i = concaveStart(); i < mixedStart(); i++)
1237  {
1238  reversePointMap[i] = newPointi++;
1239  }
1240  // Convex points become concave
1241  label newConcaveStart = newPointi;
1242  for (label i = 0; i < concaveStart(); i++)
1243  {
1244  reversePointMap[i] = newPointi++;
1245  }
1246 
1247 
1248  // Edges
1249  // ~~~~~~
1250 
1251  // From current edges into new edges
1252  labelList reverseEdgeMap(identity(edges().size()));
1253 
1254  // Flip external and internal edges
1255 
1256  label newEdgeI = 0;
1257  // Internal become external
1258  for (label i = internalStart(); i < flatStart(); i++)
1259  {
1260  reverseEdgeMap[i] = newEdgeI++;
1261  }
1262  // External become internal
1263  label newInternalStart = newEdgeI;
1264  for (label i = 0; i < internalStart(); i++)
1265  {
1266  reverseEdgeMap[i] = newEdgeI++;
1267  }
1268 
1269 
1270  pointField newPoints(points().size());
1271  newPoints.rmap(points(), reversePointMap);
1272 
1273  edgeList newEdges(edges().size());
1274  forAll(edges(), i)
1275  {
1276  const edge& e = edges()[i];
1277  newEdges[reverseEdgeMap[i]] = edge
1278  (
1279  reversePointMap[e[0]],
1280  reversePointMap[e[1]]
1281  );
1282  }
1283 
1284 
1285  // Normals are flipped
1286  // ~~~~~~~~~~~~~~~~~~~
1287 
1288  pointField newEdgeDirections(edges().size());
1289  newEdgeDirections.rmap(-1.0*edgeDirections(), reverseEdgeMap);
1290 
1291  pointField newNormals(-1.0*normals());
1292 
1293  labelListList newEdgeNormals(edgeNormals().size());
1294  UIndirectList<labelList>(newEdgeNormals, reverseEdgeMap) = edgeNormals();
1295 
1296  labelListList newFeaturePointNormals(featurePointNormals().size());
1297 
1298  // Note: featurePointNormals only go up to nonFeatureStart
1300  (
1301  newFeaturePointNormals,
1302  SubList<label>(reversePointMap, featurePointNormals().size())
1303  ) = featurePointNormals();
1304 
1305  labelList newRegionEdges(regionEdges().size());
1306  forAll(regionEdges(), i)
1307  {
1308  newRegionEdges[i] = reverseEdgeMap[regionEdges()[i]];
1309  }
1310 
1311  // Transfer
1312  concaveStart_ = newConcaveStart;
1313 
1314  // Reset points and edges
1315  reset(xferMove(newPoints), newEdges.xfer());
1316 
1317  // Transfer
1318  internalStart_ = newInternalStart;
1319 
1320  edgeDirections_.transfer(newEdgeDirections);
1321  normals_.transfer(newNormals);
1322  edgeNormals_.transfer(newEdgeNormals);
1323  featurePointNormals_.transfer(newFeaturePointNormals);
1324  regionEdges_.transfer(newRegionEdges);
1325 
1326  pointTree_.clear();
1327  edgeTree_.clear();
1328  edgeTreesByType_.clear();
1329 }
1330 
1331 
1334  const fileName& prefix
1335 ) const
1336 {
1337  Info<< nl << "Writing extendedEdgeMesh components to " << prefix
1338  << endl;
1339 
1340  edgeMesh::write(prefix + "_edgeMesh.obj");
1341 
1342  OBJstream convexFtPtStr(prefix + "_convexFeaturePts.obj");
1343  Info<< "Writing convex feature points to " << convexFtPtStr.name() << endl;
1344 
1345  for(label i = 0; i < concaveStart_; i++)
1346  {
1347  convexFtPtStr.write(points()[i]);
1348  }
1349 
1350  OBJstream concaveFtPtStr(prefix + "_concaveFeaturePts.obj");
1351  Info<< "Writing concave feature points to "
1352  << concaveFtPtStr.name() << endl;
1353 
1354  for(label i = concaveStart_; i < mixedStart_; i++)
1355  {
1356  convexFtPtStr.write(points()[i]);
1357  }
1358 
1359  OBJstream mixedFtPtStr(prefix + "_mixedFeaturePts.obj");
1360  Info<< "Writing mixed feature points to " << mixedFtPtStr.name() << endl;
1361 
1362  for(label i = mixedStart_; i < nonFeatureStart_; i++)
1363  {
1364  mixedFtPtStr.write(points()[i]);
1365  }
1366 
1367  OBJstream mixedFtPtStructureStr(prefix + "_mixedFeaturePtsStructure.obj");
1368  Info<< "Writing mixed feature point structure to "
1369  << mixedFtPtStructureStr.name() << endl;
1370 
1371  for(label i = mixedStart_; i < nonFeatureStart_; i++)
1372  {
1373  const labelList& ptEds = pointEdges()[i];
1374 
1375  forAll(ptEds, j)
1376  {
1377  const edge& e = edges()[ptEds[j]];
1378  mixedFtPtStructureStr.write
1379  (
1380  linePointRef(points()[e[0]],
1381  points()[e[1]])
1382  );
1383  }
1384  }
1385 
1386  OBJstream externalStr(prefix + "_externalEdges.obj");
1387  Info<< "Writing external edges to " << externalStr.name() << endl;
1388 
1389  for (label i = externalStart_; i < internalStart_; i++)
1390  {
1391  const edge& e = edges()[i];
1392  externalStr.write(linePointRef(points()[e[0]], points()[e[1]]));
1393  }
1394 
1395  OBJstream internalStr(prefix + "_internalEdges.obj");
1396  Info<< "Writing internal edges to " << internalStr.name() << endl;
1397 
1398  for (label i = internalStart_; i < flatStart_; i++)
1399  {
1400  const edge& e = edges()[i];
1401  internalStr.write(linePointRef(points()[e[0]], points()[e[1]]));
1402  }
1403 
1404  OBJstream flatStr(prefix + "_flatEdges.obj");
1405  Info<< "Writing flat edges to " << flatStr.name() << endl;
1406 
1407  for (label i = flatStart_; i < openStart_; i++)
1408  {
1409  const edge& e = edges()[i];
1410  flatStr.write(linePointRef(points()[e[0]], points()[e[1]]));
1411  }
1412 
1413  OBJstream openStr(prefix + "_openEdges.obj");
1414  Info<< "Writing open edges to " << openStr.name() << endl;
1415 
1416  for (label i = openStart_; i < multipleStart_; i++)
1417  {
1418  const edge& e = edges()[i];
1419  openStr.write(linePointRef(points()[e[0]], points()[e[1]]));
1420  }
1421 
1422  OBJstream multipleStr(prefix + "_multipleEdges.obj");
1423  Info<< "Writing multiple edges to " << multipleStr.name() << endl;
1424 
1425  for (label i = multipleStart_; i < edges().size(); i++)
1426  {
1427  const edge& e = edges()[i];
1428  multipleStr.write(linePointRef(points()[e[0]], points()[e[1]]));
1429  }
1430 
1431  OBJstream regionStr(prefix + "_regionEdges.obj");
1432  Info<< "Writing region edges to " << regionStr.name() << endl;
1433 
1434  forAll(regionEdges_, i)
1435  {
1436  const edge& e = edges()[regionEdges_[i]];
1437  regionStr.write(linePointRef(points()[e[0]], points()[e[1]]));
1438  }
1439 
1440  OBJstream edgeDirsStr(prefix + "_edgeDirections.obj");
1441  Info<< "Writing edge directions to " << edgeDirsStr.name() << endl;
1442 
1444  {
1445  const vector& eVec = edgeDirections_[i];
1446  const edge& e = edges()[i];
1447 
1448  edgeDirsStr.write
1449  (
1450  linePointRef(points()[e.start()], eVec + points()[e.start()])
1451  );
1452  }
1453 }
1454 
1455 
1457 {
1459 
1460  os << indent << "point classification :" << nl;
1461  os << incrIndent;
1462  os << indent << "convex feature points : "
1464  //<< setw(8) << convexStart_
1465  << nl;
1466  os << indent << "concave feature points : "
1467  << setw(8) << mixedStart_-concaveStart_
1468  //<< setw(8) << concaveStart_
1469  << nl;
1470  os << indent << "mixed feature points : "
1472  //<< setw(8) << mixedStart_
1473  << nl;
1474  os << indent << "other (non-feature) points : "
1475  << setw(8) << points().size()-nonFeatureStart_
1476  //<< setw(8) << nonFeatureStart_
1477  << nl;
1478  os << decrIndent;
1479 
1480  os << indent << "edge classification :" << nl;
1481  os << incrIndent;
1482  os << indent << "external (convex angle) edges : "
1484  //<< setw(8) << externalStart_
1485  << nl;
1486  os << indent << "internal (concave angle) edges : "
1487  << setw(8) << flatStart_-internalStart_
1488  //<< setw(8) << internalStart_
1489  << nl;
1490  os << indent << "flat region edges : "
1491  << setw(8) << openStart_-flatStart_
1492  //<< setw(8) << flatStart_
1493  << nl;
1494  os << indent << "open edges : "
1495  << setw(8) << multipleStart_-openStart_
1496  //<< setw(8) << openStart_
1497  << nl;
1498  os << indent << "multiply connected edges : "
1499  << setw(8) << edges().size()-multipleStart_
1500  //<< setw(8) << multipleStart_
1501  << nl;
1502  os << decrIndent;
1503 }
1504 
1505 
1506 // * * * * * * * * * * * * * * * IOstream Operators * * * * * * * * * * * * //
1507 
1508 Foam::Istream& Foam::operator>>
1510  Istream& is,
1512 )
1513 {
1514  label type;
1515  is >> type;
1516 
1517  vt = static_cast<Foam::extendedEdgeMesh::sideVolumeType>(type);
1518 
1519  // Check state of Istream
1520  is.check("operator>>(Istream&, sideVolumeType&)");
1521 
1522  return is;
1523 }
1524 
1525 
1526 Foam::Ostream& Foam::operator<<
1528  Ostream& os,
1530 )
1531 {
1532  os << static_cast<label>(vt);
1533 
1534  return os;
1535 }
1536 
1537 
1539 {
1540  //fileFormats::extendedEdgeMeshFormat::write(os, em.points_, em.edges_);
1541  os << "// points" << nl
1542  << em.points() << nl
1543  << "// edges" << nl
1544  << em.edges() << nl
1545  << "// concaveStart mixedStart nonFeatureStart" << nl
1546  << em.concaveStart_ << token::SPACE
1547  << em.mixedStart_ << token::SPACE
1548  << em.nonFeatureStart_ << nl
1549  << "// internalStart flatStart openStart multipleStart" << nl
1550  << em.internalStart_ << token::SPACE
1551  << em.flatStart_ << token::SPACE
1552  << em.openStart_ << token::SPACE
1553  << em.multipleStart_ << nl
1554  << "// normals" << nl
1555  << em.normals_ << nl
1556  << "// normal volume types" << nl
1557  << em.normalVolumeTypes_ << nl
1558  << "// normalDirections" << nl
1559  << em.normalDirections_ << nl
1560  << "// edgeNormals" << nl
1561  << em.edgeNormals_ << nl
1562  << "// featurePointNormals" << nl
1563  << em.featurePointNormals_ << nl
1564  << "// featurePointEdges" << nl
1565  << em.featurePointEdges_ << nl
1566  << "// regionEdges" << nl
1567  << em.regionEdges_
1568  << endl;
1569 
1570  // Check state of Ostream
1571  os.check("Ostream& operator<<(Ostream&, const extendedEdgeMesh&)");
1572 
1573  return os;
1574 }
1575 
1576 
1578 {
1579  //fileFormats::extendedEdgeMeshFormat::read(is, em.points_, em.edges_);
1580  is >> static_cast<edgeMesh&>(em)
1581  >> em.concaveStart_
1582  >> em.mixedStart_
1583  >> em.nonFeatureStart_
1584  >> em.internalStart_
1585  >> em.flatStart_
1586  >> em.openStart_
1587  >> em.multipleStart_
1588  >> em.normals_
1589  >> em.normalVolumeTypes_
1590  >> em.normalDirections_
1591  >> em.edgeNormals_
1592  >> em.featurePointNormals_
1593  >> em.featurePointEdges_
1594  >> em.regionEdges_;
1595 
1596  // Check state of Istream
1597  is.check("Istream& operator>>(Istream&, extendedEdgeMesh&)");
1598 
1599  return is;
1600 }
1601 
1602 
1603 // ************************************************************************* //
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
#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:223
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.
const double e
Elementary charge.
Definition: doubleFloat.H:78
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:253
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.
void writeObj(const fileName &prefix) const
Write all components of the extendedEdgeMesh as obj files.
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:52
word ext() const
Return file name extension (part after last .)
Definition: fileName.C:284
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.
labelListList normalDirections_
Starting directions for the edges.
A list of faces which address into the list of points.
A List obtained as a section of another List.
Definition: SubList.H:53
linePointRef line(const pointField &) const
Return edge line.
Definition: edgeI.H:169
const labelListList & pointEdges() const
Return edges.
Definition: edgeMeshI.H:65
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
cachedRandom rndGen(label(0), -1)
bool read(const fileName &, const word &ext)
Read from file. Chooses reader based on explicit extension.
~extendedEdgeMesh()
Destructor.
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.
Simple random number generator.
Definition: Random.H:49
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.
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:262
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:237
virtual void writeStats(Ostream &) const
Definition: edgeMeshIO.C:117
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:485
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 point & max() const
Maximum describing the bounding box.
Definition: boundBoxI.H:60
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.
vector point
Point is a vector.
Definition: point.H:41
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:269
labelListList featurePointEdges_
Indices of feature edges attached to feature points. The edges are.
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)
void allNearestFeatureEdges(const point &sample, const scalar searchRadiusSqr, List< pointIndexHit > &info) const
Find all the feature edges within searchDistSqr of sample.
const indexedOctree< treeDataPoint > & pointTree() const
Demand driven construction of octree for feature points.
static wordHashSet writeTypes()
Omanip< int > setw(const int i)
Definition: IOmanip.H:199
const point & min() const
Minimum describing the bounding box.
Definition: boundBoxI.H:54
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:65
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:230
void nearestFeatureEdgeByType(const point &sample, const scalarField &searchDistSqr, List< pointIndexHit > &info) const
Find the nearest point on each type of feature edge.
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
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.
Namespace for OpenFOAM.
label concaveStart() const
Return the index of the start of the concave feature points.
void allNearestFeaturePoints(const point &sample, scalar searchRadiusSqr, List< pointIndexHit > &info) const
Find all the feature points within searchDistSqr of sample.
pointStatus classifyFeaturePoint(label ptI) const
Classify the type of feature point. Requires valid stored member.