Integration of OCCT 6.5.0 from SVN
[occt.git] / src / IntPatch / IntPatch_ImpImpIntersection_4.gxx
CommitLineData
7fd59977 1// File: IntPatch_ImpImpIntersection_4.gxx
2// Created: Thu May 7 08:47:45 1992
3// Author: Jacques GOUSSARD
4// Copyright: OPEN CASCADE 1992
5
6#include <IntAna_ListOfCurve.hxx>
7#include <IntAna_ListIteratorOfListOfCurve.hxx>
8
9static
10 Standard_Boolean ExploreCurve(const gp_Cylinder& aCy,
11 const gp_Cone& aCo,
12 IntAna_Curve& aC,
13 const Standard_Real aTol,
14 IntAna_ListOfCurve& aLC);
15static
16 Standard_Boolean IsToReverse(const gp_Cylinder& Cy1,
17 const gp_Cylinder& Cy2,
18 const Standard_Real Tol);
19
20//=======================================================================
21//function : ProcessBounds
22//purpose :
23//=======================================================================
24void ProcessBounds(const Handle(IntPatch_ALine)& alig, //-- ligne courante
25 const IntPatch_SequenceOfLine& slin,
26 const IntSurf_Quadric& Quad1,
27 const IntSurf_Quadric& Quad2,
28 Standard_Boolean& procf,
29 const gp_Pnt& ptf, //-- Debut Ligne Courante
30 const Standard_Real first, //-- Paramf
31 Standard_Boolean& procl,
32 const gp_Pnt& ptl, //-- Fin Ligne courante
33 const Standard_Real last, //-- Paraml
34 Standard_Boolean& Multpoint,
35 const Standard_Real Tol)
36{
37 Standard_Integer j,k;
38 Standard_Real U1,V1,U2,V2;
39 IntPatch_Point ptsol;
40 Standard_Real d;
41
42 if (procf && procl) {
43 j = slin.Length() + 1;
44 }
45 else {
46 j = 1;
47 }
48
49
50 //-- On prend les lignes deja enregistrees
51
52 while (j <= slin.Length()) {
53 if(slin.Value(j)->ArcType() == IntPatch_Analytic) {
54 const Handle(IntPatch_ALine)& aligold = *((Handle(IntPatch_ALine)*)&slin.Value(j));
55 k = 1;
56
57 //-- On prend les vertex des lignes deja enregistrees
58
59 while (k <= aligold->NbVertex()) {
60 ptsol = aligold->Vertex(k);
61 if (!procf) {
62 d=ptf.Distance(ptsol.Value());
63 if (d <= Tol) {
64 if (!ptsol.IsMultiple()) {
65 //-- le point ptsol (de aligold) est declare multiple sur aligold
66 Multpoint = Standard_True;
67 ptsol.SetMultiple(Standard_True);
68 aligold->Replace(k,ptsol);
69 }
70 ptsol.SetParameter(first);
71 alig->AddVertex(ptsol);
72 alig->SetFirstPoint(alig->NbVertex());
73 procf = Standard_True;
74
75 //-- On restore le point avec son parametre sur aligold
76 ptsol = aligold->Vertex(k);
77
78 }
79 }
80 if (!procl) {
81 if (ptl.Distance(ptsol.Value()) <= Tol) {
82 if (!ptsol.IsMultiple()) {
83 Multpoint = Standard_True;
84 ptsol.SetMultiple(Standard_True);
85 aligold->Replace(k,ptsol);
86 }
87 ptsol.SetParameter(last);
88 alig->AddVertex(ptsol);
89 alig->SetLastPoint(alig->NbVertex());
90 procl = Standard_True;
91
92 //-- On restore le point avec son parametre sur aligold
93 ptsol = aligold->Vertex(k);
94
95 }
96 }
97 if (procf && procl) {
98 k = aligold->NbVertex()+1;
99 }
100 else {
101 k = k+1;
102 }
103 }
104 if (procf && procl) {
105 j = slin.Length()+1;
106 }
107 else {
108 j = j+1;
109 }
110 }
111 }
112 if (!procf && !procl) {
113 Quad1.Parameters(ptf,U1,V1);
114 Quad2.Parameters(ptf,U2,V2);
115 ptsol.SetValue(ptf,Tol,Standard_False);
116 ptsol.SetParameters(U1,V1,U2,V2);
117 ptsol.SetParameter(first);
118 if (ptf.Distance(ptl) <= Tol) {
119 ptsol.SetMultiple(Standard_True); // a voir
120 Multpoint = Standard_True; // a voir de meme
121 alig->AddVertex(ptsol);
122 alig->SetFirstPoint(alig->NbVertex());
123
124 ptsol.SetParameter(last);
125 alig->AddVertex(ptsol);
126 alig->SetLastPoint(alig->NbVertex());
127 }
128 else {
129 alig->AddVertex(ptsol);
130 alig->SetFirstPoint(alig->NbVertex());
131 Quad1.Parameters(ptl,U1,V1);
132 Quad2.Parameters(ptl,U2,V2);
133 ptsol.SetValue(ptl,Tol,Standard_False);
134 ptsol.SetParameters(U1,V1,U2,V2);
135 ptsol.SetParameter(last);
136 alig->AddVertex(ptsol);
137 alig->SetLastPoint(alig->NbVertex());
138 }
139 }
140 else if (!procf) {
141 Quad1.Parameters(ptf,U1,V1);
142 Quad2.Parameters(ptf,U2,V2);
143 ptsol.SetValue(ptf,Tol,Standard_False);
144 ptsol.SetParameters(U1,V1,U2,V2);
145 ptsol.SetParameter(first);
146 alig->AddVertex(ptsol);
147 alig->SetFirstPoint(alig->NbVertex());
148 }
149 else if (!procl) {
150 Quad1.Parameters(ptl,U1,V1);
151 Quad2.Parameters(ptl,U2,V2);
152 ptsol.SetValue(ptl,Tol,Standard_False);
153 ptsol.SetParameters(U1,V1,U2,V2);
154 ptsol.SetParameter(last);
155 alig->AddVertex(ptsol);
156 alig->SetLastPoint(alig->NbVertex());
157 }
158}
159//=======================================================================
160//function : IntCyCy
161//purpose :
162//=======================================================================
163Standard_Boolean IntCyCy(const IntSurf_Quadric& Quad1,
164 const IntSurf_Quadric& Quad2,
165 const Standard_Real Tol,
166 Standard_Boolean& Empty,
167 Standard_Boolean& Same,
168 Standard_Boolean& Multpoint,
169 IntPatch_SequenceOfLine& slin,
170 IntPatch_SequenceOfPoint& spnt)
171
172{
173 IntPatch_Point ptsol;
174
175 Standard_Integer i;
176
177 IntSurf_TypeTrans trans1,trans2;
178 IntAna_ResultType typint;
179
180 gp_Elips elipsol;
181 gp_Lin linsol;
182
183 gp_Cylinder Cy1(Quad1.Cylinder());
184 gp_Cylinder Cy2(Quad2.Cylinder());
185
186 IntAna_QuadQuadGeo inter(Cy1,Cy2,Tol);
187
188 if (!inter.IsDone()) {return Standard_False;}
189
190 typint = inter.TypeInter();
191 Standard_Integer NbSol = inter.NbSolutions();
192 Empty = Standard_False;
193 Same = Standard_False;
194
195 switch (typint) {
196
197 case IntAna_Empty :
198 {
199 Empty = Standard_True;
200 }
201 break;
202
203 case IntAna_Same:
204 {
205 Same = Standard_True;
206 }
207 break;
208
209
210 case IntAna_Point :
211 {
212 gp_Pnt psol(inter.Point(1));
213 Standard_Real U1,V1,U2,V2;
214 Quad1.Parameters(psol,U1,V1);
215 Quad2.Parameters(psol,U2,V2);
216 ptsol.SetValue(psol,Tol,Standard_True);
217 ptsol.SetParameters(U1,V1,U2,V2);
218 spnt.Append(ptsol);
219 }
220 break;
221
222 case IntAna_Line:
223 {
224 gp_Pnt ptref;
225 if (NbSol == 1) { // ligne de tangence
226 linsol = inter.Line(1);
227 ptref = linsol.Location();
228 gp_Dir crb1(gp_Vec(ptref,Cy1.Location()));
229 gp_Dir crb2(gp_Vec(ptref,Cy2.Location()));
230 gp_Vec norm1(Quad1.Normale(ptref));
231 gp_Vec norm2(Quad2.Normale(ptref));
232 IntSurf_Situation situcyl1;
233 IntSurf_Situation situcyl2;
234
235 if (crb1.Dot(crb2) < 0.) { // centre de courbures "opposes"
236 if (norm1.Dot(crb1) > 0.) {
237 situcyl2 = IntSurf_Inside;
238 }
239 else {
240 situcyl2 = IntSurf_Outside;
241 }
242 if (norm2.Dot(crb2) > 0.) {
243 situcyl1 = IntSurf_Inside;
244 }
245 else {
246 situcyl1 = IntSurf_Outside;
247 }
248 }
249 else {
250 if (Cy1.Radius() < Cy2.Radius()) {
251 if (norm1.Dot(crb1) > 0.) {
252 situcyl2 = IntSurf_Inside;
253 }
254 else {
255 situcyl2 = IntSurf_Outside;
256 }
257 if (norm2.Dot(crb2) > 0.) {
258 situcyl1 = IntSurf_Outside;
259 }
260 else {
261 situcyl1 = IntSurf_Inside;
262 }
263 }
264 else {
265 if (norm1.Dot(crb1) > 0.) {
266 situcyl2 = IntSurf_Outside;
267 }
268 else {
269 situcyl2 = IntSurf_Inside;
270 }
271 if (norm2.Dot(crb2) > 0.) {
272 situcyl1 = IntSurf_Inside;
273 }
274 else {
275 situcyl1 = IntSurf_Outside;
276 }
277 }
278 }
279 Handle(IntPatch_GLine) glig = new IntPatch_GLine(linsol, Standard_True, situcyl1, situcyl2);
280 slin.Append(glig);
281 }
282 else {
283 for (i=1; i <= NbSol; i++) {
284 linsol = inter.Line(i);
285 ptref = linsol.Location();
286 gp_Vec lsd = linsol.Direction();
287 Standard_Real qwe = lsd.DotCross(Quad2.Normale(ptref),Quad1.Normale(ptref));
288 if (qwe >0.00000001) {
289 trans1 = IntSurf_Out;
290 trans2 = IntSurf_In;
291 }
292 else if (qwe <-0.00000001) {
293 trans1 = IntSurf_In;
294 trans2 = IntSurf_Out;
295 }
296 else {
297 trans1=trans2=IntSurf_Undecided;
298 }
299
300 Handle(IntPatch_GLine) glig = new IntPatch_GLine(linsol, Standard_False,trans1,trans2);
301 slin.Append(glig);
302 }
303 }
304 }
305 break;
306
307 case IntAna_Ellipse:
308 {
309 gp_Vec Tgt;
310 gp_Pnt ptref;
311 IntPatch_Point pmult1;
312 IntPatch_Point pmult2;
313 elipsol = inter.Ellipse(1);
314 gp_Pnt pttang1(ElCLib::Value(PI*0.5,elipsol));
315 gp_Pnt pttang2(ElCLib::Value(1.5*PI,elipsol));
316
317 Multpoint = Standard_True;
318 pmult1.SetValue(pttang1,Tol,Standard_True);
319 pmult2.SetValue(pttang2,Tol,Standard_True);
320 pmult1.SetMultiple(Standard_True);
321 pmult2.SetMultiple(Standard_True);
322
323 Standard_Real oU1,oV1,oU2,oV2;
324 Quad1.Parameters(pttang1,oU1,oV1);
325 Quad2.Parameters(pttang1,oU2,oV2);
326 pmult1.SetParameters(oU1,oV1,oU2,oV2);
327
328 Quad1.Parameters(pttang2,oU1,oV1);
329 Quad2.Parameters(pttang2,oU2,oV2);
330 pmult2.SetParameters(oU1,oV1,oU2,oV2);
331
332
333 // on traite la premiere ellipse
334
335 //-- Calcul de la Transition de la ligne
336 ElCLib::D1(0.,elipsol,ptref,Tgt);
337 Standard_Real qwe=Tgt.DotCross(Quad2.Normale(ptref),Quad1.Normale(ptref));
338 if (qwe>0.00000001) {
339 trans1 = IntSurf_Out;
340 trans2 = IntSurf_In;
341 }
342 else if (qwe<-0.00000001) {
343 trans1 = IntSurf_In;
344 trans2 = IntSurf_Out;
345 }
346 else {
347 trans1=trans2=IntSurf_Undecided;
348 }
349 //-- Transition calculee au point 0 -> Trans2 , Trans1
350 //-- car ici, on devarit calculer en PI
351 Handle(IntPatch_GLine) glig = new IntPatch_GLine(elipsol,Standard_False,trans2,trans1);
352 pmult1.SetParameter(PI/2.);
353 glig->AddVertex(pmult1);
354 glig->SetFirstPoint(1);
355 pmult2.SetParameter(1.5*PI);
356 glig->AddVertex(pmult2);
357 glig->SetLastPoint(2);
358 slin.Append(glig);
359
360 //-- Transitions calculee au point 0 OK
361 glig = new IntPatch_GLine(elipsol,Standard_False,trans1,trans2);
362 pmult2.SetParameter(-PI/2.);
363 glig->AddVertex(pmult2);
364 glig->SetFirstPoint(1);
365 glig->AddVertex(pmult1);
366 glig->SetLastPoint(2);
367 slin.Append(glig);
368
369
370 // on traite la deuxieme ellipse
371
372 elipsol = inter.Ellipse(2);
373
374 Standard_Real param1 = ElCLib::Parameter(elipsol,pttang1);
375 Standard_Real param2 = ElCLib::Parameter(elipsol,pttang2);
376 Standard_Real parampourtransition;
377 if (param1 < param2) {
378 pmult1.SetParameter(PI*0.5);
379 pmult2.SetParameter(1.5*PI);
380 parampourtransition = PI;
381 }
382 else {
383 pmult1.SetParameter(-PI*0.5);
384 pmult2.SetParameter(PI*0.5);
385 parampourtransition = 0.0;
386 }
387
388 //-- Calcul des transitions de ligne pour la premiere ligne
389 ElCLib::D1(parampourtransition,elipsol,ptref,Tgt);
390 qwe=Tgt.DotCross(Quad2.Normale(ptref),Quad1.Normale(ptref));
391 if(qwe> 0.00000001) {
392 trans1 = IntSurf_Out;
393 trans2 = IntSurf_In;
394 }
395 else if(qwe< -0.00000001) {
396 trans1 = IntSurf_In;
397 trans2 = IntSurf_Out;
398 }
399 else {
400 trans1=trans2=IntSurf_Undecided;
401 }
402 //-- La transition a ete calculee sur un point de cette ligne
403 glig = new IntPatch_GLine(elipsol,Standard_False,trans1,trans2);
404 glig->AddVertex(pmult1);
405 glig->SetFirstPoint(1);
406 glig->AddVertex(pmult2);
407 glig->SetLastPoint(2);
408 slin.Append(glig);
409
410 if (param1 < param2) {
411 pmult2.SetParameter(-PI*0.5);
412 }
413 else {
414 pmult1.SetParameter(1.5*PI);
415 }
416
417 //-- Sur l'autre ligne, on invertse la transition
418 glig = new IntPatch_GLine(elipsol,Standard_False,trans2,trans1);
419 glig->AddVertex(pmult2);
420 glig->SetFirstPoint(1);
421 glig->AddVertex(pmult1);
422 glig->SetLastPoint(2);
423 slin.Append(glig);
424 }
425 break;
426
427
428 case IntAna_NoGeometricSolution:
429 {
430 Standard_Boolean bReverse;
431 Standard_Real U1,V1,U2,V2;
432 gp_Pnt psol;
433 //
434 bReverse=IsToReverse(Cy1, Cy2, Tol);
435 if (bReverse){
436 Cy2=Quad1.Cylinder();
437 Cy1=Quad2.Cylinder();
438 }
439 //
440 IntAna_IntQuadQuad anaint(Cy1,Cy2,Tol);
441 if (!anaint.IsDone()) {
442 return Standard_False;
443 }
444
445 if (anaint.NbPnt() == 0 && anaint.NbCurve() == 0) {
446 Empty = Standard_True;
447 }
448 else {
449 NbSol = anaint.NbPnt();
450 for (i = 1; i <= NbSol; i++) {
451 psol = anaint.Point(i);
452 Quad1.Parameters(psol,U1,V1);
453 Quad2.Parameters(psol,U2,V2);
454 ptsol.SetValue(psol,Tol,Standard_True);
455 ptsol.SetParameters(U1,V1,U2,V2);
456 spnt.Append(ptsol);
457 }
458
459 gp_Pnt ptvalid, ptf, ptl;
460 gp_Vec tgvalid;
461
462 Standard_Real first,last,para;
463 IntAna_Curve curvsol;
464 Standard_Boolean tgfound;
465 Standard_Integer kount;
466
467 NbSol = anaint.NbCurve();
468 for (i = 1; i <= NbSol; i++) {
469 curvsol = anaint.Curve(i);
470 curvsol.Domain(first,last);
471 ptf = curvsol.Value(first);
472 ptl = curvsol.Value(last);
473
474 para = last;
475 kount = 1;
476 tgfound = Standard_False;
477
478 while (!tgfound) {
479 para = (1.123*first + para)/2.123;
480 tgfound = curvsol.D1u(para,ptvalid,tgvalid);
481 if (!tgfound) {
482 kount ++;
483 tgfound = kount > 5;
484 }
485 }
486 Handle(IntPatch_ALine) alig;
487 if (kount <= 5) {
488 Standard_Real qwe = tgvalid.DotCross(Quad2.Normale(ptvalid),
489 Quad1.Normale(ptvalid));
490 if(qwe>0.00000001) {
491 trans1 = IntSurf_Out;
492 trans2 = IntSurf_In;
493 }
494 else if(qwe<-0.00000001) {
495 trans1 = IntSurf_In;
496 trans2 = IntSurf_Out;
497 }
498 else {
499 trans1=trans2=IntSurf_Undecided;
500 }
501 alig = new IntPatch_ALine(curvsol,Standard_False,trans1,trans2);
502 }
503 else {
504 alig = new IntPatch_ALine(curvsol,Standard_False);
505 //-- cout << "Transition indeterminee" << endl;
506 }
507 Standard_Boolean TempFalse1 = Standard_False;
508 Standard_Boolean TempFalse2 = Standard_False;
509
510 ProcessBounds(alig,slin,Quad1,Quad2,TempFalse1,ptf,first,
511 TempFalse2,ptl,last,Multpoint,Tol);
512 slin.Append(alig);
513 }
514 }
515 }
516 break;
517
518 default:
519 {
520 return Standard_False;
521 }
522 }
523 return Standard_True;
524}
525
526
527//=======================================================================
528//function : IntCySp
529//purpose :
530//=======================================================================
531Standard_Boolean IntCySp(const IntSurf_Quadric& Quad1,
532 const IntSurf_Quadric& Quad2,
533 const Standard_Real Tol,
534 const Standard_Boolean Reversed,
535 Standard_Boolean& Empty,
536 Standard_Boolean& Multpoint,
537 IntPatch_SequenceOfLine& slin,
538 IntPatch_SequenceOfPoint& spnt)
539
540{
541 Standard_Integer i;
542
543 IntSurf_TypeTrans trans1,trans2;
544 IntAna_ResultType typint;
545 IntPatch_Point ptsol;
546 gp_Circ cirsol;
547
548 gp_Cylinder Cy;
549 gp_Sphere Sp;
550
551 if (!Reversed) {
552 Cy = Quad1.Cylinder();
553 Sp = Quad2.Sphere();
554 }
555 else {
556 Cy = Quad2.Cylinder();
557 Sp = Quad1.Sphere();
558 }
559 IntAna_QuadQuadGeo inter(Cy,Sp,Tol);
560
561 if (!inter.IsDone()) {return Standard_False;}
562
563 typint = inter.TypeInter();
564 Standard_Integer NbSol = inter.NbSolutions();
565 Empty = Standard_False;
566
567 switch (typint) {
568
569 case IntAna_Empty :
570 {
571 Empty = Standard_True;
572 }
573 break;
574
575 case IntAna_Point :
576 {
577 gp_Pnt psol(inter.Point(1));
578 Standard_Real U1,V1,U2,V2;
579 Quad1.Parameters(psol,U1,V1);
580 Quad2.Parameters(psol,U2,V2);
581 ptsol.SetValue(psol,Tol,Standard_True);
582 ptsol.SetParameters(U1,V1,U2,V2);
583 spnt.Append(ptsol);
584 }
585 break;
586
587 case IntAna_Circle:
588 {
589 cirsol = inter.Circle(1);
590 gp_Vec Tgt;
591 gp_Pnt ptref;
592 ElCLib::D1(0.,cirsol,ptref,Tgt);
593
594 if (NbSol == 1) {
595 gp_Vec TestCurvature(ptref,Sp.Location());
596 gp_Vec Normsp,Normcyl;
597 if (!Reversed) {
598 Normcyl = Quad1.Normale(ptref);
599 Normsp = Quad2.Normale(ptref);
600 }
601 else {
602 Normcyl = Quad2.Normale(ptref);
603 Normsp = Quad1.Normale(ptref);
604 }
605
606 IntSurf_Situation situcyl;
607 IntSurf_Situation situsp;
608
609 if (Normcyl.Dot(TestCurvature) > 0.) {
610 situsp = IntSurf_Outside;
611 if (Normsp.Dot(Normcyl) > 0.) {
612 situcyl = IntSurf_Inside;
613 }
614 else {
615 situcyl = IntSurf_Outside;
616 }
617 }
618 else {
619 situsp = IntSurf_Inside;
620 if (Normsp.Dot(Normcyl) > 0.) {
621 situcyl = IntSurf_Outside;
622 }
623 else {
624 situcyl = IntSurf_Inside;
625 }
626 }
627 Handle(IntPatch_GLine) glig;
628 if (!Reversed) {
629 glig = new IntPatch_GLine(cirsol, Standard_True, situcyl, situsp);
630 }
631 else {
632 glig = new IntPatch_GLine(cirsol, Standard_True, situsp, situcyl);
633 }
634 slin.Append(glig);
635 }
636 else {
637 if (Tgt.DotCross(Quad2.Normale(ptref),Quad1.Normale(ptref)) > 0.0) {
638 trans1 = IntSurf_Out;
639 trans2 = IntSurf_In;
640 }
641 else {
642 trans1 = IntSurf_In;
643 trans2 = IntSurf_Out;
644 }
645 Handle(IntPatch_GLine) glig = new IntPatch_GLine(cirsol,Standard_False,trans1,trans2);
646 slin.Append(glig);
647
648 cirsol = inter.Circle(2);
649 ElCLib::D1(0.,cirsol,ptref,Tgt);
650 Standard_Real qwe = Tgt.DotCross(Quad2.Normale(ptref),Quad1.Normale(ptref));
651 if(qwe> 0.0000001) {
652 trans1 = IntSurf_Out;
653 trans2 = IntSurf_In;
654 }
655 else if(qwe<-0.0000001) {
656 trans1 = IntSurf_In;
657 trans2 = IntSurf_Out;
658 }
659 else {
660 trans1=trans2=IntSurf_Undecided;
661 }
662 glig = new IntPatch_GLine(cirsol,Standard_False,trans1,trans2);
663 slin.Append(glig);
664 }
665 }
666 break;
667
668 case IntAna_NoGeometricSolution:
669 {
670 gp_Pnt psol;
671 Standard_Real U1,V1,U2,V2;
672 IntAna_IntQuadQuad anaint(Cy,Sp,Tol);
673 if (!anaint.IsDone()) {
674 return Standard_False;
675 }
676
677 if (anaint.NbPnt()==0 && anaint.NbCurve()==0) {
678 Empty = Standard_True;
679 }
680 else {
681
682 NbSol = anaint.NbPnt();
683 for (i = 1; i <= NbSol; i++) {
684 psol = anaint.Point(i);
685 Quad1.Parameters(psol,U1,V1);
686 Quad2.Parameters(psol,U2,V2);
687 ptsol.SetValue(psol,Tol,Standard_True);
688 ptsol.SetParameters(U1,V1,U2,V2);
689 spnt.Append(ptsol);
690 }
691
692 gp_Pnt ptvalid,ptf,ptl;
693 gp_Vec tgvalid;
694 Standard_Real first,last,para;
695 IntAna_Curve curvsol;
696 Standard_Boolean tgfound;
697 Standard_Integer kount;
698
699 NbSol = anaint.NbCurve();
700 for (i = 1; i <= NbSol; i++) {
701 curvsol = anaint.Curve(i);
702 curvsol.Domain(first,last);
703 ptf = curvsol.Value(first);
704 ptl = curvsol.Value(last);
705
706 para = last;
707 kount = 1;
708 tgfound = Standard_False;
709
710 while (!tgfound) {
711 para = (1.123*first + para)/2.123;
712 tgfound = curvsol.D1u(para,ptvalid,tgvalid);
713 if (!tgfound) {
714 kount ++;
715 tgfound = kount > 5;
716 }
717 }
718 Handle(IntPatch_ALine) alig;
719 if (kount <= 5) {
720 Standard_Real qwe = tgvalid.DotCross(Quad2.Normale(ptvalid),
721 Quad1.Normale(ptvalid));
722 if(qwe> 0.00000001) {
723 trans1 = IntSurf_Out;
724 trans2 = IntSurf_In;
725 }
726 else if(qwe<-0.00000001) {
727 trans1 = IntSurf_In;
728 trans2 = IntSurf_Out;
729 }
730 else {
731 trans1=trans2=IntSurf_Undecided;
732 }
733 alig = new IntPatch_ALine(curvsol,Standard_False,trans1,trans2);
734 }
735 else {
736 alig = new IntPatch_ALine(curvsol,Standard_False);
737 }
738 Standard_Boolean TempFalse1a = Standard_False;
739 Standard_Boolean TempFalse2a = Standard_False;
740
741 //-- ptf et ptl : points debut et fin de alig
742
743 ProcessBounds(alig,slin,Quad1,Quad2,TempFalse1a,ptf,first,
744 TempFalse2a,ptl,last,Multpoint,Tol);
745 slin.Append(alig);
746 } //-- boucle sur les lignes
747 } //-- solution avec au moins une lihne
748 }
749 break;
750
751 default:
752 {
753 return Standard_False;
754 }
755 }
756 return Standard_True;
757}
758//=======================================================================
759//function : IntCyCo
760//purpose :
761//=======================================================================
762Standard_Boolean IntCyCo(const IntSurf_Quadric& Quad1,
763 const IntSurf_Quadric& Quad2,
764 const Standard_Real Tol,
765 const Standard_Boolean Reversed,
766 Standard_Boolean& Empty,
767 Standard_Boolean& Multpoint,
768 IntPatch_SequenceOfLine& slin,
769 IntPatch_SequenceOfPoint& spnt)
770
771{
772 IntPatch_Point ptsol;
773
774 Standard_Integer i;
775
776 IntSurf_TypeTrans trans1,trans2;
777 IntAna_ResultType typint;
778 gp_Circ cirsol;
779
780 gp_Cylinder Cy;
781 gp_Cone Co;
782
783 if (!Reversed) {
784 Cy = Quad1.Cylinder();
785 Co = Quad2.Cone();
786 }
787 else {
788 Cy = Quad2.Cylinder();
789 Co = Quad1.Cone();
790 }
791 IntAna_QuadQuadGeo inter(Cy,Co,Tol);
792
793 if (!inter.IsDone()) {return Standard_False;}
794
795 typint = inter.TypeInter();
796 Standard_Integer NbSol = inter.NbSolutions();
797 Empty = Standard_False;
798
799 switch (typint) {
800
801 case IntAna_Empty : {
802 Empty = Standard_True;
803 }
804 break;
805
806 case IntAna_Point :{
807 gp_Pnt psol(inter.Point(1));
808 Standard_Real U1,V1,U2,V2;
809 Quad1.Parameters(psol,U1,V1);
810 Quad1.Parameters(psol,U2,V2);
811 ptsol.SetValue(psol,Tol,Standard_True);
812 ptsol.SetParameters(U1,V1,U2,V2);
813 spnt.Append(ptsol);
814 }
815 break;
816
817 case IntAna_Circle: {
818 gp_Vec Tgt;
819 gp_Pnt ptref;
820 Standard_Integer j;
821 Standard_Real qwe;
822 //
823 for(j=1; j<=2; ++j) {
824 cirsol = inter.Circle(j);
825 ElCLib::D1(0.,cirsol,ptref,Tgt);
826 qwe = Tgt.DotCross(Quad2.Normale(ptref),Quad1.Normale(ptref));
827 if(qwe> 0.00000001) {
828 trans1 = IntSurf_Out;
829 trans2 = IntSurf_In;
830 }
831 else if(qwe<-0.00000001) {
832 trans1 = IntSurf_In;
833 trans2 = IntSurf_Out;
834 }
835 else {
836 trans1=trans2=IntSurf_Undecided;
837 }
838 Handle(IntPatch_GLine) glig = new IntPatch_GLine(cirsol,Standard_False,trans1,trans2);
839 slin.Append(glig);
840 }
841 }
842 break;
843
844 case IntAna_NoGeometricSolution: {
845 gp_Pnt psol;
846 Standard_Real U1,V1,U2,V2;
847 IntAna_IntQuadQuad anaint(Cy,Co,Tol);
848 if (!anaint.IsDone()) {
849 return Standard_False;
850 }
851
852 if (anaint.NbPnt() == 0 && anaint.NbCurve() == 0) {
853 Empty = Standard_True;
854 }
855 else {
856 NbSol = anaint.NbPnt();
857 for (i = 1; i <= NbSol; i++) {
858 psol = anaint.Point(i);
859 Quad1.Parameters(psol,U1,V1);
860 Quad2.Parameters(psol,U2,V2);
861 ptsol.SetValue(psol,Tol,Standard_True);
862 ptsol.SetParameters(U1,V1,U2,V2);
863 spnt.Append(ptsol);
864 }
865
866 gp_Pnt ptvalid, ptf, ptl;
867 gp_Vec tgvalid;
868 //
869 Standard_Real first,last,para;
870 Standard_Boolean tgfound,firstp,lastp,kept;
871 Standard_Integer kount;
872 //
873 //
874 //IntAna_Curve curvsol;
875 IntAna_Curve aC;
876 IntAna_ListOfCurve aLC;
877 IntAna_ListIteratorOfListOfCurve aIt;
878 Standard_Boolean bToSplit;
879
880 //
881 NbSol = anaint.NbCurve();
882 for (i = 1; i <= NbSol; ++i) {
883 kept = Standard_False;
884 //curvsol = anaint.Curve(i);
885 aC=anaint.Curve(i);
886 aLC.Clear();
887 bToSplit=ExploreCurve(Cy, Co, aC, 10.*Tol, aLC);
888 //
889 aIt.Initialize(aLC);
890 for (; aIt.More(); aIt.Next()) {
891 IntAna_Curve& curvsol=aIt.Value();
892 //
893 curvsol.Domain(first, last);
894 firstp = !curvsol.IsFirstOpen();
895 lastp = !curvsol.IsLastOpen();
896 if (firstp) {
897 ptf = curvsol.Value(first);
898 }
899 if (lastp) {
900 ptl = curvsol.Value(last);
901 }
902 para = last;
903 kount = 1;
904 tgfound = Standard_False;
905
906 while (!tgfound) {
907 para = (1.123*first + para)/2.123;
908 tgfound = curvsol.D1u(para,ptvalid,tgvalid);
909 if (!tgfound) {
910 kount ++;
911 tgfound = kount > 5;
912 }
913 }
914 Handle(IntPatch_ALine) alig;
915 if (kount <= 5) {
916 Standard_Real qwe = tgvalid.DotCross(Quad2.Normale(ptvalid),
917 Quad1.Normale(ptvalid));
918 if(qwe> 0.00000001) {
919 trans1 = IntSurf_Out;
920 trans2 = IntSurf_In;
921 }
922 else if(qwe<-0.00000001) {
923 trans1 = IntSurf_In;
924 trans2 = IntSurf_Out;
925 }
926 else {
927 trans1=trans2=IntSurf_Undecided;
928 }
929 alig = new IntPatch_ALine(curvsol,Standard_False,trans1,trans2);
930 kept = Standard_True;
931 }
932 else {
933 ptvalid = curvsol.Value(para);
934 alig = new IntPatch_ALine(curvsol,Standard_False);
935 kept = Standard_True;
936 //-- cout << "Transition indeterminee" << endl;
937 }
938 if (kept) {
939 Standard_Boolean Nfirstp = !firstp;
940 Standard_Boolean Nlastp = !lastp;
941 ProcessBounds(alig,slin,Quad1,Quad2,Nfirstp,ptf,first,
942 Nlastp,ptl,last,Multpoint,Tol);
943 slin.Append(alig);
944 }
945 } // for (; aIt.More(); aIt.Next())
946 } // for (i = 1; i <= NbSol; ++i)
947 }
948 }
949 break;
950
951 default:
952 return Standard_False;
953
954 } // switch (typint)
955
956 return Standard_True;
957}
958//=======================================================================
959//function : ExploreCurve
960//purpose :
961//=======================================================================
962Standard_Boolean ExploreCurve(const gp_Cylinder& ,//aCy,
963 const gp_Cone& aCo,
964 IntAna_Curve& aC,
965 const Standard_Real aTol,
966 IntAna_ListOfCurve& aLC)
967
968{
969 Standard_Boolean bFind=Standard_False;
970 Standard_Real aTheta, aT1, aT2, aDst;
971 gp_Pnt aPapx, aPx;
972 //
973 //aC.Dump();
974 //
975 aLC.Clear();
976 aLC.Append(aC);
977 //
978 aPapx=aCo.Apex();
979 //
980 aC.Domain(aT1, aT2);
981 //
982 aPx=aC.Value(aT1);
983 aDst=aPx.Distance(aPapx);
984 if (aDst<aTol) {
985 return bFind;
986 }
987 aPx=aC.Value(aT2);
988 aDst=aPx.Distance(aPapx);
989 if (aDst<aTol) {
990 return bFind;
991 }
992 //
993 bFind=aC.FindParameter(aPapx, aTheta);
994 if (!bFind){
995 return bFind;
996 }
997 //
998 aPx=aC.Value(aTheta);
999 aDst=aPx.Distance(aPapx);
1000 if (aDst>aTol) {
1001 return !bFind;
1002 }
1003 //
1004 // need to be splitted at aTheta
1005 IntAna_Curve aC1, aC2;
1006 //
1007 aC1=aC;
1008 aC1.SetDomain(aT1, aTheta);
1009 aC2=aC;
1010 aC2.SetDomain(aTheta, aT2);
1011 //
1012 aLC.Clear();
1013 aLC.Append(aC1);
1014 aLC.Append(aC2);
1015 //
1016 return bFind;
1017}
1018//=======================================================================
1019//function : IsToReverse
1020//purpose :
1021//=======================================================================
1022Standard_Boolean IsToReverse(const gp_Cylinder& Cy1,
1023 const gp_Cylinder& Cy2,
1024 const Standard_Real Tol)
1025{
1026 Standard_Boolean bRet;
1027 Standard_Real aR1,aR2, dR, aSc1, aSc2;
1028 //
1029 bRet=Standard_False;
1030 //
1031 aR1=Cy1.Radius();
1032 aR2=Cy2.Radius();
1033 dR=aR1-aR2;
1034 if (dR<0.) {
1035 dR=-dR;
1036 }
1037 if (dR>Tol) {
1038 bRet=aR1>aR2;
1039 }
1040 else {
1041 gp_Dir aDZ(0.,0.,1.);
1042 //
1043 const gp_Dir& aDir1=Cy1.Axis().Direction();
1044 aSc1=aDir1*aDZ;
1045 if (aSc1<0.) {
1046 aSc1=-aSc1;
1047 }
1048 //
1049 const gp_Dir& aDir2=Cy2.Axis().Direction();
1050 aSc2=aDir2*aDZ;
1051 if (aSc2<0.) {
1052 aSc2=-aSc2;
1053 }
1054 //
1055 if (aSc2<aSc1) {
1056 bRet=!bRet;
1057 }
1058 }//if (dR<Tol) {
1059 return bRet;
1060}