surfaceFeatures.H
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-2016 OpenFOAM Foundation
9  Copyright (C) 2017 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 Class
28  Foam::surfaceFeatures
29 
30 Description
31  Holds feature edges/points of surface.
32 
33  Feature edges are stored in one list and sorted:
34  0 .. externalStart_-1 : region edges
35  externalStart_ .. internalStart_-1 : external edges
36  internalStart_ .. size-1 : internal edges
37 
38 
39  NOTE: angle is included angle, not feature angle and is in degrees.
40  The included angle is the smallest angle between two planes. For coplanar
41  faces it is 180, for straight angles it is 90. To pick up straight edges
42  only use included angle of 91 degrees
43 
44 
45 SourceFiles
46  surfaceFeatures.C
47 
48 \*---------------------------------------------------------------------------*/
49 
50 #ifndef surfaceFeatures_H
51 #define surfaceFeatures_H
52 
53 #include "pointField.H"
54 #include "Map.H"
55 #include "HashSet.H"
56 #include "pointIndexHit.H"
57 #include "edgeList.H"
58 #include "typeInfo.H"
59 
60 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
61 
62 namespace Foam
63 {
64 
65 // Forward declaration of classes
66 class plane;
67 class triSurface;
68 class treeBoundBox;
69 
70 /*---------------------------------------------------------------------------*\
71  Class surfaceFeatures Declaration
72 \*---------------------------------------------------------------------------*/
73 
74 class surfaceFeatures
75 {
76 public:
77 
78  //- Edge status
79  enum edgeStatus
80  {
81  NONE,
82  REGION, //
84  INTERNAL
85  };
86 
87 
88 private:
89 
90  //- Label and scalar; used in path walking
91  class labelScalar
92  {
93  public:
94  label n_;
95  scalar len_;
96 
97  labelScalar(const label n, const scalar len)
98  :
99  n_(n),
100  len_(len)
101  {}
102  };
103 
104  // Static data
105 
106  //- Tolerance for determining whether two vectors are parallel
107  static const scalar parallelTolerance;
108 
109 
110  // Private data
111 
112  //- Reference to surface
113  const triSurface& surf_;
114 
115  //- Labels of points that are features
116  labelList featurePoints_;
117 
118  //- Labels of edges that are features
119  labelList featureEdges_;
120 
121  //- Start of external edges in featureEdges_
122  label externalStart_;
123 
124  //- Start of internal edges in featureEdges_
125  label internalStart_;
126 
127 
128  // Private Member Functions
129 
130  //- Return nearest point on edge (start..end). Also classify nearest:
131  // index=-1: nearest on mid of edge. index=0:nearest on edge.start()
132  // index=1: nearest on edge.end().
133  static pointIndexHit edgeNearest
134  (
135  const point& start,
136  const point& end,
137  const point& sample
138  );
139 
140 
141  //- Construct feature points where more than 2 feature edges meet
142  void calcFeatPoints
143  (
144  const List<edgeStatus>& edgeStat,
145  const scalar minCos
146  );
147 
148  //- Classify the angles of the feature edges
149  void classifyFeatureAngles
150  (
151  const labelListList& edgeFaces,
152  List<edgeStatus>& edgeStat,
153  const scalar minCos,
154  const bool geometricTestOnly
155  ) const;
156 
157  //- Choose next unset feature edge.
158  label nextFeatEdge
159  (
160  const List<edgeStatus>& edgeStat,
161  const labelList& featVisited,
162  const label unsetVal,
163  const label prevEdgeI,
164  const label vertI
165  ) const;
166 
167  //- Walk connected feature edges. Marks edges in featVisited.
168  labelScalar walkSegment
169  (
170  const bool mark,
171  const List<edgeStatus>& edgeStat,
172  const label startEdgeI,
173  const label startPointi,
174  const label currentFeatI,
175  labelList& featVisited
176  );
177 
178  //- Divide into multiple normal bins
179  // - set REGION if != 2 normals
180  // - set REGION if 2 normals that make feature angle
181  // - otherwise set NONE and set normals,bins
182  edgeStatus checkFlatRegionEdge
183  (
184  const scalar tol,
185  const scalar includedAngle,
186  const label edgeI
187  ) const;
188 
189 public:
190 
191  ClassName("surfaceFeatures");
192 
193  // Constructors
194 
195  //- Construct from surface
196  surfaceFeatures(const triSurface& surf);
197 
198  //- Construct from components
200  (
201  const triSurface& surf,
202  const labelList& featurePoints,
203  const labelList& featureEdges,
204  const label externalStart,
205  const label internalStart
206  );
207 
208  //- Construct from surface, angle and min cumulative length and/or
209  // number of elements. If geometric test only is true, then region
210  // information is ignored and features are only assigned based on the
211  // geometric criteria
213  (
214  const triSurface& surf,
215  const scalar includedAngle,
216  const scalar minLen = 0,
217  const label minElems = 0,
218  const bool geometricTestOnly = false
219  );
220 
221  //- Construct from dictionary
222  surfaceFeatures(const triSurface& surf, const dictionary& dict);
223 
224  //- Construct from file
225  surfaceFeatures(const triSurface& surf, const fileName& fName);
226 
227  //- Construct from pointField and edgeList (edgeMesh)
229  (
230  const triSurface& surf,
231  const pointField& points,
232  const edgeList& edges,
233  const scalar mergeTol = 1e-6,
234  const bool geometricTestOnly = false
235  );
236 
237  //- Construct as copy
238  surfaceFeatures(const surfaceFeatures& sf);
239 
240 
241  // Member Functions
242 
243  // Access
244 
245  inline const triSurface& surface() const
246  {
247  return surf_;
248  }
249 
250  //- Return feature point list
251  inline const labelList& featurePoints() const
252  {
253  return featurePoints_;
254  }
255 
256  //- Return feature edge list
257  inline const labelList& featureEdges() const
258  {
259  return featureEdges_;
260  }
261 
262  //- Start of external edges
263  inline label externalStart() const
264  {
265  return externalStart_;
266  }
267 
268  //- Start of internal edges
269  inline label internalStart() const
270  {
271  return internalStart_;
272  }
273 
274  //- Return number of region edges
275  inline label nRegionEdges() const
276  {
277  return externalStart_;
278  }
279 
280  //- Return number of external edges
281  inline label nExternalEdges() const
282  {
283  return internalStart_ - externalStart_;
284  }
285 
286  //- Return number of internal edges
287  inline label nInternalEdges() const
288  {
289  return featureEdges_.size() - internalStart_;
290  }
291 
292  //- Helper function: select a subset of featureEdges_
294  (
295  const bool regionEdges,
296  const bool externalEdges,
297  const bool internalEdges
298  ) const;
299 
300 
301  // Edit
302 
303  //- Find feature edges using provided included angle
304  void findFeatures
305  (
306  const scalar includedAngle,
307  const bool geometricTestOnly
308  );
309 
310  //- Delete small sets of edges. Edges are stringed up and any
311  // string of length < minLen (or nElems < minElems) is deleted.
313  (
314  const scalar minLen,
315  const label minElems,
316  const scalar includedAngle
317  );
318 
319  //- Mark edge status inside box as 'NONE'
320  void excludeBox
321  (
322  List<edgeStatus>& edgeStat,
323  const treeBoundBox& bb
324  ) const;
325 
326  //- Mark edge status outside box as 'NONE'
327  void subsetBox
328  (
329  List<edgeStatus>& edgeStat,
330  const treeBoundBox& bb
331  ) const;
332 
333  //- Mark edge status as 'NONE' for edges inside/outside box.
334  void deleteBox
335  (
336  List<edgeStatus>& edgeStat,
337  const treeBoundBox& bb,
338  const bool removeInside
339  ) const;
340 
341  //- If edge does not intersect the plane, mark as 'NONE'
342  void subsetPlane
343  (
344  List<edgeStatus>& edgeStat,
345  const plane& cutPlane
346  ) const;
347 
348  //- Mark edges with a single connected face as 'NONE'
349  void excludeOpen(List<edgeStatus>& edgeStat) const;
350 
351  //- Divide into multiple normal bins
352  // - set REGION if != 2 normals
353  // - set REGION if 2 normals that make feature angle
354  // - otherwise set NONE and set normals,bins
355  void checkFlatRegionEdge
356  (
357  List<edgeStatus>& edgeStat,
358  const scalar tol,
359  const scalar includedAngle
360  ) const;
361 
362 
363  //- From member feature edges to status per edge.
364  List<edgeStatus> toStatus() const;
365 
366  //- Set from status per edge
367  void setFromStatus
368  (
369  const List<edgeStatus>& edgeStat,
370  const scalar includedAngle
371  );
372 
373 
374  // Find
375 
376  //- Find nearest sample for selected surface points
377  // (usually the set of featurePoints). Return map from
378  // index in samples to surface point. Do not include
379  // points that are further than maxDist away (separate
380  // maxDist for every sample). Supply maxDistSqr.
382  (
383  const labelList& selectedPoints,
384  const pointField& samples,
385  const scalarField& maxDistSqr
386  ) const;
387 
388  //- Find nearest sample for regularly sampled points along
389  // the selected (surface) edges. Return map from sample
390  // to edge. maxDistSqr is distance squared below which
391  // gets snapped. Edge gets sampled at points
392  // sampleDist[sampleI] apart. (with a maximum of 10
393  // samples per edge)
395  (
396  const labelList& selectedEdges,
397  const pointField& samples,
398  const scalarField& sampleDist,
399  const scalarField& maxDistSqr,
400  const scalar minSampleDist = 0.1
401  ) const;
402 
403  //- Like nearestSamples but now gets nearest point on
404  // sample-edge instead of nearest sample-point itself.
405  // Return map from sample edge to feature edge.
407  (
408  const labelList& selectedEdges,
409  const edgeList& sampleEdges,
410  const labelList& selectedSampleEdges,
411  const pointField& samplePoints,
412  const scalarField& sampleDist,
413  const scalarField& maxDistSqr,
414  const scalar minSampleDist = 0.1
415  ) const;
416 
417 
418  //- Find nearest surface edge (out of selectedEdges) for
419  // each sample point.
420  // Sets:
421  // - edgeLabel : label of surface edge.
422  // - edgePoint : exact position of nearest point on edge.
423  // - edgeEndPoint : -1, 0, 1 depending on whether edgePoint is
424  // on inside/start/end of edge
425  void nearestSurfEdge
426  (
427  const labelList& selectedEdges,
428  const pointField& samples,
429  scalar searchSpanSqr, // search span
430  labelList& edgeLabel,
431  labelList& edgeEndPoint,
432  pointField& edgePoint
433  ) const;
434 
435  //- Find nearest surface edge (out of selectedEdges) for each
436  // sample edge.
437  // Sets:
438  // - edgeLabel : label of surface edge.
439  // - pointOnEdge : exact position of nearest point on edge.
440  // - pointOnFeature : exact position on sample edge.
441  void nearestSurfEdge
442  (
443  const labelList& selectedEdges,
444  const edgeList& sampleEdges,
445  const labelList& selectedSampleEdges,
446  const pointField& samplePoints,
447  const vector& searchSpan, // search span
448 
449  labelList& edgeLabel, // label of surface edge or -1
450  pointField& pointOnEdge, // point on above edge
451  pointField& pointOnFeature // point on sample edge
452  ) const;
453 
454  //- Find nearest feature edge to each surface edge. Uses the
455  // mid-point of the surface edges.
456  void nearestFeatEdge
457  (
458  const edgeList& edges,
459  const pointField& points,
460  scalar searchSpanSqr,
461  labelList& edgeLabel
462  ) const;
463 
464 
465  // Write
466 
467  //- Write as dictionary
468  void writeDict(Ostream& os) const;
469 
470  //- Write as dictionary to file
471  void write(const fileName& fName) const;
472 
473  //- Write to separate OBJ files (region, external, internal edges,
474  // feature points) for visualization
475  void writeObj(const fileName& prefix) const;
476 
477  //- Write some information
478  void writeStats(Ostream& os) const;
479 
480 
481 
482  // Member Operators
483 
484  void operator=(const surfaceFeatures& rhs);
485 
486 
487 };
488 
489 
490 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
491 
492 } // End namespace Foam
493 
494 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
495 
496 #endif
497 
498 // ************************************************************************* //
Foam::surfaceFeatures::subsetBox
void subsetBox(List< edgeStatus > &edgeStat, const treeBoundBox &bb) const
Mark edge status outside box as 'NONE'.
Definition: surfaceFeatures.C:1047
Foam::labelList
List< label > labelList
A List of labels.
Definition: List.H:67
Foam::pointField
vectorField pointField
pointField is a vectorField.
Definition: pointFieldFwd.H:44
Foam::surfaceFeatures::internalStart
label internalStart() const
Start of internal edges.
Definition: surfaceFeatures.H:268
Foam::surfaceFeatures::edgeStatus
edgeStatus
Edge status.
Definition: surfaceFeatures.H:78
pointIndexHit.H
Foam::surfaceFeatures::nearestFeatEdge
void nearestFeatEdge(const edgeList &edges, const pointField &points, scalar searchSpanSqr, labelList &edgeLabel) const
Find nearest feature edge to each surface edge. Uses the.
Definition: surfaceFeatures.C:1744
Foam::surfaceFeatures::writeDict
void writeDict(Ostream &os) const
Write as dictionary.
Definition: surfaceFeatures.C:1155
Foam::edgeList
List< edge > edgeList
A List of edges.
Definition: edgeList.H:63
Foam::surfaceFeatures::INTERNAL
"Concave" edge
Definition: surfaceFeatures.H:83
Foam::surfaceFeatures::nearestSamples
Map< label > nearestSamples(const labelList &selectedPoints, const pointField &samples, const scalarField &maxDistSqr) const
Find nearest sample for selected surface points.
Definition: surfaceFeatures.C:1240
Foam::fileName
A class for handling file names.
Definition: fileName.H:73
Foam::surfaceFeatures::selectFeatureEdges
labelList selectFeatureEdges(const bool regionEdges, const bool externalEdges, const bool internalEdges) const
Helper function: select a subset of featureEdges_.
Definition: surfaceFeatures.C:835
Foam::surfaceFeatures::toStatus
List< edgeStatus > toStatus() const
From member feature edges to status per edge.
Definition: surfaceFeatures.C:117
typeInfo.H
Foam::surfaceFeatures::nearestEdges
Map< pointIndexHit > nearestEdges(const labelList &selectedEdges, const edgeList &sampleEdges, const labelList &selectedSampleEdges, const pointField &samplePoints, const scalarField &sampleDist, const scalarField &maxDistSqr, const scalar minSampleDist=0.1) const
Like nearestSamples but now gets nearest point on.
Definition: surfaceFeatures.C:1457
Foam::surfaceFeatures::nExternalEdges
label nExternalEdges() const
Return number of external edges.
Definition: surfaceFeatures.H:280
Foam::treeBoundBox
Standard boundBox with extra functionality for use in octree.
Definition: treeBoundBox.H:86
Foam::Map< label >
Foam::surfaceFeatures::REGION
Definition: surfaceFeatures.H:81
Foam::surfaceFeatures::writeStats
void writeStats(Ostream &os) const
Write some information.
Definition: surfaceFeatures.C:1226
Foam::surfaceFeatures::operator=
void operator=(const surfaceFeatures &rhs)
Definition: surfaceFeatures.C:1806
Foam::plane
Geometric class that creates a 3D plane and can return the intersection point between a line and the ...
Definition: plane.H:89
Foam::surfaceFeatures::EXTERNAL
"Convex" edge
Definition: surfaceFeatures.H:82
Foam::surfaceFeatures::featurePoints
const labelList & featurePoints() const
Return feature point list.
Definition: surfaceFeatures.H:250
Map.H
n
label n
Definition: TABSMDCalcMethod2.H:31
Foam::surfaceFeatures::NONE
Not a classified feature edge.
Definition: surfaceFeatures.H:80
Foam::Field< vector >
Foam::triSurface
Triangulated surface description with patch information.
Definition: triSurface.H:76
Foam::surfaceFeatures
Holds feature edges/points of surface.
Definition: surfaceFeatures.H:73
Foam::surfaceFeatures::nearestSurfEdge
void nearestSurfEdge(const labelList &selectedEdges, const pointField &samples, scalar searchSpanSqr, labelList &edgeLabel, labelList &edgeEndPoint, pointField &edgePoint) const
Find nearest surface edge (out of selectedEdges) for.
Definition: surfaceFeatures.C:1608
samples
scalarField samples(nIntervals, Zero)
Foam::surfaceFeatures::featureEdges
const labelList & featureEdges() const
Return feature edge list.
Definition: surfaceFeatures.H:256
Foam::surfaceFeatures::ClassName
ClassName("surfaceFeatures")
Foam::surfaceFeatures::surfaceFeatures
surfaceFeatures(const triSurface &surf)
Construct from surface.
Definition: surfaceFeatures.C:651
HashSet.H
dict
dictionary dict
Definition: searchingEngine.H:14
edgeList.H
Foam::surfaceFeatures::writeObj
void writeObj(const fileName &prefix) const
Write to separate OBJ files (region, external, internal edges,.
Definition: surfaceFeatures.C:1174
Foam::surfaceFeatures::nInternalEdges
label nInternalEdges() const
Return number of internal edges.
Definition: surfaceFeatures.H:286
os
OBJstream os(runTime.globalPath()/outputName)
stdFoam::end
constexpr auto end(C &c) -> decltype(c.end())
Return iterator to the end of the container c.
Definition: stdFoam.H:121
Foam
Namespace for OpenFOAM.
Definition: atmBoundaryLayer.C:33
Foam::surfaceFeatures::setFromStatus
void setFromStatus(const List< edgeStatus > &edgeStat, const scalar includedAngle)
Set from status per edge.
Definition: surfaceFeatures.C:146
Foam::surfaceFeatures::trimFeatures
labelList trimFeatures(const scalar minLen, const label minElems, const scalar includedAngle)
Delete small sets of edges. Edges are stringed up and any.
Definition: surfaceFeatures.C:903
Foam::surfaceFeatures::surface
const triSurface & surface() const
Definition: surfaceFeatures.H:244
pointField.H
Foam::surfaceFeatures::excludeBox
void excludeBox(List< edgeStatus > &edgeStat, const treeBoundBox &bb) const
Mark edge status inside box as 'NONE'.
Definition: surfaceFeatures.C:1037
Foam::labelListList
List< labelList > labelListList
A List of labelList.
Definition: labelList.H:56
Foam::pointIndexHit
PointIndexHit< point > pointIndexHit
A PointIndexHit for 3D points.
Definition: pointIndexHit.H:46
Foam::Vector< scalar >
Foam::List< label >
points
const pointField & points
Definition: gmvOutputHeader.H:1
Foam::constant::electromagnetic::e
const dimensionedScalar e
Elementary charge.
Definition: createFields.H:11
Foam::surfaceFeatures::nRegionEdges
label nRegionEdges() const
Return number of region edges.
Definition: surfaceFeatures.H:274
Foam::surfaceFeatures::deleteBox
void deleteBox(List< edgeStatus > &edgeStat, const treeBoundBox &bb, const bool removeInside) const
Mark edge status as 'NONE' for edges inside/outside box.
Definition: surfaceFeatures.C:1057
Foam::surfaceFeatures::write
void write(const fileName &fName) const
Write as dictionary to file.
Definition: surfaceFeatures.C:1167
Foam::Ostream
An Ostream is an abstract base class for all output systems (streams, files, token lists,...
Definition: Ostream.H:56
Foam::surfaceFeatures::subsetPlane
void subsetPlane(List< edgeStatus > &edgeStat, const plane &cutPlane) const
If edge does not intersect the plane, mark as 'NONE'.
Definition: surfaceFeatures.C:1079
Foam::point
vector point
Point is a vector.
Definition: point.H:43
Foam::surfaceFeatures::findFeatures
void findFeatures(const scalar includedAngle, const bool geometricTestOnly)
Find feature edges using provided included angle.
Definition: surfaceFeatures.C:878
Foam::surfaceFeatures::excludeOpen
void excludeOpen(List< edgeStatus > &edgeStat) const
Mark edges with a single connected face as 'NONE'.
Definition: surfaceFeatures.C:1110
sample
Minimal example by using system/controlDict.functions:
Foam::surfaceFeatures::externalStart
label externalStart() const
Start of external edges.
Definition: surfaceFeatures.H:262