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 
179  //edgeStatus checkBinRegion
180  //(
181  // const label edgei,
182  // const labelList& bin0,
183  // const labelList& bin1
184  //) const;
185 
186  //- Divide into multiple normal bins
187  // - set REGION if != 2 normals
188  // - set REGION if 2 normals that make feature angle
189  // - otherwise set NONE and set normals,bins
190  edgeStatus checkFlatRegionEdge
191  (
192  const scalar tol,
193  const scalar includedAngle,
194  const label edgeI,
195  const point& leftPoint
196  ) const;
197 
198 public:
199 
200  ClassName("surfaceFeatures");
201 
202  // Constructors
203 
204  //- Construct from surface
205  surfaceFeatures(const triSurface& surf);
206 
207  //- Construct from components
209  (
210  const triSurface& surf,
211  const labelList& featurePoints,
212  const labelList& featureEdges,
213  const label externalStart,
214  const label internalStart
215  );
216 
217  //- Construct from surface, angle and min cumulative length and/or
218  // number of elements. If geometric test only is true, then region
219  // information is ignored and features are only assigned based on the
220  // geometric criteria
222  (
223  const triSurface& surf,
224  const scalar includedAngle,
225  const scalar minLen = 0,
226  const label minElems = 0,
227  const bool geometricTestOnly = false
228  );
229 
230  //- Construct from dictionary
231  surfaceFeatures(const triSurface& surf, const dictionary& dict);
232 
233  //- Construct from file
234  surfaceFeatures(const triSurface& surf, const fileName& fName);
235 
236  //- Construct from pointField and edgeList (edgeMesh)
238  (
239  const triSurface& surf,
240  const pointField& points,
241  const edgeList& edges,
242  const scalar mergeTol = 1e-6,
243  const bool geometricTestOnly = false
244  );
245 
246  //- Construct as copy
247  surfaceFeatures(const surfaceFeatures& sf);
248 
249 
250  // Member Functions
251 
252  // Access
253 
254  inline const triSurface& surface() const
255  {
256  return surf_;
257  }
258 
259  //- Return feature point list
260  inline const labelList& featurePoints() const
261  {
262  return featurePoints_;
263  }
264 
265  //- Return feature edge list
266  inline const labelList& featureEdges() const
267  {
268  return featureEdges_;
269  }
270 
271  //- Start of external edges
272  inline label externalStart() const
273  {
274  return externalStart_;
275  }
276 
277  //- Start of internal edges
278  inline label internalStart() const
279  {
280  return internalStart_;
281  }
282 
283  //- Return number of region edges
284  inline label nRegionEdges() const
285  {
286  return externalStart_;
287  }
288 
289  //- Return number of external edges
290  inline label nExternalEdges() const
291  {
292  return internalStart_ - externalStart_;
293  }
295  //- Return number of internal edges
296  inline label nInternalEdges() const
297  {
298  return featureEdges_.size() - internalStart_;
299  }
300 
301  //- Helper function: select a subset of featureEdges_
303  (
304  const bool regionEdges,
305  const bool externalEdges,
306  const bool internalEdges
307  ) const;
308 
309 
310  // Edit
311 
312  //- Find feature edges using provided included angle
313  void findFeatures
314  (
315  const scalar includedAngle,
316  const bool geometricTestOnly
317  );
319  //- Delete small sets of edges. Edges are stringed up and any
320  // string of length < minLen (or nElems < minElems) is deleted.
322  (
323  const scalar minLen,
324  const label minElems,
325  const scalar includedAngle
326  );
327 
328  //- Mark edge status inside box as 'NONE'
329  void excludeBox
330  (
331  List<edgeStatus>& edgeStat,
332  const treeBoundBox& bb
333  ) const;
335  //- Mark edge status outside box as 'NONE'
336  void subsetBox
337  (
338  List<edgeStatus>& edgeStat,
339  const treeBoundBox& bb
340  ) const;
341 
342  //- Mark edge status as 'NONE' for edges inside/outside box.
343  void deleteBox
344  (
345  List<edgeStatus>& edgeStat,
346  const treeBoundBox& bb,
347  const bool removeInside
348  ) const;
349 
350  //- If edge does not intersect the plane, mark as 'NONE'
351  void subsetPlane
352  (
353  List<edgeStatus>& edgeStat,
354  const plane& cutPlane
355  ) const;
356 
357  //- Mark edges with a single connected face as 'NONE'
358  void excludeOpen(List<edgeStatus>& edgeStat) const;
359 
360  //- Mark edges with >2 connected faces as 'NONE'
361  void excludeNonManifold(List<edgeStatus>& edgeStat) const;
362 
363  //- Divide into multiple normal bins
364  // - set REGION if != 2 normals
365  // - set REGION if 2 normals that make feature angle
366  // - otherwise set NONE and set normals,bins
367  void checkFlatRegionEdge
368  (
369  List<edgeStatus>& edgeStat,
370  const scalar tol,
371  const scalar includedAngle
372  ) const;
373 
374 
375  //- From member feature edges to status per edge.
376  List<edgeStatus> toStatus() const;
377 
378  //- Set from status per edge
379  void setFromStatus
380  (
381  const List<edgeStatus>& edgeStat,
382  const scalar includedAngle
383  );
384 
385 
386  // Find
387 
388  //- Find nearest sample for selected surface points
389  // (usually the set of featurePoints). Return map from
390  // index in samples to surface point. Do not include
391  // points that are further than maxDist away (separate
392  // maxDist for every sample). Supply maxDistSqr.
394  (
395  const labelList& selectedPoints,
396  const pointField& samples,
397  const scalarField& maxDistSqr
398  ) const;
399 
400  //- Find nearest sample for regularly sampled points along
401  // the selected (surface) edges. Return map from sample
402  // to edge. maxDistSqr is distance squared below which
403  // gets snapped. Edge gets sampled at points
404  // sampleDist[sampleI] apart. (with a maximum of 10
405  // samples per edge)
407  (
408  const labelList& selectedEdges,
409  const pointField& samples,
410  const scalarField& sampleDist,
411  const scalarField& maxDistSqr,
412  const scalar minSampleDist = 0.1
413  ) const;
414 
415  //- Like nearestSamples but now gets nearest point on
416  // sample-edge instead of nearest sample-point itself.
417  // Return map from sample edge to feature edge.
419  (
420  const labelList& selectedEdges,
421  const edgeList& sampleEdges,
422  const labelList& selectedSampleEdges,
423  const pointField& samplePoints,
424  const scalarField& sampleDist,
425  const scalarField& maxDistSqr,
426  const scalar minSampleDist = 0.1
427  ) const;
428 
429 
430  //- Find nearest surface edge (out of selectedEdges) for
431  // each sample point.
432  // Sets:
433  // - edgeLabel : label of surface edge.
434  // - edgePoint : exact position of nearest point on edge.
435  // - edgeEndPoint : -1, 0, 1 depending on whether edgePoint is
436  // on inside/start/end of edge
437  void nearestSurfEdge
438  (
439  const labelList& selectedEdges,
440  const pointField& samples,
441  scalar searchSpanSqr, // search span
442  labelList& edgeLabel,
443  labelList& edgeEndPoint,
444  pointField& edgePoint
445  ) const;
446 
447  //- Find nearest surface edge (out of selectedEdges) for each
448  // sample edge.
449  // Sets:
450  // - edgeLabel : label of surface edge.
451  // - pointOnEdge : exact position of nearest point on edge.
452  // - pointOnFeature : exact position on sample edge.
453  void nearestSurfEdge
454  (
455  const labelList& selectedEdges,
456  const edgeList& sampleEdges,
457  const labelList& selectedSampleEdges,
458  const pointField& samplePoints,
459  const vector& searchSpan, // search span
460 
461  labelList& edgeLabel, // label of surface edge or -1
462  pointField& pointOnEdge, // point on above edge
463  pointField& pointOnFeature // point on sample edge
464  ) const;
465 
466  //- Find nearest feature edge to each surface edge. Uses the
467  // mid-point of the surface edges.
468  void nearestFeatEdge
469  (
470  const edgeList& edges,
471  const pointField& points,
472  scalar searchSpanSqr,
473  labelList& edgeLabel
474  ) const;
475 
476 
477  // Write
478 
479  //- Write as dictionary
480  void writeDict(Ostream& os) const;
481 
482  //- Write as dictionary to file
483  void write(const fileName& fName) const;
484 
485  //- Write to separate OBJ files (region, external, internal edges,
486  // feature points) for visualization
487  void writeObj(const fileName& prefix) const;
488 
489  //- Write some information
490  void writeStats(Ostream& os) const;
491 
492 
493 
494  // Member Operators
495 
496  void operator=(const surfaceFeatures& rhs);
497 
498 
499 };
500 
501 
502 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
503 
504 } // End namespace Foam
505 
506 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
507 
508 #endif
509 
510 // ************************************************************************* //
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_.
void excludeNonManifold(List< edgeStatus > &edgeStat) const
Mark edges with >2 connected faces as &#39;NONE&#39;.
List< edgeStatus > toStatus() const
From member feature edges to status per edge.
void rhs(fvMatrix< typename Expr::value_type > &m, const Expr &expression)
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")
Basic run-time type information using word as the type&#39;s name. Used to enhance the standard RTTI to c...
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.