0022879: Possible bug in Opengl_togl_begin_layer_mode.cxx
[occt.git] / src / IntPolyh / IntPolyh_Intersection.cxx
CommitLineData
7fd59977 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
21Standard_Integer MYDISPLAY = 0;
22Standard_Integer MYPRINT = 0;
23
24# if MYDEBUG
25// # include "visudebug.hxx"
26# endif
27
28
29IntPolyh_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
44IntPolyh_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
63void 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
167Standard_Boolean IntPolyh_Intersection::IsDone() const {
168 return(done);
169}
170
171
172Standard_Integer IntPolyh_Intersection::NbSectionLines() const {
173 return(nbsectionlines);
174}
175
176
177Standard_Integer IntPolyh_Intersection::NbPointsInLine(const Standard_Integer IndexLine) const {
178
179 return(TSectionLines[IndexLine-1].NbStartPoints());
180}
181
182
183Standard_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
191Standard_Integer IntPolyh_Intersection::NbTangentZones() const {
192 return(nbtangentzones);
193}
194
195
196void 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
219void 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//=======================================================================
246Standard_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//=======================================================================
292Standard_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
356void 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
425Standard_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
433Standard_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}