0024915: Wrong intersection curves between two cylinders
[occt.git] / src / IntPatch / IntPatch_ImpImpIntersection_2.gxx
CommitLineData
b311480e 1// Created on: 1992-05-07
2// Created by: Jacques GOUSSARD
3// Copyright (c) 1992-1999 Matra Datavision
973c2be1 4// Copyright (c) 1999-2014 OPEN CASCADE SAS
b311480e 5//
973c2be1 6// This file is part of Open CASCADE Technology software library.
b311480e 7//
d5f74e42 8// This library is free software; you can redistribute it and/or modify it under
9// the terms of the GNU Lesser General Public License version 2.1 as published
973c2be1 10// by the Free Software Foundation, with special exception defined in the file
11// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12// distribution for complete text of the license and disclaimer of any warranty.
b311480e 13//
973c2be1 14// Alternatively, this file may be used under the terms of Open CASCADE
15// commercial license or contractual agreement.
7fd59977 16
7eed5d29 17static
18 Standard_Integer SetQuad(const Handle(Adaptor3d_HSurface)& theS,
19 GeomAbs_SurfaceType& theTS,
20 IntSurf_Quadric& theQuad);
21
c5c34473
J
22//=======================================================================
23//function : IntPatch_ImpImpIntersection
24//purpose :
25//=======================================================================
7fd59977 26IntPatch_ImpImpIntersection::IntPatch_ImpImpIntersection ():
27 done(Standard_False)
28{
29}
c5c34473
J
30//=======================================================================
31//function : IntPatch_ImpImpIntersection
32//purpose :
33//=======================================================================
7fd59977 34IntPatch_ImpImpIntersection::IntPatch_ImpImpIntersection
35 (const Handle(Adaptor3d_HSurface)& S1,
7eed5d29 36 const Handle(Adaptor3d_TopolTool)& D1,
7fd59977 37 const Handle(Adaptor3d_HSurface)& S2,
7eed5d29 38 const Handle(Adaptor3d_TopolTool)& D2,
39 const Standard_Real TolArc,
40 const Standard_Real TolTang)
7fd59977 41{
42 Perform(S1,D1,S2,D2,TolArc,TolTang);
43}
c5c34473
J
44//=======================================================================
45//function : Perform
46//purpose :
47//=======================================================================
7fd59977 48void IntPatch_ImpImpIntersection::Perform(const Handle(Adaptor3d_HSurface)& S1,
7eed5d29 49 const Handle(Adaptor3d_TopolTool)& D1,
50 const Handle(Adaptor3d_HSurface)& S2,
51 const Handle(Adaptor3d_TopolTool)& D2,
52 const Standard_Real TolArc,
ecc4f148 53 const Standard_Real TolTang,
54 const Standard_Boolean isTheTrimmed) {
7fd59977 55 done = Standard_False;
ecc4f148 56 Standard_Boolean isTrimmed = isTheTrimmed;
7fd59977 57 spnt.Clear();
58 slin.Clear();
59
60 empt = Standard_True;
61 tgte = Standard_False;
62 oppo = Standard_False;
63
64 Standard_Boolean all1 = Standard_False;
65 Standard_Boolean all2 = Standard_False;
66 Standard_Boolean SameSurf = Standard_False;
67 Standard_Boolean multpoint = Standard_False;
68
69 Standard_Boolean nosolonS1 = Standard_False;
c5c34473 70 // indique s il y a des points sur restriction du carreau 1
7fd59977 71 Standard_Boolean nosolonS2 = Standard_False;
c5c34473 72 // indique s il y a des points sur restriction du carreau 2
7fd59977 73 Standard_Integer i, nbpt, nbseg;
7fd59977 74 IntPatch_SequenceOfSegmentOfTheSOnBounds edg1,edg2;
75 IntPatch_SequenceOfPathPointOfTheSOnBounds pnt1,pnt2;
c5c34473 76 //
7fd59977 77 // On commence par intersecter les supports des surfaces
7eed5d29 78 IntSurf_Quadric quad1, quad2;
7fd59977 79 IntPatch_ArcFunction AFunc;
788cbaf4 80 const Standard_Real Tolang = 1.e-8;
7eed5d29 81 GeomAbs_SurfaceType typs1, typs2;
82 Standard_Boolean bEmpty = Standard_False;
c5c34473 83 //
7eed5d29 84 const Standard_Integer iT1 = SetQuad(S1, typs1, quad1);
85 const Standard_Integer iT2 = SetQuad(S2, typs2, quad2);
86 //
87 if (!iT1 || !iT2) {
88 Standard_ConstructionError::Raise();
89 return;
90 }
91 //
92 const Standard_Boolean bReverse = iT1 > iT2;
93 const Standard_Integer iTT = iT1*10 + iT2;
94 //
95 switch (iTT) {
96 case 11: { // Plane/Plane
97 if (!IntPP(quad1, quad2, Tolang, TolTang, SameSurf, slin)) {
98 return;
7fd59977 99 }
7eed5d29 100 break;
7fd59977 101 }
7eed5d29 102 //
103 case 12:
104 case 21: { // Plane/Cylinder
105 Standard_Real VMin, VMax, H;
106 //
107 const Handle(Adaptor3d_HSurface)& aSCyl = bReverse ? S2 : S1;
108 VMin = aSCyl->FirstVParameter();
109 VMax = aSCyl->LastVParameter();
110 H = (Precision::IsNegativeInfinite(VMin) ||
111 Precision::IsPositiveInfinite(VMax)) ? 0 : (VMax - VMin);
112 //
113 if (!IntPCy(quad1, quad2, Tolang, TolTang, bReverse, empt, slin, H)) {
114 return;
7fd59977 115 }
7eed5d29 116 bEmpty = empt;
117 break;
7fd59977 118 }
7eed5d29 119 //
120 case 13:
121 case 31: { // Plane/Cone
122 if (!IntPCo(quad1, quad2, Tolang, TolTang, bReverse, empt, multpoint, slin, spnt)) {
123 return;
7fd59977 124 }
7eed5d29 125 bEmpty = empt;
126 break;
7fd59977 127 }
7eed5d29 128 //
129 case 14:
130 case 41: { // Plane/Sphere
131 if (!IntPSp(quad1, quad2, Tolang, TolTang, bReverse, empt, slin, spnt)) {
132 return;
7fd59977 133 }
7eed5d29 134 bEmpty = empt;
135 break;
7fd59977 136 }
7eed5d29 137 //
138 case 15:
139 case 51: { // Plane/Torus
140 if (!IntPTo(quad1, quad2, TolTang, bReverse, empt, slin)) {
141 return;
142 }
143 bEmpty = empt;
144 break;
145 }
146 //
ecc4f148 147 case 22:
148 { // Cylinder/Cylinder
149 Standard_Boolean isDONE = Standard_False;
150
151 if(!isTrimmed)
152 {
153 isDONE = IntCyCy(quad1, quad2, TolTang, empt,
154 SameSurf, multpoint, slin, spnt);
155 }
156 else
157 {
158 Bnd_Box2d aBox1, aBox2;
159
160 const Standard_Real aU1f = S1->FirstUParameter();
161 const Standard_Real aU1l = S1->LastUParameter();
162 const Standard_Real aU2f = S2->FirstUParameter();
163 const Standard_Real aU2l = S2->LastUParameter();
164
165 aBox1.Add(gp_Pnt2d(aU1f, S1->FirstVParameter()));
166 aBox1.Add(gp_Pnt2d(aU1l, S1->LastVParameter()));
167 aBox2.Add(gp_Pnt2d(aU2f, S2->FirstVParameter()));
168 aBox2.Add(gp_Pnt2d(aU2l, S2->LastVParameter()));
169
170 const Standard_Real a2DTol = Min( S1->UResolution(TolTang),
171 S2->UResolution(TolTang));
172
173 Standard_Boolean isReversed = ((aU2l - aU2f) < (aU1l - aU1f));
174
175 if(isReversed)
176 {
177 isDONE = IntCyCyTrim(quad2, quad1, TolTang, a2DTol, aBox2, aBox1,
178 isReversed, empt, slin, spnt);
179 }
180 else
181 {
182 isDONE = IntCyCyTrim(quad1, quad2, TolTang, a2DTol, aBox1, aBox2,
183 isReversed, empt, slin, spnt);
184 }
185
186 if(!isDONE)
187 {
188 isDONE = IntCyCy(quad1, quad2, TolTang, empt,
189 SameSurf, multpoint, slin, spnt);
190 isTrimmed = Standard_False;
191 }
192 }
193
194 if (!isDONE)
195 {
196 return;
197 }
198
199 bEmpty = empt;
200 break;
7eed5d29 201 }
7eed5d29 202 //
203 case 23:
204 case 32: { // Cylinder/Cone
205 if (!IntCyCo(quad1, quad2, TolTang, bReverse, empt, multpoint, slin, spnt)) {
206 return;
207 }
208 bEmpty = empt;
209 break;
210 }
211 //
212 case 24:
213 case 42: { // Cylinder/Sphere
214 if (!IntCySp(quad1, quad2, TolTang, bReverse, empt, multpoint, slin, spnt)) {
215 return;
216 }
217 bEmpty = empt;
218 break;
219 }
220 //
221 case 25:
222 case 52: { // Cylinder/Torus
223 if (!IntCyTo(quad1, quad2, TolTang, bReverse, empt, slin)) {
224 return;
225 }
226 bEmpty = empt;
227 break;
228 }
229 //
230 case 33: { // Cone/Cone
231 if (!IntCoCo(quad1, quad2, TolTang, empt, SameSurf, multpoint, slin, spnt)) {
232 return;
233 }
234 bEmpty = empt;
235 break;
236 }
237 //
238 case 34:
239 case 43: { // Cone/Sphere
240 if (!IntCoSp(quad1, quad2, TolTang, bReverse, empt, multpoint, slin, spnt)) {
241 return;
242 }
243 bEmpty = empt;
244 break;
245 }
246 //
247 case 35:
248 case 53: { // Cone/Torus
249 if (!IntCoTo(quad1, quad2, TolTang, bReverse, empt, slin)) {
250 return;
251 }
252 break;
253 }
254 //
255 case 44: { // Sphere/Sphere
256 if (!IntSpSp(quad1, quad2, TolTang, empt, SameSurf, slin, spnt)) {
257 return;
258 }
259 bEmpty = empt;
260 break;
261 }
262 //
263 case 45:
264 case 54: { // Sphere/Torus
265 if (!IntSpTo(quad1, quad2, TolTang, bReverse, empt, slin)) {
266 return;
267 }
268 bEmpty = empt;
269 break;
270 }
271 //
272 case 55: { // Torus/Torus
273 if (!IntToTo(quad1, quad2, TolTang, SameSurf, empt, slin)) {
274 return;
275 }
276 bEmpty = empt;
277 break;
278 }
279 //
280 default: {
7fd59977 281 Standard_ConstructionError::Raise();
282 break;
283 }
7eed5d29 284 }
285 //
286 if (bEmpty) {
287 done = Standard_True;
288 return;
289 }
c5c34473 290 //
ecc4f148 291
292 if(!isTrimmed)
293 {
294 if (!SameSurf) {
295 AFunc.SetQuadric(quad2);
296 AFunc.Set(S1);
7fd59977 297
ecc4f148 298 solrst.Perform(AFunc, D1, TolArc, TolTang);
299 if (!solrst.IsDone()) {
300 return;
301 }
7fd59977 302
ecc4f148 303 if (solrst.AllArcSolution() && typs1 == typs2) {
304 all1 = Standard_True;
305 }
306 nbpt = solrst.NbPoints();
307 nbseg= solrst.NbSegments();
308 for (i=1; i<= nbpt; i++) {
309 pnt1.Append(solrst.Point(i));
310 }
311 for (i=1; i<= nbseg; i++) {
312 edg1.Append(solrst.Segment(i));
313 }
314 nosolonS1 = (nbpt == 0) && (nbseg == 0);
7fd59977 315
ecc4f148 316 if (nosolonS1 && all1) { // cas de face sans restrictions
317 all1 = Standard_False;
318 }
319 }//if (!SameSurf) {
320 else {
321 nosolonS1 = Standard_True;
7fd59977 322 }
7fd59977 323
ecc4f148 324 if (!SameSurf) {
325 AFunc.SetQuadric(quad1);
326 AFunc.Set(S2);
7fd59977 327
ecc4f148 328 solrst.Perform(AFunc, D2, TolArc, TolTang);
329 if (!solrst.IsDone()) {
330 return;
331 }
7fd59977 332
ecc4f148 333 if (solrst.AllArcSolution() && typs1 == typs2) {
334 all2 = Standard_True;
335 }
336 nbpt = solrst.NbPoints();
337 nbseg= solrst.NbSegments();
338 for (i=1; i<= nbpt; i++) {
339 pnt2.Append(solrst.Point(i));
340 }
7fd59977 341
ecc4f148 342 for (i=1; i<= nbseg; i++) {
343 edg2.Append(solrst.Segment(i));
344 }
345 nosolonS2 = (nbpt == 0) && (nbseg == 0);
7fd59977 346
ecc4f148 347 if (nosolonS2 && all2) { // cas de face sans restrictions
348 all2 = Standard_False;
349 }
350 }// if (!SameSurf) {
351 else {
352 nosolonS2 = Standard_True;
7fd59977 353 }
ecc4f148 354 //
355 if (SameSurf || (all1 && all2)) {
356 // faces "paralleles" parfaites
357 empt = Standard_False;
358 tgte = Standard_True;
359 slin.Clear();
360 spnt.Clear();
7fd59977 361
ecc4f148 362 gp_Pnt Ptreference;
7fd59977 363
ecc4f148 364 switch (typs1) {
365 case GeomAbs_Plane: {
366 Ptreference = (S1->Plane()).Location();
367 }
368 break;
369 case GeomAbs_Cylinder: {
370 Ptreference = ElSLib::Value(0.,0.,S1->Cylinder());
371 }
372 break;
373 case GeomAbs_Sphere: {
374 Ptreference = ElSLib::Value(M_PI/4.,M_PI/4.,S1->Sphere());
375 }
376 break;
377 case GeomAbs_Cone: {
378 Ptreference = ElSLib::Value(0.,10.,S1->Cone());
379 }
380 break;
381 case GeomAbs_Torus: {
382 Ptreference = ElSLib::Value(0.,0.,S1->Torus());
383 }
384 break;
385 default:
386 break;
387 }
388 //
389 oppo = quad1.Normale(Ptreference).Dot(quad2.Normale(Ptreference)) < 0.0;
390 done = Standard_True;
391 return;
392 }// if (SameSurf || (all1 && all2)) {
7fd59977 393
ecc4f148 394 if (!nosolonS1 || !nosolonS2) {
395 empt = Standard_False;
396 // C est la qu il faut commencer a bosser...
397 PutPointsOnLine(S1,S2,pnt1, slin, Standard_True, D1, quad1,quad2,
398 multpoint,TolArc);
7fd59977 399
ecc4f148 400 PutPointsOnLine(S1,S2,pnt2, slin, Standard_False,D2, quad2,quad1,
401 multpoint,TolArc);
7fd59977 402
ecc4f148 403 if (edg1.Length() != 0) {
404 ProcessSegments(edg1,slin,quad1,quad2,Standard_True,TolArc);
405 }
7fd59977 406
ecc4f148 407 if (edg2.Length() != 0) {
408 ProcessSegments(edg2,slin,quad1,quad2,Standard_False,TolArc);
409 }
7fd59977 410
ecc4f148 411 if (edg1.Length() !=0 || edg2.Length() !=0) {
412 // ProcessRLine(slin,S1,S2,TolArc);
413 ProcessRLine(slin,quad1,quad2,TolArc);
414 }
415 }//if (!nosolonS1 || !nosolonS2) {
416 else {
417 empt = ((slin.Length()==0) && (spnt.Length()==0));
7fd59977 418 }
7fd59977 419 }
ecc4f148 420
421 Standard_Integer nblin = slin.Length(),
422 aNbPnt = spnt.Length();
c5c34473
J
423 //
424 //modified by NIZNHY-PKV Tue Sep 06 10:03:35 2011f
c5c34473
J
425 if (aNbPnt) {
426 IntPatch_SequenceOfPoint aSIP;
427 //
428 for(i=1; i<=aNbPnt; ++i) {
429 Standard_Real aU1, aV1, aU2, aV2;
430 gp_Pnt2d aP2D;
431 TopAbs_State aState1, aState2;
432 //
433 const IntPatch_Point& aIP=spnt(i);
434 aIP.Parameters(aU1, aV1, aU2, aV2);
435 //
436 aP2D.SetCoord(aU1, aV1);
437 aState1=D1->Classify(aP2D, TolArc);
438 //
439 aP2D.SetCoord(aU2, aV2);
440 aState2=D2->Classify(aP2D, TolArc);
441 //
442 if(aState1!=TopAbs_OUT && aState2!=TopAbs_OUT) {
7eed5d29 443 aSIP.Append(aIP);
c5c34473
J
444 }
445 }
446 //
447 spnt.Clear();
448 //
449 aNbPnt=aSIP.Length();
450 for(i=1; i<=aNbPnt; ++i) {
451 const IntPatch_Point& aIP=aSIP(i);
452 spnt.Append(aIP);
453 }
454 //
455 }// if (aNbPnt) {
456 //modified by NIZNHY-PKV Tue Sep 06 10:18:20 2011t
457 //
7fd59977 458 for(i=1; i<=nblin; i++) {
459 IntPatch_IType thetype = slin.Value(i)->ArcType();
460 if( (thetype == IntPatch_Ellipse)
461 ||(thetype == IntPatch_Circle)
462 ||(thetype == IntPatch_Lin)
463 ||(thetype == IntPatch_Parabola)
464 ||(thetype == IntPatch_Hyperbola)) {
465 Handle(IntPatch_GLine)& glin = *((Handle(IntPatch_GLine)*)&slin.Value(i));
7fd59977 466 glin->ComputeVertexParameters(TolArc);
467 }
468 else if(thetype == IntPatch_Analytic) {
469 Handle(IntPatch_ALine)& aligold = *((Handle(IntPatch_ALine)*)&slin.Value(i));
470 aligold->ComputeVertexParameters(TolArc);
471 }
472 else if(thetype == IntPatch_Restriction) {
473 Handle(IntPatch_RLine)& rlig = *((Handle(IntPatch_RLine)*)&slin.Value(i));
474 rlig->ComputeVertexParameters(TolArc);
475 }
476 }
c5c34473 477 //
7fd59977 478 //----------------------------------------------------------------
479 //-- On place 2 vertex sur les courbes de GLine qui n en
480 //-- contiennent pas.
7fd59977 481 for(i=1; i<=nblin; i++) {
482 gp_Pnt P;
483 IntPatch_Point point;
484 Standard_Real u1,v1,u2,v2;
7fd59977 485 if(slin.Value(i)->ArcType() == IntPatch_Circle) {
486 const Handle(IntPatch_GLine)& glin = *((Handle(IntPatch_GLine)*)&slin.Value(i));
7fd59977 487 if(glin->NbVertex() == 0) {
7eed5d29 488 gp_Circ Circ = glin->Circle();
489 P=ElCLib::Value(0.0,Circ);
490 quad1.Parameters(P,u1,v1);
491 quad2.Parameters(P,u2,v2);
492 point.SetValue(P,TolArc,Standard_False);
493 point.SetParameters(u1,v1,u2,v2);
494 point.SetParameter(0.0);
495 glin->AddVertex(point);
496
497 P=ElCLib::Value(0.0,Circ);
498 quad1.Parameters(P,u1,v1);
499 quad2.Parameters(P,u2,v2);
500 point.SetValue(P,TolArc,Standard_False);
501 point.SetParameters(u1,v1,u2,v2);
502 point.SetParameter(M_PI+M_PI);
503 glin->AddVertex(point);
7fd59977 504 }
505 }
506
507 else if(slin.Value(i)->ArcType() == IntPatch_Ellipse) {
508 const Handle(IntPatch_GLine)& glin = *((Handle(IntPatch_GLine)*)&slin.Value(i));
7fd59977 509 if(glin->NbVertex() == 0) {
7eed5d29 510 gp_Elips Elips = glin->Ellipse();
511 P=ElCLib::Value(0.0,Elips);
512 quad1.Parameters(P,u1,v1);
513 quad2.Parameters(P,u2,v2);
514 point.SetValue(P,TolArc,Standard_False);
515 point.SetParameters(u1,v1,u2,v2);
516 point.SetParameter(0.0);
517 glin->AddVertex(point);
518
519 P=ElCLib::Value(0.0,Elips);
520 quad1.Parameters(P,u1,v1);
521 quad2.Parameters(P,u2,v2);
522 point.SetValue(P,TolArc,Standard_False);
523 point.SetParameters(u1,v1,u2,v2);
524 point.SetParameter(M_PI+M_PI);
525 glin->AddVertex(point);
7fd59977 526 }
527 }
528 }
7fd59977 529 done = Standard_True;
530}
7fd59977 531
7eed5d29 532//=======================================================================
533//function : SetQuad
534//purpose :
535//=======================================================================
536Standard_Integer SetQuad(const Handle(Adaptor3d_HSurface)& theS,
537 GeomAbs_SurfaceType& theTS,
538 IntSurf_Quadric& theQuad)
539{
540 theTS = theS->GetType();
541 Standard_Integer iRet = 0;
542 switch (theTS) {
543 case GeomAbs_Plane:
544 theQuad.SetValue(theS->Plane());
545 iRet = 1;
546 break;
547 case GeomAbs_Cylinder:
548 theQuad.SetValue(theS->Cylinder());
549 iRet = 2;
550 break;
551 case GeomAbs_Cone:
552 theQuad.SetValue(theS->Cone());
553 iRet = 3;
554 break;
555 case GeomAbs_Sphere:
556 theQuad.SetValue(theS->Sphere());
557 iRet = 4;
558 break;
559 case GeomAbs_Torus:
560 theQuad.SetValue(theS->Torus());
561 iRet = 5;
562 break;
563 default:
564 break;
565 }
566 //
567 return iRet;
568}
569