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
80  {
81  NONE,
82  REGION, //
83  EXTERNAL,
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 linePointRef& line,
136  const point& sample
137  );
138 
139 
140  //- Construct feature points where more than 2 feature edges meet
141  void calcFeatPoints
142  (
143  const List<edgeStatus>& edgeStat,
144  const scalar minCos
145  );
146 
147  //- Classify the angles of the feature edges
148  void classifyFeatureAngles
149  (
150  const labelListList& edgeFaces,
151  List<edgeStatus>& edgeStat,
152  const scalar minCos,
153  const bool geometricTestOnly
154  ) const;
155 
156  //- Choose next unset feature edge.
157  label nextFeatEdge
158  (
159  const List<edgeStatus>& edgeStat,
160  const labelList& featVisited,
161  const label unsetVal,
162  const label prevEdgeI,
163  const label vertI
164  ) const;
165 
166  //- Walk connected feature edges. Marks edges in featVisited.
167  labelScalar walkSegment
168  (
169  const bool mark,
170  const List<edgeStatus>& edgeStat,
171  const label startEdgeI,
172  const label startPointi,
173  const label currentFeatI,
174  labelList& featVisited
175  );
176 
177  //- Divide into multiple normal bins
178  // - set REGION if != 2 normals
179  // - set REGION if 2 normals that make feature angle
180  // - otherwise set NONE and set normals,bins
181  edgeStatus checkFlatRegionEdge
182  (
183  const scalar tol,
184  const scalar includedAngle,
185  const label edgeI
186  ) const;
187 
188 public:
189 
190  ClassName("surfaceFeatures");
191 
192  // Constructors
193 
194  //- Construct from surface
195  surfaceFeatures(const triSurface& surf);
196 
197  //- Construct from components
199  (
200  const triSurface& surf,
201  const labelList& featurePoints,
202  const labelList& featureEdges,
203  const label externalStart,
204  const label internalStart
205  );
206 
207  //- Construct from surface, angle and min cumulative length and/or
208  // number of elements. If geometric test only is true, then region
209  // information is ignored and features are only assigned based on the
210  // geometric criteria
212  (
213  const triSurface& surf,
214  const scalar includedAngle,
215  const scalar minLen = 0,
216  const label minElems = 0,
217  const bool geometricTestOnly = false
218  );
219 
220  //- Construct from dictionary
221  surfaceFeatures(const triSurface& surf, const dictionary& dict);
222 
223  //- Construct from file
224  surfaceFeatures(const triSurface& surf, const fileName& fName);
225 
226  //- Construct from pointField and edgeList (edgeMesh)
228  (
229  const triSurface& surf,
230  const pointField& points,
231  const edgeList& edges,
232  const scalar mergeTol = 1e-6,
233  const bool geometricTestOnly = false
234  );
235 
236  //- Construct as copy
237  surfaceFeatures(const surfaceFeatures& sf);
238 
239 
240  // Member Functions
241 
242  // Access
243 
244  inline const triSurface& surface() const
245  {
246  return surf_;
247  }
248 
249  //- Return feature point list
250  inline const labelList& featurePoints() const
251  {
252  return featurePoints_;
253  }
254 
255  //- Return feature edge list
256  inline const labelList& featureEdges() const
257  {
258  return featureEdges_;
259  }
260 
261  //- Start of external edges
262  inline label externalStart() const
263  {
264  return externalStart_;
265  }
266 
267  //- Start of internal edges
268  inline label internalStart() const
269  {
270  return internalStart_;
271  }
272 
273  //- Return number of region edges
274  inline label nRegionEdges() const
275  {
276  return externalStart_;
277  }
278 
279  //- Return number of external edges
280  inline label nExternalEdges() const
281  {
282  return internalStart_ - externalStart_;
283  }
285  //- Return number of internal edges
286  inline label nInternalEdges() const
287  {
288  return featureEdges_.size() - internalStart_;
289  }
290 
291  //- Helper function: select a subset of featureEdges_
293  (
294  const bool regionEdges,
295  const bool externalEdges,
296  const bool internalEdges
297  ) const;
298 
299 
300  // Edit
301 
302  //- Find feature edges using provided included angle
303  void findFeatures
304  (
305  const scalar includedAngle,
306  const bool geometricTestOnly
307  );
309  //- Delete small sets of edges. Edges are stringed up and any
310  // string of length < minLen (or nElems < minElems) is deleted.
312  (
313  const scalar minLen,
314  const label minElems,
315  const scalar includedAngle
316  );
317 
318  //- Mark edge status inside box as 'NONE'
319  void excludeBox
320  (
321  List<edgeStatus>& edgeStat,
322  const treeBoundBox& bb
323  ) const;
325  //- Mark edge status outside box as 'NONE'
326  void subsetBox
327  (
328  List<edgeStatus>& edgeStat,
329  const treeBoundBox& bb
330  ) const;
331 
332  //- Mark edge status as 'NONE' for edges inside/outside box.
333  void deleteBox
334  (
335  List<edgeStatus>& edgeStat,
336  const treeBoundBox& bb,
337  const bool removeInside
338  ) const;
339 
340  //- If edge does not intersect the plane, mark as 'NONE'
341  void subsetPlane
342  (
343  List<edgeStatus>& edgeStat,
344  const plane& cutPlane
345  ) const;
346 
347  //- Mark edges with a single connected face as 'NONE'
348  void excludeOpen(List<edgeStatus>& edgeStat) const;
349 
350  //- Divide into multiple normal bins
351  // - set REGION if != 2 normals
352  // - set REGION if 2 normals that make feature angle
353  // - otherwise set NONE and set normals,bins
354  void checkFlatRegionEdge
355  (
356  List<edgeStatus>& edgeStat,
357  const scalar tol,
358  const scalar includedAngle
359  ) const;
360 
361 
362  //- From member feature edges to status per edge.
363  List<edgeStatus> toStatus() const;
364 
365  //- Set from status per edge
366  void setFromStatus
367  (
368  const List<edgeStatus>& edgeStat,
369  const scalar includedAngle
370  );
371 
372 
373  // Find
374 
375  //- Find nearest sample for selected surface points
376  // (usually the set of featurePoints). Return map from
377  // index in samples to surface point. Do not include
378  // points that are further than maxDist away (separate
379  // maxDist for every sample). Supply maxDistSqr.
381  (
382  const labelList& selectedPoints,
383  const pointField& samples,
384  const scalarField& maxDistSqr
385  ) const;
386 
387  //- Find nearest sample for regularly sampled points along
388  // the selected (surface) edges. Return map from sample
389  // to edge. maxDistSqr is distance squared below which
390  // gets snapped. Edge gets sampled at points
391  // sampleDist[sampleI] apart. (with a maximum of 10
392  // samples per edge)
394  (
395  const labelList& selectedEdges,
396  const pointField& samples,
397  const scalarField& sampleDist,
398  const scalarField& maxDistSqr,
399  const scalar minSampleDist = 0.1
400  ) const;
401 
402  //- Like nearestSamples but now gets nearest point on
403  // sample-edge instead of nearest sample-point itself.
404  // Return map from sample edge to feature edge.
406  (
407  const labelList& selectedEdges,
408  const edgeList& sampleEdges,
409  const labelList& selectedSampleEdges,
410  const pointField& samplePoints,
411  const scalarField& sampleDist,
412  const scalarField& maxDistSqr,
413  const scalar minSampleDist = 0.1
414  ) const;
415 
416 
417  //- Find nearest surface edge (out of selectedEdges) for
418  // each sample point.
419  // Sets:
420  // - edgeLabel : label of surface edge.
421  // - edgePoint : exact position of nearest point on edge.
422  // - edgeEndPoint : -1, 0, 1 depending on whether edgePoint is
423  // on inside/start/end of edge
424  void nearestSurfEdge
425  (
426  const labelList& selectedEdges,
427  const pointField& samples,
428  scalar searchSpanSqr, // search span
429  labelList& edgeLabel,
430  labelList& edgeEndPoint,
431  pointField& edgePoint
432  ) const;
433 
434  //- Find nearest surface edge (out of selectedEdges) for each
435  // sample edge.
436  // Sets:
437  // - edgeLabel : label of surface edge.
438  // - pointOnEdge : exact position of nearest point on edge.
439  // - pointOnFeature : exact position on sample edge.
440  void nearestSurfEdge
441  (
442  const labelList& selectedEdges,
443  const edgeList& sampleEdges,
444  const labelList& selectedSampleEdges,
445  const pointField& samplePoints,
446  const vector& searchSpan, // search span
447 
448  labelList& edgeLabel, // label of surface edge or -1
449  pointField& pointOnEdge, // point on above edge
450  pointField& pointOnFeature // point on sample edge
451  ) const;
452 
453  //- Find nearest feature edge to each surface edge. Uses the
454  // mid-point of the surface edges.
455  void nearestFeatEdge
456  (
457  const edgeList& edges,
458  const pointField& points,
459  scalar searchSpanSqr,
460  labelList& edgeLabel
461  ) const;
462 
463 
464  // Write
465 
466  //- Write as dictionary
467  void writeDict(Ostream& os) const;
468 
469  //- Write as dictionary to file
470  void write(const fileName& fName) const;
471 
472  //- Write to separate OBJ files (region, external, internal edges,
473  // feature points) for visualization
474  void writeObj(const fileName& prefix) const;
475 
476  //- Write some information
477  void writeStats(Ostream& os) const;
478 
479 
480 
481  // Member Operators
482 
483  void operator=(const surfaceFeatures& rhs);
484 
485 
486 };
487 
488 
489 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
490 
491 } // End namespace Foam
492 
493 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
494 
495 #endif
496 
497 // ************************************************************************* //
dictionary dict
A class for handling file names.
Definition: fileName.H:72
void deleteBox(List< edgeStatus > &edgeStat, const treeBoundBox &bb, const bool removeInside) const
Mark edge status as &#39;NONE&#39; for edges inside/outside box.
label nRegionEdges() const
Return number of region edges.
void write(const fileName &fName) const
Write as dictionary to file.
List< edge > edgeList
List of edge.
Definition: edgeList.H:32
scalarField samples(nIntervals, Zero)
PointIndexHit< point > pointIndexHit
A PointIndexHit with a 3D point.
Definition: pointIndexHit.H:58
label externalStart() const
Start of external edges.
Map< label > nearestSamples(const labelList &selectedPoints, const pointField &samples, const scalarField &maxDistSqr) const
Find nearest sample for selected surface points.
void subsetBox(List< edgeStatus > &edgeStat, const treeBoundBox &bb) const
Mark edge status outside box as &#39;NONE&#39;.
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.
const labelList & featureEdges() const
Return feature edge list.
Geometric class that creates a 3D plane and can return the intersection point between a line and the ...
Definition: plane.H:90
List< labelList > labelListList
List of labelList.
Definition: labelList.H:38
void writeObj(const fileName &prefix) const
Write to separate OBJ files (region, external, internal edges,.
labelList selectFeatureEdges(const bool regionEdges, const bool externalEdges, const bool internalEdges) const
Helper function: select a subset of featureEdges_.
List< edgeStatus > toStatus() const
From member feature edges to status per edge.
Not a classified feature edge.
labelList trimFeatures(const scalar minLen, const label minElems, const scalar includedAngle)
Delete small sets of edges. Edges are stringed up and any.
vectorField pointField
pointField is a vectorField.
Definition: pointFieldFwd.H:38
const dimensionedScalar e
Elementary charge.
Definition: createFields.H:11
line< point, const point & > linePointRef
A line using referred points.
Definition: line.H:66
const pointField & points
void setFromStatus(const List< edgeStatus > &edgeStat, const scalar includedAngle)
Set from status per edge.
void operator=(const surfaceFeatures &rhs)
void writeStats(Ostream &os) const
Write some information.
const triSurface & surface() const
void excludeBox(List< edgeStatus > &edgeStat, const treeBoundBox &bb) const
Mark edge status inside box as &#39;NONE&#39;.
An Ostream is an abstract base class for all output systems (streams, files, token lists...
Definition: Ostream.H:56
A Vector of values with scalar precision, where scalar is float/double depending on the compilation f...
const labelList & featurePoints() const
Return feature point list.
OBJstream os(runTime.globalPath()/outputName)
ClassName("surfaceFeatures")
void subsetPlane(List< edgeStatus > &edgeStat, const plane &cutPlane) const
If edge does not intersect the plane, mark as &#39;NONE&#39;.
vector point
Point is a vector.
Definition: point.H:37
void findFeatures(const scalar includedAngle, const bool geometricTestOnly)
Find feature edges using provided included angle.
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.
surfaceFeatures(const triSurface &surf)
Construct from surface.
void excludeOpen(List< edgeStatus > &edgeStat) const
Mark edges with a single connected face as &#39;NONE&#39;.
void nearestFeatEdge(const edgeList &edges, const pointField &points, scalar searchSpanSqr, labelList &edgeLabel) const
Find nearest feature edge to each surface edge. Uses the.
Standard boundBox with extra functionality for use in octree.
Definition: treeBoundBox.H:90
void writeDict(Ostream &os) const
Write as dictionary.
label n
label nInternalEdges() const
Return number of internal edges.
List< label > labelList
A List of labels.
Definition: List.H:62
label internalStart() const
Start of internal edges.
Holds feature edges/points of surface.
label nExternalEdges() const
Return number of external edges.
Namespace for OpenFOAM.