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