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