0025292: Face/Face intersection algorithm gives different results for different order...
[occt.git] / src / Extrema / Extrema_GenExtCC.gxx
CommitLineData
b311480e 1// Created on: 1995-07-18
2// Created by: Modelistation
3// Copyright (c) 1995-1999 Matra Datavision
973c2be1 4// Copyright (c) 1999-2014 OPEN CASCADE SAS
b311480e 5//
973c2be1 6// This file is part of Open CASCADE Technology software library.
b311480e 7//
d5f74e42 8// This library is free software; you can redistribute it and/or modify it under
9// the terms of the GNU Lesser General Public License version 2.1 as published
973c2be1 10// by the Free Software Foundation, with special exception defined in the file
11// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12// distribution for complete text of the license and disclaimer of any warranty.
b311480e 13//
973c2be1 14// Alternatively, this file may be used under the terms of Open CASCADE
15// commercial license or contractual agreement.
7fd59977 16
4bbaf12b 17#include <Extrema_GlobOptFuncCC.hxx>
18#include <math_GlobOptMin.hxx>
7fd59977 19#include <Standard_NullObject.hxx>
20#include <Standard_OutOfRange.hxx>
4bbaf12b 21#include <StdFail_NotDone.hxx>
22#include <TColStd_Array1OfReal.hxx>
7fd59977 23#include <Precision.hxx>
24
5493d334 25//=======================================================================
26//function : Extrema_GenExtCC
27//purpose :
28//=======================================================================
4bbaf12b 29Extrema_GenExtCC::Extrema_GenExtCC()
30: myLowBorder(1,2),
31 myUppBorder(1,2),
32 myDone(Standard_False)
7fd59977 33{
34}
35
5493d334 36//=======================================================================
37//function : Extrema_GenExtCC
38//purpose :
39//=======================================================================
40Extrema_GenExtCC::Extrema_GenExtCC(const Curve1& C1,
41 const Curve2& C2)
4bbaf12b 42: myLowBorder(1,2),
43 myUppBorder(1,2),
44 myDone(Standard_False)
7fd59977 45{
4bbaf12b 46 myC[0] = (Standard_Address)&C1;
47 myC[1] = (Standard_Address)&C2;
48 myLowBorder(1) = C1.FirstParameter();
49 myLowBorder(2) = C2.FirstParameter();
50 myUppBorder(1) = C1.LastParameter();
51 myUppBorder(2) = C2.LastParameter();
5493d334 52 myCurveMinTol = 1.0e-9;
7fd59977 53}
54
5493d334 55//=======================================================================
56//function : Extrema_GenExtCC
57//purpose :
58//=======================================================================
59Extrema_GenExtCC::Extrema_GenExtCC(const Curve1& C1,
60 const Curve2& C2,
61 const Standard_Real Uinf,
62 const Standard_Real Usup,
63 const Standard_Real Vinf,
64 const Standard_Real Vsup)
4bbaf12b 65: myLowBorder(1,2),
66 myUppBorder(1,2),
67 myDone(Standard_False)
7fd59977 68{
4bbaf12b 69 myC[0] = (Standard_Address)&C1;
70 myC[1] = (Standard_Address)&C2;
71 myLowBorder(1) = Uinf;
72 myLowBorder(2) = Vinf;
73 myUppBorder(1) = Usup;
74 myUppBorder(2) = Vsup;
5493d334 75 myCurveMinTol = 1.0e-9;
7fd59977 76}
77
5493d334 78//=======================================================================
79//function : SetParams
80//purpose :
81//=======================================================================
82void Extrema_GenExtCC::SetParams(const Curve1& C1,
83 const Curve2& C2,
84 const Standard_Real Uinf,
85 const Standard_Real Usup,
86 const Standard_Real Vinf,
87 const Standard_Real Vsup)
7fd59977 88{
4bbaf12b 89 myC[0] = (Standard_Address)&C1;
90 myC[1] = (Standard_Address)&C2;
91 myLowBorder(1) = Uinf;
92 myLowBorder(2) = Vinf;
93 myUppBorder(1) = Usup;
94 myUppBorder(2) = Vsup;
7fd59977 95}
96
5493d334 97//=======================================================================
98//function : SetTolerance
99//purpose :
100//=======================================================================
101void Extrema_GenExtCC::SetTolerance(Standard_Real theTol)
102{
103 myCurveMinTol = theTol;
104}
105
106//=======================================================================
107//function : Perform
108//purpose :
109//=======================================================================
110void Extrema_GenExtCC::Perform()
7fd59977 111{
112 myDone = Standard_False;
113
4bbaf12b 114 Curve1 &C1 = *(Curve1*)myC[0];
115 Curve2 &C2 = *(Curve2*)myC[1];
116
117 Standard_Integer aNbInter[2];
118 aNbInter[0] = C1.NbIntervals(GeomAbs_C2);
119 aNbInter[1] = C2.NbIntervals(GeomAbs_C2);
120 TColStd_Array1OfReal anIntervals1(1, aNbInter[0] + 1);
121 TColStd_Array1OfReal anIntervals2(1, aNbInter[1] + 1);
122 C1.Intervals(anIntervals1, GeomAbs_C2);
123 C2.Intervals(anIntervals2, GeomAbs_C2);
124
125 math_MultipleVarFunction *aFunc = new Extrema_GlobOptFuncCCC2(C1, C2);
126 math_GlobOptMin aFinder(aFunc, myLowBorder, myUppBorder);
5493d334 127 Standard_Real aDiscTol = 1.0e-2;
128 Standard_Real aValueTol = 1.0e-2;
129 Standard_Real aSameTol = myCurveMinTol / (aDiscTol);
130 aFinder.SetTol(aDiscTol, aSameTol);
4bbaf12b 131
132 Standard_Integer i,j,k;
133 math_Vector aFirstBorderInterval(1,2);
134 math_Vector aSecondBorderInterval(1,2);
135 Standard_Real aF = RealLast(); // best functional value
136 Standard_Real aCurrF = RealLast(); // current functional value computed on current interval
137 for(i = 1; i <= aNbInter[0]; i++)
138 {
139 for(j = 1; j <= aNbInter[1]; j++)
140 {
141 aFirstBorderInterval(1) = anIntervals1(i);
142 aFirstBorderInterval(2) = anIntervals2(j);
143 aSecondBorderInterval(1) = anIntervals1(i + 1);
144 aSecondBorderInterval(2) = anIntervals2(j + 1);
145
146 aFinder.SetLocalParams(aFirstBorderInterval, aSecondBorderInterval);
147 aFinder.Perform();
148
149 aCurrF = aFinder.GetF();
5493d334 150 if (aCurrF < aF + aSameTol * aValueTol)
4bbaf12b 151 {
5493d334 152 if (aCurrF > aF - aSameTol * aValueTol)
4bbaf12b 153 {
5493d334 154 if (aCurrF < aF)
155 aF = aCurrF;
156
4bbaf12b 157 math_Vector sol(1,2);
5493d334 158 Standard_Integer myTmpSolCount = aFinder.NbExtrema();
4bbaf12b 159 for(k = 1; k <= myTmpSolCount; k++)
160 {
161 aFinder.Points(k, sol);
162 myPoints1.Append(sol(1));
163 myPoints2.Append(sol(2));
164 }
165 mySolCount += myTmpSolCount;
5493d334 166 } // if (aCurrF > aF - aSameTol * aValueTol)
4bbaf12b 167 else
168 {
169 aF = aCurrF;
170 mySolCount = aFinder.NbExtrema();
171 myPoints1.Clear();
172 myPoints2.Clear();
173 math_Vector sol(1,2);
174 for(k = 1; k <= mySolCount; k++)
175 {
176 aFinder.Points(k, sol);
177 myPoints1.Append(sol(1));
178 myPoints2.Append(sol(2));
179 }
180 } // else
5493d334 181 } //if (aCurrF < aF + aSameTol * aValueTol)
7fd59977 182 }
183 }
184
4bbaf12b 185 // Clear solutions clusters if it is necessary.
186 for(i = 1; i <= mySolCount - 1; i++)
187 {
188 for(j = i + 1; j <= mySolCount; j++)
189 {
5493d334 190 if (Abs(myPoints1(i) - myPoints1(j)) < (myUppBorder(1) - myLowBorder(1)) * Precision::Confusion() &&
191 Abs(myPoints2(i) - myPoints2(j)) < (myUppBorder(2) - myLowBorder(2)) * Precision::Confusion())
4bbaf12b 192 {
5493d334 193 // Points with indexes i and j is in same cluster, delete j point from extrema array.
4bbaf12b 194 myPoints1.Remove(j);
195 myPoints2.Remove(j);
196 j--;
197 mySolCount--;
198 }
7fd59977 199 }
4bbaf12b 200 }
7fd59977 201
4bbaf12b 202 delete aFunc;
7fd59977 203 myDone = Standard_True;
204}
7fd59977 205
5493d334 206//=======================================================================
207//function : IsDone
208//purpose :
209//=======================================================================
210Standard_Boolean Extrema_GenExtCC::IsDone() const
4bbaf12b 211{
212 return myDone;
213}
7fd59977 214
5493d334 215//=======================================================================
216//function : NbExt
217//purpose :
218//=======================================================================
219Standard_Integer Extrema_GenExtCC::NbExt() const
7fd59977 220{
221 StdFail_NotDone_Raise_if (!myDone, "Extrema_GenExtCC::NbExt()")
4bbaf12b 222
223 return mySolCount;
7fd59977 224}
7fd59977 225
5493d334 226//=======================================================================
227//function : SquareDistance
228//purpose :
229//=======================================================================
230Standard_Real Extrema_GenExtCC::SquareDistance(const Standard_Integer N) const
7fd59977 231{
232 StdFail_NotDone_Raise_if (!myDone, "Extrema_GenExtCC::SquareDistance()")
233 Standard_OutOfRange_Raise_if ((N < 1 || N > NbExt()), "Extrema_GenExtCC::SquareDistance()")
4bbaf12b 234
235 return Tool1::Value(*((Curve1*)myC[0]), myPoints1(N)).SquareDistance(Tool2::Value(*((Curve2*)myC[1]), myPoints2(N)));
7fd59977 236}
7fd59977 237
5493d334 238//=======================================================================
239//function : Points
240//purpose :
241//=======================================================================
242void Extrema_GenExtCC::Points(const Standard_Integer N,
243 POnC& P1,
244 POnC& P2) const
7fd59977 245{
4bbaf12b 246 StdFail_NotDone_Raise_if (!myDone, "Extrema_GenExtCC::Points()")
247 Standard_OutOfRange_Raise_if ((N < 1 || N > NbExt()), "Extrema_GenExtCC::Points()")
248
249 P1.SetValues(myPoints1(N), Tool1::Value(*((Curve1*)myC[0]), myPoints1(N)));
250 P2.SetValues(myPoints2(N), Tool2::Value(*((Curve2*)myC[1]), myPoints2(N)));
251}