b67ce99818bd2b8c2aa488d50288aeff0fa62ab1
[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
8 // under the terms of the GNU Lesser General Public 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 t, t1, t2, f1, f2, absf1, absf2;
238
239   aNbRoots=mySequenceOfRoots.Length();
240
241   for (j=1; j<=aNbRoots; j++) {
242     IntTools_Root& aR=mySequenceOfRoots.ChangeValue(j);
243     
244     t=aR.Root();
245     aR.Interval (t1, t2, f1, f2);
246
247     aType=aR.Type();
248     switch (aType) {
249     case 0: // Simple Root
250       if (f1>0. && f2<0.) {
251         aR.SetStateBefore(TopAbs_OUT);
252         aR.SetStateAfter (TopAbs_IN);
253       }
254     else {
255       aR.SetStateBefore(TopAbs_IN);
256       aR.SetStateAfter (TopAbs_OUT);
257     }
258       break;
259     
260     case 1: // Complete 0;
261       aR.SetStateBefore(TopAbs_ON);
262       aR.SetStateAfter (TopAbs_ON);
263       break;
264       
265     case 2: // Smart;
266       absf1=fabs(f1);
267       absf2=fabs(f2);
268       if (absf2 < myEpsNull) {
269         aR.SetStateAfter (TopAbs_ON);
270         if (f1>0.) {
271           aR.SetStateBefore(TopAbs_OUT);
272         }
273         else {
274           aR.SetStateBefore(TopAbs_IN);
275         }
276       }
277       
278       else {
279         aR.SetStateBefore(TopAbs_ON);
280         if (f2>0.) {
281           aR.SetStateAfter (TopAbs_OUT);
282         }
283         else {
284           aR.SetStateAfter (TopAbs_IN);
285         }
286       }
287       
288     default: break;
289     } // switch (aType)  
290   }
291 }
292
293 #include <GeomAdaptor_Curve.hxx>
294 #include <gp_Pnt.hxx>
295 #include <ElCLib.hxx>
296 #include <gp_Lin.hxx>
297 #include <gp_Circ.hxx>
298 #include <gp_Elips.hxx>
299 #include <gp_Hypr.hxx>
300 #include <gp_Parab.hxx>
301 #include <GeomAPI_ProjectPointOnCurve.hxx>
302
303 //=======================================================================
304 //function :Parameter
305 //purpose  :
306 //=======================================================================
307   Standard_Integer  IntTools::Parameter (const gp_Pnt& aP,
308                                          const Handle(Geom_Curve)& aCurve,
309                                          Standard_Real& aParameter)
310 {
311   Standard_Real aFirst, aLast;
312   GeomAbs_CurveType aCurveType;
313
314   aFirst=aCurve->FirstParameter();
315   aLast =aCurve->LastParameter ();
316
317   GeomAdaptor_Curve aGAC;
318   
319   aGAC.Load (aCurve, aFirst, aLast);
320
321   aCurveType=aGAC.GetType();
322   
323   switch (aCurveType){
324
325   case GeomAbs_Line:
326     {
327       gp_Lin aLin=aGAC.Line();
328       aParameter=ElCLib::Parameter (aLin, aP);
329       return 0;
330     }
331   case GeomAbs_Circle:
332     {
333       gp_Circ aCircle=aGAC.Circle();
334       aParameter=ElCLib::Parameter (aCircle, aP);
335       return 0;
336     }
337   case GeomAbs_Ellipse: 
338     {
339       gp_Elips aElips=aGAC.Ellipse();
340       aParameter=ElCLib::Parameter (aElips, aP);
341       return 0;
342     }
343   case GeomAbs_Hyperbola: 
344     {
345       gp_Hypr aHypr=aGAC.Hyperbola();
346       aParameter=ElCLib::Parameter (aHypr, aP);
347       return 0;
348     }
349   case GeomAbs_Parabola: 
350     {
351       gp_Parab aParab=aGAC.Parabola();
352       aParameter=ElCLib::Parameter (aParab, aP);
353       return 0;
354     }
355
356   case GeomAbs_BezierCurve:
357   case GeomAbs_BSplineCurve:
358     {
359       GeomAPI_ProjectPointOnCurve aProjector;
360       
361       aProjector.Init(aP, aCurve, aFirst, aLast);
362       Standard_Integer aNbPoints=aProjector.NbPoints();
363       if (aNbPoints) {
364         aParameter=aProjector.LowerDistanceParameter();
365         return 0;
366       }
367       else {
368         return 2;
369       }
370     }
371   default: 
372     break;
373   }
374   return 1;
375 }
376
377 #ifdef WNT
378 #pragma warning ( default : 4101 )
379 #endif