0029915: Porting to VC 2017 : Regressions in Modeling Algorithms on VC 2017
[occt.git] / src / Bnd / Bnd_Range.hxx
1 // Created on: 2016-06-07
2 // Created by: Nikolai BUKHALOV
3 // Copyright (c) 2016 OPEN CASCADE SAS
4 //
5 // This file is part of Open CASCADE Technology software library.
6 //
7 // This library is free software; you can redistribute it and/or modify it under
8 // the terms of the GNU Lesser General Public License version 2.1 as published
9 // by the Free Software Foundation, with special exception defined in the file
10 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
11 // distribution for complete text of the license and disclaimer of any warranty.
12 //
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
15
16 #ifndef _Bnd_Range_HeaderFile
17 #define _Bnd_Range_HeaderFile
18
19 #include <Standard_Real.hxx>
20 #include <Standard_ConstructionError.hxx>
21
22 #include <NCollection_List.hxx>
23
24 //! This class describes a range in 1D space restricted
25 //! by two real values.
26 //! A range can be void indicating there is no point included in the range.
27 class Bnd_Range
28 {
29 public:
30
31   //! Default constructor. Creates VOID range.
32   Bnd_Range() : myFirst(0.0), myLast(-1.0) {}
33
34   //! Constructor. Never creates VOID range.
35   Bnd_Range(const Standard_Real theMin, const Standard_Real theMax) : 
36                                                     myFirst(theMin), myLast(theMax)
37   {
38     if(myLast < myFirst)
39       throw Standard_ConstructionError("Last < First");
40   }
41
42   //! Replaces <this> with common-part of <this> and theOther
43   Standard_EXPORT void Common(const Bnd_Range& theOther);
44   
45   //! Joins *this and theOther to one interval.
46   //! Replaces *this to the result.
47   //! Returns false if the operation cannot be done (e.g.
48   //! input arguments are empty or separated).
49   //! @sa use method ::Add() to merge two ranges unconditionally
50   Standard_EXPORT Standard_Boolean Union(const Bnd_Range& theOther);
51
52   //! Splits <this> to several sub-ranges by theVal value
53   //! (e.g. range [3, 15] will be split by theVal==5 to the two
54   //! ranges: [3, 5] and [5, 15]). New ranges will be pushed to
55   //! theList (theList must be initialized correctly before
56   //! calling this method).
57   //! If thePeriod != 0.0 then at least one boundary of
58   //! new ranges (if <*this> intersects theVal+k*thePeriod) will be equal to
59   //! theVal+thePeriod*k, where k is an integer number (k = 0, +/-1, +/-2, ...).
60   //! (let thePeriod in above example be 4 ==> we will obtain
61   //! four ranges: [3, 5], [5, 9], [9, 13] and [13, 15].
62   Standard_EXPORT void Split(const Standard_Real theVal,
63                              NCollection_List<Bnd_Range>& theList,
64                              const Standard_Real thePeriod = 0.0) const;
65
66   //! Checks if <this> intersects values like
67   //!   theVal+k*thePeriod, where k is an integer number (k = 0, +/-1, +/-2, ...).
68   //! Returns:
69   //!     0 - if <this> does not intersect the theVal+k*thePeriod.
70   //!     1 - if <this> intersects theVal+k*thePeriod.
71   //!     2 - if myFirst or/and myLast are equal to theVal+k*thePeriod.
72   //!
73   //! ATTENTION!!!
74   //!  If (myFirst == myLast) then this function will return only either 0 or 2.
75   Standard_EXPORT Standard_Integer
76                       IsIntersected(const Standard_Real theVal,
77                                     const Standard_Real thePeriod = 0.0) const;
78
79   //! Extends <this> to include theParameter
80   void Add(const Standard_Real theParameter)
81   {
82     if(IsVoid())
83     {
84       myFirst = myLast = theParameter;
85       return;
86     }
87
88     myFirst = Min(myFirst, theParameter);
89     myLast = Max(myLast, theParameter);
90   }
91
92   //! Extends this range to include both ranges.
93   //! @sa use method ::Union() to check if two ranges overlap method merging
94   void Add (const Bnd_Range& theRange)
95   {
96     if (theRange.IsVoid())
97     {
98       return;
99     }
100     else if (IsVoid())
101     {
102       *this = theRange;
103     }
104     myFirst = Min(myFirst, theRange.myFirst);
105     myLast  = Max(myLast,  theRange.myLast);
106   }
107
108   //! Obtain MIN boundary of <this>.
109   //! If <this> is VOID the method returns false.
110   Standard_Boolean GetMin(Standard_Real& thePar) const
111   {
112     if(IsVoid())
113     {
114       return Standard_False;
115     }
116
117     thePar = myFirst;
118     return Standard_True;
119   }
120
121   //! Obtain MAX boundary of <this>.
122   //! If <this> is VOID the method returns false.
123   Standard_Boolean GetMax(Standard_Real& thePar) const
124   {
125     if(IsVoid())
126     {
127       return Standard_False;
128     }
129
130     thePar = myLast;
131     return Standard_True;
132   }
133
134   //! Obtain first and last boundary of <this>.
135   //! If <this> is VOID the method returns false.
136   Standard_Boolean GetBounds(Standard_Real& theFirstPar,
137                              Standard_Real& theLastPar) const
138   {
139     if(IsVoid())
140     {
141       return Standard_False;
142     }
143
144     theFirstPar = myFirst;
145     theLastPar = myLast;
146     return Standard_True;
147   }
148
149   //! Obtain theParameter satisfied to the equation
150   //!     (theParameter-MIN)/(MAX-MIN) == theLambda.
151   //!   *  theLambda == 0 --> MIN boundary will be returned;
152   //!   *  theLambda == 0.5 --> Middle point will be returned;
153   //!   *  theLambda == 1 --> MAX boundary will be returned;
154   //!   *  theLambda < 0 --> the value less than MIN will be returned;
155   //!   *  theLambda > 1 --> the value greater than MAX will be returned.
156   //! If <this> is VOID the method returns false.
157   Standard_Boolean GetIntermediatePoint(const Standard_Real theLambda,
158                                         Standard_Real& theParameter) const
159   {
160     if (IsVoid())
161     {
162       return Standard_False;
163     }
164
165     theParameter = myFirst + theLambda*(myLast - myFirst);
166     return Standard_True;
167   }
168   
169   //! Returns range value (MAX-MIN). Returns negative value for VOID range.
170   Standard_Real Delta() const
171   {
172     return (myLast - myFirst);
173   }
174
175   //! Is <this> initialized.
176   Standard_Boolean IsVoid() const
177   {
178     return (myLast < myFirst);
179   }
180
181   //! Initializes <this> by default parameters. Makes <this> VOID.
182   void SetVoid()
183   {
184     myLast = -1.0;
185     myFirst = 0.0;
186   }
187
188   //! Extends this to the given value (in both side)
189   void Enlarge(const Standard_Real theDelta)
190   {
191     if (IsVoid())
192     {
193       return;
194     }
195
196     myFirst -= theDelta;
197     myLast += theDelta;
198   }
199
200   //! Returns the copy of <*this> shifted by theVal
201   Bnd_Range Shifted(const Standard_Real theVal) const
202   {
203     return !IsVoid() ? Bnd_Range(myFirst + theVal, myLast + theVal) : Bnd_Range();
204   }
205
206   //! Shifts <*this> by theVal
207   void Shift(const Standard_Real theVal)
208   {
209     if (!IsVoid())
210     {
211       myFirst += theVal;
212       myLast  += theVal;
213     }
214   }
215
216   //! Trims the First value in range by the given lower limit.
217   //! Marks range as Void if the given Lower value is greater than range Max.
218   void TrimFrom (const Standard_Real theValLower)
219   {
220     if (!IsVoid())
221     {
222       myFirst = Max (myFirst, theValLower);
223     }
224   }
225
226   //! Trim the Last value in range by the given Upper limit.
227   //! Marks range as Void if the given Upper value is smaller than range Max.
228   void TrimTo (const Standard_Real theValUpper)
229   {
230     if (!IsVoid())
231     {
232       myLast = Min (myLast, theValUpper);
233     }
234   }
235
236   //! Returns True if the value is out of this range.
237   Standard_Boolean IsOut (Standard_Real theValue) const
238   {
239     return IsVoid()
240         || theValue < myFirst
241         || theValue > myLast;
242   }
243
244   //! Returns True if the given range is out of this range.
245   Standard_Boolean IsOut (const Bnd_Range& theRange) const
246   {
247     return IsVoid()
248         || theRange.IsVoid()
249         || theRange.myLast  < myFirst
250         || theRange.myFirst > myLast;
251   }
252
253   //! Returns TRUE if theOther is equal to <*this>
254   Standard_Boolean operator==(const Bnd_Range& theOther) const
255   {
256     return ((myFirst == theOther.myFirst) && (myLast == theOther.myLast));
257   }
258
259 private:
260
261   Standard_Real myFirst; //!< Start of range
262   Standard_Real myLast;  //!< End   of range
263
264 };
265
266 #endif