Loading...
Searching...
No Matches
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;
70/*---------------------------------------------------------------------------*\
71 Class surfaceFeatures Declaration
72\*---------------------------------------------------------------------------*/
73
75{
76public:
77
78 //- Edge status
80 {
82 REGION, //
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 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
198public:
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,
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
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.
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// ************************************************************************* //
label n
A 1D array of objects of type <T>, where the size of the vector is known and used for subscript bound...
Definition List.H:72
A HashTable to objects of type <T> with a label key.
Definition Map.H:54
An Ostream is an abstract base class for all output systems (streams, files, token lists,...
Definition Ostream.H:59
void size(const label n)
Older name for setAddressableSize.
Definition UList.H:118
A list of keyword definitions, which are a keyword followed by a number of values (eg,...
Definition dictionary.H:133
A class for handling file names.
Definition fileName.H:75
Geometric class that creates a 3D plane and can return the intersection point between a line and the ...
Definition plane.H:91
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 excludeNonManifold(List< edgeStatus > &edgeStat) const
Mark edges with >2 connected faces as 'NONE'.
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.
surfaceFeatures(const triSurface &surf)
Construct from surface.
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.
Triangulated surface description with patch information.
Definition triSurface.H:74
#define ClassName(TypeNameString)
Add typeName information from argument TypeNameString to a class.
Definition className.H:74
OBJstream os(runTime.globalPath()/outputName)
const pointField & points
Namespace for OpenFOAM.
List< edge > edgeList
List of edge.
Definition edgeList.H:32
List< labelList > labelListList
List of labelList.
Definition labelList.H:38
List< label > labelList
A List of labels.
Definition List.H:62
Field< scalar > scalarField
Specialisation of Field<T> for scalar.
line< point, const point & > linePointRef
A line using referred points.
Definition line.H:66
vector point
Point is a vector.
Definition point.H:37
void rhs(fvMatrix< typename Expr::value_type > &m, const Expr &expression)
vectorField pointField
pointField is a vectorField.
Vector< scalar > vector
Definition vector.H:57
PointIndexHit< point > pointIndexHit
A PointIndexHit with a 3D point.
runTime write()
dictionary dict
volScalarField & e
Basic run-time type information using word as the type's name. Used to enhance the standard RTTI to c...
scalarField samples(nIntervals, Zero)