3b93b0b42e53173b409aa500d5ffb2847cfdf767
[occt.git] / src / IntPolyh / IntPolyh_Intersection.cxx
1 // File:        IntPolyh_Intersection.cxx
2 // Created:     Wed Mar  3 11:33:51 1999
3 // Author:      Fabrice SERVANT
4 //              <fst>
5
6 //  modified by Edward AGAPOV (eap) Tue Jan 22 12:29:55 2002 (occ53)
7 //  Modified by skv - Thu Sep 25 18:24:29 2003 OCC567
8
9 #include <IntPolyh_Intersection.ixx>
10 #include <IntPolyh_SectionLine.hxx>
11 #include <IntPolyh_StartPoint.hxx>
12 #include <IntPolyh_MaillageAffinage.hxx>
13 #include <IntPolyh_Couple.hxx>
14
15 #ifdef DEB
16   # define MYDEBUG DEB 
17 #else
18   # define MYDEBUG 0
19 #endif
20
21 Standard_Integer MYDISPLAY = 0;
22 Standard_Integer MYPRINT   = 0;
23
24 # if MYDEBUG
25 //  # include "visudebug.hxx"
26 # endif
27
28
29 IntPolyh_Intersection::IntPolyh_Intersection(const Handle(Adaptor3d_HSurface)& S1,
30                                              const Handle(Adaptor3d_HSurface)& S2)
31 {
32   myNbSU1 = -1;
33   myNbSV1 = -1;
34   myNbSU2 = -1; 
35   myNbSV2 = -1; 
36   mySurf1 = S1;
37   mySurf2 = S2;
38   done = Standard_False;
39   TSectionLines.Init(1000);
40   TTangentZones.Init(10000);
41   Perform();
42 }
43
44 IntPolyh_Intersection::IntPolyh_Intersection(const Handle(Adaptor3d_HSurface)& S1,
45                                              const Standard_Integer NbSU1,
46                                              const Standard_Integer NbSV1,
47                                              const Handle(Adaptor3d_HSurface)& S2,
48                                              const Standard_Integer NbSU2,
49                                              const Standard_Integer NbSV2)
50 {
51   myNbSU1 = NbSU1;
52   myNbSV1 = NbSV1;
53   myNbSU2 = NbSU2; 
54   myNbSV2 = NbSV2; 
55   mySurf1 = S1;
56   mySurf2 = S2;
57   done = Standard_False;
58   TSectionLines.Init(1000);
59   TTangentZones.Init(10000);
60   Perform();
61 }
62
63 void IntPolyh_Intersection::Perform() { 
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   //GeomAbs_SurfaceType ST1 = mySurf1->GetType();
74   //GeomAbs_SurfaceType ST2 = mySurf2->GetType();
75
76 //   if(ST1 == GeomAbs_Torus || ST2 == GeomAbs_Torus)
77 //     startFromAdvanced = Standard_True;
78   
79   IntPolyh_PMaillageAffinage aPMaillageStd = 0;
80   IntPolyh_PMaillageAffinage aPMaillageFF = 0;
81   IntPolyh_PMaillageAffinage aPMaillageFR = 0;
82   IntPolyh_PMaillageAffinage aPMaillageRF = 0;
83   IntPolyh_PMaillageAffinage aPMaillageRR = 0;
84
85
86   if(!startFromAdvanced) {
87
88     isStdDone = PerformStd(aPMaillageStd,nbCouplesStd);
89
90     // default interference done well, use it
91     if(isStdDone && nbCouplesStd > 10) {
92       aPMaillageStd->StartPointsChain(TSectionLines, TTangentZones);
93     }
94     // default interference done, but too few interferences foud;
95     // use advanced interference
96     else if(isStdDone && nbCouplesStd <= 10) {
97       isAdvDone = PerformAdv(aPMaillageFF,aPMaillageFR,aPMaillageRF,aPMaillageRR,nbCouplesAdv);
98       
99       // advanced interference found
100       if(isAdvDone && nbCouplesAdv > 10) {
101         aPMaillageFF->StartPointsChain(TSectionLines,TTangentZones);
102         aPMaillageFR->StartPointsChain(TSectionLines,TTangentZones);
103         aPMaillageRF->StartPointsChain(TSectionLines,TTangentZones);
104         aPMaillageRR->StartPointsChain(TSectionLines,TTangentZones);
105       }
106       else {
107         // use result of default
108         if(nbCouplesStd > 0)
109           aPMaillageStd->StartPointsChain(TSectionLines, TTangentZones);
110       }
111     }
112     // default interference faild, use advanced
113     else {
114 //       isAdvDone = PerformAdv(aPMaillageFF,aPMaillageFR,aPMaillageRF,aPMaillageRR,nbCouplesAdv);
115       
116 //       if(isAdvDone && nbCouplesAdv > 0) {cout << "4adv done, nbc: " << nbCouplesAdv << endl;
117 //      aPMaillageFF->StartPointsChain(TSectionLines,TTangentZones);
118 //      aPMaillageFR->StartPointsChain(TSectionLines,TTangentZones);
119 //      aPMaillageRF->StartPointsChain(TSectionLines,TTangentZones);
120 //      aPMaillageRR->StartPointsChain(TSectionLines,TTangentZones);
121 //       }
122     }
123   }// start from default
124   else {
125     
126     isAdvDone = PerformAdv(aPMaillageFF,aPMaillageFR,aPMaillageRF,aPMaillageRR,nbCouplesAdv);
127
128     // advanced done, interference found; use it
129     if(isAdvDone) {
130
131       if(nbCouplesAdv > 0) {
132         aPMaillageFF->StartPointsChain(TSectionLines,TTangentZones);
133         aPMaillageFR->StartPointsChain(TSectionLines,TTangentZones);
134         aPMaillageRF->StartPointsChain(TSectionLines,TTangentZones);
135         aPMaillageRR->StartPointsChain(TSectionLines,TTangentZones);
136       }
137       else {
138         isStdDone = PerformStd(aPMaillageStd,nbCouplesStd);
139         if(isStdDone && nbCouplesStd > 0)
140           aPMaillageStd->StartPointsChain(TSectionLines, TTangentZones);
141       }
142     }
143     else {
144       isStdDone = PerformStd(aPMaillageStd,nbCouplesStd);
145       if(isStdDone && nbCouplesStd > 0)
146         aPMaillageStd->StartPointsChain(TSectionLines, TTangentZones);
147     }
148   } // start from advanced
149
150   // accept result
151   nbsectionlines = TSectionLines.NbSectionLines();
152   nbtangentzones = TTangentZones.NbTangentZones();
153
154   // clean up
155   if(aPMaillageStd) delete aPMaillageStd;
156   if(aPMaillageFF) delete aPMaillageFF;
157   if(aPMaillageFR) delete aPMaillageFR;
158   if(aPMaillageRF) delete aPMaillageRF;
159   if(aPMaillageRR) delete aPMaillageRR;
160
161   // verify
162   if(!isStdDone && !isAdvDone)
163     done = Standard_False;
164 }
165
166
167 Standard_Boolean IntPolyh_Intersection::IsDone() const {
168   return(done);
169 }
170
171
172 Standard_Integer IntPolyh_Intersection::NbSectionLines() const { 
173   return(nbsectionlines);
174 }
175
176
177 Standard_Integer IntPolyh_Intersection::NbPointsInLine(const Standard_Integer IndexLine) const { 
178   
179   return(TSectionLines[IndexLine-1].NbStartPoints());
180 }
181
182
183 Standard_Integer IntPolyh_Intersection::NbPointsInTangentZone(const Standard_Integer IndexLine) const {   
184   //-- IndexLine--;     (pas implemente) Attention : Tableaux de 0 a n-1 
185   // eap
186   // return(TTangentZones.NbTangentZones());
187   return 1;
188 }
189
190
191 Standard_Integer IntPolyh_Intersection::NbTangentZones() const { 
192   return(nbtangentzones);
193 }
194
195
196 void IntPolyh_Intersection::GetLinePoint(const Standard_Integer Indexl,
197                                  const Standard_Integer Indexp,
198                                  Standard_Real &x,
199                                  Standard_Real &y,
200                                  Standard_Real &z,
201                                  Standard_Real &u1,
202                                  Standard_Real &v1,
203                                  Standard_Real &u2,
204                                  Standard_Real &v2,
205                                  Standard_Real &incidence) const { 
206   const IntPolyh_SectionLine  &msl=TSectionLines[Indexl-1];
207   const IntPolyh_StartPoint   &sp=msl[Indexp-1];
208   x=sp.X();
209   y=sp.Y();
210   z=sp.Z();
211   u1=sp.U1();
212   v1=sp.V1();
213   u2=sp.U2();
214   v2=sp.V2();
215   incidence=sp.GetAngle();
216 }
217
218
219 void IntPolyh_Intersection::GetTangentZonePoint(const Standard_Integer Indexz,
220                                         const Standard_Integer Indexp,
221                                         Standard_Real &x,
222                                         Standard_Real &y,
223                                         Standard_Real &z,
224                                         Standard_Real &u1,
225                                         Standard_Real &v1,
226                                         Standard_Real &u2,
227                                         Standard_Real &v2) const { 
228   //--   Indexz--;    tableaux C
229   // eap
230   //const IntPolyh_StartPoint   &sp=TTangentZones[Indexp-1];
231   const IntPolyh_StartPoint   &sp=TTangentZones[Indexz-1];
232   x=sp.X();
233   y=sp.Y();
234   z=sp.Y();
235   u1=sp.U1();
236   v1=sp.V1();
237   u2=sp.U2();
238   v2=sp.V2();
239 }
240
241 //  Modified by skv - Thu Sep 25 18:07:41 2003 OCC567 Begin
242 //=======================================================================
243 //function : PerformMaillage
244 //purpose  : Computes MaillageAffinage
245 //=======================================================================
246 Standard_Boolean IntPolyh_Intersection::PerformMaillage
247                  (const Standard_Boolean            isFirstFwd,
248                   const Standard_Boolean            isSecondFwd,
249                         IntPolyh_PMaillageAffinage &theMaillageS)
250 {
251   if (myNbSU1 == -1)
252     theMaillageS = new IntPolyh_MaillageAffinage(mySurf1, mySurf2, MYPRINT);
253   else
254     theMaillageS = new IntPolyh_MaillageAffinage(mySurf1, myNbSU1, myNbSV1,
255                                                  mySurf2, myNbSU2, myNbSV2,
256                                                  MYPRINT);
257
258   theMaillageS->FillArrayOfPnt(1, isFirstFwd);
259   theMaillageS->FillArrayOfPnt(2, isSecondFwd);
260   
261   
262   Standard_Real xx0,yy0,zz0,xx1,yy1,zz1;
263   theMaillageS->CommonBox(theMaillageS->GetBox(1), theMaillageS->GetBox(2),
264                           xx0, yy0, zz0, xx1, yy1, zz1);
265   
266   theMaillageS->FillArrayOfEdges(1);
267   theMaillageS->FillArrayOfEdges(2);
268
269   theMaillageS->FillArrayOfTriangles(1);
270   theMaillageS->FillArrayOfTriangles(2);
271   
272   theMaillageS->LinkEdges2Triangles();
273   
274   theMaillageS->TrianglesDeflectionsRefinementBSB();
275
276   Standard_Integer FinTTC = theMaillageS->TriangleCompare();
277
278   // if too many intersections, consider surfaces parallel (eap)
279   if(FinTTC > 200 &&
280      (FinTTC >= theMaillageS->GetArrayOfTriangles(1).NbTriangles() ||
281       FinTTC >= theMaillageS->GetArrayOfTriangles(2).NbTriangles()) ) {
282     return Standard_False;
283   }
284
285   return Standard_True;
286 }
287
288 //=======================================================================
289 //function : PerformMaillage
290 //purpose  : Computes MaillageAffinage
291 //=======================================================================
292 Standard_Boolean IntPolyh_Intersection::PerformMaillage(IntPolyh_PMaillageAffinage &theMaillageS)
293 {
294   if (myNbSU1 == -1)
295     theMaillageS = new IntPolyh_MaillageAffinage(mySurf1, mySurf2, MYPRINT);
296   else
297     theMaillageS = new IntPolyh_MaillageAffinage(mySurf1, myNbSU1, myNbSV1,
298                                                  mySurf2, myNbSU2, myNbSV2,
299                                                  MYPRINT);
300
301   theMaillageS->FillArrayOfPnt(1);
302   theMaillageS->FillArrayOfPnt(2);
303   
304   
305   Standard_Real xx0,yy0,zz0,xx1,yy1,zz1;
306   theMaillageS->CommonBox(theMaillageS->GetBox(1), theMaillageS->GetBox(2),
307                           xx0, yy0, zz0, xx1, yy1, zz1);
308   
309   theMaillageS->FillArrayOfEdges(1);
310   theMaillageS->FillArrayOfEdges(2);
311
312   theMaillageS->FillArrayOfTriangles(1);
313   theMaillageS->FillArrayOfTriangles(2);
314   
315   theMaillageS->LinkEdges2Triangles();
316   
317   theMaillageS->TrianglesDeflectionsRefinementBSB();
318
319   Standard_Integer FinTTC = theMaillageS->TriangleCompare();
320
321   if( FinTTC == 0 ) {
322     Standard_Boolean myZone = Standard_True;
323     theMaillageS->SetEnlargeZone( myZone );
324     theMaillageS->FillArrayOfPnt(1);
325     theMaillageS->FillArrayOfPnt(2);
326     theMaillageS->CommonBox(theMaillageS->GetBox(1), theMaillageS->GetBox(2),
327                             xx0, yy0, zz0, xx1, yy1, zz1);
328     theMaillageS->FillArrayOfEdges(1);
329     theMaillageS->FillArrayOfEdges(2);
330     theMaillageS->FillArrayOfTriangles(1);
331     theMaillageS->FillArrayOfTriangles(2);
332     theMaillageS->LinkEdges2Triangles();
333     theMaillageS->TrianglesDeflectionsRefinementBSB();
334     FinTTC = theMaillageS->TriangleCompare();
335     myZone = Standard_False;
336     theMaillageS->SetEnlargeZone( myZone );
337   }
338
339   // if too many intersections, consider surfaces parallel (eap)
340   if(FinTTC > 200 &&
341      (FinTTC >= theMaillageS->GetArrayOfTriangles(1).NbTriangles() ||
342       FinTTC >= theMaillageS->GetArrayOfTriangles(2).NbTriangles()) ) {
343     return Standard_False;
344   }
345
346   return Standard_True;
347 }
348
349 //=======================================================================
350 //function : MergeCouples
351 //purpose  : This method analyzes arrays to find same couples. If some 
352 //           are detected it leaves the couple in only one array 
353 //           deleting from others.
354 //=======================================================================
355
356 void IntPolyh_Intersection::MergeCouples
357                             (IntPolyh_ArrayOfCouples &anArrayFF,
358                              IntPolyh_ArrayOfCouples &anArrayFR,
359                              IntPolyh_ArrayOfCouples &anArrayRF,
360                              IntPolyh_ArrayOfCouples &anArrayRR) const
361 {
362   // Step 1: Sorting arrays.
363   IntPolyh_ArrayOfCouples *anArrays[4];
364   Standard_Integer         aNbCouples[4];
365   Standard_Integer         i;
366   IntPolyh_ArrayOfCouples *aTmpPtr;
367   Standard_Integer         aTmpNbr;
368
369   anArrays[0] = &anArrayFF;
370   anArrays[1] = &anArrayFR;
371   anArrays[2] = &anArrayRF;
372   anArrays[3] = &anArrayRR;
373
374   for (i = 0; i < 4; i++)
375     aNbCouples[i] = anArrays[i]->NbCouples();
376
377   Standard_Boolean isChanged = Standard_True;
378
379   while (isChanged) {
380     isChanged = Standard_False;
381
382     for (i = 0; i < 3; i++) {
383       if (aNbCouples[i] < aNbCouples[i + 1]) {
384         aTmpPtr           = anArrays[i];
385         anArrays[i]       = anArrays[i + 1];
386         anArrays[i + 1]   = aTmpPtr;
387         aTmpNbr           = aNbCouples[i];
388         aNbCouples[i]     = aNbCouples[i + 1];
389         aNbCouples[i + 1] = aTmpNbr;
390         isChanged         = Standard_True;
391       }
392     }
393   }
394
395   // Step 2: Searching for same couples.
396   Standard_Integer j;
397   Standard_Integer indC1;
398   Standard_Integer indC2;
399
400   for (i = 0; i < 3; i++) {
401     for (j = i + 1; j < 4; j++) {
402       for (indC1 = 1; indC1 <= aNbCouples[i]; indC1++) {
403         IntPolyh_Couple &aCouple1 = anArrays[i]->ChangeValue(indC1);
404
405         if (aCouple1.AnalyseFlagValue() == 1)
406           continue;
407
408         for (indC2 = 1; indC2 <= aNbCouples[j]; indC2++) {
409           IntPolyh_Couple &aCouple2 = anArrays[j]->ChangeValue(indC2);
410
411           if (aCouple2.AnalyseFlagValue() == 1)
412             continue;
413
414           if (aCouple1.FirstValue()  == aCouple2.FirstValue() &&
415               aCouple1.SecondValue() == aCouple2.SecondValue()) {
416             aCouple2.SetAnalyseFlag(1);
417           }
418         }
419       }
420     }
421   }
422 }
423 //  Modified by skv - Thu Sep 25 18:07:42 2003 OCC567 End
424
425 Standard_Boolean IntPolyh_Intersection::PerformStd(IntPolyh_PMaillageAffinage& MaillageS,
426                                                    Standard_Integer&           NbCouples)
427 {
428   Standard_Boolean isdone = PerformMaillage(MaillageS);
429   NbCouples = (isdone) ? (MaillageS->GetArrayOfCouples().NbCouples()) : 0;
430   return isdone;
431 }
432
433 Standard_Boolean IntPolyh_Intersection::PerformAdv(IntPolyh_PMaillageAffinage& MaillageFF,
434                                                    IntPolyh_PMaillageAffinage& MaillageFR,
435                                                    IntPolyh_PMaillageAffinage& MaillageRF,
436                                                    IntPolyh_PMaillageAffinage& MaillageRR,
437                                                    Standard_Integer&           NbCouples)
438 {
439   Standard_Boolean isdone = Standard_True;
440   NbCouples = 0;
441
442   if(!PerformMaillage(Standard_True,Standard_False,MaillageFR) ||
443      !PerformMaillage(Standard_False,Standard_True,MaillageRF) ||
444      !PerformMaillage(Standard_True,Standard_True,MaillageFF)  ||
445      !PerformMaillage(Standard_False,Standard_False,MaillageRR) )
446     isdone = Standard_False; 
447
448   if(isdone) {
449     NbCouples = MaillageFF->GetArrayOfCouples().NbCouples() +
450       MaillageFR->GetArrayOfCouples().NbCouples() +
451         MaillageRF->GetArrayOfCouples().NbCouples() +
452           MaillageRR->GetArrayOfCouples().NbCouples();
453
454     if(NbCouples > 0)
455       MergeCouples(MaillageFF->GetArrayOfCouples(),MaillageFR->GetArrayOfCouples(),
456                    MaillageRF->GetArrayOfCouples(),MaillageRR->GetArrayOfCouples());
457   }
458   return isdone;
459 }