0024624: Lost word in license statement in source files
[occt.git] / src / BOPInt / BOPInt_ShrunkRange.cxx
1 // Created by: Peter KURNEV
2 // Copyright (c) 1999-2014 OPEN CASCADE SAS
3 //
4 // This file is part of Open CASCADE Technology software library.
5 //
6 // This library is free software; you can redistribute it and/or modify it under
7 // the terms of the GNU Lesser General Public License version 2.1 as published
8 // by the Free Software Foundation, with special exception defined in the file
9 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
10 // distribution for complete text of the license and disclaimer of any warranty.
11 //
12 // Alternatively, this file may be used under the terms of Open CASCADE
13 // commercial license or contractual agreement.
14
15 #include <BOPInt_ShrunkRange.ixx>
16
17 #include <Precision.hxx>
18
19 #include <gp.hxx>
20 #include <gp_Circ.hxx>
21
22 #include <Geom_Curve.hxx>
23
24 #include <BRep_Tool.hxx>
25 #include <BRepBuilderAPI_MakeVertex.hxx>
26 #include <BRepAdaptor_Curve.hxx>
27 #include <BndLib_Add3dCurve.hxx>
28 #include <BOPInt_Context.hxx>
29 #include <gp_Lin.hxx>
30 #include <ElCLib.hxx>
31
32 //=======================================================================
33 //function : 
34 //purpose  : 
35 //=======================================================================
36   BOPInt_ShrunkRange::BOPInt_ShrunkRange ()
37 {
38   myT1=-99;
39   myT2=myT1;
40   myTS1=myT1;
41   myTS2=myT1;
42   myErrorStatus=1;
43 }
44 //=======================================================================
45 //function : SetData
46 //purpose  : 
47 //=======================================================================
48   void BOPInt_ShrunkRange::SetData(const TopoDS_Edge& aE,
49                                    const Standard_Real aT1,
50                                    const Standard_Real aT2,
51                                    const TopoDS_Vertex& aV1,
52                                    const TopoDS_Vertex& aV2,
53                                    const Handle(BOPInt_Context)& aCtx)
54 {
55   myEdge=aE;
56   myV1=aV1;
57   myV2=aV2;
58   myT1=aT1;
59   myT2=aT2;
60   //myRange=aR;
61   myCtx=aCtx;
62   myErrorStatus=1;
63 }
64 //=======================================================================
65 //function : Edge
66 //purpose  : 
67 //=======================================================================
68   const TopoDS_Edge& BOPInt_ShrunkRange::Edge() const
69 {
70   return myEdge;
71 }
72 //=======================================================================
73 //function : ShrunkRange
74 //purpose  : 
75 //=======================================================================
76   void BOPInt_ShrunkRange::ShrunkRange(Standard_Real& aT1,
77                                        Standard_Real& aT2) const
78 {
79   aT1=myTS1;
80   aT2=myTS2;
81 }
82 //=======================================================================
83 //function : BndBox
84 //purpose  : 
85 //=======================================================================
86   const Bnd_Box& BOPInt_ShrunkRange::BndBox() const
87 {
88   return myBndBox;
89 }
90 //=======================================================================
91 //function : ErrorStatus
92 //purpose  : 
93 //=======================================================================
94   Standard_Integer BOPInt_ShrunkRange::ErrorStatus() const
95 {
96   return myErrorStatus;
97 }
98
99 //=======================================================================
100 //function : SetShrunkRange
101 //purpose  : 
102 //=======================================================================
103   void BOPInt_ShrunkRange::SetShrunkRange(const Standard_Real aT1,
104                                           const Standard_Real aT2) 
105 {
106   myTS1=aT1;
107   myTS2=aT2;
108   //
109   BRepAdaptor_Curve aBAC(myEdge);
110   BndLib_Add3dCurve::Add (aBAC, aT1, aT2, 0., myBndBox);
111 }
112
113 //=======================================================================
114 //function : Perform
115 //purpose  : 
116 //=======================================================================
117   void BOPInt_ShrunkRange::Perform()
118 {
119   Standard_Real aCF, aCL, aTolE, aTolV1, aTolV2, t1, t11, t1C, t2, t12, t2C;
120   Standard_Real aCoeff1, aCoeff2, aTol1, aTol2, dt1, dt2, aR, anEps;
121   Standard_Integer pri;
122   Standard_Boolean bInf1, bInf2, bAppr;
123   GeomAbs_CurveType aCurveType;
124   Handle(Geom_Curve) aC;
125   //
126   myErrorStatus=0;
127   myTS1=-99;
128   myTS2=myTS1;
129   anEps = 1.e-8;
130   //
131   aTolE =BRep_Tool::Tolerance(myEdge);
132   aTolV1=BRep_Tool::Tolerance(myV1);
133   aTolV2=BRep_Tool::Tolerance(myV2);
134   //for edges with the tolerance value 
135   //more than the tolerance value of vertices
136   if (aTolV1 < aTolE) {
137     aTolV1 = aTolE;
138   }
139   //
140   if (aTolV2 < aTolE) {
141     aTolV2 = aTolE;
142   }
143   //
144   t1=myT1;
145   t2=myT2;
146   //
147   BRepAdaptor_Curve aBAC(myEdge);
148   aCurveType=aBAC.GetType();
149   //
150   aC=BRep_Tool::Curve(myEdge, aCF, aCL);
151   BRep_Tool::Range(myEdge, aCF, aCL);
152   //
153   if (t1 < aCF || t2 > aCL) {
154     myErrorStatus=2;
155     return;
156   }
157   //
158   bAppr = (fabs(t2 - t1) > 100) ? Standard_False : Standard_True;
159   if (fabs(t2 - t1) < anEps) {
160     myErrorStatus=7;
161     return;
162   }
163   //
164   if (t1 > t2) {
165     myErrorStatus=3;
166     return;
167   }
168   //
169   aTol1 = aTolV1+aTolE;
170   aTol2 = aTolV2+aTolE;
171   //
172   aCoeff1 = (aTolE>0.05) ? 1. : 2.;
173   aCoeff2 = aCoeff1;
174   if (aCoeff1 == 2.) {
175     aCoeff1=(aTol1>0.05) ? 1.5 : 2.;
176     aCoeff2=(aTol2>0.05) ? 1.5 : 2.;
177   }
178   // xf
179   if (aCurveType==GeomAbs_Line && (aCoeff1 != 1 || aCoeff2 != 1)) {
180     Standard_Real aTV1, aTV2, aEps;
181     gp_Pnt aPV1, aPV2, aPC1, aPC2;
182     gp_Lin aL;
183     //
184     aEps=Precision::Confusion();
185     aEps=aEps*aEps;//1.e-14;
186     aL=aBAC.Line();
187     //
188     aPV1=BRep_Tool::Pnt(myV1);
189     aTV1=ElCLib::Parameter(aL, aPV1);
190     //
191     aPV2=BRep_Tool::Pnt(myV2);
192     aTV2=ElCLib::Parameter(aL, aPV2);
193     //
194     if (fabs(aTV1-aCF)<aEps) {
195       aCoeff1=1.;
196     }
197     if (fabs(aTV2-aCL)<aEps) {
198       aCoeff2=1.;
199     }
200   }
201   //
202   dt1=aCoeff1*aTol1;
203   dt2=aCoeff2*aTol2;
204   // xt
205   //
206   if (aCurveType==GeomAbs_Line) {
207     Standard_Real dt1x, dt2x;
208
209     dt1x = aBAC.Resolution(dt1);
210     t11=t1+dt1x;
211     
212     dt2x = aBAC.Resolution(dt2);
213     t12=t2-dt2x;
214
215     if (t11>t2 || t12<t1) {
216       t1C=t1;
217       t2C=t2;
218       myTS1=t1C;
219       myTS2=t2C;
220       //
221       // BndBox
222       Standard_Real ddx=aTolE;//1.e-12;
223       BndLib_Add3dCurve::Add (aBAC, t1C, t2C, ddx, myBndBox);
224       
225       myErrorStatus=6;//0
226       return;
227     }
228   }
229   //
230   if (aCurveType==GeomAbs_Circle) {
231     gp_Circ aCrc=aBAC.Circle();
232     aR=aCrc.Radius();
233     t1C=t1+dt1/aR;
234     t2C=t2-dt2/aR;
235   }
236   else {
237     //
238     // Vertex1 => t1C
239     gp_Pnt aP1,aP11;
240     aC->D0 (t1, aP1);
241     //
242     bInf1=Precision::IsNegativeInfinite(t1);
243     if (bInf1) {
244       t1C=t1;
245     }
246     //
247     else {
248       Standard_Real d1 = aCoeff1*aTol1;
249       //       dt1 = aBAC.Resolution(d1);
250       //
251       gp_Vec aD1vec1;
252       gp_Pnt aPoint;
253       aBAC.D1(t1, aPoint, aD1vec1);
254       Standard_Real ad1length1 = aD1vec1.Magnitude();
255       Standard_Boolean bTryOtherPoints = Standard_False;
256       dt1 = (t2 - t1) * 0.5;
257
258       if(ad1length1 > 1.e-12) {
259         dt1 = d1 / ad1length1;
260         
261         if(dt1  > (t2 - t1)) {
262           // bad parametrization, big tolerance or too small range
263           bTryOtherPoints = Standard_True;
264         }
265       }
266       else {
267         bTryOtherPoints = Standard_True;
268       }
269       
270       if(bTryOtherPoints) {
271         Standard_Integer nbsamples = 5;
272         Standard_Integer ii = 0;
273         Standard_Real adelta = (t2 - t1) / (nbsamples + 1);
274         Standard_Boolean bFound = Standard_False;
275         
276         for(ii = 1; ii <= nbsamples; ii++) {
277           Standard_Real aparameter = t1 + (adelta * ii);
278           gp_Pnt aPoint2;
279           aBAC.D1(aparameter, aPoint2, aD1vec1);
280           
281           if(aPoint.Distance(aPoint2) < d1)
282             dt1 = adelta * ii;
283           ad1length1 = aD1vec1.Magnitude();
284           
285           if(ad1length1 > 1.e-12) {
286             dt1 = d1 / ad1length1;
287             
288             if(dt1 < (t2 - t1)) {
289               bFound = Standard_True;
290               break;
291             }
292           }
293         }
294         
295         if(!bFound) {
296           if(dt1 > (t2 - t1)) {
297             dt1 = aBAC.Resolution(d1);
298           }
299         }
300       }
301       //
302       if (!bAppr) {
303         dt1 *= 10;
304       }
305       t11=t1+dt1;
306       aC->D0 (t11, aP11);
307       
308       gp_Vec aV11(aP1, aP11);
309       // avoid exception if aP1 == aP11
310       if (aV11.SquareMagnitude() < gp::Resolution())
311         t1C = t1;
312       else {
313         gp_Dir aD11(aV11);
314
315         gp_Pnt aP1L;
316         //
317         aP1L.SetCoord (aP1.X()+d1*aD11.X(),
318                        aP1.Y()+d1*aD11.Y(),
319                        aP1.Z()+d1*aD11.Z());
320
321         BRepBuilderAPI_MakeVertex aMV1(aP1L);
322         const TopoDS_Vertex& aV1L=aMV1.Vertex();
323         //
324         pri=myCtx->ComputeVE (aV1L, myEdge, t1C);
325         //
326         if (pri==-3) {
327           myErrorStatus=4;
328           return;
329         }
330       }
331     }
332     //
333     // Vertex2 => t2C
334     gp_Pnt aP2, aP12;
335     aC->D0 (t2, aP2);
336     //
337     bInf2=Precision::IsPositiveInfinite(t2);
338     if (bInf2) {
339       t2C=t2;
340     }
341     //
342     else {
343       Standard_Real d2 = aCoeff2*aTol2;
344       //       dt2 = aBAC.Resolution(d2);
345
346       //
347       gp_Vec aD1vec2;
348       gp_Pnt aPoint;
349       aBAC.D1(t2, aPoint, aD1vec2);
350       Standard_Real ad1length2 = aD1vec2.Magnitude();
351       Standard_Boolean bTryOtherPoints = Standard_False;
352       dt2 = (t2 - t1) * 0.5;
353
354       if(ad1length2 > 1.e-12) {
355         dt2 = d2 / ad1length2;
356         
357         if(dt2 > (t2 - t1)) {
358           bTryOtherPoints = Standard_True;
359         }
360       }
361       else {
362         bTryOtherPoints = Standard_True;
363       }
364
365       if(bTryOtherPoints) {
366         Standard_Integer nbsamples = 5;
367         Standard_Integer ii = 0;
368         Standard_Real adelta = (t2 - t1) / (nbsamples + 1);
369         Standard_Boolean bFound = Standard_False;
370         
371         for(ii = 1; ii <= nbsamples; ii++) {
372           Standard_Real aparameter = t2 - (adelta * ii);
373           gp_Pnt aPoint2;
374           aBAC.D1(aparameter, aPoint2, aD1vec2);
375           
376           if(aPoint.Distance(aPoint2) < d2)
377             dt2 = adelta * ii;
378           ad1length2 = aD1vec2.Magnitude();
379           
380           if(ad1length2 > 1.e-12) {
381             dt2 = d2 / ad1length2;
382             
383             if(dt2 < (t2 - t1)) {
384               bFound = Standard_True;
385               break;
386             }
387           }
388         }
389         
390         if(!bFound) {
391           if(dt2 > (t2 - t1)) {
392             dt2 = aBAC.Resolution(d2);
393           }
394         }
395       }
396       //
397       if (!bAppr) {
398         dt2 *= 10;
399       }
400
401       t12=t2-dt2;
402       aC->D0 (t12, aP12);
403       
404       gp_Vec aV12(aP2, aP12);
405       // avoid exception if aP1 == aP11
406       if (aV12.SquareMagnitude() < gp::Resolution())
407         t2C = t2;
408       else {
409         gp_Dir aD12(aV12);
410
411         gp_Pnt aP2L;
412         //
413         aP2L.SetCoord (aP2.X()+d2*aD12.X(),
414                        aP2.Y()+d2*aD12.Y(),
415                        aP2.Z()+d2*aD12.Z());
416
417         BRepBuilderAPI_MakeVertex aMV2(aP2L);
418         const TopoDS_Vertex& aV2L=aMV2.Vertex();
419         //
420         pri=myCtx->ComputeVE (aV2L, myEdge, t2C);
421         //
422         if (pri==-3) {
423           myErrorStatus=5;
424           return;
425         }
426       }
427     }
428   } // else {
429
430
431   if (t1C>t2){
432     t1C=0.5*(t2+t1);
433     t2C=t1C+0.1*(t2-t1C);
434   }
435   
436   if (t1C>t2C) {
437     t2C=t1C+0.1*(t2-t1C);
438   }
439   //
440   if (t2C-t1C < anEps) {
441     myErrorStatus = 7;
442     return;
443   }
444   //
445   myTS1=t1C;
446   myTS2=t2C;
447   //
448   // BndBox
449   Standard_Real ddx=aTolE;//1.e-12;
450   BndLib_Add3dCurve::Add (aBAC, t1C, t2C, ddx, myBndBox);
451 }
452 /////////////////////////////////////////////////////////////////////////
453 //
454 //            myErrorStatus :
455 //
456 // 1- Nothing has been done
457 // 2- The source range is out of the edge's range
458 // 3- t1 < t2 for source range
459 // 4- Can not project V1L  to the Edge;
460 // 5- Can not project V2L  to the Edge;
461 // 6- for obtained shrunk range [t11, t12] ->  t11>t2 || t12<t1;
462 // 7- too small range.