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