0023998: Bad result of intersection of two faces: curve has a loop
[occt.git] / src / IntWalk / IntWalk_PWalking_4.gxx
1 // Copyright (c) 1995-1999 Matra Datavision
2 // Copyright (c) 1999-2012 OPEN CASCADE SAS
3 //
4 // The content of this file is subject to the Open CASCADE Technology Public
5 // License Version 6.5 (the "License"). You may not use the content of this file
6 // except in compliance with the License. Please obtain a copy of the License
7 // at http://www.opencascade.org and read it completely before using this file.
8 //
9 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
10 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
11 //
12 // The Original Code and all software distributed under the License is
13 // distributed on an "AS IS" basis, without warranty of any kind, and the
14 // Initial Developer hereby disclaims all such warranties, including without
15 // limitation, any warranties of merchantability, fitness for a particular
16 // purpose or non-infringement. Please see the License for the specific terms
17 // and conditions governing the rights and limitations under the License.
18
19 //-- 
20 //-- Modif du 5 Octobre 94 (LBR) 
21 //--   if(Trouve) ...
22 //-- On deborde sur une frontiere, Duv[.] = -1 -1 -1 -1 
23 //-- donc on garde la meme iso bloquee (voir if(k!=1) )
24 //-- 
25
26 //-- Modif du 8 juillet 96 (LBR)
27 //-- simplifaication du traitement des auto-intersections.
28 //-- Idee : 
29 //--          Tester la boucle fermee en 3d et en 2d. 
30 //-- 
31
32 #include <gp_Pnt2d.hxx>
33
34
35 Standard_Boolean IntWalk_PWalking::
36         TestArret(const Standard_Boolean DejaReparti,
37                   TColStd_Array1OfReal& Param,
38                   IntImp_ConstIsoparametric&  ChoixIso)
39
40 //
41 // tester si le point d intersection donne par ces parametres reste dans le
42 // domaine naturelle de chaque carreau.
43 // si le point deborde cadrer de facon a trouver la meilleure iso (frontiere)
44 // qui intersecte le plus franchement l autre carreau
45 // sinon tester si presence de ligne fermee  
46 // 
47 {
48   Standard_Real Uvd[4],Uvf[4],Epsuv[4],Duv[4],Uvp[4],dv,dv2,ParC[4];
49   Standard_Real DPc,DPb;
50 #ifndef DEB
51   Standard_Integer i = 0, k = 0;
52 #else 
53   Standard_Integer i,k;
54 #endif
55   Epsuv[0] = ResoU1;
56   Epsuv[1] = ResoV1;
57   Epsuv[2] = ResoU2;
58   Epsuv[3] = ResoV2;
59   previousPoint.Parameters(Uvp[0],Uvp[1],Uvp[2],Uvp[3]);
60   Standard_Boolean Trouve = Standard_False;
61
62   Uvd[0]=Um1;   Uvf[0]=UM1;   Uvd[1]=Vm1;   Uvf[1]=VM1;
63   Uvd[2]=Um2;   Uvf[2]=UM2;   Uvd[3]=Vm2;   Uvf[3]=VM2;
64
65   Standard_Integer im1;
66   for ( i = 1,im1 = 0;i<=4;i++,im1++) {
67     switch(i) { 
68     case 1: k=2; break;
69     case 2: k=1; break;
70     case 3: k=4; break;
71     case 4: k=3; break;
72     }
73     if (Param(i) < (Uvd[im1]-Epsuv[im1])) {        //--     Current -----  Bound Inf -----  Previous
74       Trouve    = Standard_True;                   //-- 
75       DPc       = Uvp[im1]-Param(i);               //--     Previous  - Current
76       DPb       = Uvp[im1]-Uvd[im1];               //--     Previous  - Bound Inf
77       ParC[im1] = Uvd[im1];                        //--     ParamCorrige
78       dv        = Param(k)-Uvp[k-1];               //--     Current   - Previous (Sur Autre Direction)
79       dv2       = dv*dv;         
80       if(dv2>RealEpsilon()) {                       //--     Progression sur l autre Direction ?
81         Duv[im1]  = DPc*DPb + dv2;
82         Duv[im1]  = Duv[im1]*Duv[im1]/(DPc*DPc+dv2)/(DPb*DPb+dv2);
83       }
84       else {
85         Duv[im1]=-1.0;                              //--    Si Pas de prgogression, on ne change pas 
86       }                                             //--    le choix de l iso 
87     }   
88     else if (Param(i) > (Uvf[im1] + Epsuv[im1])) {  //--     Previous -----  Bound Sup -----  Current
89       Trouve    = Standard_True;                    //-- 
90       DPc       = Param(i)-Uvp[im1];                //--     Current   - Previous
91       DPb       = Uvf[im1]-Uvp[im1];                //--     Bound Sup - Previous 
92       ParC[im1] = Uvf[im1];                         //--     Param Corrige
93       dv        = Param(k)-Uvp[k-1];                //--     Current   - Previous (Sur autre Direction)
94       dv2       = dv*dv;
95       if(dv2>RealEpsilon()) {                       //--     Progression sur l autre Direction ?
96         Duv[im1]  =  DPc*DPb + dv2;
97         Duv[im1]  = Duv[im1]*Duv[im1]/(DPc*DPc+dv2)/(DPb*DPb+dv2);
98       }
99       else {
100         Duv[im1]=-1.0;                              //--    Si Pas de prgogression, on ne change pas 
101       }                                             //--    le choix de l iso 
102     }
103     else { 
104       Duv[im1]= -1.;
105       ParC[im1]=Param(i);
106     }
107   }
108
109   if (Trouve) {
110     //--------------------------------------------------
111     //-- Un des Parametres u1,v1,u2,v2 est en dehors  --
112     //-- des bornes naturelles.                       -- 
113     //-- On cherche la meilleure direction de         -- 
114     //-- progression et on recadre les params.        --
115     //--------------------------------------------------
116     Standard_Real ddv = -1.0;
117     k=-1;
118     for (i=0;i<=3;i++) {
119       Param(i+1) = ParC[i];
120       if(Duv[i]>ddv) { 
121         ddv = Duv[i];
122         k=i;
123       }
124     }
125     if(k!=-1) { 
126       ChoixIso   = ChoixRef[k];
127     }
128     else { 
129       if((ParC[0]<=Uvd[0]+Epsuv[0]) || (ParC[0]>=Uvf[0]-Epsuv[0])) {
130         ChoixIso = IntImp_UIsoparametricOnCaro1;
131       }
132       else if((ParC[1]<=Uvd[1]+Epsuv[1]) || (ParC[1]>=Uvf[1]-Epsuv[1])) {
133         ChoixIso = IntImp_VIsoparametricOnCaro1;
134       }
135       else if((ParC[2]<=Uvd[2]+Epsuv[2]) || (ParC[2]>=Uvf[2]-Epsuv[2])) {
136         ChoixIso = IntImp_UIsoparametricOnCaro2;
137       }
138       else if((ParC[3]<=Uvd[3]+Epsuv[3]) || (ParC[3]>=Uvf[3]-Epsuv[3])) {
139         ChoixIso = IntImp_VIsoparametricOnCaro2;
140       }
141     }
142     close = Standard_False;
143     return Standard_True;
144   }
145   else 
146     {  
147       if (!DejaReparti) { // recherche si ligne fermee
148
149         Standard_Real u,v;
150         const IntSurf_PntOn2S& POn2S1=line->Value(1);
151         //On S1
152         POn2S1.ParametersOnS1(u,v);
153         gp_Pnt2d P1uvS1(u,v);
154         previousPoint.ParametersOnS1(u,v);
155         gp_Pnt2d PrevuvS1(u,v);
156         myIntersectionOn2S.Point().ParametersOnS1(u,v);
157         gp_Pnt2d myIntersuvS1(u,v);
158         Standard_Boolean close2dS1 = (P1uvS1.XY()-PrevuvS1.XY())*
159           (P1uvS1.XY()-myIntersuvS1.XY()) < 0.0;
160         //On S2
161         POn2S1.ParametersOnS2(u,v);
162         gp_Pnt2d P1uvS2(u,v);
163         previousPoint.ParametersOnS2(u,v);
164         gp_Pnt2d PrevuvS2(u,v);
165         myIntersectionOn2S.Point().ParametersOnS2(u,v);
166         gp_Pnt2d myIntersuvS2(u,v);
167         Standard_Boolean close2dS2 = (P1uvS2.XY()-PrevuvS2.XY())*
168           (P1uvS2.XY()-myIntersuvS2.XY()) < 0.0;
169
170         close = close2dS1 && close2dS2;
171         return close;
172       }
173       else return Standard_False;
174     }
175 }
176
177