1 // Created on: 2005-09-26
2 // Created by: Igor FEOKTISTOV
3 // Copyright (c) 2005-2014 OPEN CASCADE SAS
5 // This file is part of Open CASCADE Technology software library.
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.
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
16 #include <IntPolyh_Intersection.ixx>
17 #include <IntPolyh_PMaillageAffinage.hxx>
18 #include <IntPolyh_MaillageAffinage.hxx>
19 #include <IntPolyh_ArrayOfCouples.hxx>
20 #include <IntPolyh_Couple.hxx>
21 #include <IntPolyh_Triangle.hxx>
23 Standard_Integer MYPRINT1 = 0;
26 //=======================================================================
27 //function : IntPolyh_Intersection
29 //=======================================================================
31 IntPolyh_Intersection::IntPolyh_Intersection(const Handle(Adaptor3d_HSurface)& S1,
32 const TColStd_Array1OfReal& Upars1,
33 const TColStd_Array1OfReal& Vpars1,
34 const Handle(Adaptor3d_HSurface)& S2,
35 const TColStd_Array1OfReal& Upars2,
36 const TColStd_Array1OfReal& Vpars2)
38 myNbSU1 = Upars1.Length();
39 myNbSV1 = Vpars1.Length();
40 myNbSU2 = Upars2.Length();
41 myNbSV2 = Vpars2.Length();
44 done = Standard_False;
45 TSectionLines.Init(1000);
46 TTangentZones.Init(10000);
47 Perform(Upars1, Vpars1, Upars2, Vpars2);
50 //=======================================================================
53 //=======================================================================
55 void IntPolyh_Intersection::Perform(const TColStd_Array1OfReal& Upars1,
56 const TColStd_Array1OfReal& Vpars1,
57 const TColStd_Array1OfReal& Upars2,
58 const TColStd_Array1OfReal& Vpars2) {
62 Standard_Boolean startFromAdvanced = Standard_False;
63 Standard_Boolean isStdDone = Standard_False;
64 Standard_Boolean isAdvDone = Standard_False;
65 Standard_Integer nbCouplesStd = 0;
66 Standard_Integer nbCouplesAdv = 0;
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;
76 if(!startFromAdvanced) {
78 isStdDone = PerformStd(Upars1, Vpars1, Upars2, Vpars2,
79 aPMaillageStd,nbCouplesStd);
81 // default interference done well, use it
82 if(isStdDone && nbCouplesStd > 10) {
83 aPMaillageStd->StartPointsChain(TSectionLines, TTangentZones);
85 // default interference done, but too few interferences foud;
86 // use advanced interference
87 else if(isStdDone && nbCouplesStd <= 10) {
88 isAdvDone = PerformAdv(Upars1, Vpars1, Upars2, Vpars2,
89 aPMaillageFF,aPMaillageFR,aPMaillageRF,aPMaillageRR,nbCouplesAdv);
91 // advanced interference found
92 if(isAdvDone && nbCouplesAdv > 10) {
93 aPMaillageFF->StartPointsChain(TSectionLines,TTangentZones);
94 aPMaillageFR->StartPointsChain(TSectionLines,TTangentZones);
95 aPMaillageRF->StartPointsChain(TSectionLines,TTangentZones);
96 aPMaillageRR->StartPointsChain(TSectionLines,TTangentZones);
99 // use result of default
101 aPMaillageStd->StartPointsChain(TSectionLines, TTangentZones);
104 // default interference faild, use advanced
106 // isAdvDone = PerformAdv(aPMaillageFF,aPMaillageFR,aPMaillageRF,aPMaillageRR,nbCouplesAdv);
108 // if(isAdvDone && nbCouplesAdv > 0) {cout << "4adv done, nbc: " << nbCouplesAdv << endl;
109 // aPMaillageFF->StartPointsChain(TSectionLines,TTangentZones);
110 // aPMaillageFR->StartPointsChain(TSectionLines,TTangentZones);
111 // aPMaillageRF->StartPointsChain(TSectionLines,TTangentZones);
112 // aPMaillageRR->StartPointsChain(TSectionLines,TTangentZones);
115 }// start from default
118 isAdvDone = PerformAdv(Upars1, Vpars1, Upars2, Vpars2,
119 aPMaillageFF,aPMaillageFR,aPMaillageRF,aPMaillageRR,nbCouplesAdv);
121 // advanced done, interference found; use it
124 if(nbCouplesAdv > 0) {
125 aPMaillageFF->StartPointsChain(TSectionLines,TTangentZones);
126 aPMaillageFR->StartPointsChain(TSectionLines,TTangentZones);
127 aPMaillageRF->StartPointsChain(TSectionLines,TTangentZones);
128 aPMaillageRR->StartPointsChain(TSectionLines,TTangentZones);
131 isStdDone = PerformStd(aPMaillageStd,nbCouplesStd);
132 if(isStdDone && nbCouplesStd > 0)
133 aPMaillageStd->StartPointsChain(TSectionLines, TTangentZones);
137 isStdDone = PerformStd(Upars1, Vpars1, Upars2, Vpars2,
138 aPMaillageStd,nbCouplesStd);
139 if(isStdDone && nbCouplesStd > 0)
140 aPMaillageStd->StartPointsChain(TSectionLines, TTangentZones);
142 } // start from advanced
145 nbsectionlines = TSectionLines.NbItems();
146 nbtangentzones = TTangentZones.NbItems();
149 if(aPMaillageStd) delete aPMaillageStd;
150 if(aPMaillageFF) delete aPMaillageFF;
151 if(aPMaillageFR) delete aPMaillageFR;
152 if(aPMaillageRF) delete aPMaillageRF;
153 if(aPMaillageRR) delete aPMaillageRR;
156 if(!isStdDone && !isAdvDone)
157 done = Standard_False;
160 //=======================================================================
161 //function : PerformMaillage
162 //purpose : Computes MaillageAffinage
163 //=======================================================================
164 Standard_Boolean IntPolyh_Intersection::PerformMaillage(const Standard_Boolean isFirstFwd,
165 const Standard_Boolean isSecondFwd,
166 const TColStd_Array1OfReal& Upars1,
167 const TColStd_Array1OfReal& Vpars1,
168 const TColStd_Array1OfReal& Upars2,
169 const TColStd_Array1OfReal& Vpars2,
170 IntPolyh_PMaillageAffinage &theMaillageS)
172 theMaillageS = new IntPolyh_MaillageAffinage(mySurf1, Upars1.Length(), Vpars1.Length(),
173 mySurf2, Upars2.Length(), Vpars2.Length(),
177 theMaillageS->FillArrayOfPnt(1, isFirstFwd, Upars1, Vpars1);
178 theMaillageS->FillArrayOfPnt(2, isSecondFwd, Upars2, Vpars2);
182 Standard_Real xx0,yy0,zz0,xx1,yy1,zz1;
183 theMaillageS->CommonBox(theMaillageS->GetBox(1), theMaillageS->GetBox(2),
184 xx0, yy0, zz0, xx1, yy1, zz1);
186 theMaillageS->FillArrayOfEdges(1);
187 theMaillageS->FillArrayOfEdges(2);
189 theMaillageS->FillArrayOfTriangles(1);
190 theMaillageS->FillArrayOfTriangles(2);
192 theMaillageS->LinkEdges2Triangles();
194 theMaillageS->TrianglesDeflectionsRefinementBSB();
196 Standard_Integer FinTTC = theMaillageS->TriangleCompare();
198 // if too many intersections, consider surfaces parallel (eap)
201 (FinTTC >= theMaillageS->GetArrayOfTriangles(1).NbTriangles() ||
202 FinTTC >= theMaillageS->GetArrayOfTriangles(2).NbTriangles()) ) {
203 return Standard_False;
206 //IFV test for parallel surf
208 const Standard_Real eps = .996; //~ cos of 5deg.
209 IntPolyh_ArrayOfCouples& Couples = theMaillageS->GetArrayOfCouples();
211 Standard_Integer i, npara = 0;
212 for(i = 0; i < FinTTC; ++i) {
213 Standard_Real cosa = Abs(Couples[i].AngleValue());
214 if(cosa > eps) ++npara;
216 if(npara >= theMaillageS->GetArrayOfTriangles(1).NbItems() ||
217 npara >= theMaillageS->GetArrayOfTriangles(2).NbItems() ) {
218 return Standard_False;
222 return Standard_True;
225 //=======================================================================
226 //function : PerformMaillage
227 //purpose : Computes MaillageAffinage
228 //=======================================================================
229 Standard_Boolean IntPolyh_Intersection::PerformMaillage(const TColStd_Array1OfReal& Upars1,
230 const TColStd_Array1OfReal& Vpars1,
231 const TColStd_Array1OfReal& Upars2,
232 const TColStd_Array1OfReal& Vpars2,
233 IntPolyh_PMaillageAffinage &theMaillageS)
236 theMaillageS = new IntPolyh_MaillageAffinage(mySurf1, Upars1.Length(), Vpars1.Length(),
237 mySurf2, Upars2.Length(), Vpars2.Length(),
240 theMaillageS->FillArrayOfPnt(1, Upars1, Vpars1);
241 theMaillageS->FillArrayOfPnt(2, Upars2, Vpars2);
244 Standard_Real xx0,yy0,zz0,xx1,yy1,zz1;
245 theMaillageS->CommonBox(theMaillageS->GetBox(1), theMaillageS->GetBox(2),
246 xx0, yy0, zz0, xx1, yy1, zz1);
247 theMaillageS->FillArrayOfEdges(1);
248 theMaillageS->FillArrayOfEdges(2);
250 theMaillageS->FillArrayOfTriangles(1);
251 theMaillageS->FillArrayOfTriangles(2);
253 theMaillageS->LinkEdges2Triangles();
255 theMaillageS->TrianglesDeflectionsRefinementBSB();
257 Standard_Integer FinTTC = theMaillageS->TriangleCompare();
260 Standard_Boolean myZone = Standard_True;
261 theMaillageS->SetEnlargeZone( myZone );
262 theMaillageS->FillArrayOfPnt(1);
263 theMaillageS->FillArrayOfPnt(2);
264 theMaillageS->CommonBox(theMaillageS->GetBox(1), theMaillageS->GetBox(2),
265 xx0, yy0, zz0, xx1, yy1, zz1);
266 theMaillageS->FillArrayOfEdges(1);
267 theMaillageS->FillArrayOfEdges(2);
268 theMaillageS->FillArrayOfTriangles(1);
269 theMaillageS->FillArrayOfTriangles(2);
270 theMaillageS->LinkEdges2Triangles();
271 theMaillageS->TrianglesDeflectionsRefinementBSB();
272 FinTTC = theMaillageS->TriangleCompare();
273 myZone = Standard_False;
274 theMaillageS->SetEnlargeZone( myZone );
277 // if too many intersections, consider surfaces parallel (eap)
280 (FinTTC >= theMaillageS->GetArrayOfTriangles(1).NbTriangles() ||
281 FinTTC >= theMaillageS->GetArrayOfTriangles(2).NbTriangles()) ) {
282 return Standard_False;
285 //IFV test for parallel surf
287 const Standard_Real eps = .996; //~ cos of 5deg.
288 IntPolyh_ArrayOfCouples& Couples = theMaillageS->GetArrayOfCouples();
290 Standard_Integer i, npara = 0;
291 for(i = 0; i < FinTTC; ++i) {
292 Standard_Real cosa = Abs(Couples[i].AngleValue());
293 if(cosa > eps) ++npara;
295 if(npara >= theMaillageS->GetArrayOfTriangles(1).NbItems() ||
296 npara >= theMaillageS->GetArrayOfTriangles(2).NbItems() ) {
297 return Standard_False;
301 return Standard_True;
304 //=======================================================================
305 //function : PerformAdv
307 //=======================================================================
309 Standard_Boolean IntPolyh_Intersection::PerformAdv(const TColStd_Array1OfReal& Upars1,
310 const TColStd_Array1OfReal& Vpars1,
311 const TColStd_Array1OfReal& Upars2,
312 const TColStd_Array1OfReal& Vpars2,
313 IntPolyh_PMaillageAffinage& MaillageFF,
314 IntPolyh_PMaillageAffinage& MaillageFR,
315 IntPolyh_PMaillageAffinage& MaillageRF,
316 IntPolyh_PMaillageAffinage& MaillageRR,
317 Standard_Integer& NbCouples)
319 Standard_Boolean isdone = Standard_True;
322 if(!PerformMaillage(Standard_True,Standard_False,
323 Upars1, Vpars1, Upars2, Vpars2,
325 !PerformMaillage(Standard_False,Standard_True,
326 Upars1, Vpars1, Upars2, Vpars2,
328 !PerformMaillage(Standard_True,Standard_True,
329 Upars1, Vpars1, Upars2, Vpars2,
331 !PerformMaillage(Standard_False,Standard_False,
332 Upars1, Vpars1, Upars2, Vpars2,
334 isdone = Standard_False;
337 NbCouples = MaillageFF->GetArrayOfCouples().NbItems() +
338 MaillageFR->GetArrayOfCouples().NbItems() +
339 MaillageRF->GetArrayOfCouples().NbItems() +
340 MaillageRR->GetArrayOfCouples().NbItems();
343 MergeCouples(MaillageFF->GetArrayOfCouples(),MaillageFR->GetArrayOfCouples(),
344 MaillageRF->GetArrayOfCouples(),MaillageRR->GetArrayOfCouples());
348 //=======================================================================
349 //function : PerformStd
351 //=======================================================================
353 Standard_Boolean IntPolyh_Intersection::PerformStd(const TColStd_Array1OfReal& Upars1,
354 const TColStd_Array1OfReal& Vpars1,
355 const TColStd_Array1OfReal& Upars2,
356 const TColStd_Array1OfReal& Vpars2,
357 IntPolyh_PMaillageAffinage& MaillageS,
358 Standard_Integer& NbCouples)
360 Standard_Boolean isdone = PerformMaillage(Upars1, Vpars1, Upars2, Vpars2,
362 NbCouples = (isdone) ? (MaillageS->GetArrayOfCouples().NbItems()) : 0;