boundBox.C 7.13 KB
Newer Older
1
2
3
4
/*---------------------------------------------------------------------------*\
  =========                 |
  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
   \\    /   O peration     |
5
    \\  /    A nd           | Copyright (C) 2011-2016 OpenFOAM Foundation
6
     \\/     M anipulation  | Copyright (C) 2016-2018 OpenCFD Ltd.
7
8
9
10
-------------------------------------------------------------------------------
License
    This file is part of OpenFOAM.

11
12
13
14
    OpenFOAM is free software: you can redistribute it and/or modify it
    under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.
15
16
17
18
19
20
21

    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    for more details.

    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
25
26
27

\*---------------------------------------------------------------------------*/

#include "boundBox.H"
#include "PstreamReduceOps.H"
Mark Olesen's avatar
Mark Olesen committed
28
#include "tmp.H"
29
#include "plane.H"
30

31
32
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //

33
34
35
36
37
const Foam::boundBox Foam::boundBox::greatBox
(
    point::uniform(-ROOTVGREAT),
    point::uniform(ROOTVGREAT)
);
38

39
40
41
42
43
const Foam::boundBox Foam::boundBox::invertedBox
(
    point::uniform(ROOTVGREAT),
    point::uniform(-ROOTVGREAT)
);
44
45

const Foam::faceList Foam::boundBox::faces
46
47
({
    // Point and face order as per hex cellmodel
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
    face({0, 4, 7, 3}),  // 0: x-min, left
    face({1, 2, 6, 5}),  // 1: x-max, right
    face({0, 1, 5, 4}),  // 2: y-min, bottom
    face({3, 7, 6, 2}),  // 3: y-max, top
    face({0, 3, 2, 1}),  // 4: z-min, back
    face({4, 5, 6, 7})   // 5: z-max, front
});

const Foam::FixedList<Foam::vector, 6> Foam::boundBox::faceNormals
({
    vector(-1,  0,  0), // 0: x-min, left
    vector( 1,  0,  0), // 1: x-max, right
    vector( 0, -1,  0), // 2: y-min, bottom
    vector( 0,  1,  0), // 3: y-max, top
    vector( 0,  0, -1), // 4: z-min, back
    vector( 0,  0,  1)  // 5: z-max, front
64
});
65
66


67
// * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
68

69
70
Foam::boundBox::boundBox(const UList<point>& points, bool doReduce)
:
71
    boundBox()
72
{
73
    add(points);
74
75
76

    if (doReduce)
    {
77
        reduce();
78
79
80
81
    }
}


82
Foam::boundBox::boundBox(const tmp<pointField>& tpoints, bool doReduce)
Mark Olesen's avatar
Mark Olesen committed
83
:
84
    boundBox()
Mark Olesen's avatar
Mark Olesen committed
85
{
86
87
88
89
90
91
    add(tpoints);

    if (doReduce)
    {
        reduce();
    }
Mark Olesen's avatar
Mark Olesen committed
92
93
94
}


95
96
97
98
Foam::boundBox::boundBox
(
    const UList<point>& points,
    const labelUList& indices,
99
    bool doReduce
100
101
)
:
102
    boundBox()
mattijs's avatar
mattijs committed
103
{
104
    add(points, indices);
105
106
107

    if (doReduce)
    {
108
        reduce();
109
    }
mattijs's avatar
mattijs committed
110
}
111
112


Mark Olesen's avatar
Mark Olesen committed
113
114
// * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * * //

115
Foam::tmp<Foam::pointField> Foam::boundBox::points() const
Mark Olesen's avatar
Mark Olesen committed
116
{
117
118
    auto tpt = tmp<pointField>::New(8);
    auto& pt = tpt.ref();
Mark Olesen's avatar
Mark Olesen committed
119
120
121
122
123
124
125
126
127
128

    pt[0] = min_;                                   // min-x, min-y, min-z
    pt[1] = point(max_.x(), min_.y(), min_.z());    // max-x, min-y, min-z
    pt[2] = point(max_.x(), max_.y(), min_.z());    // max-x, max-y, min-z
    pt[3] = point(min_.x(), max_.y(), min_.z());    // min-x, max-y, min-z
    pt[4] = point(min_.x(), min_.y(), max_.z());    // min-x, min-y, max-z
    pt[5] = point(max_.x(), min_.y(), max_.z());    // max-x, min-y, max-z
    pt[6] = max_;                                   // max-x, max-y, max-z
    pt[7] = point(min_.x(), max_.y(), max_.z());    // min-x, max-y, max-z

129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
    return tpt;
}


Foam::tmp<Foam::pointField> Foam::boundBox::faceCentres() const
{
    auto tpts = tmp<pointField>::New(6);
    auto& pts = tpts.ref();

    forAll(pts, facei)
    {
        pts[facei] = faceCentre(facei);
    }

    return tpts;
}


Foam::point Foam::boundBox::faceCentre(const direction facei) const
{
    point pt = boundBox::midpoint();

    if (facei > 5)
    {
        FatalErrorInFunction
            << "face should be [0..5]"
            << abort(FatalError);
    }

    switch (facei)
    {
        case 0: pt.x() = min().x(); break;  // 0: x-min, left
        case 1: pt.x() = max().x(); break;  // 1: x-max, right
        case 2: pt.y() = min().y(); break;  // 2: y-min, bottom
        case 3: pt.y() = max().y(); break;  // 3: y-max, top
        case 4: pt.z() = min().z(); break;  // 4: z-min, back
        case 5: pt.z() = max().z(); break;  // 5: z-max, front
    }

    return pt;
Mark Olesen's avatar
Mark Olesen committed
169
170
171
}


172
173
void Foam::boundBox::inflate(const scalar s)
{
174
    const vector ext = vector::one*s*mag();
175

176
177
    min_ -= ext;
    max_ += ext;
178
179
180
}


181
182
183
184
185
186
187
void Foam::boundBox::reduce()
{
    Foam::reduce(min_, minOp<point>());
    Foam::reduce(max_, maxOp<point>());
}


188
189
190
191
192
193
194
195
196
bool Foam::boundBox::intersect(const boundBox& bb)
{
    min_ = ::Foam::max(min_, bb.min_);
    max_ = ::Foam::min(max_, bb.max_);

    return !empty();
}


197
198
199
200
201
202
203
204
205
206
207
208
bool Foam::boundBox::intersects(const plane& pln) const
{
    // Require a full 3D box
    if (nDim() != 3)
    {
        return false;
    }

    bool above = false;
    bool below = false;

    tmp<pointField> tpts(points());
209
    const auto& pts = tpts();
210
211
212

    for (const point& p : pts)
    {
213
        if (pln.sideOfPlane(p) == plane::FRONT)
214
215
216
217
218
219
220
221
222
223
224
225
226
        {
            above = true;
        }
        else
        {
            below = true;
        }
    }

    return (above && below);
}


227
228
229
230
231
232
233
bool Foam::boundBox::contains(const UList<point>& points) const
{
    if (points.empty())
    {
        return true;
    }

234
    for (const point& p : points)
235
    {
236
        if (!contains(p))
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
        {
            return false;
        }
    }

    return true;
}


bool Foam::boundBox::containsAny(const UList<point>& points) const
{
    if (points.empty())
    {
        return true;
    }

253
    for (const point& p : points)
254
    {
255
        if (contains(p))
256
257
258
259
260
261
262
263
264
        {
            return true;
        }
    }

    return false;
}


265
Foam::point Foam::boundBox::nearest(const point& pt) const
266
267
268
269
270
271
{
    // Clip the point to the range of the bounding box
    const scalar surfPtx = Foam::max(Foam::min(pt.x(), max_.x()), min_.x());
    const scalar surfPty = Foam::max(Foam::min(pt.y(), max_.y()), min_.y());
    const scalar surfPtz = Foam::max(Foam::min(pt.z(), max_.z()), min_.z());

272
    return point(surfPtx, surfPty, surfPtz);
273
274
275
}


276
277
// * * * * * * * * * * * * * * * Ostream Operator  * * * * * * * * * * * * * //

278
Foam::Ostream& Foam::operator<<(Ostream& os, const boundBox& bb)
279
{
mattijs's avatar
mattijs committed
280
281
282
283
284
285
286
287
288
289
290
291
292
    if (os.format() == IOstream::ASCII)
    {
        os << bb.min_ << token::SPACE << bb.max_;
    }
    else
    {
        os.write
        (
            reinterpret_cast<const char*>(&bb.min_),
            sizeof(boundBox)
        );
    }

293
    os.check(FUNCTION_NAME);
mattijs's avatar
mattijs committed
294
295
296
297
    return os;
}


298
Foam::Istream& Foam::operator>>(Istream& is, boundBox& bb)
mattijs's avatar
mattijs committed
299
300
301
{
    if (is.format() == IOstream::ASCII)
    {
mattijs's avatar
mattijs committed
302
        is >> bb.min_ >> bb.max_;
mattijs's avatar
mattijs committed
303
304
305
306
307
308
309
310
311
312
    }
    else
    {
        is.read
        (
            reinterpret_cast<char*>(&bb.min_),
            sizeof(boundBox)
        );
    }

313
    is.check(FUNCTION_NAME);
mattijs's avatar
mattijs committed
314
    return is;
315
316
}

317

318
// ************************************************************************* //