1 // Created on: 1992-05-07
2 // Created by: Jacques GOUSSARD
3 // Copyright (c) 1992-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
6 // This file is part of Open CASCADE Technology software library.
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
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.
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
17 #include <gce_MakeLin.hxx>
19 //=======================================================================
22 //=======================================================================
23 Standard_Boolean IntCoCo(const IntSurf_Quadric& Quad1,
24 const IntSurf_Quadric& Quad2,
25 const Standard_Real Tol,
26 Standard_Boolean& Empty,
27 Standard_Boolean& Same,
28 Standard_Boolean& Multpoint,
29 IntPatch_SequenceOfLine& slin,
30 IntPatch_SequenceOfPoint& spnt)
33 Standard_Integer i, NbSol;
34 Standard_Real U1,V1,U2,V2;
35 IntSurf_TypeTrans trans1,trans2;
36 IntAna_ResultType typint;
38 gp_Cone Co1(Quad1.Cone());
39 gp_Cone Co2(Quad2.Cone());
41 IntAna_QuadQuadGeo inter(Co1,Co2,Tol);
42 if (!inter.IsDone()) {
43 return Standard_False;
46 typint = inter.TypeInter();
47 NbSol = inter.NbSolutions();
48 Empty = Standard_False;
49 Same = Standard_False;
55 Empty = Standard_True;
65 //modified by NIZNHY-PKV Wed Nov 30 12:56:06 2005f
67 Standard_Real para, aDot;
68 gp_Pnt aPApex1, aPApex2, ptbid;
71 IntPatch_Point aPtsol;
72 Handle(IntPatch_GLine) glig;
78 IntSurf_Situation situC1, situC2;
80 linsol = inter.Line(1);
81 para =ElCLib::Parameter(linsol, aPApex1);
82 ptbid=ElCLib::Value(para+5., linsol);
83 Quad1.Parameters(aPApex1, U1, V1);
84 Quad2.Parameters(aPApex1, U2, V2);
86 aPtsol.SetValue(aPApex1, Tol, Standard_False);
87 aPtsol.SetParameters(U1, V1, U2, V2);
88 aPtsol.SetParameter(para);
90 NormC1=Quad1.Normale(ptbid);
91 NormC2=Quad2.Normale(ptbid);
92 aDot=NormC1.Dot(NormC2);
94 situC1=IntSurf_Outside;
95 situC2=IntSurf_Outside;
98 Standard_Real aR1, aR2;
99 gp_Lin aLAx1(aPApex1, Co1.Axis().Direction());
100 gp_Lin aLAx2(aPApex2, Co2.Axis().Direction());
102 aR1=aLAx1.Distance(ptbid);
103 aR2=aLAx2.Distance(ptbid);
105 situC1=IntSurf_Inside;
106 situC2=IntSurf_Outside;
107 if (aR1>aR2) { // Intersection line parametrizes from Apex1 to Apex2,
108 situC1=IntSurf_Outside; // So the distance between ptbid and aLAx1 is greater than the
109 situC2=IntSurf_Inside; // distance between ptbid and aLAx2 and in that case Cone2
114 glig=new IntPatch_GLine(linsol, Standard_True, situC1, situC2);
115 glig->AddVertex(aPtsol);
116 glig->SetFirstPoint(1);
119 linsol.SetDirection(linsol.Direction().Reversed());
120 para =ElCLib::Parameter(linsol, aPApex1);
121 aPtsol.SetParameter(para);
123 glig = new IntPatch_GLine(linsol, Standard_True, situC2, situC1);
124 glig->AddVertex(aPtsol);
125 glig->SetFirstPoint(1);
128 //////////////////////
131 for (i=1; i<=2; ++i) {
132 linsol = inter.Line(i);
133 para =ElCLib::Parameter(linsol, aPApex1);
134 ptbid=ElCLib::Value(para+5., linsol);
135 Quad1.Parameters(aPApex1, U1, V1);
136 Quad2.Parameters(aPApex1, U2, V2);
139 trans2 = IntSurf_Out;
140 if (linsol.Direction().
141 DotCross(Quad2.Normale(ptbid),Quad1.Normale(ptbid)) >0.) {
142 trans1 = IntSurf_Out;
146 Multpoint = Standard_True;
148 aPtsol.SetValue(aPApex1, Tol, Standard_False);
149 aPtsol.SetParameters(U1,V1,U2,V2);
150 aPtsol.SetParameter(para);
151 aPtsol.SetMultiple(Standard_True);
153 glig = new IntPatch_GLine(linsol, Standard_False, trans1, trans2);
154 glig->AddVertex(aPtsol);
155 glig->SetFirstPoint(1);
158 linsol.SetDirection(linsol.Direction().Reversed());
159 para = ElCLib::Parameter(linsol, aPApex1);
160 aPtsol.SetParameter(para);
161 glig = new IntPatch_GLine(linsol, Standard_False, trans1, trans2);
162 glig->AddVertex(aPtsol);
163 glig->SetFirstPoint(1);
166 } //for (i=1; i<=2; ++i)
167 } //else if (NbSol==2)
170 //modified by NIZNHY-PKV Wed Nov 30 12:56:10 2005t
172 case IntAna_Point : {
174 gp_Pnt apex1(Co1.Apex());
175 gp_Pnt apex2(Co2.Apex());
176 Standard_Real param1,param2;
177 Standard_Real paramapex1 = ElCLib::LineParameter(Co1.Axis(),apex1);
178 Standard_Real paramapex2 = ElCLib::LineParameter(Co2.Axis(),apex2);
179 for (i=1; i <= NbSol; i++) {
180 ptcontact = inter.Point(i);
181 param1 = ElCLib::LineParameter(Co1.Axis(),ptcontact);
182 param2 = ElCLib::LineParameter(Co2.Axis(),ptcontact);
184 Quad1.Parameters(ptcontact,U1,V1);
185 Quad2.Parameters(ptcontact,U2,V2);
187 if (apex1.Distance(ptcontact) <= Tol &&
188 apex2.Distance(ptcontact) <= Tol) {
189 IntPatch_Point ptsol;
190 ptsol.SetValue(ptcontact,Tol,Standard_False);
191 ptsol.SetParameters(U1,V1,U2,V2);
194 else if (param1 >= paramapex1 && param2 >= paramapex2) {
195 IntPatch_Point ptsol;
196 ptsol.SetValue(ptcontact,Tol,Standard_True);
197 ptsol.SetParameters(U1,V1,U2,V2);
206 IntPatch_Point aPtsol;
209 for (i = 1; i <= NbSol; i++) {
210 gp_Circ cirsol = inter.Circle(i);
211 ElCLib::D1(0.,cirsol,ptref,Tgt);
212 Standard_Real qwe=Tgt.DotCross(Quad2.Normale(ptref),Quad1.Normale(ptref));
213 if(qwe> 0.00000001) {
214 trans1 = IntSurf_Out;
217 else if(qwe<-0.00000001){
219 trans2 = IntSurf_Out;
222 trans1=trans2=IntSurf_Undecided;
224 Handle(IntPatch_GLine) glig = new IntPatch_GLine(cirsol,Standard_False,trans1,trans2);
225 if(inter.HasCommonGen()) {
226 const gp_Pnt& aPChar = inter.PChar();
227 Quad1.Parameters(aPChar, U1, V1);
228 Quad2.Parameters(aPChar, U2, V2);
229 aPtsol.SetValue(aPChar, Tol, Standard_False);
230 aPtsol.SetParameters(U1, V1, U2, V2);
231 aPtsol.SetParameter(0.);
232 glig->AddVertex(aPtsol);
242 IntPatch_Point aPtsol;
243 gp_Elips elipsol = inter.Ellipse(1);
247 ElCLib::D1(0.,elipsol,ptref,Tgt);
249 Standard_Real qwe=Tgt.DotCross(Quad2.Normale(ptref),Quad1.Normale(ptref));
250 if(qwe> 0.00000001) {
251 trans1 = IntSurf_Out;
254 else if(qwe<-0.00000001) {
256 trans2 = IntSurf_Out;
259 trans1=trans2=IntSurf_Undecided;
261 Handle(IntPatch_GLine) glig = new IntPatch_GLine(elipsol,Standard_False,trans1,trans2);
262 if(inter.HasCommonGen()) {
263 const gp_Pnt& aPChar = inter.PChar();
264 Quad1.Parameters(aPChar, U1, V1);
265 Quad2.Parameters(aPChar, U2, V2);
266 aPtsol.SetValue(aPChar, Tol, Standard_False);
267 aPtsol.SetParameters(U1, V1, U2, V2);
268 aPtsol.SetParameter(0.);
269 glig->AddVertex(aPtsol);
277 case IntAna_Hyperbola:
279 IntPatch_Point aPtsol;
282 for(i=1; i<=2; i++) {
283 gp_Hypr hyprsol = inter.Hyperbola(i);
284 ElCLib::D1(0.,hyprsol,ptref,Tgt);
285 Standard_Real qwe=Tgt.DotCross(Quad2.Normale(ptref),Quad1.Normale(ptref));
286 if(qwe> 0.00000001) {
287 trans1 = IntSurf_Out;
290 else if(qwe<-0.00000001){
292 trans2 = IntSurf_Out;
295 trans1=trans2=IntSurf_Undecided;
297 Handle(IntPatch_GLine) glig = new IntPatch_GLine(hyprsol,Standard_False,trans1,trans2);
298 if(inter.HasCommonGen()) {
299 const gp_Pnt& aPChar = inter.PChar();
300 Quad1.Parameters(aPChar, U1, V1);
301 Quad2.Parameters(aPChar, U2, V2);
302 aPtsol.SetValue(aPChar, Tol, Standard_False);
303 aPtsol.SetParameters(U1, V1, U2, V2);
304 aPtsol.SetParameter(0.);
305 glig->AddVertex(aPtsol);
312 case IntAna_Parabola:
314 IntPatch_Point aPtsol;
315 gp_Parab parabsol = inter.Parabola(1);
317 gp_Vec Tgtorig(parabsol.YAxis().Direction());
318 Standard_Real ptran = Tgtorig.DotCross(Quad2.Normale(parabsol.Location()),
319 Quad1.Normale(parabsol.Location()));
320 if (ptran >0.00000001) {
321 trans1 = IntSurf_Out;
324 else if (ptran <-0.00000001) {
326 trans2 = IntSurf_Out;
329 trans1=trans2=IntSurf_Undecided;
332 Handle(IntPatch_GLine) glig = new IntPatch_GLine(parabsol,Standard_False,trans1,trans2);
333 if(inter.HasCommonGen()) {
334 const gp_Pnt& aPChar = inter.PChar();
335 Quad1.Parameters(aPChar, U1, V1);
336 Quad2.Parameters(aPChar, U2, V2);
337 aPtsol.SetValue(aPChar, Tol, Standard_False);
338 aPtsol.SetParameters(U1, V1, U2, V2);
339 aPtsol.SetParameter(0.);
340 glig->AddVertex(aPtsol);
347 case IntAna_NoGeometricSolution:
350 IntAna_IntQuadQuad anaint(Co1,Co2,Tol);
351 if (!anaint.IsDone()) {
352 return Standard_False;
355 if (anaint.NbPnt() == 0 && anaint.NbCurve() == 0) {
356 Empty = Standard_True;
359 NbSol = anaint.NbPnt();
360 for (i = 1; i <= NbSol; i++) {
361 psol = anaint.Point(i);
362 Quad1.Parameters(psol,U1,V1);
363 Quad2.Parameters(psol,U2,V2);
364 IntPatch_Point ptsol;
365 ptsol.SetValue(psol,Tol,Standard_True);
366 ptsol.SetParameters(U1,V1,U2,V2);
370 gp_Pnt ptvalid, ptf, ptl;
373 Standard_Real first,last,para;
374 Standard_Boolean tgfound,firstp,lastp,kept;
375 Standard_Integer kount;
377 NbSol = anaint.NbCurve();
378 for (i = 1; i <= NbSol; i++) {
379 Handle(IntPatch_ALine) alig;
380 kept = Standard_False;
381 IntAna_Curve curvsol = anaint.Curve(i);
382 curvsol.Domain(first,last);
383 firstp = !curvsol.IsFirstOpen();
384 lastp = !curvsol.IsLastOpen();
386 ptf = curvsol.Value(first);
389 ptl = curvsol.Value(last);
393 tgfound = Standard_False;
396 para = (1.123*first + para)/2.123;
397 tgfound = curvsol.D1u(para,ptvalid,tgvalid);
398 if(tgvalid.SquareMagnitude() < 1e-14) {
399 //-- on se trouve ds un cas ou les normales n'auront pas de sens
400 tgfound = Standard_False;
409 Standard_Real qwe= tgvalid.DotCross(Quad2.Normale(ptvalid),
410 Quad1.Normale(ptvalid));
411 if(qwe > 0.000000001) {
412 trans1 = IntSurf_Out;
415 else if(qwe < -0.000000001) {
417 trans2 = IntSurf_Out;
420 trans1=trans2=IntSurf_Undecided;
422 alig = new IntPatch_ALine(curvsol,Standard_False,trans1,trans2);
423 kept = Standard_True;
426 ptvalid = curvsol.Value(para);
427 alig = new IntPatch_ALine(curvsol,Standard_False);
428 kept = Standard_True;
429 //-- cout << "Transition indeterminee" << endl;
432 Standard_Boolean Nfirstp = !firstp;
433 Standard_Boolean Nlastp = !lastp;
434 ProcessBounds(alig,slin,Quad1,Quad2,Nfirstp,ptf,first,
435 Nlastp,ptl,last,Multpoint,Tol);
445 return Standard_False;
449 //When two cones have common generatrix passing through apexes
450 //it is necessary to add it is solution
451 if(inter.HasCommonGen()) {
453 IntPatch_Point aPtsol;
454 gp_Pnt aPApex1, aPApex2;
457 //common generatrix of cones
458 gce_MakeLin aMkLin(aPApex1, aPApex2);
459 const gp_Lin& linsol = aMkLin.Value();
460 Handle(IntPatch_GLine) glig =
461 new IntPatch_GLine(linsol,Standard_True,IntSurf_Undecided,IntSurf_Undecided);
463 const gp_Pnt& aPChar = inter.PChar();
464 Quad1.Parameters(aPChar, U1, V1);
465 Quad2.Parameters(aPChar, U2, V2);
466 aPtsol.SetValue(aPChar, Tol, Standard_False);
467 aPtsol.SetParameters(U1, V1, U2, V2);
468 para = ElCLib::Parameter(linsol, aPChar);
469 aPtsol.SetParameter(para);
470 glig->AddVertex(aPtsol);
476 return Standard_True;
478 //=======================================================================
481 //=======================================================================
482 Standard_Boolean IntCoSp(const IntSurf_Quadric& Quad1,
483 const IntSurf_Quadric& Quad2,
484 const Standard_Real Tol,
485 const Standard_Boolean Reversed,
486 Standard_Boolean& Empty,
487 Standard_Boolean& Multpoint,
488 IntPatch_SequenceOfLine& slin,
489 IntPatch_SequenceOfPoint& spnt)
495 IntSurf_TypeTrans trans1,trans2;
496 IntAna_ResultType typint;
500 Standard_Real U1,V1,U2,V2;
510 IntAna_QuadQuadGeo inter(Sp,Co,Tol);
512 if (!inter.IsDone()) {return Standard_False;}
514 typint = inter.TypeInter();
515 Standard_Integer NbSol = inter.NbSolutions();
516 Empty = Standard_False;
522 Empty = Standard_True;
529 gp_Pnt apex(Co.Apex());
531 Standard_Real paramapex = ElCLib::LineParameter(Co.Axis(),apex);
532 for (i=1; i <= NbSol; i++) {
533 ptcontact = inter.Point(i);
534 param = ElCLib::LineParameter(Co.Axis(),ptcontact);
535 Quad1.Parameters(ptcontact,U1,V1);
536 Quad2.Parameters(ptcontact,U2,V2);
538 if (apex.Distance(ptcontact) <= Tol) {
539 IntPatch_Point ptsol;
540 ptsol.SetValue(ptcontact,Tol,Standard_False);
541 ptsol.SetParameters(U1,V1,U2,V2);
544 else if (param >= paramapex) {
545 IntPatch_Point ptsol;
546 ptsol.SetValue(ptcontact,Tol,Standard_True);
547 ptsol.SetParameters(U1,V1,U2,V2);
559 for (i=1; i<=NbSol; i++) {
560 gp_Circ cirsol = inter.Circle(i);
561 //-- param = ElCLib::LineParameter(Co.Axis(),
562 //-- cirsol.Location());
563 //-- if (param >= paramapex) {
565 ElCLib::D1(0.,cirsol,ptref,Tgt);
566 Standard_Real qwe = Tgt.DotCross(Quad2.Normale(ptref),
567 Quad1.Normale(ptref));
568 if(qwe> 0.00000001) {
569 trans1 = IntSurf_Out;
572 else if(qwe< -0.00000001) {
574 trans2 = IntSurf_Out;
577 trans1=trans2=IntSurf_Undecided;
579 Handle(IntPatch_GLine) glig = new IntPatch_GLine(cirsol,Standard_False,trans1,trans2);
586 case IntAna_PointAndCircle:
590 gp_Pnt apex(Co.Apex());
592 Standard_Real paramapex = ElCLib::LineParameter(Co.Axis(),apex);
594 // le point est necessairement l apex
595 Quad1.Parameters(apex,U1,V1);
596 Quad2.Parameters(apex,U2,V2);
597 IntPatch_Point ptsol;
598 ptsol.SetValue(apex,Tol,Standard_False);
599 ptsol.SetParameters(U1,V1,U2,V2);
602 gp_Circ cirsol = inter.Circle(1);
603 param = ElCLib::LineParameter(Co.Axis(),
605 ElCLib::D1(0., cirsol, ptref, Tgt);
606 Standard_Real qwe = Tgt.DotCross(Quad2.Normale(ptref),
607 Quad1.Normale(ptref));
609 if (param >= paramapex)
611 if (qwe > Precision::PConfusion())
613 trans1 = IntSurf_Out;
616 else if (qwe < -Precision::PConfusion())
619 trans2 = IntSurf_Out;
623 trans1 = trans2 = IntSurf_Undecided;
628 if (qwe < -Precision::PConfusion())
630 trans1 = IntSurf_Out;
633 else if (qwe > Precision::PConfusion())
636 trans2 = IntSurf_Out;
640 trans1 = trans2 = IntSurf_Undecided;
643 Handle(IntPatch_GLine) glig = new IntPatch_GLine(cirsol, Standard_False, trans1, trans2);
648 case IntAna_NoGeometricSolution:
651 IntAna_IntQuadQuad anaint(Co,Sp,Tol);
652 if (!anaint.IsDone()) {
653 return Standard_False;
656 if (anaint.NbPnt()==0 && anaint.NbCurve()==0) {
657 Empty = Standard_True;
660 NbSol = anaint.NbPnt();
661 for (i = 1; i <= NbSol; i++) {
662 psol = anaint.Point(i);
663 Quad1.Parameters(psol,U1,V1);
664 Quad2.Parameters(psol,U2,V2);
665 IntPatch_Point ptsol;
666 ptsol.SetValue(psol,Tol,Standard_True);
667 ptsol.SetParameters(U1,V1,U2,V2);
671 gp_Pnt ptvalid, ptf, ptl;
673 Standard_Real first,last,para;
674 Standard_Boolean tgfound,firstp,lastp,kept;
675 Standard_Integer kount;
677 NbSol = anaint.NbCurve();
678 for (i = 1; i <= NbSol; i++) {
679 Handle(IntPatch_ALine) alig;
680 kept = Standard_False;
681 IntAna_Curve curvsol = anaint.Curve(i);
682 curvsol.Domain(first,last);
683 firstp = !curvsol.IsFirstOpen();
684 lastp = !curvsol.IsLastOpen();
686 ptf = curvsol.Value(first);
689 ptl = curvsol.Value(last);
693 tgfound = Standard_False;
696 para = (1.123*first + para)/2.123;
697 tgfound = curvsol.D1u(para,ptvalid,tgvalid);
704 para = ElCLib::LineParameter(Co.Axis(),ptvalid);
705 Standard_Real qwe = tgvalid.DotCross(Quad2.Normale(ptvalid),
706 Quad1.Normale(ptvalid));
707 if(qwe> 0.000000001) {
708 trans1 = IntSurf_Out;
711 else if(qwe<-0.000000001) {
713 trans2 = IntSurf_Out;
716 trans1=trans2=IntSurf_Undecided;
718 alig = new IntPatch_ALine(curvsol,Standard_False,trans1,trans2);
719 kept = Standard_True;
722 ptvalid = curvsol.Value(para);
723 para = ElCLib::LineParameter(Co.Axis(),ptvalid);
724 alig = new IntPatch_ALine(curvsol,Standard_False);
725 kept = Standard_True;
726 //-- cout << "Transition indeterminee" << endl;
729 Standard_Boolean Nfirstp = !firstp;
730 Standard_Boolean Nlastp = !lastp;
731 ProcessBounds(alig,slin,Quad1,Quad2,Nfirstp,ptf,first,
732 Nlastp,ptl,last,Multpoint,Tol);
742 return Standard_False;
746 return Standard_True;
748 //=======================================================================
751 //=======================================================================
752 Standard_Boolean IntSpSp(const IntSurf_Quadric& Quad1,
753 const IntSurf_Quadric& Quad2,
754 const Standard_Real Tol,
755 Standard_Boolean& Empty,
756 Standard_Boolean& Same,
757 IntPatch_SequenceOfLine& slin,
758 IntPatch_SequenceOfPoint& spnt)
760 // Traitement du cas Sphere/Sphere
763 IntSurf_TypeTrans trans1,trans2;
764 IntAna_ResultType typint;
765 gp_Sphere sph1(Quad1.Sphere());
766 gp_Sphere sph2(Quad2.Sphere());
768 IntAna_QuadQuadGeo inter(sph1,sph2,Tol);
769 if (!inter.IsDone()) {return Standard_False;}
771 typint = inter.TypeInter();
772 Empty = Standard_False;
773 Same = Standard_False;
779 Empty = Standard_True;
785 Same = Standard_True;
791 gp_Pnt psol(inter.Point(1));
792 Standard_Real U1,V1,U2,V2;
793 Quad1.Parameters(psol,U1,V1);
794 Quad2.Parameters(psol,U2,V2);
795 IntPatch_Point ptsol;
796 ptsol.SetValue(psol,Tol,Standard_True);
797 ptsol.SetParameters(U1,V1,U2,V2);
804 gp_Circ cirsol = inter.Circle(1);
807 ElCLib::D1(0.,cirsol,ptref,Tgt);
809 Standard_Real qwe=Tgt.DotCross(Quad2.Normale(ptref),Quad1.Normale(ptref));
811 trans1 = IntSurf_Out;
814 else if(qwe<-0.00000001) {
816 trans2 = IntSurf_Out;
819 trans1=trans2=IntSurf_Undecided;
821 Handle(IntPatch_GLine) glig = new IntPatch_GLine(cirsol,Standard_False,trans1,trans2);
828 return Standard_False; // on ne doit pas passer ici
831 return Standard_True;