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-------------------------------------------------------------------------------
11License
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
27Class
28 Foam::surfaceFeatures
29
30Description
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
45SourceFiles
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
62namespace Foam
63{
64
65// Forward declaration of classes
66class plane;
67class triSurface;
68class treeBoundBox;
69
70/*---------------------------------------------------------------------------*\
71 Class surfaceFeatures Declaration
72\*---------------------------------------------------------------------------*/
75{
76public:
77
78 //- Edge status
79 enum edgeStatus
80 {
83 EXTERNAL,
85 };
86
87
88private:
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
189public:
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,
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
239
240
241 // Member Functions
242
243 // Access
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.
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// ************************************************************************* //
label n
Minimal example by using system/controlDict.functions:
A HashTable to objects of type <T> with a label key.
Definition: Map.H:60
An Ostream is an abstract base class for all output systems (streams, files, token lists,...
Definition: Ostream.H:62
A list of keyword definitions, which are a keyword followed by a number of values (eg,...
Definition: dictionary.H:126
A class for handling file names.
Definition: fileName.H:76
Geometric class that creates a 3D plane and can return the intersection point between a line and the ...
Definition: plane.H:95
Holds feature edges/points of surface.
void findFeatures(const scalar includedAngle, const bool geometricTestOnly)
Find feature edges using provided included angle.
labelList selectFeatureEdges(const bool regionEdges, const bool externalEdges, const bool internalEdges) const
Helper function: select a subset of featureEdges_.
void setFromStatus(const List< edgeStatus > &edgeStat, const scalar includedAngle)
Set from status per edge.
const triSurface & surface() const
void excludeOpen(List< edgeStatus > &edgeStat) const
Mark edges with a single connected face as 'NONE'.
void subsetPlane(List< edgeStatus > &edgeStat, const plane &cutPlane) const
If edge does not intersect the plane, mark as 'NONE'.
ClassName("surfaceFeatures")
label nRegionEdges() const
Return number of region edges.
label nExternalEdges() const
Return number of external edges.
void operator=(const surfaceFeatures &rhs)
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 subsetBox(List< edgeStatus > &edgeStat, const treeBoundBox &bb) const
Mark edge status outside box as 'NONE'.
@ EXTERNAL
"Convex" edge
@ NONE
Not a classified feature edge.
@ INTERNAL
"Concave" edge
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.
void deleteBox(List< edgeStatus > &edgeStat, const treeBoundBox &bb, const bool removeInside) const
Mark edge status as 'NONE' for edges inside/outside box.
void writeDict(Ostream &os) const
Write as dictionary.
label internalStart() const
Start of internal edges.
label externalStart() const
Start of external edges.
void writeStats(Ostream &os) const
Write some information.
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.
const labelList & featureEdges() const
Return feature edge list.
const labelList & featurePoints() const
Return feature point list.
labelList trimFeatures(const scalar minLen, const label minElems, const scalar includedAngle)
Delete small sets of edges. Edges are stringed up and any.
void excludeBox(List< edgeStatus > &edgeStat, const treeBoundBox &bb) const
Mark edge status inside box as 'NONE'.
Standard boundBox with extra functionality for use in octree.
Definition: treeBoundBox.H:89
Triangulated surface description with patch information.
Definition: triSurface.H:79
#define ClassName(TypeNameString)
Add typeName information from argument TypeNameString to a class.
Definition: className.H:67
OBJstream os(runTime.globalPath()/outputName)
const pointField & points
Namespace for OpenFOAM.
List< label > labelList
A List of labels.
Definition: List.H:66
PointIndexHit< point > pointIndexHit
A PointIndexHit for 3D points.
Definition: pointIndexHit.H:46
vector point
Point is a vector.
Definition: point.H:43
List< labelList > labelListList
A List of labelList.
Definition: labelList.H:56
runTime write()
dictionary dict
volScalarField & e
Definition: createFields.H:11
scalarField samples(nIntervals, Zero)