0031668: Visualization - WebGL sample doesn't work on Emscripten 1.39
[occt.git] / src / Bnd / Bnd_Range.cxx
CommitLineData
d30895f5 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
17#include <Bnd_Range.hxx>
0904aa63 18#include <Standard_Dump.hxx>
d30895f5 19
20//=======================================================================
21//function : Common
22//purpose :
23//=======================================================================
24void Bnd_Range::Common(const Bnd_Range& theOther)
25{
26 if(theOther.IsVoid())
27 {
28 SetVoid();
29 }
30
31 if(IsVoid())
32 {
33 return;
34 }
35
36 myFirst = Max(myFirst, theOther.myFirst);
37 myLast = Min(myLast, theOther.myLast);
38}
261b7d9e 39
40//=======================================================================
41//function : Union
42//purpose :
43//=======================================================================
44Standard_Boolean Bnd_Range::Union(const Bnd_Range& theOther)
45{
46 if (IsVoid() || theOther.IsVoid())
47 return Standard_False;
48
49 if (myLast < theOther.myFirst)
50 return Standard_False;
51
52 if (myFirst > theOther.myLast)
53 return Standard_False;
54
55 myFirst = Min(myFirst, theOther.myFirst);
56 myLast = Max(myLast, theOther.myLast);
57
58 return Standard_True;
59}
60
61//=======================================================================
62//function : IsIntersected
63//purpose :
64//=======================================================================
65Standard_Integer Bnd_Range::IsIntersected(const Standard_Real theVal,
66 const Standard_Real thePeriod) const
67{
68 if (IsVoid())
69 return Standard_False;
70
71 const Standard_Real aPeriod = Abs(thePeriod);
72 const Standard_Real aDF = myFirst - theVal,
73 aDL = myLast - theVal;
74
75 if (aPeriod <= RealSmall())
76 {
77 const Standard_Real aDelta = aDF*aDL;
78 if (IsEqual(aDelta, 0.0))
79 return 2;
80
81 if (aDelta > 0.0)
82 return 0;
83
84 return 1;
85 }
86
87 //If <this> intersects theVal then there exists an integer
88 //number N such as
89 // (myFirst <= theVal+aPeriod*N <= myLast) <=>
90 // ((myFirst-theVal)/aPeriod <= N <= (myLast-theVal)/aPeriod).
91 //I.e. the interval [aDF/aPeriod, aDL/aPeriod] must contain at least one
92 //integer number.
93 //In this case, Floor(aDF/aPeriod) and Floor(aDL/aPeriod)
94 //return different values or aDF/aPeriod (aDL/aPeriod)
95 //is strictly integer number.
96 //Examples:
97 // 1. (aDF/aPeriod==2.8, aDL/aPeriod==3.5 =>
98 // Floor(aDF/aPeriod) == 2, Floor(aDL/aPeriod) == 3.
99 // 2. aDF/aPeriod==2.0, aDL/aPeriod==2.6 =>
100 // Floor(aDF/aPeriod) == Floor(aDL/aPeriod) == 2.
101
102 const Standard_Real aVal1 = aDF / aPeriod,
103 aVal2 = aDL / aPeriod;
104 const Standard_Integer aPar1 = static_cast<Standard_Integer>(Floor(aVal1));
105 const Standard_Integer aPar2 = static_cast<Standard_Integer>(Floor(aVal2));
106 if (aPar1 != aPar2)
107 {//Interval (myFirst, myLast] intersects seam-edge
108 if (IsEqual(aVal2, static_cast<Standard_Real>(aPar2)))
109 {//aVal2 is an integer number => myLast lies ON the "seam-edge"
110 return 2;
111 }
112
113 return 1;
114 }
115
116 //Here, aPar1 == aPar2.
117
118 if (IsEqual(aVal1, static_cast<Standard_Real>(aPar1)))
119 {//aVal1 is an integer number => myFirst lies ON the "seam-edge"
120 return 2;
121 }
122
123#if 0
124 // This check is excess because always myFirst <= myLast.
125 // So, this condition is never satisfied.
126 if (IsEqual(aVal2, static_cast<Standard_Real>(aPar2)))
127 {//aVal2 is an integer number => myLast lies ON the "seam-edge"
128 return 2;
129 }
130#endif
131
132 return 0;
133}
134
135//=======================================================================
136//function : Split
137//purpose :
138//=======================================================================
139void Bnd_Range::Split(const Standard_Real theVal,
140 NCollection_List<Bnd_Range>& theList,
141 const Standard_Real thePeriod) const
142{
143 const Standard_Real aPeriod = Abs(thePeriod);
144 if (IsIntersected(theVal, aPeriod) != 1)
145 {
146 theList.Append(*this);
147 return;
148 }
149
150 const Standard_Boolean isPeriodic = (aPeriod > 0.0);
151
152 if (!isPeriodic)
153 {
154 theList.Append(Bnd_Range(myFirst, theVal));
155 theList.Append(Bnd_Range(theVal, myLast));
156 return;
157 }
158
159 Standard_Real aValPrev = theVal + aPeriod*Ceiling((myFirst - theVal) / aPeriod);
160
161 //Now, (myFirst <= aValPrev < myFirst+aPeriod).
162
163 if (aValPrev > myFirst)
164 {
165 theList.Append(Bnd_Range(myFirst, aValPrev));
166 }
167
168 for (Standard_Real aVal = aValPrev+aPeriod; aVal <= myLast; aVal += aPeriod)
169 {
170 theList.Append(Bnd_Range(aValPrev, aVal));
171 aValPrev = aVal;
172 }
173
174 if (aValPrev < myLast)
175 {
176 theList.Append(Bnd_Range(aValPrev, myLast));
177 }
0904aa63 178}
179
180// =======================================================================
181// function : DumpJson
182// purpose :
183// =======================================================================
bc73b006 184void Bnd_Range::DumpJson (Standard_OStream& theOStream, Standard_Integer) const
0904aa63 185{
bc73b006 186 OCCT_DUMP_CLASS_BEGIN (theOStream, Bnd_Range)
0904aa63 187
bc73b006 188 OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myFirst)
189 OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myLast)
0904aa63 190}