e34d8837a2b1694325685bb77db48945a1aca915
[occt.git] / src / IntPolyh / IntPolyh_Intersection_1.cxx
1 // Created on: 2005-09-26
2 // Created by: Igor FEOKTISTOV
3 // Copyright (c) 2005-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 #include <IntPolyh_Intersection.ixx>
17 #include <IntPolyh_PMaillageAffinage.hxx>
18 #include <IntPolyh_MaillageAffinage.hxx>
19 #include <IntPolyh_ArrayOfCouples.hxx>
20 #include <IntPolyh_Couple.hxx>
21 #include <IntPolyh_Triangle.hxx>
22
23 Standard_Integer MYPRINT1   = 0;
24
25
26 //=======================================================================
27 //function : IntPolyh_Intersection
28 //purpose  : 
29 //=======================================================================
30
31 IntPolyh_Intersection::IntPolyh_Intersection(const Handle(Adaptor3d_HSurface)& S1,
32                                              const TColStd_Array1OfReal& Upars1,
33                                              const TColStd_Array1OfReal& Vpars1,
34                                              const Handle(Adaptor3d_HSurface)& S2,
35                                              const TColStd_Array1OfReal& Upars2,
36                                              const TColStd_Array1OfReal& Vpars2)
37 {
38   myNbSU1 = Upars1.Length();
39   myNbSV1 = Vpars1.Length();
40   myNbSU2 = Upars2.Length(); 
41   myNbSV2 = Vpars2.Length(); 
42   mySurf1 = S1;
43   mySurf2 = S2;
44   done = Standard_False;
45   TSectionLines.Init(1000);
46   TTangentZones.Init(10000);
47   Perform(Upars1, Vpars1, Upars2, Vpars2);
48 }
49
50 //=======================================================================
51 //function : Perform
52 //purpose  : 
53 //=======================================================================
54
55 void IntPolyh_Intersection::Perform(const TColStd_Array1OfReal& Upars1,
56                                     const TColStd_Array1OfReal& Vpars1,
57                                     const TColStd_Array1OfReal& Upars2,
58                                     const TColStd_Array1OfReal& Vpars2) { 
59
60   done = Standard_True;
61
62   Standard_Boolean startFromAdvanced = Standard_False;
63   Standard_Boolean isStdDone = Standard_False;
64   Standard_Boolean isAdvDone = Standard_False;
65   Standard_Integer nbCouplesStd = 0;
66   Standard_Integer nbCouplesAdv = 0;
67   
68   
69   IntPolyh_PMaillageAffinage aPMaillageStd = 0;
70   IntPolyh_PMaillageAffinage aPMaillageFF = 0;
71   IntPolyh_PMaillageAffinage aPMaillageFR = 0;
72   IntPolyh_PMaillageAffinage aPMaillageRF = 0;
73   IntPolyh_PMaillageAffinage aPMaillageRR = 0;
74
75
76   if(!startFromAdvanced) {
77
78     isStdDone = PerformStd(Upars1, Vpars1, Upars2, Vpars2, 
79                            aPMaillageStd,nbCouplesStd);
80
81     // default interference done well, use it
82     if(isStdDone && nbCouplesStd > 10) {
83       aPMaillageStd->StartPointsChain(TSectionLines, TTangentZones);
84     }
85     // default interference done, but too few interferences foud;
86     // use advanced interference
87     else if(isStdDone && nbCouplesStd <= 10) {
88       isAdvDone = PerformAdv(Upars1, Vpars1, Upars2, Vpars2,
89                              aPMaillageFF,aPMaillageFR,aPMaillageRF,aPMaillageRR,nbCouplesAdv);
90       
91       // advanced interference found
92       if(isAdvDone && nbCouplesAdv > 10) {
93         aPMaillageFF->StartPointsChain(TSectionLines,TTangentZones);
94         aPMaillageFR->StartPointsChain(TSectionLines,TTangentZones);
95         aPMaillageRF->StartPointsChain(TSectionLines,TTangentZones);
96         aPMaillageRR->StartPointsChain(TSectionLines,TTangentZones);
97       }
98       else {
99         // use result of default
100         if(nbCouplesStd > 0)
101           aPMaillageStd->StartPointsChain(TSectionLines, TTangentZones);
102       }
103     }
104     // default interference faild, use advanced
105     else {
106 //       isAdvDone = PerformAdv(aPMaillageFF,aPMaillageFR,aPMaillageRF,aPMaillageRR,nbCouplesAdv);
107       
108 //       if(isAdvDone && nbCouplesAdv > 0) {cout << "4adv done, nbc: " << nbCouplesAdv << endl;
109 //      aPMaillageFF->StartPointsChain(TSectionLines,TTangentZones);
110 //      aPMaillageFR->StartPointsChain(TSectionLines,TTangentZones);
111 //      aPMaillageRF->StartPointsChain(TSectionLines,TTangentZones);
112 //      aPMaillageRR->StartPointsChain(TSectionLines,TTangentZones);
113 //       }
114     }
115   }// start from default
116   else {
117     
118     isAdvDone = PerformAdv(Upars1, Vpars1, Upars2, Vpars2,
119                            aPMaillageFF,aPMaillageFR,aPMaillageRF,aPMaillageRR,nbCouplesAdv);
120
121     // advanced done, interference found; use it
122     if(isAdvDone) {
123
124       if(nbCouplesAdv > 0) {
125         aPMaillageFF->StartPointsChain(TSectionLines,TTangentZones);
126         aPMaillageFR->StartPointsChain(TSectionLines,TTangentZones);
127         aPMaillageRF->StartPointsChain(TSectionLines,TTangentZones);
128         aPMaillageRR->StartPointsChain(TSectionLines,TTangentZones);
129       }
130       else {
131         isStdDone = PerformStd(aPMaillageStd,nbCouplesStd);
132         if(isStdDone && nbCouplesStd > 0)
133           aPMaillageStd->StartPointsChain(TSectionLines, TTangentZones);
134       }
135     }
136     else {
137       isStdDone = PerformStd(Upars1, Vpars1, Upars2, Vpars2,
138                              aPMaillageStd,nbCouplesStd);
139       if(isStdDone && nbCouplesStd > 0)
140         aPMaillageStd->StartPointsChain(TSectionLines, TTangentZones);
141     }
142   } // start from advanced
143
144   // accept result
145   nbsectionlines = TSectionLines.NbItems();
146   nbtangentzones = TTangentZones.NbItems();
147
148   // clean up
149   if(aPMaillageStd) delete aPMaillageStd;
150   if(aPMaillageFF) delete aPMaillageFF;
151   if(aPMaillageFR) delete aPMaillageFR;
152   if(aPMaillageRF) delete aPMaillageRF;
153   if(aPMaillageRR) delete aPMaillageRR;
154
155   // verify
156   if(!isStdDone && !isAdvDone)
157     done = Standard_False;
158 }
159
160 //=======================================================================
161 //function : PerformMaillage
162 //purpose  : Computes MaillageAffinage
163 //=======================================================================
164 Standard_Boolean IntPolyh_Intersection::PerformMaillage(const Standard_Boolean isFirstFwd,
165                                                         const Standard_Boolean isSecondFwd,
166                                                         const TColStd_Array1OfReal& Upars1,
167                                                         const TColStd_Array1OfReal& Vpars1,
168                                                         const TColStd_Array1OfReal& Upars2,
169                                                         const TColStd_Array1OfReal& Vpars2,
170                                                         IntPolyh_PMaillageAffinage &theMaillageS)
171 {
172   theMaillageS = new IntPolyh_MaillageAffinage(mySurf1, Upars1.Length(), Vpars1.Length(),
173                                                mySurf2, Upars2.Length(), Vpars2.Length(),
174                                                MYPRINT1);
175   
176   
177   theMaillageS->FillArrayOfPnt(1, isFirstFwd, Upars1, Vpars1);
178   theMaillageS->FillArrayOfPnt(2, isSecondFwd, Upars2, Vpars2);
179   
180   
181   
182   Standard_Real xx0,yy0,zz0,xx1,yy1,zz1;
183   theMaillageS->CommonBox(theMaillageS->GetBox(1), theMaillageS->GetBox(2),
184                           xx0, yy0, zz0, xx1, yy1, zz1);
185   
186   theMaillageS->FillArrayOfEdges(1);
187   theMaillageS->FillArrayOfEdges(2);
188
189   theMaillageS->FillArrayOfTriangles(1);
190   theMaillageS->FillArrayOfTriangles(2);
191   
192   theMaillageS->LinkEdges2Triangles();
193   
194   theMaillageS->TrianglesDeflectionsRefinementBSB();
195
196   Standard_Integer FinTTC = theMaillageS->TriangleCompare();
197
198   // if too many intersections, consider surfaces parallel (eap)
199 /*
200   if(FinTTC > 200 &&
201      (FinTTC >= theMaillageS->GetArrayOfTriangles(1).NbTriangles() ||
202       FinTTC >= theMaillageS->GetArrayOfTriangles(2).NbTriangles()) ) {
203     return Standard_False;
204   }
205 */
206 //IFV test for parallel surf
207   if(FinTTC > 200) {
208     const Standard_Real eps = .996; //~ cos of 5deg.
209     IntPolyh_ArrayOfCouples& Couples = theMaillageS->GetArrayOfCouples();
210     
211     Standard_Integer i, npara = 0;
212     for(i = 0; i < FinTTC; ++i) {
213       Standard_Real cosa = Abs(Couples[i].AngleValue());
214       if(cosa > eps) ++npara;
215     }
216     if(npara >= theMaillageS->GetArrayOfTriangles(1).NbItems() ||
217        npara >= theMaillageS->GetArrayOfTriangles(2).NbItems() ) {
218       return Standard_False;
219     }
220   }
221
222   return Standard_True;
223 }
224
225 //=======================================================================
226 //function : PerformMaillage
227 //purpose  : Computes MaillageAffinage
228 //=======================================================================
229 Standard_Boolean IntPolyh_Intersection::PerformMaillage(const TColStd_Array1OfReal& Upars1,
230                                                         const TColStd_Array1OfReal& Vpars1,
231                                                         const TColStd_Array1OfReal& Upars2,
232                                                         const TColStd_Array1OfReal& Vpars2,
233                                                         IntPolyh_PMaillageAffinage &theMaillageS)
234 {
235     
236   theMaillageS = new IntPolyh_MaillageAffinage(mySurf1, Upars1.Length(), Vpars1.Length(),
237                                                mySurf2, Upars2.Length(), Vpars2.Length(),
238                                                MYPRINT1);
239   
240   theMaillageS->FillArrayOfPnt(1, Upars1, Vpars1);
241   theMaillageS->FillArrayOfPnt(2, Upars2, Vpars2);
242   
243   
244   Standard_Real xx0,yy0,zz0,xx1,yy1,zz1;
245   theMaillageS->CommonBox(theMaillageS->GetBox(1), theMaillageS->GetBox(2),
246                           xx0, yy0, zz0, xx1, yy1, zz1);
247   theMaillageS->FillArrayOfEdges(1);
248   theMaillageS->FillArrayOfEdges(2);
249
250   theMaillageS->FillArrayOfTriangles(1);
251   theMaillageS->FillArrayOfTriangles(2);
252   
253   theMaillageS->LinkEdges2Triangles();
254   
255   theMaillageS->TrianglesDeflectionsRefinementBSB();
256
257   Standard_Integer FinTTC = theMaillageS->TriangleCompare();
258
259   if( FinTTC == 0 ) {
260     Standard_Boolean myZone = Standard_True;
261     theMaillageS->SetEnlargeZone( myZone );
262     theMaillageS->FillArrayOfPnt(1);
263     theMaillageS->FillArrayOfPnt(2);
264     theMaillageS->CommonBox(theMaillageS->GetBox(1), theMaillageS->GetBox(2),
265                             xx0, yy0, zz0, xx1, yy1, zz1);
266     theMaillageS->FillArrayOfEdges(1);
267     theMaillageS->FillArrayOfEdges(2);
268     theMaillageS->FillArrayOfTriangles(1);
269     theMaillageS->FillArrayOfTriangles(2);
270     theMaillageS->LinkEdges2Triangles();
271     theMaillageS->TrianglesDeflectionsRefinementBSB();
272     FinTTC = theMaillageS->TriangleCompare();
273     myZone = Standard_False;
274     theMaillageS->SetEnlargeZone( myZone );
275   }
276
277   // if too many intersections, consider surfaces parallel (eap)
278 /*
279   if(FinTTC > 200 &&
280      (FinTTC >= theMaillageS->GetArrayOfTriangles(1).NbTriangles() ||
281       FinTTC >= theMaillageS->GetArrayOfTriangles(2).NbTriangles()) ) {
282     return Standard_False;
283   }
284 */
285 //IFV test for parallel surf
286   if(FinTTC > 200) {
287     const Standard_Real eps = .996; //~ cos of 5deg.
288     IntPolyh_ArrayOfCouples& Couples = theMaillageS->GetArrayOfCouples();
289     
290     Standard_Integer i, npara = 0;
291     for(i = 0; i < FinTTC; ++i) {
292       Standard_Real cosa = Abs(Couples[i].AngleValue());
293       if(cosa > eps) ++npara;
294     }
295     if(npara >= theMaillageS->GetArrayOfTriangles(1).NbItems() ||
296        npara >= theMaillageS->GetArrayOfTriangles(2).NbItems() ) {
297       return Standard_False;
298     }
299   }
300   
301   return Standard_True;
302 }
303
304 //=======================================================================
305 //function : PerformAdv
306 //purpose  : 
307 //=======================================================================
308
309 Standard_Boolean IntPolyh_Intersection::PerformAdv(const TColStd_Array1OfReal& Upars1,
310                                                    const TColStd_Array1OfReal& Vpars1,
311                                                    const TColStd_Array1OfReal& Upars2,
312                                                    const TColStd_Array1OfReal& Vpars2,
313                                                    IntPolyh_PMaillageAffinage& MaillageFF,
314                                                    IntPolyh_PMaillageAffinage& MaillageFR,
315                                                    IntPolyh_PMaillageAffinage& MaillageRF,
316                                                    IntPolyh_PMaillageAffinage& MaillageRR,
317                                                    Standard_Integer&           NbCouples)
318 {
319   Standard_Boolean isdone = Standard_True;
320   NbCouples = 0;
321
322   if(!PerformMaillage(Standard_True,Standard_False,
323                       Upars1, Vpars1, Upars2, Vpars2, 
324                       MaillageFR) ||
325      !PerformMaillage(Standard_False,Standard_True,
326                       Upars1, Vpars1, Upars2, Vpars2, 
327                       MaillageRF) ||
328      !PerformMaillage(Standard_True,Standard_True,
329                       Upars1, Vpars1, Upars2, Vpars2, 
330                       MaillageFF)  ||
331      !PerformMaillage(Standard_False,Standard_False,
332                       Upars1, Vpars1, Upars2, Vpars2, 
333                       MaillageRR) )
334     isdone = Standard_False; 
335
336   if(isdone) {
337     NbCouples = MaillageFF->GetArrayOfCouples().NbItems() +
338       MaillageFR->GetArrayOfCouples().NbItems() +
339         MaillageRF->GetArrayOfCouples().NbItems() +
340           MaillageRR->GetArrayOfCouples().NbItems();
341
342     if(NbCouples > 0)
343       MergeCouples(MaillageFF->GetArrayOfCouples(),MaillageFR->GetArrayOfCouples(),
344                    MaillageRF->GetArrayOfCouples(),MaillageRR->GetArrayOfCouples());
345   }
346   return isdone;
347 }
348 //=======================================================================
349 //function : PerformStd
350 //purpose  : 
351 //=======================================================================
352
353 Standard_Boolean IntPolyh_Intersection::PerformStd(const TColStd_Array1OfReal& Upars1,
354                                                    const TColStd_Array1OfReal& Vpars1,
355                                                    const TColStd_Array1OfReal& Upars2,
356                                                    const TColStd_Array1OfReal& Vpars2,
357                                                    IntPolyh_PMaillageAffinage& MaillageS,
358                                                    Standard_Integer&           NbCouples)
359 {
360   Standard_Boolean isdone = PerformMaillage(Upars1, Vpars1, Upars2, Vpars2, 
361                                             MaillageS);
362   NbCouples = (isdone) ? (MaillageS->GetArrayOfCouples().NbItems()) : 0;
363   return isdone;
364 }