surfaceFeatures.H
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration | Website: https://openfoam.org
5  \\ / A nd | Copyright (C) 2011-2024 OpenFOAM Foundation
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8 License
9  This file is part of OpenFOAM.
10 
11  OpenFOAM is free software: you can redistribute it and/or modify it
12  under the terms of the GNU General Public License as published by
13  the Free Software Foundation, either version 3 of the License, or
14  (at your option) any later version.
15 
16  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
17  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19  for more details.
20 
21  You should have received a copy of the GNU General Public License
22  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
23 
24 Class
25  Foam::surfaceFeatures
26 
27 Description
28  Holds feature edges/points of surface.
29 
30  Feature edges are stored in one list and sorted:
31  0 .. externalStart_-1 : region edges
32  externalStart_ .. internalStart_-1 : external edges
33  internalStart_ .. size-1 : internal edges
34 
35  NOTE: angle is included angle, not feature angle. The included angle is the
36  smallest angle between two planes. For coplanar faces it is 180 degrees,
37  for straight angles it is 90 degrees. To pick up straight edges only use
38  included angle of 91 degrees.
39 
40 SourceFiles
41  surfaceFeatures.C
42 
43 \*---------------------------------------------------------------------------*/
44 
45 #ifndef surfaceFeatures_H
46 #define surfaceFeatures_H
47 
48 #include "pointField.H"
49 #include "Map.H"
50 #include "HashSet.H"
51 #include "pointIndexHit.H"
52 #include "edgeList.H"
53 #include "typeInfo.H"
54 #include "boundBox.H"
55 #include "plane.H"
56 
57 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
58 
59 namespace Foam
60 {
61 
62 // Forward declaration of classes
63 class triSurface;
64 
65 /*---------------------------------------------------------------------------*\
66  Class surfaceFeatures Declaration
67 \*---------------------------------------------------------------------------*/
68 
69 class surfaceFeatures
70 {
71 public:
72 
73  enum edgeStatus
74  {
77  EXTERNAL,
79  };
80 
81 
82 private:
83 
84  //- Label and scalar; used in path walking
85  class labelScalar
86  {
87  public:
88  label n_;
89  scalar len_;
90 
91  labelScalar(const label n, const scalar len)
92  :
93  n_(n),
94  len_(len)
95  {}
96  };
97 
98  // Static data
99 
100  //- Tolerance for determining whether two vectors are parallel
101  static const scalar parallelTolerance;
102 
103 
104  // Private Data
105 
106  //- Reference to surface
107  const triSurface& surf_;
108 
109  //- Labels of points that are features
110  labelList featurePoints_;
111 
112  //- Labels of edges that are features
113  labelList featureEdges_;
114 
115  //- Start of external edges in featureEdges_
116  label externalStart_;
117 
118  //- Start of internal edges in featureEdges_
119  label internalStart_;
120 
121 
122  // Private Member Functions
123 
124  //- Return nearest point on edge (start..end). Also classify nearest:
125  // index=-1: nearest on mid of edge. index=0:nearest on edge.start()
126  // index=1: nearest on edge.end().
127  static pointIndexHit edgeNearest
128  (
129  const point& start,
130  const point& end,
131  const point& sample
132  );
133 
134 
135  //- Construct feature points where more than 2 feature edges meet
136  void calcFeatPoints
137  (
138  const List<edgeStatus>& edgeStat,
139  const scalar minCos
140  );
141 
142  //- Classify the angles of the feature edges
143  void classifyFeatureAngles
144  (
145  const labelListList& edgeFaces,
146  List<edgeStatus>& edgeStat,
147  const scalar minCos,
148  const bool geometricTestOnly
149  ) const;
150 
151  //- Choose next unset feature edge.
152  label nextFeatEdge
153  (
154  const List<edgeStatus>& edgeStat,
155  const labelList& featVisited,
156  const label unsetVal,
157  const label prevEdgeI,
158  const label vertI
159  ) const;
160 
161  //- Walk connected feature edges. Marks edges in featVisited.
162  labelScalar walkSegment
163  (
164  const bool mark,
165  const List<edgeStatus>& edgeStat,
166  const label startEdgeI,
167  const label startPointi,
168  const label currentFeatI,
169  labelList& featVisited
170  );
171 
172 public:
173 
174  ClassName("surfaceFeatures");
175 
176  // Constructors
177 
178  //- Construct from surface
179  surfaceFeatures(const triSurface&);
180 
181  //- Construct from components
183  (
184  const triSurface&,
185  const labelList& featurePoints,
186  const labelList& featureEdges,
187  const label externalStart,
188  const label internalStart
189  );
190 
191  //- Construct from surface, angle and min cumulative length and/or
192  // number of elements. If geometric test only is true, then region
193  // information is ignored and features are only assigned based on the
194  // geometric criteria
196  (
197  const triSurface&,
198  const scalar includedAngle,
199  const scalar minLen = 0,
200  const label minElems = 0,
201  const bool geometricTestOnly = false
202  );
203 
204  //- Construct from dictionary
205  surfaceFeatures(const triSurface&, const dictionary& dict);
206 
207  //- Construct from file
208  surfaceFeatures(const triSurface&, const fileName& fName);
209 
210  //- Construct from pointField and edgeList (edgeMesh)
212  (
213  const triSurface&,
214  const pointField& points,
215  const edgeList& edges,
216  const scalar mergeTol = 1e-6,
217  const bool geometricTestOnly = false
218  );
219 
220  //- Copy constructor
222 
223 
224  // Member Functions
225 
226  // Access
227 
228  inline const triSurface& surface() const
229  {
230  return surf_;
231  }
232 
233  //- Return feature point list
234  inline const labelList& featurePoints() const
235  {
236  return featurePoints_;
237  }
238 
239  //- Return feature edge list
240  inline const labelList& featureEdges() const
241  {
242  return featureEdges_;
243  }
244 
245  //- Start of external edges
246  inline label externalStart() const
247  {
248  return externalStart_;
249  }
250 
251  //- Start of internal edges
252  inline label internalStart() const
253  {
254  return internalStart_;
255  }
256 
257  //- Return number of region edges
258  inline label nRegionEdges() const
259  {
260  return externalStart_;
261  }
262 
263  //- Return number of external edges
264  inline label nExternalEdges() const
265  {
266  return internalStart_ - externalStart_;
267  }
268 
269  //- Return number of internal edges
270  inline label nInternalEdges() const
271  {
272  return featureEdges_.size() - internalStart_;
273  }
274 
275  //- Helper function: select a subset of featureEdges_
277  (
278  const bool regionEdges,
279  const bool externalEdges,
280  const bool internalEdges
281  ) const;
282 
283 
284  // Edit
285 
286  //- Find feature edges using provided included angle
287  void findFeatures
288  (
289  const scalar includedAngle,
290  const bool geometricTestOnly
291  );
292 
293  //- Delete small sets of edges. Edges are stringed up and any
294  // string of length < minLen (or nElems < minElems) is deleted.
296  (
297  const scalar minLen,
298  const label minElems,
299  const scalar includedAngle
300  );
301 
302  //- From member feature edges to status per edge.
303  List<edgeStatus> toStatus() const;
304 
305  //- Set from status per edge
306  void setFromStatus
307  (
308  const List<edgeStatus>& edgeStat,
309  const scalar includedAngle
310  );
311 
312 
313  // Find
314 
315  //- Find nearest sample for selected surface points
316  // (usually the set of featurePoints). Return map from
317  // index in samples to surface point. Do not include
318  // points that are further than maxDist away (separate
319  // maxDist for every sample). Supply maxDistSqr.
321  (
322  const labelList& selectedPoints,
323  const pointField& samples,
324  const scalarField& maxDistSqr
325  ) const;
326 
327  //- Find nearest sample for regularly sampled points along
328  // the selected (surface) edges. Return map from sample
329  // to edge. maxDistSqr is distance squared below which
330  // gets snapped. Edge gets sampled at points
331  // sampleDist[sampleI] apart. (with a maximum of 10
332  // samples per edge)
334  (
335  const labelList& selectedEdges,
336  const pointField& samples,
337  const scalarField& sampleDist,
338  const scalarField& maxDistSqr,
339  const scalar minSampleDist = 0.1
340  ) const;
341 
342  //- Like nearestSamples but now gets nearest point on
343  // sample-edge instead of nearest sample-point itself.
344  // Return map from sample edge to feature edge.
346  (
347  const labelList& selectedEdges,
348  const edgeList& sampleEdges,
349  const labelList& selectedSampleEdges,
350  const pointField& samplePoints,
351  const scalarField& sampleDist,
352  const scalarField& maxDistSqr,
353  const scalar minSampleDist = 0.1
354  ) const;
355 
356 
357  //- Find nearest surface edge (out of selectedEdges) for
358  // each sample point.
359  // Sets:
360  // - edgeLabel : label of surface edge.
361  // - edgePoint : exact position of nearest point on edge.
362  // - edgeEndPoint : -1, 0, 1 depending on whether edgePoint is
363  // on inside/start/end of edge
364  void nearestSurfEdge
365  (
366  const labelList& selectedEdges,
367  const pointField& samples,
368  scalar searchSpanSqr, // search span
369  labelList& edgeLabel,
370  labelList& edgeEndPoint,
371  pointField& edgePoint
372  ) const;
373 
374  //- Find nearest surface edge (out of selectedEdges) for each
375  // sample edge.
376  // Sets:
377  // - edgeLabel : label of surface edge.
378  // - pointOnEdge : exact position of nearest point on edge.
379  // - pointOnFeature : exact position on sample edge.
380  void nearestSurfEdge
381  (
382  const labelList& selectedEdges,
383  const edgeList& sampleEdges,
384  const labelList& selectedSampleEdges,
385  const pointField& samplePoints,
386  const vector& searchSpan, // search span
387 
388  labelList& edgeLabel, // label of surface edge or -1
389  pointField& pointOnEdge, // point on above edge
390  pointField& pointOnFeature // point on sample edge
391  ) const;
392 
393  //- Find nearest feature edge to each surface edge. Uses the
394  // mid-point of the surface edges.
395  void nearestFeatEdge
396  (
397  const edgeList& edges,
398  const pointField& points,
399  scalar searchSpanSqr,
400  labelList& edgeLabel
401  ) const;
402 
403 
404  // Write
405 
406  //- Write as dictionary
407  void writeDict(Ostream&) const;
408 
409  //- Write as dictionary to file
410  void write(const fileName& fName) const;
411 
412  //- Write to separate OBJ files (region, external, internal edges,
413  // feature points) for visualisation
414  void writeObj(const fileName& prefix) const;
415 
416 
417 
418  // Member Operators
419 
420  void operator=(const surfaceFeatures&);
421 };
422 
423 
424 //- Select edges inside or outside bounding box
425 void selectBox
426 (
427  const triSurface& surf,
428  const boundBox& bb,
429  const bool removeInside,
430  List<surfaceFeatures::edgeStatus>& edgeStat
431 );
432 
433 //- Select edges that are intersected by the given plane
434 void selectCutEdges
435 (
436  const triSurface& surf,
437  const plane& cutPlane,
438  List<surfaceFeatures::edgeStatus>& edgeStat
439 );
440 
441 //- Divide into multiple normal bins
442 // - return REGION if != 2 normals
443 // - return REGION if 2 normals that make feature angle
444 // - otherwise return NONE and set normals,bins
446 (
447  const triSurface& surf,
448  const scalar tol,
449  const scalar includedAngle,
450  const label edgei
451 );
452 
453 //- Select manifold edges
455 (
456  const triSurface& surf,
457  const scalar tol,
458  const scalar includedAngle,
459  List<surfaceFeatures::edgeStatus>& edgeStat
460 );
461 
462 
463 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
464 
465 } // End namespace Foam
466 
467 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
468 
469 #endif
470 
471 // ************************************************************************* //
label n
An Ostream is an abstract base class for all output systems (streams, files, token lists,...
Definition: Ostream.H:57
A list of keyword definitions, which are a keyword followed by any number of values (e....
Definition: dictionary.H:162
A class for handling file names.
Definition: fileName.H:82
Holds feature edges/points of surface.
void findFeatures(const scalar includedAngle, const bool geometricTestOnly)
Find feature edges using provided included angle.
surfaceFeatures(const triSurface &)
Construct from surface.
labelList selectFeatureEdges(const bool regionEdges, const bool externalEdges, const bool internalEdges) const
Helper function: select a subset of featureEdges_.
const labelList & featureEdges() const
Return feature edge list.
void setFromStatus(const List< edgeStatus > &edgeStat, const scalar includedAngle)
Set from status per edge.
void write(const fileName &fName) const
Write as dictionary to file.
const labelList & featurePoints() const
Return feature point list.
ClassName("surfaceFeatures")
label nRegionEdges() const
Return number of region edges.
label nExternalEdges() const
Return number of external edges.
void writeObj(const fileName &prefix) const
Write to separate OBJ files (region, external, internal edges,.
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.
List< edgeStatus > toStatus() const
From member feature edges to status per edge.
void writeDict(Ostream &) const
Write as dictionary.
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.
label internalStart() const
Start of internal edges.
label externalStart() const
Start of external edges.
const triSurface & surface() const
Map< label > nearestSamples(const labelList &selectedPoints, const pointField &samples, const scalarField &maxDistSqr) const
Find nearest sample for selected surface points.
void nearestFeatEdge(const edgeList &edges, const pointField &points, scalar searchSpanSqr, labelList &edgeLabel) const
Find nearest feature edge to each surface edge. Uses the.
label nInternalEdges() const
Return number of internal edges.
void operator=(const surfaceFeatures &)
labelList trimFeatures(const scalar minLen, const label minElems, const scalar includedAngle)
Delete small sets of edges. Edges are stringed up and any.
Triangulated surface description with patch information.
Definition: triSurface.H:69
const pointField & points
Namespace for OpenFOAM.
const doubleScalar e
Definition: doubleScalar.H:106
List< label > labelList
A List of labels.
Definition: labelList.H:56
intWM_LABEL_SIZE_t label
A label is an int32_t or int64_t as specified by the pre-processor macro WM_LABEL_SIZE.
Definition: label.H:59
PointIndexHit< point > pointIndexHit
Definition: pointIndexHit.H:42
surfaceFeatures::edgeStatus checkNonManifoldEdge(const triSurface &surf, const scalar tol, const scalar includedAngle, const label edgei)
Divide into multiple normal bins.
void selectBox(const triSurface &surf, const boundBox &bb, const bool removeInside, List< surfaceFeatures::edgeStatus > &edgeStat)
Select edges inside or outside bounding box.
vector point
Point is a vector.
Definition: point.H:41
List< labelList > labelListList
A List of labelList.
Definition: labelList.H:57
void selectManifoldEdges(const triSurface &surf, const scalar tol, const scalar includedAngle, List< surfaceFeatures::edgeStatus > &edgeStat)
Select manifold edges.
void selectCutEdges(const triSurface &surf, const plane &cutPlane, List< surfaceFeatures::edgeStatus > &edgeStat)
Select edges that are intersected by the given plane.
dictionary dict
Basic run-time type information using word as the type's name. Used to enhance the standard RTTI to c...
scalarField samples(nIntervals, 0)