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