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