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