0023952: Improving thread-safety of intersections, approximations and other modeling...
[occt.git] / src / IntTools / IntTools.cxx
CommitLineData
b311480e 1// Created on: 2000-08-01
2// Created by: Peter KURNEV
3// Copyright (c) 2000-2012 OPEN CASCADE SAS
4//
5// The content of this file is subject to the Open CASCADE Technology Public
6// License Version 6.5 (the "License"). You may not use the content of this file
7// except in compliance with the License. Please obtain a copy of the License
8// at http://www.opencascade.org and read it completely before using this file.
9//
10// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
11// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
12//
13// The Original Code and all software distributed under the License is
14// distributed on an "AS IS" basis, without warranty of any kind, and the
15// Initial Developer hereby disclaims all such warranties, including without
16// limitation, any warranties of merchantability, fitness for a particular
17// purpose or non-infringement. Please see the License for the specific terms
18// and conditions governing the rights and limitations under the License.
19
7fd59977 20
21
22#include <IntTools.ixx>
23#include <GProp_GProps.hxx>
24#include <BRepGProp.hxx>
25#include <BRep_Tool.hxx>
26#include <IntTools_Root.hxx>
27#include <IntTools_Array1OfRoots.hxx>
28#include <IntTools_Compare.hxx>
29#include <IntTools_QuickSort.hxx>
30#include <IntTools_Root.hxx>
31
32#include <gce_MakeCirc.hxx>
33#include <gp_Circ.hxx>
34#include <BRepAdaptor_Curve.hxx>
35#include <IntTools_CArray1OfReal.hxx>
36#include <TColStd_ListOfReal.hxx>
37#include <GCPnts_QuasiUniformDeflection.hxx>
38#include <TColStd_ListIteratorOfListOfReal.hxx>
39#include <gce_ErrorType.hxx>
40
41#ifdef WNT
42#pragma warning ( disable : 4101 )
43#endif
44//=======================================================================
45//function : IntTools::GetRadius
46//purpose :
47//=======================================================================
48 Standard_Integer IntTools::GetRadius(const BRepAdaptor_Curve& C,
49 const Standard_Real t1,
50 const Standard_Real t3,
51 Standard_Real& aR)
52{
53 GeomAbs_CurveType aType=C.GetType();
54 if (aType==GeomAbs_Line) {
55 return 1;
56 }
57
58 if (aType==GeomAbs_Circle) {
59 gp_Circ aCrc=C.Circle();
60 aR=aCrc.Radius();
61 return 0;
62 }
63
64 Standard_Real t2;
65 gp_Pnt P1, P2, P3;
66
67 t2=0.5*(t1+t3);
68
69 P1=C.Value(t1);
70 P2=C.Value(t2);
71 P3=C.Value(t3);
72 //
73 //
74 gce_MakeCirc aMakeCirc(P1, P2, P3);
75 gce_ErrorType anErrorType;
76
77 anErrorType=aMakeCirc.Status();
78
79 if (!aMakeCirc.IsDone()) {
80
81 if (anErrorType==gce_ConfusedPoints ||
82 anErrorType==gce_IntersectionError ||
83 anErrorType==gce_ColinearPoints) {//modified by NIZNHY-PKV Fri Sep 24 09:54:05 2004ft
84 return 2;
85 }
86 return -1;
87 }
88 //
89 //
90 gp_Circ aCirc=aMakeCirc.Value();
91 aR=aCirc.Radius();
92
93 return 0;
94}
95
96//=======================================================================
97//function : PrepareArgs
98//purpose :
99//=======================================================================
100 Standard_Integer IntTools::PrepareArgs(BRepAdaptor_Curve& C,
101 const Standard_Real Tmax,
102 const Standard_Real Tmin,
103 const Standard_Integer Discret,
104 const Standard_Real Deflection,
105 IntTools_CArray1OfReal& anArgs)
106{
107
108 TColStd_ListOfReal aPars;
109 Standard_Real dt, tCurrent, tNext, aR, anAbsDeflection;
110 Standard_Integer ip, i, j, aNbDeflectionPoints, aDiscretBis;
111 Standard_Boolean aRFlag;
112
113 GeomAbs_CurveType aCurveType;
114 aCurveType=C.GetType();
115
116 dt=(Tmax-Tmin)/Discret;
117 aRFlag=(dt > 1.e-5);
118 for (i=1; i<=Discret; i++) {
119 tCurrent=Tmin+(i-1)*dt;
120 aPars.Append(tCurrent);
121 tNext=tCurrent+dt;
122 if (i==Discret)
123 tNext=Tmax;
124 ///////////////////////////////////////////////////
125 if (!aRFlag) {
126 continue;
127 }
128 if (aCurveType==GeomAbs_BSplineCurve||
129 aCurveType==GeomAbs_BezierCurve ||
130 aCurveType==GeomAbs_Ellipse ||
131 aCurveType==GeomAbs_OtherCurve) { //modified by NIZNHY-PKV Fri Sep 24 09:52:42 2004ft
132 continue;
133 }
134 //
135 ip=IntTools::GetRadius (C, tCurrent, tNext, aR);
136 if (ip<0) {
137 return 1;
138 }
139 //
140 if (!ip) {
141 anAbsDeflection=Deflection*aR;
142 GCPnts_QuasiUniformDeflection anUD;
143 anUD.Initialize (C, anAbsDeflection, tCurrent, tNext);
144 if (!anUD.IsDone()) {
145 return 2;
146 }
147
148 aNbDeflectionPoints=anUD.NbPoints();
149 if (aNbDeflectionPoints > 2) {
150 aNbDeflectionPoints--;
151 for (j=2; j<=aNbDeflectionPoints; j++) {
152 tCurrent=anUD.Parameter(j);
153 aPars.Append(tCurrent);
154 }
155 }
156 }
157 }
158
159 aPars.Append(Tmax);
160 aDiscretBis=aPars.Extent();
161 anArgs.Resize(aDiscretBis);
162 TColStd_ListIteratorOfListOfReal anIt(aPars);
163 for (i=0; anIt.More(); anIt.Next(), i++) {
164 anArgs(i)=anIt.Value();
165 }
166 return 0;
167}
168
169//=======================================================================
170//function : IntTools::Length
171//purpose :
172//=======================================================================
173 Standard_Real IntTools::Length (const TopoDS_Edge& anEdge)
174{
175 Standard_Real aLength=0;
176
177 if (!BRep_Tool::Degenerated(anEdge) &&
178 BRep_Tool::IsGeometric(anEdge)) {
179
180 GProp_GProps Temp;
181 BRepGProp::LinearProperties(anEdge, Temp);
182 aLength = Temp.Mass();
183 }
184 return aLength;
185}
186
187//=======================================================================
188//function : RemoveIdenticalRoots
189//purpose :
190//=======================================================================
191 void IntTools::RemoveIdenticalRoots(IntTools_SequenceOfRoots& aSR,
192 const Standard_Real anEpsT)
193{
194 Standard_Integer aNbRoots, j, k;
195 Standard_Real anEpsT2=0.5*anEpsT;
196 aNbRoots=aSR.Length();
197 for (j=1; j<=aNbRoots; j++) {
198 const IntTools_Root& aRj=aSR(j);
199 for (k=j+1; k<=aNbRoots; k++) {
200 const IntTools_Root& aRk=aSR(k);
201 if (fabs (aRj.Root()-aRk.Root()) < anEpsT2) {
202 aSR.Remove(k);
203 aNbRoots=aSR.Length();
204 }
205 }
206 }
207}
208
209//=======================================================================
210//function : SortRoots
211//purpose :
212//=======================================================================
213 void IntTools::SortRoots(IntTools_SequenceOfRoots& mySequenceOfRoots,
214 const Standard_Real myEpsT)
215{
216 Standard_Integer j, aNbRoots;
217
218 aNbRoots=mySequenceOfRoots.Length();
219
220 IntTools_Array1OfRoots anArray1OfRoots(1, aNbRoots);
221 IntTools_Compare aComparator(myEpsT);
222
223 for (j=1; j<=aNbRoots; j++) {
224 anArray1OfRoots(j)=mySequenceOfRoots(j);
225 }
226
227 IntTools_QuickSort aQS;
228 aQS.Sort(anArray1OfRoots, aComparator);
229
230 mySequenceOfRoots.Clear();
231 for (j=1; j<=aNbRoots; j++) {
232 mySequenceOfRoots.Append(anArray1OfRoots(j));
233 }
234}
235//=======================================================================
236//function :FindRootStates
237//purpose :
238//=======================================================================
239 void IntTools::FindRootStates(IntTools_SequenceOfRoots& mySequenceOfRoots,
240 const Standard_Real myEpsNull)
241{
242 Standard_Integer aType, j, aNbRoots;
243 Standard_Real t, t1, t2, f1, f2, absf1, absf2;
244
245 aNbRoots=mySequenceOfRoots.Length();
246
247 for (j=1; j<=aNbRoots; j++) {
248 IntTools_Root& aR=mySequenceOfRoots.ChangeValue(j);
249
250 t=aR.Root();
251 aR.Interval (t1, t2, f1, f2);
252
253 aType=aR.Type();
254 switch (aType) {
255 case 0: // Simple Root
256 if (f1>0. && f2<0.) {
257 aR.SetStateBefore(TopAbs_OUT);
258 aR.SetStateAfter (TopAbs_IN);
259 }
260 else {
261 aR.SetStateBefore(TopAbs_IN);
262 aR.SetStateAfter (TopAbs_OUT);
263 }
264 break;
265
266 case 1: // Complete 0;
267 aR.SetStateBefore(TopAbs_ON);
268 aR.SetStateAfter (TopAbs_ON);
269 break;
270
271 case 2: // Smart;
272 absf1=fabs(f1);
273 absf2=fabs(f2);
274 if (absf2 < myEpsNull) {
275 aR.SetStateAfter (TopAbs_ON);
276 if (f1>0.) {
277 aR.SetStateBefore(TopAbs_OUT);
278 }
279 else {
280 aR.SetStateBefore(TopAbs_IN);
281 }
282 }
283
284 else {
285 aR.SetStateBefore(TopAbs_ON);
286 if (f2>0.) {
287 aR.SetStateAfter (TopAbs_OUT);
288 }
289 else {
290 aR.SetStateAfter (TopAbs_IN);
291 }
292 }
293
294 default: break;
295 } // switch (aType)
296 }
297}
298
299#include <GeomAdaptor_Curve.hxx>
300#include <gp_Pnt.hxx>
301#include <ElCLib.hxx>
302#include <gp_Lin.hxx>
303#include <gp_Circ.hxx>
304#include <gp_Elips.hxx>
305#include <gp_Hypr.hxx>
306#include <gp_Parab.hxx>
307#include <GeomAPI_ProjectPointOnCurve.hxx>
308
309//=======================================================================
310//function :Parameter
311//purpose :
312//=======================================================================
313 Standard_Integer IntTools::Parameter (const gp_Pnt& aP,
314 const Handle(Geom_Curve)& aCurve,
315 Standard_Real& aParameter)
316{
317 Standard_Real aFirst, aLast;
318 GeomAbs_CurveType aCurveType;
319
320 aFirst=aCurve->FirstParameter();
321 aLast =aCurve->LastParameter ();
322
323 GeomAdaptor_Curve aGAC;
324
325 aGAC.Load (aCurve, aFirst, aLast);
326
327 aCurveType=aGAC.GetType();
328
329 switch (aCurveType){
330
331 case GeomAbs_Line:
332 {
333 gp_Lin aLin=aGAC.Line();
334 aParameter=ElCLib::Parameter (aLin, aP);
335 return 0;
336 }
337 case GeomAbs_Circle:
338 {
339 gp_Circ aCircle=aGAC.Circle();
340 aParameter=ElCLib::Parameter (aCircle, aP);
341 return 0;
342 }
343 case GeomAbs_Ellipse:
344 {
345 gp_Elips aElips=aGAC.Ellipse();
346 aParameter=ElCLib::Parameter (aElips, aP);
347 return 0;
348 }
349 case GeomAbs_Hyperbola:
350 {
351 gp_Hypr aHypr=aGAC.Hyperbola();
352 aParameter=ElCLib::Parameter (aHypr, aP);
353 return 0;
354 }
355 case GeomAbs_Parabola:
356 {
357 gp_Parab aParab=aGAC.Parabola();
358 aParameter=ElCLib::Parameter (aParab, aP);
359 return 0;
360 }
361
362 case GeomAbs_BezierCurve:
363 case GeomAbs_BSplineCurve:
364 {
365 GeomAPI_ProjectPointOnCurve aProjector;
366
367 aProjector.Init(aP, aCurve, aFirst, aLast);
368 Standard_Integer aNbPoints=aProjector.NbPoints();
369 if (aNbPoints) {
370 aParameter=aProjector.LowerDistanceParameter();
371 return 0;
372 }
373 else {
374 return 2;
375 }
376 break;
377 }
378 default:
379 break;
380 }
381 return 1;
382}
383
384#ifdef WNT
385#pragma warning ( default : 4101 )
386#endif