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