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 | www.openfoam.com
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8  Copyright (C) 2011-2017 OpenFOAM Foundation
9  Copyright (C) 2015-2019 OpenCFD Ltd.
10 -------------------------------------------------------------------------------
11 License
12  This file is part of OpenFOAM.
13 
14  OpenFOAM is free software: you can redistribute it and/or modify it
15  under the terms of the GNU General Public License as published by
16  the Free Software Foundation, either version 3 of the License, or
17  (at your option) any later version.
18 
19  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
20  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
21  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22  for more details.
23 
24  You should have received a copy of the GNU General Public License
25  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
26 
27 \*---------------------------------------------------------------------------*/
28 
29 #include "extendedEdgeMesh.H"
30 #include "surfaceFeatures.H"
31 #include "triSurface.H"
32 #include "Random.H"
33 #include "Time.H"
34 #include "OBJstream.H"
35 #include "DynamicField.H"
36 #include "edgeMeshFormatsCore.H"
37 #include "IOmanip.H"
38 #include "searchableSurface.H"
39 #include "triSurfaceMesh.H"
40 
41 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
42 
43 namespace Foam
44 {
45  defineTypeNameAndDebug(extendedEdgeMesh, 0);
46 }
47 
48 
49 const Foam::Enum
50 <
52 >
54 ({
55  { pointStatus::CONVEX, "convex" },
56  { pointStatus::CONCAVE, "concave" },
57  { pointStatus::MIXED, "mixed" },
58  { pointStatus::NONFEATURE, "nonFeature" },
59 });
60 
61 
62 const Foam::Enum
63 <
65 >
67 ({
68  { edgeStatus::EXTERNAL, "external" },
69  { edgeStatus::INTERNAL, "internal" },
70  { edgeStatus::FLAT, "flat" },
71  { edgeStatus::OPEN, "open" },
72  { edgeStatus::MULTIPLE, "multiple" },
73  { edgeStatus::NONE, "none" },
74 });
75 
76 
77 const Foam::Enum
78 <
80 >
82 ({
83  { sideVolumeType::INSIDE, "inside" },
84  { sideVolumeType::OUTSIDE, "outside" },
85  { sideVolumeType::BOTH, "both" },
86  { sideVolumeType::NEITHER, "neither" },
87 });
88 
89 
91  Foam::cos(degToRad(0.1));
92 
93 
95 
97 
99 
101 
102 
104 {
105  return wordHashSet(*fileExtensionConstructorTablePtr_);
106 }
107 
108 
110 {
111  return wordHashSet(*writefileExtensionMemberFunctionTablePtr_);
112 }
113 
114 
115 // * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
116 
117 bool Foam::extendedEdgeMesh::canReadType(const word& ext, bool verbose)
118 {
119  return edgeMeshFormatsCore::checkSupport
120  (
121  readTypes(),
122  ext,
123  verbose,
124  "reading"
125  );
126 }
127 
128 
129 bool Foam::extendedEdgeMesh::canWriteType(const word& ext, bool verbose)
130 {
131  return edgeMeshFormatsCore::checkSupport
132  (
133  writeTypes(),
134  ext,
135  verbose,
136  "writing"
137  );
138 }
139 
140 
142 {
143  word ext = name.ext();
144  if (ext == "gz")
145  {
146  ext = name.lessExt().ext();
147  }
148  return canReadType(ext, verbose);
149 }
150 
151 
152 // * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
153 
156 (
157  label ptI
158 ) const
159 {
160  const labelList& ptEds(pointEdges()[ptI]);
161 
162  label nPtEds = ptEds.size();
163  label nExternal = 0;
164  label nInternal = 0;
165 
166  if (nPtEds == 0)
167  {
168  // There are no edges attached to the point, this is a problem
169  return NONFEATURE;
170  }
171 
172  forAll(ptEds, i)
173  {
174  edgeStatus edStat = getEdgeStatus(ptEds[i]);
175 
176  if (edStat == EXTERNAL)
177  {
178  nExternal++;
179  }
180  else if (edStat == INTERNAL)
181  {
182  nInternal++;
183  }
184  }
185 
186  if (nExternal == nPtEds)
187  {
188  return CONVEX;
189  }
190  else if (nInternal == nPtEds)
191  {
192  return CONCAVE;
193  }
194 
195  return MIXED;
196 }
197 
198 
200 (
201  const searchableSurface& surf,
202 
203  labelList& pointMap,
204  labelList& edgeMap,
205  labelList& pointsFromEdge,
206  labelList& oldEdge,
207  labelList& surfTri
208 )
209 {
210  const edgeList& edges = this->edges();
211  const pointField& points = this->points();
212 
213 
214  List<List<pointIndexHit>> edgeHits(edges.size());
215  {
216  pointField start(edges.size());
217  pointField end(edges.size());
218  forAll(edges, edgeI)
219  {
220  const edge& e = edges[edgeI];
221  start[edgeI] = points[e[0]];
222  end[edgeI] = points[e[1]];
223  }
224  surf.findLineAll(start, end, edgeHits);
225  }
226 
227  // Count number of hits
228  label nHits = 0;
229  forAll(edgeHits, edgeI)
230  {
231  nHits += edgeHits[edgeI].size();
232  }
233 
234  DynamicField<point> newPoints(points);
235  DynamicList<label> newToOldPoint(identity(points.size()));
236 
237  newPoints.setCapacity(newPoints.size()+nHits);
238  newToOldPoint.setCapacity(newPoints.capacity());
239 
240  DynamicList<edge> newEdges(edges);
241  DynamicList<label> newToOldEdge(identity(edges.size()));
242 
243  newEdges.setCapacity(newEdges.size()+nHits);
244  newToOldEdge.setCapacity(newEdges.capacity());
245 
246  // Information on additional points
247  DynamicList<label> dynPointsFromEdge(nHits);
248  DynamicList<label> dynOldEdge(nHits);
249  DynamicList<label> dynSurfTri(nHits);
250 
251  forAll(edgeHits, edgeI)
252  {
253  const List<pointIndexHit>& eHits = edgeHits[edgeI];
254 
255  if (eHits.size())
256  {
257  label prevPtI = edges[edgeI][0];
258  forAll(eHits, eHitI)
259  {
260  label newPtI = newPoints.size();
261 
262  newPoints.append(eHits[eHitI].hitPoint());
263  newToOldPoint.append(edges[edgeI][0]); // map from start point
264  dynPointsFromEdge.append(newPtI);
265  dynOldEdge.append(edgeI);
266  dynSurfTri.append(eHits[eHitI].index());
267 
268  if (eHitI == 0)
269  {
270  newEdges[edgeI] = edge(prevPtI, newPtI);
271  }
272  else
273  {
274  newEdges.append(edge(prevPtI, newPtI));
275  newToOldEdge.append(edgeI);
276  }
277  prevPtI = newPtI;
278  }
279  newEdges.append(edge(prevPtI, edges[edgeI][1]));
280  newToOldEdge.append(edgeI);
281  }
282  }
283 
285  allPoints.transfer(newPoints);
286  pointMap.transfer(newToOldPoint);
287 
288  edgeList allEdges;
289  allEdges.transfer(newEdges);
290  edgeMap.transfer(newToOldEdge);
291 
292  pointsFromEdge.transfer(dynPointsFromEdge);
293  oldEdge.transfer(dynOldEdge);
294  surfTri.transfer(dynSurfTri);
295 
296  // Update local information
297  autoMap(allPoints, allEdges, pointMap, edgeMap);
298 }
299 
300 
302 (
303  const searchableSurface& surf,
304  const volumeType volType, // side to keep
305  labelList& pointMap, // sub to old points
306  labelList& edgeMap // sub to old edges
307 )
308 {
309  const edgeList& edges = this->edges();
310  const pointField& points = this->points();
311 
312  // Test edge centres for inside/outside
313  if (volType == volumeType::INSIDE || volType == volumeType::OUTSIDE)
314  {
315  pointField edgeCentres(edges.size());
316  forAll(edgeCentres, edgeI)
317  {
318  const edge& e = edges[edgeI];
319  edgeCentres[edgeI] = e.centre(points);
320  }
321  List<volumeType> volTypes;
322  surf.getVolumeType(edgeCentres, volTypes);
323 
324  // Extract edges on correct side
325  edgeMap.setSize(edges.size());
326  label compactEdgeI = 0;
327 
328  forAll(volTypes, edgeI)
329  {
330  if (volTypes[edgeI] == volType)
331  {
332  edgeMap[compactEdgeI++] = edgeI;
333  }
334  }
335  edgeMap.setSize(compactEdgeI);
336 
337  // Extract used points
338  labelList pointToCompact(points.size(), -1);
339  forAll(edgeMap, i)
340  {
341  const edge& e = edges[edgeMap[i]];
342  pointToCompact[e[0]] = labelMax; // tag with a value
343  pointToCompact[e[1]] = labelMax;
344  }
345 
346  pointMap.setSize(points.size());
347  label compactPointI = 0;
348  forAll(pointToCompact, pointI)
349  {
350  if (pointToCompact[pointI] != -1)
351  {
352  pointToCompact[pointI] = compactPointI;
353  pointMap[compactPointI++] = pointI;
354  }
355  }
356  pointMap.setSize(compactPointI);
357  pointField subPoints(points, pointMap);
358 
359  // Renumber edges
360  edgeList subEdges(edgeMap.size());
361  forAll(edgeMap, i)
362  {
363  const edge& e = edges[edgeMap[i]];
364  subEdges[i][0] = pointToCompact[e[0]];
365  subEdges[i][1] = pointToCompact[e[1]];
366  }
367 
368  // Reset primitives and map other quantities
369  autoMap(subPoints, subEdges, pointMap, edgeMap);
370  }
371  else
372  {
373  pointMap = identity(points.size());
374  edgeMap = identity(edges.size());
375  }
376 }
377 
378 
379 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
380 
382 :
384  concaveStart_(0),
385  mixedStart_(0),
386  nonFeatureStart_(0),
387  internalStart_(0),
388  flatStart_(0),
389  openStart_(0),
390  multipleStart_(0),
391  normals_(0),
392  normalVolumeTypes_(0),
393  edgeDirections_(0),
394  normalDirections_(0),
395  edgeNormals_(0),
396  featurePointNormals_(0),
397  featurePointEdges_(0),
398  regionEdges_(0),
399  pointTree_(),
400  edgeTree_(),
401  edgeTreesByType_()
402 {}
403 
404 
406 :
408  concaveStart_(-1),
409  mixedStart_(-1),
410  nonFeatureStart_(-1),
411  internalStart_(-1),
412  flatStart_(-1),
413  openStart_(-1),
414  multipleStart_(-1),
415  normals_(0),
416  normalVolumeTypes_(0),
417  edgeDirections_(0),
418  normalDirections_(0),
419  edgeNormals_(0),
420  featurePointNormals_(0),
421  featurePointEdges_(0),
422  regionEdges_(0),
423  pointTree_(),
424  edgeTree_(),
425  edgeTreesByType_()
426 {}
427 
428 
430 :
431  edgeMesh(fem),
432  concaveStart_(fem.concaveStart()),
433  mixedStart_(fem.mixedStart()),
434  nonFeatureStart_(fem.nonFeatureStart()),
435  internalStart_(fem.internalStart()),
436  flatStart_(fem.flatStart()),
437  openStart_(fem.openStart()),
438  multipleStart_(fem.multipleStart()),
439  normals_(fem.normals()),
440  normalVolumeTypes_(fem.normalVolumeTypes()),
441  edgeDirections_(fem.edgeDirections()),
442  normalDirections_(fem.normalDirections()),
443  edgeNormals_(fem.edgeNormals()),
444  featurePointNormals_(fem.featurePointNormals()),
445  featurePointEdges_(fem.featurePointEdges()),
446  regionEdges_(fem.regionEdges()),
447  pointTree_(),
448  edgeTree_(),
449  edgeTreesByType_()
450 {}
451 
452 
454 {
455  is >> *this;
456 }
457 
458 
460 (
461  const pointField& points,
462  const edgeList& edges
463 )
464 :
466 {
467  this->storedPoints() = points;
468  this->storedEdges() = edges;
469 }
470 
471 
473 (
474  pointField&& points,
475  edgeList&& edges
476 )
477 :
479 {
480  this->storedPoints().transfer(points);
481  this->storedEdges().transfer(edges);
482 }
483 
484 
486 (
487  const surfaceFeatures& sFeat,
488  const boolList& surfBaffleRegions
489 )
490 :
492 {
493  // Extract and reorder the data from surfaceFeatures
494  const triSurface& surf = sFeat.surface();
495  const labelList& featureEdges = sFeat.featureEdges();
496  const labelList& featurePoints = sFeat.featurePoints();
497 
498  // Get a labelList of all the featureEdges that are region edges
499  const labelList regionFeatureEdges(identity(sFeat.nRegionEdges()));
500 
501  sortPointsAndEdges
502  (
503  surf,
504  featureEdges,
505  regionFeatureEdges,
506  featurePoints
507  );
508 
509  const labelListList& edgeFaces = surf.edgeFaces();
510 
511  normalVolumeTypes_.setSize(normals_.size());
512 
513  // Noting when the normal of a face has been used so not to duplicate
514  labelList faceMap(surf.size(), -1);
515 
516  label nAdded = 0;
517 
518  forAll(featureEdges, i)
519  {
520  label sFEI = featureEdges[i];
521 
522  // Pick up the faces adjacent to the feature edge
523  const labelList& eFaces = edgeFaces[sFEI];
524 
525  forAll(eFaces, j)
526  {
527  label eFI = eFaces[j];
528 
529  // Check to see if the points have been already used
530  if (faceMap[eFI] == -1)
531  {
532  normalVolumeTypes_[nAdded++] =
533  (
534  surfBaffleRegions[surf[eFI].region()]
535  ? BOTH
536  : INSIDE
537  );
538 
539  faceMap[eFI] = nAdded - 1;
540  }
541  }
542  }
543 }
544 
545 
547 (
549  const labelUList& featureEdges,
550  const labelUList& regionFeatureEdges,
551  const labelUList& featurePoints
552 )
553 :
555 {
556  sortPointsAndEdges
557  (
558  surf,
559  featureEdges,
560  regionFeatureEdges,
561  featurePoints
562  );
563 }
564 
565 
567 (
568  const pointField& pts,
569  const edgeList& eds,
570  label concaveStart,
571  label mixedStart,
572  label nonFeatureStart,
573  label internalStart,
574  label flatStart,
575  label openStart,
576  label multipleStart,
577  const vectorField& normals,
578  const List<sideVolumeType>& normalVolumeTypes,
579  const vectorField& edgeDirections,
580  const labelListList& normalDirections,
581  const labelListList& edgeNormals,
582  const labelListList& featurePointNormals,
583  const labelListList& featurePointEdges,
584  const labelList& regionEdges
585 )
586 :
587  edgeMesh(pts, eds),
588  concaveStart_(concaveStart),
589  mixedStart_(mixedStart),
590  nonFeatureStart_(nonFeatureStart),
591  internalStart_(internalStart),
592  flatStart_(flatStart),
593  openStart_(openStart),
594  multipleStart_(multipleStart),
595  normals_(normals),
596  normalVolumeTypes_(normalVolumeTypes),
597  edgeDirections_(edgeDirections),
598  normalDirections_(normalDirections),
599  edgeNormals_(edgeNormals),
600  featurePointNormals_(featurePointNormals),
601  featurePointEdges_(featurePointEdges),
602  regionEdges_(regionEdges),
603  pointTree_(),
604  edgeTree_(),
605  edgeTreesByType_()
606 {}
607 
608 
610 (
611  const fileName& name,
612  const word& ext
613 )
614 :
616 {
617  read(name, ext);
618 }
619 
620 
622 :
624 {
625  read(name);
626 }
627 
628 
629 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
630 
632 {}
633 
634 
635 // * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
636 
638 {
639  word ext = name.ext();
640  if (ext == "gz")
641  {
642  fileName unzipName = name.lessExt();
643  return read(unzipName, unzipName.ext());
644  }
645 
646  return read(name, ext);
647 }
648 
649 
650 // Read from file in given format
652 (
653  const fileName& name,
654  const word& ext
655 )
656 {
657  // read via selector mechanism
658  transfer(New(name, ext)());
659  return true;
660 }
661 
662 
664 (
665  const point& sample,
666  scalar searchDistSqr,
667  pointIndexHit& info
668 ) const
669 {
670  info = pointTree().findNearest
671  (
672  sample,
673  searchDistSqr
674  );
675 }
676 
677 
679 (
680  const point& sample,
681  scalar searchDistSqr,
682  pointIndexHit& info
683 ) const
684 {
685  info = edgeTree().findNearest
686  (
687  sample,
688  searchDistSqr
689  );
690 }
691 
692 
694 (
695  const pointField& samples,
696  const scalarField& searchDistSqr,
697  List<pointIndexHit>& info
698 ) const
699 {
700  info.setSize(samples.size());
701 
702  forAll(samples, i)
703  {
704  nearestFeatureEdge
705  (
706  samples[i],
707  searchDistSqr[i],
708  info[i]
709  );
710  }
711 }
712 
713 
715 (
716  const point& sample,
717  const scalarField& searchDistSqr,
718  List<pointIndexHit>& info
719 ) const
720 {
721  const PtrList<indexedOctree<treeDataEdge>>& edgeTrees = edgeTreesByType();
722 
723  info.setSize(edgeTrees.size());
724 
725  labelList sliceStarts(edgeTrees.size());
726 
727  sliceStarts[0] = externalStart_;
728  sliceStarts[1] = internalStart_;
729  sliceStarts[2] = flatStart_;
730  sliceStarts[3] = openStart_;
731  sliceStarts[4] = multipleStart_;
732 
733  forAll(edgeTrees, i)
734  {
735  info[i] = edgeTrees[i].findNearest
736  (
737  sample,
738  searchDistSqr[i]
739  );
740 
741  // The index returned by the indexedOctree is local to the slice of
742  // edges it was supplied with, return the index to the value in the
743  // complete edge list
744 
745  info[i].setIndex(info[i].index() + sliceStarts[i]);
746  }
747 }
748 
749 
751 (
752  const point& sample,
753  scalar searchRadiusSqr,
754  List<pointIndexHit>& info
755 ) const
756 {
757  // Pick up all the feature points that intersect the search sphere
758  labelList elems = pointTree().findSphere
759  (
760  sample,
761  searchRadiusSqr
762  );
763 
764  DynamicList<pointIndexHit> dynPointHit(elems.size());
765 
766  forAll(elems, elemI)
767  {
768  label index = elems[elemI];
769  label ptI = pointTree().shapes().pointLabels()[index];
770  const point& pt = points()[ptI];
771 
772  pointIndexHit nearHit(true, pt, index);
773 
774  dynPointHit.append(nearHit);
775  }
776 
777  info.transfer(dynPointHit);
778 }
779 
780 
782 (
783  const point& sample,
784  const scalar searchRadiusSqr,
785  List<pointIndexHit>& info
786 ) const
787 {
788  const PtrList<indexedOctree<treeDataEdge>>& edgeTrees = edgeTreesByType();
789 
790  info.setSize(edgeTrees.size());
791 
792  labelList sliceStarts(edgeTrees.size());
793 
794  sliceStarts[0] = externalStart_;
795  sliceStarts[1] = internalStart_;
796  sliceStarts[2] = flatStart_;
797  sliceStarts[3] = openStart_;
798  sliceStarts[4] = multipleStart_;
799 
800  DynamicList<pointIndexHit> dynEdgeHit(edgeTrees.size()*3);
801 
802  // Loop over all the feature edge types
803  forAll(edgeTrees, i)
804  {
805  // Pick up all the edges that intersect the search sphere
806  labelList elems = edgeTrees[i].findSphere
807  (
808  sample,
809  searchRadiusSqr
810  );
811 
812  forAll(elems, elemI)
813  {
814  label index = elems[elemI];
815  label edgeI = edgeTrees[i].shapes().edgeLabels()[index];
816  const edge& e = edges()[edgeI];
817 
818  pointHit hitPoint = e.line(points()).nearestDist(sample);
819 
820  label hitIndex = index + sliceStarts[i];
821 
822  pointIndexHit nearHit
823  (
824  hitPoint.hit(),
825  hitPoint.rawPoint(),
826  hitIndex
827  );
828 
829  dynEdgeHit.append(nearHit);
830  }
831  }
832 
833  info.transfer(dynEdgeHit);
834 }
835 
836 
839 {
840  if (pointTree_.empty())
841  {
842  Random rndGen(17301893);
843 
844  // Slightly extended bb. Slightly off-centred just so on symmetric
845  // geometry there are less face/edge aligned items.
846  treeBoundBox bb
847  (
848  treeBoundBox(points()).extend(rndGen, 1e-4)
849  );
850 
851  bb.min() -= point(ROOTVSMALL, ROOTVSMALL, ROOTVSMALL);
852  bb.max() += point(ROOTVSMALL, ROOTVSMALL, ROOTVSMALL);
853 
854  const labelList featurePointLabels = identity(nonFeatureStart_);
855 
856  pointTree_.reset
857  (
859  (
861  (
862  points(),
863  featurePointLabels
864  ),
865  bb, // bb
866  8, // maxLevel
867  10, // leafsize
868  3.0 // duplicity
869  )
870  );
871  }
872 
873  return *pointTree_;
874 }
875 
876 
879 {
880  if (edgeTree_.empty())
881  {
882  Random rndGen(17301893);
883 
884  // Slightly extended bb. Slightly off-centred just so on symmetric
885  // geometry there are less face/edge aligned items.
886  treeBoundBox bb
887  (
888  treeBoundBox(points()).extend(rndGen, 1e-4)
889  );
890 
891  bb.min() -= point(ROOTVSMALL, ROOTVSMALL, ROOTVSMALL);
892  bb.max() += point(ROOTVSMALL, ROOTVSMALL, ROOTVSMALL);
893 
894  labelList allEdges(identity(edges().size()));
895 
896  edgeTree_.reset
897  (
899  (
901  (
902  false, // cachebb
903  edges(), // edges
904  points(), // points
905  allEdges // selected edges
906  ),
907  bb, // bb
908  8, // maxLevel
909  10, // leafsize
910  3.0 // duplicity
911  )
912  );
913  }
914 
915  return *edgeTree_;
916 }
917 
918 
921 {
922  if (edgeTreesByType_.size() == 0)
923  {
924  edgeTreesByType_.setSize(nEdgeTypes);
925 
926  Random rndGen(872141);
927 
928  // Slightly extended bb. Slightly off-centred just so on symmetric
929  // geometry there are less face/edge aligned items.
930  treeBoundBox bb
931  (
932  treeBoundBox(points()).extend(rndGen, 1e-4)
933  );
934 
935  bb.min() -= point(ROOTVSMALL, ROOTVSMALL, ROOTVSMALL);
936  bb.max() += point(ROOTVSMALL, ROOTVSMALL, ROOTVSMALL);
937 
938  labelListList sliceEdges(nEdgeTypes);
939 
940  // External edges
941  sliceEdges[0] =
942  identity((internalStart_ - externalStart_), externalStart_);
943 
944  // Internal edges
945  sliceEdges[1] = identity((flatStart_ - internalStart_), internalStart_);
946 
947  // Flat edges
948  sliceEdges[2] = identity((openStart_ - flatStart_), flatStart_);
949 
950  // Open edges
951  sliceEdges[3] = identity((multipleStart_ - openStart_), openStart_);
952 
953  // Multiple edges
954  sliceEdges[4] =
955  identity((edges().size() - multipleStart_), multipleStart_);
956 
957  forAll(edgeTreesByType_, i)
958  {
959  edgeTreesByType_.set
960  (
961  i,
963  (
965  (
966  false, // cachebb
967  edges(), // edges
968  points(), // points
969  sliceEdges[i] // selected edges
970  ),
971  bb, // bb
972  8, // maxLevel
973  10, // leafsize
974  3.0 // duplicity
975  )
976  );
977  }
978  }
979 
980  return edgeTreesByType_;
981 }
982 
983 
985 {
987 
988  concaveStart_ = mesh.concaveStart_;
989  mixedStart_ = mesh.mixedStart_;
990  nonFeatureStart_ = mesh.nonFeatureStart_;
991  internalStart_ = mesh.internalStart_;
992  flatStart_ = mesh.flatStart_;
993  openStart_ = mesh.openStart_;
994  multipleStart_ = mesh.multipleStart_;
995  normals_.transfer(mesh.normals_);
996  normalVolumeTypes_.transfer(mesh.normalVolumeTypes_);
997  edgeDirections_.transfer(mesh.edgeDirections_);
998  normalDirections_.transfer(mesh.normalDirections_);
999  edgeNormals_.transfer(mesh.edgeNormals_);
1000  featurePointNormals_.transfer(mesh.featurePointNormals_);
1001  featurePointEdges_.transfer(mesh.featurePointEdges_);
1002  regionEdges_.transfer(mesh.regionEdges_);
1003  pointTree_ = std::move(mesh.pointTree_);
1004  edgeTree_ = std::move(mesh.edgeTree_);
1005  edgeTreesByType_.transfer(mesh.edgeTreesByType_);
1006 
1007  mesh.clear();
1008 }
1009 
1010 
1012 {
1013  edgeMesh::clear();
1014  concaveStart_ = 0;
1015  mixedStart_ = 0;
1016  nonFeatureStart_ = 0;
1017  internalStart_ = 0;
1018  flatStart_ = 0;
1019  openStart_ = 0;
1020  multipleStart_ = 0;
1021  normals_.clear();
1022  normalVolumeTypes_.clear();
1023  edgeDirections_.clear();
1024  normalDirections_.clear();
1025  edgeNormals_.clear();
1026  featurePointNormals_.clear();
1027  featurePointEdges_.clear();
1028  regionEdges_.clear();
1029  pointTree_.clear();
1030  edgeTree_.clear();
1031  edgeTreesByType_.clear();
1032 }
1033 
1034 
1036 {
1037  // Points
1038  // ~~~~~~
1039 
1040  // From current points into combined points
1041  labelList reversePointMap(points().size());
1042  labelList reverseFemPointMap(fem.points().size());
1043 
1044  label newPointi = 0;
1045  for (label i = 0; i < concaveStart(); i++)
1046  {
1047  reversePointMap[i] = newPointi++;
1048  }
1049  for (label i = 0; i < fem.concaveStart(); i++)
1050  {
1051  reverseFemPointMap[i] = newPointi++;
1052  }
1053 
1054  // Concave
1055  label newConcaveStart = newPointi;
1056  for (label i = concaveStart(); i < mixedStart(); i++)
1057  {
1058  reversePointMap[i] = newPointi++;
1059  }
1060  for (label i = fem.concaveStart(); i < fem.mixedStart(); i++)
1061  {
1062  reverseFemPointMap[i] = newPointi++;
1063  }
1064 
1065  // Mixed
1066  label newMixedStart = newPointi;
1067  for (label i = mixedStart(); i < nonFeatureStart(); i++)
1068  {
1069  reversePointMap[i] = newPointi++;
1070  }
1071  for (label i = fem.mixedStart(); i < fem.nonFeatureStart(); i++)
1072  {
1073  reverseFemPointMap[i] = newPointi++;
1074  }
1075 
1076  // Non-feature
1077  label newNonFeatureStart = newPointi;
1078  for (label i = nonFeatureStart(); i < points().size(); i++)
1079  {
1080  reversePointMap[i] = newPointi++;
1081  }
1082  for (label i = fem.nonFeatureStart(); i < fem.points().size(); i++)
1083  {
1084  reverseFemPointMap[i] = newPointi++;
1085  }
1086 
1087  pointField newPoints(newPointi);
1088  newPoints.rmap(points(), reversePointMap);
1089  newPoints.rmap(fem.points(), reverseFemPointMap);
1090 
1091 
1092  // Edges
1093  // ~~~~~
1094 
1095  // From current edges into combined edges
1096  labelList reverseEdgeMap(edges().size());
1097  labelList reverseFemEdgeMap(fem.edges().size());
1098 
1099  // External
1100  label newEdgeI = 0;
1101  for (label i = 0; i < internalStart(); i++)
1102  {
1103  reverseEdgeMap[i] = newEdgeI++;
1104  }
1105  for (label i = 0; i < fem.internalStart(); i++)
1106  {
1107  reverseFemEdgeMap[i] = newEdgeI++;
1108  }
1109 
1110  // Internal
1111  label newInternalStart = newEdgeI;
1112  for (label i = internalStart(); i < flatStart(); i++)
1113  {
1114  reverseEdgeMap[i] = newEdgeI++;
1115  }
1116  for (label i = fem.internalStart(); i < fem.flatStart(); i++)
1117  {
1118  reverseFemEdgeMap[i] = newEdgeI++;
1119  }
1120 
1121  // Flat
1122  label newFlatStart = newEdgeI;
1123  for (label i = flatStart(); i < openStart(); i++)
1124  {
1125  reverseEdgeMap[i] = newEdgeI++;
1126  }
1127  for (label i = fem.flatStart(); i < fem.openStart(); i++)
1128  {
1129  reverseFemEdgeMap[i] = newEdgeI++;
1130  }
1131 
1132  // Open
1133  label newOpenStart = newEdgeI;
1134  for (label i = openStart(); i < multipleStart(); i++)
1135  {
1136  reverseEdgeMap[i] = newEdgeI++;
1137  }
1138  for (label i = fem.openStart(); i < fem.multipleStart(); i++)
1139  {
1140  reverseFemEdgeMap[i] = newEdgeI++;
1141  }
1142 
1143  // Multiple
1144  label newMultipleStart = newEdgeI;
1145  for (label i = multipleStart(); i < edges().size(); i++)
1146  {
1147  reverseEdgeMap[i] = newEdgeI++;
1148  }
1149  for (label i = fem.multipleStart(); i < fem.edges().size(); i++)
1150  {
1151  reverseFemEdgeMap[i] = newEdgeI++;
1152  }
1153 
1154  edgeList newEdges(newEdgeI);
1155  forAll(edges(), i)
1156  {
1157  const edge& e = edges()[i];
1158  newEdges[reverseEdgeMap[i]] = edge
1159  (
1160  reversePointMap[e[0]],
1161  reversePointMap[e[1]]
1162  );
1163  }
1164  forAll(fem.edges(), i)
1165  {
1166  const edge& e = fem.edges()[i];
1167  newEdges[reverseFemEdgeMap[i]] = edge
1168  (
1169  reverseFemPointMap[e[0]],
1170  reverseFemPointMap[e[1]]
1171  );
1172  }
1173 
1174  pointField newEdgeDirections
1175  (
1176  edgeDirections().size()
1177  + fem.edgeDirections().size()
1178  );
1179  newEdgeDirections.rmap(edgeDirections(), reverseEdgeMap);
1180  newEdgeDirections.rmap(fem.edgeDirections(), reverseFemEdgeMap);
1181 
1182 
1183  // Normals
1184  // ~~~~~~~
1185 
1186  // Combine normals
1187  DynamicField<point> newNormals
1188  (
1189  normals().size()
1190  + fem.normals().size()
1191  );
1192  newNormals.append(normals());
1193  newNormals.append(fem.normals());
1194 
1195 
1196  // Combine and re-index into newNormals
1197  labelListList newEdgeNormals
1198  (
1199  edgeNormals().size()
1200  + fem.edgeNormals().size()
1201  );
1202 
1204  (
1205  newEdgeNormals,
1206  SubList<label>(reverseEdgeMap, edgeNormals().size())
1207  ) = edgeNormals();
1209  (
1210  newEdgeNormals,
1211  SubList<label>(reverseFemEdgeMap, fem.edgeNormals().size())
1212  ) = fem.edgeNormals();
1213 
1214  forAll(fem.edgeNormals(), i)
1215  {
1216  const label mapI = reverseFemEdgeMap[i];
1217  labelList& en = newEdgeNormals[mapI];
1218  forAll(en, j)
1219  {
1220  en[j] += normals().size();
1221  }
1222  }
1223 
1224 
1225  // Combine and re-index into newFeaturePointNormals
1226  labelListList newFeaturePointNormals
1227  (
1228  featurePointNormals().size()
1229  + fem.featurePointNormals().size()
1230  );
1231 
1232  // Note: featurePointNormals only go up to nonFeatureStart
1234  (
1235  newFeaturePointNormals,
1236  SubList<label>(reversePointMap, featurePointNormals().size())
1237  ) = featurePointNormals();
1239  (
1240  newFeaturePointNormals,
1241  SubList<label>(reverseFemPointMap, fem.featurePointNormals().size())
1242  ) = fem.featurePointNormals();
1243 
1244  forAll(fem.featurePointNormals(), i)
1245  {
1246  const label mapI = reverseFemPointMap[i];
1247  labelList& fn = newFeaturePointNormals[mapI];
1248  forAll(fn, j)
1249  {
1250  fn[j] += normals().size();
1251  }
1252  }
1253 
1254 
1255  // Combine regionEdges
1256  DynamicList<label> newRegionEdges
1257  (
1258  regionEdges().size()
1259  + fem.regionEdges().size()
1260  );
1261  forAll(regionEdges(), i)
1262  {
1263  newRegionEdges.append(reverseEdgeMap[regionEdges()[i]]);
1264  }
1265  forAll(fem.regionEdges(), i)
1266  {
1267  newRegionEdges.append(reverseFemEdgeMap[fem.regionEdges()[i]]);
1268  }
1269 
1270 
1271  // Assign
1272  // ~~~~~~
1273 
1274  // Transfer
1275  concaveStart_ = newConcaveStart;
1276  mixedStart_ = newMixedStart;
1277  nonFeatureStart_ = newNonFeatureStart;
1278 
1279  // Reset points and edges
1280  {
1281  edgeMesh newmesh(std::move(newPoints), std::move(newEdges));
1282  edgeMesh::transfer(newmesh);
1283  }
1284 
1285  // Transfer
1286  internalStart_ = newInternalStart;
1287  flatStart_ = newFlatStart;
1288  openStart_ = newOpenStart;
1289  multipleStart_ = newMultipleStart;
1290 
1291  edgeDirections_.transfer(newEdgeDirections);
1292 
1293  normals_.transfer(newNormals);
1294  edgeNormals_.transfer(newEdgeNormals);
1295  featurePointNormals_.transfer(newFeaturePointNormals);
1296 
1297  regionEdges_.transfer(newRegionEdges);
1298 
1299  pointTree_.clear();
1300  edgeTree_.clear();
1301  edgeTreesByType_.clear();
1302 }
1303 
1304 
1306 {
1307  // Points
1308  // ~~~~~~
1309 
1310  // From current points into new points
1311  labelList reversePointMap(identity(points().size()));
1312 
1313  // Flip convex and concave points
1314 
1315  label newPointi = 0;
1316  // Concave points become convex
1317  for (label i = concaveStart(); i < mixedStart(); i++)
1318  {
1319  reversePointMap[i] = newPointi++;
1320  }
1321  // Convex points become concave
1322  label newConcaveStart = newPointi;
1323  for (label i = 0; i < concaveStart(); i++)
1324  {
1325  reversePointMap[i] = newPointi++;
1326  }
1327 
1328 
1329  // Edges
1330  // ~~~~~~
1331 
1332  // From current edges into new edges
1333  labelList reverseEdgeMap(identity(edges().size()));
1334 
1335  // Flip external and internal edges
1336 
1337  label newEdgeI = 0;
1338  // Internal become external
1339  for (label i = internalStart(); i < flatStart(); i++)
1340  {
1341  reverseEdgeMap[i] = newEdgeI++;
1342  }
1343  // External become internal
1344  label newInternalStart = newEdgeI;
1345  for (label i = 0; i < internalStart(); i++)
1346  {
1347  reverseEdgeMap[i] = newEdgeI++;
1348  }
1349 
1350 
1351  pointField newPoints(points().size());
1352  newPoints.rmap(points(), reversePointMap);
1353 
1354  edgeList newEdges(edges().size());
1355  forAll(edges(), i)
1356  {
1357  const edge& e = edges()[i];
1358  newEdges[reverseEdgeMap[i]] = edge
1359  (
1360  reversePointMap[e[0]],
1361  reversePointMap[e[1]]
1362  );
1363  }
1364 
1365 
1366  // Normals are flipped
1367  // ~~~~~~~~~~~~~~~~~~~
1368 
1369  pointField newEdgeDirections(edges().size());
1370  newEdgeDirections.rmap(-1.0*edgeDirections(), reverseEdgeMap);
1371 
1372  pointField newNormals(-1.0*normals());
1373 
1374  labelListList newEdgeNormals(edgeNormals().size());
1375  UIndirectList<labelList>(newEdgeNormals, reverseEdgeMap) = edgeNormals();
1376 
1377  labelListList newFeaturePointNormals(featurePointNormals().size());
1378 
1379  // Note: featurePointNormals only go up to nonFeatureStart
1381  (
1382  newFeaturePointNormals,
1383  SubList<label>(reversePointMap, featurePointNormals().size())
1384  ) = featurePointNormals();
1385 
1386  labelList newRegionEdges(regionEdges().size());
1387  forAll(regionEdges(), i)
1388  {
1389  newRegionEdges[i] = reverseEdgeMap[regionEdges()[i]];
1390  }
1391 
1392  // Transfer
1393  concaveStart_ = newConcaveStart;
1394 
1395  // Reset points and edges
1396  {
1397  edgeMesh newmesh(std::move(newPoints), std::move(newEdges));
1398  edgeMesh::transfer(newmesh);
1399  }
1400 
1401  // Transfer
1402  internalStart_ = newInternalStart;
1403 
1404  edgeDirections_.transfer(newEdgeDirections);
1405  normals_.transfer(newNormals);
1406  edgeNormals_.transfer(newEdgeNormals);
1407  featurePointNormals_.transfer(newFeaturePointNormals);
1408  regionEdges_.transfer(newRegionEdges);
1409 
1410  pointTree_.clear();
1411  edgeTree_.clear();
1412  edgeTreesByType_.clear();
1413 }
1414 
1415 
1418  const pointField& subPoints,
1419  const edgeList& subEdges,
1420  const labelList& pointMap,
1421  const labelList& edgeMap
1422 )
1423 {
1424  // Determine slicing for subEdges
1425  label subIntStart = edgeMap.size();
1426  label subFlatStart = edgeMap.size();
1427  label subOpenStart = edgeMap.size();
1428  label subMultipleStart = edgeMap.size();
1429 
1430  forAll(edgeMap, subEdgeI)
1431  {
1432  label edgeI = edgeMap[subEdgeI];
1433  if (edgeI >= internalStart() && subIntStart == edgeMap.size())
1434  {
1435  subIntStart = subEdgeI;
1436  }
1437  if (edgeI >= flatStart() && subFlatStart == edgeMap.size())
1438  {
1439  subFlatStart = subEdgeI;
1440  }
1441  if (edgeI >= openStart() && subOpenStart == edgeMap.size())
1442  {
1443  subOpenStart = subEdgeI;
1444  }
1445  if (edgeI >= multipleStart() && subMultipleStart == edgeMap.size())
1446  {
1447  subMultipleStart = subEdgeI;
1448  }
1449  }
1450 
1451 
1452  // Determine slicing for subPoints
1453 
1454  label subConcaveStart = pointMap.size();
1455  label subMixedStart = pointMap.size();
1456  label subNonFeatStart = pointMap.size();
1457 
1458  forAll(pointMap, subPointI)
1459  {
1460  label pointI = pointMap[subPointI];
1461  if (pointI >= concaveStart() && subConcaveStart == pointMap.size())
1462  {
1463  subConcaveStart = subPointI;
1464  }
1465  if (pointI >= mixedStart() && subMixedStart == pointMap.size())
1466  {
1467  subMixedStart = subPointI;
1468  }
1469  if
1470  (
1471  pointI >= nonFeatureStart()
1472  && subNonFeatStart == pointMap.size()
1473  )
1474  {
1475  subNonFeatStart = subPointI;
1476  }
1477  }
1478 
1479 
1480 
1481  // Compact region edges
1482  labelList subRegionEdges;
1483  {
1484  bitSet isRegionEdge(edges().size(), regionEdges());
1485 
1486  DynamicList<label> newRegionEdges(regionEdges().size());
1487  forAll(edgeMap, subEdgeI)
1488  {
1489  if (isRegionEdge.test(edgeMap[subEdgeI]))
1490  {
1491  newRegionEdges.append(subEdgeI);
1492  }
1493  }
1494  subRegionEdges.transfer(newRegionEdges);
1495  }
1496 
1497 
1498  labelListList subFeaturePointEdges;
1499  if (featurePointEdges().size())
1500  {
1501  subFeaturePointEdges.setSize(subNonFeatStart);
1502  for (label subPointI = 0; subPointI < subNonFeatStart; subPointI++)
1503  {
1504  label pointI = pointMap[subPointI];
1505  const labelList& pEdges = featurePointEdges()[pointI];
1506 
1507  labelList& subPEdges = subFeaturePointEdges[subPointI];
1508  subPEdges.setSize(pEdges.size());
1509 
1510  if (pEdges.size())
1511  {
1512  forAll(pEdges, i)
1513  {
1514  subPEdges[i] = edgeMap[pEdges[i]];
1515  }
1516  }
1517  }
1518  }
1519 
1520 
1521  vectorField subEdgeDirections(edgeDirections(), edgeMap);
1522 
1523  // Find used normals
1524  labelList reverseNormalMap(normals().size(), -1);
1525  DynamicList<label> normalMap(normals().size());
1526 
1527  {
1528  bitSet isSubNormal(normals().size());
1529  for (label subPointI = 0; subPointI < subNonFeatStart; subPointI++)
1530  {
1531  label pointI = pointMap[subPointI];
1532  const labelList& pNormals = featurePointNormals()[pointI];
1533 
1534  isSubNormal.set(pNormals);
1535  }
1536  forAll(edgeMap, subEdgeI)
1537  {
1538  label edgeI = edgeMap[subEdgeI];
1539  const labelList& eNormals = edgeNormals()[edgeI];
1540 
1541  isSubNormal.set(eNormals);
1542  }
1543 
1544  forAll(isSubNormal, normalI)
1545  {
1546  if (isSubNormal.test(normalI))
1547  {
1548  label subNormalI = normalMap.size();
1549  reverseNormalMap[normalI] = subNormalI;
1550  normalMap.append(subNormalI);
1551  }
1552  }
1553  }
1554 
1555 
1556  // Use compaction map on data referencing normals
1557  labelListList subNormalDirections;
1558 
1559  if (normalDirections().size())
1560  {
1561  subNormalDirections.setSize(edgeMap.size());
1562 
1563  forAll(edgeMap, subEdgeI)
1564  {
1565  label edgeI = edgeMap[subEdgeI];
1566  const labelList& eNormals = normalDirections()[edgeI];
1567 
1568  labelList& subNormals = subNormalDirections[subEdgeI];
1569  subNormals.setSize(eNormals.size());
1570  forAll(eNormals, i)
1571  {
1572  if (eNormals[i] >= 0)
1573  {
1574  subNormals[i] = reverseNormalMap[eNormals[i]];
1575  }
1576  else
1577  {
1578  subNormals[i] = -1;
1579  }
1580  }
1581  }
1582  }
1583 
1584  labelListList subEdgeNormals(edgeMap.size());
1585  forAll(edgeMap, subEdgeI)
1586  {
1587  label edgeI = edgeMap[subEdgeI];
1588  const labelList& eNormals = edgeNormals()[edgeI];
1589  labelList& subNormals = subEdgeNormals[subEdgeI];
1590 
1591  subNormals = labelUIndList(reverseNormalMap, eNormals);
1592  }
1593 
1594  labelListList subPointNormals(pointMap.size());
1595  for (label subPointI = 0; subPointI < subNonFeatStart; subPointI++)
1596  {
1597  label pointI = pointMap[subPointI];
1598  const labelList& pNormals = featurePointNormals()[pointI];
1599  labelList& subNormals = subPointNormals[subPointI];
1600 
1601  subNormals = labelUIndList(reverseNormalMap, pNormals);
1602  }
1603 
1604  // Use compaction map to compact normal data
1605  vectorField subNormals(normals(), normalMap);
1606 
1607  List<extendedEdgeMesh::sideVolumeType> subNormalVolumeTypes;
1608  if (normalVolumeTypes().size())
1609  {
1610  subNormalVolumeTypes =
1612  (
1613  normalVolumeTypes(),
1614  normalMap
1615  );
1616  }
1617 
1618  extendedEdgeMesh subMesh
1619  (
1620  subPoints,
1621  subEdges,
1622 
1623  // Feature points slices
1624  subConcaveStart,
1625  subMixedStart,
1626  subNonFeatStart,
1627 
1628  // Feature edges slices
1629  subIntStart,
1630  subFlatStart,
1631  subOpenStart,
1632  subMultipleStart,
1633 
1634  // All normals
1635  subNormals,
1636  subNormalVolumeTypes,
1637 
1638  // Per edge edge vector
1639  subEdgeDirections,
1640 
1641  // Per edge list of normal indices
1642  subNormalDirections,
1643  // Per edge list of normal indices
1644  subEdgeNormals,
1645 
1646  // Per point list of normal indices
1647  subPointNormals,
1648  subFeaturePointEdges,
1649  subRegionEdges
1650  );
1651 
1652  transfer(subMesh);
1653 }
1654 
1655 
1658  const searchableSurface& surf,
1659  const volumeType volType,
1660  labelList& pointMap,
1661  labelList& edgeMap
1662 )
1663 {
1664  // Cut edges with the other surfaces
1665 
1666  labelList allPointMap; // from all to original point
1667  labelList allEdgeMap; // from all to original edge
1668 
1669  labelList pointsFromEdge; // list of new points created by cutting
1670  labelList oldEdge; // for each of these points the original edge
1671  labelList surfTri; // for each of these points the surface triangle
1672  cut
1673  (
1674  surf,
1675  allPointMap,
1676  allEdgeMap,
1677  pointsFromEdge,
1678  oldEdge,
1679  surfTri
1680  );
1681 
1682  const label nOldPoints = points().size();
1683 
1684  // Remove outside edges and compact
1685 
1686  labelList subPointMap; // sub to old points
1687  labelList subEdgeMap; // sub to old edges
1688  select(surf, volType, subPointMap, subEdgeMap);
1689 
1690  // Update overall point maps
1691  pointMap = labelUIndList(allPointMap, subPointMap);
1692  edgeMap = labelUIndList(allEdgeMap, subEdgeMap);
1693 
1694  // Extract current point and edge status
1695  List<edgeStatus> edgeStat(edges().size());
1696  List<pointStatus> pointStat(points().size());
1697  forAll(edgeStat, edgeI)
1698  {
1699  edgeStat[edgeI] = getEdgeStatus(edgeI);
1700  }
1701  forAll(pointStat, pointI)
1702  {
1703  pointStat[pointI] = getPointStatus(pointI);
1704  }
1705 
1706  // Re-classify exposed points (from cutting)
1707  labelList oldPointToIndex(nOldPoints, -1);
1708  forAll(pointsFromEdge, i)
1709  {
1710  oldPointToIndex[pointsFromEdge[i]] = i;
1711  }
1712  forAll(subPointMap, pointI)
1713  {
1714  label oldPointI = subPointMap[pointI];
1715  label index = oldPointToIndex[oldPointI];
1716  if (index != -1)
1717  {
1718  pointStat[pointI] = classifyFeaturePoint(pointI);
1719  }
1720  }
1721 
1722  // Reset based on new point and edge status
1723  labelList sortedToOriginalPoint;
1724  labelList sortedToOriginalEdge;
1725  setFromStatus
1726  (
1727  pointStat,
1728  edgeStat,
1729  sortedToOriginalPoint,
1730  sortedToOriginalEdge
1731  );
1732 
1733  // Update the overall pointMap, edgeMap
1734  pointMap = labelUIndList(pointMap, sortedToOriginalPoint)();
1735  edgeMap = labelUIndList(edgeMap, sortedToOriginalEdge)();
1736 }
1737 
1738 
1741  const List<extendedEdgeMesh::pointStatus>& pointStat,
1742  const List<extendedEdgeMesh::edgeStatus>& edgeStat,
1743  labelList& sortedToOriginalPoint,
1744  labelList& sortedToOriginalEdge
1745 )
1746 {
1747  // Use pointStatus and edgeStatus to determine new ordering
1748  label pointConcaveStart;
1749  label pointMixedStart;
1750  label pointNonFeatStart;
1751 
1752  label edgeInternalStart;
1753  label edgeFlatStart;
1754  label edgeOpenStart;
1755  label edgeMultipleStart;
1756  sortedOrder
1757  (
1758  pointStat,
1759  edgeStat,
1760  sortedToOriginalPoint,
1761  sortedToOriginalEdge,
1762 
1763  pointConcaveStart,
1764  pointMixedStart,
1765  pointNonFeatStart,
1766 
1767  edgeInternalStart,
1768  edgeFlatStart,
1769  edgeOpenStart,
1770  edgeMultipleStart
1771  );
1772 
1773 
1774  // Order points and edges
1775  labelList reversePointMap(points().size(), -1);
1776  forAll(sortedToOriginalPoint, sortedI)
1777  {
1778  reversePointMap[sortedToOriginalPoint[sortedI]] = sortedI;
1779  }
1780 
1781  edgeList sortedEdges(UIndirectList<edge>(edges(), sortedToOriginalEdge)());
1782  forAll(sortedEdges, sortedI)
1783  {
1784  inplaceRenumber(reversePointMap, sortedEdges[sortedI]);
1785  }
1786 
1787  // Update local data
1788  autoMap
1789  (
1790  pointField(points(), sortedToOriginalPoint),
1791  sortedEdges,
1792  sortedToOriginalPoint,
1793  sortedToOriginalEdge
1794  );
1795 
1796  // Reset the slice starts
1797  concaveStart_ = pointConcaveStart;
1798  mixedStart_ = pointMixedStart;
1799  nonFeatureStart_ = pointNonFeatStart;
1800  internalStart_ = edgeInternalStart;
1801  flatStart_ = edgeFlatStart;
1802  openStart_ = edgeOpenStart;
1803  multipleStart_ = edgeMultipleStart;
1804 }
1805 
1806 
1809  const scalar mergeDist,
1810  labelList& pointMap,
1811  labelList& edgeMap
1812 )
1813 {
1814  const label nOldPoints = points().size();
1815 
1816  // Detect and merge collocated feature points
1817  labelList oldToMerged;
1818  label nNewPoints = ::Foam::mergePoints
1819  (
1820  points(),
1821  SMALL,
1822  false,
1823  oldToMerged
1824  );
1825 
1826  pointMap.setSize(nNewPoints);
1827  pointMap = -1;
1828  forAll(oldToMerged, oldI)
1829  {
1830  label newI = oldToMerged[oldI];
1831  if (pointMap[newI] == -1)
1832  {
1833  pointMap[newI] = oldI;
1834  }
1835  }
1836 
1837  // Renumber edges
1838  edgeList newEdges(edges().size());
1839  forAll(edges(), edgeI)
1840  {
1841  const edge& oldE = edges()[edgeI];
1842  newEdges[edgeI] = edge(oldToMerged[oldE[0]], oldToMerged[oldE[1]]);
1843  }
1844 
1845  // Shuffle basic information (reorders point data)
1846  autoMap
1847  (
1848  pointField(points(), pointMap),
1849  newEdges,
1850  pointMap,
1851  identity(newEdges.size())
1852  );
1853 
1854  // Re-classify the merged points
1855  List<edgeStatus> edgeStat(edges().size());
1856  forAll(edgeStat, edgeI)
1857  {
1858  edgeStat[edgeI] = getEdgeStatus(edgeI);
1859  }
1860 
1861  List<pointStatus> pointStat(points().size());
1862  forAll(pointStat, pointI)
1863  {
1864  pointStat[pointI] = getPointStatus(pointI);
1865  }
1866 
1867  // Re-classify merged points
1868  labelList nPoints(nNewPoints, Zero);
1869  forAll(oldToMerged, oldPointI)
1870  {
1871  nPoints[oldToMerged[oldPointI]]++;
1872  }
1873 
1874  forAll(nPoints, pointI)
1875  {
1876  if (nPoints[pointI] != 1)
1877  {
1878  pointStat[pointI] = classifyFeaturePoint(pointI);
1879  }
1880  }
1881 
1882  labelList sortedToOriginalPoint;
1883  setFromStatus
1884  (
1885  pointStat,
1886  edgeStat,
1887  sortedToOriginalPoint,
1888  edgeMap // point merging above did not affect edge order
1889  );
1890  pointMap = labelUIndList(pointMap, sortedToOriginalPoint)();
1891 
1892  return nNewPoints != nOldPoints;
1893 }
1894 
1895 
1897 {
1898  Info<< nl << "Writing extendedEdgeMesh components to " << prefix
1899  << endl;
1900 
1901  edgeMesh::write(prefix + "_edgeMesh.obj");
1902 
1903  {
1904  OBJstream convexFtPtStr(prefix + "_convexFeaturePts.obj");
1905  Info<< "Writing " << concaveStart_
1906  << " convex feature points to " << convexFtPtStr.name() << endl;
1907 
1908  for(label i = 0; i < concaveStart_; i++)
1909  {
1910  convexFtPtStr.write(points()[i]);
1911  }
1912  }
1913 
1914  {
1915  OBJstream concaveFtPtStr(prefix + "_concaveFeaturePts.obj");
1916  Info<< "Writing " << mixedStart_-concaveStart_
1917  << " concave feature points to "
1918  << concaveFtPtStr.name() << endl;
1919 
1920  for(label i = concaveStart_; i < mixedStart_; i++)
1921  {
1922  concaveFtPtStr.write(points()[i]);
1923  }
1924  }
1925 
1926  {
1927  OBJstream mixedFtPtStr(prefix + "_mixedFeaturePts.obj");
1928  Info<< "Writing " << nonFeatureStart_-mixedStart_
1929  << " mixed feature points to " << mixedFtPtStr.name() << endl;
1930 
1931  for(label i = mixedStart_; i < nonFeatureStart_; i++)
1932  {
1933  mixedFtPtStr.write(points()[i]);
1934  }
1935  }
1936 
1937  {
1938  OBJstream mixedFtPtStructureStr(prefix+"_mixedFeaturePtsStructure.obj");
1939  Info<< "Writing "
1940  << nonFeatureStart_-mixedStart_
1941  << " mixed feature point structure to "
1942  << mixedFtPtStructureStr.name() << endl;
1943 
1944  for(label i = mixedStart_; i < nonFeatureStart_; i++)
1945  {
1946  const labelList& ptEds = pointEdges()[i];
1947 
1948  forAll(ptEds, j)
1949  {
1950  const edge& e = edges()[ptEds[j]];
1951  mixedFtPtStructureStr.write
1952  (
1953  linePointRef(points()[e[0]],
1954  points()[e[1]])
1955  );
1956  }
1957  }
1958  }
1959 
1960  {
1961  OBJstream externalStr(prefix + "_externalEdges.obj");
1962  Info<< "Writing " << internalStart_-externalStart_
1963  << " external edges to " << externalStr.name() << endl;
1964 
1965  for (label i = externalStart_; i < internalStart_; i++)
1966  {
1967  const edge& e = edges()[i];
1968  externalStr.write(linePointRef(points()[e[0]], points()[e[1]]));
1969  }
1970  }
1971 
1972  {
1973  OBJstream internalStr(prefix + "_internalEdges.obj");
1974  Info<< "Writing " << flatStart_-internalStart_
1975  << " internal edges to " << internalStr.name() << endl;
1976 
1977  for (label i = internalStart_; i < flatStart_; i++)
1978  {
1979  const edge& e = edges()[i];
1980  internalStr.write(linePointRef(points()[e[0]], points()[e[1]]));
1981  }
1982  }
1983 
1984  {
1985  OBJstream flatStr(prefix + "_flatEdges.obj");
1986  Info<< "Writing " << openStart_-flatStart_
1987  << " flat edges to " << flatStr.name() << endl;
1988 
1989  for (label i = flatStart_; i < openStart_; i++)
1990  {
1991  const edge& e = edges()[i];
1992  flatStr.write(linePointRef(points()[e[0]], points()[e[1]]));
1993  }
1994  }
1995 
1996  {
1997  OBJstream openStr(prefix + "_openEdges.obj");
1998  Info<< "Writing " << multipleStart_-openStart_
1999  << " open edges to " << openStr.name() << endl;
2000 
2001  for (label i = openStart_; i < multipleStart_; i++)
2002  {
2003  const edge& e = edges()[i];
2004  openStr.write(linePointRef(points()[e[0]], points()[e[1]]));
2005  }
2006  }
2007 
2008  {
2009  OBJstream multipleStr(prefix + "_multipleEdges.obj");
2010  Info<< "Writing " << edges().size()-multipleStart_
2011  << " multiple edges to " << multipleStr.name() << endl;
2012 
2013  for (label i = multipleStart_; i < edges().size(); i++)
2014  {
2015  const edge& e = edges()[i];
2016  multipleStr.write(linePointRef(points()[e[0]], points()[e[1]]));
2017  }
2018  }
2019 
2020  {
2021  OBJstream regionStr(prefix + "_regionEdges.obj");
2022  Info<< "Writing " << regionEdges_.size()
2023  << " region edges to " << regionStr.name() << endl;
2024 
2025  forAll(regionEdges_, i)
2026  {
2027  const edge& e = edges()[regionEdges_[i]];
2028  regionStr.write(linePointRef(points()[e[0]], points()[e[1]]));
2029  }
2030  }
2031 
2032  {
2033  OBJstream edgeDirsStr(prefix + "_edgeDirections.obj");
2034  Info<< "Writing " << edgeDirections_.size()
2035  << " edge directions to " << edgeDirsStr.name() << endl;
2036 
2037  forAll(edgeDirections_, i)
2038  {
2039  const vector& eVec = edgeDirections_[i];
2040  const edge& e = edges()[i];
2041 
2042  edgeDirsStr.write
2043  (
2044  linePointRef(points()[e.start()], eVec + points()[e.start()])
2045  );
2046  }
2047  }
2048 }
2049 
2050 
2052 {
2054 
2055  os << indent << "point classification :" << nl;
2056  os << incrIndent;
2057  os << indent << "convex feature points : "
2058  << setw(8) << concaveStart_-convexStart_
2059  //<< setw(8) << convexStart_
2060  << nl;
2061  os << indent << "concave feature points : "
2062  << setw(8) << mixedStart_-concaveStart_
2063  //<< setw(8) << concaveStart_
2064  << nl;
2065  os << indent << "mixed feature points : "
2066  << setw(8) << nonFeatureStart_-mixedStart_
2067  //<< setw(8) << mixedStart_
2068  << nl;
2069  os << indent << "other (non-feature) points : "
2070  << setw(8) << points().size()-nonFeatureStart_
2071  //<< setw(8) << nonFeatureStart_
2072  << nl;
2073  os << decrIndent;
2074 
2075  os << indent << "edge classification :" << nl;
2076  os << incrIndent;
2077  os << indent << "external (convex angle) edges : "
2078  << setw(8) << internalStart_-externalStart_
2079  //<< setw(8) << externalStart_
2080  << nl;
2081  os << indent << "internal (concave angle) edges : "
2082  << setw(8) << flatStart_-internalStart_
2083  //<< setw(8) << internalStart_
2084  << nl;
2085  os << indent << "flat region edges : "
2086  << setw(8) << openStart_-flatStart_
2087  //<< setw(8) << flatStart_
2088  << nl;
2089  os << indent << "open edges : "
2090  << setw(8) << multipleStart_-openStart_
2091  //<< setw(8) << openStart_
2092  << nl;
2093  os << indent << "multiply connected edges : "
2094  << setw(8) << edges().size()-multipleStart_
2095  //<< setw(8) << multipleStart_
2096  << nl;
2097  os << decrIndent;
2098 }
2099 
2100 
2104  const List<vector>& norms,
2105  const labelList& edNorms,
2106  const vector& fC0tofC1
2107 )
2108 {
2109  label nEdNorms = edNorms.size();
2110 
2111  if (nEdNorms == 1)
2112  {
2113  return OPEN;
2114  }
2115  else if (nEdNorms == 2)
2116  {
2117  const vector& n0(norms[edNorms[0]]);
2118  const vector& n1(norms[edNorms[1]]);
2119 
2120  if ((n0 & n1) > cosNormalAngleTol_)
2121  {
2122  return FLAT;
2123  }
2124  else if ((fC0tofC1 & n0) > 0.0)
2125  {
2126  return INTERNAL;
2127  }
2128  else
2129  {
2130  return EXTERNAL;
2131  }
2132  }
2133  else if (nEdNorms > 2)
2134  {
2135  return MULTIPLE;
2136  }
2137 
2138  // There is a problem - the edge has no normals
2139  return NONE;
2140 }
2141 
2142 
2145  const List<extendedEdgeMesh::pointStatus>& pointStat,
2146  const List<extendedEdgeMesh::edgeStatus>& edgeStat,
2147  labelList& sortedToOriginalPoint,
2148  labelList& sortedToOriginalEdge,
2149 
2150  label& pointConcaveStart,
2151  label& pointMixedStart,
2152  label& pointNonFeatStart,
2153 
2154  label& edgeInternalStart,
2155  label& edgeFlatStart,
2156  label& edgeOpenStart,
2157  label& edgeMultipleStart
2158 )
2159 {
2160  sortedToOriginalPoint.setSize(pointStat.size());
2161  sortedToOriginalPoint = -1;
2162 
2163  sortedToOriginalEdge.setSize(edgeStat.size());
2164  sortedToOriginalEdge = -1;
2165 
2166 
2167  // Order edges
2168  // ~~~~~~~~~~~
2169 
2170  label nConvex = 0;
2171  label nConcave = 0;
2172  label nMixed = 0;
2173  label nNonFeat = 0;
2174 
2175  forAll(pointStat, pointI)
2176  {
2177  switch (pointStat[pointI])
2178  {
2180  nConvex++;
2181  break;
2182 
2184  nConcave++;
2185  break;
2186 
2188  nMixed++;
2189  break;
2190 
2192  nNonFeat++;
2193  break;
2194 
2195  default:
2197  << "Problem" << exit(FatalError);
2198  break;
2199  }
2200  }
2201 
2202  label convexStart = 0;
2203  label concaveStart = nConvex;
2204  label mixedStart = concaveStart+nConcave;
2205  label nonFeatStart = mixedStart+nMixed;
2206 
2207 
2208  // Copy to parameters
2209  pointConcaveStart = concaveStart;
2210  pointMixedStart = mixedStart;
2211  pointNonFeatStart = nonFeatStart;
2212 
2213  forAll(pointStat, pointI)
2214  {
2215  switch (pointStat[pointI])
2216  {
2218  sortedToOriginalPoint[convexStart++] = pointI;
2219  break;
2220 
2222  sortedToOriginalPoint[concaveStart++] = pointI;
2223  break;
2224 
2226  sortedToOriginalPoint[mixedStart++] = pointI;
2227  break;
2228 
2230  sortedToOriginalPoint[nonFeatStart++] = pointI;
2231  break;
2232  }
2233  }
2234 
2235 
2236  // Order edges
2237  // ~~~~~~~~~~~
2238 
2239  label nExternal = 0;
2240  label nInternal = 0;
2241  label nFlat = 0;
2242  label nOpen = 0;
2243  label nMultiple = 0;
2244 
2245  forAll(edgeStat, edgeI)
2246  {
2247  switch (edgeStat[edgeI])
2248  {
2250  nExternal++;
2251  break;
2252 
2254  nInternal++;
2255  break;
2256 
2258  nFlat++;
2259  break;
2260 
2262  nOpen++;
2263  break;
2264 
2266  nMultiple++;
2267  break;
2268 
2270  default:
2272  << "Problem" << exit(FatalError);
2273  break;
2274  }
2275  }
2276 
2277  label externalStart = 0;
2278  label internalStart = nExternal;
2279  label flatStart = internalStart + nInternal;
2280  label openStart = flatStart + nFlat;
2281  label multipleStart = openStart + nOpen;
2282 
2283 
2284  // Copy to parameters
2285  edgeInternalStart = internalStart;
2286  edgeFlatStart = flatStart;
2287  edgeOpenStart = openStart;
2288  edgeMultipleStart = multipleStart;
2289 
2290  forAll(edgeStat, edgeI)
2291  {
2292  switch (edgeStat[edgeI])
2293  {
2295  sortedToOriginalEdge[externalStart++] = edgeI;
2296  break;
2297 
2299  sortedToOriginalEdge[internalStart++] = edgeI;
2300  break;
2301 
2303  sortedToOriginalEdge[flatStart++] = edgeI;
2304  break;
2305 
2307  sortedToOriginalEdge[openStart++] = edgeI;
2308  break;
2309 
2311  sortedToOriginalEdge[multipleStart++] = edgeI;
2312  break;
2313 
2315  default:
2317  << "Problem" << exit(FatalError);
2318  break;
2319  }
2320  }
2321 }
2322 
2323 
2324 // * * * * * * * * * * * * * * * IOstream Operators * * * * * * * * * * * * //
2325 
2326 Foam::Istream& Foam::operator>>
2328  Istream& is,
2330 )
2331 {
2332  label type;
2333  is >> type;
2334 
2335  vt = static_cast<Foam::extendedEdgeMesh::sideVolumeType>(type);
2336 
2337  is.check(FUNCTION_NAME);
2338  return is;
2339 }
2340 
2341 
2342 Foam::Ostream& Foam::operator<<
2344  Ostream& os,
2346 )
2347 {
2348  os << static_cast<label>(vt);
2349 
2350  return os;
2351 }
2352 
2353 
2355 {
2356  //fileFormats::extendedEdgeMeshFormat::write(os, em.points_, em.edges_);
2357  os << "// points" << nl
2358  << em.points() << nl
2359  << "// edges" << nl
2360  << em.edges() << nl
2361  << "// concaveStart mixedStart nonFeatureStart" << nl
2362  << em.concaveStart_ << token::SPACE
2363  << em.mixedStart_ << token::SPACE
2364  << em.nonFeatureStart_ << nl
2365  << "// internalStart flatStart openStart multipleStart" << nl
2366  << em.internalStart_ << token::SPACE
2367  << em.flatStart_ << token::SPACE
2368  << em.openStart_ << token::SPACE
2369  << em.multipleStart_ << nl
2370  << "// normals" << nl
2371  << em.normals_ << nl
2372  << "// normal volume types" << nl
2373  << em.normalVolumeTypes_ << nl
2374  << "// normalDirections" << nl
2375  << em.normalDirections_ << nl
2376  << "// edgeNormals" << nl
2377  << em.edgeNormals_ << nl
2378  << "// featurePointNormals" << nl
2379  << em.featurePointNormals_ << nl
2380  << "// featurePointEdges" << nl
2381  << em.featurePointEdges_ << nl
2382  << "// regionEdges" << nl
2383  << em.regionEdges_
2384  << endl;
2385 
2386  os.check(FUNCTION_NAME);
2387  return os;
2388 }
2389 
2390 
2392 {
2393  //fileFormats::extendedEdgeMeshFormat::read(is, em.points_, em.edges_);
2394  is >> static_cast<edgeMesh&>(em)
2395  >> em.concaveStart_
2396  >> em.mixedStart_
2397  >> em.nonFeatureStart_
2398  >> em.internalStart_
2399  >> em.flatStart_
2400  >> em.openStart_
2401  >> em.multipleStart_
2402  >> em.normals_
2403  >> em.normalVolumeTypes_
2404  >> em.normalDirections_
2405  >> em.edgeNormals_
2406  >> em.featurePointNormals_
2407  >> em.featurePointEdges_
2408  >> em.regionEdges_;
2409 
2410  is.check(FUNCTION_NAME);
2411  return is;
2412 }
2413 
2414 
2415 // ************************************************************************* //
Foam::extendedEdgeMesh::NONE
Unclassified (consistency with surfaceFeatures)
Definition: extendedEdgeMesh.H:112
Foam::word::lessExt
word lessExt() const
Return word without extension (part before last .)
Definition: word.C:113
Foam::pointField
vectorField pointField
pointField is a vectorField.
Definition: pointFieldFwd.H:44
Foam::extendedEdgeMesh::regionEdges_
labelList regionEdges_
Feature edges which are on the boundary between regions.
Definition: extendedEdgeMesh.H:193
Foam::Random
Random number generator.
Definition: Random.H:59
Foam::extendedEdgeMesh::edgeStatus
edgeStatus
Definition: extendedEdgeMesh.H:105
Foam::searchableSurface::findLineAll
virtual void findLineAll(const pointField &start, const pointField &end, List< List< pointIndexHit >> &) const =0
Get all intersections in order from start to end.
Foam::extendedEdgeMesh::sortedOrder
static void sortedOrder(const List< extendedEdgeMesh::pointStatus > &pointStat, const List< extendedEdgeMesh::edgeStatus > &edgeStat, labelList &sortedToOriginalPoint, labelList &sortedToOriginalEdge, label &pointConcaveStart, label &pointMixedStart, label &pointNonFeatStart, label &edgeInternalStart, label &edgeFlatStart, label &edgeOpenStart, label &edgeMultipleStart)
Determine the ordering.
Definition: extendedEdgeMesh.C:2144
Foam::extendedEdgeMesh::featurePointNormals
const labelListList & featurePointNormals() const
Return the indices of the normals that are adjacent to the.
Definition: extendedEdgeMeshI.H:177
Foam::Enum
Enum is a wrapper around a list of names/values that represent particular enumeration (or int) values...
Definition: IOstreamOption.H:51
Foam::faceMap
Pair< int > faceMap(const label facePi, const face &faceP, const label faceNi, const face &faceN)
Definition: blockMeshMergeFast.C:94
Foam::PrimitivePatch::edgeFaces
const labelListList & edgeFaces() const
Return edge-face addressing.
Definition: PrimitivePatch.C:318
Foam::PointHit::hit
bool hit() const
Is there a hit.
Definition: PointHit.H:124
Foam::labelMax
constexpr label labelMax
Definition: label.H:65
Foam::word
A class for handling words, derived from Foam::string.
Definition: word.H:62
Foam::fileName
A class for handling file names.
Definition: fileName.H:69
Foam::bitSet
A bitSet stores bits (elements with only two states) in packed internal format and supports a variety...
Definition: bitSet.H:64
Foam::OBJstream
OFstream that keeps track of vertices.
Definition: OBJstream.H:56
searchableSurface.H
Foam::extendedEdgeMesh::allNearestFeatureEdges
void allNearestFeatureEdges(const point &sample, const scalar searchRadiusSqr, List< pointIndexHit > &info) const
Find all the feature edges within searchDistSqr of sample.
Definition: extendedEdgeMesh.C:782
Foam::OFstream::name
virtual const fileName & name() const
Read/write access to the name of the stream.
Definition: OSstream.H:91
Foam::PointHit< point >
Foam::Zero
static constexpr const zero Zero
Global zero.
Definition: zero.H:128
Foam::DynamicList< label >
Foam::extendedEdgeMesh::FLAT
Neither concave or convex, on a flat surface.
Definition: extendedEdgeMesh.H:109
Foam::extendedEdgeMesh::edgeTreesByType
const PtrList< indexedOctree< treeDataEdge > > & edgeTreesByType() const
Demand driven construction of octree for boundary edges by type.
Definition: extendedEdgeMesh.C:920
Foam::extendedEdgeMesh::canReadType
static bool canReadType(const word &ext, bool verbose=false)
Can we read this file format?
Definition: extendedEdgeMesh.C:117
Foam::SubList
A List obtained as a section of another List.
Definition: SubList.H:53
Foam::extendedEdgeMesh::concaveStart_
label concaveStart_
Index of the start of the concave feature points.
Definition: extendedEdgeMesh.H:146
surfaceFeatures.H
Foam::PointHit::rawPoint
const Point & rawPoint() const
Return point with no checking.
Definition: PointHit.H:162
Foam::treeBoundBox
Standard boundBox with extra functionality for use in octree.
Definition: treeBoundBox.H:87
Foam::read
bool read(const char *buf, int32_t &val)
Same as readInt32.
Definition: int32.H:108
Foam::extendedEdgeMesh::nearestFeatureEdgeByType
void nearestFeatureEdgeByType(const point &sample, const scalarField &searchDistSqr, List< pointIndexHit > &info) const
Find the nearest point on each type of feature edge.
Definition: extendedEdgeMesh.C:715
Foam::extendedEdgeMesh::mergePointsAndSort
bool mergePointsAndSort(const scalar mergeDist, labelList &pointMap, labelList &edgeMap)
Geometric merge points. Returns true if any points merged.
Definition: extendedEdgeMesh.C:1808
Foam::DynamicField::capacity
label capacity() const noexcept
Size of the underlying storage.
Definition: DynamicFieldI.H:226
Foam::edge
An edge is a list of two point labels. The functionality it provides supports the discretisation on a...
Definition: edge.H:63
Foam::extendedEdgeMesh::autoMap
void autoMap(const pointField &subPoints, const edgeList &subEdges, const labelList &pointMap, const labelList &edgeMap)
Update with derived geometry.
Definition: extendedEdgeMesh.C:1417
Foam::extendedEdgeMesh::regionEdges
const labelList & regionEdges() const
Return the feature edges which are on the boundary between.
Definition: extendedEdgeMeshI.H:218
Foam::extendedEdgeMesh::normals
const vectorField & normals() const
Return the normals of the surfaces adjacent to the feature edges.
Definition: extendedEdgeMeshI.H:90
Foam::bitSet::set
void set(const bitSet &bitset)
Set specified bits from another bitset.
Definition: bitSetI.H:563
Foam::extendedEdgeMesh::edgeTree
const indexedOctree< treeDataEdge > & edgeTree() const
Demand driven construction of octree for boundary edges.
Definition: extendedEdgeMesh.C:878
Foam::objectRegistry::clear
void clear()
Clear all entries from the registry.
Definition: objectRegistry.C:335
Foam::extendedEdgeMesh::NONFEATURE
Not a feature point.
Definition: extendedEdgeMesh.H:100
Foam::operator>>
Istream & operator>>(Istream &, directionInfo &)
Definition: directionInfo.C:228
Foam::endl
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:337
Foam::extendedEdgeMesh::multipleStart
label multipleStart() const
Return the index of the start of the multiply-connected feature.
Definition: extendedEdgeMeshI.H:78
Foam::extendedEdgeMesh::mixedStart_
label mixedStart_
Index of the start of the mixed type feature points.
Definition: extendedEdgeMesh.H:149
Foam::boundBox::max
const point & max() const
Maximum describing the bounding box.
Definition: boundBoxI.H:97
Foam::DynamicList::capacity
label capacity() const noexcept
Size of the underlying storage.
Definition: DynamicListI.H:224
Foam::word::ext
word ext() const
Return file name extension (part after last .)
Definition: word.C:126
triSurface.H
Foam::bitSet::test
bool test(const label pos) const
Test value at specified position, never auto-vivify entries.
Definition: bitSetI.H:512
Foam::HashSet< word >
Foam::OBJstream::write
virtual Ostream & write(const char c)
Write character.
Definition: OBJstream.C:79
Foam::incrIndent
Ostream & incrIndent(Ostream &os)
Increment the indent level.
Definition: Ostream.H:314
Foam::extendedEdgeMesh::normalVolumeTypes_
List< sideVolumeType > normalVolumeTypes_
Type per normal: which side of normal to mesh.
Definition: extendedEdgeMesh.H:171
Foam::inplaceRenumber
void inplaceRenumber(const labelUList &oldToNew, IntListType &input)
Inplace renumber the values (not the indices) of a list.
Definition: ListOpsTemplates.C:61
Foam::boundBox::min
const point & min() const
Minimum describing the bounding box.
Definition: boundBoxI.H:91
Foam::treeDataPoint
Holds (reference to) pointField. Encapsulation of data needed for octree searches....
Definition: treeDataPoint.H:62
forAll
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:290
Foam::extendedEdgeMesh::sideVolumeTypeNames_
static const Enum< sideVolumeType > sideVolumeTypeNames_
Definition: extendedEdgeMesh.H:126
Foam::extendedEdgeMesh::INTERNAL
"Concave" edge
Definition: extendedEdgeMesh.H:108
Foam::DynamicField
Dynamically sized Field.
Definition: DynamicField.H:51
nPoints
label nPoints
Definition: gmvOutputHeader.H:2
Foam::extendedEdgeMesh::edgeDirections
const vectorField & edgeDirections() const
Return the edgeDirection vectors.
Definition: extendedEdgeMeshI.H:103
Foam::edgeMesh::write
static void write(const fileName &name, const edgeMesh &mesh)
Write to file.
Definition: edgeMeshIO.C:88
Foam::extendedEdgeMesh::classifyEdge
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.
Definition: extendedEdgeMesh.C:2103
Foam::surfaceFeatures::featurePoints
const labelList & featurePoints() const
Return feature point list.
Definition: surfaceFeatures.H:250
Foam::extendedEdgeMesh::nonFeatureStart
label nonFeatureStart() const
Return the index of the start of the non-feature points.
Definition: extendedEdgeMeshI.H:48
Foam::extendedEdgeMesh::concaveStart
label concaveStart() const
Return the index of the start of the concave feature points.
Definition: extendedEdgeMeshI.H:36
Foam::PointIndexHit
This class describes the interaction of (usually) a face and a point. It carries the info of a succes...
Definition: PointIndexHit.H:55
Foam::extendedEdgeMesh::readTypes
static wordHashSet readTypes()
Definition: extendedEdgeMesh.C:103
Foam::label
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:62
Foam::volumeType
An enumeration wrapper for classification of a location as being inside/outside of a volume.
Definition: volumeType.H:60
Foam::Field< vector >
Foam::triSurface
Triangulated surface description with patch information.
Definition: triSurface.H:70
Foam::extendedEdgeMesh::~extendedEdgeMesh
~extendedEdgeMesh()
Destructor.
Definition: extendedEdgeMesh.C:631
Foam::Istream
An Istream is an abstract base class for all input systems (streams, files, token lists etc)....
Definition: Istream.H:61
Foam::Info
messageStream Info
Information stream (uses stdout - output is on the master only)
Foam::extendedEdgeMesh::MIXED
A point surrounded by both convex and concave edges.
Definition: extendedEdgeMesh.H:99
Foam::extendedEdgeMesh::setFromStatus
void setFromStatus(const List< extendedEdgeMesh::pointStatus > &pointStat, const List< extendedEdgeMesh::edgeStatus > &edgeStat, labelList &sortedToOriginalPoint, labelList &sortedToOriginalEdge)
Order according to point and edge status.
Definition: extendedEdgeMesh.C:1740
Foam::name
word name(const complex &c)
Return string representation of complex.
Definition: complex.C:76
Foam::extendedEdgeMesh::sideVolumeType
sideVolumeType
Normals point to the outside.
Definition: extendedEdgeMesh.H:118
Foam::DynamicList::append
DynamicList< T, SizeMin > & append(const T &val)
Append an element to the end of this list.
Definition: DynamicListI.H:472
Foam::searchableSurface
Base class of (analytical or triangulated) surface. Encapsulates all the search routines....
Definition: searchableSurface.H:69
Foam::edgeMesh::points
const pointField & points() const
Return points.
Definition: edgeMeshI.H:99
Foam::List::transfer
void transfer(List< T > &list)
Definition: List.C:436
Foam::surfaceFeatures
Holds feature edges/points of surface.
Definition: surfaceFeatures.H:73
Foam::edgeMesh::writeStats
virtual void writeStats(Ostream &) const
Definition: edgeMeshIO.C:113
Foam::indexedOctree< Foam::treeDataPoint >
IOmanip.H
Istream and Ostream manipulators taking arguments.
Foam::treeDataEdge
Holds data for octree to work on an edges subset.
Definition: treeDataEdge.H:56
samples
scalarField samples(nIntervals, Zero)
Foam::PtrList
A list of pointers to objects of type <T>, with allocation/deallocation management of the pointers....
Definition: List.H:65
Foam::extendedEdgeMesh::multipleStart_
label multipleStart_
Index of the start of the multiply-connected feature edges.
Definition: extendedEdgeMesh.H:164
Foam::extendedEdgeMesh::clear
virtual void clear()
Clear all storage.
Definition: extendedEdgeMesh.C:1011
Foam::extendedEdgeMesh::cosNormalAngleTol_
static scalar cosNormalAngleTol_
Angular closeness tolerance for treating normals as the same.
Definition: extendedEdgeMesh.H:129
extendedEdgeMesh.H
Foam::surfaceFeatures::featureEdges
const labelList & featureEdges() const
Return feature edge list.
Definition: surfaceFeatures.H:256
Foam::extendedEdgeMesh::nearestFeaturePoint
void nearestFeaturePoint(const point &sample, scalar searchDistSqr, pointIndexHit &info) const
Find nearest surface edge for the sample point.
Definition: extendedEdgeMesh.C:664
Foam::extendedEdgeMesh::nPointTypes
static label nPointTypes
Number of possible point types (i.e. number of slices)
Definition: extendedEdgeMesh.H:252
Foam::extendedEdgeMesh::select
void select(const searchableSurface &surf, const volumeType volType, labelList &pMap, labelList &eMap)
Remove outside/inside edges. volType denotes which side to keep.
Definition: extendedEdgeMesh.C:302
cut
Patchify triangles based on orientation w.r.t other (triangulated or triangulatable) surfaces.
Foam::edgeMesh::edges
const edgeList & edges() const
Return edges.
Definition: edgeMeshI.H:105
Foam::extendedEdgeMesh::pointStatusNames_
static const Enum< pointStatus > pointStatusNames_
Definition: extendedEdgeMesh.H:103
newPointi
label newPointi
Definition: readKivaGrid.H:496
Foam::extendedEdgeMesh::externalStart_
static label externalStart_
Index of the start of the external feature edges - static as 0.
Definition: extendedEdgeMesh.H:140
Foam::Field::rmap
void rmap(const UList< Type > &mapF, const labelUList &mapAddressing)
1 to 1 reverse-map from the given field
Definition: Field.C:489
Foam::IOstream::check
virtual bool check(const char *operation) const
Check IOstream status for given operation.
Definition: IOstream.C:51
Foam::FatalError
error FatalError
Foam::extendedEdgeMesh::internalStart
label internalStart() const
Return the index of the start of the internal feature edges.
Definition: extendedEdgeMeshI.H:60
Foam::extendedEdgeMesh::edgeNormals
const labelListList & edgeNormals() const
Return the indices of the normals that are adjacent to the.
Definition: extendedEdgeMeshI.H:146
mesh
dynamicFvMesh & mesh
Definition: createDynamicFvMesh.H:6
stdFoam::end
constexpr auto end(C &c) -> decltype(c.end())
Return iterator to the end of the container c.
Definition: stdFoam.H:115
Foam::extendedEdgeMesh::MULTIPLE
Multiply connected (connected to more than two faces)
Definition: extendedEdgeMesh.H:111
Foam::fileName::ext
word ext() const
Return file name extension (part after last .)
Definition: fileNameI.H:228
Foam::extendedEdgeMesh::edgeNormals_
labelListList edgeNormals_
Indices of the normals that are adjacent to the feature edges.
Definition: extendedEdgeMesh.H:182
Foam::extendedEdgeMesh::CONVEX
Fully convex point (w.r.t normals)
Definition: extendedEdgeMesh.H:97
Foam
Namespace for OpenFOAM.
Definition: atmBoundaryLayer.C:33
Foam::extendedEdgeMesh::pointStatus
pointStatus
Definition: extendedEdgeMesh.H:95
Foam::decrIndent
Ostream & decrIndent(Ostream &os)
Decrement the indent level.
Definition: Ostream.H:321
Foam::setw
Omanip< int > setw(const int i)
Definition: IOmanip.H:199
Foam::indent
Ostream & indent(Ostream &os)
Indent stream.
Definition: Ostream.H:307
Foam::extendedEdgeMesh::mixedStart
label mixedStart() const
Return the index of the start of the mixed type feature points.
Definition: extendedEdgeMeshI.H:42
Foam::degToRad
constexpr scalar degToRad(const scalar deg) noexcept
Conversion from degrees to radians.
Definition: unitConversion.H:48
Foam::HashTable::transfer
void transfer(HashTable< T, Key, Hash > &rhs)
Transfer contents into this table.
Definition: HashTable.C:671
Foam::mergePoints
label mergePoints(const PointList &points, const scalar mergeTol, const bool verbose, labelList &pointMap, typename PointList::const_reference origin=PointList::value_type::zero)
Sorts and merges points. All points closer than/equal mergeTol get merged.
Foam::extendedEdgeMesh::edgeStatusNames_
static const Enum< edgeStatus > edgeStatusNames_
Definition: extendedEdgeMesh.H:115
Random.H
Foam::edgeMesh::clear
virtual void clear()
Clear all storage.
Definition: edgeMesh.C:115
Foam::extendedEdgeMesh::normals_
vectorField normals_
Normals of the features, to be referred to by index by both feature.
Definition: extendedEdgeMesh.H:168
Foam::exit
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:130
Foam::DynamicList::setCapacity
void setCapacity(const label nElem)
Alter the size of the underlying storage.
Definition: DynamicListI.H:232
Foam::extendedEdgeMesh::transfer
void transfer(extendedEdgeMesh &mesh)
Transfer the contents of the argument and annul the argument.
Definition: extendedEdgeMesh.C:984
Foam::surfaceFeatures::surface
const triSurface & surface() const
Definition: surfaceFeatures.H:244
Foam::New
tmp< DimensionedField< TypeR, GeoMesh > > New(const tmp< DimensionedField< TypeR, GeoMesh >> &tdf1, const word &name, const dimensionSet &dimensions)
Global function forwards to reuseTmpDimensionedField::New.
Definition: DimensionedFieldReuseFunctions.H:105
Foam::extendedEdgeMesh::internalStart_
label internalStart_
Index of the start of the internal feature edges.
Definition: extendedEdgeMesh.H:155
Foam::extendedEdgeMesh::convexStart_
static label convexStart_
Index of the start of the convex feature points - static as 0.
Definition: extendedEdgeMesh.H:137
Foam::extendedEdgeMesh::normalDirections_
labelListList normalDirections_
Starting directions for the edges.
Definition: extendedEdgeMesh.H:179
Foam::extendedEdgeMesh::openStart
label openStart() const
Return the index of the start of the open feature edges.
Definition: extendedEdgeMeshI.H:72
Time.H
Foam::extendedEdgeMesh
Description of feature edges and points.
Definition: extendedEdgeMesh.H:86
Foam::linePointRef
line< point, const point & > linePointRef
Line using referred points.
Definition: linePointRef.H:47
Foam::extendedEdgeMesh::pointTree
const indexedOctree< treeDataPoint > & pointTree() const
Demand driven construction of octree for feature points.
Definition: extendedEdgeMesh.C:838
FatalErrorInFunction
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:355
DynamicField.H
Foam::extendedEdgeMesh::extendedEdgeMesh
extendedEdgeMesh()
Construct null.
Definition: extendedEdgeMesh.C:381
Foam::nl
constexpr char nl
Definition: Ostream.H:372
Foam::extendedEdgeMesh::OPEN
Only connected to a single face.
Definition: extendedEdgeMesh.H:110
Foam::extendedEdgeMesh::nEdgeTypes
static label nEdgeTypes
Number of possible feature edge types (i.e. number of slices)
Definition: extendedEdgeMesh.H:255
Foam::extendedEdgeMesh::add
void add(const extendedEdgeMesh &fem)
Add extendedEdgeMesh. No filtering of duplicates.
Definition: extendedEdgeMesh.C:1035
Foam::Vector< scalar >
Foam::extendedEdgeMesh::trim
void trim(const searchableSurface &surf, const volumeType volType, labelList &pointMap, labelList &edgeMap)
Trim to surface. Keep volType side. Return map from current back.
Definition: extendedEdgeMesh.C:1657
Foam::List< label >
Foam::extendedEdgeMesh::writeStats
virtual void writeStats(Ostream &os) const
Dump some information.
Definition: extendedEdgeMesh.C:2051
Foam::extendedEdgeMesh::EXTERNAL
"Convex" edge
Definition: extendedEdgeMesh.H:107
Foam::start
label ListType::const_reference const label start
Definition: ListOps.H:408
Foam::type
fileName::Type type(const fileName &name, const bool followLink=true)
Return the file type: DIRECTORY or FILE, normally following symbolic links.
Definition: MSwindows.C:590
Foam::token::SPACE
Space [isspace].
Definition: token.H:112
Foam::extendedEdgeMesh::canWriteType
static bool canWriteType(const word &ext, bool verbose=false)
Can we write this file format type?
Definition: extendedEdgeMesh.C:129
Foam::UList< label >
points
const pointField & points
Definition: gmvOutputHeader.H:1
Foam::constant::electromagnetic::e
const dimensionedScalar e
Elementary charge.
Definition: createFields.H:11
Foam::identity
labelList identity(const label len, label start=0)
Create identity map of the given length with (map[i] == i)
Definition: labelList.C:38
Foam::extendedEdgeMesh::flipNormals
void flipNormals()
Flip normals. All concave become convex, all internal external.
Definition: extendedEdgeMesh.C:1305
Foam::extendedEdgeMesh::nearestFeatureEdge
void nearestFeatureEdge(const point &sample, scalar searchDistSqr, pointIndexHit &info) const
Find nearest surface edge for the sample point.
Definition: extendedEdgeMesh.C:679
Foam::volumeType::INSIDE
A location inside the volume.
Definition: volumeType.H:68
FUNCTION_NAME
#define FUNCTION_NAME
Definition: messageStream.H:261
Foam::extendedEdgeMesh::classifyFeaturePoint
pointStatus classifyFeaturePoint(label ptI) const
Classify the type of feature point. Requires valid stored member.
Definition: extendedEdgeMesh.C:156
Foam::extendedEdgeMesh::cut
void cut(const searchableSurface &, labelList &pMap, labelList &eMap, labelList &pointsFromEdge, labelList &oldEdge, labelList &surfTri)
Cut edges with surface. Return map from cut points&edges back.
Definition: extendedEdgeMesh.C:200
Foam::surfaceFeatures::nRegionEdges
label nRegionEdges() const
Return number of region edges.
Definition: surfaceFeatures.H:274
Foam::wordHashSet
HashSet< word > wordHashSet
A HashSet with word keys.
Definition: HashSet.H:412
Foam::extendedEdgeMesh::featurePointEdges_
labelListList featurePointEdges_
Indices of feature edges attached to feature points. The edges are.
Definition: extendedEdgeMesh.H:190
rndGen
Random rndGen
Definition: createFields.H:23
Foam::UIndirectList
A List with indirect addressing.
Definition: fvMatrix.H:109
Foam::DynamicField::setCapacity
void setCapacity(const label nElem)
Alter the size of the underlying storage.
Definition: DynamicFieldI.H:234
Foam::extendedEdgeMesh::writeTypes
static wordHashSet writeTypes()
Definition: extendedEdgeMesh.C:109
Foam::extendedEdgeMesh::flatStart_
label flatStart_
Index of the start of the flat feature edges.
Definition: extendedEdgeMesh.H:158
Foam::DelaunayMeshTools::allPoints
tmp< pointField > allPoints(const Triangulation &t)
Extract all points in vertex-index order.
Foam::sortedOrder
labelList sortedOrder(const UList< T > &input)
Return the (stable) sort order for the list.
Foam::Ostream
An Ostream is an abstract base class for all output systems (streams, files, token lists,...
Definition: Ostream.H:56
Foam::one::minus
A class representing the concept of -1.
Definition: one.H:103
Foam::extendedEdgeMesh::nonFeatureStart_
label nonFeatureStart_
Index of the start of the non-feature points.
Definition: extendedEdgeMesh.H:152
Foam::extendedEdgeMesh::read
bool read(const fileName &name, const word &ext)
Read from file. Chooses reader based on explicit extension.
Definition: extendedEdgeMesh.C:652
Foam::point
vector point
Point is a vector.
Definition: point.H:43
Foam::List::setSize
void setSize(const label newSize)
Alias for resize(const label)
Definition: ListI.H:146
Foam::extendedEdgeMesh::writeObj
void writeObj(const fileName &prefix) const
Write all components of the extendedEdgeMesh as obj files.
Definition: extendedEdgeMesh.C:1896
Foam::extendedEdgeMesh::allNearestFeaturePoints
void allNearestFeaturePoints(const point &sample, scalar searchRadiusSqr, List< pointIndexHit > &info) const
Find all the feature points within searchDistSqr of sample.
Definition: extendedEdgeMesh.C:751
Foam::DynamicField::append
DynamicField< T, SizeMin > & append(const T &val)
Append an element at the end of the list.
Definition: DynamicFieldI.H:475
Foam::extendedEdgeMesh::openStart_
label openStart_
Index of the start of the open feature edges.
Definition: extendedEdgeMesh.H:161
triSurfaceMesh.H
Foam::defineTypeNameAndDebug
defineTypeNameAndDebug(combustionModel, 0)
Foam::edgeMesh
Mesh data needed to do the Finite Area discretisation.
Definition: edgeFaMesh.H:52
edgeMeshFormatsCore.H
Foam::edgeMesh::transfer
void transfer(edgeMesh &mesh)
Transfer the contents of the argument and annul the argument.
Definition: edgeMesh.C:123
Foam::operator<<
Ostream & operator<<(Ostream &, const boundaryPatch &)
Definition: boundaryPatch.C:102
OBJstream.H
Foam::extendedEdgeMesh::flatStart
label flatStart() const
Return the index of the start of the flat feature edges.
Definition: extendedEdgeMeshI.H:66
Foam::extendedEdgeMesh::featurePointNormals_
labelListList featurePointNormals_
Indices of the normals that are adjacent to the feature points.
Definition: extendedEdgeMesh.H:186
Foam::volumeType::OUTSIDE
A location outside the volume.
Definition: volumeType.H:69
Foam::searchableSurface::getVolumeType
virtual void getVolumeType(const pointField &, List< volumeType > &) const =0
Determine type (inside/outside) for point.
Foam::extendedEdgeMesh::canRead
static bool canRead(const fileName &name, bool verbose=false)
Can we read this file format?
Definition: extendedEdgeMesh.C:141
Foam::PrimitivePatch
A list of faces which address into the list of points.
Definition: PrimitivePatch.H:90
Foam::extendedEdgeMesh::CONCAVE
Fully concave point.
Definition: extendedEdgeMesh.H:98
Foam::labelUIndList
UIndirectList< label > labelUIndList
UIndirectList of labels.
Definition: UIndirectList.H:59
Foam::cos
dimensionedScalar cos(const dimensionedScalar &ds)
Definition: dimensionedScalar.C:265