0027032: [Regression to 6.9.1] Result of bcut has the same volume as the object
[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_OffsetCurve ||
123         aCurveType==GeomAbs_Ellipse ||
124         aCurveType==GeomAbs_OtherCurve) { //modified by NIZNHY-PKV Fri Sep 24 09:52:42 2004ft
125       continue;
126     }
127     //
128     ip=IntTools::GetRadius (C, tCurrent, tNext, aR);  
129     if (ip<0) {
130       return 1;
131     }
132     //
133     if (!ip) {
134       anAbsDeflection=Deflection*aR;
135       GCPnts_QuasiUniformDeflection anUD;
136       anUD.Initialize (C, anAbsDeflection, tCurrent, tNext);
137       if (!anUD.IsDone()) {
138         return 2;
139       }
140       
141       aNbDeflectionPoints=anUD.NbPoints();
142       if (aNbDeflectionPoints > 2) {
143         aNbDeflectionPoints--;
144         for (j=2; j<=aNbDeflectionPoints; j++) {
145           tCurrent=anUD.Parameter(j);
146           aPars.Append(tCurrent);
147         }
148       }
149     }
150   }
151
152   aPars.Append(Tmax);
153   aDiscretBis=aPars.Extent();
154   anArgs.Resize(aDiscretBis);
155   TColStd_ListIteratorOfListOfReal anIt(aPars);
156   for (i=0; anIt.More(); anIt.Next(), i++) {
157     anArgs(i)=anIt.Value();
158   }
159   return 0;
160 }
161
162 //=======================================================================
163 //function : IntTools::Length
164 //purpose  : 
165 //=======================================================================
166   Standard_Real IntTools::Length (const TopoDS_Edge& anEdge)
167 {
168   Standard_Real aLength=0;
169
170   if (!BRep_Tool::Degenerated(anEdge) &&
171       BRep_Tool::IsGeometric(anEdge)) {
172
173     GProp_GProps Temp;
174     BRepGProp::LinearProperties(anEdge, Temp);
175     aLength = Temp.Mass();
176   }
177   return aLength;
178 }
179   
180 //=======================================================================
181 //function : RemoveIdenticalRoots 
182 //purpose  : 
183 //=======================================================================
184   void IntTools::RemoveIdenticalRoots(IntTools_SequenceOfRoots& aSR,
185                                       const Standard_Real anEpsT)
186 {
187   Standard_Integer aNbRoots, j, k;
188   Standard_Real anEpsT2=0.5*anEpsT;
189   aNbRoots=aSR.Length();
190   for (j=1; j<=aNbRoots; j++) { 
191     const IntTools_Root& aRj=aSR(j);
192     for (k=j+1; k<=aNbRoots; k++) {
193       const IntTools_Root& aRk=aSR(k);
194       if (fabs (aRj.Root()-aRk.Root()) < anEpsT2) {
195         aSR.Remove(k);
196         aNbRoots=aSR.Length();
197       }
198     }
199   }
200 }
201
202 //=======================================================================
203
204 namespace {
205   // Auxiliary: comparator function for sorting roots
206   bool IntTools_RootComparator (const IntTools_Root& theLeft, const IntTools_Root& theRight)
207   {
208     return theLeft.Root() < theRight.Root();
209   }
210 };
211
212 //=======================================================================
213 //function : SortRoots
214 //purpose  : 
215 //=======================================================================
216   void IntTools::SortRoots(IntTools_SequenceOfRoots& mySequenceOfRoots,
217                            const Standard_Real /*myEpsT*/)
218 {
219   Standard_Integer j, aNbRoots;
220
221   aNbRoots=mySequenceOfRoots.Length();
222
223   IntTools_Array1OfRoots anArray1OfRoots(1, aNbRoots);  
224   for (j=1; j<=aNbRoots; j++) {
225     anArray1OfRoots(j)=mySequenceOfRoots(j);
226   }
227   
228   std::sort (anArray1OfRoots.begin(), anArray1OfRoots.end(), IntTools_RootComparator);
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 t1, t2, f1, f2, absf2;
244
245   aNbRoots=mySequenceOfRoots.Length();
246
247   for (j=1; j<=aNbRoots; j++) {
248     IntTools_Root& aR=mySequenceOfRoots.ChangeValue(j);
249     
250     aR.Interval (t1, t2, f1, f2);
251
252     aType=aR.Type();
253     switch (aType) {
254     case 0: // Simple Root
255       if (f1>0. && f2<0.) {
256         aR.SetStateBefore(TopAbs_OUT);
257         aR.SetStateAfter (TopAbs_IN);
258       }
259     else {
260       aR.SetStateBefore(TopAbs_IN);
261       aR.SetStateAfter (TopAbs_OUT);
262     }
263       break;
264     
265     case 1: // Complete 0;
266       aR.SetStateBefore(TopAbs_ON);
267       aR.SetStateAfter (TopAbs_ON);
268       break;
269       
270     case 2: // Smart;
271       absf2=fabs(f2);
272       if (absf2 < myEpsNull) {
273         aR.SetStateAfter (TopAbs_ON);
274         if (f1>0.) {
275           aR.SetStateBefore(TopAbs_OUT);
276         }
277         else {
278           aR.SetStateBefore(TopAbs_IN);
279         }
280       }
281       
282       else {
283         aR.SetStateBefore(TopAbs_ON);
284         if (f2>0.) {
285           aR.SetStateAfter (TopAbs_OUT);
286         }
287         else {
288           aR.SetStateAfter (TopAbs_IN);
289         }
290       }
291       
292     default: break;
293     } // switch (aType)  
294   }
295 }
296
297 #include <GeomAdaptor_Curve.hxx>
298 #include <gp_Pnt.hxx>
299 #include <ElCLib.hxx>
300 #include <gp_Lin.hxx>
301 #include <gp_Circ.hxx>
302 #include <gp_Elips.hxx>
303 #include <gp_Hypr.hxx>
304 #include <gp_Parab.hxx>
305 #include <GeomAPI_ProjectPointOnCurve.hxx>
306
307 //=======================================================================
308 //function :Parameter
309 //purpose  :
310 //=======================================================================
311   Standard_Integer  IntTools::Parameter (const gp_Pnt& aP,
312                                          const Handle(Geom_Curve)& aCurve,
313                                          Standard_Real& aParameter)
314 {
315   Standard_Real aFirst, aLast;
316   GeomAbs_CurveType aCurveType;
317
318   aFirst=aCurve->FirstParameter();
319   aLast =aCurve->LastParameter ();
320
321   GeomAdaptor_Curve aGAC;
322   
323   aGAC.Load (aCurve, aFirst, aLast);
324
325   aCurveType=aGAC.GetType();
326   
327   switch (aCurveType){
328
329   case GeomAbs_Line:
330     {
331       gp_Lin aLin=aGAC.Line();
332       aParameter=ElCLib::Parameter (aLin, aP);
333       return 0;
334     }
335   case GeomAbs_Circle:
336     {
337       gp_Circ aCircle=aGAC.Circle();
338       aParameter=ElCLib::Parameter (aCircle, aP);
339       return 0;
340     }
341   case GeomAbs_Ellipse: 
342     {
343       gp_Elips aElips=aGAC.Ellipse();
344       aParameter=ElCLib::Parameter (aElips, aP);
345       return 0;
346     }
347   case GeomAbs_Hyperbola: 
348     {
349       gp_Hypr aHypr=aGAC.Hyperbola();
350       aParameter=ElCLib::Parameter (aHypr, aP);
351       return 0;
352     }
353   case GeomAbs_Parabola: 
354     {
355       gp_Parab aParab=aGAC.Parabola();
356       aParameter=ElCLib::Parameter (aParab, aP);
357       return 0;
358     }
359
360   case GeomAbs_BezierCurve:
361   case GeomAbs_BSplineCurve:
362     {
363       GeomAPI_ProjectPointOnCurve aProjector;
364       
365       aProjector.Init(aP, aCurve, aFirst, aLast);
366       Standard_Integer aNbPoints=aProjector.NbPoints();
367       if (aNbPoints) {
368         aParameter=aProjector.LowerDistanceParameter();
369         return 0;
370       }
371       else {
372         return 2;
373       }
374     }
375   default: 
376     break;
377   }
378   return 1;
379 }
380
381 #ifdef _MSC_VER
382 #pragma warning ( default : 4101 )
383 #endif